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 /* 2210491SRishi.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> 45*10616SSebastien.Roy@Sun.COM #include <inet/iptun.h> 468023SPhil.Kirk@Sun.COM #include <sys/byteorder.h> 478023SPhil.Kirk@Sun.COM #include <limits.h> 488023SPhil.Kirk@Sun.COM #include <inet/ip.h> 498023SPhil.Kirk@Sun.COM #include <inet/ip6.h> 5010491SRishi.Srivatsavai@Sun.COM #include <net/trill.h> 510Sstevel@tonic-gate 520Sstevel@tonic-gate #include "at.h" 530Sstevel@tonic-gate #include "snoop.h" 540Sstevel@tonic-gate 55*10616SSebastien.Roy@Sun.COM static headerlen_fn_t ether_header_len, fddi_header_len, tr_header_len, 56*10616SSebastien.Roy@Sun.COM ib_header_len, ipnet_header_len, ipv4_header_len, ipv6_header_len; 57*10616SSebastien.Roy@Sun.COM static interpreter_fn_t interpret_ether, interpret_fddi, interpret_tr, 58*10616SSebastien.Roy@Sun.COM interpret_ib, interpret_ipnet, interpret_iptun; 590Sstevel@tonic-gate static void addr_copy_swap(struct ether_addr *, struct ether_addr *); 60*10616SSebastien.Roy@Sun.COM static int tr_machdr_len(char *, int *, int *); 610Sstevel@tonic-gate 620Sstevel@tonic-gate interface_t *interface; 630Sstevel@tonic-gate interface_t INTERFACES[] = { 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* IEEE 802.3 CSMA/CD network */ 668023SPhil.Kirk@Sun.COM { DL_CSMACD, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6, 678023SPhil.Kirk@Sun.COM ether_header_len, interpret_ether, B_TRUE }, 680Sstevel@tonic-gate 690Sstevel@tonic-gate /* Ethernet Bus */ 708023SPhil.Kirk@Sun.COM { DL_ETHER, 1550, 12, 2, ETHERTYPE_IP, ETHERTYPE_IPV6, 718023SPhil.Kirk@Sun.COM ether_header_len, interpret_ether, B_TRUE }, 720Sstevel@tonic-gate 730Sstevel@tonic-gate /* Fiber Distributed data interface */ 748023SPhil.Kirk@Sun.COM { DL_FDDI, 4500, 19, 2, ETHERTYPE_IP, ETHERTYPE_IPV6, 758023SPhil.Kirk@Sun.COM fddi_header_len, interpret_fddi, B_FALSE }, 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* Token Ring interface */ 788023SPhil.Kirk@Sun.COM { DL_TPR, 17800, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6, 798023SPhil.Kirk@Sun.COM tr_header_len, interpret_tr, B_FALSE }, 800Sstevel@tonic-gate 810Sstevel@tonic-gate /* Infiniband */ 828023SPhil.Kirk@Sun.COM { DL_IB, 4096, 0, 2, ETHERTYPE_IP, ETHERTYPE_IPV6, 838023SPhil.Kirk@Sun.COM ib_header_len, interpret_ib, B_TRUE }, 840Sstevel@tonic-gate 858023SPhil.Kirk@Sun.COM /* ipnet */ 868105SSebastien.Roy@Sun.COM { DL_IPNET, INT_MAX, 1, 1, IPV4_VERSION, IPV6_VERSION, 878023SPhil.Kirk@Sun.COM ipnet_header_len, interpret_ipnet, B_TRUE }, 880Sstevel@tonic-gate 89*10616SSebastien.Roy@Sun.COM /* IPv4 tunnel */ 90*10616SSebastien.Roy@Sun.COM { DL_IPV4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6, 91*10616SSebastien.Roy@Sun.COM ipv4_header_len, interpret_iptun, B_FALSE }, 92*10616SSebastien.Roy@Sun.COM 93*10616SSebastien.Roy@Sun.COM /* IPv6 tunnel */ 94*10616SSebastien.Roy@Sun.COM { DL_IPV6, 0, 40, 1, IPPROTO_ENCAP, IPPROTO_IPV6, 95*10616SSebastien.Roy@Sun.COM ipv6_header_len, interpret_iptun, B_FALSE }, 96*10616SSebastien.Roy@Sun.COM 97*10616SSebastien.Roy@Sun.COM /* 6to4 tunnel */ 98*10616SSebastien.Roy@Sun.COM { DL_6TO4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6, 99*10616SSebastien.Roy@Sun.COM ipv4_header_len, interpret_iptun, B_FALSE }, 100*10616SSebastien.Roy@Sun.COM 1018023SPhil.Kirk@Sun.COM { (uint_t)-1, 0, 0, 0, 0, NULL, NULL, B_FALSE } 1020Sstevel@tonic-gate }; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* externals */ 1050Sstevel@tonic-gate extern char *dlc_header; 1060Sstevel@tonic-gate extern int pi_frame; 1070Sstevel@tonic-gate extern int pi_time_hour; 1080Sstevel@tonic-gate extern int pi_time_min; 1090Sstevel@tonic-gate extern int pi_time_sec; 1100Sstevel@tonic-gate extern int pi_time_usec; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate char *printether(); 1130Sstevel@tonic-gate char *print_ethertype(); 1140Sstevel@tonic-gate static char *print_etherinfo(); 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate char *print_fc(); 1170Sstevel@tonic-gate char *print_smttype(); 1180Sstevel@tonic-gate char *print_smtclass(); 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate struct ether_addr ether_broadcast = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 1210Sstevel@tonic-gate static char *data; /* current data buffer */ 1220Sstevel@tonic-gate static int datalen; /* current data buffer length */ 12310491SRishi.Srivatsavai@Sun.COM static const struct ether_addr all_isis_rbridges = ALL_ISIS_RBRIDGES; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate uint_t 126*10616SSebastien.Roy@Sun.COM interpret_ether(int flags, char *header, int elen, int origlen) 1270Sstevel@tonic-gate { 128*10616SSebastien.Roy@Sun.COM struct ether_header *e = (struct ether_header *)header; 12910491SRishi.Srivatsavai@Sun.COM uchar_t *off, *ieeestart; 1300Sstevel@tonic-gate int len; 1310Sstevel@tonic-gate int ieee8023 = 0; 1320Sstevel@tonic-gate extern char *dst_name; 1330Sstevel@tonic-gate int ethertype; 1342760Sdg199075 struct ether_vlan_extinfo *evx = NULL; 1350Sstevel@tonic-gate int blen = MAX(origlen, ETHERMTU); 13610491SRishi.Srivatsavai@Sun.COM boolean_t trillpkt = B_FALSE; 13710491SRishi.Srivatsavai@Sun.COM uint16_t tci = 0; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate if (data != NULL && datalen != 0 && datalen < blen) { 1400Sstevel@tonic-gate free(data); 1410Sstevel@tonic-gate data = NULL; 1420Sstevel@tonic-gate datalen = 0; 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate if (!data) { 1450Sstevel@tonic-gate data = (char *)malloc(blen); 1460Sstevel@tonic-gate if (!data) 1470Sstevel@tonic-gate pr_err("Warning: malloc failure"); 1480Sstevel@tonic-gate datalen = blen; 1490Sstevel@tonic-gate } 15010491SRishi.Srivatsavai@Sun.COM inner_pkt: 1510Sstevel@tonic-gate if (origlen < 14) { 152*10616SSebastien.Roy@Sun.COM if (flags & F_SUM) { 1530Sstevel@tonic-gate (void) sprintf(get_sum_line(), 154*10616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)", 155*10616SSebastien.Roy@Sun.COM origlen); 156*10616SSebastien.Roy@Sun.COM } 1570Sstevel@tonic-gate if (flags & F_DTAIL) 1580Sstevel@tonic-gate show_header("RUNT: ", "Short packet", origlen); 1590Sstevel@tonic-gate return (elen); 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate if (elen < 14) 1620Sstevel@tonic-gate return (elen); 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate if (memcmp(&e->ether_dhost, ðer_broadcast, 1650Sstevel@tonic-gate sizeof (struct ether_addr)) == 0) 1660Sstevel@tonic-gate dst_name = "(broadcast)"; 1670Sstevel@tonic-gate else if (e->ether_dhost.ether_addr_octet[0] & 1) 1680Sstevel@tonic-gate dst_name = "(multicast)"; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate ethertype = ntohs(e->ether_type); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate /* 1730Sstevel@tonic-gate * The 14 byte ether header screws up alignment 1740Sstevel@tonic-gate * of the rest of the packet for 32 bit aligned 1750Sstevel@tonic-gate * architectures like SPARC. Alas, we have to copy 1760Sstevel@tonic-gate * the rest of the packet in order to align it. 1770Sstevel@tonic-gate */ 1780Sstevel@tonic-gate len = elen - sizeof (struct ether_header); 17910491SRishi.Srivatsavai@Sun.COM off = (uchar_t *)(e + 1); 1800Sstevel@tonic-gate 1812760Sdg199075 if (ethertype == ETHERTYPE_VLAN) { 1822760Sdg199075 if (origlen < sizeof (struct ether_vlan_header)) { 1832760Sdg199075 if (flags & F_SUM) { 1842760Sdg199075 (void) sprintf(get_sum_line(), 1852760Sdg199075 "RUNT (short VLAN packet - %d bytes)", 1862760Sdg199075 origlen); 1872760Sdg199075 } 1882760Sdg199075 if (flags & F_DTAIL) { 1892760Sdg199075 show_header("RUNT: ", "Short VLAN packet", 1902760Sdg199075 origlen); 1912760Sdg199075 } 1922760Sdg199075 return (elen); 1932760Sdg199075 } 1942760Sdg199075 if (len < sizeof (struct ether_vlan_extinfo)) 1952760Sdg199075 return (elen); 1962760Sdg199075 1972760Sdg199075 evx = (struct ether_vlan_extinfo *)off; 1982760Sdg199075 off += sizeof (struct ether_vlan_extinfo); 1992760Sdg199075 len -= sizeof (struct ether_vlan_extinfo); 2002760Sdg199075 2012760Sdg199075 ethertype = ntohs(evx->ether_type); 20210491SRishi.Srivatsavai@Sun.COM tci = ntohs(evx->ether_tci); 2032760Sdg199075 } 2042760Sdg199075 20510491SRishi.Srivatsavai@Sun.COM if (ethertype <= 1514) { 20610491SRishi.Srivatsavai@Sun.COM /* 20710491SRishi.Srivatsavai@Sun.COM * Fake out the IEEE 802.3 packets. 20810491SRishi.Srivatsavai@Sun.COM * Should be DSAP=0xAA, SSAP=0xAA, control=0x03 20910491SRishi.Srivatsavai@Sun.COM * then three padding bytes of zero (OUI), 21010491SRishi.Srivatsavai@Sun.COM * followed by a normal ethernet-type packet. 21110491SRishi.Srivatsavai@Sun.COM */ 21210491SRishi.Srivatsavai@Sun.COM ieee8023 = ethertype; 21310491SRishi.Srivatsavai@Sun.COM ieeestart = off; 21410491SRishi.Srivatsavai@Sun.COM if (off[0] == 0xAA && off[1] == 0xAA) { 21510491SRishi.Srivatsavai@Sun.COM ethertype = ntohs(*(ushort_t *)(off + 6)); 21610491SRishi.Srivatsavai@Sun.COM off += 8; 21710491SRishi.Srivatsavai@Sun.COM len -= 8; 21810491SRishi.Srivatsavai@Sun.COM } else { 21910491SRishi.Srivatsavai@Sun.COM ethertype = 0; 22010491SRishi.Srivatsavai@Sun.COM off += 3; 22110491SRishi.Srivatsavai@Sun.COM len -= 3; 22210491SRishi.Srivatsavai@Sun.COM } 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if (flags & F_SUM) { 2262760Sdg199075 /* 2272760Sdg199075 * Set the flag that says don't display VLAN information. 2282760Sdg199075 * If it needs to change, that will be done later if the 2292760Sdg199075 * packet is VLAN tagged and if snoop is in its default 2302760Sdg199075 * summary mode. 2312760Sdg199075 */ 2322760Sdg199075 set_vlan_id(0); 2332760Sdg199075 if (evx == NULL) { 23410491SRishi.Srivatsavai@Sun.COM if (ethertype == 0 && ieee8023 > 0) { 23510491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_sum_line(), 23610491SRishi.Srivatsavai@Sun.COM "ETHER 802.3 SSAP %02X DSAP %02X, " 23710491SRishi.Srivatsavai@Sun.COM "size=%d bytes", ieeestart[0], ieeestart[1], 23810491SRishi.Srivatsavai@Sun.COM origlen); 23910491SRishi.Srivatsavai@Sun.COM } else { 24010491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_sum_line(), 24110491SRishi.Srivatsavai@Sun.COM "ETHER Type=%04X (%s), size=%d bytes", 24210491SRishi.Srivatsavai@Sun.COM ethertype, print_ethertype(ethertype), 24310491SRishi.Srivatsavai@Sun.COM origlen); 24410491SRishi.Srivatsavai@Sun.COM } 2452760Sdg199075 } else { 24610491SRishi.Srivatsavai@Sun.COM if (ethertype == 0 && ieee8023 > 0) { 24710491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_sum_line(), 24810491SRishi.Srivatsavai@Sun.COM "ETHER 802.3 SSAP %02X DSAP %02X, " 24910491SRishi.Srivatsavai@Sun.COM "VLAN ID=%hu, size=%d bytes", ieeestart[0], 25010491SRishi.Srivatsavai@Sun.COM ieeestart[1], VLAN_ID(tci), origlen); 25110491SRishi.Srivatsavai@Sun.COM } else { 25210491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_sum_line(), 25310491SRishi.Srivatsavai@Sun.COM "ETHER Type=%04X (%s), VLAN ID=%hu, " 25410491SRishi.Srivatsavai@Sun.COM "size=%d bytes", ethertype, 25510491SRishi.Srivatsavai@Sun.COM print_ethertype(ethertype), VLAN_ID(tci), 25610491SRishi.Srivatsavai@Sun.COM origlen); 25710491SRishi.Srivatsavai@Sun.COM } 2582760Sdg199075 2592760Sdg199075 if (!(flags & F_ALLSUM)) 26010491SRishi.Srivatsavai@Sun.COM set_vlan_id(VLAN_ID(tci)); 2612760Sdg199075 } 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if (flags & F_DTAIL) { 26510491SRishi.Srivatsavai@Sun.COM show_header("ETHER: ", "Ether Header", elen); 26610491SRishi.Srivatsavai@Sun.COM show_space(); 26710491SRishi.Srivatsavai@Sun.COM if (!trillpkt) { 26810491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(0, 0), 26910491SRishi.Srivatsavai@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d", 27010491SRishi.Srivatsavai@Sun.COM pi_frame, 27110491SRishi.Srivatsavai@Sun.COM pi_time_hour, pi_time_min, pi_time_sec, 27210491SRishi.Srivatsavai@Sun.COM pi_time_usec / 10); 27310491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(0, 0), 27410491SRishi.Srivatsavai@Sun.COM "Packet size = %d bytes", 27510491SRishi.Srivatsavai@Sun.COM elen, elen); 27610491SRishi.Srivatsavai@Sun.COM } 27710491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(0, 6), 27810491SRishi.Srivatsavai@Sun.COM "Destination = %s, %s", 27910491SRishi.Srivatsavai@Sun.COM printether(&e->ether_dhost), 28010491SRishi.Srivatsavai@Sun.COM print_etherinfo(&e->ether_dhost)); 28110491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(6, 6), 28210491SRishi.Srivatsavai@Sun.COM "Source = %s, %s", 28310491SRishi.Srivatsavai@Sun.COM printether(&e->ether_shost), 28410491SRishi.Srivatsavai@Sun.COM print_etherinfo(&e->ether_shost)); 28510491SRishi.Srivatsavai@Sun.COM if (evx != NULL) { 28610491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(0, 0), 28710491SRishi.Srivatsavai@Sun.COM "VLAN ID = %hu", VLAN_ID(tci)); 28810491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(0, 0), 28910491SRishi.Srivatsavai@Sun.COM "VLAN Priority = %hu", VLAN_PRI(tci)); 29010491SRishi.Srivatsavai@Sun.COM } 29110491SRishi.Srivatsavai@Sun.COM if (ieee8023 > 0) { 29210491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(12, 2), 29310491SRishi.Srivatsavai@Sun.COM "IEEE 802.3 length = %d bytes", ieee8023); 29410491SRishi.Srivatsavai@Sun.COM /* Print LLC only for non-TCP/IP packets */ 29510491SRishi.Srivatsavai@Sun.COM if (ethertype == 0) { 29610491SRishi.Srivatsavai@Sun.COM (void) snprintf(get_line(0, 0), 29710491SRishi.Srivatsavai@Sun.COM get_line_remain(), 29810491SRishi.Srivatsavai@Sun.COM "SSAP = %02X, DSAP = %02X, CTRL = %02X", 29910491SRishi.Srivatsavai@Sun.COM ieeestart[0], ieeestart[1], ieeestart[2]); 30010491SRishi.Srivatsavai@Sun.COM } 30110491SRishi.Srivatsavai@Sun.COM } 30210491SRishi.Srivatsavai@Sun.COM if (ethertype != 0 || ieee8023 == 0) 30310491SRishi.Srivatsavai@Sun.COM (void) sprintf(get_line(12, 2), 30410491SRishi.Srivatsavai@Sun.COM "Ethertype = %04X (%s)", 30510491SRishi.Srivatsavai@Sun.COM ethertype, print_ethertype(ethertype)); 30610491SRishi.Srivatsavai@Sun.COM show_space(); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate 30910491SRishi.Srivatsavai@Sun.COM /* 31010491SRishi.Srivatsavai@Sun.COM * We cannot trust the length field in the header to be correct. 31110491SRishi.Srivatsavai@Sun.COM * But we should continue to process the packet. Then user can 31210491SRishi.Srivatsavai@Sun.COM * notice something funny in the header. 31310491SRishi.Srivatsavai@Sun.COM * Go to the next protocol layer only if data have been 31410491SRishi.Srivatsavai@Sun.COM * copied. 31510491SRishi.Srivatsavai@Sun.COM */ 31610491SRishi.Srivatsavai@Sun.COM if (len > 0 && (off + len <= (uchar_t *)e + elen)) { 31710491SRishi.Srivatsavai@Sun.COM (void) memmove(data, off, len); 31810491SRishi.Srivatsavai@Sun.COM 31910491SRishi.Srivatsavai@Sun.COM if (!trillpkt && ethertype == ETHERTYPE_TRILL) { 32010491SRishi.Srivatsavai@Sun.COM ethertype = interpret_trill(flags, &e, data, &len); 32110491SRishi.Srivatsavai@Sun.COM /* Decode inner Ethernet frame */ 32210491SRishi.Srivatsavai@Sun.COM if (ethertype != 0) { 32310491SRishi.Srivatsavai@Sun.COM evx = NULL; 32410491SRishi.Srivatsavai@Sun.COM trillpkt = B_TRUE; 32510491SRishi.Srivatsavai@Sun.COM (void) memmove(data, e, len); 32610491SRishi.Srivatsavai@Sun.COM e = (struct ether_header *)data; 32710491SRishi.Srivatsavai@Sun.COM origlen = len; 32810491SRishi.Srivatsavai@Sun.COM elen = len; 32910491SRishi.Srivatsavai@Sun.COM goto inner_pkt; 33010491SRishi.Srivatsavai@Sun.COM } 33110491SRishi.Srivatsavai@Sun.COM } 33210491SRishi.Srivatsavai@Sun.COM 3330Sstevel@tonic-gate switch (ethertype) { 3340Sstevel@tonic-gate case ETHERTYPE_IP: 3350Sstevel@tonic-gate (void) interpret_ip(flags, (struct ip *)data, len); 3360Sstevel@tonic-gate break; 3370Sstevel@tonic-gate /* Just in case it is decided to add this type */ 3380Sstevel@tonic-gate case ETHERTYPE_IPV6: 3390Sstevel@tonic-gate (void) interpret_ipv6(flags, (ip6_t *)data, len); 3400Sstevel@tonic-gate break; 3410Sstevel@tonic-gate case ETHERTYPE_ARP: 3420Sstevel@tonic-gate case ETHERTYPE_REVARP: 3430Sstevel@tonic-gate interpret_arp(flags, (struct arphdr *)data, len); 3440Sstevel@tonic-gate break; 3450Sstevel@tonic-gate case ETHERTYPE_PPPOED: 3460Sstevel@tonic-gate case ETHERTYPE_PPPOES: 3470Sstevel@tonic-gate (void) interpret_pppoe(flags, (poep_t *)data, len); 3480Sstevel@tonic-gate break; 3490Sstevel@tonic-gate case ETHERTYPE_AARP: /* AppleTalk */ 3500Sstevel@tonic-gate interpret_aarp(flags, data, len); 3510Sstevel@tonic-gate break; 3520Sstevel@tonic-gate case ETHERTYPE_AT: 3530Sstevel@tonic-gate interpret_at(flags, (struct ddp_hdr *)data, len); 3540Sstevel@tonic-gate break; 35510491SRishi.Srivatsavai@Sun.COM case 0: 35610491SRishi.Srivatsavai@Sun.COM if (ieee8023 == 0) 35710491SRishi.Srivatsavai@Sun.COM break; 35810491SRishi.Srivatsavai@Sun.COM switch (ieeestart[0]) { 35910491SRishi.Srivatsavai@Sun.COM case 0xFE: 36010491SRishi.Srivatsavai@Sun.COM interpret_isis(flags, data, len, 36110491SRishi.Srivatsavai@Sun.COM memcmp(&e->ether_dhost, &all_isis_rbridges, 36210491SRishi.Srivatsavai@Sun.COM sizeof (struct ether_addr)) == 0); 36310491SRishi.Srivatsavai@Sun.COM break; 36410491SRishi.Srivatsavai@Sun.COM case 0x42: 36510491SRishi.Srivatsavai@Sun.COM interpret_bpdu(flags, data, len); 36610491SRishi.Srivatsavai@Sun.COM break; 36710491SRishi.Srivatsavai@Sun.COM } 3680Sstevel@tonic-gate break; 3690Sstevel@tonic-gate } 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate return (elen); 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate 3752760Sdg199075 /* 3762760Sdg199075 * Return the length of the ethernet header. In the case 3772760Sdg199075 * where we have a VLAN tagged packet, return the length of 3782760Sdg199075 * the ethernet header plus the length of the VLAN tag. 3792760Sdg199075 * 3802760Sdg199075 * INPUTS: e - A buffer pointer. Passing a NULL pointer 3812760Sdg199075 * is not allowed, e must be non-NULL. 3822760Sdg199075 * OUTPUTS: Return the size of an untagged ethernet header 3832760Sdg199075 * if the packet is not VLAN tagged, and the size 3842760Sdg199075 * of an untagged ethernet header plus the size of 3852760Sdg199075 * a VLAN header otherwise. 3862760Sdg199075 */ 3870Sstevel@tonic-gate uint_t 388*10616SSebastien.Roy@Sun.COM ether_header_len(char *e, size_t msgsize) 3890Sstevel@tonic-gate { 3902760Sdg199075 uint16_t ether_type = 0; 391*10616SSebastien.Roy@Sun.COM 392*10616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct ether_header)) 393*10616SSebastien.Roy@Sun.COM return (0); 394*10616SSebastien.Roy@Sun.COM 3952760Sdg199075 e += (offsetof(struct ether_header, ether_type)); 3962760Sdg199075 3972760Sdg199075 GETINT16(ether_type, e); 3982760Sdg199075 3992760Sdg199075 if (ether_type == (uint16_t)ETHERTYPE_VLAN) { 4002760Sdg199075 return (sizeof (struct ether_vlan_header)); 4012760Sdg199075 } else { 4022760Sdg199075 return (sizeof (struct ether_header)); 4032760Sdg199075 } 4040Sstevel@tonic-gate } 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * Table of Ethertypes. 4090Sstevel@tonic-gate * Some of the more popular entries 4100Sstevel@tonic-gate * are at the beginning of the table 4110Sstevel@tonic-gate * to reduce search time. 4120Sstevel@tonic-gate */ 4130Sstevel@tonic-gate struct ether_type { 4140Sstevel@tonic-gate int e_type; 4150Sstevel@tonic-gate char *e_name; 4160Sstevel@tonic-gate } ether_type [] = { 4170Sstevel@tonic-gate ETHERTYPE_IP, "IP", 4180Sstevel@tonic-gate ETHERTYPE_ARP, "ARP", 4190Sstevel@tonic-gate ETHERTYPE_REVARP, "RARP", 4200Sstevel@tonic-gate ETHERTYPE_IPV6, "IPv6", 4210Sstevel@tonic-gate ETHERTYPE_PPPOED, "PPPoE Discovery", 4220Sstevel@tonic-gate ETHERTYPE_PPPOES, "PPPoE Session", 42310491SRishi.Srivatsavai@Sun.COM ETHERTYPE_TRILL, "TRILL", 4240Sstevel@tonic-gate /* end of popular entries */ 4250Sstevel@tonic-gate ETHERTYPE_PUP, "Xerox PUP", 4260Sstevel@tonic-gate 0x0201, "Xerox PUP", 4270Sstevel@tonic-gate 0x0400, "Nixdorf", 4280Sstevel@tonic-gate 0x0600, "Xerox NS IDP", 4290Sstevel@tonic-gate 0x0601, "XNS Translation", 4300Sstevel@tonic-gate 0x0801, "X.75 Internet", 4310Sstevel@tonic-gate 0x0802, "NBS Internet", 4320Sstevel@tonic-gate 0x0803, "ECMA Internet", 4330Sstevel@tonic-gate 0x0804, "CHAOSnet", 4340Sstevel@tonic-gate 0x0805, "X.25 Level 3", 4350Sstevel@tonic-gate 0x0807, "XNS Compatibility", 4360Sstevel@tonic-gate 0x081C, "Symbolics Private", 4370Sstevel@tonic-gate 0x0888, "Xyplex", 4380Sstevel@tonic-gate 0x0889, "Xyplex", 4390Sstevel@tonic-gate 0x088A, "Xyplex", 4400Sstevel@tonic-gate 0x0900, "Ungermann-Bass network debugger", 4410Sstevel@tonic-gate 0x0A00, "Xerox IEEE802.3 PUP", 4420Sstevel@tonic-gate 0x0A01, "Xerox IEEE802.3 PUP Address Translation", 4430Sstevel@tonic-gate 0x0BAD, "Banyan Systems", 4440Sstevel@tonic-gate 0x0BAF, "Banyon VINES Echo", 4450Sstevel@tonic-gate 0x1000, "Berkeley Trailer negotiation", 4460Sstevel@tonic-gate 0x1000, "IP trailer (0)", 4470Sstevel@tonic-gate 0x1001, "IP trailer (1)", 4480Sstevel@tonic-gate 0x1002, "IP trailer (2)", 4490Sstevel@tonic-gate 0x1003, "IP trailer (3)", 4500Sstevel@tonic-gate 0x1004, "IP trailer (4)", 4510Sstevel@tonic-gate 0x1005, "IP trailer (5)", 4520Sstevel@tonic-gate 0x1006, "IP trailer (6)", 4530Sstevel@tonic-gate 0x1007, "IP trailer (7)", 4540Sstevel@tonic-gate 0x1008, "IP trailer (8)", 4550Sstevel@tonic-gate 0x1009, "IP trailer (9)", 4560Sstevel@tonic-gate 0x100a, "IP trailer (10)", 4570Sstevel@tonic-gate 0x100b, "IP trailer (11)", 4580Sstevel@tonic-gate 0x100c, "IP trailer (12)", 4590Sstevel@tonic-gate 0x100d, "IP trailer (13)", 4600Sstevel@tonic-gate 0x100e, "IP trailer (14)", 4610Sstevel@tonic-gate 0x100f, "IP trailer (15)", 4620Sstevel@tonic-gate 0x1234, "DCA - Multicast", 4630Sstevel@tonic-gate 0x1600, "VALID system protocol", 4640Sstevel@tonic-gate 0x1989, "Aviator", 4650Sstevel@tonic-gate 0x3C00, "3Com NBP virtual circuit datagram", 4660Sstevel@tonic-gate 0x3C01, "3Com NBP System control datagram", 4670Sstevel@tonic-gate 0x3C02, "3Com NBP Connect request (virtual cct)", 4680Sstevel@tonic-gate 0x3C03, "3Com NBP Connect response", 4690Sstevel@tonic-gate 0x3C04, "3Com NBP Connect complete", 4700Sstevel@tonic-gate 0x3C05, "3Com NBP Close request (virtual cct)", 4710Sstevel@tonic-gate 0x3C06, "3Com NBP Close response", 4720Sstevel@tonic-gate 0x3C07, "3Com NBP Datagram (like XNS IDP)", 4730Sstevel@tonic-gate 0x3C08, "3Com NBP Datagram broadcast", 4740Sstevel@tonic-gate 0x3C09, "3Com NBP Claim NetBIOS name", 4750Sstevel@tonic-gate 0x3C0A, "3Com NBP Delete Netbios name", 4760Sstevel@tonic-gate 0x3C0B, "3Com NBP Remote adaptor status request", 4770Sstevel@tonic-gate 0x3C0C, "3Com NBP Remote adaptor response", 4780Sstevel@tonic-gate 0x3C0D, "3Com NBP Reset", 4790Sstevel@tonic-gate 0x4242, "PCS Basic Block Protocol", 4800Sstevel@tonic-gate 0x4321, "THD - Diddle", 4810Sstevel@tonic-gate 0x5208, "BBN Simnet Private", 4820Sstevel@tonic-gate 0x6000, "DEC unass, experimental", 4830Sstevel@tonic-gate 0x6001, "DEC Dump/Load", 4840Sstevel@tonic-gate 0x6002, "DEC Remote Console", 4850Sstevel@tonic-gate 0x6003, "DECNET Phase IV, DNA Routing", 4860Sstevel@tonic-gate 0x6004, "DEC LAT", 4870Sstevel@tonic-gate 0x6005, "DEC Diagnostic", 4880Sstevel@tonic-gate 0x6006, "DEC customer protocol", 4890Sstevel@tonic-gate 0x6007, "DEC Local Area VAX Cluster (LAVC)", 4900Sstevel@tonic-gate 0x6008, "DEC unass (AMBER?)", 4910Sstevel@tonic-gate 0x6009, "DEC unass (MUMPS?)", 4920Sstevel@tonic-gate 0x6010, "3Com", 4930Sstevel@tonic-gate 0x6011, "3Com", 4940Sstevel@tonic-gate 0x6012, "3Com", 4950Sstevel@tonic-gate 0x6013, "3Com", 4960Sstevel@tonic-gate 0x6014, "3Com", 4970Sstevel@tonic-gate 0x7000, "Ungermann-Bass download", 4980Sstevel@tonic-gate 0x7001, "Ungermann-Bass NIUs", 4990Sstevel@tonic-gate 0x7002, "Ungermann-Bass diagnostic/loopback", 5000Sstevel@tonic-gate 0x7003, "Ungermann-Bass ? (NMC to/from UB Bridge)", 5010Sstevel@tonic-gate 0x7005, "Ungermann-Bass Bridge Spanning Tree", 5020Sstevel@tonic-gate 0x7007, "OS/9 Microware", 5030Sstevel@tonic-gate 0x7009, "OS/9 Net?", 5040Sstevel@tonic-gate 0x7020, "Sintrom", 5050Sstevel@tonic-gate 0x7021, "Sintrom", 5060Sstevel@tonic-gate 0x7022, "Sintrom", 5070Sstevel@tonic-gate 0x7023, "Sintrom", 5080Sstevel@tonic-gate 0x7024, "Sintrom", 5090Sstevel@tonic-gate 0x7025, "Sintrom", 5100Sstevel@tonic-gate 0x7026, "Sintrom", 5110Sstevel@tonic-gate 0x7027, "Sintrom", 5120Sstevel@tonic-gate 0x7028, "Sintrom", 5130Sstevel@tonic-gate 0x7029, "Sintrom", 5140Sstevel@tonic-gate 0x8003, "Cronus VLN", 5150Sstevel@tonic-gate 0x8004, "Cronus Direct", 5160Sstevel@tonic-gate 0x8005, "HP Probe protocol", 5170Sstevel@tonic-gate 0x8006, "Nestar", 5180Sstevel@tonic-gate 0x8008, "AT&T/Stanford Univ", 5190Sstevel@tonic-gate 0x8010, "Excelan", 5200Sstevel@tonic-gate 0x8013, "SGI diagnostic", 5210Sstevel@tonic-gate 0x8014, "SGI network games", 5220Sstevel@tonic-gate 0x8015, "SGI reserved", 5230Sstevel@tonic-gate 0x8016, "SGI XNS NameServer, bounce server", 5240Sstevel@tonic-gate 0x8019, "Apollo DOMAIN", 5250Sstevel@tonic-gate 0x802E, "Tymshare", 5260Sstevel@tonic-gate 0x802F, "Tigan,", 5270Sstevel@tonic-gate 0x8036, "Aeonic Systems", 5280Sstevel@tonic-gate 0x8037, "IPX (Novell Netware)", 5290Sstevel@tonic-gate 0x8038, "DEC LanBridge Management", 5300Sstevel@tonic-gate 0x8039, "DEC unass (DSM/DTP?)", 5310Sstevel@tonic-gate 0x803A, "DEC unass (Argonaut Console?)", 5320Sstevel@tonic-gate 0x803B, "DEC unass (VAXELN?)", 5330Sstevel@tonic-gate 0x803C, "DEC unass (NMSV? DNA Naming Service?)", 5340Sstevel@tonic-gate 0x803D, "DEC Ethernet CSMA/CD Encryption Protocol", 5350Sstevel@tonic-gate 0x803E, "DEC unass (DNA Time Service?)", 5360Sstevel@tonic-gate 0x803F, "DEC LAN Traffic Monitor Protocol", 5370Sstevel@tonic-gate 0x8040, "DEC unass (NetBios Emulator?)", 5380Sstevel@tonic-gate 0x8041, "DEC unass (MS/DOS?, Local Area System Transport?)", 5390Sstevel@tonic-gate 0x8042, "DEC unass", 5400Sstevel@tonic-gate 0x8044, "Planning Research Corp.", 5410Sstevel@tonic-gate 0x8046, "AT&T", 5420Sstevel@tonic-gate 0x8047, "AT&T", 5430Sstevel@tonic-gate 0x8049, "ExperData", 5440Sstevel@tonic-gate 0x805B, "VMTP", 5450Sstevel@tonic-gate 0x805C, "Stanford V Kernel, version 6.0", 5460Sstevel@tonic-gate 0x805D, "Evans & Sutherland", 5470Sstevel@tonic-gate 0x8060, "Little Machines", 5480Sstevel@tonic-gate 0x8062, "Counterpoint", 5490Sstevel@tonic-gate 0x8065, "University of Mass. at Amherst", 5500Sstevel@tonic-gate 0x8066, "University of Mass. at Amherst", 5510Sstevel@tonic-gate 0x8067, "Veeco Integrated Automation", 5520Sstevel@tonic-gate 0x8068, "General Dynamics", 5530Sstevel@tonic-gate 0x8069, "AT&T", 5540Sstevel@tonic-gate 0x806A, "Autophon", 5550Sstevel@tonic-gate 0x806C, "ComDesign", 5560Sstevel@tonic-gate 0x806D, "Compugraphic Corp", 5570Sstevel@tonic-gate 0x806E, "Landmark", 5580Sstevel@tonic-gate 0x806F, "Landmark", 5590Sstevel@tonic-gate 0x8070, "Landmark", 5600Sstevel@tonic-gate 0x8071, "Landmark", 5610Sstevel@tonic-gate 0x8072, "Landmark", 5620Sstevel@tonic-gate 0x8073, "Landmark", 5630Sstevel@tonic-gate 0x8074, "Landmark", 5640Sstevel@tonic-gate 0x8075, "Landmark", 5650Sstevel@tonic-gate 0x8076, "Landmark", 5660Sstevel@tonic-gate 0x8077, "Landmark", 5670Sstevel@tonic-gate 0x807A, "Matra", 5680Sstevel@tonic-gate 0x807B, "Dansk Data Elektronik", 5690Sstevel@tonic-gate 0x807C, "Merit Internodal", 5700Sstevel@tonic-gate 0x807D, "Vitalink", 5710Sstevel@tonic-gate 0x807E, "Vitalink", 5720Sstevel@tonic-gate 0x807F, "Vitalink", 5730Sstevel@tonic-gate 0x8080, "Vitalink TransLAN III Management", 5740Sstevel@tonic-gate 0x8081, "Counterpoint", 5750Sstevel@tonic-gate 0x8082, "Counterpoint", 5760Sstevel@tonic-gate 0x8083, "Counterpoint", 5770Sstevel@tonic-gate 0x8088, "Xyplex", 5780Sstevel@tonic-gate 0x8089, "Xyplex", 5790Sstevel@tonic-gate 0x808A, "Xyplex", 5800Sstevel@tonic-gate 0x809B, "EtherTalk (AppleTalk over Ethernet)", 5810Sstevel@tonic-gate 0x809C, "Datability", 5820Sstevel@tonic-gate 0x809D, "Datability", 5830Sstevel@tonic-gate 0x809E, "Datability", 5840Sstevel@tonic-gate 0x809F, "Spider Systems", 5850Sstevel@tonic-gate 0x80A3, "Nixdorf", 5860Sstevel@tonic-gate 0x80A4, "Siemens Gammasonics", 5870Sstevel@tonic-gate 0x80C0, "DCA Data Exchange Cluster", 5880Sstevel@tonic-gate 0x80C6, "Pacer Software", 5890Sstevel@tonic-gate 0x80C7, "Applitek Corp", 5900Sstevel@tonic-gate 0x80C8, "Intergraph", 5910Sstevel@tonic-gate 0x80C9, "Intergraph", 5920Sstevel@tonic-gate 0x80CB, "Intergraph", 5930Sstevel@tonic-gate 0x80CC, "Intergraph", 5940Sstevel@tonic-gate 0x80CA, "Intergraph", 5950Sstevel@tonic-gate 0x80CD, "Harris Corp", 5960Sstevel@tonic-gate 0x80CE, "Harris Corp", 5970Sstevel@tonic-gate 0x80CF, "Taylor Instrument", 5980Sstevel@tonic-gate 0x80D0, "Taylor Instrument", 5990Sstevel@tonic-gate 0x80D1, "Taylor Instrument", 6000Sstevel@tonic-gate 0x80D2, "Taylor Instrument", 6010Sstevel@tonic-gate 0x80D3, "Rosemount Corp", 6020Sstevel@tonic-gate 0x80D4, "Rosemount Corp", 6030Sstevel@tonic-gate 0x80D5, "IBM SNA Services over Ethernet", 6040Sstevel@tonic-gate 0x80DD, "Varian Associates", 6050Sstevel@tonic-gate 0x80DE, "TRFS", 6060Sstevel@tonic-gate 0x80DF, "TRFS", 6070Sstevel@tonic-gate 0x80E0, "Allen-Bradley", 6080Sstevel@tonic-gate 0x80E1, "Allen-Bradley", 6090Sstevel@tonic-gate 0x80E2, "Allen-Bradley", 6100Sstevel@tonic-gate 0x80E3, "Allen-Bradley", 6110Sstevel@tonic-gate 0x80E4, "Datability", 6120Sstevel@tonic-gate 0x80F2, "Retix", 6130Sstevel@tonic-gate 0x80F3, "AARP (Appletalk)", 6140Sstevel@tonic-gate 0x80F4, "Kinetics", 6150Sstevel@tonic-gate 0x80F5, "Kinetics", 6160Sstevel@tonic-gate 0x80F7, "Apollo", 6170Sstevel@tonic-gate 0x80FF, "Wellfleet Communications", 6180Sstevel@tonic-gate 0x8102, "Wellfleet Communications", 6190Sstevel@tonic-gate 0x8107, "Symbolics Private", 6200Sstevel@tonic-gate 0x8108, "Symbolics Private", 6210Sstevel@tonic-gate 0x8109, "Symbolics Private", 6220Sstevel@tonic-gate 0x812B, "Talaris", 6230Sstevel@tonic-gate 0x8130, "Waterloo", 6240Sstevel@tonic-gate 0x8131, "VG Lab", 6250Sstevel@tonic-gate 0x8137, "Novell (old) NetWare IPX", 6260Sstevel@tonic-gate 0x8138, "Novell", 6270Sstevel@tonic-gate 0x814C, "SNMP over Ethernet", 6280Sstevel@tonic-gate 0x817D, "XTP", 6290Sstevel@tonic-gate 0x81D6, "Lantastic", 6300Sstevel@tonic-gate 0x8888, "HP LanProbe test?", 6310Sstevel@tonic-gate 0x9000, "Loopback", 6320Sstevel@tonic-gate 0x9001, "3Com, XNS Systems Management", 6330Sstevel@tonic-gate 0x9002, "3Com, TCP/IP Systems Management", 6340Sstevel@tonic-gate 0x9003, "3Com, loopback detection", 6350Sstevel@tonic-gate 0xAAAA, "DECNET (VAX 6220 DEBNI)", 6360Sstevel@tonic-gate 0xFF00, "BBN VITAL-LanBridge cache wakeups", 6370Sstevel@tonic-gate 0, "", 6380Sstevel@tonic-gate }; 6390Sstevel@tonic-gate 6400Sstevel@tonic-gate char * 641*10616SSebastien.Roy@Sun.COM print_fc(uint_t type) 6420Sstevel@tonic-gate { 6430Sstevel@tonic-gate 6440Sstevel@tonic-gate switch (type) { 6450Sstevel@tonic-gate case 0x50: return ("LLC"); 6460Sstevel@tonic-gate case 0x4f: return ("SMT NSA"); 6470Sstevel@tonic-gate case 0x41: return ("SMT Info"); 6480Sstevel@tonic-gate default: return ("Unknown"); 6490Sstevel@tonic-gate } 6500Sstevel@tonic-gate } 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate char * 653*10616SSebastien.Roy@Sun.COM print_smtclass(uint_t type) 6540Sstevel@tonic-gate { 6550Sstevel@tonic-gate switch (type) { 6560Sstevel@tonic-gate case 0x01: return ("NIF"); 6570Sstevel@tonic-gate case 0x02: return ("SIF Conf"); 6580Sstevel@tonic-gate case 0x03: return ("SIF Oper"); 6590Sstevel@tonic-gate case 0x04: return ("ECF"); 6600Sstevel@tonic-gate case 0x05: return ("RAF"); 6610Sstevel@tonic-gate case 0x06: return ("RDF"); 6620Sstevel@tonic-gate case 0x07: return ("SRF"); 6630Sstevel@tonic-gate case 0x08: return ("PMF Get"); 6640Sstevel@tonic-gate case 0x09: return ("PMF Change"); 6650Sstevel@tonic-gate case 0x0a: return ("PMF Add"); 6660Sstevel@tonic-gate case 0x0b: return ("PMF Remove"); 6670Sstevel@tonic-gate case 0xff: return ("ESF"); 6680Sstevel@tonic-gate default: return ("Unknown"); 6690Sstevel@tonic-gate } 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate char * 673*10616SSebastien.Roy@Sun.COM print_smttype(uint_t type) 6740Sstevel@tonic-gate { 6750Sstevel@tonic-gate switch (type) { 6760Sstevel@tonic-gate case 0x01: return ("Announce"); 6770Sstevel@tonic-gate case 0x02: return ("Request"); 6780Sstevel@tonic-gate case 0x03: return ("Response"); 6790Sstevel@tonic-gate default: return ("Unknown"); 6800Sstevel@tonic-gate } 6810Sstevel@tonic-gate 6820Sstevel@tonic-gate } 6830Sstevel@tonic-gate char * 684*10616SSebastien.Roy@Sun.COM print_ethertype(int type) 6850Sstevel@tonic-gate { 6860Sstevel@tonic-gate int i; 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate for (i = 0; ether_type[i].e_type; i++) 6890Sstevel@tonic-gate if (type == ether_type[i].e_type) 6900Sstevel@tonic-gate return (ether_type[i].e_name); 6910Sstevel@tonic-gate if (type < 1500) 6920Sstevel@tonic-gate return ("LLC/802.3"); 6930Sstevel@tonic-gate 6940Sstevel@tonic-gate return ("Unknown"); 6950Sstevel@tonic-gate } 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate #define MAX_RDFLDS 14 /* changed to 14 from 8 as per IEEE */ 6980Sstevel@tonic-gate #define TR_FN_ADDR 0x80 /* dest addr is functional */ 6990Sstevel@tonic-gate #define TR_SR_ADDR 0x80 /* MAC utilizes source route */ 7000Sstevel@tonic-gate #define ACFCDASA_LEN 14 /* length of AC|FC|DA|SA */ 7010Sstevel@tonic-gate #define TR_MAC_MASK 0xc0 7020Sstevel@tonic-gate #define TR_AC 0x00 /* Token Ring access control */ 7030Sstevel@tonic-gate #define TR_LLC_FC 0x40 /* Token Ring llc frame control */ 7040Sstevel@tonic-gate #define LSAP_SNAP 0xaa 7050Sstevel@tonic-gate #define LLC_SNAP_HDR_LEN 8 7060Sstevel@tonic-gate #define LLC_HDR1_LEN 3 /* DON'T use sizeof(struct llc_hdr1) */ 7070Sstevel@tonic-gate #define CNTL_LLC_UI 0x03 /* un-numbered information packet */ 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate /* 7100Sstevel@tonic-gate * Source Routing Route Information field. 7110Sstevel@tonic-gate */ 7120Sstevel@tonic-gate struct tr_ri { 7130Sstevel@tonic-gate #if defined(_BIT_FIELDS_HTOL) 7140Sstevel@tonic-gate uchar_t rt:3; /* routing type */ 7150Sstevel@tonic-gate uchar_t len:5; /* length */ 7160Sstevel@tonic-gate uchar_t dir:1; /* direction bit */ 7170Sstevel@tonic-gate uchar_t mtu:3; /* largest frame */ 7180Sstevel@tonic-gate uchar_t res:4; /* reserved */ 7190Sstevel@tonic-gate #elif defined(_BIT_FIELDS_LTOH) 7200Sstevel@tonic-gate uchar_t len:5; /* length */ 7210Sstevel@tonic-gate uchar_t rt:3; /* routing type */ 7220Sstevel@tonic-gate uchar_t res:4; /* reserved */ 7230Sstevel@tonic-gate uchar_t mtu:3; /* largest frame */ 7240Sstevel@tonic-gate uchar_t dir:1; /* direction bit */ 7250Sstevel@tonic-gate #endif 7260Sstevel@tonic-gate /* 7270Sstevel@tonic-gate * In little endian machine, the ring field has to be stored in a 7280Sstevel@tonic-gate * ushort_t type. This implies that it is not possible to have a 7290Sstevel@tonic-gate * layout of bit field to represent bridge and ring. 7300Sstevel@tonic-gate * 7310Sstevel@tonic-gate * If the compiler uses _BIT_FIELDS_HTOL and it is a big endian 7320Sstevel@tonic-gate * machine, the following bit field definition will work. 7330Sstevel@tonic-gate * 7340Sstevel@tonic-gate * struct tr_rd { 7350Sstevel@tonic-gate * ushort_t bridge:4; 7360Sstevel@tonic-gate * ushort_t ring:12; 7370Sstevel@tonic-gate * } rd[MAX_RDFLDS]; 7380Sstevel@tonic-gate * 7390Sstevel@tonic-gate * If the compiler uses _BIT_FIELDS_LTOH and it is a big endian 7400Sstevel@tonic-gate * machine, the definition can be changed to 7410Sstevel@tonic-gate * 7420Sstevel@tonic-gate * struct tr_rd { 7430Sstevel@tonic-gate * ushort_t bridge:4; 7440Sstevel@tonic-gate * ushort_t ring:12; 7450Sstevel@tonic-gate * } rd[MAX_RDFLDS]; 7460Sstevel@tonic-gate * 7470Sstevel@tonic-gate * With little endian machine, we need to use 2 macroes. For 7480Sstevel@tonic-gate * simplicity, since the macroes work for both big and little 7490Sstevel@tonic-gate * endian machines, we will not use bit fields for the 7500Sstevel@tonic-gate * definition. 7510Sstevel@tonic-gate */ 7520Sstevel@tonic-gate #define bridge(route) (ntohs((ushort_t)(route)) & 0x0F) 7530Sstevel@tonic-gate #define ring(route) (ntohs((ushort_t)(route)) >> 4) 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate ushort_t rd[MAX_RDFLDS]; /* route designator fields */ 7560Sstevel@tonic-gate }; 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate struct tr_header { 7590Sstevel@tonic-gate uchar_t ac; 7600Sstevel@tonic-gate uchar_t fc; 7610Sstevel@tonic-gate struct ether_addr dhost; 7620Sstevel@tonic-gate struct ether_addr shost; 7630Sstevel@tonic-gate struct tr_ri ri; 7640Sstevel@tonic-gate }; 7650Sstevel@tonic-gate 7660Sstevel@tonic-gate struct llc_snap_hdr { 7670Sstevel@tonic-gate uchar_t d_lsap; /* destination service access point */ 7680Sstevel@tonic-gate uchar_t s_lsap; /* source link service access point */ 7690Sstevel@tonic-gate uchar_t control; /* short control field */ 7700Sstevel@tonic-gate uchar_t org[3]; /* Ethernet style organization field */ 7710Sstevel@tonic-gate ushort_t type; /* Ethernet style type field */ 7720Sstevel@tonic-gate }; 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate struct ether_addr tokenbroadcastaddr2 = { 7750Sstevel@tonic-gate 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff 7760Sstevel@tonic-gate }; 7770Sstevel@tonic-gate 7780Sstevel@tonic-gate int Mtutab[] = {516, 1470, 2052, 4472, 8144, 11407, 17800}; 7790Sstevel@tonic-gate 7800Sstevel@tonic-gate char * 7810Sstevel@tonic-gate print_sr(struct tr_ri *rh) 7820Sstevel@tonic-gate { 7830Sstevel@tonic-gate int hops, ii; 7840Sstevel@tonic-gate static char line[512]; 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate sprintf(line, "TR Source Route dir=%d, mtu=%d", 7878023SPhil.Kirk@Sun.COM rh->dir, Mtutab[rh->mtu]); 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate hops = (int)(rh->len - 2) / (int)2; 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate if (hops) { 7920Sstevel@tonic-gate sprintf(line+strlen(line), ", Route: "); 7930Sstevel@tonic-gate for (ii = 0; ii < hops; ii++) { 7940Sstevel@tonic-gate if (! bridge(rh->rd[ii])) { 7950Sstevel@tonic-gate sprintf(line+strlen(line), "(%d)", 7960Sstevel@tonic-gate ring(rh->rd[ii])); 7970Sstevel@tonic-gate } else { 7980Sstevel@tonic-gate sprintf(line+strlen(line), "(%d)%d", 7990Sstevel@tonic-gate ring(rh->rd[ii]), bridge(rh->rd[ii])); 8000Sstevel@tonic-gate } 8010Sstevel@tonic-gate } 8020Sstevel@tonic-gate } 8030Sstevel@tonic-gate return (&line[0]); 8040Sstevel@tonic-gate } 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate uint_t 807*10616SSebastien.Roy@Sun.COM interpret_tr(int flags, caddr_t e, int elen, int origlen) 8080Sstevel@tonic-gate { 8090Sstevel@tonic-gate struct tr_header *mh; 8100Sstevel@tonic-gate struct tr_ri *rh; 8110Sstevel@tonic-gate uchar_t fc; 8120Sstevel@tonic-gate struct llc_snap_hdr *snaphdr; 8130Sstevel@tonic-gate char *off; 8140Sstevel@tonic-gate int maclen, len; 8150Sstevel@tonic-gate boolean_t data_copied = B_FALSE; 8160Sstevel@tonic-gate extern char *dst_name, *src_name; 8170Sstevel@tonic-gate int ethertype; 8180Sstevel@tonic-gate int is_llc = 0, is_snap = 0, source_routing = 0; 8190Sstevel@tonic-gate int blen = MAX(origlen, 17800); 8200Sstevel@tonic-gate 8210Sstevel@tonic-gate if (data != NULL && datalen != 0 && datalen < blen) { 8220Sstevel@tonic-gate free(data); 8230Sstevel@tonic-gate data = NULL; 8240Sstevel@tonic-gate datalen = 0; 8250Sstevel@tonic-gate } 8260Sstevel@tonic-gate if (!data) { 8270Sstevel@tonic-gate data = (char *)malloc(blen); 8280Sstevel@tonic-gate if (!data) 8290Sstevel@tonic-gate pr_err("Warning: malloc failure"); 8300Sstevel@tonic-gate datalen = blen; 8310Sstevel@tonic-gate } 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate if (origlen < ACFCDASA_LEN) { 834*10616SSebastien.Roy@Sun.COM if (flags & F_SUM) { 8350Sstevel@tonic-gate (void) sprintf(get_sum_line(), 836*10616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)", 837*10616SSebastien.Roy@Sun.COM origlen); 838*10616SSebastien.Roy@Sun.COM } 8390Sstevel@tonic-gate if (flags & F_DTAIL) 8400Sstevel@tonic-gate show_header("RUNT: ", "Short packet", origlen); 8410Sstevel@tonic-gate return (elen); 8420Sstevel@tonic-gate } 8430Sstevel@tonic-gate if (elen < ACFCDASA_LEN) 8440Sstevel@tonic-gate return (elen); 8450Sstevel@tonic-gate 8460Sstevel@tonic-gate mh = (struct tr_header *)e; 8470Sstevel@tonic-gate rh = (struct tr_ri *)&mh->ri; 8480Sstevel@tonic-gate fc = mh->fc; 8490Sstevel@tonic-gate 8500Sstevel@tonic-gate if (is_llc = tr_machdr_len(e, &maclen, &source_routing)) { 8510Sstevel@tonic-gate snaphdr = (struct llc_snap_hdr *)(e + maclen); 8520Sstevel@tonic-gate if (snaphdr->d_lsap == LSAP_SNAP && 853*10616SSebastien.Roy@Sun.COM snaphdr->s_lsap == LSAP_SNAP && 854*10616SSebastien.Roy@Sun.COM snaphdr->control == CNTL_LLC_UI) { 8550Sstevel@tonic-gate is_snap = 1; 8560Sstevel@tonic-gate } 8570Sstevel@tonic-gate } 8580Sstevel@tonic-gate 8590Sstevel@tonic-gate if (memcmp(&mh->dhost, ðer_broadcast, 8600Sstevel@tonic-gate sizeof (struct ether_addr)) == 0) 8610Sstevel@tonic-gate dst_name = "(broadcast)"; 8620Sstevel@tonic-gate else if (memcmp(&mh->dhost, &tokenbroadcastaddr2, 863*10616SSebastien.Roy@Sun.COM sizeof (struct ether_addr)) == 0) 8640Sstevel@tonic-gate dst_name = "(mac broadcast)"; 8650Sstevel@tonic-gate else if (mh->dhost.ether_addr_octet[0] & TR_FN_ADDR) 8660Sstevel@tonic-gate dst_name = "(functional)"; 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate if (is_snap) 8690Sstevel@tonic-gate ethertype = ntohs(snaphdr->type); 8700Sstevel@tonic-gate else { 8710Sstevel@tonic-gate src_name = print_etherinfo(&mh->shost); 8720Sstevel@tonic-gate dst_name = print_etherinfo(&mh->dhost); 8730Sstevel@tonic-gate } 8740Sstevel@tonic-gate 8750Sstevel@tonic-gate /* 8760Sstevel@tonic-gate * The 14 byte ether header screws up alignment 8770Sstevel@tonic-gate * of the rest of the packet for 32 bit aligned 8780Sstevel@tonic-gate * architectures like SPARC. Alas, we have to copy 8790Sstevel@tonic-gate * the rest of the packet in order to align it. 8800Sstevel@tonic-gate */ 8810Sstevel@tonic-gate if (is_llc) { 8820Sstevel@tonic-gate if (is_snap) { 8830Sstevel@tonic-gate len = elen - (maclen + LLC_SNAP_HDR_LEN); 8840Sstevel@tonic-gate off = (char *)(e + maclen + LLC_SNAP_HDR_LEN); 8850Sstevel@tonic-gate } else { 8860Sstevel@tonic-gate len = elen - (maclen + LLC_HDR1_LEN); 8870Sstevel@tonic-gate off = (char *)(e + maclen + LLC_HDR1_LEN); 8880Sstevel@tonic-gate } 8890Sstevel@tonic-gate } else { 8900Sstevel@tonic-gate len = elen - maclen; 8910Sstevel@tonic-gate off = (char *)(e + maclen); 8920Sstevel@tonic-gate } 8930Sstevel@tonic-gate 8940Sstevel@tonic-gate if (len > 0 && (off + len <= (char *)e + elen)) { 8950Sstevel@tonic-gate (void) memcpy(data, off, len); 8960Sstevel@tonic-gate data_copied = B_TRUE; 8970Sstevel@tonic-gate } 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate if (flags & F_SUM) { 9000Sstevel@tonic-gate if (source_routing) 9010Sstevel@tonic-gate sprintf(get_sum_line(), print_sr(rh)); 9020Sstevel@tonic-gate 9030Sstevel@tonic-gate if (is_llc) { 9040Sstevel@tonic-gate if (is_snap) { 905*10616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "TR LLC w/SNAP " 906*10616SSebastien.Roy@Sun.COM "Type=%04X (%s), size=%d bytes", 907*10616SSebastien.Roy@Sun.COM ethertype, 908*10616SSebastien.Roy@Sun.COM print_ethertype(ethertype), 909*10616SSebastien.Roy@Sun.COM origlen); 9100Sstevel@tonic-gate } else { 911*10616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "TR LLC, but no " 912*10616SSebastien.Roy@Sun.COM "SNAP encoding, size = %d bytes", 913*10616SSebastien.Roy@Sun.COM origlen); 9140Sstevel@tonic-gate } 9150Sstevel@tonic-gate } else { 9160Sstevel@tonic-gate (void) sprintf(get_sum_line(), 917*10616SSebastien.Roy@Sun.COM "TR MAC FC=%02X (%s), size = %d bytes", 918*10616SSebastien.Roy@Sun.COM fc, print_fc(fc), origlen); 9190Sstevel@tonic-gate } 9200Sstevel@tonic-gate } 9210Sstevel@tonic-gate 9220Sstevel@tonic-gate if (flags & F_DTAIL) { 923*10616SSebastien.Roy@Sun.COM show_header("TR: ", "TR Header", elen); 924*10616SSebastien.Roy@Sun.COM show_space(); 925*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0), 926*10616SSebastien.Roy@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d", 927*10616SSebastien.Roy@Sun.COM pi_frame, 928*10616SSebastien.Roy@Sun.COM pi_time_hour, pi_time_min, pi_time_sec, 929*10616SSebastien.Roy@Sun.COM pi_time_usec / 10); 930*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0), 931*10616SSebastien.Roy@Sun.COM "Packet size = %d bytes", 932*10616SSebastien.Roy@Sun.COM elen); 933*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 1), 934*10616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)", 935*10616SSebastien.Roy@Sun.COM fc, print_fc(fc)); 936*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(2, 6), 937*10616SSebastien.Roy@Sun.COM "Destination = %s, %s", 938*10616SSebastien.Roy@Sun.COM printether(&mh->dhost), 939*10616SSebastien.Roy@Sun.COM print_etherinfo(&mh->dhost)); 940*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(8, 6), 941*10616SSebastien.Roy@Sun.COM "Source = %s, %s", 942*10616SSebastien.Roy@Sun.COM printether(&mh->shost), 943*10616SSebastien.Roy@Sun.COM print_etherinfo(&mh->shost)); 944*10616SSebastien.Roy@Sun.COM 945*10616SSebastien.Roy@Sun.COM if (source_routing) 946*10616SSebastien.Roy@Sun.COM sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh)); 9470Sstevel@tonic-gate 948*10616SSebastien.Roy@Sun.COM if (is_llc) { 949*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen, 1), 950*10616SSebastien.Roy@Sun.COM "Dest Service Access Point = %02x", 951*10616SSebastien.Roy@Sun.COM snaphdr->d_lsap); 952*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+1, 1), 953*10616SSebastien.Roy@Sun.COM "Source Service Access Point = %02x", 954*10616SSebastien.Roy@Sun.COM snaphdr->s_lsap); 955*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+2, 1), 956*10616SSebastien.Roy@Sun.COM "Control = %02x", 957*10616SSebastien.Roy@Sun.COM snaphdr->control); 958*10616SSebastien.Roy@Sun.COM if (is_snap) { 959*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+3, 3), 960*10616SSebastien.Roy@Sun.COM "SNAP Protocol Id = %02x%02x%02x", 961*10616SSebastien.Roy@Sun.COM snaphdr->org[0], snaphdr->org[1], 962*10616SSebastien.Roy@Sun.COM snaphdr->org[2]); 963*10616SSebastien.Roy@Sun.COM } 964*10616SSebastien.Roy@Sun.COM } 9650Sstevel@tonic-gate 966*10616SSebastien.Roy@Sun.COM if (is_snap) { 967*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+6, 2), 968*10616SSebastien.Roy@Sun.COM "SNAP Type = %04X (%s)", 969*10616SSebastien.Roy@Sun.COM ethertype, print_ethertype(ethertype)); 970*10616SSebastien.Roy@Sun.COM } 9710Sstevel@tonic-gate 972*10616SSebastien.Roy@Sun.COM show_space(); 9730Sstevel@tonic-gate } 9740Sstevel@tonic-gate 9750Sstevel@tonic-gate /* go to the next protocol layer */ 9760Sstevel@tonic-gate if (is_snap && data_copied) { 9770Sstevel@tonic-gate switch (ethertype) { 9780Sstevel@tonic-gate case ETHERTYPE_IP: 9790Sstevel@tonic-gate (void) interpret_ip(flags, (struct ip *)data, len); 9800Sstevel@tonic-gate break; 9810Sstevel@tonic-gate /* Just in case it is decided to add this type */ 9820Sstevel@tonic-gate case ETHERTYPE_IPV6: 9830Sstevel@tonic-gate (void) interpret_ipv6(flags, (ip6_t *)data, len); 9840Sstevel@tonic-gate break; 9850Sstevel@tonic-gate case ETHERTYPE_ARP: 9860Sstevel@tonic-gate case ETHERTYPE_REVARP: 9870Sstevel@tonic-gate interpret_arp(flags, (struct arphdr *)data, len); 9880Sstevel@tonic-gate break; 9890Sstevel@tonic-gate case ETHERTYPE_AARP: /* AppleTalk */ 9900Sstevel@tonic-gate interpret_aarp(flags, data, len); 9910Sstevel@tonic-gate break; 9920Sstevel@tonic-gate case ETHERTYPE_AT: 9930Sstevel@tonic-gate interpret_at(flags, (struct ddp_hdr *)data, len); 9940Sstevel@tonic-gate break; 9950Sstevel@tonic-gate default: 9960Sstevel@tonic-gate break; 9970Sstevel@tonic-gate } 9980Sstevel@tonic-gate } 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate return (elen); 10010Sstevel@tonic-gate } 10020Sstevel@tonic-gate 10030Sstevel@tonic-gate 10040Sstevel@tonic-gate /* 10050Sstevel@tonic-gate * stuffs length of mac and ri fields into *lenp 10060Sstevel@tonic-gate * returns: 10070Sstevel@tonic-gate * 0: mac frame 10080Sstevel@tonic-gate * 1: llc frame 10090Sstevel@tonic-gate */ 1010*10616SSebastien.Roy@Sun.COM static int 10110Sstevel@tonic-gate tr_machdr_len(char *e, int *lenp, int *source_routing) 10120Sstevel@tonic-gate { 10130Sstevel@tonic-gate struct tr_header *mh; 10140Sstevel@tonic-gate struct tr_ri *rh; 10150Sstevel@tonic-gate uchar_t fc; 10160Sstevel@tonic-gate 10170Sstevel@tonic-gate mh = (struct tr_header *)e; 10180Sstevel@tonic-gate rh = (struct tr_ri *)&mh->ri; 10190Sstevel@tonic-gate fc = mh->fc; 10200Sstevel@tonic-gate 10210Sstevel@tonic-gate if (mh->shost.ether_addr_octet[0] & TR_SR_ADDR) { 10220Sstevel@tonic-gate *lenp = ACFCDASA_LEN + rh->len; 10230Sstevel@tonic-gate *source_routing = 1; 10240Sstevel@tonic-gate } else { 10250Sstevel@tonic-gate *lenp = ACFCDASA_LEN; 10260Sstevel@tonic-gate *source_routing = 0; 10270Sstevel@tonic-gate } 10280Sstevel@tonic-gate 10290Sstevel@tonic-gate if ((fc & TR_MAC_MASK) == 0) 10300Sstevel@tonic-gate return (0); /* it's a MAC frame */ 10310Sstevel@tonic-gate else 10320Sstevel@tonic-gate return (1); /* it's an LLC frame */ 10330Sstevel@tonic-gate } 10340Sstevel@tonic-gate 10350Sstevel@tonic-gate uint_t 1036*10616SSebastien.Roy@Sun.COM tr_header_len(char *e, size_t msgsize) 10370Sstevel@tonic-gate { 10380Sstevel@tonic-gate struct llc_snap_hdr *snaphdr; 10390Sstevel@tonic-gate int len = 0, source_routing; 10400Sstevel@tonic-gate 10410Sstevel@tonic-gate if (tr_machdr_len(e, &len, &source_routing) == 0) 10420Sstevel@tonic-gate return (len); /* it's a MAC frame */ 10430Sstevel@tonic-gate 1044*10616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct llc_snap_hdr)) 1045*10616SSebastien.Roy@Sun.COM return (0); 1046*10616SSebastien.Roy@Sun.COM 10470Sstevel@tonic-gate snaphdr = (struct llc_snap_hdr *)(e + len); 10480Sstevel@tonic-gate if (snaphdr->d_lsap == LSAP_SNAP && 1049*10616SSebastien.Roy@Sun.COM snaphdr->s_lsap == LSAP_SNAP && 1050*10616SSebastien.Roy@Sun.COM snaphdr->control == CNTL_LLC_UI) 10510Sstevel@tonic-gate len += LLC_SNAP_HDR_LEN; /* it's a SNAP frame */ 10520Sstevel@tonic-gate else 10530Sstevel@tonic-gate len += LLC_HDR1_LEN; 10540Sstevel@tonic-gate 10550Sstevel@tonic-gate return (len); 10560Sstevel@tonic-gate } 10570Sstevel@tonic-gate 10580Sstevel@tonic-gate struct fddi_header { 10590Sstevel@tonic-gate uchar_t fc; 10600Sstevel@tonic-gate struct ether_addr dhost, shost; 10610Sstevel@tonic-gate uchar_t dsap, ssap, ctl, proto_id[3]; 10620Sstevel@tonic-gate ushort_t type; 10630Sstevel@tonic-gate }; 10640Sstevel@tonic-gate 10650Sstevel@tonic-gate uint_t 1066*10616SSebastien.Roy@Sun.COM interpret_fddi(int flags, caddr_t e, int elen, int origlen) 10670Sstevel@tonic-gate { 10680Sstevel@tonic-gate struct fddi_header fhdr, *f = &fhdr; 10690Sstevel@tonic-gate char *off; 10700Sstevel@tonic-gate int len; 10710Sstevel@tonic-gate boolean_t data_copied = B_FALSE; 10720Sstevel@tonic-gate extern char *dst_name, *src_name; 10730Sstevel@tonic-gate int ethertype; 10740Sstevel@tonic-gate int is_llc = 0, is_smt = 0, is_snap = 0; 10750Sstevel@tonic-gate int blen = MAX(origlen, 4500); 10760Sstevel@tonic-gate 10770Sstevel@tonic-gate if (data != NULL && datalen != 0 && datalen < blen) { 10780Sstevel@tonic-gate free(data); 10790Sstevel@tonic-gate data = NULL; 10800Sstevel@tonic-gate datalen = 0; 10810Sstevel@tonic-gate } 10820Sstevel@tonic-gate if (!data) { 10830Sstevel@tonic-gate data = (char *)malloc(blen); 10840Sstevel@tonic-gate if (!data) 10850Sstevel@tonic-gate pr_err("Warning: malloc failure"); 10860Sstevel@tonic-gate datalen = blen; 10870Sstevel@tonic-gate } 10880Sstevel@tonic-gate 10890Sstevel@tonic-gate if (origlen < 13) { 1090*10616SSebastien.Roy@Sun.COM if (flags & F_SUM) { 10910Sstevel@tonic-gate (void) sprintf(get_sum_line(), 1092*10616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)", 1093*10616SSebastien.Roy@Sun.COM origlen); 1094*10616SSebastien.Roy@Sun.COM } 10950Sstevel@tonic-gate if (flags & F_DTAIL) 10960Sstevel@tonic-gate show_header("RUNT: ", "Short packet", origlen); 10970Sstevel@tonic-gate return (elen); 10980Sstevel@tonic-gate } 10990Sstevel@tonic-gate if (elen < 13) 11000Sstevel@tonic-gate return (elen); 11010Sstevel@tonic-gate 11020Sstevel@tonic-gate (void) memcpy(&f->fc, e, sizeof (f->fc)); 11030Sstevel@tonic-gate addr_copy_swap(&f->dhost, (struct ether_addr *)(e+1)); 11040Sstevel@tonic-gate addr_copy_swap(&f->shost, (struct ether_addr *)(e+7)); 11050Sstevel@tonic-gate 11060Sstevel@tonic-gate if ((f->fc&0x50) == 0x50) { 11070Sstevel@tonic-gate is_llc = 1; 11080Sstevel@tonic-gate (void) memcpy(&f->dsap, e+13, sizeof (f->dsap)); 11090Sstevel@tonic-gate (void) memcpy(&f->ssap, e+14, sizeof (f->ssap)); 11100Sstevel@tonic-gate (void) memcpy(&f->ctl, e+15, sizeof (f->ctl)); 11110Sstevel@tonic-gate if (f->dsap == 0xaa && f->ssap == 0xaa) { 11120Sstevel@tonic-gate is_snap = 1; 11130Sstevel@tonic-gate (void) memcpy(&f->proto_id, e+16, sizeof (f->proto_id)); 11140Sstevel@tonic-gate (void) memcpy(&f->type, e+19, sizeof (f->type)); 11150Sstevel@tonic-gate } 11160Sstevel@tonic-gate } else { 11170Sstevel@tonic-gate if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) { 11180Sstevel@tonic-gate is_smt = 1; 11190Sstevel@tonic-gate } 11200Sstevel@tonic-gate } 11210Sstevel@tonic-gate 11220Sstevel@tonic-gate 11230Sstevel@tonic-gate if (memcmp(&f->dhost, ðer_broadcast, 11240Sstevel@tonic-gate sizeof (struct ether_addr)) == 0) 11250Sstevel@tonic-gate dst_name = "(broadcast)"; 11260Sstevel@tonic-gate else if (f->dhost.ether_addr_octet[0] & 0x01) 11270Sstevel@tonic-gate dst_name = "(multicast)"; 11280Sstevel@tonic-gate 11290Sstevel@tonic-gate if (is_snap) 11300Sstevel@tonic-gate ethertype = ntohs(f->type); 11310Sstevel@tonic-gate else { 11320Sstevel@tonic-gate src_name = print_etherinfo(&f->shost); 11330Sstevel@tonic-gate dst_name = print_etherinfo(&f->dhost); 11340Sstevel@tonic-gate } 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate /* 11370Sstevel@tonic-gate * The 14 byte ether header screws up alignment 11380Sstevel@tonic-gate * of the rest of the packet for 32 bit aligned 11390Sstevel@tonic-gate * architectures like SPARC. Alas, we have to copy 11400Sstevel@tonic-gate * the rest of the packet in order to align it. 11410Sstevel@tonic-gate */ 11420Sstevel@tonic-gate if (is_llc) { 11430Sstevel@tonic-gate if (is_snap) { 11440Sstevel@tonic-gate len = elen - 21; 11450Sstevel@tonic-gate off = (char *)(e + 21); 11460Sstevel@tonic-gate } else { 11470Sstevel@tonic-gate len = elen - 16; 11480Sstevel@tonic-gate off = (char *)(e + 16); 11490Sstevel@tonic-gate } 11500Sstevel@tonic-gate } else { 11510Sstevel@tonic-gate len = elen - 13; 11520Sstevel@tonic-gate off = (char *)(e + 13); 11530Sstevel@tonic-gate } 11540Sstevel@tonic-gate 11550Sstevel@tonic-gate if (len > 0 && (off + len <= (char *)e + elen)) { 11560Sstevel@tonic-gate (void) memcpy(data, off, len); 11570Sstevel@tonic-gate data_copied = B_TRUE; 11580Sstevel@tonic-gate } 11590Sstevel@tonic-gate 11600Sstevel@tonic-gate if (flags & F_SUM) { 11610Sstevel@tonic-gate if (is_llc) { 11620Sstevel@tonic-gate if (is_snap) { 11630Sstevel@tonic-gate (void) sprintf(get_sum_line(), 1164*10616SSebastien.Roy@Sun.COM "FDDI LLC Type=%04X (%s), size = %d bytes", 1165*10616SSebastien.Roy@Sun.COM ethertype, 1166*10616SSebastien.Roy@Sun.COM print_ethertype(ethertype), 1167*10616SSebastien.Roy@Sun.COM origlen); 11680Sstevel@tonic-gate } else { 1169*10616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "LLC, but no " 1170*10616SSebastien.Roy@Sun.COM "SNAP encoding, size = %d bytes", 1171*10616SSebastien.Roy@Sun.COM origlen); 11720Sstevel@tonic-gate } 11730Sstevel@tonic-gate } else if (is_smt) { 1174*10616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "SMT Type=%02X (%s), " 1175*10616SSebastien.Roy@Sun.COM "Class = %02X (%s), size = %d bytes", 1176*10616SSebastien.Roy@Sun.COM *(uchar_t *)(data+1), print_smttype(*(data+1)), 1177*10616SSebastien.Roy@Sun.COM *data, print_smtclass(*data), origlen); 11780Sstevel@tonic-gate } else { 11790Sstevel@tonic-gate (void) sprintf(get_sum_line(), 1180*10616SSebastien.Roy@Sun.COM "FC=%02X (%s), size = %d bytes", 1181*10616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc), origlen); 11820Sstevel@tonic-gate } 11830Sstevel@tonic-gate } 11840Sstevel@tonic-gate 11850Sstevel@tonic-gate if (flags & F_DTAIL) { 1186*10616SSebastien.Roy@Sun.COM show_header("FDDI: ", "FDDI Header", elen); 1187*10616SSebastien.Roy@Sun.COM show_space(); 1188*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0), 1189*10616SSebastien.Roy@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d", 1190*10616SSebastien.Roy@Sun.COM pi_frame, 1191*10616SSebastien.Roy@Sun.COM pi_time_hour, pi_time_min, pi_time_sec, 1192*10616SSebastien.Roy@Sun.COM pi_time_usec / 10); 1193*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0), 1194*10616SSebastien.Roy@Sun.COM "Packet size = %d bytes", 1195*10616SSebastien.Roy@Sun.COM elen, elen); 1196*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 6), 1197*10616SSebastien.Roy@Sun.COM "Destination = %s, %s", 1198*10616SSebastien.Roy@Sun.COM printether(&f->dhost), 1199*10616SSebastien.Roy@Sun.COM print_etherinfo(&f->dhost)); 1200*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(6, 6), 1201*10616SSebastien.Roy@Sun.COM "Source = %s, %s", 1202*10616SSebastien.Roy@Sun.COM printether(&f->shost), 1203*10616SSebastien.Roy@Sun.COM print_etherinfo(&f->shost)); 12040Sstevel@tonic-gate 1205*10616SSebastien.Roy@Sun.COM if (is_llc) { 1206*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1207*10616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)", 1208*10616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc)); 1209*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1210*10616SSebastien.Roy@Sun.COM "Dest Service Access Point = %02x", 1211*10616SSebastien.Roy@Sun.COM f->dsap); 1212*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1213*10616SSebastien.Roy@Sun.COM "Source Service Access Point = %02x", 1214*10616SSebastien.Roy@Sun.COM f->ssap); 1215*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1216*10616SSebastien.Roy@Sun.COM "Control = %02x", 1217*10616SSebastien.Roy@Sun.COM f->ctl); 1218*10616SSebastien.Roy@Sun.COM if (is_snap) { 1219*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1220*10616SSebastien.Roy@Sun.COM "Protocol Id = %02x%02x%02x", 1221*10616SSebastien.Roy@Sun.COM f->proto_id[0], f->proto_id[1], 1222*10616SSebastien.Roy@Sun.COM f->proto_id[2]); 1223*10616SSebastien.Roy@Sun.COM } 1224*10616SSebastien.Roy@Sun.COM } else if (is_smt) { 12250Sstevel@tonic-gate (void) sprintf(get_line(12, 2), 1226*10616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)", 1227*10616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc)); 1228*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1229*10616SSebastien.Roy@Sun.COM "Class = %02x (%s)", 1230*10616SSebastien.Roy@Sun.COM (uchar_t)*data, print_smtclass(*data)); 1231*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1232*10616SSebastien.Roy@Sun.COM "Type = %02x (%s)", 1233*10616SSebastien.Roy@Sun.COM *(uchar_t *)(data+1), print_smttype(*(data+1))); 1234*10616SSebastien.Roy@Sun.COM } else { 1235*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1236*10616SSebastien.Roy@Sun.COM "FC=%02X (%s), size = %d bytes", 1237*10616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc), origlen); 1238*10616SSebastien.Roy@Sun.COM } 12390Sstevel@tonic-gate 1240*10616SSebastien.Roy@Sun.COM if (is_snap) { 1241*10616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2), 1242*10616SSebastien.Roy@Sun.COM "LLC Type = %04X (%s)", 1243*10616SSebastien.Roy@Sun.COM ethertype, print_ethertype(ethertype)); 1244*10616SSebastien.Roy@Sun.COM } 12450Sstevel@tonic-gate 1246*10616SSebastien.Roy@Sun.COM show_space(); 12470Sstevel@tonic-gate } 12480Sstevel@tonic-gate 12490Sstevel@tonic-gate /* go to the next protocol layer */ 12500Sstevel@tonic-gate if (is_llc && is_snap && f->ctl == 0x03 && data_copied) { 12510Sstevel@tonic-gate switch (ethertype) { 12520Sstevel@tonic-gate case ETHERTYPE_IP: 12530Sstevel@tonic-gate (void) interpret_ip(flags, (struct ip *)data, len); 12540Sstevel@tonic-gate break; 12550Sstevel@tonic-gate /* Just in case it is decided to add this type */ 12560Sstevel@tonic-gate case ETHERTYPE_IPV6: 12570Sstevel@tonic-gate (void) interpret_ipv6(flags, (ip6_t *)data, len); 12580Sstevel@tonic-gate break; 12590Sstevel@tonic-gate case ETHERTYPE_ARP: 12600Sstevel@tonic-gate case ETHERTYPE_REVARP: 12610Sstevel@tonic-gate interpret_arp(flags, (struct arphdr *)data, len); 12620Sstevel@tonic-gate break; 12630Sstevel@tonic-gate default: 12640Sstevel@tonic-gate break; 12650Sstevel@tonic-gate } 12660Sstevel@tonic-gate 12670Sstevel@tonic-gate } 12680Sstevel@tonic-gate 12690Sstevel@tonic-gate return (elen); 12700Sstevel@tonic-gate } 12710Sstevel@tonic-gate 12720Sstevel@tonic-gate uint_t 1273*10616SSebastien.Roy@Sun.COM fddi_header_len(char *e, size_t msgsize) 12740Sstevel@tonic-gate { 12750Sstevel@tonic-gate struct fddi_header fhdr, *f = &fhdr; 12760Sstevel@tonic-gate 1277*10616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct fddi_header)) 1278*10616SSebastien.Roy@Sun.COM return (0); 1279*10616SSebastien.Roy@Sun.COM 12800Sstevel@tonic-gate (void) memcpy(&f->fc, e, sizeof (f->fc)); 12810Sstevel@tonic-gate (void) memcpy(&f->dhost, e+1, sizeof (struct ether_addr)); 12820Sstevel@tonic-gate (void) memcpy(&f->shost, e+7, sizeof (struct ether_addr)); 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate if ((f->fc&0x50) == 0x50) { 12850Sstevel@tonic-gate (void) memcpy(&f->dsap, e+13, sizeof (f->dsap)); 12860Sstevel@tonic-gate (void) memcpy(&f->ssap, e+14, sizeof (f->ssap)); 12870Sstevel@tonic-gate (void) memcpy(&f->ctl, e+15, sizeof (f->ctl)); 12880Sstevel@tonic-gate if (f->dsap == 0xaa && f->ssap == 0xaa) { 12890Sstevel@tonic-gate return (21); 12900Sstevel@tonic-gate } 12910Sstevel@tonic-gate return (16); 12920Sstevel@tonic-gate } else { 12930Sstevel@tonic-gate if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) { 12940Sstevel@tonic-gate return (13); 12950Sstevel@tonic-gate } 12960Sstevel@tonic-gate } 1297410Skcpoon /* Return the default FDDI header length. */ 1298410Skcpoon return (13); 12990Sstevel@tonic-gate } 13000Sstevel@tonic-gate 13010Sstevel@tonic-gate /* 13020Sstevel@tonic-gate * Print the given Ethernet address 13030Sstevel@tonic-gate */ 13040Sstevel@tonic-gate char * 1305*10616SSebastien.Roy@Sun.COM printether(struct ether_addr *p) 13060Sstevel@tonic-gate { 13070Sstevel@tonic-gate static char buf[256]; 13080Sstevel@tonic-gate 13090Sstevel@tonic-gate sprintf(buf, "%x:%x:%x:%x:%x:%x", 1310*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[0], 1311*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[1], 1312*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[2], 1313*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[3], 1314*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[4], 1315*10616SSebastien.Roy@Sun.COM p->ether_addr_octet[5]); 13160Sstevel@tonic-gate 13170Sstevel@tonic-gate return (buf); 13180Sstevel@tonic-gate } 13190Sstevel@tonic-gate 13200Sstevel@tonic-gate /* 13210Sstevel@tonic-gate * Table of Ethernet Address Assignments 13220Sstevel@tonic-gate * Some of the more popular entries 13230Sstevel@tonic-gate * are at the beginning of the table 13240Sstevel@tonic-gate * to reduce search time. Note that the 13250Sstevel@tonic-gate * e-block's are stored in host byte-order. 13260Sstevel@tonic-gate */ 13270Sstevel@tonic-gate struct block_type { 13280Sstevel@tonic-gate int e_block; 13290Sstevel@tonic-gate char *e_name; 13300Sstevel@tonic-gate } ether_block [] = { 13310Sstevel@tonic-gate 0x080020, "Sun", 13320Sstevel@tonic-gate 0x0000C6, "HP", 13330Sstevel@tonic-gate 0x08002B, "DEC", 13340Sstevel@tonic-gate 0x00000F, "NeXT", 13350Sstevel@tonic-gate 0x00000C, "Cisco", 13360Sstevel@tonic-gate 0x080069, "Silicon Graphics", 13370Sstevel@tonic-gate 0x000069, "Silicon Graphics", 13380Sstevel@tonic-gate 0x0000A7, "Network Computing Devices (NCD X-terminal)", 13390Sstevel@tonic-gate 0x08005A, "IBM", 13400Sstevel@tonic-gate 0x0000AC, "Apollo", 134110491SRishi.Srivatsavai@Sun.COM 0x0180C2, "Standard MAC Group Address", 13420Sstevel@tonic-gate /* end of popular entries */ 13430Sstevel@tonic-gate 0x000002, "BBN", 13440Sstevel@tonic-gate 0x000010, "Sytek", 13450Sstevel@tonic-gate 0x000011, "Tektronix", 13460Sstevel@tonic-gate 0x000018, "Webster (?)", 13470Sstevel@tonic-gate 0x00001B, "Novell", 13480Sstevel@tonic-gate 0x00001D, "Cabletron", 13490Sstevel@tonic-gate 0x000020, "DIAB (Data Industrier AB)", 13500Sstevel@tonic-gate 0x000021, "SC&C", 13510Sstevel@tonic-gate 0x000022, "Visual Technology", 13520Sstevel@tonic-gate 0x000029, "IMC", 13530Sstevel@tonic-gate 0x00002A, "TRW", 13540Sstevel@tonic-gate 0x00003D, "AT&T", 13550Sstevel@tonic-gate 0x000049, "Apricot Ltd.", 13560Sstevel@tonic-gate 0x000055, "AT&T", 13570Sstevel@tonic-gate 0x00005A, "S & Koch", 13580Sstevel@tonic-gate 0x00005A, "Xerox 806 (unregistered)", 13590Sstevel@tonic-gate 0x00005E, "U.S. Department of Defense (IANA)", 13600Sstevel@tonic-gate 0x000065, "Network General", 13610Sstevel@tonic-gate 0x00006B, "MIPS", 13620Sstevel@tonic-gate 0x000077, "MIPS", 13630Sstevel@tonic-gate 0x000079, "NetWare (?)", 13640Sstevel@tonic-gate 0x00007A, "Ardent", 13650Sstevel@tonic-gate 0x00007B, "Research Machines", 13660Sstevel@tonic-gate 0x00007D, "Harris (3M) (old)", 13670Sstevel@tonic-gate 0x000080, "Imagen(?)", 13680Sstevel@tonic-gate 0x000081, "Synoptics", 13690Sstevel@tonic-gate 0x000084, "Aquila (?)", 13700Sstevel@tonic-gate 0x000086, "Gateway (?)", 13710Sstevel@tonic-gate 0x000089, "Cayman Systems Gatorbox", 13720Sstevel@tonic-gate 0x000093, "Proteon", 13730Sstevel@tonic-gate 0x000094, "Asante", 13740Sstevel@tonic-gate 0x000098, "Cross Com", 13750Sstevel@tonic-gate 0x00009F, "Ameristar Technology", 13760Sstevel@tonic-gate 0x0000A2, "Wellfleet", 13770Sstevel@tonic-gate 0x0000A3, "Network Application Technology", 13780Sstevel@tonic-gate 0x0000A4, "Acorn", 13790Sstevel@tonic-gate 0x0000A6, "Network General", 13800Sstevel@tonic-gate 0x0000A7, "Network Computing Devices (NCD X-terminal)", 13810Sstevel@tonic-gate 0x0000A9, "Network Systems", 13820Sstevel@tonic-gate 0x0000AA, "Xerox", 13830Sstevel@tonic-gate 0x0000B3, "CIMLinc", 13840Sstevel@tonic-gate 0x0000B5, "Datability Terminal Server", 13850Sstevel@tonic-gate 0x0000B7, "Dove Fastnet", 13860Sstevel@tonic-gate 0x0000BC, "Allen-Bradley", 13870Sstevel@tonic-gate 0x0000C0, "Western Digital", 13880Sstevel@tonic-gate 0x0000C8, "Altos", 13890Sstevel@tonic-gate 0x0000C9, "Emulex Terminal Server", 13900Sstevel@tonic-gate 0x0000D0, "Develcon Electronics, Ltd.", 13910Sstevel@tonic-gate 0x0000D1, "Adaptec Inc. Nodem product", 13920Sstevel@tonic-gate 0x0000D7, "Dartmouth College (NED Router)", 13930Sstevel@tonic-gate 0x0000DD, "Gould", 13940Sstevel@tonic-gate 0x0000DE, "Unigraph", 13950Sstevel@tonic-gate 0x0000E2, "Acer Counterpoint", 13960Sstevel@tonic-gate 0x0000E8, "Accton Technology Corporation", 13970Sstevel@tonic-gate 0x0000EE, "Network Designers Limited(?)", 13980Sstevel@tonic-gate 0x0000EF, "Alantec", 13990Sstevel@tonic-gate 0x0000F3, "Gandalf", 14000Sstevel@tonic-gate 0x0000FD, "High Level Hardware (Orion, UK)", 14010Sstevel@tonic-gate 0x000143, "IEEE 802", 14020Sstevel@tonic-gate 0x001700, "Kabel", 14030Sstevel@tonic-gate 0x004010, "Sonic", 14040Sstevel@tonic-gate 0x00608C, "3Com", 14050Sstevel@tonic-gate 0x00800F, "SMC", 14060Sstevel@tonic-gate 0x008019, "Dayna Communications Etherprint product", 14070Sstevel@tonic-gate 0x00802D, "Xylogics, Inc. Annex terminal servers", 14080Sstevel@tonic-gate 0x008035, "Technology Works", 14090Sstevel@tonic-gate 0x008087, "Okidata", 14100Sstevel@tonic-gate 0x00808C, "Frontier Software Development", 14110Sstevel@tonic-gate 0x0080C7, "Xircom Inc.", 14120Sstevel@tonic-gate 0x0080D0, "Computer Products International", 14130Sstevel@tonic-gate 0x0080D3, "Shiva Appletalk-Ethernet interface", 14140Sstevel@tonic-gate 0x0080D4, "Chase Limited", 14150Sstevel@tonic-gate 0x0080F1, "Opus", 14160Sstevel@tonic-gate 0x00AA00, "Intel", 14170Sstevel@tonic-gate 0x00B0D0, "Computer Products International", 14180Sstevel@tonic-gate 0x00DD00, "Ungermann-Bass", 14190Sstevel@tonic-gate 0x00DD01, "Ungermann-Bass", 14200Sstevel@tonic-gate 0x00EFE5, "IBM (3Com card)", 14210Sstevel@tonic-gate 0x020406, "BBN", 14220Sstevel@tonic-gate 0x026060, "3Com", 14230Sstevel@tonic-gate 0x026086, "Satelcom MegaPac (UK)", 14240Sstevel@tonic-gate 0x02E6D3, "Bus-Tech, Inc. (BTI)", 14250Sstevel@tonic-gate 0x080001, "Computer Vision", 14260Sstevel@tonic-gate 0x080002, "3Com (Formerly Bridge)", 14270Sstevel@tonic-gate 0x080003, "ACC (Advanced Computer Communications)", 14280Sstevel@tonic-gate 0x080005, "Symbolics", 14290Sstevel@tonic-gate 0x080007, "Apple", 14300Sstevel@tonic-gate 0x080008, "BBN", 14310Sstevel@tonic-gate 0x080009, "Hewlett-Packard", 14320Sstevel@tonic-gate 0x08000A, "Nestar Systems", 14330Sstevel@tonic-gate 0x08000B, "Unisys", 14340Sstevel@tonic-gate 0x08000D, "ICL", 14350Sstevel@tonic-gate 0x08000E, "NCR", 14360Sstevel@tonic-gate 0x080010, "AT&T", 14370Sstevel@tonic-gate 0x080011, "Tektronix, Inc.", 14380Sstevel@tonic-gate 0x080017, "NSC", 14390Sstevel@tonic-gate 0x08001A, "Data General", 14400Sstevel@tonic-gate 0x08001B, "Data General", 14410Sstevel@tonic-gate 0x08001E, "Apollo", 14420Sstevel@tonic-gate 0x080022, "NBI", 14430Sstevel@tonic-gate 0x080025, "CDC", 14440Sstevel@tonic-gate 0x080026, "Norsk Data (Nord)", 14450Sstevel@tonic-gate 0x080027, "PCS Computer Systems GmbH", 14460Sstevel@tonic-gate 0x080028, "TI Explorer", 14470Sstevel@tonic-gate 0x08002E, "Metaphor", 14480Sstevel@tonic-gate 0x08002F, "Prime Computer", 14490Sstevel@tonic-gate 0x080036, "Intergraph CAE stations", 14500Sstevel@tonic-gate 0x080037, "Fujitsu-Xerox", 14510Sstevel@tonic-gate 0x080038, "Bull", 14520Sstevel@tonic-gate 0x080039, "Spider Systems", 14530Sstevel@tonic-gate 0x08003B, "Torus Systems", 14540Sstevel@tonic-gate 0x08003E, "Motorola VME bus processor module", 14550Sstevel@tonic-gate 0x080041, "DCA Digital Comm. Assoc.", 14560Sstevel@tonic-gate 0x080046, "Sony", 14570Sstevel@tonic-gate 0x080047, "Sequent", 14580Sstevel@tonic-gate 0x080049, "Univation", 14590Sstevel@tonic-gate 0x08004C, "Encore", 14600Sstevel@tonic-gate 0x08004E, "BICC", 14610Sstevel@tonic-gate 0x080056, "Stanford University", 14620Sstevel@tonic-gate 0x080057, "Evans & Sutherland (?)", 14630Sstevel@tonic-gate 0x080067, "Comdesign", 14640Sstevel@tonic-gate 0x080068, "Ridge", 14650Sstevel@tonic-gate 0x08006A, "ATTst (?)", 14660Sstevel@tonic-gate 0x08006E, "Excelan", 14670Sstevel@tonic-gate 0x080075, "DDE (Danish Data Elektronik A/S)", 14680Sstevel@tonic-gate 0x080077, "TSL (now Retix)", 14690Sstevel@tonic-gate 0x08007C, "Vitalink TransLAN III", 14700Sstevel@tonic-gate 0x080080, "XIOS", 14710Sstevel@tonic-gate 0x080081, "Crosfield Electronics", 14720Sstevel@tonic-gate 0x080086, "Imagen/QMS", 14730Sstevel@tonic-gate 0x080087, "Xyplex terminal server", 14740Sstevel@tonic-gate 0x080089, "Kinetics AppleTalk-Ethernet interface", 14750Sstevel@tonic-gate 0x08008B, "Pyramid", 14760Sstevel@tonic-gate 0x08008D, "XyVision", 14770Sstevel@tonic-gate 0x080090, "Retix Inc Bridge", 14780Sstevel@tonic-gate 0x10005A, "IBM", 14790Sstevel@tonic-gate 0x1000D4, "DEC", 14800Sstevel@tonic-gate 0x400003, "NetWare", 14810Sstevel@tonic-gate 0x800010, "AT&T", 14820Sstevel@tonic-gate 0xAA0004, "DEC (DECNET)", 14830Sstevel@tonic-gate 0xC00000, "SMC", 14840Sstevel@tonic-gate 0, "", 14850Sstevel@tonic-gate }; 14860Sstevel@tonic-gate 14870Sstevel@tonic-gate /* 14880Sstevel@tonic-gate * The oui argument should be in host byte-order to conform with 14890Sstevel@tonic-gate * the above array's values. 14900Sstevel@tonic-gate */ 14910Sstevel@tonic-gate char * 14920Sstevel@tonic-gate ether_ouiname(uint32_t oui) 14930Sstevel@tonic-gate { 14940Sstevel@tonic-gate uint_t i; 14950Sstevel@tonic-gate 14960Sstevel@tonic-gate for (i = 0; ether_block[i].e_block != 0; i++) 14970Sstevel@tonic-gate if (oui == ether_block[i].e_block) 14980Sstevel@tonic-gate return (ether_block[i].e_name); 14990Sstevel@tonic-gate 15000Sstevel@tonic-gate return (NULL); 15010Sstevel@tonic-gate } 15020Sstevel@tonic-gate 15030Sstevel@tonic-gate /* 15040Sstevel@tonic-gate * Print the additional Ethernet address info 15050Sstevel@tonic-gate */ 15060Sstevel@tonic-gate static char * 1507*10616SSebastien.Roy@Sun.COM print_etherinfo(struct ether_addr *eaddr) 15080Sstevel@tonic-gate { 15090Sstevel@tonic-gate uint_t addr = 0; 15100Sstevel@tonic-gate char *p = (char *)&addr + 1; 15110Sstevel@tonic-gate char *ename; 15120Sstevel@tonic-gate 15130Sstevel@tonic-gate (void) memcpy(p, eaddr, 3); 15140Sstevel@tonic-gate 15150Sstevel@tonic-gate if (memcmp(eaddr, ðer_broadcast, sizeof (struct ether_addr)) == 0) 15160Sstevel@tonic-gate return ("(broadcast)"); 15170Sstevel@tonic-gate 15180Sstevel@tonic-gate addr = ntohl(addr); /* make it right for little-endians */ 15190Sstevel@tonic-gate ename = ether_ouiname(addr); 15200Sstevel@tonic-gate 15210Sstevel@tonic-gate if (ename != NULL) 15220Sstevel@tonic-gate return (ename); 15230Sstevel@tonic-gate else 152410491SRishi.Srivatsavai@Sun.COM return ((eaddr->ether_addr_octet[0] & 1) ? "(multicast)" : ""); 15250Sstevel@tonic-gate } 15260Sstevel@tonic-gate 15270Sstevel@tonic-gate static uchar_t endianswap[] = { 15280Sstevel@tonic-gate 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 15290Sstevel@tonic-gate 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 15300Sstevel@tonic-gate 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 15310Sstevel@tonic-gate 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 15320Sstevel@tonic-gate 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 15330Sstevel@tonic-gate 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 15340Sstevel@tonic-gate 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 15350Sstevel@tonic-gate 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 15360Sstevel@tonic-gate 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 15370Sstevel@tonic-gate 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 15380Sstevel@tonic-gate 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 15390Sstevel@tonic-gate 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 15400Sstevel@tonic-gate 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 15410Sstevel@tonic-gate 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 15420Sstevel@tonic-gate 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 15430Sstevel@tonic-gate 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 15440Sstevel@tonic-gate 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 15450Sstevel@tonic-gate 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 15460Sstevel@tonic-gate 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 15470Sstevel@tonic-gate 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 15480Sstevel@tonic-gate 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 15490Sstevel@tonic-gate 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 15500Sstevel@tonic-gate 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 15510Sstevel@tonic-gate 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 15520Sstevel@tonic-gate 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 15530Sstevel@tonic-gate 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 15540Sstevel@tonic-gate 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 15550Sstevel@tonic-gate 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 15560Sstevel@tonic-gate 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 15570Sstevel@tonic-gate 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 15580Sstevel@tonic-gate 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 15590Sstevel@tonic-gate 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 15600Sstevel@tonic-gate }; 15610Sstevel@tonic-gate 15620Sstevel@tonic-gate static void 1563*10616SSebastien.Roy@Sun.COM addr_copy_swap(struct ether_addr *pd, struct ether_addr *ps) 15640Sstevel@tonic-gate { 15650Sstevel@tonic-gate pd->ether_addr_octet[0] = endianswap[ps->ether_addr_octet[0]]; 15660Sstevel@tonic-gate pd->ether_addr_octet[1] = endianswap[ps->ether_addr_octet[1]]; 15670Sstevel@tonic-gate pd->ether_addr_octet[2] = endianswap[ps->ether_addr_octet[2]]; 15680Sstevel@tonic-gate pd->ether_addr_octet[3] = endianswap[ps->ether_addr_octet[3]]; 15690Sstevel@tonic-gate pd->ether_addr_octet[4] = endianswap[ps->ether_addr_octet[4]]; 15700Sstevel@tonic-gate pd->ether_addr_octet[5] = endianswap[ps->ether_addr_octet[5]]; 15710Sstevel@tonic-gate } 15720Sstevel@tonic-gate 15730Sstevel@tonic-gate /* ARGSUSED */ 15740Sstevel@tonic-gate uint_t 1575*10616SSebastien.Roy@Sun.COM ib_header_len(char *hdr, size_t msgsize) 15760Sstevel@tonic-gate { 15770Sstevel@tonic-gate return (IPOIB_HDRSIZE); 15780Sstevel@tonic-gate } 15790Sstevel@tonic-gate 15800Sstevel@tonic-gate static uint_t 15810Sstevel@tonic-gate interpret_ib(int flags, char *header, int elen, int origlen) 15820Sstevel@tonic-gate { 15830Sstevel@tonic-gate struct ipoib_header *hdr = (struct ipoib_header *)header; 15840Sstevel@tonic-gate char *off; 15850Sstevel@tonic-gate int len; 15860Sstevel@tonic-gate unsigned short ethertype; 15870Sstevel@tonic-gate int blen = MAX(origlen, 4096); 15880Sstevel@tonic-gate 15890Sstevel@tonic-gate if (data != NULL && datalen != 0 && datalen < blen) { 15900Sstevel@tonic-gate free(data); 15910Sstevel@tonic-gate data = NULL; 15920Sstevel@tonic-gate datalen = 0; 15930Sstevel@tonic-gate } 15940Sstevel@tonic-gate if (data == NULL) { 15950Sstevel@tonic-gate data = malloc(blen); 15960Sstevel@tonic-gate if (data == NULL) 15970Sstevel@tonic-gate pr_err("Warning: malloc failure"); 15980Sstevel@tonic-gate datalen = blen; 15990Sstevel@tonic-gate } 16000Sstevel@tonic-gate if (origlen < IPOIB_HDRSIZE) { 16010Sstevel@tonic-gate if (flags & F_SUM) 16020Sstevel@tonic-gate (void) snprintf(get_sum_line(), MAXLINE, 16038023SPhil.Kirk@Sun.COM "RUNT (short packet - %d bytes)", origlen); 16040Sstevel@tonic-gate if (flags & F_DTAIL) 16050Sstevel@tonic-gate show_header("RUNT: ", "Short packet", origlen); 16060Sstevel@tonic-gate return (elen); 16070Sstevel@tonic-gate } 16080Sstevel@tonic-gate if (elen < IPOIB_HDRSIZE) 16090Sstevel@tonic-gate return (elen); 16100Sstevel@tonic-gate 16110Sstevel@tonic-gate /* 16120Sstevel@tonic-gate * It is not possible to understand just by looking 16130Sstevel@tonic-gate * at the header whether this was a broad/multi cast 16140Sstevel@tonic-gate * packet; thus dst_name is not updated. 16150Sstevel@tonic-gate */ 16160Sstevel@tonic-gate ethertype = ntohs(hdr->ipoib_type); 16170Sstevel@tonic-gate len = elen - IPOIB_HDRSIZE; 16180Sstevel@tonic-gate off = (char *)(hdr + 1); 16190Sstevel@tonic-gate (void) memcpy(data, off, len); 16200Sstevel@tonic-gate 16210Sstevel@tonic-gate if (flags & F_SUM) { 16220Sstevel@tonic-gate (void) snprintf(get_sum_line(), MAXLINE, 16238023SPhil.Kirk@Sun.COM "IPIB Type=%04X (%s), size = %d bytes", 16248023SPhil.Kirk@Sun.COM ethertype, 16258023SPhil.Kirk@Sun.COM print_ethertype(ethertype), 16268023SPhil.Kirk@Sun.COM origlen); 16270Sstevel@tonic-gate } 16280Sstevel@tonic-gate 16290Sstevel@tonic-gate if (flags & F_DTAIL) { 16300Sstevel@tonic-gate show_header("IPIB: ", "IPIB Header", elen); 16310Sstevel@tonic-gate show_space(); 16320Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(), 16338023SPhil.Kirk@Sun.COM "Packet %d arrived at %d:%02d:%d.%02d", 16348023SPhil.Kirk@Sun.COM pi_frame, pi_time_hour, pi_time_min, 16358023SPhil.Kirk@Sun.COM pi_time_sec, pi_time_usec / 10000); 16360Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(), 16378023SPhil.Kirk@Sun.COM "Packet size = %d bytes", elen, elen); 16380Sstevel@tonic-gate (void) snprintf(get_line(0, 2), get_line_remain(), 16398023SPhil.Kirk@Sun.COM "Ethertype = %04X (%s)", ethertype, 16408023SPhil.Kirk@Sun.COM print_ethertype(ethertype)); 16410Sstevel@tonic-gate show_space(); 16420Sstevel@tonic-gate } 16430Sstevel@tonic-gate 16440Sstevel@tonic-gate /* Go to the next protocol layer */ 16450Sstevel@tonic-gate switch (ethertype) { 16460Sstevel@tonic-gate case ETHERTYPE_IP: 16470Sstevel@tonic-gate (void) interpret_ip(flags, (struct ip *)data, len); 16480Sstevel@tonic-gate break; 16490Sstevel@tonic-gate case ETHERTYPE_IPV6: 16500Sstevel@tonic-gate (void) interpret_ipv6(flags, (ip6_t *)data, len); 16510Sstevel@tonic-gate break; 16520Sstevel@tonic-gate case ETHERTYPE_ARP: 16530Sstevel@tonic-gate case ETHERTYPE_REVARP: 16540Sstevel@tonic-gate interpret_arp(flags, (struct arphdr *)data, len); 16550Sstevel@tonic-gate break; 16560Sstevel@tonic-gate } 16570Sstevel@tonic-gate 16580Sstevel@tonic-gate return (elen); 16590Sstevel@tonic-gate } 16608023SPhil.Kirk@Sun.COM 1661*10616SSebastien.Roy@Sun.COM /* ARGSUSED */ 16628023SPhil.Kirk@Sun.COM uint_t 1663*10616SSebastien.Roy@Sun.COM ipnet_header_len(char *hdr, size_t msgsize) 16648023SPhil.Kirk@Sun.COM { 16658023SPhil.Kirk@Sun.COM return (sizeof (dl_ipnetinfo_t)); 16668023SPhil.Kirk@Sun.COM } 16678023SPhil.Kirk@Sun.COM 16688023SPhil.Kirk@Sun.COM #define MAX_UINT64_STR 22 16698023SPhil.Kirk@Sun.COM static uint_t 16708023SPhil.Kirk@Sun.COM interpret_ipnet(int flags, char *header, int elen, int origlen) 16718023SPhil.Kirk@Sun.COM { 16728023SPhil.Kirk@Sun.COM dl_ipnetinfo_t dl; 16738023SPhil.Kirk@Sun.COM size_t len = elen - sizeof (dl_ipnetinfo_t); 16748023SPhil.Kirk@Sun.COM char *off = (char *)header + sizeof (dl_ipnetinfo_t); 16758023SPhil.Kirk@Sun.COM int blen = MAX(origlen, 8252); 16768023SPhil.Kirk@Sun.COM char szone[MAX_UINT64_STR]; 16778023SPhil.Kirk@Sun.COM char dzone[MAX_UINT64_STR]; 16788023SPhil.Kirk@Sun.COM 16798023SPhil.Kirk@Sun.COM (void) memcpy(&dl, header, sizeof (dl)); 16808023SPhil.Kirk@Sun.COM if (data != NULL && datalen != 0 && datalen < blen) { 16818023SPhil.Kirk@Sun.COM free(data); 16828023SPhil.Kirk@Sun.COM data = NULL; 16838023SPhil.Kirk@Sun.COM datalen = 0; 16848023SPhil.Kirk@Sun.COM } 16858023SPhil.Kirk@Sun.COM if (data == NULL) { 16868023SPhil.Kirk@Sun.COM data = (char *)malloc(blen); 16878023SPhil.Kirk@Sun.COM if (!data) 16888023SPhil.Kirk@Sun.COM pr_err("Warning: malloc failure"); 16898023SPhil.Kirk@Sun.COM datalen = blen; 16908023SPhil.Kirk@Sun.COM } 16918023SPhil.Kirk@Sun.COM 16928023SPhil.Kirk@Sun.COM if (dl.dli_srczone == ALL_ZONES) 16938023SPhil.Kirk@Sun.COM sprintf(szone, "Unknown"); 16948023SPhil.Kirk@Sun.COM else 16958023SPhil.Kirk@Sun.COM sprintf(szone, "%llu", BE_64(dl.dli_srczone)); 16968023SPhil.Kirk@Sun.COM 16978023SPhil.Kirk@Sun.COM if (dl.dli_dstzone == ALL_ZONES) 16988023SPhil.Kirk@Sun.COM sprintf(dzone, "Unknown"); 16998023SPhil.Kirk@Sun.COM else 17008023SPhil.Kirk@Sun.COM sprintf(dzone, "%llu", BE_64(dl.dli_dstzone)); 17018023SPhil.Kirk@Sun.COM 17028023SPhil.Kirk@Sun.COM if (flags & F_SUM) { 17038023SPhil.Kirk@Sun.COM (void) snprintf(get_sum_line(), MAXLINE, 17048023SPhil.Kirk@Sun.COM "IPNET src zone %s dst zone %s", szone, dzone); 17058023SPhil.Kirk@Sun.COM } 17068023SPhil.Kirk@Sun.COM 17078023SPhil.Kirk@Sun.COM if (flags & F_DTAIL) { 17088023SPhil.Kirk@Sun.COM show_header("IPNET: ", "IPNET Header", elen); 17098023SPhil.Kirk@Sun.COM show_space(); 17108023SPhil.Kirk@Sun.COM (void) sprintf(get_line(0, 0), 17118023SPhil.Kirk@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d", 17128023SPhil.Kirk@Sun.COM pi_frame, 17138023SPhil.Kirk@Sun.COM pi_time_hour, pi_time_min, pi_time_sec, 17148023SPhil.Kirk@Sun.COM pi_time_usec / 10); 17158023SPhil.Kirk@Sun.COM (void) sprintf(get_line(0, 0), 17168023SPhil.Kirk@Sun.COM "Packet size = %d bytes", 17178023SPhil.Kirk@Sun.COM elen); 17188023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 0), get_line_remain(), 17198023SPhil.Kirk@Sun.COM "dli_version = %d", dl.dli_version); 17208023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 0), get_line_remain(), 17218023SPhil.Kirk@Sun.COM "dli_type = %d", dl.dli_ipver); 17228023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 2), get_line_remain(), 17238023SPhil.Kirk@Sun.COM "dli_srczone = %s", szone); 17248023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 2), get_line_remain(), 17258023SPhil.Kirk@Sun.COM "dli_dstzone = %s", dzone); 17268023SPhil.Kirk@Sun.COM show_space(); 17278023SPhil.Kirk@Sun.COM } 17288023SPhil.Kirk@Sun.COM memcpy(data, off, len); 17298023SPhil.Kirk@Sun.COM 17308023SPhil.Kirk@Sun.COM switch (dl.dli_ipver) { 17318023SPhil.Kirk@Sun.COM case IPV4_VERSION: 17328023SPhil.Kirk@Sun.COM (void) interpret_ip(flags, (struct ip *)data, len); 17338023SPhil.Kirk@Sun.COM break; 17348023SPhil.Kirk@Sun.COM case IPV6_VERSION: 17358023SPhil.Kirk@Sun.COM (void) interpret_ipv6(flags, (ip6_t *)data, len); 17368023SPhil.Kirk@Sun.COM break; 17378023SPhil.Kirk@Sun.COM default: 17388023SPhil.Kirk@Sun.COM break; 17398023SPhil.Kirk@Sun.COM } 17408023SPhil.Kirk@Sun.COM 17418023SPhil.Kirk@Sun.COM return (0); 17428023SPhil.Kirk@Sun.COM } 1743*10616SSebastien.Roy@Sun.COM 1744*10616SSebastien.Roy@Sun.COM uint_t 1745*10616SSebastien.Roy@Sun.COM ipv4_header_len(char *hdr, size_t msgsize) 1746*10616SSebastien.Roy@Sun.COM { 1747*10616SSebastien.Roy@Sun.COM return (msgsize < sizeof (ipha_t) ? 0 : IPH_HDR_LENGTH((ipha_t *)hdr)); 1748*10616SSebastien.Roy@Sun.COM } 1749*10616SSebastien.Roy@Sun.COM 1750*10616SSebastien.Roy@Sun.COM /* 1751*10616SSebastien.Roy@Sun.COM * The header length needs to include all potential extension headers, as the 1752*10616SSebastien.Roy@Sun.COM * caller expects to use this length as an offset to the inner network layer 1753*10616SSebastien.Roy@Sun.COM * header to be used as a filter offset. IPsec headers aren't passed up here, 1754*10616SSebastien.Roy@Sun.COM * and neither are fragmentation headers. 1755*10616SSebastien.Roy@Sun.COM */ 1756*10616SSebastien.Roy@Sun.COM uint_t 1757*10616SSebastien.Roy@Sun.COM ipv6_header_len(char *hdr, size_t msgsize) 1758*10616SSebastien.Roy@Sun.COM { 1759*10616SSebastien.Roy@Sun.COM ip6_t *ip6hdr = (ip6_t *)hdr; 1760*10616SSebastien.Roy@Sun.COM ip6_hbh_t *exthdr; 1761*10616SSebastien.Roy@Sun.COM uint_t hdrlen = sizeof (ip6_t), exthdrlen; 1762*10616SSebastien.Roy@Sun.COM char *pptr; 1763*10616SSebastien.Roy@Sun.COM uint8_t nxt; 1764*10616SSebastien.Roy@Sun.COM 1765*10616SSebastien.Roy@Sun.COM if (msgsize < sizeof (ip6_t)) 1766*10616SSebastien.Roy@Sun.COM return (0); 1767*10616SSebastien.Roy@Sun.COM 1768*10616SSebastien.Roy@Sun.COM nxt = ip6hdr->ip6_nxt; 1769*10616SSebastien.Roy@Sun.COM pptr = (char *)(ip6hdr + 1); 1770*10616SSebastien.Roy@Sun.COM 1771*10616SSebastien.Roy@Sun.COM while (nxt != IPPROTO_ENCAP && nxt != IPPROTO_IPV6) { 1772*10616SSebastien.Roy@Sun.COM switch (nxt) { 1773*10616SSebastien.Roy@Sun.COM case IPPROTO_HOPOPTS: 1774*10616SSebastien.Roy@Sun.COM case IPPROTO_DSTOPTS: 1775*10616SSebastien.Roy@Sun.COM case IPPROTO_ROUTING: 1776*10616SSebastien.Roy@Sun.COM if (msgsize < hdrlen + sizeof (ip6_hbh_t)) 1777*10616SSebastien.Roy@Sun.COM return (0); 1778*10616SSebastien.Roy@Sun.COM exthdr = (ip6_hbh_t *)pptr; 1779*10616SSebastien.Roy@Sun.COM exthdrlen = 8 + exthdr->ip6h_len * 8; 1780*10616SSebastien.Roy@Sun.COM hdrlen += exthdrlen; 1781*10616SSebastien.Roy@Sun.COM pptr += exthdrlen; 1782*10616SSebastien.Roy@Sun.COM nxt = exthdr->ip6h_nxt; 1783*10616SSebastien.Roy@Sun.COM break; 1784*10616SSebastien.Roy@Sun.COM default: 1785*10616SSebastien.Roy@Sun.COM /* 1786*10616SSebastien.Roy@Sun.COM * This is garbage, there's no way to know where the 1787*10616SSebastien.Roy@Sun.COM * inner IP header is. 1788*10616SSebastien.Roy@Sun.COM */ 1789*10616SSebastien.Roy@Sun.COM return (0); 1790*10616SSebastien.Roy@Sun.COM } 1791*10616SSebastien.Roy@Sun.COM } 1792*10616SSebastien.Roy@Sun.COM 1793*10616SSebastien.Roy@Sun.COM return (hdrlen); 1794*10616SSebastien.Roy@Sun.COM } 1795*10616SSebastien.Roy@Sun.COM 1796*10616SSebastien.Roy@Sun.COM /* ARGSUSED */ 1797*10616SSebastien.Roy@Sun.COM uint_t 1798*10616SSebastien.Roy@Sun.COM interpret_iptun(int flags, char *header, int elen, int origlen) 1799*10616SSebastien.Roy@Sun.COM { 1800*10616SSebastien.Roy@Sun.COM (void) interpret_ip(flags, (struct ip *)header, elen); 1801*10616SSebastien.Roy@Sun.COM return (elen); 1802*10616SSebastien.Roy@Sun.COM } 1803