]> source.dussan.org Git - rspamd.git/commitdiff
Add utility to convert ip to int.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 29 Mar 2014 23:03:31 +0000 (16:03 -0700)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 29 Mar 2014 23:03:31 +0000 (16:03 -0700)
src/lua/lua_ip.c

index 014b354930e1754a1355020c071348daf0d601ce..daf5a03ce0f52c8e8e94986033f08fcb97c98ee1 100644 (file)
@@ -24,6 +24,8 @@
 #include "lua_common.h"
 
 LUA_FUNCTION_DEF (ip, to_string);
+LUA_FUNCTION_DEF (ip, to_number);
+LUA_FUNCTION_DEF (ip, from_number);
 LUA_FUNCTION_DEF (ip, to_table);
 LUA_FUNCTION_DEF (ip, str_octets);
 LUA_FUNCTION_DEF (ip, inversed_str_octets);
@@ -34,6 +36,7 @@ LUA_FUNCTION_DEF (ip, get_version);
 static const struct luaL_reg    iplib_m[] = {
        LUA_INTERFACE_DEF (ip, to_string),
        LUA_INTERFACE_DEF (ip, to_table),
+       LUA_INTERFACE_DEF (ip, to_number),
        LUA_INTERFACE_DEF (ip, str_octets),
        LUA_INTERFACE_DEF (ip, inversed_str_octets),
        LUA_INTERFACE_DEF (ip, get_version),
@@ -44,6 +47,7 @@ static const struct luaL_reg    iplib_m[] = {
 
 static const struct luaL_reg    iplib_f[] = {
        LUA_INTERFACE_DEF (ip, from_string),
+       LUA_INTERFACE_DEF (ip, from_number),
        {NULL, NULL}
 };
 
@@ -212,6 +216,70 @@ lua_ip_from_string (lua_State *L)
        return 1;
 }
 
+static gint
+lua_ip_to_number (lua_State *L)
+{
+       struct rspamd_lua_ip *ip = lua_check_ip (L, 1);
+       guint32 dst[4], i;
+
+       if (ip != NULL) {
+               if (ip->af == AF_INET) {
+                       /* One integer in host byte order */
+                       lua_pushinteger (L, ntohl (ip->data.ip4.s_addr));
+               }
+               else {
+                       /* 4 integers in host byte order */
+                       G_STATIC_ASSERT (sizeof (ip->data) >= sizeof (dst));
+                       memcpy (dst, &ip->data, sizeof (dst));
+                       for (i = 0; i < G_N_ELEMENTS (dst); i ++) {
+                               lua_pushinteger (L, ntohl (dst[i]));
+                       }
+                       return 4;
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static gint
+lua_ip_from_number (lua_State *L)
+{
+       guint32 src[4], i;
+       struct rspamd_lua_ip *ip, **pip;
+
+       if (lua_gettop (L) == 1 && lua_isnumber (L, 1)) {
+               /* Ipv4 version */
+               ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
+               src[0] = lua_tointeger (L, 1);
+               ip->af = AF_INET;
+               ip->data.ip4.s_addr = htonl (src[0]);
+               pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
+               lua_setclass (L, "rspamd{ip}", -1);
+               *pip = ip;
+       }
+       else if (lua_gettop (L) == 4 && lua_isnumber (L, 1)) {
+               /* Ipv6 version */
+               for (i = 0; i < 4; i ++) {
+                       src[i] = htonl (lua_tonumber (L, i + 1));
+               }
+               G_STATIC_ASSERT (sizeof (ip->data) >= sizeof (src));
+               ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
+               ip->af = AF_INET6;
+               memcpy (&ip->data, src, sizeof (src));
+               pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
+               lua_setclass (L, "rspamd{ip}", -1);
+               *pip = ip;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
 static gint
 lua_ip_destroy (lua_State *L)
 {