static void wpa_driver_bsd_deinit(void *priv) { struct wpa_driver_bsd_data *drv = priv; int flags; /* NB: mark interface down */ if (getifflags(drv, &flags) == 0) (void) setifflags(drv, flags &~ IFF_UP); wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) { /* NB: don't whinge if device ejected or equivalent */ if (errno != ENXIO) wpa_printf(MSG_DEBUG, "%s: failed to restore roaming " "state", __func__); } if (drv->drivercaps & IEEE80211_C_BGSCAN) { /* XXX check return value */ (void) set80211param(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid); } (void) close(drv->route); /* ioctl socket */ (void) close(drv->sock); /* event socket */ free(drv); }
const char * getifinfo(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp) { if (getifflags(env, oenv, flagsp) == -1) return NULL; return getifname(env); }
static int wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) { struct wpa_driver_bsd_data *drv = priv; struct ieee80211_scan_req sr; int flags; /* XXX not true but easiest to perpetuate the myth */ /* NB: interface must be marked UP to do a scan */ if (getifflags(drv, &flags) != 0) { wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); return -1; } if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", __func__); return -1; } 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 (ssid_len != 0) { /* XXX ssid_len must be <= IEEE80211_NWID_LEN */ memcpy(sr.sr_ssid[sr.sr_nssid].ssid, ssid, ssid_len); sr.sr_ssid[sr.sr_nssid].len = ssid_len; sr.sr_nssid++; } if (drv->lastssid_len != 0 && (drv->lastssid_len != ssid_len || memcmp(drv->lastssid, ssid, ssid_len) != 0)) { /* * If we are scanning because we received a deauth * and the scan cache is warm then we'll find the * ap there and short circuit a full-blown scan. */ memcpy(sr.sr_ssid[sr.sr_nssid].ssid, drv->lastssid, drv->lastssid_len); sr.sr_ssid[sr.sr_nssid].len = drv->lastssid_len; sr.sr_nssid++; /* NB: clear so we don't retry w/o associating first */ drv->lastssid_len = 0; } if (sr.sr_nssid != 0) /* NB: check scan cache first */ sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; /* NB: net80211 delivers a scan complete event so no need to poll */ return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); }
static int wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) { struct wpa_driver_bsd_data *drv = priv; int flags; /* NB: interface must be marked UP to do a scan */ if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0) return -1; /* set desired ssid before scan */ if (wpa_driver_bsd_set_ssid(drv, ssid, 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); }
static void wpa_driver_bsd_deinit(void *priv) { struct wpa_driver_bsd_data *drv = priv; int flags; /* NB: mark interface down */ if (getifflags(drv, &flags) == 0) (void) setifflags(drv, flags &~ IFF_UP); 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__); (void) close(drv->route); /* ioctl socket */ (void) close(drv->sock); /* event socket */ free(drv); }
static void * wpa_driver_bsd_init(void *ctx, const char *ifname) { struct wpa_driver_bsd_data *drv; struct ieee80211_devcaps_req devcaps; int flags; drv = malloc(sizeof(*drv)); if (drv == NULL) return NULL; memset(drv, 0, sizeof(*drv)); /* * 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->ctx = ctx; strncpy(drv->ifname, ifname, sizeof(drv->ifname)); /* * Mark the interface as down to ensure wpa_supplicant has exclusive * access to the net80211 state machine, do this before opening the * route socket to avoid a false event that the interface disappeared. */ if (getifflags(drv, &flags) == 0) (void) setifflags(drv, flags &~ IFF_UP); 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); if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) { wpa_printf(MSG_DEBUG, "%s: failed to get device capabilities: %s", __func__, strerror(errno)); goto fail; } drv->drivercaps = devcaps.dc_drivercaps; drv->cryptocaps = devcaps.dc_cryptocaps; 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 (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " "roaming: %s", __func__, strerror(errno)); goto fail; } if (drv->drivercaps & IEEE80211_C_BGSCAN) { /* * Driver does background scanning; force the scan valid * setting to 1.5 x bg scan interval so the scan cache is * always consulted before we force a foreground scan. */ if (setscanvalid(drv) < 0) { wpa_printf(MSG_DEBUG, "%s: warning, failed to set scanvalid, scanning " "may be suboptimal: %s", __func__, strerror(errno)); } } if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", __func__, strerror(errno)); goto fail; } return drv; fail: close(drv->sock); fail1: free(drv); return NULL; }