Merge pull request #585 from g-oikonomou/generic-icmp6-in-hooks
Generic ICMPv6 input hooks
This commit is contained in:
commit
ce2ed95b93
10 changed files with 245 additions and 163 deletions
|
@ -48,6 +48,7 @@
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "contiki-lib.h"
|
#include "contiki-lib.h"
|
||||||
#include "contiki-net.h"
|
#include "contiki-net.h"
|
||||||
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
#include "net/ipv6/multicast/roll-tm.h"
|
#include "net/ipv6/multicast/roll-tm.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
|
@ -473,11 +474,16 @@ extern uint16_t uip_slen;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Local function prototypes */
|
/* Local function prototypes */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void icmp_output();
|
static void icmp_input(void);
|
||||||
static void window_update_bounds();
|
static void icmp_output(void);
|
||||||
|
static void window_update_bounds(void);
|
||||||
static void reset_trickle_timer(uint8_t);
|
static void reset_trickle_timer(uint8_t);
|
||||||
static void handle_timer(void *);
|
static void handle_timer(void *);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* ROLL TM ICMPv6 handler declaration */
|
||||||
|
UIP_ICMP6_HANDLER(roll_tm_icmp_handler, ICMP6_ROLL_TM,
|
||||||
|
UIP_ICMP6_HANDLER_CODE_ANY, icmp_input);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Return a random number in [I/2, I), for a timer with Imin when the timer's
|
/* Return a random number in [I/2, I), for a timer with Imin when the timer's
|
||||||
* current number of doublings is d */
|
* current number of doublings is d */
|
||||||
static clock_time_t
|
static clock_time_t
|
||||||
|
@ -1090,8 +1096,9 @@ accept(uint8_t in)
|
||||||
return UIP_MCAST6_ACCEPT;
|
return UIP_MCAST6_ACCEPT;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
/* ROLL TM ICMPv6 Input Handler */
|
||||||
roll_tm_icmp_input()
|
static void
|
||||||
|
icmp_input()
|
||||||
{
|
{
|
||||||
uint8_t inconsistency;
|
uint8_t inconsistency;
|
||||||
uint16_t *seq_ptr;
|
uint16_t *seq_ptr;
|
||||||
|
@ -1417,6 +1424,9 @@ init()
|
||||||
ROLL_TM_STATS_INIT();
|
ROLL_TM_STATS_INIT();
|
||||||
UIP_MCAST6_STATS_INIT(&stats);
|
UIP_MCAST6_STATS_INIT(&stats);
|
||||||
|
|
||||||
|
/* Register the ICMPv6 input handler */
|
||||||
|
uip_icmp6_register_input_handler(&roll_tm_icmp_handler);
|
||||||
|
|
||||||
for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows;
|
for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows;
|
||||||
iterswptr--) {
|
iterswptr--) {
|
||||||
iterswptr->lower_bound = -1;
|
iterswptr->lower_bound = -1;
|
||||||
|
|
|
@ -213,14 +213,6 @@
|
||||||
#define ROLL_TM_SET_M_BIT 1
|
#define ROLL_TM_SET_M_BIT 1
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Prototypes of additional Trickle Multicast functions */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Called by the uIPv6 engine when it receives a Trickle Multicast
|
|
||||||
* ICMPv6 datagram
|
|
||||||
*/
|
|
||||||
void roll_tm_icmp_input();
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* Stats datatype */
|
/* Stats datatype */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
struct roll_tm_stats {
|
struct roll_tm_stats {
|
||||||
|
|
|
@ -74,10 +74,53 @@
|
||||||
static uip_ipaddr_t tmp_ipaddr;
|
static uip_ipaddr_t tmp_ipaddr;
|
||||||
|
|
||||||
LIST(echo_reply_callback_list);
|
LIST(echo_reply_callback_list);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* List of input handlers */
|
||||||
|
LIST(input_handler_list);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uip_icmp6_input_handler_t *
|
||||||
|
input_handler_lookup(uint8_t type, uint8_t icode)
|
||||||
|
{
|
||||||
|
uip_icmp6_input_handler_t *handler = NULL;
|
||||||
|
|
||||||
|
for(handler = list_head(input_handler_list);
|
||||||
|
handler != NULL;
|
||||||
|
handler = list_item_next(handler)) {
|
||||||
|
if(handler->type == type &&
|
||||||
|
(handler->icode == icode ||
|
||||||
|
handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uint8_t
|
||||||
|
uip_icmp6_input(uint8_t type, uint8_t icode)
|
||||||
|
{
|
||||||
|
uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
|
||||||
|
|
||||||
|
if(handler == NULL) {
|
||||||
|
return UIP_ICMP6_INPUT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler->handler == NULL) {
|
||||||
|
return UIP_ICMP6_INPUT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->handler();
|
||||||
|
return UIP_ICMP6_INPUT_SUCCESS;
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_icmp6_echo_request_input(void)
|
uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
|
||||||
|
{
|
||||||
|
list_add(input_handler_list, handler);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
echo_request_input(void)
|
||||||
{
|
{
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
uint8_t temp_ext_len;
|
uint8_t temp_ext_len;
|
||||||
|
@ -275,8 +318,8 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
uip_icmp6_echo_reply_input(void)
|
echo_reply_input(void)
|
||||||
{
|
{
|
||||||
int ttl;
|
int ttl;
|
||||||
uip_ipaddr_t sender;
|
uip_ipaddr_t sender;
|
||||||
|
@ -343,6 +386,8 @@ uip_icmp6_echo_reply_input(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -362,5 +407,18 @@ uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
|
||||||
list_remove(echo_reply_callback_list, n);
|
list_remove(echo_reply_callback_list, n);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
UIP_ICMP6_HANDLER(echo_request_handler, ICMP6_ECHO_REQUEST,
|
||||||
|
UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input);
|
||||||
|
UIP_ICMP6_HANDLER(echo_reply_handler, ICMP6_ECHO_REPLY,
|
||||||
|
UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_icmp6_init()
|
||||||
|
{
|
||||||
|
/* Register Echo Request and Reply handlers */
|
||||||
|
uip_icmp6_register_input_handler(&echo_request_handler);
|
||||||
|
uip_icmp6_register_input_handler(&echo_reply_handler);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -109,24 +109,6 @@ typedef struct uip_icmp6_error{
|
||||||
|
|
||||||
/** \name ICMPv6 RFC4443 Message processing and sending */
|
/** \name ICMPv6 RFC4443 Message processing and sending */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/** \
|
|
||||||
* brief Process an echo request
|
|
||||||
*
|
|
||||||
* Perform a few checks, then send an Echo reply. The reply is
|
|
||||||
* built here.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
uip_icmp6_echo_request_input(void);
|
|
||||||
|
|
||||||
/** \
|
|
||||||
* brief Process an echo reply
|
|
||||||
*
|
|
||||||
* Perform a few checks, then call applications to inform that an echo
|
|
||||||
* reply has been received.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
uip_icmp6_echo_reply_input(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Send an icmpv6 error message
|
* \brief Send an icmpv6 error message
|
||||||
* \param type type of the error message
|
* \param type type of the error message
|
||||||
|
@ -192,8 +174,66 @@ uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
|
||||||
void
|
void
|
||||||
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
||||||
|
|
||||||
|
/* Generic ICMPv6 input handers */
|
||||||
|
typedef struct uip_icmp6_input_handler {
|
||||||
|
struct uip_icmp6_input_handler *next;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t icode;
|
||||||
|
void (*handler)(void);
|
||||||
|
} uip_icmp6_input_handler_t;
|
||||||
|
|
||||||
|
#define UIP_ICMP6_INPUT_SUCCESS 0
|
||||||
|
#define UIP_ICMP6_INPUT_ERROR 1
|
||||||
|
|
||||||
|
#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise a variable of type uip_icmp6_input_handler, to be used later as
|
||||||
|
* the argument to uip_icmp6_register_input_handler
|
||||||
|
*
|
||||||
|
* The function pointer stored in this variable will get called and will be
|
||||||
|
* expected to handle incoming ICMPv6 datagrams of the specified type/code
|
||||||
|
*
|
||||||
|
* If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function
|
||||||
|
* will handle all codes for this type. In other words, the ICMPv6
|
||||||
|
* message's code is "don't care"
|
||||||
|
*/
|
||||||
|
#define UIP_ICMP6_HANDLER(name, type, code, func) \
|
||||||
|
static uip_icmp6_input_handler_t name = { NULL, type, code, func }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Handle an incoming ICMPv6 message
|
||||||
|
* \param type The ICMPv6 message type
|
||||||
|
* \param icode The ICMPv6 message code
|
||||||
|
* \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR
|
||||||
|
*
|
||||||
|
* Generic handler for unknown ICMPv6 types. It will lookup for a registered
|
||||||
|
* function capable of handing this message type. The function must have first
|
||||||
|
* been registered with uip_icmp6_register_input_handler. The function is in
|
||||||
|
* charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to
|
||||||
|
* send whatever remains in the UIP_IP_BUF.
|
||||||
|
*
|
||||||
|
* A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be
|
||||||
|
* invoked. This is most likely because the ICMPv6 type does not have a valid
|
||||||
|
* handler associated with it.
|
||||||
|
|
||||||
|
* UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6
|
||||||
|
* type and that it was invoked. It does NOT provide any indication whatsoever
|
||||||
|
* regarding whether the handler itself succeeded.
|
||||||
|
*/
|
||||||
|
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Register a handler which can handle a specific ICMPv6 message type
|
||||||
|
* \param handler A pointer to the handler
|
||||||
|
*/
|
||||||
|
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialise the uIP ICMPv6 core
|
||||||
|
*/
|
||||||
|
void uip_icmp6_init(void);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,6 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
|
||||||
static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
|
static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
|
||||||
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
|
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
|
||||||
static uip_ds6_addr_t *addr; /** Pointer to an interface address */
|
static uip_ds6_addr_t *addr; /** Pointer to an interface address */
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* create a llao */
|
/* create a llao */
|
||||||
static void
|
static void
|
||||||
|
@ -143,8 +141,8 @@ create_llao(uint8_t *llao, uint8_t type) {
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
uip_nd6_ns_input(void)
|
ns_input(void)
|
||||||
{
|
{
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
PRINTF("Received NS from ");
|
PRINTF("Received NS from ");
|
||||||
|
@ -388,12 +386,26 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
void
|
/**
|
||||||
uip_nd6_na_input(void)
|
* Neighbor Advertisement Processing
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
na_input(void)
|
||||||
{
|
{
|
||||||
uint8_t is_llchange;
|
uint8_t is_llchange;
|
||||||
uint8_t is_router;
|
uint8_t is_router;
|
||||||
|
@ -548,8 +560,8 @@ discard:
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
#if UIP_ND6_SEND_RA
|
#if UIP_ND6_SEND_RA
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
uip_nd6_rs_input(void)
|
rs_input(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
PRINTF("Received RS from");
|
PRINTF("Received RS from");
|
||||||
|
@ -761,11 +773,18 @@ uip_nd6_rs_output(void)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* 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
|
void
|
||||||
uip_nd6_ra_input(void)
|
ra_input(void)
|
||||||
{
|
{
|
||||||
PRINTF("Received RA from");
|
PRINTF("Received RA from");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
|
@ -969,6 +988,52 @@ discard:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* !UIP_CONF_ROUTER */
|
#endif /* !UIP_CONF_ROUTER */
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
/* ICMPv6 input handlers */
|
||||||
|
#if UIP_ND6_SEND_NA
|
||||||
|
UIP_ICMP6_HANDLER(ns_input_handler, ICMP6_NS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
ns_input);
|
||||||
|
UIP_ICMP6_HANDLER(na_input_handler, ICMP6_NA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
na_input);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||||
|
UIP_ICMP6_HANDLER(rs_input_handler, ICMP6_RS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
rs_input);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !UIP_CONF_ROUTER
|
||||||
|
UIP_ICMP6_HANDLER(ra_input_handler, ICMP6_RA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
ra_input);
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_nd6_init()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if UIP_ND6_SEND_NA
|
||||||
|
/* Only handle NSs if we are prepared to send out NAs */
|
||||||
|
uip_icmp6_register_input_handler(&ns_input_handler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only handle NAs if we are prepared to send out NAs.
|
||||||
|
* This is perhaps logically incorrect, but this condition was present in
|
||||||
|
* uip_process and we keep it until proven wrong
|
||||||
|
*/
|
||||||
|
uip_icmp6_register_input_handler(&na_input_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||||
|
/* Only accept RS if we are a router and happy to send out RAs */
|
||||||
|
uip_icmp6_register_input_handler(&rs_input_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !UIP_CONF_ROUTER
|
||||||
|
/* Only process RAs if we are not a router */
|
||||||
|
uip_icmp6_register_input_handler(&ra_input_handler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -337,34 +337,8 @@ uip_nd6_ns_input(void);
|
||||||
void
|
void
|
||||||
uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
|
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_CONF_ROUTER
|
||||||
#if UIP_ND6_SEND_RA
|
#if UIP_ND6_SEND_RA
|
||||||
/**
|
|
||||||
* \brief Process a Router Solicitation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void uip_nd6_rs_input(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief send a Router Advertisement
|
* \brief send a Router Advertisement
|
||||||
*
|
*
|
||||||
|
@ -388,17 +362,9 @@ void uip_nd6_ra_output(uip_ipaddr_t *dest);
|
||||||
void uip_nd6_rs_output(void);
|
void uip_nd6_rs_output(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* \brief Initialise the uIP ND core
|
||||||
* \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
|
void uip_nd6_init(void);
|
||||||
uip_nd6_ra_input(void);
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,8 @@ uip_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
uip_ds6_init();
|
uip_ds6_init();
|
||||||
|
uip_icmp6_init();
|
||||||
|
uip_nd6_init();
|
||||||
|
|
||||||
#if UIP_TCP
|
#if UIP_TCP
|
||||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||||
|
@ -1420,67 +1422,17 @@ uip_process(uint8_t flag)
|
||||||
UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
|
UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
|
||||||
#endif /*UIP_CONF_ICMP6*/
|
#endif /*UIP_CONF_ICMP6*/
|
||||||
|
|
||||||
switch(UIP_ICMP_BUF->type) {
|
/*
|
||||||
case ICMP6_NS:
|
* Search generic input handlers.
|
||||||
#if UIP_ND6_SEND_NA
|
* The handler is in charge of setting uip_len to 0
|
||||||
uip_nd6_ns_input();
|
*/
|
||||||
#else /* UIP_ND6_SEND_NA */
|
if(uip_icmp6_input(UIP_ICMP_BUF->type,
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
UIP_ICMP_BUF->icode) == UIP_ICMP6_INPUT_ERROR) {
|
||||||
uip_len = 0;
|
PRINTF("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
|
||||||
break;
|
|
||||||
case ICMP6_NA:
|
|
||||||
#if UIP_ND6_SEND_NA
|
|
||||||
uip_nd6_na_input();
|
|
||||||
#else /* UIP_ND6_SEND_NA */
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
uip_len = 0;
|
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
|
||||||
break;
|
|
||||||
case ICMP6_RS:
|
|
||||||
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
|
||||||
uip_nd6_rs_input();
|
|
||||||
#else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
UIP_STAT(++uip_stat.icmp.drop);
|
||||||
|
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||||
|
UIP_LOG("icmp6: unknown ICMPv6 message.");
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
|
||||||
break;
|
|
||||||
case ICMP6_RA:
|
|
||||||
#if UIP_CONF_ROUTER
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
uip_len = 0;
|
|
||||||
#else /* UIP_CONF_ROUTER */
|
|
||||||
uip_nd6_ra_input();
|
|
||||||
#endif /* UIP_CONF_ROUTER */
|
|
||||||
break;
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
case ICMP6_RPL:
|
|
||||||
uip_rpl_input();
|
|
||||||
break;
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
case ICMP6_ECHO_REQUEST:
|
|
||||||
uip_icmp6_echo_request_input();
|
|
||||||
break;
|
|
||||||
case ICMP6_ECHO_REPLY:
|
|
||||||
/** Call echo reply input function. */
|
|
||||||
uip_icmp6_echo_reply_input();
|
|
||||||
PRINTF("Received an icmp6 echo reply\n");
|
|
||||||
UIP_STAT(++uip_stat.icmp.recv);
|
|
||||||
uip_len = 0;
|
|
||||||
break;
|
|
||||||
#if UIP_CONF_IPV6_ROLL_TM
|
|
||||||
case ICMP6_ROLL_TM:
|
|
||||||
roll_tm_icmp_input();
|
|
||||||
uip_len = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
|
||||||
UIP_LOG("icmp6: unknown ICMP message.");
|
|
||||||
uip_len = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uip_len > 0) {
|
if(uip_len > 0) {
|
||||||
|
|
|
@ -92,6 +92,12 @@ extern rpl_of_t RPL_OF;
|
||||||
static uip_mcast6_route_t *mcast_group;
|
static uip_mcast6_route_t *mcast_group;
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Initialise RPL ICMPv6 message handlers */
|
||||||
|
UIP_ICMP6_HANDLER(dis_handler, ICMP6_RPL, RPL_CODE_DIS, dis_input);
|
||||||
|
UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input);
|
||||||
|
UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input);
|
||||||
|
UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
get_global_addr(uip_ipaddr_t *addr)
|
get_global_addr(uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
|
@ -168,6 +174,7 @@ dis_input(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -409,6 +416,8 @@ dio_input(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rpl_process_dio(&from, &dio);
|
rpl_process_dio(&from, &dio);
|
||||||
|
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -786,6 +795,7 @@ fwd_dao:
|
||||||
dao_ack_output(instance, &dao_sender_addr, sequence);
|
dao_ack_output(instance, &dao_sender_addr, sequence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -915,6 +925,7 @@ dao_ack_input(void)
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -937,27 +948,12 @@ dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_rpl_input(void)
|
rpl_icmp6_register_handlers()
|
||||||
{
|
{
|
||||||
PRINTF("Received an RPL control message\n");
|
uip_icmp6_register_input_handler(&dis_handler);
|
||||||
switch(UIP_ICMP_BUF->icode) {
|
uip_icmp6_register_input_handler(&dio_handler);
|
||||||
case RPL_CODE_DIO:
|
uip_icmp6_register_input_handler(&dao_handler);
|
||||||
dio_input();
|
uip_icmp6_register_input_handler(&dao_ack_handler);
|
||||||
break;
|
|
||||||
case RPL_CODE_DIS:
|
|
||||||
dis_input();
|
|
||||||
break;
|
|
||||||
case RPL_CODE_DAO:
|
|
||||||
dao_input();
|
|
||||||
break;
|
|
||||||
case RPL_CODE_DAO_ACK:
|
|
||||||
dao_ack_input();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PRINTF("RPL: received an unknown ICMP6 code (%u)\n", UIP_ICMP_BUF->icode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uip_len = 0;
|
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -289,6 +289,7 @@ void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
|
||||||
void dao_output(rpl_parent_t *, uint8_t lifetime);
|
void dao_output(rpl_parent_t *, uint8_t lifetime);
|
||||||
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
||||||
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
||||||
|
void rpl_icmp6_register_handlers(void);
|
||||||
|
|
||||||
/* RPL logic functions. */
|
/* RPL logic functions. */
|
||||||
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
|
@ -300,6 +301,7 @@ rpl_init(void)
|
||||||
|
|
||||||
rpl_dag_init();
|
rpl_dag_init();
|
||||||
rpl_reset_periodic_timer();
|
rpl_reset_periodic_timer();
|
||||||
|
rpl_icmp6_register_handlers();
|
||||||
|
|
||||||
/* add rpl multicast address */
|
/* add rpl multicast address */
|
||||||
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
||||||
|
|
Loading…
Reference in a new issue