48 #if LWIP_ARP || LWIP_ETHERNET 
   59 #ifdef LWIP_HOOK_FILENAME 
   60 #include LWIP_HOOK_FILENAME 
   63 #if LWIP_IPV4 && LWIP_ARP  
   67 #define ARP_AGE_REREQUEST_USED_UNICAST   (ARP_MAXAGE - 30) 
   68 #define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) 
   77 #define ARP_MAXPENDING 5 
   81   ETHARP_STATE_EMPTY = 0,
 
   84   ETHARP_STATE_STABLE_REREQUESTING_1,
 
   85   ETHARP_STATE_STABLE_REREQUESTING_2
 
   86 #if ETHARP_SUPPORT_STATIC_ENTRIES 
   94   struct etharp_q_entry *q;
 
  108 #if !LWIP_NETIF_HWADDRHINT 
  109 static u8_t etharp_cached_entry;
 
  114 #define ETHARP_FLAG_TRY_HARD     1 
  115 #define ETHARP_FLAG_FIND_ONLY    2 
  116 #if ETHARP_SUPPORT_STATIC_ENTRIES 
  117 #define ETHARP_FLAG_STATIC_ENTRY 4 
  120 #if LWIP_NETIF_HWADDRHINT 
  121 #define ETHARP_SET_HINT(netif, hint)  if (((netif) != NULL) && ((netif)->addr_hint != NULL))  \ 
  122                                       *((netif)->addr_hint) = (hint); 
  124 #define ETHARP_SET_HINT(netif, hint)  (etharp_cached_entry = (hint)) 
  129 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) 
  130   #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" 
  134 static err_t etharp_request_dst(
struct netif *
netif, 
const ip4_addr_t *ipaddr, 
const struct eth_addr* hw_dst_addr);
 
  137                         const struct eth_addr *hwsrc_addr, 
const ip4_addr_t *ipsrc_addr,
 
  138                         const struct eth_addr *hwdst_addr, 
const ip4_addr_t *ipdst_addr,
 
  148 free_etharp_q(
struct etharp_q_entry *q)
 
  150   struct etharp_q_entry *r;
 
  164 #define free_etharp_q(q) pbuf_free(q) 
  170 etharp_free_entry(
int i)
 
  175   if (arp_table[i].q != 
NULL) {
 
  178     free_etharp_q(arp_table[i].q);
 
  179     arp_table[i].q = 
NULL;
 
  182   arp_table[i].state = ETHARP_STATE_EMPTY;
 
  185   arp_table[i].ctime = 0;
 
  186   arp_table[i].netif = 
NULL;
 
  187   ip4_addr_set_zero(&arp_table[i].ipaddr);
 
  188   arp_table[i].ethaddr = ethzero;
 
  206     u8_t state = arp_table[i].state;
 
  207     if (state != ETHARP_STATE_EMPTY
 
  209       && (state != ETHARP_STATE_STATIC)
 
  212       arp_table[i].ctime++;
 
  214           ((arp_table[i].state == ETHARP_STATE_PENDING)  &&
 
  215            (arp_table[i].ctime >= ARP_MAXPENDING))) {
 
  218              arp_table[i].state >= ETHARP_STATE_STABLE ? 
"stable" : 
"pending", (
u16_t)i));
 
  220         etharp_free_entry(i);
 
  221       } 
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
 
  223         arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
 
  224       } 
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
 
  227         arp_table[i].state = ETHARP_STATE_STABLE;
 
  228       } 
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
 
  230         etharp_request(arp_table[i].
netif, &arp_table[i].ipaddr);
 
  258 etharp_find_entry(
const ip4_addr_t *ipaddr, 
u8_t flags, 
struct netif* 
netif)
 
  266   u16_t age_queue = 0, age_pending = 0, age_stable = 0;
 
  286     u8_t state = arp_table[i].state;
 
  292     } 
else if (state != ETHARP_STATE_EMPTY) {
 
  293       LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
 
  294         state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
 
  296       if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr)
 
  306       if (state == ETHARP_STATE_PENDING) {
 
  308         if (arp_table[i].q != 
NULL) {
 
  309           if (arp_table[i].ctime >= age_queue) {
 
  311             age_queue = arp_table[i].ctime;
 
  316           if (arp_table[i].ctime >= age_pending) {
 
  318             age_pending = arp_table[i].ctime;
 
  322       } 
else if (state >= ETHARP_STATE_STABLE) {
 
  323 #if ETHARP_SUPPORT_STATIC_ENTRIES 
  325         if (state < ETHARP_STATE_STATIC)
 
  329           if (arp_table[i].ctime >= age_stable) {
 
  331             age_stable = arp_table[i].ctime;
 
  340   if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
 
  342       ((empty == 
ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
 
  386     etharp_free_entry(i);
 
  390   LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
 
  391     arp_table[i].state == ETHARP_STATE_EMPTY);
 
  394   if (ipaddr != 
NULL) {
 
  396     ip4_addr_copy(arp_table[i].ipaddr, *ipaddr);
 
  398   arp_table[i].ctime = 0;
 
  399 #if ETHARP_TABLE_MATCH_NETIF 
  400   arp_table[i].netif = 
netif;
 
  424 etharp_update_arp_entry(
struct netif *
netif, 
const ip4_addr_t *ipaddr, 
struct eth_addr *ethaddr, 
u8_t flags)
 
  429     ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
 
  430     (
u16_t)ethaddr->addr[0], (
u16_t)ethaddr->addr[1], (
u16_t)ethaddr->addr[2],
 
  431     (
u16_t)ethaddr->addr[3], (
u16_t)ethaddr->addr[4], (
u16_t)ethaddr->addr[5]));
 
  433   if (ip4_addr_isany(ipaddr) ||
 
  434       ip4_addr_isbroadcast(ipaddr, 
netif) ||
 
  435       ip4_addr_ismulticast(ipaddr)) {
 
  440   i = etharp_find_entry(ipaddr, flags, 
netif);
 
  446 #if ETHARP_SUPPORT_STATIC_ENTRIES 
  447   if (flags & ETHARP_FLAG_STATIC_ENTRY) {
 
  449     arp_table[i].state = ETHARP_STATE_STATIC;
 
  450   } 
else if (arp_table[i].state == ETHARP_STATE_STATIC) {
 
  457     arp_table[i].state = ETHARP_STATE_STABLE;
 
  461   arp_table[i].netif = 
netif;
 
  469   arp_table[i].ctime = 0;
 
  472   while (arp_table[i].q != 
NULL) {
 
  475     struct etharp_q_entry *q = arp_table[i].q;
 
  477     arp_table[i].q = q->
next;
 
  483   if (arp_table[i].q != 
NULL) {
 
  484     struct pbuf *p = arp_table[i].q;
 
  485     arp_table[i].q = 
NULL;
 
  495 #if ETHARP_SUPPORT_STATIC_ENTRIES 
  505 etharp_add_static_entry(
const ip4_addr_t *ipaddr, 
struct eth_addr *ethaddr)
 
  509     ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
 
  510     (
u16_t)ethaddr->addr[0], (
u16_t)ethaddr->addr[1], (
u16_t)ethaddr->addr[2],
 
  511     (
u16_t)ethaddr->addr[3], (
u16_t)ethaddr->addr[4], (
u16_t)ethaddr->addr[5]));
 
  513   netif = ip4_route(ipaddr);
 
  518   return etharp_update_arp_entry(
netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
 
  530 etharp_remove_static_entry(
const ip4_addr_t *ipaddr)
 
  534     ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
 
  537   i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, 
NULL);
 
  543   if (arp_table[i].
state != ETHARP_STATE_STATIC) {
 
  548   etharp_free_entry(i);
 
  566       etharp_free_entry(i);
 
  583 etharp_find_addr(
struct netif *
netif, 
const ip4_addr_t *ipaddr,
 
  584          struct eth_addr **eth_ret, 
const ip4_addr_t **ip_ret)
 
  593   i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, 
netif);
 
  594   if ((i >= 0) && (arp_table[i].
state >= ETHARP_STATE_STABLE)) {
 
  595       *eth_ret = &arp_table[i].ethaddr;
 
  596       *ip_ret = &arp_table[i].ipaddr;
 
  619     *ipaddr  = &arp_table[i].ipaddr;
 
  620     *
netif   = arp_table[i].netif;
 
  621     *eth_ret = &arp_table[i].ethaddr;
 
  645   ip4_addr_t sipaddr, dipaddr;
 
  655       (hdr->protolen != 
sizeof(ip4_addr_t)) ||
 
  658       (
"etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
 
  659       hdr->hwtype, (
u16_t)hdr->hwlen, hdr->proto, (
u16_t)hdr->protolen));
 
  671   autoip_arp_reply(
netif, hdr);
 
  676   IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
 
  677   IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
 
  680   if (ip4_addr_isany_val(*netif_ip4_addr(
netif))) {
 
  684     for_us = (
u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(
netif));
 
  692   etharp_update_arp_entry(
netif, &sipaddr, &(hdr->shwaddr),
 
  693                    for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
 
  696   switch (hdr->opcode) {
 
  710                  &hdr->shwaddr, &sipaddr,
 
  713     } 
else if (ip4_addr_isany_val(*netif_ip4_addr(
netif))) {
 
  725 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) 
  730     dhcp_arp_reply(
netif, &sipaddr);
 
  748   LWIP_ASSERT(
"arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
 
  749               arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
 
  753   if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
 
  754     if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
 
  756       if (etharp_request(
netif, &arp_table[arp_idx].ipaddr) == 
ERR_OK) {
 
  757         arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
 
  759     } 
else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
 
  761       if (etharp_request_dst(
netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == 
ERR_OK) {
 
  762         arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
 
  789 etharp_output(
struct netif *
netif, 
struct pbuf *q, 
const ip4_addr_t *ipaddr)
 
  793   const ip4_addr_t *dst_addr = ipaddr;
 
  803   if (ip4_addr_isbroadcast(ipaddr, 
netif)) {
 
  805     dest = (
const struct eth_addr *)ðbroadcast;
 
  807   } 
else if (ip4_addr_ismulticast(ipaddr)) {
 
  812     mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
 
  813     mcastaddr.addr[4] = ip4_addr3(ipaddr);
 
  814     mcastaddr.addr[5] = ip4_addr4(ipaddr);
 
  822     if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(
netif), netif_ip4_netmask(
netif)) &&
 
  823         !ip4_addr_islinklocal(ipaddr)) {
 
  830       if (!ip4_addr_islinklocal(&iphdr->src))
 
  833 #ifdef LWIP_HOOK_ETHARP_GET_GW 
  836         dst_addr = LWIP_HOOK_ETHARP_GET_GW(
netif, ipaddr);
 
  837         if (dst_addr == 
NULL)
 
  841           if (!ip4_addr_isany_val(*netif_ip4_gw(
netif))) {
 
  843             dst_addr = netif_ip4_gw(
netif);
 
  852 #if LWIP_NETIF_HWADDRHINT 
  855       u8_t etharp_cached_entry = *(
netif->addr_hint);
 
  858         if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
 
  859 #if ETHARP_TABLE_MATCH_NETIF 
  860             (arp_table[etharp_cached_entry].netif == 
netif) &&
 
  862             (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
 
  865           return etharp_output_to_arp_index(
netif, q, etharp_cached_entry);
 
  867 #if LWIP_NETIF_HWADDRHINT 
  875       if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
 
  879           (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
 
  881         ETHARP_SET_HINT(
netif, i);
 
  882         return etharp_output_to_arp_index(
netif, q, i);
 
  887     return etharp_query(
netif, dst_addr, q);
 
  930 etharp_query(
struct netif *
netif, 
const ip4_addr_t *ipaddr, 
struct pbuf *q)
 
  934   int is_new_entry = 0;
 
  938   if (ip4_addr_isbroadcast(ipaddr, 
netif) ||
 
  939       ip4_addr_ismulticast(ipaddr) ||
 
  940       ip4_addr_isany(ipaddr)) {
 
  946   i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, 
netif);
 
  959   if (arp_table[i].state == ETHARP_STATE_EMPTY) {
 
  961     arp_table[i].state = ETHARP_STATE_PENDING;
 
  963     arp_table[i].netif = 
netif;
 
  967   LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
 
  968   ((arp_table[i].state == ETHARP_STATE_PENDING) ||
 
  969    (arp_table[i].state >= ETHARP_STATE_STABLE)));
 
  972   if (is_new_entry || (q == 
NULL)) {
 
  974     result = etharp_request(
netif, ipaddr);
 
  989   if (arp_table[i].state >= ETHARP_STATE_STABLE) {
 
  991     ETHARP_SET_HINT(
netif, i);
 
  993     result = ethernet_output(
netif, q, srcaddr, &(arp_table[i].ethaddr), 
ETHTYPE_IP);
 
  995   } 
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
 
 1029       struct etharp_q_entry *new_entry;
 
 1031       new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
 
 1032       if (new_entry != 
NULL) {
 
 1033         unsigned int qlen = 0;
 
 1034         new_entry->next = 0;
 
 1036         if (arp_table[i].q != 
NULL) {
 
 1038           struct etharp_q_entry *r;
 
 1041           while (r->next != 
NULL) {
 
 1045           r->
next = new_entry;
 
 1048           arp_table[i].q = new_entry;
 
 1052           struct etharp_q_entry *old;
 
 1053           old = arp_table[i].q;
 
 1054           arp_table[i].q = arp_table[i].q->
next;
 
 1069       if (arp_table[i].q != 
NULL) {
 
 1103            const struct eth_addr *ethdst_addr,
 
 1104            const struct eth_addr *hwsrc_addr, 
const ip4_addr_t *ipsrc_addr,
 
 1105            const struct eth_addr *hwdst_addr, 
const ip4_addr_t *ipdst_addr,
 
 1119       (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
 
 1123   LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
 
 1130   LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!",
 
 1138   IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
 
 1139   IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
 
 1145   hdr->protolen = 
sizeof(ip4_addr_t);
 
 1152   if(ip4_addr_islinklocal(ipsrc_addr)) {
 
 1182 etharp_request_dst(
struct netif *
netif, 
const ip4_addr_t *ipaddr, 
const struct eth_addr* hw_dst_addr)
 
 1199 etharp_request(
struct netif *
netif, 
const ip4_addr_t *ipaddr)
 
 1202   return etharp_request_dst(
netif, ipaddr, ðbroadcast);