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