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