48 #include "contiki-default-conf.h"
53 #define PRINTF(...) printf(__VA_ARGS__)
54 #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
55 #define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5])
58 #define PRINT6ADDR(addr)
61 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
62 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
63 #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
64 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
65 #define UIP_FIRST_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLIPH_LEN])
74 static uip_ipaddr_t tmp_ipaddr;
76 LIST(echo_reply_callback_list);
79 LIST(input_handler_list);
81 static uip_icmp6_input_handler_t *
82 input_handler_lookup(uint8_t type, uint8_t icode)
84 uip_icmp6_input_handler_t *handler =
NULL;
86 for(handler =
list_head(input_handler_list);
89 if(handler->type == type &&
90 (handler->icode == icode ||
91 handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
102 uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
104 if(handler ==
NULL) {
105 return UIP_ICMP6_INPUT_ERROR;
108 if(handler->handler ==
NULL) {
109 return UIP_ICMP6_INPUT_ERROR;
113 return UIP_ICMP6_INPUT_SUCCESS;
119 list_add(input_handler_list, handler);
123 echo_request_input(
void)
125 #if UIP_CONF_IPV6_RPL
126 uint8_t temp_ext_len;
133 PRINTF(
"Received Echo Request from");
152 #if UIP_CONF_IPV6_RPL
153 if((temp_ext_len = rpl_invert_header())) {
155 UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
167 (
uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
184 (
uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
186 #if UIP_CONF_IPV6_RPL
200 PRINTF(
"Sending Echo Reply to");
214 if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 &&
UIP_ICMP_BUF->type < 128){
225 #if UIP_CONF_IPV6_RPL
239 memmove((uint8_t *)UIP_ICMP6_ERROR_BUF +
uip_ext_len + UIP_ICMP6_ERROR_LEN,
246 UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
279 UIP_ICMP6_ERROR_BUF->param = uip_htonl(param);
287 PRINTF(
"Sending ICMPv6 ERROR message type %d code %d to", type, code);
305 UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
306 UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
308 memcpy(&
UIP_IP_BUF->destipaddr, dest,
sizeof(*dest));
317 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len;
322 echo_reply_input(
void)
326 #if UIP_CONF_IPV6_RPL
327 uint8_t temp_ext_len;
334 #if UIP_CONF_IPV6_RPL
335 if((temp_ext_len = rpl_invert_header())) {
337 UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
350 (
uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
368 (
uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
370 #if UIP_CONF_IPV6_RPL
378 struct uip_icmp6_echo_reply_notification *n;
379 for(n =
list_head(echo_reply_callback_list);
382 if(n->callback !=
NULL) {
383 n->callback(&sender, ttl,
385 uip_len -
sizeof(
struct uip_icmp_hdr) - UIP_IPH_LEN);
396 uip_icmp6_echo_reply_callback_t c)
400 list_add(echo_reply_callback_list, n);
411 UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input);
413 UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input);
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
uip_len
The length of the packet in the uip_buf buffer.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 3513 a is of type uip_ipaddr_t*
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
Network interface and stateless autoconfiguration (RFC 4862)
void * list_item_next(void *item)
Get the next item following this item.
#define ICMP6_ECHO_REPLY
Echo reply.
#define NULL
The null pointer.
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
Register a handler which can handle a specific ICMPv6 message type.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
#define ICMP6_PARAM_PROB
ip6 header bad
#define UIP_STAT(s)
The uIP TCP/IP statistics.
#define ICMP6_PARAMPROB_OPTION
unrecognized option
#define UIP_IP_BUF
Pointer to IP header.
void uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
Remove a callback function for ping replies.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
void * list_head(list_t list)
Get a pointer to the first element of a list.
uint8_t uip_ext_len
The length of the extension headers.
void uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
Send an icmpv6 message.
ICMPv6 echo request and error messages (RFC 4443)
void list_add(list_t list, void *item)
Add an item at the end of a list.
#define ICMP6_ECHO_REQUEST
Echo request.
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
#define LIST(name)
Declare a linked list.
#define UIP_ICMP_BUF
Pointer to ICMP header.
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode)
Handle an incoming ICMPv6 message.
void uip_icmp6_init()
Initialise the uIP ICMPv6 core.
#define UIP_ICMP6_ERROR_LEN
ICMPv6 Error message constant part length.
void uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n, uip_icmp6_echo_reply_callback_t c)
Add a callback function for ping replies.