Changeset View
Changeset View
Standalone View
Standalone View
sbin/ifconfig/ifieee80211.c
Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <inttypes.h> | #include <inttypes.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stddef.h> /* NB: for offsetof */ | #include <stddef.h> /* NB: for offsetof */ | ||||
#include <locale.h> | |||||
#include <langinfo.h> | #include <langinfo.h> | ||||
#include <wchar.h> | |||||
#include "ifconfig.h" | #include "ifconfig.h" | ||||
#include <lib80211/lib80211_regdomain.h> | #include <lib80211/lib80211_regdomain.h> | ||||
#include <lib80211/lib80211_ioctl.h> | #include <lib80211/lib80211_ioctl.h> | ||||
#ifndef IEEE80211_FIXED_RATE_NONE | #ifndef IEEE80211_FIXED_RATE_NONE | ||||
#define IEEE80211_FIXED_RATE_NONE 0xff | #define IEEE80211_FIXED_RATE_NONE 0xff | ||||
▲ Show 20 Lines • Show All 3,330 Lines • ▼ Show 20 Lines | if (verbose && ielen >= sizeof(struct ieee80211_tdma_param)) { | ||||
printf("<v%u slot:%u slotcnt:%u slotlen:%u bintval:%u inuse:0x%x>", | printf("<v%u slot:%u slotcnt:%u slotlen:%u bintval:%u inuse:0x%x>", | ||||
tdma->tdma_version, tdma->tdma_slot, tdma->tdma_slotcnt, | tdma->tdma_version, tdma->tdma_slot, tdma->tdma_slotcnt, | ||||
LE_READ_2(&tdma->tdma_slotlen), tdma->tdma_bintval, | LE_READ_2(&tdma->tdma_slotlen), tdma->tdma_bintval, | ||||
tdma->tdma_inuse[0]); | tdma->tdma_inuse[0]); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Copy the ssid string contents into buf, truncating to fit. If the | * Copy the SSID string contents into the buffer, truncating to fit. | ||||
* ssid is entirely printable then just copy intact. Otherwise convert | * If the SSID is entirely printable then just copy intact, otherwise | ||||
* to hexadecimal. If the result is truncated then replace the last | * convert to hexadecimal (in this case, if the result is truncated | ||||
* three characters with "...". | * then replace the last three characters with "..."). | ||||
*/ | */ | ||||
static int | static int | ||||
copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len) | copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, | ||||
size_t essid_len, int *vis_essid_len) | |||||
{ | { | ||||
const u_int8_t *p; | const u_int8_t *cur, *end; | ||||
size_t maxlen; | size_t maxlen; | ||||
u_int i; | wchar_t wc; | ||||
int i, adv, vw; | |||||
if (essid_len > bufsize) | if (essid_len > bufsize) | ||||
maxlen = bufsize; | maxlen = bufsize; | ||||
else | else | ||||
maxlen = essid_len; | maxlen = essid_len; | ||||
/* determine printable or not */ | /* | ||||
emaste: Ideally we'd perform some validity checking here, not just `< ' '`. | |||||
for (i = 0, p = essid; i < maxlen; i++, p++) { | * Determine if SSID is printable or not, and calculate its | ||||
if (*p < ' ' || *p > 0x7e) | * visible width to be able to align CJK characters against | ||||
break; | * alphabetic ones correctly, if needed. | ||||
*/ | |||||
melifaroUnsubmitted Not Done Inline ActionsI'd try to split this into multiple functions to improve readability, for example: bool is_ssid_printable(essid, essid_len, &printable_len) It'd be nice to name variables in a bit more human-redable fashion melifaro: I'd try to split this into multiple functions to improve readability, for example:
bool… | |||||
cur = essid; | |||||
end = essid + maxlen; | |||||
for (vw = 0; end - cur > 0; cur += adv) { | |||||
adv = mbtowc(&wc, cur, end - cur); | |||||
if (adv < 1) | |||||
goto nonprintable; | |||||
i = wcwidth(wc); | |||||
if (i < 1) | |||||
goto nonprintable; | |||||
vw += i; | |||||
} | } | ||||
if (i != maxlen) { /* not printable, print as hex */ | memcpy(buf, essid, maxlen); | ||||
if (vis_essid_len != NULL) | |||||
*vis_essid_len = vw; | |||||
return (maxlen); | |||||
nonprintable: | |||||
if (bufsize < 3) | if (bufsize < 3) | ||||
return 0; | return 0; | ||||
strlcpy(buf, "0x", bufsize); | strcpy(buf, "0x"); | ||||
bufsize -= 2; | bufsize -= 2; | ||||
p = essid; | |||||
for (i = 0; i < maxlen && bufsize >= 2; i++) { | for (i = 0; i < maxlen && bufsize >= 2; i++) { | ||||
sprintf(&buf[2+2*i], "%02x", p[i]); | sprintf(&buf[2 + 2 * i], "%02x", essid[i]); | ||||
bufsize -= 2; | bufsize -= 2; | ||||
} | } | ||||
if (i != essid_len) | if (i != essid_len) | ||||
memcpy(&buf[2+2*i-3], "...", 3); | memcpy(&buf[2 + 2 * i - 3], "...", 3); | ||||
} else { /* printable, truncate as needed */ | if (vis_essid_len != NULL) | ||||
memcpy(buf, essid, maxlen); | *vis_essid_len = maxlen; | ||||
if (maxlen != essid_len) | return (maxlen); | ||||
memcpy(&buf[maxlen-3], "...", 3); | |||||
} | } | ||||
return maxlen; | |||||
} | |||||
static void | static void | ||||
printssid(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) | printssid(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) | ||||
{ | { | ||||
char ssid[2*IEEE80211_NWID_LEN+1]; | char ssid[2*IEEE80211_NWID_LEN+1]; | ||||
printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1]), ssid); | printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1], | ||||
NULL), ssid); | |||||
} | } | ||||
static void | static void | ||||
printrates(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) | printrates(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) | ||||
{ | { | ||||
const char *sep; | const char *sep; | ||||
int i; | int i; | ||||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | |||||
list_scan(int s) | list_scan(int s) | ||||
{ | { | ||||
uint8_t buf[24*1024]; | uint8_t buf[24*1024]; | ||||
char ssid[IEEE80211_NWID_LEN+1]; | char ssid[IEEE80211_NWID_LEN+1]; | ||||
const uint8_t *cp; | const uint8_t *cp; | ||||
int len, idlen; | int len, idlen; | ||||
if (get80211len(s, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf), &len) < 0) | if (get80211len(s, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf), &len) < 0) | ||||
errx(1, "unable to get scan results"); | errx(1, "unable to get scan results"); | ||||
Done Inline Actionserror handling from mbtowc? emaste: error handling from mbtowc? | |||||
if (len < sizeof(struct ieee80211req_scan_result)) | if (len < sizeof(struct ieee80211req_scan_result)) | ||||
return; | return; | ||||
getchaninfo(s); | getchaninfo(s); | ||||
printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" | printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" | ||||
, IEEE80211_NWID_LEN, IEEE80211_NWID_LEN, "SSID/MESH ID" | , IEEE80211_NWID_LEN, IEEE80211_NWID_LEN, "SSID/MESH ID" | ||||
, "BSSID" | , "BSSID" | ||||
, "CHAN" | , "CHAN" | ||||
, "RATE" | , "RATE" | ||||
, " S:N" | , " S:N" | ||||
, "INT" | , "INT" | ||||
, "CAPS" | , "CAPS" | ||||
); | ); | ||||
cp = buf; | cp = buf; | ||||
do { | do { | ||||
const struct ieee80211req_scan_result *sr; | const struct ieee80211req_scan_result *sr; | ||||
const uint8_t *vp, *idp; | const uint8_t *vp, *idp; | ||||
int length, visible_length; | |||||
sr = (const struct ieee80211req_scan_result *) cp; | sr = (const struct ieee80211req_scan_result *) cp; | ||||
vp = cp + sr->isr_ie_off; | vp = cp + sr->isr_ie_off; | ||||
if (sr->isr_meshid_len) { | if (sr->isr_meshid_len) { | ||||
idp = vp + sr->isr_ssid_len; | idp = vp + sr->isr_ssid_len; | ||||
idlen = sr->isr_meshid_len; | idlen = sr->isr_meshid_len; | ||||
} else { | } else { | ||||
idp = vp; | idp = vp; | ||||
idlen = sr->isr_ssid_len; | idlen = sr->isr_ssid_len; | ||||
} | } | ||||
length = copy_essid(ssid, IEEE80211_NWID_LEN, idp, idlen, | |||||
&visible_length); | |||||
printf("%-*.*s %s %3d %3dM %4d:%-4d %4d %-4.4s" | printf("%-*.*s %s %3d %3dM %4d:%-4d %4d %-4.4s" | ||||
, IEEE80211_NWID_LEN | , IEEE80211_NWID_LEN + length - visible_length | ||||
, copy_essid(ssid, IEEE80211_NWID_LEN, idp, idlen) | , length | ||||
, ssid | , ssid | ||||
, ether_ntoa((const struct ether_addr *) sr->isr_bssid) | , ether_ntoa((const struct ether_addr *) sr->isr_bssid) | ||||
, ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags) | , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags) | ||||
, getmaxrate(sr->isr_rates, sr->isr_nrates) | , getmaxrate(sr->isr_rates, sr->isr_nrates) | ||||
, (sr->isr_rssi/2)+sr->isr_noise, sr->isr_noise | , (sr->isr_rssi/2)+sr->isr_noise, sr->isr_noise | ||||
, sr->isr_intval | , sr->isr_intval | ||||
, getcaps(sr->isr_capinfo) | , getcaps(sr->isr_capinfo) | ||||
); | ); | ||||
▲ Show 20 Lines • Show All 1,908 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int i; | int i; | ||||
int hasspc; | int hasspc; | ||||
int utf8; | int utf8; | ||||
i = 0; | i = 0; | ||||
hasspc = 0; | hasspc = 0; | ||||
setlocale(LC_CTYPE, ""); | |||||
utf8 = strncmp("UTF-8", nl_langinfo(CODESET), 5) == 0; | utf8 = strncmp("UTF-8", nl_langinfo(CODESET), 5) == 0; | ||||
for (; i < len; i++) { | for (; i < len; i++) { | ||||
if (!isprint(buf[i]) && buf[i] != '\0' && !utf8) | if (!isprint(buf[i]) && buf[i] != '\0' && !utf8) | ||||
break; | break; | ||||
if (isspace(buf[i])) | if (isspace(buf[i])) | ||||
hasspc++; | hasspc++; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 382 Lines • Show Last 20 Lines |
Ideally we'd perform some validity checking here, not just < ' '.