print-ipx.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright (c) 1994, 1995, 1996
  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. * Contributed by Brad Parker (brad@fcr.com).
  22. */
  23. /* \summary: Novell IPX printer */
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27. #include <netdissect-stdinc.h>
  28. #include <stdio.h>
  29. #include "netdissect.h"
  30. #include "addrtoname.h"
  31. #include "extract.h"
  32. /* well-known sockets */
  33. #define IPX_SKT_NCP 0x0451
  34. #define IPX_SKT_SAP 0x0452
  35. #define IPX_SKT_RIP 0x0453
  36. #define IPX_SKT_NETBIOS 0x0455
  37. #define IPX_SKT_DIAGNOSTICS 0x0456
  38. #define IPX_SKT_NWLINK_DGM 0x0553 /* NWLink datagram, may contain SMB */
  39. #define IPX_SKT_EIGRP 0x85be /* Cisco EIGRP over IPX */
  40. /* IPX transport header */
  41. struct ipxHdr {
  42. uint16_t cksum; /* Checksum */
  43. uint16_t length; /* Length, in bytes, including header */
  44. uint8_t tCtl; /* Transport Control (i.e. hop count) */
  45. uint8_t pType; /* Packet Type (i.e. level 2 protocol) */
  46. uint16_t dstNet[2]; /* destination net */
  47. uint8_t dstNode[6]; /* destination node */
  48. uint16_t dstSkt; /* destination socket */
  49. uint16_t srcNet[2]; /* source net */
  50. uint8_t srcNode[6]; /* source node */
  51. uint16_t srcSkt; /* source socket */
  52. };
  53. #define ipxSize 30
  54. static const char *ipxaddr_string(uint32_t, const u_char *);
  55. static void ipx_decode(netdissect_options *, const struct ipxHdr *, const u_char *, u_int);
  56. static void ipx_sap_print(netdissect_options *, const u_short *, u_int);
  57. static void ipx_rip_print(netdissect_options *, const u_short *, u_int);
  58. /*
  59. * Print IPX datagram packets.
  60. */
  61. void
  62. ipx_print(netdissect_options *ndo, const u_char *p, u_int length)
  63. {
  64. const struct ipxHdr *ipx = (const struct ipxHdr *)p;
  65. if (!ndo->ndo_eflag)
  66. ND_PRINT((ndo, "IPX "));
  67. ND_TCHECK(ipx->srcSkt);
  68. ND_PRINT((ndo, "%s.%04x > ",
  69. ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
  70. EXTRACT_16BITS(&ipx->srcSkt)));
  71. ND_PRINT((ndo, "%s.%04x: ",
  72. ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
  73. EXTRACT_16BITS(&ipx->dstSkt)));
  74. /* take length from ipx header */
  75. ND_TCHECK(ipx->length);
  76. length = EXTRACT_16BITS(&ipx->length);
  77. ipx_decode(ndo, ipx, p + ipxSize, length - ipxSize);
  78. return;
  79. trunc:
  80. ND_PRINT((ndo, "[|ipx %d]", length));
  81. }
  82. static const char *
  83. ipxaddr_string(uint32_t net, const u_char *node)
  84. {
  85. static char line[256];
  86. snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x",
  87. net, node[0], node[1], node[2], node[3], node[4], node[5]);
  88. return line;
  89. }
  90. static void
  91. ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *datap, u_int length)
  92. {
  93. register u_short dstSkt;
  94. dstSkt = EXTRACT_16BITS(&ipx->dstSkt);
  95. switch (dstSkt) {
  96. case IPX_SKT_NCP:
  97. ND_PRINT((ndo, "ipx-ncp %d", length));
  98. break;
  99. case IPX_SKT_SAP:
  100. ipx_sap_print(ndo, (const u_short *)datap, length);
  101. break;
  102. case IPX_SKT_RIP:
  103. ipx_rip_print(ndo, (const u_short *)datap, length);
  104. break;
  105. case IPX_SKT_NETBIOS:
  106. ND_PRINT((ndo, "ipx-netbios %d", length));
  107. #ifdef ENABLE_SMB
  108. ipx_netbios_print(ndo, datap, length);
  109. #endif
  110. break;
  111. case IPX_SKT_DIAGNOSTICS:
  112. ND_PRINT((ndo, "ipx-diags %d", length));
  113. break;
  114. case IPX_SKT_NWLINK_DGM:
  115. ND_PRINT((ndo, "ipx-nwlink-dgm %d", length));
  116. #ifdef ENABLE_SMB
  117. ipx_netbios_print(ndo, datap, length);
  118. #endif
  119. break;
  120. case IPX_SKT_EIGRP:
  121. eigrp_print(ndo, datap, length);
  122. break;
  123. default:
  124. ND_PRINT((ndo, "ipx-#%x %d", dstSkt, length));
  125. break;
  126. }
  127. }
  128. static void
  129. ipx_sap_print(netdissect_options *ndo, const u_short *ipx, u_int length)
  130. {
  131. int command, i;
  132. ND_TCHECK(ipx[0]);
  133. command = EXTRACT_16BITS(ipx);
  134. ipx++;
  135. length -= 2;
  136. switch (command) {
  137. case 1:
  138. case 3:
  139. if (command == 1)
  140. ND_PRINT((ndo, "ipx-sap-req"));
  141. else
  142. ND_PRINT((ndo, "ipx-sap-nearest-req"));
  143. ND_TCHECK(ipx[0]);
  144. ND_PRINT((ndo, " %s", ipxsap_string(ndo, htons(EXTRACT_16BITS(&ipx[0])))));
  145. break;
  146. case 2:
  147. case 4:
  148. if (command == 2)
  149. ND_PRINT((ndo, "ipx-sap-resp"));
  150. else
  151. ND_PRINT((ndo, "ipx-sap-nearest-resp"));
  152. for (i = 0; i < 8 && length > 0; i++) {
  153. ND_TCHECK(ipx[0]);
  154. ND_PRINT((ndo, " %s '", ipxsap_string(ndo, htons(EXTRACT_16BITS(&ipx[0])))));
  155. if (fn_printzp(ndo, (const u_char *)&ipx[1], 48, ndo->ndo_snapend)) {
  156. ND_PRINT((ndo, "'"));
  157. goto trunc;
  158. }
  159. ND_TCHECK2(ipx[25], 10);
  160. ND_PRINT((ndo, "' addr %s",
  161. ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (const u_char *)&ipx[27])));
  162. ipx += 32;
  163. length -= 64;
  164. }
  165. break;
  166. default:
  167. ND_PRINT((ndo, "ipx-sap-?%x", command));
  168. break;
  169. }
  170. return;
  171. trunc:
  172. ND_PRINT((ndo, "[|ipx %d]", length));
  173. }
  174. static void
  175. ipx_rip_print(netdissect_options *ndo, const u_short *ipx, u_int length)
  176. {
  177. int command, i;
  178. ND_TCHECK(ipx[0]);
  179. command = EXTRACT_16BITS(ipx);
  180. ipx++;
  181. length -= 2;
  182. switch (command) {
  183. case 1:
  184. ND_PRINT((ndo, "ipx-rip-req"));
  185. if (length > 0) {
  186. ND_TCHECK(ipx[3]);
  187. ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
  188. EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])));
  189. }
  190. break;
  191. case 2:
  192. ND_PRINT((ndo, "ipx-rip-resp"));
  193. for (i = 0; i < 50 && length > 0; i++) {
  194. ND_TCHECK(ipx[3]);
  195. ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
  196. EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])));
  197. ipx += 4;
  198. length -= 8;
  199. }
  200. break;
  201. default:
  202. ND_PRINT((ndo, "ipx-rip-?%x", command));
  203. break;
  204. }
  205. return;
  206. trunc:
  207. ND_PRINT((ndo, "[|ipx %d]", length));
  208. }