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 #else /* LWIP_ND6_QUEUEING */
71 /** Pointer to a single pending outgoing packet on this entry. */
73 #endif /* LWIP_ND6_QUEUEING */
84 struct nd6_destination_cache_entry {
85 ip6_addr_t destination_addr;
86 ip6_addr_t next_hop_addr;
91 struct nd6_prefix_list_entry {
94 u32_t invalidation_timer;
95 #if LWIP_IPV6_AUTOCONFIG
97 #define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01
98 #define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02
99 #define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04
100 #endif /* LWIP_IPV6_AUTOCONFIG */
103 struct nd6_router_list_entry {
104 struct nd6_neighbor_cache_entry * neighbor_entry;
105 u32_t invalidation_timer;
110 enum nd6_neighbor_cache_entry_state {
119 #if LWIP_ND6_QUEUEING
120 /** struct for queueing outgoing packets for unknown address
121 * defined here to be accessed by memp.h
124 struct nd6_q_entry *next;
127 #endif /* LWIP_ND6_QUEUEING */
129 /** Neighbor solicitation message header. */
130 #ifdef PACK_STRUCT_USE_INCLUDES
131 # include "arch/bpstruct.h"
135 PACK_STRUCT_FIELD(u8_t type);
136 PACK_STRUCT_FIELD(u8_t code);
137 PACK_STRUCT_FIELD(u16_t chksum);
138 PACK_STRUCT_FIELD(u32_t reserved);
139 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
140 /* Options follow. */
141 } PACK_STRUCT_STRUCT;
143 #ifdef PACK_STRUCT_USE_INCLUDES
144 # include "arch/epstruct.h"
147 /** Neighbor advertisement message header. */
148 #ifdef PACK_STRUCT_USE_INCLUDES
149 # include "arch/bpstruct.h"
153 PACK_STRUCT_FIELD(u8_t type);
154 PACK_STRUCT_FIELD(u8_t code);
155 PACK_STRUCT_FIELD(u16_t chksum);
156 PACK_STRUCT_FIELD(u8_t flags);
157 PACK_STRUCT_FIELD(u8_t reserved[3]);
158 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
159 /* Options follow. */
160 } PACK_STRUCT_STRUCT;
162 #ifdef PACK_STRUCT_USE_INCLUDES
163 # include "arch/epstruct.h"
165 #define ND6_FLAG_ROUTER (0x80)
166 #define ND6_FLAG_SOLICITED (0x40)
167 #define ND6_FLAG_OVERRIDE (0x20)
169 /** Router solicitation message header. */
170 #ifdef PACK_STRUCT_USE_INCLUDES
171 # include "arch/bpstruct.h"
175 PACK_STRUCT_FIELD(u8_t type);
176 PACK_STRUCT_FIELD(u8_t code);
177 PACK_STRUCT_FIELD(u16_t chksum);
178 PACK_STRUCT_FIELD(u32_t reserved);
179 /* Options follow. */
180 } PACK_STRUCT_STRUCT;
182 #ifdef PACK_STRUCT_USE_INCLUDES
183 # include "arch/epstruct.h"
186 /** Router advertisement message header. */
187 #define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80)
188 #define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40)
189 #define ND6_RA_FLAG_HOME_AGENT (0x20)
190 #define ND6_RA_PREFERENCE_MASK (0x18)
191 #define ND6_RA_PREFERENCE_HIGH (0x08)
192 #define ND6_RA_PREFERENCE_MEDIUM (0x00)
193 #define ND6_RA_PREFERENCE_LOW (0x18)
194 #define ND6_RA_PREFERENCE_DISABLED (0x10)
195 #ifdef PACK_STRUCT_USE_INCLUDES
196 # include "arch/bpstruct.h"
200 PACK_STRUCT_FIELD(u8_t type);
201 PACK_STRUCT_FIELD(u8_t code);
202 PACK_STRUCT_FIELD(u16_t chksum);
203 PACK_STRUCT_FIELD(u8_t current_hop_limit);
204 PACK_STRUCT_FIELD(u8_t flags);
205 PACK_STRUCT_FIELD(u16_t router_lifetime);
206 PACK_STRUCT_FIELD(u32_t reachable_time);
207 PACK_STRUCT_FIELD(u32_t retrans_timer);
208 /* Options follow. */
209 } PACK_STRUCT_STRUCT;
211 #ifdef PACK_STRUCT_USE_INCLUDES
212 # include "arch/epstruct.h"
215 /** Redirect message header. */
216 #ifdef PACK_STRUCT_USE_INCLUDES
217 # include "arch/bpstruct.h"
220 struct redirect_header {
221 PACK_STRUCT_FIELD(u8_t type);
222 PACK_STRUCT_FIELD(u8_t code);
223 PACK_STRUCT_FIELD(u16_t chksum);
224 PACK_STRUCT_FIELD(u32_t reserved);
225 PACK_STRUCT_FIELD(ip6_addr_p_t target_address);
226 PACK_STRUCT_FIELD(ip6_addr_p_t destination_address);
227 /* Options follow. */
228 } PACK_STRUCT_STRUCT;
230 #ifdef PACK_STRUCT_USE_INCLUDES
231 # include "arch/epstruct.h"
234 /** Link-layer address option. */
235 #define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01)
236 #define ND6_OPTION_TYPE_TARGET_LLADDR (0x02)
237 #ifdef PACK_STRUCT_USE_INCLUDES
238 # include "arch/bpstruct.h"
241 struct lladdr_option {
242 PACK_STRUCT_FIELD(u8_t type);
243 PACK_STRUCT_FIELD(u8_t length);
244 PACK_STRUCT_FIELD(u8_t addr[NETIF_MAX_HWADDR_LEN]);
245 } PACK_STRUCT_STRUCT;
247 #ifdef PACK_STRUCT_USE_INCLUDES
248 # include "arch/epstruct.h"
251 /** Prefix information option. */
252 #define ND6_OPTION_TYPE_PREFIX_INFO (0x03)
253 #define ND6_PREFIX_FLAG_ON_LINK (0x80)
254 #define ND6_PREFIX_FLAG_AUTONOMOUS (0x40)
255 #define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20)
256 #define ND6_PREFIX_FLAG_SITE_PREFIX (0x10)
257 #ifdef PACK_STRUCT_USE_INCLUDES
258 # include "arch/bpstruct.h"
261 struct prefix_option {
262 PACK_STRUCT_FIELD(u8_t type);
263 PACK_STRUCT_FIELD(u8_t length);
264 PACK_STRUCT_FIELD(u8_t prefix_length);
265 PACK_STRUCT_FIELD(u8_t flags);
266 PACK_STRUCT_FIELD(u32_t valid_lifetime);
267 PACK_STRUCT_FIELD(u32_t preferred_lifetime);
268 PACK_STRUCT_FIELD(u8_t reserved2[3]);
269 PACK_STRUCT_FIELD(u8_t site_prefix_length);
270 PACK_STRUCT_FIELD(ip6_addr_p_t prefix);
271 } PACK_STRUCT_STRUCT;
273 #ifdef PACK_STRUCT_USE_INCLUDES
274 # include "arch/epstruct.h"
277 /** Redirected header option. */
278 #define ND6_OPTION_TYPE_REDIR_HDR (0x04)
279 #ifdef PACK_STRUCT_USE_INCLUDES
280 # include "arch/bpstruct.h"
283 struct redirected_header_option {
284 PACK_STRUCT_FIELD(u8_t type);
285 PACK_STRUCT_FIELD(u8_t length);
286 PACK_STRUCT_FIELD(u8_t reserved[6]);
287 /* Portion of redirected packet follows. */
288 /* PACK_STRUCT_FIELD(u8_t redirected[8]); */
289 } PACK_STRUCT_STRUCT;
291 #ifdef PACK_STRUCT_USE_INCLUDES
292 # include "arch/epstruct.h"
296 #define ND6_OPTION_TYPE_MTU (0x05)
297 #ifdef PACK_STRUCT_USE_INCLUDES
298 # include "arch/bpstruct.h"
302 PACK_STRUCT_FIELD(u8_t type);
303 PACK_STRUCT_FIELD(u8_t length);
304 PACK_STRUCT_FIELD(u16_t reserved);
305 PACK_STRUCT_FIELD(u32_t mtu);
306 } PACK_STRUCT_STRUCT;
308 #ifdef PACK_STRUCT_USE_INCLUDES
309 # include "arch/epstruct.h"
312 /** Route information option. */
313 #define ND6_OPTION_TYPE_ROUTE_INFO (24)
314 #ifdef PACK_STRUCT_USE_INCLUDES
315 # include "arch/bpstruct.h"
318 struct route_option {
319 PACK_STRUCT_FIELD(u8_t type);
320 PACK_STRUCT_FIELD(u8_t length);
321 PACK_STRUCT_FIELD(u8_t prefix_length);
322 PACK_STRUCT_FIELD(u8_t preference);
323 PACK_STRUCT_FIELD(u32_t route_lifetime);
324 PACK_STRUCT_FIELD(ip6_addr_p_t prefix);
325 } PACK_STRUCT_STRUCT;
327 #ifdef PACK_STRUCT_USE_INCLUDES
328 # include "arch/epstruct.h"
331 /* the possible states of an IP address */
332 #define IP6_ADDRESS_STATE_INVALID (0)
333 #define IP6_ADDRESS_STATE_VALID (0x4)
334 #define IP6_ADDRESS_STATE_PREFERRED (0x5) /* includes valid */
335 #define IP6_ADDRESS_STATE_DEPRECATED (0x6) /* includes valid */
336 #define IP6_ADDRESS_STATE_TENTATIV (0x8)
338 /** 1 second period */
339 #define ND6_TMR_INTERVAL 1000
342 /* TODO make these static? and entries accessible through API? */
343 extern struct nd6_neighbor_cache_entry neighbor_cache[];
344 extern struct nd6_destination_cache_entry destination_cache[];
345 extern struct nd6_prefix_list_entry prefix_list[];
346 extern struct nd6_router_list_entry default_router_list[];
348 /* Default values, can be updated by a RA message. */
349 extern u32_t reachable_time;
350 extern u32_t retrans_timer;
352 #define nd6_init() /* TODO should we init tables? */
354 void nd6_input(struct pbuf *p, struct netif *inp);
355 s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif);
356 s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif);
357 u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif);
358 err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p);
359 #if LWIP_ND6_TCP_REACHABILITY_HINTS
360 void nd6_reachability_hint(ip6_addr_t * ip6addr);
361 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
367 #endif /* LWIP_IPV6 */
369 #endif /* __LWIP_ND6_H__ */