📄 hostap_ioctl.c
字号:
if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) < 0) return -EINVAL; switch (val) { case HFA384X_RATES_1MBPS: rrq->value = 1000000; break; case HFA384X_RATES_2MBPS: rrq->value = 2000000; break; case HFA384X_RATES_5MBPS: rrq->value = 5500000; break; case HFA384X_RATES_11MBPS: rrq->value = 11000000; break; default: /* should not happen */ rrq->value = 11000000; ret = -EINVAL; break; } return ret;}static int prism2_ioctl_siwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; /* Set the desired AP density */ if (sens->value < 1 || sens->value > 3) return -EINVAL; if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) || local->func->reset_port(dev)) return -EINVAL; return 0;}static int prism2_ioctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; /* Get the current AP density */ if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) < 0) return -EINVAL; sens->value = __le16_to_cpu(val); sens->fixed = 1; return 0;}/* Deprecated in new wireless extension API */static int prism2_ioctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; struct sockaddr addr[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; if (local->iw_mode != IW_MODE_MASTER) { printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported " "in Host AP mode\n"); data->length = 0; return -EOPNOTSUPP; } data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); memcpy(extra, &addr, sizeof(addr[0]) * data->length); data->flags = 1; /* has quality information */ memcpy(extra + sizeof(addr[0]) * data->length, &qual, sizeof(qual[0]) * data->length); return 0;}static int prism2_ioctl_siwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (rts->disabled) val = __constant_cpu_to_le16(2347); else if (rts->value < 0 || rts->value > 2347) return -EINVAL; else val = __cpu_to_le16(rts->value); if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) || local->func->reset_port(dev)) return -EINVAL; local->rts_threshold = rts->value; return 0;}static int prism2_ioctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) < 0) return -EINVAL; rts->value = __le16_to_cpu(val); rts->disabled = (rts->value == 2347); rts->fixed = 1; return 0;}static int prism2_ioctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (rts->disabled) val = __constant_cpu_to_le16(2346); else if (rts->value < 256 || rts->value > 2346) return -EINVAL; else val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */ local->fragm_threshold = rts->value & ~0x1; if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val, 2) || local->func->reset_port(dev)) return -EINVAL; return 0;}static int prism2_ioctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val, 2, 1) < 0) return -EINVAL; rts->value = __le16_to_cpu(val); rts->disabled = (rts->value == 2346); rts->fixed = 1; return 0;}#ifndef PRISM2_NO_STATION_MODESstatic int hostap_join_ap(struct net_device *dev){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; struct hfa384x_join_request req; unsigned long flags; int i; struct hfa384x_hostscan_result *entry; memcpy(req.bssid, local->preferred_ap, ETH_ALEN); req.channel = 0; spin_lock_irqsave(&local->lock, flags); for (i = 0; i < local->last_scan_results_count; i++) { if (!local->last_scan_results) break; entry = &local->last_scan_results[i]; if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) { req.channel = entry->chid; break; } } spin_unlock_irqrestore(&local->lock, flags); if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req, sizeof(req))) { printk(KERN_DEBUG "%s: JoinRequest " MACSTR " failed\n", dev->name, MAC2STR(local->preferred_ap)); return -1; } printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n", dev->name, MAC2STR(local->preferred_ap)); return 0;}#endif /* PRISM2_NO_STATION_MODES */static int prism2_ioctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra){#ifdef PRISM2_NO_STATION_MODES return -EOPNOTSUPP;#else /* PRISM2_NO_STATION_MODES */ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN); if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) { struct hfa384x_scan_request scan_req; memset(&scan_req, 0, sizeof(scan_req)); scan_req.channel_list = __constant_cpu_to_le16(0x3fff); scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS); if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req, sizeof(scan_req))) { printk(KERN_DEBUG "%s: ScanResults request failed - " "preferred AP delayed to next unsolicited " "scan\n", dev->name); } } else if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA) { if (hostap_join_ap(dev)) return -EINVAL; } else { printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only " "in Managed mode when host_roaming is enabled\n", dev->name); } return 0;#endif /* PRISM2_NO_STATION_MODES */}static int prism2_ioctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; ap_addr->sa_family = ARPHRD_ETHER; switch (iface->type) { case HOSTAP_INTERFACE_AP: memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN); break; case HOSTAP_INTERFACE_STA: memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN); break; case HOSTAP_INTERFACE_WDS: memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN); break; default: if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID, &ap_addr->sa_data, ETH_ALEN, 1) < 0) return -EOPNOTSUPP; /* local->bssid is also updated in LinkStatus handler when in * station mode */ memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN); break; } return 0;}static int prism2_ioctl_siwnickn(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; memset(local->name, 0, sizeof(local->name)); memcpy(local->name, nickname, data->length); local->name_set = 1; if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) || local->func->reset_port(dev)) return -EINVAL; return 0;}static int prism2_ioctl_giwnickn(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; int len; char name[MAX_NAME_LEN + 3]; u16 val; len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME, &name, MAX_NAME_LEN + 2, 0); val = __le16_to_cpu(*(u16 *) name); if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN) return -EOPNOTSUPP; name[val + 2] = '\0'; data->length = val + 1; memcpy(nickname, name + 2, val + 1); return 0;}static int prism2_ioctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; /* freq => chan. */ if (freq->e == 1 && freq->m / 100000 >= freq_list[0] && freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) { int ch; int fr = freq->m / 100000; for (ch = 0; ch < FREQ_COUNT; ch++) { if (fr == freq_list[ch]) { freq->e = 0; freq->m = ch + 1; break; } } } if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT || !(local->channel_mask & (1 << (freq->m - 1)))) return -EINVAL; local->channel = freq->m; /* channel is used in prism2_setup_rids() */ if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) || local->func->reset_port(dev)) return -EINVAL; return 0;}static int prism2_ioctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) < 0) return -EINVAL; le16_to_cpus(&val); if (val < 1 || val > FREQ_COUNT) return -EINVAL; freq->m = freq_list[val - 1] * 100000; freq->e = 1; return 0;}static void hostap_monitor_set_type(local_info_t *local){ struct net_device *dev = local->ddev; if (dev == NULL) return; if (local->monitor_type == PRISM2_MONITOR_PRISM || local->monitor_type == PRISM2_MONITOR_CAPHDR) { dev->type = ARPHRD_IEEE80211_PRISM; dev->hard_header_parse = hostap_80211_prism_header_parse; } else { dev->type = ARPHRD_IEEE80211; dev->hard_header_parse = hostap_80211_header_parse; }}static int prism2_ioctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; if (iface->type == HOSTAP_INTERFACE_WDS) return -EOPNOTSUPP; if (data->flags == 0) ssid[0] = '\0'; /* ANY */ if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') { /* Setting SSID to empty string seems to kill the card in * Host AP mode */ printk(KERN_DEBUG "%s: Host AP mode does not support " "'Any' essid\n", dev->name); return -EINVAL; } memcpy(local->essid, ssid, data->length); local->essid[data->length] = '\0'; if ((!local->fw_ap && hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid)) || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) || local->func->reset_port(dev)) return -EINVAL; return 0;}static int prism2_ioctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *essid){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 val; if (iface->type == HOSTAP_INTERFACE_WDS) return -EOPNOTSUPP; data->flags = 1; /* active */ if (local->iw_mode == IW_MODE_MASTER) { data->length = strlen(local->essid); memcpy(essid, local->essid, IW_ESSID_MAX_SIZE); } else { int len; char ssid[MAX_SSID_LEN + 2]; memset(ssid, 0, sizeof(ssid)); len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID, &ssid, MAX_SSID_LEN + 2, 0); val = __le16_to_cpu(*(u16 *) ssid); if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) { return -EOPNOTSUPP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -