1#![forbid(unsafe_code)]
2
3use 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 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}