RetroArch
Classes | Macros | Enumerations | Functions | Variables
etharp.c File Reference
#include "lwip/opt.h"
#include "lwip/inet.h"
#include "netif/etharp.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
Include dependency graph for etharp.c:

Classes

struct  etharp_entry
 

Macros

#define ARP_MAXAGE   240
 
#define ARP_MAXPENDING   2
 
#define HWTYPE_ETHERNET   1
 
#define ARP_REQUEST   1
 
#define ARP_REPLY   2
 
#define ARPH_HWLEN(hdr)   (ntohs((hdr)->_hwlen_protolen) >> 8)
 
#define ARPH_PROTOLEN(hdr)   (ntohs((hdr)->_hwlen_protolen) & 0xff)
 
#define ARPH_HWLEN_SET(hdr, len)   (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))
 
#define ARPH_PROTOLEN_SET(hdr, len)   (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))
 
#define ETHARP_TRY_HARD   1
 

Enumerations

enum  etharp_state { ETHARP_STATE_EMPTY, ETHARP_STATE_PENDING, ETHARP_STATE_STABLE, ETHARP_STATE_EXPIRED }
 

Functions

static s8_t find_entry (struct ip_addr *ipaddr, u8_t flags)
 
static err_t update_arp_entry (struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
 
void etharp_init (void)
 
void etharp_tmr (void)
 
void etharp_ip_input (struct netif *netif, struct pbuf *p)
 
void etharp_arp_input (struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
 
err_t etharp_output (struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
 
err_t etharp_query (struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
 
err_t etharp_request (struct netif *netif, struct ip_addr *ipaddr)
 

Variables

static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}
 
static struct etharp_entry arp_table [ARP_TABLE_SIZE]
 

Detailed Description

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_query(our_netif, its_ip_addr, NULL) upon address change.

Macro Definition Documentation

◆ ARP_MAXAGE

#define ARP_MAXAGE   240

the time an ARP entry stays valid after its last update, (240 * 5) seconds = 20 minutes.

◆ ARP_MAXPENDING

#define ARP_MAXPENDING   2

the time an ARP entry stays pending after first request, (2 * 5) seconds = 10 seconds.

◆ ARP_REPLY

#define ARP_REPLY   2

◆ ARP_REQUEST

#define ARP_REQUEST   1

ARP message types

◆ ARPH_HWLEN

#define ARPH_HWLEN (   hdr)    (ntohs((hdr)->_hwlen_protolen) >> 8)

◆ ARPH_HWLEN_SET

#define ARPH_HWLEN_SET (   hdr,
  len 
)    (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))

◆ ARPH_PROTOLEN

#define ARPH_PROTOLEN (   hdr)    (ntohs((hdr)->_hwlen_protolen) & 0xff)

◆ ARPH_PROTOLEN_SET

#define ARPH_PROTOLEN_SET (   hdr,
  len 
)    (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))

◆ ETHARP_TRY_HARD

#define ETHARP_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).

◆ HWTYPE_ETHERNET

#define HWTYPE_ETHERNET   1

Enumeration Type Documentation

◆ etharp_state

Enumerator
ETHARP_STATE_EMPTY 
ETHARP_STATE_PENDING 
ETHARP_STATE_STABLE 
ETHARP_STATE_EXPIRED 

Function Documentation

◆ etharp_arp_input()

void etharp_arp_input ( struct netif netif,
struct eth_addr ethaddr,
struct pbuf p 
)

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.

Parameters
netifThe lwIP network interface on which the ARP packet pbuf arrived.
pbufThe ARP packet that arrived on netif. Is freed by this function.
ethaddrEthernet address of netif.
Returns
NULL
See also
pbuf_free()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ etharp_init()

void etharp_init ( void  )

Initializes ARP module.

Here is the caller graph for this function:

◆ etharp_ip_input()

void etharp_ip_input ( struct netif netif,
struct pbuf p 
)

Updates the ARP table using the given IP packet.

Uses the incoming IP packet's source address to update the ARP cache for the local network. The function does not alter or free the packet. This function must be called before the packet p is passed to the IP layer.

Parameters
netifThe lwIP network interface on which the IP packet pbuf arrived.
pbufThe IP packet that arrived on netif.
Returns
NULL
See also
pbuf_free()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ etharp_output()

err_t etharp_output ( struct netif netif,
struct ip_addr ipaddr,
struct pbuf q 
)

Resolve and fill-in Ethernet address header for outgoing 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.

Parameters
netifThe lwIP network interface which the IP packet will be sent on.
ipaddrThe IP address of the packet destination.
pbufThe pbuf(s) containing the IP packet to be sent.
Returns
  • ERR_RTE No route to destination (no gateway to external networks), or the return type of either etharp_query() or netif->linkoutput().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ etharp_query()

err_t etharp_query ( struct netif netif,
struct ip_addr ipaddr,
struct pbuf q 
)

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.

Parameters
netifThe lwIP network interface on which ipaddr must be queried for.
ipaddrThe IP address to be resolved.
qIf non-NULL, a pbuf that must be delivered to the IP address. q is not freed by this function.
Returns
  • ERR_BUF Could not make room for Ethernet header.
  • ERR_MEM Hardware address unknown, and no more ARP entries available to query for address or queue the packet.
  • ERR_MEM Could not queue packet due to memory shortage.
  • ERR_RTE No route to destination (no gateway to external networks).
  • ERR_ARG Non-unicast address given, those will not appear in ARP cache.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ etharp_request()

err_t etharp_request ( struct netif netif,
struct ip_addr ipaddr 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ etharp_tmr()

void etharp_tmr ( void  )

Clears expired entries in the ARP table.

This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds), in order to expire entries in the ARP table.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_entry()

static s8_t find_entry ( struct ip_addr ipaddr,
u8_t  flags 
)
static

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_TRY_HARD flag is set, recycle old entries. Heuristic choose the least important entry for recycling.

Parameters
ipaddrIP address to find in ARP cache, or to add if not found.
flags
  • ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of active (stable or pending) entries.
Returns
The ARP entry index that matched or is created, ERR_MEM if no entry is found or could be recycled.

a) do a search through the cache, remember candidates b) select candidate entry c) create new entry

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_arp_entry()

static err_t update_arp_entry ( struct netif netif,
struct ip_addr ipaddr,
struct eth_addr ethaddr,
u8_t  flags 
)
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.

Parameters
ipaddrIP address of the inserted ARP entry.
ethaddrEthernet address of the inserted ARP entry.
flagsDefines behaviour:
  • ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified, only existing ARP entries will be updated.
Returns
  • ERR_OK Succesfully updated ARP cache.
  • ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.
  • ERR_ARG Non-unicast address given, those will not appear in ARP cache.
See also
pbuf_free()
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ arp_table

struct etharp_entry arp_table[ARP_TABLE_SIZE]
static

◆ ethbroadcast

const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}
static