xref: /onnv-gate/usr/src/lib/libnwam/common/libnwam_util.c (revision 12036:aa269fb9cf77)
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 /*
2311767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2411767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
2511767SAnurag.Maskey@Sun.COM  */
2611767SAnurag.Maskey@Sun.COM 
2711767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
2811767SAnurag.Maskey@Sun.COM #include <assert.h>
2911767SAnurag.Maskey@Sun.COM #include <atomic.h>
3011767SAnurag.Maskey@Sun.COM #include <ctype.h>
3111767SAnurag.Maskey@Sun.COM #include <errno.h>
3211767SAnurag.Maskey@Sun.COM #include <inet/ip.h>
3311767SAnurag.Maskey@Sun.COM #include <libintl.h>
3411767SAnurag.Maskey@Sun.COM #include <libproc.h>
3511767SAnurag.Maskey@Sun.COM #include <libscf.h>
3611767SAnurag.Maskey@Sun.COM #include <net/if_dl.h>
3711767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
3811767SAnurag.Maskey@Sun.COM #include <pthread.h>
3911767SAnurag.Maskey@Sun.COM #include <stdio.h>
4011767SAnurag.Maskey@Sun.COM #include <stdlib.h>
4111767SAnurag.Maskey@Sun.COM #include <strings.h>
4211767SAnurag.Maskey@Sun.COM #include <sys/mman.h>
4311767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
4411767SAnurag.Maskey@Sun.COM #include <sys/types.h>
4511767SAnurag.Maskey@Sun.COM #include <unistd.h>
4611767SAnurag.Maskey@Sun.COM 
4711767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
4811767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
4911767SAnurag.Maskey@Sun.COM #include <libnwam.h>
5011767SAnurag.Maskey@Sun.COM 
5111767SAnurag.Maskey@Sun.COM /*
5211767SAnurag.Maskey@Sun.COM  * Utility functions for door access, common validation functions etc.
5311767SAnurag.Maskey@Sun.COM  */
5411767SAnurag.Maskey@Sun.COM 
5511767SAnurag.Maskey@Sun.COM pthread_mutex_t door_mutex = PTHREAD_MUTEX_INITIALIZER;
5611767SAnurag.Maskey@Sun.COM int nwam_door_fd = -1;
5711767SAnurag.Maskey@Sun.COM 
5811767SAnurag.Maskey@Sun.COM static int
open_door(const char * door_name,int * door_fdp)5911767SAnurag.Maskey@Sun.COM open_door(const char *door_name, int *door_fdp)
6011767SAnurag.Maskey@Sun.COM {
6111767SAnurag.Maskey@Sun.COM 	struct door_info dinfo;
6211767SAnurag.Maskey@Sun.COM 	int err = 0;
6311767SAnurag.Maskey@Sun.COM 
6411767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&door_mutex);
6511767SAnurag.Maskey@Sun.COM 
6611767SAnurag.Maskey@Sun.COM 	if (*door_fdp != -1) {
6711767SAnurag.Maskey@Sun.COM 		/* Check door fd is not old (from previous nwamd). */
6811767SAnurag.Maskey@Sun.COM 		if (door_info(*door_fdp, &dinfo) != 0 ||
6911767SAnurag.Maskey@Sun.COM 		    (dinfo.di_attributes & DOOR_REVOKED) != 0) {
7011767SAnurag.Maskey@Sun.COM 			(void) close(*door_fdp);
7111767SAnurag.Maskey@Sun.COM 			*door_fdp = -1;
7211767SAnurag.Maskey@Sun.COM 		}
7311767SAnurag.Maskey@Sun.COM 	}
7411767SAnurag.Maskey@Sun.COM 	if (*door_fdp == -1) {
7511767SAnurag.Maskey@Sun.COM 		*door_fdp = open(door_name, 0);
7611767SAnurag.Maskey@Sun.COM 		if (*door_fdp == -1)
7711767SAnurag.Maskey@Sun.COM 			err = errno;
7811767SAnurag.Maskey@Sun.COM 	}
7911767SAnurag.Maskey@Sun.COM 
8011767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&door_mutex);
8111767SAnurag.Maskey@Sun.COM 
8211767SAnurag.Maskey@Sun.COM 	return (err);
8311767SAnurag.Maskey@Sun.COM }
8411767SAnurag.Maskey@Sun.COM 
8511767SAnurag.Maskey@Sun.COM int
nwam_make_door_call(const char * door_name,int * door_fdp,void * request,size_t request_size)8611767SAnurag.Maskey@Sun.COM nwam_make_door_call(const char *door_name, int *door_fdp,
8711767SAnurag.Maskey@Sun.COM     void *request, size_t request_size)
8811767SAnurag.Maskey@Sun.COM {
8911767SAnurag.Maskey@Sun.COM 	int err;
9011767SAnurag.Maskey@Sun.COM 	door_arg_t door_args;
9111767SAnurag.Maskey@Sun.COM 
9211767SAnurag.Maskey@Sun.COM 	door_args.data_ptr = (void *)request;
9311767SAnurag.Maskey@Sun.COM 	door_args.data_size = request_size;
9411767SAnurag.Maskey@Sun.COM 	door_args.desc_ptr = NULL;
9511767SAnurag.Maskey@Sun.COM 	door_args.desc_num = 0;
9611767SAnurag.Maskey@Sun.COM 	door_args.rbuf = (void *)request;
9711767SAnurag.Maskey@Sun.COM 	door_args.rsize = request_size;
9811767SAnurag.Maskey@Sun.COM 
9911767SAnurag.Maskey@Sun.COM 	if ((err = open_door(door_name, door_fdp)) != 0)
10011767SAnurag.Maskey@Sun.COM 		return (err);
10111767SAnurag.Maskey@Sun.COM 
10211767SAnurag.Maskey@Sun.COM 	if (door_call(*door_fdp, &door_args) == -1)
10311767SAnurag.Maskey@Sun.COM 		return (errno);
10411767SAnurag.Maskey@Sun.COM 
10511767SAnurag.Maskey@Sun.COM 	return (0);
10611767SAnurag.Maskey@Sun.COM }
10711767SAnurag.Maskey@Sun.COM 
10811767SAnurag.Maskey@Sun.COM static nwam_error_t
send_msg_to_nwam(nwamd_door_arg_t * request)10911767SAnurag.Maskey@Sun.COM send_msg_to_nwam(nwamd_door_arg_t *request)
11011767SAnurag.Maskey@Sun.COM {
11111767SAnurag.Maskey@Sun.COM 	int err;
11211767SAnurag.Maskey@Sun.COM 
11311767SAnurag.Maskey@Sun.COM 	if ((err = nwam_make_door_call(NWAM_DOOR, &nwam_door_fd,
11411767SAnurag.Maskey@Sun.COM 	    request, sizeof (nwamd_door_arg_t))) != 0) {
11511767SAnurag.Maskey@Sun.COM 		if (err == ENOENT)
11611767SAnurag.Maskey@Sun.COM 			return (NWAM_ERROR_BIND);
11711767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(err));
11811767SAnurag.Maskey@Sun.COM 	}
11911767SAnurag.Maskey@Sun.COM 
12011767SAnurag.Maskey@Sun.COM 	switch (request->nwda_status) {
12111767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_OK:
12211767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
12311767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_UNKNOWN:
12411767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
12511767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_ALREADY:
12611767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
12711767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_FAILED:
12811767SAnurag.Maskey@Sun.COM 		return (request->nwda_error);
12911767SAnurag.Maskey@Sun.COM 	default:
13011767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
13111767SAnurag.Maskey@Sun.COM 	}
13211767SAnurag.Maskey@Sun.COM }
13311767SAnurag.Maskey@Sun.COM 
13411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_register_unregister(nwam_request_type_t type,const char * event_msg_file)13511767SAnurag.Maskey@Sun.COM nwam_request_register_unregister(nwam_request_type_t type,
13611767SAnurag.Maskey@Sun.COM     const char *event_msg_file)
13711767SAnurag.Maskey@Sun.COM {
13811767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
13911767SAnurag.Maskey@Sun.COM 
14011767SAnurag.Maskey@Sun.COM 	req.nwda_type = type;
14111767SAnurag.Maskey@Sun.COM 
14211767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_register_info.nwdad_name,
14311767SAnurag.Maskey@Sun.COM 	    event_msg_file,
14411767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_register_info.nwdad_name));
14511767SAnurag.Maskey@Sun.COM 
14611767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
14711767SAnurag.Maskey@Sun.COM }
14811767SAnurag.Maskey@Sun.COM 
14911767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_action(nwam_object_type_t object_type,const char * name,const char * parent,nwam_action_t action)15011767SAnurag.Maskey@Sun.COM nwam_request_action(nwam_object_type_t object_type,
15111767SAnurag.Maskey@Sun.COM     const char *name, const char *parent, nwam_action_t action)
15211767SAnurag.Maskey@Sun.COM {
15311767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
15411767SAnurag.Maskey@Sun.COM 
15511767SAnurag.Maskey@Sun.COM 	assert(name != NULL);
15611767SAnurag.Maskey@Sun.COM 
15711767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_ACTION;
15811767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_action.nwdad_object_type = object_type;
15911767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_action.nwdad_action = action;
16011767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_object_action.nwdad_name, name,
16111767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_object_action.nwdad_name));
16211767SAnurag.Maskey@Sun.COM 	if (parent != NULL) {
16311767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_object_action.nwdad_parent,
16411767SAnurag.Maskey@Sun.COM 		    parent,
16511767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_object_action.nwdad_parent));
16611767SAnurag.Maskey@Sun.COM 	} else {
16711767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_object_action.nwdad_parent[0] = '\0';
16811767SAnurag.Maskey@Sun.COM 	}
16911767SAnurag.Maskey@Sun.COM 
17011767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
17111767SAnurag.Maskey@Sun.COM }
17211767SAnurag.Maskey@Sun.COM 
17311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_state(nwam_object_type_t object_type,const char * name,const char * parent,nwam_state_t * statep,nwam_aux_state_t * auxp)17411767SAnurag.Maskey@Sun.COM nwam_request_state(nwam_object_type_t object_type, const char *name,
17511767SAnurag.Maskey@Sun.COM     const char *parent, nwam_state_t *statep, nwam_aux_state_t *auxp)
17611767SAnurag.Maskey@Sun.COM {
17711767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
17811767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
17911767SAnurag.Maskey@Sun.COM 
18011767SAnurag.Maskey@Sun.COM 	assert(name != NULL && statep != NULL && auxp != NULL);
18111767SAnurag.Maskey@Sun.COM 
18211767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_STATE;
18311767SAnurag.Maskey@Sun.COM 
18411767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_state.nwdad_object_type = object_type;
18511767SAnurag.Maskey@Sun.COM 
18611767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_object_state.nwdad_name, name,
18711767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_object_state.nwdad_name));
18811767SAnurag.Maskey@Sun.COM 	if (parent != NULL) {
18911767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_object_state.nwdad_parent,
19011767SAnurag.Maskey@Sun.COM 		    parent,
19111767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_object_state.nwdad_parent));
19211767SAnurag.Maskey@Sun.COM 	}
19311767SAnurag.Maskey@Sun.COM 
19411767SAnurag.Maskey@Sun.COM 	err = send_msg_to_nwam(&req);
19511767SAnurag.Maskey@Sun.COM 
19611767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS) {
19711767SAnurag.Maskey@Sun.COM 		*statep = req.nwda_data.nwdad_object_state.nwdad_state;
19811767SAnurag.Maskey@Sun.COM 		*auxp = req.nwda_data.nwdad_object_state.nwdad_aux_state;
19911767SAnurag.Maskey@Sun.COM 	}
20011767SAnurag.Maskey@Sun.COM 
20111767SAnurag.Maskey@Sun.COM 	return (err);
20211767SAnurag.Maskey@Sun.COM }
20311767SAnurag.Maskey@Sun.COM 
20411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_wlan(nwam_request_type_t type,const char * name,const char * essid,const char * bssid,uint32_t security_mode,uint_t keyslot,const char * key,boolean_t add_to_known_wlans)20511767SAnurag.Maskey@Sun.COM nwam_request_wlan(nwam_request_type_t type, const char *name,
20611767SAnurag.Maskey@Sun.COM     const char *essid, const char *bssid, uint32_t security_mode,
20711767SAnurag.Maskey@Sun.COM     uint_t keyslot, const char *key, boolean_t add_to_known_wlans)
20811767SAnurag.Maskey@Sun.COM {
20911767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
21011767SAnurag.Maskey@Sun.COM 
21111767SAnurag.Maskey@Sun.COM 	assert(name != NULL);
21211767SAnurag.Maskey@Sun.COM 
21311767SAnurag.Maskey@Sun.COM 	req.nwda_type = type;
21411767SAnurag.Maskey@Sun.COM 
21511767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_name, name,
21611767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_wlan_info));
21711767SAnurag.Maskey@Sun.COM 	if (essid != NULL) {
21811767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_essid, essid,
21911767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_essid));
22011767SAnurag.Maskey@Sun.COM 	} else {
22111767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_essid[0] = '\0';
22211767SAnurag.Maskey@Sun.COM 	}
22311767SAnurag.Maskey@Sun.COM 	if (bssid != NULL) {
22411767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_bssid, bssid,
22511767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_bssid));
22611767SAnurag.Maskey@Sun.COM 	} else {
22711767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_bssid[0] = '\0';
22811767SAnurag.Maskey@Sun.COM 	}
22911767SAnurag.Maskey@Sun.COM 	if (key != NULL) {
23011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_key, key,
23111767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_key));
23211767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_keyslot = keyslot;
23311767SAnurag.Maskey@Sun.COM 	} else {
23411767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_key[0] = '\0';
23511767SAnurag.Maskey@Sun.COM 	}
23611767SAnurag.Maskey@Sun.COM 
23711767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_wlan_info.nwdad_security_mode = security_mode;
23811767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_wlan_info.nwdad_add_to_known_wlans =
23911767SAnurag.Maskey@Sun.COM 	    add_to_known_wlans;
24011767SAnurag.Maskey@Sun.COM 
24111767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
24211767SAnurag.Maskey@Sun.COM }
24311767SAnurag.Maskey@Sun.COM 
24411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_wlan_scan_results(const char * name,uint_t * num_wlansp,nwam_wlan_t ** wlansp)24511767SAnurag.Maskey@Sun.COM nwam_request_wlan_scan_results(const char *name, uint_t *num_wlansp,
24611767SAnurag.Maskey@Sun.COM     nwam_wlan_t **wlansp)
24711767SAnurag.Maskey@Sun.COM {
24811767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
24911767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
25011767SAnurag.Maskey@Sun.COM 
25111767SAnurag.Maskey@Sun.COM 	assert(name != NULL && num_wlansp != NULL && wlansp != NULL);
25211767SAnurag.Maskey@Sun.COM 
25311767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS;
25411767SAnurag.Maskey@Sun.COM 
25511767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_name, name,
25611767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_name));
25711767SAnurag.Maskey@Sun.COM 
25811767SAnurag.Maskey@Sun.COM 	if ((err = send_msg_to_nwam(&req)) != NWAM_SUCCESS)
25911767SAnurag.Maskey@Sun.COM 		return (err);
26011767SAnurag.Maskey@Sun.COM 
26111767SAnurag.Maskey@Sun.COM 	*num_wlansp = req.nwda_data.nwdad_wlan_info.nwdad_num_wlans;
26211767SAnurag.Maskey@Sun.COM 
26311767SAnurag.Maskey@Sun.COM 	*wlansp = calloc(*num_wlansp, sizeof (nwam_wlan_t));
26411767SAnurag.Maskey@Sun.COM 	if (*wlansp == NULL)
26511767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
26611767SAnurag.Maskey@Sun.COM 
26711767SAnurag.Maskey@Sun.COM 	(void) memcpy(*wlansp, req.nwda_data.nwdad_wlan_info.nwdad_wlans,
26811767SAnurag.Maskey@Sun.COM 	    *num_wlansp * sizeof (nwam_wlan_t));
26911767SAnurag.Maskey@Sun.COM 
27011767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
27111767SAnurag.Maskey@Sun.COM }
27211767SAnurag.Maskey@Sun.COM 
27311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_request_active_priority_group(int64_t * priorityp)27411767SAnurag.Maskey@Sun.COM nwam_request_active_priority_group(int64_t *priorityp)
27511767SAnurag.Maskey@Sun.COM {
27611767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
27711767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
27811767SAnurag.Maskey@Sun.COM 
27911767SAnurag.Maskey@Sun.COM 	assert(priorityp != NULL);
28011767SAnurag.Maskey@Sun.COM 
28111767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_PRIORITY_GROUP;
28211767SAnurag.Maskey@Sun.COM 	err = send_msg_to_nwam(&req);
28311767SAnurag.Maskey@Sun.COM 
28411767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS)
28511767SAnurag.Maskey@Sun.COM 		*priorityp =
28611767SAnurag.Maskey@Sun.COM 		    req.nwda_data.nwdad_priority_group_info.nwdad_priority;
28711767SAnurag.Maskey@Sun.COM 
28811767SAnurag.Maskey@Sun.COM 	return (err);
28911767SAnurag.Maskey@Sun.COM }
29011767SAnurag.Maskey@Sun.COM 
29111767SAnurag.Maskey@Sun.COM /* String conversion functions */
29211767SAnurag.Maskey@Sun.COM 
29311767SAnurag.Maskey@Sun.COM const char *
nwam_value_type_to_string(nwam_value_type_t type)29411767SAnurag.Maskey@Sun.COM nwam_value_type_to_string(nwam_value_type_t type)
29511767SAnurag.Maskey@Sun.COM {
29611767SAnurag.Maskey@Sun.COM 	switch (type) {
29711767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_BOOLEAN:
29811767SAnurag.Maskey@Sun.COM 		return ("boolean");
29911767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_INT64:
30011767SAnurag.Maskey@Sun.COM 		return ("int64");
30111767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_UINT64:
30211767SAnurag.Maskey@Sun.COM 		return ("uint64");
30311767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_STRING:
30411767SAnurag.Maskey@Sun.COM 		return ("string");
30511767SAnurag.Maskey@Sun.COM 	default:
30611767SAnurag.Maskey@Sun.COM 		return ("unknown");
30711767SAnurag.Maskey@Sun.COM 	}
30811767SAnurag.Maskey@Sun.COM }
30911767SAnurag.Maskey@Sun.COM 
31011767SAnurag.Maskey@Sun.COM nwam_value_type_t
nwam_string_to_value_type(const char * typestr)31111767SAnurag.Maskey@Sun.COM nwam_string_to_value_type(const char *typestr)
31211767SAnurag.Maskey@Sun.COM {
31311767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_BOOLEAN),
31411767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
31511767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_BOOLEAN);
31611767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_INT64),
31711767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
31811767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_INT64);
31911767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_UINT64),
32011767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
32111767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_UINT64);
32211767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_STRING),
32311767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
32411767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_STRING);
32511767SAnurag.Maskey@Sun.COM 	return (NWAM_VALUE_TYPE_UNKNOWN);
32611767SAnurag.Maskey@Sun.COM }
32711767SAnurag.Maskey@Sun.COM 
32811767SAnurag.Maskey@Sun.COM const char *
nwam_action_to_string(nwam_action_t action)32911767SAnurag.Maskey@Sun.COM nwam_action_to_string(nwam_action_t action)
33011767SAnurag.Maskey@Sun.COM {
33111767SAnurag.Maskey@Sun.COM 	switch (action) {
33211767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ADD:
33311767SAnurag.Maskey@Sun.COM 		return ("add");
33411767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REMOVE:
33511767SAnurag.Maskey@Sun.COM 		return ("remove");
33611767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REFRESH:
33711767SAnurag.Maskey@Sun.COM 		return ("refresh");
33811767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ENABLE:
33911767SAnurag.Maskey@Sun.COM 		return ("enable");
34011767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DISABLE:
34111767SAnurag.Maskey@Sun.COM 		return ("disable");
34211767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DESTROY:
34311767SAnurag.Maskey@Sun.COM 		return ("destroy");
34411767SAnurag.Maskey@Sun.COM 	default:
34511767SAnurag.Maskey@Sun.COM 		return ("unknown");
34611767SAnurag.Maskey@Sun.COM 	}
34711767SAnurag.Maskey@Sun.COM }
34811767SAnurag.Maskey@Sun.COM 
34911767SAnurag.Maskey@Sun.COM const char *
nwam_event_type_to_string(int event_type)35011767SAnurag.Maskey@Sun.COM nwam_event_type_to_string(int event_type)
35111767SAnurag.Maskey@Sun.COM {
35211767SAnurag.Maskey@Sun.COM 	switch (event_type) {
35311767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_NOOP:
35411767SAnurag.Maskey@Sun.COM 		return ("NOOP");
35511767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INIT:
35611767SAnurag.Maskey@Sun.COM 		return ("INIT");
35711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_SHUTDOWN:
35811767SAnurag.Maskey@Sun.COM 		return ("SHUTDOWN");
35911767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_ACTION:
36011767SAnurag.Maskey@Sun.COM 		return ("OBJECT_ACTION");
36111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_STATE:
36211767SAnurag.Maskey@Sun.COM 		return ("OBJECT_STATE");
36311767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_PRIORITY_GROUP:
36411767SAnurag.Maskey@Sun.COM 		return ("PRIORITY_GROUP");
36511767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INFO:
36611767SAnurag.Maskey@Sun.COM 		return ("INFO");
36711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT:
36811767SAnurag.Maskey@Sun.COM 		return ("WLAN_SCAN_REPORT");
36911767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE:
37011767SAnurag.Maskey@Sun.COM 		return ("WLAN_NEED_CHOICE");
37111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_KEY:
37211767SAnurag.Maskey@Sun.COM 		return ("WLAN_NEED_KEY");
37311767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT:
37411767SAnurag.Maskey@Sun.COM 		return ("WLAN_CONNECTION_REPORT");
37511767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_ACTION:
37611767SAnurag.Maskey@Sun.COM 		return ("IF_ACTION");
37711767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_STATE:
37811767SAnurag.Maskey@Sun.COM 		return ("IF_STATE");
37911767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_ACTION:
38011767SAnurag.Maskey@Sun.COM 		return ("LINK_ACTION");
38111767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_STATE:
38211767SAnurag.Maskey@Sun.COM 		return ("LINK_STATE");
38311767SAnurag.Maskey@Sun.COM 	default:
38411767SAnurag.Maskey@Sun.COM 		return ("UNKNOWN");
38511767SAnurag.Maskey@Sun.COM 	}
38611767SAnurag.Maskey@Sun.COM }
38711767SAnurag.Maskey@Sun.COM 
38811767SAnurag.Maskey@Sun.COM const char *
nwam_state_to_string(nwam_state_t state)38911767SAnurag.Maskey@Sun.COM nwam_state_to_string(nwam_state_t state)
39011767SAnurag.Maskey@Sun.COM {
39111767SAnurag.Maskey@Sun.COM 	switch (state) {
39211767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_UNINITIALIZED:
39311767SAnurag.Maskey@Sun.COM 		return ("uninitialized");
39411767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_INITIALIZED:
39511767SAnurag.Maskey@Sun.COM 		return ("initialized");
39611767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE:
39711767SAnurag.Maskey@Sun.COM 		return ("offline");
39811767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE_TO_ONLINE:
39911767SAnurag.Maskey@Sun.COM 		return ("offline*");
40011767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_ONLINE_TO_OFFLINE:
40111767SAnurag.Maskey@Sun.COM 		return ("online*");
40211767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_ONLINE:
40311767SAnurag.Maskey@Sun.COM 		return ("online");
40411767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_MAINTENANCE:
40511767SAnurag.Maskey@Sun.COM 		return ("maintenance");
40611767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DEGRADED:
40711767SAnurag.Maskey@Sun.COM 		return ("degraded");
40811767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DISABLED:
40911767SAnurag.Maskey@Sun.COM 		return ("disabled");
41011767SAnurag.Maskey@Sun.COM 	default:
41111767SAnurag.Maskey@Sun.COM 		return ("unknown");
41211767SAnurag.Maskey@Sun.COM 	}
41311767SAnurag.Maskey@Sun.COM }
41411767SAnurag.Maskey@Sun.COM 
41511767SAnurag.Maskey@Sun.COM const char *
nwam_aux_state_to_string(nwam_aux_state_t aux_state)41611767SAnurag.Maskey@Sun.COM nwam_aux_state_to_string(nwam_aux_state_t aux_state)
41711767SAnurag.Maskey@Sun.COM {
41811767SAnurag.Maskey@Sun.COM 	switch (aux_state) {
41911767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_UNINITIALIZED:
42011767SAnurag.Maskey@Sun.COM 		return ("uninitialized");
42111767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_INITIALIZED:
42211767SAnurag.Maskey@Sun.COM 		return ("(re)initialized but not configured");
42311767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_CONDITIONS_NOT_MET:
42411767SAnurag.Maskey@Sun.COM 		return ("conditions for activation are unmet");
42511767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_MANUAL_DISABLE:
42611767SAnurag.Maskey@Sun.COM 		return ("disabled by administrator");
42711767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_FAILED:
42811767SAnurag.Maskey@Sun.COM 		return ("method/service failed");
42911767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_MISSING:
43011767SAnurag.Maskey@Sun.COM 		return ("method or FMRI not specified");
43111767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_INVALID_CONFIG:
43211767SAnurag.Maskey@Sun.COM 		return ("invalid configuration values");
43311767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_RUNNING:
43411767SAnurag.Maskey@Sun.COM 		return ("method/service executing");
43511767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_ACTIVE:
43611767SAnurag.Maskey@Sun.COM 		return ("active");
43711767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_SCANNING:
43811767SAnurag.Maskey@Sun.COM 		return ("scanning for WiFi networks");
43911767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_NEED_SELECTION:
44011767SAnurag.Maskey@Sun.COM 		return ("need WiFi network selection");
44111767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_NEED_KEY:
44211767SAnurag.Maskey@Sun.COM 		return ("need WiFi security key");
44311767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_CONNECTING:
44411767SAnurag.Maskey@Sun.COM 		return ("connecting to WiFi network");
44511767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_WAITING_FOR_ADDR:
44611767SAnurag.Maskey@Sun.COM 		return ("waiting for IP address to be set");
44711767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_DHCP_TIMED_OUT:
44811767SAnurag.Maskey@Sun.COM 		return ("DHCP wait timeout, still trying...");
44911767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_DUPLICATE_ADDR:
45011767SAnurag.Maskey@Sun.COM 		return ("duplicate address detected");
45111767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_UP:
45211767SAnurag.Maskey@Sun.COM 		return ("interface/link is up");
45311767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_DOWN:
45411767SAnurag.Maskey@Sun.COM 		return ("interface/link is down");
45511767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_NOT_FOUND:
45611767SAnurag.Maskey@Sun.COM 		return ("interface/link not found");
45711767SAnurag.Maskey@Sun.COM 	default:
45811767SAnurag.Maskey@Sun.COM 		return ("unknown");
45911767SAnurag.Maskey@Sun.COM 	}
46011767SAnurag.Maskey@Sun.COM }
46111767SAnurag.Maskey@Sun.COM 
46211767SAnurag.Maskey@Sun.COM const char *
nwam_object_type_to_string(nwam_object_type_t type)46311767SAnurag.Maskey@Sun.COM nwam_object_type_to_string(nwam_object_type_t type)
46411767SAnurag.Maskey@Sun.COM {
46511767SAnurag.Maskey@Sun.COM 	switch (type) {
46611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
46711767SAnurag.Maskey@Sun.COM 		return ("ncp");
46811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
46911767SAnurag.Maskey@Sun.COM 		return ("ncu");
47011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
47111767SAnurag.Maskey@Sun.COM 		return ("loc");
47211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
47311767SAnurag.Maskey@Sun.COM 		return ("enm");
47411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
47511767SAnurag.Maskey@Sun.COM 		return ("known wlan");
47611767SAnurag.Maskey@Sun.COM 	default:
47711767SAnurag.Maskey@Sun.COM 		return ("unknown");
47811767SAnurag.Maskey@Sun.COM 	}
47911767SAnurag.Maskey@Sun.COM }
48011767SAnurag.Maskey@Sun.COM 
48111767SAnurag.Maskey@Sun.COM nwam_object_type_t
nwam_string_to_object_type(const char * typestr)48211767SAnurag.Maskey@Sun.COM nwam_string_to_object_type(const char *typestr)
48311767SAnurag.Maskey@Sun.COM {
48411767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
48511767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCP)) == 0)
48611767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCP);
48711767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
48811767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCU)) == 0)
48911767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCU);
49011767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
49111767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_LOC)) == 0)
49211767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_LOC);
49311767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
49411767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_ENM)) == 0)
49511767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_ENM);
49611767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
49711767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_KNOWN_WLAN)) == 0)
49811767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_KNOWN_WLAN);
49911767SAnurag.Maskey@Sun.COM 	return (NWAM_OBJECT_TYPE_UNKNOWN);
50011767SAnurag.Maskey@Sun.COM }
50111767SAnurag.Maskey@Sun.COM 
50211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_errno_to_nwam_error(int errnum)50311767SAnurag.Maskey@Sun.COM nwam_errno_to_nwam_error(int errnum)
50411767SAnurag.Maskey@Sun.COM {
50511767SAnurag.Maskey@Sun.COM 	switch (errnum) {
50611767SAnurag.Maskey@Sun.COM 	case 0:
50711767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
50811767SAnurag.Maskey@Sun.COM 	case EBADF:
50911767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_BIND);
51011767SAnurag.Maskey@Sun.COM 	case EPERM:
51111767SAnurag.Maskey@Sun.COM 	case EACCES:
51211767SAnurag.Maskey@Sun.COM 		return (NWAM_PERMISSION_DENIED);
51311767SAnurag.Maskey@Sun.COM 	case ENOENT:
51411767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_FOUND);
51511767SAnurag.Maskey@Sun.COM 	case EIDRM:
51611767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
51711767SAnurag.Maskey@Sun.COM 	case EEXIST:
51811767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
51911767SAnurag.Maskey@Sun.COM 	case EAGAIN:
52011767SAnurag.Maskey@Sun.COM 	case EBUSY:
52111767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
52211767SAnurag.Maskey@Sun.COM 	case ENOMEM:
52311767SAnurag.Maskey@Sun.COM 	case ENOSPC:
52411767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
52511767SAnurag.Maskey@Sun.COM 	case EINVAL:
52611767SAnurag.Maskey@Sun.COM 	case E2BIG:
52711767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
52811767SAnurag.Maskey@Sun.COM 	default:
52911767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
53011767SAnurag.Maskey@Sun.COM 	}
53111767SAnurag.Maskey@Sun.COM }
53211767SAnurag.Maskey@Sun.COM 
53311767SAnurag.Maskey@Sun.COM /* Common validation functions */
53411767SAnurag.Maskey@Sun.COM 
53511767SAnurag.Maskey@Sun.COM /*
53611767SAnurag.Maskey@Sun.COM  * Do the flags represent a subset of valid_flags?
53711767SAnurag.Maskey@Sun.COM  */
53811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_flags(uint64_t flags,uint64_t valid_flags)53911767SAnurag.Maskey@Sun.COM nwam_valid_flags(uint64_t flags, uint64_t valid_flags)
54011767SAnurag.Maskey@Sun.COM {
54111767SAnurag.Maskey@Sun.COM 
54211767SAnurag.Maskey@Sun.COM 	if ((flags | valid_flags) != valid_flags)
54311767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
54411767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
54511767SAnurag.Maskey@Sun.COM }
54611767SAnurag.Maskey@Sun.COM 
54711767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_condition(nwam_value_t value)54811767SAnurag.Maskey@Sun.COM nwam_valid_condition(nwam_value_t value)
54911767SAnurag.Maskey@Sun.COM {
55011767SAnurag.Maskey@Sun.COM 	char **conditions;
55111767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
55211767SAnurag.Maskey@Sun.COM 	nwam_condition_object_type_t object_type;
55311767SAnurag.Maskey@Sun.COM 	nwam_condition_t condition;
55411767SAnurag.Maskey@Sun.COM 
55511767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &conditions, &numvalues)
55611767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
55711767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
55811767SAnurag.Maskey@Sun.COM 
55911767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
56011767SAnurag.Maskey@Sun.COM 		char *object_name = NULL;
56111767SAnurag.Maskey@Sun.COM 
56211767SAnurag.Maskey@Sun.COM 		if (nwam_condition_string_to_condition(conditions[i],
56311767SAnurag.Maskey@Sun.COM 		    &object_type, &condition, &object_name) != NWAM_SUCCESS)
56411767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
56511767SAnurag.Maskey@Sun.COM 		if (object_name != NULL)
56611767SAnurag.Maskey@Sun.COM 			free(object_name);
56711767SAnurag.Maskey@Sun.COM 	}
56811767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
56911767SAnurag.Maskey@Sun.COM }
57011767SAnurag.Maskey@Sun.COM 
57111767SAnurag.Maskey@Sun.COM /* check if boolean values are correct, generalize for array of booleans */
57211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_boolean(nwam_value_t value)57311767SAnurag.Maskey@Sun.COM nwam_valid_boolean(nwam_value_t value)
57411767SAnurag.Maskey@Sun.COM {
57511767SAnurag.Maskey@Sun.COM 	boolean_t *val;
57611767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
57711767SAnurag.Maskey@Sun.COM 
57811767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_boolean_array(value, &val, &numvalues)
57911767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
58011767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
58111767SAnurag.Maskey@Sun.COM 
58211767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
58311767SAnurag.Maskey@Sun.COM 		if (val[i] != B_TRUE && val[i] != B_FALSE)
58411767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
58511767SAnurag.Maskey@Sun.COM 	}
58611767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
58711767SAnurag.Maskey@Sun.COM }
58811767SAnurag.Maskey@Sun.COM 
58911767SAnurag.Maskey@Sun.COM /* check if uint64 values are correct, generalize for array of ints */
59011767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_uint64(nwam_value_t value)59111767SAnurag.Maskey@Sun.COM nwam_valid_uint64(nwam_value_t value)
59211767SAnurag.Maskey@Sun.COM {
59311767SAnurag.Maskey@Sun.COM 	int64_t *val;
59411767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
59511767SAnurag.Maskey@Sun.COM 
59611767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_int64_array(value, &val, &numvalues)
59711767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
59811767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
59911767SAnurag.Maskey@Sun.COM 
60011767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
60111767SAnurag.Maskey@Sun.COM 		if (val[i] < 0)
60211767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
60311767SAnurag.Maskey@Sun.COM 	}
60411767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
60511767SAnurag.Maskey@Sun.COM }
60611767SAnurag.Maskey@Sun.COM 
60711767SAnurag.Maskey@Sun.COM /* check if domain names are correct, generalize for array of domains */
60811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_domain(nwam_value_t value)60911767SAnurag.Maskey@Sun.COM nwam_valid_domain(nwam_value_t value)
61011767SAnurag.Maskey@Sun.COM {
61111767SAnurag.Maskey@Sun.COM 	char **domainvalues, *domain;
61211767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
61311767SAnurag.Maskey@Sun.COM 	int len, j;
61411767SAnurag.Maskey@Sun.COM 
61511767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &domainvalues, &numvalues)
61611767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
61711767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
61811767SAnurag.Maskey@Sun.COM 
61911767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
62011767SAnurag.Maskey@Sun.COM 		/*
62111767SAnurag.Maskey@Sun.COM 		 * First and last character must be alphanumeric.
62211767SAnurag.Maskey@Sun.COM 		 * Only '.' and '-' are allowed.
62311767SAnurag.Maskey@Sun.COM 		 */
62411767SAnurag.Maskey@Sun.COM 		domain = domainvalues[i];
62511767SAnurag.Maskey@Sun.COM 		len = strlen(domain);
62611767SAnurag.Maskey@Sun.COM 		if (!isalnum(domain[0]) || !isalnum(domain[len-1]))
62711767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
62811767SAnurag.Maskey@Sun.COM 		for (j = 0; j < len; j++) {
62911767SAnurag.Maskey@Sun.COM 			if (!isalnum(domain[j]) &&
63011767SAnurag.Maskey@Sun.COM 			    domain[j] != '.' && domain[j] != '-')
63111767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_INVALID_VALUE);
63211767SAnurag.Maskey@Sun.COM 		}
63311767SAnurag.Maskey@Sun.COM 	}
63411767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
63511767SAnurag.Maskey@Sun.COM }
63611767SAnurag.Maskey@Sun.COM 
63711767SAnurag.Maskey@Sun.COM /* check if address prefix is valid */
63811767SAnurag.Maskey@Sun.COM static nwam_error_t
nwam_valid_prefix(char * addr,int max_plen)63911767SAnurag.Maskey@Sun.COM nwam_valid_prefix(char *addr, int max_plen)
64011767SAnurag.Maskey@Sun.COM {
64111767SAnurag.Maskey@Sun.COM 	char *prefix, *end;
64211767SAnurag.Maskey@Sun.COM 	int prefixlen;
64311767SAnurag.Maskey@Sun.COM 
64411767SAnurag.Maskey@Sun.COM 	if ((prefix = strchr(addr, '/')) != NULL) {
64511767SAnurag.Maskey@Sun.COM 		prefix++;
64611767SAnurag.Maskey@Sun.COM 		prefixlen = strtol(prefix, &end, 10);
64711767SAnurag.Maskey@Sun.COM 		if (prefix == end || prefixlen < 0 || prefixlen > max_plen)
64811767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
64911767SAnurag.Maskey@Sun.COM 	}
65011767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
65111767SAnurag.Maskey@Sun.COM }
65211767SAnurag.Maskey@Sun.COM 
65311767SAnurag.Maskey@Sun.COM /* check if IPv4 addresses are correct, generalize for array of addresses */
65411767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_host_v4(nwam_value_t value)65511767SAnurag.Maskey@Sun.COM nwam_valid_host_v4(nwam_value_t value)
65611767SAnurag.Maskey@Sun.COM {
65711767SAnurag.Maskey@Sun.COM 	char **addrvalues, *addr;
65811767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
65911767SAnurag.Maskey@Sun.COM 	struct sockaddr_in sa;
66011767SAnurag.Maskey@Sun.COM 
66111767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &addrvalues, &numvalues)
66211767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
66311767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
66411767SAnurag.Maskey@Sun.COM 
66511767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
66611767SAnurag.Maskey@Sun.COM 		addr = strdup(addrvalues[i]);
66711767SAnurag.Maskey@Sun.COM 		if (nwam_valid_prefix(addr, IP_ABITS) != NWAM_SUCCESS) {
66811767SAnurag.Maskey@Sun.COM 			free(addr);
66911767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
67011767SAnurag.Maskey@Sun.COM 		}
67111767SAnurag.Maskey@Sun.COM 		/* replace '/' with '\0' */
67211767SAnurag.Maskey@Sun.COM 		addr = strsep(&addr, "/");
67311767SAnurag.Maskey@Sun.COM 		if (inet_pton(AF_INET, addr, &(sa.sin_addr)) != 1) {
67411767SAnurag.Maskey@Sun.COM 			free(addr);
67511767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
67611767SAnurag.Maskey@Sun.COM 		}
67711767SAnurag.Maskey@Sun.COM 		free(addr);
67811767SAnurag.Maskey@Sun.COM 	}
67911767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
68011767SAnurag.Maskey@Sun.COM }
68111767SAnurag.Maskey@Sun.COM 
68211767SAnurag.Maskey@Sun.COM /* Check if IPv4 address for default route is valid */
68311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_route_v4(nwam_value_t value)68411767SAnurag.Maskey@Sun.COM nwam_valid_route_v4(nwam_value_t value)
68511767SAnurag.Maskey@Sun.COM {
68611767SAnurag.Maskey@Sun.COM 	char *addrvalue;
68711767SAnurag.Maskey@Sun.COM 	struct sockaddr_in sa;
68811767SAnurag.Maskey@Sun.COM 
68911767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string(value, &addrvalue) != NWAM_SUCCESS)
69011767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
69111767SAnurag.Maskey@Sun.COM 
69211767SAnurag.Maskey@Sun.COM 	if (inet_pton(AF_INET, addrvalue, &(sa.sin_addr)) != 1)
69311767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
69411767SAnurag.Maskey@Sun.COM 
69511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
69611767SAnurag.Maskey@Sun.COM }
69711767SAnurag.Maskey@Sun.COM 
69811767SAnurag.Maskey@Sun.COM /* check if IPv6 addresses are correct, generalize for array of addresses */
69911767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_host_v6(nwam_value_t value)70011767SAnurag.Maskey@Sun.COM nwam_valid_host_v6(nwam_value_t value)
70111767SAnurag.Maskey@Sun.COM {
70211767SAnurag.Maskey@Sun.COM 	char **addrvalues, *addr;
70311767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
70411767SAnurag.Maskey@Sun.COM 	struct sockaddr_in6 sa;
70511767SAnurag.Maskey@Sun.COM 
70611767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &addrvalues, &numvalues)
70711767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
70811767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
70911767SAnurag.Maskey@Sun.COM 
71011767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
71111767SAnurag.Maskey@Sun.COM 		addr = strdup(addrvalues[i]);
71211767SAnurag.Maskey@Sun.COM 		if (nwam_valid_prefix(addr, IPV6_ABITS) != NWAM_SUCCESS) {
71311767SAnurag.Maskey@Sun.COM 			free(addr);
71411767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
71511767SAnurag.Maskey@Sun.COM 		}
71611767SAnurag.Maskey@Sun.COM 		/* replace '/' with '\0' */
71711767SAnurag.Maskey@Sun.COM 		addr = strsep(&addr, "/");
71811767SAnurag.Maskey@Sun.COM 		if (inet_pton(AF_INET6, addr, &(sa.sin6_addr)) != 1) {
71911767SAnurag.Maskey@Sun.COM 			free(addr);
72011767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
72111767SAnurag.Maskey@Sun.COM 		}
72211767SAnurag.Maskey@Sun.COM 		free(addr);
72311767SAnurag.Maskey@Sun.COM 	}
72411767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
72511767SAnurag.Maskey@Sun.COM }
72611767SAnurag.Maskey@Sun.COM 
72711767SAnurag.Maskey@Sun.COM /* Check if IPv4 address for default route is valid */
72811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_route_v6(nwam_value_t value)72911767SAnurag.Maskey@Sun.COM nwam_valid_route_v6(nwam_value_t value)
73011767SAnurag.Maskey@Sun.COM {
73111767SAnurag.Maskey@Sun.COM 	char *addrvalue;
73211767SAnurag.Maskey@Sun.COM 	struct sockaddr_in6 sa;
73311767SAnurag.Maskey@Sun.COM 
73411767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string(value, &addrvalue) != NWAM_SUCCESS)
73511767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
73611767SAnurag.Maskey@Sun.COM 
73711767SAnurag.Maskey@Sun.COM 	if (inet_pton(AF_INET6, addrvalue, &(sa.sin6_addr)) != 1)
73811767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
73911767SAnurag.Maskey@Sun.COM 
74011767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
74111767SAnurag.Maskey@Sun.COM }
74211767SAnurag.Maskey@Sun.COM 
74311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_host_any(nwam_value_t value)74411767SAnurag.Maskey@Sun.COM nwam_valid_host_any(nwam_value_t value)
74511767SAnurag.Maskey@Sun.COM {
74611767SAnurag.Maskey@Sun.COM 	if (nwam_valid_host_v4(value) != NWAM_SUCCESS &&
74711767SAnurag.Maskey@Sun.COM 	    nwam_valid_host_v6(value) != NWAM_SUCCESS)
74811767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
74911767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
75011767SAnurag.Maskey@Sun.COM }
75111767SAnurag.Maskey@Sun.COM 
75211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_host_or_domain(nwam_value_t value)75311767SAnurag.Maskey@Sun.COM nwam_valid_host_or_domain(nwam_value_t value)
75411767SAnurag.Maskey@Sun.COM {
75511767SAnurag.Maskey@Sun.COM 	if (nwam_valid_host_any(value) != NWAM_SUCCESS &&
75611767SAnurag.Maskey@Sun.COM 	    nwam_valid_domain(value) != NWAM_SUCCESS)
75711767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
75811767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
75911767SAnurag.Maskey@Sun.COM }
76011767SAnurag.Maskey@Sun.COM 
76111767SAnurag.Maskey@Sun.COM /* We do not validate file existence, merely that it is an absolute path. */
76211767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_file(nwam_value_t value)76311767SAnurag.Maskey@Sun.COM nwam_valid_file(nwam_value_t value)
76411767SAnurag.Maskey@Sun.COM {
76511767SAnurag.Maskey@Sun.COM 	char **files;
76611767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
76711767SAnurag.Maskey@Sun.COM 
76811767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &files, &numvalues)
76911767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
77011767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
77111767SAnurag.Maskey@Sun.COM 
77211767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
77311767SAnurag.Maskey@Sun.COM 		int j = 0;
77411767SAnurag.Maskey@Sun.COM 		while (isspace(files[i][j]))
77511767SAnurag.Maskey@Sun.COM 			j++;
77611767SAnurag.Maskey@Sun.COM 		if (files[i][j] != '/')
77711767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
77811767SAnurag.Maskey@Sun.COM 	}
77911767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
78011767SAnurag.Maskey@Sun.COM }
78111767SAnurag.Maskey@Sun.COM 
78211767SAnurag.Maskey@Sun.COM /*
78311767SAnurag.Maskey@Sun.COM  * We do not validate existence of the object pointed to by the FMRI
78411767SAnurag.Maskey@Sun.COM  * but merely ensure that it is a valid FMRI.  We do this by
78511767SAnurag.Maskey@Sun.COM  * using scf_handle_decode_fmri(), but ignore all errors bar
78611767SAnurag.Maskey@Sun.COM  * SCF_ERROR_INVALID_ARGUMENT (which indicates the FMRI is invalid).
78711767SAnurag.Maskey@Sun.COM  */
78811767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_fmri(nwam_value_t value)78911767SAnurag.Maskey@Sun.COM nwam_valid_fmri(nwam_value_t value)
79011767SAnurag.Maskey@Sun.COM {
79111767SAnurag.Maskey@Sun.COM 	char **valstr;
79211767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
79311767SAnurag.Maskey@Sun.COM 	scf_service_t *svc = NULL;
79411767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
79511767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
79611767SAnurag.Maskey@Sun.COM 
79711767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_get_string_array(value, &valstr, &numvalues))
79811767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
79911767SAnurag.Maskey@Sun.COM 		return (err);
80011767SAnurag.Maskey@Sun.COM 
80111767SAnurag.Maskey@Sun.COM 	h = scf_handle_create(SCF_VERSION);
80211767SAnurag.Maskey@Sun.COM 	if (h == NULL)
80311767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
80411767SAnurag.Maskey@Sun.COM 
80511767SAnurag.Maskey@Sun.COM 	if (scf_handle_bind(h) != 0) {
80611767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
80711767SAnurag.Maskey@Sun.COM 		goto out;
80811767SAnurag.Maskey@Sun.COM 	}
80911767SAnurag.Maskey@Sun.COM 
81011767SAnurag.Maskey@Sun.COM 	if ((svc = scf_service_create(h)) == NULL) {
81111767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
81211767SAnurag.Maskey@Sun.COM 		goto out;
81311767SAnurag.Maskey@Sun.COM 	}
81411767SAnurag.Maskey@Sun.COM 
81511767SAnurag.Maskey@Sun.COM 
81611767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
81711767SAnurag.Maskey@Sun.COM 		if (scf_handle_decode_fmri(h, valstr[i], NULL, svc,
81811767SAnurag.Maskey@Sun.COM 		    NULL, NULL, NULL, SCF_DECODE_FMRI_TRUNCATE) == 0 ||
81911767SAnurag.Maskey@Sun.COM 		    scf_error() != SCF_ERROR_INVALID_ARGUMENT) {
82011767SAnurag.Maskey@Sun.COM 			err = NWAM_SUCCESS;
82111767SAnurag.Maskey@Sun.COM 			continue;
82211767SAnurag.Maskey@Sun.COM 		}
82311767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_INVALID_VALUE;
82411767SAnurag.Maskey@Sun.COM 		break;
82511767SAnurag.Maskey@Sun.COM 	}
82611767SAnurag.Maskey@Sun.COM out:
82711767SAnurag.Maskey@Sun.COM 	scf_service_destroy(svc);
82811767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
82911767SAnurag.Maskey@Sun.COM 	return (err);
83011767SAnurag.Maskey@Sun.COM }
83111767SAnurag.Maskey@Sun.COM 
83211767SAnurag.Maskey@Sun.COM /* verifies mac-address and bssids */
83311767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_valid_mac_addr(nwam_value_t value)83411767SAnurag.Maskey@Sun.COM nwam_valid_mac_addr(nwam_value_t value)
83511767SAnurag.Maskey@Sun.COM {
83611767SAnurag.Maskey@Sun.COM 	char **mac_addrs, *addr;
83711767SAnurag.Maskey@Sun.COM 	uchar_t	*hwaddr;
83811767SAnurag.Maskey@Sun.COM 	int hwaddrlen, j;
83911767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
84011767SAnurag.Maskey@Sun.COM 
84111767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &mac_addrs, &numvalues)
84211767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
84311767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
84411767SAnurag.Maskey@Sun.COM 
84511767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
84611767SAnurag.Maskey@Sun.COM 		addr = mac_addrs[i];
84711767SAnurag.Maskey@Sun.COM 		j = 0;
84811767SAnurag.Maskey@Sun.COM 
84911767SAnurag.Maskey@Sun.COM 		/* validate that a-fA-F0-9 and ':' only */
85011767SAnurag.Maskey@Sun.COM 		while (addr[j] != 0) {
85111767SAnurag.Maskey@Sun.COM 			if (!isxdigit(addr[j]) && addr[j] != ':')
85211767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_INVALID_VALUE);
85311767SAnurag.Maskey@Sun.COM 			j++;
85411767SAnurag.Maskey@Sun.COM 		}
85511767SAnurag.Maskey@Sun.COM 
85611767SAnurag.Maskey@Sun.COM 		if ((hwaddr = _link_aton(addr, &hwaddrlen)) == NULL)
85711767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
85811767SAnurag.Maskey@Sun.COM 		free(hwaddr);
85911767SAnurag.Maskey@Sun.COM 	}
86011767SAnurag.Maskey@Sun.COM 
86111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
86211767SAnurag.Maskey@Sun.COM }
86311767SAnurag.Maskey@Sun.COM 
86411767SAnurag.Maskey@Sun.COM boolean_t
nwam_uid_is_special(void)865*12036SMichael.Hunter@Sun.COM nwam_uid_is_special(void)
86611767SAnurag.Maskey@Sun.COM {
867*12036SMichael.Hunter@Sun.COM 	uid_t uid = getuid();
868*12036SMichael.Hunter@Sun.COM 	return (uid == UID_NETADM || uid == 0);
86911767SAnurag.Maskey@Sun.COM }
87011767SAnurag.Maskey@Sun.COM 
87111767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_get_smf_string_property(const char * fmri,const char * pgname,const char * propname,char ** valuep)87211767SAnurag.Maskey@Sun.COM nwam_get_smf_string_property(const char *fmri, const char *pgname,
87311767SAnurag.Maskey@Sun.COM     const char *propname, char **valuep)
87411767SAnurag.Maskey@Sun.COM {
87511767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
87611767SAnurag.Maskey@Sun.COM 	scf_snapshot_t *snap = NULL;
87711767SAnurag.Maskey@Sun.COM 	scf_instance_t *inst = NULL;
87811767SAnurag.Maskey@Sun.COM 	scf_propertygroup_t *pg = NULL;
87911767SAnurag.Maskey@Sun.COM 	scf_property_t *prop = NULL;
88011767SAnurag.Maskey@Sun.COM 	scf_value_t *val = NULL;
88111767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
88211767SAnurag.Maskey@Sun.COM 
88311767SAnurag.Maskey@Sun.COM 	if ((*valuep = malloc(NWAM_MAX_NAME_LEN)) == NULL)
88411767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
88511767SAnurag.Maskey@Sun.COM 
88611767SAnurag.Maskey@Sun.COM 	if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
88711767SAnurag.Maskey@Sun.COM 	    scf_handle_bind(h) != 0 ||
88811767SAnurag.Maskey@Sun.COM 	    (inst = scf_instance_create(h)) == NULL ||
88911767SAnurag.Maskey@Sun.COM 	    (snap = scf_snapshot_create(h)) == NULL ||
89011767SAnurag.Maskey@Sun.COM 	    (pg = scf_pg_create(h)) == NULL ||
89111767SAnurag.Maskey@Sun.COM 	    (prop = scf_property_create(h)) == NULL ||
89211767SAnurag.Maskey@Sun.COM 	    (val = scf_value_create(h)) == NULL) {
89311767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
89411767SAnurag.Maskey@Sun.COM 		goto out;
89511767SAnurag.Maskey@Sun.COM 	}
89611767SAnurag.Maskey@Sun.COM 	if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst,
89711767SAnurag.Maskey@Sun.COM 	    NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
89811767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
89911767SAnurag.Maskey@Sun.COM 		goto out;
90011767SAnurag.Maskey@Sun.COM 	}
90111767SAnurag.Maskey@Sun.COM 	/* Retrieve value from running snapshot (if present) */
90211767SAnurag.Maskey@Sun.COM 	if (scf_instance_get_snapshot(inst, "running", snap) != 0) {
90311767SAnurag.Maskey@Sun.COM 		scf_snapshot_destroy(snap);
90411767SAnurag.Maskey@Sun.COM 		snap = NULL;
90511767SAnurag.Maskey@Sun.COM 	}
90611767SAnurag.Maskey@Sun.COM 	if (scf_instance_get_pg_composed(inst, snap, pgname, pg) != 0 ||
90711767SAnurag.Maskey@Sun.COM 	    scf_pg_get_property(pg, propname, prop) != 0 ||
90811767SAnurag.Maskey@Sun.COM 	    scf_property_get_value(prop, val) != 0 ||
90911767SAnurag.Maskey@Sun.COM 	    scf_value_get_astring(val, *valuep, NWAM_MAX_NAME_LEN) == -1) {
91011767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
91111767SAnurag.Maskey@Sun.COM 	}
91211767SAnurag.Maskey@Sun.COM out:
91311767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
91411767SAnurag.Maskey@Sun.COM 		free(*valuep);
91511767SAnurag.Maskey@Sun.COM 
91611767SAnurag.Maskey@Sun.COM 	scf_value_destroy(val);
91711767SAnurag.Maskey@Sun.COM 	scf_property_destroy(prop);
91811767SAnurag.Maskey@Sun.COM 	scf_pg_destroy(pg);
91911767SAnurag.Maskey@Sun.COM 	if (snap != NULL)
92011767SAnurag.Maskey@Sun.COM 		scf_snapshot_destroy(snap);
92111767SAnurag.Maskey@Sun.COM 	scf_instance_destroy(inst);
92211767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
92311767SAnurag.Maskey@Sun.COM 
92411767SAnurag.Maskey@Sun.COM 	return (err);
92511767SAnurag.Maskey@Sun.COM }
92611767SAnurag.Maskey@Sun.COM 
92711767SAnurag.Maskey@Sun.COM nwam_error_t
nwam_set_smf_string_property(const char * fmri,const char * pgname,const char * propname,const char * propval)92811767SAnurag.Maskey@Sun.COM nwam_set_smf_string_property(const char *fmri, const char *pgname,
92911767SAnurag.Maskey@Sun.COM     const char *propname, const char *propval)
93011767SAnurag.Maskey@Sun.COM {
93111767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
93211767SAnurag.Maskey@Sun.COM 	scf_instance_t *inst = NULL;
93311767SAnurag.Maskey@Sun.COM 	scf_propertygroup_t *pg = NULL;
93411767SAnurag.Maskey@Sun.COM 	scf_property_t *prop = NULL;
93511767SAnurag.Maskey@Sun.COM 	scf_value_t *val = NULL;
93611767SAnurag.Maskey@Sun.COM 	scf_transaction_t *tx = NULL;
93711767SAnurag.Maskey@Sun.COM 	scf_transaction_entry_t *ent = NULL;
93811767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
93911767SAnurag.Maskey@Sun.COM 	int result;
94011767SAnurag.Maskey@Sun.COM 
94111767SAnurag.Maskey@Sun.COM 	if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
94211767SAnurag.Maskey@Sun.COM 	    scf_handle_bind(h) != 0 ||
94311767SAnurag.Maskey@Sun.COM 	    (inst = scf_instance_create(h)) == NULL ||
94411767SAnurag.Maskey@Sun.COM 	    (pg = scf_pg_create(h)) == NULL ||
94511767SAnurag.Maskey@Sun.COM 	    (prop = scf_property_create(h)) == NULL ||
94611767SAnurag.Maskey@Sun.COM 	    (val = scf_value_create(h)) == NULL ||
94711767SAnurag.Maskey@Sun.COM 	    scf_value_set_astring(val, propval) != 0 ||
94811767SAnurag.Maskey@Sun.COM 	    (tx = scf_transaction_create(h)) == NULL ||
94911767SAnurag.Maskey@Sun.COM 	    (ent = scf_entry_create(h)) == NULL) {
95011767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
95111767SAnurag.Maskey@Sun.COM 		goto out;
95211767SAnurag.Maskey@Sun.COM 	}
95311767SAnurag.Maskey@Sun.COM 	if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst,
95411767SAnurag.Maskey@Sun.COM 	    NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0 ||
95511767SAnurag.Maskey@Sun.COM 	    scf_instance_get_pg_composed(inst, NULL, pgname, pg) != 0) {
95611767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
95711767SAnurag.Maskey@Sun.COM 		goto out;
95811767SAnurag.Maskey@Sun.COM 	}
95911767SAnurag.Maskey@Sun.COM 
96011767SAnurag.Maskey@Sun.COM retry:
96111767SAnurag.Maskey@Sun.COM 	if (scf_transaction_start(tx, pg) == -1 ||
96211767SAnurag.Maskey@Sun.COM 	    scf_transaction_property_change(tx, ent, propname, SCF_TYPE_ASTRING)
96311767SAnurag.Maskey@Sun.COM 	    == -1 || scf_entry_add_value(ent, val) != 0) {
96411767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
96511767SAnurag.Maskey@Sun.COM 		goto out;
96611767SAnurag.Maskey@Sun.COM 	}
96711767SAnurag.Maskey@Sun.COM 
96811767SAnurag.Maskey@Sun.COM 	result = scf_transaction_commit(tx);
96911767SAnurag.Maskey@Sun.COM 	switch (result) {
97011767SAnurag.Maskey@Sun.COM 	case 1:
97111767SAnurag.Maskey@Sun.COM 		(void) smf_refresh_instance(fmri);
97211767SAnurag.Maskey@Sun.COM 		break;
97311767SAnurag.Maskey@Sun.COM 	case 0:
97411767SAnurag.Maskey@Sun.COM 		scf_transaction_reset(tx);
97511767SAnurag.Maskey@Sun.COM 		if (scf_pg_update(pg) == -1) {
97611767SAnurag.Maskey@Sun.COM 			err = NWAM_ERROR_INTERNAL;
97711767SAnurag.Maskey@Sun.COM 			goto out;
97811767SAnurag.Maskey@Sun.COM 		}
97911767SAnurag.Maskey@Sun.COM 		goto retry;
98011767SAnurag.Maskey@Sun.COM 	default:
98111767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
98211767SAnurag.Maskey@Sun.COM 		break;
98311767SAnurag.Maskey@Sun.COM 	}
98411767SAnurag.Maskey@Sun.COM out:
98511767SAnurag.Maskey@Sun.COM 	scf_value_destroy(val);
98611767SAnurag.Maskey@Sun.COM 	scf_property_destroy(prop);
98711767SAnurag.Maskey@Sun.COM 	scf_pg_destroy(pg);
98811767SAnurag.Maskey@Sun.COM 	scf_instance_destroy(inst);
98911767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
99011767SAnurag.Maskey@Sun.COM 
99111767SAnurag.Maskey@Sun.COM 	return (err);
99211767SAnurag.Maskey@Sun.COM }
993