STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
etharp.c
Go to the documentation of this file.
1 
14 /*
15  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
16  * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
17  * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without modification,
21  * are permitted provided that the following conditions are met:
22  *
23  * 1. Redistributions of source code must retain the above copyright notice,
24  * this list of conditions and the following disclaimer.
25  * 2. Redistributions in binary form must reproduce the above copyright notice,
26  * this list of conditions and the following disclaimer in the documentation
27  * and/or other materials provided with the distribution.
28  * 3. The name of the author may not be used to endorse or promote products
29  * derived from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
32  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
34  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
36  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40  * OF SUCH DAMAGE.
41  *
42  * This file is part of the lwIP TCP/IP stack.
43  *
44  */
45 
46 #include "lwip/opt.h"
47 
48 #if LWIP_ARP || LWIP_ETHERNET
49 
50 #include "lwip/ip_addr.h"
51 #include "lwip/def.h"
52 #include "lwip/ip.h"
53 #include "lwip/stats.h"
54 #include "lwip/snmp.h"
55 #include "lwip/dhcp.h"
56 #include "lwip/autoip.h"
57 #include "netif/etharp.h"
58 #include "lwip/ip6.h"
59 
60 #if PPPOE_SUPPORT
61 #include "netif/ppp/pppoe.h"
62 #endif /* PPPOE_SUPPORT */
63 
64 #include <string.h>
65 
66 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
67 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
68 
70 #define LL_MULTICAST_ADDR_0 0x01
71 #define LL_MULTICAST_ADDR_1 0x00
72 #define LL_MULTICAST_ADDR_2 0x5e
73 
74 #if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
75 
78 #define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30)
79 #define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)
80 
88 #define ARP_MAXPENDING 5
89 
90 #define HWTYPE_ETHERNET 1
91 
92 enum etharp_state {
93  ETHARP_STATE_EMPTY = 0,
94  ETHARP_STATE_PENDING,
95  ETHARP_STATE_STABLE,
96  ETHARP_STATE_STABLE_REREQUESTING_1,
97  ETHARP_STATE_STABLE_REREQUESTING_2
98 #if ETHARP_SUPPORT_STATIC_ENTRIES
99  ,ETHARP_STATE_STATIC
100 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
101 };
102 
103 struct etharp_entry {
104 #if ARP_QUEUEING
105 
106  struct etharp_q_entry *q;
107 #else /* ARP_QUEUEING */
108 
109  struct pbuf *q;
110 #endif /* ARP_QUEUEING */
111  ip4_addr_t ipaddr;
112  struct netif *netif;
113  struct eth_addr ethaddr;
114  u16_t ctime;
115  u8_t state;
116 };
117 
118 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
119 
120 #if !LWIP_NETIF_HWADDRHINT
121 static u8_t etharp_cached_entry;
122 #endif /* !LWIP_NETIF_HWADDRHINT */
123 
126 #define ETHARP_FLAG_TRY_HARD 1
127 #define ETHARP_FLAG_FIND_ONLY 2
128 #if ETHARP_SUPPORT_STATIC_ENTRIES
129 #define ETHARP_FLAG_STATIC_ENTRY 4
130 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
131 
132 #if LWIP_NETIF_HWADDRHINT
133 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \
134  *((netif)->addr_hint) = (hint);
135 #else /* LWIP_NETIF_HWADDRHINT */
136 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint))
137 #endif /* LWIP_NETIF_HWADDRHINT */
138 
139 
140 /* Some checks, instead of etharp_init(): */
141 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
142  #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h"
143 #endif
144 
145 
146 static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr* hw_dst_addr);
147 
148 
149 #if ARP_QUEUEING
150 
155 static void
156 free_etharp_q(struct etharp_q_entry *q)
157 {
158  struct etharp_q_entry *r;
159  LWIP_ASSERT("q != NULL", q != NULL);
160  LWIP_ASSERT("q->p != NULL", q->p != NULL);
161  while (q) {
162  r = q;
163  q = q->next;
164  LWIP_ASSERT("r->p != NULL", (r->p != NULL));
165  pbuf_free(r->p);
166  memp_free(MEMP_ARP_QUEUE, r);
167  }
168 }
169 #else /* ARP_QUEUEING */
170 
172 #define free_etharp_q(q) pbuf_free(q)
173 
174 #endif /* ARP_QUEUEING */
175 
177 static void
178 etharp_free_entry(int i)
179 {
180  /* remove from SNMP ARP index tree */
181  mib2_remove_arp_entry(arp_table[i].netif, &arp_table[i].ipaddr);
182  /* and empty packet queue */
183  if (arp_table[i].q != NULL) {
184  /* remove all queued packets */
185  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
186  free_etharp_q(arp_table[i].q);
187  arp_table[i].q = NULL;
188  }
189  /* recycle entry for re-use */
190  arp_table[i].state = ETHARP_STATE_EMPTY;
191 #ifdef LWIP_DEBUG
192  /* for debugging, clean out the complete entry */
193  arp_table[i].ctime = 0;
194  arp_table[i].netif = NULL;
195  ip4_addr_set_zero(&arp_table[i].ipaddr);
196  arp_table[i].ethaddr = ethzero;
197 #endif /* LWIP_DEBUG */
198 }
199 
206 void
207 etharp_tmr(void)
208 {
209  u8_t i;
210 
211  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
212  /* remove expired entries from the ARP table */
213  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
214  u8_t state = arp_table[i].state;
215  if (state != ETHARP_STATE_EMPTY
217  && (state != ETHARP_STATE_STATIC)
218 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
219  ) {
220  arp_table[i].ctime++;
221  if ((arp_table[i].ctime >= ARP_MAXAGE) ||
222  ((arp_table[i].state == ETHARP_STATE_PENDING) &&
223  (arp_table[i].ctime >= ARP_MAXPENDING))) {
224  /* pending or stable entry has become old! */
225  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
226  arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
227  /* clean up entries that have just been expired */
228  etharp_free_entry(i);
229  } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
230  /* Don't send more than one request every 2 seconds. */
231  arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
232  } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
233  /* Reset state to stable, so that the next transmitted packet will
234  re-send an ARP request. */
235  arp_table[i].state = ETHARP_STATE_STABLE;
236  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
237  /* still pending, resend an ARP query */
238  etharp_request(arp_table[i].netif, &arp_table[i].ipaddr);
239  }
240  }
241  }
242 }
243 
265 static s8_t
266 etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif* netif)
267 {
268  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
269  s8_t empty = ARP_TABLE_SIZE;
270  u8_t i = 0;
271  /* oldest entry with packets on queue */
272  s8_t old_queue = ARP_TABLE_SIZE;
273  /* its age */
274  u16_t age_queue = 0, age_pending = 0, age_stable = 0;
275 
276  LWIP_UNUSED_ARG(netif);
277 
284  /* a) in a single search sweep, do all of this
285  * 1) remember the first empty entry (if any)
286  * 2) remember the oldest stable entry (if any)
287  * 3) remember the oldest pending entry without queued packets (if any)
288  * 4) remember the oldest pending entry with queued packets (if any)
289  * 5) search for a matching IP entry, either pending or stable
290  * until 5 matches, or all entries are searched for.
291  */
292 
293  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
294  u8_t state = arp_table[i].state;
295  /* no empty entry found yet and now we do find one? */
296  if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
297  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i));
298  /* remember first empty entry */
299  empty = i;
300  } else if (state != ETHARP_STATE_EMPTY) {
301  LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
302  state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
303  /* if given, does IP address match IP address in ARP entry? */
304  if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr)
306  && ((netif == NULL) || (netif == arp_table[i].netif))
307 #endif /* ETHARP_TABLE_MATCH_NETIF */
308  ) {
309  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
310  /* found exact IP address match, simply bail out */
311  return i;
312  }
313  /* pending entry? */
314  if (state == ETHARP_STATE_PENDING) {
315  /* pending with queued packets? */
316  if (arp_table[i].q != NULL) {
317  if (arp_table[i].ctime >= age_queue) {
318  old_queue = i;
319  age_queue = arp_table[i].ctime;
320  }
321  } else
322  /* pending without queued packets? */
323  {
324  if (arp_table[i].ctime >= age_pending) {
325  old_pending = i;
326  age_pending = arp_table[i].ctime;
327  }
328  }
329  /* stable entry? */
330  } else if (state >= ETHARP_STATE_STABLE) {
331 #if ETHARP_SUPPORT_STATIC_ENTRIES
332  /* don't record old_stable for static entries since they never expire */
333  if (state < ETHARP_STATE_STATIC)
334 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
335  {
336  /* remember entry with oldest stable entry in oldest, its age in maxtime */
337  if (arp_table[i].ctime >= age_stable) {
338  old_stable = i;
339  age_stable = arp_table[i].ctime;
340  }
341  }
342  }
343  }
344  }
345  /* { we have no match } => try to create a new entry */
346 
347  /* don't create new entry, only search? */
348  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
349  /* or no empty entry found and not allowed to recycle? */
350  ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
351  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
352  return (s8_t)ERR_MEM;
353  }
354 
355  /* b) choose the least destructive entry to recycle:
356  * 1) empty entry
357  * 2) oldest stable entry
358  * 3) oldest pending entry without queued packets
359  * 4) oldest pending entry with queued packets
360  *
361  * { ETHARP_FLAG_TRY_HARD is set at this point }
362  */
363 
364  /* 1) empty entry available? */
365  if (empty < ARP_TABLE_SIZE) {
366  i = empty;
367  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
368  } else {
369  /* 2) found recyclable stable entry? */
370  if (old_stable < ARP_TABLE_SIZE) {
371  /* recycle oldest stable*/
372  i = old_stable;
373  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
374  /* no queued packets should exist on stable entries */
375  LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
376  /* 3) found recyclable pending entry without queued packets? */
377  } else if (old_pending < ARP_TABLE_SIZE) {
378  /* recycle oldest pending */
379  i = old_pending;
380  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
381  /* 4) found recyclable pending entry with queued packets? */
382  } else if (old_queue < ARP_TABLE_SIZE) {
383  /* recycle oldest pending (queued packets are free in etharp_free_entry) */
384  i = old_queue;
385  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)));
386  /* no empty or recyclable entries found */
387  } else {
388  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
389  return (s8_t)ERR_MEM;
390  }
391 
392  /* { empty or recyclable entry found } */
393  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
394  etharp_free_entry(i);
395  }
396 
397  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
398  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
399  arp_table[i].state == ETHARP_STATE_EMPTY);
400 
401  /* IP address given? */
402  if (ipaddr != NULL) {
403  /* set IP address */
404  ip4_addr_copy(arp_table[i].ipaddr, *ipaddr);
405  }
406  arp_table[i].ctime = 0;
407 #if ETHARP_TABLE_MATCH_NETIF
408  arp_table[i].netif = netif;
409 #endif /* ETHARP_TABLE_MATCH_NETIF*/
410  return (err_t)i;
411 }
412 
423 static err_t
424 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, const struct eth_addr *dst)
425 {
426  struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
427 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
428  struct eth_vlan_hdr *vlanhdr;
429 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
430 
431  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
432  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
433 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
434  ethhdr->type = PP_HTONS(ETHTYPE_VLAN);
435  vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR);
436  vlanhdr->prio_vid = 0;
437  vlanhdr->tpid = PP_HTONS(ETHTYPE_IP);
438  if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) {
439  /* packet shall not contain VLAN header, so hide it and set correct ethertype */
440  pbuf_header(p, -SIZEOF_VLAN_HDR);
441  ethhdr = (struct eth_hdr *)p->payload;
442 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
443  ethhdr->type = PP_HTONS(ETHTYPE_IP);
444 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
445  }
446 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
447  ETHADDR32_COPY(&ethhdr->dest, dst);
448  ETHADDR16_COPY(&ethhdr->src, src);
449  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
450  /* send the packet */
451  return netif->linkoutput(netif, p);
452 }
453 
472 static err_t
473 etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
474 {
475  s8_t i;
476  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
477  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",
478  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
479  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
480  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
481  /* non-unicast address? */
482  if (ip4_addr_isany(ipaddr) ||
483  ip4_addr_isbroadcast(ipaddr, netif) ||
484  ip4_addr_ismulticast(ipaddr)) {
485  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
486  return ERR_ARG;
487  }
488  /* find or create ARP entry */
489  i = etharp_find_entry(ipaddr, flags, netif);
490  /* bail out if no entry could be found */
491  if (i < 0) {
492  return (err_t)i;
493  }
494 
495 #if ETHARP_SUPPORT_STATIC_ENTRIES
496  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
497  /* record static type */
498  arp_table[i].state = ETHARP_STATE_STATIC;
499  } else
500 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
501  {
502  /* mark it stable */
503  arp_table[i].state = ETHARP_STATE_STABLE;
504  }
505 
506  /* record network interface */
507  arp_table[i].netif = netif;
508  /* insert in SNMP ARP index tree */
509  mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
510 
511  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
512  /* update address */
513  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
514  /* reset time stamp */
515  arp_table[i].ctime = 0;
516  /* this is where we will send out queued packets! */
517 #if ARP_QUEUEING
518  while (arp_table[i].q != NULL) {
519  struct pbuf *p;
520  /* remember remainder of queue */
521  struct etharp_q_entry *q = arp_table[i].q;
522  /* pop first item off the queue */
523  arp_table[i].q = q->next;
524  /* get the packet pointer */
525  p = q->p;
526  /* now queue entry can be freed */
527  memp_free(MEMP_ARP_QUEUE, q);
528 #else /* ARP_QUEUEING */
529  if (arp_table[i].q != NULL) {
530  struct pbuf *p = arp_table[i].q;
531  arp_table[i].q = NULL;
532 #endif /* ARP_QUEUEING */
533  /* send the queued IP packet */
534  etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
535  /* free the queued IP packet */
536  pbuf_free(p);
537  }
538  return ERR_OK;
539 }
540 
541 #if ETHARP_SUPPORT_STATIC_ENTRIES
542 
550 err_t
551 etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
552 {
553  struct netif *netif;
554  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",
555  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
556  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
557  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
558 
559  netif = ip4_route(ipaddr);
560  if (netif == NULL) {
561  return ERR_RTE;
562  }
563 
564  return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
565 }
566 
575 err_t
576 etharp_remove_static_entry(const ip4_addr_t *ipaddr)
577 {
578  s8_t i;
579  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
580  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
581 
582  /* find or create ARP entry */
583  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
584  /* bail out if no entry could be found */
585  if (i < 0) {
586  return (err_t)i;
587  }
588 
589  if (arp_table[i].state != ETHARP_STATE_STATIC) {
590  /* entry wasn't a static entry, cannot remove it */
591  return ERR_ARG;
592  }
593  /* entry found, free it */
594  etharp_free_entry(i);
595  return ERR_OK;
596 }
597 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
598 
604 void etharp_cleanup_netif(struct netif *netif)
605 {
606  u8_t i;
607 
608  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
609  u8_t state = arp_table[i].state;
610  if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
611  etharp_free_entry(i);
612  }
613  }
614 }
615 
627 s8_t
628 etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
629  struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
630 {
631  s8_t i;
632 
633  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
634  eth_ret != NULL && ip_ret != NULL);
635 
636  LWIP_UNUSED_ARG(netif);
637 
638  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif);
639  if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
640  *eth_ret = &arp_table[i].ethaddr;
641  *ip_ret = &arp_table[i].ipaddr;
642  return i;
643  }
644  return -1;
645 }
646 
656 u8_t
657 etharp_get_entry(u8_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret)
658 {
659  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
660  LWIP_ASSERT("netif != NULL", netif != NULL);
661  LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL);
662 
663  if((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
664  *ipaddr = &arp_table[i].ipaddr;
665  *netif = arp_table[i].netif;
666  *eth_ret = &arp_table[i].ethaddr;
667  return 1;
668  } else {
669  return 0;
670  }
671 }
672 
673 #if ETHARP_TRUST_IP_MAC
674 
689 static void
690 etharp_ip_input(struct netif *netif, struct pbuf *p)
691 {
692  struct eth_hdr *ethhdr;
693  struct ip_hdr *iphdr;
694  ip4_addr_t iphdr_src;
695  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
696 
697  /* Only insert an entry if the source IP address of the
698  incoming IP packet comes from a host on the local network. */
699  ethhdr = (struct eth_hdr *)p->payload;
700  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
701 #if ETHARP_SUPPORT_VLAN
702  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
703  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
704  }
705 #endif /* ETHARP_SUPPORT_VLAN */
706 
707  ip4_addr_copy(iphdr_src, iphdr->src);
708 
709  /* source is not on the local network? */
710  if (!ip4_addr_netcmp(&iphdr_src, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
711  /* do nothing */
712  return;
713  }
714 
715  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
716  /* update the source IP address in the cache, if present */
717  /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk
718  * back soon (for example, if the destination IP address is ours. */
719  etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
720 }
721 #endif /* ETHARP_TRUST_IP_MAC */
722 
738 static void
739 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
740 {
741  struct etharp_hdr *hdr;
742  struct eth_hdr *ethhdr;
743  /* these are aligned properly, whereas the ARP header fields might not be */
744  ip4_addr_t sipaddr, dipaddr;
745  u8_t for_us;
746 #if LWIP_AUTOIP
747  const u8_t * ethdst_hwaddr;
748 #endif /* LWIP_AUTOIP */
749 
750  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
751 
752  /* drop short ARP packets: we have to check for p->len instead of p->tot_len here
753  since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
754  if (p->len < SIZEOF_ETHARP_PACKET) {
756  ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len,
757  (s16_t)SIZEOF_ETHARP_PACKET));
758  ETHARP_STATS_INC(etharp.lenerr);
759  ETHARP_STATS_INC(etharp.drop);
760  pbuf_free(p);
761  return;
762  }
763 
764  ethhdr = (struct eth_hdr *)p->payload;
765  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
766 #if ETHARP_SUPPORT_VLAN
767  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
768  hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
769  }
770 #endif /* ETHARP_SUPPORT_VLAN */
771 
772  /* RFC 826 "Packet Reception": */
773  if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
774  (hdr->hwlen != ETHARP_HWADDR_LEN) ||
775  (hdr->protolen != sizeof(ip4_addr_t)) ||
776  (hdr->proto != PP_HTONS(ETHTYPE_IP))) {
778  ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
779  hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
780  ETHARP_STATS_INC(etharp.proterr);
781  ETHARP_STATS_INC(etharp.drop);
782  pbuf_free(p);
783  return;
784  }
785  ETHARP_STATS_INC(etharp.recv);
786 
787 #if LWIP_AUTOIP
788  /* We have to check if a host already has configured our random
789  * created link local address and continuously check if there is
790  * a host with this IP-address so we can detect collisions */
791  autoip_arp_reply(netif, hdr);
792 #endif /* LWIP_AUTOIP */
793 
794  /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without
795  * structure packing (not using structure copy which breaks strict-aliasing rules). */
796  IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
797  IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
798 
799  /* this interface is not configured? */
800  if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
801  for_us = 0;
802  } else {
803  /* ARP packet directed to us? */
804  for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif));
805  }
806 
807  /* ARP message directed to us?
808  -> add IP address in ARP cache; assume requester wants to talk to us,
809  can result in directly sending the queued packets for this host.
810  ARP message not directed to us?
811  -> update the source IP address in the cache, if present */
812  etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
813  for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
814 
815  /* now act on the message itself */
816  switch (hdr->opcode) {
817  /* ARP request? */
818  case PP_HTONS(ARP_REQUEST):
819  /* ARP request. If it asked for our address, we send out a
820  * reply. In any case, we time-stamp any existing ARP entry,
821  * and possibly send out an IP packet that was queued on it. */
822 
823  LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
824  /* ARP request for our address? */
825  if (for_us) {
826 
827  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
828  /* Re-use pbuf to send ARP reply.
829  Since we are re-using an existing pbuf, we can't call etharp_raw since
830  that would allocate a new pbuf. */
831  hdr->opcode = htons(ARP_REPLY);
832 
833  IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
834  IPADDR2_COPY(&hdr->sipaddr, netif_ip4_addr(netif));
835 
836  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
837  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
838 #if LWIP_AUTOIP
839  /* If we are using Link-Local, all ARP packets that contain a Link-Local
840  * 'sender IP address' MUST be sent using link-layer broadcast instead of
841  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
842  ethdst_hwaddr = ip4_addr_islinklocal(netif_ip4_addr(netif)) ? (const u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
843 #endif /* LWIP_AUTOIP */
844 
845  ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
846 #if LWIP_AUTOIP
847  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
848 #else /* LWIP_AUTOIP */
849  ETHADDR16_COPY(&ethhdr->dest, &hdr->shwaddr);
850 #endif /* LWIP_AUTOIP */
851  ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
852  ETHADDR16_COPY(&ethhdr->src, ethaddr);
853 
854  /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
855  are already correct, we tested that before */
856 
857  /* return ARP reply */
858  netif->linkoutput(netif, p);
859  /* we are not configured? */
860  } else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
861  /* { for_us == 0 and netif->ip_addr.addr == 0 } */
862  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
863  /* request was not directed to us */
864  } else {
865  /* { for_us == 0 and netif->ip_addr.addr != 0 } */
866  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
867  }
868  break;
869  case PP_HTONS(ARP_REPLY):
870  /* ARP reply. We already updated the ARP cache earlier. */
871  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
872 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
873  /* DHCP wants to know about ARP replies from any host with an
874  * IP address also offered to us by the DHCP server. We do not
875  * want to take a duplicate IP address on a single network.
876  * @todo How should we handle redundant (fail-over) interfaces? */
877  dhcp_arp_reply(netif, &sipaddr);
878 #endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
879  break;
880  default:
881  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
882  ETHARP_STATS_INC(etharp.err);
883  break;
884  }
885  /* free ARP packet */
886  pbuf_free(p);
887 }
888 
892 static err_t
893 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
894 {
895  LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
896  arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
897  /* if arp table entry is about to expire: re-request it,
898  but only if its state is ETHARP_STATE_STABLE to prevent flooding the
899  network with ARP requests if this address is used frequently. */
900  if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
901  if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
902  /* issue a standard request using broadcast */
903  if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
904  arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
905  }
906  } else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
907  /* issue a unicast request (for 15 seconds) to prevent unnecessary broadcast */
908  if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == ERR_OK) {
909  arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
910  }
911  }
912  }
913 
914  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr),
915  &arp_table[arp_idx].ethaddr);
916 }
917 
936 err_t
937 etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
938 {
939  const struct eth_addr *dest;
940  struct eth_addr mcastaddr;
941  const ip4_addr_t *dst_addr = ipaddr;
942 
943  LWIP_ASSERT("netif != NULL", netif != NULL);
944  LWIP_ASSERT("q != NULL", q != NULL);
945  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
946 
947  /* make room for Ethernet header - should not fail */
948 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
949  if (pbuf_header(q, sizeof(struct eth_hdr) + SIZEOF_VLAN_HDR) != 0) {
950 #else /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
951  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
952 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
953  /* bail out */
955  ("etharp_output: could not allocate room for header.\n"));
956  LINK_STATS_INC(link.lenerr);
957  return ERR_BUF;
958  }
959 
960  /* Determine on destination hardware address. Broadcasts and multicasts
961  * are special, other IP addresses are looked up in the ARP table. */
962 
963  /* broadcast destination IP address? */
964  if (ip4_addr_isbroadcast(ipaddr, netif)) {
965  /* broadcast on Ethernet also */
966  dest = (const struct eth_addr *)&ethbroadcast;
967  /* multicast destination IP address? */
968  } else if (ip4_addr_ismulticast(ipaddr)) {
969  /* Hash IP multicast address to MAC address.*/
970  mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
971  mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
972  mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
973  mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
974  mcastaddr.addr[4] = ip4_addr3(ipaddr);
975  mcastaddr.addr[5] = ip4_addr4(ipaddr);
976  /* destination Ethernet address is multicast */
977  dest = &mcastaddr;
978  /* unicast destination IP address? */
979  } else {
980  s8_t i;
981  /* outside local network? if so, this can neither be a global broadcast nor
982  a subnet broadcast. */
983  if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
984  !ip4_addr_islinklocal(ipaddr)) {
985 #if LWIP_AUTOIP
986  struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
987 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
988  SIZEOF_VLAN_HDR +
989 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
990  sizeof(struct eth_hdr));
991  /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
992  a link-local source address must always be "directly to its destination
993  on the same physical link. The host MUST NOT send the packet to any
994  router for forwarding". */
995  if (!ip4_addr_islinklocal(&iphdr->src))
996 #endif /* LWIP_AUTOIP */
997  {
998 #ifdef LWIP_HOOK_ETHARP_GET_GW
999  /* For advanced routing, a single default gateway might not be enough, so get
1000  the IP address of the gateway to handle the current destination address. */
1001  dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr);
1002  if (dst_addr == NULL)
1003 #endif /* LWIP_HOOK_ETHARP_GET_GW */
1004  {
1005  /* interface has default gateway? */
1006  if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) {
1007  /* send to hardware address of default gateway IP address */
1008  dst_addr = netif_ip4_gw(netif);
1009  /* no default gateway available */
1010  } else {
1011  /* no route to destination error (default gateway missing) */
1012  return ERR_RTE;
1013  }
1014  }
1015  }
1016  }
1017 #if LWIP_NETIF_HWADDRHINT
1018  if (netif->addr_hint != NULL) {
1019  /* per-pcb cached entry was given */
1020  u8_t etharp_cached_entry = *(netif->addr_hint);
1021  if (etharp_cached_entry < ARP_TABLE_SIZE) {
1022 #endif /* LWIP_NETIF_HWADDRHINT */
1023  if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
1024  (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
1025  /* the per-pcb-cached entry is stable and the right one! */
1026  ETHARP_STATS_INC(etharp.cachehit);
1027  return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
1028  }
1029 #if LWIP_NETIF_HWADDRHINT
1030  }
1031  }
1032 #endif /* LWIP_NETIF_HWADDRHINT */
1033 
1034  /* find stable entry: do this here since this is a critical path for
1035  throughput and etharp_find_entry() is kind of slow */
1036  for (i = 0; i < ARP_TABLE_SIZE; i++) {
1037  if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
1038  (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
1039  /* found an existing, stable entry */
1040  ETHARP_SET_HINT(netif, i);
1041  return etharp_output_to_arp_index(netif, q, i);
1042  }
1043  }
1044  /* no stable entry found, use the (slower) query function:
1045  queue on destination Ethernet address belonging to ipaddr */
1046  return etharp_query(netif, dst_addr, q);
1047  }
1048 
1049  /* continuation for multicast/broadcast destinations */
1050  /* obtain source Ethernet address of the given interface */
1051  /* send packet directly on the link */
1052  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
1053 }
1054 
1088 err_t
1089 etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
1090 {
1091  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
1092  err_t result = ERR_MEM;
1093  int is_new_entry = 0;
1094  s8_t i; /* ARP entry index */
1095 
1096  /* non-unicast address? */
1097  if (ip4_addr_isbroadcast(ipaddr, netif) ||
1098  ip4_addr_ismulticast(ipaddr) ||
1099  ip4_addr_isany(ipaddr)) {
1100  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
1101  return ERR_ARG;
1102  }
1103 
1104  /* find entry in ARP cache, ask to create entry if queueing packet */
1105  i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif);
1106 
1107  /* could not find or create entry? */
1108  if (i < 0) {
1109  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
1110  if (q) {
1111  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
1112  ETHARP_STATS_INC(etharp.memerr);
1113  }
1114  return (err_t)i;
1115  }
1116 
1117  /* mark a fresh entry as pending (we just sent a request) */
1118  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1119  is_new_entry = 1;
1120  arp_table[i].state = ETHARP_STATE_PENDING;
1121  /* record network interface for re-sending arp request in etharp_tmr */
1122  arp_table[i].netif = netif;
1123  }
1124 
1125  /* { i is either a STABLE or (new or existing) PENDING entry } */
1126  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
1127  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1128  (arp_table[i].state >= ETHARP_STATE_STABLE)));
1129 
1130  /* do we have a new entry? or an implicit query request? */
1131  if (is_new_entry || (q == NULL)) {
1132  /* try to resolve it; send out ARP request */
1133  result = etharp_request(netif, ipaddr);
1134  if (result != ERR_OK) {
1135  /* ARP request couldn't be sent */
1136  /* We don't re-send arp request in etharp_tmr, but we still queue packets,
1137  since this failure could be temporary, and the next packet calling
1138  etharp_query again could lead to sending the queued packets. */
1139  }
1140  if (q == NULL) {
1141  return result;
1142  }
1143  }
1144 
1145  /* packet given? */
1146  LWIP_ASSERT("q != NULL", q != NULL);
1147  /* stable entry? */
1148  if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1149  /* we have a valid IP->Ethernet address mapping */
1150  ETHARP_SET_HINT(netif, i);
1151  /* send the packet */
1152  result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1153  /* pending entry? (either just created or already pending */
1154  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1155  /* entry is still pending, queue the given packet 'q' */
1156  struct pbuf *p;
1157  int copy_needed = 0;
1158  /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
1159  * to copy the whole queue into a new PBUF_RAM (see bug #11400)
1160  * PBUF_ROMs can be left as they are, since ROM must not get changed. */
1161  p = q;
1162  while (p) {
1163  LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
1164  if (p->type != PBUF_ROM) {
1165  copy_needed = 1;
1166  break;
1167  }
1168  p = p->next;
1169  }
1170  if (copy_needed) {
1171  /* copy the whole packet into new pbufs */
1173  if (p != NULL) {
1174  if (pbuf_copy(p, q) != ERR_OK) {
1175  pbuf_free(p);
1176  p = NULL;
1177  }
1178  }
1179  } else {
1180  /* referencing the old pbuf is enough */
1181  p = q;
1182  pbuf_ref(p);
1183  }
1184  /* packet could be taken over? */
1185  if (p != NULL) {
1186  /* queue packet ... */
1187 #if ARP_QUEUEING
1188  struct etharp_q_entry *new_entry;
1189  /* allocate a new arp queue entry */
1190  new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
1191  if (new_entry != NULL) {
1192  unsigned int qlen = 0;
1193  new_entry->next = 0;
1194  new_entry->p = p;
1195  if (arp_table[i].q != NULL) {
1196  /* queue was already existent, append the new entry to the end */
1197  struct etharp_q_entry *r;
1198  r = arp_table[i].q;
1199  qlen++;
1200  while (r->next != NULL) {
1201  r = r->next;
1202  qlen++;
1203  }
1204  r->next = new_entry;
1205  } else {
1206  /* queue did not exist, first item in queue */
1207  arp_table[i].q = new_entry;
1208  }
1209 #if ARP_QUEUE_LEN
1210  if (qlen >= ARP_QUEUE_LEN) {
1211  struct etharp_q_entry *old;
1212  old = arp_table[i].q;
1213  arp_table[i].q = arp_table[i].q->next;
1214  pbuf_free(old->p);
1215  memp_free(MEMP_ARP_QUEUE, old);
1216  }
1217 #endif
1218  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1219  result = ERR_OK;
1220  } else {
1221  /* the pool MEMP_ARP_QUEUE is empty */
1222  pbuf_free(p);
1223  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));
1224  result = ERR_MEM;
1225  }
1226 #else /* ARP_QUEUEING */
1227  /* always queue one packet per ARP request only, freeing a previously queued packet */
1228  if (arp_table[i].q != NULL) {
1229  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));
1230  pbuf_free(arp_table[i].q);
1231  }
1232  arp_table[i].q = p;
1233  result = ERR_OK;
1234  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1235 #endif /* ARP_QUEUEING */
1236  } else {
1237  ETHARP_STATS_INC(etharp.memerr);
1238  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));
1239  result = ERR_MEM;
1240  }
1241  }
1242  return result;
1243 }
1244 
1260 #if !LWIP_AUTOIP
1261 static
1262 #endif /* LWIP_AUTOIP */
1263 err_t
1264 etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
1265  const struct eth_addr *ethdst_addr,
1266  const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
1267  const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
1268  const u16_t opcode)
1269 {
1270  struct pbuf *p;
1271  err_t result = ERR_OK;
1272  struct eth_hdr *ethhdr;
1273 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
1274  struct eth_vlan_hdr *vlanhdr;
1275 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
1276  struct etharp_hdr *hdr;
1277 #if LWIP_AUTOIP
1278  const u8_t * ethdst_hwaddr;
1279 #endif /* LWIP_AUTOIP */
1280 
1281  LWIP_ASSERT("netif != NULL", netif != NULL);
1282 
1283  /* allocate a pbuf for the outgoing ARP request packet */
1284  p = pbuf_alloc(PBUF_RAW_TX, SIZEOF_ETHARP_PACKET_TX, PBUF_RAM);
1285  /* could allocate a pbuf for an ARP request? */
1286  if (p == NULL) {
1288  ("etharp_raw: could not allocate pbuf for ARP request.\n"));
1289  ETHARP_STATS_INC(etharp.memerr);
1290  return ERR_MEM;
1291  }
1292  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
1293  (p->len >= SIZEOF_ETHARP_PACKET_TX));
1294 
1295  ethhdr = (struct eth_hdr *)p->payload;
1296 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
1297  vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR);
1298  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
1299 #else /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
1300  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
1301 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
1302  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
1303  hdr->opcode = htons(opcode);
1304 
1305  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1306  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
1307 #if LWIP_AUTOIP
1308  /* If we are using Link-Local, all ARP packets that contain a Link-Local
1309  * 'sender IP address' MUST be sent using link-layer broadcast instead of
1310  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
1311  ethdst_hwaddr = ip4_addr_islinklocal(ipsrc_addr) ? (const u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
1312 #endif /* LWIP_AUTOIP */
1313  /* Write the ARP MAC-Addresses */
1314  ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1315  ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1316  /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without
1317  * structure packing. */
1318  IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
1319  IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
1320 
1321  hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
1322  hdr->proto = PP_HTONS(ETHTYPE_IP);
1323  /* set hwlen and protolen */
1324  hdr->hwlen = ETHARP_HWADDR_LEN;
1325  hdr->protolen = sizeof(ip4_addr_t);
1326 
1327 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
1328  ethhdr->type = PP_HTONS(ETHTYPE_VLAN);
1329  vlanhdr->tpid = PP_HTONS(ETHTYPE_ARP);
1330  vlanhdr->prio_vid = 0;
1331  if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) {
1332  /* packet shall not contain VLAN header, so hide it and set correct ethertype */
1333  pbuf_header(p, -SIZEOF_VLAN_HDR);
1334  ethhdr = (struct eth_hdr *)p->payload;
1335 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
1336  ethhdr->type = PP_HTONS(ETHTYPE_ARP);
1337 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
1338  }
1339 #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
1340 
1341  /* Write the Ethernet MAC-Addresses */
1342 #if LWIP_AUTOIP
1343  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
1344 #else /* LWIP_AUTOIP */
1345  ETHADDR16_COPY(&ethhdr->dest, ethdst_addr);
1346 #endif /* LWIP_AUTOIP */
1347  ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);
1348 
1349  /* send ARP query */
1350  result = netif->linkoutput(netif, p);
1351  ETHARP_STATS_INC(etharp.xmit);
1352  /* free ARP query packet */
1353  pbuf_free(p);
1354  p = NULL;
1355  /* could not allocate pbuf for ARP request */
1356 
1357  return result;
1358 }
1359 
1372 static err_t
1373 etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr* hw_dst_addr)
1374 {
1375  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr,
1376  (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), &ethzero,
1377  ipaddr, ARP_REQUEST);
1378 }
1379 
1389 err_t
1390 etharp_request(struct netif *netif, const ip4_addr_t *ipaddr)
1391 {
1392  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
1393  return etharp_request_dst(netif, ipaddr, &ethbroadcast);
1394 }
1395 #endif /* LWIP_IPV4 && LWIP_ARP */
1396 
1405 err_t
1406 ethernet_input(struct pbuf *p, struct netif *netif)
1407 {
1408  struct eth_hdr* ethhdr;
1409  u16_t type;
1410 #if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6
1411  s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1412 #endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
1413 
1414  if (p->len <= SIZEOF_ETH_HDR) {
1415  /* a packet with only an ethernet header (or less) is not valid for us */
1416  ETHARP_STATS_INC(etharp.proterr);
1417  ETHARP_STATS_INC(etharp.drop);
1418  MIB2_STATS_NETIF_INC(netif, ifinerrors);
1419  goto free_and_return;
1420  }
1421 
1422  /* points to packet payload, which starts with an Ethernet header */
1423  ethhdr = (struct eth_hdr *)p->payload;
1425  ("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",
1426  (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
1427  (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
1428  (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
1429  (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
1430  (unsigned)htons(ethhdr->type)));
1431 
1432  type = ethhdr->type;
1433 #if ETHARP_SUPPORT_VLAN
1434  if (type == PP_HTONS(ETHTYPE_VLAN)) {
1435  struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
1436  if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1437  /* a packet with only an ethernet/vlan header (or less) is not valid for us */
1438  ETHARP_STATS_INC(etharp.proterr);
1439  ETHARP_STATS_INC(etharp.drop);
1440  MIB2_STATS_NETIF_INC(netif, ifinerrors);
1441  goto free_and_return;
1442  }
1443 #if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
1444 #ifdef LWIP_HOOK_VLAN_CHECK
1445  if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) {
1446 #elif defined(ETHARP_VLAN_CHECK_FN)
1447  if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
1448 #elif defined(ETHARP_VLAN_CHECK)
1449  if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1450 #endif
1451  /* silently ignore this packet: not for our VLAN */
1452  pbuf_free(p);
1453  return ERR_OK;
1454  }
1455 #endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
1456  type = vlan->tpid;
1457  ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1458  }
1459 #endif /* ETHARP_SUPPORT_VLAN */
1460 
1461 #if LWIP_ARP_FILTER_NETIF
1462  netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
1463 #endif /* LWIP_ARP_FILTER_NETIF*/
1464 
1465  if (ethhdr->dest.addr[0] & 1) {
1466  /* this might be a multicast or broadcast packet */
1467  if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
1468  if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
1469  (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
1470  /* mark the pbuf as link-layer multicast */
1471  p->flags |= PBUF_FLAG_LLMCAST;
1472  }
1473  } else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
1474  /* mark the pbuf as link-layer broadcast */
1475  p->flags |= PBUF_FLAG_LLBCAST;
1476  }
1477  }
1478 
1479  switch (type) {
1480 #if LWIP_IPV4 && LWIP_ARP
1481  /* IP packet? */
1482  case PP_HTONS(ETHTYPE_IP):
1483  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1484  goto free_and_return;
1485  }
1486 #if ETHARP_TRUST_IP_MAC
1487  /* update ARP table */
1488  etharp_ip_input(netif, p);
1489 #endif /* ETHARP_TRUST_IP_MAC */
1490  /* skip Ethernet header */
1491  if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) {
1493  ("ethernet_input: IPv4 packet dropped, too short (%"S16_F"/%"S16_F")\n",
1494  p->tot_len, ip_hdr_offset));
1495  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
1496  goto free_and_return;
1497  } else {
1498  /* pass to IP layer */
1499  ip4_input(p, netif);
1500  }
1501  break;
1502 
1503  case PP_HTONS(ETHTYPE_ARP):
1504  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1505  goto free_and_return;
1506  }
1507  /* pass p to ARP module */
1508  etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
1509  break;
1510 #endif /* LWIP_IPV4 && LWIP_ARP */
1511 #if PPPOE_SUPPORT
1512  case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
1513  pppoe_disc_input(netif, p);
1514  break;
1515 
1516  case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
1517  pppoe_data_input(netif, p);
1518  break;
1519 #endif /* PPPOE_SUPPORT */
1520 
1521 #if LWIP_IPV6
1522  case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */
1523  /* skip Ethernet header */
1524  if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) {
1526  ("ethernet_input: IPv6 packet dropped, too short (%"S16_F"/%"S16_F")\n",
1527  p->tot_len, ip_hdr_offset));
1528  goto free_and_return;
1529  } else {
1530  /* pass to IPv6 layer */
1531  ip6_input(p, netif);
1532  }
1533  break;
1534 #endif /* LWIP_IPV6 */
1535 
1536  default:
1537  ETHARP_STATS_INC(etharp.proterr);
1538  ETHARP_STATS_INC(etharp.drop);
1539  MIB2_STATS_NETIF_INC(netif, ifinunknownprotos);
1540  goto free_and_return;
1541  }
1542 
1543  /* This means the pbuf is freed or consumed,
1544  so the caller doesn't have to free it again */
1545  return ERR_OK;
1546 
1547 free_and_return:
1548  pbuf_free(p);
1549  return ERR_OK;
1550 }
1551 #endif /* LWIP_ARP || LWIP_ETHERNET */
1552 
#define mib2_remove_arp_entry(ni, ip)
Definition: snmp.h:164
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:47
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:46
#define U16_F
Definition: cc.h:48
signed char s8_t
Definition: cc.h:39
signed short s16_t
Definition: cc.h:41
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:267
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:603
#define ETHARP_SUPPORT_STATIC_ENTRIES
Definition: opt.h:529
#define htons(x)
Definition: def.h:86
#define PBUF_FLAG_LLBCAST
Definition: pbuf.h:102
if(LCD_Lock==DISABLE)
Definition: lcd_log.c:249
void memp_free(memp_t type, void *mem)
Definition: memp.c:399
u16_t len
Definition: pbuf.h:125
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:199
#define ETHARP_SUPPORT_VLAN
Definition: opt.h:506
Definition: pbuf.h:77
u8_t flags
Definition: pbuf.h:131
netif_linkoutput_fn linkoutput
Definition: netif.h:211
#define ARP_QUEUE_LEN
Definition: opt.h:478
#define mib2_add_arp_entry(ni, ip)
Definition: snmp.h:163
#define NULL
Definition: usbd_def.h:53
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:652
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:886
#define PP_HTONS(x)
Definition: def.h:97
#define ERR_RTE
Definition: err.h:56
#define NETIF_FLAG_ETHARP
Definition: netif.h:90
#define ARP_TABLE_SIZE
Definition: opt.h:451
#define ERR_OK
Definition: err.h:52
u16_t tot_len
Definition: pbuf.h:122
#define ARP_MAXAGE
Definition: opt.h:459
#define LWIP_DBG_TRACE
Definition: debug.h:57
Definition: pbuf.h:108
s8_t err_t
Definition: err.h:47
#define LINK_STATS_INC(x)
Definition: stats.h:318
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:70
Definition: netif.h:182
u8_t hwaddr_len
Definition: netif.h:265
Definition: pbuf.h:81
struct pbuf * next
Definition: pbuf.h:110
void pbuf_ref(struct pbuf *p)
Definition: pbuf.c:757
#define PBUF_FLAG_LLMCAST
Definition: pbuf.h:104
#define ETHARP_STATS_INC(x)
Definition: stats.h:310
#define S16_F
Definition: cc.h:49
#define ERR_ARG
Definition: err.h:71
u8_t type
Definition: pbuf.h:128
unsigned char u8_t
Definition: cc.h:38
#define MIB2_STATS_NETIF_INC(n, x)
Definition: snmp.h:121
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:89
#define ETHARP_TABLE_MATCH_NETIF
Definition: opt.h:537
#define ETHARP_DEBUG
Definition: opt.h:2774
void * memp_malloc(memp_t type)
Definition: memp.c:303
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:113
#define X8_F
Definition: arch.h:52
#define ERR_MEM
Definition: err.h:53
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:89
unsigned short u16_t
Definition: cc.h:40
void * payload
Definition: pbuf.h:113
#define X16_F
Definition: cc.h:50
#define ERR_BUF
Definition: err.h:54