use crate::blocks::PcapBlockOwned;
use crate::error::PcapError;
use crate::read_u32_e;
use rusticata_macros::align32;
pub trait PcapNGBlock {
fn big_endian(&self) -> bool;
fn raw_data(&self) -> &[u8];
#[inline]
fn block_type(&self) -> u32 {
read_u32_e!(&self.raw_data(), self.big_endian())
}
#[inline]
fn block_length(&self) -> u32 {
read_u32_e!(&self.raw_data()[4..8], self.big_endian())
}
#[inline]
fn block_length2(&self) -> u32 {
let data = self.raw_data();
let data_len = data.len();
read_u32_e!(&data[data_len - 4..], self.big_endian())
}
fn data_len(&self) -> usize;
fn data(&self) -> &[u8];
fn header_len(&self) -> usize;
#[inline]
fn raw_header(&self) -> &[u8] {
let len = self.header_len();
&self.raw_data()[..len]
}
#[inline]
fn offset_options(&self) -> usize {
let len = self.data_len();
self.header_len() + align32!(len)
}
#[inline]
fn raw_options(&self) -> &[u8] {
let offset = self.offset_options();
let data_len = self.data_len();
if offset + 4 >= data_len {
return &[];
}
&self.raw_data()[offset..data_len - 4]
}
}
pub trait PcapNGPacketBlock {
fn big_endian(&self) -> bool;
fn truncated(&self) -> bool {
false
}
fn orig_len(&self) -> u32;
fn raw_packet_data(&self) -> &[u8];
fn packet_data(&self) -> &[u8];
}
pub trait PcapReaderIterator {
fn next(&mut self) -> Result<(usize, PcapBlockOwned), PcapError<&[u8]>>;
fn consume(&mut self, offset: usize);
fn consume_noshift(&mut self, offset: usize);
fn consumed(&self) -> usize;
fn refill(&mut self) -> Result<(), PcapError<&[u8]>>;
fn position(&self) -> usize;
fn grow(&mut self, new_size: usize) -> bool;
fn data(&self) -> &[u8];
fn reader_exhausted(&self) -> bool;
}
#[cfg(test)]
pub mod tests {
use crate::pcap::parse_pcap_frame;
use crate::pcapng::{parse_block_le, Block, SecretsType};
use crate::traits::PcapNGPacketBlock;
use crate::utils::Data;
use hex_literal::hex;
pub const FRAME_PCAP: &[u8] = &hex!(
"
34 4E 5B 5A E1 96 08 00 4A 00 00 00 4A 00 00 00
72 4D 4A D1 13 0D 4E 9C AE DE CB 73 08 00 45 00
00 3C DF 08 40 00 40 06 47 9F 0A 09 00 01 0A 09
00 02 D1 F4 11 51 34 1B 5B 17 00 00 00 00 A0 02
72 10 14 43 00 00 02 04 05 B4 04 02 08 0A E4 DB
6B 7B 00 00 00 00 01 03 03 07"
);
pub const FRAME_PCAPNG_EPB: &[u8] = &hex!(
"
06 00 00 00 74 00 00 00 01 00 00 00 E9 D3 04 00
48 EE 39 44 54 00 00 00 54 00 00 00 08 00 27 4A
BE 45 08 00 27 BB 22 84 08 00 45 00 00 46 00 00
40 00 40 11 48 89 C0 A8 38 67 C0 A8 38 66 81 AE
04 AA 00 32 53 B4 38 81 38 14 62 1D 67 46 2D DE
86 73 4D 2C BF F1 51 B2 B1 23 1B 61 E4 23 08 A2
72 81 8E 00 00 00 01 50 FF 26 2C 00 00 00 00 00
74 00 00 00"
);
pub const FRAME_PCAPNG_EPB_WITH_OPTIONS: &[u8] = &hex!(
"
06 00 00 00 F4 01 00 00 00 00 00 00 97 C3 04 00
AA 47 CA 64 3A 01 00 00 3A 01 00 00 FF FF FF FF
FF FF 00 0B 82 01 FC 42 08 00 45 00 01 2C A8 36
00 00 FA 11 17 8B 00 00 00 00 FF FF FF FF 00 44
00 43 01 18 59 1F 01 01 06 00 00 00 3D 1D 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 0B 82 01 FC 42 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 63 82 53 63 35 01 01 3D 07 01 00 0B 82 01
FC 42 32 04 00 00 00 00 37 04 01 03 06 2A FF 00
00 00 00 00 00 00 00 00 01 00 09 00 74 65 73 74
30 30 39 2D 31 00 00 00 02 00 04 00 00 00 00 00
04 00 08 00 00 00 00 00 00 00 00 00 AC 0B 0D 00
61 20 66 61 6B 65 20 73 74 72 69 6E 67 00 00 00
AD 0B 0F 00 73 6F 6D 65 20 66 61 6B 65 20 62 79
74 65 73 00 AC 4B 0E 00 6D 79 20 66 61 6B 65 20
73 74 72 69 6E 67 00 00 AD 4B 0D 00 6D 79 20 66
61 6B 65 20 62 79 74 65 73 00 00 00 23 01 0C 00
74 72 79 20 74 68 69 73 20 6F 6E 65 23 81 0C 00
61 6E 64 20 74 68 69 73 20 6F 6E 65 00 00 00 00
F4 01 00 00"
);
pub const FRAME_PCAPNG_DSB: &[u8] = &hex!(
"
0a 00 00 00 c4 00 00 00 4b 53 4c 54 b0 00 00 00
43 4c 49 45 4e 54 5f 52 41 4e 44 4f 4d 20 35 38
38 65 35 66 39 64 63 37 37 38 63 65 66 32 32 34
30 35 66 34 32 66 39 62 65 61 32 35 39 32 38 62
64 30 33 31 32 63 65 31 34 64 36 34 32 64 30 33
34 64 32 34 66 34 66 61 62 36 37 32 66 63 20 37
30 35 37 66 33 64 37 30 36 63 66 30 36 38 30 61
34 30 65 34 66 32 65 30 37 34 37 63 65 37 38 63
65 39 38 64 61 32 36 32 32 65 62 39 61 39 35 34
33 66 37 66 31 35 34 36 33 37 34 34 31 35 37 32
35 36 61 37 39 36 64 62 35 30 62 62 65 36 35 63
64 62 64 63 32 39 32 61 30 39 33 33 35 62 34 0a
c4 00 00 00"
);
pub const FRAME_PCAPNG_SHB: &[u8] = &hex!(
"
0a 0d 0d 0a c4 00 00 00 4d 3c 2b 1a 01 00 00 00
ff ff ff ff ff ff ff ff 02 00 37 00 49 6e 74 65
6c 28 52 29 20 43 6f 72 65 28 54 4d 29 20 69 37
2d 36 37 30 30 48 51 20 43 50 55 20 40 20 32 2e
36 30 47 48 7a 20 28 77 69 74 68 20 53 53 45 34
2e 32 29 00 03 00 2a 00 4c 69 6e 75 78 20 34 2e
32 30 2e 31 32 2d 67 65 6e 74 6f 6f 2d 61 6e 64
72 6f 6d 65 64 61 2d 32 30 31 39 30 33 30 35 2d
76 31 00 00 04 00 33 00 44 75 6d 70 63 61 70 20
28 57 69 72 65 73 68 61 72 6b 29 20 33 2e 31 2e
30 20 28 76 33 2e 31 2e 30 72 63 30 2d 34 36 38
2d 67 65 33 65 34 32 32 32 62 29 00 00 00 00 00
c4 00 00 00"
);
#[test]
fn test_data() {
let d = Data::Borrowed(&[0, 1, 2, 3]);
assert_eq!(d.as_ref()[1], 1);
assert_eq!(d[1], 1);
assert_eq!(&d[1..=2], &[1, 2]);
}
#[test]
fn test_pcap_packet_functions() {
let (_, pkt) = parse_pcap_frame(FRAME_PCAP).expect("packet creation failed");
assert_eq!(pkt.origlen, 74);
assert_eq!(pkt.ts_usec, 562_913);
assert_eq!(pkt.ts_sec, 1_515_933_236);
}
#[test]
fn test_pcapng_packet_functions() {
let (rem, pkt) = parse_block_le(FRAME_PCAPNG_EPB).expect("packet creation failed");
assert!(rem.is_empty());
if let Block::EnhancedPacket(epb) = pkt {
assert_eq!(epb.if_id, 1);
assert_eq!(epb.origlen, 84);
assert_eq!(epb.data.len(), 84);
assert!(epb.options.is_empty());
}
}
#[test]
fn test_pcapng_packet_epb_with_options() {
let (rem, pkt) =
parse_block_le(FRAME_PCAPNG_EPB_WITH_OPTIONS).expect("packet creation failed");
assert!(rem.is_empty());
if let Block::EnhancedPacket(epb) = pkt {
assert_eq!(epb.if_id, 0);
assert_eq!(epb.origlen, 314);
assert_eq!(epb.data.len(), 316); assert_eq!(epb.packet_data().len(), 314); }
}
#[test]
fn test_parse_enhancepacketblock() {
let (rem, pkt) =
parse_block_le(FRAME_PCAPNG_EPB_WITH_OPTIONS).expect("packet parsing failed");
assert!(rem.is_empty());
if let Block::EnhancedPacket(epb) = pkt {
assert_eq!(epb.if_id, 0);
assert_eq!(epb.origlen, 314);
assert_eq!(epb.data.len(), 316); assert_eq!(epb.packet_data().len(), 314); println!("options: {:?}", epb.options);
} else {
panic!("wrong packet type");
}
}
#[test]
fn test_pcapng_decryptionsecretsblock() {
let (rem, block) = parse_block_le(FRAME_PCAPNG_DSB).expect("could not parse DSB");
assert!(rem.is_empty());
if let Block::DecryptionSecrets(dsb) = block {
assert_eq!(dsb.secrets_type, SecretsType::TlsKeyLog);
assert!(std::str::from_utf8(dsb.data).is_ok());
} else {
unreachable!();
}
}
}