2 * Copyright (c) 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
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.
21 * pcap-util.c - common code for various files
28 #include <pcap-types.h>
30 #include "pcap/can_socketcan.h"
33 #include "pcap/nflog.h"
37 #include "pcap-usb-linux-common.h"
39 #include "pcap-util.h"
43 * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
44 * that are saved in host byte order.
46 * When reading a DLT_PFLOG packet, we need to convert those fields from
47 * the byte order of the host that wrote the file to this host's byte
51 swap_pflog_header(const struct pcap_pkthdr
*hdr
, u_char
*buf
)
53 u_int caplen
= hdr
->caplen
;
54 u_int length
= hdr
->len
;
55 u_int pfloghdr_length
;
56 struct pfloghdr
*pflhdr
= (struct pfloghdr
*)buf
;
58 if (caplen
< (u_int
) (offsetof(struct pfloghdr
, uid
) + sizeof pflhdr
->uid
) ||
59 length
< (u_int
) (offsetof(struct pfloghdr
, uid
) + sizeof pflhdr
->uid
)) {
60 /* Not enough data to have the uid field */
64 pfloghdr_length
= pflhdr
->length
;
66 if (pfloghdr_length
< (u_int
) (offsetof(struct pfloghdr
, uid
) + sizeof pflhdr
->uid
)) {
67 /* Header doesn't include uid field */
70 pflhdr
->uid
= SWAPLONG(pflhdr
->uid
);
72 if (caplen
< (u_int
) (offsetof(struct pfloghdr
, pid
) + sizeof pflhdr
->pid
) ||
73 length
< (u_int
) (offsetof(struct pfloghdr
, pid
) + sizeof pflhdr
->pid
)) {
74 /* Not enough data to have the pid field */
77 if (pfloghdr_length
< (u_int
) (offsetof(struct pfloghdr
, pid
) + sizeof pflhdr
->pid
)) {
78 /* Header doesn't include pid field */
81 pflhdr
->pid
= SWAPLONG(pflhdr
->pid
);
83 if (caplen
< (u_int
) (offsetof(struct pfloghdr
, rule_uid
) + sizeof pflhdr
->rule_uid
) ||
84 length
< (u_int
) (offsetof(struct pfloghdr
, rule_uid
) + sizeof pflhdr
->rule_uid
)) {
85 /* Not enough data to have the rule_uid field */
88 if (pfloghdr_length
< (u_int
) (offsetof(struct pfloghdr
, rule_uid
) + sizeof pflhdr
->rule_uid
)) {
89 /* Header doesn't include rule_uid field */
92 pflhdr
->rule_uid
= SWAPLONG(pflhdr
->rule_uid
);
94 if (caplen
< (u_int
) (offsetof(struct pfloghdr
, rule_pid
) + sizeof pflhdr
->rule_pid
) ||
95 length
< (u_int
) (offsetof(struct pfloghdr
, rule_pid
) + sizeof pflhdr
->rule_pid
)) {
96 /* Not enough data to have the rule_pid field */
99 if (pfloghdr_length
< (u_int
) (offsetof(struct pfloghdr
, rule_pid
) + sizeof pflhdr
->rule_pid
)) {
100 /* Header doesn't include rule_pid field */
103 pflhdr
->rule_pid
= SWAPLONG(pflhdr
->rule_pid
);
107 * Linux cooked capture packets with a protocol type of LINUX_SLL_P_CAN or
108 * LINUX_SLL_P_CANFD have SocketCAN CAN classic/CAN FD headers in front
109 * of the payload,with the CAN ID being in the byte order of the host
110 * that wrote the packet, and Linux cooked capture packets with a protocol
111 * type of LINUX_SLL_P_CANXL have SocketCAN CAN XL headers in front of the
112 * payload with the protocol/VCID field, the payload length, and the
113 * acceptance field in the byte order of the host that wrote the packet.
115 * When reading a Linux cooked capture packet, we need to check for those
116 * packets and, if the byte order host that wrote the packet, as
117 * indicated by the byte order of the pcap file or pcapng section
118 * containing the packet, is the opposite of our byte order, convert
119 * the header files to our byte order by byte-swapping them.
122 swap_socketcan_header(uint16_t protocol
, u_int caplen
, u_int length
,
125 pcap_can_socketcan_hdr
*hdrp
;
126 pcap_can_socketcan_xl_hdr
*xl_hdrp
;
130 case LINUX_SLL_P_CAN
:
131 case LINUX_SLL_P_CANFD
:
133 * CAN classic/CAN FD packet; fix up the packet's header
134 * by byte-swapping the CAN ID field.
136 hdrp
= (pcap_can_socketcan_hdr
*)buf
;
137 if (caplen
< (u_int
) (offsetof(pcap_can_socketcan_hdr
, can_id
) + sizeof hdrp
->can_id
) ||
138 length
< (u_int
) (offsetof(pcap_can_socketcan_hdr
, can_id
) + sizeof hdrp
->can_id
)) {
139 /* Not enough data to have the can_id field */
142 hdrp
->can_id
= SWAPLONG(hdrp
->can_id
);
145 case LINUX_SLL_P_CANXL
:
147 * CAN XL packet; fix up the packet's header by
148 * byte-swapping the priority/VCID field, the
149 * payload length, and the acceptance field.
151 xl_hdrp
= (pcap_can_socketcan_xl_hdr
*)buf
;
152 if (caplen
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, priority_vcid
) + sizeof xl_hdrp
->priority_vcid
) ||
153 length
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, priority_vcid
) + sizeof xl_hdrp
->priority_vcid
)) {
154 /* Not enough data to have the priority_vcid field */
157 xl_hdrp
->priority_vcid
= SWAPLONG(xl_hdrp
->priority_vcid
);
158 if (caplen
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, payload_length
) + sizeof xl_hdrp
->payload_length
) ||
159 length
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, payload_length
) + sizeof xl_hdrp
->payload_length
)) {
160 /* Not enough data to have the payload_length field */
163 xl_hdrp
->payload_length
= SWAPSHORT(xl_hdrp
->payload_length
);
164 if (caplen
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, acceptance_field
) + sizeof xl_hdrp
->acceptance_field
) ||
165 length
< (u_int
) (offsetof(pcap_can_socketcan_xl_hdr
, acceptance_field
) + sizeof xl_hdrp
->acceptance_field
)) {
166 /* Not enough data to have the acceptance_field field */
169 xl_hdrp
->acceptance_field
= SWAPLONG(xl_hdrp
->acceptance_field
);
174 * Not a CAN packet; nothing to do.
181 * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
182 * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
183 * with the CAN ID being in host byte order.
185 * When reading a DLT_LINUX_SLL packet, we need to check for those
186 * packets and convert the CAN ID from the byte order of the host that
187 * wrote the file to this host's byte order.
190 swap_linux_sll_socketcan_header(const struct pcap_pkthdr
*hdr
, u_char
*buf
)
192 u_int caplen
= hdr
->caplen
;
193 u_int length
= hdr
->len
;
194 struct sll_header
*shdr
= (struct sll_header
*)buf
;
196 if (caplen
< (u_int
) sizeof(struct sll_header
) ||
197 length
< (u_int
) sizeof(struct sll_header
)) {
198 /* Not enough data to have the protocol field */
203 * Byte-swap what needs to be byte-swapped.
205 swap_socketcan_header(EXTRACT_BE_U_2(&shdr
->sll_protocol
),
206 caplen
- (u_int
) sizeof(struct sll_header
),
207 length
- (u_int
) sizeof(struct sll_header
),
208 buf
+ sizeof(struct sll_header
));
212 * The same applies for DLT_LINUX_SLL2.
215 swap_linux_sll2_socketcan_header(const struct pcap_pkthdr
*hdr
, u_char
*buf
)
217 u_int caplen
= hdr
->caplen
;
218 u_int length
= hdr
->len
;
219 struct sll2_header
*shdr
= (struct sll2_header
*)buf
;
221 if (caplen
< (u_int
) sizeof(struct sll2_header
) ||
222 length
< (u_int
) sizeof(struct sll2_header
)) {
223 /* Not enough data to have the protocol field */
228 * Byte-swap what needs to be byte-swapped.
230 swap_socketcan_header(EXTRACT_BE_U_2(&shdr
->sll2_protocol
),
231 caplen
- (u_int
) sizeof(struct sll2_header
),
232 length
- (u_int
) sizeof(struct sll2_header
),
233 buf
+ sizeof(struct sll2_header
));
237 * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
238 * byte order when capturing (it's supplied directly from a
239 * memory-mapped buffer shared by the kernel).
241 * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
242 * need to convert it from the byte order of the host that wrote the
243 * file to this host's byte order.
246 swap_linux_usb_header(const struct pcap_pkthdr
*hdr
, u_char
*buf
,
247 int header_len_64_bytes
)
249 pcap_usb_header_mmapped
*uhdr
= (pcap_usb_header_mmapped
*)buf
;
250 bpf_u_int32 offset
= 0;
253 * "offset" is the offset *past* the field we're swapping;
254 * we skip the field *before* checking to make sure
255 * the captured data length includes the entire field.
259 * The URB id is a totally opaque value; do we really need to
260 * convert it to the reading host's byte order???
262 offset
+= 8; /* skip past id */
263 if (hdr
->caplen
< offset
)
265 uhdr
->id
= SWAPLL(uhdr
->id
);
267 offset
+= 4; /* skip past various 1-byte fields */
269 offset
+= 2; /* skip past bus_id */
270 if (hdr
->caplen
< offset
)
272 uhdr
->bus_id
= SWAPSHORT(uhdr
->bus_id
);
274 offset
+= 2; /* skip past various 1-byte fields */
276 offset
+= 8; /* skip past ts_sec */
277 if (hdr
->caplen
< offset
)
279 uhdr
->ts_sec
= SWAPLL(uhdr
->ts_sec
);
281 offset
+= 4; /* skip past ts_usec */
282 if (hdr
->caplen
< offset
)
284 uhdr
->ts_usec
= SWAPLONG(uhdr
->ts_usec
);
286 offset
+= 4; /* skip past status */
287 if (hdr
->caplen
< offset
)
289 uhdr
->status
= SWAPLONG(uhdr
->status
);
291 offset
+= 4; /* skip past urb_len */
292 if (hdr
->caplen
< offset
)
294 uhdr
->urb_len
= SWAPLONG(uhdr
->urb_len
);
296 offset
+= 4; /* skip past data_len */
297 if (hdr
->caplen
< offset
)
299 uhdr
->data_len
= SWAPLONG(uhdr
->data_len
);
301 if (uhdr
->transfer_type
== URB_ISOCHRONOUS
) {
302 offset
+= 4; /* skip past s.iso.error_count */
303 if (hdr
->caplen
< offset
)
305 uhdr
->s
.iso
.error_count
= SWAPLONG(uhdr
->s
.iso
.error_count
);
307 offset
+= 4; /* skip past s.iso.numdesc */
308 if (hdr
->caplen
< offset
)
310 uhdr
->s
.iso
.numdesc
= SWAPLONG(uhdr
->s
.iso
.numdesc
);
312 offset
+= 8; /* skip USB setup header */
315 * With the old header, there are no isochronous descriptors
318 * With the new header, the actual number of descriptors in
319 * the header is not s.iso.numdesc, it's ndesc - only the
320 * first N descriptors, for some value of N, are put into
321 * the header, and ndesc is set to the actual number copied.
322 * In addition, if s.iso.numdesc is negative, no descriptors
323 * are captured, and ndesc is set to 0.
325 if (header_len_64_bytes
) {
327 * This is either the "version 1" header, with
328 * 16 bytes of additional fields at the end, or
329 * a "version 0" header from a memory-mapped
330 * capture, with 16 bytes of zeroed-out padding
331 * at the end. Byte swap them as if this were
332 * a "version 1" header.
334 offset
+= 4; /* skip past interval */
335 if (hdr
->caplen
< offset
)
337 uhdr
->interval
= SWAPLONG(uhdr
->interval
);
339 offset
+= 4; /* skip past start_frame */
340 if (hdr
->caplen
< offset
)
342 uhdr
->start_frame
= SWAPLONG(uhdr
->start_frame
);
344 offset
+= 4; /* skip past xfer_flags */
345 if (hdr
->caplen
< offset
)
347 uhdr
->xfer_flags
= SWAPLONG(uhdr
->xfer_flags
);
349 offset
+= 4; /* skip past ndesc */
350 if (hdr
->caplen
< offset
)
352 uhdr
->ndesc
= SWAPLONG(uhdr
->ndesc
);
354 if (uhdr
->transfer_type
== URB_ISOCHRONOUS
) {
355 /* swap the values in struct linux_usb_isodesc */
356 usb_isodesc
*pisodesc
;
359 pisodesc
= (usb_isodesc
*)(void *)(buf
+offset
);
360 for (i
= 0; i
< uhdr
->ndesc
; i
++) {
361 offset
+= 4; /* skip past status */
362 if (hdr
->caplen
< offset
)
364 pisodesc
->status
= SWAPLONG(pisodesc
->status
);
366 offset
+= 4; /* skip past offset */
367 if (hdr
->caplen
< offset
)
369 pisodesc
->offset
= SWAPLONG(pisodesc
->offset
);
371 offset
+= 4; /* skip past len */
372 if (hdr
->caplen
< offset
)
374 pisodesc
->len
= SWAPLONG(pisodesc
->len
);
376 offset
+= 4; /* skip past padding */
385 * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
386 * data. They begin with a fixed-length header with big-endian fields,
387 * followed by a set of TLVs, where the type and length are in host
388 * byte order but the values are either big-endian or are a raw byte
389 * sequence that's the same regardless of the host's byte order.
391 * When reading a DLT_NFLOG packet, we need to convert the type and
392 * length values from the byte order of the host that wrote the file
393 * to the byte order of this host.
396 swap_nflog_header(const struct pcap_pkthdr
*hdr
, u_char
*buf
)
399 nflog_hdr_t
*nfhdr
= (nflog_hdr_t
*)buf
;
401 u_int caplen
= hdr
->caplen
;
402 u_int length
= hdr
->len
;
405 if (caplen
< (u_int
) sizeof(nflog_hdr_t
) ||
406 length
< (u_int
) sizeof(nflog_hdr_t
)) {
407 /* Not enough data to have any TLVs. */
411 if (nfhdr
->nflog_version
!= 0) {
412 /* Unknown NFLOG version */
416 length
-= sizeof(nflog_hdr_t
);
417 caplen
-= sizeof(nflog_hdr_t
);
418 p
+= sizeof(nflog_hdr_t
);
420 while (caplen
>= sizeof(nflog_tlv_t
)) {
421 tlv
= (nflog_tlv_t
*) p
;
423 /* Swap the type and length. */
424 tlv
->tlv_type
= SWAPSHORT(tlv
->tlv_type
);
425 tlv
->tlv_length
= SWAPSHORT(tlv
->tlv_length
);
427 /* Get the length of the TLV. */
428 size
= tlv
->tlv_length
;
430 size
+= 4 - size
% 4;
432 /* Is the TLV's length less than the minimum? */
433 if (size
< sizeof(nflog_tlv_t
)) {
434 /* Yes. Give up now. */
438 /* Do we have enough data for the full TLV? */
439 if (caplen
< size
|| length
< size
) {
444 /* Skip over the TLV. */
452 swap_pseudo_headers(int linktype
, struct pcap_pkthdr
*hdr
, u_char
*data
)
455 * Convert pseudo-headers from the byte order of
456 * the host on which the file was saved to our
457 * byte order, as necessary.
462 swap_pflog_header(hdr
, data
);
466 swap_linux_sll_socketcan_header(hdr
, data
);
470 swap_linux_sll2_socketcan_header(hdr
, data
);
474 swap_linux_usb_header(hdr
, data
, 0);
477 case DLT_USB_LINUX_MMAPPED
:
478 swap_linux_usb_header(hdr
, data
, 1);
482 swap_nflog_header(hdr
, data
);
488 packet_length_might_be_wrong(struct pcap_pkthdr
*hdr
,
489 const pcap_usb_header_mmapped
*usb_hdr
)
491 uint32_t old_style_packet_length
;
494 * Calculate the packet length the old way.
495 * We know that the multiplication won't overflow, but
496 * we don't know that the additions won't. Calculate
497 * it with no overflow checks, as that's how it
498 * would have been calculated when it was captured.
500 old_style_packet_length
= iso_pseudo_header_len(usb_hdr
) +
502 return (hdr
->len
== old_style_packet_length
);
506 pcapint_post_process(int linktype
, int swapped
, struct pcap_pkthdr
*hdr
,
510 swap_pseudo_headers(linktype
, hdr
, data
);
513 * Is this a memory-mapped Linux USB capture?
515 if (linktype
== DLT_USB_LINUX_MMAPPED
) {
519 * In older versions of libpcap, in memory-mapped Linux
520 * USB captures, the original length of completion events
521 * for incoming isochronous transfers was miscalculated;
522 * it needed to be calculated based on the offsets and
523 * lengths in the descriptors, not on the raw URB length,
526 * If this packet contains transferred data (yes, data_flag
527 * is 0 if we *do* have data), it's a completion event
528 * for an incoming isochronous transfer, and the
529 * transfer length appears to have been calculated
530 * from the raw URB length, fix it.
532 * We only do this if we have the full USB pseudo-header,
533 * because we will have to look at that header and at
534 * all of the isochronous descriptors.
536 if (hdr
->caplen
< sizeof (pcap_usb_header_mmapped
)) {
538 * We don't have the full pseudo-header.
543 const pcap_usb_header_mmapped
*usb_hdr
=
544 (const pcap_usb_header_mmapped
*) data
;
547 * Make sure the number of descriptors is sane.
549 * The Linux binary USB monitor code limits the number of
550 * isochronous descriptors to 128; if the number in the file
551 * is larger than that, either 1) the file's been damaged
552 * or 2) the file was produced after the number was raised
555 * In case 1), the number can't be trusted, so don't rely on
556 * it to attempt to fix the original length field in the pcap
559 * In case 2), the system was probably running a version of
560 * libpcap that didn't miscalculate the original length, so
561 * it probably doesn't need to be fixed.
563 * This avoids the possibility of the product of the number of
564 * descriptors and the size of descriptors won't overflow an
565 * unsigned 32-bit integer.
567 if (usb_hdr
->ndesc
> USB_MAXDESC
)
570 if (!usb_hdr
->data_flag
&&
571 is_isochronous_transfer_completion(usb_hdr
) &&
572 packet_length_might_be_wrong(hdr
, usb_hdr
)) {
576 * Make sure we have all of the descriptors,
577 * as we will have to look at all of them.
579 * If not, we don't bother trying to fix
582 if (hdr
->caplen
< iso_pseudo_header_len(usb_hdr
))
586 * Calculate what the length should have been.
588 len
= incoming_isochronous_transfer_completed_len(hdr
,
592 * len is the smaller of UINT_MAX and the total
593 * header plus data length. That's guaranteed
594 * to fit in a UINT_MAX.
596 * Don't reduce the original length to a value
597 * below the captured length, however, as that
600 if (len
>= hdr
->caplen
)
604 * If the captured length is greater than the
605 * length, use the captured length.
607 * For completion events for incoming isochronous
608 * transfers, it's based on data_len, which is
609 * calculated the same way we calculated
610 * pre_truncation_data_len above, except that
611 * it has access to all the isochronous descriptors,
612 * not just the ones that the kernel were able to
613 * provide us or, for a capture file, that weren't
614 * sliced off by a snapshot length.
616 * However, it might have been reduced by the USB
617 * capture mechanism arbitrarily limiting the amount
618 * of data it provides to userland, or by the libpcap
619 * capture code limiting it to being no more than the
620 * snapshot, so we don't want to just use it all the
621 * time; we only do so to try to get a better estimate
622 * of the actual length - and to make sure the
623 * original length is always >= the captured length.
625 if (hdr
->caplen
> hdr
->len
)
626 hdr
->len
= hdr
->caplen
;