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>
4510616SSebastien.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
5510616SSebastien.Roy@Sun.COM static headerlen_fn_t ether_header_len, fddi_header_len, tr_header_len,
5610616SSebastien.Roy@Sun.COM ib_header_len, ipnet_header_len, ipv4_header_len, ipv6_header_len;
5710616SSebastien.Roy@Sun.COM static interpreter_fn_t interpret_ether, interpret_fddi, interpret_tr,
5810616SSebastien.Roy@Sun.COM interpret_ib, interpret_ipnet, interpret_iptun;
590Sstevel@tonic-gate static void addr_copy_swap(struct ether_addr *, struct ether_addr *);
6010616SSebastien.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
8910616SSebastien.Roy@Sun.COM /* IPv4 tunnel */
9010616SSebastien.Roy@Sun.COM { DL_IPV4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
9110616SSebastien.Roy@Sun.COM ipv4_header_len, interpret_iptun, B_FALSE },
9210616SSebastien.Roy@Sun.COM
9310616SSebastien.Roy@Sun.COM /* IPv6 tunnel */
9410616SSebastien.Roy@Sun.COM { DL_IPV6, 0, 40, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
9510616SSebastien.Roy@Sun.COM ipv6_header_len, interpret_iptun, B_FALSE },
9610616SSebastien.Roy@Sun.COM
9710616SSebastien.Roy@Sun.COM /* 6to4 tunnel */
9810616SSebastien.Roy@Sun.COM { DL_6TO4, 0, 9, 1, IPPROTO_ENCAP, IPPROTO_IPV6,
9910616SSebastien.Roy@Sun.COM ipv4_header_len, interpret_iptun, B_FALSE },
10010616SSebastien.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
interpret_ether(int flags,char * header,int elen,int origlen)12610616SSebastien.Roy@Sun.COM interpret_ether(int flags, char *header, int elen, int origlen)
1270Sstevel@tonic-gate {
12810616SSebastien.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) {
15210616SSebastien.Roy@Sun.COM if (flags & F_SUM) {
1530Sstevel@tonic-gate (void) sprintf(get_sum_line(),
15410616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)",
15510616SSebastien.Roy@Sun.COM origlen);
15610616SSebastien.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
ether_header_len(char * e,size_t msgsize)38810616SSebastien.Roy@Sun.COM ether_header_len(char *e, size_t msgsize)
3890Sstevel@tonic-gate {
3902760Sdg199075 uint16_t ether_type = 0;
39110616SSebastien.Roy@Sun.COM
39210616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct ether_header))
39310616SSebastien.Roy@Sun.COM return (0);
39410616SSebastien.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 *
print_fc(uint_t type)64110616SSebastien.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 *
print_smtclass(uint_t type)65310616SSebastien.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 *
print_smttype(uint_t type)67310616SSebastien.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 *
print_ethertype(int type)68410616SSebastien.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 *
print_sr(struct tr_ri * rh)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
interpret_tr(int flags,caddr_t e,int elen,int origlen)80710616SSebastien.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) {
83410616SSebastien.Roy@Sun.COM if (flags & F_SUM) {
8350Sstevel@tonic-gate (void) sprintf(get_sum_line(),
83610616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)",
83710616SSebastien.Roy@Sun.COM origlen);
83810616SSebastien.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 &&
85310616SSebastien.Roy@Sun.COM snaphdr->s_lsap == LSAP_SNAP &&
85410616SSebastien.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,
86310616SSebastien.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) {
90510616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "TR LLC w/SNAP "
90610616SSebastien.Roy@Sun.COM "Type=%04X (%s), size=%d bytes",
90710616SSebastien.Roy@Sun.COM ethertype,
90810616SSebastien.Roy@Sun.COM print_ethertype(ethertype),
90910616SSebastien.Roy@Sun.COM origlen);
9100Sstevel@tonic-gate } else {
91110616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "TR LLC, but no "
91210616SSebastien.Roy@Sun.COM "SNAP encoding, size = %d bytes",
91310616SSebastien.Roy@Sun.COM origlen);
9140Sstevel@tonic-gate }
9150Sstevel@tonic-gate } else {
9160Sstevel@tonic-gate (void) sprintf(get_sum_line(),
91710616SSebastien.Roy@Sun.COM "TR MAC FC=%02X (%s), size = %d bytes",
91810616SSebastien.Roy@Sun.COM fc, print_fc(fc), origlen);
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate }
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate if (flags & F_DTAIL) {
92310616SSebastien.Roy@Sun.COM show_header("TR: ", "TR Header", elen);
92410616SSebastien.Roy@Sun.COM show_space();
92510616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0),
92610616SSebastien.Roy@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d",
92710616SSebastien.Roy@Sun.COM pi_frame,
92810616SSebastien.Roy@Sun.COM pi_time_hour, pi_time_min, pi_time_sec,
92910616SSebastien.Roy@Sun.COM pi_time_usec / 10);
93010616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0),
93110616SSebastien.Roy@Sun.COM "Packet size = %d bytes",
93210616SSebastien.Roy@Sun.COM elen);
93310616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 1),
93410616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)",
93510616SSebastien.Roy@Sun.COM fc, print_fc(fc));
93610616SSebastien.Roy@Sun.COM (void) sprintf(get_line(2, 6),
93710616SSebastien.Roy@Sun.COM "Destination = %s, %s",
93810616SSebastien.Roy@Sun.COM printether(&mh->dhost),
93910616SSebastien.Roy@Sun.COM print_etherinfo(&mh->dhost));
94010616SSebastien.Roy@Sun.COM (void) sprintf(get_line(8, 6),
94110616SSebastien.Roy@Sun.COM "Source = %s, %s",
94210616SSebastien.Roy@Sun.COM printether(&mh->shost),
94310616SSebastien.Roy@Sun.COM print_etherinfo(&mh->shost));
94410616SSebastien.Roy@Sun.COM
94510616SSebastien.Roy@Sun.COM if (source_routing)
94610616SSebastien.Roy@Sun.COM sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh));
9470Sstevel@tonic-gate
94810616SSebastien.Roy@Sun.COM if (is_llc) {
94910616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen, 1),
95010616SSebastien.Roy@Sun.COM "Dest Service Access Point = %02x",
95110616SSebastien.Roy@Sun.COM snaphdr->d_lsap);
95210616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+1, 1),
95310616SSebastien.Roy@Sun.COM "Source Service Access Point = %02x",
95410616SSebastien.Roy@Sun.COM snaphdr->s_lsap);
95510616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+2, 1),
95610616SSebastien.Roy@Sun.COM "Control = %02x",
95710616SSebastien.Roy@Sun.COM snaphdr->control);
95810616SSebastien.Roy@Sun.COM if (is_snap) {
95910616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+3, 3),
96010616SSebastien.Roy@Sun.COM "SNAP Protocol Id = %02x%02x%02x",
96110616SSebastien.Roy@Sun.COM snaphdr->org[0], snaphdr->org[1],
96210616SSebastien.Roy@Sun.COM snaphdr->org[2]);
96310616SSebastien.Roy@Sun.COM }
96410616SSebastien.Roy@Sun.COM }
9650Sstevel@tonic-gate
96610616SSebastien.Roy@Sun.COM if (is_snap) {
96710616SSebastien.Roy@Sun.COM (void) sprintf(get_line(maclen+6, 2),
96810616SSebastien.Roy@Sun.COM "SNAP Type = %04X (%s)",
96910616SSebastien.Roy@Sun.COM ethertype, print_ethertype(ethertype));
97010616SSebastien.Roy@Sun.COM }
9710Sstevel@tonic-gate
97210616SSebastien.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 */
101010616SSebastien.Roy@Sun.COM static int
tr_machdr_len(char * e,int * lenp,int * source_routing)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
tr_header_len(char * e,size_t msgsize)103610616SSebastien.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
104410616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct llc_snap_hdr))
104510616SSebastien.Roy@Sun.COM return (0);
104610616SSebastien.Roy@Sun.COM
10470Sstevel@tonic-gate snaphdr = (struct llc_snap_hdr *)(e + len);
10480Sstevel@tonic-gate if (snaphdr->d_lsap == LSAP_SNAP &&
104910616SSebastien.Roy@Sun.COM snaphdr->s_lsap == LSAP_SNAP &&
105010616SSebastien.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
interpret_fddi(int flags,caddr_t e,int elen,int origlen)106610616SSebastien.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) {
109010616SSebastien.Roy@Sun.COM if (flags & F_SUM) {
10910Sstevel@tonic-gate (void) sprintf(get_sum_line(),
109210616SSebastien.Roy@Sun.COM "RUNT (short packet - %d bytes)",
109310616SSebastien.Roy@Sun.COM origlen);
109410616SSebastien.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(),
116410616SSebastien.Roy@Sun.COM "FDDI LLC Type=%04X (%s), size = %d bytes",
116510616SSebastien.Roy@Sun.COM ethertype,
116610616SSebastien.Roy@Sun.COM print_ethertype(ethertype),
116710616SSebastien.Roy@Sun.COM origlen);
11680Sstevel@tonic-gate } else {
116910616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "LLC, but no "
117010616SSebastien.Roy@Sun.COM "SNAP encoding, size = %d bytes",
117110616SSebastien.Roy@Sun.COM origlen);
11720Sstevel@tonic-gate }
11730Sstevel@tonic-gate } else if (is_smt) {
117410616SSebastien.Roy@Sun.COM (void) sprintf(get_sum_line(), "SMT Type=%02X (%s), "
117510616SSebastien.Roy@Sun.COM "Class = %02X (%s), size = %d bytes",
117610616SSebastien.Roy@Sun.COM *(uchar_t *)(data+1), print_smttype(*(data+1)),
117710616SSebastien.Roy@Sun.COM *data, print_smtclass(*data), origlen);
11780Sstevel@tonic-gate } else {
11790Sstevel@tonic-gate (void) sprintf(get_sum_line(),
118010616SSebastien.Roy@Sun.COM "FC=%02X (%s), size = %d bytes",
118110616SSebastien.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) {
118610616SSebastien.Roy@Sun.COM show_header("FDDI: ", "FDDI Header", elen);
118710616SSebastien.Roy@Sun.COM show_space();
118810616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0),
118910616SSebastien.Roy@Sun.COM "Packet %d arrived at %d:%02d:%d.%05d",
119010616SSebastien.Roy@Sun.COM pi_frame,
119110616SSebastien.Roy@Sun.COM pi_time_hour, pi_time_min, pi_time_sec,
119210616SSebastien.Roy@Sun.COM pi_time_usec / 10);
119310616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 0),
119410616SSebastien.Roy@Sun.COM "Packet size = %d bytes",
119510616SSebastien.Roy@Sun.COM elen, elen);
119610616SSebastien.Roy@Sun.COM (void) sprintf(get_line(0, 6),
119710616SSebastien.Roy@Sun.COM "Destination = %s, %s",
119810616SSebastien.Roy@Sun.COM printether(&f->dhost),
119910616SSebastien.Roy@Sun.COM print_etherinfo(&f->dhost));
120010616SSebastien.Roy@Sun.COM (void) sprintf(get_line(6, 6),
120110616SSebastien.Roy@Sun.COM "Source = %s, %s",
120210616SSebastien.Roy@Sun.COM printether(&f->shost),
120310616SSebastien.Roy@Sun.COM print_etherinfo(&f->shost));
12040Sstevel@tonic-gate
120510616SSebastien.Roy@Sun.COM if (is_llc) {
120610616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
120710616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)",
120810616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc));
120910616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
121010616SSebastien.Roy@Sun.COM "Dest Service Access Point = %02x",
121110616SSebastien.Roy@Sun.COM f->dsap);
121210616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
121310616SSebastien.Roy@Sun.COM "Source Service Access Point = %02x",
121410616SSebastien.Roy@Sun.COM f->ssap);
121510616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
121610616SSebastien.Roy@Sun.COM "Control = %02x",
121710616SSebastien.Roy@Sun.COM f->ctl);
121810616SSebastien.Roy@Sun.COM if (is_snap) {
121910616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
122010616SSebastien.Roy@Sun.COM "Protocol Id = %02x%02x%02x",
122110616SSebastien.Roy@Sun.COM f->proto_id[0], f->proto_id[1],
122210616SSebastien.Roy@Sun.COM f->proto_id[2]);
122310616SSebastien.Roy@Sun.COM }
122410616SSebastien.Roy@Sun.COM } else if (is_smt) {
12250Sstevel@tonic-gate (void) sprintf(get_line(12, 2),
122610616SSebastien.Roy@Sun.COM "Frame Control = %02x (%s)",
122710616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc));
122810616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
122910616SSebastien.Roy@Sun.COM "Class = %02x (%s)",
123010616SSebastien.Roy@Sun.COM (uchar_t)*data, print_smtclass(*data));
123110616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
123210616SSebastien.Roy@Sun.COM "Type = %02x (%s)",
123310616SSebastien.Roy@Sun.COM *(uchar_t *)(data+1), print_smttype(*(data+1)));
123410616SSebastien.Roy@Sun.COM } else {
123510616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
123610616SSebastien.Roy@Sun.COM "FC=%02X (%s), size = %d bytes",
123710616SSebastien.Roy@Sun.COM f->fc, print_fc(f->fc), origlen);
123810616SSebastien.Roy@Sun.COM }
12390Sstevel@tonic-gate
124010616SSebastien.Roy@Sun.COM if (is_snap) {
124110616SSebastien.Roy@Sun.COM (void) sprintf(get_line(12, 2),
124210616SSebastien.Roy@Sun.COM "LLC Type = %04X (%s)",
124310616SSebastien.Roy@Sun.COM ethertype, print_ethertype(ethertype));
124410616SSebastien.Roy@Sun.COM }
12450Sstevel@tonic-gate
124610616SSebastien.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
fddi_header_len(char * e,size_t msgsize)127310616SSebastien.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
127710616SSebastien.Roy@Sun.COM if (msgsize < sizeof (struct fddi_header))
127810616SSebastien.Roy@Sun.COM return (0);
127910616SSebastien.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 *
printether(struct ether_addr * p)130510616SSebastien.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",
131010616SSebastien.Roy@Sun.COM p->ether_addr_octet[0],
131110616SSebastien.Roy@Sun.COM p->ether_addr_octet[1],
131210616SSebastien.Roy@Sun.COM p->ether_addr_octet[2],
131310616SSebastien.Roy@Sun.COM p->ether_addr_octet[3],
131410616SSebastien.Roy@Sun.COM p->ether_addr_octet[4],
131510616SSebastien.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 *
ether_ouiname(uint32_t oui)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 *
print_etherinfo(struct ether_addr * eaddr)150710616SSebastien.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
addr_copy_swap(struct ether_addr * pd,struct ether_addr * ps)156310616SSebastien.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
ib_header_len(char * hdr,size_t msgsize)157510616SSebastien.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
interpret_ib(int flags,char * header,int elen,int origlen)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
166110616SSebastien.Roy@Sun.COM /* ARGSUSED */
16628023SPhil.Kirk@Sun.COM uint_t
ipnet_header_len(char * hdr,size_t msgsize)166310616SSebastien.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
interpret_ipnet(int flags,char * header,int elen,int origlen)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
1692*10639SDarren.Reed@Sun.COM if (dl.dli_zsrc == ALL_ZONES)
16938023SPhil.Kirk@Sun.COM sprintf(szone, "Unknown");
16948023SPhil.Kirk@Sun.COM else
1695*10639SDarren.Reed@Sun.COM sprintf(szone, "%lu", BE_32(dl.dli_zsrc));
16968023SPhil.Kirk@Sun.COM
1697*10639SDarren.Reed@Sun.COM if (dl.dli_zdst == ALL_ZONES)
16988023SPhil.Kirk@Sun.COM sprintf(dzone, "Unknown");
16998023SPhil.Kirk@Sun.COM else
1700*10639SDarren.Reed@Sun.COM sprintf(dzone, "%lu", BE_32(dl.dli_zdst));
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(),
1721*10639SDarren.Reed@Sun.COM "dli_family = %d", dl.dli_family);
17228023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 2), get_line_remain(),
1723*10639SDarren.Reed@Sun.COM "dli_zsrc = %s", szone);
17248023SPhil.Kirk@Sun.COM (void) snprintf(get_line(0, 2), get_line_remain(),
1725*10639SDarren.Reed@Sun.COM "dli_zdst = %s", dzone);
17268023SPhil.Kirk@Sun.COM show_space();
17278023SPhil.Kirk@Sun.COM }
17288023SPhil.Kirk@Sun.COM memcpy(data, off, len);
17298023SPhil.Kirk@Sun.COM
1730*10639SDarren.Reed@Sun.COM switch (dl.dli_family) {
1731*10639SDarren.Reed@Sun.COM case AF_INET:
17328023SPhil.Kirk@Sun.COM (void) interpret_ip(flags, (struct ip *)data, len);
17338023SPhil.Kirk@Sun.COM break;
1734*10639SDarren.Reed@Sun.COM case AF_INET6:
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 }
174310616SSebastien.Roy@Sun.COM
174410616SSebastien.Roy@Sun.COM uint_t
ipv4_header_len(char * hdr,size_t msgsize)174510616SSebastien.Roy@Sun.COM ipv4_header_len(char *hdr, size_t msgsize)
174610616SSebastien.Roy@Sun.COM {
174710616SSebastien.Roy@Sun.COM return (msgsize < sizeof (ipha_t) ? 0 : IPH_HDR_LENGTH((ipha_t *)hdr));
174810616SSebastien.Roy@Sun.COM }
174910616SSebastien.Roy@Sun.COM
175010616SSebastien.Roy@Sun.COM /*
175110616SSebastien.Roy@Sun.COM * The header length needs to include all potential extension headers, as the
175210616SSebastien.Roy@Sun.COM * caller expects to use this length as an offset to the inner network layer
175310616SSebastien.Roy@Sun.COM * header to be used as a filter offset. IPsec headers aren't passed up here,
175410616SSebastien.Roy@Sun.COM * and neither are fragmentation headers.
175510616SSebastien.Roy@Sun.COM */
175610616SSebastien.Roy@Sun.COM uint_t
ipv6_header_len(char * hdr,size_t msgsize)175710616SSebastien.Roy@Sun.COM ipv6_header_len(char *hdr, size_t msgsize)
175810616SSebastien.Roy@Sun.COM {
175910616SSebastien.Roy@Sun.COM ip6_t *ip6hdr = (ip6_t *)hdr;
176010616SSebastien.Roy@Sun.COM ip6_hbh_t *exthdr;
176110616SSebastien.Roy@Sun.COM uint_t hdrlen = sizeof (ip6_t), exthdrlen;
176210616SSebastien.Roy@Sun.COM char *pptr;
176310616SSebastien.Roy@Sun.COM uint8_t nxt;
176410616SSebastien.Roy@Sun.COM
176510616SSebastien.Roy@Sun.COM if (msgsize < sizeof (ip6_t))
176610616SSebastien.Roy@Sun.COM return (0);
176710616SSebastien.Roy@Sun.COM
176810616SSebastien.Roy@Sun.COM nxt = ip6hdr->ip6_nxt;
176910616SSebastien.Roy@Sun.COM pptr = (char *)(ip6hdr + 1);
177010616SSebastien.Roy@Sun.COM
177110616SSebastien.Roy@Sun.COM while (nxt != IPPROTO_ENCAP && nxt != IPPROTO_IPV6) {
177210616SSebastien.Roy@Sun.COM switch (nxt) {
177310616SSebastien.Roy@Sun.COM case IPPROTO_HOPOPTS:
177410616SSebastien.Roy@Sun.COM case IPPROTO_DSTOPTS:
177510616SSebastien.Roy@Sun.COM case IPPROTO_ROUTING:
177610616SSebastien.Roy@Sun.COM if (msgsize < hdrlen + sizeof (ip6_hbh_t))
177710616SSebastien.Roy@Sun.COM return (0);
177810616SSebastien.Roy@Sun.COM exthdr = (ip6_hbh_t *)pptr;
177910616SSebastien.Roy@Sun.COM exthdrlen = 8 + exthdr->ip6h_len * 8;
178010616SSebastien.Roy@Sun.COM hdrlen += exthdrlen;
178110616SSebastien.Roy@Sun.COM pptr += exthdrlen;
178210616SSebastien.Roy@Sun.COM nxt = exthdr->ip6h_nxt;
178310616SSebastien.Roy@Sun.COM break;
178410616SSebastien.Roy@Sun.COM default:
178510616SSebastien.Roy@Sun.COM /*
178610616SSebastien.Roy@Sun.COM * This is garbage, there's no way to know where the
178710616SSebastien.Roy@Sun.COM * inner IP header is.
178810616SSebastien.Roy@Sun.COM */
178910616SSebastien.Roy@Sun.COM return (0);
179010616SSebastien.Roy@Sun.COM }
179110616SSebastien.Roy@Sun.COM }
179210616SSebastien.Roy@Sun.COM
179310616SSebastien.Roy@Sun.COM return (hdrlen);
179410616SSebastien.Roy@Sun.COM }
179510616SSebastien.Roy@Sun.COM
179610616SSebastien.Roy@Sun.COM /* ARGSUSED */
179710616SSebastien.Roy@Sun.COM uint_t
interpret_iptun(int flags,char * header,int elen,int origlen)179810616SSebastien.Roy@Sun.COM interpret_iptun(int flags, char *header, int elen, int origlen)
179910616SSebastien.Roy@Sun.COM {
180010616SSebastien.Roy@Sun.COM (void) interpret_ip(flags, (struct ip *)header, elen);
180110616SSebastien.Roy@Sun.COM return (elen);
180210616SSebastien.Roy@Sun.COM }
1803