ancontrol.c revision 201387
161822Sgreen/*
255992Swpaul * Copyright 1997, 1998, 1999
355992Swpaul *	Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
455992Swpaul *
555992Swpaul * Redistribution and use in source and binary forms, with or without
655992Swpaul * modification, are permitted provided that the following conditions
755992Swpaul * are met:
855992Swpaul * 1. Redistributions of source code must retain the above copyright
955992Swpaul *    notice, this list of conditions and the following disclaimer.
1055992Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1155992Swpaul *    notice, this list of conditions and the following disclaimer in the
1255992Swpaul *    documentation and/or other materials provided with the distribution.
1355992Swpaul * 3. All advertising materials mentioning features or use of this software
1455992Swpaul *    must display the following acknowledgement:
1555992Swpaul *	This product includes software developed by Bill Paul.
1655992Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1755992Swpaul *    may be used to endorse or promote products derived from this software
1855992Swpaul *    without specific prior written permission.
1955992Swpaul *
2055992Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2155992Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2255992Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2355992Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
2455992Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2555992Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2655992Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2755992Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2855992Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2955992Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3055992Swpaul * THE POSSIBILITY OF SUCH DAMAGE.
3155992Swpaul */
3255992Swpaul
33114601Sobrien#if 0
3481586Sru#ifndef lint
3581586Srustatic const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\
3681586Sru	Bill Paul. All rights reserved.";
3781586Sru#endif
38114601Sobrien#endif
39114601Sobrien#include <sys/cdefs.h>
40114601Sobrien__FBSDID("$FreeBSD: head/usr.sbin/ancontrol/ancontrol.c 201387 2010-01-02 11:05:34Z ed $");
4181586Sru
4255992Swpaul#include <sys/types.h>
4355992Swpaul#include <sys/cdefs.h>
4455992Swpaul#include <sys/socket.h>
4555992Swpaul#include <sys/ioctl.h>
4655992Swpaul
4790868Smike#include <arpa/inet.h>
4890868Smike
4955992Swpaul#include <net/if.h>
5055992Swpaul#include <net/if_var.h>
5155992Swpaul#include <net/ethernet.h>
5255992Swpaul
5355992Swpaul#include <dev/an/if_aironet_ieee.h>
5455992Swpaul
5555992Swpaul#include <stdio.h>
5655992Swpaul#include <string.h>
5755992Swpaul#include <stdlib.h>
5855992Swpaul#include <unistd.h>
5955992Swpaul#include <errno.h>
6055992Swpaul#include <err.h>
6188748Sambrisko#include <md4.h>
62108401Sambrisko#include <ctype.h>
6355992Swpaul
64108401Sambriskostatic int an_getval(const char *, struct an_req *);
6599800Salfredstatic void an_setval(const char *, struct an_req *);
66132860Snjlstatic void an_printwords(const u_int16_t *, int);
67132860Snjlstatic void an_printspeeds(const u_int8_t *, int);
6899800Salfredstatic void an_printbool(int);
69132860Snjlstatic void an_printhex(const char *, int);
7099800Salfredstatic void an_printstr(char *, int);
7199800Salfredstatic void an_dumpstatus(const char *);
7299800Salfredstatic void an_dumpstats(const char *);
7399800Salfredstatic void an_dumpconfig(const char *);
7499800Salfredstatic void an_dumpcaps(const char *);
7599800Salfredstatic void an_dumpssid(const char *);
7699800Salfredstatic void an_dumpap(const char *);
7799800Salfredstatic void an_setconfig(const char *, int, void *);
7899800Salfredstatic void an_setssid(const char *, int, void *);
7999800Salfredstatic void an_setap(const char *, int, void *);
8099800Salfredstatic void an_setspeed(const char *, int, void *);
8199800Salfredstatic void an_readkeyinfo(const char *);
8255992Swpaul#ifdef ANCACHE
8399800Salfredstatic void an_zerocache(const char *);
8499800Salfredstatic void an_readcache(const char *);
8555992Swpaul#endif
8699800Salfredstatic int an_hex2int(char);
87132860Snjlstatic void an_str2key(const char *, struct an_ltv_key *);
88132860Snjlstatic void an_setkeys(const char *, const char *, int);
89132860Snjlstatic void an_enable_tx_key(const char *, const char *);
90132860Snjlstatic void an_enable_leap_mode(const char *, const char *);
91108401Sambriskostatic void an_dumprssimap(const char *);
92132860Snjlstatic void usage(const char *);
9355992Swpaul
9455992Swpaul#define ACT_DUMPSTATS 1
9555992Swpaul#define ACT_DUMPCONFIG 2
9655992Swpaul#define ACT_DUMPSTATUS 3
9755992Swpaul#define ACT_DUMPCAPS 4
9855992Swpaul#define ACT_DUMPSSID 5
9955992Swpaul#define ACT_DUMPAP 6
10055992Swpaul
10155992Swpaul#define ACT_SET_OPMODE 7
102119156Sambrisko#define ACT_SET_SSID 8
10355992Swpaul#define ACT_SET_FREQ 11
10455992Swpaul#define ACT_SET_AP1 12
10555992Swpaul#define ACT_SET_AP2 13
10655992Swpaul#define ACT_SET_AP3 14
10755992Swpaul#define ACT_SET_AP4 15
10855992Swpaul#define ACT_SET_DRIVERNAME 16
10955992Swpaul#define ACT_SET_SCANMODE 17
11055992Swpaul#define ACT_SET_TXRATE 18
11155992Swpaul#define ACT_SET_RTS_THRESH 19
11255992Swpaul#define ACT_SET_PWRSAVE 20
11355992Swpaul#define ACT_SET_DIVERSITY_RX 21
11455992Swpaul#define ACT_SET_DIVERSITY_TX 22
11555992Swpaul#define ACT_SET_RTS_RETRYLIM 23
11655992Swpaul#define ACT_SET_WAKE_DURATION 24
11755992Swpaul#define ACT_SET_BEACON_PERIOD 25
11855992Swpaul#define ACT_SET_TXPWR 26
11955992Swpaul#define ACT_SET_FRAG_THRESH 27
12055992Swpaul#define ACT_SET_NETJOIN 28
12155992Swpaul#define ACT_SET_MYNAME 29
12255992Swpaul#define ACT_SET_MAC 30
12355992Swpaul
12455992Swpaul#define ACT_DUMPCACHE 31
12555992Swpaul#define ACT_ZEROCACHE 32
12655992Swpaul
12768692Swpaul#define ACT_ENABLE_WEP 33
12868692Swpaul#define ACT_SET_KEY_TYPE 34
12968692Swpaul#define ACT_SET_KEYS 35
13069772Sarchie#define ACT_ENABLE_TX_KEY 36
13183269Sbrooks#define ACT_SET_MONITOR_MODE 37
13288748Sambrisko#define ACT_SET_LEAP_MODE 38
13368692Swpaul
134108401Sambrisko#define ACT_DUMPRSSIMAP 39
135108401Sambrisko
136132860Snjlstatic int
137132860Snjlan_getval(const char *iface, struct an_req *areq)
13855992Swpaul{
13955992Swpaul	struct ifreq		ifr;
140108401Sambrisko	int			s, okay = 1;
14155992Swpaul
142132900Snjl	bzero(&ifr, sizeof(ifr));
14355992Swpaul
14461815Sroberto	strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
14555992Swpaul	ifr.ifr_data = (caddr_t)areq;
14655992Swpaul
14755992Swpaul	s = socket(AF_INET, SOCK_DGRAM, 0);
14855992Swpaul
14955992Swpaul	if (s == -1)
15055992Swpaul		err(1, "socket");
15155992Swpaul
152108401Sambrisko	if (ioctl(s, SIOCGAIRONET, &ifr) == -1) {
153108401Sambrisko		okay = 0;
15455992Swpaul		err(1, "SIOCGAIRONET");
155108401Sambrisko	}
15655992Swpaul
15755992Swpaul	close(s);
15855992Swpaul
159132860Snjl	return (okay);
16055992Swpaul}
16155992Swpaul
162132860Snjlstatic void
163132860Snjlan_setval(const char *iface, struct an_req *areq)
16455992Swpaul{
16555992Swpaul	struct ifreq		ifr;
16655992Swpaul	int			s;
16755992Swpaul
168132900Snjl	bzero(&ifr, sizeof(ifr));
16955992Swpaul
17061815Sroberto	strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
17155992Swpaul	ifr.ifr_data = (caddr_t)areq;
17255992Swpaul
17355992Swpaul	s = socket(AF_INET, SOCK_DGRAM, 0);
17455992Swpaul
17555992Swpaul	if (s == -1)
17655992Swpaul		err(1, "socket");
17755992Swpaul
17855992Swpaul	if (ioctl(s, SIOCSAIRONET, &ifr) == -1)
17955992Swpaul		err(1, "SIOCSAIRONET");
18055992Swpaul
18155992Swpaul	close(s);
18255992Swpaul
18355992Swpaul	return;
18455992Swpaul}
18555992Swpaul
186132860Snjlstatic void
187132860Snjlan_printstr(char *str, int len)
18855992Swpaul{
18955992Swpaul	int			i;
19055992Swpaul
19155992Swpaul	for (i = 0; i < len - 1; i++) {
19255992Swpaul		if (str[i] == '\0')
19355992Swpaul			str[i] = ' ';
19455992Swpaul	}
19555992Swpaul
19655992Swpaul	printf("[ %.*s ]", len, str);
19755992Swpaul}
19855992Swpaul
199132860Snjlstatic void
200132860Snjlan_printwords(const u_int16_t *w, int len)
20155992Swpaul{
20255992Swpaul	int			i;
20355992Swpaul
20455992Swpaul	printf("[ ");
20555992Swpaul	for (i = 0; i < len; i++)
206132860Snjl		printf("%u ", w[i]);
20755992Swpaul	printf("]");
20855992Swpaul}
20955992Swpaul
210132860Snjlstatic void
211132860Snjlan_printspeeds(const u_int8_t *w, int len)
21255992Swpaul{
21355992Swpaul	int			i;
21455992Swpaul
21555992Swpaul	printf("[ ");
21655992Swpaul	for (i = 0; i < len && w[i]; i++)
21755992Swpaul		printf("%2.1fMbps ", w[i] * 0.500);
21855992Swpaul	printf("]");
21955992Swpaul}
22055992Swpaul
221132860Snjlstatic void
222132860Snjlan_printbool(int val)
22355992Swpaul{
22455992Swpaul	if (val)
22555992Swpaul		printf("[ On ]");
22655992Swpaul	else
22755992Swpaul		printf("[ Off ]");
22855992Swpaul}
22955992Swpaul
230132860Snjlstatic void
231132860Snjlan_printhex(const char *ptr, int len)
23255992Swpaul{
23355992Swpaul	int			i;
23455992Swpaul
23555992Swpaul	printf("[ ");
23655992Swpaul	for (i = 0; i < len; i++) {
23755992Swpaul		printf("%02x", ptr[i] & 0xFF);
23855992Swpaul		if (i < (len - 1))
23955992Swpaul			printf(":");
24055992Swpaul	}
24155992Swpaul
24255992Swpaul	printf(" ]");
24355992Swpaul}
24455992Swpaul
24568692Swpaul
24668692Swpaul
247132860Snjlstatic void
248132860Snjlan_dumpstatus(const char *iface)
24955992Swpaul{
25055992Swpaul	struct an_ltv_status	*sts;
25155992Swpaul	struct an_req		areq;
252108401Sambrisko	struct an_ltv_rssi_map	an_rssimap;
253108401Sambrisko	int rssimap_valid = 0;
25455992Swpaul
255108401Sambrisko	/*
256108401Sambrisko	 * Try to get RSSI to percent and dBM table
257108401Sambrisko	 */
258108401Sambrisko
259108401Sambrisko	an_rssimap.an_len = sizeof(an_rssimap);
260108401Sambrisko	an_rssimap.an_type = AN_RID_RSSI_MAP;
261108401Sambrisko	rssimap_valid = an_getval(iface, (struct an_req*)&an_rssimap);
262108401Sambrisko
263108401Sambrisko	if (rssimap_valid)
264108401Sambrisko		printf("RSSI table:\t\t[ present ]\n");
265108401Sambrisko	else
266108401Sambrisko		printf("RSSI table:\t\t[ not available ]\n");
267108401Sambrisko
26855992Swpaul	areq.an_len = sizeof(areq);
26955992Swpaul	areq.an_type = AN_RID_STATUS;
27055992Swpaul
27155992Swpaul	an_getval(iface, &areq);
27255992Swpaul
27355992Swpaul	sts = (struct an_ltv_status *)&areq;
27455992Swpaul
27555992Swpaul	printf("MAC address:\t\t");
27655992Swpaul	an_printhex((char *)&sts->an_macaddr, ETHER_ADDR_LEN);
27755992Swpaul	printf("\nOperating mode:\t\t[ ");
27855992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_CONFIGURED)
27955992Swpaul		printf("configured ");
28055992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_MAC_ENABLED)
28155992Swpaul		printf("MAC ON ");
28255992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_RX_ENABLED)
28355992Swpaul		printf("RX ON ");
28455992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_IN_SYNC)
28555992Swpaul		printf("synced ");
28655992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
28755992Swpaul		printf("associated ");
28888748Sambrisko	if (sts->an_opmode & AN_STATUS_OPMODE_LEAP)
28988748Sambrisko		printf("LEAP ");
29055992Swpaul	if (sts->an_opmode & AN_STATUS_OPMODE_ERROR)
29155992Swpaul		printf("error ");
29255992Swpaul	printf("]\n");
29355992Swpaul	printf("Error code:\t\t");
29455992Swpaul	an_printhex((char *)&sts->an_errcode, 1);
295108401Sambrisko	if (rssimap_valid)
296132860Snjl		printf("\nSignal strength:\t[ %u%% ]",
297108401Sambrisko		    an_rssimap.an_entries[
298108401Sambrisko			sts->an_normalized_strength].an_rss_pct);
299108401Sambrisko	else
300132860Snjl		printf("\nSignal strength:\t[ %u%% ]",
301108401Sambrisko		    sts->an_normalized_strength);
302132860Snjl	printf("\nAverage Noise:\t\t[ %u%% ]", sts->an_avg_noise_prev_min_pc);
303108401Sambrisko	if (rssimap_valid)
304132860Snjl		printf("\nSignal quality:\t\t[ %u%% ]",
305108401Sambrisko		    an_rssimap.an_entries[
306108401Sambrisko			sts->an_cur_signal_quality].an_rss_pct);
307108401Sambrisko	else
308132860Snjl		printf("\nSignal quality:\t\t[ %u ]",
309108401Sambrisko		    sts->an_cur_signal_quality);
310132860Snjl	printf("\nMax Noise:\t\t[ %u%% ]", sts->an_max_noise_prev_min_pc);
31178788Sbrooks	/*
31278788Sbrooks	 * XXX: This uses the old definition of the rate field (units of
31378788Sbrooks	 * 500kbps).  Technically the new definition is that this field
31478788Sbrooks	 * contains arbitrary values, but no devices which need this
31578788Sbrooks	 * support exist and the IEEE seems to intend to use the old
31678788Sbrooks	 * definition until they get something big so we'll keep using
31778788Sbrooks	 * it as well because this will work with new cards with
31878788Sbrooks	 * rate <= 63.5Mbps.
31978788Sbrooks	 */
320132860Snjl	printf("\nCurrent TX rate:\t[ %u%s ]", sts->an_current_tx_rate / 2,
32178788Sbrooks	    (sts->an_current_tx_rate % 2) ? ".5" : "");
32255992Swpaul	printf("\nCurrent SSID:\t\t");
32355992Swpaul	an_printstr((char *)&sts->an_ssid, sts->an_ssidlen);
32455992Swpaul	printf("\nCurrent AP name:\t");
32555992Swpaul	an_printstr((char *)&sts->an_ap_name, 16);
32655992Swpaul	printf("\nCurrent BSSID:\t\t");
32755992Swpaul	an_printhex((char *)&sts->an_cur_bssid, ETHER_ADDR_LEN);
32855992Swpaul	printf("\nBeacon period:\t\t");
32955992Swpaul	an_printwords(&sts->an_beacon_period, 1);
33055992Swpaul	printf("\nDTIM period:\t\t");
33155992Swpaul	an_printwords(&sts->an_dtim_period, 1);
33255992Swpaul	printf("\nATIM duration:\t\t");
33355992Swpaul	an_printwords(&sts->an_atim_duration, 1);
33455992Swpaul	printf("\nHOP period:\t\t");
33555992Swpaul	an_printwords(&sts->an_hop_period, 1);
33655992Swpaul	printf("\nChannel set:\t\t");
33755992Swpaul	an_printwords(&sts->an_channel_set, 1);
33855992Swpaul	printf("\nCurrent channel:\t");
33955992Swpaul	an_printwords(&sts->an_cur_channel, 1);
34055992Swpaul	printf("\nHops to backbone:\t");
34155992Swpaul	an_printwords(&sts->an_hops_to_backbone, 1);
34255992Swpaul	printf("\nTotal AP load:\t\t");
34355992Swpaul	an_printwords(&sts->an_ap_total_load, 1);
34455992Swpaul	printf("\nOur generated load:\t");
34555992Swpaul	an_printwords(&sts->an_our_generated_load, 1);
34655992Swpaul	printf("\nAccumulated ARL:\t");
34755992Swpaul	an_printwords(&sts->an_accumulated_arl, 1);
34855992Swpaul	printf("\n");
34955992Swpaul	return;
35055992Swpaul}
35155992Swpaul
352132860Snjlstatic void
353132860Snjlan_dumpcaps(const char *iface)
35455992Swpaul{
35555992Swpaul	struct an_ltv_caps	*caps;
35655992Swpaul	struct an_req		areq;
35755992Swpaul	u_int16_t		tmp;
35855992Swpaul
35955992Swpaul	areq.an_len = sizeof(areq);
36055992Swpaul	areq.an_type = AN_RID_CAPABILITIES;
36155992Swpaul
36255992Swpaul	an_getval(iface, &areq);
36355992Swpaul
36455992Swpaul	caps = (struct an_ltv_caps *)&areq;
36555992Swpaul
36655992Swpaul	printf("OUI:\t\t\t");
36755992Swpaul	an_printhex((char *)&caps->an_oui, 3);
36855992Swpaul	printf("\nProduct number:\t\t");
36955992Swpaul	an_printwords(&caps->an_prodnum, 1);
37055992Swpaul	printf("\nManufacturer name:\t");
37155992Swpaul	an_printstr((char *)&caps->an_manufname, 32);
37255992Swpaul	printf("\nProduce name:\t\t");
37355992Swpaul	an_printstr((char *)&caps->an_prodname, 16);
37455992Swpaul	printf("\nFirmware version:\t");
37555992Swpaul	an_printstr((char *)&caps->an_prodvers, 1);
37655992Swpaul	printf("\nOEM MAC address:\t");
37755992Swpaul	an_printhex((char *)&caps->an_oemaddr, ETHER_ADDR_LEN);
37855992Swpaul	printf("\nAironet MAC address:\t");
37955992Swpaul	an_printhex((char *)&caps->an_aironetaddr, ETHER_ADDR_LEN);
38055992Swpaul	printf("\nRadio type:\t\t[ ");
38155992Swpaul	if (caps->an_radiotype & AN_RADIOTYPE_80211_FH)
38255992Swpaul		printf("802.11 FH");
38355992Swpaul	else if (caps->an_radiotype & AN_RADIOTYPE_80211_DS)
38455992Swpaul		printf("802.11 DS");
38555992Swpaul	else if (caps->an_radiotype & AN_RADIOTYPE_LM2000_DS)
38655992Swpaul		printf("LM2000 DS");
38755992Swpaul	else
38855992Swpaul		printf("unknown (%x)", caps->an_radiotype);
38955992Swpaul	printf(" ]");
39055992Swpaul	printf("\nRegulatory domain:\t");
39155992Swpaul	an_printwords(&caps->an_regdomain, 1);
39255992Swpaul	printf("\nAssigned CallID:\t");
39355992Swpaul	an_printhex((char *)&caps->an_callid, 6);
39455992Swpaul	printf("\nSupported speeds:\t");
39555992Swpaul	an_printspeeds(caps->an_rates, 8);
39655992Swpaul	printf("\nRX Diversity:\t\t[ ");
397108401Sambrisko	if (caps->an_rx_diversity == AN_DIVERSITY_FACTORY_DEFAULT)
398108401Sambrisko		printf("factory default");
399108401Sambrisko	else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
40055992Swpaul		printf("antenna 1 only");
40155992Swpaul	else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
40255992Swpaul		printf("antenna 2 only");
40355992Swpaul	else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
40455992Swpaul		printf("antenna 1 and 2");
40555992Swpaul	printf(" ]");
40655992Swpaul	printf("\nTX Diversity:\t\t[ ");
407108401Sambrisko	if (caps->an_tx_diversity == AN_DIVERSITY_FACTORY_DEFAULT)
408108401Sambrisko		printf("factory default");
409108401Sambrisko	else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
41055992Swpaul		printf("antenna 1 only");
411108401Sambrisko	else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
41255992Swpaul		printf("antenna 2 only");
413108401Sambrisko	else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
41455992Swpaul		printf("antenna 1 and 2");
41555992Swpaul	printf(" ]");
41655992Swpaul	printf("\nSupported power levels:\t");
41755992Swpaul	an_printwords(caps->an_tx_powerlevels, 8);
41855992Swpaul	printf("\nHardware revision:\t");
41955992Swpaul	tmp = ntohs(caps->an_hwrev);
42055992Swpaul	an_printhex((char *)&tmp, 2);
42155992Swpaul	printf("\nSoftware revision:\t");
42255992Swpaul	tmp = ntohs(caps->an_fwrev);
42355992Swpaul	an_printhex((char *)&tmp, 2);
42455992Swpaul	printf("\nSoftware subrevision:\t");
42555992Swpaul	tmp = ntohs(caps->an_fwsubrev);
42655992Swpaul	an_printhex((char *)&tmp, 2);
42755992Swpaul	printf("\nInterface revision:\t");
42855992Swpaul	tmp = ntohs(caps->an_ifacerev);
42955992Swpaul	an_printhex((char *)&tmp, 2);
43055992Swpaul	printf("\nBootblock revision:\t");
43155992Swpaul	tmp = ntohs(caps->an_bootblockrev);
43255992Swpaul	an_printhex((char *)&tmp, 2);
43355992Swpaul	printf("\n");
43455992Swpaul	return;
43555992Swpaul}
43655992Swpaul
437132860Snjlstatic void
438132860Snjlan_dumpstats(const char *iface)
43955992Swpaul{
44055992Swpaul	struct an_ltv_stats	*stats;
44155992Swpaul	struct an_req		areq;
44255992Swpaul
44355992Swpaul	areq.an_len = sizeof(areq);
44455992Swpaul	areq.an_type = AN_RID_32BITS_CUM;
44555992Swpaul
44655992Swpaul	an_getval(iface, &areq);
44755992Swpaul
448132900Snjl	stats = (struct an_ltv_stats *)((uint16_t *)&areq - 1);
44955992Swpaul
450132860Snjl	printf("RX overruns:\t\t\t\t\t[ %u ]\n", stats->an_rx_overruns);
451132860Snjl	printf("RX PLCP CSUM errors:\t\t\t\t[ %u ]\n",
45255992Swpaul	    stats->an_rx_plcp_csum_errs);
453132860Snjl	printf("RX PLCP format errors:\t\t\t\t[ %u ]\n",
45455992Swpaul	    stats->an_rx_plcp_format_errs);
455132860Snjl	printf("RX PLCP length errors:\t\t\t\t[ %u ]\n",
45655992Swpaul	    stats->an_rx_plcp_len_errs);
457132860Snjl	printf("RX MAC CRC errors:\t\t\t\t[ %u ]\n",
45855992Swpaul	    stats->an_rx_mac_crc_errs);
459132860Snjl	printf("RX MAC CRC OK:\t\t\t\t\t[ %u ]\n",
46055992Swpaul	    stats->an_rx_mac_crc_ok);
461132860Snjl	printf("RX WEP errors:\t\t\t\t\t[ %u ]\n",
46255992Swpaul	    stats->an_rx_wep_errs);
463132860Snjl	printf("RX WEP OK:\t\t\t\t\t[ %u ]\n",
46455992Swpaul	    stats->an_rx_wep_ok);
465132860Snjl	printf("Long retries:\t\t\t\t\t[ %u ]\n",
46655992Swpaul	    stats->an_retry_long);
467132860Snjl	printf("Short retries:\t\t\t\t\t[ %u ]\n",
46855992Swpaul	    stats->an_retry_short);
469132860Snjl	printf("Retries exhausted:\t\t\t\t[ %u ]\n",
47055992Swpaul	    stats->an_retry_max);
471132860Snjl	printf("Bad ACK:\t\t\t\t\t[ %u ]\n",
47255992Swpaul	    stats->an_no_ack);
473132860Snjl	printf("Bad CTS:\t\t\t\t\t[ %u ]\n",
47455992Swpaul	    stats->an_no_cts);
475132860Snjl	printf("RX good ACKs:\t\t\t\t\t[ %u ]\n",
47655992Swpaul	    stats->an_rx_ack_ok);
477132860Snjl	printf("RX good CTSs:\t\t\t\t\t[ %u ]\n",
47855992Swpaul	    stats->an_rx_cts_ok);
479132860Snjl	printf("TX good ACKs:\t\t\t\t\t[ %u ]\n",
48055992Swpaul	    stats->an_tx_ack_ok);
481132860Snjl	printf("TX good RTSs:\t\t\t\t\t[ %u ]\n",
48255992Swpaul	    stats->an_tx_rts_ok);
483132860Snjl	printf("TX good CTSs:\t\t\t\t\t[ %u ]\n",
48455992Swpaul	    stats->an_tx_cts_ok);
485132860Snjl	printf("LMAC multicasts transmitted:\t\t\t[ %u ]\n",
48655992Swpaul	    stats->an_tx_lmac_mcasts);
487132860Snjl	printf("LMAC broadcasts transmitted:\t\t\t[ %u ]\n",
48855992Swpaul	    stats->an_tx_lmac_bcasts);
489132860Snjl	printf("LMAC unicast frags transmitted:\t\t\t[ %u ]\n",
49055992Swpaul	    stats->an_tx_lmac_ucast_frags);
491132860Snjl	printf("LMAC unicasts transmitted:\t\t\t[ %u ]\n",
49255992Swpaul	    stats->an_tx_lmac_ucasts);
493132860Snjl	printf("Beacons transmitted:\t\t\t\t[ %u ]\n",
49455992Swpaul	    stats->an_tx_beacons);
495132860Snjl	printf("Beacons received:\t\t\t\t[ %u ]\n",
49655992Swpaul	    stats->an_rx_beacons);
497132860Snjl	printf("Single transmit collisions:\t\t\t[ %u ]\n",
49855992Swpaul	    stats->an_tx_single_cols);
499132860Snjl	printf("Multiple transmit collisions:\t\t\t[ %u ]\n",
50055992Swpaul	    stats->an_tx_multi_cols);
501132860Snjl	printf("Transmits without deferrals:\t\t\t[ %u ]\n",
50255992Swpaul	    stats->an_tx_defers_no);
503132860Snjl	printf("Transmits deferred due to protocol:\t\t[ %u ]\n",
50455992Swpaul	    stats->an_tx_defers_prot);
505132860Snjl	printf("Transmits deferred due to energy detect:\t\t[ %u ]\n",
50655992Swpaul	    stats->an_tx_defers_energy);
507132860Snjl	printf("RX duplicate frames/frags:\t\t\t[ %u ]\n",
50855992Swpaul	    stats->an_rx_dups);
509132860Snjl	printf("RX partial frames:\t\t\t\t[ %u ]\n",
51055992Swpaul	    stats->an_rx_partial);
511132860Snjl	printf("TX max lifetime exceeded:\t\t\t[ %u ]\n",
51255992Swpaul	    stats->an_tx_too_old);
513132860Snjl	printf("RX max lifetime exceeded:\t\t\t[ %u ]\n",
51455992Swpaul	    stats->an_tx_too_old);
515132860Snjl	printf("Sync lost due to too many missed beacons:\t[ %u ]\n",
51655992Swpaul	    stats->an_lostsync_missed_beacons);
517132860Snjl	printf("Sync lost due to ARL exceeded:\t\t\t[ %u ]\n",
51855992Swpaul	    stats->an_lostsync_arl_exceeded);
519132860Snjl	printf("Sync lost due to deauthentication:\t\t[ %u ]\n",
52055992Swpaul	    stats->an_lostsync_deauthed);
521132860Snjl	printf("Sync lost due to disassociation:\t\t[ %u ]\n",
52255992Swpaul	    stats->an_lostsync_disassociated);
523132860Snjl	printf("Sync lost due to excess change in TSF timing:\t[ %u ]\n",
52455992Swpaul	    stats->an_lostsync_tsf_timing);
525132860Snjl	printf("Host transmitted multicasts:\t\t\t[ %u ]\n",
52655992Swpaul	    stats->an_tx_host_mcasts);
527132860Snjl	printf("Host transmitted broadcasts:\t\t\t[ %u ]\n",
52855992Swpaul	    stats->an_tx_host_bcasts);
529132860Snjl	printf("Host transmitted unicasts:\t\t\t[ %u ]\n",
53055992Swpaul	    stats->an_tx_host_ucasts);
531132860Snjl	printf("Host transmission failures:\t\t\t[ %u ]\n",
53255992Swpaul	    stats->an_tx_host_failed);
533132860Snjl	printf("Host received multicasts:\t\t\t[ %u ]\n",
53455992Swpaul	    stats->an_rx_host_mcasts);
535132860Snjl	printf("Host received broadcasts:\t\t\t[ %u ]\n",
53655992Swpaul	    stats->an_rx_host_bcasts);
537132860Snjl	printf("Host received unicasts:\t\t\t\t[ %u ]\n",
53855992Swpaul	    stats->an_rx_host_ucasts);
539132860Snjl	printf("Host receive discards:\t\t\t\t[ %u ]\n",
54055992Swpaul	    stats->an_rx_host_discarded);
541132860Snjl	printf("HMAC transmitted multicasts:\t\t\t[ %u ]\n",
54255992Swpaul	    stats->an_tx_hmac_mcasts);
543132860Snjl	printf("HMAC transmitted broadcasts:\t\t\t[ %u ]\n",
54455992Swpaul	    stats->an_tx_hmac_bcasts);
545132860Snjl	printf("HMAC transmitted unicasts:\t\t\t[ %u ]\n",
54655992Swpaul	    stats->an_tx_hmac_ucasts);
547132860Snjl	printf("HMAC transmissions failed:\t\t\t[ %u ]\n",
54855992Swpaul	    stats->an_tx_hmac_failed);
549132860Snjl	printf("HMAC received multicasts:\t\t\t[ %u ]\n",
55055992Swpaul	    stats->an_rx_hmac_mcasts);
551132860Snjl	printf("HMAC received broadcasts:\t\t\t[ %u ]\n",
55255992Swpaul	    stats->an_rx_hmac_bcasts);
553132860Snjl	printf("HMAC received unicasts:\t\t\t\t[ %u ]\n",
55455992Swpaul	    stats->an_rx_hmac_ucasts);
555132860Snjl	printf("HMAC receive discards:\t\t\t\t[ %u ]\n",
55655992Swpaul	    stats->an_rx_hmac_discarded);
557132860Snjl	printf("HMAC transmits accepted:\t\t\t[ %u ]\n",
55855992Swpaul	    stats->an_tx_hmac_accepted);
559132860Snjl	printf("SSID mismatches:\t\t\t\t[ %u ]\n",
56055992Swpaul	    stats->an_ssid_mismatches);
561132860Snjl	printf("Access point mismatches:\t\t\t[ %u ]\n",
56255992Swpaul	    stats->an_ap_mismatches);
563132860Snjl	printf("Speed mismatches:\t\t\t\t[ %u ]\n",
56455992Swpaul	    stats->an_rates_mismatches);
565132860Snjl	printf("Authentication rejects:\t\t\t\t[ %u ]\n",
56655992Swpaul	    stats->an_auth_rejects);
567132860Snjl	printf("Authentication timeouts:\t\t\t[ %u ]\n",
56855992Swpaul	    stats->an_auth_timeouts);
569132860Snjl	printf("Association rejects:\t\t\t\t[ %u ]\n",
57055992Swpaul	    stats->an_assoc_rejects);
571132860Snjl	printf("Association timeouts:\t\t\t\t[ %u ]\n",
57255992Swpaul	    stats->an_assoc_timeouts);
573132860Snjl	printf("Management frames received:\t\t\t[ %u ]\n",
57455992Swpaul	    stats->an_rx_mgmt_pkts);
575132860Snjl	printf("Management frames transmitted:\t\t\t[ %u ]\n",
57655992Swpaul	    stats->an_tx_mgmt_pkts);
577132860Snjl	printf("Refresh frames received:\t\t\t[ %u ]\n",
57855992Swpaul	    stats->an_rx_refresh_pkts),
579132860Snjl	printf("Refresh frames transmitted:\t\t\t[ %u ]\n",
58055992Swpaul	    stats->an_tx_refresh_pkts),
581132860Snjl	printf("Poll frames received:\t\t\t\t[ %u ]\n",
58255992Swpaul	    stats->an_rx_poll_pkts);
583132860Snjl	printf("Poll frames transmitted:\t\t\t[ %u ]\n",
58455992Swpaul	    stats->an_tx_poll_pkts);
585132860Snjl	printf("Host requested sync losses:\t\t\t[ %u ]\n",
58655992Swpaul	    stats->an_lostsync_hostreq);
587132860Snjl	printf("Host transmitted bytes:\t\t\t\t[ %u ]\n",
58855992Swpaul	    stats->an_host_tx_bytes);
589132860Snjl	printf("Host received bytes:\t\t\t\t[ %u ]\n",
59055992Swpaul	    stats->an_host_rx_bytes);
591132860Snjl	printf("Uptime in microseconds:\t\t\t\t[ %u ]\n",
59255992Swpaul	    stats->an_uptime_usecs);
593132860Snjl	printf("Uptime in seconds:\t\t\t\t[ %u ]\n",
59455992Swpaul	    stats->an_uptime_secs);
595132860Snjl	printf("Sync lost due to better AP:\t\t\t[ %u ]\n",
59655992Swpaul	    stats->an_lostsync_better_ap);
59755992Swpaul}
59855992Swpaul
599132860Snjlstatic void
600132860Snjlan_dumpap(const char *iface)
60155992Swpaul{
60255992Swpaul	struct an_ltv_aplist	*ap;
60355992Swpaul	struct an_req		areq;
60455992Swpaul
60555992Swpaul	areq.an_len = sizeof(areq);
60655992Swpaul	areq.an_type = AN_RID_APLIST;
60755992Swpaul
60855992Swpaul	an_getval(iface, &areq);
60955992Swpaul
61055992Swpaul	ap = (struct an_ltv_aplist *)&areq;
61155992Swpaul	printf("Access point 1:\t\t\t");
61255992Swpaul	an_printhex((char *)&ap->an_ap1, ETHER_ADDR_LEN);
61355992Swpaul	printf("\nAccess point 2:\t\t\t");
61455992Swpaul	an_printhex((char *)&ap->an_ap2, ETHER_ADDR_LEN);
61555992Swpaul	printf("\nAccess point 3:\t\t\t");
61655992Swpaul	an_printhex((char *)&ap->an_ap3, ETHER_ADDR_LEN);
61755992Swpaul	printf("\nAccess point 4:\t\t\t");
61855992Swpaul	an_printhex((char *)&ap->an_ap4, ETHER_ADDR_LEN);
61955992Swpaul	printf("\n");
62055992Swpaul
62155992Swpaul	return;
62255992Swpaul}
62355992Swpaul
624132860Snjlstatic void
625132860Snjlan_dumpssid(const char *iface)
62655992Swpaul{
627119156Sambrisko	struct an_ltv_ssidlist_new	*ssid;
62855992Swpaul	struct an_req		areq;
629119156Sambrisko	int			i, max;
63055992Swpaul
63155992Swpaul	areq.an_len = sizeof(areq);
63255992Swpaul	areq.an_type = AN_RID_SSIDLIST;
63355992Swpaul
63455992Swpaul	an_getval(iface, &areq);
63555992Swpaul
636119156Sambrisko	max = (areq.an_len - 4) / sizeof(struct an_ltv_ssid_entry);
637119156Sambrisko	if ( max > MAX_SSIDS ) {
638132860Snjl		printf("Too many SSIDs only printing %d of %d\n",
639119156Sambrisko		    MAX_SSIDS, max);
640119156Sambrisko		max = MAX_SSIDS;
641119156Sambrisko	}
642119156Sambrisko	ssid = (struct an_ltv_ssidlist_new *)&areq;
643119156Sambrisko	for (i = 0; i < max; i++)
644119156Sambrisko		printf("SSID %2d:\t\t\t[ %.*s ]\n", i + 1,
645119156Sambrisko		    ssid->an_entry[i].an_len,
646119156Sambrisko		    ssid->an_entry[i].an_ssid);
64755992Swpaul
64855992Swpaul	return;
64955992Swpaul}
65055992Swpaul
651132860Snjlstatic void
652132860Snjlan_dumpconfig(const char *iface)
65355992Swpaul{
65455992Swpaul	struct an_ltv_genconfig	*cfg;
65555992Swpaul	struct an_req		areq;
65680454Sbrooks	unsigned char		diversity;
65755992Swpaul
65855992Swpaul	areq.an_len = sizeof(areq);
65955992Swpaul	areq.an_type = AN_RID_ACTUALCFG;
66055992Swpaul
66155992Swpaul	an_getval(iface, &areq);
66255992Swpaul
66355992Swpaul	cfg = (struct an_ltv_genconfig *)&areq;
66455992Swpaul
66555992Swpaul	printf("Operating mode:\t\t\t\t[ ");
66655992Swpaul	if ((cfg->an_opmode & 0x7) == AN_OPMODE_IBSS_ADHOC)
66755992Swpaul		printf("ad-hoc");
66855992Swpaul	if ((cfg->an_opmode & 0x7) == AN_OPMODE_INFRASTRUCTURE_STATION)
66955992Swpaul		printf("infrastructure");
67055992Swpaul	if ((cfg->an_opmode & 0x7) == AN_OPMODE_AP)
67155992Swpaul		printf("access point");
67255992Swpaul	if ((cfg->an_opmode & 0x7) == AN_OPMODE_AP_REPEATER)
67355992Swpaul		printf("access point repeater");
67455992Swpaul	printf(" ]");
67555992Swpaul	printf("\nReceive mode:\t\t\t\t[ ");
67655992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_BC_MC_ADDR)
67755992Swpaul		printf("broadcast/multicast/unicast");
67855992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_BC_ADDR)
67955992Swpaul		printf("broadcast/unicast");
68055992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_ADDR)
68155992Swpaul		printf("unicast");
68255992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_80211_MONITOR_CURBSS)
68355992Swpaul		printf("802.11 monitor, current BSSID");
68455992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_80211_MONITOR_ANYBSS)
68555992Swpaul		printf("802.11 monitor, any BSSID");
68655992Swpaul	if ((cfg->an_rxmode & 0x7) == AN_RXMODE_LAN_MONITOR_CURBSS)
68755992Swpaul		printf("LAN monitor, current BSSID");
68855992Swpaul	printf(" ]");
68955992Swpaul	printf("\nFragment threshold:\t\t\t");
69055992Swpaul	an_printwords(&cfg->an_fragthresh, 1);
69155992Swpaul	printf("\nRTS threshold:\t\t\t\t");
69255992Swpaul	an_printwords(&cfg->an_rtsthresh, 1);
69355992Swpaul	printf("\nMAC address:\t\t\t\t");
69455992Swpaul	an_printhex((char *)&cfg->an_macaddr, ETHER_ADDR_LEN);
69555992Swpaul	printf("\nSupported rates:\t\t\t");
69655992Swpaul	an_printspeeds(cfg->an_rates, 8);
69755992Swpaul	printf("\nShort retry limit:\t\t\t");
69855992Swpaul	an_printwords(&cfg->an_shortretry_limit, 1);
69955992Swpaul	printf("\nLong retry limit:\t\t\t");
70055992Swpaul	an_printwords(&cfg->an_longretry_limit, 1);
70155992Swpaul	printf("\nTX MSDU lifetime:\t\t\t");
70255992Swpaul	an_printwords(&cfg->an_tx_msdu_lifetime, 1);
70355992Swpaul	printf("\nRX MSDU lifetime:\t\t\t");
70455992Swpaul	an_printwords(&cfg->an_rx_msdu_lifetime, 1);
70555992Swpaul	printf("\nStationary:\t\t\t\t");
70655992Swpaul	an_printbool(cfg->an_stationary);
70755992Swpaul	printf("\nOrdering:\t\t\t\t");
70855992Swpaul	an_printbool(cfg->an_ordering);
70955992Swpaul	printf("\nDevice type:\t\t\t\t[ ");
71055992Swpaul	if (cfg->an_devtype == AN_DEVTYPE_PC4500)
71155992Swpaul		printf("PC4500");
71255992Swpaul	else if (cfg->an_devtype == AN_DEVTYPE_PC4800)
71355992Swpaul		printf("PC4800");
71455992Swpaul	else
71555992Swpaul		printf("unknown (%x)", cfg->an_devtype);
71655992Swpaul	printf(" ]");
71755992Swpaul	printf("\nScanning mode:\t\t\t\t[ ");
71855992Swpaul	if (cfg->an_scanmode == AN_SCANMODE_ACTIVE)
71955992Swpaul		printf("active");
72055992Swpaul	if (cfg->an_scanmode == AN_SCANMODE_PASSIVE)
72155992Swpaul		printf("passive");
72255992Swpaul	if (cfg->an_scanmode == AN_SCANMODE_AIRONET_ACTIVE)
72355992Swpaul		printf("Aironet active");
72455992Swpaul	printf(" ]");
72555992Swpaul	printf("\nProbe delay:\t\t\t\t");
72655992Swpaul	an_printwords(&cfg->an_probedelay, 1);
72755992Swpaul	printf("\nProbe energy timeout:\t\t\t");
72855992Swpaul	an_printwords(&cfg->an_probe_energy_timeout, 1);
72955992Swpaul	printf("\nProbe response timeout:\t\t\t");
73055992Swpaul	an_printwords(&cfg->an_probe_response_timeout, 1);
73155992Swpaul	printf("\nBeacon listen timeout:\t\t\t");
73255992Swpaul	an_printwords(&cfg->an_beacon_listen_timeout, 1);
73355992Swpaul	printf("\nIBSS join network timeout:\t\t");
73455992Swpaul	an_printwords(&cfg->an_ibss_join_net_timeout, 1);
73555992Swpaul	printf("\nAuthentication timeout:\t\t\t");
73655992Swpaul	an_printwords(&cfg->an_auth_timeout, 1);
73768692Swpaul	printf("\nWEP enabled:\t\t\t\t[ ");
73869772Sarchie	if (cfg->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE)
73969772Sarchie	{
74088748Sambrisko		if (cfg->an_authtype & AN_AUTHTYPE_LEAP)
74188748Sambrisko			 printf("LEAP");
74288748Sambrisko		else if (cfg->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED)
74369772Sarchie			 printf("mixed cell");
74469772Sarchie		else
74569772Sarchie			 printf("full");
74669772Sarchie	}
74768692Swpaul	else
74868692Swpaul		printf("no");
74968692Swpaul	printf(" ]");
75055992Swpaul	printf("\nAuthentication type:\t\t\t[ ");
75168692Swpaul	if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_NONE)
75268692Swpaul		printf("none");
75368692Swpaul	if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_OPEN)
75455992Swpaul		printf("open");
75568692Swpaul	if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_SHAREDKEY)
75655992Swpaul		printf("shared key");
75755992Swpaul	printf(" ]");
75855992Swpaul	printf("\nAssociation timeout:\t\t\t");
75955992Swpaul	an_printwords(&cfg->an_assoc_timeout, 1);
76055992Swpaul	printf("\nSpecified AP association timeout:\t");
76155992Swpaul	an_printwords(&cfg->an_specified_ap_timeout, 1);
76255992Swpaul	printf("\nOffline scan interval:\t\t\t");
76355992Swpaul	an_printwords(&cfg->an_offline_scan_interval, 1);
76455992Swpaul	printf("\nOffline scan duration:\t\t\t");
76555992Swpaul	an_printwords(&cfg->an_offline_scan_duration, 1);
76655992Swpaul	printf("\nLink loss delay:\t\t\t");
76755992Swpaul	an_printwords(&cfg->an_link_loss_delay, 1);
76855992Swpaul	printf("\nMax beacon loss time:\t\t\t");
76955992Swpaul	an_printwords(&cfg->an_max_beacon_lost_time, 1);
77055992Swpaul	printf("\nRefresh interval:\t\t\t");
77155992Swpaul	an_printwords(&cfg->an_refresh_interval, 1);
77255992Swpaul	printf("\nPower save mode:\t\t\t[ ");
77355992Swpaul	if (cfg->an_psave_mode == AN_PSAVE_NONE)
77455992Swpaul		printf("none");
77555992Swpaul	if (cfg->an_psave_mode == AN_PSAVE_CAM)
77655992Swpaul		printf("constantly awake mode");
77755992Swpaul	if (cfg->an_psave_mode == AN_PSAVE_PSP)
77855992Swpaul		printf("PSP");
77955992Swpaul	if (cfg->an_psave_mode == AN_PSAVE_PSP_CAM)
78055992Swpaul		printf("PSP-CAM (fast PSP)");
78155992Swpaul	printf(" ]");
78255992Swpaul	printf("\nSleep through DTIMs:\t\t\t");
78355992Swpaul	an_printbool(cfg->an_sleep_for_dtims);
78455992Swpaul	printf("\nPower save listen interval:\t\t");
78555992Swpaul	an_printwords(&cfg->an_listen_interval, 1);
78655992Swpaul	printf("\nPower save fast listen interval:\t");
78755992Swpaul	an_printwords(&cfg->an_fast_listen_interval, 1);
78855992Swpaul	printf("\nPower save listen decay:\t\t");
78955992Swpaul	an_printwords(&cfg->an_listen_decay, 1);
79055992Swpaul	printf("\nPower save fast listen decay:\t\t");
79155992Swpaul	an_printwords(&cfg->an_fast_listen_decay, 1);
79255992Swpaul	printf("\nAP/ad-hoc Beacon period:\t\t");
79355992Swpaul	an_printwords(&cfg->an_beacon_period, 1);
79455992Swpaul	printf("\nAP/ad-hoc ATIM duration:\t\t");
79555992Swpaul	an_printwords(&cfg->an_atim_duration, 1);
79655992Swpaul	printf("\nAP/ad-hoc current channel:\t\t");
79755992Swpaul	an_printwords(&cfg->an_ds_channel, 1);
79855992Swpaul	printf("\nAP/ad-hoc DTIM period:\t\t\t");
79955992Swpaul	an_printwords(&cfg->an_dtim_period, 1);
80055992Swpaul	printf("\nRadio type:\t\t\t\t[ ");
80155992Swpaul	if (cfg->an_radiotype & AN_RADIOTYPE_80211_FH)
80255992Swpaul		printf("802.11 FH");
80355992Swpaul	else if (cfg->an_radiotype & AN_RADIOTYPE_80211_DS)
80455992Swpaul		printf("802.11 DS");
80555992Swpaul	else if (cfg->an_radiotype & AN_RADIOTYPE_LM2000_DS)
80655992Swpaul		printf("LM2000 DS");
80755992Swpaul	else
80855992Swpaul		printf("unknown (%x)", cfg->an_radiotype);
80955992Swpaul	printf(" ]");
81055992Swpaul	printf("\nRX Diversity:\t\t\t\t[ ");
81180454Sbrooks	diversity = cfg->an_diversity & 0xFF;
812108401Sambrisko	if (diversity == AN_DIVERSITY_FACTORY_DEFAULT)
813108401Sambrisko		printf("factory default");
814108401Sambrisko	else if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
81555992Swpaul		printf("antenna 1 only");
81680454Sbrooks	else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
81755992Swpaul		printf("antenna 2 only");
81880454Sbrooks	else if (diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
81955992Swpaul		printf("antenna 1 and 2");
82055992Swpaul	printf(" ]");
82155992Swpaul	printf("\nTX Diversity:\t\t\t\t[ ");
82280454Sbrooks	diversity = (cfg->an_diversity >> 8) & 0xFF;
823108401Sambrisko	if (diversity == AN_DIVERSITY_FACTORY_DEFAULT)
824108401Sambrisko		printf("factory default");
825108401Sambrisko	else if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
82655992Swpaul		printf("antenna 1 only");
82780454Sbrooks	else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
82855992Swpaul		printf("antenna 2 only");
82980454Sbrooks	else if (diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
83055992Swpaul		printf("antenna 1 and 2");
83155992Swpaul	printf(" ]");
83255992Swpaul	printf("\nTransmit power level:\t\t\t");
83355992Swpaul	an_printwords(&cfg->an_tx_power, 1);
83455992Swpaul	printf("\nRSS threshold:\t\t\t\t");
83555992Swpaul	an_printwords(&cfg->an_rss_thresh, 1);
83655992Swpaul	printf("\nNode name:\t\t\t\t");
83755992Swpaul	an_printstr((char *)&cfg->an_nodename, 16);
83855992Swpaul	printf("\nARL threshold:\t\t\t\t");
83955992Swpaul	an_printwords(&cfg->an_arl_thresh, 1);
84055992Swpaul	printf("\nARL decay:\t\t\t\t");
84155992Swpaul	an_printwords(&cfg->an_arl_decay, 1);
84255992Swpaul	printf("\nARL delay:\t\t\t\t");
84355992Swpaul	an_printwords(&cfg->an_arl_delay, 1);
84488748Sambrisko	printf("\nConfiguration:\t\t\t\t[ ");
84588748Sambrisko	if (cfg->an_home_product & AN_HOME_NETWORK)
84688748Sambrisko		printf("Home Configuration");
84788748Sambrisko	else
84888748Sambrisko		printf("Enterprise Configuration");
84988748Sambrisko	printf(" ]");
85055992Swpaul
85155992Swpaul	printf("\n");
85269772Sarchie	printf("\n");
85369772Sarchie	an_readkeyinfo(iface);
85455992Swpaul}
85555992Swpaul
856132860Snjlstatic void
857132860Snjlan_dumprssimap(const char *iface)
858108401Sambrisko{
859108401Sambrisko	struct an_ltv_rssi_map	*rssi;
860108401Sambrisko	struct an_req		areq;
861108401Sambrisko	int                     i;
86255992Swpaul
863108401Sambrisko	areq.an_len = sizeof(areq);
864108401Sambrisko	areq.an_type = AN_RID_RSSI_MAP;
865108401Sambrisko
866108401Sambrisko	an_getval(iface, &areq);
867108401Sambrisko
868108401Sambrisko	rssi = (struct an_ltv_rssi_map *)&areq;
869108401Sambrisko
870108401Sambrisko	printf("idx\tpct\t dBm\n");
871108401Sambrisko
872108401Sambrisko	for (i = 0; i < 0xFF; i++) {
873108401Sambrisko		/*
874108401Sambrisko		 * negate the dBm value: it's the only way the power
875108401Sambrisko		 * level makes sense
876108401Sambrisko		 */
877108401Sambrisko		printf("%3d\t%3d\t%4d\n", i,
878108401Sambrisko			rssi->an_entries[i].an_rss_pct,
879108401Sambrisko			- rssi->an_entries[i].an_rss_dbm);
880108401Sambrisko	}
881108401Sambrisko}
882108401Sambrisko
883132860Snjlstatic void
884132860Snjlusage(const char *p)
88555992Swpaul{
88655992Swpaul	fprintf(stderr, "usage:  %s -i iface -A (show specified APs)\n", p);
88755992Swpaul	fprintf(stderr, "\t%s -i iface -N (show specified SSIDss)\n", p);
88855992Swpaul	fprintf(stderr, "\t%s -i iface -S (show NIC status)\n", p);
88955992Swpaul	fprintf(stderr, "\t%s -i iface -I (show NIC capabilities)\n", p);
89055992Swpaul	fprintf(stderr, "\t%s -i iface -T (show stats counters)\n", p);
89155992Swpaul	fprintf(stderr, "\t%s -i iface -C (show current config)\n", p);
892108401Sambrisko	fprintf(stderr, "\t%s -i iface -R (show RSSI map)\n", p);
89389380Sambrisko	fprintf(stderr, "\t%s -i iface -t 0-4 (set TX speed)\n", p);
89489380Sambrisko	fprintf(stderr, "\t%s -i iface -s 0-3 (set power save mode)\n", p);
89589380Sambrisko	fprintf(stderr, "\t%s -i iface [-v 1-4] -a AP (specify AP)\n", p);
89655992Swpaul	fprintf(stderr, "\t%s -i iface -b val (set beacon period)\n", p);
89755992Swpaul	fprintf(stderr, "\t%s -i iface [-v 0|1] -d val (set diversity)\n", p);
89855992Swpaul	fprintf(stderr, "\t%s -i iface -j val (set netjoin timeout)\n", p);
89989380Sambrisko	fprintf(stderr, "\t%s -i iface -e 0-4 (enable transmit key)\n", p);
90089380Sambrisko	fprintf(stderr, "\t%s -i iface [-v 0-8] -k key (set key)\n", p);
90189380Sambrisko	fprintf(stderr, "\t%s -i iface -K 0-2 (no auth/open/shared secret)\n", p);
90289380Sambrisko	fprintf(stderr, "\t%s -i iface -W 0-2 (no WEP/full WEP/mixed cell)\n", p);
90355992Swpaul	fprintf(stderr, "\t%s -i iface -l val (set station name)\n", p);
90455992Swpaul	fprintf(stderr, "\t%s -i iface -m val (set MAC address)\n", p);
90589380Sambrisko	fprintf(stderr, "\t%s -i iface [-v 1-3] -n SSID "
90655992Swpaul	    "(specify SSID)\n", p);
90755992Swpaul	fprintf(stderr, "\t%s -i iface -o 0|1 (set operating mode)\n", p);
90855992Swpaul	fprintf(stderr, "\t%s -i iface -c val (set ad-hoc channel)\n", p);
90955992Swpaul	fprintf(stderr, "\t%s -i iface -f val (set frag threshold)\n", p);
91055992Swpaul	fprintf(stderr, "\t%s -i iface -r val (set RTS threshold)\n", p);
91183269Sbrooks	fprintf(stderr, "\t%s -i iface -M 0-15 (set monitor mode)\n", p);
91288748Sambrisko	fprintf(stderr, "\t%s -i iface -L user (enter LEAP authentication mode)\n", p);
91355992Swpaul#ifdef ANCACHE
91455992Swpaul	fprintf(stderr, "\t%s -i iface -Q print signal quality cache\n", p);
91555992Swpaul	fprintf(stderr, "\t%s -i iface -Z zero out signal cache\n", p);
91655992Swpaul#endif
91755992Swpaul
91855992Swpaul	fprintf(stderr, "\t%s -h (display this message)\n", p);
91955992Swpaul
92055992Swpaul	exit(1);
92155992Swpaul}
92255992Swpaul
923132860Snjlstatic void
924132860Snjlan_setconfig(const char *iface, int act, void *arg)
92555992Swpaul{
92655992Swpaul	struct an_ltv_genconfig	*cfg;
92755992Swpaul	struct an_ltv_caps	*caps;
92855992Swpaul	struct an_req		areq;
92955992Swpaul	struct an_req		areq_caps;
93055992Swpaul	u_int16_t		diversity = 0;
93155992Swpaul	struct ether_addr	*addr;
93255992Swpaul	int			i;
93355992Swpaul
93455992Swpaul	areq.an_len = sizeof(areq);
93555992Swpaul	areq.an_type = AN_RID_GENCONFIG;
93655992Swpaul	an_getval(iface, &areq);
93755992Swpaul	cfg = (struct an_ltv_genconfig *)&areq;
93855992Swpaul
93955992Swpaul	areq_caps.an_len = sizeof(areq);
94055992Swpaul	areq_caps.an_type = AN_RID_CAPABILITIES;
94155992Swpaul	an_getval(iface, &areq_caps);
94255992Swpaul	caps = (struct an_ltv_caps *)&areq_caps;
94355992Swpaul
94455992Swpaul	switch(act) {
94555992Swpaul	case ACT_SET_OPMODE:
94655992Swpaul		cfg->an_opmode = atoi(arg);
94755992Swpaul		break;
94855992Swpaul	case ACT_SET_FREQ:
94955992Swpaul		cfg->an_ds_channel = atoi(arg);
95055992Swpaul		break;
95155992Swpaul	case ACT_SET_PWRSAVE:
95255992Swpaul		cfg->an_psave_mode = atoi(arg);
95355992Swpaul		break;
95455992Swpaul	case ACT_SET_SCANMODE:
95555992Swpaul		cfg->an_scanmode = atoi(arg);
95655992Swpaul		break;
95755992Swpaul	case ACT_SET_DIVERSITY_RX:
95855992Swpaul	case ACT_SET_DIVERSITY_TX:
95955992Swpaul		switch(atoi(arg)) {
96055992Swpaul		case 0:
96155992Swpaul			diversity = AN_DIVERSITY_FACTORY_DEFAULT;
96255992Swpaul			break;
96355992Swpaul		case 1:
96455992Swpaul			diversity = AN_DIVERSITY_ANTENNA_1_ONLY;
96555992Swpaul			break;
96655992Swpaul		case 2:
96755992Swpaul			diversity = AN_DIVERSITY_ANTENNA_2_ONLY;
96855992Swpaul			break;
96955992Swpaul		case 3:
97055992Swpaul			diversity = AN_DIVERSITY_ANTENNA_1_AND_2;
97155992Swpaul			break;
97255992Swpaul		default:
973132860Snjl			errx(1, "bad diversity setting: %u", diversity);
97455992Swpaul			break;
97555992Swpaul		}
976108401Sambrisko		if (act == ACT_SET_DIVERSITY_RX) {
977108401Sambrisko			cfg->an_diversity &= 0xFF00;
978108401Sambrisko			cfg->an_diversity |= diversity;
979108401Sambrisko		} else {
98055992Swpaul			cfg->an_diversity &= 0x00FF;
98155992Swpaul			cfg->an_diversity |= (diversity << 8);
98255992Swpaul		}
98355992Swpaul		break;
98455992Swpaul	case ACT_SET_TXPWR:
98555992Swpaul		for (i = 0; i < 8; i++) {
98655992Swpaul			if (caps->an_tx_powerlevels[i] == atoi(arg))
98755992Swpaul				break;
98855992Swpaul		}
98955992Swpaul		if (i == 8)
99055992Swpaul			errx(1, "unsupported power level: %dmW", atoi(arg));
99155992Swpaul
99255992Swpaul		cfg->an_tx_power = atoi(arg);
99355992Swpaul		break;
99455992Swpaul	case ACT_SET_RTS_THRESH:
99555992Swpaul		cfg->an_rtsthresh = atoi(arg);
99655992Swpaul		break;
99755992Swpaul	case ACT_SET_RTS_RETRYLIM:
99855992Swpaul		cfg->an_shortretry_limit =
99955992Swpaul		   cfg->an_longretry_limit = atoi(arg);
100055992Swpaul		break;
100155992Swpaul	case ACT_SET_BEACON_PERIOD:
100255992Swpaul		cfg->an_beacon_period = atoi(arg);
100355992Swpaul		break;
100455992Swpaul	case ACT_SET_WAKE_DURATION:
100555992Swpaul		cfg->an_atim_duration = atoi(arg);
100655992Swpaul		break;
100755992Swpaul	case ACT_SET_FRAG_THRESH:
100855992Swpaul		cfg->an_fragthresh = atoi(arg);
100955992Swpaul		break;
101055992Swpaul	case ACT_SET_NETJOIN:
101155992Swpaul		cfg->an_ibss_join_net_timeout = atoi(arg);
101255992Swpaul		break;
101355992Swpaul	case ACT_SET_MYNAME:
101455992Swpaul		bzero(cfg->an_nodename, 16);
101555992Swpaul		strncpy((char *)&cfg->an_nodename, optarg, 16);
101655992Swpaul		break;
101755992Swpaul	case ACT_SET_MAC:
101855992Swpaul		addr = ether_aton((char *)arg);
101955992Swpaul
102055992Swpaul		if (addr == NULL)
102155992Swpaul			errx(1, "badly formatted address");
102255992Swpaul		bzero(cfg->an_macaddr, ETHER_ADDR_LEN);
1023132900Snjl		bcopy(addr, &cfg->an_macaddr, ETHER_ADDR_LEN);
102455992Swpaul		break;
102568692Swpaul	case ACT_ENABLE_WEP:
102669772Sarchie		switch (atoi (arg)) {
102769772Sarchie		case 0:
102869772Sarchie			/* no WEP */
102969772Sarchie			cfg->an_authtype &= ~(AN_AUTHTYPE_PRIVACY_IN_USE
103088748Sambrisko					| AN_AUTHTYPE_ALLOW_UNENCRYPTED
103188748Sambrisko					| AN_AUTHTYPE_LEAP);
103269772Sarchie			break;
103369772Sarchie		case 1:
103469772Sarchie			/* full WEP */
103569772Sarchie			cfg->an_authtype |= AN_AUTHTYPE_PRIVACY_IN_USE;
103669772Sarchie			cfg->an_authtype &= ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
103788748Sambrisko			cfg->an_authtype &= ~AN_AUTHTYPE_LEAP;
103869772Sarchie			break;
103969772Sarchie		case 2:
104069772Sarchie			/* mixed cell */
104169772Sarchie			cfg->an_authtype = AN_AUTHTYPE_PRIVACY_IN_USE
104269772Sarchie					| AN_AUTHTYPE_ALLOW_UNENCRYPTED;
104369772Sarchie			break;
104469772Sarchie		}
104568692Swpaul		break;
104668692Swpaul	case ACT_SET_KEY_TYPE:
104768692Swpaul		cfg->an_authtype = (cfg->an_authtype & ~AN_AUTHTYPE_MASK)
104868692Swpaul		        | atoi(arg);
104968692Swpaul		break;
105083269Sbrooks	case ACT_SET_MONITOR_MODE:
105183269Sbrooks		areq.an_type = AN_RID_MONITOR_MODE;
105283269Sbrooks		cfg->an_len = atoi(arg);      /* mode is put in length */
105383269Sbrooks		break;
105455992Swpaul	default:
105555992Swpaul		errx(1, "unknown action");
105655992Swpaul		break;
105755992Swpaul	}
105855992Swpaul
105955992Swpaul	an_setval(iface, &areq);
106055992Swpaul	exit(0);
106155992Swpaul}
106255992Swpaul
1063132860Snjlstatic void
1064132860Snjlan_setspeed(const char *iface, int act __unused, void *arg)
106555992Swpaul{
106655992Swpaul	struct an_req		areq;
106755992Swpaul	struct an_ltv_caps	*caps;
106855992Swpaul	u_int16_t		speed;
106955992Swpaul
107055992Swpaul	areq.an_len = sizeof(areq);
107155992Swpaul	areq.an_type = AN_RID_CAPABILITIES;
107255992Swpaul
107355992Swpaul	an_getval(iface, &areq);
107455992Swpaul	caps = (struct an_ltv_caps *)&areq;
107555992Swpaul
107655992Swpaul	switch(atoi(arg)) {
107755992Swpaul	case 0:
107855992Swpaul		speed = 0;
107955992Swpaul		break;
108055992Swpaul	case 1:
108155992Swpaul		speed = AN_RATE_1MBPS;
108255992Swpaul		break;
108355992Swpaul	case 2:
108455992Swpaul		speed = AN_RATE_2MBPS;
108555992Swpaul		break;
108655992Swpaul	case 3:
108755992Swpaul		if (caps->an_rates[2] != AN_RATE_5_5MBPS)
108855992Swpaul			errx(1, "5.5Mbps not supported on this card");
108955992Swpaul		speed = AN_RATE_5_5MBPS;
109055992Swpaul		break;
109155992Swpaul	case 4:
109255992Swpaul		if (caps->an_rates[3] != AN_RATE_11MBPS)
109355992Swpaul			errx(1, "11Mbps not supported on this card");
109455992Swpaul		speed = AN_RATE_11MBPS;
109555992Swpaul		break;
109655992Swpaul	default:
109755992Swpaul		errx(1, "unsupported speed");
109855992Swpaul		break;
109955992Swpaul	}
110055992Swpaul
110155992Swpaul	areq.an_len = 6;
110255992Swpaul	areq.an_type = AN_RID_TX_SPEED;
110355992Swpaul	areq.an_val[0] = speed;
110455992Swpaul
110555992Swpaul	an_setval(iface, &areq);
110655992Swpaul	exit(0);
110755992Swpaul}
110855992Swpaul
1109132860Snjlstatic void
1110132860Snjlan_setap(const char *iface, int act, void *arg)
111155992Swpaul{
111255992Swpaul	struct an_ltv_aplist	*ap;
111355992Swpaul	struct an_req		areq;
111455992Swpaul	struct ether_addr	*addr;
111555992Swpaul
111655992Swpaul	areq.an_len = sizeof(areq);
111755992Swpaul	areq.an_type = AN_RID_APLIST;
111855992Swpaul
111955992Swpaul	an_getval(iface, &areq);
112055992Swpaul	ap = (struct an_ltv_aplist *)&areq;
112155992Swpaul
112255992Swpaul	addr = ether_aton((char *)arg);
112355992Swpaul
112455992Swpaul	if (addr == NULL)
112555992Swpaul		errx(1, "badly formatted address");
112655992Swpaul
112755992Swpaul	switch(act) {
112855992Swpaul	case ACT_SET_AP1:
112955992Swpaul		bzero(ap->an_ap1, ETHER_ADDR_LEN);
1130132900Snjl		bcopy(addr, &ap->an_ap1, ETHER_ADDR_LEN);
113155992Swpaul		break;
113255992Swpaul	case ACT_SET_AP2:
113355992Swpaul		bzero(ap->an_ap2, ETHER_ADDR_LEN);
1134132900Snjl		bcopy(addr, &ap->an_ap2, ETHER_ADDR_LEN);
113555992Swpaul		break;
113655992Swpaul	case ACT_SET_AP3:
113755992Swpaul		bzero(ap->an_ap3, ETHER_ADDR_LEN);
1138132900Snjl		bcopy(addr, &ap->an_ap3, ETHER_ADDR_LEN);
113955992Swpaul		break;
114055992Swpaul	case ACT_SET_AP4:
114155992Swpaul		bzero(ap->an_ap4, ETHER_ADDR_LEN);
1142132900Snjl		bcopy(addr, &ap->an_ap4, ETHER_ADDR_LEN);
114355992Swpaul		break;
114455992Swpaul	default:
114555992Swpaul		errx(1, "unknown action");
114655992Swpaul		break;
114755992Swpaul	}
114855992Swpaul
114955992Swpaul	an_setval(iface, &areq);
115055992Swpaul	exit(0);
115155992Swpaul}
115255992Swpaul
1153132860Snjlstatic void
1154132860Snjlan_setssid(const char *iface, int act, void *arg)
115555992Swpaul{
1156119156Sambrisko	struct an_ltv_ssidlist_new	*ssid;
115755992Swpaul	struct an_req		areq;
1158119156Sambrisko	int			max;
115955992Swpaul
116055992Swpaul	areq.an_len = sizeof(areq);
116155992Swpaul	areq.an_type = AN_RID_SSIDLIST;
116255992Swpaul
116355992Swpaul	an_getval(iface, &areq);
1164119156Sambrisko	ssid = (struct an_ltv_ssidlist_new *)&areq;
116555992Swpaul
1166119156Sambrisko	max = (areq.an_len - 4) / sizeof(struct an_ltv_ssid_entry);
1167119156Sambrisko	if ( max > MAX_SSIDS ) {
1168132860Snjl		printf("Too many SSIDs only printing %d of %d\n",
1169119156Sambrisko		    MAX_SSIDS, max);
1170119156Sambrisko		max = MAX_SSIDS;
117155992Swpaul	}
117255992Swpaul
1173119156Sambrisko	if ( act > max ) {
1174119156Sambrisko		errx(1, "bad modifier %d: there "
1175119156Sambrisko		    "are only %d SSID settings", act, max);
1176119156Sambrisko		exit(1);
1177119156Sambrisko	}
1178119156Sambrisko
1179119156Sambrisko	bzero(ssid->an_entry[act-1].an_ssid,
1180119156Sambrisko	    sizeof(ssid->an_entry[act-1].an_ssid));
1181119156Sambrisko	strlcpy(ssid->an_entry[act-1].an_ssid, (char *)arg,
1182119156Sambrisko	    sizeof(ssid->an_entry[act-1].an_ssid));
1183119156Sambrisko	ssid->an_entry[act-1].an_len
1184119156Sambrisko	    = strlen(ssid->an_entry[act-1].an_ssid);
1185119156Sambrisko
118655992Swpaul	an_setval(iface, &areq);
1187119156Sambrisko
118855992Swpaul	exit(0);
118955992Swpaul}
119055992Swpaul
119155992Swpaul#ifdef ANCACHE
1192132860Snjlstatic void
1193132860Snjlan_zerocache(const char *iface)
119455992Swpaul{
119555992Swpaul	struct an_req		areq;
119655992Swpaul
1197132900Snjl	bzero(&areq, sizeof(areq));
119855992Swpaul	areq.an_len = 0;
119955992Swpaul	areq.an_type = AN_RID_ZERO_CACHE;
120055992Swpaul
120155992Swpaul	an_getval(iface, &areq);
120255992Swpaul}
120355992Swpaul
1204132860Snjlstatic void
1205132860Snjlan_readcache(const char *iface)
120655992Swpaul{
120755992Swpaul	struct an_req		areq;
1208132900Snjl	uint16_t 		*an_sigitems;
120955992Swpaul	struct an_sigcache 	*sc;
121055992Swpaul	int 			i;
121155992Swpaul
121255992Swpaul	if (iface == NULL)
121355992Swpaul		errx(1, "must specify interface name");
121455992Swpaul
1215132900Snjl	bzero(&areq, sizeof(areq));
121655992Swpaul	areq.an_len = AN_MAX_DATALEN;
121755992Swpaul	areq.an_type = AN_RID_READ_CACHE;
121855992Swpaul
121955992Swpaul	an_getval(iface, &areq);
122055992Swpaul
1221132900Snjl	an_sigitems = areq.an_val;
1222132900Snjl	sc = (struct an_sigcache *)((int32_t *)areq.an_val + 1);
122355992Swpaul
122455992Swpaul	for (i = 0; i < *an_sigitems; i++) {
122555992Swpaul		printf("[%d/%d]:", i+1, *an_sigitems);
122655992Swpaul		printf(" %02x:%02x:%02x:%02x:%02x:%02x,",
122755992Swpaul		  		    	sc->macsrc[0]&0xff,
122855992Swpaul		  		    	sc->macsrc[1]&0xff,
122955992Swpaul		   		    	sc->macsrc[2]&0xff,
123055992Swpaul		   			sc->macsrc[3]&0xff,
123155992Swpaul		   			sc->macsrc[4]&0xff,
123255992Swpaul		   			sc->macsrc[5]&0xff);
123355992Swpaul        	printf(" %d.%d.%d.%d,",((sc->ipsrc >> 0) & 0xff),
123455992Swpaul				        ((sc->ipsrc >> 8) & 0xff),
123555992Swpaul				        ((sc->ipsrc >> 16) & 0xff),
123655992Swpaul				        ((sc->ipsrc >> 24) & 0xff));
123755992Swpaul		printf(" sig: %d, noise: %d, qual: %d\n",
123855992Swpaul		   			sc->signal,
123955992Swpaul		   			sc->noise,
124055992Swpaul		   			sc->quality);
124155992Swpaul		sc++;
124255992Swpaul	}
124355992Swpaul}
124455992Swpaul#endif
124555992Swpaul
1246132860Snjlstatic int
1247132860Snjlan_hex2int(char c)
124868692Swpaul{
124968692Swpaul	if (c >= '0' && c <= '9')
125068692Swpaul		return (c - '0');
125168692Swpaul	if (c >= 'A' && c <= 'F')
125268692Swpaul		return (c - 'A' + 10);
125368692Swpaul	if (c >= 'a' && c <= 'f')
125468692Swpaul		return (c - 'a' + 10);
125555992Swpaul
125668692Swpaul	return (0);
125768692Swpaul}
125868692Swpaul
1259132860Snjlstatic void
1260132860Snjlan_str2key(const char *s, struct an_ltv_key *k)
126168692Swpaul{
126268692Swpaul	int			n, i;
126368692Swpaul	char			*p;
126468692Swpaul
126568692Swpaul	/* Is this a hex string? */
126668692Swpaul	if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
126768692Swpaul		/* Yes, convert to int. */
126868692Swpaul		n = 0;
126968692Swpaul		p = (char *)&k->key[0];
127080454Sbrooks		for (i = 2; s[i] != '\0' && s[i + 1] != '\0'; i+= 2) {
127168692Swpaul			*p++ = (an_hex2int(s[i]) << 4) + an_hex2int(s[i + 1]);
127268692Swpaul			n++;
127368692Swpaul		}
127480454Sbrooks		if (s[i] != '\0')
127580454Sbrooks			errx(1, "hex strings must be of even length");
127668692Swpaul		k->klen = n;
127768692Swpaul	} else {
127868692Swpaul		/* No, just copy it in. */
127968692Swpaul		bcopy(s, k->key, strlen(s));
128068692Swpaul		k->klen = strlen(s);
128168692Swpaul	}
128268692Swpaul
128368692Swpaul	return;
128468692Swpaul}
128568692Swpaul
1286132860Snjlstatic void
1287132860Snjlan_setkeys(const char *iface, const char *key, int keytype)
128868692Swpaul{
128968692Swpaul	struct an_req		areq;
129068692Swpaul	struct an_ltv_key	*k;
129168692Swpaul
1292132900Snjl	bzero(&areq, sizeof(areq));
129368692Swpaul	k = (struct an_ltv_key *)&areq;
129468692Swpaul
129568692Swpaul	if (strlen(key) > 28) {
129668692Swpaul		err(1, "encryption key must be no "
129768692Swpaul		    "more than 18 characters long");
129868692Swpaul	}
129968692Swpaul
130068692Swpaul	an_str2key(key, k);
130168692Swpaul
130268692Swpaul	k->kindex=keytype/2;
130368692Swpaul
130468692Swpaul	if (!(k->klen==0 || k->klen==5 || k->klen==13)) {
130568692Swpaul		err(1, "encryption key must be 0, 5 or 13 bytes long");
130668692Swpaul	}
130768692Swpaul
130868692Swpaul	/* default mac and only valid one (from manual) 1.0.0.0.0.0 */
130968692Swpaul	k->mac[0]=1;
131068692Swpaul	k->mac[1]=0;
131168692Swpaul	k->mac[2]=0;
131268692Swpaul	k->mac[3]=0;
131368692Swpaul	k->mac[4]=0;
131468692Swpaul	k->mac[5]=0;
131568692Swpaul
131688748Sambrisko	switch(keytype & 1) {
131768692Swpaul	case 0:
131868692Swpaul	  areq.an_len = sizeof(struct an_ltv_key);
131968692Swpaul	  areq.an_type = AN_RID_WEP_PERM;
132068692Swpaul	  an_setval(iface, &areq);
132168692Swpaul	  break;
132268692Swpaul	case 1:
132368692Swpaul	  areq.an_len = sizeof(struct an_ltv_key);
132468692Swpaul	  areq.an_type = AN_RID_WEP_TEMP;
132568692Swpaul	  an_setval(iface, &areq);
132668692Swpaul	  break;
132768692Swpaul	}
132868692Swpaul}
132968692Swpaul
1330201387Sedstatic void
1331201387Sedan_readkeyinfo(const char *iface)
133269772Sarchie{
133369772Sarchie	struct an_req		areq;
133489380Sambrisko	struct an_ltv_genconfig	*cfg;
133569772Sarchie	struct an_ltv_key	*k;
133669772Sarchie	int i;
133789380Sambrisko	int home;
133869772Sarchie
133989380Sambrisko	areq.an_len = sizeof(areq);
134089380Sambrisko	areq.an_type = AN_RID_ACTUALCFG;
134189380Sambrisko	an_getval(iface, &areq);
134289380Sambrisko	cfg = (struct an_ltv_genconfig *)&areq;
134389380Sambrisko	if (cfg->an_home_product & AN_HOME_NETWORK)
134489380Sambrisko		home = 1;
134589380Sambrisko	else
134689380Sambrisko		home = 0;
134789380Sambrisko
1348132900Snjl	bzero(&areq, sizeof(areq));
134969772Sarchie	k = (struct an_ltv_key *)&areq;
135069772Sarchie
135169772Sarchie	printf("WEP Key status:\n");
135269772Sarchie	areq.an_type = AN_RID_WEP_TEMP;  	/* read first key */
135388748Sambrisko	for(i=0; i<5; i++) {
135469772Sarchie		areq.an_len = sizeof(struct an_ltv_key);
135569772Sarchie		an_getval(iface, &areq);
135688748Sambrisko       		if (k->kindex == 0xffff)
135783269Sbrooks			break;
135888748Sambrisko		switch (k->klen) {
135969772Sarchie		case 0:
1360132860Snjl			printf("\tKey %u is unset\n", k->kindex);
136169772Sarchie			break;
136269772Sarchie		case 5:
1363132860Snjl			printf("\tKey %u is set  40 bits\n", k->kindex);
136469772Sarchie			break;
136569772Sarchie		case 13:
1366132860Snjl			printf("\tKey %u is set 128 bits\n", k->kindex);
136769772Sarchie			break;
136869772Sarchie		default:
1369132860Snjl			printf("\tWEP Key %d has an unknown size %u\n",
137069772Sarchie			    i, k->klen);
137169772Sarchie		}
137269772Sarchie
137369772Sarchie		areq.an_type = AN_RID_WEP_PERM;	/* read next key */
137469772Sarchie	}
137569772Sarchie	k->kindex = 0xffff;
137669772Sarchie	areq.an_len = sizeof(struct an_ltv_key);
137769772Sarchie      	an_getval(iface, &areq);
137889380Sambrisko	printf("\tThe active transmit key is %d\n", 4 * home + k->mac[0]);
137969772Sarchie
138069772Sarchie	return;
138169772Sarchie}
138269772Sarchie
1383132860Snjlstatic void
1384132860Snjlan_enable_tx_key(const char *iface, const char *arg)
138569772Sarchie{
138669772Sarchie	struct an_req		areq;
138769772Sarchie	struct an_ltv_key	*k;
138888748Sambrisko	struct an_ltv_genconfig *config;
138969772Sarchie
1390132900Snjl	bzero(&areq, sizeof(areq));
139188748Sambrisko
139288748Sambrisko	/* set home or not home mode */
139388748Sambrisko	areq.an_len  = sizeof(struct an_ltv_genconfig);
139488748Sambrisko	areq.an_type = AN_RID_GENCONFIG;
139588748Sambrisko	an_getval(iface, &areq);
139688748Sambrisko	config = (struct an_ltv_genconfig *)&areq;
139788748Sambrisko	if (atoi(arg) == 4) {
139888748Sambrisko		config->an_home_product |= AN_HOME_NETWORK;
139988748Sambrisko	}else{
140088748Sambrisko		config->an_home_product &= ~AN_HOME_NETWORK;
140188748Sambrisko	}
140288748Sambrisko	an_setval(iface, &areq);
140388748Sambrisko
1404132900Snjl	bzero(&areq, sizeof(areq));
140588748Sambrisko
140669772Sarchie	k = (struct an_ltv_key *)&areq;
140769772Sarchie
140869772Sarchie	/* From a Cisco engineer write the transmit key to use in the
140969772Sarchie	   first MAC, index is FFFF*/
141069772Sarchie	k->kindex=0xffff;
141169772Sarchie	k->klen=0;
141269772Sarchie
141369772Sarchie	k->mac[0]=atoi(arg);
141469772Sarchie	k->mac[1]=0;
141569772Sarchie	k->mac[2]=0;
141669772Sarchie	k->mac[3]=0;
141769772Sarchie	k->mac[4]=0;
141869772Sarchie	k->mac[5]=0;
141969772Sarchie
142069772Sarchie	areq.an_len = sizeof(struct an_ltv_key);
142169772Sarchie	areq.an_type = AN_RID_WEP_PERM;
142269772Sarchie	an_setval(iface, &areq);
142369772Sarchie}
142469772Sarchie
1425132860Snjlstatic void
1426132860Snjlan_enable_leap_mode(const char *iface, const char *username)
142788748Sambrisko{
142888748Sambrisko	struct an_req		areq;
142988748Sambrisko	struct an_ltv_status	*sts;
143088748Sambrisko	struct an_ltv_genconfig	*cfg;
143188748Sambrisko	struct an_ltv_caps	*caps;
143288748Sambrisko	struct an_ltv_leap_username an_username;
143388748Sambrisko	struct an_ltv_leap_password an_password;
143488748Sambrisko	char *password;
143588748Sambrisko	MD4_CTX context;
143688748Sambrisko	int len;
143788748Sambrisko	int i;
143888748Sambrisko	char unicode_password[LEAP_PASSWORD_MAX * 2];
143988748Sambrisko
144088748Sambrisko	areq.an_len = sizeof(areq);
144188748Sambrisko	areq.an_type = AN_RID_CAPABILITIES;
144288748Sambrisko
144388748Sambrisko	an_getval(iface, &areq);
144488748Sambrisko
144588748Sambrisko	caps = (struct an_ltv_caps *)&areq;
144688748Sambrisko
144788748Sambrisko	if (!caps->an_softcaps & AN_AUTHTYPE_LEAP) {
144888748Sambrisko		fprintf(stderr, "Firmware does not support LEAP\n");
144988748Sambrisko		exit(1);
145088748Sambrisko	}
145188748Sambrisko
145288748Sambrisko	bzero(&an_username, sizeof(an_username));
145388748Sambrisko	bzero(&an_password, sizeof(an_password));
145488748Sambrisko
145588748Sambrisko	len = strlen(username);
145688748Sambrisko	if (len > LEAP_USERNAME_MAX) {
145788748Sambrisko		printf("Username too long (max %d)\n", LEAP_USERNAME_MAX);
145888748Sambrisko		exit(1);
145988748Sambrisko	}
146088748Sambrisko	strncpy(an_username.an_username, username, len);
146188748Sambrisko	an_username.an_username_len = len;
146288748Sambrisko	an_username.an_len  = sizeof(an_username);
146388748Sambrisko	an_username.an_type = AN_RID_LEAPUSERNAME;
146488748Sambrisko
146588748Sambrisko	password = getpass("Enter LEAP password:");
146688748Sambrisko
146788748Sambrisko	len = strlen(password);
146888748Sambrisko	if (len > LEAP_PASSWORD_MAX) {
146988748Sambrisko		printf("Password too long (max %d)\n", LEAP_PASSWORD_MAX);
147088748Sambrisko		exit(1);
147188748Sambrisko	}
147288748Sambrisko
147388748Sambrisko	bzero(&unicode_password, sizeof(unicode_password));
147488748Sambrisko	for(i = 0; i < len; i++) {
147588748Sambrisko		unicode_password[i * 2] = *password++;
147688748Sambrisko	}
147788748Sambrisko
147888748Sambrisko	/* First half */
147988748Sambrisko	MD4Init(&context);
148088748Sambrisko	MD4Update(&context, unicode_password, len * 2);
148188748Sambrisko	MD4Final(&an_password.an_password[0], &context);
148288748Sambrisko
148388748Sambrisko	/* Second half */
148488748Sambrisko	MD4Init (&context);
148588748Sambrisko	MD4Update (&context, &an_password.an_password[0], 16);
148688748Sambrisko	MD4Final (&an_password.an_password[16], &context);
148788748Sambrisko
148888748Sambrisko	an_password.an_password_len = 32;
148988748Sambrisko	an_password.an_len  = sizeof(an_password);
149088748Sambrisko	an_password.an_type = AN_RID_LEAPPASSWORD;
149188748Sambrisko
149288748Sambrisko	an_setval(iface, (struct an_req *)&an_username);
149388748Sambrisko	an_setval(iface, (struct an_req *)&an_password);
149488748Sambrisko
149588748Sambrisko	areq.an_len = sizeof(areq);
149688748Sambrisko	areq.an_type = AN_RID_GENCONFIG;
149788748Sambrisko	an_getval(iface, &areq);
149888748Sambrisko	cfg = (struct an_ltv_genconfig *)&areq;
149988748Sambrisko	cfg->an_authtype = (AN_AUTHTYPE_PRIVACY_IN_USE | AN_AUTHTYPE_LEAP);
150088748Sambrisko	an_setval(iface, &areq);
150188748Sambrisko
150288748Sambrisko	sts = (struct an_ltv_status *)&areq;
150388748Sambrisko	areq.an_type = AN_RID_STATUS;
150488748Sambrisko
150588748Sambrisko	for (i = 60; i > 0; i--) {
150688748Sambrisko		an_getval(iface, &areq);
150788748Sambrisko		if (sts->an_opmode & AN_STATUS_OPMODE_LEAP) {
150888748Sambrisko			printf("Authenticated\n");
150988748Sambrisko			break;
151088748Sambrisko		}
151188748Sambrisko		sleep(1);
151288748Sambrisko	}
151388748Sambrisko
151488748Sambrisko	if (i == 0) {
151588748Sambrisko		fprintf(stderr, "Failed LEAP authentication\n");
151688748Sambrisko		exit(1);
151788748Sambrisko	}
151888748Sambrisko}
151988748Sambrisko
1520132860Snjlint
1521132860Snjlmain(int argc, char *argv[])
152255992Swpaul{
152355992Swpaul	int			ch;
152455992Swpaul	int			act = 0;
152580454Sbrooks	const char		*iface = NULL;
152655992Swpaul	int			modifier = 0;
152768692Swpaul	char			*key = NULL;
152855992Swpaul	void			*arg = NULL;
152955992Swpaul	char			*p = argv[0];
153055992Swpaul
153167823Sjoe	/* Get the interface name */
153267823Sjoe	opterr = 0;
153367823Sjoe	ch = getopt(argc, argv, "i:");
153467823Sjoe	if (ch == 'i') {
153567823Sjoe		iface = optarg;
153667823Sjoe	} else {
153770532Simp		if (argc > 1 && *argv[1] != '-') {
153870532Simp			iface = argv[1];
153970532Simp			optind = 2;
154070532Simp		} else {
154170532Simp			iface = "an0";
154270532Simp			optind = 1;
154370532Simp		}
154467823Sjoe		optreset = 1;
154567823Sjoe	}
154667823Sjoe	opterr = 1;
154767823Sjoe
154855992Swpaul	while ((ch = getopt(argc, argv,
1549137169Sceri	    "ANISCTRht:a:e:o:s:n:v:d:j:b:c:f:r:p:w:m:l:k:K:W:QZM:L:")) != -1) {
155055992Swpaul		switch(ch) {
155155992Swpaul		case 'Z':
155255992Swpaul#ifdef ANCACHE
155355992Swpaul			act = ACT_ZEROCACHE;
155455992Swpaul#else
155555992Swpaul			errx(1, "ANCACHE not available");
155655992Swpaul#endif
155755992Swpaul			break;
155855992Swpaul		case 'Q':
155955992Swpaul#ifdef ANCACHE
156055992Swpaul			act = ACT_DUMPCACHE;
156155992Swpaul#else
156255992Swpaul			errx(1, "ANCACHE not available");
156355992Swpaul#endif
156455992Swpaul			break;
156555992Swpaul		case 'A':
156655992Swpaul			act = ACT_DUMPAP;
156755992Swpaul			break;
156855992Swpaul		case 'N':
156955992Swpaul			act = ACT_DUMPSSID;
157055992Swpaul			break;
157155992Swpaul		case 'S':
157255992Swpaul			act = ACT_DUMPSTATUS;
157355992Swpaul			break;
157455992Swpaul		case 'I':
157555992Swpaul			act = ACT_DUMPCAPS;
157655992Swpaul			break;
157755992Swpaul		case 'T':
157855992Swpaul			act = ACT_DUMPSTATS;
157955992Swpaul			break;
158055992Swpaul		case 'C':
158155992Swpaul			act = ACT_DUMPCONFIG;
158255992Swpaul			break;
1583108401Sambrisko		case 'R':
1584108401Sambrisko			act = ACT_DUMPRSSIMAP;
1585108401Sambrisko			break;
158655992Swpaul		case 't':
158755992Swpaul			act = ACT_SET_TXRATE;
158855992Swpaul			arg = optarg;
158955992Swpaul			break;
159055992Swpaul		case 's':
159155992Swpaul			act = ACT_SET_PWRSAVE;
159255992Swpaul			arg = optarg;
159355992Swpaul			break;
159455992Swpaul		case 'p':
159555992Swpaul			act = ACT_SET_TXPWR;
159655992Swpaul			arg = optarg;
159755992Swpaul			break;
159855992Swpaul		case 'v':
159955992Swpaul			modifier = atoi(optarg);
160055992Swpaul			break;
160155992Swpaul		case 'a':
160255992Swpaul			switch(modifier) {
160355992Swpaul			case 0:
160455992Swpaul			case 1:
160555992Swpaul				act = ACT_SET_AP1;
160655992Swpaul				break;
160755992Swpaul			case 2:
160855992Swpaul				act = ACT_SET_AP2;
160955992Swpaul				break;
161055992Swpaul			case 3:
161155992Swpaul				act = ACT_SET_AP3;
161255992Swpaul				break;
161355992Swpaul			case 4:
161455992Swpaul				act = ACT_SET_AP4;
161555992Swpaul				break;
161655992Swpaul			default:
161755992Swpaul				errx(1, "bad modifier %d: there "
161855992Swpaul				    "are only 4 access point settings",
161955992Swpaul				    modifier);
162055992Swpaul				usage(p);
162155992Swpaul				break;
162255992Swpaul			}
162355992Swpaul			arg = optarg;
162455992Swpaul			break;
162555992Swpaul		case 'b':
162655992Swpaul			act = ACT_SET_BEACON_PERIOD;
162755992Swpaul			arg = optarg;
162855992Swpaul			break;
162955992Swpaul		case 'd':
163055992Swpaul			switch(modifier) {
163155992Swpaul			case 0:
163255992Swpaul				act = ACT_SET_DIVERSITY_RX;
163355992Swpaul				break;
163455992Swpaul			case 1:
163555992Swpaul				act = ACT_SET_DIVERSITY_TX;
163655992Swpaul				break;
163755992Swpaul			default:
1638108401Sambrisko				errx(1, "must specify RX or TX diversity");
163955992Swpaul				break;
164055992Swpaul			}
1641108401Sambrisko			if (!isdigit(*optarg)) {
1642108401Sambrisko				errx(1, "%s is not numeric", optarg);
1643108401Sambrisko				exit(1);
1644108401Sambrisko			}
164555992Swpaul			arg = optarg;
164655992Swpaul			break;
164755992Swpaul		case 'j':
164855992Swpaul			act = ACT_SET_NETJOIN;
164955992Swpaul			arg = optarg;
165055992Swpaul			break;
165155992Swpaul		case 'l':
165255992Swpaul			act = ACT_SET_MYNAME;
165355992Swpaul			arg = optarg;
165455992Swpaul			break;
165555992Swpaul		case 'm':
165655992Swpaul			act = ACT_SET_MAC;
165755992Swpaul			arg = optarg;
165855992Swpaul			break;
165955992Swpaul		case 'n':
1660119156Sambrisko			if (modifier == 0)
1661119156Sambrisko				modifier = 1;
1662119156Sambrisko			act = ACT_SET_SSID;
166355992Swpaul			arg = optarg;
166455992Swpaul			break;
166555992Swpaul		case 'o':
166655992Swpaul			act = ACT_SET_OPMODE;
166755992Swpaul			arg = optarg;
166855992Swpaul			break;
166955992Swpaul		case 'c':
167055992Swpaul			act = ACT_SET_FREQ;
167155992Swpaul			arg = optarg;
167255992Swpaul			break;
167355992Swpaul		case 'f':
167455992Swpaul			act = ACT_SET_FRAG_THRESH;
167555992Swpaul			arg = optarg;
167655992Swpaul			break;
167768692Swpaul		case 'W':
167868692Swpaul			act = ACT_ENABLE_WEP;
167968692Swpaul			arg = optarg;
168068692Swpaul			break;
168168692Swpaul		case 'K':
168268692Swpaul			act = ACT_SET_KEY_TYPE;
168368692Swpaul			arg = optarg;
168468692Swpaul			break;
168568692Swpaul		case 'k':
168668692Swpaul			act = ACT_SET_KEYS;
168768692Swpaul			key = optarg;
168868692Swpaul			break;
168969772Sarchie		case 'e':
169069772Sarchie			act = ACT_ENABLE_TX_KEY;
169169772Sarchie			arg = optarg;
169269772Sarchie			break;
169355992Swpaul		case 'q':
169455992Swpaul			act = ACT_SET_RTS_RETRYLIM;
169555992Swpaul			arg = optarg;
169655992Swpaul			break;
169755992Swpaul		case 'r':
169855992Swpaul			act = ACT_SET_RTS_THRESH;
169955992Swpaul			arg = optarg;
170055992Swpaul			break;
170155992Swpaul		case 'w':
170255992Swpaul			act = ACT_SET_WAKE_DURATION;
170355992Swpaul			arg = optarg;
170455992Swpaul			break;
170583269Sbrooks		case 'M':
170683269Sbrooks			act = ACT_SET_MONITOR_MODE;
170783269Sbrooks			arg = optarg;
170883269Sbrooks			break;
170988748Sambrisko		case 'L':
171088748Sambrisko			act = ACT_SET_LEAP_MODE;
171188748Sambrisko			arg = optarg;
171288748Sambrisko			break;
171355992Swpaul		case 'h':
171455992Swpaul		default:
171555992Swpaul			usage(p);
171655992Swpaul		}
171755992Swpaul	}
171855992Swpaul
171968692Swpaul	if (iface == NULL || (!act && !key))
172055992Swpaul		usage(p);
172155992Swpaul
172255992Swpaul	switch(act) {
172355992Swpaul	case ACT_DUMPSTATUS:
172455992Swpaul		an_dumpstatus(iface);
172555992Swpaul		break;
172655992Swpaul	case ACT_DUMPCAPS:
172755992Swpaul		an_dumpcaps(iface);
172855992Swpaul		break;
172955992Swpaul	case ACT_DUMPSTATS:
173055992Swpaul		an_dumpstats(iface);
173155992Swpaul		break;
173255992Swpaul	case ACT_DUMPCONFIG:
173355992Swpaul		an_dumpconfig(iface);
173455992Swpaul		break;
173555992Swpaul	case ACT_DUMPSSID:
173655992Swpaul		an_dumpssid(iface);
173755992Swpaul		break;
173855992Swpaul	case ACT_DUMPAP:
173955992Swpaul		an_dumpap(iface);
174055992Swpaul		break;
1741108401Sambrisko	case ACT_DUMPRSSIMAP:
1742108401Sambrisko		an_dumprssimap(iface);
1743108401Sambrisko		break;
1744119156Sambrisko	case ACT_SET_SSID:
1745119156Sambrisko		an_setssid(iface, modifier, arg);
174655992Swpaul		break;
174755992Swpaul	case ACT_SET_AP1:
174855992Swpaul	case ACT_SET_AP2:
174955992Swpaul	case ACT_SET_AP3:
175055992Swpaul	case ACT_SET_AP4:
175155992Swpaul		an_setap(iface, act, arg);
175255992Swpaul		break;
175355992Swpaul	case ACT_SET_TXRATE:
175455992Swpaul		an_setspeed(iface, act, arg);
175555992Swpaul		break;
175655992Swpaul#ifdef ANCACHE
175755992Swpaul	case ACT_ZEROCACHE:
175855992Swpaul		an_zerocache(iface);
175955992Swpaul		break;
176055992Swpaul	case ACT_DUMPCACHE:
176155992Swpaul		an_readcache(iface);
176255992Swpaul		break;
176368692Swpaul
176455992Swpaul#endif
176568692Swpaul	case ACT_SET_KEYS:
176668692Swpaul		an_setkeys(iface, key, modifier);
176768692Swpaul		break;
176869772Sarchie	case ACT_ENABLE_TX_KEY:
176969772Sarchie		an_enable_tx_key(iface, arg);
177069772Sarchie		break;
177188748Sambrisko	case ACT_SET_LEAP_MODE:
177288748Sambrisko		an_enable_leap_mode(iface, arg);
177388748Sambrisko		break;
177455992Swpaul	default:
177555992Swpaul		an_setconfig(iface, act, arg);
177655992Swpaul		break;
177755992Swpaul	}
177855992Swpaul
177955992Swpaul	exit(0);
178055992Swpaul}
178155992Swpaul
1782