xref: /freebsd/contrib/libpcap/pcap-util.c (revision afdbf109c6a661a729938f68211054a0a50d38ac)
16f9cba8fSJoseph Mingrone /*
26f9cba8fSJoseph Mingrone  * Copyright (c) 1993, 1994, 1995, 1996, 1997
36f9cba8fSJoseph Mingrone  *	The Regents of the University of California.  All rights reserved.
46f9cba8fSJoseph Mingrone  *
56f9cba8fSJoseph Mingrone  * Redistribution and use in source and binary forms, with or without
66f9cba8fSJoseph Mingrone  * modification, are permitted provided that: (1) source code distributions
76f9cba8fSJoseph Mingrone  * retain the above copyright notice and this paragraph in its entirety, (2)
86f9cba8fSJoseph Mingrone  * distributions including binary code include the above copyright notice and
96f9cba8fSJoseph Mingrone  * this paragraph in its entirety in the documentation or other materials
106f9cba8fSJoseph Mingrone  * provided with the distribution, and (3) all advertising materials mentioning
116f9cba8fSJoseph Mingrone  * features or use of this software display the following acknowledgement:
126f9cba8fSJoseph Mingrone  * ``This product includes software developed by the University of California,
136f9cba8fSJoseph Mingrone  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
146f9cba8fSJoseph Mingrone  * the University nor the names of its contributors may be used to endorse
156f9cba8fSJoseph Mingrone  * or promote products derived from this software without specific prior
166f9cba8fSJoseph Mingrone  * written permission.
176f9cba8fSJoseph Mingrone  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
186f9cba8fSJoseph Mingrone  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
196f9cba8fSJoseph Mingrone  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
206f9cba8fSJoseph Mingrone  *
21*afdbf109SJoseph Mingrone  * pcap-util.c - common code for various files
226f9cba8fSJoseph Mingrone  */
236f9cba8fSJoseph Mingrone 
246f9cba8fSJoseph Mingrone #include <config.h>
256f9cba8fSJoseph Mingrone 
266f9cba8fSJoseph Mingrone #include <pcap-types.h>
276f9cba8fSJoseph Mingrone 
28*afdbf109SJoseph Mingrone #include "pcap/can_socketcan.h"
29*afdbf109SJoseph Mingrone #include "pcap/sll.h"
30*afdbf109SJoseph Mingrone #include "pcap/usb.h"
31*afdbf109SJoseph Mingrone #include "pcap/nflog.h"
32*afdbf109SJoseph Mingrone 
336f9cba8fSJoseph Mingrone #include "pcap-int.h"
346f9cba8fSJoseph Mingrone #include "extract.h"
356f9cba8fSJoseph Mingrone #include "pcap-usb-linux-common.h"
366f9cba8fSJoseph Mingrone 
376f9cba8fSJoseph Mingrone #include "pcap-util.h"
386f9cba8fSJoseph Mingrone #include "pflog.h"
396f9cba8fSJoseph Mingrone 
406f9cba8fSJoseph Mingrone /*
416f9cba8fSJoseph Mingrone  * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
426f9cba8fSJoseph Mingrone  * that are saved in host byte order.
436f9cba8fSJoseph Mingrone  *
446f9cba8fSJoseph Mingrone  * When reading a DLT_PFLOG packet, we need to convert those fields from
456f9cba8fSJoseph Mingrone  * the byte order of the host that wrote the file to this host's byte
466f9cba8fSJoseph Mingrone  * order.
476f9cba8fSJoseph Mingrone  */
486f9cba8fSJoseph Mingrone static void
swap_pflog_header(const struct pcap_pkthdr * hdr,u_char * buf)496f9cba8fSJoseph Mingrone swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
506f9cba8fSJoseph Mingrone {
516f9cba8fSJoseph Mingrone 	u_int caplen = hdr->caplen;
526f9cba8fSJoseph Mingrone 	u_int length = hdr->len;
536f9cba8fSJoseph Mingrone 	u_int pfloghdr_length;
546f9cba8fSJoseph Mingrone 	struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
556f9cba8fSJoseph Mingrone 
566f9cba8fSJoseph Mingrone 	if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) ||
576f9cba8fSJoseph Mingrone 	    length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
586f9cba8fSJoseph Mingrone 		/* Not enough data to have the uid field */
596f9cba8fSJoseph Mingrone 		return;
606f9cba8fSJoseph Mingrone 	}
616f9cba8fSJoseph Mingrone 
626f9cba8fSJoseph Mingrone 	pfloghdr_length = pflhdr->length;
636f9cba8fSJoseph Mingrone 
646f9cba8fSJoseph Mingrone 	if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
656f9cba8fSJoseph Mingrone 		/* Header doesn't include uid field */
666f9cba8fSJoseph Mingrone 		return;
676f9cba8fSJoseph Mingrone 	}
686f9cba8fSJoseph Mingrone 	pflhdr->uid = SWAPLONG(pflhdr->uid);
696f9cba8fSJoseph Mingrone 
706f9cba8fSJoseph Mingrone 	if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) ||
716f9cba8fSJoseph Mingrone 	    length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
726f9cba8fSJoseph Mingrone 		/* Not enough data to have the pid field */
736f9cba8fSJoseph Mingrone 		return;
746f9cba8fSJoseph Mingrone 	}
756f9cba8fSJoseph Mingrone 	if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
766f9cba8fSJoseph Mingrone 		/* Header doesn't include pid field */
776f9cba8fSJoseph Mingrone 		return;
786f9cba8fSJoseph Mingrone 	}
796f9cba8fSJoseph Mingrone 	pflhdr->pid = SWAPLONG(pflhdr->pid);
806f9cba8fSJoseph Mingrone 
816f9cba8fSJoseph Mingrone 	if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) ||
826f9cba8fSJoseph Mingrone 	    length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
836f9cba8fSJoseph Mingrone 		/* Not enough data to have the rule_uid field */
846f9cba8fSJoseph Mingrone 		return;
856f9cba8fSJoseph Mingrone 	}
866f9cba8fSJoseph Mingrone 	if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
876f9cba8fSJoseph Mingrone 		/* Header doesn't include rule_uid field */
886f9cba8fSJoseph Mingrone 		return;
896f9cba8fSJoseph Mingrone 	}
906f9cba8fSJoseph Mingrone 	pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
916f9cba8fSJoseph Mingrone 
926f9cba8fSJoseph Mingrone 	if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) ||
936f9cba8fSJoseph Mingrone 	    length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
946f9cba8fSJoseph Mingrone 		/* Not enough data to have the rule_pid field */
956f9cba8fSJoseph Mingrone 		return;
966f9cba8fSJoseph Mingrone 	}
976f9cba8fSJoseph Mingrone 	if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
986f9cba8fSJoseph Mingrone 		/* Header doesn't include rule_pid field */
996f9cba8fSJoseph Mingrone 		return;
1006f9cba8fSJoseph Mingrone 	}
1016f9cba8fSJoseph Mingrone 	pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
1026f9cba8fSJoseph Mingrone }
1036f9cba8fSJoseph Mingrone 
1046f9cba8fSJoseph Mingrone /*
105*afdbf109SJoseph Mingrone  * Linux cooked capture packets with a protocol type of LINUX_SLL_P_CAN or
106*afdbf109SJoseph Mingrone  * LINUX_SLL_P_CANFD have SocketCAN CAN classic/CAN FD headers in front
107*afdbf109SJoseph Mingrone  * of the payload,with the CAN ID being in the byte order of the host
108*afdbf109SJoseph Mingrone  * that wrote the packet, and Linux cooked capture packets with a protocol
109*afdbf109SJoseph Mingrone  * type of LINUX_SLL_P_CANXL have SocketCAN CAN XL headers in front of the
110*afdbf109SJoseph Mingrone  * payload with the protocol/VCID field, the payload length, and the
111*afdbf109SJoseph Mingrone  * acceptance field in the byte order of the host that wrote the packet.
112*afdbf109SJoseph Mingrone  *
113*afdbf109SJoseph Mingrone  * When reading a Linux cooked capture packet, we need to check for those
114*afdbf109SJoseph Mingrone  * packets and, if the byte order host that wrote the packet, as
115*afdbf109SJoseph Mingrone  * indicated by the byte order of the pcap file or pcapng section
116*afdbf109SJoseph Mingrone  * containing the packet, is the opposite of our byte order, convert
117*afdbf109SJoseph Mingrone  * the header files to our byte order by byte-swapping them.
118*afdbf109SJoseph Mingrone  */
119*afdbf109SJoseph Mingrone static void
swap_socketcan_header(uint16_t protocol,u_int caplen,u_int length,u_char * buf)120*afdbf109SJoseph Mingrone swap_socketcan_header(uint16_t protocol, u_int caplen, u_int length,
121*afdbf109SJoseph Mingrone     u_char *buf)
122*afdbf109SJoseph Mingrone {
123*afdbf109SJoseph Mingrone 	pcap_can_socketcan_hdr *hdrp;
124*afdbf109SJoseph Mingrone 	pcap_can_socketcan_xl_hdr *xl_hdrp;
125*afdbf109SJoseph Mingrone 
126*afdbf109SJoseph Mingrone 	switch (protocol) {
127*afdbf109SJoseph Mingrone 
128*afdbf109SJoseph Mingrone 	case LINUX_SLL_P_CAN:
129*afdbf109SJoseph Mingrone 	case LINUX_SLL_P_CANFD:
130*afdbf109SJoseph Mingrone 		/*
131*afdbf109SJoseph Mingrone 		 * CAN classic/CAN FD packet; fix up the packet's header
132*afdbf109SJoseph Mingrone 		 * by byte-swapping the CAN ID field.
133*afdbf109SJoseph Mingrone 		 */
134*afdbf109SJoseph Mingrone 		hdrp = (pcap_can_socketcan_hdr *)buf;
135*afdbf109SJoseph Mingrone 		if (caplen < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id) ||
136*afdbf109SJoseph Mingrone 		    length < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id)) {
137*afdbf109SJoseph Mingrone 			/* Not enough data to have the can_id field */
138*afdbf109SJoseph Mingrone 			return;
139*afdbf109SJoseph Mingrone 		}
140*afdbf109SJoseph Mingrone 		hdrp->can_id = SWAPLONG(hdrp->can_id);
141*afdbf109SJoseph Mingrone 		break;
142*afdbf109SJoseph Mingrone 
143*afdbf109SJoseph Mingrone 	case LINUX_SLL_P_CANXL:
144*afdbf109SJoseph Mingrone 		/*
145*afdbf109SJoseph Mingrone 		 * CAN XL packet; fix up the packet's header by
146*afdbf109SJoseph Mingrone 		 * byte-swapping the priority/VCID field, the
147*afdbf109SJoseph Mingrone 		 * payload length, and the acceptance field.
148*afdbf109SJoseph Mingrone 		 */
149*afdbf109SJoseph Mingrone 		xl_hdrp = (pcap_can_socketcan_xl_hdr *)buf;
150*afdbf109SJoseph Mingrone 		if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid) ||
151*afdbf109SJoseph Mingrone 		    length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid)) {
152*afdbf109SJoseph Mingrone 			/* Not enough data to have the priority_vcid field */
153*afdbf109SJoseph Mingrone 			return;
154*afdbf109SJoseph Mingrone 		}
155*afdbf109SJoseph Mingrone 		xl_hdrp->priority_vcid = SWAPLONG(xl_hdrp->priority_vcid);
156*afdbf109SJoseph Mingrone 		if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length) ||
157*afdbf109SJoseph Mingrone 		    length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length)) {
158*afdbf109SJoseph Mingrone 			/* Not enough data to have the payload_length field */
159*afdbf109SJoseph Mingrone 			return;
160*afdbf109SJoseph Mingrone 		}
161*afdbf109SJoseph Mingrone 		xl_hdrp->payload_length = SWAPSHORT(xl_hdrp->payload_length);
162*afdbf109SJoseph Mingrone 		if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field) ||
163*afdbf109SJoseph Mingrone 		    length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field)) {
164*afdbf109SJoseph Mingrone 			/* Not enough data to have the acceptance_field field */
165*afdbf109SJoseph Mingrone 			return;
166*afdbf109SJoseph Mingrone 		}
167*afdbf109SJoseph Mingrone 		xl_hdrp->acceptance_field = SWAPLONG(xl_hdrp->acceptance_field);
168*afdbf109SJoseph Mingrone 		break;
169*afdbf109SJoseph Mingrone 
170*afdbf109SJoseph Mingrone 	default:
171*afdbf109SJoseph Mingrone 		/*
172*afdbf109SJoseph Mingrone 		 * Not a CAN packet; nothing to do.
173*afdbf109SJoseph Mingrone 		 */
174*afdbf109SJoseph Mingrone 		break;
175*afdbf109SJoseph Mingrone 	}
176*afdbf109SJoseph Mingrone }
177*afdbf109SJoseph Mingrone 
178*afdbf109SJoseph Mingrone /*
1796f9cba8fSJoseph Mingrone  * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
1806f9cba8fSJoseph Mingrone  * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
1816f9cba8fSJoseph Mingrone  * with the CAN ID being in host byte order.
1826f9cba8fSJoseph Mingrone  *
1836f9cba8fSJoseph Mingrone  * When reading a DLT_LINUX_SLL packet, we need to check for those
1846f9cba8fSJoseph Mingrone  * packets and convert the CAN ID from the byte order of the host that
1856f9cba8fSJoseph Mingrone  * wrote the file to this host's byte order.
1866f9cba8fSJoseph Mingrone  */
1876f9cba8fSJoseph Mingrone static void
swap_linux_sll_socketcan_header(const struct pcap_pkthdr * hdr,u_char * buf)188*afdbf109SJoseph Mingrone swap_linux_sll_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
1896f9cba8fSJoseph Mingrone {
1906f9cba8fSJoseph Mingrone 	u_int caplen = hdr->caplen;
1916f9cba8fSJoseph Mingrone 	u_int length = hdr->len;
1926f9cba8fSJoseph Mingrone 	struct sll_header *shdr = (struct sll_header *)buf;
1936f9cba8fSJoseph Mingrone 
1946f9cba8fSJoseph Mingrone 	if (caplen < (u_int) sizeof(struct sll_header) ||
1956f9cba8fSJoseph Mingrone 	    length < (u_int) sizeof(struct sll_header)) {
1966f9cba8fSJoseph Mingrone 		/* Not enough data to have the protocol field */
1976f9cba8fSJoseph Mingrone 		return;
1986f9cba8fSJoseph Mingrone 	}
1996f9cba8fSJoseph Mingrone 
2006f9cba8fSJoseph Mingrone 	/*
201*afdbf109SJoseph Mingrone 	 * Byte-swap what needs to be byte-swapped.
2026f9cba8fSJoseph Mingrone 	 */
203*afdbf109SJoseph Mingrone 	swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll_protocol),
204*afdbf109SJoseph Mingrone 	    caplen - (u_int) sizeof(struct sll_header),
205*afdbf109SJoseph Mingrone 	    length - (u_int) sizeof(struct sll_header),
206*afdbf109SJoseph Mingrone 	    buf + sizeof(struct sll_header));
2076f9cba8fSJoseph Mingrone }
2086f9cba8fSJoseph Mingrone 
2096f9cba8fSJoseph Mingrone /*
2106f9cba8fSJoseph Mingrone  * The same applies for DLT_LINUX_SLL2.
2116f9cba8fSJoseph Mingrone  */
2126f9cba8fSJoseph Mingrone static void
swap_linux_sll2_socketcan_header(const struct pcap_pkthdr * hdr,u_char * buf)213*afdbf109SJoseph Mingrone swap_linux_sll2_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
2146f9cba8fSJoseph Mingrone {
2156f9cba8fSJoseph Mingrone 	u_int caplen = hdr->caplen;
2166f9cba8fSJoseph Mingrone 	u_int length = hdr->len;
2176f9cba8fSJoseph Mingrone 	struct sll2_header *shdr = (struct sll2_header *)buf;
2186f9cba8fSJoseph Mingrone 
2196f9cba8fSJoseph Mingrone 	if (caplen < (u_int) sizeof(struct sll2_header) ||
2206f9cba8fSJoseph Mingrone 	    length < (u_int) sizeof(struct sll2_header)) {
2216f9cba8fSJoseph Mingrone 		/* Not enough data to have the protocol field */
2226f9cba8fSJoseph Mingrone 		return;
2236f9cba8fSJoseph Mingrone 	}
2246f9cba8fSJoseph Mingrone 
2256f9cba8fSJoseph Mingrone 	/*
226*afdbf109SJoseph Mingrone 	 * Byte-swap what needs to be byte-swapped.
2276f9cba8fSJoseph Mingrone 	 */
228*afdbf109SJoseph Mingrone 	swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll2_protocol),
229*afdbf109SJoseph Mingrone 	    caplen - (u_int) sizeof(struct sll2_header),
230*afdbf109SJoseph Mingrone 	    length - (u_int) sizeof(struct sll2_header),
231*afdbf109SJoseph Mingrone 	    buf + sizeof(struct sll2_header));
2326f9cba8fSJoseph Mingrone }
2336f9cba8fSJoseph Mingrone 
2346f9cba8fSJoseph Mingrone /*
2356f9cba8fSJoseph Mingrone  * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
2366f9cba8fSJoseph Mingrone  * byte order when capturing (it's supplied directly from a
2376f9cba8fSJoseph Mingrone  * memory-mapped buffer shared by the kernel).
2386f9cba8fSJoseph Mingrone  *
2396f9cba8fSJoseph Mingrone  * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
2406f9cba8fSJoseph Mingrone  * need to convert it from the byte order of the host that wrote the
2416f9cba8fSJoseph Mingrone  * file to this host's byte order.
2426f9cba8fSJoseph Mingrone  */
2436f9cba8fSJoseph Mingrone static void
swap_linux_usb_header(const struct pcap_pkthdr * hdr,u_char * buf,int header_len_64_bytes)2446f9cba8fSJoseph Mingrone swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
2456f9cba8fSJoseph Mingrone     int header_len_64_bytes)
2466f9cba8fSJoseph Mingrone {
2476f9cba8fSJoseph Mingrone 	pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
2486f9cba8fSJoseph Mingrone 	bpf_u_int32 offset = 0;
2496f9cba8fSJoseph Mingrone 
2506f9cba8fSJoseph Mingrone 	/*
2516f9cba8fSJoseph Mingrone 	 * "offset" is the offset *past* the field we're swapping;
2526f9cba8fSJoseph Mingrone 	 * we skip the field *before* checking to make sure
2536f9cba8fSJoseph Mingrone 	 * the captured data length includes the entire field.
2546f9cba8fSJoseph Mingrone 	 */
2556f9cba8fSJoseph Mingrone 
2566f9cba8fSJoseph Mingrone 	/*
2576f9cba8fSJoseph Mingrone 	 * The URB id is a totally opaque value; do we really need to
2586f9cba8fSJoseph Mingrone 	 * convert it to the reading host's byte order???
2596f9cba8fSJoseph Mingrone 	 */
2606f9cba8fSJoseph Mingrone 	offset += 8;			/* skip past id */
2616f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2626f9cba8fSJoseph Mingrone 		return;
2636f9cba8fSJoseph Mingrone 	uhdr->id = SWAPLL(uhdr->id);
2646f9cba8fSJoseph Mingrone 
2656f9cba8fSJoseph Mingrone 	offset += 4;			/* skip past various 1-byte fields */
2666f9cba8fSJoseph Mingrone 
2676f9cba8fSJoseph Mingrone 	offset += 2;			/* skip past bus_id */
2686f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2696f9cba8fSJoseph Mingrone 		return;
2706f9cba8fSJoseph Mingrone 	uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
2716f9cba8fSJoseph Mingrone 
2726f9cba8fSJoseph Mingrone 	offset += 2;			/* skip past various 1-byte fields */
2736f9cba8fSJoseph Mingrone 
2746f9cba8fSJoseph Mingrone 	offset += 8;			/* skip past ts_sec */
2756f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2766f9cba8fSJoseph Mingrone 		return;
2776f9cba8fSJoseph Mingrone 	uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
2786f9cba8fSJoseph Mingrone 
2796f9cba8fSJoseph Mingrone 	offset += 4;			/* skip past ts_usec */
2806f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2816f9cba8fSJoseph Mingrone 		return;
2826f9cba8fSJoseph Mingrone 	uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
2836f9cba8fSJoseph Mingrone 
2846f9cba8fSJoseph Mingrone 	offset += 4;			/* skip past status */
2856f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2866f9cba8fSJoseph Mingrone 		return;
2876f9cba8fSJoseph Mingrone 	uhdr->status = SWAPLONG(uhdr->status);
2886f9cba8fSJoseph Mingrone 
2896f9cba8fSJoseph Mingrone 	offset += 4;			/* skip past urb_len */
2906f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2916f9cba8fSJoseph Mingrone 		return;
2926f9cba8fSJoseph Mingrone 	uhdr->urb_len = SWAPLONG(uhdr->urb_len);
2936f9cba8fSJoseph Mingrone 
2946f9cba8fSJoseph Mingrone 	offset += 4;			/* skip past data_len */
2956f9cba8fSJoseph Mingrone 	if (hdr->caplen < offset)
2966f9cba8fSJoseph Mingrone 		return;
2976f9cba8fSJoseph Mingrone 	uhdr->data_len = SWAPLONG(uhdr->data_len);
2986f9cba8fSJoseph Mingrone 
2996f9cba8fSJoseph Mingrone 	if (uhdr->transfer_type == URB_ISOCHRONOUS) {
3006f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past s.iso.error_count */
3016f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3026f9cba8fSJoseph Mingrone 			return;
3036f9cba8fSJoseph Mingrone 		uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
3046f9cba8fSJoseph Mingrone 
3056f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past s.iso.numdesc */
3066f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3076f9cba8fSJoseph Mingrone 			return;
3086f9cba8fSJoseph Mingrone 		uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
3096f9cba8fSJoseph Mingrone 	} else
3106f9cba8fSJoseph Mingrone 		offset += 8;			/* skip USB setup header */
3116f9cba8fSJoseph Mingrone 
3126f9cba8fSJoseph Mingrone 	/*
3136f9cba8fSJoseph Mingrone 	 * With the old header, there are no isochronous descriptors
3146f9cba8fSJoseph Mingrone 	 * after the header.
3156f9cba8fSJoseph Mingrone 	 *
3166f9cba8fSJoseph Mingrone 	 * With the new header, the actual number of descriptors in
3176f9cba8fSJoseph Mingrone 	 * the header is not s.iso.numdesc, it's ndesc - only the
3186f9cba8fSJoseph Mingrone 	 * first N descriptors, for some value of N, are put into
3196f9cba8fSJoseph Mingrone 	 * the header, and ndesc is set to the actual number copied.
3206f9cba8fSJoseph Mingrone 	 * In addition, if s.iso.numdesc is negative, no descriptors
3216f9cba8fSJoseph Mingrone 	 * are captured, and ndesc is set to 0.
3226f9cba8fSJoseph Mingrone 	 */
3236f9cba8fSJoseph Mingrone 	if (header_len_64_bytes) {
3246f9cba8fSJoseph Mingrone 		/*
3256f9cba8fSJoseph Mingrone 		 * This is either the "version 1" header, with
3266f9cba8fSJoseph Mingrone 		 * 16 bytes of additional fields at the end, or
3276f9cba8fSJoseph Mingrone 		 * a "version 0" header from a memory-mapped
3286f9cba8fSJoseph Mingrone 		 * capture, with 16 bytes of zeroed-out padding
3296f9cba8fSJoseph Mingrone 		 * at the end.  Byte swap them as if this were
3306f9cba8fSJoseph Mingrone 		 * a "version 1" header.
3316f9cba8fSJoseph Mingrone 		 */
3326f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past interval */
3336f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3346f9cba8fSJoseph Mingrone 			return;
3356f9cba8fSJoseph Mingrone 		uhdr->interval = SWAPLONG(uhdr->interval);
3366f9cba8fSJoseph Mingrone 
3376f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past start_frame */
3386f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3396f9cba8fSJoseph Mingrone 			return;
3406f9cba8fSJoseph Mingrone 		uhdr->start_frame = SWAPLONG(uhdr->start_frame);
3416f9cba8fSJoseph Mingrone 
3426f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past xfer_flags */
3436f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3446f9cba8fSJoseph Mingrone 			return;
3456f9cba8fSJoseph Mingrone 		uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
3466f9cba8fSJoseph Mingrone 
3476f9cba8fSJoseph Mingrone 		offset += 4;			/* skip past ndesc */
3486f9cba8fSJoseph Mingrone 		if (hdr->caplen < offset)
3496f9cba8fSJoseph Mingrone 			return;
3506f9cba8fSJoseph Mingrone 		uhdr->ndesc = SWAPLONG(uhdr->ndesc);
3516f9cba8fSJoseph Mingrone 
3526f9cba8fSJoseph Mingrone 		if (uhdr->transfer_type == URB_ISOCHRONOUS) {
3536f9cba8fSJoseph Mingrone 			/* swap the values in struct linux_usb_isodesc */
3546f9cba8fSJoseph Mingrone 			usb_isodesc *pisodesc;
3556f9cba8fSJoseph Mingrone 			uint32_t i;
3566f9cba8fSJoseph Mingrone 
3576f9cba8fSJoseph Mingrone 			pisodesc = (usb_isodesc *)(void *)(buf+offset);
3586f9cba8fSJoseph Mingrone 			for (i = 0; i < uhdr->ndesc; i++) {
3596f9cba8fSJoseph Mingrone 				offset += 4;		/* skip past status */
3606f9cba8fSJoseph Mingrone 				if (hdr->caplen < offset)
3616f9cba8fSJoseph Mingrone 					return;
3626f9cba8fSJoseph Mingrone 				pisodesc->status = SWAPLONG(pisodesc->status);
3636f9cba8fSJoseph Mingrone 
3646f9cba8fSJoseph Mingrone 				offset += 4;		/* skip past offset */
3656f9cba8fSJoseph Mingrone 				if (hdr->caplen < offset)
3666f9cba8fSJoseph Mingrone 					return;
3676f9cba8fSJoseph Mingrone 				pisodesc->offset = SWAPLONG(pisodesc->offset);
3686f9cba8fSJoseph Mingrone 
3696f9cba8fSJoseph Mingrone 				offset += 4;		/* skip past len */
3706f9cba8fSJoseph Mingrone 				if (hdr->caplen < offset)
3716f9cba8fSJoseph Mingrone 					return;
3726f9cba8fSJoseph Mingrone 				pisodesc->len = SWAPLONG(pisodesc->len);
3736f9cba8fSJoseph Mingrone 
3746f9cba8fSJoseph Mingrone 				offset += 4;		/* skip past padding */
3756f9cba8fSJoseph Mingrone 
3766f9cba8fSJoseph Mingrone 				pisodesc++;
3776f9cba8fSJoseph Mingrone 			}
3786f9cba8fSJoseph Mingrone 		}
3796f9cba8fSJoseph Mingrone 	}
3806f9cba8fSJoseph Mingrone }
3816f9cba8fSJoseph Mingrone 
3826f9cba8fSJoseph Mingrone /*
3836f9cba8fSJoseph Mingrone  * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
3846f9cba8fSJoseph Mingrone  * data.  They begin with a fixed-length header with big-endian fields,
3856f9cba8fSJoseph Mingrone  * followed by a set of TLVs, where the type and length are in host
3866f9cba8fSJoseph Mingrone  * byte order but the values are either big-endian or are a raw byte
3876f9cba8fSJoseph Mingrone  * sequence that's the same regardless of the host's byte order.
3886f9cba8fSJoseph Mingrone  *
3896f9cba8fSJoseph Mingrone  * When reading a DLT_NFLOG packet, we need to convert the type and
3906f9cba8fSJoseph Mingrone  * length values from the byte order of the host that wrote the file
3916f9cba8fSJoseph Mingrone  * to the byte order of this host.
3926f9cba8fSJoseph Mingrone  */
3936f9cba8fSJoseph Mingrone static void
swap_nflog_header(const struct pcap_pkthdr * hdr,u_char * buf)3946f9cba8fSJoseph Mingrone swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
3956f9cba8fSJoseph Mingrone {
3966f9cba8fSJoseph Mingrone 	u_char *p = buf;
3976f9cba8fSJoseph Mingrone 	nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
3986f9cba8fSJoseph Mingrone 	nflog_tlv_t *tlv;
3996f9cba8fSJoseph Mingrone 	u_int caplen = hdr->caplen;
4006f9cba8fSJoseph Mingrone 	u_int length = hdr->len;
401*afdbf109SJoseph Mingrone 	u_int size;
4026f9cba8fSJoseph Mingrone 
4036f9cba8fSJoseph Mingrone 	if (caplen < (u_int) sizeof(nflog_hdr_t) ||
4046f9cba8fSJoseph Mingrone 	    length < (u_int) sizeof(nflog_hdr_t)) {
4056f9cba8fSJoseph Mingrone 		/* Not enough data to have any TLVs. */
4066f9cba8fSJoseph Mingrone 		return;
4076f9cba8fSJoseph Mingrone 	}
4086f9cba8fSJoseph Mingrone 
4096f9cba8fSJoseph Mingrone 	if (nfhdr->nflog_version != 0) {
4106f9cba8fSJoseph Mingrone 		/* Unknown NFLOG version */
4116f9cba8fSJoseph Mingrone 		return;
4126f9cba8fSJoseph Mingrone 	}
4136f9cba8fSJoseph Mingrone 
4146f9cba8fSJoseph Mingrone 	length -= sizeof(nflog_hdr_t);
4156f9cba8fSJoseph Mingrone 	caplen -= sizeof(nflog_hdr_t);
4166f9cba8fSJoseph Mingrone 	p += sizeof(nflog_hdr_t);
4176f9cba8fSJoseph Mingrone 
4186f9cba8fSJoseph Mingrone 	while (caplen >= sizeof(nflog_tlv_t)) {
4196f9cba8fSJoseph Mingrone 		tlv = (nflog_tlv_t *) p;
4206f9cba8fSJoseph Mingrone 
4216f9cba8fSJoseph Mingrone 		/* Swap the type and length. */
4226f9cba8fSJoseph Mingrone 		tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
4236f9cba8fSJoseph Mingrone 		tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
4246f9cba8fSJoseph Mingrone 
4256f9cba8fSJoseph Mingrone 		/* Get the length of the TLV. */
4266f9cba8fSJoseph Mingrone 		size = tlv->tlv_length;
4276f9cba8fSJoseph Mingrone 		if (size % 4 != 0)
4286f9cba8fSJoseph Mingrone 			size += 4 - size % 4;
4296f9cba8fSJoseph Mingrone 
4306f9cba8fSJoseph Mingrone 		/* Is the TLV's length less than the minimum? */
4316f9cba8fSJoseph Mingrone 		if (size < sizeof(nflog_tlv_t)) {
4326f9cba8fSJoseph Mingrone 			/* Yes. Give up now. */
4336f9cba8fSJoseph Mingrone 			return;
4346f9cba8fSJoseph Mingrone 		}
4356f9cba8fSJoseph Mingrone 
4366f9cba8fSJoseph Mingrone 		/* Do we have enough data for the full TLV? */
4376f9cba8fSJoseph Mingrone 		if (caplen < size || length < size) {
4386f9cba8fSJoseph Mingrone 			/* No. */
4396f9cba8fSJoseph Mingrone 			return;
4406f9cba8fSJoseph Mingrone 		}
4416f9cba8fSJoseph Mingrone 
4426f9cba8fSJoseph Mingrone 		/* Skip over the TLV. */
4436f9cba8fSJoseph Mingrone 		length -= size;
4446f9cba8fSJoseph Mingrone 		caplen -= size;
4456f9cba8fSJoseph Mingrone 		p += size;
4466f9cba8fSJoseph Mingrone 	}
4476f9cba8fSJoseph Mingrone }
4486f9cba8fSJoseph Mingrone 
4496f9cba8fSJoseph Mingrone static void
swap_pseudo_headers(int linktype,struct pcap_pkthdr * hdr,u_char * data)4506f9cba8fSJoseph Mingrone swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
4516f9cba8fSJoseph Mingrone {
4526f9cba8fSJoseph Mingrone 	/*
4536f9cba8fSJoseph Mingrone 	 * Convert pseudo-headers from the byte order of
4546f9cba8fSJoseph Mingrone 	 * the host on which the file was saved to our
4556f9cba8fSJoseph Mingrone 	 * byte order, as necessary.
4566f9cba8fSJoseph Mingrone 	 */
4576f9cba8fSJoseph Mingrone 	switch (linktype) {
4586f9cba8fSJoseph Mingrone 
4596f9cba8fSJoseph Mingrone 	case DLT_PFLOG:
4606f9cba8fSJoseph Mingrone 		swap_pflog_header(hdr, data);
4616f9cba8fSJoseph Mingrone 		break;
4626f9cba8fSJoseph Mingrone 
4636f9cba8fSJoseph Mingrone 	case DLT_LINUX_SLL:
464*afdbf109SJoseph Mingrone 		swap_linux_sll_socketcan_header(hdr, data);
4656f9cba8fSJoseph Mingrone 		break;
4666f9cba8fSJoseph Mingrone 
4676f9cba8fSJoseph Mingrone 	case DLT_LINUX_SLL2:
468*afdbf109SJoseph Mingrone 		swap_linux_sll2_socketcan_header(hdr, data);
4696f9cba8fSJoseph Mingrone 		break;
4706f9cba8fSJoseph Mingrone 
4716f9cba8fSJoseph Mingrone 	case DLT_USB_LINUX:
4726f9cba8fSJoseph Mingrone 		swap_linux_usb_header(hdr, data, 0);
4736f9cba8fSJoseph Mingrone 		break;
4746f9cba8fSJoseph Mingrone 
4756f9cba8fSJoseph Mingrone 	case DLT_USB_LINUX_MMAPPED:
4766f9cba8fSJoseph Mingrone 		swap_linux_usb_header(hdr, data, 1);
4776f9cba8fSJoseph Mingrone 		break;
4786f9cba8fSJoseph Mingrone 
4796f9cba8fSJoseph Mingrone 	case DLT_NFLOG:
4806f9cba8fSJoseph Mingrone 		swap_nflog_header(hdr, data);
4816f9cba8fSJoseph Mingrone 		break;
4826f9cba8fSJoseph Mingrone 	}
4836f9cba8fSJoseph Mingrone }
4846f9cba8fSJoseph Mingrone 
485*afdbf109SJoseph Mingrone static inline int
packet_length_might_be_wrong(struct pcap_pkthdr * hdr,const pcap_usb_header_mmapped * usb_hdr)486*afdbf109SJoseph Mingrone packet_length_might_be_wrong(struct pcap_pkthdr *hdr,
487*afdbf109SJoseph Mingrone     const pcap_usb_header_mmapped *usb_hdr)
488*afdbf109SJoseph Mingrone {
489*afdbf109SJoseph Mingrone 	uint32_t old_style_packet_length;
490*afdbf109SJoseph Mingrone 
491*afdbf109SJoseph Mingrone 	/*
492*afdbf109SJoseph Mingrone 	 * Calculate the packet length the old way.
493*afdbf109SJoseph Mingrone 	 * We know that the multiplication won't overflow, but
494*afdbf109SJoseph Mingrone 	 * we don't know that the additions won't.  Calculate
495*afdbf109SJoseph Mingrone 	 * it with no overflow checks, as that's how it
496*afdbf109SJoseph Mingrone 	 * would have been calculated when it was captured.
497*afdbf109SJoseph Mingrone 	 */
498*afdbf109SJoseph Mingrone 	old_style_packet_length = iso_pseudo_header_len(usb_hdr) +
499*afdbf109SJoseph Mingrone 	    usb_hdr->urb_len;
500*afdbf109SJoseph Mingrone 	return (hdr->len == old_style_packet_length);
501*afdbf109SJoseph Mingrone }
502*afdbf109SJoseph Mingrone 
5036f9cba8fSJoseph Mingrone void
pcapint_post_process(int linktype,int swapped,struct pcap_pkthdr * hdr,u_char * data)504*afdbf109SJoseph Mingrone pcapint_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr,
5056f9cba8fSJoseph Mingrone     u_char *data)
5066f9cba8fSJoseph Mingrone {
5076f9cba8fSJoseph Mingrone 	if (swapped)
5086f9cba8fSJoseph Mingrone 		swap_pseudo_headers(linktype, hdr, data);
5096f9cba8fSJoseph Mingrone 
5106f9cba8fSJoseph Mingrone 	/*
511*afdbf109SJoseph Mingrone 	 * Is this a memory-mapped Linux USB capture?
512*afdbf109SJoseph Mingrone 	 */
513*afdbf109SJoseph Mingrone 	if (linktype == DLT_USB_LINUX_MMAPPED) {
514*afdbf109SJoseph Mingrone 		/*
515*afdbf109SJoseph Mingrone 		 * Yes.
516*afdbf109SJoseph Mingrone 		 *
517*afdbf109SJoseph Mingrone 		 * In older versions of libpcap, in memory-mapped Linux
518*afdbf109SJoseph Mingrone 		 * USB captures, the original length of completion events
519*afdbf109SJoseph Mingrone 		 * for incoming isochronous transfers was miscalculated;
520*afdbf109SJoseph Mingrone 		 * it needed to be calculated based on the offsets and
521*afdbf109SJoseph Mingrone 		 * lengths in the descriptors, not on the raw URB length,
522*afdbf109SJoseph Mingrone 		 * but it wasn't.
5236f9cba8fSJoseph Mingrone 		 *
5246f9cba8fSJoseph Mingrone 		 * If this packet contains transferred data (yes, data_flag
525*afdbf109SJoseph Mingrone 		 * is 0 if we *do* have data), it's a completion event
526*afdbf109SJoseph Mingrone 		 * for an incoming isochronous transfer, and the
527*afdbf109SJoseph Mingrone 		 * transfer length appears to have been calculated
528*afdbf109SJoseph Mingrone 		 * from the raw URB length, fix it.
5296f9cba8fSJoseph Mingrone 		 *
530*afdbf109SJoseph Mingrone 		 * We only do this if we have the full USB pseudo-header,
531*afdbf109SJoseph Mingrone 		 * because we will have to look at that header and at
532*afdbf109SJoseph Mingrone 		 * all of the isochronous descriptors.
5336f9cba8fSJoseph Mingrone 		 */
534*afdbf109SJoseph Mingrone 		if (hdr->caplen < sizeof (pcap_usb_header_mmapped)) {
5356f9cba8fSJoseph Mingrone 			/*
536*afdbf109SJoseph Mingrone 			 * We don't have the full pseudo-header.
5376f9cba8fSJoseph Mingrone 			 */
538*afdbf109SJoseph Mingrone 			return;
539*afdbf109SJoseph Mingrone 		}
540*afdbf109SJoseph Mingrone 
541*afdbf109SJoseph Mingrone 		const pcap_usb_header_mmapped *usb_hdr =
542*afdbf109SJoseph Mingrone 		    (const pcap_usb_header_mmapped *) data;
543*afdbf109SJoseph Mingrone 
544*afdbf109SJoseph Mingrone 		/*
545*afdbf109SJoseph Mingrone 		 * Make sure the number of descriptors is sane.
546*afdbf109SJoseph Mingrone 		 *
547*afdbf109SJoseph Mingrone 		 * The Linux binary USB monitor code limits the number of
548*afdbf109SJoseph Mingrone 		 * isochronous descriptors to 128; if the number in the file
549*afdbf109SJoseph Mingrone 		 * is larger than that, either 1) the file's been damaged
550*afdbf109SJoseph Mingrone 		 * or 2) the file was produced after the number was raised
551*afdbf109SJoseph Mingrone 		 * in the kernel.
552*afdbf109SJoseph Mingrone 		 *
553*afdbf109SJoseph Mingrone 		 * In case 1), the number can't be trusted, so don't rely on
554*afdbf109SJoseph Mingrone 		 * it to attempt to fix the original length field in the pcap
555*afdbf109SJoseph Mingrone 		 * or pcapng header.
556*afdbf109SJoseph Mingrone 		 *
557*afdbf109SJoseph Mingrone 		 * In case 2), the system was probably running a version of
558*afdbf109SJoseph Mingrone 		 * libpcap that didn't miscalculate the original length, so
559*afdbf109SJoseph Mingrone 		 * it probably doesn't need to be fixed.
560*afdbf109SJoseph Mingrone 		 *
561*afdbf109SJoseph Mingrone 		 * This avoids the possibility of the product of the number of
562*afdbf109SJoseph Mingrone 		 * descriptors and the size of descriptors won't overflow an
563*afdbf109SJoseph Mingrone 		 * unsigned 32-bit integer.
564*afdbf109SJoseph Mingrone 		 */
565*afdbf109SJoseph Mingrone 		if (usb_hdr->ndesc > USB_MAXDESC)
566*afdbf109SJoseph Mingrone 			return;
567*afdbf109SJoseph Mingrone 
568*afdbf109SJoseph Mingrone 		if (!usb_hdr->data_flag &&
569*afdbf109SJoseph Mingrone 		    is_isochronous_transfer_completion(usb_hdr) &&
570*afdbf109SJoseph Mingrone 		    packet_length_might_be_wrong(hdr, usb_hdr)) {
571*afdbf109SJoseph Mingrone 			u_int len;
572*afdbf109SJoseph Mingrone 
573*afdbf109SJoseph Mingrone 			/*
574*afdbf109SJoseph Mingrone 			 * Make sure we have all of the descriptors,
575*afdbf109SJoseph Mingrone 			 * as we will have to look at all of them.
576*afdbf109SJoseph Mingrone 			 *
577*afdbf109SJoseph Mingrone 			 * If not, we don't bother trying to fix
578*afdbf109SJoseph Mingrone 			 * anything.
579*afdbf109SJoseph Mingrone 			 */
580*afdbf109SJoseph Mingrone 			if (hdr->caplen < iso_pseudo_header_len(usb_hdr))
581*afdbf109SJoseph Mingrone 				return;
582*afdbf109SJoseph Mingrone 
583*afdbf109SJoseph Mingrone 			/*
584*afdbf109SJoseph Mingrone 			 * Calculate what the length should have been.
585*afdbf109SJoseph Mingrone 			 */
586*afdbf109SJoseph Mingrone 			len = incoming_isochronous_transfer_completed_len(hdr,
587*afdbf109SJoseph Mingrone 			    data);
588*afdbf109SJoseph Mingrone 
589*afdbf109SJoseph Mingrone 			/*
590*afdbf109SJoseph Mingrone 			 * len is the smaller of UINT_MAX and the total
591*afdbf109SJoseph Mingrone 			 * header plus data length.  That's guaranteed
592*afdbf109SJoseph Mingrone 			 * to fit in a UINT_MAX.
593*afdbf109SJoseph Mingrone 			 *
594*afdbf109SJoseph Mingrone 			 * Don't reduce the original length to a value
595*afdbf109SJoseph Mingrone 			 * below the captured length, however, as that
596*afdbf109SJoseph Mingrone 			 * is bogus.
597*afdbf109SJoseph Mingrone 			 */
598*afdbf109SJoseph Mingrone 			if (len >= hdr->caplen)
599*afdbf109SJoseph Mingrone 				hdr->len = len;
600*afdbf109SJoseph Mingrone 
601*afdbf109SJoseph Mingrone 			/*
602*afdbf109SJoseph Mingrone 			 * If the captured length is greater than the
603*afdbf109SJoseph Mingrone 			 * length, use the captured length.
604*afdbf109SJoseph Mingrone 			 *
605*afdbf109SJoseph Mingrone 			 * For completion events for incoming isochronous
606*afdbf109SJoseph Mingrone 			 * transfers, it's based on data_len, which is
607*afdbf109SJoseph Mingrone 			 * calculated the same way we calculated
608*afdbf109SJoseph Mingrone 			 * pre_truncation_data_len above, except that
609*afdbf109SJoseph Mingrone 			 * it has access to all the isochronous descriptors,
610*afdbf109SJoseph Mingrone 			 * not just the ones that the kernel were able to
611*afdbf109SJoseph Mingrone 			 * provide us or, for a capture file, that weren't
612*afdbf109SJoseph Mingrone 			 * sliced off by a snapshot length.
613*afdbf109SJoseph Mingrone 			 *
614*afdbf109SJoseph Mingrone 			 * However, it might have been reduced by the USB
615*afdbf109SJoseph Mingrone 			 * capture mechanism arbitrarily limiting the amount
616*afdbf109SJoseph Mingrone 			 * of data it provides to userland, or by the libpcap
617*afdbf109SJoseph Mingrone 			 * capture code limiting it to being no more than the
618*afdbf109SJoseph Mingrone 			 * snapshot, so we don't want to just use it all the
619*afdbf109SJoseph Mingrone 			 * time; we only do so to try to get a better estimate
620*afdbf109SJoseph Mingrone 			 * of the actual length - and to make sure the
621*afdbf109SJoseph Mingrone 			 * original length is always >= the captured length.
622*afdbf109SJoseph Mingrone 			 */
623*afdbf109SJoseph Mingrone 			if (hdr->caplen > hdr->len)
624*afdbf109SJoseph Mingrone 				hdr->len = hdr->caplen;
6256f9cba8fSJoseph Mingrone 		}
6266f9cba8fSJoseph Mingrone 	}
6276f9cba8fSJoseph Mingrone }
628