Local changes: - In contrib/libpcap/pcap/bpf.h, do not include pcap/dlt.h. Our system net/dlt.h is pulled in from net/bpf.h. - sys/net/dlt.h: Incorporate changes from libpcap 1.10.3. - lib/libpcap/Makefile: Update for libpcap 1.10.3. Changelog: https://git.tcpdump.org/libpcap/blob/95691ebe7564afa3faa5c6ba0dbd17e351be455a:/CHANGES Reviewed by: emaste Obtained from: https://www.tcpdump.org/release/libpcap-1.10.3.tar.gz Sponsored by: The FreeBSD Foundation
131 lines
4.8 KiB
C
131 lines
4.8 KiB
C
/*
|
|
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that: (1) source code distributions
|
|
* retain the above copyright notice and this paragraph in its entirety, (2)
|
|
* distributions including binary code include the above copyright notice and
|
|
* this paragraph in its entirety in the documentation or other materials
|
|
* provided with the distribution, and (3) all advertising materials mentioning
|
|
* features or use of this software display the following acknowledgement:
|
|
* ``This product includes software developed by the University of California,
|
|
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
|
* the University nor the names of its contributors may be used to endorse
|
|
* or promote products derived from this software without specific prior
|
|
* written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* pcap-usb-linux-common.c - common code for everything that needs to
|
|
* deal with Linux USB captures.
|
|
*/
|
|
|
|
#include "pcap/pcap.h"
|
|
#include "pcap/usb.h"
|
|
|
|
#include "pcap-usb-linux-common.h"
|
|
|
|
/*
|
|
* Compute, from the data provided by the Linux USB memory-mapped capture
|
|
* mechanism, the amount of packet data that would have been provided
|
|
* had the capture mechanism not chopped off any data at the end, if, in
|
|
* fact, it did so.
|
|
*
|
|
* Set the "unsliced length" field of the packet header to that value.
|
|
*/
|
|
void
|
|
fix_linux_usb_mmapped_length(struct pcap_pkthdr *pkth, const u_char *bp)
|
|
{
|
|
const pcap_usb_header_mmapped *hdr;
|
|
u_int bytes_left;
|
|
|
|
/*
|
|
* All callers of this routine must ensure that pkth->caplen is
|
|
* >= sizeof (pcap_usb_header_mmapped).
|
|
*/
|
|
bytes_left = pkth->caplen;
|
|
bytes_left -= sizeof (pcap_usb_header_mmapped);
|
|
|
|
hdr = (const pcap_usb_header_mmapped *) bp;
|
|
if (!hdr->data_flag && hdr->transfer_type == URB_ISOCHRONOUS &&
|
|
hdr->event_type == URB_COMPLETE &&
|
|
(hdr->endpoint_number & URB_TRANSFER_IN) &&
|
|
pkth->len == sizeof(pcap_usb_header_mmapped) +
|
|
(hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len) {
|
|
usb_isodesc *descs;
|
|
u_int pre_truncation_data_len, pre_truncation_len;
|
|
|
|
descs = (usb_isodesc *) (bp + sizeof(pcap_usb_header_mmapped));
|
|
|
|
/*
|
|
* We have data (yes, data_flag is 0 if we *do* have data),
|
|
* and this is a "this is complete" incoming isochronous
|
|
* transfer event, and the length was calculated based
|
|
* on the URB length.
|
|
*
|
|
* That's not correct, because the data isn't contiguous,
|
|
* and the isochronous descriptos show how it's scattered.
|
|
*
|
|
* Find the end of the last chunk of data in the buffer
|
|
* referred to by the isochronous descriptors; that indicates
|
|
* how far into the buffer the data would have gone.
|
|
*
|
|
* Make sure we don't run past the end of the captured data
|
|
* while processing the isochronous descriptors.
|
|
*/
|
|
pre_truncation_data_len = 0;
|
|
for (uint32_t desc = 0;
|
|
desc < hdr->ndesc && bytes_left >= sizeof (usb_isodesc);
|
|
desc++, bytes_left -= sizeof (usb_isodesc)) {
|
|
u_int desc_end;
|
|
|
|
if (descs[desc].len != 0) {
|
|
desc_end = descs[desc].offset + descs[desc].len;
|
|
if (desc_end > pre_truncation_data_len)
|
|
pre_truncation_data_len = desc_end;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Now calculate the total length based on that data
|
|
* length.
|
|
*/
|
|
pre_truncation_len = sizeof(pcap_usb_header_mmapped) +
|
|
(hdr->ndesc * sizeof (usb_isodesc)) +
|
|
pre_truncation_data_len;
|
|
|
|
/*
|
|
* If that's greater than or equal to the captured length,
|
|
* use that as the length.
|
|
*/
|
|
if (pre_truncation_len >= pkth->caplen)
|
|
pkth->len = pre_truncation_len;
|
|
|
|
/*
|
|
* If the captured length is greater than the length,
|
|
* use the captured length.
|
|
*
|
|
* For completion events for incoming isochronous transfers,
|
|
* it's based on data_len, which is calculated the same way
|
|
* we calculated pre_truncation_data_len above, except that
|
|
* it has access to all the isochronous descriptors, not
|
|
* just the ones that the kernel were able to provide us or,
|
|
* for a capture file, that weren't sliced off by a snapshot
|
|
* length.
|
|
*
|
|
* However, it might have been reduced by the USB capture
|
|
* mechanism arbitrarily limiting the amount of data it
|
|
* provides to userland, or by the libpcap capture code
|
|
* limiting it to being no more than the snapshot, so
|
|
* we don't want to just use it all the time; we only
|
|
* do so to try to get a better estimate of the actual
|
|
* length - and to make sure the on-the-network length
|
|
* is always >= the captured length.
|
|
*/
|
|
if (pkth->caplen > pkth->len)
|
|
pkth->len = pkth->caplen;
|
|
}
|
|
}
|