Date: Tue, 29 Nov 2005 06:06:57 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87416 for review Message-ID: <200511290606.jAT66v66060564@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87416 Change 87416 by sam@sam_ebb on 2005/11/29 06:06:02 print decoded wme, wpa, rsn, and ath ie's with -v Affected files ... .. //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#53 edit Differences ... ==== //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#53 (text+ko) ==== @@ -812,6 +812,252 @@ } } +#define LE_READ_2(p) \ + ((u_int16_t) \ + ((((const u_int8_t *)(p))[0] ) | \ + (((const u_int8_t *)(p))[1] << 8))) +#define LE_READ_4(p) \ + ((u_int32_t) \ + ((((const u_int8_t *)(p))[0] ) | \ + (((const u_int8_t *)(p))[1] << 8) | \ + (((const u_int8_t *)(p))[2] << 16) | \ + (((const u_int8_t *)(p))[3] << 24))) + +/* + * NB: The decoding routines assume a properly formatted ie + * which should be safe as the kernel only retains them + * if they parse ok. + */ + +static void +printwmeie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ +#define MS(_v, _f) (((_v) & _f) >> _f##_S) + static const char *acnames[] = { "BE", "BK", "VO", "VI" }; + int i; + + printf("%s", tag); + if (verbose) { + printf("<qosinfo 0x%x", ie[ + __offsetof(struct ieee80211_wme_param, param_qosInfo)]); + ie += __offsetof(struct ieee80211_wme_param, params_acParams); + for (i = 0; i < WME_NUM_AC; i++) { + printf(" %s[%saifsn %u cwmin %u cwmax %u txop %u]" + , acnames[i] + , MS(ie[0], WME_PARAM_ACM) ? "acm " : "" + , MS(ie[0], WME_PARAM_AIFSN) + , MS(ie[1], WME_PARAM_LOGCWMIN) + , MS(ie[1], WME_PARAM_LOGCWMAX) + , LE_READ_2(ie+2) + ); + ie += 4; + } + printf(">"); + } +#undef MS +} + +static void +printathie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + + printf("%s", tag); + if (verbose) { + const struct ieee80211_ath_ie *ath = + (const struct ieee80211_ath_ie *)ie; + + printf("<"); + if (ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) + printf("DTURBO,"); + if (ath->ath_capability & ATHEROS_CAP_COMPRESSION) + printf("COMP,"); + if (ath->ath_capability & ATHEROS_CAP_FAST_FRAME) + printf("FF,"); + if (ath->ath_capability & ATHEROS_CAP_XR) + printf("XR,"); + if (ath->ath_capability & ATHEROS_CAP_AR) + printf("AR,"); + if (ath->ath_capability & ATHEROS_CAP_BURST) + printf("BURST,"); + if (ath->ath_capability & ATHEROS_CAP_WME) + printf("WME,"); + if (ath->ath_capability & ATHEROS_CAP_BOOST) + printf("BOOST,"); + printf("0x%x>", LE_READ_2(ath->ath_defkeyix)); + } +} + +static const char * +wpa_cipher(const u_int8_t *sel) +{ +#define WPA_SEL(x) (((x)<<24)|WPA_OUI) + u_int32_t w = LE_READ_4(sel); + + switch (w) { + case WPA_SEL(WPA_CSE_NULL): + return "NONE"; + case WPA_SEL(WPA_CSE_WEP40): + return "WEP40"; + case WPA_SEL(WPA_CSE_WEP104): + return "WEP104"; + case WPA_SEL(WPA_CSE_TKIP): + return "TKIP"; + case WPA_SEL(WPA_CSE_CCMP): + return "AES-CCMP"; + } + return "?"; /* NB: so 1<< is discarded */ +#undef WPA_SEL +} + +static const char * +wpa_keymgmt(const u_int8_t *sel) +{ +#define WPA_SEL(x) (((x)<<24)|WPA_OUI) + u_int32_t w = LE_READ_4(sel); + + switch (w) { + case WPA_SEL(WPA_ASE_8021X_UNSPEC): + return "8021X-UNSPEC"; + case WPA_SEL(WPA_ASE_8021X_PSK): + return "8021X-PSK"; + case WPA_SEL(WPA_ASE_NONE): + return "NONE"; + } + return "?"; +#undef WPA_SEL +} + +static void +printwpaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + u_int8_t len = ie[1]; + + printf("%s", tag); + if (verbose) { + const char *sep; + int n; + + ie += 6, len -= 4; /* NB: len is payload only */ + + printf("<v%u", LE_READ_2(ie)); + ie += 2, len -= 2; + + printf(" mc:%s", wpa_cipher(ie)); + ie += 4, len -= 4; + + /* unicast ciphers */ + n = LE_READ_2(ie); + ie += 2, len -= 2; + sep = " uc:"; + for (; n > 0; n--) { + printf("%s%s", sep, wpa_cipher(ie)); + ie += 4, len -= 4; + sep = "+"; + } + + /* key management algorithms */ + n = LE_READ_2(ie); + ie += 2, len -= 2; + sep = " km:"; + for (; n > 0; n--) { + printf("%s%s", sep, wpa_keymgmt(ie)); + ie += 4, len -= 4; + sep = "+"; + } + + if (len > 2) /* optional capabilities */ + printf(", caps 0x%x", LE_READ_2(ie)); + printf(">"); + } +} + +static const char * +rsn_cipher(const u_int8_t *sel) +{ +#define RSN_SEL(x) (((x)<<24)|RSN_OUI) + u_int32_t w = LE_READ_4(sel); + + switch (w) { + case RSN_SEL(RSN_CSE_NULL): + return "NONE"; + case RSN_SEL(RSN_CSE_WEP40): + return "WEP40"; + case RSN_SEL(RSN_CSE_WEP104): + return "WEP104"; + case RSN_SEL(RSN_CSE_TKIP): + return "TKIP"; + case RSN_SEL(RSN_CSE_CCMP): + return "AES-CCMP"; + case RSN_SEL(RSN_CSE_WRAP): + return "AES-OCB"; + } + return "?"; +#undef WPA_SEL +} + +static const char * +rsn_keymgmt(const u_int8_t *sel) +{ +#define RSN_SEL(x) (((x)<<24)|RSN_OUI) + u_int32_t w = LE_READ_4(sel); + + switch (w) { + case RSN_SEL(RSN_ASE_8021X_UNSPEC): + return "8021X-UNSPEC"; + case RSN_SEL(RSN_ASE_8021X_PSK): + return "8021X-PSK"; + case RSN_SEL(RSN_ASE_NONE): + return "NONE"; + } + return "?"; +#undef RSN_SEL +} + +static void +printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + u_int8_t len = ie[1]; + + printf("%s", tag); + if (verbose) { + const char *sep; + int n; + + ie += 6, len -= 4; /* NB: len is payload only */ + + printf("<v%u", LE_READ_2(ie)); + ie += 2, len -= 2; + + printf(" mc:%s", rsn_cipher(ie)); + ie += 4, len -= 4; + + /* unicast ciphers */ + n = LE_READ_2(ie); + ie += 2, len -= 2; + sep = " uc:"; + for (; n > 0; n--) { + printf("%s%s", sep, rsn_cipher(ie)); + ie += 4, len -= 4; + sep = "+"; + } + + /* key management algorithms */ + n = LE_READ_2(ie); + ie += 2, len -= 2; + sep = " km:"; + for (; n > 0; n--) { + printf("%s%s", sep, rsn_keymgmt(ie)); + ie += 4, len -= 4; + sep = "+"; + } + + if (len > 2) /* optional capabilities */ + printf(", caps 0x%x", LE_READ_2(ie)); + /* XXXPMKID */ + printf(">"); + } +} + /* * Copy the ssid string contents into buf, truncating to fit. If the * ssid is entirely printable then just copy intact. Otherwise convert @@ -887,16 +1133,16 @@ switch (vp[0]) { case IEEE80211_ELEMID_VENDOR: if (iswpaoui(vp)) - printie(" WPA", vp, 2+vp[1], maxcols); + printwpaie(" WPA", vp, 2+vp[1], maxcols); else if (iswmeoui(vp)) - printie(" WME", vp, 2+vp[1], maxcols); + printwmeie(" WME", vp, 2+vp[1], maxcols); else if (isatherosoui(vp)) - printie(" ATH", vp, 2+vp[1], maxcols); + printathie(" ATH", vp, 2+vp[1], maxcols); else printie(" VEN", vp, 2+vp[1], maxcols); break; case IEEE80211_ELEMID_RSN: - printie(" RSN", vp, 2+vp[1], maxcols); + printrsnie(" RSN", vp, 2+vp[1], maxcols); break; default: printie(" ???", vp, 2+vp[1], maxcols);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511290606.jAT66v66060564>