Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers autoip.c Source File

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 #include "lwip/opt.h"
00066 
00067 #if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
00068 
00069 #include "lwip/mem.h"
00070 #include "lwip/udp.h"
00071 #include "lwip/ip_addr.h"
00072 #include "lwip/netif.h"
00073 #include "lwip/autoip.h"
00074 #include "netif/etharp.h"
00075 
00076 #include <stdlib.h>
00077 #include <string.h>
00078 
00079 /* 169.254.0.0 */
00080 #define AUTOIP_NET         0xA9FE0000
00081 /* 169.254.1.0 */
00082 #define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
00083 /* 169.254.254.255 */
00084 #define AUTOIP_RANGE_END   (AUTOIP_NET | 0xFEFF)
00085 
00086 
00087 /** Pseudo random macro based on netif informations.
00088  * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
00089 #ifndef LWIP_AUTOIP_RAND
00090 #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
00091                                    ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
00092                                    ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
00093                                    ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
00094                                    (netif->autoip?netif->autoip->tried_llipaddr:0))
00095 #endif /* LWIP_AUTOIP_RAND */
00096 
00097 /**
00098  * Macro that generates the initial IP address to be tried by AUTOIP.
00099  * If you want to override this, define it to something else in lwipopts.h.
00100  */
00101 #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
00102 #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
00103   htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
00104                  ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
00105 #endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
00106 
00107 /* static functions */
00108 static void autoip_handle_arp_conflict(struct netif *netif);
00109 
00110 /* creates a pseudo random LL IP-Address for a network interface */
00111 static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr);
00112 
00113 /* sends an ARP probe */
00114 static err_t autoip_arp_probe(struct netif *netif);
00115 
00116 /* sends an ARP announce */
00117 static err_t autoip_arp_announce(struct netif *netif);
00118 
00119 /* configure interface for use with current LL IP-Address */
00120 static err_t autoip_bind(struct netif *netif);
00121 
00122 /* start sending probes for llipaddr */
00123 static void autoip_start_probing(struct netif *netif);
00124 
00125 /**
00126  * Initialize this module
00127  */
00128 void
00129 autoip_init(void)
00130 {
00131   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n"));
00132 }
00133 
00134 /** Set a statically allocated struct autoip to work with.
00135  * Using this prevents autoip_start to allocate it using mem_malloc.
00136  *
00137  * @param netif the netif for which to set the struct autoip
00138  * @param dhcp (uninitialised) dhcp struct allocated by the application
00139  */
00140 void
00141 autoip_set_struct(struct netif *netif, struct autoip *autoip)
00142 {
00143   LWIP_ASSERT("netif != NULL", netif != NULL);
00144   LWIP_ASSERT("autoip != NULL", autoip != NULL);
00145   LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL);
00146 
00147   /* clear data structure */
00148   memset(autoip, 0, sizeof(struct autoip));
00149   /* autoip->state = AUTOIP_STATE_OFF; */
00150   netif->autoip = autoip;
00151 }
00152 
00153 /**
00154  * Handle a IP address conflict after an ARP conflict detection
00155  */
00156 static void
00157 autoip_handle_arp_conflict(struct netif *netif)
00158 {
00159   /* Somehow detect if we are defending or retreating */
00160   unsigned char defend = 1; /* tbd */
00161 
00162   if(defend) {
00163     if(netif->autoip->lastconflict > 0) {
00164       /* retreat, there was a conflicting ARP in the last
00165        * DEFEND_INTERVAL seconds
00166        */
00167       LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00168         ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
00169 
00170       /* TODO: close all TCP sessions */
00171       autoip_start(netif);
00172     } else {
00173       LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00174         ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
00175       autoip_arp_announce(netif);
00176       netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00177     }
00178   } else {
00179     LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00180       ("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
00181     /* TODO: close all TCP sessions */
00182     autoip_start(netif);
00183   }
00184 }
00185 
00186 /**
00187  * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
00188  *
00189  * @param netif network interface on which create the IP-Address
00190  * @param ipaddr ip address to initialize
00191  */
00192 static void
00193 autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr)
00194 {
00195   /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
00196    * compliant to RFC 3927 Section 2.1
00197    * We have 254 * 256 possibilities */
00198 
00199   u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
00200   addr += netif->autoip->tried_llipaddr;
00201   addr = AUTOIP_NET | (addr & 0xffff);
00202   /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ 
00203 
00204   if (addr < AUTOIP_RANGE_START) {
00205     addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00206   }
00207   if (addr > AUTOIP_RANGE_END) {
00208     addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00209   }
00210   LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
00211     (addr <= AUTOIP_RANGE_END));
00212   ip4_addr_set_u32(ipaddr, htonl(addr));
00213   
00214   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00215     ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00216     (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
00217     ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
00218 }
00219 
00220 /**
00221  * Sends an ARP probe from a network interface
00222  *
00223  * @param netif network interface used to send the probe
00224  */
00225 static err_t
00226 autoip_arp_probe(struct netif *netif)
00227 {
00228   return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
00229     (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
00230     &netif->autoip->llipaddr, ARP_REQUEST);
00231 }
00232 
00233 /**
00234  * Sends an ARP announce from a network interface
00235  *
00236  * @param netif network interface used to send the announce
00237  */
00238 static err_t
00239 autoip_arp_announce(struct netif *netif)
00240 {
00241   return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
00242     (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, &ethzero,
00243     &netif->autoip->llipaddr, ARP_REQUEST);
00244 }
00245 
00246 /**
00247  * Configure interface for use with current LL IP-Address
00248  *
00249  * @param netif network interface to configure with current LL IP-Address
00250  */
00251 static err_t
00252 autoip_bind(struct netif *netif)
00253 {
00254   struct autoip *autoip = netif->autoip;
00255   ip_addr_t sn_mask, gw_addr;
00256 
00257   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00258     ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00259     (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
00260     ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00261     ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00262 
00263   IP4_ADDR(&sn_mask, 255, 255, 0, 0);
00264   IP4_ADDR(&gw_addr, 0, 0, 0, 0);
00265 
00266   netif_set_ipaddr(netif, &autoip->llipaddr);
00267   netif_set_netmask(netif, &sn_mask);
00268   netif_set_gw(netif, &gw_addr);  
00269 
00270   /* bring the interface up */
00271   netif_set_up(netif);
00272 
00273   return ERR_OK;
00274 }
00275 
00276 /**
00277  * Start AutoIP client
00278  *
00279  * @param netif network interface on which start the AutoIP client
00280  */
00281 err_t
00282 autoip_start(struct netif *netif)
00283 {
00284   struct autoip *autoip = netif->autoip;
00285   err_t result = ERR_OK;
00286 
00287   if(netif_is_up(netif)) {
00288     netif_set_down(netif);
00289   }
00290 
00291   /* Set IP-Address, Netmask and Gateway to 0 to make sure that
00292    * ARP Packets are formed correctly
00293    */
00294   ip_addr_set_zero(&netif->ip_addr);
00295   ip_addr_set_zero(&netif->netmask);
00296   ip_addr_set_zero(&netif->gw);
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\n"));
00315   } else {
00316     autoip->state = AUTOIP_STATE_OFF;
00317     autoip->ttw = 0;
00318     autoip->sent_num = 0;
00319     memset(&autoip->llipaddr, 0, sizeof(ip_addr_t));
00320     autoip->lastconflict = 0;
00321   }
00322 
00323   autoip_create_addr(netif, &(autoip->llipaddr));
00324   autoip->tried_llipaddr++;
00325   autoip_start_probing(netif);
00326 
00327   return result;
00328 }
00329 
00330 static void
00331 autoip_start_probing(struct netif *netif)
00332 {
00333   struct autoip *autoip = netif->autoip;
00334 
00335   autoip->state = AUTOIP_STATE_PROBING;
00336   autoip->sent_num = 0;
00337   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00338      ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00339       ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
00340       ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
00341 
00342   /* time to wait to first probe, this is randomly
00343    * choosen out of 0 to PROBE_WAIT seconds.
00344    * compliant to RFC 3927 Section 2.2.1
00345    */
00346   autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
00347 
00348   /*
00349    * if we tried more then MAX_CONFLICTS we must limit our rate for
00350    * accquiring and probing address
00351    * compliant to RFC 3927 Section 2.2.1
00352    */
00353   if(autoip->tried_llipaddr > MAX_CONFLICTS) {
00354     autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00355   }
00356 }
00357 
00358 /**
00359  * Handle a possible change in the network configuration.
00360  *
00361  * If there is an AutoIP address configured, take the interface down
00362  * and begin probing with the same address.
00363  */
00364 void
00365 autoip_network_changed(struct netif *netif)
00366 {
00367   if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
00368     netif_set_down(netif);
00369     autoip_start_probing(netif);
00370   }
00371 }
00372 
00373 /**
00374  * Stop AutoIP client
00375  *
00376  * @param netif network interface on which stop the AutoIP client
00377  */
00378 err_t
00379 autoip_stop(struct netif *netif)
00380 {
00381   netif->autoip->state = AUTOIP_STATE_OFF;
00382   netif_set_down(netif);
00383   return ERR_OK;
00384 }
00385 
00386 /**
00387  * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
00388  */
00389 void
00390 autoip_tmr()
00391 {
00392   struct netif *netif = netif_list;
00393   /* loop through netif's */
00394   while (netif != NULL) {
00395     /* only act on AutoIP configured interfaces */
00396     if (netif->autoip != NULL) {
00397       if(netif->autoip->lastconflict > 0) {
00398         netif->autoip->lastconflict--;
00399       }
00400 
00401       LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00402         ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
00403         (u16_t)(netif->autoip->state), netif->autoip->ttw));
00404 
00405       switch(netif->autoip->state) {
00406         case AUTOIP_STATE_PROBING:
00407           if(netif->autoip->ttw > 0) {
00408             netif->autoip->ttw--;
00409           } else {
00410             if(netif->autoip->sent_num >= PROBE_NUM) {
00411               netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
00412               netif->autoip->sent_num = 0;
00413               netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
00414               LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00415                  ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00416                   ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
00417                   ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
00418             } else {
00419               autoip_arp_probe(netif);
00420               LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00421                 ("autoip_tmr() PROBING Sent Probe\n"));
00422               netif->autoip->sent_num++;
00423               /* calculate time to wait to next probe */
00424               netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
00425                 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
00426                 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
00427             }
00428           }
00429           break;
00430 
00431         case AUTOIP_STATE_ANNOUNCING:
00432           if(netif->autoip->ttw > 0) {
00433             netif->autoip->ttw--;
00434           } else {
00435             if(netif->autoip->sent_num == 0) {
00436              /* We are here the first time, so we waited ANNOUNCE_WAIT seconds
00437               * Now we can bind to an IP address and use it.
00438               *
00439               * autoip_bind calls netif_set_up. This triggers a gratuitous ARP
00440               * which counts as an announcement.
00441               */
00442               autoip_bind(netif);
00443             } else {
00444               autoip_arp_announce(netif);
00445               LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00446                 ("autoip_tmr() ANNOUNCING Sent Announce\n"));
00447             }
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     }
00464     /* proceed to next network interface */
00465     netif = netif->next;
00466   }
00467 }
00468 
00469 /**
00470  * Handles every incoming ARP Packet, called by etharp_arp_input.
00471  *
00472  * @param netif network interface to use for autoip processing
00473  * @param hdr Incoming ARP packet
00474  */
00475 void
00476 autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
00477 {
00478   LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
00479   if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
00480    /* when ip.src == llipaddr && hw.src != netif->hwaddr
00481     *
00482     * when probing  ip.dst == llipaddr && hw.src != netif->hwaddr
00483     * we have a conflict and must solve it
00484     */
00485     ip_addr_t sipaddr, dipaddr;
00486     struct eth_addr netifaddr;
00487     netifaddr.addr[0] = netif->hwaddr[0];
00488     netifaddr.addr[1] = netif->hwaddr[1];
00489     netifaddr.addr[2] = netif->hwaddr[2];
00490     netifaddr.addr[3] = netif->hwaddr[3];
00491     netifaddr.addr[4] = netif->hwaddr[4];
00492     netifaddr.addr[5] = netif->hwaddr[5];
00493 
00494     /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
00495      * structure packing (not using structure copy which breaks strict-aliasing rules).
00496      */
00497     SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
00498     SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
00499       
00500     if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
00501         ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
00502          (netif->autoip->sent_num == 0))) {
00503      /* RFC 3927 Section 2.2.1:
00504       * from beginning to after ANNOUNCE_WAIT
00505       * seconds we have a conflict if
00506       * ip.src == llipaddr OR
00507       * ip.dst == llipaddr && hw.src != own hwaddr
00508       */
00509       if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
00510           (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
00511            !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
00512         LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00513           ("autoip_arp_reply(): Probe Conflict detected\n"));
00514         autoip_start(netif);
00515       }
00516     } else {
00517      /* RFC 3927 Section 2.5:
00518       * in any state we have a conflict if
00519       * ip.src == llipaddr && hw.src != own hwaddr
00520       */
00521       if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
00522           !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
00523         LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00524           ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
00525         autoip_handle_arp_conflict(netif);
00526       }
00527     }
00528   }
00529 }
00530 
00531 #endif /* LWIP_AUTOIP */