1use crate::id::id_to_canid_t;
15use embedded_can::Id;
16use libc::{sa_family_t, sockaddr, sockaddr_can, sockaddr_storage, socklen_t};
17use nix::net::if_::if_nametoindex;
18use socket2::SockAddr;
19use std::{fmt, io, mem, mem::size_of, os::raw::c_int};
20
21pub use libc::{AF_CAN, CAN_RAW, PF_CAN};
22
23#[derive(Clone, Copy)]
35pub struct CanAddr(sockaddr_can);
36
37impl CanAddr {
38 pub fn new(ifindex: u32) -> Self {
41 let mut addr = Self::default();
42 addr.0.can_ifindex = ifindex as c_int;
43 addr
44 }
45
46 pub fn new_j1939(ifindex: u32, name: u64, pgn: u32, jaddr: u8) -> Self {
49 let mut addr = Self::new(ifindex);
50 addr.0.can_addr.j1939.name = name;
51 addr.0.can_addr.j1939.pgn = pgn;
52 addr.0.can_addr.j1939.addr = jaddr;
53 addr
54 }
55
56 pub fn new_isotp<R, T>(ifindex: u32, rx_id: R, tx_id: T) -> Self
59 where
60 R: Into<Id>,
61 T: Into<Id>,
62 {
63 let mut addr = Self::new(ifindex);
64 addr.0.can_addr.tp.rx_id = id_to_canid_t(rx_id);
65 addr.0.can_addr.tp.tx_id = id_to_canid_t(tx_id);
66 addr
67 }
68
69 pub fn from_iface(ifname: &str) -> io::Result<Self> {
71 let ifindex = if_nametoindex(ifname)?;
72 Ok(Self::new(ifindex))
73 }
74
75 pub fn from_iface_j1939(ifname: &str, name: u64, pgn: u32, jaddr: u8) -> io::Result<Self> {
77 let mut addr = Self::from_iface(ifname)?;
78 addr.0.can_addr.j1939.name = name;
79 addr.0.can_addr.j1939.pgn = pgn;
80 addr.0.can_addr.j1939.addr = jaddr;
81 Ok(addr)
82 }
83
84 pub fn from_iface_isotp<R, T>(ifname: &str, rx_id: R, tx_id: T) -> io::Result<Self>
86 where
87 R: Into<Id>,
88 T: Into<Id>,
89 {
90 let mut addr = Self::from_iface(ifname)?;
91 addr.0.can_addr.tp.rx_id = id_to_canid_t(rx_id);
92 addr.0.can_addr.tp.tx_id = id_to_canid_t(tx_id);
93 Ok(addr)
94 }
95
96 pub fn as_ptr(&self) -> *const sockaddr_can {
98 &self.0
99 }
100
101 pub fn as_sockaddr_ptr(&self) -> *const sockaddr {
103 self.as_ptr().cast()
104 }
105
106 pub fn len() -> usize {
108 size_of::<sockaddr_can>()
109 }
110
111 pub fn as_bytes(&self) -> &[u8] {
113 crate::as_bytes(&self.0)
114 }
115
116 pub fn into_storage(self) -> (sockaddr_storage, socklen_t) {
120 let can_addr = self.as_bytes();
121 let len = can_addr.len();
122
123 let mut storage: sockaddr_storage = unsafe { mem::zeroed() };
124 let sock_addr = crate::as_bytes_mut(&mut storage);
125
126 sock_addr[..len].copy_from_slice(can_addr);
127 (storage, len as socklen_t)
128 }
129
130 pub fn into_sock_addr(self) -> SockAddr {
132 SockAddr::from(self)
133 }
134}
135
136impl Default for CanAddr {
137 fn default() -> Self {
138 let mut addr: sockaddr_can = unsafe { mem::zeroed() };
139 addr.can_family = AF_CAN as sa_family_t;
140 Self(addr)
141 }
142}
143
144impl fmt::Debug for CanAddr {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 write!(
147 f,
148 "CanAddr {{ can_family: {}, can_ifindex: {} }}",
149 self.0.can_family, self.0.can_ifindex
150 )
151 }
152}
153
154impl From<sockaddr_can> for CanAddr {
155 fn from(addr: sockaddr_can) -> Self {
156 Self(addr)
157 }
158}
159
160impl From<CanAddr> for SockAddr {
161 fn from(addr: CanAddr) -> Self {
162 let (storage, len) = addr.into_storage();
163 unsafe { SockAddr::new(storage, len) }
164 }
165}
166
167impl AsRef<sockaddr_can> for CanAddr {
168 fn as_ref(&self) -> &sockaddr_can {
169 &self.0
170 }
171}
172
173#[cfg(test)]
176mod tests {
177 use super::*;
178 use crate::as_bytes;
179
180 const IDX: u32 = 42;
181
182 #[test]
183 fn test_addr() {
184 let _addr = CanAddr::new(IDX);
185
186 assert_eq!(size_of::<sockaddr_can>(), CanAddr::len());
187 }
188
189 #[test]
190 fn test_addr_to_sock_addr() {
191 let addr = CanAddr::new(IDX);
192
193 let (sock_addr, len) = addr.clone().into_storage();
194
195 assert_eq!(CanAddr::len() as socklen_t, len);
196 assert_eq!(as_bytes(&addr), &as_bytes(&sock_addr)[0..len as usize]);
197 }
198}