13871Syz147064 /*
23871Syz147064 * CDDL HEADER START
33871Syz147064 *
43871Syz147064 * The contents of this file are subject to the terms of the
53871Syz147064 * Common Development and Distribution License (the "License").
63871Syz147064 * You may not use this file except in compliance with the License.
73871Syz147064 *
83871Syz147064 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93871Syz147064 * or http://www.opensolaris.org/os/licensing.
103871Syz147064 * See the License for the specific language governing permissions
113871Syz147064 * and limitations under the License.
123871Syz147064 *
133871Syz147064 * When distributing Covered Code, include this CDDL HEADER in each
143871Syz147064 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153871Syz147064 * If applicable, add the following below this CDDL HEADER, with the
163871Syz147064 * fields enclosed by brackets "[]" replaced with your own identifying
173871Syz147064 * information: Portions Copyright [yyyy] [name of copyright owner]
183871Syz147064 *
193871Syz147064 * CDDL HEADER END
203871Syz147064 */
213871Syz147064 /*
22*10266SQuaker.Fang@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
233871Syz147064 * Use is subject to license terms.
243871Syz147064 */
253871Syz147064
263871Syz147064 #include <libintl.h>
273871Syz147064 #include <stdio.h>
283871Syz147064 #include <stdlib.h>
293871Syz147064 #include <unistd.h>
303871Syz147064 #include <fcntl.h>
315895Syz147064 #include <stddef.h>
323871Syz147064 #include <string.h>
333871Syz147064 #include <stropts.h>
343871Syz147064 #include <libdevinfo.h>
353871Syz147064 #include <net/if.h>
363871Syz147064 #include <net/if_dl.h>
373871Syz147064 #include <net/if_types.h>
385895Syz147064 #include <libdlpi.h>
395895Syz147064 #include <libdllink.h>
404126Szf162725 #include <libscf.h>
413871Syz147064 #include <libdlwlan.h>
425895Syz147064 #include <libdladm_impl.h>
433871Syz147064 #include <libdlwlan_impl.h>
444126Szf162725 #include <net/wpa.h>
453871Syz147064
468453SAnurag.Maskey@Sun.COM static dladm_status_t wpa_instance_create(dladm_handle_t, datalink_id_t,
478453SAnurag.Maskey@Sun.COM void *);
488453SAnurag.Maskey@Sun.COM static dladm_status_t wpa_instance_delete(dladm_handle_t, datalink_id_t);
493871Syz147064
508453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_bsstype(dladm_handle_t, datalink_id_t, void *,
518453SAnurag.Maskey@Sun.COM int);
528453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_essid(dladm_handle_t, datalink_id_t, void *,
538453SAnurag.Maskey@Sun.COM int);
548453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_bssid(dladm_handle_t, datalink_id_t, void *,
558453SAnurag.Maskey@Sun.COM int);
568453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_signal(dladm_handle_t, datalink_id_t, void *,
578453SAnurag.Maskey@Sun.COM int);
588453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_encryption(dladm_handle_t, datalink_id_t, void *,
598453SAnurag.Maskey@Sun.COM int);
608453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_authmode(dladm_handle_t, datalink_id_t, void *,
618453SAnurag.Maskey@Sun.COM int);
628453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_linkstatus(dladm_handle_t, datalink_id_t, void *,
638453SAnurag.Maskey@Sun.COM int);
648453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_esslist(dladm_handle_t, datalink_id_t, void *,
658453SAnurag.Maskey@Sun.COM int);
668453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_rate(dladm_handle_t, datalink_id_t, void *, int);
678453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_mode(dladm_handle_t, datalink_id_t, void *, int);
688453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_capability(dladm_handle_t, datalink_id_t, void *,
698453SAnurag.Maskey@Sun.COM int);
708453SAnurag.Maskey@Sun.COM static dladm_status_t do_get_wpamode(dladm_handle_t, datalink_id_t, void *,
718453SAnurag.Maskey@Sun.COM int);
724126Szf162725
738453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_bsstype(dladm_handle_t, datalink_id_t,
748453SAnurag.Maskey@Sun.COM dladm_wlan_bsstype_t *);
758453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_authmode(dladm_handle_t, datalink_id_t,
768453SAnurag.Maskey@Sun.COM dladm_wlan_auth_t *);
778453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_encryption(dladm_handle_t, datalink_id_t,
785895Syz147064 dladm_wlan_secmode_t *);
798453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_essid(dladm_handle_t, datalink_id_t,
808453SAnurag.Maskey@Sun.COM dladm_wlan_essid_t *);
818453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_createibss(dladm_handle_t, datalink_id_t,
828453SAnurag.Maskey@Sun.COM boolean_t *);
838453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_key(dladm_handle_t, datalink_id_t,
848453SAnurag.Maskey@Sun.COM dladm_wlan_key_t *, uint_t);
858453SAnurag.Maskey@Sun.COM static dladm_status_t do_set_channel(dladm_handle_t, datalink_id_t,
868453SAnurag.Maskey@Sun.COM dladm_wlan_channel_t *);
873871Syz147064
888453SAnurag.Maskey@Sun.COM static dladm_status_t do_scan(dladm_handle_t, datalink_id_t, void *, int);
898453SAnurag.Maskey@Sun.COM static dladm_status_t do_connect(dladm_handle_t, datalink_id_t, void *, int,
907663SSowmini.Varadhan@Sun.COM dladm_wlan_attr_t *, boolean_t, void *, uint_t,
917663SSowmini.Varadhan@Sun.COM int);
928453SAnurag.Maskey@Sun.COM static dladm_status_t do_disconnect(dladm_handle_t, datalink_id_t, void *,
938453SAnurag.Maskey@Sun.COM int);
945895Syz147064 static boolean_t find_val_by_name(const char *, val_desc_t *,
955895Syz147064 uint_t, uint_t *);
965895Syz147064 static boolean_t find_name_by_val(uint_t, val_desc_t *, uint_t, char **);
975895Syz147064 static void generate_essid(dladm_wlan_essid_t *);
983871Syz147064
993871Syz147064 static dladm_status_t dladm_wlan_wlresult2status(wldp_t *);
1008453SAnurag.Maskey@Sun.COM static dladm_status_t dladm_wlan_validate(dladm_handle_t, datalink_id_t);
1013871Syz147064
1023871Syz147064 static val_desc_t linkstatus_vals[] = {
1035903Ssowmini { "disconnected", DLADM_WLAN_LINK_DISCONNECTED },
1045903Ssowmini { "connected", DLADM_WLAN_LINK_CONNECTED }
1053871Syz147064 };
1063871Syz147064
1073871Syz147064 static val_desc_t secmode_vals[] = {
1085903Ssowmini { "none", DLADM_WLAN_SECMODE_NONE },
1095903Ssowmini { "wep", DLADM_WLAN_SECMODE_WEP },
1105903Ssowmini { "wpa", DLADM_WLAN_SECMODE_WPA }
1113871Syz147064 };
1123871Syz147064
1133871Syz147064 static val_desc_t strength_vals[] = {
1145903Ssowmini { "very weak", DLADM_WLAN_STRENGTH_VERY_WEAK },
1155895Syz147064 { "weak", DLADM_WLAN_STRENGTH_WEAK },
1165895Syz147064 { "good", DLADM_WLAN_STRENGTH_GOOD },
1175903Ssowmini { "very good", DLADM_WLAN_STRENGTH_VERY_GOOD },
1185903Ssowmini { "excellent", DLADM_WLAN_STRENGTH_EXCELLENT }
1193871Syz147064 };
1203871Syz147064
1213871Syz147064 static val_desc_t mode_vals[] = {
1225903Ssowmini { "a", DLADM_WLAN_MODE_80211A },
1235903Ssowmini { "b", DLADM_WLAN_MODE_80211B },
1245903Ssowmini { "g", DLADM_WLAN_MODE_80211G },
125*10266SQuaker.Fang@Sun.COM { "n", DLADM_WLAN_MODE_80211GN },
126*10266SQuaker.Fang@Sun.COM { "n", DLADM_WLAN_MODE_80211AN }
1273871Syz147064 };
1283871Syz147064
1293871Syz147064 static val_desc_t auth_vals[] = {
1305895Syz147064 { "open", DLADM_WLAN_AUTH_OPEN },
1315903Ssowmini { "shared", DLADM_WLAN_AUTH_SHARED }
1323871Syz147064 };
1333871Syz147064
1343871Syz147064 static val_desc_t bsstype_vals[] = {
1355903Ssowmini { "bss", DLADM_WLAN_BSSTYPE_BSS },
1365903Ssowmini { "ibss", DLADM_WLAN_BSSTYPE_IBSS },
1375903Ssowmini { "any", DLADM_WLAN_BSSTYPE_ANY }
1383871Syz147064 };
1393871Syz147064
1407663SSowmini.Varadhan@Sun.COM #define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET)
1413871Syz147064
1423871Syz147064 static dladm_status_t
dladm_wlan_wlresult2status(wldp_t * gbuf)1433871Syz147064 dladm_wlan_wlresult2status(wldp_t *gbuf)
1443871Syz147064 {
1453871Syz147064 switch (gbuf->wldp_result) {
1463871Syz147064 case WL_SUCCESS:
1473871Syz147064 return (DLADM_STATUS_OK);
1483871Syz147064
1493871Syz147064 case WL_NOTSUPPORTED:
1503871Syz147064 case WL_LACK_FEATURE:
1513871Syz147064 return (DLADM_STATUS_NOTSUP);
1523871Syz147064
1533871Syz147064 case WL_READONLY:
1543871Syz147064 return (DLADM_STATUS_PROPRDONLY);
1553871Syz147064
1563871Syz147064 default:
1573871Syz147064 break;
1583871Syz147064 }
1593871Syz147064
1603871Syz147064 return (DLADM_STATUS_FAILED);
1613871Syz147064 }
1623871Syz147064
1633871Syz147064 static dladm_wlan_mode_t
do_convert_mode(wl_phy_conf_t * phyp)1643871Syz147064 do_convert_mode(wl_phy_conf_t *phyp)
1653871Syz147064 {
166*10266SQuaker.Fang@Sun.COM wl_erp_t *wlep = &phyp->wl_phy_erp_conf;
167*10266SQuaker.Fang@Sun.COM wl_ofdm_t *wlop = &phyp->wl_phy_ofdm_conf;
168*10266SQuaker.Fang@Sun.COM
1693871Syz147064 switch (phyp->wl_phy_fhss_conf.wl_fhss_subtype) {
1703871Syz147064 case WL_ERP:
171*10266SQuaker.Fang@Sun.COM return (wlep->wl_erp_ht_enabled ?
172*10266SQuaker.Fang@Sun.COM DLADM_WLAN_MODE_80211GN : DLADM_WLAN_MODE_80211G);
1733871Syz147064 case WL_OFDM:
174*10266SQuaker.Fang@Sun.COM return (wlop->wl_ofdm_ht_enabled ?
175*10266SQuaker.Fang@Sun.COM DLADM_WLAN_MODE_80211AN : DLADM_WLAN_MODE_80211A);
1763871Syz147064 case WL_DSSS:
1773871Syz147064 case WL_FHSS:
1783871Syz147064 return (DLADM_WLAN_MODE_80211B);
1793871Syz147064 default:
1803871Syz147064 break;
1813871Syz147064 }
1823871Syz147064
1833871Syz147064 return (DLADM_WLAN_MODE_NONE);
1843871Syz147064 }
1853871Syz147064
1865895Syz147064 boolean_t
i_dladm_wlan_convert_chan(wl_phy_conf_t * phyp,uint32_t * channelp)1875895Syz147064 i_dladm_wlan_convert_chan(wl_phy_conf_t *phyp, uint32_t *channelp)
1883871Syz147064 {
1893871Syz147064 wl_fhss_t *wlfp = &phyp->wl_phy_fhss_conf;
1903871Syz147064 wl_ofdm_t *wlop = &phyp->wl_phy_ofdm_conf;
1913871Syz147064
1923871Syz147064 switch (wlfp->wl_fhss_subtype) {
1933871Syz147064 case WL_FHSS:
1943871Syz147064 case WL_DSSS:
1953871Syz147064 case WL_IRBASE:
1963871Syz147064 case WL_HRDS:
1973871Syz147064 case WL_ERP:
1983871Syz147064 *channelp = wlfp->wl_fhss_channel;
1993871Syz147064 break;
2003871Syz147064 case WL_OFDM:
2013871Syz147064 *channelp = DLADM_WLAN_OFDM2CHAN(wlop->wl_ofdm_frequency);
2023871Syz147064 break;
2033871Syz147064 default:
2043871Syz147064 return (B_FALSE);
2053871Syz147064 }
2063871Syz147064 return (B_TRUE);
2073871Syz147064 }
2083871Syz147064
2093871Syz147064 #define IEEE80211_RATE 0x7f
2103871Syz147064 static void
fill_wlan_attr(wl_ess_conf_t * wlp,dladm_wlan_attr_t * attrp)2113871Syz147064 fill_wlan_attr(wl_ess_conf_t *wlp, dladm_wlan_attr_t *attrp)
2123871Syz147064 {
2133871Syz147064 int i;
2143871Syz147064
2153871Syz147064 (void) memset(attrp, 0, sizeof (*attrp));
2163871Syz147064
2173871Syz147064 (void) snprintf(attrp->wa_essid.we_bytes, DLADM_WLAN_MAX_ESSID_LEN,
2183871Syz147064 "%s", wlp->wl_ess_conf_essid.wl_essid_essid);
2193871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID;
2203871Syz147064
2213871Syz147064 (void) memcpy(attrp->wa_bssid.wb_bytes, wlp->wl_ess_conf_bssid,
2223871Syz147064 DLADM_WLAN_BSSID_LEN);
2233871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID;
2243871Syz147064
2253871Syz147064 attrp->wa_secmode = (wlp->wl_ess_conf_wepenabled ==
2263871Syz147064 WL_ENC_WEP ? DLADM_WLAN_SECMODE_WEP : DLADM_WLAN_SECMODE_NONE);
2274126Szf162725 if (wlp->wl_ess_conf_reserved[0] > 0)
2284126Szf162725 attrp->wa_secmode = DLADM_WLAN_SECMODE_WPA;
2293871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE;
2303871Syz147064
2313871Syz147064 attrp->wa_bsstype = (wlp->wl_ess_conf_bsstype == WL_BSS_BSS ?
2323871Syz147064 DLADM_WLAN_BSSTYPE_BSS : DLADM_WLAN_BSSTYPE_IBSS);
2333871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE;
2343871Syz147064
2353871Syz147064 attrp->wa_auth = (wlp->wl_ess_conf_authmode == 0 ?
2363871Syz147064 DLADM_WLAN_AUTH_OPEN : DLADM_WLAN_AUTH_SHARED);
2373871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
2383871Syz147064
2393871Syz147064 attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(wlp->wl_ess_conf_sl);
2403871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH;
2413871Syz147064
2423871Syz147064 attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)&wlp->wl_phy_conf);
2433871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_MODE;
2443871Syz147064
2453871Syz147064 for (i = 0; i < MAX_SCAN_SUPPORT_RATES; i++) {
2463871Syz147064 wlp->wl_supported_rates[i] &= IEEE80211_RATE;
2473871Syz147064 if (wlp->wl_supported_rates[i] > attrp->wa_speed)
2483871Syz147064 attrp->wa_speed = wlp->wl_supported_rates[i];
2493871Syz147064 }
2503871Syz147064 if (attrp->wa_speed > 0)
2513871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED;
2523871Syz147064
2535895Syz147064 if (i_dladm_wlan_convert_chan((wl_phy_conf_t *)&wlp->wl_phy_conf,
2543871Syz147064 &attrp->wa_channel))
2553871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_CHANNEL;
2563871Syz147064 }
2573871Syz147064
2583871Syz147064 dladm_status_t
dladm_wlan_scan(dladm_handle_t handle,datalink_id_t linkid,void * arg,boolean_t (* func)(void *,dladm_wlan_attr_t *))2598453SAnurag.Maskey@Sun.COM dladm_wlan_scan(dladm_handle_t handle, datalink_id_t linkid, void *arg,
2603871Syz147064 boolean_t (*func)(void *, dladm_wlan_attr_t *))
2613871Syz147064 {
2625895Syz147064 int i;
2633871Syz147064 uint32_t count;
2643871Syz147064 wl_ess_conf_t *wlp;
2657663SSowmini.Varadhan@Sun.COM wl_ess_list_t *wls = NULL;
2667663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE];
2677663SSowmini.Varadhan@Sun.COM wl_linkstatus_t wl_status;
2683871Syz147064 dladm_wlan_attr_t wlattr;
2693871Syz147064 dladm_status_t status;
2703871Syz147064
2718453SAnurag.Maskey@Sun.COM if ((status = dladm_wlan_validate(handle, linkid)) != DLADM_STATUS_OK)
2725895Syz147064 goto done;
2733871Syz147064
2748453SAnurag.Maskey@Sun.COM status = do_get_linkstatus(handle, linkid, &wl_status,
2758453SAnurag.Maskey@Sun.COM sizeof (wl_status));
2767663SSowmini.Varadhan@Sun.COM if (status != DLADM_STATUS_OK)
2773871Syz147064 goto done;
2783871Syz147064
2798453SAnurag.Maskey@Sun.COM if ((status = do_scan(handle, linkid, buf, sizeof (buf))) !=
2808453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK)
2813871Syz147064 goto done;
2823871Syz147064
2834126Szf162725 if (func == NULL) {
2844126Szf162725 status = DLADM_STATUS_OK;
2854126Szf162725 goto done;
2864126Szf162725 }
2874126Szf162725
2887663SSowmini.Varadhan@Sun.COM wls = malloc(WLDP_BUFSIZE);
2897663SSowmini.Varadhan@Sun.COM if (wls == NULL) {
2907663SSowmini.Varadhan@Sun.COM status = DLADM_STATUS_NOMEM;
2917663SSowmini.Varadhan@Sun.COM goto done;
2927663SSowmini.Varadhan@Sun.COM }
2937663SSowmini.Varadhan@Sun.COM
2948453SAnurag.Maskey@Sun.COM if ((status = do_get_esslist(handle, linkid, wls, WLDP_BUFSIZE))
2957663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
2963871Syz147064 goto done;
2973871Syz147064
2987663SSowmini.Varadhan@Sun.COM wlp = wls->wl_ess_list_ess;
2997663SSowmini.Varadhan@Sun.COM count = wls->wl_ess_list_num;
3003871Syz147064
3013871Syz147064 for (i = 0; i < count; i++, wlp++) {
3023871Syz147064 fill_wlan_attr(wlp, &wlattr);
3033871Syz147064 if (!func(arg, &wlattr))
3043871Syz147064 break;
3053871Syz147064 }
3063871Syz147064
3077663SSowmini.Varadhan@Sun.COM if (wl_status != WL_CONNECTED) {
3088453SAnurag.Maskey@Sun.COM status = do_get_linkstatus(handle, linkid, &wl_status,
3097663SSowmini.Varadhan@Sun.COM sizeof (&wl_status));
3105895Syz147064 if (status != DLADM_STATUS_OK)
3113871Syz147064 goto done;
3127663SSowmini.Varadhan@Sun.COM if (wl_status == WL_CONNECTED)
3138453SAnurag.Maskey@Sun.COM (void) do_disconnect(handle, linkid, buf, sizeof (buf));
3143871Syz147064 }
3153871Syz147064
3163871Syz147064 status = DLADM_STATUS_OK;
3173871Syz147064 done:
3187663SSowmini.Varadhan@Sun.COM free(wls);
3193871Syz147064 return (status);
3203871Syz147064 }
3213871Syz147064
3223871Syz147064 /*
3233871Syz147064 * Structures used in building the list of eligible WLANs to connect to.
3243871Syz147064 * Specifically, `connect_state' has the WLAN attributes that must be matched
3253871Syz147064 * (in `cs_attr') and a growing list of WLANs that matched those attributes
3263871Syz147064 * chained through `cs_list'. Each element in the list is of type `attr_node'
3273871Syz147064 * and has the matching WLAN's attributes and a pointer to the next element.
3283871Syz147064 * For convenience, `cs_count' tracks the number of elements in the list.
3293871Syz147064 */
3303871Syz147064 typedef struct attr_node {
3313871Syz147064 dladm_wlan_attr_t an_attr;
3323871Syz147064 struct attr_node *an_next;
3333871Syz147064 } attr_node_t;
3343871Syz147064
3353871Syz147064 typedef struct connect_state {
3363871Syz147064 dladm_wlan_attr_t *cs_attr;
3373871Syz147064 uint_t cs_count;
3383871Syz147064 attr_node_t *cs_list;
3393871Syz147064 } connect_state_t;
3403871Syz147064
3413871Syz147064 /*
3423871Syz147064 * Compare two sets of WLAN attributes. For now, we only consider strength
3433871Syz147064 * and speed (in that order), which matches the documented default policy for
3443871Syz147064 * dladm_wlan_connect().
3453871Syz147064 */
3463871Syz147064 static int
attr_compare(const void * p1,const void * p2)3473871Syz147064 attr_compare(const void *p1, const void *p2)
3483871Syz147064 {
3493871Syz147064 dladm_wlan_attr_t *attrp1, *attrp2;
3503871Syz147064
3513871Syz147064 attrp1 = (*(dladm_wlan_attr_t **)p1);
3523871Syz147064 attrp2 = (*(dladm_wlan_attr_t **)p2);
3533871Syz147064
3543871Syz147064 if (attrp1->wa_strength < attrp2->wa_strength)
3553871Syz147064 return (1);
3563871Syz147064
3573871Syz147064 if (attrp1->wa_strength > attrp2->wa_strength)
3583871Syz147064 return (-1);
3593871Syz147064
3603871Syz147064 return (attrp2->wa_speed - attrp1->wa_speed);
3613871Syz147064 }
3623871Syz147064
3633871Syz147064 /*
3643871Syz147064 * Callback function used by dladm_wlan_connect() to filter out unwanted
3653871Syz147064 * WLANs when scanning for available WLANs. Always returns B_TRUE to
3663871Syz147064 * continue the scan.
3673871Syz147064 */
3683871Syz147064 static boolean_t
connect_cb(void * arg,dladm_wlan_attr_t * attrp)3693871Syz147064 connect_cb(void *arg, dladm_wlan_attr_t *attrp)
3703871Syz147064 {
3713871Syz147064 attr_node_t *nodep;
3723871Syz147064 dladm_wlan_attr_t *fattrp;
3733871Syz147064 connect_state_t *statep = (connect_state_t *)arg;
3743871Syz147064
3753871Syz147064 fattrp = statep->cs_attr;
3763871Syz147064 if (fattrp == NULL)
3773871Syz147064 goto append;
3783871Syz147064
3793871Syz147064 if ((fattrp->wa_valid & attrp->wa_valid) != fattrp->wa_valid)
3803871Syz147064 return (B_TRUE);
3813871Syz147064
3823871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0 &&
3833871Syz147064 strncmp(fattrp->wa_essid.we_bytes, attrp->wa_essid.we_bytes,
3843871Syz147064 DLADM_WLAN_MAX_ESSID_LEN) != 0)
3853871Syz147064 return (B_TRUE);
3863871Syz147064
3873871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 &&
3883871Syz147064 fattrp->wa_secmode != attrp->wa_secmode)
3893871Syz147064 return (B_TRUE);
3903871Syz147064
3913871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_MODE) != 0 &&
3923871Syz147064 fattrp->wa_mode != attrp->wa_mode)
3933871Syz147064 return (B_TRUE);
3943871Syz147064
3953871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_STRENGTH) != 0 &&
3963871Syz147064 fattrp->wa_strength != attrp->wa_strength)
3973871Syz147064 return (B_TRUE);
3983871Syz147064
3993871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_SPEED) != 0 &&
4003871Syz147064 fattrp->wa_speed != attrp->wa_speed)
4013871Syz147064 return (B_TRUE);
4023871Syz147064
4033871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_AUTH) != 0) {
4043871Syz147064 attrp->wa_auth = fattrp->wa_auth;
4053871Syz147064 attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
4063871Syz147064 }
4073871Syz147064
4083871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 &&
4093871Syz147064 fattrp->wa_bsstype != attrp->wa_bsstype)
4103871Syz147064 return (B_TRUE);
4113871Syz147064
4123871Syz147064 if ((fattrp->wa_valid & DLADM_WLAN_ATTR_BSSID) != 0 &&
4133871Syz147064 memcmp(fattrp->wa_bssid.wb_bytes, attrp->wa_bssid.wb_bytes,
4143871Syz147064 DLADM_WLAN_BSSID_LEN) != 0)
4153871Syz147064 return (B_TRUE);
4163871Syz147064 append:
4173871Syz147064 nodep = malloc(sizeof (attr_node_t));
4183871Syz147064 if (nodep == NULL)
4193871Syz147064 return (B_TRUE);
4203871Syz147064
4213871Syz147064 (void) memcpy(&nodep->an_attr, attrp, sizeof (dladm_wlan_attr_t));
4223871Syz147064 nodep->an_next = statep->cs_list;
4233871Syz147064 statep->cs_list = nodep;
4243871Syz147064 statep->cs_count++;
4253871Syz147064
4263871Syz147064 return (B_TRUE);
4273871Syz147064 }
4283871Syz147064
4294126Szf162725 #define IEEE80211_C_WPA 0x01800000
4304126Szf162725
4313871Syz147064 static dladm_status_t
do_connect(dladm_handle_t handle,datalink_id_t linkid,void * buf,int bufsize,dladm_wlan_attr_t * attrp,boolean_t create_ibss,void * keys,uint_t key_count,int timeout)4328453SAnurag.Maskey@Sun.COM do_connect(dladm_handle_t handle, datalink_id_t linkid, void *buf, int bufsize,
4337663SSowmini.Varadhan@Sun.COM dladm_wlan_attr_t *attrp, boolean_t create_ibss, void *keys,
4347663SSowmini.Varadhan@Sun.COM uint_t key_count, int timeout)
4353871Syz147064 {
4365895Syz147064 dladm_wlan_secmode_t secmode;
4375895Syz147064 dladm_wlan_auth_t authmode;
4385895Syz147064 dladm_wlan_bsstype_t bsstype;
4395895Syz147064 dladm_wlan_essid_t essid;
4405895Syz147064 boolean_t essid_valid = B_FALSE;
4415895Syz147064 dladm_status_t status;
4425895Syz147064 dladm_wlan_channel_t channel;
4435895Syz147064 hrtime_t start;
4445895Syz147064 wl_capability_t *caps;
4457663SSowmini.Varadhan@Sun.COM wl_linkstatus_t wl_status;
4463871Syz147064
4473871Syz147064 if ((attrp->wa_valid & DLADM_WLAN_ATTR_CHANNEL) != 0) {
4483871Syz147064 channel = attrp->wa_channel;
4498453SAnurag.Maskey@Sun.COM status = do_set_channel(handle, linkid, &channel);
4505895Syz147064 if (status != DLADM_STATUS_OK)
4513871Syz147064 goto fail;
4523871Syz147064 }
4533871Syz147064
4543871Syz147064 secmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) ?
4553871Syz147064 attrp->wa_secmode : DLADM_WLAN_SECMODE_NONE;
4563871Syz147064
4578453SAnurag.Maskey@Sun.COM if ((status = do_set_encryption(handle, linkid, &secmode)) !=
4588453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK)
4593871Syz147064 goto fail;
4603871Syz147064
4613871Syz147064 authmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_AUTH) != 0) ?
4623871Syz147064 attrp->wa_auth : DLADM_WLAN_AUTH_OPEN;
4633871Syz147064
4648453SAnurag.Maskey@Sun.COM if ((status = do_set_authmode(handle, linkid, &authmode)) !=
4658453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK)
4663871Syz147064 goto fail;
4673871Syz147064
4683871Syz147064 bsstype = ((attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0) ?
4693871Syz147064 attrp->wa_bsstype : DLADM_WLAN_BSSTYPE_BSS;
4703871Syz147064
4718453SAnurag.Maskey@Sun.COM if ((status = do_set_bsstype(handle, linkid, &bsstype)) !=
4728453SAnurag.Maskey@Sun.COM DLADM_STATUS_OK)
4733871Syz147064 goto fail;
4743871Syz147064
4753871Syz147064 if (secmode == DLADM_WLAN_SECMODE_WEP) {
4765895Syz147064 if (keys == NULL || key_count == 0 ||
4775895Syz147064 key_count > MAX_NWEPKEYS) {
4785895Syz147064 status = DLADM_STATUS_BADARG;
4795895Syz147064 goto fail;
4805895Syz147064 }
4818453SAnurag.Maskey@Sun.COM status = do_set_key(handle, linkid, keys, key_count);
4825895Syz147064 if (status != DLADM_STATUS_OK)
4833871Syz147064 goto fail;
4844126Szf162725 } else if (secmode == DLADM_WLAN_SECMODE_WPA) {
4855895Syz147064 if (keys == NULL || key_count == 0 ||
4865895Syz147064 key_count > MAX_NWEPKEYS) {
4875895Syz147064 status = DLADM_STATUS_BADARG;
4885895Syz147064 goto fail;
4895895Syz147064 }
4908453SAnurag.Maskey@Sun.COM status = do_get_capability(handle, linkid, buf, bufsize);
4915895Syz147064 if (status != DLADM_STATUS_OK)
4924126Szf162725 goto fail;
4937663SSowmini.Varadhan@Sun.COM caps = (wl_capability_t *)buf;
4944126Szf162725 if ((caps->caps & IEEE80211_C_WPA) == 0)
4954126Szf162725 return (DLADM_STATUS_NOTSUP);
4963871Syz147064 }
4973871Syz147064
4983871Syz147064 if (create_ibss) {
4998453SAnurag.Maskey@Sun.COM status = do_set_channel(handle, linkid, &channel);
5005895Syz147064 if (status != DLADM_STATUS_OK)
5013871Syz147064 goto fail;
5023871Syz147064
5038453SAnurag.Maskey@Sun.COM status = do_set_createibss(handle, linkid, &create_ibss);
5045895Syz147064 if (status != DLADM_STATUS_OK)
5053871Syz147064 goto fail;
5063871Syz147064
5073871Syz147064 if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0) {
5083871Syz147064 generate_essid(&essid);
5093871Syz147064 essid_valid = B_TRUE;
5103871Syz147064 }
5113871Syz147064 }
5123871Syz147064
5133871Syz147064 if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0) {
5143871Syz147064 essid = attrp->wa_essid;
5153871Syz147064 essid_valid = B_TRUE;
5163871Syz147064 }
5173871Syz147064
5185895Syz147064 if (!essid_valid) {
5195895Syz147064 status = DLADM_STATUS_FAILED;
5205895Syz147064 goto fail;
5215895Syz147064 }
5225895Syz147064
5238453SAnurag.Maskey@Sun.COM if ((status = do_set_essid(handle, linkid, &essid)) != DLADM_STATUS_OK)
5243871Syz147064 goto fail;
5253871Syz147064
5264126Szf162725 /*
5274126Szf162725 * Because wpa daemon needs getting essid from driver,
5284126Szf162725 * we need call do_set_essid() first, then call wpa_instance_create().
5294126Szf162725 */
5304126Szf162725 if (secmode == DLADM_WLAN_SECMODE_WPA && keys != NULL)
5318453SAnurag.Maskey@Sun.COM (void) wpa_instance_create(handle, linkid, keys);
5324126Szf162725
5333871Syz147064 start = gethrtime();
5343871Syz147064 for (;;) {
5358453SAnurag.Maskey@Sun.COM status = do_get_linkstatus(handle, linkid, &wl_status,
5367663SSowmini.Varadhan@Sun.COM sizeof (wl_status));
5375895Syz147064 if (status != DLADM_STATUS_OK)
5383871Syz147064 goto fail;
5393871Syz147064
5407663SSowmini.Varadhan@Sun.COM if (wl_status == WL_CONNECTED)
5413871Syz147064 break;
5423871Syz147064
5433871Syz147064 (void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE);
5443871Syz147064 if ((timeout >= 0) && (gethrtime() - start) /
5455895Syz147064 NANOSEC >= timeout) {
5465895Syz147064 status = DLADM_STATUS_TIMEDOUT;
5475895Syz147064 goto fail;
5485895Syz147064 }
5493871Syz147064 }
5505895Syz147064 status = DLADM_STATUS_OK;
5513871Syz147064 fail:
5525895Syz147064 return (status);
5533871Syz147064 }
5543871Syz147064
5553871Syz147064 dladm_status_t
dladm_wlan_connect(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_attr_t * attrp,int timeout,void * keys,uint_t key_count,uint_t flags)5568453SAnurag.Maskey@Sun.COM dladm_wlan_connect(dladm_handle_t handle, datalink_id_t linkid,
5578453SAnurag.Maskey@Sun.COM dladm_wlan_attr_t *attrp, int timeout, void *keys, uint_t key_count,
5588453SAnurag.Maskey@Sun.COM uint_t flags)
5593871Syz147064 {
5605895Syz147064 int i;
5617663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE];
5623871Syz147064 connect_state_t state = {0, NULL, NULL};
5633871Syz147064 attr_node_t *nodep = NULL;
5643871Syz147064 boolean_t create_ibss, set_authmode;
5653871Syz147064 dladm_wlan_attr_t **wl_list = NULL;
5665895Syz147064 dladm_status_t status;
5677663SSowmini.Varadhan@Sun.COM wl_linkstatus_t wl_status;
5683871Syz147064
5698453SAnurag.Maskey@Sun.COM if ((status = dladm_wlan_validate(handle, linkid)) != DLADM_STATUS_OK)
5706233Syz147064 return (status);
5713871Syz147064
5728453SAnurag.Maskey@Sun.COM if ((status = do_get_linkstatus(handle, linkid, &wl_status,
5738453SAnurag.Maskey@Sun.COM sizeof (wl_status))) != DLADM_STATUS_OK)
5743871Syz147064 goto done;
5753871Syz147064
5767663SSowmini.Varadhan@Sun.COM if (wl_status == WL_CONNECTED) {
5773871Syz147064 status = DLADM_STATUS_ISCONN;
5783871Syz147064 goto done;
5793871Syz147064 }
5803871Syz147064
5813871Syz147064 set_authmode = ((attrp != NULL) &&
5823871Syz147064 (attrp->wa_valid & DLADM_WLAN_ATTR_MODE) != 0);
5833871Syz147064 create_ibss = ((flags & DLADM_WLAN_CONNECT_CREATEIBSS) != 0 &&
5843871Syz147064 attrp != NULL &&
5853871Syz147064 (attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 &&
5863871Syz147064 attrp->wa_bsstype == DLADM_WLAN_BSSTYPE_IBSS);
5873871Syz147064
5883871Syz147064 if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0 ||
5893871Syz147064 (create_ibss && attrp != NULL &&
5903871Syz147064 (attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0)) {
5918453SAnurag.Maskey@Sun.COM status = do_connect(handle, linkid, buf, sizeof (buf), attrp,
5927663SSowmini.Varadhan@Sun.COM create_ibss, keys, key_count, timeout);
5933871Syz147064 goto done;
5943871Syz147064 }
5953871Syz147064
5963871Syz147064 state.cs_attr = attrp;
5973871Syz147064 state.cs_list = NULL;
5983871Syz147064 state.cs_count = 0;
5993871Syz147064
6008453SAnurag.Maskey@Sun.COM status = dladm_wlan_scan(handle, linkid, &state, connect_cb);
6013871Syz147064 if (status != DLADM_STATUS_OK)
6023871Syz147064 goto done;
6033871Syz147064
6043871Syz147064 if (state.cs_count == 0) {
6053871Syz147064 if (!create_ibss) {
6063871Syz147064 status = DLADM_STATUS_NOTFOUND;
6073871Syz147064 goto done;
6083871Syz147064 }
6098453SAnurag.Maskey@Sun.COM status = do_connect(handle, linkid, buf, sizeof (buf),
6107663SSowmini.Varadhan@Sun.COM attrp, create_ibss, keys, key_count, timeout);
6113871Syz147064 goto done;
6123871Syz147064 }
6133871Syz147064
6143871Syz147064 wl_list = malloc(state.cs_count * sizeof (dladm_wlan_attr_t *));
6153871Syz147064 if (wl_list == NULL) {
6163871Syz147064 status = DLADM_STATUS_NOMEM;
6173871Syz147064 goto done;
6183871Syz147064 }
6193871Syz147064
6203871Syz147064 nodep = state.cs_list;
6213871Syz147064 for (i = 0; i < state.cs_count; i++) {
6223871Syz147064 wl_list[i] = &nodep->an_attr;
6233871Syz147064 nodep = nodep->an_next;
6243871Syz147064 }
6253871Syz147064 qsort(wl_list, state.cs_count, sizeof (dladm_wlan_attr_t *),
6263871Syz147064 attr_compare);
6273871Syz147064
6283871Syz147064 for (i = 0; i < state.cs_count; i++) {
6293871Syz147064 dladm_wlan_attr_t *ap = wl_list[i];
6303871Syz147064
6318453SAnurag.Maskey@Sun.COM status = do_connect(handle, linkid, buf, sizeof (buf),
6327663SSowmini.Varadhan@Sun.COM ap, create_ibss, keys, key_count, timeout);
6333871Syz147064 if (status == DLADM_STATUS_OK)
6343871Syz147064 break;
6353871Syz147064
6363871Syz147064 if (!set_authmode) {
6373871Syz147064 ap->wa_auth = DLADM_WLAN_AUTH_SHARED;
6383871Syz147064 ap->wa_valid |= DLADM_WLAN_ATTR_AUTH;
6398453SAnurag.Maskey@Sun.COM status = do_connect(handle, linkid, buf, sizeof (buf),
6407663SSowmini.Varadhan@Sun.COM ap, create_ibss, keys, key_count, timeout);
6413871Syz147064 if (status == DLADM_STATUS_OK)
6423871Syz147064 break;
6433871Syz147064 }
6443871Syz147064 }
6453871Syz147064 done:
6463871Syz147064 if ((status != DLADM_STATUS_OK) && (status != DLADM_STATUS_ISCONN))
6478453SAnurag.Maskey@Sun.COM (void) do_disconnect(handle, linkid, buf, sizeof (buf));
6483871Syz147064
6493871Syz147064 while (state.cs_list != NULL) {
6503871Syz147064 nodep = state.cs_list;
6513871Syz147064 state.cs_list = nodep->an_next;
6523871Syz147064 free(nodep);
6533871Syz147064 }
6543871Syz147064 free(wl_list);
6553871Syz147064 return (status);
6563871Syz147064 }
6573871Syz147064
6583871Syz147064 dladm_status_t
dladm_wlan_disconnect(dladm_handle_t handle,datalink_id_t linkid)6598453SAnurag.Maskey@Sun.COM dladm_wlan_disconnect(dladm_handle_t handle, datalink_id_t linkid)
6603871Syz147064 {
6617663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE];
6623871Syz147064 dladm_status_t status;
6637663SSowmini.Varadhan@Sun.COM wl_linkstatus_t wl_status;
6643871Syz147064
6658453SAnurag.Maskey@Sun.COM if ((status = dladm_wlan_validate(handle, linkid)) != DLADM_STATUS_OK)
6665895Syz147064 return (status);
6673871Syz147064
6688453SAnurag.Maskey@Sun.COM if ((status = do_get_linkstatus(handle, linkid, &wl_status,
6698453SAnurag.Maskey@Sun.COM sizeof (wl_status))) != DLADM_STATUS_OK)
6703871Syz147064 goto done;
6713871Syz147064
6727663SSowmini.Varadhan@Sun.COM if (wl_status != WL_CONNECTED) {
6733871Syz147064 status = DLADM_STATUS_NOTCONN;
6743871Syz147064 goto done;
6753871Syz147064 }
6763871Syz147064
6778453SAnurag.Maskey@Sun.COM if ((status = do_disconnect(handle, linkid, buf, sizeof (buf)))
6787663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
6793871Syz147064 goto done;
6803871Syz147064
6818453SAnurag.Maskey@Sun.COM if ((status = do_get_linkstatus(handle, linkid, &wl_status,
6828453SAnurag.Maskey@Sun.COM sizeof (wl_status))) != DLADM_STATUS_OK)
6833871Syz147064 goto done;
6843871Syz147064
6857663SSowmini.Varadhan@Sun.COM if (wl_status == WL_CONNECTED) {
6863871Syz147064 status = DLADM_STATUS_FAILED;
6873871Syz147064 goto done;
6883871Syz147064 }
6893871Syz147064
6903871Syz147064 status = DLADM_STATUS_OK;
6913871Syz147064 done:
6923871Syz147064 return (status);
6933871Syz147064 }
6943871Syz147064
6955895Syz147064 dladm_status_t
dladm_wlan_get_linkattr(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_linkattr_t * attrp)6968453SAnurag.Maskey@Sun.COM dladm_wlan_get_linkattr(dladm_handle_t handle, datalink_id_t linkid,
6978453SAnurag.Maskey@Sun.COM dladm_wlan_linkattr_t *attrp)
6983871Syz147064 {
6993871Syz147064 wl_rssi_t signal;
7003871Syz147064 wl_bss_type_t bsstype;
7013871Syz147064 wl_authmode_t authmode;
7023871Syz147064 wl_encryption_t encryption;
7037663SSowmini.Varadhan@Sun.COM wl_rates_t *ratesp = NULL;
7043871Syz147064 dladm_wlan_attr_t *wl_attrp;
7055895Syz147064 dladm_status_t status;
7067663SSowmini.Varadhan@Sun.COM char buf[WLDP_BUFSIZE];
7077663SSowmini.Varadhan@Sun.COM wl_essid_t wls;
7087663SSowmini.Varadhan@Sun.COM wl_phy_conf_t wl_phy_conf;
7097663SSowmini.Varadhan@Sun.COM wl_linkstatus_t wl_status;
7103871Syz147064
7113871Syz147064 if (attrp == NULL)
7123871Syz147064 return (DLADM_STATUS_BADARG);
7133871Syz147064
7148453SAnurag.Maskey@Sun.COM if ((status = dladm_wlan_validate(handle, linkid)) != DLADM_STATUS_OK)
7155895Syz147064 goto done;
7163871Syz147064
7173871Syz147064 (void) memset(attrp, 0, sizeof (*attrp));
7183871Syz147064 wl_attrp = &attrp->la_wlan_attr;
7193871Syz147064
7208453SAnurag.Maskey@Sun.COM if ((status = do_get_linkstatus(handle, linkid, &wl_status,
7218453SAnurag.Maskey@Sun.COM sizeof (wl_status))) != DLADM_STATUS_OK)
7223871Syz147064 goto done;
7233871Syz147064
7243871Syz147064 attrp->la_valid |= DLADM_WLAN_LINKATTR_STATUS;
7257663SSowmini.Varadhan@Sun.COM if (wl_status != WL_CONNECTED)
7265895Syz147064 attrp->la_status = DLADM_WLAN_LINK_DISCONNECTED;
7275895Syz147064 else
7285895Syz147064 attrp->la_status = DLADM_WLAN_LINK_CONNECTED;
7293871Syz147064
7308453SAnurag.Maskey@Sun.COM if ((status = do_get_essid(handle, linkid, &wls, sizeof (wls)))
7317663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
7323871Syz147064 goto done;
7333871Syz147064
7347663SSowmini.Varadhan@Sun.COM (void) strlcpy(wl_attrp->wa_essid.we_bytes, wls.wl_essid_essid,
7353871Syz147064 DLADM_WLAN_MAX_ESSID_LEN);
7363871Syz147064
7373871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID;
7383871Syz147064
7398453SAnurag.Maskey@Sun.COM if ((status = do_get_bssid(handle, linkid, buf, sizeof (buf)))
7407663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
7413871Syz147064 goto done;
7423871Syz147064
7437663SSowmini.Varadhan@Sun.COM (void) memcpy(wl_attrp->wa_bssid.wb_bytes, buf, DLADM_WLAN_BSSID_LEN);
7443871Syz147064
7453871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID;
7463871Syz147064
7475895Syz147064 if (attrp->la_status == DLADM_WLAN_LINK_DISCONNECTED) {
7484126Szf162725 attrp->la_valid |= DLADM_WLAN_LINKATTR_WLAN;
7494126Szf162725 status = DLADM_STATUS_OK;
7504126Szf162725 goto done;
7514126Szf162725 }
7524126Szf162725
7538453SAnurag.Maskey@Sun.COM if ((status = do_get_encryption(handle, linkid, &encryption,
7547663SSowmini.Varadhan@Sun.COM sizeof (encryption))) != DLADM_STATUS_OK)
7553871Syz147064 goto done;
7563871Syz147064
7573871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE;
7583871Syz147064
7593871Syz147064 switch (encryption) {
7603871Syz147064 case WL_NOENCRYPTION:
7613871Syz147064 wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_NONE;
7623871Syz147064 break;
7633871Syz147064 case WL_ENC_WEP:
7643871Syz147064 wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_WEP;
7653871Syz147064 break;
7664126Szf162725 case WL_ENC_WPA:
7674126Szf162725 wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_WPA;
7684126Szf162725 break;
7693871Syz147064 default:
7703871Syz147064 wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_SECMODE;
7713871Syz147064 break;
7723871Syz147064 }
7733871Syz147064
7748453SAnurag.Maskey@Sun.COM if ((status = do_get_signal(handle, linkid, &signal, sizeof (signal)))
7757663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
7763871Syz147064 goto done;
7773871Syz147064
7783871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH;
7793871Syz147064 wl_attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(signal);
7803871Syz147064
7817663SSowmini.Varadhan@Sun.COM ratesp = malloc(WLDP_BUFSIZE);
7827663SSowmini.Varadhan@Sun.COM if (ratesp == NULL) {
7837663SSowmini.Varadhan@Sun.COM status = DLADM_STATUS_NOMEM;
7847663SSowmini.Varadhan@Sun.COM goto done;
7857663SSowmini.Varadhan@Sun.COM }
7867663SSowmini.Varadhan@Sun.COM
7878453SAnurag.Maskey@Sun.COM if ((status = do_get_rate(handle, linkid, ratesp, WLDP_BUFSIZE))
7887663SSowmini.Varadhan@Sun.COM != DLADM_STATUS_OK)
7893871Syz147064 goto done;
7903871Syz147064
7913871Syz147064 if (ratesp->wl_rates_num > 0) {
7923871Syz147064 uint_t i, r = 0;
7933871Syz147064
7943871Syz147064 for (i = 0; i < ratesp->wl_rates_num; i++) {
7953871Syz147064 if (ratesp->wl_rates_rates[i] > r)
7963871Syz147064 r = ratesp->wl_rates_rates[i];
7973871Syz147064 }
7983871Syz147064 wl_attrp->wa_speed = r;
7993871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED;
8003871Syz147064 }
8013871Syz147064
8028453SAnurag.Maskey@Sun.COM if ((status = do_get_authmode(handle, linkid, &authmode,
8037663SSowmini.Varadhan@Sun.COM sizeof (authmode))) != DLADM_STATUS_OK)
8043871Syz147064 goto done;
8053871Syz147064
8063871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
8073871Syz147064
8083871Syz147064 switch (authmode) {
8093871Syz147064 case WL_OPENSYSTEM:
8103871Syz147064 wl_attrp->wa_auth = DLADM_WLAN_AUTH_OPEN;
8113871Syz147064 break;
8123871Syz147064 case WL_SHAREDKEY:
8133871Syz147064 wl_attrp->wa_auth = DLADM_WLAN_AUTH_SHARED;
8143871Syz147064 break;
8153871Syz147064 default:
8163871Syz147064 wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_AUTH;
8173871Syz147064 break;
8183871Syz147064 }
8193871Syz147064
8208453SAnurag.Maskey@Sun.COM if ((status = do_get_bsstype(handle, linkid, &bsstype,
8217663SSowmini.Varadhan@Sun.COM sizeof (bsstype))) != DLADM_STATUS_OK)
8223871Syz147064 goto done;
8233871Syz147064
8243871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE;
8253871Syz147064
8263871Syz147064 switch (bsstype) {
8273871Syz147064 case WL_BSS_BSS:
8283871Syz147064 wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_BSS;
8293871Syz147064 break;
8303871Syz147064 case WL_BSS_IBSS:
8313871Syz147064 wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_IBSS;
8323871Syz147064 break;
8333871Syz147064 case WL_BSS_ANY:
8343871Syz147064 wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_ANY;
8353871Syz147064 break;
8363871Syz147064 default:
8373871Syz147064 wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_BSSTYPE;
8383871Syz147064 break;
8393871Syz147064 }
8403871Syz147064
8418453SAnurag.Maskey@Sun.COM if ((status = do_get_mode(handle, linkid, &wl_phy_conf,
8427663SSowmini.Varadhan@Sun.COM sizeof (wl_phy_conf))) != DLADM_STATUS_OK)
8433871Syz147064 goto done;
8443871Syz147064
8457663SSowmini.Varadhan@Sun.COM wl_attrp->wa_mode = do_convert_mode(&wl_phy_conf);
8463871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE;
8473871Syz147064 if (wl_attrp->wa_mode != DLADM_WLAN_MODE_NONE)
8483871Syz147064 wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE;
8493871Syz147064
8503871Syz147064 attrp->la_valid |= DLADM_WLAN_LINKATTR_WLAN;
8513871Syz147064 status = DLADM_STATUS_OK;
8523871Syz147064
8533871Syz147064 done:
8547663SSowmini.Varadhan@Sun.COM free(ratesp);
8553871Syz147064 return (status);
8563871Syz147064 }
8573871Syz147064
8587408SSebastien.Roy@Sun.COM /*
8597408SSebastien.Roy@Sun.COM * Check to see if the link is wireless.
8607408SSebastien.Roy@Sun.COM */
8613871Syz147064 static dladm_status_t
dladm_wlan_validate(dladm_handle_t handle,datalink_id_t linkid)8628453SAnurag.Maskey@Sun.COM dladm_wlan_validate(dladm_handle_t handle, datalink_id_t linkid)
8633871Syz147064 {
8647408SSebastien.Roy@Sun.COM uint32_t media;
8653871Syz147064 dladm_status_t status;
8663871Syz147064
8678453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, NULL, &media,
8688453SAnurag.Maskey@Sun.COM NULL, 0);
8697408SSebastien.Roy@Sun.COM if (status == DLADM_STATUS_OK) {
8707408SSebastien.Roy@Sun.COM if (media != DL_WIFI)
8717408SSebastien.Roy@Sun.COM status = DLADM_STATUS_LINKINVAL;
8723871Syz147064 }
8733871Syz147064 return (status);
8743871Syz147064 }
8753871Syz147064
8763871Syz147064 static boolean_t
find_val_by_name(const char * str,val_desc_t * vdp,uint_t cnt,uint_t * valp)8773871Syz147064 find_val_by_name(const char *str, val_desc_t *vdp, uint_t cnt, uint_t *valp)
8783871Syz147064 {
8793871Syz147064 int i;
8803871Syz147064
8813871Syz147064 for (i = 0; i < cnt; i++) {
8823871Syz147064 if (strcasecmp(str, vdp[i].vd_name) == 0) {
8833871Syz147064 *valp = vdp[i].vd_val;
8843871Syz147064 return (B_TRUE);
8853871Syz147064 }
8863871Syz147064 }
8873871Syz147064 return (B_FALSE);
8883871Syz147064 }
8893871Syz147064
8903871Syz147064 static boolean_t
find_name_by_val(uint_t val,val_desc_t * vdp,uint_t cnt,char ** strp)8913871Syz147064 find_name_by_val(uint_t val, val_desc_t *vdp, uint_t cnt, char **strp)
8923871Syz147064 {
8933871Syz147064 int i;
8943871Syz147064
8953871Syz147064 for (i = 0; i < cnt; i++) {
8963871Syz147064 if (val == vdp[i].vd_val) {
8973871Syz147064 *strp = vdp[i].vd_name;
8983871Syz147064 return (B_TRUE);
8993871Syz147064 }
9003871Syz147064 }
9013871Syz147064 return (B_FALSE);
9023871Syz147064 }
9033871Syz147064
9043871Syz147064 const char *
dladm_wlan_essid2str(dladm_wlan_essid_t * essid,char * buf)9053871Syz147064 dladm_wlan_essid2str(dladm_wlan_essid_t *essid, char *buf)
9063871Syz147064 {
9073871Syz147064 (void) snprintf(buf, DLADM_STRSIZE, "%s", essid->we_bytes);
9083871Syz147064 return (buf);
9093871Syz147064 }
9103871Syz147064
9113871Syz147064 const char *
dladm_wlan_bssid2str(dladm_wlan_bssid_t * bssid,char * buf)9123871Syz147064 dladm_wlan_bssid2str(dladm_wlan_bssid_t *bssid, char *buf)
9133871Syz147064 {
9143871Syz147064 return (_link_ntoa(bssid->wb_bytes, buf, DLADM_WLAN_BSSID_LEN,
9153871Syz147064 IFT_OTHER));
9163871Syz147064 }
9173871Syz147064
9183871Syz147064 static const char *
dladm_wlan_val2str(uint_t val,val_desc_t * vdp,uint_t cnt,char * buf)9193871Syz147064 dladm_wlan_val2str(uint_t val, val_desc_t *vdp, uint_t cnt, char *buf)
9203871Syz147064 {
9213871Syz147064 char *s;
9223871Syz147064
9233871Syz147064 if (!find_name_by_val(val, vdp, cnt, &s))
9243871Syz147064 s = "";
9253871Syz147064
9263871Syz147064 (void) snprintf(buf, DLADM_STRSIZE, "%s", s);
9273871Syz147064 return (buf);
9283871Syz147064 }
9293871Syz147064
9303871Syz147064 const char *
dladm_wlan_secmode2str(dladm_wlan_secmode_t * secmode,char * buf)9313871Syz147064 dladm_wlan_secmode2str(dladm_wlan_secmode_t *secmode, char *buf)
9323871Syz147064 {
9333871Syz147064 return (dladm_wlan_val2str((uint_t)*secmode, secmode_vals,
9343871Syz147064 VALCNT(secmode_vals), buf));
9353871Syz147064 }
9363871Syz147064
9373871Syz147064 const char *
dladm_wlan_strength2str(dladm_wlan_strength_t * strength,char * buf)9383871Syz147064 dladm_wlan_strength2str(dladm_wlan_strength_t *strength, char *buf)
9393871Syz147064 {
9403871Syz147064 return (dladm_wlan_val2str((uint_t)*strength, strength_vals,
9413871Syz147064 VALCNT(strength_vals), buf));
9423871Syz147064 }
9433871Syz147064
9443871Syz147064 const char *
dladm_wlan_mode2str(dladm_wlan_mode_t * mode,char * buf)9453871Syz147064 dladm_wlan_mode2str(dladm_wlan_mode_t *mode, char *buf)
9463871Syz147064 {
9473871Syz147064 return (dladm_wlan_val2str((uint_t)*mode, mode_vals,
9483871Syz147064 VALCNT(mode_vals), buf));
9493871Syz147064 }
9503871Syz147064
9513871Syz147064 const char *
dladm_wlan_speed2str(dladm_wlan_speed_t * speed,char * buf)9523871Syz147064 dladm_wlan_speed2str(dladm_wlan_speed_t *speed, char *buf)
9533871Syz147064 {
9543871Syz147064 (void) snprintf(buf, DLADM_STRSIZE, "%.*f", *speed % 2,
9553871Syz147064 (float)(*speed) / 2);
9563871Syz147064 return (buf);
9573871Syz147064 }
9583871Syz147064
9593871Syz147064 const char *
dladm_wlan_auth2str(dladm_wlan_auth_t * auth,char * buf)9603871Syz147064 dladm_wlan_auth2str(dladm_wlan_auth_t *auth, char *buf)
9613871Syz147064 {
9623871Syz147064 return (dladm_wlan_val2str((uint_t)*auth, auth_vals,
9633871Syz147064 VALCNT(auth_vals), buf));
9643871Syz147064 }
9653871Syz147064
9663871Syz147064 const char *
dladm_wlan_bsstype2str(dladm_wlan_bsstype_t * bsstype,char * buf)9673871Syz147064 dladm_wlan_bsstype2str(dladm_wlan_bsstype_t *bsstype, char *buf)
9683871Syz147064 {
9693871Syz147064 return (dladm_wlan_val2str((uint_t)*bsstype, bsstype_vals,
9703871Syz147064 VALCNT(bsstype_vals), buf));
9713871Syz147064 }
9723871Syz147064
9733871Syz147064 const char *
dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t * linkstatus,char * buf)9743871Syz147064 dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t *linkstatus, char *buf)
9753871Syz147064 {
9763871Syz147064 return (dladm_wlan_val2str((uint_t)*linkstatus, linkstatus_vals,
9773871Syz147064 VALCNT(linkstatus_vals), buf));
9783871Syz147064 }
9793871Syz147064
9803871Syz147064 dladm_status_t
dladm_wlan_str2essid(const char * str,dladm_wlan_essid_t * essid)9813871Syz147064 dladm_wlan_str2essid(const char *str, dladm_wlan_essid_t *essid)
9823871Syz147064 {
9836834Sff224033 if (str[0] == '\0' || strlen(str) > DLADM_WLAN_MAX_ESSID_LEN - 1)
9843871Syz147064 return (DLADM_STATUS_BADARG);
9853871Syz147064
9863871Syz147064 (void) strlcpy(essid->we_bytes, str, DLADM_WLAN_MAX_ESSID_LEN);
9873871Syz147064 return (DLADM_STATUS_OK);
9883871Syz147064 }
9893871Syz147064
9903871Syz147064 dladm_status_t
dladm_wlan_str2bssid(const char * str,dladm_wlan_bssid_t * bssid)9913871Syz147064 dladm_wlan_str2bssid(const char *str, dladm_wlan_bssid_t *bssid)
9923871Syz147064 {
9933871Syz147064 int len;
9943871Syz147064 uchar_t *buf;
9953871Syz147064
9963871Syz147064 buf = _link_aton(str, &len);
9973871Syz147064 if (buf == NULL)
9983871Syz147064 return (DLADM_STATUS_BADARG);
9993871Syz147064
10003871Syz147064 if (len != DLADM_WLAN_BSSID_LEN) {
10013871Syz147064 free(buf);
10023871Syz147064 return (DLADM_STATUS_BADARG);
10033871Syz147064 }
10043871Syz147064
10053871Syz147064 (void) memcpy(bssid->wb_bytes, buf, len);
10063871Syz147064 free(buf);
10073871Syz147064 return (DLADM_STATUS_OK);
10083871Syz147064 }
10093871Syz147064
10103871Syz147064 dladm_status_t
dladm_wlan_str2secmode(const char * str,dladm_wlan_secmode_t * secmode)10113871Syz147064 dladm_wlan_str2secmode(const char *str, dladm_wlan_secmode_t *secmode)
10123871Syz147064 {
10133871Syz147064 uint_t val;
10143871Syz147064
10153871Syz147064 if (!find_val_by_name(str, secmode_vals, VALCNT(secmode_vals), &val))
10163871Syz147064 return (DLADM_STATUS_BADARG);
10173871Syz147064
10183871Syz147064 *secmode = (dladm_wlan_secmode_t)val;
10193871Syz147064 return (DLADM_STATUS_OK);
10203871Syz147064 }
10213871Syz147064
10223871Syz147064 dladm_status_t
dladm_wlan_str2strength(const char * str,dladm_wlan_strength_t * strength)10233871Syz147064 dladm_wlan_str2strength(const char *str, dladm_wlan_strength_t *strength)
10243871Syz147064 {
10253871Syz147064 uint_t val;
10263871Syz147064
10273871Syz147064 if (!find_val_by_name(str, strength_vals, VALCNT(strength_vals), &val))
10283871Syz147064 return (DLADM_STATUS_BADARG);
10293871Syz147064
10303871Syz147064 *strength = (dladm_wlan_strength_t)val;
10313871Syz147064 return (DLADM_STATUS_OK);
10323871Syz147064 }
10333871Syz147064
10343871Syz147064 dladm_status_t
dladm_wlan_str2mode(const char * str,dladm_wlan_mode_t * mode)10353871Syz147064 dladm_wlan_str2mode(const char *str, dladm_wlan_mode_t *mode)
10363871Syz147064 {
10373871Syz147064 uint_t val;
10383871Syz147064
10393871Syz147064 if (!find_val_by_name(str, mode_vals, VALCNT(mode_vals), &val))
10403871Syz147064 return (DLADM_STATUS_BADARG);
10413871Syz147064
10423871Syz147064 *mode = (dladm_wlan_mode_t)val;
10433871Syz147064 return (DLADM_STATUS_OK);
10443871Syz147064 }
10453871Syz147064
10463871Syz147064 dladm_status_t
dladm_wlan_str2speed(const char * str,dladm_wlan_speed_t * speed)10473871Syz147064 dladm_wlan_str2speed(const char *str, dladm_wlan_speed_t *speed)
10483871Syz147064 {
10493871Syz147064 *speed = (dladm_wlan_speed_t)(atof(str) * 2);
10503871Syz147064 return (DLADM_STATUS_OK);
10513871Syz147064 }
10523871Syz147064
10533871Syz147064 dladm_status_t
dladm_wlan_str2auth(const char * str,dladm_wlan_auth_t * auth)10543871Syz147064 dladm_wlan_str2auth(const char *str, dladm_wlan_auth_t *auth)
10553871Syz147064 {
10563871Syz147064 uint_t val;
10573871Syz147064
10583871Syz147064 if (!find_val_by_name(str, auth_vals, VALCNT(auth_vals), &val))
10593871Syz147064 return (DLADM_STATUS_BADARG);
10603871Syz147064
10613871Syz147064 *auth = (dladm_wlan_auth_t)val;
10623871Syz147064 return (DLADM_STATUS_OK);
10633871Syz147064 }
10643871Syz147064
10653871Syz147064 dladm_status_t
dladm_wlan_str2bsstype(const char * str,dladm_wlan_bsstype_t * bsstype)10663871Syz147064 dladm_wlan_str2bsstype(const char *str, dladm_wlan_bsstype_t *bsstype)
10673871Syz147064 {
10683871Syz147064 uint_t val;
10693871Syz147064
10703871Syz147064 if (!find_val_by_name(str, bsstype_vals, VALCNT(bsstype_vals), &val))
10713871Syz147064 return (DLADM_STATUS_BADARG);
10723871Syz147064
10733871Syz147064 *bsstype = (dladm_wlan_bsstype_t)val;
10743871Syz147064 return (DLADM_STATUS_OK);
10753871Syz147064 }
10763871Syz147064
10773871Syz147064 dladm_status_t
dladm_wlan_str2linkstatus(const char * str,dladm_wlan_linkstatus_t * linkstatus)10783871Syz147064 dladm_wlan_str2linkstatus(const char *str, dladm_wlan_linkstatus_t *linkstatus)
10793871Syz147064 {
10803871Syz147064 uint_t val;
10813871Syz147064
10825895Syz147064 if (!find_val_by_name(str, linkstatus_vals,
10835895Syz147064 VALCNT(linkstatus_vals), &val)) {
10843871Syz147064 return (DLADM_STATUS_BADARG);
10855895Syz147064 }
10863871Syz147064
10873871Syz147064 *linkstatus = (dladm_wlan_linkstatus_t)val;
10883871Syz147064 return (DLADM_STATUS_OK);
10893871Syz147064 }
10903871Syz147064
10915895Syz147064 dladm_status_t
i_dladm_wlan_legacy_ioctl(dladm_handle_t handle,datalink_id_t linkid,wldp_t * gbuf,uint_t id,size_t len,uint_t cmd,size_t cmdlen)10928453SAnurag.Maskey@Sun.COM i_dladm_wlan_legacy_ioctl(dladm_handle_t handle, datalink_id_t linkid,
10938453SAnurag.Maskey@Sun.COM wldp_t *gbuf, uint_t id, size_t len, uint_t cmd, size_t cmdlen)
10943871Syz147064 {
10955895Syz147064 char linkname[MAXPATHLEN];
10965895Syz147064 int fd, rc;
10973871Syz147064 struct strioctl stri;
10985895Syz147064 uint32_t flags;
10995895Syz147064 dladm_status_t status;
11005895Syz147064 uint32_t media;
11015895Syz147064 char link[MAXLINKNAMELEN];
11025895Syz147064
11038453SAnurag.Maskey@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL,
11048453SAnurag.Maskey@Sun.COM &media, link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) {
11055895Syz147064 return (status);
11065895Syz147064 }
11075895Syz147064
11085895Syz147064 if (media != DL_WIFI)
11095895Syz147064 return (DLADM_STATUS_BADARG);
11105895Syz147064
11115895Syz147064 if (!(flags & DLADM_OPT_ACTIVE))
11125895Syz147064 return (DLADM_STATUS_TEMPONLY);
11135895Syz147064
11145895Syz147064 /*
11155895Syz147064 * dlpi_open() is not used here because libdlpi depends on libdladm,
11165895Syz147064 * and we do not want to introduce recursive dependencies.
11175895Syz147064 */
11185895Syz147064 (void) snprintf(linkname, MAXPATHLEN, "/dev/net/%s", link);
11195895Syz147064 if ((fd = open(linkname, O_RDWR)) < 0)
11207408SSebastien.Roy@Sun.COM return (dladm_errno2status(errno));
11213871Syz147064
11223871Syz147064 gbuf->wldp_type = NET_802_11;
11233871Syz147064 gbuf->wldp_id = id;
11243871Syz147064 gbuf->wldp_length = len;
11253871Syz147064
11263871Syz147064 stri.ic_timout = 0;
11273871Syz147064 stri.ic_dp = (char *)gbuf;
11283871Syz147064 stri.ic_cmd = cmd;
11293871Syz147064 stri.ic_len = cmdlen;
11303871Syz147064
11313871Syz147064 if ((rc = ioctl(fd, I_STR, &stri)) != 0) {
11325895Syz147064 if (rc > 0) {
11335895Syz147064 /*
11345895Syz147064 * Non-negative return value indicates the specific
11355895Syz147064 * operation failed and the reason for the failure
11365895Syz147064 * was stored in gbuf->wldp_result.
11375895Syz147064 */
11385895Syz147064 status = dladm_wlan_wlresult2status(gbuf);
11395895Syz147064 } else {
11405895Syz147064 /*
11415895Syz147064 * Negative return value indicates the ioctl failed.
11425895Syz147064 */
11435895Syz147064 status = dladm_errno2status(errno);
11445895Syz147064 }
11453871Syz147064 }
11465895Syz147064 (void) close(fd);
11475895Syz147064 return (status);
11483871Syz147064 }
11493871Syz147064
11507663SSowmini.Varadhan@Sun.COM static dladm_status_t
do_cmd_ioctl(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen,uint_t cmd)11518453SAnurag.Maskey@Sun.COM do_cmd_ioctl(dladm_handle_t handle, datalink_id_t linkid, void *buf,
11528453SAnurag.Maskey@Sun.COM int buflen, uint_t cmd)
11533871Syz147064 {
11545895Syz147064 wldp_t *gbuf;
11555895Syz147064 dladm_status_t status = DLADM_STATUS_OK;
11565895Syz147064
11575895Syz147064 if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
11585895Syz147064 return (DLADM_STATUS_NOMEM);
11595895Syz147064
11603871Syz147064 (void) memset(gbuf, 0, MAX_BUF_LEN);
11618453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_legacy_ioctl(handle, linkid, gbuf, cmd,
11628453SAnurag.Maskey@Sun.COM WLDP_BUFSIZE, WLAN_COMMAND, sizeof (wldp_t));
11637663SSowmini.Varadhan@Sun.COM (void) memcpy(buf, gbuf->wldp_buf, buflen);
11645895Syz147064 free(gbuf);
11655895Syz147064 return (status);
11663871Syz147064 }
11673871Syz147064
11685895Syz147064 static dladm_status_t
do_scan(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)11698453SAnurag.Maskey@Sun.COM do_scan(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
11703871Syz147064 {
11718453SAnurag.Maskey@Sun.COM return (do_cmd_ioctl(handle, linkid, buf, buflen, WL_SCAN));
11723871Syz147064 }
11733871Syz147064
11745895Syz147064 static dladm_status_t
do_disconnect(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)11758453SAnurag.Maskey@Sun.COM do_disconnect(dladm_handle_t handle, datalink_id_t linkid, void *buf,
11768453SAnurag.Maskey@Sun.COM int buflen)
11773871Syz147064 {
11788453SAnurag.Maskey@Sun.COM if (do_get_wpamode(handle, linkid, buf, buflen) == 0 &&
11797663SSowmini.Varadhan@Sun.COM ((wl_wpa_t *)(buf))->wpa_flag > 0)
11808453SAnurag.Maskey@Sun.COM (void) wpa_instance_delete(handle, linkid);
11817663SSowmini.Varadhan@Sun.COM
11828453SAnurag.Maskey@Sun.COM return (do_cmd_ioctl(handle, linkid, buf, buflen, WL_DISASSOCIATE));
11833871Syz147064 }
11843871Syz147064
11855895Syz147064 static dladm_status_t
do_get_esslist(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)11868453SAnurag.Maskey@Sun.COM do_get_esslist(dladm_handle_t handle, datalink_id_t linkid, void *buf,
11878453SAnurag.Maskey@Sun.COM int buflen)
11883871Syz147064 {
11898453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_ESS_LIST,
11908453SAnurag.Maskey@Sun.COM buflen, B_FALSE));
11913871Syz147064 }
11923871Syz147064
11935895Syz147064 static dladm_status_t
do_get_bssid(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)11948453SAnurag.Maskey@Sun.COM do_get_bssid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
11953871Syz147064 {
11968453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_BSSID,
11978453SAnurag.Maskey@Sun.COM buflen, B_FALSE));
11983871Syz147064 }
11993871Syz147064
12005895Syz147064 static dladm_status_t
do_get_essid(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12018453SAnurag.Maskey@Sun.COM do_get_essid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
12023871Syz147064 {
12038453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_ESSID,
12048453SAnurag.Maskey@Sun.COM buflen, B_FALSE));
12053871Syz147064 }
12063871Syz147064
12075895Syz147064 static dladm_status_t
do_get_bsstype(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12088453SAnurag.Maskey@Sun.COM do_get_bsstype(dladm_handle_t handle, datalink_id_t linkid, void *buf,
12098453SAnurag.Maskey@Sun.COM int buflen)
12103871Syz147064 {
12118453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_BSSTYPE,
12127663SSowmini.Varadhan@Sun.COM buflen, B_FALSE));
12133871Syz147064 }
12143871Syz147064
12153871Syz147064 static dladm_status_t
do_get_linkstatus(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12168453SAnurag.Maskey@Sun.COM do_get_linkstatus(dladm_handle_t handle, datalink_id_t linkid, void *buf,
12178453SAnurag.Maskey@Sun.COM int buflen)
12183871Syz147064 {
12198453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_LINKSTATUS,
12207663SSowmini.Varadhan@Sun.COM buflen, B_FALSE));
12213871Syz147064 }
12223871Syz147064
12235895Syz147064 static dladm_status_t
do_get_rate(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12248453SAnurag.Maskey@Sun.COM do_get_rate(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
12258453SAnurag.Maskey@Sun.COM {
12268453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf,
12278453SAnurag.Maskey@Sun.COM MAC_PROP_WL_DESIRED_RATES, buflen, B_FALSE));
12288453SAnurag.Maskey@Sun.COM }
12298453SAnurag.Maskey@Sun.COM
12308453SAnurag.Maskey@Sun.COM static dladm_status_t
do_get_authmode(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12318453SAnurag.Maskey@Sun.COM do_get_authmode(dladm_handle_t handle, datalink_id_t linkid, void *buf,
12328453SAnurag.Maskey@Sun.COM int buflen)
12338453SAnurag.Maskey@Sun.COM {
12348453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf,
12358453SAnurag.Maskey@Sun.COM MAC_PROP_WL_AUTH_MODE, buflen, B_FALSE));
12368453SAnurag.Maskey@Sun.COM }
12378453SAnurag.Maskey@Sun.COM
12388453SAnurag.Maskey@Sun.COM static dladm_status_t
do_get_encryption(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12398453SAnurag.Maskey@Sun.COM do_get_encryption(dladm_handle_t handle, datalink_id_t linkid, void *buf,
12408453SAnurag.Maskey@Sun.COM int buflen)
12418453SAnurag.Maskey@Sun.COM {
12428453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf,
12438453SAnurag.Maskey@Sun.COM MAC_PROP_WL_ENCRYPTION, buflen, B_FALSE));
12448453SAnurag.Maskey@Sun.COM }
12458453SAnurag.Maskey@Sun.COM
12468453SAnurag.Maskey@Sun.COM static dladm_status_t
do_get_signal(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12478453SAnurag.Maskey@Sun.COM do_get_signal(dladm_handle_t handle, datalink_id_t linkid, void *buf,
12488453SAnurag.Maskey@Sun.COM int buflen)
12498453SAnurag.Maskey@Sun.COM {
12508453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_RSSI,
12518453SAnurag.Maskey@Sun.COM buflen, B_FALSE));
12528453SAnurag.Maskey@Sun.COM }
12538453SAnurag.Maskey@Sun.COM
12548453SAnurag.Maskey@Sun.COM static dladm_status_t
do_get_mode(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)12558453SAnurag.Maskey@Sun.COM do_get_mode(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
12568453SAnurag.Maskey@Sun.COM {
12578453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_PHY_CONFIG,
12588453SAnurag.Maskey@Sun.COM buflen, B_FALSE));
12598453SAnurag.Maskey@Sun.COM }
12608453SAnurag.Maskey@Sun.COM
12618453SAnurag.Maskey@Sun.COM static dladm_status_t
do_set_bsstype(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_bsstype_t * bsstype)12628453SAnurag.Maskey@Sun.COM do_set_bsstype(dladm_handle_t handle, datalink_id_t linkid,
12638453SAnurag.Maskey@Sun.COM dladm_wlan_bsstype_t *bsstype)
12643871Syz147064 {
12653871Syz147064 wl_bss_type_t ibsstype;
12663871Syz147064
12673871Syz147064 switch (*bsstype) {
12683871Syz147064 case DLADM_WLAN_BSSTYPE_BSS:
12693871Syz147064 ibsstype = WL_BSS_BSS;
12703871Syz147064 break;
12713871Syz147064 case DLADM_WLAN_BSSTYPE_IBSS:
12723871Syz147064 ibsstype = WL_BSS_IBSS;
12733871Syz147064 break;
12743871Syz147064 default:
12753871Syz147064 ibsstype = WL_BSS_ANY;
12763871Syz147064 break;
12773871Syz147064 }
12788453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &ibsstype,
12798453SAnurag.Maskey@Sun.COM MAC_PROP_WL_BSSTYPE, sizeof (ibsstype), B_TRUE));
12803871Syz147064 }
12813871Syz147064
12825895Syz147064 static dladm_status_t
do_set_authmode(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_auth_t * auth)12838453SAnurag.Maskey@Sun.COM do_set_authmode(dladm_handle_t handle, datalink_id_t linkid,
12848453SAnurag.Maskey@Sun.COM dladm_wlan_auth_t *auth)
12853871Syz147064 {
12863871Syz147064 wl_authmode_t auth_mode;
12873871Syz147064
12883871Syz147064 switch (*auth) {
12893871Syz147064 case DLADM_WLAN_AUTH_OPEN:
12903871Syz147064 auth_mode = WL_OPENSYSTEM;
12913871Syz147064 break;
12923871Syz147064 case DLADM_WLAN_AUTH_SHARED:
12933871Syz147064 auth_mode = WL_SHAREDKEY;
12943871Syz147064 break;
12953871Syz147064 default:
12965895Syz147064 return (DLADM_STATUS_NOTSUP);
12973871Syz147064 }
12988453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &auth_mode,
12998453SAnurag.Maskey@Sun.COM MAC_PROP_WL_AUTH_MODE, sizeof (auth_mode), B_TRUE));
13003871Syz147064 }
13013871Syz147064
13025895Syz147064 static dladm_status_t
do_set_encryption(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_secmode_t * secmode)13038453SAnurag.Maskey@Sun.COM do_set_encryption(dladm_handle_t handle, datalink_id_t linkid,
13048453SAnurag.Maskey@Sun.COM dladm_wlan_secmode_t *secmode)
13053871Syz147064 {
13063871Syz147064 wl_encryption_t encryption;
13073871Syz147064
13083871Syz147064 switch (*secmode) {
13093871Syz147064 case DLADM_WLAN_SECMODE_NONE:
13103871Syz147064 encryption = WL_NOENCRYPTION;
13113871Syz147064 break;
13123871Syz147064 case DLADM_WLAN_SECMODE_WEP:
13133871Syz147064 encryption = WL_ENC_WEP;
13143871Syz147064 break;
13154126Szf162725 case DLADM_WLAN_SECMODE_WPA:
13164126Szf162725 return (0);
13173871Syz147064 default:
13185895Syz147064 return (DLADM_STATUS_NOTSUP);
13193871Syz147064 }
13208453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &encryption,
13218453SAnurag.Maskey@Sun.COM MAC_PROP_WL_ENCRYPTION, sizeof (encryption), B_TRUE));
13223871Syz147064 }
13233871Syz147064
13245895Syz147064 static dladm_status_t
do_set_key(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_key_t * keys,uint_t key_count)13258453SAnurag.Maskey@Sun.COM do_set_key(dladm_handle_t handle, datalink_id_t linkid, dladm_wlan_key_t *keys,
13263871Syz147064 uint_t key_count)
13273871Syz147064 {
13283871Syz147064 int i;
13293871Syz147064 wl_wep_key_t *wkp;
13303871Syz147064 wl_wep_key_tab_t wepkey_tab;
13314126Szf162725 dladm_wlan_key_t *kp;
13323871Syz147064
13333871Syz147064 if (key_count == 0 || key_count > MAX_NWEPKEYS || keys == NULL)
13345895Syz147064 return (DLADM_STATUS_BADARG);
13353871Syz147064
13363871Syz147064 (void) memset(wepkey_tab, 0, sizeof (wepkey_tab));
13373871Syz147064 for (i = 0; i < MAX_NWEPKEYS; i++)
13383871Syz147064 wepkey_tab[i].wl_wep_operation = WL_NUL;
13393871Syz147064
13403871Syz147064 for (i = 0; i < key_count; i++) {
13413871Syz147064 kp = &keys[i];
13423871Syz147064 if (kp->wk_idx == 0 || kp->wk_idx > MAX_NWEPKEYS)
13435895Syz147064 return (DLADM_STATUS_BADARG);
13443871Syz147064 if (kp->wk_len != DLADM_WLAN_WEPKEY64_LEN &&
13453871Syz147064 kp->wk_len != DLADM_WLAN_WEPKEY128_LEN)
13465895Syz147064 return (DLADM_STATUS_BADARG);
13473871Syz147064
13483871Syz147064 wkp = &wepkey_tab[kp->wk_idx - 1];
13493871Syz147064 wkp->wl_wep_operation = WL_ADD;
13503871Syz147064 wkp->wl_wep_length = kp->wk_len;
13513871Syz147064 (void) memcpy(wkp->wl_wep_key, kp->wk_val, kp->wk_len);
13523871Syz147064 }
13533871Syz147064
13548453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &wepkey_tab,
13558453SAnurag.Maskey@Sun.COM MAC_PROP_WL_KEY_TAB, sizeof (wepkey_tab), B_TRUE));
13563871Syz147064 }
13573871Syz147064
13585895Syz147064 static dladm_status_t
do_set_essid(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_essid_t * essid)13598453SAnurag.Maskey@Sun.COM do_set_essid(dladm_handle_t handle, datalink_id_t linkid,
13608453SAnurag.Maskey@Sun.COM dladm_wlan_essid_t *essid)
13613871Syz147064 {
13623871Syz147064 wl_essid_t iessid;
13633871Syz147064
13643871Syz147064 (void) memset(&iessid, 0, sizeof (essid));
13653871Syz147064
13663871Syz147064 if (essid != NULL && essid->we_bytes[0] != '\0') {
13673871Syz147064 iessid.wl_essid_length = strlen(essid->we_bytes);
13683871Syz147064 (void) strlcpy(iessid.wl_essid_essid, essid->we_bytes,
13693871Syz147064 sizeof (iessid.wl_essid_essid));
13703871Syz147064 } else {
13715895Syz147064 return (DLADM_STATUS_BADARG);
13725102Syz147064 }
13738453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &iessid, MAC_PROP_WL_ESSID,
13747663SSowmini.Varadhan@Sun.COM sizeof (iessid), B_TRUE));
13753871Syz147064 }
13763871Syz147064
13773871Syz147064 static dladm_status_t
do_set_channel(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_channel_t * channel)13788453SAnurag.Maskey@Sun.COM do_set_channel(dladm_handle_t handle, datalink_id_t linkid,
13798453SAnurag.Maskey@Sun.COM dladm_wlan_channel_t *channel)
13803871Syz147064 {
13813871Syz147064 wl_phy_conf_t phy_conf;
13823871Syz147064
13833871Syz147064 if (*channel > MAX_CHANNEL_NUM)
13845895Syz147064 return (DLADM_STATUS_BADVAL);
13853871Syz147064
13863871Syz147064 (void) memset(&phy_conf, 0xff, sizeof (phy_conf));
13873871Syz147064 phy_conf.wl_phy_dsss_conf.wl_dsss_channel = *channel;
13883871Syz147064
13898453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &phy_conf,
13908453SAnurag.Maskey@Sun.COM MAC_PROP_WL_PHY_CONFIG, sizeof (phy_conf), B_TRUE));
13913871Syz147064 }
13923871Syz147064
13935895Syz147064 static dladm_status_t
do_set_createibss(dladm_handle_t handle,datalink_id_t linkid,boolean_t * create_ibss)13948453SAnurag.Maskey@Sun.COM do_set_createibss(dladm_handle_t handle, datalink_id_t linkid,
13958453SAnurag.Maskey@Sun.COM boolean_t *create_ibss)
13963871Syz147064 {
13973871Syz147064 wl_create_ibss_t cr = (wl_create_ibss_t)(*create_ibss);
13983871Syz147064
13998453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &cr, MAC_PROP_WL_CREATE_IBSS,
14007663SSowmini.Varadhan@Sun.COM sizeof (cr), B_TRUE));
14013871Syz147064 }
14023871Syz147064
14033871Syz147064 static void
generate_essid(dladm_wlan_essid_t * essid)14043871Syz147064 generate_essid(dladm_wlan_essid_t *essid)
14053871Syz147064 {
14063871Syz147064 srandom(gethrtime());
14073871Syz147064 (void) snprintf(essid->we_bytes, DLADM_WLAN_MAX_ESSID_LEN, "%d",
14083871Syz147064 random());
14093871Syz147064 }
14104126Szf162725
14115895Syz147064 static dladm_status_t
do_get_capability(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)14128453SAnurag.Maskey@Sun.COM do_get_capability(dladm_handle_t handle, datalink_id_t linkid, void *buf,
14138453SAnurag.Maskey@Sun.COM int buflen)
14144126Szf162725 {
14158453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_CAPABILITY,
14167663SSowmini.Varadhan@Sun.COM buflen, B_FALSE));
14174126Szf162725 }
14184126Szf162725
14194126Szf162725 static dladm_status_t
do_get_wpamode(dladm_handle_t handle,datalink_id_t linkid,void * buf,int buflen)14208453SAnurag.Maskey@Sun.COM do_get_wpamode(dladm_handle_t handle, datalink_id_t linkid, void *buf,
14218453SAnurag.Maskey@Sun.COM int buflen)
14224126Szf162725 {
14238453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_WPA, buflen,
14247663SSowmini.Varadhan@Sun.COM B_FALSE));
14254126Szf162725 }
14264126Szf162725
14274126Szf162725 dladm_status_t
dladm_wlan_wpa_get_sr(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_ess_t * sr,uint_t escnt,uint_t * estot)14288453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_get_sr(dladm_handle_t handle, datalink_id_t linkid,
14298453SAnurag.Maskey@Sun.COM dladm_wlan_ess_t *sr, uint_t escnt, uint_t *estot)
14304126Szf162725 {
14314126Szf162725 int i, n;
14324126Szf162725 wl_wpa_ess_t *es;
14334126Szf162725 dladm_status_t status;
14344126Szf162725
14357663SSowmini.Varadhan@Sun.COM es = malloc(WLDP_BUFSIZE);
14367663SSowmini.Varadhan@Sun.COM if (es == NULL)
14374126Szf162725 return (DLADM_STATUS_NOMEM);
14384126Szf162725
14398453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, es, MAC_PROP_WL_SCANRESULTS,
14407663SSowmini.Varadhan@Sun.COM WLDP_BUFSIZE, B_FALSE);
14414126Szf162725
14424126Szf162725 if (status == DLADM_STATUS_OK) {
14434126Szf162725 n = (es->count > escnt) ? escnt : es->count;
14444126Szf162725 for (i = 0; i < n; i ++) {
14454126Szf162725 (void) memcpy(sr[i].we_bssid.wb_bytes, es->ess[i].bssid,
14464126Szf162725 DLADM_WLAN_BSSID_LEN);
14474126Szf162725 sr[i].we_ssid_len = es->ess[i].ssid_len;
14484126Szf162725 (void) memcpy(sr[i].we_ssid.we_bytes, es->ess[i].ssid,
14494126Szf162725 es->ess[i].ssid_len);
14504126Szf162725 sr[i].we_wpa_ie_len = es->ess[i].wpa_ie_len;
14514126Szf162725 (void) memcpy(sr[i].we_wpa_ie, es->ess[i].wpa_ie,
14524126Szf162725 es->ess[i].wpa_ie_len);
14534126Szf162725 sr[i].we_freq = es->ess[i].freq;
14544126Szf162725 }
14554126Szf162725 *estot = n;
14564126Szf162725 }
14574126Szf162725
14587663SSowmini.Varadhan@Sun.COM free(es);
14594126Szf162725 return (status);
14604126Szf162725 }
14614126Szf162725
14624126Szf162725 dladm_status_t
dladm_wlan_wpa_set_ie(dladm_handle_t handle,datalink_id_t linkid,uint8_t * wpa_ie,uint_t wpa_ie_len)14638453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_set_ie(dladm_handle_t handle, datalink_id_t linkid,
14648453SAnurag.Maskey@Sun.COM uint8_t *wpa_ie, uint_t wpa_ie_len)
14654126Szf162725 {
14664126Szf162725 wl_wpa_ie_t *ie;
14674126Szf162725 uint_t len;
14684126Szf162725 dladm_status_t status;
14694126Szf162725
14704126Szf162725 if (wpa_ie_len > DLADM_WLAN_MAX_WPA_IE_LEN)
14714126Szf162725 return (DLADM_STATUS_BADARG);
14724126Szf162725 len = sizeof (wl_wpa_ie_t) + wpa_ie_len;
14734126Szf162725 ie = malloc(len);
14744126Szf162725 if (ie == NULL)
14754126Szf162725 return (DLADM_STATUS_NOMEM);
14764126Szf162725
14774126Szf162725 (void) memset(ie, 0, len);
14784126Szf162725 ie->wpa_ie_len = wpa_ie_len;
14794126Szf162725 (void) memcpy(ie->wpa_ie, wpa_ie, wpa_ie_len);
14804126Szf162725
14818453SAnurag.Maskey@Sun.COM status = i_dladm_wlan_param(handle, linkid, ie, MAC_PROP_WL_SETOPTIE,
14828453SAnurag.Maskey@Sun.COM len, B_TRUE);
14834126Szf162725 free(ie);
14844126Szf162725
14854126Szf162725 return (status);
14864126Szf162725 }
14874126Szf162725
14884126Szf162725 dladm_status_t
dladm_wlan_wpa_set_wpa(dladm_handle_t handle,datalink_id_t linkid,boolean_t flag)14898453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_set_wpa(dladm_handle_t handle, datalink_id_t linkid,
14908453SAnurag.Maskey@Sun.COM boolean_t flag)
14914126Szf162725 {
14925895Syz147064 wl_wpa_t wpa;
14934126Szf162725
14944126Szf162725 wpa.wpa_flag = flag;
14958453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &wpa, MAC_PROP_WL_WPA,
14967663SSowmini.Varadhan@Sun.COM sizeof (wpa), B_TRUE));
14974126Szf162725 }
14984126Szf162725
14994126Szf162725 dladm_status_t
dladm_wlan_wpa_del_key(dladm_handle_t handle,datalink_id_t linkid,uint_t key_idx,const dladm_wlan_bssid_t * addr)15008453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_del_key(dladm_handle_t handle, datalink_id_t linkid,
15018453SAnurag.Maskey@Sun.COM uint_t key_idx, const dladm_wlan_bssid_t *addr)
15024126Szf162725 {
15035895Syz147064 wl_del_key_t wk;
15044126Szf162725
15054126Szf162725 wk.idk_keyix = key_idx;
15064126Szf162725 if (addr != NULL)
15074126Szf162725 (void) memcpy((char *)wk.idk_macaddr, addr->wb_bytes,
15084126Szf162725 DLADM_WLAN_BSSID_LEN);
15094126Szf162725
15108453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &wk, MAC_PROP_WL_DELKEY,
15117663SSowmini.Varadhan@Sun.COM sizeof (wk), B_TRUE));
15124126Szf162725 }
15134126Szf162725
15144126Szf162725 dladm_status_t
dladm_wlan_wpa_set_key(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_cipher_t cipher,const dladm_wlan_bssid_t * addr,boolean_t set_tx,uint64_t seq,uint_t key_idx,uint8_t * key,uint_t key_len)15158453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_set_key(dladm_handle_t handle, datalink_id_t linkid,
15168453SAnurag.Maskey@Sun.COM dladm_wlan_cipher_t cipher, const dladm_wlan_bssid_t *addr,
15178453SAnurag.Maskey@Sun.COM boolean_t set_tx, uint64_t seq, uint_t key_idx, uint8_t *key,
15188453SAnurag.Maskey@Sun.COM uint_t key_len)
15194126Szf162725 {
15205895Syz147064 wl_key_t wk;
15214126Szf162725
15224126Szf162725 (void) memset(&wk, 0, sizeof (wl_key_t));
15234126Szf162725 switch (cipher) {
15244126Szf162725 case DLADM_WLAN_CIPHER_WEP:
15254126Szf162725 wk.ik_type = IEEE80211_CIPHER_WEP;
15264126Szf162725 break;
15274126Szf162725 case DLADM_WLAN_CIPHER_TKIP:
15284126Szf162725 wk.ik_type = IEEE80211_CIPHER_TKIP;
15294126Szf162725 break;
15304126Szf162725 case DLADM_WLAN_CIPHER_AES_OCB:
15314126Szf162725 wk.ik_type = IEEE80211_CIPHER_AES_OCB;
15324126Szf162725 break;
15334126Szf162725 case DLADM_WLAN_CIPHER_AES_CCM:
15344126Szf162725 wk.ik_type = IEEE80211_CIPHER_AES_CCM;
15354126Szf162725 break;
15364126Szf162725 case DLADM_WLAN_CIPHER_CKIP:
15374126Szf162725 wk.ik_type = IEEE80211_CIPHER_CKIP;
15384126Szf162725 break;
15394126Szf162725 case DLADM_WLAN_CIPHER_NONE:
15404126Szf162725 wk.ik_type = IEEE80211_CIPHER_NONE;
15414126Szf162725 break;
15424126Szf162725 default:
15434126Szf162725 return (DLADM_STATUS_BADARG);
15444126Szf162725 }
15454126Szf162725 wk.ik_flags = IEEE80211_KEY_RECV;
15464126Szf162725 if (set_tx) {
15474126Szf162725 wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
15484126Szf162725 (void) memcpy(wk.ik_macaddr, addr->wb_bytes,
15494126Szf162725 DLADM_WLAN_BSSID_LEN);
15504126Szf162725 } else
15514126Szf162725 (void) memset(wk.ik_macaddr, 0, DLADM_WLAN_BSSID_LEN);
15524126Szf162725 wk.ik_keyix = key_idx;
15534126Szf162725 wk.ik_keylen = key_len;
15544126Szf162725 (void) memcpy(&wk.ik_keyrsc, &seq, 6); /* only use 48-bit of seq */
15554126Szf162725 (void) memcpy(wk.ik_keydata, key, key_len);
15564126Szf162725
15578453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &wk, MAC_PROP_WL_KEY,
15587663SSowmini.Varadhan@Sun.COM sizeof (wk), B_TRUE));
15594126Szf162725 }
15604126Szf162725
15614126Szf162725 dladm_status_t
dladm_wlan_wpa_set_mlme(dladm_handle_t handle,datalink_id_t linkid,dladm_wlan_mlme_op_t op,dladm_wlan_reason_t reason,dladm_wlan_bssid_t * bssid)15628453SAnurag.Maskey@Sun.COM dladm_wlan_wpa_set_mlme(dladm_handle_t handle, datalink_id_t linkid,
15638453SAnurag.Maskey@Sun.COM dladm_wlan_mlme_op_t op, dladm_wlan_reason_t reason,
15648453SAnurag.Maskey@Sun.COM dladm_wlan_bssid_t *bssid)
15654126Szf162725 {
15664126Szf162725 wl_mlme_t mlme;
15674126Szf162725
15684126Szf162725 (void) memset(&mlme, 0, sizeof (wl_mlme_t));
15694126Szf162725 switch (op) {
15704126Szf162725 case DLADM_WLAN_MLME_ASSOC:
15714126Szf162725 mlme.im_op = IEEE80211_MLME_ASSOC;
15724126Szf162725 break;
15734126Szf162725 case DLADM_WLAN_MLME_DISASSOC:
15744126Szf162725 mlme.im_op = IEEE80211_MLME_DISASSOC;
15754126Szf162725 break;
15764126Szf162725 default:
15774126Szf162725 return (DLADM_STATUS_BADARG);
15784126Szf162725 }
15794126Szf162725 mlme.im_reason = reason;
15804126Szf162725 if (bssid != NULL)
15814126Szf162725 (void) memcpy(mlme.im_macaddr, bssid->wb_bytes,
15824126Szf162725 DLADM_WLAN_BSSID_LEN);
15834126Szf162725
15848453SAnurag.Maskey@Sun.COM return (i_dladm_wlan_param(handle, linkid, &mlme, MAC_PROP_WL_MLME,
15857663SSowmini.Varadhan@Sun.COM sizeof (mlme), B_TRUE));
15864126Szf162725 }
15874126Szf162725
15884126Szf162725 /*
15894126Szf162725 * routines of create instance
15904126Szf162725 */
15914126Szf162725 static scf_propertygroup_t *
add_property_group_to_instance(scf_handle_t * handle,scf_instance_t * instance,const char * pg_name,const char * pg_type)15924126Szf162725 add_property_group_to_instance(scf_handle_t *handle, scf_instance_t *instance,
15934126Szf162725 const char *pg_name, const char *pg_type)
15944126Szf162725 {
15954126Szf162725 scf_propertygroup_t *pg;
15964126Szf162725
15974126Szf162725 pg = scf_pg_create(handle);
15984126Szf162725 if (pg == NULL)
15994126Szf162725 return (NULL);
16004126Szf162725
16014126Szf162725 if (scf_instance_add_pg(instance, pg_name, pg_type, 0, pg) != 0) {
16024126Szf162725 scf_pg_destroy(pg);
16034126Szf162725 return (NULL);
16044126Szf162725 }
16054126Szf162725
16064126Szf162725 return (pg);
16074126Szf162725 }
16084126Szf162725
16095895Syz147064 static dladm_status_t
add_new_property(scf_handle_t * handle,const char * prop_name,scf_type_t type,const char * val,scf_transaction_t * tx)16104126Szf162725 add_new_property(scf_handle_t *handle, const char *prop_name,
16114126Szf162725 scf_type_t type, const char *val, scf_transaction_t *tx)
16124126Szf162725 {
16134126Szf162725 scf_value_t *value = NULL;
16144126Szf162725 scf_transaction_entry_t *entry = NULL;
16154126Szf162725
16164126Szf162725 entry = scf_entry_create(handle);
16174126Szf162725 if (entry == NULL)
16184126Szf162725 goto out;
16194126Szf162725
16204126Szf162725 value = scf_value_create(handle);
16214126Szf162725 if (value == NULL)
16224126Szf162725 goto out;
16234126Szf162725
16244126Szf162725 if (scf_transaction_property_new(tx, entry, prop_name, type) != 0)
16254126Szf162725 goto out;
16264126Szf162725
16274126Szf162725 if (scf_value_set_from_string(value, type, val) != 0)
16284126Szf162725 goto out;
16294126Szf162725
16304126Szf162725 if (scf_entry_add_value(entry, value) != 0)
16314126Szf162725 goto out;
16324126Szf162725
16335895Syz147064 return (DLADM_STATUS_OK);
16344126Szf162725
16354126Szf162725 out:
16364126Szf162725 if (value != NULL)
16374126Szf162725 scf_value_destroy(value);
16384126Szf162725 if (entry != NULL)
16394126Szf162725 scf_entry_destroy(entry);
16404126Szf162725
16415895Syz147064 return (DLADM_STATUS_FAILED);
16424126Szf162725 }
16434126Szf162725
16445895Syz147064 static dladm_status_t
add_pg_method(scf_handle_t * handle,scf_instance_t * instance,const char * pg_name,const char * flags)16454126Szf162725 add_pg_method(scf_handle_t *handle, scf_instance_t *instance,
16464126Szf162725 const char *pg_name, const char *flags)
16474126Szf162725 {
16484126Szf162725 int rv, size;
16495895Syz147064 dladm_status_t status = DLADM_STATUS_FAILED;
16504126Szf162725 char *command = NULL;
16514126Szf162725 scf_transaction_t *tran = NULL;
16524126Szf162725 scf_propertygroup_t *pg;
16534126Szf162725
16544126Szf162725 pg = add_property_group_to_instance(handle, instance,
16554126Szf162725 pg_name, SCF_GROUP_METHOD);
16564126Szf162725 if (pg == NULL)
16574126Szf162725 goto out;
16584126Szf162725
16594126Szf162725 tran = scf_transaction_create(handle);
16604126Szf162725 if (tran == NULL)
16614126Szf162725 goto out;
16624126Szf162725
16634126Szf162725 size = strlen(SVC_METHOD) + strlen(" ") + strlen(flags) + 1;
16644126Szf162725 command = malloc(size);
16654126Szf162725 if (command == NULL) {
16665895Syz147064 status = DLADM_STATUS_NOMEM;
16674126Szf162725 goto out;
16684126Szf162725 }
16694126Szf162725 (void) snprintf(command, size, "%s %s", SVC_METHOD, flags);
16704126Szf162725
16714126Szf162725 do {
16724126Szf162725 if (scf_transaction_start(tran, pg) != 0)
16734126Szf162725 goto out;
16744126Szf162725
16754126Szf162725 if (add_new_property(handle, SCF_PROPERTY_EXEC,
16765895Syz147064 SCF_TYPE_ASTRING, command, tran) != DLADM_STATUS_OK) {
16774126Szf162725 goto out;
16784126Szf162725 }
16794126Szf162725
16804126Szf162725 rv = scf_transaction_commit(tran);
16814126Szf162725 switch (rv) {
16824126Szf162725 case 1:
16835895Syz147064 status = DLADM_STATUS_OK;
16844126Szf162725 goto out;
16854126Szf162725 case 0:
16864126Szf162725 scf_transaction_destroy_children(tran);
16874126Szf162725 if (scf_pg_update(pg) == -1) {
16884126Szf162725 goto out;
16894126Szf162725 }
16904126Szf162725 break;
16914126Szf162725 case -1:
16924126Szf162725 default:
16934126Szf162725 goto out;
16944126Szf162725 }
16954126Szf162725 } while (rv == 0);
16964126Szf162725
16974126Szf162725 out:
16984126Szf162725 if (tran != NULL) {
16994126Szf162725 scf_transaction_destroy_children(tran);
17004126Szf162725 scf_transaction_destroy(tran);
17014126Szf162725 }
17024126Szf162725
17034126Szf162725 if (pg != NULL)
17044126Szf162725 scf_pg_destroy(pg);
17054126Szf162725
17064126Szf162725 if (command != NULL)
17074126Szf162725 free(command);
17084126Szf162725
17094126Szf162725 return (status);
17104126Szf162725 }
17114126Szf162725
17125895Syz147064 static dladm_status_t
do_create_instance(scf_handle_t * handle,scf_service_t * svc,const char * instance_name,const char * command)17134126Szf162725 do_create_instance(scf_handle_t *handle, scf_service_t *svc,
17144126Szf162725 const char *instance_name, const char *command)
17154126Szf162725 {
17165895Syz147064 dladm_status_t status = DLADM_STATUS_FAILED;
17174126Szf162725 char *buf;
17184126Szf162725 ssize_t max_fmri_len;
17194126Szf162725 scf_instance_t *instance;
17204126Szf162725
17214126Szf162725 instance = scf_instance_create(handle);
17224126Szf162725 if (instance == NULL)
17234126Szf162725 goto out;
17244126Szf162725
17254126Szf162725 if (scf_service_add_instance(svc, instance_name, instance) != 0) {
17264126Szf162725 if (scf_error() == SCF_ERROR_EXISTS)
17274126Szf162725 /* Let the caller deal with the duplicate instance */
17285895Syz147064 status = DLADM_STATUS_EXIST;
17294126Szf162725 goto out;
17304126Szf162725 }
17314126Szf162725
17324126Szf162725 if (add_pg_method(handle, instance, "start",
17335895Syz147064 command) != DLADM_STATUS_OK) {
17344126Szf162725 goto out;
17354126Szf162725 }
17364126Szf162725
17374126Szf162725 /* enabling the instance */
17384126Szf162725 max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
17394126Szf162725 if ((buf = malloc(max_fmri_len + 1)) == NULL)
17404126Szf162725 goto out;
17414126Szf162725
17424126Szf162725 if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
17434126Szf162725 if ((smf_disable_instance(buf, 0) != 0) ||
17444126Szf162725 (smf_enable_instance(buf, SMF_TEMPORARY) != 0)) {
17454126Szf162725 goto out;
17464126Szf162725 }
17475895Syz147064 status = DLADM_STATUS_OK;
17484126Szf162725 }
17494126Szf162725
17504126Szf162725 out:
17514126Szf162725 if (instance != NULL)
17524126Szf162725 scf_instance_destroy(instance);
17534126Szf162725 return (status);
17544126Szf162725 }
17554126Szf162725
17565895Syz147064 static dladm_status_t
create_instance(const char * instance_name,const char * command)17574126Szf162725 create_instance(const char *instance_name, const char *command)
17584126Szf162725 {
17595895Syz147064 dladm_status_t status = DLADM_STATUS_FAILED;
17604126Szf162725 scf_service_t *svc = NULL;
17614126Szf162725 scf_handle_t *handle = NULL;
17624126Szf162725
17634126Szf162725 handle = scf_handle_create(SCF_VERSION);
17644126Szf162725 if (handle == NULL)
17654126Szf162725 goto out;
17664126Szf162725
17674126Szf162725 if (scf_handle_bind(handle) == -1)
17684126Szf162725 goto out;
17694126Szf162725
17704126Szf162725 if ((svc = scf_service_create(handle)) == NULL)
17714126Szf162725 goto out;
17724126Szf162725
17734126Szf162725 if (scf_handle_decode_fmri(handle, SERVICE_NAME, NULL, svc,
17744126Szf162725 NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0)
17754126Szf162725 goto out;
17764126Szf162725
17774126Szf162725 status = do_create_instance(handle, svc, instance_name, command);
17784126Szf162725
17794126Szf162725 out:
17804126Szf162725 if (svc != NULL)
17814126Szf162725 scf_service_destroy(svc);
17824126Szf162725
17834126Szf162725 if (handle != NULL) {
17844126Szf162725 (void) scf_handle_unbind(handle);
17854126Szf162725 scf_handle_destroy(handle);
17864126Szf162725 }
17874126Szf162725
17884126Szf162725 return (status);
17894126Szf162725 }
17904126Szf162725
17914126Szf162725 /*
17924126Szf162725 * routines of delete instance
17934126Szf162725 */
17944126Szf162725 #define DEFAULT_TIMEOUT 60000000
17954126Szf162725 #define INIT_WAIT_USECS 50000
17964126Szf162725
17974126Szf162725 static void
wait_until_disabled(scf_handle_t * handle,char * fmri)17984126Szf162725 wait_until_disabled(scf_handle_t *handle, char *fmri)
17994126Szf162725 {
18004126Szf162725 char *state;
18014126Szf162725 useconds_t max;
18024126Szf162725 useconds_t usecs;
18034126Szf162725 uint64_t *cp = NULL;
18044126Szf162725 scf_simple_prop_t *sp = NULL;
18054126Szf162725
18064126Szf162725 max = DEFAULT_TIMEOUT;
18074126Szf162725
18084126Szf162725 if (((sp = scf_simple_prop_get(handle, fmri, "stop",
18094126Szf162725 SCF_PROPERTY_TIMEOUT)) != NULL) &&
18104126Szf162725 ((cp = scf_simple_prop_next_count(sp)) != NULL) && (*cp != 0))
18114126Szf162725 max = (*cp) * 1000000; /* convert to usecs */
18124126Szf162725
18134126Szf162725 if (sp != NULL)
18144126Szf162725 scf_simple_prop_free(sp);
18154126Szf162725
18164126Szf162725 for (usecs = INIT_WAIT_USECS; max > 0; max -= usecs) {
18174126Szf162725 /* incremental wait */
18184126Szf162725 usecs *= 2;
18194126Szf162725 usecs = (usecs > max) ? max : usecs;
18204126Szf162725
18214126Szf162725 (void) usleep(usecs);
18224126Szf162725
18234126Szf162725 /* Check state after the wait */
18244126Szf162725 if ((state = smf_get_state(fmri)) != NULL) {
18254126Szf162725 if (strcmp(state, "disabled") == 0)
18264126Szf162725 return;
18274126Szf162725 }
18284126Szf162725 }
18294126Szf162725 }
18304126Szf162725
18315895Syz147064 static dladm_status_t
delete_instance(const char * instance_name)18324126Szf162725 delete_instance(const char *instance_name)
18334126Szf162725 {
18345895Syz147064 dladm_status_t status = DLADM_STATUS_FAILED;
18354126Szf162725 char *buf;
18364126Szf162725 ssize_t max_fmri_len;
18374126Szf162725 scf_scope_t *scope = NULL;
18384126Szf162725 scf_service_t *svc = NULL;
18394126Szf162725 scf_handle_t *handle = NULL;
18404126Szf162725 scf_instance_t *instance;
18414126Szf162725
18424126Szf162725 handle = scf_handle_create(SCF_VERSION);
18434126Szf162725 if (handle == NULL)
18444126Szf162725 goto out;
18454126Szf162725
18464126Szf162725 if (scf_handle_bind(handle) == -1)
18474126Szf162725 goto out;
18484126Szf162725
18494126Szf162725 if ((scope = scf_scope_create(handle)) == NULL)
18504126Szf162725 goto out;
18514126Szf162725
18524126Szf162725 if ((svc = scf_service_create(handle)) == NULL)
18534126Szf162725 goto out;
18544126Szf162725
18554126Szf162725 if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1)
18564126Szf162725 goto out;
18574126Szf162725
18584126Szf162725 if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0)
18594126Szf162725 goto out;
18604126Szf162725
18614126Szf162725 instance = scf_instance_create(handle);
18624126Szf162725 if (instance == NULL)
18634126Szf162725 goto out;
18644126Szf162725
18654126Szf162725 if (scf_service_get_instance(svc, instance_name, instance) != 0) {
18664126Szf162725 scf_error_t scf_errnum = scf_error();
18674126Szf162725
18684126Szf162725 if (scf_errnum == SCF_ERROR_NOT_FOUND)
18695895Syz147064 status = DLADM_STATUS_OK;
18704126Szf162725
18714126Szf162725 scf_instance_destroy(instance);
18724126Szf162725 goto out;
18734126Szf162725 }
18744126Szf162725
18754126Szf162725 max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
18764126Szf162725 if ((buf = malloc(max_fmri_len + 1)) == NULL) {
18774126Szf162725 scf_instance_destroy(instance);
18784126Szf162725 goto out;
18794126Szf162725 }
18804126Szf162725
18814126Szf162725 if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
18824126Szf162725 char *state;
18834126Szf162725
18844126Szf162725 state = smf_get_state(buf);
18854126Szf162725 if (state && (strcmp(state, SCF_STATE_STRING_ONLINE) == 0 ||
18864126Szf162725 strcmp(state, SCF_STATE_STRING_DEGRADED) == 0)) {
18874126Szf162725 if (smf_disable_instance(buf, 0) == 0) {
18884126Szf162725 /*
18894126Szf162725 * Wait for some time till timeout to avoid
18904126Szf162725 * a race with scf_instance_delete() below.
18914126Szf162725 */
18924126Szf162725 wait_until_disabled(handle, buf);
18934126Szf162725 }
18944126Szf162725 }
18954126Szf162725 }
18964126Szf162725
18974126Szf162725 if (scf_instance_delete(instance) != 0) {
18984126Szf162725 scf_instance_destroy(instance);
18994126Szf162725 goto out;
19004126Szf162725 }
19014126Szf162725
19024126Szf162725 scf_instance_destroy(instance);
19034126Szf162725
19045895Syz147064 status = DLADM_STATUS_OK;
19054126Szf162725
19064126Szf162725 out:
19074126Szf162725 if (svc != NULL)
19084126Szf162725 scf_service_destroy(svc);
19094126Szf162725
19104126Szf162725 if (scope != NULL)
19114126Szf162725 scf_scope_destroy(scope);
19124126Szf162725
19134126Szf162725 if (handle != NULL) {
19144126Szf162725 (void) scf_handle_unbind(handle);
19154126Szf162725 scf_handle_destroy(handle);
19164126Szf162725 }
19174126Szf162725
19184126Szf162725 return (status);
19194126Szf162725 }
19204126Szf162725
19215895Syz147064 static dladm_status_t
wpa_instance_create(dladm_handle_t handle,datalink_id_t linkid,void * key)19228453SAnurag.Maskey@Sun.COM wpa_instance_create(dladm_handle_t handle, datalink_id_t linkid, void *key)
19234126Szf162725 {
19245895Syz147064 dladm_status_t status = DLADM_STATUS_FAILED;
19254126Szf162725 char *command = NULL;
19264126Szf162725 char *wk_name = ((dladm_wlan_key_t *)key)->wk_name;
19274126Szf162725 int size;
19285895Syz147064 char instance_name[MAXLINKNAMELEN];
19295895Syz147064
19305895Syz147064 /*
19315895Syz147064 * Use the link name as the instance name of the network/wpad service.
19325895Syz147064 */
19338453SAnurag.Maskey@Sun.COM status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
19348453SAnurag.Maskey@Sun.COM instance_name, sizeof (instance_name));
19355895Syz147064 if (status != DLADM_STATUS_OK)
19365895Syz147064 goto out;
19374126Szf162725
19384126Szf162725 size = strlen(instance_name) + strlen(" -i -k ") + strlen(wk_name) + 1;
19394126Szf162725 command = malloc(size);
19404126Szf162725 if (command == NULL) {
19415895Syz147064 status = DLADM_STATUS_NOMEM;
19424126Szf162725 goto out;
19434126Szf162725 }
19444126Szf162725 (void) snprintf(command, size, "-i %s -k %s", instance_name, wk_name);
19454126Szf162725
19464126Szf162725 status = create_instance(instance_name, command);
19475895Syz147064 if (status == DLADM_STATUS_EXIST) {
19484126Szf162725 /*
19494126Szf162725 * Delete the existing instance and create a new instance
19504126Szf162725 * with the supplied arguments.
19514126Szf162725 */
19524126Szf162725 if ((status = delete_instance(instance_name)) ==
19535895Syz147064 DLADM_STATUS_OK) {
19544126Szf162725 status = create_instance(instance_name, command);
19554126Szf162725 }
19564126Szf162725 }
19574126Szf162725
19584126Szf162725 out:
19594126Szf162725 if (command != NULL)
19604126Szf162725 free(command);
19614126Szf162725
19624126Szf162725 return (status);
19634126Szf162725 }
19644126Szf162725
19655895Syz147064 static dladm_status_t
wpa_instance_delete(dladm_handle_t handle,datalink_id_t linkid)19668453SAnurag.Maskey@Sun.COM wpa_instance_delete(dladm_handle_t handle, datalink_id_t linkid)
19674126Szf162725 {
19685895Syz147064 char instance_name[MAXLINKNAMELEN];
19694126Szf162725
19705895Syz147064 /*
19715895Syz147064 * Get the instance name of the network/wpad service (the same as
19725895Syz147064 * the link name).
19735895Syz147064 */
19748453SAnurag.Maskey@Sun.COM if (dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
19758453SAnurag.Maskey@Sun.COM instance_name, sizeof (instance_name)) != DLADM_STATUS_OK)
19765895Syz147064 return (DLADM_STATUS_FAILED);
19774126Szf162725
19785895Syz147064 return (delete_instance(instance_name));
19794126Szf162725 }
1980