diff --git a/boards/native/include/eui_provider_params.h b/boards/native/include/eui_provider_params.h new file mode 100644 index 0000000000..0af230a2c9 --- /dev/null +++ b/boards/native/include/eui_provider_params.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ML!PA Consulting GmbH + * + * 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. + */ + +/** + * @ingroup boards_native + * @{ + * + * @file + * @brief EUI providers found on the board + * + * @author Benjamin Valentin + */ +#ifndef EUI_PROVIDER_PARAMS_H +#define EUI_PROVIDER_PARAMS_H + +#include "native_cli_eui_provider.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name EUI sources on the board + * EUI-64 can be provided with the -Z command line argument + * @{ + */ +#define EUI64_PROVIDER_FUNC native_cli_get_eui64 +#define EUI64_PROVIDER_TYPE NETDEV_ANY +#define EUI64_PROVIDER_INDEX NETDEV_INDEX_ANY +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* EUI_PROVIDER_PARAMS_H */ +/** @} */ diff --git a/cpu/native/Makefile b/cpu/native/Makefile index 552c3f8b25..9f279f954a 100644 --- a/cpu/native/Makefile +++ b/cpu/native/Makefile @@ -30,6 +30,10 @@ ifneq (,$(filter backtrace,$(USEMODULE))) DIRS += backtrace endif +ifneq (,$(filter native_cli_eui_provider,$(USEMODULE))) + DIRS += cli_eui_provider +endif + include $(RIOTBASE)/Makefile.base INCLUDES = $(NATIVEINCLUDES) diff --git a/cpu/native/Makefile.dep b/cpu/native/Makefile.dep index 19ddb2ea39..01620b3bad 100644 --- a/cpu/native/Makefile.dep +++ b/cpu/native/Makefile.dep @@ -21,6 +21,14 @@ ifneq (,$(filter periph_rtc,$(USEMODULE))) USEMODULE += xtimer endif +ifneq (,$(filter eui_provider,$(USEMODULE))) + USEMODULE += native_cli_eui_provider +endif + +ifneq (,$(filter native_cli_eui_provider,$(USEMODULE))) + USEMODULE += l2util +endif + USEMODULE += periph # UART is needed by startup.c diff --git a/cpu/native/cli_eui_provider/Makefile b/cpu/native/cli_eui_provider/Makefile new file mode 100644 index 0000000000..cafbfc6040 --- /dev/null +++ b/cpu/native/cli_eui_provider/Makefile @@ -0,0 +1,3 @@ +MODULE := native_cli_eui_provider + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/native/cli_eui_provider/eui_provider.c b/cpu/native/cli_eui_provider/eui_provider.c new file mode 100644 index 0000000000..b187b19743 --- /dev/null +++ b/cpu/native/cli_eui_provider/eui_provider.c @@ -0,0 +1,65 @@ +/** + * Native CPU EUI provider + * + * Copyright (C) 2020 Benjamin Valentin + * + * 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. + * + * @ingroup cpu_native + * @{ + * @file + * @author Benjamin Valentin + * @} + */ + +#include +#include + +#include "net/l2util.h" +#include "native_cli_eui_provider.h" +#include "list.h" + +#include "native_internal.h" + +/* list of user supplied EUI-64s */ +typedef struct { + list_node_t node; + eui64_t addr; +} native_eui64_list_t; + +static list_node_t head; + +/* parse EUI-64 from command line */ +void native_cli_add_eui64(const char *s) +{ + _native_syscall_enter(); + native_eui64_list_t *e = real_malloc(sizeof(native_eui64_list_t)); + _native_syscall_leave(); + + size_t res = l2util_addr_from_str(s, e->addr.uint8); + assert(res <= sizeof(eui64_t)); + + /* if the provided address exceeds eui64_t, l2util_addr_from_str() + * *will* corrupt memory. */ + if (res > sizeof(eui64_t)) { + exit(-1); + } + + list_add(&head, &e->node); +} + +/* callback for EUI provider */ +int native_cli_get_eui64(uint8_t index, eui64_t *addr) +{ + uint8_t cnt = 0; + for (list_node_t *e = head.next; e != NULL; e = e->next) { + if (cnt++ == index) { + *addr = container_of(e, native_eui64_list_t, node)->addr; + return 0; + } + } + + return -1; +} diff --git a/cpu/native/include/native_cli_eui_provider.h b/cpu/native/include/native_cli_eui_provider.h new file mode 100644 index 0000000000..0ed57a7a22 --- /dev/null +++ b/cpu/native/include/native_cli_eui_provider.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * 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. + */ + +/** + * @ingroup cpu_native + * @{ + * + * @file + * @brief Command-line EUI provider for native + * + * @author Benjamin Valentin + */ + +#ifndef NATIVE_CLI_EUI_PROVIDER_H +#define NATIVE_CLI_EUI_PROVIDER_H + +#include "net/eui64.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name parse a string as an EUI-64 and add it to the list of EUI-64s + * + * @param s[in] EUI-64 as hexadecimal string representation + */ +void native_cli_add_eui64(const char *s); + +/** + * @name Get a command-line provided EUI-64 + * + * @param index index of ZEP device + * @param addr[out] user supplied EUI-64 + * + * @return 0 on success, negatvie if no more EUIs are available. + */ +int native_cli_get_eui64(uint8_t index, eui64_t *addr); + +#ifdef __cplusplus +} +#endif + +#endif /* NATIVE_CLI_EUI_PROVIDER_H */ +/** @} */ diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index d61689eb26..b997b0a0ae 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -181,8 +181,6 @@ int register_interrupt(int sig, _native_callback_t handler); */ int unregister_interrupt(int sig); -//#include - #ifdef __cplusplus } #endif diff --git a/cpu/native/include/socket_zep.h b/cpu/native/include/socket_zep.h index 7529e7d8ef..4731cb0a6a 100644 --- a/cpu/native/include/socket_zep.h +++ b/cpu/native/include/socket_zep.h @@ -98,8 +98,10 @@ typedef struct { * * @param[in] dev the preallocated socket_zep_t device handle to setup * @param[in] params initialization parameters + * @param[in] index index of @p params in a global parameter struct array. + * If initialized manually, pass a unique identifier instead. */ -void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params); +void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params, uint8_t index); /** * @brief Cleanup socket resources diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index 1291961a05..9d2c5ca910 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -408,7 +408,7 @@ static void _send_zep_hello(socket_zep_t *dev) } } -void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params) +void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params, uint8_t index) { int res; @@ -418,6 +418,8 @@ void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params) memset(dev, 0, sizeof(socket_zep_t)); dev->netdev.netdev.driver = &socket_zep_driver; + netdev_register(&dev->netdev.netdev, NETDEV_SOCKET_ZEP, index); + res = _bind_local(params); if (res < 0) { @@ -431,30 +433,9 @@ void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params) _send_zep_hello(dev); } - /* generate hardware address from local address */ - uint8_t ss_array[sizeof(struct sockaddr_storage)] = { 0 }; - socklen_t ss_len = sizeof(struct sockaddr_storage); + /* setup hardware address */ + netdev_ieee802154_setup(&dev->netdev); - if (getpeername(dev->sock_fd, (struct sockaddr *)&ss_array, &ss_len) < 0) { - err(EXIT_FAILURE, "ZEP: Unable to retrieve remote address"); - } - assert(ss_len >= IEEE802154_LONG_ADDRESS_LEN); - if (getsockname(dev->sock_fd, (struct sockaddr *)&ss_array, &ss_len) < 0) { - err(EXIT_FAILURE, "ZEP: Unable to retrieve local address"); - } - assert(ss_len >= IEEE802154_LONG_ADDRESS_LEN); - - /* generate hardware address from socket address and port info */ - dev->netdev.long_addr[1] = 'Z'; /* The "OUI" */ - dev->netdev.long_addr[2] = 'E'; - dev->netdev.long_addr[3] = 'P'; - for (unsigned i = 0; i < ss_len; i++) { /* generate NIC from local source */ - unsigned addr_idx = (i % (IEEE802154_LONG_ADDRESS_LEN / 2)) + - (IEEE802154_LONG_ADDRESS_LEN / 2); - dev->netdev.long_addr[addr_idx] ^= ss_array[i]; - } - dev->netdev.short_addr[0] = dev->netdev.long_addr[6]; - dev->netdev.short_addr[1] = dev->netdev.long_addr[7]; native_async_read_setup(); native_async_read_add_handler(dev->sock_fd, dev, _socket_isr); } diff --git a/cpu/native/startup.c b/cpu/native/startup.c index 522a8195a6..9009487290 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -84,6 +84,9 @@ netdev_tap_params_t netdev_tap_params[NETDEV_TAP_MAX]; #ifdef MODULE_PERIPH_GPIO_LINUX #include "gpiodev_linux.h" #endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER +#include "native_cli_eui_provider.h" +#endif #ifdef MODULE_SOCKET_ZEP #include "socket_zep_params.h" @@ -107,6 +110,9 @@ static const char short_opts[] = ":hi:s:deEoc:" #ifdef MODULE_SOCKET_ZEP "z:" #endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER + "U:" +#endif #ifdef MODULE_PERIPH_SPIDEV_LINUX "p:" #endif @@ -133,6 +139,9 @@ static const struct option long_opts[] = { #ifdef MODULE_SOCKET_ZEP { "zep", required_argument, NULL, 'z' }, #endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER + { "eui64", required_argument, NULL, 'U' }, +#endif #ifdef MODULE_PERIPH_SPIDEV_LINUX { "spi", required_argument, NULL, 'p' }, #endif @@ -268,23 +277,29 @@ void usage_exit(int status) real_printf(" ", i + 1); } #endif - real_printf(" [-i ] [-d] [-e|-E] [-o] [-c ]\n"); + real_printf(" [-i ] [-d] [-e|-E] [-o] [-c ]"); #ifdef MODULE_PERIPH_GPIO_LINUX - real_printf(" [-g ]\n"); + real_printf(" [-g ]"); #endif + real_printf(" [-i ] [-d] [-e|-E] [-o] [-c ]"); #if defined(MODULE_SOCKET_ZEP) && (SOCKET_ZEP_MAX > 0) - real_printf(" -z [[:,]:]\n"); + real_printf(" -z [[:,]:]"); for (int i = 0; i < SOCKET_ZEP_MAX - 1; i++) { /* for further interfaces the local address must be different so we omit * the braces (marking them as optional) to be 100% clear on that */ - real_printf(" -z :,:\n"); + real_printf(" -z :,:"); } #endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER + real_printf(" [--eui64 …]"); +#endif #ifdef MODULE_PERIPH_SPIDEV_LINUX - real_printf(" [-p ::]\n"); + real_printf(" [-p ::]"); #endif - real_printf(" help: %s -h\n\n", _progname); + real_printf("\n\n"); + + real_printf("help: %s -h\n", _progname); real_printf("\nOptions:\n" " -h, --help\n" @@ -320,6 +335,11 @@ void usage_exit(int status) " The ZEP interface connects to the remote address and may listen\n" " on a local address.\n" " Required to be provided SOCKET_ZEP_MAX times\n" +#endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER +" -U , --eui64=\n" +" provide a ZEP interface with EUI-64 (MAC address)\n" +" This argument can be provided multiple times\n" #endif ); #ifdef MODULE_MTD_NATIVE @@ -411,6 +431,7 @@ static void _zep_params_setup(char *zep_str, int zep) &socket_zep_params[zep].remote_port); } } + #endif /** @brief Initialization function pointer type */ @@ -528,6 +549,11 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e _zep_params_setup(optarg, zeps++); break; #endif +#ifdef MODULE_NATIVE_CLI_EUI_PROVIDER + case 'U': + native_cli_add_eui64(optarg); + break; +#endif #ifdef MODULE_PERIPH_SPIDEV_LINUX case 'p': { long bus = strtol(optarg, &optarg, 10); diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index e5d3623d6a..2a1b2b040d 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -317,6 +317,7 @@ typedef enum { NETDEV_SAM0_ETH, NETDEV_ESP_NOW, NETDEV_NRF24L01P_NG, + NETDEV_SOCKET_ZEP, /* add more if needed */ } netdev_type_t; /** @} */ diff --git a/pkg/lwip/contrib/lwip.c b/pkg/lwip/contrib/lwip.c index ea7a7234b7..fbd8672d2f 100644 --- a/pkg/lwip/contrib/lwip.c +++ b/pkg/lwip/contrib/lwip.c @@ -228,7 +228,7 @@ void lwip_bootstrap(void) } #elif defined(MODULE_SOCKET_ZEP) for (unsigned i = 0; i < LWIP_NETIF_NUMOF; i++) { - socket_zep_setup(&socket_zep_devs[i], &socket_zep_params[i]); + socket_zep_setup(&socket_zep_devs[i], &socket_zep_params[i], i); if (netif_add(&netif[i], &socket_zep_devs[i], lwip_netdev_init, tcpip_6lowpan_input) == NULL) { DEBUG("Could not add socket_zep device\n"); diff --git a/sys/net/gnrc/netif/init_devs/auto_init_socket_zep.c b/sys/net/gnrc/netif/init_devs/auto_init_socket_zep.c index b509bb0bdb..c57ba7de33 100644 --- a/sys/net/gnrc/netif/init_devs/auto_init_socket_zep.c +++ b/sys/net/gnrc/netif/init_devs/auto_init_socket_zep.c @@ -46,7 +46,7 @@ void auto_init_socket_zep(void) for (int i = 0; i < SOCKET_ZEP_MAX; i++) { LOG_DEBUG("[auto_init_netif: initializing socket ZEP device #%u\n", i); /* setup netdev device */ - socket_zep_setup(&_socket_zeps[i], &socket_zep_params[i]); + socket_zep_setup(&_socket_zeps[i], &socket_zep_params[i], i); gnrc_netif_ieee802154_create(&_netif[i], _socket_zep_stacks[i], SOCKET_ZEP_MAC_STACKSIZE, SOCKET_ZEP_MAC_PRIO, "socket_zep", diff --git a/tests/socket_zep/main.c b/tests/socket_zep/main.c index 4f0ef80084..3243584525 100644 --- a/tests/socket_zep/main.c +++ b/tests/socket_zep/main.c @@ -52,7 +52,7 @@ static void test_init(void) printf("Initializing socket ZEP with (local: [%s]:%s, remote: [%s]:%s)\n", p->local_addr, p->local_port, p->remote_addr, p->remote_port); - socket_zep_setup(&_dev, p); + socket_zep_setup(&_dev, p, 0); netdev->event_callback = _event_cb; expect(netdev->driver->init(netdev) >= 0); _print_info(netdev);