1*11767SAnurag.Maskey@Sun.COM /*
2*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
3*11767SAnurag.Maskey@Sun.COM  *
4*11767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
5*11767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
6*11767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
7*11767SAnurag.Maskey@Sun.COM  *
8*11767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
11*11767SAnurag.Maskey@Sun.COM  * and limitations under the License.
12*11767SAnurag.Maskey@Sun.COM  *
13*11767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11767SAnurag.Maskey@Sun.COM  *
19*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
20*11767SAnurag.Maskey@Sun.COM  */
21*11767SAnurag.Maskey@Sun.COM 
22*11767SAnurag.Maskey@Sun.COM /*
23*11767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*11767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
25*11767SAnurag.Maskey@Sun.COM  */
26*11767SAnurag.Maskey@Sun.COM 
27*11767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
28*11767SAnurag.Maskey@Sun.COM #include <assert.h>
29*11767SAnurag.Maskey@Sun.COM #include <atomic.h>
30*11767SAnurag.Maskey@Sun.COM #include <ctype.h>
31*11767SAnurag.Maskey@Sun.COM #include <errno.h>
32*11767SAnurag.Maskey@Sun.COM #include <inet/ip.h>
33*11767SAnurag.Maskey@Sun.COM #include <libintl.h>
34*11767SAnurag.Maskey@Sun.COM #include <libproc.h>
35*11767SAnurag.Maskey@Sun.COM #include <libscf.h>
36*11767SAnurag.Maskey@Sun.COM #include <net/if_dl.h>
37*11767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
38*11767SAnurag.Maskey@Sun.COM #include <pthread.h>
39*11767SAnurag.Maskey@Sun.COM #include <stdio.h>
40*11767SAnurag.Maskey@Sun.COM #include <stdlib.h>
41*11767SAnurag.Maskey@Sun.COM #include <strings.h>
42*11767SAnurag.Maskey@Sun.COM #include <sys/mman.h>
43*11767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
44*11767SAnurag.Maskey@Sun.COM #include <sys/types.h>
45*11767SAnurag.Maskey@Sun.COM #include <unistd.h>
46*11767SAnurag.Maskey@Sun.COM 
47*11767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
48*11767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
49*11767SAnurag.Maskey@Sun.COM #include <libnwam.h>
50*11767SAnurag.Maskey@Sun.COM 
51*11767SAnurag.Maskey@Sun.COM /*
52*11767SAnurag.Maskey@Sun.COM  * Utility functions for door access, common validation functions etc.
53*11767SAnurag.Maskey@Sun.COM  */
54*11767SAnurag.Maskey@Sun.COM 
55*11767SAnurag.Maskey@Sun.COM pthread_mutex_t door_mutex = PTHREAD_MUTEX_INITIALIZER;
56*11767SAnurag.Maskey@Sun.COM int nwam_door_fd = -1;
57*11767SAnurag.Maskey@Sun.COM 
58*11767SAnurag.Maskey@Sun.COM static int
59*11767SAnurag.Maskey@Sun.COM open_door(const char *door_name, int *door_fdp)
60*11767SAnurag.Maskey@Sun.COM {
61*11767SAnurag.Maskey@Sun.COM 	struct door_info dinfo;
62*11767SAnurag.Maskey@Sun.COM 	int err = 0;
63*11767SAnurag.Maskey@Sun.COM 
64*11767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&door_mutex);
65*11767SAnurag.Maskey@Sun.COM 
66*11767SAnurag.Maskey@Sun.COM 	if (*door_fdp != -1) {
67*11767SAnurag.Maskey@Sun.COM 		/* Check door fd is not old (from previous nwamd). */
68*11767SAnurag.Maskey@Sun.COM 		if (door_info(*door_fdp, &dinfo) != 0 ||
69*11767SAnurag.Maskey@Sun.COM 		    (dinfo.di_attributes & DOOR_REVOKED) != 0) {
70*11767SAnurag.Maskey@Sun.COM 			(void) close(*door_fdp);
71*11767SAnurag.Maskey@Sun.COM 			*door_fdp = -1;
72*11767SAnurag.Maskey@Sun.COM 		}
73*11767SAnurag.Maskey@Sun.COM 	}
74*11767SAnurag.Maskey@Sun.COM 	if (*door_fdp == -1) {
75*11767SAnurag.Maskey@Sun.COM 		*door_fdp = open(door_name, 0);
76*11767SAnurag.Maskey@Sun.COM 		if (*door_fdp == -1)
77*11767SAnurag.Maskey@Sun.COM 			err = errno;
78*11767SAnurag.Maskey@Sun.COM 	}
79*11767SAnurag.Maskey@Sun.COM 
80*11767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&door_mutex);
81*11767SAnurag.Maskey@Sun.COM 
82*11767SAnurag.Maskey@Sun.COM 	return (err);
83*11767SAnurag.Maskey@Sun.COM }
84*11767SAnurag.Maskey@Sun.COM 
85*11767SAnurag.Maskey@Sun.COM int
86*11767SAnurag.Maskey@Sun.COM nwam_make_door_call(const char *door_name, int *door_fdp,
87*11767SAnurag.Maskey@Sun.COM     void *request, size_t request_size)
88*11767SAnurag.Maskey@Sun.COM {
89*11767SAnurag.Maskey@Sun.COM 	int err;
90*11767SAnurag.Maskey@Sun.COM 	door_arg_t door_args;
91*11767SAnurag.Maskey@Sun.COM 
92*11767SAnurag.Maskey@Sun.COM 	door_args.data_ptr = (void *)request;
93*11767SAnurag.Maskey@Sun.COM 	door_args.data_size = request_size;
94*11767SAnurag.Maskey@Sun.COM 	door_args.desc_ptr = NULL;
95*11767SAnurag.Maskey@Sun.COM 	door_args.desc_num = 0;
96*11767SAnurag.Maskey@Sun.COM 	door_args.rbuf = (void *)request;
97*11767SAnurag.Maskey@Sun.COM 	door_args.rsize = request_size;
98*11767SAnurag.Maskey@Sun.COM 
99*11767SAnurag.Maskey@Sun.COM 	if ((err = open_door(door_name, door_fdp)) != 0)
100*11767SAnurag.Maskey@Sun.COM 		return (err);
101*11767SAnurag.Maskey@Sun.COM 
102*11767SAnurag.Maskey@Sun.COM 	if (door_call(*door_fdp, &door_args) == -1)
103*11767SAnurag.Maskey@Sun.COM 		return (errno);
104*11767SAnurag.Maskey@Sun.COM 
105*11767SAnurag.Maskey@Sun.COM 	return (0);
106*11767SAnurag.Maskey@Sun.COM }
107*11767SAnurag.Maskey@Sun.COM 
108*11767SAnurag.Maskey@Sun.COM static nwam_error_t
109*11767SAnurag.Maskey@Sun.COM send_msg_to_nwam(nwamd_door_arg_t *request)
110*11767SAnurag.Maskey@Sun.COM {
111*11767SAnurag.Maskey@Sun.COM 	int err;
112*11767SAnurag.Maskey@Sun.COM 
113*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_make_door_call(NWAM_DOOR, &nwam_door_fd,
114*11767SAnurag.Maskey@Sun.COM 	    request, sizeof (nwamd_door_arg_t))) != 0) {
115*11767SAnurag.Maskey@Sun.COM 		if (err == ENOENT)
116*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ERROR_BIND);
117*11767SAnurag.Maskey@Sun.COM 		return (nwam_errno_to_nwam_error(err));
118*11767SAnurag.Maskey@Sun.COM 	}
119*11767SAnurag.Maskey@Sun.COM 
120*11767SAnurag.Maskey@Sun.COM 	switch (request->nwda_status) {
121*11767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_OK:
122*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
123*11767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_UNKNOWN:
124*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
125*11767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_ALREADY:
126*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
127*11767SAnurag.Maskey@Sun.COM 	case NWAM_REQUEST_STATUS_FAILED:
128*11767SAnurag.Maskey@Sun.COM 		return (request->nwda_error);
129*11767SAnurag.Maskey@Sun.COM 	default:
130*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
131*11767SAnurag.Maskey@Sun.COM 	}
132*11767SAnurag.Maskey@Sun.COM }
133*11767SAnurag.Maskey@Sun.COM 
134*11767SAnurag.Maskey@Sun.COM nwam_error_t
135*11767SAnurag.Maskey@Sun.COM nwam_request_register_unregister(nwam_request_type_t type,
136*11767SAnurag.Maskey@Sun.COM     const char *event_msg_file)
137*11767SAnurag.Maskey@Sun.COM {
138*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
139*11767SAnurag.Maskey@Sun.COM 
140*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = type;
141*11767SAnurag.Maskey@Sun.COM 
142*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_register_info.nwdad_name,
143*11767SAnurag.Maskey@Sun.COM 	    event_msg_file,
144*11767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_register_info.nwdad_name));
145*11767SAnurag.Maskey@Sun.COM 
146*11767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
147*11767SAnurag.Maskey@Sun.COM }
148*11767SAnurag.Maskey@Sun.COM 
149*11767SAnurag.Maskey@Sun.COM nwam_error_t
150*11767SAnurag.Maskey@Sun.COM nwam_request_action(nwam_object_type_t object_type,
151*11767SAnurag.Maskey@Sun.COM     const char *name, const char *parent, nwam_action_t action)
152*11767SAnurag.Maskey@Sun.COM {
153*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
154*11767SAnurag.Maskey@Sun.COM 
155*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL);
156*11767SAnurag.Maskey@Sun.COM 
157*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_ACTION;
158*11767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_action.nwdad_object_type = object_type;
159*11767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_action.nwdad_action = action;
160*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_object_action.nwdad_name, name,
161*11767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_object_action.nwdad_name));
162*11767SAnurag.Maskey@Sun.COM 	if (parent != NULL) {
163*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_object_action.nwdad_parent,
164*11767SAnurag.Maskey@Sun.COM 		    parent,
165*11767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_object_action.nwdad_parent));
166*11767SAnurag.Maskey@Sun.COM 	} else {
167*11767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_object_action.nwdad_parent[0] = '\0';
168*11767SAnurag.Maskey@Sun.COM 	}
169*11767SAnurag.Maskey@Sun.COM 
170*11767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
171*11767SAnurag.Maskey@Sun.COM }
172*11767SAnurag.Maskey@Sun.COM 
173*11767SAnurag.Maskey@Sun.COM nwam_error_t
174*11767SAnurag.Maskey@Sun.COM nwam_request_state(nwam_object_type_t object_type, const char *name,
175*11767SAnurag.Maskey@Sun.COM     const char *parent, nwam_state_t *statep, nwam_aux_state_t *auxp)
176*11767SAnurag.Maskey@Sun.COM {
177*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
178*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
179*11767SAnurag.Maskey@Sun.COM 
180*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL && statep != NULL && auxp != NULL);
181*11767SAnurag.Maskey@Sun.COM 
182*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_STATE;
183*11767SAnurag.Maskey@Sun.COM 
184*11767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_object_state.nwdad_object_type = object_type;
185*11767SAnurag.Maskey@Sun.COM 
186*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_object_state.nwdad_name, name,
187*11767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_object_state.nwdad_name));
188*11767SAnurag.Maskey@Sun.COM 	if (parent != NULL) {
189*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_object_state.nwdad_parent,
190*11767SAnurag.Maskey@Sun.COM 		    parent,
191*11767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_object_state.nwdad_parent));
192*11767SAnurag.Maskey@Sun.COM 	}
193*11767SAnurag.Maskey@Sun.COM 
194*11767SAnurag.Maskey@Sun.COM 	err = send_msg_to_nwam(&req);
195*11767SAnurag.Maskey@Sun.COM 
196*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS) {
197*11767SAnurag.Maskey@Sun.COM 		*statep = req.nwda_data.nwdad_object_state.nwdad_state;
198*11767SAnurag.Maskey@Sun.COM 		*auxp = req.nwda_data.nwdad_object_state.nwdad_aux_state;
199*11767SAnurag.Maskey@Sun.COM 	}
200*11767SAnurag.Maskey@Sun.COM 
201*11767SAnurag.Maskey@Sun.COM 	return (err);
202*11767SAnurag.Maskey@Sun.COM }
203*11767SAnurag.Maskey@Sun.COM 
204*11767SAnurag.Maskey@Sun.COM nwam_error_t
205*11767SAnurag.Maskey@Sun.COM nwam_request_wlan(nwam_request_type_t type, const char *name,
206*11767SAnurag.Maskey@Sun.COM     const char *essid, const char *bssid, uint32_t security_mode,
207*11767SAnurag.Maskey@Sun.COM     uint_t keyslot, const char *key, boolean_t add_to_known_wlans)
208*11767SAnurag.Maskey@Sun.COM {
209*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
210*11767SAnurag.Maskey@Sun.COM 
211*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL);
212*11767SAnurag.Maskey@Sun.COM 
213*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = type;
214*11767SAnurag.Maskey@Sun.COM 
215*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_name, name,
216*11767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_wlan_info));
217*11767SAnurag.Maskey@Sun.COM 	if (essid != NULL) {
218*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_essid, essid,
219*11767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_essid));
220*11767SAnurag.Maskey@Sun.COM 	} else {
221*11767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_essid[0] = '\0';
222*11767SAnurag.Maskey@Sun.COM 	}
223*11767SAnurag.Maskey@Sun.COM 	if (bssid != NULL) {
224*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_bssid, bssid,
225*11767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_bssid));
226*11767SAnurag.Maskey@Sun.COM 	} else {
227*11767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_bssid[0] = '\0';
228*11767SAnurag.Maskey@Sun.COM 	}
229*11767SAnurag.Maskey@Sun.COM 	if (key != NULL) {
230*11767SAnurag.Maskey@Sun.COM 		(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_key, key,
231*11767SAnurag.Maskey@Sun.COM 		    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_key));
232*11767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_keyslot = keyslot;
233*11767SAnurag.Maskey@Sun.COM 	} else {
234*11767SAnurag.Maskey@Sun.COM 		req.nwda_data.nwdad_wlan_info.nwdad_key[0] = '\0';
235*11767SAnurag.Maskey@Sun.COM 	}
236*11767SAnurag.Maskey@Sun.COM 
237*11767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_wlan_info.nwdad_security_mode = security_mode;
238*11767SAnurag.Maskey@Sun.COM 	req.nwda_data.nwdad_wlan_info.nwdad_add_to_known_wlans =
239*11767SAnurag.Maskey@Sun.COM 	    add_to_known_wlans;
240*11767SAnurag.Maskey@Sun.COM 
241*11767SAnurag.Maskey@Sun.COM 	return (send_msg_to_nwam(&req));
242*11767SAnurag.Maskey@Sun.COM }
243*11767SAnurag.Maskey@Sun.COM 
244*11767SAnurag.Maskey@Sun.COM nwam_error_t
245*11767SAnurag.Maskey@Sun.COM nwam_request_wlan_scan_results(const char *name, uint_t *num_wlansp,
246*11767SAnurag.Maskey@Sun.COM     nwam_wlan_t **wlansp)
247*11767SAnurag.Maskey@Sun.COM {
248*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
249*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
250*11767SAnurag.Maskey@Sun.COM 
251*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL && num_wlansp != NULL && wlansp != NULL);
252*11767SAnurag.Maskey@Sun.COM 
253*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS;
254*11767SAnurag.Maskey@Sun.COM 
255*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(req.nwda_data.nwdad_wlan_info.nwdad_name, name,
256*11767SAnurag.Maskey@Sun.COM 	    sizeof (req.nwda_data.nwdad_wlan_info.nwdad_name));
257*11767SAnurag.Maskey@Sun.COM 
258*11767SAnurag.Maskey@Sun.COM 	if ((err = send_msg_to_nwam(&req)) != NWAM_SUCCESS)
259*11767SAnurag.Maskey@Sun.COM 		return (err);
260*11767SAnurag.Maskey@Sun.COM 
261*11767SAnurag.Maskey@Sun.COM 	*num_wlansp = req.nwda_data.nwdad_wlan_info.nwdad_num_wlans;
262*11767SAnurag.Maskey@Sun.COM 
263*11767SAnurag.Maskey@Sun.COM 	*wlansp = calloc(*num_wlansp, sizeof (nwam_wlan_t));
264*11767SAnurag.Maskey@Sun.COM 	if (*wlansp == NULL)
265*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
266*11767SAnurag.Maskey@Sun.COM 
267*11767SAnurag.Maskey@Sun.COM 	(void) memcpy(*wlansp, req.nwda_data.nwdad_wlan_info.nwdad_wlans,
268*11767SAnurag.Maskey@Sun.COM 	    *num_wlansp * sizeof (nwam_wlan_t));
269*11767SAnurag.Maskey@Sun.COM 
270*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
271*11767SAnurag.Maskey@Sun.COM }
272*11767SAnurag.Maskey@Sun.COM 
273*11767SAnurag.Maskey@Sun.COM nwam_error_t
274*11767SAnurag.Maskey@Sun.COM nwam_request_active_priority_group(int64_t *priorityp)
275*11767SAnurag.Maskey@Sun.COM {
276*11767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t req;
277*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
278*11767SAnurag.Maskey@Sun.COM 
279*11767SAnurag.Maskey@Sun.COM 	assert(priorityp != NULL);
280*11767SAnurag.Maskey@Sun.COM 
281*11767SAnurag.Maskey@Sun.COM 	req.nwda_type = NWAM_REQUEST_TYPE_PRIORITY_GROUP;
282*11767SAnurag.Maskey@Sun.COM 	err = send_msg_to_nwam(&req);
283*11767SAnurag.Maskey@Sun.COM 
284*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS)
285*11767SAnurag.Maskey@Sun.COM 		*priorityp =
286*11767SAnurag.Maskey@Sun.COM 		    req.nwda_data.nwdad_priority_group_info.nwdad_priority;
287*11767SAnurag.Maskey@Sun.COM 
288*11767SAnurag.Maskey@Sun.COM 	return (err);
289*11767SAnurag.Maskey@Sun.COM }
290*11767SAnurag.Maskey@Sun.COM 
291*11767SAnurag.Maskey@Sun.COM /* String conversion functions */
292*11767SAnurag.Maskey@Sun.COM 
293*11767SAnurag.Maskey@Sun.COM const char *
294*11767SAnurag.Maskey@Sun.COM nwam_value_type_to_string(nwam_value_type_t type)
295*11767SAnurag.Maskey@Sun.COM {
296*11767SAnurag.Maskey@Sun.COM 	switch (type) {
297*11767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_BOOLEAN:
298*11767SAnurag.Maskey@Sun.COM 		return ("boolean");
299*11767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_INT64:
300*11767SAnurag.Maskey@Sun.COM 		return ("int64");
301*11767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_UINT64:
302*11767SAnurag.Maskey@Sun.COM 		return ("uint64");
303*11767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_STRING:
304*11767SAnurag.Maskey@Sun.COM 		return ("string");
305*11767SAnurag.Maskey@Sun.COM 	default:
306*11767SAnurag.Maskey@Sun.COM 		return ("unknown");
307*11767SAnurag.Maskey@Sun.COM 	}
308*11767SAnurag.Maskey@Sun.COM }
309*11767SAnurag.Maskey@Sun.COM 
310*11767SAnurag.Maskey@Sun.COM nwam_value_type_t
311*11767SAnurag.Maskey@Sun.COM nwam_string_to_value_type(const char *typestr)
312*11767SAnurag.Maskey@Sun.COM {
313*11767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_BOOLEAN),
314*11767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
315*11767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_BOOLEAN);
316*11767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_INT64),
317*11767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
318*11767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_INT64);
319*11767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_UINT64),
320*11767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
321*11767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_UINT64);
322*11767SAnurag.Maskey@Sun.COM 	if (strncmp(typestr, nwam_value_type_to_string(NWAM_VALUE_TYPE_STRING),
323*11767SAnurag.Maskey@Sun.COM 	    strlen(typestr)) == 0)
324*11767SAnurag.Maskey@Sun.COM 		return (NWAM_VALUE_TYPE_STRING);
325*11767SAnurag.Maskey@Sun.COM 	return (NWAM_VALUE_TYPE_UNKNOWN);
326*11767SAnurag.Maskey@Sun.COM }
327*11767SAnurag.Maskey@Sun.COM 
328*11767SAnurag.Maskey@Sun.COM const char *
329*11767SAnurag.Maskey@Sun.COM nwam_action_to_string(nwam_action_t action)
330*11767SAnurag.Maskey@Sun.COM {
331*11767SAnurag.Maskey@Sun.COM 	switch (action) {
332*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ADD:
333*11767SAnurag.Maskey@Sun.COM 		return ("add");
334*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REMOVE:
335*11767SAnurag.Maskey@Sun.COM 		return ("remove");
336*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REFRESH:
337*11767SAnurag.Maskey@Sun.COM 		return ("refresh");
338*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ENABLE:
339*11767SAnurag.Maskey@Sun.COM 		return ("enable");
340*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DISABLE:
341*11767SAnurag.Maskey@Sun.COM 		return ("disable");
342*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DESTROY:
343*11767SAnurag.Maskey@Sun.COM 		return ("destroy");
344*11767SAnurag.Maskey@Sun.COM 	default:
345*11767SAnurag.Maskey@Sun.COM 		return ("unknown");
346*11767SAnurag.Maskey@Sun.COM 	}
347*11767SAnurag.Maskey@Sun.COM }
348*11767SAnurag.Maskey@Sun.COM 
349*11767SAnurag.Maskey@Sun.COM const char *
350*11767SAnurag.Maskey@Sun.COM nwam_event_type_to_string(int event_type)
351*11767SAnurag.Maskey@Sun.COM {
352*11767SAnurag.Maskey@Sun.COM 	switch (event_type) {
353*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_NOOP:
354*11767SAnurag.Maskey@Sun.COM 		return ("NOOP");
355*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INIT:
356*11767SAnurag.Maskey@Sun.COM 		return ("INIT");
357*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_SHUTDOWN:
358*11767SAnurag.Maskey@Sun.COM 		return ("SHUTDOWN");
359*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_ACTION:
360*11767SAnurag.Maskey@Sun.COM 		return ("OBJECT_ACTION");
361*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_OBJECT_STATE:
362*11767SAnurag.Maskey@Sun.COM 		return ("OBJECT_STATE");
363*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_PRIORITY_GROUP:
364*11767SAnurag.Maskey@Sun.COM 		return ("PRIORITY_GROUP");
365*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_INFO:
366*11767SAnurag.Maskey@Sun.COM 		return ("INFO");
367*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT:
368*11767SAnurag.Maskey@Sun.COM 		return ("WLAN_SCAN_REPORT");
369*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE:
370*11767SAnurag.Maskey@Sun.COM 		return ("WLAN_NEED_CHOICE");
371*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_NEED_KEY:
372*11767SAnurag.Maskey@Sun.COM 		return ("WLAN_NEED_KEY");
373*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT:
374*11767SAnurag.Maskey@Sun.COM 		return ("WLAN_CONNECTION_REPORT");
375*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_ACTION:
376*11767SAnurag.Maskey@Sun.COM 		return ("IF_ACTION");
377*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_IF_STATE:
378*11767SAnurag.Maskey@Sun.COM 		return ("IF_STATE");
379*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_ACTION:
380*11767SAnurag.Maskey@Sun.COM 		return ("LINK_ACTION");
381*11767SAnurag.Maskey@Sun.COM 	case NWAM_EVENT_TYPE_LINK_STATE:
382*11767SAnurag.Maskey@Sun.COM 		return ("LINK_STATE");
383*11767SAnurag.Maskey@Sun.COM 	default:
384*11767SAnurag.Maskey@Sun.COM 		return ("UNKNOWN");
385*11767SAnurag.Maskey@Sun.COM 	}
386*11767SAnurag.Maskey@Sun.COM }
387*11767SAnurag.Maskey@Sun.COM 
388*11767SAnurag.Maskey@Sun.COM const char *
389*11767SAnurag.Maskey@Sun.COM nwam_state_to_string(nwam_state_t state)
390*11767SAnurag.Maskey@Sun.COM {
391*11767SAnurag.Maskey@Sun.COM 	switch (state) {
392*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_UNINITIALIZED:
393*11767SAnurag.Maskey@Sun.COM 		return ("uninitialized");
394*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_INITIALIZED:
395*11767SAnurag.Maskey@Sun.COM 		return ("initialized");
396*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE:
397*11767SAnurag.Maskey@Sun.COM 		return ("offline");
398*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE_TO_ONLINE:
399*11767SAnurag.Maskey@Sun.COM 		return ("offline*");
400*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_ONLINE_TO_OFFLINE:
401*11767SAnurag.Maskey@Sun.COM 		return ("online*");
402*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_ONLINE:
403*11767SAnurag.Maskey@Sun.COM 		return ("online");
404*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_MAINTENANCE:
405*11767SAnurag.Maskey@Sun.COM 		return ("maintenance");
406*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DEGRADED:
407*11767SAnurag.Maskey@Sun.COM 		return ("degraded");
408*11767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DISABLED:
409*11767SAnurag.Maskey@Sun.COM 		return ("disabled");
410*11767SAnurag.Maskey@Sun.COM 	default:
411*11767SAnurag.Maskey@Sun.COM 		return ("unknown");
412*11767SAnurag.Maskey@Sun.COM 	}
413*11767SAnurag.Maskey@Sun.COM }
414*11767SAnurag.Maskey@Sun.COM 
415*11767SAnurag.Maskey@Sun.COM const char *
416*11767SAnurag.Maskey@Sun.COM nwam_aux_state_to_string(nwam_aux_state_t aux_state)
417*11767SAnurag.Maskey@Sun.COM {
418*11767SAnurag.Maskey@Sun.COM 	switch (aux_state) {
419*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_UNINITIALIZED:
420*11767SAnurag.Maskey@Sun.COM 		return ("uninitialized");
421*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_INITIALIZED:
422*11767SAnurag.Maskey@Sun.COM 		return ("(re)initialized but not configured");
423*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_CONDITIONS_NOT_MET:
424*11767SAnurag.Maskey@Sun.COM 		return ("conditions for activation are unmet");
425*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_MANUAL_DISABLE:
426*11767SAnurag.Maskey@Sun.COM 		return ("disabled by administrator");
427*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_FAILED:
428*11767SAnurag.Maskey@Sun.COM 		return ("method/service failed");
429*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_MISSING:
430*11767SAnurag.Maskey@Sun.COM 		return ("method or FMRI not specified");
431*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_INVALID_CONFIG:
432*11767SAnurag.Maskey@Sun.COM 		return ("invalid configuration values");
433*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_METHOD_RUNNING:
434*11767SAnurag.Maskey@Sun.COM 		return ("method/service executing");
435*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_ACTIVE:
436*11767SAnurag.Maskey@Sun.COM 		return ("active");
437*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_SCANNING:
438*11767SAnurag.Maskey@Sun.COM 		return ("scanning for WiFi networks");
439*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_NEED_SELECTION:
440*11767SAnurag.Maskey@Sun.COM 		return ("need WiFi network selection");
441*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_NEED_KEY:
442*11767SAnurag.Maskey@Sun.COM 		return ("need WiFi security key");
443*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_LINK_WIFI_CONNECTING:
444*11767SAnurag.Maskey@Sun.COM 		return ("connecting to WiFi network");
445*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_WAITING_FOR_ADDR:
446*11767SAnurag.Maskey@Sun.COM 		return ("waiting for IP address to be set");
447*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_DHCP_TIMED_OUT:
448*11767SAnurag.Maskey@Sun.COM 		return ("DHCP wait timeout, still trying...");
449*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_IF_DUPLICATE_ADDR:
450*11767SAnurag.Maskey@Sun.COM 		return ("duplicate address detected");
451*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_UP:
452*11767SAnurag.Maskey@Sun.COM 		return ("interface/link is up");
453*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_DOWN:
454*11767SAnurag.Maskey@Sun.COM 		return ("interface/link is down");
455*11767SAnurag.Maskey@Sun.COM 	case NWAM_AUX_STATE_NOT_FOUND:
456*11767SAnurag.Maskey@Sun.COM 		return ("interface/link not found");
457*11767SAnurag.Maskey@Sun.COM 	default:
458*11767SAnurag.Maskey@Sun.COM 		return ("unknown");
459*11767SAnurag.Maskey@Sun.COM 	}
460*11767SAnurag.Maskey@Sun.COM }
461*11767SAnurag.Maskey@Sun.COM 
462*11767SAnurag.Maskey@Sun.COM const char *
463*11767SAnurag.Maskey@Sun.COM nwam_object_type_to_string(nwam_object_type_t type)
464*11767SAnurag.Maskey@Sun.COM {
465*11767SAnurag.Maskey@Sun.COM 	switch (type) {
466*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
467*11767SAnurag.Maskey@Sun.COM 		return ("ncp");
468*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
469*11767SAnurag.Maskey@Sun.COM 		return ("ncu");
470*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
471*11767SAnurag.Maskey@Sun.COM 		return ("loc");
472*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
473*11767SAnurag.Maskey@Sun.COM 		return ("enm");
474*11767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
475*11767SAnurag.Maskey@Sun.COM 		return ("known wlan");
476*11767SAnurag.Maskey@Sun.COM 	default:
477*11767SAnurag.Maskey@Sun.COM 		return ("unknown");
478*11767SAnurag.Maskey@Sun.COM 	}
479*11767SAnurag.Maskey@Sun.COM }
480*11767SAnurag.Maskey@Sun.COM 
481*11767SAnurag.Maskey@Sun.COM nwam_object_type_t
482*11767SAnurag.Maskey@Sun.COM nwam_string_to_object_type(const char *typestr)
483*11767SAnurag.Maskey@Sun.COM {
484*11767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
485*11767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCP)) == 0)
486*11767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCP);
487*11767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
488*11767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCU)) == 0)
489*11767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCU);
490*11767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
491*11767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_LOC)) == 0)
492*11767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_LOC);
493*11767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
494*11767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_ENM)) == 0)
495*11767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_ENM);
496*11767SAnurag.Maskey@Sun.COM 	if (strcasecmp(typestr,
497*11767SAnurag.Maskey@Sun.COM 	    nwam_object_type_to_string(NWAM_OBJECT_TYPE_KNOWN_WLAN)) == 0)
498*11767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_KNOWN_WLAN);
499*11767SAnurag.Maskey@Sun.COM 	return (NWAM_OBJECT_TYPE_UNKNOWN);
500*11767SAnurag.Maskey@Sun.COM }
501*11767SAnurag.Maskey@Sun.COM 
502*11767SAnurag.Maskey@Sun.COM nwam_error_t
503*11767SAnurag.Maskey@Sun.COM nwam_errno_to_nwam_error(int errnum)
504*11767SAnurag.Maskey@Sun.COM {
505*11767SAnurag.Maskey@Sun.COM 	switch (errnum) {
506*11767SAnurag.Maskey@Sun.COM 	case 0:
507*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
508*11767SAnurag.Maskey@Sun.COM 	case EBADF:
509*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_BIND);
510*11767SAnurag.Maskey@Sun.COM 	case EPERM:
511*11767SAnurag.Maskey@Sun.COM 	case EACCES:
512*11767SAnurag.Maskey@Sun.COM 		return (NWAM_PERMISSION_DENIED);
513*11767SAnurag.Maskey@Sun.COM 	case ENOENT:
514*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_FOUND);
515*11767SAnurag.Maskey@Sun.COM 	case EIDRM:
516*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
517*11767SAnurag.Maskey@Sun.COM 	case EEXIST:
518*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
519*11767SAnurag.Maskey@Sun.COM 	case EAGAIN:
520*11767SAnurag.Maskey@Sun.COM 	case EBUSY:
521*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
522*11767SAnurag.Maskey@Sun.COM 	case ENOMEM:
523*11767SAnurag.Maskey@Sun.COM 	case ENOSPC:
524*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
525*11767SAnurag.Maskey@Sun.COM 	case EINVAL:
526*11767SAnurag.Maskey@Sun.COM 	case E2BIG:
527*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
528*11767SAnurag.Maskey@Sun.COM 	default:
529*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
530*11767SAnurag.Maskey@Sun.COM 	}
531*11767SAnurag.Maskey@Sun.COM }
532*11767SAnurag.Maskey@Sun.COM 
533*11767SAnurag.Maskey@Sun.COM /* Common validation functions */
534*11767SAnurag.Maskey@Sun.COM 
535*11767SAnurag.Maskey@Sun.COM /*
536*11767SAnurag.Maskey@Sun.COM  * Do the flags represent a subset of valid_flags?
537*11767SAnurag.Maskey@Sun.COM  */
538*11767SAnurag.Maskey@Sun.COM nwam_error_t
539*11767SAnurag.Maskey@Sun.COM nwam_valid_flags(uint64_t flags, uint64_t valid_flags)
540*11767SAnurag.Maskey@Sun.COM {
541*11767SAnurag.Maskey@Sun.COM 
542*11767SAnurag.Maskey@Sun.COM 	if ((flags | valid_flags) != valid_flags)
543*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
544*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
545*11767SAnurag.Maskey@Sun.COM }
546*11767SAnurag.Maskey@Sun.COM 
547*11767SAnurag.Maskey@Sun.COM nwam_error_t
548*11767SAnurag.Maskey@Sun.COM nwam_valid_condition(nwam_value_t value)
549*11767SAnurag.Maskey@Sun.COM {
550*11767SAnurag.Maskey@Sun.COM 	char **conditions;
551*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
552*11767SAnurag.Maskey@Sun.COM 	nwam_condition_object_type_t object_type;
553*11767SAnurag.Maskey@Sun.COM 	nwam_condition_t condition;
554*11767SAnurag.Maskey@Sun.COM 
555*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &conditions, &numvalues)
556*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
557*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
558*11767SAnurag.Maskey@Sun.COM 
559*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
560*11767SAnurag.Maskey@Sun.COM 		char *object_name = NULL;
561*11767SAnurag.Maskey@Sun.COM 
562*11767SAnurag.Maskey@Sun.COM 		if (nwam_condition_string_to_condition(conditions[i],
563*11767SAnurag.Maskey@Sun.COM 		    &object_type, &condition, &object_name) != NWAM_SUCCESS)
564*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
565*11767SAnurag.Maskey@Sun.COM 		if (object_name != NULL)
566*11767SAnurag.Maskey@Sun.COM 			free(object_name);
567*11767SAnurag.Maskey@Sun.COM 	}
568*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
569*11767SAnurag.Maskey@Sun.COM }
570*11767SAnurag.Maskey@Sun.COM 
571*11767SAnurag.Maskey@Sun.COM /* check if boolean values are correct, generalize for array of booleans */
572*11767SAnurag.Maskey@Sun.COM nwam_error_t
573*11767SAnurag.Maskey@Sun.COM nwam_valid_boolean(nwam_value_t value)
574*11767SAnurag.Maskey@Sun.COM {
575*11767SAnurag.Maskey@Sun.COM 	boolean_t *val;
576*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
577*11767SAnurag.Maskey@Sun.COM 
578*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_boolean_array(value, &val, &numvalues)
579*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
580*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
581*11767SAnurag.Maskey@Sun.COM 
582*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
583*11767SAnurag.Maskey@Sun.COM 		if (val[i] != B_TRUE && val[i] != B_FALSE)
584*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
585*11767SAnurag.Maskey@Sun.COM 	}
586*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
587*11767SAnurag.Maskey@Sun.COM }
588*11767SAnurag.Maskey@Sun.COM 
589*11767SAnurag.Maskey@Sun.COM /* check if uint64 values are correct, generalize for array of ints */
590*11767SAnurag.Maskey@Sun.COM nwam_error_t
591*11767SAnurag.Maskey@Sun.COM nwam_valid_uint64(nwam_value_t value)
592*11767SAnurag.Maskey@Sun.COM {
593*11767SAnurag.Maskey@Sun.COM 	int64_t *val;
594*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
595*11767SAnurag.Maskey@Sun.COM 
596*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_int64_array(value, &val, &numvalues)
597*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
598*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
599*11767SAnurag.Maskey@Sun.COM 
600*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
601*11767SAnurag.Maskey@Sun.COM 		if (val[i] < 0)
602*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
603*11767SAnurag.Maskey@Sun.COM 	}
604*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
605*11767SAnurag.Maskey@Sun.COM }
606*11767SAnurag.Maskey@Sun.COM 
607*11767SAnurag.Maskey@Sun.COM /* check if domain names are correct, generalize for array of domains */
608*11767SAnurag.Maskey@Sun.COM nwam_error_t
609*11767SAnurag.Maskey@Sun.COM nwam_valid_domain(nwam_value_t value)
610*11767SAnurag.Maskey@Sun.COM {
611*11767SAnurag.Maskey@Sun.COM 	char **domainvalues, *domain;
612*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
613*11767SAnurag.Maskey@Sun.COM 	int len, j;
614*11767SAnurag.Maskey@Sun.COM 
615*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &domainvalues, &numvalues)
616*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
617*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
618*11767SAnurag.Maskey@Sun.COM 
619*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
620*11767SAnurag.Maskey@Sun.COM 		/*
621*11767SAnurag.Maskey@Sun.COM 		 * First and last character must be alphanumeric.
622*11767SAnurag.Maskey@Sun.COM 		 * Only '.' and '-' are allowed.
623*11767SAnurag.Maskey@Sun.COM 		 */
624*11767SAnurag.Maskey@Sun.COM 		domain = domainvalues[i];
625*11767SAnurag.Maskey@Sun.COM 		len = strlen(domain);
626*11767SAnurag.Maskey@Sun.COM 		if (!isalnum(domain[0]) || !isalnum(domain[len-1]))
627*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
628*11767SAnurag.Maskey@Sun.COM 		for (j = 0; j < len; j++) {
629*11767SAnurag.Maskey@Sun.COM 			if (!isalnum(domain[j]) &&
630*11767SAnurag.Maskey@Sun.COM 			    domain[j] != '.' && domain[j] != '-')
631*11767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_INVALID_VALUE);
632*11767SAnurag.Maskey@Sun.COM 		}
633*11767SAnurag.Maskey@Sun.COM 	}
634*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
635*11767SAnurag.Maskey@Sun.COM }
636*11767SAnurag.Maskey@Sun.COM 
637*11767SAnurag.Maskey@Sun.COM /* check if address prefix is valid */
638*11767SAnurag.Maskey@Sun.COM static nwam_error_t
639*11767SAnurag.Maskey@Sun.COM nwam_valid_prefix(char *addr, int max_plen)
640*11767SAnurag.Maskey@Sun.COM {
641*11767SAnurag.Maskey@Sun.COM 	char *prefix, *end;
642*11767SAnurag.Maskey@Sun.COM 	int prefixlen;
643*11767SAnurag.Maskey@Sun.COM 
644*11767SAnurag.Maskey@Sun.COM 	if ((prefix = strchr(addr, '/')) != NULL) {
645*11767SAnurag.Maskey@Sun.COM 		prefix++;
646*11767SAnurag.Maskey@Sun.COM 		prefixlen = strtol(prefix, &end, 10);
647*11767SAnurag.Maskey@Sun.COM 		if (prefix == end || prefixlen < 0 || prefixlen > max_plen)
648*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
649*11767SAnurag.Maskey@Sun.COM 	}
650*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
651*11767SAnurag.Maskey@Sun.COM }
652*11767SAnurag.Maskey@Sun.COM 
653*11767SAnurag.Maskey@Sun.COM /* check if IPv4 addresses are correct, generalize for array of addresses */
654*11767SAnurag.Maskey@Sun.COM nwam_error_t
655*11767SAnurag.Maskey@Sun.COM nwam_valid_host_v4(nwam_value_t value)
656*11767SAnurag.Maskey@Sun.COM {
657*11767SAnurag.Maskey@Sun.COM 	char **addrvalues, *addr;
658*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
659*11767SAnurag.Maskey@Sun.COM 	struct sockaddr_in sa;
660*11767SAnurag.Maskey@Sun.COM 
661*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &addrvalues, &numvalues)
662*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
663*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
664*11767SAnurag.Maskey@Sun.COM 
665*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
666*11767SAnurag.Maskey@Sun.COM 		addr = strdup(addrvalues[i]);
667*11767SAnurag.Maskey@Sun.COM 		if (nwam_valid_prefix(addr, IP_ABITS) != NWAM_SUCCESS) {
668*11767SAnurag.Maskey@Sun.COM 			free(addr);
669*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
670*11767SAnurag.Maskey@Sun.COM 		}
671*11767SAnurag.Maskey@Sun.COM 		/* replace '/' with '\0' */
672*11767SAnurag.Maskey@Sun.COM 		addr = strsep(&addr, "/");
673*11767SAnurag.Maskey@Sun.COM 		if (inet_pton(AF_INET, addr, &(sa.sin_addr)) != 1) {
674*11767SAnurag.Maskey@Sun.COM 			free(addr);
675*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
676*11767SAnurag.Maskey@Sun.COM 		}
677*11767SAnurag.Maskey@Sun.COM 		free(addr);
678*11767SAnurag.Maskey@Sun.COM 	}
679*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
680*11767SAnurag.Maskey@Sun.COM }
681*11767SAnurag.Maskey@Sun.COM 
682*11767SAnurag.Maskey@Sun.COM /* Check if IPv4 address for default route is valid */
683*11767SAnurag.Maskey@Sun.COM nwam_error_t
684*11767SAnurag.Maskey@Sun.COM nwam_valid_route_v4(nwam_value_t value)
685*11767SAnurag.Maskey@Sun.COM {
686*11767SAnurag.Maskey@Sun.COM 	char *addrvalue;
687*11767SAnurag.Maskey@Sun.COM 	struct sockaddr_in sa;
688*11767SAnurag.Maskey@Sun.COM 
689*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string(value, &addrvalue) != NWAM_SUCCESS)
690*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
691*11767SAnurag.Maskey@Sun.COM 
692*11767SAnurag.Maskey@Sun.COM 	if (inet_pton(AF_INET, addrvalue, &(sa.sin_addr)) != 1)
693*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
694*11767SAnurag.Maskey@Sun.COM 
695*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
696*11767SAnurag.Maskey@Sun.COM }
697*11767SAnurag.Maskey@Sun.COM 
698*11767SAnurag.Maskey@Sun.COM /* check if IPv6 addresses are correct, generalize for array of addresses */
699*11767SAnurag.Maskey@Sun.COM nwam_error_t
700*11767SAnurag.Maskey@Sun.COM nwam_valid_host_v6(nwam_value_t value)
701*11767SAnurag.Maskey@Sun.COM {
702*11767SAnurag.Maskey@Sun.COM 	char **addrvalues, *addr;
703*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
704*11767SAnurag.Maskey@Sun.COM 	struct sockaddr_in6 sa;
705*11767SAnurag.Maskey@Sun.COM 
706*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &addrvalues, &numvalues)
707*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
708*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
709*11767SAnurag.Maskey@Sun.COM 
710*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
711*11767SAnurag.Maskey@Sun.COM 		addr = strdup(addrvalues[i]);
712*11767SAnurag.Maskey@Sun.COM 		if (nwam_valid_prefix(addr, IPV6_ABITS) != NWAM_SUCCESS) {
713*11767SAnurag.Maskey@Sun.COM 			free(addr);
714*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
715*11767SAnurag.Maskey@Sun.COM 		}
716*11767SAnurag.Maskey@Sun.COM 		/* replace '/' with '\0' */
717*11767SAnurag.Maskey@Sun.COM 		addr = strsep(&addr, "/");
718*11767SAnurag.Maskey@Sun.COM 		if (inet_pton(AF_INET6, addr, &(sa.sin6_addr)) != 1) {
719*11767SAnurag.Maskey@Sun.COM 			free(addr);
720*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
721*11767SAnurag.Maskey@Sun.COM 		}
722*11767SAnurag.Maskey@Sun.COM 		free(addr);
723*11767SAnurag.Maskey@Sun.COM 	}
724*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
725*11767SAnurag.Maskey@Sun.COM }
726*11767SAnurag.Maskey@Sun.COM 
727*11767SAnurag.Maskey@Sun.COM /* Check if IPv4 address for default route is valid */
728*11767SAnurag.Maskey@Sun.COM nwam_error_t
729*11767SAnurag.Maskey@Sun.COM nwam_valid_route_v6(nwam_value_t value)
730*11767SAnurag.Maskey@Sun.COM {
731*11767SAnurag.Maskey@Sun.COM 	char *addrvalue;
732*11767SAnurag.Maskey@Sun.COM 	struct sockaddr_in6 sa;
733*11767SAnurag.Maskey@Sun.COM 
734*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string(value, &addrvalue) != NWAM_SUCCESS)
735*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
736*11767SAnurag.Maskey@Sun.COM 
737*11767SAnurag.Maskey@Sun.COM 	if (inet_pton(AF_INET6, addrvalue, &(sa.sin6_addr)) != 1)
738*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
739*11767SAnurag.Maskey@Sun.COM 
740*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
741*11767SAnurag.Maskey@Sun.COM }
742*11767SAnurag.Maskey@Sun.COM 
743*11767SAnurag.Maskey@Sun.COM nwam_error_t
744*11767SAnurag.Maskey@Sun.COM nwam_valid_host_any(nwam_value_t value)
745*11767SAnurag.Maskey@Sun.COM {
746*11767SAnurag.Maskey@Sun.COM 	if (nwam_valid_host_v4(value) != NWAM_SUCCESS &&
747*11767SAnurag.Maskey@Sun.COM 	    nwam_valid_host_v6(value) != NWAM_SUCCESS)
748*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
749*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
750*11767SAnurag.Maskey@Sun.COM }
751*11767SAnurag.Maskey@Sun.COM 
752*11767SAnurag.Maskey@Sun.COM nwam_error_t
753*11767SAnurag.Maskey@Sun.COM nwam_valid_host_or_domain(nwam_value_t value)
754*11767SAnurag.Maskey@Sun.COM {
755*11767SAnurag.Maskey@Sun.COM 	if (nwam_valid_host_any(value) != NWAM_SUCCESS &&
756*11767SAnurag.Maskey@Sun.COM 	    nwam_valid_domain(value) != NWAM_SUCCESS)
757*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
758*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
759*11767SAnurag.Maskey@Sun.COM }
760*11767SAnurag.Maskey@Sun.COM 
761*11767SAnurag.Maskey@Sun.COM /* We do not validate file existence, merely that it is an absolute path. */
762*11767SAnurag.Maskey@Sun.COM nwam_error_t
763*11767SAnurag.Maskey@Sun.COM nwam_valid_file(nwam_value_t value)
764*11767SAnurag.Maskey@Sun.COM {
765*11767SAnurag.Maskey@Sun.COM 	char **files;
766*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
767*11767SAnurag.Maskey@Sun.COM 
768*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &files, &numvalues)
769*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
770*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
771*11767SAnurag.Maskey@Sun.COM 
772*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
773*11767SAnurag.Maskey@Sun.COM 		int j = 0;
774*11767SAnurag.Maskey@Sun.COM 		while (isspace(files[i][j]))
775*11767SAnurag.Maskey@Sun.COM 			j++;
776*11767SAnurag.Maskey@Sun.COM 		if (files[i][j] != '/')
777*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
778*11767SAnurag.Maskey@Sun.COM 	}
779*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
780*11767SAnurag.Maskey@Sun.COM }
781*11767SAnurag.Maskey@Sun.COM 
782*11767SAnurag.Maskey@Sun.COM /*
783*11767SAnurag.Maskey@Sun.COM  * We do not validate existence of the object pointed to by the FMRI
784*11767SAnurag.Maskey@Sun.COM  * but merely ensure that it is a valid FMRI.  We do this by
785*11767SAnurag.Maskey@Sun.COM  * using scf_handle_decode_fmri(), but ignore all errors bar
786*11767SAnurag.Maskey@Sun.COM  * SCF_ERROR_INVALID_ARGUMENT (which indicates the FMRI is invalid).
787*11767SAnurag.Maskey@Sun.COM  */
788*11767SAnurag.Maskey@Sun.COM nwam_error_t
789*11767SAnurag.Maskey@Sun.COM nwam_valid_fmri(nwam_value_t value)
790*11767SAnurag.Maskey@Sun.COM {
791*11767SAnurag.Maskey@Sun.COM 	char **valstr;
792*11767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
793*11767SAnurag.Maskey@Sun.COM 	scf_service_t *svc = NULL;
794*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
795*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
796*11767SAnurag.Maskey@Sun.COM 
797*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_get_string_array(value, &valstr, &numvalues))
798*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
799*11767SAnurag.Maskey@Sun.COM 		return (err);
800*11767SAnurag.Maskey@Sun.COM 
801*11767SAnurag.Maskey@Sun.COM 	h = scf_handle_create(SCF_VERSION);
802*11767SAnurag.Maskey@Sun.COM 	if (h == NULL)
803*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ERROR_INTERNAL);
804*11767SAnurag.Maskey@Sun.COM 
805*11767SAnurag.Maskey@Sun.COM 	if (scf_handle_bind(h) != 0) {
806*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
807*11767SAnurag.Maskey@Sun.COM 		goto out;
808*11767SAnurag.Maskey@Sun.COM 	}
809*11767SAnurag.Maskey@Sun.COM 
810*11767SAnurag.Maskey@Sun.COM 	if ((svc = scf_service_create(h)) == NULL) {
811*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
812*11767SAnurag.Maskey@Sun.COM 		goto out;
813*11767SAnurag.Maskey@Sun.COM 	}
814*11767SAnurag.Maskey@Sun.COM 
815*11767SAnurag.Maskey@Sun.COM 
816*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
817*11767SAnurag.Maskey@Sun.COM 		if (scf_handle_decode_fmri(h, valstr[i], NULL, svc,
818*11767SAnurag.Maskey@Sun.COM 		    NULL, NULL, NULL, SCF_DECODE_FMRI_TRUNCATE) == 0 ||
819*11767SAnurag.Maskey@Sun.COM 		    scf_error() != SCF_ERROR_INVALID_ARGUMENT) {
820*11767SAnurag.Maskey@Sun.COM 			err = NWAM_SUCCESS;
821*11767SAnurag.Maskey@Sun.COM 			continue;
822*11767SAnurag.Maskey@Sun.COM 		}
823*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_INVALID_VALUE;
824*11767SAnurag.Maskey@Sun.COM 		break;
825*11767SAnurag.Maskey@Sun.COM 	}
826*11767SAnurag.Maskey@Sun.COM out:
827*11767SAnurag.Maskey@Sun.COM 	scf_service_destroy(svc);
828*11767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
829*11767SAnurag.Maskey@Sun.COM 	return (err);
830*11767SAnurag.Maskey@Sun.COM }
831*11767SAnurag.Maskey@Sun.COM 
832*11767SAnurag.Maskey@Sun.COM /* verifies mac-address and bssids */
833*11767SAnurag.Maskey@Sun.COM nwam_error_t
834*11767SAnurag.Maskey@Sun.COM nwam_valid_mac_addr(nwam_value_t value)
835*11767SAnurag.Maskey@Sun.COM {
836*11767SAnurag.Maskey@Sun.COM 	char **mac_addrs, *addr;
837*11767SAnurag.Maskey@Sun.COM 	uchar_t	*hwaddr;
838*11767SAnurag.Maskey@Sun.COM 	int hwaddrlen, j;
839*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
840*11767SAnurag.Maskey@Sun.COM 
841*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string_array(value, &mac_addrs, &numvalues)
842*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
843*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
844*11767SAnurag.Maskey@Sun.COM 
845*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
846*11767SAnurag.Maskey@Sun.COM 		addr = mac_addrs[i];
847*11767SAnurag.Maskey@Sun.COM 		j = 0;
848*11767SAnurag.Maskey@Sun.COM 
849*11767SAnurag.Maskey@Sun.COM 		/* validate that a-fA-F0-9 and ':' only */
850*11767SAnurag.Maskey@Sun.COM 		while (addr[j] != 0) {
851*11767SAnurag.Maskey@Sun.COM 			if (!isxdigit(addr[j]) && addr[j] != ':')
852*11767SAnurag.Maskey@Sun.COM 				return (NWAM_ENTITY_INVALID_VALUE);
853*11767SAnurag.Maskey@Sun.COM 			j++;
854*11767SAnurag.Maskey@Sun.COM 		}
855*11767SAnurag.Maskey@Sun.COM 
856*11767SAnurag.Maskey@Sun.COM 		if ((hwaddr = _link_aton(addr, &hwaddrlen)) == NULL)
857*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
858*11767SAnurag.Maskey@Sun.COM 		free(hwaddr);
859*11767SAnurag.Maskey@Sun.COM 	}
860*11767SAnurag.Maskey@Sun.COM 
861*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
862*11767SAnurag.Maskey@Sun.COM }
863*11767SAnurag.Maskey@Sun.COM 
864*11767SAnurag.Maskey@Sun.COM boolean_t
865*11767SAnurag.Maskey@Sun.COM nwam_uid_is_netadm(void)
866*11767SAnurag.Maskey@Sun.COM {
867*11767SAnurag.Maskey@Sun.COM 	return (getuid() == UID_NETADM);
868*11767SAnurag.Maskey@Sun.COM }
869*11767SAnurag.Maskey@Sun.COM 
870*11767SAnurag.Maskey@Sun.COM nwam_error_t
871*11767SAnurag.Maskey@Sun.COM nwam_get_smf_string_property(const char *fmri, const char *pgname,
872*11767SAnurag.Maskey@Sun.COM     const char *propname, char **valuep)
873*11767SAnurag.Maskey@Sun.COM {
874*11767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
875*11767SAnurag.Maskey@Sun.COM 	scf_snapshot_t *snap = NULL;
876*11767SAnurag.Maskey@Sun.COM 	scf_instance_t *inst = NULL;
877*11767SAnurag.Maskey@Sun.COM 	scf_propertygroup_t *pg = NULL;
878*11767SAnurag.Maskey@Sun.COM 	scf_property_t *prop = NULL;
879*11767SAnurag.Maskey@Sun.COM 	scf_value_t *val = NULL;
880*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
881*11767SAnurag.Maskey@Sun.COM 
882*11767SAnurag.Maskey@Sun.COM 	if ((*valuep = malloc(NWAM_MAX_NAME_LEN)) == NULL)
883*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
884*11767SAnurag.Maskey@Sun.COM 
885*11767SAnurag.Maskey@Sun.COM 	if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
886*11767SAnurag.Maskey@Sun.COM 	    scf_handle_bind(h) != 0 ||
887*11767SAnurag.Maskey@Sun.COM 	    (inst = scf_instance_create(h)) == NULL ||
888*11767SAnurag.Maskey@Sun.COM 	    (snap = scf_snapshot_create(h)) == NULL ||
889*11767SAnurag.Maskey@Sun.COM 	    (pg = scf_pg_create(h)) == NULL ||
890*11767SAnurag.Maskey@Sun.COM 	    (prop = scf_property_create(h)) == NULL ||
891*11767SAnurag.Maskey@Sun.COM 	    (val = scf_value_create(h)) == NULL) {
892*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
893*11767SAnurag.Maskey@Sun.COM 		goto out;
894*11767SAnurag.Maskey@Sun.COM 	}
895*11767SAnurag.Maskey@Sun.COM 	if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst,
896*11767SAnurag.Maskey@Sun.COM 	    NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
897*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
898*11767SAnurag.Maskey@Sun.COM 		goto out;
899*11767SAnurag.Maskey@Sun.COM 	}
900*11767SAnurag.Maskey@Sun.COM 	/* Retrieve value from running snapshot (if present) */
901*11767SAnurag.Maskey@Sun.COM 	if (scf_instance_get_snapshot(inst, "running", snap) != 0) {
902*11767SAnurag.Maskey@Sun.COM 		scf_snapshot_destroy(snap);
903*11767SAnurag.Maskey@Sun.COM 		snap = NULL;
904*11767SAnurag.Maskey@Sun.COM 	}
905*11767SAnurag.Maskey@Sun.COM 	if (scf_instance_get_pg_composed(inst, snap, pgname, pg) != 0 ||
906*11767SAnurag.Maskey@Sun.COM 	    scf_pg_get_property(pg, propname, prop) != 0 ||
907*11767SAnurag.Maskey@Sun.COM 	    scf_property_get_value(prop, val) != 0 ||
908*11767SAnurag.Maskey@Sun.COM 	    scf_value_get_astring(val, *valuep, NWAM_MAX_NAME_LEN) == -1) {
909*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
910*11767SAnurag.Maskey@Sun.COM 	}
911*11767SAnurag.Maskey@Sun.COM out:
912*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
913*11767SAnurag.Maskey@Sun.COM 		free(*valuep);
914*11767SAnurag.Maskey@Sun.COM 
915*11767SAnurag.Maskey@Sun.COM 	scf_value_destroy(val);
916*11767SAnurag.Maskey@Sun.COM 	scf_property_destroy(prop);
917*11767SAnurag.Maskey@Sun.COM 	scf_pg_destroy(pg);
918*11767SAnurag.Maskey@Sun.COM 	if (snap != NULL)
919*11767SAnurag.Maskey@Sun.COM 		scf_snapshot_destroy(snap);
920*11767SAnurag.Maskey@Sun.COM 	scf_instance_destroy(inst);
921*11767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
922*11767SAnurag.Maskey@Sun.COM 
923*11767SAnurag.Maskey@Sun.COM 	return (err);
924*11767SAnurag.Maskey@Sun.COM }
925*11767SAnurag.Maskey@Sun.COM 
926*11767SAnurag.Maskey@Sun.COM nwam_error_t
927*11767SAnurag.Maskey@Sun.COM nwam_set_smf_string_property(const char *fmri, const char *pgname,
928*11767SAnurag.Maskey@Sun.COM     const char *propname, const char *propval)
929*11767SAnurag.Maskey@Sun.COM {
930*11767SAnurag.Maskey@Sun.COM 	scf_handle_t *h = NULL;
931*11767SAnurag.Maskey@Sun.COM 	scf_instance_t *inst = NULL;
932*11767SAnurag.Maskey@Sun.COM 	scf_propertygroup_t *pg = NULL;
933*11767SAnurag.Maskey@Sun.COM 	scf_property_t *prop = NULL;
934*11767SAnurag.Maskey@Sun.COM 	scf_value_t *val = NULL;
935*11767SAnurag.Maskey@Sun.COM 	scf_transaction_t *tx = NULL;
936*11767SAnurag.Maskey@Sun.COM 	scf_transaction_entry_t *ent = NULL;
937*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err = NWAM_SUCCESS;
938*11767SAnurag.Maskey@Sun.COM 	int result;
939*11767SAnurag.Maskey@Sun.COM 
940*11767SAnurag.Maskey@Sun.COM 	if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
941*11767SAnurag.Maskey@Sun.COM 	    scf_handle_bind(h) != 0 ||
942*11767SAnurag.Maskey@Sun.COM 	    (inst = scf_instance_create(h)) == NULL ||
943*11767SAnurag.Maskey@Sun.COM 	    (pg = scf_pg_create(h)) == NULL ||
944*11767SAnurag.Maskey@Sun.COM 	    (prop = scf_property_create(h)) == NULL ||
945*11767SAnurag.Maskey@Sun.COM 	    (val = scf_value_create(h)) == NULL ||
946*11767SAnurag.Maskey@Sun.COM 	    scf_value_set_astring(val, propval) != 0 ||
947*11767SAnurag.Maskey@Sun.COM 	    (tx = scf_transaction_create(h)) == NULL ||
948*11767SAnurag.Maskey@Sun.COM 	    (ent = scf_entry_create(h)) == NULL) {
949*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
950*11767SAnurag.Maskey@Sun.COM 		goto out;
951*11767SAnurag.Maskey@Sun.COM 	}
952*11767SAnurag.Maskey@Sun.COM 	if (scf_handle_decode_fmri(h, fmri, NULL, NULL, inst,
953*11767SAnurag.Maskey@Sun.COM 	    NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0 ||
954*11767SAnurag.Maskey@Sun.COM 	    scf_instance_get_pg_composed(inst, NULL, pgname, pg) != 0) {
955*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ENTITY_NOT_FOUND;
956*11767SAnurag.Maskey@Sun.COM 		goto out;
957*11767SAnurag.Maskey@Sun.COM 	}
958*11767SAnurag.Maskey@Sun.COM 
959*11767SAnurag.Maskey@Sun.COM retry:
960*11767SAnurag.Maskey@Sun.COM 	if (scf_transaction_start(tx, pg) == -1 ||
961*11767SAnurag.Maskey@Sun.COM 	    scf_transaction_property_change(tx, ent, propname, SCF_TYPE_ASTRING)
962*11767SAnurag.Maskey@Sun.COM 	    == -1 || scf_entry_add_value(ent, val) != 0) {
963*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
964*11767SAnurag.Maskey@Sun.COM 		goto out;
965*11767SAnurag.Maskey@Sun.COM 	}
966*11767SAnurag.Maskey@Sun.COM 
967*11767SAnurag.Maskey@Sun.COM 	result = scf_transaction_commit(tx);
968*11767SAnurag.Maskey@Sun.COM 	switch (result) {
969*11767SAnurag.Maskey@Sun.COM 	case 1:
970*11767SAnurag.Maskey@Sun.COM 		(void) smf_refresh_instance(fmri);
971*11767SAnurag.Maskey@Sun.COM 		break;
972*11767SAnurag.Maskey@Sun.COM 	case 0:
973*11767SAnurag.Maskey@Sun.COM 		scf_transaction_reset(tx);
974*11767SAnurag.Maskey@Sun.COM 		if (scf_pg_update(pg) == -1) {
975*11767SAnurag.Maskey@Sun.COM 			err = NWAM_ERROR_INTERNAL;
976*11767SAnurag.Maskey@Sun.COM 			goto out;
977*11767SAnurag.Maskey@Sun.COM 		}
978*11767SAnurag.Maskey@Sun.COM 		goto retry;
979*11767SAnurag.Maskey@Sun.COM 	default:
980*11767SAnurag.Maskey@Sun.COM 		err = NWAM_ERROR_INTERNAL;
981*11767SAnurag.Maskey@Sun.COM 		break;
982*11767SAnurag.Maskey@Sun.COM 	}
983*11767SAnurag.Maskey@Sun.COM out:
984*11767SAnurag.Maskey@Sun.COM 	scf_value_destroy(val);
985*11767SAnurag.Maskey@Sun.COM 	scf_property_destroy(prop);
986*11767SAnurag.Maskey@Sun.COM 	scf_pg_destroy(pg);
987*11767SAnurag.Maskey@Sun.COM 	scf_instance_destroy(inst);
988*11767SAnurag.Maskey@Sun.COM 	scf_handle_destroy(h);
989*11767SAnurag.Maskey@Sun.COM 
990*11767SAnurag.Maskey@Sun.COM 	return (err);
991*11767SAnurag.Maskey@Sun.COM }
992