stm32plus::net ARP Module
ARP. The mission-critical protocol that you’ve never heard of.
The Address Resolution Protocol (ARP) exists because the datalink layer talks in terms of MAC addresses and the network layer talks IP addresses. ARP exists as a translation module that maps between the two.
Under the hood it’s a very simple protocol that works by generating broadcast frames that ask questions such as “hey, who’s got IP address 192.168.1.2?”. And of course it also responds to questions from other stations with answers such as “I own 192.168.1.2 and my MAC address is 02-00-00-00-00-00”.
The internal implementation of ARP in stm32plus::net involves a cache so that we can maintain the IP-to-MAC association in-memory for frequently used hosts and it has the capability to broadcast our IP-to-MAC association on startup so that other stations on the LAN can update their cache appropriately.
You don’t have to do anything to get ARP to work, it works in the background responding automatically to requests for your address.
ARP implementation
ARP has no compile-time configuration parameters. You just include it in your Network layer configuration as shown in the example below. This is a stripped down example to show only Arp
in the network layer. In practice you are going to have more than just ARP in there:
typedef NetworkLayer<MyDatalinkLayer,Arp> MyNetworkLayer;
Configuration Parameters
The following parameters are made available in the stack’s configuration object for customisation:
// true if we broadcast our own address on startup, default is true bool arp_startupBroadcast; // number of entries to include in the ARP cache, default is 10 uint16_t arp_cacheSize; // The max seconds to keep an ARP cache entry, default is 600 uint32_t arp_cacheExpirySeconds; // how long in ms to wait for an ARP reply, default is 5000 uint32_t arp_replyTimeout; // number of times to retry, default is 5 uint8_t arp_retries;
If you set arp_startupBroadcast
to true
then a gratuitous ARP request is sent when the ARP module learns your IP address. This feature allows other stations on the network to update their caches so that they don’t have to send queries to us when we start sending data. The default is true
.
arp_cacheSize
is the maximum number of entries that the ARP cache can hold. A cache entry costs 16 bytes therefore the default of 10 entries costs you 160 bytes of SRAM.
arp_cacheExpirySeconds
is the number of seconds to hold a mapping in the cache after it has last been used. Cache entries are only ejected if the cache is full and a new entry needs to be added.
arp_replyTimeout
is the number of milliseconds to wait for a reply from the LAN when we need to query for a MAC address.
arp_retries
is the number of times we will retry after a timeout when querying for a MAC address. The net effect to the user is that if you try to send a packet to an IP address that does not exist on the LAN then you will have to wait for arp_retries * arp_replyTimeout/1000
seconds for it to give up and timeout.
Methods exposed
void arpBroadcastMyAddress(); void arpSendRequest(IpAddress& ipaddress); void arpSendProbe(IpAddress& ipaddress);
arpBroadcastMyAddress
will send a gratuitous ARP request informing all stations on the network of our IP-to-MAC mapping.
arpSendRequest
will broadcast a request to find out who owns the given IP address. A successful response will result in the mapping being added to the ARP cache and an event being raised.
arpSendProbe
will send an ARP probe which is a request to find out if anyone owns the given IP address. The LLIP application protocol uses this to discover if the address that it has selected has already been claimed by another station.
Events raised
The ARP module raises the following events.
sender | ArpReceiveEventSender |
---|---|
event | ArpReceiveEvent |
identifier | NetEventType::ARP_FRAME |
context | IRQ |
purpose | ARP frame received annoucement |
/** * ARP receive frame event */ struct ArpReceiveEvent : NetEventDescriptor { /** * The ARP frame that arrived */ const ArpFrameData& arpFrameData; /** * Constructor */ ArpReceiveEvent(const ArpFrameData& afd) : NetEventDescriptor(NetEventType::ARP_FRAME), arpFrameData(afd) { } };
This event is raised after any ARP frame has been received, request or reply. The ArpFrameData
structure contains the decoded ARP frame information.