diff --git a/client/Makefile.am b/client/Makefile.am
index 357067ba6..3fb8f5197 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -53,6 +53,8 @@ endif
wicked_SOURCES = \
arputil.c \
compat.c \
+ duid.c \
+ iaid.c \
ifup.c \
ifdown.c \
ifcheck.c \
@@ -65,14 +67,13 @@ wicked_SOURCES = \
tester.c
noinst_HEADERS = \
- arputil.h \
ifup.h \
ifdown.h \
ifcheck.h \
ifreload.h \
ifstatus.h \
+ main.h \
reachable.h \
- tester.h \
wicked-client.h
install-data-local:
diff --git a/client/arputil.h b/client/arputil.h
deleted file mode 100644
index 17608dfc9..000000000
--- a/client/arputil.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * wicked client arp actions and utilities
- *
- * Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see or write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Marius Tomaschewski
- *
- */
-#ifndef __WICKED_CLIENT_ARPUTIL_H__
-#define __WICKED_CLIENT_ARPUTIL_H__
-
-extern int ni_do_arp(int argc, char **argv);
-
-#endif /* __WICKED_CLIENT_ARPUTIL_H__ */
diff --git a/client/duid.c b/client/duid.c
new file mode 100644
index 000000000..5bc4f8336
--- /dev/null
+++ b/client/duid.c
@@ -0,0 +1,837 @@
+/*
+ * wicked client main commands
+ *
+ * Copyright (C) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authors:
+ * Marius Tomaschewski
+ * Nirmoy Das
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include "duid.h"
+
+
+static int
+ni_do_duid_dump(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_var_array_t vars = NI_VAR_ARRAY_INIT;
+ ni_duid_map_t *map = NULL;
+ ni_var_t *var;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ if (argc - optind)
+ goto usage;
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_duid_map_load(NULL)))
+ goto cleanup;
+
+ status = NI_WICKED_RC_SUCCESS;
+ if (ni_duid_map_to_vars(map, &vars)) {
+ unsigned int i;
+
+ for (i = 0, var = vars.data; i < vars.count; ++i, ++var) {
+ printf("%s\t%s\n", var->name ? var->name : "default", var->value);
+ }
+ ni_var_array_destroy(&vars);
+ }
+
+cleanup:
+ ni_duid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_duid_get(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_duid_map_t *map = NULL;
+ const char *scope = NULL;
+ const char *duid = NULL;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope show device specific duid instead of default\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ if (argc - optind)
+ goto usage;
+
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_duid_map_load(NULL)))
+ goto cleanup;
+
+ status = NI_WICKED_RC_NO_DEVICE;
+ if (ni_duid_map_get_duid(map, scope, &duid, NULL)) {
+ printf("%s\t%s\n", scope ? scope : "default", duid);
+ status = NI_WICKED_RC_SUCCESS;
+ } else
+ if (scope && ni_duid_map_get_duid(map, NULL, &duid, NULL)) {
+ printf("%s\t%s\n", "default", duid);
+ status = NI_WICKED_RC_SUCCESS;
+ }
+
+cleanup:
+ ni_duid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_duid_del(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_duid_map_t *map = NULL;
+ const char *scope = NULL;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope delete device specific duid instead of default\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ if (argc - optind)
+ goto usage;
+
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_duid_map_load(NULL)))
+ goto cleanup;
+
+ if (ni_duid_map_del(map, scope)) {
+ if (ni_duid_map_save(map))
+ status = NI_WICKED_RC_SUCCESS;
+ }
+
+cleanup:
+ ni_duid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_duid_set(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_duid_map_t *map = NULL;
+ const char *scope = NULL;
+ const char *duid = NULL;
+ ni_opaque_t raw;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope set device specific duid instead of default\n"
+ "\n"
+ "Arguments:\n"
+ " duid duid string as colon-separated hex bytes\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 1:
+ duid = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+ if (ni_string_empty(duid) || !ni_duid_parse_hex(&raw, duid)) {
+ fprintf(stderr, "%s: unable to parse duid hex string argument\n", argv[0]);
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_duid_map_load(NULL)))
+ goto cleanup;
+
+ if (!ni_duid_map_set(map, scope, duid))
+ goto cleanup;
+
+ if (!ni_duid_map_save(map))
+ goto cleanup;
+
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ ni_duid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_duid_create_update(const char *scope, const char *duid)
+{
+ int status = NI_WICKED_RC_ERROR;
+ ni_duid_map_t *map = NULL;
+
+ if (!(map = ni_duid_map_load(NULL)))
+ goto cleanup;
+
+ if (!ni_duid_map_set(map, scope, duid))
+ goto cleanup;
+
+ if (!ni_duid_map_save(map))
+ goto cleanup;
+
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ ni_duid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_duid_create_en(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's', OPT_UPDATE = 'u' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { "update", no_argument, NULL, OPT_UPDATE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ const char *scope = NULL;
+ ni_bool_t update = FALSE;
+ const char *en = NULL;
+ const char *id = NULL;
+ const char *hex = NULL;
+ ni_opaque_t raw;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:u", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_UPDATE:
+ update = TRUE;
+ break;
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope create device specific duid instead of default\n"
+ " --update create a duid and update duid map file\n"
+ "\n"
+ "Arguments:\n"
+ " enterprise-number IANA assigned 32bit enterprise number\n"
+ " machine-identifier machine identifier as colon-separated hex bytes\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 2:
+ en = argv[optind++];
+ id = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ goto cleanup;
+ }
+
+ if (!ni_duid_create_en(&raw, en, id)) {
+ fprintf(stderr, "%s: cannot create duid using enterprise-number '%s' and identifier '%s'\n",
+ argv[0], en, id);
+ goto cleanup;
+ }
+
+ hex = raw.len ? ni_duid_print_hex(&raw) : NULL;
+ if (ni_string_empty(hex)) {
+ fprintf(stderr, "%s: cannot format en duid as a colon-separated hex string\n", argv[0]);
+ goto cleanup;
+ }
+
+ if (update) {
+ status = ni_do_duid_create_update(scope, hex);
+ if (status != NI_WICKED_RC_SUCCESS) {
+ fprintf(stderr, "%s: cannot update duid map file using the created duid\n", argv[0]);
+ goto cleanup;
+ }
+ }
+
+ printf("%s\t%s\n", scope ? scope : "default", hex);
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ return status;
+}
+
+static inline void
+ni_do_duid_create_ll_print_hwtypes(FILE *out)
+{
+ const ni_intmap_t *hwtype = ni_duid_hwtype_map();
+ unsigned int alias = -1U;
+
+ fprintf(out, "Supported hardware types are:\n");
+ for (; hwtype && hwtype->name; ++hwtype) {
+ if (alias == hwtype->value)
+ continue;
+ alias = hwtype->value;
+ fprintf(out, " %s\n", hwtype->name);
+ }
+}
+
+static int
+ni_do_duid_create_ll_type(uint16_t type, int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's', OPT_UPDATE = 'u' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { "update", no_argument, NULL, OPT_UPDATE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ const char *scope = NULL;
+ ni_bool_t update = FALSE;
+ const char *ifname = NULL;
+ const char *hwtype = NULL;
+ const char *hwaddr = NULL;
+ const char *hex = NULL;
+ ni_opaque_t raw;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:u", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_UPDATE:
+ update = TRUE;
+ break;
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] [ [ifname] | ]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope create device specific duid instead of default\n"
+ " --update create a duid and update duid map file\n"
+ "\n"
+ "Arguments:\n"
+ " ifname get hardware type and address from interface\n"
+ " htwype hardware type to use in the duid\n"
+ " htaddr hardware address to use in the duid\n"
+ "\n", argv[0]);
+ ni_do_duid_create_ll_print_hwtypes(stderr);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 2:
+ hwtype = argv[optind++];
+ hwaddr = argv[optind++];
+ break;
+ case 1:
+ ifname = argv[optind++];
+ break;
+ case 0:
+ break;
+ default:
+ goto usage;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ goto cleanup;
+ }
+
+ if (hwtype || hwaddr) {
+ switch (type) {
+ case NI_DUID_TYPE_LL:
+ if (ni_duid_create_ll(&raw, hwtype, hwaddr))
+ status = NI_WICKED_RC_SUCCESS;
+ break;
+ case NI_DUID_TYPE_LLT:
+ if (ni_duid_create_llt(&raw, hwtype, hwaddr))
+ status = NI_WICKED_RC_SUCCESS;
+ break;
+ default:
+ break;
+ }
+ if (status != NI_WICKED_RC_SUCCESS) {
+ fprintf(stderr, "%s: cannot create duid using hardware type '%s' and address '%s'\n",
+ argv[0], hwtype, hwaddr);
+ goto cleanup;
+ }
+ } else {
+ ni_netconfig_t *nc = ni_global_state_handle(1);
+ ni_netdev_t *dev = NULL;
+
+ if (!nc) {
+ fprintf(stderr, "%s: cannot retrieve interface properties", argv[0]);
+ goto cleanup;
+ }
+
+ if (ifname) {
+ dev = ni_netdev_by_name(nc, ifname);
+ if (!dev || !ni_duid_create_from_device(&raw, type, dev)) {
+ hwtype = dev ? ni_duid_hwtype_to_name(dev->link.hwaddr.type) : "missing";
+ fprintf(stderr, "%s: unable to create %s duid using %s device '%s'\n",
+ argv[0], ni_duid_type_to_name(type),
+ hwtype ? hwtype : "unsupported", ifname);
+ goto cleanup;
+ }
+ } else {
+ dev = scope ? ni_netdev_by_name(nc, scope) : NULL;
+ if (!ni_duid_create_pref_device(&raw, type, nc, dev)) {
+ fprintf(stderr, "%s: unable to create any %s duid (no usable devices)",
+ argv[0], ni_duid_type_to_name(type));
+ goto cleanup;
+ }
+ }
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ hex = raw.len ? ni_duid_print_hex(&raw) : NULL;
+ if (ni_string_empty(hex)) {
+ fprintf(stderr, "%s: cannot format en duid as a colon-separated hex string\n", argv[0]);
+ goto cleanup;
+ }
+
+ if (update) {
+ status = ni_do_duid_create_update(scope, hex);
+ if (status != NI_WICKED_RC_SUCCESS) {
+ fprintf(stderr, "%s: cannot update duid map file using the created duid\n", argv[0]);
+ goto cleanup;
+ }
+ }
+
+ printf("%s\t%s\n", scope ? scope : "default", hex);
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ return status;
+}
+
+static inline int
+ni_do_duid_create_ll(int argc, char **argv)
+{
+ return ni_do_duid_create_ll_type(NI_DUID_TYPE_LL, argc, argv);
+}
+
+static inline int
+ni_do_duid_create_llt(int argc, char **argv)
+{
+ return ni_do_duid_create_ll_type(NI_DUID_TYPE_LLT, argc, argv);
+}
+
+static int
+ni_do_duid_create_uuid(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_SCOPE = 's', OPT_UPDATE = 'u',
+ OPT_MACHINE_ID = 'm', OPT_PRODUCT_ID = 'p' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "scope", required_argument, NULL, OPT_SCOPE },
+ { "update", no_argument, NULL, OPT_UPDATE },
+ { "machine-id", optional_argument, NULL, OPT_MACHINE_ID },
+ { "product-id", optional_argument, NULL, OPT_PRODUCT_ID },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ const char *scope = NULL;
+ ni_bool_t update = FALSE;
+ unsigned int type = 0;
+ const char *from = NULL;
+ const char *hex = NULL;
+ ni_opaque_t raw;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hs:um::p::", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_MACHINE_ID:
+ type = OPT_MACHINE_ID;
+ from = optarg;
+ break;
+ case OPT_PRODUCT_ID:
+ type = OPT_PRODUCT_ID;
+ from = optarg;
+ break;
+ case OPT_UPDATE:
+ update = TRUE;
+ break;
+ case OPT_SCOPE:
+ if (optarg && !ni_string_eq(optarg, "default"))
+ scope = optarg;
+ break;
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] [uuid]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ " --scope create device specific duid instead of default\n"
+ " --update create a duid and update duid map file\n"
+ " --machine-id[=FILE] import uuid from /etc/machine-id file\n"
+ " --product-id[=FILE] import uuid from dmi product-id sysfs file\n"
+ "\n"
+ "Arguments:\n"
+ " uuid create duid using specified uuid-string\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (type) {
+ case OPT_MACHINE_ID:
+ case OPT_PRODUCT_ID:
+ if ((argc - optind) != 0)
+ goto usage;
+ break;
+ default:
+ if ((argc - optind) != 1)
+ goto usage;
+ from = argv[optind++];
+ break;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (scope && !ni_netdev_name_is_valid(scope)) {
+ fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
+ ni_print_suspect(scope, ni_string_len(scope)));
+ goto cleanup;
+ }
+
+ switch (type) {
+ case OPT_MACHINE_ID:
+ if (!ni_duid_create_uuid_machine_id(&raw, from)) {
+ fprintf(stderr, "%s: cannot create duid by importing uuid from machine-id%s%s",
+ argv[0], from ? " file ": "", from ? from : "");
+ goto cleanup;
+ }
+ break;
+ case OPT_PRODUCT_ID:
+ if (!ni_duid_create_uuid_dmi_product_id(&raw, from)) {
+ fprintf(stderr, "%s: cannot create duid by importing uuid from dmi product-id%s%s",
+ argv[0], from ? " file ": "", from ? from : "");
+ goto cleanup;
+ }
+ break;
+ default:
+ if (!ni_duid_create_uuid_string(&raw, from)) {
+ fprintf(stderr, "%s: cannot create duid by importing uuid string '%s'",
+ argv[0], from);
+ goto cleanup;
+ }
+ break;
+ }
+
+ hex = raw.len ? ni_duid_print_hex(&raw) : NULL;
+ if (ni_string_empty(hex)) {
+ fprintf(stderr, "%s: cannot format en duid as a colon-separated hex string\n", argv[0]);
+ goto cleanup;
+ }
+
+ if (update) {
+ status = ni_do_duid_create_update(scope, hex);
+ if (status != NI_WICKED_RC_SUCCESS) {
+ fprintf(stderr, "%s: cannot update duid map file using the created duid\n", argv[0]);
+ goto cleanup;
+ }
+ }
+
+ printf("%s\t%s\n", scope ? scope : "default", hex);
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ return status;
+}
+
+static int
+ni_do_duid_create(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ const char *type = NULL;
+ char *command = NULL;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] ...\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ if (optind >= argc || ni_string_empty(argv[optind])) {
+ fprintf(stderr, "%s: missing duid type argument\n\n", argv[0]);
+ goto usage;
+ }
+
+ type = argv[optind];
+ ni_string_printf(&command, "%s %s", argv[0], type);
+ argv[optind] = command;
+
+ if (ni_string_eq(type, "ll")) {
+ status = ni_do_duid_create_ll(argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(type, "llt")) {
+ status = ni_do_duid_create_llt(argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(type, "en")) {
+ status = ni_do_duid_create_en(argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(type, "uuid")) {
+ status = ni_do_duid_create_uuid(argc - optind, argv + optind);
+ } else {
+ argv[optind] = (char *)type;
+ fprintf(stderr, "%s: unsupported duid type '%s'\n", argv[0],
+ ni_print_suspect(type, ni_string_len(type)));
+ goto usage;
+ }
+ argv[optind] = (char *)type;
+
+cleanup:
+ ni_string_free(&command);
+ return status;
+}
+
+int
+ni_do_duid(const char *caller, int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ char *program = NULL;
+ char *command = NULL;
+ const char *cmd;
+
+ ni_string_printf(&program, "%s %s", caller ? caller : "wicked",
+ argv[0] ? argv[0] : "duid");
+
+ optind = 1;
+ argv[0] = program;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "\nUsage:\n"
+ " %s [common options] [...]\n"
+ "\n"
+ "Common options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n"
+ "Supported commands:\n"
+ " help show this help text and exit.\n"
+ " dump, show show the duid map contents\n"
+ " get [options] get current duid\n"
+ " del [options] delete current duid\n"
+ " set [options] set/update the duid\n"
+ " create [...] create a new duid\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+
+ if (optind >= argc || ni_string_empty(argv[optind])) {
+ fprintf(stderr, "%s: missing command argument\n", argv[0]);
+ goto usage;
+ }
+
+ cmd = argv[optind];
+ ni_string_printf(&command, "%s %s", program, cmd);
+ argv[optind] = command;
+
+ if (ni_string_eq(cmd, "help")) {
+ argv[optind] = (char *)cmd;
+ status = NI_WICKED_RC_SUCCESS;
+ goto usage;
+ } else
+ if (ni_string_eq(cmd, "dump")) {
+ status = ni_do_duid_dump(argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "get")) {
+ status = ni_do_duid_get (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "set")) {
+ status = ni_do_duid_set (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "del")) {
+ status = ni_do_duid_del (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "create")) {
+ status = ni_do_duid_create (argc - optind, argv + optind);
+ } else {
+ argv[optind] = (char *)cmd;
+ fprintf(stderr, "%s: unsupported command %s\n", program, (char *)cmd);
+ goto usage;
+ }
+ argv[optind] = (char *)cmd;
+
+cleanup:
+ argv[0] = NULL;
+ ni_string_free(&command);
+ ni_string_free(&program);
+ return status;
+}
+
diff --git a/client/iaid.c b/client/iaid.c
new file mode 100644
index 000000000..97d033fdc
--- /dev/null
+++ b/client/iaid.c
@@ -0,0 +1,458 @@
+/*
+ * wicked client iaid commands
+ *
+ * Copyright (C) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authors:
+ * Marius Tomaschewski
+ * Nirmoy Das
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include "iaid.h"
+
+static int
+ni_do_iaid_dump(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_var_array_t vars = NI_VAR_ARRAY_INIT;
+ ni_iaid_map_t *map = NULL;
+ const ni_var_t *var;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ if (argc - optind)
+ goto usage;
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_iaid_map_load(NULL)))
+ goto cleanup;
+
+ status = NI_WICKED_RC_SUCCESS;
+ if (ni_iaid_map_to_vars(map, &vars)) {
+ unsigned int i;
+
+ for (i = 0, var = vars.data; i < vars.count; ++i, ++var) {
+ printf("%s\t%s\n", var->name, var->value);
+ }
+ }
+ ni_var_array_destroy(&vars);
+
+cleanup:
+ ni_iaid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_iaid_get(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_iaid_map_t *map = NULL;
+ const char *ifname = NULL;
+ unsigned int iaid;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 1:
+ ifname = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ if (!ni_netdev_name_is_valid(ifname)) {
+ fprintf(stderr, "%s: invalid interface name '%s'\n", argv[0],
+ ni_print_suspect(ifname, ni_string_len(ifname)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_iaid_map_load(NULL)))
+ goto cleanup;
+
+ status = NI_WICKED_RC_NO_DEVICE;
+ if (ni_iaid_map_get_iaid(map, ifname, &iaid)) {
+ printf("%s\t%u\n", ifname, iaid);
+ status = NI_WICKED_RC_SUCCESS;
+ }
+
+cleanup:
+ ni_iaid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_iaid_del(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_iaid_map_t *map = NULL;
+ const char *ifname = NULL;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 1:
+ ifname = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ if (!ni_netdev_name_is_valid(ifname)) {
+ fprintf(stderr, "%s: invalid interface name '%s'\n", argv[0],
+ ni_print_suspect(ifname, ni_string_len(ifname)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_iaid_map_load(NULL)))
+ goto cleanup;
+
+ status = NI_WICKED_RC_NO_DEVICE;
+ if (ni_iaid_map_del_name(map, ifname)) {
+ if (ni_iaid_map_save(map))
+ status = NI_WICKED_RC_SUCCESS;
+ }
+
+cleanup:
+ ni_iaid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_iaid_set(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_UNIQUE = 'U' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "unique", no_argument, NULL, OPT_UNIQUE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_iaid_map_t *map = NULL;
+ const char *ifname = NULL;
+ const char *ifiaid = NULL;
+ ni_bool_t unique = FALSE;
+ const char *conflict;
+ unsigned int iaid;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hU", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_UNIQUE:
+ unique = TRUE;
+ break;
+
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 2:
+ ifname = argv[optind++];
+ ifiaid = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ if (!ni_netdev_name_is_valid(ifname)) {
+ fprintf(stderr, "%s: invalid interface name '%s'\n", argv[0],
+ ni_print_suspect(ifname, ni_string_len(ifname)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ if (ni_parse_uint(ifiaid, &iaid, 0) != 0) {
+ fprintf(stderr, "%s: unable to parse iaid argument '%s'\n", argv[0],
+ ni_print_suspect(ifiaid, ni_string_len(ifiaid)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ status = NI_WICKED_RC_ERROR;
+ if (!(map = ni_iaid_map_load(NULL)))
+ goto cleanup;
+
+ if (unique && ni_iaid_map_get_name(map, iaid, &conflict)) {
+ fprintf(stderr, "%s: iaid %u in use by '%s'\n", argv[0], iaid, conflict);
+ status = NI_WICKED_RC_NO_DEVICE;
+ goto cleanup;
+ }
+
+ if (ni_iaid_map_set(map, ifname, iaid)) {
+ if (ni_iaid_map_save(map))
+ status = NI_WICKED_RC_SUCCESS;
+ }
+
+ if (status == NI_WICKED_RC_SUCCESS)
+ printf("%s\t%u\n", ifname, iaid);
+
+cleanup:
+ ni_iaid_map_free(map);
+ return status;
+}
+
+static int
+ni_do_iaid_create(int argc, char **argv)
+{
+ enum { OPT_HELP = 'h', OPT_UPDATE = 'u' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { "update", no_argument, NULL, OPT_UPDATE },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ ni_iaid_map_t *map = NULL;
+ const char *ifname = NULL;
+ ni_bool_t update = TRUE;
+ ni_netconfig_t *nc;
+ ni_netdev_t *dev;
+ unsigned int iaid;
+
+ optind = 1;
+ while ((opt = getopt_long(argc, argv, "+hu", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_UPDATE:
+ update = TRUE;
+ break;
+
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "Usage: %s [options] \n"
+ "\n"
+ "Options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+ switch (argc - optind) {
+ case 1:
+ ifname = argv[optind++];
+ break;
+ default:
+ goto usage;
+ }
+
+ if (ni_netdev_name_is_valid(ifname)) {
+ fprintf(stderr, "%s: invalid interface name '%s'\n", argv[0],
+ ni_print_suspect(ifname, ni_string_len(ifname)));
+ status = NI_WICKED_RC_ERROR;
+ goto cleanup;
+ }
+
+ if (!(nc = ni_global_state_handle(1))) {
+ fprintf(stderr, "%s: cannot retrieve interface properties", argv[0]);
+ goto cleanup;
+ }
+
+ if (!(dev = ni_netdev_by_name(nc, ifname))) {
+ fprintf(stderr, "%s: interface %s does not exists\n", argv[0], ifname);
+ goto cleanup;
+ }
+
+ if (!(map = ni_iaid_map_load(NULL)))
+ goto cleanup;
+
+ if (!ni_iaid_create(&iaid, dev, map)) {
+ fprintf(stderr, "%s: cannot create iaid for interface %s\n", argv[0], ifname);
+ goto cleanup;
+ }
+
+ if (update && (!ni_iaid_map_set(map, ifname, iaid) || !ni_iaid_map_save(map))) {
+ fprintf(stderr, "%s: unable to update iaid map file\n", argv[0]);
+ goto cleanup;
+ }
+
+ printf("%s\t%u\n", ifname, iaid);
+ status = NI_WICKED_RC_SUCCESS;
+
+cleanup:
+ ni_iaid_map_free(map);
+ return status;
+}
+
+int
+ni_do_iaid(const char *caller, int argc, char **argv)
+{
+ enum { OPT_HELP = 'h' };
+ static struct option options[] = {
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int opt = 0, status = NI_WICKED_RC_USAGE;
+ char *program = NULL;
+ char *command = NULL;
+ const char *cmd;
+
+ ni_string_printf(&program, "%s %s", caller ? caller : "wicked",
+ argv[0] ? argv[0] : "iaid");
+
+ optind = 1;
+ argv[0] = program;
+ while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
+ switch (opt) {
+ case OPT_HELP:
+ status = NI_WICKED_RC_SUCCESS;
+ default:
+ usage:
+ fprintf(stderr,
+ "\nUsage:\n"
+ " %s [common options] command [...]\n"
+ "\n"
+ "Common options:\n"
+ " --help, -h show this help text and exit.\n"
+ "\n"
+ "Supported Commands:\n"
+ " help show this help text and exit.\n"
+ " dump show the iaid map contents\n"
+ " get get current device iaid\n"
+ " del delete current device iaid\n"
+ " set set/update the device iaid\n"
+ " create create a new device iaid\n"
+ "\n", argv[0]);
+ goto cleanup;
+ }
+ }
+
+ if (optind >= argc || ni_string_empty(argv[optind])) {
+ fprintf(stderr, "%s: missing command\n", program);
+ goto usage;
+ }
+
+ cmd = argv[optind];
+ ni_string_printf(&command, "%s %s", program, cmd);
+ argv[optind] = command;
+
+ if (ni_string_eq(cmd, "help")) {
+ argv[optind] = (char *)cmd;
+ status = NI_WICKED_RC_SUCCESS;
+ goto usage;
+ } else
+ if (ni_string_eq(cmd, "dump")) {
+ status = ni_do_iaid_dump(argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "get")) {
+ status = ni_do_iaid_get (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "del")) {
+ status = ni_do_iaid_del (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "set")) {
+ status = ni_do_iaid_set (argc - optind, argv + optind);
+ } else
+ if (ni_string_eq(cmd, "create")) {
+ status = ni_do_iaid_create (argc - optind, argv + optind);
+ } else {
+ argv[optind] = (char *)cmd;
+ fprintf(stderr, "%s: unsupported command %s\n", program, cmd);
+ goto usage;
+ }
+ argv[optind] = (char *)cmd;
+
+cleanup:
+ argv[0] = NULL;
+ ni_string_free(&command);
+ ni_string_free(&program);
+ return status;
+}
+
diff --git a/client/main.c b/client/main.c
index b57634558..6fd89f7f8 100644
--- a/client/main.c
+++ b/client/main.c
@@ -55,8 +55,7 @@
#include "ifcheck.h"
#include "ifreload.h"
#include "ifstatus.h"
-#include "arputil.h"
-#include "tester.h"
+#include "main.h"
enum {
OPT_HELP,
@@ -180,6 +179,8 @@ main(int argc, char **argv)
" convert [subcommand]\n"
" xpath [options] expr ...\n"
" test [subcommand]\n"
+ " iaid [subcommand]\n"
+ " duid [subcommand]\n"
" arp [options] \n"
"\n", program);
goto done;
@@ -314,11 +315,17 @@ main(int argc, char **argv)
if (!strcmp(cmd, "convert")) {
status = do_convert(argc - optind, argv + optind);
} else
+ if (!strcmp(cmd, "duid")) {
+ status = ni_do_duid(program, argc - optind, argv + optind);
+ } else
+ if (!strcmp(cmd, "iaid")) {
+ status = ni_do_iaid(program, argc - optind, argv + optind);
+ } else
if (!strcmp(cmd, "test")) {
status = ni_do_test(program, argc - optind, argv + optind);
} else
if (!strcmp(cmd, "arp")) {
- status = ni_do_arp(argc - optind, argv + optind);
+ status = ni_do_arp(program, argc - optind, argv + optind);
} else {
fprintf(stderr, "Unsupported command %s\n", cmd);
goto usage;
diff --git a/client/main.h b/client/main.h
new file mode 100644
index 000000000..0d3ac29c9
--- /dev/null
+++ b/client/main.h
@@ -0,0 +1,32 @@
+/*
+ * wicked client main commands
+ *
+ * Copyright (C) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authors:
+ * Marius Tomaschewski
+ * Nirmoy Das
+ *
+ */
+#ifndef WICKED_CLIENT_MAIN_H
+#define WICKED_CLIENT_MAIN_H
+
+extern int ni_do_arp (const char *caller, int argc, char **argv);
+extern int ni_do_test(const char *caller, int argc, char **argv);
+extern int ni_do_duid(const char *caller, int argc, char **argv);
+extern int ni_do_iaid(const char *caller, int argc, char **argv);
+
+#endif /* WICKED_CLIENT_MAIN_H */
diff --git a/client/tester.c b/client/tester.c
index c0f2c4d9b..950603bb1 100644
--- a/client/tester.c
+++ b/client/tester.c
@@ -37,7 +37,6 @@
#include
#include
-#include "tester.h"
#include "dhcp4/tester.h"
#include "dhcp6/tester.h"
#include "netinfo_priv.h"
diff --git a/client/tester.h b/client/tester.h
deleted file mode 100644
index 550d5c3c2..000000000
--- a/client/tester.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * wicked client tester commands
- *
- * Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see or write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Marius Tomaschewski
- *
- */
-#ifndef WICKED_CLIENT_TESTER_H
-#define WICKED_CLIENT_TESTER_H
-
-extern int ni_do_test(const char *caller, int argc, char **argv);
-
-#endif /* WICKED_CLIENT_TESTER_H */