xref: /freebsd/contrib/tcpdump/print-arp.c (revision cc391cce1125c1163b0cc425704a4279ca0dbe9a)
14edb46e9SPaul Traina /*
2699fc314SBill Fenner  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
34edb46e9SPaul Traina  *	The Regents of the University of California.  All rights reserved.
44edb46e9SPaul Traina  *
54edb46e9SPaul Traina  * Redistribution and use in source and binary forms, with or without
64edb46e9SPaul Traina  * modification, are permitted provided that: (1) source code distributions
74edb46e9SPaul Traina  * retain the above copyright notice and this paragraph in its entirety, (2)
84edb46e9SPaul Traina  * distributions including binary code include the above copyright notice and
94edb46e9SPaul Traina  * this paragraph in its entirety in the documentation or other materials
104edb46e9SPaul Traina  * provided with the distribution, and (3) all advertising materials mentioning
114edb46e9SPaul Traina  * features or use of this software display the following acknowledgement:
124edb46e9SPaul Traina  * ``This product includes software developed by the University of California,
134edb46e9SPaul Traina  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
144edb46e9SPaul Traina  * the University nor the names of its contributors may be used to endorse
154edb46e9SPaul Traina  * or promote products derived from this software without specific prior
164edb46e9SPaul Traina  * written permission.
174edb46e9SPaul Traina  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
184edb46e9SPaul Traina  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
194edb46e9SPaul Traina  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20a88113a8SBill Fenner  *
21a88113a8SBill Fenner  * $FreeBSD$
224edb46e9SPaul Traina  */
234edb46e9SPaul Traina 
244edb46e9SPaul Traina #ifndef lint
25cc391cceSBruce M Simpson static const char rcsid[] _U_ =
26cc391cceSBruce M Simpson     "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.61.2.2 2003/11/16 08:51:10 guy Exp $ (LBL)";
27a88113a8SBill Fenner #endif
28a88113a8SBill Fenner 
29a88113a8SBill Fenner #ifdef HAVE_CONFIG_H
30a88113a8SBill Fenner #include "config.h"
314edb46e9SPaul Traina #endif
324edb46e9SPaul Traina 
33cc391cceSBruce M Simpson #include <tcpdump-stdinc.h>
344edb46e9SPaul Traina 
354edb46e9SPaul Traina #include <stdio.h>
364edb46e9SPaul Traina #include <string.h>
374edb46e9SPaul Traina 
384edb46e9SPaul Traina #include "interface.h"
394edb46e9SPaul Traina #include "addrtoname.h"
40943ee2b1SBill Fenner #include "ether.h"
414edb46e9SPaul Traina #include "ethertype.h"
424edb46e9SPaul Traina #include "extract.h"			/* must come after interface.h */
434edb46e9SPaul Traina 
44943ee2b1SBill Fenner /*
45943ee2b1SBill Fenner  * Address Resolution Protocol.
46943ee2b1SBill Fenner  *
47943ee2b1SBill Fenner  * See RFC 826 for protocol description.  ARP packets are variable
48943ee2b1SBill Fenner  * in size; the arphdr structure defines the fixed-length portion.
49943ee2b1SBill Fenner  * Protocol type values are the same as those for 10 Mb/s Ethernet.
50943ee2b1SBill Fenner  * It is followed by the variable-sized fields ar_sha, arp_spa,
51943ee2b1SBill Fenner  * arp_tha and arp_tpa in that order, according to the lengths
52943ee2b1SBill Fenner  * specified.  Field names used correspond to RFC 826.
53943ee2b1SBill Fenner  */
540e0def19SBill Fenner struct	arp_pkthdr {
55943ee2b1SBill Fenner 	u_short	ar_hrd;		/* format of hardware address */
56943ee2b1SBill Fenner #define ARPHRD_ETHER 	1	/* ethernet hardware format */
57943ee2b1SBill Fenner #define ARPHRD_IEEE802	6	/* token-ring hardware format */
58a1c2090eSBill Fenner #define ARPHRD_ARCNET	7	/* arcnet hardware format */
59943ee2b1SBill Fenner #define ARPHRD_FRELAY 	15	/* frame relay hardware format */
60a1c2090eSBill Fenner #define ARPHRD_STRIP 	23	/* Ricochet Starmode Radio hardware format */
61a1c2090eSBill Fenner #define ARPHRD_IEEE1394	24	/* IEEE 1394 (FireWire) hardware format */
62943ee2b1SBill Fenner 	u_short	ar_pro;		/* format of protocol address */
63943ee2b1SBill Fenner 	u_char	ar_hln;		/* length of hardware address */
64943ee2b1SBill Fenner 	u_char	ar_pln;		/* length of protocol address */
65943ee2b1SBill Fenner 	u_short	ar_op;		/* one of: */
66943ee2b1SBill Fenner #define	ARPOP_REQUEST	1	/* request to resolve address */
67943ee2b1SBill Fenner #define	ARPOP_REPLY	2	/* response to previous request */
68943ee2b1SBill Fenner #define	ARPOP_REVREQUEST 3	/* request protocol address given hardware */
69943ee2b1SBill Fenner #define	ARPOP_REVREPLY	4	/* response giving protocol address */
70943ee2b1SBill Fenner #define ARPOP_INVREQUEST 8 	/* request to identify peer */
71943ee2b1SBill Fenner #define ARPOP_INVREPLY	9	/* response identifying peer */
72943ee2b1SBill Fenner /*
73943ee2b1SBill Fenner  * The remaining fields are variable in size,
74943ee2b1SBill Fenner  * according to the sizes above.
75943ee2b1SBill Fenner  */
76943ee2b1SBill Fenner #ifdef COMMENT_ONLY
77943ee2b1SBill Fenner 	u_char	ar_sha[];	/* sender hardware address */
78943ee2b1SBill Fenner 	u_char	ar_spa[];	/* sender protocol address */
79943ee2b1SBill Fenner 	u_char	ar_tha[];	/* target hardware address */
80943ee2b1SBill Fenner 	u_char	ar_tpa[];	/* target protocol address */
81943ee2b1SBill Fenner #endif
820e0def19SBill Fenner #define ar_sha(ap)	(((const u_char *)((ap)+1))+0)
830e0def19SBill Fenner #define ar_spa(ap)	(((const u_char *)((ap)+1))+  (ap)->ar_hln)
840e0def19SBill Fenner #define ar_tha(ap)	(((const u_char *)((ap)+1))+  (ap)->ar_hln+(ap)->ar_pln)
850e0def19SBill Fenner #define ar_tpa(ap)	(((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
86943ee2b1SBill Fenner };
87943ee2b1SBill Fenner 
88943ee2b1SBill Fenner #define ARP_HDRLEN	8
89943ee2b1SBill Fenner 
90cc391cceSBruce M Simpson #define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd)
91a1c2090eSBill Fenner #define HLN(ap) ((ap)->ar_hln)
92a1c2090eSBill Fenner #define PLN(ap) ((ap)->ar_pln)
93cc391cceSBruce M Simpson #define OP(ap)  EXTRACT_16BITS(&(ap)->ar_op)
94cc391cceSBruce M Simpson #define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro)
95a1c2090eSBill Fenner #define SHA(ap) (ar_sha(ap))
96a1c2090eSBill Fenner #define SPA(ap) (ar_spa(ap))
97a1c2090eSBill Fenner #define THA(ap) (ar_tha(ap))
98a1c2090eSBill Fenner #define TPA(ap) (ar_tpa(ap))
994edb46e9SPaul Traina 
100cc391cceSBruce M Simpson /*
101cc391cceSBruce M Simpson  * ATM Address Resolution Protocol.
102cc391cceSBruce M Simpson  *
103cc391cceSBruce M Simpson  * See RFC 2225 for protocol description.  ATMARP packets are similar
104cc391cceSBruce M Simpson  * to ARP packets, except that there are no length fields for the
105cc391cceSBruce M Simpson  * protocol address - instead, there are type/length fields for
106cc391cceSBruce M Simpson  * the ATM number and subaddress - and the hardware addresses consist
107cc391cceSBruce M Simpson  * of an ATM number and an ATM subaddress.
108cc391cceSBruce M Simpson  */
109cc391cceSBruce M Simpson struct	atmarp_pkthdr {
110cc391cceSBruce M Simpson 	u_short	aar_hrd;	/* format of hardware address */
111cc391cceSBruce M Simpson #define ARPHRD_ATM2225	19	/* ATM (RFC 2225) */
112cc391cceSBruce M Simpson 	u_short	aar_pro;	/* format of protocol address */
113cc391cceSBruce M Simpson 	u_char	aar_shtl;	/* length of source ATM number */
114cc391cceSBruce M Simpson 	u_char	aar_sstl;	/* length of source ATM subaddress */
115cc391cceSBruce M Simpson #define ATMARP_IS_E164	0x40	/* bit in type/length for E.164 format */
116cc391cceSBruce M Simpson #define ATMARP_LEN_MASK	0x3F	/* length of {sub}address in type/length */
117cc391cceSBruce M Simpson 	u_short	aar_op;		/* same as regular ARP */
118cc391cceSBruce M Simpson #define ATMARPOP_NAK	10	/* NAK */
119cc391cceSBruce M Simpson 	u_char	aar_spln;	/* length of source protocol address */
120cc391cceSBruce M Simpson 	u_char	aar_thtl;	/* length of target ATM number */
121cc391cceSBruce M Simpson 	u_char	aar_tstl;	/* length of target ATM subaddress */
122cc391cceSBruce M Simpson 	u_char	aar_tpln;	/* length of target protocol address */
123cc391cceSBruce M Simpson /*
124cc391cceSBruce M Simpson  * The remaining fields are variable in size,
125cc391cceSBruce M Simpson  * according to the sizes above.
126cc391cceSBruce M Simpson  */
127cc391cceSBruce M Simpson #ifdef COMMENT_ONLY
128cc391cceSBruce M Simpson 	u_char	aar_sha[];	/* source ATM number */
129cc391cceSBruce M Simpson 	u_char	aar_ssa[];	/* source ATM subaddress */
130cc391cceSBruce M Simpson 	u_char	aar_spa[];	/* sender protocol address */
131cc391cceSBruce M Simpson 	u_char	aar_tha[];	/* target ATM number */
132cc391cceSBruce M Simpson 	u_char	aar_tsa[];	/* target ATM subaddress */
133cc391cceSBruce M Simpson 	u_char	aar_tpa[];	/* target protocol address */
134cc391cceSBruce M Simpson #endif
135cc391cceSBruce M Simpson 
136cc391cceSBruce M Simpson #define ATMHRD(ap)  EXTRACT_16BITS(&(ap)->aar_hrd)
137cc391cceSBruce M Simpson #define ATMSHLN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK)
138cc391cceSBruce M Simpson #define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK)
139cc391cceSBruce M Simpson #define ATMSPLN(ap) ((ap)->aar_spln)
140cc391cceSBruce M Simpson #define ATMOP(ap)   EXTRACT_16BITS(&(ap)->aar_op)
141cc391cceSBruce M Simpson #define ATMPRO(ap)  EXTRACT_16BITS(&(ap)->aar_pro)
142cc391cceSBruce M Simpson #define ATMTHLN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK)
143cc391cceSBruce M Simpson #define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK)
144cc391cceSBruce M Simpson #define ATMTPLN(ap) ((ap)->aar_tpln)
145cc391cceSBruce M Simpson #define aar_sha(ap)	((const u_char *)((ap)+1))
146cc391cceSBruce M Simpson #define aar_ssa(ap)	(aar_sha(ap) + ATMSHLN(ap))
147cc391cceSBruce M Simpson #define aar_spa(ap)	(aar_ssa(ap) + ATMSSLN(ap))
148cc391cceSBruce M Simpson #define aar_tha(ap)	(aar_spa(ap) + ATMSPLN(ap))
149cc391cceSBruce M Simpson #define aar_tsa(ap)	(aar_tha(ap) + ATMTHLN(ap))
150cc391cceSBruce M Simpson #define aar_tpa(ap)	(aar_tsa(ap) + ATMTSLN(ap))
151cc391cceSBruce M Simpson };
152cc391cceSBruce M Simpson 
153cc391cceSBruce M Simpson #define ATMSHA(ap) (aar_sha(ap))
154cc391cceSBruce M Simpson #define ATMSSA(ap) (aar_ssa(ap))
155cc391cceSBruce M Simpson #define ATMSPA(ap) (aar_spa(ap))
156cc391cceSBruce M Simpson #define ATMTHA(ap) (aar_tha(ap))
157cc391cceSBruce M Simpson #define ATMTSA(ap) (aar_tsa(ap))
158cc391cceSBruce M Simpson #define ATMTPA(ap) (aar_tpa(ap))
159cc391cceSBruce M Simpson 
1604edb46e9SPaul Traina static u_char ezero[6];
1614edb46e9SPaul Traina 
162cc391cceSBruce M Simpson static void
163cc391cceSBruce M Simpson atmarp_addr_print(const u_char *ha, u_int ha_len, const u_char *srca,
164cc391cceSBruce M Simpson     u_int srca_len)
165cc391cceSBruce M Simpson {
166cc391cceSBruce M Simpson 	if (ha_len == 0)
167cc391cceSBruce M Simpson 		(void)printf("<No address>");
168cc391cceSBruce M Simpson 	else {
169cc391cceSBruce M Simpson 		(void)printf("%s", linkaddr_string(ha, ha_len));
170cc391cceSBruce M Simpson 		if (srca_len != 0)
171cc391cceSBruce M Simpson 			(void)printf(",%s", linkaddr_string(srca, srca_len));
172cc391cceSBruce M Simpson 	}
173cc391cceSBruce M Simpson }
174cc391cceSBruce M Simpson 
175cc391cceSBruce M Simpson static void
176cc391cceSBruce M Simpson atmarp_print(const u_char *bp, u_int length, u_int caplen)
177cc391cceSBruce M Simpson {
178cc391cceSBruce M Simpson 	const struct atmarp_pkthdr *ap;
179cc391cceSBruce M Simpson 	u_short pro, hrd, op;
180cc391cceSBruce M Simpson 
181cc391cceSBruce M Simpson 	ap = (const struct atmarp_pkthdr *)bp;
182cc391cceSBruce M Simpson 	TCHECK(*ap);
183cc391cceSBruce M Simpson 
184cc391cceSBruce M Simpson 	hrd = ATMHRD(ap);
185cc391cceSBruce M Simpson 	pro = ATMPRO(ap);
186cc391cceSBruce M Simpson 	op = ATMOP(ap);
187cc391cceSBruce M Simpson 
188cc391cceSBruce M Simpson 	if (!TTEST2(*aar_tpa(ap), ATMTPLN(ap))) {
189cc391cceSBruce M Simpson 		(void)printf("truncated-atmarp");
190cc391cceSBruce M Simpson 		default_print((const u_char *)ap, length);
191cc391cceSBruce M Simpson 		return;
192cc391cceSBruce M Simpson 	}
193cc391cceSBruce M Simpson 
194cc391cceSBruce M Simpson 	if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
195cc391cceSBruce M Simpson 	    ATMSPLN(ap) != 4 || ATMTPLN(ap) != 4) {
196cc391cceSBruce M Simpson 		(void)printf("atmarp-#%d for proto #%d (%d/%d) hardware #%d",
197cc391cceSBruce M Simpson 				op, pro, ATMSPLN(ap), ATMTPLN(ap), hrd);
198cc391cceSBruce M Simpson 		return;
199cc391cceSBruce M Simpson 	}
200cc391cceSBruce M Simpson 	if (pro == ETHERTYPE_TRAIL)
201cc391cceSBruce M Simpson 		(void)printf("trailer-");
202cc391cceSBruce M Simpson 	switch (op) {
203cc391cceSBruce M Simpson 
204cc391cceSBruce M Simpson 	case ARPOP_REQUEST:
205cc391cceSBruce M Simpson 		(void)printf("arp who-has %s", ipaddr_string(ATMTPA(ap)));
206cc391cceSBruce M Simpson 		if (ATMTHLN(ap) != 0) {
207cc391cceSBruce M Simpson 			(void)printf(" (");
208cc391cceSBruce M Simpson 			atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap),
209cc391cceSBruce M Simpson 			    ATMTSA(ap), ATMTSLN(ap));
210cc391cceSBruce M Simpson 			(void)printf(")");
211cc391cceSBruce M Simpson 		}
212cc391cceSBruce M Simpson 		(void)printf(" tell %s", ipaddr_string(ATMSPA(ap)));
213cc391cceSBruce M Simpson 		break;
214cc391cceSBruce M Simpson 
215cc391cceSBruce M Simpson 	case ARPOP_REPLY:
216cc391cceSBruce M Simpson 		(void)printf("arp reply %s", ipaddr_string(ATMSPA(ap)));
217cc391cceSBruce M Simpson 		(void)printf(" is-at ");
218cc391cceSBruce M Simpson 		atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap),
219cc391cceSBruce M Simpson 		    ATMSSLN(ap));
220cc391cceSBruce M Simpson 		break;
221cc391cceSBruce M Simpson 
222cc391cceSBruce M Simpson 	case ARPOP_INVREQUEST:
223cc391cceSBruce M Simpson 		(void)printf("invarp who-is ");
224cc391cceSBruce M Simpson 		atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap), ATMTSA(ap),
225cc391cceSBruce M Simpson 		    ATMTSLN(ap));
226cc391cceSBruce M Simpson 		(void)printf(" tell ");
227cc391cceSBruce M Simpson 		atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap),
228cc391cceSBruce M Simpson 		    ATMSSLN(ap));
229cc391cceSBruce M Simpson 		break;
230cc391cceSBruce M Simpson 
231cc391cceSBruce M Simpson 	case ARPOP_INVREPLY:
232cc391cceSBruce M Simpson 		(void)printf("invarp reply ");
233cc391cceSBruce M Simpson 		atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap),
234cc391cceSBruce M Simpson 		    ATMSSLN(ap));
235cc391cceSBruce M Simpson 		(void)printf(" at %s", ipaddr_string(ATMSPA(ap)));
236cc391cceSBruce M Simpson 		break;
237cc391cceSBruce M Simpson 
238cc391cceSBruce M Simpson 	case ATMARPOP_NAK:
239cc391cceSBruce M Simpson 		(void)printf("nak reply for %s",
240cc391cceSBruce M Simpson 			ipaddr_string(ATMSPA(ap)));
241cc391cceSBruce M Simpson 		break;
242cc391cceSBruce M Simpson 
243cc391cceSBruce M Simpson 	default:
244cc391cceSBruce M Simpson 		(void)printf("atmarp-#%d", op);
245cc391cceSBruce M Simpson 		default_print((const u_char *)ap, caplen);
246cc391cceSBruce M Simpson 		return;
247cc391cceSBruce M Simpson 	}
248cc391cceSBruce M Simpson 	return;
249cc391cceSBruce M Simpson trunc:
250cc391cceSBruce M Simpson 	(void)printf("[|atmarp]");
251cc391cceSBruce M Simpson }
252cc391cceSBruce M Simpson 
2534edb46e9SPaul Traina void
254a1c2090eSBill Fenner arp_print(const u_char *bp, u_int length, u_int caplen)
2554edb46e9SPaul Traina {
2560e0def19SBill Fenner 	const struct arp_pkthdr *ap;
257a1c2090eSBill Fenner 	u_short pro, hrd, op;
2584edb46e9SPaul Traina 
2590e0def19SBill Fenner 	ap = (const struct arp_pkthdr *)bp;
260a1c2090eSBill Fenner 	TCHECK(*ap);
261cc391cceSBruce M Simpson 	hrd = HRD(ap);
262cc391cceSBruce M Simpson 	if (hrd == ARPHRD_ATM2225) {
263cc391cceSBruce M Simpson 		atmarp_print(bp, length, caplen);
264cc391cceSBruce M Simpson 		return;
265cc391cceSBruce M Simpson 	}
266cc391cceSBruce M Simpson 	pro = PRO(ap);
267cc391cceSBruce M Simpson 	op = OP(ap);
268cc391cceSBruce M Simpson 
269cc391cceSBruce M Simpson 	if (!TTEST2(*ar_tpa(ap), PLN(ap))) {
2704edb46e9SPaul Traina 		(void)printf("truncated-arp");
271a1c2090eSBill Fenner 		default_print((const u_char *)ap, length);
2724edb46e9SPaul Traina 		return;
2734edb46e9SPaul Traina 	}
2744edb46e9SPaul Traina 
275cc391cceSBruce M Simpson 	if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
276cc391cceSBruce M Simpson 	    PLN(ap) != 4 || HLN(ap) == 0) {
2774edb46e9SPaul Traina 		(void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",
278a1c2090eSBill Fenner 				op, pro, PLN(ap), hrd, HLN(ap));
2794edb46e9SPaul Traina 		return;
2804edb46e9SPaul Traina 	}
2814edb46e9SPaul Traina 	if (pro == ETHERTYPE_TRAIL)
2824edb46e9SPaul Traina 		(void)printf("trailer-");
2834edb46e9SPaul Traina 	switch (op) {
2844edb46e9SPaul Traina 
2854edb46e9SPaul Traina 	case ARPOP_REQUEST:
2864edb46e9SPaul Traina 		(void)printf("arp who-has %s", ipaddr_string(TPA(ap)));
287a1c2090eSBill Fenner 		if (memcmp((const char *)ezero, (const char *)THA(ap), HLN(ap)) != 0)
288a1c2090eSBill Fenner 			(void)printf(" (%s)",
289a1c2090eSBill Fenner 			    linkaddr_string(THA(ap), HLN(ap)));
2904edb46e9SPaul Traina 		(void)printf(" tell %s", ipaddr_string(SPA(ap)));
2914edb46e9SPaul Traina 		break;
2924edb46e9SPaul Traina 
2934edb46e9SPaul Traina 	case ARPOP_REPLY:
2944edb46e9SPaul Traina 		(void)printf("arp reply %s", ipaddr_string(SPA(ap)));
295a1c2090eSBill Fenner 		(void)printf(" is-at %s", linkaddr_string(SHA(ap), HLN(ap)));
2964edb46e9SPaul Traina 		break;
2974edb46e9SPaul Traina 
298a1c2090eSBill Fenner 	case ARPOP_REVREQUEST:
2994edb46e9SPaul Traina 		(void)printf("rarp who-is %s tell %s",
300a1c2090eSBill Fenner 			linkaddr_string(THA(ap), HLN(ap)),
301a1c2090eSBill Fenner 			linkaddr_string(SHA(ap), HLN(ap)));
3024edb46e9SPaul Traina 		break;
3034edb46e9SPaul Traina 
304a1c2090eSBill Fenner 	case ARPOP_REVREPLY:
3054edb46e9SPaul Traina 		(void)printf("rarp reply %s at %s",
306a1c2090eSBill Fenner 			linkaddr_string(THA(ap), HLN(ap)),
3074edb46e9SPaul Traina 			ipaddr_string(TPA(ap)));
3084edb46e9SPaul Traina 		break;
3094edb46e9SPaul Traina 
310cc391cceSBruce M Simpson 	case ARPOP_INVREQUEST:
311cc391cceSBruce M Simpson 		(void)printf("invarp who-is %s tell %s",
312cc391cceSBruce M Simpson 			linkaddr_string(THA(ap), HLN(ap)),
313cc391cceSBruce M Simpson 			linkaddr_string(SHA(ap), HLN(ap)));
314cc391cceSBruce M Simpson 		break;
315cc391cceSBruce M Simpson 
316cc391cceSBruce M Simpson 	case ARPOP_INVREPLY:
317cc391cceSBruce M Simpson 		(void)printf("invarp reply %s at %s",
318cc391cceSBruce M Simpson 			linkaddr_string(THA(ap), HLN(ap)),
319cc391cceSBruce M Simpson 			ipaddr_string(TPA(ap)));
320cc391cceSBruce M Simpson 		break;
321cc391cceSBruce M Simpson 
3224edb46e9SPaul Traina 	default:
3234edb46e9SPaul Traina 		(void)printf("arp-#%d", op);
324a1c2090eSBill Fenner 		default_print((const u_char *)ap, caplen);
3254edb46e9SPaul Traina 		return;
3264edb46e9SPaul Traina 	}
3274edb46e9SPaul Traina 	if (hrd != ARPHRD_ETHER)
3282ebf6c05SBill Fenner 		printf(" hardware #%d", hrd);
329a1c2090eSBill Fenner 	return;
330a1c2090eSBill Fenner trunc:
331a1c2090eSBill Fenner 	(void)printf("[|arp]");
3324edb46e9SPaul Traina }
333