text: The system calls procedure arpinit once, at system startup. Arpinit creates rarpsem, the mutual exclusion semaphore used with RARP, and assigns state AS_FREE to all entries in the ARP cache. In addition, arpinit initializes a few data items for the related RARP protocol; these are irrelevant to the code in this chapter. Note that arpinit does not initialize the timer process or set up calls to arptimer. These details are handled separately because our design uses a single timer process for many protocols.
  /* arpinit.c - arpinit */
  #include <conf.h>
  #include <kernel.h>
  #include <proc.h>
  #include <network.h>
  /* * arpinit - initialize data structures for ARP processing
  *
  */
  void arpinit()
  {
  int i;
  rarpsem = screate(1);
  rarppid = BADPID;
  for (i=0; i<ARP_TSIZE; ++i)
  arptable[i].ae_state = AS_FREE;
  I
  int rarpsem;
  int rarppid;
  struct arpentry arptable [ARP_TSIZE] ;
  When building ARP software, the programmer configures the system by choosing values for parameters such as:
  • Size of the ARP cache
  • Timeout interval the sender waits for an ARP response
  • Number of times a sender retries a request
  • Time interval between retries
  • Timeout (time-to-live) for a cache entry
  • Size of packet retransmission queue
  Typical designs use symbolic constants for parameters such as cache size, allowing the system manager to change the configuration for specific installations. For installations in which managers need more control, utility programs can be written that allow a manager to make changes at run time. For example, in some software it is possible for a manager to examine the ARP cache, delete an entry, or change values (e.g., the time-to-live field). However, some parameters cannot be changed easily. For example, many programmers choose between fixed retransmission delays or exponential backoff and embed their choice in the code itself.
  This implementation of ARP uses a single, global cache to hold bindings obtained from all networks. It permits multiple packets to be enqueued waiting for an address to be resolved, and uses an independent timer to age cache entries. Eventually, entries timeout. If the cache is completely full when a new entry must be inserted, an old entry must be discarded. Our design uses a round-robin replacement policy, implemented with a global pointer that moves to the next cache entry each time one is taken. The example code shows the declarations of data structures that comprise the cache and the procedures that operate on them.