/*------------------------------------------------------------------------ * arptimer - Iterate through ARP cache, aging (possibly removing) entries *------------------------------------------------------------------------ * gran - time since last iteration */ void arptimer(int gran) { struct arpentry *pae; STATWORD ps; int i; disable(ps); /* mutex */ for (i=0; i<ARP_TSIZE; ++i) { if ((pae = &arptable[i])->ae_state == AS_FREE) continue; if (pae->ae_ttl == ARP_INF) continue; /* don't time out permanent entry */ if ((pae->ae_ttl -= gran) <= 0) if (pae->ae_state == AS_RESOLVED) pae->ae_state = AS_FREE; else if (++pae->ae_attempts > ARP_MAXRETRY) { pae->ae_state = AS_FREE; arpdq(pae); } else { pae->ae_ttl = ARP_RESEND; arpsend(pae); } } restore(ps); }
/*------------------------------------------------------------------------ * arpalloc - allocate an entry in the ARP table * N.B. Assumes interrupts DISABLED *------------------------------------------------------------------------ */ struct arpentry *arpalloc() { static int aenext = 0; struct arpentry *pae; int i; for (i=0; i<ARP_TSIZE; ++i) { if (arptable[aenext].ae_state == AS_FREE) break; aenext = (aenext + 1) % ARP_TSIZE; } pae = & arptable[aenext]; aenext = (aenext + 1) % ARP_TSIZE; if (pae->ae_state == AS_PENDING && pae->ae_queue >= 0) arpdq(pae); pae->ae_state = AS_PENDING; return pae; }