summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ancontrol
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2001-12-31 22:01:44 +0000
committerambrisko <ambrisko@FreeBSD.org>2001-12-31 22:01:44 +0000
commit508de04e82ba1f0e7980cac1a0be35273fa34c8a (patch)
tree26932daacce7480f16007714fc886d711f073176 /usr.sbin/ancontrol
parent85fc04400d2760738010ae522bfd792cf6c17b1d (diff)
downloadFreeBSD-src-508de04e82ba1f0e7980cac1a0be35273fa34c8a.zip
FreeBSD-src-508de04e82ba1f0e7980cac1a0be35273fa34c8a.tar.gz
Fix bugs in the structure for rx_frame by making gap length one byte and
a packed array so sizeof work. This broke RFMON mode and passing up 802.11 packets. The Linux emulation code was derived from the open source Linux driver to maintain compatibility. LEAP support is added, hints from Richard Johnson. I've verified this locally with PC350v42510.img firmware. More bug fixing from Marco to fix long passwords. Change DELAYs in flash part of driver to FLASH_DELAY which uses tsleep so it doesn't look like your system died during a flash update. Install header files in /usr/include/dev/an Cleanup some ifmedia bugs add "Home" key mode to ifmedia and ancontrol. This way you can manage 2 keys a little easier. Map the home mode into key 5. Enhance ifconfig to dump the various configured SSIDs. I use a bunch of different ones and roam between them. Use the syntax similar to the WEP keys to deal with setting difference SSIDs. Bump up up the Card capabilities RID since they added 2 bytes to it in the latest firmware. Thankfully we changed it from a terminal failure so the card still worked but the driver whined. Some cleanup patches from Marco Molteni. Submitted by: Richard Johnson <raj@cisco.com> Marco Molteni <molter@tin.it> and myself Various checks: David Wolfskill <david@catwhisker.org> Reviewed by: Brooks Davis <brooks@freebsd.org> Warner Losh <imp@freebsd.org> Approved by: Brooks Davis <brooks@freebsd.org> Warner Losh <imp@freebsd.org> Obtained from: Linux emulation API's from Aironet driver.
Diffstat (limited to 'usr.sbin/ancontrol')
-rw-r--r--usr.sbin/ancontrol/Makefile1
-rw-r--r--usr.sbin/ancontrol/ancontrol.833
-rw-r--r--usr.sbin/ancontrol/ancontrol.c150
3 files changed, 173 insertions, 11 deletions
diff --git a/usr.sbin/ancontrol/Makefile b/usr.sbin/ancontrol/Makefile
index fe33ae1..696af71 100644
--- a/usr.sbin/ancontrol/Makefile
+++ b/usr.sbin/ancontrol/Makefile
@@ -4,6 +4,7 @@ PROG= ancontrol
MAN= ancontrol.8
CFLAGS+= -I${.CURDIR}/../../sys -DANCACHE
+LDADD+= -lmd
WARNS?= 2
diff --git a/usr.sbin/ancontrol/ancontrol.8 b/usr.sbin/ancontrol/ancontrol.8
index 0b5f21d..90d8730 100644
--- a/usr.sbin/ancontrol/ancontrol.8
+++ b/usr.sbin/ancontrol/ancontrol.8
@@ -82,10 +82,14 @@
.Nm
.Fl i Ar iface Fl m Ar mac_address
.Nm
+.Fl i Ar iface Fl m Ar mac address
+.Nm
.Fl i Ar iface
.Op Fl v Cm 1 | 2 | 3
.Fl n Ar SSID
.Nm
+.Fl i Ar iface Fl o Ar 0|1
+.Nm
.Fl i Ar iface Fl o Cm 0 | 1
.Nm
.Fl i Ar iface Fl p Ar tx_power
@@ -259,7 +263,7 @@ option: selection
sets the receive diversity and
.Cm 1
sets the transmit diversity.
-.It Fl i Ar iface Fl e Cm 0 | 1 | 2 | 3
+.It Fl i Ar iface Fl e Cm 0 | 1 | 2 | 3 | 4
Set the transmit WEP key to use.
Note that until this command is issued, the device will use the
last key programmed.
@@ -267,8 +271,9 @@ The transmit key is stored in NVRAM.
Currently
set transmit key can be checked via
.Fl C
-option.
-.It Fl i Ar iface Oo Fl v Cm 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 Oc Fl k Ar key
+option. The 4th key sets the card in "Home Network Mode" and uses the
+home key.
+.It Fl i Ar iface Oo Fl v Cm 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 Oc Fl k Ar key
Set a WEP key.
For 40 bit prefix 10 hex character with 0x.
For 128 bit prefix 26 hex character with 0x.
@@ -289,7 +294,8 @@ Note that the device will use the most recently-programmed key by default.
Currently set keys can be checked via
.Fl C
option, only the sizes of the
-keys are returned.
+keys are returned. The 8th key is for the home key. Note that
+the value for the home key can be read back from firmware.
.It Fl i Ar iface Fl K Cm 0 | 1 | 2
Set authorization type.
Use
@@ -310,6 +316,9 @@ for no WEP,
to enable full WEP,
.Cm 2
for mixed cell.
+.It Fl i Ar iface Fl L Ar user_name
+Enable LEAP and query for password. It will check to see if it
+has authenticated for up to 60s. To disable LEAP set WEP mode.
.It Fl i Ar iface Fl j Ar netjoin_timeout
Set the ad-hoc network join timeout.
When a station is first activated
@@ -423,6 +432,22 @@ need to be retransmitted instead of the whole packet.
The fragmentation
threshold can be anything from 64 to 2312 bytes.
The default is 2312.
+.It Fl i Ar iface Fl M Ar 0-15
+Set monitor mode via bit mask, meaning:
+.Bl -tag -offset indent -compact -width 0x000000
+.Em "Bit Mask Meaning"
+.It 0
+to not dump 802.11 packet.
+.It 1
+to enable 802.11 monitor.
+.It 2
+to monitor any SSID.
+.It 4
+to not skip beacons, monitor beacons produces a high system load.
+.It 8
+to enable full Aironet header returned via BPF.
+Note it appears that a SSID must be set.
+.El
.It Fl i Ar iface Fl r Ar RTS_threshold
Set the RTS/CTS threshold for a given interface.
This controls the
diff --git a/usr.sbin/ancontrol/ancontrol.c b/usr.sbin/ancontrol/ancontrol.c
index 0a89c4f..eadc5e3 100644
--- a/usr.sbin/ancontrol/ancontrol.c
+++ b/usr.sbin/ancontrol/ancontrol.c
@@ -56,6 +56,7 @@ static const char rcsid[] =
#include <unistd.h>
#include <errno.h>
#include <err.h>
+#include <md4.h>
static void an_getval __P((const char *, struct an_req *));
static void an_setval __P((const char *, struct an_req *));
@@ -83,6 +84,7 @@ static int an_hex2int __P((char));
static void an_str2key __P((char *, struct an_ltv_key *));
static void an_setkeys __P((const char *, char *, int));
static void an_enable_tx_key __P((const char *, char *));
+static void an_enable_leap_mode __P((const char *, char *));
static void usage __P((char *));
int main __P((int, char **));
@@ -126,6 +128,7 @@ int main __P((int, char **));
#define ACT_SET_KEYS 35
#define ACT_ENABLE_TX_KEY 36
#define ACT_SET_MONITOR_MODE 37
+#define ACT_SET_LEAP_MODE 38
static void an_getval(iface, areq)
const char *iface;
@@ -277,6 +280,8 @@ static void an_dumpstatus(iface)
printf("synced ");
if (sts->an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
printf("associated ");
+ if (sts->an_opmode & AN_STATUS_OPMODE_LEAP)
+ printf("LEAP ");
if (sts->an_opmode & AN_STATUS_OPMODE_ERROR)
printf("error ");
printf("]\n");
@@ -285,6 +290,7 @@ static void an_dumpstatus(iface)
printf("\nSignal quality:\t\t");
an_printhex((char *)&sts->an_cur_signal_quality, 1);
printf("\nSignal strength:\t[ %d%% ]",sts->an_normalized_rssi);
+ printf("\nMax Noise:\t\t[ %d%% ]",sts->an_avg_noise_prev_min);
/*
* XXX: This uses the old definition of the rate field (units of
* 500kbps). Technically the new definition is that this field
@@ -707,7 +713,9 @@ static void an_dumpconfig(iface)
printf("\nWEP enabled:\t\t\t\t[ ");
if (cfg->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE)
{
- if (cfg->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED)
+ if (cfg->an_authtype & AN_AUTHTYPE_LEAP)
+ printf("LEAP");
+ else if (cfg->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED)
printf("mixed cell");
else
printf("full");
@@ -805,6 +813,12 @@ static void an_dumpconfig(iface)
an_printwords(&cfg->an_arl_decay, 1);
printf("\nARL delay:\t\t\t\t");
an_printwords(&cfg->an_arl_delay, 1);
+ printf("\nConfiguration:\t\t\t\t[ ");
+ if (cfg->an_home_product & AN_HOME_NETWORK)
+ printf("Home Configuration");
+ else
+ printf("Enterprise Configuration");
+ printf(" ]");
printf("\n");
printf("\n");
@@ -842,6 +856,7 @@ static void usage(p)
fprintf(stderr, "\t%s -i iface -f val (set frag threshold)\n", p);
fprintf(stderr, "\t%s -i iface -r val (set RTS threshold)\n", p);
fprintf(stderr, "\t%s -i iface -M 0-15 (set monitor mode)\n", p);
+ fprintf(stderr, "\t%s -i iface -L user (enter LEAP authentication mode)\n", p);
#ifdef ANCACHE
fprintf(stderr, "\t%s -i iface -Q print signal quality cache\n", p);
fprintf(stderr, "\t%s -i iface -Z zero out signal cache\n", p);
@@ -962,12 +977,14 @@ static void an_setconfig(iface, act, arg)
case 0:
/* no WEP */
cfg->an_authtype &= ~(AN_AUTHTYPE_PRIVACY_IN_USE
- | AN_AUTHTYPE_ALLOW_UNENCRYPTED);
+ | AN_AUTHTYPE_ALLOW_UNENCRYPTED
+ | AN_AUTHTYPE_LEAP);
break;
case 1:
/* full WEP */
cfg->an_authtype |= AN_AUTHTYPE_PRIVACY_IN_USE;
cfg->an_authtype &= ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
+ cfg->an_authtype &= ~AN_AUTHTYPE_LEAP;
break;
case 2:
/* mixed cell */
@@ -1261,7 +1278,7 @@ static void an_setkeys(iface, key, keytype)
k->mac[4]=0;
k->mac[5]=0;
- switch(keytype & 1){
+ switch(keytype & 1) {
case 0:
areq.an_len = sizeof(struct an_ltv_key);
areq.an_type = AN_RID_WEP_PERM;
@@ -1289,12 +1306,12 @@ static void an_readkeyinfo(iface)
printf("WEP Key status:\n");
areq.an_type = AN_RID_WEP_TEMP; /* read first key */
- for(i=0; i<5; i++){
+ for(i=0; i<5; i++) {
areq.an_len = sizeof(struct an_ltv_key);
an_getval(iface, &areq);
- if(k->kindex == 0xffff)
+ if (k->kindex == 0xffff)
break;
- switch (k->klen){
+ switch (k->klen) {
case 0:
printf("\tKey %d is unset\n",k->kindex);
break;
@@ -1325,8 +1342,24 @@ static void an_enable_tx_key(iface, arg)
{
struct an_req areq;
struct an_ltv_key *k;
+ struct an_ltv_genconfig *config;
bzero((char *)&areq, sizeof(areq));
+
+ /* set home or not home mode */
+ areq.an_len = sizeof(struct an_ltv_genconfig);
+ areq.an_type = AN_RID_GENCONFIG;
+ an_getval(iface, &areq);
+ config = (struct an_ltv_genconfig *)&areq;
+ if (atoi(arg) == 4) {
+ config->an_home_product |= AN_HOME_NETWORK;
+ }else{
+ config->an_home_product &= ~AN_HOME_NETWORK;
+ }
+ an_setval(iface, &areq);
+
+ bzero((char *)&areq, sizeof(areq));
+
k = (struct an_ltv_key *)&areq;
/* From a Cisco engineer write the transmit key to use in the
@@ -1348,6 +1381,102 @@ static void an_enable_tx_key(iface, arg)
return;
}
+static void an_enable_leap_mode(iface, username)
+ const char *iface;
+ char *username;
+{
+ struct an_req areq;
+ struct an_ltv_status *sts;
+ struct an_ltv_genconfig *cfg;
+ struct an_ltv_caps *caps;
+ struct an_ltv_leap_username an_username;
+ struct an_ltv_leap_password an_password;
+ char *password;
+ MD4_CTX context;
+ int len;
+ int i;
+ char unicode_password[LEAP_PASSWORD_MAX * 2];
+
+ areq.an_len = sizeof(areq);
+ areq.an_type = AN_RID_CAPABILITIES;
+
+ an_getval(iface, &areq);
+
+ caps = (struct an_ltv_caps *)&areq;
+
+ if (!caps->an_softcaps & AN_AUTHTYPE_LEAP) {
+ fprintf(stderr, "Firmware does not support LEAP\n");
+ exit(1);
+ }
+
+ bzero(&an_username, sizeof(an_username));
+ bzero(&an_password, sizeof(an_password));
+
+ len = strlen(username);
+ if (len > LEAP_USERNAME_MAX) {
+ printf("Username too long (max %d)\n", LEAP_USERNAME_MAX);
+ exit(1);
+ }
+ strncpy(an_username.an_username, username, len);
+ an_username.an_username_len = len;
+ an_username.an_len = sizeof(an_username);
+ an_username.an_type = AN_RID_LEAPUSERNAME;
+
+ password = getpass("Enter LEAP password:");
+
+ len = strlen(password);
+ if (len > LEAP_PASSWORD_MAX) {
+ printf("Password too long (max %d)\n", LEAP_PASSWORD_MAX);
+ exit(1);
+ }
+
+ bzero(&unicode_password, sizeof(unicode_password));
+ for(i = 0; i < len; i++) {
+ unicode_password[i * 2] = *password++;
+ }
+
+ /* First half */
+ MD4Init(&context);
+ MD4Update(&context, unicode_password, len * 2);
+ MD4Final(&an_password.an_password[0], &context);
+
+ /* Second half */
+ MD4Init (&context);
+ MD4Update (&context, &an_password.an_password[0], 16);
+ MD4Final (&an_password.an_password[16], &context);
+
+ an_password.an_password_len = 32;
+ an_password.an_len = sizeof(an_password);
+ an_password.an_type = AN_RID_LEAPPASSWORD;
+
+ an_setval(iface, (struct an_req *)&an_username);
+ an_setval(iface, (struct an_req *)&an_password);
+
+ areq.an_len = sizeof(areq);
+ areq.an_type = AN_RID_GENCONFIG;
+ an_getval(iface, &areq);
+ cfg = (struct an_ltv_genconfig *)&areq;
+ cfg->an_authtype = (AN_AUTHTYPE_PRIVACY_IN_USE | AN_AUTHTYPE_LEAP);
+ an_setval(iface, &areq);
+
+ sts = (struct an_ltv_status *)&areq;
+ areq.an_type = AN_RID_STATUS;
+
+ for (i = 60; i > 0; i--) {
+ an_getval(iface, &areq);
+ if (sts->an_opmode & AN_STATUS_OPMODE_LEAP) {
+ printf("Authenticated\n");
+ break;
+ }
+ sleep(1);
+ }
+
+ if (i == 0) {
+ fprintf(stderr, "Failed LEAP authentication\n");
+ exit(1);
+ }
+}
+
int main(argc, argv)
int argc;
char *argv[];
@@ -1378,7 +1507,7 @@ int main(argc, argv)
opterr = 1;
while ((ch = getopt(argc, argv,
- "ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:")) != -1) {
+ "ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:L:")) != -1) {
switch(ch) {
case 'Z':
#ifdef ANCACHE
@@ -1545,6 +1674,10 @@ int main(argc, argv)
act = ACT_SET_MONITOR_MODE;
arg = optarg;
break;
+ case 'L':
+ act = ACT_SET_LEAP_MODE;
+ arg = optarg;
+ break;
case 'h':
default:
usage(p);
@@ -1602,6 +1735,9 @@ int main(argc, argv)
case ACT_ENABLE_TX_KEY:
an_enable_tx_key(iface, arg);
break;
+ case ACT_SET_LEAP_MODE:
+ an_enable_leap_mode(iface, arg);
+ break;
default:
an_setconfig(iface, act, arg);
break;
OpenPOWER on IntegriCloud