xref: /minix3/external/bsd/tcpdump/dist/print-atalk.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
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 AppleTalk packets.
22*b636d99dSDavid van Moolenbroek  */
23*b636d99dSDavid van Moolenbroek 
24*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
25*b636d99dSDavid van Moolenbroek #ifndef lint
26*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-atalk.c,v 1.5 2014/11/20 03:05:03 christos Exp $");
27*b636d99dSDavid van Moolenbroek #endif
28*b636d99dSDavid van Moolenbroek 
29*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
30*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
31*b636d99dSDavid van Moolenbroek #include "config.h"
32*b636d99dSDavid van Moolenbroek #endif
33*b636d99dSDavid van Moolenbroek 
34*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
35*b636d99dSDavid van Moolenbroek 
36*b636d99dSDavid van Moolenbroek #include <stdio.h>
37*b636d99dSDavid van Moolenbroek #include <string.h>
38*b636d99dSDavid van Moolenbroek 
39*b636d99dSDavid van Moolenbroek #include "interface.h"
40*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
41*b636d99dSDavid van Moolenbroek #include "ethertype.h"
42*b636d99dSDavid van Moolenbroek #include "extract.h"			/* must come after interface.h */
43*b636d99dSDavid van Moolenbroek #include "appletalk.h"
44*b636d99dSDavid van Moolenbroek 
45*b636d99dSDavid van Moolenbroek static const char tstr[] = "[|atalk]";
46*b636d99dSDavid van Moolenbroek 
47*b636d99dSDavid van Moolenbroek static const struct tok type2str[] = {
48*b636d99dSDavid van Moolenbroek 	{ ddpRTMP,		"rtmp" },
49*b636d99dSDavid van Moolenbroek 	{ ddpRTMPrequest,	"rtmpReq" },
50*b636d99dSDavid van Moolenbroek 	{ ddpECHO,		"echo" },
51*b636d99dSDavid van Moolenbroek 	{ ddpIP,		"IP" },
52*b636d99dSDavid van Moolenbroek 	{ ddpARP,		"ARP" },
53*b636d99dSDavid van Moolenbroek 	{ ddpKLAP,		"KLAP" },
54*b636d99dSDavid van Moolenbroek 	{ 0,			NULL }
55*b636d99dSDavid van Moolenbroek };
56*b636d99dSDavid van Moolenbroek 
57*b636d99dSDavid van Moolenbroek struct aarp {
58*b636d99dSDavid van Moolenbroek 	uint16_t	htype, ptype;
59*b636d99dSDavid van Moolenbroek 	uint8_t		halen, palen;
60*b636d99dSDavid van Moolenbroek 	uint16_t	op;
61*b636d99dSDavid van Moolenbroek 	uint8_t		hsaddr[6];
62*b636d99dSDavid van Moolenbroek 	uint8_t		psaddr[4];
63*b636d99dSDavid van Moolenbroek 	uint8_t		hdaddr[6];
64*b636d99dSDavid van Moolenbroek 	uint8_t		pdaddr[4];
65*b636d99dSDavid van Moolenbroek };
66*b636d99dSDavid van Moolenbroek 
67*b636d99dSDavid van Moolenbroek static void atp_print(netdissect_options *, const struct atATP *, u_int);
68*b636d99dSDavid van Moolenbroek static void atp_bitmap_print(netdissect_options *, u_char);
69*b636d99dSDavid van Moolenbroek static void nbp_print(netdissect_options *, const struct atNBP *, u_int, u_short, u_char, u_char);
70*b636d99dSDavid van Moolenbroek static const struct atNBPtuple *nbp_tuple_print(netdissect_options *ndo, const struct atNBPtuple *,
71*b636d99dSDavid van Moolenbroek 						const u_char *,
72*b636d99dSDavid van Moolenbroek 						u_short, u_char, u_char);
73*b636d99dSDavid van Moolenbroek static const struct atNBPtuple *nbp_name_print(netdissect_options *, const struct atNBPtuple *,
74*b636d99dSDavid van Moolenbroek 					       const u_char *);
75*b636d99dSDavid van Moolenbroek static const char *ataddr_string(netdissect_options *, u_short, u_char);
76*b636d99dSDavid van Moolenbroek static void ddp_print(netdissect_options *, const u_char *, u_int, int, u_short, u_char, u_char);
77*b636d99dSDavid van Moolenbroek static const char *ddpskt_string(netdissect_options *, int);
78*b636d99dSDavid van Moolenbroek 
79*b636d99dSDavid van Moolenbroek /*
80*b636d99dSDavid van Moolenbroek  * Print LLAP packets received on a physical LocalTalk interface.
81*b636d99dSDavid van Moolenbroek  */
82*b636d99dSDavid van Moolenbroek u_int
ltalk_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)83*b636d99dSDavid van Moolenbroek ltalk_if_print(netdissect_options *ndo,
84*b636d99dSDavid van Moolenbroek                const struct pcap_pkthdr *h, const u_char *p)
85*b636d99dSDavid van Moolenbroek {
86*b636d99dSDavid van Moolenbroek 	return (llap_print(ndo, p, h->caplen));
87*b636d99dSDavid van Moolenbroek }
88*b636d99dSDavid van Moolenbroek 
89*b636d99dSDavid van Moolenbroek /*
90*b636d99dSDavid van Moolenbroek  * Print AppleTalk LLAP packets.
91*b636d99dSDavid van Moolenbroek  */
92*b636d99dSDavid van Moolenbroek u_int
llap_print(netdissect_options * ndo,register const u_char * bp,u_int length)93*b636d99dSDavid van Moolenbroek llap_print(netdissect_options *ndo,
94*b636d99dSDavid van Moolenbroek            register const u_char *bp, u_int length)
95*b636d99dSDavid van Moolenbroek {
96*b636d99dSDavid van Moolenbroek 	register const struct LAP *lp;
97*b636d99dSDavid van Moolenbroek 	register const struct atDDP *dp;
98*b636d99dSDavid van Moolenbroek 	register const struct atShortDDP *sdp;
99*b636d99dSDavid van Moolenbroek 	u_short snet;
100*b636d99dSDavid van Moolenbroek 	u_int hdrlen;
101*b636d99dSDavid van Moolenbroek 
102*b636d99dSDavid van Moolenbroek 	if (length < sizeof(*lp)) {
103*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [|llap %u]", length));
104*b636d99dSDavid van Moolenbroek 		return (length);
105*b636d99dSDavid van Moolenbroek 	}
106*b636d99dSDavid van Moolenbroek 	lp = (const struct LAP *)bp;
107*b636d99dSDavid van Moolenbroek 	bp += sizeof(*lp);
108*b636d99dSDavid van Moolenbroek 	length -= sizeof(*lp);
109*b636d99dSDavid van Moolenbroek 	hdrlen = sizeof(*lp);
110*b636d99dSDavid van Moolenbroek 	switch (lp->type) {
111*b636d99dSDavid van Moolenbroek 
112*b636d99dSDavid van Moolenbroek 	case lapShortDDP:
113*b636d99dSDavid van Moolenbroek 		if (length < ddpSSize) {
114*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [|sddp %u]", length));
115*b636d99dSDavid van Moolenbroek 			return (length);
116*b636d99dSDavid van Moolenbroek 		}
117*b636d99dSDavid van Moolenbroek 		sdp = (const struct atShortDDP *)bp;
118*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s.%s",
119*b636d99dSDavid van Moolenbroek 		    ataddr_string(ndo, 0, lp->src), ddpskt_string(ndo, sdp->srcSkt)));
120*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " > %s.%s:",
121*b636d99dSDavid van Moolenbroek 		    ataddr_string(ndo, 0, lp->dst), ddpskt_string(ndo, sdp->dstSkt)));
122*b636d99dSDavid van Moolenbroek 		bp += ddpSSize;
123*b636d99dSDavid van Moolenbroek 		length -= ddpSSize;
124*b636d99dSDavid van Moolenbroek 		hdrlen += ddpSSize;
125*b636d99dSDavid van Moolenbroek 		ddp_print(ndo, bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
126*b636d99dSDavid van Moolenbroek 		break;
127*b636d99dSDavid van Moolenbroek 
128*b636d99dSDavid van Moolenbroek 	case lapDDP:
129*b636d99dSDavid van Moolenbroek 		if (length < ddpSize) {
130*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [|ddp %u]", length));
131*b636d99dSDavid van Moolenbroek 			return (length);
132*b636d99dSDavid van Moolenbroek 		}
133*b636d99dSDavid van Moolenbroek 		dp = (const struct atDDP *)bp;
134*b636d99dSDavid van Moolenbroek 		snet = EXTRACT_16BITS(&dp->srcNet);
135*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode),
136*b636d99dSDavid van Moolenbroek 		    ddpskt_string(ndo, dp->srcSkt)));
137*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " > %s.%s:",
138*b636d99dSDavid van Moolenbroek 		    ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
139*b636d99dSDavid van Moolenbroek 		    ddpskt_string(ndo, dp->dstSkt)));
140*b636d99dSDavid van Moolenbroek 		bp += ddpSize;
141*b636d99dSDavid van Moolenbroek 		length -= ddpSize;
142*b636d99dSDavid van Moolenbroek 		hdrlen += ddpSize;
143*b636d99dSDavid van Moolenbroek 		ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
144*b636d99dSDavid van Moolenbroek 		break;
145*b636d99dSDavid van Moolenbroek 
146*b636d99dSDavid van Moolenbroek #ifdef notdef
147*b636d99dSDavid van Moolenbroek 	case lapKLAP:
148*b636d99dSDavid van Moolenbroek 		klap_print(bp, length);
149*b636d99dSDavid van Moolenbroek 		break;
150*b636d99dSDavid van Moolenbroek #endif
151*b636d99dSDavid van Moolenbroek 
152*b636d99dSDavid van Moolenbroek 	default:
153*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%d > %d at-lap#%d %u",
154*b636d99dSDavid van Moolenbroek 		    lp->src, lp->dst, lp->type, length));
155*b636d99dSDavid van Moolenbroek 		break;
156*b636d99dSDavid van Moolenbroek 	}
157*b636d99dSDavid van Moolenbroek 	return (hdrlen);
158*b636d99dSDavid van Moolenbroek }
159*b636d99dSDavid van Moolenbroek 
160*b636d99dSDavid van Moolenbroek /*
161*b636d99dSDavid van Moolenbroek  * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
162*b636d99dSDavid van Moolenbroek  * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
163*b636d99dSDavid van Moolenbroek  * packets in them).
164*b636d99dSDavid van Moolenbroek  */
165*b636d99dSDavid van Moolenbroek void
atalk_print(netdissect_options * ndo,register const u_char * bp,u_int length)166*b636d99dSDavid van Moolenbroek atalk_print(netdissect_options *ndo,
167*b636d99dSDavid van Moolenbroek             register const u_char *bp, u_int length)
168*b636d99dSDavid van Moolenbroek {
169*b636d99dSDavid van Moolenbroek 	register const struct atDDP *dp;
170*b636d99dSDavid van Moolenbroek 	u_short snet;
171*b636d99dSDavid van Moolenbroek 
172*b636d99dSDavid van Moolenbroek         if(!ndo->ndo_eflag)
173*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, "AT "));
174*b636d99dSDavid van Moolenbroek 
175*b636d99dSDavid van Moolenbroek 	if (length < ddpSize) {
176*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [|ddp %u]", length));
177*b636d99dSDavid van Moolenbroek 		return;
178*b636d99dSDavid van Moolenbroek 	}
179*b636d99dSDavid van Moolenbroek 	dp = (const struct atDDP *)bp;
180*b636d99dSDavid van Moolenbroek 	snet = EXTRACT_16BITS(&dp->srcNet);
181*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode),
182*b636d99dSDavid van Moolenbroek 	       ddpskt_string(ndo, dp->srcSkt)));
183*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " > %s.%s: ",
184*b636d99dSDavid van Moolenbroek 	       ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
185*b636d99dSDavid van Moolenbroek 	       ddpskt_string(ndo, dp->dstSkt)));
186*b636d99dSDavid van Moolenbroek 	bp += ddpSize;
187*b636d99dSDavid van Moolenbroek 	length -= ddpSize;
188*b636d99dSDavid van Moolenbroek 	ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
189*b636d99dSDavid van Moolenbroek }
190*b636d99dSDavid van Moolenbroek 
191*b636d99dSDavid van Moolenbroek /* XXX should probably pass in the snap header and do checks like arp_print() */
192*b636d99dSDavid van Moolenbroek void
aarp_print(netdissect_options * ndo,register const u_char * bp,u_int length)193*b636d99dSDavid van Moolenbroek aarp_print(netdissect_options *ndo,
194*b636d99dSDavid van Moolenbroek            register const u_char *bp, u_int length)
195*b636d99dSDavid van Moolenbroek {
196*b636d99dSDavid van Moolenbroek 	register const struct aarp *ap;
197*b636d99dSDavid van Moolenbroek 
198*b636d99dSDavid van Moolenbroek #define AT(member) ataddr_string(ndo, (ap->member[1]<<8)|ap->member[2],ap->member[3])
199*b636d99dSDavid van Moolenbroek 
200*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "aarp "));
201*b636d99dSDavid van Moolenbroek 	ap = (const struct aarp *)bp;
202*b636d99dSDavid van Moolenbroek 	if (EXTRACT_16BITS(&ap->htype) == 1 &&
203*b636d99dSDavid van Moolenbroek 	    EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK &&
204*b636d99dSDavid van Moolenbroek 	    ap->halen == 6 && ap->palen == 4 )
205*b636d99dSDavid van Moolenbroek 		switch (EXTRACT_16BITS(&ap->op)) {
206*b636d99dSDavid van Moolenbroek 
207*b636d99dSDavid van Moolenbroek 		case 1:				/* request */
208*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "who-has %s tell %s", AT(pdaddr), AT(psaddr)));
209*b636d99dSDavid van Moolenbroek 			return;
210*b636d99dSDavid van Moolenbroek 
211*b636d99dSDavid van Moolenbroek 		case 2:				/* response */
212*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "reply %s is-at %s", AT(psaddr), etheraddr_string(ndo, ap->hsaddr)));
213*b636d99dSDavid van Moolenbroek 			return;
214*b636d99dSDavid van Moolenbroek 
215*b636d99dSDavid van Moolenbroek 		case 3:				/* probe (oy!) */
216*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "probe %s tell %s", AT(pdaddr), AT(psaddr)));
217*b636d99dSDavid van Moolenbroek 			return;
218*b636d99dSDavid van Moolenbroek 		}
219*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "len %u op %u htype %u ptype %#x halen %u palen %u",
220*b636d99dSDavid van Moolenbroek 	    length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype),
221*b636d99dSDavid van Moolenbroek 	    EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen));
222*b636d99dSDavid van Moolenbroek }
223*b636d99dSDavid van Moolenbroek 
224*b636d99dSDavid van Moolenbroek /*
225*b636d99dSDavid van Moolenbroek  * Print AppleTalk Datagram Delivery Protocol packets.
226*b636d99dSDavid van Moolenbroek  */
227*b636d99dSDavid van Moolenbroek static void
ddp_print(netdissect_options * ndo,register const u_char * bp,register u_int length,register int t,register u_short snet,register u_char snode,u_char skt)228*b636d99dSDavid van Moolenbroek ddp_print(netdissect_options *ndo,
229*b636d99dSDavid van Moolenbroek           register const u_char *bp, register u_int length, register int t,
230*b636d99dSDavid van Moolenbroek           register u_short snet, register u_char snode, u_char skt)
231*b636d99dSDavid van Moolenbroek {
232*b636d99dSDavid van Moolenbroek 
233*b636d99dSDavid van Moolenbroek 	switch (t) {
234*b636d99dSDavid van Moolenbroek 
235*b636d99dSDavid van Moolenbroek 	case ddpNBP:
236*b636d99dSDavid van Moolenbroek 		nbp_print(ndo, (const struct atNBP *)bp, length, snet, snode, skt);
237*b636d99dSDavid van Moolenbroek 		break;
238*b636d99dSDavid van Moolenbroek 
239*b636d99dSDavid van Moolenbroek 	case ddpATP:
240*b636d99dSDavid van Moolenbroek 		atp_print(ndo, (const struct atATP *)bp, length);
241*b636d99dSDavid van Moolenbroek 		break;
242*b636d99dSDavid van Moolenbroek 
243*b636d99dSDavid van Moolenbroek 	case ddpEIGRP:
244*b636d99dSDavid van Moolenbroek 		eigrp_print(ndo, bp, length);
245*b636d99dSDavid van Moolenbroek 		break;
246*b636d99dSDavid van Moolenbroek 
247*b636d99dSDavid van Moolenbroek 	default:
248*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " at-%s %d", tok2str(type2str, NULL, t), length));
249*b636d99dSDavid van Moolenbroek 		break;
250*b636d99dSDavid van Moolenbroek 	}
251*b636d99dSDavid van Moolenbroek }
252*b636d99dSDavid van Moolenbroek 
253*b636d99dSDavid van Moolenbroek static void
atp_print(netdissect_options * ndo,register const struct atATP * ap,u_int length)254*b636d99dSDavid van Moolenbroek atp_print(netdissect_options *ndo,
255*b636d99dSDavid van Moolenbroek           register const struct atATP *ap, u_int length)
256*b636d99dSDavid van Moolenbroek {
257*b636d99dSDavid van Moolenbroek 	char c;
258*b636d99dSDavid van Moolenbroek 	uint32_t data;
259*b636d99dSDavid van Moolenbroek 
260*b636d99dSDavid van Moolenbroek 	if ((const u_char *)(ap + 1) > ndo->ndo_snapend) {
261*b636d99dSDavid van Moolenbroek 		/* Just bail if we don't have the whole chunk. */
262*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s", tstr));
263*b636d99dSDavid van Moolenbroek 		return;
264*b636d99dSDavid van Moolenbroek 	}
265*b636d99dSDavid van Moolenbroek 	if (length < sizeof(*ap)) {
266*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [|atp %u]", length));
267*b636d99dSDavid van Moolenbroek 		return;
268*b636d99dSDavid van Moolenbroek 	}
269*b636d99dSDavid van Moolenbroek 	length -= sizeof(*ap);
270*b636d99dSDavid van Moolenbroek 	switch (ap->control & 0xc0) {
271*b636d99dSDavid van Moolenbroek 
272*b636d99dSDavid van Moolenbroek 	case atpReqCode:
273*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " atp-req%s %d",
274*b636d99dSDavid van Moolenbroek 			     ap->control & atpXO? " " : "*",
275*b636d99dSDavid van Moolenbroek 			     EXTRACT_16BITS(&ap->transID)));
276*b636d99dSDavid van Moolenbroek 
277*b636d99dSDavid van Moolenbroek 		atp_bitmap_print(ndo, ap->bitmap);
278*b636d99dSDavid van Moolenbroek 
279*b636d99dSDavid van Moolenbroek 		if (length != 0)
280*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [len=%u]", length));
281*b636d99dSDavid van Moolenbroek 
282*b636d99dSDavid van Moolenbroek 		switch (ap->control & (atpEOM|atpSTS)) {
283*b636d99dSDavid van Moolenbroek 		case atpEOM:
284*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [EOM]"));
285*b636d99dSDavid van Moolenbroek 			break;
286*b636d99dSDavid van Moolenbroek 		case atpSTS:
287*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [STS]"));
288*b636d99dSDavid van Moolenbroek 			break;
289*b636d99dSDavid van Moolenbroek 		case atpEOM|atpSTS:
290*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [EOM,STS]"));
291*b636d99dSDavid van Moolenbroek 			break;
292*b636d99dSDavid van Moolenbroek 		}
293*b636d99dSDavid van Moolenbroek 		break;
294*b636d99dSDavid van Moolenbroek 
295*b636d99dSDavid van Moolenbroek 	case atpRspCode:
296*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " atp-resp%s%d:%d (%u)",
297*b636d99dSDavid van Moolenbroek 			     ap->control & atpEOM? "*" : " ",
298*b636d99dSDavid van Moolenbroek 			     EXTRACT_16BITS(&ap->transID), ap->bitmap, length));
299*b636d99dSDavid van Moolenbroek 		switch (ap->control & (atpXO|atpSTS)) {
300*b636d99dSDavid van Moolenbroek 		case atpXO:
301*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [XO]"));
302*b636d99dSDavid van Moolenbroek 			break;
303*b636d99dSDavid van Moolenbroek 		case atpSTS:
304*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [STS]"));
305*b636d99dSDavid van Moolenbroek 			break;
306*b636d99dSDavid van Moolenbroek 		case atpXO|atpSTS:
307*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [XO,STS]"));
308*b636d99dSDavid van Moolenbroek 			break;
309*b636d99dSDavid van Moolenbroek 		}
310*b636d99dSDavid van Moolenbroek 		break;
311*b636d99dSDavid van Moolenbroek 
312*b636d99dSDavid van Moolenbroek 	case atpRelCode:
313*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " atp-rel  %d", EXTRACT_16BITS(&ap->transID)));
314*b636d99dSDavid van Moolenbroek 
315*b636d99dSDavid van Moolenbroek 		atp_bitmap_print(ndo, ap->bitmap);
316*b636d99dSDavid van Moolenbroek 
317*b636d99dSDavid van Moolenbroek 		/* length should be zero */
318*b636d99dSDavid van Moolenbroek 		if (length)
319*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [len=%u]", length));
320*b636d99dSDavid van Moolenbroek 
321*b636d99dSDavid van Moolenbroek 		/* there shouldn't be any control flags */
322*b636d99dSDavid van Moolenbroek 		if (ap->control & (atpXO|atpEOM|atpSTS)) {
323*b636d99dSDavid van Moolenbroek 			c = '[';
324*b636d99dSDavid van Moolenbroek 			if (ap->control & atpXO) {
325*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%cXO", c));
326*b636d99dSDavid van Moolenbroek 				c = ',';
327*b636d99dSDavid van Moolenbroek 			}
328*b636d99dSDavid van Moolenbroek 			if (ap->control & atpEOM) {
329*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%cEOM", c));
330*b636d99dSDavid van Moolenbroek 				c = ',';
331*b636d99dSDavid van Moolenbroek 			}
332*b636d99dSDavid van Moolenbroek 			if (ap->control & atpSTS) {
333*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%cSTS", c));
334*b636d99dSDavid van Moolenbroek 				c = ',';
335*b636d99dSDavid van Moolenbroek 			}
336*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "]"));
337*b636d99dSDavid van Moolenbroek 		}
338*b636d99dSDavid van Moolenbroek 		break;
339*b636d99dSDavid van Moolenbroek 
340*b636d99dSDavid van Moolenbroek 	default:
341*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " atp-0x%x  %d (%u)", ap->control,
342*b636d99dSDavid van Moolenbroek 			     EXTRACT_16BITS(&ap->transID), length));
343*b636d99dSDavid van Moolenbroek 		break;
344*b636d99dSDavid van Moolenbroek 	}
345*b636d99dSDavid van Moolenbroek 	data = EXTRACT_32BITS(&ap->userData);
346*b636d99dSDavid van Moolenbroek 	if (data != 0)
347*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " 0x%x", data));
348*b636d99dSDavid van Moolenbroek }
349*b636d99dSDavid van Moolenbroek 
350*b636d99dSDavid van Moolenbroek static void
atp_bitmap_print(netdissect_options * ndo,register u_char bm)351*b636d99dSDavid van Moolenbroek atp_bitmap_print(netdissect_options *ndo,
352*b636d99dSDavid van Moolenbroek                  register u_char bm)
353*b636d99dSDavid van Moolenbroek {
354*b636d99dSDavid van Moolenbroek 	register char c;
355*b636d99dSDavid van Moolenbroek 	register int i;
356*b636d99dSDavid van Moolenbroek 
357*b636d99dSDavid van Moolenbroek 	/*
358*b636d99dSDavid van Moolenbroek 	 * The '& 0xff' below is needed for compilers that want to sign
359*b636d99dSDavid van Moolenbroek 	 * extend a u_char, which is the case with the Ultrix compiler.
360*b636d99dSDavid van Moolenbroek 	 * (gcc is smart enough to eliminate it, at least on the Sparc).
361*b636d99dSDavid van Moolenbroek 	 */
362*b636d99dSDavid van Moolenbroek 	if ((bm + 1) & (bm & 0xff)) {
363*b636d99dSDavid van Moolenbroek 		c = '<';
364*b636d99dSDavid van Moolenbroek 		for (i = 0; bm; ++i) {
365*b636d99dSDavid van Moolenbroek 			if (bm & 1) {
366*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%c%d", c, i));
367*b636d99dSDavid van Moolenbroek 				c = ',';
368*b636d99dSDavid van Moolenbroek 			}
369*b636d99dSDavid van Moolenbroek 			bm >>= 1;
370*b636d99dSDavid van Moolenbroek 		}
371*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ">"));
372*b636d99dSDavid van Moolenbroek 	} else {
373*b636d99dSDavid van Moolenbroek 		for (i = 0; bm; ++i)
374*b636d99dSDavid van Moolenbroek 			bm >>= 1;
375*b636d99dSDavid van Moolenbroek 		if (i > 1)
376*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "<0-%d>", i - 1));
377*b636d99dSDavid van Moolenbroek 		else
378*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "<0>"));
379*b636d99dSDavid van Moolenbroek 	}
380*b636d99dSDavid van Moolenbroek }
381*b636d99dSDavid van Moolenbroek 
382*b636d99dSDavid van Moolenbroek static void
nbp_print(netdissect_options * ndo,register const struct atNBP * np,u_int length,register u_short snet,register u_char snode,register u_char skt)383*b636d99dSDavid van Moolenbroek nbp_print(netdissect_options *ndo,
384*b636d99dSDavid van Moolenbroek           register const struct atNBP *np, u_int length, register u_short snet,
385*b636d99dSDavid van Moolenbroek           register u_char snode, register u_char skt)
386*b636d99dSDavid van Moolenbroek {
387*b636d99dSDavid van Moolenbroek 	register const struct atNBPtuple *tp =
388*b636d99dSDavid van Moolenbroek 		(const struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
389*b636d99dSDavid van Moolenbroek 	int i;
390*b636d99dSDavid van Moolenbroek 	const u_char *ep;
391*b636d99dSDavid van Moolenbroek 
392*b636d99dSDavid van Moolenbroek 	if (length < nbpHeaderSize) {
393*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " truncated-nbp %u", length));
394*b636d99dSDavid van Moolenbroek 		return;
395*b636d99dSDavid van Moolenbroek 	}
396*b636d99dSDavid van Moolenbroek 
397*b636d99dSDavid van Moolenbroek 	length -= nbpHeaderSize;
398*b636d99dSDavid van Moolenbroek 	if (length < 8) {
399*b636d99dSDavid van Moolenbroek 		/* must be room for at least one tuple */
400*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " truncated-nbp %u", length + nbpHeaderSize));
401*b636d99dSDavid van Moolenbroek 		return;
402*b636d99dSDavid van Moolenbroek 	}
403*b636d99dSDavid van Moolenbroek 	/* ep points to end of available data */
404*b636d99dSDavid van Moolenbroek 	ep = ndo->ndo_snapend;
405*b636d99dSDavid van Moolenbroek 	if ((const u_char *)tp > ep) {
406*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s", tstr));
407*b636d99dSDavid van Moolenbroek 		return;
408*b636d99dSDavid van Moolenbroek 	}
409*b636d99dSDavid van Moolenbroek 	switch (i = np->control & 0xf0) {
410*b636d99dSDavid van Moolenbroek 
411*b636d99dSDavid van Moolenbroek 	case nbpBrRq:
412*b636d99dSDavid van Moolenbroek 	case nbpLkUp:
413*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", np->id));
414*b636d99dSDavid van Moolenbroek 		if ((const u_char *)(tp + 1) > ep) {
415*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s", tstr));
416*b636d99dSDavid van Moolenbroek 			return;
417*b636d99dSDavid van Moolenbroek 		}
418*b636d99dSDavid van Moolenbroek 		(void)nbp_name_print(ndo, tp, ep);
419*b636d99dSDavid van Moolenbroek 		/*
420*b636d99dSDavid van Moolenbroek 		 * look for anomalies: the spec says there can only
421*b636d99dSDavid van Moolenbroek 		 * be one tuple, the address must match the source
422*b636d99dSDavid van Moolenbroek 		 * address and the enumerator should be zero.
423*b636d99dSDavid van Moolenbroek 		 */
424*b636d99dSDavid van Moolenbroek 		if ((np->control & 0xf) != 1)
425*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [ntup=%d]", np->control & 0xf));
426*b636d99dSDavid van Moolenbroek 		if (tp->enumerator)
427*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [enum=%d]", tp->enumerator));
428*b636d99dSDavid van Moolenbroek 		if (EXTRACT_16BITS(&tp->net) != snet ||
429*b636d99dSDavid van Moolenbroek 		    tp->node != snode || tp->skt != skt)
430*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [addr=%s.%d]",
431*b636d99dSDavid van Moolenbroek 			    ataddr_string(ndo, EXTRACT_16BITS(&tp->net),
432*b636d99dSDavid van Moolenbroek 			    tp->node), tp->skt));
433*b636d99dSDavid van Moolenbroek 		break;
434*b636d99dSDavid van Moolenbroek 
435*b636d99dSDavid van Moolenbroek 	case nbpLkUpReply:
436*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " nbp-reply %d:", np->id));
437*b636d99dSDavid van Moolenbroek 
438*b636d99dSDavid van Moolenbroek 		/* print each of the tuples in the reply */
439*b636d99dSDavid van Moolenbroek 		for (i = np->control & 0xf; --i >= 0 && tp; )
440*b636d99dSDavid van Moolenbroek 			tp = nbp_tuple_print(ndo, tp, ep, snet, snode, skt);
441*b636d99dSDavid van Moolenbroek 		break;
442*b636d99dSDavid van Moolenbroek 
443*b636d99dSDavid van Moolenbroek 	default:
444*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " nbp-0x%x  %d (%u)", np->control, np->id, length));
445*b636d99dSDavid van Moolenbroek 		break;
446*b636d99dSDavid van Moolenbroek 	}
447*b636d99dSDavid van Moolenbroek }
448*b636d99dSDavid van Moolenbroek 
449*b636d99dSDavid van Moolenbroek /* print a counted string */
450*b636d99dSDavid van Moolenbroek static const char *
print_cstring(netdissect_options * ndo,register const char * cp,register const u_char * ep)451*b636d99dSDavid van Moolenbroek print_cstring(netdissect_options *ndo,
452*b636d99dSDavid van Moolenbroek               register const char *cp, register const u_char *ep)
453*b636d99dSDavid van Moolenbroek {
454*b636d99dSDavid van Moolenbroek 	register u_int length;
455*b636d99dSDavid van Moolenbroek 
456*b636d99dSDavid van Moolenbroek 	if (cp >= (const char *)ep) {
457*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s", tstr));
458*b636d99dSDavid van Moolenbroek 		return (0);
459*b636d99dSDavid van Moolenbroek 	}
460*b636d99dSDavid van Moolenbroek 	length = *cp++;
461*b636d99dSDavid van Moolenbroek 
462*b636d99dSDavid van Moolenbroek 	/* Spec says string can be at most 32 bytes long */
463*b636d99dSDavid van Moolenbroek 	if (length > 32) {
464*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[len=%u]", length));
465*b636d99dSDavid van Moolenbroek 		return (0);
466*b636d99dSDavid van Moolenbroek 	}
467*b636d99dSDavid van Moolenbroek 	while ((int)--length >= 0) {
468*b636d99dSDavid van Moolenbroek 		if (cp >= (const char *)ep) {
469*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s", tstr));
470*b636d99dSDavid van Moolenbroek 			return (0);
471*b636d99dSDavid van Moolenbroek 		}
472*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%c", *cp++));
473*b636d99dSDavid van Moolenbroek 	}
474*b636d99dSDavid van Moolenbroek 	return (cp);
475*b636d99dSDavid van Moolenbroek }
476*b636d99dSDavid van Moolenbroek 
477*b636d99dSDavid van Moolenbroek static const struct atNBPtuple *
nbp_tuple_print(netdissect_options * ndo,register const struct atNBPtuple * tp,register const u_char * ep,register u_short snet,register u_char snode,register u_char skt)478*b636d99dSDavid van Moolenbroek nbp_tuple_print(netdissect_options *ndo,
479*b636d99dSDavid van Moolenbroek                 register const struct atNBPtuple *tp, register const u_char *ep,
480*b636d99dSDavid van Moolenbroek                 register u_short snet, register u_char snode, register u_char skt)
481*b636d99dSDavid van Moolenbroek {
482*b636d99dSDavid van Moolenbroek 	register const struct atNBPtuple *tpn;
483*b636d99dSDavid van Moolenbroek 
484*b636d99dSDavid van Moolenbroek 	if ((const u_char *)(tp + 1) > ep) {
485*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s", tstr));
486*b636d99dSDavid van Moolenbroek 		return 0;
487*b636d99dSDavid van Moolenbroek 	}
488*b636d99dSDavid van Moolenbroek 	tpn = nbp_name_print(ndo, tp, ep);
489*b636d99dSDavid van Moolenbroek 
490*b636d99dSDavid van Moolenbroek 	/* if the enumerator isn't 1, print it */
491*b636d99dSDavid van Moolenbroek 	if (tp->enumerator != 1)
492*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "(%d)", tp->enumerator));
493*b636d99dSDavid van Moolenbroek 
494*b636d99dSDavid van Moolenbroek 	/* if the socket doesn't match the src socket, print it */
495*b636d99dSDavid van Moolenbroek 	if (tp->skt != skt)
496*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " %d", tp->skt));
497*b636d99dSDavid van Moolenbroek 
498*b636d99dSDavid van Moolenbroek 	/* if the address doesn't match the src address, it's an anomaly */
499*b636d99dSDavid van Moolenbroek 	if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode)
500*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [addr=%s]",
501*b636d99dSDavid van Moolenbroek 		    ataddr_string(ndo, EXTRACT_16BITS(&tp->net), tp->node)));
502*b636d99dSDavid van Moolenbroek 
503*b636d99dSDavid van Moolenbroek 	return (tpn);
504*b636d99dSDavid van Moolenbroek }
505*b636d99dSDavid van Moolenbroek 
506*b636d99dSDavid van Moolenbroek static const struct atNBPtuple *
nbp_name_print(netdissect_options * ndo,const struct atNBPtuple * tp,register const u_char * ep)507*b636d99dSDavid van Moolenbroek nbp_name_print(netdissect_options *ndo,
508*b636d99dSDavid van Moolenbroek                const struct atNBPtuple *tp, register const u_char *ep)
509*b636d99dSDavid van Moolenbroek {
510*b636d99dSDavid van Moolenbroek 	register const char *cp = (const char *)tp + nbpTupleSize;
511*b636d99dSDavid van Moolenbroek 
512*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " "));
513*b636d99dSDavid van Moolenbroek 
514*b636d99dSDavid van Moolenbroek 	/* Object */
515*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\""));
516*b636d99dSDavid van Moolenbroek 	if ((cp = print_cstring(ndo, cp, ep)) != NULL) {
517*b636d99dSDavid van Moolenbroek 		/* Type */
518*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ":"));
519*b636d99dSDavid van Moolenbroek 		if ((cp = print_cstring(ndo, cp, ep)) != NULL) {
520*b636d99dSDavid van Moolenbroek 			/* Zone */
521*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "@"));
522*b636d99dSDavid van Moolenbroek 			if ((cp = print_cstring(ndo, cp, ep)) != NULL)
523*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "\""));
524*b636d99dSDavid van Moolenbroek 		}
525*b636d99dSDavid van Moolenbroek 	}
526*b636d99dSDavid van Moolenbroek 	return ((const struct atNBPtuple *)cp);
527*b636d99dSDavid van Moolenbroek }
528*b636d99dSDavid van Moolenbroek 
529*b636d99dSDavid van Moolenbroek 
530*b636d99dSDavid van Moolenbroek #define HASHNAMESIZE 4096
531*b636d99dSDavid van Moolenbroek 
532*b636d99dSDavid van Moolenbroek struct hnamemem {
533*b636d99dSDavid van Moolenbroek 	int addr;
534*b636d99dSDavid van Moolenbroek 	char *name;
535*b636d99dSDavid van Moolenbroek 	struct hnamemem *nxt;
536*b636d99dSDavid van Moolenbroek };
537*b636d99dSDavid van Moolenbroek 
538*b636d99dSDavid van Moolenbroek static struct hnamemem hnametable[HASHNAMESIZE];
539*b636d99dSDavid van Moolenbroek 
540*b636d99dSDavid van Moolenbroek static const char *
ataddr_string(netdissect_options * ndo,u_short atnet,u_char athost)541*b636d99dSDavid van Moolenbroek ataddr_string(netdissect_options *ndo,
542*b636d99dSDavid van Moolenbroek               u_short atnet, u_char athost)
543*b636d99dSDavid van Moolenbroek {
544*b636d99dSDavid van Moolenbroek 	register struct hnamemem *tp, *tp2;
545*b636d99dSDavid van Moolenbroek 	register int i = (atnet << 8) | athost;
546*b636d99dSDavid van Moolenbroek 	char nambuf[256+1];
547*b636d99dSDavid van Moolenbroek 	static int first = 1;
548*b636d99dSDavid van Moolenbroek 	FILE *fp;
549*b636d99dSDavid van Moolenbroek 
550*b636d99dSDavid van Moolenbroek 	/*
551*b636d99dSDavid van Moolenbroek 	 * if this is the first call, see if there's an AppleTalk
552*b636d99dSDavid van Moolenbroek 	 * number to name map file.
553*b636d99dSDavid van Moolenbroek 	 */
554*b636d99dSDavid van Moolenbroek 	if (first && (first = 0, !ndo->ndo_nflag)
555*b636d99dSDavid van Moolenbroek 	    && (fp = fopen("/etc/atalk.names", "r"))) {
556*b636d99dSDavid van Moolenbroek 		char line[256];
557*b636d99dSDavid van Moolenbroek 		int i1, i2;
558*b636d99dSDavid van Moolenbroek 
559*b636d99dSDavid van Moolenbroek 		while (fgets(line, sizeof(line), fp)) {
560*b636d99dSDavid van Moolenbroek 			if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
561*b636d99dSDavid van Moolenbroek 				continue;
562*b636d99dSDavid van Moolenbroek 			if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3)
563*b636d99dSDavid van Moolenbroek 				/* got a hostname. */
564*b636d99dSDavid van Moolenbroek 				i2 |= (i1 << 8);
565*b636d99dSDavid van Moolenbroek 			else if (sscanf(line, "%d %256s", &i1, nambuf) == 2)
566*b636d99dSDavid van Moolenbroek 				/* got a net name */
567*b636d99dSDavid van Moolenbroek 				i2 = (i1 << 8) | 255;
568*b636d99dSDavid van Moolenbroek 			else
569*b636d99dSDavid van Moolenbroek 				continue;
570*b636d99dSDavid van Moolenbroek 
571*b636d99dSDavid van Moolenbroek 			for (tp = &hnametable[i2 & (HASHNAMESIZE-1)];
572*b636d99dSDavid van Moolenbroek 			     tp->nxt; tp = tp->nxt)
573*b636d99dSDavid van Moolenbroek 				;
574*b636d99dSDavid van Moolenbroek 			tp->addr = i2;
575*b636d99dSDavid van Moolenbroek 			tp->nxt = newhnamemem();
576*b636d99dSDavid van Moolenbroek 			tp->name = strdup(nambuf);
577*b636d99dSDavid van Moolenbroek 		}
578*b636d99dSDavid van Moolenbroek 		fclose(fp);
579*b636d99dSDavid van Moolenbroek 	}
580*b636d99dSDavid van Moolenbroek 
581*b636d99dSDavid van Moolenbroek 	for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
582*b636d99dSDavid van Moolenbroek 		if (tp->addr == i)
583*b636d99dSDavid van Moolenbroek 			return (tp->name);
584*b636d99dSDavid van Moolenbroek 
585*b636d99dSDavid van Moolenbroek 	/* didn't have the node name -- see if we've got the net name */
586*b636d99dSDavid van Moolenbroek 	i |= 255;
587*b636d99dSDavid van Moolenbroek 	for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
588*b636d99dSDavid van Moolenbroek 		if (tp2->addr == i) {
589*b636d99dSDavid van Moolenbroek 			tp->addr = (atnet << 8) | athost;
590*b636d99dSDavid van Moolenbroek 			tp->nxt = newhnamemem();
591*b636d99dSDavid van Moolenbroek 			(void)snprintf(nambuf, sizeof(nambuf), "%s.%d",
592*b636d99dSDavid van Moolenbroek 			    tp2->name, athost);
593*b636d99dSDavid van Moolenbroek 			tp->name = strdup(nambuf);
594*b636d99dSDavid van Moolenbroek 			return (tp->name);
595*b636d99dSDavid van Moolenbroek 		}
596*b636d99dSDavid van Moolenbroek 
597*b636d99dSDavid van Moolenbroek 	tp->addr = (atnet << 8) | athost;
598*b636d99dSDavid van Moolenbroek 	tp->nxt = newhnamemem();
599*b636d99dSDavid van Moolenbroek 	if (athost != 255)
600*b636d99dSDavid van Moolenbroek 		(void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost);
601*b636d99dSDavid van Moolenbroek 	else
602*b636d99dSDavid van Moolenbroek 		(void)snprintf(nambuf, sizeof(nambuf), "%d", atnet);
603*b636d99dSDavid van Moolenbroek 	tp->name = strdup(nambuf);
604*b636d99dSDavid van Moolenbroek 
605*b636d99dSDavid van Moolenbroek 	return (tp->name);
606*b636d99dSDavid van Moolenbroek }
607*b636d99dSDavid van Moolenbroek 
608*b636d99dSDavid van Moolenbroek static const struct tok skt2str[] = {
609*b636d99dSDavid van Moolenbroek 	{ rtmpSkt,	"rtmp" },	/* routing table maintenance */
610*b636d99dSDavid van Moolenbroek 	{ nbpSkt,	"nis" },	/* name info socket */
611*b636d99dSDavid van Moolenbroek 	{ echoSkt,	"echo" },	/* AppleTalk echo protocol */
612*b636d99dSDavid van Moolenbroek 	{ zipSkt,	"zip" },	/* zone info protocol */
613*b636d99dSDavid van Moolenbroek 	{ 0,		NULL }
614*b636d99dSDavid van Moolenbroek };
615*b636d99dSDavid van Moolenbroek 
616*b636d99dSDavid van Moolenbroek static const char *
ddpskt_string(netdissect_options * ndo,register int skt)617*b636d99dSDavid van Moolenbroek ddpskt_string(netdissect_options *ndo,
618*b636d99dSDavid van Moolenbroek               register int skt)
619*b636d99dSDavid van Moolenbroek {
620*b636d99dSDavid van Moolenbroek 	static char buf[8];
621*b636d99dSDavid van Moolenbroek 
622*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_nflag) {
623*b636d99dSDavid van Moolenbroek 		(void)snprintf(buf, sizeof(buf), "%d", skt);
624*b636d99dSDavid van Moolenbroek 		return (buf);
625*b636d99dSDavid van Moolenbroek 	}
626*b636d99dSDavid van Moolenbroek 	return (tok2str(skt2str, "%d", skt));
627*b636d99dSDavid van Moolenbroek }
628