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