Import luanet library
authorSteven Barth <steven@midlink.org>
Mon, 30 Mar 2009 11:27:43 +0000 (11:27 +0000)
committerSteven Barth <steven@midlink.org>
Mon, 30 Mar 2009 11:27:43 +0000 (11:27 +0000)
Relicensed with author's permission
Thanks John

21 files changed:
contrib/package/luci/Makefile
libs/luanet/Makefile [new file with mode: 0644]
libs/luanet/src/Makefile [new file with mode: 0644]
libs/luanet/src/base64.c [new file with mode: 0644]
libs/luanet/src/base64.h [new file with mode: 0644]
libs/luanet/src/bridge.c [new file with mode: 0644]
libs/luanet/src/bridge.h [new file with mode: 0644]
libs/luanet/src/df.c [new file with mode: 0644]
libs/luanet/src/df.h [new file with mode: 0644]
libs/luanet/src/helper.c [new file with mode: 0644]
libs/luanet/src/helper.h [new file with mode: 0644]
libs/luanet/src/ifconfig.c [new file with mode: 0644]
libs/luanet/src/ifconfig.h [new file with mode: 0644]
libs/luanet/src/iwconfig.c [new file with mode: 0644]
libs/luanet/src/iwconfig.h [new file with mode: 0644]
libs/luanet/src/main.c [new file with mode: 0644]
libs/luanet/src/route.c [new file with mode: 0644]
libs/luanet/src/route.h [new file with mode: 0644]
libs/luanet/src/test.lua [new file with mode: 0755]
libs/luanet/src/vconfig.c [new file with mode: 0644]
libs/luanet/src/vconfig.h [new file with mode: 0644]

index 45c3ecb..044eca6 100644 (file)
@@ -213,6 +213,17 @@ define Package/luci-json/install
 endef
 
 
 endef
 
 
+define Package/luci-luanet
+  $(call Package/luci/libtemplate)
+  TITLE:=luanet
+  DEPENDS+=+libiw
+endef
+
+define Package/luci-luanet/install
+        $(call Package/luci/install/template,$(1),libs/luanet)
+endef
+
+
 
 NIXIO_TLS:=axtls
 
 
 NIXIO_TLS:=axtls
 
@@ -821,6 +832,9 @@ endif
 ifneq ($(CONFIG_PACKAGE_luci-json),)
        PKG_SELECTED_MODULES+=libs/json
 endif
 ifneq ($(CONFIG_PACKAGE_luci-json),)
        PKG_SELECTED_MODULES+=libs/json
 endif
+ifneq ($(CONFIG_PACKAGE_luci-luanet),)
+       PKG_SELECTED_MODULES+=libs/luanet
+endif
 ifneq ($(CONFIG_PACKAGE_luci-nixio),)
        PKG_SELECTED_MODULES+=libs/nixio
 endif
 ifneq ($(CONFIG_PACKAGE_luci-nixio),)
        PKG_SELECTED_MODULES+=libs/nixio
 endif
@@ -997,6 +1011,7 @@ $(eval $(call BuildPackage,luci-http))
 $(eval $(call BuildPackage,luci-httpclient))
 $(eval $(call BuildPackage,luci-ipkg))
 $(eval $(call BuildPackage,luci-json))
 $(eval $(call BuildPackage,luci-httpclient))
 $(eval $(call BuildPackage,luci-ipkg))
 $(eval $(call BuildPackage,luci-json))
+$(eval $(call BuildPackage,luci-luanet))
 $(eval $(call BuildPackage,luci-nixio))
 $(eval $(call BuildPackage,luci-uci))
 $(eval $(call BuildPackage,luci-sys))
 $(eval $(call BuildPackage,luci-nixio))
 $(eval $(call BuildPackage,luci-uci))
 $(eval $(call BuildPackage,luci-sys))
diff --git a/libs/luanet/Makefile b/libs/luanet/Makefile
new file mode 100644 (file)
index 0000000..702f866
--- /dev/null
@@ -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 (file)
index 0000000..852a7c4
--- /dev/null
@@ -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 (file)
index 0000000..f897cf7
--- /dev/null
@@ -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 (file)
index 0000000..e32365f
--- /dev/null
@@ -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 (file)
index 0000000..478f8b1
--- /dev/null
@@ -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 (file)
index 0000000..87202f6
--- /dev/null
@@ -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 (file)
index 0000000..be582f6
--- /dev/null
@@ -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 (file)
index 0000000..7fe3f6e
--- /dev/null
@@ -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 (file)
index 0000000..5767992
--- /dev/null
@@ -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 (file)
index 0000000..dec5552
--- /dev/null
@@ -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 (file)
index 0000000..58ce45e
--- /dev/null
@@ -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 (file)
index 0000000..dffffd5
--- /dev/null
@@ -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 (file)
index 0000000..5fc65b6
--- /dev/null
@@ -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 (file)
index 0000000..59240d5
--- /dev/null
@@ -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 (file)
index 0000000..0a42276
--- /dev/null
@@ -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 (file)
index 0000000..1690b74
--- /dev/null
@@ -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 (file)
index 0000000..53f6e98
--- /dev/null
@@ -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 (executable)
index 0000000..713836b
--- /dev/null
@@ -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 (file)
index 0000000..7adccc9
--- /dev/null
@@ -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 (file)
index 0000000..25bb616
--- /dev/null
@@ -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