1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker * Copyright (c) 1993, 1994, 1995, 1996, 1997
3*8b26181fSAndroid Build Coastguard Worker * The Regents of the University of California. All rights reserved.
4*8b26181fSAndroid Build Coastguard Worker *
5*8b26181fSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*8b26181fSAndroid Build Coastguard Worker * modification, are permitted provided that: (1) source code distributions
7*8b26181fSAndroid Build Coastguard Worker * retain the above copyright notice and this paragraph in its entirety, (2)
8*8b26181fSAndroid Build Coastguard Worker * distributions including binary code include the above copyright notice and
9*8b26181fSAndroid Build Coastguard Worker * this paragraph in its entirety in the documentation or other materials
10*8b26181fSAndroid Build Coastguard Worker * provided with the distribution, and (3) all advertising materials mentioning
11*8b26181fSAndroid Build Coastguard Worker * features or use of this software display the following acknowledgement:
12*8b26181fSAndroid Build Coastguard Worker * ``This product includes software developed by the University of California,
13*8b26181fSAndroid Build Coastguard Worker * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*8b26181fSAndroid Build Coastguard Worker * the University nor the names of its contributors may be used to endorse
15*8b26181fSAndroid Build Coastguard Worker * or promote products derived from this software without specific prior
16*8b26181fSAndroid Build Coastguard Worker * written permission.
17*8b26181fSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*8b26181fSAndroid Build Coastguard Worker * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*8b26181fSAndroid Build Coastguard Worker * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*8b26181fSAndroid Build Coastguard Worker *
21*8b26181fSAndroid Build Coastguard Worker * pcap-common.c - common code for pcap and pcapng files
22*8b26181fSAndroid Build Coastguard Worker */
23*8b26181fSAndroid Build Coastguard Worker
24*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
25*8b26181fSAndroid Build Coastguard Worker #include <config.h>
26*8b26181fSAndroid Build Coastguard Worker #endif
27*8b26181fSAndroid Build Coastguard Worker
28*8b26181fSAndroid Build Coastguard Worker #include <pcap-types.h>
29*8b26181fSAndroid Build Coastguard Worker
30*8b26181fSAndroid Build Coastguard Worker #include "pcap-int.h"
31*8b26181fSAndroid Build Coastguard Worker #include "extract.h"
32*8b26181fSAndroid Build Coastguard Worker #include "pcap-usb-linux-common.h"
33*8b26181fSAndroid Build Coastguard Worker
34*8b26181fSAndroid Build Coastguard Worker #include "pcap-util.h"
35*8b26181fSAndroid Build Coastguard Worker
36*8b26181fSAndroid Build Coastguard Worker #include "pflog.h"
37*8b26181fSAndroid Build Coastguard Worker #include "pcap/can_socketcan.h"
38*8b26181fSAndroid Build Coastguard Worker #include "pcap/sll.h"
39*8b26181fSAndroid Build Coastguard Worker #include "pcap/usb.h"
40*8b26181fSAndroid Build Coastguard Worker #include "pcap/nflog.h"
41*8b26181fSAndroid Build Coastguard Worker
42*8b26181fSAndroid Build Coastguard Worker /*
43*8b26181fSAndroid Build Coastguard Worker * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
44*8b26181fSAndroid Build Coastguard Worker * that are saved in host byte order.
45*8b26181fSAndroid Build Coastguard Worker *
46*8b26181fSAndroid Build Coastguard Worker * When reading a DLT_PFLOG packet, we need to convert those fields from
47*8b26181fSAndroid Build Coastguard Worker * the byte order of the host that wrote the file to this host's byte
48*8b26181fSAndroid Build Coastguard Worker * order.
49*8b26181fSAndroid Build Coastguard Worker */
50*8b26181fSAndroid Build Coastguard Worker static void
swap_pflog_header(const struct pcap_pkthdr * hdr,u_char * buf)51*8b26181fSAndroid Build Coastguard Worker swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
52*8b26181fSAndroid Build Coastguard Worker {
53*8b26181fSAndroid Build Coastguard Worker u_int caplen = hdr->caplen;
54*8b26181fSAndroid Build Coastguard Worker u_int length = hdr->len;
55*8b26181fSAndroid Build Coastguard Worker u_int pfloghdr_length;
56*8b26181fSAndroid Build Coastguard Worker struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
57*8b26181fSAndroid Build Coastguard Worker
58*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) ||
59*8b26181fSAndroid Build Coastguard Worker length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
60*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the uid field */
61*8b26181fSAndroid Build Coastguard Worker return;
62*8b26181fSAndroid Build Coastguard Worker }
63*8b26181fSAndroid Build Coastguard Worker
64*8b26181fSAndroid Build Coastguard Worker pfloghdr_length = pflhdr->length;
65*8b26181fSAndroid Build Coastguard Worker
66*8b26181fSAndroid Build Coastguard Worker if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
67*8b26181fSAndroid Build Coastguard Worker /* Header doesn't include uid field */
68*8b26181fSAndroid Build Coastguard Worker return;
69*8b26181fSAndroid Build Coastguard Worker }
70*8b26181fSAndroid Build Coastguard Worker pflhdr->uid = SWAPLONG(pflhdr->uid);
71*8b26181fSAndroid Build Coastguard Worker
72*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) ||
73*8b26181fSAndroid Build Coastguard Worker length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
74*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the pid field */
75*8b26181fSAndroid Build Coastguard Worker return;
76*8b26181fSAndroid Build Coastguard Worker }
77*8b26181fSAndroid Build Coastguard Worker if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
78*8b26181fSAndroid Build Coastguard Worker /* Header doesn't include pid field */
79*8b26181fSAndroid Build Coastguard Worker return;
80*8b26181fSAndroid Build Coastguard Worker }
81*8b26181fSAndroid Build Coastguard Worker pflhdr->pid = SWAPLONG(pflhdr->pid);
82*8b26181fSAndroid Build Coastguard Worker
83*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) ||
84*8b26181fSAndroid Build Coastguard Worker length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
85*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the rule_uid field */
86*8b26181fSAndroid Build Coastguard Worker return;
87*8b26181fSAndroid Build Coastguard Worker }
88*8b26181fSAndroid Build Coastguard Worker if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
89*8b26181fSAndroid Build Coastguard Worker /* Header doesn't include rule_uid field */
90*8b26181fSAndroid Build Coastguard Worker return;
91*8b26181fSAndroid Build Coastguard Worker }
92*8b26181fSAndroid Build Coastguard Worker pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
93*8b26181fSAndroid Build Coastguard Worker
94*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) ||
95*8b26181fSAndroid Build Coastguard Worker length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
96*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the rule_pid field */
97*8b26181fSAndroid Build Coastguard Worker return;
98*8b26181fSAndroid Build Coastguard Worker }
99*8b26181fSAndroid Build Coastguard Worker if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
100*8b26181fSAndroid Build Coastguard Worker /* Header doesn't include rule_pid field */
101*8b26181fSAndroid Build Coastguard Worker return;
102*8b26181fSAndroid Build Coastguard Worker }
103*8b26181fSAndroid Build Coastguard Worker pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
104*8b26181fSAndroid Build Coastguard Worker }
105*8b26181fSAndroid Build Coastguard Worker
106*8b26181fSAndroid Build Coastguard Worker /*
107*8b26181fSAndroid Build Coastguard Worker * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
108*8b26181fSAndroid Build Coastguard Worker * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
109*8b26181fSAndroid Build Coastguard Worker * with the CAN ID being in host byte order.
110*8b26181fSAndroid Build Coastguard Worker *
111*8b26181fSAndroid Build Coastguard Worker * When reading a DLT_LINUX_SLL packet, we need to check for those
112*8b26181fSAndroid Build Coastguard Worker * packets and convert the CAN ID from the byte order of the host that
113*8b26181fSAndroid Build Coastguard Worker * wrote the file to this host's byte order.
114*8b26181fSAndroid Build Coastguard Worker */
115*8b26181fSAndroid Build Coastguard Worker static void
swap_linux_sll_header(const struct pcap_pkthdr * hdr,u_char * buf)116*8b26181fSAndroid Build Coastguard Worker swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
117*8b26181fSAndroid Build Coastguard Worker {
118*8b26181fSAndroid Build Coastguard Worker u_int caplen = hdr->caplen;
119*8b26181fSAndroid Build Coastguard Worker u_int length = hdr->len;
120*8b26181fSAndroid Build Coastguard Worker struct sll_header *shdr = (struct sll_header *)buf;
121*8b26181fSAndroid Build Coastguard Worker uint16_t protocol;
122*8b26181fSAndroid Build Coastguard Worker pcap_can_socketcan_hdr *chdr;
123*8b26181fSAndroid Build Coastguard Worker
124*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) sizeof(struct sll_header) ||
125*8b26181fSAndroid Build Coastguard Worker length < (u_int) sizeof(struct sll_header)) {
126*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the protocol field */
127*8b26181fSAndroid Build Coastguard Worker return;
128*8b26181fSAndroid Build Coastguard Worker }
129*8b26181fSAndroid Build Coastguard Worker
130*8b26181fSAndroid Build Coastguard Worker protocol = EXTRACT_BE_U_2(&shdr->sll_protocol);
131*8b26181fSAndroid Build Coastguard Worker if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
132*8b26181fSAndroid Build Coastguard Worker return;
133*8b26181fSAndroid Build Coastguard Worker
134*8b26181fSAndroid Build Coastguard Worker /*
135*8b26181fSAndroid Build Coastguard Worker * SocketCAN packet; fix up the packet's header.
136*8b26181fSAndroid Build Coastguard Worker */
137*8b26181fSAndroid Build Coastguard Worker chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
138*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
139*8b26181fSAndroid Build Coastguard Worker length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
140*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the CAN ID */
141*8b26181fSAndroid Build Coastguard Worker return;
142*8b26181fSAndroid Build Coastguard Worker }
143*8b26181fSAndroid Build Coastguard Worker chdr->can_id = SWAPLONG(chdr->can_id);
144*8b26181fSAndroid Build Coastguard Worker }
145*8b26181fSAndroid Build Coastguard Worker
146*8b26181fSAndroid Build Coastguard Worker /*
147*8b26181fSAndroid Build Coastguard Worker * The same applies for DLT_LINUX_SLL2.
148*8b26181fSAndroid Build Coastguard Worker */
149*8b26181fSAndroid Build Coastguard Worker static void
swap_linux_sll2_header(const struct pcap_pkthdr * hdr,u_char * buf)150*8b26181fSAndroid Build Coastguard Worker swap_linux_sll2_header(const struct pcap_pkthdr *hdr, u_char *buf)
151*8b26181fSAndroid Build Coastguard Worker {
152*8b26181fSAndroid Build Coastguard Worker u_int caplen = hdr->caplen;
153*8b26181fSAndroid Build Coastguard Worker u_int length = hdr->len;
154*8b26181fSAndroid Build Coastguard Worker struct sll2_header *shdr = (struct sll2_header *)buf;
155*8b26181fSAndroid Build Coastguard Worker uint16_t protocol;
156*8b26181fSAndroid Build Coastguard Worker pcap_can_socketcan_hdr *chdr;
157*8b26181fSAndroid Build Coastguard Worker
158*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) sizeof(struct sll2_header) ||
159*8b26181fSAndroid Build Coastguard Worker length < (u_int) sizeof(struct sll2_header)) {
160*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the protocol field */
161*8b26181fSAndroid Build Coastguard Worker return;
162*8b26181fSAndroid Build Coastguard Worker }
163*8b26181fSAndroid Build Coastguard Worker
164*8b26181fSAndroid Build Coastguard Worker protocol = EXTRACT_BE_U_2(&shdr->sll2_protocol);
165*8b26181fSAndroid Build Coastguard Worker if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
166*8b26181fSAndroid Build Coastguard Worker return;
167*8b26181fSAndroid Build Coastguard Worker
168*8b26181fSAndroid Build Coastguard Worker /*
169*8b26181fSAndroid Build Coastguard Worker * SocketCAN packet; fix up the packet's header.
170*8b26181fSAndroid Build Coastguard Worker */
171*8b26181fSAndroid Build Coastguard Worker chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll2_header));
172*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id) ||
173*8b26181fSAndroid Build Coastguard Worker length < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id)) {
174*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have the CAN ID */
175*8b26181fSAndroid Build Coastguard Worker return;
176*8b26181fSAndroid Build Coastguard Worker }
177*8b26181fSAndroid Build Coastguard Worker chdr->can_id = SWAPLONG(chdr->can_id);
178*8b26181fSAndroid Build Coastguard Worker }
179*8b26181fSAndroid Build Coastguard Worker
180*8b26181fSAndroid Build Coastguard Worker /*
181*8b26181fSAndroid Build Coastguard Worker * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
182*8b26181fSAndroid Build Coastguard Worker * byte order when capturing (it's supplied directly from a
183*8b26181fSAndroid Build Coastguard Worker * memory-mapped buffer shared by the kernel).
184*8b26181fSAndroid Build Coastguard Worker *
185*8b26181fSAndroid Build Coastguard Worker * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
186*8b26181fSAndroid Build Coastguard Worker * need to convert it from the byte order of the host that wrote the
187*8b26181fSAndroid Build Coastguard Worker * file to this host's byte order.
188*8b26181fSAndroid Build Coastguard Worker */
189*8b26181fSAndroid Build Coastguard Worker static void
swap_linux_usb_header(const struct pcap_pkthdr * hdr,u_char * buf,int header_len_64_bytes)190*8b26181fSAndroid Build Coastguard Worker swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
191*8b26181fSAndroid Build Coastguard Worker int header_len_64_bytes)
192*8b26181fSAndroid Build Coastguard Worker {
193*8b26181fSAndroid Build Coastguard Worker pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
194*8b26181fSAndroid Build Coastguard Worker bpf_u_int32 offset = 0;
195*8b26181fSAndroid Build Coastguard Worker
196*8b26181fSAndroid Build Coastguard Worker /*
197*8b26181fSAndroid Build Coastguard Worker * "offset" is the offset *past* the field we're swapping;
198*8b26181fSAndroid Build Coastguard Worker * we skip the field *before* checking to make sure
199*8b26181fSAndroid Build Coastguard Worker * the captured data length includes the entire field.
200*8b26181fSAndroid Build Coastguard Worker */
201*8b26181fSAndroid Build Coastguard Worker
202*8b26181fSAndroid Build Coastguard Worker /*
203*8b26181fSAndroid Build Coastguard Worker * The URB id is a totally opaque value; do we really need to
204*8b26181fSAndroid Build Coastguard Worker * convert it to the reading host's byte order???
205*8b26181fSAndroid Build Coastguard Worker */
206*8b26181fSAndroid Build Coastguard Worker offset += 8; /* skip past id */
207*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
208*8b26181fSAndroid Build Coastguard Worker return;
209*8b26181fSAndroid Build Coastguard Worker uhdr->id = SWAPLL(uhdr->id);
210*8b26181fSAndroid Build Coastguard Worker
211*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past various 1-byte fields */
212*8b26181fSAndroid Build Coastguard Worker
213*8b26181fSAndroid Build Coastguard Worker offset += 2; /* skip past bus_id */
214*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
215*8b26181fSAndroid Build Coastguard Worker return;
216*8b26181fSAndroid Build Coastguard Worker uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
217*8b26181fSAndroid Build Coastguard Worker
218*8b26181fSAndroid Build Coastguard Worker offset += 2; /* skip past various 1-byte fields */
219*8b26181fSAndroid Build Coastguard Worker
220*8b26181fSAndroid Build Coastguard Worker offset += 8; /* skip past ts_sec */
221*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
222*8b26181fSAndroid Build Coastguard Worker return;
223*8b26181fSAndroid Build Coastguard Worker uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
224*8b26181fSAndroid Build Coastguard Worker
225*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past ts_usec */
226*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
227*8b26181fSAndroid Build Coastguard Worker return;
228*8b26181fSAndroid Build Coastguard Worker uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
229*8b26181fSAndroid Build Coastguard Worker
230*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past status */
231*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
232*8b26181fSAndroid Build Coastguard Worker return;
233*8b26181fSAndroid Build Coastguard Worker uhdr->status = SWAPLONG(uhdr->status);
234*8b26181fSAndroid Build Coastguard Worker
235*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past urb_len */
236*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
237*8b26181fSAndroid Build Coastguard Worker return;
238*8b26181fSAndroid Build Coastguard Worker uhdr->urb_len = SWAPLONG(uhdr->urb_len);
239*8b26181fSAndroid Build Coastguard Worker
240*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past data_len */
241*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
242*8b26181fSAndroid Build Coastguard Worker return;
243*8b26181fSAndroid Build Coastguard Worker uhdr->data_len = SWAPLONG(uhdr->data_len);
244*8b26181fSAndroid Build Coastguard Worker
245*8b26181fSAndroid Build Coastguard Worker if (uhdr->transfer_type == URB_ISOCHRONOUS) {
246*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past s.iso.error_count */
247*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
248*8b26181fSAndroid Build Coastguard Worker return;
249*8b26181fSAndroid Build Coastguard Worker uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
250*8b26181fSAndroid Build Coastguard Worker
251*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past s.iso.numdesc */
252*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
253*8b26181fSAndroid Build Coastguard Worker return;
254*8b26181fSAndroid Build Coastguard Worker uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
255*8b26181fSAndroid Build Coastguard Worker } else
256*8b26181fSAndroid Build Coastguard Worker offset += 8; /* skip USB setup header */
257*8b26181fSAndroid Build Coastguard Worker
258*8b26181fSAndroid Build Coastguard Worker /*
259*8b26181fSAndroid Build Coastguard Worker * With the old header, there are no isochronous descriptors
260*8b26181fSAndroid Build Coastguard Worker * after the header.
261*8b26181fSAndroid Build Coastguard Worker *
262*8b26181fSAndroid Build Coastguard Worker * With the new header, the actual number of descriptors in
263*8b26181fSAndroid Build Coastguard Worker * the header is not s.iso.numdesc, it's ndesc - only the
264*8b26181fSAndroid Build Coastguard Worker * first N descriptors, for some value of N, are put into
265*8b26181fSAndroid Build Coastguard Worker * the header, and ndesc is set to the actual number copied.
266*8b26181fSAndroid Build Coastguard Worker * In addition, if s.iso.numdesc is negative, no descriptors
267*8b26181fSAndroid Build Coastguard Worker * are captured, and ndesc is set to 0.
268*8b26181fSAndroid Build Coastguard Worker */
269*8b26181fSAndroid Build Coastguard Worker if (header_len_64_bytes) {
270*8b26181fSAndroid Build Coastguard Worker /*
271*8b26181fSAndroid Build Coastguard Worker * This is either the "version 1" header, with
272*8b26181fSAndroid Build Coastguard Worker * 16 bytes of additional fields at the end, or
273*8b26181fSAndroid Build Coastguard Worker * a "version 0" header from a memory-mapped
274*8b26181fSAndroid Build Coastguard Worker * capture, with 16 bytes of zeroed-out padding
275*8b26181fSAndroid Build Coastguard Worker * at the end. Byte swap them as if this were
276*8b26181fSAndroid Build Coastguard Worker * a "version 1" header.
277*8b26181fSAndroid Build Coastguard Worker */
278*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past interval */
279*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
280*8b26181fSAndroid Build Coastguard Worker return;
281*8b26181fSAndroid Build Coastguard Worker uhdr->interval = SWAPLONG(uhdr->interval);
282*8b26181fSAndroid Build Coastguard Worker
283*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past start_frame */
284*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
285*8b26181fSAndroid Build Coastguard Worker return;
286*8b26181fSAndroid Build Coastguard Worker uhdr->start_frame = SWAPLONG(uhdr->start_frame);
287*8b26181fSAndroid Build Coastguard Worker
288*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past xfer_flags */
289*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
290*8b26181fSAndroid Build Coastguard Worker return;
291*8b26181fSAndroid Build Coastguard Worker uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
292*8b26181fSAndroid Build Coastguard Worker
293*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past ndesc */
294*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
295*8b26181fSAndroid Build Coastguard Worker return;
296*8b26181fSAndroid Build Coastguard Worker uhdr->ndesc = SWAPLONG(uhdr->ndesc);
297*8b26181fSAndroid Build Coastguard Worker
298*8b26181fSAndroid Build Coastguard Worker if (uhdr->transfer_type == URB_ISOCHRONOUS) {
299*8b26181fSAndroid Build Coastguard Worker /* swap the values in struct linux_usb_isodesc */
300*8b26181fSAndroid Build Coastguard Worker usb_isodesc *pisodesc;
301*8b26181fSAndroid Build Coastguard Worker uint32_t i;
302*8b26181fSAndroid Build Coastguard Worker
303*8b26181fSAndroid Build Coastguard Worker pisodesc = (usb_isodesc *)(void *)(buf+offset);
304*8b26181fSAndroid Build Coastguard Worker for (i = 0; i < uhdr->ndesc; i++) {
305*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past status */
306*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
307*8b26181fSAndroid Build Coastguard Worker return;
308*8b26181fSAndroid Build Coastguard Worker pisodesc->status = SWAPLONG(pisodesc->status);
309*8b26181fSAndroid Build Coastguard Worker
310*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past offset */
311*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
312*8b26181fSAndroid Build Coastguard Worker return;
313*8b26181fSAndroid Build Coastguard Worker pisodesc->offset = SWAPLONG(pisodesc->offset);
314*8b26181fSAndroid Build Coastguard Worker
315*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past len */
316*8b26181fSAndroid Build Coastguard Worker if (hdr->caplen < offset)
317*8b26181fSAndroid Build Coastguard Worker return;
318*8b26181fSAndroid Build Coastguard Worker pisodesc->len = SWAPLONG(pisodesc->len);
319*8b26181fSAndroid Build Coastguard Worker
320*8b26181fSAndroid Build Coastguard Worker offset += 4; /* skip past padding */
321*8b26181fSAndroid Build Coastguard Worker
322*8b26181fSAndroid Build Coastguard Worker pisodesc++;
323*8b26181fSAndroid Build Coastguard Worker }
324*8b26181fSAndroid Build Coastguard Worker }
325*8b26181fSAndroid Build Coastguard Worker }
326*8b26181fSAndroid Build Coastguard Worker }
327*8b26181fSAndroid Build Coastguard Worker
328*8b26181fSAndroid Build Coastguard Worker /*
329*8b26181fSAndroid Build Coastguard Worker * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
330*8b26181fSAndroid Build Coastguard Worker * data. They begin with a fixed-length header with big-endian fields,
331*8b26181fSAndroid Build Coastguard Worker * followed by a set of TLVs, where the type and length are in host
332*8b26181fSAndroid Build Coastguard Worker * byte order but the values are either big-endian or are a raw byte
333*8b26181fSAndroid Build Coastguard Worker * sequence that's the same regardless of the host's byte order.
334*8b26181fSAndroid Build Coastguard Worker *
335*8b26181fSAndroid Build Coastguard Worker * When reading a DLT_NFLOG packet, we need to convert the type and
336*8b26181fSAndroid Build Coastguard Worker * length values from the byte order of the host that wrote the file
337*8b26181fSAndroid Build Coastguard Worker * to the byte order of this host.
338*8b26181fSAndroid Build Coastguard Worker */
339*8b26181fSAndroid Build Coastguard Worker static void
swap_nflog_header(const struct pcap_pkthdr * hdr,u_char * buf)340*8b26181fSAndroid Build Coastguard Worker swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
341*8b26181fSAndroid Build Coastguard Worker {
342*8b26181fSAndroid Build Coastguard Worker u_char *p = buf;
343*8b26181fSAndroid Build Coastguard Worker nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
344*8b26181fSAndroid Build Coastguard Worker nflog_tlv_t *tlv;
345*8b26181fSAndroid Build Coastguard Worker u_int caplen = hdr->caplen;
346*8b26181fSAndroid Build Coastguard Worker u_int length = hdr->len;
347*8b26181fSAndroid Build Coastguard Worker uint16_t size;
348*8b26181fSAndroid Build Coastguard Worker
349*8b26181fSAndroid Build Coastguard Worker if (caplen < (u_int) sizeof(nflog_hdr_t) ||
350*8b26181fSAndroid Build Coastguard Worker length < (u_int) sizeof(nflog_hdr_t)) {
351*8b26181fSAndroid Build Coastguard Worker /* Not enough data to have any TLVs. */
352*8b26181fSAndroid Build Coastguard Worker return;
353*8b26181fSAndroid Build Coastguard Worker }
354*8b26181fSAndroid Build Coastguard Worker
355*8b26181fSAndroid Build Coastguard Worker if (nfhdr->nflog_version != 0) {
356*8b26181fSAndroid Build Coastguard Worker /* Unknown NFLOG version */
357*8b26181fSAndroid Build Coastguard Worker return;
358*8b26181fSAndroid Build Coastguard Worker }
359*8b26181fSAndroid Build Coastguard Worker
360*8b26181fSAndroid Build Coastguard Worker length -= sizeof(nflog_hdr_t);
361*8b26181fSAndroid Build Coastguard Worker caplen -= sizeof(nflog_hdr_t);
362*8b26181fSAndroid Build Coastguard Worker p += sizeof(nflog_hdr_t);
363*8b26181fSAndroid Build Coastguard Worker
364*8b26181fSAndroid Build Coastguard Worker while (caplen >= sizeof(nflog_tlv_t)) {
365*8b26181fSAndroid Build Coastguard Worker tlv = (nflog_tlv_t *) p;
366*8b26181fSAndroid Build Coastguard Worker
367*8b26181fSAndroid Build Coastguard Worker /* Swap the type and length. */
368*8b26181fSAndroid Build Coastguard Worker tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
369*8b26181fSAndroid Build Coastguard Worker tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
370*8b26181fSAndroid Build Coastguard Worker
371*8b26181fSAndroid Build Coastguard Worker /* Get the length of the TLV. */
372*8b26181fSAndroid Build Coastguard Worker size = tlv->tlv_length;
373*8b26181fSAndroid Build Coastguard Worker if (size % 4 != 0)
374*8b26181fSAndroid Build Coastguard Worker size += 4 - size % 4;
375*8b26181fSAndroid Build Coastguard Worker
376*8b26181fSAndroid Build Coastguard Worker /* Is the TLV's length less than the minimum? */
377*8b26181fSAndroid Build Coastguard Worker if (size < sizeof(nflog_tlv_t)) {
378*8b26181fSAndroid Build Coastguard Worker /* Yes. Give up now. */
379*8b26181fSAndroid Build Coastguard Worker return;
380*8b26181fSAndroid Build Coastguard Worker }
381*8b26181fSAndroid Build Coastguard Worker
382*8b26181fSAndroid Build Coastguard Worker /* Do we have enough data for the full TLV? */
383*8b26181fSAndroid Build Coastguard Worker if (caplen < size || length < size) {
384*8b26181fSAndroid Build Coastguard Worker /* No. */
385*8b26181fSAndroid Build Coastguard Worker return;
386*8b26181fSAndroid Build Coastguard Worker }
387*8b26181fSAndroid Build Coastguard Worker
388*8b26181fSAndroid Build Coastguard Worker /* Skip over the TLV. */
389*8b26181fSAndroid Build Coastguard Worker length -= size;
390*8b26181fSAndroid Build Coastguard Worker caplen -= size;
391*8b26181fSAndroid Build Coastguard Worker p += size;
392*8b26181fSAndroid Build Coastguard Worker }
393*8b26181fSAndroid Build Coastguard Worker }
394*8b26181fSAndroid Build Coastguard Worker
395*8b26181fSAndroid Build Coastguard Worker static void
swap_pseudo_headers(int linktype,struct pcap_pkthdr * hdr,u_char * data)396*8b26181fSAndroid Build Coastguard Worker swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
397*8b26181fSAndroid Build Coastguard Worker {
398*8b26181fSAndroid Build Coastguard Worker /*
399*8b26181fSAndroid Build Coastguard Worker * Convert pseudo-headers from the byte order of
400*8b26181fSAndroid Build Coastguard Worker * the host on which the file was saved to our
401*8b26181fSAndroid Build Coastguard Worker * byte order, as necessary.
402*8b26181fSAndroid Build Coastguard Worker */
403*8b26181fSAndroid Build Coastguard Worker switch (linktype) {
404*8b26181fSAndroid Build Coastguard Worker
405*8b26181fSAndroid Build Coastguard Worker case DLT_PFLOG:
406*8b26181fSAndroid Build Coastguard Worker swap_pflog_header(hdr, data);
407*8b26181fSAndroid Build Coastguard Worker break;
408*8b26181fSAndroid Build Coastguard Worker
409*8b26181fSAndroid Build Coastguard Worker case DLT_LINUX_SLL:
410*8b26181fSAndroid Build Coastguard Worker swap_linux_sll_header(hdr, data);
411*8b26181fSAndroid Build Coastguard Worker break;
412*8b26181fSAndroid Build Coastguard Worker
413*8b26181fSAndroid Build Coastguard Worker case DLT_LINUX_SLL2:
414*8b26181fSAndroid Build Coastguard Worker swap_linux_sll2_header(hdr, data);
415*8b26181fSAndroid Build Coastguard Worker break;
416*8b26181fSAndroid Build Coastguard Worker
417*8b26181fSAndroid Build Coastguard Worker case DLT_USB_LINUX:
418*8b26181fSAndroid Build Coastguard Worker swap_linux_usb_header(hdr, data, 0);
419*8b26181fSAndroid Build Coastguard Worker break;
420*8b26181fSAndroid Build Coastguard Worker
421*8b26181fSAndroid Build Coastguard Worker case DLT_USB_LINUX_MMAPPED:
422*8b26181fSAndroid Build Coastguard Worker swap_linux_usb_header(hdr, data, 1);
423*8b26181fSAndroid Build Coastguard Worker break;
424*8b26181fSAndroid Build Coastguard Worker
425*8b26181fSAndroid Build Coastguard Worker case DLT_NFLOG:
426*8b26181fSAndroid Build Coastguard Worker swap_nflog_header(hdr, data);
427*8b26181fSAndroid Build Coastguard Worker break;
428*8b26181fSAndroid Build Coastguard Worker }
429*8b26181fSAndroid Build Coastguard Worker }
430*8b26181fSAndroid Build Coastguard Worker
431*8b26181fSAndroid Build Coastguard Worker void
pcap_post_process(int linktype,int swapped,struct pcap_pkthdr * hdr,u_char * data)432*8b26181fSAndroid Build Coastguard Worker pcap_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr,
433*8b26181fSAndroid Build Coastguard Worker u_char *data)
434*8b26181fSAndroid Build Coastguard Worker {
435*8b26181fSAndroid Build Coastguard Worker if (swapped)
436*8b26181fSAndroid Build Coastguard Worker swap_pseudo_headers(linktype, hdr, data);
437*8b26181fSAndroid Build Coastguard Worker
438*8b26181fSAndroid Build Coastguard Worker fixup_pcap_pkthdr(linktype, hdr, data);
439*8b26181fSAndroid Build Coastguard Worker }
440*8b26181fSAndroid Build Coastguard Worker
441*8b26181fSAndroid Build Coastguard Worker void
fixup_pcap_pkthdr(int linktype,struct pcap_pkthdr * hdr,const u_char * data)442*8b26181fSAndroid Build Coastguard Worker fixup_pcap_pkthdr(int linktype, struct pcap_pkthdr *hdr, const u_char *data)
443*8b26181fSAndroid Build Coastguard Worker {
444*8b26181fSAndroid Build Coastguard Worker const pcap_usb_header_mmapped *usb_hdr;
445*8b26181fSAndroid Build Coastguard Worker
446*8b26181fSAndroid Build Coastguard Worker usb_hdr = (const pcap_usb_header_mmapped *) data;
447*8b26181fSAndroid Build Coastguard Worker if (linktype == DLT_USB_LINUX_MMAPPED &&
448*8b26181fSAndroid Build Coastguard Worker hdr->caplen >= sizeof (pcap_usb_header_mmapped)) {
449*8b26181fSAndroid Build Coastguard Worker /*
450*8b26181fSAndroid Build Coastguard Worker * In older versions of libpcap, in memory-mapped captures,
451*8b26181fSAndroid Build Coastguard Worker * the "on-the-bus length" for completion events for
452*8b26181fSAndroid Build Coastguard Worker * incoming isochronous transfers was miscalculated; it
453*8b26181fSAndroid Build Coastguard Worker * needed to be calculated based on the* offsets and lengths
454*8b26181fSAndroid Build Coastguard Worker * in the descriptors, not on the raw URB length, but it
455*8b26181fSAndroid Build Coastguard Worker * wasn't.
456*8b26181fSAndroid Build Coastguard Worker *
457*8b26181fSAndroid Build Coastguard Worker * If this packet contains transferred data (yes, data_flag
458*8b26181fSAndroid Build Coastguard Worker * is 0 if we *do* have data), and the total on-the-network
459*8b26181fSAndroid Build Coastguard Worker * length is equal to the value calculated from the raw URB
460*8b26181fSAndroid Build Coastguard Worker * length, then it might be one of those transfers.
461*8b26181fSAndroid Build Coastguard Worker *
462*8b26181fSAndroid Build Coastguard Worker * We only do this if we have the full USB pseudo-header.
463*8b26181fSAndroid Build Coastguard Worker */
464*8b26181fSAndroid Build Coastguard Worker if (!usb_hdr->data_flag &&
465*8b26181fSAndroid Build Coastguard Worker hdr->len == sizeof(pcap_usb_header_mmapped) +
466*8b26181fSAndroid Build Coastguard Worker (usb_hdr->ndesc * sizeof (usb_isodesc)) + usb_hdr->urb_len) {
467*8b26181fSAndroid Build Coastguard Worker /*
468*8b26181fSAndroid Build Coastguard Worker * It might need fixing; fix it if it's a completion
469*8b26181fSAndroid Build Coastguard Worker * event for an incoming isochronous transfer.
470*8b26181fSAndroid Build Coastguard Worker */
471*8b26181fSAndroid Build Coastguard Worker fix_linux_usb_mmapped_length(hdr, data);
472*8b26181fSAndroid Build Coastguard Worker }
473*8b26181fSAndroid Build Coastguard Worker }
474*8b26181fSAndroid Build Coastguard Worker }
475