From 5291f3b2bd607508e44ef825258c42d9918f0002 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Mon, 28 Sep 2015 14:40:35 +0200 Subject: [PATCH] gnrc_ipv6_whitelist: initial import --- Makefile.dep | 4 + sys/include/net/gnrc/ipv6/whitelist.h | 78 +++++++++++++++++++ sys/net/gnrc/Makefile | 3 + sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 16 +++- .../network_layer/ipv6/whitelist/Makefile | 3 + .../ipv6/whitelist/gnrc_ipv6_whitelist.c | 67 ++++++++++++++++ .../whitelist/gnrc_ipv6_whitelist_print.c | 36 +++++++++ 7 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 sys/include/net/gnrc/ipv6/whitelist.h create mode 100644 sys/net/gnrc/network_layer/ipv6/whitelist/Makefile create mode 100644 sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist.c create mode 100644 sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist_print.c diff --git a/Makefile.dep b/Makefile.dep index 89bab4b852..0c29e594ef 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -225,6 +225,10 @@ ifneq (,$(filter gnrc_ipv6_ext,$(USEMODULE))) USEMODULE += gnrc_ipv6 endif +ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE))) + USEMODULE += ipv6_addr +endif + ifneq (,$(filter gnrc_ipv6_router,$(USEMODULE))) USEMODULE += gnrc_ipv6 endif diff --git a/sys/include/net/gnrc/ipv6/whitelist.h b/sys/include/net/gnrc/ipv6/whitelist.h new file mode 100644 index 0000000000..b954b8e0d9 --- /dev/null +++ b/sys/include/net/gnrc/ipv6/whitelist.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * 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 gnrc_ipv6_whitelist Allows to whitelist certain IPv6 source addresses for + * reception. + * @ingroup gnrc_ipv6 + * @brief This allows you to only accept IPv6 addresses that are defined in this list. + * @{ + * + * @file + * @brief IPv6 whitelist definitions + * + * @author Martine Lenders + */ +#ifndef GNRC_IPV6_WHITELIST_H_ +#define GNRC_IPV6_WHITELIST_H_ + +#include + +#include "net/ipv6/addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Maximum size of the whitelist. + */ +#ifndef GNRC_IPV6_WHITELIST_SIZE +#define GNRC_IPV6_WHITELIST_SIZE (8) +#endif + +/** + * @brief Adds an IPv6 address to the whitelist. + * + * @param[in] addr An IPv6 address. + * + * @return 0, on success. + * @return -1, if whitelist is full. + */ +int gnrc_ipv6_whitelist_add(const ipv6_addr_t *addr); + +/** + * @brief Removes an IPv6 address from the whitelist. + * + * Addresses not in the whitelist will be ignored. + * + * @param[in] addr An IPv6 address. + */ +void gnrc_ipv6_whitelist_del(const ipv6_addr_t *addr); + +/** + * @brief Checks if an IPv6 address is whitelisted. + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is whitelisted. + * @return false, if @p addr is not whitelisted. + */ +bool gnrc_ipv6_whitelisted(const ipv6_addr_t *addr); + +/** + * @brief Prints the whitelist. + */ +void gnrc_ipv6_whitelist_print(void); + +#ifdef __cplusplus +} +#endif + +#endif /* GNRC_IPV6_WHITELIST_H_ */ +/** @} */ diff --git a/sys/net/gnrc/Makefile b/sys/net/gnrc/Makefile index cc7f891353..6ac2001c7a 100644 --- a/sys/net/gnrc/Makefile +++ b/sys/net/gnrc/Makefile @@ -28,6 +28,9 @@ endif ifneq (,$(filter gnrc_ipv6_netif,$(USEMODULE))) DIRS += network_layer/ipv6/netif endif +ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE))) + DIRS += network_layer/ipv6/whitelist +endif ifneq (,$(filter gnrc_ndp,$(USEMODULE))) DIRS += network_layer/ndp endif diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 4d89ec1941..74d138d232 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -30,6 +30,7 @@ #include "net/gnrc/ipv6/nc.h" #include "net/gnrc/ipv6/netif.h" +#include "net/gnrc/ipv6/whitelist.h" #include "net/gnrc/ipv6.h" @@ -706,6 +707,13 @@ static void _receive(gnrc_pktsnip_t *pkt) gnrc_pktbuf_release(pkt); return; } +#ifdef MODULE_GNRC_IPV6_WHITELIST + if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(ipv6->data))->src)) { + DEBUG("ipv6: Source address not whitelisted, dropping packet\n"); + gnrc_pktbuf_release(pkt); + return; + } +#endif } else { if (!ipv6_hdr_is(pkt->data)) { @@ -713,7 +721,13 @@ static void _receive(gnrc_pktsnip_t *pkt) gnrc_pktbuf_release(pkt); return; } - +#ifdef MODULE_GNRC_IPV6_WHITELIST + if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(pkt->data))->src)) { + DEBUG("ipv6: Source address not whitelisted, dropping packet\n"); + gnrc_pktbuf_release(pkt); + return; + } +#endif /* seize ipv6 as a temporary variable */ ipv6 = gnrc_pktbuf_start_write(pkt); diff --git a/sys/net/gnrc/network_layer/ipv6/whitelist/Makefile b/sys/net/gnrc/network_layer/ipv6/whitelist/Makefile new file mode 100644 index 0000000000..0638a322b9 --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/whitelist/Makefile @@ -0,0 +1,3 @@ +MODULE = gnrc_ipv6_whitelist + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist.c b/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist.c new file mode 100644 index 0000000000..d2beae5224 --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) Freie Universität Berlin + * + * 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 + * @author Martine Lenders + */ + +#include "bitfield.h" + +#include "net/gnrc/ipv6/whitelist.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +ipv6_addr_t gnrc_ipv6_whitelist[GNRC_IPV6_WHITELIST_SIZE]; +BITFIELD(gnrc_ipv6_whitelist_set, GNRC_IPV6_WHITELIST_SIZE); + +#if ENABLE_DEBUG +static char addr_str[IPV6_ADDR_MAX_STR_LEN]; +#endif + +int gnrc_ipv6_whitelist_add(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_WHITELIST_SIZE; i++) { + if (!bf_isset(gnrc_ipv6_whitelist_set, i)) { + bf_set(gnrc_ipv6_whitelist_set, i); + gnrc_ipv6_whitelist[i].u64[0].u64 = addr->u64[0].u64; + gnrc_ipv6_whitelist[i].u64[1].u64 = addr->u64[1].u64; + DEBUG("IPv6 whitelist: whitelisted %s\n", + ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); + return 0; + } + } + return -1; +} + +void gnrc_ipv6_whitelist_del(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_WHITELIST_SIZE; i++) { + if (ipv6_addr_equal(addr, &gnrc_ipv6_whitelist[i])) { + bf_unset(gnrc_ipv6_whitelist_set, i); + DEBUG("IPv6 whitelist: unwhitelisted %s\n", + ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); + } + } +} + +bool gnrc_ipv6_whitelisted(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_WHITELIST_SIZE; i++) { + if (bf_isset(gnrc_ipv6_whitelist_set, i) && + ipv6_addr_equal(addr, &gnrc_ipv6_whitelist[i])) { + return true; + } + } + return false; +} + +/** @} */ diff --git a/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist_print.c b/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist_print.c new file mode 100644 index 0000000000..9d2ad072ba --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/whitelist/gnrc_ipv6_whitelist_print.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) Freie Universität Berlin + * + * 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 + * @author Martine Lenders + */ + +#include + +#include "bitfield.h" +#include "net/ipv6/addr.h" + +#include "net/gnrc/ipv6/whitelist.h" + +extern ipv6_addr_t gnrc_ipv6_whitelist[GNRC_IPV6_WHITELIST_SIZE]; +extern BITFIELD(gnrc_ipv6_whitelist_set, GNRC_IPV6_WHITELIST_SIZE); + +void gnrc_ipv6_whitelist_print(void) +{ + char addr_str[IPV6_ADDR_MAX_STR_LEN]; + for (int i = 0; i < GNRC_IPV6_WHITELIST_SIZE; i++) { + if (bf_isset(gnrc_ipv6_whitelist_set, i)) { + puts(ipv6_addr_to_str(addr_str, &gnrc_ipv6_whitelist[i], sizeof(addr_str))); + } + } +} + +/** @} */