xref: /openbsd/usr.sbin/tcpdump/print-ipx.c (revision f96bb33f)
1 /*	$OpenBSD: print-ipx.c,v 1.16 2020/01/24 22:46:37 procter Exp $	*/
2 
3 /*
4  * Copyright (c) 1994, 1995, 1996
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  * Format and print Novell IPX packets.
24  * Contributed by Brad Parker (brad@fcr.com).
25  */
26 
27 #include <sys/time.h>
28 #include <sys/socket.h>
29 
30 #include <netinet/in.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip_var.h>
33 #include <netinet/udp.h>
34 #include <netinet/udp_var.h>
35 #include <netinet/tcp.h>
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include "interface.h"
42 #include "addrtoname.h"
43 #include "ipx.h"
44 #include "extract.h"
45 
46 
47 static const char *ipxaddr_string(u_int32_t, const u_char *);
48 void ipx_decode(const struct ipxHdr *, const u_char *, u_int);
49 void ipx_sap_print(const u_short *, u_int);
50 void ipx_rip_print(const u_short *, u_int);
51 
52 /*
53  * Print IPX datagram packets.
54  */
55 void
ipx_print(const u_char * p,u_int length)56 ipx_print(const u_char *p, u_int length)
57 {
58 	const struct ipxHdr *ipx = (const struct ipxHdr *)p;
59 
60 	TCHECK(ipx->srcSkt);
61 	printf("%s.%x > ",
62 	    ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
63 	    EXTRACT_16BITS(&ipx->srcSkt));
64 
65 	printf("%s.%x:",
66 	    ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
67 	    EXTRACT_16BITS(&ipx->dstSkt));
68 
69 	/* take length from ipx header */
70 	TCHECK(ipx->length);
71 	length = EXTRACT_16BITS(&ipx->length);
72 
73 	ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
74 	return;
75 trunc:
76 	printf("[|ipx %d]", length);
77 }
78 
79 static const char *
ipxaddr_string(u_int32_t net,const u_char * node)80 ipxaddr_string(u_int32_t net, const u_char *node)
81 {
82     static char line[256];
83 
84     snprintf(line, sizeof(line), "%x.%02x:%02x:%02x:%02x:%02x:%02x",
85 	    net, node[0], node[1], node[2], node[3], node[4], node[5]);
86 
87     return line;
88 }
89 
90 void
ipx_decode(const struct ipxHdr * ipx,const u_char * datap,u_int length)91 ipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length)
92 {
93     u_short dstSkt;
94 
95     dstSkt = EXTRACT_16BITS(&ipx->dstSkt);
96     switch (dstSkt) {
97       case IPX_SKT_NCP:
98 	printf(" ipx-ncp %d", length);
99 	break;
100       case IPX_SKT_SAP:
101 	ipx_sap_print((u_short *)datap, length);
102 	break;
103       case IPX_SKT_RIP:
104 	ipx_rip_print((u_short *)datap, length);
105 	break;
106       case IPX_SKT_NETBIOS:
107 	printf(" ipx-netbios %d", length);
108 	break;
109       case IPX_SKT_DIAGNOSTICS:
110 	printf(" ipx-diags %d", length);
111 	break;
112       default:
113 	printf(" ipx-#%x %d", dstSkt, length);
114 	break;
115     }
116 }
117 
118 void
ipx_sap_print(const u_short * ipx,u_int length)119 ipx_sap_print(const u_short *ipx, u_int length)
120 {
121     int command, i;
122 
123     TCHECK(ipx[0]);
124     command = EXTRACT_16BITS(ipx);
125     ipx++;
126     length -= 2;
127 
128     switch (command) {
129       case 1:
130       case 3:
131 	if (command == 1)
132 	    printf("ipx-sap-req");
133 	else
134 	    printf("ipx-sap-nearest-req");
135 
136 	if (length > 0) {
137 	    TCHECK(ipx[1]);
138 	    printf(" %x '", EXTRACT_16BITS(&ipx[0]));
139 	    fn_print((u_char *)&ipx[1], min(snapend, (u_char *)&ipx[1] + 48));
140 	    putchar('\'');
141 	}
142 	break;
143 
144       case 2:
145       case 4:
146 	if (command == 2)
147 	    printf("ipx-sap-resp");
148 	else
149 	    printf("ipx-sap-nearest-resp");
150 
151 	for (i = 0; i < 8 && length > 0; i++) {
152 	    TCHECK2(ipx[27], 1);
153 	    printf(" %x '", EXTRACT_16BITS(&ipx[0]));
154 	    fn_print((u_char *)&ipx[1], min(snapend, (u_char *)&ipx[1] + 48));
155 	    printf("' addr %s",
156 		ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27]));
157 	    ipx += 32;
158 	    length -= 64;
159 	}
160 	break;
161       default:
162 	    printf("ipx-sap-?%x", command);
163 	break;
164     }
165 	return;
166 trunc:
167 	printf("[|ipx %d]", length);
168 }
169 
170 void
ipx_rip_print(const u_short * ipx,u_int length)171 ipx_rip_print(const u_short *ipx, u_int length)
172 {
173     int command, i;
174 
175     TCHECK(ipx[0]);
176     command = EXTRACT_16BITS(ipx);
177     ipx++;
178     length -= 2;
179 
180     switch (command) {
181       case 1:
182 	printf("ipx-rip-req");
183 	if (length > 0) {
184 	    TCHECK(ipx[3]);
185 	    printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]),
186 		EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
187 	}
188 	break;
189       case 2:
190 	printf("ipx-rip-resp");
191 	for (i = 0; i < 50 && length > 0; i++) {
192 	    TCHECK(ipx[3]);
193 	    printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]),
194 		EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
195 
196 	    ipx += 4;
197 	    length -= 8;
198 	}
199 	break;
200       default:
201 	    printf("ipx-rip-?%x", command);
202     }
203 	return;
204 trunc:
205 	printf("[|ipx %d]", length);
206 }
207 
208