--- a/Makefile +++ b/Makefile @@ -15,6 +15,11 @@ IWINFO_CLI_OBJ = iwinfo_cli.o +ifneq ($(filter rt,$(IWINFO_BACKENDS)),) + IWINFO_CFLAGS += -DUSE_RTWIFI + IWINFO_LIB_OBJ += iwinfo_rt_scan.o +endif + ifneq ($(filter wl,$(IWINFO_BACKENDS)),) IWINFO_CFLAGS += -DUSE_WL IWINFO_LIB_OBJ += iwinfo_wl.o --- a/iwinfo_wext.c +++ b/iwinfo_wext.c @@ -556,7 +559,11 @@ .phyname = wext_get_phyname, .assoclist = wext_get_assoclist, .txpwrlist = wext_get_txpwrlist, +#ifdef USE_RTWIFI + .scanlist = rt_get_scanlist, +#else .scanlist = wext_get_scanlist, +#endif .freqlist = wext_get_freqlist, .countrylist = wext_get_countrylist, .close = wext_close --- /dev/null +++ b/iwinfo_rt_scan.c @@ -0,0 +1,147 @@ +#include "iwinfo.h" +#include "iwinfo_wext.h" + +struct survey_table +{ + char channel[4]; + char ssid[33]; + char bssid[20]; + char security[23]; + char *crypto; + char signal[6]; +}; + +struct survey_table st[64]; +int survey_count = 0; + +#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) +void iwpriv(const char *name, const char *key, const char *val) +{ + int socket_id; + struct iwreq wrq; + char data[64]; + snprintf(data, 64, "%s=%s", key, val); + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + strcpy(wrq.ifr_ifrn.ifrn_name, name); + wrq.u.data.length = strlen(data); + wrq.u.data.pointer = data; + wrq.u.data.flags = 0; + ioctl(socket_id, RTPRIV_IOCTL_SET, &wrq); + close(socket_id); +} + +static void next_field(char **line, char *output, int n) { + char *l = *line; + int i; + + memcpy(output, *line, n); + *line = &l[n]; + + for (i = n - 1; i > 0; i--) { + if (output[i] != ' ') + break; + output[i] = '\0'; + } +} + +#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) +void wifi_site_survey(const char *ifname, char* essid, int print) +{ + char *s = malloc(IW_SCAN_MAX_DATA); + int ret; + int socket_id; + struct iwreq wrq; + char *line, *start; + iwpriv(ifname, "SiteSurvey", (essid ? essid : "")); + sleep(5); + memset(s, 0x00, IW_SCAN_MAX_DATA); + strcpy(wrq.ifr_name, ifname); + wrq.u.data.length = IW_SCAN_MAX_DATA; + wrq.u.data.pointer = s; + wrq.u.data.flags = 0; + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + ret = ioctl(socket_id, RTPRIV_IOCTL_GSITESURVEY, &wrq); + close(socket_id); + if(ret != 0) + goto out; + if(wrq.u.data.length < 1) + goto out; + /* ioctl result starts with a newline, for some reason */ + start = s; + while (*start == '\n') + start++; + line = strtok((char *)start, "\n"); + line = strtok(NULL, "\n"); + survey_count = 0; + while(line && (survey_count < 64)) { + next_field(&line, st[survey_count].channel, sizeof(st->channel)); + next_field(&line, st[survey_count].ssid, sizeof(st->ssid)); + next_field(&line, st[survey_count].bssid, sizeof(st->bssid)); + next_field(&line, st[survey_count].security, sizeof(st->security)); + next_field(&line, st[survey_count].signal, sizeof(st->signal)); + line = strtok(NULL, "\n"); + st[survey_count].crypto = strstr(st[survey_count].security, "/"); + if (st[survey_count].crypto) { + *st[survey_count].crypto = '\0'; + st[survey_count].crypto++; + if (print) printf("%s|%s|%s|%s\n", + st[survey_count].channel, st[survey_count].ssid, st[survey_count].bssid, st[survey_count].security); + } + survey_count++; + } + if (survey_count == 0 && !print) + printf("No results"); +out: + free(s); +} + +/*struct survey_table +{ + char channel[4]; + char ssid[33]; + char bssid[20]; + char security[23]; + char *crypto; +}; +*/ + +int rt_get_scanlist(const char *ifname, char *buf, int *len) +{ + struct iwinfo_scanlist_entry *e = (struct iwinfo_scanlist_entry *) buf; + int i = 0; + + survey_count = 0; + + wifi_site_survey(ifname, NULL, 0); + + for (i = 0; i < survey_count; i++) { + int j; + for (j = 0; j < 6; j++) { + e[i].mac[j] = (uint8_t) strtoul(&st[i].bssid[j * 3], NULL, 16); + } + strcpy(e[i].ssid, st[i].ssid); + e[i].channel = atoi(st[i].channel); + e[i].mode = IWINFO_OPMODE_MASTER; + e[i].quality = atoi(st[i].signal); + e[i].quality_max = 100; + memset(&e[i].crypto, 0, sizeof(struct iwinfo_crypto_entry)); + if (strstr(st[i].security, "WPA")) { + e[i].crypto.enabled = 1; + e[i].crypto.auth_suites |= IWINFO_KMGMT_PSK; + } + if (!st[i].crypto) + continue; + if (strstr(st[i].crypto, "TKIP")) + e[i].crypto.group_ciphers |= IWINFO_CIPHER_TKIP; + if (strstr(st[i].crypto, "AES")) + e[i].crypto.group_ciphers |= IWINFO_CIPHER_AESOCB; + if (strstr(st[i].security, "WPA2")) + e[i].crypto.wpa_version = 2; + else if (strstr(st[i].security, "WPA")) + e[i].crypto.wpa_version = 1; + } + *len = survey_count * sizeof(struct iwinfo_scanlist_entry); + + return 0; +} + --- a/iwinfo_wext.h +++ b/iwinfo_wext.h @@ -378,5 +378,6 @@ #define IW_IE_KEY_MGMT_NUM 3 int wext_get_scanlist(const char *ifname, char *buf, int *len); +int rt_get_scanlist(const char *ifname, char *buf, int *len); #endif