summaryrefslogtreecommitdiffhomepage
path: root/libs/luanet
diff options
context:
space:
mode:
Diffstat (limited to 'libs/luanet')
-rw-r--r--libs/luanet/Makefile18
-rw-r--r--libs/luanet/src/Makefile18
-rw-r--r--libs/luanet/src/base64.c121
-rw-r--r--libs/luanet/src/base64.h23
-rw-r--r--libs/luanet/src/bridge.c171
-rw-r--r--libs/luanet/src/bridge.h27
-rw-r--r--libs/luanet/src/df.c122
-rw-r--r--libs/luanet/src/df.h23
-rw-r--r--libs/luanet/src/helper.c73
-rw-r--r--libs/luanet/src/helper.h31
-rw-r--r--libs/luanet/src/ifconfig.c250
-rw-r--r--libs/luanet/src/ifconfig.h30
-rw-r--r--libs/luanet/src/iwconfig.c829
-rw-r--r--libs/luanet/src/iwconfig.h28
-rw-r--r--libs/luanet/src/main.c95
-rw-r--r--libs/luanet/src/route.c45
-rw-r--r--libs/luanet/src/route.h21
-rwxr-xr-xlibs/luanet/src/test.lua132
-rw-r--r--libs/luanet/src/vconfig.c93
-rw-r--r--libs/luanet/src/vconfig.h27
20 files changed, 2177 insertions, 0 deletions
diff --git a/libs/luanet/Makefile b/libs/luanet/Makefile
new file mode 100644
index 000000000..702f866b0
--- /dev/null
+++ b/libs/luanet/Makefile
@@ -0,0 +1,18 @@
+ifeq ($(CFLAGS),)
+ MYLDFLAGS ?= -L../../../contrib/uci/dist/usr/lib/
+endif
+
+include ../../build/module.mk
+include ../../build/config.mk
+include ../../build/gccconfig.mk
+
+compile:
+ make -Csrc \
+ CFLAGS="$(CFLAGS) $(FPIC) $(LUA_CFLAGS) $(EXTRA_CFLAGS)" \
+ LDFLAGS="$(LDFLAGS)" \
+ MYLDFLAGS="$(MYLDFLAGS)"
+ mkdir -p dist/usr/lib/lua/
+ cp src/luanet.so dist/usr/lib/lua
+
+clean: luaclean
+ make -Csrc clean
diff --git a/libs/luanet/src/Makefile b/libs/luanet/src/Makefile
new file mode 100644
index 000000000..852a7c4f4
--- /dev/null
+++ b/libs/luanet/src/Makefile
@@ -0,0 +1,18 @@
+PROGS=luanet.so
+STRIP?=strip
+CFLAGS?=
+CFLAGS+=-pedantic -Werror -Wall -I/usr/include/lua5.1/ -std=gnu99
+LDFLAGS?=
+LDFLAGS+=
+OBJS=ifconfig.o bridge.o iwconfig.o helper.o route.o vconfig.o main.o df.o base64.o
+
+all: $(PROGS)
+
+$(PROGS): $(OBJS)
+ $(CC) $(CFLAGS) -shared -Wl,-soname,luanet -liw $(LDFLAGS) $^ -o $@
+
+clean:
+ rm -f $(PROGS) *.o *.so
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $^ -o $@
diff --git a/libs/luanet/src/base64.c b/libs/luanet/src/base64.c
new file mode 100644
index 000000000..f897cf7aa
--- /dev/null
+++ b/libs/luanet/src/base64.c
@@ -0,0 +1,121 @@
+/*
+ * Base64.c
+ * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+
+unsigned char map2[] =
+{
+ 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
+};
+
+int b64_decode(lua_State *L)
+{
+ int i, v;
+ unsigned char out[512];
+ unsigned char *dst = out;
+ char *in;
+ if(lua_gettop(L) != 1)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ in = (char *)lua_tostring (L, 1);
+ v = 0;
+ for (i = 0; in[i] && in[i] != '='; i++) {
+ unsigned int index= in[i]-43;
+ if (index>=(sizeof(map2)/sizeof(map2[0])) || map2[index] == 0xff)
+ return -1;
+ v = (v << 6) + map2[index];
+ if (i & 3) {
+ if (dst - out < 512) {
+ *dst++ = v >> (6 - 2 * (i & 3));
+ }
+ }
+ }
+ if(!(dst - out))
+ return 0;
+ lua_pushstring(L, (char*)out);
+ return 1;
+}
+
+/*****************************************************************************
+* b64_encode: stolen from VLC's http.c
+* simplified by michael
+* fixed edge cases and made it work from data (vs. strings) by ryan.
+*****************************************************************************/
+
+int b64_encode(lua_State *L)
+{
+ static const char b64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ char *ret, *dst, *src, tmp[1024];
+ unsigned i_bits = 0;
+ int i_shift = 0;
+ int bytes_remaining, len;
+ if(lua_gettop(L) != 1)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ src = (char *)lua_tostring (L, 1);
+ bytes_remaining = len = strlen(src);
+ if (len < 512) {
+ ret = dst = tmp;
+ } else
+ return 0;
+
+ if (len) { // special edge case, what should we really do here?
+ while (bytes_remaining) {
+ i_bits = (i_bits << 8) + *src++;
+ bytes_remaining--;
+ i_shift += 8;
+
+ do {
+ *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
+ i_shift -= 6;
+ } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0));
+ }
+ while ((dst - ret) & 3)
+ *dst++ = '=';
+ }
+ *dst = '\0';
+ lua_pushstring(L, tmp);
+ return 1;
+}
diff --git a/libs/luanet/src/base64.h b/libs/luanet/src/base64.h
new file mode 100644
index 000000000..e32365f8d
--- /dev/null
+++ b/libs/luanet/src/base64.h
@@ -0,0 +1,23 @@
+/*
+ * Base64.c
+ * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+int b64_decode(lua_State *L);
+int b64_encode(lua_State *L);
diff --git a/libs/luanet/src/bridge.c b/libs/luanet/src/bridge.c
new file mode 100644
index 000000000..478f8b14f
--- /dev/null
+++ b/libs/luanet/src/bridge.c
@@ -0,0 +1,171 @@
+/*
+ * 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>
+ */
+
+#include <string.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+static int sock_bridge = 0;
+int bridge_startup()
+{
+ if(!sock_bridge)
+ sock_bridge = socket(AF_LOCAL, SOCK_STREAM, 0);
+ return sock_bridge;
+}
+
+void bridge_shutdown(void)
+{
+ if(!sock_bridge)
+ return;
+ close(sock_bridge);
+ sock_bridge = 0;
+}
+
+static inline int _bridge_new(lua_State *L, int i)
+{
+ char *ifname;
+ if(lua_gettop(L) != 1)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+
+ ifname = (char *)lua_tostring (L, 1);
+ if(!ioctl(sock_bridge, i, ifname))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+int bridge_new(lua_State *L)
+{
+ return _bridge_new(L, SIOCBRADDBR);
+}
+
+int bridge_del(lua_State *L)
+{
+ return _bridge_new(L, SIOCBRDELBR);
+}
+
+static inline int _bridge_addif(lua_State *L, int i)
+{
+ struct ifreq ifr;
+ char *br, *ifname;
+ if(lua_gettop(L) != 2)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ br = (char *)lua_tostring (L, 1);
+ ifname = (char *)lua_tostring (L, 2);
+ strncpy(ifr.ifr_name, br, IFNAMSIZ);
+ ifr.ifr_ifindex = if_nametoindex(ifname);
+ if(ifr.ifr_ifindex == 0)
+ {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+ if(!ioctl(sock_bridge, i, &ifr))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+int bridge_addif(lua_State *L)
+{
+ return _bridge_addif(L, SIOCBRADDIF);
+}
+
+int bridge_delif(lua_State *L)
+{
+ return _bridge_addif(L, SIOCBRDELIF);
+}
+
+#define SYSFS_PATH_MAX 512
+#define SYSFS_CLASS_NET "/sys/class/net/"
+static int isbridge(const struct dirent *entry)
+{
+ char path[SYSFS_PATH_MAX];
+ struct stat st;
+
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/bridge", entry->d_name);
+ return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
+}
+
+static int isdev(const struct dirent *entry)
+{
+ if(*entry->d_name == '.')
+ return 0;
+ return 1;
+}
+
+static inline void bridge_getifs(lua_State *L, const char *ifname)
+{
+ struct dirent **namelist;
+ int i, count = 0;
+ char path[SYSFS_PATH_MAX];
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brif", ifname);
+ count = scandir(path, &namelist, isdev, alphasort);
+ if(count < 0)
+ return;
+
+ for(i = 0; i < count; i++)
+ {
+ lua_pushinteger(L, i + 1);
+ lua_pushstring(L, namelist[i]->d_name);
+ lua_settable(L, -3);
+ free(namelist[i]);
+ }
+ free(namelist);
+ return;
+}
+
+int bridge_getall(lua_State *L)
+{
+ struct dirent **namelist;
+ int i, count = 0;
+ count = scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
+ if (count < 0)
+ return 0;
+
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushstring(L, namelist[i]->d_name);
+ lua_newtable(L);
+ bridge_getifs(L, namelist[i]->d_name);
+ free(namelist[i]);
+ lua_settable(L, -3);
+ }
+ free(namelist);
+ return 1;
+}
diff --git a/libs/luanet/src/bridge.h b/libs/luanet/src/bridge.h
new file mode 100644
index 000000000..87202f64f
--- /dev/null
+++ b/libs/luanet/src/bridge.h
@@ -0,0 +1,27 @@
+/*
+ * 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>
+ */
+
+#ifndef _BRIDGE_H__
+#define _BRIDGE_H__
+int bridge_startup(void);
+void bridge_shutdown(void);
+int bridge_new(lua_State *L);
+int bridge_del(lua_State *L);
+int bridge_addif(lua_State *L);
+int bridge_delif(lua_State *L);
+int bridge_getall(lua_State *L);
+#endif
diff --git a/libs/luanet/src/df.c b/libs/luanet/src/df.c
new file mode 100644
index 000000000..be582f6ef
--- /dev/null
+++ b/libs/luanet/src/df.c
@@ -0,0 +1,122 @@
+/* based on busybox code */
+#include <stdio.h>
+#include <string.h>
+#include <mntent.h>
+#include <sys/vfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "helper.h"
+
+struct mntent *find_mount_point(const char *name, const char *table)
+{
+ struct stat s;
+ dev_t mountDevice;
+ FILE *mountTable;
+ struct mntent *mountEntry;
+
+ if (stat(name, &s) != 0)
+ return 0;
+
+ if ((s.st_mode & S_IFMT) == S_IFBLK)
+ mountDevice = s.st_rdev;
+ else
+ mountDevice = s.st_dev;
+
+
+ mountTable = setmntent(table ? table : "/etc/mtab", "r");
+ if (!mountTable)
+ return 0;
+
+ while ((mountEntry = getmntent(mountTable)) != 0) {
+ if (strcmp(name, mountEntry->mnt_dir) == 0
+ || strcmp(name, mountEntry->mnt_fsname) == 0
+ ) { /* String match. */
+ break;
+ }
+ if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */
+ break;
+ if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */
+ break;
+ }
+ endmntent(mountTable);
+ return mountEntry;
+}
+
+static unsigned long kscale(unsigned long b, unsigned long bs)
+{
+ return (b * (unsigned long long) bs + 1024/2) / 1024;
+}
+
+int df(lua_State *L)
+{
+ unsigned long blocks_used;
+ unsigned blocks_percent_used;
+ FILE *mount_table;
+ struct mntent *mount_entry = 0;
+ struct statfs s;
+ /* default display is kilobytes */
+ const char *disp_units_hdr = "1k-blocks";
+ int cnt = 0;
+ printf("Filesystem %-15sUsed Available Use%% Mounted on\n",
+ disp_units_hdr);
+
+ mount_table = NULL;
+ mount_table = setmntent("/etc/mtab", "r");
+ lua_newtable(L);
+ while (1) {
+ const char *device;
+ const char *mount_point;
+
+ if (mount_table) {
+ mount_entry = getmntent(mount_table);
+ if (!mount_entry) {
+ endmntent(mount_table);
+ break;
+ }
+ }
+
+ device = mount_entry->mnt_fsname;
+ mount_point = mount_entry->mnt_dir;
+
+ if (statfs(mount_point, &s) != 0) {
+ perror(mount_point);
+ continue;
+ }
+
+ if ((s.f_blocks > 0) || !mount_table)
+ {
+ blocks_used = s.f_blocks - s.f_bfree;
+ blocks_percent_used = 0;
+ if (blocks_used + s.f_bavail)
+ {
+ blocks_percent_used = (blocks_used * 100ULL + (blocks_used + s.f_bavail) / 2 )
+ / (blocks_used + s.f_bavail);
+ }
+ lua_pushinteger(L, ++cnt);
+ lua_newtable(L);
+
+ add_table_entry_int(L, "blocks", kscale(s.f_blocks, s.f_bsize));
+ add_table_entry_int(L, "used", kscale(s.f_blocks-s.f_bfree, s.f_bsize));
+ add_table_entry_int(L, "avail", kscale(s.f_bavail, s.f_bsize));
+ add_table_entry_int(L, "percent", blocks_percent_used);
+ add_table_entry(L, "device", device);
+ add_table_entry(L, "mountpoint", mount_point);
+ add_table_entry_int(L, "blocksize", s.f_bsize);
+ lua_settable(L, -3);
+
+ /*printf("\n%-20s" + 1, device)
+ printf(" %9lu %9lu %9lu %3u%% %s\n",
+ kscale(s.f_blocks, s.f_bsize),
+ kscale(s.f_blocks-s.f_bfree, s.f_bsize),
+ kscale(s.f_bavail, s.f_bsize),
+ blocks_percent_used, mount_point);*/
+ }
+ }
+ return 1;
+}
diff --git a/libs/luanet/src/df.h b/libs/luanet/src/df.h
new file mode 100644
index 000000000..7fe3f6e43
--- /dev/null
+++ b/libs/luanet/src/df.h
@@ -0,0 +1,23 @@
+/*
+ * 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>
+ */
+
+#ifndef _DF_H__
+#define _DF_H__
+
+int df(lua_State *L);
+
+#endif
diff --git a/libs/luanet/src/helper.c b/libs/luanet/src/helper.c
new file mode 100644
index 000000000..57679925b
--- /dev/null
+++ b/libs/luanet/src/helper.c
@@ -0,0 +1,73 @@
+/*
+ * 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>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+int char2ipv4(char *c, char *ip)
+{
+ int i;
+ char *tmp = strdup(c);
+ char *t = tmp;
+ char *e = NULL;
+ int ret = -1;
+ for(i = 0; i < 4; i++)
+ {
+ int j = strtol(t, &e, 10);
+ if((j < 0) || (j > 255))
+ goto error;
+ if(i != 3)
+ if(*e != '.')
+ goto error;
+ *ip++ = j;
+ t = e + 1;
+ }
+ ret = 0;
+error:
+ free(tmp);
+ return ret;
+}
+
+void ipv42char(char *b, char *ip)
+{
+ sprintf(ip, "%d.%d.%d.%d", b[0] & 0xff, b[1] & 0xff, b[2] & 0xff, b[3] & 0xff);
+}
+
+void mac2char(char *b, char *mac)
+{
+ sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
+ b[0] & 0xff, b[1] & 0xff, b[2] & 0xff, b[3] & 0xff, b[4] & 0xff, b[5] & 0xff);
+}
+
+void add_table_entry(lua_State *L, const char *k, const char *v)
+{
+ lua_pushstring(L, k);
+ lua_pushstring(L, v);
+ lua_settable(L, -3);
+}
+
+void add_table_entry_int(lua_State *L, const char *k, int v)
+{
+ lua_pushstring(L, k);
+ lua_pushinteger(L, v);
+ lua_settable(L, -3);
+}
diff --git a/libs/luanet/src/helper.h b/libs/luanet/src/helper.h
new file mode 100644
index 000000000..dec55529b
--- /dev/null
+++ b/libs/luanet/src/helper.h
@@ -0,0 +1,31 @@
+/*
+ * 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>
+ */
+
+#ifndef _HELPER_H__
+#define _HELPER_H__
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+int char2ipv4(char *c, char *ip);
+void ipv42char(char *b, char *ip);
+void mac2char(char *b, char *mac);
+void add_table_entry(lua_State *L, const char *k, const char *v);
+void add_table_entry_int(lua_State *L, const char *k, int v);
+
+#endif
diff --git a/libs/luanet/src/ifconfig.c b/libs/luanet/src/ifconfig.c
new file mode 100644
index 000000000..58ce45e90
--- /dev/null
+++ b/libs/luanet/src/ifconfig.c
@@ -0,0 +1,250 @@
+/*
+ * 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>
+ */
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/sockios.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "helper.h"
+
+int sock_ifconfig = 0;
+
+int ifc_startup(void)
+{
+ if(!sock_ifconfig)
+ sock_ifconfig = socket(AF_INET, SOCK_DGRAM, 0);
+ return sock_ifconfig;
+}
+
+void ifc_shutdown(void)
+{
+ if(!sock_ifconfig)
+ return;
+ close(sock_ifconfig);
+ sock_ifconfig = 0;
+}
+
+static int isdev(const struct dirent *entry)
+{
+ if(*entry->d_name == '.')
+ return 0;
+ return 1;
+}
+
+static void ifc_addif(lua_State *L, char *ifname)
+{
+ char *ip = malloc(32);
+ struct ifreq ifr;
+ lua_pushstring(L, ifname);
+ lua_newtable(L);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if(!ioctl(sock_ifconfig, SIOCGIFADDR, &ifr))
+ {
+ ipv42char(&ifr.ifr_addr.sa_data[2], ip);
+ add_table_entry(L, "ip", ip);
+ }
+
+ if(!ioctl(sock_ifconfig, SIOCGIFNETMASK, &ifr))
+ {
+ ipv42char(&ifr.ifr_netmask.sa_data[2], ip);
+ add_table_entry(L, "netmask", ip);
+ }
+
+ if(!ioctl(sock_ifconfig, SIOCGIFBRDADDR, &ifr))
+ {
+ ipv42char(&ifr.ifr_broadaddr.sa_data[2], ip);
+ add_table_entry(L, "broadaddr", ip);
+ }
+
+ if(!ioctl(sock_ifconfig, SIOCGIFHWADDR, &ifr))
+ {
+ mac2char(ifr.ifr_hwaddr.sa_data, ip);
+ add_table_entry(L, "mac", ip);
+ }
+
+ if(!ioctl(sock_ifconfig, SIOCGIFFLAGS, &ifr))
+ {
+ if(ifr.ifr_flags & IFF_UP)
+ add_table_entry(L, "up", "1");
+ else
+ add_table_entry(L, "up", "0");
+ }
+
+ ioctl(sock_ifconfig, SIOCGIFMTU, &ifr);
+ lua_pushstring(L, "mtu");
+ lua_pushinteger(L, ifr.ifr_mtu);
+ lua_settable(L, -3);
+ free(ip);
+ lua_settable(L, -3);
+}
+
+#define SYSFS_CLASS_NET "/sys/class/net/"
+int ifc_getall(lua_State *L)
+{
+ int numreqs = 50;
+ struct dirent **namelist;
+ int i, count = 0;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ ifc.ifc_buf = NULL;
+ count = scandir(SYSFS_CLASS_NET, &namelist, isdev, alphasort);
+ if (count < 0)
+ {
+ return 0;
+ }
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ ifc_addif(L, namelist[i]->d_name);
+ free(namelist[i]);
+ }
+ free(namelist);
+
+ ifc.ifc_len = sizeof(struct ifreq) * numreqs;
+ ifc.ifc_buf = malloc(ifc.ifc_len);
+ if(ioctl(sock_ifconfig, SIOCGIFCONF, &ifc) < 0)
+ goto out;
+ ifr = ifc.ifc_req;
+ for(i = 0; i < ifc.ifc_len; i += sizeof(struct ifreq))
+ {
+ if(strchr(ifr->ifr_name, ':'))
+ ifc_addif(L, ifr->ifr_name);
+ ifr++;
+ }
+out:
+ free(ifc.ifc_buf);
+ return 1;
+}
+
+static inline int _ifc_setip(lua_State *L, int i)
+{
+ struct ifreq ifr;
+ char *ifname, *ip;
+ if(lua_gettop(L) != 2)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ ifname = (char *)lua_tostring (L, 1);
+ ip = (char *)lua_tostring (L, 2);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ ifr.ifr_addr.sa_family = AF_INET;
+ if(char2ipv4(ip, &ifr.ifr_addr.sa_data[2]))
+ {
+ lua_pushstring(L, "invalid ip");
+ lua_error(L);
+ return 0;
+ }
+ if(!ioctl(sock_ifconfig, i, &ifr))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+int ifc_setip(lua_State *L)
+{
+ return _ifc_setip(L, SIOCSIFADDR);
+}
+
+int ifc_setnetmask(lua_State *L)
+{
+ return _ifc_setip(L, SIOCGIFNETMASK);
+}
+
+int ifc_setbroadcast(lua_State *L)
+{
+ return _ifc_setip(L, SIOCSIFBRDADDR);
+}
+
+int ifc_setmtu(lua_State *L)
+{
+ struct ifreq ifr;
+ char *ifname;
+ int mtu;
+ if(lua_gettop(L) != 2)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ ifname = (char *)lua_tostring (L, 1);
+ mtu = (int)lua_tointeger (L, 2);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ ifr.ifr_mtu = mtu;
+ if(!ioctl(sock_ifconfig, SIOCSIFMTU, &ifr))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+static int _ifc_up(lua_State *L, int up)
+{
+ struct ifreq ifr;
+ char *ifname;
+ if(lua_gettop(L) != 1)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+
+ ifname = (char *)lua_tostring (L, 1);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if(ioctl(sock_ifconfig, SIOCGIFFLAGS, &ifr) < 0)
+ {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+ if(up)
+ ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+ else
+ ifr.ifr_flags &= ~IFF_UP;
+ if(!ioctl(sock_ifconfig, SIOCSIFFLAGS, &ifr))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+int ifc_up(lua_State *L)
+{
+ return _ifc_up(L, 1);
+}
+
+int ifc_down(lua_State *L)
+{
+ return _ifc_up(L, 0);
+}
+
diff --git a/libs/luanet/src/ifconfig.h b/libs/luanet/src/ifconfig.h
new file mode 100644
index 000000000..dffffd583
--- /dev/null
+++ b/libs/luanet/src/ifconfig.h
@@ -0,0 +1,30 @@
+/*
+ * 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>
+ */
+
+#ifndef _IFCONFIG_H__
+#define _IFCONFIG_H__
+int ifc_startup(void);
+void ifc_shutdown(void);
+
+int ifc_getall(lua_State *L);
+int ifc_setip(lua_State *L);
+int ifc_setnetmask(lua_State *L);
+int ifc_setbroadcast(lua_State *L);
+int ifc_setmtu(lua_State *L);
+int ifc_up(lua_State *L);
+int ifc_down(lua_State *L);
+#endif
diff --git a/libs/luanet/src/iwconfig.c b/libs/luanet/src/iwconfig.c
new file mode 100644
index 000000000..5fc65b607
--- /dev/null
+++ b/libs/luanet/src/iwconfig.c
@@ -0,0 +1,829 @@
+/*
+ * 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>
+ */
+
+#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;
+}
diff --git a/libs/luanet/src/iwconfig.h b/libs/luanet/src/iwconfig.h
new file mode 100644
index 000000000..59240d570
--- /dev/null
+++ b/libs/luanet/src/iwconfig.h
@@ -0,0 +1,28 @@
+/*
+ * 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>
+ */
+
+#ifndef _IWCONFIG_H__
+#define _IWCONFIG_H__
+int iwc_startup(void);
+void iwc_shutdown(void);
+int iwc_get(lua_State *L);
+int iwc_getall(lua_State *L);
+int iwc_set_essid(lua_State *L);
+int iwc_set_mode(lua_State *L);
+int iwc_set_channel(lua_State *L);
+int iwc_scan(lua_State *L);
+#endif
diff --git a/libs/luanet/src/main.c b/libs/luanet/src/main.c
new file mode 100644
index 000000000..0a42276cb
--- /dev/null
+++ b/libs/luanet/src/main.c
@@ -0,0 +1,95 @@
+/*
+ * 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>
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "route.h"
+#include "bridge.h"
+#include "ifconfig.h"
+#include "iwconfig.h"
+#include "vconfig.h"
+#include "df.h"
+#include "base64.h"
+
+int psleep(lua_State *L)
+{
+ int s;
+ if(lua_gettop(L) != 1)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+
+ s = (int)lua_tointeger (L, 1);
+ sleep(s);
+ return 0;
+}
+
+static luaL_reg func[] = {
+ {"ifc_getall", ifc_getall},
+ {"ifc_setip", ifc_setip},
+ {"ifc_setnetmask", ifc_setnetmask},
+ {"ifc_setbroadcast", ifc_setbroadcast},
+ {"ifc_setmtu", ifc_setmtu},
+ {"ifc_up", ifc_up},
+ {"ifc_down", ifc_down},
+ {"bridge_getall", bridge_getall},
+ {"bridge_new", bridge_new},
+ {"bridge_del", bridge_del},
+ {"bridge_addif", bridge_addif},
+ {"bridge_delif", bridge_delif},
+ {"iwc_getall", iwc_getall},
+ {"iwc_set_essid", iwc_set_essid},
+ {"iwc_set_mode", iwc_set_mode},
+ {"iwc_set_channel", iwc_set_channel},
+ {"iwc_scan", iwc_scan},
+ {"vlan_getall", vlan_getall},
+ {"vlan_add", vlan_add},
+ {"vlan_del", vlan_del},
+ {"df", df},
+ {"b64_encode", b64_encode},
+ {"b64_decode", b64_decode},
+ {"sleep", psleep},
+ {NULL, NULL}
+};
+
+int luaopen_luanet(lua_State *L)
+{
+ ifc_startup();
+ bridge_startup();
+ iwc_startup();
+ luaL_openlib(L, "luanet", func, 0);
+ lua_pushstring(L, "_VERSION");
+ lua_pushstring(L, "1.0");
+ lua_rawset(L, -3);
+ return 1;
+}
+
+int luaclose_luanet(lua_State *L)
+{
+ ifc_shutdown();
+ bridge_shutdown();
+ iwc_shutdown();
+ lua_pushstring(L, "Called");
+ return 1;
+}
diff --git a/libs/luanet/src/route.c b/libs/luanet/src/route.c
new file mode 100644
index 000000000..1690b74b7
--- /dev/null
+++ b/libs/luanet/src/route.c
@@ -0,0 +1,45 @@
+/*
+ * 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>
+ */
+
+#include <linux/sockios.h>
+#include <net/route.h>
+#include <sys/ioctl.h>
+
+#include "helper.h"
+
+extern int sock_ifconfig;
+
+int route_add(char *dev, int flag_gateway, int flag_host, char *dst, char *gateway, char *mask)
+{
+ struct rtentry r;
+ char ip[4];
+ r.rt_flags = RTF_UP;
+ if(flag_gateway)
+ r.rt_flags |= RTF_GATEWAY;
+ if(flag_host)
+ r.rt_flags |= RTF_HOST;
+ r.rt_dst.sa_family = AF_INET;
+ r.rt_gateway.sa_family = AF_INET;
+ r.rt_genmask.sa_family = AF_INET;
+ char2ipv4(dst, ip);
+ ((struct sockaddr_in *) &r.rt_dst)->sin_addr.s_addr = (unsigned int)ip;
+ char2ipv4(gateway, ip);
+ ((struct sockaddr_in *) &r.rt_gateway)->sin_addr.s_addr = (unsigned int)ip;
+ char2ipv4(mask, ip);
+ ((struct sockaddr_in *) &r.rt_genmask)->sin_addr.s_addr = (unsigned int)ip;
+ return ioctl(sock_ifconfig, SIOCADDRT, (void *) &r);
+}
diff --git a/libs/luanet/src/route.h b/libs/luanet/src/route.h
new file mode 100644
index 000000000..53f6e98b9
--- /dev/null
+++ b/libs/luanet/src/route.h
@@ -0,0 +1,21 @@
+/*
+ * 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>
+ */
+
+#ifndef _ROUTE_H__
+#define _ROUTE_H__
+int route_add(char *dev, int flag_gateway, int flag_host, char *dst, char *gateway, char *mask);
+#endif
diff --git a/libs/luanet/src/test.lua b/libs/luanet/src/test.lua
new file mode 100755
index 000000000..713836b55
--- /dev/null
+++ b/libs/luanet/src/test.lua
@@ -0,0 +1,132 @@
+#!/usr/bin/lua
+
+print("luanet test")
+local luanet = require("luanet")
+
+print("sleeping 4 secs")
+luanet.sleep(4)
+
+print("---ifconfig---\n")
+print("set ip wlan0 -> 192.168.1.2")
+print(luanet.ifc_setip("wlan0", "192.168.1.2"))
+print("set ip wlan0:1 -> 192.168.2.2")
+print(luanet.ifc_setip("wlan0:1", "192.168.2.2"))
+print("set mtu wlan0 -> 1400")
+print(luanet.ifc_setmtu("wlan0", "1400"))
+--print("set down wlan0 ->")
+--print(luanet.ifc_down("wlan0"))
+--print("set up wlan0 ->")
+--print(luanet.ifc_up("wlan0"))
+local devs = luanet.ifc_getall()
+for i,v in pairs(devs) do
+ print("\ndev -> "..i)
+ print(devs[i].ip)
+ print(devs[i].netmask)
+ print(devs[i].broadaddr)
+ print(devs[i].mac)
+ print(devs[i].mtu)
+ print(devs[i].up)
+end
+
+
+print("\n\n---bridge---\n")
+print("add bridge br-test ->")
+print(luanet.bridge_new("br-test"))
+
+print("add wlan0 to br-test ->")
+print(luanet.bridge_addif("br-test", "wlan0"))
+
+print("listing bridges")
+local brs = luanet.bridge_getall()
+if brs then
+ for i,v in pairs(brs) do
+ print(i)
+ for j,k in pairs(v) do
+ print(j.."->"..k)
+ end
+ end
+end
+print("del wlan0 from br-test ->")
+print(luanet.bridge_delif("br-test", "wlan0"))
+
+print("del bridge br-test ->")
+print(luanet.bridge_del("br-test"))
+
+
+print("\n\n---wifi---\n")
+print("set wlan0 essid test123")
+print(luanet.iwc_set_essid("wlan0", "test123"))
+print("set wifi channel to 3")
+print(luanet.iwc_set_channel("wlan0", 3))
+print("set wifi to managed")
+print(luanet.iwc_set_mode("wlan0", "managed"))
+print("\nget all wifi devices")
+local wifidevs = luanet.iwc_getall()
+if wifidevs then
+ for i,v in pairs(wifidevs) do
+ print(i)
+ for j,k in pairs(v) do
+ print(" "..j.."->"..k)
+ end
+ end
+end
+local scan = luanet.iwc_scan("wlan0")
+print("\nscanning wifi on wlan0")
+if scan then
+ for i,v in pairs(scan) do
+ print("\n"..i)
+ print(" mac -> "..v.addr)
+ print(" frequency -> "..v.frequency)
+ print(" channel -> "..v.channel)
+ print(" mode -> "..v.mode)
+ print(" essid -> "..v.essid)
+ print(" key -> "..v.key)
+ print(" wpa1gcipher -> "..(v.wpa1gcipher or ""))
+ print(" wpa1pcipher -> "..(v.wpa1pcipher or ""))
+ print(" wpa1auth -> "..(v.wpa1auth or ""))
+ print(" wpa2gcipher -> "..(v.wpa2gcipher or ""))
+ print(" wpa2pcipher -> "..(v.wpa2pcipher or ""))
+ print(" wpa2auth -> "..(v.wpa2auth or ""))
+ print(" bitrates")
+ for j,k in ipairs(v.bitrates) do
+ --print(j.."->"..k)
+ end
+ end
+end
+
+
+print("\n\n---vlan---\n")
+print("add wlan0 to vlan0")
+print(luanet.vlan_add("wlan0", 0));
+print("add wlan0 to vlan1")
+print(luanet.vlan_add("wlan0", 1));
+print("del wlan0 from all vlans")
+print(luanet.vlan_del("wlan0.0"));
+print("add wlan0 to vlan6")
+print(luanet.vlan_add("wlan0", 6));
+local vlans = luanet.vlan_getall()
+if vlans then
+ for i,v in ipairs(vlans) do
+ print(i.."->"..v)
+ end
+end
+
+
+print("\n\n---df---\n")
+
+print("getting disc usage")
+local discs = luanet.df()
+if discs then
+ for i,v in ipairs(discs) do
+ print(i.."->")
+ for k,l in pairs(v) do
+ print(" "..k.."->"..l)
+ end
+ end
+end
+
+
+print("\n\n---b64---\n")
+print("test2 -->"..(luanet.b64_encode("test2") or "fail"))
+print("dGVzdDI= -->"..(luanet.b64_decode("dGVzdDI=") or "fail"))
+
diff --git a/libs/luanet/src/vconfig.c b/libs/luanet/src/vconfig.c
new file mode 100644
index 000000000..7adccc9a9
--- /dev/null
+++ b/libs/luanet/src/vconfig.c
@@ -0,0 +1,93 @@
+/*
+ * 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>
+ */
+
+#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 <linux/if_vlan.h>
+#include <iwlib.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+extern int sock_ifconfig;
+
+
+static inline int _vlan_add(lua_State *L, int i)
+{
+ struct vlan_ioctl_args ifr;
+ int a = (i == ADD_VLAN_CMD)?(2):(1);
+ char *ifname;
+ if(lua_gettop(L) != a)
+ {
+ lua_pushstring(L, "invalid arg list");
+ lua_error(L);
+ return 0;
+ }
+ ifname = (char *)lua_tostring (L, 1);
+ ifr.cmd = i;
+ if(i == ADD_VLAN_CMD)
+ ifr.u.VID = (int)lua_tointeger (L, 2);
+ strncpy(ifr.device1, ifname, IFNAMSIZ);
+ if(!ioctl(sock_ifconfig, SIOCSIFVLAN, &ifr))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+int vlan_add(lua_State *L)
+{
+ return _vlan_add(L, ADD_VLAN_CMD);
+}
+
+int vlan_del(lua_State *L)
+{
+ return _vlan_add(L, DEL_VLAN_CMD);
+}
+
+int vlan_getall(lua_State *L)
+{
+ struct dirent **namelist;
+ int n = 0, i, count = 0;
+ count = scandir("/proc/net/vlan/", &namelist, NULL, alphasort);
+ if (count < 0)
+ return 0;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ if(strcmp(namelist[i]->d_name, "config") && (*namelist[i]->d_name != '.'))
+ {
+ n++;
+ lua_pushinteger(L, n);
+ lua_pushstring(L, namelist[i]->d_name);
+ lua_settable(L, -3);
+ }
+ free(namelist[i]);
+ }
+ free(namelist);
+ return 1;
+}
diff --git a/libs/luanet/src/vconfig.h b/libs/luanet/src/vconfig.h
new file mode 100644
index 000000000..25bb6161d
--- /dev/null
+++ b/libs/luanet/src/vconfig.h
@@ -0,0 +1,27 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2008 Steven Barth <steven@midlink.org>
+ */
+
+#ifndef _VCONFIG_H__
+#define _VCONFIG_H__
+
+int vlan_add(lua_State *L);
+int vlan_del(lua_State *L);
+int vlan_getall(lua_State *L);
+
+#endif