Home | History | Annotate | Download | only in snoop
      1     0    stevel /*
      2     0    stevel  * CDDL HEADER START
      3     0    stevel  *
      4     0    stevel  * The contents of this file are subject to the terms of the
      5  3431  carlsonj  * Common Development and Distribution License (the "License").
      6  3431  carlsonj  * You may not use this file except in compliance with the License.
      7     0    stevel  *
      8     0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0    stevel  * or http://www.opensolaris.org/os/licensing.
     10     0    stevel  * See the License for the specific language governing permissions
     11     0    stevel  * and limitations under the License.
     12     0    stevel  *
     13     0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0    stevel  *
     19     0    stevel  * CDDL HEADER END
     20     0    stevel  */
     21     0    stevel /*
     22  3431  carlsonj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23     0    stevel  * Use is subject to license terms.
     24     0    stevel  */
     25     0    stevel 
     26     0    stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27     0    stevel 
     28     0    stevel #include <sys/types.h>
     29     0    stevel #include <sys/errno.h>
     30     0    stevel #include <setjmp.h>
     31     0    stevel #include <sys/socket.h>
     32     0    stevel #include <net/if.h>
     33     0    stevel #include <net/if_arp.h>
     34     0    stevel #include <netinet/in_systm.h>
     35     0    stevel #include <netinet/in.h>
     36     0    stevel #include <netinet/ip.h>
     37     0    stevel #include <netinet/if_ether.h>
     38     0    stevel #include <netdb.h>
     39     0    stevel #include <net/if_types.h>
     40     0    stevel 
     41     0    stevel #include "snoop.h"
     42     0    stevel 
     43     0    stevel extern char *dlc_header;
     44     0    stevel extern jmp_buf xdr_err;
     45     0    stevel 
     46     0    stevel static char *printip(unsigned char *);
     47     0    stevel static char *addrtoname_align(unsigned char *);
     48     0    stevel 
     49     0    stevel static char unarp_addr[] = "Unknown";
     50     0    stevel char *opname[] = {
     51     0    stevel 	"",
     52     0    stevel 	"ARP Request",
     53     0    stevel 	"ARP Reply",
     54     0    stevel 	"REVARP Request",
     55     0    stevel 	"REVARP Reply",
     56     0    stevel };
     57     0    stevel 
     58     0    stevel void
     59     0    stevel interpret_arp(int flags, struct arphdr *ap, int alen)
     60     0    stevel {
     61     0    stevel 	char *line;
     62     0    stevel 	extern char *src_name, *dst_name;
     63     0    stevel 	unsigned char *sip, *tip, *sha, *tha;
     64     0    stevel 	char *smacbuf = NULL, *dmacbuf = NULL;
     65     0    stevel 	int maclen;
     66     0    stevel 	ushort_t arpop;
     67     0    stevel 	boolean_t is_ip = B_FALSE;
     68     0    stevel 
     69     0    stevel 	/*
     70     0    stevel 	 * Check that at least the generic ARP header was received.
     71     0    stevel 	 */
     72     0    stevel 	if (sizeof (struct arphdr) > alen)
     73     0    stevel 		goto short_packet;
     74     0    stevel 
     75     0    stevel 	arpop = ntohs(ap->ar_op);
     76     0    stevel 	maclen = ap->ar_hln;
     77     0    stevel 	if (ntohs(ap->ar_pro) == ETHERTYPE_IP)
     78     0    stevel 		is_ip = B_TRUE;
     79     0    stevel 
     80     0    stevel 	sha = (unsigned char *)(ap + 1);
     81     0    stevel 	sip = sha + maclen;
     82     0    stevel 	tha = sip + ap->ar_pln;
     83     0    stevel 	tip = tha + maclen;
     84     0    stevel 
     85     0    stevel 	/*
     86     0    stevel 	 * Check that the protocol/hardware addresses were received.
     87     0    stevel 	 */
     88     0    stevel 	if ((tip + ap->ar_pln) > ((unsigned char *)ap + alen))
     89     0    stevel 		goto short_packet;
     90     0    stevel 
     91     0    stevel 	if (maclen == 0) {
     92     0    stevel 		smacbuf = dmacbuf = unarp_addr;
     93     0    stevel 	} else {
     94     0    stevel 		if (((flags & F_DTAIL) && is_ip) || (arpop == ARPOP_REPLY)) {
     95     0    stevel 			smacbuf = _link_ntoa(sha, NULL, maclen, IFT_OTHER);
     96     0    stevel 			if (smacbuf == NULL)
     97     0    stevel 				pr_err("Warning: malloc failure");
     98     0    stevel 		}
     99     0    stevel 
    100     0    stevel 		if (((flags & F_DTAIL) && is_ip) || (arpop ==
    101     0    stevel 		    REVARP_REQUEST) || (arpop == REVARP_REPLY)) {
    102     0    stevel 			dmacbuf = _link_ntoa(tha, NULL, maclen, IFT_OTHER);
    103     0    stevel 			if (dmacbuf == NULL)
    104     0    stevel 				pr_err("Warning: malloc failure");
    105     0    stevel 		}
    106     0    stevel 	}
    107     0    stevel 
    108     0    stevel 	src_name = addrtoname_align(sip);
    109     0    stevel 
    110     0    stevel 	if (flags & F_SUM) {
    111     0    stevel 
    112     0    stevel 		line = get_sum_line();
    113     0    stevel 
    114     0    stevel 		switch (arpop) {
    115     0    stevel 		case ARPOP_REQUEST:
    116     0    stevel 			(void) snprintf(line, MAXLINE, "ARP C Who is %s ?",
    117     0    stevel 			    printip(tip));
    118     0    stevel 			break;
    119     0    stevel 		case ARPOP_REPLY:
    120     0    stevel 			(void) snprintf(line, MAXLINE, "ARP R %s is %s",
    121     0    stevel 			    printip(sip), smacbuf);
    122     0    stevel 			dst_name = addrtoname_align(tip);
    123     0    stevel 			break;
    124     0    stevel 		case REVARP_REQUEST:
    125     0    stevel 			(void) snprintf(line, MAXLINE, "RARP C Who is %s ?",
    126     0    stevel 			    dmacbuf);
    127     0    stevel 			break;
    128     0    stevel 		case REVARP_REPLY:
    129     0    stevel 			(void) snprintf(line, MAXLINE, "RARP R %s is %s",
    130     0    stevel 			    dmacbuf, printip(tip));
    131     0    stevel 			dst_name = addrtoname_align(tip);
    132     0    stevel 			break;
    133     0    stevel 		}
    134     0    stevel 	}
    135     0    stevel 
    136     0    stevel 	if (flags & F_DTAIL) {
    137     0    stevel 		show_header("ARP:  ", "ARP/RARP Frame", alen);
    138     0    stevel 		show_space();
    139     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    140  3431  carlsonj 		    "Hardware type = %d (%s)", ntohs(ap->ar_hrd),
    141  3431  carlsonj 		    arp_htype(ntohs(ap->ar_hrd)));
    142     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    143     0    stevel 		    "Protocol type = %04x (%s)", ntohs(ap->ar_pro),
    144     0    stevel 		    print_ethertype(ntohs(ap->ar_pro)));
    145     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    146     0    stevel 		    "Length of hardware address = %d bytes", ap->ar_hln);
    147     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    148     0    stevel 		    "Length of protocol address = %d bytes", ap->ar_pln);
    149     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    150     0    stevel 		    "Opcode %d (%s)", arpop,
    151     0    stevel 		    (arpop > REVARP_REPLY) ? opname[0] : opname[arpop]);
    152     0    stevel 
    153     0    stevel 		if (is_ip) {
    154     0    stevel 			(void) snprintf(get_line(0, 0), get_line_remain(),
    155     0    stevel 			    "Sender's hardware address = %s", smacbuf);
    156     0    stevel 			(void) snprintf(get_line(0, 0), get_line_remain(),
    157     0    stevel 			    "Sender's protocol address = %s",
    158     0    stevel 			    printip(sip));
    159     0    stevel 			(void) snprintf(get_line(0, 0), get_line_remain(),
    160     0    stevel 			    "Target hardware address = %s",
    161     0    stevel 			    arpop == ARPOP_REQUEST ? "?" : dmacbuf);
    162     0    stevel 			(void) snprintf(get_line(0, 0), get_line_remain(),
    163     0    stevel 			    "Target protocol address = %s",
    164     0    stevel 			    arpop == REVARP_REQUEST ? "?" :
    165     0    stevel 			    printip(tip));
    166     0    stevel 		}
    167     0    stevel 		show_trailer();
    168     0    stevel 	}
    169     0    stevel 
    170     0    stevel 	if (maclen != 0) {
    171     0    stevel 		free(smacbuf);
    172     0    stevel 		free(dmacbuf);
    173     0    stevel 	}
    174     0    stevel 	return;
    175     0    stevel 
    176     0    stevel short_packet:
    177     0    stevel 	if (flags & F_SUM) {
    178     0    stevel 		(void) snprintf(get_sum_line(), MAXLINE,
    179     0    stevel 		    "ARP (short packet)");
    180     0    stevel 	} else if (flags & F_DTAIL) {
    181     0    stevel 		show_header("ARP:  ", "ARP/RARP Frame", alen);
    182     0    stevel 		show_space();
    183     0    stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
    184     0    stevel 		    "ARP (short packet)");
    185     0    stevel 	}
    186     0    stevel }
    187     0    stevel 
    188     0    stevel char *
    189     0    stevel printip(unsigned char *p)
    190     0    stevel {
    191     0    stevel 	static char buff[MAXHOSTNAMELEN + 32];
    192     0    stevel 	char *ap, *np;
    193     0    stevel 	struct in_addr a;
    194     0    stevel 
    195     0    stevel 	memcpy(&a, p, 4);
    196     0    stevel 	ap = (char *)inet_ntoa(a);
    197     0    stevel 	np = (char *)addrtoname(AF_INET, &a);
    198     0    stevel 	(void) snprintf(buff, MAXHOSTNAMELEN, "%s, %s", ap, np);
    199     0    stevel 	return (buff);
    200     0    stevel }
    201     0    stevel 
    202     0    stevel char *
    203     0    stevel addrtoname_align(unsigned char *p)
    204     0    stevel {
    205     0    stevel 	struct in_addr a;
    206     0    stevel 
    207     0    stevel 	memcpy(&a, p, 4);
    208     0    stevel 	return ((char *)addrtoname(AF_INET, &a));
    209     0    stevel }
    210  3431  carlsonj 
    211  3431  carlsonj /*
    212  3431  carlsonj  * These numbers are assigned by the IANA.  See the arp-parameters registry.
    213  3431  carlsonj  * Only those values that are used within Solaris have #defines.
    214  3431  carlsonj  */
    215  3431  carlsonj const char *
    216  3431  carlsonj arp_htype(int t)
    217  3431  carlsonj {
    218  3431  carlsonj 	switch (t) {
    219  3431  carlsonj 	case ARPHRD_ETHER:
    220  3431  carlsonj 		return ("Ethernet (10Mb)");
    221  3431  carlsonj 	case 2:
    222  3431  carlsonj 		return ("Experimental Ethernet (3MB)");
    223  3431  carlsonj 	case 3:
    224  3431  carlsonj 		return ("Amateur Radio AX.25");
    225  3431  carlsonj 	case 4:
    226  3431  carlsonj 		return ("Proteon ProNET Token Ring");
    227  3431  carlsonj 	case 5:
    228  3431  carlsonj 		return ("Chaos");
    229  3431  carlsonj 	case ARPHRD_IEEE802:
    230  3431  carlsonj 		return ("IEEE 802");
    231  3431  carlsonj 	case 7:
    232  3431  carlsonj 		return ("ARCNET");
    233  3431  carlsonj 	case 8:
    234  3431  carlsonj 		return ("Hyperchannel");
    235  3431  carlsonj 	case 9:
    236  3431  carlsonj 		return ("Lanstar");
    237  3431  carlsonj 	case 10:
    238  3431  carlsonj 		return ("Autonet");
    239  3431  carlsonj 	case 11:
    240  3431  carlsonj 		return ("LocalTalk");
    241  3431  carlsonj 	case 12:
    242  3431  carlsonj 		return ("LocalNet");
    243  3431  carlsonj 	case 13:
    244  3431  carlsonj 		return ("Ultra Link");
    245  3431  carlsonj 	case 14:
    246  3431  carlsonj 		return ("SMDS");
    247  3431  carlsonj 	case ARPHRD_FRAME:
    248  3431  carlsonj 		return ("Frame Relay");
    249  3431  carlsonj 	case ARPHRD_ATM:
    250  3431  carlsonj 		return ("ATM");
    251  3431  carlsonj 	case ARPHRD_HDLC:
    252  3431  carlsonj 		return ("HDLC");
    253  3431  carlsonj 	case ARPHRD_FC:
    254  3431  carlsonj 		return ("Fibre Channel");
    255  3431  carlsonj 	case ARPHRD_IPATM:
    256  3431  carlsonj 		return ("IP-ATM");
    257  3431  carlsonj 	case ARPHRD_TUNNEL:
    258  3431  carlsonj 		return ("Tunnel");
    259  3431  carlsonj 	case ARPHRD_IB:
    260  3431  carlsonj 		return ("IPIB");
    261  3431  carlsonj 	};
    262  3431  carlsonj 	return ("UNKNOWN");
    263  3431  carlsonj }
    264