📄 iw_ndis.c
字号:
else nrates = NDIS_MAX_RATES; for (i = 0 ; i < nrates ; i++) { if (item->rates[i] & 0x7f) { iwe.u.bitrate.value = ((item->rates[i] & 0x7f) * 500000); current_val = iwe_stream_add_value(event, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } } if ((current_val - event) > IW_EV_LCP_LEN) event = current_val; memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; sprintf(buf, "bcn_int=%d", item->config.beacon_period); iwe.u.data.length = strlen(buf); event = iwe_stream_add_point(event, end_buf, &iwe, buf); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; sprintf(buf, "atim=%u", item->config.atim_window); iwe.u.data.length = strlen(buf); event = iwe_stream_add_point(event, end_buf, &iwe, buf); if (item->length > sizeof(*item)) { unsigned char *iep = (unsigned char *)item->ies + sizeof(struct ndis_fixed_ies); unsigned char *end = iep + item->ie_length; while (iep + 1 < end && iep + 2 + iep[1] <= end) { unsigned char ielen = 2 + iep[1]; if (ielen > SSID_MAX_WPA_IE_LEN) { iep += ielen; continue; } if (iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 && memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) { unsigned char *p = buf; p += sprintf(p, "wpa_ie="); for (i = 0; i < ielen; i++) p += sprintf(p, "%02x", iep[i]); DBGTRACE2("adding wpa_ie :%lu", (unsigned long)strlen(buf)); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; iwe.u.data.length = strlen(buf); event = iwe_stream_add_point(event, end_buf, &iwe, buf); } else if (iep[0] == WLAN_EID_RSN) { unsigned char *p = buf; for (i = 0; i < ielen; i++) p += sprintf(p, "%02x", iep[i]); DBGTRACE2("adding rsn_ie :%lu", (unsigned long)strlen(buf)); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; iwe.u.data.length = strlen(buf); event = iwe_stream_add_point(event, end_buf, &iwe, buf); } iep += ielen; } } DBGTRACE2("event = %p, current_val = %p", event, current_val); TRACEEXIT1(return event);}int set_scan(struct ndis_handle *handle){ NDIS_STATUS res; TRACEENTER1("%s", ""); res = miniport_set_int(handle, OID_802_11_BSSID_LIST_SCAN, 0); handle->scan_timestamp = jiffies; if (res == NDIS_STATUS_NOT_SUPPORTED || res == NDIS_STATUS_INVALID_DATA) { WARNING("scanning failed (%08X)", res); TRACEEXIT1(return -EOPNOTSUPP); } else TRACEEXIT1(return 0);}static int iw_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; return set_scan(handle);}static int iw_get_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; unsigned int i, list_len, needed; NDIS_STATUS res; struct ndis_bssid_list *bssid_list; char *event = extra; struct ndis_ssid_item *cur_item ; TRACEENTER1("%s", ""); if (time_before(jiffies, handle->scan_timestamp + 3 * HZ)) return -EAGAIN; /* try with space for a few scan items */ list_len = sizeof(ULONG) + sizeof(struct ndis_ssid_item) * 8; bssid_list = kmalloc(list_len, GFP_KERNEL); /* some drivers don't set bssid_list->num_items to 0 if OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */ memset(bssid_list, 0, list_len); res = miniport_query_info_needed(handle, OID_802_11_BSSID_LIST, bssid_list, list_len, &needed); if (needed > 0 || res == NDIS_STATUS_INVALID_LENGTH) { /* now try with required space */ kfree(bssid_list); list_len = needed; bssid_list = kmalloc(list_len, GFP_KERNEL); memset(bssid_list, 0, list_len); res = miniport_query_info(handle, OID_802_11_BSSID_LIST, bssid_list, list_len); } if (res == NDIS_STATUS_INVALID_DATA) { WARNING("getting BSSID list failed (%08X)", res); kfree(bssid_list); TRACEEXIT1(return -EOPNOTSUPP); } for (i = 0, cur_item = &bssid_list->items[0] ; i < bssid_list->num_items ; i++) { event = ndis_translate_scan(dev, event, extra + IW_SCAN_MAX_DATA, cur_item); cur_item = (struct ndis_ssid_item *)((char *)cur_item + cur_item->length); } wrqu->data.length = event - extra; wrqu->data.flags = 0; kfree(bssid_list); TRACEEXIT1(return 0);}static int iw_set_power_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; ULONG power_mode; if (wrqu->power.disabled == 1) power_mode = NDIS_POWER_OFF; else if (wrqu->power.flags & IW_POWER_MIN) power_mode = NDIS_POWER_MIN; else // if (wrqu->power.flags & IW_POWER_MAX) power_mode = NDIS_POWER_MAX; res = miniport_set_info(handle, OID_802_11_POWER_MODE, &power_mode, sizeof(power_mode)); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("setting power mode failed (%08X)", res); return -EINVAL; } return 0;}static int iw_get_power_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; ULONG power_mode; res = miniport_query_info(handle, OID_802_11_POWER_MODE, &power_mode, sizeof(power_mode)); if (res == NDIS_STATUS_NOT_SUPPORTED) return -EOPNOTSUPP; if (power_mode == NDIS_POWER_OFF) wrqu->power.disabled = 1; else { if (wrqu->power.flags != 0) return 0; wrqu->power.flags |= IW_POWER_ALL_R; wrqu->power.flags |= IW_POWER_TIMEOUT; wrqu->power.value = 0; wrqu->power.disabled = 0; if (power_mode == NDIS_POWER_MIN) wrqu->power.flags |= IW_POWER_MIN; else // if (power_mode == NDIS_POWER_MAX) wrqu->power.flags |= IW_POWER_MAX; } return 0;}static int iw_get_sensitivity(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; ndis_rssi rssi_trigger; res = miniport_query_info(handle, OID_802_11_RSSI_TRIGGER, &rssi_trigger, sizeof(rssi_trigger)); if (res) return -EOPNOTSUPP; wrqu->param.value = rssi_trigger; wrqu->param.disabled = (rssi_trigger == 0); wrqu->param.fixed = 1; return 0;}static int iw_set_sensitivity(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; NDIS_STATUS res; ndis_rssi rssi_trigger; if (wrqu->param.disabled) rssi_trigger = 0; else rssi_trigger = wrqu->param.value; res = miniport_set_info(handle, OID_802_11_RSSI_TRIGGER, &rssi_trigger, sizeof(rssi_trigger)); if (res) return -EINVAL; return 0;}static int iw_get_ndis_stats(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; struct iw_statistics *stats = &handle->wireless_stats; memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual)); return 0;}static int iw_get_range(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct iw_range *range = (struct iw_range *)extra; struct iw_point *data = &wrqu->data; struct ndis_handle *handle = (struct ndis_handle *)dev->priv; unsigned int i; NDIS_STATUS res; ndis_rates rates; ndis_tx_power_level tx_power; data->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); range->txpower_capa = IW_TXPOW_MWATT; range->num_txpower = 0; res = miniport_query_info(handle, OID_802_11_TX_POWER_LEVEL, &tx_power, sizeof(tx_power)); if (!res) { range->num_txpower = 1; range->txpower[0] = tx_power; } range->we_version_compiled = WIRELESS_EXT; range->we_version_source = 0; range->retry_capa = IW_RETRY_LIMIT; range->retry_flags = IW_RETRY_LIMIT; range->min_retry = 0; range->max_retry = 255; range->num_channels = 1; range->max_qual.qual = 100; range->max_qual.level = 154; range->max_qual.noise = 154; range->sensitivity = 3; range->max_encoding_tokens = 4; range->num_encoding_sizes = 2; range->encoding_size[0] = 5; range->encoding_size[1] = 13; range->num_bitrates = 0; res = miniport_query_info(handle, OID_802_11_SUPPORTED_RATES, &rates, sizeof(rates)); if (res) WARNING("getting bit rates failed: %08X", res); else { for (i = 0 ; i < NDIS_MAX_RATES_EX && range->num_bitrates < IW_MAX_BITRATES ; i++) if (rates[i] & 0x80) continue; else if (rates[i] & 0x7f) { range->bitrate[range->num_bitrates] = (rates[i] & 0x7f) * 500000; range->num_bitrates++; } } range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && i < IW_MAX_FREQUENCIES; i++) { range->freq[i].i = i + 1; range->freq[i].m = freq_chan[i] * 100000; range->freq[i].e = 1; } range->num_frequency = i; range->min_rts = 0; range->max_rts = 2347; range->min_frag = 256; range->max_frag = 2346; return 0;}static const iw_handler ndis_handler[] = { [SIOCGIWNAME - SIOCIWFIRST] = iw_get_network_type, [SIOCSIWESSID - SIOCIWFIRST] = iw_set_essid, [SIOCGIWESSID - SIOCIWFIRST] = iw_get_essid, [SIOCSIWMODE - SIOCIWFIRST] = iw_set_infra_mode, [SIOCGIWMODE - SIOCIWFIRST] = iw_get_infra_mode, [SIOCGIWFREQ - SIOCIWFIRST] = iw_get_freq, [SIOCSIWFREQ - SIOCIWFIRST] = iw_set_freq, [SIOCGIWTXPOW - SIOCIWFIRST] = iw_get_tx_power, [SIOCSIWTXPOW - SIOCIWFIRST] = iw_set_tx_power, [SIOCGIWRATE - SIOCIWFIRST] = iw_get_bitrate, [SIOCSIWRATE - SIOCIWFIRST] = iw_set_bitrate, [SIOCGIWRTS - SIOCIWFIRST] = iw_get_rts_threshold, [SIOCGIWFRAG - SIOCIWFIRST] = iw_get_frag_threshold, [SIOCGIWAP - SIOCIWFIRST] = iw_get_ap_address, [SIOCSIWAP - SIOCIWFIRST] = iw_set_ap_address, [SIOCSIWENCODE - SIOCIWFIRST] = iw_set_encr, [SIOCGIWENCODE - SIOCIWFIRST] = iw_get_encr, [SIOCSIWSCAN - SIOCIWFIRST] = iw_set_scan, [SIOCGIWSCAN - SIOCIWFIRST] = iw_get_scan, [SIOCGIWPOWER - SIOCIWFIRST] = iw_get_power_mode, [SIOCSIWPOWER - SIOCIWFIRST] = iw_set_power_mode, [SIOCGIWRANGE - SIOCIWFIRST] = iw_get_range, [SIOCGIWSTATS - SIOCIWFIRST] = iw_get_ndis_stats, [SIOCGIWSENS - SIOCIWFIRST] = iw_get_sensitivity, [SIOCSIWSENS - SIOCIWFIRST] = iw_set_sensitivity, [SIOCGIWNICKN - SIOCIWFIRST] = iw_get_nick, [SIOCSIWNICKN - SIOCIWFIRST] = iw_set_nick, [SIOCSIWCOMMIT - SIOCIWFIRST] = iw_set_dummy,};/* private ioctl's */static int priv_reset(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ int res; res = miniport_reset(dev->priv); if (res) { WARNING("reset returns %08X", res); return -EOPNOTSUPP; } return 0;}static int priv_power_profile(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; struct miniport_char *miniport = &handle->driver->miniport_char; ULONG profile_inf; miniport = &handle->driver->miniport_char; if (!miniport->pnp_event_notify) TRACEEXIT2(return -EOPNOTSUPP); /* 1 for AC and 0 for Battery */ if (wrqu->param.value) profile_inf = NdisPowerProfileAcOnLine; else profile_inf = NdisPowerProfileBattery; miniport->pnp_event_notify(handle->adapter_ctx, NdisDevicePnPEventPowerProfileChanged, &profile_inf, sizeof(profile_inf)); TRACEEXIT2(return 0);}static int priv_network_type(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; enum network_type network_type; NDIS_STATUS res; char type; 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') network_type = Ndis802_11OFDM24; else network_type = Ndis802_11Automode; res = miniport_set_int(handle, OID_802_11_NETWORK_TYPE_IN_USE, network_type); if (res == NDIS_STATUS_INVALID_DATA) { WARNING("setting network type to %d failed (%08X)",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -