4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
32 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/socket.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <netinet/if_ether.h>
41 #include <sys/ib/clients/ibd/ibd.h>
42 #include <sys/ethernet.h>
45 #include <inet/iptun.h>
46 #include <sys/byteorder.h>
50 #include <net/trill.h>
55 static headerlen_fn_t ether_header_len
, fddi_header_len
, tr_header_len
,
56 ib_header_len
, ipnet_header_len
, ipv4_header_len
, ipv6_header_len
;
57 static interpreter_fn_t interpret_ether
, interpret_fddi
, interpret_tr
,
58 interpret_ib
, interpret_ipnet
, interpret_iptun
;
59 static void addr_copy_swap(struct ether_addr
*, struct ether_addr
*);
60 static int tr_machdr_len(char *, int *, int *);
62 interface_t
*interface
;
63 interface_t INTERFACES
[] = {
65 /* IEEE 802.3 CSMA/CD network */
66 { DL_CSMACD
, 1550, 12, 2, ETHERTYPE_IP
, ETHERTYPE_IPV6
,
67 ether_header_len
, interpret_ether
, B_TRUE
},
70 { DL_ETHER
, 1550, 12, 2, ETHERTYPE_IP
, ETHERTYPE_IPV6
,
71 ether_header_len
, interpret_ether
, B_TRUE
},
73 /* Fiber Distributed data interface */
74 { DL_FDDI
, 4500, 19, 2, ETHERTYPE_IP
, ETHERTYPE_IPV6
,
75 fddi_header_len
, interpret_fddi
, B_FALSE
},
77 /* Token Ring interface */
78 { DL_TPR
, 17800, 0, 2, ETHERTYPE_IP
, ETHERTYPE_IPV6
,
79 tr_header_len
, interpret_tr
, B_FALSE
},
82 { DL_IB
, 4096, 0, 2, ETHERTYPE_IP
, ETHERTYPE_IPV6
,
83 ib_header_len
, interpret_ib
, B_TRUE
},
86 { DL_IPNET
, INT_MAX
, 1, 1, IPV4_VERSION
, IPV6_VERSION
,
87 ipnet_header_len
, interpret_ipnet
, B_TRUE
},
90 { DL_IPV4
, 0, 9, 1, IPPROTO_ENCAP
, IPPROTO_IPV6
,
91 ipv4_header_len
, interpret_iptun
, B_FALSE
},
94 { DL_IPV6
, 0, 40, 1, IPPROTO_ENCAP
, IPPROTO_IPV6
,
95 ipv6_header_len
, interpret_iptun
, B_FALSE
},
98 { DL_6TO4
, 0, 9, 1, IPPROTO_ENCAP
, IPPROTO_IPV6
,
99 ipv4_header_len
, interpret_iptun
, B_FALSE
},
101 { (uint_t
)-1, 0, 0, 0, 0, 0, NULL
, B_FALSE
}
105 extern char *dlc_header
;
107 extern int pi_time_hour
;
108 extern int pi_time_min
;
109 extern int pi_time_sec
;
110 extern int pi_time_usec
;
113 char *print_ethertype();
114 static char *print_etherinfo();
117 char *print_smttype();
118 char *print_smtclass();
120 struct ether_addr ether_broadcast
= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
121 static char *data
; /* current data buffer */
122 static int datalen
; /* current data buffer length */
123 static const struct ether_addr all_isis_rbridges
= ALL_ISIS_RBRIDGES
;
126 interpret_ether(int flags
, char *header
, int elen
, int origlen
)
128 struct ether_header
*e
= (struct ether_header
*)header
;
129 uchar_t
*off
, *ieeestart
;
132 extern char *dst_name
;
134 struct ether_vlan_extinfo
*evx
= NULL
;
135 int blen
= MAX(origlen
, ETHERMTU
);
136 boolean_t trillpkt
= B_FALSE
;
139 if (data
!= NULL
&& datalen
!= 0 && datalen
< blen
) {
145 data
= (char *)malloc(blen
);
147 pr_err("Warning: malloc failure");
153 (void) sprintf(get_sum_line(),
154 "RUNT (short packet - %d bytes)",
158 show_header("RUNT: ", "Short packet", origlen
);
164 if (memcmp(&e
->ether_dhost
, ðer_broadcast
,
165 sizeof (struct ether_addr
)) == 0)
166 dst_name
= "(broadcast)";
167 else if (e
->ether_dhost
.ether_addr_octet
[0] & 1)
168 dst_name
= "(multicast)";
170 ethertype
= ntohs(e
->ether_type
);
173 * The 14 byte ether header screws up alignment
174 * of the rest of the packet for 32 bit aligned
175 * architectures like SPARC. Alas, we have to copy
176 * the rest of the packet in order to align it.
178 len
= elen
- sizeof (struct ether_header
);
179 off
= (uchar_t
*)(e
+ 1);
181 if (ethertype
== ETHERTYPE_VLAN
) {
182 if (origlen
< sizeof (struct ether_vlan_header
)) {
184 (void) sprintf(get_sum_line(),
185 "RUNT (short VLAN packet - %d bytes)",
188 if (flags
& F_DTAIL
) {
189 show_header("RUNT: ", "Short VLAN packet",
194 if (len
< sizeof (struct ether_vlan_extinfo
))
197 evx
= (struct ether_vlan_extinfo
*)off
;
198 off
+= sizeof (struct ether_vlan_extinfo
);
199 len
-= sizeof (struct ether_vlan_extinfo
);
201 ethertype
= ntohs(evx
->ether_type
);
202 tci
= ntohs(evx
->ether_tci
);
205 if (ethertype
<= 1514) {
207 * Fake out the IEEE 802.3 packets.
208 * Should be DSAP=0xAA, SSAP=0xAA, control=0x03
209 * then three padding bytes of zero (OUI),
210 * followed by a normal ethernet-type packet.
212 ieee8023
= ethertype
;
214 if (off
[0] == 0xAA && off
[1] == 0xAA) {
215 ethertype
= ntohs(*(ushort_t
*)(off
+ 6));
227 * Set the flag that says don't display VLAN information.
228 * If it needs to change, that will be done later if the
229 * packet is VLAN tagged and if snoop is in its default
234 if (ethertype
== 0 && ieee8023
> 0) {
235 (void) sprintf(get_sum_line(),
236 "ETHER 802.3 SSAP %02X DSAP %02X, "
237 "size=%d bytes", ieeestart
[0], ieeestart
[1],
240 (void) sprintf(get_sum_line(),
241 "ETHER Type=%04X (%s), size=%d bytes",
242 ethertype
, print_ethertype(ethertype
),
246 if (ethertype
== 0 && ieee8023
> 0) {
247 (void) sprintf(get_sum_line(),
248 "ETHER 802.3 SSAP %02X DSAP %02X, "
249 "VLAN ID=%hu, size=%d bytes", ieeestart
[0],
250 ieeestart
[1], VLAN_ID(tci
), origlen
);
252 (void) sprintf(get_sum_line(),
253 "ETHER Type=%04X (%s), VLAN ID=%hu, "
254 "size=%d bytes", ethertype
,
255 print_ethertype(ethertype
), VLAN_ID(tci
),
259 if (!(flags
& F_ALLSUM
))
260 set_vlan_id(VLAN_ID(tci
));
264 if (flags
& F_DTAIL
) {
265 show_header("ETHER: ", "Ether Header", elen
);
268 (void) sprintf(get_line(0, 0),
269 "Packet %d arrived at %d:%02d:%d.%05d",
271 pi_time_hour
, pi_time_min
, pi_time_sec
,
273 (void) sprintf(get_line(0, 0),
274 "Packet size = %d bytes",
277 (void) sprintf(get_line(0, 6),
278 "Destination = %s, %s",
279 printether(&e
->ether_dhost
),
280 print_etherinfo(&e
->ether_dhost
));
281 (void) sprintf(get_line(6, 6),
283 printether(&e
->ether_shost
),
284 print_etherinfo(&e
->ether_shost
));
286 (void) sprintf(get_line(0, 0),
287 "VLAN ID = %hu", VLAN_ID(tci
));
288 (void) sprintf(get_line(0, 0),
289 "VLAN Priority = %hu", VLAN_PRI(tci
));
292 (void) sprintf(get_line(12, 2),
293 "IEEE 802.3 length = %d bytes", ieee8023
);
294 /* Print LLC only for non-TCP/IP packets */
295 if (ethertype
== 0) {
296 (void) snprintf(get_line(0, 0),
298 "SSAP = %02X, DSAP = %02X, CTRL = %02X",
299 ieeestart
[0], ieeestart
[1], ieeestart
[2]);
302 if (ethertype
!= 0 || ieee8023
== 0)
303 (void) sprintf(get_line(12, 2),
304 "Ethertype = %04X (%s)",
305 ethertype
, print_ethertype(ethertype
));
310 * We cannot trust the length field in the header to be correct.
311 * But we should continue to process the packet. Then user can
312 * notice something funny in the header.
313 * Go to the next protocol layer only if data have been
316 if (len
> 0 && (off
+ len
<= (uchar_t
*)e
+ elen
)) {
317 (void) memmove(data
, off
, len
);
319 if (!trillpkt
&& ethertype
== ETHERTYPE_TRILL
) {
320 ethertype
= interpret_trill(flags
, &e
, data
, &len
);
321 /* Decode inner Ethernet frame */
322 if (ethertype
!= 0) {
325 (void) memmove(data
, e
, len
);
326 e
= (struct ether_header
*)data
;
335 (void) interpret_ip(flags
, (struct ip
*)data
, len
);
337 /* Just in case it is decided to add this type */
339 (void) interpret_ipv6(flags
, (ip6_t
*)data
, len
);
342 case ETHERTYPE_REVARP
:
343 interpret_arp(flags
, (struct arphdr
*)data
, len
);
345 case ETHERTYPE_PPPOED
:
346 case ETHERTYPE_PPPOES
:
347 (void) interpret_pppoe(flags
, (poep_t
*)data
, len
);
349 case ETHERTYPE_AARP
: /* AppleTalk */
350 interpret_aarp(flags
, data
, len
);
353 interpret_at(flags
, (struct ddp_hdr
*)data
, len
);
358 switch (ieeestart
[0]) {
360 interpret_isis(flags
, data
, len
,
361 memcmp(&e
->ether_dhost
, &all_isis_rbridges
,
362 sizeof (struct ether_addr
)) == 0);
365 interpret_bpdu(flags
, data
, len
);
376 * Return the length of the ethernet header. In the case
377 * where we have a VLAN tagged packet, return the length of
378 * the ethernet header plus the length of the VLAN tag.
380 * INPUTS: e - A buffer pointer. Passing a NULL pointer
381 * is not allowed, e must be non-NULL.
382 * OUTPUTS: Return the size of an untagged ethernet header
383 * if the packet is not VLAN tagged, and the size
384 * of an untagged ethernet header plus the size of
385 * a VLAN header otherwise.
388 ether_header_len(char *e
, size_t msgsize
)
390 uint16_t ether_type
= 0;
392 if (msgsize
< sizeof (struct ether_header
))
395 e
+= (offsetof(struct ether_header
, ether_type
));
397 GETINT16(ether_type
, e
);
399 if (ether_type
== (uint16_t)ETHERTYPE_VLAN
) {
400 return (sizeof (struct ether_vlan_header
));
402 return (sizeof (struct ether_header
));
408 * Table of Ethertypes.
409 * Some of the more popular entries
410 * are at the beginning of the table
411 * to reduce search time.
418 ETHERTYPE_ARP
, "ARP",
419 ETHERTYPE_REVARP
, "RARP",
420 ETHERTYPE_IPV6
, "IPv6",
421 ETHERTYPE_PPPOED
, "PPPoE Discovery",
422 ETHERTYPE_PPPOES
, "PPPoE Session",
423 ETHERTYPE_TRILL
, "TRILL",
424 /* end of popular entries */
425 ETHERTYPE_PUP
, "Xerox PUP",
428 0x0600, "Xerox NS IDP",
429 0x0601, "XNS Translation",
430 0x0801, "X.75 Internet",
431 0x0802, "NBS Internet",
432 0x0803, "ECMA Internet",
434 0x0805, "X.25 Level 3",
435 0x0807, "XNS Compatibility",
436 0x081C, "Symbolics Private",
440 0x0900, "Ungermann-Bass network debugger",
441 0x0A00, "Xerox IEEE802.3 PUP",
442 0x0A01, "Xerox IEEE802.3 PUP Address Translation",
443 0x0BAD, "Banyan Systems",
444 0x0BAF, "Banyon VINES Echo",
445 0x1000, "Berkeley Trailer negotiation",
446 0x1000, "IP trailer (0)",
447 0x1001, "IP trailer (1)",
448 0x1002, "IP trailer (2)",
449 0x1003, "IP trailer (3)",
450 0x1004, "IP trailer (4)",
451 0x1005, "IP trailer (5)",
452 0x1006, "IP trailer (6)",
453 0x1007, "IP trailer (7)",
454 0x1008, "IP trailer (8)",
455 0x1009, "IP trailer (9)",
456 0x100a, "IP trailer (10)",
457 0x100b, "IP trailer (11)",
458 0x100c, "IP trailer (12)",
459 0x100d, "IP trailer (13)",
460 0x100e, "IP trailer (14)",
461 0x100f, "IP trailer (15)",
462 0x1234, "DCA - Multicast",
463 0x1600, "VALID system protocol",
465 0x3C00, "3Com NBP virtual circuit datagram",
466 0x3C01, "3Com NBP System control datagram",
467 0x3C02, "3Com NBP Connect request (virtual cct)",
468 0x3C03, "3Com NBP Connect response",
469 0x3C04, "3Com NBP Connect complete",
470 0x3C05, "3Com NBP Close request (virtual cct)",
471 0x3C06, "3Com NBP Close response",
472 0x3C07, "3Com NBP Datagram (like XNS IDP)",
473 0x3C08, "3Com NBP Datagram broadcast",
474 0x3C09, "3Com NBP Claim NetBIOS name",
475 0x3C0A, "3Com NBP Delete Netbios name",
476 0x3C0B, "3Com NBP Remote adaptor status request",
477 0x3C0C, "3Com NBP Remote adaptor response",
478 0x3C0D, "3Com NBP Reset",
479 0x4242, "PCS Basic Block Protocol",
480 0x4321, "THD - Diddle",
481 0x5208, "BBN Simnet Private",
482 0x6000, "DEC unass, experimental",
483 0x6001, "DEC Dump/Load",
484 0x6002, "DEC Remote Console",
485 0x6003, "DECNET Phase IV, DNA Routing",
487 0x6005, "DEC Diagnostic",
488 0x6006, "DEC customer protocol",
489 0x6007, "DEC Local Area VAX Cluster (LAVC)",
490 0x6008, "DEC unass (AMBER?)",
491 0x6009, "DEC unass (MUMPS?)",
497 0x7000, "Ungermann-Bass download",
498 0x7001, "Ungermann-Bass NIUs",
499 0x7002, "Ungermann-Bass diagnostic/loopback",
500 0x7003, "Ungermann-Bass ? (NMC to/from UB Bridge)",
501 0x7005, "Ungermann-Bass Bridge Spanning Tree",
502 0x7007, "OS/9 Microware",
514 0x8003, "Cronus VLN",
515 0x8004, "Cronus Direct",
516 0x8005, "HP Probe protocol",
518 0x8008, "AT&T/Stanford Univ",
520 0x8013, "SGI diagnostic",
521 0x8014, "SGI network games",
522 0x8015, "SGI reserved",
523 0x8016, "SGI XNS NameServer, bounce server",
524 0x8019, "Apollo DOMAIN",
527 0x8036, "Aeonic Systems",
528 0x8037, "IPX (Novell Netware)",
529 0x8038, "DEC LanBridge Management",
530 0x8039, "DEC unass (DSM/DTP?)",
531 0x803A, "DEC unass (Argonaut Console?)",
532 0x803B, "DEC unass (VAXELN?)",
533 0x803C, "DEC unass (NMSV? DNA Naming Service?)",
534 0x803D, "DEC Ethernet CSMA/CD Encryption Protocol",
535 0x803E, "DEC unass (DNA Time Service?)",
536 0x803F, "DEC LAN Traffic Monitor Protocol",
537 0x8040, "DEC unass (NetBios Emulator?)",
538 0x8041, "DEC unass (MS/DOS?, Local Area System Transport?)",
540 0x8044, "Planning Research Corp.",
545 0x805C, "Stanford V Kernel, version 6.0",
546 0x805D, "Evans & Sutherland",
547 0x8060, "Little Machines",
548 0x8062, "Counterpoint",
549 0x8065, "University of Mass. at Amherst",
550 0x8066, "University of Mass. at Amherst",
551 0x8067, "Veeco Integrated Automation",
552 0x8068, "General Dynamics",
556 0x806D, "Compugraphic Corp",
568 0x807B, "Dansk Data Elektronik",
569 0x807C, "Merit Internodal",
573 0x8080, "Vitalink TransLAN III Management",
574 0x8081, "Counterpoint",
575 0x8082, "Counterpoint",
576 0x8083, "Counterpoint",
580 0x809B, "EtherTalk (AppleTalk over Ethernet)",
581 0x809C, "Datability",
582 0x809D, "Datability",
583 0x809E, "Datability",
584 0x809F, "Spider Systems",
586 0x80A4, "Siemens Gammasonics",
587 0x80C0, "DCA Data Exchange Cluster",
588 0x80C6, "Pacer Software",
589 0x80C7, "Applitek Corp",
590 0x80C8, "Intergraph",
591 0x80C9, "Intergraph",
592 0x80CB, "Intergraph",
593 0x80CC, "Intergraph",
594 0x80CA, "Intergraph",
595 0x80CD, "Harris Corp",
596 0x80CE, "Harris Corp",
597 0x80CF, "Taylor Instrument",
598 0x80D0, "Taylor Instrument",
599 0x80D1, "Taylor Instrument",
600 0x80D2, "Taylor Instrument",
601 0x80D3, "Rosemount Corp",
602 0x80D4, "Rosemount Corp",
603 0x80D5, "IBM SNA Services over Ethernet",
604 0x80DD, "Varian Associates",
607 0x80E0, "Allen-Bradley",
608 0x80E1, "Allen-Bradley",
609 0x80E2, "Allen-Bradley",
610 0x80E3, "Allen-Bradley",
611 0x80E4, "Datability",
613 0x80F3, "AARP (Appletalk)",
617 0x80FF, "Wellfleet Communications",
618 0x8102, "Wellfleet Communications",
619 0x8107, "Symbolics Private",
620 0x8108, "Symbolics Private",
621 0x8109, "Symbolics Private",
625 0x8137, "Novell (old) NetWare IPX",
627 0x814C, "SNMP over Ethernet",
630 0x8888, "HP LanProbe test?",
632 0x9001, "3Com, XNS Systems Management",
633 0x9002, "3Com, TCP/IP Systems Management",
634 0x9003, "3Com, loopback detection",
635 0xAAAA, "DECNET (VAX 6220 DEBNI)",
636 0xFF00, "BBN VITAL-LanBridge cache wakeups",
641 print_fc(uint_t type
)
645 case 0x50: return ("LLC");
646 case 0x4f: return ("SMT NSA");
647 case 0x41: return ("SMT Info");
648 default: return ("Unknown");
653 print_smtclass(uint_t type
)
656 case 0x01: return ("NIF");
657 case 0x02: return ("SIF Conf");
658 case 0x03: return ("SIF Oper");
659 case 0x04: return ("ECF");
660 case 0x05: return ("RAF");
661 case 0x06: return ("RDF");
662 case 0x07: return ("SRF");
663 case 0x08: return ("PMF Get");
664 case 0x09: return ("PMF Change");
665 case 0x0a: return ("PMF Add");
666 case 0x0b: return ("PMF Remove");
667 case 0xff: return ("ESF");
668 default: return ("Unknown");
673 print_smttype(uint_t type
)
676 case 0x01: return ("Announce");
677 case 0x02: return ("Request");
678 case 0x03: return ("Response");
679 default: return ("Unknown");
684 print_ethertype(int type
)
688 for (i
= 0; ether_type
[i
].e_type
; i
++)
689 if (type
== ether_type
[i
].e_type
)
690 return (ether_type
[i
].e_name
);
692 return ("LLC/802.3");
697 #define MAX_RDFLDS 14 /* changed to 14 from 8 as per IEEE */
698 #define TR_FN_ADDR 0x80 /* dest addr is functional */
699 #define TR_SR_ADDR 0x80 /* MAC utilizes source route */
700 #define ACFCDASA_LEN 14 /* length of AC|FC|DA|SA */
701 #define TR_MAC_MASK 0xc0
702 #define TR_AC 0x00 /* Token Ring access control */
703 #define TR_LLC_FC 0x40 /* Token Ring llc frame control */
704 #define LSAP_SNAP 0xaa
705 #define LLC_SNAP_HDR_LEN 8
706 #define LLC_HDR1_LEN 3 /* DON'T use sizeof(struct llc_hdr1) */
707 #define CNTL_LLC_UI 0x03 /* un-numbered information packet */
710 * Source Routing Route Information field.
713 #if defined(_BIT_FIELDS_HTOL)
714 uchar_t rt
:3; /* routing type */
715 uchar_t len
:5; /* length */
716 uchar_t dir
:1; /* direction bit */
717 uchar_t mtu
:3; /* largest frame */
718 uchar_t res
:4; /* reserved */
719 #elif defined(_BIT_FIELDS_LTOH)
720 uchar_t len
:5; /* length */
721 uchar_t rt
:3; /* routing type */
722 uchar_t res
:4; /* reserved */
723 uchar_t mtu
:3; /* largest frame */
724 uchar_t dir
:1; /* direction bit */
727 * In little endian machine, the ring field has to be stored in a
728 * ushort_t type. This implies that it is not possible to have a
729 * layout of bit field to represent bridge and ring.
731 * If the compiler uses _BIT_FIELDS_HTOL and it is a big endian
732 * machine, the following bit field definition will work.
739 * If the compiler uses _BIT_FIELDS_LTOH and it is a big endian
740 * machine, the definition can be changed to
747 * With little endian machine, we need to use 2 macroes. For
748 * simplicity, since the macroes work for both big and little
749 * endian machines, we will not use bit fields for the
752 #define bridge(route) (ntohs((ushort_t)(route)) & 0x0F)
753 #define ring(route) (ntohs((ushort_t)(route)) >> 4)
755 ushort_t rd
[MAX_RDFLDS
]; /* route designator fields */
761 struct ether_addr dhost
;
762 struct ether_addr shost
;
766 struct llc_snap_hdr
{
767 uchar_t d_lsap
; /* destination service access point */
768 uchar_t s_lsap
; /* source link service access point */
769 uchar_t control
; /* short control field */
770 uchar_t org
[3]; /* Ethernet style organization field */
771 ushort_t type
; /* Ethernet style type field */
774 struct ether_addr tokenbroadcastaddr2
= {
775 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff
778 int Mtutab
[] = {516, 1470, 2052, 4472, 8144, 11407, 17800};
781 print_sr(struct tr_ri
*rh
)
784 static char line
[512];
786 sprintf(line
, "TR Source Route dir=%d, mtu=%d",
787 rh
->dir
, Mtutab
[rh
->mtu
]);
789 hops
= (int)(rh
->len
- 2) / (int)2;
792 sprintf(line
+strlen(line
), ", Route: ");
793 for (ii
= 0; ii
< hops
; ii
++) {
794 if (! bridge(rh
->rd
[ii
])) {
795 sprintf(line
+strlen(line
), "(%d)",
798 sprintf(line
+strlen(line
), "(%d)%d",
799 ring(rh
->rd
[ii
]), bridge(rh
->rd
[ii
]));
807 interpret_tr(int flags
, caddr_t e
, int elen
, int origlen
)
809 struct tr_header
*mh
;
812 struct llc_snap_hdr
*snaphdr
;
815 boolean_t data_copied
= B_FALSE
;
816 extern char *dst_name
, *src_name
;
818 int is_llc
= 0, is_snap
= 0, source_routing
= 0;
819 int blen
= MAX(origlen
, 17800);
821 if (data
!= NULL
&& datalen
!= 0 && datalen
< blen
) {
827 data
= (char *)malloc(blen
);
829 pr_err("Warning: malloc failure");
833 if (origlen
< ACFCDASA_LEN
) {
835 (void) sprintf(get_sum_line(),
836 "RUNT (short packet - %d bytes)",
840 show_header("RUNT: ", "Short packet", origlen
);
843 if (elen
< ACFCDASA_LEN
)
846 mh
= (struct tr_header
*)e
;
847 rh
= (struct tr_ri
*)&mh
->ri
;
850 if (is_llc
= tr_machdr_len(e
, &maclen
, &source_routing
)) {
851 snaphdr
= (struct llc_snap_hdr
*)(e
+ maclen
);
852 if (snaphdr
->d_lsap
== LSAP_SNAP
&&
853 snaphdr
->s_lsap
== LSAP_SNAP
&&
854 snaphdr
->control
== CNTL_LLC_UI
) {
859 if (memcmp(&mh
->dhost
, ðer_broadcast
,
860 sizeof (struct ether_addr
)) == 0)
861 dst_name
= "(broadcast)";
862 else if (memcmp(&mh
->dhost
, &tokenbroadcastaddr2
,
863 sizeof (struct ether_addr
)) == 0)
864 dst_name
= "(mac broadcast)";
865 else if (mh
->dhost
.ether_addr_octet
[0] & TR_FN_ADDR
)
866 dst_name
= "(functional)";
869 ethertype
= ntohs(snaphdr
->type
);
871 src_name
= print_etherinfo(&mh
->shost
);
872 dst_name
= print_etherinfo(&mh
->dhost
);
876 * The 14 byte ether header screws up alignment
877 * of the rest of the packet for 32 bit aligned
878 * architectures like SPARC. Alas, we have to copy
879 * the rest of the packet in order to align it.
883 len
= elen
- (maclen
+ LLC_SNAP_HDR_LEN
);
884 off
= (char *)(e
+ maclen
+ LLC_SNAP_HDR_LEN
);
886 len
= elen
- (maclen
+ LLC_HDR1_LEN
);
887 off
= (char *)(e
+ maclen
+ LLC_HDR1_LEN
);
891 off
= (char *)(e
+ maclen
);
894 if (len
> 0 && (off
+ len
<= (char *)e
+ elen
)) {
895 (void) memcpy(data
, off
, len
);
896 data_copied
= B_TRUE
;
901 sprintf(get_sum_line(), print_sr(rh
));
905 (void) sprintf(get_sum_line(), "TR LLC w/SNAP "
906 "Type=%04X (%s), size=%d bytes",
908 print_ethertype(ethertype
),
911 (void) sprintf(get_sum_line(), "TR LLC, but no "
912 "SNAP encoding, size = %d bytes",
916 (void) sprintf(get_sum_line(),
917 "TR MAC FC=%02X (%s), size = %d bytes",
918 fc
, print_fc(fc
), origlen
);
922 if (flags
& F_DTAIL
) {
923 show_header("TR: ", "TR Header", elen
);
925 (void) sprintf(get_line(0, 0),
926 "Packet %d arrived at %d:%02d:%d.%05d",
928 pi_time_hour
, pi_time_min
, pi_time_sec
,
930 (void) sprintf(get_line(0, 0),
931 "Packet size = %d bytes",
933 (void) sprintf(get_line(0, 1),
934 "Frame Control = %02x (%s)",
936 (void) sprintf(get_line(2, 6),
937 "Destination = %s, %s",
938 printether(&mh
->dhost
),
939 print_etherinfo(&mh
->dhost
));
940 (void) sprintf(get_line(8, 6),
942 printether(&mh
->shost
),
943 print_etherinfo(&mh
->shost
));
946 sprintf(get_line(ACFCDASA_LEN
, rh
->len
), print_sr(rh
));
949 (void) sprintf(get_line(maclen
, 1),
950 "Dest Service Access Point = %02x",
952 (void) sprintf(get_line(maclen
+1, 1),
953 "Source Service Access Point = %02x",
955 (void) sprintf(get_line(maclen
+2, 1),
959 (void) sprintf(get_line(maclen
+3, 3),
960 "SNAP Protocol Id = %02x%02x%02x",
961 snaphdr
->org
[0], snaphdr
->org
[1],
967 (void) sprintf(get_line(maclen
+6, 2),
968 "SNAP Type = %04X (%s)",
969 ethertype
, print_ethertype(ethertype
));
975 /* go to the next protocol layer */
976 if (is_snap
&& data_copied
) {
979 (void) interpret_ip(flags
, (struct ip
*)data
, len
);
981 /* Just in case it is decided to add this type */
983 (void) interpret_ipv6(flags
, (ip6_t
*)data
, len
);
986 case ETHERTYPE_REVARP
:
987 interpret_arp(flags
, (struct arphdr
*)data
, len
);
989 case ETHERTYPE_AARP
: /* AppleTalk */
990 interpret_aarp(flags
, data
, len
);
993 interpret_at(flags
, (struct ddp_hdr
*)data
, len
);
1005 * stuffs length of mac and ri fields into *lenp
1011 tr_machdr_len(char *e
, int *lenp
, int *source_routing
)
1013 struct tr_header
*mh
;
1017 mh
= (struct tr_header
*)e
;
1018 rh
= (struct tr_ri
*)&mh
->ri
;
1021 if (mh
->shost
.ether_addr_octet
[0] & TR_SR_ADDR
) {
1022 *lenp
= ACFCDASA_LEN
+ rh
->len
;
1023 *source_routing
= 1;
1025 *lenp
= ACFCDASA_LEN
;
1026 *source_routing
= 0;
1029 if ((fc
& TR_MAC_MASK
) == 0)
1030 return (0); /* it's a MAC frame */
1032 return (1); /* it's an LLC frame */
1036 tr_header_len(char *e
, size_t msgsize
)
1038 struct llc_snap_hdr
*snaphdr
;
1039 int len
= 0, source_routing
;
1041 if (tr_machdr_len(e
, &len
, &source_routing
) == 0)
1042 return (len
); /* it's a MAC frame */
1044 if (msgsize
< sizeof (struct llc_snap_hdr
))
1047 snaphdr
= (struct llc_snap_hdr
*)(e
+ len
);
1048 if (snaphdr
->d_lsap
== LSAP_SNAP
&&
1049 snaphdr
->s_lsap
== LSAP_SNAP
&&
1050 snaphdr
->control
== CNTL_LLC_UI
)
1051 len
+= LLC_SNAP_HDR_LEN
; /* it's a SNAP frame */
1053 len
+= LLC_HDR1_LEN
;
1058 struct fddi_header
{
1060 struct ether_addr dhost
, shost
;
1061 uchar_t dsap
, ssap
, ctl
, proto_id
[3];
1066 interpret_fddi(int flags
, caddr_t e
, int elen
, int origlen
)
1068 struct fddi_header fhdr
, *f
= &fhdr
;
1071 boolean_t data_copied
= B_FALSE
;
1072 extern char *dst_name
, *src_name
;
1074 int is_llc
= 0, is_smt
= 0, is_snap
= 0;
1075 int blen
= MAX(origlen
, 4500);
1077 if (data
!= NULL
&& datalen
!= 0 && datalen
< blen
) {
1083 data
= (char *)malloc(blen
);
1085 pr_err("Warning: malloc failure");
1090 if (flags
& F_SUM
) {
1091 (void) sprintf(get_sum_line(),
1092 "RUNT (short packet - %d bytes)",
1095 if (flags
& F_DTAIL
)
1096 show_header("RUNT: ", "Short packet", origlen
);
1102 (void) memcpy(&f
->fc
, e
, sizeof (f
->fc
));
1103 addr_copy_swap(&f
->dhost
, (struct ether_addr
*)(e
+1));
1104 addr_copy_swap(&f
->shost
, (struct ether_addr
*)(e
+7));
1106 if ((f
->fc
&0x50) == 0x50) {
1108 (void) memcpy(&f
->dsap
, e
+13, sizeof (f
->dsap
));
1109 (void) memcpy(&f
->ssap
, e
+14, sizeof (f
->ssap
));
1110 (void) memcpy(&f
->ctl
, e
+15, sizeof (f
->ctl
));
1111 if (f
->dsap
== 0xaa && f
->ssap
== 0xaa) {
1113 (void) memcpy(&f
->proto_id
, e
+16, sizeof (f
->proto_id
));
1114 (void) memcpy(&f
->type
, e
+19, sizeof (f
->type
));
1117 if ((f
->fc
&0x41) == 0x41 || (f
->fc
&0x4f) == 0x4f) {
1123 if (memcmp(&f
->dhost
, ðer_broadcast
,
1124 sizeof (struct ether_addr
)) == 0)
1125 dst_name
= "(broadcast)";
1126 else if (f
->dhost
.ether_addr_octet
[0] & 0x01)
1127 dst_name
= "(multicast)";
1130 ethertype
= ntohs(f
->type
);
1132 src_name
= print_etherinfo(&f
->shost
);
1133 dst_name
= print_etherinfo(&f
->dhost
);
1137 * The 14 byte ether header screws up alignment
1138 * of the rest of the packet for 32 bit aligned
1139 * architectures like SPARC. Alas, we have to copy
1140 * the rest of the packet in order to align it.
1145 off
= (char *)(e
+ 21);
1148 off
= (char *)(e
+ 16);
1152 off
= (char *)(e
+ 13);
1155 if (len
> 0 && (off
+ len
<= (char *)e
+ elen
)) {
1156 (void) memcpy(data
, off
, len
);
1157 data_copied
= B_TRUE
;
1160 if (flags
& F_SUM
) {
1163 (void) sprintf(get_sum_line(),
1164 "FDDI LLC Type=%04X (%s), size = %d bytes",
1166 print_ethertype(ethertype
),
1169 (void) sprintf(get_sum_line(), "LLC, but no "
1170 "SNAP encoding, size = %d bytes",
1173 } else if (is_smt
) {
1174 (void) sprintf(get_sum_line(), "SMT Type=%02X (%s), "
1175 "Class = %02X (%s), size = %d bytes",
1176 *(uchar_t
*)(data
+1), print_smttype(*(data
+1)),
1177 *data
, print_smtclass(*data
), origlen
);
1179 (void) sprintf(get_sum_line(),
1180 "FC=%02X (%s), size = %d bytes",
1181 f
->fc
, print_fc(f
->fc
), origlen
);
1185 if (flags
& F_DTAIL
) {
1186 show_header("FDDI: ", "FDDI Header", elen
);
1188 (void) sprintf(get_line(0, 0),
1189 "Packet %d arrived at %d:%02d:%d.%05d",
1191 pi_time_hour
, pi_time_min
, pi_time_sec
,
1193 (void) sprintf(get_line(0, 0),
1194 "Packet size = %d bytes",
1196 (void) sprintf(get_line(0, 6),
1197 "Destination = %s, %s",
1198 printether(&f
->dhost
),
1199 print_etherinfo(&f
->dhost
));
1200 (void) sprintf(get_line(6, 6),
1202 printether(&f
->shost
),
1203 print_etherinfo(&f
->shost
));
1206 (void) sprintf(get_line(12, 2),
1207 "Frame Control = %02x (%s)",
1208 f
->fc
, print_fc(f
->fc
));
1209 (void) sprintf(get_line(12, 2),
1210 "Dest Service Access Point = %02x",
1212 (void) sprintf(get_line(12, 2),
1213 "Source Service Access Point = %02x",
1215 (void) sprintf(get_line(12, 2),
1219 (void) sprintf(get_line(12, 2),
1220 "Protocol Id = %02x%02x%02x",
1221 f
->proto_id
[0], f
->proto_id
[1],
1224 } else if (is_smt
) {
1225 (void) sprintf(get_line(12, 2),
1226 "Frame Control = %02x (%s)",
1227 f
->fc
, print_fc(f
->fc
));
1228 (void) sprintf(get_line(12, 2),
1229 "Class = %02x (%s)",
1230 (uchar_t
)*data
, print_smtclass(*data
));
1231 (void) sprintf(get_line(12, 2),
1233 *(uchar_t
*)(data
+1), print_smttype(*(data
+1)));
1235 (void) sprintf(get_line(12, 2),
1236 "FC=%02X (%s), size = %d bytes",
1237 f
->fc
, print_fc(f
->fc
), origlen
);
1241 (void) sprintf(get_line(12, 2),
1242 "LLC Type = %04X (%s)",
1243 ethertype
, print_ethertype(ethertype
));
1249 /* go to the next protocol layer */
1250 if (is_llc
&& is_snap
&& f
->ctl
== 0x03 && data_copied
) {
1251 switch (ethertype
) {
1253 (void) interpret_ip(flags
, (struct ip
*)data
, len
);
1255 /* Just in case it is decided to add this type */
1256 case ETHERTYPE_IPV6
:
1257 (void) interpret_ipv6(flags
, (ip6_t
*)data
, len
);
1260 case ETHERTYPE_REVARP
:
1261 interpret_arp(flags
, (struct arphdr
*)data
, len
);
1273 fddi_header_len(char *e
, size_t msgsize
)
1275 struct fddi_header fhdr
, *f
= &fhdr
;
1277 if (msgsize
< sizeof (struct fddi_header
))
1280 (void) memcpy(&f
->fc
, e
, sizeof (f
->fc
));
1281 (void) memcpy(&f
->dhost
, e
+1, sizeof (struct ether_addr
));
1282 (void) memcpy(&f
->shost
, e
+7, sizeof (struct ether_addr
));
1284 if ((f
->fc
&0x50) == 0x50) {
1285 (void) memcpy(&f
->dsap
, e
+13, sizeof (f
->dsap
));
1286 (void) memcpy(&f
->ssap
, e
+14, sizeof (f
->ssap
));
1287 (void) memcpy(&f
->ctl
, e
+15, sizeof (f
->ctl
));
1288 if (f
->dsap
== 0xaa && f
->ssap
== 0xaa) {
1293 if ((f
->fc
&0x41) == 0x41 || (f
->fc
&0x4f) == 0x4f) {
1297 /* Return the default FDDI header length. */
1302 * Print the given Ethernet address
1305 printether(struct ether_addr
*p
)
1307 static char buf
[256];
1309 sprintf(buf
, "%x:%x:%x:%x:%x:%x",
1310 p
->ether_addr_octet
[0],
1311 p
->ether_addr_octet
[1],
1312 p
->ether_addr_octet
[2],
1313 p
->ether_addr_octet
[3],
1314 p
->ether_addr_octet
[4],
1315 p
->ether_addr_octet
[5]);
1321 * Table of Ethernet Address Assignments
1322 * Some of the more popular entries
1323 * are at the beginning of the table
1324 * to reduce search time. Note that the
1325 * e-block's are stored in host byte-order.
1330 } ether_block
[] = {
1336 0x080069, "Silicon Graphics",
1337 0x000069, "Silicon Graphics",
1338 0x0000A7, "Network Computing Devices (NCD X-terminal)",
1341 0x0180C2, "Standard MAC Group Address",
1342 /* end of popular entries */
1345 0x000011, "Tektronix",
1346 0x000018, "Webster (?)",
1348 0x00001D, "Cabletron",
1349 0x000020, "DIAB (Data Industrier AB)",
1351 0x000022, "Visual Technology",
1355 0x000049, "Apricot Ltd.",
1357 0x00005A, "S & Koch",
1358 0x00005A, "Xerox 806 (unregistered)",
1359 0x00005E, "U.S. Department of Defense (IANA)",
1360 0x000065, "Network General",
1363 0x000079, "NetWare (?)",
1365 0x00007B, "Research Machines",
1366 0x00007D, "Harris (3M) (old)",
1367 0x000080, "Imagen(?)",
1368 0x000081, "Synoptics",
1369 0x000084, "Aquila (?)",
1370 0x000086, "Gateway (?)",
1371 0x000089, "Cayman Systems Gatorbox",
1372 0x000093, "Proteon",
1374 0x000098, "Cross Com",
1375 0x00009F, "Ameristar Technology",
1376 0x0000A2, "Wellfleet",
1377 0x0000A3, "Network Application Technology",
1379 0x0000A6, "Network General",
1380 0x0000A7, "Network Computing Devices (NCD X-terminal)",
1381 0x0000A9, "Network Systems",
1383 0x0000B3, "CIMLinc",
1384 0x0000B5, "Datability Terminal Server",
1385 0x0000B7, "Dove Fastnet",
1386 0x0000BC, "Allen-Bradley",
1387 0x0000C0, "Western Digital",
1389 0x0000C9, "Emulex Terminal Server",
1390 0x0000D0, "Develcon Electronics, Ltd.",
1391 0x0000D1, "Adaptec Inc. Nodem product",
1392 0x0000D7, "Dartmouth College (NED Router)",
1394 0x0000DE, "Unigraph",
1395 0x0000E2, "Acer Counterpoint",
1396 0x0000E8, "Accton Technology Corporation",
1397 0x0000EE, "Network Designers Limited(?)",
1398 0x0000EF, "Alantec",
1399 0x0000F3, "Gandalf",
1400 0x0000FD, "High Level Hardware (Orion, UK)",
1401 0x000143, "IEEE 802",
1406 0x008019, "Dayna Communications Etherprint product",
1407 0x00802D, "Xylogics, Inc. Annex terminal servers",
1408 0x008035, "Technology Works",
1409 0x008087, "Okidata",
1410 0x00808C, "Frontier Software Development",
1411 0x0080C7, "Xircom Inc.",
1412 0x0080D0, "Computer Products International",
1413 0x0080D3, "Shiva Appletalk-Ethernet interface",
1414 0x0080D4, "Chase Limited",
1417 0x00B0D0, "Computer Products International",
1418 0x00DD00, "Ungermann-Bass",
1419 0x00DD01, "Ungermann-Bass",
1420 0x00EFE5, "IBM (3Com card)",
1423 0x026086, "Satelcom MegaPac (UK)",
1424 0x02E6D3, "Bus-Tech, Inc. (BTI)",
1425 0x080001, "Computer Vision",
1426 0x080002, "3Com (Formerly Bridge)",
1427 0x080003, "ACC (Advanced Computer Communications)",
1428 0x080005, "Symbolics",
1431 0x080009, "Hewlett-Packard",
1432 0x08000A, "Nestar Systems",
1437 0x080011, "Tektronix, Inc.",
1439 0x08001A, "Data General",
1440 0x08001B, "Data General",
1444 0x080026, "Norsk Data (Nord)",
1445 0x080027, "PCS Computer Systems GmbH",
1446 0x080028, "TI Explorer",
1447 0x08002E, "Metaphor",
1448 0x08002F, "Prime Computer",
1449 0x080036, "Intergraph CAE stations",
1450 0x080037, "Fujitsu-Xerox",
1452 0x080039, "Spider Systems",
1453 0x08003B, "Torus Systems",
1454 0x08003E, "Motorola VME bus processor module",
1455 0x080041, "DCA Digital Comm. Assoc.",
1457 0x080047, "Sequent",
1458 0x080049, "Univation",
1461 0x080056, "Stanford University",
1462 0x080057, "Evans & Sutherland (?)",
1463 0x080067, "Comdesign",
1465 0x08006A, "ATTst (?)",
1466 0x08006E, "Excelan",
1467 0x080075, "DDE (Danish Data Elektronik A/S)",
1468 0x080077, "TSL (now Retix)",
1469 0x08007C, "Vitalink TransLAN III",
1471 0x080081, "Crosfield Electronics",
1472 0x080086, "Imagen/QMS",
1473 0x080087, "Xyplex terminal server",
1474 0x080089, "Kinetics AppleTalk-Ethernet interface",
1475 0x08008B, "Pyramid",
1476 0x08008D, "XyVision",
1477 0x080090, "Retix Inc Bridge",
1480 0x400003, "NetWare",
1482 0xAA0004, "DEC (DECNET)",
1488 * The oui argument should be in host byte-order to conform with
1489 * the above array's values.
1492 ether_ouiname(uint32_t oui
)
1496 for (i
= 0; ether_block
[i
].e_block
!= 0; i
++)
1497 if (oui
== ether_block
[i
].e_block
)
1498 return (ether_block
[i
].e_name
);
1504 * Print the additional Ethernet address info
1507 print_etherinfo(struct ether_addr
*eaddr
)
1510 char *p
= (char *)&addr
+ 1;
1513 (void) memcpy(p
, eaddr
, 3);
1515 if (memcmp(eaddr
, ðer_broadcast
, sizeof (struct ether_addr
)) == 0)
1516 return ("(broadcast)");
1518 addr
= ntohl(addr
); /* make it right for little-endians */
1519 ename
= ether_ouiname(addr
);
1524 return ((eaddr
->ether_addr_octet
[0] & 1) ? "(multicast)" : "");
1527 static uchar_t endianswap
[] = {
1528 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1529 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1530 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1531 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1532 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1533 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1534 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1535 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1536 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1537 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1538 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1539 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1540 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1541 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1542 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1543 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1544 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1545 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1546 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1547 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1548 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1549 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1550 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1551 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1552 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1553 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1554 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1555 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1556 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1557 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1558 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1559 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
1563 addr_copy_swap(struct ether_addr
*pd
, struct ether_addr
*ps
)
1565 pd
->ether_addr_octet
[0] = endianswap
[ps
->ether_addr_octet
[0]];
1566 pd
->ether_addr_octet
[1] = endianswap
[ps
->ether_addr_octet
[1]];
1567 pd
->ether_addr_octet
[2] = endianswap
[ps
->ether_addr_octet
[2]];
1568 pd
->ether_addr_octet
[3] = endianswap
[ps
->ether_addr_octet
[3]];
1569 pd
->ether_addr_octet
[4] = endianswap
[ps
->ether_addr_octet
[4]];
1570 pd
->ether_addr_octet
[5] = endianswap
[ps
->ether_addr_octet
[5]];
1575 ib_header_len(char *hdr
, size_t msgsize
)
1577 return (IPOIB_HDRSIZE
);
1581 interpret_ib(int flags
, char *header
, int elen
, int origlen
)
1583 struct ipoib_header
*hdr
= (struct ipoib_header
*)header
;
1586 unsigned short ethertype
;
1587 int blen
= MAX(origlen
, 4096);
1589 if (data
!= NULL
&& datalen
!= 0 && datalen
< blen
) {
1595 data
= malloc(blen
);
1597 pr_err("Warning: malloc failure");
1600 if (origlen
< IPOIB_HDRSIZE
) {
1602 (void) snprintf(get_sum_line(), MAXLINE
,
1603 "RUNT (short packet - %d bytes)", origlen
);
1604 if (flags
& F_DTAIL
)
1605 show_header("RUNT: ", "Short packet", origlen
);
1608 if (elen
< IPOIB_HDRSIZE
)
1612 * It is not possible to understand just by looking
1613 * at the header whether this was a broad/multi cast
1614 * packet; thus dst_name is not updated.
1616 ethertype
= ntohs(hdr
->ipoib_type
);
1617 len
= elen
- IPOIB_HDRSIZE
;
1618 off
= (char *)(hdr
+ 1);
1619 (void) memcpy(data
, off
, len
);
1621 if (flags
& F_SUM
) {
1622 (void) snprintf(get_sum_line(), MAXLINE
,
1623 "IPIB Type=%04X (%s), size = %d bytes",
1625 print_ethertype(ethertype
),
1629 if (flags
& F_DTAIL
) {
1630 show_header("IPIB: ", "IPIB Header", elen
);
1632 (void) snprintf(get_line(0, 0), get_line_remain(),
1633 "Packet %d arrived at %d:%02d:%d.%02d",
1634 pi_frame
, pi_time_hour
, pi_time_min
,
1635 pi_time_sec
, pi_time_usec
/ 10000);
1636 (void) snprintf(get_line(0, 0), get_line_remain(),
1637 "Packet size = %d bytes", elen
, elen
);
1638 (void) snprintf(get_line(0, 2), get_line_remain(),
1639 "Ethertype = %04X (%s)", ethertype
,
1640 print_ethertype(ethertype
));
1644 /* Go to the next protocol layer */
1645 switch (ethertype
) {
1647 (void) interpret_ip(flags
, (struct ip
*)data
, len
);
1649 case ETHERTYPE_IPV6
:
1650 (void) interpret_ipv6(flags
, (ip6_t
*)data
, len
);
1653 case ETHERTYPE_REVARP
:
1654 interpret_arp(flags
, (struct arphdr
*)data
, len
);
1663 ipnet_header_len(char *hdr
, size_t msgsize
)
1665 return (sizeof (dl_ipnetinfo_t
));
1668 #define MAX_UINT64_STR 22
1670 interpret_ipnet(int flags
, char *header
, int elen
, int origlen
)
1673 size_t len
= elen
- sizeof (dl_ipnetinfo_t
);
1674 char *off
= (char *)header
+ sizeof (dl_ipnetinfo_t
);
1675 int blen
= MAX(origlen
, 8252);
1676 char szone
[MAX_UINT64_STR
];
1677 char dzone
[MAX_UINT64_STR
];
1679 (void) memcpy(&dl
, header
, sizeof (dl
));
1680 if (data
!= NULL
&& datalen
!= 0 && datalen
< blen
) {
1686 data
= (char *)malloc(blen
);
1688 pr_err("Warning: malloc failure");
1692 if (dl
.dli_zsrc
== ALL_ZONES
)
1693 sprintf(szone
, "Unknown");
1695 sprintf(szone
, "%lu", BE_32(dl
.dli_zsrc
));
1697 if (dl
.dli_zdst
== ALL_ZONES
)
1698 sprintf(dzone
, "Unknown");
1700 sprintf(dzone
, "%lu", BE_32(dl
.dli_zdst
));
1702 if (flags
& F_SUM
) {
1703 (void) snprintf(get_sum_line(), MAXLINE
,
1704 "IPNET src zone %s dst zone %s", szone
, dzone
);
1707 if (flags
& F_DTAIL
) {
1708 show_header("IPNET: ", "IPNET Header", elen
);
1710 (void) sprintf(get_line(0, 0),
1711 "Packet %d arrived at %d:%02d:%d.%05d",
1713 pi_time_hour
, pi_time_min
, pi_time_sec
,
1715 (void) sprintf(get_line(0, 0),
1716 "Packet size = %d bytes",
1718 (void) snprintf(get_line(0, 0), get_line_remain(),
1719 "dli_version = %d", dl
.dli_version
);
1720 (void) snprintf(get_line(0, 0), get_line_remain(),
1721 "dli_family = %d", dl
.dli_family
);
1722 (void) snprintf(get_line(0, 2), get_line_remain(),
1723 "dli_zsrc = %s", szone
);
1724 (void) snprintf(get_line(0, 2), get_line_remain(),
1725 "dli_zdst = %s", dzone
);
1728 memcpy(data
, off
, len
);
1730 switch (dl
.dli_family
) {
1732 (void) interpret_ip(flags
, (struct ip
*)data
, len
);
1735 (void) interpret_ipv6(flags
, (ip6_t
*)data
, len
);
1745 ipv4_header_len(char *hdr
, size_t msgsize
)
1747 return (msgsize
< sizeof (ipha_t
) ? 0 : IPH_HDR_LENGTH((ipha_t
*)hdr
));
1751 * The header length needs to include all potential extension headers, as the
1752 * caller expects to use this length as an offset to the inner network layer
1753 * header to be used as a filter offset. IPsec headers aren't passed up here,
1754 * and neither are fragmentation headers.
1757 ipv6_header_len(char *hdr
, size_t msgsize
)
1759 ip6_t
*ip6hdr
= (ip6_t
*)hdr
;
1761 uint_t hdrlen
= sizeof (ip6_t
), exthdrlen
;
1765 if (msgsize
< sizeof (ip6_t
))
1768 nxt
= ip6hdr
->ip6_nxt
;
1769 pptr
= (char *)(ip6hdr
+ 1);
1771 while (nxt
!= IPPROTO_ENCAP
&& nxt
!= IPPROTO_IPV6
) {
1773 case IPPROTO_HOPOPTS
:
1774 case IPPROTO_DSTOPTS
:
1775 case IPPROTO_ROUTING
:
1776 if (msgsize
< hdrlen
+ sizeof (ip6_hbh_t
))
1778 exthdr
= (ip6_hbh_t
*)pptr
;
1779 exthdrlen
= 8 + exthdr
->ip6h_len
* 8;
1780 hdrlen
+= exthdrlen
;
1782 nxt
= exthdr
->ip6h_nxt
;
1786 * This is garbage, there's no way to know where the
1787 * inner IP header is.
1798 interpret_iptun(int flags
, char *header
, int elen
, int origlen
)
1800 (void) interpret_ip(flags
, (struct ip
*)header
, elen
);