OpenWrt – Rev 4

Subversion Repositories:
Rev:
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,10 @@ IWINFO_CLI         = iwinfo
 IWINFO_CLI_LDFLAGS = $(LDFLAGS) -L. -liwinfo
 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
--- a/iwinfo_cli.c
+++ b/iwinfo_cli.c
@@ -111,7 +111,11 @@ static char * format_signal(int sig)
        if (!sig)
                snprintf(buf, sizeof(buf), "unknown");
        else
+#ifdef USE_RTWIFI
+               snprintf(buf, sizeof(buf), "%d %", sig);
+#else
                snprintf(buf, sizeof(buf), "%d dBm", sig);
+#endif
 
        return buf;
 }
@@ -600,7 +604,11 @@ static void print_scanlist(const struct
                        IWINFO_OPMODE_NAMES[e->mode],
                        format_channel(e->channel));
                printf("          Signal: %s  Quality: %s/%s\n",
+#ifdef USE_RTWIFI
+                       format_signal(e->signal),
+#else
                        format_signal(e->signal - 0x100),
+#endif
                        format_quality(e->quality),
                        format_quality_max(e->quality_max));
                printf("          Encryption: %s\n\n",
--- /dev/null
+++ b/iwinfo_rt_scan.c
@@ -0,0 +1,157 @@
+#include "iwinfo.h"
+#include "iwinfo_wext.h"
+
+struct survey_table
+{
+       char channel[4];
+       char ssid[33];
+       char len[4];
+       char bssid[20];
+       char security[23];
+       char *crypto;
+       char signal[9];
+};
+
+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)) {
+               memset(&st[survey_count], 0, sizeof(st[survey_count]));
+
+               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].len, sizeof(st->len));
+               next_field(&line, st[survey_count].bssid, sizeof(st->bssid));
+               next_field(&line, st[survey_count].security, sizeof(st->security));
+               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);
+               }
+               next_field(&line, st[survey_count].signal, sizeof(st->signal));
+               line = strtok(NULL, "\n");
+
+               /* skip hidden ssid */
+               if (!strcmp(st[survey_count].len, "0")) {
+                       continue;
+               }
+               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].signal = atoi(st[i].signal);
+               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.c
+++ b/iwinfo_wext.c
@@ -556,7 +556,11 @@ const struct iwinfo_ops wext_ops = {
        .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
--- a/iwinfo_wext.h
+++ b/iwinfo_wext.h
@@ -379,4 +379,8 @@ static const unsigned int standard_event
 
 int wext_get_scanlist(const char *ifname, char *buf, int *len);
 
+#ifdef USE_RTWIFI
+int rt_get_scanlist(const char *ifname, char *buf, int *len);
+#endif
+
 #endif