1*6ba597c5SAnurag S. Maskey /*
2*6ba597c5SAnurag S. Maskey  * CDDL HEADER START
3*6ba597c5SAnurag S. Maskey  *
4*6ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
5*6ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
6*6ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
7*6ba597c5SAnurag S. Maskey  *
8*6ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
10*6ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
11*6ba597c5SAnurag S. Maskey  * and limitations under the License.
12*6ba597c5SAnurag S. Maskey  *
13*6ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
14*6ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
16*6ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
17*6ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6ba597c5SAnurag S. Maskey  *
19*6ba597c5SAnurag S. Maskey  * CDDL HEADER END
20*6ba597c5SAnurag S. Maskey  */
21*6ba597c5SAnurag S. Maskey 
22*6ba597c5SAnurag S. Maskey /*
23*6ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*6ba597c5SAnurag S. Maskey  * Use is subject to license terms.
25*6ba597c5SAnurag S. Maskey  */
26*6ba597c5SAnurag S. Maskey 
27*6ba597c5SAnurag S. Maskey #include <assert.h>
28*6ba597c5SAnurag S. Maskey #include <ctype.h>
29*6ba597c5SAnurag S. Maskey #include <sys/param.h>
30*6ba597c5SAnurag S. Maskey #include <sys/types.h>
31*6ba597c5SAnurag S. Maskey #include <sys/stat.h>
32*6ba597c5SAnurag S. Maskey #include <stdio.h>
33*6ba597c5SAnurag S. Maskey #include <stdlib.h>
34*6ba597c5SAnurag S. Maskey #include <strings.h>
35*6ba597c5SAnurag S. Maskey #include <unistd.h>
36*6ba597c5SAnurag S. Maskey #include <libdllink.h>
37*6ba597c5SAnurag S. Maskey #include <libdlwlan.h>
38*6ba597c5SAnurag S. Maskey 
39*6ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
40*6ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
41*6ba597c5SAnurag S. Maskey #include <libnwam.h>
42*6ba597c5SAnurag S. Maskey 
43*6ba597c5SAnurag S. Maskey /*
44*6ba597c5SAnurag S. Maskey  * Functions to support creating, modifying and destroying
45*6ba597c5SAnurag S. Maskey  * known WLAN objects. These represent the WiFi connection history,
46*6ba597c5SAnurag S. Maskey  * and are used by nwamd to identify and connect to known WLANs in
47*6ba597c5SAnurag S. Maskey  * scan results.
48*6ba597c5SAnurag S. Maskey  */
49*6ba597c5SAnurag S. Maskey 
50*6ba597c5SAnurag S. Maskey static nwam_error_t valid_keyname(nwam_value_t);
51*6ba597c5SAnurag S. Maskey static nwam_error_t valid_keyslot(nwam_value_t);
52*6ba597c5SAnurag S. Maskey static nwam_error_t valid_secmode(nwam_value_t);
53*6ba597c5SAnurag S. Maskey 
54*6ba597c5SAnurag S. Maskey struct nwam_prop_table_entry known_wlan_prop_table_entries[] = {
56*6ba597c5SAnurag S. Maskey 	    1, 1, nwam_valid_uint64,
57*6ba597c5SAnurag S. Maskey 	    "specifies priority of known WLAN - lower values are prioritized",
58*6ba597c5SAnurag S. Maskey 	    NWAM_TYPE_ANY, NWAM_CLASS_ANY},
60*6ba597c5SAnurag S. Maskey 	    0, NWAM_MAX_NUM_VALUES, nwam_valid_mac_addr,
61*6ba597c5SAnurag S. Maskey 	    "specifies BSSID(s) (of the form aa:bb:cc:dd:ee:ff) associated "
62*6ba597c5SAnurag S. Maskey 	    "with known WLAN",
63*6ba597c5SAnurag S. Maskey 	    NWAM_TYPE_ANY, NWAM_CLASS_ANY},
65*6ba597c5SAnurag S. Maskey 	    0, 1, valid_keyname,
66*6ba597c5SAnurag S. Maskey 	    "specifies security key name used with known WLAN",
67*6ba597c5SAnurag S. Maskey 	    NWAM_TYPE_ANY, NWAM_CLASS_ANY},
69*6ba597c5SAnurag S. Maskey 	    0, 1, valid_keyslot,
70*6ba597c5SAnurag S. Maskey 	    "specifies key slot [1-4] for security key used with known WLAN",
71*6ba597c5SAnurag S. Maskey 	    NWAM_TYPE_ANY, NWAM_CLASS_ANY},
73*6ba597c5SAnurag S. Maskey 	    0, 1, valid_secmode,
74*6ba597c5SAnurag S. Maskey 	    "specifies security mode used for known WLAN",
75*6ba597c5SAnurag S. Maskey 	    NWAM_TYPE_ANY, NWAM_CLASS_ANY}
76*6ba597c5SAnurag S. Maskey };
77*6ba597c5SAnurag S. Maskey 
78*6ba597c5SAnurag S. Maskey #define	NWAM_NUM_KNOWN_WLAN_PROPS	\
79*6ba597c5SAnurag S. Maskey 		(sizeof (known_wlan_prop_table_entries) / \
80*6ba597c5SAnurag S. Maskey 		sizeof (*known_wlan_prop_table_entries))
81*6ba597c5SAnurag S. Maskey 
82*6ba597c5SAnurag S. Maskey struct nwam_prop_table known_wlan_prop_table =
83*6ba597c5SAnurag S. Maskey 	{ NWAM_NUM_KNOWN_WLAN_PROPS, known_wlan_prop_table_entries };
84*6ba597c5SAnurag S. Maskey 
85*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_read(const char * name,uint64_t flags,nwam_known_wlan_handle_t * kwhp)86*6ba597c5SAnurag S. Maskey nwam_known_wlan_read(const char *name, uint64_t flags,
87*6ba597c5SAnurag S. Maskey     nwam_known_wlan_handle_t *kwhp)
88*6ba597c5SAnurag S. Maskey {
89*6ba597c5SAnurag S. Maskey 	return (nwam_read(NWAM_OBJECT_TYPE_KNOWN_WLAN,
90*6ba597c5SAnurag S. Maskey 	    NWAM_KNOWN_WLAN_CONF_FILE, name, flags, kwhp));
91*6ba597c5SAnurag S. Maskey }
92*6ba597c5SAnurag S. Maskey 
93*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_create(const char * name,nwam_known_wlan_handle_t * kwhp)94*6ba597c5SAnurag S. Maskey nwam_known_wlan_create(const char *name, nwam_known_wlan_handle_t *kwhp)
95*6ba597c5SAnurag S. Maskey {
96*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
97*6ba597c5SAnurag S. Maskey 	nwam_value_t priorityval = NULL;
98*6ba597c5SAnurag S. Maskey 
99*6ba597c5SAnurag S. Maskey 	assert(kwhp != NULL && name != NULL);
100*6ba597c5SAnurag S. Maskey 
101*6ba597c5SAnurag S. Maskey 	if ((err = nwam_create(NWAM_OBJECT_TYPE_KNOWN_WLAN,
102*6ba597c5SAnurag S. Maskey 	    NWAM_KNOWN_WLAN_CONF_FILE, name, kwhp)) != NWAM_SUCCESS)
103*6ba597c5SAnurag S. Maskey 		return (err);
104*6ba597c5SAnurag S. Maskey 
105*6ba597c5SAnurag S. Maskey 	/*
106*6ba597c5SAnurag S. Maskey 	 * Create new object list for known WLAN.  The initial priority is
107*6ba597c5SAnurag S. Maskey 	 * also set.
108*6ba597c5SAnurag S. Maskey 	 */
109*6ba597c5SAnurag S. Maskey 	if ((err = nwam_alloc_object_list(&((*kwhp)->nwh_data)))
110*6ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
111*6ba597c5SAnurag S. Maskey 		goto finish;
112*6ba597c5SAnurag S. Maskey 	if ((err = nwam_value_create_uint64(0, &priorityval)) != NWAM_SUCCESS)
113*6ba597c5SAnurag S. Maskey 		goto finish;
114*6ba597c5SAnurag S. Maskey 	err = nwam_set_prop_value((*kwhp)->nwh_data,
115*6ba597c5SAnurag S. Maskey 	    NWAM_KNOWN_WLAN_PROP_PRIORITY, priorityval);
116*6ba597c5SAnurag S. Maskey 
117*6ba597c5SAnurag S. Maskey finish:
118*6ba597c5SAnurag S. Maskey 	nwam_value_free(priorityval);
119*6ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
120*6ba597c5SAnurag S. Maskey 		nwam_known_wlan_free(*kwhp);
121*6ba597c5SAnurag S. Maskey 		*kwhp = NULL;
122*6ba597c5SAnurag S. Maskey 	}
123*6ba597c5SAnurag S. Maskey 	return (err);
124*6ba597c5SAnurag S. Maskey }
125*6ba597c5SAnurag S. Maskey 
126*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_get_name(nwam_known_wlan_handle_t kwh,char ** namep)127*6ba597c5SAnurag S. Maskey nwam_known_wlan_get_name(nwam_known_wlan_handle_t kwh, char **namep)
128*6ba597c5SAnurag S. Maskey {
129*6ba597c5SAnurag S. Maskey 	return (nwam_get_name(kwh, namep));
130*6ba597c5SAnurag S. Maskey }
131*6ba597c5SAnurag S. Maskey 
132*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_set_name(nwam_known_wlan_handle_t kwh,const char * name)133*6ba597c5SAnurag S. Maskey nwam_known_wlan_set_name(nwam_known_wlan_handle_t kwh, const char *name)
134*6ba597c5SAnurag S. Maskey {
135*6ba597c5SAnurag S. Maskey 	return (nwam_set_name(kwh, name));
136*6ba597c5SAnurag S. Maskey }
137*6ba597c5SAnurag S. Maskey 
138*6ba597c5SAnurag S. Maskey boolean_t
nwam_known_wlan_can_set_name(nwam_known_wlan_handle_t kwh)139*6ba597c5SAnurag S. Maskey nwam_known_wlan_can_set_name(nwam_known_wlan_handle_t kwh)
140*6ba597c5SAnurag S. Maskey {
141*6ba597c5SAnurag S. Maskey 	return (!kwh->nwh_committed);
142*6ba597c5SAnurag S. Maskey }
143*6ba597c5SAnurag S. Maskey 
144*6ba597c5SAnurag S. Maskey /*
145*6ba597c5SAnurag S. Maskey  * Used to store wlan names/priorities for prioritized walk.
146*6ba597c5SAnurag S. Maskey  */
147*6ba597c5SAnurag S. Maskey struct nwam_wlan_info {
148*6ba597c5SAnurag S. Maskey 	char *wlan_name;
149*6ba597c5SAnurag S. Maskey 	uint64_t wlan_priority;
150*6ba597c5SAnurag S. Maskey 	boolean_t wlan_walked;
151*6ba597c5SAnurag S. Maskey };
152*6ba597c5SAnurag S. Maskey 
153*6ba597c5SAnurag S. Maskey struct nwam_wlan_info_list {
154*6ba597c5SAnurag S. Maskey 	struct nwam_wlan_info **list;
155*6ba597c5SAnurag S. Maskey 	uint_t num_wlans;
156*6ba597c5SAnurag S. Maskey };
157*6ba597c5SAnurag S. Maskey 
158*6ba597c5SAnurag S. Maskey /*
159*6ba597c5SAnurag S. Maskey  * Used to read in each known WLAN name/priority.
160*6ba597c5SAnurag S. Maskey  */
161*6ba597c5SAnurag S. Maskey static int
get_wlans_cb(nwam_known_wlan_handle_t kwh,void * data)162*6ba597c5SAnurag S. Maskey get_wlans_cb(nwam_known_wlan_handle_t kwh, void *data)
163*6ba597c5SAnurag S. Maskey {
164*6ba597c5SAnurag S. Maskey 	struct nwam_wlan_info_list *wil = data;
165*6ba597c5SAnurag S. Maskey 	struct nwam_wlan_info **list = wil->list;
166*6ba597c5SAnurag S. Maskey 	struct nwam_wlan_info **newlist = NULL;
167*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
168*6ba597c5SAnurag S. Maskey 	nwam_value_t priorityval = NULL;
169*6ba597c5SAnurag S. Maskey 	uint_t num_wlans = wil->num_wlans;
170*6ba597c5SAnurag S. Maskey 
171*6ba597c5SAnurag S. Maskey 	/* Reallocate WLAN list and allocate new info list element. */
172*6ba597c5SAnurag S. Maskey 	if ((newlist = realloc(list,
173*6ba597c5SAnurag S. Maskey 	    sizeof (struct nwam_wlan_info *) * ++num_wlans)) == NULL ||
174*6ba597c5SAnurag S. Maskey 	    (newlist[num_wlans - 1] = calloc(1,
175*6ba597c5SAnurag S. Maskey 	    sizeof (struct nwam_wlan_info))) == NULL) {
176*6ba597c5SAnurag S. Maskey 		if (newlist != NULL)
177*6ba597c5SAnurag S. Maskey 			free(newlist);
178*6ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
179*6ba597c5SAnurag S. Maskey 	}
180*6ba597c5SAnurag S. Maskey 
181*6ba597c5SAnurag S. Maskey 	/* Update list since realloc() may have relocated it */
182*6ba597c5SAnurag S. Maskey 	wil->list = newlist;
183*6ba597c5SAnurag S. Maskey 
184*6ba597c5SAnurag S. Maskey 	/* Retrieve name/priority */
185*6ba597c5SAnurag S. Maskey 	if ((err = nwam_known_wlan_get_name(kwh,
186*6ba597c5SAnurag S. Maskey 	    &((newlist[num_wlans - 1])->wlan_name))) != NWAM_SUCCESS ||
187*6ba597c5SAnurag S. Maskey 	    (err = nwam_known_wlan_get_prop_value(kwh,
188*6ba597c5SAnurag S. Maskey 	    NWAM_KNOWN_WLAN_PROP_PRIORITY, &priorityval)) != NWAM_SUCCESS ||
189*6ba597c5SAnurag S. Maskey 	    (err = nwam_value_get_uint64(priorityval,
190*6ba597c5SAnurag S. Maskey 	    &((newlist[num_wlans - 1])->wlan_priority))) != NWAM_SUCCESS) {
191*6ba597c5SAnurag S. Maskey 		free(newlist[num_wlans - 1]->wlan_name);
192*6ba597c5SAnurag S. Maskey 		nwam_value_free(priorityval);
193*6ba597c5SAnurag S. Maskey 		free(newlist[num_wlans - 1]);
194*6ba597c5SAnurag S. Maskey 		return (err);
195*6ba597c5SAnurag S. Maskey 	}
196*6ba597c5SAnurag S. Maskey 	nwam_value_free(priorityval);
197*6ba597c5SAnurag S. Maskey 
198*6ba597c5SAnurag S. Maskey 	(newlist[num_wlans - 1])->wlan_walked = B_FALSE;
199*6ba597c5SAnurag S. Maskey 
200*6ba597c5SAnurag S. Maskey 	wil->num_wlans = num_wlans;
201*6ba597c5SAnurag S. Maskey 
202*6ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
203*6ba597c5SAnurag S. Maskey }
204*6ba597c5SAnurag S. Maskey 
205*6ba597c5SAnurag S. Maskey /*
206*6ba597c5SAnurag S. Maskey  * Some recursion is required here, since if _WALK_PRIORITY_ORDER is specified,
207*6ba597c5SAnurag S. Maskey  * we need to first walk the list of known WLANs to retrieve names
208*6ba597c5SAnurag S. Maskey  * and priorities, then utilize that list to carry out an in-order walk.
209*6ba597c5SAnurag S. Maskey  */
210*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_walk_known_wlans(int (* cb)(nwam_known_wlan_handle_t,void *),void * data,uint64_t flags,int * retp)211*6ba597c5SAnurag S. Maskey nwam_walk_known_wlans(int(*cb)(nwam_known_wlan_handle_t, void *), void *data,
212*6ba597c5SAnurag S. Maskey     uint64_t flags, int *retp)
213*6ba597c5SAnurag S. Maskey {
214*6ba597c5SAnurag S. Maskey 	nwam_known_wlan_handle_t kwh;
215*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
216*6ba597c5SAnurag S. Maskey 	int ret = 0;
217*6ba597c5SAnurag S. Maskey 
218*6ba597c5SAnurag S. Maskey 	assert(cb != NULL);
219*6ba597c5SAnurag S. Maskey 
220*6ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags,
222*6ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
223*6ba597c5SAnurag S. Maskey 		return (err);
224*6ba597c5SAnurag S. Maskey 
225*6ba597c5SAnurag S. Maskey 	if ((flags & NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER) != 0) {
226*6ba597c5SAnurag S. Maskey 		struct nwam_wlan_info_list wil = { NULL, 0};
227*6ba597c5SAnurag S. Maskey 		uint64_t iflags = flags &~
228*6ba597c5SAnurag S. Maskey 		    NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER;
229*6ba597c5SAnurag S. Maskey 		uint64_t minpriority;
230*6ba597c5SAnurag S. Maskey 		int errval, i, j, minindex;
231*6ba597c5SAnurag S. Maskey 
232*6ba597c5SAnurag S. Maskey 		if (nwam_walk_known_wlans(get_wlans_cb, &wil, iflags, &errval)
233*6ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS) {
234*6ba597c5SAnurag S. Maskey 			err = (nwam_error_t)errval;
235*6ba597c5SAnurag S. Maskey 			goto done;
236*6ba597c5SAnurag S. Maskey 		}
237*6ba597c5SAnurag S. Maskey 
238*6ba597c5SAnurag S. Maskey 		err = NWAM_SUCCESS;
239*6ba597c5SAnurag S. Maskey 
240*6ba597c5SAnurag S. Maskey 		for (i = 0; i < wil.num_wlans; i++) {
241*6ba597c5SAnurag S. Maskey 			/* Find lowest priority value not walked so far. */
242*6ba597c5SAnurag S. Maskey 			minpriority = (uint64_t)-1;
243*6ba597c5SAnurag S. Maskey 			for (j = 0; j < wil.num_wlans; j++) {
244*6ba597c5SAnurag S. Maskey 				if (wil.list[j]->wlan_priority < minpriority &&
245*6ba597c5SAnurag S. Maskey 				    !(wil.list[j]->wlan_walked)) {
246*6ba597c5SAnurag S. Maskey 					minpriority =
247*6ba597c5SAnurag S. Maskey 					    wil.list[j]->wlan_priority;
248*6ba597c5SAnurag S. Maskey 					minindex = j;
249*6ba597c5SAnurag S. Maskey 				}
250*6ba597c5SAnurag S. Maskey 			}
251*6ba597c5SAnurag S. Maskey 			wil.list[minindex]->wlan_walked = B_TRUE;
252*6ba597c5SAnurag S. Maskey 			if ((err = nwam_known_wlan_read
253*6ba597c5SAnurag S. Maskey 			    (wil.list[minindex]->wlan_name,
254*6ba597c5SAnurag S. Maskey 			    iflags, &kwh)) != NWAM_SUCCESS) {
255*6ba597c5SAnurag S. Maskey 				goto done;
256*6ba597c5SAnurag S. Maskey 			}
257*6ba597c5SAnurag S. Maskey 			ret = cb(kwh, data);
258*6ba597c5SAnurag S. Maskey 			if (ret != 0) {
259*6ba597c5SAnurag S. Maskey 				nwam_known_wlan_free(kwh);
260*6ba597c5SAnurag S. Maskey 				err = NWAM_WALK_HALTED;
261*6ba597c5SAnurag S. Maskey 				goto done;
262*6ba597c5SAnurag S. Maskey 			}
263*6ba597c5SAnurag S. Maskey 			nwam_known_wlan_free(kwh);
264*6ba597c5SAnurag S. Maskey 		}
265*6ba597c5SAnurag S. Maskey done:
266*6ba597c5SAnurag S. Maskey 		if (wil.list != NULL) {
267*6ba597c5SAnurag S. Maskey 			for (j = 0; j < wil.num_wlans; j++) {
268*6ba597c5SAnurag S. Maskey 				free(wil.list[j]->wlan_name);
269*6ba597c5SAnurag S. Maskey 				free(wil.list[j]);
270*6ba597c5SAnurag S. Maskey 			}
271*6ba597c5SAnurag S. Maskey 			free(wil.list);
272*6ba597c5SAnurag S. Maskey 		}
273*6ba597c5SAnurag S. Maskey 		if (retp != NULL)
274*6ba597c5SAnurag S. Maskey 			*retp = ret;
275*6ba597c5SAnurag S. Maskey 		return (err);
276*6ba597c5SAnurag S. Maskey 	}
277*6ba597c5SAnurag S. Maskey 
278*6ba597c5SAnurag S. Maskey 	return (nwam_walk(NWAM_OBJECT_TYPE_KNOWN_WLAN,
279*6ba597c5SAnurag S. Maskey 	    NWAM_KNOWN_WLAN_CONF_FILE, cb, data, flags, retp, NULL));
280*6ba597c5SAnurag S. Maskey }
281*6ba597c5SAnurag S. Maskey 
282*6ba597c5SAnurag S. Maskey void
nwam_known_wlan_free(nwam_known_wlan_handle_t kwh)283*6ba597c5SAnurag S. Maskey nwam_known_wlan_free(nwam_known_wlan_handle_t kwh)
284*6ba597c5SAnurag S. Maskey {
285*6ba597c5SAnurag S. Maskey 	nwam_free(kwh);
286*6ba597c5SAnurag S. Maskey }
287*6ba597c5SAnurag S. Maskey 
288*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_copy(nwam_known_wlan_handle_t oldkwh,const char * newname,nwam_known_wlan_handle_t * newkwhp)289*6ba597c5SAnurag S. Maskey nwam_known_wlan_copy(nwam_known_wlan_handle_t oldkwh, const char *newname,
290*6ba597c5SAnurag S. Maskey     nwam_known_wlan_handle_t *newkwhp)
291*6ba597c5SAnurag S. Maskey {
292*6ba597c5SAnurag S. Maskey 	return (nwam_copy(NWAM_KNOWN_WLAN_CONF_FILE, oldkwh, newname, newkwhp));
293*6ba597c5SAnurag S. Maskey }
294*6ba597c5SAnurag S. Maskey 
295*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_known_wlan_delete_prop(nwam_known_wlan_handle_t kwh,const char * propname)296*6ba597c5SAnurag S. Maskey nwam_known_wlan_delete_prop(nwam_known_wlan_handle_t kwh, const char *propname)
297*6ba597c5SAnurag S. Maskey {
298*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
299*6ba597c5SAnurag S. Maskey 	void *olddata;
300*6ba597c5SAnurag S. Maskey 
301*6ba597c5SAnurag S. Maskey 	assert(kwh != NULL && propname != NULL);
302*6ba597c5SAnurag S. Maskey 
303*6ba597c5SAnurag S. Maskey 	/*
304*6ba597c5SAnurag S. Maskey 	 * Duplicate data, remove property and validate. If validation
305*6ba597c5SAnurag S. Maskey 	 * fails, revert to data duplicated prior to remove.
306*6ba597c5SAnurag S. Maskey 	 */
307*6ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(kwh->nwh_data, &olddata))
308*6ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
309*6ba597c5SAnurag S. Maskey 		return (err);
310*6ba597c5SAnurag S. Maskey 	if ((err = nwam_delete_prop(kwh->nwh_data, propname)) != NWAM_SUCCESS) {
311*6ba597c5SAnurag S. Maskey 		nwam_free_object_list(kwh->nwh_data);
312*6ba597c5SAnurag S. Maskey 		kwh->nwh_data = olddata;
313*6ba597c5SAnurag S. Maskey 		return (err);
314*6ba597c5SAnurag S. Maskey 	}