diff options
Diffstat (limited to 'usr.sbin/ancontrol')
-rw-r--r-- | usr.sbin/ancontrol/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/ancontrol/ancontrol.8 | 33 | ||||
-rw-r--r-- | usr.sbin/ancontrol/ancontrol.c | 150 |
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; |