netlink_packet_utils/
parsers.rs1use std::{
4 mem::size_of,
5 net::{IpAddr, Ipv4Addr, Ipv6Addr},
6};
7
8use anyhow::Context;
9use byteorder::{BigEndian, ByteOrder, NativeEndian};
10
11use crate::DecodeError;
12
13pub fn parse_mac(payload: &[u8]) -> Result<[u8; 6], DecodeError> {
14 if payload.len() != 6 {
15 return Err(format!("invalid MAC address: {payload:?}").into());
16 }
17 let mut address: [u8; 6] = [0; 6];
18 for (i, byte) in payload.iter().enumerate() {
19 address[i] = *byte;
20 }
21 Ok(address)
22}
23
24pub fn parse_ipv6(payload: &[u8]) -> Result<[u8; 16], DecodeError> {
25 if payload.len() != 16 {
26 return Err(format!("invalid IPv6 address: {payload:?}").into());
27 }
28 let mut address: [u8; 16] = [0; 16];
29 for (i, byte) in payload.iter().enumerate() {
30 address[i] = *byte;
31 }
32 Ok(address)
33}
34
35pub fn parse_ip(payload: &[u8]) -> Result<IpAddr, DecodeError> {
36 match payload.len() {
37 4 => Ok(
38 Ipv4Addr::new(payload[0], payload[1], payload[2], payload[3])
39 .into(),
40 ),
41 16 => Ok(Ipv6Addr::from([
42 payload[0],
43 payload[1],
44 payload[2],
45 payload[3],
46 payload[4],
47 payload[5],
48 payload[6],
49 payload[7],
50 payload[8],
51 payload[9],
52 payload[10],
53 payload[11],
54 payload[12],
55 payload[13],
56 payload[14],
57 payload[15],
58 ])
59 .into()),
60 _ => Err(format!("invalid IPv6 address: {payload:?}").into()),
61 }
62}
63
64pub fn parse_string(payload: &[u8]) -> Result<String, DecodeError> {
65 if payload.is_empty() {
66 return Ok(String::new());
67 }
68 let slice = if payload[payload.len() - 1] == 0 {
70 &payload[..payload.len() - 1]
71 } else {
72 &payload[..payload.len()]
73 };
74 let s = String::from_utf8(slice.to_vec()).context("invalid string")?;
75 Ok(s)
76}
77
78pub fn parse_u8(payload: &[u8]) -> Result<u8, DecodeError> {
79 if payload.len() != 1 {
80 return Err(format!("invalid u8: {payload:?}").into());
81 }
82 Ok(payload[0])
83}
84
85pub fn parse_u32(payload: &[u8]) -> Result<u32, DecodeError> {
86 if payload.len() != size_of::<u32>() {
87 return Err(format!("invalid u32: {payload:?}").into());
88 }
89 Ok(NativeEndian::read_u32(payload))
90}
91
92pub fn parse_u64(payload: &[u8]) -> Result<u64, DecodeError> {
93 if payload.len() != size_of::<u64>() {
94 return Err(format!("invalid u64: {payload:?}").into());
95 }
96 Ok(NativeEndian::read_u64(payload))
97}
98
99pub fn parse_u128(payload: &[u8]) -> Result<u128, DecodeError> {
100 if payload.len() != size_of::<u128>() {
101 return Err(format!("invalid u128: {payload:?}").into());
102 }
103 Ok(NativeEndian::read_u128(payload))
104}
105
106pub fn parse_u16(payload: &[u8]) -> Result<u16, DecodeError> {
107 if payload.len() != size_of::<u16>() {
108 return Err(format!("invalid u16: {payload:?}").into());
109 }
110 Ok(NativeEndian::read_u16(payload))
111}
112
113pub fn parse_i32(payload: &[u8]) -> Result<i32, DecodeError> {
114 if payload.len() != 4 {
115 return Err(format!("invalid u32: {payload:?}").into());
116 }
117 Ok(NativeEndian::read_i32(payload))
118}
119
120pub fn parse_u16_be(payload: &[u8]) -> Result<u16, DecodeError> {
121 if payload.len() != size_of::<u16>() {
122 return Err(format!("invalid u16: {payload:?}").into());
123 }
124 Ok(BigEndian::read_u16(payload))
125}
126
127pub fn parse_u32_be(payload: &[u8]) -> Result<u32, DecodeError> {
128 if payload.len() != size_of::<u32>() {
129 return Err(format!("invalid u32: {payload:?}").into());
130 }
131 Ok(BigEndian::read_u32(payload))
132}