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.