print-tipc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that: (1) source code distributions
  7. * retain the above copyright notice and this paragraph in its entirety, (2)
  8. * distributions including binary code include the above copyright notice and
  9. * this paragraph in its entirety in the documentation or other materials
  10. * provided with the distribution, and (3) all advertising materials mentioning
  11. * features or use of this software display the following acknowledgement:
  12. * ``This product includes software developed by the University of California,
  13. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14. * the University nor the names of its contributors may be used to endorse
  15. * or promote products derived from this software without specific prior
  16. * written permission.
  17. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20. */
  21. /* \summary: Transparent Inter-Process Communication (TIPC) protocol printer */
  22. /*
  23. * specification:
  24. * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html
  25. * http://tipc.sourceforge.net/doc/tipc_message_formats.html
  26. */
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30. #include <netdissect-stdinc.h>
  31. #include "netdissect.h"
  32. #include "ether.h"
  33. #include "ethertype.h"
  34. #include "extract.h"
  35. static const char tstr[] = "[|TIPC]";
  36. #define TIPC_USER_LOW_IMPORTANCE 0
  37. #define TIPC_USER_MEDIUM_IMPORTANCE 1
  38. #define TIPC_USER_HIGH_IMPORTANCE 2
  39. #define TIPC_USER_CRITICAL_IMPORTANCE 3
  40. #define TIPC_USER_BCAST_PROTOCOL 5
  41. #define TIPC_USER_MSG_BUNDLER 6
  42. #define TIPC_USER_LINK_PROTOCOL 7
  43. #define TIPC_USER_CONN_MANAGER 8
  44. #define TIPC_USER_CHANGEOVER_PROTOCOL 10
  45. #define TIPC_USER_NAME_DISTRIBUTOR 11
  46. #define TIPC_USER_MSG_FRAGMENTER 12
  47. #define TIPC_USER_LINK_CONFIG 13
  48. #define TIPC_CONN_MSG 0
  49. #define TIPC_DIRECT_MSG 1
  50. #define TIPC_NAMED_MSG 2
  51. #define TIPC_MCAST_MSG 3
  52. #define TIPC_ZONE(addr) (((addr) >> 24) & 0xFF)
  53. #define TIPC_CLUSTER(addr) (((addr) >> 12) & 0xFFF)
  54. #define TIPC_NODE(addr) (((addr) >> 0) & 0xFFF)
  55. struct tipc_pkthdr {
  56. uint32_t w0;
  57. uint32_t w1;
  58. };
  59. #define TIPC_VER(w0) (((w0) >> 29) & 0x07)
  60. #define TIPC_USER(w0) (((w0) >> 25) & 0x0F)
  61. #define TIPC_HSIZE(w0) (((w0) >> 21) & 0x0F)
  62. #define TIPC_MSIZE(w0) (((w0) >> 0) & 0xFFFF)
  63. #define TIPC_MTYPE(w1) (((w1) >> 29) & 0x07)
  64. #define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF)
  65. #define TIPC_LINK_ACK(w2) (((w2) >> 16) & 0xFFFF)
  66. #define TIPC_LINK_SEQ(w2) (((w2) >> 0) & 0xFFFF)
  67. static const struct tok tipcuser_values[] = {
  68. { TIPC_USER_LOW_IMPORTANCE, "Low Importance Data payload" },
  69. { TIPC_USER_MEDIUM_IMPORTANCE, "Medium Importance Data payload" },
  70. { TIPC_USER_HIGH_IMPORTANCE, "High Importance Data payload" },
  71. { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" },
  72. { TIPC_USER_BCAST_PROTOCOL, "Broadcast Link Protocol internal" },
  73. { TIPC_USER_MSG_BUNDLER, "Message Bundler Protocol internal" },
  74. { TIPC_USER_LINK_PROTOCOL, "Link State Protocol internal" },
  75. { TIPC_USER_CONN_MANAGER, "Connection Manager internal" },
  76. { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" },
  77. { TIPC_USER_NAME_DISTRIBUTOR, "Name Table Update Protocol internal" },
  78. { TIPC_USER_MSG_FRAGMENTER, "Message Fragmentation Protocol internal" },
  79. { TIPC_USER_LINK_CONFIG, "Neighbor Detection Protocol internal" },
  80. { 0, NULL }
  81. };
  82. static const struct tok tipcmtype_values[] = {
  83. { TIPC_CONN_MSG, "CONN_MSG" },
  84. { TIPC_DIRECT_MSG, "MCAST_MSG" },
  85. { TIPC_NAMED_MSG, "NAMED_MSG" },
  86. { TIPC_MCAST_MSG, "DIRECT_MSG" },
  87. { 0, NULL }
  88. };
  89. static const struct tok tipc_linkconf_mtype_values[] = {
  90. { 0, "Link request" },
  91. { 1, "Link response" },
  92. { 0, NULL }
  93. };
  94. struct payload_tipc_pkthdr {
  95. uint32_t w0;
  96. uint32_t w1;
  97. uint32_t w2;
  98. uint32_t prev_node;
  99. uint32_t orig_port;
  100. uint32_t dest_port;
  101. uint32_t orig_node;
  102. uint32_t dest_node;
  103. uint32_t name_type;
  104. uint32_t w9;
  105. uint32_t wA;
  106. };
  107. struct internal_tipc_pkthdr {
  108. uint32_t w0;
  109. uint32_t w1;
  110. uint32_t w2;
  111. uint32_t prev_node;
  112. uint32_t w4;
  113. uint32_t w5;
  114. uint32_t orig_node;
  115. uint32_t dest_node;
  116. uint32_t trans_seq;
  117. uint32_t w9;
  118. };
  119. #define TIPC_SEQ_GAP(w1) (((w1) >> 16) & 0x1FFF)
  120. #define TIPC_BC_GAP_AFTER(w2) (((w2) >> 16) & 0xFFFF)
  121. #define TIPC_BC_GAP_TO(w2) (((w2) >> 0) & 0xFFFF)
  122. #define TIPC_LAST_SENT_FRAG(w4) (((w4) >> 16) & 0xFFFF)
  123. #define TIPC_NEXT_SENT_FRAG(w4) (((w4) >> 0) & 0xFFFF)
  124. #define TIPC_SESS_NO(w5) (((w5) >> 16) & 0xFFFF)
  125. #define TIPC_MSG_CNT(w9) (((w9) >> 16) & 0xFFFF)
  126. #define TIPC_LINK_TOL(w9) (((w9) >> 0) & 0xFFFF)
  127. struct link_conf_tipc_pkthdr {
  128. uint32_t w0;
  129. uint32_t w1;
  130. uint32_t dest_domain;
  131. uint32_t prev_node;
  132. uint32_t ntwrk_id;
  133. uint32_t w5;
  134. uint8_t media_address[16];
  135. };
  136. #define TIPC_NODE_SIG(w1) (((w1) >> 0) & 0xFFFF)
  137. #define TIPC_MEDIA_ID(w5) (((w5) >> 0) & 0xFF)
  138. static void
  139. print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap)
  140. {
  141. uint32_t w0, w1, w2;
  142. u_int user;
  143. u_int hsize;
  144. u_int msize;
  145. u_int mtype;
  146. u_int broadcast_ack;
  147. u_int link_ack;
  148. u_int link_seq;
  149. u_int prev_node;
  150. u_int orig_port;
  151. u_int dest_port;
  152. u_int orig_node;
  153. u_int dest_node;
  154. ND_TCHECK(ap->dest_port);
  155. w0 = EXTRACT_32BITS(&ap->w0);
  156. user = TIPC_USER(w0);
  157. hsize = TIPC_HSIZE(w0);
  158. msize = TIPC_MSIZE(w0);
  159. w1 = EXTRACT_32BITS(&ap->w1);
  160. mtype = TIPC_MTYPE(w1);
  161. prev_node = EXTRACT_32BITS(&ap->prev_node);
  162. orig_port = EXTRACT_32BITS(&ap->orig_port);
  163. dest_port = EXTRACT_32BITS(&ap->dest_port);
  164. if (hsize <= 6) {
  165. ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
  166. TIPC_VER(w0),
  167. TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
  168. orig_port, dest_port,
  169. hsize*4, msize,
  170. tok2str(tipcuser_values, "unknown", user),
  171. tok2str(tipcmtype_values, "Unknown", mtype)));
  172. } else {
  173. ND_TCHECK(ap->dest_node);
  174. orig_node = EXTRACT_32BITS(&ap->orig_node);
  175. dest_node = EXTRACT_32BITS(&ap->dest_node);
  176. ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
  177. TIPC_VER(w0),
  178. TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
  179. orig_port,
  180. TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
  181. dest_port,
  182. hsize*4, msize,
  183. tok2str(tipcuser_values, "unknown", user),
  184. tok2str(tipcmtype_values, "Unknown", mtype)));
  185. if (ndo->ndo_vflag) {
  186. broadcast_ack = TIPC_BROADCAST_ACK(w1);
  187. w2 = EXTRACT_32BITS(&ap->w2);
  188. link_ack = TIPC_LINK_ACK(w2);
  189. link_seq = TIPC_LINK_SEQ(w2);
  190. ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u",
  191. TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
  192. broadcast_ack, link_ack, link_seq));
  193. }
  194. }
  195. return;
  196. trunc:
  197. ND_PRINT((ndo, "%s", tstr));
  198. }
  199. static void
  200. print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap)
  201. {
  202. uint32_t w0, w1, w2, w4, w5, w9;
  203. u_int user;
  204. u_int hsize;
  205. u_int msize;
  206. u_int mtype;
  207. u_int seq_gap;
  208. u_int broadcast_ack;
  209. u_int bc_gap_after;
  210. u_int bc_gap_to;
  211. u_int prev_node;
  212. u_int last_sent_frag;
  213. u_int next_sent_frag;
  214. u_int sess_no;
  215. u_int orig_node;
  216. u_int dest_node;
  217. u_int trans_seq;
  218. u_int msg_cnt;
  219. u_int link_tol;
  220. ND_TCHECK(ap->dest_node);
  221. w0 = EXTRACT_32BITS(&ap->w0);
  222. user = TIPC_USER(w0);
  223. hsize = TIPC_HSIZE(w0);
  224. msize = TIPC_MSIZE(w0);
  225. w1 = EXTRACT_32BITS(&ap->w1);
  226. mtype = TIPC_MTYPE(w1);
  227. orig_node = EXTRACT_32BITS(&ap->orig_node);
  228. dest_node = EXTRACT_32BITS(&ap->dest_node);
  229. ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)",
  230. TIPC_VER(w0),
  231. TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
  232. TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
  233. hsize*4, msize,
  234. tok2str(tipcuser_values, "unknown", user),
  235. tok2str(tipcmtype_values, "Unknown", mtype), w1));
  236. if (ndo->ndo_vflag) {
  237. ND_TCHECK(*ap);
  238. seq_gap = TIPC_SEQ_GAP(w1);
  239. broadcast_ack = TIPC_BROADCAST_ACK(w1);
  240. w2 = EXTRACT_32BITS(&ap->w2);
  241. bc_gap_after = TIPC_BC_GAP_AFTER(w2);
  242. bc_gap_to = TIPC_BC_GAP_TO(w2);
  243. prev_node = EXTRACT_32BITS(&ap->prev_node);
  244. w4 = EXTRACT_32BITS(&ap->w4);
  245. last_sent_frag = TIPC_LAST_SENT_FRAG(w4);
  246. next_sent_frag = TIPC_NEXT_SENT_FRAG(w4);
  247. w5 = EXTRACT_32BITS(&ap->w5);
  248. sess_no = TIPC_SESS_NO(w5);
  249. trans_seq = EXTRACT_32BITS(&ap->trans_seq);
  250. w9 = EXTRACT_32BITS(&ap->w9);
  251. msg_cnt = TIPC_MSG_CNT(w9);
  252. link_tol = TIPC_LINK_TOL(w9);
  253. ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u",
  254. TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
  255. sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to,
  256. last_sent_frag, next_sent_frag, trans_seq, msg_cnt,
  257. link_tol));
  258. }
  259. return;
  260. trunc:
  261. ND_PRINT((ndo, "%s", tstr));
  262. }
  263. static void
  264. print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap)
  265. {
  266. uint32_t w0, w1, w5;
  267. u_int user;
  268. u_int hsize;
  269. u_int msize;
  270. u_int mtype;
  271. u_int node_sig;
  272. u_int prev_node;
  273. u_int dest_domain;
  274. u_int ntwrk_id;
  275. u_int media_id;
  276. ND_TCHECK(ap->prev_node);
  277. w0 = EXTRACT_32BITS(&ap->w0);
  278. user = TIPC_USER(w0);
  279. hsize = TIPC_HSIZE(w0);
  280. msize = TIPC_MSIZE(w0);
  281. w1 = EXTRACT_32BITS(&ap->w1);
  282. mtype = TIPC_MTYPE(w1);
  283. dest_domain = EXTRACT_32BITS(&ap->dest_domain);
  284. prev_node = EXTRACT_32BITS(&ap->prev_node);
  285. ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
  286. TIPC_VER(w0),
  287. TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
  288. TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain),
  289. hsize*4, msize,
  290. tok2str(tipcuser_values, "unknown", user),
  291. tok2str(tipc_linkconf_mtype_values, "Unknown", mtype)));
  292. if (ndo->ndo_vflag) {
  293. ND_TCHECK(ap->w5);
  294. node_sig = TIPC_NODE_SIG(w1);
  295. ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id);
  296. w5 = EXTRACT_32BITS(&ap->w5);
  297. media_id = TIPC_MEDIA_ID(w5);
  298. ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u",
  299. node_sig, ntwrk_id, media_id));
  300. }
  301. return;
  302. trunc:
  303. ND_PRINT((ndo, "%s", tstr));
  304. }
  305. void
  306. tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_,
  307. u_int caplen _U_)
  308. {
  309. const struct tipc_pkthdr *ap;
  310. uint32_t w0;
  311. u_int user;
  312. ap = (const struct tipc_pkthdr *)bp;
  313. ND_TCHECK(ap->w0);
  314. w0 = EXTRACT_32BITS(&ap->w0);
  315. user = TIPC_USER(w0);
  316. switch (user)
  317. {
  318. case TIPC_USER_LOW_IMPORTANCE:
  319. case TIPC_USER_MEDIUM_IMPORTANCE:
  320. case TIPC_USER_HIGH_IMPORTANCE:
  321. case TIPC_USER_CRITICAL_IMPORTANCE:
  322. case TIPC_USER_NAME_DISTRIBUTOR:
  323. case TIPC_USER_CONN_MANAGER:
  324. print_payload(ndo, (const struct payload_tipc_pkthdr *)bp);
  325. break;
  326. case TIPC_USER_LINK_CONFIG:
  327. print_link_conf(ndo, (const struct link_conf_tipc_pkthdr *)bp);
  328. break;
  329. case TIPC_USER_BCAST_PROTOCOL:
  330. case TIPC_USER_MSG_BUNDLER:
  331. case TIPC_USER_LINK_PROTOCOL:
  332. case TIPC_USER_CHANGEOVER_PROTOCOL:
  333. case TIPC_USER_MSG_FRAGMENTER:
  334. print_internal(ndo, (const struct internal_tipc_pkthdr *)bp);
  335. break;
  336. }
  337. return;
  338. trunc:
  339. ND_PRINT((ndo, "%s", tstr));
  340. }
  341. /*
  342. * Local Variables:
  343. * c-style: bsd
  344. * End:
  345. */