xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/nwamadm/nwamadm.c (revision 12805:288ae711509e)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
2312145SAnurag.Maskey@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411767SAnurag.Maskey@Sun.COM  */
2511767SAnurag.Maskey@Sun.COM 
2611767SAnurag.Maskey@Sun.COM /*
2711767SAnurag.Maskey@Sun.COM  * nwamadm is a command interpreter to administer NWAM profiles.  It
2811767SAnurag.Maskey@Sun.COM  * is all in C (i.e., no lex/yacc), and all the argument passing is
2911767SAnurag.Maskey@Sun.COM  * argc/argv based.  main() calls the command's handler function,
3011767SAnurag.Maskey@Sun.COM  * which first calls parse_argv() to parse the input arguments and set
3111767SAnurag.Maskey@Sun.COM  * approriate variables for each command.  The rest of the program is
3211767SAnurag.Maskey@Sun.COM  * helper functions for the handler functions.
3311767SAnurag.Maskey@Sun.COM  */
3411767SAnurag.Maskey@Sun.COM 
3511767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
3611767SAnurag.Maskey@Sun.COM #include <assert.h>
3711767SAnurag.Maskey@Sun.COM #include <errno.h>
3811767SAnurag.Maskey@Sun.COM #include <libdlwlan.h>
3912576SAnurag.Maskey@Oracle.COM #include <libinetutil.h>
4011767SAnurag.Maskey@Sun.COM #include <libnwam.h>
4111767SAnurag.Maskey@Sun.COM #include <libscf.h>
4211767SAnurag.Maskey@Sun.COM #include <locale.h>
4311767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
4411767SAnurag.Maskey@Sun.COM #include <ofmt.h>
4511767SAnurag.Maskey@Sun.COM #include <stdarg.h>
4611767SAnurag.Maskey@Sun.COM #include <stdio.h>
4711767SAnurag.Maskey@Sun.COM #include <stdlib.h>
4811767SAnurag.Maskey@Sun.COM #include <string.h>
4911767SAnurag.Maskey@Sun.COM #include <strings.h>
5011767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
5111767SAnurag.Maskey@Sun.COM #include <sys/types.h>
5211767SAnurag.Maskey@Sun.COM #include <unistd.h>
5311767SAnurag.Maskey@Sun.COM 
5411767SAnurag.Maskey@Sun.COM #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
5511767SAnurag.Maskey@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
5611767SAnurag.Maskey@Sun.COM #endif
5711767SAnurag.Maskey@Sun.COM 
5811767SAnurag.Maskey@Sun.COM typedef void (cmd_func_t)(int, char **);
5911767SAnurag.Maskey@Sun.COM 
6011767SAnurag.Maskey@Sun.COM struct cmd {
6111767SAnurag.Maskey@Sun.COM 	uint_t		cmd_num;		/* command number */
6211767SAnurag.Maskey@Sun.COM 	const char	*cmd_name;		/* command name */
6311767SAnurag.Maskey@Sun.COM 	cmd_func_t	*cmd_handler;		/* function to call */
6411767SAnurag.Maskey@Sun.COM 	const char	*cmd_usage;		/* short form help */
6511767SAnurag.Maskey@Sun.COM 	const char	*cmd_desc;		/* command description */
6611767SAnurag.Maskey@Sun.COM 	boolean_t	cmd_needs_nwamd;	/* nwam needs to run */
6711767SAnurag.Maskey@Sun.COM };
6811767SAnurag.Maskey@Sun.COM 
6911767SAnurag.Maskey@Sun.COM /* constants for commands */
7011767SAnurag.Maskey@Sun.COM #define	CMD_HELP	0
7111767SAnurag.Maskey@Sun.COM #define	CMD_ENABLE	1
7211767SAnurag.Maskey@Sun.COM #define	CMD_DISABLE	2
7311767SAnurag.Maskey@Sun.COM #define	CMD_LIST	3
7411767SAnurag.Maskey@Sun.COM #define	CMD_SHOW_EVENTS	4
7511767SAnurag.Maskey@Sun.COM #define	CMD_SCAN_WIFI	5
7611767SAnurag.Maskey@Sun.COM #define	CMD_SELECT_WIFI	6
7711767SAnurag.Maskey@Sun.COM 
7811767SAnurag.Maskey@Sun.COM #define	CMD_MIN		CMD_HELP
7911767SAnurag.Maskey@Sun.COM #define	CMD_MAX		CMD_SELECT_WIFI
8011767SAnurag.Maskey@Sun.COM 
8111767SAnurag.Maskey@Sun.COM /* functions to call */
8211767SAnurag.Maskey@Sun.COM static cmd_func_t help_func, enable_func, disable_func, list_func;
8311767SAnurag.Maskey@Sun.COM static cmd_func_t show_events_func, scan_wifi_func, select_wifi_func;
8411767SAnurag.Maskey@Sun.COM static ofmt_cb_t print_list_cb;
8511767SAnurag.Maskey@Sun.COM 
8611767SAnurag.Maskey@Sun.COM /* table of commands and usage */
8711767SAnurag.Maskey@Sun.COM static struct cmd cmdtab[] = {
8811767SAnurag.Maskey@Sun.COM 	{ CMD_HELP,		"help",		help_func,
8911767SAnurag.Maskey@Sun.COM 	    "help",
9011767SAnurag.Maskey@Sun.COM 	    "Print this usage message.",		B_FALSE		},
9111767SAnurag.Maskey@Sun.COM 	{ CMD_ENABLE,		"enable",	enable_func,
9211767SAnurag.Maskey@Sun.COM 	    "enable [-p <profile-type>] [-c <ncu-class>] <object-name>",
9311767SAnurag.Maskey@Sun.COM 	    "Enable the specified profile.",		B_FALSE		},
9411767SAnurag.Maskey@Sun.COM 	{ CMD_DISABLE,		"disable",	disable_func,
9511767SAnurag.Maskey@Sun.COM 	    "disable [-p <profile-type>] [-c <ncu-class>] <object-name>",
9611767SAnurag.Maskey@Sun.COM 	    "Disable the specified profile.",		B_FALSE		},
9711767SAnurag.Maskey@Sun.COM 	{ CMD_LIST,		"list",		list_func,
9811767SAnurag.Maskey@Sun.COM 	    "list [-x] [-p <profile-type>] [-c <ncu-class>] [<object-name>]",
9911767SAnurag.Maskey@Sun.COM 	    "List profiles and their current states.",	B_TRUE		},
10011767SAnurag.Maskey@Sun.COM 	{ CMD_SHOW_EVENTS,	"show-events",	show_events_func,
10111767SAnurag.Maskey@Sun.COM 	    "show-events",
10211767SAnurag.Maskey@Sun.COM 	    "Display all events.",			B_TRUE		},
10311767SAnurag.Maskey@Sun.COM 	{ CMD_SCAN_WIFI,	"scan-wifi",	scan_wifi_func,
10411767SAnurag.Maskey@Sun.COM 	    "scan-wifi <link-name>",
10511767SAnurag.Maskey@Sun.COM 	    "Request a WiFi scan for the selected link.", B_TRUE	},
10611767SAnurag.Maskey@Sun.COM 	{ CMD_SELECT_WIFI,	"select-wifi",	select_wifi_func,
10711767SAnurag.Maskey@Sun.COM 	    "select-wifi <link-name>",
10811767SAnurag.Maskey@Sun.COM 	    "Make a WLAN selection from the last WiFi scan.", B_TRUE	}
10911767SAnurag.Maskey@Sun.COM };
11011767SAnurag.Maskey@Sun.COM 
11111767SAnurag.Maskey@Sun.COM /* Structure for "nwamadm list" output */
11211767SAnurag.Maskey@Sun.COM 
11311767SAnurag.Maskey@Sun.COM typedef struct profile_entry {
11411767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	p_type;
11511767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	p_ncu_class;
11611767SAnurag.Maskey@Sun.COM 	char			p_name[NWAM_MAX_NAME_LEN];
11711767SAnurag.Maskey@Sun.COM 	nwam_state_t		p_state;
11811767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t	p_aux_state;
11911767SAnurag.Maskey@Sun.COM } profile_entry_t;
12011767SAnurag.Maskey@Sun.COM 
12111767SAnurag.Maskey@Sun.COM /* widths of colums for printing */
12211767SAnurag.Maskey@Sun.COM #define	TYPE_WIDTH		12	/* width of TYPE column */
12311767SAnurag.Maskey@Sun.COM #define	PROFILE_WIDTH		15	/* width of PROFILE column */
12411767SAnurag.Maskey@Sun.COM #define	STATE_WIDTH		15	/* width of STATE column */
12511767SAnurag.Maskey@Sun.COM #define	AUXSTATE_WIDTH		36	/* width of AUXILIARY STATE column */
12611767SAnurag.Maskey@Sun.COM 
12712576SAnurag.Maskey@Oracle.COM #define	EVENT_WIDTH		15	/* width of EVENT column */
12812576SAnurag.Maskey@Oracle.COM #define	DESCRIPTION_WIDTH	64	/* width of DESCRIPTION column */
12911767SAnurag.Maskey@Sun.COM 
13011767SAnurag.Maskey@Sun.COM /* id for columns of "nwamadm list" */
13111767SAnurag.Maskey@Sun.COM typedef enum {
13211767SAnurag.Maskey@Sun.COM 	LIST_TYPE,
13311767SAnurag.Maskey@Sun.COM 	LIST_PROFILE,
13411767SAnurag.Maskey@Sun.COM 	LIST_STATE,
13511767SAnurag.Maskey@Sun.COM 	LIST_AUXSTATE
13611767SAnurag.Maskey@Sun.COM } list_field_id_t;
13711767SAnurag.Maskey@Sun.COM 
13811767SAnurag.Maskey@Sun.COM static const ofmt_field_t list_fields[] = {
13911767SAnurag.Maskey@Sun.COM 	/* header,		width,		id,		callback */
14011767SAnurag.Maskey@Sun.COM 	{ "TYPE",		TYPE_WIDTH,	LIST_TYPE,	print_list_cb },
14111767SAnurag.Maskey@Sun.COM 	{ "PROFILE",		PROFILE_WIDTH,	LIST_PROFILE,	print_list_cb },
14211767SAnurag.Maskey@Sun.COM 	{ "STATE",		STATE_WIDTH,	LIST_STATE,	print_list_cb },
14311767SAnurag.Maskey@Sun.COM 	{ "AUXILIARY STATE",	AUXSTATE_WIDTH,	LIST_AUXSTATE,	print_list_cb },
14411767SAnurag.Maskey@Sun.COM 	{ NULL,			0,		0,		NULL }
14511767SAnurag.Maskey@Sun.COM };
14611767SAnurag.Maskey@Sun.COM 
14711767SAnurag.Maskey@Sun.COM /* Global variables */
14811767SAnurag.Maskey@Sun.COM 
14911767SAnurag.Maskey@Sun.COM /* set early in main(), never modified thereafter, used all over the place */
15011767SAnurag.Maskey@Sun.COM static char *execname;
15111767SAnurag.Maskey@Sun.COM 
15211767SAnurag.Maskey@Sun.COM /* whether the auxilary states are to be printed or not */
15311767SAnurag.Maskey@Sun.COM static boolean_t extended_list = B_FALSE;
15411767SAnurag.Maskey@Sun.COM 
15511767SAnurag.Maskey@Sun.COM /* Functions */
15611767SAnurag.Maskey@Sun.COM 
15711767SAnurag.Maskey@Sun.COM static const char *
cmd_to_str(int cmd_num)15811767SAnurag.Maskey@Sun.COM cmd_to_str(int cmd_num)
15911767SAnurag.Maskey@Sun.COM {
16011767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
16111767SAnurag.Maskey@Sun.COM 	return (cmdtab[cmd_num].cmd_name);
16211767SAnurag.Maskey@Sun.COM }
16311767SAnurag.Maskey@Sun.COM 
16411767SAnurag.Maskey@Sun.COM /* returns description of given command */
16511767SAnurag.Maskey@Sun.COM static const char *
long_help(int cmd_num)16611767SAnurag.Maskey@Sun.COM long_help(int cmd_num)
16711767SAnurag.Maskey@Sun.COM {
16811767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
16911767SAnurag.Maskey@Sun.COM 	return (gettext(cmdtab[cmd_num].cmd_desc));
17011767SAnurag.Maskey@Sun.COM }
17111767SAnurag.Maskey@Sun.COM 
17211767SAnurag.Maskey@Sun.COM /*
17311767SAnurag.Maskey@Sun.COM  * Called with explicit B_TRUE when help is explicitly required,
17411767SAnurag.Maskey@Sun.COM  * B_FALSE for errors
17511767SAnurag.Maskey@Sun.COM  */
17611767SAnurag.Maskey@Sun.COM static void
usage(boolean_t explicit)17711767SAnurag.Maskey@Sun.COM usage(boolean_t explicit)
17811767SAnurag.Maskey@Sun.COM {
17911767SAnurag.Maskey@Sun.COM 	int	i;
18011767SAnurag.Maskey@Sun.COM 	FILE	*fd = explicit ? stdout : stderr;
18111767SAnurag.Maskey@Sun.COM 
18211767SAnurag.Maskey@Sun.COM 	(void) fprintf(fd, gettext("usage: <subcommand> <args> ...\n"));
18311767SAnurag.Maskey@Sun.COM 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
18411767SAnurag.Maskey@Sun.COM 		(void) fprintf(fd, "\t%s\n", cmdtab[i].cmd_usage);
18511767SAnurag.Maskey@Sun.COM 		if (explicit)
18611767SAnurag.Maskey@Sun.COM 			(void) fprintf(fd, "\t\t%s\n\n", long_help(i));
18711767SAnurag.Maskey@Sun.COM 	}
18811767SAnurag.Maskey@Sun.COM }
18911767SAnurag.Maskey@Sun.COM 
19011767SAnurag.Maskey@Sun.COM /* PRINTFLIKE1 */
19111767SAnurag.Maskey@Sun.COM static void
die(const char * format,...)19211767SAnurag.Maskey@Sun.COM die(const char *format, ...)
19311767SAnurag.Maskey@Sun.COM {
19411767SAnurag.Maskey@Sun.COM 	va_list alist;
19511767SAnurag.Maskey@Sun.COM 
19611767SAnurag.Maskey@Sun.COM 	format = gettext(format);
19711767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: ", execname);
19811767SAnurag.Maskey@Sun.COM 
19911767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
20011767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
20111767SAnurag.Maskey@Sun.COM 	va_end(alist);
20211767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "\n");
20311767SAnurag.Maskey@Sun.COM 
20411767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
20511767SAnurag.Maskey@Sun.COM }
20611767SAnurag.Maskey@Sun.COM 
20711767SAnurag.Maskey@Sun.COM /* PRINTFLIKE2 */
20811767SAnurag.Maskey@Sun.COM static void
die_nwamerr(nwam_error_t err,const char * format,...)20911767SAnurag.Maskey@Sun.COM die_nwamerr(nwam_error_t err, const char *format, ...)
21011767SAnurag.Maskey@Sun.COM {
21111767SAnurag.Maskey@Sun.COM 	va_list alist;
21211767SAnurag.Maskey@Sun.COM 
21311767SAnurag.Maskey@Sun.COM 	format = gettext(format);
21411767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: ", execname);
21511767SAnurag.Maskey@Sun.COM 
21611767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
21711767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
21811767SAnurag.Maskey@Sun.COM 	va_end(alist);
21911767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, ": %s\n", nwam_strerror(err));
22011767SAnurag.Maskey@Sun.COM 
22111767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
22211767SAnurag.Maskey@Sun.COM }
22311767SAnurag.Maskey@Sun.COM 
22411767SAnurag.Maskey@Sun.COM /* prints the usage for cmd_num and exits */
22511767SAnurag.Maskey@Sun.COM static void
die_usage(int cmd_num)22611767SAnurag.Maskey@Sun.COM die_usage(int cmd_num)
22711767SAnurag.Maskey@Sun.COM {
22811767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
22911767SAnurag.Maskey@Sun.COM 
23011767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "%s: %s\n", gettext("usage"),
23111767SAnurag.Maskey@Sun.COM 	    cmdtab[cmd_num].cmd_usage);
23211767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "\t%s\n", long_help(cmd_num));
23311767SAnurag.Maskey@Sun.COM 
23411767SAnurag.Maskey@Sun.COM 	exit(EXIT_FAILURE);
23511767SAnurag.Maskey@Sun.COM }
23611767SAnurag.Maskey@Sun.COM 
23711767SAnurag.Maskey@Sun.COM /*
23811767SAnurag.Maskey@Sun.COM  * Prints the usage and description of all commands
23911767SAnurag.Maskey@Sun.COM  */
24011767SAnurag.Maskey@Sun.COM /* ARGSUSED */
24111767SAnurag.Maskey@Sun.COM static void
help_func(int argc,char * argv[])24211767SAnurag.Maskey@Sun.COM help_func(int argc, char *argv[])
24311767SAnurag.Maskey@Sun.COM {
24411767SAnurag.Maskey@Sun.COM 	usage(B_TRUE);
24511767SAnurag.Maskey@Sun.COM }
24611767SAnurag.Maskey@Sun.COM 
24711767SAnurag.Maskey@Sun.COM /* determines if the NCP is active or not.  If so, sets arg and halts walk. */
24811767SAnurag.Maskey@Sun.COM static int
active_ncp_callback(nwam_ncp_handle_t ncph,void * arg)24911767SAnurag.Maskey@Sun.COM active_ncp_callback(nwam_ncp_handle_t ncph, void *arg)
25011767SAnurag.Maskey@Sun.COM {
25111767SAnurag.Maskey@Sun.COM 	char			**namep = arg;
25211767SAnurag.Maskey@Sun.COM 	nwam_state_t		state = NWAM_STATE_UNINITIALIZED;
25311767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t	aux;
25411767SAnurag.Maskey@Sun.COM 
25511767SAnurag.Maskey@Sun.COM 	(void) nwam_ncp_get_state(ncph, &state, &aux);
25611767SAnurag.Maskey@Sun.COM 	if (state == NWAM_STATE_ONLINE) {
25711767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_get_name(ncph, namep) != NWAM_SUCCESS)
25811767SAnurag.Maskey@Sun.COM 			*namep = NULL;
25911767SAnurag.Maskey@Sun.COM 		return (1);
26011767SAnurag.Maskey@Sun.COM 	}
26111767SAnurag.Maskey@Sun.COM 
26211767SAnurag.Maskey@Sun.COM 	return (0);
26311767SAnurag.Maskey@Sun.COM }
26411767SAnurag.Maskey@Sun.COM 
26511767SAnurag.Maskey@Sun.COM /* find the currently active NCP and returns its handle */
26611767SAnurag.Maskey@Sun.COM static nwam_ncp_handle_t
determine_active_ncp()26711767SAnurag.Maskey@Sun.COM determine_active_ncp()
26811767SAnurag.Maskey@Sun.COM {
26911767SAnurag.Maskey@Sun.COM 	char *active_ncp;
27011767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
27111767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
27211767SAnurag.Maskey@Sun.COM 
27311767SAnurag.Maskey@Sun.COM 	if (nwam_walk_ncps(active_ncp_callback, &active_ncp, 0, NULL)
27411767SAnurag.Maskey@Sun.COM 	    == NWAM_WALK_HALTED) {
27511767SAnurag.Maskey@Sun.COM 		if (active_ncp == NULL)
27611767SAnurag.Maskey@Sun.COM 			return (NULL);
27711767SAnurag.Maskey@Sun.COM 
27811767SAnurag.Maskey@Sun.COM 		/* retrieve the NCP handle */
27911767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_read(active_ncp, 0, &ncph);
28011767SAnurag.Maskey@Sun.COM 		free(active_ncp);
28111767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS)
28211767SAnurag.Maskey@Sun.COM 			return (ncph);
28311767SAnurag.Maskey@Sun.COM 	}
28411767SAnurag.Maskey@Sun.COM 
28511767SAnurag.Maskey@Sun.COM 	return (NULL);
28611767SAnurag.Maskey@Sun.COM }
28711767SAnurag.Maskey@Sun.COM 
28811767SAnurag.Maskey@Sun.COM /* check if the given name is a valid loc, test by reading the given loc */
28911767SAnurag.Maskey@Sun.COM static boolean_t
valid_loc(const char * name)29011767SAnurag.Maskey@Sun.COM valid_loc(const char *name)
29111767SAnurag.Maskey@Sun.COM {
29211767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch;
29311767SAnurag.Maskey@Sun.COM 
29411767SAnurag.Maskey@Sun.COM 	if (nwam_loc_read(name, 0, &loch) != NWAM_SUCCESS)
29511767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
29611767SAnurag.Maskey@Sun.COM 	nwam_loc_free(loch);
29711767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
29811767SAnurag.Maskey@Sun.COM }
29911767SAnurag.Maskey@Sun.COM 
30011767SAnurag.Maskey@Sun.COM static boolean_t
valid_enm(const char * name)30111767SAnurag.Maskey@Sun.COM valid_enm(const char *name)
30211767SAnurag.Maskey@Sun.COM {
30311767SAnurag.Maskey@Sun.COM 	nwam_enm_handle_t enmh;
30411767SAnurag.Maskey@Sun.COM 
30511767SAnurag.Maskey@Sun.COM 	if (nwam_enm_read(name, 0, &enmh) != NWAM_SUCCESS)
30611767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
30711767SAnurag.Maskey@Sun.COM 	nwam_enm_free(enmh);
30811767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
30911767SAnurag.Maskey@Sun.COM }
31011767SAnurag.Maskey@Sun.COM 
31111767SAnurag.Maskey@Sun.COM static boolean_t
valid_ncp(const char * name)31211767SAnurag.Maskey@Sun.COM valid_ncp(const char *name)
31311767SAnurag.Maskey@Sun.COM {
31411767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
31511767SAnurag.Maskey@Sun.COM 
31611767SAnurag.Maskey@Sun.COM 	if (nwam_ncp_read(name, 0, &ncph) != NWAM_SUCCESS)
31711767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
31811767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
31911767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
32011767SAnurag.Maskey@Sun.COM }
32111767SAnurag.Maskey@Sun.COM 
32211767SAnurag.Maskey@Sun.COM static boolean_t
valid_ncu(const char * name)32311767SAnurag.Maskey@Sun.COM valid_ncu(const char *name)
32411767SAnurag.Maskey@Sun.COM {
32511767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
32611767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
32711767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
32811767SAnurag.Maskey@Sun.COM 
32911767SAnurag.Maskey@Sun.COM 	if ((ncph = determine_active_ncp()) == NULL)
33011767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
33111767SAnurag.Maskey@Sun.COM 
33211767SAnurag.Maskey@Sun.COM 	ret = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_ANY, 0, &ncuh);
33311767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
33411767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS && ret != NWAM_ENTITY_MULTIPLE_VALUES)
33511767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
33611767SAnurag.Maskey@Sun.COM 	nwam_ncu_free(ncuh);
33711767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
33811767SAnurag.Maskey@Sun.COM }
33911767SAnurag.Maskey@Sun.COM 
34011767SAnurag.Maskey@Sun.COM /*
34111767SAnurag.Maskey@Sun.COM  * Given a name, returns object type (loc, enm, ncp, or ncu) and how many
34211767SAnurag.Maskey@Sun.COM  * objects matched that name.
34311767SAnurag.Maskey@Sun.COM  */
34411767SAnurag.Maskey@Sun.COM static nwam_object_type_t
determine_object_type(const char * name,int * num)34511767SAnurag.Maskey@Sun.COM determine_object_type(const char *name, int *num)
34611767SAnurag.Maskey@Sun.COM {
34711767SAnurag.Maskey@Sun.COM 	nwam_object_type_t type;
34811767SAnurag.Maskey@Sun.COM 	int n = 0;
34911767SAnurag.Maskey@Sun.COM 
35011767SAnurag.Maskey@Sun.COM 	/* see if a valid loc, enm, ncp and/or ncu exists with given name */
35111767SAnurag.Maskey@Sun.COM 	if (valid_loc(name)) {
35211767SAnurag.Maskey@Sun.COM 		n++;
35311767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_LOC;
35411767SAnurag.Maskey@Sun.COM 	}
35511767SAnurag.Maskey@Sun.COM 	if (valid_enm(name)) {
35611767SAnurag.Maskey@Sun.COM 		n++;
35711767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_ENM;
35811767SAnurag.Maskey@Sun.COM 	}
35911767SAnurag.Maskey@Sun.COM 	if (valid_ncp(name)) {
36011767SAnurag.Maskey@Sun.COM 		n++;
36111767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCP;
36211767SAnurag.Maskey@Sun.COM 	}
36311767SAnurag.Maskey@Sun.COM 	if (valid_ncu(name)) {
36411767SAnurag.Maskey@Sun.COM 		n++;
36511767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCU;
36611767SAnurag.Maskey@Sun.COM 	}
36711767SAnurag.Maskey@Sun.COM 
36811767SAnurag.Maskey@Sun.COM 	/* if n > 1, then it means *type was set multiple times, undo it */
36911767SAnurag.Maskey@Sun.COM 	if (n != 1)
37011767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_UNKNOWN;
37111767SAnurag.Maskey@Sun.COM 
37211767SAnurag.Maskey@Sun.COM 	*num = n;
37311767SAnurag.Maskey@Sun.COM 	return (type);
37411767SAnurag.Maskey@Sun.COM }
37511767SAnurag.Maskey@Sun.COM 
37611767SAnurag.Maskey@Sun.COM /*
37711767SAnurag.Maskey@Sun.COM  * Parses argv array and populates object_type and name.
37811767SAnurag.Maskey@Sun.COM  * Program exits on failure.
37911767SAnurag.Maskey@Sun.COM  */
38011767SAnurag.Maskey@Sun.COM static void
parse_argv(int argc,char * argv[],int cmd_num,nwam_object_type_t * object_type,nwam_ncu_type_t * ncu_type,nwam_ncu_class_t * ncu_class,const char ** name)38111767SAnurag.Maskey@Sun.COM parse_argv(int argc, char *argv[], int cmd_num, nwam_object_type_t *object_type,
38211767SAnurag.Maskey@Sun.COM     nwam_ncu_type_t *ncu_type, nwam_ncu_class_t *ncu_class, const char **name)
38311767SAnurag.Maskey@Sun.COM {
38411767SAnurag.Maskey@Sun.COM 	int			arg;
38511767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
38611767SAnurag.Maskey@Sun.COM 	uint64_t		ncu = NWAM_NCU_TYPE_ANY;
38711767SAnurag.Maskey@Sun.COM 	uint64_t		class = NWAM_NCU_CLASS_ANY;
38811767SAnurag.Maskey@Sun.COM 
38911767SAnurag.Maskey@Sun.COM 	/* check argv for option */
39011767SAnurag.Maskey@Sun.COM 	optind = 0;
39111767SAnurag.Maskey@Sun.COM 	while ((arg = getopt(argc, argv, "?p:c:x")) != EOF) {
39211767SAnurag.Maskey@Sun.COM 		switch (arg) {
39311767SAnurag.Maskey@Sun.COM 		case 'p':
39411767SAnurag.Maskey@Sun.COM 			type = nwam_string_to_object_type(optarg);
39511767SAnurag.Maskey@Sun.COM 			if (type == NWAM_OBJECT_TYPE_UNKNOWN)
39611767SAnurag.Maskey@Sun.COM 				die("Invalid profile-type: %s", optarg);
39711767SAnurag.Maskey@Sun.COM 			break;
39811767SAnurag.Maskey@Sun.COM 		case 'c':
39911767SAnurag.Maskey@Sun.COM 			if (nwam_value_string_get_uint64(NWAM_NCU_PROP_CLASS,
40011767SAnurag.Maskey@Sun.COM 			    optarg, &class) != NWAM_SUCCESS) {
40111767SAnurag.Maskey@Sun.COM 				die("Invalid ncu-class: %s", optarg);
40211767SAnurag.Maskey@Sun.COM 			}
40311767SAnurag.Maskey@Sun.COM 			ncu = nwam_ncu_class_to_type(class);
40411767SAnurag.Maskey@Sun.COM 			if (ncu == NWAM_NCU_TYPE_ANY ||
40511767SAnurag.Maskey@Sun.COM 			    ncu == NWAM_NCU_TYPE_UNKNOWN)
40611767SAnurag.Maskey@Sun.COM 				die("Invalid ncu-class: %s", optarg);
40711767SAnurag.Maskey@Sun.COM 			break;
40811767SAnurag.Maskey@Sun.COM 		case 'x':
40911767SAnurag.Maskey@Sun.COM 			/* -x is only for list */
41011767SAnurag.Maskey@Sun.COM 			if (cmd_num != CMD_LIST)
41111767SAnurag.Maskey@Sun.COM 				die("-x can only be used with 'list'");
41211767SAnurag.Maskey@Sun.COM 			extended_list = B_TRUE;
41311767SAnurag.Maskey@Sun.COM 			break;
41411767SAnurag.Maskey@Sun.COM 		case '?':
41511767SAnurag.Maskey@Sun.COM 		default:
41611767SAnurag.Maskey@Sun.COM 			die_usage(cmd_num);
41711767SAnurag.Maskey@Sun.COM 		}
41811767SAnurag.Maskey@Sun.COM 	}
41911767SAnurag.Maskey@Sun.COM 
42011767SAnurag.Maskey@Sun.COM 	if (ncu != NWAM_NCU_TYPE_ANY) {
42111767SAnurag.Maskey@Sun.COM 		/* If -c is given, -p must be NCU. If unspecified, assume NCU */
42211767SAnurag.Maskey@Sun.COM 		if (type != NWAM_OBJECT_TYPE_UNKNOWN &&
42311767SAnurag.Maskey@Sun.COM 		    type != NWAM_OBJECT_TYPE_NCU)
42411767SAnurag.Maskey@Sun.COM 			die("'-c <ncu-class>' can only be used for ncu");
42511767SAnurag.Maskey@Sun.COM 
42611767SAnurag.Maskey@Sun.COM 		type = NWAM_OBJECT_TYPE_NCU;
42711767SAnurag.Maskey@Sun.COM 	}
42811767SAnurag.Maskey@Sun.COM 
42911767SAnurag.Maskey@Sun.COM 	/* name is mandatory for enable and disable, but not for list */
43011767SAnurag.Maskey@Sun.COM 	if (optind == (argc-1))
43111767SAnurag.Maskey@Sun.COM 		*name = argv[optind];
43211767SAnurag.Maskey@Sun.COM 	else if (argc != optind)
43311767SAnurag.Maskey@Sun.COM 		die("too many profile names given");
43411767SAnurag.Maskey@Sun.COM 	else if (cmd_num != CMD_LIST)
43511767SAnurag.Maskey@Sun.COM 		die("no profile name given");
43611767SAnurag.Maskey@Sun.COM 
43711767SAnurag.Maskey@Sun.COM 	/*
43811767SAnurag.Maskey@Sun.COM 	 * No need to determine type for list.
43911767SAnurag.Maskey@Sun.COM 	 * If -p is not given for enable or disable, then determine type.
44011767SAnurag.Maskey@Sun.COM 	 */
44111767SAnurag.Maskey@Sun.COM 	if (cmd_num != CMD_LIST && type == NWAM_OBJECT_TYPE_UNKNOWN) {
44211767SAnurag.Maskey@Sun.COM 		int num = 0;
44311767SAnurag.Maskey@Sun.COM 
44411767SAnurag.Maskey@Sun.COM 		type = determine_object_type(*name, &num);
44511767SAnurag.Maskey@Sun.COM 		if (num == 0) {
44611767SAnurag.Maskey@Sun.COM 			die("no profile matched '%s'", *name);
44711767SAnurag.Maskey@Sun.COM 		} else if (num > 1) {
44811767SAnurag.Maskey@Sun.COM 			die("more than one profile matched '%s' - use "
44911767SAnurag.Maskey@Sun.COM 			    "'-p <profile-type>' to specify a profile type.",
45011767SAnurag.Maskey@Sun.COM 			    *name);
45111767SAnurag.Maskey@Sun.COM 		}
45211767SAnurag.Maskey@Sun.COM 	}
45311767SAnurag.Maskey@Sun.COM 
45411767SAnurag.Maskey@Sun.COM 	*object_type = type;
45511767SAnurag.Maskey@Sun.COM 	*ncu_type = ncu;
45611767SAnurag.Maskey@Sun.COM 	*ncu_class = class;
45711767SAnurag.Maskey@Sun.COM }
45811767SAnurag.Maskey@Sun.COM 
45911767SAnurag.Maskey@Sun.COM /* Enables/Disables profiles depending on boolean */
46011767SAnurag.Maskey@Sun.COM static nwam_error_t
loc_action(const char * name,boolean_t enable,char ** realnamep)46111767SAnurag.Maskey@Sun.COM loc_action(const char *name, boolean_t enable, char **realnamep)
46211767SAnurag.Maskey@Sun.COM {
46311767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch;
46411767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
46511767SAnurag.Maskey@Sun.COM 
46611767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_loc_read(name, 0, &loch)) != NWAM_SUCCESS)
46711767SAnurag.Maskey@Sun.COM 		return (ret);
46811767SAnurag.Maskey@Sun.COM 
46911767SAnurag.Maskey@Sun.COM 	if (enable)
47011767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_enable(loch);
47111767SAnurag.Maskey@Sun.COM 	else
47211767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_disable(loch);
47311767SAnurag.Maskey@Sun.COM 
47411767SAnurag.Maskey@Sun.COM 	(void) nwam_loc_get_name(loch, realnamep);
47511767SAnurag.Maskey@Sun.COM 	nwam_loc_free(loch);
47611767SAnurag.Maskey@Sun.COM 	return (ret);
47711767SAnurag.Maskey@Sun.COM }
47811767SAnurag.Maskey@Sun.COM 
47911767SAnurag.Maskey@Sun.COM static nwam_error_t
enm_action(const char * name,boolean_t enable,char ** realnamep)48011767SAnurag.Maskey@Sun.COM enm_action(const char *name, boolean_t enable, char **realnamep)
48111767SAnurag.Maskey@Sun.COM {
48211767SAnurag.Maskey@Sun.COM 	nwam_enm_handle_t enmh;
48311767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
48411767SAnurag.Maskey@Sun.COM 
48511767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_enm_read(name, 0, &enmh)) != NWAM_SUCCESS)
48611767SAnurag.Maskey@Sun.COM 		return (ret);
48711767SAnurag.Maskey@Sun.COM 
48811767SAnurag.Maskey@Sun.COM 	if (enable)
48911767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_enable(enmh);
49011767SAnurag.Maskey@Sun.COM 	else
49111767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_disable(enmh);
49211767SAnurag.Maskey@Sun.COM 
49311767SAnurag.Maskey@Sun.COM 	(void) nwam_enm_get_name(enmh, realnamep);
49411767SAnurag.Maskey@Sun.COM 	nwam_enm_free(enmh);
49511767SAnurag.Maskey@Sun.COM 	return (ret);
49611767SAnurag.Maskey@Sun.COM }
49711767SAnurag.Maskey@Sun.COM 
49811767SAnurag.Maskey@Sun.COM static nwam_error_t
ncu_action(const char * name,nwam_ncp_handle_t ncph,nwam_ncu_type_t type,boolean_t enable,char ** realnamep)49911767SAnurag.Maskey@Sun.COM ncu_action(const char *name, nwam_ncp_handle_t ncph, nwam_ncu_type_t type,
50011767SAnurag.Maskey@Sun.COM     boolean_t enable, char **realnamep)
50111767SAnurag.Maskey@Sun.COM {
50211767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
50311767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
50411767SAnurag.Maskey@Sun.COM 	boolean_t retrieved_ncph = B_FALSE;
50511767SAnurag.Maskey@Sun.COM 
50611767SAnurag.Maskey@Sun.COM 	if (ncph == NULL) {
50711767SAnurag.Maskey@Sun.COM 		if ((ncph = determine_active_ncp()) == NULL)
50811767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_FOUND);
50911767SAnurag.Maskey@Sun.COM 		retrieved_ncph = B_TRUE;
51011767SAnurag.Maskey@Sun.COM 	}
51111767SAnurag.Maskey@Sun.COM 
51211767SAnurag.Maskey@Sun.COM 	ret = nwam_ncu_read(ncph, name, type, 0, &ncuh);
51311767SAnurag.Maskey@Sun.COM 	switch (ret) {
51411767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
51511767SAnurag.Maskey@Sun.COM 		if (enable)
51611767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_enable(ncuh);
51711767SAnurag.Maskey@Sun.COM 		else
51811767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_disable(ncuh);
51911767SAnurag.Maskey@Sun.COM 		(void) nwam_ncu_get_name(ncuh, realnamep);
52011767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(ncuh);
52111767SAnurag.Maskey@Sun.COM 		break;
52211767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_MULTIPLE_VALUES:
52311767SAnurag.Maskey@Sun.COM 		/* Call ncu_action() for link and interface types */
52411767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_LINK, enable,
52511767SAnurag.Maskey@Sun.COM 		    realnamep);
52611767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
52711767SAnurag.Maskey@Sun.COM 			break;
52811767SAnurag.Maskey@Sun.COM 
52911767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, ncph, NWAM_NCU_TYPE_INTERFACE, enable,
53011767SAnurag.Maskey@Sun.COM 		    realnamep);
53111767SAnurag.Maskey@Sun.COM 		break;
53211767SAnurag.Maskey@Sun.COM 	}
53311767SAnurag.Maskey@Sun.COM 	if (retrieved_ncph)
53411767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
53511767SAnurag.Maskey@Sun.COM 
53611767SAnurag.Maskey@Sun.COM 	return (ret);
53711767SAnurag.Maskey@Sun.COM }
53811767SAnurag.Maskey@Sun.COM 
53911767SAnurag.Maskey@Sun.COM /*
54011767SAnurag.Maskey@Sun.COM  * If more than one type of profile with the same name, return error.
54111767SAnurag.Maskey@Sun.COM  * In such situations, the -p option must be used.
54211767SAnurag.Maskey@Sun.COM  * If a location is enabled when a different one is already enabled, then
54311767SAnurag.Maskey@Sun.COM  * that location is disabled automatically by nwamd.
54411767SAnurag.Maskey@Sun.COM  */
54511767SAnurag.Maskey@Sun.COM static void
enable_func(int argc,char * argv[])54611767SAnurag.Maskey@Sun.COM enable_func(int argc, char *argv[])
54711767SAnurag.Maskey@Sun.COM {
54811767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
54911767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
55011767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
55111767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
55211767SAnurag.Maskey@Sun.COM 	const char		*name;
55311767SAnurag.Maskey@Sun.COM 	char			*realname = NULL;
55411767SAnurag.Maskey@Sun.COM 
55511767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
55611767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_ENABLE, &type, &ncu_type, &ncu_class, &name);
55711767SAnurag.Maskey@Sun.COM 
55811767SAnurag.Maskey@Sun.COM 	/*
55911767SAnurag.Maskey@Sun.COM 	 * NCPs and Locations don't need to disable the currently active
56011767SAnurag.Maskey@Sun.COM 	 * profile - nwamd automatically switches to the new active profile.
56111767SAnurag.Maskey@Sun.COM 	 * and will disable it if necessary.
56211767SAnurag.Maskey@Sun.COM 	 */
56311767SAnurag.Maskey@Sun.COM 
56411767SAnurag.Maskey@Sun.COM 	/* activate given profile */
56511767SAnurag.Maskey@Sun.COM 	switch (type) {
56611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
56711767SAnurag.Maskey@Sun.COM 		ret = loc_action(name, B_TRUE, &realname);
56811767SAnurag.Maskey@Sun.COM 		break;
56911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
57011767SAnurag.Maskey@Sun.COM 		ret = enm_action(name, B_TRUE, &realname);
57111767SAnurag.Maskey@Sun.COM 		break;
57211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
57311767SAnurag.Maskey@Sun.COM 	{
57411767SAnurag.Maskey@Sun.COM 		nwam_ncp_handle_t ncph;
57511767SAnurag.Maskey@Sun.COM 
57611767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncp_read(name, 0, &ncph)) != NWAM_SUCCESS)
57711767SAnurag.Maskey@Sun.COM 			break;
57811767SAnurag.Maskey@Sun.COM 
57911767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_enable(ncph);
58011767SAnurag.Maskey@Sun.COM 		(void) nwam_ncp_get_name(ncph, &realname);
58111767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
58211767SAnurag.Maskey@Sun.COM 		break;
58311767SAnurag.Maskey@Sun.COM 	}
58411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
58511767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, NULL, ncu_type, B_TRUE, &realname);
58611767SAnurag.Maskey@Sun.COM 		break;
58711767SAnurag.Maskey@Sun.COM 	}
58811767SAnurag.Maskey@Sun.COM 
58911767SAnurag.Maskey@Sun.COM 	switch (ret) {
59011767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
59111767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Enabling %s '%s'\n"),
59211767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
59311767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
59411767SAnurag.Maskey@Sun.COM 		break;
59511767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_MANUAL:
59611767SAnurag.Maskey@Sun.COM 		die("Only profiles with manual activation-mode can be enabled");
59711767SAnurag.Maskey@Sun.COM 		break;
59811767SAnurag.Maskey@Sun.COM 	default:
59911767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "Could not enable %s '%s'",
60011767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
60111767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
60211767SAnurag.Maskey@Sun.COM 	}
60311767SAnurag.Maskey@Sun.COM 	free(realname);
60411767SAnurag.Maskey@Sun.COM }
60511767SAnurag.Maskey@Sun.COM 
60611767SAnurag.Maskey@Sun.COM /*
60711767SAnurag.Maskey@Sun.COM  * Disables a given profile.  Similar to enable, the -p option must be used
60811767SAnurag.Maskey@Sun.COM  * if more than one type of profile is matched by the given name.
60911767SAnurag.Maskey@Sun.COM  */
61011767SAnurag.Maskey@Sun.COM static void
disable_func(int argc,char * argv[])61111767SAnurag.Maskey@Sun.COM disable_func(int argc, char *argv[])
61211767SAnurag.Maskey@Sun.COM {
61311767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
61411767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
61511767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
61611767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
61711767SAnurag.Maskey@Sun.COM 	const char		*name;
61811767SAnurag.Maskey@Sun.COM 	char			*realname = NULL;
61911767SAnurag.Maskey@Sun.COM 
62011767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
62111767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_DISABLE, &type, &ncu_type, &ncu_class,
62211767SAnurag.Maskey@Sun.COM 	    &name);
62311767SAnurag.Maskey@Sun.COM 
62411767SAnurag.Maskey@Sun.COM 	/* deactivate the given profile */
62511767SAnurag.Maskey@Sun.COM 	switch (type) {
62611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
62711767SAnurag.Maskey@Sun.COM 		ret = loc_action(name, B_FALSE, &realname);
62811767SAnurag.Maskey@Sun.COM 		break;
62911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
63011767SAnurag.Maskey@Sun.COM 		ret = enm_action(name, B_FALSE, &realname);
63111767SAnurag.Maskey@Sun.COM 		break;
63211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
63311767SAnurag.Maskey@Sun.COM 		ret = ncu_action(name, NULL, ncu_type, B_FALSE, &realname);
63411767SAnurag.Maskey@Sun.COM 		break;
63511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
63611767SAnurag.Maskey@Sun.COM 		die("ncp's cannot be disabled.  Enable a different ncp to "
63711767SAnurag.Maskey@Sun.COM 		    "switch to that ncp");
63811767SAnurag.Maskey@Sun.COM 	}
63911767SAnurag.Maskey@Sun.COM 
64011767SAnurag.Maskey@Sun.COM 	switch (ret) {
64111767SAnurag.Maskey@Sun.COM 	case NWAM_SUCCESS:
64211767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Disabling %s '%s'\n"),
64311767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
64411767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
64511767SAnurag.Maskey@Sun.COM 		break;
64611767SAnurag.Maskey@Sun.COM 	case NWAM_ENTITY_NOT_MANUAL:
64711767SAnurag.Maskey@Sun.COM 		die("Only profiles with manual activation-mode can be "
64811767SAnurag.Maskey@Sun.COM 		    "disabled");
64911767SAnurag.Maskey@Sun.COM 		break;
65011767SAnurag.Maskey@Sun.COM 	default:
65111767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "Could not disable %s '%s'",
65211767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(type),
65311767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
65411767SAnurag.Maskey@Sun.COM 	}
65511767SAnurag.Maskey@Sun.COM 	free(realname);
65611767SAnurag.Maskey@Sun.COM }
65711767SAnurag.Maskey@Sun.COM 
65811767SAnurag.Maskey@Sun.COM /* prints each column */
65911767SAnurag.Maskey@Sun.COM static boolean_t
print_list_cb(ofmt_arg_t * ofarg,char * buf,uint_t bufsize)66011767SAnurag.Maskey@Sun.COM print_list_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
66111767SAnurag.Maskey@Sun.COM {
66211767SAnurag.Maskey@Sun.COM 	profile_entry_t *pent = ofarg->ofmt_cbarg;
66311767SAnurag.Maskey@Sun.COM 
66411767SAnurag.Maskey@Sun.COM 	switch (ofarg->ofmt_id) {
66511767SAnurag.Maskey@Sun.COM 	case LIST_TYPE:
66611767SAnurag.Maskey@Sun.COM 		/* ncu:ip or ncu:phys for NCUs; ncp, loc, enm for others */
66711767SAnurag.Maskey@Sun.COM 		if (pent->p_type == NWAM_OBJECT_TYPE_NCU) {
66811767SAnurag.Maskey@Sun.COM 			const char *class;
66911767SAnurag.Maskey@Sun.COM 			if (nwam_uint64_get_value_string(NWAM_NCU_PROP_CLASS,
67011767SAnurag.Maskey@Sun.COM 			    pent->p_ncu_class, &class) != NWAM_SUCCESS)
67111767SAnurag.Maskey@Sun.COM 				class = ""; /* empty */
67211767SAnurag.Maskey@Sun.COM 			(void) snprintf(buf, bufsize, "%s:%s",
67311767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(pent->p_type), class);
67411767SAnurag.Maskey@Sun.COM 		} else {
67511767SAnurag.Maskey@Sun.COM 			(void) strlcpy(buf,
67611767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(pent->p_type), bufsize);
67711767SAnurag.Maskey@Sun.COM 		}
67811767SAnurag.Maskey@Sun.COM 		break;
67911767SAnurag.Maskey@Sun.COM 	case LIST_PROFILE:
68011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf, pent->p_name, bufsize);
68111767SAnurag.Maskey@Sun.COM 		break;
68211767SAnurag.Maskey@Sun.COM 	case LIST_STATE:
68311767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf, nwam_state_to_string(pent->p_state),
68411767SAnurag.Maskey@Sun.COM 		    bufsize);
68511767SAnurag.Maskey@Sun.COM 		break;
68611767SAnurag.Maskey@Sun.COM 	case LIST_AUXSTATE:
68711767SAnurag.Maskey@Sun.COM 		(void) strlcpy(buf,
68811767SAnurag.Maskey@Sun.COM 		    nwam_aux_state_to_string(pent->p_aux_state), bufsize);
68911767SAnurag.Maskey@Sun.COM 		break;
69011767SAnurag.Maskey@Sun.COM 	default:
69111767SAnurag.Maskey@Sun.COM 		die("invalid print_list_cb() input: %d", ofarg->ofmt_id);
69211767SAnurag.Maskey@Sun.COM 		break;
69311767SAnurag.Maskey@Sun.COM 	}
69411767SAnurag.Maskey@Sun.COM 	return (B_TRUE);
69511767SAnurag.Maskey@Sun.COM }
69611767SAnurag.Maskey@Sun.COM 
69711767SAnurag.Maskey@Sun.COM /* returns the state and auxilliary state of the object */
69811767SAnurag.Maskey@Sun.COM static nwam_state_t
determine_object_state(nwam_object_type_t type,void * handle,nwam_aux_state_t * aux_statep)69911767SAnurag.Maskey@Sun.COM determine_object_state(nwam_object_type_t type, void *handle,
70011767SAnurag.Maskey@Sun.COM     nwam_aux_state_t *aux_statep)
70111767SAnurag.Maskey@Sun.COM {
70211767SAnurag.Maskey@Sun.COM 	nwam_state_t state;
70311767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t astate;
70411767SAnurag.Maskey@Sun.COM 	nwam_error_t ret;
70511767SAnurag.Maskey@Sun.COM 
70611767SAnurag.Maskey@Sun.COM 	switch (type) {
70711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
70811767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_state(handle, &state, &astate);
70911767SAnurag.Maskey@Sun.COM 		break;
71011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
71111767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_state(handle, &state, &astate);
71211767SAnurag.Maskey@Sun.COM 		break;
71311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
71411767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_get_state(handle, &state, &astate);
71511767SAnurag.Maskey@Sun.COM 		break;
71611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
71711767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_state(handle, &state, &astate);
71811767SAnurag.Maskey@Sun.COM 		break;
71911767SAnurag.Maskey@Sun.COM 	default:
72011767SAnurag.Maskey@Sun.COM 		/* NOTREACHED */
72111767SAnurag.Maskey@Sun.COM 		break;
72211767SAnurag.Maskey@Sun.COM 	}
72311767SAnurag.Maskey@Sun.COM 
72411767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_PERMISSION_DENIED) {
72511767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not get object state");
72611767SAnurag.Maskey@Sun.COM 	} else if (ret != NWAM_SUCCESS) {
72711767SAnurag.Maskey@Sun.COM 		state = NWAM_STATE_UNINITIALIZED;
72811767SAnurag.Maskey@Sun.COM 		astate = NWAM_AUX_STATE_UNINITIALIZED;
72911767SAnurag.Maskey@Sun.COM 	}
73011767SAnurag.Maskey@Sun.COM 
73111767SAnurag.Maskey@Sun.COM 	if (aux_statep != NULL)
73211767SAnurag.Maskey@Sun.COM 		*aux_statep = astate;
73311767SAnurag.Maskey@Sun.COM 	return (state);
73411767SAnurag.Maskey@Sun.COM }
73511767SAnurag.Maskey@Sun.COM 
73611767SAnurag.Maskey@Sun.COM /* populate profile_entry_t with values for object with given handle */
73711767SAnurag.Maskey@Sun.COM static int
add_to_profile_entry(nwam_object_type_t type,void * handle,profile_entry_t * pent)73811767SAnurag.Maskey@Sun.COM add_to_profile_entry(nwam_object_type_t type, void *handle,
73911767SAnurag.Maskey@Sun.COM     profile_entry_t *pent)
74011767SAnurag.Maskey@Sun.COM {
74111767SAnurag.Maskey@Sun.COM 	char		*name;
74211767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
74311767SAnurag.Maskey@Sun.COM 
74411767SAnurag.Maskey@Sun.COM 	pent->p_type = type;
74511767SAnurag.Maskey@Sun.COM 	if (type == NWAM_OBJECT_TYPE_NCU) {
74611767SAnurag.Maskey@Sun.COM 		nwam_ncu_class_t class;
74711767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_class(handle, &class))
74811767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
74911767SAnurag.Maskey@Sun.COM 			return (ret);
75011767SAnurag.Maskey@Sun.COM 		pent->p_ncu_class = class;
75111767SAnurag.Maskey@Sun.COM 	} else {
75211767SAnurag.Maskey@Sun.COM 		pent->p_ncu_class = -1;
75311767SAnurag.Maskey@Sun.COM 	}
75411767SAnurag.Maskey@Sun.COM 
75511767SAnurag.Maskey@Sun.COM 	switch (type) {
75611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
75711767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_name(handle, &name);
75811767SAnurag.Maskey@Sun.COM 		break;
75911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
76011767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_name(handle, &name);
76111767SAnurag.Maskey@Sun.COM 		break;
76211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
76311767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_get_name(handle, &name);
76411767SAnurag.Maskey@Sun.COM 		break;
76511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
76611767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_name(handle, &name);
76711767SAnurag.Maskey@Sun.COM 		break;
76811767SAnurag.Maskey@Sun.COM 	default:
76911767SAnurag.Maskey@Sun.COM 		/* NOTREACHED */
77011767SAnurag.Maskey@Sun.COM 		break;
77111767SAnurag.Maskey@Sun.COM 	}
77211767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
77311767SAnurag.Maskey@Sun.COM 		return (ret);
77411767SAnurag.Maskey@Sun.COM 	}
77511767SAnurag.Maskey@Sun.COM 	(void) strlcpy(pent->p_name, name, sizeof (pent->p_name));
77611767SAnurag.Maskey@Sun.COM 	free(name);
77711767SAnurag.Maskey@Sun.COM 
77811767SAnurag.Maskey@Sun.COM 	pent->p_state = determine_object_state(type, handle,
77911767SAnurag.Maskey@Sun.COM 	    &pent->p_aux_state);
78011767SAnurag.Maskey@Sun.COM 
78111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
78211767SAnurag.Maskey@Sun.COM }
78311767SAnurag.Maskey@Sun.COM 
78411767SAnurag.Maskey@Sun.COM /* callback functions used by walk */
78511767SAnurag.Maskey@Sun.COM 
78611767SAnurag.Maskey@Sun.COM static int
list_ncu_cb(nwam_ncu_handle_t ncuh,void * arg)78711767SAnurag.Maskey@Sun.COM list_ncu_cb(nwam_ncu_handle_t ncuh, void *arg)
78811767SAnurag.Maskey@Sun.COM {
78911767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
79011767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
79111767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
79211767SAnurag.Maskey@Sun.COM 
79311767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
79411767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCU, ncuh, &pent);
79511767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
79611767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add ncu to list");
79711767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
79811767SAnurag.Maskey@Sun.COM 	return (0);
79911767SAnurag.Maskey@Sun.COM }
80011767SAnurag.Maskey@Sun.COM 
80111767SAnurag.Maskey@Sun.COM static int
list_ncp_cb(nwam_ncp_handle_t ncph,void * arg)80211767SAnurag.Maskey@Sun.COM list_ncp_cb(nwam_ncp_handle_t ncph, void *arg)
80311767SAnurag.Maskey@Sun.COM {
80411767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
80511767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
80611767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
80711767SAnurag.Maskey@Sun.COM 	nwam_state_t	state;
80811767SAnurag.Maskey@Sun.COM 
80911767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
81011767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_NCP, ncph, &pent);
81111767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
81211767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add ncp to list");
81311767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
81411767SAnurag.Maskey@Sun.COM 
81511767SAnurag.Maskey@Sun.COM 	state = determine_object_state(NWAM_OBJECT_TYPE_NCP, ncph, NULL);
81611767SAnurag.Maskey@Sun.COM 	if (state == NWAM_STATE_ONLINE) {
81711767SAnurag.Maskey@Sun.COM 		(void) nwam_ncp_walk_ncus(ncph, list_ncu_cb, ofmt,
81811767SAnurag.Maskey@Sun.COM 		    NWAM_FLAG_NCU_TYPE_ALL, NULL);
81911767SAnurag.Maskey@Sun.COM 	}
82011767SAnurag.Maskey@Sun.COM 	return (0);
82111767SAnurag.Maskey@Sun.COM }
82211767SAnurag.Maskey@Sun.COM 
82311767SAnurag.Maskey@Sun.COM static int
list_loc_cb(nwam_loc_handle_t loch,void * arg)82411767SAnurag.Maskey@Sun.COM list_loc_cb(nwam_loc_handle_t loch, void *arg)
82511767SAnurag.Maskey@Sun.COM {
82611767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
82711767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
82811767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
82911767SAnurag.Maskey@Sun.COM 
83011767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
83111767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_LOC, loch, &pent);
83211767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
83311767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add loc to list");
83411767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
83511767SAnurag.Maskey@Sun.COM 	return (0);
83611767SAnurag.Maskey@Sun.COM }
83711767SAnurag.Maskey@Sun.COM 
83811767SAnurag.Maskey@Sun.COM static int
list_enm_cb(nwam_enm_handle_t enmh,void * arg)83911767SAnurag.Maskey@Sun.COM list_enm_cb(nwam_enm_handle_t enmh, void *arg)
84011767SAnurag.Maskey@Sun.COM {
84111767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt = arg;
84211767SAnurag.Maskey@Sun.COM 	profile_entry_t pent;
84311767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
84411767SAnurag.Maskey@Sun.COM 
84511767SAnurag.Maskey@Sun.COM 	bzero(&pent, sizeof (profile_entry_t));
84611767SAnurag.Maskey@Sun.COM 	ret = add_to_profile_entry(NWAM_OBJECT_TYPE_ENM, enmh, &pent);
84711767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
84811767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "could not add enm to list");
84911767SAnurag.Maskey@Sun.COM 	ofmt_print(ofmt, &pent);
85011767SAnurag.Maskey@Sun.COM 	return (0);
85111767SAnurag.Maskey@Sun.COM }
85211767SAnurag.Maskey@Sun.COM 
85311767SAnurag.Maskey@Sun.COM /*
85411767SAnurag.Maskey@Sun.COM  * lists all profiles and their state
85511767SAnurag.Maskey@Sun.COM  */
85611767SAnurag.Maskey@Sun.COM static void
list_func(int argc,char * argv[])85711767SAnurag.Maskey@Sun.COM list_func(int argc, char *argv[])
85811767SAnurag.Maskey@Sun.COM {
85911767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret = NWAM_SUCCESS;
86011767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	type = NWAM_OBJECT_TYPE_UNKNOWN;
86111767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t		ncu_type = NWAM_NCU_TYPE_ANY;
86211767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	ncu_class = NWAM_NCU_CLASS_ANY;
86311767SAnurag.Maskey@Sun.COM 	char			*name = NULL;
86411767SAnurag.Maskey@Sun.COM 
86511767SAnurag.Maskey@Sun.COM 	ofmt_handle_t	ofmt;
86611767SAnurag.Maskey@Sun.COM 	ofmt_status_t	oferr;
86711767SAnurag.Maskey@Sun.COM 	char		*default_fields = "type,profile,state";
86811767SAnurag.Maskey@Sun.COM 	char		*extended_fields = "type,profile,state,auxiliary state";
86911767SAnurag.Maskey@Sun.COM 	char		*fields = NULL;
87011767SAnurag.Maskey@Sun.COM 
87111767SAnurag.Maskey@Sun.COM 	/* parse_argv() returns only on success */
87211767SAnurag.Maskey@Sun.COM 	parse_argv(argc, argv, CMD_LIST, &type, &ncu_type, &ncu_class,
87311767SAnurag.Maskey@Sun.COM 	    (const char **)&name);
87411767SAnurag.Maskey@Sun.COM 
87511767SAnurag.Maskey@Sun.COM 	if (extended_list)
87611767SAnurag.Maskey@Sun.COM 		fields = extended_fields;
87711767SAnurag.Maskey@Sun.COM 	else
87811767SAnurag.Maskey@Sun.COM 		fields = default_fields;
87911767SAnurag.Maskey@Sun.COM 	oferr = ofmt_open(fields, list_fields, 0, 0, &ofmt);
88011767SAnurag.Maskey@Sun.COM 	if (oferr != OFMT_SUCCESS) {
88111767SAnurag.Maskey@Sun.COM 		char buf[OFMT_BUFSIZE];
88211767SAnurag.Maskey@Sun.COM 		(void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
88311767SAnurag.Maskey@Sun.COM 		die("ofmt_open() failed: %s", buf);
88411767SAnurag.Maskey@Sun.COM 	}
88511767SAnurag.Maskey@Sun.COM 
88611767SAnurag.Maskey@Sun.COM 	/* object-name given in command-line */
88711767SAnurag.Maskey@Sun.COM 	if (name != NULL) {
88811767SAnurag.Maskey@Sun.COM 		boolean_t found = B_FALSE;
88911767SAnurag.Maskey@Sun.COM 
89011767SAnurag.Maskey@Sun.COM 		/*
89111767SAnurag.Maskey@Sun.COM 		 * If objects with different types have the same name
89211767SAnurag.Maskey@Sun.COM 		 * (type = UNKNOWN), then try to open handle for each object
89311767SAnurag.Maskey@Sun.COM 		 * and print if successful.
89411767SAnurag.Maskey@Sun.COM 		 */
89511767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCP ||
89611767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
89711767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
89811767SAnurag.Maskey@Sun.COM 			if (nwam_ncp_read(name, 0, &ncph) == NWAM_SUCCESS) {
89911767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
90011767SAnurag.Maskey@Sun.COM 				(void) list_ncp_cb(ncph, ofmt);
90111767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
90211767SAnurag.Maskey@Sun.COM 			}
90311767SAnurag.Maskey@Sun.COM 		}
90411767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCU ||
90511767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
90611767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
90711767SAnurag.Maskey@Sun.COM 			nwam_ncu_handle_t ncuh;
90811767SAnurag.Maskey@Sun.COM 
90911767SAnurag.Maskey@Sun.COM 			if ((ncph = determine_active_ncp()) != NULL) {
91011767SAnurag.Maskey@Sun.COM 				ret = nwam_ncu_read(ncph, name, ncu_type, 0,
91111767SAnurag.Maskey@Sun.COM 				    &ncuh);
91211767SAnurag.Maskey@Sun.COM 				if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
91311767SAnurag.Maskey@Sun.COM 					found = B_TRUE;
91411767SAnurag.Maskey@Sun.COM 					if (nwam_ncu_read(ncph, name,
91511767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_LINK, 0, &ncuh)
91611767SAnurag.Maskey@Sun.COM 					    == NWAM_SUCCESS) {
91711767SAnurag.Maskey@Sun.COM 						(void) list_ncu_cb(ncuh, ofmt);
91811767SAnurag.Maskey@Sun.COM 						nwam_ncu_free(ncuh);
91911767SAnurag.Maskey@Sun.COM 					}
92011767SAnurag.Maskey@Sun.COM 					if (nwam_ncu_read(ncph, name,
92111767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_INTERFACE, 0, &ncuh)
92211767SAnurag.Maskey@Sun.COM 					    == NWAM_SUCCESS) {
92311767SAnurag.Maskey@Sun.COM 						(void) list_ncu_cb(ncuh, ofmt);
92411767SAnurag.Maskey@Sun.COM 						nwam_ncu_free(ncuh);
92511767SAnurag.Maskey@Sun.COM 					}
92611767SAnurag.Maskey@Sun.COM 				} else if (ret == NWAM_SUCCESS) {
92711767SAnurag.Maskey@Sun.COM 					found = B_TRUE;
92811767SAnurag.Maskey@Sun.COM 					(void) list_ncu_cb(ncuh, ofmt);
92911767SAnurag.Maskey@Sun.COM 					nwam_ncu_free(ncuh);
93011767SAnurag.Maskey@Sun.COM 				}
93111767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
93211767SAnurag.Maskey@Sun.COM 			}
93311767SAnurag.Maskey@Sun.COM 		}
93411767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_LOC ||
93511767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
93611767SAnurag.Maskey@Sun.COM 			nwam_loc_handle_t loch;
93711767SAnurag.Maskey@Sun.COM 			if (nwam_loc_read(name, 0, &loch) == NWAM_SUCCESS) {
93811767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
93911767SAnurag.Maskey@Sun.COM 				(void) list_loc_cb(loch, ofmt);
94011767SAnurag.Maskey@Sun.COM 				nwam_loc_free(loch);
94111767SAnurag.Maskey@Sun.COM 			}
94211767SAnurag.Maskey@Sun.COM 		}
94311767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_ENM ||
94411767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
94511767SAnurag.Maskey@Sun.COM 			nwam_enm_handle_t enmh;
94611767SAnurag.Maskey@Sun.COM 			if (nwam_enm_read(name, 0, &enmh) == NWAM_SUCCESS) {
94711767SAnurag.Maskey@Sun.COM 				found = B_TRUE;
94811767SAnurag.Maskey@Sun.COM 				(void) list_enm_cb(enmh, ofmt);
94911767SAnurag.Maskey@Sun.COM 				nwam_enm_free(enmh);
95011767SAnurag.Maskey@Sun.COM 			}
95111767SAnurag.Maskey@Sun.COM 		}
95211767SAnurag.Maskey@Sun.COM 		/* If at least object is found, don't return error */
95311767SAnurag.Maskey@Sun.COM 		if (found)
95411767SAnurag.Maskey@Sun.COM 			ret = NWAM_SUCCESS;
95511767SAnurag.Maskey@Sun.COM 		else
95611767SAnurag.Maskey@Sun.COM 			ret = NWAM_ENTITY_NOT_FOUND;
95711767SAnurag.Maskey@Sun.COM 	}
95811767SAnurag.Maskey@Sun.COM 
95911767SAnurag.Maskey@Sun.COM 	/* object-name not given in command-line */
96011767SAnurag.Maskey@Sun.COM 	if (name == NULL) {
96111767SAnurag.Maskey@Sun.COM 		/*
96211767SAnurag.Maskey@Sun.COM 		 * If type given (type != UNKNOWN), just walk objects in that
96311767SAnurag.Maskey@Sun.COM 		 * type.  Otherwise, walk all ncp, ncu, loc and enm.
96411767SAnurag.Maskey@Sun.COM 		 */
96511767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCP ||
96611767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
96711767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_ncps(list_ncp_cb, ofmt, 0, NULL);
96811767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
96911767SAnurag.Maskey@Sun.COM 				goto done;
97011767SAnurag.Maskey@Sun.COM 		}
97111767SAnurag.Maskey@Sun.COM 		/* no UNKNOWN for NCUs.  They walked with active NCP above */
97211767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_NCU) {
97311767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t ncph;
97411767SAnurag.Maskey@Sun.COM 			if ((ncph = determine_active_ncp()) != NULL) {
97511767SAnurag.Maskey@Sun.COM 				ret = nwam_ncp_walk_ncus(ncph, list_ncu_cb,
97611767SAnurag.Maskey@Sun.COM 				    ofmt, nwam_ncu_class_to_flag(ncu_class),
97711767SAnurag.Maskey@Sun.COM 				    NULL);
97811767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncph);
97911767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
98011767SAnurag.Maskey@Sun.COM 					goto done;
98111767SAnurag.Maskey@Sun.COM 			}
98211767SAnurag.Maskey@Sun.COM 		}
98311767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_LOC ||
98411767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
98511767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_locs(list_loc_cb, ofmt,
98611767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
98711767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
98811767SAnurag.Maskey@Sun.COM 				goto done;
98911767SAnurag.Maskey@Sun.COM 		}
99011767SAnurag.Maskey@Sun.COM 		if (type == NWAM_OBJECT_TYPE_ENM ||
99111767SAnurag.Maskey@Sun.COM 		    type == NWAM_OBJECT_TYPE_UNKNOWN) {
99211767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_enms(list_enm_cb, ofmt,
99311767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
99411767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
99511767SAnurag.Maskey@Sun.COM 				goto done;
99611767SAnurag.Maskey@Sun.COM 		}
99711767SAnurag.Maskey@Sun.COM 	}
99811767SAnurag.Maskey@Sun.COM 
99911767SAnurag.Maskey@Sun.COM done:
100011767SAnurag.Maskey@Sun.COM 	ofmt_close(ofmt);
100111767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_ENTITY_NOT_FOUND && name != NULL)
100211767SAnurag.Maskey@Sun.COM 		die("no profile matched '%s'", name);
100311767SAnurag.Maskey@Sun.COM 	else if (ret != NWAM_SUCCESS)
100411767SAnurag.Maskey@Sun.COM 		die_nwamerr(ret, "list failed during walk");
100511767SAnurag.Maskey@Sun.COM }
100611767SAnurag.Maskey@Sun.COM 
100711767SAnurag.Maskey@Sun.COM /*
100811767SAnurag.Maskey@Sun.COM  * Print NWAM events.
100911767SAnurag.Maskey@Sun.COM  */
101011767SAnurag.Maskey@Sun.COM static void
eventhandler(nwam_event_t event)101111767SAnurag.Maskey@Sun.COM eventhandler(nwam_event_t event)
101211767SAnurag.Maskey@Sun.COM {
101311767SAnurag.Maskey@Sun.COM 	char description[DESCRIPTION_WIDTH];
101411767SAnurag.Maskey@Sun.COM 	char statestr[DESCRIPTION_WIDTH];
101511767SAnurag.Maskey@Sun.COM 	char objstr[DESCRIPTION_WIDTH];
101611767SAnurag.Maskey@Sun.COM 	char *object = NULL;
101711767SAnurag.Maskey@Sun.COM 	const char *action = NULL;
101811767SAnurag.Maskey@Sun.COM 	char *state = NULL;
101911767SAnurag.Maskey@Sun.COM 	boolean_t display = B_TRUE;
102011767SAnurag.Maskey@Sun.COM 	int i;
102111767SAnurag.Maskey@Sun.COM 	nwam_wlan_t *wlans;
102211767SAnurag.Maskey@Sun.COM 
102311767SAnurag.Maskey@Sun.COM 	(void) strlcpy(description, "-", sizeof (description));
102411767SAnurag.Maskey@Sun.COM 
102511767SAnurag.Maskey@Sun.COM 	switch (event->nwe_type) {
102611767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_ACTION:
102711767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
102811767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_action.nwe_action);
102911767SAnurag.Maskey@Sun.COM 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
103011767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string
103111767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_action.nwe_object_type),
103211767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_object_action.nwe_name);
103311767SAnurag.Maskey@Sun.COM 		object = objstr;
103411767SAnurag.Maskey@Sun.COM 		break;
103511767SAnurag.Maskey@Sun.COM 
103611767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_STATE:
103711767SAnurag.Maskey@Sun.COM 		(void) snprintf(statestr, sizeof (statestr), "%s, %s",
103811767SAnurag.Maskey@Sun.COM 		    nwam_state_to_string
103911767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_state),
104011767SAnurag.Maskey@Sun.COM 		    nwam_aux_state_to_string
104111767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_aux_state));
104211767SAnurag.Maskey@Sun.COM 		state = statestr;
104311767SAnurag.Maskey@Sun.COM 
104411767SAnurag.Maskey@Sun.COM 		(void) snprintf(objstr, sizeof (objstr), "%s %s",
104511767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string
104611767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_object_state.nwe_object_type),
104711767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_object_state.nwe_name);
104811767SAnurag.Maskey@Sun.COM 		object = objstr;
104911767SAnurag.Maskey@Sun.COM 		break;
105011767SAnurag.Maskey@Sun.COM 
105111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_PRIORITY_GROUP:
105211767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, DESCRIPTION_WIDTH,
105311767SAnurag.Maskey@Sun.COM 		    "priority-group: %d",
105411767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_priority_group_info.nwe_priority);
105511767SAnurag.Maskey@Sun.COM 		break;
105611767SAnurag.Maskey@Sun.COM 
105711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT:
105811767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
105911767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
106011767SAnurag.Maskey@Sun.COM 		wlans = event->nwe_data.nwe_wlan_info.nwe_wlans;
106111767SAnurag.Maskey@Sun.COM 		for (i = 0;
106211767SAnurag.Maskey@Sun.COM 		    i < event->nwe_data.nwe_wlan_info.nwe_num_wlans;
106311767SAnurag.Maskey@Sun.COM 		    i++) {
106411767SAnurag.Maskey@Sun.COM 			(void) snprintf(description, DESCRIPTION_WIDTH,
106511767SAnurag.Maskey@Sun.COM 			    "%d: %c%c ESSID %s BSSID %s", i + 1,
106611767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_selected ? 'S' : '-',
106711767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_connected ? 'C' : '-',
106811767SAnurag.Maskey@Sun.COM 			    wlans[i].nww_essid, wlans[i].nww_bssid);
106911767SAnurag.Maskey@Sun.COM 			(void) printf("%-*s %-*s\n", EVENT_WIDTH, "-",
107011767SAnurag.Maskey@Sun.COM 			    DESCRIPTION_WIDTH, description);
107111767SAnurag.Maskey@Sun.COM 		}
107211767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
107311767SAnurag.Maskey@Sun.COM 		break;
107411767SAnurag.Maskey@Sun.COM 
107511767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE:
107611767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
107711767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
107811767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
107911767SAnurag.Maskey@Sun.COM 		break;
108011767SAnurag.Maskey@Sun.COM 
108111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_KEY:
108211767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s \n", EVENT_WIDTH,
108311767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type));
108411767SAnurag.Maskey@Sun.COM 		display = B_FALSE;
108511767SAnurag.Maskey@Sun.COM 		break;
108611767SAnurag.Maskey@Sun.COM 
108711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT:
108811767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, DESCRIPTION_WIDTH,
108911767SAnurag.Maskey@Sun.COM 		    gettext("connect to WLAN ESSID %s, BSSID %s %s"),
109011767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_essid,
109111767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_wlans[0].nww_bssid,
109211767SAnurag.Maskey@Sun.COM 		    event->nwe_data.nwe_wlan_info.nwe_connected ?
109311767SAnurag.Maskey@Sun.COM 		    "succeeded" : "failed");
109411767SAnurag.Maskey@Sun.COM 		break;
109511767SAnurag.Maskey@Sun.COM 
109611767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INFO:
109711767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
109811767SAnurag.Maskey@Sun.COM 		    "%s", event->nwe_data.nwe_info.nwe_message);
109911767SAnurag.Maskey@Sun.COM 		break;
110011767SAnurag.Maskey@Sun.COM 
110111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_ACTION:
110211767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
110311767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_if_action.nwe_action);
110411767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_if_action.nwe_name;
110511767SAnurag.Maskey@Sun.COM 		break;
110611767SAnurag.Maskey@Sun.COM 
110711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_STATE:
110811767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_if_state.nwe_name;
110911767SAnurag.Maskey@Sun.COM 		if (event->nwe_data.nwe_if_state.nwe_addr_valid) {
111011767SAnurag.Maskey@Sun.COM 			struct sockaddr_storage *address =
111111767SAnurag.Maskey@Sun.COM 			    &(event->nwe_data.nwe_if_state.nwe_addr);
111212576SAnurag.Maskey@Oracle.COM 			struct sockaddr_storage *netmask =
111312576SAnurag.Maskey@Oracle.COM 			    &(event->nwe_data.nwe_if_state.nwe_netmask);
111411767SAnurag.Maskey@Sun.COM 			struct sockaddr_in *v4addr;
111511767SAnurag.Maskey@Sun.COM 			struct sockaddr_in6 *v6addr;
111611767SAnurag.Maskey@Sun.COM 			char addrstr[NWAM_MAX_VALUE_LEN];
1117*12805SDarren.Reed@Oracle.COM 			int plen = mask2plen((struct sockaddr *)netmask);
111811767SAnurag.Maskey@Sun.COM 
111911767SAnurag.Maskey@Sun.COM 			switch (address->ss_family) {
112011767SAnurag.Maskey@Sun.COM 			case AF_INET:
112111767SAnurag.Maskey@Sun.COM 				v4addr = (struct sockaddr_in *)address;
112211767SAnurag.Maskey@Sun.COM 				(void) inet_ntop(AF_INET, &v4addr->sin_addr,
112311767SAnurag.Maskey@Sun.COM 				    addrstr, sizeof (addrstr));
112411767SAnurag.Maskey@Sun.COM 				break;
112511767SAnurag.Maskey@Sun.COM 			case AF_INET6:
112611767SAnurag.Maskey@Sun.COM 				v6addr = (struct sockaddr_in6 *)address;
112711767SAnurag.Maskey@Sun.COM 				(void) inet_ntop(AF_INET6, &v6addr->sin6_addr,
112811767SAnurag.Maskey@Sun.COM 				    addrstr, sizeof (addrstr));
112911767SAnurag.Maskey@Sun.COM 				break;
113011767SAnurag.Maskey@Sun.COM 			}
113111767SAnurag.Maskey@Sun.COM 			(void) snprintf(statestr, sizeof (statestr),
113212576SAnurag.Maskey@Oracle.COM 			    "flags %x addr %s/%d",
113312576SAnurag.Maskey@Oracle.COM 			    event->nwe_data.nwe_if_state.nwe_flags,
113412576SAnurag.Maskey@Oracle.COM 			    addrstr, plen);
113511767SAnurag.Maskey@Sun.COM 		} else {
113611767SAnurag.Maskey@Sun.COM 			(void) snprintf(statestr, sizeof (statestr),
113712576SAnurag.Maskey@Oracle.COM 			    "flags %x", event->nwe_data.nwe_if_state.nwe_flags);
113811767SAnurag.Maskey@Sun.COM 		}
113911767SAnurag.Maskey@Sun.COM 		state = statestr;
114011767SAnurag.Maskey@Sun.COM 		break;
114111767SAnurag.Maskey@Sun.COM 
114211767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_ACTION:
114311767SAnurag.Maskey@Sun.COM 		action = nwam_action_to_string
114411767SAnurag.Maskey@Sun.COM 		    (event->nwe_data.nwe_link_action.nwe_action);
114511767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_link_action.nwe_name;
114611767SAnurag.Maskey@Sun.COM 		break;
114711767SAnurag.Maskey@Sun.COM 
114811767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_STATE:
114911767SAnurag.Maskey@Sun.COM 		state = event->nwe_data.nwe_link_state.nwe_link_up ?
115011767SAnurag.Maskey@Sun.COM 		    "up" : "down";
115111767SAnurag.Maskey@Sun.COM 		object = event->nwe_data.nwe_link_state.nwe_name;
115211767SAnurag.Maskey@Sun.COM 		break;
115311767SAnurag.Maskey@Sun.COM 	}
115411767SAnurag.Maskey@Sun.COM 
115511767SAnurag.Maskey@Sun.COM 	if (object != NULL && action != NULL) {
115611767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
115711767SAnurag.Maskey@Sun.COM 		    "%s -> action %s", object, action);
115811767SAnurag.Maskey@Sun.COM 	} else if (object != NULL && state != NULL) {
115911767SAnurag.Maskey@Sun.COM 		(void) snprintf(description, sizeof (description),
116011767SAnurag.Maskey@Sun.COM 		    "%s -> state %s", object, state);
116111767SAnurag.Maskey@Sun.COM 	}
116211767SAnurag.Maskey@Sun.COM 
116311767SAnurag.Maskey@Sun.COM 	if (display) {
116411767SAnurag.Maskey@Sun.COM 		(void) printf("%-*s %-*s\n", EVENT_WIDTH,
116511767SAnurag.Maskey@Sun.COM 		    nwam_event_type_to_string(event->nwe_type),
116611767SAnurag.Maskey@Sun.COM 		    DESCRIPTION_WIDTH,
116711767SAnurag.Maskey@Sun.COM 		    description);
116811767SAnurag.Maskey@Sun.COM 	}
116911767SAnurag.Maskey@Sun.COM }
117011767SAnurag.Maskey@Sun.COM 
117111767SAnurag.Maskey@Sun.COM /*
117211767SAnurag.Maskey@Sun.COM  * listens for events and displays them via the eventhandler() function above.
117311767SAnurag.Maskey@Sun.COM  */
117411767SAnurag.Maskey@Sun.COM /* ARGSUSED */
117511767SAnurag.Maskey@Sun.COM static void
show_events_func(int argc,char * argv[])117611767SAnurag.Maskey@Sun.COM show_events_func(int argc, char *argv[])
117711767SAnurag.Maskey@Sun.COM {
117811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
117911767SAnurag.Maskey@Sun.COM 	nwam_event_t event;
118011767SAnurag.Maskey@Sun.COM 
118111767SAnurag.Maskey@Sun.COM 	err = nwam_events_init();
118211767SAnurag.Maskey@Sun.COM 
118311767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
118411767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not bind to receive events");
118511767SAnurag.Maskey@Sun.COM 
118611767SAnurag.Maskey@Sun.COM 	/* print header */
118711767SAnurag.Maskey@Sun.COM 	(void) printf("%-*s %-*s\n", EVENT_WIDTH, "EVENT",
118811767SAnurag.Maskey@Sun.COM 	    DESCRIPTION_WIDTH, "DESCRIPTION");
118911767SAnurag.Maskey@Sun.COM 
119011767SAnurag.Maskey@Sun.COM 	do {
119111767SAnurag.Maskey@Sun.COM 		/*
119211767SAnurag.Maskey@Sun.COM 		 * Needed for stdout redirection to ensure event output is
119311767SAnurag.Maskey@Sun.COM 		 * regularly flushed to file.
119411767SAnurag.Maskey@Sun.COM 		 */
119511767SAnurag.Maskey@Sun.COM 		(void) fflush(stdout);
119611767SAnurag.Maskey@Sun.COM 		err = nwam_event_wait(&event);
119711767SAnurag.Maskey@Sun.COM 		if (err == NWAM_SUCCESS) {
119811767SAnurag.Maskey@Sun.COM 			eventhandler(event);
119911767SAnurag.Maskey@Sun.COM 			nwam_event_free(event);
120011767SAnurag.Maskey@Sun.COM 		}
120111767SAnurag.Maskey@Sun.COM 	} while (err == NWAM_SUCCESS);
120211767SAnurag.Maskey@Sun.COM 	die_nwamerr(err, "event handling stopped");
120311767SAnurag.Maskey@Sun.COM }
120411767SAnurag.Maskey@Sun.COM 
120511767SAnurag.Maskey@Sun.COM /* May need to convert case-insensitive link name match to case-sensitive one */
120611767SAnurag.Maskey@Sun.COM static nwam_error_t
name_to_linkname(char * name,char ** linknamep)120711767SAnurag.Maskey@Sun.COM name_to_linkname(char *name, char **linknamep)
120811767SAnurag.Maskey@Sun.COM {
120911767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
121011767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph = NULL;
121111767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh = NULL;
121211767SAnurag.Maskey@Sun.COM 
121311767SAnurag.Maskey@Sun.COM 	if ((ncph = determine_active_ncp()) == NULL)
121411767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_FOUND);
121511767SAnurag.Maskey@Sun.COM 
121611767SAnurag.Maskey@Sun.COM 	err = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK, 0, &ncuh);
121711767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS)
121811767SAnurag.Maskey@Sun.COM 		err = nwam_ncu_get_name(ncuh, linknamep);
121911767SAnurag.Maskey@Sun.COM 
122011767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
122111767SAnurag.Maskey@Sun.COM 	nwam_ncu_free(ncuh);
122211767SAnurag.Maskey@Sun.COM 	return (err);
122311767SAnurag.Maskey@Sun.COM }
122411767SAnurag.Maskey@Sun.COM 
122511767SAnurag.Maskey@Sun.COM static void
scan_wifi_func(int argc,char * argv[])122611767SAnurag.Maskey@Sun.COM scan_wifi_func(int argc, char *argv[])
122711767SAnurag.Maskey@Sun.COM {
122811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
122911767SAnurag.Maskey@Sun.COM 	char *linkname = NULL;
123011767SAnurag.Maskey@Sun.COM 
123111767SAnurag.Maskey@Sun.COM 	if (argc != 1)
123211767SAnurag.Maskey@Sun.COM 		die_usage(CMD_SCAN_WIFI);
123311767SAnurag.Maskey@Sun.COM 
123411767SAnurag.Maskey@Sun.COM 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS)
123511767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "scan request failed for %s", argv[0]);
123611767SAnurag.Maskey@Sun.COM 
123711767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_scan(linkname);
123811767SAnurag.Maskey@Sun.COM 
123911767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
124011767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "scan request failed for %s", linkname);
124111767SAnurag.Maskey@Sun.COM 
124211767SAnurag.Maskey@Sun.COM 	free(linkname);
124311767SAnurag.Maskey@Sun.COM }
124411767SAnurag.Maskey@Sun.COM 
124511767SAnurag.Maskey@Sun.COM static void
select_wifi_func(int argc,char * argv[])124611767SAnurag.Maskey@Sun.COM select_wifi_func(int argc, char *argv[])
124711767SAnurag.Maskey@Sun.COM {
124811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
124911767SAnurag.Maskey@Sun.COM 	char *linkname = NULL;
125011767SAnurag.Maskey@Sun.COM 	uint_t i, choice, num_wlans = 0;
125111767SAnurag.Maskey@Sun.COM 	uint32_t security_mode;
125211767SAnurag.Maskey@Sun.COM 	boolean_t have_key = B_FALSE;
125311767SAnurag.Maskey@Sun.COM 	nwam_wlan_t *wlans = NULL;
125411767SAnurag.Maskey@Sun.COM 	char choicestr[NWAM_MAX_VALUE_LEN];
125511767SAnurag.Maskey@Sun.COM 	char modestr[NWAM_MAX_VALUE_LEN];
125611767SAnurag.Maskey@Sun.COM 	char essid[NWAM_MAX_VALUE_LEN];
125711767SAnurag.Maskey@Sun.COM 	char bssid[NWAM_MAX_VALUE_LEN];
125811767SAnurag.Maskey@Sun.COM 
125911767SAnurag.Maskey@Sun.COM 	if (argc != 1)
126011767SAnurag.Maskey@Sun.COM 		die_usage(CMD_SELECT_WIFI);
126111767SAnurag.Maskey@Sun.COM 
126211767SAnurag.Maskey@Sun.COM 	if ((err = name_to_linkname(argv[0], &linkname)) != NWAM_SUCCESS) {
126311767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not retrieve scan results for %s",
126411767SAnurag.Maskey@Sun.COM 		    argv[0]);
126511767SAnurag.Maskey@Sun.COM 	}
126611767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_get_scan_results(linkname, &num_wlans, &wlans);
126711767SAnurag.Maskey@Sun.COM 
126811767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
126911767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not retrieve scan results for %s",
127011767SAnurag.Maskey@Sun.COM 		    linkname);
127111767SAnurag.Maskey@Sun.COM 	}
127211767SAnurag.Maskey@Sun.COM 	bssid[0] = '\0';
127311767SAnurag.Maskey@Sun.COM 
127411767SAnurag.Maskey@Sun.COM 	/* Loop until valid selection made */
127511767SAnurag.Maskey@Sun.COM 	for (;;) {
127611767SAnurag.Maskey@Sun.COM 		(void) printf("\n");
127711767SAnurag.Maskey@Sun.COM 		/* Display WLAN choices for user to select from */
127811767SAnurag.Maskey@Sun.COM 		for (i = 0; i < num_wlans; i++) {
127911767SAnurag.Maskey@Sun.COM 			(void) printf("%d: ESSID %s BSSID %s\n",
128011767SAnurag.Maskey@Sun.COM 			    i + 1, wlans[i].nww_essid, wlans[i].nww_bssid);
128111767SAnurag.Maskey@Sun.COM 		}
128211767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("%d: Other\n"), i + 1);
128311767SAnurag.Maskey@Sun.COM 
128411767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("\nChoose WLAN to connect to [1-%d]: "),
128511767SAnurag.Maskey@Sun.COM 		    i + 1);
128611767SAnurag.Maskey@Sun.COM 
128711767SAnurag.Maskey@Sun.COM 		if (fgets(choicestr, sizeof (choicestr), stdin) != NULL &&
128811767SAnurag.Maskey@Sun.COM 		    (choice = atoi(choicestr)) >= 1 && choice <= (i + 1))
128911767SAnurag.Maskey@Sun.COM 			break;
129011767SAnurag.Maskey@Sun.COM 	}
129111767SAnurag.Maskey@Sun.COM 
129212145SAnurag.Maskey@Sun.COM 	if (choice == i + 1 || wlans[choice - 1].nww_essid[0] == '\0') {
129311767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_handle_t kwh = NULL;
129411767SAnurag.Maskey@Sun.COM 		nwam_value_t keynameval = NULL;
129511767SAnurag.Maskey@Sun.COM 
129612145SAnurag.Maskey@Sun.COM 		/* If "Other" or a hidden WLAN is selected, ask for ESSID */
129711767SAnurag.Maskey@Sun.COM 		do {
129811767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("\nEnter WLAN name: "));
129911767SAnurag.Maskey@Sun.COM 			while (fgets(essid, sizeof (essid), stdin) == NULL) {}
130011767SAnurag.Maskey@Sun.COM 			essid[strlen(essid) - 1] = '\0';
130111767SAnurag.Maskey@Sun.COM 		} while (strspn(essid, " \t") == strlen(essid));
130211767SAnurag.Maskey@Sun.COM 
130312145SAnurag.Maskey@Sun.COM 		/* If "Other" was selected, secmode must be specified. */
130412145SAnurag.Maskey@Sun.COM 		if (choice == i + 1) {
130512145SAnurag.Maskey@Sun.COM 			for (;;) {
130612145SAnurag.Maskey@Sun.COM 				(void) printf(gettext("1: None\n"));
130712145SAnurag.Maskey@Sun.COM 				(void) printf(gettext("2: WEP\n"));
130812145SAnurag.Maskey@Sun.COM 				(void) printf(gettext("3: WPA\n"));
130912145SAnurag.Maskey@Sun.COM 				(void) printf(gettext("Enter security mode: "));
131012145SAnurag.Maskey@Sun.COM 				if (fgets(modestr, sizeof (choicestr), stdin)
131112145SAnurag.Maskey@Sun.COM 				    != NULL &&
131212145SAnurag.Maskey@Sun.COM 				    (security_mode = atoi(modestr)) >= 1 &&
131312145SAnurag.Maskey@Sun.COM 				    security_mode <= 3)
131412145SAnurag.Maskey@Sun.COM 					break;
131512145SAnurag.Maskey@Sun.COM 			}
131612145SAnurag.Maskey@Sun.COM 		} else {
131712145SAnurag.Maskey@Sun.COM 			security_mode = wlans[choice - 1].nww_security_mode;
131812145SAnurag.Maskey@Sun.COM 			have_key = wlans[choice - 1].nww_have_key;
131911767SAnurag.Maskey@Sun.COM 		}
132011767SAnurag.Maskey@Sun.COM 
132111767SAnurag.Maskey@Sun.COM 		/*
132211767SAnurag.Maskey@Sun.COM 		 * We have to determine if we have a key for this ESSID from
132311767SAnurag.Maskey@Sun.COM 		 * the known WLAN list, since we cannot determine this from
132411767SAnurag.Maskey@Sun.COM 		 * the scan results.
132511767SAnurag.Maskey@Sun.COM 		 */
132611767SAnurag.Maskey@Sun.COM 		if (nwam_known_wlan_read(essid, 0, &kwh) == NWAM_SUCCESS &&
132711767SAnurag.Maskey@Sun.COM 		    nwam_known_wlan_get_prop_value(kwh,
132811767SAnurag.Maskey@Sun.COM 		    NWAM_KNOWN_WLAN_PROP_KEYNAME, &keynameval) == NWAM_SUCCESS)
132911767SAnurag.Maskey@Sun.COM 			have_key = B_TRUE;
133011767SAnurag.Maskey@Sun.COM 		else
133111767SAnurag.Maskey@Sun.COM 			have_key = B_FALSE;
133211767SAnurag.Maskey@Sun.COM 
133311767SAnurag.Maskey@Sun.COM 		nwam_value_free(keynameval);
133411767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_free(kwh);
133511767SAnurag.Maskey@Sun.COM 	} else {
133611767SAnurag.Maskey@Sun.COM 		(void) strlcpy(essid, wlans[choice - 1].nww_essid,
133711767SAnurag.Maskey@Sun.COM 		    sizeof (essid));
133811767SAnurag.Maskey@Sun.COM 		(void) strlcpy(bssid, wlans[choice - 1].nww_bssid,
133911767SAnurag.Maskey@Sun.COM 		    sizeof (bssid));
134011767SAnurag.Maskey@Sun.COM 		security_mode = wlans[choice - 1].nww_security_mode;
134111767SAnurag.Maskey@Sun.COM 		have_key = wlans[choice - 1].nww_have_key;
134211767SAnurag.Maskey@Sun.COM 	}
134311767SAnurag.Maskey@Sun.COM 
134411767SAnurag.Maskey@Sun.COM 	if (security_mode != DLADM_WLAN_SECMODE_NONE && !have_key) {
134511767SAnurag.Maskey@Sun.COM 		uint_t keyslot = 1;
134611767SAnurag.Maskey@Sun.COM 		char key[NWAM_MAX_VALUE_LEN];
134711767SAnurag.Maskey@Sun.COM 		char slotstr[NWAM_MAX_VALUE_LEN];
134811767SAnurag.Maskey@Sun.COM 
134911767SAnurag.Maskey@Sun.COM 		do {
135011767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("\nEnter WLAN key for "
135111767SAnurag.Maskey@Sun.COM 			    "ESSID %s: "), essid);
135211767SAnurag.Maskey@Sun.COM 			while (fgets(key, sizeof (key), stdin) == NULL) {}
135311767SAnurag.Maskey@Sun.COM 			key[strlen(key) - 1] = '\0';
135411767SAnurag.Maskey@Sun.COM 		} while (strspn(key, " \t") == strlen(key));
135511767SAnurag.Maskey@Sun.COM 
135611767SAnurag.Maskey@Sun.COM 		if (security_mode == DLADM_WLAN_SECMODE_WEP) {
135711767SAnurag.Maskey@Sun.COM 			for (;;) {
135811767SAnurag.Maskey@Sun.COM 				(void) printf(
135911767SAnurag.Maskey@Sun.COM 				    gettext("\nEnter key slot [1-4]: "));
136011767SAnurag.Maskey@Sun.COM 				if (fgets(slotstr, sizeof (slotstr), stdin)
136111767SAnurag.Maskey@Sun.COM 				    != NULL && (keyslot = atoi(slotstr)) >= 1 &&
136211767SAnurag.Maskey@Sun.COM 				    keyslot <= 4)
136311767SAnurag.Maskey@Sun.COM 					break;
136411767SAnurag.Maskey@Sun.COM 			}
136511767SAnurag.Maskey@Sun.COM 		}
136611767SAnurag.Maskey@Sun.COM 
136711767SAnurag.Maskey@Sun.COM 		err = nwam_wlan_set_key(linkname, essid, NULL, security_mode,
136811767SAnurag.Maskey@Sun.COM 		    keyslot, key);
136911767SAnurag.Maskey@Sun.COM 		if (err != NWAM_SUCCESS)
137011767SAnurag.Maskey@Sun.COM 			die_nwamerr(err, "could not set WiFi key");
137111767SAnurag.Maskey@Sun.COM 	}
137211767SAnurag.Maskey@Sun.COM 	err = nwam_wlan_select(linkname, essid, bssid[0] != '\0' ? bssid : NULL,
137311767SAnurag.Maskey@Sun.COM 	    security_mode, B_TRUE);
137411767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
137511767SAnurag.Maskey@Sun.COM 		die_nwamerr(err, "could not select WLAN %s", essid);
137611767SAnurag.Maskey@Sun.COM 	free(wlans);
137711767SAnurag.Maskey@Sun.COM 	free(linkname);
137811767SAnurag.Maskey@Sun.COM }
137911767SAnurag.Maskey@Sun.COM 
138011767SAnurag.Maskey@Sun.COM int
main(int argc,char * argv[])138111767SAnurag.Maskey@Sun.COM main(int argc, char *argv[])
138211767SAnurag.Maskey@Sun.COM {
138311767SAnurag.Maskey@Sun.COM 	int i;
138411767SAnurag.Maskey@Sun.COM 	char *state;
138511767SAnurag.Maskey@Sun.COM 
138611767SAnurag.Maskey@Sun.COM 	(void) setlocale(LC_ALL, "");
138711767SAnurag.Maskey@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
138811767SAnurag.Maskey@Sun.COM 
138911767SAnurag.Maskey@Sun.COM 	if ((execname = strrchr(argv[0], '/')) == NULL)
139011767SAnurag.Maskey@Sun.COM 		execname = argv[0];
139111767SAnurag.Maskey@Sun.COM 	else
139211767SAnurag.Maskey@Sun.COM 		execname++;
139311767SAnurag.Maskey@Sun.COM 
139411767SAnurag.Maskey@Sun.COM 	if (argc < 2) {
139511767SAnurag.Maskey@Sun.COM 		usage(B_FALSE);
139611767SAnurag.Maskey@Sun.COM 		exit(EXIT_FAILURE);
139711767SAnurag.Maskey@Sun.COM 	}
139811767SAnurag.Maskey@Sun.COM 
139911767SAnurag.Maskey@Sun.COM 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
140011767SAnurag.Maskey@Sun.COM 		if (strcmp(argv[1], cmd_to_str(i)) == 0) {
140111767SAnurag.Maskey@Sun.COM 			if (cmdtab[i].cmd_needs_nwamd) {
140211767SAnurag.Maskey@Sun.COM 				state = smf_get_state(NWAM_FMRI);
140311767SAnurag.Maskey@Sun.COM 				if (state == NULL || strcmp(state,
140411767SAnurag.Maskey@Sun.COM 				    SCF_STATE_STRING_ONLINE) != 0) {
140511767SAnurag.Maskey@Sun.COM 					free(state);
140611767SAnurag.Maskey@Sun.COM 					die("enable '%s' to use '%s %s'",
140711767SAnurag.Maskey@Sun.COM 					    NWAM_FMRI, execname,
140811767SAnurag.Maskey@Sun.COM 					    cmd_to_str(cmdtab[i].cmd_num));
140911767SAnurag.Maskey@Sun.COM 				}
141011767SAnurag.Maskey@Sun.COM 				free(state);
141111767SAnurag.Maskey@Sun.COM 			}
141211767SAnurag.Maskey@Sun.COM 
141311767SAnurag.Maskey@Sun.COM 			cmdtab[i].cmd_handler(argc - 2, &(argv[2]));
141411767SAnurag.Maskey@Sun.COM 
141511767SAnurag.Maskey@Sun.COM 			exit(EXIT_SUCCESS);
141611767SAnurag.Maskey@Sun.COM 		}
141711767SAnurag.Maskey@Sun.COM 	}
141811767SAnurag.Maskey@Sun.COM 
141911767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
142011767SAnurag.Maskey@Sun.COM 	    execname, argv[1]);
142111767SAnurag.Maskey@Sun.COM 	usage(B_FALSE);
142211767SAnurag.Maskey@Sun.COM 
142311767SAnurag.Maskey@Sun.COM 	return (1);
142411767SAnurag.Maskey@Sun.COM }
1425