Warning, cross-references for /kernel/lwip/core/ipv4/autoip.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 #include "lwip/opt.h"
0066
0067 #if LWIP_AUTOIP
0068
0069 #include "lwip/mem.h"
0070 #include "lwip/udp.h"
0071 #include "lwip/ip_addr.h"
0072 #include "lwip/netif.h"
0073 #include "lwip/autoip.h"
0074 #include "netif/etharp.h"
0075
0076 #include <stdlib.h>
0077 #include <string.h>
0078
0079
0080 #define AUTOIP_NET 0xA9FE0000
0081
0082 #define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
0083
0084 #define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF)
0085
0086
0087
0088
0089 #ifndef LWIP_AUTOIP_RAND
0090 #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
0091 ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
0092 ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
0093 ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
0094 (netif->autoip?netif->autoip->tried_llipaddr:0))
0095 #endif
0096
0097
0098
0099
0100
0101 #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
0102 #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
0103 htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
0104 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
0105 #endif
0106
0107
0108 static void autoip_handle_arp_conflict(struct netif *netif);
0109
0110
0111 static void autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr);
0112
0113
0114 static err_t autoip_arp_probe(struct netif *netif);
0115
0116
0117 static err_t autoip_arp_announce(struct netif *netif);
0118
0119
0120 static err_t autoip_bind(struct netif *netif);
0121
0122
0123 static void autoip_start_probing(struct netif *netif);
0124
0125
0126
0127
0128 void
0129 autoip_init(void)
0130 {
0131 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n"));
0132 }
0133
0134
0135
0136
0137 static void
0138 autoip_handle_arp_conflict(struct netif *netif)
0139 {
0140
0141 unsigned char defend = 1;
0142
0143 if(defend) {
0144 if(netif->autoip->lastconflict > 0) {
0145
0146
0147
0148 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0149 ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
0150
0151
0152 autoip_start(netif);
0153 } else {
0154 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0155 ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
0156 autoip_arp_announce(netif);
0157 netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
0158 }
0159 } else {
0160 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0161 ("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
0162
0163 autoip_start(netif);
0164 }
0165 }
0166
0167
0168
0169
0170
0171
0172
0173 static void
0174 autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr)
0175 {
0176
0177
0178
0179
0180 u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
0181 addr += netif->autoip->tried_llipaddr;
0182 addr = AUTOIP_NET | (addr & 0xffff);
0183
0184
0185 if (addr < AUTOIP_RANGE_START) {
0186 addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
0187 }
0188 if (addr > AUTOIP_RANGE_END) {
0189 addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
0190 }
0191 LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
0192 (addr <= AUTOIP_RANGE_END));
0193 ipaddr->addr = htonl(addr);
0194
0195 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0196 ("autoip_create_addr(): tried_llipaddr=%"U16_F", 0x%08"X32_F"\n",
0197 (u16_t)(netif->autoip->tried_llipaddr), (u32_t)(ipaddr->addr)));
0198 }
0199
0200
0201
0202
0203
0204
0205 static err_t
0206 autoip_arp_probe(struct netif *netif)
0207 {
0208 return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
0209 (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero,
0210 &netif->autoip->llipaddr, ARP_REQUEST);
0211 }
0212
0213
0214
0215
0216
0217
0218 static err_t
0219 autoip_arp_announce(struct netif *netif)
0220 {
0221 return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
0222 (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero,
0223 &netif->autoip->llipaddr, ARP_REQUEST);
0224 }
0225
0226
0227
0228
0229
0230
0231 static err_t
0232 autoip_bind(struct netif *netif)
0233 {
0234 struct autoip *autoip = netif->autoip;
0235 struct ip_addr sn_mask, gw_addr;
0236
0237 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0238 ("autoip_bind(netif=%p) %c%c%"U16_F" 0x%08"X32_F"\n",
0239 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, autoip->llipaddr.addr));
0240
0241 IP4_ADDR(&sn_mask, 255, 255, 0, 0);
0242 IP4_ADDR(&gw_addr, 0, 0, 0, 0);
0243
0244 netif_set_ipaddr(netif, &autoip->llipaddr);
0245 netif_set_netmask(netif, &sn_mask);
0246 netif_set_gw(netif, &gw_addr);
0247
0248
0249 netif_set_up(netif);
0250
0251 return ERR_OK;
0252 }
0253
0254
0255
0256
0257
0258
0259 err_t
0260 autoip_start(struct netif *netif)
0261 {
0262 struct autoip *autoip = netif->autoip;
0263 err_t result = ERR_OK;
0264
0265 if(netif_is_up(netif)) {
0266 netif_set_down(netif);
0267 }
0268
0269
0270
0271
0272 netif->ip_addr.addr = 0;
0273 netif->netmask.addr = 0;
0274 netif->gw.addr = 0;
0275
0276 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0277 ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
0278 netif->name[1], (u16_t)netif->num));
0279 if(autoip == NULL) {
0280
0281 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0282 ("autoip_start(): starting new AUTOIP client\n"));
0283 autoip = mem_malloc(sizeof(struct autoip));
0284 if(autoip == NULL) {
0285 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0286 ("autoip_start(): could not allocate autoip\n"));
0287 return ERR_MEM;
0288 }
0289 memset( autoip, 0, sizeof(struct autoip));
0290
0291 netif->autoip = autoip;
0292 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
0293 } else {
0294 autoip->state = AUTOIP_STATE_OFF;
0295 autoip->ttw = 0;
0296 autoip->sent_num = 0;
0297 memset(&autoip->llipaddr, 0, sizeof(struct ip_addr));
0298 autoip->lastconflict = 0;
0299 }
0300
0301 autoip_create_addr(netif, &(autoip->llipaddr));
0302 autoip->tried_llipaddr++;
0303 autoip_start_probing(netif);
0304
0305 return result;
0306 }
0307
0308 static void
0309 autoip_start_probing(struct netif *netif)
0310 {
0311 struct autoip *autoip = netif->autoip;
0312
0313 autoip->state = AUTOIP_STATE_PROBING;
0314 autoip->sent_num = 0;
0315
0316
0317
0318
0319
0320 autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
0321
0322
0323
0324
0325
0326
0327 if(autoip->tried_llipaddr > MAX_CONFLICTS) {
0328 autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
0329 }
0330 }
0331
0332
0333
0334
0335
0336
0337
0338 void
0339 autoip_network_changed(struct netif *netif)
0340 {
0341 if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
0342 netif_set_down(netif);
0343 autoip_start_probing(netif);
0344 }
0345 }
0346
0347
0348
0349
0350
0351
0352 err_t
0353 autoip_stop(struct netif *netif)
0354 {
0355 netif->autoip->state = AUTOIP_STATE_OFF;
0356 netif_set_down(netif);
0357 return ERR_OK;
0358 }
0359
0360
0361
0362
0363 void
0364 autoip_tmr()
0365 {
0366 struct netif *netif = netif_list;
0367
0368 while (netif != NULL) {
0369
0370 if (netif->autoip != NULL) {
0371 if(netif->autoip->lastconflict > 0) {
0372 netif->autoip->lastconflict--;
0373 }
0374
0375 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0376 ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
0377 (u16_t)(netif->autoip->state), netif->autoip->ttw));
0378
0379 switch(netif->autoip->state) {
0380 case AUTOIP_STATE_PROBING:
0381 if(netif->autoip->ttw > 0) {
0382 netif->autoip->ttw--;
0383 } else {
0384 if(netif->autoip->sent_num >= PROBE_NUM) {
0385 netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
0386 netif->autoip->sent_num = 0;
0387 netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
0388 } else {
0389 autoip_arp_probe(netif);
0390 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0391 ("autoip_tmr() PROBING Sent Probe\n"));
0392 netif->autoip->sent_num++;
0393
0394 netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
0395 ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
0396 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
0397 }
0398 }
0399 break;
0400
0401 case AUTOIP_STATE_ANNOUNCING:
0402 if(netif->autoip->ttw > 0) {
0403 netif->autoip->ttw--;
0404 } else {
0405 if(netif->autoip->sent_num == 0) {
0406
0407
0408
0409
0410
0411
0412 autoip_bind(netif);
0413 } else {
0414 autoip_arp_announce(netif);
0415 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
0416 ("autoip_tmr() ANNOUNCING Sent Announce\n"));
0417 }
0418 netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
0419 netif->autoip->sent_num++;
0420
0421 if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
0422 netif->autoip->state = AUTOIP_STATE_BOUND;
0423 netif->autoip->sent_num = 0;
0424 netif->autoip->ttw = 0;
0425 }
0426 }
0427 break;
0428 }
0429 }
0430
0431 netif = netif->next;
0432 }
0433 }
0434
0435
0436
0437
0438
0439
0440
0441 void
0442 autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
0443 {
0444 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
0445 if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
0446
0447
0448
0449
0450
0451 struct ip_addr sipaddr, dipaddr;
0452 struct eth_addr netifaddr;
0453 netifaddr.addr[0] = netif->hwaddr[0];
0454 netifaddr.addr[1] = netif->hwaddr[1];
0455 netifaddr.addr[2] = netif->hwaddr[2];
0456 netifaddr.addr[3] = netif->hwaddr[3];
0457 netifaddr.addr[4] = netif->hwaddr[4];
0458 netifaddr.addr[5] = netif->hwaddr[5];
0459
0460
0461
0462
0463 SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
0464 SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
0465
0466 if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
0467 ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
0468 (netif->autoip->sent_num == 0))) {
0469
0470
0471
0472
0473
0474
0475 if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
0476 (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
0477 !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
0478 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
0479 ("autoip_arp_reply(): Probe Conflict detected\n"));
0480 autoip_start(netif);
0481 }
0482 } else {
0483
0484
0485
0486
0487 if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
0488 !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
0489 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
0490 ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
0491 autoip_handle_arp_conflict(netif);
0492 }
0493 }
0494 }
0495 }
0496
0497 #endif