xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ether.c (revision 10491:8893b747ecdf)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52760Sdg199075  * Common Development and Distribution License (the "License").
62760Sdg199075  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*10491SRishi.Srivatsavai@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <stdio.h>
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <string.h>
292760Sdg199075 #include <stddef.h>
300Sstevel@tonic-gate #include <fcntl.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/time.h>
340Sstevel@tonic-gate #include <sys/sysmacros.h>
350Sstevel@tonic-gate #include <sys/socket.h>
360Sstevel@tonic-gate #include <net/if.h>
370Sstevel@tonic-gate #include <netinet/in_systm.h>
380Sstevel@tonic-gate #include <netinet/in.h>
390Sstevel@tonic-gate #include <netinet/ip.h>
400Sstevel@tonic-gate #include <netinet/if_ether.h>
410Sstevel@tonic-gate #include <sys/ib/clients/ibd/ibd.h>
422760Sdg199075 #include <sys/ethernet.h>
432760Sdg199075 #include <sys/vlan.h>
448023SPhil.Kirk@Sun.COM #include <sys/zone.h>
458023SPhil.Kirk@Sun.COM #include <sys/byteorder.h>
468023SPhil.Kirk@Sun.COM #include <limits.h>
478023SPhil.Kirk@Sun.COM #include <inet/ip.h>
488023SPhil.Kirk@Sun.COM #include <inet/ip6.h>
49*10491SRishi.Srivatsavai@Sun.COM #include <net/trill.h>
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #include "at.h"
520Sstevel@tonic-gate #include "snoop.h"
530Sstevel@tonic-gate 
548023SPhil.Kirk@Sun.COM static uint_t ether_header_len(char *), fddi_header_len(char *),
558023SPhil.Kirk@Sun.COM 	tr_header_len(char *), ib_header_len(char *), ipnet_header_len(char *);
560Sstevel@tonic-gate static uint_t interpret_ether(), interpret_fddi(), interpret_tr();
578023SPhil.Kirk@Sun.COM static uint_t interpret_ib(int, char *, int, int),
588023SPhil.Kirk@Sun.COM 	interpret_ipnet(int, char *, int, int);
590Sstevel@tonic-gate static void addr_copy_swap(struct ether_addr *, struct ether_addr *);
600Sstevel@tonic-gate 
610Sstevel@tonic-gate interface_t *interface;
620Sstevel@tonic-gate interface_t INTERFACES[] = {
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	/* IEEE 802.3 CSMA/CD network */
658023SPhil.Kirk@Sun.COM 	{ DL_CSMACD, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
668023SPhil.Kirk@Sun.COM 	    ether_header_len, interpret_ether, B_TRUE },
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	/* Ethernet Bus */
698023SPhil.Kirk@Sun.COM 	{ DL_ETHER, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
708023SPhil.Kirk@Sun.COM 	    ether_header_len, interpret_ether, B_TRUE },
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	/* Fiber Distributed data interface */
738023SPhil.Kirk@Sun.COM 	{ DL_FDDI, 4500, 19, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
748023SPhil.Kirk@Sun.COM 	    fddi_header_len, interpret_fddi, B_FALSE },
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	/* Token Ring interface */
778023SPhil.Kirk@Sun.COM 	{ DL_TPR, 17800, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
788023SPhil.Kirk@Sun.COM 	    tr_header_len, interpret_tr, B_FALSE },
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 	/* Infiniband */
818023SPhil.Kirk@Sun.COM 	{ DL_IB, 4096, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6,
828023SPhil.Kirk@Sun.COM 	    ib_header_len, interpret_ib, B_TRUE },
830Sstevel@tonic-gate 
848023SPhil.Kirk@Sun.COM 	/* ipnet */
858105SSebastien.Roy@Sun.COM 	{ DL_IPNET, INT_MAX, 1, 1, IPV4_VERSION, IPV6_VERSION,
868023SPhil.Kirk@Sun.COM 	    ipnet_header_len, interpret_ipnet, B_TRUE },
870Sstevel@tonic-gate 
888023SPhil.Kirk@Sun.COM 	{ (uint_t)-1, 0, 0, 0, 0, NULL, NULL, B_FALSE }
890Sstevel@tonic-gate };
900Sstevel@tonic-gate 
910Sstevel@tonic-gate /* externals */
920Sstevel@tonic-gate extern char *dlc_header;
930Sstevel@tonic-gate extern int pi_frame;
940Sstevel@tonic-gate extern int pi_time_hour;
950Sstevel@tonic-gate extern int pi_time_min;
960Sstevel@tonic-gate extern int pi_time_sec;
970Sstevel@tonic-gate extern int pi_time_usec;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate char *printether();
1000Sstevel@tonic-gate char *print_ethertype();
1010Sstevel@tonic-gate static char *print_etherinfo();
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate char *print_fc();
1040Sstevel@tonic-gate char *print_smttype();
1050Sstevel@tonic-gate char *print_smtclass();
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate struct ether_addr ether_broadcast = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1080Sstevel@tonic-gate static char *data;			/* current data buffer */
1090Sstevel@tonic-gate static int datalen;			/* current data buffer length */
110*10491SRishi.Srivatsavai@Sun.COM static const struct ether_addr all_isis_rbridges = ALL_ISIS_RBRIDGES;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate uint_t
1130Sstevel@tonic-gate interpret_ether(flags, e, elen, origlen)
1140Sstevel@tonic-gate 	int flags;
1150Sstevel@tonic-gate 	struct ether_header *e;
1160Sstevel@tonic-gate 	int elen, origlen;
1170Sstevel@tonic-gate {
118*10491SRishi.Srivatsavai@Sun.COM 	uchar_t *off, *ieeestart;
1190Sstevel@tonic-gate 	int len;
1200Sstevel@tonic-gate 	int ieee8023 = 0;
1210Sstevel@tonic-gate 	extern char *dst_name;
1220Sstevel@tonic-gate 	int ethertype;
1232760Sdg199075 	struct ether_vlan_extinfo *evx = NULL;
1240Sstevel@tonic-gate 	int blen = MAX(origlen, ETHERMTU);
125*10491SRishi.Srivatsavai@Sun.COM 	boolean_t trillpkt = B_FALSE;
126*10491SRishi.Srivatsavai@Sun.COM 	uint16_t tci = 0;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 	if (data != NULL && datalen != 0 && datalen < blen) {
1290Sstevel@tonic-gate 		free(data);
1300Sstevel@tonic-gate 		data = NULL;
1310Sstevel@tonic-gate 		datalen = 0;
1320Sstevel@tonic-gate 	}
1330Sstevel@tonic-gate 	if (!data) {
1340Sstevel@tonic-gate 		data = (char *)malloc(blen);
1350Sstevel@tonic-gate 		if (!data)
1360Sstevel@tonic-gate 			pr_err("Warning: malloc failure");
1370Sstevel@tonic-gate 		datalen = blen;
1380Sstevel@tonic-gate 	}
139*10491SRishi.Srivatsavai@Sun.COM inner_pkt:
1400Sstevel@tonic-gate 	if (origlen < 14) {
1410Sstevel@tonic-gate 		if (flags & F_SUM)
1420Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
1430Sstevel@tonic-gate 			"RUNT (short packet - %d bytes)",
1440Sstevel@tonic-gate 			origlen);
1450Sstevel@tonic-gate 		if (flags & F_DTAIL)
1460Sstevel@tonic-gate 			show_header("RUNT:  ", "Short packet", origlen);
1470Sstevel@tonic-gate 		return (elen);
1480Sstevel@tonic-gate 	}
1490Sstevel@tonic-gate 	if (elen < 14)
1500Sstevel@tonic-gate 		return (elen);
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	if (memcmp(&e->ether_dhost, &ether_broadcast,
1530Sstevel@tonic-gate 	    sizeof (struct ether_addr)) == 0)
1540Sstevel@tonic-gate 		dst_name = "(broadcast)";
1550Sstevel@tonic-gate 	else if (e->ether_dhost.ether_addr_octet[0] & 1)
1560Sstevel@tonic-gate 		dst_name = "(multicast)";
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	ethertype = ntohs(e->ether_type);
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	/*
1610Sstevel@tonic-gate 	 * The 14 byte ether header screws up alignment
1620Sstevel@tonic-gate 	 * of the rest of the packet for 32 bit aligned
1630Sstevel@tonic-gate 	 * architectures like SPARC. Alas, we have to copy
1640Sstevel@tonic-gate 	 * the rest of the packet in order to align it.
1650Sstevel@tonic-gate 	 */
1660Sstevel@tonic-gate 	len = elen - sizeof (struct ether_header);
167*10491SRishi.Srivatsavai@Sun.COM 	off = (uchar_t *)(e + 1);
1680Sstevel@tonic-gate 
1692760Sdg199075 	if (ethertype == ETHERTYPE_VLAN) {
1702760Sdg199075 		if (origlen < sizeof (struct ether_vlan_header)) {
1712760Sdg199075 			if (flags & F_SUM) {
1722760Sdg199075 				(void) sprintf(get_sum_line(),
1732760Sdg199075 				    "RUNT (short VLAN packet - %d bytes)",
1742760Sdg199075 				    origlen);
1752760Sdg199075 			}
1762760Sdg199075 			if (flags & F_DTAIL) {
1772760Sdg199075 				show_header("RUNT:  ", "Short VLAN packet",
1782760Sdg199075 				    origlen);
1792760Sdg199075 			}
1802760Sdg199075 			return (elen);
1812760Sdg199075 		}
1822760Sdg199075 		if (len < sizeof (struct ether_vlan_extinfo))
1832760Sdg199075 			return (elen);
1842760Sdg199075 
1852760Sdg199075 		evx = (struct ether_vlan_extinfo *)off;
1862760Sdg199075 		off += sizeof (struct ether_vlan_extinfo);
1872760Sdg199075 		len -= sizeof (struct ether_vlan_extinfo);
1882760Sdg199075 
1892760Sdg199075 		ethertype = ntohs(evx->ether_type);
190*10491SRishi.Srivatsavai@Sun.COM 		tci = ntohs(evx->ether_tci);
1912760Sdg199075 	}
1922760Sdg199075 
193*10491SRishi.Srivatsavai@Sun.COM 	if (ethertype <= 1514) {
194*10491SRishi.Srivatsavai@Sun.COM 		/*
195*10491SRishi.Srivatsavai@Sun.COM 		 * Fake out the IEEE 802.3 packets.
196*10491SRishi.Srivatsavai@Sun.COM 		 * Should be DSAP=0xAA, SSAP=0xAA, control=0x03
197*10491SRishi.Srivatsavai@Sun.COM 		 * then three padding bytes of zero (OUI),
198*10491SRishi.Srivatsavai@Sun.COM 		 * followed by a normal ethernet-type packet.
199*10491SRishi.Srivatsavai@Sun.COM 		 */
200*10491SRishi.Srivatsavai@Sun.COM 		ieee8023 = ethertype;
201*10491SRishi.Srivatsavai@Sun.COM 		ieeestart = off;
202*10491SRishi.Srivatsavai@Sun.COM 		if (off[0] == 0xAA && off[1] == 0xAA) {
203*10491SRishi.Srivatsavai@Sun.COM 			ethertype = ntohs(*(ushort_t *)(off + 6));
204*10491SRishi.Srivatsavai@Sun.COM 			off += 8;
205*10491SRishi.Srivatsavai@Sun.COM 			len -= 8;
206*10491SRishi.Srivatsavai@Sun.COM 		} else {
207*10491SRishi.Srivatsavai@Sun.COM 			ethertype = 0;
208*10491SRishi.Srivatsavai@Sun.COM 			off += 3;
209*10491SRishi.Srivatsavai@Sun.COM 			len -= 3;
210*10491SRishi.Srivatsavai@Sun.COM 		}
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	if (flags & F_SUM) {
2142760Sdg199075 		/*
2152760Sdg199075 		 * Set the flag that says don't display VLAN information.
2162760Sdg199075 		 * If it needs to change, that will be done later if the
2172760Sdg199075 		 * packet is VLAN tagged and if snoop is in its default
2182760Sdg199075 		 * summary mode.
2192760Sdg199075 		 */
2202760Sdg199075 		set_vlan_id(0);
2212760Sdg199075 		if (evx == NULL) {
222*10491SRishi.Srivatsavai@Sun.COM 			if (ethertype == 0 && ieee8023 > 0) {
223*10491SRishi.Srivatsavai@Sun.COM 				(void) sprintf(get_sum_line(),
224*10491SRishi.Srivatsavai@Sun.COM 				    "ETHER 802.3 SSAP %02X DSAP %02X, "
225*10491SRishi.Srivatsavai@Sun.COM 				    "size=%d bytes", ieeestart[0], ieeestart[1],
226*10491SRishi.Srivatsavai@Sun.COM 				    origlen);
227*10491SRishi.Srivatsavai@Sun.COM 			} else {
228*10491SRishi.Srivatsavai@Sun.COM 				(void) sprintf(get_sum_line(),
229*10491SRishi.Srivatsavai@Sun.COM 				    "ETHER Type=%04X (%s), size=%d bytes",
230*10491SRishi.Srivatsavai@Sun.COM 				    ethertype, print_ethertype(ethertype),
231*10491SRishi.Srivatsavai@Sun.COM 				    origlen);
232*10491SRishi.Srivatsavai@Sun.COM 			}
2332760Sdg199075 		} else {
234*10491SRishi.Srivatsavai@Sun.COM 			if (ethertype == 0 && ieee8023 > 0) {
235*10491SRishi.Srivatsavai@Sun.COM 				(void) sprintf(get_sum_line(),
236*10491SRishi.Srivatsavai@Sun.COM 				    "ETHER 802.3 SSAP %02X DSAP %02X, "
237*10491SRishi.Srivatsavai@Sun.COM 				    "VLAN ID=%hu, size=%d bytes", ieeestart[0],
238*10491SRishi.Srivatsavai@Sun.COM 				    ieeestart[1], VLAN_ID(tci), origlen);
239*10491SRishi.Srivatsavai@Sun.COM 			} else {
240*10491SRishi.Srivatsavai@Sun.COM 				(void) sprintf(get_sum_line(),
241*10491SRishi.Srivatsavai@Sun.COM 				    "ETHER Type=%04X (%s), VLAN ID=%hu, "
242*10491SRishi.Srivatsavai@Sun.COM 				    "size=%d bytes", ethertype,
243*10491SRishi.Srivatsavai@Sun.COM 				    print_ethertype(ethertype), VLAN_ID(tci),
244*10491SRishi.Srivatsavai@Sun.COM 				    origlen);
245*10491SRishi.Srivatsavai@Sun.COM 			}
2462760Sdg199075 
2472760Sdg199075 			if (!(flags & F_ALLSUM))
248*10491SRishi.Srivatsavai@Sun.COM 				set_vlan_id(VLAN_ID(tci));
2492760Sdg199075 		}
2500Sstevel@tonic-gate 	}
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	if (flags & F_DTAIL) {
253*10491SRishi.Srivatsavai@Sun.COM 		show_header("ETHER:  ", "Ether Header", elen);
254*10491SRishi.Srivatsavai@Sun.COM 		show_space();
255*10491SRishi.Srivatsavai@Sun.COM 		if (!trillpkt) {
256*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(0, 0),
257*10491SRishi.Srivatsavai@Sun.COM 			    "Packet %d arrived at %d:%02d:%d.%05d",
258*10491SRishi.Srivatsavai@Sun.COM 			    pi_frame,
259*10491SRishi.Srivatsavai@Sun.COM 			    pi_time_hour, pi_time_min, pi_time_sec,
260*10491SRishi.Srivatsavai@Sun.COM 			    pi_time_usec / 10);
261*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(0, 0),
262*10491SRishi.Srivatsavai@Sun.COM 			    "Packet size = %d bytes",
263*10491SRishi.Srivatsavai@Sun.COM 			    elen, elen);
264*10491SRishi.Srivatsavai@Sun.COM 		}
265*10491SRishi.Srivatsavai@Sun.COM 		(void) sprintf(get_line(0, 6),
266*10491SRishi.Srivatsavai@Sun.COM 		    "Destination = %s, %s",
267*10491SRishi.Srivatsavai@Sun.COM 		    printether(&e->ether_dhost),
268*10491SRishi.Srivatsavai@Sun.COM 		    print_etherinfo(&e->ether_dhost));
269*10491SRishi.Srivatsavai@Sun.COM 		(void) sprintf(get_line(6, 6),
270*10491SRishi.Srivatsavai@Sun.COM 		    "Source      = %s, %s",
271*10491SRishi.Srivatsavai@Sun.COM 		    printether(&e->ether_shost),
272*10491SRishi.Srivatsavai@Sun.COM 		    print_etherinfo(&e->ether_shost));
273*10491SRishi.Srivatsavai@Sun.COM 		if (evx != NULL) {
274*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(0, 0),
275*10491SRishi.Srivatsavai@Sun.COM 			    "VLAN ID     = %hu", VLAN_ID(tci));
276*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(0, 0),
277*10491SRishi.Srivatsavai@Sun.COM 			    "VLAN Priority = %hu", VLAN_PRI(tci));
278*10491SRishi.Srivatsavai@Sun.COM 		}
279*10491SRishi.Srivatsavai@Sun.COM 		if (ieee8023 > 0) {
280*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(12, 2),
281*10491SRishi.Srivatsavai@Sun.COM 			    "IEEE 802.3 length = %d bytes", ieee8023);
282*10491SRishi.Srivatsavai@Sun.COM 			/* Print LLC only for non-TCP/IP packets */
283*10491SRishi.Srivatsavai@Sun.COM 			if (ethertype == 0) {
284*10491SRishi.Srivatsavai@Sun.COM 				(void) snprintf(get_line(0, 0),
285*10491SRishi.Srivatsavai@Sun.COM 				    get_line_remain(),
286*10491SRishi.Srivatsavai@Sun.COM 				    "SSAP = %02X, DSAP = %02X, CTRL = %02X",
287*10491SRishi.Srivatsavai@Sun.COM 				    ieeestart[0], ieeestart[1], ieeestart[2]);
288*10491SRishi.Srivatsavai@Sun.COM 			}
289*10491SRishi.Srivatsavai@Sun.COM 		}
290*10491SRishi.Srivatsavai@Sun.COM 		if (ethertype != 0 || ieee8023 == 0)
291*10491SRishi.Srivatsavai@Sun.COM 			(void) sprintf(get_line(12, 2),
292*10491SRishi.Srivatsavai@Sun.COM 			    "Ethertype = %04X (%s)",
293*10491SRishi.Srivatsavai@Sun.COM 			    ethertype, print_ethertype(ethertype));
294*10491SRishi.Srivatsavai@Sun.COM 		show_space();
2950Sstevel@tonic-gate 	}
2960Sstevel@tonic-gate 
297*10491SRishi.Srivatsavai@Sun.COM 	/*
298*10491SRishi.Srivatsavai@Sun.COM 	 * We cannot trust the length field in the header to be correct.
299*10491SRishi.Srivatsavai@Sun.COM 	 * But we should continue to process the packet.  Then user can
300*10491SRishi.Srivatsavai@Sun.COM 	 * notice something funny in the header.
301*10491SRishi.Srivatsavai@Sun.COM 	 * Go to the next protocol layer only if data have been
302*10491SRishi.Srivatsavai@Sun.COM 	 * copied.
303*10491SRishi.Srivatsavai@Sun.COM 	 */
304*10491SRishi.Srivatsavai@Sun.COM 	if (len > 0 && (off + len <= (uchar_t *)e + elen)) {
305*10491SRishi.Srivatsavai@Sun.COM 		(void) memmove(data, off, len);
306*10491SRishi.Srivatsavai@Sun.COM 
307*10491SRishi.Srivatsavai@Sun.COM 		if (!trillpkt && ethertype == ETHERTYPE_TRILL) {
308*10491SRishi.Srivatsavai@Sun.COM 			ethertype = interpret_trill(flags, &e, data, &len);
309*10491SRishi.Srivatsavai@Sun.COM 			/* Decode inner Ethernet frame */
310*10491SRishi.Srivatsavai@Sun.COM 			if (ethertype != 0) {
311*10491SRishi.Srivatsavai@Sun.COM 				evx = NULL;
312*10491SRishi.Srivatsavai@Sun.COM 				trillpkt = B_TRUE;
313*10491SRishi.Srivatsavai@Sun.COM 				(void) memmove(data, e, len);
314*10491SRishi.Srivatsavai@Sun.COM 				e = (struct ether_header *)data;
315*10491SRishi.Srivatsavai@Sun.COM 				origlen = len;
316*10491SRishi.Srivatsavai@Sun.COM 				elen = len;
317*10491SRishi.Srivatsavai@Sun.COM 				goto inner_pkt;
318*10491SRishi.Srivatsavai@Sun.COM 			}
319*10491SRishi.Srivatsavai@Sun.COM 		}
320*10491SRishi.Srivatsavai@Sun.COM 
3210Sstevel@tonic-gate 		switch (ethertype) {
3220Sstevel@tonic-gate 		case ETHERTYPE_IP:
3230Sstevel@tonic-gate 			(void) interpret_ip(flags, (struct ip *)data, len);
3240Sstevel@tonic-gate 			break;
3250Sstevel@tonic-gate 		/* Just in case it is decided to add this type */
3260Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
3270Sstevel@tonic-gate 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
3280Sstevel@tonic-gate 			break;
3290Sstevel@tonic-gate 		case ETHERTYPE_ARP:
3300Sstevel@tonic-gate 		case ETHERTYPE_REVARP:
3310Sstevel@tonic-gate 			interpret_arp(flags, (struct arphdr *)data, len);
3320Sstevel@tonic-gate 			break;
3330Sstevel@tonic-gate 		case ETHERTYPE_PPPOED:
3340Sstevel@tonic-gate 		case ETHERTYPE_PPPOES:
3350Sstevel@tonic-gate 			(void) interpret_pppoe(flags, (poep_t *)data, len);
3360Sstevel@tonic-gate 			break;
3370Sstevel@tonic-gate 		case ETHERTYPE_AARP:    /* AppleTalk */
3380Sstevel@tonic-gate 			interpret_aarp(flags, data, len);
3390Sstevel@tonic-gate 			break;
3400Sstevel@tonic-gate 		case ETHERTYPE_AT:
3410Sstevel@tonic-gate 			interpret_at(flags, (struct ddp_hdr *)data, len);
3420Sstevel@tonic-gate 			break;
343*10491SRishi.Srivatsavai@Sun.COM 		case 0:
344*10491SRishi.Srivatsavai@Sun.COM 			if (ieee8023 == 0)
345*10491SRishi.Srivatsavai@Sun.COM 				break;
346*10491SRishi.Srivatsavai@Sun.COM 			switch (ieeestart[0]) {
347*10491SRishi.Srivatsavai@Sun.COM 			case 0xFE:
348*10491SRishi.Srivatsavai@Sun.COM 				interpret_isis(flags, data, len,
349*10491SRishi.Srivatsavai@Sun.COM 				    memcmp(&e->ether_dhost, &all_isis_rbridges,
350*10491SRishi.Srivatsavai@Sun.COM 				    sizeof (struct ether_addr)) == 0);
351*10491SRishi.Srivatsavai@Sun.COM 				break;
352*10491SRishi.Srivatsavai@Sun.COM 			case 0x42:
353*10491SRishi.Srivatsavai@Sun.COM 				interpret_bpdu(flags, data, len);
354*10491SRishi.Srivatsavai@Sun.COM 				break;
355*10491SRishi.Srivatsavai@Sun.COM 			}
3560Sstevel@tonic-gate 			break;
3570Sstevel@tonic-gate 		}
3580Sstevel@tonic-gate 	}
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 	return (elen);
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate 
3632760Sdg199075 /*
3642760Sdg199075  * Return the length of the ethernet header.  In the case
3652760Sdg199075  * where we have a VLAN tagged packet, return the length of
3662760Sdg199075  * the ethernet header plus the length of the VLAN tag.
3672760Sdg199075  *
3682760Sdg199075  * INPUTS:  e  -  A buffer pointer.  Passing a NULL pointer
3692760Sdg199075  *                is not allowed, e must be non-NULL.
3702760Sdg199075  * OUTPUTS:  Return the size of an untagged ethernet header
3712760Sdg199075  *           if the packet is not VLAN tagged, and the size
3722760Sdg199075  *           of an untagged ethernet header plus the size of
3732760Sdg199075  *           a VLAN header otherwise.
3742760Sdg199075  */
3750Sstevel@tonic-gate uint_t
3760Sstevel@tonic-gate ether_header_len(e)
3770Sstevel@tonic-gate char *e;
3780Sstevel@tonic-gate {
3792760Sdg199075 	uint16_t ether_type = 0;
3802760Sdg199075 	e += (offsetof(struct ether_header, ether_type));
3812760Sdg199075 
3822760Sdg199075 	GETINT16(ether_type, e);
3832760Sdg199075 
3842760Sdg199075 	if (ether_type == (uint16_t)ETHERTYPE_VLAN) {
3852760Sdg199075 		return (sizeof (struct ether_vlan_header));
3862760Sdg199075 	} else {
3872760Sdg199075 		return (sizeof (struct ether_header));
3882760Sdg199075 	}
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate /*
3930Sstevel@tonic-gate  * Table of Ethertypes.
3940Sstevel@tonic-gate  * Some of the more popular entries
3950Sstevel@tonic-gate  * are at the beginning of the table
3960Sstevel@tonic-gate  * to reduce search time.
3970Sstevel@tonic-gate  */
3980Sstevel@tonic-gate struct ether_type {
3990Sstevel@tonic-gate 	int   e_type;
4000Sstevel@tonic-gate 	char *e_name;
4010Sstevel@tonic-gate } ether_type [] = {
4020Sstevel@tonic-gate ETHERTYPE_IP, "IP",
4030Sstevel@tonic-gate ETHERTYPE_ARP, "ARP",
4040Sstevel@tonic-gate ETHERTYPE_REVARP, "RARP",
4050Sstevel@tonic-gate ETHERTYPE_IPV6, "IPv6",
4060Sstevel@tonic-gate ETHERTYPE_PPPOED, "PPPoE Discovery",
4070Sstevel@tonic-gate ETHERTYPE_PPPOES, "PPPoE Session",
408*10491SRishi.Srivatsavai@Sun.COM ETHERTYPE_TRILL, "TRILL",
4090Sstevel@tonic-gate /* end of popular entries */
4100Sstevel@tonic-gate ETHERTYPE_PUP,	"Xerox PUP",
4110Sstevel@tonic-gate 0x0201, "Xerox PUP",
4120Sstevel@tonic-gate 0x0400, "Nixdorf",
4130Sstevel@tonic-gate 0x0600, "Xerox NS IDP",
4140Sstevel@tonic-gate 0x0601, "XNS Translation",
4150Sstevel@tonic-gate 0x0801, "X.75 Internet",
4160Sstevel@tonic-gate 0x0802, "NBS Internet",
4170Sstevel@tonic-gate 0x0803, "ECMA Internet",
4180Sstevel@tonic-gate 0x0804, "CHAOSnet",
4190Sstevel@tonic-gate 0x0805, "X.25 Level 3",
4200Sstevel@tonic-gate 0x0807, "XNS Compatibility",
4210Sstevel@tonic-gate 0x081C, "Symbolics Private",
4220Sstevel@tonic-gate 0x0888, "Xyplex",
4230Sstevel@tonic-gate 0x0889, "Xyplex",
4240Sstevel@tonic-gate 0x088A, "Xyplex",
4250Sstevel@tonic-gate 0x0900, "Ungermann-Bass network debugger",
4260Sstevel@tonic-gate 0x0A00, "Xerox IEEE802.3 PUP",
4270Sstevel@tonic-gate 0x0A01, "Xerox IEEE802.3 PUP Address Translation",
4280Sstevel@tonic-gate 0x0BAD, "Banyan Systems",
4290Sstevel@tonic-gate 0x0BAF, "Banyon VINES Echo",
4300Sstevel@tonic-gate 0x1000, "Berkeley Trailer negotiation",
4310Sstevel@tonic-gate 0x1000,	"IP trailer (0)",
4320Sstevel@tonic-gate 0x1001,	"IP trailer (1)",
4330Sstevel@tonic-gate 0x1002,	"IP trailer (2)",
4340Sstevel@tonic-gate 0x1003,	"IP trailer (3)",
4350Sstevel@tonic-gate 0x1004,	"IP trailer (4)",
4360Sstevel@tonic-gate 0x1005,	"IP trailer (5)",
4370Sstevel@tonic-gate 0x1006,	"IP trailer (6)",
4380Sstevel@tonic-gate 0x1007,	"IP trailer (7)",
4390Sstevel@tonic-gate 0x1008,	"IP trailer (8)",
4400Sstevel@tonic-gate 0x1009,	"IP trailer (9)",
4410Sstevel@tonic-gate 0x100a,	"IP trailer (10)",
4420Sstevel@tonic-gate 0x100b,	"IP trailer (11)",
4430Sstevel@tonic-gate 0x100c,	"IP trailer (12)",
4440Sstevel@tonic-gate 0x100d,	"IP trailer (13)",
4450Sstevel@tonic-gate 0x100e,	"IP trailer (14)",
4460Sstevel@tonic-gate 0x100f,	"IP trailer (15)",
4470Sstevel@tonic-gate 0x1234, "DCA - Multicast",
4480Sstevel@tonic-gate 0x1600, "VALID system protocol",
4490Sstevel@tonic-gate 0x1989, "Aviator",
4500Sstevel@tonic-gate 0x3C00, "3Com NBP virtual circuit datagram",
4510Sstevel@tonic-gate 0x3C01, "3Com NBP System control datagram",
4520Sstevel@tonic-gate 0x3C02, "3Com NBP Connect request (virtual cct)",
4530Sstevel@tonic-gate 0x3C03, "3Com NBP Connect response",
4540Sstevel@tonic-gate 0x3C04, "3Com NBP Connect complete",
4550Sstevel@tonic-gate 0x3C05, "3Com NBP Close request (virtual cct)",
4560Sstevel@tonic-gate 0x3C06, "3Com NBP Close response",
4570Sstevel@tonic-gate 0x3C07, "3Com NBP Datagram (like XNS IDP)",
4580Sstevel@tonic-gate 0x3C08, "3Com NBP Datagram broadcast",
4590Sstevel@tonic-gate 0x3C09, "3Com NBP Claim NetBIOS name",
4600Sstevel@tonic-gate 0x3C0A, "3Com NBP Delete Netbios name",
4610Sstevel@tonic-gate 0x3C0B, "3Com NBP Remote adaptor status request",
4620Sstevel@tonic-gate 0x3C0C, "3Com NBP Remote adaptor response",
4630Sstevel@tonic-gate 0x3C0D, "3Com NBP Reset",
4640Sstevel@tonic-gate 0x4242, "PCS Basic Block Protocol",
4650Sstevel@tonic-gate 0x4321, "THD - Diddle",
4660Sstevel@tonic-gate 0x5208, "BBN Simnet Private",
4670Sstevel@tonic-gate 0x6000, "DEC unass, experimental",
4680Sstevel@tonic-gate 0x6001, "DEC Dump/Load",
4690Sstevel@tonic-gate 0x6002, "DEC Remote Console",
4700Sstevel@tonic-gate 0x6003, "DECNET Phase IV, DNA Routing",
4710Sstevel@tonic-gate 0x6004, "DEC LAT",
4720Sstevel@tonic-gate 0x6005, "DEC Diagnostic",
4730Sstevel@tonic-gate 0x6006, "DEC customer protocol",
4740Sstevel@tonic-gate 0x6007, "DEC Local Area VAX Cluster (LAVC)",
4750Sstevel@tonic-gate 0x6008, "DEC unass (AMBER?)",
4760Sstevel@tonic-gate 0x6009, "DEC unass (MUMPS?)",
4770Sstevel@tonic-gate 0x6010, "3Com",
4780Sstevel@tonic-gate 0x6011, "3Com",
4790Sstevel@tonic-gate 0x6012, "3Com",
4800Sstevel@tonic-gate 0x6013, "3Com",
4810Sstevel@tonic-gate 0x6014, "3Com",
4820Sstevel@tonic-gate 0x7000, "Ungermann-Bass download",
4830Sstevel@tonic-gate 0x7001, "Ungermann-Bass NIUs",
4840Sstevel@tonic-gate 0x7002, "Ungermann-Bass diagnostic/loopback",
4850Sstevel@tonic-gate 0x7003, "Ungermann-Bass ? (NMC to/from UB Bridge)",
4860Sstevel@tonic-gate 0x7005, "Ungermann-Bass Bridge Spanning Tree",
4870Sstevel@tonic-gate 0x7007, "OS/9 Microware",
4880Sstevel@tonic-gate 0x7009, "OS/9 Net?",
4890Sstevel@tonic-gate 0x7020, "Sintrom",
4900Sstevel@tonic-gate 0x7021, "Sintrom",
4910Sstevel@tonic-gate 0x7022, "Sintrom",
4920Sstevel@tonic-gate 0x7023, "Sintrom",
4930Sstevel@tonic-gate 0x7024, "Sintrom",
4940Sstevel@tonic-gate 0x7025, "Sintrom",
4950Sstevel@tonic-gate 0x7026, "Sintrom",
4960Sstevel@tonic-gate 0x7027, "Sintrom",
4970Sstevel@tonic-gate 0x7028, "Sintrom",
4980Sstevel@tonic-gate 0x7029, "Sintrom",
4990Sstevel@tonic-gate 0x8003, "Cronus VLN",
5000Sstevel@tonic-gate 0x8004, "Cronus Direct",
5010Sstevel@tonic-gate 0x8005, "HP Probe protocol",
5020Sstevel@tonic-gate 0x8006, "Nestar",
5030Sstevel@tonic-gate 0x8008, "AT&T/Stanford Univ",
5040Sstevel@tonic-gate 0x8010, "Excelan",
5050Sstevel@tonic-gate 0x8013, "SGI diagnostic",
5060Sstevel@tonic-gate 0x8014, "SGI network games",
5070Sstevel@tonic-gate 0x8015, "SGI reserved",
5080Sstevel@tonic-gate 0x8016, "SGI XNS NameServer, bounce server",
5090Sstevel@tonic-gate 0x8019, "Apollo DOMAIN",
5100Sstevel@tonic-gate 0x802E, "Tymshare",
5110Sstevel@tonic-gate 0x802F, "Tigan,",
5120Sstevel@tonic-gate 0x8036, "Aeonic Systems",
5130Sstevel@tonic-gate 0x8037, "IPX (Novell Netware)",
5140Sstevel@tonic-gate 0x8038, "DEC LanBridge Management",
5150Sstevel@tonic-gate 0x8039, "DEC unass (DSM/DTP?)",
5160Sstevel@tonic-gate 0x803A, "DEC unass (Argonaut Console?)",
5170Sstevel@tonic-gate 0x803B, "DEC unass (VAXELN?)",
5180Sstevel@tonic-gate 0x803C, "DEC unass (NMSV? DNA Naming Service?)",
5190Sstevel@tonic-gate 0x803D, "DEC Ethernet CSMA/CD Encryption Protocol",
5200Sstevel@tonic-gate 0x803E, "DEC unass (DNA Time Service?)",
5210Sstevel@tonic-gate 0x803F, "DEC LAN Traffic Monitor Protocol",
5220Sstevel@tonic-gate 0x8040, "DEC unass (NetBios Emulator?)",
5230Sstevel@tonic-gate 0x8041, "DEC unass (MS/DOS?, Local Area System Transport?)",
5240Sstevel@tonic-gate 0x8042, "DEC unass",
5250Sstevel@tonic-gate 0x8044, "Planning Research Corp.",
5260Sstevel@tonic-gate 0x8046, "AT&T",
5270Sstevel@tonic-gate 0x8047, "AT&T",
5280Sstevel@tonic-gate 0x8049, "ExperData",
5290Sstevel@tonic-gate 0x805B, "VMTP",
5300Sstevel@tonic-gate 0x805C, "Stanford V Kernel, version 6.0",
5310Sstevel@tonic-gate 0x805D, "Evans & Sutherland",
5320Sstevel@tonic-gate 0x8060, "Little Machines",
5330Sstevel@tonic-gate 0x8062, "Counterpoint",
5340Sstevel@tonic-gate 0x8065, "University of Mass. at Amherst",
5350Sstevel@tonic-gate 0x8066, "University of Mass. at Amherst",
5360Sstevel@tonic-gate 0x8067, "Veeco Integrated Automation",
5370Sstevel@tonic-gate 0x8068, "General Dynamics",
5380Sstevel@tonic-gate 0x8069, "AT&T",
5390Sstevel@tonic-gate 0x806A, "Autophon",
5400Sstevel@tonic-gate 0x806C, "ComDesign",
5410Sstevel@tonic-gate 0x806D, "Compugraphic Corp",
5420Sstevel@tonic-gate 0x806E, "Landmark",
5430Sstevel@tonic-gate 0x806F, "Landmark",
5440Sstevel@tonic-gate 0x8070, "Landmark",
5450Sstevel@tonic-gate 0x8071, "Landmark",
5460Sstevel@tonic-gate 0x8072, "Landmark",
5470Sstevel@tonic-gate 0x8073, "Landmark",
5480Sstevel@tonic-gate 0x8074, "Landmark",
5490Sstevel@tonic-gate 0x8075, "Landmark",
5500Sstevel@tonic-gate 0x8076, "Landmark",
5510Sstevel@tonic-gate 0x8077, "Landmark",
5520Sstevel@tonic-gate 0x807A, "Matra",
5530Sstevel@tonic-gate 0x807B, "Dansk Data Elektronik",
5540Sstevel@tonic-gate 0x807C, "Merit Internodal",
5550Sstevel@tonic-gate 0x807D, "Vitalink",
5560Sstevel@tonic-gate 0x807E, "Vitalink",
5570Sstevel@tonic-gate 0x807F, "Vitalink",
5580Sstevel@tonic-gate 0x8080, "Vitalink TransLAN III Management",
5590Sstevel@tonic-gate 0x8081, "Counterpoint",
5600Sstevel@tonic-gate 0x8082, "Counterpoint",
5610Sstevel@tonic-gate 0x8083, "Counterpoint",
5620Sstevel@tonic-gate 0x8088, "Xyplex",
5630Sstevel@tonic-gate 0x8089, "Xyplex",
5640Sstevel@tonic-gate 0x808A, "Xyplex",
5650Sstevel@tonic-gate 0x809B, "EtherTalk (AppleTalk over Ethernet)",
5660Sstevel@tonic-gate 0x809C, "Datability",
5670Sstevel@tonic-gate 0x809D, "Datability",
5680Sstevel@tonic-gate 0x809E, "Datability",
5690Sstevel@tonic-gate 0x809F, "Spider Systems",
5700Sstevel@tonic-gate 0x80A3, "Nixdorf",
5710Sstevel@tonic-gate 0x80A4, "Siemens Gammasonics",
5720Sstevel@tonic-gate 0x80C0, "DCA Data Exchange Cluster",
5730Sstevel@tonic-gate 0x80C6, "Pacer Software",
5740Sstevel@tonic-gate 0x80C7, "Applitek Corp",
5750Sstevel@tonic-gate 0x80C8, "Intergraph",
5760Sstevel@tonic-gate 0x80C9, "Intergraph",
5770Sstevel@tonic-gate 0x80CB, "Intergraph",
5780Sstevel@tonic-gate 0x80CC, "Intergraph",
5790Sstevel@tonic-gate 0x80CA, "Intergraph",
5800Sstevel@tonic-gate 0x80CD, "Harris Corp",
5810Sstevel@tonic-gate 0x80CE, "Harris Corp",
5820Sstevel@tonic-gate 0x80CF, "Taylor Instrument",
5830Sstevel@tonic-gate 0x80D0, "Taylor Instrument",
5840Sstevel@tonic-gate 0x80D1, "Taylor Instrument",
5850Sstevel@tonic-gate 0x80D2, "Taylor Instrument",
5860Sstevel@tonic-gate 0x80D3, "Rosemount Corp",
5870Sstevel@tonic-gate 0x80D4, "Rosemount Corp",
5880Sstevel@tonic-gate 0x80D5, "IBM SNA Services over Ethernet",
5890Sstevel@tonic-gate 0x80DD, "Varian Associates",
5900Sstevel@tonic-gate 0x80DE, "TRFS",
5910Sstevel@tonic-gate 0x80DF, "TRFS",
5920Sstevel@tonic-gate 0x80E0, "Allen-Bradley",
5930Sstevel@tonic-gate 0x80E1, "Allen-Bradley",
5940Sstevel@tonic-gate 0x80E2, "Allen-Bradley",
5950Sstevel@tonic-gate 0x80E3, "Allen-Bradley",
5960Sstevel@tonic-gate 0x80E4, "Datability",
5970Sstevel@tonic-gate 0x80F2, "Retix",
5980Sstevel@tonic-gate 0x80F3, "AARP (Appletalk)",
5990Sstevel@tonic-gate 0x80F4, "Kinetics",
6000Sstevel@tonic-gate 0x80F5, "Kinetics",
6010Sstevel@tonic-gate 0x80F7, "Apollo",
6020Sstevel@tonic-gate 0x80FF, "Wellfleet Communications",
6030Sstevel@tonic-gate 0x8102, "Wellfleet Communications",
6040Sstevel@tonic-gate 0x8107, "Symbolics Private",
6050Sstevel@tonic-gate 0x8108, "Symbolics Private",
6060Sstevel@tonic-gate 0x8109, "Symbolics Private",
6070Sstevel@tonic-gate 0x812B, "Talaris",
6080Sstevel@tonic-gate 0x8130, "Waterloo",
6090Sstevel@tonic-gate 0x8131, "VG Lab",
6100Sstevel@tonic-gate 0x8137, "Novell (old) NetWare IPX",
6110Sstevel@tonic-gate 0x8138, "Novell",
6120Sstevel@tonic-gate 0x814C, "SNMP over Ethernet",
6130Sstevel@tonic-gate 0x817D, "XTP",
6140Sstevel@tonic-gate 0x81D6, "Lantastic",
6150Sstevel@tonic-gate 0x8888, "HP LanProbe test?",
6160Sstevel@tonic-gate 0x9000, "Loopback",
6170Sstevel@tonic-gate 0x9001, "3Com, XNS Systems Management",
6180Sstevel@tonic-gate 0x9002, "3Com, TCP/IP Systems Management",
6190Sstevel@tonic-gate 0x9003, "3Com, loopback detection",
6200Sstevel@tonic-gate 0xAAAA, "DECNET	(VAX 6220 DEBNI)",
6210Sstevel@tonic-gate 0xFF00, "BBN VITAL-LanBridge cache wakeups",
6220Sstevel@tonic-gate 0,	"",
6230Sstevel@tonic-gate };
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate char *
6260Sstevel@tonic-gate print_fc(type)
6270Sstevel@tonic-gate uint_t type;
6280Sstevel@tonic-gate {
6290Sstevel@tonic-gate 
6300Sstevel@tonic-gate 	switch (type) {
6310Sstevel@tonic-gate 		case 0x50: return ("LLC");
6320Sstevel@tonic-gate 		case 0x4f: return ("SMT NSA");
6330Sstevel@tonic-gate 		case 0x41: return ("SMT Info");
6340Sstevel@tonic-gate 		default: return ("Unknown");
6350Sstevel@tonic-gate 	}
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate char *
6390Sstevel@tonic-gate print_smtclass(type)
6400Sstevel@tonic-gate uint_t type;
6410Sstevel@tonic-gate {
6420Sstevel@tonic-gate 	switch (type) {
6430Sstevel@tonic-gate 		case 0x01: return ("NIF");
6440Sstevel@tonic-gate 		case 0x02: return ("SIF Conf");
6450Sstevel@tonic-gate 		case 0x03: return ("SIF Oper");
6460Sstevel@tonic-gate 		case 0x04: return ("ECF");
6470Sstevel@tonic-gate 		case 0x05: return ("RAF");
6480Sstevel@tonic-gate 		case 0x06: return ("RDF");
6490Sstevel@tonic-gate 		case 0x07: return ("SRF");
6500Sstevel@tonic-gate 		case 0x08: return ("PMF Get");
6510Sstevel@tonic-gate 		case 0x09: return ("PMF Change");
6520Sstevel@tonic-gate 		case 0x0a: return ("PMF Add");
6530Sstevel@tonic-gate 		case 0x0b: return ("PMF Remove");
6540Sstevel@tonic-gate 		case 0xff: return ("ESF");
6550Sstevel@tonic-gate 		default: return ("Unknown");
6560Sstevel@tonic-gate 	}
6570Sstevel@tonic-gate 
6580Sstevel@tonic-gate }
6590Sstevel@tonic-gate char *
6600Sstevel@tonic-gate print_smttype(type)
6610Sstevel@tonic-gate uint_t type;
6620Sstevel@tonic-gate {
6630Sstevel@tonic-gate 	switch (type) {
6640Sstevel@tonic-gate 		case 0x01: return ("Announce");
6650Sstevel@tonic-gate 		case 0x02: return ("Request");
6660Sstevel@tonic-gate 		case 0x03: return ("Response");
6670Sstevel@tonic-gate 		default: return ("Unknown");
6680Sstevel@tonic-gate 	}
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate }
6710Sstevel@tonic-gate char *
6720Sstevel@tonic-gate print_ethertype(type)
6730Sstevel@tonic-gate 	int type;
6740Sstevel@tonic-gate {
6750Sstevel@tonic-gate 	int i;
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate 	for (i = 0; ether_type[i].e_type; i++)
6780Sstevel@tonic-gate 		if (type == ether_type[i].e_type)
6790Sstevel@tonic-gate 			return (ether_type[i].e_name);
6800Sstevel@tonic-gate 	if (type < 1500)
6810Sstevel@tonic-gate 		return ("LLC/802.3");
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 	return ("Unknown");
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate #define	MAX_RDFLDS	14		/* changed to 14 from 8 as per IEEE */
6870Sstevel@tonic-gate #define	TR_FN_ADDR	0x80		/* dest addr is functional */
6880Sstevel@tonic-gate #define	TR_SR_ADDR	0x80		/* MAC utilizes source route */
6890Sstevel@tonic-gate #define	ACFCDASA_LEN	14		/* length of AC|FC|DA|SA */
6900Sstevel@tonic-gate #define	TR_MAC_MASK	0xc0
6910Sstevel@tonic-gate #define	TR_AC		0x00		/* Token Ring access control */
6920Sstevel@tonic-gate #define	TR_LLC_FC	0x40		/* Token Ring llc frame control */
6930Sstevel@tonic-gate #define	LSAP_SNAP	0xaa
6940Sstevel@tonic-gate #define	LLC_SNAP_HDR_LEN	8
6950Sstevel@tonic-gate #define	LLC_HDR1_LEN	3		/* DON'T use sizeof(struct llc_hdr1) */
6960Sstevel@tonic-gate #define	CNTL_LLC_UI	0x03		/* un-numbered information packet */
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate /*
6990Sstevel@tonic-gate  * Source Routing Route Information field.
7000Sstevel@tonic-gate  */
7010Sstevel@tonic-gate struct tr_ri {
7020Sstevel@tonic-gate #if defined(_BIT_FIELDS_HTOL)
7030Sstevel@tonic-gate 	uchar_t rt:3;			/* routing type */
7040Sstevel@tonic-gate 	uchar_t len:5;			/* length */
7050Sstevel@tonic-gate 	uchar_t dir:1;			/* direction bit */
7060Sstevel@tonic-gate 	uchar_t mtu:3;			/* largest frame */
7070Sstevel@tonic-gate 	uchar_t res:4;			/* reserved */
7080Sstevel@tonic-gate #elif defined(_BIT_FIELDS_LTOH)
7090Sstevel@tonic-gate 	uchar_t len:5;			/* length */
7100Sstevel@tonic-gate 	uchar_t rt:3;			/* routing type */
7110Sstevel@tonic-gate 	uchar_t res:4;			/* reserved */
7120Sstevel@tonic-gate 	uchar_t mtu:3;			/* largest frame */
7130Sstevel@tonic-gate 	uchar_t dir:1;			/* direction bit */
7140Sstevel@tonic-gate #endif
7150Sstevel@tonic-gate /*
7160Sstevel@tonic-gate  * In little endian machine, the ring field has to be stored in a
7170Sstevel@tonic-gate  * ushort_t type.  This implies that it is not possible to have a
7180Sstevel@tonic-gate  * layout of bit field to represent bridge and ring.
7190Sstevel@tonic-gate  *
7200Sstevel@tonic-gate  * If the compiler uses _BIT_FIELDS_HTOL and it is a big endian
7210Sstevel@tonic-gate  * machine, the following bit field definition will work.
7220Sstevel@tonic-gate  *
7230Sstevel@tonic-gate  *	struct tr_rd {
7240Sstevel@tonic-gate  *		ushort_t bridge:4;
7250Sstevel@tonic-gate  *		ushort_t ring:12;
7260Sstevel@tonic-gate  *	} rd[MAX_RDFLDS];
7270Sstevel@tonic-gate  *
7280Sstevel@tonic-gate  * If the compiler uses _BIT_FIELDS_LTOH and it is a big endian
7290Sstevel@tonic-gate  * machine, the definition can be changed to
7300Sstevel@tonic-gate  *
7310Sstevel@tonic-gate  *	struct tr_rd {
7320Sstevel@tonic-gate  *		ushort_t bridge:4;
7330Sstevel@tonic-gate  *		ushort_t ring:12;
7340Sstevel@tonic-gate  *	} rd[MAX_RDFLDS];
7350Sstevel@tonic-gate  *
7360Sstevel@tonic-gate  * With little endian machine, we need to use 2 macroes.  For
7370Sstevel@tonic-gate  * simplicity, since the macroes work for both big and little
7380Sstevel@tonic-gate  * endian machines, we will not use bit fields for the
7390Sstevel@tonic-gate  * definition.
7400Sstevel@tonic-gate  */
7410Sstevel@tonic-gate #define	bridge(route)	(ntohs((ushort_t)(route)) & 0x0F)
7420Sstevel@tonic-gate #define	ring(route)	(ntohs((ushort_t)(route)) >> 4)
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate 	ushort_t rd[MAX_RDFLDS];	/* route designator fields */
7450Sstevel@tonic-gate };
7460Sstevel@tonic-gate 
7470Sstevel@tonic-gate struct tr_header {
7480Sstevel@tonic-gate 	uchar_t		ac;
7490Sstevel@tonic-gate 	uchar_t		fc;
7500Sstevel@tonic-gate 	struct ether_addr dhost;
7510Sstevel@tonic-gate 	struct ether_addr shost;
7520Sstevel@tonic-gate 	struct tr_ri	ri;
7530Sstevel@tonic-gate };
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate struct llc_snap_hdr {
7560Sstevel@tonic-gate 	uchar_t  d_lsap;		/* destination service access point */
7570Sstevel@tonic-gate 	uchar_t  s_lsap;		/* source link service access point */
7580Sstevel@tonic-gate 	uchar_t  control;		/* short control field */
7590Sstevel@tonic-gate 	uchar_t  org[3];		/* Ethernet style organization field */
7600Sstevel@tonic-gate 	ushort_t type;			/* Ethernet style type field */
7610Sstevel@tonic-gate };
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate struct ether_addr tokenbroadcastaddr2 = {
7640Sstevel@tonic-gate 	0xc0, 0x00, 0xff, 0xff, 0xff, 0xff
7650Sstevel@tonic-gate };
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate int Mtutab[] = {516, 1470, 2052, 4472, 8144, 11407, 17800};
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate char *
7700Sstevel@tonic-gate print_sr(struct tr_ri *rh)
7710Sstevel@tonic-gate {
7720Sstevel@tonic-gate 	int hops, ii;
7730Sstevel@tonic-gate 	static char line[512];
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate 	sprintf(line, "TR Source Route dir=%d, mtu=%d",
7768023SPhil.Kirk@Sun.COM 	    rh->dir, Mtutab[rh->mtu]);
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 	hops = (int)(rh->len - 2) / (int)2;
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	if (hops) {
7810Sstevel@tonic-gate 		sprintf(line+strlen(line), ", Route: ");
7820Sstevel@tonic-gate 		for (ii = 0; ii < hops; ii++) {
7830Sstevel@tonic-gate 			if (! bridge(rh->rd[ii])) {
7840Sstevel@tonic-gate 				sprintf(line+strlen(line), "(%d)",
7850Sstevel@tonic-gate 				    ring(rh->rd[ii]));
7860Sstevel@tonic-gate 			} else {
7870Sstevel@tonic-gate 				sprintf(line+strlen(line), "(%d)%d",
7880Sstevel@tonic-gate 				    ring(rh->rd[ii]), bridge(rh->rd[ii]));
7890Sstevel@tonic-gate 			}
7900Sstevel@tonic-gate 		}
7910Sstevel@tonic-gate 	}
7920Sstevel@tonic-gate 	return (&line[0]);
7930Sstevel@tonic-gate }
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate uint_t
7960Sstevel@tonic-gate interpret_tr(flags, e, elen, origlen)
7970Sstevel@tonic-gate 	int flags;
7980Sstevel@tonic-gate 	caddr_t	e;
7990Sstevel@tonic-gate 	int elen, origlen;
8000Sstevel@tonic-gate {
8010Sstevel@tonic-gate 	struct tr_header *mh;
8020Sstevel@tonic-gate 	struct tr_ri *rh;
8030Sstevel@tonic-gate 	uchar_t fc;
8040Sstevel@tonic-gate 	struct llc_snap_hdr *snaphdr;
8050Sstevel@tonic-gate 	char *off;
8060Sstevel@tonic-gate 	int maclen, len;
8070Sstevel@tonic-gate 	boolean_t data_copied = B_FALSE;
8080Sstevel@tonic-gate 	extern char *dst_name, *src_name;
8090Sstevel@tonic-gate 	int ethertype;
8100Sstevel@tonic-gate 	int is_llc = 0, is_snap = 0, source_routing = 0;
8110Sstevel@tonic-gate 	int tr_machdr_len(char *, int *, int *);
8120Sstevel@tonic-gate 	int blen = MAX(origlen, 17800);
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate 	if (data != NULL && datalen != 0 && datalen < blen) {
8150Sstevel@tonic-gate 		free(data);
8160Sstevel@tonic-gate 		data = NULL;
8170Sstevel@tonic-gate 		datalen = 0;
8180Sstevel@tonic-gate 	}
8190Sstevel@tonic-gate 	if (!data) {
8200Sstevel@tonic-gate 		data = (char *)malloc(blen);
8210Sstevel@tonic-gate 		if (!data)
8220Sstevel@tonic-gate 			pr_err("Warning: malloc failure");
8230Sstevel@tonic-gate 		datalen = blen;
8240Sstevel@tonic-gate 	}
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 	if (origlen < ACFCDASA_LEN) {
8270Sstevel@tonic-gate 		if (flags & F_SUM)
8280Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
8290Sstevel@tonic-gate 			"RUNT (short packet - %d bytes)",
8300Sstevel@tonic-gate 			origlen);
8310Sstevel@tonic-gate 		if (flags & F_DTAIL)
8320Sstevel@tonic-gate 			show_header("RUNT:  ", "Short packet", origlen);
8330Sstevel@tonic-gate 		return (elen);
8340Sstevel@tonic-gate 	}
8350Sstevel@tonic-gate 	if (elen < ACFCDASA_LEN)
8360Sstevel@tonic-gate 		return (elen);
8370Sstevel@tonic-gate 
8380Sstevel@tonic-gate 	mh = (struct tr_header *)e;
8390Sstevel@tonic-gate 	rh = (struct tr_ri *)&mh->ri;
8400Sstevel@tonic-gate 	fc = mh->fc;
8410Sstevel@tonic-gate 
8420Sstevel@tonic-gate 	if (is_llc = tr_machdr_len(e, &maclen, &source_routing)) {
8430Sstevel@tonic-gate 		snaphdr = (struct llc_snap_hdr *)(e + maclen);
8440Sstevel@tonic-gate 		if (snaphdr->d_lsap == LSAP_SNAP &&
8450Sstevel@tonic-gate 			snaphdr->s_lsap == LSAP_SNAP &&
8460Sstevel@tonic-gate 			snaphdr->control == CNTL_LLC_UI) {
8470Sstevel@tonic-gate 			is_snap = 1;
8480Sstevel@tonic-gate 		}
8490Sstevel@tonic-gate 	}
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 	if (memcmp(&mh->dhost, &ether_broadcast,
8520Sstevel@tonic-gate 	    sizeof (struct ether_addr)) == 0)
8530Sstevel@tonic-gate 		dst_name = "(broadcast)";
8540Sstevel@tonic-gate 	else if (memcmp(&mh->dhost, &tokenbroadcastaddr2,
8550Sstevel@tonic-gate 		sizeof (struct ether_addr)) == 0)
8560Sstevel@tonic-gate 		dst_name = "(mac broadcast)";
8570Sstevel@tonic-gate 	else if (mh->dhost.ether_addr_octet[0] & TR_FN_ADDR)
8580Sstevel@tonic-gate 		dst_name = "(functional)";
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 	if (is_snap)
8610Sstevel@tonic-gate 		ethertype = ntohs(snaphdr->type);
8620Sstevel@tonic-gate 	else {
8630Sstevel@tonic-gate 		src_name =  print_etherinfo(&mh->shost);
8640Sstevel@tonic-gate 		dst_name =  print_etherinfo(&mh->dhost);
8650Sstevel@tonic-gate 	}
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 	/*
8680Sstevel@tonic-gate 	 * The 14 byte ether header screws up alignment
8690Sstevel@tonic-gate 	 * of the rest of the packet for 32 bit aligned
8700Sstevel@tonic-gate 	 * architectures like SPARC. Alas, we have to copy
8710Sstevel@tonic-gate 	 * the rest of the packet in order to align it.
8720Sstevel@tonic-gate 	 */
8730Sstevel@tonic-gate 	if (is_llc) {
8740Sstevel@tonic-gate 		if (is_snap) {
8750Sstevel@tonic-gate 			len = elen - (maclen + LLC_SNAP_HDR_LEN);
8760Sstevel@tonic-gate 			off = (char *)(e + maclen + LLC_SNAP_HDR_LEN);
8770Sstevel@tonic-gate 		} else {
8780Sstevel@tonic-gate 			len = elen - (maclen + LLC_HDR1_LEN);
8790Sstevel@tonic-gate 			off = (char *)(e + maclen + LLC_HDR1_LEN);
8800Sstevel@tonic-gate 		}
8810Sstevel@tonic-gate 	} else {
8820Sstevel@tonic-gate 		len = elen - maclen;
8830Sstevel@tonic-gate 		off = (char *)(e + maclen);
8840Sstevel@tonic-gate 	}
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 	if (len > 0 && (off + len <= (char *)e + elen)) {
8870Sstevel@tonic-gate 		(void) memcpy(data, off, len);
8880Sstevel@tonic-gate 		data_copied = B_TRUE;
8890Sstevel@tonic-gate 	}
8900Sstevel@tonic-gate 
8910Sstevel@tonic-gate 	if (flags & F_SUM) {
8920Sstevel@tonic-gate 		if (source_routing)
8930Sstevel@tonic-gate 			sprintf(get_sum_line(), print_sr(rh));
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 		if (is_llc) {
8960Sstevel@tonic-gate 			if (is_snap) {
8970Sstevel@tonic-gate 				(void) sprintf(get_sum_line(),
8980Sstevel@tonic-gate 				"TR LLC w/SNAP Type=%04X (%s), size=%d bytes",
8990Sstevel@tonic-gate 				ethertype,
9000Sstevel@tonic-gate 				print_ethertype(ethertype),
9010Sstevel@tonic-gate 				origlen);
9020Sstevel@tonic-gate 			} else {
9030Sstevel@tonic-gate 				(void) sprintf(get_sum_line(),
9040Sstevel@tonic-gate 				"TR LLC, but no SNAP encoding, size = %d bytes",
9050Sstevel@tonic-gate 				origlen);
9060Sstevel@tonic-gate 			}
9070Sstevel@tonic-gate 		} else {
9080Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
9090Sstevel@tonic-gate 				"TR MAC FC=%02X (%s), size = %d bytes",
9100Sstevel@tonic-gate 				fc, print_fc(fc), origlen);
9110Sstevel@tonic-gate 		}
9120Sstevel@tonic-gate 	}
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 	if (flags & F_DTAIL) {
9150Sstevel@tonic-gate 	show_header("TR:  ", "TR Header", elen);
9160Sstevel@tonic-gate 	show_space();
9170Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
9180Sstevel@tonic-gate 		"Packet %d arrived at %d:%02d:%d.%05d",
9190Sstevel@tonic-gate 		pi_frame,
9200Sstevel@tonic-gate 		pi_time_hour, pi_time_min, pi_time_sec,
9210Sstevel@tonic-gate 		pi_time_usec / 10);
9220Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
9230Sstevel@tonic-gate 		"Packet size = %d bytes",
9240Sstevel@tonic-gate 		elen);
9250Sstevel@tonic-gate 	(void) sprintf(get_line(0, 1),
9260Sstevel@tonic-gate 		"Frame Control = %02x (%s)",
9270Sstevel@tonic-gate 		fc, print_fc(fc));
9280Sstevel@tonic-gate 	(void) sprintf(get_line(2, 6),
9290Sstevel@tonic-gate 		"Destination = %s, %s",
9300Sstevel@tonic-gate 		printether(&mh->dhost),
9310Sstevel@tonic-gate 		print_etherinfo(&mh->dhost));
9320Sstevel@tonic-gate 	(void) sprintf(get_line(8, 6),
9330Sstevel@tonic-gate 		"Source      = %s, %s",
9340Sstevel@tonic-gate 		printether(&mh->shost),
9350Sstevel@tonic-gate 		print_etherinfo(&mh->shost));
9360Sstevel@tonic-gate 
9370Sstevel@tonic-gate 	if (source_routing)
9380Sstevel@tonic-gate 		sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh));
9390Sstevel@tonic-gate 
9400Sstevel@tonic-gate 	if (is_llc) {
9410Sstevel@tonic-gate 		(void) sprintf(get_line(maclen, 1),
9420Sstevel@tonic-gate 			"Dest   Service Access Point = %02x",
9430Sstevel@tonic-gate 			snaphdr->d_lsap);
9440Sstevel@tonic-gate 		(void) sprintf(get_line(maclen+1, 1),
9450Sstevel@tonic-gate 			"Source Service Access Point = %02x",
9460Sstevel@tonic-gate 			snaphdr->s_lsap);
9470Sstevel@tonic-gate 		(void) sprintf(get_line(maclen+2, 1),
9480Sstevel@tonic-gate 			"Control = %02x",
9490Sstevel@tonic-gate 			snaphdr->control);
9500Sstevel@tonic-gate 		if (is_snap)
9510Sstevel@tonic-gate 			(void) sprintf(get_line(maclen+3, 3),
9520Sstevel@tonic-gate 				"SNAP Protocol Id = %02x%02x%02x",
9530Sstevel@tonic-gate 				snaphdr->org[0], snaphdr->org[1],
9540Sstevel@tonic-gate 				snaphdr->org[2]);
9550Sstevel@tonic-gate 	}
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 	if (is_snap)
9580Sstevel@tonic-gate 		(void) sprintf(get_line(maclen+6, 2),
9590Sstevel@tonic-gate 		"SNAP Type = %04X (%s)",
9600Sstevel@tonic-gate 		ethertype, print_ethertype(ethertype));
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 	show_space();
9630Sstevel@tonic-gate 	}
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate 	/* go to the next protocol layer */
9660Sstevel@tonic-gate 	if (is_snap && data_copied) {
9670Sstevel@tonic-gate 		switch (ethertype) {
9680Sstevel@tonic-gate 		case ETHERTYPE_IP:
9690Sstevel@tonic-gate 			(void) interpret_ip(flags, (struct ip *)data, len);
9700Sstevel@tonic-gate 			break;
9710Sstevel@tonic-gate 		/* Just in case it is decided to add this type */
9720Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
9730Sstevel@tonic-gate 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
9740Sstevel@tonic-gate 			break;
9750Sstevel@tonic-gate 		case ETHERTYPE_ARP:
9760Sstevel@tonic-gate 		case ETHERTYPE_REVARP:
9770Sstevel@tonic-gate 			interpret_arp(flags, (struct arphdr *)data, len);
9780Sstevel@tonic-gate 			break;
9790Sstevel@tonic-gate 		case ETHERTYPE_AARP:	/* AppleTalk */
9800Sstevel@tonic-gate 			interpret_aarp(flags, data, len);
9810Sstevel@tonic-gate 			break;
9820Sstevel@tonic-gate 		case ETHERTYPE_AT:
9830Sstevel@tonic-gate 			interpret_at(flags, (struct ddp_hdr *)data, len);
9840Sstevel@tonic-gate 			break;
9850Sstevel@tonic-gate 		default:
9860Sstevel@tonic-gate 			break;
9870Sstevel@tonic-gate 		}
9880Sstevel@tonic-gate 	}
9890Sstevel@tonic-gate 
9900Sstevel@tonic-gate 	return (elen);
9910Sstevel@tonic-gate }
9920Sstevel@tonic-gate 
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate /*
9950Sstevel@tonic-gate  *	stuffs length of mac and ri fields into *lenp
9960Sstevel@tonic-gate  *	returns:
9970Sstevel@tonic-gate  *		0: mac frame
9980Sstevel@tonic-gate  *		1: llc frame
9990Sstevel@tonic-gate  */
10000Sstevel@tonic-gate int
10010Sstevel@tonic-gate tr_machdr_len(char *e, int *lenp, int *source_routing)
10020Sstevel@tonic-gate {
10030Sstevel@tonic-gate 	struct tr_header *mh;
10040Sstevel@tonic-gate 	struct tr_ri *rh;
10050Sstevel@tonic-gate 	uchar_t fc;
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate 	mh = (struct tr_header *)e;
10080Sstevel@tonic-gate 	rh = (struct tr_ri *)&mh->ri;
10090Sstevel@tonic-gate 	fc = mh->fc;
10100Sstevel@tonic-gate 
10110Sstevel@tonic-gate 	if (mh->shost.ether_addr_octet[0] & TR_SR_ADDR) {
10120Sstevel@tonic-gate 		*lenp = ACFCDASA_LEN + rh->len;
10130Sstevel@tonic-gate 		*source_routing = 1;
10140Sstevel@tonic-gate 	} else {
10150Sstevel@tonic-gate 		*lenp = ACFCDASA_LEN;
10160Sstevel@tonic-gate 		*source_routing = 0;
10170Sstevel@tonic-gate 	}
10180Sstevel@tonic-gate 
10190Sstevel@tonic-gate 	if ((fc & TR_MAC_MASK) == 0)
10200Sstevel@tonic-gate 		return (0);		/* it's a MAC frame */
10210Sstevel@tonic-gate 	else
10220Sstevel@tonic-gate 		return (1);		/* it's an LLC frame */
10230Sstevel@tonic-gate }
10240Sstevel@tonic-gate 
10250Sstevel@tonic-gate uint_t
10260Sstevel@tonic-gate tr_header_len(e)
10270Sstevel@tonic-gate char	*e;
10280Sstevel@tonic-gate {
10290Sstevel@tonic-gate 	struct llc_snap_hdr *snaphdr;
10300Sstevel@tonic-gate 	int len = 0, source_routing;
10310Sstevel@tonic-gate 
10320Sstevel@tonic-gate 	if (tr_machdr_len(e, &len, &source_routing) == 0)
10330Sstevel@tonic-gate 		return (len);		/* it's a MAC frame */
10340Sstevel@tonic-gate 
10350Sstevel@tonic-gate 	snaphdr = (struct llc_snap_hdr *)(e + len);
10360Sstevel@tonic-gate 	if (snaphdr->d_lsap == LSAP_SNAP &&
10370Sstevel@tonic-gate 			snaphdr->s_lsap == LSAP_SNAP &&
10380Sstevel@tonic-gate 			snaphdr->control == CNTL_LLC_UI)
10390Sstevel@tonic-gate 		len += LLC_SNAP_HDR_LEN;	/* it's a SNAP frame */
10400Sstevel@tonic-gate 	else
10410Sstevel@tonic-gate 		len += LLC_HDR1_LEN;
10420Sstevel@tonic-gate 
10430Sstevel@tonic-gate 	return (len);
10440Sstevel@tonic-gate }
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate struct fddi_header {
10470Sstevel@tonic-gate 	uchar_t fc;
10480Sstevel@tonic-gate 	struct ether_addr dhost, shost;
10490Sstevel@tonic-gate 	uchar_t dsap, ssap, ctl, proto_id[3];
10500Sstevel@tonic-gate 	ushort_t	type;
10510Sstevel@tonic-gate };
10520Sstevel@tonic-gate 
10530Sstevel@tonic-gate uint_t
10540Sstevel@tonic-gate interpret_fddi(flags, e, elen, origlen)
10550Sstevel@tonic-gate 	int flags;
10560Sstevel@tonic-gate 	caddr_t	e;
10570Sstevel@tonic-gate 	int elen, origlen;
10580Sstevel@tonic-gate {
10590Sstevel@tonic-gate 	struct fddi_header fhdr, *f = &fhdr;
10600Sstevel@tonic-gate 	char *off;
10610Sstevel@tonic-gate 	int len;
10620Sstevel@tonic-gate 	boolean_t data_copied = B_FALSE;
10630Sstevel@tonic-gate 	extern char *dst_name, *src_name;
10640Sstevel@tonic-gate 	int ethertype;
10650Sstevel@tonic-gate 	int is_llc = 0, is_smt = 0, is_snap = 0;
10660Sstevel@tonic-gate 	int blen = MAX(origlen, 4500);
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 	if (data != NULL && datalen != 0 && datalen < blen) {
10690Sstevel@tonic-gate 		free(data);
10700Sstevel@tonic-gate 		data = NULL;
10710Sstevel@tonic-gate 		datalen = 0;
10720Sstevel@tonic-gate 	}
10730Sstevel@tonic-gate 	if (!data) {
10740Sstevel@tonic-gate 		data = (char *)malloc(blen);
10750Sstevel@tonic-gate 		if (!data)
10760Sstevel@tonic-gate 			pr_err("Warning: malloc failure");
10770Sstevel@tonic-gate 		datalen = blen;
10780Sstevel@tonic-gate 	}
10790Sstevel@tonic-gate 
10800Sstevel@tonic-gate 	if (origlen < 13) {
10810Sstevel@tonic-gate 		if (flags & F_SUM)
10820Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
10830Sstevel@tonic-gate 			"RUNT (short packet - %d bytes)",
10840Sstevel@tonic-gate 			origlen);
10850Sstevel@tonic-gate 		if (flags & F_DTAIL)
10860Sstevel@tonic-gate 			show_header("RUNT:  ", "Short packet", origlen);
10870Sstevel@tonic-gate 		return (elen);
10880Sstevel@tonic-gate 	}
10890Sstevel@tonic-gate 	if (elen < 13)
10900Sstevel@tonic-gate 		return (elen);
10910Sstevel@tonic-gate 
10920Sstevel@tonic-gate 	(void) memcpy(&f->fc, e, sizeof (f->fc));
10930Sstevel@tonic-gate 	addr_copy_swap(&f->dhost, (struct ether_addr *)(e+1));
10940Sstevel@tonic-gate 	addr_copy_swap(&f->shost, (struct ether_addr *)(e+7));
10950Sstevel@tonic-gate 
10960Sstevel@tonic-gate 	if ((f->fc&0x50) == 0x50) {
10970Sstevel@tonic-gate 		is_llc = 1;
10980Sstevel@tonic-gate 		(void) memcpy(&f->dsap, e+13, sizeof (f->dsap));
10990Sstevel@tonic-gate 		(void) memcpy(&f->ssap, e+14, sizeof (f->ssap));
11000Sstevel@tonic-gate 		(void) memcpy(&f->ctl, e+15, sizeof (f->ctl));
11010Sstevel@tonic-gate 		if (f->dsap == 0xaa && f->ssap == 0xaa) {
11020Sstevel@tonic-gate 			is_snap = 1;
11030Sstevel@tonic-gate 			(void) memcpy(&f->proto_id, e+16, sizeof (f->proto_id));
11040Sstevel@tonic-gate 			(void) memcpy(&f->type, e+19, sizeof (f->type));
11050Sstevel@tonic-gate 		}
11060Sstevel@tonic-gate 	} else {
11070Sstevel@tonic-gate 		if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) {
11080Sstevel@tonic-gate 			is_smt = 1;
11090Sstevel@tonic-gate 		}
11100Sstevel@tonic-gate 	}
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 
11130Sstevel@tonic-gate 	if (memcmp(&f->dhost, &ether_broadcast,
11140Sstevel@tonic-gate 	    sizeof (struct ether_addr)) == 0)
11150Sstevel@tonic-gate 		dst_name = "(broadcast)";
11160Sstevel@tonic-gate 	else if (f->dhost.ether_addr_octet[0] & 0x01)
11170Sstevel@tonic-gate 		dst_name = "(multicast)";
11180Sstevel@tonic-gate 
11190Sstevel@tonic-gate 	if (is_snap)
11200Sstevel@tonic-gate 		ethertype = ntohs(f->type);
11210Sstevel@tonic-gate 	else {
11220Sstevel@tonic-gate 		src_name = 	print_etherinfo(&f->shost);
11230Sstevel@tonic-gate 		dst_name =  print_etherinfo(&f->dhost);
11240Sstevel@tonic-gate 	}
11250Sstevel@tonic-gate 
11260Sstevel@tonic-gate 	/*
11270Sstevel@tonic-gate 	 * The 14 byte ether header screws up alignment
11280Sstevel@tonic-gate 	 * of the rest of the packet for 32 bit aligned
11290Sstevel@tonic-gate 	 * architectures like SPARC. Alas, we have to copy
11300Sstevel@tonic-gate 	 * the rest of the packet in order to align it.
11310Sstevel@tonic-gate 	 */
11320Sstevel@tonic-gate 	if (is_llc) {
11330Sstevel@tonic-gate 		if (is_snap) {
11340Sstevel@tonic-gate 			len = elen - 21;
11350Sstevel@tonic-gate 			off = (char *)(e + 21);
11360Sstevel@tonic-gate 		} else {
11370Sstevel@tonic-gate 			len = elen - 16;
11380Sstevel@tonic-gate 			off = (char *)(e + 16);
11390Sstevel@tonic-gate 		}
11400Sstevel@tonic-gate 	} else {
11410Sstevel@tonic-gate 		len = elen - 13;
11420Sstevel@tonic-gate 		off = (char *)(e + 13);
11430Sstevel@tonic-gate 	}
11440Sstevel@tonic-gate 
11450Sstevel@tonic-gate 	if (len > 0 && (off + len <= (char *)e + elen)) {
11460Sstevel@tonic-gate 		(void) memcpy(data, off, len);
11470Sstevel@tonic-gate 		data_copied = B_TRUE;
11480Sstevel@tonic-gate 	}
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 	if (flags & F_SUM) {
11510Sstevel@tonic-gate 		if (is_llc) {
11520Sstevel@tonic-gate 			if (is_snap) {
11530Sstevel@tonic-gate 				(void) sprintf(get_sum_line(),
11540Sstevel@tonic-gate 				"FDDI LLC Type=%04X (%s), size = %d bytes",
11550Sstevel@tonic-gate 				ethertype,
11560Sstevel@tonic-gate 				print_ethertype(ethertype),
11570Sstevel@tonic-gate 				origlen);
11580Sstevel@tonic-gate 			} else {
11590Sstevel@tonic-gate 				(void) sprintf(get_sum_line(),
11600Sstevel@tonic-gate 				"LLC, but no SNAP encoding, size = %d bytes",
11610Sstevel@tonic-gate 				origlen);
11620Sstevel@tonic-gate 			}
11630Sstevel@tonic-gate 		} else if (is_smt) {
11640Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
11650Sstevel@tonic-gate 		"SMT Type=%02X (%s), Class = %02X (%s), size = %d bytes",
11660Sstevel@tonic-gate 			*(uchar_t *)(data+1), print_smttype(*(data+1)), *data,
11670Sstevel@tonic-gate 			print_smtclass(*data), origlen);
11680Sstevel@tonic-gate 		} else {
11690Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
11700Sstevel@tonic-gate 				"FC=%02X (%s), size = %d bytes",
11710Sstevel@tonic-gate 				f->fc, print_fc(f->fc), origlen);
11720Sstevel@tonic-gate 		}
11730Sstevel@tonic-gate 	}
11740Sstevel@tonic-gate 
11750Sstevel@tonic-gate 	if (flags & F_DTAIL) {
11760Sstevel@tonic-gate 	show_header("FDDI:  ", "FDDI Header", elen);
11770Sstevel@tonic-gate 	show_space();
11780Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
11790Sstevel@tonic-gate 		"Packet %d arrived at %d:%02d:%d.%05d",
11800Sstevel@tonic-gate 		pi_frame,
11810Sstevel@tonic-gate 		pi_time_hour, pi_time_min, pi_time_sec,
11820Sstevel@tonic-gate 		pi_time_usec / 10);
11830Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
11840Sstevel@tonic-gate 		"Packet size = %d bytes",
11850Sstevel@tonic-gate 		elen, elen);
11860Sstevel@tonic-gate 	(void) sprintf(get_line(0, 6),
11870Sstevel@tonic-gate 		"Destination = %s, %s",
11880Sstevel@tonic-gate 		printether(&f->dhost),
11890Sstevel@tonic-gate 		print_etherinfo(&f->dhost));
11900Sstevel@tonic-gate 	(void) sprintf(get_line(6, 6),
11910Sstevel@tonic-gate 		"Source      = %s, %s",
11920Sstevel@tonic-gate 		printether(&f->shost),
11930Sstevel@tonic-gate 		print_etherinfo(&f->shost));
11940Sstevel@tonic-gate 
11950Sstevel@tonic-gate 	if (is_llc) {
11960Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
11970Sstevel@tonic-gate 			"Frame Control = %02x (%s)",
11980Sstevel@tonic-gate 			f->fc, print_fc(f->fc));
11990Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12000Sstevel@tonic-gate 			"Dest   Service Access Point = %02x",
12010Sstevel@tonic-gate 			f->dsap);
12020Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12030Sstevel@tonic-gate 			"Source Service Access Point = %02x",
12040Sstevel@tonic-gate 			f->ssap);
12050Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12060Sstevel@tonic-gate 			"Control = %02x",
12070Sstevel@tonic-gate 			f->ctl);
12080Sstevel@tonic-gate 		if (is_snap)
12090Sstevel@tonic-gate 			(void) sprintf(get_line(12, 2),
12100Sstevel@tonic-gate 				"Protocol Id = %02x%02x%02x",
12110Sstevel@tonic-gate 				f->proto_id[0], f->proto_id[1], f->proto_id[2]);
12120Sstevel@tonic-gate 	} else if (is_smt) {
12130Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12140Sstevel@tonic-gate 			"Frame Control = %02x (%s)",
12150Sstevel@tonic-gate 			f->fc, print_fc(f->fc));
12160Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12170Sstevel@tonic-gate 			"Class = %02x (%s)",
12180Sstevel@tonic-gate 			(uchar_t)*data, print_smtclass(*data));
12190Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12200Sstevel@tonic-gate 			"Type = %02x (%s)",
12210Sstevel@tonic-gate 			*(uchar_t *)(data+1), print_smttype(*(data+1)));
12220Sstevel@tonic-gate 	} else {
12230Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12240Sstevel@tonic-gate 			"FC=%02X (%s), size = %d bytes",
12250Sstevel@tonic-gate 			f->fc, print_fc(f->fc), origlen);
12260Sstevel@tonic-gate 	}
12270Sstevel@tonic-gate 
12280Sstevel@tonic-gate 	if (is_snap)
12290Sstevel@tonic-gate 		(void) sprintf(get_line(12, 2),
12300Sstevel@tonic-gate 		"LLC Type = %04X (%s)",
12310Sstevel@tonic-gate 		ethertype, print_ethertype(ethertype));
12320Sstevel@tonic-gate 
12330Sstevel@tonic-gate 	show_space();
12340Sstevel@tonic-gate 	}
12350Sstevel@tonic-gate 
12360Sstevel@tonic-gate 	/* go to the next protocol layer */
12370Sstevel@tonic-gate 	if (is_llc && is_snap && f->ctl == 0x03 && data_copied) {
12380Sstevel@tonic-gate 		switch (ethertype) {
12390Sstevel@tonic-gate 		case ETHERTYPE_IP:
12400Sstevel@tonic-gate 			(void) interpret_ip(flags, (struct ip *)data, len);
12410Sstevel@tonic-gate 			break;
12420Sstevel@tonic-gate 		/* Just in case it is decided to add this type */
12430Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
12440Sstevel@tonic-gate 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
12450Sstevel@tonic-gate 			break;
12460Sstevel@tonic-gate 		case ETHERTYPE_ARP:
12470Sstevel@tonic-gate 		case ETHERTYPE_REVARP:
12480Sstevel@tonic-gate 			interpret_arp(flags, (struct arphdr *)data, len);
12490Sstevel@tonic-gate 			break;
12500Sstevel@tonic-gate 		default:
12510Sstevel@tonic-gate 			break;
12520Sstevel@tonic-gate 		}
12530Sstevel@tonic-gate 
12540Sstevel@tonic-gate 	}
12550Sstevel@tonic-gate 
12560Sstevel@tonic-gate 	return (elen);
12570Sstevel@tonic-gate }
12580Sstevel@tonic-gate 
12590Sstevel@tonic-gate uint_t
1260410Skcpoon fddi_header_len(char *e)
12610Sstevel@tonic-gate {
12620Sstevel@tonic-gate 	struct fddi_header fhdr, *f = &fhdr;
12630Sstevel@tonic-gate 
12640Sstevel@tonic-gate 	(void) memcpy(&f->fc, e, sizeof (f->fc));
12650Sstevel@tonic-gate 	(void) memcpy(&f->dhost, e+1, sizeof (struct ether_addr));
12660Sstevel@tonic-gate 	(void) memcpy(&f->shost, e+7, sizeof (struct ether_addr));
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate 	if ((f->fc&0x50) == 0x50) {
12690Sstevel@tonic-gate 		(void) memcpy(&f->dsap, e+13, sizeof (f->dsap));
12700Sstevel@tonic-gate 		(void) memcpy(&f->ssap, e+14, sizeof (f->ssap));
12710Sstevel@tonic-gate 		(void) memcpy(&f->ctl, e+15, sizeof (f->ctl));
12720Sstevel@tonic-gate 		if (f->dsap == 0xaa && f->ssap == 0xaa) {
12730Sstevel@tonic-gate 			return (21);
12740Sstevel@tonic-gate 		}
12750Sstevel@tonic-gate 		return (16);
12760Sstevel@tonic-gate 	} else {
12770Sstevel@tonic-gate 		if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) {
12780Sstevel@tonic-gate 			return (13);
12790Sstevel@tonic-gate 		}
12800Sstevel@tonic-gate 	}
1281410Skcpoon 	/* Return the default FDDI header length. */
1282410Skcpoon 	return (13);
12830Sstevel@tonic-gate }
12840Sstevel@tonic-gate 
12850Sstevel@tonic-gate /*
12860Sstevel@tonic-gate  * Print the given Ethernet address
12870Sstevel@tonic-gate  */
12880Sstevel@tonic-gate char *
12890Sstevel@tonic-gate printether(p)
12900Sstevel@tonic-gate 	struct ether_addr *p;
12910Sstevel@tonic-gate {
12920Sstevel@tonic-gate 	static char buf[256];
12930Sstevel@tonic-gate 
12940Sstevel@tonic-gate 	sprintf(buf, "%x:%x:%x:%x:%x:%x",
12950Sstevel@tonic-gate 		p->ether_addr_octet[0],
12960Sstevel@tonic-gate 		p->ether_addr_octet[1],
12970Sstevel@tonic-gate 		p->ether_addr_octet[2],
12980Sstevel@tonic-gate 		p->ether_addr_octet[3],
12990Sstevel@tonic-gate 		p->ether_addr_octet[4],
13000Sstevel@tonic-gate 		p->ether_addr_octet[5]);
13010Sstevel@tonic-gate 
13020Sstevel@tonic-gate 	return (buf);
13030Sstevel@tonic-gate }
13040Sstevel@tonic-gate 
13050Sstevel@tonic-gate /*
13060Sstevel@tonic-gate  * Table of Ethernet Address Assignments
13070Sstevel@tonic-gate  * Some of the more popular entries
13080Sstevel@tonic-gate  * are at the beginning of the table
13090Sstevel@tonic-gate  * to reduce search time.  Note that the
13100Sstevel@tonic-gate  * e-block's are stored in host byte-order.
13110Sstevel@tonic-gate  */
13120Sstevel@tonic-gate struct block_type {
13130Sstevel@tonic-gate 	int	e_block;
13140Sstevel@tonic-gate 	char	*e_name;
13150Sstevel@tonic-gate } ether_block [] = {
13160Sstevel@tonic-gate 0x080020,	"Sun",
13170Sstevel@tonic-gate 0x0000C6,	"HP",
13180Sstevel@tonic-gate 0x08002B,	"DEC",
13190Sstevel@tonic-gate 0x00000F,	"NeXT",
13200Sstevel@tonic-gate 0x00000C,	"Cisco",
13210Sstevel@tonic-gate 0x080069,	"Silicon Graphics",
13220Sstevel@tonic-gate 0x000069,	"Silicon Graphics",
13230Sstevel@tonic-gate 0x0000A7,	"Network Computing Devices (NCD	X-terminal)",
13240Sstevel@tonic-gate 0x08005A,	"IBM",
13250Sstevel@tonic-gate 0x0000AC,	"Apollo",
1326*10491SRishi.Srivatsavai@Sun.COM 0x0180C2,	"Standard MAC Group Address",
13270Sstevel@tonic-gate /* end of popular entries */
13280Sstevel@tonic-gate 0x000002,	"BBN",
13290Sstevel@tonic-gate 0x000010,	"Sytek",
13300Sstevel@tonic-gate 0x000011,	"Tektronix",
13310Sstevel@tonic-gate 0x000018,	"Webster (?)",
13320Sstevel@tonic-gate 0x00001B,	"Novell",
13330Sstevel@tonic-gate 0x00001D,	"Cabletron",
13340Sstevel@tonic-gate 0x000020,	"DIAB (Data Industrier AB)",
13350Sstevel@tonic-gate 0x000021,	"SC&C",
13360Sstevel@tonic-gate 0x000022,	"Visual Technology",
13370Sstevel@tonic-gate 0x000029,	"IMC",
13380Sstevel@tonic-gate 0x00002A,	"TRW",
13390Sstevel@tonic-gate 0x00003D,	"AT&T",
13400Sstevel@tonic-gate 0x000049,	"Apricot Ltd.",
13410Sstevel@tonic-gate 0x000055,	"AT&T",
13420Sstevel@tonic-gate 0x00005A,	"S & Koch",
13430Sstevel@tonic-gate 0x00005A,	"Xerox 806 (unregistered)",
13440Sstevel@tonic-gate 0x00005E,	"U.S. Department of Defense (IANA)",
13450Sstevel@tonic-gate 0x000065,	"Network General",
13460Sstevel@tonic-gate 0x00006B,	"MIPS",
13470Sstevel@tonic-gate 0x000077,	"MIPS",
13480Sstevel@tonic-gate 0x000079,	"NetWare (?)",
13490Sstevel@tonic-gate 0x00007A,	"Ardent",
13500Sstevel@tonic-gate 0x00007B,	"Research Machines",
13510Sstevel@tonic-gate 0x00007D,	"Harris (3M) (old)",
13520Sstevel@tonic-gate 0x000080,	"Imagen(?)",
13530Sstevel@tonic-gate 0x000081,	"Synoptics",
13540Sstevel@tonic-gate 0x000084,	"Aquila (?)",
13550Sstevel@tonic-gate 0x000086,	"Gateway (?)",
13560Sstevel@tonic-gate 0x000089,	"Cayman Systems	Gatorbox",
13570Sstevel@tonic-gate 0x000093,	"Proteon",
13580Sstevel@tonic-gate 0x000094,	"Asante",
13590Sstevel@tonic-gate 0x000098,	"Cross Com",
13600Sstevel@tonic-gate 0x00009F,	"Ameristar Technology",
13610Sstevel@tonic-gate 0x0000A2,	"Wellfleet",
13620Sstevel@tonic-gate 0x0000A3,	"Network Application Technology",
13630Sstevel@tonic-gate 0x0000A4,	"Acorn",
13640Sstevel@tonic-gate 0x0000A6,	"Network General",
13650Sstevel@tonic-gate 0x0000A7,	"Network Computing Devices (NCD	X-terminal)",
13660Sstevel@tonic-gate 0x0000A9,	"Network Systems",
13670Sstevel@tonic-gate 0x0000AA,	"Xerox",
13680Sstevel@tonic-gate 0x0000B3,	"CIMLinc",
13690Sstevel@tonic-gate 0x0000B5,	"Datability Terminal Server",
13700Sstevel@tonic-gate 0x0000B7,	"Dove Fastnet",
13710Sstevel@tonic-gate 0x0000BC,	"Allen-Bradley",
13720Sstevel@tonic-gate 0x0000C0,	"Western Digital",
13730Sstevel@tonic-gate 0x0000C8,	"Altos",
13740Sstevel@tonic-gate 0x0000C9,	"Emulex Terminal Server",
13750Sstevel@tonic-gate 0x0000D0,	"Develcon Electronics, Ltd.",
13760Sstevel@tonic-gate 0x0000D1,	"Adaptec Inc. Nodem product",
13770Sstevel@tonic-gate 0x0000D7,	"Dartmouth College (NED Router)",
13780Sstevel@tonic-gate 0x0000DD,	"Gould",
13790Sstevel@tonic-gate 0x0000DE,	"Unigraph",
13800Sstevel@tonic-gate 0x0000E2,	"Acer Counterpoint",
13810Sstevel@tonic-gate 0x0000E8,	"Accton Technology Corporation",
13820Sstevel@tonic-gate 0x0000EE,	"Network Designers Limited(?)",
13830Sstevel@tonic-gate 0x0000EF,	"Alantec",
13840Sstevel@tonic-gate 0x0000F3,	"Gandalf",
13850Sstevel@tonic-gate 0x0000FD,	"High Level Hardware (Orion, UK)",
13860Sstevel@tonic-gate 0x000143,	"IEEE 802",
13870Sstevel@tonic-gate 0x001700,	"Kabel",
13880Sstevel@tonic-gate 0x004010,	"Sonic",
13890Sstevel@tonic-gate 0x00608C,	"3Com",
13900Sstevel@tonic-gate 0x00800F,	"SMC",
13910Sstevel@tonic-gate 0x008019,	"Dayna Communications Etherprint product",
13920Sstevel@tonic-gate 0x00802D,	"Xylogics, Inc.	Annex terminal servers",
13930Sstevel@tonic-gate 0x008035,	"Technology Works",
13940Sstevel@tonic-gate 0x008087,	"Okidata",
13950Sstevel@tonic-gate 0x00808C,	"Frontier Software Development",
13960Sstevel@tonic-gate 0x0080C7,	"Xircom Inc.",
13970Sstevel@tonic-gate 0x0080D0,	"Computer Products International",
13980Sstevel@tonic-gate 0x0080D3,	"Shiva Appletalk-Ethernet interface",
13990Sstevel@tonic-gate 0x0080D4,	"Chase Limited",
14000Sstevel@tonic-gate 0x0080F1,	"Opus",
14010Sstevel@tonic-gate 0x00AA00,	"Intel",
14020Sstevel@tonic-gate 0x00B0D0,	"Computer Products International",
14030Sstevel@tonic-gate 0x00DD00,	"Ungermann-Bass",
14040Sstevel@tonic-gate 0x00DD01,	"Ungermann-Bass",
14050Sstevel@tonic-gate 0x00EFE5,	"IBM (3Com card)",
14060Sstevel@tonic-gate 0x020406,	"BBN",
14070Sstevel@tonic-gate 0x026060,	"3Com",
14080Sstevel@tonic-gate 0x026086,	"Satelcom MegaPac (UK)",
14090Sstevel@tonic-gate 0x02E6D3,	"Bus-Tech, Inc. (BTI)",
14100Sstevel@tonic-gate 0x080001,	"Computer Vision",
14110Sstevel@tonic-gate 0x080002,	"3Com (Formerly Bridge)",
14120Sstevel@tonic-gate 0x080003,	"ACC (Advanced Computer Communications)",
14130Sstevel@tonic-gate 0x080005,	"Symbolics",
14140Sstevel@tonic-gate 0x080007,	"Apple",
14150Sstevel@tonic-gate 0x080008,	"BBN",
14160Sstevel@tonic-gate 0x080009,	"Hewlett-Packard",
14170Sstevel@tonic-gate 0x08000A,	"Nestar Systems",
14180Sstevel@tonic-gate 0x08000B,	"Unisys",
14190Sstevel@tonic-gate 0x08000D,	"ICL",
14200Sstevel@tonic-gate 0x08000E,	"NCR",
14210Sstevel@tonic-gate 0x080010,	"AT&T",
14220Sstevel@tonic-gate 0x080011,	"Tektronix, Inc.",
14230Sstevel@tonic-gate 0x080017,	"NSC",
14240Sstevel@tonic-gate 0x08001A,	"Data General",
14250Sstevel@tonic-gate 0x08001B,	"Data General",
14260Sstevel@tonic-gate 0x08001E,	"Apollo",
14270Sstevel@tonic-gate 0x080022,	"NBI",
14280Sstevel@tonic-gate 0x080025,	"CDC",
14290Sstevel@tonic-gate 0x080026,	"Norsk Data (Nord)",
14300Sstevel@tonic-gate 0x080027,	"PCS Computer Systems GmbH",
14310Sstevel@tonic-gate 0x080028,	"TI Explorer",
14320Sstevel@tonic-gate 0x08002E,	"Metaphor",
14330Sstevel@tonic-gate 0x08002F,	"Prime Computer",
14340Sstevel@tonic-gate 0x080036,	"Intergraph CAE stations",
14350Sstevel@tonic-gate 0x080037,	"Fujitsu-Xerox",
14360Sstevel@tonic-gate 0x080038,	"Bull",
14370Sstevel@tonic-gate 0x080039,	"Spider Systems",
14380Sstevel@tonic-gate 0x08003B,	"Torus Systems",
14390Sstevel@tonic-gate 0x08003E,	"Motorola VME bus processor module",
14400Sstevel@tonic-gate 0x080041,	"DCA Digital Comm. Assoc.",
14410Sstevel@tonic-gate 0x080046,	"Sony",
14420Sstevel@tonic-gate 0x080047,	"Sequent",
14430Sstevel@tonic-gate 0x080049,	"Univation",
14440Sstevel@tonic-gate 0x08004C,	"Encore",
14450Sstevel@tonic-gate 0x08004E,	"BICC",
14460Sstevel@tonic-gate 0x080056,	"Stanford University",
14470Sstevel@tonic-gate 0x080057,	"Evans & Sutherland (?)",
14480Sstevel@tonic-gate 0x080067,	"Comdesign",
14490Sstevel@tonic-gate 0x080068,	"Ridge",
14500Sstevel@tonic-gate 0x08006A,	"ATTst (?)",
14510Sstevel@tonic-gate 0x08006E,	"Excelan",
14520Sstevel@tonic-gate 0x080075,	"DDE (Danish Data Elektronik A/S)",
14530Sstevel@tonic-gate 0x080077,	"TSL (now Retix)",
14540Sstevel@tonic-gate 0x08007C,	"Vitalink TransLAN III",
14550Sstevel@tonic-gate 0x080080,	"XIOS",
14560Sstevel@tonic-gate 0x080081,	"Crosfield Electronics",
14570Sstevel@tonic-gate 0x080086,	"Imagen/QMS",
14580Sstevel@tonic-gate 0x080087,	"Xyplex	terminal server",
14590Sstevel@tonic-gate 0x080089,	"Kinetics AppleTalk-Ethernet interface",
14600Sstevel@tonic-gate 0x08008B,	"Pyramid",
14610Sstevel@tonic-gate 0x08008D,	"XyVision",
14620Sstevel@tonic-gate 0x080090,	"Retix Inc Bridge",
14630Sstevel@tonic-gate 0x10005A,	"IBM",
14640Sstevel@tonic-gate 0x1000D4,	"DEC",
14650Sstevel@tonic-gate 0x400003,	"NetWare",
14660Sstevel@tonic-gate 0x800010,	"AT&T",
14670Sstevel@tonic-gate 0xAA0004,	"DEC (DECNET)",
14680Sstevel@tonic-gate 0xC00000,	"SMC",
14690Sstevel@tonic-gate 0,		"",
14700Sstevel@tonic-gate };
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate /*
14730Sstevel@tonic-gate  * The oui argument should be in host byte-order to conform with
14740Sstevel@tonic-gate  * the above array's values.
14750Sstevel@tonic-gate  */
14760Sstevel@tonic-gate char *
14770Sstevel@tonic-gate ether_ouiname(uint32_t oui)
14780Sstevel@tonic-gate {
14790Sstevel@tonic-gate 	uint_t i;
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate 	for (i = 0; ether_block[i].e_block != 0; i++)
14820Sstevel@tonic-gate 		if (oui == ether_block[i].e_block)
14830Sstevel@tonic-gate 			return (ether_block[i].e_name);
14840Sstevel@tonic-gate 
14850Sstevel@tonic-gate 	return (NULL);
14860Sstevel@tonic-gate }
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate /*
14890Sstevel@tonic-gate  * Print the additional Ethernet address info
14900Sstevel@tonic-gate  */
14910Sstevel@tonic-gate static char *
14920Sstevel@tonic-gate print_etherinfo(eaddr)
14930Sstevel@tonic-gate 	struct ether_addr *eaddr;
14940Sstevel@tonic-gate {
14950Sstevel@tonic-gate 	uint_t addr = 0;
14960Sstevel@tonic-gate 	char *p = (char *)&addr + 1;
14970Sstevel@tonic-gate 	char *ename;
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate 	(void) memcpy(p, eaddr, 3);
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 	if (memcmp(eaddr, &ether_broadcast, sizeof (struct ether_addr)) == 0)
15020Sstevel@tonic-gate 		return ("(broadcast)");
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate 	addr = ntohl(addr);	/* make it right for little-endians */
15050Sstevel@tonic-gate 	ename = ether_ouiname(addr);
15060Sstevel@tonic-gate 
15070Sstevel@tonic-gate 	if (ename != NULL)
15080Sstevel@tonic-gate 		return (ename);
15090Sstevel@tonic-gate 	else
1510*10491SRishi.Srivatsavai@Sun.COM 		return ((eaddr->ether_addr_octet[0] & 1) ? "(multicast)" : "");
15110Sstevel@tonic-gate }
15120Sstevel@tonic-gate 
15130Sstevel@tonic-gate static uchar_t	endianswap[] = {
15140Sstevel@tonic-gate 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
15150Sstevel@tonic-gate 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
15160Sstevel@tonic-gate 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
15170Sstevel@tonic-gate 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
15180Sstevel@tonic-gate 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
15190Sstevel@tonic-gate 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
15200Sstevel@tonic-gate 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
15210Sstevel@tonic-gate 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
15220Sstevel@tonic-gate 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
15230Sstevel@tonic-gate 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
15240Sstevel@tonic-gate 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
15250Sstevel@tonic-gate 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
15260Sstevel@tonic-gate 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
15270Sstevel@tonic-gate 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
15280Sstevel@tonic-gate 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
15290Sstevel@tonic-gate 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
15300Sstevel@tonic-gate 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
15310Sstevel@tonic-gate 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
15320Sstevel@tonic-gate 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
15330Sstevel@tonic-gate 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
15340Sstevel@tonic-gate 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
15350Sstevel@tonic-gate 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
15360Sstevel@tonic-gate 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
15370Sstevel@tonic-gate 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
15380Sstevel@tonic-gate 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
15390Sstevel@tonic-gate 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
15400Sstevel@tonic-gate 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
15410Sstevel@tonic-gate 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
15420Sstevel@tonic-gate 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
15430Sstevel@tonic-gate 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
15440Sstevel@tonic-gate 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
15450Sstevel@tonic-gate 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
15460Sstevel@tonic-gate };
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate static void
15490Sstevel@tonic-gate addr_copy_swap(pd, ps)
15500Sstevel@tonic-gate 	struct ether_addr	*pd;
15510Sstevel@tonic-gate 	struct ether_addr	*ps;
15520Sstevel@tonic-gate {
15530Sstevel@tonic-gate 	pd->ether_addr_octet[0] = endianswap[ps->ether_addr_octet[0]];
15540Sstevel@tonic-gate 	pd->ether_addr_octet[1] = endianswap[ps->ether_addr_octet[1]];
15550Sstevel@tonic-gate 	pd->ether_addr_octet[2] = endianswap[ps->ether_addr_octet[2]];
15560Sstevel@tonic-gate 	pd->ether_addr_octet[3] = endianswap[ps->ether_addr_octet[3]];
15570Sstevel@tonic-gate 	pd->ether_addr_octet[4] = endianswap[ps->ether_addr_octet[4]];
15580Sstevel@tonic-gate 	pd->ether_addr_octet[5] = endianswap[ps->ether_addr_octet[5]];
15590Sstevel@tonic-gate }
15600Sstevel@tonic-gate 
15610Sstevel@tonic-gate /* ARGSUSED */
15620Sstevel@tonic-gate uint_t
15630Sstevel@tonic-gate ib_header_len(char *hdr)
15640Sstevel@tonic-gate {
15650Sstevel@tonic-gate 	return (IPOIB_HDRSIZE);
15660Sstevel@tonic-gate }
15670Sstevel@tonic-gate 
15680Sstevel@tonic-gate static uint_t
15690Sstevel@tonic-gate interpret_ib(int flags, char *header, int elen, int origlen)
15700Sstevel@tonic-gate {
15710Sstevel@tonic-gate 	struct ipoib_header *hdr = (struct ipoib_header *)header;
15720Sstevel@tonic-gate 	char *off;
15730Sstevel@tonic-gate 	int len;
15740Sstevel@tonic-gate 	extern char *dst_name;
15750Sstevel@tonic-gate 	unsigned short ethertype;
15760Sstevel@tonic-gate 	int blen = MAX(origlen, 4096);
15770Sstevel@tonic-gate 
15780Sstevel@tonic-gate 	if (data != NULL && datalen != 0 && datalen < blen) {
15790Sstevel@tonic-gate 		free(data);
15800Sstevel@tonic-gate 		data = NULL;
15810Sstevel@tonic-gate 		datalen = 0;
15820Sstevel@tonic-gate 	}
15830Sstevel@tonic-gate 	if (data == NULL) {
15840Sstevel@tonic-gate 		data = malloc(blen);
15850Sstevel@tonic-gate 		if (data == NULL)
15860Sstevel@tonic-gate 			pr_err("Warning: malloc failure");
15870Sstevel@tonic-gate 		datalen = blen;
15880Sstevel@tonic-gate 	}
15890Sstevel@tonic-gate 	if (origlen < IPOIB_HDRSIZE) {
15900Sstevel@tonic-gate 		if (flags & F_SUM)
15910Sstevel@tonic-gate 			(void) snprintf(get_sum_line(), MAXLINE,
15928023SPhil.Kirk@Sun.COM 			    "RUNT (short packet - %d bytes)", origlen);
15930Sstevel@tonic-gate 		if (flags & F_DTAIL)
15940Sstevel@tonic-gate 			show_header("RUNT:  ", "Short packet", origlen);
15950Sstevel@tonic-gate 		return (elen);
15960Sstevel@tonic-gate 	}
15970Sstevel@tonic-gate 	if (elen < IPOIB_HDRSIZE)
15980Sstevel@tonic-gate 		return (elen);
15990Sstevel@tonic-gate 
16000Sstevel@tonic-gate 	/*
16010Sstevel@tonic-gate 	 * It is not possible to understand just by looking
16020Sstevel@tonic-gate 	 * at the header whether this was a broad/multi cast
16030Sstevel@tonic-gate 	 * packet; thus dst_name is not updated.
16040Sstevel@tonic-gate 	 */
16050Sstevel@tonic-gate 	ethertype = ntohs(hdr->ipoib_type);
16060Sstevel@tonic-gate 	len = elen - IPOIB_HDRSIZE;
16070Sstevel@tonic-gate 	off = (char *)(hdr + 1);
16080Sstevel@tonic-gate 	(void) memcpy(data, off, len);
16090Sstevel@tonic-gate 
16100Sstevel@tonic-gate 	if (flags & F_SUM) {
16110Sstevel@tonic-gate 		(void) snprintf(get_sum_line(), MAXLINE,
16128023SPhil.Kirk@Sun.COM 		    "IPIB Type=%04X (%s), size = %d bytes",
16138023SPhil.Kirk@Sun.COM 		    ethertype,
16148023SPhil.Kirk@Sun.COM 		    print_ethertype(ethertype),
16158023SPhil.Kirk@Sun.COM 		    origlen);
16160Sstevel@tonic-gate 	}
16170Sstevel@tonic-gate 
16180Sstevel@tonic-gate 	if (flags & F_DTAIL) {
16190Sstevel@tonic-gate 		show_header("IPIB:  ", "IPIB Header", elen);
16200Sstevel@tonic-gate 		show_space();
16210Sstevel@tonic-gate 		(void) snprintf(get_line(0, 0), get_line_remain(),
16228023SPhil.Kirk@Sun.COM 		    "Packet %d arrived at %d:%02d:%d.%02d",
16238023SPhil.Kirk@Sun.COM 		    pi_frame, pi_time_hour, pi_time_min,
16248023SPhil.Kirk@Sun.COM 		    pi_time_sec, pi_time_usec / 10000);
16250Sstevel@tonic-gate 		(void) snprintf(get_line(0, 0), get_line_remain(),
16268023SPhil.Kirk@Sun.COM 		    "Packet size = %d bytes", elen, elen);
16270Sstevel@tonic-gate 		(void) snprintf(get_line(0, 2), get_line_remain(),
16288023SPhil.Kirk@Sun.COM 		    "Ethertype = %04X (%s)", ethertype,
16298023SPhil.Kirk@Sun.COM 		    print_ethertype(ethertype));
16300Sstevel@tonic-gate 		show_space();
16310Sstevel@tonic-gate 	}
16320Sstevel@tonic-gate 
16330Sstevel@tonic-gate 	/* Go to the next protocol layer */
16340Sstevel@tonic-gate 	switch (ethertype) {
16350Sstevel@tonic-gate 		case ETHERTYPE_IP:
16360Sstevel@tonic-gate 			(void) interpret_ip(flags, (struct ip *)data, len);
16370Sstevel@tonic-gate 			break;
16380Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
16390Sstevel@tonic-gate 			(void) interpret_ipv6(flags, (ip6_t *)data, len);
16400Sstevel@tonic-gate 			break;
16410Sstevel@tonic-gate 		case ETHERTYPE_ARP:
16420Sstevel@tonic-gate 		case ETHERTYPE_REVARP:
16430Sstevel@tonic-gate 			interpret_arp(flags, (struct arphdr *)data, len);
16440Sstevel@tonic-gate 			break;
16450Sstevel@tonic-gate 	}
16460Sstevel@tonic-gate 
16470Sstevel@tonic-gate 	return (elen);
16480Sstevel@tonic-gate }
16498023SPhil.Kirk@Sun.COM 
16508023SPhil.Kirk@Sun.COM uint_t
16518023SPhil.Kirk@Sun.COM ipnet_header_len(char *hdr)
16528023SPhil.Kirk@Sun.COM {
16538023SPhil.Kirk@Sun.COM 	return (sizeof (dl_ipnetinfo_t));
16548023SPhil.Kirk@Sun.COM }
16558023SPhil.Kirk@Sun.COM 
16568023SPhil.Kirk@Sun.COM #define	MAX_UINT64_STR	22
16578023SPhil.Kirk@Sun.COM static uint_t
16588023SPhil.Kirk@Sun.COM interpret_ipnet(int flags, char *header, int elen, int origlen)
16598023SPhil.Kirk@Sun.COM {
16608023SPhil.Kirk@Sun.COM 	dl_ipnetinfo_t dl;
16618023SPhil.Kirk@Sun.COM 	size_t len = elen - sizeof (dl_ipnetinfo_t);
16628023SPhil.Kirk@Sun.COM 	char *off = (char *)header + sizeof (dl_ipnetinfo_t);
16638023SPhil.Kirk@Sun.COM 	int blen = MAX(origlen, 8252);
16648023SPhil.Kirk@Sun.COM 	char szone[MAX_UINT64_STR];
16658023SPhil.Kirk@Sun.COM 	char dzone[MAX_UINT64_STR];
16668023SPhil.Kirk@Sun.COM 
16678023SPhil.Kirk@Sun.COM 	(void) memcpy(&dl, header, sizeof (dl));
16688023SPhil.Kirk@Sun.COM 	if (data != NULL && datalen != 0 && datalen < blen) {
16698023SPhil.Kirk@Sun.COM 		free(data);
16708023SPhil.Kirk@Sun.COM 		data = NULL;
16718023SPhil.Kirk@Sun.COM 		datalen = 0;
16728023SPhil.Kirk@Sun.COM 	}
16738023SPhil.Kirk@Sun.COM 	if (data == NULL) {
16748023SPhil.Kirk@Sun.COM 		data = (char *)malloc(blen);
16758023SPhil.Kirk@Sun.COM 		if (!data)
16768023SPhil.Kirk@Sun.COM 			pr_err("Warning: malloc failure");
16778023SPhil.Kirk@Sun.COM 		datalen = blen;
16788023SPhil.Kirk@Sun.COM 	}
16798023SPhil.Kirk@Sun.COM 
16808023SPhil.Kirk@Sun.COM 	if (dl.dli_srczone == ALL_ZONES)
16818023SPhil.Kirk@Sun.COM 		sprintf(szone, "Unknown");
16828023SPhil.Kirk@Sun.COM 	else
16838023SPhil.Kirk@Sun.COM 		sprintf(szone, "%llu", BE_64(dl.dli_srczone));
16848023SPhil.Kirk@Sun.COM 
16858023SPhil.Kirk@Sun.COM 	if (dl.dli_dstzone == ALL_ZONES)
16868023SPhil.Kirk@Sun.COM 		sprintf(dzone, "Unknown");
16878023SPhil.Kirk@Sun.COM 	else
16888023SPhil.Kirk@Sun.COM 		sprintf(dzone, "%llu", BE_64(dl.dli_dstzone));
16898023SPhil.Kirk@Sun.COM 
16908023SPhil.Kirk@Sun.COM 	if (flags & F_SUM) {
16918023SPhil.Kirk@Sun.COM 		(void) snprintf(get_sum_line(), MAXLINE,
16928023SPhil.Kirk@Sun.COM 		    "IPNET src zone %s dst zone %s", szone, dzone);
16938023SPhil.Kirk@Sun.COM 	}
16948023SPhil.Kirk@Sun.COM 
16958023SPhil.Kirk@Sun.COM 	if (flags & F_DTAIL) {
16968023SPhil.Kirk@Sun.COM 		show_header("IPNET:  ", "IPNET Header", elen);
16978023SPhil.Kirk@Sun.COM 		show_space();
16988023SPhil.Kirk@Sun.COM 		(void) sprintf(get_line(0, 0),
16998023SPhil.Kirk@Sun.COM 		    "Packet %d arrived at %d:%02d:%d.%05d",
17008023SPhil.Kirk@Sun.COM 		    pi_frame,
17018023SPhil.Kirk@Sun.COM 		    pi_time_hour, pi_time_min, pi_time_sec,
17028023SPhil.Kirk@Sun.COM 		    pi_time_usec / 10);
17038023SPhil.Kirk@Sun.COM 		(void) sprintf(get_line(0, 0),
17048023SPhil.Kirk@Sun.COM 		    "Packet size = %d bytes",
17058023SPhil.Kirk@Sun.COM 		    elen);
17068023SPhil.Kirk@Sun.COM 		(void) snprintf(get_line(0, 0), get_line_remain(),
17078023SPhil.Kirk@Sun.COM 		    "dli_version = %d", dl.dli_version);
17088023SPhil.Kirk@Sun.COM 		(void) snprintf(get_line(0, 0), get_line_remain(),
17098023SPhil.Kirk@Sun.COM 		    "dli_type = %d", dl.dli_ipver);
17108023SPhil.Kirk@Sun.COM 		(void) snprintf(get_line(0, 2), get_line_remain(),
17118023SPhil.Kirk@Sun.COM 		    "dli_srczone = %s", szone);
17128023SPhil.Kirk@Sun.COM 		(void) snprintf(get_line(0, 2), get_line_remain(),
17138023SPhil.Kirk@Sun.COM 		    "dli_dstzone = %s", dzone);
17148023SPhil.Kirk@Sun.COM 		show_space();
17158023SPhil.Kirk@Sun.COM 	}
17168023SPhil.Kirk@Sun.COM 	memcpy(data, off, len);
17178023SPhil.Kirk@Sun.COM 
17188023SPhil.Kirk@Sun.COM 	switch (dl.dli_ipver) {
17198023SPhil.Kirk@Sun.COM 	case IPV4_VERSION:
17208023SPhil.Kirk@Sun.COM 		(void) interpret_ip(flags, (struct ip *)data, len);
17218023SPhil.Kirk@Sun.COM 		break;
17228023SPhil.Kirk@Sun.COM 	case IPV6_VERSION:
17238023SPhil.Kirk@Sun.COM 		(void) interpret_ipv6(flags, (ip6_t *)data, len);
17248023SPhil.Kirk@Sun.COM 		break;
17258023SPhil.Kirk@Sun.COM 	default:
17268023SPhil.Kirk@Sun.COM 		break;
17278023SPhil.Kirk@Sun.COM 	}
17288023SPhil.Kirk@Sun.COM 
17298023SPhil.Kirk@Sun.COM 	return (0);
17308023SPhil.Kirk@Sun.COM }
1731