00001 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 #include "uip_arp.h"
00063 
00064 #include <string.h>
00065 
00066 #ifdef __ICCARM__
00067         #pragma pack(1)
00068 #endif
00069 
00070 struct arp_hdr {
00071   struct uip_eth_hdr ethhdr;
00072   u16_t hwtype;
00073   u16_t protocol;
00074   u8_t hwlen;
00075   u8_t protolen;
00076   u16_t opcode;
00077   struct uip_eth_addr shwaddr;
00078   u16_t sipaddr[2];
00079   struct uip_eth_addr dhwaddr;
00080   u16_t dipaddr[2];
00081 } PACK_STRUCT_END;
00082 
00083 #ifdef __ICCARM__
00084         #pragma pack()
00085 #endif
00086 
00087 #ifdef __ICCARM__
00088         #pragma pack(1)
00089 #endif
00090 
00091 struct ethip_hdr {
00092   struct uip_eth_hdr ethhdr;
00093   
00094   u8_t vhl,
00095     tos,
00096     len[2],
00097     ipid[2],
00098     ipoffset[2],
00099     ttl,
00100     proto;
00101   u16_t ipchksum;
00102   u16_t srcipaddr[2],
00103     destipaddr[2];
00104 } PACK_STRUCT_END;
00105 
00106 #ifdef __ICCARM__
00107         #pragma pack()
00108 #endif
00109 
00110 #define ARP_REQUEST 1
00111 #define ARP_REPLY   2
00112 
00113 #define ARP_HWTYPE_ETH 1
00114 
00115 struct arp_entry {
00116   u16_t ipaddr[2];
00117   struct uip_eth_addr ethaddr;
00118   u8_t time;
00119 };
00120 
00121 static const struct uip_eth_addr broadcast_ethaddr =
00122   {{0xff,0xff,0xff,0xff,0xff,0xff}};
00123 static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
00124 
00125 static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
00126 static u16_t ipaddr[2];
00127 static u8_t i, c;
00128 
00129 static u8_t arptime;
00130 static u8_t tmpage;
00131 
00132 #define BUF   ((struct arp_hdr *)&uip_buf[0])
00133 #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
00134 
00139 
00140 void
00141 uip_arp_init(void)
00142 {
00143   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00144     memset(arp_table[i].ipaddr, 0, 4);
00145   }
00146 }
00147 
00156 
00157 void
00158 uip_arp_timer(void)
00159 {
00160   struct arp_entry *tabptr;
00161 
00162   ++arptime;
00163   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00164     tabptr = &arp_table[i];
00165     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
00166        arptime - tabptr->time >= UIP_ARP_MAXAGE) {
00167       memset(tabptr->ipaddr, 0, 4);
00168     }
00169   }
00170 
00171 }
00172 
00173 static void
00174 uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
00175 {
00176   register struct arp_entry *tabptr;
00177   
00178 
00179 
00180   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00181 
00182     tabptr = &arp_table[i];
00183     
00184     if(tabptr->ipaddr[0] != 0 &&
00185        tabptr->ipaddr[1] != 0) {
00186 
00187       
00188 
00189       if(ipaddr[0] == tabptr->ipaddr[0] &&
00190          ipaddr[1] == tabptr->ipaddr[1]) {
00191         
00192         
00193         memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
00194         tabptr->time = arptime;
00195 
00196         return;
00197       }
00198     }
00199   }
00200 
00201   
00202 
00203 
00204   
00205   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00206     tabptr = &arp_table[i];
00207     if(tabptr->ipaddr[0] == 0 &&
00208        tabptr->ipaddr[1] == 0) {
00209       break;
00210     }
00211   }
00212 
00213   
00214 
00215   if(i == UIP_ARPTAB_SIZE) {
00216     tmpage = 0;
00217     c = 0;
00218     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00219       tabptr = &arp_table[i];
00220       if(arptime - tabptr->time > tmpage) {
00221         tmpage = arptime - tabptr->time;
00222         c = i;
00223       }
00224     }
00225     i = c;
00226     tabptr = &arp_table[i];
00227   }
00228 
00229   
00230 
00231   memcpy(tabptr->ipaddr, ipaddr, 4);
00232   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
00233   tabptr->time = arptime;
00234 }
00235 
00248 
00249 #if 1
00250 void
00251 uip_arp_ipin(void)
00252 {
00253   uip_len -= sizeof(struct uip_eth_hdr);
00254         
00255   
00256 
00257   if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
00258      (uip_hostaddr[0] & uip_netmask[0])) {
00259     return;
00260   }
00261   if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
00262      (uip_hostaddr[1] & uip_netmask[1])) {
00263     return;
00264   }
00265   uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
00266 
00267   return;
00268 }
00269 #endif 
00270 
00292 
00293 void
00294 uip_arp_arpin(void)
00295 {
00296 
00297   if(uip_len < sizeof(struct arp_hdr)) {
00298     uip_len = 0;
00299     return;
00300   }
00301   uip_len = 0;
00302 
00303   switch(BUF->opcode) {
00304   case HTONS(ARP_REQUEST):
00305     
00306 
00307     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
00308       
00309 
00310 
00311       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
00312 
00313       
00314       BUF->opcode = HTONS(2);
00315 
00316       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
00317       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
00318       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
00319       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
00320 
00321       BUF->dipaddr[0] = BUF->sipaddr[0];
00322       BUF->dipaddr[1] = BUF->sipaddr[1];
00323       BUF->sipaddr[0] = uip_hostaddr[0];
00324       BUF->sipaddr[1] = uip_hostaddr[1];
00325 
00326       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
00327       uip_len = sizeof(struct arp_hdr);
00328     }
00329     break;
00330   case HTONS(ARP_REPLY):
00331     
00332 
00333     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
00334       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
00335     }
00336     break;
00337   }
00338 
00339   return;
00340 }
00341 
00368 
00369 void
00370 uip_arp_out(void)
00371 {
00372   struct arp_entry *tabptr;
00373 
00374   
00375 
00376 
00377 
00378 
00379 
00380 
00381   
00382   if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
00383     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
00384   } else {
00385     
00386     if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
00387       
00388 
00389 
00390       uip_ipaddr_copy(ipaddr, uip_draddr);
00391     } else {
00392       
00393       uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
00394     }
00395 
00396     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
00397       tabptr = &arp_table[i];
00398       if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
00399         break;
00400       }
00401     }
00402 
00403     if(i == UIP_ARPTAB_SIZE) {
00404       
00405 
00406 
00407       memset(BUF->ethhdr.dest.addr, 0xff, 6);
00408       memset(BUF->dhwaddr.addr, 0x00, 6);
00409       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
00410       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
00411 
00412       uip_ipaddr_copy(BUF->dipaddr, ipaddr);
00413       uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
00414       BUF->opcode = HTONS(ARP_REQUEST); 
00415       BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
00416       BUF->protocol = HTONS(UIP_ETHTYPE_IP);
00417       BUF->hwlen = 6;
00418       BUF->protolen = 4;
00419       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
00420 
00421       uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
00422 
00423       uip_len = sizeof(struct arp_hdr);
00424       return;
00425     }
00426 
00427     
00428     memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
00429   }
00430   memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
00431 
00432   IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
00433 
00434   uip_len += sizeof(struct uip_eth_hdr);
00435 }
00436 
00437