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