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