diff -urp usr.sbin/wpa/wpa_supplicant/driver_freebsd.c.orig usr.sbin/wpa/wpa_supplicant/driver_freebsd.c --- usr.sbin/wpa/wpa_supplicant/driver_freebsd.c.orig Sat Apr 22 14:17:51 2006 +++ usr.sbin/wpa/wpa_supplicant/driver_freebsd.c Wed Jul 26 23:20:27 2006 @@ -369,6 +369,87 @@ wpa_driver_bsd_disassociate(void *priv, return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); } +/* honour unicast/multicast cipher suite and key management suite */ +static int +wpa_driver_bsd_set_ciphers(void *priv, struct wpa_driver_associate_params *params) +{ + struct wpa_driver_bsd_data *drv = priv; + int v = 0; + + /* XXX wpa_supplicant always uses CIPHER_NONE in IBSS mode */ + if (params->pairwise_suite == CIPHER_NONE) + v = 1<pairwise_suite & CIPHER_WEP40) + v = 1<pairwise_suite & CIPHER_TKIP) + v = 1<pairwise_suite & CIPHER_CCMP) + v = 1<pairwise_suite & CIPHER_WEP104) + v = 1<pairwise_suite); + return -1; + } + switch (params->group_suite) { + case CIPHER_NONE: + v = IEEE80211_CIPHER_NONE; + break; + case CIPHER_WEP40: + v = IEEE80211_CIPHER_WEP; + break; + case CIPHER_TKIP: + v = IEEE80211_CIPHER_TKIP; + break; + case CIPHER_CCMP: + v = IEEE80211_CIPHER_AES_CCM; + break; + case CIPHER_WEP104: + v = IEEE80211_CIPHER_WEP; + break; + default: + wpa_printf(MSG_DEBUG, + "unsupported group cipher suite %u\n", + params->group_suite); + return -1; + } + if (set80211param(drv, IEEE80211_IOC_MCASTCIPHER, v)) { + wpa_printf(MSG_DEBUG, + "Unable to set group key cipher to %u\n", v); + return -1; + } + switch (params->key_mgmt_suite) { + case KEY_MGMT_WPA_NONE: + v = WPA_ASE_NONE; + break; + case KEY_MGMT_802_1X: + v = WPA_ASE_8021X_UNSPEC; + break; + case KEY_MGMT_PSK: + v = WPA_ASE_8021X_PSK; + break; + default: + wpa_printf(MSG_DEBUG, + "unsupported key mgmt suite %u\n", + params->key_mgmt_suite); + return -1; + } + if (set80211param(drv, IEEE80211_IOC_KEYMGTALGS, v)) { + wpa_printf(MSG_DEBUG, + "Unable to set key mgmt suite to %u\n", v); + return -1; + } + + if (params->mode != IEEE80211_MODE_IBSS) + return 0; + + /* set desired ssid before MLME state transition */ + return wpa_driver_bsd_set_ssid(priv, params->ssid, params->ssid_len); +} + static int wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) { @@ -387,7 +468,8 @@ wpa_driver_bsd_associate(void *priv, str ); /* XXX error handling is wrong but unclear what to do... */ - if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) + if (params->mode != IEEE80211_MODE_IBSS && + wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) return -1; privacy = !(params->pairwise_suite == CIPHER_NONE && @@ -404,13 +486,25 @@ wpa_driver_bsd_associate(void *priv, str params->wpa_ie[0] == RSN_INFO_ELEM ? 2 : 1) < 0) return -1; + if (wpa_driver_bsd_set_ciphers(drv, params)) + return -1; + memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_ASSOC; if (params->ssid != NULL) memcpy(mlme.im_ssid, params->ssid, params->ssid_len); mlme.im_ssid_len = params->ssid_len; - if (params->bssid != NULL) + if (params->bssid != NULL) { memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); + + /* + * XXX ieee80211_find_node_with_ssid() matches addr2, + * not BSSID; therefore, nullify macaddr to search by + * SSID only. + */ + if (params->mode == IEEE80211_MODE_IBSS) + memset(mlme.im_macaddr, 0, IEEE80211_ADDR_LEN); + } if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) return -1; return 0;