From b6978b30e8ddb659502d14f8802ec1a03651b018 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 8 Mar 2014 21:24:50 +0000 Subject: [PATCH] Declare and Implement generic ICMPv6 handler management --- core/net/ipv6/uip-icmp6.c | 43 ++++++++++++++++++++++++++++++++ core/net/ipv6/uip-icmp6.h | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index 1ad0c62fc..e788b6d7f 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -74,7 +74,50 @@ static uip_ipaddr_t tmp_ipaddr; 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 +uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler) +{ + list_add(input_handler_list, handler); +} /*---------------------------------------------------------------------------*/ void uip_icmp6_echo_request_input(void) diff --git a/core/net/ipv6/uip-icmp6.h b/core/net/ipv6/uip-icmp6.h index fd5f7136f..842ae3670 100644 --- a/core/net/ipv6/uip-icmp6.h +++ b/core/net/ipv6/uip-icmp6.h @@ -192,8 +192,60 @@ uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n, void 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); /** @} */