80 #if LWIP_IPV4 && LWIP_AUTOIP 94 #ifndef LWIP_AUTOIP_RAND 95 #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ 96 ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ 97 ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ 98 ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ 99 (netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0)) 106 #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR 107 #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ 108 lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ 109 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) 114 static void autoip_start_probing(
struct netif *
netif);
125 autoip_set_struct(
struct netif *
netif,
struct autoip *autoip)
127 LWIP_ASSERT(
"netif != NULL", netif != NULL);
128 LWIP_ASSERT(
"autoip != NULL", autoip != NULL);
129 LWIP_ASSERT(
"netif already has a struct autoip set",
130 netif_autoip_data(netif) == NULL);
133 memset(autoip, 0,
sizeof(
struct autoip));
135 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
143 autoip_restart(
struct netif *netif)
145 struct autoip* autoip = netif_autoip_data(netif);
146 autoip->tried_llipaddr++;
154 autoip_handle_arp_conflict(
struct netif *netif)
156 struct autoip* autoip = netif_autoip_data(netif);
165 if (autoip->lastconflict > 0) {
168 (
"autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
171 autoip_restart(netif);
174 (
"autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
175 autoip_arp_announce(netif);
176 autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
187 autoip_create_addr(
struct netif *netif, ip4_addr_t *ipaddr)
189 struct autoip* autoip = netif_autoip_data(netif);
195 u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
196 addr += autoip->tried_llipaddr;
197 addr = AUTOIP_NET | (addr & 0xffff);
200 if (addr < AUTOIP_RANGE_START) {
201 addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
203 if (addr > AUTOIP_RANGE_END) {
204 addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
206 LWIP_ASSERT(
"AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
207 (addr <= AUTOIP_RANGE_END));
208 ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
211 (
"autoip_create_addr(): tried_llipaddr=%"U16_F
", %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
212 (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
213 ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
222 autoip_arp_probe(
struct netif *netif)
224 struct autoip* autoip = netif_autoip_data(netif);
226 return etharp_request(netif, &autoip->llipaddr);
235 autoip_arp_announce(
struct netif *netif)
237 return etharp_gratuitous(netif);
246 autoip_bind(
struct netif *netif)
248 struct autoip* autoip = netif_autoip_data(netif);
249 ip4_addr_t sn_mask, gw_addr;
252 (
"autoip_bind(netif=%p) %c%c%"U16_F
" %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
253 (
void*)netif, netif->
name[0], netif->
name[1], (u16_t)netif->
num,
254 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
255 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
257 IP4_ADDR(&sn_mask, 255, 255, 0, 0);
258 IP4_ADDR(&gw_addr, 0, 0, 0, 0);
260 netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
273 autoip_start(
struct netif *netif)
275 struct autoip* autoip = netif_autoip_data(netif);
283 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
286 (
"autoip_start(netif=%p) %c%c%"U16_F
"\n", (
void*)netif, netif->
name[0],
287 netif->
name[1], (u16_t)netif->
num));
288 if (autoip == NULL) {
291 (
"autoip_start(): starting new AUTOIP client\n"));
292 autoip = (
struct autoip *)
mem_malloc(
sizeof(
struct autoip));
293 if (autoip == NULL) {
295 (
"autoip_start(): could not allocate autoip\n"));
298 memset(autoip, 0,
sizeof(
struct autoip));
300 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
303 autoip->state = AUTOIP_STATE_OFF;
305 autoip->sent_num = 0;
306 ip4_addr_set_zero(&autoip->llipaddr);
307 autoip->lastconflict = 0;
310 autoip_create_addr(netif, &(autoip->llipaddr));
311 autoip_start_probing(netif);
317 autoip_start_probing(
struct netif *netif)
319 struct autoip* autoip = netif_autoip_data(netif);
321 autoip->state = AUTOIP_STATE_PROBING;
322 autoip->sent_num = 0;
324 (
"autoip_start_probing(): changing state to PROBING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
325 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
326 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
332 autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
339 if (autoip->tried_llipaddr > MAX_CONFLICTS) {
340 autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
351 autoip_network_changed(
struct netif *netif)
353 struct autoip* autoip = netif_autoip_data(netif);
355 if (autoip && (autoip->state != AUTOIP_STATE_OFF)) {
356 autoip_start_probing(netif);
367 autoip_stop(
struct netif *netif)
369 struct autoip* autoip = netif_autoip_data(netif);
371 if (autoip != NULL) {
372 autoip->state = AUTOIP_STATE_OFF;
373 if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
374 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
388 while (netif != NULL) {
389 struct autoip* autoip = netif_autoip_data(netif);
391 if (autoip != NULL) {
392 if (autoip->lastconflict > 0) {
393 autoip->lastconflict--;
397 (
"autoip_tmr() AutoIP-State: %"U16_F
", ttw=%"U16_F
"\n",
398 (u16_t)(autoip->state), autoip->ttw));
400 if (autoip->ttw > 0) {
404 switch(autoip->state) {
405 case AUTOIP_STATE_PROBING:
406 if (autoip->ttw == 0) {
407 if (autoip->sent_num >= PROBE_NUM) {
409 autoip->state = AUTOIP_STATE_ANNOUNCING;
413 autoip->sent_num = 1;
414 autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
416 (
"autoip_tmr(): changing state to ANNOUNCING: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
417 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
418 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
420 autoip_arp_probe(netif);
423 if (autoip->sent_num == PROBE_NUM) {
425 autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
428 autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
429 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
430 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
436 case AUTOIP_STATE_ANNOUNCING:
437 if (autoip->ttw == 0) {
438 autoip_arp_announce(netif);
440 autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
443 if (autoip->sent_num >= ANNOUNCE_NUM) {
444 autoip->state = AUTOIP_STATE_BOUND;
445 autoip->sent_num = 0;
448 (
"autoip_tmr(): changing state to BOUND: %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
449 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
450 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
472 autoip_arp_reply(
struct netif *netif,
struct etharp_hdr *hdr)
474 struct autoip* autoip = netif_autoip_data(netif);
477 if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) {
483 ip4_addr_t sipaddr, dipaddr;
490 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
491 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
493 if (autoip->state == AUTOIP_STATE_PROBING) {
500 if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
501 (ip4_addr_isany_val(sipaddr) &&
502 ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
503 !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
505 (
"autoip_arp_reply(): Probe Conflict detected\n"));
506 autoip_restart(netif);
513 if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
514 !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
516 (
"autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
517 autoip_handle_arp_conflict(netif);
530 autoip_supplied_address(
const struct netif *netif)
532 if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) {
533 struct autoip* autoip = netif_autoip_data(netif);
534 return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING);
540 autoip_accept_packet(
struct netif *netif,
const ip4_addr_t *addr)
542 struct autoip* autoip = netif_autoip_data(netif);
543 return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr));
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
struct netif * netif_list
#define LWIP_DEBUGF(debug, message)
#define netif_is_up(netif)
#define LWIP_DBG_LEVEL_WARNING
void * mem_malloc(mem_size_t size)
#define ETHADDR16_COPY(dst, src)