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