Added an API for getting a callback when a ping reply is received.
This commit is contained in:
parent
75cbf4f48a
commit
9114cd3215
3 changed files with 150 additions and 4 deletions
|
@ -71,6 +71,8 @@ static uip_ipaddr_t tmp_ipaddr;
|
|||
#include "rpl/rpl.h"
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
LIST(echo_reply_callback_list);
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -238,7 +240,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
|
||||
UIP_STAT(++uip_stat.icmp.sent);
|
||||
|
||||
PRINTF("Sending ICMPv6 ERROR message to");
|
||||
PRINTF("Sending ICMPv6 ERROR message type %d code %d to", type, code);
|
||||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
PRINTF("from");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -248,7 +250,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_send(uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||
uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||
{
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
|
@ -272,6 +274,92 @@ uip_icmp6_send(uip_ipaddr_t *dest, int type, int code, int payload_len)
|
|||
tcpip_ipv6_output();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_echo_reply_input(void)
|
||||
{
|
||||
int ttl;
|
||||
uip_ipaddr_t sender;
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
uint8_t temp_ext_len;
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
uip_ipaddr_copy(&sender, &UIP_IP_BUF->srcipaddr);
|
||||
ttl = UIP_IP_BUF->ttl;
|
||||
|
||||
if(uip_ext_len > 0) {
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
if((temp_ext_len = rpl_invert_header())) {
|
||||
/* If there were other extension headers*/
|
||||
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
|
||||
if (uip_ext_len != temp_ext_len) {
|
||||
uip_len -= (uip_ext_len - temp_ext_len);
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo reply payload (starting after the icmp
|
||||
* header) to the new location in the reply. The shift is
|
||||
* equal to the length of the remaining extension headers
|
||||
* present Note: UIP_ICMP_BUF still points to the echo reply
|
||||
* at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - (uip_ext_len - temp_ext_len),
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
|
||||
}
|
||||
uip_ext_len = temp_ext_len;
|
||||
uip_len -= uip_ext_len;
|
||||
} else {
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
/* If there were extension headers*/
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
uip_len -= uip_ext_len;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo reply payload (starting after the icmp header)
|
||||
* to the new location in the reply. The shift is equal to the
|
||||
* length of the extension headers present Note: UIP_ICMP_BUF
|
||||
* still points to the echo request at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len,
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
|
||||
uip_ext_len = 0;
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
}
|
||||
|
||||
/* Call all registered applications to let them know an echo reply
|
||||
has been received. */
|
||||
{
|
||||
struct uip_icmp6_echo_reply_notification *n;
|
||||
for(n = list_head(echo_reply_callback_list);
|
||||
n != NULL;
|
||||
n = list_item_next(n)) {
|
||||
if(n->callback != NULL) {
|
||||
n->callback(&sender, ttl,
|
||||
(uint8_t *)&UIP_ICMP_BUF[sizeof(struct uip_icmp_hdr)],
|
||||
uip_len - sizeof(struct uip_icmp_hdr) - UIP_IPH_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
|
||||
uip_icmp6_echo_reply_callback_t c)
|
||||
{
|
||||
if(n != NULL && c != NULL) {
|
||||
n->callback = c;
|
||||
list_add(echo_reply_callback_list, n);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
|
||||
{
|
||||
list_remove(echo_reply_callback_list, n);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
|
|
@ -113,6 +113,15 @@ typedef struct uip_icmp6_error{
|
|||
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
|
||||
* \param type type of the error message
|
||||
|
@ -130,7 +139,55 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
|||
* \param payload_len length of the payload
|
||||
*/
|
||||
void
|
||||
uip_icmp6_send(uip_ipaddr_t *dest, int type, int code, int payload_len);
|
||||
uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len);
|
||||
|
||||
|
||||
|
||||
typedef void (* uip_icmp6_echo_reply_callback_t)(uip_ipaddr_t *source,
|
||||
uint8_t ttl,
|
||||
uint8_t *data,
|
||||
uint16_t datalen);
|
||||
struct uip_icmp6_echo_reply_notification {
|
||||
struct uip_icmp6_echo_reply_notification *next;
|
||||
uip_icmp6_echo_reply_callback_t callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Add a callback function for ping replies
|
||||
* \param n A struct uip_icmp6_echo_reply_notification that must have been allocated by the caller
|
||||
* \param c A pointer to the callback function to be called
|
||||
*
|
||||
* This function adds a callback function to the list of
|
||||
* callback functions that are called when an ICMP echo
|
||||
* reply (ping reply) is received. This is used when
|
||||
* implementing a ping protocol: attach a callback
|
||||
* function to the ping reply, then send out a ping packet
|
||||
* with uip_icmp6_send().
|
||||
*
|
||||
* The caller must have statically allocated a struct
|
||||
* uip_icmp6_echo_reply_notification to hold the internal
|
||||
* state of the callback function.
|
||||
*
|
||||
* When a ping reply packet is received, all registered
|
||||
* callback functions are called. The callback functions
|
||||
* must not modify the contents of the uIP buffer.
|
||||
*/
|
||||
void
|
||||
uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
|
||||
uip_icmp6_echo_reply_callback_t c);
|
||||
|
||||
/**
|
||||
* \brief Remove a callback function for ping replies
|
||||
* \param n A struct uip_icmp6_echo_reply_notification that must have been previously added with uip_icmp6_echo_reply_callback_add()
|
||||
*
|
||||
* This function removes a callback function from the list of
|
||||
* callback functions that are called when an ICMP echo
|
||||
* reply (ping reply) is received.
|
||||
*/
|
||||
void
|
||||
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
||||
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -1431,7 +1431,8 @@ uip_process(uint8_t flag)
|
|||
uip_icmp6_echo_request_input();
|
||||
break;
|
||||
case ICMP6_ECHO_REPLY:
|
||||
/** \note We don't implement any application callback for now */
|
||||
/** 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;
|
||||
|
|
Loading…
Reference in a new issue