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