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
use std::mem::size_of;
use byteorder::{ByteOrder, NativeEndian};
use failure::ResultExt;
use crate::DecodeError;
pub fn parse_mac(payload: &[u8]) -> Result<[u8; 6], DecodeError> {
if payload.len() != 6 {
return Err(format!("invalid MAC address: {:?}", payload).into());
}
let mut address: [u8; 6] = [0; 6];
for (i, byte) in payload.iter().enumerate() {
address[i] = *byte;
}
Ok(address)
}
pub fn parse_ipv6(payload: &[u8]) -> Result<[u8; 16], DecodeError> {
if payload.len() != 16 {
return Err(format!("invalid IPv6 address: {:?}", payload).into());
}
let mut address: [u8; 16] = [0; 16];
for (i, byte) in payload.iter().enumerate() {
address[i] = *byte;
}
Ok(address)
}
pub fn parse_string(payload: &[u8]) -> Result<String, DecodeError> {
if payload.is_empty() {
return Ok(String::new());
}
let slice = if payload[payload.len() - 1] == 0 {
&payload[..payload.len() - 1]
} else {
&payload[..payload.len()]
};
let s = String::from_utf8(slice.to_vec()).context("invalid string")?;
Ok(s)
}
pub fn parse_u8(payload: &[u8]) -> Result<u8, DecodeError> {
if payload.len() != 1 {
return Err(format!("invalid u8: {:?}", payload).into());
}
Ok(payload[0])
}
pub fn parse_u32(payload: &[u8]) -> Result<u32, DecodeError> {
if payload.len() != size_of::<u32>() {
return Err(format!("invalid u32: {:?}", payload).into());
}
Ok(NativeEndian::read_u32(payload))
}
pub fn parse_u64(payload: &[u8]) -> Result<u64, DecodeError> {
if payload.len() != size_of::<u64>() {
return Err(format!("invalid u64: {:?}", payload).into());
}
Ok(NativeEndian::read_u64(payload))
}
pub fn parse_u16(payload: &[u8]) -> Result<u16, DecodeError> {
if payload.len() != size_of::<u16>() {
return Err(format!("invalid u16: {:?}", payload).into());
}
Ok(NativeEndian::read_u16(payload))
}
pub fn parse_i32(payload: &[u8]) -> Result<i32, DecodeError> {
if payload.len() != 4 {
return Err(format!("invalid u32: {:?}", payload).into());
}
Ok(NativeEndian::read_i32(payload))
}