ReactOS  0.4.14-dev-815-ge410a12
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 
59 #if PPPOE_SUPPORT
60 #include "netif/ppp_oe.h"
61 #endif /* PPPOE_SUPPORT */
62 
63 #include <string.h>
64 
65 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
66 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
67 
69 #define LL_MULTICAST_ADDR_0 0x01
70 #define LL_MULTICAST_ADDR_1 0x00
71 #define LL_MULTICAST_ADDR_2 0x5e
72 
73 #if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
74 
79 #define ARP_MAXAGE 240
80 
82 #define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12)
83 
91 #define ARP_MAXPENDING 2
92 
93 #define HWTYPE_ETHERNET 1
94 
95 enum etharp_state {
96  ETHARP_STATE_EMPTY = 0,
97  ETHARP_STATE_PENDING,
98  ETHARP_STATE_STABLE,
99  ETHARP_STATE_STABLE_REREQUESTING
100 #if ETHARP_SUPPORT_STATIC_ENTRIES
101  ,ETHARP_STATE_STATIC
102 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
103 };
104 
105 struct etharp_entry {
106 #if ARP_QUEUEING
107 
108  struct etharp_q_entry *q;
109 #else /* ARP_QUEUEING */
110 
111  struct pbuf *q;
112 #endif /* ARP_QUEUEING */
113  ip_addr_t ipaddr;
114  struct netif *netif;
115  struct eth_addr ethaddr;
116  u8_t state;
117  u8_t ctime;
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 
128 #define ETHARP_FLAG_TRY_HARD 1
129 #define ETHARP_FLAG_FIND_ONLY 2
130 #if ETHARP_SUPPORT_STATIC_ENTRIES
131 #define ETHARP_FLAG_STATIC_ENTRY 4
132 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
133 
134 #if LWIP_NETIF_HWADDRHINT
135 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \
136  *((netif)->addr_hint) = (hint);
137 #else /* LWIP_NETIF_HWADDRHINT */
138 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint))
139 #endif /* LWIP_NETIF_HWADDRHINT */
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 
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 
171 #define free_etharp_q(q) pbuf_free(q)
172 
173 #endif /* ARP_QUEUEING */
174 
176 static void
177 etharp_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_free_entry: 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 #ifdef LWIP_DEBUG
191  /* for debugging, clean out the complete entry */
192  arp_table[i].ctime = 0;
193  arp_table[i].netif = NULL;
194  ip_addr_set_zero(&arp_table[i].ipaddr);
195  arp_table[i].ethaddr = ethzero;
196 #endif /* LWIP_DEBUG */
197 }
198 
205 void
206 etharp_tmr(void)
207 {
208  u8_t i;
209 
210  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
211  /* remove expired entries from the ARP table */
212  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
213  u8_t state = arp_table[i].state;
214  if (state != ETHARP_STATE_EMPTY
216  && (state != ETHARP_STATE_STATIC)
217 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
218  ) {
219  arp_table[i].ctime++;
220  if ((arp_table[i].ctime >= ARP_MAXAGE) ||
221  ((arp_table[i].state == ETHARP_STATE_PENDING) &&
222  (arp_table[i].ctime >= ARP_MAXPENDING))) {
223  /* pending or stable entry has become old! */
224  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
225  arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
226  /* clean up entries that have just been expired */
227  etharp_free_entry(i);
228  }
229  else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
230  /* Reset state to stable, so that the next transmitted packet will
231  re-send an ARP request. */
232  arp_table[i].state = ETHARP_STATE_STABLE;
233  }
234 #if ARP_QUEUEING
235  /* still pending entry? (not expired) */
236  if (arp_table[i].state == ETHARP_STATE_PENDING) {
237  /* resend an ARP query here? */
238  }
239 #endif /* ARP_QUEUEING */
240  }
241  }
242 }
243 
265 static s8_t
266 etharp_find_entry(ip_addr_t *ipaddr, u8_t flags)
267 {
268  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
270  u8_t i = 0, age_pending = 0, age_stable = 0;
271  /* oldest entry with packets on queue */
272  s8_t old_queue = ARP_TABLE_SIZE;
273  /* its age */
274  u8_t age_queue = 0;
275 
282  /* a) in a single search sweep, do all of this
283  * 1) remember the first empty entry (if any)
284  * 2) remember the oldest stable entry (if any)
285  * 3) remember the oldest pending entry without queued packets (if any)
286  * 4) remember the oldest pending entry with queued packets (if any)
287  * 5) search for a matching IP entry, either pending or stable
288  * until 5 matches, or all entries are searched for.
289  */
290 
291  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
292  u8_t state = arp_table[i].state;
293  /* no empty entry found yet and now we do find one? */
294  if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
295  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i));
296  /* remember first empty entry */
297  empty = i;
298  } else if (state != ETHARP_STATE_EMPTY) {
299  LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
300  state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
301  /* if given, does IP address match IP address in ARP entry? */
302  if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
303  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
304  /* found exact IP address match, simply bail out */
305  return i;
306  }
307  /* pending entry? */
308  if (state == ETHARP_STATE_PENDING) {
309  /* pending with queued packets? */
310  if (arp_table[i].q != NULL) {
311  if (arp_table[i].ctime >= age_queue) {
312  old_queue = i;
313  age_queue = arp_table[i].ctime;
314  }
315  } else
316  /* pending without queued packets? */
317  {
318  if (arp_table[i].ctime >= age_pending) {
319  old_pending = i;
320  age_pending = arp_table[i].ctime;
321  }
322  }
323  /* stable entry? */
324  } else if (state >= ETHARP_STATE_STABLE) {
325 #if ETHARP_SUPPORT_STATIC_ENTRIES
326  /* don't record old_stable for static entries since they never expire */
327  if (state < ETHARP_STATE_STATIC)
328 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
329  {
330  /* remember entry with oldest stable entry in oldest, its age in maxtime */
331  if (arp_table[i].ctime >= age_stable) {
332  old_stable = i;
333  age_stable = arp_table[i].ctime;
334  }
335  }
336  }
337  }
338  }
339  /* { we have no match } => try to create a new entry */
340 
341  /* don't create new entry, only search? */
342  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
343  /* or no empty entry found and not allowed to recycle? */
344  ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
345  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
346  return (s8_t)ERR_MEM;
347  }
348 
349  /* b) choose the least destructive entry to recycle:
350  * 1) empty entry
351  * 2) oldest stable entry
352  * 3) oldest pending entry without queued packets
353  * 4) oldest pending entry with queued packets
354  *
355  * { ETHARP_FLAG_TRY_HARD is set at this point }
356  */
357 
358  /* 1) empty entry available? */
359  if (empty < ARP_TABLE_SIZE) {
360  i = empty;
361  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
362  } else {
363  /* 2) found recyclable stable entry? */
364  if (old_stable < ARP_TABLE_SIZE) {
365  /* recycle oldest stable*/
366  i = old_stable;
367  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
368  /* no queued packets should exist on stable entries */
369  LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
370  /* 3) found recyclable pending entry without queued packets? */
371  } else if (old_pending < ARP_TABLE_SIZE) {
372  /* recycle oldest pending */
373  i = old_pending;
374  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
375  /* 4) found recyclable pending entry with queued packets? */
376  } else if (old_queue < ARP_TABLE_SIZE) {
377  /* recycle oldest pending (queued packets are free in etharp_free_entry) */
378  i = old_queue;
379  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)));
380  /* no empty or recyclable entries found */
381  } else {
382  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
383  return (s8_t)ERR_MEM;
384  }
385 
386  /* { empty or recyclable entry found } */
387  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
388  etharp_free_entry(i);
389  }
390 
391  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
392  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
393  arp_table[i].state == ETHARP_STATE_EMPTY);
394 
395  /* IP address given? */
396  if (ipaddr != NULL) {
397  /* set IP address */
398  ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
399  }
400  arp_table[i].ctime = 0;
401  return (err_t)i;
402 }
403 
414 static err_t
415 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
416 {
417  struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
418 
419  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
420  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
421  ETHADDR32_COPY(&ethhdr->dest, dst);
422  ETHADDR16_COPY(&ethhdr->src, src);
423  ethhdr->type = PP_HTONS(ETHTYPE_IP);
424  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
425  /* send the packet */
426  return netif->linkoutput(netif, p);
427 }
428 
447 static err_t
448 etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
449 {
450  s8_t i;
451  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
452  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",
453  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
454  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
455  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
456  /* non-unicast address? */
457  if (ip_addr_isany(ipaddr) ||
458  ip_addr_isbroadcast(ipaddr, netif) ||
459  ip_addr_ismulticast(ipaddr)) {
460  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
461  return ERR_ARG;
462  }
463  /* find or create ARP entry */
464  i = etharp_find_entry(ipaddr, flags);
465  /* bail out if no entry could be found */
466  if (i < 0) {
467  return (err_t)i;
468  }
469 
470 #if ETHARP_SUPPORT_STATIC_ENTRIES
471  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
472  /* record static type */
473  arp_table[i].state = ETHARP_STATE_STATIC;
474  } else
475 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
476  {
477  /* mark it stable */
478  arp_table[i].state = ETHARP_STATE_STABLE;
479  }
480 
481  /* record network interface */
482  arp_table[i].netif = netif;
483  /* insert in SNMP ARP index tree */
484  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);
485 
486  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
487  /* update address */
488  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
489  /* reset time stamp */
490  arp_table[i].ctime = 0;
491  /* this is where we will send out queued packets! */
492 #if ARP_QUEUEING
493  while (arp_table[i].q != NULL) {
494  struct pbuf *p;
495  /* remember remainder of queue */
496  struct etharp_q_entry *q = arp_table[i].q;
497  /* pop first item off the queue */
498  arp_table[i].q = q->next;
499  /* get the packet pointer */
500  p = q->p;
501  /* now queue entry can be freed */
502  memp_free(MEMP_ARP_QUEUE, q);
503 #else /* ARP_QUEUEING */
504  if (arp_table[i].q != NULL) {
505  struct pbuf *p = arp_table[i].q;
506  arp_table[i].q = NULL;
507 #endif /* ARP_QUEUEING */
508  /* send the queued IP packet */
509  etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
510  /* free the queued IP packet */
511  pbuf_free(p);
512  }
513  return ERR_OK;
514 }
515 
516 #if ETHARP_SUPPORT_STATIC_ENTRIES
517 
525 err_t
526 etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
527 {
528  struct netif *netif;
529  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",
530  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
531  ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
532  ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
533 
534  netif = ip_route(ipaddr);
535  if (netif == NULL) {
536  return ERR_RTE;
537  }
538 
539  return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
540 }
541 
550 err_t
551 etharp_remove_static_entry(ip_addr_t *ipaddr)
552 {
553  s8_t i;
554  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
555  ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
556 
557  /* find or create ARP entry */
558  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
559  /* bail out if no entry could be found */
560  if (i < 0) {
561  return (err_t)i;
562  }
563 
564  if (arp_table[i].state != ETHARP_STATE_STATIC) {
565  /* entry wasn't a static entry, cannot remove it */
566  return ERR_ARG;
567  }
568  /* entry found, free it */
569  etharp_free_entry(i);
570  return ERR_OK;
571 }
572 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
573 
579 void etharp_cleanup_netif(struct netif *netif)
580 {
581  u8_t i;
582 
583  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
584  u8_t state = arp_table[i].state;
585  if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
586  etharp_free_entry(i);
587  }
588  }
589 }
590 
602 s8_t
603 etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
604  struct eth_addr **eth_ret, ip_addr_t **ip_ret)
605 {
606  s8_t i;
607 
608  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
609  eth_ret != NULL && ip_ret != NULL);
610 
612 
613  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
614  if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
615  *eth_ret = &arp_table[i].ethaddr;
616  *ip_ret = &arp_table[i].ipaddr;
617  return i;
618  }
619  return -1;
620 }
621 
622 #if ETHARP_TRUST_IP_MAC
623 
638 static void
639 etharp_ip_input(struct netif *netif, struct pbuf *p)
640 {
641  struct eth_hdr *ethhdr;
642  struct ip_hdr *iphdr;
643  ip_addr_t iphdr_src;
644  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
645 
646  /* Only insert an entry if the source IP address of the
647  incoming IP packet comes from a host on the local network. */
648  ethhdr = (struct eth_hdr *)p->payload;
649  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
650 #if ETHARP_SUPPORT_VLAN
651  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
652  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
653  }
654 #endif /* ETHARP_SUPPORT_VLAN */
655 
656  ip_addr_copy(iphdr_src, iphdr->src);
657 
658  /* source is not on the local network? */
659  if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) {
660  /* do nothing */
661  return;
662  }
663 
664  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
665  /* update the source IP address in the cache, if present */
666  /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk
667  * back soon (for example, if the destination IP address is ours. */
668  etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
669 }
670 #endif /* ETHARP_TRUST_IP_MAC */
671 
687 static void
688 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
689 {
690  struct etharp_hdr *hdr;
691  struct eth_hdr *ethhdr;
692  /* these are aligned properly, whereas the ARP header fields might not be */
693  ip_addr_t sipaddr, dipaddr;
694  u8_t for_us;
695 #if LWIP_AUTOIP
696  const u8_t * ethdst_hwaddr;
697 #endif /* LWIP_AUTOIP */
698 
699  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
700 
701  /* drop short ARP packets: we have to check for p->len instead of p->tot_len here
702  since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
703  if (p->len < SIZEOF_ETHARP_PACKET) {
705  ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len,
706  (s16_t)SIZEOF_ETHARP_PACKET));
707  ETHARP_STATS_INC(etharp.lenerr);
708  ETHARP_STATS_INC(etharp.drop);
709  pbuf_free(p);
710  return;
711  }
712 
713  ethhdr = (struct eth_hdr *)p->payload;
714  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
715 #if ETHARP_SUPPORT_VLAN
716  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
717  hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
718  }
719 #endif /* ETHARP_SUPPORT_VLAN */
720 
721  /* RFC 826 "Packet Reception": */
722  if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
723  (hdr->hwlen != ETHARP_HWADDR_LEN) ||
724  (hdr->protolen != sizeof(ip_addr_t)) ||
725  (hdr->proto != PP_HTONS(ETHTYPE_IP))) {
727  ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
728  hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
729  ETHARP_STATS_INC(etharp.proterr);
730  ETHARP_STATS_INC(etharp.drop);
731  pbuf_free(p);
732  return;
733  }
734  ETHARP_STATS_INC(etharp.recv);
735 
736 #if LWIP_AUTOIP
737  /* We have to check if a host already has configured our random
738  * created link local address and continously check if there is
739  * a host with this IP-address so we can detect collisions */
740  autoip_arp_reply(netif, hdr);
741 #endif /* LWIP_AUTOIP */
742 
743  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
744  * structure packing (not using structure copy which breaks strict-aliasing rules). */
745  IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
746  IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
747 
748  /* this interface is not configured? */
749  if (ip_addr_isany(&netif->ip_addr)) {
750  for_us = 0;
751  } else {
752  /* ARP packet directed to us? */
753  for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr));
754  }
755 
756  /* ARP message directed to us?
757  -> add IP address in ARP cache; assume requester wants to talk to us,
758  can result in directly sending the queued packets for this host.
759  ARP message not directed to us?
760  -> update the source IP address in the cache, if present */
761  etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
762  for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
763 
764  /* now act on the message itself */
765  switch (hdr->opcode) {
766  /* ARP request? */
767  case PP_HTONS(ARP_REQUEST):
768  /* ARP request. If it asked for our address, we send out a
769  * reply. In any case, we time-stamp any existing ARP entry,
770  * and possiby send out an IP packet that was queued on it. */
771 
772  LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
773  /* ARP request for our address? */
774  if (for_us) {
775 
776  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
777  /* Re-use pbuf to send ARP reply.
778  Since we are re-using an existing pbuf, we can't call etharp_raw since
779  that would allocate a new pbuf. */
780  hdr->opcode = htons(ARP_REPLY);
781 
782  IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
783  IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr);
784 
785  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
786  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
787 #if LWIP_AUTOIP
788  /* If we are using Link-Local, all ARP packets that contain a Link-Local
789  * 'sender IP address' MUST be sent using link-layer broadcast instead of
790  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
791  ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
792 #endif /* LWIP_AUTOIP */
793 
794  ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
795 #if LWIP_AUTOIP
796  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
797 #else /* LWIP_AUTOIP */
798  ETHADDR16_COPY(&ethhdr->dest, &hdr->shwaddr);
799 #endif /* LWIP_AUTOIP */
800  ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
801  ETHADDR16_COPY(&ethhdr->src, ethaddr);
802 
803  /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
804  are already correct, we tested that before */
805 
806  /* return ARP reply */
807  netif->linkoutput(netif, p);
808  /* we are not configured? */
809  } else if (ip_addr_isany(&netif->ip_addr)) {
810  /* { for_us == 0 and netif->ip_addr.addr == 0 } */
811  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
812  /* request was not directed to us */
813  } else {
814  /* { for_us == 0 and netif->ip_addr.addr != 0 } */
815  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
816  }
817  break;
818  case PP_HTONS(ARP_REPLY):
819  /* ARP reply. We already updated the ARP cache earlier. */
820  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
821 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
822  /* DHCP wants to know about ARP replies from any host with an
823  * IP address also offered to us by the DHCP server. We do not
824  * want to take a duplicate IP address on a single network.
825  * @todo How should we handle redundant (fail-over) interfaces? */
826  dhcp_arp_reply(netif, &sipaddr);
827 #endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
828  break;
829  default:
830  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
831  ETHARP_STATS_INC(etharp.err);
832  break;
833  }
834  /* free ARP packet */
835  pbuf_free(p);
836 }
837 
841 static err_t
842 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
843 {
844  LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
845  arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
846  /* if arp table entry is about to expire: re-request it,
847  but only if its state is ETHARP_STATE_STABLE to prevent flooding the
848  network with ARP requests if this address is used frequently. */
849  if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
850  (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
851  if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
852  arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
853  }
854  }
855 
856  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr),
857  &arp_table[arp_idx].ethaddr);
858 }
859 
878 err_t
879 etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
880 {
881  struct eth_addr *dest;
882  struct eth_addr mcastaddr;
883  ip_addr_t *dst_addr = ipaddr;
884 
885  LWIP_ASSERT("netif != NULL", netif != NULL);
886  LWIP_ASSERT("q != NULL", q != NULL);
887  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
888 
889  /* make room for Ethernet header - should not fail */
890  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
891  /* bail out */
893  ("etharp_output: could not allocate room for header.\n"));
894  LINK_STATS_INC(link.lenerr);
895  return ERR_BUF;
896  }
897 
898  /* Determine on destination hardware address. Broadcasts and multicasts
899  * are special, other IP addresses are looked up in the ARP table. */
900 
901  /* broadcast destination IP address? */
902  if (ip_addr_isbroadcast(ipaddr, netif)) {
903  /* broadcast on Ethernet also */
904  dest = (struct eth_addr *)&ethbroadcast;
905  /* multicast destination IP address? */
906  } else if (ip_addr_ismulticast(ipaddr)) {
907  /* Hash IP multicast address to MAC address.*/
908  mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
909  mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
910  mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
911  mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
912  mcastaddr.addr[4] = ip4_addr3(ipaddr);
913  mcastaddr.addr[5] = ip4_addr4(ipaddr);
914  /* destination Ethernet address is multicast */
915  dest = &mcastaddr;
916  /* unicast destination IP address? */
917  } else {
918  s8_t i;
919  /* outside local network? if so, this can neither be a global broadcast nor
920  a subnet broadcast. */
921  if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&
922  !ip_addr_islinklocal(ipaddr)) {
923 #if LWIP_AUTOIP
924  struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
925  sizeof(struct eth_hdr));
926  /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
927  a link-local source address must always be "directly to its destination
928  on the same physical link. The host MUST NOT send the packet to any
929  router for forwarding". */
930  if (!ip_addr_islinklocal(&iphdr->src))
931 #endif /* LWIP_AUTOIP */
932  {
933  /* interface has default gateway? */
934  if (!ip_addr_isany(&netif->gw)) {
935  /* send to hardware address of default gateway IP address */
936  dst_addr = &(netif->gw);
937  /* no default gateway available */
938  } else {
939  /* no route to destination error (default gateway missing) */
940  return ERR_RTE;
941  }
942  }
943  }
944 #if LWIP_NETIF_HWADDRHINT
945  if (netif->addr_hint != NULL) {
946  /* per-pcb cached entry was given */
947  u8_t etharp_cached_entry = *(netif->addr_hint);
948  if (etharp_cached_entry < ARP_TABLE_SIZE) {
949 #endif /* LWIP_NETIF_HWADDRHINT */
950  if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
951  (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
952  /* the per-pcb-cached entry is stable and the right one! */
953  ETHARP_STATS_INC(etharp.cachehit);
954  return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
955  }
956 #if LWIP_NETIF_HWADDRHINT
957  }
958  }
959 #endif /* LWIP_NETIF_HWADDRHINT */
960 
961  /* find stable entry: do this here since this is a critical path for
962  throughput and etharp_find_entry() is kind of slow */
963  for (i = 0; i < ARP_TABLE_SIZE; i++) {
964  if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
965  (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
966  /* found an existing, stable entry */
967  ETHARP_SET_HINT(netif, i);
968  return etharp_output_to_arp_index(netif, q, i);
969  }
970  }
971  /* no stable entry found, use the (slower) query function:
972  queue on destination Ethernet address belonging to ipaddr */
973  return etharp_query(netif, dst_addr, q);
974  }
975 
976  /* continuation for multicast/broadcast destinations */
977  /* obtain source Ethernet address of the given interface */
978  /* send packet directly on the link */
979  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
980 }
981 
1015 err_t
1016 etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
1017 {
1018  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
1019  err_t result = ERR_MEM;
1020  s8_t i; /* ARP entry index */
1021 
1022  /* non-unicast address? */
1023  if (ip_addr_isbroadcast(ipaddr, netif) ||
1024  ip_addr_ismulticast(ipaddr) ||
1025  ip_addr_isany(ipaddr)) {
1026  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
1027  return ERR_ARG;
1028  }
1029 
1030  /* find entry in ARP cache, ask to create entry if queueing packet */
1031  i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
1032 
1033  /* could not find or create entry? */
1034  if (i < 0) {
1035  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
1036  if (q) {
1037  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
1038  ETHARP_STATS_INC(etharp.memerr);
1039  }
1040  return (err_t)i;
1041  }
1042 
1043  /* mark a fresh entry as pending (we just sent a request) */
1044  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1045  arp_table[i].state = ETHARP_STATE_PENDING;
1046  }
1047 
1048  /* { i is either a STABLE or (new or existing) PENDING entry } */
1049  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
1050  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1051  (arp_table[i].state >= ETHARP_STATE_STABLE)));
1052 
1053  /* do we have a pending entry? or an implicit query request? */
1054  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
1055  /* try to resolve it; send out ARP request */
1056  result = etharp_request(netif, ipaddr);
1057  if (result != ERR_OK) {
1058  /* ARP request couldn't be sent */
1059  /* We don't re-send arp request in etharp_tmr, but we still queue packets,
1060  since this failure could be temporary, and the next packet calling
1061  etharp_query again could lead to sending the queued packets. */
1062  }
1063  if (q == NULL) {
1064  return result;
1065  }
1066  }
1067 
1068  /* packet given? */
1069  LWIP_ASSERT("q != NULL", q != NULL);
1070  /* stable entry? */
1071  if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1072  /* we have a valid IP->Ethernet address mapping */
1073  ETHARP_SET_HINT(netif, i);
1074  /* send the packet */
1075  result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1076  /* pending entry? (either just created or already pending */
1077  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1078  /* entry is still pending, queue the given packet 'q' */
1079  struct pbuf *p;
1080  int copy_needed = 0;
1081  /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
1082  * to copy the whole queue into a new PBUF_RAM (see bug #11400)
1083  * PBUF_ROMs can be left as they are, since ROM must not get changed. */
1084  p = q;
1085  while (p) {
1086  LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
1087  if(p->type != PBUF_ROM) {
1088  copy_needed = 1;
1089  break;
1090  }
1091  p = p->next;
1092  }
1093  if(copy_needed) {
1094  /* copy the whole packet into new pbufs */
1095  p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
1096  if(p != NULL) {
1097  if (pbuf_copy(p, q) != ERR_OK) {
1098  pbuf_free(p);
1099  p = NULL;
1100  }
1101  }
1102  } else {
1103  /* referencing the old pbuf is enough */
1104  p = q;
1105  pbuf_ref(p);
1106  }
1107  /* packet could be taken over? */
1108  if (p != NULL) {
1109  /* queue packet ... */
1110 #if ARP_QUEUEING
1111  struct etharp_q_entry *new_entry;
1112  /* allocate a new arp queue entry */
1113  new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
1114  if (new_entry != NULL) {
1115  new_entry->next = 0;
1116  new_entry->p = p;
1117  if(arp_table[i].q != NULL) {
1118  /* queue was already existent, append the new entry to the end */
1119  struct etharp_q_entry *r;
1120  r = arp_table[i].q;
1121  while (r->next != NULL) {
1122  r = r->next;
1123  }
1124  r->next = new_entry;
1125  } else {
1126  /* queue did not exist, first item in queue */
1127  arp_table[i].q = new_entry;
1128  }
1129  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1130  result = ERR_OK;
1131  } else {
1132  /* the pool MEMP_ARP_QUEUE is empty */
1133  pbuf_free(p);
1134  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));
1135  result = ERR_MEM;
1136  }
1137 #else /* ARP_QUEUEING */
1138  /* always queue one packet per ARP request only, freeing a previously queued packet */
1139  if (arp_table[i].q != NULL) {
1140  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));
1141  pbuf_free(arp_table[i].q);
1142  }
1143  arp_table[i].q = p;
1144  result = ERR_OK;
1145  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
1146 #endif /* ARP_QUEUEING */
1147  } else {
1148  ETHARP_STATS_INC(etharp.memerr);
1149  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));
1150  result = ERR_MEM;
1151  }
1152  }
1153  return result;
1154 }
1155 
1171 #if !LWIP_AUTOIP
1172 static
1173 #endif /* LWIP_AUTOIP */
1174 err_t
1175 etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
1176  const struct eth_addr *ethdst_addr,
1177  const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
1178  const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
1179  const u16_t opcode)
1180 {
1181  struct pbuf *p;
1182  err_t result = ERR_OK;
1183  struct eth_hdr *ethhdr;
1184  struct etharp_hdr *hdr;
1185 #if LWIP_AUTOIP
1186  const u8_t * ethdst_hwaddr;
1187 #endif /* LWIP_AUTOIP */
1188 
1189  LWIP_ASSERT("netif != NULL", netif != NULL);
1190 
1191  /* allocate a pbuf for the outgoing ARP request packet */
1192  p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM);
1193  /* could allocate a pbuf for an ARP request? */
1194  if (p == NULL) {
1196  ("etharp_raw: could not allocate pbuf for ARP request.\n"));
1197  ETHARP_STATS_INC(etharp.memerr);
1198  return ERR_MEM;
1199  }
1200  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
1201  (p->len >= SIZEOF_ETHARP_PACKET));
1202 
1203  ethhdr = (struct eth_hdr *)p->payload;
1204  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
1205  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
1206  hdr->opcode = htons(opcode);
1207 
1208  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1209  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
1210 #if LWIP_AUTOIP
1211  /* If we are using Link-Local, all ARP packets that contain a Link-Local
1212  * 'sender IP address' MUST be sent using link-layer broadcast instead of
1213  * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
1214  ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
1215 #endif /* LWIP_AUTOIP */
1216  /* Write the ARP MAC-Addresses */
1217  ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1218  ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1219  /* Write the Ethernet MAC-Addresses */
1220 #if LWIP_AUTOIP
1221  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
1222 #else /* LWIP_AUTOIP */
1223  ETHADDR16_COPY(&ethhdr->dest, ethdst_addr);
1224 #endif /* LWIP_AUTOIP */
1225  ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);
1226  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
1227  * structure packing. */
1228  IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
1229  IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
1230 
1231  hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
1232  hdr->proto = PP_HTONS(ETHTYPE_IP);
1233  /* set hwlen and protolen */
1234  hdr->hwlen = ETHARP_HWADDR_LEN;
1235  hdr->protolen = sizeof(ip_addr_t);
1236 
1237  ethhdr->type = PP_HTONS(ETHTYPE_ARP);
1238  /* send ARP query */
1239  result = netif->linkoutput(netif, p);
1240  ETHARP_STATS_INC(etharp.xmit);
1241  /* free ARP query packet */
1242  pbuf_free(p);
1243  p = NULL;
1244  /* could not allocate pbuf for ARP request */
1245 
1246  return result;
1247 }
1248 
1258 err_t
1259 etharp_request(struct netif *netif, ip_addr_t *ipaddr)
1260 {
1261  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
1262  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
1263  (struct eth_addr *)netif->hwaddr, &netif->ip_addr, &ethzero,
1264  ipaddr, ARP_REQUEST);
1265 }
1266 #endif /* LWIP_ARP */
1267 
1276 err_t
1277 ethernet_input(struct pbuf *p, struct netif *netif)
1278 {
1279  struct eth_hdr* ethhdr;
1280  u16_t type;
1281 #if LWIP_ARP || ETHARP_SUPPORT_VLAN
1282  s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1283 #endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
1284 
1285  if (p->len <= SIZEOF_ETH_HDR) {
1286  /* a packet with only an ethernet header (or less) is not valid for us */
1287  ETHARP_STATS_INC(etharp.proterr);
1288  ETHARP_STATS_INC(etharp.drop);
1289  goto free_and_return;
1290  }
1291 
1292  /* points to packet payload, which starts with an Ethernet header */
1293  ethhdr = (struct eth_hdr *)p->payload;
1295  ("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",
1296  (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
1297  (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
1298  (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
1299  (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
1300  (unsigned)htons(ethhdr->type)));
1301 
1302  type = ethhdr->type;
1303 #if ETHARP_SUPPORT_VLAN
1304  if (type == PP_HTONS(ETHTYPE_VLAN)) {
1305  struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
1306  if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1307  /* a packet with only an ethernet/vlan header (or less) is not valid for us */
1308  ETHARP_STATS_INC(etharp.proterr);
1309  ETHARP_STATS_INC(etharp.drop);
1310  goto free_and_return;
1311  }
1312 #if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
1313 #ifdef ETHARP_VLAN_CHECK_FN
1314  if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
1315 #elif defined(ETHARP_VLAN_CHECK)
1316  if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1317 #endif
1318  /* silently ignore this packet: not for our VLAN */
1319  pbuf_free(p);
1320  return ERR_OK;
1321  }
1322 #endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
1323  type = vlan->tpid;
1324  ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1325  }
1326 #endif /* ETHARP_SUPPORT_VLAN */
1327 
1328 #if LWIP_ARP_FILTER_NETIF
1329  netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
1330 #endif /* LWIP_ARP_FILTER_NETIF*/
1331 
1332  if (ethhdr->dest.addr[0] & 1) {
1333  /* this might be a multicast or broadcast packet */
1334  if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
1335  if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
1336  (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
1337  /* mark the pbuf as link-layer multicast */
1338  p->flags |= PBUF_FLAG_LLMCAST;
1339  }
1340  } else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
1341  /* mark the pbuf as link-layer broadcast */
1342  p->flags |= PBUF_FLAG_LLBCAST;
1343  }
1344  }
1345 
1346  switch (type) {
1347 #if LWIP_ARP
1348  /* IP packet? */
1349  case PP_HTONS(ETHTYPE_IP):
1350  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1351  goto free_and_return;
1352  }
1353 #if ETHARP_TRUST_IP_MAC
1354  /* update ARP table */
1355  etharp_ip_input(netif, p);
1356 #endif /* ETHARP_TRUST_IP_MAC */
1357  /* skip Ethernet header */
1358  if(pbuf_header(p, -ip_hdr_offset)) {
1359  LWIP_ASSERT("Can't move over header in packet", 0);
1360  goto free_and_return;
1361  } else {
1362  /* pass to IP layer */
1363  ip_input(p, netif);
1364  }
1365  break;
1366 
1367  case PP_HTONS(ETHTYPE_ARP):
1368  if (!(netif->flags & NETIF_FLAG_ETHARP)) {
1369  goto free_and_return;
1370  }
1371  /* pass p to ARP module */
1372  etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
1373  break;
1374 #endif /* LWIP_ARP */
1375 #if PPPOE_SUPPORT
1376  case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
1377  pppoe_disc_input(netif, p);
1378  break;
1379 
1380  case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
1381  pppoe_data_input(netif, p);
1382  break;
1383 #endif /* PPPOE_SUPPORT */
1384 
1385  default:
1386  ETHARP_STATS_INC(etharp.proterr);
1387  ETHARP_STATS_INC(etharp.drop);
1388  goto free_and_return;
1389  }
1390 
1391  /* This means the pbuf is freed or consumed,
1392  so the caller doesn't have to free it again */
1393  return ERR_OK;
1394 
1395 free_and_return:
1396  pbuf_free(p);
1397  return ERR_OK;
1398 }
1399 #endif /* LWIP_ARP || LWIP_ETHERNET */
#define IPADDR2_COPY(dest, src)
Definition: ip_addr.h:158
#define ip_addr_islinklocal(addr1)
Definition: ip_addr.h:210
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:190
#define ERR_ARG
Definition: err.h:70
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
char hdr[14]
Definition: iptest.cpp:33
#define ERR_RTE
Definition: err.h:56
#define snmp_insert_arpidx_tree(ni, ip)
Definition: snmp.h:257
#define S16_F
Definition: cc.h:37
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
#define ETHARP_SUPPORT_STATIC_ENTRIES
Definition: opt.h:493
#define ip4_addr2(ipaddr)
Definition: ip_addr.h:221
err_t ip_input(struct pbuf *p, struct netif *inp)
Definition: ip.c:305
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define PBUF_FLAG_LLBCAST
Definition: pbuf.h:73
#define snmp_delete_arpidx_tree(ni, ip)
Definition: snmp.h:258
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
Definition: pbuf.h:58
struct netif * ip_route(ip_addr_t *dest)
Definition: ip.c:124
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
u8_t hwaddr_len
Definition: netif.h:188
smooth NULL
Definition: ftsmooth.c:416
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
Definition: pbuf.h:54
s8_t err_t
Definition: err.h:47
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:852
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define PP_HTONS(x)
Definition: def.h:88
#define ip_addr_set_zero(ipaddr)
Definition: ip_addr.h:168
ip_addr_t gw
Definition: netif.h:143
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
#define NETIF_FLAG_ETHARP
Definition: netif.h:88
#define U16_F
Definition: cc.h:36
#define ARP_TABLE_SIZE
Definition: opt.h:433
#define ERR_OK
Definition: err.h:52
__u16 ctime
Definition: mkdosfs.c:362
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define ip_addr_ismulticast(addr1)
Definition: ip_addr.h:208
Definition: pbuf.h:79
#define ip4_addr3(ipaddr)
Definition: ip_addr.h:222
#define LINK_STATS_INC(x)
Definition: stats.h:227
#define X16_F
Definition: cc.h:38
Definition: netif.h:136
Definition: pbuf.h:59
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLbitfield flags
Definition: glext.h:7161
ip_addr_t ip_addr
Definition: netif.h:141
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:46
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
void pbuf_ref(struct pbuf *p)
Definition: pbuf.c:723
#define PBUF_FLAG_LLMCAST
Definition: pbuf.h:75
static int state
Definition: maze.c:121
GLenum src
Definition: glext.h:6340
signed char s8_t
Definition: cc.h:28
#define ETHARP_STATS_INC(x)
Definition: stats.h:219
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:74
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
Definition: ip.h:116
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:47
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define ERR_MEM
Definition: fontsub.h:52
#define ERR_BUF
Definition: err.h:54
GLenum GLenum dst
Definition: glext.h:6340
unsigned char u8_t
Definition: cc.h:23
#define LWIP_DBG_TRACE
Definition: debug.h:57
BOOL empty
Definition: button.c:170
#define ip4_addr4(ipaddr)
Definition: ip_addr.h:223
ip_addr_t netmask
Definition: netif.h:142
static char * dest
Definition: rtl.c:135
unsigned short u16_t
Definition: cc.h:24
const WCHAR * link
Definition: db.cpp:989
#define ETHARP_DEBUG
Definition: opt.h:1898
void * memp_malloc(memp_t type)
Definition: memp.c:390
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
GLuint64EXT * result
Definition: glext.h:11304
netif_linkoutput_fn linkoutput
Definition: netif.h:155
#define X8_F
Definition: arch.h:52
#define ip_addr_netcmp(addr1, addr2, mask)
Definition: ip_addr.h:194
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
signed short s16_t
Definition: cc.h:29