Address Resolution Protocol module for IP over Ethernet.
Functionally, ARP is divided into two parts. The first maps an IP address to a physical address when sending a packet, and the second part answers requests from other machines for our physical address.
This implementation complies with RFC 826 (Ethernet ARP). It supports Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 if an interface calls etharp_gratuitous(our_netif) upon address change.
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "netif/etharp.h"
#include <string.h>
Data Structures | |
struct | etharp_entry |
Macros | |
#define | ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) |
Re-request a used ARP entry 1 minute before it would expire to prevent breaking a steadily used connection because the ARP entry timed out. More... | |
#define | ARP_MAXAGE 240 |
the time an ARP entry stays valid after its last update, for ARP_TMR_INTERVAL = 5000, this is (240 * 5) seconds = 20 minutes. More... | |
#define | ARP_MAXPENDING 2 |
the time an ARP entry stays pending after first request, for ARP_TMR_INTERVAL = 5000, this is (2 * 5) seconds = 10 seconds. More... | |
#define | ETHARP_FLAG_FIND_ONLY 2 |
#define | ETHARP_FLAG_TRY_HARD 1 |
Try hard to create a new entry - we want the IP address to appear in the cache (even if this means removing an active entry or so). More... | |
#define | ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) |
#define | free_etharp_q(q) pbuf_free(q) |
Compatibility define: free the queued pbuf. More... | |
#define | HWTYPE_ETHERNET 1 |
#define | LL_MULTICAST_ADDR_0 0x01 |
The 24-bit IANA multicast OUI is 01-00-5e: More... | |
#define | LL_MULTICAST_ADDR_1 0x00 |
#define | LL_MULTICAST_ADDR_2 0x5e |
Enumerations | |
enum | etharp_state { ETHARP_STATE_EMPTY = 0, ETHARP_STATE_PENDING, ETHARP_STATE_STABLE, ETHARP_STATE_STABLE_REREQUESTING } |
Functions | |
static void | etharp_arp_input (struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) |
Responds to ARP requests to us. More... | |
void | etharp_cleanup_netif (struct netif *netif) |
Remove all ARP table entries of the specified netif. More... | |
s8_t | etharp_find_addr (struct netif *netif, ip_addr_t *ipaddr, struct eth_addr **eth_ret, ip_addr_t **ip_ret) |
Finds (stable) ethernet/IP address pair from ARP table using interface and IP address index. More... | |
static s8_t | etharp_find_entry (ip_addr_t *ipaddr, u8_t flags) |
Search the ARP table for a matching or new entry. More... | |
static void | etharp_free_entry (int i) |
Clean up ARP table entries. More... | |
err_t | etharp_output (struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) |
Resolve and fill-in Ethernet address header for outgoing IP packet. More... | |
static err_t | etharp_output_to_arp_index (struct netif *netif, struct pbuf *q, u8_t arp_idx) |
Just a small helper function that sends a pbuf to an ethernet address in the arp_table specified by the index 'arp_idx'. More... | |
err_t | etharp_query (struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) |
Send an ARP request for the given IP address and/or queue a packet. More... | |
static err_t | etharp_raw (struct netif *netif, const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr, const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, const u16_t opcode) |
Send a raw ARP packet (opcode and all addresses can be modified) More... | |
err_t | etharp_request (struct netif *netif, ip_addr_t *ipaddr) |
Send an ARP request packet asking for ipaddr. More... | |
static err_t | etharp_send_ip (struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) |
Send an IP packet on the network using netif->linkoutput The ethernet header is filled in before sending. More... | |
void | etharp_tmr (void) |
Clears expired entries in the ARP table. More... | |
static err_t | etharp_update_arp_entry (struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) |
Update (or insert) a IP/MAC address pair in the ARP cache. More... | |
err_t | ethernet_input (struct pbuf *p, struct netif *netif) |
Process received ethernet frames. More... | |
Variables | |
static struct etharp_entry | arp_table [ARP_TABLE_SIZE] |
static u8_t | etharp_cached_entry |
struct eth_addr | ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}} |
struct eth_addr | ethzero = {{0,0,0,0,0,0}} |
#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) |
Re-request a used ARP entry 1 minute before it would expire to prevent breaking a steadily used connection because the ARP entry timed out.
Referenced by etharp_output_to_arp_index().
#define ARP_MAXAGE 240 |
the time an ARP entry stays valid after its last update, for ARP_TMR_INTERVAL = 5000, this is (240 * 5) seconds = 20 minutes.
Referenced by etharp_tmr().
#define ARP_MAXPENDING 2 |
the time an ARP entry stays pending after first request, for ARP_TMR_INTERVAL = 5000, this is (2 * 5) seconds = 10 seconds.
Keep this number at least 2, otherwise it might run out instantly if the timeout occurs directly after a request.
Referenced by etharp_tmr().
#define ETHARP_FLAG_FIND_ONLY 2 |
Referenced by etharp_arp_input(), etharp_find_addr(), etharp_find_entry(), and etharp_update_arp_entry().
#define ETHARP_FLAG_TRY_HARD 1 |
Try hard to create a new entry - we want the IP address to appear in the cache (even if this means removing an active entry or so).
Referenced by etharp_arp_input(), etharp_find_entry(), etharp_query(), and etharp_update_arp_entry().
#define ETHARP_SET_HINT | ( | netif, | |
hint | |||
) | (etharp_cached_entry = (hint)) |
Referenced by etharp_output(), and etharp_query().
#define free_etharp_q | ( | q | ) | pbuf_free(q) |
Compatibility define: free the queued pbuf.
Referenced by etharp_free_entry().
#define HWTYPE_ETHERNET 1 |
Referenced by etharp_arp_input(), and etharp_raw().
#define LL_MULTICAST_ADDR_0 0x01 |
The 24-bit IANA multicast OUI is 01-00-5e:
Referenced by etharp_output(), and ethernet_input().
#define LL_MULTICAST_ADDR_1 0x00 |
Referenced by etharp_output(), and ethernet_input().
#define LL_MULTICAST_ADDR_2 0x5e |
Referenced by etharp_output(), and ethernet_input().
enum etharp_state |
|
static |
Responds to ARP requests to us.
Upon ARP replies to us, add entry to cache send out queued IP packets. Updates cache with snooped address pairs.
Should be called for incoming ARP packets. The pbuf in the argument is freed by this function.
netif | The lwIP network interface on which the ARP packet pbuf arrived. |
ethaddr | Ethernet address of netif. |
p | The ARP packet that arrived on netif. Is freed by this function. |
References ARP_REPLY, ARP_REQUEST, ETHADDR16_COPY, ETHARP_DEBUG, ETHARP_FLAG_FIND_ONLY, ETHARP_FLAG_TRY_HARD, ETHARP_HWADDR_LEN, ETHARP_STATS_INC, etharp_update_arp_entry(), ETHTYPE_IP, ETHTYPE_VLAN, htons, netif::hwaddr_len, HWTYPE_ETHERNET, netif::ip_addr, ip_addr_cmp, ip_addr_isany, ip_addr_islinklocal, IPADDR2_COPY, pbuf::len, netif::linkoutput, LWIP_ASSERT, LWIP_DBG_LEVEL_WARNING, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_ERROR(), NULL, pbuf::payload, pbuf_free(), PP_HTONS, S16_F, SIZEOF_ETH_HDR, SIZEOF_ETHARP_PACKET, pbuf::tot_len, and U16_F.
Referenced by ethernet_input().
Remove all ARP table entries of the specified netif.
netif | points to a network interface |
References arp_table, etharp_free_entry(), ETHARP_STATE_EMPTY, etharp_entry::state, and netif::state.
Referenced by netif_set_down().
s8_t etharp_find_addr | ( | struct netif * | netif, |
ip_addr_t * | ipaddr, | ||
struct eth_addr ** | eth_ret, | ||
ip_addr_t ** | ip_ret | ||
) |
Finds (stable) ethernet/IP address pair from ARP table using interface and IP address index.
netif | points to interface index |
ipaddr | points to the (network order) IP address index |
eth_ret | points to return pointer |
ip_ret | points to return pointer |
References arp_table, etharp_entry::ethaddr, etharp_find_entry(), ETHARP_FLAG_FIND_ONLY, ETHARP_STATE_STABLE, etharp_entry::ipaddr, LWIP_ASSERT, LWIP_UNUSED_ARG, NULL, and netif::state.
Search the ARP table for a matching or new entry.
If an IP address is given, return a pending or stable ARP entry that matches the address. If no match is found, create a new entry with this address set, but in state ETHARP_EMPTY. The caller must check and possibly change the state of the returned entry.
If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
In all cases, attempt to create new entries from an empty entry. If no empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle old entries. Heuristic choose the least important entry for recycling.
ipaddr | IP address to find in ARP cache, or to add if not found. |
flags |
netif | netif related to this address (used for NETIF_HWADDRHINT) |
a) do a search through the cache, remember candidates b) select candidate entry c) create new entry
References arp_table, etharp_entry::ctime, ERR_MEM, ETHARP_DEBUG, ETHARP_FLAG_FIND_ONLY, ETHARP_FLAG_TRY_HARD, etharp_free_entry(), ETHARP_STATE_EMPTY, ETHARP_STATE_PENDING, ETHARP_STATE_STABLE, ip_addr_cmp, ip_addr_copy, LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, NULL, etharp_entry::state, and U16_F.
Referenced by etharp_find_addr(), etharp_query(), and etharp_update_arp_entry().
|
static |
Clean up ARP table entries.
References arp_table, etharp_entry::ctime, etharp_entry::ethaddr, ETHARP_DEBUG, ETHARP_STATE_EMPTY, ethzero, free_etharp_q, ip_addr_set_zero, LWIP_DEBUGF, etharp_entry::netif, NULL, etharp_entry::q, snmp_delete_arpidx_tree, etharp_entry::state, and U16_F.
Referenced by etharp_cleanup_netif(), etharp_find_entry(), etharp_tmr(), and etharp_update_arp_entry().
Resolve and fill-in Ethernet address header for outgoing IP packet.
For IP multicast and broadcast, corresponding Ethernet addresses are selected and the packet is transmitted on the link.
For unicast addresses, the packet is submitted to etharp_query(). In case the IP address is outside the local network, the IP address of the gateway is used.
netif | The lwIP network interface which the IP packet will be sent on. |
q | The pbuf(s) containing the IP packet to be sent. |
ipaddr | The IP address of the packet destination. |
References arp_table, ERR_BUF, ERR_RTE, etharp_cached_entry, ETHARP_DEBUG, etharp_output_to_arp_index(), etharp_query(), etharp_send_ip(), ETHARP_SET_HINT, ETHARP_STATE_STABLE, ETHARP_STATS_INC, netif::gw, netif::hwaddr, ip4_addr2, ip4_addr3, ip4_addr4, netif::ip_addr, ip_addr_cmp, ip_addr_isany, ip_addr_isbroadcast, ip_addr_islinklocal, ip_addr_ismulticast, ip_addr_netcmp, LINK_STATS_INC, LL_MULTICAST_ADDR_0, LL_MULTICAST_ADDR_1, LL_MULTICAST_ADDR_2, LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_TRACE, LWIP_DEBUGF, netif::netmask, NULL, pbuf::payload, and pbuf_header().
Referenced by ethernetif_init().
|
static |
Just a small helper function that sends a pbuf to an ethernet address in the arp_table specified by the index 'arp_idx'.
References ARP_AGE_REREQUEST_USED, arp_table, ERR_OK, etharp_entry::ethaddr, etharp_request(), etharp_send_ip(), ETHARP_STATE_STABLE, ETHARP_STATE_STABLE_REREQUESTING, netif::hwaddr, LWIP_ASSERT, and etharp_entry::state.
Referenced by etharp_output().
Send an ARP request for the given IP address and/or queue a packet.
If the IP address was not yet in the cache, a pending ARP cache entry is added and an ARP request is sent for the given address. The packet is queued on this entry.
If the IP address was already pending in the cache, a new ARP request is sent for the given address. The packet is queued on this entry.
If the IP address was already stable in the cache, and a packet is given, it is directly sent and no ARP request is sent out.
If the IP address was already stable in the cache, and no packet is given, an ARP request is sent out.
netif | The lwIP network interface on which ipaddr must be queried for. |
ipaddr | The IP address to be resolved. |
q | If non-NULL, a pbuf that must be delivered to the IP address. q is not freed by this function. |
References arp_table, ERR_ARG, ERR_MEM, ERR_OK, ETHARP_DEBUG, etharp_find_entry(), ETHARP_FLAG_TRY_HARD, etharp_request(), etharp_send_ip(), ETHARP_SET_HINT, ETHARP_STATE_EMPTY, ETHARP_STATE_PENDING, ETHARP_STATE_STABLE, ETHARP_STATS_INC, netif::hwaddr, if(), ip_addr_isany, ip_addr_isbroadcast, ip_addr_ismulticast, pbuf::len, LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, memp_malloc(), pbuf::next, NULL, pbuf_alloc(), pbuf_copy(), pbuf_free(), PBUF_RAM, PBUF_RAW, pbuf_ref(), PBUF_ROM, etharp_entry::q, S16_F, etharp_entry::state, pbuf::tot_len, and pbuf::type.
Referenced by etharp_output().
|
static |
Send a raw ARP packet (opcode and all addresses can be modified)
netif | the lwip network interface on which to send the ARP packet |
ethsrc_addr | the source MAC address for the ethernet header |
ethdst_addr | the destination MAC address for the ethernet header |
hwsrc_addr | the source MAC address for the ARP protocol header |
ipsrc_addr | the source IP address for the ARP protocol header |
hwdst_addr | the destination MAC address for the ARP protocol header |
ipdst_addr | the destination IP address for the ARP protocol header |
opcode | the type of the ARP packet |
References ERR_MEM, ERR_OK, ETHADDR16_COPY, ETHARP_DEBUG, ETHARP_HWADDR_LEN, ETHARP_STATS_INC, ETHTYPE_ARP, ETHTYPE_IP, htons, netif::hwaddr_len, HWTYPE_ETHERNET, ip_addr_islinklocal, IPADDR2_COPY, pbuf::len, netif::linkoutput, LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_TRACE, LWIP_DEBUGF, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_RAM, PBUF_RAW, PP_HTONS, SIZEOF_ETH_HDR, and SIZEOF_ETHARP_PACKET.
Referenced by etharp_request().
Send an ARP request packet asking for ipaddr.
netif | the lwip network interface on which to send the request |
ipaddr | the IP address for which to ask |
References ARP_REQUEST, ETHARP_DEBUG, etharp_raw(), netif::hwaddr, netif::ip_addr, LWIP_DBG_TRACE, and LWIP_DEBUGF.
Referenced by etharp_output_to_arp_index(), and etharp_query().
|
static |
Send an IP packet on the network using netif->linkoutput The ethernet header is filled in before sending.
netif the lwIP network interface on which to send the packet p the packet to send, p->payload pointing to the (uninitialized) ethernet header src the source MAC address to be copied into the ethernet header dst the destination MAC address to be copied into the ethernet header
References ETHADDR16_COPY, ETHADDR32_COPY, ETHARP_DEBUG, ETHARP_HWADDR_LEN, ETHTYPE_IP, netif::hwaddr_len, netif::linkoutput, LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, pbuf::payload, and PP_HTONS.
Referenced by etharp_output(), etharp_output_to_arp_index(), etharp_query(), and etharp_update_arp_entry().
Clears expired entries in the ARP table.
This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), in order to expire entries in the ARP table.
References ARP_MAXAGE, ARP_MAXPENDING, arp_table, etharp_entry::ctime, ETHARP_DEBUG, etharp_free_entry(), ETHARP_STATE_EMPTY, ETHARP_STATE_PENDING, ETHARP_STATE_STABLE, ETHARP_STATE_STABLE_REREQUESTING, LWIP_DEBUGF, etharp_entry::state, and U16_F.
Referenced by arp_timer().
|
static |
Update (or insert) a IP/MAC address pair in the ARP cache.
If a pending entry is resolved, any queued packets will be sent at this point.
netif | netif related to this entry (used for NETIF_ADDRHINT) |
ipaddr | IP address of the inserted ARP entry. |
ethaddr | Ethernet address of the inserted ARP entry. |
flags |
References arp_table, etharp_entry::ctime, ERR_ARG, ERR_OK, ERR_RTE, ETHADDR32_COPY, ETHARP_DEBUG, etharp_find_entry(), ETHARP_FLAG_FIND_ONLY, ETHARP_FLAG_TRY_HARD, etharp_free_entry(), ETHARP_HWADDR_LEN, etharp_send_ip(), ETHARP_STATE_STABLE, netif::hwaddr, netif::hwaddr_len, ip4_addr1_16, ip4_addr2_16, ip4_addr3_16, ip4_addr4_16, ip_addr_isany, ip_addr_isbroadcast, ip_addr_ismulticast, ip_route(), LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, memp_free(), etharp_entry::netif, pbuf::next, NULL, pbuf_free(), etharp_entry::q, S16_F, snmp_insert_arpidx_tree, etharp_entry::state, netif::state, U16_F, and X16_F.
Referenced by etharp_arp_input().
Process received ethernet frames.
Using this function instead of directly calling ip_input and passing ARP frames through etharp in ethernetif_input, the ARP cache is protected from concurrent access.
p | the recevied packet, p->payload pointing to the ethernet header |
netif | the network interface on which the packet was received |
References ERR_OK, eth_addr_cmp, etharp_arp_input(), ETHARP_DEBUG, ETHARP_STATS_INC, ETHTYPE_ARP, ETHTYPE_IP, ETHTYPE_PPPOE, ETHTYPE_PPPOEDISC, ETHTYPE_VLAN, pbuf::flags, netif::flags, htons, netif::hwaddr, ip_input(), pbuf::len, LL_MULTICAST_ADDR_0, LL_MULTICAST_ADDR_1, LL_MULTICAST_ADDR_2, LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, NETIF_FLAG_ETHARP, pbuf::payload, PBUF_FLAG_LLBCAST, PBUF_FLAG_LLMCAST, pbuf_free(), pbuf_header(), PP_HTONS, SIZEOF_ETH_HDR, and X8_F.
Referenced by ethernet_configure_interface().
|
static |
|
static |
Referenced by etharp_output().
struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}} |
struct eth_addr ethzero = {{0,0,0,0,0,0}} |
Referenced by etharp_free_entry().