From da60c56365ac13a262ffa6adaba7540c4d914843 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Wed, 24 Oct 2018 10:06:23 +0200 Subject: ipcpd: Add broadcast IPCP This adds a broadcast IPCP that allows us to easily create multicast applications. The broadcast IPCP accepts flows for ".mc". A tool, obc (Ouroboros broadcast), is added that sends and reads a message to a broadcast layer. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/tools/CMakeLists.txt | 1 + src/tools/irm/irm_ipcp_bootstrap.c | 16 +++- src/tools/irm/irm_ipcp_create.c | 17 ++-- src/tools/irm/irm_ipcp_enroll.c | 37 ++++++--- src/tools/obc/CMakeLists.txt | 16 ++++ src/tools/obc/obc.c | 154 +++++++++++++++++++++++++++++++++++++ 6 files changed, 219 insertions(+), 22 deletions(-) create mode 100644 src/tools/obc/CMakeLists.txt create mode 100644 src/tools/obc/obc.c (limited to 'src/tools') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index d7a4d17a..7c40d9ae 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(irm) add_subdirectory(ocbr) add_subdirectory(oecho) +add_subdirectory(obc) add_subdirectory(oping) add_subdirectory(operf) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 3d9386ad..861b1521 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -51,6 +51,7 @@ #endif #define NORMAL "normal" +#define BROADCAST "broadcast" #define UDP "udp" #define ETH_LLC "eth-llc" #define ETH_DIX "eth-dix" @@ -86,7 +87,7 @@ static void usage(void) " name \n" " layer \n" " [type [TYPE]]\n" - "where TYPE = {" NORMAL " " LOCAL " " + "where TYPE = {" NORMAL " " BROADCAST " " LOCAL " " UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "},\n\n" "if TYPE == " NORMAL "\n" " [addr
(default: %d)]\n" @@ -125,7 +126,9 @@ static void usage(void) "if TYPE == " RAPTOR "\n" " [hash [ALGORITHM] (default: %s)]\n" "where ALGORITHM = {" SHA3_224 " " SHA3_256 " " - SHA3_384 " " SHA3_512 "}\n\n", + SHA3_384 " " SHA3_512 "}\n" + "if TYPE == " BROADCAST "\n" + " [autobind]\n\n", DEFAULT_ADDR_SIZE, DEFAULT_EID_SIZE, DEFAULT_TTL, FLAT_RANDOM_ADDR_AUTH, LINK_STATE_ROUTING, SIMPLE_PFF, SHA3_256, SHA3_256, 0xA000, SHA3_256, SHA3_256, SHA3_256); @@ -250,6 +253,8 @@ int do_bootstrap_ipcp(int argc, if (ipcp_type != NULL) { if (strcmp(ipcp_type, NORMAL) == 0) type = IPCP_NORMAL; + else if (strcmp(ipcp_type, BROADCAST) == 0) + type = IPCP_BROADCAST; else if (strcmp(ipcp_type, UDP) == 0) type = IPCP_UDP; else if (strcmp(ipcp_type, ETH_LLC) == 0) @@ -285,8 +290,9 @@ int do_bootstrap_ipcp(int argc, } conf.type = ipcps[i].type; - if (autobind && conf.type != IPCP_NORMAL) { - printf("Can only bind normal IPCPs, " + if (autobind && (conf.type != IPCP_NORMAL && + conf.type != IPCP_BROADCAST)) { + printf("Can not bind this IPCP type," "autobind disabled.\n\n"); autobind = false; } @@ -326,6 +332,8 @@ int do_bootstrap_ipcp(int argc, conf.dev = dev; conf.ethertype = ethertype; break; + case IPCP_BROADCAST: + /* FALLTHRU */ case IPCP_LOCAL: /* FALLTHRU */ case IPCP_RAPTOR: diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c index c8866962..5694eccf 100644 --- a/src/tools/irm/irm_ipcp_create.c +++ b/src/tools/irm/irm_ipcp_create.c @@ -44,19 +44,20 @@ #include "irm_ops.h" #include "irm_utils.h" -#define NORMAL "normal" -#define UDP "udp" -#define ETH_LLC "eth-llc" -#define ETH_DIX "eth-dix" -#define LOCAL "local" -#define RAPTOR "raptor" +#define NORMAL "normal" +#define BROADCAST "broadcast" +#define UDP "udp" +#define ETH_LLC "eth-llc" +#define ETH_DIX "eth-dix" +#define LOCAL "local" +#define RAPTOR "raptor" static void usage(void) { printf("Usage: irm ipcp create\n" " name \n" " type [TYPE]\n\n" - "where TYPE = {" NORMAL " " LOCAL " " + "where TYPE = {" NORMAL " " BROADCAST " " LOCAL " " UDP " " ETH_LLC " " RAPTOR "}\n"); } @@ -90,6 +91,8 @@ int do_create_ipcp(int argc, if (strcmp(ipcp_type, NORMAL) == 0) type = IPCP_NORMAL; + else if (strcmp(ipcp_type, BROADCAST) == 0) + type = IPCP_BROADCAST; else if (strcmp(ipcp_type, UDP) == 0) type = IPCP_UDP; else if (strcmp(ipcp_type, LOCAL) == 0) diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c index c1628af6..5b6caf55 100644 --- a/src/tools/irm/irm_ipcp_enroll.c +++ b/src/tools/irm/irm_ipcp_enroll.c @@ -46,30 +46,39 @@ #include +#define NORMAL "normal" +#define BROADCAST "broadcast" + static void usage(void) { printf("Usage: irm ipcp enroll\n" " name \n" " layer \n" - " [autobind]\n"); + " [type [TYPE], default = normal]\n" + " [autobind]\n" + "where TYPE = {" NORMAL " " BROADCAST "}\n"); } int do_enroll_ipcp(int argc, char ** argv) { - char * ipcp = NULL; - char * layer = NULL; + char * ipcp = NULL; + char * layer = NULL; struct ipcp_info * ipcps; - pid_t pid = -1; - ssize_t len = 0; - int i = 0; - bool autobind = false; + pid_t pid = -1; + ssize_t len = 0; + int i = 0; + bool autobind = false; int cargs; + char * ipcp_type = NORMAL; + enum ipcp_type type = IPCP_INVALID; while (argc > 0) { cargs = 2; if (matches(*argv, "name") == 0) { ipcp = *(argv + 1); + } else if (matches(*argv, "type") == 0) { + ipcp_type = *(argv + 1); } else if (matches(*argv, "layer") == 0) { layer = *(argv + 1); } else if (matches(*argv, "autobind") == 0) { @@ -90,14 +99,19 @@ int do_enroll_ipcp(int argc, return -1; } + if (strcmp(ipcp_type, NORMAL) == 0) + type = IPCP_NORMAL; + else if (strcmp(ipcp_type, BROADCAST) == 0) + type = IPCP_BROADCAST; + len = irm_list_ipcps(&ipcps); for (i = 0; i < len; i++) if (wildcard_match(ipcps[i].name, ipcp) == 0 && - ipcps[i].type == IPCP_NORMAL) + ipcps[i].type == type) pid = ipcps[i].pid; if (pid < 0) { - pid = irm_create_ipcp(ipcp, IPCP_NORMAL); + pid = irm_create_ipcp(ipcp, type); if (pid < 0) goto fail; free(ipcps); @@ -105,7 +119,7 @@ int do_enroll_ipcp(int argc, } for (i = 0; i < len; i++) { - if (ipcps[i].type != IPCP_NORMAL) + if (ipcps[i].type != type) continue; if (wildcard_match(ipcps[i].name, ipcp) == 0) { pid = ipcps[i].pid; @@ -121,7 +135,8 @@ int do_enroll_ipcp(int argc, } if (autobind && irm_bind_process(pid, layer)) { - printf("Failed to bind %d to %s.\n", pid, layer); + printf("Failed to bind %d to %s.\n", + pid, layer); goto fail; } } diff --git a/src/tools/obc/CMakeLists.txt b/src/tools/obc/CMakeLists.txt new file mode 100644 index 00000000..db5e999b --- /dev/null +++ b/src/tools/obc/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +set(SOURCE_FILES + # Add source files here + obc.c + ) + +add_executable(obc ${SOURCE_FILES}) + +target_link_libraries(obc LINK_PUBLIC ouroboros-dev) + +install(TARGETS obc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/tools/obc/obc.c b/src/tools/obc/obc.c new file mode 100644 index 00000000..747d01d3 --- /dev/null +++ b/src/tools/obc/obc.c @@ -0,0 +1,154 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2018 + * + * A simple broadcast application + * + * Dimitri Staessens + * Sander Vrijders + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _POSIX_C_SOURCE 199309L + +#include + +#include +#include +#include + +#define BUF_SIZE 256 + +static void usage(void) +{ + printf("Usage: obc [OPTION]...\n" + "Sends a message to a broadcast network\n\n" + " -n --name Name of the broadcast layer\n" + " -m --message A message to send\n" + " [-l, --listen Listen mode]\n" + " --help Display this help text and exit\n"); +} + +static int reader_main(const char * dst) +{ + int fd; + char buf[BUF_SIZE]; + + printf("Starting a reader.\n"); + + fd = flow_alloc(dst, NULL, NULL); + if (fd < 0) { + printf("Failed to allocate multicast flow.\n"); + return -1; + } + + printf("New flow.\n"); + + while (true) { + ssize_t count = flow_read(fd, &buf, BUF_SIZE); + if (count < 0) { + printf("Failed to read.\n"); + flow_dealloc(fd); + break; + } + + printf("Message is %.*s.\n", (int) count, buf); + } + + return 0; +} + +static int writer_main(const char * dst, + const char * message) +{ + int fd = 0; + + fd = flow_alloc(dst, NULL, NULL); + if (fd < 0) { + printf("Failed to allocate multicast flow.\n"); + return -1; + } + + if (flow_write(fd, message, strlen(message) + 1) < 0) { + printf("Failed to write packet.\n"); + flow_dealloc(fd); + return -1; + } + + flow_dealloc(fd); + + return 0; +} + +int main(int argc, + char ** argv) +{ + int ret = -1; + bool reader = false; + char * name = NULL; + char * msg = "Ouroboros multicast rocks!"; + + argc--; + argv++; + while (argc > 0) { + if (strcmp(*argv, "-l") == 0 || + strcmp(*argv, "--listen") == 0) { + reader = true; + } else if (strcmp(*argv, "-n") == 0 || + strcmp(*argv, "--name") == 0) { + name = *(argv + 1); + argc--; + argv++; + } else if (strcmp(*argv, "-m") == 0 || + strcmp(*argv, "--message") == 0) { + msg = *(argv + 1); + argc--; + argv++; + } else { + usage(); + return 0; + } + argc--; + argv++; + } + + if (name == NULL) { + printf("Please specify a name.\n\n"); + usage(); + exit(EXIT_FAILURE); + } + + if (reader) + ret = reader_main(name); + else + ret = writer_main(name, msg); + + return ret; +} -- cgit v1.2.3