67 #if LWIP_IPV4 && LWIP_AUTOIP 80 #define AUTOIP_NET 0xA9FE0000 82 #define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) 84 #define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) 89 #ifndef LWIP_AUTOIP_RAND 90 #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ 91 ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ 92 ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ 93 ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ 94 (netif->autoip?netif->autoip->tried_llipaddr:0)) 101 #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR 102 #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ 103 htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ 104 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) 108 static void autoip_handle_arp_conflict(
struct netif *
netif);
111 static void autoip_create_addr(
struct netif *
netif, ip4_addr_t *ipaddr);
123 static void autoip_start_probing(
struct netif *
netif);
133 autoip_set_struct(
struct netif *
netif,
struct autoip *autoip)
137 LWIP_ASSERT(
"netif already has a struct autoip set", netif->autoip ==
NULL);
140 memset(autoip, 0,
sizeof(
struct autoip));
142 netif->autoip = autoip;
150 autoip_restart(
struct netif *netif)
152 netif->autoip->tried_llipaddr++;
160 autoip_handle_arp_conflict(
struct netif *netif)
163 unsigned char defend = 1;
166 if (netif->autoip->lastconflict > 0) {
171 (
"autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
174 autoip_restart(netif);
177 (
"autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
178 autoip_arp_announce(netif);
179 netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
183 (
"autoip_handle_arp_conflict(): we do not defend, retreating\n"));
185 autoip_restart(netif);
196 autoip_create_addr(
struct netif *netif, ip4_addr_t *ipaddr)
202 u32_t addr =
ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
203 addr += netif->autoip->tried_llipaddr;
204 addr = AUTOIP_NET | (addr & 0xffff);
207 if (addr < AUTOIP_RANGE_START) {
208 addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
210 if (addr > AUTOIP_RANGE_END) {
211 addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
213 LWIP_ASSERT(
"AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
214 (addr <= AUTOIP_RANGE_END));
215 ip4_addr_set_u32(ipaddr,
htonl(addr));
219 (
u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
220 ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
229 autoip_arp_probe(
struct netif *netif)
231 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
232 (
struct eth_addr *)netif->
hwaddr, IP4_ADDR_ANY, ðzero,
233 &netif->autoip->llipaddr, ARP_REQUEST);
242 autoip_arp_announce(
struct netif *netif)
244 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
245 (
struct eth_addr *)netif->
hwaddr, &netif->autoip->llipaddr, ðzero,
246 &netif->autoip->llipaddr, ARP_REQUEST);
255 autoip_bind(
struct netif *netif)
257 struct autoip *autoip = netif->autoip;
258 ip4_addr_t sn_mask, gw_addr;
261 (
"autoip_bind(netif=%p) %c%c%"U16_F
" %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
263 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
264 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
266 IP4_ADDR(&sn_mask, 255, 255, 0, 0);
267 IP4_ADDR(&gw_addr, 0, 0, 0, 0);
269 netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
281 autoip_start(
struct netif *netif)
283 struct autoip *autoip = netif->autoip;
291 netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
294 (
"autoip_start(netif=%p) %c%c%"U16_F
"\n", (
void*)netif, netif->
name[0],
296 if (autoip ==
NULL) {
299 (
"autoip_start(): starting new AUTOIP client\n"));
300 autoip = (
struct autoip *)
mem_malloc(
sizeof(
struct autoip));
301 if (autoip ==
NULL) {
303 (
"autoip_start(): could not allocate autoip\n"));
306 memset(autoip, 0,
sizeof(
struct autoip));
308 netif->autoip = autoip;
311 autoip->state = AUTOIP_STATE_OFF;
313 autoip->sent_num = 0;
314 ip4_addr_set_zero(&autoip->llipaddr);
315 autoip->lastconflict = 0;
318 autoip_create_addr(netif, &(autoip->llipaddr));
319 autoip_start_probing(netif);
325 autoip_start_probing(
struct netif *netif)
327 struct autoip *autoip = netif->autoip;
329 autoip->
state = AUTOIP_STATE_PROBING;
330 autoip->sent_num = 0;
332 (
"autoip_start_probing(): changing state to PROBING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
333 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
334 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
340 autoip->ttw = (
u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
347 if (autoip->tried_llipaddr > MAX_CONFLICTS) {
348 autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
359 autoip_network_changed(
struct netif *netif)
361 if (netif->autoip && netif->autoip->
state != AUTOIP_STATE_OFF) {
362 autoip_start_probing(netif);
372 autoip_stop(
struct netif *netif)
375 netif->autoip->
state = AUTOIP_STATE_OFF;
376 if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
377 netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
391 while (netif !=
NULL) {
393 if (netif->autoip !=
NULL) {
394 if (netif->autoip->lastconflict > 0) {
395 netif->autoip->lastconflict--;
399 (
"autoip_tmr() AutoIP-State: %"U16_F
", ttw=%"U16_F
"\n",
400 (
u16_t)(netif->autoip->
state), netif->autoip->ttw));
402 switch(netif->autoip->
state) {
403 case AUTOIP_STATE_PROBING:
404 if (netif->autoip->ttw > 0) {
405 netif->autoip->ttw--;
407 if (netif->autoip->sent_num >= PROBE_NUM) {
408 netif->autoip->
state = AUTOIP_STATE_ANNOUNCING;
409 netif->autoip->sent_num = 0;
410 netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
412 (
"autoip_tmr(): changing state to ANNOUNCING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
413 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
414 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
416 autoip_arp_probe(netif);
418 (
"autoip_tmr() PROBING Sent Probe\n"));
419 netif->autoip->sent_num++;
421 netif->autoip->ttw = (
u16_t)((LWIP_AUTOIP_RAND(netif) %
422 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
423 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
428 case AUTOIP_STATE_ANNOUNCING:
429 if (netif->autoip->ttw > 0) {
430 netif->autoip->ttw--;
432 if (netif->autoip->sent_num == 0) {
441 autoip_arp_announce(netif);
443 (
"autoip_tmr() ANNOUNCING Sent Announce\n"));
445 netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
446 netif->autoip->sent_num++;
448 if (netif->autoip->sent_num >= ANNOUNCE_NUM) {
449 netif->autoip->
state = AUTOIP_STATE_BOUND;
450 netif->autoip->sent_num = 0;
451 netif->autoip->ttw = 0;
453 (
"autoip_tmr(): changing state to BOUND: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
454 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
455 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
477 autoip_arp_reply(
struct netif *netif,
struct etharp_hdr *hdr)
480 if ((netif->autoip !=
NULL) && (netif->autoip->
state != AUTOIP_STATE_OFF)) {
486 ip4_addr_t sipaddr, dipaddr;
487 struct eth_addr netifaddr;
488 ETHADDR16_COPY(netifaddr.addr, netif->
hwaddr);
493 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
494 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
496 if ((netif->autoip->
state == AUTOIP_STATE_PROBING) ||
497 ((netif->autoip->
state == AUTOIP_STATE_ANNOUNCING) &&
498 (netif->autoip->sent_num == 0))) {
505 if ((ip4_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
506 (ip4_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
507 !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
509 (
"autoip_arp_reply(): Probe Conflict detected\n"));
510 autoip_restart(netif);
517 if (ip4_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
518 !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
520 (
"autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
521 autoip_handle_arp_conflict(netif);
534 autoip_supplied_address(
struct netif *netif)
536 if ((netif !=
NULL) && (netif->autoip !=
NULL)) {
537 if (netif->autoip->
state == AUTOIP_STATE_BOUND) {
struct netif * netif_list
#define LWIP_DBG_LEVEL_WARNING
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
#define LWIP_ASSERT(message, assertion)
void * mem_malloc(mem_size_t size)
#define LWIP_ERROR(message, expression, handler)
#define netif_is_up(netif)
#define LWIP_DEBUGF(debug, message)