1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

ng_icmpv6_echo: initial import

This commit is contained in:
Martine Lenders 2015-04-01 17:35:23 +02:00 committed by Martine Lenders
parent da2ec1b89e
commit 86133b8404
7 changed files with 263 additions and 1 deletions

View File

@ -53,6 +53,11 @@ ifneq (,$(filter ng_sixlowpan_ctx,$(USEMODULE)))
USEMODULE += vtimer
endif
ifneq (,$(filter ng_icmpv6_echo,$(USEMODULE)))
USEMODULE += ng_icmpv6
USEMODULE += ng_netbase
endif
ifneq (,$(filter ng_icmpv6,$(USEMODULE)))
USEMODULE += ng_ipv6
endif

View File

@ -65,6 +65,9 @@ endif
ifneq (,$(filter ng_icmpv6,$(USEMODULE)))
DIRS += net/network_layer/ng_icmpv6
endif
ifneq (,$(filter ng_icmpv6_echo,$(USEMODULE)))
DIRS += net/network_layer/ng_icmpv6/echo
endif
ifneq (,$(filter ng_ipv6,$(USEMODULE)))
DIRS += net/network_layer/ng_ipv6
endif

View File

@ -34,6 +34,7 @@
#include "net/ng_nettype.h"
#include "net/ng_pkt.h"
#include "net/ng_icmpv6/echo.h"
#include "net/ng_icmpv6/error.h"
#include "net/ng_icmpv6/types.h"

View File

@ -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_ */
/** @} */

View File

@ -0,0 +1,3 @@
MODULE = ng_icmpv6_echo
include $(RIOTBASE)/Makefile.base

View File

@ -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);
}
}
/** @} */

View File

@ -28,6 +28,7 @@
#include "utlist.h"
#include "net/ng_icmpv6.h"
#include "net/ng_icmpv6/echo.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
@ -77,7 +78,8 @@ void ng_icmpv6_demux(kernel_pid_t iface, ng_pktsnip_t *pkt)
#ifdef MODULE_NG_ICMPV6_ECHO
case NG_ICMPV6_ECHO_REQ:
DEBUG("icmpv6: handle echo request.\n");
/* TODO */
ng_icmpv6_echo_req_handle(iface, (ng_ipv6_hdr_t *)ipv6->data,
(ng_icmpv6_echo_t *)hdr, icmpv6->size);
break;
#endif