MeterLogger
etharp.c
Go to the documentation of this file.
1 /**
2  * @file
3  * Address Resolution Protocol module for IP over Ethernet
4  *
5  * Functionally, ARP is divided into two parts. The first maps an IP address
6  * to a physical address when sending a packet, and the second part answers
7  * requests from other machines for our physical address.
8  *
9  * This implementation complies with RFC 826 (Ethernet ARP). It supports
10  * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
11  * if an interface calls etharp_gratuitous(our_netif) upon address change.
12  */
13 
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 
59 #if PPPOE_SUPPORT
60 #include "netif/ppp_oe.h"
61 #endif /* PPPOE_SUPPORT */
62 
63 #include <string.h>
64 
65 #ifdef MEMLEAK_DEBUG
66 static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
67 #endif
68 
69 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
70 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
71 
72 #if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
73 
74 /** the time an ARP entry stays valid after its last update,
75  * for ARP_TMR_INTERVAL = 5000, this is
76  * (240 * 5) seconds = 20 minutes.
77  */
78 #define ARP_MAXAGE 240
79 /** Re-request a used ARP entry 1 minute before it would expire to prevent
80  * breaking a steadily used connection because the ARP entry timed out. */
81 #define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12)
82 /** the time an ARP entry stays pending after first request,
83  * for ARP_TMR_INTERVAL = 5000, this is
84  * (2 * 5) seconds = 10 seconds.
85  *
86  * @internal Keep this number at least 2, otherwise it might
87  * run out instantly if the timeout occurs directly after a request.
88  */
89 #define ARP_MAXPENDING 2
90 
91 #define HWTYPE_ETHERNET 1
92 
93 enum etharp_state {
94  ETHARP_STATE_EMPTY = 0,
95  ETHARP_STATE_PENDING,
96  ETHARP_STATE_STABLE,
97  ETHARP_STATE_STABLE_REREQUESTING
98 };
99 
100 struct etharp_entry {
101 #if ARP_QUEUEING
102  /** Pointer to queue of pending outgoing packets on this ARP entry. */
103  struct etharp_q_entry *q;
104 #else /* ARP_QUEUEING */
105  /** Pointer to a single pending outgoing packet on this ARP entry. */
106  struct pbuf *q;
107 #endif /* ARP_QUEUEING */
108  ip_addr_t ipaddr;
109  struct eth_addr ethaddr;
110 #if LWIP_SNMP || LWIP_ARP
111  struct netif *netif;
112 #endif /* LWIP_SNMP */
113  u8_t state;
114  u8_t ctime;
115 #if ETHARP_SUPPORT_STATIC_ENTRIES
116  u8_t static_entry;
117 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
118 };
119 
120 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
121 
122 #if !LWIP_NETIF_HWADDRHINT
123 static u8_t etharp_cached_entry;
124 #endif /* !LWIP_NETIF_HWADDRHINT */
125 
126 /** Try hard to create a new entry - we want the IP address to appear in
127  the cache (even if this means removing an active entry or so). */
128 #define ETHARP_FLAG_TRY_HARD 1
129 #define ETHARP_FLAG_FIND_ONLY 2
130 #define ETHARP_FLAG_STATIC_ENTRY 4
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 static err_t update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags);
140 
141 
142 /* Some checks, instead of etharp_init(): */
143 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
144  #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h"
145 #endif
146 
147 
148 #if ARP_QUEUEING
149 /**
150  * Free a complete queue of etharp entries
151  *
152  * @param q a qeueue of etharp_q_entry's to free
153  */
154 static void
155 free_etharp_q(struct etharp_q_entry *q)
156 {
157  struct etharp_q_entry *r;
158  LWIP_ASSERT("q != NULL", q != NULL);
159  LWIP_ASSERT("q->p != NULL", q->p != NULL);
160  while (q) {
161  r = q;
162  q = q->next;
163  LWIP_ASSERT("r->p != NULL", (r->p != NULL));
164  pbuf_free(r->p);
165  memp_free(MEMP_ARP_QUEUE, r);
166  }
167 }
168 #else /* ARP_QUEUEING */
169 
170 /** Compatibility define: free the queued pbuf */
171 #define free_etharp_q(q) pbuf_free(q)
172 
173 #endif /* ARP_QUEUEING */
174 
175 /** Clean up ARP table entries */
176 static void ICACHE_FLASH_ATTR
177 free_entry(int i)
178 {
179  /* remove from SNMP ARP index tree */
180  snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
181  /* and empty packet queue */
182  if (arp_table[i].q != NULL) {
183  /* remove all queued packets */
184  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
185  free_etharp_q(arp_table[i].q);
186  arp_table[i].q = NULL;
187  }
188  /* recycle entry for re-use */
189  arp_table[i].state = ETHARP_STATE_EMPTY;
190 #if ETHARP_SUPPORT_STATIC_ENTRIES
191  arp_table[i].static_entry = 0;
192 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
193 #ifdef LWIP_DEBUG
194  /* for debugging, clean out the complete entry */
195  arp_table[i].ctime = 0;
196 #if LWIP_SNMP
197  arp_table[i].netif = NULL;
198 #endif /* LWIP_SNMP */
199  ip_addr_set_zero(&arp_table[i].ipaddr);
200  arp_table[i].ethaddr = ethzero;
201 #endif /* LWIP_DEBUG */
202 }
203 
204 /**
205  * Clears expired entries in the ARP table.
206  *
207  * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds),
208  * in order to expire entries in the ARP table.
209  */
210 void
211 etharp_tmr(void)
212 {
213  u8_t i;
214 
215  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
216  /* remove expired entries from the ARP table */
217  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
218  u8_t state = arp_table[i].state;
219  if (state != ETHARP_STATE_EMPTY
221  && (arp_table[i].static_entry == 0)
222 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
223  ) {
224  arp_table[i].ctime++;
225  if ((arp_table[i].ctime >= ARP_MAXAGE) ||
226  ((arp_table[i].state == ETHARP_STATE_PENDING) &&
227  (arp_table[i].ctime >= ARP_MAXPENDING))) {
228  /* pending or stable entry has become old! */
229  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
230  arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
231  /* clean up entries that have just been expired */
232  free_entry(i);
233  }
234  else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
235  /* Reset state to stable, so that the next transmitted packet will
236  re-send an ARP request. */
237  arp_table[i].state = ETHARP_STATE_STABLE;
238  }
239 #if ARP_QUEUEING
240  /* still pending entry? (not expired) */
241  if (arp_table[i].state == ETHARP_STATE_PENDING) {
242  /* resend an ARP query here? */
243  }
244 #endif /* ARP_QUEUEING */
245  }
246  }
247 }
248 
249 /**
250  * Search the ARP table for a matching or new entry.
251  *
252  * If an IP address is given, return a pending or stable ARP entry that matches
253  * the address. If no match is found, create a new entry with this address set,
254  * but in state ETHARP_EMPTY. The caller must check and possibly change the
255  * state of the returned entry.
256  *
257  * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
258  *
259  * In all cases, attempt to create new entries from an empty entry. If no
260  * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle
261  * old entries. Heuristic choose the least important entry for recycling.
262  *
263  * @param ipaddr IP address to find in ARP cache, or to add if not found.
264  * @param flags @see definition of ETHARP_FLAG_*
265  * @param netif netif related to this address (used for NETIF_HWADDRHINT)
266  *
267  * @return The ARP entry index that matched or is created, ERR_MEM if no
268  * entry is found or could be recycled.
269  */
270 static s8_t ICACHE_FLASH_ATTR
271 find_entry(ip_addr_t *ipaddr, u8_t flags)
272 {
273  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
274  s8_t empty = ARP_TABLE_SIZE;
275  u8_t i = 0, age_pending = 0, age_stable = 0;
276  /* oldest entry with packets on queue */
277  s8_t old_queue = ARP_TABLE_SIZE;
278  /* its age */
279  u8_t age_queue = 0;
280 
281  /**
282  * a) do a search through the cache, remember candidates
283  * b) select candidate entry
284  * c) create new entry
285  */
286 
287  /* a) in a single search sweep, do all of this
288  * 1) remember the first empty entry (if any)
289  * 2) remember the oldest stable entry (if any)
290  * 3) remember the oldest pending entry without queued packets (if any)
291  * 4) remember the oldest pending entry with queued packets (if any)
292  * 5) search for a matching IP entry, either pending or stable
293  * until 5 matches, or all entries are searched for.
294  */
295 
296  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
297  u8_t state = arp_table[i].state;
298  /* no empty entry found yet and now we do find one? */
299  if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
300  LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i));
301  /* remember first empty entry */
302  empty = i;
303  } else if (state != ETHARP_STATE_EMPTY) {
304  LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
305  state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
306  /* if given, does IP address match IP address in ARP entry? */
307  if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
308  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching entry %"U16_F"\n", (u16_t)i));
309  /* found exact IP address match, simply bail out */
310  return i;
311  }
312  /* pending entry? */
313  if (state == ETHARP_STATE_PENDING) {
314  /* pending with queued packets? */
315  if (arp_table[i].q != NULL) {
316  if (arp_table[i].ctime >= age_queue) {
317  old_queue = i;
318  age_queue = arp_table[i].ctime;
319  }
320  } else
321  /* pending without queued packets? */
322  {
323  if (arp_table[i].ctime >= age_pending) {
324  old_pending = i;
325  age_pending = arp_table[i].ctime;
326  }
327  }
328  /* stable entry? */
329  } else if (state >= ETHARP_STATE_STABLE) {
330 #if ETHARP_SUPPORT_STATIC_ENTRIES
331  /* don't record old_stable for static entries since they never expire */
332  if (arp_table[i].static_entry == 0)
333 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
334  {
335  /* remember entry with oldest stable entry in oldest, its age in maxtime */
336  if (arp_table[i].ctime >= age_stable) {
337  old_stable = i;
338  age_stable = arp_table[i].ctime;
339  }
340  }
341  }
342  }
343  }
344  /* { we have no match } => try to create a new entry */
345 
346  /* don't create new entry, only search? */
347  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
348  /* or no empty entry found and not allowed to recycle? */
349  ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
350  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty entry found and not allowed to recycle\n"));
351  return (s8_t)ERR_MEM;
352  }
353 
354  /* b) choose the least destructive entry to recycle:
355  * 1) empty entry
356  * 2) oldest stable entry
357  * 3) oldest pending entry without queued packets
358  * 4) oldest pending entry with queued packets
359  *
360  * { ETHARP_FLAG_TRY_HARD is set at this point }
361  */
362 
363  /* 1) empty entry available? */
364  if (empty < ARP_TABLE_SIZE) {
365  i = empty;
366  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
367  } else {
368  /* 2) found recyclable stable entry? */
369  if (old_stable < ARP_TABLE_SIZE) {
370  /* recycle oldest stable*/
371  i = old_stable;
372  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
373  /* no queued packets should exist on stable entries */
374  LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
375  /* 3) found recyclable pending entry without queued packets? */
376  } else if (old_pending < ARP_TABLE_SIZE) {
377  /* recycle oldest pending */
378  i = old_pending;
379  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
380  /* 4) found recyclable pending entry with queued packets? */
381  } else if (old_queue < ARP_TABLE_SIZE) {
382  /* recycle oldest pending (queued packets are free in free_entry) */
383  i = old_queue;
384  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
385  /* no empty or recyclable entries found */
386  } else {
387  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty or recyclable entries found\n"));
388  return (s8_t)ERR_MEM;
389  }
390 
391  /* { empty or recyclable entry found } */
392  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
393  free_entry(i);
394  }
395 
396  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
397  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
398  arp_table[i].state == ETHARP_STATE_EMPTY);
399 
400  /* IP address given? */
401  if (ipaddr != NULL) {
402  /* set IP address */
403  ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
404  }
405  arp_table[i].ctime = 0;
406 #if ETHARP_SUPPORT_STATIC_ENTRIES
407  arp_table[i].static_entry = 0;
408 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
409  return (err_t)i;
410 }
411 
412 /**
413  * Send an IP packet on the network using netif->linkoutput
414  * The ethernet header is filled in before sending.
415  *
416  * @params netif the lwIP network interface on which to send the packet
417  * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header
418  * @params src the source MAC address to be copied into the ethernet header
419  * @params dst the destination MAC address to be copied into the ethernet header
420  * @return ERR_OK if the packet was sent, any other err_t on failure
421  */
423 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
424 {
425  struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
426 
427  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
428  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
429  ETHADDR32_COPY(&ethhdr->dest, dst);
430  ETHADDR16_COPY(&ethhdr->src, src);
431  ethhdr->type = PP_HTONS(ETHTYPE_IP);
432  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
433  /* send the packet */
434  return netif->linkoutput(netif, p);
435 }
436 
437 /**
438  * Update (or insert) a IP/MAC address pair in the ARP cache.
439  *
440  * If a pending entry is resolved, any queued packets will be sent
441  * at this point.
442  *
443  * @param netif netif related to this entry (used for NETIF_ADDRHINT)
444  * @param ipaddr IP address of the inserted ARP entry.
445  * @param ethaddr Ethernet address of the inserted ARP entry.
446  * @param flags @see definition of ETHARP_FLAG_*
447  *
448  * @return
449  * - ERR_OK Succesfully updated ARP cache.
450  * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
451  * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
452  *
453  * @see pbuf_free()
454  */
456 update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
457 {
458  s8_t i;
459  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
460  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("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",
461  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
462  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
463  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
464  /* non-unicast address? */
465  if (ip_addr_isany(ipaddr) ||
466  ip_addr_isbroadcast(ipaddr, netif) ||
467  ip_addr_ismulticast(ipaddr)) {
468  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
469  return ERR_ARG;
470  }
471  /* find or create ARP entry */
472  i = find_entry(ipaddr, flags);
473  /* bail out if no entry could be found */
474  if (i < 0) {
475  return (err_t)i;
476  }
477 
478 #if ETHARP_SUPPORT_STATIC_ENTRIES
479  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
480  /* record static type */
481  arp_table[i].static_entry = 1;
482  }
483 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
484 
485  /* mark it stable */
486  arp_table[i].state = ETHARP_STATE_STABLE;
487 
488 #if LWIP_SNMP
489  /* record network interface */
490  arp_table[i].netif = netif;
491 #endif /* LWIP_SNMP */
492  /* insert in SNMP ARP index tree */
493  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);
494 
495  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
496  /* update address */
497  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
498  /* reset time stamp */
499  arp_table[i].ctime = 0;
500  /* this is where we will send out queued packets! */
501 #if ARP_QUEUEING
502  while (arp_table[i].q != NULL) {
503  struct pbuf *p;
504  /* remember remainder of queue */
505  struct etharp_q_entry *q = arp_table[i].q;
506  /* pop first item off the queue */
507  arp_table[i].q = q->next;
508  /* get the packet pointer */
509  p = q->p;
510  /* now queue entry can be freed */
511  memp_free(MEMP_ARP_QUEUE, q);
512 #else /* ARP_QUEUEING */
513  if (arp_table[i].q != NULL) {
514  struct pbuf *p = arp_table[i].q;
515  arp_table[i].q = NULL;
516 #endif /* ARP_QUEUEING */
517  /* send the queued IP packet */
518  etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
519  /* free the queued IP packet */
520  pbuf_free(p);
521  }
522  return ERR_OK;
523 }
524 
525 #if ETHARP_SUPPORT_STATIC_ENTRIES
526 /** Add a new static entry to the ARP table. If an entry exists for the
527  * specified IP address, this entry is overwritten.
528  * If packets are queued for the specified IP address, they are sent out.
529  *
530  * @param ipaddr IP address for the new static entry
531  * @param ethaddr ethernet address for the new static entry
532  * @return @see return values of etharp_add_static_entry
533  */
534 err_t
535 etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
536 {
537  struct netif *netif;
538  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",
539  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
540  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
541  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
542 
543  netif = ip_route(ipaddr);
544  if (netif == NULL) {
545  return ERR_RTE;
546  }
547 
548  return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
549 }
550 
551 /** Remove a static entry from the ARP table previously added with a call to
552  * etharp_add_static_entry.
553  *
554  * @param ipaddr IP address of the static entry to remove
555  * @return ERR_OK: entry removed
556  * ERR_MEM: entry wasn't found
557  * ERR_ARG: entry wasn't a static entry but a dynamic one
558  */
559 err_t
560 etharp_remove_static_entry(ip_addr_t *ipaddr)
561 {
562  s8_t i;
563  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
564  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
565 
566  /* find or create ARP entry */
567  i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
568  /* bail out if no entry could be found */
569  if (i < 0) {
570  return (err_t)i;
571  }
572 
573  if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
574  (arp_table[i].static_entry == 0)) {
575  /* entry wasn't a static entry, cannot remove it */
576  return ERR_ARG;
577  }
578  /* entry found, free it */
579  free_entry(i);
580  return ERR_OK;
581 }
582 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
583 
584 /**
585  * Remove all ARP table entries of the specified netif.
586  *
587  * @param netif points to a network interface
588  */
589 void ICACHE_FLASH_ATTR etharp_cleanup_netif(struct netif *netif)
590 {
591  u8_t i;
592 
593  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
594  u8_t state = arp_table[i].state;
595  if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
596  free_entry(i);
597  }
598  }
599 }
600 
601 /**
602  * Finds (stable) ethernet/IP address pair from ARP table
603  * using interface and IP address index.
604  * @note the addresses in the ARP table are in network order!
605  *
606  * @param netif points to interface index
607  * @param ipaddr points to the (network order) IP address index
608  * @param eth_ret points to return pointer
609  * @param ip_ret points to return pointer
610  * @return table index if found, -1 otherwise
611  */
612 s8_t
613 etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
614  struct eth_addr **eth_ret, ip_addr_t **ip_ret)
615 {
616  s8_t i;
617 
618  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
619  eth_ret != NULL && ip_ret != NULL);
620 
621  LWIP_UNUSED_ARG(netif);
622 
623  i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
624  if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
625  *eth_ret = &arp_table[i].ethaddr;
626  *ip_ret = &arp_table[i].ipaddr;
627  return i;
628  }
629  return -1;
630 }
631 
632 #if ETHARP_TRUST_IP_MAC
633 /**
634  * Updates the ARP table using the given IP packet.
635  *
636  * Uses the incoming IP packet's source address to update the
637  * ARP cache for the local network. The function does not alter
638  * or free the packet. This function must be called before the
639  * packet p is passed to the IP layer.
640  *
641  * @param netif The lwIP network interface on which the IP packet pbuf arrived.
642  * @param p The IP packet that arrived on netif.
643  *
644  * @return NULL
645  *
646  * @see pbuf_free()
647  */
648 static void ICACHE_FLASH_ATTR
649 etharp_ip_input(struct netif *netif, struct pbuf *p)
650 {
651  struct eth_hdr *ethhdr;
652  struct ip_hdr *iphdr;
653  ip_addr_t iphdr_src;
654  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
655 
656  /* Only insert an entry if the source IP address of the
657  incoming IP packet comes from a host on the local network. */
658  ethhdr = (struct eth_hdr *)p->payload;
659  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
660 #if ETHARP_SUPPORT_VLAN
661  if (ethhdr->type == ETHTYPE_VLAN) {
662  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
663  }
664 #endif /* ETHARP_SUPPORT_VLAN */
665 
666  ip_addr_copy(iphdr_src, iphdr->src);
667 
668  /* source is not on the local network? */
669  if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) {
670  /* do nothing */
671  return;
672  }
673 
674  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
675  /* update the source IP address in the cache, if present */
676  /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk
677  * back soon (for example, if the destination IP address is ours. */
678  update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
679 }
680 #endif /* ETHARP_TRUST_IP_MAC */
681 
682 /**
683  * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache
684  * send out queued IP packets. Updates cache with snooped address pairs.
685  *
686  * Should be called for incoming ARP packets. The pbuf in the argument
687  * is freed by this function.
688  *
689  * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
690  * @param ethaddr Ethernet address of netif.
691  * @param p The ARP packet that arrived on netif. Is freed by this function.
692  *
693  * @return NULL
694  *
695  * @see pbuf_free()
696  */
697 static void ICACHE_FLASH_ATTR
698 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
699 {
700  struct etharp_hdr *hdr;
701  struct eth_hdr *ethhdr;
702  /* these are aligned properly, whereas the ARP header fields might not be */
703  ip_addr_t sipaddr, dipaddr;
704  u8_t for_us;
705 #if LWIP_AUTOIP
706  const u8_t * ethdst_hwaddr;
707 #endif /* LWIP_AUTOIP */
708 #ifdef EBUF_LWIP
709  struct pbuf *q;
710 #endif /* EBUF_LWIP */
711 
712  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
713 
714  /* drop short ARP packets: we have to check for p->len instead of p->tot_len here
715  since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
716  if (p->len < SIZEOF_ETHARP_PACKET) {
718  ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len,
719  (s16_t)SIZEOF_ETHARP_PACKET));
720  ETHARP_STATS_INC(etharp.lenerr);
721  ETHARP_STATS_INC(etharp.drop);
722  pbuf_free(p);
723  return;
724  }
725 
726  ethhdr = (struct eth_hdr *)p->payload;
727  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
728 #if ETHARP_SUPPORT_VLAN
729  if (ethhdr->type == ETHTYPE_VLAN) {
730  hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
731  }
732 #endif /* ETHARP_SUPPORT_VLAN */
733 
734  /* RFC 826 "Packet Reception": */
735  if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
736  (hdr->hwlen != ETHARP_HWADDR_LEN) ||
737  (hdr->protolen != sizeof(ip_addr_t)) ||
738  (hdr->proto != PP_HTONS(ETHTYPE_IP)) ||
739  (ethhdr->type != PP_HTONS(ETHTYPE_ARP))) {
741  ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
742  hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type));
743  ETHARP_STATS_INC(etharp.proterr);
744  ETHARP_STATS_INC(etharp.drop);
745  pbuf_free(p);
746  return;
747  }
748  ETHARP_STATS_INC(etharp.recv);
749 
750 #if LWIP_AUTOIP
751  /* We have to check if a host already has configured our random
752  * created link local address and continously check if there is
753  * a host with this IP-address so we can detect collisions */
754  autoip_arp_reply(netif, hdr);
755 #endif /* LWIP_AUTOIP */
756 
757  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
758  * structure packing (not using structure copy which breaks strict-aliasing rules). */
759  IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
760  IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
761 
762  /* this interface is not configured? */
763  if (ip_addr_isany(&netif->ip_addr)) {
764  for_us = 0;
765  } else {
766  /* ARP packet directed to us? */
767  for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr));
768  }
769 
770  /* ARP message directed to us?
771  -> add IP address in ARP cache; assume requester wants to talk to us,
772  can result in directly sending the queued packets for this host.
773  ARP message not directed to us?
774  -> update the source IP address in the cache, if present */
775  update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
776  for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
777 
778  /* now act on the message itself */
779  switch (hdr->opcode) {
780  /* ARP request? */
781  case PP_HTONS(ARP_REQUEST):
782  /* ARP request. If it asked for our address, we send out a
783  * reply. In any case, we time-stamp any existing ARP entry,
784  * and possiby send out an IP packet that was queued on it. */
785 
786  LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
787  /* ARP request for our address? */
788  if (for_us) {
789 
790  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
791  /* Re-use pbuf to send ARP reply.
792  Since we are re-using an existing pbuf, we can't call etharp_raw since
793  that would allocate a new pbuf. */
794  hdr->opcode = htons(ARP_REPLY);
795 
796  IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
797  IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr);
798 
799  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
800  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
801 #if LWIP_AUTOIP
802  /* If we are using Link-Local, all ARP packets that contain a Link-Local
803  * 'sender IP address' MUST be sent using link-layer broadcast instead of
804  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
805  ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
806 #endif /* LWIP_AUTOIP */
807 
808  ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
809 #if LWIP_AUTOIP
810  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
811 #else /* LWIP_AUTOIP */
812  ETHADDR16_COPY(&ethhdr->dest, &hdr->shwaddr);
813 #endif /* LWIP_AUTOIP */
814  ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
815  ETHADDR16_COPY(&ethhdr->src, ethaddr);
816 
817  /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
818  are already correct, we tested that before */
819 #ifdef EBUF_LWIP
820  /*
821  * don't do flip-flop here... do a copy here.
822  * otherwise, we need to handle existing pbuf->eb in ieee80211_output.c
823  */
824 
826  if (q != NULL) {
827  pbuf_copy(q, p);
828  //pbuf_free(p);
829  } else {
830  LWIP_ASSERT("q != NULL", q != NULL);
831  }
832 
833  netif->linkoutput(netif, q);
834  pbuf_free(q);
835 #else
836 
837  /* return ARP reply */
838  netif->linkoutput(netif, p);
839 #endif /* ESF_LWIP */
840  /* we are not configured? */
841  } else if (ip_addr_isany(&netif->ip_addr)) {
842  /* { for_us == 0 and netif->ip_addr.addr == 0 } */
843  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
844  /* request was not directed to us */
845  } else {
846  /* { for_us == 0 and netif->ip_addr.addr != 0 } */
847  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
848  }
849  break;
850  case PP_HTONS(ARP_REPLY):
851  /* ARP reply. We already updated the ARP cache earlier. */
852  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
853 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
854  /* DHCP wants to know about ARP replies from any host with an
855  * IP address also offered to us by the DHCP server. We do not
856  * want to take a duplicate IP address on a single network.
857  * @todo How should we handle redundant (fail-over) interfaces? */
858  dhcp_arp_reply(netif, &sipaddr);
859 #endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
860  break;
861  default:
862  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
863  ETHARP_STATS_INC(etharp.err);
864  break;
865  }
866  /* free ARP packet */
867  pbuf_free(p);
868 }
869 
870 /** Just a small helper function that sends a pbuf to an ethernet address
871  * in the arp_table specified by the index 'arp_idx'.
872  */
874 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
875 {
876  LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
877  arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
878  /* if arp table entry is about to expire: re-request it,
879  but only if its state is ETHARP_STATE_STABLE to prevent flooding the
880  network with ARP requests if this address is used frequently. */
881  if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
882  (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
883  if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
884  arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
885  }
886  }
887 
888  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr),
889  &arp_table[arp_idx].ethaddr);
890 }
891 
892 /**
893  * Resolve and fill-in Ethernet address header for outgoing IP packet.
894  *
895  * For IP multicast and broadcast, corresponding Ethernet addresses
896  * are selected and the packet is transmitted on the link.
897  *
898  * For unicast addresses, the packet is submitted to etharp_query(). In
899  * case the IP address is outside the local network, the IP address of
900  * the gateway is used.
901  *
902  * @param netif The lwIP network interface which the IP packet will be sent on.
903  * @param q The pbuf(s) containing the IP packet to be sent.
904  * @param ipaddr The IP address of the packet destination.
905  *
906  * @return
907  * - ERR_RTE No route to destination (no gateway to external networks),
908  * or the return type of either etharp_query() or etharp_send_ip().
909  */
910 err_t
911 etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
912 {
913  struct eth_addr *dest, mcastaddr;
914 
915  /* make room for Ethernet header - should not fail */
916  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
917  /* bail out */
919  ("etharp_output: could not allocate room for header.\n"));
920  LINK_STATS_INC(link.lenerr);
921  return ERR_BUF;
922  }
923 
924  /* assume unresolved Ethernet address */
925  dest = NULL;
926  /* Determine on destination hardware address. Broadcasts and multicasts
927  * are special, other IP addresses are looked up in the ARP table. */
928 
929  /* broadcast destination IP address? */
930  if (ip_addr_isbroadcast(ipaddr, netif)) {
931  /* broadcast on Ethernet also */
932  dest = (struct eth_addr *)&ethbroadcast;
933  /* multicast destination IP address? */
934  } else if (ip_addr_ismulticast(ipaddr)) {
935  /* Hash IP multicast address to MAC address.*/
936  mcastaddr.addr[0] = 0x01;
937  mcastaddr.addr[1] = 0x00;
938  mcastaddr.addr[2] = 0x5e;
939  mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
940  mcastaddr.addr[4] = ip4_addr3(ipaddr);
941  mcastaddr.addr[5] = ip4_addr4(ipaddr);
942  /* destination Ethernet address is multicast */
943  dest = &mcastaddr;
944  /* unicast destination IP address? */
945  } else {
946  s8_t i;
947  /* outside local network? if so, this can neither be a global broadcast nor
948  a subnet broadcast. */
949  if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&
950  !ip_addr_islinklocal(ipaddr)) {
951 #if LWIP_AUTOIP
952  struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
953  sizeof(struct eth_hdr));
954  /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
955  a link-local source address must always be "directly to its destination
956  on the same physical link. The host MUST NOT send the packet to any
957  router for forwarding". */
958  if (!ip_addr_islinklocal(&iphdr->src))
959 #endif /* LWIP_AUTOIP */
960  {
961  /* interface has default gateway? */
962  if (!ip_addr_isany(&netif->gw)) {
963  /* send to hardware address of default gateway IP address */
964  ipaddr = &(netif->gw);
965  /* no default gateway available */
966  } else {
967  /* no route to destination error (default gateway missing) */
968  return ERR_RTE;
969  }
970  }
971  }
972 #if LWIP_NETIF_HWADDRHINT
973  if (netif->addr_hint != NULL) {
974  /* per-pcb cached entry was given */
975  u8_t etharp_cached_entry = *(netif->addr_hint);
976  if (etharp_cached_entry < ARP_TABLE_SIZE) {
977 #endif /* LWIP_NETIF_HWADDRHINT */
978  if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
979  (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr))) {
980  /* the per-pcb-cached entry is stable and the right one! */
981  ETHARP_STATS_INC(etharp.cachehit);
982  return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
983  }
984 #if LWIP_NETIF_HWADDRHINT
985  }
986  }
987 #endif /* LWIP_NETIF_HWADDRHINT */
988  /* find stable entry: do this here since this is a critical path for
989  throughput and etharp_find_entry() is kind of slow */
990  for (i = 0; i < ARP_TABLE_SIZE; i++) {
991  if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
992  (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr))) {
993  /* found an existing, stable entry */
994  ETHARP_SET_HINT(netif, i);
995  return etharp_output_to_arp_index(netif, q, i);
996  }
997  }
998  /* queue on destination Ethernet address belonging to ipaddr */
999  return etharp_query(netif, ipaddr, q);
1000  }
1001 
1002  /* continuation for multicast/broadcast destinations */
1003  /* obtain source Ethernet address of the given interface */
1004  /* send packet directly on the link */
1005  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
1006 }
1007 
1008 /**
1009  * Send an ARP request for the given IP address and/or queue a packet.
1010  *
1011  * If the IP address was not yet in the cache, a pending ARP cache entry
1012  * is added and an ARP request is sent for the given address. The packet
1013  * is queued on this entry.
1014  *
1015  * If the IP address was already pending in the cache, a new ARP request
1016  * is sent for the given address. The packet is queued on this entry.
1017  *
1018  * If the IP address was already stable in the cache, and a packet is
1019  * given, it is directly sent and no ARP request is sent out.
1020  *
1021  * If the IP address was already stable in the cache, and no packet is
1022  * given, an ARP request is sent out.
1023  *
1024  * @param netif The lwIP network interface on which ipaddr
1025  * must be queried for.
1026  * @param ipaddr The IP address to be resolved.
1027  * @param q If non-NULL, a pbuf that must be delivered to the IP address.
1028  * q is not freed by this function.
1029  *
1030  * @note q must only be ONE packet, not a packet queue!
1031  *
1032  * @return
1033  * - ERR_BUF Could not make room for Ethernet header.
1034  * - ERR_MEM Hardware address unknown, and no more ARP entries available
1035  * to query for address or queue the packet.
1036  * - ERR_MEM Could not queue packet due to memory shortage.
1037  * - ERR_RTE No route to destination (no gateway to external networks).
1038  * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
1039  *
1040  */
1041 err_t
1042 etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
1043 {
1044  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
1045  err_t result = ERR_MEM;
1046  s8_t i; /* ARP entry index */
1047 
1048  /* non-unicast address? */
1049  if (ip_addr_isbroadcast(ipaddr, netif) ||
1050  ip_addr_ismulticast(ipaddr) ||
1051  ip_addr_isany(ipaddr)) {
1052  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
1053  return ERR_ARG;
1054  }
1055 
1056  /* find entry in ARP cache, ask to create entry if queueing packet */
1057  i = find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
1058 
1059  /* could not find or create entry? */
1060  if (i < 0) {
1061  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
1062  if (q) {
1063  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
1064  ETHARP_STATS_INC(etharp.memerr);
1065  }
1066  return (err_t)i;
1067  }
1068 
1069  /* mark a fresh entry as pending (we just sent a request) */
1070  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1071  arp_table[i].state = ETHARP_STATE_PENDING;
1072  }
1073 
1074  /* { i is either a STABLE or (new or existing) PENDING entry } */
1075  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
1076  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1077  (arp_table[i].state >= ETHARP_STATE_STABLE)));
1078 
1079  /* do we have a pending entry? or an implicit query request? */
1080  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
1081  /* try to resolve it; send out ARP request */
1082  result = etharp_request(netif, ipaddr);
1083  if (result != ERR_OK) {
1084  /* ARP request couldn't be sent */
1085  /* We don't re-send arp request in etharp_tmr, but we still queue packets,
1086  since this failure could be temporary, and the next packet calling
1087  etharp_query again could lead to sending the queued packets. */
1088  }
1089  if (q == NULL) {
1090  return result;
1091  }
1092  }
1093 
1094  /* packet given? */
1095  LWIP_ASSERT("q != NULL", q != NULL);
1096  /* stable entry? */
1097  if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1098  /* we have a valid IP->Ethernet address mapping */
1099  ETHARP_SET_HINT(netif, i);
1100  /* send the packet */
1101  result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1102  /* pending entry? (either just created or already pending */
1103  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1104  /* entry is still pending, queue the given packet 'q' */
1105  struct pbuf *p;
1106  int copy_needed = 0;
1107  /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
1108  * to copy the whole queue into a new PBUF_RAM (see bug #11400)
1109  * PBUF_ROMs can be left as they are, since ROM must not get changed. */
1110  p = q;
1111  while (p) {
1112  LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
1113  if(p->type != PBUF_ROM) {
1114  copy_needed = 1;
1115  break;
1116  }
1117  p = p->next;
1118  }
1119  if(copy_needed) {
1120  /* copy the whole packet into new pbufs */
1121  p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
1122  if(p != NULL) {
1123  if (pbuf_copy(p, q) != ERR_OK) {
1124  pbuf_free(p);
1125  p = NULL;
1126  }
1127  }
1128  } else {
1129  /* referencing the old pbuf is enough */
1130  p = q;
1131  pbuf_ref(p);
1132  }
1133  /* packet could be taken over? */
1134  if (p != NULL) {
1135  /* queue packet ... */
1136 #if ARP_QUEUEING
1137  struct etharp_q_entry *new_entry;
1138  /* allocate a new arp queue entry */
1139  new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
1140  if (new_entry != NULL) {
1141  unsigned int qlen = 0;
1142  new_entry->next = 0;
1143  new_entry->p = p;
1144  if(arp_table[i].q != NULL) {
1145  /* queue was already existent, append the new entry to the end */
1146  struct etharp_q_entry *r;
1147  r = arp_table[i].q;
1148  qlen++;
1149  while (r->next != NULL) {
1150  r = r->next;
1151  qlen++;
1152  }
1153  r->next = new_entry;
1154  } else {
1155  /* queue did not exist, first item in queue */
1156  arp_table[i].q = new_entry;
1157  }
1158  if(qlen >= 3) {
1159  struct etharp_q_entry *old;
1160  old = arp_table[i].q;
1161  arp_table[i].q = arp_table[i].q->next;
1162  pbuf_free(old->p);
1163  memp_free(MEM_ARP_QUEUE, old);
1164  }
1165  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1166  result = ERR_OK;
1167  } else {
1168  /* the pool MEMP_ARP_QUEUE is empty */
1169  pbuf_free(p);
1170  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));
1171  result = ERR_MEM;
1172  }
1173 #else /* ARP_QUEUEING */
1174  /* always queue one packet per ARP request only, freeing a previously queued packet */
1175  if (arp_table[i].q != NULL) {
1176  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));
1177  pbuf_free(arp_table[i].q);
1178  }
1179  arp_table[i].q = p;
1180  result = ERR_OK;
1181  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1182 #endif /* ARP_QUEUEING */
1183  } else {
1184  ETHARP_STATS_INC(etharp.memerr);
1185  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));
1186  result = ERR_MEM;
1187  }
1188  }
1189  return result;
1190 }
1191 
1192 /**
1193  * Send a raw ARP packet (opcode and all addresses can be modified)
1194  *
1195  * @param netif the lwip network interface on which to send the ARP packet
1196  * @param ethsrc_addr the source MAC address for the ethernet header
1197  * @param ethdst_addr the destination MAC address for the ethernet header
1198  * @param hwsrc_addr the source MAC address for the ARP protocol header
1199  * @param ipsrc_addr the source IP address for the ARP protocol header
1200  * @param hwdst_addr the destination MAC address for the ARP protocol header
1201  * @param ipdst_addr the destination IP address for the ARP protocol header
1202  * @param opcode the type of the ARP packet
1203  * @return ERR_OK if the ARP packet has been sent
1204  * ERR_MEM if the ARP packet couldn't be allocated
1205  * any other err_t on failure
1206  */
1207 #if !LWIP_AUTOIP
1208 static
1209 #endif /* LWIP_AUTOIP */
1211 etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
1212  const struct eth_addr *ethdst_addr,
1213  const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
1214  const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
1215  const u16_t opcode)
1216 {
1217  struct pbuf *p;
1218  err_t result = ERR_OK;
1219  struct eth_hdr *ethhdr;
1220  struct etharp_hdr *hdr;
1221 #if LWIP_AUTOIP
1222  const u8_t * ethdst_hwaddr;
1223 #endif /* LWIP_AUTOIP */
1224 
1225  /* allocate a pbuf for the outgoing ARP request packet */
1226  p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM);
1227  /* could allocate a pbuf for an ARP request? */
1228  if (p == NULL) {
1230  ("etharp_raw: could not allocate pbuf for ARP request.\n"));
1231  ETHARP_STATS_INC(etharp.memerr);
1232  return ERR_MEM;
1233  }
1234  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
1235  (p->len >= SIZEOF_ETHARP_PACKET));
1236 
1237  ethhdr = (struct eth_hdr *)p->payload;
1238  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
1239  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
1240  hdr->opcode = htons(opcode);
1241 
1242  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1243  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
1244 #if LWIP_AUTOIP
1245  /* If we are using Link-Local, all ARP packets that contain a Link-Local
1246  * 'sender IP address' MUST be sent using link-layer broadcast instead of
1247  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
1248  ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
1249 #endif /* LWIP_AUTOIP */
1250  /* Write the ARP MAC-Addresses */
1251  ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1252  ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1253  /* Write the Ethernet MAC-Addresses */
1254 #if LWIP_AUTOIP
1255  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
1256 #else /* LWIP_AUTOIP */
1257  ETHADDR16_COPY(&ethhdr->dest, ethdst_addr);
1258 #endif /* LWIP_AUTOIP */
1259  ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);
1260  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
1261  * structure packing. */
1262  IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
1263  IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
1264 
1265  hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
1266  hdr->proto = PP_HTONS(ETHTYPE_IP);
1267  /* set hwlen and protolen */
1268  hdr->hwlen = ETHARP_HWADDR_LEN;
1269  hdr->protolen = sizeof(ip_addr_t);
1270 
1271  ethhdr->type = PP_HTONS(ETHTYPE_ARP);
1272  /* send ARP query */
1273  result = netif->linkoutput(netif, p);
1274  ETHARP_STATS_INC(etharp.xmit);
1275  /* free ARP query packet */
1276  pbuf_free(p);
1277  p = NULL;
1278  /* could not allocate pbuf for ARP request */
1279 
1280  return result;
1281 }
1282 
1283 /**
1284  * Send an ARP request packet asking for ipaddr.
1285  *
1286  * @param netif the lwip network interface on which to send the request
1287  * @param ipaddr the IP address for which to ask
1288  * @return ERR_OK if the request has been sent
1289  * ERR_MEM if the ARP packet couldn't be allocated
1290  * any other err_t on failure
1291  */
1292 err_t
1293 etharp_request(struct netif *netif, ip_addr_t *ipaddr)
1294 {
1295  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
1296  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
1297  (struct eth_addr *)netif->hwaddr, &netif->ip_addr, &ethzero,
1298  ipaddr, ARP_REQUEST);
1299 }
1300 #endif /* LWIP_ARP */
1301 
1302 /**
1303  * Process received ethernet frames. Using this function instead of directly
1304  * calling ip_input and passing ARP frames through etharp in ethernetif_input,
1305  * the ARP cache is protected from concurrent access.
1306  *
1307  * @param p the recevied packet, p->payload pointing to the ethernet header
1308  * @param netif the network interface on which the packet was received
1309  */
1310 err_t
1311 ethernet_input(struct pbuf *p, struct netif *netif)
1312 {
1313  struct eth_hdr* ethhdr;
1314  u16_t type;
1315  s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1316 
1317  if (p->len <= SIZEOF_ETH_HDR) {
1318  /* a packet with only an ethernet header (or less) is not valid for us modify by ives at 2014.4.24*/
1319  ETHARP_STATS_INC(etharp.proterr);
1320  ETHARP_STATS_INC(etharp.drop);
1321  goto free_and_return;
1322  }
1323 
1324  /* points to packet payload, which starts with an Ethernet header */
1325  ethhdr = (struct eth_hdr *)p->payload;
1327  ("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",
1328  (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
1329  (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
1330  (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
1331  (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
1332  (unsigned)htons(ethhdr->type)));
1333 
1334  type = ethhdr->type;
1335 #if ETHARP_SUPPORT_VLAN
1336  if (type == PP_HTONS(ETHTYPE_VLAN)) {
1337  struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
1338  if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1339  /* a packet with only an ethernet/vlan header (or less) is not valid for us modify by ives at 2014.4.24*/
1340  ETHARP_STATS_INC(etharp.proterr);
1341  ETHARP_STATS_INC(etharp.drop);
1342  goto free_and_return;
1343  }
1344 #ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */
1345  if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1346  /* silently ignore this packet: not for our VLAN */
1347  pbuf_free(p);
1348  return ERR_OK;
1349  }
1350 #endif /* ETHARP_VLAN_CHECK */
1351  type = vlan->tpid;
1352  ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1353  }
1354 #endif /* ETHARP_SUPPORT_VLAN */
1355 
1356 #if LWIP_ARP_FILTER_NETIF
1357  netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
1358 #endif /* LWIP_ARP_FILTER_NETIF*/
1359 
1360  switch (type) {
1361 #if LWIP_ARP
1362  /* IP packet? */
1363  case PP_HTONS(ETHTYPE_IP):
1364  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1365  goto free_and_return;
1366  }
1367 #if ETHARP_TRUST_IP_MAC
1368  /* update ARP table */
1369  etharp_ip_input(netif, p);
1370 #endif /* ETHARP_TRUST_IP_MAC */
1371  /* skip Ethernet header */
1372  if(pbuf_header(p, -ip_hdr_offset)) {
1373  LWIP_ASSERT("Can't move over header in packet", 0);
1374  goto free_and_return;
1375  } else {
1376  /* pass to IP layer */
1377  ip_input(p, netif);
1378  }
1379  break;
1380 
1381  case PP_HTONS(ETHTYPE_ARP):
1382  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1383  goto free_and_return;
1384  }
1385  /* pass p to ARP module */
1386  etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
1387  break;
1388 #endif /* LWIP_ARP */
1389 #if PPPOE_SUPPORT
1390  case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
1391  pppoe_disc_input(netif, p);
1392  break;
1393 
1394  case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
1395  pppoe_data_input(netif, p);
1396  break;
1397 #endif /* PPPOE_SUPPORT */
1398 
1399  default:
1400  ETHARP_STATS_INC(etharp.proterr);
1401  ETHARP_STATS_INC(etharp.drop);
1402  goto free_and_return;
1403  }
1404 
1405  /* This means the pbuf is freed or consumed,
1406  so the caller doesn't have to free it again */
1407  return ERR_OK;
1408 
1409 free_and_return:
1410  pbuf_free(p);
1411  return ERR_OK;
1412 }
1413 #endif /* LWIP_ARP || LWIP_ETHERNET */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:191
u16_t tot_len
Definition: pbuf.h:90
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
void memp_free(memp_t type, void *mem) ICACHE_FLASH_ATTR
Definition: memp.c:438
struct pbuf * next
Definition: pbuf.h:78
u16_t len
Definition: pbuf.h:93
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) ICACHE_FLASH_ATTR
Definition: pbuf.c:930
#define ip_addr_netcmp(addr1, addr2, mask)
Definition: ip_addr.h:194
#define U16_F
Definition: cc.h:61
signed char s8_t
Definition: cc.h:53
signed short s16_t
Definition: cc.h:55
#define ETHARP_SUPPORT_STATIC_ENTRIES
Definition: opt.h:489
#define NULL
Definition: def.h:47
#define htons(x)
Definition: def.h:81
#define LWIP_DBG_TRACE
Definition: debug.h:56
const ip_addr_t ip_addr_any ICACHE_RODATA_ATTR
Definition: ip_addr.c:44
#define ICACHE_FLASH_ATTR
Definition: c_types.h:99
void * memp_malloc(memp_t type) ICACHE_FLASH_ATTR
Definition: memp.c:393
Definition: pbuf.h:58
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:73
u8_t hwaddr_len
Definition: netif.h:189
struct netif * ip_route(ip_addr_t *dest) ICACHE_FLASH_ATTR
Definition: ip.c:125
Definition: pbuf.h:54
#define PP_HTONS(x)
Definition: def.h:92
#define ip_addr_islinklocal(addr1)
Definition: ip_addr.h:210
#define snmp_delete_arpidx_tree(ni, ip)
Definition: snmp.h:258
ip_addr_t gw
Definition: netif.h:146
#define ERR_RTE
Definition: err.h:56
#define NETIF_FLAG_ETHARP
Definition: netif.h:88
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define ARP_TABLE_SIZE
Definition: opt.h:431
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
#define ERR_OK
Definition: err.h:52
#define IPADDR2_COPY(dest, src)
Definition: ip_addr.h:158
static state_t * state
Definition: aes.c:67
Definition: pbuf.h:76
s8_t err_t
Definition: err.h:47
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define LINK_STATS_INC(x)
Definition: stats.h:227
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:45
Definition: netif.h:139
Definition: pbuf.h:59
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
ip_addr_t ip_addr
Definition: netif.h:144
#define snmp_insert_arpidx_tree(ni, ip)
Definition: snmp.h:257
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
#define ip4_addr3(ipaddr)
Definition: ip_addr.h:222
#define ip_addr_set_zero(ipaddr)
Definition: ip_addr.h:168
#define ETHARP_STATS_INC(x)
Definition: stats.h:219
#define S16_F
Definition: cc.h:60
#define ERR_ARG
Definition: err.h:68
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
Definition: pbuf.c:685
void pbuf_ref(struct pbuf *p) ICACHE_FLASH_ATTR
Definition: pbuf.c:801
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
Definition: ip.h:116
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
Definition: pbuf.c:573
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
err_t ip_input(struct pbuf *p, struct netif *inp) ICACHE_FLASH_ATTR
Definition: ip.c:923
void * payload
Definition: pbuf.h:81
#define ip4_addr2(ipaddr)
Definition: ip_addr.h:221
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
ip_addr_t netmask
Definition: netif.h:145
u8_t type
Definition: pbuf.h:96
#define ip4_addr4(ipaddr)
Definition: ip_addr.h:223
#define ETHARP_DEBUG
Definition: opt.h:1812
#define ip_addr_ismulticast(addr1)
Definition: ip_addr.h:208
netif_linkoutput_fn linkoutput
Definition: netif.h:158
#define X8_F
Definition: arch.h:52
#define ERR_MEM
Definition: err.h:53
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
struct pbuf * pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) ICACHE_FLASH_ATTR
Definition: pbuf.c:234
unsigned short u16_t
Definition: cc.h:54
#define X16_F
Definition: cc.h:62
#define ERR_BUF
Definition: err.h:54