00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #include <ubixos/types.h>
00038 #include <lib/kprintf.h>
00039 
00040 #include "net/debug.h"
00041 #include "net/ipv4/inet.h"
00042 #include "netif/arp.h"
00043 #include "net/ipv4/ip.h"
00044 
00045 
00046 #define ARP_MAXAGE 2  
00047 
00048 #define HWTYPE_ETHERNET 1
00049 
00050 #define ARP_REQUEST 1
00051 #define ARP_REPLY 2
00052 
00053 
00054 PACK_STRUCT_BEGIN
00055 struct arp_hdr {
00056   PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
00057   PACK_STRUCT_FIELD(uInt16 hwtype);
00058   PACK_STRUCT_FIELD(uInt16 proto);
00059   PACK_STRUCT_FIELD(uInt16 _hwlen_protolen);
00060   PACK_STRUCT_FIELD(uInt16 opcode);
00061   PACK_STRUCT_FIELD(struct eth_addr shwaddr);
00062   PACK_STRUCT_FIELD(struct ip_addr sipaddr);
00063   PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
00064   PACK_STRUCT_FIELD(struct ip_addr dipaddr);
00065 } PACK_STRUCT_STRUCT;
00066 PACK_STRUCT_END
00067 
00068 #define ARPH_HWLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) >> 8)
00069 #define ARPH_PROTOLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) & 0xff)
00070 
00071 
00072 #define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS(ARPH_PROTOLEN(hdr) | ((len) << 8))
00073 #define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS((len) | (ARPH_HWLEN(hdr) << 8))
00074 
00075 PACK_STRUCT_BEGIN
00076 struct ethip_hdr {
00077   PACK_STRUCT_FIELD(struct eth_hdr eth);
00078   PACK_STRUCT_FIELD(struct ip_hdr ip);
00079 };
00080 PACK_STRUCT_END
00081 
00082 struct arp_entry {
00083   struct ip_addr ipaddr;
00084   struct eth_addr ethaddr;
00085   uInt8 ctime;
00086 };
00087 
00088 static struct arp_entry arp_table[ARP_TABLE_SIZE];
00089 static uInt8 ctime;
00090 
00091 
00092 void
00093 arp_init(void)
00094 {
00095   uInt8 i;
00096   
00097   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00098     ip_addr_set(&(arp_table[i].ipaddr),
00099                 IP_ADDR_ANY);
00100   }
00101 }
00102 
00103 void
00104 arp_tmr(void)
00105 {
00106   uInt8 i;
00107   
00108   ++ctime;
00109   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00110     if(!ip_addr_isany(&arp_table[i].ipaddr) &&       
00111        ctime - arp_table[i].ctime >= ARP_MAXAGE) {
00112       DEBUGF(ARP_DEBUG, ("arp_timer: expired entry %d.\n", i));
00113       ip_addr_set(&(arp_table[i].ipaddr),
00114                   IP_ADDR_ANY);
00115     }
00116   }  
00117 }
00118 
00119 static void
00120 add_arp_entry(struct ip_addr *ipaddr, struct eth_addr *ethaddr)
00121 {
00122   uInt8 i, j, k;
00123   uInt8 maxtime;
00124   
00125   
00126 
00127 
00128   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00129     
00130     
00131     if(!ip_addr_isany(&arp_table[i].ipaddr)) {
00132       
00133 
00134       if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00135         
00136         for(k = 0; k < 6; ++k) {
00137           arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00138         }
00139         arp_table[i].ctime = ctime;
00140         return;
00141       }
00142     }
00143   }
00144 
00145   
00146 
00147 
00148   
00149   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00150     if(ip_addr_isany(&arp_table[i].ipaddr)) {
00151       break;
00152     }
00153   }
00154 
00155   
00156 
00157   if(i == ARP_TABLE_SIZE) {
00158     maxtime = 0;
00159     j = 0;
00160     for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00161       if(ctime - arp_table[i].ctime > maxtime) {
00162         maxtime = ctime - arp_table[i].ctime;
00163         j = i;
00164       }
00165     }
00166     i = j;
00167   }
00168 
00169   
00170 
00171   ip_addr_set(&arp_table[i].ipaddr, ipaddr);
00172   for(k = 0; k < 6; ++k) {
00173     arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00174   }
00175   arp_table[i].ctime = ctime;
00176   return;
00177 
00178 }
00179 
00180 void
00181 arp_ip_input(struct netif *netif, struct pbuf *p)
00182 {
00183   struct ethip_hdr *hdr;
00184   
00185   hdr = p->payload;
00186   
00187   
00188 
00189   if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
00190     return;
00191   }
00192   DEBUGF(ARP_DEBUG, ("arp_ip_input: updating ARP table.\n"));
00193   add_arp_entry(&(hdr->ip.src), &(hdr->eth.src));
00194 }
00195 
00196 struct pbuf *
00197 arp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
00198 {
00199   struct arp_hdr *hdr;
00200   uInt8 i;
00201   
00202   if(p->tot_len < sizeof(struct arp_hdr)) {
00203     kprintf("arp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct arp_hdr));
00204     pbuf_free(p);
00205     return NULL;
00206   }
00207 
00208   hdr = p->payload;
00209   
00210   switch(htons(hdr->opcode)) {
00211   case ARP_REQUEST:
00212     
00213 
00214     if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00215       hdr->opcode = htons(ARP_REPLY);
00216 
00217       ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
00218       ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00219 
00220       for(i = 0; i < 6; ++i) {
00221         hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
00222         hdr->shwaddr.addr[i] = ethaddr->addr[i];
00223         hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
00224         hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00225       }
00226 
00227       hdr->hwtype = htons(HWTYPE_ETHERNET);
00228       ARPH_HWLEN_SET(hdr, 6);
00229       
00230       hdr->proto = htons(ETHTYPE_IP);
00231       ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));      
00232       
00233       hdr->ethhdr.type = htons(ETHTYPE_ARP);      
00234       return p;
00235     }
00236     break;
00237   case ARP_REPLY:    
00238     
00239     if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00240       add_arp_entry(&(hdr->sipaddr), &(hdr->shwaddr));
00241     }
00242     break;
00243   default:
00244     kprintf("arp_arp_input: unknown type %d\n", htons(hdr->opcode));
00245     break;
00246   }
00247 
00248   pbuf_free(p);
00249   return NULL;
00250 }
00251 
00252 struct eth_addr *
00253 arp_lookup(struct ip_addr *ipaddr)
00254 {
00255   uInt8 i;
00256   
00257   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00258     if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00259       return &arp_table[i].ethaddr;
00260     }
00261   }
00262   return NULL;  
00263 }
00264 
00265 struct pbuf *
00266 arp_query(struct netif *netif, struct eth_addr *ethaddr, struct ip_addr *ipaddr)
00267 {
00268   struct arp_hdr *hdr;
00269   struct pbuf *p;
00270   uInt8 i;
00271 
00272   p = pbuf_alloc(PBUF_LINK, sizeof(struct arp_hdr), PBUF_RAM);
00273   if(p == NULL) {
00274     return NULL;
00275   }
00276 
00277   hdr = p->payload;
00278   
00279   hdr->opcode = htons(ARP_REQUEST);
00280 
00281   for(i = 0; i < 6; ++i) {
00282     hdr->dhwaddr.addr[i] = 0x00;
00283     hdr->shwaddr.addr[i] = ethaddr->addr[i];
00284   }
00285   
00286   ip_addr_set(&(hdr->dipaddr), ipaddr);
00287   ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00288 
00289   hdr->hwtype = htons(HWTYPE_ETHERNET);
00290   ARPH_HWLEN_SET(hdr, 6);
00291 
00292   hdr->proto = htons(ETHTYPE_IP);
00293   ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00294 
00295   for(i = 0; i < 6; ++i) {
00296     hdr->ethhdr.dest.addr[i] = 0xff;
00297     hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00298   }
00299   
00300   hdr->ethhdr.type = htons(ETHTYPE_ARP);      
00301   return p;
00302 }
00303 
00304 
00305 
00306 
00307