static int settunnel(prop_dictionary_t env, prop_dictionary_t oenv) { const struct paddr_prefix *srcpfx, *dstpfx; struct if_laddrreq req; prop_data_t srcdata, dstdata; srcdata = (prop_data_t)prop_dictionary_get(env, "tunsrc"); dstdata = (prop_data_t)prop_dictionary_get(env, "tundst"); if (srcdata == NULL || dstdata == NULL) { warnx("%s.%d", __func__, __LINE__); errno = ENOENT; return -1; } srcpfx = prop_data_data_nocopy(srcdata); dstpfx = prop_data_data_nocopy(dstdata); if (srcpfx->pfx_addr.sa_family != dstpfx->pfx_addr.sa_family) errx(EXIT_FAILURE, "source and destination address families do not match"); memset(&req, 0, sizeof(req)); memcpy(&req.addr, &srcpfx->pfx_addr, MIN(sizeof(req.addr), srcpfx->pfx_addr.sa_len)); memcpy(&req.dstaddr, &dstpfx->pfx_addr, MIN(sizeof(req.dstaddr), dstpfx->pfx_addr.sa_len)); #ifdef INET6 if (req.addr.ss_family == AF_INET6) { struct sockaddr_in6 *s6, *d; s6 = (struct sockaddr_in6 *)&req.addr; d = (struct sockaddr_in6 *)&req.dstaddr; if (s6->sin6_scope_id != d->sin6_scope_id) { errx(EXIT_FAILURE, "scope mismatch"); /* NOTREACHED */ } if (IN6_IS_ADDR_MULTICAST(&d->sin6_addr) || IN6_IS_ADDR_MULTICAST(&s6->sin6_addr)) errx(EXIT_FAILURE, "tunnel src/dst is multicast"); /* embed scopeid */ if (s6->sin6_scope_id && IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) { *(u_int16_t *)&s6->sin6_addr.s6_addr[2] = htons(s6->sin6_scope_id); } if (d->sin6_scope_id && IN6_IS_ADDR_LINKLOCAL(&d->sin6_addr)) { *(u_int16_t *)&d->sin6_addr.s6_addr[2] = htons(d->sin6_scope_id); } } #endif /* INET6 */ if (direct_ioctl(env, SIOCSLIFPHYADDR, &req) == -1) warn("SIOCSLIFPHYADDR"); return 0; }
static int setifpowersavesleep(prop_dictionary_t env, prop_dictionary_t oenv) { struct ieee80211_power power; int64_t maxsleep; bool rc; rc = prop_dictionary_get_int64(env, "powersavesleep", &maxsleep); assert(rc); if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) err(EXIT_FAILURE, "SIOCG80211POWER"); power.i_maxsleep = maxsleep; if (direct_ioctl(env, SIOCS80211POWER, &power) == -1) err(EXIT_FAILURE, "SIOCS80211POWER"); return 0; }
static int setifpowersave(prop_dictionary_t env, prop_dictionary_t oenv) { struct ieee80211_power power; bool on, rc; if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) err(EXIT_FAILURE, "SIOCG80211POWER"); rc = prop_dictionary_get_bool(env, "powersave", &on); assert(rc); power.i_enabled = on ? 1 : 0; if (direct_ioctl(env, SIOCS80211POWER, &power) == -1) { warn("SIOCS80211POWER"); return -1; } return 0; }
int indirect_ioctl(prop_dictionary_t env, unsigned long cmd, void *data) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_data = data; return direct_ioctl(env, cmd, &ifr); }
static int unsetifbssid(prop_dictionary_t env, prop_dictionary_t oenv) { struct ieee80211_bssid bssid; memset(&bssid, 0, sizeof(bssid)); if (direct_ioctl(env, SIOCS80211BSSID, &bssid) == -1) err(EXIT_FAILURE, "SIOCS80211BSSID"); return 0; }
static int setifchan(prop_dictionary_t env, prop_dictionary_t oenv) { bool rc; struct ieee80211chanreq channel; rc = prop_dictionary_get_uint16(env, "chan", &channel.i_channel); assert(rc); if (direct_ioctl(env, SIOCS80211CHANNEL, &channel) == -1) err(EXIT_FAILURE, "SIOCS80211CHANNEL"); return 0; }
static void list_scan(prop_dictionary_t env) { u_int8_t buf[64*1024 - 1]; struct ieee80211req ireq; char ssid[IEEE80211_NWID_LEN+1]; const u_int8_t *cp; int len, ssidmax; const struct ieee80211req_scan_result *sr; memset(&ireq, 0, sizeof(ireq)); ireq.i_type = IEEE80211_IOC_SCAN_RESULTS; ireq.i_data = buf; ireq.i_len = sizeof(buf); if (direct_ioctl(env, SIOCG80211, &ireq) < 0) errx(EXIT_FAILURE, "unable to get scan results"); len = ireq.i_len; if (len < (int)sizeof(*sr)) return; ssidmax = calc_len(buf, len); printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" , ssidmax, ssidmax, "SSID" , "BSSID" , "CHAN" , "RATE" , "S:N" , "INT" , "CAPS" ); cp = buf; while (len >= (int)sizeof(*sr)) { const uint8_t *vp; sr = (const struct ieee80211req_scan_result *) cp; vp = (const u_int8_t *)(sr+1); (void)copy_essid(ssid, sizeof(ssid), vp, sr->isr_ssid_len); printf("%-*.*s %s %3d %3dM %3d:%-3d %3d %-4.4s" , ssidmax, ssidmax, ssid , ether_ntoa((const struct ether_addr *) sr->isr_bssid) , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags) , getmaxrate(sr->isr_rates, sr->isr_nrates) , sr->isr_rssi, sr->isr_noise , sr->isr_intval , getcaps(sr->isr_capinfo) ); printies(vp + sr->isr_ssid_len, sr->isr_ie_len, 24); printf("\n"); cp += sr->isr_len, len -= sr->isr_len; } }
static int unsetifnwkey(prop_dictionary_t env, prop_dictionary_t oenv) { struct ieee80211_nwkey nwkey; int i; nwkey.i_wepon = 0; nwkey.i_defkid = 1; for (i = 0; i < IEEE80211_WEP_NKID; i++) { nwkey.i_key[i].i_keylen = 0; nwkey.i_key[i].i_keydat = NULL; } if (direct_ioctl(env, SIOCS80211NWKEY, &nwkey) == -1) err(EXIT_FAILURE, "SIOCS80211NWKEY"); return 0; }
static enum ieee80211_opmode get80211opmode(prop_dictionary_t env) { struct ifmediareq ifmr; memset(&ifmr, 0, sizeof(ifmr)); if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) ; else if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) return IEEE80211_M_IBSS; /* XXX ahdemo */ else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) return IEEE80211_M_HOSTAP; else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) return IEEE80211_M_MONITOR; return IEEE80211_M_STA; }
static int set80211(prop_dictionary_t env, uint16_t type, int16_t val, int16_t len, u_int8_t *data) { struct ieee80211req ireq; memset(&ireq, 0, sizeof(ireq)); ireq.i_type = type; ireq.i_val = val; ireq.i_len = len; ireq.i_data = data; if (direct_ioctl(env, SIOCS80211, &ireq) == -1) { warn("SIOCS80211"); return -1; } return 0; }
static int scan_exec(prop_dictionary_t env, prop_dictionary_t oenv) { struct ifreq ifr; if (direct_ioctl(env, SIOCGIFFLAGS, &ifr) == -1) { warn("ioctl(SIOCGIFFLAGS)"); return -1; } if ((ifr.ifr_flags & IFF_UP) == 0) errx(EXIT_FAILURE, "The interface must be up before scanning."); scan_and_wait(env); list_scan(env); return 0; }
static void tunnel_status(prop_dictionary_t env, prop_dictionary_t oenv) { char dstserv[sizeof(",65535")]; char srcserv[sizeof(",65535")]; char psrcaddr[NI_MAXHOST]; char pdstaddr[NI_MAXHOST]; const int niflag = Nflag ? 0 : (NI_NUMERICHOST|NI_NUMERICSERV); struct if_laddrreq req; const struct afswtch *afp; psrcaddr[0] = pdstaddr[0] = '\0'; memset(&req, 0, sizeof(req)); if (direct_ioctl(env, SIOCGLIFPHYADDR, &req) == -1) return; afp = lookup_af_bynum(req.addr.ss_family); #ifdef INET6 if (req.addr.ss_family == AF_INET6) inet6_getscopeid((struct sockaddr_in6 *)&req.addr, INET6_IS_ADDR_LINKLOCAL); #endif /* INET6 */ getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len, psrcaddr, sizeof(psrcaddr), &srcserv[1], sizeof(srcserv) - 1, niflag); #ifdef INET6 if (req.dstaddr.ss_family == AF_INET6) inet6_getscopeid((struct sockaddr_in6 *)&req.dstaddr, INET6_IS_ADDR_LINKLOCAL); #endif getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len, pdstaddr, sizeof(pdstaddr), &dstserv[1], sizeof(dstserv) - 1, niflag); srcserv[0] = (strcmp(&srcserv[1], "0") == 0) ? '\0' : ','; dstserv[0] = (strcmp(&dstserv[1], "0") == 0) ? '\0' : ','; printf("\ttunnel %s %s%s --> %s%s\n", afp ? afp->af_name : "???", psrcaddr, srcserv, pdstaddr, dstserv); }
static int setifbssid(prop_dictionary_t env, prop_dictionary_t oenv) { char buf[24]; struct ieee80211_bssid bssid; struct ether_addr *ea; if (getargstr(env, "bssid", buf, sizeof(buf)) == -1) errx(EXIT_FAILURE, "%s: BSSID too long", __func__); ea = ether_aton(buf); if (ea == NULL) { errx(EXIT_FAILURE, "malformed BSSID: %s", buf); return -1; } memcpy(&bssid.i_bssid, ea->ether_addr_octet, sizeof(bssid.i_bssid)); if (direct_ioctl(env, SIOCS80211BSSID, &bssid) == -1) err(EXIT_FAILURE, "SIOCS80211BSSID"); return 0; }
static void ieee80211_status(prop_dictionary_t env, prop_dictionary_t oenv) { int i, nwkey_verbose; struct ieee80211_nwid nwid; struct ieee80211_nwkey nwkey; struct ieee80211_power power; u_int8_t keybuf[IEEE80211_WEP_NKID][16]; struct ieee80211_bssid bssid; struct ieee80211chanreq channel; struct ieee80211req ireq; struct ether_addr ea; static const u_int8_t zero_macaddr[IEEE80211_ADDR_LEN]; enum ieee80211_opmode opmode = get80211opmode(env); memset(&bssid, 0, sizeof(bssid)); memset(&nwkey, 0, sizeof(nwkey)); memset(&nwid, 0, sizeof(nwid)); memset(&nwid, 0, sizeof(nwid)); if (indirect_ioctl(env, SIOCG80211NWID, &nwid) == -1) return; if (nwid.i_len > IEEE80211_NWID_LEN) { errx(EXIT_FAILURE, "SIOCG80211NWID: wrong length of nwid (%d)", nwid.i_len); } printf("\tssid "); print_string(nwid.i_nwid, nwid.i_len); if (opmode == IEEE80211_M_HOSTAP) { ireq.i_type = IEEE80211_IOC_HIDESSID; if (direct_ioctl(env, SIOCG80211, &ireq) != -1) { if (ireq.i_val) printf(" [hidden]"); else if (vflag) printf(" [shown]"); } ireq.i_type = IEEE80211_IOC_APBRIDGE; if (direct_ioctl(env, SIOCG80211, &ireq) != -1) { if (ireq.i_val) printf(" apbridge"); else if (vflag) printf(" -apbridge"); } } ireq.i_type = IEEE80211_IOC_RTSTHRESHOLD; if (direct_ioctl(env, SIOCG80211, &ireq) == -1) ; else if (ireq.i_val < IEEE80211_RTS_MAX) printf(" rts %d", ireq.i_val); else if (vflag) printf(" -rts"); ireq.i_type = IEEE80211_IOC_FRAGTHRESHOLD; if (direct_ioctl(env, SIOCG80211, &ireq) == -1) ; else if (ireq.i_val < IEEE80211_FRAG_MAX) printf(" frag %d", ireq.i_val); else if (vflag) printf(" -frag"); memset(&nwkey, 0, sizeof(nwkey)); /* show nwkey only when WEP is enabled */ if (direct_ioctl(env, SIOCG80211NWKEY, &nwkey) == -1 || nwkey.i_wepon == 0) { printf("\n"); goto skip_wep; } printf(" nwkey "); /* try to retrieve WEP keys */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { nwkey.i_key[i].i_keydat = keybuf[i]; nwkey.i_key[i].i_keylen = sizeof(keybuf[i]); } if (direct_ioctl(env, SIOCG80211NWKEY, &nwkey) == -1) { printf("*****"); } else { nwkey_verbose = 0; /* check to see non default key or multiple keys defined */ if (nwkey.i_defkid != 1) { nwkey_verbose = 1; } else { for (i = 1; i < IEEE80211_WEP_NKID; i++) { if (nwkey.i_key[i].i_keylen != 0) { nwkey_verbose = 1; break; } } } /* check extra ambiguity with keywords */ if (!nwkey_verbose) { if (nwkey.i_key[0].i_keylen >= 2 && isdigit(nwkey.i_key[0].i_keydat[0]) && nwkey.i_key[0].i_keydat[1] == ':') nwkey_verbose = 1; else if (nwkey.i_key[0].i_keylen >= 7 && strncasecmp("persist", (const char *)nwkey.i_key[0].i_keydat, 7) == 0) nwkey_verbose = 1; } if (nwkey_verbose) printf("%d:", nwkey.i_defkid); for (i = 0; i < IEEE80211_WEP_NKID; i++) { if (i > 0) printf(","); if (nwkey.i_key[i].i_keylen < 0) printf("persist"); else print_string(nwkey.i_key[i].i_keydat, nwkey.i_key[i].i_keylen); if (!nwkey_verbose) break; } } printf("\n"); skip_wep: if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) goto skip_power; printf("\tpowersave "); if (power.i_enabled) printf("on (%dms sleep)", power.i_maxsleep); else printf("off"); printf("\n"); skip_power: if (direct_ioctl(env, SIOCG80211BSSID, &bssid) == -1) return; if (direct_ioctl(env, SIOCG80211CHANNEL, &channel) == -1) return; if (memcmp(bssid.i_bssid, zero_macaddr, IEEE80211_ADDR_LEN) == 0) { if (channel.i_channel != (u_int16_t)-1) printf("\tchan %d\n", channel.i_channel); } else { memcpy(ea.ether_addr_octet, bssid.i_bssid, sizeof(ea.ether_addr_octet)); printf("\tbssid %s", ether_ntoa(&ea)); if (channel.i_channel != IEEE80211_CHAN_ANY) printf(" chan %d", channel.i_channel); printf("\n"); } }
static void ieee80211_statistics(prop_dictionary_t env) { #ifndef SMALL struct ieee80211_stats stats; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_buflen = sizeof(stats); ifr.ifr_buf = (caddr_t)&stats; if (direct_ioctl(env, (zflag) ? SIOCG80211ZSTATS : SIOCG80211STATS, &ifr) == -1) return; #define STAT_PRINT(_member, _desc) \ printf("\t" _desc ": %" PRIu32 "\n", stats._member) STAT_PRINT(is_rx_badversion, "rx frame with bad version"); STAT_PRINT(is_rx_tooshort, "rx frame too short"); STAT_PRINT(is_rx_wrongbss, "rx from wrong bssid"); STAT_PRINT(is_rx_dup, "rx discard 'cuz dup"); STAT_PRINT(is_rx_wrongdir, "rx w/ wrong direction"); STAT_PRINT(is_rx_mcastecho, "rx discard 'cuz mcast echo"); STAT_PRINT(is_rx_notassoc, "rx discard 'cuz sta !assoc"); STAT_PRINT(is_rx_noprivacy, "rx w/ wep but privacy off"); STAT_PRINT(is_rx_unencrypted, "rx w/o wep and privacy on"); STAT_PRINT(is_rx_wepfail, "rx wep processing failed"); STAT_PRINT(is_rx_decap, "rx decapsulation failed"); STAT_PRINT(is_rx_mgtdiscard, "rx discard mgt frames"); STAT_PRINT(is_rx_ctl, "rx discard ctrl frames"); STAT_PRINT(is_rx_beacon, "rx beacon frames"); STAT_PRINT(is_rx_rstoobig, "rx rate set truncated"); STAT_PRINT(is_rx_elem_missing, "rx required element missing"); STAT_PRINT(is_rx_elem_toobig, "rx element too big"); STAT_PRINT(is_rx_elem_toosmall, "rx element too small"); STAT_PRINT(is_rx_elem_unknown, "rx element unknown"); STAT_PRINT(is_rx_badchan, "rx frame w/ invalid chan"); STAT_PRINT(is_rx_chanmismatch, "rx frame chan mismatch"); STAT_PRINT(is_rx_nodealloc, "rx frame dropped"); STAT_PRINT(is_rx_ssidmismatch, "rx frame ssid mismatch "); STAT_PRINT(is_rx_auth_unsupported, "rx w/ unsupported auth alg"); STAT_PRINT(is_rx_auth_fail, "rx sta auth failure"); STAT_PRINT(is_rx_auth_countermeasures, "rx auth discard 'cuz CM"); STAT_PRINT(is_rx_assoc_bss, "rx assoc from wrong bssid"); STAT_PRINT(is_rx_assoc_notauth, "rx assoc w/o auth"); STAT_PRINT(is_rx_assoc_capmismatch, "rx assoc w/ cap mismatch"); STAT_PRINT(is_rx_assoc_norate, "rx assoc w/ no rate match"); STAT_PRINT(is_rx_assoc_badwpaie, "rx assoc w/ bad WPA IE"); STAT_PRINT(is_rx_deauth, "rx deauthentication"); STAT_PRINT(is_rx_disassoc, "rx disassociation"); STAT_PRINT(is_rx_badsubtype, "rx frame w/ unknown subtyp"); STAT_PRINT(is_rx_nobuf, "rx failed for lack of buf"); STAT_PRINT(is_rx_decryptcrc, "rx decrypt failed on crc"); STAT_PRINT(is_rx_ahdemo_mgt, "rx discard ahdemo mgt fram"); STAT_PRINT(is_rx_bad_auth, "rx bad auth request"); STAT_PRINT(is_rx_unauth, "rx on unauthorized port"); STAT_PRINT(is_rx_badkeyid, "rx w/ incorrect keyid"); STAT_PRINT(is_rx_ccmpreplay, "rx seq# violation (CCMP)"); STAT_PRINT(is_rx_ccmpformat, "rx format bad (CCMP)"); STAT_PRINT(is_rx_ccmpmic, "rx MIC check failed (CCMP)"); STAT_PRINT(is_rx_tkipreplay, "rx seq# violation (TKIP)"); STAT_PRINT(is_rx_tkipformat, "rx format bad (TKIP)"); STAT_PRINT(is_rx_tkipmic, "rx MIC check failed (TKIP)"); STAT_PRINT(is_rx_tkipicv, "rx ICV check failed (TKIP)"); STAT_PRINT(is_rx_badcipher, "rx failed 'cuz key type"); STAT_PRINT(is_rx_nocipherctx, "rx failed 'cuz key !setup"); STAT_PRINT(is_rx_acl, "rx discard 'cuz acl policy"); STAT_PRINT(is_tx_nobuf, "tx failed for lack of buf"); STAT_PRINT(is_tx_nonode, "tx failed for no node"); STAT_PRINT(is_tx_unknownmgt, "tx of unknown mgt frame"); STAT_PRINT(is_tx_badcipher, "tx failed 'cuz key type"); STAT_PRINT(is_tx_nodefkey, "tx failed 'cuz no defkey"); STAT_PRINT(is_tx_noheadroom, "tx failed 'cuz no space"); STAT_PRINT(is_tx_fragframes, "tx frames fragmented"); STAT_PRINT(is_tx_frags, "tx fragments created"); STAT_PRINT(is_scan_active, "active scans started"); STAT_PRINT(is_scan_passive, "passive scans started"); STAT_PRINT(is_node_timeout, "nodes timed out inactivity"); STAT_PRINT(is_crypto_nomem, "no memory for crypto ctx"); STAT_PRINT(is_crypto_tkip, "tkip crypto done in s/w"); STAT_PRINT(is_crypto_tkipenmic, "tkip en-MIC done in s/w"); STAT_PRINT(is_crypto_tkipdemic, "tkip de-MIC done in s/w"); STAT_PRINT(is_crypto_tkipcm, "tkip counter measures"); STAT_PRINT(is_crypto_ccmp, "ccmp crypto done in s/w"); STAT_PRINT(is_crypto_wep, "wep crypto done in s/w"); STAT_PRINT(is_crypto_setkey_cipher, "cipher rejected key"); STAT_PRINT(is_crypto_setkey_nokey, "no key index for setkey"); STAT_PRINT(is_crypto_delkey, "driver key delete failed"); STAT_PRINT(is_crypto_badcipher, "unknown cipher"); STAT_PRINT(is_crypto_nocipher, "cipher not available"); STAT_PRINT(is_crypto_attachfail, "cipher attach failed"); STAT_PRINT(is_crypto_swfallback, "cipher fallback to s/w"); STAT_PRINT(is_crypto_keyfail, "driver key alloc failed"); STAT_PRINT(is_crypto_enmicfail, "en-MIC failed"); STAT_PRINT(is_ibss_capmismatch, "merge failed-cap mismatch"); STAT_PRINT(is_ibss_norate, "merge failed-rate mismatch"); STAT_PRINT(is_ps_unassoc, "ps-poll for unassoc. sta"); STAT_PRINT(is_ps_badaid, "ps-poll w/ incorrect aid"); STAT_PRINT(is_ps_qempty, "ps-poll w/ nothing to send"); STAT_PRINT(is_ff_badhdr, "fast frame rx'd w/ bad hdr"); STAT_PRINT(is_ff_tooshort, "fast frame rx decap error"); STAT_PRINT(is_ff_split, "fast frame rx split error"); STAT_PRINT(is_ff_decap, "fast frames decap'd"); STAT_PRINT(is_ff_encap, "fast frames encap'd for tx"); STAT_PRINT(is_rx_badbintval, "rx frame w/ bogus bintval"); #endif }
static int setifnwkey(prop_dictionary_t env, prop_dictionary_t oenv) { const char *val; char buf[256]; struct ieee80211_nwkey nwkey; int i; u_int8_t keybuf[IEEE80211_WEP_NKID][16]; if (getargstr(env, "nwkey", buf, sizeof(buf)) == -1) errx(EXIT_FAILURE, "%s: nwkey too long", __func__); val = buf; nwkey.i_wepon = IEEE80211_NWKEY_WEP; nwkey.i_defkid = 1; for (i = 0; i < IEEE80211_WEP_NKID; i++) { nwkey.i_key[i].i_keylen = sizeof(keybuf[i]); nwkey.i_key[i].i_keydat = keybuf[i]; } if (strcasecmp("persist", val) == 0) { /* use all values from persistent memory */ nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST; nwkey.i_defkid = 0; for (i = 0; i < IEEE80211_WEP_NKID; i++) nwkey.i_key[i].i_keylen = -1; } else if (strncasecmp("persist:", val, 8) == 0) { val += 8; /* program keys in persistent memory */ nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST; goto set_nwkey; } else { set_nwkey: if (isdigit((unsigned char)val[0]) && val[1] == ':') { /* specifying a full set of four keys */ nwkey.i_defkid = val[0] - '0'; val += 2; for (i = 0; i < IEEE80211_WEP_NKID; i++) { val = get_string(val, ",", keybuf[i], &nwkey.i_key[i].i_keylen, true); if (val == NULL) { errno = EINVAL; return -1; } } if (*val != '\0') { errx(EXIT_FAILURE, "SIOCS80211NWKEY: too many keys."); } } else { val = get_string(val, NULL, keybuf[0], &nwkey.i_key[0].i_keylen, true); if (val == NULL) { errno = EINVAL; return -1; } i = 1; } } for (; i < IEEE80211_WEP_NKID; i++) nwkey.i_key[i].i_keylen = 0; if (direct_ioctl(env, SIOCS80211NWKEY, &nwkey) == -1) err(EXIT_FAILURE, "SIOCS80211NWKEY"); return 0; }