1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1991-2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <net/if.h>
33 #include <net/if_arp.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/in.h>
36 #include <netinet/if_ether.h>
37 
38 #include <at.h>
39 #include <snoop.h>
40 
41 static char *printat(uint8_t *);
42 
43 static char *aarp_opname[] = {
44 	"",
45 	"AARP Request",
46 	"AARP Reply",
47 	"AARP Probe",
48 };
49 
50 void
51 interpret_aarp(int flags, char *data, int alen)
52 {
53 	/* LINTED */
54 	struct ether_arp *ap = (struct ether_arp *)data;
55 
56 	extern char *dst_name;
57 
58 	if (flags & F_SUM) {
59 		if (alen < sizeof (struct ether_arp)) {
60 			(void) snprintf(get_sum_line(), MAXLINE,
61 			    "AARP (short packet)");
62 			return;
63 		}
64 
65 		switch (ntohs(ap->arp_op)) {
66 		case AARP_REQ:
67 			(void) snprintf(get_sum_line(), MAXLINE,
68 			    "AARP C Who is %s ?",
69 			    printat(ap->arp_tpa));
70 			break;
71 		case AARP_RESP:
72 			(void) snprintf(get_sum_line(), MAXLINE,
73 			    "AARP R %s is %s",
74 			    printat(ap->arp_spa),
75 			    printether((struct ether_addr *)&ap->arp_sha));
76 			dst_name = printat(ap->arp_tpa);
77 			break;
78 		case AARP_PROBE:
79 			(void) snprintf(get_sum_line(), MAXLINE,
80 			    "AARP Probe %s ?",
81 			    printat(ap->arp_tpa));
82 			break;
83 		}
84 	}
85 
86 	if (flags & F_DTAIL) {
87 		show_header("AARP: ", "AARP Frame", alen);
88 		show_space();
89 
90 		if (alen < sizeof (struct ether_arp)) {
91 			(void) snprintf(get_line(0, 0), get_line_remain(),
92 			    "AARP (short packet)");
93 			return;
94 		}
95 
96 		(void) snprintf(get_line(0, 0), get_line_remain(),
97 		    "Hardware type = %d",
98 		    ntohs(ap->arp_hrd));
99 		(void) snprintf(get_line(0, 0), get_line_remain(),
100 		    "Protocol type = %04X (%s)",
101 		    ntohs(ap->arp_pro),
102 		    print_ethertype(ntohs(ap->arp_pro)));
103 		(void) snprintf(get_line(0, 0), get_line_remain(),
104 		    "Length of hardware address = %d bytes",
105 		    ap->arp_hln);
106 		(void) snprintf(get_line(0, 0), get_line_remain(),
107 		    "Length of protocol address = %d bytes",
108 		    ap->arp_pln);
109 		(void) snprintf(get_line(0, 0), get_line_remain(),
110 		    "Opcode %d (%s)",
111 		    ntohs(ap->arp_op),
112 		    aarp_opname[ntohs(ap->arp_op)]);
113 
114 		if (ntohs(ap->arp_hrd) == ARPHRD_ETHER &&
115 		    ntohs(ap->arp_pro) == ETHERTYPE_AT) {
116 			(void) snprintf(get_line(0, 0), get_line_remain(),
117 			    "Sender's hardware address = %s",
118 			    printether((struct ether_addr *)&ap->arp_sha));
119 			(void) snprintf(get_line(0, 0), get_line_remain(),
120 			    "Sender's protocol address = %s",
121 			    printat(ap->arp_spa));
122 			(void) snprintf(get_line(0, 0), get_line_remain(),
123 			    "Target hardware address = %s",
124 			    (ntohs(ap->arp_op) == AARP_REQ ||
125 				ntohs(ap->arp_op) == AARP_PROBE) ? "?" :
126 			    printether((struct ether_addr *)&ap->arp_tha));
127 			(void) snprintf(get_line(0, 0), get_line_remain(),
128 			    "Target protocol address = %s",
129 			    ntohs(ap->arp_op) == REVARP_REQUEST ? "?" :
130 			    printat(ap->arp_tpa));
131 		}
132 		show_trailer();
133 	}
134 }
135 
136 static char *
137 printat(uint8_t *p)
138 {
139 	static char buf[16];
140 
141 	(void) snprintf(buf, sizeof (buf),  "%d.%d", get_short(&p[1]), p[3]);
142 	return (buf);
143 }
144