SatCat5
eth_header.cc
1 // Copyright 2023-2025 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/log.h>
8 
13 
14 bool MacAddr::operator==(const eth::MacAddr& other) const
15 {
16  return (addr[0] == other.addr[0])
17  && (addr[1] == other.addr[1])
18  && (addr[2] == other.addr[2])
19  && (addr[3] == other.addr[3])
20  && (addr[4] == other.addr[4])
21  && (addr[5] == other.addr[5]);
22 }
23 
24 bool MacAddr::operator<(const eth::MacAddr& other) const
25 {
26  for (unsigned a = 0 ; a < 6 ; ++a) {
27  if (addr[a] < other.addr[a]) return true;
28  if (addr[a] > other.addr[a]) return false;
29  }
30  return false; // All bytes equal
31 }
32 
34 {
35  // Match the broadcast address only (FF:FF:FF:FF:FF:FF).
36  return (*this == MACADDR_BROADCAST);
37 }
38 
40 {
41  // Match the L2 multicast block: (01:80:C2:**:**:**),
42  // except for link-local addresses: (01:80:C2:00:00:**).
43  return (addr[0] == BASEADDR_L2MULTICAST.addr[0])
44  && (addr[1] == BASEADDR_L2MULTICAST.addr[1])
45  && (addr[2] == BASEADDR_L2MULTICAST.addr[2])
46  && !is_swcontrol();
47 }
48 
50 {
51  // Match the reserved UDP multicast block (01:00::5E:*:*:*).
52  return (addr[0] == BASEADDR_L3MULTICAST.addr[0])
53  && (addr[1] == BASEADDR_L3MULTICAST.addr[1])
54  && (addr[2] == BASEADDR_L3MULTICAST.addr[2]);
55 }
56 
58 {
59  // Match any type of broadcast or multicast address range.
60  return is_broadcast() || is_l2multicast() || is_l3multicast();
61 }
62 
64 {
65  // Address block (01:80:C2:00:00:*) is reserved for link-local control
66  // messages, such as pause frames, Spanning Tree Protocol, etc.
67  return (addr[0] == BASEADDR_LINKLOCAL.addr[0])
68  && (addr[1] == BASEADDR_LINKLOCAL.addr[1])
69  && (addr[2] == BASEADDR_LINKLOCAL.addr[2])
70  && (addr[3] == BASEADDR_LINKLOCAL.addr[3])
71  && (addr[4] == BASEADDR_LINKLOCAL.addr[4]);
72 }
73 
74 bool MacAddr::is_unicast() const
75 {
76  // Is this a normal unicast MAC? (i.e., Not from a reserved block.)
77  return is_valid() && !(is_multicast() || is_swcontrol());
78 }
79 
80 bool MacAddr::is_valid() const
81 {
82  // Is this a valid MAC of any kind? (i.e., Not zero).
83  return (*this != MACADDR_NONE);
84 }
85 
87 {
88  // Convention is six hex bytes with ":" delimeter.
89  // e.g., "DE:AD:BE:EF:CA:FE"
90  for (unsigned a = 0 ; a < 6 ; ++a) {
91  if (a) wr.wr_str(":");
92  wr.wr_h32(addr[a], 2);
93  }
94 }
95 
97 {
98  wr.wr_str(" = 0x");
99  wr.wr_h32(value, 4);
100 }
101 
103 {
104  wr.wr_str("\r\n VlanID = 0x"); wr.wr_h32(vid(), 3);
105  wr.wr_str("\r\n DropOK = "); wr.wr_d32(dei());
106  wr.wr_str("\r\n Priority = "); wr.wr_d32(pcp());
107 }
108 
110 {
111  wr.wr_str("\r\n DstMAC = "); dst.log_to(wr);
112  wr.wr_str("\r\n SrcMAC = "); src.log_to(wr);
113  wr.wr_str("\r\n EType "); type.log_to(wr);
114  if (vtag.value) vtag.log_to(wr);
115 }
116 
118 {
119  dst.write_to(wr);
120  src.write_to(wr);
121  if (SATCAT5_VLAN_ENABLE && vtag.value) {
122  satcat5::eth::ETYPE_VTAG.write_to(wr);
123  vtag.write_to(wr);
124  }
125  type.write_to(wr);
126 }
127 
129 {
130  if (rd->get_read_ready() < 14) {
131  return false; // Error (incomplete header)
132  } else {
133  dst.read_from(rd); // Read primary header
134  src.read_from(rd);
135  type.read_from(rd);
136  if (SATCAT5_VLAN_ENABLE && type == ETYPE_VTAG) {
137  if (rd->get_read_ready() >= 4) {
138  vtag.read_from(rd); // Tagged frame
139  type.read_from(rd);
140  } else {
141  return false; // Error (incomplete tag)
142  }
143  } else {
144  vtag.value = 0; // Untagged frame
145  }
146  return true; // Success
147  }
148 }
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
Internal buffer used by the Log class.
Definition: log.h:134
void wr_h32(u32 val, unsigned nhex=8)
Write an integer (u32) in hexadecimal format.
Definition: log.cc:303
void wr_str(const char *str)
Write a null-terminated UTF-8 string.
Definition: log.cc:297
void wr_d32(u32 val, unsigned zpad=0)
Write an unsigned integer (u32) in decimal format.
Definition: log.cc:317
Type definitions for Ethernet frames and protocol handlers.
Diagnostic logging to UART and/or Ethernet ports.
An Ethernet frame header.
Definition: eth_header.h:167
void write_to(satcat5::io::Writeable *wr) const
Write Ethernet header to the designated stream.
Definition: eth_header.cc:117
satcat5::eth::MacType type
Ethernet header fields.
Definition: eth_header.h:172
satcat5::eth::VlanTag vtag
Ethernet header fields.
Definition: eth_header.h:173
satcat5::eth::MacAddr src
Ethernet header fields.
Definition: eth_header.h:171
satcat5::eth::MacAddr dst
Ethernet header fields.
Definition: eth_header.h:170
bool read_from(satcat5::io::Readable *rd)
Read Ethernet header from the designated stream.
Definition: eth_header.cc:128
void log_to(satcat5::log::LogBuffer &wr) const
Human-readable report of all fields.
Definition: eth_header.cc:109
An Ethernet MAC address (with serializable interface).
Definition: eth_header.h:29
void write_to(satcat5::io::Writeable *wr) const
Write this field to a byte-stream.
Definition: eth_header.h:86
bool operator<(const satcat5::eth::MacAddr &other) const
Basic comparisons.
Definition: eth_header.cc:24
bool is_l2multicast() const
L2 multicast (01:80:C2:*:*:* except link-local)
Definition: eth_header.cc:39
bool is_valid() const
Any nonzero address.
Definition: eth_header.cc:80
bool is_l3multicast() const
L3 multicast (01:00:5E:*:*:*)
Definition: eth_header.cc:49
bool read_from(satcat5::io::Readable *rd)
Read this field from a byte-stream.
Definition: eth_header.h:89
bool is_swcontrol() const
Link-local control (01:80:C2:00:00:*)
Definition: eth_header.cc:63
u8 addr[6]
Byte array in network order (Index 0 = MSB)
Definition: eth_header.h:31
bool is_multicast() const
Broadcast, L2 multicast, or L3 multicast.
Definition: eth_header.cc:57
bool is_broadcast() const
Broadcast (FF:FF:FF:FF:FF:FF)
Definition: eth_header.cc:33
void log_to(satcat5::log::LogBuffer &wr) const
Format this field as a human-readable string.
Definition: eth_header.cc:86
bool is_unicast() const
Any normal single-destination address.
Definition: eth_header.cc:74
EtherType field (uint16) is used a protocol-ID [1536..65535].
Definition: eth_header.h:96
u16 value
The 16-bit value is stored in processor-native order.
Definition: eth_header.h:98
void write_to(satcat5::io::Writeable *wr) const
Write this field to a byte-stream.
Definition: eth_header.h:115
void log_to(satcat5::log::LogBuffer &wr) const
Format this field as a human-readable string.
Definition: eth_header.cc:96
bool read_from(satcat5::io::Readable *rd)
Read this field from a byte-stream.
Definition: eth_header.h:118
Header contents for an 802.1Q Virtual-LAN tag.
Definition: eth_header.h:124
void log_to(satcat5::log::LogBuffer &wr) const
Format this field as a human-readable string.
Definition: eth_header.cc:102
bool read_from(satcat5::io::Readable *rd)
Read this field from a byte-stream.
Definition: eth_header.h:159
u16 pcp() const
Accessors for each individual field.
Definition: eth_header.h:137
u16 value
The 16-bit value holds VID, DEI, and PCP fields.
Definition: eth_header.h:126
void write_to(satcat5::io::Writeable *wr) const
Write this field to a byte-stream.
Definition: eth_header.h:156
u16 vid() const
Accessors for each individual field.
Definition: eth_header.h:135
u16 dei() const
Accessors for each individual field.
Definition: eth_header.h:136