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
47static const char *ipxaddr_string(u_int32_t, const u_char *);
48void ipx_decode(const struct ipxHdr *, const u_char *, u_int);
49void ipx_sap_print(const u_short *, u_int);
50void ipx_rip_print(const u_short *, u_int);
51
52/*
53 * Print IPX datagram packets.
54 */
55void
56ipx_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;
75trunc:
76	printf("[|ipx %d]", length);
77}
78
79static const char *
80ipxaddr_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
90void
91ipx_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
118void
119ipx_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;
166trunc:
167	printf("[|ipx %d]", length);
168}
169
170void
171ipx_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;
204trunc:
205	printf("[|ipx %d]", length);
206}
207
208