Close PR# 21843 and PR# 21864. This adds support for WEP and updates some

of the data structures to include new members that weren't defined in the
manual I have.

I opted to use Doug Ambrisko's WEP patches since David Cornejo's patches
did not include the necessary changes to ancontrol(8) to actually enable
and use WEP.

NOTE: I don't currently have access to an Aironet card, so I can't test
any of this. Everything compiles and close scrutiny doesn't reveal any
obvious problems, but Murphy's Law applies. This means I will probably
leave these changes in -current for a bit longer than usual until I'm
sure they work right.
This commit is contained in:
Bill Paul 2000-11-13 23:04:16 +00:00
parent 0634de0c1f
commit a614c4dc7b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=68692
5 changed files with 285 additions and 25 deletions

View File

@ -151,6 +151,15 @@ struct an_sigcache {
};
#endif
struct an_ltv_key {
u_int16_t an_len;
u_int16_t an_type;
u_int16_t kindex;
u_int8_t mac[6];
u_int16_t klen;
u_int8_t key[16]; /* 40-bit keys */
};
#ifndef _KERNEL
struct an_ltv_stats {
u_int16_t an_fudge;
@ -312,7 +321,10 @@ struct an_ltv_genconfig {
u_int16_t an_diversity; /* 0x72 */
u_int16_t an_tx_power; /* 0x74 */
u_int16_t an_rss_thresh; /* 0x76 */
u_int16_t an_rsvd6[4]; /* 0x78 */
u_int16_t an_modulation_type; /* 0x78 */
u_int16_t an_short_preamble; /* 0x7A */
u_int16_t an_home_product; /* 0x7C */
u_int16_t an_rsvd6; /* 0x7E */
/* Aironet extensions. */
u_int8_t an_nodename[16]; /* 0x80 */
u_int16_t an_arl_thresh; /* 0x90 */
@ -357,6 +369,8 @@ struct an_ltv_genconfig {
#define AN_AUTHTYPE_OPEN 0x0001
#define AN_AUTHTYPE_SHAREDKEY 0x0002
#define AN_AUTHTYPE_EXCLUDE_UNENCRYPTED 0x0004
#define AN_AUTHTYPE_MASK 0x00ff
#define AN_AUTHTYPE_ENABLE 0x0100
#define AN_PSAVE_NONE 0x0000
#define AN_PSAVE_CAM 0x0001
@ -459,6 +473,7 @@ struct an_ltv_caps {
u_int16_t an_ifacerev; /* 0x7A */
u_int16_t an_softcaps; /* 0x7C */
u_int16_t an_bootblockrev; /* 0x7E */
u_int16_t an_req_hw_support; /* 0x80 */
};
struct an_ltv_apinfo {
@ -480,7 +495,7 @@ struct an_ltv_status {
u_int8_t an_macaddr[6]; /* 0x02 */
u_int16_t an_opmode; /* 0x08 */
u_int16_t an_errcode; /* 0x0A */
u_int16_t an_cur_signal_quality; /* 0x0C */
u_int16_t an_cur_signal_strength; /* 0x0C */
u_int16_t an_ssidlen; /* 0x0E */
u_int8_t an_ssid[32]; /* 0x10 */
u_int8_t an_ap_name[16]; /* 0x30 */
@ -498,7 +513,16 @@ struct an_ltv_status {
u_int16_t an_ap_total_load; /* 0x66 */
u_int16_t an_our_generated_load; /* 0x68 */
u_int16_t an_accumulated_arl; /* 0x6A */
u_int16_t an_rsvd0; /* 0x6C */
u_int16_t an_cur_signal_quality; /* 0x6C */
u_int16_t an_current_tx_rate; /* 0x6E */
u_int16_t an_ap_device; /* 0x70 */
u_int16_t an_normalized_rssi; /* 0x72 */
u_int16_t an_short_pre_in_use; /* 0x74 */
u_int8_t an_ap_ip_addr[4]; /* 0x76 */
u_int16_t an_max_noise_prev_sec; /* 0x7A */
u_int16_t an_avg_noise_prev_min; /* 0x7C */
u_int16_t an_max_noise_prev_min; /* 0x7E */
u_int16_t an_spare[2];
};
#define AN_STATUS_OPMODE_CONFIGURED 0x0001
@ -508,6 +532,14 @@ struct an_ltv_status {
#define AN_STATUS_OPMODE_ASSOCIATED 0x0020
#define AN_STATUS_OPMODE_ERROR 0x8000
struct an_ltv_wepkey {
u_int16_t an_len; /* 0x00 */
u_int16_t an_type; /* 0xXX */
u_int16_t an_key_index; /* 0x02 */
u_int8_t an_mac_addr[6]; /* 0x04 */
u_int16_t an_key_len; /* 0x0A */
u_int8_t an_key[13]; /* 0x0C */
};
/*
* These are all the LTV record types that we can read or write
@ -523,7 +555,11 @@ struct an_ltv_status {
#define AN_RID_APLIST 0xFF12 /* Valid AP list */
#define AN_RID_DRVNAME 0xFF13 /* ID name of this node for diag */
#define AN_RID_ENCAPPROTO 0xFF14 /* Payload encapsulation type */
#define AN_RID_WEP_TEMP 0xFF15 /* Temporary Key */
#define AN_RID_WEP_PERM 0xFF16 /* Perminant Key */
#define AN_RID_ACTUALCFG 0xFF20 /* Current configuration settings */
#define AN_RID_WEP_VOLATILE 0xFF15 /* Volatile WEP Key */
#define AN_RID_WEP_PERSISTENT 0xFF16 /* Persistent WEP Key */
/*
* Reporting (read only)

View File

@ -208,7 +208,7 @@ int an_probe(dev)
if (an_read_record(sc, (struct an_ltv_gen *)&ssid))
return(0);
/* See if the ssid matches what we expect. */
/* See if the ssid matches what we expect ... but doesn't have to */
if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
return(0);
@ -483,6 +483,10 @@ static void an_txeof(sc, status)
struct ifnet *ifp;
int id;
/* TX DONE enable lan monitor DJA
an_enable_sniff();
*/
ifp = &sc->arpcom.ac_if;
ifp->if_timer = 0;
@ -726,7 +730,7 @@ static int an_read_record(sc, ltv)
/* Now read the data. */
ptr = &ltv->an_val;
for (i = 0; i < (ltv->an_len - 1) >> 1; i++)
for (i = 0; i < (ltv->an_len - 2) >> 1; i++)
ptr[i] = CSR_READ_2(sc, AN_DATA1);
return(0);
@ -748,10 +752,10 @@ static int an_write_record(sc, ltv)
if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
return(EIO);
CSR_WRITE_2(sc, AN_DATA1, ltv->an_len);
CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2);
ptr = &ltv->an_val;
for (i = 0; i < (ltv->an_len - 1) >> 1; i++)
for (i = 0; i < (ltv->an_len - 4) >> 1; i++)
CSR_WRITE_2(sc, AN_DATA1, ptr[i]);
if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
@ -926,6 +930,29 @@ static void an_setdef(sc, areq)
case AN_RID_TX_SPEED:
sp = (struct an_ltv_gen *)areq;
sc->an_tx_rate = sp->an_val;
break;
case AN_RID_WEP_TEMP:
/* Disable the MAC. */
an_cmd(sc, AN_CMD_DISABLE, 0);
/* Just write the Key, we don't want to save it */
an_write_record(sc, (struct an_ltv_gen *)areq);
/* Turn the MAC back on. */
an_cmd(sc, AN_CMD_ENABLE, 0);
break;
case AN_RID_WEP_PERM:
/* Disable the MAC. */
an_cmd(sc, AN_CMD_DISABLE, 0);
/* Just write the Key, the card will save it in this mode */
an_write_record(sc, (struct an_ltv_gen *)areq);
/* Turn the MAC back on. */
an_cmd(sc, AN_CMD_ENABLE, 0);
break;
default:
printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type);
@ -958,8 +985,10 @@ static void an_promisc(sc, promisc)
!(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS)
) {
sc->an_rxmode = sc->an_config.an_rxmode;
/* kills card DJA, if in sniff mode can't TX packets
sc->an_config.an_rxmode |=
AN_RXMODE_LAN_MONITOR_CURBSS;
*/
} else {
sc->an_config.an_rxmode = sc->an_rxmode;
}
@ -1136,8 +1165,10 @@ static void an_init(xsc)
sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
/* Initialize promisc mode. */
if (ifp->if_flags & IFF_PROMISC)
/* Kills card DJA can't TX packet in sniff mode
if (ifp->if_flags & IFF_PROMISC)
sc->an_config.an_rxmode |= AN_RXMODE_LAN_MONITOR_CURBSS;
*/
sc->an_rxmode = sc->an_config.an_rxmode;
@ -1255,6 +1286,9 @@ static void an_start(ifp)
m_freem(m0);
m0 = NULL;
/* TX START disable lan monitor ? DJA
an_disable_sniff():
*/
sc->an_rdata.an_tx_ring[idx] = id;
if (an_cmd(sc, AN_CMD_TX, id))
printf("an%d: xmit failed\n", sc->an_unit);

View File

@ -273,7 +273,10 @@ struct an_ltv_genconfig {
u_int16_t an_diversity; /* 0x72 */
u_int16_t an_tx_power; /* 0x74 */
u_int16_t an_rss_thresh; /* 0x76 */
u_int16_t an_rsvd6[4]; /* 0x78 */
u_int16_t an_modulation_type; /* 0x78 */
u_int16_t an_short_preamble; /* 0x7A */
u_int16_t an_home_product; /* 0x7C */
u_int16_t an_rsvd6; /* 0x7E */
/* Aironet extensions. */
u_int8_t an_nodename[16]; /* 0x80 */
u_int16_t an_arl_thresh; /* 0x90 */
@ -416,6 +419,9 @@ struct an_rid_encap {
#define AN_TXENCAP_RFC1024 0x0000
#define AN_TXENCAP_80211 0x0002
#define AN_RID_WEP_TEMP 0xFF15
#define AN_RID_WEP_PERM 0xFF16
/*
* Actual config, same structure as general config (read only).
*/
@ -451,6 +457,7 @@ struct an_ltv_caps {
u_int16_t an_ifacerev; /* 0x7A */
u_int16_t an_softcaps; /* 0x7C */
u_int16_t an_bootblockrev; /* 0x7E */
u_int16_t an_req_hw_support; /* 0x80 */
};
/*
@ -492,7 +499,7 @@ struct an_ltv_status {
u_int8_t an_macaddr[6]; /* 0x02 */
u_int16_t an_opmode; /* 0x08 */
u_int16_t an_errcode; /* 0x0A */
u_int16_t an_cur_signal_quality; /* 0x0C */
u_int16_t an_cur_signal_strength; /* 0x0C */
u_int16_t an_ssidlen; /* 0x0E */
u_int8_t an_ssid[32]; /* 0x10 */
u_int8_t an_ap_name[16]; /* 0x30 */
@ -510,7 +517,16 @@ struct an_ltv_status {
u_int16_t an_ap_total_load; /* 0x66 */
u_int16_t an_our_generated_load; /* 0x68 */
u_int16_t an_accumulated_arl; /* 0x6A */
u_int16_t an_rsvd0[10]; /* 0x6C */
u_int16_t an_cur_signal_quality; /* 0x6C */
u_int16_t an_current_tx_rate; /* 0x6E */
u_int16_t an_ap_device; /* 0x70 */
u_int16_t an_normalized_rssi; /* 0x72 */
u_int16_t an_short_pre_in_use; /* 0x74 */
u_int8_t an_ap_ip_addr[4]; /* 0x76 */
u_int16_t an_max_noise_prev_sec; /* 0x7A */
u_int16_t an_avg_noise_prev_min; /* 0x7C */
u_int16_t an_max_noise_prev_min; /* 0x7E */
u_int16_t an_spare[2];
};
#define AN_STATUS_OPMODE_CONFIGURED 0x0001
@ -640,6 +656,25 @@ struct an_ltv_stats {
u_int32_t an_rsvd[10];
};
/*
* Volatile WEP Key
*/
#define AN_RID_WEP_VOLATILE 0xFF15 /* Volatile WEP Key */
struct an_ltv_wepkey {
u_int16_t an_len; /* 0x00 */
u_int16_t an_type; /* 0xXX */
u_int16_t an_key_index; /* 0x02 */
u_int8_t an_mac_addr[6]; /* 0x04 */
u_int16_t an_key_len; /* 0x0A */
u_int8_t an_key[13]; /* 0x0C */
};
/*
* Persistent WEP Key
*/
#define AN_RID_WEP_PERSISTENT 0xFF16 /* Persistent WEP Key */
/*
* Receive frame structure.
*/
@ -786,6 +821,8 @@ struct an_softc {
struct an_ltv_caps an_caps;
struct an_ltv_ssidlist an_ssidlist;
struct an_ltv_aplist an_aplist;
struct an_ltv_key an_temp_keys;
struct an_ltv_key an_perm_keys;
int an_tx_rate;
int an_rxmode;
int an_gone;
@ -854,3 +891,5 @@ driver_intr_t an_intr;
#define AN_SNAP_WORD0 (AN_SNAP_K1 | (AN_SNAP_K1 << 8))
#define AN_SNAP_WORD1 (AN_SNAP_K2 | (AN_SNAP_CONTROL << 8))
#define AN_SNAPHDR_LEN 0x6

View File

@ -54,13 +54,27 @@
.Nm ancontrol
.Fl i Ar iface Fl s Ar 0|1|2|3
.Nm ancontrol
.Fl i Ar iface Fl a Ar AP
.Fl i Ar iface
.Op Fl v Ar 1|2|3|4
.Fl a Ar AP
.Nm ancontrol
.Fl i Ar iface Fl b Ar beacon period
.Nm ancontrol
.Fl i Ar iface Fl d Ar 0|1|2|3
.Fl i Ar iface
.Op v Ar 0|1
.Fl d Ar 0|1|2|3
.Nm ancontrol
.Fl i Ar iface Fl e Ar 0|1
.Nm ancontrol
.Fl i Ar iface
.Op Fl v Ar 0|1
.Fl k Ar key
.Nm ancontrol
.Fl i Ar iface
.Fl K Ar mode
.Nm ancontrol
.Fl i Ar iface
.Fl W Ar mode
.Nm ancontrol
.Fl i Ar iface Fl j Ar netjoin timeout
.Nm ancontrol
@ -68,8 +82,9 @@
.Nm ancontrol
.Fl i Ar iface Fl m Ar mac address
.Nm ancontrol
.Fl i Ar iface Fl n Ar SSID
.Fl i Ar iface
.Op Fl v Ar 1|2|3
.Fl n Ar SSID
.Nm ancontrol
.Fl i Ar iface Fl o Ar 0|1
.Nm ancontrol
@ -184,7 +199,7 @@ Valid selections are as follows:
.Pp
Note that for IBSS (ad-hoc) mode, only PSP mode is supported, and only
if the ATIM window is non-zero.
.It Fl i Ar iface Fl a Ar AP "[-v 1|2|3|4]"
.It Fl i Ar iface "[-v 1|2|3|4]" Fl a Ar AP
Set prefered access point.
The
.Ar AP
@ -205,7 +220,7 @@ Set the ad-hoc mode beacon period.
The becon period is specified in
milliseconds.
The default is 100ms.
.It Fl i Ar iface Fl d Ar 0|1|2|3 "-v 0|1"
.It Fl i Ar iface "-v 0|1" Fl d Ar 0|1|2|3
Select the antenna diversity.
Aironet devices can be configured with up
to two antennas, and transmit and receive diversity can be configured
@ -230,6 +245,16 @@ option: selection
sets the receive diversity and
.Ar 1
sets the transmit diversity.
.It Fl i Ar iface "[ -v 0|1 ]" Fl k Ar key
Set the WEP key. For 40 bit prefix 10 hex character with 0x.
For 128 bit prefix 26 hex character with 0x.
Supports 4 keys, use even numbers are permanet and odd number
are temporary keys for example "-v 1" sets the first temporary key.
.It Fl i Ar iface Fl K Ar 0|1|2|4
Set authorization type. Use 0 for none, 1 for "Open",
2 for "Shared Key", 4 for "Exclude unencrypted".
.It Fl i Ar iface Fl W Ar 0|1
Enable WEP. Use 1 to enable, 0 for disable.
.It Fl i Ar iface Fl j Ar netjoin timeout
Set the ad-hoc network join timeout.
When a station is first activated
@ -257,7 +282,7 @@ is specified as a series of six hexadecimal values separated by colons,
e.g.: 00:60:1d:12:34:56.
This programs the new address into the card
and updates the interface as well.
.It Fl i Ar iface Fl n Ar SSID "[-v 1|2|3]"
.It Fl i Ar iface "[-v 1|2|3]" Fl n Ar SSID
Set the desired SSID (network name). There are three SSIDs which allows
the NIC to work with access points at several locations without needing
to be reconfigured.

View File

@ -118,6 +118,10 @@ int main __P((int, char **));
#define ACT_DUMPCACHE 31
#define ACT_ZEROCACHE 32
#define ACT_ENABLE_WEP 33
#define ACT_SET_KEY_TYPE 34
#define ACT_SET_KEYS 35
static void an_getval(iface, areq)
char *iface;
struct an_req *areq;
@ -240,6 +244,8 @@ static void an_printhex(ptr, len)
return;
}
static void an_dumpstatus(iface)
char *iface;
{
@ -681,14 +687,20 @@ static void an_dumpconfig(iface)
an_printwords(&cfg->an_ibss_join_net_timeout, 1);
printf("\nAuthentication timeout:\t\t\t");
an_printwords(&cfg->an_auth_timeout, 1);
printf("\nWEP enabled:\t\t\t\t[ ");
if (cfg->an_authtype & AN_AUTHTYPE_ENABLE)
printf("yes");
else
printf("no");
printf(" ]");
printf("\nAuthentication type:\t\t\t[ ");
if (cfg->an_authtype == AN_AUTHTYPE_NONE)
printf("no auth");
if (cfg->an_authtype == AN_AUTHTYPE_OPEN)
if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_NONE)
printf("none");
if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_OPEN)
printf("open");
if (cfg->an_authtype == AN_AUTHTYPE_SHAREDKEY)
if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_SHAREDKEY)
printf("shared key");
if (cfg->an_authtype == AN_AUTHTYPE_EXCLUDE_UNENCRYPTED)
if ((cfg->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_EXCLUDE_UNENCRYPTED)
printf("exclude unencrypted");
printf(" ]");
printf("\nAssociation timeout:\t\t\t");
@ -795,6 +807,9 @@ static void usage(p)
fprintf(stderr, "\t%s -i iface -b val (set beacon period)\n", p);
fprintf(stderr, "\t%s -i iface [-v 0|1] -d val (set diversity)\n", p);
fprintf(stderr, "\t%s -i iface -j val (set netjoin timeout)\n", p);
fprintf(stderr, "\t%s -i iface [-v 0|1|2|3|4|5|6|7] -k key (set key)\n", p);
fprintf(stderr, "\t%s -i iface -K 0|1|2|4 (set auth type 2=shared secret)\n", p);
fprintf(stderr, "\t%s -i iface -W 0|1 (enable WEP)\n", p);
fprintf(stderr, "\t%s -i iface -l val (set station name)\n", p);
fprintf(stderr, "\t%s -i iface -m val (set MAC address)\n", p);
fprintf(stderr, "\t%s -i iface [-v 1|2|3] -n SSID "
@ -918,6 +933,14 @@ static void an_setconfig(iface, act, arg)
bzero(cfg->an_macaddr, ETHER_ADDR_LEN);
bcopy((char *)addr, (char *)&cfg->an_macaddr, ETHER_ADDR_LEN);
break;
case ACT_ENABLE_WEP:
cfg->an_authtype = (cfg->an_authtype & AN_AUTHTYPE_MASK)
| atoi(arg) * AN_AUTHTYPE_ENABLE;
break;
case ACT_SET_KEY_TYPE:
cfg->an_authtype = (cfg->an_authtype & ~AN_AUTHTYPE_MASK)
| atoi(arg);
break;
default:
errx(1, "unknown action");
break;
@ -1122,6 +1145,92 @@ static void an_readcache(iface)
}
#endif
static int an_hex2int(c)
char c;
{
if (c >= '0' && c <= '9')
return (c - '0');
if (c >= 'A' && c <= 'F')
return (c - 'A' + 10);
if (c >= 'a' && c <= 'f')
return (c - 'a' + 10);
return (0);
}
static void an_str2key(s, k)
char *s;
struct an_ltv_key *k;
{
int n, i;
char *p;
/* Is this a hex string? */
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
/* Yes, convert to int. */
n = 0;
p = (char *)&k->key[0];
for (i = 2; i < strlen(s); i+= 2) {
*p++ = (an_hex2int(s[i]) << 4) + an_hex2int(s[i + 1]);
n++;
}
k->klen = n;
} else {
/* No, just copy it in. */
bcopy(s, k->key, strlen(s));
k->klen = strlen(s);
}
return;
}
static void an_setkeys(iface, key, keytype)
char *iface;
char *key;
int keytype;
{
struct an_req areq;
struct an_ltv_key *k;
bzero((char *)&areq, sizeof(areq));
k = (struct an_ltv_key *)&areq;
if (strlen(key) > 28) {
err(1, "encryption key must be no "
"more than 18 characters long");
}
an_str2key(key, k);
k->kindex=keytype/2;
if (!(k->klen==0 || k->klen==5 || k->klen==13)) {
err(1, "encryption key must be 0, 5 or 13 bytes long");
}
/* default mac and only valid one (from manual) 1.0.0.0.0.0 */
k->mac[0]=1;
k->mac[1]=0;
k->mac[2]=0;
k->mac[3]=0;
k->mac[4]=0;
k->mac[5]=0;
switch(keytype & 1){
case 0:
areq.an_len = sizeof(struct an_ltv_key);
areq.an_type = AN_RID_WEP_PERM;
an_setval(iface, &areq);
break;
case 1:
areq.an_len = sizeof(struct an_ltv_key);
areq.an_type = AN_RID_WEP_TEMP;
an_setval(iface, &areq);
break;
}
return;
}
int main(argc, argv)
int argc;
@ -1131,6 +1240,7 @@ int main(argc, argv)
int act = 0;
char *iface = NULL;
int modifier = 0;
char *key = NULL;
void *arg = NULL;
char *p = argv[0];
@ -1147,7 +1257,7 @@ int main(argc, argv)
opterr = 1;
while ((ch = getopt(argc, argv,
"ANISCTht:a:o:s:n:v:d:j:b:c:r:p:w:m:l:QZ")) != -1) {
"ANISCTht:a:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZ")) != -1) {
switch(ch) {
case 'Z':
#ifdef ANCACHE
@ -1282,6 +1392,18 @@ int main(argc, argv)
act = ACT_SET_FRAG_THRESH;
arg = optarg;
break;
case 'W':
act = ACT_ENABLE_WEP;
arg = optarg;
break;
case 'K':
act = ACT_SET_KEY_TYPE;
arg = optarg;
break;
case 'k':
act = ACT_SET_KEYS;
key = optarg;
break;
case 'q':
act = ACT_SET_RTS_RETRYLIM;
arg = optarg;
@ -1300,7 +1422,7 @@ int main(argc, argv)
}
}
if (iface == NULL || !act)
if (iface == NULL || (!act && !key))
usage(p);
switch(act) {
@ -1343,7 +1465,11 @@ int main(argc, argv)
case ACT_DUMPCACHE:
an_readcache(iface);
break;
#endif
case ACT_SET_KEYS:
an_setkeys(iface, key, modifier);
break;
default:
an_setconfig(iface, act, arg);
break;