1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 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-sll.c,v 1.10 2023/08/17 20:19:40 christos Exp $"); 25 #endif 26 27 /* \summary: Linux cooked sockets capture printer */ 28 29 #ifdef HAVE_CONFIG_H 30 #include <config.h> 31 #endif 32 33 #ifdef HAVE_NET_IF_H 34 /* 35 * Include diag-control.h before <net/if.h>, which too defines a macro 36 * named ND_UNREACHABLE. 37 */ 38 #include "diag-control.h" 39 #include <net/if.h> 40 #endif 41 42 #include "netdissect-stdinc.h" 43 44 #define ND_LONGJMP_FROM_TCHECK 45 #include "netdissect.h" 46 #include "addrtoname.h" 47 #include "ethertype.h" 48 #include "extract.h" 49 50 /* 51 * For captures on Linux cooked sockets, we construct a fake header 52 * that includes: 53 * 54 * a 2-byte "packet type" which is one of: 55 * 56 * LINUX_SLL_HOST packet was sent to us 57 * LINUX_SLL_BROADCAST packet was broadcast 58 * LINUX_SLL_MULTICAST packet was multicast 59 * LINUX_SLL_OTHERHOST packet was sent to somebody else 60 * LINUX_SLL_OUTGOING packet was sent *by* us; 61 * 62 * a 2-byte Ethernet protocol field; 63 * 64 * a 2-byte link-layer type; 65 * 66 * a 2-byte link-layer address length; 67 * 68 * an 8-byte source link-layer address, whose actual length is 69 * specified by the previous value. 70 * 71 * All fields except for the link-layer address are in network byte order. 72 * 73 * DO NOT change the layout of this structure, or change any of the 74 * LINUX_SLL_ values below. If you must change the link-layer header 75 * for a "cooked" Linux capture, introduce a new DLT_ type (ask 76 * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it 77 * a value that collides with a value already being used), and use the 78 * new header in captures of that type, so that programs that can 79 * handle DLT_LINUX_SLL captures will continue to handle them correctly 80 * without any change, and so that capture files with different headers 81 * can be told apart and programs that read them can dissect the 82 * packets in them. 83 * 84 * This structure, and the #defines below, must be the same in the 85 * libpcap and tcpdump versions of "sll.h". 86 */ 87 88 /* 89 * A DLT_LINUX_SLL fake link-layer header. 90 */ 91 #define SLL_HDR_LEN 16 /* total header length */ 92 #define SLL_ADDRLEN 8 /* length of address field */ 93 94 struct sll_header { 95 nd_uint16_t sll_pkttype; /* packet type */ 96 nd_uint16_t sll_hatype; /* link-layer address type */ 97 nd_uint16_t sll_halen; /* link-layer address length */ 98 nd_byte sll_addr[SLL_ADDRLEN]; /* link-layer address */ 99 nd_uint16_t sll_protocol; /* protocol */ 100 }; 101 102 /* 103 * A DLT_LINUX_SLL2 fake link-layer header. 104 */ 105 #define SLL2_HDR_LEN 20 /* total header length */ 106 107 struct sll2_header { 108 nd_uint16_t sll2_protocol; /* protocol */ 109 nd_uint16_t sll2_reserved_mbz; /* reserved - must be zero */ 110 nd_uint32_t sll2_if_index; /* 1-based interface index */ 111 nd_uint16_t sll2_hatype; /* link-layer address type */ 112 nd_uint8_t sll2_pkttype; /* packet type */ 113 nd_uint8_t sll2_halen; /* link-layer address length */ 114 nd_byte sll2_addr[SLL_ADDRLEN]; /* link-layer address */ 115 }; 116 117 /* 118 * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the 119 * PACKET_ values on Linux, but are defined here so that they're 120 * available even on systems other than Linux, and so that they 121 * don't change even if the PACKET_ values change. 122 */ 123 #define LINUX_SLL_HOST 0 124 #define LINUX_SLL_BROADCAST 1 125 #define LINUX_SLL_MULTICAST 2 126 #define LINUX_SLL_OTHERHOST 3 127 #define LINUX_SLL_OUTGOING 4 128 129 /* 130 * The LINUX_SLL_ values for "sll_protocol"; these correspond to the 131 * ETH_P_ values on Linux, but are defined here so that they're 132 * available even on systems other than Linux. We assume, for now, 133 * that the ETH_P_ values won't change in Linux; if they do, then: 134 * 135 * if we don't translate them in "pcap-linux.c", capture files 136 * won't necessarily be readable if captured on a system that 137 * defines ETH_P_ values that don't match these values; 138 * 139 * if we do translate them in "pcap-linux.c", that makes life 140 * unpleasant for the BPF code generator, as the values you test 141 * for in the kernel aren't the values that you test for when 142 * reading a capture file, so the fixup code run on BPF programs 143 * handed to the kernel ends up having to do more work. 144 * 145 * Add other values here as necessary, for handling packet types that 146 * might show up on non-Ethernet, non-802.x networks. (Not all the ones 147 * in the Linux "if_ether.h" will, I suspect, actually show up in 148 * captures.) 149 */ 150 #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ 151 #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ 152 153 static const struct tok sll_pkttype_values[] = { 154 { LINUX_SLL_HOST, "In" }, 155 { LINUX_SLL_BROADCAST, "B" }, 156 { LINUX_SLL_MULTICAST, "M" }, 157 { LINUX_SLL_OTHERHOST, "P" }, 158 { LINUX_SLL_OUTGOING, "Out" }, 159 { 0, NULL} 160 }; 161 162 static void 163 sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length) 164 { 165 u_short ether_type; 166 167 ndo->ndo_protocol = "sll"; 168 ND_PRINT("%3s ", 169 tok2str(sll_pkttype_values,"?",GET_BE_U_2(sllp->sll_pkttype))); 170 171 /* 172 * XXX - check the link-layer address type value? 173 * For now, we just assume 6 means Ethernet. 174 * XXX - print others as strings of hex? 175 */ 176 if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN) 177 ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr)); 178 179 if (!ndo->ndo_qflag) { 180 ether_type = GET_BE_U_2(sllp->sll_protocol); 181 182 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { 183 /* 184 * Not an Ethernet type; what type is it? 185 */ 186 switch (ether_type) { 187 188 case LINUX_SLL_P_802_3: 189 /* 190 * Ethernet_802.3 IPX frame. 191 */ 192 ND_PRINT("802.3"); 193 break; 194 195 case LINUX_SLL_P_802_2: 196 /* 197 * 802.2. 198 */ 199 ND_PRINT("802.2"); 200 break; 201 202 default: 203 /* 204 * What is it? 205 */ 206 ND_PRINT("ethertype Unknown (0x%04x)", 207 ether_type); 208 break; 209 } 210 } else { 211 ND_PRINT("ethertype %s (0x%04x)", 212 tok2str(ethertype_values, "Unknown", ether_type), 213 ether_type); 214 } 215 ND_PRINT(", length %u: ", length); 216 } 217 } 218 219 /* 220 * This is the top level routine of the printer. 'p' points to the 221 * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp, 222 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 223 * is the number of bytes actually captured. 224 */ 225 void 226 sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) 227 { 228 u_int caplen = h->caplen; 229 u_int length = h->len; 230 const struct sll_header *sllp; 231 u_short hatype; 232 u_short ether_type; 233 int llc_hdrlen; 234 u_int hdrlen; 235 236 ndo->ndo_protocol = "sll"; 237 ND_TCHECK_LEN(p, SLL_HDR_LEN); 238 239 sllp = (const struct sll_header *)p; 240 241 if (ndo->ndo_eflag) 242 sll_print(ndo, sllp, length); 243 244 /* 245 * Go past the cooked-mode header. 246 */ 247 length -= SLL_HDR_LEN; 248 caplen -= SLL_HDR_LEN; 249 p += SLL_HDR_LEN; 250 hdrlen = SLL_HDR_LEN; 251 252 hatype = GET_BE_U_2(sllp->sll_hatype); 253 switch (hatype) { 254 255 case 803: 256 /* 257 * This is an packet with a radiotap header; 258 * just dissect the payload as such. 259 */ 260 ndo->ndo_ll_hdr_len += SLL_HDR_LEN; 261 ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen); 262 return; 263 } 264 ether_type = GET_BE_U_2(sllp->sll_protocol); 265 266 recurse: 267 /* 268 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet 269 * packet type? 270 */ 271 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { 272 /* 273 * Yes - what type is it? 274 */ 275 switch (ether_type) { 276 277 case LINUX_SLL_P_802_3: 278 /* 279 * Ethernet_802.3 IPX frame. 280 */ 281 ipx_print(ndo, p, length); 282 break; 283 284 case LINUX_SLL_P_802_2: 285 /* 286 * 802.2. 287 * Try to print the LLC-layer header & higher layers. 288 */ 289 llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); 290 if (llc_hdrlen < 0) 291 goto unknown; /* unknown LLC type */ 292 hdrlen += llc_hdrlen; 293 break; 294 295 default: 296 /*FALLTHROUGH*/ 297 298 unknown: 299 /* packet type not known, print raw packet */ 300 if (!ndo->ndo_suppress_default_print) 301 ND_DEFAULTPRINT(p, caplen); 302 break; 303 } 304 } else if (ether_type == ETHERTYPE_8021Q) { 305 /* 306 * Print VLAN information, and then go back and process 307 * the enclosed type field. 308 */ 309 if (caplen < 4) { 310 ndo->ndo_protocol = "vlan"; 311 nd_print_trunc(ndo); 312 ndo->ndo_ll_hdr_len += hdrlen + caplen; 313 return; 314 } 315 if (ndo->ndo_eflag) { 316 uint16_t tag = GET_BE_U_2(p); 317 318 ND_PRINT("%s, ", ieee8021q_tci_string(tag)); 319 } 320 321 ether_type = GET_BE_U_2(p + 2); 322 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) 323 ether_type = LINUX_SLL_P_802_2; 324 if (!ndo->ndo_qflag) { 325 ND_PRINT("ethertype %s, ", 326 tok2str(ethertype_values, "Unknown", ether_type)); 327 } 328 p += 4; 329 length -= 4; 330 caplen -= 4; 331 hdrlen += 4; 332 goto recurse; 333 } else { 334 if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { 335 /* ether_type not known, print raw packet */ 336 if (!ndo->ndo_eflag) 337 sll_print(ndo, sllp, length + SLL_HDR_LEN); 338 if (!ndo->ndo_suppress_default_print) 339 ND_DEFAULTPRINT(p, caplen); 340 } 341 } 342 343 ndo->ndo_ll_hdr_len += hdrlen; 344 } 345 346 static void 347 sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length) 348 { 349 u_short ether_type; 350 351 ndo->ndo_protocol = "sll2"; 352 ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index)); 353 354 /* 355 * XXX - check the link-layer address type value? 356 * For now, we just assume 6 means Ethernet. 357 * XXX - print others as strings of hex? 358 */ 359 if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN) 360 ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr)); 361 362 if (!ndo->ndo_qflag) { 363 ether_type = GET_BE_U_2(sllp->sll2_protocol); 364 365 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { 366 /* 367 * Not an Ethernet type; what type is it? 368 */ 369 switch (ether_type) { 370 371 case LINUX_SLL_P_802_3: 372 /* 373 * Ethernet_802.3 IPX frame. 374 */ 375 ND_PRINT("802.3"); 376 break; 377 378 case LINUX_SLL_P_802_2: 379 /* 380 * 802.2. 381 */ 382 ND_PRINT("802.2"); 383 break; 384 385 default: 386 /* 387 * What is it? 388 */ 389 ND_PRINT("ethertype Unknown (0x%04x)", 390 ether_type); 391 break; 392 } 393 } else { 394 ND_PRINT("ethertype %s (0x%04x)", 395 tok2str(ethertype_values, "Unknown", ether_type), 396 ether_type); 397 } 398 ND_PRINT(", length %u: ", length); 399 } 400 } 401 402 /* 403 * This is the top level routine of the printer. 'p' points to the 404 * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp, 405 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 406 * is the number of bytes actually captured. 407 */ 408 void 409 sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) 410 { 411 u_int caplen = h->caplen; 412 u_int length = h->len; 413 const struct sll2_header *sllp; 414 u_short hatype; 415 u_short ether_type; 416 int llc_hdrlen; 417 u_int hdrlen; 418 #ifdef HAVE_NET_IF_H 419 uint32_t if_index; 420 char ifname[IF_NAMESIZE]; 421 #endif 422 423 ndo->ndo_protocol = "sll2"; 424 ND_TCHECK_LEN(p, SLL2_HDR_LEN); 425 426 sllp = (const struct sll2_header *)p; 427 #ifdef HAVE_NET_IF_H 428 if_index = GET_BE_U_4(sllp->sll2_if_index); 429 if (!if_indextoname(if_index, ifname)) 430 strncpy(ifname, "?", 2); 431 ND_PRINT("%-5s ", ifname); 432 #endif 433 434 ND_PRINT("%-3s ", 435 tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype))); 436 437 if (ndo->ndo_eflag) 438 sll2_print(ndo, sllp, length); 439 440 /* 441 * Go past the cooked-mode header. 442 */ 443 length -= SLL2_HDR_LEN; 444 caplen -= SLL2_HDR_LEN; 445 p += SLL2_HDR_LEN; 446 hdrlen = SLL2_HDR_LEN; 447 448 hatype = GET_BE_U_2(sllp->sll2_hatype); 449 switch (hatype) { 450 451 case 803: 452 /* 453 * This is an packet with a radiotap header; 454 * just dissect the payload as such. 455 */ 456 ndo->ndo_ll_hdr_len += SLL2_HDR_LEN; 457 ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen); 458 return; 459 } 460 ether_type = GET_BE_U_2(sllp->sll2_protocol); 461 462 recurse: 463 /* 464 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet 465 * packet type? 466 */ 467 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) { 468 /* 469 * Yes - what type is it? 470 */ 471 switch (ether_type) { 472 473 case LINUX_SLL_P_802_3: 474 /* 475 * Ethernet_802.3 IPX frame. 476 */ 477 ipx_print(ndo, p, length); 478 break; 479 480 case LINUX_SLL_P_802_2: 481 /* 482 * 802.2. 483 * Try to print the LLC-layer header & higher layers. 484 */ 485 llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL); 486 if (llc_hdrlen < 0) 487 goto unknown; /* unknown LLC type */ 488 hdrlen += llc_hdrlen; 489 break; 490 491 default: 492 /*FALLTHROUGH*/ 493 494 unknown: 495 /* packet type not known, print raw packet */ 496 if (!ndo->ndo_suppress_default_print) 497 ND_DEFAULTPRINT(p, caplen); 498 break; 499 } 500 } else if (ether_type == ETHERTYPE_8021Q) { 501 /* 502 * Print VLAN information, and then go back and process 503 * the enclosed type field. 504 */ 505 if (caplen < 4) { 506 ndo->ndo_protocol = "vlan"; 507 nd_print_trunc(ndo); 508 ndo->ndo_ll_hdr_len += hdrlen + caplen; 509 return; 510 } 511 if (ndo->ndo_eflag) { 512 uint16_t tag = GET_BE_U_2(p); 513 514 ND_PRINT("%s, ", ieee8021q_tci_string(tag)); 515 } 516 517 ether_type = GET_BE_U_2(p + 2); 518 if (ether_type <= MAX_ETHERNET_LENGTH_VAL) 519 ether_type = LINUX_SLL_P_802_2; 520 if (!ndo->ndo_qflag) { 521 ND_PRINT("ethertype %s, ", 522 tok2str(ethertype_values, "Unknown", ether_type)); 523 } 524 p += 4; 525 length -= 4; 526 caplen -= 4; 527 hdrlen += 4; 528 goto recurse; 529 } else { 530 if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) { 531 /* ether_type not known, print raw packet */ 532 if (!ndo->ndo_eflag) 533 sll2_print(ndo, sllp, length + SLL2_HDR_LEN); 534 if (!ndo->ndo_suppress_default_print) 535 ND_DEFAULTPRINT(p, caplen); 536 } 537 } 538 539 ndo->ndo_ll_hdr_len += hdrlen; 540 } 541