1 / 18

Address Discovery and Binding (ARP)

Address Discovery and Binding (ARP). ARP binds high-level IP addresses to low-level physical addresses. Address binding software forms a boundary between higher layers of protocol software, which use IP addresses, and lower layers of device driver software, which use hardware addresses.

cheryl
Download Presentation

Address Discovery and Binding (ARP)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Address Discovery and Binding (ARP) ARP binds high-level IP addresses to low-level physical addresses. Address binding software forms a boundary between higher layers of protocol software, which use IP addresses, and lower layers of device driver software, which use hardware addresses. ARP is considered residing in the network interface layer. UDP TCP IP IGMP ICMP ARP Network Interface RARP

  2. Organization of ARP Software Conceptually, ARP software can be divided into three parts:. - Output Module: bind IP address to H/W address when sending a datagram. Network interface calls this module to bind IP address to MAC address - Input Module: handle ARP packets that arrive from network; it updates the ARP cache by adding new bindings -Cache manager: implement cache replacement policy; it examines entries in the cache and removes them when they reach a specified age.

  3. ARP Design Rules - Single Cache: - A single physical cache holds entries for all networks. (all NICs share one cache) - Each entry contains a field that specifies the network from which the binding was obtained. - Global Replacement Policy: - An existing item in the cache can be removed, independent of whether the new binding comes from the same network. - Cache Timeout and Removal: - When an entry is added to the cache, ARP initializes time-to-live field on the entry. - Cache manager discards the entry when the value reaches zero. - Multiple Queues of Waiting Packets: - Each entry in the ARP cache has a queue of outgoing packets destined for the address in that entry. - When an ARP reply arrives that contains the needed hardware address, the S/W removes packets from the queue and transmits them. - Exclusive Access: - Interrupt is disabled to guarantee that only one process accesses the ARP cache at any time; avoids context switching

  4. Network Byte Order - Big Endian: lowest memory address holds high-order byte of the integer -Little Endian: lowest memory address contains low-order byte of the integer - Internet standard byte order: integers are sent most significant byte first (Big Endian style). (p.69, Vol.1) 0x128c n n n+1 n+1 0x12 0x8c 0x8c 0x12 Little endian Big endian

  5. H/W Type Protocol Type HLen. PLen. ARP Operation Sender Hardware Address Sender Protocol Address Target Hardware Address Target Protocol Address ARP Packet Format /* arp.h - SHA, SPA, THA, TPA */ /* Internet Address Resolution Protocol (see RFCs 826, 920) */ #define AR_HARDWARE 1 /* Ethernet hardware type code */ /* Definitions of codes used in operation field of ARP packet */ #define AR_REQUEST 1 /* ARP request to resolve address*/ #define AR_REPLY 2 /* reply to a resolve request */ #define RA_REQUEST 3 /* reverse ARP request (RARP packets)*/ #define RA_REPLY 4 /* reply to a reverse request (RARP ")*/ struct arp { u_short ar_hwtype; /* hardware type */ u_short ar_prtype; /* protocol type */ u_char ar_hwlen; /* hardware address length */ u_char ar_prlen; /* protocol address length */ u_short ar_op; /* ARP operation (see list above) */ u_char ar_addrs[1];/* sender and target hw & proto addrs */ /* char ar_sha[???]; - sender's physical hardware address */ /* char ar_spa[???]; - sender's protocol address (IP addr.) */ /* char ar_tha[???]; - target's physical hardware address */ /* char ar_tpa[???]; - target's protocol address (IP) */ }; #define SHA(p) (&p->ar_addrs[0]) #define SPA(p) (&p->ar_addrs[p->ar_hwlen]) #define THA(p) (&p->ar_addrs[p->ar_hwlen + p->ar_prlen]) #define TPA(p) (&p->ar_addrs[(p->ar_hwlen*2) + p->ar_prlen])

  6. prlen state hwtype prtype hwlen *pni queue attempts ttl H/W Addr Protocol Addr state *pni queue ttl Protocol Addr H/W Addr state *pni queue ttl Protocol Addr H/W Addr struct arpentry { /* format of entry in ARP cache*/ short ae_state;/* state of this entry (see below)*/ short ae_hwtype; /* hardware type */ short ae_prtype; /* protocol type */ char ae_hwlen; /* hardware address length*/ char ae_prlen; /* protocol address length*/ struct netif *ae_pni; /* pointer to interface structure*/ int ae_queue; /* queue of packets for this address*/ int ae_attempts; /* number of retries so far */ int ae_ttl; /* time to live */ u_char ae_hwa[MAXHWALEN]; /* Hardware address*/ u_char ae_pra[MAXPRALEN]; /* Protocol address */ }; #define AS_FREE 0 /* Entry is unused (initial value)*/ #define AS_PENDING 1 /* Entry is used but incomplete*/ #define AS_RESOLVED 2 /* Entry has been resolved*/ /* RARP variables */ extern int rarppid; /* id of process waiting for RARP reply*/ extern int rarpsem; /* semaphore for access to RARP service*/ /* ARP variables */ extern struct arpentry arptable[ARP_TSIZE]; /* ARP function declarations */ int arp_in(struct netif *, struct ep *); struct arpentry *arpfind(u_char *, u_short, struct netif *); struct arpentry *arpadd(struct netif *, struct arp *); ARP Cache Table

  7. ARP Input Processing Struct arp *parp=(struct arp *)pep->ep_data; arp_in( ) { translate the big endian to little endian; if (different htype and ptype between ARP and nif) {freebuf( ); return OK;} pae=arpfind(using SA-IP); if(arp-table have the entry of the SA-IP of incoming ARP data} {update entry; update entry timer;} if (ARP.target IP =! My IP) freebuf(pep); return(ok); if(pae ==0) arpadd( ); if(pae->state == AS_PENDING) {pae->state = AS_RESOLVED; arpqsend(); } if(receive an ARP Request) { to form a ARP Reply packet; send an ARP Reply; } } #if BYTE_ORDER == LITTLE_ENDIAN #define hs2net(x) (unsigned) ((((x)>>8) &0xff) | (((x) & 0xff)<<8)) #define net2hs(x) hs2net(x) #define hl2net(x) (((((x)& 0xff)<<24) | ((x)>>24) & 0xff) | \ (((x) & 0xff0000)>>8) | (((x) & 0xff00)<<8)) #define net2hl(x) hl2net(x) #endif #if BYTE_ORDER == BIG_ENDIAN #define hs2net(x) (x) #define net2hs(x) (x) #define hl2net(x) (x) #define net2hl(x) (x) #endif

  8. int arp_in(struct netif *pni, struct ep *pep) { struct arp *parp = (struct arp *)pep->ep_data; struct arpentry *pae; int arplen; parp->ar_hwtype = net2hs(parp->ar_hwtype); parp->ar_prtype = net2hs(parp->ar_prtype); parp->ar_op = net2hs(parp->ar_op); if (parp->ar_hwtype != pni->ni_hwtype || parp->ar_prtype != EPT_IP) { freebuf(pep); return OK; } if (pae = arpfind(SPA(parp), parp->ar_prtype, pni)) { memcpy(pae->ae_hwa, SHA(parp), pae->ae_hwlen); pae->ae_ttl = ARP_TIMEOUT; } if (!memcmp(TPA(parp), &pni->ni_ip, IP_ALEN)) { freebuf(pep); return OK; } Source Protocol Address in ARP format

  9. if (pae == 0) pae = arpadd(pni, parp); if (pae->ae_state == AS_PENDING) { pae->ae_state = AS_RESOLVED; arpqsend(pae); //send out the pending packet for resolving the MAC address } if (parp->ar_op == AR_REQUEST) { parp->ar_op = AR_REPLY; memcpy(TPA(parp), SPA(parp), parp->ar_prlen); memcpy(THA(parp), SHA(parp), parp->ar_hwlen); memcpy(pep->ep_dst, THA(parp), EP_ALEN); memcpy(SHA(parp), pni->ni_hwa.ha_addr, pni->ni_hwa.ha_len); memcpy(SPA(parp), &pni->ni_ip, IP_ALEN); parp->ar_hwtype = hs2net(parp->ar_hwtype); parp->ar_prtype = hs2net(parp->ar_prtype); parp->ar_op = hs2net(parp->ar_op); arplen = ARP_HLEN + 2*(parp->ar_prlen + parp->ar_hwlen); write(pni->ni_dev, pep, arplen); } else freebuf(pep); return OK; } Write to network interface

  10. /* arpfind.c - arpfind */ struct arpentry * arpfind(u_char *pra, u_short prtype, struct netif *pni) { struct arpentry *pae; int i; for (i=0; i<ARP_TSIZE; ++i) { pae = &arptable[i]; if (pae->ae_state == AS_FREE) continue; if (pae->ae_prtype == prtype && pae->ae_pni == pni && BLKEQU(pae->ae_pra, pra, pae->ae_prlen)) return pae; } return 0; }

  11. /* arpsend.c - arpsend */ int arpsend(struct arpentry *pae) { struct netif *pni = pae->ae_pni; struct ep *pep; struct arp *parp; int arplen; pep = (struct ep *) getbuf(Net.netpool); if ((int)pep == SYSERR) return SYSERR; memcpy(pep->ep_dst, pni->ni_hwb.ha_addr, pae->ae_hwlen); pep->ep_type = EPT_ARP; pep->ep_order = EPO_NET; parp = (struct arp *) pep->ep_data; parp->ar_hwtype = hs2net(pae->ae_hwtype); parp->ar_prtype = hs2net(pae->ae_prtype); parp->ar_hwlen = pae->ae_hwlen; parp->ar_prlen = pae->ae_prlen; parp->ar_op = hs2net(AR_REQUEST); memcpy(SHA(parp), pni->ni_hwa.ha_addr, pae->ae_hwlen); memcpy(SPA(parp), &pni->ni_ip, pae->ae_prlen); memset(THA(parp), 0, pae->ae_hwlen); memcpy(TPA(parp), pae->ae_pra, pae->ae_prlen); arplen = ARP_HLEN + 2*(parp->ar_hwlen + parp->ar_prlen); write(pni->ni_dev, pep, EP_HLEN+arplen); return OK; }

  12. /* arpadd.c - arpadd */ struct arpentry *arpalloc(void); /*------------------------------------------------------------------------ * arpadd - Add a RESOLVED entry to the ARP cache * N.B. Assumes interrupts disabled *------------------------------------------------------------------------ */ struct arpentry * arpadd(struct netif *pni, struct arp *parp) { struct arpentry *pae; pae = arpalloc(); pae->ae_hwtype = parp->ar_hwtype; pae->ae_prtype = parp->ar_prtype; pae->ae_hwlen = parp->ar_hwlen; pae->ae_prlen = parp->ar_prlen; pae->ae_pni = pni; pae->ae_queue = EMPTY; memcpy(pae->ae_hwa, SHA(parp), parp->ar_hwlen); memcpy(pae->ae_pra, SPA(parp), parp->ar_prlen); pae->ae_ttl = ARP_TIMEOUT; pae->ae_state = AS_RESOLVED; return pae; }

  13. /* arpqsend.c - arpqsend */ int netwrite(struct netif *, struct ep *, unsigned); /*------------------------------------------------------------------------ * arpqsend - write packets queued waiting for an ARP resolution *------------------------------------------------------------------------ */ void arpqsend(struct arpentry *pae) { struct ep *pep; struct netif *pni; if (pae->ae_queue == EMPTY) return; pni = pae->ae_pni; while (pep = (struct ep *)deq(pae->ae_queue)) netwrite(pni, pep, pep->ep_len); freeq(pae->ae_queue); pae->ae_queue = EMPTY; }

  14. If a process (e.g., the IP process) needs to send a datagram but no entry in the ARP cache for DA IP address • Create a new ARP cache entry • Broadcast a ARP request packet • Enqueue the packet awaiting for transmission (wait for DA MAC address)

  15. ARP Output Processing A service for sending out the IP packet netwrite( ) { if (local) return local_out( ); else if (DA_IP is broadcast) { DA_MAC = NIC’s H/W broadcast address ; write ( ); return ok; } disable (ps); pae = arpfind(); if (pae && AS_RESOLVED) { DA_MAC = ARP_entry’s_H/W address; restore (ps); return write( ); } if (DA-IP is classD) { restore (ps); return SYSERR; } if (pae == 0) { arpalloc ( ); arpsend ( ); } if (ARP queue is empty) generate a new pending queue; if (enq(pae->ae_queue, pep, 0) < 0) freebuf(pep); restore (ps); return OK; } Entry the critical section : ARP Table The pending packet is stored in the queue for waiting DA MAC address resolved

  16. 4.7 ARP cache Management 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; } Round robin to find a free cache entry or replacement Do the cache replacement policy Only pending state has waiting packets

  17. Periodic cache maintenance 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); }

  18. Deallocating queued packets void arpdq(struct arpentry *pae) { struct ep *pep; struct ip *pip; if (pae->ae_queue < 0) /* nothing to do */ return; while (pep = (struct ep *)deq(pae->ae_queue)) { if (gateway && pae->ae_prtype == EPT_IP) { pip = (struct ip *)pep->ep_data; icmp(ICT_DESTUR, ICC_HOSTUR, pip->ip_src, pep, 0); } else freebuf(pep); } freeq(pae->ae_queue); pae->ae_queue = EMPTY; }

More Related