SatCat5
ip_dhcp.h
Go to the documentation of this file.
1 // Copyright 2023-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
27 
28 #pragma once
29 
30 #include <satcat5/eth_arp.h>
31 #include <satcat5/net_core.h>
32 #include <satcat5/ip_core.h>
33 #include <satcat5/polling.h>
34 #include <satcat5/udp_core.h>
35 
36 // Set default for maximum client-ID length (range 1 - 254).
37 #ifndef SATCAT5_DHCP_MAX_ID_LEN
38 #define SATCAT5_DHCP_MAX_ID_LEN 62
39 #endif
40 
41 namespace satcat5 {
42  namespace ip {
44  struct DhcpId {
45  u8 id_len; // Number of bytes in "id"
46  u8 type; // Type code (RFC2132 Section 9.14)
47  u8 id[SATCAT5_DHCP_MAX_ID_LEN];
48 
49  DhcpId() = default;
50  DhcpId(const DhcpId& t) = default;
51  DhcpId& operator=(const DhcpId& t) = default;
52  };
53 
57  enum class DhcpState {
58  INIT, // Initial state
59  SELECTING, // DISCOVER sent, waiting for OFFER
60  TESTING, // ARP sent, waiting for reply
61  REQUESTING, // REQUEST sent, waiting for ACK
62  BOUND, // Successfully bound
63  RENEWING, // Normal unicast renew
64  REBINDING, // Fallback broadcast renew
65  INFORMING, // INFORM pending or sent; waiting for ACK
66  STOPPED, // Manually halted
67  };
68 
71  class DhcpClient final
73  , public satcat5::net::Protocol
74  , public satcat5::poll::Timer
75  {
76  public:
79  ~DhcpClient() SATCAT5_OPTIONAL_DTOR;
80 
82  void inform(const satcat5::ip::Addr& new_addr);
83 
87  void release(const satcat5::ip::Addr& new_addr = satcat5::ip::ADDR_NONE);
88 
91  void renew();
92 
95  { return m_state; }
96 
98  u32 status() const;
99 
103  inline void set_client_id(const satcat5::ip::DhcpId* id)
104  { m_client_id = id; }
105 
106  private:
107  // Event handler methods.
108  void arp_event(
109  const satcat5::eth::MacAddr& mac,
110  const satcat5::ip::Addr& ip) override;
111  void frame_rcvd(satcat5::io::LimitedRead& src) override;
112  void timer_event() override;
113 
114  // Internal methods.
115  void next_timer();
116  void send_message(u8 opcode);
117 
118  // Internal state.
119  satcat5::udp::Dispatch* const m_iface;
120  const satcat5::ip::DhcpId* m_client_id;
124  u16 m_seconds;
126  u32 m_timeout;
127  u32 m_xid;
128  };
129 
131  struct DhcpAddress {
132  u32 client;
133  u32 timeout;
134 
135  DhcpAddress() = default;
136  DhcpAddress(const DhcpAddress& t) = default;
137  DhcpAddress& operator=(const DhcpAddress& t) = default;
138  };
139 
144  class DhcpPool {
145  public:
149  virtual unsigned addr2idx(const satcat5::ip::Addr& addr) const = 0;
150 
154  virtual satcat5::ip::Addr idx2addr(unsigned idx) const = 0;
155 
159  virtual satcat5::ip::DhcpAddress* idx2meta(unsigned idx) = 0;
160 
162  inline bool contains(const satcat5::ip::Addr& addr)
163  { return idx2addr(addr2idx(addr)).value > 0; }
164 
167  { return idx2meta(addr2idx(addr)); }
168  };
169 
172  template <unsigned SIZE> class DhcpPoolStatic final
173  : public satcat5::ip::DhcpPool
174  {
175  public:
176  DhcpPoolStatic(const satcat5::ip::Addr& base) : m_base(base) {}
177 
178  unsigned addr2idx(const satcat5::ip::Addr& addr) const override
179  { return (unsigned)(addr.value - m_base.value); }
180 
181  satcat5::ip::Addr idx2addr(unsigned idx) const override
182  { return (idx < SIZE) ? (m_base + idx) : ADDR_NONE; }
183 
184  satcat5::ip::DhcpAddress* idx2meta(unsigned idx) override
185  { return (idx < SIZE) ? (m_array + idx) : 0; }
186 
187  private:
188  const satcat5::ip::Addr m_base;
189  satcat5::ip::DhcpAddress m_array[SIZE];
190  };
191 
194  class DhcpServer final
195  : public satcat5::net::Protocol
196  , public satcat5::poll::Timer
197  {
198  public:
200  DhcpServer(
201  satcat5::udp::Dispatch* iface,
202  satcat5::ip::DhcpPool* pool);
203  ~DhcpServer() SATCAT5_OPTIONAL_DTOR;
204 
206  void count_leases(unsigned& free, unsigned& taken) const;
207 
210  satcat5::ip::Addr request(u32 lease_seconds,
211  const satcat5::ip::Addr& addr = satcat5::ip::ADDR_NONE);
212 
216  inline void set_dns(const satcat5::ip::Addr& addr)
217  { m_dns = addr; }
218  inline void set_domain(const char* name)
219  { m_domain = name; }
220  inline void set_gateway(const satcat5::ip::Subnet& gateway)
221  { m_gateway = gateway; }
223 
225  inline void max_lease(u32 seconds)
226  { m_max_lease = seconds; }
227 
228  private:
229  // Event handler methods.
230  void frame_rcvd(satcat5::io::LimitedRead& src) override;
231  void timer_event() override;
232 
233  // Internal methods.
234  satcat5::ip::Addr offer(
235  u32 client_id, u32 req_ipaddr, u32 req_lease);
236  satcat5::ip::Addr reserve(
237  u32 client_id, u32 req_ipaddr, u32 req_lease);
238 
239  // Pointers to helper objects.
240  satcat5::udp::Dispatch* const m_iface;
241  satcat5::ip::DhcpPool* const m_pool;
242 
243  // Current reference time.
244  u32 m_time;
246 
247  // Round-robin indexing into the lease pool.
248  unsigned m_next_lease;
249  unsigned m_next_timer;
250 
251  // Parameters relayed to new clients.
253  const char* m_domain;
255  };
256  }
257 }
Callback interface for responding to ARP and ICMP events.
Definition: eth_arp.h:46
Limited read of next N bytes.
Definition: io_readable.h:255
DHCP Client for leasing an IP address from a server.
Definition: ip_dhcp.h:75
void inform(const satcat5::ip::Addr &new_addr)
Set a static IP and fetch other parameters from the server.
Definition: ip_dhcp.cc:163
u32 m_timeout
Time to next action, in seconds.
Definition: ip_dhcp.h:126
DhcpClient(satcat5::udp::Dispatch *iface)
Attach this DHCP client to a UDP-dispatch object.
Definition: ip_dhcp.cc:128
void arp_event(const satcat5::eth::MacAddr &mac, const satcat5::ip::Addr &ip) override
Callback for any announced MAC/IP address pair.
Definition: ip_dhcp.cc:213
void renew()
Request extension of current lease if held, otherwise request a new lease.
Definition: ip_dhcp.cc:186
satcat5::ip::DhcpState m_state
Client state.
Definition: ip_dhcp.h:122
u32 m_server_id
Server-ID (may not match IP-addr)
Definition: ip_dhcp.h:125
satcat5::udp::Address m_server
Server IP+MAC address.
Definition: ip_dhcp.h:121
void timer_event() override
Child class MUST override this method.
Definition: ip_dhcp.cc:346
void set_client_id(const satcat5::ip::DhcpId *id)
Set an explicit client identifier (RFC2132 Section 9.14).
Definition: ip_dhcp.h:103
void frame_rcvd(satcat5::io::LimitedRead &src) override
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
Definition: ip_dhcp.cc:227
satcat5::ip::Addr m_ipaddr
Assigned IP address, if any.
Definition: ip_dhcp.h:123
satcat5::ip::DhcpState state() const
Report current lease state.
Definition: ip_dhcp.h:94
void release(const satcat5::ip::Addr &new_addr=satcat5::ip::ADDR_NONE)
Relinquish the currently held lease, if one exists.
Definition: ip_dhcp.cc:178
u32 m_xid
Client/server transaction-ID.
Definition: ip_dhcp.h:127
u32 status() const
Report remaining lease time, or zero if none is held.
Definition: ip_dhcp.cc:200
u16 m_seconds
Seconds since start of process.
Definition: ip_dhcp.h:124
Generic container for a group of DhcpAddress objects.
Definition: ip_dhcp.h:144
virtual satcat5::ip::Addr idx2addr(unsigned idx) const =0
Fetch IP-address for Nth object in the pool.
virtual satcat5::ip::DhcpAddress * idx2meta(unsigned idx)=0
Fetch metadata for Nth object in the pool.or Returns NULL if the index is out of bounds.
satcat5::ip::DhcpAddress * addr2meta(const satcat5::ip::Addr &addr)
Two-step lookup of metadata from address.
Definition: ip_dhcp.h:166
virtual unsigned addr2idx(const satcat5::ip::Addr &addr) const =0
Find index associated with the given IP address.
bool contains(const satcat5::ip::Addr &addr)
Does this pool contain the designated address?
Definition: ip_dhcp.h:162
The simplest possible implementation of DhcpPool, supporting a contiguous range of IP-addresses from ...
Definition: ip_dhcp.h:174
satcat5::ip::DhcpAddress * idx2meta(unsigned idx) override
Fetch metadata for Nth object in the pool.or Returns NULL if the index is out of bounds.
Definition: ip_dhcp.h:184
satcat5::ip::Addr idx2addr(unsigned idx) const override
Fetch IP-address for Nth object in the pool.
Definition: ip_dhcp.h:181
unsigned addr2idx(const satcat5::ip::Addr &addr) const override
Find index associated with the given IP address.
Definition: ip_dhcp.h:178
DHCP Server for managing leases to other clients.
Definition: ip_dhcp.h:197
unsigned m_next_timer
Next timer event.
Definition: ip_dhcp.h:249
u32 m_max_lease
Maximum lease in seconds.
Definition: ip_dhcp.h:245
unsigned m_next_lease
Next lease request.
Definition: ip_dhcp.h:248
u32 m_time
Arbitrary timescale (+1/sec)
Definition: ip_dhcp.h:244
void set_domain(const char *name)
Set various optional client-configuration fields.
Definition: ip_dhcp.h:218
satcat5::ip::Subnet m_gateway
Default gateway and subnet mask.
Definition: ip_dhcp.h:254
DhcpServer(satcat5::udp::Dispatch *iface, satcat5::ip::DhcpPool *pool)
Attach this DHCP server to a UDP-dispatch object and address pool.
Definition: ip_dhcp.cc:528
void set_gateway(const satcat5::ip::Subnet &gateway)
Set various optional client-configuration fields.
Definition: ip_dhcp.h:220
satcat5::ip::Addr m_dns
DNS server, if one is available.
Definition: ip_dhcp.h:252
const char * m_domain
Domain name (human-readable)
Definition: ip_dhcp.h:253
void timer_event() override
Child class MUST override this method.
Definition: ip_dhcp.cc:796
satcat5::ip::Addr request(u32 lease_seconds, const satcat5::ip::Addr &addr=satcat5::ip::ADDR_NONE)
Manually request/reserve an IP address for the next N seconds.
Definition: ip_dhcp.cc:579
void frame_rcvd(satcat5::io::LimitedRead &src) override
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
Definition: ip_dhcp.cc:587
void count_leases(unsigned &free, unsigned &taken) const
Report the number of active or open leases.
Definition: ip_dhcp.cc:562
void max_lease(u32 seconds)
Change the lease timeout. (Mostly used for testing.)
Definition: ip_dhcp.h:225
void set_dns(const satcat5::ip::Addr &addr)
Set various optional client-configuration fields.
Definition: ip_dhcp.h:216
A net::Protocol is the counterpart to net::Dispatch that handles a particular data stream,...
Definition: net_protocol.h:28
Timer objects are polled after a fixed delay or at a regular interval.
Definition: polling.h:213
Implementation of "net::Address" for UDP Dispatch.
Definition: udp_core.h:72
Dispatcher sorts incoming UDP messages by port index.
Definition: udp_dispatch.h:20
Protocol handler for the Address Resolution Protocol (ARP)
DhcpState
DHCP protocol state.
Definition: ip_dhcp.h:57
Generic network Dispatch API.
Core event-processing loop for SatCat5 software.
An Ethernet MAC address (with serializable interface).
Definition: eth_header.h:29
IPv4 address is a 32-bit unsigned integer.
Definition: ip_core.h:15
u32 value
Raw access to the underlying representation.
Definition: ip_core.h:17
One address in the pool allocated to a DhcpServer.
Definition: ip_dhcp.h:131
u32 timeout
Lease expiration time.
Definition: ip_dhcp.h:133
u32 client
Hash of client-ID.
Definition: ip_dhcp.h:132
A unique client-identifier.
Definition: ip_dhcp.h:44
An IPv4 subnet consists of a base address and a subnet mask.
Definition: ip_core.h:87