SatCat5
ip_core.h
1 // Copyright 2021-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 // Basic type definitions for Internet Protocol v4 packets (IPv4)
6 
7 #pragma once
8 
9 #include <satcat5/io_core.h>
10 
11 namespace satcat5 {
12  namespace ip {
15  struct Addr {
17  u32 value;
18 
20  constexpr Addr()
21  : value(0) {}
23  constexpr Addr(u32 ip) // NOLINT
24  : value(ip) {}
26  constexpr Addr(u16 msb, u16 lsb)
27  : value(65536ul * msb + lsb) {}
29  constexpr Addr(u8 a, u8 b, u8 c, u8 d)
30  : value(16777216ul * a + 65536ul * b + 256ul * c + d) {}
31  Addr(const Addr& t) = default;
32  Addr& operator=(const Addr& t) = default;
33 
36  constexpr bool operator==(const satcat5::ip::Addr& other) const
37  {return value == other.value;}
38  constexpr bool operator!=(const satcat5::ip::Addr& other) const
39  {return value != other.value;}
40  inline void write_to(satcat5::io::Writeable* wr) const
41  {wr->write_u32(value);}
43  {value = rd->read_u32(); return true;}
44  constexpr satcat5::ip::Addr operator+(unsigned offset) const
45  {return satcat5::ip::Addr(value + (u32)offset);}
47 
49  void log_to(satcat5::log::LogBuffer& wr) const;
50 
51  // Tests for various reserved address ranges:
52  bool is_broadcast() const;
53  bool is_multicast() const;
54  bool is_reserved() const;
55  bool is_unicast() const;
56  bool is_valid() const;
57  };
58 
60  constexpr u32 cidr_prefix(unsigned npre) {
61  return (npre ? ~((0x80000000 >> (npre-1)) - 1) : 0);
62  }
63 
66  struct Mask : public satcat5::ip::Addr {
68  constexpr Mask()
69  : Addr() {}
71  constexpr Mask(unsigned npre) // NOLINT
72  : Addr(satcat5::ip::cidr_prefix(npre)) {}
74  constexpr Mask(u8 a, u8 b, u8 c, u8 d)
75  : Addr(a, b, c, d) {}
77  constexpr Mask(const satcat5::ip::Addr& addr) // NOLINT
78  : Addr(addr.value) {}
79  Mask& operator=(const Mask& t) = default;
80 
83  unsigned prefix() const;
84  };
85 
87  struct Subnet {
88  // Raw access to the underlying representation.
91 
92  Subnet() = default;
93  Subnet(const Subnet& t) = default;
94  Subnet& operator=(const Subnet& t) = default;
95 
97  constexpr bool contains(const satcat5::ip::Addr& other) const
98  {return (addr.value & mask.value) == (other.value & mask.value);}
99 
102  constexpr bool operator==(const satcat5::ip::Addr& other) const
103  {return (addr == other) && (mask == Mask(32));}
104  constexpr bool operator==(const satcat5::ip::Subnet& other) const
105  {return (addr == other.addr) && (mask == other.mask);}
106  constexpr bool operator!=(const satcat5::ip::Subnet& other) const
107  {return (addr != other.addr) || (mask != other.mask);}
109 
111  inline unsigned prefix() const
112  {return mask.prefix();}
113 
115  void log_to(satcat5::log::LogBuffer& wr) const;
116  };
117 
119  struct Port {
121  u16 value;
122 
124  constexpr Port(u16 port) : value(port) {} // NOLINT
125  Port(const Port& t) = default;
126  Port& operator=(const Port& t) = default;
127 
130  constexpr bool operator==(const satcat5::ip::Port& other) const
131  {return value == other.value;}
132  constexpr bool operator!=(const satcat5::ip::Port& other) const
133  {return value != other.value;}
134  inline void write_to(satcat5::io::Writeable* wr) const
135  {wr->write_u16(value);}
137  {value = rd->read_u16(); return true;}
139  };
140 
143  constexpr unsigned
144  HDR_MIN_WORDS = 5,
145  HDR_MIN_SHORTS = 2 * HDR_MIN_WORDS,
146  HDR_MIN_BYTES = 4 * HDR_MIN_WORDS,
147  HDR_MAX_WORDS = 15,
148  HDR_MAX_SHORTS = 2 * HDR_MAX_WORDS,
149  HDR_MAX_BYTES = 4 * HDR_MAX_WORDS;
151 
152  // Commonly used IP-addresses and other constants:
153  constexpr satcat5::ip::Mask
154  MASK_NONE = 0,
155  MASK_8 = 8,
156  MASK_16 = 16,
157  MASK_24 = 24,
158  MASK_32 = 32;
159  constexpr satcat5::ip::Port
160  PORT_NONE = 0;
161  constexpr satcat5::ip::Addr
162  ADDR_NONE(0, 0, 0, 0),
163  ADDR_BROADCAST(255, 255, 255, 255),
164  ADDR_LOOPBACK(127, 0, 0, 1),
165  ADDR_ALL_SYSTEMS(224, 0, 0, 1),
166  ADDR_ALL_ROUTERS(224, 0, 0, 2),
167  ADDR_PTP_PDELAY(224, 0, 0, 107),
168  ADDR_PTP_PRIMARY(224, 0, 1, 129);
169  constexpr satcat5::ip::Subnet
170  DEFAULT_ROUTE = {ADDR_NONE, MASK_NONE},
171  UDP_MULTICAST = {Addr(224, 0, 0, 0), Mask(4)};
172 
173  constexpr u8 PROTO_ICMP = 0x01;
174  constexpr u8 PROTO_IGMP = 0x02;
175  constexpr u8 PROTO_TCP = 0x06;
176  constexpr u8 PROTO_UDP = 0x11;
177 
180  struct Header {
182  u16 data[HDR_MAX_SHORTS];
183 
184  Header() = default;
185  Header(const Header& t) = default;
186  Header& operator=(const Header& t) = default;
187 
188  // Accessors for specific sub-fields.
189  // See also: https://en.wikipedia.org/wiki/IPv4#Header
190  constexpr unsigned ver() const
191  {return (data[0] >> 12) & 0x0F;}
192  constexpr unsigned ihl() const
193  {return (data[0] >> 8) & 0x0F;}
194  constexpr unsigned len_total() const
195  {return data[1];}
196  constexpr u16 id() const
197  {return data[2];}
198  constexpr u16 frg() const
199  {return data[3] & 0xBFFF;}
200  constexpr unsigned len_inner() const
201  {return len_total() - 4*ihl();}
202  constexpr u8 ttl() const
203  {return (u8)(data[4] >> 8);}
204  constexpr u8 proto() const
205  {return (u8)(data[4] & 0x00FF);}
206  constexpr u16 chk() const
207  {return data[5];}
208  constexpr satcat5::ip::Addr src() const
209  {return satcat5::ip::Addr(data[6], data[7]);}
210  constexpr satcat5::ip::Addr dst() const
211  {return satcat5::ip::Addr(data[8], data[9]);}
212 
219  void chk_incr16(u16 prev, u16 next);
220  void chk_incr32(u32 prev, u32 next);
222 
224  void option_alert();
225 
228  void write_to(satcat5::io::Writeable* wr) const;
229 
237  bool read_core(satcat5::io::Readable* rd); // Core header (first 20 bytes)
238 
243  bool read_from(satcat5::io::Readable* rd); // Entire header (up to 64 bytes)
244  };
245 
248  u16 checksum(unsigned wcount, const u16* data, u16 prev = UINT16_MAX);
249  }
250 }
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
Internal buffer used by the Log class.
Definition: log.h:134
I/O interface core definitions.
IPv4 address is a 32-bit unsigned integer.
Definition: ip_core.h:15
constexpr satcat5::ip::Addr operator+(unsigned offset) const
Commonly used operators.
Definition: ip_core.h:44
u32 value
Raw access to the underlying representation.
Definition: ip_core.h:17
constexpr bool operator==(const satcat5::ip::Addr &other) const
Commonly used operators.
Definition: ip_core.h:36
bool is_multicast() const
IP multicast (224.*.*.*)
Definition: ip_core.cc:41
bool read_from(satcat5::io::Readable *rd)
Commonly used operators.
Definition: ip_core.h:42
constexpr Addr(u8 a, u8 b, u8 c, u8 d)
Constructor in human-readable form (a.b.c.d)
Definition: ip_core.h:29
bool is_unicast() const
Any normal single-destination address.
Definition: ip_core.cc:59
void log_to(satcat5::log::LogBuffer &wr) const
Format this IP address in standard form, e.g., "192.168.1.2".
Definition: ip_core.cc:12
constexpr bool operator!=(const satcat5::ip::Addr &other) const
Commonly used operators.
Definition: ip_core.h:38
constexpr Addr()
Constructor for the null address (0.0.0.0).
Definition: ip_core.h:20
bool is_valid() const
Any nonzero address.
Definition: ip_core.cc:63
bool is_reserved() const
Reserved blocks (0.*.*.* or 127.*.*.*)
Definition: ip_core.cc:50
constexpr Addr(u16 msb, u16 lsb)
Constructor for two 16-bit integers.
Definition: ip_core.h:26
bool is_broadcast() const
Limited broadcast (255.255.255.255)
Definition: ip_core.cc:37
void write_to(satcat5::io::Writeable *wr) const
Commonly used operators.
Definition: ip_core.h:40
constexpr Addr(u32 ip)
Constructor for a single 32-bit integer.
Definition: ip_core.h:23
Structure for holding an IPv4 Header, including options.
Definition: ip_core.h:180
constexpr u16 id() const
< Identifier / sequence number
Definition: ip_core.h:196
constexpr unsigned len_total() const
< Total bytes including header
Definition: ip_core.h:194
void write_to(satcat5::io::Writeable *wr) const
Write IPv4 header to the designated stream.
Definition: ip_core.cc:82
constexpr unsigned len_inner() const
< Inner bytes excluding header
Definition: ip_core.h:200
constexpr u16 chk() const
< Checksum (incoming only)
Definition: ip_core.h:206
void chk_incr16(u16 prev, u16 next)
Incremental update to checksum when replacing a given field.
Definition: ip_core.cc:94
constexpr u8 ttl() const
< Time to Live (TTL)
Definition: ip_core.h:202
bool read_from(satcat5::io::Readable *rd)
Read an entire IPv4 header from the designated stream.
Definition: ip_core.cc:127
void option_alert()
}
Definition: ip_core.cc:106
constexpr u8 proto() const
< Inner protocol (UDP/TCP/etc.)
Definition: ip_core.h:204
constexpr u16 frg() const
< Fragment offset
Definition: ip_core.h:198
constexpr unsigned ver() const
< Header version (i.e., "4")
Definition: ip_core.h:190
constexpr unsigned ihl() const
< Header length (4-byte words)
Definition: ip_core.h:192
constexpr satcat5::ip::Addr dst() const
< Destination address
Definition: ip_core.h:210
bool read_core(satcat5::io::Readable *rd)
Read a partial IPv4 header from the designated stream.
Definition: ip_core.cc:115
u16 data[HDR_MAX_SHORTS]
Raw access to the underlying header contents.
Definition: ip_core.h:182
constexpr satcat5::ip::Addr src() const
< Source address
Definition: ip_core.h:208
IPv4 subnet masks share functionality with a basic address, but are constructed differently to match ...
Definition: ip_core.h:66
constexpr Mask()
Constructor for the wildcard mask (match all addresses).
Definition: ip_core.h:68
unsigned prefix() const
Convert this subnet-mask to a CIDR prefix length.
Definition: ip_core.cc:67
constexpr Mask(u8 a, u8 b, u8 c, u8 d)
Constructor in subnet-mask form (a.b.c.d).
Definition: ip_core.h:74
constexpr Mask(unsigned npre)
Constructor for the a CIDR prefix (e.g., /24).
Definition: ip_core.h:71
constexpr Mask(const satcat5::ip::Addr &addr)
Copy-constructor.
Definition: ip_core.h:77
UDP and TCP ports are both 16-bit unsigned integers.
Definition: ip_core.h:119
constexpr bool operator!=(const satcat5::ip::Port &other) const
Commonly used operators.
Definition: ip_core.h:132
bool read_from(satcat5::io::Readable *rd)
Commonly used operators.
Definition: ip_core.h:136
void write_to(satcat5::io::Writeable *wr) const
Commonly used operators.
Definition: ip_core.h:134
u16 value
Raw access to the underlying representation.
Definition: ip_core.h:121
constexpr Port(u16 port)
Constructor.
Definition: ip_core.h:124
constexpr bool operator==(const satcat5::ip::Port &other) const
Commonly used operators.
Definition: ip_core.h:130
An IPv4 subnet consists of a base address and a subnet mask.
Definition: ip_core.h:87
void log_to(satcat5::log::LogBuffer &wr) const
Format this subnet in CIDR form, e.g., "192.168.1.0/24".
Definition: ip_core.cc:29
unsigned prefix() const
Get the CIDR prefix length for this subnet.
Definition: ip_core.h:111
satcat5::ip::Mask mask
Subnet mask.
Definition: ip_core.h:90
constexpr bool operator!=(const satcat5::ip::Subnet &other) const
Commonly used operators.
Definition: ip_core.h:106
constexpr bool operator==(const satcat5::ip::Addr &other) const
Commonly used operators.
Definition: ip_core.h:102
constexpr bool contains(const satcat5::ip::Addr &other) const
Does this subnet contain the given address?
Definition: ip_core.h:97
satcat5::ip::Addr addr
Base address.
Definition: ip_core.h:89
constexpr bool operator==(const satcat5::ip::Subnet &other) const
Commonly used operators.
Definition: ip_core.h:104