xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/nwamadm/nwamadm.c (revision 11767:8f30d0e611c6)
1*11767SAnurag.Maskey@Sun.COM /*
2*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
3*11767SAnurag.Maskey@Sun.COM  *
4*11767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
5*11767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
6*11767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
7*11767SAnurag.Maskey@Sun.COM  *
8*11767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
11*11767SAnurag.Maskey@Sun.COM  * and limitations under the License.
12*11767SAnurag.Maskey@Sun.COM  *
13*11767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11767SAnurag.Maskey@Sun.COM  *
19*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
20*11767SAnurag.Maskey@Sun.COM  */
21*11767SAnurag.Maskey@Sun.COM 
22*11767SAnurag.Maskey@Sun.COM /*
23*11767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*11767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
25*11767SAnurag.Maskey@Sun.COM  */
26*11767SAnurag.Maskey@Sun.COM 
27*11767SAnurag.Maskey@Sun.COM /*
28*11767SAnurag.Maskey@Sun.COM  * nwamadm is a command interpreter to administer NWAM profiles.  It
29*11767SAnurag.Maskey@Sun.COM  * is all in C (i.e., no lex/yacc), and all the argument passing is
30*11767SAnurag.Maskey@Sun.COM  * argc/argv based.  main() calls the command's handler function,
31*11767SAnurag.Maskey@Sun.COM  * which first calls parse_argv() to parse the input arguments and set
32*11767SAnurag.Maskey@Sun.COM  * approriate variables for each command.  The rest of the program is
33*11767SAnurag.Maskey@Sun.COM  * helper functions for the handler functions.
34*11767SAnurag.Maskey@Sun.COM  */
35*11767SAnurag.Maskey@Sun.COM 
36*11767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
37*11767SAnurag.Maskey@Sun.COM #include <assert.h>
38*11767SAnurag.Maskey@Sun.COM #include <errno.h>
39*11767SAnurag.Maskey@Sun.COM #include <libdlwlan.h>
40*11767SAnurag.Maskey@Sun.COM #include <libnwam.h>
41*11767SAnurag.Maskey@Sun.COM #include <libscf.h>
42*11767SAnurag.Maskey@Sun.COM #include <locale.h>
43*11767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
44*11767SAnurag.Maskey@Sun.COM #include <ofmt.h>
45*11767SAnurag.Maskey@Sun.COM #include <stdarg.h>
46*11767SAnurag.Maskey@Sun.COM #include <stdio.h>
47*11767SAnurag.Maskey@Sun.COM #include <stdlib.h>
48*11767SAnurag.Maskey@Sun.COM #include <string.h>
49*11767SAnurag.Maskey@Sun.COM #include <strings.h>
50*11767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
51*11767SAnurag.Maskey@Sun.COM #include <sys/types.h>
52*11767SAnurag.Maskey@Sun.COM #include <unistd.h>
53*11767SAnurag.Maskey@Sun.COM 
54*11767SAnurag.Maskey@Sun.COM #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
55*11767SAnurag.Maskey@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
56*11767SAnurag.Maskey@Sun.COM #endif
57*11767SAnurag.Maskey@Sun.COM 
58*11767SAnurag.Maskey@Sun.COM typedef void (cmd_func_t)(int, char **);
59*11767SAnurag.Maskey@Sun.COM 
60*11767SAnurag.Maskey@Sun.COM struct cmd {
61*11767SAnurag.Maskey@Sun.COM 	uint_t		cmd_num;		/* command number */
62*11767SAnurag.Maskey@Sun.COM 	const char	*cmd_name;		/* command name */
63*11767SAnurag.Maskey@Sun.COM 	cmd_func_t	*cmd_handler;		/* function to call */
64*11767SAnurag.Maskey@Sun.COM 	const char	*cmd_usage;		/* short form help */
65*11767SAnurag.Maskey@Sun.COM 	const char	*cmd_desc;		/* command description */
66*11767SAnurag.Maskey@Sun.COM 	boolean_t	cmd_needs_nwamd;	/* nwam needs to run */
67*11767SAnurag.Maskey@Sun.COM };
68*11767SAnurag.Maskey@Sun.COM 
69*11767SAnurag.Maskey@Sun.COM /* constants for commands */
70*11767SAnurag.Maskey@Sun.COM #define	CMD_HELP	0
71*11767SAnurag.Maskey@Sun.COM #define	CMD_ENABLE	1
72*11767SAnurag.Maskey@Sun.COM #define	CMD_DISABLE	2
73*11767SAnurag.Maskey@Sun.COM #define	CMD_LIST	3
74*11767SAnurag.Maskey@Sun.COM #define	CMD_SHOW_EVENTS	4
75*11767SAnurag.Maskey@Sun.COM #define	CMD_SCAN_WIFI	5
76*11767SAnurag.Maskey@Sun.COM #define	CMD_SELECT_WIFI	6
77*11767SAnurag.Maskey@Sun.COM 
78*11767SAnurag.Maskey@Sun.COM #define	CMD_MIN		CMD_HELP
79*11767SAnurag.Maskey@Sun.COM #define	CMD_MAX		CMD_SELECT_WIFI
80*11767SAnurag.Maskey@Sun.COM 
81*11767SAnurag.Maskey@Sun.COM /* functions to call */
82*11767SAnurag.Maskey@Sun.COM static cmd_func_t help_func, enable_func, disable_func, list_func;
83*11767SAnurag.Maskey@Sun.COM static cmd_func_t show_events_func, scan_wifi_func, select_wifi_func;
84*11767SAnurag.Maskey@Sun.COM static ofmt_cb_t print_list_cb;
85*11767SAnurag.Maskey@Sun.COM 
86*11767SAnurag.Maskey@Sun.COM /* table of commands and usage */
87*11767SAnurag.Maskey@Sun.COM static struct cmd cmdtab[] = {
88*11767SAnurag.Maskey@Sun.COM 	{ CMD_HELP,		"help",		help_func,
89*11767SAnurag.Maskey@Sun.COM 	    "help",
90*11767SAnurag.Maskey@Sun.COM 	    "Print this usage message.",		B_FALSE		},
91*11767SAnurag.Maskey@Sun.COM 	{ CMD_ENABLE,		"enable",	enable_func,
92*11767SAnurag.Maskey@Sun.COM 	    "enable [-p <profile-type>] [-c <ncu-class>] <object-name>",
93*11767SAnurag.Maskey@Sun.COM 	    "Enable the specified profile.",		B_FALSE		},
94*11767SAnurag.Maskey@Sun.COM 	{ CMD_DISABLE,		"disable",	disable_func,
95*11767SAnurag.Maskey@Sun.COM 	    "disable [-p <profile-type>] [-c <ncu-class>] <object-name>",
96*11767SAnurag.Maskey@Sun.COM 	    "Disable the specified profile.",		B_FALSE		},
97*11767SAnurag.Maskey@Sun.COM 	{ CMD_LIST,		"list",		list_func,
98*11767SAnurag.Maskey@Sun.COM 	    "list [-x] [-p <profile-type>] [-c <ncu-class>] [<object-name>]",
99*11767SAnurag.Maskey@Sun.COM 	    "List profiles and their current states.",	B_TRUE		},
100*11767SAnurag.Maskey@Sun.COM 	{ CMD_SHOW_EVENTS,	"show-events",	show_events_func,
101*11767SAnurag.Maskey@Sun.COM 	    "show-events",
102*11767SAnurag.Maskey@Sun.COM 	    "Display all events.",			B_TRUE		},
103*11767SAnurag.Maskey@Sun.COM 	{ CMD_SCAN_WIFI,	"scan-wifi",	scan_wifi_func,
104*11767SAnurag.Maskey@Sun.COM 	    "scan-wifi <link-name>",
105*11767SAnurag.Maskey@Sun.COM 	    "Request a WiFi scan for the selected link.", B_TRUE	},
106*11767SAnurag.Maskey@Sun.COM 	{ CMD_SELECT_WIFI,	"select-wifi",	select_wifi_func,
107*11767SAnurag.Maskey@Sun.COM 	    "select-wifi <link-name>",
108*11767SAnurag.Maskey@Sun.COM 	    "Make a WLAN selection from the last WiFi scan.", B_TRUE	}
109*11767SAnurag.Maskey@Sun.COM };
110*11767SAnurag.Maskey@Sun.COM 
111*11767SAnurag.Maskey@Sun.COM /* Structure for "nwamadm list" output */
112*11767SAnurag.Maskey@Sun.COM 
113*11767SAnurag.Maskey@Sun.COM typedef struct profile_entry {
114*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	p_type;
115*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	p_ncu_class;
116*11767SAnurag.Maskey@Sun.COM 	char			p_name[NWAM_MAX_NAME_LEN];
117*11767SAnurag.Maskey@Sun.COM 	nwam_state_t		p_state;
118*11767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t	p_aux_state;
119*11767SAnurag.Maskey@Sun.COM } profile_entry_t;
120*11767SAnurag.Maskey@Sun.COM 
121*11767SAnurag.Maskey@Sun.COM /* widths of colums for printing */
122*11767SAnurag.Maskey@Sun.COM #define	TYPE_WIDTH		12	/* width of TYPE column */
123*11767SAnurag.Maskey@Sun.COM #define	PROFILE_WIDTH		15	/* width of PROFILE column */
124*11767SAnurag.Maskey@Sun.COM #define	STATE_WIDTH		15	/* width of STATE column */
125*11767SAnurag.Maskey@Sun.COM #define	AUXSTATE_WIDTH		36	/* width of AUXILIARY STATE column */
126*11767SAnurag.Maskey@Sun.COM 
127*11767SAnurag.Maskey@Sun.COM #define	EVENT_WIDTH		22	/* width of EVENT column */
128*11767SAnurag.Maskey@Sun.COM #define	DESCRIPTION_WIDTH	56	/* width of DESCRIPTION column */
129*11767SAnurag.Maskey@Sun.COM 
130*11767SAnurag.Maskey@Sun.COM /* id for columns of "nwamadm list" */
131*11767SAnurag.Maskey@Sun.COM typedef enum {
132*11767SAnurag.Maskey@Sun.COM 	LIST_TYPE,
133*11767SAnurag.Maskey@Sun.COM 	LIST_PROFILE,
134*11767SAnurag.Maskey@Sun.COM 	LIST_STATE,
135*11767SAnurag.Maskey@Sun.COM 	LIST_AUXSTATE
136*11767SAnurag.Maskey@Sun.COM } list_field_id_t;
137*11767SAnurag.Maskey@Sun.COM 
138*11767SAnurag.Maskey@Sun.COM static const ofmt_field_t list_fields[] = {
139*11767SAnurag.Maskey@Sun.COM 	/* header,		width,		id,		callback */
140*11767SAnurag.Maskey@Sun.COM 	{ "TYPE",		TYPE_WIDTH,	LIST_TYPE,	print_list_cb },
141*11767SAnurag.Maskey@Sun.COM 	{ "PROFILE",		PROFILE_WIDTH,	LIST_PROFILE,	print_list_cb },
142*11767SAnurag.Maskey@Sun.COM 	{ "STATE",		STATE_WIDTH,	LIST_STATE,	print_list_cb },
143*11767SAnurag.Maskey@Sun.COM 	{ "AUXILIARY STATE",	AUXSTATE_WIDTH,	LIST_AUXSTATE,	print_list_cb },
144*11767SAnurag.Maskey@Sun.COM 	{ NULL,			0,		0,		NULL }
145*11767SAnurag.Maskey@Sun.COM };
146*11767SAnurag.Maskey@Sun.COM 
147*11767SAnurag.Maskey@Sun.COM /* Global variables */
148*11767SAnurag.Maskey@Sun.COM 
149*11767SAnurag.Maskey@Sun.COM /* set early in main(), never modified thereafter, used all over the place */
150*11767SAnurag.Maskey@Sun.COM static char *execname;
151*11767SAnurag.Maskey@Sun.COM 
152*11767SAnurag.Maskey@Sun.COM /* whether the auxilary states are to be printed or not */
153*11767SAnurag.Maskey@Sun.COM static boolean_t extended_list = B_FALSE;
154*11767SAnurag.Maskey@Sun.COM 
155*11767SAnurag.Maskey@Sun.COM /* Functions */
156*11767SAnurag.Maskey@Sun.COM 
157*11767SAnurag.Maskey@Sun.COM static const char *
158*11767SAnurag.Maskey@Sun.COM cmd_to_str(int cmd_num)
159*11767SAnurag.Maskey@Sun.COM {
160*11767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
161*11767SAnurag.Maskey@Sun.COM 	return (cmdtab[cmd_num].cmd_name);
162*11767SAnurag.Maskey@Sun.COM }
163*11767SAnurag.Maskey@Sun.COM 
164*11767SAnurag.Maskey@Sun.COM /* returns description of given command */
165*11767SAnurag.Maskey@Sun.COM static const char *
166*11767SAnurag.Maskey@Sun.COM long_help(int cmd_num)
167*11767SAnurag.Maskey@Sun.COM {
168*11767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
169*11767SAnurag.Maskey@Sun.COM 	return (gettext(cmdtab[cmd_num].cmd_desc));
170*11767SAnurag.Maskey@Sun.COM }
171*11767SAnurag.Maskey@Sun.COM 
172*11767SAnurag.Maskey@Sun.COM /*
173*11767SAnurag.Maskey@Sun.COM  * Called with explicit B_TRUE when help is explicitly required,
174*11767SAnurag.Maskey@Sun.COM  * B_FALSE for errors
175*11767SAnurag.Maskey@Sun.COM  */
176*11767SAnurag.Maskey@Sun.COM static void
177*11767SAnurag.Maskey@Sun.COM usage(boolean_t explicit)
178*11767SAnurag.Maskey@Sun.COM {
179*11767SAnurag.Maskey@Sun.COM 	int	i;
180*11767SAnurag.Maskey@Sun.COM 	FILE	*fd = explicit ? stdout : stderr;
181*11767SAnurag.Maskey@Sun.COM 
182*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(fd, gettext("usage: <subcommand> <args> ...\n"));
183*11767SAnurag.Maskey@Sun.COM 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
184*11767SAnurag.Maskey@Sun.COM 		(void) fprintf(fd, "\t%s\n", cmdtab[i].cmd_usage);
185*11767SAnurag.Maskey@Sun.COM 		if (explicit)
186*11767SAnurag.Maskey@Sun.COM 			(void) fprintf(fd, "\t\t%s\n\n", long_help(i));
187*11767SAnurag.Maskey@Sun.COM 	}
188*11767SAnurag.Maskey@Sun.COM }
189*11767SAnurag.Maskey@Sun.COM 
190*11767SAnurag.Maskey@Sun.COM /* PRINTFLIKE1 */
191*11767SAnurag.Maskey@Sun.COM static void
192*11767SAnurag.Maskey@Sun.COM die(const char *format, ...)
193*11767SAnurag.Maskey@Sun.COM {
194*11767SAnurag.Maskey@Sun.COM 	va_list alist;
195*11767SAnurag.Maskey@Sun.COM 
196*11767SAnurag.Maskey@Sun.COM 	format = gettext(format);
197*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: ", execname);
198*11767SAnurag.Maskey@Sun.COM 
199*11767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
200*11767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
201*11767SAnurag.Maskey@Sun.COM 	va_end(alist);
202*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "\n");
203*11767SAnurag.Maskey@Sun.COM 
204*11767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
205*11767SAnurag.Maskey@Sun.COM }
206*11767SAnurag.Maskey@Sun.COM 
207*11767SAnurag.Maskey@Sun.COM /* PRINTFLIKE2 */
208*11767SAnurag.Maskey@Sun.COM static void
209*11767SAnurag.Maskey@Sun.COM die_nwamerr(nwam_error_t err, const char *format, ...)
210*11767SAnurag.Maskey@Sun.COM {
211*11767SAnurag.Maskey@Sun.COM 	va_list alist;
212*11767SAnurag.Maskey@Sun.COM 
213*11767SAnurag.Maskey@Sun.COM 	format = gettext(format);
214*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: ", execname);
215*11767SAnurag.Maskey@Sun.COM 
216*11767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
217*11767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
218*11767SAnurag.Maskey@Sun.COM 	va_end(alist);
219*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, ": %s\n", nwam_strerror(err));
220*11767SAnurag.Maskey@Sun.COM 
221*11767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
222*11767SAnurag.Maskey@Sun.COM }
223*11767SAnurag.Maskey@Sun.COM 
224*11767SAnurag.Maskey@Sun.COM /* prints the usage for cmd_num and exits */
225*11767SAnurag.Maskey@Sun.COM static void
226*11767SAnurag.Maskey@Sun.COM die_usage(int cmd_num)
227*11767SAnurag.Maskey@Sun.COM {
228*11767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
229*11767SAnurag.Maskey@Sun.COM 
230*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: %s\n", gettext("usage"),
231*11767SAnurag.Maskey@Sun.COM 	    cmdtab[cmd_num].cmd_usage);
232*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "\t%s\n", long_help(cmd_num));
233*11767SAnurag.Maskey@Sun.COM 
234*11767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
235*11767SAnurag.Maskey@Sun.COM }
236*11767SAnurag.Maskey@Sun.COM 
237*11767SAnurag.Maskey@Sun.COM /*
238*11767SAnurag.Maskey@Sun.COM  * Prints the usage and description of all commands
239*11767SAnurag.Maskey@Sun.COM  */
240*11767SAnurag.Maskey@Sun.COM /* ARGSUSED */
241*11767SAnurag.Maskey@Sun.COM static void
242*11767SAnurag.Maskey@Sun.COM help_func(int argc, char *argv[])
243*11767SAnurag.Maskey@Sun.COM {
244*11767SAnurag.Maskey@Sun.COM 	usage(B_TRUE);
245*11767SAnurag.Maskey@Sun.COM }
246*11767SAnurag.Maskey@Sun.COM 
247*11767SAnurag.Maskey@Sun.COM /* determines if the NCP is active or not.  If so, sets arg and halts walk. */
248*11767SAnurag.Maskey@Sun.COM static int
249*11767SAnurag.Maskey@Sun.COM active_ncp_callback(nwam_ncp_handle_t ncph, void *arg)
250*11767SAnurag.Maskey@Sun.COM {
251*11767SAnurag.Maskey@Sun.COM 	char			**namep = arg;
252*11767SAnurag.Maskey@Sun.COM 	nwam_state_t		state = NWAM_STATE_UNINITIALIZED;
253*11767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t	aux;
254*11767SAnurag.Maskey@Sun.COM 
255*11767SAnurag.Maskey@Sun.COM 	(void) nwam_ncp_get_state(ncph, &state, &aux);
256*11767SAnurag.Maskey@Sun.COM 	if (state == NWAM_STATE_ONLINE) {
257*11767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_get_name(ncph, namep) != NWAM_SUCCESS)
258*11767SAnurag.Maskey@Sun.COM 			*namep = NULL;
259*11767SAnurag.Maskey@Sun.COM 		return (1);
260*11767SAnurag.Maskey@Sun.COM 	}
261*11767SAnurag.Maskey@Sun.COM 
262*11767SAnurag.Maskey@Sun.COM 	return (0);
263*11767SAnurag.Maskey@Sun.COM }
264*11767SAnurag.Maskey@Sun.COM 
265*11767SAnurag.Maskey@Sun.COM /* find the currently active NCP and returns its handle */
266*11767SAnurag.Maskey@Sun.COM static nwam_ncp_handle_t
267*11767SAnurag.Maskey@Sun.COM determine_active_ncp()
268*11767SAnurag.Maskey@Sun.COM {
269*11767SAnurag.Maskey@Sun.COM 	char *active_ncp;
270*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
271*11767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
272*11767SAnurag.Maskey@Sun.COM 
273*11767SAnurag.Maskey@Sun.COM 	if (nwam_walk_ncps(active_ncp_callback, &active_ncp, 0, NULL)
274*11767SAnurag.Maskey@Sun.COM 	    == NWAM_WALK_HALTED) {
275*11767SAnurag.Maskey@Sun.COM 		if (active_ncp == NULL)
276*11767SAnurag.Maskey@Sun.COM 			return (NULL);
277*11767SAnurag.Maskey@Sun.COM 
278*11767SAnurag.Maskey@Sun.COM 		/* retrieve the NCP handle */
279*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_read(active_ncp, 0, &ncph);
280*11767SAnurag.Maskey@Sun.COM 		free(active_ncp);
281*11767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS)
282*11767SAnurag.Maskey@Sun.COM 			return (ncph);
283*11767SAnurag.Maskey@Sun.COM 	}
284*11767SAnurag.Maskey@Sun.COM 
285*11767SAnurag.Maskey@Sun.COM 	return (NULL);
286*11767SAnurag.Maskey@Sun.COM }
287*11767SAnurag.Maskey@Sun.COM 
288*11767SAnurag.Maskey@Sun.COM /* check if the given name is a valid loc, test by reading the given loc */
289*11767SAnurag.Maskey@Sun.COM static boolean_t
290*11767SAnurag.Maskey@Sun.COM valid_loc(const char *name)
291*11767SAnurag.Maskey@Sun.COM {
292*11767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch;
293*11767SAnurag.Maskey@Sun.COM 
294*11767SAnurag.Maskey@Sun.COM 	if (nwam_loc_read(name, 0, &loch) != NWAM_SUCCESS)
295*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
296*11767SAnurag.Maskey@Sun.COM 	nwam_loc_free(loch);
297*11767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
298*11767SAnurag.Maskey@Sun.COM }
299*11767SAnurag.Maskey@Sun.COM 
300*11767SAnurag.Maskey@Sun.COM static boolean_t
301*11767SAnurag.Maskey@Sun.COM valid_enm(const char *name)
302*11767SAnurag.Maskey@Sun.COM {
303*11767SAnurag.Maskey@Sun.COM 	nwam_enm_handle_t enmh;
304*11767SAnurag.Maskey@Sun.COM 
305*11767SAnurag.Maskey@Sun.COM 	if (nwam_enm_read(name, 0, &enmh) != NWAM_SUCCESS)
306*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
307*11767SAnurag.Maskey@Sun.COM 	nwam_enm_free(enmh);
308*11767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
309*11767SAnurag.Maskey@Sun.COM }
310*11767SAnurag.Maskey@Sun.COM 
311*11767SAnurag.Maskey@Sun.COM static boolean_t
312*11767SAnurag.Maskey@Sun.COM valid_ncp(const char *name)
313*11767SAnurag.Maskey@Sun.COM {
314*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
315*11767SAnurag.Maskey@Sun.COM 
316*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncp_read(name, 0, &ncph) != NWAM_SUCCESS)
317*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
318*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
319*11767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
320*11767SAnurag.Maskey@Sun.COM }
321*11767SAnurag.Maskey@Sun.COM 
322*11767SAnurag.Maskey@Sun.COM static boolean_t
323*11767SAnurag.Maskey@Sun.COM valid_ncu(const char *name)
324*11767SAnurag.Maskey@Sun.COM {
325*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
326*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
327*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
328*11767SAnurag.Maskey@Sun.COM 
329*11767SAnurag.Maskey@Sun.COM 	if ((ncph = determine_active_ncp()) == NULL)
330*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
331*11767SAnurag.Maskey@Sun.COM 
332*11767SAnurag.Maskey@Sun.COM 	ret = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_ANY, 0, &ncuh);
333*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
334*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS && ret != NWAM_ENTITY_MULTIPLE_VALUES)
335*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
336*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_free(ncuh);
337*11767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
338*11767SAnurag.Maskey@Sun.COM }
339*11767SAnurag.Maskey@Sun.COM 
340*11767SAnurag.Maskey@Sun.COM /*
341*11767SAnurag.Maskey@Sun.COM  * Given a name, returns object type (loc, enm, ncp, or ncu) and how many
342*11767SAnurag.Maskey@Sun.COM  * objects matched that name.
343*11767SAnurag.Maskey@Sun.COM  */
344*11767SAnurag.Maskey@Sun.COM static nwam_object_type_t
345*11767SAnurag.Maskey@Sun.COM determine_object_type(const char *name, int *num)
346*11767SAnurag.Maskey@Sun.COM {
347*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t type;
348*11767SAnurag.Maskey@Sun.COM 	int n = 0;
349*11767SAnurag.Maskey@Sun.COM 
350*11767SAnurag.Maskey@Sun.COM 	/* see if a valid loc, enm, ncp and/or ncu exists with given name */
351*11767SAnurag.Maskey@Sun.COM 	if (valid_loc(name)) {
352*11767SAnurag.Maskey@Sun.COM 		n++;
353*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_LOC;
354*11767SAnurag.Maskey@Sun.COM 	}
355*11767SAnurag.Maskey@Sun.COM 	if (valid_enm(name)) {
356*11767SAnurag.Maskey@Sun.COM 		n++;
357*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_ENM;
358*11767SAnurag.Maskey@Sun.COM 	}
359*11767SAnurag.Maskey@Sun.COM 	if (valid_ncp(name)) {
360*11767SAnurag.Maskey@Sun.COM 		n++;
361*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCP;
362*11767SAnurag.Maskey@Sun.COM 	}
363*11767SAnurag.Maskey@Sun.COM 	if (valid_ncu(name)) {
364*11767SAnurag.Maskey@Sun.COM 		n++;
365*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCU;
366*11767SAnurag.Maskey@Sun.COM 	}
367*11767SAnurag.Maskey@Sun.COM 
368*11767SAnurag.Maskey@Sun.COM 	/* if n > 1, then it means *type was set multiple times, undo it */
369*11767SAnurag.Maskey@Sun.COM 	if (n != 1)
370*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_UNKNOWN;
371*11767SAnurag.Maskey@Sun.COM 
372*11767SAnurag.Maskey@Sun.COM 	*num = n;
373*11767SAnurag.Maskey@Sun.COM 	return (type);
374*11767SAnurag.Maskey@Sun.COM }
375*11767SAnurag.Maskey@Sun.COM 
376*11767SAnurag.Maskey@Sun.COM /*
377*11767SAnurag.Maskey@Sun.COM  * Parses argv array and populates object_type and name.
378*11767SAnurag.Maskey@Sun.COM  * Program exits on failure.
379*11767SAnurag.Maskey@Sun.COM  */
380*11767SAnurag.Maskey@Sun.COM static void
381*11767SAnurag.Maskey@Sun.COM parse_argv(int argc, char *argv[], int cmd_num, nwam_object_type_t *object_type,
382*11767SAnurag.Maskey@Sun.COM     nwam_ncu_type_t *ncu_type, nwam_ncu_class_t *ncu_class, const char **name)
383*11767SAnurag.Maskey@Sun.COM {
384*11767SAnurag.Maskey@Sun.COM 	int			arg;
385*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
386*11767SAnurag.Maskey@Sun.COM 	uint64_t		ncu = NWAM_NCU_TYPE_ANY;
387*11767SAnurag.Maskey@Sun.COM 	uint64_t		class = NWAM_NCU_CLASS_ANY;
388*11767SAnurag.Maskey@Sun.COM 
389*11767SAnurag.Maskey@Sun.COM 	/* check argv for option */
390*11767SAnurag.Maskey@Sun.COM 	optind = 0;
391*11767SAnurag.Maskey@Sun.COM 	while ((arg = getopt(argc, argv, "?p:c:x")) != EOF) {
392*11767SAnurag.Maskey@Sun.COM 		switch (arg) {
393*11767SAnurag.Maskey@Sun.COM 		case 'p':
394*11767SAnurag.Maskey@Sun.COM 			type = nwam_string_to_object_type(optarg);
395*11767SAnurag.Maskey@Sun.COM 			if (type == NWAM_OBJECT_TYPE_UNKNOWN)
396*11767SAnurag.Maskey@Sun.COM 				die("Invalid profile-type: %s", optarg);
397*11767SAnurag.Maskey@Sun.COM 			break;
398*11767SAnurag.Maskey@Sun.COM 		case 'c':
399*11767SAnurag.Maskey@Sun.COM 			if (nwam_value_string_get_uint64(NWAM_NCU_PROP_CLASS,
400*11767SAnurag.Maskey@Sun.COM 			    optarg, &class) != NWAM_SUCCESS) {
401*11767SAnurag.Maskey@Sun.COM 				die("Invalid ncu-class: %s", optarg);
402*11767SAnurag.Maskey@Sun.COM 			}
403*11767SAnurag.Maskey@Sun.COM 			ncu = nwam_ncu_class_to_type(class);
404*11767SAnurag.Maskey@Sun.COM 			if (ncu == NWAM_NCU_TYPE_ANY ||
405*11767SAnurag.Maskey@Sun.COM 			    ncu == NWAM_NCU_TYPE_UNKNOWN)
406*11767SAnurag.Maskey@Sun.COM 				die("Invalid ncu-class: %s", optarg);
407*11767SAnurag.Maskey@Sun.COM 			break;
408*11767SAnurag.Maskey@Sun.COM 		case 'x':
409*11767SAnurag.Maskey@Sun.COM 			/* -x is only for list */
410*11767SAnurag.Maskey@Sun.COM 			if (cmd_num != CMD_LIST)
411*11767SAnurag.Maskey@Sun.COM 				die("-x can only be used with 'list'");
412*11767SAnurag.Maskey@Sun.COM 			extended_list = B_TRUE;
413*11767SAnurag.Maskey@Sun.COM 			break;
414*11767SAnurag.Maskey@Sun.COM 		case '?':
415*11767SAnurag.Maskey@Sun.COM 		default:
416*11767SAnurag.Maskey@Sun.COM 			die_usage(cmd_num);
417*11767SAnurag.Maskey@Sun.COM 		}
418*11767SAnurag.Maskey@Sun.COM 	}
419*11767SAnurag.Maskey@Sun.COM 
420*11767SAnurag.Maskey@Sun.COM 	if (ncu != NWAM_NCU_TYPE_ANY) {
421*11767SAnurag.Maskey@Sun.COM 		/* If -c is given, -p must be NCU. If unspecified, assume NCU */
422*11767SAnurag.Maskey@Sun.COM 		if (type != NWAM_OBJECT_TYPE_UNKNOWN &&
423*11767SAnurag.Maskey@Sun.COM 		    type != NWAM_OBJECT_TYPE_NCU)
424*11767SAnurag.Maskey@Sun.COM 			die("'-c <ncu-class>' can only be used for ncu");
425*11767SAnurag.Maskey@Sun.COM 
426*11767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCU;
427*11767SAnurag.Maskey@Sun.COM 	}
428*11767SAnurag.Maskey@Sun.COM 
429*11767SAnurag.Maskey@Sun.COM 	/* name is mandatory for enable and disable, but not for list */
430*11767SAnurag.Maskey@Sun.COM 	if (optind == (argc-1))
431*11767SAnurag.Maskey@Sun.COM 		*name = argv[optind];
432*11767SAnurag.Maskey@Sun.COM 	else if (argc != optind)
433*11767SAnurag.Maskey@Sun.COM 		die("too many profile names given");
434*11767SAnurag.Maskey@Sun.COM 	else if (cmd_num != CMD_LIST)
435*11767SAnurag.Maskey@Sun.COM 		die("no profile name given");
436*11767SAnurag.Maskey@Sun.COM 
437*11767SAnurag.Maskey@Sun.COM 	/*
438*11767SAnurag.Maskey@Sun.COM 	 * No need to determine type for list.
439*11767SAnurag.Maskey@Sun.COM 	 * If -p is not given for enable or disable, then determine type.
440*11767SAnurag.Maskey@Sun.COM 	 */
441*11767SAnurag.Maskey@Sun.COM 	if (cmd_num != CMD_LIST && type == NWAM_OBJECT_TYPE_UNKNOWN) {
442*11767SAnurag.Maskey@Sun.COM 		int num = 0;
443*11767SAnurag.Maskey@Sun.COM 
444*11767SAnurag.Maskey@Sun.COM 		type = determine_object_type(*name, &num);
445*11767SAnurag.Maskey@Sun.COM 		if (num == 0) {
446*11767SAnurag.Maskey@Sun.COM 			die("no profile matched '%s'", *name);
447*11767SAnurag.Maskey@Sun.COM 		} else if (num > 1) {
448*11767SAnurag.Maskey@Sun.COM 			die("more than one profile matched '%s' - use "
449*11767SAnurag.Maskey@Sun.COM 			    "'-p <profile-type>' to specify a profile type.",
450*11767SAnurag.Maskey@Sun.COM 			    *name);
451*11767SAnurag.Maskey@Sun.COM 		}
452*11767SAnurag.Maskey@Sun.COM 	}
453*11767SAnurag.Maskey@Sun.COM 
454*11767SAnurag.Maskey@Sun.COM 	*object_type = type;
455*11767SAnurag.Maskey@Sun.COM 	*ncu_type = ncu;
456*11767SAnurag.Maskey@Sun.COM 	*ncu_class = class;
457*11767SAnurag.Maskey@Sun.COM }
458*11767SAnurag.Maskey@Sun.COM 
459*11767SAnurag.Maskey@Sun.COM /* Enables/Disables profiles depending on boolean */
460*11767SAnurag.Maskey@Sun.COM static nwam_error_t
461*11767SAnurag.Maskey@Sun.COM loc_action(const char *name, boolean_t enable, char **realnamep)
462*11767SAnurag.Maskey@Sun.COM {
463*11767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch;
464*11767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
465*11767SAnurag.Maskey@Sun.COM 
466*11767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_loc_read(name, 0, &loch)) != NWAM_SUCCESS)
467*11767SAnurag.Maskey@Sun.COM 		return (ret);
468*11767SAnurag.Maskey@Sun.COM 
469*11767SAnurag.Maskey@Sun.COM 	if (enable)
470*11767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_enable(loch);
471*11767SAnurag.Maskey@Sun.COM 	else
472*11767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_disable(loch);
473*11767SAnurag.Maskey@Sun.COM 
474*11767SAnurag.Maskey@Sun.COM 	(void) nwam_loc_get_name(loch, realnamep);
475*11767SAnurag.Maskey@Sun.COM 	nwam_loc_free(loch);
476*11767SAnurag.Maskey@Sun.COM 	return (ret);
477*11767SAnurag.Maskey@Sun.COM }
478*11767SAnurag.Maskey@Sun.COM 
479*11767SAnurag.Maskey@Sun.COM static nwam_error_t
480*11767SAnurag.Maskey@Sun.COM enm_action(const char *name, boolean_t enable, char **realnamep)
481*11767SAnurag.Maskey@Sun.COM {
482*11767SAnurag.Maskey@Sun.COM 	nwam_enm_handle_t enmh;
483*11767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
484*11767SAnurag.Maskey@Sun.COM 
485*11767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_enm_read(name, 0, &enmh)) != NWAM_SUCCESS)
486*11767SAnurag.Maskey@Sun.COM 		return (ret);
487*11767SAnurag.Maskey@Sun.COM 
488*11767SAnurag.Maskey@Sun.COM 	if (enable)
489*11767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_enable(enmh);
490*11767SAnurag.Maskey@Sun.COM 	else
491*11767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_disable(enmh);
492*11767SAnurag.Maskey@Sun.COM 
493*11767SAnurag.Maskey@Sun.COM 	(void) nwam_enm_get_name(enmh, realnamep);
494*11767SAnurag.Maskey@Sun.COM 	nwam_enm_free(enmh);
495*11767SAnurag.Maskey@Sun.COM 	return (ret);
496*11767SAnurag.Maskey@Sun.COM }
497*11767SAnurag.Maskey@Sun.COM 
498*11767SAnurag.Maskey@Sun.COM static nwam_error_t
499*11767SAnurag.Maskey@Sun.COM ncu_action(const char *name, nwam_ncp_handle_t ncph, nwam_ncu_type_t type,
500*11767SAnurag.Maskey@Sun.COM     boolean_t enable, char **realnamep)
501*11767SAnurag.Maskey@Sun.COM {
502*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
503*11767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
504*11767SAnurag.Maskey@Sun.COM 	boolean_t retrieved_ncph = B_FALSE;
505*11767SAnurag.Maskey@Sun.COM 
506*11767SAnurag.Maskey@Sun.COM 	if (ncph == NULL) {
507*11767SAnurag.Maskey@Sun.COM 		if ((ncph = determine_active_ncp()) == NULL)
508*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_FOUND);
509*11767SAnurag.Maskey@Sun.COM 		retrieved_ncph = B_TRUE;
510*11767SAnurag.Maskey@Sun.COM 	}
511*11767SAnurag.Maskey@Sun.COM 
512*11767SAnurag.Maskey@Sun.COM 	ret = nwam_ncu_read(ncph, name, type, 0, &ncuh);
513*11767SAnurag.Maskey@Sun.COM 	switch (ret) {
514*11767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
515*11767SAnurag.Maskey@Sun.COM 		if (enable)
516*11767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_enable(ncuh);
517*11767SAnurag.Maskey@Sun.COM 		else
518*11767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_disable(ncuh);
519*11767SAnurag.Maskey@Sun.COM 		(void) nwam_ncu_get_name(ncuh, realnamep);
520*11767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(ncuh);
521*11767SAnurag.Maskey@Sun.COM 		break;
522*11767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_MULTIPLE_VALUES:
523*11767SAnurag.Maskey@Sun.COM 		/* Call ncu_action() for link and interface types */
524*11767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_LINK, enable,
525*11767SAnurag.Maskey@Sun.COM 		    realnamep);
526*11767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
527*11767SAnurag.Maskey@Sun.COM 			break;
528*11767SAnurag.Maskey@Sun.COM 
529*11767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_INTERFACE, enable,
530*11767SAnurag.Maskey@Sun.COM 		    realnamep);
531*11767SAnurag.Maskey@Sun.COM 		break;
532*11767SAnurag.Maskey@Sun.COM 	}
533*11767SAnurag.Maskey@Sun.COM 	if (retrieved_ncph)
534*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
535*11767SAnurag.Maskey@Sun.COM 
536*11767SAnurag.Maskey@Sun.COM 	return (ret);
537*11767SAnurag.Maskey@Sun.COM }
538*11767SAnurag.Maskey@Sun.COM 
539*11767SAnurag.Maskey@Sun.COM /*
540*11767SAnurag.Maskey@Sun.COM  * If more than one type of profile with the same name, return error.
541*11767SAnurag.Maskey@Sun.COM  * In such situations, the -p option must be used.
542*11767SAnurag.Maskey@Sun.COM  * If a location is enabled when a different one is already enabled, then
543*11767SAnurag.Maskey@Sun.COM  * that location is disabled automatically by nwamd.
544*11767SAnurag.Maskey@Sun.COM  */
545*11767SAnurag.Maskey@Sun.COM static void
546*11767SAnurag.Maskey@Sun.COM enable_func(int argc, char *argv[])
547*11767SAnurag.Maskey@Sun.COM {
548*11767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
549*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
550*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
551*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
552*11767SAnurag.Maskey@Sun.COM 	const char		*name;
553*11767SAnurag.Maskey@Sun.COM 	char			*realname = NULL;
554*11767SAnurag.Maskey@Sun.COM 
555*11767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
556*11767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_ENABLE, &type, &ncu_type, &ncu_class, &name);
557*11767SAnurag.Maskey@Sun.COM 
558*11767SAnurag.Maskey@Sun.COM 	/*
559*11767SAnurag.Maskey@Sun.COM 	 * NCPs and Locations don't need to disable the currently active
560*11767SAnurag.Maskey@Sun.COM 	 * profile - nwamd automatically switches to the new active profile.
561*11767SAnurag.Maskey@Sun.COM 	 * and will disable it if necessary.
562*11767SAnurag.Maskey@Sun.COM 	 */
563*11767SAnurag.Maskey@Sun.COM 
564*11767SAnurag.Maskey@Sun.COM 	/* activate given profile */
565*11767SAnurag.Maskey@Sun.COM 	switch (type) {
566*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
567*11767SAnurag.Maskey@Sun.COM 		ret = loc_action(name, B_TRUE, &realname);
568*11767SAnurag.Maskey@Sun.COM 		break;
569*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
570*11767SAnurag.Maskey@Sun.COM 		ret = enm_action(name, B_TRUE, &realname);
571*11767SAnurag.Maskey@Sun.COM 		break;
572*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
573*11767SAnurag.Maskey@Sun.COM 	{
574*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_handle_t ncph;
575*11767SAnurag.Maskey@Sun.COM 
576*11767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncp_read(name, 0, &ncph)) != NWAM_SUCCESS)
577*11767SAnurag.Maskey@Sun.COM 			break;
578*11767SAnurag.Maskey@Sun.COM 
579*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_enable(ncph);
580*11767SAnurag.Maskey@Sun.COM 		(void) nwam_ncp_get_name(ncph, &realname);
581*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
582*11767SAnurag.Maskey@Sun.COM 		break;
583*11767SAnurag.Maskey@Sun.COM 	}
584*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
585*11767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, NULL, ncu_type, B_TRUE, &realname);
586*11767SAnurag.Maskey@Sun.COM 		break;
587*11767SAnurag.Maskey@Sun.COM 	}
588*11767SAnurag.Maskey@Sun.COM 
589*11767SAnurag.Maskey@Sun.COM 	switch (ret) {
590*11767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
591*11767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Enabling %s '%s'\n"),
592*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
593*11767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
594*11767SAnurag.Maskey@Sun.COM 		break;
595*11767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_MANUAL:
596*11767SAnurag.Maskey@Sun.COM 		die("Only profiles with manual activation-mode can be enabled");
597*11767SAnurag.Maskey@Sun.COM 		break;
598*11767SAnurag.Maskey@Sun.COM 	default:
599*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "Could not enable %s '%s'",
600*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
601*11767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
602*11767SAnurag.Maskey@Sun.COM 	}
603*11767SAnurag.Maskey@Sun.COM 	free(realname);
604*11767SAnurag.Maskey@Sun.COM }
605*11767SAnurag.Maskey@Sun.COM 
606*11767SAnurag.Maskey@Sun.COM /*
607*11767SAnurag.Maskey@Sun.COM  * Disables a given profile.  Similar to enable, the -p option must be used
608*11767SAnurag.Maskey@Sun.COM  * if more than one type of profile is matched by the given name.
609*11767SAnurag.Maskey@Sun.COM  */
610*11767SAnurag.Maskey@Sun.COM static void
611*11767SAnurag.Maskey@Sun.COM disable_func(int argc, char *argv[])
612*11767SAnurag.Maskey@Sun.COM {
613*11767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
614*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
615*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
616*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
617*11767SAnurag.Maskey@Sun.COM 	const char		*name;
618*11767SAnurag.Maskey@Sun.COM 	char			*realname = NULL;
619*11767SAnurag.Maskey@Sun.COM 
620*11767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
621*11767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_DISABLE, &type, &ncu_type, &ncu_class,
622*11767SAnurag.Maskey@Sun.COM 	    &name);
623*11767SAnurag.Maskey@Sun.COM 
624*11767SAnurag.Maskey@Sun.COM 	/* deactivate the given profile */
625*11767SAnurag.Maskey@Sun.COM 	switch (type) {
626*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
627*11767SAnurag.Maskey@Sun.COM 		ret = loc_action(name, B_FALSE, &realname);
628*11767SAnurag.Maskey@Sun.COM 		break;
629*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
630*11767SAnurag.Maskey@Sun.COM 		ret = enm_action(name, B_FALSE, &realname);
631*11767SAnurag.Maskey@Sun.COM 		break;
632*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
633*11767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, NULL, ncu_type, B_FALSE, &realname);
634*11767SAnurag.Maskey@Sun.COM 		break;
635*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
636*11767SAnurag.Maskey@Sun.COM 		die("ncp's cannot be disabled.  Enable a different ncp to "
637*11767SAnurag.Maskey@Sun.COM 		    "switch to that ncp");
638*11767SAnurag.Maskey@Sun.COM 	}
639*11767SAnurag.Maskey@Sun.COM 
640*11767SAnurag.Maskey@Sun.COM 	switch (ret) {
641*11767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
642*11767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Disabling %s '%s'\n"),
643*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
644*11767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
645*11767SAnurag.Maskey@Sun.COM 		break;
646*11767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_MANUAL:
647*11767SAnurag.Maskey@Sun.COM 		die("Only profiles with manual activation-mode can be "
648*11767SAnurag.Maskey@Sun.COM 		    "disabled");
649*11767SAnurag.Maskey@Sun.COM 		break;
650*11767SAnurag.Maskey@Sun.COM 	default:
651*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "Could not disable %s '%s'",
652*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
653*11767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
654*11767SAnurag.Maskey@Sun.COM 	}
655*11767SAnurag.Maskey@Sun.COM 	free(realname);
656*11767SAnurag.Maskey@Sun.COM }
657*11767SAnurag.Maskey@Sun.COM 
658*11767SAnurag.Maskey@Sun.COM /* prints each column */
659*11767SAnurag.Maskey@Sun.COM static boolean_t
660*11767SAnurag.Maskey@Sun.COM print_list_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
661*11767SAnurag.Maskey@Sun.COM {
662*11767SAnurag.Maskey@Sun.COM 	profile_entry_t *pent = ofarg->ofmt_cbarg;
663*11767SAnurag.Maskey@Sun.COM 
664*11767SAnurag.Maskey@Sun.COM 	switch (ofarg->ofmt_id) {
665*11767SAnurag.Maskey@Sun.COM 	case LIST_TYPE:
666*11767SAnurag.Maskey@Sun.COM 		/* ncu:ip or ncu:phys for NCUs; ncp, loc, enm for others */
667*11767SAnurag.Maskey@Sun.COM 		if (pent->p_type == NWAM_OBJECT_TYPE_NCU) {
668*11767SAnurag.Maskey@Sun.COM 			const char *class;
669*11767SAnurag.Maskey@Sun.COM 			if (nwam_uint64_get_value_string(NWAM_NCU_PROP_CLASS,
670*11767SAnurag.Maskey@Sun.COM 			    pent->p_ncu_class, &class) != NWAM_SUCCESS)
671*11767SAnurag.Maskey@Sun.COM 				class = ""; /* empty */
672*11767SAnurag.Maskey@Sun.COM 			(void) snprintf(buf, bufsize, "%s:%s",
673*11767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(pent->p_type), class);
674*11767SAnurag.Maskey@Sun.COM 		} else {
675*11767SAnurag.Maskey@Sun.COM 			(void) strlcpy(buf,
676*11767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(pent->p_type), bufsize);
677*11767SAnurag.Maskey@Sun.COM 		}
678*11767SAnurag.Maskey@Sun.COM 		break;
679*11767SAnurag.Maskey@Sun.COM 	case LIST_PROFILE:
680*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf, pent->p_name, bufsize);
681*11767SAnurag.Maskey@Sun.COM 		break;
682*11767SAnurag.Maskey@Sun.COM 	case LIST_STATE:
683*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf, nwam_state_to_string(pent->p_state),
684*11767SAnurag.Maskey@Sun.COM 		    bufsize);
685*11767SAnurag.Maskey@Sun.COM 		break;
686*11767SAnurag.Maskey@Sun.COM 	case LIST_AUXSTATE:
687*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf,
688*11767SAnurag.Maskey@Sun.COM 		    nwam_aux_state_to_string(pent->p_aux_state), bufsize);
689*11767SAnurag.Maskey@Sun.COM 		break;
690*11767SAnurag.Maskey@Sun.COM 	default:
691*11767SAnurag.Maskey@Sun.COM 		die("invalid print_list_cb() input: %d", ofarg->ofmt_id);
692*11767SAnurag.Maskey@Sun.COM 		break;
693*11767SAnurag.Maskey@Sun.COM 	}
694*11767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
695*11767SAnurag.Maskey@Sun.COM }
696*11767SAnurag.Maskey@Sun.COM 
697*11767SAnurag.Maskey@Sun.COM /* returns the state and auxilliary state of the object */
698*11767SAnurag.Maskey@Sun.COM static nwam_state_t
699*11767SAnurag.Maskey@Sun.COM determine_object_state(nwam_object_type_t type, void *handle,
700*11767SAnurag.Maskey@Sun.COM     nwam_aux_state_t *aux_statep)
701*11767SAnurag.Maskey@Sun.COM {
702*11767SAnurag.Maskey@Sun.COM 	nwam_state_t state;
703*11767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t astate;
704*11767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
705*11767SAnurag.Maskey@Sun.COM 
706*11767SAnurag.Maskey@Sun.COM 	switch (type) {
707*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
708*11767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_state(handle, &state, &astate);
709*11767SAnurag.Maskey@Sun.COM 		break;
710*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
711*11767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_state(handle, &state, &astate);
712*11767SAnurag.Maskey@Sun.COM 		break;
713*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
714*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_get_state(handle, &state, &astate);
715*11767SAnurag.Maskey@Sun.COM 		break;
716*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
717*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_state(handle, &state, &astate);
718*11767SAnurag.Maskey@Sun.COM 		break;
719*11767SAnurag.Maskey@Sun.COM 	default:
720*11767SAnurag.Maskey@Sun.COM 		/* NOTREACHED */
721*11767SAnurag.Maskey@Sun.COM 		break;
722*11767SAnurag.Maskey@Sun.COM 	}
723*11767SAnurag.Maskey@Sun.COM 
724*11767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_PERMISSION_DENIED) {
725*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not get object state");
726*11767SAnurag.Maskey@Sun.COM 	} else if (ret != NWAM_SUCCESS) {
727*11767SAnurag.Maskey@Sun.COM 		state = NWAM_STATE_UNINITIALIZED;
728*11767SAnurag.Maskey@Sun.COM 		astate = NWAM_AUX_STATE_UNINITIALIZED;
729*11767SAnurag.Maskey@Sun.COM 	}
730*11767SAnurag.Maskey@Sun.COM 
731*11767SAnurag.Maskey@Sun.COM 	if (aux_statep != NULL)
732*11767SAnurag.Maskey@Sun.COM 		*aux_statep = astate;
733*11767SAnurag.Maskey@Sun.COM 	return (state);
734*11767SAnurag.Maskey@Sun.COM }
735*11767SAnurag.Maskey@Sun.COM 
736*11767SAnurag.Maskey@Sun.COM /* populate profile_entry_t with values for object with given handle */
737*11767SAnurag.Maskey@Sun.COM static int
738*11767SAnurag.Maskey@Sun.COM add_to_profile_entry(nwam_object_type_t type, void *handle,
739*11767SAnurag.Maskey@Sun.COM     profile_entry_t *pent)
740*11767SAnurag.Maskey@Sun.COM {
741*11767SAnurag.Maskey@Sun.COM 	char		*name;
742*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
743*11767SAnurag.Maskey@Sun.COM 
744*11767SAnurag.Maskey@Sun.COM 	pent->p_type = type;
745*11767SAnurag.Maskey@Sun.COM 	if (type == NWAM_OBJECT_TYPE_NCU) {
746*11767SAnurag.Maskey@Sun.COM 		nwam_ncu_class_t class;
747*11767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_class(handle, &class))
748*11767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
749*11767SAnurag.Maskey@Sun.COM 			return (ret);
750*11767SAnurag.Maskey@Sun.COM 		pent->p_ncu_class = class;
751*11767SAnurag.Maskey@Sun.COM 	} else {
752*11767SAnurag.Maskey@Sun.COM 		pent->p_ncu_class = -1;
753*11767SAnurag.Maskey@Sun.COM 	}
754*11767SAnurag.Maskey@Sun.COM 
755*11767SAnurag.Maskey@Sun.COM 	switch (type) {
756*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
757*11767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_name(handle, &name);
758*11767SAnurag.Maskey@Sun.COM 		break;
759*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
760*11767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_name(handle, &name);
761*11767SAnurag.Maskey@Sun.COM 		break;
762*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
763*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_get_name(handle, &name);
764*11767SAnurag.Maskey@Sun.COM 		break;
765*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
766*11767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_name(handle, &name);
767*11767SAnurag.Maskey@Sun.COM 		break;
768*11767SAnurag.Maskey@Sun.COM 	default:
769*11767SAnurag.Maskey@Sun.COM 		/* NOTREACHED */
770*11767SAnurag.Maskey@Sun.COM 		break;
771*11767SAnurag.Maskey@Sun.COM 	}
772*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
773*11767SAnurag.Maskey@Sun.COM 		return (ret);
774*11767SAnurag.Maskey@Sun.COM 	}
775*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(pent->p_name, name, sizeof (pent->p_name));
776*11767SAnurag.Maskey@Sun.COM 	free(name);
777*11767SAnurag.Maskey@Sun.COM 
778*11767SAnurag.Maskey@Sun.COM 	pent->p_state = determine_object_state(type, handle,
779*11767SAnurag.Maskey@Sun.COM 	    &pent->p_aux_state);
780*11767SAnurag.Maskey@Sun.COM 
781*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
782*11767SAnurag.Maskey@Sun.COM }
783*11767SAnurag.Maskey@Sun.COM 
784*11767SAnurag.Maskey@Sun.COM /* callback functions used by walk */
785*11767SAnurag.Maskey@Sun.COM 
786*11767SAnurag.Maskey@Sun.COM static int
787*11767SAnurag.Maskey@Sun.COM list_ncu_cb(nwam_ncu_handle_t ncuh, void *arg)
788*11767SAnurag.Maskey@Sun.COM {
789*11767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
790*11767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
791*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
792*11767SAnurag.Maskey@Sun.COM 
793*11767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
794*11767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCU, ncuh, &pent);
795*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
796*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add ncu to list");
797*11767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
798*11767SAnurag.Maskey@Sun.COM 	return (0);
799*11767SAnurag.Maskey@Sun.COM }
800*11767SAnurag.Maskey@Sun.COM 
801*11767SAnurag.Maskey@Sun.COM static int
802*11767SAnurag.Maskey@Sun.COM list_ncp_cb(nwam_ncp_handle_t ncph, void *arg)
803*11767SAnurag.Maskey@Sun.COM {
804*11767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
805*11767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
806*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
807*11767SAnurag.Maskey@Sun.COM 	nwam_state_t	state;
808*11767SAnurag.Maskey@Sun.COM 
809*11767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
810*11767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCP, ncph, &pent);
811*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
812*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add ncp to list");
813*11767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
814*11767SAnurag.Maskey@Sun.COM 
815*11767SAnurag.Maskey@Sun.COM 	state = determine_object_state(NWAM_OBJECT_TYPE_NCP, ncph, NULL);
816*11767SAnurag.Maskey@Sun.COM 	if (state == NWAM_STATE_ONLINE) {
817*11767SAnurag.Maskey@Sun.COM 		(void) nwam_ncp_walk_ncus(ncph, list_ncu_cb, ofmt,
818*11767SAnurag.Maskey@Sun.COM 		    NWAM_FLAG_NCU_TYPE_ALL, NULL);
819*11767SAnurag.Maskey@Sun.COM 	}
820*11767SAnurag.Maskey@Sun.COM 	return (0);
821*11767SAnurag.Maskey@Sun.COM }
822*11767SAnurag.Maskey@Sun.COM 
823*11767SAnurag.Maskey@Sun.COM static int
824*11767SAnurag.Maskey@Sun.COM list_loc_cb(nwam_loc_handle_t loch, void *arg)
825*11767SAnurag.Maskey@Sun.COM {
826*11767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
827*11767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
828*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
829*11767SAnurag.Maskey@Sun.COM 
830*11767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
831*11767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_LOC, loch, &pent);
832*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
833*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add loc to list");
834*11767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
835*11767SAnurag.Maskey@Sun.COM 	return (0);
836*11767SAnurag.Maskey@Sun.COM }
837*11767SAnurag.Maskey@Sun.COM 
838*11767SAnurag.Maskey@Sun.COM static int
839*11767SAnurag.Maskey@Sun.COM list_enm_cb(nwam_enm_handle_t enmh, void *arg)
840*11767SAnurag.Maskey@Sun.COM {
841*11767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
842*11767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
843*11767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
844*11767SAnurag.Maskey@Sun.COM 
845*11767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
846*11767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_ENM, enmh, &pent);
847*11767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
848*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add enm to list");
849*11767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
850*11767SAnurag.Maskey@Sun.COM 	return (0);
851*11767SAnurag.Maskey@Sun.COM }
852*11767SAnurag.Maskey@Sun.COM 
853*11767SAnurag.Maskey@Sun.COM /*
854*11767SAnurag.Maskey@Sun.COM  * lists all profiles and their state
855*11767SAnurag.Maskey@Sun.COM  */
856*11767SAnurag.Maskey@Sun.COM static void
857*11767SAnurag.Maskey@Sun.COM list_func(int argc, char *argv[])
858*11767SAnurag.Maskey@Sun.COM {
859*11767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret = NWAM_SUCCESS;
860*11767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
861*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
862*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
863*11767SAnurag.Maskey@Sun.COM 	char			*name = NULL;
864*11767SAnurag.Maskey@Sun.COM 
865*11767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt;
866*11767SAnurag.Maskey@Sun.COM 	ofmt_status_t	oferr;
867*11767SAnurag.Maskey@Sun.COM 	char		*default_fields = "type,profile,state";
868*11767SAnurag.Maskey@Sun.COM 	char		*extended_fields = "type,profile,state,auxiliary state";
869*11767SAnurag.Maskey@Sun.COM 	char		*fields = NULL;
870*11767SAnurag.Maskey@Sun.COM 
871*11767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
872*11767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_LIST, &type, &ncu_type, &ncu_class,
873*11767SAnurag.Maskey@Sun.COM 	    (const char **)&name);
874*11767SAnurag.Maskey@Sun.COM 
875*11767SAnurag.Maskey@Sun.COM 	if (extended_list)
876*11767SAnurag.Maskey@Sun.COM 		fields = extended_fields;
877*11767SAnurag.Maskey@Sun.COM 	else
878*11767SAnurag.Maskey@Sun.COM 		fields = default_fields;
879*11767SAnurag.Maskey@Sun.COM 	oferr = ofmt_open(fields, list_fields, 0, 0, &ofmt);
880*11767SAnurag.Maskey@Sun.COM 	if (oferr != OFMT_SUCCESS) {
881*11767SAnurag.Maskey@Sun.COM 		char buf[OFMT_BUFSIZE];
882*11767SAnurag.Maskey@Sun.COM 		(void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
883*11767SAnurag.Maskey@Sun.COM 		die("ofmt_open() failed: %s", buf);
884*11767SAnurag.Maskey@Sun.COM 	}
885*11767SAnurag.Maskey@Sun.COM 
886*11767SAnurag.Maskey@Sun.COM 	/* object-name given in command-line */
887*11767SAnurag.Maskey@Sun.COM 	if (name != NULL) {
888*11767SAnurag.Maskey@Sun.COM 		boolean_t found = B_FALSE;
889*11767SAnurag.Maskey@Sun.COM 
890*11767SAnurag.Maskey@Sun.COM 		/*
891*11767SAnurag.Maskey@Sun.COM 		 * If objects with different types have the same name
892*11767SAnurag.Maskey@Sun.COM 		 * (type = UNKNOWN), then try to open handle for each object
893*11767SAnurag.Maskey@Sun.COM 		 * and print if successful.
894*11767SAnurag.Maskey@Sun.COM 		 */
895*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCP ||
896*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
897*11767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
898*11767SAnurag.Maskey@Sun.COM 			if (nwam_ncp_read(name, 0, &ncph) == NWAM_SUCCESS) {
899*11767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
900*11767SAnurag.Maskey@Sun.COM 				(void) list_ncp_cb(ncph, ofmt);
901*11767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
902*11767SAnurag.Maskey@Sun.COM 			}
903*11767SAnurag.Maskey@Sun.COM 		}
904*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCU ||
905*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
906*11767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
907*11767SAnurag.Maskey@Sun.COM 			nwam_ncu_handle_t ncuh;
908*11767SAnurag.Maskey@Sun.COM 
909*11767SAnurag.Maskey@Sun.COM 			if ((ncph = determine_active_ncp()) != NULL) {
910*11767SAnurag.Maskey@Sun.COM 				ret = nwam_ncu_read(ncph, name, ncu_type, 0,
911*11767SAnurag.Maskey@Sun.COM 				    &ncuh);
912*11767SAnurag.Maskey@Sun.COM 				if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
913*11767SAnurag.Maskey@Sun.COM 					found = B_TRUE;
914*11767SAnurag.Maskey@Sun.COM 					if (nwam_ncu_read(ncph, name,
915*11767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_LINK, 0, &ncuh)
916*11767SAnurag.Maskey@Sun.COM 					    == NWAM_SUCCESS) {
917*11767SAnurag.Maskey@Sun.COM 						(void) list_ncu_cb(ncuh, ofmt);
918*11767SAnurag.Maskey@Sun.COM 						nwam_ncu_free(ncuh);
919*11767SAnurag.Maskey@Sun.COM 					}
920*11767SAnurag.Maskey@Sun.COM 					if (nwam_ncu_read(ncph, name,
921*11767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_INTERFACE, 0, &ncuh)
922*11767SAnurag.Maskey@Sun.COM 					    == NWAM_SUCCESS) {
923*11767SAnurag.Maskey@Sun.COM 						(void) list_ncu_cb(ncuh, ofmt);
924*11767SAnurag.Maskey@Sun.COM 						nwam_ncu_free(ncuh);
925*11767SAnurag.Maskey@Sun.COM 					}
926*11767SAnurag.Maskey@Sun.COM 				} else if (ret == NWAM_SUCCESS) {
927*11767SAnurag.Maskey@Sun.COM 					found = B_TRUE;
928*11767SAnurag.Maskey@Sun.COM 					(void) list_ncu_cb(ncuh, ofmt);
929*11767SAnurag.Maskey@Sun.COM 					nwam_ncu_free(ncuh);
930*11767SAnurag.Maskey@Sun.COM 				}
931*11767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
932*11767SAnurag.Maskey@Sun.COM 			}
933*11767SAnurag.Maskey@Sun.COM 		}
934*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_LOC ||
935*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
936*11767SAnurag.Maskey@Sun.COM 			nwam_loc_handle_t loch;
937*11767SAnurag.Maskey@Sun.COM 			if (nwam_loc_read(name, 0, &loch) == NWAM_SUCCESS) {
938*11767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
939*11767SAnurag.Maskey@Sun.COM 				(void) list_loc_cb(loch, ofmt);
940*11767SAnurag.Maskey@Sun.COM 				nwam_loc_free(loch);
941*11767SAnurag.Maskey@Sun.COM 			}
942*11767SAnurag.Maskey@Sun.COM 		}
943*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_ENM ||
944*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
945*11767SAnurag.Maskey@Sun.COM 			nwam_enm_handle_t enmh;
946*11767SAnurag.Maskey@Sun.COM 			if (nwam_enm_read(name, 0, &enmh) == NWAM_SUCCESS) {
947*11767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
948*11767SAnurag.Maskey@Sun.COM 				(void) list_enm_cb(enmh, ofmt);
949*11767SAnurag.Maskey@Sun.COM 				nwam_enm_free(enmh);
950*11767SAnurag.Maskey@Sun.COM 			}
951*11767SAnurag.Maskey@Sun.COM 		}
952*11767SAnurag.Maskey@Sun.COM 		/* If at least object is found, don't return error */
953*11767SAnurag.Maskey@Sun.COM 		if (found)
954*11767SAnurag.Maskey@Sun.COM 			ret = NWAM_SUCCESS;
955*11767SAnurag.Maskey@Sun.COM 		else
956*11767SAnurag.Maskey@Sun.COM 			ret = NWAM_ENTITY_NOT_FOUND;
957*11767SAnurag.Maskey@Sun.COM 	}
958*11767SAnurag.Maskey@Sun.COM 
959*11767SAnurag.Maskey@Sun.COM 	/* object-name not given in command-line */
960*11767SAnurag.Maskey@Sun.COM 	if (name == NULL) {
961*11767SAnurag.Maskey@Sun.COM 		/*
962*11767SAnurag.Maskey@Sun.COM 		 * If type given (type != UNKNOWN), just walk objects in that
963*11767SAnurag.Maskey@Sun.COM 		 * type.  Otherwise, walk all ncp, ncu, loc and enm.
964*11767SAnurag.Maskey@Sun.COM 		 */
965*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCP ||
966*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
967*11767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_ncps(list_ncp_cb, ofmt, 0, NULL);
968*11767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
969*11767SAnurag.Maskey@Sun.COM 				goto done;
970*11767SAnurag.Maskey@Sun.COM 		}
971*11767SAnurag.Maskey@Sun.COM 		/* no UNKNOWN for NCUs.  They walked with active NCP above */
972*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCU) {
973*11767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
974*11767SAnurag.Maskey@Sun.COM 			if ((ncph = determine_active_ncp()) != NULL) {
975*11767SAnurag.Maskey@Sun.COM 				ret = nwam_ncp_walk_ncus(ncph, list_ncu_cb,
976*11767SAnurag.Maskey@Sun.COM 				    ofmt, nwam_ncu_class_to_flag(ncu_class),
977*11767SAnurag.Maskey@Sun.COM 				    NULL);
978*11767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
979*11767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
980*11767SAnurag.Maskey@Sun.COM 					goto done;
981*11767SAnurag.Maskey@Sun.COM 			}
982*11767SAnurag.Maskey@Sun.COM 		}
983*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_LOC ||
984*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
985*11767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_locs(list_loc_cb, ofmt,
986*11767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
987*11767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
988*11767SAnurag.Maskey@Sun.COM 				goto done;
989*11767SAnurag.Maskey@Sun.COM 		}
990*11767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_ENM ||
991*11767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
992*11767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_enms(list_enm_cb, ofmt,
993*11767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
994*11767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
995*11767SAnurag.Maskey@Sun.COM 				goto done;
996*11767SAnurag.Maskey@Sun.COM 		}
997*11767SAnurag.Maskey@Sun.COM 	}
998*11767SAnurag.Maskey@Sun.COM 
999*11767SAnurag.Maskey@Sun.COM done:
1000*11767SAnurag.Maskey@Sun.COM 	ofmt_close(ofmt);
1001*11767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_ENTITY_NOT_FOUND && name != NULL)
1002*11767SAnurag.Maskey@Sun.COM 		die("no profile matched '%s'", name);
1003*11767SAnurag.Maskey@Sun.COM 	else if (ret != NWAM_SUCCESS)
1004*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "list failed during walk");
1005*11767SAnurag.Maskey@Sun.COM }
1006*11767SAnurag.Maskey@Sun.COM 
1007*11767SAnurag.Maskey@Sun.COM /*
1008*11767SAnurag.Maskey@Sun.COM  * Print NWAM events.
1009*11767SAnurag.Maskey@Sun.COM  */
1010*11767SAnurag.Maskey@Sun.COM static void
1011*11767SAnurag.Maskey@Sun.COM eventhandler(nwam_event_t event)
1012*11767SAnurag.Maskey@Sun.COM {
1013*11767SAnurag.Maskey@Sun.COM 	char description[DESCRIPTION_WIDTH];
1014*11767SAnurag.Maskey@Sun.COM 	char statestr[DESCRIPTION_WIDTH];
1015*11767SAnurag.Maskey@Sun.COM 	char objstr[DESCRIPTION_WIDTH];
1016*11767SAnurag.Maskey@Sun.COM 	char *object = NULL;
1017*11767SAnurag.Maskey@Sun.COM 	const char *action = NULL;
1018*11767SAnurag.Maskey@Sun.COM 	char *state = NULL;
1019*11767SAnurag.Maskey@Sun.COM 	boolean_t display = B_TRUE;
1020*11767SAnurag.Maskey@Sun.COM 	int i;
1021*11767SAnurag.Maskey@Sun.COM 	nwam_wlan_t *wlans;
1022*11767SAnurag.Maskey@Sun.COM 
1023*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(description, "-", sizeof (description));
1024*11767SAnurag.Maskey@Sun.COM 
1025*11767SAnurag.Maskey@Sun.COM 	switch (event->nwe_type) {
1026*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_ACTION:
1027*11767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
1028*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_action.nwe_action);
1029*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
1030*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string
1031*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_action.nwe_object_type),
1032*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_object_action.nwe_name);
1033*11767SAnurag.Maskey@Sun.COM 		object = objstr;
1034*11767SAnurag.Maskey@Sun.COM 		break;
1035*11767SAnurag.Maskey@Sun.COM 
1036*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_STATE:
1037*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(statestr, sizeof (statestr), "%s, %s",
1038*11767SAnurag.Maskey@Sun.COM 		    nwam_state_to_string
1039*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_state),
1040*11767SAnurag.Maskey@Sun.COM 		    nwam_aux_state_to_string
1041*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_aux_state));
1042*11767SAnurag.Maskey@Sun.COM 		state = statestr;
1043*11767SAnurag.Maskey@Sun.COM 
1044*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
1045*11767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string
1046*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_object_type),
1047*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_object_state.nwe_name);
1048*11767SAnurag.Maskey@Sun.COM 		object = objstr;
1049*11767SAnurag.Maskey@Sun.COM 		break;
1050*11767SAnurag.Maskey@Sun.COM 
1051*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_PRIORITY_GROUP:
1052*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, DESCRIPTION_WIDTH,
1053*11767SAnurag.Maskey@Sun.COM 		    "priority-group: %d",
1054*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_priority_group_info.nwe_priority);
1055*11767SAnurag.Maskey@Sun.COM 		break;
1056*11767SAnurag.Maskey@Sun.COM 
1057*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT:
1058*11767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
1059*11767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
1060*11767SAnurag.Maskey@Sun.COM 		wlans = event->nwe_data.nwe_wlan_info.nwe_wlans;
1061*11767SAnurag.Maskey@Sun.COM 		for (i = 0;
1062*11767SAnurag.Maskey@Sun.COM 		    i < event->nwe_data.nwe_wlan_info.nwe_num_wlans;
1063*11767SAnurag.Maskey@Sun.COM 		    i++) {
1064*11767SAnurag.Maskey@Sun.COM 			(void) snprintf(description, DESCRIPTION_WIDTH,
1065*11767SAnurag.Maskey@Sun.COM 			    "%d: %c%c ESSID %s BSSID %s", i + 1,
1066*11767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_selected ? 'S' : '-',
1067*11767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_connected ? 'C' : '-',
1068*11767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_essid, wlans[i].nww_bssid);
1069*11767SAnurag.Maskey@Sun.COM 			(void) printf("%-*s %-*s\n", EVENT_WIDTH, "-",
1070*11767SAnurag.Maskey@Sun.COM 			    DESCRIPTION_WIDTH, description);
1071*11767SAnurag.Maskey@Sun.COM 		}
1072*11767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
1073*11767SAnurag.Maskey@Sun.COM 		break;
1074*11767SAnurag.Maskey@Sun.COM 
1075*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE:
1076*11767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
1077*11767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
1078*11767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
1079*11767SAnurag.Maskey@Sun.COM 		break;
1080*11767SAnurag.Maskey@Sun.COM 
1081*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_KEY:
1082*11767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
1083*11767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
1084*11767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
1085*11767SAnurag.Maskey@Sun.COM 		break;
1086*11767SAnurag.Maskey@Sun.COM 
1087*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT:
1088*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, DESCRIPTION_WIDTH,
1089*11767SAnurag.Maskey@Sun.COM 		    gettext("connect to WLAN ESSID %s, BSSID %s %s"),
1090*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_essid,
1091*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_bssid,
1092*11767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_connected ?
1093*11767SAnurag.Maskey@Sun.COM 		    "succeeded" : "failed");
1094*11767SAnurag.Maskey@Sun.COM 		break;
1095*11767SAnurag.Maskey@Sun.COM 
1096*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INFO:
1097*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
1098*11767SAnurag.Maskey@Sun.COM 		    "%s", event->nwe_data.nwe_info.nwe_message);
1099*11767SAnurag.Maskey@Sun.COM 		break;
1100*11767SAnurag.Maskey@Sun.COM 
1101*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_ACTION:
1102*11767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
1103*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_if_action.nwe_action);
1104*11767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_if_action.nwe_name;
1105*11767SAnurag.Maskey@Sun.COM 		break;
1106*11767SAnurag.Maskey@Sun.COM 
1107*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_STATE:
1108*11767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_if_state.nwe_name;
1109*11767SAnurag.Maskey@Sun.COM 		if (event->nwe_data.nwe_if_state.nwe_addr_valid) {
1110*11767SAnurag.Maskey@Sun.COM 			struct sockaddr_storage *address =
1111*11767SAnurag.Maskey@Sun.COM 			    &(event->nwe_data.nwe_if_state.nwe_addr);
1112*11767SAnurag.Maskey@Sun.COM 			struct sockaddr_in *v4addr;
1113*11767SAnurag.Maskey@Sun.COM 			struct sockaddr_in6 *v6addr;
1114*11767SAnurag.Maskey@Sun.COM 			char addrstr[NWAM_MAX_VALUE_LEN];
1115*11767SAnurag.Maskey@Sun.COM 
1116*11767SAnurag.Maskey@Sun.COM 			switch (address->ss_family) {
1117*11767SAnurag.Maskey@Sun.COM 			case AF_INET:
1118*11767SAnurag.Maskey@Sun.COM 				v4addr = (struct sockaddr_in *)address;
1119*11767SAnurag.Maskey@Sun.COM 				(void) inet_ntop(AF_INET, &v4addr->sin_addr,
1120*11767SAnurag.Maskey@Sun.COM 				    addrstr, sizeof (addrstr));
1121*11767SAnurag.Maskey@Sun.COM 				break;
1122*11767SAnurag.Maskey@Sun.COM 			case AF_INET6:
1123*11767SAnurag.Maskey@Sun.COM 				v6addr = (struct sockaddr_in6 *)address;
1124*11767SAnurag.Maskey@Sun.COM 				(void) inet_ntop(AF_INET6, &v6addr->sin6_addr,
1125*11767SAnurag.Maskey@Sun.COM 				    addrstr, sizeof (addrstr));
1126*11767SAnurag.Maskey@Sun.COM 				break;
1127*11767SAnurag.Maskey@Sun.COM 			}
1128*11767SAnurag.Maskey@Sun.COM 			(void) snprintf(statestr, sizeof (statestr),
1129*11767SAnurag.Maskey@Sun.COM 			    "index %d flags 0x%x address %s",
1130*11767SAnurag.Maskey@Sun.COM 			    event->nwe_data.nwe_if_state.nwe_index,
1131*11767SAnurag.Maskey@Sun.COM 			    event->nwe_data.nwe_if_state.nwe_flags, addrstr);
1132*11767SAnurag.Maskey@Sun.COM 		} else {
1133*11767SAnurag.Maskey@Sun.COM 			(void) snprintf(statestr, sizeof (statestr),
1134*11767SAnurag.Maskey@Sun.COM 			    "(%d) flags %x",
1135*11767SAnurag.Maskey@Sun.COM 			    event->nwe_data.nwe_if_state.nwe_index,
1136*11767SAnurag.Maskey@Sun.COM 			    event->nwe_data.nwe_if_state.nwe_flags);
1137*11767SAnurag.Maskey@Sun.COM 		}
1138*11767SAnurag.Maskey@Sun.COM 		state = statestr;
1139*11767SAnurag.Maskey@Sun.COM 		break;
1140*11767SAnurag.Maskey@Sun.COM 
1141*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_ACTION:
1142*11767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
1143*11767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_link_action.nwe_action);
1144*11767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_link_action.nwe_name;
1145*11767SAnurag.Maskey@Sun.COM 		break;
1146*11767SAnurag.Maskey@Sun.COM 
1147*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_STATE:
1148*11767SAnurag.Maskey@Sun.COM 		state = event->nwe_data.nwe_link_state.nwe_link_up ?
1149*11767SAnurag.Maskey@Sun.COM 		    "up" : "down";
1150*11767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_link_state.nwe_name;
1151*11767SAnurag.Maskey@Sun.COM 		break;
1152*11767SAnurag.Maskey@Sun.COM 	}
1153*11767SAnurag.Maskey@Sun.COM 
1154*11767SAnurag.Maskey@Sun.COM 	if (object != NULL && action != NULL) {
1155*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
1156*11767SAnurag.Maskey@Sun.COM 		    "%s -> action %s", object, action);
1157*11767SAnurag.Maskey@Sun.COM 	} else if (object != NULL && state != NULL) {
1158*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
1159*11767SAnurag.Maskey@Sun.COM 		    "%s -> state %s", object, state);
1160*11767SAnurag.Maskey@Sun.COM 	}
1161*11767SAnurag.Maskey@Sun.COM 
1162*11767SAnurag.Maskey@Sun.COM 	if (display) {
1163*11767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s %-*s\n", EVENT_WIDTH,
1164*11767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type),
1165*11767SAnurag.Maskey@Sun.COM 		    DESCRIPTION_WIDTH,
1166*11767SAnurag.Maskey@Sun.COM 		    description);
1167*11767SAnurag.Maskey@Sun.COM 	}
1168*11767SAnurag.Maskey@Sun.COM }
1169*11767SAnurag.Maskey@Sun.COM 
1170*11767SAnurag.Maskey@Sun.COM /*
1171*11767SAnurag.Maskey@Sun.COM  * listens for events and displays them via the eventhandler() function above.
1172*11767SAnurag.Maskey@Sun.COM  */
1173*11767SAnurag.Maskey@Sun.COM /* ARGSUSED */
1174*11767SAnurag.Maskey@Sun.COM static void
1175*11767SAnurag.Maskey@Sun.COM show_events_func(int argc, char *argv[])
1176*11767SAnurag.Maskey@Sun.COM {
1177*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1178*11767SAnurag.Maskey@Sun.COM 	nwam_event_t event;
1179*11767SAnurag.Maskey@Sun.COM 
1180*11767SAnurag.Maskey@Sun.COM 	err = nwam_events_init();
1181*11767SAnurag.Maskey@Sun.COM 
1182*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1183*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not bind to receive events");
1184*11767SAnurag.Maskey@Sun.COM 
1185*11767SAnurag.Maskey@Sun.COM 	/* print header */
1186*11767SAnurag.Maskey@Sun.COM 	(void) printf("%-*s %-*s\n", EVENT_WIDTH, "EVENT",
1187*11767SAnurag.Maskey@Sun.COM 	    DESCRIPTION_WIDTH, "DESCRIPTION");
1188*11767SAnurag.Maskey@Sun.COM 
1189*11767SAnurag.Maskey@Sun.COM 	do {
1190*11767SAnurag.Maskey@Sun.COM 		/*
1191*11767SAnurag.Maskey@Sun.COM 		 * Needed for stdout redirection to ensure event output is
1192*11767SAnurag.Maskey@Sun.COM 		 * regularly flushed to file.
1193*11767SAnurag.Maskey@Sun.COM 		 */
1194*11767SAnurag.Maskey@Sun.COM 		(void) fflush(stdout);
1195*11767SAnurag.Maskey@Sun.COM 		err = nwam_event_wait(&event);
1196*11767SAnurag.Maskey@Sun.COM 		if (err == NWAM_SUCCESS) {
1197*11767SAnurag.Maskey@Sun.COM 			eventhandler(event);
1198*11767SAnurag.Maskey@Sun.COM 			nwam_event_free(event);
1199*11767SAnurag.Maskey@Sun.COM 		}
1200*11767SAnurag.Maskey@Sun.COM 	} while (err == NWAM_SUCCESS);
1201*11767SAnurag.Maskey@Sun.COM 	die_nwamerr(err, "event handling stopped");
1202*11767SAnurag.Maskey@Sun.COM }
1203*11767SAnurag.Maskey@Sun.COM 
1204*11767SAnurag.Maskey@Sun.COM /* May need to convert case-insensitive link name match to case-sensitive one */
1205*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1206*11767SAnurag.Maskey@Sun.COM name_to_linkname(char *name, char **linknamep)
1207*11767SAnurag.Maskey@Sun.COM {
1208*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1209*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph = NULL;
1210*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh = NULL;
1211*11767SAnurag.Maskey@Sun.COM 
1212*11767SAnurag.Maskey@Sun.COM 	if ((ncph = determine_active_ncp()) == NULL)
1213*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_FOUND);
1214*11767SAnurag.Maskey@Sun.COM 
1215*11767SAnurag.Maskey@Sun.COM 	err = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK, 0, &ncuh);
1216*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS)
1217*11767SAnurag.Maskey@Sun.COM 		err = nwam_ncu_get_name(ncuh, linknamep);
1218*11767SAnurag.Maskey@Sun.COM 
1219*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
1220*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_free(ncuh);
1221*11767SAnurag.Maskey@Sun.COM 	return (err);
1222*11767SAnurag.Maskey@Sun.COM }
1223*11767SAnurag.Maskey@Sun.COM 
1224*11767SAnurag.Maskey@Sun.COM static void
1225*11767SAnurag.Maskey@Sun.COM scan_wifi_func(int argc, char *argv[])
1226*11767SAnurag.Maskey@Sun.COM {
1227*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1228*11767SAnurag.Maskey@Sun.COM 	char *linkname = NULL;
1229*11767SAnurag.Maskey@Sun.COM 
1230*11767SAnurag.Maskey@Sun.COM 	if (argc != 1)
1231*11767SAnurag.Maskey@Sun.COM 		die_usage(CMD_SCAN_WIFI);
1232*11767SAnurag.Maskey@Sun.COM 
1233*11767SAnurag.Maskey@Sun.COM 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS)
1234*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "scan request failed for %s", argv[0]);
1235*11767SAnurag.Maskey@Sun.COM 
1236*11767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_scan(linkname);
1237*11767SAnurag.Maskey@Sun.COM 
1238*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1239*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "scan request failed for %s", linkname);
1240*11767SAnurag.Maskey@Sun.COM 
1241*11767SAnurag.Maskey@Sun.COM 	free(linkname);
1242*11767SAnurag.Maskey@Sun.COM }
1243*11767SAnurag.Maskey@Sun.COM 
1244*11767SAnurag.Maskey@Sun.COM static void
1245*11767SAnurag.Maskey@Sun.COM select_wifi_func(int argc, char *argv[])
1246*11767SAnurag.Maskey@Sun.COM {
1247*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1248*11767SAnurag.Maskey@Sun.COM 	char *linkname = NULL;
1249*11767SAnurag.Maskey@Sun.COM 	uint_t i, choice, num_wlans = 0;
1250*11767SAnurag.Maskey@Sun.COM 	uint32_t security_mode;
1251*11767SAnurag.Maskey@Sun.COM 	boolean_t have_key = B_FALSE;
1252*11767SAnurag.Maskey@Sun.COM 	nwam_wlan_t *wlans = NULL;
1253*11767SAnurag.Maskey@Sun.COM 	char choicestr[NWAM_MAX_VALUE_LEN];
1254*11767SAnurag.Maskey@Sun.COM 	char modestr[NWAM_MAX_VALUE_LEN];
1255*11767SAnurag.Maskey@Sun.COM 	char essid[NWAM_MAX_VALUE_LEN];
1256*11767SAnurag.Maskey@Sun.COM 	char bssid[NWAM_MAX_VALUE_LEN];
1257*11767SAnurag.Maskey@Sun.COM 
1258*11767SAnurag.Maskey@Sun.COM 	if (argc != 1)
1259*11767SAnurag.Maskey@Sun.COM 		die_usage(CMD_SELECT_WIFI);
1260*11767SAnurag.Maskey@Sun.COM 
1261*11767SAnurag.Maskey@Sun.COM 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS) {
1262*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not retrieve scan results for %s",
1263*11767SAnurag.Maskey@Sun.COM 		    argv[0]);
1264*11767SAnurag.Maskey@Sun.COM 	}
1265*11767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_get_scan_results(linkname, &num_wlans, &wlans);
1266*11767SAnurag.Maskey@Sun.COM 
1267*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
1268*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not retrieve scan results for %s",
1269*11767SAnurag.Maskey@Sun.COM 		    linkname);
1270*11767SAnurag.Maskey@Sun.COM 	}
1271*11767SAnurag.Maskey@Sun.COM 	bssid[0] = '\0';
1272*11767SAnurag.Maskey@Sun.COM 
1273*11767SAnurag.Maskey@Sun.COM 	/* Loop until valid selection made */
1274*11767SAnurag.Maskey@Sun.COM 	for (;;) {
1275*11767SAnurag.Maskey@Sun.COM 		(void) printf("\n");
1276*11767SAnurag.Maskey@Sun.COM 		/* Display WLAN choices for user to select from */
1277*11767SAnurag.Maskey@Sun.COM 		for (i = 0; i < num_wlans; i++) {
1278*11767SAnurag.Maskey@Sun.COM 			(void) printf("%d: ESSID %s BSSID %s\n",
1279*11767SAnurag.Maskey@Sun.COM 			    i + 1, wlans[i].nww_essid, wlans[i].nww_bssid);
1280*11767SAnurag.Maskey@Sun.COM 		}
1281*11767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("%d: Other\n"), i + 1);
1282*11767SAnurag.Maskey@Sun.COM 
1283*11767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("\nChoose WLAN to connect to [1-%d]: "),
1284*11767SAnurag.Maskey@Sun.COM 		    i + 1);
1285*11767SAnurag.Maskey@Sun.COM 
1286*11767SAnurag.Maskey@Sun.COM 		if (fgets(choicestr, sizeof (choicestr), stdin) != NULL &&
1287*11767SAnurag.Maskey@Sun.COM 		    (choice = atoi(choicestr)) >= 1 && choice <= (i + 1))
1288*11767SAnurag.Maskey@Sun.COM 			break;
1289*11767SAnurag.Maskey@Sun.COM 	}
1290*11767SAnurag.Maskey@Sun.COM 
1291*11767SAnurag.Maskey@Sun.COM 	if (choice == i + 1) {
1292*11767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_handle_t kwh = NULL;
1293*11767SAnurag.Maskey@Sun.COM 		nwam_value_t keynameval = NULL;
1294*11767SAnurag.Maskey@Sun.COM 
1295*11767SAnurag.Maskey@Sun.COM 		/* "Other" was selected - ESSID/secmode must be specified. */
1296*11767SAnurag.Maskey@Sun.COM 		do {
1297*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("\nEnter WLAN name: "));
1298*11767SAnurag.Maskey@Sun.COM 			while (fgets(essid, sizeof (essid), stdin) == NULL) {}
1299*11767SAnurag.Maskey@Sun.COM 			essid[strlen(essid) - 1] = '\0';
1300*11767SAnurag.Maskey@Sun.COM 		} while (strspn(essid, " \t") == strlen(essid));
1301*11767SAnurag.Maskey@Sun.COM 
1302*11767SAnurag.Maskey@Sun.COM 		for (;;) {
1303*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("1: None\n"));
1304*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("2: WEP\n"));
1305*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("3: WPA\n"));
1306*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("Enter security mode: "));
1307*11767SAnurag.Maskey@Sun.COM 			if (fgets(modestr, sizeof (choicestr), stdin) != NULL &&
1308*11767SAnurag.Maskey@Sun.COM 			    (security_mode = atoi(modestr)) >= 1 &&
1309*11767SAnurag.Maskey@Sun.COM 			    security_mode <= 3)
1310*11767SAnurag.Maskey@Sun.COM 				break;
1311*11767SAnurag.Maskey@Sun.COM 		}
1312*11767SAnurag.Maskey@Sun.COM 
1313*11767SAnurag.Maskey@Sun.COM 		/*
1314*11767SAnurag.Maskey@Sun.COM 		 * We have to determine if we have a key for this ESSID from
1315*11767SAnurag.Maskey@Sun.COM 		 * the known WLAN list, since we cannot determine this from
1316*11767SAnurag.Maskey@Sun.COM 		 * the scan results.
1317*11767SAnurag.Maskey@Sun.COM 		 */
1318*11767SAnurag.Maskey@Sun.COM 		if (nwam_known_wlan_read(essid, 0, &kwh) == NWAM_SUCCESS &&
1319*11767SAnurag.Maskey@Sun.COM 		    nwam_known_wlan_get_prop_value(kwh,
1320*11767SAnurag.Maskey@Sun.COM 		    NWAM_KNOWN_WLAN_PROP_KEYNAME, &keynameval) == NWAM_SUCCESS)
1321*11767SAnurag.Maskey@Sun.COM 			have_key = B_TRUE;
1322*11767SAnurag.Maskey@Sun.COM 		else
1323*11767SAnurag.Maskey@Sun.COM 			have_key = B_FALSE;
1324*11767SAnurag.Maskey@Sun.COM 
1325*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(keynameval);
1326*11767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_free(kwh);
1327*11767SAnurag.Maskey@Sun.COM 	} else {
1328*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(essid, wlans[choice - 1].nww_essid,
1329*11767SAnurag.Maskey@Sun.COM 		    sizeof (essid));
1330*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(bssid, wlans[choice - 1].nww_bssid,
1331*11767SAnurag.Maskey@Sun.COM 		    sizeof (bssid));
1332*11767SAnurag.Maskey@Sun.COM 		security_mode = wlans[choice - 1].nww_security_mode;
1333*11767SAnurag.Maskey@Sun.COM 		have_key = wlans[choice - 1].nww_have_key;
1334*11767SAnurag.Maskey@Sun.COM 	}
1335*11767SAnurag.Maskey@Sun.COM 
1336*11767SAnurag.Maskey@Sun.COM 	if (security_mode != DLADM_WLAN_SECMODE_NONE && !have_key) {
1337*11767SAnurag.Maskey@Sun.COM 		uint_t keyslot = 1;
1338*11767SAnurag.Maskey@Sun.COM 		char key[NWAM_MAX_VALUE_LEN];
1339*11767SAnurag.Maskey@Sun.COM 		char slotstr[NWAM_MAX_VALUE_LEN];
1340*11767SAnurag.Maskey@Sun.COM 
1341*11767SAnurag.Maskey@Sun.COM 		do {
1342*11767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("\nEnter WLAN key for "
1343*11767SAnurag.Maskey@Sun.COM 			    "ESSID %s: "), essid);
1344*11767SAnurag.Maskey@Sun.COM 			while (fgets(key, sizeof (key), stdin) == NULL) {}
1345*11767SAnurag.Maskey@Sun.COM 			key[strlen(key) - 1] = '\0';
1346*11767SAnurag.Maskey@Sun.COM 		} while (strspn(key, " \t") == strlen(key));
1347*11767SAnurag.Maskey@Sun.COM 
1348*11767SAnurag.Maskey@Sun.COM 		if (security_mode == DLADM_WLAN_SECMODE_WEP) {
1349*11767SAnurag.Maskey@Sun.COM 			for (;;) {
1350*11767SAnurag.Maskey@Sun.COM 				(void) printf(
1351*11767SAnurag.Maskey@Sun.COM 				    gettext("\nEnter key slot [1-4]: "));
1352*11767SAnurag.Maskey@Sun.COM 				if (fgets(slotstr, sizeof (slotstr), stdin)
1353*11767SAnurag.Maskey@Sun.COM 				    != NULL && (keyslot = atoi(slotstr)) >= 1 &&
1354*11767SAnurag.Maskey@Sun.COM 				    keyslot <= 4)
1355*11767SAnurag.Maskey@Sun.COM 					break;
1356*11767SAnurag.Maskey@Sun.COM 			}
1357*11767SAnurag.Maskey@Sun.COM 		}
1358*11767SAnurag.Maskey@Sun.COM 
1359*11767SAnurag.Maskey@Sun.COM 		err = nwam_wlan_set_key(linkname, essid, NULL, security_mode,
1360*11767SAnurag.Maskey@Sun.COM 		    keyslot, key);
1361*11767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS)
1362*11767SAnurag.Maskey@Sun.COM 			die_nwamerr(err, "could not set WiFi key");
1363*11767SAnurag.Maskey@Sun.COM 	}
1364*11767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_select(linkname, essid, bssid[0] != '\0' ? bssid : NULL,
1365*11767SAnurag.Maskey@Sun.COM 	    security_mode, B_TRUE);
1366*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1367*11767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not select WLAN %s", essid);
1368*11767SAnurag.Maskey@Sun.COM 	free(wlans);
1369*11767SAnurag.Maskey@Sun.COM 	free(linkname);
1370*11767SAnurag.Maskey@Sun.COM }
1371*11767SAnurag.Maskey@Sun.COM 
1372*11767SAnurag.Maskey@Sun.COM int
1373*11767SAnurag.Maskey@Sun.COM main(int argc, char *argv[])
1374*11767SAnurag.Maskey@Sun.COM {
1375*11767SAnurag.Maskey@Sun.COM 	int i;
1376*11767SAnurag.Maskey@Sun.COM 	char *state;
1377*11767SAnurag.Maskey@Sun.COM 
1378*11767SAnurag.Maskey@Sun.COM 	(void) setlocale(LC_ALL, "");
1379*11767SAnurag.Maskey@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
1380*11767SAnurag.Maskey@Sun.COM 
1381*11767SAnurag.Maskey@Sun.COM 	if ((execname = strrchr(argv[0], '/')) == NULL)
1382*11767SAnurag.Maskey@Sun.COM 		execname = argv[0];
1383*11767SAnurag.Maskey@Sun.COM 	else
1384*11767SAnurag.Maskey@Sun.COM 		execname++;
1385*11767SAnurag.Maskey@Sun.COM 
1386*11767SAnurag.Maskey@Sun.COM 	if (argc < 2) {
1387*11767SAnurag.Maskey@Sun.COM 		usage(B_FALSE);
1388*11767SAnurag.Maskey@Sun.COM 		exit(EXIT_FAILURE);
1389*11767SAnurag.Maskey@Sun.COM 	}
1390*11767SAnurag.Maskey@Sun.COM 
1391*11767SAnurag.Maskey@Sun.COM 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
1392*11767SAnurag.Maskey@Sun.COM 		if (strcmp(argv[1], cmd_to_str(i)) == 0) {
1393*11767SAnurag.Maskey@Sun.COM 			if (cmdtab[i].cmd_needs_nwamd) {
1394*11767SAnurag.Maskey@Sun.COM 				state = smf_get_state(NWAM_FMRI);
1395*11767SAnurag.Maskey@Sun.COM 				if (state == NULL || strcmp(state,
1396*11767SAnurag.Maskey@Sun.COM 				    SCF_STATE_STRING_ONLINE) != 0) {
1397*11767SAnurag.Maskey@Sun.COM 					free(state);
1398*11767SAnurag.Maskey@Sun.COM 					die("enable '%s' to use '%s %s'",
1399*11767SAnurag.Maskey@Sun.COM 					    NWAM_FMRI, execname,
1400*11767SAnurag.Maskey@Sun.COM 					    cmd_to_str(cmdtab[i].cmd_num));
1401*11767SAnurag.Maskey@Sun.COM 				}
1402*11767SAnurag.Maskey@Sun.COM 				free(state);
1403*11767SAnurag.Maskey@Sun.COM 			}
1404*11767SAnurag.Maskey@Sun.COM 
1405*11767SAnurag.Maskey@Sun.COM 			cmdtab[i].cmd_handler(argc - 2, &(argv[2]));
1406*11767SAnurag.Maskey@Sun.COM 
1407*11767SAnurag.Maskey@Sun.COM 			exit(EXIT_SUCCESS);
1408*11767SAnurag.Maskey@Sun.COM 		}
1409*11767SAnurag.Maskey@Sun.COM 	}
1410*11767SAnurag.Maskey@Sun.COM 
1411*11767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
1412*11767SAnurag.Maskey@Sun.COM 	    execname, argv[1]);
1413*11767SAnurag.Maskey@Sun.COM 	usage(B_FALSE);
1414*11767SAnurag.Maskey@Sun.COM 
1415*11767SAnurag.Maskey@Sun.COM 	return (1);
1416*11767SAnurag.Maskey@Sun.COM }
1417