1#![cfg_attr(feature = "core", feature(no_std))]
2
3#[cfg(feature = "core")]
9extern crate collections;
10
11#[cfg(not(feature = "core"))]
12pub mod iter;
13
14use nom::{
15 call, do_parse, i32, map, named_args, named_attr,
16 number::{streaming::be_u32, Endianness},
17 switch, take, u16, u32, verify,
18};
19
20#[allow(non_camel_case_types)]
22#[derive(Debug, PartialEq, Copy, Clone)]
23pub enum LinkType {
24 NULL,
25 ETHERNET,
26 AX25,
27 IEEE802_5,
28 ARCNET_BSD,
29 SLIP,
30 PPP,
31 FDDI,
32 PPP_HDLC,
33 PPP_ETHER,
34 ATM_RFC1483,
35 RAW,
36 C_HDLC,
37 IEEE802_11,
38 FRELAY,
39 LOOP,
40 LINUX_SLL,
41 LTALK,
42 PFLOG,
43 IEEE802_11_PRISM,
44 IP_OVER_FC,
45 SUNATM,
46 IEEE802_11_RADIOTAP,
47 ARCNET_LINUX,
48 APPLE_IP_OVER_IEEE1394,
49 MTP2_WITH_PHDR,
50 MTP2,
51 MTP3,
52 SCCP,
53 DOCSIS,
54 LINUX_IRDA,
55 USER0,
56 USER1,
57 USER2,
58 USER3,
59 USER4,
60 USER5,
61 USER6,
62 USER7,
63 USER8,
64 USER9,
65 USER10,
66 USER11,
67 USER12,
68 USER13,
69 USER14,
70 USER15,
71 IEEE802_11_AVS,
72 BACNET_MS_TP,
73 PPP_PPPD,
74 GPRS_LLC,
75 GPF_T,
76 GPF_F,
77 LINUX_LAPD,
78 BLUETOOTH_HCI_H4,
79 USB_LINUX,
80 PPI,
81 IEEE802_15_4,
82 SITA,
83 ERF,
84 BLUETOOTH_HCI_H4_WITH_PHDR,
85 AX25_KISS,
86 LAPD,
87 PPP_WITH_DIR,
88 C_HDLC_WITH_DIR,
89 FRELAY_WITH_DIR,
90 IPMB_LINUX,
91 IEEE802_15_4_NONASK_PHY,
92 USB_LINUX_MMAPPED,
93 FC_2,
94 FC_2_WITH_FRAME_DELIMS,
95 IPNET,
96 CAN_SOCKETCAN,
97 IPV4,
98 IPV6,
99 IEEE802_15_4_NOFCS,
100 DBUS,
101 DVB_CI,
102 MUX27010,
103 STANAG_5066_D_PDU,
104 NFLOG,
105 NETANALYZER,
106 NETANALYZER_TRANSPARENT,
107 IPOIB,
108 MPEG_2_TS,
109 NG40,
110 NFC_LLCP,
111 INFINIBAND,
112 SCTP,
113 USBPCAP,
114 RTAC_SERIAL,
115 BLUETOOTH_LE_LL,
116 NETLINK,
117 BLUETOOTH_LINUX_MONITOR,
118 BLUETOOTH_BREDR_BB,
119 BLUETOOTH_LE_LL_WITH_PHDR,
120 PROFIBUS_DL,
121 PKTAP,
122 EPON,
123 IPMI_HPM_2,
124 ZWAVE_R1_R2,
125 ZWAVE_R3,
126 WATTSTOPPER_DLM,
127 ISO_14443,
128 RDS,
129 USB_DARWIN,
130 SDLC,
131 UNKNOWN,
132}
133
134impl From<u32> for LinkType {
135 fn from(n: u32) -> LinkType {
136 match n {
137 0 => LinkType::NULL,
138 1 => LinkType::ETHERNET,
139 3 => LinkType::AX25,
140 6 => LinkType::IEEE802_5,
141 7 => LinkType::ARCNET_BSD,
142 8 => LinkType::SLIP,
143 9 => LinkType::PPP,
144 10 => LinkType::FDDI,
145 50 => LinkType::PPP_HDLC,
146 51 => LinkType::PPP_ETHER,
147 100 => LinkType::ATM_RFC1483,
148 101 => LinkType::RAW,
149 104 => LinkType::C_HDLC,
150 105 => LinkType::IEEE802_11,
151 107 => LinkType::FRELAY,
152 108 => LinkType::LOOP,
153 113 => LinkType::LINUX_SLL,
154 114 => LinkType::LTALK,
155 117 => LinkType::PFLOG,
156 119 => LinkType::IEEE802_11_PRISM,
157 122 => LinkType::IP_OVER_FC,
158 123 => LinkType::SUNATM,
159 127 => LinkType::IEEE802_11_RADIOTAP,
160 129 => LinkType::ARCNET_LINUX,
161 138 => LinkType::APPLE_IP_OVER_IEEE1394,
162 139 => LinkType::MTP2_WITH_PHDR,
163 140 => LinkType::MTP2,
164 141 => LinkType::MTP3,
165 142 => LinkType::SCCP,
166 143 => LinkType::DOCSIS,
167 144 => LinkType::LINUX_IRDA,
168 147 => LinkType::USER0,
169 148 => LinkType::USER1,
170 149 => LinkType::USER2,
171 150 => LinkType::USER3,
172 151 => LinkType::USER4,
173 152 => LinkType::USER5,
174 153 => LinkType::USER6,
175 154 => LinkType::USER7,
176 155 => LinkType::USER8,
177 156 => LinkType::USER9,
178 157 => LinkType::USER10,
179 158 => LinkType::USER11,
180 159 => LinkType::USER12,
181 160 => LinkType::USER13,
182 161 => LinkType::USER14,
183 162 => LinkType::USER15,
184 163 => LinkType::IEEE802_11_AVS,
185 165 => LinkType::BACNET_MS_TP,
186 166 => LinkType::PPP_PPPD,
187 169 => LinkType::GPRS_LLC,
188 170 => LinkType::GPF_T,
189 171 => LinkType::GPF_F,
190 177 => LinkType::LINUX_LAPD,
191 187 => LinkType::BLUETOOTH_HCI_H4,
192 189 => LinkType::USB_LINUX,
193 192 => LinkType::PPI,
194 195 => LinkType::IEEE802_15_4,
195 196 => LinkType::SITA,
196 197 => LinkType::ERF,
197 201 => LinkType::BLUETOOTH_HCI_H4_WITH_PHDR,
198 202 => LinkType::AX25_KISS,
199 203 => LinkType::LAPD,
200 204 => LinkType::PPP_WITH_DIR,
201 205 => LinkType::C_HDLC_WITH_DIR,
202 206 => LinkType::FRELAY_WITH_DIR,
203 209 => LinkType::IPMB_LINUX,
204 215 => LinkType::IEEE802_15_4_NONASK_PHY,
205 220 => LinkType::USB_LINUX_MMAPPED,
206 224 => LinkType::FC_2,
207 225 => LinkType::FC_2_WITH_FRAME_DELIMS,
208 226 => LinkType::IPNET,
209 227 => LinkType::CAN_SOCKETCAN,
210 228 => LinkType::IPV4,
211 229 => LinkType::IPV6,
212 230 => LinkType::IEEE802_15_4_NOFCS,
213 231 => LinkType::DBUS,
214 235 => LinkType::DVB_CI,
215 236 => LinkType::MUX27010,
216 237 => LinkType::STANAG_5066_D_PDU,
217 239 => LinkType::NFLOG,
218 240 => LinkType::NETANALYZER,
219 241 => LinkType::NETANALYZER_TRANSPARENT,
220 242 => LinkType::IPOIB,
221 243 => LinkType::MPEG_2_TS,
222 244 => LinkType::NG40,
223 245 => LinkType::NFC_LLCP,
224 247 => LinkType::INFINIBAND,
225 248 => LinkType::SCTP,
226 249 => LinkType::USBPCAP,
227 250 => LinkType::RTAC_SERIAL,
228 251 => LinkType::BLUETOOTH_LE_LL,
229 253 => LinkType::NETLINK,
230 254 => LinkType::BLUETOOTH_LINUX_MONITOR,
231 255 => LinkType::BLUETOOTH_BREDR_BB,
232 256 => LinkType::BLUETOOTH_LE_LL_WITH_PHDR,
233 257 => LinkType::PROFIBUS_DL,
234 258 => LinkType::PKTAP,
235 259 => LinkType::EPON,
236 260 => LinkType::IPMI_HPM_2,
237 261 => LinkType::ZWAVE_R1_R2,
238 262 => LinkType::ZWAVE_R3,
239 263 => LinkType::WATTSTOPPER_DLM,
240 264 => LinkType::ISO_14443,
241 265 => LinkType::RDS,
242 266 => LinkType::USB_DARWIN,
243 268 => LinkType::SDLC,
244 _ => LinkType::UNKNOWN,
245 }
246 }
247}
248
249#[derive(PartialEq, Debug)]
253pub struct Header {
254 pub major: u16,
256 pub minor: u16,
258 pub this_zone: i32,
265 pub sigfigs: u32,
267 pub snaplen: u32,
270 pub network: LinkType,
271 pub nano_sec: bool,
272 pub endianness: Endianness,
273}
274
275#[derive(PartialEq, Debug)]
277pub struct Record {
278 pub ts_sec: u32,
279 pub ts_nanosec: u32,
280 pub orig_len: u32,
281 pub data: Vec<u8>,
282}
283
284named_args!(parse_header_e(e: Endianness, nsec: bool)<Header>,
285 do_parse!(
286 major: u16!(e) >>
287 minor: u16!(e) >>
288 this_zone: i32!(e) >>
289 sigfigs: u32!(e) >>
290 snaplen: u32!(e) >>
291 network: verify!(
292 map!(u32!(e), LinkType::from),
293 |val:&LinkType| { *val != LinkType::UNKNOWN }
294 ) >>
295 (Header {
296 major: major,
297 minor: minor,
298 this_zone: this_zone,
299 sigfigs: sigfigs,
300 snaplen: snaplen,
301 network: network,
302 nano_sec: nsec,
303 endianness: e
304 })
305 )
306);
307
308named_attr!(
309#[doc=""],
314pub parse_header<Header>, switch!(be_u32,
315 0xa1b2c3d4 => call!(parse_header_e, Endianness::Big, false) | 0xd4c3b2a1 => call!(parse_header_e, Endianness::Little, false) | 0xa1b23c4d => call!(parse_header_e, Endianness::Big, true) | 0x4d3cb2a1 => call!(parse_header_e, Endianness::Little, true) ));
320
321named_args!(pub parse_record(e: Endianness, nano_sec: bool)<Record>, do_parse!(
322 ts_sec: u32!(e) >>
323 ts_subsec: u32!(e) >>
324 incl_len: u32!(e) >>
325 orig_len: u32!(e) >>
326 data: take!(incl_len) >>
327
328 (Record {
329 ts_sec: ts_sec,
330 ts_nanosec: if nano_sec {ts_subsec} else {ts_subsec*1000},
331 orig_len: orig_len,
332 data: Vec::from(data)
333 })
334));
335
336#[cfg(test)]
337mod tests {
338 use super::*;
339
340 #[test]
341 fn parse_header_be_usec() {
342 let i = b"\xa1\xb2\xc3\xd4\x00\x02\x00\x04\xFF\xFF\xFF\xFF\
343 \x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x0a";
344 let h = Header {
345 major: 2,
346 minor: 4,
347 this_zone: -1,
348 sigfigs: 1,
349 snaplen: 1,
350 network: LinkType::ETHERNET,
351 nano_sec: false,
352 endianness: Endianness::Big,
353 };
354 assert_eq!(parse_header(&i[..]), Ok((&[10][..], h)));
355 }
356 #[test]
357 fn parse_header_le_usec() {
358 let i = b"\xd4\xc3\xb2\xa1\x02\x00\x04\x00\xFF\xFF\xFF\xFF\
359 \x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0a";
360 let h = Header {
361 major: 2,
362 minor: 4,
363 this_zone: -1,
364 sigfigs: 1,
365 snaplen: 1,
366 network: LinkType::ETHERNET,
367 nano_sec: false,
368 endianness: Endianness::Little,
369 };
370 assert_eq!(parse_header(&i[..]), Ok((&[10][..], h)));
371 }
372
373 #[test]
374 fn parse_header_be_nsec() {
375 let i = b"\xa1\xb2\x3c\x4d\x00\x02\x00\x04\xFF\xFF\xFF\xFF\
376 \x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x0a";
377 let h = Header {
378 major: 2,
379 minor: 4,
380 this_zone: -1,
381 sigfigs: 1,
382 snaplen: 1,
383 network: LinkType::ETHERNET,
384 nano_sec: true,
385 endianness: Endianness::Big,
386 };
387 assert_eq!(parse_header(&i[..]), Ok((&[10][..], h)));
388 }
389 #[test]
390 fn parse_header_le_nsec() {
391 let i = b"\x4d\x3c\xb2\xa1\x02\x00\x04\x00\xFF\xFF\xFF\xFF\
392 \x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0a";
393 let h = Header {
394 major: 2,
395 minor: 4,
396 this_zone: -1,
397 sigfigs: 1,
398 snaplen: 1,
399 network: LinkType::ETHERNET,
400 nano_sec: true,
401 endianness: Endianness::Little,
402 };
403 assert_eq!(parse_header(&i[..]), Ok((&[10][..], h)));
404 }
405
406 #[test]
407 fn parse_record_be_empty() {
408 let i = b"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\
409 \x00\x00\x00\x00\x0a";
410 let r = Record {
411 ts_sec: 1,
412 ts_nanosec: 0,
413 orig_len: 0,
414 data: Vec::new(),
415 };
416 assert_eq!(
417 parse_record(&i[..], Endianness::Big, false),
418 Ok((&[10][..], r))
419 );
420 }
421 #[test]
422 fn parse_record_be_some_orig_data_zero_incl() {
423 let i = b"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\
424 \x00\x00\x00\x03\x0a";
425 let r = Record {
426 ts_sec: 1,
427 ts_nanosec: 2,
428 orig_len: 3,
429 data: Vec::new(),
430 };
431 assert_eq!(
432 parse_record(&i[..], Endianness::Big, true),
433 Ok((&[10][..], r))
434 );
435 }
436 #[test]
437 fn parse_record_be_some_orig_data_parially_incl() {
438 let i = b"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x02\
439 \x00\x00\x00\x03\x0a\x0b\x80";
440 let r = Record {
441 ts_sec: 1,
442 ts_nanosec: 2,
443 orig_len: 3,
444 data: vec![10, 11],
445 };
446 assert_eq!(
447 parse_record(&i[..], Endianness::Big, true),
448 Ok((&[128][..], r))
449 );
450 }
451 #[test]
452 fn parse_record_be_all_data_incl() {
453 let i = b"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\
454 \x00\x00\x00\x03\x0a\x0b\x0c\x80";
455 let r = Record {
456 ts_sec: 1,
457 ts_nanosec: 2,
458 orig_len: 3,
459 data: vec![10, 11, 12],
460 };
461 assert_eq!(
462 parse_record(&i[..], Endianness::Big, true),
463 Ok((&[128][..], r))
464 );
465 }
466
467 #[test]
468 fn parse_record_le_empty() {
469 let i = b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
470 \x00\x00\x00\x00\x0a";
471 let r = Record {
472 ts_sec: 1,
473 ts_nanosec: 0,
474 orig_len: 0,
475 data: Vec::new(),
476 };
477 assert_eq!(
478 parse_record(&i[..], Endianness::Little, true),
479 Ok((&[10][..], r))
480 );
481 }
482 #[test]
483 fn parse_record_le_some_orig_data_zero_incl() {
484 let i = b"\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\
485 \x03\x00\x00\x00\x0a";
486 let r = Record {
487 ts_sec: 1,
488 ts_nanosec: 2,
489 orig_len: 3,
490 data: Vec::new(),
491 };
492 assert_eq!(
493 parse_record(&i[..], Endianness::Little, true),
494 Ok((&[10][..], r))
495 );
496 }
497 #[test]
498 fn parse_record_le_some_orig_data_parially_incl() {
499 let i = b"\x01\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\
500 \x03\x00\x00\x00\x0a\x0b\x80";
501 let r = Record {
502 ts_sec: 1,
503 ts_nanosec: 2,
504 orig_len: 3,
505 data: vec![10, 11],
506 };
507 assert_eq!(
508 parse_record(&i[..], Endianness::Little, true),
509 Ok((&[128][..], r))
510 );
511 }
512 #[test]
513 fn parse_record_le_all_data_incl() {
514 let i = b"\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\
515 \x03\x00\x00\x00\x0a\x0b\x0c\x80";
516 let r = Record {
517 ts_sec: 1,
518 ts_nanosec: 2,
519 orig_len: 3,
520 data: vec![10, 11, 12],
521 };
522 assert_eq!(
523 parse_record(&i[..], Endianness::Little, true),
524 Ok((&[128][..], r))
525 );
526 }
527 #[test]
528 fn parse_record_le_all_data_incl_usec() {
529 let i = b"\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\
530 \x03\x00\x00\x00\x0a\x0b\x0c\x80";
531 let r = Record {
532 ts_sec: 1,
533 ts_nanosec: 2000,
534 orig_len: 3,
535 data: vec![10, 11, 12],
536 };
537 assert_eq!(
538 parse_record(&i[..], Endianness::Little, false),
539 Ok((&[128][..], r))
540 );
541 }
542
543 #[test]
544 fn parse_all_link_type() {
545 for j in 0..270u32 {
546 let linktype = LinkType::from(j);
547 if let LinkType::UNKNOWN = linktype {
548 continue;
549 }
550
551 let mut i = b"\xa1\xb2\xc3\xd4\x00\x02\x00\x04\xFF\xFF\xFF\xFF\
552 \x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00"
553 .to_vec();
554 i[22] = (j >> 8) as u8;
555 i[23] = j as u8;
556
557 let h = Header {
558 major: 2,
559 minor: 4,
560 this_zone: -1,
561 sigfigs: 1,
562 snaplen: 1,
563 network: linktype,
564 nano_sec: false,
565 endianness: Endianness::Big,
566 };
567 assert_eq!(parse_header(&i[..]), Ok((&[][..], h)));
568 }
569 }
570}