00001
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
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
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include "lwip/opt.h"
00072 #include "lwip/inet.h"
00073 #include "netif/etharp.h"
00074 #include "lwip/ip.h"
00075 #include "lwip/stats.h"
00076
00077 #define htons HTONS
00078 #define htonl HTONL
00079
00080
00081 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
00082 # include "lwip/dhcp.h"
00083 #endif
00084
00086 #define ARP_MAXAGE 120
00087
00088 #define ARP_MAXPENDING 2
00089
00090 #define HWTYPE_ETHERNET 1
00091
00093 #define ARP_REQUEST 1
00094 #define ARP_REPLY 2
00095
00096 #define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8)
00097 #define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff)
00098
00099 #define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))
00100 #define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))
00101
00102 enum etharp_state {
00103 ETHARP_STATE_EMPTY,
00104 ETHARP_STATE_PENDING,
00105 ETHARP_STATE_STABLE
00106 };
00107
00108 struct etharp_entry {
00109 struct ip_addr ipaddr;
00110 struct eth_addr ethaddr;
00111 enum etharp_state state;
00112 #if ARP_QUEUEING
00113 struct pbuf *p;
00114 #endif
00115 u8_t ctime;
00116 };
00117
00118 static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
00119 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
00120
00121 static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
00122 #define ARP_INSERT_FLAG 1
00123
00127 void
00128 etharp_init(void)
00129 {
00130 u8_t i;
00131
00132 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00133 arp_table[i].state = ETHARP_STATE_EMPTY;
00134 #if ARP_QUEUEING
00135 arp_table[i].p = NULL;
00136 #endif
00137 }
00138 }
00139
00146 void
00147 etharp_tmr(void)
00148 {
00149 u8_t i;
00150
00151 DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
00152
00153 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00154 arp_table[i].ctime++;
00155 if((arp_table[i].state == ETHARP_STATE_STABLE) &&
00156 (arp_table[i].ctime >= ARP_MAXAGE)) {
00157 DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
00158 arp_table[i].state = ETHARP_STATE_EMPTY;
00159 #if ARP_QUEUEING
00160
00161 pbuf_free(arp_table[i].p);
00162 arp_table[i].p = NULL;
00163 #endif
00164 } else if((arp_table[i].state == ETHARP_STATE_PENDING) &&
00165 (arp_table[i].ctime >= ARP_MAXPENDING)) {
00166 arp_table[i].state = ETHARP_STATE_EMPTY;
00167 #if ARP_QUEUEING
00168 DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u - dequeueing %p.\n", i, (void *)(arp_table[i].p)));
00169
00170 pbuf_free(arp_table[i].p);
00171 arp_table[i].p = NULL;
00172 #else
00173 DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
00174 #endif
00175 }
00176 }
00177 }
00178
00186 static u8_t
00187 find_arp_entry(void)
00188 {
00189 u8_t i, j, maxtime;
00190
00191
00192 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00193 if(arp_table[i].state == ETHARP_STATE_EMPTY) {
00194 DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));
00195 break;
00196 }
00197 }
00198
00199
00200
00201 if(i == ARP_TABLE_SIZE) {
00202 maxtime = 0;
00203 j = ARP_TABLE_SIZE;
00204 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00205
00206 if((arp_table[i].state == ETHARP_STATE_STABLE) &&
00207 #if ARP_QUEUEING
00208 (arp_table[i].p == NULL) &&
00209 #endif
00210 (arp_table[i].ctime >= maxtime)) {
00211 maxtime = arp_table[i].ctime;
00212 j = i;
00213 }
00214 }
00215 DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
00216 i = j;
00217 }
00218 DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u, state %u\n", i, arp_table[i].state));
00219 return i;
00220 }
00221
00236 static struct pbuf *
00237 update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
00238 {
00239 u8_t i, k;
00240 #if ARP_QUEUEING
00241 struct pbuf *p;
00242 struct eth_hdr *ethhdr;
00243 #endif
00244 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
00245 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
00246 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
00247
00248 if (ipaddr->addr == 0) {
00249 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n"));
00250 return NULL;
00251 }
00252
00253
00254
00255 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00256
00257
00258 if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00259
00260 if(arp_table[i].state == ETHARP_STATE_PENDING) {
00261 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i));
00262
00263 arp_table[i].state = ETHARP_STATE_STABLE;
00264
00265 }
00266
00267 if(arp_table[i].state == ETHARP_STATE_STABLE) {
00268 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));
00269
00270 for(k = 0; k < netif->hwaddr_len; ++k) {
00271 arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00272 }
00273
00274 arp_table[i].ctime = 0;
00275 #if ARP_QUEUEING
00276
00277 if((p = arp_table[i].p) != NULL) {
00278
00279 arp_table[i].p = NULL;
00280
00281 ethhdr = p->payload;
00282 for(k = 0; k < netif->hwaddr_len; ++k) {
00283 ethhdr->dest.addr[k] = ethaddr->addr[k];
00284 }
00285 ethhdr->type = htons(ETHTYPE_IP);
00286 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet.\n"));
00287
00288 netif->linkoutput(netif, p);
00289
00290 pbuf_free(p);
00291 }
00292 #endif
00293 return NULL;
00294 }
00295 }
00296 }
00297
00298
00299 LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
00300
00301 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: IP address not yet in table\n"));
00302
00303 if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG))
00304 {
00305 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
00306
00307 i = find_arp_entry();
00308 if(i == ARP_TABLE_SIZE) {
00309 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n"));
00310 return NULL;
00311 }
00312
00313 if (arp_table[i].state == ETHARP_STATE_STABLE) {
00314 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: overwriting old stable entry %u\n", i));
00315
00316 #if ARP_QUEUEING
00317 LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL);
00318 #endif
00319 } else {
00320 DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state));
00321 LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
00322 }
00323
00324 ip_addr_set(&arp_table[i].ipaddr, ipaddr);
00325
00326 for(k = 0; k < netif->hwaddr_len; ++k) {
00327 arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00328 }
00329
00330 arp_table[i].ctime = 0;
00331
00332 arp_table[i].state = ETHARP_STATE_STABLE;
00333
00334 #if ARP_QUEUEING
00335 arp_table[i].p = NULL;
00336 #endif
00337 }
00338 else
00339 {
00340 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no matching stable entry to update\n"));
00341 }
00342 return NULL;
00343 }
00344
00360 struct pbuf *
00361 etharp_ip_input(struct netif *netif, struct pbuf *p)
00362 {
00363 struct ethip_hdr *hdr;
00364
00365
00366
00367 hdr = p->payload;
00368
00369 if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
00370
00371 return NULL;
00372 }
00373
00374 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
00375
00376 update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG);
00377 return NULL;
00378 }
00379
00380
00395 struct pbuf *
00396 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
00397 {
00398 struct etharp_hdr *hdr;
00399 u8_t i;
00400
00401
00402 if(p->tot_len < sizeof(struct etharp_hdr)) {
00403 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
00404 pbuf_free(p);
00405 return NULL;
00406 }
00407
00408 hdr = p->payload;
00409
00410 switch(htons(hdr->opcode)) {
00411
00412 case ARP_REQUEST:
00413
00414
00415
00416
00417 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
00418
00419 if(netif->ip_addr.addr == 0) {
00420 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
00421 pbuf_free(p);
00422 return NULL;
00423 }
00424
00425 update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
00426
00427 if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00428
00429 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
00430
00431 hdr->opcode = htons(ARP_REPLY);
00432
00433 ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
00434 ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00435
00436 for(i = 0; i < netif->hwaddr_len; ++i) {
00437 hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
00438 hdr->shwaddr.addr[i] = ethaddr->addr[i];
00439 hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
00440 hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00441 }
00442
00443 hdr->hwtype = htons(HWTYPE_ETHERNET);
00444 ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
00445
00446 hdr->proto = htons(ETHTYPE_IP);
00447 ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00448
00449 hdr->ethhdr.type = htons(ETHTYPE_ARP);
00450
00451 netif->linkoutput(netif, p);
00452 } else {
00453 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
00454 }
00455 break;
00456 case ARP_REPLY:
00457
00458 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
00459 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
00460
00461 dhcp_arp_reply(netif, &hdr->sipaddr);
00462 #endif
00463
00464 if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00465 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is for us\n"));
00466
00467 update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
00468
00469 } else {
00470 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is not for us\n"));
00471
00472 update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
00473
00474 update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
00475 }
00476 break;
00477 default:
00478 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
00479 break;
00480 }
00481
00482 pbuf_free(p);
00483 p = NULL;
00484
00485 return NULL;
00486 }
00487
00512 struct pbuf *
00513 etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
00514 {
00515 struct eth_addr *dest, *srcaddr, mcastaddr;
00516 struct eth_hdr *ethhdr;
00517 u8_t i;
00518
00519
00520 if(pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
00521
00522
00523 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
00524 #ifdef LINK_STATS
00525 ++lwip_stats.link.lenerr;
00526 #endif
00527 return NULL;
00528 }
00529
00530
00531 srcaddr = (struct eth_addr *)netif->hwaddr;
00532
00533
00534 dest = NULL;
00535
00536
00537
00538
00539
00540
00541 if(ip_addr_isany(ipaddr) ||
00542 ip_addr_isbroadcast(ipaddr, &(netif->netmask))) {
00543
00544 dest = (struct eth_addr *)ðbroadcast;
00545 }
00546
00547 else if(ip_addr_ismulticast(ipaddr)) {
00548
00549 mcastaddr.addr[0] = 0x01;
00550 mcastaddr.addr[1] = 0x0;
00551 mcastaddr.addr[2] = 0x5e;
00552 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
00553 mcastaddr.addr[4] = ip4_addr3(ipaddr);
00554 mcastaddr.addr[5] = ip4_addr4(ipaddr);
00555
00556 dest = &mcastaddr;
00557 }
00558
00559 else {
00560
00561
00562 if(!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
00563
00564 if (netif->gw.addr != 0)
00565 {
00566
00567 ipaddr = &(netif->gw);
00568 }
00569
00570 else
00571 {
00572
00573 return NULL;
00574 }
00575 }
00576
00577
00578 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00579
00580 if(arp_table[i].state == ETHARP_STATE_STABLE &&
00581 ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00582 dest = &arp_table[i].ethaddr;
00583 break;
00584 }
00585 }
00586
00587 if (dest == NULL) {
00588
00589 etharp_query(netif, ipaddr, q);
00590
00591 return NULL;
00592 }
00593
00594 else
00595 {
00596
00597 }
00598 }
00599
00600
00601 if (dest != NULL) {
00602
00603
00604 ethhdr = q->payload;
00605
00606 for(i = 0; i < netif->hwaddr_len; i++) {
00607 ethhdr->dest.addr[i] = dest->addr[i];
00608 ethhdr->src.addr[i] = srcaddr->addr[i];
00609 }
00610
00611 ethhdr->type = htons(ETHTYPE_IP);
00612
00613 return q;
00614 }
00615
00616 return NULL;
00617 }
00618
00644 err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
00645 {
00646 struct eth_addr *srcaddr;
00647 struct etharp_hdr *hdr;
00648 struct pbuf *p;
00649 err_t result = ERR_OK;
00650 u8_t i;
00651 u8_t perform_arp_request = 1;
00652
00653 if (q);
00654
00655 srcaddr = (struct eth_addr *)netif->hwaddr;
00656
00657 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00658 if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00659 if (arp_table[i].state == ETHARP_STATE_PENDING) {
00660 DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
00661
00662 break;
00663 }
00664 else if (arp_table[i].state == ETHARP_STATE_STABLE) {
00665 DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i));
00666
00667
00668 perform_arp_request = 0;
00669 break;
00670 }
00671 }
00672 }
00673
00674 if (i == ARP_TABLE_SIZE) {
00675 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));
00676
00677 i = find_arp_entry();
00678
00679 if (i == ARP_TABLE_SIZE) {
00680 DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
00681 return ERR_MEM;
00682 }
00683 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i));
00684
00685 ip_addr_set(&arp_table[i].ipaddr, ipaddr);
00686 arp_table[i].ctime = 0;
00687 arp_table[i].state = ETHARP_STATE_PENDING;
00688 #if ARP_QUEUEING
00689
00690 if (arp_table[i].p != NULL) {
00691 pbuf_free(arp_table[i].p);
00692 arp_table[i].p = NULL;
00693 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
00694 }
00695 #endif
00696 }
00697 #if ARP_QUEUEING
00698
00699 if (q != NULL) {
00700
00701 #if ARP_QUEUE_FIRST == 0
00702
00703 if (arp_table[i].p != NULL) {
00704 pbuf_free(arp_table[i].p);
00705 arp_table[i].p = NULL;
00706 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
00707 }
00708 #endif
00709
00710 if (arp_table[i].p == NULL) {
00711
00712 q = pbuf_take(q);
00713
00714 arp_table[i].p = q;
00715
00716 pbuf_ref(q);
00717 DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
00718 }
00719 }
00720 #endif
00721
00722 if (perform_arp_request)
00723 {
00724
00725 p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
00726
00727 if (p != NULL) {
00728 u8_t j;
00729 DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
00730 hdr = p->payload;
00731 hdr->opcode = htons(ARP_REQUEST);
00732 for(j = 0; j < netif->hwaddr_len; ++j)
00733 {
00734 hdr->dhwaddr.addr[j] = 0x00;
00735 hdr->shwaddr.addr[j] = srcaddr->addr[j];
00736 }
00737 ip_addr_set(&(hdr->dipaddr), ipaddr);
00738 ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00739
00740 hdr->hwtype = htons(HWTYPE_ETHERNET);
00741 ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
00742
00743 hdr->proto = htons(ETHTYPE_IP);
00744 ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00745 for(j = 0; j < netif->hwaddr_len; ++j)
00746 {
00747 hdr->ethhdr.dest.addr[j] = 0xff;
00748 hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
00749 }
00750 hdr->ethhdr.type = htons(ETHTYPE_ARP);
00751
00752 result = netif->linkoutput(netif, p);
00753
00754 pbuf_free(p);
00755 p = NULL;
00756 } else {
00757 result = ERR_MEM;
00758 DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
00759 }
00760 }
00761 return result;
00762 }