statime_linux/
socket.rs

1#![forbid(unsafe_code)]
2
3//! Event and General sockets for linux systems
4
5use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
6
7use timestamped_socket::{
8    interface::InterfaceName,
9    networkaddress::{EthernetAddress, MacAddress},
10    socket::{
11        open_interface_ethernet, open_interface_udp4, open_interface_udp6, InterfaceTimestampMode,
12        Open, Socket,
13    },
14};
15
16const IPV6_PRIMARY_MULTICAST: Ipv6Addr = Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0x181);
17const IPV6_PDELAY_MULTICAST: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x6b);
18
19const IPV4_PRIMARY_MULTICAST: Ipv4Addr = Ipv4Addr::new(224, 0, 1, 129);
20const IPV4_PDELAY_MULTICAST: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 107);
21
22const EVENT_PORT: u16 = 319;
23const GENERAL_PORT: u16 = 320;
24
25const PTP_ETHERTYPE: u16 = 0x88f7;
26
27pub trait PtpTargetAddress {
28    const PRIMARY_EVENT: Self;
29    const PRIMARY_GENERAL: Self;
30    const PDELAY_EVENT: Self;
31    const PDELAY_GENERAL: Self;
32}
33
34impl PtpTargetAddress for SocketAddrV4 {
35    const PRIMARY_EVENT: Self = SocketAddrV4::new(IPV4_PRIMARY_MULTICAST, EVENT_PORT);
36    const PRIMARY_GENERAL: Self = SocketAddrV4::new(IPV4_PRIMARY_MULTICAST, GENERAL_PORT);
37    const PDELAY_EVENT: Self = SocketAddrV4::new(IPV4_PDELAY_MULTICAST, EVENT_PORT);
38    const PDELAY_GENERAL: Self = SocketAddrV4::new(IPV4_PDELAY_MULTICAST, GENERAL_PORT);
39}
40
41impl PtpTargetAddress for SocketAddrV6 {
42    const PRIMARY_EVENT: Self = SocketAddrV6::new(IPV6_PRIMARY_MULTICAST, EVENT_PORT, 0, 0);
43    const PRIMARY_GENERAL: Self = SocketAddrV6::new(IPV6_PRIMARY_MULTICAST, GENERAL_PORT, 0, 0);
44    const PDELAY_EVENT: Self = SocketAddrV6::new(IPV6_PDELAY_MULTICAST, EVENT_PORT, 0, 0);
45    const PDELAY_GENERAL: Self = SocketAddrV6::new(IPV6_PDELAY_MULTICAST, GENERAL_PORT, 0, 0);
46}
47
48impl PtpTargetAddress for EthernetAddress {
49    const PRIMARY_EVENT: Self = EthernetAddress::new(
50        PTP_ETHERTYPE,
51        MacAddress::new([0x01, 0x1b, 0x19, 0x00, 0x00, 0x00]),
52        0,
53    );
54    const PRIMARY_GENERAL: Self = Self::PRIMARY_EVENT;
55    const PDELAY_EVENT: Self = EthernetAddress::new(
56        PTP_ETHERTYPE,
57        MacAddress::new([0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e]),
58        0,
59    );
60    const PDELAY_GENERAL: Self = Self::PDELAY_EVENT;
61}
62
63pub fn open_ipv4_event_socket(
64    interface: InterfaceName,
65    timestamping: InterfaceTimestampMode,
66    bind_phc: Option<u32>,
67) -> std::io::Result<Socket<SocketAddrV4, Open>> {
68    let socket = open_interface_udp4(interface, EVENT_PORT, timestamping, bind_phc)?;
69    socket.join_multicast(SocketAddrV4::new(IPV4_PRIMARY_MULTICAST, 0), interface)?;
70    socket.join_multicast(SocketAddrV4::new(IPV4_PDELAY_MULTICAST, 0), interface)?;
71    Ok(socket)
72}
73
74pub fn open_ipv4_general_socket(
75    interface: InterfaceName,
76) -> std::io::Result<Socket<SocketAddrV4, Open>> {
77    let socket = open_interface_udp4(interface, GENERAL_PORT, InterfaceTimestampMode::None, None)?;
78    socket.join_multicast(SocketAddrV4::new(IPV4_PRIMARY_MULTICAST, 0), interface)?;
79    socket.join_multicast(SocketAddrV4::new(IPV4_PDELAY_MULTICAST, 0), interface)?;
80    Ok(socket)
81}
82
83pub fn open_ipv6_event_socket(
84    interface: InterfaceName,
85    timestamping: InterfaceTimestampMode,
86    bind_phc: Option<u32>,
87) -> std::io::Result<Socket<SocketAddrV6, Open>> {
88    let socket = open_interface_udp6(interface, EVENT_PORT, timestamping, bind_phc)?;
89    socket.join_multicast(
90        SocketAddrV6::new(IPV6_PRIMARY_MULTICAST, 0, 0, 0),
91        interface,
92    )?;
93    socket.join_multicast(SocketAddrV6::new(IPV6_PDELAY_MULTICAST, 0, 0, 0), interface)?;
94    Ok(socket)
95}
96
97pub fn open_ipv6_general_socket(
98    interface: InterfaceName,
99) -> std::io::Result<Socket<SocketAddrV6, Open>> {
100    let socket = open_interface_udp6(interface, GENERAL_PORT, InterfaceTimestampMode::None, None)?;
101    // Port, flowinfo and scope doesn't matter for join multicast
102    socket.join_multicast(
103        SocketAddrV6::new(IPV6_PRIMARY_MULTICAST, 0, 0, 0),
104        interface,
105    )?;
106    socket.join_multicast(SocketAddrV6::new(IPV6_PDELAY_MULTICAST, 0, 0, 0), interface)?;
107    Ok(socket)
108}
109
110pub fn open_ethernet_socket(
111    interface: InterfaceName,
112    timestamping: InterfaceTimestampMode,
113    bind_phc: Option<u32>,
114) -> std::io::Result<Socket<EthernetAddress, Open>> {
115    let socket = open_interface_ethernet(interface, PTP_ETHERTYPE, timestamping, bind_phc)?;
116    socket.join_multicast(EthernetAddress::PRIMARY_EVENT, interface)?;
117    socket.join_multicast(EthernetAddress::PDELAY_EVENT, interface)?;
118    Ok(socket)
119}