From f233acf9ff8074c108546b2dbc5ac3e6205461d2 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sat, 6 Apr 2024 12:33:22 +0100 Subject: [PATCH] netlink uevent hello world --- pkgs/default.nix | 1 + pkgs/nellie/default.nix | 28 +++++++++++++++ pkgs/nellie/nellie.c | 79 +++++++++++++++++++++++++++++++++++++++++ pkgs/nellie/test.lua | 5 +++ 4 files changed, 113 insertions(+) create mode 100644 pkgs/nellie/default.nix create mode 100644 pkgs/nellie/nellie.c create mode 100644 pkgs/nellie/test.lua diff --git a/pkgs/default.nix b/pkgs/default.nix index e2257b6..f910146 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -82,6 +82,7 @@ in { zyxel-bootconfig = callPackage ./zyxel-bootconfig {}; min-collect-garbage = callPackage ./min-collect-garbage {}; min-copy-closure = callPackage ./min-copy-closure {}; + nellie = callPackage ./nellie {}; netlink-lua = callPackage ./netlink-lua {}; odhcp-script = callPackage ./odhcp-script {}; odhcp6c = callPackage ./odhcp6c {}; diff --git a/pkgs/nellie/default.nix b/pkgs/nellie/default.nix new file mode 100644 index 0000000..4594b5b --- /dev/null +++ b/pkgs/nellie/default.nix @@ -0,0 +1,28 @@ +{ lua, lib, fetchpatch, fetchFromGitHub, stdenv }: + +let pname = "nellie"; +in lua.pkgs.buildLuaPackage { + inherit pname; + version = "0.1.1-1"; + + src = ./.; + + buildPhase = "$CC -shared -l lua -o nellie.so nellie.c"; + + # for the checks to work you need to + # nix-build--option sandbox false + # otherwise the sandbox doesn't see any uevent messages + + # doCheck = stdenv.hostPlatform == stdenv.buildPlatform; + + checkPhase = '' + export LUA_CPATH=./?.so + lua test.lua + ''; + + installPhase = '' + mkdir -p "$out/lib/lua/${lua.luaversion}" + cp nellie.so "$out/lib/lua/${lua.luaversion}/" + ''; + +} diff --git a/pkgs/nellie/nellie.c b/pkgs/nellie/nellie.c new file mode 100644 index 0000000..2267c51 --- /dev/null +++ b/pkgs/nellie/nellie.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include +#include +#include +#include + +/* static int l_close_socket(lua_State *L) { */ +/* LStream *p = (LStream *) luaL_checkudata(L, 1, LUA_FILEHANDLE); */ +/* int res = fclose(p->f); */ +/* return luaL_fileresult(L, (res == 0), NULL); */ +/* } */ + + +static int l_read_from_socket(lua_State *L) { + /* struct sockaddr_nl sa; */ + /* memset(&sa, 0, sizeof(sa)); */ + int length = 32; + + if(lua_isnumber(L, 2)) + length = lua_tointeger(L, 2); + + lua_getfield(L, 1, "fileno"); + int fd = (int) lua_tointeger(L, -1); + char *buf = (char *) malloc(length); + int bytes = recv(fd, buf, length, 0); + + if(bytes > 0) { + lua_pushlstring(L, buf, bytes); + free(buf); + return 1; + } else { + free(buf); + return 0; + } +} + +static int l_open_socket(lua_State *L) { + int netlink_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT); + + struct sockaddr_nl sa; + memset(&sa, 0, sizeof(sa)); + sa.nl_family = AF_NETLINK; + sa.nl_pid = getpid(); + sa.nl_groups = 4; /* rebroadcasts from mdevd */ + + if(bind(netlink_fd, (struct sockaddr *) &sa, sizeof(sa))==0) { + lua_newtable(L); + lua_pushliteral(L, "fileno"); + lua_pushinteger(L, netlink_fd); + lua_settable(L, 1); + + lua_pushliteral(L, "read"); + lua_pushcfunction(L, l_read_from_socket); + lua_settable(L, 1); + + return 1; + } else { + return 0; + } +} + + +static const struct luaL_Reg funcs [] = { + {"open", l_open_socket}, + {NULL, NULL} /* sentinel */ +}; + + +/* "luaopen_" prefix is magic and tells lua to run this function + * when it dlopens the library + */ + +int luaopen_nellie (lua_State *L) { + luaL_newlib(L, funcs); + return 1; +} diff --git a/pkgs/nellie/test.lua b/pkgs/nellie/test.lua new file mode 100644 index 0000000..f540d21 --- /dev/null +++ b/pkgs/nellie/test.lua @@ -0,0 +1,5 @@ +local nellie = require('nellie') +print('dfg') +local f = nellie.open() + +print(string.byte(f:read(1000), 0, 60))