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
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "lwip/opt.h"
00047
00048 #if LWIP_ARP || LWIP_ETHERNET
00049
00050 #include "lwip/ip_addr.h"
00051 #include "lwip/def.h"
00052 #include "lwip/ip.h"
00053 #include "lwip/stats.h"
00054 #include "lwip/snmp.h"
00055 #include "lwip/dhcp.h"
00056 #include "lwip/autoip.h"
00057 #include "netif/etharp.h"
00058
00059 #if PPPOE_SUPPORT
00060 #include "netif/ppp_oe.h"
00061 #endif
00062
00063 #include <string.h>
00064
00065 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
00066 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
00067
00068
00069 #define LL_MULTICAST_ADDR_0 0x01
00070 #define LL_MULTICAST_ADDR_1 0x00
00071 #define LL_MULTICAST_ADDR_2 0x5e
00072
00073 #if LWIP_ARP
00074
00075
00076
00077
00078
00079 #define ARP_MAXAGE 240
00080
00081
00082 #define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12)
00083
00084
00085
00086
00087
00088
00089
00090
00091 #define ARP_MAXPENDING 2
00092
00093 #define HWTYPE_ETHERNET 1
00094
00095 enum etharp_state {
00096 ETHARP_STATE_EMPTY = 0,
00097 ETHARP_STATE_PENDING,
00098 ETHARP_STATE_STABLE,
00099 ETHARP_STATE_STABLE_REREQUESTING
00100 #if ETHARP_SUPPORT_STATIC_ENTRIES
00101 ,ETHARP_STATE_STATIC
00102 #endif
00103 };
00104
00105 struct etharp_entry {
00106 #if ARP_QUEUEING
00107
00108 struct etharp_q_entry *q;
00109 #else
00110
00111 struct pbuf *q;
00112 #endif
00113 ip_addr_t ipaddr;
00114 struct netif *netif;
00115 struct eth_addr ethaddr;
00116 u8_t state;
00117 u8_t ctime;
00118 };
00119
00120 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
00121
00122 #if !LWIP_NETIF_HWADDRHINT
00123 static u8_t etharp_cached_entry;
00124 #endif
00125
00126
00127
00128 #define ETHARP_FLAG_TRY_HARD 1
00129 #define ETHARP_FLAG_FIND_ONLY 2
00130 #if ETHARP_SUPPORT_STATIC_ENTRIES
00131 #define ETHARP_FLAG_STATIC_ENTRY 4
00132 #endif
00133
00134 #if LWIP_NETIF_HWADDRHINT
00135 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \
00136 *((netif)->addr_hint) = (hint);
00137 #else
00138 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint))
00139 #endif
00140
00141
00142
00143 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
00144 #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h"
00145 #endif
00146
00147
00148 #if ARP_QUEUEING
00149
00150
00151
00152
00153
00154 static void
00155 free_etharp_q(struct etharp_q_entry *q)
00156 {
00157 struct etharp_q_entry *r;
00158 LWIP_ASSERT("q != NULL", q != NULL);
00159 LWIP_ASSERT("q->p != NULL", q->p != NULL);
00160 while (q) {
00161 r = q;
00162 q = q->next;
00163 LWIP_ASSERT("r->p != NULL", (r->p != NULL));
00164 pbuf_free(r->p);
00165 memp_free(MEMP_ARP_QUEUE, r);
00166 }
00167 }
00168 #else
00169
00170
00171 #define free_etharp_q(q) pbuf_free(q)
00172
00173 #endif
00174
00175
00176 static void
00177 etharp_free_entry(int i)
00178 {
00179
00180 snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
00181
00182 if (arp_table[i].q != NULL) {
00183
00184 LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
00185 free_etharp_q(arp_table[i].q);
00186 arp_table[i].q = NULL;
00187 }
00188
00189 arp_table[i].state = ETHARP_STATE_EMPTY;
00190 #ifdef LWIP_DEBUG
00191
00192 arp_table[i].ctime = 0;
00193 arp_table[i].netif = NULL;
00194 ip_addr_set_zero(&arp_table[i].ipaddr);
00195 arp_table[i].ethaddr = ethzero;
00196 #endif
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 void
00206 etharp_tmr(void)
00207 {
00208 u8_t i;
00209
00210 LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
00211
00212 for (i = 0; i < ARP_TABLE_SIZE; ++i) {
00213 u8_t state = arp_table[i].state;
00214 if (state != ETHARP_STATE_EMPTY
00215 #if ETHARP_SUPPORT_STATIC_ENTRIES
00216 && (state != ETHARP_STATE_STATIC)
00217 #endif
00218 ) {
00219 arp_table[i].ctime++;
00220 if ((arp_table[i].ctime >= ARP_MAXAGE) ||
00221 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
00222 (arp_table[i].ctime >= ARP_MAXPENDING))) {
00223
00224 LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
00225 arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
00226
00227 etharp_free_entry(i);
00228 }
00229 else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
00230
00231
00232 arp_table[i].state = ETHARP_STATE_STABLE;
00233 }
00234 #if ARP_QUEUEING
00235
00236 if (arp_table[i].state == ETHARP_STATE_PENDING) {
00237
00238 }
00239 #endif
00240 }
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 static s8_t
00266 etharp_find_entry(ip_addr_t *ipaddr, u8_t flags)
00267 {
00268 s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
00269 s8_t empty = ARP_TABLE_SIZE;
00270 u8_t i = 0, age_pending = 0, age_stable = 0;
00271
00272 s8_t old_queue = ARP_TABLE_SIZE;
00273
00274 u8_t age_queue = 0;
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 for (i = 0; i < ARP_TABLE_SIZE; ++i) {
00292 u8_t state = arp_table[i].state;
00293
00294 if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
00295 LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i));
00296
00297 empty = i;
00298 } else if (state != ETHARP_STATE_EMPTY) {
00299 LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
00300 state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
00301
00302 if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00303 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
00304
00305 return i;
00306 }
00307
00308 if (state == ETHARP_STATE_PENDING) {
00309
00310 if (arp_table[i].q != NULL) {
00311 if (arp_table[i].ctime >= age_queue) {
00312 old_queue = i;
00313 age_queue = arp_table[i].ctime;
00314 }
00315 } else
00316
00317 {
00318 if (arp_table[i].ctime >= age_pending) {
00319 old_pending = i;
00320 age_pending = arp_table[i].ctime;
00321 }
00322 }
00323
00324 } else if (state >= ETHARP_STATE_STABLE) {
00325 #if ETHARP_SUPPORT_STATIC_ENTRIES
00326
00327 if (state < ETHARP_STATE_STATIC)
00328 #endif
00329 {
00330
00331 if (arp_table[i].ctime >= age_stable) {
00332 old_stable = i;
00333 age_stable = arp_table[i].ctime;
00334 }
00335 }
00336 }
00337 }
00338 }
00339
00340
00341
00342 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
00343
00344 ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
00345 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
00346 return (s8_t)ERR_MEM;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 if (empty < ARP_TABLE_SIZE) {
00360 i = empty;
00361 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
00362 } else {
00363
00364 if (old_stable < ARP_TABLE_SIZE) {
00365
00366 i = old_stable;
00367 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
00368
00369 LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
00370
00371 } else if (old_pending < ARP_TABLE_SIZE) {
00372
00373 i = old_pending;
00374 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
00375
00376 } else if (old_queue < ARP_TABLE_SIZE) {
00377
00378 i = old_queue;
00379 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
00380
00381 } else {
00382 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
00383 return (s8_t)ERR_MEM;
00384 }
00385
00386
00387 LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
00388 etharp_free_entry(i);
00389 }
00390
00391 LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
00392 LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
00393 arp_table[i].state == ETHARP_STATE_EMPTY);
00394
00395
00396 if (ipaddr != NULL) {
00397
00398 ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
00399 }
00400 arp_table[i].ctime = 0;
00401 return (err_t)i;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 static err_t
00415 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
00416 {
00417 struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
00418
00419 LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
00420 (netif->hwaddr_len == ETHARP_HWADDR_LEN));
00421 ETHADDR32_COPY(ðhdr->dest, dst);
00422 ETHADDR16_COPY(ðhdr->src, src);
00423 ethhdr->type = PP_HTONS(ETHTYPE_IP);
00424 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
00425
00426 return netif->linkoutput(netif, p);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 static err_t
00448 etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
00449 {
00450 s8_t i;
00451 LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
00452 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
00453 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
00454 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
00455 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
00456
00457 if (ip_addr_isany(ipaddr) ||
00458 ip_addr_isbroadcast(ipaddr, netif) ||
00459 ip_addr_ismulticast(ipaddr)) {
00460 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
00461 return ERR_ARG;
00462 }
00463
00464 i = etharp_find_entry(ipaddr, flags);
00465
00466 if (i < 0) {
00467 return (err_t)i;
00468 }
00469
00470 #if ETHARP_SUPPORT_STATIC_ENTRIES
00471 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
00472
00473 arp_table[i].state = ETHARP_STATE_STATIC;
00474 } else
00475 #endif
00476 {
00477
00478 arp_table[i].state = ETHARP_STATE_STABLE;
00479 }
00480
00481
00482 arp_table[i].netif = netif;
00483
00484 snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);
00485
00486 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
00487
00488 ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
00489
00490 arp_table[i].ctime = 0;
00491
00492 #if ARP_QUEUEING
00493 while (arp_table[i].q != NULL) {
00494 struct pbuf *p;
00495
00496 struct etharp_q_entry *q = arp_table[i].q;
00497
00498 arp_table[i].q = q->next;
00499
00500 p = q->p;
00501
00502 memp_free(MEMP_ARP_QUEUE, q);
00503 #else
00504 if (arp_table[i].q != NULL) {
00505 struct pbuf *p = arp_table[i].q;
00506 arp_table[i].q = NULL;
00507 #endif
00508
00509 etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
00510
00511 pbuf_free(p);
00512 }
00513 return ERR_OK;
00514 }
00515
00516 #if ETHARP_SUPPORT_STATIC_ENTRIES
00517
00518
00519
00520
00521
00522
00523
00524
00525 err_t
00526 etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
00527 {
00528 struct netif *netif;
00529 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
00530 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
00531 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
00532 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
00533
00534 netif = ip_route(ipaddr);
00535 if (netif == NULL) {
00536 return ERR_RTE;
00537 }
00538
00539 return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 err_t
00551 etharp_remove_static_entry(ip_addr_t *ipaddr)
00552 {
00553 s8_t i;
00554 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00555 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
00556
00557
00558 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
00559
00560 if (i < 0) {
00561 return (err_t)i;
00562 }
00563
00564 if (arp_table[i].state != ETHARP_STATE_STATIC) {
00565
00566 return ERR_ARG;
00567 }
00568
00569 etharp_free_entry(i);
00570 return ERR_OK;
00571 }
00572 #endif
00573
00574
00575
00576
00577
00578
00579 void etharp_cleanup_netif(struct netif *netif)
00580 {
00581 u8_t i;
00582
00583 for (i = 0; i < ARP_TABLE_SIZE; ++i) {
00584 u8_t state = arp_table[i].state;
00585 if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
00586 etharp_free_entry(i);
00587 }
00588 }
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 s8_t
00603 etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
00604 struct eth_addr **eth_ret, ip_addr_t **ip_ret)
00605 {
00606 s8_t i;
00607
00608 LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
00609 eth_ret != NULL && ip_ret != NULL);
00610
00611 LWIP_UNUSED_ARG(netif);
00612
00613 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
00614 if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
00615 *eth_ret = &arp_table[i].ethaddr;
00616 *ip_ret = &arp_table[i].ipaddr;
00617 return i;
00618 }
00619 return -1;
00620 }
00621
00622 #if ETHARP_TRUST_IP_MAC
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 static void
00639 etharp_ip_input(struct netif *netif, struct pbuf *p)
00640 {
00641 struct eth_hdr *ethhdr;
00642 struct ip_hdr *iphdr;
00643 ip_addr_t iphdr_src;
00644 LWIP_ERROR("netif != NULL", (netif != NULL), return;);
00645
00646
00647
00648 ethhdr = (struct eth_hdr *)p->payload;
00649 iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
00650 #if ETHARP_SUPPORT_VLAN
00651 if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
00652 iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
00653 }
00654 #endif
00655
00656 ip_addr_copy(iphdr_src, iphdr->src);
00657
00658
00659 if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) {
00660
00661 return;
00662 }
00663
00664 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
00665
00666
00667
00668 etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
00669 }
00670 #endif
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 static void
00688 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
00689 {
00690 struct etharp_hdr *hdr;
00691 struct eth_hdr *ethhdr;
00692
00693 ip_addr_t sipaddr, dipaddr;
00694 u8_t for_us;
00695 #if LWIP_AUTOIP
00696 const u8_t * ethdst_hwaddr;
00697 #endif
00698
00699 LWIP_ERROR("netif != NULL", (netif != NULL), return;);
00700
00701
00702
00703 if (p->len < SIZEOF_ETHARP_PACKET) {
00704 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
00705 ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len,
00706 (s16_t)SIZEOF_ETHARP_PACKET));
00707 ETHARP_STATS_INC(etharp.lenerr);
00708 ETHARP_STATS_INC(etharp.drop);
00709 pbuf_free(p);
00710 return;
00711 }
00712
00713 ethhdr = (struct eth_hdr *)p->payload;
00714 hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
00715 #if ETHARP_SUPPORT_VLAN
00716 if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
00717 hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
00718 }
00719 #endif
00720
00721
00722 if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
00723 (hdr->hwlen != ETHARP_HWADDR_LEN) ||
00724 (hdr->protolen != sizeof(ip_addr_t)) ||
00725 (hdr->proto != PP_HTONS(ETHTYPE_IP))) {
00726 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
00727 ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
00728 hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
00729 ETHARP_STATS_INC(etharp.proterr);
00730 ETHARP_STATS_INC(etharp.drop);
00731 pbuf_free(p);
00732 return;
00733 }
00734 ETHARP_STATS_INC(etharp.recv);
00735
00736 #if LWIP_AUTOIP
00737
00738
00739
00740 autoip_arp_reply(netif, hdr);
00741 #endif
00742
00743
00744
00745 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
00746 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
00747
00748
00749 if (ip_addr_isany(&netif->ip_addr)) {
00750 for_us = 0;
00751 } else {
00752
00753 for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr));
00754 }
00755
00756
00757
00758
00759
00760
00761 etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
00762 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
00763
00764
00765 switch (hdr->opcode) {
00766
00767 case PP_HTONS(ARP_REQUEST):
00768
00769
00770
00771
00772 LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
00773
00774 if (for_us) {
00775
00776 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
00777
00778
00779
00780 hdr->opcode = htons(ARP_REPLY);
00781
00782 IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
00783 IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr);
00784
00785 LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
00786 (netif->hwaddr_len == ETHARP_HWADDR_LEN));
00787 #if LWIP_AUTOIP
00788
00789
00790
00791 ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
00792 #endif
00793
00794 ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
00795 #if LWIP_AUTOIP
00796 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
00797 #else
00798 ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr);
00799 #endif
00800 ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
00801 ETHADDR16_COPY(ðhdr->src, ethaddr);
00802
00803
00804
00805
00806
00807 netif->linkoutput(netif, p);
00808
00809 } else if (ip_addr_isany(&netif->ip_addr)) {
00810
00811 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
00812
00813 } else {
00814
00815 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
00816 }
00817 break;
00818 case PP_HTONS(ARP_REPLY):
00819
00820 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
00821 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
00822
00823
00824
00825
00826 dhcp_arp_reply(netif, &sipaddr);
00827 #endif
00828 break;
00829 default:
00830 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
00831 ETHARP_STATS_INC(etharp.err);
00832 break;
00833 }
00834
00835 pbuf_free(p);
00836 }
00837
00838
00839
00840
00841 static err_t
00842 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
00843 {
00844 LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
00845 arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
00846
00847
00848
00849 if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
00850 (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
00851 if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
00852 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
00853 }
00854 }
00855
00856 return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr),
00857 &arp_table[arp_idx].ethaddr);
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 err_t
00879 etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
00880 {
00881 struct eth_addr *dest;
00882 struct eth_addr mcastaddr;
00883 ip_addr_t *dst_addr = ipaddr;
00884
00885 LWIP_ASSERT("netif != NULL", netif != NULL);
00886 LWIP_ASSERT("q != NULL", q != NULL);
00887 LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
00888
00889
00890 if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
00891
00892 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
00893 ("etharp_output: could not allocate room for header.\n"));
00894 LINK_STATS_INC(link.lenerr);
00895 return ERR_BUF;
00896 }
00897
00898
00899
00900
00901
00902 if (ip_addr_isbroadcast(ipaddr, netif)) {
00903
00904 dest = (struct eth_addr *)ðbroadcast;
00905
00906 } else if (ip_addr_ismulticast(ipaddr)) {
00907
00908 mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
00909 mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
00910 mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
00911 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
00912 mcastaddr.addr[4] = ip4_addr3(ipaddr);
00913 mcastaddr.addr[5] = ip4_addr4(ipaddr);
00914
00915 dest = &mcastaddr;
00916
00917 } else {
00918 s8_t i;
00919
00920
00921 if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&
00922 !ip_addr_islinklocal(ipaddr)) {
00923 #if LWIP_AUTOIP
00924 struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
00925 sizeof(struct eth_hdr));
00926
00927
00928
00929
00930 if (!ip_addr_islinklocal(&iphdr->src))
00931 #endif
00932 {
00933
00934 if (!ip_addr_isany(&netif->gw)) {
00935
00936 dst_addr = &(netif->gw);
00937
00938 } else {
00939
00940 return ERR_RTE;
00941 }
00942 }
00943 }
00944 #if LWIP_NETIF_HWADDRHINT
00945 if (netif->addr_hint != NULL) {
00946
00947 u8_t etharp_cached_entry = *(netif->addr_hint);
00948 if (etharp_cached_entry < ARP_TABLE_SIZE) {
00949 #endif
00950 if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
00951 (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
00952
00953 ETHARP_STATS_INC(etharp.cachehit);
00954 return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
00955 }
00956 #if LWIP_NETIF_HWADDRHINT
00957 }
00958 }
00959 #endif
00960
00961
00962
00963 for (i = 0; i < ARP_TABLE_SIZE; i++) {
00964 if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
00965 (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
00966
00967 ETHARP_SET_HINT(netif, i);
00968 return etharp_output_to_arp_index(netif, q, i);
00969 }
00970 }
00971
00972
00973 return etharp_query(netif, dst_addr, q);
00974 }
00975
00976
00977
00978
00979 return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
00980 }
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 err_t
01016 etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
01017 {
01018 struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
01019 err_t result = ERR_MEM;
01020 s8_t i;
01021
01022
01023 if (ip_addr_isbroadcast(ipaddr, netif) ||
01024 ip_addr_ismulticast(ipaddr) ||
01025 ip_addr_isany(ipaddr)) {
01026 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
01027 return ERR_ARG;
01028 }
01029
01030
01031 i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
01032
01033
01034 if (i < 0) {
01035 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
01036 if (q) {
01037 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
01038 ETHARP_STATS_INC(etharp.memerr);
01039 }
01040 return (err_t)i;
01041 }
01042
01043
01044 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
01045 arp_table[i].state = ETHARP_STATE_PENDING;
01046 }
01047
01048
01049 LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
01050 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
01051 (arp_table[i].state >= ETHARP_STATE_STABLE)));
01052
01053
01054 if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
01055
01056 result = etharp_request(netif, ipaddr);
01057 if (result != ERR_OK) {
01058
01059
01060
01061
01062 }
01063 if (q == NULL) {
01064 return result;
01065 }
01066 }
01067
01068
01069 LWIP_ASSERT("q != NULL", q != NULL);
01070
01071 if (arp_table[i].state >= ETHARP_STATE_STABLE) {
01072
01073 ETHARP_SET_HINT(netif, i);
01074
01075 result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
01076
01077 } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
01078
01079 struct pbuf *p;
01080 int copy_needed = 0;
01081
01082
01083
01084 p = q;
01085 while (p) {
01086 LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
01087 if(p->type != PBUF_ROM) {
01088 copy_needed = 1;
01089 break;
01090 }
01091 p = p->next;
01092 }
01093 if(copy_needed) {
01094
01095 p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
01096 if(p != NULL) {
01097 if (pbuf_copy(p, q) != ERR_OK) {
01098 pbuf_free(p);
01099 p = NULL;
01100 }
01101 }
01102 } else {
01103
01104 p = q;
01105 pbuf_ref(p);
01106 }
01107
01108 if (p != NULL) {
01109
01110 #if ARP_QUEUEING
01111 struct etharp_q_entry *new_entry;
01112
01113 new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
01114 if (new_entry != NULL) {
01115 new_entry->next = 0;
01116 new_entry->p = p;
01117 if(arp_table[i].q != NULL) {
01118
01119 struct etharp_q_entry *r;
01120 r = arp_table[i].q;
01121 while (r->next != NULL) {
01122 r = r->next;
01123 }
01124 r->next = new_entry;
01125 } else {
01126
01127 arp_table[i].q = new_entry;
01128 }
01129 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
01130 result = ERR_OK;
01131 } else {
01132
01133 pbuf_free(p);
01134 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
01135 result = ERR_MEM;
01136 }
01137 #else
01138
01139 if (arp_table[i].q != NULL) {
01140 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
01141 pbuf_free(arp_table[i].q);
01142 }
01143 arp_table[i].q = p;
01144 result = ERR_OK;
01145 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
01146 #endif
01147 } else {
01148 ETHARP_STATS_INC(etharp.memerr);
01149 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
01150 result = ERR_MEM;
01151 }
01152 }
01153 return result;
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171 #if !LWIP_AUTOIP
01172 static
01173 #endif
01174 err_t
01175 etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
01176 const struct eth_addr *ethdst_addr,
01177 const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
01178 const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
01179 const u16_t opcode)
01180 {
01181 struct pbuf *p;
01182 err_t result = ERR_OK;
01183 struct eth_hdr *ethhdr;
01184 struct etharp_hdr *hdr;
01185 #if LWIP_AUTOIP
01186 const u8_t * ethdst_hwaddr;
01187 #endif
01188
01189 LWIP_ASSERT("netif != NULL", netif != NULL);
01190
01191
01192 p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM);
01193
01194 if (p == NULL) {
01195 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01196 ("etharp_raw: could not allocate pbuf for ARP request.\n"));
01197 ETHARP_STATS_INC(etharp.memerr);
01198 return ERR_MEM;
01199 }
01200 LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
01201 (p->len >= SIZEOF_ETHARP_PACKET));
01202
01203 ethhdr = (struct eth_hdr *)p->payload;
01204 hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
01205 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
01206 hdr->opcode = htons(opcode);
01207
01208 LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
01209 (netif->hwaddr_len == ETHARP_HWADDR_LEN));
01210 #if LWIP_AUTOIP
01211
01212
01213
01214 ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
01215 #endif
01216
01217 ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
01218 ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
01219
01220 #if LWIP_AUTOIP
01221 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
01222 #else
01223 ETHADDR16_COPY(ðhdr->dest, ethdst_addr);
01224 #endif
01225 ETHADDR16_COPY(ðhdr->src, ethsrc_addr);
01226
01227
01228 IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
01229 IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
01230
01231 hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
01232 hdr->proto = PP_HTONS(ETHTYPE_IP);
01233
01234 hdr->hwlen = ETHARP_HWADDR_LEN;
01235 hdr->protolen = sizeof(ip_addr_t);
01236
01237 ethhdr->type = PP_HTONS(ETHTYPE_ARP);
01238
01239 result = netif->linkoutput(netif, p);
01240 ETHARP_STATS_INC(etharp.xmit);
01241
01242 pbuf_free(p);
01243 p = NULL;
01244
01245
01246 return result;
01247 }
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258 err_t
01259 etharp_request(struct netif *netif, ip_addr_t *ipaddr)
01260 {
01261 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
01262 return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
01263 (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero,
01264 ipaddr, ARP_REQUEST);
01265 }
01266 #endif
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 err_t
01277 ethernet_input(struct pbuf *p, struct netif *netif)
01278 {
01279 struct eth_hdr* ethhdr;
01280 u16_t type;
01281 #if LWIP_ARP || ETHARP_SUPPORT_VLAN
01282 s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
01283 #endif
01284
01285 if (p->len <= SIZEOF_ETH_HDR) {
01286
01287 ETHARP_STATS_INC(etharp.proterr);
01288 ETHARP_STATS_INC(etharp.drop);
01289 goto free_and_return;
01290 }
01291
01292
01293 ethhdr = (struct eth_hdr *)p->payload;
01294 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
01295 ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n",
01296 (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
01297 (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
01298 (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
01299 (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
01300 (unsigned)htons(ethhdr->type)));
01301
01302 type = ethhdr->type;
01303 #if ETHARP_SUPPORT_VLAN
01304 if (type == PP_HTONS(ETHTYPE_VLAN)) {
01305 struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
01306 if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
01307
01308 ETHARP_STATS_INC(etharp.proterr);
01309 ETHARP_STATS_INC(etharp.drop);
01310 goto free_and_return;
01311 }
01312 #if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN)
01313 #ifdef ETHARP_VLAN_CHECK_FN
01314 if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
01315 #elif defined(ETHARP_VLAN_CHECK)
01316 if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
01317 #endif
01318
01319 pbuf_free(p);
01320 return ERR_OK;
01321 }
01322 #endif
01323 type = vlan->tpid;
01324 ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
01325 }
01326 #endif
01327
01328 #if LWIP_ARP_FILTER_NETIF
01329 netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
01330 #endif
01331
01332 if (ethhdr->dest.addr[0] & 1) {
01333
01334 if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
01335 if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
01336 (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
01337
01338 p->flags |= PBUF_FLAG_LLMCAST;
01339 }
01340 } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) {
01341
01342 p->flags |= PBUF_FLAG_LLBCAST;
01343 }
01344 }
01345
01346 switch (type) {
01347 #if LWIP_ARP
01348
01349 case PP_HTONS(ETHTYPE_IP):
01350 if (!(netif->flags & NETIF_FLAG_ETHARP)) {
01351 goto free_and_return;
01352 }
01353 #if ETHARP_TRUST_IP_MAC
01354
01355 etharp_ip_input(netif, p);
01356 #endif
01357
01358 if(pbuf_header(p, -ip_hdr_offset)) {
01359 LWIP_ASSERT("Can't move over header in packet", 0);
01360 goto free_and_return;
01361 } else {
01362
01363 ip_input(p, netif);
01364 }
01365 break;
01366
01367 case PP_HTONS(ETHTYPE_ARP):
01368 if (!(netif->flags & NETIF_FLAG_ETHARP)) {
01369 goto free_and_return;
01370 }
01371
01372 etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
01373 break;
01374 #endif
01375 #if PPPOE_SUPPORT
01376 case PP_HTONS(ETHTYPE_PPPOEDISC):
01377 pppoe_disc_input(netif, p);
01378 break;
01379
01380 case PP_HTONS(ETHTYPE_PPPOE):
01381 pppoe_data_input(netif, p);
01382 break;
01383 #endif
01384
01385 default:
01386 ETHARP_STATS_INC(etharp.proterr);
01387 ETHARP_STATS_INC(etharp.drop);
01388 goto free_and_return;
01389 }
01390
01391
01392
01393 return ERR_OK;
01394
01395 free_and_return:
01396 pbuf_free(p);
01397 return ERR_OK;
01398 }
01399 #endif