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.
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 #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, ðbroadcast, 00229 (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, 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, ðbroadcast, 00242 (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, 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 */
Generated on Tue Jul 12 2022 21:10:24 by 1.7.2