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