contiki/core/net/uip-nd6.h

735 lines
25 KiB
C
Raw Normal View History

2011-01-05 17:01:03 +00:00
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Neighbor discovery (RFC 4861)
* \author Julien Abeille <jabeille@cisco.com>
* \author Mathilde Durvy <mdurvy@cisco.com>
*/
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#ifndef __UIP_ND6_H__
#define __UIP_ND6_H__
#include "net/uip.h"
#include "sys/stimer.h"
/**
* \name General
* @{
*/
/** \brief HOP LIMIT to be used when sending ND messages (255) */
#define UIP_ND6_HOP_LIMIT 255
/** \brief INFINITE lifetime */
#define UIP_ND6_INFINITE_LIFETIME 0xFFFFFFFF
/** @} */
#define UIP_ND6_DEF_MAXDADNS 1
/** \name Configuration options */
/** @{ */
#ifndef UIP_CONF_ND6_MAX_NEIGHBORS
/** \brief max number of entries in the neighbor cache */
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#endif /*UIP_CONF_ND6_MAX_NEIGHBORS*/
#ifndef UIP_CONF_ND6_MAX_DEFROUTERS
/** \brief max number of entries in the default router cache */
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
#endif /*UIP_CONF_ND6_MAX_DEFROUTERS*/
#ifndef UIP_CONF_ND6_MAX_PREFIXES
/** \brief max number of entries in the prefix list */
#define UIP_CONF_ND6_MAX_PREFIXES 2
#endif /*UIP_CONF_ND6_MAX_PREFIXES*/
/** @} */
/** \name RFC 4861 Host constant */
/** @{ */
#define UIP_ND6_MAX_RTR_SOLICITATION_DELAY 1
#define UIP_ND6_RTR_SOLICITATION_INTERVAL 4
#define UIP_ND6_MAX_RTR_SOLICITATIONS 3
/** @} */
/** \name RFC 4861 Router constants */
/** @{ */
#ifndef UIP_CONF_ND6_SEND_RA
#define UIP_ND6_SEND_RA 1 /* enable/disable RA sending */
#else
#define UIP_ND6_SEND_RA UIP_CONF_ND6_SEND_RA
#endif
#define UIP_ND6_MAX_RA_INTERVAL 600
#define UIP_ND6_MIN_RA_INTERVAL (UIP_ND6_MAX_RA_INTERVAL / 3)
#define UIP_ND6_M_FLAG 0
#define UIP_ND6_O_FLAG 0
#define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL
#define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/
#define UIP_ND6_MAX_INITIAL_RAS 3 /*transmissions*/
#define UIP_ND6_MIN_DELAY_BETWEEN_RAS 3 /*seconds*/
//#define UIP_ND6_MAX_RA_DELAY_TIME 0.5 /*seconds*/
#define UIP_ND6_MAX_RA_DELAY_TIME_MS 500 /*milli seconds*/
/** @} */
/** \name RFC 4861 Node constant */
#define UIP_ND6_MAX_MULTICAST_SOLICIT 3
#define UIP_ND6_MAX_UNICAST_SOLICIT 3
#ifdef UIP_CONF_ND6_REACHABLE_TIME
#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME
#else
#define UIP_ND6_REACHABLE_TIME 30000
#endif
#ifdef UIP_CONF_ND6_RETRANS_TIMER
#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER
#else
#define UIP_ND6_RETRANS_TIMER 1000
#endif
#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5
#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2)
#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2)
/** @} */
/** \name ND6 option types */
/** @{ */
#define UIP_ND6_OPT_SLLAO 1
#define UIP_ND6_OPT_TLLAO 2
#define UIP_ND6_OPT_PREFIX_INFO 3
#define UIP_ND6_OPT_REDIRECTED_HDR 4
#define UIP_ND6_OPT_MTU 5
/** @} */
/** \name ND6 option types */
/** @{ */
#define UIP_ND6_OPT_TYPE_OFFSET 0
#define UIP_ND6_OPT_LEN_OFFSET 1
#define UIP_ND6_OPT_DATA_OFFSET 2
/** \name ND6 message length (excluding options) */
/** @{ */
#define UIP_ND6_NA_LEN 20
#define UIP_ND6_NS_LEN 20
#define UIP_ND6_RA_LEN 12
#define UIP_ND6_RS_LEN 4
/** @} */
/** \name ND6 option length in bytes */
/** @{ */
#define UIP_ND6_OPT_HDR_LEN 2
#define UIP_ND6_OPT_PREFIX_INFO_LEN 32
#define UIP_ND6_OPT_MTU_LEN 8
/* Length of TLLAO and SLLAO options, it is L2 dependant */
#if UIP_CONF_LL_802154
/* If the interface is 802.15.4. For now we use only long addresses */
#define UIP_ND6_OPT_SHORT_LLAO_LEN 8
#define UIP_ND6_OPT_LONG_LLAO_LEN 16
/** \brief length of a ND6 LLAO option for 802.15.4 */
#define UIP_ND6_OPT_LLAO_LEN UIP_ND6_OPT_LONG_LLAO_LEN
#else /*UIP_CONF_LL_802154*/
#if UIP_CONF_LL_80211
/* If the interface is 802.11 */
/** \brief length of a ND6 LLAO option for 802.11 */
#define UIP_ND6_OPT_LLAO_LEN 8
#else /*UIP_CONF_LL_80211*/
/** \brief length of a ND6 LLAO option for default L2 type (e.g. Ethernet) */
#define UIP_ND6_OPT_LLAO_LEN 8
#endif /*UIP_CONF_LL_80211*/
#endif /*UIP_CONF_LL_802154*/
/** @} */
/** \name Neighbor Advertisement flags masks */
/** @{ */
#define UIP_ND6_NA_FLAG_ROUTER 0x80
#define UIP_ND6_NA_FLAG_SOLICITED 0x40
#define UIP_ND6_NA_FLAG_OVERRIDE 0x20
#define UIP_ND6_RA_FLAG_ONLINK 0x80
#define UIP_ND6_RA_FLAG_AUTONOMOUS 0x40
/** @} */
/**
* \brief Possible states for the neighbor cache entries
*
* NO_STATE is for implementation purposes: a router entry contains a pointer
* to a neighbor entry, which holds its ip address. If we do not know the LL
* address of the router, we do not have to create a neighbor entry as per
* RFC 4861. However, we still need to have the IP of the router stored in a
* neighbor entry, hence we create an entry in the NO_STATE state
*/
typedef enum {
INCOMPLETE = 0,
REACHABLE = 1,
STALE = 2,
DELAY = 3,
PROBE = 4,
NO_STATE = 5
} uip_neighbor_state;
/**
* \name ND structures
* @{
*/
/** \brief An entry in the neighbor cache */
struct uip_nd6_neighbor {
uip_ipaddr_t ipaddr;
uip_lladdr_t lladdr;
u8_t isrouter;
uip_neighbor_state state;
struct stimer reachable;
struct stimer last_send; /**< last time a ND message was sent */
u8_t count_send; /**< how many ND message were already sent */
u8_t used; /**< brief is this neighbor currently used */
#if UIP_CONF_IPV6_QUEUE_PKT
u8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN];
/**< buffer to hold one packet during address resolution */
u8_t queue_buf_len;
/**< length of the pkt in buffer, used as "boolean" as well*/
#endif /*UIP_CONF_QUEUE_PKT*/
};
/** \brief An entry in the default router list */
struct uip_nd6_defrouter {
struct uip_nd6_neighbor *nb;
struct stimer lifetime;
/**< the lifetime contained in RA corresponds to the interval field
* of the timer
*/
u8_t used; /**< Is this default router entry currently used */
};
/** \brief A prefix list entry */
struct uip_nd6_prefix {
uip_ipaddr_t ipaddr;
u8_t length;
/**< we do not use preferred lifetime, which is always smaller than
* valid lifetime (for addr, preferred->deprecated)
*/
struct stimer vlifetime;
u8_t is_infinite; /**< Is the prefix lifetime INFINITE */
u8_t used; /**< Is this prefix entry currently used */
};
/** @} */
extern struct etimer uip_nd6_timer_periodic;
/**
* \note
* We do not use a destination cache, do next-hop determination each time
* a packet needs to be sent. (info such as rtt, path mtu could be stored
* in uip_conn)
*
*/
/**
* \name ND message structures
* @{
*/
/**
* \brief A neighbor solicitation constant part
*
* Possible option is: SLLAO
*/
typedef struct uip_nd6_ns {
uint32_t reserved;
uip_ipaddr_t tgtipaddr;
} uip_nd6_ns;
/**
* \brief A neighbor advertisement constant part.
*
* Possible option is: TLLAO
*/
typedef struct uip_nd6_na {
uint8_t flagsreserved;
uint8_t reserved[3];
uip_ipaddr_t tgtipaddr;
} uip_nd6_na;
/**
* \brief A router solicitation constant part
*
* Possible option is: SLLAO
*/
typedef struct uip_nd6_rs {
uint32_t reserved;
} uip_nd6_rs;
/**
* \brief A router advertisement constant part
*
* Possible options are: SLLAO, MTU, Prefix Information
*/
typedef struct uip_nd6_ra {
uint8_t cur_ttl;
uint8_t flags_reserved;
uint16_t router_lifetime;
uint32_t reachable_time;
uint32_t retrans_timer;
} uip_nd6_ra;
/**
* \brief A redirect message constant part
*
* Possible options are: TLLAO, redirected header
*/
typedef struct uip_nd6_redirect {
uint32_t reserved;
uip_ipaddr_t tgtipaddress;
uip_ipaddr_t destipaddress;
} uip_nd6_redirect;
/** @} */
/**
* \name ND Option structures
* @{
*/
/** \brief ND option header */
typedef struct uip_nd6_opt_hdr {
uint8_t type;
uint8_t len;
} uip_nd6_opt_hdr;
/** \brief ND option prefix information */
typedef struct uip_nd6_opt_prefix_info {
uint8_t type;
uint8_t len;
uint8_t preflen;
uint8_t flagsreserved1;
uint32_t validlt;
uint32_t preferredlt;
uint32_t reserved2;
uip_ipaddr_t prefix;
} uip_nd6_opt_prefix_info ;
/** \brief ND option MTU */
typedef struct uip_nd6_opt_mtu {
uint8_t type;
uint8_t len;
uint16_t reserved;
uint32_t mtu;
} uip_nd6_opt_mtu;
/** \struct Redirected header option */
typedef struct uip_nd6_opt_redirected_hdr {
uint8_t type;
uint8_t len;
uint8_t reserved[6];
} uip_nd6_opt_redirected_hdr;
/** @} */
/**
* \name ND Neighbor Cache, Router List and Prefix List handling functions
* @{
*/
/**
* \brief Initialize Neighbor Discovery structures
*/
void uip_nd6_init(void);
/**
* \brief Periodic processing of Neighbor Discovery Structures
*/
void uip_nd6_periodic(void);
/**
* \brief Look for a neighbor cache entry corresponding to a specific IP
* address
* \param ipaddr the specific IP address
* \return the corresponding neighbor cache entry
*/
struct uip_nd6_neighbor *uip_nd6_nbrcache_lookup(uip_ipaddr_t *ipaddr);
/**
* \brief Add a neighbor cache entry
* \param ipaddr the IP address of the entry
* \param lladdr the layer 2 address of the entry
* \param isrouter true is the entry is a router
* \param state the state of the entry
* \return the new neighbor or updated cache entry
*/
struct uip_nd6_neighbor * uip_nd6_nbrcache_add(uip_ipaddr_t *ipaddr,
uip_lladdr_t *lladdr,
u8_t isrouter,
uip_neighbor_state state);
/**
* \brief Returns a default router
*/
struct uip_nd6_defrouter * uip_nd6_choose_defrouter(void);
/**
* \brief Find a default router corresponding to a given neighbor cache entry
* \param neighbor the neighbor cache entry
* \return the corresponding router if any
*/
struct uip_nd6_defrouter *
uip_nd6_defrouter_lookup(struct uip_nd6_neighbor *neighbor);
/**
* \brief Remove a default router
* \param router to be removed
*/
void uip_nd6_defrouter_rm(struct uip_nd6_defrouter *router);
/**
* \brief Add a default router
* \param neighbor the corresponding neighbor cache entry
* \param interval the lifetime of the router
* \return the new or updated defrouter entry
*/
struct uip_nd6_defrouter *
uip_nd6_defrouter_add(struct uip_nd6_neighbor *neighbor, unsigned long interval);
/**
* \brief Check if an IP address in on-link by looking at prefix list
* \param ipaddr an IP address
* \return true if on-link
*/
u8_t uip_nd6_is_addr_onlink(uip_ipaddr_t *ipaddr);
/**
* \brief Find a given prefix
* \param ipaddr an IP address
* \return the corresponding prefix if any
*/
struct uip_nd6_prefix *
uip_nd6_prefix_lookup(uip_ipaddr_t *ipaddr);
/**
* \brief Add a prefix
* \param ipaddr the IP address of the prefix
* \param length the length of the prefix
* \param interval the lifetime of the prefix
* \return the new or updated prefix entry
*/
struct uip_nd6_prefix *
uip_nd6_prefix_add(uip_ipaddr_t *ipaddr, u8_t length, unsigned long interval);
/**
* \brief Remove a prefix from th eprefix list
* \param prefix pointer to the prefix to be removed
*/
void
uip_nd6_prefix_rm(struct uip_nd6_prefix *prefix);
/** @} */
/**
* \name ND Messages Processing and Generation
* @{
*/
/**
* \brief Process a neighbor solicitation
*
* The NS can be received in 3 cases (procedures):
* - sender is performing DAD (ip src = unspecified, no SLLAO option)
* - sender is performing NUD (ip dst = unicast)
* - sender is performing address resolution (ip dest = solicited node mcast
* address)
*
* We do:
* - if the tgt belongs to me, reply, otherwise ignore
* - if i was performing DAD for the same address, two cases:
* -- I already sent a NS, hence I win
* -- I did not send a NS yet, hence I lose
*
* If we need to send a NA in response (i.e. the NS was done for NUD, or
* address resolution, or DAD and there is a conflict), we do it in this
* function: set src, dst, tgt address in the three cases, then for all cases
* set the rest, including SLLAO
*
*/
void
uip_nd6_ns_input(void);
/**
* \brief Send a neighbor solicitation, send a Neighbor Advertisement
* \param src pointer to the src of the NS if known
* \param dest pointer to ip address to send the NS, for DAD or ADDR Resol,
* MUST be NULL, for NUD, must be correct unicast dest
* \param tgt pointer to ip address to fill the target address field, must
* not be NULL
*
* - RFC 4861, 7.2.2 :
* "If the source address of the packet prompting the solicitation is the
* same as one of the addresses assigned to the outgoing interface, that
* address SHOULD be placed in the IP Source Address of the outgoing
* solicitation. Otherwise, any one of the addresses assigned to the
* interface should be used."
* This is why we have a src ip address as argument. If NULL, we will do
* src address selection, otherwise we use the argument.
*
* - we check if it is a NS for Address resolution or NUD, if yes we include
* a SLLAO option, otherwise no.
*/
void
uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
/**
* \brief Process a Neighbor Advertisement
*
* we might have to send a pkt that had been buffered while address
* resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT)
*
* As per RFC 4861, on link layer that have addresses, TLLAO options MUST be
* included when responding to multicast solicitations, SHOULD be included in
* response to unicast (here we assume it is for now)
*
* NA can be received after sending NS for DAD, Address resolution or NUD. Can
* be unsolicited as well.
* It can trigger update of the state of the neighbor in the neighbor cache,
* router in the router list.
* If the NS was for DAD, it means DAD failed
*
*/
void
uip_nd6_na_input(void);
#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
/**
* \brief Process a Router Solicitation
*
*/
void uip_nd6_rs_input(void);
/**
* \brief send a Router Advertisement
*
* Only for router, for periodic as well as sollicited RA
*/
void uip_nd6_ra_output(uip_ipaddr_t *dest);
#endif /* UIP_ND6_SEND_RA */
#endif /*UIP_CONF_ROUTER*/
/**
* \brief Send a Router Solicitation
*
* src is chosen through the uip_netif_select_src function. If src is
* unspecified (i.e. we do not have a preferred address yet), then we do not
* put a SLLAO option (MUST NOT in RFC 4861). Otherwise we do.
*
* RS message format,
* possible option is SLLAO, MUST NOT be included if source = unspecified
* SHOULD be included otherwise
*/
void uip_nd6_rs_output(void);
/**
*
* \brief process a Router Advertisement
*
* - Possible actions when receiving a RA: add router to router list,
* recalculate reachable time, update link hop limit, update retrans timer.
* - If MTU option: update MTU.
* - If SLLAO option: update entry in neighbor cache
* - If prefix option: start autoconf, add prefix to prefix list
*/
void
uip_nd6_ra_input(void);
/** @} */
void
uip_appserver_addr_get(uip_ipaddr_t *ipaddr);
/*--------------------------------------*/
/******* ANNEX - message formats ********/
/*--------------------------------------*/
/*
* RS format. possible option is SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* RA format. possible options: prefix information, MTU, SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Cur Hop Limit |M|O| Reserved | Router Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reachable Time |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Retrans Timer |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* NS format: options should be SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* NA message format. possible options is TLLAO
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |R|S|O| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* Redirect message format. Possible options are TLLAO and Redirected header
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Destination Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* SLLAO/TLLAO option:
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Link-Layer Address ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* Prefix information option
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Prefix Length |L|A| Reserved1 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Valid Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Preferred Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved2 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Prefix +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* MTU option
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | MTU |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* Redirected header option
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* ~ IP header + data ~
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
#endif /* __UIP_ND6_H__ */
/** @} */