netlink_packet_sock_diag/inet/
socket_id.rs1use std::convert::{TryFrom, TryInto};
4use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
5
6use byteorder::{BigEndian, ByteOrder};
7use netlink_packet_utils::traits::{Emitable, ParseableParametrized};
8use netlink_packet_utils::{DecodeError, buffer};
9
10use crate::constants::*;
11
12pub const SOCKET_ID_LEN: usize = 48;
13
14buffer!(SocketIdBuffer(SOCKET_ID_LEN) {
15 source_port: (slice, 0..2),
16 destination_port: (slice, 2..4),
17 source_address: (slice, 4..20),
18 destination_address: (slice, 20..36),
19 interface_id: (u32, 36..40),
20 cookie: (slice, 40..48),
21});
22
23#[derive(Debug, PartialEq, Eq, Clone)]
24pub struct SocketId {
25 pub source_port: u16,
26 pub destination_port: u16,
27 pub source_address: IpAddr,
28 pub destination_address: IpAddr,
29 pub interface_id: u32,
30 pub cookie: [u8; 8],
35}
36
37impl SocketId {
38 pub fn new_v4() -> Self {
39 Self {
40 source_port: 0,
41 destination_port: 0,
42 source_address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
43 destination_address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
44 interface_id: 0,
45 cookie: [0; 8],
46 }
47 }
48 pub fn new_v6() -> Self {
49 Self {
50 source_port: 0,
51 destination_port: 0,
52 source_address: IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)),
53 destination_address: IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)),
54 interface_id: 0,
55 cookie: [0; 8],
56 }
57 }
58}
59
60impl<'a, T: AsRef<[u8]> + 'a> ParseableParametrized<SocketIdBuffer<&'a T>, u8> for SocketId {
61 type Error = DecodeError;
62 fn parse_with_param(buf: &SocketIdBuffer<&'a T>, af: u8) -> Result<Self, DecodeError> {
63 let (source_address, destination_address) = match af {
64 AF_INET => {
65 let s = &buf.source_address()[..4];
66 let source = IpAddr::V4(Ipv4Addr::new(s[0], s[1], s[2], s[3]));
67
68 let s = &buf.destination_address()[..4];
69 let destination = IpAddr::V4(Ipv4Addr::new(s[0], s[1], s[2], s[3]));
70
71 (source, destination)
72 }
73 AF_INET6 => {
74 let bytes: [u8; 16] = buf.source_address().try_into().unwrap();
75 let source = IpAddr::V6(Ipv6Addr::from(bytes));
76
77 let bytes: [u8; 16] = buf.destination_address().try_into().unwrap();
78 let destination = IpAddr::V6(Ipv6Addr::from(bytes));
79 (source, destination)
80 }
81 _ => {
82 return Err(DecodeError::from(format!(
83 "unsupported address family {af}: expected AF_INET ({AF_INET}) or AF_INET6 ({AF_INET6})"
84 )));
85 }
86 };
87
88 Ok(Self {
89 source_port: BigEndian::read_u16(buf.source_port()),
90 destination_port: BigEndian::read_u16(buf.destination_port()),
91 source_address,
92 destination_address,
93 interface_id: buf.interface_id(),
94 cookie: TryFrom::try_from(buf.cookie()).unwrap(),
97 })
98 }
99}
100
101impl Emitable for SocketId {
102 fn buffer_len(&self) -> usize {
103 SOCKET_ID_LEN
104 }
105
106 fn emit(&self, buffer: &mut [u8]) {
107 let mut buffer = SocketIdBuffer::new_unchecked(buffer);
108
109 BigEndian::write_u16(buffer.source_port_mut(), self.source_port);
110 BigEndian::write_u16(buffer.destination_port_mut(), self.destination_port);
111
112 let mut address_buf: [u8; 16] = [0; 16];
113 match self.source_address {
114 IpAddr::V4(ip) => address_buf[0..4].copy_from_slice(&ip.octets()[..]),
115 IpAddr::V6(ip) => address_buf.copy_from_slice(&ip.octets()[..]),
116 }
117
118 buffer.source_address_mut().copy_from_slice(&address_buf[..]);
119
120 address_buf = [0; 16];
121 match self.destination_address {
122 IpAddr::V4(ip) => address_buf[0..4].copy_from_slice(&ip.octets()[..]),
123 IpAddr::V6(ip) => address_buf.copy_from_slice(&ip.octets()[..]),
124 }
125
126 buffer.destination_address_mut().copy_from_slice(&address_buf[..]);
127
128 buffer.set_interface_id(self.interface_id);
129 buffer.cookie_mut().copy_from_slice(&self.cookie[..]);
130 }
131}