The Pedigree Project  0.1
autoip.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
48 /*
49  *
50  * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
51  * All rights reserved.
52  *
53  * Redistribution and use in source and binary forms, with or without modification,
54  * are permitted provided that the following conditions are met:
55  *
56  * 1. Redistributions of source code must retain the above copyright notice,
57  * this list of conditions and the following disclaimer.
58  * 2. Redistributions in binary form must reproduce the above copyright notice,
59  * this list of conditions and the following disclaimer in the documentation
60  * and/or other materials provided with the distribution.
61  * 3. The name of the author may not be used to endorse or promote products
62  * derived from this software without specific prior written permission.
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
65  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
66  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
67  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
68  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
69  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
70  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
71  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
72  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
73  * OF SUCH DAMAGE.
74  *
75  * Author: Dominik Spies <kontakt@dspies.de>
76  */
77 
78 #include "lwip/opt.h"
79 
80 #if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
81 
82 #include "lwip/mem.h"
83 /* #include "lwip/udp.h" */
84 #include "lwip/ip_addr.h"
85 #include "lwip/netif.h"
86 #include "lwip/autoip.h"
87 #include "lwip/etharp.h"
88 #include "lwip/prot/autoip.h"
89 
90 #include <string.h>
91 
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))
100 #endif /* LWIP_AUTOIP_RAND */
101 
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)))
110 #endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
111 
112 /* static functions */
113 static err_t autoip_arp_announce(struct netif *netif);
114 static void autoip_start_probing(struct netif *netif);
115 
124 void
125 autoip_set_struct(struct netif *netif, struct autoip *autoip)
126 {
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);
131 
132  /* clear data structure */
133  memset(autoip, 0, sizeof(struct autoip));
134  /* autoip->state = AUTOIP_STATE_OFF; */
135  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
136 }
137 
142 static void
143 autoip_restart(struct netif *netif)
144 {
145  struct autoip* autoip = netif_autoip_data(netif);
146  autoip->tried_llipaddr++;
147  autoip_start(netif);
148 }
149 
153 static void
154 autoip_handle_arp_conflict(struct netif *netif)
155 {
156  struct autoip* autoip = netif_autoip_data(netif);
157 
158  /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
159  a) means retreat on the first conflict and
160  b) allows to keep an already configured address when having only one
161  conflict in 10 seconds
162  We use option b) since it helps to improve the chance that one of the two
163  conflicting hosts may be able to retain its address. */
164 
165  if (autoip->lastconflict > 0) {
166  /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
168  ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
169 
170  /* Active TCP sessions are aborted when removing the ip addresss */
171  autoip_restart(netif);
172  } else {
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;
177  }
178 }
179 
186 static void
187 autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
188 {
189  struct autoip* autoip = netif_autoip_data(netif);
190 
191  /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
192  * compliant to RFC 3927 Section 2.1
193  * We have 254 * 256 possibilities */
194 
195  u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
196  addr += autoip->tried_llipaddr;
197  addr = AUTOIP_NET | (addr & 0xffff);
198  /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
199 
200  if (addr < AUTOIP_RANGE_START) {
201  addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
202  }
203  if (addr > AUTOIP_RANGE_END) {
204  addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
205  }
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));
209 
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)));
214 }
215 
221 static err_t
222 autoip_arp_probe(struct netif *netif)
223 {
224  struct autoip* autoip = netif_autoip_data(netif);
225  /* this works because netif->ip_addr is ANY */
226  return etharp_request(netif, &autoip->llipaddr);
227 }
228 
234 static err_t
235 autoip_arp_announce(struct netif *netif)
236 {
237  return etharp_gratuitous(netif);
238 }
239 
245 static err_t
246 autoip_bind(struct netif *netif)
247 {
248  struct autoip* autoip = netif_autoip_data(netif);
249  ip4_addr_t sn_mask, gw_addr;
250 
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)));
256 
257  IP4_ADDR(&sn_mask, 255, 255, 0, 0);
258  IP4_ADDR(&gw_addr, 0, 0, 0, 0);
259 
260  netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
261  /* interface is used by routing now that an address is set */
262 
263  return ERR_OK;
264 }
265 
272 err_t
273 autoip_start(struct netif *netif)
274 {
275  struct autoip* autoip = netif_autoip_data(netif);
276  err_t result = ERR_OK;
277 
278  LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
279 
280  /* Set IP-Address, Netmask and Gateway to 0 to make sure that
281  * ARP Packets are formed correctly
282  */
283  netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
284 
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) {
289  /* no AutoIP client attached yet? */
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"));
296  return ERR_MEM;
297  }
298  memset(autoip, 0, sizeof(struct autoip));
299  /* store this AutoIP client in the netif */
300  netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
301  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
302  } else {
303  autoip->state = AUTOIP_STATE_OFF;
304  autoip->ttw = 0;
305  autoip->sent_num = 0;
306  ip4_addr_set_zero(&autoip->llipaddr);
307  autoip->lastconflict = 0;
308  }
309 
310  autoip_create_addr(netif, &(autoip->llipaddr));
311  autoip_start_probing(netif);
312 
313  return result;
314 }
315 
316 static void
317 autoip_start_probing(struct netif *netif)
318 {
319  struct autoip* autoip = netif_autoip_data(netif);
320 
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)));
327 
328  /* time to wait to first probe, this is randomly
329  * chosen out of 0 to PROBE_WAIT seconds.
330  * compliant to RFC 3927 Section 2.2.1
331  */
332  autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
333 
334  /*
335  * if we tried more then MAX_CONFLICTS we must limit our rate for
336  * acquiring and probing address
337  * compliant to RFC 3927 Section 2.2.1
338  */
339  if (autoip->tried_llipaddr > MAX_CONFLICTS) {
340  autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
341  }
342 }
343 
350 void
351 autoip_network_changed(struct netif *netif)
352 {
353  struct autoip* autoip = netif_autoip_data(netif);
354 
355  if (autoip && (autoip->state != AUTOIP_STATE_OFF)) {
356  autoip_start_probing(netif);
357  }
358 }
359 
366 err_t
367 autoip_stop(struct netif *netif)
368 {
369  struct autoip* autoip = netif_autoip_data(netif);
370 
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);
375  }
376  }
377  return ERR_OK;
378 }
379 
383 void
384 autoip_tmr(void)
385 {
386  struct netif *netif = netif_list;
387  /* loop through netif's */
388  while (netif != NULL) {
389  struct autoip* autoip = netif_autoip_data(netif);
390  /* only act on AutoIP configured interfaces */
391  if (autoip != NULL) {
392  if (autoip->lastconflict > 0) {
393  autoip->lastconflict--;
394  }
395 
397  ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
398  (u16_t)(autoip->state), autoip->ttw));
399 
400  if (autoip->ttw > 0) {
401  autoip->ttw--;
402  }
403 
404  switch(autoip->state) {
405  case AUTOIP_STATE_PROBING:
406  if (autoip->ttw == 0) {
407  if (autoip->sent_num >= PROBE_NUM) {
408  /* Switch to ANNOUNCING: now we can bind to an IP address and use it */
409  autoip->state = AUTOIP_STATE_ANNOUNCING;
410  autoip_bind(netif);
411  /* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP
412  which counts as an announcement */
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)));
419  } else {
420  autoip_arp_probe(netif);
421  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
422  autoip->sent_num++;
423  if (autoip->sent_num == PROBE_NUM) {
424  /* calculate time to wait to for announce */
425  autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
426  } else {
427  /* calculate time to wait to next probe */
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);
431  }
432  }
433  }
434  break;
435 
436  case AUTOIP_STATE_ANNOUNCING:
437  if (autoip->ttw == 0) {
438  autoip_arp_announce(netif);
439  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
440  autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
441  autoip->sent_num++;
442 
443  if (autoip->sent_num >= ANNOUNCE_NUM) {
444  autoip->state = AUTOIP_STATE_BOUND;
445  autoip->sent_num = 0;
446  autoip->ttw = 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)));
451  }
452  }
453  break;
454 
455  default:
456  /* nothing to do in other states */
457  break;
458  }
459  }
460  /* proceed to next network interface */
461  netif = netif->next;
462  }
463 }
464 
471 void
472 autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
473 {
474  struct autoip* autoip = netif_autoip_data(netif);
475 
476  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
477  if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) {
478  /* when ip.src == llipaddr && hw.src != netif->hwaddr
479  *
480  * when probing ip.dst == llipaddr && hw.src != netif->hwaddr
481  * we have a conflict and must solve it
482  */
483  ip4_addr_t sipaddr, dipaddr;
484  struct eth_addr netifaddr;
485  ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
486 
487  /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without
488  * structure packing (not using structure copy which breaks strict-aliasing rules).
489  */
490  IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
491  IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
492 
493  if (autoip->state == AUTOIP_STATE_PROBING) {
494  /* RFC 3927 Section 2.2.1:
495  * from beginning to after ANNOUNCE_WAIT
496  * seconds we have a conflict if
497  * ip.src == llipaddr OR
498  * ip.dst == llipaddr && hw.src != own hwaddr
499  */
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);
507  }
508  } else {
509  /* RFC 3927 Section 2.5:
510  * in any state we have a conflict if
511  * ip.src == llipaddr && hw.src != own hwaddr
512  */
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);
518  }
519  }
520  }
521 }
522 
529 u8_t
530 autoip_supplied_address(const struct netif *netif)
531 {
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);
535  }
536  return 0;
537 }
538 
539 u8_t
540 autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr)
541 {
542  struct autoip* autoip = netif_autoip_data(netif);
543  return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr));
544 }
545 
546 #endif /* LWIP_IPV4 && LWIP_AUTOIP */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:322
struct netif * netif_list
Definition: netif.c:123
u8_t num
Definition: netif.h:328
Definition: err.h:84
struct netif * next
Definition: netif.h:246
#define AUTOIP_DEBUG
Definition: opt.h:2854
Definition: err.h:115
Definition: netif.h:244
s8_t err_t
Definition: err.h:76
#define LWIP_DEBUGF(debug, message)
#define netif_is_up(netif)
Definition: netif.h:420
Definition: err.h:82
char name[2]
Definition: netif.h:326
void * mem_malloc(mem_size_t size)
Definition: mem.c:622
#define ETHADDR16_COPY(dst, src)