Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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);
}
Beispiel #5
0
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
	}
}
Beispiel #8
0
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;
}
Beispiel #9
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;
}
Beispiel #10
0
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;
}
Beispiel #11
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);
}
Beispiel #13
0
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;
}
Beispiel #14
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");
	}
}
Beispiel #15
0
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
}
Beispiel #16
0
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;
}