67 #if LWIP_ARP || LWIP_ETHERNET 78 #ifdef LWIP_HOOK_FILENAME 79 #include LWIP_HOOK_FILENAME 82 #if LWIP_IPV4 && LWIP_ARP 86 #define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30) 87 #define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) 96 #define ARP_MAXPENDING 5 100 ETHARP_STATE_EMPTY = 0,
101 ETHARP_STATE_PENDING,
103 ETHARP_STATE_STABLE_REREQUESTING_1,
104 ETHARP_STATE_STABLE_REREQUESTING_2
105 #if ETHARP_SUPPORT_STATIC_ENTRIES 110 struct etharp_entry {
113 struct etharp_q_entry *q;
127 #if !LWIP_NETIF_HWADDRHINT 128 static u8_t etharp_cached_entry;
133 #define ETHARP_FLAG_TRY_HARD 1 134 #define ETHARP_FLAG_FIND_ONLY 2 135 #if ETHARP_SUPPORT_STATIC_ENTRIES 136 #define ETHARP_FLAG_STATIC_ENTRY 4 139 #if LWIP_NETIF_HWADDRHINT 140 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ 141 *((netif)->addr_hint) = (hint); 143 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) 148 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) 149 #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" 153 static err_t etharp_request_dst(
struct netif *
netif,
const ip4_addr_t *ipaddr,
const struct eth_addr* hw_dst_addr);
156 const struct eth_addr *hwsrc_addr,
const ip4_addr_t *ipsrc_addr,
157 const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
167 free_etharp_q(
struct etharp_q_entry *q)
169 struct etharp_q_entry *r;
170 LWIP_ASSERT(
"q != NULL", q != NULL);
171 LWIP_ASSERT(
"q->p != NULL", q->p != NULL);
175 LWIP_ASSERT(
"r->p != NULL", (r->p != NULL));
183 #define free_etharp_q(q) pbuf_free(q) 189 etharp_free_entry(
int i)
192 mib2_remove_arp_entry(arp_table[i].
netif, &arp_table[i].ipaddr);
194 if (arp_table[i].q != NULL) {
196 LWIP_DEBUGF(
ETHARP_DEBUG, (
"etharp_free_entry: freeing entry %"U16_F
", packet queue %p.\n", (u16_t)i, (
void *)(arp_table[i].q)));
197 free_etharp_q(arp_table[i].q);
198 arp_table[i].q = NULL;
201 arp_table[i].state = ETHARP_STATE_EMPTY;
204 arp_table[i].ctime = 0;
205 arp_table[i].netif = NULL;
206 ip4_addr_set_zero(&arp_table[i].ipaddr);
207 arp_table[i].ethaddr = ethzero;
225 u8_t state = arp_table[i].state;
226 if (state != ETHARP_STATE_EMPTY
228 && (state != ETHARP_STATE_STATIC)
231 arp_table[i].ctime++;
233 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
234 (arp_table[i].ctime >= ARP_MAXPENDING))) {
237 arp_table[i].state >= ETHARP_STATE_STABLE ?
"stable" :
"pending", (u16_t)i));
239 etharp_free_entry(i);
240 }
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
242 arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
243 }
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
246 arp_table[i].state = ETHARP_STATE_STABLE;
247 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
249 etharp_request(arp_table[i].
netif, &arp_table[i].ipaddr);
277 etharp_find_entry(
const ip4_addr_t *ipaddr, u8_t flags,
struct netif*
netif)
285 u16_t age_queue = 0, age_pending = 0, age_stable = 0;
305 u8_t state = arp_table[i].state;
307 if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
311 }
else if (state != ETHARP_STATE_EMPTY) {
312 LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
313 state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
315 if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr)
317 && ((netif == NULL) || (netif == arp_table[i].netif))
325 if (state == ETHARP_STATE_PENDING) {
327 if (arp_table[i].q != NULL) {
328 if (arp_table[i].ctime >= age_queue) {
330 age_queue = arp_table[i].ctime;
335 if (arp_table[i].ctime >= age_pending) {
337 age_pending = arp_table[i].ctime;
341 }
else if (state >= ETHARP_STATE_STABLE) {
342 #if ETHARP_SUPPORT_STATIC_ENTRIES 344 if (state < ETHARP_STATE_STATIC)
348 if (arp_table[i].ctime >= age_stable) {
350 age_stable = arp_table[i].ctime;
359 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
361 ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
376 if (empty < ARP_TABLE_SIZE) {
381 if (old_stable < ARP_TABLE_SIZE) {
386 LWIP_ASSERT(
"arp_table[i].q == NULL", arp_table[i].q == NULL);
388 }
else if (old_pending < ARP_TABLE_SIZE) {
393 }
else if (old_queue < ARP_TABLE_SIZE) {
404 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
405 etharp_free_entry(i);
408 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
409 LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
410 arp_table[i].state == ETHARP_STATE_EMPTY);
413 if (ipaddr != NULL) {
415 ip4_addr_copy(arp_table[i].ipaddr, *ipaddr);
417 arp_table[i].ctime = 0;
418 #if ETHARP_TABLE_MATCH_NETIF 419 arp_table[i].netif = netif;
443 etharp_update_arp_entry(
struct netif *netif,
const ip4_addr_t *ipaddr,
struct eth_addr *ethaddr, u8_t flags)
446 LWIP_ASSERT(
"netif->hwaddr_len == ETH_HWADDR_LEN", netif->
hwaddr_len == ETH_HWADDR_LEN);
448 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
449 (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
450 (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
452 if (ip4_addr_isany(ipaddr) ||
453 ip4_addr_isbroadcast(ipaddr, netif) ||
454 ip4_addr_ismulticast(ipaddr)) {
459 i = etharp_find_entry(ipaddr, flags, netif);
465 #if ETHARP_SUPPORT_STATIC_ENTRIES 466 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
468 arp_table[i].state = ETHARP_STATE_STATIC;
469 }
else if (arp_table[i].state == ETHARP_STATE_STATIC) {
476 arp_table[i].state = ETHARP_STATE_STABLE;
480 arp_table[i].netif = netif;
482 mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
488 arp_table[i].ctime = 0;
491 while (arp_table[i].q != NULL) {
494 struct etharp_q_entry *q = arp_table[i].q;
496 arp_table[i].q = q->
next;
502 if (arp_table[i].q != NULL) {
503 struct pbuf *p = arp_table[i].q;
504 arp_table[i].q = NULL;
514 #if ETHARP_SUPPORT_STATIC_ENTRIES 524 etharp_add_static_entry(
const ip4_addr_t *ipaddr,
struct eth_addr *ethaddr)
528 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
529 (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
530 (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
532 netif = ip4_route(ipaddr);
537 return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
549 etharp_remove_static_entry(
const ip4_addr_t *ipaddr)
553 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
556 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
562 if (arp_table[i].state != ETHARP_STATE_STATIC) {
567 etharp_free_entry(i);
578 etharp_cleanup_netif(
struct netif *netif)
583 u8_t state = arp_table[i].state;
584 if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
585 etharp_free_entry(i);
602 etharp_find_addr(
struct netif *netif,
const ip4_addr_t *ipaddr,
603 struct eth_addr **eth_ret,
const ip4_addr_t **ip_ret)
607 LWIP_ASSERT(
"eth_ret != NULL && ip_ret != NULL",
608 eth_ret != NULL && ip_ret != NULL);
612 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif);
613 if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
614 *eth_ret = &arp_table[i].ethaddr;
615 *ip_ret = &arp_table[i].ipaddr;
631 etharp_get_entry(u8_t i, ip4_addr_t **ipaddr,
struct netif **netif,
struct eth_addr **eth_ret)
633 LWIP_ASSERT(
"ipaddr != NULL", ipaddr != NULL);
634 LWIP_ASSERT(
"netif != NULL", netif != NULL);
635 LWIP_ASSERT(
"eth_ret != NULL", eth_ret != NULL);
637 if((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
638 *ipaddr = &arp_table[i].ipaddr;
639 *netif = arp_table[i].netif;
640 *eth_ret = &arp_table[i].ethaddr;
660 etharp_input(
struct pbuf *p,
struct netif *netif)
664 ip4_addr_t sipaddr, dipaddr;
667 LWIP_ERROR(
"netif != NULL", (netif != NULL),
return;);
672 if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
673 (hdr->hwlen != ETH_HWADDR_LEN) ||
674 (hdr->protolen !=
sizeof(ip4_addr_t)) ||
677 (
"etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F
"/%"U16_F
"/%"U16_F
"/%"U16_F
")\n",
678 hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen));
679 ETHARP_STATS_INC(etharp.proterr);
680 ETHARP_STATS_INC(etharp.drop);
684 ETHARP_STATS_INC(etharp.recv);
690 autoip_arp_reply(netif, hdr);
695 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
696 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
699 if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
703 for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif));
711 etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
712 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
715 switch (hdr->opcode) {
717 case PP_HTONS(ARP_REQUEST):
729 &hdr->shwaddr, &sipaddr,
732 }
else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
741 case PP_HTONS(ARP_REPLY):
744 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) 749 dhcp_arp_reply(netif, &sipaddr);
754 ETHARP_STATS_INC(etharp.err);
765 etharp_output_to_arp_index(
struct netif *netif,
struct pbuf *q, u8_t arp_idx)
767 LWIP_ASSERT(
"arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
768 arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
772 if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
773 if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
775 if (etharp_request(netif, &arp_table[arp_idx].ipaddr) ==
ERR_OK) {
776 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
778 }
else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
780 if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) ==
ERR_OK) {
781 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
808 etharp_output(
struct netif *netif,
struct pbuf *q,
const ip4_addr_t *ipaddr)
812 const ip4_addr_t *dst_addr = ipaddr;
814 LWIP_ASSERT(
"netif != NULL", netif != NULL);
815 LWIP_ASSERT(
"q != NULL", q != NULL);
816 LWIP_ASSERT(
"ipaddr != NULL", ipaddr != NULL);
822 if (ip4_addr_isbroadcast(ipaddr, netif)) {
824 dest = (
const struct eth_addr *)ðbroadcast;
826 }
else if (ip4_addr_ismulticast(ipaddr)) {
829 mcastaddr.addr[1] = LL_IP4_MULTICAST_ADDR_1;
830 mcastaddr.addr[2] = LL_IP4_MULTICAST_ADDR_2;
831 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
832 mcastaddr.addr[4] = ip4_addr3(ipaddr);
833 mcastaddr.addr[5] = ip4_addr4(ipaddr);
841 if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
842 !ip4_addr_islinklocal(ipaddr)) {
849 if (!ip4_addr_islinklocal(&iphdr->src))
852 #ifdef LWIP_HOOK_ETHARP_GET_GW 855 dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr);
856 if (dst_addr == NULL)
860 if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) {
862 dst_addr = netif_ip4_gw(netif);
871 #if LWIP_NETIF_HWADDRHINT 872 if (netif->addr_hint != NULL) {
874 u8_t etharp_cached_entry = *(netif->addr_hint);
875 if (etharp_cached_entry < ARP_TABLE_SIZE) {
877 if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
878 #if ETHARP_TABLE_MATCH_NETIF 879 (arp_table[etharp_cached_entry].netif == netif) &&
881 (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
883 ETHARP_STATS_INC(etharp.cachehit);
884 return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
886 #if LWIP_NETIF_HWADDRHINT 894 if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
896 (arp_table[i].netif == netif) &&
898 (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
900 ETHARP_SET_HINT(netif, i);
901 return etharp_output_to_arp_index(netif, q, i);
906 return etharp_query(netif, dst_addr, q);
949 etharp_query(
struct netif *netif,
const ip4_addr_t *ipaddr,
struct pbuf *q)
953 int is_new_entry = 0;
957 if (ip4_addr_isbroadcast(ipaddr, netif) ||
958 ip4_addr_ismulticast(ipaddr) ||
959 ip4_addr_isany(ipaddr)) {
965 i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif);
972 ETHARP_STATS_INC(etharp.memerr);
978 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
980 arp_table[i].state = ETHARP_STATE_PENDING;
982 arp_table[i].netif = netif;
986 LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
987 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
988 (arp_table[i].state >= ETHARP_STATE_STABLE)));
991 if (is_new_entry || (q == NULL)) {
993 result = etharp_request(netif, ipaddr);
1006 LWIP_ASSERT(
"q != NULL", q != NULL);
1008 if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1010 ETHARP_SET_HINT(netif, i);
1012 result = ethernet_output(netif, q, srcaddr, &(arp_table[i].ethaddr),
ETHTYPE_IP);
1014 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1017 int copy_needed = 0;
1023 LWIP_ASSERT(
"no packet queues allowed!", (p->
len != p->
tot_len) || (p->
next == 0));
1048 struct etharp_q_entry *new_entry;
1050 new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
1051 if (new_entry != NULL) {
1052 unsigned int qlen = 0;
1053 new_entry->next = 0;
1055 if (arp_table[i].q != NULL) {
1057 struct etharp_q_entry *r;
1060 while (r->next != NULL) {
1064 r->
next = new_entry;
1067 arp_table[i].q = new_entry;
1071 struct etharp_q_entry *old;
1072 old = arp_table[i].q;
1073 arp_table[i].q = arp_table[i].q->
next;
1088 if (arp_table[i].q != NULL) {
1097 ETHARP_STATS_INC(etharp.memerr);
1121 etharp_raw(
struct netif *netif,
const struct eth_addr *ethsrc_addr,
1122 const struct eth_addr *ethdst_addr,
1123 const struct eth_addr *hwsrc_addr,
const ip4_addr_t *ipsrc_addr,
1124 const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
1131 LWIP_ASSERT(
"netif != NULL", netif != NULL);
1138 (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
1139 ETHARP_STATS_INC(etharp.memerr);
1142 LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
1143 (p->
len >= SIZEOF_ETHARP_HDR));
1147 hdr->opcode = lwip_htons(opcode);
1149 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!",
1157 IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
1158 IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
1160 hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
1163 hdr->hwlen = ETH_HWADDR_LEN;
1164 hdr->protolen =
sizeof(ip4_addr_t);
1171 if(ip4_addr_islinklocal(ipsrc_addr)) {
1172 ethernet_output(netif, p, ethsrc_addr, ðbroadcast,
ETHTYPE_ARP);
1176 ethernet_output(netif, p, ethsrc_addr, ethdst_addr,
ETHTYPE_ARP);
1179 ETHARP_STATS_INC(etharp.xmit);
1201 etharp_request_dst(
struct netif *netif,
const ip4_addr_t *ipaddr,
const struct eth_addr* hw_dst_addr)
1203 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, hw_dst_addr,
1204 (
struct eth_addr *)netif->
hwaddr, netif_ip4_addr(netif), ðzero,
1205 ipaddr, ARP_REQUEST);
1218 etharp_request(
struct netif *netif,
const ip4_addr_t *ipaddr)
1221 return etharp_request_dst(netif, ipaddr, ðbroadcast);
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
#define ETHARP_SUPPORT_STATIC_ENTRIES
void pbuf_ref(struct pbuf *p)
#define LWIP_ALIGNMENT_CAST(target_type, val)
void memp_free(memp_t type, void *mem)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
#define LWIP_DBG_LEVEL_SERIOUS
#define ETHADDR32_COPY(dst, src)
#define LWIP_DEBUGF(debug, message)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define LWIP_DBG_LEVEL_WARNING
#define LL_IP4_MULTICAST_ADDR_0
#define LWIP_UNUSED_ARG(x)
#define ETHARP_TABLE_MATCH_NETIF
u8_t pbuf_free(struct pbuf *p)
void * memp_malloc(memp_t type)
#define ETHADDR16_COPY(dst, src)