SatCat5
ptp_interface.cc
1 // Copyright 2023-2024 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/eth_header.h>
7 #include <satcat5/ip_core.h>
8 #include <satcat5/ptp_interface.h>
9 #include <satcat5/udp_core.h>
10 #include <satcat5/utils.h>
11 
13 using satcat5::ptp::PacketType;
15 
16 // Note: This function is timing-critical, because it is often called
17 // from inside interrupt service routines. Minimize excess delays.
18 bool Interface::ptp_dispatch(const u8* peek, unsigned length)
19 {
20  // Sanity check: If no PTP callback, skip detailed inspection.
21  m_ptp_rx_type = PacketType::NON_PTP;
22  if (!m_ptp_callback) return false;
23 
24  // Avoid out-of-bounds read
25  if (length < 14) return false;
26 
27  // Peek at the contents and determine if it is a PTP message.
28  satcat5::eth::MacType ether_type =
29  {extract_be_u16(peek + 12)};
30 
31  if (ether_type == satcat5::eth::ETYPE_PTP) {
32  // PTP - L2 if etherType is 0x88F7
33  m_ptp_rx_type = PacketType::PTP_L2;
34  } else if (ether_type == satcat5::eth::ETYPE_IPV4) {
35  // Might be PTP - L3 if ether_type is 0x0800
36  // Get IPv4 protocol type, check if it's UDP.
37 
38  // Avoid out-of-bounds read
39  if (length < 24) return false;
40 
41  u8 protocol = peek[23];
42  if (protocol == satcat5::ip::PROTO_UDP) {
43  // Get the IPv4 header length (in 32-bit words)
44  unsigned header_length = peek[14] & 0x000f;
45 
46  // Read the UDP source and destination ports
47  // (their position depends on the header length)
48  unsigned src_port_index = 14 + header_length * 4;
49  unsigned dst_port_index = 16 + header_length * 4;
50 
51  // Avoid out-of-bounds read
52  if (length < dst_port_index + 2) return false;
53 
54  satcat5::ip::Port src_port = extract_be_u16(peek + src_port_index);
55  satcat5::ip::Port dst_port = extract_be_u16(peek + dst_port_index);
56 
57  // If source or destination port is 319 or 320, message is PTP - L3
58  if (src_port == satcat5::udp::PORT_PTP_EVENT ||
59  src_port == satcat5::udp::PORT_PTP_GENERAL ||
60  dst_port == satcat5::udp::PORT_PTP_EVENT ||
61  dst_port == satcat5::udp::PORT_PTP_GENERAL) {
62  m_ptp_rx_type = PacketType::PTP_L3;
63  }
64  }
65  }
66 
67  // Indicate whether caller should call ptp_notify().
68  return m_ptp_rx_type != PacketType::NON_PTP;
69 }
Generic API for network ports that support PTP.
Definition: ptp_interface.h:27
Type definitions for Ethernet frames and protocol handlers.
EtherType field (uint16) is used a protocol-ID [1536..65535].
Definition: eth_header.h:96
UDP and TCP ports are both 16-bit unsigned integers.
Definition: ip_core.h:119
Miscellaneous mathematical utility functions.
u16 extract_be_u16(const u8 *src)
Extract fields from a big-endian byte array.
Definition: utils.cc:151