xref: /minix3/external/bsd/tcpdump/dist/print-ipx.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
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