📄 iw_ndis.c
字号:
res = miniport_query_info(handle, OID_802_11_RTS_THRESHOLD, &rts_threshold, sizeof(rts_threshold)); if (res == NDIS_STATUS_NOT_SUPPORTED) return -EOPNOTSUPP; wrqu->rts.value = rts_threshold; return 0;}static int iw_get_frag_threshold(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; ndis_fragmentation_threshold frag_threshold; NDIS_STATUS res; res = miniport_query_info(handle, OID_802_11_FRAGMENTATION_THRESHOLD, &frag_threshold, sizeof(frag_threshold)); if (res == NDIS_STATUS_NOT_SUPPORTED) return -EOPNOTSUPP; wrqu->frag.value = frag_threshold; return 0;}int get_ap_address(struct ndis_handle *handle, mac_address ap_addr){ NDIS_STATUS res; TRACEENTER1("%s", ""); res = miniport_query_info(handle, OID_802_11_BSSID, ap_addr, ETH_ALEN); if (res == NDIS_STATUS_ADAPTER_NOT_READY) memset(ap_addr, 0, ETH_ALEN); DBGTRACE1(MACSTR, MAC2STR(ap_addr)); TRACEEXIT1(return 0);}static int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; mac_address ap_addr; TRACEENTER1("%s", ""); get_ap_address(handle, ap_addr); memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN); wrqu->ap_addr.sa_family = ARPHRD_ETHER; TRACEEXIT1(return 0);}static int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; mac_address ap_addr; memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN); DBGTRACE1(MACSTR, MAC2STR(ap_addr)); res = miniport_set_info(handle, OID_802_11_BSSID, ap_addr, ETH_ALEN); if (res) { WARNING("setting AP mac address failed (%08X)", res); TRACEEXIT1(return -EINVAL); } TRACEEXIT1(return 0);}int set_auth_mode(struct ndis_handle *handle, int auth_mode){ NDIS_STATUS res; res = miniport_set_int(handle, OID_802_11_AUTHENTICATION_MODE, auth_mode); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("setting auth mode failed (%08X)", res); TRACEEXIT2(return -EINVAL); } else { handle->auth_mode = auth_mode; TRACEEXIT2(return 0); }}int set_encr_mode(struct ndis_handle *handle, int encr_mode){ NDIS_STATUS res; res = miniport_set_int(handle, OID_802_11_ENCRYPTION_STATUS, encr_mode); if (res == NDIS_STATUS_INVALID_DATA) TRACEEXIT2(return -EINVAL); else { handle->encr_mode = encr_mode; TRACEEXIT2(return 0); }}static int iw_get_encr(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; int index, status; struct encr_info *encr_info = &handle->encr_info; TRACEENTER2("handle = %p", handle); wrqu->data.length = 0; extra[0] = 0; index = (wrqu->encoding.flags & IW_ENCODE_INDEX); DBGTRACE2("index = %u", index); if (index > 0) index--; else index = encr_info->tx_key_index; if (index < 0 || index >= MAX_ENCR_KEYS) { WARNING("encryption index out of range (%u)", index); TRACEEXIT1(return -EINVAL); } if (index != encr_info->tx_key_index) { if (encr_info->keys[index].length > 0) { wrqu->data.flags |= IW_ENCODE_ENABLED; wrqu->data.length = encr_info->keys[index].length; memcpy(extra, encr_info->keys[index].key, encr_info->keys[index].length); } else wrqu->data.flags |= IW_ENCODE_DISABLED; TRACEEXIT1(return 0); } /* transmit key */ res = miniport_query_int(handle, OID_802_11_ENCRYPTION_STATUS, &status); if (res == NDIS_STATUS_NOT_SUPPORTED) { WARNING("getting encryption status failed (%08X)", res); TRACEEXIT1(return -EOPNOTSUPP); } if (status == Ndis802_11EncryptionDisabled || status == Ndis802_11EncryptionNotSupported) wrqu->data.flags |= IW_ENCODE_DISABLED; else { if (status == Ndis802_11Encryption1KeyAbsent || status == Ndis802_11Encryption2KeyAbsent || status == Ndis802_11Encryption3KeyAbsent) wrqu->data.flags |= IW_ENCODE_NOKEY; else { wrqu->data.flags |= IW_ENCODE_ENABLED; wrqu->encoding.flags |= index+1; wrqu->data.length = encr_info->keys[index].length; memcpy(extra, encr_info->keys[index].key, encr_info->keys[index].length); } } res = miniport_query_int(handle, OID_802_11_AUTHENTICATION_MODE, &status); if (res == NDIS_STATUS_NOT_SUPPORTED) { WARNING("getting authentication mode failed (%08X)", res); TRACEEXIT1(return -EOPNOTSUPP); } if (status == Ndis802_11AuthModeOpen) wrqu->data.flags |= IW_ENCODE_OPEN; else if (status == Ndis802_11AuthModeShared) wrqu->data.flags |= IW_ENCODE_RESTRICTED; else if (status == Ndis802_11AuthModeAutoSwitch) wrqu->data.flags |= IW_ENCODE_RESTRICTED; TRACEEXIT1(return 0);}/* index must be 0 - N, as per NDIS */int add_wep_key(struct ndis_handle *handle, char *key, int key_len, int index){ struct ndis_encr_key ndis_key; NDIS_STATUS res; TRACEENTER2("key index: %d", index); if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) { WARNING("invalid key length (%d)", key_len); TRACEEXIT2(return -EINVAL); } if (index < 0 || index >= MAX_ENCR_KEYS) { WARNING("invalid key index (%d)", index); TRACEEXIT2(return -EINVAL); } ndis_key.struct_size = sizeof(ndis_key); ndis_key.length = key_len; memcpy(&ndis_key.key, key, key_len); ndis_key.index = index; if (index == handle->encr_info.tx_key_index) ndis_key.index |= (1 << 31); res = miniport_set_info(handle, OID_802_11_ADD_WEP, &ndis_key, sizeof(ndis_key)); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("adding encryption key %d failed (%08X)", index+1, res); TRACEEXIT1(return -EINVAL); } /* Atheros driver messes up ndis_key during ADD_WEP, so * don't rely on that; instead use info in key and key_len */ handle->encr_info.keys[index].length = key_len; memcpy(&handle->encr_info.keys[index].key, key, key_len); if (index == handle->encr_info.tx_key_index) { res = set_encr_mode(handle, Ndis802_11Encryption1Enabled); if (res) WARNING("encryption couldn't be enabled (%08X)", res); } TRACEEXIT1(return 0);}static int iw_set_encr(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; unsigned int index, key_len; struct encr_info *encr_info = &handle->encr_info; unsigned char *key; TRACEENTER1("%s", ""); index = (wrqu->encoding.flags & IW_ENCODE_INDEX); DBGTRACE2("index = %u", index); /* iwconfig gives index as 1 - N */ if (index > 0) index--; else index = encr_info->tx_key_index; if (index < 0 || index >= MAX_ENCR_KEYS) { WARNING("encryption index out of range (%u)", index); TRACEEXIT1(return -EINVAL); } /* remove key if disabled */ if (wrqu->data.flags & IW_ENCODE_DISABLED) { ndis_key_index keyindex = index; res = miniport_set_info(handle, OID_802_11_REMOVE_WEP, &keyindex, sizeof(keyindex)); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("removing encryption key %d failed (%08X)", index, res); TRACEEXIT1(return -EINVAL); } encr_info->keys[index].length = 0; /* if it is transmit key, disable encryption */ if (index == encr_info->tx_key_index) { res = set_encr_mode(handle, Ndis802_11EncryptionDisabled); if (res) WARNING("changing encr status failed (%08X)", res); } TRACEEXIT1(return 0); } /* global encryption state (for all keys) */ if (wrqu->data.flags & IW_ENCODE_OPEN) res = set_auth_mode(handle, Ndis802_11AuthModeOpen); else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED) res = set_auth_mode(handle, Ndis802_11AuthModeShared); if (res) { WARNING("setting authentication mode failed (%08X)", res); TRACEEXIT1(return -EINVAL); } DBGTRACE2("key length: %d", wrqu->data.length); if (wrqu->data.length > 0) { key_len = wrqu->data.length; key = wrqu->data.pointer; } else { // must be set as tx key if (encr_info->keys[index].length == 0) { WARNING("key %d is not set", index+1); TRACEEXIT1(return -EINVAL); } key_len = encr_info->keys[index].length; key = encr_info->keys[index].key; encr_info->tx_key_index = index; } if (add_wep_key(handle, key, key_len, index)) TRACEEXIT2(return -EINVAL); if (index == encr_info->tx_key_index) { /* if transmit key is at index other than 0, some * drivers, at least Atheros and TI, want another * (global) non-transmit key to be set; don't know why */ if (index != 0) { int i; for (i = 0; i < MAX_ENCR_KEYS; i++) if (i != index && encr_info->keys[i].length != 0) break; if (i == MAX_ENCR_KEYS) { if (index == 0) i = index + 1; else i = index - 1; if (add_wep_key(handle, key, key_len, i)) WARNING("couldn't add broadcast key" " at %d", i); } } /* ndis drivers want essid to be set after setting encr */ set_essid(handle, handle->essid.essid, handle->essid.length); } TRACEEXIT1(return 0);} static int iw_set_nick(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; if (wrqu->data.length > IW_ESSID_MAX_SIZE) return -EINVAL; memcpy(handle->nick, extra, wrqu->data.length); handle->nick[IW_ESSID_MAX_SIZE] = 0; return 0;}static int iw_get_nick(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; memcpy(extra, handle->nick, IW_ESSID_MAX_SIZE+1); wrqu->data.length = strlen(handle->nick); return 0;}static char *ndis_translate_scan(struct net_device *dev, char *event, char *end_buf, struct ndis_ssid_item *item){ struct iw_event iwe; char *current_val; int i, nrates; unsigned char buf[MAX_WPA_IE_LEN * 2 + 30]; TRACEENTER1("%p, %p", event, item); /* add mac address */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.len = IW_EV_ADDR_LEN; memcpy(iwe.u.ap_addr.sa_data, item->mac, ETH_ALEN); event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_ADDR_LEN); /* add essid */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; iwe.u.data.length = item->ssid.length; if (iwe.u.data.length > IW_ESSID_MAX_SIZE) iwe.u.data.length = IW_ESSID_MAX_SIZE; iwe.u.data.flags = 1; iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; event = iwe_stream_add_point(event, end_buf, &iwe, item->ssid.essid); /* add protocol name */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWNAME; strncpy(iwe.u.name, network_type_to_name(item->net_type), IFNAMSIZ); event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_CHAR_LEN); /* add mode */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (item->mode == Ndis802_11IBSS) iwe.u.mode = IW_MODE_ADHOC; else if (item->mode == Ndis802_11Infrastructure) iwe.u.mode = IW_MODE_INFRA; else // if (item->mode == Ndis802_11AutoUnknown) iwe.u.mode = IW_MODE_AUTO; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_UINT_LEN); /* add freq */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; iwe.u.freq.m = item->config.ds_config; if (item->config.ds_config > 1000000) { iwe.u.freq.m = item->config.ds_config / 10; iwe.u.freq.e = 1; } else iwe.u.freq.m = item->config.ds_config; /* convert from kHz to Hz */ iwe.u.freq.e += 3; iwe.len = IW_EV_FREQ_LEN; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_FREQ_LEN); /* add qual */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; iwe.u.qual.level = item->rssi; iwe.u.qual.noise = 0; iwe.u.qual.qual = 0; iwe.len = IW_EV_QUAL_LEN; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_QUAL_LEN); /* add key info */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; if (item->privacy == Ndis802_11PrivFilterAcceptAll) iwe.u.data.flags = IW_ENCODE_DISABLED; else iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; iwe.u.data.length = 0; iwe.len = IW_EV_POINT_LEN; event = iwe_stream_add_point(event, end_buf, &iwe, item->ssid.essid); /* add rate */ memset(&iwe, 0, sizeof(iwe)); current_val = event + IW_EV_LCP_LEN; iwe.cmd = SIOCGIWRATE; if (item->length > sizeof(struct ndis_ssid_item)) nrates = NDIS_MAX_RATES_EX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -