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
use prelude::*;
pub struct TlsParser;
impl Parsable<PathIp> for TlsParser {
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) => if let Some(_) = any.downcast_ref::<TcpPacket>() {
Some(())
} else {
None
},
_ => None,
},
None => Some(()),
}) >>
content_type: map_opt!(be_u8, TlsRecordContentType::from_u8) >>
version: take!(2) >>
length: be_u16 >>
(Box::new(TlsPacket {
content_type: content_type,
version: TlsRecordVersion {
major: version[0],
minor: version[1],
},
length: length,
}))
)
}
}
impl fmt::Display for TlsParser {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TLS")
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct TlsPacket {
pub content_type: TlsRecordContentType,
pub version: TlsRecordVersion,
pub length: u16,
}
#[derive(Debug, Eq, PartialEq)]
pub enum TlsRecordContentType {
ChangeCipherSpec,
Alert,
Handshake,
ApplicationData,
Heartbeat,
}
impl TlsRecordContentType {
pub fn from_u8(input: u8) -> Option<TlsRecordContentType> {
match input {
20 => Some(TlsRecordContentType::ChangeCipherSpec),
21 => Some(TlsRecordContentType::Alert),
22 => Some(TlsRecordContentType::Handshake),
23 => Some(TlsRecordContentType::ApplicationData),
24 => Some(TlsRecordContentType::Heartbeat),
_ => None,
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct TlsRecordVersion {
pub major: u8,
pub minor: u8,
}