netlink_bindings/
primitives.rs

1pub 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    // TODO: check family
57    parse_be_u32(buf).map(Ipv4Addr::from_bits)
58}
59
60pub fn parse_ipv6(buf: &[u8]) -> Option<Ipv6Addr> {
61    // TODO: check family
62    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    // TODO: check family
75    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    // TODO: check family
86    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()); // AF_INET
122    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)); // padding
125}
126
127pub fn encode_sockaddr_v6(buf: &mut Vec<u8>, val: SocketAddrV6) {
128    buf.extend(&10u16.to_ne_bytes()); // AF_INET6
129    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}