1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #include <sys/cdefs.h> 23 #ifndef lint 24 __RCSID("$NetBSD: print-ether.c,v 1.11 2024/09/02 16:15:31 christos Exp $"); 25 #endif 26 27 /* \summary: Ethernet printer */ 28 29 #include <config.h> 30 31 #include "netdissect-stdinc.h" 32 33 #define ND_LONGJMP_FROM_TCHECK 34 #include "netdissect.h" 35 #include "extract.h" 36 #include "addrtoname.h" 37 #include "ethertype.h" 38 39 /* 40 * Structure of an Ethernet header. 41 */ 42 struct ether_header { 43 nd_mac_addr ether_dhost; 44 nd_mac_addr ether_shost; 45 nd_uint16_t ether_length_type; 46 }; 47 48 /* 49 * Length of an Ethernet header; note that some compilers may pad 50 * "struct ether_header" to a multiple of 4 bytes, for example, so 51 * "sizeof (struct ether_header)" may not give the right answer. 52 */ 53 #define ETHER_HDRLEN 14 54 55 const struct tok ethertype_values[] = { 56 { ETHERTYPE_IP, "IPv4" }, 57 { ETHERTYPE_MPLS, "MPLS unicast" }, 58 { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, 59 { ETHERTYPE_IPV6, "IPv6" }, 60 { ETHERTYPE_8021Q, "802.1Q" }, 61 { ETHERTYPE_8021Q9100, "802.1Q-9100" }, 62 { ETHERTYPE_8021QinQ, "802.1Q-QinQ" }, 63 { ETHERTYPE_8021Q9200, "802.1Q-9200" }, 64 { ETHERTYPE_MACSEC, "802.1AE MACsec" }, 65 { ETHERTYPE_VMAN, "VMAN" }, 66 { ETHERTYPE_PUP, "PUP" }, 67 { ETHERTYPE_ARP, "ARP"}, 68 { ETHERTYPE_REVARP, "Reverse ARP"}, 69 { ETHERTYPE_NS, "NS" }, 70 { ETHERTYPE_SPRITE, "Sprite" }, 71 { ETHERTYPE_TRAIL, "Trail" }, 72 { ETHERTYPE_MOPDL, "MOP DL" }, 73 { ETHERTYPE_MOPRC, "MOP RC" }, 74 { ETHERTYPE_DN, "DN" }, 75 { ETHERTYPE_LAT, "LAT" }, 76 { ETHERTYPE_SCA, "SCA" }, 77 { ETHERTYPE_TEB, "TEB" }, 78 { ETHERTYPE_LANBRIDGE, "Lanbridge" }, 79 { ETHERTYPE_DECDNS, "DEC DNS" }, 80 { ETHERTYPE_DECDTS, "DEC DTS" }, 81 { ETHERTYPE_VEXP, "VEXP" }, 82 { ETHERTYPE_VPROD, "VPROD" }, 83 { ETHERTYPE_ATALK, "Appletalk" }, 84 { ETHERTYPE_AARP, "Appletalk ARP" }, 85 { ETHERTYPE_IPX, "IPX" }, 86 { ETHERTYPE_PPP, "PPP" }, 87 { ETHERTYPE_MPCP, "MPCP" }, 88 { ETHERTYPE_SLOW, "Slow Protocols" }, 89 { ETHERTYPE_PPPOED, "PPPoE D" }, 90 { ETHERTYPE_PPPOES, "PPPoE S" }, 91 { ETHERTYPE_EAPOL, "EAPOL" }, 92 { ETHERTYPE_REALTEK, "Realtek protocols" }, 93 { ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat" }, 94 { ETHERTYPE_JUMBO, "Jumbo" }, 95 { ETHERTYPE_NSH, "NSH" }, 96 { ETHERTYPE_LOOPBACK, "Loopback" }, 97 { ETHERTYPE_ISO, "OSI" }, 98 { ETHERTYPE_GRE_ISO, "GRE-OSI" }, 99 { ETHERTYPE_CFM_OLD, "CFM (old)" }, 100 { ETHERTYPE_CFM, "CFM" }, 101 { ETHERTYPE_IEEE1905_1, "IEEE1905.1" }, 102 { ETHERTYPE_LLDP, "LLDP" }, 103 { ETHERTYPE_TIPC, "TIPC"}, 104 { ETHERTYPE_GEONET_OLD, "GeoNet (old)"}, 105 { ETHERTYPE_GEONET, "GeoNet"}, 106 { ETHERTYPE_CALM_FAST, "CALM FAST"}, 107 { ETHERTYPE_AOE, "AoE" }, 108 { ETHERTYPE_PTP, "PTP" }, 109 { ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" }, 110 { 0, NULL} 111 }; 112 113 static void 114 ether_addresses_print(netdissect_options *ndo, const u_char *src, 115 const u_char *dst) 116 { 117 ND_PRINT("%s > %s, ", 118 GET_ETHERADDR_STRING(src), GET_ETHERADDR_STRING(dst)); 119 } 120 121 static void 122 ether_type_print(netdissect_options *ndo, uint16_t type) 123 { 124 if (!ndo->ndo_qflag) 125 ND_PRINT("ethertype %s (0x%04x)", 126 tok2str(ethertype_values, "Unknown", type), type); 127 else 128 ND_PRINT("%s", 129 tok2str(ethertype_values, "Unknown Ethertype (0x%04x)", type)); 130 } 131 132 /* 133 * Common code for printing Ethernet frames. 134 * 135 * It can handle Ethernet headers with extra tag information inserted 136 * after the destination and source addresses, as is inserted by some 137 * switch chips, and extra encapsulation header information before 138 * printing Ethernet header information (such as a LANE ID for ATM LANE). 139 */ 140 static u_int 141 ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, 142 u_int caplen, 143 void (*print_switch_tag)(netdissect_options *ndo, const u_char *), 144 u_int switch_tag_len, 145 void (*print_encap_header)(netdissect_options *ndo, const u_char *), 146 const u_char *encap_header_arg) 147 { 148 const struct ether_header *ehp; 149 u_int orig_length; 150 u_int hdrlen; 151 u_short length_type; 152 int printed_length; 153 int llc_hdrlen; 154 struct lladdr_info src, dst; 155 156 if (length < caplen) { 157 ND_PRINT("[length %u < caplen %u]", length, caplen); 158 nd_print_invalid(ndo); 159 return length; 160 } 161 if (caplen < ETHER_HDRLEN + switch_tag_len) { 162 nd_print_trunc(ndo); 163 return caplen; 164 } 165 166 if (print_encap_header != NULL) 167 (*print_encap_header)(ndo, encap_header_arg); 168 169 orig_length = length; 170 171 /* 172 * Get the source and destination addresses, skip past them, 173 * and print them if we're printing the link-layer header. 174 */ 175 ehp = (const struct ether_header *)p; 176 src.addr = ehp->ether_shost; 177 src.addr_string = etheraddr_string; 178 dst.addr = ehp->ether_dhost; 179 dst.addr_string = etheraddr_string; 180 181 length -= 2*MAC_ADDR_LEN; 182 caplen -= 2*MAC_ADDR_LEN; 183 p += 2*MAC_ADDR_LEN; 184 hdrlen = 2*MAC_ADDR_LEN; 185 186 if (ndo->ndo_eflag) 187 ether_addresses_print(ndo, src.addr, dst.addr); 188 189 /* 190 * Print the switch tag, if we have one, and skip past it. 191 */ 192 if (print_switch_tag != NULL) 193 (*print_switch_tag)(ndo, p); 194 195 length -= switch_tag_len; 196 caplen -= switch_tag_len; 197 p += switch_tag_len; 198 hdrlen += switch_tag_len; 199 200 /* 201 * Get the length/type field, skip past it, and print it 202 * if we're printing the link-layer header. 203 */ 204 recurse: 205 length_type = GET_BE_U_2(p); 206 207 length -= 2; 208 caplen -= 2; 209 p += 2; 210 hdrlen += 2; 211 212 /* 213 * Process 802.1AE MACsec headers. 214 */ 215 printed_length = 0; 216 if (length_type == ETHERTYPE_MACSEC) { 217 /* 218 * MACsec, aka IEEE 802.1AE-2006 219 * Print the header, and try to print the payload if it's not encrypted 220 */ 221 if (ndo->ndo_eflag) { 222 ether_type_print(ndo, length_type); 223 ND_PRINT(", length %u: ", orig_length); 224 printed_length = 1; 225 } 226 227 int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen, 228 &src, &dst); 229 230 if (ret == 0) { 231 /* Payload is encrypted; print it as raw data. */ 232 if (!ndo->ndo_suppress_default_print) 233 ND_DEFAULTPRINT(p, caplen); 234 return hdrlen; 235 } else if (ret > 0) { 236 /* Problem printing the header; just quit. */ 237 return ret; 238 } else { 239 /* 240 * Keep processing type/length fields. 241 */ 242 length_type = GET_BE_U_2(p); 243 244 ND_ICHECK_U(caplen, <, 2); 245 length -= 2; 246 caplen -= 2; 247 p += 2; 248 hdrlen += 2; 249 } 250 } 251 252 /* 253 * Process VLAN tag types. 254 */ 255 while (length_type == ETHERTYPE_8021Q || 256 length_type == ETHERTYPE_8021Q9100 || 257 length_type == ETHERTYPE_8021Q9200 || 258 length_type == ETHERTYPE_8021QinQ) { 259 /* 260 * It has a VLAN tag. 261 * Print VLAN information, and then go back and process 262 * the enclosed type field. 263 */ 264 if (caplen < 4) { 265 ndo->ndo_protocol = "vlan"; 266 nd_print_trunc(ndo); 267 return hdrlen + caplen; 268 } 269 if (length < 4) { 270 ndo->ndo_protocol = "vlan"; 271 nd_print_trunc(ndo); 272 return hdrlen + length; 273 } 274 if (ndo->ndo_eflag) { 275 uint16_t tag = GET_BE_U_2(p); 276 277 ether_type_print(ndo, length_type); 278 if (!printed_length) { 279 ND_PRINT(", length %u: ", orig_length); 280 printed_length = 1; 281 } else 282 ND_PRINT(", "); 283 ND_PRINT("%s, ", ieee8021q_tci_string(tag)); 284 } 285 286 length_type = GET_BE_U_2(p + 2); 287 p += 4; 288 length -= 4; 289 caplen -= 4; 290 hdrlen += 4; 291 } 292 293 /* 294 * We now have the final length/type field. 295 */ 296 if (length_type <= MAX_ETHERNET_LENGTH_VAL) { 297 /* 298 * It's a length field, containing the length of the 299 * remaining payload; use it as such, as long as 300 * it's not too large (bigger than the actual payload). 301 */ 302 if (length_type < length) { 303 length = length_type; 304 if (caplen > length) 305 caplen = length; 306 } 307 308 /* 309 * Cut off the snapshot length to the end of the 310 * payload. 311 */ 312 if (!nd_push_snaplen(ndo, p, length)) { 313 (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 314 "%s: can't push snaplen on buffer stack", __func__); 315 } 316 317 if (ndo->ndo_eflag) { 318 ND_PRINT("802.3"); 319 if (!printed_length) 320 ND_PRINT(", length %u: ", length); 321 } 322 323 /* 324 * An LLC header follows the length. Print that and 325 * higher layers. 326 */ 327 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 328 if (llc_hdrlen < 0) { 329 /* packet type not known, print raw packet */ 330 if (!ndo->ndo_suppress_default_print) 331 ND_DEFAULTPRINT(p, caplen); 332 llc_hdrlen = -llc_hdrlen; 333 } 334 hdrlen += llc_hdrlen; 335 nd_pop_packet_info(ndo); 336 } else if (length_type == ETHERTYPE_JUMBO) { 337 /* 338 * It's a type field, with the type for Alteon jumbo frames. 339 * See 340 * 341 * https://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 342 * 343 * which indicates that, following the type field, 344 * there's an LLC header and payload. 345 */ 346 /* Try to print the LLC-layer header & higher layers */ 347 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 348 if (llc_hdrlen < 0) { 349 /* packet type not known, print raw packet */ 350 if (!ndo->ndo_suppress_default_print) 351 ND_DEFAULTPRINT(p, caplen); 352 llc_hdrlen = -llc_hdrlen; 353 } 354 hdrlen += llc_hdrlen; 355 } else if (length_type == ETHERTYPE_ARISTA) { 356 if (caplen < 2) { 357 ND_PRINT("[|arista]"); 358 return hdrlen + caplen; 359 } 360 if (length < 2) { 361 ND_PRINT("[|arista]"); 362 return hdrlen + length; 363 } 364 ether_type_print(ndo, length_type); 365 ND_PRINT(", length %u: ", orig_length); 366 int bytesConsumed = arista_ethertype_print(ndo, p, length); 367 if (bytesConsumed > 0) { 368 p += bytesConsumed; 369 length -= bytesConsumed; 370 caplen -= bytesConsumed; 371 hdrlen += bytesConsumed; 372 goto recurse; 373 } else { 374 /* subtype/version not known, print raw packet */ 375 if (!ndo->ndo_eflag && length_type > MAX_ETHERNET_LENGTH_VAL) { 376 ether_addresses_print(ndo, src.addr, dst.addr); 377 ether_type_print(ndo, length_type); 378 ND_PRINT(", length %u: ", orig_length); 379 } 380 if (!ndo->ndo_suppress_default_print) 381 ND_DEFAULTPRINT(p, caplen); 382 } 383 } else { 384 /* 385 * It's a type field with some other value. 386 */ 387 if (ndo->ndo_eflag) { 388 ether_type_print(ndo, length_type); 389 if (!printed_length) 390 ND_PRINT(", length %u: ", orig_length); 391 else 392 ND_PRINT(", "); 393 } 394 if (ethertype_print(ndo, length_type, p, length, caplen, &src, &dst) == 0) { 395 /* type not known, print raw packet */ 396 if (!ndo->ndo_eflag) { 397 /* 398 * We didn't print the full link-layer 399 * header, as -e wasn't specified, so 400 * print only the source and destination 401 * MAC addresses and the final Ethernet 402 * type. 403 */ 404 ether_addresses_print(ndo, src.addr, dst.addr); 405 ether_type_print(ndo, length_type); 406 ND_PRINT(", length %u: ", orig_length); 407 } 408 409 if (!ndo->ndo_suppress_default_print) 410 ND_DEFAULTPRINT(p, caplen); 411 } 412 } 413 invalid: 414 return hdrlen; 415 } 416 417 /* 418 * Print an Ethernet frame while specifying a non-standard Ethernet header 419 * length. 420 * This might be encapsulated within another frame; we might be passed 421 * a pointer to a function that can print header information for that 422 * frame's protocol, and an argument to pass to that function. 423 * 424 * FIXME: caplen can and should be derived from ndo->ndo_snapend and p. 425 */ 426 u_int 427 ether_switch_tag_print(netdissect_options *ndo, const u_char *p, u_int length, 428 u_int caplen, 429 void (*print_switch_tag)(netdissect_options *, const u_char *), 430 u_int switch_tag_len) 431 { 432 return ether_common_print(ndo, p, length, caplen, print_switch_tag, 433 switch_tag_len, NULL, NULL); 434 } 435 436 /* 437 * Print an Ethernet frame. 438 * This might be encapsulated within another frame; we might be passed 439 * a pointer to a function that can print header information for that 440 * frame's protocol, and an argument to pass to that function. 441 * 442 * FIXME: caplen can and should be derived from ndo->ndo_snapend and p. 443 */ 444 u_int 445 ether_print(netdissect_options *ndo, 446 const u_char *p, u_int length, u_int caplen, 447 void (*print_encap_header)(netdissect_options *ndo, const u_char *), 448 const u_char *encap_header_arg) 449 { 450 ndo->ndo_protocol = "ether"; 451 return ether_common_print(ndo, p, length, caplen, NULL, 0, 452 print_encap_header, encap_header_arg); 453 } 454 455 /* 456 * This is the top level routine of the printer. 'p' points 457 * to the ether header of the packet, 'h->len' is the length 458 * of the packet off the wire, and 'h->caplen' is the number 459 * of bytes actually captured. 460 */ 461 void 462 ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 463 const u_char *p) 464 { 465 ndo->ndo_protocol = "ether"; 466 ndo->ndo_ll_hdr_len += 467 ether_print(ndo, p, h->len, h->caplen, NULL, NULL); 468 } 469 470 /* 471 * This is the top level routine of the printer. 'p' points 472 * to the ether header of the packet, 'h->len' is the length 473 * of the packet off the wire, and 'h->caplen' is the number 474 * of bytes actually captured. 475 * 476 * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header 477 * before the Ethernet header. 478 */ 479 void 480 netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 481 const u_char *p) 482 { 483 /* 484 * Fail if we don't have enough data for the Hilscher pseudo-header. 485 */ 486 ndo->ndo_protocol = "netanalyzer"; 487 ND_TCHECK_LEN(p, 4); 488 489 /* Skip the pseudo-header. */ 490 ndo->ndo_ll_hdr_len += 4; 491 ndo->ndo_ll_hdr_len += 492 ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL); 493 } 494 495 /* 496 * This is the top level routine of the printer. 'p' points 497 * to the ether header of the packet, 'h->len' is the length 498 * of the packet off the wire, and 'h->caplen' is the number 499 * of bytes actually captured. 500 * 501 * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte 502 * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF 503 * before the Ethernet header. 504 */ 505 void 506 netanalyzer_transparent_if_print(netdissect_options *ndo, 507 const struct pcap_pkthdr *h, 508 const u_char *p) 509 { 510 /* 511 * Fail if we don't have enough data for the Hilscher pseudo-header, 512 * preamble, and SOF. 513 */ 514 ndo->ndo_protocol = "netanalyzer_transparent"; 515 ND_TCHECK_LEN(p, 12); 516 517 /* Skip the pseudo-header, preamble, and SOF. */ 518 ndo->ndo_ll_hdr_len += 12; 519 ndo->ndo_ll_hdr_len += 520 ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL); 521 } 522 523 /* 524 * Prints the packet payload, given an Ethernet type code for the payload's 525 * protocol. 526 * 527 * Returns non-zero if it can do so, zero if the ethertype is unknown. 528 */ 529 530 int 531 ethertype_print(netdissect_options *ndo, 532 u_short ether_type, const u_char *p, 533 u_int length, u_int caplen, 534 const struct lladdr_info *src, const struct lladdr_info *dst) 535 { 536 switch (ether_type) { 537 538 case ETHERTYPE_IP: 539 ip_print(ndo, p, length); 540 return (1); 541 542 case ETHERTYPE_IPV6: 543 ip6_print(ndo, p, length); 544 return (1); 545 546 case ETHERTYPE_ARP: 547 case ETHERTYPE_REVARP: 548 arp_print(ndo, p, length, caplen); 549 return (1); 550 551 case ETHERTYPE_DN: 552 decnet_print(ndo, p, length, caplen); 553 return (1); 554 555 case ETHERTYPE_ATALK: 556 if (ndo->ndo_vflag) 557 ND_PRINT("et1 "); 558 atalk_print(ndo, p, length); 559 return (1); 560 561 case ETHERTYPE_AARP: 562 aarp_print(ndo, p, length); 563 return (1); 564 565 case ETHERTYPE_IPX: 566 ND_PRINT("(NOV-ETHII) "); 567 ipx_print(ndo, p, length); 568 return (1); 569 570 case ETHERTYPE_ISO: 571 if (length == 0 || caplen == 0) { 572 ndo->ndo_protocol = "isoclns"; 573 nd_print_trunc(ndo); 574 return (1); 575 } 576 /* At least one byte is required */ 577 /* FIXME: Reference for this byte? */ 578 ND_TCHECK_LEN(p, 1); 579 isoclns_print(ndo, p + 1, length - 1); 580 return(1); 581 582 case ETHERTYPE_PPPOED: 583 case ETHERTYPE_PPPOES: 584 case ETHERTYPE_PPPOED2: 585 case ETHERTYPE_PPPOES2: 586 pppoe_print(ndo, p, length); 587 return (1); 588 589 case ETHERTYPE_EAPOL: 590 eapol_print(ndo, p); 591 return (1); 592 593 case ETHERTYPE_REALTEK: 594 rtl_print(ndo, p, length, src, dst); 595 return (1); 596 597 case ETHERTYPE_PPP: 598 if (length) { 599 ND_PRINT(": "); 600 ppp_print(ndo, p, length); 601 } 602 return (1); 603 604 case ETHERTYPE_MPCP: 605 mpcp_print(ndo, p, length); 606 return (1); 607 608 case ETHERTYPE_SLOW: 609 slow_print(ndo, p, length); 610 return (1); 611 612 case ETHERTYPE_CFM: 613 case ETHERTYPE_CFM_OLD: 614 cfm_print(ndo, p, length); 615 return (1); 616 617 case ETHERTYPE_LLDP: 618 lldp_print(ndo, p, length); 619 return (1); 620 621 case ETHERTYPE_NSH: 622 nsh_print(ndo, p, length); 623 return (1); 624 625 case ETHERTYPE_LOOPBACK: 626 loopback_print(ndo, p, length); 627 return (1); 628 629 case ETHERTYPE_MPLS: 630 case ETHERTYPE_MPLS_MULTI: 631 mpls_print(ndo, p, length); 632 return (1); 633 634 case ETHERTYPE_TIPC: 635 tipc_print(ndo, p, length, caplen); 636 return (1); 637 638 case ETHERTYPE_MS_NLB_HB: 639 msnlb_print(ndo, p); 640 return (1); 641 642 case ETHERTYPE_GEONET_OLD: 643 case ETHERTYPE_GEONET: 644 geonet_print(ndo, p, length, src); 645 return (1); 646 647 case ETHERTYPE_CALM_FAST: 648 calm_fast_print(ndo, p, length, src); 649 return (1); 650 651 case ETHERTYPE_AOE: 652 aoe_print(ndo, p, length); 653 return (1); 654 655 case ETHERTYPE_PTP: 656 ptp_print(ndo, p, length); 657 return (1); 658 659 case ETHERTYPE_LAT: 660 case ETHERTYPE_SCA: 661 case ETHERTYPE_MOPRC: 662 case ETHERTYPE_MOPDL: 663 case ETHERTYPE_IEEE1905_1: 664 /* default_print for now */ 665 default: 666 return (0); 667 } 668 } 669