recognize WPS ie's

Submitted by:	"Chuck Tuffli" <chuck@tuffli.net>
MFC after:	1 week
This commit is contained in:
Sam Leffler 2008-08-09 05:37:22 +00:00
parent bfd58cce84
commit ed8b5a9370
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=181454
2 changed files with 84 additions and 1 deletions

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
.Dd July 30, 2008
.Dd August 8, 2008
.Dt IFCONFIG 8
.Os
.Sh NAME
@ -1233,6 +1233,8 @@ Possible elements include:
(station supports WME),
.Cm WPA
(station supports WPA),
.Cm WPS
(station supports WPS),
.Cm RSN
(station supports 802.11i/RSN),
.Cm HTCAP

View File

@ -2441,6 +2441,79 @@ printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
}
}
/* XXX move to a public include file */
#define IEEE80211_WPS_DEV_PASS_ID 0x1012
#define IEEE80211_WPS_SELECTED_REG 0x1041
#define IEEE80211_WPS_SETUP_STATE 0x1044
#define IEEE80211_WPS_UUID_E 0x1047
#define IEEE80211_WPS_VERSION 0x104a
#define BE_READ_2(p) \
((u_int16_t) \
((((const u_int8_t *)(p))[1] ) | \
(((const u_int8_t *)(p))[0] << 8)))
static void
printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
u_int8_t len = ie[1];
printf("%s", tag);
if (verbose) {
static const char *dev_pass_id[] = {
"D", /* Default (PIN) */
"U", /* User-specified */
"M", /* Machine-specified */
"K", /* Rekey */
"P", /* PushButton */
"R" /* Registrar-specified */
};
int n;
ie +=6, len -= 4; /* NB: len is payload only */
/* WPS IE in Beacon and Probe Resp frames have different fields */
printf("<");
while (len) {
uint16_t tlv_type = BE_READ_2(ie);
uint16_t tlv_len = BE_READ_2(ie + 2);
ie += 4, len -= 4;
switch (tlv_type) {
case IEEE80211_WPS_VERSION:
printf("v:%d.%d", *ie >> 4, *ie & 0xf);
break;
case IEEE80211_WPS_SETUP_STATE:
/* Only 1 and 2 are valid */
if (*ie == 0 || *ie >= 3)
printf(" state:B");
else
printf(" st:%s", *ie == 1 ? "N" : "C");
break;
case IEEE80211_WPS_SELECTED_REG:
printf(" sel:%s", *ie ? "T" : "F");
break;
case IEEE80211_WPS_DEV_PASS_ID:
n = LE_READ_2(ie);
if (n < N(dev_pass_id))
printf(" dpi:%s", dev_pass_id[n]);
break;
case IEEE80211_WPS_UUID_E:
printf(" uuid-e:");
for (n = 0; n < (tlv_len - 1); n++)
printf("%02x-", ie[n]);
printf("%02x", ie[n]);
break;
}
ie += tlv_len, len -= tlv_len;
}
printf(">");
}
#undef N
}
/*
* Copy the ssid string contents into buf, truncating to fit. If the
* ssid is entirely printable then just copy intact. Otherwise convert
@ -2563,6 +2636,12 @@ isatherosoui(const u_int8_t *frm)
return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
}
static __inline int
iswpsoui(const uint8_t *frm)
{
return frm[1] > 3 && LE_READ_4(frm+2) == ((WPS_OUI_TYPE<<24)|WPA_OUI);
}
static const char *
iename(int elemid)
{
@ -2624,6 +2703,8 @@ printies(const u_int8_t *vp, int ielen, int maxcols)
printwmeparam(" WME", vp, 2+vp[1], maxcols);
else if (isatherosoui(vp))
printathie(" ATH", vp, 2+vp[1], maxcols);
else if (iswpsoui(vp))
printwpsie(" WPS", vp, 2+vp[1], maxcols);
else if (verbose)
printie(" VEN", vp, 2+vp[1], maxcols);
break;