xref: /freebsd/contrib/tcpdump/print-arp.c (revision 699fc31439c6d227def4f2fdf7b4f4c5f3d02828)
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.
204edb46e9SPaul Traina  */
214edb46e9SPaul Traina 
224edb46e9SPaul Traina #ifndef lint
232ebf6c05SBill Fenner static const char rcsid[] =
24699fc314SBill Fenner     "@(#) $Header: print-arp.c,v 1.43 97/06/15 13:20:27 leres Exp $ (LBL)";
254edb46e9SPaul Traina #endif
264edb46e9SPaul Traina 
274edb46e9SPaul Traina #include <sys/param.h>
284edb46e9SPaul Traina #include <sys/time.h>
294edb46e9SPaul Traina #include <sys/socket.h>
304edb46e9SPaul Traina 
314edb46e9SPaul Traina #if __STDC__
324edb46e9SPaul Traina struct mbuf;
334edb46e9SPaul Traina struct rtentry;
344edb46e9SPaul Traina #endif
354edb46e9SPaul Traina #include <net/if.h>
36ee3e7633SGarrett Wollman #include <net/if_var.h>
374edb46e9SPaul Traina 
384edb46e9SPaul Traina #include <netinet/in.h>
394edb46e9SPaul Traina #include <netinet/if_ether.h>
404edb46e9SPaul Traina 
41699fc314SBill Fenner #ifdef HAVE_MEMORY_H
42699fc314SBill Fenner #include <memory.h>
43699fc314SBill Fenner #endif
444edb46e9SPaul Traina #include <stdio.h>
454edb46e9SPaul Traina #include <string.h>
464edb46e9SPaul Traina 
474edb46e9SPaul Traina #include "interface.h"
484edb46e9SPaul Traina #include "addrtoname.h"
494edb46e9SPaul Traina #include "ethertype.h"
504edb46e9SPaul Traina #include "extract.h"			/* must come after interface.h */
514edb46e9SPaul Traina 
524edb46e9SPaul Traina /* Compatibility */
534edb46e9SPaul Traina #ifndef REVARP_REQUEST
544edb46e9SPaul Traina #define REVARP_REQUEST		3
554edb46e9SPaul Traina #endif
564edb46e9SPaul Traina #ifndef REVARP_REPLY
574edb46e9SPaul Traina #define REVARP_REPLY		4
584edb46e9SPaul Traina #endif
594edb46e9SPaul Traina 
604edb46e9SPaul Traina static u_char ezero[6];
614edb46e9SPaul Traina 
624edb46e9SPaul Traina void
634edb46e9SPaul Traina arp_print(register const u_char *bp, u_int length, u_int caplen)
644edb46e9SPaul Traina {
654edb46e9SPaul Traina 	register const struct ether_arp *ap;
664edb46e9SPaul Traina 	register const struct ether_header *eh;
674edb46e9SPaul Traina 	register u_short pro, hrd, op;
684edb46e9SPaul Traina 
694edb46e9SPaul Traina 	ap = (struct ether_arp *)bp;
704edb46e9SPaul Traina 	if ((u_char *)(ap + 1) > snapend) {
714edb46e9SPaul Traina 		printf("[|arp]");
724edb46e9SPaul Traina 		return;
734edb46e9SPaul Traina 	}
744edb46e9SPaul Traina 	if (length < sizeof(struct ether_arp)) {
754edb46e9SPaul Traina 		(void)printf("truncated-arp");
764edb46e9SPaul Traina 		default_print((u_char *)ap, length);
774edb46e9SPaul Traina 		return;
784edb46e9SPaul Traina 	}
794edb46e9SPaul Traina 
804edb46e9SPaul Traina 	pro = EXTRACT_16BITS(&ap->arp_pro);
814edb46e9SPaul Traina 	hrd = EXTRACT_16BITS(&ap->arp_hrd);
824edb46e9SPaul Traina 	op = EXTRACT_16BITS(&ap->arp_op);
834edb46e9SPaul Traina 
844edb46e9SPaul Traina 	if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
854edb46e9SPaul Traina 	    || ap->arp_hln != sizeof(SHA(ap))
864edb46e9SPaul Traina 	    || ap->arp_pln != sizeof(SPA(ap))) {
874edb46e9SPaul Traina 		(void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",
884edb46e9SPaul Traina 				op, pro, ap->arp_pln,
894edb46e9SPaul Traina 				hrd, ap->arp_hln);
904edb46e9SPaul Traina 		return;
914edb46e9SPaul Traina 	}
924edb46e9SPaul Traina 	if (pro == ETHERTYPE_TRAIL)
934edb46e9SPaul Traina 		(void)printf("trailer-");
944edb46e9SPaul Traina 	eh = (struct ether_header *)packetp;
954edb46e9SPaul Traina 	switch (op) {
964edb46e9SPaul Traina 
974edb46e9SPaul Traina 	case ARPOP_REQUEST:
984edb46e9SPaul Traina 		(void)printf("arp who-has %s", ipaddr_string(TPA(ap)));
994edb46e9SPaul Traina 		if (memcmp((char *)ezero, (char *)THA(ap), 6) != 0)
1004edb46e9SPaul Traina 			(void)printf(" (%s)", etheraddr_string(THA(ap)));
1014edb46e9SPaul Traina 		(void)printf(" tell %s", ipaddr_string(SPA(ap)));
1024edb46e9SPaul Traina 		if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
1034edb46e9SPaul Traina 			(void)printf(" (%s)", etheraddr_string(SHA(ap)));
1044edb46e9SPaul Traina 		break;
1054edb46e9SPaul Traina 
1064edb46e9SPaul Traina 	case ARPOP_REPLY:
1074edb46e9SPaul Traina 		(void)printf("arp reply %s", ipaddr_string(SPA(ap)));
1084edb46e9SPaul Traina 		if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
1094edb46e9SPaul Traina 			(void)printf(" (%s)", etheraddr_string(SHA(ap)));
1104edb46e9SPaul Traina 		(void)printf(" is-at %s", etheraddr_string(SHA(ap)));
1114edb46e9SPaul Traina 		if (memcmp((char *)EDST(eh), (char *)THA(ap), 6) != 0)
1124edb46e9SPaul Traina 			(void)printf(" (%s)", etheraddr_string(THA(ap)));
1134edb46e9SPaul Traina 		break;
1144edb46e9SPaul Traina 
1154edb46e9SPaul Traina 	case REVARP_REQUEST:
1164edb46e9SPaul Traina 		(void)printf("rarp who-is %s tell %s",
1174edb46e9SPaul Traina 			etheraddr_string(THA(ap)),
1184edb46e9SPaul Traina 			etheraddr_string(SHA(ap)));
1194edb46e9SPaul Traina 		break;
1204edb46e9SPaul Traina 
1214edb46e9SPaul Traina 	case REVARP_REPLY:
1224edb46e9SPaul Traina 		(void)printf("rarp reply %s at %s",
1234edb46e9SPaul Traina 			etheraddr_string(THA(ap)),
1244edb46e9SPaul Traina 			ipaddr_string(TPA(ap)));
1254edb46e9SPaul Traina 		break;
1264edb46e9SPaul Traina 
1274edb46e9SPaul Traina 	default:
1284edb46e9SPaul Traina 		(void)printf("arp-#%d", op);
1294edb46e9SPaul Traina 		default_print((u_char *)ap, caplen);
1304edb46e9SPaul Traina 		return;
1314edb46e9SPaul Traina 	}
1324edb46e9SPaul Traina 	if (hrd != ARPHRD_ETHER)
1332ebf6c05SBill Fenner 		printf(" hardware #%d", hrd);
1344edb46e9SPaul Traina }
135