00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include "lwip/opt.h"
00066
00067 #if LWIP_AUTOIP
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
00080 #define AUTOIP_NET 0xA9FE0000
00081
00082 #define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
00083
00084 #define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF)
00085
00086
00087
00088
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
00096
00097
00098
00099
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
00106
00107
00108 static void autoip_handle_arp_conflict(struct netif *netif);
00109
00110
00111 static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr);
00112
00113
00114 static err_t autoip_arp_probe(struct netif *netif);
00115
00116
00117 static err_t autoip_arp_announce(struct netif *netif);
00118
00119
00120 static err_t autoip_bind(struct netif *netif);
00121
00122
00123 static void autoip_start_probing(struct netif *netif);
00124
00125
00126
00127
00128
00129
00130
00131
00132 void
00133 autoip_set_struct(struct netif *netif, struct autoip *autoip)
00134 {
00135 LWIP_ASSERT("netif != NULL", netif != NULL);
00136 LWIP_ASSERT("autoip != NULL", autoip != NULL);
00137 LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL);
00138
00139
00140 memset(autoip, 0, sizeof(struct autoip));
00141
00142 netif->autoip = autoip;
00143 }
00144
00145
00146
00147
00148
00149 static void
00150 autoip_restart(struct netif *netif)
00151 {
00152 netif->autoip->tried_llipaddr++;
00153 autoip_start(netif);
00154 }
00155
00156
00157
00158
00159 static void
00160 autoip_handle_arp_conflict(struct netif *netif)
00161 {
00162
00163 unsigned char defend = 1;
00164
00165 if (defend) {
00166 if (netif->autoip->lastconflict > 0) {
00167
00168
00169
00170 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00171 ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
00172
00173
00174 autoip_restart(netif);
00175 } else {
00176 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00177 ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
00178 autoip_arp_announce(netif);
00179 netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00180 }
00181 } else {
00182 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00183 ("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
00184
00185 autoip_restart(netif);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 static void
00196 autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr)
00197 {
00198
00199
00200
00201
00202 u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
00203 addr += netif->autoip->tried_llipaddr;
00204 addr = AUTOIP_NET | (addr & 0xffff);
00205
00206
00207 if (addr < AUTOIP_RANGE_START) {
00208 addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00209 }
00210 if (addr > AUTOIP_RANGE_END) {
00211 addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
00212 }
00213 LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
00214 (addr <= AUTOIP_RANGE_END));
00215 ip4_addr_set_u32(ipaddr, htonl(addr));
00216
00217 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00218 ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00219 (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
00220 ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
00221 }
00222
00223
00224
00225
00226
00227
00228 static err_t
00229 autoip_arp_probe(struct netif *netif)
00230 {
00231 return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
00232 (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero,
00233 &netif->autoip->llipaddr, ARP_REQUEST);
00234 }
00235
00236
00237
00238
00239
00240
00241 static err_t
00242 autoip_arp_announce(struct netif *netif)
00243 {
00244 return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
00245 (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero,
00246 &netif->autoip->llipaddr, ARP_REQUEST);
00247 }
00248
00249
00250
00251
00252
00253
00254 static err_t
00255 autoip_bind(struct netif *netif)
00256 {
00257 struct autoip *autoip = netif->autoip;
00258 ip_addr_t sn_mask, gw_addr;
00259
00260 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00261 ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00262 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
00263 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
00264 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
00265
00266 IP4_ADDR(&sn_mask, 255, 255, 0, 0);
00267 IP4_ADDR(&gw_addr, 0, 0, 0, 0);
00268
00269 netif_set_ipaddr(netif, &autoip->llipaddr);
00270 netif_set_netmask(netif, &sn_mask);
00271 netif_set_gw(netif, &gw_addr);
00272
00273
00274 netif_set_up(netif);
00275
00276 return ERR_OK;
00277 }
00278
00279
00280
00281
00282
00283
00284 err_t
00285 autoip_start(struct netif *netif)
00286 {
00287 struct autoip *autoip = netif->autoip;
00288 err_t result = ERR_OK;
00289
00290 if (netif_is_up(netif)) {
00291 netif_set_down(netif);
00292 }
00293
00294
00295
00296
00297 ip_addr_set_zero(&netif->ip_addr);
00298 ip_addr_set_zero(&netif->netmask);
00299 ip_addr_set_zero(&netif->gw);
00300
00301 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00302 ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
00303 netif->name[1], (u16_t)netif->num));
00304 if (autoip == NULL) {
00305
00306 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00307 ("autoip_start(): starting new AUTOIP client\n"));
00308 autoip = (struct autoip *)mem_malloc(sizeof(struct autoip));
00309 if (autoip == NULL) {
00310 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00311 ("autoip_start(): could not allocate autoip\n"));
00312 return ERR_MEM;
00313 }
00314 memset(autoip, 0, sizeof(struct autoip));
00315
00316 netif->autoip = autoip;
00317 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
00318 } else {
00319 autoip->state = AUTOIP_STATE_OFF;
00320 autoip->ttw = 0;
00321 autoip->sent_num = 0;
00322 ip_addr_set_zero(&autoip->llipaddr);
00323 autoip->lastconflict = 0;
00324 }
00325
00326 autoip_create_addr(netif, &(autoip->llipaddr));
00327 autoip_start_probing(netif);
00328
00329 return result;
00330 }
00331
00332 static void
00333 autoip_start_probing(struct netif *netif)
00334 {
00335 struct autoip *autoip = netif->autoip;
00336
00337 autoip->state = AUTOIP_STATE_PROBING;
00338 autoip->sent_num = 0;
00339 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00340 ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00341 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
00342 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
00343
00344
00345
00346
00347
00348 autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
00349
00350
00351
00352
00353
00354
00355 if (autoip->tried_llipaddr > MAX_CONFLICTS) {
00356 autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 void
00367 autoip_network_changed(struct netif *netif)
00368 {
00369 if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
00370 netif_set_down(netif);
00371 autoip_start_probing(netif);
00372 }
00373 }
00374
00375
00376
00377
00378
00379
00380 err_t
00381 autoip_stop(struct netif *netif)
00382 {
00383 netif->autoip->state = AUTOIP_STATE_OFF;
00384 netif_set_down(netif);
00385 return ERR_OK;
00386 }
00387
00388
00389
00390
00391 void
00392 autoip_tmr()
00393 {
00394 struct netif *netif = netif_list;
00395
00396 while (netif != NULL) {
00397
00398 if (netif->autoip != NULL) {
00399 if (netif->autoip->lastconflict > 0) {
00400 netif->autoip->lastconflict--;
00401 }
00402
00403 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00404 ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
00405 (u16_t)(netif->autoip->state), netif->autoip->ttw));
00406
00407 switch(netif->autoip->state) {
00408 case AUTOIP_STATE_PROBING:
00409 if (netif->autoip->ttw > 0) {
00410 netif->autoip->ttw--;
00411 } else {
00412 if (netif->autoip->sent_num >= PROBE_NUM) {
00413 netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
00414 netif->autoip->sent_num = 0;
00415 netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
00416 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00417 ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00418 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
00419 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
00420 } else {
00421 autoip_arp_probe(netif);
00422 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00423 ("autoip_tmr() PROBING Sent Probe\n"));
00424 netif->autoip->sent_num++;
00425
00426 netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
00427 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
00428 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
00429 }
00430 }
00431 break;
00432
00433 case AUTOIP_STATE_ANNOUNCING:
00434 if (netif->autoip->ttw > 0) {
00435 netif->autoip->ttw--;
00436 } else {
00437 if (netif->autoip->sent_num == 0) {
00438
00439
00440
00441
00442
00443
00444 autoip_bind(netif);
00445 } else {
00446 autoip_arp_announce(netif);
00447 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
00448 ("autoip_tmr() ANNOUNCING Sent Announce\n"));
00449 }
00450 netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
00451 netif->autoip->sent_num++;
00452
00453 if (netif->autoip->sent_num >= ANNOUNCE_NUM) {
00454 netif->autoip->state = AUTOIP_STATE_BOUND;
00455 netif->autoip->sent_num = 0;
00456 netif->autoip->ttw = 0;
00457 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00458 ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00459 ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
00460 ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
00461 }
00462 }
00463 break;
00464 }
00465 }
00466
00467 netif = netif->next;
00468 }
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 void
00478 autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
00479 {
00480 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
00481 if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
00482
00483
00484
00485
00486
00487 ip_addr_t sipaddr, dipaddr;
00488 struct eth_addr netifaddr;
00489 ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
00490
00491
00492
00493
00494 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
00495 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
00496
00497 if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
00498 ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
00499 (netif->autoip->sent_num == 0))) {
00500
00501
00502
00503
00504
00505
00506 if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
00507 (ip_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
00515
00516
00517
00518 if (ip_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 #endif