📄 assoc.c
字号:
if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); ret = libertas_prepare_and_send_command(priv, CMD_802_11_KEY_MATERIAL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, assoc_req); assoc_req->flags = flags; } if (ret) goto out; if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); ret = libertas_prepare_and_send_command(priv, CMD_802_11_KEY_MATERIAL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, assoc_req); assoc_req->flags = flags; }out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret;}static int assoc_helper_wpa_ie(wlan_private *priv, struct assoc_request * assoc_req){ wlan_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_ASSOC); if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); adapter->wpa_ie_len = assoc_req->wpa_ie_len; } else { memset(&adapter->wpa_ie, 0, MAX_WPA_IE_LEN); adapter->wpa_ie_len = 0; } lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret;}static int should_deauth_infrastructure(wlan_adapter *adapter, struct assoc_request * assoc_req){ if (adapter->connect_status != LIBERTAS_CONNECTED) return 0; if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { lbs_deb_assoc("Deauthenticating due to new SSID in " " configuration request.\n"); return 1; } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { lbs_deb_assoc("Deauthenticating due to updated security " "info in configuration request.\n"); return 1; } } if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { lbs_deb_assoc("Deauthenticating due to new BSSID in " " configuration request.\n"); return 1; } if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { lbs_deb_assoc("Deauthenticating due to channel switch.\n"); return 1; } /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { if (assoc_req->mode != IW_MODE_INFRA) return 1; } return 0;}static int should_stop_adhoc(wlan_adapter *adapter, struct assoc_request * assoc_req){ if (adapter->connect_status != LIBERTAS_CONNECTED) return 0; if (libertas_ssid_cmp(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len, assoc_req->ssid, assoc_req->ssid_len) != 0) return 1; /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { if (assoc_req->mode != IW_MODE_ADHOC) return 1; } if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { if (assoc_req->channel != adapter->curbssparams.channel) return 1; } return 0;}void libertas_association_worker(struct work_struct *work){ wlan_private *priv = container_of(work, wlan_private, assoc_work.work); wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req = NULL; int ret = 0; int find_any_ssid = 0; DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_ASSOC); mutex_lock(&adapter->lock); assoc_req = adapter->pending_assoc_req; adapter->pending_assoc_req = NULL; adapter->in_progress_assoc_req = assoc_req; mutex_unlock(&adapter->lock); if (!assoc_req) goto done; print_assoc_req(__func__, assoc_req); /* If 'any' SSID was specified, find an SSID to associate with */ if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) && !assoc_req->ssid_len) find_any_ssid = 1; /* But don't use 'any' SSID if there's a valid locked BSSID to use */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { if (compare_ether_addr(assoc_req->bssid, bssid_any) && compare_ether_addr(assoc_req->bssid, bssid_off)) find_any_ssid = 0; } if (find_any_ssid) { u8 new_mode; ret = libertas_find_best_network_ssid(priv, assoc_req->ssid, &assoc_req->ssid_len, assoc_req->mode, &new_mode); if (ret) { lbs_deb_assoc("Could not find best network\n"); ret = -ENETUNREACH; goto out; } /* Ensure we switch to the mode of the AP */ if (assoc_req->mode == IW_MODE_AUTO) { set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); assoc_req->mode = new_mode; } } /* * Check if the attributes being changing require deauthentication * from the currently associated infrastructure access point. */ if (adapter->mode == IW_MODE_INFRA) { if (should_deauth_infrastructure(adapter, assoc_req)) { ret = libertas_send_deauthentication(priv); if (ret) { lbs_deb_assoc("Deauthentication due to new " "configuration request failed: %d\n", ret); } } } else if (adapter->mode == IW_MODE_ADHOC) { if (should_stop_adhoc(adapter, assoc_req)) { ret = libertas_stop_adhoc_network(priv); if (ret) { lbs_deb_assoc("Teardown of AdHoc network due to " "new configuration request failed: %d\n", ret); } } } /* Send the various configuration bits to the firmware */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { ret = assoc_helper_mode(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); goto out; } } if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { ret = assoc_helper_channel(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n", __LINE__, ret); goto out; } } if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { ret = assoc_helper_wep_keys(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); goto out; } } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { ret = assoc_helper_secinfo(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); goto out; } } if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { ret = assoc_helper_wpa_ie(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); goto out; } } if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { ret = assoc_helper_wpa_keys(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); goto out; } } /* SSID/BSSID should be the _last_ config option set, because they * trigger the association attempt. */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { int success = 1; ret = assoc_helper_associate(priv, assoc_req); if (ret) { lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n", ret); success = 0; } if (adapter->connect_status != LIBERTAS_CONNECTED) { lbs_deb_assoc("ASSOC: association attempt unsuccessful, " "not connected.\n"); success = 0; } if (success) { lbs_deb_assoc("ASSOC: association attempt successful. " "Associated to '%s' (%s)\n", escape_essid(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len), print_mac(mac, adapter->curbssparams.bssid)); libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, CMD_OPTION_WAITFORRSP, 0, NULL); libertas_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, CMD_OPTION_WAITFORRSP, 0, NULL); } else { ret = -1; } }out: if (ret) { lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", ret); } mutex_lock(&adapter->lock); adapter->in_progress_assoc_req = NULL; mutex_unlock(&adapter->lock); kfree(assoc_req);done: lbs_deb_leave(LBS_DEB_ASSOC);}/* * Caller MUST hold any necessary locks */struct assoc_request * wlan_get_association_request(wlan_adapter *adapter){ struct assoc_request * assoc_req; if (!adapter->pending_assoc_req) { adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); if (!adapter->pending_assoc_req) { lbs_pr_info("Not enough memory to allocate association" " request!\n"); return NULL; } } /* Copy current configuration attributes to the association request, * but don't overwrite any that are already set. */ assoc_req = adapter->pending_assoc_req; if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid, IW_ESSID_MAX_SIZE); assoc_req->ssid_len = adapter->curbssparams.ssid_len; } if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) assoc_req->channel = adapter->curbssparams.channel; if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) assoc_req->band = adapter->curbssparams.band; if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) assoc_req->mode = adapter->mode; if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { memcpy(&assoc_req->bssid, adapter->curbssparams.bssid, ETH_ALEN); } if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) { int i; for (i = 0; i < 4; i++) { memcpy(&assoc_req->wep_keys[i], &adapter->wep_keys[i], sizeof(struct enc_key)); } } if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) assoc_req->wep_tx_keyidx = adapter->wep_tx_keyidx; if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { memcpy(&assoc_req->wpa_mcast_key, &adapter->wpa_mcast_key, sizeof(struct enc_key)); } if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { memcpy(&assoc_req->wpa_unicast_key, &adapter->wpa_unicast_key, sizeof(struct enc_key)); } if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { memcpy(&assoc_req->secinfo, &adapter->secinfo, sizeof(struct wlan_802_11_security)); } if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { memcpy(&assoc_req->wpa_ie, &adapter->wpa_ie, MAX_WPA_IE_LEN); assoc_req->wpa_ie_len = adapter->wpa_ie_len; } print_assoc_req(__func__, assoc_req); return assoc_req;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -