📄 driver_hostap.c
字号:
if (dev_up) { memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, IFNAMSIZ, "%sap", drv->iface); ifr.ifr_mtu = HOSTAPD_MTU; if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { perror("ioctl[SIOCSIFMTU]"); printf("Setting MTU failed - trying to survive with " "current value\n"); } } return 0;}static int hostapd_ioctl(void *priv, struct prism2_hostapd_param *param, int len){ struct hostap_driver_data *drv = priv; struct iwreq iwr; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); iwr.u.data.pointer = (caddr_t) param; iwr.u.data.length = len; if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); return -1; } return 0;}static int hostap_set_encryption(const char *ifname, void *priv, const char *alg, const u8 *addr, int idx, const u8 *key, size_t key_len, int txkey){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param *param; u8 *buf; size_t blen; int ret = 0; blen = sizeof(*param) + key_len; buf = os_zalloc(blen); if (buf == NULL) return -1; param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_SET_ENCRYPTION; if (addr == NULL) memset(param->sta_addr, 0xff, ETH_ALEN); else memcpy(param->sta_addr, addr, ETH_ALEN); os_strlcpy((char *) param->u.crypt.alg, alg, HOSTAP_CRYPT_ALG_NAME_LEN); param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; param->u.crypt.idx = idx; param->u.crypt.key_len = key_len; memcpy((u8 *) (param + 1), key, key_len); if (hostapd_ioctl(drv, param, blen)) { printf("Failed to set encryption.\n"); ret = -1; } free(buf); return ret;}static int hostap_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, u8 *seq){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param *param; u8 *buf; size_t blen; int ret = 0; blen = sizeof(*param) + 32; buf = os_zalloc(blen); if (buf == NULL) return -1; param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_GET_ENCRYPTION; if (addr == NULL) memset(param->sta_addr, 0xff, ETH_ALEN); else memcpy(param->sta_addr, addr, ETH_ALEN); param->u.crypt.idx = idx; if (hostapd_ioctl(drv, param, blen)) { printf("Failed to get encryption.\n"); ret = -1; } else { memcpy(seq, param->u.crypt.seq, 8); } free(buf); return ret;}static int hostap_ioctl_prism2param(void *priv, int param, int value){ struct hostap_driver_data *drv = priv; struct iwreq iwr; int *i; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); i = (int *) iwr.u.name; *i++ = param; *i++ = value; if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) { perror("ioctl[PRISM2_IOCTL_PRISM2_PARAM]"); return -1; } return 0;}static int hostap_set_ieee8021x(const char *ifname, void *priv, int enabled){ struct hostap_driver_data *drv = priv; /* enable kernel driver support for IEEE 802.1X */ if (hostap_ioctl_prism2param(drv, PRISM2_PARAM_IEEE_802_1X, enabled)) { printf("Could not setup IEEE 802.1X support in kernel driver." "\n"); return -1; } if (!enabled) return 0; /* use host driver implementation of encryption to allow * individual keys and passing plaintext EAPOL frames */ if (hostap_ioctl_prism2param(drv, PRISM2_PARAM_HOST_DECRYPT, 1) || hostap_ioctl_prism2param(drv, PRISM2_PARAM_HOST_ENCRYPT, 1)) { printf("Could not setup host-based encryption in kernel " "driver.\n"); return -1; } return 0;}static int hostap_set_privacy(const char *ifname, void *priv, int enabled){ struct hostap_drvier_data *drv = priv; return hostap_ioctl_prism2param(drv, PRISM2_PARAM_PRIVACY_INVOKED, enabled);} static int hostap_set_ssid(const char *ifname, void *priv, const u8 *buf, int len){ struct hostap_driver_data *drv = priv; struct iwreq iwr; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); iwr.u.essid.flags = 1; /* SSID active */ iwr.u.essid.pointer = (caddr_t) buf; iwr.u.essid.length = len + 1; if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { perror("ioctl[SIOCSIWESSID]"); printf("len=%d\n", len); return -1; } return 0;}static int hostap_flush(void *priv){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_FLUSH; return hostapd_ioctl(drv, ¶m, sizeof(param));}static int hostap_read_sta_data(void *priv, struct hostap_sta_driver_data *data, const u8 *addr){ struct hostap_driver_data *drv = priv; char buf[1024], line[128], *pos; FILE *f; unsigned long val; memset(data, 0, sizeof(*data)); snprintf(buf, sizeof(buf), "/proc/net/hostap/%s/" MACSTR, drv->iface, MAC2STR(addr)); f = fopen(buf, "r"); if (!f) return -1; /* Need to read proc file with in one piece, so use large enough * buffer. */ setbuffer(f, buf, sizeof(buf)); while (fgets(line, sizeof(line), f)) { pos = strchr(line, '='); if (!pos) continue; *pos++ = '\0'; val = strtoul(pos, NULL, 10); if (strcmp(line, "rx_packets") == 0) data->rx_packets = val; else if (strcmp(line, "tx_packets") == 0) data->tx_packets = val; else if (strcmp(line, "rx_bytes") == 0) data->rx_bytes = val; else if (strcmp(line, "tx_bytes") == 0) data->tx_bytes = val; } fclose(f); return 0;}static int hostap_sta_add(const char *ifname, void *priv, const u8 *addr, u16 aid, u16 capability, u8 *supp_rates, size_t supp_rates_len, int flags, u16 listen_interval){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param param; int tx_supp_rates = 0; size_t i;#define WLAN_RATE_1M BIT(0)#define WLAN_RATE_2M BIT(1)#define WLAN_RATE_5M5 BIT(2)#define WLAN_RATE_11M BIT(3) for (i = 0; i < supp_rates_len; i++) { if ((supp_rates[i] & 0x7f) == 2) tx_supp_rates |= WLAN_RATE_1M; if ((supp_rates[i] & 0x7f) == 4) tx_supp_rates |= WLAN_RATE_2M; if ((supp_rates[i] & 0x7f) == 11) tx_supp_rates |= WLAN_RATE_5M5; if ((supp_rates[i] & 0x7f) == 22) tx_supp_rates |= WLAN_RATE_11M; } 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; param.u.add_sta.tx_supp_rates = tx_supp_rates; return hostapd_ioctl(drv, ¶m, sizeof(param));}static int hostap_sta_remove(void *priv, const u8 *addr){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param param; hostap_sta_set_flags(drv, addr, 0, 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))) { printf("Could not remove station from kernel driver.\n"); return -1; } return 0;}static int hostap_get_inact_sec(void *priv, const u8 *addr){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_GET_INFO_STA; memcpy(param.sta_addr, addr, ETH_ALEN); if (hostapd_ioctl(drv, ¶m, sizeof(param))) { return -1; } return param.u.get_info_sta.inactive_sec;}static int hostap_sta_clear_stats(void *priv, const u8 *addr){ struct hostap_driver_data *drv = priv; struct prism2_hostapd_param param; memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_STA_CLEAR_STATS; memcpy(param.sta_addr, addr, ETH_ALEN); if (hostapd_ioctl(drv, ¶m, sizeof(param))) { return -1; } return 0;}static int hostap_set_assoc_ap(void *priv, const u8 *addr){ struct hostap_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))) return -1; return 0;}static int hostapd_ioctl_set_generic_elem(struct hostap_driver_data *drv){ struct prism2_hostapd_param *param; int res; size_t blen, elem_len; elem_len = drv->generic_ie_len + drv->wps_ie_len; blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + elem_len; if (blen < sizeof(*param)) blen = sizeof(*param); param = os_zalloc(blen); if (param == NULL) return -1; param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT; param->u.generic_elem.len = elem_len; if (drv->generic_ie) { os_memcpy(param->u.generic_elem.data, drv->generic_ie, drv->generic_ie_len); } if (drv->wps_ie) { os_memcpy(¶m->u.generic_elem.data[drv->generic_ie_len], drv->wps_ie, drv->wps_ie_len); } wpa_hexdump(MSG_DEBUG, "hostap: Set generic IE", param->u.generic_elem.data, elem_len); res = hostapd_ioctl(drv, param, blen); os_free(param); return res;}static int hostap_set_generic_elem(const char *ifname, void *priv, const u8 *elem, size_t elem_len){ struct hostap_driver_data *drv = priv; os_free(drv->generic_ie); drv->generic_ie = NULL; drv->generic_ie_len = 0; if (elem) { drv->generic_ie = os_malloc(elem_len); if (drv->generic_ie == NULL) return -1; os_memcpy(drv->generic_ie, elem, elem_len); drv->generic_ie_len = elem_len; } return hostapd_ioctl_set_generic_elem(drv);}static int hostap_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie, size_t len){ /* Host AP driver supports only one set of extra IEs, so we need to * use the ProbeResp IEs also for Beacon frames since they include more * information. */ return 0;}static int hostap_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie, size_t len){ struct hostap_driver_data *drv = priv; os_free(drv->wps_ie); drv->wps_ie = NULL; drv->wps_ie_len = 0; if (ie) { drv->wps_ie = os_malloc(len); if (drv->wps_ie == NULL) return -1; os_memcpy(drv->wps_ie, ie, len); drv->wps_ie_len = len; } return hostapd_ioctl_set_generic_elem(drv);}static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -