4 * Neighbor discovery and stateless address autoconfiguration for IPv6.
5 * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
6 * (Address autoconfiguration).
10 * Copyright (c) 2010 Inico Technologies Ltd.
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * This file is part of the lwIP TCP/IP stack.
37 * Author: Ivan Delamer <delamer@inicotech.com>
40 * Please coordinate changes and requests with Ivan Delamer
41 * <delamer@inicotech.com>
44 #ifndef __LWIP_ND6_H__
45 #define __LWIP_ND6_H__
49 #if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
51 #include "lwip/pbuf.h"
53 #include "lwip/ip6_addr.h"
54 #include "lwip/netif.h"
61 /* Struct for tables. */
62 struct nd6_neighbor_cache_entry {
63 ip6_addr_t next_hop_address;
65 u8_t lladdr[NETIF_MAX_HWADDR_LEN];
68 /** Pointer to queue of pending outgoing packets on this entry. */
69 struct nd6_q_entry *q;
70 #endif /* LWIP_ND6_QUEUEING */
81 struct nd6_destination_cache_entry {
82 ip6_addr_t destination_addr;
83 ip6_addr_t next_hop_addr;
88 struct nd6_prefix_list_entry {
91 u32_t invalidation_timer;
92 #if LWIP_IPV6_AUTOCONFIG
94 #define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01
95 #define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02
96 #define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04
97 #endif /* LWIP_IPV6_AUTOCONFIG */
100 struct nd6_router_list_entry {
101 struct nd6_neighbor_cache_entry * neighbor_entry;
102 u32_t invalidation_timer;
107 enum nd6_neighbor_cache_entry_state {
116 #if LWIP_ND6_QUEUEING
117 /** struct for queueing outgoing packets for unknown address
118 * defined here to be accessed by memp.h
121 struct nd6_q_entry *next;
124 #endif /* LWIP_ND6_QUEUEING */
126 /** Neighbor solicitation message header. */
127 #ifdef PACK_STRUCT_USE_INCLUDES
128 # include "arch/bpstruct.h"
132 PACK_STRUCT_FIELD(u8_t type);
133 PACK_STRUCT_FIELD(u8_t code);
134 PACK_STRUCT_FIELD(u16_t chksum);
135 PACK_STRUCT_FIELD(u32_t reserved);
136 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
137 /* Options follow. */
138 } PACK_STRUCT_STRUCT;
140 #ifdef PACK_STRUCT_USE_INCLUDES
141 # include "arch/epstruct.h"
144 /** Neighbor advertisement message header. */
145 #ifdef PACK_STRUCT_USE_INCLUDES
146 # include "arch/bpstruct.h"
150 PACK_STRUCT_FIELD(u8_t type);
151 PACK_STRUCT_FIELD(u8_t code);
152 PACK_STRUCT_FIELD(u16_t chksum);
153 PACK_STRUCT_FIELD(u8_t flags);
154 PACK_STRUCT_FIELD(u8_t reserved[3]);
155 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
156 /* Options follow. */
157 } PACK_STRUCT_STRUCT;
159 #ifdef PACK_STRUCT_USE_INCLUDES
160 # include "arch/epstruct.h"
162 #define ND6_FLAG_ROUTER (0x80)
163 #define ND6_FLAG_SOLICITED (0x40)
164 #define ND6_FLAG_OVERRIDE (0x20)
166 /** Router solicitation message header. */
167 #ifdef PACK_STRUCT_USE_INCLUDES
168 # include "arch/bpstruct.h"
172 PACK_STRUCT_FIELD(u8_t type);
173 PACK_STRUCT_FIELD(u8_t code);
174 PACK_STRUCT_FIELD(u16_t chksum);
175 PACK_STRUCT_FIELD(u32_t reserved);
176 /* Options follow. */
177 } PACK_STRUCT_STRUCT;
179 #ifdef PACK_STRUCT_USE_INCLUDES
180 # include "arch/epstruct.h"
183 /** Router advertisement message header. */
184 #define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80)
185 #define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40)
186 #define ND6_RA_FLAG_HOME_AGENT (0x20)
187 #define ND6_RA_PREFERENCE_MASK (0x18)
188 #define ND6_RA_PREFERENCE_HIGH (0x08)
189 #define ND6_RA_PREFERENCE_MEDIUM (0x00)
190 #define ND6_RA_PREFERENCE_LOW (0x18)
191 #define ND6_RA_PREFERENCE_DISABLED (0x10)
192 #ifdef PACK_STRUCT_USE_INCLUDES
193 # include "arch/bpstruct.h"
197 PACK_STRUCT_FIELD(u8_t type);
198 PACK_STRUCT_FIELD(u8_t code);
199 PACK_STRUCT_FIELD(u16_t chksum);
200 PACK_STRUCT_FIELD(u8_t current_hop_limit);
201 PACK_STRUCT_FIELD(u8_t flags);
202 PACK_STRUCT_FIELD(u16_t router_lifetime);
203 PACK_STRUCT_FIELD(u32_t reachable_time);
204 PACK_STRUCT_FIELD(u32_t retrans_timer);
205 /* Options follow. */
206 } PACK_STRUCT_STRUCT;
208 #ifdef PACK_STRUCT_USE_INCLUDES
209 # include "arch/epstruct.h"
212 /** Redirect message header. */
213 #ifdef PACK_STRUCT_USE_INCLUDES
214 # include "arch/bpstruct.h"
217 struct redirect_header {
218 PACK_STRUCT_FIELD(u8_t type);
219 PACK_STRUCT_FIELD(u8_t code);
220 PACK_STRUCT_FIELD(u16_t chksum);
221 PACK_STRUCT_FIELD(u32_t reserved);
222 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
223 PACK_STRUCT_FIELD(ip6_addr_p_t destination_address);
224 /* Options follow. */
225 } PACK_STRUCT_STRUCT;
227 #ifdef PACK_STRUCT_USE_INCLUDES
228 # include "arch/epstruct.h"
231 /** Link-layer address option. */
232 #define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01)
233 #define ND6_OPTION_TYPE_TARGET_LLADDR (0x02)
234 #ifdef PACK_STRUCT_USE_INCLUDES
235 # include "arch/bpstruct.h"
238 struct lladdr_option {
239 PACK_STRUCT_FIELD(u8_t type);
240 PACK_STRUCT_FIELD(u8_t length);
241 PACK_STRUCT_FIELD(u8_t addr[NETIF_MAX_HWADDR_LEN]);
242 } PACK_STRUCT_STRUCT;
244 #ifdef PACK_STRUCT_USE_INCLUDES
245 # include "arch/epstruct.h"
248 /** Prefix information option. */
249 #define ND6_OPTION_TYPE_PREFIX_INFO (0x03)
250 #define ND6_PREFIX_FLAG_ON_LINK (0x80)
251 #define ND6_PREFIX_FLAG_AUTONOMOUS (0x40)
252 #define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20)
253 #define ND6_PREFIX_FLAG_SITE_PREFIX (0x10)
254 #ifdef PACK_STRUCT_USE_INCLUDES
255 # include "arch/bpstruct.h"
258 struct prefix_option {
259 PACK_STRUCT_FIELD(u8_t type);
260 PACK_STRUCT_FIELD(u8_t length);
261 PACK_STRUCT_FIELD(u8_t prefix_length);
262 PACK_STRUCT_FIELD(u8_t flags);
263 PACK_STRUCT_FIELD(u32_t valid_lifetime);
264 PACK_STRUCT_FIELD(u32_t preferred_lifetime);
265 PACK_STRUCT_FIELD(u8_t reserved2[3]);
266 PACK_STRUCT_FIELD(u8_t site_prefix_length);
267 PACK_STRUCT_FIELD(ip6_addr_p_t prefix);
268 } PACK_STRUCT_STRUCT;
270 #ifdef PACK_STRUCT_USE_INCLUDES
271 # include "arch/epstruct.h"
274 /** Redirected header option. */
275 #define ND6_OPTION_TYPE_REDIR_HDR (0x04)
276 #ifdef PACK_STRUCT_USE_INCLUDES
277 # include "arch/bpstruct.h"
280 struct redirected_header_option {
281 PACK_STRUCT_FIELD(u8_t type);
282 PACK_STRUCT_FIELD(u8_t length);
283 PACK_STRUCT_FIELD(u8_t reserved[6]);
284 /* Portion of redirected packet follows. */
285 /* PACK_STRUCT_FIELD(u8_t redirected[8]); */
286 } PACK_STRUCT_STRUCT;
288 #ifdef PACK_STRUCT_USE_INCLUDES
289 # include "arch/epstruct.h"
293 #define ND6_OPTION_TYPE_MTU (0x05)
294 #ifdef PACK_STRUCT_USE_INCLUDES
295 # include "arch/bpstruct.h"
299 PACK_STRUCT_FIELD(u8_t type);
300 PACK_STRUCT_FIELD(u8_t length);
301 PACK_STRUCT_FIELD(u16_t reserved);
302 PACK_STRUCT_FIELD(u32_t mtu);
303 } PACK_STRUCT_STRUCT;
305 #ifdef PACK_STRUCT_USE_INCLUDES
306 # include "arch/epstruct.h"
309 /** Route information option. */
310 #define ND6_OPTION_TYPE_ROUTE_INFO (24)
311 #ifdef PACK_STRUCT_USE_INCLUDES
312 # include "arch/bpstruct.h"
315 struct route_option {
316 PACK_STRUCT_FIELD(u8_t type);
317 PACK_STRUCT_FIELD(u8_t length);
318 PACK_STRUCT_FIELD(u8_t prefix_length);
319 PACK_STRUCT_FIELD(u8_t preference);
320 PACK_STRUCT_FIELD(u32_t route_lifetime);
321 PACK_STRUCT_FIELD(ip6_addr_p_t prefix);
322 } PACK_STRUCT_STRUCT;
324 #ifdef PACK_STRUCT_USE_INCLUDES
325 # include "arch/epstruct.h"
328 /* the possible states of an IP address */
329 #define IP6_ADDRESS_STATE_INVALID (0)
330 #define IP6_ADDRESS_STATE_VALID (0x4)
331 #define IP6_ADDRESS_STATE_PREFERRED (0x5) /* includes valid */
332 #define IP6_ADDRESS_STATE_DEPRECATED (0x6) /* includes valid */
333 #define IP6_ADDRESS_STATE_TENTATIV (0x8)
335 /** 1 second period */
336 #define ND6_TMR_INTERVAL 1000
339 /* TODO make these static? and entries accessible through API? */
340 extern struct nd6_neighbor_cache_entry neighbor_cache[];
341 extern struct nd6_destination_cache_entry destination_cache[];
342 extern struct nd6_prefix_list_entry prefix_list[];
343 extern struct nd6_router_list_entry default_router_list[];
345 /* Default values, can be updated by a RA message. */
346 extern u32_t reachable_time;
347 extern u32_t retrans_timer;
349 #define nd6_init() /* TODO should we init tables? */
351 void nd6_input(struct pbuf *p, struct netif *inp);
352 s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif);
353 s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif);
354 u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif);
355 #if LWIP_ND6_QUEUEING
356 err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p);
357 #endif /* LWIP_ND6_QUEUEING */
358 #if LWIP_ND6_TCP_REACHABILITY_HINTS
359 void nd6_reachability_hint(ip6_addr_t * ip6addr);
360 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
366 #endif /* LWIP_IPV6 */
368 #endif /* __LWIP_ND6_H__ */