SatCat5
udp_core.cc
1 // Copyright 2021-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/udp_core.h>
7 #include <satcat5/udp_dispatch.h>
8 
9 using satcat5::ip::PROTO_UDP;
11 using satcat5::udp::HEADER_BYTES;
12 using satcat5::udp::PORT_NONE;
13 
14 Address::Address(satcat5::udp::Dispatch* iface)
15  : m_iface(nullptr)
16  , m_addr(nullptr, PROTO_UDP)
17  , m_dstport(PORT_NONE)
18  , m_srcport(PORT_NONE)
19 {
20  init(iface);
21 }
22 
24  if (iface && !m_iface) {
25  m_iface = iface;
26  m_addr.init(iface->iface());
27  }
28 }
29 
31  const satcat5::udp::Addr& dstaddr,
32  const satcat5::eth::MacAddr& dstmac,
33  const satcat5::udp::Port& dstport,
34  const satcat5::udp::Port& srcport,
35  const satcat5::eth::VlanTag& vtag)
36 {
37  m_dstport = dstport;
38  m_srcport = (m_iface && srcport == PORT_NONE)
39  ? m_iface->next_free_port() : srcport;
40  m_addr.connect(dstaddr, dstmac, vtag);
41 }
42 
44  const satcat5::udp::Addr& dstaddr,
45  const satcat5::udp::Port& dstport,
46  const satcat5::udp::Port& srcport,
47  const satcat5::eth::VlanTag& vtag)
48 {
49  m_dstport = dstport;
50  m_srcport = (m_iface && srcport == PORT_NONE)
51  ? m_iface->next_free_port() : srcport;
52  m_addr.connect(dstaddr, vtag);
53 }
54 
56  return m_iface
57  && m_addr.matches_reply_address()
58  && m_iface->reply_src() == dstport()
59  && m_iface->reply_dst() == srcport();
60 }
61 
63  return m_iface;
64 }
65 
66 satcat5::ip::Header Address::ip_header(unsigned len) const {
67  // IP frame contains 8-byte UDP header plus inner UDP data.
68  return m_iface->iface()->next_header(PROTO_UDP, dstaddr(), len + HEADER_BYTES);
69 }
70 
72  return m_iface ? m_iface->open_write(m_addr, m_srcport, m_dstport, len) : nullptr;
73 }
74 
76  if (m_iface) {
77  m_addr.save_reply_address(); // Save IP/MAC/VLAN parameters
78  m_dstport = m_iface->reply_src(); // Swap dst/src port numbers
79  m_srcport = m_iface->reply_dst();
80  }
81 }
82 
84  src.write_to(wr);
85  dst.write_to(wr);
86  wr->write_u16(length);
87  // Checksum of 0 means checksum is disabled as permitted under IETF RFC 768
88  wr->write_u16(0x0);
89 }
90 
92  if (rd->get_read_ready() < HEADER_BYTES) {return false;}
93  src.read_from(rd);
94  dst.read_from(rd);
95  length = rd->read_u16();
96  // Read and discard checksum
97  rd->read_u16();
98  return true;
99 }
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
void connect(const satcat5::ip::Addr &dstaddr, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Automatic address resolution using routing table + ARP.
Definition: ip_address.cc:54
void save_reply_address() override
Bind this Address object to the parent interface's current reply address, as provided in net::Dispatc...
Definition: ip_address.cc:152
bool matches_reply_address() const override
Does this Address object match the parent interface's current reply address? Multicast destinations s...
Definition: ip_address.cc:139
void init(satcat5::ip::Dispatch *iface)
Deferred initialization of the upstream interface.
Definition: ip_address.cc:47
satcat5::ip::Header next_header(u8 protocol, const satcat5::ip::Addr &dst, unsigned inner_bytes, u8 ttl=SATCAT5_IP_TTL)
Create a basic IPv4 header with the specified information.
Definition: ip_dispatch.cc:79
The "Dispatch" is a generic interface that knows how to read a designated protocol layer and sort inc...
Definition: net_dispatch.h:36
Implementation of "net::Address" for UDP Dispatch.
Definition: udp_core.h:72
void save_reply_address() override
Bind this Address object to the parent interface's current reply address, as provided in net::Dispatc...
Definition: udp_core.cc:75
satcat5::net::Dispatch * iface() const override
Fetch a pointer to the underlying interface.
Definition: udp_core.cc:62
satcat5::io::Writeable * open_write(unsigned len) override
Open a new frame to the designated address and type.
Definition: udp_core.cc:71
void connect(const satcat5::udp::Addr &dstaddr, const satcat5::eth::MacAddr &dstmac, const satcat5::udp::Port &dstport, const satcat5::udp::Port &srcport=satcat5::udp::PORT_NONE, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Manual address resolution (user supplies IP + MAC).
Definition: udp_core.cc:30
bool matches_reply_address() const override
Does this Address object match the parent interface's current reply address? Multicast destinations s...
Definition: udp_core.cc:55
void init(satcat5::udp::Dispatch *iface)
Deferred initialization of the upstream interface.
Definition: udp_core.cc:23
Dispatcher sorts incoming UDP messages by port index.
Definition: udp_dispatch.h:20
satcat5::io::Writeable * open_write(satcat5::ip::Address &addr, const satcat5::udp::Port &src, const satcat5::udp::Port &dst, unsigned len)
Send a datagram to the designated UDP address and port.
Definition: udp_dispatch.cc:84
satcat5::udp::Port next_free_port()
Get the next unclaimed dynamically-allocated port index.
Definition: udp_dispatch.cc:48
An Ethernet MAC address (with serializable interface).
Definition: eth_header.h:29
Header contents for an 802.1Q Virtual-LAN tag.
Definition: eth_header.h:124
IPv4 address is a 32-bit unsigned integer.
Definition: ip_core.h:15
Structure for holding an IPv4 Header, including options.
Definition: ip_core.h:180
UDP and TCP ports are both 16-bit unsigned integers.
Definition: ip_core.h:119
void write_to(satcat5::io::Writeable *wr) const
Write UDP header to the designated stream.
Definition: udp_core.cc:83
bool read_from(satcat5::io::Readable *rd)
Read UDP header from the designated stream.
Definition: udp_core.cc:91