static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname) { struct rsn_preauth_interface *piface; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "RSN pre-auth interface '%s'\n", ifname); piface = wpa_zalloc(sizeof(*piface)); if (piface == NULL) return -1; piface->hapd = hapd; piface->ifname = strdup(ifname); if (piface->ifname == NULL) { goto fail1; } piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH, rsn_preauth_receive, piface, 1); if (piface->l2 == NULL) { printf("Failed to open register layer 2 access to " "ETH_P_PREAUTH\n"); goto fail2; } piface->next = hapd->preauth_iface; hapd->preauth_iface = piface; return 0; fail2: free(piface->ifname); fail1: free(piface); return -1; }
static int rsn_preauth_iface_add(struct asd_data *wasd, const char *ifname) { struct rsn_preauth_interface *piface; asd_printf(ASD_DEFAULT,MSG_DEBUG, "RSN pre-auth interface '%s'", ifname); piface = os_zalloc(sizeof(*piface)); if (piface == NULL) return -1; piface->wasd = wasd; piface->ifname = os_strdup(ifname); if (piface->ifname == NULL) { goto fail1; } piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH, rsn_preauth_receive, piface, 1); if (piface->l2 == NULL) { asd_printf(ASD_DEFAULT,MSG_ERROR, "Failed to open register layer 2 access " "to ETH_P_PREAUTH"); goto fail2; } piface->next = wasd->preauth_iface; wasd->preauth_iface = piface; return 0; fail2: os_free(piface->ifname); fail1: os_free(piface); return -1; }
int rsn_preauth_init(struct wpa_supplicant *wpa_s, u8 *dst) { struct eapol_config eapol_conf; struct eapol_ctx *ctx; if (wpa_s->preauth_eapol) return -1; wpa_msg(wpa_s, MSG_DEBUG, "RSN: starting pre-authentication with " MACSTR, MAC2STR(dst)); wpa_s->l2_preauth = l2_packet_init(wpa_s->ifname, wpa_drv_get_mac_addr(wpa_s), ETH_P_RSN_PREAUTH, rsn_preauth_receive, wpa_s); if (wpa_s->l2_preauth == NULL) { wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet " "processing for pre-authentication"); return -2; } ctx = malloc(sizeof(*ctx)); if (ctx == NULL) { wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context."); return -4; } memset(ctx, 0, sizeof(*ctx)); ctx->ctx = wpa_s; ctx->preauth = 1; ctx->cb = rsn_preauth_eapol_cb; ctx->cb_ctx = wpa_s; ctx->scard_ctx = wpa_s->scard; ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done; ctx->eapol_send = wpa_eapol_send_preauth; wpa_s->preauth_eapol = eapol_sm_init(ctx); if (wpa_s->preauth_eapol == NULL) { free(ctx); wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL " "state machines for pre-authentication"); return -3; } memset(&eapol_conf, 0, sizeof(eapol_conf)); eapol_conf.accept_802_1x_keys = 0; eapol_conf.required_keys = 0; eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; if (wpa_s->current_ssid) eapol_conf.workaround = wpa_s->current_ssid->eap_workaround; eapol_sm_notify_config(wpa_s->preauth_eapol, wpa_s->current_ssid, &eapol_conf); memcpy(wpa_s->preauth_bssid, dst, ETH_ALEN); eapol_sm_notify_portValid(wpa_s->preauth_eapol, TRUE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(wpa_s->preauth_eapol, TRUE); eloop_register_timeout(60, 0, rsn_preauth_timeout, wpa_s, NULL); return 0; }
struct wpa_supplicant * wapi_supplicant_init(struct wpa_supplicant *wpa_s) { g_wpa_s = wpa_s; for (;;) { wpa_s->l2_wapi = l2_packet_init( wpa_s->ifname, wpa_drv_get_mac_addr(wpa_s), ETH_P_WAI, wapi_supplicant_rx_wai, wpa_s, 0); wpa_printf(MSG_INFO, "%s: Init WAPI packet %s\n", __func__, wpa_s->ifname); if (wpa_s->l2_wapi) { break; } sleep(5); } if (l2_packet_get_own_addr(wpa_s->l2_wapi, wpa_s->own_addr)) { fprintf(stderr, "Failed to get own L2 address\n"); return NULL; } wpa_printf(MSG_DEBUG, "Own MAC address: " MACSTR, MAC2STR(wpa_s->own_addr)); WIFI_lib_init(); return wpa_s; }
struct l2_packet_data * l2_packet_init_bridge( const char *br_ifname, const char *ifname, const u8 *own_addr, unsigned short protocol, void (*rx_callback)(void *ctx, const u8 *src_addr, const u8 *buf, size_t len), void *rx_callback_ctx, int l2_hdr) { return l2_packet_init(br_ifname, own_addr, protocol, rx_callback, rx_callback_ctx, l2_hdr); }
static void * bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct bsd_driver_data *drv; drv = os_zalloc(sizeof(struct bsd_driver_data)); if (drv == NULL) { printf("Could not allocate memory for bsd driver data\n"); goto bad; } drv->hapd = hapd; drv->sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, handle_read, drv, 0); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; /* mark down during setup */ if (bsd_ctrl_iface(drv, 0) < 0) goto bad; drv->route = socket(PF_ROUTE, SOCK_RAW, 0); if (drv->route < 0) { perror("socket(PF_ROUTE,SOCK_RAW)"); goto bad; } eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, NULL); if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) { wpa_printf(MSG_ERROR, "%s: failed to set operation mode", __func__); goto bad; } return drv; bad: if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->sock >= 0) close(drv->sock); if (drv != NULL) os_free(drv); return NULL; }
static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface, struct sockaddr_un *from, void *buf, size_t len) { int *reg_cmd = buf; u8 own_addr[ETH_ALEN]; int res; u16 proto; if (len != 2 * sizeof(int)) { wpa_printf(MSG_DEBUG, "Invalid l2_register length %lu", (unsigned long) len); return; } proto = reg_cmd[0]; if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH && proto != ETH_P_80211_ENCAP) { wpa_printf(MSG_DEBUG, "Refused l2_packet connection for " "ethertype 0x%x", proto); return; } if (iface->l2) { wpa_printf(MSG_DEBUG, "Cleaning up forgotten l2_packet " "instance"); l2_packet_deinit(iface->l2); iface->l2 = NULL; } os_memcpy(&iface->l2_addr, from, sizeof(iface->l2_addr)); iface->l2 = l2_packet_init(iface->ifname, NULL, proto, wpa_priv_l2_rx, iface, reg_cmd[1]); if (iface->l2 == NULL) { wpa_printf(MSG_DEBUG, "Failed to initialize l2_packet " "instance for protocol %d", proto); return; } if (l2_packet_get_own_addr(iface->l2, own_addr) < 0) { wpa_printf(MSG_DEBUG, "Failed to get own address from " "l2_packet"); l2_packet_deinit(iface->l2); iface->l2 = NULL; return; } res = sendto(iface->fd, own_addr, ETH_ALEN, 0, (struct sockaddr *) from, sizeof(*from)); wpa_printf(MSG_DEBUG, "L2 registration: res=%d", res); }
static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname) { struct l2_packet_data *l2; struct wpa_sm_ctx *ctx; os_memset(&dummy_driver, 0, sizeof(dummy_driver)); wpa_s->driver = &dummy_driver; ctx = os_zalloc(sizeof(*ctx)); assert(ctx != NULL); ctx->ctx = wpa_s; ctx->set_state = _wpa_supplicant_set_state; ctx->get_state = _wpa_supplicant_get_state; ctx->req_scan = _wpa_supplicant_req_scan; ctx->deauthenticate = _wpa_supplicant_deauthenticate; ctx->disassociate = _wpa_supplicant_disassociate; ctx->set_key = wpa_supplicant_set_key; ctx->scan = wpa_supplicant_scan; ctx->get_ssid = _wpa_supplicant_get_ssid; ctx->get_bssid = wpa_supplicant_get_bssid; ctx->ether_send = wpa_ether_send; ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; ctx->alloc_eapol = _wpa_alloc_eapol; ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; ctx->add_pmkid = wpa_supplicant_add_pmkid; ctx->remove_pmkid = wpa_supplicant_remove_pmkid; ctx->set_config_blob = wpa_supplicant_set_config_blob; ctx->get_config_blob = wpa_supplicant_get_config_blob; ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection; wpa_s->wpa = wpa_sm_init(ctx); assert(wpa_s->wpa != NULL); wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN); os_strncpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname, NULL); l2 = l2_packet_init(wpa_s->ifname, NULL, ETH_P_RSN_PREAUTH, NULL, NULL, 0); assert(l2 != NULL); if (l2_packet_get_own_addr(l2, wpa_s->own_addr)) { wpa_printf(MSG_WARNING, "Failed to get own L2 address\n"); exit(-1); } l2_packet_deinit(l2); wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr); }
static int bsd_init(struct hostapd_data *hapd) { struct bsd_driver_data *drv; drv = malloc(sizeof(struct bsd_driver_data)); if (drv == NULL) { printf("Could not allocate memory for bsd driver data\n"); goto bad; } memset(drv, 0, sizeof(*drv)); drv->ops = bsd_driver_ops; drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) goto bad; bsd_set_iface_flags(drv, 0); /* mark down during setup */ hapd->driver = &drv->ops; return 0; bad: if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv != NULL) free(drv); return -1; }
static int atheros_receive_probe_req(struct atheros_driver_data *drv) { int ret = 0; #ifdef CONFIG_WPS struct ieee80211req_set_filter filt; wpa_printf(MSG_DEBUG, "%s Enter", __func__); filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ; ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, sizeof(struct ieee80211req_set_filter)); if (ret) return ret; drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, atheros_raw_receive, drv, 1); if (drv->sock_raw == NULL) return -1; #endif /* CONFIG_WPS */ return ret; }
static int wpa_supplicant_driver_init(const char *link, struct wpa_supplicant *wpa_s) { wpa_s->l2 = l2_packet_init(link, ETHERTYPE_EAPOL, wpa_supplicant_rx_eapol, wpa_s); if (wpa_s->l2 == NULL) return (-1); if (l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) { (void) fprintf(stderr, "Failed to get own L2 address\n"); return (-1); } if (wpa_s->driver->set_wpa(wpa_s->linkid, 1) < 0) { wpa_printf(MSG_ERROR, "Failed to enable WPA in the driver."); return (-1); } wpa_clear_keys(wpa_s, NULL); wpa_supplicant_req_scan(wpa_s, 0, 100000); return (0); }
static int wpa_driver_roboswitch_set_param(void *priv, const char *param) { struct wpa_driver_roboswitch_data *drv = priv; char *sep; if (param == NULL || os_strstr(param, "multicast_only=1") == NULL) { sep = drv->ifname + os_strlen(drv->ifname); *sep = '.'; drv->l2 = l2_packet_init(drv->ifname, NULL, ETH_P_ALL, wpa_driver_roboswitch_receive, drv, 1); if (drv->l2 == NULL) { wpa_printf(MSG_INFO, "%s: Unable to listen on %s", __func__, drv->ifname); return -1; } *sep = '\0'; l2_packet_get_own_addr(drv->l2, drv->own_addr); } else { wpa_printf(MSG_DEBUG, "%s: Ignoring unicast frames", __func__); drv->l2 = NULL; } return 0; }
/** * rsn_preauth_init - Start new RSN pre-authentication * @sm: Pointer to WPA state machine data from wpa_sm_init() * @dst: Authenticator address (BSSID) with which to preauthenticate * @eap_conf: Current EAP configuration * Returns: 0 on success, -1 on another pre-authentication is in progress, * -2 on layer 2 packet initialization failure, -3 on EAPOL state machine * initialization failure, -4 on memory allocation failure * * This function request an RSN pre-authentication with a given destination * address. This is usually called for PMKSA candidates found from scan results * or from driver reports. In addition, ctrl_iface PREAUTH command can trigger * pre-authentication. */ int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst, struct eap_peer_config *eap_conf) { struct eapol_config eapol_conf; struct eapol_ctx *ctx; if (sm->preauth_eapol) return -1; wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: starting pre-authentication " "with " MACSTR, MAC2STR(dst)); sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr, ETH_P_RSN_PREAUTH, rsn_preauth_receive, sm, 0); if (sm->l2_preauth == NULL) { wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet " "processing for pre-authentication"); return -2; } if (sm->bridge_ifname) { sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname, sm->own_addr, ETH_P_RSN_PREAUTH, rsn_preauth_receive, sm, 0); if (sm->l2_preauth_br == NULL) { wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 " "packet processing (bridge) for " "pre-authentication"); return -2; } } ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) { wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context."); return -4; } ctx->ctx = sm->ctx->ctx; ctx->msg_ctx = sm->ctx->ctx; ctx->preauth = 1; ctx->cb = rsn_preauth_eapol_cb; ctx->cb_ctx = sm; ctx->scard_ctx = sm->scard_ctx; ctx->eapol_send = rsn_preauth_eapol_send; ctx->eapol_send_ctx = sm; ctx->set_config_blob = sm->ctx->set_config_blob; ctx->get_config_blob = sm->ctx->get_config_blob; sm->preauth_eapol = eapol_sm_init(ctx); if (sm->preauth_eapol == NULL) { os_free(ctx); wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL " "state machines for pre-authentication"); return -3; } os_memset(&eapol_conf, 0, sizeof(eapol_conf)); eapol_conf.accept_802_1x_keys = 0; eapol_conf.required_keys = 0; eapol_conf.fast_reauth = sm->fast_reauth; eapol_conf.workaround = sm->eap_workaround; eapol_sm_notify_config(sm->preauth_eapol, eap_conf, &eapol_conf); /* * Use a shorter startPeriod with preauthentication since the first * preauth EAPOL-Start frame may end up being dropped due to race * condition in the AP between the data receive and key configuration * after the 4-Way Handshake. */ eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6); os_memcpy(sm->preauth_bssid, dst, ETH_ALEN); eapol_sm_notify_portValid(sm->preauth_eapol, TRUE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE); eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0, rsn_preauth_timeout, sm, NULL); return 0; }
static void * atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct atheros_driver_data *drv; struct ifreq ifr; struct iwreq iwr; char brname[IFNAMSIZ]; drv = os_zalloc(sizeof(struct atheros_driver_data)); if (drv == NULL) { printf("Could not allocate memory for atheros driver data\n"); return NULL; } drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } memcpy(drv->iface, params->ifname, sizeof(drv->iface)); memset(&ifr, 0, sizeof(ifr)); os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { perror("ioctl(SIOCGIFINDEX)"); goto bad; } drv->ifindex = ifr.ifr_ifindex; drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; if (params->bridge[0]) { wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", params->bridge[0]); drv->sock_recv = l2_packet_init(params->bridge[0], NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_recv == NULL) goto bad; } else if (linux_br_get(brname, drv->iface) == 0) { wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " "EAPOL receive", brname); drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_recv == NULL) goto bad; } else drv->sock_recv = drv->sock_xmit; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); iwr.u.mode = IW_MODE_MASTER; if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { perror("ioctl[SIOCSIWMODE]"); printf("Could not set interface to master mode!\n"); goto bad; } /* mark down during setup */ linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); atheros_set_privacy(drv, 0); /* default to no privacy */ atheros_receive_probe_req(drv); if (atheros_wireless_event_init(drv)) goto bad; return drv; bad: if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) l2_packet_deinit(drv->sock_recv); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv != NULL) free(drv); return NULL; }
static void * madwifi_init(struct hostapd_data *hapd) { struct madwifi_driver_data *drv; struct ifreq ifr; struct iwreq iwr; drv = os_zalloc(sizeof(struct madwifi_driver_data)); if (drv == NULL) { printf("Could not allocate memory for madwifi driver data\n"); return NULL; } drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); memset(&ifr, 0, sizeof(ifr)); os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { perror("ioctl(SIOCGIFINDEX)"); goto bad; } drv->ifindex = ifr.ifr_ifindex; drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) goto bad; if (hapd->conf->bridge[0] != '\0') { wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", hapd->conf->bridge); drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_recv == NULL) goto bad; } else drv->sock_recv = drv->sock_xmit; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); iwr.u.mode = IW_MODE_MASTER; if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { perror("ioctl[SIOCSIWMODE]"); printf("Could not set interface to master mode!\n"); goto bad; } madwifi_set_iface_flags(drv, 0); /* mark down during setup */ madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */ madwifi_receive_probe_req(drv); return drv; bad: if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv != NULL) free(drv); return NULL; }
static void * bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct bsd_driver_data *drv; drv = os_zalloc(sizeof(struct bsd_driver_data)); if (drv == NULL) { printf("Could not allocate memory for bsd driver data\n"); goto bad; } drv->hapd = hapd; drv->sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); /* * NB: We require the interface name be mappable to an index. * This implies we do not support having wpa_supplicant * wait for an interface to appear. This seems ok; that * doesn't belong here; it's really the job of devd. * XXXSCW: devd is FreeBSD-specific. */ drv->ifindex = if_nametoindex(drv->ifname); if (drv->ifindex == 0) { printf("%s: interface %s does not exist", __func__, drv->ifname); goto bad; } drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, handle_read, drv, 0); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; /* mark down during setup */ if (bsd_ctrl_iface(drv, 0) < 0) goto bad; drv->route = socket(PF_ROUTE, SOCK_RAW, 0); if (drv->route < 0) { perror("socket(PF_ROUTE,SOCK_RAW)"); goto bad; } eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, NULL); return drv; bad: if (drv == NULL) return NULL; if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->sock >= 0) close(drv->sock); os_free(drv); return NULL; }
static int wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) { struct bsd_driver_data *drv = priv; struct ieee80211req_mlme mlme; u32 mode; int privacy; int ret = 0; wpa_printf(MSG_DEBUG, "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" , __func__ , (unsigned int) params->ssid_len, params->ssid , (unsigned int) params->wpa_ie_len , params->pairwise_suite , params->group_suite , params->key_mgmt_suite ); switch (params->mode) { case IEEE80211_MODE_INFRA: mode = 0 /* STA */; break; case IEEE80211_MODE_IBSS: mode = IFM_IEEE80211_IBSS; break; case IEEE80211_MODE_AP: mode = IFM_IEEE80211_HOSTAP; break; default: wpa_printf(MSG_ERROR, "%s: unknown operation mode", __func__); return -1; } if (bsd_set_mediaopt(drv, IFM_OMASK, mode) < 0) { wpa_printf(MSG_ERROR, "%s: failed to set operation mode", __func__); return -1; } if (params->mode == IEEE80211_MODE_AP) { drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, handle_read, drv, 0); if (drv->sock_xmit == NULL) return -1; drv->is_ap = 1; return 0; } if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted) < 0) ret = -1; if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) ret = -1; /* XXX error handling is wrong but unclear what to do... */ if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) return -1; privacy = !(params->pairwise_suite == CIPHER_NONE && params->group_suite == CIPHER_NONE && params->key_mgmt_suite == KEY_MGMT_NONE && params->wpa_ie_len == 0); wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy); if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) return -1; if (params->wpa_ie_len && set80211param(drv, IEEE80211_IOC_WPA, params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) return -1; os_memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_ASSOC; if (params->ssid != NULL) os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len); mlme.im_ssid_len = params->ssid_len; if (params->bssid != NULL) os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) return -1; return ret; }
int hostapd_setup_wpa(struct hostapd_data *hapd) { struct wpa_auth_config _conf; struct wpa_auth_callbacks cb; const u8 *wpa_ie; size_t wpa_ie_len; hostapd_wpa_auth_conf(hapd->conf, &_conf); if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EAPOL_TX_STATUS) _conf.tx_status = 1; os_memset(&cb, 0, sizeof(cb)); cb.ctx = hapd; cb.logger = hostapd_wpa_auth_logger; cb.disconnect = hostapd_wpa_auth_disconnect; cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report; cb.set_eapol = hostapd_wpa_auth_set_eapol; cb.get_eapol = hostapd_wpa_auth_get_eapol; cb.get_psk = hostapd_wpa_auth_get_psk; cb.get_msk = hostapd_wpa_auth_get_msk; cb.set_key = hostapd_wpa_auth_set_key; cb.get_seqnum = hostapd_wpa_auth_get_seqnum; cb.send_eapol = hostapd_wpa_auth_send_eapol; cb.for_each_sta = hostapd_wpa_auth_for_each_sta; cb.for_each_auth = hostapd_wpa_auth_for_each_auth; cb.send_ether = hostapd_wpa_auth_send_ether; #ifdef CONFIG_IEEE80211R cb.send_ft_action = hostapd_wpa_auth_send_ft_action; cb.add_sta = hostapd_wpa_auth_add_sta; #endif /* CONFIG_IEEE80211R */ hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb); if (hapd->wpa_auth == NULL) { wpa_printf(MSG_ERROR, "WPA initialization failed."); return -1; } if (hostapd_set_privacy(hapd, 1)) { wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked " "for interface %s", hapd->conf->iface); return -1; } wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) { wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " "the kernel driver."); return -1; } if (rsn_preauth_iface_init(hapd)) { wpa_printf(MSG_ERROR, "Initialization of RSN " "pre-authentication failed."); return -1; } #ifdef CONFIG_IEEE80211R if (!hostapd_drv_none(hapd)) { hapd->l2 = l2_packet_init(hapd->conf->bridge[0] ? hapd->conf->bridge : hapd->conf->iface, NULL, ETH_P_RRB, hostapd_rrb_receive, hapd, 1); if (hapd->l2 == NULL && (hapd->driver == NULL || hapd->driver->send_ether == NULL)) { wpa_printf(MSG_ERROR, "Failed to open l2_packet " "interface"); return -1; } } #endif /* CONFIG_IEEE80211R */ return 0; }
static void *rtl871x_driver_init_ops(struct hostapd_data *hapd, struct wpa_init_params *params) { struct rtl871x_driver_data *drv; struct ifreq ifr; char ifrn_name[IFNAMSIZ + 1]; // for mgnt_l2_sock/mgnt_sock char brname[IFNAMSIZ]; drv = os_zalloc(sizeof(struct rtl871x_driver_data)); if (drv == NULL) { printf("Could not allocate memory for rtl871x driver data\n"); return NULL; } drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } os_memcpy(drv->iface, params->ifname, sizeof(drv->iface)); linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); // set interface up os_memset(&ifr, 0, sizeof(ifr)); os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { perror("ioctl(SIOCGIFINDEX)"); goto bad; } drv->ifindex = ifr.ifr_ifindex; printf("drv->ifindex=%d\n", drv->ifindex); drv->l2_sock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, rtl871x_handle_read, drv, 1); if (drv->l2_sock == NULL) goto bad; if (l2_packet_get_own_addr(drv->l2_sock, params->own_addr)) goto bad; if (params->bridge[0]) { wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", params->bridge[0]); drv->l2_sock_recv = l2_packet_init(params->bridge[0], NULL, ETH_P_EAPOL, rtl871x_handle_read, drv, 1); if (drv->l2_sock_recv == NULL) { drv->l2_sock_recv = drv->l2_sock; printf("no br0 interface , let l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock); } } else if (linux_br_get(brname, drv->iface) == 0) { wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " "EAPOL receive", brname); drv->l2_sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, rtl871x_handle_read, drv, 1); if (drv->l2_sock_recv == NULL) goto bad; } else { drv->l2_sock_recv = drv->l2_sock; printf("l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock); } os_memset(ifrn_name, 0, sizeof(ifrn_name)); snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s", "wlan0"); #ifdef CONFIG_MGNT_L2SOCK drv->mgnt_l2_sock = NULL; drv->mgnt_l2_sock = l2_packet_init(ifrn_name, NULL, ETH_P_80211_RAW, rtl871x_recvive_mgmt_frame, drv, 1); if (drv->mgnt_l2_sock == NULL) goto bad; #else #ifdef CONFIG_MLME_OFFLOAD drv->mgnt_sock = -1; #else drv->mgnt_sock = rtl871x_mgnt_sock_init(drv, ifrn_name); if (drv->mgnt_sock < 0) { goto bad; } #endif #endif if (rtl871x_set_mode(drv, IW_MODE_MASTER)<0) { printf("Could not set interface to master mode!\n"); goto bad; } #ifndef CONFIG_MLME_OFFLOAD rtl871x_set_iface_flags(drv, 1); // set mgnt interface up #endif if (rtl871x_wireless_event_init(drv)) goto bad; os_memcpy(drv->hw_mac, params->own_addr, ETH_ALEN); return drv; bad: if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock) l2_packet_deinit(drv->l2_sock_recv); if (drv->l2_sock != NULL) l2_packet_deinit(drv->l2_sock); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); #ifdef CONFIG_MGNT_L2SOCK if ( drv->mgnt_l2_sock != NULL) l2_packet_deinit(drv->mgnt_l2_sock); #else if (drv->mgnt_sock >= 0) close(drv->mgnt_sock); #endif if (drv != NULL) free(drv); return NULL; }