From 10ea1226bcd5600e6053b1b0a1eeeb6da92a49a7 Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Tue, 26 Jan 2016 11:28:01 +0100 Subject: [PATCH] gnrc/ipv6: add blacklisting of IPv6 addresses --- Makefile.dep | 4 + sys/include/net/gnrc/ipv6/blacklist.h | 79 +++++++++++++++++++ sys/net/gnrc/Makefile | 3 + .../network_layer/ipv6/blacklist/Makefile | 3 + .../ipv6/blacklist/gnrc_ipv6_blacklist.c | 68 ++++++++++++++++ .../blacklist/gnrc_ipv6_blacklist_print.c | 37 +++++++++ sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 16 ++++ sys/shell/commands/Makefile | 3 + sys/shell/commands/sc_blacklist.c | 63 +++++++++++++++ sys/shell/commands/shell_commands.c | 7 ++ 10 files changed, 283 insertions(+) create mode 100644 sys/include/net/gnrc/ipv6/blacklist.h create mode 100644 sys/net/gnrc/network_layer/ipv6/blacklist/Makefile create mode 100644 sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist.c create mode 100644 sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist_print.c create mode 100644 sys/shell/commands/sc_blacklist.c diff --git a/Makefile.dep b/Makefile.dep index c0cb60f92c..ff30654c85 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -223,6 +223,10 @@ ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE))) USEMODULE += ipv6_addr endif +ifneq (,$(filter gnrc_ipv6_blacklist,$(USEMODULE))) + USEMODULE += ipv6_addr +endif + ifneq (,$(filter gnrc_ipv6_router,$(USEMODULE))) USEMODULE += gnrc_ipv6 endif diff --git a/sys/include/net/gnrc/ipv6/blacklist.h b/sys/include/net/gnrc/ipv6/blacklist.h new file mode 100644 index 0000000000..8a954d06c4 --- /dev/null +++ b/sys/include/net/gnrc/ipv6/blacklist.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Martine Lenders + * Copyright (C) 2016 Martin Landsmann + * + * 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_gnrc_ipv6_blacklist IPv6 address blacklist + * @ingroup net_gnrc_ipv6 + * @brief This refuses IPv6 addresses that are defined in this list. + * @{ + * + * @file + * @brief IPv6 blacklist definitions + * + * @author Martine Lenders + * @author Martin Landsmann + */ +#ifndef GNRC_IPV6_BLACKLIST_H_ +#define GNRC_IPV6_BLACKLIST_H_ + +#include + +#include "net/ipv6/addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Maximum size of the blacklist. + */ +#ifndef GNRC_IPV6_BLACKLIST_SIZE +#define GNRC_IPV6_BLACKLIST_SIZE (8) +#endif + +/** + * @brief Adds an IPv6 address to the blacklist. + * + * @param[in] addr An IPv6 address. + * + * @return 0, on success. + * @return -1, if blacklist is full. + */ +int gnrc_ipv6_blacklist_add(const ipv6_addr_t *addr); + +/** + * @brief Removes an IPv6 address from the blacklist. + * + * Addresses not in the blacklist will be ignored. + * + * @param[in] addr An IPv6 address. + */ +void gnrc_ipv6_blacklist_del(const ipv6_addr_t *addr); + +/** + * @brief Checks if an IPv6 address is blacklisted. + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is blacklisted. + * @return false, if @p addr is not blacklisted. + */ +bool gnrc_ipv6_blacklisted(const ipv6_addr_t *addr); + +/** + * @brief Prints the blacklist. + */ +void gnrc_ipv6_blacklist_print(void); + +#ifdef __cplusplus +} +#endif + +#endif /* GNRC_IPV6_BLACKLIST_H_ */ +/** @} */ diff --git a/sys/net/gnrc/Makefile b/sys/net/gnrc/Makefile index 76c83ddd2d..28e2d4f390 100644 --- a/sys/net/gnrc/Makefile +++ b/sys/net/gnrc/Makefile @@ -34,6 +34,9 @@ endif ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE))) DIRS += network_layer/ipv6/whitelist endif +ifneq (,$(filter gnrc_ipv6_blacklist,$(USEMODULE))) + DIRS += network_layer/ipv6/blacklist +endif ifneq (,$(filter gnrc_ndp,$(USEMODULE))) DIRS += network_layer/ndp endif diff --git a/sys/net/gnrc/network_layer/ipv6/blacklist/Makefile b/sys/net/gnrc/network_layer/ipv6/blacklist/Makefile new file mode 100644 index 0000000000..6cf34cffbd --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/blacklist/Makefile @@ -0,0 +1,3 @@ +MODULE = gnrc_ipv6_blacklist + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist.c b/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist.c new file mode 100644 index 0000000000..1b90309cb9 --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist.c @@ -0,0 +1,68 @@ +/* + * 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 + * @author Martin Landsmann + */ + +#include +#include "bitfield.h" + +#include "net/gnrc/ipv6/blacklist.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +ipv6_addr_t gnrc_ipv6_blacklist[GNRC_IPV6_BLACKLIST_SIZE]; +BITFIELD(gnrc_ipv6_blacklist_set, GNRC_IPV6_BLACKLIST_SIZE); + +#if ENABLE_DEBUG +static char addr_str[IPV6_ADDR_MAX_STR_LEN]; +#endif + +int gnrc_ipv6_blacklist_add(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_BLACKLIST_SIZE; i++) { + if (!bf_isset(gnrc_ipv6_blacklist_set, i)) { + bf_set(gnrc_ipv6_blacklist_set, i); + memcpy(&gnrc_ipv6_blacklist[i], addr, sizeof(*addr)); + DEBUG("IPv6 blacklist: blacklisted %s\n", + ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); + return 0; + } + } + return -1; +} + +void gnrc_ipv6_blacklist_del(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_BLACKLIST_SIZE; i++) { + if (ipv6_addr_equal(addr, &gnrc_ipv6_blacklist[i])) { + bf_unset(gnrc_ipv6_blacklist_set, i); + DEBUG("IPv6 blacklist: unblacklisted %s\n", + ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); + } + } +} + +bool gnrc_ipv6_blacklisted(const ipv6_addr_t *addr) +{ + for (int i = 0; i < GNRC_IPV6_BLACKLIST_SIZE; i++) { + if (bf_isset(gnrc_ipv6_blacklist_set, i) && + ipv6_addr_equal(addr, &gnrc_ipv6_blacklist[i])) { + return true; + } + } + return false; +} + +/** @} */ diff --git a/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist_print.c b/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist_print.c new file mode 100644 index 0000000000..b32cabe7ec --- /dev/null +++ b/sys/net/gnrc/network_layer/ipv6/blacklist/gnrc_ipv6_blacklist_print.c @@ -0,0 +1,37 @@ +/* + * 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 + * @author Martin Landsmann + */ + +#include + +#include "bitfield.h" +#include "net/ipv6/addr.h" + +#include "net/gnrc/ipv6/blacklist.h" + +extern ipv6_addr_t gnrc_ipv6_blacklist[GNRC_IPV6_BLACKLIST_SIZE]; +extern BITFIELD(gnrc_ipv6_blacklist_set, GNRC_IPV6_BLACKLIST_SIZE); + +void gnrc_ipv6_blacklist_print(void) +{ + char addr_str[IPV6_ADDR_MAX_STR_LEN]; + for (int i = 0; i < GNRC_IPV6_BLACKLIST_SIZE; i++) { + if (bf_isset(gnrc_ipv6_blacklist_set, i)) { + puts(ipv6_addr_to_str(addr_str, &gnrc_ipv6_blacklist[i], sizeof(addr_str))); + } + } +} + +/** @} */ diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 8b50581aa7..d2062acbce 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -32,6 +32,7 @@ #include "net/gnrc/ipv6/nc.h" #include "net/gnrc/ipv6/netif.h" #include "net/gnrc/ipv6/whitelist.h" +#include "net/gnrc/ipv6/blacklist.h" #include "net/gnrc/ipv6.h" @@ -734,6 +735,13 @@ static void _receive(gnrc_pktsnip_t *pkt) gnrc_pktbuf_release(pkt); return; } +#endif +#ifdef MODULE_GNRC_IPV6_BLACKLIST + if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(pkt->data))->src)) { + DEBUG("ipv6: Source address blacklisted, dropping packet\n"); + gnrc_pktbuf_release(pkt); + return; + } #endif /* seize ipv6 as a temporary variable */ ipv6 = gnrc_pktbuf_start_write(pkt); @@ -762,6 +770,14 @@ static void _receive(gnrc_pktsnip_t *pkt) return; } #endif +#ifdef MODULE_GNRC_IPV6_BLACKLIST + else if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(ipv6->data))->src)) { + /* if ipv6 header already marked*/ + DEBUG("ipv6: Source address blacklisted, dropping packet\n"); + gnrc_pktbuf_release(pkt); + return; + } +#endif /* extract header */ hdr = (ipv6_hdr_t *)ipv6->data; diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 616c5fb5e9..5628af01c7 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -41,6 +41,9 @@ endif ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE))) SRC += sc_whitelist.c endif +ifneq (,$(filter gnrc_ipv6_blacklist,$(USEMODULE))) + SRC += sc_blacklist.c +endif ifneq (,$(filter gnrc_icmpv6_echo xtimer,$(USEMODULE))) SRC += sc_icmpv6_echo.c endif diff --git a/sys/shell/commands/sc_blacklist.c b/sys/shell/commands/sc_blacklist.c new file mode 100644 index 0000000000..27df59e750 --- /dev/null +++ b/sys/shell/commands/sc_blacklist.c @@ -0,0 +1,63 @@ +/* + * 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 + * @author Martin Landsmann + */ + +#include +#include + +#include "net/gnrc/ipv6/blacklist.h" + +static void _usage(char *cmd) +{ + printf("usage: * %s\n", cmd); + puts(" Lists all addresses in the blacklist."); + printf(" * %s add \n", cmd); + puts(" Adds to the blacklist."); + printf(" * %s del \n", cmd); + puts(" Deletes from the blacklist."); + printf(" * %s help\n", cmd); + puts(" Print this."); +} + +int _blacklist(int argc, char **argv) +{ + ipv6_addr_t addr; + if (argc < 2) { + gnrc_ipv6_blacklist_print(); + return 0; + } + else if (argc > 2) { + if (ipv6_addr_from_str(&addr, argv[2]) == NULL) { + _usage(argv[0]); + return 1; + } + } + if (strcmp("add", argv[1]) == 0) { + gnrc_ipv6_blacklist_add(&addr); + } + else if (strcmp("del", argv[1]) == 0) { + gnrc_ipv6_blacklist_del(&addr); + } + else if (strcmp("help", argv[1]) == 0) { + _usage(argv[0]); + } + else { + _usage(argv[0]); + return 1; + } + return 0; +} + +/** @} */ diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 32aa16702c..35b16029f7 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -102,6 +102,10 @@ extern int _ipv6_nc_routers(int argc, char **argv); extern int _whitelist(int argc, char **argv); #endif +#ifdef MODULE_GNRC_IPV6_BLACKLIST +extern int _blacklist(int argc, char **argv); +#endif + #ifdef MODULE_GNRC_ZEP #ifdef MODULE_IPV6_ADDR extern int _zep_init(int argc, char **argv); @@ -184,6 +188,9 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_GNRC_IPV6_WHITELIST {"whitelist", "whitelists an address for receival ('whitelist [add|del|help]')", _whitelist }, #endif +#ifdef MODULE_GNRC_IPV6_BLACKLIST + {"blacklist", "blacklists an address for receival ('blacklist [add|del|help]')", _blacklist }, +#endif #ifdef MODULE_GNRC_ZEP #ifdef MODULE_IPV6_ADDR {"zep_init", "initializes ZEP (Zigbee Encapsulation Protocol)", _zep_init },