diff --git a/Makefile.dep b/Makefile.dep index c0cb60f92c19c12f1bc24b0be9f8eb25b04c34fe..ff30654c85017f6a47dc571414f45317e5015a30 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 0000000000000000000000000000000000000000..8a954d06c4b01dbee290710c84a64470f6714459 --- /dev/null +++ b/sys/include/net/gnrc/ipv6/blacklist.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * Copyright (C) 2016 Martin Landsmann <martin.landsmann@haw-hamburg.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_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 <mlenders@inf.fu-berlin.de> + * @author Martin Landsmann <martin.landsmann@haw-hamburg.de> + */ +#ifndef GNRC_IPV6_BLACKLIST_H_ +#define GNRC_IPV6_BLACKLIST_H_ + +#include <stdbool.h> + +#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 76c83ddd2d92f169055404904936272121aa3edd..28e2d4f39060004f7b971579a3d365ff2c7442fc 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 0000000000000000000000000000000000000000..6cf34cffbd91e1f9b1af80c687aafc2e58d3f1cd --- /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 0000000000000000000000000000000000000000..1b90309cb9e642eb9403a4c04f92b87b0bde23a8 --- /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 <mlenders@inf.fu-berlin.de> + * @author Martin Landsmann <martin.landsmann@haw-hamburg.de> + */ + +#include <string.h> +#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 0000000000000000000000000000000000000000..b32cabe7ec270e055d9d9b910120b84444393993 --- /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 <mlenders@inf.fu-berlin.de> + * @author Martin Landsmann <martin.landsmann@haw-hamburg.de> + */ + +#include <stdio.h> + +#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 8b50581aa77b45cb6d5527e7af1fa5a30764cb93..d2062acbcea09aa3dbe6e80e61f77508dea2fc81 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 616c5fb5e9ffbb9183ebc5873f8e06375be09f10..5628af01c7453dadd896608ed97d80316843c5f1 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 0000000000000000000000000000000000000000..27df59e75060e063490084df66b040973e173955 --- /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 <mlenders@inf.fu-berlin.de> + * @author Martin Landsmann <martin.landsmann@haw-hamburg.de> + */ + +#include <stdio.h> +#include <string.h> + +#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 <addr>\n", cmd); + puts(" Adds <addr> to the blacklist."); + printf(" * %s del <addr>\n", cmd); + puts(" Deletes <addr> 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 32aa16702cbfaf544c2f7d4e4c85dafde273e2ad..35b16029f78c6dff32b35fe80ffe932521480a8a 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 },