7 #include <satcat5/eth_dispatch.h>
11 namespace eth = satcat5::eth;
12 namespace ip = satcat5::ip;
13 namespace log = satcat5::log;
20 static const unsigned DEBUG_VERBOSE = 0;
23 static const u16 ARP_HTYPE_ETHERNET = 0x0001;
24 static const u16 ARP_PTYPE_IPV4 = 0x0800;
25 static const u8 ARP_HLEN_ETHERNET = 6;
26 static const u8 ARP_PLEN_IPV4 = 4;
27 static const u16 ARP_OPER_QUERY = 0x0001;
28 static const u16 ARP_OPER_REPLY = 0x0002;
37 u16 htype = src->read_u16();
38 u16 ptype = src->read_u16();
41 oper = src->read_u16();
48 if (DEBUG_VERBOSE > 0)
52 if (htype != ARP_HTYPE_ETHERNET)
return false;
53 if (ptype != ARP_PTYPE_IPV4)
return false;
54 if (hlen != ARP_HLEN_ETHERNET)
return false;
55 if (plen != ARP_PLEN_IPV4)
return false;
58 if (
sha == eth::MACADDR_NONE)
return false;
59 if (
sha == eth::MACADDR_BROADCAST)
return false;
64 wr->write_u16(ARP_HTYPE_ETHERNET);
65 wr->write_u16(ARP_PTYPE_IPV4);
78 : eth::
Protocol(dispatch, eth::ETYPE_ARP)
91 eth::MACADDR_BROADCAST,
102 return send_internal(
105 eth::MACADDR_BROADCAST,
114 return send_internal(
117 eth::MACADDR_BROADCAST,
120 eth::MACADDR_BROADCAST,
128 item = m_listeners.
next(item);
133 if (DEBUG_VERBOSE > 1)
134 log::Log(log::DEBUG,
"ProtoArp: frame_rcvd");
147 item = m_listeners.
next(item);
156 if (reply_spa != eth::MACADDR_NONE) {
159 if (DEBUG_VERBOSE > 0)
160 log::Log(log::DEBUG,
"ProtoArp: Sending reply");
161 auto vtag =
m_iface->reply_vtag();
162 send_internal(ARP_OPER_REPLY, vtag, hdr.
sha, reply_spa, hdr.
tpa, hdr.
sha, hdr.
spa);
163 }
else if (DEBUG_VERBOSE > 1) {
170 if (hdr.
oper != ARP_OPER_QUERY)
return eth::MACADDR_NONE;
171 if (hdr.
tpa == m_ipaddr)
return m_iface->macaddr();
175 if (!m_table)
return eth::MACADDR_NONE;
177 if (!route.is_proxy_arp())
return eth::MACADDR_NONE;
178 return (route.dstmac == eth::MACADDR_NONE) ?
m_iface->macaddr() : route.dstmac;
181 bool ProtoArp::send_internal(u16 opcode,
191 if (!(opcode == ARP_OPER_REPLY || tpa.
is_unicast())) {
192 if (DEBUG_VERBOSE > 0)
200 if (!wr)
return false;
203 wr->write_u16(ARP_HTYPE_ETHERNET);
204 wr->write_u16(ARP_PTYPE_IPV4);
207 wr->write_u16(opcode);
Callback interface for responding to ARP and ICMP events.
virtual void gateway_change(const satcat5::ip::Addr &dstaddr, const satcat5::ip::Addr &gateway)
Callback for changes to gateway configuration.
virtual void arp_event(const satcat5::eth::MacAddr &mac, const satcat5::ip::Addr &ip)=0
Callback for any announced MAC/IP address pair.
Implemention of "net::Dispatch" for Ethernet frames.
satcat5::io::Writeable * open_write(const satcat5::eth::MacAddr &dst, const satcat5::eth::MacType &type, satcat5::eth::VlanTag vtag=satcat5::eth::VTAG_NONE)
Send a frame to the designated Ethernet address/VLAN.
Protocol handler for Ethernet-to-IPv4 ARP queries and replies.
bool send_query(const satcat5::ip::Addr &target, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Send a query for a given IP address.
ProtoArp(satcat5::eth::Dispatch *dispatcher, const satcat5::ip::Addr &ipaddr=satcat5::ip::ADDR_NONE)
Attach this ARP handler to an eth::Dispatch interface.
void gateway_change(const satcat5::ip::Addr &dstaddr, const satcat5::ip::Addr &gateway)
Notify all listeners of a change in gateway configuration.
bool send_probe(const satcat5::ip::Addr &target, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Send a probe to test if a given address is occupied.
void frame_rcvd(satcat5::io::LimitedRead &src) override
New-frame notifications from the parent interface.
bool send_announce(const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE) const
Send an unsolicited ARP announcement.
Accept incoming Ethernet packets by EtherType.
satcat5::eth::Dispatch *const m_iface
Parent interface (e.g., for address and I/O)
Limited read of next N bytes.
Abstract API for reading byte-streams and packets.
bool read_obj(T &t)
Templated wrapper for any object with the following method: bool read_from(satcat5::io::Readable* rd)...
u8 read_u8()
One of many functions for reading integer/floating point values, see details.
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Abstract API for writing byte-streams and packets.
void write_u8(u8 data)
One of many functions for writing integer/floating point values, see details.
virtual bool write_finalize()
Mark end of frame and release temporary working data.
void write_obj(const T &obj)
Templated wrapper for any object with the following method: void write_to(satcat5::io::Writeable* wr)...
satcat5::ip::Route route_lookup(const satcat5::ip::Addr &dstaddr) const
Next-hop routing lookup for the given destination address.
The Log class creates and formats one log message.
Log & write(const char *str)
Formatting methods for various data types.
T * next(const T *item) const
Fetch pointer to the next item.
Protocol handler for the Address Resolution Protocol (ARP)
Internet Protocol v4 (IPv4) forwarding table.
Diagnostic logging to UART and/or Ethernet ports.
An Ethernet MAC address (with serializable interface).
bool is_unicast() const
Any normal single-destination address.
Header contents for an 802.1Q Virtual-LAN tag.
IPv4 address is a 32-bit unsigned integer.
u32 value
Raw access to the underlying representation.
bool is_unicast() const
Any normal single-destination address.