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
swap_pflog_header(const struct pcap_pkthdr * hdr,u_char * buf)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
swap_socketcan_header(uint16_t protocol,u_int caplen,u_int length,u_char * buf)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
swap_linux_sll_socketcan_header(const struct pcap_pkthdr * hdr,u_char * buf)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
swap_linux_sll2_socketcan_header(const struct pcap_pkthdr * hdr,u_char * buf)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
swap_linux_usb_header(const struct pcap_pkthdr * hdr,u_char * buf,int header_len_64_bytes)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
swap_nflog_header(const struct pcap_pkthdr * hdr,u_char * buf)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
swap_pseudo_headers(int linktype,struct pcap_pkthdr * hdr,u_char * data)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
packet_length_might_be_wrong(struct pcap_pkthdr * hdr,const pcap_usb_header_mmapped * usb_hdr)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
pcapint_post_process(int linktype,int swapped,struct pcap_pkthdr * hdr,u_char * data)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