Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
lwip_autoip.c
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 */
Generated on Tue Jul 12 2022 11:02:41 by
