ReactOS 0.4.16-dev-329-g9223134
autoip.c
Go to the documentation of this file.
1
27/*
28 *
29 * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without modification,
33 * are permitted provided that the following conditions are met:
34 *
35 * 1. Redistributions of source code must retain the above copyright notice,
36 * this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 * 3. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
46 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
48 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
51 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
52 * OF SUCH DAMAGE.
53 *
54 * Author: Dominik Spies <kontakt@dspies.de>
55 */
56
57#include "lwip/opt.h"
58
59#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
60
61#include "lwip/mem.h"
62/* #include "lwip/udp.h" */
63#include "lwip/ip_addr.h"
64#include "lwip/netif.h"
65#include "lwip/autoip.h"
66#include "lwip/acd.h"
67#include "lwip/etharp.h"
68#include "lwip/prot/autoip.h"
69
70#include <string.h>
71
76#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
77#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
78 lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
79 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
80#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
81
82/* Function definitions */
83static void autoip_restart(struct netif *netif);
84static void autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr);
85static err_t autoip_bind(struct netif *netif);
86static void autoip_conflict_callback(struct netif *netif,
88
97void
98autoip_set_struct(struct netif *netif, struct autoip *autoip)
99{
101 LWIP_ASSERT("netif != NULL", netif != NULL);
102 LWIP_ASSERT("autoip != NULL", autoip != NULL);
103 LWIP_ASSERT("netif already has a struct autoip set",
104 netif_autoip_data(netif) == NULL);
105
106 /* clear data structure */
107 memset(autoip, 0, sizeof(struct autoip));
108 /* autoip->state = AUTOIP_STATE_OFF; */
109 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
110}
111
118void
119autoip_remove_struct(struct netif *netif)
120{
122 LWIP_ASSERT("netif != NULL", netif != NULL);
123 LWIP_ASSERT("netif has no struct autoip set",
124 netif_autoip_data(netif) != NULL);
125
126 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, NULL);
127}
128
133static void
134autoip_restart(struct netif *netif)
135{
136 struct autoip *autoip = netif_autoip_data(netif);
137 autoip->tried_llipaddr++;
138 autoip_start(netif);
139}
140
141
148static void
149autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
150{
151 struct autoip *autoip = netif_autoip_data(netif);
152
153 /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
154 * compliant to RFC 3927 Section 2.1
155 * We have 254 * 256 possibilities */
156
157 u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
158 addr += autoip->tried_llipaddr;
159 addr = AUTOIP_NET | (addr & 0xffff);
160 /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
161
162 if (addr < AUTOIP_RANGE_START) {
164 }
165 if (addr > AUTOIP_RANGE_END) {
167 }
168 LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
170 ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
171
173 ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
174 (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
175 ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
176}
177
178
184static err_t
185autoip_bind(struct netif *netif)
186{
187 struct autoip *autoip = netif_autoip_data(netif);
188 ip4_addr_t sn_mask, gw_addr;
189
190 autoip->state = AUTOIP_STATE_BOUND;
191
193 ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
194 (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
195 ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
196 ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
197
198 IP4_ADDR(&sn_mask, 255, 255, 0, 0);
199 IP4_ADDR(&gw_addr, 0, 0, 0, 0);
200
201 netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
202 /* interface is used by routing now that an address is set */
203
204 return ERR_OK;
205}
206
213static void
214autoip_conflict_callback(struct netif *netif, acd_callback_enum_t state)
215{
216 struct autoip *autoip = netif_autoip_data(netif);
217
218 switch (state) {
219 case ACD_IP_OK:
220 autoip_bind(netif);
221 break;
223 autoip_restart(netif);
224 break;
225 case ACD_DECLINE:
226 /* "delete" conflicting address so a new one will be selected in
227 * autoip_start() */
228 ip4_addr_set_any(&autoip->llipaddr);
229 autoip_stop(netif);
230 break;
231 default:
232 break;
233 }
234}
235
242err_t
243autoip_start(struct netif *netif)
244{
245 struct autoip *autoip = netif_autoip_data(netif);
247
249 LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
250
251 if (autoip == NULL) {
252 /* no AutoIP client attached yet? */
254 ("autoip_start(): starting new AUTOIP client\n"));
255 autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip));
256 if (autoip == NULL) {
258 ("autoip_start(): could not allocate autoip\n"));
259 return ERR_MEM;
260 }
261 /* store this AutoIP client in the netif */
262 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
263 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip\n"));
264 }
265
266 if (autoip->state == AUTOIP_STATE_OFF) {
268 ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0],
269 netif->name[1], (u16_t)netif->num));
270
271 /* add acd struct to list*/
272 acd_add(netif, &autoip->acd, autoip_conflict_callback);
273
274 /* In accordance to RFC3927 section 2.1:
275 * Keep using the same link local address as much as possible.
276 * Only when there is none or when there was a conflict, select a new one.
277 */
278 if (!ip4_addr_islinklocal(&autoip->llipaddr)) {
279 autoip_create_addr(netif, &(autoip->llipaddr));
280 }
281 autoip->state = AUTOIP_STATE_CHECKING;
282 acd_start(netif, &autoip->acd, autoip->llipaddr);
283 } else {
285 ("autoip_start(): already started on netif=%p %c%c%"U16_F"\n",
286 (void *)netif, netif->name[0],
287 netif->name[1], (u16_t)netif->num));
288 }
289
290 return result;
291}
292
293
300void
301autoip_network_changed_link_up(struct netif *netif)
302{
303 struct autoip *autoip = netif_autoip_data(netif);
304
305 if (autoip && (autoip->state != AUTOIP_STATE_OFF) && !LWIP_DHCP_AUTOIP_COOP) {
307 ("autoip_network_changed_link_up(): start acd\n"));
308 autoip->state = AUTOIP_STATE_CHECKING;
309 /* Start acd check again for the last used address */
310 acd_start(netif, &autoip->acd, autoip->llipaddr);
311 }
312}
313
321void
322autoip_network_changed_link_down(struct netif *netif)
323{
324 struct autoip *autoip = netif_autoip_data(netif);
325
326 if (autoip && (autoip->state != AUTOIP_STATE_OFF) && LWIP_DHCP_AUTOIP_COOP) {
328 ("autoip_network_changed_link_down(): stop autoip\n"));
329 autoip_stop(netif);
330 }
331}
332
339err_t
340autoip_stop(struct netif *netif)
341{
342 struct autoip *autoip = netif_autoip_data(netif);
343
345 if (autoip != NULL) {
346 autoip->state = AUTOIP_STATE_OFF;
347 if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
348 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
349 }
350 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,("autoip_stop()\n"));
351 }
352 return ERR_OK;
353}
354
361u8_t
362autoip_supplied_address(struct netif *netif)
363{
364 struct autoip *autoip = netif_autoip_data(netif);
365 return (autoip != NULL)
366 && (ip4_addr_eq(netif_ip4_addr(netif), &(autoip->llipaddr)))
367 && (autoip->state == AUTOIP_STATE_BOUND);
368}
369
370u8_t
371autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr)
372{
373 struct autoip *autoip = netif_autoip_data(netif);
374 return (autoip != NULL)
375 && (ip4_addr_eq(addr, &(autoip->llipaddr)))
376 && (autoip->state == AUTOIP_STATE_BOUND);
377}
378
379#endif /* LWIP_IPV4 && LWIP_AUTOIP */
static int state
Definition: maze.c:121
#define lwip_ntohl(x)
Definition: def.h:89
#define lwip_htonl(x)
Definition: def.h:88
#define NULL
Definition: types.h:112
#define U16_F
Definition: cc.h:19
void * mem_calloc(mem_size_t count, mem_size_t size)
Definition: mem.c:999
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:130
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
#define ERR_MEM
Definition: fontsub.h:52
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint64EXT * result
Definition: glext.h:11304
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
uint16_t u16_t
Definition: arch.h:127
#define LWIP_DBG_STATE
Definition: debug.h:85
#define LWIP_DBG_TRACE
Definition: debug.h:83
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
@ ERR_ARG
Definition: err.h:88
#define LWIP_DHCP_AUTOIP_COOP
Definition: opt.h:1010
#define AUTOIP_DEBUG
Definition: opt.h:3533
#define LWIP_ASSERT_CORE_LOCKED()
Definition: opt.h:227
#define netif_is_up(netif)
Definition: netif.h:479
acd_callback_enum_t
Definition: acd.h:81
@ ACD_RESTART_CLIENT
Definition: acd.h:83
@ ACD_IP_OK
Definition: acd.h:82
@ ACD_DECLINE
Definition: acd.h:84
@ AUTOIP_STATE_OFF
Definition: autoip.h:56
@ AUTOIP_STATE_BOUND
Definition: autoip.h:58
@ AUTOIP_STATE_CHECKING
Definition: autoip.h:57
#define AUTOIP_RANGE_END
Definition: autoip.h:52
#define AUTOIP_RANGE_START
Definition: autoip.h:50
#define AUTOIP_NET
Definition: autoip.h:48
#define memset(x, y, z)
Definition: compat.h:39
Definition: netif.h:269
char name[2]
Definition: netif.h:356
u8_t num
Definition: netif.h:359