diff options
author | Sowmini Varadhan <Sowmini.Varadhan@Sun.COM> | 2008-09-23 08:53:55 -0400 |
---|---|---|
committer | Sowmini Varadhan <Sowmini.Varadhan@Sun.COM> | 2008-09-23 08:53:55 -0400 |
commit | bcb5c89da22515e2ccf139578bad3caebcd716ad (patch) | |
tree | 73b9b6fd6d4f922320824ca7e61d7e71c61fbb7e /usr/src/lib/libdladm | |
parent | fc6df3bdbec9a23827d64460d15c987a4497ef35 (diff) | |
download | illumos-joyent-bcb5c89da22515e2ccf139578bad3caebcd716ad.tar.gz |
6721363 concise 'show-linkprop' default output
6744703 wifi property ioctls should try the Brussels path through DLD_CONTROL_DEV first.
Diffstat (limited to 'usr/src/lib/libdladm')
-rw-r--r-- | usr/src/lib/libdladm/common/libdlwlan.c | 368 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdlwlan_impl.h | 13 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/linkprop.c | 519 |
3 files changed, 548 insertions, 352 deletions
diff --git a/usr/src/lib/libdladm/common/libdlwlan.c b/usr/src/lib/libdladm/common/libdlwlan.c index ee46fca3ee..9694c5350b 100644 --- a/usr/src/lib/libdladm/common/libdlwlan.c +++ b/usr/src/lib/libdladm/common/libdlwlan.c @@ -46,18 +46,18 @@ static dladm_status_t wpa_instance_create(datalink_id_t, void *); static dladm_status_t wpa_instance_delete(datalink_id_t); -static dladm_status_t do_get_bsstype(datalink_id_t, wldp_t *); -static dladm_status_t do_get_essid(datalink_id_t, wldp_t *); -static dladm_status_t do_get_bssid(datalink_id_t, wldp_t *); -static dladm_status_t do_get_signal(datalink_id_t, wldp_t *); -static dladm_status_t do_get_encryption(datalink_id_t, wldp_t *); -static dladm_status_t do_get_authmode(datalink_id_t, wldp_t *); -static dladm_status_t do_get_linkstatus(datalink_id_t, wldp_t *); -static dladm_status_t do_get_esslist(datalink_id_t, wldp_t *); -static dladm_status_t do_get_rate(datalink_id_t, wldp_t *); -static dladm_status_t do_get_mode(datalink_id_t, wldp_t *); -static dladm_status_t do_get_capability(datalink_id_t, wldp_t *); -static dladm_status_t do_get_wpamode(datalink_id_t, wldp_t *); +static dladm_status_t do_get_bsstype(datalink_id_t, void *, int); +static dladm_status_t do_get_essid(datalink_id_t, void *, int); +static dladm_status_t do_get_bssid(datalink_id_t, void *, int); +static dladm_status_t do_get_signal(datalink_id_t, void *, int); +static dladm_status_t do_get_encryption(datalink_id_t, void *, int); +static dladm_status_t do_get_authmode(datalink_id_t, void *, int); +static dladm_status_t do_get_linkstatus(datalink_id_t, void *, int); +static dladm_status_t do_get_esslist(datalink_id_t, void *, int); +static dladm_status_t do_get_rate(datalink_id_t, void *, int); +static dladm_status_t do_get_mode(datalink_id_t, void *, int); +static dladm_status_t do_get_capability(datalink_id_t, void *, int); +static dladm_status_t do_get_wpamode(datalink_id_t, void *, int); static dladm_status_t do_set_bsstype(datalink_id_t, dladm_wlan_bsstype_t *); static dladm_status_t do_set_authmode(datalink_id_t, dladm_wlan_auth_t *); @@ -68,10 +68,11 @@ static dladm_status_t do_set_createibss(datalink_id_t, boolean_t *); static dladm_status_t do_set_key(datalink_id_t, dladm_wlan_key_t *, uint_t); static dladm_status_t do_set_channel(datalink_id_t, dladm_wlan_channel_t *); -static dladm_status_t do_scan(datalink_id_t, wldp_t *); -static dladm_status_t do_connect(datalink_id_t, wldp_t *, dladm_wlan_attr_t *, - boolean_t, void *, uint_t, int); -static dladm_status_t do_disconnect(datalink_id_t, wldp_t *); +static dladm_status_t do_scan(datalink_id_t, void *, int); +static dladm_status_t do_connect(datalink_id_t, void *, int, + dladm_wlan_attr_t *, boolean_t, void *, uint_t, + int); +static dladm_status_t do_disconnect(datalink_id_t, void *, int); static boolean_t find_val_by_name(const char *, val_desc_t *, uint_t, uint_t *); static boolean_t find_name_by_val(uint_t, val_desc_t *, uint_t, char **); @@ -116,8 +117,7 @@ static val_desc_t bsstype_vals[] = { { "any", DLADM_WLAN_BSSTYPE_ANY } }; -#define IS_CONNECTED(gbuf) \ - ((*(wl_linkstatus_t *)((gbuf)->wldp_buf) == WL_CONNECTED)) +#define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) static dladm_status_t dladm_wlan_wlresult2status(wldp_t *gbuf) @@ -237,24 +237,20 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg, int i; uint32_t count; wl_ess_conf_t *wlp; - wldp_t *gbuf = NULL; + wl_ess_list_t *wls = NULL; + char buf[WLDP_BUFSIZE]; + wl_linkstatus_t wl_status; dladm_wlan_attr_t wlattr; dladm_status_t status; - boolean_t connected; if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK) goto done; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = DLADM_STATUS_NOMEM; - goto done; - } - - if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK) + status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status)); + if (status != DLADM_STATUS_OK) goto done; - connected = IS_CONNECTED(gbuf); - if ((status = do_scan(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_scan(linkid, buf, sizeof (buf))) != DLADM_STATUS_OK) goto done; if (func == NULL) { @@ -262,11 +258,18 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg, goto done; } - if ((status = do_get_esslist(linkid, gbuf)) != DLADM_STATUS_OK) + wls = malloc(WLDP_BUFSIZE); + if (wls == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + if ((status = do_get_esslist(linkid, wls, WLDP_BUFSIZE)) + != DLADM_STATUS_OK) goto done; - wlp = ((wl_ess_list_t *)gbuf->wldp_buf)->wl_ess_list_ess; - count = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num; + wlp = wls->wl_ess_list_ess; + count = wls->wl_ess_list_num; for (i = 0; i < count; i++, wlp++) { fill_wlan_attr(wlp, &wlattr); @@ -274,17 +277,18 @@ dladm_wlan_scan(datalink_id_t linkid, void *arg, break; } - if (!connected) { - status = do_get_linkstatus(linkid, gbuf); + if (wl_status != WL_CONNECTED) { + status = do_get_linkstatus(linkid, &wl_status, + sizeof (&wl_status)); if (status != DLADM_STATUS_OK) goto done; - if (IS_CONNECTED(gbuf)) - (void) do_disconnect(linkid, gbuf); + if (wl_status == WL_CONNECTED) + (void) do_disconnect(linkid, buf, sizeof (buf)); } status = DLADM_STATUS_OK; done: - free(gbuf); + free(wls); return (status); } @@ -398,8 +402,9 @@ append: #define IEEE80211_C_WPA 0x01800000 static dladm_status_t -do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp, - boolean_t create_ibss, void *keys, uint_t key_count, int timeout) +do_connect(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) { dladm_wlan_secmode_t secmode; dladm_wlan_auth_t authmode; @@ -410,6 +415,7 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp, dladm_wlan_channel_t channel; hrtime_t start; wl_capability_t *caps; + wl_linkstatus_t wl_status; if ((attrp->wa_valid & DLADM_WLAN_ATTR_CHANNEL) != 0) { channel = attrp->wa_channel; @@ -451,10 +457,10 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp, status = DLADM_STATUS_BADARG; goto fail; } - status = do_get_capability(linkid, gbuf); + status = do_get_capability(linkid, buf, bufsize); if (status != DLADM_STATUS_OK) goto fail; - caps = (wl_capability_t *)(gbuf->wldp_buf); + caps = (wl_capability_t *)buf; if ((caps->caps & IEEE80211_C_WPA) == 0) return (DLADM_STATUS_NOTSUP); } @@ -496,11 +502,12 @@ do_connect(datalink_id_t linkid, wldp_t *gbuf, dladm_wlan_attr_t *attrp, start = gethrtime(); for (;;) { - status = do_get_linkstatus(linkid, gbuf); + status = do_get_linkstatus(linkid, &wl_status, + sizeof (wl_status)); if (status != DLADM_STATUS_OK) goto fail; - if (IS_CONNECTED(gbuf)) + if (wl_status == WL_CONNECTED) break; (void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE); @@ -520,23 +527,22 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp, int timeout, void *keys, uint_t key_count, uint_t flags) { int i; - wldp_t *gbuf = NULL; + char buf[WLDP_BUFSIZE]; connect_state_t state = {0, NULL, NULL}; attr_node_t *nodep = NULL; boolean_t create_ibss, set_authmode; dladm_wlan_attr_t **wl_list = NULL; dladm_status_t status; + wl_linkstatus_t wl_status; if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK) return (status); - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) - return (DLADM_STATUS_NOMEM); - - if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status))) + != DLADM_STATUS_OK) goto done; - if (IS_CONNECTED(gbuf)) { + if (wl_status == WL_CONNECTED) { status = DLADM_STATUS_ISCONN; goto done; } @@ -551,8 +557,8 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp, if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0 || (create_ibss && attrp != NULL && (attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0)) { - status = do_connect(linkid, gbuf, attrp, create_ibss, keys, - key_count, timeout); + status = do_connect(linkid, buf, sizeof (buf), attrp, + create_ibss, keys, key_count, timeout); goto done; } @@ -569,8 +575,8 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp, status = DLADM_STATUS_NOTFOUND; goto done; } - status = do_connect(linkid, gbuf, attrp, create_ibss, keys, - key_count, timeout); + status = do_connect(linkid, buf, sizeof (buf), + attrp, create_ibss, keys, key_count, timeout); goto done; } @@ -591,30 +597,29 @@ dladm_wlan_connect(datalink_id_t linkid, dladm_wlan_attr_t *attrp, for (i = 0; i < state.cs_count; i++) { dladm_wlan_attr_t *ap = wl_list[i]; - status = do_connect(linkid, gbuf, ap, create_ibss, keys, - key_count, timeout); + status = do_connect(linkid, buf, sizeof (buf), + ap, create_ibss, keys, key_count, timeout); if (status == DLADM_STATUS_OK) break; if (!set_authmode) { ap->wa_auth = DLADM_WLAN_AUTH_SHARED; ap->wa_valid |= DLADM_WLAN_ATTR_AUTH; - status = do_connect(linkid, gbuf, ap, create_ibss, keys, - key_count, timeout); + status = do_connect(linkid, buf, sizeof (buf), + ap, create_ibss, keys, key_count, timeout); if (status == DLADM_STATUS_OK) break; } } done: if ((status != DLADM_STATUS_OK) && (status != DLADM_STATUS_ISCONN)) - (void) do_disconnect(linkid, gbuf); + (void) do_disconnect(linkid, buf, sizeof (buf)); while (state.cs_list != NULL) { nodep = state.cs_list; state.cs_list = nodep->an_next; free(nodep); } - free(gbuf); free(wl_list); return (status); } @@ -622,53 +627,54 @@ done: dladm_status_t dladm_wlan_disconnect(datalink_id_t linkid) { - wldp_t *gbuf; + char buf[WLDP_BUFSIZE]; dladm_status_t status; + wl_linkstatus_t wl_status; if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK) return (status); - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = DLADM_STATUS_NOMEM; - goto done; - } - - if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status))) + != DLADM_STATUS_OK) goto done; - if (!IS_CONNECTED(gbuf)) { + if (wl_status != WL_CONNECTED) { status = DLADM_STATUS_NOTCONN; goto done; } - if ((status = do_disconnect(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_disconnect(linkid, buf, sizeof (buf))) + != DLADM_STATUS_OK) goto done; - if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status))) + != DLADM_STATUS_OK) goto done; - if (IS_CONNECTED(gbuf)) { + if (wl_status == WL_CONNECTED) { status = DLADM_STATUS_FAILED; goto done; } status = DLADM_STATUS_OK; done: - free(gbuf); return (status); } dladm_status_t dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) { - wldp_t *gbuf = NULL; wl_rssi_t signal; wl_bss_type_t bsstype; wl_authmode_t authmode; wl_encryption_t encryption; - wl_rates_t *ratesp; + wl_rates_t *ratesp = NULL; dladm_wlan_attr_t *wl_attrp; dladm_status_t status; + char buf[WLDP_BUFSIZE]; + wl_essid_t wls; + wl_phy_conf_t wl_phy_conf; + wl_linkstatus_t wl_status; if (attrp == NULL) return (DLADM_STATUS_BADARG); @@ -676,37 +682,33 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) if ((status = dladm_wlan_validate(linkid)) != DLADM_STATUS_OK) goto done; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = DLADM_STATUS_NOMEM; - goto done; - } - (void) memset(attrp, 0, sizeof (*attrp)); wl_attrp = &attrp->la_wlan_attr; - if ((status = do_get_linkstatus(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_linkstatus(linkid, &wl_status, sizeof (wl_status))) + != DLADM_STATUS_OK) goto done; attrp->la_valid |= DLADM_WLAN_LINKATTR_STATUS; - if (!IS_CONNECTED(gbuf)) + if (wl_status != WL_CONNECTED) attrp->la_status = DLADM_WLAN_LINK_DISCONNECTED; else attrp->la_status = DLADM_WLAN_LINK_CONNECTED; - if ((status = do_get_essid(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_essid(linkid, &wls, sizeof (wls))) + != DLADM_STATUS_OK) goto done; - (void) strlcpy(wl_attrp->wa_essid.we_bytes, - ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid, + (void) strlcpy(wl_attrp->wa_essid.we_bytes, wls.wl_essid_essid, DLADM_WLAN_MAX_ESSID_LEN); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID; - if ((status = do_get_bssid(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_bssid(linkid, buf, sizeof (buf))) + != DLADM_STATUS_OK) goto done; - (void) memcpy(wl_attrp->wa_bssid.wb_bytes, gbuf->wldp_buf, - DLADM_WLAN_BSSID_LEN); + (void) memcpy(wl_attrp->wa_bssid.wb_bytes, buf, DLADM_WLAN_BSSID_LEN); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID; @@ -716,10 +718,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) goto done; } - if ((status = do_get_encryption(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_encryption(linkid, &encryption, + sizeof (encryption))) != DLADM_STATUS_OK) goto done; - encryption = *(wl_encryption_t *)(gbuf->wldp_buf); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE; switch (encryption) { @@ -737,17 +739,23 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) break; } - if ((status = do_get_signal(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_signal(linkid, &signal, sizeof (signal))) + != DLADM_STATUS_OK) goto done; - signal = *(wl_rssi_t *)(gbuf->wldp_buf); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH; wl_attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(signal); - if ((status = do_get_rate(linkid, gbuf)) != DLADM_STATUS_OK) + ratesp = malloc(WLDP_BUFSIZE); + if (ratesp == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + if ((status = do_get_rate(linkid, ratesp, WLDP_BUFSIZE)) + != DLADM_STATUS_OK) goto done; - ratesp = (wl_rates_t *)(gbuf->wldp_buf); if (ratesp->wl_rates_num > 0) { uint_t i, r = 0; @@ -759,10 +767,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED; } - if ((status = do_get_authmode(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_authmode(linkid, &authmode, + sizeof (authmode))) != DLADM_STATUS_OK) goto done; - authmode = *(wl_authmode_t *)(gbuf->wldp_buf); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH; switch (authmode) { @@ -777,10 +785,10 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) break; } - if ((status = do_get_bsstype(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_bsstype(linkid, &bsstype, + sizeof (bsstype))) != DLADM_STATUS_OK) goto done; - bsstype = *(wl_bss_type_t *)(gbuf->wldp_buf); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; switch (bsstype) { @@ -798,10 +806,11 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) break; } - if ((status = do_get_mode(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_mode(linkid, &wl_phy_conf, + sizeof (wl_phy_conf))) != DLADM_STATUS_OK) goto done; - wl_attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)(gbuf->wldp_buf)); + wl_attrp->wa_mode = do_convert_mode(&wl_phy_conf); wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE; if (wl_attrp->wa_mode != DLADM_WLAN_MODE_NONE) wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE; @@ -810,7 +819,7 @@ dladm_wlan_get_linkattr(datalink_id_t linkid, dladm_wlan_linkattr_t *attrp) status = DLADM_STATUS_OK; done: - free(gbuf); + free(ratesp); return (status); } @@ -1047,8 +1056,8 @@ dladm_wlan_str2linkstatus(const char *str, dladm_wlan_linkstatus_t *linkstatus) } dladm_status_t -i_dladm_wlan_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, size_t len, - uint_t cmd, size_t cmdlen) +i_dladm_wlan_legacy_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, + size_t len, uint_t cmd, size_t cmdlen) { char linkname[MAXPATHLEN]; int fd, rc; @@ -1105,17 +1114,8 @@ i_dladm_wlan_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, size_t len, return (status); } -dladm_status_t -i_dladm_wlan_get_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id) -{ - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (i_dladm_wlan_ioctl(linkid, gbuf, id, MAX_BUF_LEN, - WLAN_GET_PARAM, MAX_BUF_LEN)); -} - -dladm_status_t -i_dladm_wlan_set_ioctl(datalink_id_t linkid, uint_t id, void *buf, - uint_t buflen) +static dladm_status_t +do_cmd_ioctl(datalink_id_t linkid, void *buf, int buflen, uint_t cmd) { wldp_t *gbuf; dladm_status_t status = DLADM_STATUS_OK; @@ -1124,99 +1124,97 @@ i_dladm_wlan_set_ioctl(datalink_id_t linkid, uint_t id, void *buf, return (DLADM_STATUS_NOMEM); (void) memset(gbuf, 0, MAX_BUF_LEN); - (void) memcpy(gbuf->wldp_buf, buf, buflen); - buflen += WIFI_BUF_OFFSET; - status = i_dladm_wlan_ioctl(linkid, gbuf, id, buflen, - WLAN_SET_PARAM, buflen); - + status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, cmd, WLDP_BUFSIZE, + WLAN_COMMAND, sizeof (wldp_t)); + (void) memcpy(buf, gbuf->wldp_buf, buflen); free(gbuf); return (status); } static dladm_status_t -do_cmd_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t cmd) +do_scan(datalink_id_t linkid, void *buf, int buflen) { - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (i_dladm_wlan_ioctl(linkid, gbuf, cmd, sizeof (wldp_t), - WLAN_COMMAND, sizeof (wldp_t))); + return (do_cmd_ioctl(linkid, buf, buflen, WL_SCAN)); } static dladm_status_t -do_scan(datalink_id_t linkid, wldp_t *gbuf) +do_disconnect(datalink_id_t linkid, void *buf, int buflen) { - return (do_cmd_ioctl(linkid, gbuf, WL_SCAN)); -} - -static dladm_status_t -do_disconnect(datalink_id_t linkid, wldp_t *gbuf) -{ - if (do_get_wpamode(linkid, gbuf) == 0 && - ((wl_wpa_t *)(gbuf->wldp_buf))->wpa_flag > 0) + if (do_get_wpamode(linkid, buf, buflen) == 0 && + ((wl_wpa_t *)(buf))->wpa_flag > 0) (void) wpa_instance_delete(linkid); - return (do_cmd_ioctl(linkid, gbuf, WL_DISASSOCIATE)); + return (do_cmd_ioctl(linkid, buf, buflen, WL_DISASSOCIATE)); } static dladm_status_t -do_get_esslist(datalink_id_t linkid, wldp_t *gbuf) +do_get_esslist(datalink_id_t linkid, void *buf, int buflen) { - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (i_dladm_wlan_ioctl(linkid, gbuf, WL_ESS_LIST, MAX_BUF_LEN, - WLAN_GET_PARAM, sizeof (wldp_t))); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ESS_LIST, buflen, + B_FALSE)); } static dladm_status_t -do_get_bssid(datalink_id_t linkid, wldp_t *gbuf) +do_get_bssid(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_BSSID)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_BSSID, buflen, + B_FALSE)); } static dladm_status_t -do_get_essid(datalink_id_t linkid, wldp_t *gbuf) +do_get_essid(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_ESSID)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ESSID, buflen, + B_FALSE)); } static dladm_status_t -do_get_bsstype(datalink_id_t linkid, wldp_t *gbuf) +do_get_bsstype(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_BSS_TYPE)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_BSSTYPE, buflen, + B_FALSE)); } static dladm_status_t -do_get_linkstatus(datalink_id_t linkid, wldp_t *gbuf) +do_get_linkstatus(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_LINKSTATUS)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_LINKSTATUS, buflen, + B_FALSE)); } static dladm_status_t -do_get_rate(datalink_id_t linkid, wldp_t *gbuf) +do_get_rate(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_DESIRED_RATES)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_DESIRED_RATES, + buflen, B_FALSE)); } static dladm_status_t -do_get_authmode(datalink_id_t linkid, wldp_t *gbuf) +do_get_authmode(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_AUTH_MODE)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_AUTH_MODE, buflen, + B_FALSE)); } static dladm_status_t -do_get_encryption(datalink_id_t linkid, wldp_t *gbuf) +do_get_encryption(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_ENCRYPTION)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_ENCRYPTION, buflen, + B_FALSE)); } static dladm_status_t -do_get_signal(datalink_id_t linkid, wldp_t *gbuf) +do_get_signal(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_RSSI)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RSSI, buflen, + B_FALSE)); } static dladm_status_t -do_get_mode(datalink_id_t linkid, wldp_t *gbuf) +do_get_mode(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_PHY_CONFIG)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG, + buflen, B_FALSE)); } static dladm_status_t @@ -1235,8 +1233,8 @@ do_set_bsstype(datalink_id_t linkid, dladm_wlan_bsstype_t *bsstype) ibsstype = WL_BSS_ANY; break; } - return (i_dladm_wlan_set_ioctl(linkid, WL_BSS_TYPE, &ibsstype, - sizeof (ibsstype))); + return (i_dladm_wlan_param(linkid, &ibsstype, MAC_PROP_WL_BSSTYPE, + sizeof (ibsstype), B_TRUE)); } static dladm_status_t @@ -1254,8 +1252,8 @@ do_set_authmode(datalink_id_t linkid, dladm_wlan_auth_t *auth) default: return (DLADM_STATUS_NOTSUP); } - return (i_dladm_wlan_set_ioctl(linkid, WL_AUTH_MODE, &auth_mode, - sizeof (auth_mode))); + return (i_dladm_wlan_param(linkid, &auth_mode, MAC_PROP_WL_AUTH_MODE, + sizeof (auth_mode), B_TRUE)); } static dladm_status_t @@ -1275,8 +1273,8 @@ do_set_encryption(datalink_id_t linkid, dladm_wlan_secmode_t *secmode) default: return (DLADM_STATUS_NOTSUP); } - return (i_dladm_wlan_set_ioctl(linkid, WL_ENCRYPTION, &encryption, - sizeof (encryption))); + return (i_dladm_wlan_param(linkid, &encryption, MAC_PROP_WL_ENCRYPTION, + sizeof (encryption), B_TRUE)); } static dladm_status_t @@ -1309,8 +1307,8 @@ do_set_key(datalink_id_t linkid, dladm_wlan_key_t *keys, (void) memcpy(wkp->wl_wep_key, kp->wk_val, kp->wk_len); } - return (i_dladm_wlan_set_ioctl(linkid, WL_WEP_KEY_TAB, &wepkey_tab, - sizeof (wepkey_tab))); + return (i_dladm_wlan_param(linkid, &wepkey_tab, MAC_PROP_WL_KEY_TAB, + sizeof (wepkey_tab), B_TRUE)); } static dladm_status_t @@ -1327,8 +1325,8 @@ do_set_essid(datalink_id_t linkid, dladm_wlan_essid_t *essid) } else { return (DLADM_STATUS_BADARG); } - return (i_dladm_wlan_set_ioctl(linkid, WL_ESSID, &iessid, - sizeof (iessid))); + return (i_dladm_wlan_param(linkid, &iessid, MAC_PROP_WL_ESSID, + sizeof (iessid), B_TRUE)); } static dladm_status_t @@ -1342,8 +1340,8 @@ do_set_channel(datalink_id_t linkid, dladm_wlan_channel_t *channel) (void) memset(&phy_conf, 0xff, sizeof (phy_conf)); phy_conf.wl_phy_dsss_conf.wl_dsss_channel = *channel; - return (i_dladm_wlan_set_ioctl(linkid, WL_PHY_CONFIG, &phy_conf, - sizeof (phy_conf))); + return (i_dladm_wlan_param(linkid, &phy_conf, MAC_PROP_WL_PHY_CONFIG, + sizeof (phy_conf), B_TRUE)); } static dladm_status_t @@ -1351,8 +1349,8 @@ do_set_createibss(datalink_id_t linkid, boolean_t *create_ibss) { wl_create_ibss_t cr = (wl_create_ibss_t)(*create_ibss); - return (i_dladm_wlan_set_ioctl(linkid, WL_CREATE_IBSS, - &cr, sizeof (cr))); + return (i_dladm_wlan_param(linkid, &cr, MAC_PROP_WL_CREATE_IBSS, + sizeof (cr), B_TRUE)); } static void @@ -1364,15 +1362,17 @@ generate_essid(dladm_wlan_essid_t *essid) } static dladm_status_t -do_get_capability(datalink_id_t linkid, wldp_t *gbuf) +do_get_capability(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_CAPABILITY)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_CAPABILITY, + buflen, B_FALSE)); } static dladm_status_t -do_get_wpamode(datalink_id_t linkid, wldp_t *gbuf) +do_get_wpamode(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_WPA)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_WPA, buflen, + B_FALSE)); } dladm_status_t @@ -1380,17 +1380,17 @@ dladm_wlan_wpa_get_sr(datalink_id_t linkid, dladm_wlan_ess_t *sr, uint_t escnt, uint_t *estot) { int i, n; - wldp_t *gbuf; wl_wpa_ess_t *es; dladm_status_t status; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) + es = malloc(WLDP_BUFSIZE); + if (es == NULL) return (DLADM_STATUS_NOMEM); - status = i_dladm_wlan_get_ioctl(linkid, gbuf, WL_SCANRESULTS); + status = i_dladm_wlan_param(linkid, es, MAC_PROP_WL_SCANRESULTS, + WLDP_BUFSIZE, B_FALSE); if (status == DLADM_STATUS_OK) { - es = (wl_wpa_ess_t *)(gbuf->wldp_buf); n = (es->count > escnt) ? escnt : es->count; for (i = 0; i < n; i ++) { (void) memcpy(sr[i].we_bssid.wb_bytes, es->ess[i].bssid, @@ -1406,7 +1406,7 @@ dladm_wlan_wpa_get_sr(datalink_id_t linkid, dladm_wlan_ess_t *sr, *estot = n; } - free(gbuf); + free(es); return (status); } @@ -1428,7 +1428,8 @@ dladm_wlan_wpa_set_ie(datalink_id_t linkid, uint8_t *wpa_ie, uint_t wpa_ie_len) ie->wpa_ie_len = wpa_ie_len; (void) memcpy(ie->wpa_ie, wpa_ie, wpa_ie_len); - status = i_dladm_wlan_set_ioctl(linkid, WL_SETOPTIE, ie, len); + status = i_dladm_wlan_param(linkid, ie, MAC_PROP_WL_SETOPTIE, len, + B_TRUE); free(ie); return (status); @@ -1440,8 +1441,8 @@ dladm_wlan_wpa_set_wpa(datalink_id_t linkid, boolean_t flag) wl_wpa_t wpa; wpa.wpa_flag = flag; - return (i_dladm_wlan_set_ioctl(linkid, WL_WPA, &wpa, - sizeof (wl_wpa_t))); + return (i_dladm_wlan_param(linkid, &wpa, MAC_PROP_WL_WPA, + sizeof (wpa), B_TRUE)); } dladm_status_t @@ -1455,8 +1456,8 @@ dladm_wlan_wpa_del_key(datalink_id_t linkid, uint_t key_idx, (void) memcpy((char *)wk.idk_macaddr, addr->wb_bytes, DLADM_WLAN_BSSID_LEN); - return (i_dladm_wlan_set_ioctl(linkid, WL_DELKEY, &wk, - sizeof (wl_del_key_t))); + return (i_dladm_wlan_param(linkid, &wk, MAC_PROP_WL_DELKEY, + sizeof (wk), B_TRUE)); } dladm_status_t @@ -1501,7 +1502,8 @@ dladm_wlan_wpa_set_key(datalink_id_t linkid, dladm_wlan_cipher_t cipher, (void) memcpy(&wk.ik_keyrsc, &seq, 6); /* only use 48-bit of seq */ (void) memcpy(wk.ik_keydata, key, key_len); - return (i_dladm_wlan_set_ioctl(linkid, WL_KEY, &wk, sizeof (wl_key_t))); + return (i_dladm_wlan_param(linkid, &wk, MAC_PROP_WL_KEY, + sizeof (wk), B_TRUE)); } dladm_status_t @@ -1526,8 +1528,8 @@ dladm_wlan_wpa_set_mlme(datalink_id_t linkid, dladm_wlan_mlme_op_t op, (void) memcpy(mlme.im_macaddr, bssid->wb_bytes, DLADM_WLAN_BSSID_LEN); - return (i_dladm_wlan_set_ioctl(linkid, WL_MLME, &mlme, - sizeof (wl_mlme_t))); + return (i_dladm_wlan_param(linkid, &mlme, MAC_PROP_WL_MLME, + sizeof (mlme), B_TRUE)); } /* diff --git a/usr/src/lib/libdladm/common/libdlwlan_impl.h b/usr/src/lib/libdladm/common/libdlwlan_impl.h index 9611b5319b..256876f030 100644 --- a/usr/src/lib/libdladm/common/libdlwlan_impl.h +++ b/usr/src/lib/libdladm/common/libdlwlan_impl.h @@ -26,10 +26,9 @@ #ifndef _LIBDLWLAN_IMPL_H #define _LIBDLWLAN_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <inet/wifi_ioctl.h> +#include <sys/mac.h> /* * Implementation-private data structures, macros, and constants. @@ -75,12 +74,10 @@ typedef enum { DLADM_WLAN_PM_FAST } dladm_wlan_powermode_t; -extern dladm_status_t i_dladm_wlan_get_ioctl(datalink_id_t, wldp_t *, - uint_t); -extern dladm_status_t i_dladm_wlan_set_ioctl(datalink_id_t, uint_t, - void *, uint_t); -extern dladm_status_t i_dladm_wlan_ioctl(datalink_id_t, wldp_t *, uint_t, - size_t, uint_t, size_t); +extern dladm_status_t i_dladm_wlan_legacy_ioctl(datalink_id_t, wldp_t *, + uint_t, size_t, uint_t, size_t); +extern dladm_status_t i_dladm_wlan_param(datalink_id_t, void *, + mac_prop_id_t, size_t, boolean_t); extern boolean_t i_dladm_wlan_convert_chan(wl_phy_conf_t *, uint32_t *); #ifdef __cplusplus diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index 2e78907edb..dd43d9331b 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -48,6 +48,8 @@ #include <sys/param.h> #include <inttypes.h> #include <sys/ethernet.h> +#include <net/wpa.h> +#include <sys/sysmacros.h> /* * The linkprop get() callback. @@ -98,20 +100,23 @@ typedef dladm_status_t pd_checkf_t(struct prop_desc *pd, uint_t cnt, val_desc_t *propval, datalink_media_t); -typedef struct dladm_public_prop_s { +typedef struct link_attr_s { mac_prop_id_t pp_id; size_t pp_valsize; char *pp_name; - char *pp_desc; -} dladm_public_prop_t; +} link_attr_t; -static dld_ioc_macprop_t *i_dladm_buf_alloc(size_t, datalink_id_t, const char *, - uint_t, dladm_status_t *); +static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t, + const char *, uint_t, dladm_status_t *); +static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t, + mac_prop_id_t, uint_t, + dladm_status_t *); static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **, uint_t, uint_t); static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **, uint_t *, dladm_prop_type_t, uint_t); -static dladm_public_prop_t *dladm_name2prop(const char *); +static link_attr_t *dladm_name2prop(const char *); +static link_attr_t *dladm_id2prop(mac_prop_id_t); static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t, dladm_status_t *); static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod, @@ -128,6 +133,11 @@ static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate, static dladm_status_t i_dladm_speed_get(struct prop_desc *, datalink_id_t, char **, uint_t *, uint_t); +static dladm_status_t i_dladm_wlan_get_legacy_ioctl(datalink_id_t, void *, + uint_t, uint_t); +static dladm_status_t i_dladm_wlan_set_legacy_ioctl(datalink_id_t, void *, + uint_t, uint_t); +static dladm_status_t i_dladm_macprop(void *, boolean_t); typedef struct prop_desc { /* @@ -193,70 +203,104 @@ typedef struct prop_desc { #define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1 +/* + * Supported link properties enumerated in the prop_table[] array are + * computed using the callback functions in that array. To compute the + * property value, multiple distinct system calls may be needed (e.g., + * for wifi speed, we need to issue system calls to get desired/supported + * rates). The link_attr[] table enumerates the interfaces to the kernel, + * and the type/size of the data passed in the user-kernel interface. + */ +static link_attr_t link_attr[] = { + { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex"}, + + { MAC_PROP_SPEED, sizeof (uint64_t), "speed"}, + + { MAC_PROP_STATUS, sizeof (link_state_t), "state"}, + + { MAC_PROP_AUTONEG, sizeof (uint8_t), "adv_autoneg_cap"}, + + { MAC_PROP_MTU, sizeof (uint32_t), "mtu"}, + + { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), "flowctrl"}, + + { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), "zone"}, + + { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), "autopush"}, + + { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), "adv_1000fdx_cap"}, + + { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), "en_1000fdx_cap"}, + + { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), "adv_1000hdx_cap"}, + + { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), "en_1000hdx_cap"}, + + { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), "adv_100fdx_cap"}, + + { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), "en_100fdx_cap"}, + + { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), "adv_100hdx_cap"}, + + { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), "en_100hdx_cap"}, + + { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), "adv_10fdx_cap"}, + + { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), "en_10fdx_cap"}, + + { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), "adv_10hdx_cap"}, + + { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), "en_10hdx_cap"}, -static dladm_public_prop_t dladm_prop[] = { - { MAC_PROP_DUPLEX, sizeof (link_duplex_t), - "duplex", "link duplex mode" }, + { MAC_PROP_WL_ESSID, sizeof (wl_linkstatus_t), "essid"}, - { MAC_PROP_SPEED, sizeof (uint64_t), - "speed", "link speed (bps)" }, + { MAC_PROP_WL_BSSID, sizeof (wl_bssid_t), "bssid"}, - { MAC_PROP_STATUS, sizeof (link_state_t), - "state", "link up/down" }, + { MAC_PROP_WL_BSSTYPE, sizeof (wl_bss_type_t), "bsstype"}, - { MAC_PROP_AUTONEG, sizeof (uint8_t), - "adv_autoneg_cap", "Advertised auto-negotiation" }, + { MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"}, - { MAC_PROP_MTU, sizeof (uint32_t), - "mtu", "current link mtu" }, + /* wl_rates_t has variable length */ + { MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"}, - { MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t), - "flowctrl", "flowcontrol" }, + /* wl_rates_t has variable length */ + { MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"}, - { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t), - "zone", "non-global zones" }, + { MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"}, - { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush), - "autopush", "autopush modules" }, + { MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"}, - { MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t), - "adv_1000fdx_cap", "Adv 1000 Mbps fdx" }, + { MAC_PROP_WL_RSSI, sizeof (wl_rssi_t), "signal"}, - { MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t), - "en_1000fdx_cap", "Enable 1000 Mbps fdx" }, + { MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"}, - { MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t), - "adv_1000hdx_cap", "Adv 1000 Mbps hdx" }, + { MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"}, - { MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t), - "en_1000hdx_cap", "Enable 1000 Mbps hdx" }, + { MAC_PROP_WL_WPA, sizeof (wl_wpa_t), "wpa"}, - { MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t), - "adv_100fdx_cap", "Adv 100 Mbps fdx" }, + /* wl_wpa_ess_t has variable length */ + { MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"}, - { MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t), - "en_100fdx_cap", "Enable 100 Mbps fdx" }, + { MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"}, - { MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t), - "adv_100hdx_cap", "Adv 100 Mbps hdx" }, + { MAC_PROP_WL_RADIO, sizeof (dladm_wlan_radio_t), "wl_radio"}, - { MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t), - "en_100hdx_cap", "Enable 100 Mbps hdx" }, + { MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t), "wl_ess_list"}, - { MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t), - "adv_10fdx_cap", "Adv 10 Mbps fdx" }, + { MAC_PROP_WL_KEY_TAB, sizeof (wl_wep_key_tab_t), "wl_wep_key"}, - { MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t), - "en_10fdx_cap", "Enable 10 Mbps fdx" }, + { MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"}, - { MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t), - "adv_10hdx_cap", "Adv 10 Mbps hdx" }, + /* wl_wpa_ie_t has variable length */ + { MAC_PROP_WL_SETOPTIE, sizeof (wl_wpa_ie_t), "set_ie"}, - { MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t), - "en_10hdx_cap", "Enable 10 Mbps hdx" }, + { MAC_PROP_WL_DELKEY, sizeof (wl_del_key_t), "wpa_del_key"}, - { MAC_PROP_PRIVATE, 0, - "driver-private", "" } + { MAC_PROP_WL_KEY, sizeof (wl_key_t), "wl_key"}, + + { MAC_PROP_WL_MLME, sizeof (wl_mlme_t), "mlme"}, + + { MAC_PROP_PRIVATE, 0, "driver-private"} }; static val_desc_t link_duplex_vals[] = { @@ -414,6 +458,12 @@ static prop_desc_t prop_table[] = { #define DLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) +/* + * when retrieving private properties, we pass down a buffer with + * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value. + */ +#define DLADM_PROP_BUF_CHUNK 1024 + static dladm_status_t i_dladm_set_linkprop_db(datalink_id_t, const char *, char **, uint_t); static dladm_status_t i_dladm_get_linkprop_db(datalink_id_t, const char *, @@ -1244,6 +1294,8 @@ do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, return (DLADM_STATUS_OK); } +#define WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET) + /* ARGSUSED */ static dladm_status_t do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid, @@ -1251,19 +1303,16 @@ do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid, { wl_rates_t *wrp; uint_t i; - wldp_t *gbuf = NULL; dladm_status_t status = DLADM_STATUS_OK; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = DLADM_STATUS_NOMEM; - goto done; - } + wrp = malloc(WLDP_BUFSIZE); + if (wrp == NULL) + return (DLADM_STATUS_NOMEM); - status = i_dladm_wlan_get_ioctl(linkid, gbuf, id); + status = i_dladm_wlan_param(linkid, wrp, id, WLDP_BUFSIZE, B_FALSE); if (status != DLADM_STATUS_OK) goto done; - wrp = (wl_rates_t *)gbuf->wldp_buf; if (wrp->wl_rates_num > *val_cnt) { status = DLADM_STATUS_TOOSMALL; goto done; @@ -1283,7 +1332,7 @@ do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid, *val_cnt = wrp->wl_rates_num; done: - free(gbuf); + free(wrp); return (status); } @@ -1296,7 +1345,7 @@ do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid, val_cnt, flags)); return (do_get_rate_common(pd, linkid, prop_val, val_cnt, - WL_DESIRED_RATES)); + MAC_PROP_WL_DESIRED_RATES)); } /* ARGSUSED */ @@ -1314,7 +1363,7 @@ do_get_rate_mod(struct prop_desc *pd, datalink_id_t linkid, case DL_WIFI: return (do_get_rate_common(pd, linkid, prop_val, val_cnt, - WL_SUPPORTED_RATES)); + MAC_PROP_WL_SUPPORTED_RATES)); default: return (DLADM_STATUS_BADARG); } @@ -1325,26 +1374,24 @@ do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates) { int i; uint_t len; - wldp_t *gbuf; wl_rates_t *wrp; dladm_status_t status = DLADM_STATUS_OK; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) + wrp = malloc(WLDP_BUFSIZE); + if (wrp == NULL) return (DLADM_STATUS_NOMEM); - (void) memset(gbuf, 0, MAX_BUF_LEN); - - wrp = (wl_rates_t *)gbuf->wldp_buf; + bzero(wrp, WLDP_BUFSIZE); for (i = 0; i < rates->wr_cnt; i++) wrp->wl_rates_rates[i] = rates->wr_rates[i]; wrp->wl_rates_num = rates->wr_cnt; len = offsetof(wl_rates_t, wl_rates_rates) + (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; - status = i_dladm_wlan_ioctl(linkid, gbuf, WL_DESIRED_RATES, len, - WLAN_SET_PARAM, len); + status = i_dladm_wlan_param(linkid, wrp, MAC_PROP_WL_DESIRED_RATES, + len, B_TRUE); - free(gbuf); + free(wrp); return (status); } @@ -1420,9 +1467,10 @@ done: } static dladm_status_t -do_get_phyconf(datalink_id_t linkid, wldp_t *gbuf) +do_get_phyconf(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_PHY_CONFIG)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG, + buflen, B_FALSE)); } /* ARGSUSED */ @@ -1431,17 +1479,16 @@ do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) { uint32_t channel; - wldp_t *gbuf; + char buf[WLDP_BUFSIZE]; dladm_status_t status = DLADM_STATUS_OK; + wl_phy_conf_t wl_phy_conf; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) - return (DLADM_STATUS_NOMEM); - - if ((status = do_get_phyconf(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_phyconf(linkid, buf, sizeof (buf))) + != DLADM_STATUS_OK) goto done; - if (!i_dladm_wlan_convert_chan((wl_phy_conf_t *)gbuf->wldp_buf, - &channel)) { + (void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf)); + if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) { status = DLADM_STATUS_NOTFOUND; goto done; } @@ -1450,14 +1497,14 @@ do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid, *val_cnt = 1; done: - free(gbuf); return (status); } static dladm_status_t -do_get_powermode(datalink_id_t linkid, wldp_t *gbuf) +do_get_powermode(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_POWER_MODE)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_POWER_MODE, + buflen, B_FALSE)); } /* ARGSUSED */ @@ -1465,19 +1512,17 @@ static dladm_status_t do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid, char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags) { - wl_ps_mode_t *mode; + wl_ps_mode_t mode; const char *s; - wldp_t *gbuf; + char buf[WLDP_BUFSIZE]; dladm_status_t status = DLADM_STATUS_OK; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) - return (DLADM_STATUS_NOMEM); - - if ((status = do_get_powermode(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_powermode(linkid, buf, sizeof (buf))) + != DLADM_STATUS_OK) goto done; - mode = (wl_ps_mode_t *)(gbuf->wldp_buf); - switch (mode->wl_ps_mode) { + (void) memcpy(&mode, buf, sizeof (mode)); + switch (mode.wl_ps_mode) { case WL_PM_AM: s = "off"; break; @@ -1495,7 +1540,6 @@ do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid, *val_cnt = 1; done: - free(gbuf); return (status); } @@ -1519,8 +1563,8 @@ do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm) default: return (DLADM_STATUS_NOTSUP); } - return (i_dladm_wlan_set_ioctl(linkid, WL_POWER_MODE, &ps_mode, - sizeof (ps_mode))); + return (i_dladm_wlan_param(linkid, &ps_mode, MAC_PROP_WL_POWER_MODE, + sizeof (ps_mode), B_TRUE)); } /* ARGSUSED */ @@ -1540,9 +1584,10 @@ do_set_powermode_prop(prop_desc_t *pd, datalink_id_t linkid, } static dladm_status_t -do_get_radio(datalink_id_t linkid, wldp_t *gbuf) +do_get_radio(datalink_id_t linkid, void *buf, int buflen) { - return (i_dladm_wlan_get_ioctl(linkid, gbuf, WL_RADIO)); + return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RADIO, buflen, + B_FALSE)); } /* ARGSUSED */ @@ -1552,16 +1597,14 @@ do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid, { wl_radio_t radio; const char *s; - wldp_t *gbuf; + char buf[WLDP_BUFSIZE]; dladm_status_t status = DLADM_STATUS_OK; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) - return (DLADM_STATUS_NOMEM); - - if ((status = do_get_radio(linkid, gbuf)) != DLADM_STATUS_OK) + if ((status = do_get_radio(linkid, buf, sizeof (buf))) + != DLADM_STATUS_OK) goto done; - radio = *(wl_radio_t *)(gbuf->wldp_buf); + (void) memcpy(&radio, buf, sizeof (radio)); switch (radio) { case B_TRUE: s = "on"; @@ -1577,7 +1620,6 @@ do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid, *val_cnt = 1; done: - free(gbuf); return (status); } @@ -1596,7 +1638,8 @@ do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio) default: return (DLADM_STATUS_NOTSUP); } - return (i_dladm_wlan_set_ioctl(linkid, WL_RADIO, &r, sizeof (r))); + return (i_dladm_wlan_param(linkid, &r, MAC_PROP_WL_RADIO, + sizeof (r), B_TRUE)); } /* ARGSUSED */ @@ -1688,32 +1731,39 @@ done: return (status); } -static dladm_public_prop_t * +static link_attr_t * dladm_name2prop(const char *prop_name) { - dladm_public_prop_t *p; + link_attr_t *p; - for (p = dladm_prop; p->pp_id != MAC_PROP_PRIVATE; p++) { + for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { if (strcmp(p->pp_name, prop_name) == 0) break; } return (p); } +static link_attr_t * +dladm_id2prop(mac_prop_id_t propid) +{ + link_attr_t *p; + + for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) { + if (p->pp_id == propid) + break; + } + return (p); +} static dld_ioc_macprop_t * -i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name, - uint_t flags, dladm_status_t *status) +i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid, + const char *prop_name, mac_prop_id_t propid, uint_t flags, + dladm_status_t *status) { int dsize; dld_ioc_macprop_t *dip; - dladm_public_prop_t *p; *status = DLADM_STATUS_OK; - p = dladm_name2prop(prop_name); - if (p->pp_id != MAC_PROP_PRIVATE) - valsize = p->pp_valsize; - dsize = MAC_PROP_BUFSIZE(valsize); dip = malloc(dsize); if (dip == NULL) { @@ -1725,25 +1775,48 @@ i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name, (void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name)); dip->pr_version = MAC_PROP_VERSION; dip->pr_linkid = linkid; - dip->pr_num = p->pp_id; + dip->pr_num = propid; dip->pr_flags = flags; return (dip); } +static dld_ioc_macprop_t * +i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid, + const char *prop_name, uint_t flags, dladm_status_t *status) +{ + link_attr_t *p; + + p = dladm_name2prop(prop_name); + valsize = MAX(p->pp_valsize, valsize); + return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id, + flags, status)); +} + +static dld_ioc_macprop_t * +i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid, + mac_prop_id_t propid, uint_t flags, dladm_status_t *status) +{ + link_attr_t *p; + + p = dladm_id2prop(propid); + valsize = MAX(p->pp_valsize, valsize); + return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid, + flags, status)); +} + /* ARGSUSED */ static dladm_status_t i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media) { dld_ioc_macprop_t *dip; - int fd; dladm_status_t status = DLADM_STATUS_OK; uint8_t u8; uint16_t u16; uint32_t u32; void *val; - dip = i_dladm_buf_alloc(0, linkid, pd->pd_name, 0, &status); + dip = i_dladm_buf_alloc_by_name(0, linkid, pd->pd_name, 0, &status); if (dip == NULL) return (status); @@ -1778,16 +1851,27 @@ i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid, else dip->pr_valsize = 0; + status = i_dladm_macprop(dip, B_TRUE); + +done: + free(dip); + return (status); +} + +dladm_status_t +i_dladm_macprop(void *dip, boolean_t set) +{ + int fd; + dladm_status_t status = DLADM_STATUS_OK; + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { status = dladm_errno2status(errno); - goto done; + return (status); } - if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0) + if (ioctl(fd, (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip)) status = dladm_errno2status(errno); (void) close(fd); -done: - free(dip); return (status); } @@ -1795,24 +1879,13 @@ static dld_ioc_macprop_t * i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, dladm_status_t *status) { - int fd; dld_ioc_macprop_t *dip = NULL; - *status = DLADM_STATUS_OK; - - dip = i_dladm_buf_alloc(0, linkid, prop_name, flags, status); + dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status); if (dip == NULL) return (NULL); - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { - *status = dladm_errno2status(errno); - goto done; - } - if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) - *status = dladm_errno2status(errno); - - (void) close(fd); -done: + *status = i_dladm_macprop(dip, B_FALSE); if (*status != DLADM_STATUS_OK) { free(dip); return (NULL); @@ -1999,11 +2072,11 @@ static dladm_status_t i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags) { - int fd, i, slen; + int i, slen; int bufsize = 0; dld_ioc_macprop_t *dip = NULL; uchar_t *dp; - dladm_public_prop_t *p; + link_attr_t *p; dladm_status_t status = DLADM_STATUS_OK; if ((prop_name == NULL && prop_val != NULL) || @@ -2025,25 +2098,19 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, /* * getting default value. so use more buffer space. */ - bufsize += 1024; + bufsize += DLADM_PROP_BUF_CHUNK; } - dip = i_dladm_buf_alloc(bufsize + 1, linkid, prop_name, + dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name, (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status); if (dip == NULL) return (status); dp = (uchar_t *)dip->pr_val; slen = 0; - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { - status = dladm_errno2status(errno); - goto done; - } + if (prop_val == NULL) { - if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) { - status = dladm_errno2status(errno); - goto done; - } + status = i_dladm_macprop(dip, B_FALSE); } else { for (i = 0; i < val_cnt; i++) { int plen = 0; @@ -2058,13 +2125,9 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, dp[slen++] = ','; dp += (plen + 1); } + status = i_dladm_macprop(dip, B_TRUE); } - if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0) - status = dladm_errno2status(errno); -done: - if (fd > 0) - (void) close(fd); free(dip); return (status); } @@ -2073,10 +2136,9 @@ static dladm_status_t i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags) { - int fd; - dladm_status_t status = DLADM_STATUS_OK; + dladm_status_t status = DLADM_STATUS_OK; dld_ioc_macprop_t *dip = NULL; - dladm_public_prop_t *p; + link_attr_t *p; char tmp = '\0'; if ((prop_name == NULL && prop_val != NULL) || @@ -2096,23 +2158,15 @@ i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, /* * private properties: all parsing is done in the kernel. */ - dip = i_dladm_buf_alloc(1024, linkid, prop_name, dld_flags, &status); + dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name, + dld_flags, &status); if (dip == NULL) return (status); - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { - free(dip); - return (DLADM_STATUS_BADARG); - } - - if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) { - status = dladm_errno2status(errno); - } else { + if ((status = i_dladm_macprop(dip, B_FALSE)) == DLADM_STATUS_OK) { (void) strncpy(*prop_val, dip->pr_val, DLADM_PROP_VAL_MAX); *val_cnt = 1; } - - (void) close(fd); free(dip); return (status); } @@ -2162,3 +2216,146 @@ i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid, free(buf); return (status); } + +int +macprop_to_wifi(mac_prop_id_t wl_prop) +{ + switch (wl_prop) { + case MAC_PROP_WL_ESSID: + return (WL_ESSID); + case MAC_PROP_WL_BSSID: + return (WL_BSSID); + case MAC_PROP_WL_BSSTYPE: + return (WL_BSS_TYPE); + case MAC_PROP_WL_LINKSTATUS: + return (WL_LINKSTATUS); + case MAC_PROP_WL_DESIRED_RATES: + return (WL_DESIRED_RATES); + case MAC_PROP_WL_SUPPORTED_RATES: + return (WL_SUPPORTED_RATES); + case MAC_PROP_WL_AUTH_MODE: + return (WL_AUTH_MODE); + case MAC_PROP_WL_ENCRYPTION: + return (WL_ENCRYPTION); + case MAC_PROP_WL_RSSI: + return (WL_RSSI); + case MAC_PROP_WL_PHY_CONFIG: + return (WL_PHY_CONFIG); + case MAC_PROP_WL_CAPABILITY: + return (WL_CAPABILITY); + case MAC_PROP_WL_WPA: + return (WL_WPA); + case MAC_PROP_WL_SCANRESULTS: + return (WL_SCANRESULTS); + case MAC_PROP_WL_POWER_MODE: + return (WL_POWER_MODE); + case MAC_PROP_WL_RADIO: + return (WL_RADIO); + case MAC_PROP_WL_ESS_LIST: + return (WL_ESS_LIST); + case MAC_PROP_WL_KEY_TAB: + return (WL_WEP_KEY_TAB); + case MAC_PROP_WL_CREATE_IBSS: + return (WL_CREATE_IBSS); + case MAC_PROP_WL_SETOPTIE: + return (WL_SETOPTIE); + case MAC_PROP_WL_DELKEY: + return (WL_DELKEY); + case MAC_PROP_WL_KEY: + return (WL_KEY); + case MAC_PROP_WL_MLME: + return (WL_MLME); + default: + return (-1); + } +} + +dladm_status_t +i_dladm_wlan_param(datalink_id_t linkid, void *buf, mac_prop_id_t cmd, + size_t len, boolean_t set) +{ + uint32_t flags; + dladm_status_t status; + uint32_t media; + dld_ioc_macprop_t *dip; + void *dp; + + if ((status = dladm_datalink_id2info(linkid, &flags, NULL, &media, + NULL, 0)) != DLADM_STATUS_OK) { + return (status); + } + + if (media != DL_WIFI) + return (DLADM_STATUS_BADARG); + + if (!(flags & DLADM_OPT_ACTIVE)) + return (DLADM_STATUS_TEMPONLY); + + if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET)) + len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1; + + dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status); + if (dip == NULL) + return (DLADM_STATUS_NOMEM); + + dp = (uchar_t *)dip->pr_val; + if (set) + (void) memcpy(dp, buf, len); + + status = i_dladm_macprop(dip, set); + if (status == DLADM_STATUS_NOTSUP) { + if (set) { + status = i_dladm_wlan_set_legacy_ioctl(linkid, + buf, len, macprop_to_wifi(cmd)); + } else { + status = i_dladm_wlan_get_legacy_ioctl(linkid, + buf, len, macprop_to_wifi(cmd)); + } + } else if (status == DLADM_STATUS_OK) { + if (!set) + (void) memcpy(buf, dp, len); + } + + free(dip); + return (status); +} + +static dladm_status_t +i_dladm_wlan_get_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, + uint_t id) +{ + wldp_t *gbuf; + dladm_status_t status; + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) + return (DLADM_STATUS_NOMEM); + + (void) memset(gbuf, 0, MAX_BUF_LEN); + status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, MAX_BUF_LEN, + WLAN_GET_PARAM, sizeof (wldp_t)); + if (status == DLADM_STATUS_OK) + (void) memcpy(buf, gbuf->wldp_buf, buflen); + + free(gbuf); + return (status); +} + +static dladm_status_t +i_dladm_wlan_set_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen, + uint_t id) +{ + wldp_t *gbuf; + dladm_status_t status = DLADM_STATUS_OK; + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) + return (DLADM_STATUS_NOMEM); + + (void) memset(gbuf, 0, MAX_BUF_LEN); + (void) memcpy(gbuf->wldp_buf, buf, buflen); + buflen += WIFI_BUF_OFFSET; + status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, buflen, + WLAN_SET_PARAM, buflen); + + free(gbuf); + return (status); +} |