123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- #include "uip_arp.h"
- #include <string.h>
- struct arp_hdr {
- struct uip_eth_hdr ethhdr;
- u16_t hwtype;
- u16_t protocol;
- u8_t hwlen;
- u8_t protolen;
- u16_t opcode;
- struct uip_eth_addr shwaddr;
- uip_ipaddr_t sipaddr;
- struct uip_eth_addr dhwaddr;
- uip_ipaddr_t dipaddr;
- };
- struct ethip_hdr {
- struct uip_eth_hdr ethhdr;
-
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
- };
- #define ARP_REQUEST 1
- #define ARP_REPLY 2
- #define ARP_HWTYPE_ETH 1
- struct arp_entry {
- uip_ipaddr_t ipaddr;
- struct uip_eth_addr ethaddr;
- u8_t time;
- };
- static const struct uip_eth_addr broadcast_ethaddr =
- {{0xff,0xff,0xff,0xff,0xff,0xff}};
- static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
- static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
- static uip_ipaddr_t ipaddr;
- static u8_t i, c;
- static u8_t arptime;
- static u8_t tmpage;
- #define BUF ((struct arp_hdr *)&uip_buf[0])
- #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
- #define DEBUG 0
- #if DEBUG
- #include <stdio.h>
- #define PRINTF(...) printf(__VA_ARGS__)
- #else
- #define PRINTF(...)
- #endif
- void
- uip_arp_init(void)
- {
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- memset(&arp_table[i].ipaddr, 0, 4);
- }
- }
- void
- uip_arp_timer(void)
- {
- struct arp_entry *tabptr = NULL;
- ++arptime;
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) &&
- arptime - tabptr->time >= UIP_ARP_MAXAGE) {
- memset(&tabptr->ipaddr, 0, 4);
- }
- }
- }
- static void
- uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
- {
- register struct arp_entry *tabptr = NULL;
-
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
-
- if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
-
- if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
-
- memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
- tabptr->time = arptime;
- return;
- }
- }
- }
-
-
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
- break;
- }
- }
-
- if(i == UIP_ARPTAB_SIZE) {
- tmpage = 0;
- c = 0;
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(arptime - tabptr->time > tmpage) {
- tmpage = arptime - tabptr->time;
- c = i;
- }
- }
- i = c;
- tabptr = &arp_table[i];
- }
-
- uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
- memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
- tabptr->time = arptime;
- }
- #if 0
- void
- uip_arp_ipin(void)
- {
- uip_len -= sizeof(struct uip_eth_hdr);
-
- if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
- (uip_hostaddr[0] & uip_netmask[0])) {
- return;
- }
- if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
- (uip_hostaddr[1] & uip_netmask[1])) {
- return;
- }
- uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
- return;
- }
- #endif
- void
- uip_arp_arpin(void)
- {
- if(uip_len < sizeof(struct arp_hdr)) {
- uip_len = 0;
- return;
- }
- uip_len = 0;
- switch(BUF->opcode) {
- case HTONS(ARP_REQUEST):
-
-
- PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
- BUF->dipaddr.u8[0], BUF->dipaddr.u8[1],
- BUF->dipaddr.u8[2], BUF->dipaddr.u8[3],
- uip_hostaddr.u8[0], uip_hostaddr.u8[1],
- uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
- if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
-
- uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
- BUF->opcode = HTONS(ARP_REPLY);
- memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
- memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
- uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr);
- uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
- BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
- uip_len = sizeof(struct arp_hdr);
- }
- break;
- case HTONS(ARP_REPLY):
-
- if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
- uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
- }
- break;
- }
- return;
- }
- void
- uip_arp_out(void)
- {
- struct arp_entry *tabptr = NULL;
-
-
- if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) {
- memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
- } else {
-
- if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) {
-
- uip_ipaddr_copy(&ipaddr, &uip_draddr);
- } else {
-
- uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr);
- }
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
- break;
- }
- }
- if(i == UIP_ARPTAB_SIZE) {
-
- memset(BUF->ethhdr.dest.addr, 0xff, 6);
- memset(BUF->dhwaddr.addr, 0x00, 6);
- memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
- uip_ipaddr_copy(&BUF->dipaddr, &ipaddr);
- uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
- BUF->opcode = HTONS(ARP_REQUEST);
- BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
- BUF->protocol = HTONS(UIP_ETHTYPE_IP);
- BUF->hwlen = 6;
- BUF->protolen = 4;
- BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
- uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
- uip_len = sizeof(struct arp_hdr);
- return;
- }
-
- memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
- }
- memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
- IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
- uip_len += sizeof(struct uip_eth_hdr);
- }
|