netlink_bindings/
primitives.rs1pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
2
3macro_rules! gen_parse {
4 ($name:ident => $from:ident, $type:ident) => {
5 pub fn $name(buf: &[u8]) -> Option<$type> {
6 if buf.len() != size_of::<$type>() {
7 return None;
8 }
9 Some($type::$from(buf.try_into().unwrap()))
10 }
11 };
12 ($($name:ident => $from:ident, $type:ident;)+) => {
13 $(gen_parse!($name => $from, $type);)+
14 }
15}
16
17gen_parse! {
18 parse_u8 => from_ne_bytes, u8;
19 parse_u16 => from_ne_bytes, u16;
20 parse_u32 => from_ne_bytes, u32;
21 parse_u64 => from_ne_bytes, u64;
22 parse_u128 => from_ne_bytes, u128;
23
24 parse_be_u8 => from_be_bytes, u8;
25 parse_be_u16 => from_be_bytes, u16;
26 parse_be_u32 => from_be_bytes, u32;
27 parse_be_u64 => from_be_bytes, u64;
28 parse_be_u128 => from_be_bytes, u128;
29
30 parse_le_u8 => from_le_bytes, u8;
31 parse_le_u16 => from_le_bytes, u16;
32 parse_le_u32 => from_le_bytes, u32;
33 parse_le_u64 => from_le_bytes, u64;
34 parse_le_u128 => from_le_bytes, u128;
35
36 parse_i8 => from_ne_bytes, i8;
37 parse_i16 => from_ne_bytes, i16;
38 parse_i32 => from_ne_bytes, i32;
39 parse_i64 => from_ne_bytes, i64;
40 parse_i128 => from_ne_bytes, i128;
41
42 parse_be_i8 => from_be_bytes, i8;
43 parse_be_i16 => from_be_bytes, i16;
44 parse_be_i32 => from_be_bytes, i32;
45 parse_be_i64 => from_be_bytes, i64;
46 parse_be_i128 => from_be_bytes, i128;
47
48 parse_le_i8 => from_le_bytes, i8;
49 parse_le_i16 => from_le_bytes, i16;
50 parse_le_i32 => from_le_bytes, i32;
51 parse_le_i64 => from_le_bytes, i64;
52 parse_le_i128 => from_le_bytes, i128;
53}
54
55pub fn parse_ipv4(buf: &[u8]) -> Option<Ipv4Addr> {
56 parse_be_u32(buf).map(Ipv4Addr::from_bits)
58}
59
60pub fn parse_ipv6(buf: &[u8]) -> Option<Ipv6Addr> {
61 parse_be_u128(buf).map(Ipv6Addr::from_bits)
63}
64
65pub fn parse_ip(buf: &[u8]) -> Option<IpAddr> {
66 match buf.len() {
67 4 => Some(IpAddr::V4(parse_ipv4(buf).unwrap())),
68 16 => Some(IpAddr::V6(parse_ipv6(buf).unwrap())),
69 _ => None,
70 }
71}
72
73pub fn parse_sockaddr_v4(buf: &[u8]) -> Option<SocketAddrV4> {
74 if buf.len() != 16 {
76 return None;
77 }
78 Some(SocketAddrV4::new(
79 Ipv4Addr::from_bits(parse_be_u32(&buf[4..8])?),
80 parse_be_u16(&buf[2..4])?,
81 ))
82}
83
84pub fn parse_sockaddr_v6(buf: &[u8]) -> Option<SocketAddrV6> {
85 if buf.len() != 28 {
87 return None;
88 }
89 Some(SocketAddrV6::new(
90 Ipv6Addr::from_bits(parse_be_u128(&buf[8..24])?),
91 parse_be_u16(&buf[2..4])?,
92 parse_u32(&buf[4..8])?,
93 parse_u32(&buf[24..28])?,
94 ))
95}
96
97pub fn parse_sockaddr(buf: &[u8]) -> Option<SocketAddr> {
98 match buf.len() {
99 16 => Some(SocketAddr::V4(parse_sockaddr_v4(buf).unwrap())),
100 28 => Some(SocketAddr::V6(parse_sockaddr_v6(buf).unwrap())),
101 _ => None,
102 }
103}
104
105pub fn encode_ipv4(buf: &mut Vec<u8>, val: Ipv4Addr) {
106 buf.extend(&val.to_bits().to_be_bytes())
107}
108
109pub fn encode_ipv6(buf: &mut Vec<u8>, val: Ipv6Addr) {
110 buf.extend(&val.to_bits().to_be_bytes())
111}
112
113pub fn encode_ip(buf: &mut Vec<u8>, val: IpAddr) {
114 match val {
115 IpAddr::V4(addr) => encode_ipv4(buf, addr),
116 IpAddr::V6(addr) => encode_ipv6(buf, addr),
117 }
118}
119
120pub fn encode_sockaddr_v4(buf: &mut Vec<u8>, val: SocketAddrV4) {
121 buf.extend(&2u16.to_ne_bytes()); buf.extend(&val.port().to_be_bytes());
123 buf.extend(&val.ip().to_bits().to_be_bytes());
124 buf.extend(std::iter::repeat_n(0u8, 8)); }
126
127pub fn encode_sockaddr_v6(buf: &mut Vec<u8>, val: SocketAddrV6) {
128 buf.extend(&10u16.to_ne_bytes()); buf.extend(&val.port().to_be_bytes());
130 buf.extend(&val.flowinfo().to_ne_bytes());
131 buf.extend(&val.ip().to_bits().to_be_bytes());
132 buf.extend(&val.scope_id().to_ne_bytes());
133}
134
135pub fn encode_sockaddr(buf: &mut Vec<u8>, val: SocketAddr) {
136 match val {
137 SocketAddr::V4(addr) => encode_sockaddr_v4(buf, addr),
138 SocketAddr::V6(addr) => encode_sockaddr_v6(buf, addr),
139 }
140}