📄 driver_wext.c
字号:
if (auth_alg & AUTH_ALG_SHARED_KEY) algs |= IW_AUTH_ALG_SHARED_KEY; if (auth_alg & AUTH_ALG_LEAP) algs |= IW_AUTH_ALG_LEAP; if (algs == 0) { /* at least one algorithm should be set */ algs = IW_AUTH_ALG_OPEN_SYSTEM; } res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, algs); drv->auth_alg_fallback = res == -2; return res;}/** * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE * @priv: Pointer to private wext data from wpa_driver_wext_init() * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS * Returns: 0 on success, -1 on failure */int wpa_driver_wext_set_mode(void *priv, int mode){ struct wpa_driver_wext_data *drv = priv; struct iwreq iwr; int ret = 0; os_memset(&iwr, 0, sizeof(iwr)); os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); iwr.u.mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA; if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { perror("ioctl[SIOCSIWMODE]"); ret = -1; } return ret;}static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv, u32 cmd, const u8 *bssid, const u8 *pmkid){ struct iwreq iwr; struct iw_pmksa pmksa; int ret = 0; os_memset(&iwr, 0, sizeof(iwr)); os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); os_memset(&pmksa, 0, sizeof(pmksa)); pmksa.cmd = cmd; pmksa.bssid.sa_family = ARPHRD_ETHER; if (bssid) os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); if (pmkid) os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); iwr.u.data.pointer = (caddr_t) &pmksa; iwr.u.data.length = sizeof(pmksa); if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { if (errno != EOPNOTSUPP) perror("ioctl[SIOCSIWPMKSA]"); ret = -1; } return ret;}static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid){ struct wpa_driver_wext_data *drv = priv; return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);}static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid){ struct wpa_driver_wext_data *drv = priv; return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);}static int wpa_driver_wext_flush_pmkid(void *priv){ struct wpa_driver_wext_data *drv = priv; return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);}static int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa){ struct wpa_driver_wext_data *drv = priv; if (!drv->has_capability) return -1; os_memcpy(capa, &drv->capa, sizeof(*capa)); return 0;}int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, const char *ifname){ if (ifname == NULL) { drv->ifindex2 = -1; return 0; } drv->ifindex2 = if_nametoindex(ifname); if (drv->ifindex2 <= 0) return -1; wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for " "wireless events", drv->ifindex2, ifname); return 0;}int wpa_driver_wext_set_operstate(void *priv, int state){ struct wpa_driver_wext_data *drv = priv; wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)", __func__, drv->operstate, state, state ? "UP" : "DORMANT"); drv->operstate = state; return wpa_driver_wext_send_oper_ifla( drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);}#ifdef CONFIG_CLIENT_MLMEstatic int hostapd_ioctl(struct wpa_driver_wext_data *drv, struct prism2_hostapd_param *param, int len){ struct iwreq iwr; os_memset(&iwr, 0, sizeof(iwr)); os_strncpy(iwr.ifr_name, drv->ifname, 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 struct wpa_hw_modes *wpa_driver_wext_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags){ struct wpa_driver_wext_data *drv = priv; struct prism2_hostapd_param *param; u8 *pos, *end; struct wpa_hw_modes *modes = NULL; int i; param = os_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) < 0) { perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); goto out; } *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 = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes)); if (modes == NULL) goto out; for (i = 0; i < *num_modes; i++) { struct hostapd_ioctl_hw_modes_hdr *hdr; struct wpa_hw_modes *feature; int clen, rlen; hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos; pos = (u8 *) (hdr + 1); clen = hdr->num_channels * sizeof(struct wpa_channel_data); rlen = hdr->num_rates * sizeof(struct wpa_rate_data); feature = &modes[i]; switch (hdr->mode) { case MODE_IEEE80211A: feature->mode = WPA_MODE_IEEE80211A; break; case MODE_IEEE80211B: feature->mode = WPA_MODE_IEEE80211B; break; case MODE_IEEE80211G: feature->mode = WPA_MODE_IEEE80211G; break; case MODE_ATHEROS_TURBO: case MODE_ATHEROS_TURBOG: wpa_printf(MSG_ERROR, "Skip unsupported hw_mode=%d in " "get_hw_features data", hdr->mode); pos += clen + rlen; continue; default: wpa_printf(MSG_ERROR, "Unknown hw_mode=%d in " "get_hw_features data", hdr->mode); ieee80211_sta_free_hw_features(modes, *num_modes); modes = NULL; break; } feature->num_channels = hdr->num_channels; feature->num_rates = hdr->num_rates; feature->channels = os_malloc(clen); feature->rates = os_malloc(rlen); if (!feature->channels || !feature->rates || pos + clen + rlen > end) { ieee80211_sta_free_hw_features(modes, *num_modes); modes = NULL; break; } os_memcpy(feature->channels, pos, clen); pos += clen; os_memcpy(feature->rates, pos, rlen); pos += rlen; }out: os_free(param); return modes;}int wpa_driver_wext_set_channel(void *priv, wpa_hw_mode phymode, int chan, int freq){ return wpa_driver_wext_set_freq(priv, freq);}static void wpa_driver_wext_mlme_read(int sock, void *eloop_ctx, void *sock_ctx){ struct wpa_driver_wext_data *drv = eloop_ctx; int len; unsigned char buf[3000]; struct ieee80211_frame_info *fi; struct ieee80211_rx_status rx_status; len = recv(sock, buf, sizeof(buf), 0); if (len < 0) { perror("recv[MLME]"); return; } if (len < (int) sizeof(struct ieee80211_frame_info)) { wpa_printf(MSG_DEBUG, "WEXT: Too short MLME frame (len=%d)", len); return; } fi = (struct ieee80211_frame_info *) buf; if (ntohl(fi->version) != IEEE80211_FI_VERSION) { wpa_printf(MSG_DEBUG, "WEXT: Invalid MLME frame info version " "0x%x", ntohl(fi->version)); return; } os_memset(&rx_status, 0, sizeof(rx_status)); rx_status.ssi = ntohl(fi->ssi_signal); rx_status.channel = ntohl(fi->channel); ieee80211_sta_rx(drv->ctx, buf + sizeof(struct ieee80211_frame_info), len - sizeof(struct ieee80211_frame_info), &rx_status);}static int wpa_driver_wext_open_mlme(struct wpa_driver_wext_data *drv){ int flags, ifindex, s, *i; struct sockaddr_ll addr; struct iwreq iwr; os_memset(&iwr, 0, sizeof(iwr)); os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); i = (int *) iwr.u.name; *i++ = PRISM2_PARAM_USER_SPACE_MLME; *i++ = 1; if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) { wpa_printf(MSG_ERROR, "WEXT: Failed to configure driver to " "use user space MLME"); return -1; } ifindex = if_nametoindex(drv->mlmedev); if (ifindex == 0) { wpa_printf(MSG_ERROR, "WEXT: mlmedev='%s' not found", drv->mlmedev); return -1; } if (wpa_driver_wext_get_ifflags_ifname(drv, drv->mlmedev, &flags) != 0 || wpa_driver_wext_set_ifflags_ifname(drv, drv->mlmedev, flags | IFF_UP) != 0) { wpa_printf(MSG_ERROR, "WEXT: Could not set interface " "'%s' UP", drv->mlmedev); return -1; } s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (s < 0) { perror("socket[PF_PACKET,SOCK_RAW]"); return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sll_family = AF_PACKET; addr.sll_ifindex = ifindex; if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(MLME)"); return -1; } if (eloop_register_read_sock(s, wpa_driver_wext_mlme_read, drv, NULL)) { wpa_printf(MSG_ERROR, "WEXT: Could not register MLME read " "socket"); close(s); return -1; } return s;}static int wpa_driver_wext_send_mlme(void *priv, const u8 *data, size_t data_len){ struct wpa_driver_wext_data *drv = priv; int ret; ret = send(drv->mlme_sock, data, data_len, 0); if (ret < 0) { perror("send[MLME]"); return -1; } return 0;}static int wpa_driver_wext_mlme_add_sta(void *priv, const u8 *addr, const u8 *supp_rates, size_t supp_rates_len){ struct wpa_driver_wext_data *drv = priv; struct prism2_hostapd_param param; size_t len; os_memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_ADD_STA; os_memcpy(param.sta_addr, addr, ETH_ALEN); len = supp_rates_len; if (len > sizeof(param.u.add_sta.supp_rates)) len = sizeof(param.u.add_sta.supp_rates); os_memcpy(param.u.add_sta.supp_rates, supp_rates, len); return hostapd_ioctl(drv, ¶m, sizeof(param));}static int wpa_driver_wext_mlme_remove_sta(void *priv, const u8 *addr){ struct wpa_driver_wext_data *drv = priv; struct prism2_hostapd_param param; os_memset(¶m, 0, sizeof(param)); param.cmd = PRISM2_HOSTAPD_REMOVE_STA; os_memcpy(param.sta_addr, addr, ETH_ALEN); return hostapd_ioctl(drv, ¶m, sizeof(param));}#endif /* CONFIG_CLIENT_MLME */static int wpa_driver_wext_set_param(void *priv, const char *param){#ifdef CONFIG_CLIENT_MLME struct wpa_driver_wext_data *drv = priv; const char *pos, *pos2; size_t len; if (param == NULL) return 0; wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); pos = os_strstr(param, "mlmedev="); if (pos) { pos += 8; pos2 = os_strchr(pos, ' '); if (pos2) len = pos2 - pos; else len = os_strlen(pos); if (len + 1 > sizeof(drv->mlmedev)) return -1; os_memcpy(drv->mlmedev, pos, len); drv->mlmedev[len] = '\0'; wpa_printf(MSG_DEBUG, "WEXT: Using user space MLME with " "mlmedev='%s'", drv->mlmedev); drv->capa.flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; drv->mlme_sock = wpa_driver_wext_open_mlme(drv); if (drv->mlme_sock < 0) return -1; }#endif /* CONFIG_CLIENT_MLME */ return 0;}int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv){ return drv->we_version_compiled;}const struct wpa_driver_ops wpa_driver_wext_ops = { .name = "wext", .desc = "Linux wireless extensions (generic)", .get_bssid = wpa_driver_wext_get_bssid, .get_ssid = wpa_driver_wext_get_ssid, .set_wpa = wpa_driver_wext_set_wpa, .set_key = wpa_driver_wext_set_key, .set_countermeasures = wpa_driver_wext_set_countermeasures, .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted, .scan = wpa_driver_wext_scan, .get_scan_results = wpa_driver_wext_get_scan_results, .deauthenticate = wpa_driver_wext_deauthenticate, .disassociate = wpa_driver_wext_disassociate, .associate = wpa_driver_wext_associate, .set_auth_alg = wpa_driver_wext_set_auth_alg, .init = wpa_driver_wext_init, .deinit = wpa_driver_wext_deinit, .set_param = wpa_driver_wext_set_param, .add_pmkid = wpa_driver_wext_add_pmkid, .remove_pmkid = wpa_driver_wext_remove_pmkid, .flush_pmkid = wpa_driver_wext_flush_pmkid, .get_capa = wpa_driver_wext_get_capa, .set_operstate = wpa_driver_wext_set_operstate,#ifdef CONFIG_CLIENT_MLME .get_hw_feature_data = wpa_driver_wext_get_hw_feature_data, .set_channel = wpa_driver_wext_set_channel, .set_ssid = wpa_driver_wext_set_ssid, .set_bssid = wpa_driver_wext_set_bssid, .send_mlme = wpa_driver_wext_send_mlme, .mlme_add_sta = wpa_driver_wext_mlme_add_sta, .mlme_remove_sta = wpa_driver_wext_mlme_remove_sta,#endif /* CONFIG_CLIENT_MLME */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -