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
41static char *printat(uint8_t *);
42
43static char *aarp_opname[] = {
44	"",
45	"AARP Request",
46	"AARP Reply",
47	"AARP Probe",
48};
49
50void
51interpret_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
136static char *
137printat(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