1fe77cc0Robert Mustacchi/*
2fe77cc0Robert Mustacchi * This file and its contents are supplied under the terms of the
3fe77cc0Robert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4fe77cc0Robert Mustacchi * You may only use this file in accordance with the terms of version
5fe77cc0Robert Mustacchi * 1.0 of the CDDL.
6fe77cc0Robert Mustacchi *
7fe77cc0Robert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8fe77cc0Robert Mustacchi * source.  A copy of the CDDL is also available via the Internet at
9fe77cc0Robert Mustacchi * http://www.illumos.org/license/CDDL.
10fe77cc0Robert Mustacchi */
11fe77cc0Robert Mustacchi
12fe77cc0Robert Mustacchi
13fe77cc0Robert Mustacchi/*
14fe77cc0Robert Mustacchi * Copyright (c) 2012 Joyent, Inc.  All rights reserved.
15fe77cc0Robert Mustacchi * Use is subject to license terms.
16fe77cc0Robert Mustacchi */
17fe77cc0Robert Mustacchi
18fe77cc0Robert Mustacchi#include <sys/types.h>
19fe77cc0Robert Mustacchi#include <sys/stat.h>
20fe77cc0Robert Mustacchi#include <values.h>
21fe77cc0Robert Mustacchi#include <fcntl.h>
22fe77cc0Robert Mustacchi#include <errno.h>
23fe77cc0Robert Mustacchi#include <string.h>
24fe77cc0Robert Mustacchi#include <strings.h>
25fe77cc0Robert Mustacchi#include <stdio.h>
26fe77cc0Robert Mustacchi#include <stdlib.h>
27fe77cc0Robert Mustacchi#include <unistd.h>
28fe77cc0Robert Mustacchi#include <stropts.h>
29fe77cc0Robert Mustacchi#include <zone.h>
30fe77cc0Robert Mustacchi#include <libgen.h>
31fe77cc0Robert Mustacchi#include <assert.h>
32fe77cc0Robert Mustacchi
33fe77cc0Robert Mustacchi#include <libipd.h>
34fe77cc0Robert Mustacchi
35fe77cc0Robert Mustacchistatic char *g_pname;
36fe77cc0Robert Mustacchistatic char g_zonename[ZONENAME_MAX];
37fe77cc0Robert Mustacchistatic zoneid_t	g_zid;
38fe77cc0Robert Mustacchi
39fe77cc0Robert Mustacchi#define	E_SUCCESS	0
40fe77cc0Robert Mustacchi#define	E_ERROR		1
41fe77cc0Robert Mustacchi#define	E_USAGE		2
42fe77cc0Robert Mustacchi
43fe77cc0Robert Mustacchitypedef int (*idc_cmd_func_t)(int, char *[]);
44fe77cc0Robert Mustacchitypedef struct ipdadm_cmd {
45fe77cc0Robert Mustacchi	const char	*idc_name;	/* subcommand name */
46fe77cc0Robert Mustacchi	idc_cmd_func_t	idc_func;	/* subcommand function */
47fe77cc0Robert Mustacchi	const char	*idc_usage;	/* subcommand help */
48fe77cc0Robert Mustacchi} ipdadm_cmd_t;
49fe77cc0Robert Mustacchi
50fe77cc0Robert Mustacchistatic int ipdadm_list(int, char *[]);
51fe77cc0Robert Mustacchistatic int ipdadm_info(int, char *[]);
52fe77cc0Robert Mustacchistatic int ipdadm_corrupt(int, char *[]);
53fe77cc0Robert Mustacchistatic int ipdadm_delay(int, char *[]);
54fe77cc0Robert Mustacchistatic int ipdadm_drop(int, char *[]);
55fe77cc0Robert Mustacchistatic int ipdadm_remove(int, char *[]);
56fe77cc0Robert Mustacchi
57fe77cc0Robert Mustacchi#define	IPDADM_NCMDS	6
58fe77cc0Robert Mustacchistatic ipdadm_cmd_t ipdadm_cmds[] = {
59fe77cc0Robert Mustacchi	{ "list", ipdadm_list, "list [-v]" },
60fe77cc0Robert Mustacchi	{ "info", ipdadm_info, "info" },
61fe77cc0Robert Mustacchi	{ "corrupt", ipdadm_corrupt, "corrupt <percentage>" },
62fe77cc0Robert Mustacchi	{ "delay", ipdadm_delay, "delay <microseconds>" },
63fe77cc0Robert Mustacchi	{ "drop", ipdadm_drop, "drop <percentage>" },
64fe77cc0Robert Mustacchi	{ "remove", ipdadm_remove, "remove [corrupt|delay|drop]" }
65fe77cc0Robert Mustacchi};
66fe77cc0Robert Mustacchi
67fe77cc0Robert Mustacchistatic int
68fe77cc0Robert Mustacchiusage(FILE *fp)
69fe77cc0Robert Mustacchi{
70fe77cc0Robert Mustacchi	int ii;
71fe77cc0Robert Mustacchi	ipdadm_cmd_t *cmd;
72fe77cc0Robert Mustacchi
73fe77cc0Robert Mustacchi	(void) fprintf(fp, "Usage: %s [-z zonename] subcommand "
74fe77cc0Robert Mustacchi	    "[subcommand opts]\n\n", g_pname);
75fe77cc0Robert Mustacchi	(void) fprintf(fp, "Subcommands:\n");
76fe77cc0Robert Mustacchi	for (ii = 0; ii < IPDADM_NCMDS; ii++) {
77fe77cc0Robert Mustacchi		cmd = &ipdadm_cmds[ii];
78fe77cc0Robert Mustacchi		(void) fprintf(fp, "\t%s\n", cmd->idc_usage);
79fe77cc0Robert Mustacchi	}
80fe77cc0Robert Mustacchi
81fe77cc0Robert Mustacchi	return (E_USAGE);
82fe77cc0Robert Mustacchi}
83fe77cc0Robert Mustacchi
84fe77cc0Robert Mustacchistatic void
85fe77cc0Robert Mustacchiipdadm_list_one(zoneid_t z, const ipd_config_t *icp, void *arg)
86fe77cc0Robert Mustacchi{
87fe77cc0Robert Mustacchi	char zonename[ZONENAME_MAX];
88fe77cc0Robert Mustacchi	int opt_v = (int)(intptr_t)arg;
89fe77cc0Robert Mustacchi
90fe77cc0Robert Mustacchi	if (getzonenamebyid(z, zonename, sizeof (zonename)) < 0)
91fe77cc0Robert Mustacchi		(void) printf("%ld", z);
92fe77cc0Robert Mustacchi	else
93fe77cc0Robert Mustacchi		(void) printf("%s", zonename);
94fe77cc0Robert Mustacchi
95fe77cc0Robert Mustacchi	if (!opt_v) {
96fe77cc0Robert Mustacchi		(void) printf("\n");
97fe77cc0Robert Mustacchi		return;
98fe77cc0Robert Mustacchi	}
99fe77cc0Robert Mustacchi
100fe77cc0Robert Mustacchi	(void) printf("\t%u\t%u\t%u\n", icp->ic_corrupt, icp->ic_drop,
101fe77cc0Robert Mustacchi	    icp->ic_delay);
102fe77cc0Robert Mustacchi}
103fe77cc0Robert Mustacchi
104fe77cc0Robert Mustacchistatic int
105fe77cc0Robert Mustacchiipdadm_list(int argc, char *argv[])
106fe77cc0Robert Mustacchi{
107fe77cc0Robert Mustacchi	int opt_v = 0;
108fe77cc0Robert Mustacchi	int fd, rval;
109fe77cc0Robert Mustacchi	ipd_stathdl_t hdl;
110fe77cc0Robert Mustacchi
111fe77cc0Robert Mustacchi	if (argc > 1)
112fe77cc0Robert Mustacchi		return (usage(stderr));
113fe77cc0Robert Mustacchi
114fe77cc0Robert Mustacchi	if (argc == 1) {
115fe77cc0Robert Mustacchi		if (strcmp(argv[0], "-v") == 0)
116fe77cc0Robert Mustacchi			++opt_v;
117fe77cc0Robert Mustacchi		else
118fe77cc0Robert Mustacchi			return (usage(stderr));
119fe77cc0Robert Mustacchi	}
120fe77cc0Robert Mustacchi
121fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
122ceec9e1Keith M Wesolowski	if (fd < 0) {
123ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
124ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
125ceec9e1Keith M Wesolowski		return (E_ERROR);
126ceec9e1Keith M Wesolowski	}
127fe77cc0Robert Mustacchi	rval = ipd_status_read(fd, &hdl);
128fe77cc0Robert Mustacchi	(void) ipd_close(fd);
129fe77cc0Robert Mustacchi
130fe77cc0Robert Mustacchi	if (rval != 0) {
131fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to get list info: %s\n",
132fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
133fe77cc0Robert Mustacchi		return (E_ERROR);
134fe77cc0Robert Mustacchi	}
135fe77cc0Robert Mustacchi
136fe77cc0Robert Mustacchi	ipd_status_foreach_zone(hdl, ipdadm_list_one, (void *)(intptr_t)opt_v);
137fe77cc0Robert Mustacchi	ipd_status_free(hdl);
138fe77cc0Robert Mustacchi
139fe77cc0Robert Mustacchi	return (E_SUCCESS);
140fe77cc0Robert Mustacchi}
141fe77cc0Robert Mustacchi
142fe77cc0Robert Mustacchi/*ARGSUSED*/
143fe77cc0Robert Mustacchistatic int
144fe77cc0Robert Mustacchiipdadm_info(int argc, char *argv[])
145fe77cc0Robert Mustacchi{
146fe77cc0Robert Mustacchi	int rval, fd;
147fe77cc0Robert Mustacchi	ipd_stathdl_t hdl;
148fe77cc0Robert Mustacchi	ipd_config_t *icp;
149fe77cc0Robert Mustacchi
150fe77cc0Robert Mustacchi	if (argc != 0)
151fe77cc0Robert Mustacchi		return (usage(stderr));
152fe77cc0Robert Mustacchi
153fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
154ceec9e1Keith M Wesolowski	if (fd < 0) {
155ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
156ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
157ceec9e1Keith M Wesolowski		return (E_ERROR);
158ceec9e1Keith M Wesolowski	}
159fe77cc0Robert Mustacchi	rval = ipd_status_read(fd, &hdl);
160fe77cc0Robert Mustacchi	(void) ipd_close(fd);
161fe77cc0Robert Mustacchi	if (rval != 0) {
162fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to get info: %s\n",
163fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
164fe77cc0Robert Mustacchi		return (E_ERROR);
165fe77cc0Robert Mustacchi	}
166fe77cc0Robert Mustacchi
167fe77cc0Robert Mustacchi	if (ipd_status_get_config(hdl, g_zid, &icp) != 0) {
168fe77cc0Robert Mustacchi		if (ipd_errno == EIPD_ZC_NOENT) {
169fe77cc0Robert Mustacchi			(void) printf("zone %s does not exist or has no "
170fe77cc0Robert Mustacchi			    "ipd actions enabled\n", g_zonename);
171fe77cc0Robert Mustacchi			return (E_SUCCESS);
172fe77cc0Robert Mustacchi		}
173fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to get info: %s\n",
174fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
175fe77cc0Robert Mustacchi		return (E_ERROR);
176fe77cc0Robert Mustacchi	}
177fe77cc0Robert Mustacchi
178fe77cc0Robert Mustacchi	(void) printf("ipd information for zone %s:\n",
179fe77cc0Robert Mustacchi	    g_zonename);
180fe77cc0Robert Mustacchi	(void) printf("\tcorrupt:\t%u%% chance of packet corruption\n",
181fe77cc0Robert Mustacchi	    icp->ic_corrupt);
182fe77cc0Robert Mustacchi	(void) printf("\tdrop:\t\t%u%% chance of packet drop\n",
183fe77cc0Robert Mustacchi	    icp->ic_drop);
184fe77cc0Robert Mustacchi	(void) printf("\tdelay:\t\t%u microsecond delay per packet\n",
185fe77cc0Robert Mustacchi	    icp->ic_delay);
186fe77cc0Robert Mustacchi
187fe77cc0Robert Mustacchi	ipd_status_free(hdl);
188fe77cc0Robert Mustacchi
189fe77cc0Robert Mustacchi	return (E_SUCCESS);
190fe77cc0Robert Mustacchi}
191fe77cc0Robert Mustacchi
192fe77cc0Robert Mustacchistatic long
193fe77cc0Robert Mustacchiipdadm_parse_long(const char *str, const char *name, long min, long max)
194fe77cc0Robert Mustacchi{
195fe77cc0Robert Mustacchi	long val;
196fe77cc0Robert Mustacchi	char *end;
197fe77cc0Robert Mustacchi
198fe77cc0Robert Mustacchi	errno = 0;
199fe77cc0Robert Mustacchi	val = strtol(str, &end, 10);
200fe77cc0Robert Mustacchi	if (errno != 0) {
201fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: invalid value for %s: %s\n",
202fe77cc0Robert Mustacchi		    g_pname, name, str);
203fe77cc0Robert Mustacchi		exit(E_ERROR);
204fe77cc0Robert Mustacchi	}
205fe77cc0Robert Mustacchi
206fe77cc0Robert Mustacchi	/*
207fe77cc0Robert Mustacchi	 * We want to make sure that we got the whole string. If not that's an
208fe77cc0Robert Mustacchi	 * error. e.g. 23.42 should not be valid.
209fe77cc0Robert Mustacchi	 */
210fe77cc0Robert Mustacchi	if (*end != '\0') {
211fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: %s value must be an integer\n",
212fe77cc0Robert Mustacchi		    g_pname, name);
213fe77cc0Robert Mustacchi		exit(E_ERROR);
214fe77cc0Robert Mustacchi	}
215fe77cc0Robert Mustacchi
216fe77cc0Robert Mustacchi	if (val < min || val > max) {
217fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: %s value must be between %ld and "
218fe77cc0Robert Mustacchi		    "%ld inclusive\n", g_pname, name, min, max);
219fe77cc0Robert Mustacchi		exit(E_ERROR);
220fe77cc0Robert Mustacchi	}
221fe77cc0Robert Mustacchi
222fe77cc0Robert Mustacchi	return (val);
223fe77cc0Robert Mustacchi}
224fe77cc0Robert Mustacchi
225fe77cc0Robert Mustacchistatic int
226fe77cc0Robert Mustacchiipdadm_corrupt(int argc, char *argv[])
227fe77cc0Robert Mustacchi{
228fe77cc0Robert Mustacchi	int rval, fd;
229fe77cc0Robert Mustacchi	long val;
230fe77cc0Robert Mustacchi	ipd_config_t ic;
231fe77cc0Robert Mustacchi
232fe77cc0Robert Mustacchi	if (argc != 1) {
233fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: corrupt <percentage>\n",
234fe77cc0Robert Mustacchi		    g_pname);
235fe77cc0Robert Mustacchi		return (usage(stderr));
236fe77cc0Robert Mustacchi	}
237fe77cc0Robert Mustacchi
238fe77cc0Robert Mustacchi	val = ipdadm_parse_long(argv[0], "corrupt", 0, 100);
239fe77cc0Robert Mustacchi	bzero(&ic, sizeof (ic));
240fe77cc0Robert Mustacchi	ic.ic_mask = IPDM_CORRUPT;
241fe77cc0Robert Mustacchi	ic.ic_corrupt = val;
242fe77cc0Robert Mustacchi
243fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
244ceec9e1Keith M Wesolowski	if (fd < 0) {
245ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
246ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
247ceec9e1Keith M Wesolowski		return (E_ERROR);
248ceec9e1Keith M Wesolowski	}
249fe77cc0Robert Mustacchi	rval = ipd_ctl(fd, g_zid, &ic);
250fe77cc0Robert Mustacchi	(void) ipd_close(fd);
251fe77cc0Robert Mustacchi
252fe77cc0Robert Mustacchi	if (rval != 0) {
253fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to change corrupt "
254fe77cc0Robert Mustacchi		    "value: %s\n", g_pname, ipd_errmsg);
255fe77cc0Robert Mustacchi		return (E_ERROR);
256fe77cc0Robert Mustacchi	}
257fe77cc0Robert Mustacchi
258fe77cc0Robert Mustacchi	return (E_SUCCESS);
259fe77cc0Robert Mustacchi}
260fe77cc0Robert Mustacchi
261fe77cc0Robert Mustacchistatic int
262fe77cc0Robert Mustacchiipdadm_delay(int argc, char *argv[])
263fe77cc0Robert Mustacchi{
264fe77cc0Robert Mustacchi	long val;
265fe77cc0Robert Mustacchi	int fd, rval;
266fe77cc0Robert Mustacchi	ipd_config_t ic;
267fe77cc0Robert Mustacchi
268fe77cc0Robert Mustacchi	if (argc != 1) {
269fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: delay <microseconds>\n",
270fe77cc0Robert Mustacchi		    g_pname);
271fe77cc0Robert Mustacchi		return (usage(stderr));
272fe77cc0Robert Mustacchi	}
273fe77cc0Robert Mustacchi
274fe77cc0Robert Mustacchi	val = ipdadm_parse_long(argv[0], "delay", 0, MAXLONG);
275fe77cc0Robert Mustacchi	bzero(&ic, sizeof (ic));
276fe77cc0Robert Mustacchi	ic.ic_mask = IPDM_DELAY;
277fe77cc0Robert Mustacchi	ic.ic_delay = val;
278fe77cc0Robert Mustacchi
279fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
280ceec9e1Keith M Wesolowski	if (fd < 0) {
281ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
282ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
283ceec9e1Keith M Wesolowski		return (E_ERROR);
284ceec9e1Keith M Wesolowski	}
285fe77cc0Robert Mustacchi	rval = ipd_ctl(fd, g_zid, &ic);
286fe77cc0Robert Mustacchi	(void) ipd_close(fd);
287fe77cc0Robert Mustacchi
288fe77cc0Robert Mustacchi	if (rval != 0) {
289fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to change delay value: %s\n",
290fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
291fe77cc0Robert Mustacchi		return (E_ERROR);
292fe77cc0Robert Mustacchi	}
293fe77cc0Robert Mustacchi
294fe77cc0Robert Mustacchi	return (E_SUCCESS);
295fe77cc0Robert Mustacchi}
296fe77cc0Robert Mustacchi
297fe77cc0Robert Mustacchistatic int
298fe77cc0Robert Mustacchiipdadm_drop(int argc, char *argv[])
299fe77cc0Robert Mustacchi{
300fe77cc0Robert Mustacchi	long val;
301fe77cc0Robert Mustacchi	int fd, rval;
302fe77cc0Robert Mustacchi	ipd_config_t ic;
303fe77cc0Robert Mustacchi
304fe77cc0Robert Mustacchi	if (argc != 1) {
305fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: drop <percentage>\n",
306fe77cc0Robert Mustacchi		    g_pname);
307fe77cc0Robert Mustacchi		return (usage(stderr));
308fe77cc0Robert Mustacchi	}
309fe77cc0Robert Mustacchi
310fe77cc0Robert Mustacchi	val = ipdadm_parse_long(argv[0], "drop", 0, 100);
311fe77cc0Robert Mustacchi	bzero(&ic, sizeof (ic));
312fe77cc0Robert Mustacchi	ic.ic_mask = IPDM_DROP;
313fe77cc0Robert Mustacchi	ic.ic_drop = val;
314fe77cc0Robert Mustacchi
315fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
316ceec9e1Keith M Wesolowski	if (fd < 0) {
317ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
318ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
319ceec9e1Keith M Wesolowski		return (E_ERROR);
320ceec9e1Keith M Wesolowski	}
321fe77cc0Robert Mustacchi	rval = ipd_ctl(fd, g_zid, &ic);
322fe77cc0Robert Mustacchi	(void) ipd_close(fd);
323fe77cc0Robert Mustacchi
324fe77cc0Robert Mustacchi	if (rval != 0) {
325fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to change drop value: %s\n",
326fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
327fe77cc0Robert Mustacchi		return (E_ERROR);
328fe77cc0Robert Mustacchi	}
329fe77cc0Robert Mustacchi
330fe77cc0Robert Mustacchi	return (E_SUCCESS);
331fe77cc0Robert Mustacchi}
332fe77cc0Robert Mustacchi
333fe77cc0Robert Mustacchistatic int
334fe77cc0Robert Mustacchiipdadm_remove_valid(const char *str)
335fe77cc0Robert Mustacchi{
336fe77cc0Robert Mustacchi	if (strcmp(str, "corrupt") == 0) {
337fe77cc0Robert Mustacchi		return (IPDM_CORRUPT);
338fe77cc0Robert Mustacchi	} else if (strcmp(str, "drop") == 0) {
339fe77cc0Robert Mustacchi		return (IPDM_DROP);
340fe77cc0Robert Mustacchi	} else if (strcmp(str, "delay") == 0) {
341fe77cc0Robert Mustacchi		return (IPDM_DELAY);
342fe77cc0Robert Mustacchi	}
343fe77cc0Robert Mustacchi
344fe77cc0Robert Mustacchi	return (0);
345fe77cc0Robert Mustacchi}
346fe77cc0Robert Mustacchi
347fe77cc0Robert Mustacchistatic int
348fe77cc0Robert Mustacchiipdadm_remove(int argc, char *argv[])
349fe77cc0Robert Mustacchi{
350fe77cc0Robert Mustacchi	ipd_config_t ic;
351fe77cc0Robert Mustacchi	char *cur, *res;
352fe77cc0Robert Mustacchi	int rval, fd;
353fe77cc0Robert Mustacchi
354fe77cc0Robert Mustacchi	if (argc < 1) {
355fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: remove <arguments>\n",
356fe77cc0Robert Mustacchi		    g_pname);
357fe77cc0Robert Mustacchi		return (usage(stderr));
358fe77cc0Robert Mustacchi	}
359fe77cc0Robert Mustacchi
360fe77cc0Robert Mustacchi	if (argc > 1) {
361fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: remove's arguments must be "
362fe77cc0Robert Mustacchi		    "comma seperated\n", g_pname);
363fe77cc0Robert Mustacchi		return (E_ERROR);
364fe77cc0Robert Mustacchi	}
365fe77cc0Robert Mustacchi
366fe77cc0Robert Mustacchi	bzero(&ic, sizeof (ic));
367fe77cc0Robert Mustacchi
368fe77cc0Robert Mustacchi	cur = argv[0];
369fe77cc0Robert Mustacchi	while ((res = strchr(cur, ',')) != NULL) {
370fe77cc0Robert Mustacchi		*res = '\0';
371fe77cc0Robert Mustacchi		if ((rval = ipdadm_remove_valid(cur)) == 0) {
372fe77cc0Robert Mustacchi			(void) fprintf(stderr, "%s: unknown remove "
373fe77cc0Robert Mustacchi			    "argument: %s\n", g_pname, cur);
374fe77cc0Robert Mustacchi			return (E_ERROR);
375fe77cc0Robert Mustacchi		}
376fe77cc0Robert Mustacchi		ic.ic_mask |= rval;
377fe77cc0Robert Mustacchi		cur = res + 1;
378fe77cc0Robert Mustacchi	}
379fe77cc0Robert Mustacchi
380fe77cc0Robert Mustacchi	if ((rval = ipdadm_remove_valid(cur)) == 0) {
381fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: unknown remove argument: %s\n",
382fe77cc0Robert Mustacchi		    g_pname, cur);
383fe77cc0Robert Mustacchi		return (E_ERROR);
384fe77cc0Robert Mustacchi	}
385fe77cc0Robert Mustacchi	ic.ic_mask |= rval;
386fe77cc0Robert Mustacchi
387fe77cc0Robert Mustacchi	fd = ipd_open(NULL);
388ceec9e1Keith M Wesolowski	if (fd < 0) {
389ceec9e1Keith M Wesolowski		(void) fprintf(stderr, "%s: failed to open ipd ctl node: %s\n",
390ceec9e1Keith M Wesolowski		    g_pname, ipd_errmsg);
391ceec9e1Keith M Wesolowski		return (E_ERROR);
392ceec9e1Keith M Wesolowski	}
393fe77cc0Robert Mustacchi	rval = ipd_ctl(fd, g_zid, &ic);
394fe77cc0Robert Mustacchi	(void) ipd_close(fd);
395fe77cc0Robert Mustacchi	if (rval == -1) {
396fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to remove instances: %s\n",
397fe77cc0Robert Mustacchi		    g_pname, ipd_errmsg);
398fe77cc0Robert Mustacchi		return (E_ERROR);
399fe77cc0Robert Mustacchi	}
400fe77cc0Robert Mustacchi
401fe77cc0Robert Mustacchi	return (E_SUCCESS);
402fe77cc0Robert Mustacchi}
403fe77cc0Robert Mustacchi
404fe77cc0Robert Mustacchi
405fe77cc0Robert Mustacchiint
406fe77cc0Robert Mustacchimain(int argc, char *argv[])
407fe77cc0Robert Mustacchi{
408fe77cc0Robert Mustacchi	int ii;
409fe77cc0Robert Mustacchi	ipdadm_cmd_t *cmd;
410fe77cc0Robert Mustacchi
411fe77cc0Robert Mustacchi	g_pname = basename(argv[0]);
412fe77cc0Robert Mustacchi
413fe77cc0Robert Mustacchi	if (argc < 2)
414fe77cc0Robert Mustacchi		return (usage(stderr));
415fe77cc0Robert Mustacchi	argc--;
416fe77cc0Robert Mustacchi	argv++;
417fe77cc0Robert Mustacchi
418fe77cc0Robert Mustacchi	g_zid = getzoneid();
419fe77cc0Robert Mustacchi	if (strcmp("-z", argv[0]) == 0) {
420fe77cc0Robert Mustacchi		argc--;
421fe77cc0Robert Mustacchi		argv++;
422fe77cc0Robert Mustacchi		if (argc < 1) {
423fe77cc0Robert Mustacchi			(void) fprintf(stderr, "%s: -z requires an argument\n",
424fe77cc0Robert Mustacchi			    g_pname);
425fe77cc0Robert Mustacchi			return (usage(stderr));
426fe77cc0Robert Mustacchi		}
427fe77cc0Robert Mustacchi
428fe77cc0Robert Mustacchi		if (g_zid != GLOBAL_ZONEID) {
429fe77cc0Robert Mustacchi			(void) fprintf(stderr, "%s: -z option only permitted "
430fe77cc0Robert Mustacchi			    "in global zone\n", g_pname);
431fe77cc0Robert Mustacchi			return (usage(stderr));
432fe77cc0Robert Mustacchi		}
433fe77cc0Robert Mustacchi
434fe77cc0Robert Mustacchi		g_zid = getzoneidbyname(argv[0]);
435fe77cc0Robert Mustacchi		if (g_zid == -1) {
436fe77cc0Robert Mustacchi			(void) fprintf(stderr, "%s: %s: invalid zone\n",
437fe77cc0Robert Mustacchi			    g_pname, argv[0]);
438fe77cc0Robert Mustacchi			return (E_ERROR);
439fe77cc0Robert Mustacchi		}
440fe77cc0Robert Mustacchi		argc--;
441fe77cc0Robert Mustacchi		argv++;
442fe77cc0Robert Mustacchi	}
443fe77cc0Robert Mustacchi
444fe77cc0Robert Mustacchi	if (getzonenamebyid(g_zid, g_zonename, sizeof (g_zonename)) < 0) {
445fe77cc0Robert Mustacchi		(void) fprintf(stderr, "%s: failed to get zonename: %s\n",
446fe77cc0Robert Mustacchi		    g_pname, strerror(errno));
447fe77cc0Robert Mustacchi		return (E_ERROR);
448fe77cc0Robert Mustacchi	}
449fe77cc0Robert Mustacchi
450fe77cc0Robert Mustacchi	if (argc < 1)
451fe77cc0Robert Mustacchi		return (usage(stderr));
452fe77cc0Robert Mustacchi
453fe77cc0Robert Mustacchi	for (ii = 0; ii < IPDADM_NCMDS; ii++) {
454fe77cc0Robert Mustacchi		cmd = &ipdadm_cmds[ii];
455fe77cc0Robert Mustacchi		if (strcmp(argv[0], cmd->idc_name) == 0) {
456fe77cc0Robert Mustacchi			argv++;
457fe77cc0Robert Mustacchi			argc--;
458fe77cc0Robert Mustacchi			assert(cmd->idc_func != NULL);
459fe77cc0Robert Mustacchi			return (cmd->idc_func(argc, argv));
460fe77cc0Robert Mustacchi		}
461fe77cc0Robert Mustacchi	}
462fe77cc0Robert Mustacchi
463fe77cc0Robert Mustacchi	(void) fprintf(stderr, "%s: %s: unknown command\n", g_pname, argv[0]);
464fe77cc0Robert Mustacchi	return (usage(stderr));
465fe77cc0Robert Mustacchi}
466