]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/lwip_tcpip/v2_0/src/netif/etharp.c
4a1757ef1b15ec9aa9f1a3fc97f04e5ab5baaeb4
[karo-tx-redboot.git] / packages / net / lwip_tcpip / v2_0 / src / 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) and supports
10  * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6.
11  */
12
13 /*
14  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
15  * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
16  * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without modification,
20  * are permitted provided that the following conditions are met:
21  *
22  * 1. Redistributions of source code must retain the above copyright notice,
23  *    this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright notice,
25  *    this list of conditions and the following disclaimer in the documentation
26  *    and/or other materials provided with the distribution.
27  * 3. The name of the author may not be used to endorse or promote products
28  *    derived from this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
31  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
32  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
33  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
35  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39  * OF SUCH DAMAGE.
40  *
41  * This file is part of the lwIP TCP/IP stack.
42  *
43  * Author: Adam Dunkels <adam@sics.se>
44  *
45  */
46
47 /**
48  * TODO:
49  * - pbufs should be sent from the queue once an ARP entry state
50  *   goes from PENDING to STABLE.
51  * - Non-PENDING entries MUST NOT have queued packets.
52  */
53
54 /*
55  * TODO:
56  *
57 RFC 3220 4.6          IP Mobility Support for IPv4          January 2002
58
59       -  A Gratuitous ARP [45] is an ARP packet sent by a node in order
60          to spontaneously cause other nodes to update an entry in their
61          ARP cache.  A gratuitous ARP MAY use either an ARP Request or
62          an ARP Reply packet.  In either case, the ARP Sender Protocol
63          Address and ARP Target Protocol Address are both set to the IP
64          address of the cache entry to be updated, and the ARP Sender
65          Hardware Address is set to the link-layer address to which this
66          cache entry should be updated.  When using an ARP Reply packet,
67          the Target Hardware Address is also set to the link-layer
68          address to which this cache entry should be updated (this field
69          is not used in an ARP Request packet).
70
71          In either case, for a gratuitous ARP, the ARP packet MUST be
72          transmitted as a local broadcast packet on the local link.  As
73          specified in [36], any node receiving any ARP packet (Request
74          or Reply) MUST update its local ARP cache with the Sender
75          Protocol and Hardware Addresses in the ARP packet, if the
76          receiving node has an entry for that IP address already in its
77          ARP cache.  This requirement in the ARP protocol applies even
78          for ARP Request packets, and for ARP Reply packets that do not
79          match any ARP Request transmitted by the receiving node [36].
80 *
81   My suggestion would be to send a ARP request for our newly obtained
82   address upon configuration of an Ethernet interface.
83
84 */
85
86 #include "lwip/opt.h"
87 #include "lwip/inet.h"
88 #include "netif/etharp.h"
89 #include "lwip/ip.h"
90 #include "lwip/stats.h"
91
92 /* ARP needs to inform DHCP of any ARP replies? */
93 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
94 #  include "lwip/dhcp.h"
95 #endif
96
97 /* allows new queueing code to be disabled (0) for regression testing */
98 #define ARP_NEW_QUEUE 1
99
100 /** the time an ARP entry stays valid after its last update, (120 * 10) seconds = 20 minutes. */
101 #define ARP_MAXAGE 120
102 /** the time an ARP entry stays pending after first request, (1 * 10) seconds = 10 seconds. */
103 #define ARP_MAXPENDING 1
104
105 #define HWTYPE_ETHERNET 1
106
107 /** ARP message types */
108 #define ARP_REQUEST 1
109 #define ARP_REPLY 2
110
111 #define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8)
112 #define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff)
113
114 #define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8))
115 #define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8))
116
117 enum etharp_state {
118   ETHARP_STATE_EMPTY,
119   ETHARP_STATE_PENDING,
120   ETHARP_STATE_STABLE,
121   /** @internal convenience transitional state used in etharp_tmr() */
122   ETHARP_STATE_EXPIRED
123 };
124
125 struct etharp_entry {
126   struct ip_addr ipaddr;
127   struct eth_addr ethaddr;
128   enum etharp_state state;
129 #if ARP_QUEUEING
130   /** 
131    * Pointer to queue of pending outgoing packets on this ARP entry.
132    * Must be at most a single packet for now. */
133   struct pbuf *p;
134 #endif
135   u8_t ctime;
136 };
137
138 static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
139 static struct etharp_entry arp_table[ARP_TABLE_SIZE];
140
141 static s8_t find_arp_entry(void);
142 /** ask update_arp_entry() to add instead of merely update an ARP entry */
143 #define ARP_INSERT_FLAG 1
144 static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
145 /**
146  * Initializes ARP module.
147  */
148 void
149 etharp_init(void)
150 {
151   s8_t i;
152   /* clear ARP entries */
153   for(i = 0; i < ARP_TABLE_SIZE; ++i) {
154     arp_table[i].state = ETHARP_STATE_EMPTY;
155 #if ARP_QUEUEING
156     arp_table[i].p = NULL;
157 #endif
158     arp_table[i].ctime = 0;
159   }
160 }
161
162 /**
163  * Clears expired entries in the ARP table.
164  *
165  * This function should be called every ETHARP_TMR_INTERVAL microseconds (10 seconds),
166  * in order to expire entries in the ARP table.
167  */
168 void
169 etharp_tmr(void)
170 {
171   s8_t i;
172
173   LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
174   /* remove expired entries from the ARP table */
175   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
176     arp_table[i].ctime++;
177     /* a resolved/stable entry? */
178     if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
179          /* entry has become old? */
180         (arp_table[i].ctime >= ARP_MAXAGE)) {
181       LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
182       arp_table[i].state = ETHARP_STATE_EXPIRED;
183     /* an unresolved/pending entry? */
184     } else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
185          /* entry unresolved/pending for too long? */
186         (arp_table[i].ctime >= ARP_MAXPENDING)) {
187       LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
188       arp_table[i].state = ETHARP_STATE_EXPIRED;
189     }
190     /* clean up entries that have just been expired */
191     if (arp_table[i].state == ETHARP_STATE_EXPIRED) {
192 #if ARP_QUEUEING
193       /* and empty packet queue */
194       if (arp_table[i].p != NULL) {
195         /* remove all queued packets */
196         LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
197         pbuf_free(arp_table[i].p);
198         arp_table[i].p = NULL;
199       }
200 #endif
201       /* recycle entry for re-use */      
202       arp_table[i].state = ETHARP_STATE_EMPTY;
203     }
204   }
205 }
206
207 /**
208  * Return an empty ARP entry (possibly recycling the oldest stable entry).
209  *
210  * @return The ARP entry index that is available, ERR_MEM if no usable
211  * entry is found.
212  */
213 static s8_t
214 find_arp_entry(void)
215 {
216   s8_t i, j;
217   u8_t maxtime = 0;
218
219   j = ARP_TABLE_SIZE;
220   /* search ARP table for an unused or old entry */
221   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
222         /* empty entry? */
223     if (arp_table[i].state == ETHARP_STATE_EMPTY) {
224       LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning empty entry %u\n", i));
225       return i;
226         /* stable entry? */
227     } else if (arp_table[i].state == ETHARP_STATE_STABLE) {
228       /* remember entry with oldest stable entry in j */
229       if (arp_table[i].ctime >= maxtime) maxtime = arp_table[j = i].ctime;
230     }
231   }
232   /* no empty entry found? */
233   if (i == ARP_TABLE_SIZE) {
234         LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
235     /* fall-back to oldest stable */
236         i = j;
237   }
238   /* no available entry found? */
239   if (i == ARP_TABLE_SIZE) {
240     LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
241     /* return failure */
242     return ERR_MEM;
243   }
244
245   /* clean up the recycled stable entry */
246   if (arp_table[i].state == ETHARP_STATE_STABLE) {
247 #if ARP_QUEUEING
248     /* and empty the packet queue */
249     if (arp_table[i].p != NULL) {
250       /* remove all queued packets */
251       LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
252       pbuf_free(arp_table[i].p);
253       arp_table[i].p = NULL;
254     }
255 #endif
256     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_arp_entry: recycling oldest stable entry %u\n", i));
257     arp_table[i].state = ETHARP_STATE_EMPTY;
258   }
259   LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", i));
260   return i;
261 }
262
263 /**
264  * Update (or insert) a IP/MAC address pair in the ARP cache.
265  *
266  * If a pending entry is resolved, any queued packets will be sent
267  * at this point.
268  * 
269  * @param ipaddr IP address of the inserted ARP entry.
270  * @param ethaddr Ethernet address of the inserted ARP entry.
271  * @param flags Defines behaviour:
272  * - ARP_INSERT_FLAG Allows ARP to insert this as a new item. If not specified,
273  * only existing ARP entries will be updated.
274  *
275  * @return pbuf If non-NULL, a packet that was queued on a pending entry.
276  * You should sent it and must call pbuf_free() afterwards.
277  *
278  * @see pbuf_free()
279  */
280 static struct pbuf *
281 update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
282 {
283   s8_t i, k;
284   LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
285   LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
286   LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n",
287                                         ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), 
288                                         ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
289                                         ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
290   /* do not update for 0.0.0.0 addresses */
291   if (ipaddr->addr == 0) {
292     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n"));
293     return NULL;
294   }
295   /* Walk through the ARP mapping table and try to find an entry to
296   update. If none is found, the IP -> MAC address mapping is
297   inserted in the ARP table. */
298   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
299     /* Check if the source IP address of the incoming packet matches
300     the IP address in this ARP table entry. */
301     if (arp_table[i].state != ETHARP_STATE_EMPTY &&
302         ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
303       /* pending entry? */
304       if (arp_table[i].state == ETHARP_STATE_PENDING) {
305         LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i));
306         /* A pending entry was found, mark it stable */
307         arp_table[i].state = ETHARP_STATE_STABLE;
308         /* fall-through to next if */
309       }
310       /* stable entry? (possibly just marked to become stable) */
311       if (arp_table[i].state == ETHARP_STATE_STABLE) {
312 #if ARP_QUEUEING
313         struct pbuf *p;
314         struct eth_hdr *ethhdr;
315 #endif
316         LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));
317         /* An old entry found, update this and return. */
318         for (k = 0; k < netif->hwaddr_len; ++k) {
319           arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
320         }
321         /* reset time stamp */
322         arp_table[i].ctime = 0;
323 /* this is where we will send out queued packets! */
324 #if ARP_QUEUEING
325         while (arp_table[i].p != NULL) {
326           /* get the first packet on the queue (if any) */
327           p = arp_table[i].p;
328           /* remember (and reference) remainder of queue */
329           arp_table[i].p = pbuf_dequeue(p);
330           /* fill-in Ethernet header */
331           ethhdr = p->payload;
332           for (k = 0; k < netif->hwaddr_len; ++k) {
333             ethhdr->dest.addr[k] = ethaddr->addr[k];
334             ethhdr->src.addr[k] = netif->hwaddr[k];
335           }
336           ethhdr->type = htons(ETHTYPE_IP);
337           LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p));
338           /* send the queued IP packet */
339           netif->linkoutput(netif, p);
340           /* free the queued IP packet */
341           pbuf_free(p);
342         }
343 #endif
344         /* IP addresses should only occur once in the ARP entry, we are done */
345         return NULL;
346       }
347     } /* if STABLE */
348   } /* for all ARP entries */
349
350   /* no matching ARP entry was found */
351   LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
352
353   LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: IP address not yet in table\n"));
354   /* allowed to insert a new entry? */
355   if (flags & ARP_INSERT_FLAG)
356   {
357     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
358     /* find an empty or old entry. */
359     i = find_arp_entry();
360     if (i == ERR_MEM) {
361       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n"));
362       return NULL;
363     }
364     /* set IP address */
365     ip_addr_set(&arp_table[i].ipaddr, ipaddr);
366     /* set Ethernet hardware address */
367     for (k = 0; k < netif->hwaddr_len; ++k) {
368       arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
369     }
370     /* reset time-stamp */
371     arp_table[i].ctime = 0;
372     /* mark as stable */
373     arp_table[i].state = ETHARP_STATE_STABLE;
374     /* no queued packet */
375 #if ARP_QUEUEING
376     arp_table[i].p = NULL;
377 #endif
378   }
379   else
380   {
381     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no matching stable entry to update\n"));
382   }
383   return NULL;
384 }
385
386 /**
387  * Updates the ARP table using the given IP packet.
388  *
389  * Uses the incoming IP packet's source address to update the
390  * ARP cache for the local network. The function does not alter
391  * or free the packet. This function must be called before the
392  * packet p is passed to the IP layer.
393  *
394  * @param netif The lwIP network interface on which the IP packet pbuf arrived.
395  * @param pbuf The IP packet that arrived on netif.
396  *
397  * @return NULL
398  *
399  * @see pbuf_free()
400  */
401 struct pbuf *
402 etharp_ip_input(struct netif *netif, struct pbuf *p)
403 {
404   struct ethip_hdr *hdr;
405
406   /* Only insert an entry if the source IP address of the
407      incoming IP packet comes from a host on the local network. */
408   hdr = p->payload;
409   /* source is on local network? */
410   if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
411     /* do nothing */
412     return NULL;
413   }
414
415   LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
416   /* update ARP table, ask to insert entry */
417   update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG);
418   return NULL;
419 }
420
421
422 /**
423  * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
424  * send out queued IP packets. Updates cache with snooped address pairs.
425  *
426  * Should be called for incoming ARP packets. The pbuf in the argument
427  * is freed by this function.
428  *
429  * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
430  * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
431  * @param ethaddr Ethernet address of netif.
432  *
433  * @return NULL
434  *
435  * @see pbuf_free()
436  */
437 struct pbuf *
438 etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
439 {
440   struct etharp_hdr *hdr;
441   /* these are aligned properly, whereas the ARP header fields might not be */
442   struct ip_addr sipaddr, dipaddr;
443   u8_t i;
444   u8_t for_us;
445
446   /* drop short ARP packets */
447   if (p->tot_len < sizeof(struct etharp_hdr)) {
448     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
449     pbuf_free(p);
450     return NULL;
451   }
452
453   hdr = p->payload;
454  
455   /* get aligned copies of addresses */
456   *(struct ip_addr2 *)&sipaddr = hdr->sipaddr;
457   *(struct ip_addr2 *)&dipaddr = hdr->dipaddr;
458
459   /* this interface is not configured? */
460   if (netif->ip_addr.addr == 0) {
461     for_us = 0;
462   } else {
463     /* ARP packet directed to us? */
464     for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
465   }
466
467   /* ARP message directed to us? */
468   if (for_us) {
469     /* add IP address in ARP cache; assume requester wants to talk to us.
470      * can result in directly sending the queued packets for this host. */
471     update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ARP_INSERT_FLAG);
472   /* ARP message not directed to us? */
473   } else {
474     /* update the source IP address in the cache, if present */
475     update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
476   }
477
478   /* now act on the message itself */
479   switch (htons(hdr->opcode)) {
480   /* ARP request? */
481   case ARP_REQUEST:
482     /* ARP request. If it asked for our address, we send out a
483      * reply. In any case, we time-stamp any existing ARP entry,
484      * and possiby send out an IP packet that was queued on it. */
485
486     LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
487     /* ARP request for our address? */
488     if (for_us) {
489
490       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
491       /* re-use pbuf to send ARP reply */
492       hdr->opcode = htons(ARP_REPLY);
493
494       hdr->dipaddr = hdr->sipaddr;
495       hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
496
497       for(i = 0; i < netif->hwaddr_len; ++i) {
498         hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
499         hdr->shwaddr.addr[i] = ethaddr->addr[i];
500         hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
501         hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
502       }
503
504       hdr->hwtype = htons(HWTYPE_ETHERNET);
505       ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
506
507       hdr->proto = htons(ETHTYPE_IP);
508       ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
509
510       hdr->ethhdr.type = htons(ETHTYPE_ARP);
511       /* return ARP reply */
512       netif->linkoutput(netif, p);
513     /* we are not configured? */
514     } else if (netif->ip_addr.addr == 0) {
515       /* { for_us == 0 and netif->ip_addr.addr == 0 } */
516       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
517     /* request was not directed to us */
518     } else {
519       /* { for_us == 0 and netif->ip_addr.addr != 0 } */
520       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
521     }
522     break;
523   case ARP_REPLY:
524     /* ARP reply. We insert or update the ARP table later. */
525     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
526 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
527     /* DHCP wants to know about ARP replies to our wanna-have-address */
528     if (for_us) dhcp_arp_reply(netif, &sipaddr);
529 #endif
530     break;
531   default:
532     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
533     break;
534   }
535   /* free ARP packet */
536   pbuf_free(p);
537   p = NULL;
538   /* nothing to send, we did it! */
539   return NULL;
540 }
541
542 /**
543  * Resolve and fill-in Ethernet address header for outgoing packet.
544  *
545  * If ARP has the Ethernet address in cache, the given packet is
546  * returned, ready to be sent.
547  *
548  * If ARP does not have the Ethernet address in cache the packet is
549  * queued (if enabled and space available) and a ARP request is sent.
550  * This ARP request is returned as a pbuf, which should be sent by
551  * the caller.
552  *
553  * A returned non-NULL packet should be sent by the caller.
554  *
555  * If ARP failed to allocate resources, NULL is returned.
556  *
557  * @param netif The lwIP network interface which the IP packet will be sent on.
558  * @param ipaddr The IP address of the packet destination.
559  * @param pbuf The pbuf(s) containing the IP packet to be sent.
560  *
561  * @return If non-NULL, a packet ready to be sent by caller.
562  *
563  */
564 struct pbuf *
565 etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
566 {
567   struct eth_addr *dest, *srcaddr, mcastaddr;
568   struct eth_hdr *ethhdr;
569   s8_t i;
570
571   /* make room for Ethernet header */
572   if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
573     /* The pbuf_header() call shouldn't fail, and we'll just bail
574     out if it does.. */
575     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
576     LINK_STATS_INC(link.lenerr);
577     return NULL;
578   }
579
580   /* assume unresolved Ethernet address */
581   dest = NULL;
582   /* Construct Ethernet header. Start with looking up deciding which
583      MAC address to use as a destination address. Broadcasts and
584      multicasts are special, all other addresses are looked up in the
585      ARP table. */
586
587   /* destination IP address is an IP broadcast address? */
588   if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif)) {
589     /* broadcast on Ethernet also */
590     dest = (struct eth_addr *)&ethbroadcast;
591   }
592   /* destination IP address is an IP multicast address? */
593   else if (ip_addr_ismulticast(ipaddr)) {
594     /* Hash IP multicast address to MAC address. */
595     mcastaddr.addr[0] = 0x01;
596     mcastaddr.addr[1] = 0x00;
597     mcastaddr.addr[2] = 0x5e;
598     mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
599     mcastaddr.addr[4] = ip4_addr3(ipaddr);
600     mcastaddr.addr[5] = ip4_addr4(ipaddr);
601     /* destination Ethernet address is multicast */
602     dest = &mcastaddr;
603   }
604   /* destination IP address is an IP unicast address */
605   else {
606     /* destination IP network address not on local network?
607      * IP layer wants us to forward to the default gateway */
608     if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
609       /* interface has default gateway? */
610       if (netif->gw.addr != 0)
611       {
612         /* route to default gateway IP address */
613         ipaddr = &(netif->gw);
614       }
615       /* no gateway available? */
616       else
617       {
618         /* IP destination address outside local network, but no gateway available */
619         /* { packet is discarded } */
620         return NULL;
621       }
622     }
623
624     /* Ethernet address for IP destination address is in ARP cache? */
625     for (i = 0; i < ARP_TABLE_SIZE; ++i) {
626       /* match found? */
627       if (arp_table[i].state == ETHARP_STATE_STABLE &&
628         ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
629         dest = &arp_table[i].ethaddr;
630         break;
631       }
632     }
633     /* could not find the destination Ethernet address in ARP cache? */
634     if (dest == NULL) {
635       /* ARP query for the IP address, submit this IP packet for queueing */
636       /* TODO: How do we handle netif->ipaddr == ipaddr? */
637       etharp_query(netif, ipaddr, q);
638       /* { packet was queued (ERR_OK), or discarded } */
639       /* return nothing */
640       return NULL;
641     }
642     /* destination Ethernet address resolved from ARP cache */
643     else
644     {
645       /* fallthrough */
646     }
647   }
648
649   /* destination Ethernet address known */
650   if (dest != NULL) {
651     /* obtain source Ethernet address of the given interface */
652     srcaddr = (struct eth_addr *)netif->hwaddr;
653
654     /* A valid IP->MAC address mapping was found, fill in the
655      * Ethernet header for the outgoing packet */
656     ethhdr = q->payload;
657
658     for(i = 0; i < netif->hwaddr_len; i++) {
659       ethhdr->dest.addr[i] = dest->addr[i];
660       ethhdr->src.addr[i] = srcaddr->addr[i];
661     }
662
663     ethhdr->type = htons(ETHTYPE_IP);
664     /* return the outgoing packet */
665     return q;
666   }
667   /* never reached; here for safety */
668   return NULL;
669 }
670
671 /**
672  * Send an ARP request for the given IP address.
673  *
674  * Sends an ARP request for the given IP address, unless
675  * a request for this address is already pending. Optionally
676  * queues an outgoing packet on the resulting ARP entry.
677  *
678  * @param netif The lwIP network interface where ipaddr
679  * must be queried for.
680  * @param ipaddr The IP address to be resolved.
681  * @param q If non-NULL, a pbuf that must be queued on the
682  * ARP entry for the ipaddr IP address.
683  *
684  * @return NULL.
685  *
686  * @note Might be used in the future by manual IP configuration
687  * as well.
688  *
689  * TODO: use the ctime field to see how long ago an ARP request was sent,
690  * possibly retry.
691  */
692 err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
693 {
694   struct eth_addr *srcaddr;
695   struct etharp_hdr *hdr;
696   err_t result = ERR_OK;
697   s8_t i;
698   u8_t perform_arp_request = 1;
699   /* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
700   (void)q;
701   srcaddr = (struct eth_addr *)netif->hwaddr;
702   /* bail out if this IP address is pending */
703   for (i = 0; i < ARP_TABLE_SIZE; ++i) {
704     if (arp_table[i].state != ETHARP_STATE_EMPTY &&
705         ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
706       if (arp_table[i].state == ETHARP_STATE_PENDING) {
707         LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
708         /* break out of for-loop, user may wish to queue a packet on a pending entry */
709         /* TODO: we will issue a new ARP request, which should not occur too often */
710         /* we might want to run a faster timer on ARP to limit this */
711         break;
712       }
713       else if (arp_table[i].state == ETHARP_STATE_STABLE) {
714         LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i));
715         /* User wishes to queue a packet on a stable entry (or does she want to send
716          * out the packet immediately, we will not know), so we force an ARP request.
717          * Upon response we will send out the queued packet in etharp_update().
718          * 
719          * Alternatively, we could accept the stable entry, and just send out the packet
720          * immediately. I chose to implement the former approach.
721          */
722         perform_arp_request = (q?1:0);
723         break;
724       }
725     }
726   }
727   /* queried address not yet in ARP table? */
728   if (i == ARP_TABLE_SIZE) {
729     LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));
730     /* find an available (unused or old) entry */
731     i = find_arp_entry();
732     /* bail out if no ARP entries are available */
733     if (i == ERR_MEM) {
734       LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n"));
735       return ERR_MEM;
736     }
737     /* i is available, create ARP entry */
738     arp_table[i].state = ETHARP_STATE_PENDING;
739     ip_addr_set(&arp_table[i].ipaddr, ipaddr);
740   }
741   /* { i is now valid } */
742 #if ARP_QUEUEING /* queue packet (even on a stable entry, see above) */
743   /* copy any PBUF_REF referenced payloads into PBUF_RAM */
744   q = pbuf_take(q);
745   pbuf_queue(arp_table[i].p, q);
746 #endif
747   /* ARP request? */
748   if (perform_arp_request)
749   {
750     struct pbuf *p;
751     /* allocate a pbuf for the outgoing ARP request packet */
752     p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
753     /* could allocate pbuf? */
754     if (p != NULL) {
755       u8_t j;
756       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
757       hdr = p->payload;
758       hdr->opcode = htons(ARP_REQUEST);
759       for (j = 0; j < netif->hwaddr_len; ++j)
760       {
761         hdr->shwaddr.addr[j] = srcaddr->addr[j];
762         /* the hardware address is what we ask for, in
763          * a request it is a don't-care, we use 0's */
764         hdr->dhwaddr.addr[j] = 0x00;
765       }
766       hdr->dipaddr = *(struct ip_addr2 *)ipaddr;
767       hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
768
769       hdr->hwtype = htons(HWTYPE_ETHERNET);
770       ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
771
772       hdr->proto = htons(ETHTYPE_IP);
773       ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
774       for (j = 0; j < netif->hwaddr_len; ++j)
775       {
776         hdr->ethhdr.dest.addr[j] = 0xff;
777         hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
778       }
779       hdr->ethhdr.type = htons(ETHTYPE_ARP);
780       /* send ARP query */
781       result = netif->linkoutput(netif, p);
782       /* free ARP query packet */
783       pbuf_free(p);
784       p = NULL;
785     } else {
786       result = ERR_MEM;
787       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
788     }
789   }
790   return result;
791 }