]> The Tcpdump Group git mirrors - libpcap/blob - pcap-util.c
CI: Call print_so_deps() on rpcapd in remote enabled build
[libpcap] / pcap-util.c
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 <stddef.h>
27
28 #include <pcap-types.h>
29
30 #include "pcap/can_socketcan.h"
31 #include "pcap/sll.h"
32 #include "pcap/usb.h"
33 #include "pcap/nflog.h"
34
35 #include "pcap-int.h"
36 #include "extract.h"
37 #include "pcap-usb-linux-common.h"
38
39 #include "pcap-util.h"
40 #include "pflog.h"
41
42 /*
43 * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
44 * that are saved in host byte order.
45 *
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
48 * order.
49 */
50 static void
51 swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
52 {
53 u_int caplen = hdr->caplen;
54 u_int length = hdr->len;
55 u_int pfloghdr_length;
56 struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
57
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 */
61 return;
62 }
63
64 pfloghdr_length = pflhdr->length;
65
66 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
67 /* Header doesn't include uid field */
68 return;
69 }
70 pflhdr->uid = SWAPLONG(pflhdr->uid);
71
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 */
75 return;
76 }
77 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
78 /* Header doesn't include pid field */
79 return;
80 }
81 pflhdr->pid = SWAPLONG(pflhdr->pid);
82
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 */
86 return;
87 }
88 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
89 /* Header doesn't include rule_uid field */
90 return;
91 }
92 pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
93
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 */
97 return;
98 }
99 if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
100 /* Header doesn't include rule_pid field */
101 return;
102 }
103 pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
104 }
105
106 /*
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.
114 *
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.
120 */
121 static void
122 swap_socketcan_header(uint16_t protocol, u_int caplen, u_int length,
123 u_char *buf)
124 {
125 pcap_can_socketcan_hdr *hdrp;
126 pcap_can_socketcan_xl_hdr *xl_hdrp;
127
128 switch (protocol) {
129
130 case LINUX_SLL_P_CAN:
131 case LINUX_SLL_P_CANFD:
132 /*
133 * CAN classic/CAN FD packet; fix up the packet's header
134 * by byte-swapping the CAN ID field.
135 */
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 */
140 return;
141 }
142 hdrp->can_id = SWAPLONG(hdrp->can_id);
143 break;
144
145 case LINUX_SLL_P_CANXL:
146 /*
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.
150 */
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 */
155 return;
156 }
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 */
161 return;
162 }
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 */
167 return;
168 }
169 xl_hdrp->acceptance_field = SWAPLONG(xl_hdrp->acceptance_field);
170 break;
171
172 default:
173 /*
174 * Not a CAN packet; nothing to do.
175 */
176 break;
177 }
178 }
179
180 /*
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.
184 *
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.
188 */
189 static void
190 swap_linux_sll_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
191 {
192 u_int caplen = hdr->caplen;
193 u_int length = hdr->len;
194 struct sll_header *shdr = (struct sll_header *)buf;
195
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 */
199 return;
200 }
201
202 /*
203 * Byte-swap what needs to be byte-swapped.
204 */
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));
209 }
210
211 /*
212 * The same applies for DLT_LINUX_SLL2.
213 */
214 static void
215 swap_linux_sll2_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
216 {
217 u_int caplen = hdr->caplen;
218 u_int length = hdr->len;
219 struct sll2_header *shdr = (struct sll2_header *)buf;
220
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 */
224 return;
225 }
226
227 /*
228 * Byte-swap what needs to be byte-swapped.
229 */
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));
234 }
235
236 /*
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).
240 *
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.
244 */
245 static void
246 swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
247 int header_len_64_bytes)
248 {
249 pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
250 bpf_u_int32 offset = 0;
251
252 /*
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.
256 */
257
258 /*
259 * The URB id is a totally opaque value; do we really need to
260 * convert it to the reading host's byte order???
261 */
262 offset += 8; /* skip past id */
263 if (hdr->caplen < offset)
264 return;
265 uhdr->id = SWAPLL(uhdr->id);
266
267 offset += 4; /* skip past various 1-byte fields */
268
269 offset += 2; /* skip past bus_id */
270 if (hdr->caplen < offset)
271 return;
272 uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
273
274 offset += 2; /* skip past various 1-byte fields */
275
276 offset += 8; /* skip past ts_sec */
277 if (hdr->caplen < offset)
278 return;
279 uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
280
281 offset += 4; /* skip past ts_usec */
282 if (hdr->caplen < offset)
283 return;
284 uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
285
286 offset += 4; /* skip past status */
287 if (hdr->caplen < offset)
288 return;
289 uhdr->status = SWAPLONG(uhdr->status);
290
291 offset += 4; /* skip past urb_len */
292 if (hdr->caplen < offset)
293 return;
294 uhdr->urb_len = SWAPLONG(uhdr->urb_len);
295
296 offset += 4; /* skip past data_len */
297 if (hdr->caplen < offset)
298 return;
299 uhdr->data_len = SWAPLONG(uhdr->data_len);
300
301 if (uhdr->transfer_type == URB_ISOCHRONOUS) {
302 offset += 4; /* skip past s.iso.error_count */
303 if (hdr->caplen < offset)
304 return;
305 uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
306
307 offset += 4; /* skip past s.iso.numdesc */
308 if (hdr->caplen < offset)
309 return;
310 uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
311 } else
312 offset += 8; /* skip USB setup header */
313
314 /*
315 * With the old header, there are no isochronous descriptors
316 * after the header.
317 *
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.
324 */
325 if (header_len_64_bytes) {
326 /*
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.
333 */
334 offset += 4; /* skip past interval */
335 if (hdr->caplen < offset)
336 return;
337 uhdr->interval = SWAPLONG(uhdr->interval);
338
339 offset += 4; /* skip past start_frame */
340 if (hdr->caplen < offset)
341 return;
342 uhdr->start_frame = SWAPLONG(uhdr->start_frame);
343
344 offset += 4; /* skip past xfer_flags */
345 if (hdr->caplen < offset)
346 return;
347 uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
348
349 offset += 4; /* skip past ndesc */
350 if (hdr->caplen < offset)
351 return;
352 uhdr->ndesc = SWAPLONG(uhdr->ndesc);
353
354 if (uhdr->transfer_type == URB_ISOCHRONOUS) {
355 /* swap the values in struct linux_usb_isodesc */
356 usb_isodesc *pisodesc;
357 uint32_t i;
358
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)
363 return;
364 pisodesc->status = SWAPLONG(pisodesc->status);
365
366 offset += 4; /* skip past offset */
367 if (hdr->caplen < offset)
368 return;
369 pisodesc->offset = SWAPLONG(pisodesc->offset);
370
371 offset += 4; /* skip past len */
372 if (hdr->caplen < offset)
373 return;
374 pisodesc->len = SWAPLONG(pisodesc->len);
375
376 offset += 4; /* skip past padding */
377
378 pisodesc++;
379 }
380 }
381 }
382 }
383
384 /*
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.
390 *
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.
394 */
395 static void
396 swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
397 {
398 u_char *p = buf;
399 nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
400 nflog_tlv_t *tlv;
401 u_int caplen = hdr->caplen;
402 u_int length = hdr->len;
403 u_int size;
404
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. */
408 return;
409 }
410
411 if (nfhdr->nflog_version != 0) {
412 /* Unknown NFLOG version */
413 return;
414 }
415
416 length -= sizeof(nflog_hdr_t);
417 caplen -= sizeof(nflog_hdr_t);
418 p += sizeof(nflog_hdr_t);
419
420 while (caplen >= sizeof(nflog_tlv_t)) {
421 tlv = (nflog_tlv_t *) p;
422
423 /* Swap the type and length. */
424 tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
425 tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
426
427 /* Get the length of the TLV. */
428 size = tlv->tlv_length;
429 if (size % 4 != 0)
430 size += 4 - size % 4;
431
432 /* Is the TLV's length less than the minimum? */
433 if (size < sizeof(nflog_tlv_t)) {
434 /* Yes. Give up now. */
435 return;
436 }
437
438 /* Do we have enough data for the full TLV? */
439 if (caplen < size || length < size) {
440 /* No. */
441 return;
442 }
443
444 /* Skip over the TLV. */
445 length -= size;
446 caplen -= size;
447 p += size;
448 }
449 }
450
451 static void
452 swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
453 {
454 /*
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.
458 */
459 switch (linktype) {
460
461 case DLT_PFLOG:
462 swap_pflog_header(hdr, data);
463 break;
464
465 case DLT_LINUX_SLL:
466 swap_linux_sll_socketcan_header(hdr, data);
467 break;
468
469 case DLT_LINUX_SLL2:
470 swap_linux_sll2_socketcan_header(hdr, data);
471 break;
472
473 case DLT_USB_LINUX:
474 swap_linux_usb_header(hdr, data, 0);
475 break;
476
477 case DLT_USB_LINUX_MMAPPED:
478 swap_linux_usb_header(hdr, data, 1);
479 break;
480
481 case DLT_NFLOG:
482 swap_nflog_header(hdr, data);
483 break;
484 }
485 }
486
487 static inline int
488 packet_length_might_be_wrong(struct pcap_pkthdr *hdr,
489 const pcap_usb_header_mmapped *usb_hdr)
490 {
491 uint32_t old_style_packet_length;
492
493 /*
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.
499 */
500 old_style_packet_length = iso_pseudo_header_len(usb_hdr) +
501 usb_hdr->urb_len;
502 return (hdr->len == old_style_packet_length);
503 }
504
505 void
506 pcapint_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr,
507 u_char *data)
508 {
509 if (swapped)
510 swap_pseudo_headers(linktype, hdr, data);
511
512 /*
513 * Is this a memory-mapped Linux USB capture?
514 */
515 if (linktype == DLT_USB_LINUX_MMAPPED) {
516 /*
517 * Yes.
518 *
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,
524 * but it wasn't.
525 *
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.
531 *
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.
535 */
536 if (hdr->caplen < sizeof (pcap_usb_header_mmapped)) {
537 /*
538 * We don't have the full pseudo-header.
539 */
540 return;
541 }
542
543 const pcap_usb_header_mmapped *usb_hdr =
544 (const pcap_usb_header_mmapped *) data;
545
546 /*
547 * Make sure the number of descriptors is sane.
548 *
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
553 * in the kernel.
554 *
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
557 * or pcapng header.
558 *
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.
562 *
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.
566 */
567 if (usb_hdr->ndesc > USB_MAXDESC)
568 return;
569
570 if (!usb_hdr->data_flag &&
571 is_isochronous_transfer_completion(usb_hdr) &&
572 packet_length_might_be_wrong(hdr, usb_hdr)) {
573 u_int len;
574
575 /*
576 * Make sure we have all of the descriptors,
577 * as we will have to look at all of them.
578 *
579 * If not, we don't bother trying to fix
580 * anything.
581 */
582 if (hdr->caplen < iso_pseudo_header_len(usb_hdr))
583 return;
584
585 /*
586 * Calculate what the length should have been.
587 */
588 len = incoming_isochronous_transfer_completed_len(hdr,
589 data);
590
591 /*
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.
595 *
596 * Don't reduce the original length to a value
597 * below the captured length, however, as that
598 * is bogus.
599 */
600 if (len >= hdr->caplen)
601 hdr->len = len;
602
603 /*
604 * If the captured length is greater than the
605 * length, use the captured length.
606 *
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.
615 *
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.
624 */
625 if (hdr->caplen > hdr->len)
626 hdr->len = hdr->caplen;
627 }
628 }
629 }