16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
2319cbc0aaSAnurag S. Maskey  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
246ba597c5SAnurag S. Maskey  */
256ba597c5SAnurag S. Maskey 
266ba597c5SAnurag S. Maskey /*
276ba597c5SAnurag S. Maskey  * nwamadm is a command interpreter to administer NWAM profiles.  It
286ba597c5SAnurag S. Maskey  * is all in C (i.e., no lex/yacc), and all the argument passing is
296ba597c5SAnurag S. Maskey  * argc/argv based.  main() calls the command's handler function,
306ba597c5SAnurag S. Maskey  * which first calls parse_argv() to parse the input arguments and set
316ba597c5SAnurag S. Maskey  * approriate variables for each command.  The rest of the program is
326ba597c5SAnurag S. Maskey  * helper functions for the handler functions.
336ba597c5SAnurag S. Maskey  */
346ba597c5SAnurag S. Maskey 
356ba597c5SAnurag S. Maskey #include <arpa/inet.h>
366ba597c5SAnurag S. Maskey #include <assert.h>
376ba597c5SAnurag S. Maskey #include <errno.h>
386ba597c5SAnurag S. Maskey #include <libdlwlan.h>
39*f6da83d4SAnurag S. Maskey #include <libinetutil.h>
406ba597c5SAnurag S. Maskey #include <libnwam.h>
416ba597c5SAnurag S. Maskey #include <libscf.h>
426ba597c5SAnurag S. Maskey #include <locale.h>
436ba597c5SAnurag S. Maskey #include <netinet/in.h>
446ba597c5SAnurag S. Maskey #include <ofmt.h>
456ba597c5SAnurag S. Maskey #include <stdarg.h>
466ba597c5SAnurag S. Maskey #include <stdio.h>
476ba597c5SAnurag S. Maskey #include <stdlib.h>
486ba597c5SAnurag S. Maskey #include <string.h>
496ba597c5SAnurag S. Maskey #include <strings.h>
506ba597c5SAnurag S. Maskey #include <sys/socket.h>
516ba597c5SAnurag S. Maskey #include <sys/types.h>
526ba597c5SAnurag S. Maskey #include <unistd.h>
536ba597c5SAnurag S. Maskey 
546ba597c5SAnurag S. Maskey #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
556ba597c5SAnurag S. Maskey #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
566ba597c5SAnurag S. Maskey #endif
576ba597c5SAnurag S. Maskey 
586ba597c5SAnurag S. Maskey typedef void (cmd_func_t)(int, char **);
596ba597c5SAnurag S. Maskey 
606ba597c5SAnurag S. Maskey struct cmd {
616ba597c5SAnurag S. Maskey 	uint_t		cmd_num;		/* command number */
626ba597c5SAnurag S. Maskey 	const char	*cmd_name;		/* command name */
636ba597c5SAnurag S. Maskey 	cmd_func_t	*cmd_handler;		/* function to call */
646ba597c5SAnurag S. Maskey 	const char	*cmd_usage;		/* short form help */
656ba597c5SAnurag S. Maskey 	const char	*cmd_desc;		/* command description */
666ba597c5SAnurag S. Maskey 	boolean_t	cmd_needs_nwamd;	/* nwam needs to run */
676ba597c5SAnurag S. Maskey };
686ba597c5SAnurag S. Maskey 
696ba597c5SAnurag S. Maskey /* constants for commands */
706ba597c5SAnurag S. Maskey #define	CMD_HELP	0
716ba597c5SAnurag S. Maskey #define	CMD_ENABLE	1
726ba597c5SAnurag S. Maskey #define	CMD_DISABLE	2
736ba597c5SAnurag S. Maskey #define	CMD_LIST	3
746ba597c5SAnurag S. Maskey #define	CMD_SHOW_EVENTS	4
756ba597c5SAnurag S. Maskey #define	CMD_SCAN_WIFI	5
766ba597c5SAnurag S. Maskey #define	CMD_SELECT_WIFI	6
776ba597c5SAnurag S. Maskey 
786ba597c5SAnurag S. Maskey #define	CMD_MIN		CMD_HELP
796ba597c5SAnurag S. Maskey #define	CMD_MAX		CMD_SELECT_WIFI
806ba597c5SAnurag S. Maskey 
816ba597c5SAnurag S. Maskey /* functions to call */
826ba597c5SAnurag S. Maskey static cmd_func_t help_func, enable_func, disable_func, list_func;
836ba597c5SAnurag S. Maskey static cmd_func_t show_events_func, scan_wifi_func, select_wifi_func;
846ba597c5SAnurag S. Maskey static ofmt_cb_t print_list_cb;
856ba597c5SAnurag S. Maskey 
866ba597c5SAnurag S. Maskey /* table of commands and usage */
876ba597c5SAnurag S. Maskey static struct cmd cmdtab[] = {
886ba597c5SAnurag S. Maskey 	{ CMD_HELP,		"help",		help_func,
896ba597c5SAnurag S. Maskey 	    "help",
906ba597c5SAnurag S. Maskey 	    "Print this usage message.",		B_FALSE		},
916ba597c5SAnurag S. Maskey 	{ CMD_ENABLE,		"enable",	enable_func,
926ba597c5SAnurag S. Maskey 	    "enable [-p <profile-type>] [-c <ncu-class>] <object-name>",
936ba597c5SAnurag S. Maskey 	    "Enable the specified profile.",		B_FALSE		},
946ba597c5SAnurag S. Maskey 	{ CMD_DISABLE,		"disable",	disable_func,
956ba597c5SAnurag S. Maskey 	    "disable [-p <profile-type>] [-c <ncu-class>] <object-name>",
966ba597c5SAnurag S. Maskey 	    "Disable the specified profile.",		B_FALSE		},
976ba597c5SAnurag S. Maskey 	{ CMD_LIST,		"list",		list_func,
986ba597c5SAnurag S. Maskey 	    "list [-x] [-p <profile-type>] [-c <ncu-class>] [<object-name>]",
996ba597c5SAnurag S. Maskey 	    "List profiles and their current states.",	B_TRUE		},
1006ba597c5SAnurag S. Maskey 	{ CMD_SHOW_EVENTS,	"show-events",	show_events_func,
1016ba597c5SAnurag S. Maskey 	    "show-events",
1026ba597c5SAnurag S. Maskey 	    "Display all events.",			B_TRUE		},
1036ba597c5SAnurag S. Maskey 	{ CMD_SCAN_WIFI,	"scan-wifi",	scan_wifi_func,
1046ba597c5SAnurag S. Maskey 	    "scan-wifi <link-name>",
1056ba597c5SAnurag S. Maskey 	    "Request a WiFi scan for the selected link.", B_TRUE	},
1066ba597c5SAnurag S. Maskey 	{ CMD_SELECT_WIFI,	"select-wifi",	select_wifi_func,
1076ba597c5SAnurag S. Maskey 	    "select-wifi <link-name>",
1086ba597c5SAnurag S. Maskey 	    "Make a WLAN selection from the last WiFi scan.", B_TRUE	}
1096ba597c5SAnurag S. Maskey };
1106ba597c5SAnurag S. Maskey 
1116ba597c5SAnurag S. Maskey /* Structure for "nwamadm list" output */
1126ba597c5SAnurag S. Maskey 
1136ba597c5SAnurag S. Maskey typedef struct profile_entry {
1146ba597c5SAnurag S. Maskey 	nwam_object_type_t	p_type;
1156ba597c5SAnurag S. Maskey 	nwam_ncu_class_t	p_ncu_class;
1166ba597c5SAnurag S. Maskey 	char			p_name[NWAM_MAX_NAME_LEN];
1176ba597c5SAnurag S. Maskey 	nwam_state_t		p_state;
1186ba597c5SAnurag S. Maskey 	nwam_aux_state_t	p_aux_state;
1196ba597c5SAnurag S. Maskey } profile_entry_t;
1206ba597c5SAnurag S. Maskey 
1216ba597c5SAnurag S. Maskey /* widths of colums for printing */
1226ba597c5SAnurag S. Maskey #define	TYPE_WIDTH		12	/* width of TYPE column */
1236ba597c5SAnurag S. Maskey #define	PROFILE_WIDTH		15	/* width of PROFILE column */
1246ba597c5SAnurag S. Maskey #define	STATE_WIDTH		15	/* width of STATE column */
1256ba597c5SAnurag S. Maskey #define	AUXSTATE_WIDTH		36	/* width of AUXILIARY STATE column */
1266ba597c5SAnurag S. Maskey 
127*f6da83d4SAnurag S. Maskey #define	EVENT_WIDTH		15	/* width of EVENT column */
128*f6da83d4SAnurag S. Maskey #define	DESCRIPTION_WIDTH	64	/* width of DESCRIPTION column */
1296ba597c5SAnurag S. Maskey 
1306ba597c5SAnurag S. Maskey /* id for columns of "nwamadm list" */
1316ba597c5SAnurag S. Maskey typedef enum {
1326ba597c5SAnurag S. Maskey 	LIST_TYPE,
1336ba597c5SAnurag S. Maskey 	LIST_PROFILE,
1346ba597c5SAnurag S. Maskey 	LIST_STATE,
1356ba597c5SAnurag S. Maskey 	LIST_AUXSTATE
1366ba597c5SAnurag S. Maskey } list_field_id_t;
1376ba597c5SAnurag S. Maskey 
1386ba597c5SAnurag S. Maskey static const ofmt_field_t list_fields[] = {
1396ba597c5SAnurag S. Maskey 	/* header,		width,		id,		callback */
1406ba597c5SAnurag S. Maskey 	{ "TYPE",		TYPE_WIDTH,	LIST_TYPE,	print_list_cb },
1416ba597c5SAnurag S. Maskey 	{ "PROFILE",		PROFILE_WIDTH,	LIST_PROFILE,	print_list_cb },
1426ba597c5SAnurag S. Maskey 	{ "STATE",		STATE_WIDTH,	LIST_STATE,	print_list_cb },
1436ba597c5SAnurag S. Maskey 	{ "AUXILIARY STATE",	AUXSTATE_WIDTH,	LIST_AUXSTATE,	print_list_cb },
1446ba597c5SAnurag S. Maskey 	{ NULL,			0,		0,		NULL }
1456ba597c5SAnurag S. Maskey };
1466ba597c5SAnurag S. Maskey 
1476ba597c5SAnurag S. Maskey /* Global variables */
1486ba597c5SAnurag S. Maskey 
1496ba597c5SAnurag S. Maskey /* set early in main(), never modified thereafter, used all over the place */
1506ba597c5SAnurag S. Maskey static char *execname;
1516ba597c5SAnurag S. Maskey 
1526ba597c5SAnurag S. Maskey /* whether the auxilary states are to be printed or not */
1536ba597c5SAnurag S. Maskey static boolean_t extended_list = B_FALSE;
1546ba597c5SAnurag S. Maskey 
1556ba597c5SAnurag S. Maskey /* Functions */
1566ba597c5SAnurag S. Maskey 
1576ba597c5SAnurag S. Maskey static const char *
1586ba597c5SAnurag S. Maskey cmd_to_str(int cmd_num)
1596ba597c5SAnurag S. Maskey {
1606ba597c5SAnurag S. Maskey 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
1616ba597c5SAnurag S. Maskey 	return (cmdtab[cmd_num].cmd_name);
1626ba597c5SAnurag S. Maskey }
1636ba597c5SAnurag S. Maskey 
1646ba597c5SAnurag S. Maskey /* returns description of given command */
1656ba597c5SAnurag S. Maskey static const char *
1666ba597c5SAnurag S. Maskey long_help(int cmd_num)
1676ba597c5SAnurag S. Maskey {
1686ba597c5SAnurag S. Maskey 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
1696ba597c5SAnurag S. Maskey 	return (gettext(cmdtab[cmd_num].cmd_desc));
1706ba597c5SAnurag S. Maskey }
1716ba597c5SAnurag S. Maskey 
1726ba597c5SAnurag S. Maskey /*
1736ba597c5SAnurag S. Maskey  * Called with explicit B_TRUE when help is explicitly required,
1746ba597c5SAnurag S. Maskey  * B_FALSE for errors
1756ba597c5SAnurag S. Maskey  */
1766ba597c5SAnurag S. Maskey static void
1776ba597c5SAnurag S. Maskey usage(boolean_t explicit)
1786ba597c5SAnurag S. Maskey {
1796ba597c5SAnurag S. Maskey 	int	i;
1806ba597c5SAnurag S. Maskey 	FILE	*fd = explicit ? stdout : stderr;
1816ba597c5SAnurag S. Maskey 
1826ba597c5SAnurag S. Maskey 	(void) fprintf(fd, gettext("usage: <subcommand> <args> ...\n"));
1836ba597c5SAnurag S. Maskey 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
1846ba597c5SAnurag S. Maskey 		(void) fprintf(fd, "\t%s\n", cmdtab[i].cmd_usage);
1856ba597c5SAnurag S. Maskey 		if (explicit)
1866ba597c5SAnurag S. Maskey 			(void) fprintf(fd, "\t\t%s\n\n", long_help(i));
1876ba597c5SAnurag S. Maskey 	}
1886ba597c5SAnurag S. Maskey }
1896ba597c5SAnurag S. Maskey 
1906ba597c5SAnurag S. Maskey /* PRINTFLIKE1 */
1916ba597c5SAnurag S. Maskey static void
1926ba597c5SAnurag S. Maskey die(const char *format, ...)
1936ba597c5SAnurag S. Maskey {
1946ba597c5SAnurag S. Maskey 	va_list alist;
1956ba597c5SAnurag S. Maskey 
1966ba597c5SAnurag S. Maskey 	format = gettext(format);
1976ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, "%s: ", execname);
1986ba597c5SAnurag S. Maskey 
1996ba597c5SAnurag S. Maskey 	va_start(alist, format);
2006ba597c5SAnurag S. Maskey 	(void) vfprintf(stderr, format, alist);
2016ba597c5SAnurag S. Maskey 	va_end(alist);
2026ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, "\n");
2036ba597c5SAnurag S. Maskey 
2046ba597c5SAnurag S. Maskey 	exit(EXIT_FAILURE);
2056ba597c5SAnurag S. Maskey }
2066ba597c5SAnurag S. Maskey 
2076ba597c5SAnurag S. Maskey /* PRINTFLIKE2 */
2086ba597c5SAnurag S. Maskey static void
2096ba597c5SAnurag S. Maskey die_nwamerr(nwam_error_t err, const char *format, ...)
2106ba597c5SAnurag S. Maskey {
2116ba597c5SAnurag S. Maskey 	va_list alist;
2126ba597c5SAnurag S. Maskey 
2136ba597c5SAnurag S. Maskey 	format = gettext(format);
2146ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, "%s: ", execname);
2156ba597c5SAnurag S. Maskey 
2166ba597c5SAnurag S. Maskey 	va_start(alist, format);
2176ba597c5SAnurag S. Maskey 	(void) vfprintf(stderr, format, alist);
2186ba597c5SAnurag S. Maskey 	va_end(alist);
2196ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, ": %s\n", nwam_strerror(err));
2206ba597c5SAnurag S. Maskey 
2216ba597c5SAnurag S. Maskey 	exit(EXIT_FAILURE);
2226ba597c5SAnurag S. Maskey }
2236ba597c5SAnurag S. Maskey 
2246ba597c5SAnurag S. Maskey /* prints the usage for cmd_num and exits */
2256ba597c5SAnurag S. Maskey static void
2266ba597c5SAnurag S. Maskey die_usage(int cmd_num)
2276ba597c5SAnurag S. Maskey {
2286ba597c5SAnurag S. Maskey 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
2296ba597c5SAnurag S. Maskey 
2306ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, "%s: %s\n", gettext("usage"),
2316ba597c5SAnurag S. Maskey 	    cmdtab[cmd_num].cmd_usage);
2326ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, "\t%s\n", long_help(cmd_num));
2336ba597c5SAnurag S. Maskey 
2346ba597c5SAnurag S. Maskey 	exit(EXIT_FAILURE);
2356ba597c5SAnurag S. Maskey }
2366ba597c5SAnurag S. Maskey 
2376ba597c5SAnurag S. Maskey /*
2386ba597c5SAnurag S. Maskey  * Prints the usage and description of all commands
2396ba597c5SAnurag S. Maskey  */
2406ba597c5SAnurag S. Maskey /* ARGSUSED */
2416ba597c5SAnurag S. Maskey static void
2426ba597c5SAnurag S. Maskey help_func(int argc, char *argv[])
2436ba597c5SAnurag S. Maskey {
2446ba597c5SAnurag S. Maskey 	usage(B_TRUE);
2456ba597c5SAnurag S. Maskey }
2466ba597c5SAnurag S. Maskey 
2476ba597c5SAnurag S. Maskey /* determines if the NCP is active or not.  If so, sets arg and halts walk. */
2486ba597c5SAnurag S. Maskey static int
2496ba597c5SAnurag S. Maskey active_ncp_callback(nwam_ncp_handle_t ncph, void *arg)
2506ba597c5SAnurag S. Maskey {
2516ba597c5SAnurag S. Maskey 	char			**namep = arg;
2526ba597c5SAnurag S. Maskey 	nwam_state_t		state = NWAM_STATE_UNINITIALIZED;
2536ba597c5SAnurag S. Maskey 	nwam_aux_state_t	aux;
2546ba597c5SAnurag S. Maskey 
2556ba597c5SAnurag S. Maskey 	(void) nwam_ncp_get_state(ncph, &state, &aux);
2566ba597c5SAnurag S. Maskey 	if (state == NWAM_STATE_ONLINE) {
2576ba597c5SAnurag S. Maskey 		if (nwam_ncp_get_name(ncph, namep) != NWAM_SUCCESS)
2586ba597c5SAnurag S. Maskey 			*namep = NULL;
2596ba597c5SAnurag S. Maskey 		return (1);
2606ba597c5SAnurag S. Maskey 	}
2616ba597c5SAnurag S. Maskey 
2626ba597c5SAnurag S. Maskey 	return (0);
2636ba597c5SAnurag S. Maskey }
2646ba597c5SAnurag S. Maskey 
2656ba597c5SAnurag S. Maskey /* find the currently active NCP and returns its handle */
2666ba597c5SAnurag S. Maskey static nwam_ncp_handle_t
2676ba597c5SAnurag S. Maskey determine_active_ncp()
2686ba597c5SAnurag S. Maskey {
2696ba597c5SAnurag S. Maskey 	char *active_ncp;
2706ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
2716ba597c5SAnurag S. Maskey 	nwam_error_t ret;
2726ba597c5SAnurag S. Maskey 
2736ba597c5SAnurag S. Maskey 	if (nwam_walk_ncps(active_ncp_callback, &active_ncp, 0, NULL)
2746ba597c5SAnurag S. Maskey 	    == NWAM_WALK_HALTED) {
2756ba597c5SAnurag S. Maskey 		if (active_ncp == NULL)
2766ba597c5SAnurag S. Maskey 			return (NULL);
2776ba597c5SAnurag S. Maskey 
2786ba597c5SAnurag S. Maskey 		/* retrieve the NCP handle */
2796ba597c5SAnurag S. Maskey 		ret = nwam_ncp_read(active_ncp, 0, &ncph);
2806ba597c5SAnurag S. Maskey 		free(active_ncp);
2816ba597c5SAnurag S. Maskey 		if (ret == NWAM_SUCCESS)
2826ba597c5SAnurag S. Maskey 			return (ncph);
2836ba597c5SAnurag S. Maskey 	}
2846ba597c5SAnurag S. Maskey 
2856ba597c5SAnurag S. Maskey 	return (NULL);
2866ba597c5SAnurag S. Maskey }
2876ba597c5SAnurag S. Maskey 
2886ba597c5SAnurag S. Maskey /* check if the given name is a valid loc, test by reading the given loc */
2896ba597c5SAnurag S. Maskey static boolean_t
2906ba597c5SAnurag S. Maskey valid_loc(const char *name)
2916ba597c5SAnurag S. Maskey {
2926ba597c5SAnurag S. Maskey 	nwam_loc_handle_t loch;
2936ba597c5SAnurag S. Maskey 
2946ba597c5SAnurag S. Maskey 	if (nwam_loc_read(name, 0, &loch) != NWAM_SUCCESS)
2956ba597c5SAnurag S. Maskey 		return (B_FALSE);
2966ba597c5SAnurag S. Maskey 	nwam_loc_free(loch);
2976ba597c5SAnurag S. Maskey 	return (B_TRUE);
2986ba597c5SAnurag S. Maskey }
2996ba597c5SAnurag S. Maskey 
3006ba597c5SAnurag S. Maskey static boolean_t
3016ba597c5SAnurag S. Maskey valid_enm(const char *name)
3026ba597c5SAnurag S. Maskey {
3036ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
3046ba597c5SAnurag S. Maskey 
3056ba597c5SAnurag S. Maskey 	if (nwam_enm_read(name, 0, &enmh) != NWAM_SUCCESS)
3066ba597c5SAnurag S. Maskey 		return (B_FALSE);
3076ba597c5SAnurag S. Maskey 	nwam_enm_free(enmh);
3086ba597c5SAnurag S. Maskey 	return (B_TRUE);
3096ba597c5SAnurag S. Maskey }
3106ba597c5SAnurag S. Maskey 
3116ba597c5SAnurag S. Maskey static boolean_t
3126ba597c5SAnurag S. Maskey valid_ncp(const char *name)
3136ba597c5SAnurag S. Maskey {
3146ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
3156ba597c5SAnurag S. Maskey 
3166ba597c5SAnurag S. Maskey 	if (nwam_ncp_read(name, 0, &ncph) != NWAM_SUCCESS)
3176ba597c5SAnurag S. Maskey 		return (B_FALSE);
3186ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
3196ba597c5SAnurag S. Maskey 	return (B_TRUE);
3206ba597c5SAnurag S. Maskey }
3216ba597c5SAnurag S. Maskey 
3226ba597c5SAnurag S. Maskey static boolean_t
3236ba597c5SAnurag S. Maskey valid_ncu(const char *name)
3246ba597c5SAnurag S. Maskey {
3256ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
3266ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh;
3276ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
3286ba597c5SAnurag S. Maskey 
3296ba597c5SAnurag S. Maskey 	if ((ncph = determine_active_ncp()) == NULL)
3306ba597c5SAnurag S. Maskey 		return (B_FALSE);
3316ba597c5SAnurag S. Maskey 
3326ba597c5SAnurag S. Maskey 	ret = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_ANY, 0, &ncuh);
3336ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
3346ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS && ret != NWAM_ENTITY_MULTIPLE_VALUES)
3356ba597c5SAnurag S. Maskey 		return (B_FALSE);
3366ba597c5SAnurag S. Maskey 	nwam_ncu_free(ncuh);
3376ba597c5SAnurag S. Maskey 	return (B_TRUE);
3386ba597c5SAnurag S. Maskey }
3396ba597c5SAnurag S. Maskey 
3406ba597c5SAnurag S. Maskey /*
3416ba597c5SAnurag S. Maskey  * Given a name, returns object type (loc, enm, ncp, or ncu) and how many
3426ba597c5SAnurag S. Maskey  * objects matched that name.
3436ba597c5SAnurag S. Maskey  */
3446ba597c5SAnurag S. Maskey static nwam_object_type_t
3456ba597c5SAnurag S. Maskey determine_object_type(const char *name, int *num)
3466ba597c5SAnurag S. Maskey {
3476ba597c5SAnurag S. Maskey 	nwam_object_type_t type;
3486ba597c5SAnurag S. Maskey 	int n = 0;
3496ba597c5SAnurag S. Maskey 
3506ba597c5SAnurag S. Maskey 	/* see if a valid loc, enm, ncp and/or ncu exists with given name */
3516ba597c5SAnurag S. Maskey 	if (valid_loc(name)) {
3526ba597c5SAnurag S. Maskey 		n++;
3536ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_LOC;
3546ba597c5SAnurag S. Maskey 	}
3556ba597c5SAnurag S. Maskey 	if (valid_enm(name)) {
3566ba597c5SAnurag S. Maskey 		n++;
3576ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_ENM;
3586ba597c5SAnurag S. Maskey 	}
3596ba597c5SAnurag S. Maskey 	if (valid_ncp(name)) {
3606ba597c5SAnurag S. Maskey 		n++;
3616ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_NCP;
3626ba597c5SAnurag S. Maskey 	}
3636ba597c5SAnurag S. Maskey 	if (valid_ncu(name)) {
3646ba597c5SAnurag S. Maskey 		n++;
3656ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_NCU;
3666ba597c5SAnurag S. Maskey 	}
3676ba597c5SAnurag S. Maskey 
3686ba597c5SAnurag S. Maskey 	/* if n > 1, then it means *type was set multiple times, undo it */
3696ba597c5SAnurag S. Maskey 	if (n != 1)
3706ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_UNKNOWN;
3716ba597c5SAnurag S. Maskey 
3726ba597c5SAnurag S. Maskey 	*num = n;
3736ba597c5SAnurag S. Maskey 	return (type);
3746ba597c5SAnurag S. Maskey }
3756ba597c5SAnurag S. Maskey 
3766ba597c5SAnurag S. Maskey /*
3776ba597c5SAnurag S. Maskey  * Parses argv array and populates object_type and name.
3786ba597c5SAnurag S. Maskey  * Program exits on failure.
3796ba597c5SAnurag S. Maskey  */
3806ba597c5SAnurag S. Maskey static void
3816ba597c5SAnurag S. Maskey parse_argv(int argc, char *argv[], int cmd_num, nwam_object_type_t *object_type,
3826ba597c5SAnurag S. Maskey     nwam_ncu_type_t *ncu_type, nwam_ncu_class_t *ncu_class, const char **name)
3836ba597c5SAnurag S. Maskey {
3846ba597c5SAnurag S. Maskey 	int			arg;
3856ba597c5SAnurag S. Maskey 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
3866ba597c5SAnurag S. Maskey 	uint64_t		ncu = NWAM_NCU_TYPE_ANY;
3876ba597c5SAnurag S. Maskey 	uint64_t		class = NWAM_NCU_CLASS_ANY;
3886ba597c5SAnurag S. Maskey 
3896ba597c5SAnurag S. Maskey 	/* check argv for option */
3906ba597c5SAnurag S. Maskey 	optind = 0;
3916ba597c5SAnurag S. Maskey 	while ((arg = getopt(argc, argv, "?p:c:x")) != EOF) {
3926ba597c5SAnurag S. Maskey 		switch (arg) {
3936ba597c5SAnurag S. Maskey 		case 'p':
3946ba597c5SAnurag S. Maskey 			type = nwam_string_to_object_type(optarg);
3956ba597c5SAnurag S. Maskey 			if (type == NWAM_OBJECT_TYPE_UNKNOWN)
3966ba597c5SAnurag S. Maskey 				die("Invalid profile-type: %s", optarg);
3976ba597c5SAnurag S. Maskey 			break;
3986ba597c5SAnurag S. Maskey 		case 'c':
3996ba597c5SAnurag S. Maskey 			if (nwam_value_string_get_uint64(NWAM_NCU_PROP_CLASS,
4006ba597c5SAnurag S. Maskey 			    optarg, &class) != NWAM_SUCCESS) {
4016ba597c5SAnurag S. Maskey 				die("Invalid ncu-class: %s", optarg);
4026ba597c5SAnurag S. Maskey 			}
4036ba597c5SAnurag S. Maskey 			ncu = nwam_ncu_class_to_type(class);
4046ba597c5SAnurag S. Maskey 			if (ncu == NWAM_NCU_TYPE_ANY ||
4056ba597c5SAnurag S. Maskey 			    ncu == NWAM_NCU_TYPE_UNKNOWN)
4066ba597c5SAnurag S. Maskey 				die("Invalid ncu-class: %s", optarg);
4076ba597c5SAnurag S. Maskey 			break;
4086ba597c5SAnurag S. Maskey 		case 'x':
4096ba597c5SAnurag S. Maskey 			/* -x is only for list */
4106ba597c5SAnurag S. Maskey 			if (cmd_num != CMD_LIST)
4116ba597c5SAnurag S. Maskey 				die("-x can only be used with 'list'");
4126ba597c5SAnurag S. Maskey 			extended_list = B_TRUE;
4136ba597c5SAnurag S. Maskey 			break;
4146ba597c5SAnurag S. Maskey 		case '?':
4156ba597c5SAnurag S. Maskey 		default:
4166ba597c5SAnurag S. Maskey 			die_usage(cmd_num);
4176ba597c5SAnurag S. Maskey 		}
4186ba597c5SAnurag S. Maskey 	}
4196ba597c5SAnurag S. Maskey 
4206ba597c5SAnurag S. Maskey 	if (ncu != NWAM_NCU_TYPE_ANY) {
4216ba597c5SAnurag S. Maskey 		/* If -c is given, -p must be NCU. If unspecified, assume NCU */
4226ba597c5SAnurag S. Maskey 		if (type != NWAM_OBJECT_TYPE_UNKNOWN &&
4236ba597c5SAnurag S. Maskey 		    type != NWAM_OBJECT_TYPE_NCU)
4246ba597c5SAnurag S. Maskey 			die("'-c <ncu-class>' can only be used for ncu");
4256ba597c5SAnurag S. Maskey 
4266ba597c5SAnurag S. Maskey 		type = NWAM_OBJECT_TYPE_NCU;
4276ba597c5SAnurag S. Maskey 	}
4286ba597c5SAnurag S. Maskey 
4296ba597c5SAnurag S. Maskey 	/* name is mandatory for enable and disable, but not for list */
4306ba597c5SAnurag S. Maskey 	if (optind == (argc-1))
4316ba597c5SAnurag S. Maskey 		*name = argv[optind];
4326ba597c5SAnurag S. Maskey 	else if (argc != optind)
4336ba597c5SAnurag S. Maskey 		die("too many profile names given");
4346ba597c5SAnurag S. Maskey 	else if (cmd_num != CMD_LIST)
4356ba597c5SAnurag S. Maskey 		die("no profile name given");
4366ba597c5SAnurag S. Maskey 
4376ba597c5SAnurag S. Maskey 	/*
4386ba597c5SAnurag S. Maskey 	 * No need to determine type for list.
4396ba597c5SAnurag S. Maskey 	 * If -p is not given for enable or disable, then determine type.
4406ba597c5SAnurag S. Maskey 	 */
4416ba597c5SAnurag S. Maskey 	if (cmd_num != CMD_LIST && type == NWAM_OBJECT_TYPE_UNKNOWN) {
4426ba597c5SAnurag S. Maskey 		int num = 0;
4436ba597c5SAnurag S. Maskey 
4446ba597c5SAnurag S. Maskey 		type = determine_object_type(*name, &num);
4456ba597c5SAnurag S. Maskey 		if (num == 0) {
4466ba597c5SAnurag S. Maskey 			die("no profile matched '%s'", *name);
4476ba597c5SAnurag S. Maskey 		} else if (num > 1) {
4486ba597c5SAnurag S. Maskey 			die("more than one profile matched '%s' - use "
4496ba597c5SAnurag S. Maskey 			    "'-p <profile-type>' to specify a profile type.",
4506ba597c5SAnurag S. Maskey 			    *name);
4516ba597c5SAnurag S. Maskey 		}
4526ba597c5SAnurag S. Maskey 	}
4536ba597c5SAnurag S. Maskey 
4546ba597c5SAnurag S. Maskey 	*object_type = type;
4556ba597c5SAnurag S. Maskey 	*ncu_type = ncu;
4566ba597c5SAnurag S. Maskey 	*ncu_class = class;
4576ba597c5SAnurag S. Maskey }
4586ba597c5SAnurag S. Maskey 
4596ba597c5SAnurag S. Maskey /* Enables/Disables profiles depending on boolean */
4606ba597c5SAnurag S. Maskey static nwam_error_t
4616ba597c5SAnurag S. Maskey loc_action(const char *name, boolean_t enable, char **realnamep)
4626ba597c5SAnurag S. Maskey {
4636ba597c5SAnurag S. Maskey 	nwam_loc_handle_t loch;
4646ba597c5SAnurag S. Maskey 	nwam_error_t ret;
4656ba597c5SAnurag S. Maskey 
4666ba597c5SAnurag S. Maskey 	if ((ret = nwam_loc_read(name, 0, &loch)) != NWAM_SUCCESS)
4676ba597c5SAnurag S. Maskey 		return (ret);
4686ba597c5SAnurag S. Maskey 
4696ba597c5SAnurag S. Maskey 	if (enable)
4706ba597c5SAnurag S. Maskey 		ret = nwam_loc_enable(loch);
4716ba597c5SAnurag S. Maskey 	else
4726ba597c5SAnurag S. Maskey 		ret = nwam_loc_disable(loch);
4736ba597c5SAnurag S. Maskey 
4746ba597c5SAnurag S. Maskey 	(void) nwam_loc_get_name(loch, realnamep);
4756ba597c5SAnurag S. Maskey 	nwam_loc_free(loch);
4766ba597c5SAnurag S. Maskey 	return (ret);
4776ba597c5SAnurag S. Maskey }
4786ba597c5SAnurag S. Maskey 
4796ba597c5SAnurag S. Maskey static nwam_error_t
4806ba597c5SAnurag S. Maskey enm_action(const char *name, boolean_t enable, char **realnamep)
4816ba597c5SAnurag S. Maskey {
4826ba597c5SAnurag S. Maskey 	nwam_enm_handle_t enmh;
4836ba597c5SAnurag S. Maskey 	nwam_error_t ret;
4846ba597c5SAnurag S. Maskey 
4856ba597c5SAnurag S. Maskey 	if ((ret = nwam_enm_read(name, 0, &enmh)) != NWAM_SUCCESS)
4866ba597c5SAnurag S. Maskey 		return (ret);
4876ba597c5SAnurag S. Maskey 
4886ba597c5SAnurag S. Maskey 	if (enable)
4896ba597c5SAnurag S. Maskey 		ret = nwam_enm_enable(enmh);
4906ba597c5SAnurag S. Maskey 	else
4916ba597c5SAnurag S. Maskey 		ret = nwam_enm_disable(enmh);
4926ba597c5SAnurag S. Maskey 
4936ba597c5SAnurag S. Maskey 	(void) nwam_enm_get_name(enmh, realnamep);
4946ba597c5SAnurag S. Maskey 	nwam_enm_free(enmh);
4956ba597c5SAnurag S. Maskey 	return (ret);
4966ba597c5SAnurag S. Maskey }
4976ba597c5SAnurag S. Maskey 
4986ba597c5SAnurag S. Maskey static nwam_error_t
4996ba597c5SAnurag S. Maskey ncu_action(const char *name, nwam_ncp_handle_t ncph, nwam_ncu_type_t type,
5006ba597c5SAnurag S. Maskey     boolean_t enable, char **realnamep)
5016ba597c5SAnurag S. Maskey {
5026ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh;
5036ba597c5SAnurag S. Maskey 	nwam_error_t ret;
5046ba597c5SAnurag S. Maskey 	boolean_t retrieved_ncph = B_FALSE;
5056ba597c5SAnurag S. Maskey 
5066ba597c5SAnurag S. Maskey 	if (ncph == NULL) {
5076ba597c5SAnurag S. Maskey 		if ((ncph = determine_active_ncp()) == NULL)
5086ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_FOUND);
5096ba597c5SAnurag S. Maskey 		retrieved_ncph = B_TRUE;
5106ba597c5SAnurag S. Maskey 	}
5116ba597c5SAnurag S. Maskey 
5126ba597c5SAnurag S. Maskey 	ret = nwam_ncu_read(ncph, name, type, 0, &ncuh);
5136ba597c5SAnurag S. Maskey 	switch (ret) {
5146ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
5156ba597c5SAnurag S. Maskey 		if (enable)
5166ba597c5SAnurag S. Maskey 			ret = nwam_ncu_enable(ncuh);
5176ba597c5SAnurag S. Maskey 		else
5186ba597c5SAnurag S. Maskey 			ret = nwam_ncu_disable(ncuh);
5196ba597c5SAnurag S. Maskey 		(void) nwam_ncu_get_name(ncuh, realnamep);
5206ba597c5SAnurag S. Maskey 		nwam_ncu_free(ncuh);
5216ba597c5SAnurag S. Maskey 		break;
5226ba597c5SAnurag S. Maskey 	case NWAM_ENTITY_MULTIPLE_VALUES:
5236ba597c5SAnurag S. Maskey 		/* Call ncu_action() for link and interface types */
5246ba597c5SAnurag S. Maskey 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_LINK, enable,
5256ba597c5SAnurag S. Maskey 		    realnamep);
5266ba597c5SAnurag S. Maskey 		if (ret != NWAM_SUCCESS)
5276ba597c5SAnurag S. Maskey 			break;
5286ba597c5SAnurag S. Maskey 
5296ba597c5SAnurag S. Maskey 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_INTERFACE, enable,
5306ba597c5SAnurag S. Maskey 		    realnamep);
5316ba597c5SAnurag S. Maskey 		break;
5326ba597c5SAnurag S. Maskey 	}
5336ba597c5SAnurag S. Maskey 	if (retrieved_ncph)
5346ba597c5SAnurag S. Maskey 		nwam_ncp_free(ncph);
5356ba597c5SAnurag S. Maskey 
5366ba597c5SAnurag S. Maskey 	return (ret);
5376ba597c5SAnurag S. Maskey }
5386ba597c5SAnurag S. Maskey 
5396ba597c5SAnurag S. Maskey /*
5406ba597c5SAnurag S. Maskey  * If more than one type of profile with the same name, return error.
5416ba597c5SAnurag S. Maskey  * In such situations, the -p option must be used.
5426ba597c5SAnurag S. Maskey  * If a location is enabled when a different one is already enabled, then
5436ba597c5SAnurag S. Maskey  * that location is disabled automatically by nwamd.
5446ba597c5SAnurag S. Maskey  */
5456ba597c5SAnurag S. Maskey static void
5466ba597c5SAnurag S. Maskey enable_func(int argc, char *argv[])
5476ba597c5SAnurag S. Maskey {
5486ba597c5SAnurag S. Maskey 	nwam_error_t		ret;
5496ba597c5SAnurag S. Maskey 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
5506ba597c5SAnurag S. Maskey 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
5516ba597c5SAnurag S. Maskey 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
5526ba597c5SAnurag S. Maskey 	const char		*name;
5536ba597c5SAnurag S. Maskey 	char			*realname = NULL;
5546ba597c5SAnurag S. Maskey 
5556ba597c5SAnurag S. Maskey 	/* parse_argv() returns only on success */
5566ba597c5SAnurag S. Maskey 	parse_argv(argc, argv, CMD_ENABLE, &type, &ncu_type, &ncu_class, &name);
5576ba597c5SAnurag S. Maskey 
5586ba597c5SAnurag S. Maskey 	/*
5596ba597c5SAnurag S. Maskey 	 * NCPs and Locations don't need to disable the currently active
5606ba597c5SAnurag S. Maskey 	 * profile - nwamd automatically switches to the new active profile.
5616ba597c5SAnurag S. Maskey 	 * and will disable it if necessary.
5626ba597c5SAnurag S. Maskey 	 */
5636ba597c5SAnurag S. Maskey 
5646ba597c5SAnurag S. Maskey 	/* activate given profile */
5656ba597c5SAnurag S. Maskey 	switch (type) {
5666ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_LOC:
5676ba597c5SAnurag S. Maskey 		ret = loc_action(name, B_TRUE, &realname);
5686ba597c5SAnurag S. Maskey 		break;
5696ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_ENM:
5706ba597c5SAnurag S. Maskey 		ret = enm_action(name, B_TRUE, &realname);
5716ba597c5SAnurag S. Maskey 		break;
5726ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCP:
5736ba597c5SAnurag S. Maskey 	{
5746ba597c5SAnurag S. Maskey 		nwam_ncp_handle_t ncph;
5756ba597c5SAnurag S. Maskey 
5766ba597c5SAnurag S. Maskey 		if ((ret = nwam_ncp_read(name, 0, &ncph)) != NWAM_SUCCESS)
5776ba597c5SAnurag S. Maskey 			break;
5786ba597c5SAnurag S. Maskey 
5796ba597c5SAnurag S. Maskey 		ret = nwam_ncp_enable(ncph);
5806ba597c5SAnurag S. Maskey 		(void) nwam_ncp_get_name(ncph, &realname);
5816ba597c5SAnurag S. Maskey 		nwam_ncp_free(ncph);
5826ba597c5SAnurag S. Maskey 		break;
5836ba597c5SAnurag S. Maskey 	}
5846ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCU:
5856ba597c5SAnurag S. Maskey 		ret = ncu_action(name, NULL, ncu_type, B_TRUE, &realname);
5866ba597c5SAnurag S. Maskey 		break;
5876ba597c5SAnurag S. Maskey 	}
5886ba597c5SAnurag S. Maskey 
5896ba597c5SAnurag S. Maskey 	switch (ret) {
5906ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
5916ba597c5SAnurag S. Maskey 		(void) printf(gettext("Enabling %s '%s'\n"),
5926ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(type),
5936ba597c5SAnurag S. Maskey 		    realname != NULL ? realname : name);
5946ba597c5SAnurag S. Maskey 		break;
5956ba597c5SAnurag S. Maskey 	case NWAM_ENTITY_NOT_MANUAL:
5966ba597c5SAnurag S. Maskey 		die("Only profiles with manual activation-mode can be enabled");
5976ba597c5SAnurag S. Maskey 		break;
5986ba597c5SAnurag S. Maskey 	default:
5996ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "Could not enable %s '%s'",
6006ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(type),
6016ba597c5SAnurag S. Maskey 		    realname != NULL ? realname : name);
6026ba597c5SAnurag S. Maskey 	}
6036ba597c5SAnurag S. Maskey 	free(realname);
6046ba597c5SAnurag S. Maskey }
6056ba597c5SAnurag S. Maskey 
6066ba597c5SAnurag S. Maskey /*
6076ba597c5SAnurag S. Maskey  * Disables a given profile.  Similar to enable, the -p option must be used
6086ba597c5SAnurag S. Maskey  * if more than one type of profile is matched by the given name.
6096ba597c5SAnurag S. Maskey  */
6106ba597c5SAnurag S. Maskey static void
6116ba597c5SAnurag S. Maskey disable_func(int argc, char *argv[])
6126ba597c5SAnurag S. Maskey {
6136ba597c5SAnurag S. Maskey 	nwam_error_t		ret;
6146ba597c5SAnurag S. Maskey 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
6156ba597c5SAnurag S. Maskey 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
6166ba597c5SAnurag S. Maskey 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
6176ba597c5SAnurag S. Maskey 	const char		*name;
6186ba597c5SAnurag S. Maskey 	char			*realname = NULL;
6196ba597c5SAnurag S. Maskey 
6206ba597c5SAnurag S. Maskey 	/* parse_argv() returns only on success */
6216ba597c5SAnurag S. Maskey 	parse_argv(argc, argv, CMD_DISABLE, &type, &ncu_type, &ncu_class,
6226ba597c5SAnurag S. Maskey 	    &name);
6236ba597c5SAnurag S. Maskey 
6246ba597c5SAnurag S. Maskey 	/* deactivate the given profile */
6256ba597c5SAnurag S. Maskey 	switch (type) {
6266ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_LOC:
6276ba597c5SAnurag S. Maskey 		ret = loc_action(name, B_FALSE, &realname);
6286ba597c5SAnurag S. Maskey 		break;
6296ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_ENM:
6306ba597c5SAnurag S. Maskey 		ret = enm_action(name, B_FALSE, &realname);
6316ba597c5SAnurag S. Maskey 		break;
6326ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCU:
6336ba597c5SAnurag S. Maskey 		ret = ncu_action(name, NULL, ncu_type, B_FALSE, &realname);
6346ba597c5SAnurag S. Maskey 		break;
6356ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCP:
6366ba597c5SAnurag S. Maskey 		die("ncp's cannot be disabled.  Enable a different ncp to "
6376ba597c5SAnurag S. Maskey 		    "switch to that ncp");
6386ba597c5SAnurag S. Maskey 	}
6396ba597c5SAnurag S. Maskey 
6406ba597c5SAnurag S. Maskey 	switch (ret) {
6416ba597c5SAnurag S. Maskey 	case NWAM_SUCCESS:
6426ba597c5SAnurag S. Maskey 		(void) printf(gettext("Disabling %s '%s'\n"),
6436ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(type),
6446ba597c5SAnurag S. Maskey 		    realname != NULL ? realname : name);
6456ba597c5SAnurag S. Maskey 		break;
6466ba597c5SAnurag S. Maskey 	case NWAM_ENTITY_NOT_MANUAL:
6476ba597c5SAnurag S. Maskey 		die("Only profiles with manual activation-mode can be "
6486ba597c5SAnurag S. Maskey 		    "disabled");
6496ba597c5SAnurag S. Maskey 		break;
6506ba597c5SAnurag S. Maskey 	default:
6516ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "Could not disable %s '%s'",
6526ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(type),
6536ba597c5SAnurag S. Maskey 		    realname != NULL ? realname : name);
6546ba597c5SAnurag S. Maskey 	}
6556ba597c5SAnurag S. Maskey 	free(realname);
6566ba597c5SAnurag S. Maskey }
6576ba597c5SAnurag S. Maskey 
6586ba597c5SAnurag S. Maskey /* prints each column */
6596ba597c5SAnurag S. Maskey static boolean_t
6606ba597c5SAnurag S. Maskey print_list_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
6616ba597c5SAnurag S. Maskey {
6626ba597c5SAnurag S. Maskey 	profile_entry_t *pent = ofarg->ofmt_cbarg;
6636ba597c5SAnurag S. Maskey 
6646ba597c5SAnurag S. Maskey 	switch (ofarg->ofmt_id) {
6656ba597c5SAnurag S. Maskey 	case LIST_TYPE:
6666ba597c5SAnurag S. Maskey 		/* ncu:ip or ncu:phys for NCUs; ncp, loc, enm for others */
6676ba597c5SAnurag S. Maskey 		if (pent->p_type == NWAM_OBJECT_TYPE_NCU) {
6686ba597c5SAnurag S. Maskey 			const char *class;
6696ba597c5SAnurag S. Maskey 			if (nwam_uint64_get_value_string(NWAM_NCU_PROP_CLASS,
6706ba597c5SAnurag S. Maskey 			    pent->p_ncu_class, &class) != NWAM_SUCCESS)
6716ba597c5SAnurag S. Maskey 				class = ""; /* empty */
6726ba597c5SAnurag S. Maskey 			(void) snprintf(buf, bufsize, "%s:%s",
6736ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(pent->p_type), class);
6746ba597c5SAnurag S. Maskey 		} else {
6756ba597c5SAnurag S. Maskey 			(void) strlcpy(buf,
6766ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(pent->p_type), bufsize);
6776ba597c5SAnurag S. Maskey 		}
6786ba597c5SAnurag S. Maskey 		break;
6796ba597c5SAnurag S. Maskey 	case LIST_PROFILE:
6806ba597c5SAnurag S. Maskey 		(void) strlcpy(buf, pent->p_name, bufsize);
6816ba597c5SAnurag S. Maskey 		break;
6826ba597c5SAnurag S. Maskey 	case LIST_STATE:
6836ba597c5SAnurag S. Maskey 		(void) strlcpy(buf, nwam_state_to_string(pent->p_state),
6846ba597c5SAnurag S. Maskey 		    bufsize);
6856ba597c5SAnurag S. Maskey 		break;
6866ba597c5SAnurag S. Maskey 	case LIST_AUXSTATE:
6876ba597c5SAnurag S. Maskey 		(void) strlcpy(buf,
6886ba597c5SAnurag S. Maskey 		    nwam_aux_state_to_string(pent->p_aux_state), bufsize);
6896ba597c5SAnurag S. Maskey 		break;
6906ba597c5SAnurag S. Maskey 	default:
6916ba597c5SAnurag S. Maskey 		die("invalid print_list_cb() input: %d", ofarg->ofmt_id);
6926ba597c5SAnurag S. Maskey 		break;
6936ba597c5SAnurag S. Maskey 	}
6946ba597c5SAnurag S. Maskey 	return (B_TRUE);
6956ba597c5SAnurag S. Maskey }
6966ba597c5SAnurag S. Maskey 
6976ba597c5SAnurag S. Maskey /* returns the state and auxilliary state of the object */
6986ba597c5SAnurag S. Maskey static nwam_state_t
6996ba597c5SAnurag S. Maskey determine_object_state(nwam_object_type_t type, void *handle,
7006ba597c5SAnurag S. Maskey     nwam_aux_state_t *aux_statep)
7016ba597c5SAnurag S. Maskey {
7026ba597c5SAnurag S. Maskey 	nwam_state_t state;
7036ba597c5SAnurag S. Maskey 	nwam_aux_state_t astate;
7046ba597c5SAnurag S. Maskey 	nwam_error_t ret;
7056ba597c5SAnurag S. Maskey 
7066ba597c5SAnurag S. Maskey 	switch (type) {
7076ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_ENM:
7086ba597c5SAnurag S. Maskey 		ret = nwam_enm_get_state(handle, &state, &astate);
7096ba597c5SAnurag S. Maskey 		break;
7106ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_LOC:
7116ba597c5SAnurag S. Maskey 		ret = nwam_loc_get_state(handle, &state, &astate);
7126ba597c5SAnurag S. Maskey 		break;
7136ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCP:
7146ba597c5SAnurag S. Maskey 		ret = nwam_ncp_get_state(handle, &state, &astate);
7156ba597c5SAnurag S. Maskey 		break;
7166ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCU:
7176ba597c5SAnurag S. Maskey 		ret = nwam_ncu_get_state(handle, &state, &astate);
7186ba597c5SAnurag S. Maskey 		break;
7196ba597c5SAnurag S. Maskey 	default:
7206ba597c5SAnurag S. Maskey 		/* NOTREACHED */
7216ba597c5SAnurag S. Maskey 		break;
7226ba597c5SAnurag S. Maskey 	}
7236ba597c5SAnurag S. Maskey 
7246ba597c5SAnurag S. Maskey 	if (ret == NWAM_PERMISSION_DENIED) {
7256ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "could not get object state");
7266ba597c5SAnurag S. Maskey 	} else if (ret != NWAM_SUCCESS) {
7276ba597c5SAnurag S. Maskey 		state = NWAM_STATE_UNINITIALIZED;
7286ba597c5SAnurag S. Maskey 		astate = NWAM_AUX_STATE_UNINITIALIZED;
7296ba597c5SAnurag S. Maskey 	}
7306ba597c5SAnurag S. Maskey 
7316ba597c5SAnurag S. Maskey 	if (aux_statep != NULL)
7326ba597c5SAnurag S. Maskey 		*aux_statep = astate;
7336ba597c5SAnurag S. Maskey 	return (state);
7346ba597c5SAnurag S. Maskey }
7356ba597c5SAnurag S. Maskey 
7366ba597c5SAnurag S. Maskey /* populate profile_entry_t with values for object with given handle */
7376ba597c5SAnurag S. Maskey static int
7386ba597c5SAnurag S. Maskey add_to_profile_entry(nwam_object_type_t type, void *handle,
7396ba597c5SAnurag S. Maskey     profile_entry_t *pent)
7406ba597c5SAnurag S. Maskey {
7416ba597c5SAnurag S. Maskey 	char		*name;
7426ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
7436ba597c5SAnurag S. Maskey 
7446ba597c5SAnurag S. Maskey 	pent->p_type = type;
7456ba597c5SAnurag S. Maskey 	if (type == NWAM_OBJECT_TYPE_NCU) {
7466ba597c5SAnurag S. Maskey 		nwam_ncu_class_t class;
7476ba597c5SAnurag S. Maskey 		if ((ret = nwam_ncu_get_ncu_class(handle, &class))
7486ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
7496ba597c5SAnurag S. Maskey 			return (ret);
7506ba597c5SAnurag S. Maskey 		pent->p_ncu_class = class;
7516ba597c5SAnurag S. Maskey 	} else {
7526ba597c5SAnurag S. Maskey 		pent->p_ncu_class = -1;
7536ba597c5SAnurag S. Maskey 	}
7546ba597c5SAnurag S. Maskey 
7556ba597c5SAnurag S. Maskey 	switch (type) {
7566ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_ENM:
7576ba597c5SAnurag S. Maskey 		ret = nwam_enm_get_name(handle, &name);
7586ba597c5SAnurag S. Maskey 		break;
7596ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_LOC:
7606ba597c5SAnurag S. Maskey 		ret = nwam_loc_get_name(handle, &name);
7616ba597c5SAnurag S. Maskey 		break;
7626ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCP:
7636ba597c5SAnurag S. Maskey 		ret = nwam_ncp_get_name(handle, &name);
7646ba597c5SAnurag S. Maskey 		break;
7656ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCU:
7666ba597c5SAnurag S. Maskey 		ret = nwam_ncu_get_name(handle, &name);
7676ba597c5SAnurag S. Maskey 		break;
7686ba597c5SAnurag S. Maskey 	default:
7696ba597c5SAnurag S. Maskey 		/* NOTREACHED */
7706ba597c5SAnurag S. Maskey 		break;
7716ba597c5SAnurag S. Maskey 	}
7726ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS) {
7736ba597c5SAnurag S. Maskey 		return (ret);
7746ba597c5SAnurag S. Maskey 	}
7756ba597c5SAnurag S. Maskey 	(void) strlcpy(pent->p_name, name, sizeof (pent->p_name));
7766ba597c5SAnurag S. Maskey 	free(name);
7776ba597c5SAnurag S. Maskey 
7786ba597c5SAnurag S. Maskey 	pent->p_state = determine_object_state(type, handle,
7796ba597c5SAnurag S. Maskey 	    &pent->p_aux_state);
7806ba597c5SAnurag S. Maskey 
7816ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
7826ba597c5SAnurag S. Maskey }
7836ba597c5SAnurag S. Maskey 
7846ba597c5SAnurag S. Maskey /* callback functions used by walk */
7856ba597c5SAnurag S. Maskey 
7866ba597c5SAnurag S. Maskey static int
7876ba597c5SAnurag S. Maskey list_ncu_cb(nwam_ncu_handle_t ncuh, void *arg)
7886ba597c5SAnurag S. Maskey {
7896ba597c5SAnurag S. Maskey 	ofmt_handle_t	ofmt = arg;
7906ba597c5SAnurag S. Maskey 	profile_entry_t pent;
7916ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
7926ba597c5SAnurag S. Maskey 
7936ba597c5SAnurag S. Maskey 	bzero(&pent, sizeof (profile_entry_t));
7946ba597c5SAnurag S. Maskey 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCU, ncuh, &pent);
7956ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS)
7966ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "could not add ncu to list");
7976ba597c5SAnurag S. Maskey 	ofmt_print(ofmt, &pent);
7986ba597c5SAnurag S. Maskey 	return (0);
7996ba597c5SAnurag S. Maskey }
8006ba597c5SAnurag S. Maskey 
8016ba597c5SAnurag S. Maskey static int
8026ba597c5SAnurag S. Maskey list_ncp_cb(nwam_ncp_handle_t ncph, void *arg)
8036ba597c5SAnurag S. Maskey {
8046ba597c5SAnurag S. Maskey 	ofmt_handle_t	ofmt = arg;
8056ba597c5SAnurag S. Maskey 	profile_entry_t pent;
8066ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
8076ba597c5SAnurag S. Maskey 	nwam_state_t	state;
8086ba597c5SAnurag S. Maskey 
8096ba597c5SAnurag S. Maskey 	bzero(&pent, sizeof (profile_entry_t));
8106ba597c5SAnurag S. Maskey 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCP, ncph, &pent);
8116ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS)
8126ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "could not add ncp to list");
8136ba597c5SAnurag S. Maskey 	ofmt_print(ofmt, &pent);
8146ba597c5SAnurag S. Maskey 
8156ba597c5SAnurag S. Maskey 	state = determine_object_state(NWAM_OBJECT_TYPE_NCP, ncph, NULL);
8166ba597c5SAnurag S. Maskey 	if (state == NWAM_STATE_ONLINE) {
8176ba597c5SAnurag S. Maskey 		(void) nwam_ncp_walk_ncus(ncph, list_ncu_cb, ofmt,
8186ba597c5SAnurag S. Maskey 		    NWAM_FLAG_NCU_TYPE_ALL, NULL);
8196ba597c5SAnurag S. Maskey 	}
8206ba597c5SAnurag S. Maskey 	return (0);
8216ba597c5SAnurag S. Maskey }
8226ba597c5SAnurag S. Maskey 
8236ba597c5SAnurag S. Maskey static int
8246ba597c5SAnurag S. Maskey list_loc_cb(nwam_loc_handle_t loch, void *arg)
8256ba597c5SAnurag S. Maskey {
8266ba597c5SAnurag S. Maskey 	ofmt_handle_t	ofmt = arg;
8276ba597c5SAnurag S. Maskey 	profile_entry_t pent;
8286ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
8296ba597c5SAnurag S. Maskey 
8306ba597c5SAnurag S. Maskey 	bzero(&pent, sizeof (profile_entry_t));
8316ba597c5SAnurag S. Maskey 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_LOC, loch, &pent);
8326ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS)
8336ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "could not add loc to list");
8346ba597c5SAnurag S. Maskey 	ofmt_print(ofmt, &pent);
8356ba597c5SAnurag S. Maskey 	return (0);
8366ba597c5SAnurag S. Maskey }
8376ba597c5SAnurag S. Maskey 
8386ba597c5SAnurag S. Maskey static int
8396ba597c5SAnurag S. Maskey list_enm_cb(nwam_enm_handle_t enmh, void *arg)
8406ba597c5SAnurag S. Maskey {
8416ba597c5SAnurag S. Maskey 	ofmt_handle_t	ofmt = arg;
8426ba597c5SAnurag S. Maskey 	profile_entry_t pent;
8436ba597c5SAnurag S. Maskey 	nwam_error_t	ret;
8446ba597c5SAnurag S. Maskey 
8456ba597c5SAnurag S. Maskey 	bzero(&pent, sizeof (profile_entry_t));
8466ba597c5SAnurag S. Maskey 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_ENM, enmh, &pent);
8476ba597c5SAnurag S. Maskey 	if (ret != NWAM_SUCCESS)
8486ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "could not add enm to list");
8496ba597c5SAnurag S. Maskey 	ofmt_print(ofmt, &pent);
8506ba597c5SAnurag S. Maskey 	return (0);
8516ba597c5SAnurag S. Maskey }
8526ba597c5SAnurag S. Maskey 
8536ba597c5SAnurag S. Maskey /*
8546ba597c5SAnurag S. Maskey  * lists all profiles and their state
8556ba597c5SAnurag S. Maskey  */
8566ba597c5SAnurag S. Maskey static void
8576ba597c5SAnurag S. Maskey list_func(int argc, char *argv[])
8586ba597c5SAnurag S. Maskey {
8596ba597c5SAnurag S. Maskey 	nwam_error_t		ret = NWAM_SUCCESS;
8606ba597c5SAnurag S. Maskey 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
8616ba597c5SAnurag S. Maskey 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
8626ba597c5SAnurag S. Maskey 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
8636ba597c5SAnurag S. Maskey 	char			*name = NULL;
8646ba597c5SAnurag S. Maskey 
8656ba597c5SAnurag S. Maskey 	ofmt_handle_t	ofmt;
8666ba597c5SAnurag S. Maskey 	ofmt_status_t	oferr;
8676ba597c5SAnurag S. Maskey 	char		*default_fields = "type,profile,state";
8686ba597c5SAnurag S. Maskey 	char		*extended_fields = "type,profile,state,auxiliary state";
8696ba597c5SAnurag S. Maskey 	char		*fields = NULL;
8706ba597c5SAnurag S. Maskey 
8716ba597c5SAnurag S. Maskey 	/* parse_argv() returns only on success */
8726ba597c5SAnurag S. Maskey 	parse_argv(argc, argv, CMD_LIST, &type, &ncu_type, &ncu_class,
8736ba597c5SAnurag S. Maskey 	    (const char **)&name);
8746ba597c5SAnurag S. Maskey 
8756ba597c5SAnurag S. Maskey 	if (extended_list)
8766ba597c5SAnurag S. Maskey 		fields = extended_fields;
8776ba597c5SAnurag S. Maskey 	else
8786ba597c5SAnurag S. Maskey 		fields = default_fields;
8796ba597c5SAnurag S. Maskey 	oferr = ofmt_open(fields, list_fields, 0, 0, &ofmt);
8806ba597c5SAnurag S. Maskey 	if (oferr != OFMT_SUCCESS) {
8816ba597c5SAnurag S. Maskey 		char buf[OFMT_BUFSIZE];
8826ba597c5SAnurag S. Maskey 		(void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
8836ba597c5SAnurag S. Maskey 		die("ofmt_open() failed: %s", buf);
8846ba597c5SAnurag S. Maskey 	}
8856ba597c5SAnurag S. Maskey 
8866ba597c5SAnurag S. Maskey 	/* object-name given in command-line */
8876ba597c5SAnurag S. Maskey 	if (name != NULL) {
8886ba597c5SAnurag S. Maskey 		boolean_t found = B_FALSE;
8896ba597c5SAnurag S. Maskey 
8906ba597c5SAnurag S. Maskey 		/*
8916ba597c5SAnurag S. Maskey 		 * If objects with different types have the same name
8926ba597c5SAnurag S. Maskey 		 * (type = UNKNOWN), then try to open handle for each object
8936ba597c5SAnurag S. Maskey 		 * and print if successful.
8946ba597c5SAnurag S. Maskey 		 */
8956ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_NCP ||
8966ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
8976ba597c5SAnurag S. Maskey 			nwam_ncp_handle_t ncph;
8986ba597c5SAnurag S. Maskey 			if (nwam_ncp_read(name, 0, &ncph) == NWAM_SUCCESS) {
8996ba597c5SAnurag S. Maskey 				found = B_TRUE;
9006ba597c5SAnurag S. Maskey 				(void) list_ncp_cb(ncph, ofmt);
9016ba597c5SAnurag S. Maskey 				nwam_ncp_free(ncph);
9026ba597c5SAnurag S. Maskey 			}
9036ba597c5SAnurag S. Maskey 		}
9046ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_NCU ||
9056ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9066ba597c5SAnurag S. Maskey 			nwam_ncp_handle_t ncph;
9076ba597c5SAnurag S. Maskey 			nwam_ncu_handle_t ncuh;
9086ba597c5SAnurag S. Maskey 
9096ba597c5SAnurag S. Maskey 			if ((ncph = determine_active_ncp()) != NULL) {
9106ba597c5SAnurag S. Maskey 				ret = nwam_ncu_read(ncph, name, ncu_type, 0,
9116ba597c5SAnurag S. Maskey 				    &ncuh);
9126ba597c5SAnurag S. Maskey 				if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
9136ba597c5SAnurag S. Maskey 					found = B_TRUE;
9146ba597c5SAnurag S. Maskey 					if (nwam_ncu_read(ncph, name,
9156ba597c5SAnurag S. Maskey 					    NWAM_NCU_TYPE_LINK, 0, &ncuh)
9166ba597c5SAnurag S. Maskey 					    == NWAM_SUCCESS) {
9176ba597c5SAnurag S. Maskey 						(void) list_ncu_cb(ncuh, ofmt);
9186ba597c5SAnurag S. Maskey 						nwam_ncu_free(ncuh);
9196ba597c5SAnurag S. Maskey 					}
9206ba597c5SAnurag S. Maskey 					if (nwam_ncu_read(ncph, name,
9216ba597c5SAnurag S. Maskey 					    NWAM_NCU_TYPE_INTERFACE, 0, &ncuh)
9226ba597c5SAnurag S. Maskey 					    == NWAM_SUCCESS) {
9236ba597c5SAnurag S. Maskey 						(void) list_ncu_cb(ncuh, ofmt);
9246ba597c5SAnurag S. Maskey 						nwam_ncu_free(ncuh);
9256ba597c5SAnurag S. Maskey 					}
9266ba597c5SAnurag S. Maskey 				} else if (ret == NWAM_SUCCESS) {
9276ba597c5SAnurag S. Maskey 					found = B_TRUE;
9286ba597c5SAnurag S. Maskey 					(void) list_ncu_cb(ncuh, ofmt);
9296ba597c5SAnurag S. Maskey 					nwam_ncu_free(ncuh);
9306ba597c5SAnurag S. Maskey 				}
9316ba597c5SAnurag S. Maskey 				nwam_ncp_free(ncph);
9326ba597c5SAnurag S. Maskey 			}
9336ba597c5SAnurag S. Maskey 		}
9346ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_LOC ||
9356ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9366ba597c5SAnurag S. Maskey 			nwam_loc_handle_t loch;
9376ba597c5SAnurag S. Maskey 			if (nwam_loc_read(name, 0, &loch) == NWAM_SUCCESS) {
9386ba597c5SAnurag S. Maskey 				found = B_TRUE;
9396ba597c5SAnurag S. Maskey 				(void) list_loc_cb(loch, ofmt);
9406ba597c5SAnurag S. Maskey 				nwam_loc_free(loch);
9416ba597c5SAnurag S. Maskey 			}
9426ba597c5SAnurag S. Maskey 		}
9436ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_ENM ||
9446ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9456ba597c5SAnurag S. Maskey 			nwam_enm_handle_t enmh;
9466ba597c5SAnurag S. Maskey 			if (nwam_enm_read(name, 0, &enmh) == NWAM_SUCCESS) {
9476ba597c5SAnurag S. Maskey 				found = B_TRUE;
9486ba597c5SAnurag S. Maskey 				(void) list_enm_cb(enmh, ofmt);
9496ba597c5SAnurag S. Maskey 				nwam_enm_free(enmh);
9506ba597c5SAnurag S. Maskey 			}
9516ba597c5SAnurag S. Maskey 		}
9526ba597c5SAnurag S. Maskey 		/* If at least object is found, don't return error */
9536ba597c5SAnurag S. Maskey 		if (found)
9546ba597c5SAnurag S. Maskey 			ret = NWAM_SUCCESS;
9556ba597c5SAnurag S. Maskey 		else
9566ba597c5SAnurag S. Maskey 			ret = NWAM_ENTITY_NOT_FOUND;
9576ba597c5SAnurag S. Maskey 	}
9586ba597c5SAnurag S. Maskey 
9596ba597c5SAnurag S. Maskey 	/* object-name not given in command-line */
9606ba597c5SAnurag S. Maskey 	if (name == NULL) {
9616ba597c5SAnurag S. Maskey 		/*
9626ba597c5SAnurag S. Maskey 		 * If type given (type != UNKNOWN), just walk objects in that
9636ba597c5SAnurag S. Maskey 		 * type.  Otherwise, walk all ncp, ncu, loc and enm.
9646ba597c5SAnurag S. Maskey 		 */
9656ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_NCP ||
9666ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9676ba597c5SAnurag S. Maskey 			ret = nwam_walk_ncps(list_ncp_cb, ofmt, 0, NULL);
9686ba597c5SAnurag S. Maskey 			if (ret != NWAM_SUCCESS)
9696ba597c5SAnurag S. Maskey 				goto done;
9706ba597c5SAnurag S. Maskey 		}
9716ba597c5SAnurag S. Maskey 		/* no UNKNOWN for NCUs.  They walked with active NCP above */
9726ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_NCU) {
9736ba597c5SAnurag S. Maskey 			nwam_ncp_handle_t ncph;
9746ba597c5SAnurag S. Maskey 			if ((ncph = determine_active_ncp()) != NULL) {
9756ba597c5SAnurag S. Maskey 				ret = nwam_ncp_walk_ncus(ncph, list_ncu_cb,
9766ba597c5SAnurag S. Maskey 				    ofmt, nwam_ncu_class_to_flag(ncu_class),
9776ba597c5SAnurag S. Maskey 				    NULL);
9786ba597c5SAnurag S. Maskey 				nwam_ncp_free(ncph);
9796ba597c5SAnurag S. Maskey 				if (ret != NWAM_SUCCESS)
9806ba597c5SAnurag S. Maskey 					goto done;
9816ba597c5SAnurag S. Maskey 			}
9826ba597c5SAnurag S. Maskey 		}
9836ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_LOC ||
9846ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9856ba597c5SAnurag S. Maskey 			ret = nwam_walk_locs(list_loc_cb, ofmt,
9866ba597c5SAnurag S. Maskey 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
9876ba597c5SAnurag S. Maskey 			if (ret != NWAM_SUCCESS)
9886ba597c5SAnurag S. Maskey 				goto done;
9896ba597c5SAnurag S. Maskey 		}
9906ba597c5SAnurag S. Maskey 		if (type == NWAM_OBJECT_TYPE_ENM ||
9916ba597c5SAnurag S. Maskey 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
9926ba597c5SAnurag S. Maskey 			ret = nwam_walk_enms(list_enm_cb, ofmt,
9936ba597c5SAnurag S. Maskey 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
9946ba597c5SAnurag S. Maskey 			if (ret != NWAM_SUCCESS)
9956ba597c5SAnurag S. Maskey 				goto done;
9966ba597c5SAnurag S. Maskey 		}
9976ba597c5SAnurag S. Maskey 	}
9986ba597c5SAnurag S. Maskey 
9996ba597c5SAnurag S. Maskey done:
10006ba597c5SAnurag S. Maskey 	ofmt_close(ofmt);
10016ba597c5SAnurag S. Maskey 	if (ret == NWAM_ENTITY_NOT_FOUND && name != NULL)
10026ba597c5SAnurag S. Maskey 		die("no profile matched '%s'", name);
10036ba597c5SAnurag S. Maskey 	else if (ret != NWAM_SUCCESS)
10046ba597c5SAnurag S. Maskey 		die_nwamerr(ret, "list failed during walk");
10056ba597c5SAnurag S. Maskey }
10066ba597c5SAnurag S. Maskey 
10076ba597c5SAnurag S. Maskey /*
10086ba597c5SAnurag S. Maskey  * Print NWAM events.
10096ba597c5SAnurag S. Maskey  */
10106ba597c5SAnurag S. Maskey static void
10116ba597c5SAnurag S. Maskey eventhandler(nwam_event_t event)
10126ba597c5SAnurag S. Maskey {
10136ba597c5SAnurag S. Maskey 	char description[DESCRIPTION_WIDTH];
10146ba597c5SAnurag S. Maskey 	char statestr[DESCRIPTION_WIDTH];
10156ba597c5SAnurag S. Maskey 	char objstr[DESCRIPTION_WIDTH];
10166ba597c5SAnurag S. Maskey 	char *object = NULL;
10176ba597c5SAnurag S. Maskey 	const char *action = NULL;
10186ba597c5SAnurag S. Maskey 	char *state = NULL;
10196ba597c5SAnurag S. Maskey 	boolean_t display = B_TRUE;
10206ba597c5SAnurag S. Maskey 	int i;
10216ba597c5SAnurag S. Maskey 	nwam_wlan_t *wlans;
10226ba597c5SAnurag S. Maskey 
10236ba597c5SAnurag S. Maskey 	(void) strlcpy(description, "-", sizeof (description));
10246ba597c5SAnurag S. Maskey 
10256ba597c5SAnurag S. Maskey 	switch (event->nwe_type) {
10266ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_OBJECT_ACTION:
10276ba597c5SAnurag S. Maskey 		action = nwam_action_to_string
10286ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_object_action.nwe_action);
10296ba597c5SAnurag S. Maskey 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
10306ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string
10316ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_object_action.nwe_object_type),
10326ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_object_action.nwe_name);
10336ba597c5SAnurag S. Maskey 		object = objstr;
10346ba597c5SAnurag S. Maskey 		break;
10356ba597c5SAnurag S. Maskey 
10366ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_OBJECT_STATE:
10376ba597c5SAnurag S. Maskey 		(void) snprintf(statestr, sizeof (statestr), "%s, %s",
10386ba597c5SAnurag S. Maskey 		    nwam_state_to_string
10396ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_object_state.nwe_state),
10406ba597c5SAnurag S. Maskey 		    nwam_aux_state_to_string
10416ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_object_state.nwe_aux_state));
10426ba597c5SAnurag S. Maskey 		state = statestr;
10436ba597c5SAnurag S. Maskey 
10446ba597c5SAnurag S. Maskey 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
10456ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string
10466ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_object_state.nwe_object_type),
10476ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_object_state.nwe_name);
10486ba597c5SAnurag S. Maskey 		object = objstr;
10496ba597c5SAnurag S. Maskey 		break;
10506ba597c5SAnurag S. Maskey 
10516ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_PRIORITY_GROUP:
10526ba597c5SAnurag S. Maskey 		(void) snprintf(description, DESCRIPTION_WIDTH,
10536ba597c5SAnurag S. Maskey 		    "priority-group: %d",
10546ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_priority_group_info.nwe_priority);
10556ba597c5SAnurag S. Maskey 		break;
10566ba597c5SAnurag S. Maskey 
10576ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT:
10586ba597c5SAnurag S. Maskey 		(void) printf("%-*s \n", EVENT_WIDTH,
10596ba597c5SAnurag S. Maskey 		    nwam_event_type_to_string(event->nwe_type));
10606ba597c5SAnurag S. Maskey 		wlans = event->nwe_data.nwe_wlan_info.nwe_wlans;
10616ba597c5SAnurag S. Maskey 		for (i = 0;
10626ba597c5SAnurag S. Maskey 		    i < event->nwe_data.nwe_wlan_info.nwe_num_wlans;
10636ba597c5SAnurag S. Maskey 		    i++) {
10646ba597c5SAnurag S. Maskey 			(void) snprintf(description, DESCRIPTION_WIDTH,
10656ba597c5SAnurag S. Maskey 			    "%d: %c%c ESSID %s BSSID %s", i + 1,
10666ba597c5SAnurag S. Maskey 			    wlans[i].nww_selected ? 'S' : '-',
10676ba597c5SAnurag S. Maskey 			    wlans[i].nww_connected ? 'C' : '-',
10686ba597c5SAnurag S. Maskey 			    wlans[i].nww_essid, wlans[i].nww_bssid);
10696ba597c5SAnurag S. Maskey 			(void) printf("%-*s %-*s\n", EVENT_WIDTH, "-",
10706ba597c5SAnurag S. Maskey 			    DESCRIPTION_WIDTH, description);
10716ba597c5SAnurag S. Maskey 		}
10726ba597c5SAnurag S. Maskey 		display = B_FALSE;
10736ba597c5SAnurag S. Maskey 		break;
10746ba597c5SAnurag S. Maskey 
10756ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE:
10766ba597c5SAnurag S. Maskey 		(void) printf("%-*s \n", EVENT_WIDTH,
10776ba597c5SAnurag S. Maskey 		    nwam_event_type_to_string(event->nwe_type));
10786ba597c5SAnurag S. Maskey 		display = B_FALSE;
10796ba597c5SAnurag S. Maskey 		break;
10806ba597c5SAnurag S. Maskey 
10816ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_WLAN_NEED_KEY:
10826ba597c5SAnurag S. Maskey 		(void) printf("%-*s \n", EVENT_WIDTH,
10836ba597c5SAnurag S. Maskey 		    nwam_event_type_to_string(event->nwe_type));
10846ba597c5SAnurag S. Maskey 		display = B_FALSE;
10856ba597c5SAnurag S. Maskey 		break;
10866ba597c5SAnurag S. Maskey 
10876ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT:
10886ba597c5SAnurag S. Maskey 		(void) snprintf(description, DESCRIPTION_WIDTH,
10896ba597c5SAnurag S. Maskey 		    gettext("connect to WLAN ESSID %s, BSSID %s %s"),
10906ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_essid,
10916ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_bssid,
10926ba597c5SAnurag S. Maskey 		    event->nwe_data.nwe_wlan_info.nwe_connected ?
10936ba597c5SAnurag S. Maskey 		    "succeeded" : "failed");
10946ba597c5SAnurag S. Maskey 		break;
10956ba597c5SAnurag S. Maskey 
10966ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_INFO:
10976ba597c5SAnurag S. Maskey 		(void) snprintf(description, sizeof (description),
10986ba597c5SAnurag S. Maskey 		    "%s", event->nwe_data.nwe_info.nwe_message);
10996ba597c5SAnurag S. Maskey 		break;
11006ba597c5SAnurag S. Maskey 
11016ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_IF_ACTION:
11026ba597c5SAnurag S. Maskey 		action = nwam_action_to_string
11036ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_if_action.nwe_action);
11046ba597c5SAnurag S. Maskey 		object = event->nwe_data.nwe_if_action.nwe_name;
11056ba597c5SAnurag S. Maskey 		break;
11066ba597c5SAnurag S. Maskey 
11076ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_IF_STATE:
11086ba597c5SAnurag S. Maskey 		object = event->nwe_data.nwe_if_state.nwe_name;
11096ba597c5SAnurag S. Maskey 		if (event->nwe_data.nwe_if_state.nwe_addr_valid) {
11106ba597c5SAnurag S. Maskey 			struct sockaddr_storage *address =
11116ba597c5SAnurag S. Maskey 			    &(event->nwe_data.nwe_if_state.nwe_addr);
1112*f6da83d4SAnurag S. Maskey 			struct sockaddr_storage *netmask =
1113*f6da83d4SAnurag S. Maskey 			    &(event->nwe_data.nwe_if_state.nwe_netmask);
11146ba597c5SAnurag S. Maskey 			struct sockaddr_in *v4addr;
11156ba597c5SAnurag S. Maskey 			struct sockaddr_in6 *v6addr;
11166ba597c5SAnurag S. Maskey 			char addrstr[NWAM_MAX_VALUE_LEN];
1117*f6da83d4SAnurag S. Maskey 			int plen = mask2plen(netmask);
11186ba597c5SAnurag S. Maskey 
11196ba597c5SAnurag S. Maskey 			switch (address->ss_family) {
11206ba597c5SAnurag S. Maskey 			case AF_INET:
11216ba597c5SAnurag S. Maskey 				v4addr = (struct sockaddr_in *)address;
11226ba597c5SAnurag S. Maskey 				(void) inet_ntop(AF_INET, &v4addr->sin_addr,
11236ba597c5SAnurag S. Maskey 				    addrstr, sizeof (addrstr));
11246ba597c5SAnurag S. Maskey 				break;
11256ba597c5SAnurag S. Maskey 			case AF_INET6:
11266ba597c5SAnurag S. Maskey 				v6addr = (struct sockaddr_in6 *)address;
11276ba597c5SAnurag S. Maskey 				(void) inet_ntop(AF_INET6, &v6addr->sin6_addr,
11286ba597c5SAnurag S. Maskey 				    addrstr, sizeof (addrstr));
11296ba597c5SAnurag S. Maskey 				break;
11306ba597c5SAnurag S. Maskey 			}
11316ba597c5SAnurag S. Maskey 			(void) snprintf(statestr, sizeof (statestr),
1132*f6da83d4SAnurag S. Maskey 			    "flags %x addr %s/%d",
1133*f6da83d4SAnurag S. Maskey 			    event->nwe_data.nwe_if_state.nwe_flags,
1134*f6da83d4SAnurag S. Maskey 			    addrstr, plen);
11356ba597c5SAnurag S. Maskey 		} else {
11366ba597c5SAnurag S. Maskey 			(void) snprintf(statestr, sizeof (statestr),
1137*f6da83d4SAnurag S. Maskey 			    "flags %x", event->nwe_data.nwe_if_state.nwe_flags);
11386ba597c5SAnurag S. Maskey 		}
11396ba597c5SAnurag S. Maskey 		state = statestr;
11406ba597c5SAnurag S. Maskey 		break;
11416ba597c5SAnurag S. Maskey 
11426ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_LINK_ACTION:
11436ba597c5SAnurag S. Maskey 		action = nwam_action_to_string
11446ba597c5SAnurag S. Maskey 		    (event->nwe_data.nwe_link_action.nwe_action);
11456ba597c5SAnurag S. Maskey 		object = event->nwe_data.nwe_link_action.nwe_name;
11466ba597c5SAnurag S. Maskey 		break;
11476ba597c5SAnurag S. Maskey 
11486ba597c5SAnurag S. Maskey 	case NWAM_EVENT_TYPE_LINK_STATE:
11496ba597c5SAnurag S. Maskey 		state = event->nwe_data.nwe_link_state.nwe_link_up ?
11506ba597c5SAnurag S. Maskey 		    "up" : "down";
11516ba597c5SAnurag S. Maskey 		object = event->nwe_data.nwe_link_state.nwe_name;
11526ba597c5SAnurag S. Maskey 		break;
11536ba597c5SAnurag S. Maskey 	}
11546ba597c5SAnurag S. Maskey 
11556ba597c5SAnurag S. Maskey 	if (object != NULL && action != NULL) {
11566ba597c5SAnurag S. Maskey 		(void) snprintf(description, sizeof (description),
11576ba597c5SAnurag S. Maskey 		    "%s -> action %s", object, action);
11586ba597c5SAnurag S. Maskey 	} else if (object != NULL && state != NULL) {
11596ba597c5SAnurag S. Maskey 		(void) snprintf(description, sizeof (description),
11606ba597c5SAnurag S. Maskey 		    "%s -> state %s", object, state);
11616ba597c5SAnurag S. Maskey 	}
11626ba597c5SAnurag S. Maskey 
11636ba597c5SAnurag S. Maskey 	if (display) {
11646ba597c5SAnurag S. Maskey 		(void) printf("%-*s %-*s\n", EVENT_WIDTH,
11656ba597c5SAnurag S. Maskey 		    nwam_event_type_to_string(event->nwe_type),
11666ba597c5SAnurag S. Maskey 		    DESCRIPTION_WIDTH,
11676ba597c5SAnurag S. Maskey 		    description);
11686ba597c5SAnurag S. Maskey 	}
11696ba597c5SAnurag S. Maskey }
11706ba597c5SAnurag S. Maskey 
11716ba597c5SAnurag S. Maskey /*
11726ba597c5SAnurag S. Maskey  * listens for events and displays them via the eventhandler() function above.
11736ba597c5SAnurag S. Maskey  */
11746ba597c5SAnurag S. Maskey /* ARGSUSED */
11756ba597c5SAnurag S. Maskey static void
11766ba597c5SAnurag S. Maskey show_events_func(int argc, char *argv[])
11776ba597c5SAnurag S. Maskey {
11786ba597c5SAnurag S. Maskey 	nwam_error_t err;
11796ba597c5SAnurag S. Maskey 	nwam_event_t event;
11806ba597c5SAnurag S. Maskey 
11816ba597c5SAnurag S. Maskey 	err = nwam_events_init();
11826ba597c5SAnurag S. Maskey 
11836ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
11846ba597c5SAnurag S. Maskey 		die_nwamerr(err, "could not bind to receive events");
11856ba597c5SAnurag S. Maskey 
11866ba597c5SAnurag S. Maskey 	/* print header */
11876ba597c5SAnurag S. Maskey 	(void) printf("%-*s %-*s\n", EVENT_WIDTH, "EVENT",
11886ba597c5SAnurag S. Maskey 	    DESCRIPTION_WIDTH, "DESCRIPTION");
11896ba597c5SAnurag S. Maskey 
11906ba597c5SAnurag S. Maskey 	do {
11916ba597c5SAnurag S. Maskey 		/*
11926ba597c5SAnurag S. Maskey 		 * Needed for stdout redirection to ensure event output is
11936ba597c5SAnurag S. Maskey 		 * regularly flushed to file.
11946ba597c5SAnurag S. Maskey 		 */
11956ba597c5SAnurag S. Maskey 		(void) fflush(stdout);
11966ba597c5SAnurag S. Maskey 		err = nwam_event_wait(&event);
11976ba597c5SAnurag S. Maskey 		if (err == NWAM_SUCCESS) {
11986ba597c5SAnurag S. Maskey 			eventhandler(event);
11996ba597c5SAnurag S. Maskey 			nwam_event_free(event);
12006ba597c5SAnurag S. Maskey 		}
12016ba597c5SAnurag S. Maskey 	} while (err == NWAM_SUCCESS);
12026ba597c5SAnurag S. Maskey 	die_nwamerr(err, "event handling stopped");
12036ba597c5SAnurag S. Maskey }
12046ba597c5SAnurag S. Maskey 
12056ba597c5SAnurag S. Maskey /* May need to convert case-insensitive link name match to case-sensitive one */
12066ba597c5SAnurag S. Maskey static nwam_error_t
12076ba597c5SAnurag S. Maskey name_to_linkname(char *name, char **linknamep)
12086ba597c5SAnurag S. Maskey {
12096ba597c5SAnurag S. Maskey 	nwam_error_t err;
12106ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph = NULL;
12116ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh = NULL;
12126ba597c5SAnurag S. Maskey 
12136ba597c5SAnurag S. Maskey 	if ((ncph = determine_active_ncp()) == NULL)
12146ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_FOUND);
12156ba597c5SAnurag S. Maskey 
12166ba597c5SAnurag S. Maskey 	err = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK, 0, &ncuh);
12176ba597c5SAnurag S. Maskey 	if (err == NWAM_SUCCESS)
12186ba597c5SAnurag S. Maskey 		err = nwam_ncu_get_name(ncuh, linknamep);
12196ba597c5SAnurag S. Maskey 
12206ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
12216ba597c5SAnurag S. Maskey 	nwam_ncu_free(ncuh);
12226ba597c5SAnurag S. Maskey 	return (err);
12236ba597c5SAnurag S. Maskey }
12246ba597c5SAnurag S. Maskey 
12256ba597c5SAnurag S. Maskey static void
12266ba597c5SAnurag S. Maskey scan_wifi_func(int argc, char *argv[])
12276ba597c5SAnurag S. Maskey {
12286ba597c5SAnurag S. Maskey 	nwam_error_t err;
12296ba597c5SAnurag S. Maskey 	char *linkname = NULL;
12306ba597c5SAnurag S. Maskey 
12316ba597c5SAnurag S. Maskey 	if (argc != 1)
12326ba597c5SAnurag S. Maskey 		die_usage(CMD_SCAN_WIFI);
12336ba597c5SAnurag S. Maskey 
12346ba597c5SAnurag S. Maskey 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS)
12356ba597c5SAnurag S. Maskey 		die_nwamerr(err, "scan request failed for %s", argv[0]);
12366ba597c5SAnurag S. Maskey 
12376ba597c5SAnurag S. Maskey 	err = nwam_wlan_scan(linkname);
12386ba597c5SAnurag S. Maskey 
12396ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
12406ba597c5SAnurag S. Maskey 		die_nwamerr(err, "scan request failed for %s", linkname);
12416ba597c5SAnurag S. Maskey 
12426ba597c5SAnurag S. Maskey 	free(linkname);
12436ba597c5SAnurag S. Maskey }
12446ba597c5SAnurag S. Maskey 
12456ba597c5SAnurag S. Maskey static void
12466ba597c5SAnurag S. Maskey select_wifi_func(int argc, char *argv[])
12476ba597c5SAnurag S. Maskey {
12486ba597c5SAnurag S. Maskey 	nwam_error_t err;
12496ba597c5SAnurag S. Maskey 	char *linkname = NULL;
12506ba597c5SAnurag S. Maskey 	uint_t i, choice, num_wlans = 0;
12516ba597c5SAnurag S. Maskey 	uint32_t security_mode;
12526ba597c5SAnurag S. Maskey 	boolean_t have_key = B_FALSE;
12536ba597c5SAnurag S. Maskey 	nwam_wlan_t *wlans = NULL;
12546ba597c5SAnurag S. Maskey 	char choicestr[NWAM_MAX_VALUE_LEN];
12556ba597c5SAnurag S. Maskey 	char modestr[NWAM_MAX_VALUE_LEN];
12566ba597c5SAnurag S. Maskey 	char essid[NWAM_MAX_VALUE_LEN];
12576ba597c5SAnurag S. Maskey 	char bssid[NWAM_MAX_VALUE_LEN];
12586ba597c5SAnurag S. Maskey 
12596ba597c5SAnurag S. Maskey 	if (argc != 1)
12606ba597c5SAnurag S. Maskey 		die_usage(CMD_SELECT_WIFI);
12616ba597c5SAnurag S. Maskey 
12626ba597c5SAnurag S. Maskey 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS) {
12636ba597c5SAnurag S. Maskey 		die_nwamerr(err, "could not retrieve scan results for %s",
12646ba597c5SAnurag S. Maskey 		    argv[0]);
12656ba597c5SAnurag S. Maskey 	}
12666ba597c5SAnurag S. Maskey 	err = nwam_wlan_get_scan_results(linkname, &num_wlans, &wlans);
12676ba597c5SAnurag S. Maskey 
12686ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
12696ba597c5SAnurag S. Maskey 		die_nwamerr(err, "could not retrieve scan results for %s",
12706ba597c5SAnurag S. Maskey 		    linkname);
12716ba597c5SAnurag S. Maskey 	}
12726ba597c5SAnurag S. Maskey 	bssid[0] = '\0';
12736ba597c5SAnurag S. Maskey 
12746ba597c5SAnurag S. Maskey 	/* Loop until valid selection made */
12756ba597c5SAnurag S. Maskey 	for (;;) {
12766ba597c5SAnurag S. Maskey 		(void) printf("\n");
12776ba597c5SAnurag S. Maskey 		/* Display WLAN choices for user to select from */
12786ba597c5SAnurag S. Maskey 		for (i = 0; i < num_wlans; i++) {
12796ba597c5SAnurag S. Maskey 			(void) printf("%d: ESSID %s BSSID %s\n",
12806ba597c5SAnurag S. Maskey 			    i + 1, wlans[i].nww_essid, wlans[i].nww_bssid);
12816ba597c5SAnurag S. Maskey 		}
12826ba597c5SAnurag S. Maskey 		(void) printf(gettext("%d: Other\n"), i + 1);
12836ba597c5SAnurag S. Maskey 
12846ba597c5SAnurag S. Maskey 		(void) printf(gettext("\nChoose WLAN to connect to [1-%d]: "),
12856ba597c5SAnurag S. Maskey 		    i + 1);
12866ba597c5SAnurag S. Maskey 
12876ba597c5SAnurag S. Maskey 		if (fgets(choicestr, sizeof (choicestr), stdin) != NULL &&
12886ba597c5SAnurag S. Maskey 		    (choice = atoi(choicestr)) >= 1 && choice <= (i + 1))
12896ba597c5SAnurag S. Maskey 			break;
12906ba597c5SAnurag S. Maskey 	}
12916ba597c5SAnurag S. Maskey 
129219cbc0aaSAnurag S. Maskey 	if (choice == i + 1 || wlans[choice - 1].nww_essid[0] == '\0') {
12936ba597c5SAnurag S. Maskey 		nwam_known_wlan_handle_t kwh = NULL;
12946ba597c5SAnurag S. Maskey 		nwam_value_t keynameval = NULL;
12956ba597c5SAnurag S. Maskey 
129619cbc0aaSAnurag S. Maskey 		/* If "Other" or a hidden WLAN is selected, ask for ESSID */
12976ba597c5SAnurag S. Maskey 		do {
12986ba597c5SAnurag S. Maskey 			(void) printf(gettext("\nEnter WLAN name: "));
12996ba597c5SAnurag S. Maskey 			while (fgets(essid, sizeof (essid), stdin) == NULL) {}
13006ba597c5SAnurag S. Maskey 			essid[strlen(essid) - 1] = '\0';
13016ba597c5SAnurag S. Maskey 		} while (strspn(essid, " \t") == strlen(essid));
13026ba597c5SAnurag S. Maskey 
130319cbc0aaSAnurag S. Maskey 		/* If "Other" was selected, secmode must be specified. */
130419cbc0aaSAnurag S. Maskey 		if (choice == i + 1) {
130519cbc0aaSAnurag S. Maskey 			for (;;) {
130619cbc0aaSAnurag S. Maskey 				(void) printf(gettext("1: None\n"));
130719cbc0aaSAnurag S. Maskey 				(void) printf(gettext("2: WEP\n"));
130819cbc0aaSAnurag S. Maskey 				(void) printf(gettext("3: WPA\n"));
130919cbc0aaSAnurag S. Maskey 				(void) printf(gettext("Enter security mode: "));
131019cbc0aaSAnurag S. Maskey 				if (fgets(modestr, sizeof (choicestr), stdin)
131119cbc0aaSAnurag S. Maskey 				    != NULL &&
131219cbc0aaSAnurag S. Maskey 				    (security_mode = atoi(modestr)) >= 1 &&
131319cbc0aaSAnurag S. Maskey 				    security_mode <= 3)
131419cbc0aaSAnurag S. Maskey 					break;
131519cbc0aaSAnurag S. Maskey 			}
131619cbc0aaSAnurag S. Maskey 		} else {
131719cbc0aaSAnurag S. Maskey 			security_mode = wlans[choice - 1].nww_security_mode;
131819cbc0aaSAnurag S. Maskey 			have_key = wlans[choice - 1].nww_have_key;
13196ba597c5SAnurag S. Maskey 		}
13206ba597c5SAnurag S. Maskey 
13216ba597c5SAnurag S. Maskey 		/*
13226ba597c5SAnurag S. Maskey 		 * We have to determine if we have a key for this ESSID from
13236ba597c5SAnurag S. Maskey 		 * the known WLAN list, since we cannot determine this from
13246ba597c5SAnurag S. Maskey 		 * the scan results.
13256ba597c5SAnurag S. Maskey 		 */
13266ba597c5SAnurag S. Maskey 		if (nwam_known_wlan_read(essid, 0, &kwh) == NWAM_SUCCESS &&
13276ba597c5SAnurag S. Maskey 		    nwam_known_wlan_get_prop_value(kwh,
13286ba597c5SAnurag S. Maskey 		    NWAM_KNOWN_WLAN_PROP_KEYNAME, &keynameval) == NWAM_SUCCESS)
13296ba597c5SAnurag S. Maskey 			have_key = B_TRUE;
13306ba597c5SAnurag S. Maskey 		else
13316ba597c5SAnurag S. Maskey 			have_key = B_FALSE;
13326ba597c5SAnurag S. Maskey 
13336ba597c5SAnurag S. Maskey 		nwam_value_free(keynameval);
13346ba597c5SAnurag S. Maskey 		nwam_known_wlan_free(kwh);
13356ba597c5SAnurag S. Maskey 	} else {
13366ba597c5SAnurag S. Maskey 		(void) strlcpy(essid, wlans[choice - 1].nww_essid,
13376ba597c5SAnurag S. Maskey 		    sizeof (essid));
13386ba597c5SAnurag S. Maskey 		(void) strlcpy(bssid, wlans[choice - 1].nww_bssid,
13396ba597c5SAnurag S. Maskey 		    sizeof (bssid));
13406ba597c5SAnurag S. Maskey 		security_mode = wlans[choice - 1].nww_security_mode;
13416ba597c5SAnurag S. Maskey 		have_key = wlans[choice - 1].nww_have_key;
13426ba597c5SAnurag S. Maskey 	}
13436ba597c5SAnurag S. Maskey 
13446ba597c5SAnurag S. Maskey 	if (security_mode != DLADM_WLAN_SECMODE_NONE && !have_key) {
13456ba597c5SAnurag S. Maskey 		uint_t keyslot = 1;
13466ba597c5SAnurag S. Maskey 		char key[NWAM_MAX_VALUE_LEN];
13476ba597c5SAnurag S. Maskey 		char slotstr[NWAM_MAX_VALUE_LEN];
13486ba597c5SAnurag S. Maskey 
13496ba597c5SAnurag S. Maskey 		do {
13506ba597c5SAnurag S. Maskey 			(void) printf(gettext("\nEnter WLAN key for "
13516ba597c5SAnurag S. Maskey 			    "ESSID %s: "), essid);
13526ba597c5SAnurag S. Maskey 			while (fgets(key, sizeof (key), stdin) == NULL) {}
13536ba597c5SAnurag S. Maskey 			key[strlen(key) - 1] = '\0';
13546ba597c5SAnurag S. Maskey 		} while (strspn(key, " \t") == strlen(key));
13556ba597c5SAnurag S. Maskey 
13566ba597c5SAnurag S. Maskey 		if (security_mode == DLADM_WLAN_SECMODE_WEP) {
13576ba597c5SAnurag S. Maskey 			for (;;) {
13586ba597c5SAnurag S. Maskey 				(void) printf(
13596ba597c5SAnurag S. Maskey 				    gettext("\nEnter key slot [1-4]: "));
13606ba597c5SAnurag S. Maskey 				if (fgets(slotstr, sizeof (slotstr), stdin)
13616ba597c5SAnurag S. Maskey 				    != NULL && (keyslot = atoi(slotstr)) >= 1 &&
13626ba597c5SAnurag S. Maskey 				    keyslot <= 4)
13636ba597c5SAnurag S. Maskey 					break;
13646ba597c5SAnurag S. Maskey 			}
13656ba597c5SAnurag S. Maskey 		}
13666ba597c5SAnurag S. Maskey 
13676ba597c5SAnurag S. Maskey 		err = nwam_wlan_set_key(linkname, essid, NULL, security_mode,
13686ba597c5SAnurag S. Maskey 		    keyslot, key);
13696ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS)
13706ba597c5SAnurag S. Maskey 			die_nwamerr(err, "could not set WiFi key");
13716ba597c5SAnurag S. Maskey 	}
13726ba597c5SAnurag S. Maskey 	err = nwam_wlan_select(linkname, essid, bssid[0] != '\0' ? bssid : NULL,
13736ba597c5SAnurag S. Maskey 	    security_mode, B_TRUE);
13746ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
13756ba597c5SAnurag S. Maskey 		die_nwamerr(err, "could not select WLAN %s", essid);
13766ba597c5SAnurag S. Maskey 	free(wlans);
13776ba597c5SAnurag S. Maskey 	free(linkname);
13786ba597c5SAnurag S. Maskey }
13796ba597c5SAnurag S. Maskey 
13806ba597c5SAnurag S. Maskey int
13816ba597c5SAnurag S. Maskey main(int argc, char *argv[])
13826ba597c5SAnurag S. Maskey {
13836ba597c5SAnurag S. Maskey 	int i;
13846ba597c5SAnurag S. Maskey 	char *state;
13856ba597c5SAnurag S. Maskey 
13866ba597c5SAnurag S. Maskey 	(void) setlocale(LC_ALL, "");
13876ba597c5SAnurag S. Maskey 	(void) textdomain(TEXT_DOMAIN);
13886ba597c5SAnurag S. Maskey 
13896ba597c5SAnurag S. Maskey 	if ((execname = strrchr(argv[0], '/')) == NULL)
13906ba597c5SAnurag S. Maskey 		execname = argv[0];
13916ba597c5SAnurag S. Maskey 	else
13926ba597c5SAnurag S. Maskey 		execname++;
13936ba597c5SAnurag S. Maskey 
13946ba597c5SAnurag S. Maskey 	if (argc < 2) {
13956ba597c5SAnurag S. Maskey 		usage(B_FALSE);
13966ba597c5SAnurag S. Maskey 		exit(EXIT_FAILURE);
13976ba597c5SAnurag S. Maskey 	}
13986ba597c5SAnurag S. Maskey 
13996ba597c5SAnurag S. Maskey 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
14006ba597c5SAnurag S. Maskey 		if (strcmp(argv[1], cmd_to_str(i)) == 0) {
14016ba597c5SAnurag S. Maskey 			if (cmdtab[i].cmd_needs_nwamd) {
14026ba597c5SAnurag S. Maskey 				state = smf_get_state(NWAM_FMRI);
14036ba597c5SAnurag S. Maskey 				if (state == NULL || strcmp(state,
14046ba597c5SAnurag S. Maskey 				    SCF_STATE_STRING_ONLINE) != 0) {
14056ba597c5SAnurag S. Maskey 					free(state);
14066ba597c5SAnurag S. Maskey 					die("enable '%s' to use '%s %s'",
14076ba597c5SAnurag S. Maskey 					    NWAM_FMRI, execname,
14086ba597c5SAnurag S. Maskey 					    cmd_to_str(cmdtab[i].cmd_num));
14096ba597c5SAnurag S. Maskey 				}
14106ba597c5SAnurag S. Maskey 				free(state);
14116ba597c5SAnurag S. Maskey 			}
14126ba597c5SAnurag S. Maskey 
14136ba597c5SAnurag S. Maskey 			cmdtab[i].cmd_handler(argc - 2, &(argv[2]));
14146ba597c5SAnurag S. Maskey 
14156ba597c5SAnurag S. Maskey 			exit(EXIT_SUCCESS);
14166ba597c5SAnurag S. Maskey 		}
14176ba597c5SAnurag S. Maskey 	}
14186ba597c5SAnurag S. Maskey 
14196ba597c5SAnurag S. Maskey 	(void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
14206ba597c5SAnurag S. Maskey 	    execname, argv[1]);
14216ba597c5SAnurag S. Maskey 	usage(B_FALSE);
14226ba597c5SAnurag S. Maskey 
14236ba597c5SAnurag S. Maskey 	return (1);
14246ba597c5SAnurag S. Maskey }
1425