71 #include "lwip/ip_addr.h"
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);
123 static void autoip_start_probing(
struct netif *
netif);
141 autoip_set_struct(
struct netif *
netif,
struct autoip *autoip)
145 LWIP_ASSERT(
"netif already has a struct autoip set", netif->autoip ==
NULL);
148 memset(autoip, 0,
sizeof(
struct autoip));
150 netif->autoip = autoip;
158 autoip_restart(
struct netif *netif)
160 netif->autoip->tried_llipaddr++;
168 autoip_handle_arp_conflict(
struct netif *netif)
171 unsigned char defend = 1;
174 if(netif->autoip->lastconflict > 0) {
179 (
"autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
182 autoip_restart(netif);
185 (
"autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
186 autoip_arp_announce(netif);
187 netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
191 (
"autoip_handle_arp_conflict(): we do not defend, retreating\n"));
193 autoip_restart(netif);
204 autoip_create_addr(
struct netif *netif,
ip_addr_t *ipaddr)
210 u32_t addr =
ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
211 addr += netif->autoip->tried_llipaddr;
212 addr = AUTOIP_NET | (addr & 0xffff);
215 if (addr < AUTOIP_RANGE_START) {
216 addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
218 if (addr > AUTOIP_RANGE_END) {
219 addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
221 LWIP_ASSERT(
"AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
222 (addr <= AUTOIP_RANGE_END));
237 autoip_arp_probe(
struct netif *netif)
239 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
241 &netif->autoip->llipaddr, ARP_REQUEST);
250 autoip_arp_announce(
struct netif *netif)
252 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
253 (
struct eth_addr *)netif->
hwaddr, &netif->autoip->llipaddr, ðzero,
254 &netif->autoip->llipaddr, ARP_REQUEST);
263 autoip_bind(
struct netif *netif)
265 struct autoip *autoip = netif->autoip;
269 (
"autoip_bind(netif=%p) %c%c%"U16_F
" %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
293 autoip_start(
struct netif *netif)
295 struct autoip *autoip = netif->autoip;
310 (
"autoip_start(netif=%p) %c%c%"U16_F
"\n", (
void*)netif, netif->
name[0],
315 (
"autoip_start(): starting new AUTOIP client\n"));
316 autoip = (
struct autoip *)
mem_malloc(
sizeof(
struct autoip));
319 (
"autoip_start(): could not allocate autoip\n"));
322 memset(autoip, 0,
sizeof(
struct autoip));
324 netif->autoip = autoip;
327 autoip->state = AUTOIP_STATE_OFF;
329 autoip->sent_num = 0;
331 autoip->lastconflict = 0;
334 autoip_create_addr(netif, &(autoip->llipaddr));
335 autoip_start_probing(netif);
341 autoip_start_probing(
struct netif *netif)
343 struct autoip *autoip = netif->autoip;
345 autoip->
state = AUTOIP_STATE_PROBING;
346 autoip->sent_num = 0;
348 (
"autoip_start_probing(): changing state to PROBING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
356 autoip->ttw = (
u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
363 if(autoip->tried_llipaddr > MAX_CONFLICTS) {
364 autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
375 autoip_network_changed(
struct netif *netif)
377 if (netif->autoip && netif->autoip->
state != AUTOIP_STATE_OFF) {
379 autoip_start_probing(netif);
389 autoip_stop(
struct netif *netif)
391 netif->autoip->
state = AUTOIP_STATE_OFF;
404 while (netif !=
NULL) {
406 if (netif->autoip !=
NULL) {
407 if(netif->autoip->lastconflict > 0) {
408 netif->autoip->lastconflict--;
412 (
"autoip_tmr() AutoIP-State: %"U16_F
", ttw=%"U16_F
"\n",
413 (
u16_t)(netif->autoip->
state), netif->autoip->ttw));
415 switch(netif->autoip->
state) {
416 case AUTOIP_STATE_PROBING:
417 if(netif->autoip->ttw > 0) {
418 netif->autoip->ttw--;
420 if(netif->autoip->sent_num >= PROBE_NUM) {
421 netif->autoip->
state = AUTOIP_STATE_ANNOUNCING;
422 netif->autoip->sent_num = 0;
423 netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
425 (
"autoip_tmr(): changing state to ANNOUNCING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
429 autoip_arp_probe(netif);
431 (
"autoip_tmr() PROBING Sent Probe\n"));
432 netif->autoip->sent_num++;
434 netif->autoip->ttw = (
u16_t)((LWIP_AUTOIP_RAND(netif) %
435 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
436 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
441 case AUTOIP_STATE_ANNOUNCING:
442 if(netif->autoip->ttw > 0) {
443 netif->autoip->ttw--;
445 if(netif->autoip->sent_num == 0) {
454 autoip_arp_announce(netif);
456 (
"autoip_tmr() ANNOUNCING Sent Announce\n"));
458 netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
459 netif->autoip->sent_num++;
461 if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
462 netif->autoip->
state = AUTOIP_STATE_BOUND;
463 netif->autoip->sent_num = 0;
464 netif->autoip->ttw = 0;
466 (
"autoip_tmr(): changing state to BOUND: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
486 autoip_arp_reply(
struct netif *netif,
struct etharp_hdr *hdr)
489 if ((netif->autoip !=
NULL) && (netif->autoip->
state != AUTOIP_STATE_OFF)) {
496 struct eth_addr netifaddr;
497 ETHADDR16_COPY(netifaddr.addr, netif->
hwaddr);
505 if ((netif->autoip->
state == AUTOIP_STATE_PROBING) ||
506 ((netif->autoip->
state == AUTOIP_STATE_ANNOUNCING) &&
507 (netif->autoip->sent_num == 0))) {
514 if ((
ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
515 (
ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
516 !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
518 (
"autoip_arp_reply(): Probe Conflict detected\n"));
519 autoip_restart(netif);
526 if (
ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
527 !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
529 (
"autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
530 autoip_handle_arp_conflict(netif);