1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek * Copyright (c) 1994, 1995, 1996
3*b636d99dSDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
4*b636d99dSDavid van Moolenbroek *
5*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek * written permission.
17*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek *
21*b636d99dSDavid van Moolenbroek * Format and print Novell IPX packets.
22*b636d99dSDavid van Moolenbroek * Contributed by Brad Parker (brad@fcr.com).
23*b636d99dSDavid van Moolenbroek */
24*b636d99dSDavid van Moolenbroek
25*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
26*b636d99dSDavid van Moolenbroek #ifndef lint
27*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-ipx.c,v 1.4 2014/11/20 03:05:03 christos Exp $");
28*b636d99dSDavid van Moolenbroek #endif
29*b636d99dSDavid van Moolenbroek
30*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
31*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
32*b636d99dSDavid van Moolenbroek #include "config.h"
33*b636d99dSDavid van Moolenbroek #endif
34*b636d99dSDavid van Moolenbroek
35*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
36*b636d99dSDavid van Moolenbroek
37*b636d99dSDavid van Moolenbroek #include <stdio.h>
38*b636d99dSDavid van Moolenbroek
39*b636d99dSDavid van Moolenbroek #include "interface.h"
40*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
41*b636d99dSDavid van Moolenbroek #include "extract.h"
42*b636d99dSDavid van Moolenbroek
43*b636d99dSDavid van Moolenbroek /* well-known sockets */
44*b636d99dSDavid van Moolenbroek #define IPX_SKT_NCP 0x0451
45*b636d99dSDavid van Moolenbroek #define IPX_SKT_SAP 0x0452
46*b636d99dSDavid van Moolenbroek #define IPX_SKT_RIP 0x0453
47*b636d99dSDavid van Moolenbroek #define IPX_SKT_NETBIOS 0x0455
48*b636d99dSDavid van Moolenbroek #define IPX_SKT_DIAGNOSTICS 0x0456
49*b636d99dSDavid van Moolenbroek #define IPX_SKT_NWLINK_DGM 0x0553 /* NWLink datagram, may contain SMB */
50*b636d99dSDavid van Moolenbroek #define IPX_SKT_EIGRP 0x85be /* Cisco EIGRP over IPX */
51*b636d99dSDavid van Moolenbroek
52*b636d99dSDavid van Moolenbroek /* IPX transport header */
53*b636d99dSDavid van Moolenbroek struct ipxHdr {
54*b636d99dSDavid van Moolenbroek uint16_t cksum; /* Checksum */
55*b636d99dSDavid van Moolenbroek uint16_t length; /* Length, in bytes, including header */
56*b636d99dSDavid van Moolenbroek uint8_t tCtl; /* Transport Control (i.e. hop count) */
57*b636d99dSDavid van Moolenbroek uint8_t pType; /* Packet Type (i.e. level 2 protocol) */
58*b636d99dSDavid van Moolenbroek uint16_t dstNet[2]; /* destination net */
59*b636d99dSDavid van Moolenbroek uint8_t dstNode[6]; /* destination node */
60*b636d99dSDavid van Moolenbroek uint16_t dstSkt; /* destination socket */
61*b636d99dSDavid van Moolenbroek uint16_t srcNet[2]; /* source net */
62*b636d99dSDavid van Moolenbroek uint8_t srcNode[6]; /* source node */
63*b636d99dSDavid van Moolenbroek uint16_t srcSkt; /* source socket */
64*b636d99dSDavid van Moolenbroek };
65*b636d99dSDavid van Moolenbroek
66*b636d99dSDavid van Moolenbroek #define ipxSize 30
67*b636d99dSDavid van Moolenbroek
68*b636d99dSDavid van Moolenbroek static const char *ipxaddr_string(uint32_t, const u_char *);
69*b636d99dSDavid van Moolenbroek static void ipx_decode(netdissect_options *, const struct ipxHdr *, const u_char *, u_int);
70*b636d99dSDavid van Moolenbroek static void ipx_sap_print(netdissect_options *, const u_short *, u_int);
71*b636d99dSDavid van Moolenbroek static void ipx_rip_print(netdissect_options *, const u_short *, u_int);
72*b636d99dSDavid van Moolenbroek
73*b636d99dSDavid van Moolenbroek /*
74*b636d99dSDavid van Moolenbroek * Print IPX datagram packets.
75*b636d99dSDavid van Moolenbroek */
76*b636d99dSDavid van Moolenbroek void
ipx_print(netdissect_options * ndo,const u_char * p,u_int length)77*b636d99dSDavid van Moolenbroek ipx_print(netdissect_options *ndo, const u_char *p, u_int length)
78*b636d99dSDavid van Moolenbroek {
79*b636d99dSDavid van Moolenbroek const struct ipxHdr *ipx = (const struct ipxHdr *)p;
80*b636d99dSDavid van Moolenbroek
81*b636d99dSDavid van Moolenbroek if (!ndo->ndo_eflag)
82*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "IPX "));
83*b636d99dSDavid van Moolenbroek
84*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx->srcSkt);
85*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s.%04x > ",
86*b636d99dSDavid van Moolenbroek ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
87*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&ipx->srcSkt)));
88*b636d99dSDavid van Moolenbroek
89*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s.%04x: ",
90*b636d99dSDavid van Moolenbroek ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
91*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&ipx->dstSkt)));
92*b636d99dSDavid van Moolenbroek
93*b636d99dSDavid van Moolenbroek /* take length from ipx header */
94*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx->length);
95*b636d99dSDavid van Moolenbroek length = EXTRACT_16BITS(&ipx->length);
96*b636d99dSDavid van Moolenbroek
97*b636d99dSDavid van Moolenbroek ipx_decode(ndo, ipx, (u_char *)ipx + ipxSize, length - ipxSize);
98*b636d99dSDavid van Moolenbroek return;
99*b636d99dSDavid van Moolenbroek trunc:
100*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|ipx %d]", length));
101*b636d99dSDavid van Moolenbroek }
102*b636d99dSDavid van Moolenbroek
103*b636d99dSDavid van Moolenbroek static const char *
ipxaddr_string(uint32_t net,const u_char * node)104*b636d99dSDavid van Moolenbroek ipxaddr_string(uint32_t net, const u_char *node)
105*b636d99dSDavid van Moolenbroek {
106*b636d99dSDavid van Moolenbroek static char line[256];
107*b636d99dSDavid van Moolenbroek
108*b636d99dSDavid van Moolenbroek snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x",
109*b636d99dSDavid van Moolenbroek net, node[0], node[1], node[2], node[3], node[4], node[5]);
110*b636d99dSDavid van Moolenbroek
111*b636d99dSDavid van Moolenbroek return line;
112*b636d99dSDavid van Moolenbroek }
113*b636d99dSDavid van Moolenbroek
114*b636d99dSDavid van Moolenbroek static void
ipx_decode(netdissect_options * ndo,const struct ipxHdr * ipx,const u_char * datap,u_int length)115*b636d99dSDavid van Moolenbroek ipx_decode(netdissect_options *ndo, const struct ipxHdr *ipx, const u_char *datap, u_int length)
116*b636d99dSDavid van Moolenbroek {
117*b636d99dSDavid van Moolenbroek register u_short dstSkt;
118*b636d99dSDavid van Moolenbroek
119*b636d99dSDavid van Moolenbroek dstSkt = EXTRACT_16BITS(&ipx->dstSkt);
120*b636d99dSDavid van Moolenbroek switch (dstSkt) {
121*b636d99dSDavid van Moolenbroek case IPX_SKT_NCP:
122*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-ncp %d", length));
123*b636d99dSDavid van Moolenbroek break;
124*b636d99dSDavid van Moolenbroek case IPX_SKT_SAP:
125*b636d99dSDavid van Moolenbroek ipx_sap_print(ndo, (u_short *)datap, length);
126*b636d99dSDavid van Moolenbroek break;
127*b636d99dSDavid van Moolenbroek case IPX_SKT_RIP:
128*b636d99dSDavid van Moolenbroek ipx_rip_print(ndo, (u_short *)datap, length);
129*b636d99dSDavid van Moolenbroek break;
130*b636d99dSDavid van Moolenbroek case IPX_SKT_NETBIOS:
131*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-netbios %d", length));
132*b636d99dSDavid van Moolenbroek #ifdef TCPDUMP_DO_SMB
133*b636d99dSDavid van Moolenbroek ipx_netbios_print(ndo, datap, length);
134*b636d99dSDavid van Moolenbroek #endif
135*b636d99dSDavid van Moolenbroek break;
136*b636d99dSDavid van Moolenbroek case IPX_SKT_DIAGNOSTICS:
137*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-diags %d", length));
138*b636d99dSDavid van Moolenbroek break;
139*b636d99dSDavid van Moolenbroek case IPX_SKT_NWLINK_DGM:
140*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-nwlink-dgm %d", length));
141*b636d99dSDavid van Moolenbroek #ifdef TCPDUMP_DO_SMB
142*b636d99dSDavid van Moolenbroek ipx_netbios_print(ndo, datap, length);
143*b636d99dSDavid van Moolenbroek #endif
144*b636d99dSDavid van Moolenbroek break;
145*b636d99dSDavid van Moolenbroek case IPX_SKT_EIGRP:
146*b636d99dSDavid van Moolenbroek eigrp_print(ndo, datap, length);
147*b636d99dSDavid van Moolenbroek break;
148*b636d99dSDavid van Moolenbroek default:
149*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-#%x %d", dstSkt, length));
150*b636d99dSDavid van Moolenbroek break;
151*b636d99dSDavid van Moolenbroek }
152*b636d99dSDavid van Moolenbroek }
153*b636d99dSDavid van Moolenbroek
154*b636d99dSDavid van Moolenbroek static void
ipx_sap_print(netdissect_options * ndo,const u_short * ipx,u_int length)155*b636d99dSDavid van Moolenbroek ipx_sap_print(netdissect_options *ndo, const u_short *ipx, u_int length)
156*b636d99dSDavid van Moolenbroek {
157*b636d99dSDavid van Moolenbroek int command, i;
158*b636d99dSDavid van Moolenbroek
159*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[0]);
160*b636d99dSDavid van Moolenbroek command = EXTRACT_16BITS(ipx);
161*b636d99dSDavid van Moolenbroek ipx++;
162*b636d99dSDavid van Moolenbroek length -= 2;
163*b636d99dSDavid van Moolenbroek
164*b636d99dSDavid van Moolenbroek switch (command) {
165*b636d99dSDavid van Moolenbroek case 1:
166*b636d99dSDavid van Moolenbroek case 3:
167*b636d99dSDavid van Moolenbroek if (command == 1)
168*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-sap-req"));
169*b636d99dSDavid van Moolenbroek else
170*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-sap-nearest-req"));
171*b636d99dSDavid van Moolenbroek
172*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[0]);
173*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))));
174*b636d99dSDavid van Moolenbroek break;
175*b636d99dSDavid van Moolenbroek
176*b636d99dSDavid van Moolenbroek case 2:
177*b636d99dSDavid van Moolenbroek case 4:
178*b636d99dSDavid van Moolenbroek if (command == 2)
179*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-sap-resp"));
180*b636d99dSDavid van Moolenbroek else
181*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-sap-nearest-resp"));
182*b636d99dSDavid van Moolenbroek
183*b636d99dSDavid van Moolenbroek for (i = 0; i < 8 && length > 0; i++) {
184*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[0]);
185*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))));
186*b636d99dSDavid van Moolenbroek if (fn_printzp(ndo, (u_char *)&ipx[1], 48, ndo->ndo_snapend)) {
187*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "'"));
188*b636d99dSDavid van Moolenbroek goto trunc;
189*b636d99dSDavid van Moolenbroek }
190*b636d99dSDavid van Moolenbroek ND_TCHECK2(ipx[25], 10);
191*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "' addr %s",
192*b636d99dSDavid van Moolenbroek ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27])));
193*b636d99dSDavid van Moolenbroek ipx += 32;
194*b636d99dSDavid van Moolenbroek length -= 64;
195*b636d99dSDavid van Moolenbroek }
196*b636d99dSDavid van Moolenbroek break;
197*b636d99dSDavid van Moolenbroek default:
198*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-sap-?%x", command));
199*b636d99dSDavid van Moolenbroek break;
200*b636d99dSDavid van Moolenbroek }
201*b636d99dSDavid van Moolenbroek return;
202*b636d99dSDavid van Moolenbroek trunc:
203*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|ipx %d]", length));
204*b636d99dSDavid van Moolenbroek }
205*b636d99dSDavid van Moolenbroek
206*b636d99dSDavid van Moolenbroek static void
ipx_rip_print(netdissect_options * ndo,const u_short * ipx,u_int length)207*b636d99dSDavid van Moolenbroek ipx_rip_print(netdissect_options *ndo, const u_short *ipx, u_int length)
208*b636d99dSDavid van Moolenbroek {
209*b636d99dSDavid van Moolenbroek int command, i;
210*b636d99dSDavid van Moolenbroek
211*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[0]);
212*b636d99dSDavid van Moolenbroek command = EXTRACT_16BITS(ipx);
213*b636d99dSDavid van Moolenbroek ipx++;
214*b636d99dSDavid van Moolenbroek length -= 2;
215*b636d99dSDavid van Moolenbroek
216*b636d99dSDavid van Moolenbroek switch (command) {
217*b636d99dSDavid van Moolenbroek case 1:
218*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-rip-req"));
219*b636d99dSDavid van Moolenbroek if (length > 0) {
220*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[3]);
221*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
222*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])));
223*b636d99dSDavid van Moolenbroek }
224*b636d99dSDavid van Moolenbroek break;
225*b636d99dSDavid van Moolenbroek case 2:
226*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-rip-resp"));
227*b636d99dSDavid van Moolenbroek for (i = 0; i < 50 && length > 0; i++) {
228*b636d99dSDavid van Moolenbroek ND_TCHECK(ipx[3]);
229*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
230*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])));
231*b636d99dSDavid van Moolenbroek
232*b636d99dSDavid van Moolenbroek ipx += 4;
233*b636d99dSDavid van Moolenbroek length -= 8;
234*b636d99dSDavid van Moolenbroek }
235*b636d99dSDavid van Moolenbroek break;
236*b636d99dSDavid van Moolenbroek default:
237*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ipx-rip-?%x", command));
238*b636d99dSDavid van Moolenbroek break;
239*b636d99dSDavid van Moolenbroek }
240*b636d99dSDavid van Moolenbroek return;
241*b636d99dSDavid van Moolenbroek trunc:
242*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|ipx %d]", length));
243*b636d99dSDavid van Moolenbroek }
244