Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_autoip.c Source File

lwip_autoip.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * AutoIP Automatic LinkLocal IP Configuration
00004  *
00005  * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
00006  * with RFC 3927.
00007  *
00008  * @defgroup autoip AUTOIP
00009  * @ingroup ip4
00010  * AUTOIP related functions
00011  * USAGE:
00012  *
00013  * define @ref LWIP_AUTOIP 1 in your lwipopts.h
00014  * Options:
00015  * AUTOIP_TMR_INTERVAL msecs,
00016  *   I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
00017  *   Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
00018  *
00019  * Without DHCP:
00020  * - Call autoip_start() after netif_add().
00021  *
00022  * With DHCP:
00023  * - define @ref LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
00024  * - Configure your DHCP Client.
00025  * 
00026  * @see netifapi_autoip
00027  */
00028 
00029 /*
00030  *
00031  * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
00032  * All rights reserved.
00033  *
00034  * Redistribution and use in source and binary forms, with or without modification,
00035  * are permitted provided that the following conditions are met:
00036  *
00037  * 1. Redistributions of source code must retain the above copyright notice,
00038  *    this list of conditions and the following disclaimer.
00039  * 2. Redistributions in binary form must reproduce the above copyright notice,
00040  *    this list of conditions and the following disclaimer in the documentation
00041  *    and/or other materials provided with the distribution.
00042  * 3. The name of the author may not be used to endorse or promote products
00043  *    derived from this software without specific prior written permission.
00044  *
00045  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00046  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00047  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00048  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00049  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00050  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00051  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00052  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00053  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00054  * OF SUCH DAMAGE.
00055  *
00056  * Author: Dominik Spies <kontakt@dspies.de>
00057  */
00058 
00059 #include "lwip/opt.h"
00060 
00061 #if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
00062 
00063 #include "lwip/mem.h"
00064 /* #include "lwip/udp.h" */
00065 #include "lwip/ip_addr.h"
00066 #include "lwip/netif.h"
00067 #include "lwip/autoip.h"
00068 #include "lwip/etharp.h"
00069 #include "lwip/prot/autoip.h"
00070 
00071 #include <string.h>
00072 
00073 /** Pseudo random macro based on netif informations.
00074  * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
00075 #ifndef LWIP_AUTOIP_RAND
00076 #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
00077                                    ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
00078                                    ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
00079                                    ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
00080                                    (netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0))
00081 #endif /* LWIP_AUTOIP_RAND */
00082 
00083 /**
00084  * Macro that generates the initial IP address to be tried by AUTOIP.
00085  * If you want to override this, define it to something else in lwipopts.h.
00086  */
00087 #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
00088 #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
00089   lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
00090                  ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
00091 #endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
00092 
00093 /* static functions */
00094 static err_t autoip_arp_announce(struct netif *netif);
00095 static void autoip_start_probing(struct netif *netif);
00096 
00097 /**
00098  * @ingroup autoip 
00099  * Set a statically allocated struct autoip to work with.
00100  * Using this prevents autoip_start to allocate it using mem_malloc.
00101  *
00102  * @param netif the netif for which to set the struct autoip
00103  * @param autoip (uninitialised) autoip struct allocated by the application
00104  */
00105 void
00106 autoip_set_struct(struct netif *netif, struct autoip *autoip)
00107 {
00108   LWIP_ASSERT("netif != NULL", netif != NULL);
00109   LWIP_ASSERT("autoip != NULL", autoip != NULL);
00110   LWIP_ASSERT("netif already has a struct autoip set",
00111               netif_autoip_data(netif) == NULL);
00112 
00113   /* clear data structure */
00114   memset(autoip, 0, sizeof(struct autoip));
00115   /* autoip->state = AUTOIP_STATE_OFF; */
00116   netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
00117 }
00118 
00119 /** Restart AutoIP client and check the next address (conflict detected)
00120  *
00121  * @param netif The netif under AutoIP control
00122  */
00123 static void
00124 autoip_restart(struct netif *netif)
00125 {
00126   struct autoip* autoip = netif_autoip_data(netif);
00127   autoip->tried_llipaddr++;
00128   autoip_start(netif);
00129 }
00130 
00131 /**
00132  * Handle a IP address conflict after an ARP conflict detection
00133  */
00134 static void
00135 autoip_handle_arp_conflict(struct netif *netif)
00136 {
00137   struct autoip* autoip = netif_autoip_data(netif);
00138 
00139   /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
00140      a) means retreat on the first conflict and
00141      b) allows to keep an already configured address when having only one
00142         conflict in 10 seconds
00143      We use option b) since it helps to improve the chance that one of the two
00144      conflicting hosts may be able to retain its address. */
00145 
00146   if (autoip->lastconflict > 0) {
00147     /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
00148     LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00149       ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
00150 
00151     /* Active TCP sessions are aborted when removing the ip addresss */
00152     autoip_restart(netif);
00153   } else {
00154     LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00155       ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
00156     autoip_arp_announce(netif);
00157     autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00158   }
00159 }
00160 
00161 /**
00162  * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
00163  *
00164  * @param netif network interface on which create the IP-Address
00165  * @param ipaddr ip address to initialize
00166  */
00167 static void
00168 autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
00169 {
00170   struct autoip* autoip = netif_autoip_data(netif);
00171 
00172   /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
00173    * compliant to RFC 3927 Section 2.1
00174    * We have 254 * 256 possibilities */
00175 
00176   u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
00177   addr += autoip->tried_llipaddr;
00178   addr = AUTOIP_NET | (addr & 0xffff);
00179   /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
00180 
00181   if (addr < AUTOIP_RANGE_START) {
00182     addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00183   }
00184   if (addr > AUTOIP_RANGE_END) {
00185     addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00186   }
00187   LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
00188     (addr <= AUTOIP_RANGE_END));
00189   ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
00190 
00191   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00192     ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00193     (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
00194     ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
00195 }
00196 
00197 /**
00198  * Sends an ARP probe from a network interface
00199  *
00200  * @param netif network interface used to send the probe
00201  */
00202 static err_t
00203 autoip_arp_probe(struct netif *netif)
00204 {
00205   struct autoip* autoip = netif_autoip_data(netif);
00206   /* this works because netif->ip_addr is ANY */
00207   return etharp_request(netif, &autoip->llipaddr);
00208 }
00209 
00210 /**
00211  * Sends an ARP announce from a network interface
00212  *
00213  * @param netif network interface used to send the announce
00214  */
00215 static err_t
00216 autoip_arp_announce(struct netif *netif)
00217 {
00218   return etharp_gratuitous(netif);
00219 }
00220 
00221 /**
00222  * Configure interface for use with current LL IP-Address
00223  *
00224  * @param netif network interface to configure with current LL IP-Address
00225  */
00226 static err_t
00227 autoip_bind(struct netif *netif)
00228 {
00229   struct autoip* autoip = netif_autoip_data(netif);
00230   ip4_addr_t sn_mask, gw_addr;
00231 
00232   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00233     ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00234     (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
00235     ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00236     ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00237 
00238   IP4_ADDR(&sn_mask, 255, 255, 0, 0);
00239   IP4_ADDR(&gw_addr, 0, 0, 0, 0);
00240 
00241   netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
00242   /* interface is used by routing now that an address is set */
00243 
00244   return ERR_OK;
00245 }
00246 
00247 /**
00248  * @ingroup autoip 
00249  * Start AutoIP client
00250  *
00251  * @param netif network interface on which start the AutoIP client
00252  */
00253 err_t
00254 autoip_start(struct netif *netif)
00255 {
00256   struct autoip* autoip = netif_autoip_data(netif);
00257   err_t result = ERR_OK;
00258 
00259   LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
00260 
00261   /* Set IP-Address, Netmask and Gateway to 0 to make sure that
00262    * ARP Packets are formed correctly
00263    */
00264   netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
00265 
00266   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00267     ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
00268     netif->name[1], (u16_t)netif->num));
00269   if (autoip == NULL) {
00270     /* no AutoIP client attached yet? */
00271     LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00272       ("autoip_start(): starting new AUTOIP client\n"));
00273     autoip = (struct autoip *)mem_malloc(sizeof(struct autoip));
00274     if (autoip == NULL) {
00275       LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00276         ("autoip_start(): could not allocate autoip\n"));
00277       return ERR_MEM;
00278     }
00279     memset(autoip, 0, sizeof(struct autoip));
00280     /* store this AutoIP client in the netif */
00281     netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
00282     LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
00283   } else {
00284     autoip->state = AUTOIP_STATE_OFF;
00285     autoip->ttw = 0;
00286     autoip->sent_num = 0;
00287     ip4_addr_set_zero(&autoip->llipaddr);
00288     autoip->lastconflict = 0;
00289   }
00290 
00291   autoip_create_addr(netif, &(autoip->llipaddr));
00292   autoip_start_probing(netif);
00293 
00294   return result;
00295 }
00296 
00297 static void
00298 autoip_start_probing(struct netif *netif)
00299 {
00300   struct autoip* autoip = netif_autoip_data(netif);
00301 
00302   autoip->state = AUTOIP_STATE_PROBING;
00303   autoip->sent_num = 0;
00304   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00305      ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00306       ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00307       ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00308 
00309   /* time to wait to first probe, this is randomly
00310    * chosen out of 0 to PROBE_WAIT seconds.
00311    * compliant to RFC 3927 Section 2.2.1
00312    */
00313   autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
00314 
00315   /*
00316    * if we tried more then MAX_CONFLICTS we must limit our rate for
00317    * acquiring and probing address
00318    * compliant to RFC 3927 Section 2.2.1
00319    */
00320   if (autoip->tried_llipaddr > MAX_CONFLICTS) {
00321     autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00322   }
00323 }
00324 
00325 /**
00326  * Handle a possible change in the network configuration.
00327  *
00328  * If there is an AutoIP address configured, take the interface down
00329  * and begin probing with the same address.
00330  */
00331 void
00332 autoip_network_changed(struct netif *netif)
00333 {
00334   struct autoip* autoip = netif_autoip_data(netif);
00335 
00336   if (autoip && (autoip->state != AUTOIP_STATE_OFF)) {
00337     autoip_start_probing(netif);
00338   }
00339 }
00340 
00341 /**
00342  * @ingroup autoip 
00343  * Stop AutoIP client
00344  *
00345  * @param netif network interface on which stop the AutoIP client
00346  */
00347 err_t
00348 autoip_stop(struct netif *netif)
00349 {
00350   struct autoip* autoip = netif_autoip_data(netif);
00351 
00352   if (autoip != NULL) {
00353     autoip->state = AUTOIP_STATE_OFF;
00354     if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
00355       netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
00356     }
00357   }
00358   return ERR_OK;
00359 }
00360 
00361 /**
00362  * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
00363  */
00364 void
00365 autoip_tmr(void)
00366 {
00367   struct netif *netif = netif_list;
00368   /* loop through netif's */
00369   while (netif != NULL) {
00370     struct autoip* autoip = netif_autoip_data(netif);
00371     /* only act on AutoIP configured interfaces */
00372     if (autoip != NULL) {
00373       if (autoip->lastconflict > 0) {
00374         autoip->lastconflict--;
00375       }
00376 
00377       LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00378         ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
00379         (u16_t)(autoip->state), autoip->ttw));
00380 
00381       if (autoip->ttw > 0) {
00382         autoip->ttw--;
00383       }
00384 
00385       switch(autoip->state) {
00386         case AUTOIP_STATE_PROBING:
00387           if (autoip->ttw == 0) {
00388             if (autoip->sent_num >= PROBE_NUM) {
00389               /* Switch to ANNOUNCING: now we can bind to an IP address and use it */
00390               autoip->state = AUTOIP_STATE_ANNOUNCING;
00391               autoip_bind(netif);
00392               /* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP
00393                  which counts as an announcement */
00394               autoip->sent_num = 1;
00395               autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
00396               LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00397                  ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00398                   ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00399                   ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00400             } else {
00401               autoip_arp_probe(netif);
00402               LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
00403               autoip->sent_num++;
00404               if (autoip->sent_num == PROBE_NUM) {
00405                 /* calculate time to wait to for announce */
00406                 autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
00407               } else {
00408                 /* calculate time to wait to next probe */
00409                 autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
00410                   ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
00411                   PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
00412               }
00413             }
00414           }
00415           break;
00416 
00417         case AUTOIP_STATE_ANNOUNCING:
00418           if (autoip->ttw == 0) {
00419             autoip_arp_announce(netif);
00420             LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
00421             autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00422             autoip->sent_num++;
00423 
00424             if (autoip->sent_num >= ANNOUNCE_NUM) {
00425                 autoip->state = AUTOIP_STATE_BOUND;
00426                 autoip->sent_num = 0;
00427                 autoip->ttw = 0;
00428                  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00429                     ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00430                      ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00431                      ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00432             }
00433           }
00434           break;
00435 
00436         default:
00437           /* nothing to do in other states */
00438           break;
00439       }
00440     }
00441     /* proceed to next network interface */
00442     netif = netif->next;
00443   }
00444 }
00445 
00446 /**
00447  * Handles every incoming ARP Packet, called by etharp_input().
00448  *
00449  * @param netif network interface to use for autoip processing
00450  * @param hdr Incoming ARP packet
00451  */
00452 void
00453 autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
00454 {
00455   struct autoip* autoip = netif_autoip_data(netif);
00456 
00457   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
00458   if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) {
00459    /* when ip.src == llipaddr && hw.src != netif->hwaddr
00460     *
00461     * when probing  ip.dst == llipaddr && hw.src != netif->hwaddr
00462     * we have a conflict and must solve it
00463     */
00464     ip4_addr_t sipaddr, dipaddr;
00465     struct eth_addr netifaddr;
00466     ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
00467 
00468     /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without
00469      * structure packing (not using structure copy which breaks strict-aliasing rules).
00470      */
00471     IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
00472     IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
00473 
00474     if (autoip->state == AUTOIP_STATE_PROBING) {
00475      /* RFC 3927 Section 2.2.1:
00476       * from beginning to after ANNOUNCE_WAIT
00477       * seconds we have a conflict if
00478       * ip.src == llipaddr OR
00479       * ip.dst == llipaddr && hw.src != own hwaddr
00480       */
00481       if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
00482           (ip4_addr_isany_val(sipaddr) &&
00483            ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
00484            !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
00485         LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00486           ("autoip_arp_reply(): Probe Conflict detected\n"));
00487         autoip_restart(netif);
00488       }
00489     } else {
00490      /* RFC 3927 Section 2.5:
00491       * in any state we have a conflict if
00492       * ip.src == llipaddr && hw.src != own hwaddr
00493       */
00494       if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
00495           !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
00496         LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00497           ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
00498         autoip_handle_arp_conflict(netif);
00499       }
00500     }
00501   }
00502 }
00503 
00504 /** check if AutoIP supplied netif->ip_addr
00505  *
00506  * @param netif the netif to check
00507  * @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING),
00508  *         0 otherwise
00509  */
00510 u8_t
00511 autoip_supplied_address(const struct netif *netif)
00512 {
00513   if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) {
00514     struct autoip* autoip = netif_autoip_data(netif);
00515     return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING);
00516   }
00517   return 0;
00518 }
00519 
00520 u8_t
00521 autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr)
00522 {
00523   struct autoip* autoip = netif_autoip_data(netif);
00524   return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr));
00525 }
00526 
00527 #endif /* LWIP_IPV4 && LWIP_AUTOIP */