ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

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