Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

arp.c File Reference

#include "lwip/inet.h"
#include "netif/arp.h"
#include "lwip/ip.h"

Include dependency graph for arp.c:

Go to the source code of this file.

Data Structures

struct  arp_entry
struct  arp_hdr
struct  ethip_hdr

Defines

#define ARP_MAXAGE   2
#define HWTYPE_ETHERNET   1
#define ARP_REQUEST   1
#define ARP_REPLY   2
#define htons   HTONS
#define htonl   HTONL
#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))

Functions

u8_t get_u8_t_from_char (char c, int low)
unsigned char get_char_from_u8_t (u8_t value)
void string2mac (struct eth_addr *mac, char *name)
void mac2string (struct eth_addr *mac, char *name)
void arp_init (void)
void arp_tmr (void)
void add_arp_entry (struct ip_addr *ipaddr, struct eth_addr *ethaddr)
void arp_ip_input (struct netif *netif, struct pbuf *p)
pbufarp_arp_input (struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
eth_addrarp_lookup (struct ip_addr *ipaddr)
pbufarp_query (struct netif *netif, struct eth_addr *ethaddr, struct ip_addr *ipaddr)

Variables

PACK_STRUCT_BEGIN struct arp_hdr PACK_STRUCT_STRUCT
arp_entry arp_table [ARP_TABLE_SIZE]
u8_t ctime


Define Documentation

#define ARP_MAXAGE   2
 

Definition at line 50 of file arp.c.

Referenced by arp_tmr(), and etharp_tmr().

#define ARP_REPLY   2
 

Definition at line 55 of file arp.c.

Referenced by arp_arp_input(), and etharp_arp_input().

#define ARP_REQUEST   1
 

Definition at line 54 of file arp.c.

Referenced by arp_arp_input(), arp_query(), etharp_arp_input(), and etharp_query().

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

Definition at line 74 of file arp.c.

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

Definition at line 78 of file arp.c.

Referenced by arp_arp_input(), arp_query(), etharp_arp_input(), and etharp_query().

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

Definition at line 75 of file arp.c.

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

Definition at line 79 of file arp.c.

Referenced by arp_arp_input(), arp_query(), etharp_arp_input(), and etharp_query().

#define htonl   HTONL
 

Definition at line 57 of file arp.c.

#define htons   HTONS
 

Definition at line 56 of file arp.c.

#define HWTYPE_ETHERNET   1
 

Definition at line 52 of file arp.c.

Referenced by arp_arp_input(), arp_query(), etharp_arp_input(), and etharp_query().


Function Documentation

void add_arp_entry struct ip_addr ipaddr,
struct eth_addr ethaddr
[static]
 

Definition at line 181 of file arp.c.

References arp_table, ctime, arp_entry::ctime, arp_entry::ethaddr, ip_addr_cmp, ip_addr_isany, ip_addr_set, ipaddr, and u8_t.

Referenced by arp_arp_input(), and arp_ip_input().

00182 {
00183   u8_t i, j, k;
00184   u8_t maxtime;
00185   
00186   /* Walk through the ARP mapping table and try to find an entry to
00187      update. If none is found, the IP -> MAC address mapping is
00188      inserted in the ARP table. */
00189   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00190     
00191     /* Only check those entries that are actually in use. */
00192     if(!ip_addr_isany(&arp_table[i].ipaddr)) {
00193       /* Check if the source IP address of the incoming packet matches
00194          the IP address in this ARP table entry. */
00195       if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00196         /* An old entry found, update this and return. */
00197         for(k = 0; k < 6; ++k) {
00198           arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00199         }
00200         arp_table[i].ctime = ctime;
00201         return;
00202       }
00203     }
00204   }
00205 
00206   /* If we get here, no existing ARP table entry was found, so we
00207      create one. */
00208 
00209   /* First, we try to find an unused entry in the ARP table. */
00210   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00211     if(ip_addr_isany(&arp_table[i].ipaddr)) {
00212       break;
00213     }
00214   }
00215 
00216   /* If no unused entry is found, we try to find the oldest entry and
00217      throw it away. */
00218   if(i == ARP_TABLE_SIZE) {
00219     maxtime = 0;
00220     j = 0;
00221     for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00222       if(ctime - arp_table[i].ctime > maxtime) {
00223         maxtime = ctime - arp_table[i].ctime;
00224         j = i;
00225       }
00226     }
00227     i = j;
00228   }
00229 
00230   /* Now, i is the ARP table entry which we will fill with the new
00231      information. */
00232   ip_addr_set(&arp_table[i].ipaddr, ipaddr);
00233   for(k = 0; k < 6; ++k) {
00234     arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00235   }
00236   arp_table[i].ctime = ctime;
00237   return;
00238 
00239 }

struct pbuf* arp_arp_input struct netif netif,
struct eth_addr ethaddr,
struct pbuf p
 

Definition at line 257 of file arp.c.

References add_arp_entry(), ARP_REPLY, ARP_REQUEST, ARPH_HWLEN_SET, ARPH_PROTOLEN_SET, ETHTYPE_ARP, ETHTYPE_IP, htons, HWTYPE_ETHERNET, netif::ip_addr, ip_addr_cmp, ip_addr_set, NULL, pbuf::payload, pbuf_free(), pbuf::tot_len, and u8_t.

00258 {
00259   struct arp_hdr *hdr;
00260   u8_t i;
00261   
00262   if(p->tot_len < sizeof(struct arp_hdr)) {
00263 
00264     pbuf_free(p);
00265     return NULL;
00266   }
00267 
00268   hdr = p->payload;
00269   
00270   switch(htons(hdr->opcode)) {
00271   case ARP_REQUEST:
00272     /* ARP request. If it asked for our address, we send out a
00273        reply. */
00274 
00275     if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00276       hdr->opcode = htons(ARP_REPLY);
00277 
00278       ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
00279       ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00280 
00281       for(i = 0; i < 6; ++i) {
00282         hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
00283         hdr->shwaddr.addr[i] = ethaddr->addr[i];
00284         hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
00285         hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00286       }
00287 
00288       hdr->hwtype = htons(HWTYPE_ETHERNET);
00289       ARPH_HWLEN_SET(hdr, 6);
00290       
00291       hdr->proto = htons(ETHTYPE_IP);
00292       ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));      
00293       
00294       hdr->ethhdr.type = htons(ETHTYPE_ARP);      
00295       return p;
00296     }
00297     break;
00298   case ARP_REPLY:    
00299     /* ARP reply. We insert or update the ARP table. */
00300 
00301     if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00302       add_arp_entry(&(hdr->sipaddr), &(hdr->shwaddr));
00303 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
00304       dhcp_arp_reply(&hdr->sipaddr);
00305 #endif      
00306     }
00307     break;
00308   default:
00309 
00310     break;
00311   }
00312 
00313   pbuf_free(p);
00314   return NULL;
00315 }

Here is the call graph for this function:

void arp_init void   ) 
 

Definition at line 155 of file arp.c.

References arp_table, IP_ADDR_ANY, ip_addr_set, ipaddr, and u8_t.

00156 {
00157   u8_t i;
00158   
00159   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00160     ip_addr_set(&(arp_table[i].ipaddr),
00161                 IP_ADDR_ANY);
00162   }
00163 }

void arp_ip_input struct netif netif,
struct pbuf p
 

Definition at line 242 of file arp.c.

References add_arp_entry(), netif::ip_addr, ip_addr_maskcmp, netif::netmask, and pbuf::payload.

00243 {
00244   struct ethip_hdr *hdr;
00245   
00246   hdr = p->payload;
00247   
00248   /* Only insert/update an entry if the source IP address of the
00249      incoming IP packet comes from a host on the local network. */
00250   if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
00251     return;
00252   }
00253   add_arp_entry(&(hdr->ip.src), &(hdr->eth.src));
00254 }

Here is the call graph for this function:

struct eth_addr* arp_lookup struct ip_addr ipaddr  ) 
 

Definition at line 318 of file arp.c.

References arp_table, arp_entry::ethaddr, ip_addr_cmp, ipaddr, NULL, and u8_t.

00319 {
00320   u8_t i;
00321   
00322   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00323     if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00324       return &arp_table[i].ethaddr;
00325     }
00326   }
00327   return NULL;  
00328 }

struct pbuf* arp_query struct netif netif,
struct eth_addr ethaddr,
struct ip_addr ipaddr
 

Definition at line 331 of file arp.c.

References ARP_REQUEST, ARPH_HWLEN_SET, ARPH_PROTOLEN_SET, ETHTYPE_ARP, ETHTYPE_IP, htons, HWTYPE_ETHERNET, netif::ip_addr, ip_addr_set, ipaddr, NULL, pbuf_alloc(), PBUF_LINK, PBUF_RAM, and u8_t.

00332 {
00333   struct arp_hdr *hdr;
00334   struct pbuf *p;
00335   u8_t i;
00336 
00337   p = pbuf_alloc(PBUF_LINK, sizeof(struct arp_hdr), PBUF_RAM);
00338   if(p == NULL) {
00339     return NULL;
00340   }
00341 
00342   hdr = p->payload;
00343   
00344   hdr->opcode = htons(ARP_REQUEST);
00345 
00346   for(i = 0; i < 6; ++i) {
00347     hdr->dhwaddr.addr[i] = 0x00;
00348     hdr->shwaddr.addr[i] = ethaddr->addr[i];
00349   }
00350   
00351   ip_addr_set(&(hdr->dipaddr), ipaddr);
00352   ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00353 
00354   hdr->hwtype = htons(HWTYPE_ETHERNET);
00355   ARPH_HWLEN_SET(hdr, 6);
00356 
00357   hdr->proto = htons(ETHTYPE_IP);
00358   ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00359 
00360   for(i = 0; i < 6; ++i) {
00361     hdr->ethhdr.dest.addr[i] = 0xff;
00362     hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00363   }
00364   
00365   hdr->ethhdr.type = htons(ETHTYPE_ARP);      
00366   return p;
00367 }

Here is the call graph for this function:

void arp_tmr void   ) 
 

Definition at line 166 of file arp.c.

References ARP_MAXAGE, arp_table, arp_entry::ctime, ctime, IP_ADDR_ANY, ip_addr_isany, ip_addr_set, ipaddr, and u8_t.

00167 {
00168   u8_t i;
00169   
00170   ++ctime;
00171   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00172     if(!ip_addr_isany(&arp_table[i].ipaddr) &&       
00173        ctime - arp_table[i].ctime >= ARP_MAXAGE) {
00174       ip_addr_set(&(arp_table[i].ipaddr),
00175                   IP_ADDR_ANY);
00176     }
00177   }  
00178 }

unsigned char get_char_from_u8_t u8_t  value  ) 
 

Definition at line 119 of file arp.c.

References u8_t.

Referenced by mac2string().

00119                                             {
00120   if(value < 10){
00121     return (unsigned char)(value + 48); //48 is the ascii code for '0'
00122   }else{
00123     return (unsigned char)(value + 55); //65 would be the ascii code for 'A'
00124   }
00125 }

u8_t get_u8_t_from_char char  c,
int  low
 

Definition at line 98 of file arp.c.

References u8_t.

Referenced by string2mac().

00098                                        {
00099 
00100   if(low){
00101     /* a-z */
00102     if((c >= 97) && (c <= 122)) return (c-87);
00103     /* A-Z */
00104     else if((c >= 65) && (c <= 90)) return (c-55);
00105     /* 0-9 */
00106     else if((c >= 48) && (c <= 57)) return (c-48);
00107   }else{ /* !low */
00108     /* a-z */
00109     if((c >= 97) && (c <= 122)) return ((c-87)<<4);
00110     /* A-Z */
00111     else if((c >= 65) && (c <= 90)) return ((c-55)<<4);
00112     /* 0-9 */
00113     else if((c >= 48) && (c <= 57)) return ((c-48)<<4);
00114   }
00115   return -1;
00116 }

void mac2string struct eth_addr mac,
char *  name
 

Definition at line 138 of file arp.c.

References get_char_from_u8_t(), name, and u8_t.

00138                                                  {
00139   int i,hop=0;
00140   u8_t aux;
00141 
00142   for(i=0; i<5; i++){
00143     aux = mac->addr[i];
00144     name[hop] = get_char_from_u8_t((aux & 0xf0)>>4);
00145     name[hop+1] = get_char_from_u8_t((aux & 0x0f));
00146     name[hop+2] = 0x3a; //0x3a is the code ascii (in hex) for ':'
00147     hop+=3;
00148   }
00149   name[hop] = get_char_from_u8_t((mac->addr[5] & 0xf0)>>4);
00150   name[hop+1] = get_char_from_u8_t((mac->addr[5] & 0x0f));
00151 }

Here is the call graph for this function:

void string2mac struct eth_addr mac,
char *  name
 

Definition at line 128 of file arp.c.

References get_u8_t_from_char(), and name.

00128                                                  {
00129   int i,hop=0;
00130 
00131   for(i=0; i<6; i++){
00132     mac->addr[i] = get_u8_t_from_char(name[hop],0) + get_u8_t_from_char(name[hop+1],1);
00133     hop+=3;
00134   }
00135 }

Here is the call graph for this function:


Variable Documentation

struct arp_entry arp_table[ARP_TABLE_SIZE] [static]
 

Definition at line 94 of file arp.c.

Referenced by add_arp_entry(), arp_init(), arp_lookup(), and arp_tmr().

u8_t ctime [static]
 

Definition at line 95 of file arp.c.

Referenced by add_arp_entry(), and arp_tmr().

PACK_STRUCT_BEGIN struct arp_hdr PACK_STRUCT_STRUCT
 


Generated on Wed Jan 14 12:59:01 2004 for RTL-lwIP-0.4 by doxygen 1.3.4