2 * Copyright 1997, 1998, 1999
3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
34 static const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\
35 Bill Paul. All rights reserved.";
36 static const char rcsid[] =
40 #include <sys/types.h>
41 #include <sys/cdefs.h>
42 #include <sys/socket.h>
43 #include <sys/ioctl.h>
44 #include <sys/socket.h>
46 #include <arpa/inet.h>
49 #include <net/if_var.h>
50 #include <net/ethernet.h>
52 #include <dev/an/if_aironet_ieee.h>
62 static void an_getval __P((const char *, struct an_req *));
63 static void an_setval __P((const char *, struct an_req *));
64 static void an_printwords __P((u_int16_t *, int));
65 static void an_printspeeds __P((u_int8_t*, int));
66 static void an_printbool __P((int));
67 static void an_printhex __P((char *, int));
68 static void an_printstr __P((char *, int));
69 static void an_dumpstatus __P((const char *));
70 static void an_dumpstats __P((const char *));
71 static void an_dumpconfig __P((const char *));
72 static void an_dumpcaps __P((const char *));
73 static void an_dumpssid __P((const char *));
74 static void an_dumpap __P((const char *));
75 static void an_setconfig __P((const char *, int, void *));
76 static void an_setssid __P((const char *, int, void *));
77 static void an_setap __P((const char *, int, void *));
78 static void an_setspeed __P((const char *, int, void *));
79 static void an_readkeyinfo __P((const char *));
81 static void an_zerocache __P((const char *));
82 static void an_readcache __P((const char *));
84 static int an_hex2int __P((char));
85 static void an_str2key __P((char *, struct an_ltv_key *));
86 static void an_setkeys __P((const char *, char *, int));
87 static void an_enable_tx_key __P((const char *, char *));
88 static void an_enable_leap_mode __P((const char *, char *));
89 static void usage __P((char *));
90 int main __P((int, char **));
92 #define ACT_DUMPSTATS 1
93 #define ACT_DUMPCONFIG 2
94 #define ACT_DUMPSTATUS 3
95 #define ACT_DUMPCAPS 4
96 #define ACT_DUMPSSID 5
99 #define ACT_SET_OPMODE 7
100 #define ACT_SET_SSID1 8
101 #define ACT_SET_SSID2 9
102 #define ACT_SET_SSID3 10
103 #define ACT_SET_FREQ 11
104 #define ACT_SET_AP1 12
105 #define ACT_SET_AP2 13
106 #define ACT_SET_AP3 14
107 #define ACT_SET_AP4 15
108 #define ACT_SET_DRIVERNAME 16
109 #define ACT_SET_SCANMODE 17
110 #define ACT_SET_TXRATE 18
111 #define ACT_SET_RTS_THRESH 19
112 #define ACT_SET_PWRSAVE 20
113 #define ACT_SET_DIVERSITY_RX 21
114 #define ACT_SET_DIVERSITY_TX 22
115 #define ACT_SET_RTS_RETRYLIM 23
116 #define ACT_SET_WAKE_DURATION 24
117 #define ACT_SET_BEACON_PERIOD 25
118 #define ACT_SET_TXPWR 26
119 #define ACT_SET_FRAG_THRESH 27
120 #define ACT_SET_NETJOIN 28
121 #define ACT_SET_MYNAME 29
122 #define ACT_SET_MAC 30
124 #define ACT_DUMPCACHE 31
125 #define ACT_ZEROCACHE 32
127 #define ACT_ENABLE_WEP 33
128 #define ACT_SET_KEY_TYPE 34
129 #define ACT_SET_KEYS 35
130 #define ACT_ENABLE_TX_KEY 36
131 #define ACT_SET_MONITOR_MODE 37
132 #define ACT_SET_LEAP_MODE 38
134 static void an_getval(iface, areq)
141 bzero((char *)&ifr, sizeof(ifr));
143 strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
144 ifr.ifr_data = (caddr_t)areq;
146 s = socket(AF_INET, SOCK_DGRAM, 0);
151 if (ioctl(s, SIOCGAIRONET, &ifr) == -1)
152 err(1, "SIOCGAIRONET");
159 static void an_setval(iface, areq)
166 bzero((char *)&ifr, sizeof(ifr));
168 strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
169 ifr.ifr_data = (caddr_t)areq;
171 s = socket(AF_INET, SOCK_DGRAM, 0);
176 if (ioctl(s, SIOCSAIRONET, &ifr) == -1)
177 err(1, "SIOCSAIRONET");
184 static void an_printstr(str, len)
190 for (i = 0; i < len - 1; i++) {
195 printf("[ %.*s ]", len, str);
200 static void an_printwords(w, len)
207 for (i = 0; i < len; i++)
214 static void an_printspeeds(w, len)
221 for (i = 0; i < len && w[i]; i++)
222 printf("%2.1fMbps ", w[i] * 0.500);
228 static void an_printbool(val)
239 static void an_printhex(ptr, len)
246 for (i = 0; i < len; i++) {
247 printf("%02x", ptr[i] & 0xFF);
258 static void an_dumpstatus(iface)
261 struct an_ltv_status *sts;
264 areq.an_len = sizeof(areq);
265 areq.an_type = AN_RID_STATUS;
267 an_getval(iface, &areq);
269 sts = (struct an_ltv_status *)&areq;
271 printf("MAC address:\t\t");
272 an_printhex((char *)&sts->an_macaddr, ETHER_ADDR_LEN);
273 printf("\nOperating mode:\t\t[ ");
274 if (sts->an_opmode & AN_STATUS_OPMODE_CONFIGURED)
275 printf("configured ");
276 if (sts->an_opmode & AN_STATUS_OPMODE_MAC_ENABLED)
278 if (sts->an_opmode & AN_STATUS_OPMODE_RX_ENABLED)
280 if (sts->an_opmode & AN_STATUS_OPMODE_IN_SYNC)
282 if (sts->an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
283 printf("associated ");
284 if (sts->an_opmode & AN_STATUS_OPMODE_LEAP)
286 if (sts->an_opmode & AN_STATUS_OPMODE_ERROR)
289 printf("Error code:\t\t");
290 an_printhex((char *)&sts->an_errcode, 1);
291 printf("\nSignal quality:\t\t");
292 an_printhex((char *)&sts->an_cur_signal_quality, 1);
293 printf("\nSignal strength:\t[ %d%% ]",sts->an_normalized_rssi);
294 printf("\nMax Noise:\t\t[ %d%% ]",sts->an_avg_noise_prev_min);
296 * XXX: This uses the old definition of the rate field (units of
297 * 500kbps). Technically the new definition is that this field
298 * contains arbitrary values, but no devices which need this
299 * support exist and the IEEE seems to intend to use the old
300 * definition until they get something big so we'll keep using
301 * it as well because this will work with new cards with
304 printf("\nCurrent TX rate:\t[ %d%s ]", sts->an_current_tx_rate / 2,
305 (sts->an_current_tx_rate % 2) ? ".5" : "");
306 printf("\nCurrent SSID:\t\t");
307 an_printstr((char *)&sts->an_ssid, sts->an_ssidlen);
308 printf("\nCurrent AP name:\t");
309 an_printstr((char *)&sts->an_ap_name, 16);
310 printf("\nCurrent BSSID:\t\t");
311 an_printhex((char *)&sts->an_cur_bssid, ETHER_ADDR_LEN);
312 printf("\nBeacon period:\t\t");
313 an_printwords(&sts->an_beacon_period, 1);
314 printf("\nDTIM period:\t\t");
315 an_printwords(&sts->an_dtim_period, 1);
316 printf("\nATIM duration:\t\t");
317 an_printwords(&sts->an_atim_duration, 1);
318 printf("\nHOP period:\t\t");
319 an_printwords(&sts->an_hop_period, 1);
320 printf("\nChannel set:\t\t");
321 an_printwords(&sts->an_channel_set, 1);
322 printf("\nCurrent channel:\t");
323 an_printwords(&sts->an_cur_channel, 1);
324 printf("\nHops to backbone:\t");
325 an_printwords(&sts->an_hops_to_backbone, 1);
326 printf("\nTotal AP load:\t\t");
327 an_printwords(&sts->an_ap_total_load, 1);
328 printf("\nOur generated load:\t");
329 an_printwords(&sts->an_our_generated_load, 1);
330 printf("\nAccumulated ARL:\t");
331 an_printwords(&sts->an_accumulated_arl, 1);
336 static void an_dumpcaps(iface)
339 struct an_ltv_caps *caps;
343 areq.an_len = sizeof(areq);
344 areq.an_type = AN_RID_CAPABILITIES;
346 an_getval(iface, &areq);
348 caps = (struct an_ltv_caps *)&areq;
350 printf("OUI:\t\t\t");
351 an_printhex((char *)&caps->an_oui, 3);
352 printf("\nProduct number:\t\t");
353 an_printwords(&caps->an_prodnum, 1);
354 printf("\nManufacturer name:\t");
355 an_printstr((char *)&caps->an_manufname, 32);
356 printf("\nProduce name:\t\t");
357 an_printstr((char *)&caps->an_prodname, 16);
358 printf("\nFirmware version:\t");
359 an_printstr((char *)&caps->an_prodvers, 1);
360 printf("\nOEM MAC address:\t");
361 an_printhex((char *)&caps->an_oemaddr, ETHER_ADDR_LEN);
362 printf("\nAironet MAC address:\t");
363 an_printhex((char *)&caps->an_aironetaddr, ETHER_ADDR_LEN);
364 printf("\nRadio type:\t\t[ ");
365 if (caps->an_radiotype & AN_RADIOTYPE_80211_FH)
367 else if (caps->an_radiotype & AN_RADIOTYPE_80211_DS)
369 else if (caps->an_radiotype & AN_RADIOTYPE_LM2000_DS)
372 printf("unknown (%x)", caps->an_radiotype);
374 printf("\nRegulatory domain:\t");
375 an_printwords(&caps->an_regdomain, 1);
376 printf("\nAssigned CallID:\t");
377 an_printhex((char *)&caps->an_callid, 6);
378 printf("\nSupported speeds:\t");
379 an_printspeeds(caps->an_rates, 8);
380 printf("\nRX Diversity:\t\t[ ");
381 if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
382 printf("antenna 1 only");
383 else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
384 printf("antenna 2 only");
385 else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
386 printf("antenna 1 and 2");
388 printf("\nTX Diversity:\t\t[ ");
389 if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
390 printf("antenna 1 only");
391 else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
392 printf("antenna 2 only");
393 else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
394 printf("antenna 1 and 2");
396 printf("\nSupported power levels:\t");
397 an_printwords(caps->an_tx_powerlevels, 8);
398 printf("\nHardware revision:\t");
399 tmp = ntohs(caps->an_hwrev);
400 an_printhex((char *)&tmp, 2);
401 printf("\nSoftware revision:\t");
402 tmp = ntohs(caps->an_fwrev);
403 an_printhex((char *)&tmp, 2);
404 printf("\nSoftware subrevision:\t");
405 tmp = ntohs(caps->an_fwsubrev);
406 an_printhex((char *)&tmp, 2);
407 printf("\nInterface revision:\t");
408 tmp = ntohs(caps->an_ifacerev);
409 an_printhex((char *)&tmp, 2);
410 printf("\nBootblock revision:\t");
411 tmp = ntohs(caps->an_bootblockrev);
412 an_printhex((char *)&tmp, 2);
417 static void an_dumpstats(iface)
420 struct an_ltv_stats *stats;
424 areq.an_len = sizeof(areq);
425 areq.an_type = AN_RID_32BITS_CUM;
427 an_getval(iface, &areq);
429 ptr = (caddr_t)&areq;
431 stats = (struct an_ltv_stats *)ptr;
433 printf("RX overruns:\t\t\t\t\t[ %d ]\n", stats->an_rx_overruns);
434 printf("RX PLCP CSUM errors:\t\t\t\t[ %d ]\n",
435 stats->an_rx_plcp_csum_errs);
436 printf("RX PLCP format errors:\t\t\t\t[ %d ]\n",
437 stats->an_rx_plcp_format_errs);
438 printf("RX PLCP length errors:\t\t\t\t[ %d ]\n",
439 stats->an_rx_plcp_len_errs);
440 printf("RX MAC CRC errors:\t\t\t\t[ %d ]\n",
441 stats->an_rx_mac_crc_errs);
442 printf("RX MAC CRC OK:\t\t\t\t\t[ %d ]\n",
443 stats->an_rx_mac_crc_ok);
444 printf("RX WEP errors:\t\t\t\t\t[ %d ]\n",
445 stats->an_rx_wep_errs);
446 printf("RX WEP OK:\t\t\t\t\t[ %d ]\n",
447 stats->an_rx_wep_ok);
448 printf("Long retries:\t\t\t\t\t[ %d ]\n",
449 stats->an_retry_long);
450 printf("Short retries:\t\t\t\t\t[ %d ]\n",
451 stats->an_retry_short);
452 printf("Retries exhausted:\t\t\t\t[ %d ]\n",
453 stats->an_retry_max);
454 printf("Bad ACK:\t\t\t\t\t[ %d ]\n",
456 printf("Bad CTS:\t\t\t\t\t[ %d ]\n",
458 printf("RX good ACKs:\t\t\t\t\t[ %d ]\n",
459 stats->an_rx_ack_ok);
460 printf("RX good CTSs:\t\t\t\t\t[ %d ]\n",
461 stats->an_rx_cts_ok);
462 printf("TX good ACKs:\t\t\t\t\t[ %d ]\n",
463 stats->an_tx_ack_ok);
464 printf("TX good RTSs:\t\t\t\t\t[ %d ]\n",
465 stats->an_tx_rts_ok);
466 printf("TX good CTSs:\t\t\t\t\t[ %d ]\n",
467 stats->an_tx_cts_ok);
468 printf("LMAC multicasts transmitted:\t\t\t[ %d ]\n",
469 stats->an_tx_lmac_mcasts);
470 printf("LMAC broadcasts transmitted:\t\t\t[ %d ]\n",
471 stats->an_tx_lmac_bcasts);
472 printf("LMAC unicast frags transmitted:\t\t\t[ %d ]\n",
473 stats->an_tx_lmac_ucast_frags);
474 printf("LMAC unicasts transmitted:\t\t\t[ %d ]\n",
475 stats->an_tx_lmac_ucasts);
476 printf("Beacons transmitted:\t\t\t\t[ %d ]\n",
477 stats->an_tx_beacons);
478 printf("Beacons received:\t\t\t\t[ %d ]\n",
479 stats->an_rx_beacons);
480 printf("Single transmit collisions:\t\t\t[ %d ]\n",
481 stats->an_tx_single_cols);
482 printf("Multiple transmit collisions:\t\t\t[ %d ]\n",
483 stats->an_tx_multi_cols);
484 printf("Transmits without deferrals:\t\t\t[ %d ]\n",
485 stats->an_tx_defers_no);
486 printf("Transmits deferred due to protocol:\t\t[ %d ]\n",
487 stats->an_tx_defers_prot);
488 printf("Transmits deferred due to energy detect:\t\t[ %d ]\n",
489 stats->an_tx_defers_energy);
490 printf("RX duplicate frames/frags:\t\t\t[ %d ]\n",
492 printf("RX partial frames:\t\t\t\t[ %d ]\n",
493 stats->an_rx_partial);
494 printf("TX max lifetime exceeded:\t\t\t[ %d ]\n",
495 stats->an_tx_too_old);
496 printf("RX max lifetime exceeded:\t\t\t[ %d ]\n",
497 stats->an_tx_too_old);
498 printf("Sync lost due to too many missed beacons:\t[ %d ]\n",
499 stats->an_lostsync_missed_beacons);
500 printf("Sync lost due to ARL exceeded:\t\t\t[ %d ]\n",
501 stats->an_lostsync_arl_exceeded);
502 printf("Sync lost due to deauthentication:\t\t[ %d ]\n",
503 stats->an_lostsync_deauthed);
504 printf("Sync lost due to disassociation:\t\t[ %d ]\n",
505 stats->an_lostsync_disassociated);
506 printf("Sync lost due to excess change in TSF timing:\t[ %d ]\n",
507 stats->an_lostsync_tsf_timing);
508 printf("Host transmitted multicasts:\t\t\t[ %d ]\n",
509 stats->an_tx_host_mcasts);
510 printf("Host transmitted broadcasts:\t\t\t[ %d ]\n",
511 stats->an_tx_host_bcasts);
512 printf("Host transmitted unicasts:\t\t\t[ %d ]\n",
513 stats->an_tx_host_ucasts);
514 printf("Host transmission failures:\t\t\t[ %d ]\n",
515 stats->an_tx_host_failed);
516 printf("Host received multicasts:\t\t\t[ %d ]\n",
517 stats->an_rx_host_mcasts);
518 printf("Host received broadcasts:\t\t\t[ %d ]\n",
519 stats->an_rx_host_bcasts);
520 printf("Host received unicasts:\t\t\t\t[ %d ]\n",
521 stats->an_rx_host_ucasts);
522 printf("Host receive discards:\t\t\t\t[ %d ]\n",
523 stats->an_rx_host_discarded);
524 printf("HMAC transmitted multicasts:\t\t\t[ %d ]\n",
525 stats->an_tx_hmac_mcasts);
526 printf("HMAC transmitted broadcasts:\t\t\t[ %d ]\n",
527 stats->an_tx_hmac_bcasts);
528 printf("HMAC transmitted unicasts:\t\t\t[ %d ]\n",
529 stats->an_tx_hmac_ucasts);
530 printf("HMAC transmissions failed:\t\t\t[ %d ]\n",
531 stats->an_tx_hmac_failed);
532 printf("HMAC received multicasts:\t\t\t[ %d ]\n",
533 stats->an_rx_hmac_mcasts);
534 printf("HMAC received broadcasts:\t\t\t[ %d ]\n",
535 stats->an_rx_hmac_bcasts);
536 printf("HMAC received unicasts:\t\t\t\t[ %d ]\n",
537 stats->an_rx_hmac_ucasts);
538 printf("HMAC receive discards:\t\t\t\t[ %d ]\n",
539 stats->an_rx_hmac_discarded);
540 printf("HMAC transmits accepted:\t\t\t[ %d ]\n",
541 stats->an_tx_hmac_accepted);
542 printf("SSID mismatches:\t\t\t\t[ %d ]\n",
543 stats->an_ssid_mismatches);
544 printf("Access point mismatches:\t\t\t[ %d ]\n",
545 stats->an_ap_mismatches);
546 printf("Speed mismatches:\t\t\t\t[ %d ]\n",
547 stats->an_rates_mismatches);
548 printf("Authentication rejects:\t\t\t\t[ %d ]\n",
549 stats->an_auth_rejects);
550 printf("Authentication timeouts:\t\t\t[ %d ]\n",
551 stats->an_auth_timeouts);
552 printf("Association rejects:\t\t\t\t[ %d ]\n",
553 stats->an_assoc_rejects);
554 printf("Association timeouts:\t\t\t\t[ %d ]\n",
555 stats->an_assoc_timeouts);
556 printf("Management frames received:\t\t\t[ %d ]\n",
557 stats->an_rx_mgmt_pkts);
558 printf("Management frames transmitted:\t\t\t[ %d ]\n",
559 stats->an_tx_mgmt_pkts);
560 printf("Refresh frames received:\t\t\t[ %d ]\n",
561 stats->an_rx_refresh_pkts),
562 printf("Refresh frames transmitted:\t\t\t[ %d ]\n",
563 stats->an_tx_refresh_pkts),
564 printf("Poll frames received:\t\t\t\t[ %d ]\n",
565 stats->an_rx_poll_pkts);
566 printf("Poll frames transmitted:\t\t\t[ %d ]\n",
567 stats->an_tx_poll_pkts);
568 printf("Host requested sync losses:\t\t\t[ %d ]\n",
569 stats->an_lostsync_hostreq);
570 printf("Host transmitted bytes:\t\t\t\t[ %d ]\n",
571 stats->an_host_tx_bytes);
572 printf("Host received bytes:\t\t\t\t[ %d ]\n",
573 stats->an_host_rx_bytes);
574 printf("Uptime in microseconds:\t\t\t\t[ %d ]\n",
575 stats->an_uptime_usecs);
576 printf("Uptime in seconds:\t\t\t\t[ %d ]\n",
577 stats->an_uptime_secs);
578 printf("Sync lost due to better AP:\t\t\t[ %d ]\n",
579 stats->an_lostsync_better_ap);
584 static void an_dumpap(iface)
587 struct an_ltv_aplist *ap;
590 areq.an_len = sizeof(areq);
591 areq.an_type = AN_RID_APLIST;
593 an_getval(iface, &areq);
595 ap = (struct an_ltv_aplist *)&areq;
596 printf("Access point 1:\t\t\t");
597 an_printhex((char *)&ap->an_ap1, ETHER_ADDR_LEN);
598 printf("\nAccess point 2:\t\t\t");
599 an_printhex((char *)&ap->an_ap2, ETHER_ADDR_LEN);
600 printf("\nAccess point 3:\t\t\t");
601 an_printhex((char *)&ap->an_ap3, ETHER_ADDR_LEN);
602 printf("\nAccess point 4:\t\t\t");
603 an_printhex((char *)&ap->an_ap4, ETHER_ADDR_LEN);
609 static void an_dumpssid(iface)
612 struct an_ltv_ssidlist *ssid;
615 areq.an_len = sizeof(areq);
616 areq.an_type = AN_RID_SSIDLIST;
618 an_getval(iface, &areq);
620 ssid = (struct an_ltv_ssidlist *)&areq;
621 printf("SSID 1:\t\t\t[ %.*s ]\n", ssid->an_ssid1_len, ssid->an_ssid1);
622 printf("SSID 2:\t\t\t[ %.*s ]\n", ssid->an_ssid2_len, ssid->an_ssid2);
623 printf("SSID 3:\t\t\t[ %.*s ]\n", ssid->an_ssid3_len, ssid->an_ssid3);
628 static void an_dumpconfig(iface)
631 struct an_ltv_genconfig *cfg;
633 unsigned char diversity;
635 areq.an_len = sizeof(areq);
636 areq.an_type = AN_RID_ACTUALCFG;
638 an_getval(iface, &areq);
640 cfg = (struct an_ltv_genconfig *)&areq;
642 printf("Operating mode:\t\t\t\t[ ");
643 if ((cfg->an_opmode & 0x7) == AN_OPMODE_IBSS_ADHOC)
645 if ((cfg->an_opmode & 0x7) == AN_OPMODE_INFRASTRUCTURE_STATION)
646 printf("infrastructure");
647 if ((cfg->an_opmode & 0x7) == AN_OPMODE_AP)
648 printf("access point");
649 if ((cfg->an_opmode & 0x7) == AN_OPMODE_AP_REPEATER)
650 printf("access point repeater");
652 printf("\nReceive mode:\t\t\t\t[ ");
653 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_BC_MC_ADDR)
654 printf("broadcast/multicast/unicast");
655 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_BC_ADDR)
656 printf("broadcast/unicast");
657 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_ADDR)
659 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_80211_MONITOR_CURBSS)
660 printf("802.11 monitor, current BSSID");
661 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_80211_MONITOR_ANYBSS)
662 printf("802.11 monitor, any BSSID");
663 if ((cfg->an_rxmode & 0x7) == AN_RXMODE_LAN_MONITOR_CURBSS)
664 printf("LAN monitor, current BSSID");
666 printf("\nFragment threshold:\t\t\t");
667 an_printwords(&cfg->an_fragthresh, 1);
668 printf("\nRTS threshold:\t\t\t\t");
669 an_printwords(&cfg->an_rtsthresh, 1);
670 printf("\nMAC address:\t\t\t\t");
671 an_printhex((char *)&cfg->an_macaddr, ETHER_ADDR_LEN);
672 printf("\nSupported rates:\t\t\t");
673 an_printspeeds(cfg->an_rates, 8);
674 printf("\nShort retry limit:\t\t\t");
675 an_printwords(&cfg->an_shortretry_limit, 1);
676 printf("\nLong retry limit:\t\t\t");
677 an_printwords(&cfg->an_longretry_limit, 1);
678 printf("\nTX MSDU lifetime:\t\t\t");
679 an_printwords(&cfg->an_tx_msdu_lifetime, 1);
680 printf("\nRX MSDU lifetime:\t\t\t");
681 an_printwords(&cfg->an_rx_msdu_lifetime, 1);
682 printf("\nStationary:\t\t\t\t");
683 an_printbool(cfg->an_stationary);
684 printf("\nOrdering:\t\t\t\t");
685 an_printbool(cfg->an_ordering);
686 printf("\nDevice type:\t\t\t\t[ ");
687 if (cfg->an_devtype == AN_DEVTYPE_PC4500)
689 else if (cfg->an_devtype == AN_DEVTYPE_PC4800)
692 printf("unknown (%x)", cfg->an_devtype);
694 printf("\nScanning mode:\t\t\t\t[ ");
695 if (cfg->an_scanmode == AN_SCANMODE_ACTIVE)
697 if (cfg->an_scanmode == AN_SCANMODE_PASSIVE)
699 if (cfg->an_scanmode == AN_SCANMODE_AIRONET_ACTIVE)
700 printf("Aironet active");
702 printf("\nProbe delay:\t\t\t\t");
703 an_printwords(&cfg->an_probedelay, 1);
704 printf("\nProbe energy timeout:\t\t\t");
705 an_printwords(&cfg->an_probe_energy_timeout, 1);
706 printf("\nProbe response timeout:\t\t\t");
707 an_printwords(&cfg->an_probe_response_timeout, 1);
708 printf("\nBeacon listen timeout:\t\t\t");
709 an_printwords(&cfg->an_beacon_listen_timeout, 1);
710 printf("\nIBSS join network timeout:\t\t");
711 an_printwords(&cfg->an_ibss_join_net_timeout, 1);
712 printf("\nAuthentication timeout:\t\t\t");
713 an_printwords(&cfg->an_auth_timeout, 1);
714 printf("\nWEP enabled:\t\t\t\t[ ");
715 if (cfg->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE)
717 if (cfg->an_authtype & AN_AUTHTYPE_LEAP)
719 else if (cfg->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED)
720 printf("mixed cell");
727 printf("\nAuthentication type:\t\t\t[ ");
728 if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_NONE)
730 if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_OPEN)
732 if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_SHAREDKEY)
733 printf("shared key");
735 printf("\nAssociation timeout:\t\t\t");
736 an_printwords(&cfg->an_assoc_timeout, 1);
737 printf("\nSpecified AP association timeout:\t");
738 an_printwords(&cfg->an_specified_ap_timeout, 1);
739 printf("\nOffline scan interval:\t\t\t");
740 an_printwords(&cfg->an_offline_scan_interval, 1);
741 printf("\nOffline scan duration:\t\t\t");
742 an_printwords(&cfg->an_offline_scan_duration, 1);
743 printf("\nLink loss delay:\t\t\t");
744 an_printwords(&cfg->an_link_loss_delay, 1);
745 printf("\nMax beacon loss time:\t\t\t");
746 an_printwords(&cfg->an_max_beacon_lost_time, 1);
747 printf("\nRefresh interval:\t\t\t");
748 an_printwords(&cfg->an_refresh_interval, 1);
749 printf("\nPower save mode:\t\t\t[ ");
750 if (cfg->an_psave_mode == AN_PSAVE_NONE)
752 if (cfg->an_psave_mode == AN_PSAVE_CAM)
753 printf("constantly awake mode");
754 if (cfg->an_psave_mode == AN_PSAVE_PSP)
756 if (cfg->an_psave_mode == AN_PSAVE_PSP_CAM)
757 printf("PSP-CAM (fast PSP)");
759 printf("\nSleep through DTIMs:\t\t\t");
760 an_printbool(cfg->an_sleep_for_dtims);
761 printf("\nPower save listen interval:\t\t");
762 an_printwords(&cfg->an_listen_interval, 1);
763 printf("\nPower save fast listen interval:\t");
764 an_printwords(&cfg->an_fast_listen_interval, 1);
765 printf("\nPower save listen decay:\t\t");
766 an_printwords(&cfg->an_listen_decay, 1);
767 printf("\nPower save fast listen decay:\t\t");
768 an_printwords(&cfg->an_fast_listen_decay, 1);
769 printf("\nAP/ad-hoc Beacon period:\t\t");
770 an_printwords(&cfg->an_beacon_period, 1);
771 printf("\nAP/ad-hoc ATIM duration:\t\t");
772 an_printwords(&cfg->an_atim_duration, 1);
773 printf("\nAP/ad-hoc current channel:\t\t");
774 an_printwords(&cfg->an_ds_channel, 1);
775 printf("\nAP/ad-hoc DTIM period:\t\t\t");
776 an_printwords(&cfg->an_dtim_period, 1);
777 printf("\nRadio type:\t\t\t\t[ ");
778 if (cfg->an_radiotype & AN_RADIOTYPE_80211_FH)
780 else if (cfg->an_radiotype & AN_RADIOTYPE_80211_DS)
782 else if (cfg->an_radiotype & AN_RADIOTYPE_LM2000_DS)
785 printf("unknown (%x)", cfg->an_radiotype);
787 printf("\nRX Diversity:\t\t\t\t[ ");
788 diversity = cfg->an_diversity & 0xFF;
789 if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
790 printf("antenna 1 only");
791 else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
792 printf("antenna 2 only");
793 else if (diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
794 printf("antenna 1 and 2");
796 printf("\nTX Diversity:\t\t\t\t[ ");
797 diversity = (cfg->an_diversity >> 8) & 0xFF;
798 if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY)
799 printf("antenna 1 only");
800 else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY)
801 printf("antenna 2 only");
802 else if (diversity == AN_DIVERSITY_ANTENNA_1_AND_2)
803 printf("antenna 1 and 2");
805 printf("\nTransmit power level:\t\t\t");
806 an_printwords(&cfg->an_tx_power, 1);
807 printf("\nRSS threshold:\t\t\t\t");
808 an_printwords(&cfg->an_rss_thresh, 1);
809 printf("\nNode name:\t\t\t\t");
810 an_printstr((char *)&cfg->an_nodename, 16);
811 printf("\nARL threshold:\t\t\t\t");
812 an_printwords(&cfg->an_arl_thresh, 1);
813 printf("\nARL decay:\t\t\t\t");
814 an_printwords(&cfg->an_arl_decay, 1);
815 printf("\nARL delay:\t\t\t\t");
816 an_printwords(&cfg->an_arl_delay, 1);
817 printf("\nConfiguration:\t\t\t\t[ ");
818 if (cfg->an_home_product & AN_HOME_NETWORK)
819 printf("Home Configuration");
821 printf("Enterprise Configuration");
826 an_readkeyinfo(iface);
835 fprintf(stderr, "usage: %s -i iface -A (show specified APs)\n", p);
836 fprintf(stderr, "\t%s -i iface -N (show specified SSIDss)\n", p);
837 fprintf(stderr, "\t%s -i iface -S (show NIC status)\n", p);
838 fprintf(stderr, "\t%s -i iface -I (show NIC capabilities)\n", p);
839 fprintf(stderr, "\t%s -i iface -T (show stats counters)\n", p);
840 fprintf(stderr, "\t%s -i iface -C (show current config)\n", p);
841 fprintf(stderr, "\t%s -i iface -t 0-4 (set TX speed)\n", p);
842 fprintf(stderr, "\t%s -i iface -s 0-3 (set power save mode)\n", p);
843 fprintf(stderr, "\t%s -i iface [-v 1-4] -a AP (specify AP)\n", p);
844 fprintf(stderr, "\t%s -i iface -b val (set beacon period)\n", p);
845 fprintf(stderr, "\t%s -i iface [-v 0|1] -d val (set diversity)\n", p);
846 fprintf(stderr, "\t%s -i iface -j val (set netjoin timeout)\n", p);
847 fprintf(stderr, "\t%s -i iface -e 0-4 (enable transmit key)\n", p);
848 fprintf(stderr, "\t%s -i iface [-v 0-8] -k key (set key)\n", p);
849 fprintf(stderr, "\t%s -i iface -K 0-2 (no auth/open/shared secret)\n", p);
850 fprintf(stderr, "\t%s -i iface -W 0-2 (no WEP/full WEP/mixed cell)\n", p);
851 fprintf(stderr, "\t%s -i iface -l val (set station name)\n", p);
852 fprintf(stderr, "\t%s -i iface -m val (set MAC address)\n", p);
853 fprintf(stderr, "\t%s -i iface [-v 1-3] -n SSID "
854 "(specify SSID)\n", p);
855 fprintf(stderr, "\t%s -i iface -o 0|1 (set operating mode)\n", p);
856 fprintf(stderr, "\t%s -i iface -c val (set ad-hoc channel)\n", p);
857 fprintf(stderr, "\t%s -i iface -f val (set frag threshold)\n", p);
858 fprintf(stderr, "\t%s -i iface -r val (set RTS threshold)\n", p);
859 fprintf(stderr, "\t%s -i iface -M 0-15 (set monitor mode)\n", p);
860 fprintf(stderr, "\t%s -i iface -L user (enter LEAP authentication mode)\n", p);
862 fprintf(stderr, "\t%s -i iface -Q print signal quality cache\n", p);
863 fprintf(stderr, "\t%s -i iface -Z zero out signal cache\n", p);
866 fprintf(stderr, "\t%s -h (display this message)\n", p);
872 static void an_setconfig(iface, act, arg)
877 struct an_ltv_genconfig *cfg;
878 struct an_ltv_caps *caps;
880 struct an_req areq_caps;
881 u_int16_t diversity = 0;
882 struct ether_addr *addr;
885 areq.an_len = sizeof(areq);
886 areq.an_type = AN_RID_GENCONFIG;
887 an_getval(iface, &areq);
888 cfg = (struct an_ltv_genconfig *)&areq;
890 areq_caps.an_len = sizeof(areq);
891 areq_caps.an_type = AN_RID_CAPABILITIES;
892 an_getval(iface, &areq_caps);
893 caps = (struct an_ltv_caps *)&areq_caps;
897 cfg->an_opmode = atoi(arg);
900 cfg->an_ds_channel = atoi(arg);
902 case ACT_SET_PWRSAVE:
903 cfg->an_psave_mode = atoi(arg);
905 case ACT_SET_SCANMODE:
906 cfg->an_scanmode = atoi(arg);
908 case ACT_SET_DIVERSITY_RX:
909 case ACT_SET_DIVERSITY_TX:
912 diversity = AN_DIVERSITY_FACTORY_DEFAULT;
915 diversity = AN_DIVERSITY_ANTENNA_1_ONLY;
918 diversity = AN_DIVERSITY_ANTENNA_2_ONLY;
921 diversity = AN_DIVERSITY_ANTENNA_1_AND_2;
924 errx(1, "bad diversity setting: %d", diversity);
927 if (atoi(arg) == ACT_SET_DIVERSITY_RX) {
928 cfg->an_diversity &= 0x00FF;
929 cfg->an_diversity |= (diversity << 8);
931 cfg->an_diversity &= 0xFF00;
932 cfg->an_diversity |= diversity;
936 for (i = 0; i < 8; i++) {
937 if (caps->an_tx_powerlevels[i] == atoi(arg))
941 errx(1, "unsupported power level: %dmW", atoi(arg));
943 cfg->an_tx_power = atoi(arg);
945 case ACT_SET_RTS_THRESH:
946 cfg->an_rtsthresh = atoi(arg);
948 case ACT_SET_RTS_RETRYLIM:
949 cfg->an_shortretry_limit =
950 cfg->an_longretry_limit = atoi(arg);
952 case ACT_SET_BEACON_PERIOD:
953 cfg->an_beacon_period = atoi(arg);
955 case ACT_SET_WAKE_DURATION:
956 cfg->an_atim_duration = atoi(arg);
958 case ACT_SET_FRAG_THRESH:
959 cfg->an_fragthresh = atoi(arg);
961 case ACT_SET_NETJOIN:
962 cfg->an_ibss_join_net_timeout = atoi(arg);
965 bzero(cfg->an_nodename, 16);
966 strncpy((char *)&cfg->an_nodename, optarg, 16);
969 addr = ether_aton((char *)arg);
972 errx(1, "badly formatted address");
973 bzero(cfg->an_macaddr, ETHER_ADDR_LEN);
974 bcopy((char *)addr, (char *)&cfg->an_macaddr, ETHER_ADDR_LEN);
977 switch (atoi (arg)) {
980 cfg->an_authtype &= ~(AN_AUTHTYPE_PRIVACY_IN_USE
981 | AN_AUTHTYPE_ALLOW_UNENCRYPTED
986 cfg->an_authtype |= AN_AUTHTYPE_PRIVACY_IN_USE;
987 cfg->an_authtype &= ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
988 cfg->an_authtype &= ~AN_AUTHTYPE_LEAP;
992 cfg->an_authtype = AN_AUTHTYPE_PRIVACY_IN_USE
993 | AN_AUTHTYPE_ALLOW_UNENCRYPTED;
997 case ACT_SET_KEY_TYPE:
998 cfg->an_authtype = (cfg->an_authtype & ~AN_AUTHTYPE_MASK)
1001 case ACT_SET_MONITOR_MODE:
1002 areq.an_type = AN_RID_MONITOR_MODE;
1003 cfg->an_len = atoi(arg); /* mode is put in length */
1006 errx(1, "unknown action");
1010 an_setval(iface, &areq);
1014 static void an_setspeed(iface, act, arg)
1020 struct an_ltv_caps *caps;
1023 areq.an_len = sizeof(areq);
1024 areq.an_type = AN_RID_CAPABILITIES;
1026 an_getval(iface, &areq);
1027 caps = (struct an_ltv_caps *)&areq;
1034 speed = AN_RATE_1MBPS;
1037 speed = AN_RATE_2MBPS;
1040 if (caps->an_rates[2] != AN_RATE_5_5MBPS)
1041 errx(1, "5.5Mbps not supported on this card");
1042 speed = AN_RATE_5_5MBPS;
1045 if (caps->an_rates[3] != AN_RATE_11MBPS)
1046 errx(1, "11Mbps not supported on this card");
1047 speed = AN_RATE_11MBPS;
1050 errx(1, "unsupported speed");
1055 areq.an_type = AN_RID_TX_SPEED;
1056 areq.an_val[0] = speed;
1058 an_setval(iface, &areq);
1062 static void an_setap(iface, act, arg)
1067 struct an_ltv_aplist *ap;
1069 struct ether_addr *addr;
1071 areq.an_len = sizeof(areq);
1072 areq.an_type = AN_RID_APLIST;
1074 an_getval(iface, &areq);
1075 ap = (struct an_ltv_aplist *)&areq;
1077 addr = ether_aton((char *)arg);
1080 errx(1, "badly formatted address");
1084 bzero(ap->an_ap1, ETHER_ADDR_LEN);
1085 bcopy((char *)addr, (char *)&ap->an_ap1, ETHER_ADDR_LEN);
1088 bzero(ap->an_ap2, ETHER_ADDR_LEN);
1089 bcopy((char *)addr, (char *)&ap->an_ap2, ETHER_ADDR_LEN);
1092 bzero(ap->an_ap3, ETHER_ADDR_LEN);
1093 bcopy((char *)addr, (char *)&ap->an_ap3, ETHER_ADDR_LEN);
1096 bzero(ap->an_ap4, ETHER_ADDR_LEN);
1097 bcopy((char *)addr, (char *)&ap->an_ap4, ETHER_ADDR_LEN);
1100 errx(1, "unknown action");
1104 an_setval(iface, &areq);
1108 static void an_setssid(iface, act, arg)
1113 struct an_ltv_ssidlist *ssid;
1116 areq.an_len = sizeof(areq);
1117 areq.an_type = AN_RID_SSIDLIST;
1119 an_getval(iface, &areq);
1120 ssid = (struct an_ltv_ssidlist *)&areq;
1124 bzero(ssid->an_ssid1, sizeof(ssid->an_ssid1));
1125 strlcpy(ssid->an_ssid1, (char *)arg, sizeof(ssid->an_ssid1));
1126 ssid->an_ssid1_len = strlen(ssid->an_ssid1);
1129 bzero(ssid->an_ssid2, sizeof(ssid->an_ssid2));
1130 strlcpy(ssid->an_ssid2, (char *)arg, sizeof(ssid->an_ssid2));
1131 ssid->an_ssid2_len = strlen(ssid->an_ssid2);
1134 bzero(ssid->an_ssid3, sizeof(ssid->an_ssid3));
1135 strlcpy(ssid->an_ssid3, (char *)arg, sizeof(ssid->an_ssid3));
1136 ssid->an_ssid3_len = strlen(ssid->an_ssid3);
1139 errx(1, "unknown action");
1143 an_setval(iface, &areq);
1148 static void an_zerocache(iface)
1153 bzero((char *)&areq, sizeof(areq));
1155 areq.an_type = AN_RID_ZERO_CACHE;
1157 an_getval(iface, &areq);
1162 static void an_readcache(iface)
1167 struct an_sigcache *sc;
1172 errx(1, "must specify interface name");
1174 bzero((char *)&areq, sizeof(areq));
1175 areq.an_len = AN_MAX_DATALEN;
1176 areq.an_type = AN_RID_READ_CACHE;
1178 an_getval(iface, &areq);
1180 an_sigitems = (int *) &areq.an_val;
1181 pt = ((char *) &areq.an_val);
1183 sc = (struct an_sigcache *) pt;
1185 for (i = 0; i < *an_sigitems; i++) {
1186 printf("[%d/%d]:", i+1, *an_sigitems);
1187 printf(" %02x:%02x:%02x:%02x:%02x:%02x,",
1193 sc->macsrc[5]&0xff);
1194 printf(" %d.%d.%d.%d,",((sc->ipsrc >> 0) & 0xff),
1195 ((sc->ipsrc >> 8) & 0xff),
1196 ((sc->ipsrc >> 16) & 0xff),
1197 ((sc->ipsrc >> 24) & 0xff));
1198 printf(" sig: %d, noise: %d, qual: %d\n",
1209 static int an_hex2int(c)
1212 if (c >= '0' && c <= '9')
1214 if (c >= 'A' && c <= 'F')
1215 return (c - 'A' + 10);
1216 if (c >= 'a' && c <= 'f')
1217 return (c - 'a' + 10);
1222 static void an_str2key(s, k)
1224 struct an_ltv_key *k;
1229 /* Is this a hex string? */
1230 if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
1231 /* Yes, convert to int. */
1233 p = (char *)&k->key[0];
1234 for (i = 2; s[i] != '\0' && s[i + 1] != '\0'; i+= 2) {
1235 *p++ = (an_hex2int(s[i]) << 4) + an_hex2int(s[i + 1]);
1239 errx(1, "hex strings must be of even length");
1242 /* No, just copy it in. */
1243 bcopy(s, k->key, strlen(s));
1244 k->klen = strlen(s);
1250 static void an_setkeys(iface, key, keytype)
1256 struct an_ltv_key *k;
1258 bzero((char *)&areq, sizeof(areq));
1259 k = (struct an_ltv_key *)&areq;
1261 if (strlen(key) > 28) {
1262 err(1, "encryption key must be no "
1263 "more than 18 characters long");
1268 k->kindex=keytype/2;
1270 if (!(k->klen==0 || k->klen==5 || k->klen==13)) {
1271 err(1, "encryption key must be 0, 5 or 13 bytes long");
1274 /* default mac and only valid one (from manual) 1.0.0.0.0.0 */
1282 switch(keytype & 1) {
1284 areq.an_len = sizeof(struct an_ltv_key);
1285 areq.an_type = AN_RID_WEP_PERM;
1286 an_setval(iface, &areq);
1289 areq.an_len = sizeof(struct an_ltv_key);
1290 areq.an_type = AN_RID_WEP_TEMP;
1291 an_setval(iface, &areq);
1298 static void an_readkeyinfo(iface)
1302 struct an_ltv_genconfig *cfg;
1303 struct an_ltv_key *k;
1307 areq.an_len = sizeof(areq);
1308 areq.an_type = AN_RID_ACTUALCFG;
1309 an_getval(iface, &areq);
1310 cfg = (struct an_ltv_genconfig *)&areq;
1311 if (cfg->an_home_product & AN_HOME_NETWORK)
1316 bzero((char *)&areq, sizeof(areq));
1317 k = (struct an_ltv_key *)&areq;
1319 printf("WEP Key status:\n");
1320 areq.an_type = AN_RID_WEP_TEMP; /* read first key */
1321 for(i=0; i<5; i++) {
1322 areq.an_len = sizeof(struct an_ltv_key);
1323 an_getval(iface, &areq);
1324 if (k->kindex == 0xffff)
1328 printf("\tKey %d is unset\n",k->kindex);
1331 printf("\tKey %d is set 40 bits\n",k->kindex);
1334 printf("\tKey %d is set 128 bits\n",k->kindex);
1337 printf("\tWEP Key %d has an unknown size %d\n",
1341 areq.an_type = AN_RID_WEP_PERM; /* read next key */
1344 areq.an_len = sizeof(struct an_ltv_key);
1345 an_getval(iface, &areq);
1346 printf("\tThe active transmit key is %d\n", 4 * home + k->mac[0]);
1351 static void an_enable_tx_key(iface, arg)
1356 struct an_ltv_key *k;
1357 struct an_ltv_genconfig *config;
1359 bzero((char *)&areq, sizeof(areq));
1361 /* set home or not home mode */
1362 areq.an_len = sizeof(struct an_ltv_genconfig);
1363 areq.an_type = AN_RID_GENCONFIG;
1364 an_getval(iface, &areq);
1365 config = (struct an_ltv_genconfig *)&areq;
1366 if (atoi(arg) == 4) {
1367 config->an_home_product |= AN_HOME_NETWORK;
1369 config->an_home_product &= ~AN_HOME_NETWORK;
1371 an_setval(iface, &areq);
1373 bzero((char *)&areq, sizeof(areq));
1375 k = (struct an_ltv_key *)&areq;
1377 /* From a Cisco engineer write the transmit key to use in the
1378 first MAC, index is FFFF*/
1382 k->mac[0]=atoi(arg);
1389 areq.an_len = sizeof(struct an_ltv_key);
1390 areq.an_type = AN_RID_WEP_PERM;
1391 an_setval(iface, &areq);
1396 static void an_enable_leap_mode(iface, username)
1401 struct an_ltv_status *sts;
1402 struct an_ltv_genconfig *cfg;
1403 struct an_ltv_caps *caps;
1404 struct an_ltv_leap_username an_username;
1405 struct an_ltv_leap_password an_password;
1410 char unicode_password[LEAP_PASSWORD_MAX * 2];
1412 areq.an_len = sizeof(areq);
1413 areq.an_type = AN_RID_CAPABILITIES;
1415 an_getval(iface, &areq);
1417 caps = (struct an_ltv_caps *)&areq;
1419 if (!caps->an_softcaps & AN_AUTHTYPE_LEAP) {
1420 fprintf(stderr, "Firmware does not support LEAP\n");
1424 bzero(&an_username, sizeof(an_username));
1425 bzero(&an_password, sizeof(an_password));
1427 len = strlen(username);
1428 if (len > LEAP_USERNAME_MAX) {
1429 printf("Username too long (max %d)\n", LEAP_USERNAME_MAX);
1432 strncpy(an_username.an_username, username, len);
1433 an_username.an_username_len = len;
1434 an_username.an_len = sizeof(an_username);
1435 an_username.an_type = AN_RID_LEAPUSERNAME;
1437 password = getpass("Enter LEAP password:");
1439 len = strlen(password);
1440 if (len > LEAP_PASSWORD_MAX) {
1441 printf("Password too long (max %d)\n", LEAP_PASSWORD_MAX);
1445 bzero(&unicode_password, sizeof(unicode_password));
1446 for(i = 0; i < len; i++) {
1447 unicode_password[i * 2] = *password++;
1452 MD4Update(&context, unicode_password, len * 2);
1453 MD4Final(&an_password.an_password[0], &context);
1457 MD4Update (&context, &an_password.an_password[0], 16);
1458 MD4Final (&an_password.an_password[16], &context);
1460 an_password.an_password_len = 32;
1461 an_password.an_len = sizeof(an_password);
1462 an_password.an_type = AN_RID_LEAPPASSWORD;
1464 an_setval(iface, (struct an_req *)&an_username);
1465 an_setval(iface, (struct an_req *)&an_password);
1467 areq.an_len = sizeof(areq);
1468 areq.an_type = AN_RID_GENCONFIG;
1469 an_getval(iface, &areq);
1470 cfg = (struct an_ltv_genconfig *)&areq;
1471 cfg->an_authtype = (AN_AUTHTYPE_PRIVACY_IN_USE | AN_AUTHTYPE_LEAP);
1472 an_setval(iface, &areq);
1474 sts = (struct an_ltv_status *)&areq;
1475 areq.an_type = AN_RID_STATUS;
1477 for (i = 60; i > 0; i--) {
1478 an_getval(iface, &areq);
1479 if (sts->an_opmode & AN_STATUS_OPMODE_LEAP) {
1480 printf("Authenticated\n");
1487 fprintf(stderr, "Failed LEAP authentication\n");
1492 int main(argc, argv)
1498 const char *iface = NULL;
1504 /* Get the interface name */
1506 ch = getopt(argc, argv, "i:");
1510 if (argc > 1 && *argv[1] != '-') {
1521 while ((ch = getopt(argc, argv,
1522 "ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:L:")) != -1) {
1526 act = ACT_ZEROCACHE;
1528 errx(1, "ANCACHE not available");
1533 act = ACT_DUMPCACHE;
1535 errx(1, "ANCACHE not available");
1545 act = ACT_DUMPSTATUS;
1551 act = ACT_DUMPSTATS;
1554 act = ACT_DUMPCONFIG;
1557 act = ACT_SET_TXRATE;
1561 act = ACT_SET_PWRSAVE;
1565 act = ACT_SET_TXPWR;
1569 modifier = atoi(optarg);
1587 errx(1, "bad modifier %d: there "
1588 "are only 4 access point settings",
1596 act = ACT_SET_BEACON_PERIOD;
1602 act = ACT_SET_DIVERSITY_RX;
1605 act = ACT_SET_DIVERSITY_TX;
1608 errx(1, "must specift RX or TX diversity");
1614 act = ACT_SET_NETJOIN;
1618 act = ACT_SET_MYNAME;
1629 act = ACT_SET_SSID1;
1632 act = ACT_SET_SSID2;
1635 act = ACT_SET_SSID3;
1638 errx(1, "bad modifier %d: there"
1639 "are only 3 SSID settings", modifier);
1646 act = ACT_SET_OPMODE;
1654 act = ACT_SET_FRAG_THRESH;
1658 act = ACT_ENABLE_WEP;
1662 act = ACT_SET_KEY_TYPE;
1670 act = ACT_ENABLE_TX_KEY;
1674 act = ACT_SET_RTS_RETRYLIM;
1678 act = ACT_SET_RTS_THRESH;
1682 act = ACT_SET_WAKE_DURATION;
1686 act = ACT_SET_MONITOR_MODE;
1690 act = ACT_SET_LEAP_MODE;
1699 if (iface == NULL || (!act && !key))
1703 case ACT_DUMPSTATUS:
1704 an_dumpstatus(iface);
1710 an_dumpstats(iface);
1712 case ACT_DUMPCONFIG:
1713 an_dumpconfig(iface);
1724 an_setssid(iface, act, arg);
1730 an_setap(iface, act, arg);
1732 case ACT_SET_TXRATE:
1733 an_setspeed(iface, act, arg);
1737 an_zerocache(iface);
1740 an_readcache(iface);
1745 an_setkeys(iface, key, modifier);
1747 case ACT_ENABLE_TX_KEY:
1748 an_enable_tx_key(iface, arg);
1750 case ACT_SET_LEAP_MODE:
1751 an_enable_leap_mode(iface, arg);
1754 an_setconfig(iface, act, arg);