4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <sys/types.h>
29 #include <sys/errno.h>
31 #include <sys/socket.h>
33 #include <net/if_arp.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/in.h>
36 #include <netinet/ip.h>
37 #include <netinet/if_ether.h>
39 #include <net/if_types.h>
43 extern char *dlc_header
;
44 extern jmp_buf xdr_err
;
46 static char *printip(unsigned char *);
47 static char *addrtoname_align(unsigned char *);
49 static char unarp_addr
[] = "Unknown";
59 interpret_arp(int flags
, struct arphdr
*ap
, int alen
)
62 extern char *src_name
, *dst_name
;
63 unsigned char *sip
, *tip
, *sha
, *tha
;
64 char *smacbuf
= NULL
, *dmacbuf
= NULL
;
67 boolean_t is_ip
= B_FALSE
;
70 * Check that at least the generic ARP header was received.
72 if (sizeof (struct arphdr
) > alen
)
75 arpop
= ntohs(ap
->ar_op
);
77 if (ntohs(ap
->ar_pro
) == ETHERTYPE_IP
)
80 sha
= (unsigned char *)(ap
+ 1);
82 tha
= sip
+ ap
->ar_pln
;
86 * Check that the protocol/hardware addresses were received.
88 if ((tip
+ ap
->ar_pln
) > ((unsigned char *)ap
+ alen
))
92 smacbuf
= dmacbuf
= unarp_addr
;
94 if (((flags
& F_DTAIL
) && is_ip
) || (arpop
== ARPOP_REPLY
)) {
95 smacbuf
= _link_ntoa(sha
, NULL
, maclen
, IFT_OTHER
);
97 pr_err("Warning: malloc failure");
100 if (((flags
& F_DTAIL
) && is_ip
) || (arpop
==
101 REVARP_REQUEST
) || (arpop
== REVARP_REPLY
)) {
102 dmacbuf
= _link_ntoa(tha
, NULL
, maclen
, IFT_OTHER
);
104 pr_err("Warning: malloc failure");
108 src_name
= addrtoname_align(sip
);
112 line
= get_sum_line();
116 (void) snprintf(line
, MAXLINE
, "ARP C Who is %s ?",
120 (void) snprintf(line
, MAXLINE
, "ARP R %s is %s",
121 printip(sip
), smacbuf
);
122 dst_name
= addrtoname_align(tip
);
125 (void) snprintf(line
, MAXLINE
, "RARP C Who is %s ?",
129 (void) snprintf(line
, MAXLINE
, "RARP R %s is %s",
130 dmacbuf
, printip(tip
));
131 dst_name
= addrtoname_align(tip
);
136 if (flags
& F_DTAIL
) {
137 show_header("ARP: ", "ARP/RARP Frame", alen
);
139 (void) snprintf(get_line(0, 0), get_line_remain(),
140 "Hardware type = %d (%s)", ntohs(ap
->ar_hrd
),
141 arp_htype(ntohs(ap
->ar_hrd
)));
142 (void) snprintf(get_line(0, 0), get_line_remain(),
143 "Protocol type = %04x (%s)", ntohs(ap
->ar_pro
),
144 print_ethertype(ntohs(ap
->ar_pro
)));
145 (void) snprintf(get_line(0, 0), get_line_remain(),
146 "Length of hardware address = %d bytes", ap
->ar_hln
);
147 (void) snprintf(get_line(0, 0), get_line_remain(),
148 "Length of protocol address = %d bytes", ap
->ar_pln
);
149 (void) snprintf(get_line(0, 0), get_line_remain(),
150 "Opcode %d (%s)", arpop
,
151 (arpop
> REVARP_REPLY
) ? opname
[0] : opname
[arpop
]);
154 (void) snprintf(get_line(0, 0), get_line_remain(),
155 "Sender's hardware address = %s", smacbuf
);
156 (void) snprintf(get_line(0, 0), get_line_remain(),
157 "Sender's protocol address = %s",
159 (void) snprintf(get_line(0, 0), get_line_remain(),
160 "Target hardware address = %s",
161 arpop
== ARPOP_REQUEST
? "?" : dmacbuf
);
162 (void) snprintf(get_line(0, 0), get_line_remain(),
163 "Target protocol address = %s",
164 arpop
== REVARP_REQUEST
? "?" :
178 (void) snprintf(get_sum_line(), MAXLINE
,
179 "ARP (short packet)");
180 } else if (flags
& F_DTAIL
) {
181 show_header("ARP: ", "ARP/RARP Frame", alen
);
183 (void) snprintf(get_line(0, 0), get_line_remain(),
184 "ARP (short packet)");
189 printip(unsigned char *p
)
191 static char buff
[MAXHOSTNAMELEN
+ 32];
196 ap
= (char *)inet_ntoa(a
);
197 np
= (char *)addrtoname(AF_INET
, &a
);
198 (void) snprintf(buff
, MAXHOSTNAMELEN
, "%s, %s", ap
, np
);
203 addrtoname_align(unsigned char *p
)
208 return ((char *)addrtoname(AF_INET
, &a
));
212 * These numbers are assigned by the IANA. See the arp-parameters registry.
213 * Only those values that are used within Solaris have #defines.
220 return ("Ethernet (10Mb)");
222 return ("Experimental Ethernet (3MB)");
224 return ("Amateur Radio AX.25");
226 return ("Proteon ProNET Token Ring");
234 return ("Hyperchannel");
240 return ("LocalTalk");
244 return ("Ultra Link");
248 return ("Frame Relay");
254 return ("Fibre Channel");