📄 iw_ndis.c
字号:
struct wrap_ndis_device *wnd = netdev_priv(dev); enum network_type network_type; NDIS_STATUS res; char type; ENTER2(""); type = wrqu->param.value; if (type == 'f') network_type = Ndis802_11FH; else if (type == 'b') network_type = Ndis802_11DS; else if (type == 'a') network_type = Ndis802_11OFDM5; else if (type == 'g' || type == 'n') network_type = Ndis802_11OFDM24; else network_type = Ndis802_11Automode; res = miniport_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, network_type); if (res) { WARNING("setting network type to %d failed (%08X)", network_type, res); EXIT2(return -EINVAL); } EXIT2(return 0);}static int priv_media_stream_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); NDIS_STATUS res; int mode; ENTER2(""); if (wrqu->param.value > 0) mode = Ndis802_11MediaStreamOn; else mode = Ndis802_11MediaStreamOff; res = miniport_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode); if (res) { WARNING("oid failed (%08X)", res); EXIT2(return -EINVAL); } EXIT2(return 0);}static int priv_set_encr_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); int res; ENTER2(""); res = set_encr_mode(wnd, wrqu->param.value); if (res < 0) EXIT2(return -1); EXIT2(return 0);}static int priv_set_auth_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); int res; ENTER2(""); res = set_auth_mode(wnd, wrqu->param.value); if (res < 0) EXIT2(return -1); EXIT2(return 0);}static int priv_reload_defaults(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); int res; ENTER2(""); res = miniport_set_int(wnd, OID_802_11_RELOAD_DEFAULTS, Ndis802_11ReloadWEPKeys); if (res) { WARNING("reloading defaults failed: %08X", res); return -EOPNOTSUPP; } return 0;}#if WIRELESS_EXT <= 17/* WPA support through 'ndiswrapper' driver interface */static int wpa_init(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); ENTER2(""); if (test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) || test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) || test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) EXIT2(return 0); else { WARNING("driver is not WEP/WPA capable"); EXIT2(return -1); }}static int wpa_deinit(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ ENTER2(""); EXIT2(return 0);}static int wpa_set_wpa(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); ENTER2("flags = %d, wnd->capa.encr = %ld", wrqu->data.flags, wnd->capa.encr); if (wrqu->data.flags) { if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) || test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) EXIT2(return 0); else { WARNING("driver is not WPA capable"); EXIT2(return -1); } } else EXIT2(return 0);}static int wpa_set_key(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); 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]; ENTER2(""); if (wrqu->data.length) size = wrqu->data.length; else size = sizeof(wpa_key); if (copy_from_user(&wpa_key, wrqu->data.pointer, size)) EXIT2(return -EFAULT); if (wpa_key.addr && copy_from_user(&addr, wpa_key.addr, ETH_ALEN)) EXIT2(return -EFAULT); if (wpa_key.seq && copy_from_user(&seq, wpa_key.seq, wpa_key.seq_len)) EXIT2(return -EFAULT); if (wpa_key.key && copy_from_user(&key, wpa_key.key, wpa_key.key_len)) EXIT2(return -EFAULT); TRACE2("alg = %d, key_index = %d", wpa_key.alg, wpa_key.key_index); if (wpa_key.alg == WPA_ALG_WEP) { if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr)) EXIT2(return -1); if (wpa_key.set_tx) wnd->encr_info.tx_key_index = wpa_key.key_index; if (add_wep_key(wnd, key, wpa_key.key_len, wpa_key.key_index)) EXIT2(return -1); else EXIT2(return 0); } if (wpa_key.key_len > sizeof(ndis_key.key)) { TRACE2("incorrect key length (%u)", (u32)wpa_key.key_len); EXIT2(return -1); } if (wpa_key.seq_len > IW_ENCODING_TOKEN_MAX) { TRACE2("incorrect seq? length = (%u)", (u32)wpa_key.seq_len); EXIT2(return -1); } TRACE2("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) - sizeof(ndis_key.key) + wpa_key.key_len; 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; } TRACE2("infra_mode = %d, key.addr = %p, addr = " MACSTRSEP, wnd->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 (wnd->infrastructure_mode == Ndis802_11IBSS) memset(ndis_key.bssid, 0xff, ETH_ALEN); else get_ap_address(wnd, ndis_key.bssid); } else { /* pairwise key */ ndis_key.index |= (1 << 30); memcpy(&ndis_key.bssid, addr, ETH_ALEN); } TRACE2("bssid " MACSTRSEP, 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 */ wnd->encr_info.keys[wpa_key.key_index].length = 0; memset(&wnd->encr_info.keys[wpa_key.key_index].key, 0, wpa_key.key_len); TRACE2("key %d removed", wpa_key.key_index); } else { res = miniport_set_info(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); if (res) { TRACE2("adding key failed (%08X), %u", res, ndis_key.struct_size); EXIT2(return -1); } wnd->encr_info.keys[wpa_key.key_index].length = wpa_key.key_len; memcpy(&wnd->encr_info.keys[wpa_key.key_index].key, &ndis_key.key, wpa_key.key_len); if (wpa_key.set_tx) wnd->encr_info.tx_key_index = wpa_key.key_index; TRACE2("key %d added", wpa_key.key_index); } EXIT2(return 0);}static int wpa_disassociate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); disassociate(wnd, 1); EXIT2(return 0);}static int wpa_associate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); struct wpa_assoc_info wpa_assoc_info; char ssid[NDIS_ESSID_MAX_SIZE]; int infra_mode, auth_mode, encr_mode, priv_mode, size; ENTER2(""); memset(&wpa_assoc_info, 0, sizeof(wpa_assoc_info)); wpa_assoc_info.mode = IEEE80211_MODE_INFRA; if (wrqu->data.length == 0) size = (void *)&wpa_assoc_info.auth_alg - (void *)&wpa_assoc_info.bssid; else size = min((size_t)wrqu->data.length, sizeof(wpa_assoc_info)); if (copy_from_user(&wpa_assoc_info, wrqu->data.pointer, size)) EXIT2(return -EFAULT); if (copy_from_user(&ssid, wpa_assoc_info.ssid, wpa_assoc_info.ssid_len)) EXIT2(return -EFAULT); if (wpa_assoc_info.mode == IEEE80211_MODE_IBSS) infra_mode = Ndis802_11IBSS; else infra_mode = Ndis802_11Infrastructure; TRACE2("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 if (wpa_assoc_info.group_suite == CIPHER_TKIP) encr_mode = Ndis802_11Encryption2Enabled; else encr_mode = Ndis802_11EncryptionDisabled; break; default: encr_mode = Ndis802_11EncryptionDisabled; }; set_infra_mode(wnd, infra_mode); set_priv_filter(wnd, priv_mode); set_auth_mode(wnd, auth_mode); set_encr_mode(wnd, 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)) EXIT2(return -1); } }#endif /* set ssid */ if (set_essid(wnd, ssid, wpa_assoc_info.ssid_len)) EXIT2(return -1); EXIT2(return 0);}static int wpa_set_countermeasures(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ ENTER2(""); return 0;}static int wpa_deauthenticate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); EXIT2(return deauthenticate(wnd));}static int wpa_set_priv_filter(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); int flags; ENTER2("filter: %d", wrqu->param.value); if (wrqu->param.value) flags = Ndis802_11PrivFilter8021xWEP; else flags = Ndis802_11PrivFilterAcceptAll; if (set_priv_filter(wnd, flags)) EXIT2(return -1); EXIT2(return 0);}static int wpa_set_auth_alg(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); int mode; ENTER2(""); if (wrqu->param.value & AUTH_ALG_SHARED_KEY) mode = Ndis802_11AuthModeShared; else if (wrqu->param.value & AUTH_ALG_OPEN_SYSTEM) mode = Ndis802_11AuthModeOpen; else EXIT2(return -1); TRACE2("%d", mode); if (set_auth_mode(wnd, mode)) EXIT2(return -1); EXIT2(return 0);}static int wpa_get_capa(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct wrap_ndis_device *wnd = netdev_priv(dev); struct wpa_driver_capa *drv_capa; ENTER2("%p", wnd); drv_capa = (struct wpa_driver_capa *)wrqu->data.pointer; if (!drv_capa) EXIT2(return -1); drv_capa->key_mgmt = 0; if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth)) drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; if (test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth)) drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth)) drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2; if (test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth)) drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; if (test_bit(Ndis802_11AuthModeWPANone, &wnd->capa.auth)) drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE; drv_capa->enc = 0; if (test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr)) drv_capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104; if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr)) drv_capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP; if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) drv_capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP; /* TODO: how to check if LEAP is supported? */ drv_capa->auth = WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED; drv_capa->flags = WPA_DRIVER_FLAGS_DRIVER_IE | WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC; EXIT2(return 0);}#endif // WIRELESS_EXT <= 17static const struct iw_priv_args priv_args[] = {#if WIRELESS_EXT <= 17 {W
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -