1 /* 2 * Copyright (c) 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 * pcap-util.c - common code for various files 22 */ 23 24 #include <config.h> 25 26 #include <pcap-types.h> 27 28 #include "pcap/can_socketcan.h" 29 #include "pcap/sll.h" 30 #include "pcap/usb.h" 31 #include "pcap/nflog.h" 32 33 #include "pcap-int.h" 34 #include "extract.h" 35 #include "pcap-usb-linux-common.h" 36 37 #include "pcap-util.h" 38 #include "pflog.h" 39 40 /* 41 * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields 42 * that are saved in host byte order. 43 * 44 * When reading a DLT_PFLOG packet, we need to convert those fields from 45 * the byte order of the host that wrote the file to this host's byte 46 * order. 47 */ 48 static void 49 swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf) 50 { 51 u_int caplen = hdr->caplen; 52 u_int length = hdr->len; 53 u_int pfloghdr_length; 54 struct pfloghdr *pflhdr = (struct pfloghdr *)buf; 55 56 if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) || 57 length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) { 58 /* Not enough data to have the uid field */ 59 return; 60 } 61 62 pfloghdr_length = pflhdr->length; 63 64 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) { 65 /* Header doesn't include uid field */ 66 return; 67 } 68 pflhdr->uid = SWAPLONG(pflhdr->uid); 69 70 if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) || 71 length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) { 72 /* Not enough data to have the pid field */ 73 return; 74 } 75 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) { 76 /* Header doesn't include pid field */ 77 return; 78 } 79 pflhdr->pid = SWAPLONG(pflhdr->pid); 80 81 if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) || 82 length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) { 83 /* Not enough data to have the rule_uid field */ 84 return; 85 } 86 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) { 87 /* Header doesn't include rule_uid field */ 88 return; 89 } 90 pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid); 91 92 if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) || 93 length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) { 94 /* Not enough data to have the rule_pid field */ 95 return; 96 } 97 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) { 98 /* Header doesn't include rule_pid field */ 99 return; 100 } 101 pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid); 102 } 103 104 /* 105 * Linux cooked capture packets with a protocol type of LINUX_SLL_P_CAN or 106 * LINUX_SLL_P_CANFD have SocketCAN CAN classic/CAN FD headers in front 107 * of the payload,with the CAN ID being in the byte order of the host 108 * that wrote the packet, and Linux cooked capture packets with a protocol 109 * type of LINUX_SLL_P_CANXL have SocketCAN CAN XL headers in front of the 110 * payload with the protocol/VCID field, the payload length, and the 111 * acceptance field in the byte order of the host that wrote the packet. 112 * 113 * When reading a Linux cooked capture packet, we need to check for those 114 * packets and, if the byte order host that wrote the packet, as 115 * indicated by the byte order of the pcap file or pcapng section 116 * containing the packet, is the opposite of our byte order, convert 117 * the header files to our byte order by byte-swapping them. 118 */ 119 static void 120 swap_socketcan_header(uint16_t protocol, u_int caplen, u_int length, 121 u_char *buf) 122 { 123 pcap_can_socketcan_hdr *hdrp; 124 pcap_can_socketcan_xl_hdr *xl_hdrp; 125 126 switch (protocol) { 127 128 case LINUX_SLL_P_CAN: 129 case LINUX_SLL_P_CANFD: 130 /* 131 * CAN classic/CAN FD packet; fix up the packet's header 132 * by byte-swapping the CAN ID field. 133 */ 134 hdrp = (pcap_can_socketcan_hdr *)buf; 135 if (caplen < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id) || 136 length < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id)) { 137 /* Not enough data to have the can_id field */ 138 return; 139 } 140 hdrp->can_id = SWAPLONG(hdrp->can_id); 141 break; 142 143 case LINUX_SLL_P_CANXL: 144 /* 145 * CAN XL packet; fix up the packet's header by 146 * byte-swapping the priority/VCID field, the 147 * payload length, and the acceptance field. 148 */ 149 xl_hdrp = (pcap_can_socketcan_xl_hdr *)buf; 150 if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid) || 151 length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid)) { 152 /* Not enough data to have the priority_vcid field */ 153 return; 154 } 155 xl_hdrp->priority_vcid = SWAPLONG(xl_hdrp->priority_vcid); 156 if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length) || 157 length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length)) { 158 /* Not enough data to have the payload_length field */ 159 return; 160 } 161 xl_hdrp->payload_length = SWAPSHORT(xl_hdrp->payload_length); 162 if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field) || 163 length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field)) { 164 /* Not enough data to have the acceptance_field field */ 165 return; 166 } 167 xl_hdrp->acceptance_field = SWAPLONG(xl_hdrp->acceptance_field); 168 break; 169 170 default: 171 /* 172 * Not a CAN packet; nothing to do. 173 */ 174 break; 175 } 176 } 177 178 /* 179 * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or 180 * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload, 181 * with the CAN ID being in host byte order. 182 * 183 * When reading a DLT_LINUX_SLL packet, we need to check for those 184 * packets and convert the CAN ID from the byte order of the host that 185 * wrote the file to this host's byte order. 186 */ 187 static void 188 swap_linux_sll_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf) 189 { 190 u_int caplen = hdr->caplen; 191 u_int length = hdr->len; 192 struct sll_header *shdr = (struct sll_header *)buf; 193 194 if (caplen < (u_int) sizeof(struct sll_header) || 195 length < (u_int) sizeof(struct sll_header)) { 196 /* Not enough data to have the protocol field */ 197 return; 198 } 199 200 /* 201 * Byte-swap what needs to be byte-swapped. 202 */ 203 swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll_protocol), 204 caplen - (u_int) sizeof(struct sll_header), 205 length - (u_int) sizeof(struct sll_header), 206 buf + sizeof(struct sll_header)); 207 } 208 209 /* 210 * The same applies for DLT_LINUX_SLL2. 211 */ 212 static void 213 swap_linux_sll2_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf) 214 { 215 u_int caplen = hdr->caplen; 216 u_int length = hdr->len; 217 struct sll2_header *shdr = (struct sll2_header *)buf; 218 219 if (caplen < (u_int) sizeof(struct sll2_header) || 220 length < (u_int) sizeof(struct sll2_header)) { 221 /* Not enough data to have the protocol field */ 222 return; 223 } 224 225 /* 226 * Byte-swap what needs to be byte-swapped. 227 */ 228 swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll2_protocol), 229 caplen - (u_int) sizeof(struct sll2_header), 230 length - (u_int) sizeof(struct sll2_header), 231 buf + sizeof(struct sll2_header)); 232 } 233 234 /* 235 * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host 236 * byte order when capturing (it's supplied directly from a 237 * memory-mapped buffer shared by the kernel). 238 * 239 * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we 240 * need to convert it from the byte order of the host that wrote the 241 * file to this host's byte order. 242 */ 243 static void 244 swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf, 245 int header_len_64_bytes) 246 { 247 pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf; 248 bpf_u_int32 offset = 0; 249 250 /* 251 * "offset" is the offset *past* the field we're swapping; 252 * we skip the field *before* checking to make sure 253 * the captured data length includes the entire field. 254 */ 255 256 /* 257 * The URB id is a totally opaque value; do we really need to 258 * convert it to the reading host's byte order??? 259 */ 260 offset += 8; /* skip past id */ 261 if (hdr->caplen < offset) 262 return; 263 uhdr->id = SWAPLL(uhdr->id); 264 265 offset += 4; /* skip past various 1-byte fields */ 266 267 offset += 2; /* skip past bus_id */ 268 if (hdr->caplen < offset) 269 return; 270 uhdr->bus_id = SWAPSHORT(uhdr->bus_id); 271 272 offset += 2; /* skip past various 1-byte fields */ 273 274 offset += 8; /* skip past ts_sec */ 275 if (hdr->caplen < offset) 276 return; 277 uhdr->ts_sec = SWAPLL(uhdr->ts_sec); 278 279 offset += 4; /* skip past ts_usec */ 280 if (hdr->caplen < offset) 281 return; 282 uhdr->ts_usec = SWAPLONG(uhdr->ts_usec); 283 284 offset += 4; /* skip past status */ 285 if (hdr->caplen < offset) 286 return; 287 uhdr->status = SWAPLONG(uhdr->status); 288 289 offset += 4; /* skip past urb_len */ 290 if (hdr->caplen < offset) 291 return; 292 uhdr->urb_len = SWAPLONG(uhdr->urb_len); 293 294 offset += 4; /* skip past data_len */ 295 if (hdr->caplen < offset) 296 return; 297 uhdr->data_len = SWAPLONG(uhdr->data_len); 298 299 if (uhdr->transfer_type == URB_ISOCHRONOUS) { 300 offset += 4; /* skip past s.iso.error_count */ 301 if (hdr->caplen < offset) 302 return; 303 uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count); 304 305 offset += 4; /* skip past s.iso.numdesc */ 306 if (hdr->caplen < offset) 307 return; 308 uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc); 309 } else 310 offset += 8; /* skip USB setup header */ 311 312 /* 313 * With the old header, there are no isochronous descriptors 314 * after the header. 315 * 316 * With the new header, the actual number of descriptors in 317 * the header is not s.iso.numdesc, it's ndesc - only the 318 * first N descriptors, for some value of N, are put into 319 * the header, and ndesc is set to the actual number copied. 320 * In addition, if s.iso.numdesc is negative, no descriptors 321 * are captured, and ndesc is set to 0. 322 */ 323 if (header_len_64_bytes) { 324 /* 325 * This is either the "version 1" header, with 326 * 16 bytes of additional fields at the end, or 327 * a "version 0" header from a memory-mapped 328 * capture, with 16 bytes of zeroed-out padding 329 * at the end. Byte swap them as if this were 330 * a "version 1" header. 331 */ 332 offset += 4; /* skip past interval */ 333 if (hdr->caplen < offset) 334 return; 335 uhdr->interval = SWAPLONG(uhdr->interval); 336 337 offset += 4; /* skip past start_frame */ 338 if (hdr->caplen < offset) 339 return; 340 uhdr->start_frame = SWAPLONG(uhdr->start_frame); 341 342 offset += 4; /* skip past xfer_flags */ 343 if (hdr->caplen < offset) 344 return; 345 uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags); 346 347 offset += 4; /* skip past ndesc */ 348 if (hdr->caplen < offset) 349 return; 350 uhdr->ndesc = SWAPLONG(uhdr->ndesc); 351 352 if (uhdr->transfer_type == URB_ISOCHRONOUS) { 353 /* swap the values in struct linux_usb_isodesc */ 354 usb_isodesc *pisodesc; 355 uint32_t i; 356 357 pisodesc = (usb_isodesc *)(void *)(buf+offset); 358 for (i = 0; i < uhdr->ndesc; i++) { 359 offset += 4; /* skip past status */ 360 if (hdr->caplen < offset) 361 return; 362 pisodesc->status = SWAPLONG(pisodesc->status); 363 364 offset += 4; /* skip past offset */ 365 if (hdr->caplen < offset) 366 return; 367 pisodesc->offset = SWAPLONG(pisodesc->offset); 368 369 offset += 4; /* skip past len */ 370 if (hdr->caplen < offset) 371 return; 372 pisodesc->len = SWAPLONG(pisodesc->len); 373 374 offset += 4; /* skip past padding */ 375 376 pisodesc++; 377 } 378 } 379 } 380 } 381 382 /* 383 * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order 384 * data. They begin with a fixed-length header with big-endian fields, 385 * followed by a set of TLVs, where the type and length are in host 386 * byte order but the values are either big-endian or are a raw byte 387 * sequence that's the same regardless of the host's byte order. 388 * 389 * When reading a DLT_NFLOG packet, we need to convert the type and 390 * length values from the byte order of the host that wrote the file 391 * to the byte order of this host. 392 */ 393 static void 394 swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf) 395 { 396 u_char *p = buf; 397 nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf; 398 nflog_tlv_t *tlv; 399 u_int caplen = hdr->caplen; 400 u_int length = hdr->len; 401 u_int size; 402 403 if (caplen < (u_int) sizeof(nflog_hdr_t) || 404 length < (u_int) sizeof(nflog_hdr_t)) { 405 /* Not enough data to have any TLVs. */ 406 return; 407 } 408 409 if (nfhdr->nflog_version != 0) { 410 /* Unknown NFLOG version */ 411 return; 412 } 413 414 length -= sizeof(nflog_hdr_t); 415 caplen -= sizeof(nflog_hdr_t); 416 p += sizeof(nflog_hdr_t); 417 418 while (caplen >= sizeof(nflog_tlv_t)) { 419 tlv = (nflog_tlv_t *) p; 420 421 /* Swap the type and length. */ 422 tlv->tlv_type = SWAPSHORT(tlv->tlv_type); 423 tlv->tlv_length = SWAPSHORT(tlv->tlv_length); 424 425 /* Get the length of the TLV. */ 426 size = tlv->tlv_length; 427 if (size % 4 != 0) 428 size += 4 - size % 4; 429 430 /* Is the TLV's length less than the minimum? */ 431 if (size < sizeof(nflog_tlv_t)) { 432 /* Yes. Give up now. */ 433 return; 434 } 435 436 /* Do we have enough data for the full TLV? */ 437 if (caplen < size || length < size) { 438 /* No. */ 439 return; 440 } 441 442 /* Skip over the TLV. */ 443 length -= size; 444 caplen -= size; 445 p += size; 446 } 447 } 448 449 static void 450 swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data) 451 { 452 /* 453 * Convert pseudo-headers from the byte order of 454 * the host on which the file was saved to our 455 * byte order, as necessary. 456 */ 457 switch (linktype) { 458 459 case DLT_PFLOG: 460 swap_pflog_header(hdr, data); 461 break; 462 463 case DLT_LINUX_SLL: 464 swap_linux_sll_socketcan_header(hdr, data); 465 break; 466 467 case DLT_LINUX_SLL2: 468 swap_linux_sll2_socketcan_header(hdr, data); 469 break; 470 471 case DLT_USB_LINUX: 472 swap_linux_usb_header(hdr, data, 0); 473 break; 474 475 case DLT_USB_LINUX_MMAPPED: 476 swap_linux_usb_header(hdr, data, 1); 477 break; 478 479 case DLT_NFLOG: 480 swap_nflog_header(hdr, data); 481 break; 482 } 483 } 484 485 static inline int 486 packet_length_might_be_wrong(struct pcap_pkthdr *hdr, 487 const pcap_usb_header_mmapped *usb_hdr) 488 { 489 uint32_t old_style_packet_length; 490 491 /* 492 * Calculate the packet length the old way. 493 * We know that the multiplication won't overflow, but 494 * we don't know that the additions won't. Calculate 495 * it with no overflow checks, as that's how it 496 * would have been calculated when it was captured. 497 */ 498 old_style_packet_length = iso_pseudo_header_len(usb_hdr) + 499 usb_hdr->urb_len; 500 return (hdr->len == old_style_packet_length); 501 } 502 503 void 504 pcapint_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr, 505 u_char *data) 506 { 507 if (swapped) 508 swap_pseudo_headers(linktype, hdr, data); 509 510 /* 511 * Is this a memory-mapped Linux USB capture? 512 */ 513 if (linktype == DLT_USB_LINUX_MMAPPED) { 514 /* 515 * Yes. 516 * 517 * In older versions of libpcap, in memory-mapped Linux 518 * USB captures, the original length of completion events 519 * for incoming isochronous transfers was miscalculated; 520 * it needed to be calculated based on the offsets and 521 * lengths in the descriptors, not on the raw URB length, 522 * but it wasn't. 523 * 524 * If this packet contains transferred data (yes, data_flag 525 * is 0 if we *do* have data), it's a completion event 526 * for an incoming isochronous transfer, and the 527 * transfer length appears to have been calculated 528 * from the raw URB length, fix it. 529 * 530 * We only do this if we have the full USB pseudo-header, 531 * because we will have to look at that header and at 532 * all of the isochronous descriptors. 533 */ 534 if (hdr->caplen < sizeof (pcap_usb_header_mmapped)) { 535 /* 536 * We don't have the full pseudo-header. 537 */ 538 return; 539 } 540 541 const pcap_usb_header_mmapped *usb_hdr = 542 (const pcap_usb_header_mmapped *) data; 543 544 /* 545 * Make sure the number of descriptors is sane. 546 * 547 * The Linux binary USB monitor code limits the number of 548 * isochronous descriptors to 128; if the number in the file 549 * is larger than that, either 1) the file's been damaged 550 * or 2) the file was produced after the number was raised 551 * in the kernel. 552 * 553 * In case 1), the number can't be trusted, so don't rely on 554 * it to attempt to fix the original length field in the pcap 555 * or pcapng header. 556 * 557 * In case 2), the system was probably running a version of 558 * libpcap that didn't miscalculate the original length, so 559 * it probably doesn't need to be fixed. 560 * 561 * This avoids the possibility of the product of the number of 562 * descriptors and the size of descriptors won't overflow an 563 * unsigned 32-bit integer. 564 */ 565 if (usb_hdr->ndesc > USB_MAXDESC) 566 return; 567 568 if (!usb_hdr->data_flag && 569 is_isochronous_transfer_completion(usb_hdr) && 570 packet_length_might_be_wrong(hdr, usb_hdr)) { 571 u_int len; 572 573 /* 574 * Make sure we have all of the descriptors, 575 * as we will have to look at all of them. 576 * 577 * If not, we don't bother trying to fix 578 * anything. 579 */ 580 if (hdr->caplen < iso_pseudo_header_len(usb_hdr)) 581 return; 582 583 /* 584 * Calculate what the length should have been. 585 */ 586 len = incoming_isochronous_transfer_completed_len(hdr, 587 data); 588 589 /* 590 * len is the smaller of UINT_MAX and the total 591 * header plus data length. That's guaranteed 592 * to fit in a UINT_MAX. 593 * 594 * Don't reduce the original length to a value 595 * below the captured length, however, as that 596 * is bogus. 597 */ 598 if (len >= hdr->caplen) 599 hdr->len = len; 600 601 /* 602 * If the captured length is greater than the 603 * length, use the captured length. 604 * 605 * For completion events for incoming isochronous 606 * transfers, it's based on data_len, which is 607 * calculated the same way we calculated 608 * pre_truncation_data_len above, except that 609 * it has access to all the isochronous descriptors, 610 * not just the ones that the kernel were able to 611 * provide us or, for a capture file, that weren't 612 * sliced off by a snapshot length. 613 * 614 * However, it might have been reduced by the USB 615 * capture mechanism arbitrarily limiting the amount 616 * of data it provides to userland, or by the libpcap 617 * capture code limiting it to being no more than the 618 * snapshot, so we don't want to just use it all the 619 * time; we only do so to try to get a better estimate 620 * of the actual length - and to make sure the 621 * original length is always >= the captured length. 622 */ 623 if (hdr->caplen > hdr->len) 624 hdr->len = hdr->caplen; 625 } 626 } 627 } 628