Skip to main content

socketcan/
socket.rs

1// socketcan/src/socket.rs
2//
3// Implements sockets for CANbus 2.0 and FD for SocketCAN on Linux.
4//
5// This file is part of the Rust 'socketcan-rs' library.
6//
7// Licensed under the MIT license:
8//   <LICENSE or http://opensource.org/licenses/MIT>
9// This file may not be copied, modified, or distributed except according
10// to those terms.
11
12//! Implementation of sockets for CANbus 2.0 and FD for SocketCAN on Linux.
13
14use crate::{
15    as_bytes, as_bytes_mut,
16    frame::{can_frame_default, canfd_frame_default, AsPtr},
17    id::CAN_ERR_MASK,
18    timestamp::CanTimestamps,
19    CanAnyFrame, CanFdFrame, CanFrame, CanRawFrame, Error, IoError, IoErrorKind, IoResult, Result,
20};
21pub use embedded_can::{
22    self, blocking::Can as BlockingCan, nb::Can as NonBlockingCan, ExtendedId,
23    Frame as EmbeddedFrame, Id, StandardId,
24};
25use libc::{canid_t, socklen_t, AF_CAN, EINPROGRESS, SOL_SOCKET};
26use socket2::SockAddr;
27use std::{
28    fmt,
29    io::{Read, Write},
30    mem::{size_of, size_of_val, zeroed},
31    os::{
32        raw::{c_int, c_void},
33        unix::io::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd},
34    },
35    ptr,
36    time::{Duration, SystemTime},
37};
38
39pub use libc::{
40    CANFD_MTU, CAN_MTU, CAN_RAW, CAN_RAW_ERR_FILTER, CAN_RAW_FD_FRAMES, CAN_RAW_FILTER,
41    CAN_RAW_JOIN_FILTERS, CAN_RAW_LOOPBACK, CAN_RAW_RECV_OWN_MSGS, SOL_CAN_BASE, SOL_CAN_RAW,
42};
43
44// TODO: This can be removed on the next major version update
45pub use crate::CanAddr;
46
47/// Check an error return value for timeouts.
48///
49/// Due to the fact that timeouts are reported as errors, calling `read_frame`
50/// on a socket with a timeout that does not receive a frame in time will
51/// result in an error being returned. This trait adds a `should_retry` method
52/// to `Error` and `Result` to check for this condition.
53pub trait ShouldRetry {
54    /// Check for timeout
55    ///
56    /// If `true`, the error is probably due to a timeout.
57    fn should_retry(&self) -> bool;
58}
59
60impl ShouldRetry for IoError {
61    fn should_retry(&self) -> bool {
62        match self.kind() {
63            // EAGAIN, EINPROGRESS and EWOULDBLOCK are the three possible codes
64            // returned when a timeout occurs. the stdlib already maps EAGAIN
65            // and EWOULDBLOCK os WouldBlock
66            IoErrorKind::WouldBlock => true,
67            // however, EINPROGRESS is also valid
68            IoErrorKind::Other => {
69                matches!(self.raw_os_error(), Some(errno) if errno == EINPROGRESS)
70            }
71            _ => false,
72        }
73    }
74}
75
76impl<E: fmt::Debug> ShouldRetry for IoResult<E> {
77    fn should_retry(&self) -> bool {
78        match *self {
79            Err(ref e) => e.should_retry(),
80            _ => false,
81        }
82    }
83}
84
85// ===== Private local helper functions =====
86
87/// Tries to open the CAN socket by the interface number.
88fn raw_open_socket(addr: &CanAddr) -> IoResult<socket2::Socket> {
89    let af_can = socket2::Domain::from(AF_CAN);
90    let can_raw = socket2::Protocol::from(CAN_RAW);
91
92    let sock = socket2::Socket::new_raw(af_can, socket2::Type::RAW, Some(can_raw))?;
93    sock.bind(&SockAddr::from(*addr))?;
94    Ok(sock)
95}
96
97/// `setsockopt` wrapper
98///
99/// The libc `setsockopt` function is set to set various options on a socket.
100/// `set_socket_option` offers a somewhat type-safe wrapper that does not
101/// require messing around with `*const c_void`s.
102///
103/// A proper `std::io::Error` will be returned on failure.
104///
105/// Example use:
106///
107/// ```text
108/// let fd = ...;  // some file descriptor, this will be stdout
109/// set_socket_option(fd, SOL_TCP, TCP_NO_DELAY, 1 as c_int)
110/// ```
111///
112/// Note that the `val` parameter must be specified correctly; if an option
113/// expects an integer, it is advisable to pass in a `c_int`, not the default
114/// of `i32`.
115#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
116#[inline]
117pub fn set_socket_option<T>(fd: c_int, level: c_int, name: c_int, val: &T) -> IoResult<()> {
118    let ret = unsafe {
119        libc::setsockopt(
120            fd,
121            level,
122            name,
123            val as *const _ as *const c_void,
124            size_of::<T>() as socklen_t,
125        )
126    };
127
128    match ret {
129        0 => Ok(()),
130        _ => Err(IoError::last_os_error()),
131    }
132}
133
134/// Sets a collection of multiple socket options with one call.
135#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
136pub fn set_socket_option_mult<T>(
137    fd: c_int,
138    level: c_int,
139    name: c_int,
140    values: &[T],
141) -> IoResult<()> {
142    let ret = if values.is_empty() {
143        // can't pass in a ptr to a 0-len slice, pass a null ptr instead
144        unsafe { libc::setsockopt(fd, level, name, ptr::null(), 0) }
145    } else {
146        unsafe {
147            libc::setsockopt(
148                fd,
149                level,
150                name,
151                values.as_ptr().cast(),
152                size_of_val(values) as socklen_t,
153            )
154        }
155    };
156
157    match ret {
158        0 => Ok(()),
159        _ => Err(IoError::last_os_error()),
160    }
161}
162
163// ===== Common 'Socket' trait =====
164
165/// Common trait for SocketCAN sockets.
166///
167/// Note that a socket it created by opening it, and then closed by
168/// dropping it.
169pub trait Socket: AsRawFd {
170    /// Open a named CAN device.
171    ///
172    /// Usually the more common case, opens a socket can device by name, such
173    /// as "can0", "vcan0", or "socan0".
174    fn open(ifname: &str) -> IoResult<Self>
175    where
176        Self: Sized,
177    {
178        let addr = CanAddr::from_iface(ifname)?;
179        Self::open_addr(&addr)
180    }
181
182    /// Open CAN device by interface number.
183    ///
184    /// Opens a CAN device by kernel interface number.
185    fn open_iface(ifindex: u32) -> IoResult<Self>
186    where
187        Self: Sized,
188    {
189        let addr = CanAddr::new(ifindex);
190        Self::open_addr(&addr)
191    }
192
193    /// Open a CAN socket by address.
194    fn open_addr(addr: &CanAddr) -> IoResult<Self>
195    where
196        Self: Sized;
197
198    /// Gets a shared reference to the underlying socket object
199    fn as_raw_socket(&self) -> &socket2::Socket;
200
201    /// Gets a mutable reference to the underlying socket object
202    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket;
203
204    /// Determines if the socket is currently in nonblocking mode.
205    fn nonblocking(&self) -> IoResult<bool> {
206        self.as_raw_socket().nonblocking()
207    }
208
209    /// Change socket to non-blocking mode or back to blocking mode.
210    fn set_nonblocking(&self, nonblocking: bool) -> IoResult<()> {
211        self.as_raw_socket().set_nonblocking(nonblocking)
212    }
213
214    /// The type of CAN frame that can be read and written by the socket.
215    ///
216    /// This is typically distinguished by the size of the supported frame,
217    /// with the primary difference between a `CanFrame` and a `CanFdFrame`.
218    type FrameType;
219
220    /// Gets the read timeout on the socket, if any.
221    fn read_timeout(&self) -> IoResult<Option<Duration>> {
222        self.as_raw_socket().read_timeout()
223    }
224
225    /// Sets the read timeout on the socket
226    ///
227    /// For convenience, the result value can be checked using
228    /// `ShouldRetry::should_retry` when a timeout is set.
229    ///
230    /// If the duration is set to `None` then write calls will block
231    /// indefinitely.
232    fn set_read_timeout<D>(&self, duration: D) -> IoResult<()>
233    where
234        D: Into<Option<Duration>>,
235    {
236        self.as_raw_socket().set_read_timeout(duration.into())
237    }
238
239    /// Gets the write timeout on the socket, if any.
240    fn write_timeout(&self) -> IoResult<Option<Duration>> {
241        self.as_raw_socket().write_timeout()
242    }
243
244    /// Sets the write timeout on the socket
245    ///
246    /// If the duration is set to `None` then write calls will block
247    /// indefinitely.
248    fn set_write_timeout<D>(&self, duration: D) -> IoResult<()>
249    where
250        D: Into<Option<Duration>>,
251    {
252        self.as_raw_socket().set_write_timeout(duration.into())
253    }
254
255    /// Blocking read a single can frame.
256    ///
257    /// Concurrent readers: each `recvmsg()` consumes one frame from the
258    /// socket's kernel receive queue. If two tasks call `read_frame*` on the
259    /// same socket concurrently (via shared references), each will receive a
260    /// disjoint subset of frames, but no two will ever observe the same
261    /// frame. The frames are not duplicated and the call is safe, but the
262    /// per-reader stream is not deterministic — design with that in mind.
263    fn read_frame(&self) -> IoResult<Self::FrameType>;
264
265    /// Blocking read a single can frame with timeout.
266    fn read_frame_timeout(&self, timeout: Duration) -> IoResult<Self::FrameType> {
267        use nix::poll::{poll, PollFd, PollFlags, PollTimeout};
268        let pollfd = PollFd::new(
269            unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) },
270            PollFlags::POLLIN,
271        );
272
273        match poll(
274            &mut [pollfd],
275            timeout.try_into().unwrap_or(PollTimeout::MAX),
276        )? {
277            0 => Err(IoErrorKind::TimedOut.into()),
278            _ => self.read_frame(),
279        }
280    }
281
282    /// Blocking read a CAN frame and its socket-layer arrival timestamp.
283    ///
284    /// Requires [`SocketOptions::set_recv_timestamp`] to be called with `true`
285    /// before this method. Returns an `InvalidData` error if no
286    /// `SO_TIMESTAMPNS` control message was delivered.
287    fn read_frame_with_timestamp(&self) -> IoResult<(Self::FrameType, SystemTime)> {
288        Err(IoError::from_raw_os_error(libc::ENOSYS))
289    }
290
291    /// Blocking read a CAN frame and its raw hardware clock timestamp.
292    ///
293    /// Requires [`SocketOptions::set_timestamping`] to be called with
294    /// `SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_OPT_CMSG` (and any
295    /// other desired flags) before this method. Returns an `InvalidData` error
296    /// if no hardware timestamp was delivered.
297    fn read_frame_with_hw_timestamp(&self) -> IoResult<(Self::FrameType, Duration)> {
298        Err(IoError::from_raw_os_error(libc::ENOSYS))
299    }
300
301    /// Blocking read a CAN frame and all available timestamps.
302    ///
303    /// Populates whichever [`CanTimestamps`] fields correspond to the
304    /// `SO_TIMESTAMPNS` and/or `SO_TIMESTAMPING` modes that were enabled on
305    /// the socket before the call. Fields for disabled modes are `None`.
306    fn read_frame_with_timestamps(&self) -> IoResult<(Self::FrameType, CanTimestamps)> {
307        Err(IoError::from_raw_os_error(libc::ENOSYS))
308    }
309
310    /// Writes a normal CAN 2.0 frame to the socket.
311    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
312    where
313        F: Into<Self::FrameType> + AsPtr;
314
315    /// Blocking write a single can frame, retrying until it gets sent
316    /// successfully.
317    fn write_frame_insist<F>(&self, frame: &F) -> IoResult<()>
318    where
319        F: Into<Self::FrameType> + AsPtr,
320    {
321        loop {
322            match self.write_frame(frame) {
323                Ok(v) => return Ok(v),
324                Err(e) if e.should_retry() => (),
325                Err(e) => return Err(e),
326            }
327        }
328    }
329}
330
331/// Traits for setting CAN socket options.
332///
333/// These are blocking calls, even when implemented on asynchronous sockets.
334pub trait SocketOptions: AsRawFd {
335    /// Sets an option on the socket.
336    ///
337    /// The libc `setsockopt` function is set to set various options on a socket.
338    /// `set_socket_option` offers a somewhat type-safe wrapper that does not
339    /// require messing around with `*const c_void`s.
340    ///
341    /// A proper `std::io::Error` will be returned on failure.
342    ///
343    /// Example use:
344    ///
345    /// ```text
346    /// sock.set_socket_option(SOL_TCP, TCP_NO_DELAY, 1 as c_int)
347    /// ```
348    ///
349    /// Note that the `val` parameter must be specified correctly; if an option
350    /// expects an integer, it is advisable to pass in a `c_int`, not the default
351    /// of `i32`.
352    fn set_socket_option<T>(&self, level: c_int, name: c_int, val: &T) -> IoResult<()> {
353        let ret = unsafe {
354            libc::setsockopt(
355                self.as_raw_fd(),
356                level,
357                name,
358                val as *const _ as *const c_void,
359                size_of::<T>() as socklen_t,
360            )
361        };
362
363        match ret {
364            0 => Ok(()),
365            _ => Err(IoError::last_os_error()),
366        }
367    }
368
369    /// Sets a collection of multiple socket options with one call.
370    fn set_socket_option_mult<T>(&self, level: c_int, name: c_int, values: &[T]) -> IoResult<()> {
371        let ret = if values.is_empty() {
372            // can't pass in a ptr to a 0-len slice, pass a null ptr instead
373            unsafe { libc::setsockopt(self.as_raw_fd(), level, name, ptr::null(), 0) }
374        } else {
375            unsafe {
376                libc::setsockopt(
377                    self.as_raw_fd(),
378                    level,
379                    name,
380                    values.as_ptr().cast(),
381                    size_of_val(values) as socklen_t,
382                )
383            }
384        };
385
386        match ret {
387            0 => Ok(()),
388            _ => Err(IoError::last_os_error()),
389        }
390    }
391
392    /// Sets CAN ID filters on the socket.
393    ///
394    /// CAN packages received by SocketCAN are matched against these filters,
395    /// only matching packets are returned by the interface.
396    ///
397    /// See `CanFilter` for details on how filtering works. By default, all
398    /// single filter matching all incoming frames is installed.
399    fn set_filters<F>(&self, filters: &[F]) -> IoResult<()>
400    where
401        F: Into<CanFilter> + Copy,
402    {
403        let filters: Vec<CanFilter> = filters.iter().map(|f| (*f).into()).collect();
404        self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, &filters)
405    }
406
407    /// Disable reception of CAN frames.
408    ///
409    /// Sets a completely empty filter; disabling all CAN frame reception.
410    fn set_filter_drop_all(&self) -> IoResult<()> {
411        let filters: &[CanFilter] = &[];
412        self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, filters)
413    }
414
415    /// Accept all frames, disabling any kind of filtering.
416    ///
417    /// Replace the current filter with one containing a single rule that
418    /// acceps all CAN frames.
419    fn set_filter_accept_all(&self) -> IoResult<()> {
420        // safe unwrap: 0, 0 is a valid mask/id pair
421        self.set_filters(&[(0, 0)])
422    }
423
424    /// Sets the error mask on the socket.
425    ///
426    /// By default (`ERR_MASK_NONE`) no error conditions are reported as
427    /// special error frames by the socket. Enabling error conditions by
428    /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
429    /// socket to receive notification about the specified conditions.
430    fn set_error_filter(&self, mask: u32) -> IoResult<()> {
431        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
432    }
433
434    /// Sets the error mask on the socket to reject all errors.
435    #[inline(always)]
436    fn set_error_filter_drop_all(&self) -> IoResult<()> {
437        self.set_error_filter(0)
438    }
439
440    /// Sets the error mask on the socket to accept all errors.
441    #[inline(always)]
442    fn set_error_filter_accept_all(&self) -> IoResult<()> {
443        self.set_error_filter(CAN_ERR_MASK)
444    }
445
446    /// Sets the error mask on the socket.
447    ///
448    /// By default (`ERR_MASK_NONE`) no error conditions are reported as
449    /// special error frames by the socket. Enabling error conditions by
450    /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
451    /// socket to receive notification about the specified conditions.
452    fn set_error_mask(&self, mask: u32) -> IoResult<()> {
453        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
454    }
455
456    /// Enable or disable loopback.
457    ///
458    /// By default, loopback is enabled, causing other applications that open
459    /// the same CAN bus to see frames emitted by different applications on
460    /// the same system.
461    fn set_loopback(&self, enabled: bool) -> IoResult<()> {
462        let loopback = c_int::from(enabled);
463        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback)
464    }
465
466    /// Enable or disable receiving of own frames.
467    ///
468    /// When loopback is enabled, this settings controls if CAN frames sent
469    /// are received back immediately by sender. Default is off.
470    fn set_recv_own_msgs(&self, enabled: bool) -> IoResult<()> {
471        let recv_own_msgs = c_int::from(enabled);
472        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs)
473    }
474
475    /// Enable or disable join filters.
476    ///
477    /// By default a frame is accepted if it matches any of the filters set
478    /// with `set_filters`. If join filters is enabled, a frame has to match
479    /// _all_ filters to be accepted.
480    fn set_join_filters(&self, enabled: bool) -> IoResult<()> {
481        let join_filters = c_int::from(enabled);
482        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &join_filters)
483    }
484
485    /// Enable or disable `SO_TIMESTAMPNS` on the socket.
486    ///
487    /// When enabled, `recvmsg()` delivers a `SCM_TIMESTAMPNS` control message
488    /// containing the socket-layer arrival time as a `timespec`. Call this
489    /// before using [`Socket::read_frame_with_timestamp`].
490    ///
491    /// This option is independent of [`set_timestamping`]; both can be
492    /// enabled simultaneously and the resulting timestamps land in
493    /// separate fields of [`CanTimestamps`].
494    ///
495    /// [`set_timestamping`]: Self::set_timestamping
496    /// [`CanTimestamps`]: crate::CanTimestamps
497    fn set_recv_timestamp(&self, enable: bool) -> IoResult<()> {
498        let val = c_int::from(enable);
499        self.set_socket_option(SOL_SOCKET, libc::SO_TIMESTAMPNS, &val)
500    }
501
502    /// Set `SO_TIMESTAMPING` flags on the socket.
503    ///
504    /// `flags` is a bitmask of `SOF_TIMESTAMPING_*` constants. Each
505    /// timestamp source needs two flags — one to select **when** it is
506    /// taken, and one to request that it be **reported** in the ancillary
507    /// data:
508    ///
509    /// | When (selector)                  | Report (in ancillary data)            |
510    /// |----------------------------------|---------------------------------------|
511    /// | [`SOF_TIMESTAMPING_RX_SOFTWARE`] | [`SOF_TIMESTAMPING_SOFTWARE`]         |
512    /// | [`SOF_TIMESTAMPING_RX_HARDWARE`] | [`SOF_TIMESTAMPING_RAW_HARDWARE`]     |
513    ///
514    /// Setting only a selector flag silently delivers no timestamps;
515    /// setting only a reporter flag captures nothing to report.
516    ///
517    /// In addition, [`SOF_TIMESTAMPING_OPT_CMSG`] is required for RX
518    /// timestamps to actually appear in the cmsg returned by `recvmsg()`
519    /// on non-IP sockets (which includes CAN raw).
520    ///
521    /// Call this before using [`Socket::read_frame_with_timestamps`] or
522    /// [`Socket::read_frame_with_hw_timestamp`].
523    ///
524    /// [`SOF_TIMESTAMPING_OPT_CMSG`]: crate::SOF_TIMESTAMPING_OPT_CMSG
525    /// [`SOF_TIMESTAMPING_RX_SOFTWARE`]: crate::SOF_TIMESTAMPING_RX_SOFTWARE
526    /// [`SOF_TIMESTAMPING_SOFTWARE`]: crate::SOF_TIMESTAMPING_SOFTWARE
527    /// [`SOF_TIMESTAMPING_RX_HARDWARE`]: crate::SOF_TIMESTAMPING_RX_HARDWARE
528    /// [`SOF_TIMESTAMPING_RAW_HARDWARE`]: crate::SOF_TIMESTAMPING_RAW_HARDWARE
529    fn set_timestamping(&self, flags: u32) -> IoResult<()> {
530        let val = flags as c_int;
531        self.set_socket_option(SOL_SOCKET, libc::SO_TIMESTAMPING, &val)
532    }
533}
534
535// ===== Private helpers =====
536
537/// Returns true if the interface bound to `fd` reports RX hardware timestamp support.
538///
539/// Issues a `SIOCETHTOOL` / `ETHTOOL_GET_TS_INFO` ioctl and checks the
540/// `SOF_TIMESTAMPING_RX_HARDWARE` bit.
541///
542/// Returns `false` on any error (unbound socket, unsupported ioctl,
543/// unknown interface, etc).
544fn hw_timestamps_supported(fd: RawFd) -> bool {
545    use crate::timestamp::{EthtoolTsInfo, ETHTOOL_GET_TS_INFO, SOF_TIMESTAMPING_RX_HARDWARE};
546    // Ioctl is u64 in glibc and i32 in musl this ensures the correct type is used for both
547    const SIOCETHTOOL: libc::Ioctl = libc::SIOCETHTOOL as libc::Ioctl;
548
549    // Retrieve the interface index from the bound socket address.
550    let ifindex = unsafe {
551        let mut addr: libc::sockaddr_can = zeroed();
552        let mut addrlen = size_of::<libc::sockaddr_can>() as socklen_t;
553        let ret = libc::getsockname(fd, &mut addr as *mut _ as *mut libc::sockaddr, &mut addrlen);
554        if ret != 0 || addr.can_ifindex <= 0 {
555            return false;
556        }
557        addr.can_ifindex as libc::c_uint
558    };
559
560    // Convert interface index to a name string.
561    let mut ifname = [0 as libc::c_char; libc::IF_NAMESIZE];
562    if unsafe { libc::if_indextoname(ifindex, ifname.as_mut_ptr()) }.is_null() {
563        return false;
564    }
565
566    // Query hardware timestamping capabilities via SIOCETHTOOL.
567    let mut ts_info = EthtoolTsInfo {
568        cmd: ETHTOOL_GET_TS_INFO,
569        so_timestamping: 0,
570        phc_index: 0,
571        tx_types: 0,
572        tx_reserved: [0; 3],
573        rx_filters: 0,
574        rx_reserved: [0; 3],
575    };
576
577    let ret = unsafe {
578        let mut ifr: libc::ifreq = zeroed();
579        ifr.ifr_name.copy_from_slice(&ifname);
580        ifr.ifr_ifru.ifru_data = (&mut ts_info as *mut EthtoolTsInfo).cast();
581        libc::ioctl(fd, SIOCETHTOOL, &mut ifr)
582    };
583
584    ret == 0 && ts_info.so_timestamping & SOF_TIMESTAMPING_RX_HARDWARE != 0
585}
586
587/// Size of the `recvmsg()` ancillary control buffer.
588///
589/// Comfortably larger than what we need today:
590/// `CMSG_SPACE(sizeof(timespec))`            — `SO_TIMESTAMPNS` cmsg
591/// `+ CMSG_SPACE(3 * sizeof(timespec))`      — `SO_TIMESTAMPING` cmsg
592/// ≈ 80 bytes on 64-bit Linux. 256 leaves headroom for future cmsg types.
593const CTRL_BUF_SIZE: usize = 256;
594
595/// Properly-aligned backing storage for the `recvmsg()` ancillary buffer.
596///
597/// `CMSG_FIRSTHDR`/`CMSG_NXTHDR` interpret the buffer as a sequence of
598/// `cmsghdr` structures, which require `usize` alignment on Linux. A raw
599/// `[u8; N]` has alignment 1; aligning to 8 bytes satisfies the contract
600/// on all supported architectures.
601#[repr(C, align(8))]
602struct CtrlBuf([u8; CTRL_BUF_SIZE]);
603
604/// Issues `recvmsg()` on `fd`, writing frame bytes into `frame_buf`, and
605/// parses any `SOL_SOCKET` timestamp control messages into a [`CanTimestamps`].
606///
607/// Returns `(bytes_received, timestamps)`. The returned byte count is the
608/// *real* packet size on the wire (via `MSG_TRUNC`), even if it exceeds
609/// `frame_buf.len()`; callers should compare against `CAN_MTU`/`CANFD_MTU`
610/// before trusting the buffer contents. Timestamp fields are `None` when
611/// the corresponding socket option was not enabled before the call.
612///
613/// Returns `InvalidData` if the kernel sets `MSG_CTRUNC`, indicating the
614/// ancillary buffer was too small to hold all delivered cmsgs.
615fn recvmsg_with_ctrl(fd: RawFd, frame_buf: &mut [u8]) -> IoResult<(usize, CanTimestamps)> {
616    use crate::timestamp::{timespec_to_duration, timespec_to_system_time};
617
618    let mut iov = libc::iovec {
619        iov_base: frame_buf.as_mut_ptr() as *mut libc::c_void,
620        iov_len: frame_buf.len(),
621    };
622
623    let mut ctrl = CtrlBuf([0u8; CTRL_BUF_SIZE]);
624    let mut msg: libc::msghdr = unsafe { zeroed() };
625    msg.msg_iov = &mut iov;
626    msg.msg_iovlen = 1;
627    msg.msg_control = ctrl.0.as_mut_ptr() as *mut libc::c_void;
628    msg.msg_controllen = ctrl.0.len() as _;
629
630    // MSG_TRUNC: return the real packet length even if the iov was too small,
631    // so callers can distinguish classic vs. FD frames by byte count rather
632    // than silently truncating an FD frame into a classic-sized buffer.
633    let n = unsafe { libc::recvmsg(fd, &mut msg, libc::MSG_TRUNC) };
634    if n < 0 {
635        return Err(IoError::last_os_error());
636    }
637
638    if msg.msg_flags & libc::MSG_CTRUNC != 0 {
639        return Err(IoError::new(
640            IoErrorKind::InvalidData,
641            "recvmsg ancillary control buffer overflowed (MSG_CTRUNC)",
642        ));
643    }
644
645    // Minimum cmsg_len for the two payload types we accept. A shorter cmsg
646    // means the payload is truncated; skip rather than reading past it.
647    let ns_min = unsafe { libc::CMSG_LEN(size_of::<libc::timespec>() as u32) } as usize;
648    let scm_min = unsafe { libc::CMSG_LEN((3 * size_of::<libc::timespec>()) as u32) } as usize;
649
650    let mut ts = CanTimestamps::default();
651    let mut cmsg = unsafe { libc::CMSG_FIRSTHDR(&msg) };
652
653    while !cmsg.is_null() {
654        let (level, typ, len) = unsafe {
655            (
656                (*cmsg).cmsg_level,
657                (*cmsg).cmsg_type,
658                (*cmsg).cmsg_len as usize,
659            )
660        };
661        let data = unsafe { libc::CMSG_DATA(cmsg) };
662        match (level, typ) {
663            (SOL_SOCKET, libc::SO_TIMESTAMPNS) if len >= ns_min => {
664                let timespec = unsafe { ptr::read_unaligned(data.cast::<libc::timespec>()) };
665                ts.socket = Some(timespec_to_system_time(timespec));
666            }
667            (SOL_SOCKET, libc::SO_TIMESTAMPING) if len >= scm_min => {
668                // scm_timestamping: [timespec; 3]
669                // [0] = RX_SOFTWARE (sw), [1] deprecated (zero), [2] = HW
670                let tss = unsafe { ptr::read_unaligned(data.cast::<[libc::timespec; 3]>()) };
671                if tss[0].tv_sec != 0 || tss[0].tv_nsec != 0 {
672                    ts.sw = Some(timespec_to_system_time(tss[0]));
673                }
674                if tss[2].tv_sec != 0 || tss[2].tv_nsec != 0 {
675                    ts.hw = Some(timespec_to_duration(tss[2]));
676                }
677            }
678            _ => {}
679        }
680        cmsg = unsafe { libc::CMSG_NXTHDR(&msg, cmsg) };
681    }
682
683    Ok((n as usize, ts))
684}
685
686// ===== CanSocket =====
687
688/// A socket for classic CAN 2.0 devices.
689///
690/// This provides an interface to read and write classic CAN 2.0 frames to
691/// the bus, with up to 8 bytes of data per frame. It wraps a Linux socket
692/// descriptor to a Raw SocketCAN socket.
693///
694/// The socket is automatically closed when the object is dropped. To close
695/// manually, use std::drop::Drop. Internally this is just a wrapped socket
696/// (file) descriptor.
697#[allow(missing_copy_implementations)]
698#[derive(Debug)]
699pub struct CanSocket(socket2::Socket);
700
701impl CanSocket {
702    /// Reads a low-level libc `can_frame` from the socket.
703    pub fn read_raw_frame(&self) -> IoResult<libc::can_frame> {
704        let mut frame = can_frame_default();
705        // SAFETY: `frame` is fully zero-initialised by `can_frame_default`.
706        self.as_raw_socket()
707            .read_exact(unsafe { as_bytes_mut(&mut frame) })?;
708        Ok(frame)
709    }
710
711    /// Returns `true` if the bound interface supports hardware receive timestamps.
712    ///
713    /// Returns `false` if the socket is unbound, the interface does not exist,
714    /// or the driver does not implement the ethtool timestamp query.
715    pub fn has_hw_timestamps(&self) -> bool {
716        hw_timestamps_supported(self.as_raw_fd())
717    }
718}
719
720impl Socket for CanSocket {
721    /// CanSocket reads/writes classic CAN 2.0 frames.
722    type FrameType = CanFrame;
723
724    /// Opens the socket by interface index.
725    fn open_addr(addr: &CanAddr) -> IoResult<Self> {
726        let sock = raw_open_socket(addr)?;
727        Ok(Self(sock))
728    }
729
730    /// Gets a shared reference to the underlying socket object
731    fn as_raw_socket(&self) -> &socket2::Socket {
732        &self.0
733    }
734
735    /// Gets a mutable reference to the underlying socket object
736    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
737        &mut self.0
738    }
739
740    /// Writes a normal CAN 2.0 frame to the socket.
741    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
742    where
743        F: Into<CanFrame> + AsPtr,
744    {
745        self.as_raw_socket().write_all(frame.as_bytes())
746    }
747
748    /// Reads a normal CAN 2.0 frame from the socket.
749    fn read_frame(&self) -> IoResult<CanFrame> {
750        let frame = self.read_raw_frame()?;
751        Ok(frame.into())
752    }
753
754    fn read_frame_with_timestamp(&self) -> IoResult<(CanFrame, SystemTime)> {
755        let (frame, ts) = self.read_frame_with_timestamps()?;
756        let timestamp = ts.socket.ok_or_else(|| {
757            IoError::new(
758                IoErrorKind::InvalidData,
759                "no SO_TIMESTAMPNS control message received",
760            )
761        })?;
762        Ok((frame, timestamp))
763    }
764
765    fn read_frame_with_hw_timestamp(&self) -> IoResult<(CanFrame, Duration)> {
766        let (frame, ts) = self.read_frame_with_timestamps()?;
767        let hw_ts = ts.hw.ok_or_else(|| {
768            IoError::new(
769                IoErrorKind::InvalidData,
770                "no SO_TIMESTAMPING hardware timestamp received",
771            )
772        })?;
773        Ok((frame, hw_ts))
774    }
775
776    fn read_frame_with_timestamps(&self) -> IoResult<(CanFrame, CanTimestamps)> {
777        let mut frame = can_frame_default();
778        // SAFETY: `frame` is fully zero-initialised by `can_frame_default`.
779        let buf = unsafe { as_bytes_mut(&mut frame) };
780        let (n, ts) = recvmsg_with_ctrl(self.as_raw_fd(), buf)?;
781        if n != CAN_MTU {
782            return Err(IoError::from(IoErrorKind::InvalidData));
783        }
784        Ok((CanFrame::from(frame), ts))
785    }
786}
787
788// ===== embedded_can I/O traits =====
789
790impl embedded_can::blocking::Can for CanSocket {
791    type Frame = CanFrame;
792    type Error = Error;
793
794    /// Blocking call to receive the next frame from the bus.
795    ///
796    /// This block and wait for the next frame to be received from the bus.
797    /// If an error frame is received, it will be converted to a `CanError`
798    /// and returned as an error.
799    fn receive(&mut self) -> Result<Self::Frame> {
800        match self.read_frame() {
801            Ok(CanFrame::Error(frame)) => Err(frame.into_error().into()),
802            Ok(frame) => Ok(frame),
803            Err(e) => Err(e.into()),
804        }
805    }
806
807    /// Blocking transmit of a frame to the bus.
808    fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
809        self.write_frame_insist(frame)?;
810        Ok(())
811    }
812}
813
814impl SocketOptions for CanSocket {}
815
816impl embedded_can::nb::Can for CanSocket {
817    type Frame = CanFrame;
818    type Error = Error;
819
820    /// Non-blocking call to receive the next frame from the bus.
821    ///
822    /// If an error frame is received, it will be converted to a `CanError`
823    /// and returned as an error.
824    /// If no frame is available, it returns a `WouldBlck` error.
825    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
826        match self.read_frame() {
827            Ok(CanFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
828            Ok(frame) => Ok(frame),
829            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
830            Err(err) => Err(Error::from(err).into()),
831        }
832    }
833
834    /// Non-blocking transmit of a frame to the bus.
835    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
836        match self.write_frame(frame) {
837            Ok(_) => Ok(None),
838            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
839            Err(err) => Err(Error::from(err).into()),
840        }
841    }
842}
843
844// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
845impl AsRawFd for CanSocket {
846    fn as_raw_fd(&self) -> RawFd {
847        self.0.as_raw_fd()
848    }
849}
850
851impl From<OwnedFd> for CanSocket {
852    fn from(fd: OwnedFd) -> Self {
853        Self(socket2::Socket::from(fd))
854    }
855}
856
857impl IntoRawFd for CanSocket {
858    fn into_raw_fd(self) -> RawFd {
859        self.0.into_raw_fd()
860    }
861}
862
863impl AsFd for CanSocket {
864    fn as_fd(&self) -> BorrowedFd<'_> {
865        self.0.as_fd()
866    }
867}
868
869impl Read for CanSocket {
870    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
871        self.0.read(buf)
872    }
873}
874
875impl Write for CanSocket {
876    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
877        self.0.write(buf)
878    }
879
880    fn flush(&mut self) -> IoResult<()> {
881        self.0.flush()
882    }
883}
884
885// ===== CanFdSocket =====
886
887/// A socket for CAN FD devices.
888///
889/// This can transmit and receive CAN 2.0 frames with up to 8-bytes of data,
890/// or CAN Flexible Data (FD) frames with up to 64-bytes of data.
891#[allow(missing_copy_implementations)]
892#[derive(Debug)]
893pub struct CanFdSocket(socket2::Socket);
894
895impl CanFdSocket {
896    // Enable or disable FD mode on a socket.
897    fn set_fd_mode(sock: socket2::Socket, enable: bool) -> IoResult<socket2::Socket> {
898        let enable = enable as c_int;
899
900        let ret = unsafe {
901            libc::setsockopt(
902                sock.as_raw_fd(),
903                SOL_CAN_RAW,
904                CAN_RAW_FD_FRAMES,
905                &enable as *const _ as *const c_void,
906                size_of::<c_int>() as u32,
907            )
908        };
909
910        match ret {
911            0 => Ok(sock),
912            _ => Err(IoError::last_os_error()),
913        }
914    }
915
916    // Figures out the type of frame from the MTU len read in.
917    // This assumes a socket read a raw packet into a `canfd_frame` and
918    // now needs to figure out which type it is by the MTU size.
919    fn convert_raw_frame(mtu_len: usize, raw_frame: libc::canfd_frame) -> IoResult<CanAnyFrame> {
920        match mtu_len {
921            CAN_MTU => {
922                let mut frame = can_frame_default();
923                // SAFETY: `frame` is zero-initialised; `raw_frame` was either
924                // filled by the kernel or zero-initialised before partial fill,
925                // so all its bytes are valid for read.
926                unsafe {
927                    as_bytes_mut(&mut frame)[..CAN_MTU]
928                        .copy_from_slice(&as_bytes(&raw_frame)[..CAN_MTU]);
929                }
930                Ok(CanFrame::from(frame).into())
931            }
932            CANFD_MTU => Ok(CanFdFrame::from(raw_frame).into()),
933            _ => Err(IoError::from(IoErrorKind::InvalidData)),
934        }
935    }
936
937    /// Returns `true` if the bound interface supports hardware receive timestamps.
938    ///
939    /// Returns `false` if the socket is unbound, the interface does not exist,
940    /// or the driver does not implement the ethtool timestamp query.
941    pub fn has_hw_timestamps(&self) -> bool {
942        hw_timestamps_supported(self.as_raw_fd())
943    }
944
945    /// Reads a raw CAN frame from the socket.
946    ///
947    /// This might be either type of CAN frame, a classic CAN 2.0 frame
948    /// or an FD frame.
949    pub fn read_raw_frame(&self) -> IoResult<CanRawFrame> {
950        let mut fdframe = canfd_frame_default();
951
952        // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
953        let buf = unsafe { as_bytes_mut(&mut fdframe) };
954        match self.as_raw_socket().read(buf)? {
955            // If we only get 'can_frame' number of bytes, then the return is,
956            // by definition, a can_frame, so we just copy the bytes into the
957            // proper type.
958            CAN_MTU => {
959                let mut frame = can_frame_default();
960                // SAFETY: `frame` zero-initialised; `fdframe` likewise (and
961                // possibly partially overwritten by the kernel above).
962                unsafe {
963                    as_bytes_mut(&mut frame)[..CAN_MTU]
964                        .copy_from_slice(&as_bytes(&fdframe)[..CAN_MTU]);
965                }
966                Ok(frame.into())
967            }
968            CANFD_MTU => Ok(fdframe.into()),
969            _ => Err(IoError::last_os_error()),
970        }
971    }
972}
973
974impl Socket for CanFdSocket {
975    /// CanFdSocket can read/write classic CAN 2.0 or FD frames.
976    type FrameType = CanAnyFrame;
977
978    /// Opens the FD socket by interface index.
979    fn open_addr(addr: &CanAddr) -> IoResult<Self> {
980        raw_open_socket(addr)
981            .and_then(|sock| Self::set_fd_mode(sock, true))
982            .map(Self)
983    }
984
985    /// Gets a shared reference to the underlying socket object
986    fn as_raw_socket(&self) -> &socket2::Socket {
987        &self.0
988    }
989
990    /// Gets a mutable reference to the underlying socket object
991    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
992        &mut self.0
993    }
994
995    /// Writes any type of CAN frame to the socket.
996    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
997    where
998        F: Into<Self::FrameType> + AsPtr,
999    {
1000        self.as_raw_socket().write_all(frame.as_bytes())
1001    }
1002
1003    /// Reads either type of CAN frame from the socket.
1004    fn read_frame(&self) -> IoResult<CanAnyFrame> {
1005        let mut fdframe = canfd_frame_default();
1006
1007        // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
1008        let n = self
1009            .as_raw_socket()
1010            .read(unsafe { as_bytes_mut(&mut fdframe) })?;
1011        Self::convert_raw_frame(n, fdframe)
1012    }
1013
1014    fn read_frame_with_timestamp(&self) -> IoResult<(CanAnyFrame, SystemTime)> {
1015        let (frame, ts) = self.read_frame_with_timestamps()?;
1016        let sw_ts = ts.socket.ok_or_else(|| {
1017            IoError::new(
1018                IoErrorKind::InvalidData,
1019                "no SO_TIMESTAMPNS control message received",
1020            )
1021        })?;
1022        Ok((frame, sw_ts))
1023    }
1024
1025    fn read_frame_with_hw_timestamp(&self) -> IoResult<(CanAnyFrame, Duration)> {
1026        let (frame, ts) = self.read_frame_with_timestamps()?;
1027        let hw_ts = ts.hw.ok_or_else(|| {
1028            IoError::new(
1029                IoErrorKind::InvalidData,
1030                "no SO_TIMESTAMPING hardware timestamp received",
1031            )
1032        })?;
1033        Ok((frame, hw_ts))
1034    }
1035
1036    fn read_frame_with_timestamps(&self) -> IoResult<(CanAnyFrame, CanTimestamps)> {
1037        let mut fdframe = canfd_frame_default();
1038        // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
1039        let buf = unsafe { as_bytes_mut(&mut fdframe) };
1040        let (n, ts) = recvmsg_with_ctrl(self.as_raw_fd(), buf)?;
1041        let any_frame = Self::convert_raw_frame(n, fdframe)?;
1042        Ok((any_frame, ts))
1043    }
1044}
1045
1046impl SocketOptions for CanFdSocket {}
1047
1048impl embedded_can::blocking::Can for CanFdSocket {
1049    type Frame = CanAnyFrame;
1050    type Error = Error;
1051
1052    /// Blocking call to receive the next frame from the bus.
1053    ///
1054    /// This block and wait for the next frame to be received from the bus.
1055    /// If an error frame is received, it will be converted to a `CanError`
1056    /// and returned as an error.
1057    fn receive(&mut self) -> Result<Self::Frame> {
1058        match self.read_frame() {
1059            Ok(CanAnyFrame::Error(frame)) => Err(frame.into_error().into()),
1060            Ok(frame) => Ok(frame),
1061            Err(e) => Err(e.into()),
1062        }
1063    }
1064
1065    /// Blocking transmit of a frame to the bus.
1066    fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
1067        self.write_frame_insist(frame)?;
1068        Ok(())
1069    }
1070}
1071
1072impl embedded_can::nb::Can for CanFdSocket {
1073    type Frame = CanAnyFrame;
1074    type Error = Error;
1075
1076    /// Non-blocking call to receive the next frame from the bus.
1077    ///
1078    /// If an error frame is received, it will be converted to a `CanError`
1079    /// and returned as an error.
1080    /// If no frame is available, it returns a `WouldBlck` error.
1081    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
1082        match self.read_frame() {
1083            Ok(CanAnyFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
1084            Ok(frame) => Ok(frame),
1085            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
1086            Err(err) => Err(Error::from(err).into()),
1087        }
1088    }
1089
1090    /// Non-blocking transmit of a frame to the bus.
1091    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
1092        match self.write_frame(frame) {
1093            Ok(_) => Ok(None),
1094            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
1095            Err(err) => Err(Error::from(err).into()),
1096        }
1097    }
1098}
1099
1100// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
1101impl AsRawFd for CanFdSocket {
1102    fn as_raw_fd(&self) -> RawFd {
1103        self.0.as_raw_fd()
1104    }
1105}
1106
1107impl From<OwnedFd> for CanFdSocket {
1108    fn from(fd: OwnedFd) -> CanFdSocket {
1109        Self(socket2::Socket::from(fd))
1110    }
1111}
1112
1113impl TryFrom<CanSocket> for CanFdSocket {
1114    type Error = IoError;
1115
1116    fn try_from(sock: CanSocket) -> std::result::Result<Self, Self::Error> {
1117        let CanSocket(sock2) = sock;
1118        let sock = CanFdSocket::set_fd_mode(sock2, true)?;
1119        Ok(CanFdSocket(sock))
1120    }
1121}
1122
1123impl IntoRawFd for CanFdSocket {
1124    fn into_raw_fd(self) -> RawFd {
1125        self.0.into_raw_fd()
1126    }
1127}
1128
1129impl AsFd for CanFdSocket {
1130    fn as_fd(&self) -> BorrowedFd<'_> {
1131        self.0.as_fd()
1132    }
1133}
1134
1135impl Read for CanFdSocket {
1136    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
1137        self.0.read(buf)
1138    }
1139}
1140
1141impl Write for CanFdSocket {
1142    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
1143        self.0.write(buf)
1144    }
1145
1146    fn flush(&mut self) -> IoResult<()> {
1147        self.0.flush()
1148    }
1149}
1150
1151// ===== CanFilter =====
1152
1153/// The CAN filter defines which ID's can be accepted on a socket.
1154///
1155/// Each filter contains an internal id and mask. Packets are considered to
1156/// be matched by a filter if `received_id & mask == filter_id & mask` holds
1157/// true.
1158///
1159/// A socket can be given multiple filters, and each one can be inverted
1160/// ([ref](https://docs.kernel.org/networking/can.html#raw-protocol-sockets-with-can-filters-sock-raw))
1161#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1162pub struct CanFilter(libc::can_filter);
1163
1164impl CanFilter {
1165    /// Construct a new CAN filter.
1166    pub fn new(id: canid_t, mask: canid_t) -> Self {
1167        Self(libc::can_filter {
1168            can_id: id,
1169            can_mask: mask,
1170        })
1171    }
1172
1173    /// Construct a new inverted CAN filter.
1174    pub fn new_inverted(id: canid_t, mask: canid_t) -> Self {
1175        Self::new(id | libc::CAN_INV_FILTER, mask)
1176    }
1177}
1178
1179impl From<libc::can_filter> for CanFilter {
1180    fn from(filt: libc::can_filter) -> Self {
1181        Self(filt)
1182    }
1183}
1184
1185impl From<(u32, u32)> for CanFilter {
1186    fn from(filt: (u32, u32)) -> Self {
1187        CanFilter::new(filt.0, filt.1)
1188    }
1189}
1190
1191impl AsRef<libc::can_filter> for CanFilter {
1192    fn as_ref(&self) -> &libc::can_filter {
1193        &self.0
1194    }
1195}