static int bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) { wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); if (!params->enabled) { /* XXX restore state */ return set80211param(priv, IEEE80211_IOC_AUTHMODE, IEEE80211_AUTH_AUTO); } if (!params->wpa && !params->ieee802_1x) { wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled", __func__); return -1; } if (params->wpa && bsd_configure_wpa(priv, params) != 0) { wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state", __func__); return -1; } if (set80211param(priv, IEEE80211_IOC_AUTHMODE, (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X", __func__); return -1; } return bsd_ctrl_iface(priv, 1); }
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 bsd_deinit(void *priv) { struct bsd_driver_data *drv = priv; if (drv->route >= 0) { eloop_unregister_read_sock(drv->route); close(drv->route); } bsd_ctrl_iface(drv, 0); if (drv->sock >= 0) close(drv->sock); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); os_free(drv); }
static void wpa_driver_bsd_deinit(void *priv) { struct bsd_driver_data *drv = priv; wpa_driver_bsd_set_wpa(drv, 0); eloop_unregister_read_sock(drv->route); /* NB: mark interface down */ bsd_ctrl_iface(drv, 0); wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", __func__); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); (void) close(drv->route); /* ioctl socket */ (void) close(drv->sock); /* event socket */ os_free(drv); }
static void * wpa_driver_bsd_init(void *ctx, const char *ifname) { #define GETPARAM(drv, param, v) \ (((v) = get80211param(drv, param)) != -1) struct bsd_driver_data *drv; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; /* * 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. */ drv->ifindex = if_nametoindex(ifname); if (drv->ifindex == 0) { wpa_printf(MSG_DEBUG, "%s: interface %s does not exist", __func__, ifname); goto fail1; } drv->sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->sock < 0) goto fail1; drv->route = socket(PF_ROUTE, SOCK_RAW, 0); if (drv->route < 0) goto fail; eloop_register_read_sock(drv->route, wpa_driver_bsd_event_receive, ctx, drv); drv->ctx = ctx; os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); /* Down interface during setup. */ if (bsd_ctrl_iface(drv, 0) < 0) goto fail; if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", __func__, strerror(errno)); goto fail; } if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", __func__, strerror(errno)); goto fail; } if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", __func__, strerror(errno)); goto fail; } if (wpa_driver_bsd_capa(drv)) goto fail; return drv; fail: close(drv->sock); fail1: os_free(drv); return NULL; #undef GETPARAM }
static int wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) { struct bsd_driver_data *drv = priv; #ifdef IEEE80211_IOC_SCAN_MAX_SSID struct ieee80211_scan_req sr; int i; #endif /* IEEE80211_IOC_SCAN_MAX_SSID */ if (bsd_set_mediaopt(drv, IFM_OMASK, 0 /* STA */) < 0) { wpa_printf(MSG_ERROR, "%s: failed to set operation mode", __func__); return -1; } if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { wpa_printf(MSG_ERROR, "%s: failed to set " "wpa_supplicant-based roaming: %s", __func__, strerror(errno)); return -1; } if (wpa_driver_bsd_set_wpa(drv, 1) < 0) { wpa_printf(MSG_ERROR, "%s: failed to set wpa: %s", __func__, strerror(errno)); return -1; } /* NB: interface must be marked UP to do a scan */ if (bsd_ctrl_iface(drv, 1) < 0) return -1; #ifdef IEEE80211_IOC_SCAN_MAX_SSID os_memset(&sr, 0, sizeof(sr)); sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOJOIN; sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; if (params->num_ssids > 0) { sr.sr_nssid = params->num_ssids; #if 0 /* Boundary check is done by upper layer */ if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID) sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID; #endif /* NB: check scan cache first */ sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; } for (i = 0; i < sr.sr_nssid; i++) { sr.sr_ssid[i].len = params->ssids[i].ssid_len; os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid, sr.sr_ssid[i].len); } /* NB: net80211 delivers a scan complete event so no need to poll */ return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); #else /* IEEE80211_IOC_SCAN_MAX_SSID */ /* set desired ssid before scan */ if (bsd_set_ssid(drv, params->ssids[0].ssid, params->ssids[0].ssid_len) < 0) return -1; /* NB: net80211 delivers a scan complete event so no need to poll */ return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0); #endif /* IEEE80211_IOC_SCAN_MAX_SSID */ }
static int bsd_commit(void *priv) { return bsd_ctrl_iface(priv, 1); }
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; }