diff options
Diffstat (limited to 'src/tools/irm')
| -rw-r--r-- | src/tools/irm/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/tools/irm/irm_bind_ipcp.c | 27 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp.c | 1 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_bootstrap.c | 202 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_connect.c | 45 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_create.c | 8 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_destroy.c | 33 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_disconnect.c | 45 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_enroll.c | 84 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_list.c | 158 | ||||
| -rw-r--r-- | src/tools/irm/irm_ops.h | 3 | ||||
| -rw-r--r-- | src/tools/irm/irm_register.c | 62 | ||||
| -rw-r--r-- | src/tools/irm/irm_unbind_ipcp.c | 32 | ||||
| -rw-r--r-- | src/tools/irm/irm_unregister.c | 61 | ||||
| -rw-r--r-- | src/tools/irm/irm_utils.c | 75 | ||||
| -rw-r--r-- | src/tools/irm/irm_utils.h | 43 | 
16 files changed, 662 insertions, 218 deletions
| diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt index e87bd0a5..ca32e9c7 100644 --- a/src/tools/irm/CMakeLists.txt +++ b/src/tools/irm/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCE_FILES    irm_ipcp_destroy.c    irm_ipcp_bootstrap.c    irm_ipcp_enroll.c +  irm_ipcp_list.c    irm_ipcp_connect.c    irm_ipcp_disconnect.c    irm_unbind_program.c diff --git a/src/tools/irm/irm_bind_ipcp.c b/src/tools/irm/irm_bind_ipcp.c index 2fcacec7..a30b4192 100644 --- a/src/tools/irm/irm_bind_ipcp.c +++ b/src/tools/irm/irm_bind_ipcp.c @@ -45,6 +45,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm bind ipcp <name> name <name>\n"); @@ -53,13 +55,11 @@ static void usage(void)  int do_bind_ipcp(int     argc,                   char ** argv)  { -        char * ipcp = NULL; -        char * name = NULL; - -        pid_t * pids = NULL; -        ssize_t len  = 0; - -        int i; +        char *             ipcp = NULL; +        char *             name = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -85,12 +85,17 @@ int do_bind_ipcp(int     argc,                  return -1;          } -        len = irm_list_ipcps(ipcp, &pids); - +        len = irm_list_ipcps(&ipcps);          for (i = 0; i < len; ++i) -                irm_bind_process(pids[i], name); +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_bind_process(ipcps[i].pid, name)) { +                                free(ipcps); +                                return -1; +                        } +                        break; +                } -        free(pids); +        free(ipcps);          return 0;  } diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c index a791f6a4..89aa4145 100644 --- a/src/tools/irm/irm_ipcp.c +++ b/src/tools/irm/irm_ipcp.c @@ -68,6 +68,7 @@ static const struct cmd {          { "enroll",     do_enroll_ipcp },          { "connect",    do_connect_ipcp },          { "disconnect", do_disconnect_ipcp }, +        { "list",       do_list_ipcp},          { "help",       do_help },          { NULL,         NULL }  }; diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 4eeedbd3..07dcea0f 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -36,6 +36,12 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +#include <ouroboros/irm.h> + +#include "irm_ops.h" +#include "irm_utils.h" + +#include <assert.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> @@ -43,10 +49,6 @@  #ifdef __FreeBSD__  #include <sys/socket.h>  #endif -#include <ouroboros/irm.h> - -#include "irm_ops.h" -#include "irm_utils.h"  #define NORMAL                 "normal"  #define UDP                    "udp" @@ -83,7 +85,7 @@ static void usage(void)          printf("Usage: irm ipcp bootstrap\n"                 "                name <ipcp name>\n"                 "                layer <layer name>\n" -               "                type [TYPE]\n" +               "                [type [TYPE]]\n"                 "where TYPE = {" NORMAL " " LOCAL " "                 UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "},\n\n"                 "if TYPE == " NORMAL "\n" @@ -132,8 +134,8 @@ static void usage(void)  int do_bootstrap_ipcp(int     argc,                        char ** argv)  { -        char *             name           = NULL; -        pid_t              pid; +        char *             ipcp           = NULL; +        pid_t              pid            = -1;          struct ipcp_config conf;          uint8_t            addr_size      = DEFAULT_ADDR_SIZE;          uint8_t            eid_size       = DEFAULT_EID_SIZE; @@ -145,10 +147,11 @@ int do_bootstrap_ipcp(int     argc,          uint32_t           ip_addr        = 0;          uint32_t           dns_addr       = DEFAULT_DDNS;          char *             ipcp_type      = NULL; -        char *             layer_name     = NULL; +        enum ipcp_type     type; +        char *             layer          = NULL;          char *             dev            = NULL;          uint16_t           ethertype      = DEFAULT_ETHERTYPE; -        pid_t *            pids           = NULL; +        struct ipcp_info * ipcps;          ssize_t            len            = 0;          int                i              = 0;          bool               autobind       = false; @@ -159,9 +162,9 @@ int do_bootstrap_ipcp(int     argc,                  if (matches(*argv, "type") == 0) {                          ipcp_type = *(argv + 1);                  } else if (matches(*argv, "layer") == 0) { -                        layer_name = *(argv + 1); +                        layer = *(argv + 1);                  } else if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "hash") == 0) {                          if (strcmp(*(argv + 1), SHA3_224) == 0)                                  hash_algo = DIR_HASH_SHA3_224; @@ -231,98 +234,133 @@ int do_bootstrap_ipcp(int     argc,                  argv += cargs;          } -        if (name == NULL || layer_name == NULL || ipcp_type == NULL) { +        if (ipcp == NULL || layer == NULL) {                  usage();                  return -1;          } -        strcpy(conf.layer_info.layer_name, layer_name); -        if (strcmp(ipcp_type, UDP) != 0) -                conf.layer_info.dir_hash_algo = hash_algo; - -        if (strcmp(ipcp_type, NORMAL) == 0) { -                conf.type           = IPCP_NORMAL; -                conf.addr_size      = addr_size; -                conf.eid_size       = eid_size; -                conf.max_ttl        = max_ttl; -                conf.addr_auth_type = addr_auth_type; -                conf.routing_type   = routing_type; -                conf.pff_type       = pff_type; -        } else if (strcmp(ipcp_type, UDP) == 0) { -                conf.type = IPCP_UDP; -                if (ip_addr == 0) { -                        usage(); -                        return -1; -                } -                conf.ip_addr = ip_addr; -                conf.dns_addr = dns_addr; -        } else if (strcmp(ipcp_type, LOCAL) == 0) { -                conf.type = IPCP_LOCAL; -        } else if (strcmp(ipcp_type, RAPTOR) == 0) { -                conf.type = IPCP_RAPTOR; -        } else if (strcmp(ipcp_type, ETH_LLC) == 0) { -                conf.type = IPCP_ETH_LLC; -                if (dev == NULL) { -                        usage(); -                        return -1; -                } -                conf.dev = dev; -        } else if (strcmp(ipcp_type, ETH_DIX) == 0) { -                conf.type = IPCP_ETH_DIX; -                if (dev == NULL) { -                        usage(); -                        return -1; +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) { +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        break;                  } -                conf.dev = dev; -                conf.ethertype = ethertype; -        } else { -                usage(); -                return -1;          } -        if (autobind && conf.type != IPCP_NORMAL) { -                printf("Can only bind normal IPCPs, autobind disabled.\n"); -                autobind = false; -        } +        if (pid == -1) { +                if (ipcp_type == NULL) { +                        printf("No IPCPs matching %s found.\n\n", ipcp); +                        goto fail; +                } else { +                        if (strcmp(ipcp_type, NORMAL) == 0) +                                type = IPCP_NORMAL; +                        else if (strcmp(ipcp_type, UDP) == 0) +                                type = IPCP_UDP; +                        else if (strcmp(ipcp_type, ETH_LLC) == 0) +                                type = IPCP_ETH_LLC; +                        else if (strcmp(ipcp_type, ETH_DIX) == 0) +                                type = IPCP_ETH_DIX; +                        else if (strcmp(ipcp_type, LOCAL) == 0) +                                type = IPCP_LOCAL; +                        else if (strcmp(ipcp_type, RAPTOR) == 0) +                                type = IPCP_RAPTOR; +                        else goto fail_usage; +                } -        len = irm_list_ipcps(name, &pids); -        if (len <= 0) { -                pid = irm_create_ipcp(name, conf.type); -                if (pid <= 0) -                        return -1; -                len = irm_list_ipcps(name, &pids); +                pid = irm_create_ipcp(ipcp, type); +                if (pid < 0) +                        goto fail; +                free(ipcps); +                len = irm_list_ipcps(&ipcps);          }          for (i = 0; i < len; i++) { -                if (autobind && irm_bind_process(pids[i], name)) { -                        printf("Failed to bind %d to %s.\n", pids[i], name); -                        free(pids); -                        return -1; -                } +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        if (ipcp_type != NULL && type != ipcps[i].type) { +                                printf("Types do not match.\n\n"); +                                goto fail; +                        } +                        conf.type = ipcps[i].type; -                if (autobind && irm_bind_process(pids[i], layer_name)) { -                        printf("Failed to bind %d to %s.\n", -                               pids[i], layer_name); -                        irm_unbind_process(pids[i], name); -                        free(pids); -                        return -1; -                } +                        if (autobind && conf.type != IPCP_NORMAL) { +                                printf("Can only bind normal IPCPs, " +                                       "autobind disabled.\n"); +                                autobind = false; +                        } + +                        strcpy(conf.layer_info.layer_name, layer); +                        if (conf.type == IPCP_UDP) +                                conf.layer_info.dir_hash_algo = hash_algo; -                if (irm_bootstrap_ipcp(pids[i], &conf)) { -                        if (autobind) { -                                irm_unbind_process(pids[i], name); -                                irm_unbind_process(pids[i], layer_name); +                        switch (conf.type) { +                        case IPCP_NORMAL: +                                conf.addr_size      = addr_size; +                                conf.eid_size       = eid_size; +                                conf.max_ttl        = max_ttl; +                                conf.addr_auth_type = addr_auth_type; +                                conf.routing_type   = routing_type; +                                conf.pff_type       = pff_type; +                                break; +                        case IPCP_UDP: +                                if (ip_addr == 0) +                                        goto fail_usage; +                                conf.ip_addr = ip_addr; +                                conf.dns_addr = dns_addr; +                                break; +                        case IPCP_ETH_LLC: +                                if (dev == NULL) +                                        goto fail_usage; +                                conf.dev = dev; +                                break; +                        case IPCP_ETH_DIX: +                                if (dev == NULL) +                                        goto fail_usage; +                                conf.dev = dev; +                                conf.ethertype = ethertype; +                                break; +                        case IPCP_LOCAL: +                                /* FALLTHRU */ +                        case IPCP_RAPTOR: +                                break; +                        default: +                                assert(false); +                                break; +                        } + +                        if (autobind && irm_bind_process(pid, ipcp)) { +                                printf("Failed to bind %d to %s.\n", pid, ipcp); +                                goto fail; +                        } + +                        if (autobind && irm_bind_process(pid, layer)) { +                                printf("Failed to bind %d to %s.\n", +                                       pid, layer); +                                irm_unbind_process(pid, ipcp); +                                goto fail; +                        } + +                        if (irm_bootstrap_ipcp(pid, &conf)) { +                                if (autobind) { +                                        irm_unbind_process(pid, ipcp); +                                        irm_unbind_process(pid, layer); +                                } +                                goto fail;                          } -                        free(pids); -                        return -1;                  }          } -        free(pids); +        free(ipcps);          return 0;   unknown_param:          printf("Unknown parameter for %s: \"%s\".\n", *argv, *(argv + 1));          return -1; + + fail_usage: +        usage(); + fail: +        free(ipcps); +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_connect.c b/src/tools/irm/irm_ipcp_connect.c index b9cad57d..42c07354 100644 --- a/src/tools/irm/irm_ipcp_connect.c +++ b/src/tools/irm/irm_ipcp_connect.c @@ -60,19 +60,21 @@ static void usage(void)  int do_connect_ipcp(int     argc,                      char ** argv)  { -        char *  name      = NULL; -        char *  dst_name  = NULL; -        char *  comp_name = NULL; -        pid_t * pids      = NULL; -        ssize_t len       = 0; +        char *             ipcp = NULL; +        char *             dst  = NULL; +        char *             comp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len  = 0; +        pid_t              pid  = -1; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "dst") == 0) { -                        dst_name = *(argv + 1); +                        dst = *(argv + 1);                  } else if (matches(*argv, "component") == 0) { -                        comp_name = *(argv + 1); +                        comp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcpi connect\".\n", *argv); @@ -83,28 +85,29 @@ int do_connect_ipcp(int     argc,                  argv += 2;          } -        if (name == NULL || dst_name == NULL || comp_name == NULL) { +        if (ipcp == NULL || dst == NULL || comp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len != 1) +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (strcmp(ipcps[i].name, ipcp) == 0) +                        pid = ipcps[i].pid; + +        free(ipcps); + +        if (pid == -1)                  return -1; -        if (!strcmp(comp_name, DT)) -                comp_name = DT_COMP; +        if (!strcmp(comp, DT)) +                comp = DT_COMP; -        if (!strcmp(comp_name , MGMT)) -                comp_name = MGMT_COMP; +        if (!strcmp(comp , MGMT)) +                comp = MGMT_COMP; -        if (irm_connect_ipcp(pids[0], dst_name, comp_name)) { -                free(pids); +        if (irm_connect_ipcp(pid, dst, comp))                  return -1; -        } - -        if (pids != NULL) -                free(pids);          return 0;  } diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c index 6da853ba..c8866962 100644 --- a/src/tools/irm/irm_ipcp_create.c +++ b/src/tools/irm/irm_ipcp_create.c @@ -47,6 +47,7 @@  #define NORMAL  "normal"  #define UDP     "udp"  #define ETH_LLC "eth-llc" +#define ETH_DIX "eth-dix"  #define LOCAL   "local"  #define RAPTOR  "raptor" @@ -59,7 +60,8 @@ static void usage(void)                 UDP " " ETH_LLC " " RAPTOR "}\n");  } -int do_create_ipcp(int argc, char ** argv) +int do_create_ipcp(int     argc, +                   char ** argv)  {          char * ipcp_type = NULL;          char * ipcp_name = NULL; @@ -94,6 +96,8 @@ int do_create_ipcp(int argc, char ** argv)                  type = IPCP_LOCAL;          else if (strcmp(ipcp_type, ETH_LLC) == 0)                  type = IPCP_ETH_LLC; +        else if (strcmp(ipcp_type, ETH_DIX) == 0) +                type = IPCP_ETH_DIX;          else if (strcmp(ipcp_type, RAPTOR) == 0)                  type = IPCP_RAPTOR;          else { @@ -102,7 +106,7 @@ int do_create_ipcp(int argc, char ** argv)          }          pid = irm_create_ipcp(ipcp_name, type); -        if (pid == 0) +        if (pid <= 0)                  return -1;          return 0; diff --git a/src/tools/irm/irm_ipcp_destroy.c b/src/tools/irm/irm_ipcp_destroy.c index 4c37f52b..cb86b167 100644 --- a/src/tools/irm/irm_ipcp_destroy.c +++ b/src/tools/irm/irm_ipcp_destroy.c @@ -44,22 +44,25 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm ipcp destroy\n"                 "                name <ipcp name>\n");  } -int do_destroy_ipcp(int argc, char ** argv) +int do_destroy_ipcp(int     argc, +                    char ** argv)  { -        char *  name = NULL; -        pid_t * pids; -        ssize_t len = 0; -        int     i = 0; +        char *             ipcp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        int                i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcp destroy\".\n", *argv); @@ -70,20 +73,26 @@ int do_destroy_ipcp(int argc, char ** argv)                  argv += 2;          } -        if (name == NULL) { +        if (ipcp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); +        len = irm_list_ipcps(&ipcps);          if (len <= 0) -                return -1; +                goto fail;          for (i = 0; i < len; i++) -                if (irm_destroy_ipcp(pids[i])) -                        return -1; +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_destroy_ipcp(ipcps[i].pid)) +                                goto fail_destroy; +                        break; +                } -        free(pids);          return 0; + fail_destroy: +        free(ipcps); + fail: +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_disconnect.c b/src/tools/irm/irm_ipcp_disconnect.c index 8b5eb596..73f1588d 100644 --- a/src/tools/irm/irm_ipcp_disconnect.c +++ b/src/tools/irm/irm_ipcp_disconnect.c @@ -60,19 +60,21 @@ static void usage(void)  int do_disconnect_ipcp(int     argc,                         char ** argv)  { -        char *  name      = NULL; -        char *  dst_name  = NULL; -        char *  comp_name = NULL; -        pid_t * pids      = NULL; -        ssize_t len       = 0; +        char *             ipcp = NULL; +        char *             dst  = NULL; +        char *             comp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len  = 0; +        pid_t              pid  = -1; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "dst") == 0) { -                        dst_name = *(argv + 1); +                        dst = *(argv + 1);                  } else if (matches(*argv, "component") == 0) { -                        comp_name = *(argv + 1); +                        comp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcpi connect\".\n", *argv); @@ -83,28 +85,29 @@ int do_disconnect_ipcp(int     argc,                  argv += 2;          } -        if (name == NULL || dst_name == NULL || comp_name == NULL) { +        if (ipcp == NULL || dst == NULL || comp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len != 1) +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (strcmp(ipcps[i].name, ipcp) == 0) +                        pid = ipcps[i].pid; + +        free(ipcps); + +        if (pid == -1)                  return -1; -        if (!strcmp(comp_name, DT)) -                comp_name = DT_COMP; +        if (!strcmp(comp, DT)) +                comp = DT_COMP; -        if (!strcmp(comp_name , MGMT)) -                comp_name = MGMT_COMP; +        if (!strcmp(comp , MGMT)) +                comp = MGMT_COMP; -        if (irm_disconnect_ipcp(pids[0], dst_name, comp_name)) { -                free(pids); +        if (irm_disconnect_ipcp(pid, dst, comp))                  return -1; -        } - -        if (pids != NULL) -                free(pids);          return 0;  } diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c index 8b897096..c1628af6 100644 --- a/src/tools/irm/irm_ipcp_enroll.c +++ b/src/tools/irm/irm_ipcp_enroll.c @@ -44,6 +44,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm ipcp enroll\n" @@ -52,23 +54,24 @@ static void usage(void)                 "                [autobind]\n");  } -int do_enroll_ipcp(int argc, char ** argv) +int do_enroll_ipcp(int     argc, +                   char ** argv)  { -        char *  name       = NULL; -        char *  layer_name = NULL; -        pid_t * pids       = NULL; -        pid_t   pid; -        ssize_t len        = 0; -        int     i          = 0; -        bool    autobind   = false; -        int     cargs; +        char *             ipcp     = NULL; +        char *             layer    = NULL; +        struct ipcp_info * ipcps; +        pid_t              pid      = -1; +        ssize_t            len      = 0; +        int                i        = 0; +        bool               autobind = false; +        int                cargs;          while (argc > 0) {                  cargs = 2;                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "layer") == 0) { -                        layer_name = *(argv + 1); +                        layer = *(argv + 1);                  } else if (matches(*argv, "autobind") == 0) {                          autobind = true;                          cargs = 1; @@ -82,42 +85,53 @@ int do_enroll_ipcp(int argc, char ** argv)                  argv += cargs;          } -        if (layer_name == NULL || name == NULL) { +        if (layer == NULL || ipcp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len <= 0) { -                pid = irm_create_ipcp(name, IPCP_NORMAL); -                if (pid == 0) -                        return -1; -                len = irm_list_ipcps(name, &pids); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (wildcard_match(ipcps[i].name, ipcp) == 0 && +                    ipcps[i].type == IPCP_NORMAL) +                        pid = ipcps[i].pid; + +        if (pid < 0) { +                pid = irm_create_ipcp(ipcp, IPCP_NORMAL); +                if (pid < 0) +                        goto fail; +                free(ipcps); +                len = irm_list_ipcps(&ipcps);          }          for (i = 0; i < len; i++) { -                if (autobind && irm_bind_process(pids[i], name)) { -                        free(pids); -                        return -1; -                } +                if (ipcps[i].type != IPCP_NORMAL) +                        continue; +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        if (autobind && irm_bind_process(pid, ipcp)) { +                                printf("Failed to bind %d to %s.\n", pid, ipcp); +                                goto fail; +                        } -                if (irm_enroll_ipcp(pids[i], layer_name)) { -                        if (autobind) -                                irm_unbind_process(pids[i], name); -                        free(pids); -                        return -1; -                } +                        if (irm_enroll_ipcp(pid, layer)) { +                                if (autobind) +                                        irm_unbind_process(pid, ipcp); +                                goto fail; +                        } -                if (autobind && irm_bind_process(pids[i], layer_name)) { -                        printf("Failed to bind %d to %s.\n", -                               pids[i], layer_name); -                        free(pids); -                        return -1; +                        if (autobind && irm_bind_process(pid, layer)) { +                                printf("Failed to bind %d to %s.\n", pid, layer); +                                goto fail; +                        }                  }          } -        if (pids != NULL) -                free(pids); +        free(ipcps);          return 0; + + fail: +        free(ipcps); +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_list.c b/src/tools/irm/irm_ipcp_list.c new file mode 100644 index 00000000..e16ca523 --- /dev/null +++ b/src/tools/irm/irm_ipcp_list.c @@ -0,0 +1,158 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2018 + * + * Create IPC Processes + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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. + */ + +#include <ouroboros/irm.h> + +#include "irm_ops.h" +#include "irm_utils.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NORMAL  "normal" +#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 list\n" +               "                [name  <ipcp name>]\n" +               "                [layer <layer_name>]\n\n" +               "                [type [TYPE]]\n\n" +               "where TYPE = {" NORMAL " " LOCAL " " +               UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "}\n"); +} + +static char * str_type(enum ipcp_type type) +{ +        switch(type) { +        case IPCP_NORMAL: +                return NORMAL; +        case IPCP_ETH_LLC: +                return ETH_LLC; +        case IPCP_ETH_DIX: +                return ETH_DIX; +        case IPCP_UDP: +                return UDP; +        case IPCP_RAPTOR: +                return RAPTOR; +        case IPCP_LOCAL: +                return LOCAL; +        default: +                return "UNKNOWN"; +        } +}; + +int do_list_ipcp(int     argc, +                 char ** argv) +{ +        char *             ipcp_type = NULL; +        char *             ipcp_name = NULL; +        enum ipcp_type     type      = -1; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i; + +        while (argc > 0) { +                if (matches(*argv, "type") == 0) { +                        ipcp_type = *(argv + 1); +                } else if (matches(*argv, "name") == 0) { +                        ipcp_name = *(argv + 1); +                } else { +                        printf("\"%s\" is unknown, try \"irm " +                               "ipcp list\".\n", *argv); +                        return -1; +                } + +                argc -= 2; +                argv += 2; +        } + +        if (ipcp_type != NULL) { +                if (strcmp(ipcp_type, NORMAL) == 0) +                        type = IPCP_NORMAL; +                else if (strcmp(ipcp_type, UDP) == 0) +                        type = IPCP_UDP; +                else if (strcmp(ipcp_type, LOCAL) == 0) +                        type = IPCP_LOCAL; +                else if (strcmp(ipcp_type, ETH_LLC) == 0) +                        type = IPCP_ETH_LLC; +                else if (strcmp(ipcp_type, ETH_DIX) == 0) +                        type = IPCP_ETH_DIX; +                else if (strcmp(ipcp_type, RAPTOR) == 0) +                        type = IPCP_RAPTOR; +                else { +                        usage(); +                        return -1; +                } +        } + +        len = irm_list_ipcps(&ipcps); +        if (len == 0) { +                printf("No IPCPs in system.\n\n"); +                return 0; +        } + +        /* FIXME: Implement filtering based on type and name. */ +        (void) type; +        (void) ipcp_name; + +        printf("+---------+----------------------+------------+" +               "----------------------+\n"); +        printf("| %7s | %20s | %10s | %20s |\n", "pid", "name", "type", "layer"); +        printf("+---------+----------------------+------------+" +               "----------------------+\n"); + +        for (i = 0; i < len; i++) +                printf("| %7d | %20s | %10s | %20s |\n", +                       ipcps[i].pid, +                       ipcps[i].name, +                       str_type(ipcps[i].type), +                       ipcps[i].layer); + +        printf("+---------+----------------------+------------+" +               "----------------------+\n\n"); + +        free(ipcps); + +        return 0; +} diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h index a2cb5399..74035434 100644 --- a/src/tools/irm/irm_ops.h +++ b/src/tools/irm/irm_ops.h @@ -57,6 +57,9 @@ int do_connect_ipcp(int     argc,  int do_disconnect_ipcp(int     argc,                         char ** argv); +int do_list_ipcp(int     argc, +                 char ** argv); +  int bind_cmd(int     argc,               char ** argv); diff --git a/src/tools/irm/irm_register.c b/src/tools/irm/irm_register.c index 574c2224..59d65a69 100644 --- a/src/tools/irm/irm_register.c +++ b/src/tools/irm/irm_register.c @@ -38,29 +38,42 @@  #include <ouroboros/irm.h> -#include <stdio.h>  #include "irm_ops.h"  #include "irm_utils.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define MAX_IPCPS  128  #define MAX_LAYERS 128  static void usage(void)  {          printf("Usage: irm register\n"                 "           name <name>\n" +               "           ipcp <ipcp to register with>\n" +               "           [ipcp <ipcp to register with>]\n" +               "           [... (maximum %d ipcps)]\n"                 "           layer <layer to register with>\n"                 "           [layer <layer to register with>]\n"                 "           [... (maximum %d layers)]\n" -               , MAX_LAYERS); +               , MAX_IPCPS, MAX_LAYERS);  } -int do_register(int argc, char ** argv) +int do_register(int     argc, +                char ** argv)  { -        char * name = NULL; -        char * layers[MAX_LAYERS]; -        size_t layers_len = 0; +        char *             name       = NULL; +        char *             layers[MAX_LAYERS]; +        size_t             layers_len = 0; +        char *             ipcp[MAX_IPCPS]; +        size_t             ipcp_len   = 0; +        struct ipcp_info * ipcps; +        size_t             len; +        size_t             i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -68,7 +81,13 @@ int do_register(int argc, char ** argv)                  } else if (matches(*argv, "layer") == 0) {                          layers[layers_len++] = *(argv + 1);                          if (layers_len > MAX_LAYERS) { -                                printf("Too many layers specified\n"); +                                printf("Too many layers specified.\n"); +                                return -1; +                        } +                } else if (matches(*argv, "ipcp") == 0) { +                        ipcp[ipcp_len++] = *(argv + 1); +                        if (ipcp_len > MAX_IPCPS) { +                                printf("Too many IPCPs specified.\n");                                  return -1;                          }                  } else { @@ -81,10 +100,35 @@ int do_register(int argc, char ** argv)                  argv += 2;          } -        if (layers_len < 1 || name == NULL) { +        if ((layers_len < 1 && ipcp_len < 1) || name == NULL) {                  usage();                  return -1;          } -        return irm_reg(name, layers, layers_len); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; ++i) { +                size_t j; +                for (j = 0; j < layers_len; j++) { +                        if (wildcard_match(ipcps[i].layer, layers[j]) == 0) { +                                if (irm_reg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +                for (j = 0; j < ipcp_len; j++) { +                        if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) { +                                if (irm_reg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +        } + +        free(ipcps); + +        return 0;  } diff --git a/src/tools/irm/irm_unbind_ipcp.c b/src/tools/irm/irm_unbind_ipcp.c index f804da90..9b2a930a 100644 --- a/src/tools/irm/irm_unbind_ipcp.c +++ b/src/tools/irm/irm_unbind_ipcp.c @@ -45,6 +45,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm unbind ipcp <name>\n" @@ -52,15 +54,14 @@ static void usage(void)                 "\n");  } -int do_unbind_ipcp(int argc, char ** argv) +int do_unbind_ipcp(int     argc, +                   char ** argv)  { -        char * ipcp = NULL; -        char * name = NULL; - -        pid_t * pids = NULL; -        ssize_t len  = 0; - -        int i; +        char *             ipcp = NULL; +        char *             name = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -81,17 +82,22 @@ int do_unbind_ipcp(int argc, char ** argv)                  --argc;          } -        if (ipcp == NULL) { +        if (ipcp == NULL || name  == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(ipcp, &pids); - +        len = irm_list_ipcps(&ipcps);          for (i = 0; i < len; ++i) -                irm_unbind_process(pids[i], name); +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_unbind_process(ipcps[i].pid, name)) { +                                free(ipcps); +                                return -1; +                        } +                        break; +                } -        free(pids); +        free(ipcps);          return 0;  } diff --git a/src/tools/irm/irm_unregister.c b/src/tools/irm/irm_unregister.c index 3b161169..52491b42 100644 --- a/src/tools/irm/irm_unregister.c +++ b/src/tools/irm/irm_unregister.c @@ -36,31 +36,41 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ -#include <stdio.h> -#include <string.h> -  #include <ouroboros/irm.h>  #include "irm_ops.h"  #include "irm_utils.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define MAX_IPCPS  128  #define MAX_LAYERS 128  static void usage(void)  {          printf("Usage: irm unregister\n"                 "           name <name>\n" +               "           ipcp <ipcp to register with>\n" +               "           [ipcp <ipcp to register with>]\n" +               "           [... (maximum %d ipcps)]\n"                 "           layer <layer to unregister from>\n"                 "           [layer <layer to unregister from>]\n"                 "           [... (maximum %d layers)]\n" -               , MAX_LAYERS); +               , MAX_IPCPS, MAX_LAYERS);  }  int do_unregister(int argc, char ** argv)  { -        char * layers[MAX_LAYERS]; -        size_t layers_len = 0; -        char * name = NULL; +        char *             name       = NULL; +        char *             layers[MAX_LAYERS]; +        size_t             layers_len = 0; +        char *             ipcp[MAX_IPCPS]; +        size_t             ipcp_len   = 0; +        struct ipcp_info * ipcps; +        size_t             len; +        size_t             i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -68,7 +78,13 @@ int do_unregister(int argc, char ** argv)                  } else if (matches(*argv, "layer") == 0) {                          layers[layers_len++] = *(argv + 1);                          if (layers_len > MAX_LAYERS) { -                                printf("Too many layers specified\n"); +                                printf("Too many layers specified.\n"); +                                return -1; +                        } +                } else if (matches(*argv, "ipcp") == 0) { +                        ipcp[ipcp_len++] = *(argv + 1); +                        if (ipcp_len > MAX_IPCPS) { +                                printf("Too many IPCPs specified.\n");                                  return -1;                          }                  } else { @@ -81,10 +97,35 @@ int do_unregister(int argc, char ** argv)                  argv += 2;          } -        if (layers_len == 0 || name == NULL) { +        if ((layers_len < 1 && ipcp_len < 1) || name == NULL) {                  usage();                  return -1;          } -        return irm_unreg(name, layers, layers_len); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; ++i) { +                size_t j; +                for (j = 0; j < layers_len; j++) { +                        if (wildcard_match(ipcps[i].layer, layers[j]) == 0) { +                                if (irm_unreg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +                for (j = 0; j < ipcp_len; j++) { +                        if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) { +                                if (irm_unreg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +        } + +        free(ipcps); + +        return 0;  } diff --git a/src/tools/irm/irm_utils.c b/src/tools/irm/irm_utils.c index 573eab70..c5ea9246 100644 --- a/src/tools/irm/irm_utils.c +++ b/src/tools/irm/irm_utils.c @@ -36,9 +36,48 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +/* + * Copyright (c) 1989, 1993, 1994 + *      The Regents of the University of California.  All rights reserved. + * + * Wildcard Match code below is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * wildcard_match is based on the fnmatch function from POSIX.2. + * Implementation based on that one from FreeBSD. + */ + +  #include <string.h> -#include <stdbool.h> -#include <stdlib.h>  #include "irm_utils.h" @@ -52,3 +91,35 @@ int matches(const char * cmd,          return memcmp(pattern, cmd, len);  } + +int wildcard_match(const char * pattern, +                   const char * string) +{ +        char c; + +        /* For loop? Why not Zoidberg? */ +        for (;;) { +                switch (c = *pattern++) { +                case '\0': +                        return (*string == '\0' ? 0 : -1); +                case '*': +                        c = *pattern; + +                        if (c == '\0') +                                return 0; + +                        /* General case, use recursion. */ +                        while ((c = *string) != '\0') { +                                if (!wildcard_match(pattern, string)) +                                        return 0; +                                ++string; +                        } +                        return -1; +                default: +                        if (c != *string) +                                return -1; +                        string++; +                        break; +                } +        } +} diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h index 9f24c4b7..03113f12 100644 --- a/src/tools/irm/irm_utils.h +++ b/src/tools/irm/irm_utils.h @@ -36,10 +36,53 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +/* + * Copyright (c) 1989, 1993, 1994 + *      The Regents of the University of California.  All rights reserved. + * + * Wildcard Match code below is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * wildcard_match is based on the fnmatch function from POSIX.2. + * Implementation based on that one from FreeBSD. + */ +  #ifndef OUROBOROS_TOOLS_IRM_UTILS_H  #define OUROBOROS_TOOLS_IRM_UTILS_H  int matches(const char * cmd,              const char * pattern); +int wildcard_match(const char * pattern, +                   const char * string); +  #endif /* OUROBOROS_TOOLS_IRM_UTILS_H */ | 
