]> git.ipfire.org Git - location/libloc.git/commitdiff
lua: Add a Network object
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 13:43:34 +0000 (13:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 13:43:34 +0000 (13:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/lua/database.c
src/lua/location.c
src/lua/location.h
src/lua/network.c [new file with mode: 0644]
src/lua/network.h [new file with mode: 0644]
tests/lua/main.lua

index 8b986a406ec4e0fe366a3f855b22bade7afbed84..e3ed1fcdb1fae96808a26cd124d257c56fc364a7 100644 (file)
@@ -240,7 +240,9 @@ src_lua_location_la_SOURCES = \
        src/lua/database.c \
        src/lua/database.h \
        src/lua/location.c \
-       src/lua/location.h
+       src/lua/location.h \
+       src/lua/network.c \
+       src/lua/network.h
 
 src_lua_location_la_CFLAGS = \
        $(AM_CFLAGS) \
@@ -262,7 +264,9 @@ EXTRA_DIST += \
        src/lua/database.c \
        src/lua/database.h \
        src/lua/location.c \
-       src/lua/location.h
+       src/lua/location.h \
+       src/lua/network.c \
+       src/lua/network.h
 
 LUA_TESTS = \
        tests/lua/main.lua
index 13a81bd6840bb846b7830b088c69b37262c98ea6..2912f4c94f204d25fe0fb36f68f3595d5cce3106 100644 (file)
@@ -109,15 +109,5 @@ static const struct luaL_Reg database_functions[] = {
 };
 
 int register_database(lua_State* L) {
-       // Create a new metatable
-       luaL_newmetatable(L, "location.Database");
-
-       // Set functions
-       luaL_setfuncs(L, database_functions, 0);
-
-       // Configure metatable
-       lua_pushvalue(L, -1);
-       lua_setfield(L, -2, "__index");
-
-       return 1;
+       return register_class(L, "location.Database", database_functions);
 }
index ee9bce512a24a14f4346b8fec85031fabad19d25..315a790413113f7186b66b33b654af12d3875e8a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "location.h"
 #include "database.h"
+#include "network.h"
 
 struct loc_ctx* ctx = NULL;
 
@@ -55,5 +56,10 @@ int luaopen_location(lua_State* L) {
 
        lua_setfield(L, -2, "Database");
 
+       // Register Network type
+       register_network(L);
+
+       lua_setfield(L, -2, "Network");
+
        return 1;
 }
index 6eef1a6769c5aea59350a7d6338d66646fc824a2..cc261e61e53c924eadb9b808c979d85b174b9327 100644 (file)
@@ -25,4 +25,19 @@ extern struct loc_ctx* ctx;
 
 int luaopen_location(lua_State* L);
 
+static inline int register_class(lua_State* L,
+               const char* name, const struct luaL_Reg* functions) {
+       // Create a new metatable
+       luaL_newmetatable(L, name);
+
+       // Set functions
+       luaL_setfuncs(L, functions, 0);
+
+       // Configure metatable
+       lua_pushvalue(L, -1);
+       lua_setfield(L, -2, "__index");
+
+       return 1;
+}
+
 #endif /* LUA_LOCATION_LOCATION_H */
diff --git a/src/lua/network.c b/src/lua/network.c
new file mode 100644 (file)
index 0000000..0706fe2
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+       libloc - A library to determine the location of someone on the Internet
+
+       Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
+
+       This library 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.
+
+       This library 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.
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include <libloc/network.h>
+
+#include "location.h"
+#include "network.h"
+
+typedef struct network {
+       struct loc_network* network;
+} Network;
+
+static Network* luaL_checknetwork(lua_State* L, int i) {
+       void* userdata = luaL_checkudata(L, i, "location.Network");
+
+       // Throw an error if the argument doesn't match
+       luaL_argcheck(L, userdata, i, "Network expected");
+
+       return (Network*)userdata;
+}
+
+static int create_network(lua_State* L, struct loc_network* network) {
+       // Allocate a new object
+       Network* self = (Network*)lua_newuserdata(L, sizeof(*self));
+
+       // Set metatable
+       luaL_setmetatable(L, "location.Network");
+
+       // Store network
+       self->network = loc_network_ref(network);
+
+       return 1;
+}
+
+static int Network_new(lua_State* L) {
+       struct loc_network* network = NULL;
+       const char* n = NULL;
+       int r;
+
+       // Fetch the network
+       n = luaL_checkstring(L, 1);
+
+       // Parse the string
+       r = loc_network_new_from_string(ctx, &network, n);
+       if (r)
+               return luaL_error(L, "Could not create network %s: %s\n", n, strerror(errno));
+
+       // Return the network
+       r = create_network(L, network);
+       loc_network_unref(network);
+
+       return r;
+}
+
+static int Network_gc(lua_State* L) {
+       Network* self = luaL_checknetwork(L, 0);
+
+       if (self->network)
+               loc_network_unref(self->network);
+
+       free(self);
+       return 0;
+}
+
+static int Network_tostring(lua_State* L) {
+       Network* self = luaL_checknetwork(L, 1);
+
+       // Push string representation of the network
+       lua_pushstring(L, loc_network_str(self->network));
+
+       return 1;
+}
+
+// ASN
+
+static int Network_get_asn(lua_State* L) {
+       Network* self = luaL_checknetwork(L, 0);
+
+       uint32_t asn = loc_network_get_asn(self->network);
+
+       // Push ASN
+       if (asn)
+               lua_pushnumber(L, asn);
+       else
+               lua_pushnil(L);
+
+       return 1;
+}
+
+// Family
+
+static int Network_get_family(lua_State* L) {
+       Network* self = luaL_checknetwork(L, 0);
+
+       // Push family
+       lua_pushnumber(L, loc_network_address_family(self->network));
+
+       return 1;
+}
+
+// Country Code
+
+static int Network_get_country_code(lua_State* L) {
+       Network* self = luaL_checknetwork(L, 0);
+
+       const char* country_code = loc_network_get_country_code(self->network);
+
+       // Push country code
+       if (country_code && *country_code)
+               lua_pushstring(L, country_code);
+       else
+               lua_pushnil(L);
+
+       return 1;
+}
+
+static const struct luaL_Reg Network_functions[] = {
+       { "new", Network_new },
+       { "get_asn", Network_get_asn },
+       { "get_family", Network_get_family },
+       { "get_country_code", Network_get_country_code },
+       { "__gc", Network_gc },
+       { "__tostring", Network_tostring },
+       { NULL, NULL },
+};
+
+int register_network(lua_State* L) {
+       return register_class(L, "location.Network", Network_functions);
+}
diff --git a/src/lua/network.h b/src/lua/network.h
new file mode 100644 (file)
index 0000000..54be76d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+       libloc - A library to determine the location of someone on the Internet
+
+       Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
+
+       This library 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.
+
+       This library 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.
+*/
+
+#ifndef LUA_LOCATION_NETWORK_H
+#define LUA_LOCATION_NETWORK_H
+
+#include <lua.h>
+#include <lauxlib.h>
+
+int register_network(lua_State* L);
+
+#endif /* LUA_LOCATION_NETWORK_H */
index 174bd3bd201a6ae97686dfdfea16da2034320094..fada1680cc77247eedd808b2ae744816bf9c67c3 100755 (executable)
@@ -46,4 +46,19 @@ function test_lookup()
        db.lookup("81.3.27.32")
 end
 
+function test_network()
+       location = require("location")
+
+       n1 = location.Network.new("10.0.0.0/8")
+
+       -- The ASN should be nul
+       luaunit.assertNil(n1.get_asn())
+
+       -- The family should be IPv4
+       luaunit.assertEquals(n1.get_family(), 2)
+
+       -- The country code should be empty
+       luaunit.assertNil(n1.get_country_code())
+end
+
 os.exit(luaunit.LuaUnit.run())