📄 iw_ndis.c
字号:
network_type, res); TRACEEXIT2(return -EINVAL); } TRACEEXIT2(return 0);}/* WPA support */static int wpa_init(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; TRACEENTER2(""); if (test_bit(Ndis802_11Encryption2Enabled, &handle->capa) || test_bit(Ndis802_11Encryption3Enabled, &handle->capa)) { if (set_infra_mode(handle, Ndis802_11Infrastructure)) WARNING("couldn't enable infrastructure/managed mode"); TRACEEXIT2(return 0); } else { WARNING("driver is not WPA capable"); TRACEEXIT2(return -1); }}static int wpa_deinit(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ TRACEENTER2(""); TRACEEXIT2(return 0);}static int wpa_set_wpa(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; TRACEENTER2(""); DBGTRACE1("flags = %d, handle->capa = %ld", wrqu->data.flags, handle->capa); if (wrqu->data.flags) { if (test_bit(Ndis802_11Encryption2Enabled, &handle->capa) || test_bit(Ndis802_11Encryption3Enabled, &handle->capa)) TRACEEXIT2(return 0); else { WARNING("driver is not WPA capable"); TRACEEXIT2(return -1); } } else TRACEEXIT2(return 0);}static int wpa_set_key(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; struct ndis_add_key ndis_key; struct wpa_key wpa_key; int i, size; NDIS_STATUS res; mac_address addr; u8 seq[IW_ENCODING_TOKEN_MAX]; u8 key[IW_ENCODING_TOKEN_MAX]; if (wrqu->data.length) size = wrqu->data.length; else size = sizeof(wpa_key); if (copy_from_user(&wpa_key, wrqu->data.pointer, size)) TRACEEXIT1(return -1); if (wpa_key.addr && copy_from_user(&addr, wpa_key.addr, ETH_ALEN)) TRACEEXIT1(return -1); if (wpa_key.seq && copy_from_user(&seq, wpa_key.seq, wpa_key.seq_len)) TRACEEXIT1(return -1); if (wpa_key.key && copy_from_user(&key, wpa_key.key, wpa_key.key_len)) TRACEEXIT1(return -1); TRACEENTER2("alg = %d, key_index = %d", wpa_key.alg, wpa_key.key_index); if (wpa_key.alg == WPA_ALG_WEP) { if (test_bit(Ndis802_11EncryptionDisabled, &handle->capa)) TRACEEXIT2(return -1); if (wpa_key.set_tx) handle->encr_info.tx_key_index = wpa_key.key_index; if (add_wep_key(handle, key, wpa_key.key_len, wpa_key.key_index)) TRACEEXIT2(return -1); else TRACEEXIT2(return 0); } if (wpa_key.key_len > sizeof(ndis_key.key)) { DBGTRACE2("incorrect key length (%u)", (u32)wpa_key.key_len); TRACEEXIT2(return -1); } if (wpa_key.seq_len > IW_ENCODING_TOKEN_MAX) { DBGTRACE2("incorrect seq? length = (%u)", (u32)wpa_key.seq_len); TRACEEXIT2(return -1); } DBGTRACE2("setting key %d, %u", wpa_key.key_index, (u32)wpa_key.key_len); memset(&ndis_key, 0, sizeof(ndis_key)); ndis_key.struct_size = sizeof(ndis_key); ndis_key.length = wpa_key.key_len; ndis_key.index = wpa_key.key_index; if (wpa_key.seq && wpa_key.seq_len > 0) { for (i = 0, ndis_key.rsc = 0 ; i < wpa_key.seq_len ; i++) ndis_key.rsc |= (seq[i] << (i * 8)); ndis_key.index |= 1 << 29; } DBGTRACE1("infra_mode = %d, key.addr = %p, addr = " MACSTR, handle->infrastructure_mode, wpa_key.addr, MAC2STR(addr)); if (wpa_key.addr == NULL || memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) { /* group key */ if (handle->infrastructure_mode == Ndis802_11IBSS) memset(ndis_key.bssid, 0xff, ETH_ALEN); else get_ap_address(handle, ndis_key.bssid); } else { /* pairwise key */ ndis_key.index |= (1 << 30); memcpy(&ndis_key.bssid, addr, ETH_ALEN); } DBGTRACE2("bssid " MACSTR, MAC2STR(ndis_key.bssid)); if (wpa_key.set_tx) ndis_key.index |= (1 << 31); if (wpa_key.alg == WPA_ALG_TKIP && wpa_key.key_len == 32) { /* wpa_supplicant gives us the Michael MIC RX/TX keys in * different order than NDIS spec, so swap the order here. */ memcpy(ndis_key.key, key, 16); memcpy(ndis_key.key + 16, key + 24, 8); memcpy(ndis_key.key + 24, key + 16, 8); } else memcpy(ndis_key.key, key, wpa_key.key_len); if (wpa_key.alg == WPA_ALG_NONE || wpa_key.key_len == 0) { /* TI driver crashes kernel if OID_802_11_REMOVE_KEY is * called; other drivers seem to not require it, so * for now, don't remove the key from drvier */ handle->encr_info.keys[wpa_key.key_index].length = 0; memset(&handle->encr_info.keys[wpa_key.key_index].key, 0, wpa_key.key_len); DBGTRACE2("key %d removed", wpa_key.key_index); } else { res = miniport_set_info(handle, OID_802_11_ADD_KEY, &ndis_key, sizeof(ndis_key)); if (res == NDIS_STATUS_INVALID_DATA) { DBGTRACE2("adding key failed (%08X), %u", res, ndis_key.struct_size); TRACEEXIT2(return -1); } handle->encr_info.keys[wpa_key.key_index].length = wpa_key.key_len; memcpy(&handle->encr_info.keys[wpa_key.key_index].key, &ndis_key.key, wpa_key.key_len); if (wpa_key.set_tx) handle->encr_info.tx_key_index = wpa_key.key_index; DBGTRACE2("key %d added", wpa_key.key_index); } TRACEEXIT2(return 0);}static int wpa_disassociate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; unsigned char buf[NDIS_ESSID_MAX_SIZE]; int i; TRACEENTER2("%s", ""); get_random_bytes(buf, sizeof(buf)); for (i = 0; i < sizeof(buf); i++) buf[i] = 'a' + (buf[i] % ('z' - 'a')); set_essid(handle, buf, sizeof(buf)); TRACEEXIT2(return 0);}static int wpa_associate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; struct wpa_assoc_info wpa_assoc_info; char ssid[NDIS_ESSID_MAX_SIZE]; int auth_mode, encr_mode, priv_mode, size; TRACEENTER2("%s", ""); if (wrqu->data.length == 0) size = (void *)&wpa_assoc_info.key_mgmt_suite - (void *)&wpa_assoc_info.bssid; else { if (wrqu->data.length > sizeof(wpa_assoc_info)) size = sizeof(wpa_assoc_info); else size = wrqu->data.length; } memset(&wpa_assoc_info, 0, sizeof(wpa_assoc_info)); if (copy_from_user(&wpa_assoc_info, wrqu->data.pointer, size)) TRACEEXIT1(return -1); if (copy_from_user(&ssid, wpa_assoc_info.ssid, wpa_assoc_info.ssid_len)) TRACEEXIT1(return -1); /* setting the mode here clears the keys set earlier, so * ignore this request */ /* if (wpa_assoc_info.mode == IEEE80211_MODE_IBSS) set_infra_mode(handle, Ndis802_11IBSS); else set_infra_mode(handle, Ndis802_11Infrastructure); */ DBGTRACE1("key_mgmt_suite = %d, pairwise_suite = %d, group_suite= %d", wpa_assoc_info.key_mgmt_suite, wpa_assoc_info.pairwise_suite, wpa_assoc_info.group_suite); if (wpa_assoc_info.wpa_ie == NULL || wpa_assoc_info.wpa_ie_len == 0) { if (wpa_assoc_info.auth_alg & AUTH_ALG_SHARED_KEY) { if (wpa_assoc_info.auth_alg & AUTH_ALG_OPEN_SYSTEM) auth_mode = Ndis802_11AuthModeAutoSwitch; else auth_mode = Ndis802_11AuthModeShared; } else auth_mode = Ndis802_11AuthModeOpen; priv_mode = Ndis802_11PrivFilterAcceptAll; } else if (wpa_assoc_info.wpa_ie[0] == RSN_INFO_ELEM) { priv_mode = Ndis802_11PrivFilter8021xWEP; if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_PSK) auth_mode = Ndis802_11AuthModeWPA2PSK; else auth_mode = Ndis802_11AuthModeWPA2; } else { priv_mode = Ndis802_11PrivFilter8021xWEP; if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_WPA_NONE || wpa_assoc_info.key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) auth_mode = Ndis802_11AuthModeWPANone; else if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_PSK) auth_mode = Ndis802_11AuthModeWPAPSK; else auth_mode = Ndis802_11AuthModeWPA; } switch (wpa_assoc_info.pairwise_suite) { case CIPHER_CCMP: encr_mode = Ndis802_11Encryption3Enabled; break; case CIPHER_TKIP: encr_mode = Ndis802_11Encryption2Enabled; break; case CIPHER_WEP40: case CIPHER_WEP104: encr_mode = Ndis802_11Encryption1Enabled; break; case CIPHER_NONE: if (wpa_assoc_info.group_suite == CIPHER_CCMP) encr_mode = Ndis802_11Encryption3Enabled; else encr_mode = Ndis802_11Encryption2Enabled; break; default: encr_mode = Ndis802_11EncryptionDisabled; }; set_privacy_filter(handle, priv_mode); set_auth_mode(handle, auth_mode); set_encr_mode(handle, encr_mode);#if 0 /* set channel */ for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])); i++) { if (wpa_assoc_info.freq == freq_chan[i]) { union iwreq_data freq_req; memset(&freq_req, 0, sizeof(freq_req)); freq_req.freq.m = i; if (iw_set_freq(dev, NULL, &freq_req, NULL)) TRACEEXIT2(return -1); } }#endif /* set ssid */ if (set_essid(handle, ssid, wpa_assoc_info.ssid_len)) TRACEEXIT2(return -1); TRACEEXIT2(return 0);}static int wpa_set_countermeasures(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ TRACEENTER2("%s", ""); return 0;}static int wpa_deauthenticate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ int ret; TRACEENTER2("%s", ""); ret = wpa_disassociate(dev, info, wrqu, extra); TRACEEXIT2(return ret);}int set_privacy_filter(struct ndis_handle *handle, int flags){ NDIS_STATUS res; TRACEENTER2("filter: %d", flags); res = miniport_set_int(handle, OID_802_11_PRIVACY_FILTER, flags); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("setting privacy filter to %d failed (%08X)", flags, res); TRACEEXIT2(return -EINVAL); } TRACEEXIT2(return 0);}static int wpa_set_privacy_filter(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; int flags; TRACEENTER2("filter: %d", wrqu->param.value); if (wrqu->param.value) flags = Ndis802_11PrivFilter8021xWEP; else flags = Ndis802_11PrivFilterAcceptAll; if (set_privacy_filter(handle, flags)) TRACEEXIT2(return -1); TRACEEXIT2(return 0);}static int wpa_set_auth_alg(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = (struct ndis_handle *)dev->priv; int mode; if (wrqu->param.value & AUTH_ALG_SHARED_KEY) mode = Ndis802_11AuthModeShared; else if (wrqu->param.value & AUTH_ALG_OPEN_SYSTEM) mode = Ndis802_11AuthModeOpen; else TRACEEXIT2(return -1); DBGTRACE2("%d", mode); if (set_auth_mode(handle, mode)) TRACEEXIT2(return -1); TRACEEXIT2(return 0);}static const struct iw_priv_args priv_args[] = { {WPA_SET_WPA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setwpa"}, {WPA_SET_KEY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setkey"}, {WPA_ASSOCIATE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "associate"}, {WPA_DISASSOCIATE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "disassociate"}, {WPA_DROP_UNENCRYPTED, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypted"}, {WPA_SET_COUNTERMEASURES, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "countermeasures"}, {WPA_DEAUTHENTICATE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "deauthenticate"}, {WPA_SET_AUTH_ALG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "auth_alg"}, {PRIV_RESET, 0, 0, "ndis_reset"}, {PRIV_POWER_PROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "power_profile"}, {PRIV_NETWORK_TYPE, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "network_type"},};static const iw_handler priv_handler[] = { [WPA_SET_WPA - SIOCIWFIRSTPRIV] = wpa_set_wpa, [WPA_SET_KEY - SIOCIWFIRSTPRIV] = wpa_set_key, [WPA_ASSOCIATE - SIOCIWFIRSTPRIV] = wpa_associate, [WPA_DISASSOCIATE - SIOCIWFIRSTPRIV] = wpa_disassociate, [WPA_DROP_UNENCRYPTED - SIOCIWFIRSTPRIV] = wpa_set_privacy_filter, [WPA_SET_COUNTERMEASURES- SIOCIWFIRSTPRIV] = wpa_set_countermeasures, [WPA_DEAUTHENTICATE - SIOCIWFIRSTPRIV] = wpa_deauthenticate, [WPA_SET_AUTH_ALG - SIOCIWFIRSTPRIV] = wpa_set_auth_alg, [WPA_INIT - SIOCIWFIRSTPRIV] = wpa_init, [WPA_DEINIT - SIOCIWFIRSTPRIV] = wpa_deinit, [PRIV_RESET - SIOCIWFIRSTPRIV] = priv_reset, [PRIV_POWER_PROFILE - SIOCIWFIRSTPRIV] = priv_power_profile, [PRIV_NETWORK_TYPE - SIOCIWFIRSTPRIV] = priv_network_type,};const struct iw_handler_def ndis_handler_def = { .num_standard = sizeof(ndis_handler) / sizeof(ndis_handler[0]), .num_private = sizeof(priv_handler) / sizeof(priv_handler[0]), .num_private_args = sizeof(priv_args) / sizeof(priv_args[0]), .standard = (iw_handler *)ndis_handler, .private = (iw_handler *)priv_handler, .private_args = (struct iw_priv_args *)priv_args,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -