-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse_example.rs
118 lines (99 loc) · 3.07 KB
/
parse_example.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::marker::PhantomData;
use std::net::Ipv4Addr;
use jppe_derive::{BorrowByteDecode, BorrowByteEncode};
use jppe::prelude::MacAddress;
#[derive(Debug, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub struct Layer<'a> {
pub layer12: EthernetHeader<'a>,
#[jppe(branch="layer12.r#type")]
pub layer3: Layer3<'a>,
#[jppe(branch="layer3.get_protocol().unwrap_or_default()")]
pub layer4: Layer4<'a>,
pub remain: &'a [u8],
}
#[derive(Debug, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub enum Layer3<'a> {
#[jppe(branch_value=0x0800)]
Ipv4(Ipv4Header<'a>),
#[jppe(branch_default)]
Unknown,
}
impl<'a> Layer3<'a> {
pub fn get_protocol(&self) -> Option<u8> {
match self {
Self::Ipv4(v) => Some(v.protocol),
_ => None,
}
}
}
#[derive(Debug, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub enum Layer4<'a> {
#[jppe(branch_value=6)]
Tcp(TcpHeader<'a>),
#[jppe(branch_value=17)]
Udp(UdpHeader<'a>),
#[jppe(branch_default)]
Unknown,
}
#[derive(Debug, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub struct EthernetHeader<'a> {
pub smac: MacAddress,
pub dmac: MacAddress,
pub r#type: u16,
_mark: PhantomData<&'a ()>,
}
#[derive(Debug, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub struct Ipv4Header<'a> {
#[jppe(bits_start=0xf0, untake)]
pub version: u8,
#[jppe(bits=0x0f, value_decode="header_length << 2", value_encode="header_length >> 2")]
pub header_length: u8,
pub tos: u8,
pub total_length: u16,
pub identification: u16,
#[jppe(bits_start=0xe000, untake)]
pub flags: u16,
#[jppe(bits=0x1fff)]
pub fragment_offset: u16,
pub ttl: u8,
pub protocol: u8,
pub checksum: u16,
pub src: Ipv4Addr,
pub dst: Ipv4Addr,
#[jppe(length="header_length - 20")]
pub options: &'a [u8],
}
#[derive(Debug, Default, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub struct TcpHeader<'a> {
pub sport: u16,
pub dport: u16,
pub seq: u32,
pub ack: u32,
#[jppe(bits_start=0xf000, value_decode="header_length * 4", value_encode="header_length / 4", untake)]
pub header_length: u16,
#[jppe(bits=0x0fff)]
pub flags: u16,
pub window: u16,
pub checksum: u16,
pub urgent_pointer: u16,
#[jppe(length="header_length - 20")]
pub options: &'a [u8],
}
#[derive(Debug, Default, PartialEq, Eq, BorrowByteEncode, BorrowByteDecode)]
pub struct UdpHeader<'a> {
pub sport: u16,
pub dport: u16,
pub length: u16,
pub checksum: u16,
_mark: PhantomData<&'a ()>,
}
fn main() {
let input = b"\x00\xc0\x9f\x32\x41\x8c\x00\xe0\x18\xb1\x0c\xad\x08\x00\x45\x00\
\x00\x38\x00\x00\x40\x00\x40\x11\x65\x47\xc0\xa8\xaa\x08\xc0\xa8\
\xaa\x14\x80\x1b\x00\x35\x00\x24\x85\xed\x10\x32\x01\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\
\x6d\x00\x00\x10\x00\x01";
let (_, value) = jppe::decode_borrow::<Layer<'_>>(input).unwrap();
println!(">>> {value:?}");
assert_eq!(jppe::encode_borrow(value), input);
}