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   2760   dg199075  * Common Development and Distribution License (the "License").
      6   2760   dg199075  * 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  10491      Rishi  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0     stevel  * Use is subject to license terms.
     24      0     stevel  */
     25      0     stevel 
     26      0     stevel #include <stdio.h>
     27      0     stevel #include <stdlib.h>
     28      0     stevel #include <string.h>
     29   2760   dg199075 #include <stddef.h>
     30      0     stevel #include <fcntl.h>
     31      0     stevel #include <string.h>
     32      0     stevel #include <sys/types.h>
     33      0     stevel #include <sys/time.h>
     34      0     stevel #include <sys/sysmacros.h>
     35      0     stevel #include <sys/socket.h>
     36      0     stevel #include <net/if.h>
     37      0     stevel #include <netinet/in_systm.h>
     38      0     stevel #include <netinet/in.h>
     39      0     stevel #include <netinet/ip.h>
     40      0     stevel #include <netinet/if_ether.h>
     41      0     stevel #include <sys/ib/clients/ibd/ibd.h>
     42   2760   dg199075 #include <sys/ethernet.h>
     43   2760   dg199075 #include <sys/vlan.h>
     44   8023       Phil #include <sys/zone.h>
     45  10616  Sebastien #include <inet/iptun.h>
     46   8023       Phil #include <sys/byteorder.h>
     47   8023       Phil #include <limits.h>
     48   8023       Phil #include <inet/ip.h>
     49   8023       Phil #include <inet/ip6.h>
     50  10491      Rishi #include <net/trill.h>
     51      0     stevel 
     52      0     stevel #include "at.h"
     53      0     stevel #include "snoop.h"
     54      0     stevel 
     55  10616  Sebastien static headerlen_fn_t ether_header_len, fddi_header_len, tr_header_len,
     56  10616  Sebastien     ib_header_len, ipnet_header_len, ipv4_header_len, ipv6_header_len;
     57  10616  Sebastien static interpreter_fn_t interpret_ether, interpret_fddi, interpret_tr,
     58  10616  Sebastien     interpret_ib, interpret_ipnet, interpret_iptun;
     59      0     stevel static void addr_copy_swap(struct ether_addr *, struct ether_addr *);
     60  10616  Sebastien static int tr_machdr_len(char *, int *, int *);
     61      0     stevel 
     62      0     stevel interface_t *interface;
     63      0     stevel interface_t INTERFACES[] = {
     64      0     stevel 
     65      0     stevel 	/* IEEE 802.3 CSMA/CD network */
     66   8023       Phil 	{ DL_CSMACD, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
     67   8023       Phil 	    ether_header_len, interpret_ether, B_TRUE },
     68      0     stevel 
     69      0     stevel 	/* Ethernet Bus */
     70   8023       Phil 	{ DL_ETHER, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
     71   8023       Phil 	    ether_header_len, interpret_ether, B_TRUE },
     72      0     stevel 
     73      0     stevel 	/* Fiber Distributed data interface */
     74   8023       Phil 	{ DL_FDDI, 4500, 19, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
     75   8023       Phil 	    fddi_header_len, interpret_fddi, B_FALSE },
     76      0     stevel 
     77      0     stevel 	/* Token Ring interface */
     78   8023       Phil 	{ DL_TPR, 17800, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
     79   8023       Phil 	    tr_header_len, interpret_tr, B_FALSE },
     80      0     stevel 
     81      0     stevel 	/* Infiniband */
     82   8023       Phil 	{ DL_IB, 4096, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
     83   8023       Phil 	    ib_header_len, interpret_ib, B_TRUE },
     84      0     stevel 
     85   8023       Phil 	/* ipnet */
     86   8105  Sebastien 	{ DL_IPNET, INT_MAX, 1, 1, IPV4_VERSION, IPV6_VERSION,
     87   8023       Phil 	    ipnet_header_len, interpret_ipnet, B_TRUE },
     88      0     stevel 
     89  10616  Sebastien 	/* IPv4 tunnel */
     90  10616  Sebastien 	{ DL_IPV4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
     91  10616  Sebastien 	    ipv4_header_len, interpret_iptun, B_FALSE },
     92  10616  Sebastien 
     93  10616  Sebastien 	/* IPv6 tunnel */
     94  10616  Sebastien 	{ DL_IPV6, 0, 40, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
     95  10616  Sebastien 	    ipv6_header_len, interpret_iptun, B_FALSE },
     96  10616  Sebastien 
     97  10616  Sebastien 	/* 6to4 tunnel */
     98  10616  Sebastien 	{ DL_6TO4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
     99  10616  Sebastien 	    ipv4_header_len, interpret_iptun, B_FALSE },
    100  10616  Sebastien 
    101   8023       Phil 	{ (uint_t)-1, 0, 0, 0, 0, NULL, NULL, B_FALSE }
    102      0     stevel };
    103      0     stevel 
    104      0     stevel /* externals */
    105      0     stevel extern char *dlc_header;
    106      0     stevel extern int pi_frame;
    107      0     stevel extern int pi_time_hour;
    108      0     stevel extern int pi_time_min;
    109      0     stevel extern int pi_time_sec;
    110      0     stevel extern int pi_time_usec;
    111      0     stevel 
    112      0     stevel char *printether();
    113      0     stevel char *print_ethertype();
    114      0     stevel static char *print_etherinfo();
    115      0     stevel 
    116      0     stevel char *print_fc();
    117      0     stevel char *print_smttype();
    118      0     stevel char *print_smtclass();
    119      0     stevel 
    120      0     stevel struct ether_addr ether_broadcast = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    121      0     stevel static char *data;			/* current data buffer */
    122      0     stevel static int datalen;			/* current data buffer length */
    123  10491      Rishi static const struct ether_addr all_isis_rbridges = ALL_ISIS_RBRIDGES;
    124      0     stevel 
    125      0     stevel uint_t
    126  10616  Sebastien interpret_ether(int flags, char *header, int elen, int origlen)
    127      0     stevel {
    128  10616  Sebastien 	struct ether_header *e = (struct ether_header *)header;
    129  10491      Rishi 	uchar_t *off, *ieeestart;
    130      0     stevel 	int len;
    131      0     stevel 	int ieee8023 = 0;
    132      0     stevel 	extern char *dst_name;
    133      0     stevel 	int ethertype;
    134   2760   dg199075 	struct ether_vlan_extinfo *evx = NULL;
    135      0     stevel 	int blen = MAX(origlen, ETHERMTU);
    136  10491      Rishi 	boolean_t trillpkt = B_FALSE;
    137  10491      Rishi 	uint16_t tci = 0;
    138      0     stevel 
    139      0     stevel 	if (data != NULL && datalen != 0 && datalen < blen) {
    140      0     stevel 		free(data);
    141      0     stevel 		data = NULL;
    142      0     stevel 		datalen = 0;
    143      0     stevel 	}
    144      0     stevel 	if (!data) {
    145      0     stevel 		data = (char *)malloc(blen);
    146      0     stevel 		if (!data)
    147      0     stevel 			pr_err("Warning: malloc failure");
    148      0     stevel 		datalen = blen;
    149      0     stevel 	}
    150  10491      Rishi inner_pkt:
    151      0     stevel 	if (origlen < 14) {
    152  10616  Sebastien 		if (flags & F_SUM) {
    153      0     stevel 			(void) sprintf(get_sum_line(),
    154  10616  Sebastien 			    "RUNT (short packet - %d bytes)",
    155  10616  Sebastien 			    origlen);
    156  10616  Sebastien 		}
    157      0     stevel 		if (flags & F_DTAIL)
    158      0     stevel 			show_header("RUNT:  ", "Short packet", origlen);
    159      0     stevel 		return (elen);
    160      0     stevel 	}
    161      0     stevel 	if (elen < 14)
    162      0     stevel 		return (elen);
    163      0     stevel 
    164      0     stevel 	if (memcmp(&e->ether_dhost, &ether_broadcast,
    165      0     stevel 	    sizeof (struct ether_addr)) == 0)
    166      0     stevel 		dst_name = "(broadcast)";
    167      0     stevel 	else if (e->ether_dhost.ether_addr_octet[0] & 1)
    168      0     stevel 		dst_name = "(multicast)";
    169      0     stevel 
    170      0     stevel 	ethertype = ntohs(e->ether_type);
    171      0     stevel 
    172      0     stevel 	/*
    173      0     stevel 	 * The 14 byte ether header screws up alignment
    174      0     stevel 	 * of the rest of the packet for 32 bit aligned
    175      0     stevel 	 * architectures like SPARC. Alas, we have to copy
    176      0     stevel 	 * the rest of the packet in order to align it.
    177      0     stevel 	 */
    178      0     stevel 	len = elen - sizeof (struct ether_header);
    179  10491      Rishi 	off = (uchar_t *)(e + 1);
    180   2760   dg199075 
    181   2760   dg199075 	if (ethertype == ETHERTYPE_VLAN) {
    182   2760   dg199075 		if (origlen < sizeof (struct ether_vlan_header)) {
    183   2760   dg199075 			if (flags & F_SUM) {
    184   2760   dg199075 				(void) sprintf(get_sum_line(),
    185   2760   dg199075 				    "RUNT (short VLAN packet - %d bytes)",
    186   2760   dg199075 				    origlen);
    187   2760   dg199075 			}
    188   2760   dg199075 			if (flags & F_DTAIL) {
    189   2760   dg199075 				show_header("RUNT:  ", "Short VLAN packet",
    190   2760   dg199075 				    origlen);
    191   2760   dg199075 			}
    192   2760   dg199075 			return (elen);
    193   2760   dg199075 		}
    194   2760   dg199075 		if (len < sizeof (struct ether_vlan_extinfo))
    195   2760   dg199075 			return (elen);
    196   2760   dg199075 
    197   2760   dg199075 		evx = (struct ether_vlan_extinfo *)off;
    198   2760   dg199075 		off += sizeof (struct ether_vlan_extinfo);
    199   2760   dg199075 		len -= sizeof (struct ether_vlan_extinfo);
    200   2760   dg199075 
    201   2760   dg199075 		ethertype = ntohs(evx->ether_type);
    202  10491      Rishi 		tci = ntohs(evx->ether_tci);
    203      0     stevel 	}
    204      0     stevel 
    205  10491      Rishi 	if (ethertype <= 1514) {
    206  10491      Rishi 		/*
    207  10491      Rishi 		 * Fake out the IEEE 802.3 packets.
    208  10491      Rishi 		 * Should be DSAP=0xAA, SSAP=0xAA, control=0x03
    209  10491      Rishi 		 * then three padding bytes of zero (OUI),
    210  10491      Rishi 		 * followed by a normal ethernet-type packet.
    211  10491      Rishi 		 */
    212  10491      Rishi 		ieee8023 = ethertype;
    213  10491      Rishi 		ieeestart = off;
    214  10491      Rishi 		if (off[0] == 0xAA && off[1] == 0xAA) {
    215  10491      Rishi 			ethertype = ntohs(*(ushort_t *)(off + 6));
    216  10491      Rishi 			off += 8;
    217  10491      Rishi 			len -= 8;
    218  10491      Rishi 		} else {
    219  10491      Rishi 			ethertype = 0;
    220  10491      Rishi 			off += 3;
    221  10491      Rishi 			len -= 3;
    222  10491      Rishi 		}
    223      0     stevel 	}
    224      0     stevel 
    225      0     stevel 	if (flags & F_SUM) {
    226   2760   dg199075 		/*
    227   2760   dg199075 		 * Set the flag that says don't display VLAN information.
    228   2760   dg199075 		 * If it needs to change, that will be done later if the
    229   2760   dg199075 		 * packet is VLAN tagged and if snoop is in its default
    230   2760   dg199075 		 * summary mode.
    231   2760   dg199075 		 */
    232   2760   dg199075 		set_vlan_id(0);
    233   2760   dg199075 		if (evx == NULL) {
    234  10491      Rishi 			if (ethertype == 0 && ieee8023 > 0) {
    235  10491      Rishi 				(void) sprintf(get_sum_line(),
    236  10491      Rishi 				    "ETHER 802.3 SSAP %02X DSAP %02X, "
    237  10491      Rishi 				    "size=%d bytes", ieeestart[0], ieeestart[1],
    238  10491      Rishi 				    origlen);
    239  10491      Rishi 			} else {
    240  10491      Rishi 				(void) sprintf(get_sum_line(),
    241  10491      Rishi 				    "ETHER Type=%04X (%s), size=%d bytes",
    242  10491      Rishi 				    ethertype, print_ethertype(ethertype),
    243  10491      Rishi 				    origlen);
    244  10491      Rishi 			}
    245   2760   dg199075 		} else {
    246  10491      Rishi 			if (ethertype == 0 && ieee8023 > 0) {
    247  10491      Rishi 				(void) sprintf(get_sum_line(),
    248  10491      Rishi 				    "ETHER 802.3 SSAP %02X DSAP %02X, "
    249  10491      Rishi 				    "VLAN ID=%hu, size=%d bytes", ieeestart[0],
    250  10491      Rishi 				    ieeestart[1], VLAN_ID(tci), origlen);
    251  10491      Rishi 			} else {
    252  10491      Rishi 				(void) sprintf(get_sum_line(),
    253  10491      Rishi 				    "ETHER Type=%04X (%s), VLAN ID=%hu, "
    254  10491      Rishi 				    "size=%d bytes", ethertype,
    255  10491      Rishi 				    print_ethertype(ethertype), VLAN_ID(tci),
    256  10491      Rishi 				    origlen);
    257  10491      Rishi 			}
    258   2760   dg199075 
    259   2760   dg199075 			if (!(flags & F_ALLSUM))
    260  10491      Rishi 				set_vlan_id(VLAN_ID(tci));
    261   2760   dg199075 		}
    262      0     stevel 	}
    263      0     stevel 
    264      0     stevel 	if (flags & F_DTAIL) {
    265  10491      Rishi 		show_header("ETHER:  ", "Ether Header", elen);
    266  10491      Rishi 		show_space();
    267  10491      Rishi 		if (!trillpkt) {
    268  10491      Rishi 			(void) sprintf(get_line(0, 0),
    269  10491      Rishi 			    "Packet %d arrived at %d:%02d:%d.%05d",
    270  10491      Rishi 			    pi_frame,
    271  10491      Rishi 			    pi_time_hour, pi_time_min, pi_time_sec,
    272  10491      Rishi 			    pi_time_usec / 10);
    273  10491      Rishi 			(void) sprintf(get_line(0, 0),
    274  10491      Rishi 			    "Packet size = %d bytes",
    275  10491      Rishi 			    elen, elen);
    276  10491      Rishi 		}
    277  10491      Rishi 		(void) sprintf(get_line(0, 6),
    278  10491      Rishi 		    "Destination = %s, %s",
    279  10491      Rishi 		    printether(&e->ether_dhost),
    280  10491      Rishi 		    print_etherinfo(&e->ether_dhost));
    281  10491      Rishi 		(void) sprintf(get_line(6, 6),
    282  10491      Rishi 		    "Source      = %s, %s",
    283  10491      Rishi 		    printether(&e->ether_shost),
    284  10491      Rishi 		    print_etherinfo(&e->ether_shost));
    285  10491      Rishi 		if (evx != NULL) {
    286  10491      Rishi 			(void) sprintf(get_line(0, 0),
    287  10491      Rishi 			    "VLAN ID     = %hu", VLAN_ID(tci));
    288  10491      Rishi 			(void) sprintf(get_line(0, 0),
    289  10491      Rishi 			    "VLAN Priority = %hu", VLAN_PRI(tci));
    290  10491      Rishi 		}
    291  10491      Rishi 		if (ieee8023 > 0) {
    292  10491      Rishi 			(void) sprintf(get_line(12, 2),
    293  10491      Rishi 			    "IEEE 802.3 length = %d bytes", ieee8023);
    294  10491      Rishi 			/* Print LLC only for non-TCP/IP packets */
    295  10491      Rishi 			if (ethertype == 0) {
    296  10491      Rishi 				(void) snprintf(get_line(0, 0),
    297  10491      Rishi 				    get_line_remain(),
    298  10491      Rishi 				    "SSAP = %02X, DSAP = %02X, CTRL = %02X",
    299  10491      Rishi 				    ieeestart[0], ieeestart[1], ieeestart[2]);
    300  10491      Rishi 			}
    301  10491      Rishi 		}
    302  10491      Rishi 		if (ethertype != 0 || ieee8023 == 0)
    303  10491      Rishi 			(void) sprintf(get_line(12, 2),
    304  10491      Rishi 			    "Ethertype = %04X (%s)",
    305  10491      Rishi 			    ethertype, print_ethertype(ethertype));
    306  10491      Rishi 		show_space();
    307      0     stevel 	}
    308      0     stevel 
    309  10491      Rishi 	/*
    310  10491      Rishi 	 * We cannot trust the length field in the header to be correct.
    311  10491      Rishi 	 * But we should continue to process the packet.  Then user can
    312  10491      Rishi 	 * notice something funny in the header.
    313  10491      Rishi 	 * Go to the next protocol layer only if data have been
    314  10491      Rishi 	 * copied.
    315  10491      Rishi 	 */
    316  10491      Rishi 	if (len > 0 && (off + len <= (uchar_t *)e + elen)) {
    317  10491      Rishi 		(void) memmove(data, off, len);
    318  10491      Rishi 
    319  10491      Rishi 		if (!trillpkt && ethertype == ETHERTYPE_TRILL) {
    320  10491      Rishi 			ethertype = interpret_trill(flags, &e, data, &len);
    321  10491      Rishi 			/* Decode inner Ethernet frame */
    322  10491      Rishi 			if (ethertype != 0) {
    323  10491      Rishi 				evx = NULL;
    324  10491      Rishi 				trillpkt = B_TRUE;
    325  10491      Rishi 				(void) memmove(data, e, len);
    326  10491      Rishi 				e = (struct ether_header *)data;
    327  10491      Rishi 				origlen = len;
    328  10491      Rishi 				elen = len;
    329  10491      Rishi 				goto inner_pkt;
    330  10491      Rishi 			}
    331  10491      Rishi 		}
    332  10491      Rishi 
    333      0     stevel 		switch (ethertype) {
    334      0     stevel 		case ETHERTYPE_IP:
    335      0     stevel 			(void) interpret_ip(flags, (struct ip *)data, len);
    336      0     stevel 			break;
    337      0     stevel 		/* Just in case it is decided to add this type */
    338      0     stevel 		case ETHERTYPE_IPV6:
    339      0     stevel 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
    340      0     stevel 			break;
    341      0     stevel 		case ETHERTYPE_ARP:
    342      0     stevel 		case ETHERTYPE_REVARP:
    343      0     stevel 			interpret_arp(flags, (struct arphdr *)data, len);
    344      0     stevel 			break;
    345      0     stevel 		case ETHERTYPE_PPPOED:
    346      0     stevel 		case ETHERTYPE_PPPOES:
    347      0     stevel 			(void) interpret_pppoe(flags, (poep_t *)data, len);
    348      0     stevel 			break;
    349      0     stevel 		case ETHERTYPE_AARP:    /* AppleTalk */
    350      0     stevel 			interpret_aarp(flags, data, len);
    351      0     stevel 			break;
    352      0     stevel 		case ETHERTYPE_AT:
    353      0     stevel 			interpret_at(flags, (struct ddp_hdr *)data, len);
    354      0     stevel 			break;
    355  10491      Rishi 		case 0:
    356  10491      Rishi 			if (ieee8023 == 0)
    357  10491      Rishi 				break;
    358  10491      Rishi 			switch (ieeestart[0]) {
    359  10491      Rishi 			case 0xFE:
    360  10491      Rishi 				interpret_isis(flags, data, len,
    361  10491      Rishi 				    memcmp(&e->ether_dhost, &all_isis_rbridges,
    362  10491      Rishi 				    sizeof (struct ether_addr)) == 0);
    363  10491      Rishi 				break;
    364  10491      Rishi 			case 0x42:
    365  10491      Rishi 				interpret_bpdu(flags, data, len);
    366  10491      Rishi 				break;
    367  10491      Rishi 			}
    368      0     stevel 			break;
    369      0     stevel 		}
    370      0     stevel 	}
    371      0     stevel 
    372      0     stevel 	return (elen);
    373      0     stevel }
    374      0     stevel 
    375   2760   dg199075 /*
    376   2760   dg199075  * Return the length of the ethernet header.  In the case
    377   2760   dg199075  * where we have a VLAN tagged packet, return the length of
    378   2760   dg199075  * the ethernet header plus the length of the VLAN tag.
    379   2760   dg199075  *
    380   2760   dg199075  * INPUTS:  e  -  A buffer pointer.  Passing a NULL pointer
    381   2760   dg199075  *                is not allowed, e must be non-NULL.
    382   2760   dg199075  * OUTPUTS:  Return the size of an untagged ethernet header
    383   2760   dg199075  *           if the packet is not VLAN tagged, and the size
    384   2760   dg199075  *           of an untagged ethernet header plus the size of
    385   2760   dg199075  *           a VLAN header otherwise.
    386   2760   dg199075  */
    387      0     stevel uint_t
    388  10616  Sebastien ether_header_len(char *e, size_t msgsize)
    389      0     stevel {
    390   2760   dg199075 	uint16_t ether_type = 0;
    391  10616  Sebastien 
    392  10616  Sebastien 	if (msgsize < sizeof (struct ether_header))
    393  10616  Sebastien 		return (0);
    394  10616  Sebastien 
    395   2760   dg199075 	e += (offsetof(struct ether_header, ether_type));
    396   2760   dg199075 
    397   2760   dg199075 	GETINT16(ether_type, e);
    398   2760   dg199075 
    399   2760   dg199075 	if (ether_type == (uint16_t)ETHERTYPE_VLAN) {
    400   2760   dg199075 		return (sizeof (struct ether_vlan_header));
    401   2760   dg199075 	} else {
    402   2760   dg199075 		return (sizeof (struct ether_header));
    403   2760   dg199075 	}
    404      0     stevel }
    405      0     stevel 
    406      0     stevel 
    407      0     stevel /*
    408      0     stevel  * Table of Ethertypes.
    409      0     stevel  * Some of the more popular entries
    410      0     stevel  * are at the beginning of the table
    411      0     stevel  * to reduce search time.
    412      0     stevel  */
    413      0     stevel struct ether_type {
    414      0     stevel 	int   e_type;
    415      0     stevel 	char *e_name;
    416      0     stevel } ether_type [] = {
    417      0     stevel ETHERTYPE_IP, "IP",
    418      0     stevel ETHERTYPE_ARP, "ARP",
    419      0     stevel ETHERTYPE_REVARP, "RARP",
    420      0     stevel ETHERTYPE_IPV6, "IPv6",
    421      0     stevel ETHERTYPE_PPPOED, "PPPoE Discovery",
    422      0     stevel ETHERTYPE_PPPOES, "PPPoE Session",
    423  10491      Rishi ETHERTYPE_TRILL, "TRILL",
    424      0     stevel /* end of popular entries */
    425      0     stevel ETHERTYPE_PUP,	"Xerox PUP",
    426      0     stevel 0x0201, "Xerox PUP",
    427      0     stevel 0x0400, "Nixdorf",
    428      0     stevel 0x0600, "Xerox NS IDP",
    429      0     stevel 0x0601, "XNS Translation",
    430      0     stevel 0x0801, "X.75 Internet",
    431      0     stevel 0x0802, "NBS Internet",
    432      0     stevel 0x0803, "ECMA Internet",
    433      0     stevel 0x0804, "CHAOSnet",
    434      0     stevel 0x0805, "X.25 Level 3",
    435      0     stevel 0x0807, "XNS Compatibility",
    436      0     stevel 0x081C, "Symbolics Private",
    437      0     stevel 0x0888, "Xyplex",
    438      0     stevel 0x0889, "Xyplex",
    439      0     stevel 0x088A, "Xyplex",
    440      0     stevel 0x0900, "Ungermann-Bass network debugger",
    441      0     stevel 0x0A00, "Xerox IEEE802.3 PUP",
    442      0     stevel 0x0A01, "Xerox IEEE802.3 PUP Address Translation",
    443      0     stevel 0x0BAD, "Banyan Systems",
    444      0     stevel 0x0BAF, "Banyon VINES Echo",
    445      0     stevel 0x1000, "Berkeley Trailer negotiation",
    446      0     stevel 0x1000,	"IP trailer (0)",
    447      0     stevel 0x1001,	"IP trailer (1)",
    448      0     stevel 0x1002,	"IP trailer (2)",
    449      0     stevel 0x1003,	"IP trailer (3)",
    450      0     stevel 0x1004,	"IP trailer (4)",
    451      0     stevel 0x1005,	"IP trailer (5)",
    452      0     stevel 0x1006,	"IP trailer (6)",
    453      0     stevel 0x1007,	"IP trailer (7)",
    454      0     stevel 0x1008,	"IP trailer (8)",
    455      0     stevel 0x1009,	"IP trailer (9)",
    456      0     stevel 0x100a,	"IP trailer (10)",
    457      0     stevel 0x100b,	"IP trailer (11)",
    458      0     stevel 0x100c,	"IP trailer (12)",
    459      0     stevel 0x100d,	"IP trailer (13)",
    460      0     stevel 0x100e,	"IP trailer (14)",
    461      0     stevel 0x100f,	"IP trailer (15)",
    462      0     stevel 0x1234, "DCA - Multicast",
    463      0     stevel 0x1600, "VALID system protocol",
    464      0     stevel 0x1989, "Aviator",
    465      0     stevel 0x3C00, "3Com NBP virtual circuit datagram",
    466      0     stevel 0x3C01, "3Com NBP System control datagram",
    467      0     stevel 0x3C02, "3Com NBP Connect request (virtual cct)",
    468      0     stevel 0x3C03, "3Com NBP Connect response",
    469      0     stevel 0x3C04, "3Com NBP Connect complete",
    470      0     stevel 0x3C05, "3Com NBP Close request (virtual cct)",
    471      0     stevel 0x3C06, "3Com NBP Close response",
    472      0     stevel 0x3C07, "3Com NBP Datagram (like XNS IDP)",
    473      0     stevel 0x3C08, "3Com NBP Datagram broadcast",
    474      0     stevel 0x3C09, "3Com NBP Claim NetBIOS name",
    475      0     stevel 0x3C0A, "3Com NBP Delete Netbios name",
    476      0     stevel 0x3C0B, "3Com NBP Remote adaptor status request",
    477      0     stevel 0x3C0C, "3Com NBP Remote adaptor response",
    478      0     stevel 0x3C0D, "3Com NBP Reset",
    479      0     stevel 0x4242, "PCS Basic Block Protocol",
    480      0     stevel 0x4321, "THD - Diddle",
    481      0     stevel 0x5208, "BBN Simnet Private",
    482      0     stevel 0x6000, "DEC unass, experimental",
    483      0     stevel 0x6001, "DEC Dump/Load",
    484      0     stevel 0x6002, "DEC Remote Console",
    485      0     stevel 0x6003, "DECNET Phase IV, DNA Routing",
    486      0     stevel 0x6004, "DEC LAT",
    487      0     stevel 0x6005, "DEC Diagnostic",
    488      0     stevel 0x6006, "DEC customer protocol",
    489      0     stevel 0x6007, "DEC Local Area VAX Cluster (LAVC)",
    490      0     stevel 0x6008, "DEC unass (AMBER?)",
    491      0     stevel 0x6009, "DEC unass (MUMPS?)",
    492      0     stevel 0x6010, "3Com",
    493      0     stevel 0x6011, "3Com",
    494      0     stevel 0x6012, "3Com",
    495      0     stevel 0x6013, "3Com",
    496      0     stevel 0x6014, "3Com",
    497      0     stevel 0x7000, "Ungermann-Bass download",
    498      0     stevel 0x7001, "Ungermann-Bass NIUs",
    499      0     stevel 0x7002, "Ungermann-Bass diagnostic/loopback",
    500      0     stevel 0x7003, "Ungermann-Bass ? (NMC to/from UB Bridge)",
    501      0     stevel 0x7005, "Ungermann-Bass Bridge Spanning Tree",
    502      0     stevel 0x7007, "OS/9 Microware",
    503      0     stevel 0x7009, "OS/9 Net?",
    504      0     stevel 0x7020, "Sintrom",
    505      0     stevel 0x7021, "Sintrom",
    506      0     stevel 0x7022, "Sintrom",
    507      0     stevel 0x7023, "Sintrom",
    508      0     stevel 0x7024, "Sintrom",
    509      0     stevel 0x7025, "Sintrom",
    510      0     stevel 0x7026, "Sintrom",
    511      0     stevel 0x7027, "Sintrom",
    512      0     stevel 0x7028, "Sintrom",
    513      0     stevel 0x7029, "Sintrom",
    514      0     stevel 0x8003, "Cronus VLN",
    515      0     stevel 0x8004, "Cronus Direct",
    516      0     stevel 0x8005, "HP Probe protocol",
    517      0     stevel 0x8006, "Nestar",
    518      0     stevel 0x8008, "AT&T/Stanford Univ",
    519      0     stevel 0x8010, "Excelan",
    520      0     stevel 0x8013, "SGI diagnostic",
    521      0     stevel 0x8014, "SGI network games",
    522      0     stevel 0x8015, "SGI reserved",
    523      0     stevel 0x8016, "SGI XNS NameServer, bounce server",
    524      0     stevel 0x8019, "Apollo DOMAIN",
    525      0     stevel 0x802E, "Tymshare",
    526      0     stevel 0x802F, "Tigan,",
    527      0     stevel 0x8036, "Aeonic Systems",
    528      0     stevel 0x8037, "IPX (Novell Netware)",
    529      0     stevel 0x8038, "DEC LanBridge Management",
    530      0     stevel 0x8039, "DEC unass (DSM/DTP?)",
    531      0     stevel 0x803A, "DEC unass (Argonaut Console?)",
    532      0     stevel 0x803B, "DEC unass (VAXELN?)",
    533      0     stevel 0x803C, "DEC unass (NMSV? DNA Naming Service?)",
    534      0     stevel 0x803D, "DEC Ethernet CSMA/CD Encryption Protocol",
    535      0     stevel 0x803E, "DEC unass (DNA Time Service?)",
    536      0     stevel 0x803F, "DEC LAN Traffic Monitor Protocol",
    537      0     stevel 0x8040, "DEC unass (NetBios Emulator?)",
    538      0     stevel 0x8041, "DEC unass (MS/DOS?, Local Area System Transport?)",
    539      0     stevel 0x8042, "DEC unass",
    540      0     stevel 0x8044, "Planning Research Corp.",
    541      0     stevel 0x8046, "AT&T",
    542      0     stevel 0x8047, "AT&T",
    543      0     stevel 0x8049, "ExperData",
    544      0     stevel 0x805B, "VMTP",
    545      0     stevel 0x805C, "Stanford V Kernel, version 6.0",
    546      0     stevel 0x805D, "Evans & Sutherland",
    547      0     stevel 0x8060, "Little Machines",
    548      0     stevel 0x8062, "Counterpoint",
    549      0     stevel 0x8065, "University of Mass. at Amherst",
    550      0     stevel 0x8066, "University of Mass. at Amherst",
    551      0     stevel 0x8067, "Veeco Integrated Automation",
    552      0     stevel 0x8068, "General Dynamics",
    553      0     stevel 0x8069, "AT&T",
    554      0     stevel 0x806A, "Autophon",
    555      0     stevel 0x806C, "ComDesign",
    556      0     stevel 0x806D, "Compugraphic Corp",
    557      0     stevel 0x806E, "Landmark",
    558      0     stevel 0x806F, "Landmark",
    559      0     stevel 0x8070, "Landmark",
    560      0     stevel 0x8071, "Landmark",
    561      0     stevel 0x8072, "Landmark",
    562      0     stevel 0x8073, "Landmark",
    563      0     stevel 0x8074, "Landmark",
    564      0     stevel 0x8075, "Landmark",
    565      0     stevel 0x8076, "Landmark",
    566      0     stevel 0x8077, "Landmark",
    567      0     stevel 0x807A, "Matra",
    568      0     stevel 0x807B, "Dansk Data Elektronik",
    569      0     stevel 0x807C, "Merit Internodal",
    570      0     stevel 0x807D, "Vitalink",
    571      0     stevel 0x807E, "Vitalink",
    572      0     stevel 0x807F, "Vitalink",
    573      0     stevel 0x8080, "Vitalink TransLAN III Management",
    574      0     stevel 0x8081, "Counterpoint",
    575      0     stevel 0x8082, "Counterpoint",
    576      0     stevel 0x8083, "Counterpoint",
    577      0     stevel 0x8088, "Xyplex",
    578      0     stevel 0x8089, "Xyplex",
    579      0     stevel 0x808A, "Xyplex",
    580      0     stevel 0x809B, "EtherTalk (AppleTalk over Ethernet)",
    581      0     stevel 0x809C, "Datability",
    582      0     stevel 0x809D, "Datability",
    583      0     stevel 0x809E, "Datability",
    584      0     stevel 0x809F, "Spider Systems",
    585      0     stevel 0x80A3, "Nixdorf",
    586      0     stevel 0x80A4, "Siemens Gammasonics",
    587      0     stevel 0x80C0, "DCA Data Exchange Cluster",
    588      0     stevel 0x80C6, "Pacer Software",
    589      0     stevel 0x80C7, "Applitek Corp",
    590      0     stevel 0x80C8, "Intergraph",
    591      0     stevel 0x80C9, "Intergraph",
    592      0     stevel 0x80CB, "Intergraph",
    593      0     stevel 0x80CC, "Intergraph",
    594      0     stevel 0x80CA, "Intergraph",
    595      0     stevel 0x80CD, "Harris Corp",
    596      0     stevel 0x80CE, "Harris Corp",
    597      0     stevel 0x80CF, "Taylor Instrument",
    598      0     stevel 0x80D0, "Taylor Instrument",
    599      0     stevel 0x80D1, "Taylor Instrument",
    600      0     stevel 0x80D2, "Taylor Instrument",
    601      0     stevel 0x80D3, "Rosemount Corp",
    602      0     stevel 0x80D4, "Rosemount Corp",
    603      0     stevel 0x80D5, "IBM SNA Services over Ethernet",
    604      0     stevel 0x80DD, "Varian Associates",
    605      0     stevel 0x80DE, "TRFS",
    606      0     stevel 0x80DF, "TRFS",
    607      0     stevel 0x80E0, "Allen-Bradley",
    608      0     stevel 0x80E1, "Allen-Bradley",
    609      0     stevel 0x80E2, "Allen-Bradley",
    610      0     stevel 0x80E3, "Allen-Bradley",
    611      0     stevel 0x80E4, "Datability",
    612      0     stevel 0x80F2, "Retix",
    613      0     stevel 0x80F3, "AARP (Appletalk)",
    614      0     stevel 0x80F4, "Kinetics",
    615      0     stevel 0x80F5, "Kinetics",
    616      0     stevel 0x80F7, "Apollo",
    617      0     stevel 0x80FF, "Wellfleet Communications",
    618      0     stevel 0x8102, "Wellfleet Communications",
    619      0     stevel 0x8107, "Symbolics Private",
    620      0     stevel 0x8108, "Symbolics Private",
    621      0     stevel 0x8109, "Symbolics Private",
    622      0     stevel 0x812B, "Talaris",
    623      0     stevel 0x8130, "Waterloo",
    624      0     stevel 0x8131, "VG Lab",
    625      0     stevel 0x8137, "Novell (old) NetWare IPX",
    626      0     stevel 0x8138, "Novell",
    627      0     stevel 0x814C, "SNMP over Ethernet",
    628      0     stevel 0x817D, "XTP",
    629      0     stevel 0x81D6, "Lantastic",
    630      0     stevel 0x8888, "HP LanProbe test?",
    631      0     stevel 0x9000, "Loopback",
    632      0     stevel 0x9001, "3Com, XNS Systems Management",
    633      0     stevel 0x9002, "3Com, TCP/IP Systems Management",
    634      0     stevel 0x9003, "3Com, loopback detection",
    635      0     stevel 0xAAAA, "DECNET	(VAX 6220 DEBNI)",
    636      0     stevel 0xFF00, "BBN VITAL-LanBridge cache wakeups",
    637      0     stevel 0,	"",
    638      0     stevel };
    639      0     stevel 
    640      0     stevel char *
    641  10616  Sebastien print_fc(uint_t type)
    642      0     stevel {
    643      0     stevel 
    644      0     stevel 	switch (type) {
    645      0     stevel 		case 0x50: return ("LLC");
    646      0     stevel 		case 0x4f: return ("SMT NSA");
    647      0     stevel 		case 0x41: return ("SMT Info");
    648      0     stevel 		default: return ("Unknown");
    649      0     stevel 	}
    650      0     stevel }
    651      0     stevel 
    652      0     stevel char *
    653  10616  Sebastien print_smtclass(uint_t type)
    654      0     stevel {
    655      0     stevel 	switch (type) {
    656      0     stevel 		case 0x01: return ("NIF");
    657      0     stevel 		case 0x02: return ("SIF Conf");
    658      0     stevel 		case 0x03: return ("SIF Oper");
    659      0     stevel 		case 0x04: return ("ECF");
    660      0     stevel 		case 0x05: return ("RAF");
    661      0     stevel 		case 0x06: return ("RDF");
    662      0     stevel 		case 0x07: return ("SRF");
    663      0     stevel 		case 0x08: return ("PMF Get");
    664      0     stevel 		case 0x09: return ("PMF Change");
    665      0     stevel 		case 0x0a: return ("PMF Add");
    666      0     stevel 		case 0x0b: return ("PMF Remove");
    667      0     stevel 		case 0xff: return ("ESF");
    668      0     stevel 		default: return ("Unknown");
    669      0     stevel 	}
    670      0     stevel 
    671      0     stevel }
    672      0     stevel char *
    673  10616  Sebastien print_smttype(uint_t type)
    674      0     stevel {
    675      0     stevel 	switch (type) {
    676      0     stevel 		case 0x01: return ("Announce");
    677      0     stevel 		case 0x02: return ("Request");
    678      0     stevel 		case 0x03: return ("Response");
    679      0     stevel 		default: return ("Unknown");
    680      0     stevel 	}
    681      0     stevel 
    682      0     stevel }
    683      0     stevel char *
    684  10616  Sebastien print_ethertype(int type)
    685      0     stevel {
    686      0     stevel 	int i;
    687      0     stevel 
    688      0     stevel 	for (i = 0; ether_type[i].e_type; i++)
    689      0     stevel 		if (type == ether_type[i].e_type)
    690      0     stevel 			return (ether_type[i].e_name);
    691      0     stevel 	if (type < 1500)
    692      0     stevel 		return ("LLC/802.3");
    693      0     stevel 
    694      0     stevel 	return ("Unknown");
    695      0     stevel }
    696      0     stevel 
    697      0     stevel #define	MAX_RDFLDS	14		/* changed to 14 from 8 as per IEEE */
    698      0     stevel #define	TR_FN_ADDR	0x80		/* dest addr is functional */
    699      0     stevel #define	TR_SR_ADDR	0x80		/* MAC utilizes source route */
    700      0     stevel #define	ACFCDASA_LEN	14		/* length of AC|FC|DA|SA */
    701      0     stevel #define	TR_MAC_MASK	0xc0
    702      0     stevel #define	TR_AC		0x00		/* Token Ring access control */
    703      0     stevel #define	TR_LLC_FC	0x40		/* Token Ring llc frame control */
    704      0     stevel #define	LSAP_SNAP	0xaa
    705      0     stevel #define	LLC_SNAP_HDR_LEN	8
    706      0     stevel #define	LLC_HDR1_LEN	3		/* DON'T use sizeof(struct llc_hdr1) */
    707      0     stevel #define	CNTL_LLC_UI	0x03		/* un-numbered information packet */
    708      0     stevel 
    709      0     stevel /*
    710      0     stevel  * Source Routing Route Information field.
    711      0     stevel  */
    712      0     stevel struct tr_ri {
    713      0     stevel #if defined(_BIT_FIELDS_HTOL)
    714      0     stevel 	uchar_t rt:3;			/* routing type */
    715      0     stevel 	uchar_t len:5;			/* length */
    716      0     stevel 	uchar_t dir:1;			/* direction bit */
    717      0     stevel 	uchar_t mtu:3;			/* largest frame */
    718      0     stevel 	uchar_t res:4;			/* reserved */
    719      0     stevel #elif defined(_BIT_FIELDS_LTOH)
    720      0     stevel 	uchar_t len:5;			/* length */
    721      0     stevel 	uchar_t rt:3;			/* routing type */
    722      0     stevel 	uchar_t res:4;			/* reserved */
    723      0     stevel 	uchar_t mtu:3;			/* largest frame */
    724      0     stevel 	uchar_t dir:1;			/* direction bit */
    725      0     stevel #endif
    726      0     stevel /*
    727      0     stevel  * In little endian machine, the ring field has to be stored in a
    728      0     stevel  * ushort_t type.  This implies that it is not possible to have a
    729      0     stevel  * layout of bit field to represent bridge and ring.
    730      0     stevel  *
    731      0     stevel  * If the compiler uses _BIT_FIELDS_HTOL and it is a big endian
    732      0     stevel  * machine, the following bit field definition will work.
    733      0     stevel  *
    734      0     stevel  *	struct tr_rd {
    735      0     stevel  *		ushort_t bridge:4;
    736      0     stevel  *		ushort_t ring:12;
    737      0     stevel  *	} rd[MAX_RDFLDS];
    738      0     stevel  *
    739      0     stevel  * If the compiler uses _BIT_FIELDS_LTOH and it is a big endian
    740      0     stevel  * machine, the definition can be changed to
    741      0     stevel  *
    742      0     stevel  *	struct tr_rd {
    743      0     stevel  *		ushort_t bridge:4;
    744      0     stevel  *		ushort_t ring:12;
    745      0     stevel  *	} rd[MAX_RDFLDS];
    746      0     stevel  *
    747      0     stevel  * With little endian machine, we need to use 2 macroes.  For
    748      0     stevel  * simplicity, since the macroes work for both big and little
    749      0     stevel  * endian machines, we will not use bit fields for the
    750      0     stevel  * definition.
    751      0     stevel  */
    752      0     stevel #define	bridge(route)	(ntohs((ushort_t)(route)) & 0x0F)
    753      0     stevel #define	ring(route)	(ntohs((ushort_t)(route)) >> 4)
    754      0     stevel 
    755      0     stevel 	ushort_t rd[MAX_RDFLDS];	/* route designator fields */
    756      0     stevel };
    757      0     stevel 
    758      0     stevel struct tr_header {
    759      0     stevel 	uchar_t		ac;
    760      0     stevel 	uchar_t		fc;
    761      0     stevel 	struct ether_addr dhost;
    762      0     stevel 	struct ether_addr shost;
    763      0     stevel 	struct tr_ri	ri;
    764      0     stevel };
    765      0     stevel 
    766      0     stevel struct llc_snap_hdr {
    767      0     stevel 	uchar_t  d_lsap;		/* destination service access point */
    768      0     stevel 	uchar_t  s_lsap;		/* source link service access point */
    769      0     stevel 	uchar_t  control;		/* short control field */
    770      0     stevel 	uchar_t  org[3];		/* Ethernet style organization field */
    771      0     stevel 	ushort_t type;			/* Ethernet style type field */
    772      0     stevel };
    773      0     stevel 
    774      0     stevel struct ether_addr tokenbroadcastaddr2 = {
    775      0     stevel 	0xc0, 0x00, 0xff, 0xff, 0xff, 0xff
    776      0     stevel };
    777      0     stevel 
    778      0     stevel int Mtutab[] = {516, 1470, 2052, 4472, 8144, 11407, 17800};
    779      0     stevel 
    780      0     stevel char *
    781      0     stevel print_sr(struct tr_ri *rh)
    782      0     stevel {
    783      0     stevel 	int hops, ii;
    784      0     stevel 	static char line[512];
    785      0     stevel 
    786      0     stevel 	sprintf(line, "TR Source Route dir=%d, mtu=%d",
    787   8023       Phil 	    rh->dir, Mtutab[rh->mtu]);
    788      0     stevel 
    789      0     stevel 	hops = (int)(rh->len - 2) / (int)2;
    790      0     stevel 
    791      0     stevel 	if (hops) {
    792      0     stevel 		sprintf(line+strlen(line), ", Route: ");
    793      0     stevel 		for (ii = 0; ii < hops; ii++) {
    794      0     stevel 			if (! bridge(rh->rd[ii])) {
    795      0     stevel 				sprintf(line+strlen(line), "(%d)",
    796      0     stevel 				    ring(rh->rd[ii]));
    797      0     stevel 			} else {
    798      0     stevel 				sprintf(line+strlen(line), "(%d)%d",
    799      0     stevel 				    ring(rh->rd[ii]), bridge(rh->rd[ii]));
    800      0     stevel 			}
    801      0     stevel 		}
    802      0     stevel 	}
    803      0     stevel 	return (&line[0]);
    804      0     stevel }
    805      0     stevel 
    806      0     stevel uint_t
    807  10616  Sebastien interpret_tr(int flags, caddr_t e, int elen, int origlen)
    808      0     stevel {
    809      0     stevel 	struct tr_header *mh;
    810      0     stevel 	struct tr_ri *rh;
    811      0     stevel 	uchar_t fc;
    812      0     stevel 	struct llc_snap_hdr *snaphdr;
    813      0     stevel 	char *off;
    814      0     stevel 	int maclen, len;
    815      0     stevel 	boolean_t data_copied = B_FALSE;
    816      0     stevel 	extern char *dst_name, *src_name;
    817      0     stevel 	int ethertype;
    818      0     stevel 	int is_llc = 0, is_snap = 0, source_routing = 0;
    819      0     stevel 	int blen = MAX(origlen, 17800);
    820      0     stevel 
    821      0     stevel 	if (data != NULL && datalen != 0 && datalen < blen) {
    822      0     stevel 		free(data);
    823      0     stevel 		data = NULL;
    824      0     stevel 		datalen = 0;
    825      0     stevel 	}
    826      0     stevel 	if (!data) {
    827      0     stevel 		data = (char *)malloc(blen);
    828      0     stevel 		if (!data)
    829      0     stevel 			pr_err("Warning: malloc failure");
    830      0     stevel 		datalen = blen;
    831      0     stevel 	}
    832      0     stevel 
    833      0     stevel 	if (origlen < ACFCDASA_LEN) {
    834  10616  Sebastien 		if (flags & F_SUM) {
    835      0     stevel 			(void) sprintf(get_sum_line(),
    836  10616  Sebastien 			    "RUNT (short packet - %d bytes)",
    837  10616  Sebastien 			    origlen);
    838  10616  Sebastien 		}
    839      0     stevel 		if (flags & F_DTAIL)
    840      0     stevel 			show_header("RUNT:  ", "Short packet", origlen);
    841      0     stevel 		return (elen);
    842      0     stevel 	}
    843      0     stevel 	if (elen < ACFCDASA_LEN)
    844      0     stevel 		return (elen);
    845      0     stevel 
    846      0     stevel 	mh = (struct tr_header *)e;
    847      0     stevel 	rh = (struct tr_ri *)&mh->ri;
    848      0     stevel 	fc = mh->fc;
    849      0     stevel 
    850      0     stevel 	if (is_llc = tr_machdr_len(e, &maclen, &source_routing)) {
    851      0     stevel 		snaphdr = (struct llc_snap_hdr *)(e + maclen);
    852      0     stevel 		if (snaphdr->d_lsap == LSAP_SNAP &&
    853  10616  Sebastien 		    snaphdr->s_lsap == LSAP_SNAP &&
    854  10616  Sebastien 		    snaphdr->control == CNTL_LLC_UI) {
    855      0     stevel 			is_snap = 1;
    856      0     stevel 		}
    857      0     stevel 	}
    858      0     stevel 
    859      0     stevel 	if (memcmp(&mh->dhost, &ether_broadcast,
    860      0     stevel 	    sizeof (struct ether_addr)) == 0)
    861      0     stevel 		dst_name = "(broadcast)";
    862      0     stevel 	else if (memcmp(&mh->dhost, &tokenbroadcastaddr2,
    863  10616  Sebastien 	    sizeof (struct ether_addr)) == 0)
    864      0     stevel 		dst_name = "(mac broadcast)";
    865      0     stevel 	else if (mh->dhost.ether_addr_octet[0] & TR_FN_ADDR)
    866      0     stevel 		dst_name = "(functional)";
    867      0     stevel 
    868      0     stevel 	if (is_snap)
    869      0     stevel 		ethertype = ntohs(snaphdr->type);
    870      0     stevel 	else {
    871      0     stevel 		src_name =  print_etherinfo(&mh->shost);
    872      0     stevel 		dst_name =  print_etherinfo(&mh->dhost);
    873      0     stevel 	}
    874      0     stevel 
    875      0     stevel 	/*
    876      0     stevel 	 * The 14 byte ether header screws up alignment
    877      0     stevel 	 * of the rest of the packet for 32 bit aligned
    878      0     stevel 	 * architectures like SPARC. Alas, we have to copy
    879      0     stevel 	 * the rest of the packet in order to align it.
    880      0     stevel 	 */
    881      0     stevel 	if (is_llc) {
    882      0     stevel 		if (is_snap) {
    883      0     stevel 			len = elen - (maclen + LLC_SNAP_HDR_LEN);
    884      0     stevel 			off = (char *)(e + maclen + LLC_SNAP_HDR_LEN);
    885      0     stevel 		} else {
    886      0     stevel 			len = elen - (maclen + LLC_HDR1_LEN);
    887      0     stevel 			off = (char *)(e + maclen + LLC_HDR1_LEN);
    888      0     stevel 		}
    889      0     stevel 	} else {
    890      0     stevel 		len = elen - maclen;
    891      0     stevel 		off = (char *)(e + maclen);
    892      0     stevel 	}
    893      0     stevel 
    894      0     stevel 	if (len > 0 && (off + len <= (char *)e + elen)) {
    895      0     stevel 		(void) memcpy(data, off, len);
    896      0     stevel 		data_copied = B_TRUE;
    897      0     stevel 	}
    898      0     stevel 
    899      0     stevel 	if (flags & F_SUM) {
    900      0     stevel 		if (source_routing)
    901      0     stevel 			sprintf(get_sum_line(), print_sr(rh));
    902      0     stevel 
    903      0     stevel 		if (is_llc) {
    904      0     stevel 			if (is_snap) {
    905  10616  Sebastien 				(void) sprintf(get_sum_line(), "TR LLC w/SNAP "
    906  10616  Sebastien 				    "Type=%04X (%s), size=%d bytes",
    907  10616  Sebastien 				    ethertype,
    908  10616  Sebastien 				    print_ethertype(ethertype),
    909  10616  Sebastien 				    origlen);
    910      0     stevel 			} else {
    911  10616  Sebastien 				(void) sprintf(get_sum_line(), "TR LLC, but no "
    912  10616  Sebastien 				    "SNAP encoding, size = %d bytes",
    913  10616  Sebastien 				    origlen);
    914      0     stevel 			}
    915      0     stevel 		} else {
    916      0     stevel 			(void) sprintf(get_sum_line(),
    917  10616  Sebastien 			    "TR MAC FC=%02X (%s), size = %d bytes",
    918  10616  Sebastien 			    fc, print_fc(fc), origlen);
    919      0     stevel 		}
    920      0     stevel 	}
    921      0     stevel 
    922      0     stevel 	if (flags & F_DTAIL) {
    923  10616  Sebastien 		show_header("TR:  ", "TR Header", elen);
    924  10616  Sebastien 		show_space();
    925  10616  Sebastien 		(void) sprintf(get_line(0, 0),
    926  10616  Sebastien 		    "Packet %d arrived at %d:%02d:%d.%05d",
    927  10616  Sebastien 		    pi_frame,
    928  10616  Sebastien 		    pi_time_hour, pi_time_min, pi_time_sec,
    929  10616  Sebastien 		    pi_time_usec / 10);
    930  10616  Sebastien 		(void) sprintf(get_line(0, 0),
    931  10616  Sebastien 		    "Packet size = %d bytes",
    932  10616  Sebastien 		    elen);
    933  10616  Sebastien 		(void) sprintf(get_line(0, 1),
    934  10616  Sebastien 		    "Frame Control = %02x (%s)",
    935  10616  Sebastien 		    fc, print_fc(fc));
    936  10616  Sebastien 		(void) sprintf(get_line(2, 6),
    937  10616  Sebastien 		    "Destination = %s, %s",
    938  10616  Sebastien 		    printether(&mh->dhost),
    939  10616  Sebastien 		    print_etherinfo(&mh->dhost));
    940  10616  Sebastien 		(void) sprintf(get_line(8, 6),
    941  10616  Sebastien 		    "Source      = %s, %s",
    942  10616  Sebastien 		    printether(&mh->shost),
    943  10616  Sebastien 		    print_etherinfo(&mh->shost));
    944      0     stevel 
    945  10616  Sebastien 		if (source_routing)
    946  10616  Sebastien 			sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh));
    947      0     stevel 
    948  10616  Sebastien 		if (is_llc) {
    949  10616  Sebastien 			(void) sprintf(get_line(maclen, 1),
    950  10616  Sebastien 			    "Dest   Service Access Point = %02x",
    951  10616  Sebastien 			    snaphdr->d_lsap);
    952  10616  Sebastien 			(void) sprintf(get_line(maclen+1, 1),
    953  10616  Sebastien 			    "Source Service Access Point = %02x",
    954  10616  Sebastien 			    snaphdr->s_lsap);
    955  10616  Sebastien 			(void) sprintf(get_line(maclen+2, 1),
    956  10616  Sebastien 			    "Control = %02x",
    957  10616  Sebastien 			    snaphdr->control);
    958  10616  Sebastien 			if (is_snap) {
    959  10616  Sebastien 				(void) sprintf(get_line(maclen+3, 3),
    960  10616  Sebastien 				    "SNAP Protocol Id = %02x%02x%02x",
    961  10616  Sebastien 				    snaphdr->org[0], snaphdr->org[1],
    962  10616  Sebastien 				    snaphdr->org[2]);
    963  10616  Sebastien 			}
    964  10616  Sebastien 		}
    965      0     stevel 
    966  10616  Sebastien 		if (is_snap) {
    967  10616  Sebastien 			(void) sprintf(get_line(maclen+6, 2),
    968  10616  Sebastien 			    "SNAP Type = %04X (%s)",
    969  10616  Sebastien 			    ethertype, print_ethertype(ethertype));
    970  10616  Sebastien 		}
    971      0     stevel 
    972  10616  Sebastien 		show_space();
    973      0     stevel 	}
    974      0     stevel 
    975      0     stevel 	/* go to the next protocol layer */
    976      0     stevel 	if (is_snap && data_copied) {
    977      0     stevel 		switch (ethertype) {
    978      0     stevel 		case ETHERTYPE_IP:
    979      0     stevel 			(void) interpret_ip(flags, (struct ip *)data, len);
    980      0     stevel 			break;
    981      0     stevel 		/* Just in case it is decided to add this type */
    982      0     stevel 		case ETHERTYPE_IPV6:
    983      0     stevel 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
    984      0     stevel 			break;
    985      0     stevel 		case ETHERTYPE_ARP:
    986      0     stevel 		case ETHERTYPE_REVARP:
    987      0     stevel 			interpret_arp(flags, (struct arphdr *)data, len);
    988      0     stevel 			break;
    989      0     stevel 		case ETHERTYPE_AARP:	/* AppleTalk */
    990      0     stevel 			interpret_aarp(flags, data, len);
    991      0     stevel 			break;
    992      0     stevel 		case ETHERTYPE_AT:
    993      0     stevel 			interpret_at(flags, (struct ddp_hdr *)data, len);
    994      0     stevel 			break;
    995      0     stevel 		default:
    996      0     stevel 			break;
    997      0     stevel 		}
    998      0     stevel 	}
    999      0     stevel 
   1000      0     stevel 	return (elen);
   1001      0     stevel }
   1002      0     stevel 
   1003      0     stevel 
   1004      0     stevel /*
   1005      0     stevel  *	stuffs length of mac and ri fields into *lenp
   1006      0     stevel  *	returns:
   1007      0     stevel  *		0: mac frame
   1008      0     stevel  *		1: llc frame
   1009      0     stevel  */
   1010  10616  Sebastien static int
   1011      0     stevel tr_machdr_len(char *e, int *lenp, int *source_routing)
   1012      0     stevel {
   1013      0     stevel 	struct tr_header *mh;
   1014      0     stevel 	struct tr_ri *rh;
   1015      0     stevel 	uchar_t fc;
   1016      0     stevel 
   1017      0     stevel 	mh = (struct tr_header *)e;
   1018      0     stevel 	rh = (struct tr_ri *)&mh->ri;
   1019      0     stevel 	fc = mh->fc;
   1020      0     stevel 
   1021      0     stevel 	if (mh->shost.ether_addr_octet[0] & TR_SR_ADDR) {
   1022      0     stevel 		*lenp = ACFCDASA_LEN + rh->len;
   1023      0     stevel 		*source_routing = 1;
   1024      0     stevel 	} else {
   1025      0     stevel 		*lenp = ACFCDASA_LEN;
   1026      0     stevel 		*source_routing = 0;
   1027      0     stevel 	}
   1028      0     stevel 
   1029      0     stevel 	if ((fc & TR_MAC_MASK) == 0)
   1030      0     stevel 		return (0);		/* it's a MAC frame */
   1031      0     stevel 	else
   1032      0     stevel 		return (1);		/* it's an LLC frame */
   1033      0     stevel }
   1034      0     stevel 
   1035      0     stevel uint_t
   1036  10616  Sebastien tr_header_len(char *e, size_t msgsize)
   1037      0     stevel {
   1038      0     stevel 	struct llc_snap_hdr *snaphdr;
   1039      0     stevel 	int len = 0, source_routing;
   1040      0     stevel 
   1041      0     stevel 	if (tr_machdr_len(e, &len, &source_routing) == 0)
   1042      0     stevel 		return (len);		/* it's a MAC frame */
   1043      0     stevel 
   1044  10616  Sebastien 	if (msgsize < sizeof (struct llc_snap_hdr))
   1045  10616  Sebastien 		return (0);
   1046  10616  Sebastien 
   1047      0     stevel 	snaphdr = (struct llc_snap_hdr *)(e + len);
   1048      0     stevel 	if (snaphdr->d_lsap == LSAP_SNAP &&
   1049  10616  Sebastien 	    snaphdr->s_lsap == LSAP_SNAP &&
   1050  10616  Sebastien 	    snaphdr->control == CNTL_LLC_UI)
   1051      0     stevel 		len += LLC_SNAP_HDR_LEN;	/* it's a SNAP frame */
   1052      0     stevel 	else
   1053      0     stevel 		len += LLC_HDR1_LEN;
   1054      0     stevel 
   1055      0     stevel 	return (len);
   1056      0     stevel }
   1057      0     stevel 
   1058      0     stevel struct fddi_header {
   1059      0     stevel 	uchar_t fc;
   1060      0     stevel 	struct ether_addr dhost, shost;
   1061      0     stevel 	uchar_t dsap, ssap, ctl, proto_id[3];
   1062      0     stevel 	ushort_t	type;
   1063      0     stevel };
   1064      0     stevel 
   1065      0     stevel uint_t
   1066  10616  Sebastien interpret_fddi(int flags, caddr_t e, int elen, int origlen)
   1067      0     stevel {
   1068      0     stevel 	struct fddi_header fhdr, *f = &fhdr;
   1069      0     stevel 	char *off;
   1070      0     stevel 	int len;
   1071      0     stevel 	boolean_t data_copied = B_FALSE;
   1072      0     stevel 	extern char *dst_name, *src_name;
   1073      0     stevel 	int ethertype;
   1074      0     stevel 	int is_llc = 0, is_smt = 0, is_snap = 0;
   1075      0     stevel 	int blen = MAX(origlen, 4500);
   1076      0     stevel 
   1077      0     stevel 	if (data != NULL && datalen != 0 && datalen < blen) {
   1078      0     stevel 		free(data);
   1079      0     stevel 		data = NULL;
   1080      0     stevel 		datalen = 0;
   1081      0     stevel 	}
   1082      0     stevel 	if (!data) {
   1083      0     stevel 		data = (char *)malloc(blen);
   1084      0     stevel 		if (!data)
   1085      0     stevel 			pr_err("Warning: malloc failure");
   1086      0     stevel 		datalen = blen;
   1087      0     stevel 	}
   1088      0     stevel 
   1089      0     stevel 	if (origlen < 13) {
   1090  10616  Sebastien 		if (flags & F_SUM) {
   1091      0     stevel 			(void) sprintf(get_sum_line(),
   1092  10616  Sebastien 			    "RUNT (short packet - %d bytes)",
   1093  10616  Sebastien 			    origlen);
   1094  10616  Sebastien 		}
   1095      0     stevel 		if (flags & F_DTAIL)
   1096      0     stevel 			show_header("RUNT:  ", "Short packet", origlen);
   1097      0     stevel 		return (elen);
   1098      0     stevel 	}
   1099      0     stevel 	if (elen < 13)
   1100      0     stevel 		return (elen);
   1101      0     stevel 
   1102      0     stevel 	(void) memcpy(&f->fc, e, sizeof (f->fc));
   1103      0     stevel 	addr_copy_swap(&f->dhost, (struct ether_addr *)(e+1));
   1104      0     stevel 	addr_copy_swap(&f->shost, (struct ether_addr *)(e+7));
   1105      0     stevel 
   1106      0     stevel 	if ((f->fc&0x50) == 0x50) {
   1107      0     stevel 		is_llc = 1;
   1108      0     stevel 		(void) memcpy(&f->dsap, e+13, sizeof (f->dsap));
   1109      0     stevel 		(void) memcpy(&f->ssap, e+14, sizeof (f->ssap));
   1110      0     stevel 		(void) memcpy(&f->ctl, e+15, sizeof (f->ctl));
   1111      0     stevel 		if (f->dsap == 0xaa && f->ssap == 0xaa) {
   1112      0     stevel 			is_snap = 1;
   1113      0     stevel 			(void) memcpy(&f->proto_id, e+16, sizeof (f->proto_id));
   1114      0     stevel 			(void) memcpy(&f->type, e+19, sizeof (f->type));
   1115      0     stevel 		}
   1116      0     stevel 	} else {
   1117      0     stevel 		if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) {
   1118      0     stevel 			is_smt = 1;
   1119      0     stevel 		}
   1120      0     stevel 	}
   1121      0     stevel 
   1122      0     stevel 
   1123      0     stevel 	if (memcmp(&f->dhost, &ether_broadcast,
   1124      0     stevel 	    sizeof (struct ether_addr)) == 0)
   1125      0     stevel 		dst_name = "(broadcast)";
   1126      0     stevel 	else if (f->dhost.ether_addr_octet[0] & 0x01)
   1127      0     stevel 		dst_name = "(multicast)";
   1128      0     stevel 
   1129      0     stevel 	if (is_snap)
   1130      0     stevel 		ethertype = ntohs(f->type);
   1131      0     stevel 	else {
   1132      0     stevel 		src_name = 	print_etherinfo(&f->shost);
   1133      0     stevel 		dst_name =  print_etherinfo(&f->dhost);
   1134      0     stevel 	}
   1135      0     stevel 
   1136      0     stevel 	/*
   1137      0     stevel 	 * The 14 byte ether header screws up alignment
   1138      0     stevel 	 * of the rest of the packet for 32 bit aligned
   1139      0     stevel 	 * architectures like SPARC. Alas, we have to copy
   1140      0     stevel 	 * the rest of the packet in order to align it.
   1141      0     stevel 	 */
   1142      0     stevel 	if (is_llc) {
   1143      0     stevel 		if (is_snap) {
   1144      0     stevel 			len = elen - 21;
   1145      0     stevel 			off = (char *)(e + 21);
   1146      0     stevel 		} else {
   1147      0     stevel 			len = elen - 16;
   1148      0     stevel 			off = (char *)(e + 16);
   1149      0     stevel 		}
   1150      0     stevel 	} else {
   1151      0     stevel 		len = elen - 13;
   1152      0     stevel 		off = (char *)(e + 13);
   1153      0     stevel 	}
   1154      0     stevel 
   1155      0     stevel 	if (len > 0 && (off + len <= (char *)e + elen)) {
   1156      0     stevel 		(void) memcpy(data, off, len);
   1157      0     stevel 		data_copied = B_TRUE;
   1158      0     stevel 	}
   1159      0     stevel 
   1160      0     stevel 	if (flags & F_SUM) {
   1161      0     stevel 		if (is_llc) {
   1162      0     stevel 			if (is_snap) {
   1163      0     stevel 				(void) sprintf(get_sum_line(),
   1164  10616  Sebastien 				    "FDDI LLC Type=%04X (%s), size = %d bytes",
   1165  10616  Sebastien 				    ethertype,
   1166  10616  Sebastien 				    print_ethertype(ethertype),
   1167  10616  Sebastien 				    origlen);
   1168      0     stevel 			} else {
   1169  10616  Sebastien 				(void) sprintf(get_sum_line(), "LLC, but no "
   1170  10616  Sebastien 				    "SNAP encoding, size = %d bytes",
   1171  10616  Sebastien 				    origlen);
   1172      0     stevel 			}
   1173      0     stevel 		} else if (is_smt) {
   1174  10616  Sebastien 			(void) sprintf(get_sum_line(), "SMT Type=%02X (%s), "
   1175  10616  Sebastien 			    "Class = %02X (%s), size = %d bytes",
   1176  10616  Sebastien 			    *(uchar_t *)(data+1), print_smttype(*(data+1)),
   1177  10616  Sebastien 			    *data, print_smtclass(*data), origlen);
   1178      0     stevel 		} else {
   1179      0     stevel 			(void) sprintf(get_sum_line(),
   1180  10616  Sebastien 			    "FC=%02X (%s), size = %d bytes",
   1181  10616  Sebastien 			    f->fc, print_fc(f->fc), origlen);
   1182      0     stevel 		}
   1183      0     stevel 	}
   1184      0     stevel 
   1185      0     stevel 	if (flags & F_DTAIL) {
   1186  10616  Sebastien 		show_header("FDDI:  ", "FDDI Header", elen);
   1187  10616  Sebastien 		show_space();
   1188  10616  Sebastien 		(void) sprintf(get_line(0, 0),
   1189  10616  Sebastien 		    "Packet %d arrived at %d:%02d:%d.%05d",
   1190  10616  Sebastien 		    pi_frame,
   1191  10616  Sebastien 		    pi_time_hour, pi_time_min, pi_time_sec,
   1192  10616  Sebastien 		    pi_time_usec / 10);
   1193  10616  Sebastien 		(void) sprintf(get_line(0, 0),
   1194  10616  Sebastien 		    "Packet size = %d bytes",
   1195  10616  Sebastien 		    elen, elen);
   1196  10616  Sebastien 		(void) sprintf(get_line(0, 6),
   1197  10616  Sebastien 		    "Destination = %s, %s",
   1198  10616  Sebastien 		    printether(&f->dhost),
   1199  10616  Sebastien 		    print_etherinfo(&f->dhost));
   1200  10616  Sebastien 		(void) sprintf(get_line(6, 6),
   1201  10616  Sebastien 		    "Source      = %s, %s",
   1202  10616  Sebastien 		    printether(&f->shost),
   1203  10616  Sebastien 		    print_etherinfo(&f->shost));
   1204      0     stevel 
   1205  10616  Sebastien 		if (is_llc) {
   1206      0     stevel 			(void) sprintf(get_line(12, 2),
   1207  10616  Sebastien 			    "Frame Control = %02x (%s)",
   1208  10616  Sebastien 			    f->fc, print_fc(f->fc));
   1209  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1210  10616  Sebastien 			    "Dest   Service Access Point = %02x",
   1211  10616  Sebastien 			    f->dsap);
   1212  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1213  10616  Sebastien 			    "Source Service Access Point = %02x",
   1214  10616  Sebastien 			    f->ssap);
   1215  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1216  10616  Sebastien 			    "Control = %02x",
   1217  10616  Sebastien 			    f->ctl);
   1218  10616  Sebastien 			if (is_snap) {
   1219  10616  Sebastien 				(void) sprintf(get_line(12, 2),
   1220  10616  Sebastien 				    "Protocol Id = %02x%02x%02x",
   1221  10616  Sebastien 				    f->proto_id[0], f->proto_id[1],
   1222  10616  Sebastien 				    f->proto_id[2]);
   1223  10616  Sebastien 			}
   1224  10616  Sebastien 		} else if (is_smt) {
   1225  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1226  10616  Sebastien 			    "Frame Control = %02x (%s)",
   1227  10616  Sebastien 			    f->fc, print_fc(f->fc));
   1228  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1229  10616  Sebastien 			    "Class = %02x (%s)",
   1230  10616  Sebastien 			    (uchar_t)*data, print_smtclass(*data));
   1231  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1232  10616  Sebastien 			    "Type = %02x (%s)",
   1233  10616  Sebastien 			    *(uchar_t *)(data+1), print_smttype(*(data+1)));
   1234  10616  Sebastien 		} else {
   1235  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1236  10616  Sebastien 			    "FC=%02X (%s), size = %d bytes",
   1237  10616  Sebastien 			    f->fc, print_fc(f->fc), origlen);
   1238  10616  Sebastien 		}
   1239      0     stevel 
   1240  10616  Sebastien 		if (is_snap) {
   1241  10616  Sebastien 			(void) sprintf(get_line(12, 2),
   1242  10616  Sebastien 			    "LLC Type = %04X (%s)",
   1243  10616  Sebastien 			    ethertype, print_ethertype(ethertype));
   1244  10616  Sebastien 		}
   1245      0     stevel 
   1246  10616  Sebastien 		show_space();
   1247      0     stevel 	}
   1248      0     stevel 
   1249      0     stevel 	/* go to the next protocol layer */
   1250      0     stevel 	if (is_llc && is_snap && f->ctl == 0x03 && data_copied) {
   1251      0     stevel 		switch (ethertype) {
   1252      0     stevel 		case ETHERTYPE_IP:
   1253      0     stevel 			(void) interpret_ip(flags, (struct ip *)data, len);
   1254      0     stevel 			break;
   1255      0     stevel 		/* Just in case it is decided to add this type */
   1256      0     stevel 		case ETHERTYPE_IPV6:
   1257      0     stevel 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
   1258      0     stevel 			break;
   1259      0     stevel 		case ETHERTYPE_ARP:
   1260      0     stevel 		case ETHERTYPE_REVARP:
   1261      0     stevel 			interpret_arp(flags, (struct arphdr *)data, len);
   1262      0     stevel 			break;
   1263      0     stevel 		default:
   1264      0     stevel 			break;
   1265      0     stevel 		}
   1266      0     stevel 
   1267      0     stevel 	}
   1268      0     stevel 
   1269      0     stevel 	return (elen);
   1270      0     stevel }
   1271      0     stevel 
   1272      0     stevel uint_t
   1273  10616  Sebastien fddi_header_len(char *e, size_t msgsize)
   1274      0     stevel {
   1275      0     stevel 	struct fddi_header fhdr, *f = &fhdr;
   1276  10616  Sebastien 
   1277  10616  Sebastien 	if (msgsize < sizeof (struct fddi_header))
   1278  10616  Sebastien 		return (0);
   1279      0     stevel 
   1280      0     stevel 	(void) memcpy(&f->fc, e, sizeof (f->fc));
   1281      0     stevel 	(void) memcpy(&f->dhost, e+1, sizeof (struct ether_addr));
   1282      0     stevel 	(void) memcpy(&f->shost, e+7, sizeof (struct ether_addr));
   1283      0     stevel 
   1284      0     stevel 	if ((f->fc&0x50) == 0x50) {
   1285      0     stevel 		(void) memcpy(&f->dsap, e+13, sizeof (f->dsap));
   1286      0     stevel 		(void) memcpy(&f->ssap, e+14, sizeof (f->ssap));
   1287      0     stevel 		(void) memcpy(&f->ctl, e+15, sizeof (f->ctl));
   1288      0     stevel 		if (f->dsap == 0xaa && f->ssap == 0xaa) {
   1289      0     stevel 			return (21);
   1290      0     stevel 		}
   1291      0     stevel 		return (16);
   1292      0     stevel 	} else {
   1293      0     stevel 		if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) {
   1294      0     stevel 			return (13);
   1295      0     stevel 		}
   1296      0     stevel 	}
   1297    410     kcpoon 	/* Return the default FDDI header length. */
   1298    410     kcpoon 	return (13);
   1299      0     stevel }
   1300      0     stevel 
   1301      0     stevel /*
   1302      0     stevel  * Print the given Ethernet address
   1303      0     stevel  */
   1304      0     stevel char *
   1305  10616  Sebastien printether(struct ether_addr *p)
   1306      0     stevel {
   1307      0     stevel 	static char buf[256];
   1308      0     stevel 
   1309      0     stevel 	sprintf(buf, "%x:%x:%x:%x:%x:%x",
   1310  10616  Sebastien 	    p->ether_addr_octet[0],
   1311  10616  Sebastien 	    p->ether_addr_octet[1],
   1312  10616  Sebastien 	    p->ether_addr_octet[2],
   1313  10616  Sebastien 	    p->ether_addr_octet[3],
   1314  10616  Sebastien 	    p->ether_addr_octet[4],
   1315  10616  Sebastien 	    p->ether_addr_octet[5]);
   1316      0     stevel 
   1317      0     stevel 	return (buf);
   1318      0     stevel }
   1319      0     stevel 
   1320      0     stevel /*
   1321      0     stevel  * Table of Ethernet Address Assignments
   1322      0     stevel  * Some of the more popular entries
   1323      0     stevel  * are at the beginning of the table
   1324      0     stevel  * to reduce search time.  Note that the
   1325      0     stevel  * e-block's are stored in host byte-order.
   1326      0     stevel  */
   1327      0     stevel struct block_type {
   1328      0     stevel 	int	e_block;
   1329      0     stevel 	char	*e_name;
   1330      0     stevel } ether_block [] = {
   1331      0     stevel 0x080020,	"Sun",
   1332      0     stevel 0x0000C6,	"HP",
   1333      0     stevel 0x08002B,	"DEC",
   1334      0     stevel 0x00000F,	"NeXT",
   1335      0     stevel 0x00000C,	"Cisco",
   1336      0     stevel 0x080069,	"Silicon Graphics",
   1337      0     stevel 0x000069,	"Silicon Graphics",
   1338      0     stevel 0x0000A7,	"Network Computing Devices (NCD	X-terminal)",
   1339      0     stevel 0x08005A,	"IBM",
   1340      0     stevel 0x0000AC,	"Apollo",
   1341  10491      Rishi 0x0180C2,	"Standard MAC Group Address",
   1342      0     stevel /* end of popular entries */
   1343      0     stevel 0x000002,	"BBN",
   1344      0     stevel 0x000010,	"Sytek",
   1345      0     stevel 0x000011,	"Tektronix",
   1346      0     stevel 0x000018,	"Webster (?)",
   1347      0     stevel 0x00001B,	"Novell",
   1348      0     stevel 0x00001D,	"Cabletron",
   1349      0     stevel 0x000020,	"DIAB (Data Industrier AB)",
   1350      0     stevel 0x000021,	"SC&C",
   1351      0     stevel 0x000022,	"Visual Technology",
   1352      0     stevel 0x000029,	"IMC",
   1353      0     stevel 0x00002A,	"TRW",
   1354      0     stevel 0x00003D,	"AT&T",
   1355      0     stevel 0x000049,	"Apricot Ltd.",
   1356      0     stevel 0x000055,	"AT&T",
   1357      0     stevel 0x00005A,	"S & Koch",
   1358      0     stevel 0x00005A,	"Xerox 806 (unregistered)",
   1359      0     stevel 0x00005E,	"U.S. Department of Defense (IANA)",
   1360      0     stevel 0x000065,	"Network General",
   1361      0     stevel 0x00006B,	"MIPS",
   1362      0     stevel 0x000077,	"MIPS",
   1363      0     stevel 0x000079,	"NetWare (?)",
   1364      0     stevel 0x00007A,	"Ardent",
   1365      0     stevel 0x00007B,	"Research Machines",
   1366      0     stevel 0x00007D,	"Harris (3M) (old)",
   1367      0     stevel 0x000080,	"Imagen(?)",
   1368      0     stevel 0x000081,	"Synoptics",
   1369      0     stevel 0x000084,	"Aquila (?)",
   1370      0     stevel 0x000086,	"Gateway (?)",
   1371      0     stevel 0x000089,	"Cayman Systems	Gatorbox",
   1372      0     stevel 0x000093,	"Proteon",
   1373      0     stevel 0x000094,	"Asante",
   1374      0     stevel 0x000098,	"Cross Com",
   1375      0     stevel 0x00009F,	"Ameristar Technology",
   1376      0     stevel 0x0000A2,	"Wellfleet",
   1377      0     stevel 0x0000A3,	"Network Application Technology",
   1378      0     stevel 0x0000A4,	"Acorn",
   1379      0     stevel 0x0000A6,	"Network General",
   1380      0     stevel 0x0000A7,	"Network Computing Devices (NCD	X-terminal)",
   1381      0     stevel 0x0000A9,	"Network Systems",
   1382      0     stevel 0x0000AA,	"Xerox",
   1383      0     stevel 0x0000B3,	"CIMLinc",
   1384      0     stevel 0x0000B5,	"Datability Terminal Server",
   1385      0     stevel 0x0000B7,	"Dove Fastnet",
   1386      0     stevel 0x0000BC,	"Allen-Bradley",
   1387      0     stevel 0x0000C0,	"Western Digital",
   1388      0     stevel 0x0000C8,	"Altos",
   1389      0     stevel 0x0000C9,	"Emulex Terminal Server",
   1390      0     stevel 0x0000D0,	"Develcon Electronics, Ltd.",
   1391      0     stevel 0x0000D1,	"Adaptec Inc. Nodem product",
   1392      0     stevel 0x0000D7,	"Dartmouth College (NED Router)",
   1393      0     stevel 0x0000DD,	"Gould",
   1394      0     stevel 0x0000DE,	"Unigraph",
   1395      0     stevel 0x0000E2,	"Acer Counterpoint",
   1396      0     stevel 0x0000E8,	"Accton Technology Corporation",
   1397      0     stevel 0x0000EE,	"Network Designers Limited(?)",
   1398      0     stevel 0x0000EF,	"Alantec",
   1399      0     stevel 0x0000F3,	"Gandalf",
   1400      0     stevel 0x0000FD,	"High Level Hardware (Orion, UK)",
   1401      0     stevel 0x000143,	"IEEE 802",
   1402      0     stevel 0x001700,	"Kabel",
   1403      0     stevel 0x004010,	"Sonic",
   1404      0     stevel 0x00608C,	"3Com",
   1405      0     stevel 0x00800F,	"SMC",
   1406      0     stevel 0x008019,	"Dayna Communications Etherprint product",
   1407      0     stevel 0x00802D,	"Xylogics, Inc.	Annex terminal servers",
   1408      0     stevel 0x008035,	"Technology Works",
   1409      0     stevel 0x008087,	"Okidata",
   1410      0     stevel 0x00808C,	"Frontier Software Development",
   1411      0     stevel 0x0080C7,	"Xircom Inc.",
   1412      0     stevel 0x0080D0,	"Computer Products International",
   1413      0     stevel 0x0080D3,	"Shiva Appletalk-Ethernet interface",
   1414      0     stevel 0x0080D4,	"Chase Limited",
   1415      0     stevel 0x0080F1,	"Opus",
   1416      0     stevel 0x00AA00,	"Intel",
   1417      0     stevel 0x00B0D0,	"Computer Products International",
   1418      0     stevel 0x00DD00,	"Ungermann-Bass",
   1419      0     stevel 0x00DD01,	"Ungermann-Bass",
   1420      0     stevel 0x00EFE5,	"IBM (3Com card)",
   1421      0     stevel 0x020406,	"BBN",
   1422      0     stevel 0x026060,	"3Com",
   1423      0     stevel 0x026086,	"Satelcom MegaPac (UK)",
   1424      0     stevel 0x02E6D3,	"Bus-Tech, Inc. (BTI)",
   1425      0     stevel 0x080001,	"Computer Vision",
   1426      0     stevel 0x080002,	"3Com (Formerly Bridge)",
   1427      0     stevel 0x080003,	"ACC (Advanced Computer Communications)",
   1428      0     stevel 0x080005,	"Symbolics",
   1429      0     stevel 0x080007,	"Apple",
   1430      0     stevel 0x080008,	"BBN",
   1431      0     stevel 0x080009,	"Hewlett-Packard",
   1432      0     stevel 0x08000A,	"Nestar Systems",
   1433      0     stevel 0x08000B,	"Unisys",
   1434      0     stevel 0x08000D,	"ICL",
   1435      0     stevel 0x08000E,	"NCR",
   1436      0     stevel 0x080010,	"AT&T",
   1437      0     stevel 0x080011,	"Tektronix, Inc.",
   1438      0     stevel 0x080017,	"NSC",
   1439      0     stevel 0x08001A,	"Data General",
   1440      0     stevel 0x08001B,	"Data General",
   1441      0     stevel 0x08001E,	"Apollo",
   1442      0     stevel 0x080022,	"NBI",
   1443      0     stevel 0x080025,	"CDC",
   1444      0     stevel 0x080026,	"Norsk Data (Nord)",
   1445      0     stevel 0x080027,	"PCS Computer Systems GmbH",
   1446      0     stevel 0x080028,	"TI Explorer",
   1447      0     stevel 0x08002E,	"Metaphor",
   1448      0     stevel 0x08002F,	"Prime Computer",
   1449      0     stevel 0x080036,	"Intergraph CAE stations",
   1450      0     stevel 0x080037,	"Fujitsu-Xerox",
   1451      0     stevel 0x080038,	"Bull",
   1452      0     stevel 0x080039,	"Spider Systems",
   1453      0     stevel 0x08003B,	"Torus Systems",
   1454      0     stevel 0x08003E,	"Motorola VME bus processor module",
   1455      0     stevel 0x080041,	"DCA Digital Comm. Assoc.",
   1456      0     stevel 0x080046,	"Sony",
   1457      0     stevel 0x080047,	"Sequent",
   1458      0     stevel 0x080049,	"Univation",
   1459      0     stevel 0x08004C,	"Encore",
   1460      0     stevel 0x08004E,	"BICC",
   1461      0     stevel 0x080056,	"Stanford University",
   1462      0     stevel 0x080057,	"Evans & Sutherland (?)",
   1463      0     stevel 0x080067,	"Comdesign",
   1464      0     stevel 0x080068,	"Ridge",
   1465      0     stevel 0x08006A,	"ATTst (?)",
   1466      0     stevel 0x08006E,	"Excelan",
   1467      0     stevel 0x080075,	"DDE (Danish Data Elektronik A/S)",
   1468      0     stevel 0x080077,	"TSL (now Retix)",
   1469      0     stevel 0x08007C,	"Vitalink TransLAN III",
   1470      0     stevel 0x080080,	"XIOS",
   1471      0     stevel 0x080081,	"Crosfield Electronics",
   1472      0     stevel 0x080086,	"Imagen/QMS",
   1473      0     stevel 0x080087,	"Xyplex	terminal server",
   1474      0     stevel 0x080089,	"Kinetics AppleTalk-Ethernet interface",
   1475      0     stevel 0x08008B,	"Pyramid",
   1476      0     stevel 0x08008D,	"XyVision",
   1477      0     stevel 0x080090,	"Retix Inc Bridge",
   1478      0     stevel 0x10005A,	"IBM",
   1479      0     stevel 0x1000D4,	"DEC",
   1480      0     stevel 0x400003,	"NetWare",
   1481      0     stevel 0x800010,	"AT&T",
   1482      0     stevel 0xAA0004,	"DEC (DECNET)",
   1483      0     stevel 0xC00000,	"SMC",
   1484      0     stevel 0,		"",
   1485      0     stevel };
   1486      0     stevel 
   1487      0     stevel /*
   1488      0     stevel  * The oui argument should be in host byte-order to conform with
   1489      0     stevel  * the above array's values.
   1490      0     stevel  */
   1491      0     stevel char *
   1492      0     stevel ether_ouiname(uint32_t oui)
   1493      0     stevel {
   1494      0     stevel 	uint_t i;
   1495      0     stevel 
   1496      0     stevel 	for (i = 0; ether_block[i].e_block != 0; i++)
   1497      0     stevel 		if (oui == ether_block[i].e_block)
   1498      0     stevel 			return (ether_block[i].e_name);
   1499      0     stevel 
   1500      0     stevel 	return (NULL);
   1501      0     stevel }
   1502      0     stevel 
   1503      0     stevel /*
   1504      0     stevel  * Print the additional Ethernet address info
   1505      0     stevel  */
   1506      0     stevel static char *
   1507  10616  Sebastien print_etherinfo(struct ether_addr *eaddr)
   1508      0     stevel {
   1509      0     stevel 	uint_t addr = 0;
   1510      0     stevel 	char *p = (char *)&addr + 1;
   1511      0     stevel 	char *ename;
   1512      0     stevel 
   1513      0     stevel 	(void) memcpy(p, eaddr, 3);
   1514      0     stevel 
   1515      0     stevel 	if (memcmp(eaddr, &ether_broadcast, sizeof (struct ether_addr)) == 0)
   1516      0     stevel 		return ("(broadcast)");
   1517      0     stevel 
   1518      0     stevel 	addr = ntohl(addr);	/* make it right for little-endians */
   1519      0     stevel 	ename = ether_ouiname(addr);
   1520      0     stevel 
   1521      0     stevel 	if (ename != NULL)
   1522      0     stevel 		return (ename);
   1523      0     stevel 	else
   1524  10491      Rishi 		return ((eaddr->ether_addr_octet[0] & 1) ? "(multicast)" : "");
   1525      0     stevel }
   1526      0     stevel 
   1527      0     stevel static uchar_t	endianswap[] = {
   1528      0     stevel 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
   1529      0     stevel 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
   1530      0     stevel 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
   1531      0     stevel 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
   1532      0     stevel 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
   1533      0     stevel 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
   1534      0     stevel 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
   1535      0     stevel 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
   1536      0     stevel 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
   1537      0     stevel 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
   1538      0     stevel 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
   1539      0     stevel 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
   1540      0     stevel 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
   1541      0     stevel 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
   1542      0     stevel 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
   1543      0     stevel 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
   1544      0     stevel 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
   1545      0     stevel 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
   1546      0     stevel 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
   1547      0     stevel 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
   1548      0     stevel 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
   1549      0     stevel 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
   1550      0     stevel 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
   1551      0     stevel 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
   1552      0     stevel 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
   1553      0     stevel 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
   1554      0     stevel 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
   1555      0     stevel 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
   1556      0     stevel 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
   1557      0     stevel 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
   1558      0     stevel 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
   1559      0     stevel 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
   1560      0     stevel };
   1561      0     stevel 
   1562      0     stevel static void
   1563  10616  Sebastien addr_copy_swap(struct ether_addr *pd, struct ether_addr *ps)
   1564      0     stevel {
   1565      0     stevel 	pd->ether_addr_octet[0] = endianswap[ps->ether_addr_octet[0]];
   1566      0     stevel 	pd->ether_addr_octet[1] = endianswap[ps->ether_addr_octet[1]];
   1567      0     stevel 	pd->ether_addr_octet[2] = endianswap[ps->ether_addr_octet[2]];
   1568      0     stevel 	pd->ether_addr_octet[3] = endianswap[ps->ether_addr_octet[3]];
   1569      0     stevel 	pd->ether_addr_octet[4] = endianswap[ps->ether_addr_octet[4]];
   1570      0     stevel 	pd->ether_addr_octet[5] = endianswap[ps->ether_addr_octet[5]];
   1571      0     stevel }
   1572      0     stevel 
   1573      0     stevel /* ARGSUSED */
   1574      0     stevel uint_t
   1575  10616  Sebastien ib_header_len(char *hdr, size_t msgsize)
   1576      0     stevel {
   1577      0     stevel 	return (IPOIB_HDRSIZE);
   1578      0     stevel }
   1579      0     stevel 
   1580      0     stevel static uint_t
   1581      0     stevel interpret_ib(int flags, char *header, int elen, int origlen)
   1582      0     stevel {
   1583      0     stevel 	struct ipoib_header *hdr = (struct ipoib_header *)header;
   1584      0     stevel 	char *off;
   1585      0     stevel 	int len;
   1586      0     stevel 	unsigned short ethertype;
   1587      0     stevel 	int blen = MAX(origlen, 4096);
   1588      0     stevel 
   1589      0     stevel 	if (data != NULL && datalen != 0 && datalen < blen) {
   1590      0     stevel 		free(data);
   1591      0     stevel 		data = NULL;
   1592      0     stevel 		datalen = 0;
   1593      0     stevel 	}
   1594      0     stevel 	if (data == NULL) {
   1595      0     stevel 		data = malloc(blen);
   1596      0     stevel 		if (data == NULL)
   1597      0     stevel 			pr_err("Warning: malloc failure");
   1598      0     stevel 		datalen = blen;
   1599      0     stevel 	}
   1600      0     stevel 	if (origlen < IPOIB_HDRSIZE) {
   1601      0     stevel 		if (flags & F_SUM)
   1602      0     stevel 			(void) snprintf(get_sum_line(), MAXLINE,
   1603   8023       Phil 			    "RUNT (short packet - %d bytes)", origlen);
   1604      0     stevel 		if (flags & F_DTAIL)
   1605      0     stevel 			show_header("RUNT:  ", "Short packet", origlen);
   1606      0     stevel 		return (elen);
   1607      0     stevel 	}
   1608      0     stevel 	if (elen < IPOIB_HDRSIZE)
   1609      0     stevel 		return (elen);
   1610      0     stevel 
   1611      0     stevel 	/*
   1612      0     stevel 	 * It is not possible to understand just by looking
   1613      0     stevel 	 * at the header whether this was a broad/multi cast
   1614      0     stevel 	 * packet; thus dst_name is not updated.
   1615      0     stevel 	 */
   1616      0     stevel 	ethertype = ntohs(hdr->ipoib_type);
   1617      0     stevel 	len = elen - IPOIB_HDRSIZE;
   1618      0     stevel 	off = (char *)(hdr + 1);
   1619      0     stevel 	(void) memcpy(data, off, len);
   1620      0     stevel 
   1621      0     stevel 	if (flags & F_SUM) {
   1622      0     stevel 		(void) snprintf(get_sum_line(), MAXLINE,
   1623   8023       Phil 		    "IPIB Type=%04X (%s), size = %d bytes",
   1624   8023       Phil 		    ethertype,
   1625   8023       Phil 		    print_ethertype(ethertype),
   1626   8023       Phil 		    origlen);
   1627      0     stevel 	}
   1628      0     stevel 
   1629      0     stevel 	if (flags & F_DTAIL) {
   1630      0     stevel 		show_header("IPIB:  ", "IPIB Header", elen);
   1631      0     stevel 		show_space();
   1632      0     stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
   1633   8023       Phil 		    "Packet %d arrived at %d:%02d:%d.%02d",
   1634   8023       Phil 		    pi_frame, pi_time_hour, pi_time_min,
   1635   8023       Phil 		    pi_time_sec, pi_time_usec / 10000);
   1636      0     stevel 		(void) snprintf(get_line(0, 0), get_line_remain(),
   1637   8023       Phil 		    "Packet size = %d bytes", elen, elen);
   1638      0     stevel 		(void) snprintf(get_line(0, 2), get_line_remain(),
   1639   8023       Phil 		    "Ethertype = %04X (%s)", ethertype,
   1640   8023       Phil 		    print_ethertype(ethertype));
   1641      0     stevel 		show_space();
   1642      0     stevel 	}
   1643      0     stevel 
   1644      0     stevel 	/* Go to the next protocol layer */
   1645      0     stevel 	switch (ethertype) {
   1646      0     stevel 		case ETHERTYPE_IP:
   1647      0     stevel 			(void) interpret_ip(flags, (struct ip *)data, len);
   1648      0     stevel 			break;
   1649      0     stevel 		case ETHERTYPE_IPV6:
   1650      0     stevel 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
   1651      0     stevel 			break;
   1652      0     stevel 		case ETHERTYPE_ARP:
   1653      0     stevel 		case ETHERTYPE_REVARP:
   1654      0     stevel 			interpret_arp(flags, (struct arphdr *)data, len);
   1655      0     stevel 			break;
   1656      0     stevel 	}
   1657      0     stevel 
   1658      0     stevel 	return (elen);
   1659      0     stevel }
   1660   8023       Phil 
   1661  10616  Sebastien /* ARGSUSED */
   1662   8023       Phil uint_t
   1663  10616  Sebastien ipnet_header_len(char *hdr, size_t msgsize)
   1664   8023       Phil {
   1665   8023       Phil 	return (sizeof (dl_ipnetinfo_t));
   1666   8023       Phil }
   1667   8023       Phil 
   1668   8023       Phil #define	MAX_UINT64_STR	22
   1669   8023       Phil static uint_t
   1670   8023       Phil interpret_ipnet(int flags, char *header, int elen, int origlen)
   1671   8023       Phil {
   1672   8023       Phil 	dl_ipnetinfo_t dl;
   1673   8023       Phil 	size_t len = elen - sizeof (dl_ipnetinfo_t);
   1674   8023       Phil 	char *off = (char *)header + sizeof (dl_ipnetinfo_t);
   1675   8023       Phil 	int blen = MAX(origlen, 8252);
   1676   8023       Phil 	char szone[MAX_UINT64_STR];
   1677   8023       Phil 	char dzone[MAX_UINT64_STR];
   1678   8023       Phil 
   1679   8023       Phil 	(void) memcpy(&dl, header, sizeof (dl));
   1680   8023       Phil 	if (data != NULL && datalen != 0 && datalen < blen) {
   1681   8023       Phil 		free(data);
   1682   8023       Phil 		data = NULL;
   1683   8023       Phil 		datalen = 0;
   1684   8023       Phil 	}
   1685   8023       Phil 	if (data == NULL) {
   1686   8023       Phil 		data = (char *)malloc(blen);
   1687   8023       Phil 		if (!data)
   1688   8023       Phil 			pr_err("Warning: malloc failure");
   1689   8023       Phil 		datalen = blen;
   1690   8023       Phil 	}
   1691   8023       Phil 
   1692  10639     Darren 	if (dl.dli_zsrc == ALL_ZONES)
   1693   8023       Phil 		sprintf(szone, "Unknown");
   1694   8023       Phil 	else
   1695  10639     Darren 		sprintf(szone, "%lu", BE_32(dl.dli_zsrc));
   1696   8023       Phil 
   1697  10639     Darren 	if (dl.dli_zdst == ALL_ZONES)
   1698   8023       Phil 		sprintf(dzone, "Unknown");
   1699   8023       Phil 	else
   1700  10639     Darren 		sprintf(dzone, "%lu", BE_32(dl.dli_zdst));
   1701   8023       Phil 
   1702   8023       Phil 	if (flags & F_SUM) {
   1703   8023       Phil 		(void) snprintf(get_sum_line(), MAXLINE,
   1704   8023       Phil 		    "IPNET src zone %s dst zone %s", szone, dzone);
   1705   8023       Phil 	}
   1706   8023       Phil 
   1707   8023       Phil 	if (flags & F_DTAIL) {
   1708   8023       Phil 		show_header("IPNET:  ", "IPNET Header", elen);
   1709   8023       Phil 		show_space();
   1710   8023       Phil 		(void) sprintf(get_line(0, 0),
   1711   8023       Phil 		    "Packet %d arrived at %d:%02d:%d.%05d",
   1712   8023       Phil 		    pi_frame,
   1713   8023       Phil 		    pi_time_hour, pi_time_min, pi_time_sec,
   1714   8023       Phil 		    pi_time_usec / 10);
   1715   8023       Phil 		(void) sprintf(get_line(0, 0),
   1716   8023       Phil 		    "Packet size = %d bytes",
   1717   8023       Phil 		    elen);
   1718   8023       Phil 		(void) snprintf(get_line(0, 0), get_line_remain(),
   1719   8023       Phil 		    "dli_version = %d", dl.dli_version);
   1720   8023       Phil 		(void) snprintf(get_line(0, 0), get_line_remain(),
   1721  10639     Darren 		    "dli_family = %d", dl.dli_family);
   1722   8023       Phil 		(void) snprintf(get_line(0, 2), get_line_remain(),
   1723  10639     Darren 		    "dli_zsrc = %s", szone);
   1724   8023       Phil 		(void) snprintf(get_line(0, 2), get_line_remain(),
   1725  10639     Darren 		    "dli_zdst = %s", dzone);
   1726   8023       Phil 		show_space();
   1727   8023       Phil 	}
   1728   8023       Phil 	memcpy(data, off, len);
   1729   8023       Phil 
   1730  10639     Darren 	switch (dl.dli_family) {
   1731  10639     Darren 	case AF_INET:
   1732   8023       Phil 		(void) interpret_ip(flags, (struct ip *)data, len);
   1733   8023       Phil 		break;
   1734  10639     Darren 	case AF_INET6:
   1735   8023       Phil 		(void) interpret_ipv6(flags, (ip6_t *)data, len);
   1736   8023       Phil 		break;
   1737   8023       Phil 	default:
   1738   8023       Phil 		break;
   1739   8023       Phil 	}
   1740   8023       Phil 
   1741   8023       Phil 	return (0);
   1742   8023       Phil }
   1743  10616  Sebastien 
   1744  10616  Sebastien uint_t
   1745  10616  Sebastien ipv4_header_len(char *hdr, size_t msgsize)
   1746  10616  Sebastien {
   1747  10616  Sebastien 	return (msgsize < sizeof (ipha_t) ? 0 : IPH_HDR_LENGTH((ipha_t *)hdr));
   1748  10616  Sebastien }
   1749  10616  Sebastien 
   1750  10616  Sebastien /*
   1751  10616  Sebastien  * The header length needs to include all potential extension headers, as the
   1752  10616  Sebastien  * caller expects to use this length as an offset to the inner network layer
   1753  10616  Sebastien  * header to be used as a filter offset.  IPsec headers aren't passed up here,
   1754  10616  Sebastien  * and neither are fragmentation headers.
   1755  10616  Sebastien  */
   1756  10616  Sebastien uint_t
   1757  10616  Sebastien ipv6_header_len(char *hdr, size_t msgsize)
   1758  10616  Sebastien {
   1759  10616  Sebastien 	ip6_t		*ip6hdr = (ip6_t *)hdr;
   1760  10616  Sebastien 	ip6_hbh_t	*exthdr;
   1761  10616  Sebastien 	uint_t		hdrlen = sizeof (ip6_t), exthdrlen;
   1762  10616  Sebastien 	char		*pptr;
   1763  10616  Sebastien 	uint8_t		nxt;
   1764  10616  Sebastien 
   1765  10616  Sebastien 	if (msgsize < sizeof (ip6_t))
   1766  10616  Sebastien 		return (0);
   1767  10616  Sebastien 
   1768  10616  Sebastien 	nxt = ip6hdr->ip6_nxt;
   1769  10616  Sebastien 	pptr = (char *)(ip6hdr + 1);
   1770  10616  Sebastien 
   1771  10616  Sebastien 	while (nxt != IPPROTO_ENCAP && nxt != IPPROTO_IPV6) {
   1772  10616  Sebastien 		switch (nxt) {
   1773  10616  Sebastien 		case IPPROTO_HOPOPTS:
   1774  10616  Sebastien 		case IPPROTO_DSTOPTS:
   1775  10616  Sebastien 		case IPPROTO_ROUTING:
   1776  10616  Sebastien 			if (msgsize < hdrlen + sizeof (ip6_hbh_t))
   1777  10616  Sebastien 				return (0);
   1778  10616  Sebastien 			exthdr = (ip6_hbh_t *)pptr;
   1779  10616  Sebastien 			exthdrlen = 8 + exthdr->ip6h_len * 8;
   1780  10616  Sebastien 			hdrlen += exthdrlen;
   1781  10616  Sebastien 			pptr += exthdrlen;
   1782  10616  Sebastien 			nxt = exthdr->ip6h_nxt;
   1783  10616  Sebastien 			break;
   1784  10616  Sebastien 		default:
   1785  10616  Sebastien 			/*
   1786  10616  Sebastien 			 * This is garbage, there's no way to know where the
   1787  10616  Sebastien 			 * inner IP header is.
   1788  10616  Sebastien 			 */
   1789  10616  Sebastien 			return (0);
   1790  10616  Sebastien 		}
   1791  10616  Sebastien 	}
   1792  10616  Sebastien 
   1793  10616  Sebastien 	return (hdrlen);
   1794  10616  Sebastien }
   1795  10616  Sebastien 
   1796  10616  Sebastien /* ARGSUSED */
   1797  10616  Sebastien uint_t
   1798  10616  Sebastien interpret_iptun(int flags, char *header, int elen, int origlen)
   1799  10616  Sebastien {
   1800  10616  Sebastien 	(void) interpret_ip(flags, (struct ip *)header, elen);
   1801  10616  Sebastien 	return (elen);
   1802  10616  Sebastien }
   1803