Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


a few fixs
[palacios.releases.git] / geekos / src / lwip / netif / etharp.c
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_query(our_netif, its_ip_addr, NULL) upon
12  * address change.
13  */
14
15 /*
16  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
17  * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
18  * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without modification,
22  * are permitted provided that the following conditions are met:
23  *
24  * 1. Redistributions of source code must retain the above copyright notice,
25  *    this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright notice,
27  *    this list of conditions and the following disclaimer in the documentation
28  *    and/or other materials provided with the distribution.
29  * 3. The name of the author may not be used to endorse or promote products
30  *    derived from this software without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
33  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
34  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
35  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
37  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
41  * OF SUCH DAMAGE.
42  *
43  * This file is part of the lwIP TCP/IP stack.
44  *
45  */
46  
47 #include "lwip/opt.h"
48
49 #if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
50
51 #include "lwip/inet.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 /** the time an ARP entry stays valid after its last update,
66  *  for ARP_TMR_INTERVAL = 5000, this is
67  *  (240 * 5) seconds = 20 minutes.
68  */
69 #define ARP_MAXAGE 240
70 /** the time an ARP entry stays pending after first request,
71  *  for ARP_TMR_INTERVAL = 5000, this is
72  *  (2 * 5) seconds = 10 seconds.
73  * 
74  *  @internal Keep this number at least 2, otherwise it might
75  *  run out instantly if the timeout occurs directly after a request.
76  */
77 #define ARP_MAXPENDING 2
78
79 #define HWTYPE_ETHERNET 1
80
81 #define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8)
82 #define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff)
83
84 #define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))
85 #define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))
86
87 enum etharp_state {
88   ETHARP_STATE_EMPTY = 0,
89   ETHARP_STATE_PENDING,
90   ETHARP_STATE_STABLE
91 };
92
93 struct etharp_entry {
94 #if ARP_QUEUEING
95   /** 
96    * Pointer to queue of pending outgoing packets on this ARP entry.
97    */
98   struct etharp_q_entry *q;
99 #endif
100   struct ip_addr ipaddr;
101   struct eth_addr ethaddr;
102   enum etharp_state state;
103   u8_t ctime;
104   struct netif *netif;
105 };
106
107 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
108 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
109 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
110 #if !LWIP_NETIF_HWADDRHINT
111 static u8_t etharp_cached_entry;
112 #endif
113
114 /**
115  * Try hard to create a new entry - we want the IP address to appear in
116  * the cache (even if this means removing an active entry or so). */
117 #define ETHARP_TRY_HARD 1
118 #define ETHARP_FIND_ONLY  2
119
120 #if LWIP_NETIF_HWADDRHINT
121 #define NETIF_SET_HINT(netif, hint)  if (((netif) != NULL) && ((netif)->addr_hint != NULL))  \
122                                       *((netif)->addr_hint) = (hint);
123 static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif);
124 #else /* LWIP_NETIF_HWADDRHINT */
125 static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);
126 #endif /* LWIP_NETIF_HWADDRHINT */
127
128 static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
129
130
131 /* Some checks, instead of etharp_init(): */
132 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
133   #error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h"
134 #endif
135
136
137 #if ARP_QUEUEING
138 /**
139  * Free a complete queue of etharp entries
140  *
141  * @param q a qeueue of etharp_q_entry's to free
142  */
143 static void
144 free_etharp_q(struct etharp_q_entry *q)
145 {
146   struct etharp_q_entry *r;
147   LWIP_ASSERT("q != NULL", q != NULL);
148   LWIP_ASSERT("q->p != NULL", q->p != NULL);
149   while (q) {
150     r = q;
151     q = q->next;
152     LWIP_ASSERT("r->p != NULL", (r->p != NULL));
153     pbuf_free(r->p);
154     memp_free(MEMP_ARP_QUEUE, r);
155   }
156 }
157 #endif
158
159 /**
160  * Clears expired entries in the ARP table.
161  *
162  * This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds),
163  * in order to expire entries in the ARP table.
164  */
165 void
166 etharp_tmr(void)
167 {
168   u8_t i;
169
170   LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
171   /* remove expired entries from the ARP table */
172   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
173     arp_table[i].ctime++;
174     if (((arp_table[i].state == ETHARP_STATE_STABLE) &&
175          (arp_table[i].ctime >= ARP_MAXAGE)) ||
176         ((arp_table[i].state == ETHARP_STATE_PENDING)  &&
177          (arp_table[i].ctime >= ARP_MAXPENDING))) {
178          /* pending or stable entry has become old! */
179       LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
180            arp_table[i].state == ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
181       /* clean up entries that have just been expired */
182       /* remove from SNMP ARP index tree */
183       snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
184 #if ARP_QUEUEING
185       /* and empty packet queue */
186       if (arp_table[i].q != NULL) {
187         /* remove all queued packets */
188         LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
189         free_etharp_q(arp_table[i].q);
190         arp_table[i].q = NULL;
191       }
192 #endif
193       /* recycle entry for re-use */      
194       arp_table[i].state = ETHARP_STATE_EMPTY;
195     }
196 #if ARP_QUEUEING
197     /* still pending entry? (not expired) */
198     if (arp_table[i].state == ETHARP_STATE_PENDING) {
199         /* resend an ARP query here? */
200     }
201 #endif
202   }
203 }
204
205 /**
206  * Search the ARP table for a matching or new entry.
207  * 
208  * If an IP address is given, return a pending or stable ARP entry that matches
209  * the address. If no match is found, create a new entry with this address set,
210  * but in state ETHARP_EMPTY. The caller must check and possibly change the
211  * state of the returned entry.
212  * 
213  * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
214  * 
215  * In all cases, attempt to create new entries from an empty entry. If no
216  * empty entries are available and ETHARP_TRY_HARD flag is set, recycle
217  * old entries. Heuristic choose the least important entry for recycling.
218  *
219  * @param ipaddr IP address to find in ARP cache, or to add if not found.
220  * @param flags
221  * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of
222  * active (stable or pending) entries.
223  *  
224  * @return The ARP entry index that matched or is created, ERR_MEM if no
225  * entry is found or could be recycled.
226  */
227 static s8_t
228 #if LWIP_NETIF_HWADDRHINT
229 find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif)
230 #else /* LWIP_NETIF_HWADDRHINT */
231 find_entry(struct ip_addr *ipaddr, u8_t flags)
232 #endif /* LWIP_NETIF_HWADDRHINT */
233 {
234   s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
235   s8_t empty = ARP_TABLE_SIZE;
236   u8_t i = 0, age_pending = 0, age_stable = 0;
237 #if ARP_QUEUEING
238   /* oldest entry with packets on queue */
239   s8_t old_queue = ARP_TABLE_SIZE;
240   /* its age */
241   u8_t age_queue = 0;
242 #endif
243
244   /* First, test if the last call to this function asked for the
245    * same address. If so, we're really fast! */
246   if (ipaddr) {
247     /* ipaddr to search for was given */
248 #if LWIP_NETIF_HWADDRHINT
249     if ((netif != NULL) && (netif->addr_hint != NULL)) {
250       /* per-pcb cached entry was given */
251       u8_t per_pcb_cache = *(netif->addr_hint);
252       if ((per_pcb_cache < ARP_TABLE_SIZE) && arp_table[per_pcb_cache].state == ETHARP_STATE_STABLE) {
253         /* the per-pcb-cached entry is stable */
254         if (ip_addr_cmp(ipaddr, &arp_table[per_pcb_cache].ipaddr)) {
255           /* per-pcb cached entry was the right one! */
256           ETHARP_STATS_INC(etharp.cachehit);
257           return per_pcb_cache;
258         }
259       }
260     }
261 #else /* #if LWIP_NETIF_HWADDRHINT */
262     if (arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) {
263       /* the cached entry is stable */
264       if (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr)) {
265         /* cached entry was the right one! */
266         ETHARP_STATS_INC(etharp.cachehit);
267         return etharp_cached_entry;
268       }
269     }
270 #endif /* #if LWIP_NETIF_HWADDRHINT */
271   }
272
273   /**
274    * a) do a search through the cache, remember candidates
275    * b) select candidate entry
276    * c) create new entry
277    */
278
279   /* a) in a single search sweep, do all of this
280    * 1) remember the first empty entry (if any)
281    * 2) remember the oldest stable entry (if any)
282    * 3) remember the oldest pending entry without queued packets (if any)
283    * 4) remember the oldest pending entry with queued packets (if any)
284    * 5) search for a matching IP entry, either pending or stable
285    *    until 5 matches, or all entries are searched for.
286    */
287
288   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
289     /* no empty entry found yet and now we do find one? */
290     if ((empty == ARP_TABLE_SIZE) && (arp_table[i].state == ETHARP_STATE_EMPTY)) {
291       LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i));
292       /* remember first empty entry */
293       empty = i;
294     }
295     /* pending entry? */
296     else if (arp_table[i].state == ETHARP_STATE_PENDING) {
297       /* if given, does IP address match IP address in ARP entry? */
298       if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
299         LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i));
300         /* found exact IP address match, simply bail out */
301 #if LWIP_NETIF_HWADDRHINT
302         NETIF_SET_HINT(netif, i);
303 #else /* #if LWIP_NETIF_HWADDRHINT */
304         etharp_cached_entry = i;
305 #endif /* #if LWIP_NETIF_HWADDRHINT */
306         return i;
307 #if ARP_QUEUEING
308       /* pending with queued packets? */
309       } else if (arp_table[i].q != NULL) {
310         if (arp_table[i].ctime >= age_queue) {
311           old_queue = i;
312           age_queue = arp_table[i].ctime;
313         }
314 #endif
315       /* pending without queued packets? */
316       } else {
317         if (arp_table[i].ctime >= age_pending) {
318           old_pending = i;
319           age_pending = arp_table[i].ctime;
320         }
321       }        
322     }
323     /* stable entry? */
324     else if (arp_table[i].state == ETHARP_STATE_STABLE) {
325       /* if given, does IP address match IP address in ARP entry? */
326       if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
327         LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i));
328         /* found exact IP address match, simply bail out */
329 #if LWIP_NETIF_HWADDRHINT
330         NETIF_SET_HINT(netif, i);
331 #else /* #if LWIP_NETIF_HWADDRHINT */
332         etharp_cached_entry = i;
333 #endif /* #if LWIP_NETIF_HWADDRHINT */
334         return i;
335       /* remember entry with oldest stable entry in oldest, its age in maxtime */
336       } else if (arp_table[i].ctime >= age_stable) {
337         old_stable = i;
338         age_stable = arp_table[i].ctime;
339       }
340     }
341   }
342   /* { we have no match } => try to create a new entry */
343    
344   /* no empty entry found and not allowed to recycle? */
345   if (((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0))
346       /* or don't create new entry, only search? */
347       || ((flags & ETHARP_FIND_ONLY) != 0)) {
348     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty entry found and not allowed to recycle\n"));
349     return (s8_t)ERR_MEM;
350   }
351   
352   /* b) choose the least destructive entry to recycle:
353    * 1) empty entry
354    * 2) oldest stable entry
355    * 3) oldest pending entry without queued packets
356    * 4) oldest pending entry without queued packets
357    * 
358    * { ETHARP_TRY_HARD is set at this point }
359    */ 
360
361   /* 1) empty entry available? */
362   if (empty < ARP_TABLE_SIZE) {
363     i = empty;
364     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
365   }
366   /* 2) found recyclable stable entry? */
367   else if (old_stable < ARP_TABLE_SIZE) {
368     /* recycle oldest stable*/
369     i = old_stable;
370     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
371 #if ARP_QUEUEING
372     /* no queued packets should exist on stable entries */
373     LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
374 #endif
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 #if ARP_QUEUEING
381   /* 4) found recyclable pending entry with queued packets? */
382   } else if (old_queue < ARP_TABLE_SIZE) {
383     /* recycle oldest pending */
384     i = old_queue;
385     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)));
386     free_etharp_q(arp_table[i].q);
387     arp_table[i].q = NULL;
388 #endif
389     /* no empty or recyclable entries found */
390   } else {
391     return (s8_t)ERR_MEM;
392   }
393
394   /* { empty or recyclable entry found } */
395   LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
396
397   if (arp_table[i].state != ETHARP_STATE_EMPTY)
398   {
399     snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
400   }
401   /* recycle entry (no-op for an already empty entry) */
402   arp_table[i].state = ETHARP_STATE_EMPTY;
403
404   /* IP address given? */
405   if (ipaddr != NULL) {
406     /* set IP address */
407     ip_addr_set(&arp_table[i].ipaddr, ipaddr);
408   }
409   arp_table[i].ctime = 0;
410 #if LWIP_NETIF_HWADDRHINT
411   NETIF_SET_HINT(netif, i);
412 #else /* #if LWIP_NETIF_HWADDRHINT */
413   etharp_cached_entry = i;
414 #endif /* #if LWIP_NETIF_HWADDRHINT */
415   return (err_t)i;
416 }
417
418 /**
419  * Send an IP packet on the network using netif->linkoutput
420  * The ethernet header is filled in before sending.
421  *
422  * @params netif the lwIP network interface on which to send the packet
423  * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header
424  * @params src the source MAC address to be copied into the ethernet header
425  * @params dst the destination MAC address to be copied into the ethernet header
426  * @return ERR_OK if the packet was sent, any other err_t on failure
427  */
428 static err_t
429 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
430 {
431   struct eth_hdr *ethhdr = p->payload;
432   u8_t k;
433
434   LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
435               (netif->hwaddr_len == ETHARP_HWADDR_LEN));
436   k = ETHARP_HWADDR_LEN;
437   while(k > 0) {
438     k--;
439     ethhdr->dest.addr[k] = dst->addr[k];
440     ethhdr->src.addr[k]  = src->addr[k];
441   }
442   ethhdr->type = htons(ETHTYPE_IP);
443   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
444   /* send the packet */
445   return netif->linkoutput(netif, p);
446 }
447
448 /**
449  * Update (or insert) a IP/MAC address pair in the ARP cache.
450  *
451  * If a pending entry is resolved, any queued packets will be sent
452  * at this point.
453  * 
454  * @param ipaddr IP address of the inserted ARP entry.
455  * @param ethaddr Ethernet address of the inserted ARP entry.
456  * @param flags Defines behaviour:
457  * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified,
458  * only existing ARP entries will be updated.
459  *
460  * @return
461  * - ERR_OK Succesfully updated ARP cache.
462  * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.
463  * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
464  *
465  * @see pbuf_free()
466  */
467 static err_t
468 update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
469 {
470   s8_t i;
471   u8_t k;
472   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 3, ("update_arp_entry()\n"));
473   LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
474   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",
475                                         ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), 
476                                         ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
477                                         ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
478   /* non-unicast address? */
479   if (ip_addr_isany(ipaddr) ||
480       ip_addr_isbroadcast(ipaddr, netif) ||
481       ip_addr_ismulticast(ipaddr)) {
482     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
483     return ERR_ARG;
484   }
485   /* find or create ARP entry */
486 #if LWIP_NETIF_HWADDRHINT
487   i = find_entry(ipaddr, flags, netif);
488 #else /* LWIP_NETIF_HWADDRHINT */
489   i = find_entry(ipaddr, flags);
490 #endif /* LWIP_NETIF_HWADDRHINT */
491   /* bail out if no entry could be found */
492   if (i < 0)
493     return (err_t)i;
494   
495   /* mark it stable */
496   arp_table[i].state = ETHARP_STATE_STABLE;
497   /* record network interface */
498   arp_table[i].netif = netif;
499
500   /* insert in SNMP ARP index tree */
501   snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);
502
503   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
504   /* update address */
505   k = ETHARP_HWADDR_LEN;
506   while (k > 0) {
507     k--;
508     arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
509   }
510   /* reset time stamp */
511   arp_table[i].ctime = 0;
512 #if ARP_QUEUEING
513   /* this is where we will send out queued packets! */
514   while (arp_table[i].q != NULL) {
515     struct pbuf *p;
516     /* remember remainder of queue */
517     struct etharp_q_entry *q = arp_table[i].q;
518     /* pop first item off the queue */
519     arp_table[i].q = q->next;
520     /* get the packet pointer */
521     p = q->p;
522     /* now queue entry can be freed */
523     memp_free(MEMP_ARP_QUEUE, q);
524     /* send the queued IP packet */
525     etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
526     /* free the queued IP packet */
527     pbuf_free(p);
528   }
529 #endif
530   return ERR_OK;
531 }
532
533 /**
534  * Finds (stable) ethernet/IP address pair from ARP table
535  * using interface and IP address index.
536  * @note the addresses in the ARP table are in network order!
537  *
538  * @param netif points to interface index
539  * @param ipaddr points to the (network order) IP address index
540  * @param eth_ret points to return pointer
541  * @param ip_ret points to return pointer
542  * @return table index if found, -1 otherwise
543  */
544 s8_t
545 etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr,
546          struct eth_addr **eth_ret, struct ip_addr **ip_ret)
547 {
548   s8_t i;
549
550   LWIP_UNUSED_ARG(netif);
551
552 #if LWIP_NETIF_HWADDRHINT
553   i = find_entry(ipaddr, ETHARP_FIND_ONLY, NULL);
554 #else /* LWIP_NETIF_HWADDRHINT */
555   i = find_entry(ipaddr, ETHARP_FIND_ONLY);
556 #endif /* LWIP_NETIF_HWADDRHINT */
557   if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) {
558       *eth_ret = &arp_table[i].ethaddr;
559       *ip_ret = &arp_table[i].ipaddr;
560       return i;
561   }
562   return -1;
563 }
564
565 /**
566  * Updates the ARP table using the given IP packet.
567  *
568  * Uses the incoming IP packet's source address to update the
569  * ARP cache for the local network. The function does not alter
570  * or free the packet. This function must be called before the
571  * packet p is passed to the IP layer.
572  *
573  * @param netif The lwIP network interface on which the IP packet pbuf arrived.
574  * @param p The IP packet that arrived on netif.
575  *
576  * @return NULL
577  *
578  * @see pbuf_free()
579  */
580 void
581 etharp_ip_input(struct netif *netif, struct pbuf *p)
582 {
583   struct ethip_hdr *hdr;
584   LWIP_ERROR("netif != NULL", (netif != NULL), return;);
585   /* Only insert an entry if the source IP address of the
586      incoming IP packet comes from a host on the local network. */
587   hdr = p->payload;
588   /* source is not on the local network? */
589   if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
590     /* do nothing */
591     return;
592   }
593
594   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
595   /* update ARP table */
596   /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk
597    * back soon (for example, if the destination IP address is ours. */
598   update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);
599 }
600
601
602 /**
603  * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
604  * send out queued IP packets. Updates cache with snooped address pairs.
605  *
606  * Should be called for incoming ARP packets. The pbuf in the argument
607  * is freed by this function.
608  *
609  * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
610  * @param ethaddr Ethernet address of netif.
611  * @param p The ARP packet that arrived on netif. Is freed by this function.
612  *
613  * @return NULL
614  *
615  * @see pbuf_free()
616  */
617 void
618 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
619 {
620   struct etharp_hdr *hdr;
621   /* these are aligned properly, whereas the ARP header fields might not be */
622   struct ip_addr sipaddr, dipaddr;
623   u8_t i;
624   u8_t for_us;
625 #if LWIP_AUTOIP
626   const u8_t * ethdst_hwaddr;
627 #endif /* LWIP_AUTOIP */
628
629   LWIP_ERROR("netif != NULL", (netif != NULL), return;);
630   
631   /* drop short ARP packets: we have to check for p->len instead of p->tot_len here
632      since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
633   if (p->len < sizeof(struct etharp_hdr)) {
634     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, (s16_t)sizeof(struct etharp_hdr)));
635     ETHARP_STATS_INC(etharp.lenerr);
636     ETHARP_STATS_INC(etharp.drop);
637     pbuf_free(p);
638     return;
639   }
640
641   hdr = p->payload;
642
643   /* RFC 826 "Packet Reception": */
644   if ((hdr->hwtype != htons(HWTYPE_ETHERNET)) ||
645       (hdr->_hwlen_protolen != htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr))) ||
646       (hdr->proto != htons(ETHTYPE_IP)) ||
647       (hdr->ethhdr.type != htons(ETHTYPE_ARP)))  {
648     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1,
649       ("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",
650       hdr->hwtype, ARPH_HWLEN(hdr), hdr->proto, ARPH_PROTOLEN(hdr), hdr->ethhdr.type));
651     ETHARP_STATS_INC(etharp.proterr);
652     ETHARP_STATS_INC(etharp.drop);
653     pbuf_free(p);
654     return;
655   }
656   ETHARP_STATS_INC(etharp.recv);
657
658 #if LWIP_AUTOIP
659   /* We have to check if a host already has configured our random
660    * created link local address and continously check if there is
661    * a host with this IP-address so we can detect collisions */
662   autoip_arp_reply(netif, hdr);
663 #endif /* LWIP_AUTOIP */
664
665   /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
666    * structure packing (not using structure copy which breaks strict-aliasing rules). */
667   SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
668   SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
669
670   /* this interface is not configured? */
671   if (netif->ip_addr.addr == 0) {
672     for_us = 0;
673   } else {
674     /* ARP packet directed to us? */
675     for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
676   }
677
678   /* ARP message directed to us? */
679   if (for_us) {
680     /* add IP address in ARP cache; assume requester wants to talk to us.
681      * can result in directly sending the queued packets for this host. */
682     update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);
683   /* ARP message not directed to us? */
684   } else {
685     /* update the source IP address in the cache, if present */
686     update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
687   }
688
689   /* now act on the message itself */
690   switch (htons(hdr->opcode)) {
691   /* ARP request? */
692   case ARP_REQUEST:
693     /* ARP request. If it asked for our address, we send out a
694      * reply. In any case, we time-stamp any existing ARP entry,
695      * and possiby send out an IP packet that was queued on it. */
696
697     LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
698     /* ARP request for our address? */
699     if (for_us) {
700
701       LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
702       /* Re-use pbuf to send ARP reply.
703          Since we are re-using an existing pbuf, we can't call etharp_raw since
704          that would allocate a new pbuf. */
705       hdr->opcode = htons(ARP_REPLY);
706
707       hdr->dipaddr = hdr->sipaddr;
708       hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
709
710       LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
711                   (netif->hwaddr_len == ETHARP_HWADDR_LEN));
712       i = ETHARP_HWADDR_LEN;
713 #if LWIP_AUTOIP
714       /* If we are using Link-Local, ARP packets must be broadcast on the
715        * link layer. (See RFC3927 Section 2.5) */
716       ethdst_hwaddr = ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
717 #endif /* LWIP_AUTOIP */
718
719       while(i > 0) {
720         i--;
721         hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
722 #if LWIP_AUTOIP
723         hdr->ethhdr.dest.addr[i] = ethdst_hwaddr[i];
724 #else  /* LWIP_AUTOIP */
725         hdr->ethhdr.dest.addr[i] = hdr->shwaddr.addr[i];
726 #endif /* LWIP_AUTOIP */
727         hdr->shwaddr.addr[i] = ethaddr->addr[i];
728         hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
729       }
730
731       /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
732          are already correct, we tested that before */
733
734       /* return ARP reply */
735       netif->linkoutput(netif, p);
736     /* we are not configured? */
737     } else if (netif->ip_addr.addr == 0) {
738       /* { for_us == 0 and netif->ip_addr.addr == 0 } */
739       LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
740     /* request was not directed to us */
741     } else {
742       /* { for_us == 0 and netif->ip_addr.addr != 0 } */
743       LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
744     }
745     break;
746   case ARP_REPLY:
747     /* ARP reply. We already updated the ARP cache earlier. */
748     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
749 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
750     /* DHCP wants to know about ARP replies from any host with an
751      * IP address also offered to us by the DHCP server. We do not
752      * want to take a duplicate IP address on a single network.
753      * @todo How should we handle redundant (fail-over) interfaces? */
754     dhcp_arp_reply(netif, &sipaddr);
755 #endif
756     break;
757   default:
758     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
759     ETHARP_STATS_INC(etharp.err);
760     break;
761   }
762   /* free ARP packet */
763   pbuf_free(p);
764 }
765
766 /**
767  * Resolve and fill-in Ethernet address header for outgoing IP packet.
768  *
769  * For IP multicast and broadcast, corresponding Ethernet addresses
770  * are selected and the packet is transmitted on the link.
771  *
772  * For unicast addresses, the packet is submitted to etharp_query(). In
773  * case the IP address is outside the local network, the IP address of
774  * the gateway is used.
775  *
776  * @param netif The lwIP network interface which the IP packet will be sent on.
777  * @param q The pbuf(s) containing the IP packet to be sent.
778  * @param ipaddr The IP address of the packet destination.
779  *
780  * @return
781  * - ERR_RTE No route to destination (no gateway to external networks),
782  * or the return type of either etharp_query() or etharp_send_ip().
783  */
784 err_t
785 etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr)
786 {
787   struct eth_addr *dest, mcastaddr;
788
789   /* make room for Ethernet header - should not fail */
790   if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
791     /* bail out */
792     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
793     LINK_STATS_INC(link.lenerr);
794     return ERR_BUF;
795   }
796
797   /* assume unresolved Ethernet address */
798   dest = NULL;
799   /* Determine on destination hardware address. Broadcasts and multicasts
800    * are special, other IP addresses are looked up in the ARP table. */
801
802   /* broadcast destination IP address? */
803   if (ip_addr_isbroadcast(ipaddr, netif)) {
804     /* broadcast on Ethernet also */
805     dest = (struct eth_addr *)&ethbroadcast;
806   /* multicast destination IP address? */
807   } else if (ip_addr_ismulticast(ipaddr)) {
808     /* Hash IP multicast address to MAC address.*/
809     mcastaddr.addr[0] = 0x01;
810     mcastaddr.addr[1] = 0x00;
811     mcastaddr.addr[2] = 0x5e;
812     mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
813     mcastaddr.addr[4] = ip4_addr3(ipaddr);
814     mcastaddr.addr[5] = ip4_addr4(ipaddr);
815     /* destination Ethernet address is multicast */
816     dest = &mcastaddr;
817   /* unicast destination IP address? */
818   } else {
819     /* outside local network? */
820     if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
821       /* interface has default gateway? */
822       if (netif->gw.addr != 0) {
823         /* send to hardware address of default gateway IP address */
824         ipaddr = &(netif->gw);
825       /* no default gateway available */
826       } else {
827         /* no route to destination error (default gateway missing) */
828         return ERR_RTE;
829       }
830     }
831     /* queue on destination Ethernet address belonging to ipaddr */
832     return etharp_query(netif, ipaddr, q);
833   }
834
835   /* continuation for multicast/broadcast destinations */
836   /* obtain source Ethernet address of the given interface */
837   /* send packet directly on the link */
838   return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
839 }
840
841 /**
842  * Send an ARP request for the given IP address and/or queue a packet.
843  *
844  * If the IP address was not yet in the cache, a pending ARP cache entry
845  * is added and an ARP request is sent for the given address. The packet
846  * is queued on this entry.
847  *
848  * If the IP address was already pending in the cache, a new ARP request
849  * is sent for the given address. The packet is queued on this entry.
850  *
851  * If the IP address was already stable in the cache, and a packet is
852  * given, it is directly sent and no ARP request is sent out. 
853  * 
854  * If the IP address was already stable in the cache, and no packet is
855  * given, an ARP request is sent out.
856  * 
857  * @param netif The lwIP network interface on which ipaddr
858  * must be queried for.
859  * @param ipaddr The IP address to be resolved.
860  * @param q If non-NULL, a pbuf that must be delivered to the IP address.
861  * q is not freed by this function.
862  *
863  * @note q must only be ONE packet, not a packet queue!
864  *
865  * @return
866  * - ERR_BUF Could not make room for Ethernet header.
867  * - ERR_MEM Hardware address unknown, and no more ARP entries available
868  *   to query for address or queue the packet.
869  * - ERR_MEM Could not queue packet due to memory shortage.
870  * - ERR_RTE No route to destination (no gateway to external networks).
871  * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
872  *
873  */
874 err_t
875 etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
876 {
877   struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
878   err_t result = ERR_MEM;
879   s8_t i; /* ARP entry index */
880
881   /* non-unicast address? */
882   if (ip_addr_isbroadcast(ipaddr, netif) ||
883       ip_addr_ismulticast(ipaddr) ||
884       ip_addr_isany(ipaddr)) {
885     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
886     return ERR_ARG;
887   }
888
889   /* find entry in ARP cache, ask to create entry if queueing packet */
890 #if LWIP_NETIF_HWADDRHINT
891   i = find_entry(ipaddr, ETHARP_TRY_HARD, netif);
892 #else /* LWIP_NETIF_HWADDRHINT */
893   i = find_entry(ipaddr, ETHARP_TRY_HARD);
894 #endif /* LWIP_NETIF_HWADDRHINT */
895
896   /* could not find or create entry? */
897   if (i < 0) {
898     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
899     if (q) {
900       LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
901       ETHARP_STATS_INC(etharp.memerr);
902     }
903     return (err_t)i;
904   }
905
906   /* mark a fresh entry as pending (we just sent a request) */
907   if (arp_table[i].state == ETHARP_STATE_EMPTY) {
908     arp_table[i].state = ETHARP_STATE_PENDING;
909   }
910
911   /* { i is either a STABLE or (new or existing) PENDING entry } */
912   LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
913   ((arp_table[i].state == ETHARP_STATE_PENDING) ||
914    (arp_table[i].state == ETHARP_STATE_STABLE)));
915
916   /* do we have a pending entry? or an implicit query request? */
917   if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
918     /* try to resolve it; send out ARP request */
919     result = etharp_request(netif, ipaddr);
920     if (result != ERR_OK) {
921       /* ARP request couldn't be sent */
922       /* We don't re-send arp request in etharp_tmr, but we still queue packets,
923          since this failure could be temporary, and the next packet calling
924          etharp_query again could lead to sending the queued packets. */
925     }
926   }
927   
928   /* packet given? */
929   if (q != NULL) {
930     /* stable entry? */
931     if (arp_table[i].state == ETHARP_STATE_STABLE) {
932       /* we have a valid IP->Ethernet address mapping */
933       /* send the packet */
934       result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
935     /* pending entry? (either just created or already pending */
936     } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
937 #if ARP_QUEUEING /* queue the given q packet */
938       struct pbuf *p;
939       int copy_needed = 0;
940       /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
941        * to copy the whole queue into a new PBUF_RAM (see bug #11400) 
942        * PBUF_ROMs can be left as they are, since ROM must not get changed. */
943       p = q;
944       while (p) {
945         LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
946         if(p->type != PBUF_ROM) {
947           copy_needed = 1;
948           break;
949         }
950         p = p->next;
951       }
952       if(copy_needed) {
953         /* copy the whole packet into new pbufs */
954         p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
955         if(p != NULL) {
956           if (pbuf_copy(p, q) != ERR_OK) {
957             pbuf_free(p);
958             p = NULL;
959           }
960         }
961       } else {
962         /* referencing the old pbuf is enough */
963         p = q;
964         pbuf_ref(p);
965       }
966       /* packet could be taken over? */
967       if (p != NULL) {
968         /* queue packet ... */
969         struct etharp_q_entry *new_entry;
970         /* allocate a new arp queue entry */
971         new_entry = memp_malloc(MEMP_ARP_QUEUE);
972         if (new_entry != NULL) {
973           new_entry->next = 0;
974           new_entry->p = p;
975           if(arp_table[i].q != NULL) {
976             /* queue was already existent, append the new entry to the end */
977             struct etharp_q_entry *r;
978             r = arp_table[i].q;
979             while (r->next != NULL) {
980               r = r->next;
981             }
982             r->next = new_entry;
983           } else {
984             /* queue did not exist, first item in queue */
985             arp_table[i].q = new_entry;
986           }
987           LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
988           result = ERR_OK;
989         } else {
990           /* the pool MEMP_ARP_QUEUE is empty */
991           pbuf_free(p);
992           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));
993           /* { result == ERR_MEM } through initialization */
994         }
995       } else {
996         ETHARP_STATS_INC(etharp.memerr);
997         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));
998         /* { result == ERR_MEM } through initialization */
999       }
1000 #else /* ARP_QUEUEING == 0 */
1001       /* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */
1002       /* { result == ERR_MEM } through initialization */
1003       LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));
1004 #endif
1005     }
1006   }
1007   return result;
1008 }
1009
1010 /**
1011  * Send a raw ARP packet (opcode and all addresses can be modified)
1012  *
1013  * @param netif the lwip network interface on which to send the ARP packet
1014  * @param ethsrc_addr the source MAC address for the ethernet header
1015  * @param ethdst_addr the destination MAC address for the ethernet header
1016  * @param hwsrc_addr the source MAC address for the ARP protocol header
1017  * @param ipsrc_addr the source IP address for the ARP protocol header
1018  * @param hwdst_addr the destination MAC address for the ARP protocol header
1019  * @param ipdst_addr the destination IP address for the ARP protocol header
1020  * @param opcode the type of the ARP packet
1021  * @return ERR_OK if the ARP packet has been sent
1022  *         ERR_MEM if the ARP packet couldn't be allocated
1023  *         any other err_t on failure
1024  */
1025 #if !LWIP_AUTOIP
1026 static
1027 #endif /* LWIP_AUTOIP */
1028 err_t
1029 etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
1030            const struct eth_addr *ethdst_addr,
1031            const struct eth_addr *hwsrc_addr, const struct ip_addr *ipsrc_addr,
1032            const struct eth_addr *hwdst_addr, const struct ip_addr *ipdst_addr,
1033            const u16_t opcode)
1034 {
1035   struct pbuf *p;
1036   err_t result = ERR_OK;
1037   u8_t k; /* ARP entry index */
1038   struct etharp_hdr *hdr;
1039 #if LWIP_AUTOIP
1040   const u8_t * ethdst_hwaddr;
1041 #endif /* LWIP_AUTOIP */
1042
1043   /* allocate a pbuf for the outgoing ARP request packet */
1044   p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
1045   /* could allocate a pbuf for an ARP request? */
1046   if (p == NULL) {
1047     LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 2, ("etharp_raw: could not allocate pbuf for ARP request.\n"));
1048     ETHARP_STATS_INC(etharp.memerr);
1049     return ERR_MEM;
1050   }
1051   LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
1052               (p->len >= sizeof(struct etharp_hdr)));
1053
1054   hdr = p->payload;
1055   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
1056   hdr->opcode = htons(opcode);
1057
1058   LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1059               (netif->hwaddr_len == ETHARP_HWADDR_LEN));
1060   k = ETHARP_HWADDR_LEN;
1061 #if LWIP_AUTOIP
1062   /* If we are using Link-Local, ARP packets must be broadcast on the
1063    * link layer. (See RFC3927 Section 2.5) */
1064   ethdst_hwaddr = ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
1065 #endif /* LWIP_AUTOIP */
1066   /* Write MAC-Addresses (combined loop for both headers) */
1067   while(k > 0) {
1068     k--;
1069     /* Write the ARP MAC-Addresses */
1070     hdr->shwaddr.addr[k] = hwsrc_addr->addr[k];
1071     hdr->dhwaddr.addr[k] = hwdst_addr->addr[k];
1072     /* Write the Ethernet MAC-Addresses */
1073 #if LWIP_AUTOIP
1074     hdr->ethhdr.dest.addr[k] = ethdst_hwaddr[k];
1075 #else  /* LWIP_AUTOIP */
1076     hdr->ethhdr.dest.addr[k] = ethdst_addr->addr[k];
1077 #endif /* LWIP_AUTOIP */
1078     hdr->ethhdr.src.addr[k]  = ethsrc_addr->addr[k];
1079   }
1080   hdr->sipaddr = *(struct ip_addr2 *)ipsrc_addr;
1081   hdr->dipaddr = *(struct ip_addr2 *)ipdst_addr;
1082
1083   hdr->hwtype = htons(HWTYPE_ETHERNET);
1084   hdr->proto = htons(ETHTYPE_IP);
1085   /* set hwlen and protolen together */
1086   hdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr));
1087
1088   hdr->ethhdr.type = htons(ETHTYPE_ARP);
1089   /* send ARP query */
1090   result = netif->linkoutput(netif, p);
1091   ETHARP_STATS_INC(etharp.xmit);
1092   /* free ARP query packet */
1093   pbuf_free(p);
1094   p = NULL;
1095   /* could not allocate pbuf for ARP request */
1096
1097   return result;
1098 }
1099
1100 /**
1101  * Send an ARP request packet asking for ipaddr.
1102  *
1103  * @param netif the lwip network interface on which to send the request
1104  * @param ipaddr the IP address for which to ask
1105  * @return ERR_OK if the request has been sent
1106  *         ERR_MEM if the ARP packet couldn't be allocated
1107  *         any other err_t on failure
1108  */
1109 err_t
1110 etharp_request(struct netif *netif, struct ip_addr *ipaddr)
1111 {
1112   LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
1113   return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
1114                     (struct eth_addr *)netif->hwaddr, &netif->ip_addr, &ethzero,
1115                     ipaddr, ARP_REQUEST);
1116 }
1117
1118 /**
1119  * Process received ethernet frames. Using this function instead of directly
1120  * calling ip_input and passing ARP frames through etharp in ethernetif_input,
1121  * the ARP cache is protected from concurrent access.
1122  *
1123  * @param p the recevied packet, p->payload pointing to the ethernet header
1124  * @param netif the network interface on which the packet was received
1125  */
1126 err_t
1127 ethernet_input(struct pbuf *p, struct netif *netif)
1128 {
1129   struct eth_hdr* ethhdr;
1130
1131   /* points to packet payload, which starts with an Ethernet header */
1132   ethhdr = p->payload;
1133   
1134   switch (htons(ethhdr->type)) {
1135     /* IP packet? */
1136     case ETHTYPE_IP:
1137 #if ETHARP_TRUST_IP_MAC
1138       /* update ARP table */
1139       etharp_ip_input(netif, p);
1140 #endif /* ETHARP_TRUST_IP_MAC */
1141       /* skip Ethernet header */
1142       if(pbuf_header(p, -(s16_t)sizeof(struct eth_hdr))) {
1143         LWIP_ASSERT("Can't move over header in packet", 0);
1144         pbuf_free(p);
1145         p = NULL;
1146       } else {
1147         /* pass to IP layer */
1148         ip_input(p, netif);
1149       }
1150       break;
1151       
1152     case ETHTYPE_ARP:
1153       /* pass p to ARP module */
1154       etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
1155       break;
1156
1157 #if PPPOE_SUPPORT
1158     case ETHTYPE_PPPOEDISC: /* PPP Over Ethernet Discovery Stage */
1159       pppoe_disc_input(netif, p);
1160       break;
1161
1162     case ETHTYPE_PPPOE: /* PPP Over Ethernet Session Stage */
1163       pppoe_data_input(netif, p);
1164       break;
1165 #endif /* PPPOE_SUPPORT */
1166
1167     default:
1168       pbuf_free(p);
1169       p = NULL;
1170       break;
1171   }
1172
1173   /* This means the pbuf is freed or consumed,
1174      so the caller doesn't have to free it again */
1175   return ERR_OK;
1176 }
1177 #endif /* LWIP_ARP */