

7 changed files with 263 additions and 1 deletions
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @defgroup net_ng_icmpv6_echo ICMPv6 echo messages |
||||
* @ingroup net_ng_icmpv6 |
||||
* @brief ICMPv6 echo request and reply |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief ICMPv6 echo message definitions |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
#ifndef NG_ICMPV6_ECHO_H_ |
||||
#define NG_ICMPV6_ECHO_H_ |
||||
|
||||
#include <inttypes.h> |
||||
|
||||
#include "byteorder.h" |
||||
#include "kernel_types.h" |
||||
#include "net/ng_icmpv6/types.h" |
||||
#include "net/ng_ipv6/hdr.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief Echo request and response message format. |
||||
* @extends ng_icmpv6_hdr_t |
||||
* |
||||
* @see <a href="https://tools.ietf.org/html/rfc4443#section-4.1"> |
||||
* RFC 4443, section 4.1 |
||||
* </a> |
||||
* @see <a href="https://tools.ietf.org/html/rfc4443#section-4.2"> |
||||
* RFC 4443, section 4.2 |
||||
* </a> |
||||
*/ |
||||
typedef struct __attribute__((packed)) { |
||||
uint8_t type; /**< message type */ |
||||
uint8_t code; /**< message code */ |
||||
network_uint16_t csum; /**< checksum */ |
||||
network_uint16_t id; /**< identifier */ |
||||
network_uint16_t seq; /**< Sequence number */ |
||||
} ng_icmpv6_echo_t; |
||||
|
||||
/**
|
||||
* @brief Builds an ICMPv6 echo message of type @p type for sending. |
||||
* |
||||
* @param[in] type Type of the echo message. Expected to be either |
||||
* NG_ICMPV6_ECHO_REQ or NG_ICMPV6_ECHO_REP. |
||||
* @param[in] id ID for the echo message in host byte-order |
||||
* @param[in] seq Sequence number for the echo message in host byte-order |
||||
* @param[in] data Payload for the echo message |
||||
* @param[in] data_len Length of @p data |
||||
* |
||||
* @return The echo message on success |
||||
* @return NULL, on failure |
||||
*/ |
||||
ng_pktsnip_t *ng_icmpv6_echo_build(uint8_t type, uint16_t id, uint16_t seq, |
||||
uint8_t *data, size_t data_len); |
||||
|
||||
/**
|
||||
* @brief Builds an ICMPv6 echo request for sending. |
||||
* |
||||
* @see <a href="https://tools.ietf.org/html/rfc4443#section-4.1"> |
||||
* RFC 4443, section 4.1 |
||||
* </a> |
||||
* |
||||
* @param[in] id ID for the echo request in host byte-order |
||||
* @param[in] seq Sequence number for the echo request in host byte-order |
||||
* @param[in] data Payload for the echo request |
||||
* @param[in] data_len Length of @p data |
||||
* |
||||
* @return The echo request message on success |
||||
* @return NULL, on failure |
||||
*/ |
||||
static inline ng_pktsnip_t *ng_icmpv6_echo_req_build(uint16_t id, uint16_t seq, |
||||
uint8_t *data, size_t data_len) |
||||
{ |
||||
return ng_icmpv6_echo_build(NG_ICMPV6_ECHO_REQ, id, seq, data, data_len); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Builds an ICMPv6 echo reply for sending. |
||||
* |
||||
* @see <a href="https://tools.ietf.org/html/rfc4443#section-4.2"> |
||||
* RFC 4443, section 4.2 |
||||
* </a> |
||||
* |
||||
* @param[in] id ID for the echo reply in host byte-order |
||||
* @param[in] seq Sequence number for the echo reply in host byte-order |
||||
* @param[in] data Payload for the echo reply |
||||
* @param[in] data_len Length of @p data |
||||
* |
||||
* @return The echo reply message on success |
||||
* @return NULL, on failure |
||||
*/ |
||||
static inline ng_pktsnip_t *ng_icmpv6_echo_rep_build(uint16_t id, uint16_t seq, |
||||
uint8_t *data, size_t data_len) |
||||
{ |
||||
return ng_icmpv6_echo_build(NG_ICMPV6_ECHO_REP, id, seq, data, data_len); |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 echo request handler |
||||
* |
||||
* @param[in] iface The interface the echo requuest was received on. |
||||
* @param[in] ipv6_hdr The IPv6 header of the echo request. |
||||
* @param[in] echo The Echo Request message. |
||||
* @param[in] len Length of the echo request message (ng_ipv6_hdr_t::len |
||||
* of @p ipv6_hdr minus length of extension headers). |
||||
*/ |
||||
void ng_icmpv6_echo_req_handle(kernel_pid_t iface, ng_ipv6_hdr_t *ipv6_hdr, |
||||
ng_icmpv6_echo_t *echo, uint16_t len); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* NG_ICMPV6_ECHO_H_ */ |
||||
/** @} */ |
@ -0,0 +1,3 @@
|
||||
MODULE = ng_icmpv6_echo
|
||||
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @{ |
||||
* |
||||
* @file |
||||
*/ |
||||
|
||||
#include "net/ng_netbase.h" |
||||
|
||||
#include "net/ng_icmpv6.h" |
||||
#include "net/ng_icmpv6/echo.h" |
||||
#include "utlist.h" |
||||
|
||||
#define ENABLE_DEBUG (0) |
||||
#include "debug.h" |
||||
|
||||
ng_pktsnip_t *ng_icmpv6_echo_build(uint8_t type, uint16_t id, uint16_t seq, |
||||
uint8_t *data, size_t data_len) |
||||
{ |
||||
ng_pktsnip_t *pkt; |
||||
ng_icmpv6_echo_t *echo; |
||||
|
||||
if ((pkt = ng_icmpv6_build(type, 0, data_len + sizeof(ng_icmpv6_echo_t))) == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
DEBUG("icmpv6_echo: Building echo message with type=%" PRIu8 "id=%" PRIu16 |
||||
", seq=%" PRIu16, type, id, seq); |
||||
echo = (ng_icmpv6_echo_t *)pkt->data; |
||||
echo->id = byteorder_htons(id >> 16); |
||||
echo->seq = byteorder_htons(seq); |
||||
|
||||
if (data != NULL) { |
||||
memcpy(echo + 1, data, data_len); |
||||
#if defined(MODULE_OD) && ENABLE_DEBUG |
||||
DEBUG(", payload:\n"); |
||||
od_hex_dump(data, data_len, OD_WIDTH_DEFAULT); |
||||
#endif |
||||
DEBUG("\n"); |
||||
} |
||||
#if ENABLE_DEBUG |
||||
else { |
||||
DEBUG("\n"); |
||||
} |
||||
#endif |
||||
|
||||
return pkt; |
||||
} |
||||
|
||||
void ng_icmpv6_echo_req_handle(kernel_pid_t iface, ng_ipv6_hdr_t *ipv6_hdr, |
||||
ng_icmpv6_echo_t *echo, uint16_t len) |
||||
{ |
||||
uint8_t *payload = ((uint8_t *)echo) + sizeof(ng_icmpv6_echo_t); |
||||
ng_pktsnip_t *hdr, *pkt; |
||||
ng_netreg_entry_t *sendto = NULL; |
||||
|
||||
if ((echo == NULL) || (len < sizeof(ng_icmpv6_echo_t))) { |
||||
DEBUG("icmpv6_echo: echo was NULL or len (%" PRIu16 |
||||
") was < sizeof(ng_icmpv6_echo_t)\n", len); |
||||
return; |
||||
} |
||||
|
||||
pkt = _echo_build(NG_ICMPV6_ECHO_REP, byteorder_ntohs(echo->id), |
||||
byteorder_ntohs(echo->seq), payload, |
||||
len - sizeof(ng_icmpv6_echo_t)); |
||||
|
||||
if (pkt == NULL) { |
||||
DEBUG("icmpv6_echo: no space left in packet buffer\n"); |
||||
return; |
||||
} |
||||
|
||||
if (ng_ipv6_addr_is_multicast(&ipv6_hdr->dst)) { |
||||
hdr = ng_ipv6_hdr_build(pkt, NULL, 0, (uint8_t *)&ipv6_hdr->src, |
||||
sizeof(ng_ipv6_addr_t)); |
||||
} |
||||
else { |
||||
hdr = ng_ipv6_hdr_build(pkt, (uint8_t *)&ipv6_hdr->dst, |
||||
sizeof(ng_ipv6_addr_t), (uint8_t *)&ipv6_hdr->src, |
||||
sizeof(ng_ipv6_addr_t)); |
||||
} |
||||
|
||||
if (hdr == NULL) { |
||||
DEBUG("icmpv6_echo: no space left in packet buffer\n"); |
||||
ng_pktbuf_release(pkt); |
||||
return; |
||||
} |
||||
|
||||
pkt = hdr; |
||||
hdr = ng_netif_hdr_build(NULL, 0, NULL, 0); |
||||
|
||||
((ng_netif_hdr_t *)hdr->data)->if_pid = iface; |
||||
|
||||
LL_PREPEND(pkt, hdr); |
||||
|
||||
sendto = ng_netreg_lookup(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL); |
||||
|
||||
if (sendto == NULL) { |
||||
DEBUG("icmpv6_echo: no receivers for IPv6 packets\n"); |
||||
ng_pktbuf_release(pkt); |
||||
return; |
||||
} |
||||
|
||||
/* ICMPv6 is not interested anymore so `- 1` */ |
||||
ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL) - 1); |
||||
|
||||
while (sendto != NULL) { |
||||
ng_netapi_send(sendto->pid, pkt); |
||||
sendto = ng_netreg_getnext(sendto); |
||||
} |
||||
} |
||||
|
||||
/** @} */ |
Loading…
Reference in new issue