📄 driver_devicescape.c
字号:
}static int i802_set_assoc_ap(void *priv, const u8 *addr){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR; memcpy(param.sta_addr, addr, ETH_ALEN); if (hostapd_ioctl(drv, ¶m, sizeof(param))) { printf("Could not set associated AP address to kernel " "driver.\n"); return -1; } return 0;}static int i802_sta_add(const char *ifname, void *priv, const u8 *addr, u16 aid, u16 capability, u8 *supp_rates, size_t supp_rates_len, int flags){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; int len; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_ADD_STA; memcpy(param.sta_addr, addr, ETH_ALEN); param.u.add_sta.aid = aid; param.u.add_sta.capability = capability; len = supp_rates_len; if (len > sizeof(param.u.add_sta.supp_rates)) len = sizeof(param.u.add_sta.supp_rates); memcpy(param.u.add_sta.supp_rates, supp_rates, len); return hostapd_ioctl_iface(ifname, drv, ¶m, sizeof(param));}static int i802_sta_remove(void *priv, const u8 *addr){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; i802_sta_set_flags(drv, addr, 0, ~WLAN_STA_AUTHORIZED); memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_REMOVE_STA; memcpy(param.sta_addr, addr, ETH_ALEN); if (hostapd_ioctl(drv, ¶m, sizeof(param))) return -1; return 0;}static int i802_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA; memcpy(param.sta_addr, addr, ETH_ALEN); param.u.set_flags_sta.flags_or = flags_or; param.u.set_flags_sta.flags_and = flags_and; return hostapd_ioctl(drv, ¶m, sizeof(param));}static int i802_set_generic_elem(void *priv, const u8 *elem, size_t elem_len){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param *param; u8 *buf; size_t blen; int ret = 0; blen = sizeof(*param) + elem_len; buf = wpa_zalloc(blen); if (buf == NULL) return -1; param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_HOSTAPD_SET_GENERIC_INFO_ELEM; param->u.set_generic_info_elem.len = elem_len; memcpy(param->u.set_generic_info_elem.data, elem, elem_len); if (hostapd_ioctl(drv, param, blen)) { printf("%s: Failed to set generic info element\n", drv->iface); ret = -1; } free(buf); return ret;}static int i802_set_channel_flag(void *priv, int mode, int chan, int flag, unsigned char power_level, unsigned char antenna_max){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_CHANNEL_FLAG; switch (mode) { case HOSTAPD_MODE_IEEE80211A: param.u.set_channel_flag.mode = MODE_IEEE80211A; break; case HOSTAPD_MODE_IEEE80211B: param.u.set_channel_flag.mode = MODE_IEEE80211B; break; case HOSTAPD_MODE_IEEE80211G: param.u.set_channel_flag.mode = MODE_IEEE80211G; break; } param.u.set_channel_flag.chan = chan; param.u.set_channel_flag.flag = flag; param.u.set_channel_flag.power_level = power_level; param.u.set_channel_flag.antenna_max = antenna_max; if (hostapd_ioctl(drv, ¶m, sizeof(param))) { printf("Failed to set channel flag (mode=%d chan=%d flag=0x%x)" "\n", mode, chan, flag); return -1; } return 0;}static int i802_set_regulatory_domain(void *priv, unsigned int rd){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN; param.u.set_regulatory_domain.rd = rd; if (hostapd_ioctl(drv, ¶m, sizeof(param))) { printf("Failed to set regulatory domain (%x)\n", rd); return -1; } return 0;}static int i802_set_tx_queue_params(void *priv, int queue, int aifs, int cw_min, int cw_max, int burst_time){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS; param.u.tx_queue_params.queue = queue; param.u.tx_queue_params.aifs = aifs; param.u.tx_queue_params.cw_min = cw_min; param.u.tx_queue_params.cw_max = cw_max; param.u.tx_queue_params.burst_time = burst_time; if (hostapd_ioctl(drv, ¶m, sizeof(param))) return -1; return 0;}static int i802_set_beacon(const char *ifname, void *priv, u8 *head, size_t head_len, u8 *tail, size_t tail_len){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param *param; int len, ret = 0; param = wpa_zalloc(sizeof(*param) + head_len + tail_len); if (param == NULL) { printf("Failed to alloc memory for beacon ioctl\n"); return -1; } len = (¶m->u.beacon.data[0] - (u8 *) param) + head_len + tail_len; param->cmd = PRISM2_HOSTAPD_SET_BEACON; param->u.beacon.head_len = head_len; param->u.beacon.tail_len = tail_len; memcpy(¶m->u.beacon.data[0], head, head_len); memcpy(¶m->u.beacon.data[0] + head_len, tail, tail_len); if (len < sizeof(*param)) len = sizeof(*param); if (hostapd_ioctl_iface(ifname, drv, param, len)) { printf("Could not set beacon data to kernel driver.\n"); printf("ifname='%s' head=%p head_len=%d tail=%p tail_len=%d " "cmd=%d\n", ifname, head, head_len, tail, tail_len, param->cmd); ret = -1; } free(param); return ret;}static int i802_set_ieee8021x(const char *ifname, void *priv, int enabled){ struct i802_driver_data *drv = priv; if (hostap_ioctl_prism2param_iface(ifname, drv, PRISM2_PARAM_IEEE_802_1X, enabled)) { printf("%s: Could not %s IEEE 802.1X PAE support in kernel " "driver.\n", ifname, enabled ? "enable" : "disable"); return -1; } if (hostap_ioctl_prism2param_iface(ifname, drv, PRISM2_PARAM_EAPOL, enabled)) { printf("%s: Could not %s EAPOL support in kernel " "driver.\n", ifname, enabled ? "enable" : "disable"); return -1; } return 0;}static int i802_set_privacy(void *priv, int enabled){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_PRIVACY_INVOKED, enabled);}static int i802_set_beacon_int(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_BEACON_INT, value);}static int i802_set_dtim_period(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_DTIM_PERIOD, value);}static int i802_set_broadcast_ssid(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_BROADCAST_SSID, value);}static int i802_set_cts_protect(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES, value);}static int i802_set_key_tx_rx_threshold(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_KEY_TX_RX_THRESHOLD, value);}static int i802_set_preamble(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_PREAMBLE, value);}static int i802_set_short_slot_time(void *priv, int value){ struct i802_driver_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_SHORT_SLOT_TIME, value);}static struct hostapd_hw_modes * i802_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param *param; u8 *pos, *end; struct hostapd_hw_modes *modes; int i; param = wpa_zalloc(PRISM2_HOSTAPD_MAX_BUF_SIZE); if (param == NULL) return NULL; param->cmd = PRISM2_HOSTAPD_GET_HW_FEATURES; if (hostapd_ioctl(drv, param, PRISM2_HOSTAPD_MAX_BUF_SIZE)) { free(param); return NULL; } *num_modes = param->u.hw_features.num_modes; *flags = param->u.hw_features.flags; pos = param->u.hw_features.data; end = pos + PRISM2_HOSTAPD_MAX_BUF_SIZE - (param->u.hw_features.data - (u8 *) param); modes = wpa_zalloc(*num_modes * sizeof(struct hostapd_hw_modes)); if (modes == NULL) { free(param); return NULL; } for (i = 0; i < *num_modes; i++) { struct hostapd_ioctl_hw_modes_hdr *hdr; struct hostapd_hw_modes *feature; int clen, rlen; hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos; feature = &modes[i]; switch (hdr->mode) { case MODE_IEEE80211A: feature->mode = HOSTAPD_MODE_IEEE80211A; break; case MODE_IEEE80211B: feature->mode = HOSTAPD_MODE_IEEE80211B; break; case MODE_IEEE80211G: feature->mode = HOSTAPD_MODE_IEEE80211G; break; default: wpa_printf(MSG_ERROR, "Unknown hw_mode=%d in " "get_hw_features data", hdr->mode); hostapd_free_hw_features(modes, *num_modes); modes = NULL; break; } feature->num_channels = hdr->num_channels; feature->num_rates = hdr->num_rates; pos = (u8 *) (hdr + 1); clen = hdr->num_channels * sizeof(struct hostapd_channel_data); rlen = hdr->num_rates * sizeof(struct hostapd_rate_data); feature->channels = malloc(clen); feature->rates = malloc(rlen); if (!feature->channels || !feature->rates) { hostapd_free_hw_features(modes, *num_modes); modes = NULL; break; } memcpy(feature->channels, pos, clen); pos += clen; memcpy(feature->rates, pos, rlen); pos += rlen; } free(param); return modes;}static int i802_set_sta_vlan(void *priv, const u8 *addr, const char *ifname, int vlan_id){ struct i802_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_SET_STA_VLAN; memcpy(param.sta_addr, addr, ETH_ALEN); strncpy(param.u.set_sta_vlan.vlan_name, ifname, IFNAMSIZ); param.u.set_sta_vlan.vlan_id = vlan_id; return hostapd_ioctl(drv, ¶m, sizeof(param));}static void handle_data(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, struct ieee80211_frame_info *fi){ struct ieee80211_hdr *hdr; u16 fc, ethertype; u8 *pos, *sa; size_t left; struct sta_info *sta; if (len < sizeof(struct ieee80211_hdr)) return; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); if ((fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) != WLAN_FC_TODS) { printf("Not ToDS data frame (fc=0x%04x)\n", fc); return; } sa = hdr->addr2; sta = ap_get_sta(hapd, sa); if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { printf("Data frame from not associated STA " MACSTR "\n", MAC2STR(sa)); if (sta && (sta->flags & WLAN_STA_AUTH)) hostapd_sta_disassoc( hapd, sa, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); else hostapd_sta_deauth( hapd, sa, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); return; } pos = (u8 *) (hdr + 1); left = len - sizeof(*hdr); if (left < sizeof(rfc1042_header)) { printf("Too short data frame\n"); return; } if (memcmp(pos, rfc1042_header, sizeof(rfc1042_header)) != 0) { printf("Data frame with no RFC1042 header\n"); return; } pos += sizeof(rfc1042_header); left -= sizeof(rfc1042_header); if (left < 2) { printf("No ethertype in data frame\n"); return; } ethertype = *pos++ << 8; ethertype |= *pos++; left -= 2; switch (ethertype) { case ETH_P_PAE: ieee802_1x_receive(hapd, sa, pos, left); break; default: printf("Unknown ethertype 0x%04x in data frame\n", ethertype); break; }}static void handle_tx_callback(struct hostapd_data *hapd, u8 *buf, size_t len, int ok){ struct ieee80211_hdr *hdr; u16 fc, type, stype; struct sta_info *sta; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); switch (type) { case WLAN_FC_TYPE_MGMT: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "MGMT (TX callback) %s\n", ok ? "ACK" : "fail"); ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); break; case WLAN_FC_TYPE_CTRL: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "CTRL (TX callback) %s\n", ok ? "ACK" : "fail"); break; case WLAN_FC_TYPE_DATA: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "DATA (TX callback) %s\n", ok ? "ACK" : "fail"); sta = ap_get_sta(hapd, hdr->addr1); if (sta && sta->flags & WLAN_STA_PENDING_POLL) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "STA " MACSTR " %s pending activity poll\n", MAC2STR(sta->addr), ok ? "ACKed" : "did not ACK"); if (ok) sta->flags &= ~WLAN_STA_PENDING_POLL; } if (sta) ieee802_1x_tx_status(hapd, sta, buf, len, ok); break; default: printf("unknown TX callback frame type %d\n", type); break; }}static void dump_frame_info(struct ieee80211_frame_info *fi, size_t len){ u64 ts, tus; tus = ts = be_to_host64(fi->hosttime); ts /= 1000000; tus -= ts * 1000000; wpa_hexdump(MSG_DEBUG, "Frame info dump", (u8 *) fi, len); printf("version:\t0x%08x\n", ntohl(fi->version)); printf("length:\t%d\n", ntohl(fi->length)); printf("mactime:\t%lld\n", be_to_host64(fi->mactime)); printf("hosttime:\t%lld.%06lld\n", ts, tus); printf("phytype:\t%d\n", ntohl(fi->phytype)); printf("channel:\t%d\n", ntohl(fi->channel)); printf("datarate:\t%d\n", ntohl(fi->datarate)); printf("antenna:\t%d\n", ntohl(fi->antenna)); printf("priority\t%d\n", ntohl(fi->priority)); printf("ssi_type:\t%d\n", ntohl(fi->ssi_type)); printf("ssi_signal:\t%d\n", ntohl(fi->ssi_signal)); printf("ssi_noise:\t%d\n", ntohl(fi->ssi_noise)); printf("preamble:\t%d\n", ntohl(fi->preamble)); printf("encoding:\t%d\n", ntohl(fi->encoding)); printf("msg_type:\t%d\n", ntohl(fi->msg_type));}static void hostapd_michael_mic_failure(struct hostapd_data *hapd, u8 *buf, size_t len){ struct ieee80211_hdr *hdr; if (len < 24) { printf("Too short frame (%d) with Michael MIC failure\n", len); return; } hdr = (struct ieee80211_hdr *) buf; /* TODO: mlme_michaelmicfailure_indication(hapd, hdr->addr2); */}static void handle_frame(struct hostapd_iface *iface, u8 *buf, size_t len, struct ieee80211_frame_info *fi){ struct ieee80211_hdr *hdr; u16 fc, type, stype; size_t data_len = len; struct hostapd_data *hapd = NULL; int i, broadcast_bssid = 0; u8 *bssid; int msg_type = ntohl(fi->msg_type); /* special handling for message types without IEEE 802.11 header */ if (msg_type == ieee80211_msg_set_aid_for_sta) {#if 0 /* TODO */ ieee802_11_set_aid_for_sta(iface->bss[0], buf, data_len);#endif return; } if (msg_type == ieee80211_msg_key_threshold_notification) {#if 0 /* TODO */ ieee802_11_key_threshold_notification(iface->bss[0], buf, data_len);#endif return; } /* PS-Poll frame from not associated is 16 bytes. All other frames * passed to hostapd are 24 bytes or longer. */ if (len < 24 && (msg_type != ieee80211_msg_sta_not_assoc || len < 16)) { printf("handle_frame: too short (%lu), type %d\n", (unsigned long) len, msg_type); return; } hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); bssid = hdr->addr3; type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); if (type == WLAN_FC_TYPE_DATA) { switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { case WLAN_FC_TODS: bssid = hdr->addr1; break; case WLAN_FC_FROMDS: bssid = hdr->addr2; break; } } for (i = 0; i < iface->num_bss; i++) { if (memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) { hapd = iface->bss[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -