summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2013-09-29 14:27:52 -0700
committerRobert Mustacchi <rm@joyent.com>2013-11-06 08:09:36 -0800
commitfe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1 (patch)
treeb5723fc87b94e5c73aa9c243dc40e6dac6ef5440 /usr/src/cmd
parentc6d054cbc999e5c8b9ad1aa01dbb4800b84f06bd (diff)
downloadillumos-joyent-fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1.tar.gz
4236 Internet Packet Disturber
4237 net_* and hook_* man pages are wrong Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Brendan Gregg <brendan.gregg@joyent.com> Reviewed by: Keith M Wesolowski <wesolows@foobazco.org> Reviewed by: Sebastien Roy <seb@delphix.com> Approved by: Dan McDonald <danmcd@nexenta.com>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/Makefile3
-rw-r--r--usr/src/cmd/devfsadm/misc_link.c4
-rw-r--r--usr/src/cmd/ipdadm/Makefile45
-rw-r--r--usr/src/cmd/ipdadm/ipdadm.c435
4 files changed, 486 insertions, 1 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 1fa2a43e8f..d04b74d498 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -21,7 +21,7 @@
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2010 Nexenta Systems, Inc. All rights reserved.
-# Copyright 2011 Joyent, Inc. All rights reserved.
+# Copyright (c) 2012 Joyent, Inc. All rights reserved.
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved.
@@ -207,6 +207,7 @@ COMMON_SUBDIRS= \
intrstat \
ipcrm \
ipcs \
+ ipdadm \
ipf \
isainfo \
isalist \
diff --git a/usr/src/cmd/devfsadm/misc_link.c b/usr/src/cmd/devfsadm/misc_link.c
index 9465e2c886..b7aef8b00d 100644
--- a/usr/src/cmd/devfsadm/misc_link.c
+++ b/usr/src/cmd/devfsadm/misc_link.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#include <regex.h>
@@ -107,6 +108,9 @@ static devfsadm_create_t misc_cbt[] = {
"(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)",
TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
},
+ { "pseudo", "ddi_pseudo", "ipd",
+ TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
+ },
{ "pseudo", "ddi_pseudo",
"(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|"
"(^ipsync$)|(^ipscan$)|(^iplookup$)",
diff --git a/usr/src/cmd/ipdadm/Makefile b/usr/src/cmd/ipdadm/Makefile
new file mode 100644
index 0000000000..349899e5f6
--- /dev/null
+++ b/usr/src/cmd/ipdadm/Makefile
@@ -0,0 +1,45 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 Joyent, Inc. All rights reserved.
+#
+
+PROG= ipdadm
+OBJS = ipdadm.o
+SRCS = $(OBJS:%.o=../%.c)
+
+
+include ../Makefile.cmd
+include ../Makefile.ctf
+
+CLEANFILES += $(OBJS)
+CFLAGS += $(CCVERBOSE)
+LDLIBS += -lipd
+
+.KEEP_STATE:
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+clean:
+ -$(RM) $(CLEANFILES)
+
+lint: lint_PROG
+
+%.o: ../%.c
+ $(COMPILE.c) $<
+ $(POST_PROCESS_O)
+
+install: $(PROG) $(ROOTUSRSBINPROG)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/ipdadm/ipdadm.c b/usr/src/cmd/ipdadm/ipdadm.c
new file mode 100644
index 0000000000..ca68541690
--- /dev/null
+++ b/usr/src/cmd/ipdadm/ipdadm.c
@@ -0,0 +1,435 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+
+/*
+ * Copyright (c) 2012 Joyent, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <values.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <zone.h>
+#include <libgen.h>
+#include <assert.h>
+
+#include <libipd.h>
+
+static char *g_pname;
+static char g_zonename[ZONENAME_MAX];
+static zoneid_t g_zid;
+
+#define E_SUCCESS 0
+#define E_ERROR 1
+#define E_USAGE 2
+
+typedef int (*idc_cmd_func_t)(int, char *[]);
+typedef struct ipdadm_cmd {
+ const char *idc_name; /* subcommand name */
+ idc_cmd_func_t idc_func; /* subcommand function */
+ const char *idc_usage; /* subcommand help */
+} ipdadm_cmd_t;
+
+static int ipdadm_list(int, char *[]);
+static int ipdadm_info(int, char *[]);
+static int ipdadm_corrupt(int, char *[]);
+static int ipdadm_delay(int, char *[]);
+static int ipdadm_drop(int, char *[]);
+static int ipdadm_remove(int, char *[]);
+
+#define IPDADM_NCMDS 6
+static ipdadm_cmd_t ipdadm_cmds[] = {
+ { "list", ipdadm_list, "list [-v]" },
+ { "info", ipdadm_info, "info" },
+ { "corrupt", ipdadm_corrupt, "corrupt <percentage>" },
+ { "delay", ipdadm_delay, "delay <microseconds>" },
+ { "drop", ipdadm_drop, "drop <percentage>" },
+ { "remove", ipdadm_remove, "remove [corrupt|delay|drop]" }
+};
+
+static int
+usage(FILE *fp)
+{
+ int ii;
+ ipdadm_cmd_t *cmd;
+
+ (void) fprintf(fp, "Usage: %s [-z zonename] subcommand "
+ "[subcommand opts]\n\n", g_pname);
+ (void) fprintf(fp, "Subcommands:\n");
+ for (ii = 0; ii < IPDADM_NCMDS; ii++) {
+ cmd = &ipdadm_cmds[ii];
+ (void) fprintf(fp, "\t%s\n", cmd->idc_usage);
+ }
+
+ return (E_USAGE);
+}
+
+static void
+ipdadm_list_one(zoneid_t z, const ipd_config_t *icp, void *arg)
+{
+ char zonename[ZONENAME_MAX];
+ int opt_v = (int)(intptr_t)arg;
+
+ if (getzonenamebyid(z, zonename, sizeof (zonename)) < 0)
+ (void) printf("%ld", z);
+ else
+ (void) printf("%s", zonename);
+
+ if (!opt_v) {
+ (void) printf("\n");
+ return;
+ }
+
+ (void) printf("\t%u\t%u\t%u\n", icp->ic_corrupt, icp->ic_drop,
+ icp->ic_delay);
+}
+
+static int
+ipdadm_list(int argc, char *argv[])
+{
+ int opt_v = 0;
+ int fd, rval;
+ ipd_stathdl_t hdl;
+
+ if (argc > 1)
+ return (usage(stderr));
+
+ if (argc == 1) {
+ if (strcmp(argv[0], "-v") == 0)
+ ++opt_v;
+ else
+ return (usage(stderr));
+ }
+
+ fd = ipd_open(NULL);
+ rval = ipd_status_read(fd, &hdl);
+ (void) ipd_close(fd);
+
+ if (rval != 0) {
+ (void) fprintf(stderr, "%s: failed to get list info: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ ipd_status_foreach_zone(hdl, ipdadm_list_one, (void *)(intptr_t)opt_v);
+ ipd_status_free(hdl);
+
+ return (E_SUCCESS);
+}
+
+/*ARGSUSED*/
+static int
+ipdadm_info(int argc, char *argv[])
+{
+ int rval, fd;
+ ipd_stathdl_t hdl;
+ ipd_config_t *icp;
+
+ if (argc != 0)
+ return (usage(stderr));
+
+ fd = ipd_open(NULL);
+ rval = ipd_status_read(fd, &hdl);
+ (void) ipd_close(fd);
+ if (rval != 0) {
+ (void) fprintf(stderr, "%s: failed to get info: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ if (ipd_status_get_config(hdl, g_zid, &icp) != 0) {
+ if (ipd_errno == EIPD_ZC_NOENT) {
+ (void) printf("zone %s does not exist or has no "
+ "ipd actions enabled\n", g_zonename);
+ return (E_SUCCESS);
+ }
+ (void) fprintf(stderr, "%s: failed to get info: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ (void) printf("ipd information for zone %s:\n",
+ g_zonename);
+ (void) printf("\tcorrupt:\t%u%% chance of packet corruption\n",
+ icp->ic_corrupt);
+ (void) printf("\tdrop:\t\t%u%% chance of packet drop\n",
+ icp->ic_drop);
+ (void) printf("\tdelay:\t\t%u microsecond delay per packet\n",
+ icp->ic_delay);
+
+ ipd_status_free(hdl);
+
+ return (E_SUCCESS);
+}
+
+static long
+ipdadm_parse_long(const char *str, const char *name, long min, long max)
+{
+ long val;
+ char *end;
+
+ errno = 0;
+ val = strtol(str, &end, 10);
+ if (errno != 0) {
+ (void) fprintf(stderr, "%s: invalid value for %s: %s\n",
+ g_pname, name, str);
+ exit(E_ERROR);
+ }
+
+ /*
+ * We want to make sure that we got the whole string. If not that's an
+ * error. e.g. 23.42 should not be valid.
+ */
+ if (*end != '\0') {
+ (void) fprintf(stderr, "%s: %s value must be an integer\n",
+ g_pname, name);
+ exit(E_ERROR);
+ }
+
+ if (val < min || val > max) {
+ (void) fprintf(stderr, "%s: %s value must be between %ld and "
+ "%ld inclusive\n", g_pname, name, min, max);
+ exit(E_ERROR);
+ }
+
+ return (val);
+}
+
+static int
+ipdadm_corrupt(int argc, char *argv[])
+{
+ int rval, fd;
+ long val;
+ ipd_config_t ic;
+
+ if (argc != 1) {
+ (void) fprintf(stderr, "%s: corrupt <percentage>\n",
+ g_pname);
+ return (usage(stderr));
+ }
+
+ val = ipdadm_parse_long(argv[0], "corrupt", 0, 100);
+ bzero(&ic, sizeof (ic));
+ ic.ic_mask = IPDM_CORRUPT;
+ ic.ic_corrupt = val;
+
+ fd = ipd_open(NULL);
+ rval = ipd_ctl(fd, g_zid, &ic);
+ (void) ipd_close(fd);
+
+ if (rval != 0) {
+ (void) fprintf(stderr, "%s: failed to change corrupt "
+ "value: %s\n", g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ return (E_SUCCESS);
+}
+
+static int
+ipdadm_delay(int argc, char *argv[])
+{
+ long val;
+ int fd, rval;
+ ipd_config_t ic;
+
+ if (argc != 1) {
+ (void) fprintf(stderr, "%s: delay <microseconds>\n",
+ g_pname);
+ return (usage(stderr));
+ }
+
+ val = ipdadm_parse_long(argv[0], "delay", 0, MAXLONG);
+ bzero(&ic, sizeof (ic));
+ ic.ic_mask = IPDM_DELAY;
+ ic.ic_delay = val;
+
+ fd = ipd_open(NULL);
+ rval = ipd_ctl(fd, g_zid, &ic);
+ (void) ipd_close(fd);
+
+ if (rval != 0) {
+ (void) fprintf(stderr, "%s: failed to change delay value: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ return (E_SUCCESS);
+}
+
+static int
+ipdadm_drop(int argc, char *argv[])
+{
+ long val;
+ int fd, rval;
+ ipd_config_t ic;
+
+ if (argc != 1) {
+ (void) fprintf(stderr, "%s: drop <percentage>\n",
+ g_pname);
+ return (usage(stderr));
+ }
+
+ val = ipdadm_parse_long(argv[0], "drop", 0, 100);
+ bzero(&ic, sizeof (ic));
+ ic.ic_mask = IPDM_DROP;
+ ic.ic_drop = val;
+
+ fd = ipd_open(NULL);
+ rval = ipd_ctl(fd, g_zid, &ic);
+ (void) ipd_close(fd);
+
+ if (rval != 0) {
+ (void) fprintf(stderr, "%s: failed to change drop value: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ return (E_SUCCESS);
+}
+
+static int
+ipdadm_remove_valid(const char *str)
+{
+ if (strcmp(str, "corrupt") == 0) {
+ return (IPDM_CORRUPT);
+ } else if (strcmp(str, "drop") == 0) {
+ return (IPDM_DROP);
+ } else if (strcmp(str, "delay") == 0) {
+ return (IPDM_DELAY);
+ }
+
+ return (0);
+}
+
+static int
+ipdadm_remove(int argc, char *argv[])
+{
+ ipd_config_t ic;
+ char *cur, *res;
+ int rval, fd;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, "%s: remove <arguments>\n",
+ g_pname);
+ return (usage(stderr));
+ }
+
+ if (argc > 1) {
+ (void) fprintf(stderr, "%s: remove's arguments must be "
+ "comma seperated\n", g_pname);
+ return (E_ERROR);
+ }
+
+ bzero(&ic, sizeof (ic));
+
+ cur = argv[0];
+ while ((res = strchr(cur, ',')) != NULL) {
+ *res = '\0';
+ if ((rval = ipdadm_remove_valid(cur)) == 0) {
+ (void) fprintf(stderr, "%s: unknown remove "
+ "argument: %s\n", g_pname, cur);
+ return (E_ERROR);
+ }
+ ic.ic_mask |= rval;
+ cur = res + 1;
+ }
+
+ if ((rval = ipdadm_remove_valid(cur)) == 0) {
+ (void) fprintf(stderr, "%s: unknown remove argument: %s\n",
+ g_pname, cur);
+ return (E_ERROR);
+ }
+ ic.ic_mask |= rval;
+
+ fd = ipd_open(NULL);
+ rval = ipd_ctl(fd, g_zid, &ic);
+ (void) ipd_close(fd);
+ if (rval == -1) {
+ (void) fprintf(stderr, "%s: failed to remove instances: %s\n",
+ g_pname, ipd_errmsg);
+ return (E_ERROR);
+ }
+
+ return (E_SUCCESS);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int ii;
+ ipdadm_cmd_t *cmd;
+
+ g_pname = basename(argv[0]);
+
+ if (argc < 2)
+ return (usage(stderr));
+ argc--;
+ argv++;
+
+ g_zid = getzoneid();
+ if (strcmp("-z", argv[0]) == 0) {
+ argc--;
+ argv++;
+ if (argc < 1) {
+ (void) fprintf(stderr, "%s: -z requires an argument\n",
+ g_pname);
+ return (usage(stderr));
+ }
+
+ if (g_zid != GLOBAL_ZONEID) {
+ (void) fprintf(stderr, "%s: -z option only permitted "
+ "in global zone\n", g_pname);
+ return (usage(stderr));
+ }
+
+ g_zid = getzoneidbyname(argv[0]);
+ if (g_zid == -1) {
+ (void) fprintf(stderr, "%s: %s: invalid zone\n",
+ g_pname, argv[0]);
+ return (E_ERROR);
+ }
+ argc--;
+ argv++;
+ }
+
+ if (getzonenamebyid(g_zid, g_zonename, sizeof (g_zonename)) < 0) {
+ (void) fprintf(stderr, "%s: failed to get zonename: %s\n",
+ g_pname, strerror(errno));
+ return (E_ERROR);
+ }
+
+ if (argc < 1)
+ return (usage(stderr));
+
+ for (ii = 0; ii < IPDADM_NCMDS; ii++) {
+ cmd = &ipdadm_cmds[ii];
+ if (strcmp(argv[0], cmd->idc_name) == 0) {
+ argv++;
+ argc--;
+ assert(cmd->idc_func != NULL);
+ return (cmd->idc_func(argc, argv));
+ }
+ }
+
+ (void) fprintf(stderr, "%s: %s: unknown command\n", g_pname, argv[0]);
+ return (usage(stderr));
+}