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
119
120
121
122
123
124
125
126
use prelude::*;
pub struct Ipv6Parser;
impl Parsable<PathIp> for Ipv6Parser {
fn parse<'a>(&mut self,
input: &'a [u8],
result: Option<&ParserResultVec>,
_: Option<&mut PathIp>)
-> IResult<&'a [u8], ParserResult> {
do_parse!(input,
expr_opt!(match result {
Some(vector) => match vector.last() {
Some(ref any) => match (any.downcast_ref::<EthernetPacket>(),
any.downcast_ref::<Ipv4Packet>(),
any.downcast_ref::<Ipv6Packet>()) {
(Some(eth), _, _) => if eth.ethertype == EtherType::Ipv6 {
Some(())
} else {
None
},
(_, Some(ipv4), _) => if ipv4.protocol == IpProtocol::Ipv6 {
Some(())
} else {
None
},
(_, _, Some(ipv6)) => if ipv6.next_header == IpProtocol::Ipv6 {
Some(())
} else {
None
},
_ => None,
},
_ => None,
},
None => Some(()),
}) >>
ver_tc_fl: bits!(tuple!(tag_bits!(u8, 4, 6),
take_bits!(u8, 8),
take_bits!(u32, 20))) >>
payload_length: be_u16 >>
next_header: map_opt!(be_u8, IpProtocol::from_u8) >>
hop_limit: be_u8 >>
src: tuple!(be_u16, be_u16, be_u16, be_u16, be_u16, be_u16, be_u16, be_u16) >>
dst: tuple!(be_u16, be_u16, be_u16, be_u16, be_u16, be_u16, be_u16, be_u16) >>
(Box::new(Ipv6Packet {
version: ver_tc_fl.0,
traffic_class: ver_tc_fl.1,
flow_label: ver_tc_fl.2,
payload_length: payload_length,
next_header: next_header,
hop_limit: hop_limit,
src: Ipv6Addr::new(src.0, src.1, src.2, src.3,
src.4, src.5, src.6, src.7),
dst: Ipv6Addr::new(dst.0, dst.1, dst.2, dst.3,
dst.4, dst.5, dst.6, dst.7),
}))
)
}
}
impl fmt::Display for Ipv6Parser {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "IPv6")
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Ipv6Packet {
pub version: u8,
pub traffic_class: u8,
pub flow_label: u32,
pub payload_length: u16,
pub next_header: IpProtocol,
pub hop_limit: u8,
pub src: Ipv6Addr,
pub dst: Ipv6Addr,
}