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 2004 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(e) 1122 char *e; 1123 { 1124 struct fddi_header fhdr, *f = &fhdr; 1125 1126 (void) memcpy(&f->fc, e, sizeof (f->fc)); 1127 (void) memcpy(&f->dhost, e+1, sizeof (struct ether_addr)); 1128 (void) memcpy(&f->shost, e+7, sizeof (struct ether_addr)); 1129 1130 if ((f->fc&0x50) == 0x50) { 1131 (void) memcpy(&f->dsap, e+13, sizeof (f->dsap)); 1132 (void) memcpy(&f->ssap, e+14, sizeof (f->ssap)); 1133 (void) memcpy(&f->ctl, e+15, sizeof (f->ctl)); 1134 if (f->dsap == 0xaa && f->ssap == 0xaa) { 1135 return (21); 1136 } 1137 return (16); 1138 } else { 1139 if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) { 1140 return (13); 1141 } 1142 } 1143 } 1144 1145 /* 1146 * Print the given Ethernet address 1147 */ 1148 char * 1149 printether(p) 1150 struct ether_addr *p; 1151 { 1152 static char buf[256]; 1153 1154 sprintf(buf, "%x:%x:%x:%x:%x:%x", 1155 p->ether_addr_octet[0], 1156 p->ether_addr_octet[1], 1157 p->ether_addr_octet[2], 1158 p->ether_addr_octet[3], 1159 p->ether_addr_octet[4], 1160 p->ether_addr_octet[5]); 1161 1162 return (buf); 1163 } 1164 1165 /* 1166 * Table of Ethernet Address Assignments 1167 * Some of the more popular entries 1168 * are at the beginning of the table 1169 * to reduce search time. Note that the 1170 * e-block's are stored in host byte-order. 1171 */ 1172 struct block_type { 1173 int e_block; 1174 char *e_name; 1175 } ether_block [] = { 1176 0x080020, "Sun", 1177 0x0000C6, "HP", 1178 0x08002B, "DEC", 1179 0x00000F, "NeXT", 1180 0x00000C, "Cisco", 1181 0x080069, "Silicon Graphics", 1182 0x000069, "Silicon Graphics", 1183 0x0000A7, "Network Computing Devices (NCD X-terminal)", 1184 0x08005A, "IBM", 1185 0x0000AC, "Apollo", 1186 /* end of popular entries */ 1187 0x000002, "BBN", 1188 0x000010, "Sytek", 1189 0x000011, "Tektronix", 1190 0x000018, "Webster (?)", 1191 0x00001B, "Novell", 1192 0x00001D, "Cabletron", 1193 0x000020, "DIAB (Data Industrier AB)", 1194 0x000021, "SC&C", 1195 0x000022, "Visual Technology", 1196 0x000029, "IMC", 1197 0x00002A, "TRW", 1198 0x00003D, "AT&T", 1199 0x000049, "Apricot Ltd.", 1200 0x000055, "AT&T", 1201 0x00005A, "S & Koch", 1202 0x00005A, "Xerox 806 (unregistered)", 1203 0x00005E, "U.S. Department of Defense (IANA)", 1204 0x000065, "Network General", 1205 0x00006B, "MIPS", 1206 0x000077, "MIPS", 1207 0x000079, "NetWare (?)", 1208 0x00007A, "Ardent", 1209 0x00007B, "Research Machines", 1210 0x00007D, "Harris (3M) (old)", 1211 0x000080, "Imagen(?)", 1212 0x000081, "Synoptics", 1213 0x000084, "Aquila (?)", 1214 0x000086, "Gateway (?)", 1215 0x000089, "Cayman Systems Gatorbox", 1216 0x000093, "Proteon", 1217 0x000094, "Asante", 1218 0x000098, "Cross Com", 1219 0x00009F, "Ameristar Technology", 1220 0x0000A2, "Wellfleet", 1221 0x0000A3, "Network Application Technology", 1222 0x0000A4, "Acorn", 1223 0x0000A6, "Network General", 1224 0x0000A7, "Network Computing Devices (NCD X-terminal)", 1225 0x0000A9, "Network Systems", 1226 0x0000AA, "Xerox", 1227 0x0000B3, "CIMLinc", 1228 0x0000B5, "Datability Terminal Server", 1229 0x0000B7, "Dove Fastnet", 1230 0x0000BC, "Allen-Bradley", 1231 0x0000C0, "Western Digital", 1232 0x0000C8, "Altos", 1233 0x0000C9, "Emulex Terminal Server", 1234 0x0000D0, "Develcon Electronics, Ltd.", 1235 0x0000D1, "Adaptec Inc. Nodem product", 1236 0x0000D7, "Dartmouth College (NED Router)", 1237 0x0000DD, "Gould", 1238 0x0000DE, "Unigraph", 1239 0x0000E2, "Acer Counterpoint", 1240 0x0000E8, "Accton Technology Corporation", 1241 0x0000EE, "Network Designers Limited(?)", 1242 0x0000EF, "Alantec", 1243 0x0000F3, "Gandalf", 1244 0x0000FD, "High Level Hardware (Orion, UK)", 1245 0x000143, "IEEE 802", 1246 0x001700, "Kabel", 1247 0x004010, "Sonic", 1248 0x00608C, "3Com", 1249 0x00800F, "SMC", 1250 0x008019, "Dayna Communications Etherprint product", 1251 0x00802D, "Xylogics, Inc. Annex terminal servers", 1252 0x008035, "Technology Works", 1253 0x008087, "Okidata", 1254 0x00808C, "Frontier Software Development", 1255 0x0080C7, "Xircom Inc.", 1256 0x0080D0, "Computer Products International", 1257 0x0080D3, "Shiva Appletalk-Ethernet interface", 1258 0x0080D4, "Chase Limited", 1259 0x0080F1, "Opus", 1260 0x00AA00, "Intel", 1261 0x00B0D0, "Computer Products International", 1262 0x00DD00, "Ungermann-Bass", 1263 0x00DD01, "Ungermann-Bass", 1264 0x00EFE5, "IBM (3Com card)", 1265 0x020406, "BBN", 1266 0x026060, "3Com", 1267 0x026086, "Satelcom MegaPac (UK)", 1268 0x02E6D3, "Bus-Tech, Inc. (BTI)", 1269 0x080001, "Computer Vision", 1270 0x080002, "3Com (Formerly Bridge)", 1271 0x080003, "ACC (Advanced Computer Communications)", 1272 0x080005, "Symbolics", 1273 0x080007, "Apple", 1274 0x080008, "BBN", 1275 0x080009, "Hewlett-Packard", 1276 0x08000A, "Nestar Systems", 1277 0x08000B, "Unisys", 1278 0x08000D, "ICL", 1279 0x08000E, "NCR", 1280 0x080010, "AT&T", 1281 0x080011, "Tektronix, Inc.", 1282 0x080017, "NSC", 1283 0x08001A, "Data General", 1284 0x08001B, "Data General", 1285 0x08001E, "Apollo", 1286 0x080022, "NBI", 1287 0x080025, "CDC", 1288 0x080026, "Norsk Data (Nord)", 1289 0x080027, "PCS Computer Systems GmbH", 1290 0x080028, "TI Explorer", 1291 0x08002E, "Metaphor", 1292 0x08002F, "Prime Computer", 1293 0x080036, "Intergraph CAE stations", 1294 0x080037, "Fujitsu-Xerox", 1295 0x080038, "Bull", 1296 0x080039, "Spider Systems", 1297 0x08003B, "Torus Systems", 1298 0x08003E, "Motorola VME bus processor module", 1299 0x080041, "DCA Digital Comm. Assoc.", 1300 0x080046, "Sony", 1301 0x080047, "Sequent", 1302 0x080049, "Univation", 1303 0x08004C, "Encore", 1304 0x08004E, "BICC", 1305 0x080056, "Stanford University", 1306 0x080057, "Evans & Sutherland (?)", 1307 0x080067, "Comdesign", 1308 0x080068, "Ridge", 1309 0x08006A, "ATTst (?)", 1310 0x08006E, "Excelan", 1311 0x080075, "DDE (Danish Data Elektronik A/S)", 1312 0x080077, "TSL (now Retix)", 1313 0x08007C, "Vitalink TransLAN III", 1314 0x080080, "XIOS", 1315 0x080081, "Crosfield Electronics", 1316 0x080086, "Imagen/QMS", 1317 0x080087, "Xyplex terminal server", 1318 0x080089, "Kinetics AppleTalk-Ethernet interface", 1319 0x08008B, "Pyramid", 1320 0x08008D, "XyVision", 1321 0x080090, "Retix Inc Bridge", 1322 0x10005A, "IBM", 1323 0x1000D4, "DEC", 1324 0x400003, "NetWare", 1325 0x800010, "AT&T", 1326 0xAA0004, "DEC (DECNET)", 1327 0xC00000, "SMC", 1328 0, "", 1329 }; 1330 1331 /* 1332 * The oui argument should be in host byte-order to conform with 1333 * the above array's values. 1334 */ 1335 char * 1336 ether_ouiname(uint32_t oui) 1337 { 1338 uint_t i; 1339 1340 for (i = 0; ether_block[i].e_block != 0; i++) 1341 if (oui == ether_block[i].e_block) 1342 return (ether_block[i].e_name); 1343 1344 return (NULL); 1345 } 1346 1347 /* 1348 * Print the additional Ethernet address info 1349 */ 1350 static char * 1351 print_etherinfo(eaddr) 1352 struct ether_addr *eaddr; 1353 { 1354 uint_t addr = 0; 1355 char *p = (char *)&addr + 1; 1356 char *ename; 1357 1358 (void) memcpy(p, eaddr, 3); 1359 1360 if (memcmp(eaddr, ðer_broadcast, sizeof (struct ether_addr)) == 0) 1361 return ("(broadcast)"); 1362 1363 if (eaddr->ether_addr_octet[0] & 1) 1364 return ("(multicast)"); 1365 1366 addr = ntohl(addr); /* make it right for little-endians */ 1367 ename = ether_ouiname(addr); 1368 1369 if (ename != NULL) 1370 return (ename); 1371 else 1372 return (""); 1373 } 1374 1375 static uchar_t endianswap[] = { 1376 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 1377 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 1378 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 1379 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 1380 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 1381 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 1382 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 1383 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 1384 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 1385 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 1386 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 1387 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 1388 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 1389 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 1390 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 1391 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 1392 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 1393 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 1394 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 1395 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 1396 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 1397 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 1398 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 1399 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 1400 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 1401 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 1402 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 1403 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 1404 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 1405 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 1406 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 1407 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 1408 }; 1409 1410 static void 1411 addr_copy_swap(pd, ps) 1412 struct ether_addr *pd; 1413 struct ether_addr *ps; 1414 { 1415 pd->ether_addr_octet[0] = endianswap[ps->ether_addr_octet[0]]; 1416 pd->ether_addr_octet[1] = endianswap[ps->ether_addr_octet[1]]; 1417 pd->ether_addr_octet[2] = endianswap[ps->ether_addr_octet[2]]; 1418 pd->ether_addr_octet[3] = endianswap[ps->ether_addr_octet[3]]; 1419 pd->ether_addr_octet[4] = endianswap[ps->ether_addr_octet[4]]; 1420 pd->ether_addr_octet[5] = endianswap[ps->ether_addr_octet[5]]; 1421 } 1422 1423 /* ARGSUSED */ 1424 uint_t 1425 ib_header_len(char *hdr) 1426 { 1427 return (IPOIB_HDRSIZE); 1428 } 1429 1430 static uint_t 1431 interpret_ib(int flags, char *header, int elen, int origlen) 1432 { 1433 struct ipoib_header *hdr = (struct ipoib_header *)header; 1434 char *off; 1435 int len; 1436 extern char *dst_name; 1437 unsigned short ethertype; 1438 int blen = MAX(origlen, 4096); 1439 1440 if (data != NULL && datalen != 0 && datalen < blen) { 1441 free(data); 1442 data = NULL; 1443 datalen = 0; 1444 } 1445 if (data == NULL) { 1446 data = malloc(blen); 1447 if (data == NULL) 1448 pr_err("Warning: malloc failure"); 1449 datalen = blen; 1450 } 1451 if (origlen < IPOIB_HDRSIZE) { 1452 if (flags & F_SUM) 1453 (void) snprintf(get_sum_line(), MAXLINE, 1454 "RUNT (short packet - %d bytes)", origlen); 1455 if (flags & F_DTAIL) 1456 show_header("RUNT: ", "Short packet", origlen); 1457 return (elen); 1458 } 1459 if (elen < IPOIB_HDRSIZE) 1460 return (elen); 1461 1462 /* 1463 * It is not possible to understand just by looking 1464 * at the header whether this was a broad/multi cast 1465 * packet; thus dst_name is not updated. 1466 */ 1467 ethertype = ntohs(hdr->ipoib_type); 1468 len = elen - IPOIB_HDRSIZE; 1469 off = (char *)(hdr + 1); 1470 (void) memcpy(data, off, len); 1471 1472 if (flags & F_SUM) { 1473 (void) snprintf(get_sum_line(), MAXLINE, 1474 "IPIB Type=%04X (%s), size = %d bytes", 1475 ethertype, 1476 print_ethertype(ethertype), 1477 origlen); 1478 } 1479 1480 if (flags & F_DTAIL) { 1481 show_header("IPIB: ", "IPIB Header", elen); 1482 show_space(); 1483 (void) snprintf(get_line(0, 0), get_line_remain(), 1484 "Packet %d arrived at %d:%02d:%d.%02d", 1485 pi_frame, pi_time_hour, pi_time_min, 1486 pi_time_sec, pi_time_usec / 10000); 1487 (void) snprintf(get_line(0, 0), get_line_remain(), 1488 "Packet size = %d bytes", elen, elen); 1489 (void) snprintf(get_line(0, 2), get_line_remain(), 1490 "Ethertype = %04X (%s)", ethertype, 1491 print_ethertype(ethertype)); 1492 show_space(); 1493 } 1494 1495 /* Go to the next protocol layer */ 1496 switch (ethertype) { 1497 case ETHERTYPE_IP: 1498 (void) interpret_ip(flags, (struct ip *)data, len); 1499 break; 1500 case ETHERTYPE_IPV6: 1501 (void) interpret_ipv6(flags, (ip6_t *)data, len); 1502 break; 1503 case ETHERTYPE_ARP: 1504 case ETHERTYPE_REVARP: 1505 interpret_arp(flags, (struct arphdr *)data, len); 1506 break; 1507 } 1508 1509 return (elen); 1510 } 1511