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"
|
#include "rpl/rpl.h"
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
LIST(echo_reply_callback_list);
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -238,7 +240,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||||
|
|
||||||
UIP_STAT(++uip_stat.icmp.sent);
|
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);
|
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||||
PRINTF("from");
|
PRINTF("from");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
|
@ -248,7 +250,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
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;
|
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();
|
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 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -113,6 +113,15 @@ typedef struct uip_icmp6_error{
|
||||||
void
|
void
|
||||||
uip_icmp6_echo_request_input(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
|
||||||
|
@ -130,7 +139,55 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
||||||
* \param payload_len length of the payload
|
* \param payload_len length of the payload
|
||||||
*/
|
*/
|
||||||
void
|
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();
|
uip_icmp6_echo_request_input();
|
||||||
break;
|
break;
|
||||||
case ICMP6_ECHO_REPLY:
|
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");
|
PRINTF("Received an icmp6 echo reply\n");
|
||||||
UIP_STAT(++uip_stat.icmp.recv);
|
UIP_STAT(++uip_stat.icmp.recv);
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
|
Loading…
Reference in a new issue