summaryrefslogtreecommitdiffhomepage
path: root/libs/luanet/src/iwconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/luanet/src/iwconfig.c')
-rw-r--r--libs/luanet/src/iwconfig.c881
1 files changed, 0 insertions, 881 deletions
diff --git a/libs/luanet/src/iwconfig.c b/libs/luanet/src/iwconfig.c
deleted file mode 100644
index 707116928..000000000
--- a/libs/luanet/src/iwconfig.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
- * Copyright (C) 2008 Steven Barth <steven@midlink.org>
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- */
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/route.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <linux/sockios.h>
-#include "iwlib.h"
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#include "helper.h"
-
-static int sock_iwconfig = 0;
-
-typedef struct iwscan_state
-{
- /* State */
- int ap_num; /* Access Point number 1->N */
- int val_index; /* Value in table 0->(N-1) */
-} iwscan_state;
-
-int iwc_startup(void)
-{
- if(!sock_iwconfig)
- sock_iwconfig = iw_sockets_open();
- return sock_iwconfig;
-}
-
-void iwc_shutdown(void)
-{
- if(!sock_iwconfig)
- return;
- iw_sockets_close(sock_iwconfig);
- sock_iwconfig = 0;
-}
-
-/* taken from wireless tools */
-static int
-get_info(char * ifname, struct wireless_info * info)
-{
- struct iwreq wrq;
-
- memset((char*) info, 0, sizeof(struct wireless_info));
-
- /* Get basic information */
- if(iw_get_basic_config(sock_iwconfig, ifname, &(info->b)) < 0)
- {
- /* If no wireless name : no wireless extensions */
- /* But let's check if the interface exists at all */
- struct ifreq ifr;
-
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if(ioctl(sock_iwconfig, SIOCGIFFLAGS, &ifr) < 0)
- return(-ENODEV);
- else
- return(-ENOTSUP);
- }
-
- /* Get ranges */
- if(iw_get_range_info(sock_iwconfig, ifname, &(info->range)) >= 0)
- info->has_range = 1;
-
- /* Get AP address */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWAP, &wrq) >= 0)
- {
- info->has_ap_addr = 1;
- memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
- }
-
- /* Get bit rate */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWRATE, &wrq) >= 0)
- {
- info->has_bitrate = 1;
- memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
- }
-
- /* Get Power Management settings */
- wrq.u.power.flags = 0;
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWPOWER, &wrq) >= 0)
- {
- info->has_power = 1;
- memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
- }
-
- /* Get stats */
- if(iw_get_stats(sock_iwconfig, ifname, &(info->stats),
- &info->range, info->has_range) >= 0)
- {
- info->has_stats = 1;
- }
-
- /* Get NickName */
- wrq.u.essid.pointer = (caddr_t) info->nickname;
- wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
- wrq.u.essid.flags = 0;
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWNICKN, &wrq) >= 0)
- if(wrq.u.data.length > 1)
- info->has_nickname = 1;
-
- if((info->has_range) && (info->range.we_version_compiled > 9))
- {
- /* Get Transmit Power */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWTXPOW, &wrq) >= 0)
- {
- info->has_txpower = 1;
- memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
- }
- }
-
- /* Get sensitivity */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWSENS, &wrq) >= 0)
- {
- info->has_sens = 1;
- memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
- }
-
- if((info->has_range) && (info->range.we_version_compiled > 10))
- {
- /* Get retry limit/lifetime */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWRETRY, &wrq) >= 0)
- {
- info->has_retry = 1;
- memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
- }
- }
-
- /* Get RTS threshold */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWRTS, &wrq) >= 0)
- {
- info->has_rts = 1;
- memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
- }
-
- /* Get fragmentation threshold */
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWFRAG, &wrq) >= 0)
- {
- info->has_frag = 1;
- memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
- }
-
- return(0);
-}
-
-void iwc_get(lua_State *L, char *ifname)
-{
- struct wireless_info info;
- int rc = get_info(ifname, &info);
- char buffer[128];
- if(rc)
- return;
-
- lua_pushstring(L, ifname);
- lua_newtable(L);
-
- if(info.b.has_essid)
- {
- if(info.b.essid_on)
- add_table_entry(L, "essid", info.b.essid);
- else
- add_table_entry(L, "essid", "off");
- }
-
- if(info.b.has_mode)
- add_table_entry(L, "mode", iw_operation_mode[info.b.mode]);
-
- if(info.b.has_freq)
- {
- double freq = info.b.freq; /* Frequency/channel */
- int channel = -1; /* Converted to channel */
- char tmp[4];
- if(info.has_range && (freq < KILO))
- channel = iw_channel_to_freq((int) freq, &freq, &info.range);
- iw_print_freq(buffer, sizeof(buffer), freq, -1, info.b.freq_flags);
- snprintf(tmp, 4, "%d", channel);
- add_table_entry(L, "channel", tmp);
- add_table_entry(L, "freq", buffer);
- }
-
- if(info.has_ap_addr)
- add_table_entry(L, "macap", iw_sawap_ntop(&info.ap_addr, buffer));
-
- if(info.has_bitrate)
- {
- iw_print_bitrate(buffer, sizeof(buffer), info.bitrate.value);
- add_table_entry(L, "bitrate", buffer);
- }
-
- if(info.has_txpower)
- {
- iw_print_txpower(buffer, sizeof(buffer), &info.txpower);
- add_table_entry(L, "txpower", buffer);
- }
- lua_settable(L, -3);
-}
-
-int iwc_getall(lua_State *L)
-{
- FILE *fp;
- char buffer[128];
- char *b = buffer;
- fp = fopen("/proc/net/wireless", "r");
- if(!fp)
- return -1;
- fgets(buffer, 128, fp);
- fgets(buffer, 128, fp);
- lua_newtable(L);
- while(fgets(buffer, 128, fp))
- {
- char *t;
- b = buffer;
- while(*b == ' ')
- b++;
- t = strstr(b, ":");
- if(t)
- *t = '\0';
- iwc_get(L, b);
- }
- return 1;
-}
-
-/* taken from wireless tools */
-int iwc_set_essid(lua_State *L)
-{
- struct iwreq wrq;
- int i = 1;
- char essid[IW_ESSID_MAX_SIZE + 1];
- int we_kernel_version;
- char *ifname, *e;
- if(lua_gettop(L) != 2)
- {
- lua_pushstring(L, "invalid arg list");
- lua_error(L);
- return 0;
- }
- ifname = (char *)lua_tostring (L, 1);
- e = (char *)lua_tostring (L, 2);
-
- if((!strcasecmp(e, "off")) | (!strcasecmp(e, "any")))
- {
- wrq.u.essid.flags = 0;
- essid[0] = '\0';
- } else if(!strcasecmp(e, "on"))
- {
- /* Get old essid */
- memset(essid, '\0', sizeof(essid));
- wrq.u.essid.pointer = (caddr_t) essid;
- wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
- wrq.u.essid.flags = 0;
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWESSID, &wrq) < 0)
- return 0;
- wrq.u.essid.flags = 1;
- } else {
- wrq.u.essid.flags = 1;
- strcpy(essid, e); /* Size checked, all clear */
- i++;
- }
-
- /* Get version from kernel, device may not have range... */
- we_kernel_version = iw_get_kernel_we_version();
-
- /* Finally set the ESSID value */
- wrq.u.essid.pointer = (caddr_t) essid;
- wrq.u.essid.length = strlen(essid);
- if(we_kernel_version < 21)
- wrq.u.essid.length++;
-
- if(!iw_set_ext(sock_iwconfig, ifname, SIOCSIWESSID, &wrq))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
- return 1;
-}
-
-/* taken from wireless tools */
-int iwc_set_mode(lua_State *L)
-{
- struct iwreq wrq;
- unsigned int k; /* Must be unsigned */
- char *ifname, *mode;
-
- if(lua_gettop(L) != 2)
- {
- lua_pushstring(L, "invalid arg list");
- lua_error(L);
- return 0;
- }
- ifname = (char *)lua_tostring (L, 1);
- mode = (char *)lua_tostring (L, 2);
-
- /* Check if it is a uint, otherwise get is as a string */
- if(sscanf(mode, "%ui", &k) != 1)
- {
- k = 0;
- while((k < IW_NUM_OPER_MODE) && strncasecmp(mode, iw_operation_mode[k], 3))
- k++;
- }
- if(k >= IW_NUM_OPER_MODE)
- return 0;
-
- wrq.u.mode = k;
- if(!iw_set_ext(sock_iwconfig, ifname, SIOCSIWMODE, &wrq))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
- return 1;
-}
-
-int iwc_set_channel(lua_State *L)
-{
- struct iwreq wrq;
- char *ifname;
- int channel;
- if(lua_gettop(L) != 2)
- {
- lua_pushstring(L, "invalid arg list");
- lua_error(L);
- return 0;
- }
- ifname = (char *)lua_tostring (L, 1);
- channel = (int)lua_tointeger(L, 2);
-
- if(channel == -1)
- {
- wrq.u.freq.m = -1;
- wrq.u.freq.e = 0;
- wrq.u.freq.flags = 0;
- } else {
- iw_float2freq(channel, &wrq.u.freq);
- wrq.u.freq.flags = IW_FREQ_FIXED;
- }
- if(!iw_set_ext(sock_iwconfig, ifname, SIOCSIWFREQ, &wrq))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
- return 1;
-}
-
-static const char * iw_ie_cypher_name[] = {
- "none",
- "WEP-40",
- "TKIP",
- "WRAP",
- "CCMP",
- "WEP-104",
-};
-#define IW_ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))
-#define IW_IE_CYPHER_NUM IW_ARRAY_LEN(iw_ie_cypher_name)
-
-static const char * iw_ie_key_mgmt_name[] = {
- "none",
- "802.1x",
- "PSK",
-};
-#define IW_IE_KEY_MGMT_NUM IW_ARRAY_LEN(iw_ie_key_mgmt_name)
-
-static inline void iw_print_ie_wpa(lua_State *L, unsigned char * iebuf, int buflen)
-{
- int ielen = iebuf[1] + 2;
- int offset = 2; /* Skip the IE id, and the length. */
- unsigned char wpa1_oui[3] = {0x00, 0x50, 0xf2};
- unsigned char wpa2_oui[3] = {0x00, 0x0f, 0xac};
- unsigned char *wpa_oui;
- int i;
- uint16_t ver = 0;
- uint16_t cnt = 0;
- int wpa1 = 0, wpa2 = 0;
- char buf[256];
- if(ielen > buflen)
- ielen = buflen;
-
- switch(iebuf[0])
- {
- case 0x30: /* WPA2 */
- /* Check if we have enough data */
- if(ielen < 4)
- return;
- wpa_oui = wpa2_oui;
- break;
-
- case 0xdd: /* WPA or else */
- wpa_oui = wpa1_oui;
- /* Not all IEs that start with 0xdd are WPA.
- * * So check that the OUI is valid. */
- if((ielen < 8)
- || ((memcmp(&iebuf[offset], wpa_oui, 3) != 0)
- && (iebuf[offset+3] == 0x01)))
- {
- return;
- }
-
- offset += 4;
- break;
-
- default:
- return;
- }
-
- /* Pick version number (little endian) */
- ver = iebuf[offset] | (iebuf[offset + 1] << 8);
- offset += 2;
-
- if(iebuf[0] == 0xdd)
- wpa1 = 1;
- if(iebuf[0] == 0x30)
- wpa2 = 1;
-
- if(ielen < (offset + 4))
- {
- if(wpa1)
- {
- add_table_entry(L, "wpa1gcipher", "TKIP");
- add_table_entry(L, "wpa1pcipher", "TKIP");
- } else {
- add_table_entry(L, "wpa2gcipher", "TKIP");
- add_table_entry(L, "wpa2pcipher", "TKIP");
- }
- return;
- }
-
- if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
- {
- if(wpa1)
- add_table_entry(L, "wpa1gcipher", "Proprietary");
- else
- add_table_entry(L, "wpa2gcipher", "Proprietary");
- } else {
- if(wpa1)
- add_table_entry(L, "wpa1gcipher", iebuf[offset+3][iw_ie_cypher_name]);
- else
- add_table_entry(L, "wpa2gcipher", iebuf[offset+3][iw_ie_cypher_name]);
- }
- offset += 4;
-
- if(ielen < (offset + 2))
- {
- if(wpa1)
- add_table_entry(L, "wpa1pcipher", "TKIP");
- else
- add_table_entry(L, "wpa2pcipher", "TKIP");
- return;
- }
- /* Otherwise, we have some number of pairwise ciphers. */
- cnt = iebuf[offset] | (iebuf[offset + 1] << 8);
- offset += 2;
- if(ielen < (offset + 4*cnt))
- return;
- *buf = '\0';
- for(i = 0; i < cnt; i++)
- {
- if(i > 0)
- strncat(buf, " ", 256);
- if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
- {
- strncat(buf, "Proprietary", 256);
- } else {
- if(iebuf[offset+3] <= IW_IE_CYPHER_NUM)
- strncat(buf, iw_ie_cypher_name[iebuf[offset+3]], 256);
- else
- strncat(buf, "unknown", 256);
- }
- offset+=4;
- }
- if(wpa1)
- add_table_entry(L, "wpa1pcipher", buf);
- else
- add_table_entry(L, "wpa2pcipher", buf);
-
- /* Check if we are done */
- if(ielen < (offset + 2))
- return;
-
- /* Now, we have authentication suites. */
- cnt = iebuf[offset] | (iebuf[offset + 1] << 8);
- offset += 2;
- *buf = '\0';
- if(ielen < (offset + 4*cnt))
- return;
-
- for(i = 0; i < cnt; i++)
- {
- if(i != 0)
- strncat(buf, " ", 256);
- if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
- {
- strncat(buf, "Proprietary", 256);
- } else {
- if(iebuf[offset+3] <= IW_IE_KEY_MGMT_NUM)
- strncat(buf, iw_ie_key_mgmt_name[iebuf[offset+3]], 256);
- else
- strncat(buf, "unknown", 256);
- }
- offset+=4;
- }
- if(wpa1)
- add_table_entry(L, "wpa1auth", buf);
- else
- add_table_entry(L, "wpa2auth", buf);
- /* Check if we are done */
- if(ielen < (offset + 1))
- return;
-}
-
-static inline void print_scanning_token(lua_State *L, struct stream_descr *stream,
- struct iw_event *event, struct iwscan_state *state, struct iw_range *iw_range, int has_range)
-{
- char buffer[128]; /* Temporary buffer */
-
- /* Now, let's decode the event */
- switch(event->cmd)
- {
- case SIOCGIWAP:
- add_table_entry(L, "addr", iw_saether_ntop(&event->u.ap_addr, buffer));
- state->ap_num++;
- break;
- case SIOCGIWFREQ:
- {
- double freq; /* Frequency/channel */
- int channel = -1; /* Converted to channel */
- freq = iw_freq2float(&(event->u.freq));
- /* Convert to channel if possible */
- if(has_range)
- channel = iw_freq_to_channel(freq, iw_range);
- snprintf(buffer, 128, "%1.3f", freq);
- add_table_entry(L, "frequency", buffer);
- snprintf(buffer, 128, "%d", channel);
- add_table_entry(L, "channel", buffer);
- //iw_print_freq(buffer, sizeof(buffer), freq, channel, event->u.freq.flags);
- //printf(" %s\n", buffer);
- }
- break;
- case SIOCGIWMODE:
- /* Note : event->u.mode is unsigned, no need to check <= 0 */
- if(event->u.mode >= IW_NUM_OPER_MODE)
- event->u.mode = IW_NUM_OPER_MODE;
- add_table_entry(L, "mode", iw_operation_mode[event->u.mode]);
- break;
- case SIOCGIWESSID:
- {
- char essid[IW_ESSID_MAX_SIZE+1];
- memset(essid, '\0', sizeof(essid));
- if((event->u.essid.pointer) && (event->u.essid.length))
- memcpy(essid, event->u.essid.pointer, event->u.essid.length);
- if(event->u.essid.flags)
- add_table_entry(L, "essid", essid);
- else
- add_table_entry(L, "essid", "off/any/hidden");
- }
- break;
- case SIOCGIWENCODE:
- {
- unsigned char key[IW_ENCODING_TOKEN_MAX];
- if(event->u.data.pointer)
- memcpy(key, event->u.data.pointer, event->u.data.length);
- else
- event->u.data.flags |= IW_ENCODE_NOKEY;
- if(event->u.data.flags & IW_ENCODE_DISABLED)
- {
- add_table_entry(L, "key", "off");
- } else {
- iw_print_key(buffer, sizeof(buffer), key, event->u.data.length,
- event->u.data.flags);
- add_table_entry(L, "key", buffer);
- }
- }
- break;
- case SIOCGIWRATE:
- if(state->val_index == 0)
- {
- lua_pushstring(L, "bitrates");
- lua_newtable(L);
- }
- //iw_print_bitrate(buffer, sizeof(buffer), event->u.bitrate.value);
- snprintf(buffer, sizeof(buffer), "%d", event->u.bitrate.value);
- lua_pushinteger(L, state->val_index + 1);
- lua_pushstring(L, buffer);
- lua_settable(L, -3);
-
- /* Check for termination */
- if(stream->value == NULL)
- {
- lua_settable(L, -3);
- state->val_index = 0;
- } else
- state->val_index++;
- break;
- case IWEVGENIE:
- {
- int offset = 0;
- unsigned char *buffer = event->u.data.pointer;
- int buflen = event->u.data.length;
- while(offset <= (buflen - 2))
- {
- switch(buffer[offset])
- {
- case 0xdd: /* WPA1 (and other) */
- case 0x30: /* WPA2 */
- iw_print_ie_wpa(L, buffer + offset, buflen);
- break;
- default:
- break;
- }
- offset += buffer[offset+1] + 2;
- }
- }
- break;
- default:
- break;
- } /* switch(event->cmd) */
-}
-
-int iwc_scan(lua_State *L)
-{
- struct iwreq wrq;
- struct iw_scan_req scanopt; /* Options for 'set' */
- int scanflags = 0; /* Flags for scan */
- unsigned char *buffer = NULL; /* Results */
- int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
- struct iw_range range;
- int has_range;
- struct timeval tv; /* Select timeout */
- int timeout = 15000000; /* 15s */
- char *ifname;
- if(lua_gettop(L) != 1)
- {
- lua_pushstring(L, "invalid arg list");
- lua_error(L);
- return 0;
- }
- ifname = (char *)lua_tostring (L, 1);
-
- /* Debugging stuff */
- if((IW_EV_LCP_PK2_LEN != IW_EV_LCP_PK_LEN) || (IW_EV_POINT_PK2_LEN != IW_EV_POINT_PK_LEN))
- {
- fprintf(stderr, "*** Please report to jt@hpl.hp.com your platform details\n");
- fprintf(stderr, "*** and the following line :\n");
- fprintf(stderr, "*** IW_EV_LCP_PK2_LEN = %zu ; IW_EV_POINT_PK2_LEN = %zu\n\n",
- IW_EV_LCP_PK2_LEN, IW_EV_POINT_PK2_LEN);
- }
-
- /* Get range stuff */
- has_range = (iw_get_range_info(sock_iwconfig, ifname, &range) >= 0);
-
- /* Check if the interface could support scanning. */
- if((!has_range) || (range.we_version_compiled < 14))
- {
- lua_pushstring(L, "interface does not support scanning");
- lua_error(L);
- return 0;
- }
-
- /* Init timeout value -> 250ms between set and first get */
- tv.tv_sec = 0;
- tv.tv_usec = 250000;
-
- /* Clean up set args */
- memset(&scanopt, 0, sizeof(scanopt));
-
- wrq.u.data.pointer = NULL;
- wrq.u.data.flags = 0;
- wrq.u.data.length = 0;
-
- /* Initiate Scanning */
- if(iw_set_ext(sock_iwconfig, ifname, SIOCSIWSCAN, &wrq) < 0)
- {
- if((errno != EPERM) || (scanflags != 0))
- {
- lua_pushstring(L, "interface does not support scanning");
- lua_error(L);
- return 0;
- }
- /* If we don't have the permission to initiate the scan, we may
- * * still have permission to read left-over results.
- * * But, don't wait !!! */
- #if 0
- /* Not cool, it display for non wireless interfaces... */
- fprintf(stderr, "%-8.16s (Could not trigger scanning, just reading left-over results)\n", ifname);
- #endif
- tv.tv_usec = 0;
- }
- timeout -= tv.tv_usec;
-
- /* Forever */
- while(1)
- {
- fd_set rfds; /* File descriptors for select */
- int last_fd; /* Last fd */
- int ret;
-
- /* Guess what ? We must re-generate rfds each time */
- FD_ZERO(&rfds);
- last_fd = -1;
- /* In here, add the rtnetlink fd in the list */
-
- /* Wait until something happens */
- ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
-
- /* Check if there was an error */
- if(ret < 0)
- {
- if(errno == EAGAIN || errno == EINTR)
- continue;
- lua_pushstring(L, "unhandled signal");
- lua_error(L);
- return 0;
- }
-
- /* Check if there was a timeout */
- if(ret == 0)
- {
- unsigned char * newbuf;
-
-realloc:
- /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
- newbuf = realloc(buffer, buflen);
- if(newbuf == NULL)
- {
- if(buffer)
- free(buffer);
- fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
- return 0;
- }
- buffer = newbuf;
-
- /* Try to read the results */
- wrq.u.data.pointer = buffer;
- wrq.u.data.flags = 0;
- wrq.u.data.length = buflen;
- if(iw_get_ext(sock_iwconfig, ifname, SIOCGIWSCAN, &wrq) < 0)
- {
- /* Check if buffer was too small (WE-17 only) */
- if((errno == E2BIG) && (range.we_version_compiled > 16))
- {
- /* Some driver may return very large scan results, either
- * because there are many cells, or because they have many
- * large elements in cells (like IWEVCUSTOM). Most will
- * only need the regular sized buffer. We now use a dynamic
- * allocation of the buffer to satisfy everybody. Of course,
- * as we don't know in advance the size of the array, we try
- * various increasing sizes. Jean II */
-
- /* Check if the driver gave us any hints. */
- if(wrq.u.data.length > buflen)
- buflen = wrq.u.data.length;
- else
- buflen *= 2;
-
- /* Try again */
- goto realloc;
- }
-
- /* Check if results not available yet */
- if(errno == EAGAIN)
- {
- /* Restart timer for only 100ms*/
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- timeout -= tv.tv_usec;
- if(timeout > 0)
- continue; /* Try again later */
- }
-
- /* Bad error */
- free(buffer);
- fprintf(stderr, "%-8.16s Failed to read scan data : %s\n\n",
- ifname, strerror(errno));
- return 0;
- } else
- /* We have the results, go to process them */
- break;
- }
-
- /* In here, check if event and event type
- * * if scan event, read results. All errors bad & no reset timeout */
- }
-
- if(wrq.u.data.length)
- {
- struct iw_event iwe;
- struct stream_descr stream;
- struct iwscan_state state = { .ap_num = 1, .val_index = 0 };
- int ret;
- int table = 0;
- iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
- lua_newtable(L);
- do
- {
- /* Extract an event and print it */
- ret = iw_extract_event_stream(&stream, &iwe,
- range.we_version_compiled);
- if(ret > 0)
- {
- if(iwe.cmd == SIOCGIWAP)
- {
- if(table)
- lua_settable(L, -3);
- table = 1;
- lua_pushinteger(L, state.ap_num);
- lua_newtable(L);
- }
- print_scanning_token(L, &stream, &iwe, &state, &range, has_range);
- }
- } while(ret > 0);
- lua_settable(L, -3);
- free(buffer);
- return 1;
- }
- free(buffer);
- return 0;
-}
-
-int iwc_frequencies(lua_State *L)
-{
- int i;
- int has_range;
- char *ifname;
- struct iw_range range;
-
- if(lua_gettop(L) != 1)
- {
- lua_pushstring(L, "invalid arg list");
- lua_error(L);
- return 0;
- }
-
- ifname = (char *)lua_tostring (L, 1);
-
- /* Get range stuff */
- has_range = (iw_get_range_info(sock_iwconfig, ifname, &range) >= 0);
-
- /* Check if the interface could support scanning. */
- if((!has_range) || (range.we_version_compiled < 14))
- {
- lua_pushstring(L, "interface does not support frequency enumeration");
- lua_error(L);
- }
- else
- {
- lua_newtable(L);
-
- for(i = 0; i < range.num_frequency; i++)
- {
- lua_pushnumber(L, i + 1);
- lua_newtable(L);
-
- lua_pushinteger(L, 1);
- lua_pushinteger(L, (int)range.freq[i].i);
- lua_settable(L, -3);
-
- lua_pushinteger(L, 2);
- lua_pushnumber(L, iw_freq2float(&(range.freq[i])));
- lua_settable(L, -3);
-
- lua_settable(L, -3);
- }
-
- return 1;
- }
-
- return 0;
-}