Lunatik ist ein Framework zum Scripting des Linux -Kernels mit Lua. Es besteht aus dem LUA -Dolmetscher, der so modifiziert wurde, dass sie im Kernel ausgeführt werden. ein Gerätetreiber (geschrieben in lua =)) und ein Befehlszeilen -Tool zum Laden und Ausführen von Skripten und zum Verwalten von Laufzeitumgebungen aus dem Benutzerbereich; eine C -API zum Laden und Ausführen von Skripten und zur Verwaltung von Laufzeitumgebungen aus dem Kernel; und Lua -APIs für die Bindung von Kerneleinrichtungen an Lua -Skripte.
Hier ist ein Beispiel für einen in Lua geschriebenen Charakter -Gerätetreiber mit Lunatik, um zufällige ASCII -druckbare Zeichen zu generieren:
-- /lib/modules/lua/passwd.lua
--
-- implements /dev/passwd for generate passwords
-- usage: $ sudo lunatik run passwd
-- $ head -c <width> /dev/passwd
local device = require ( " device " )
local linux = require ( " linux " )
local function nop () end -- do nothing
local s = linux . stat
local driver = { name = " passwd " , open = nop , release = nop , mode = s . IRUGO }
function driver : read () -- read(2) callback
-- generate random ASCII printable characters
return string.char ( linux . random ( 32 , 126 ))
end
-- creates a new character device
device . new ( driver )Installieren Sie Abhängigkeiten (hier für Debian/Ubuntu, um an die eigene Verteilung angepasst zu werden):
sudo apt install git build-essential lua5.4 dwarves clang llvm libelf-dev linux-headers- $( uname -r ) linux-tools-common linux-tools- $( uname -r ) pkg-config libpcap-dev m4 lunatik kompilieren und installieren:
LUNATIK_DIR= ~ /lunatik # to be adapted
mkdir " ${LUNATIK_DIR} " ; cd " ${LUNATIK_DIR} "
git clone --depth 1 --recurse-submodules https://github.com/luainkernel/lunatik.git
cd lunatik
make
sudo make install Sobald das Skript debian_kernel_postinst_lunatik.sh von Tools/möglicherweise in /etc/kernel/postinst.d/ kopiert werden kann, wird lunatik (und auch die xdp benötigte Libs) auf dem Kernel -Upgrade zusammengestellt.
sudo lunatik # execute Lunatik REPL
Lunatik 3.5 Copyright (C) 2023-2024 ring-0 Ltda.
> return 42 -- execute this line in the kernel
42
usage: lunatik [load | unload | reload | status | list] [run | spawn | stop < script > ]load : Laden Sie Lunatik -Kernel -Moduleunload : Lunatik -Kernelmodule entladenreload : Lunatik -Kernel -Module neu ladenstatus : Zeigen Sie, welche Lunatik -Kernel -Module derzeit geladen sindlist : Zeigen Sie, welche Laufzeitumgebungen derzeit ausgeführt werdenrun : Erstellen Sie eine neue Laufzeitumgebung, um das script /lib/modules/lua/<script>.lua auszuführenspawn : Erstellen Sie /lib/modules/lua/<script>.lua neue Laufzeitumgebung und lakenstop : Stoppen Sie die Laufzeitumgebung, die erstellt wurde, um das Skript <script> auszuführendefault : Starten Sie eine Reply (Read -E -E -Druck -Schleife) Lunatik 3.4 basiert auf LUA 5.4, die für den Kernel angepasst sind.
Lunatik unterstützt weder die Gleitkomma-Arithmetik, daher unterstützt sie weder __div noch __pow Metamethods, und die Typnummer hat nur die Subtyp- Ganzzahl .
Lunatik unterstützt nicht sowohl IO- als auch OS -Bibliotheken und die angegebenen Kennungen aus den folgenden Bibliotheken:
Lunatik modifiziert die folgenden Kennungen:
"Lua 5.4-kernel" ."/lib/modules/lua/?.lua;/lib/modules/lua/?/init.lua" .Lunatik unterstützt lual_stream, lual_execresult, lual_fileresult, luaopen_io und luaopen_os nicht .
Lunatik modifiziert lual_openlibs, um luaopen_io und luaopen_os zu entfernen.
#include <lunatik.h> int lunatik_runtime ( lunatik_object_t * * pruntime , const char * script , bool sleep ); lunatik_runtime () erstellt eine neue runtime und lädt dann das Skript /lib/modules/lua/<script>.lua als Einstiegspunkt für diese Umgebung. Es darf nur aus dem Prozesskontext aufgerufen werden. Die runtime ist ein Lunatik -Objekt, das einen Lua -Staat besitzt. Lunatik -Objekte sind spezielle Lua UserData, die auch einen Sperrtyp und einen Referenzschalter enthalten. Wenn sleep wahr ist, verwendet Lunatik_Runtime () ein Mutex, um die runtime und das GFP_Kernel -Flag zu sperren, um den neuen Speicher später auf Lunatik_Run () aufzuteilen. Andernfalls wird ein Spinlock und GFP_atomic verwendet. lunatik_runtime () öffnet die auf Lunatik vorhandenen Lua -Standardbibliotheken. Wenn er erfolgreich ist, setzt Lunatik_Runtime () die Adresse, die von pruntime und Luas zusätzlichem Platz mit einem Zeiger für die neu erstellte runtime angezeigt wird, den Referenzzähler auf 1 festgelegt und dann 0 zurückgegeben. Andernfalls gibt es -ENOMEM zurück, wenn ein unzureichender Speicher verfügbar ist. oder -EINVAL , wenn es das script nicht laden oder ausführt.
-- /lib/modules/lua/mydevice.lua
function myread ( len , off )
return " 42 "
end static lunatik_object_t * runtime ;
static int __init mydevice_init ( void )
{
return lunatik_runtime ( & runtime , "mydevice" , true);
} int lunatik_stop ( lunatik_object_t * runtime ); Lunatik_Stop () schließt den für diese runtime erstellten LUA -Status und verringert den Referenzzähler. Sobald der Referenzschalter auf Null abgeschlossen ist, werden der Sperrtyp und der für die runtime zugewiesene Speicher freigegeben. Wenn die runtime veröffentlicht wurde, gibt sie 1 zurück; Ansonsten kehrt es 0 zurück.
void lunatik_run ( lunatik_object_t * runtime , < inttype > ( * handler )(...), < inttype > & ret , ...); lunatik_run () sperrt die runtime und ruft den handler auf, den zugehörigen LUA -Staat als erstes Argument zu bestehen, gefolgt von den variadischen Argumenten. Wenn der LUA -Staat geschlossen wurde, wird ret mit -ENXIO festgelegt; Andernfalls wird ret mit dem Ergebnis des handler(L, ...) aufgerufen. Dann stellt es den Lua -Stack wieder her und schaltet die runtime frei. Es ist als Makro definiert.
static int l_read ( lua_State * L , char * buf , size_t len , loff_t * off )
{
size_t llen ;
const char * lbuf ;
lua_getglobal ( L , "myread" );
lua_pushinteger ( L , len );
lua_pushinteger ( L , * off );
if ( lua_pcall ( L , 2 , 2 , 0 ) != LUA_OK ) { /* calls myread(len, off) */
pr_err ( "%sn" , lua_tostring ( L , -1 ));
return - ECANCELED ;
}
lbuf = lua_tolstring ( L , -2 , & llen );
llen = min ( len , llen );
if ( copy_to_user ( buf , lbuf , llen ) != 0 )
return - EFAULT ;
* off = ( loff_t ) luaL_optinteger ( L , -1 , * off + llen );
return ( ssize_t ) llen ;
}
static ssize_t mydevice_read ( struct file * f , char * buf , size_t len , loff_t * off )
{
ssize_t ret ;
lunatik_object_t * runtime = ( lunatik_object_t * ) f -> private_data ;
lunatik_run ( runtime , l_read , ret , buf , len , off );
return ret ;
} void lunatik_getobject ( lunatik_object_t * object ); lunatik_getObject () erhöht den Referenzzähler dieses object (z. B. runtime ).
int lunatik_putobject ( lunatik_object_t * object ); lunatik_putObject () verringert den Referenzzähler dieses object (z. B. runtime ). Wenn das object veröffentlicht wurde, gibt es 1 zurück; Ansonsten kehrt es 0 zurück.
lunatik_object_t * lunatik_toruntime ( lua_State * L ); lunatik_toruntime () gibt die runtime zurück, auf die der zusätzliche Platz des L verwiesen wird.
Die lunatik -Bibliothek bietet Unterstützung beim Laden und Ausführen von Skripten und zum Verwalten von Laufzeitumgebungen von LuA.
lunatik.runtime(script [, sleep]) Lunatik.Runtime () erstellt eine neue Laufzeitumgebung, lädt dann das Skript /lib/modules/lua/<script>.lua als Einstiegspunkt für diese Umgebung. Es gibt ein Lunatik -Objekt zurück, das die runtime darstellt. Wenn sleep wahr ist oder weggelassen ist, wird ein Mutex und GFP_Kernel verwendet. Andernfalls wird ein Spinlock und GFP_atomic verwendet. Lunatik.Runtime () öffnet die auf Lunatik vorhandenen Lua -Standardbibliotheken.
runtime:stop() Laufzeit: Stop () stoppt die runtime und löscht seine Referenz aus dem Laufzeitobjekt.
runtime:resume([obj1, ...]) Laufzeit: Resume () setzt die Ausführung einer runtime fort. Die Werte obj1, ... werden als Argumente an die auf der runtime zurückgegebene Funktion übergeben. Wenn die runtime ergeben hat, startet resume() sie neu; Die Werte obj1, ... werden als Ergebnisse aus der Erträge übergeben.
Die device unterstützt das Schreiben von Charaktergerättreibern in LUA.
device.new(driver) device.new () gibt ein neues device zurück und installiert seinen driver im System. Der driver muss als eine Tabelle definiert werden, die das folgende Feld enthält:
name : Zeichenfolge Definieren des Gerätenamens; Es wird zum Erstellen der Gerätedatei (z. B. /dev/<name> ) verwendet. Die driver kann optional die folgenden Felder enthalten:
read : Rückruffunktion, um den Lesevorgang in der Gerätedatei zu verarbeiten. Es empfängt die driver als erstes Argument, gefolgt von zwei Zahlen, der zu length zu lesen und die offset . Es sollte eine Zeichenfolge und optional den updated offset zurückgeben. Wenn die Länge der zurückgegebenen Zeichenfolge größer als die angeforderte length ist, wird die Zeichenfolge auf diese length korrigiert. Wenn der updated offset nicht zurückgegeben wird, wird der offset mit offset + length aktualisiert.write : Rückruffunktion, um den Schreibvorgang in der Gerätedatei zu verarbeiten. Es empfängt die driver als erstes Argument, gefolgt von der zu schriftlichen Zeichenfolge und als Ganzzahl als offset . Es kann optional die schriftliche length zurückgeben, gefolgt von dem updated offset . Wenn die zurückgegebene Länge größer als die angeforderte length ist, wird die zurückgegebene Länge korrigiert. Wenn der updated offset nicht zurückgegeben wird, wird der offset mit offset + length aktualisiert.open : Rückruffunktion, um den geöffneten Vorgang in der Gerätedatei zu verarbeiten. Es erhält die driver und es wird erwartet, dass nichts zurückkommt.release : Rückruffunktion, um den Freigabebetrieb in der Gerätedatei zu verarbeiten. Es erhält die driver und es wird erwartet, dass nichts zurückkommt.mode : Eine Ganzzahl, die den Gerätedateimodus angibt. Wenn ein Operationsrückruf nicht definiert ist, gibt das device für seinen Zugriff an VFS -ENXIO .
device.stop(dev) , dev:stop() Device.Stop () entfernt einen vom dev -Objekt angegebenen driver aus dem System.
Die linux -Bibliothek unterstützt einige Linux -Kernel -Einrichtungen.
linux.random([m [, n]])linux.random () ahmt das Verhalten von math.random nach, aber bindung <linux/random.h> 's get_random_u32 () und get_random_u64 () apis.
Wenn Sie ohne Argumente aufgerufen werden, erzeugt er eine Ganzzahl mit allen Bits (Pseudo) zufällig. Bei zwei Ganzzahlen m und n , Linux.random () aufgerufen, gibt eine Pseudo-Random-Ganzzahl mit gleichmäßiger Verteilung im Bereich [m, n] zurück. Der Call math.random(n) für ein positives n entspricht math.random(1, n) .
linux.statLinux.Stat ist eine Tabelle, in der <Linux/Stat.H> Ganzzahl -Flags nach Lua exportiert.
"IRWXUGO" : Erlaubnis zum Lesen , Schreiben und Ausführen für Benutzer , Gruppe und andere ."IRUGO" : Erlaubnis nur für Benutzer , Gruppe und andere zu lesen ."IWUGO" : Erlaubnis nur für Benutzer , Gruppe und andere zu schreiben ."IXUGO" : Erlaubnis nur für Benutzer , Gruppe und andere auszuführen . linux.schedule([timeout [, state]]) Linux.Schedule () legt den aktuellen state fest und schläft den Schlaf, bis timeout -Millisekunden verstrichen sind. Wenn timeout weggelassen wird, verwendet es MAX_SCHEDULE_TIMEOUT . Wenn state weggelassen wird, verwendet er task.INTERRUPTIBLE .
linux.taskLinux.Task ist eine Tabelle, die Aufgabenstatus -Flags nach Lua exportiert.
"RUNNING" : Aufgabe wird auf einer CPU ausgeführt oder darauf warten, ausgeführt zu werden."INTERRUPTIBLE" : Aufgabe wartet auf ein Signal oder eine Ressource (Schlaf)."UNINTERRUPTIBLE" : verhält sich wie "unterbrochen", mit der Ausnahme, dass das Signal die Aufgabe nicht aufweckt."KILLABLE" : verhält sich wie "ununterbrochen", mit der Ausnahme, dass tödliche Signale die Aufgabe aufwachen."IDLE" : verhält sich wie "ununterbrochen", mit der Ausnahme, dass es die loadavg -Buchhaltung vermeidet. linux.time()Linux.time () gibt die aktuelle Zeit in Nanosekunden seit der Epoche zurück.
linux.errnoLinux.errno ist eine Tabelle, in der <UAPI/ASM-Generic/Errno-Base.h> Flags nach Lua exportiert.
"PERM" : Operation nicht zulässig."NOENT" : Keine solche Datei oder Verzeichnis."SRCH" : Kein solcher Prozess."INTR" : unterbrochener Systemaufruf."IO" : I/O -Fehler."NXIO" : Kein solches Gerät oder eine solche Adresse."2BIG" :, Argumentliste zu lange."NOEXEC" : Exec -Formatfehler."BADF" : Schlechte Dateinummer."CHILD" : Keine Kinderprozesse."AGAIN" : Versuchen Sie es erneut."NOMEM" : Aus dem Gedächtnis."ACCES" : Erlaubnis abgelehnt."FAULT" : Schlechte Adresse."NOTBLK" : Blockgerät erforderlich."BUSY" : Gerät oder Ressource beschäftigt."EXIST" : Datei existiert."XDEV" : Cross-Device-Link."NODEV" : Kein solches Gerät."NOTDIR" : Kein Verzeichnis."ISDIR" : ist ein Verzeichnis."INVAL" : Ungültiges Argument."NFILE" : Datei -Tabellenüberlauf."MFILE" : Zu viele geöffnete Dateien."NOTTY" : keine Schreibmaschine."TXTBSY" : Textdatei beschäftigt."FBIG" : Datei zu groß."NOSPC" : Kein Speicherplatz auf dem Gerät."SPIPE" : Illegale Suche."ROFS" : schreibgeschütztes Dateisystem."MLINK" : Zu viele Links."PIPE" : gebrochenes Rohr."DOM" : Mathematikargument aus Domain of Func."RANGE" : Mathematikergebnis nicht dargestellt. linux.hton16(num)Linux.hton16 () konvertiert die Host-Byte-Reihenfolge, um Byte-Bestellung für eine 16-Bit-Ganzzahl zu vernetzen.
linux.hton32(num)Linux.hton32 () konvertiert die Host-Byte-Reihenfolge, um Byte-Bestellung für eine 32-Bit-Ganzzahl zu vernetzen.
linux.hton64(num)Linux.hton64 () konvertiert die Host-Byte-Reihenfolge, um eine Byte-Bestellung für eine 64-Bit-Ganzzahl zu vernetzen.
linux.ntoh16(num)Linux.ntoh16 () konvertiert die Netzwerk-Byte-Reihenfolge, um die Byte-Reihenfolge für eine 16-Bit-Ganzzahl zu hosten.
linux.ntoh32(num)Linux.ntoh32 () konvertiert die Netzwerk-Byte-Reihenfolge, um die Byte-Reihenfolge für eine 32-Bit-Ganzzahl zu hosten.
linux.ntoh64(num)Linux.ntoh64 () konvertiert die Netzwerk-Byte-Reihenfolge, um die Byte-Bestellung für eine 64-Bit-Ganzzahl zu hosten.
linux.htobe16(num)Linux.htobe16 () konvertiert den Host-Byte-Order in Big-Endian-Byte-Order für eine 16-Bit-Ganzzahl.
linux.htobe32(num)Linux.htobe32 () konvertiert den Host-Byte-Order in Big-Endian-Byte-Order für eine 32-Bit-Ganzzahl.
linux.htobe64(num)Linux.htobe64 () konvertiert den Host-Byte-Order in Big-Endian-Byte-Order für eine 64-Bit-Ganzzahl.
linux.be16toh(num)Linux.be16toh () konvertiert die Big-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 16-Bit-Ganzzahl zu veranstalten.
linux.be32toh(num)Linux.be32toh () konvertiert die Big-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 32-Bit-Ganzzahl zu veranstalten.
linux.be64toh(num)Linux.be64toh () konvertiert die Big-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 64-Bit-Ganzzahl zu veranstalten.
linux.htole16(num)Linux.htole16 () konvertiert den Host-Byte-Order in Little-Endian-Byte-Order für eine 16-Bit-Ganzzahl.
linux.htole32(num)Linux.htole32 () konvertiert den Host-Byte-Order in Little-Endian-Byte-Order für eine 32-Bit-Ganzzahl.
linux.htole64(num)Linux.htole64 () konvertiert den Host-Byte-Order in Little-Endian-Byte-Order für eine 64-Bit-Ganzzahl.
linux.le16toh(num)Linux.le16toh () konvertiert die Little-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 16-Bit-Ganzzahl zu veranstalten.
linux.le32toh(num)Linux.le32toh () konvertiert die Little-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 32-Bit-Ganzzahl zu veranstalten.
linux.le64toh(num)Linux.le64toh () konvertiert die Little-Endian-Byte-Reihenfolge, um die Byte-Bestellung für eine 64-Bit-Ganzzahl zu veranstalten.
Die notifier -Bibliothek unterstützt die Kernel -Notifierketten.
notifier.keyboard(callback) Notifier.Keyboard () gibt ein neues Tastatur notifier -Objekt zurück und installiert es im System. Die callback wird aufgerufen, wenn ein Konsolentastaturereignis stattfindet (z. B. wurde eine Taste gedrückt oder veröffentlicht). Dieser callback erhält die folgenden Argumente:
event : Die verfügbaren Ereignisse werden durch die Tabelle "Notifier.kbd" definiert.down : true , wenn die Taste gedrückt wird; false , wenn es veröffentlicht wird.shift : true , wenn der Schichtschlüssel gehalten wird; false , sonst.key : Schlüsselcode oder Tasten abhängig vom event . Die callback kann die von der Notifier -Tabelle definierten Werte zurückgeben.
notifier.kbdNotifier.kbd ist eine Tabelle, die KBD -Flaggen nach Lua exportiert.
"KEYCODE" : Tastaturschlüsselcode , vor einem anderen aufgerufen."UNBOUND_KEYCODE" : Tastatur -Tastaturcode , der nicht an andere gebunden ist."UNICODE" : Tastatur Unicode."KEYSYM" : Tastatur Tasten ."POST_KEYSYM" : Nach der Tastatur -Tasteninterpretation aufgerufen. notifier.netdevice(callback) Notifier.netDevice () gibt ein neues NetDevice notifier -Objekt zurück und installiert es im System. Die callback wird aufgerufen, wenn ein Konsolen -NetDevice -Ereignis stattfindet (z. B. wurde eine Netzwerkschnittstelle angeschlossen oder getrennt). Dieser callback erhält die folgenden Argumente:
event : Die verfügbaren Ereignisse werden durch die Tabelle "Notifier.netdev" definiert.name : Der Gerätename. Die callback kann die von der Notifier -Tabelle definierten Werte zurückgeben.
notifier.netdevNotifier.netdev ist eine Tabelle, die NetDev -Flags nach Lua exportiert.
notifier.notifyNotifier.notify ist eine Tabelle, in der die Exporte Flags an Lua benachrichtigen.
"DONE" : Es ist egal."OK" : passt zu mir."BAD" : Schlechtes/Veto -Action."STOP" : saubere Art, aus dem Notifier zurückzukehren und weitere Anrufe zu stoppen. notfr:delete() Notfr: Delete () entfernt einen vom notfr -Objekt aus dem System angegebenen notifier .
Die socket -Bibliothek unterstützt das Kernel -Networking -Handling. Diese Bibliothek wurde von Chengzhi Tans GSOC -Projekt inspiriert.
socket.new(family, type, protocol) Socket.new () erstellt ein neues socket -Objekt. Diese Funktion empfängt die folgenden Argumente:
family : Die verfügbaren Adressfamilien sind durch die Socket.af -Tabelle definiert.sock : Die verfügbaren Typen sind in der Socket.Sock -Tabelle vorhanden.protocol : Die verfügbaren Protokolle werden in der Tabelle von Socket.IPProto definiert. socket.afSocket.af ist eine Tabelle, die die Exporte Familien (AF) nach Lua anspricht.
"UNSPEC" : nicht spezifiziert."UNIX" : UNIX -Domain -Sockets."LOCAL" : POSIX -Name für af_unix."INET" : Internet -IP -Protokoll."AX25" : Amateur -Radio AX.25."IPX" : Novell IPX."APPLETALK" : Appletalk DDP."NETROM" : Amateur -Radio -Netz/Rom."BRIDGE" : Multiprotocol Bridge."ATMPVC" : ATM PVCS."X25" : RESANDED FÜR X.25 -Projekt."INET6" : IP Version 6."ROSE" : Amateur Radio X.25 PLP."DEC" : reserviert für das decnet -Projekt."NETBEUI" : reserviert für ein 802.2llc -Projekt."SECURITY" : Sicherheitsrückruf Pseudo AF."KEY" : PF_Key Key Management API."NETLINK" : NetLink."ROUTE" : Alias, um 4.4bs zu emulieren."PACKET" : Paketfamilie."ASH" : Asche."ECONET" : Acorn Econet."ATMSVC" : ATM SVCS."RDS" : RDS Sockets."SNA" : Linux SNA -Projekt (Nutters!)."IRDA" : Irda -Sockel."PPPOX" : Pppox Sockets."WANPIPE" : Wanpipe -API -Sockets."LLC" : Linux LLC."IB" : Native Infiniband -Adresse."MPLS" : MPLS."CAN" : Controller Area Network."TIPC" : TIPC Sockets."BLUETOOTH" : Bluetooth Sockets."IUCV" : IUCV Sockets."RXRPC" : RXRPC -Sockel."ISDN" : Misdn Sockets."PHONET" : Phonet Sockets."IEEE802154" : IEEE802154 Sockets."CAIF" : CAIF -Steckdosen."ALG" : Algorithmus -Sockel."NFC" : NFC Sockets."VSOCK" : vsockets."KCM" : Kernel Connection Multiplexor."QIPCRTR" : Qualcomm IPC -Router."SMC" : Reservennummer für die PF_SMC -Protokollfamilie, die die Familie der AF_Inet -Adressfamilie wiederverwendet."XDP" : XDP Sockets."MCTP" : Management -Komponenten -Transportprotokoll."MAX" : Maximum. socket.sockSocket.Sock ist eine Tabelle, die Socket -Typen (Socken) exportiert:
"STREAM" : Stream (Verbindung) Socket."DGRAM" : Datagram (Conn.less) Socket."RAW" : Rohsteck."RDM" : Zuverlässige Nachricht."SEQPACKET" : Sequentielle Paket -Socket."DCCP" : Datagramm -Überlastungsregelungsprotokoll -Socket."PACKET" : Linux -spezifische Möglichkeit, Pakete auf der Entwicklungsebene zu erhalten.und Flaggen (Socke):
"CLOEXEC" : n/a."NONBLOCK" : n/a. socket.ipprotoSocket.IPProto ist eine Tabelle, die IP -Protokolle (IPPROTO) nach Lua exportiert.
"IP" : Dummy -Protokoll für TCP."ICMP" : Internet -Steuermeldungsprotokoll."IGMP" : Internet Group Management Protocol."IPIP" : IPIP -Tunnel (ältere Ka9q -Tunnel verwenden 94)."TCP" : Transmissionskontrollprotokoll."EGP" : Außenprotokoll."PUP" : Puppenprotokoll."UDP" : User Datagram Protocol."IDP" : XNS IDP -Protokoll."TP" : Daher transportieren Protokoll Klasse 4."DCCP" : Datagramm -Überlastungskontrollprotokoll."IPV6" : IPv6-in-IPV4-Tunneling."RSVP" : RSVP -Protokoll."GRE" : Cisco Gre Tunnels (RFC 1701.1702)."ESP" : Verkapselungssicherheitsnutzlastprotokoll."AH" : Authentifizierungs -Header -Protokoll."MTP" : Multicast -Transportprotokoll."BEETPH" : IP -Option Pseudo -Header für Rüben."ENCAP" : Kapselungsheader."PIM" : Protokollunabhängiges Multicast."COMP" : Kompressions -Header -Protokoll."SCTP" : Stream Control Transport Protocol."UDPLITE" : UDP-Lite (RFC 3828)."MPLS" : MPLS in IP (RFC 4023)."ETHERNET" : Ethernet-within-ipv6-Kapselung."RAW" : RAW IP -Pakete."MPTCP" : Multipath -TCP -Verbindung. sock:close() Sock: Close () entfernt sock aus dem System.
sock:send(message, [addr [, port]]) SOCK: SEND () sendet eine String message über die Socket sock . Wenn die sock af.INET ist, wird die folgenden Argumente erwartet:
addr : integer beschreibt die Ziel -IPv4 -Adresse.port : integer beschreibt den Ziel -IPv4 -Port.Ansonsten:
addr : Packed String, in dem die Zieladresse beschrieben wird. sock:receive(length, [flags [, from]]) Sock: empfangen () erhält eine Zeichenfolge mit bis zu length von Bytes durch die Socket sock . Die verfügbaren Nachrichtenflags werden in der Tabelle Socket.MSG definiert. Wenn from true ist, gibt es die empfangene Nachricht zurück, gefolgt von der Adresse des Peer. Andernfalls gibt es nur die empfangene Nachricht zurück.
socket.msgSocket.MSG ist eine Tabelle, die Nachrichtenflags in Lua exportiert.
"OOB" : n/a."PEEK" : n/a."DONTROUTE" : n/a."TRYHARD" : Synonym für "DONTROUTE" für Decnet."CTRUNC" : n/a."PROBE" : Senden Sie nicht. Nur Sondenpfad Fe für MTU."TRUNC" : n/a."DONTWAIT" : Nicht blockierende IO."EOR" : Ende der Aufzeichnung."WAITALL" : Warten Sie auf eine vollständige Anfrage."FIN" : n/a."SYN" : n/a."CONFIRM" : Pfadvalidität bestätigen."RST" : n/a."ERRQUEUE" : Meldung von der Fehlerwarteschlange abrufen."NOSIGNAL" : generieren Sie keine Sigpipe."MORE" : Der Absender wird mehr senden."WAITFORONE" : recvmmsg (): Blockieren Sie, bis 1+ Pakete verfügbar sind."SENDPAGE_NOPOLICY" : sendPage () intern: keine Richtlinie anwenden."SENDPAGE_NOTLAST" : sendPage () intern: nicht die letzte Seite."BATCH" : sendmmsg (): Weitere Nachrichten kommen."EOF" : n/a."NO_SHARED_FRAGS" : sendPage () intern: Seitenfrags werden nicht freigegeben."SENDPAGE_DECRYPTED" : SENDPAGE () INTERNEHT: PAGE kann einen einfachen Text tragen und Verschlüsselung erfordern."ZEROCOPY" : Verwenden Sie Benutzerdaten im Kernel -Pfad."FASTOPEN" : Daten in TCP Syn."CMSG_CLOEXEC" : setze close_on_exec für den Dateideskriptor, der über scm_rights empfangen wird. sock:bind(addr [, port]) Sock: Bind () bindet die Socket sock an eine bestimmte Adresse. Wenn die sock af.INET ist, wird die folgenden Argumente erwartet:
addr : integer beschreibt Host IPv4 -Adresse.port : integer beschreibt Host IPv4 -Port.Ansonsten:
addr : Packed String, die die Hostadresse beschreibt. sock:listen([backlog]) Sock: Hören () verschiebt die sock in den Hörzustand.
backlog : Ausstehende Verbindungen Warteschlangengröße. Wenn es weggelassen wird, verwendet es Somaxconn als Standard. sock:accept([flags]) Sock: Accept () akzeptiert eine Verbindung auf Socket sock . Es gibt ein neues socket -Objekt zurück. Die verfügbaren Flaggen sind auf der Socket.Sock -Tabelle vorhanden.
sock:connect(addr [, port] [, flags]) SOCK: Connect () verbindet die Socket sock mit dem addr . Wenn die sock af.INET ist, wird die folgenden Argumente erwartet:
addr : integer beschreibt die Ziel -IPv4 -Adresse.port : integer beschreibt den Ziel -IPv4 -Port.Ansonsten:
addr : Packed String, in dem die Zieladresse beschrieben wird.Die verfügbaren Flaggen sind auf der Socket.Sock -Tabelle vorhanden.
Für Datagramm -Sockets ist addr die Adresse, an die Datagramme standardmäßig gesendet werden, und die einzige Adresse, aus der Datagramme empfangen werden. Für Stream -Sockets Versuche, eine Verbindung zu addr .
sock:getsockname() SOCK: GETOCKNAME () Erhalten Sie die Adresse, an die die Socket sock gebunden ist. Wenn die sock af.INET ist, gibt sie Folgendes zurück:
addr : integer beschreibt die begrenzte IPv4 -Adresse.port : integer beschreibt den begrenzten IPv4 -Port.Ansonsten:
addr : Packed String, in dem die begrenzte Adresse beschrieben wird. sock:getpeername() SOCK: GetPeername () Holen Sie sich die Adresse, die die Socket sock angeschlossen ist. Wenn die sock af.INET ist, gibt sie Folgendes zurück:
addr : integer beschreibt die IPv4 -Adresse des Peer.port : integer beschreibt den IPv4 -Port des Peer.Ansonsten:
addr : Packed String, in dem die Adresse des Peer beschrieben wird. Die socket.inet Bibliothek bietet Unterstützung für hochrangige IPv4-Sockets.
inet.tcp() Inet.tcp () erstellt eine neue socket mit AF.Inet Adressfamilie, Sock.stream Typ und IpproTo.tcp Protocol. Es überschreibt socket -Methoden, um Adressen als Number-und-DOTS-Notation (z. B. "127.0.0.1" ) anstelle von Ganzzahlen zu verwenden.
inet.udp() Inet.Udp () erstellt eine neue socket mit AF.Inet Adressfamilie, Sock.dgram -Typ und IpproTo.UdP -Protokoll. Es überschreibt socket -Methoden, um Adressen als Number-und-DOTS-Notation (z. B. "127.0.0.1" ) anstelle von Ganzzahlen zu verwenden.
udp:receivefrom(length [, flags]) UDP: Empfesselfrom () ist nur ein Alias zu sock:receive(length, flags, true) .
Die rcu Bibliothek unterstützt den Kernel Read-Copy Update (RCU) -Synchronisationsmechanismus. Diese Bibliothek wurde vom GSOC -Projekt von Caio Messias inspiriert.
rcu.table([size]) rcu.table () erstellt ein neues rcu.table -Objekt, das die generische Hash -Tabelle von Kernel bindet. Diese Funktion empfängt als Argument die Anzahl der auf die nächsten Leistung von 2. abgerundeten Eimer. Die Standardgröße beträgt 1024 . Der Schlüssel muss ein Zeichenfolge sein und Wert muss ein Lunatik -Objekt oder ein Null sein.
Die thread -Bibliothek unterstützt die Kernel -Thread -Primitiven.
thread.run(runtime, name) Thread.run () erstellt ein neues thread -Objekt und weckt es auf. Diese Funktion empfängt die folgenden Argumente:
runtime : Die Laufzeitumgebung zum Ausführen einer Aufgabe im erstellten Kernel -Thread. Die Aufgabe muss angegeben werden, indem eine Funktion im Skript in der runtime zurückgegeben wird.name : Zeichenfolge, die den Namen für den Thread darstellt (z. B. wie in ps ). thread.shouldstop() thread.shouldStop () gibt true zurück, wenn thread.stop () genannt wurde; Ansonsten kehrt es false zurück.
thread.current() thread.current () gibt ein thread -Objekt zurück, das die aktuelle Aufgabe darstellt.
thrd:stop() Thrd: Stop () stellt Thread.ShouldStop () auf dem Thread thrd ein, um wahr zurückzukehren, weckt thrd und wartet darauf, dass es beendet.
thrd:task() Thrd: Task () gibt eine Tabelle zurück, die die Aufgabeninformationen dieses thread enthält (z. B. "CPU", "Befehl", "PID" und "TGID").
Die fib -Bibliothek unterstützt die Kernel -Weiterleitungsinformationsbasis.
fib.newrule(table, priority)fib.newrule () bindet die Kernel fib_nl_newrule api; Es erstellt eine neue FIB -Regel, die mit der angegebenen Priorioty mit der angegebenen Routing -Tabelle übereinstimmt. Diese Funktion ähnelt der von IPROUTE2 bereitgestellten IP-Regel des Benutzerraums.
fib.delrule(table, priority)fib.delrule () bindet die Kernel fib_nl_delrule api; Es entfernt eine FIB -Regel, die mit der angegebenen Priorioty mit der angegebenen Routing -Tabelle übereinstimmt. Diese Funktion ähnelt dem von IPROUTE2 bereitgestellten Benutzer-Space-Befehl IP-Regel del.
Die data unterstützt die Bindung des Systemspeichers an LuA.
data.new(size) Data.new () erstellt ein neues data , das size zuweist.
d:getnumber(offset) D: GetNumber () extrahiert einen lua_intener aus dem von einem data verwiesenen Speicher und einen Byte offset , beginnend von Null.
d:setnumber(offset, number) D: setNumber () Fügen Sie eine lUA_Integer number in den Speicher ein, auf den ein data und ein Byte offset von Null bezeichnet werden.
d:getbyte(offset) D: GetByte () extrahiert ein Byte aus dem Speicher, auf das ein data und ein Byte offset aus Null bezeichnet werden.
d:setbyte(offset, byte) D: setByte () Ein Byte in den Speicher einfügen, auf das ein data und ein Byte offset in Null bezeichnet werden.
d:getstring(offset[, length]) D: GetString () extrahiert eine Zeichenfolge mit length Bytes aus dem von einem data verwiesenen Speicher und einem Byte offset von Null. Wenn length weggelassen wird, extrahiert sie alle Bytes vom offset bis zum Ende der data .
d:setstring(offset, s) D: setString () Einfügen die Zeichenfolge s in den von einem data verwiesenen Speicher und einen Byte offset , beginnend von Null.
d:getint8(offset) D: GetInt8 (D, Offset) extrahiert eine signierte 8-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setint8(offset, number) D: setInt8 () fügt eine signierte 8-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getuint8(offset) D: Getuint8 () extrahiert eine nicht signierte 8-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setuint8(offset, number) D: setUint8 () fügt eine nicht signierte 8-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getint16(offset) D: GetInt16 () Extrahiert eine signierte 16-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setint16(offset, number) D: setInt16 () fügt eine signierte 16-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getuint16(offset) D: Getuint16 () extrahiert eine nicht signierte 16-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setuint16(offset, number) D: setUint16 () fügt eine nicht signierte 16-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getint32(offset) D: GetInt32 () Extrahiert eine signierte 32-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setint32(offset, number) D: setInt32 () fügt eine signierte 32-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getuint32(offset) D: GETUINT32 () Extrahiert eine nicht signierte 32-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setuint32(offset, number) D: SETUINT32 () fügt eine nicht signierte 32-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
d:getint64(offset) D: GetInt64 () Extrahiert eine signierte 64-Bit-Ganzzahl aus dem Speicher, auf das ein data und ein Byte- offset von Null abgewiesen werden.
d:setint64(offset, number) D: setInt64 () fügt eine signierte 64-Bit-Nummer in den Speicher ein, auf den ein data und ein Byte- offset von Null bezeichnet werden.
Die probe unterstützt Kernelsonden.
probe.new(symbol|address, handlers) Sonde.new () gibt ein neues probe zur Überwachung eines Kernel symbol (String) oder address (leichte UserData) zurück und installiert seine handlers im System. Der handler muss als eine Tabelle definiert werden, die das folgende Feld enthält:
pre : Funktion, die vor der untersuchten Anweisung aufgerufen werden soll. Es empfängt das symbol oder address , gefolgt von einer Schließung, die aufgerufen werden kann, um die CPU -Register und den Stapel im Systemprotokoll anzuzeigen.post : Funktion, die nach der untersuchten Anweisung aufgerufen werden soll. Es empfängt das symbol oder address , gefolgt von einer Schließung, die aufgerufen werden kann, um die CPU -Register und den Stapel im Systemprotokoll anzuzeigen. p:stop() P: Stop () entfernt die probe aus dem System.
p:enable(bool) P: Enable () aktiviert oder deaktiviert die probe , entsprechend bool .
Die syscall -Bibliothek bietet Unterstützung für Systemanrufadressen und Nummern.
syscall.address(number) syscall.address () gibt die Systemaufrufadresse (Light UserData) zurück, auf die die angegebene number bezeichnet wird.
syscall.number(name) syScall.number () gibt die Systemaufrufnummer zurück, auf die der angegebene name verwiesen wird.
Die Bibliothek syscall.table bietet Unterstützung für Übersetzungssystem -Anrufnamen für Adressen (Light UserData).
Die xdp -Bibliothek unterstützt das Kernel Express Data Path (XDP) -Subsystem. Diese Bibliothek wurde vom GSOC -Projekt von Victor Nogueira inspiriert.
xdp.attach(callback) XDP.attach () registriert eine callback zur aktuellen runtime , die von einem XDP/EBPF -Programm aufgerufen werden soll, wenn es BPF_LUAXDP_RUN KFUNC aufruft. Dieser callback erhält die folgenden Argumente:
buffer : Ein data , das den Netzwerkpuffer darstellt.argument : Ein data , das das vom XDP/EBPF -Programm übergebene Argument enthält. Die callback kann die von der XDP.Action -Tabelle definierten Werte zurückgeben.
xdp.detach() XDP.Detach () Unregistriert den callback , das mit der aktuellen runtime zugeordnet ist, falls vorhanden.
xdp.actionXDP.Action ist eine Tabelle, in der XDP_Action -Flags in Lua exportiert werden.
"ABORTED" : Zeigt an, dass das XDP -Programm abgebrochen wurde, typischerweise aufgrund eines Fehlers."DROP" : Gibt an, dass das Paket fallen gelassen werden sollte und es vollständig verworfen."PASS" : Ermöglicht das Paket an den Linux -Netzwerkstapel."TX" : Überträgt das Paket wieder auf derselben Schnittstelle, die er empfangen hat."REDIRECT" : Umleitet das Paket in eine andere Schnittstelle oder Verarbeitungskontext. Die xtable -Bibliothek unterstützt die Entwicklung von Netfilter Xtable -Erweiterungen.
xtable.match(opts)Xtable.match () gibt ein neues Xtable -Objekt für Übereinstimmungen zurück. Diese Funktion empfängt die folgenden Argumente:
opts : Eine Tabelle mit den folgenden Feldern:name : Zeichenfolge, die den Xtable -Erweiterungsnamen darstellt.revision : Ganzzahl, die die Xtable -Erweiterungsrevision darstellt.family : Adressfamilie, einer von Netfilter.Family.proto : Protokollnummer, einer von Socket.IPProto.hooks : Haken, um die Erweiterung an einen Wert aus einer der Hooks -Tabelle anzubringen - netfilter.inet_hooks, netfilter.bridge_hooks und netfilter.arp_hooks (Hinweis: netfilter.netdev_hooks ist nicht für legacy x_tables verfügbar). (ZB - 1 << inet_hooks.LOCAL_OUT ).match : Funktion, die für passende Pakete aufgerufen werden soll. Es erhält die folgenden Argumente:skb (readonly): Ein data , das den Socket -Puffer darstellt.par : Ein Tisch mit hotdrop , thoff (Transportheader -Offset) und fragoff -Feldern (Fragment -Offset).userargs : Eine Lua -Zeichenfolge, die vom UserSpace Xtable -Modul übergeben wurde.true zurückgeben, wenn das Paket mit der Erweiterung übereinstimmt. Ansonsten muss es false zurückgeben.checkentry : Funktion zum Überprüfen des Eintrags. Diese Funktion empfängt userargs als Argument.destroy : Funktion, um die Xtable -Erweiterung zu zerstören. Diese Funktion empfängt userargs als Argument. xtable.target(opts)xtable.target () gibt ein neues Xtable -Objekt für die Zielerweiterung zurück. Diese Funktion empfängt die folgenden Argumente:
opts : Eine Tabelle mit den folgenden Feldern:name : Zeichenfolge, die den Xtable -Erweiterungsnamen darstellt.revision : Ganzzahl, die die Xtable -Erweiterungsrevision darstellt.family : Adressfamilie, einer von Netfilter.Family.proto : Protokollnummer, einer von Socket.IPProto.hooks : Haken, um die Erweiterung an einen Wert aus einer der Hooks -Tabelle anzubringen - netfilter.inet_hooks, netfilter.bridge_hooks und netfilter.arp_hooks (Hinweis: netfilter.netdev_hooks ist nicht für legacy x_tables verfügbar). (ZB - 1 << inet_hooks.LOCAL_OUT ).target : Funktion, die für Targeting -Pakete aufgerufen werden soll. Es erhält die folgenden Argumente:skb : Ein data , das den Socket -Puffer darstellt.par (readonly): eine Tabelle mit hotdrop , thoff (Transportheader -Offset) und fragoff (Fragment -Offset) -Felder.userargs : Eine Lua -Zeichenfolge, die vom UserSpace Xtable -Modul übergeben wurde.checkentry : Funktion zum Überprüfen des Eintrags. Diese Funktion empfängt userargs als Argument.destroy : Funktion, um die Xtable -Erweiterung zu zerstören. Diese Funktion empfängt userargs als Argument. Die netfilter -Bibliothek unterstützt das neue Netfilter Hook -System.
netfilter.register(ops) netfilter.register () registriert einen neuen Netfilter -Haken mit der angegebenen ops -Tabelle. Diese Funktion empfängt die folgenden Argumente:
ops : Eine Tabelle mit den folgenden Feldern:pf : Protokollfamilie, eine von NetFilter.Familyhooknum : Haken, um den Filter an einen Wert aus einer der Hooks -Tabelle anzubringen - netfilter.inet_hooks, netfilter.bridge_hooks, netfilter.arp_hooks und netfilter.netdev_hooks. (EG - inet_hooks.LOCAL_OUT + 11 ).priority : Priorität des Hakens. Einer der Werte aus dem netfilter.ip_priority oder netfilter.bridge_priority tables.hook : Funktion, die für den Haken gerufen werden soll. Es erhält die folgenden Argumente:skb : a data object representing the socket buffer.netfilter.familynetfilter.family is a table that exports address families to Lua.
"UNSPEC" : Unspecified."INET" : Internet Protocol version 4."IPV4" : Internet Protocol version 4."IPV6" : Internet Protocol version 6."ARP" : Address Resolution Protocol."NETDEV" : Device ingress and egress path"BRIDGE" : Ethernet Bridge. netfilter.actionnetfilter.action is a table that exports netfilter actions to Lua.
"DROP" : NF_DROP . The packet is dropped. It is not forwarded, processed, or seen by any other network layer."ACCEPT" : NF_ACCEPT . The packet is accepted and passed to the next step in the network processing chain."STOLEN" : NF_STOLEN . The packet is taken by the handler, and processing stops."QUEUE" : NF_QUEUE . The packet is queued for user-space processing."REPEAT" : NF_REPEAT . The packet is sent through the hook chain again."STOP" : NF_STOP . Processing of the packet stops."CONTINUE" : XT_CONTINUE . Return the packet should continue traversing the rules within the same table."RETURN" : XT_RETURN . Return the packet to the previous chain. netfilter.inet_hooksnetfilter.inet_hooks is a table that exports inet netfilter hooks to Lua.
"PRE_ROUTING" : NF_INET_PRE_ROUTING . The packet is received by the network stack."LOCAL_IN" : NF_INET_LOCAL_IN . The packet is destined for the local system."FORWARD" : NF_INET_FORWARD . The packet is to be forwarded to another host."LOCAL_OUT" : NF_INET_LOCAL_OUT . The packet is generated by the local system."POST_ROUTING" : NF_INET_POST_ROUTING . The packet is about to be sent out. netfilter.bridge_hooksnetfilter.bridge_hooks is a table that exports bridge netfilter hooks to Lua.
"PRE_ROUTING" : NF_BR_PRE_ROUTING . First hook invoked, runs before forward database is consulted."LOCAL_IN" : NF_BR_LOCAL_IN . Invoked for packets destined for the machine where the bridge was configured on."FORWARD" : NF_BR_FORWARD . Called for frames that are bridged to a different port of the same logical bridge device."LOCAL_OUT" : NF_BR_LOCAL_OUT . Called for locally originating packets that will be transmitted via the bridge."POST_ROUTING" : NF_BR_POST_ROUTING . Called for all locally generated packets and all bridged packets netfilter.arp_hooksnetfilter.arp_hooks is a table that exports arp netfilter hooks to Lua.
"IN" : NF_ARP_IN . The packet is received by the network stack."OUT" : NF_ARP_OUT . The packet is generated by the local system."FORWARD" : NF_ARP_FORWARD . The packet is to be forwarded to another host. netfilter.netdev_hooksnetfilter.netdev_hooks is a table that exports netdev netfilter hooks to Lua.
"INGRESS" : NF_NETDEV_INGRESS . The packet is received by the network stack."EGRESS" : NF_NETDEV_EGRESS . The packet is generated by the local system. netfilter.ip_prioritynetfilter.ip_priority is a table that exports netfilter IPv4/IPv6 priority levels to Lua.
"FIRST" : NF_IP_PRI_FIRST"RAW_BEFORE_DEFRAG" : NF_IP_PRI_RAW_BEFORE_DEFRAG"CONNTRACK_DEFRAG" : NF_IP_PRI_CONNTRACK_DEFRAG"RAW" : NF_IP_PRI_RAW"SELINUX_FIRST" : NF_IP_PRI_SELINUX_FIRST"CONNTRACK" : NF_IP_PRI_CONNTRACK"MANGLE" : NF_IP_PRI_MANGLE"NAT_DST" : NF_IP_PRI_NAT_DST"FILTER" : NF_IP_PRI_FILTER"SECURITY" : NF_IP_PRI_SECURITY"NAT_SRC" : NF_IP_PRI_NAT_SRC"SELINUX_LAST" : NF_IP_PRI_SELINUX_LAST"CONNTRACK_HELPER" : NF_IP_PRI_CONNTRACK_HELPER"LAST" : NF_IP_PRI_LAST netfilter.bridge_prioritynetfilter.bridge_priority is a table that exports netfilter bridge priority levels to Lua.
"FIRST" : NF_BR_PRI_FIRST"NAT_DST_BRIDGED" : NF_BR_PRI_NAT_DST_BRIDGED"FILTER_BRIDGED" : NF_BR_PRI_FILTER_BRIDGED"BRNF" : NF_BR_PRI_BRNF"NAT_DST_OTHER" : NF_BR_PRI_NAT_DST_OTHER"FILTER_OTHER" : NF_BR_PRI_FILTER_OTHER"NAT_SRC" : NF_BR_PRI_NAT_SRC"LAST" : NF_BR_PRI_LAST The luaxt userspace library provides support for generating userspace code for xtable extensions.
To build the library, the following steps are required:
usr/lib/xtable and create a libxt_<ext_name>.lua file.luaxt ) in the created file.LUAXTABLE_MODULE=<ext_name> make to build the extension and LUAXTABLE_MODULE=<ext_name> make install (as root) to install the userspace plugin to the system. Now load the extension normally using iptables .
luaxt.match(opts)luaxt.match() returns a new luaxt object for match extensions. This function receives the following arguments:
opts : a table containing the following fields:revision : integer representing the xtable extension revision ( must be same as used in corresponding kernel extension).family : address family, one of luaxt.familyhelp : function to be called for displaying help message for the extension.init : function to be called for initializing the extension. This function receives an par table that can be used to set userargs . ( par.userargs = "mydata" )print : function to be called for printing the arguments. This function recevies userargs set by the init or parse function.save : function to be called for saving the arguments. This function recevies userargs set by the init or parse function.parse : function to be called for parsing the command line arguments. This function receives an par table that can be used to set userargs and flags . ( par.userargs = "mydata" )final_check : function to be called for final checking of the arguments. This function receives flags set by the parse function. luaxt.target(opts)luaxt.target() returns a new luaxt object for target extensions. This function receives the following arguments:
opts : a table containing the following fields:revision : integer representing the xtable extension revision ( must be same as used in corresponding kernel extension).family : address family, one of luaxt.familyhelp : function to be called for displaying help message for the extension.init : function to be called for initializing the extension. This function receives an par table that can be used to set userargs . ( par.userargs = "mydata" )print : function to be called for printing the arguments. This function recevies userargs set by the init or parse function.save : function to be called for saving the arguments. This function recevies userargs set by the init or parse function.parse : function to be called for parsing the command line arguments. This function receives an par table that can be used to set userargs and flags . ( par.userargs = "mydata" )final_check : function to be called for final checking of the arguments. This function receives flags set by the parse function. luaxt.familyluaxt.family is a table that exports address families to Lua.
"UNSPEC" : Unspecified."INET" : Internet Protocol version 4."IPV4" : Internet Protocol version 4."IPV6" : Internet Protocol version 6."ARP" : Address Resolution Protocol."NETDEV" : Device ingress and egress path"BRIDGE" : Ethernet Bridge.completion The completion library provides support for the kernel completion primitives.
Task completion is a synchronization mechanism used to coordinate the execution of multiple threads, similar to pthread_barrier , it allows threads to wait for a specific event to occur before proceeding, ensuring certain tasks are complete in a race-free manner.
completion.new() completion.new() creates a new completion object.
c:complete()c:complete() signals a single thread waiting on this completion.
c:wait([timeout]) c:wait() waits for completion of a task until the specified timeout expires. The timeout is specified in milliseconds. If the timeout parameter is omitted, it waits indefinitely. Passing a timeout value less than zero results in undefined behavior. Threads waiting for events can be interrupted by signals, for example, such as when thread.stop is invoked. Therefore, this function can return in three ways:
truenil, "timeout"nil, "interrupt" spyglass is a kernel script that implements a keylogger inspired by the spy kernel module. This kernel script logs the keysym of the pressed keys in a device ( /dev/spyglass ). If the keysym is a printable character, spyglass logs the keysym itself; otherwise, it logs a mnemonic of the ASCII code, (eg, <del> stands for 127 ).
sudo make examples_install # installs examples
sudo lunatik run examples/spyglass # runs spyglass
sudo tail -f /dev/spyglass # prints the key log
sudo sh -c "echo 'enable=false' > /dev/spyglass" # disable the key logging
sudo sh -c "echo 'enable=true' > /dev/spyglass" # enable the key logging
sudo sh -c "echo 'net=127.0.0.1:1337' > /dev/spyglass" # enable network support
nc -lu 127.0.0.1 1337 & # listen to UDP 127.0.0.1:1337
sudo tail -f /dev/spyglass # sends the key log through the network
keylocker is a kernel script that implements Konami Code for locking and unlocking the console keyboard. When the user types ↑ ↑ ↓ ↓ ← → ← → LCTRL LALT , the keyboard will be locked ; that is, the system will stop processing any key pressed until the user types the same key sequence again.
sudo make examples_install # installs examples
sudo lunatik run examples/keylocker # runs keylocker
<↑> <↑> <↓> <↓> <←> <→> <←> <→> <LCTRL> <LALT> # locks keyboard
<↑> <↑> <↓> <↓> <←> <→> <←> <→> <LCTRL> <LALT> # unlocks keyboard
tap is a kernel script that implements a sniffer using AF_PACKET socket. It prints destination and source MAC addresses followed by Ethernet type and the frame size.
sudo make examples_install # installs examples
sudo lunatik run examples/tap # runs tap
cat /dev/tap
shared is a kernel script that implements an in-memory key-value store using rcu, data, socket and thread.
sudo make examples_install # installs examples
sudo lunatik spawn examples/shared # spawns shared
nc 127.0.0.1 90 # connects to shared
foo=bar # assigns "bar" to foo
foo # retrieves foo
bar
^C # finishes the connection
echod is an echo server implemented as kernel scripts.
sudo make examples_install # installs examples
sudo lunatik spawn examples/echod/daemon # runs echod
nc 127.0.0.1 1337
hello kernel!
hello kernel!
systrack is a kernel script that implements a device driver to monitor system calls. It prints the amount of times each system call was called since the driver has been installed.
sudo make examples_install # installs examples
sudo lunatik run examples/systrack # runs systracker
cat /dev/systrack
writev: 0
close: 1927
write: 1085
openat: 2036
read: 4131
readv: 0
filter is a kernel extension composed by a XDP/eBPF program to filter HTTPS sessions and a Lua kernel script to filter SNI TLS extension. This kernel extension drops any HTTPS request destinated to a blacklisted server.
Compile and install libbpf , libxdp and xdp-loader :
mkdir -p " ${LUNATIK_DIR} " ; cd " ${LUNATIK_DIR} " # LUNATIK_DIR must be set to the same value as above (Setup section)
git clone --depth 1 --recurse-submodules https://github.com/xdp-project/xdp-tools.git
cd xdp-tools/lib/libbpf/src
make
sudo DESTDIR=/ make install
cd ../../../
make libxdp
cd xdp-loader
make
sudo make installCome back to this repository, install and load the filter:
cd ${LUNATIK_DIR} /lunatik # cf. above
sudo make btf_install # needed to export the 'bpf_luaxdp_run' kfunc
sudo make examples_install # installs examples
make ebpf # builds the XDP/eBPF program
sudo make ebpf_install # installs the XDP/eBPF program
sudo lunatik run examples/filter/sni false # runs the Lua kernel script
sudo xdp-loader load -m skb < ifname > https.o # loads the XDP/eBPF programFor example, testing is easy thanks to docker. Assuming docker is installed and running:
sudo xdp-loader load -m skb docker0 https.o
sudo journalctl -ft kerneldocker run --rm -it alpine/curl https://ebpf.io The system logs (in the first terminal) should display filter_sni: ebpf.io DROP , and the docker run… should return curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to ebpf.io:443 .
This other sni filter uses netfilter api.
dnsblock is a kernel script that uses the lunatik xtable library to filter DNS packets. This script drops any outbound DNS packet with question matching the blacklist provided by the user.
sudo make examples_install # installs examples
cd examples/dnsblock
make # builds the userspace extension for netfilter
sudo make install # installs the extension to Xtables directory
sudo lunatik run examples/dnsblock/dnsblock false # runs the Lua kernel script
sudo iptables -A OUTPUT -m dnsblock -j DROP # this initiates the netfilter framework to load our extension
sudo make examples_install # installs examples
sudo lunatik run examples/dnsblock/nf_dnsblock false # runs the Lua kernel script
dnsdoctor is a kernel script that uses the lunatik xtable library to change the DNS response from Public IP to a Private IP if the destination IP matches the one provided by the user. For example, if the user wants to change the DNS response from 192.168.10.1 to 10.1.2.3 for the domain lunatik.com if the query is being sent to 10.1.1.2 (a private client), this script can be used.
sudo make examples_install # installs examples
cd examples/dnsdoctor
setup.sh # sets up the environment
# test the setup, a response with IP 192.168.10.1 should be returned
dig lunatik.com
# run the Lua kernel script
sudo lunatik run examples/dnsdoctor/dnsdoctor false
# build and install the userspace extension for netfilter
make
sudo make install
# add rule to the mangle table
sudo iptables -t mangle -A PREROUTING -p udp --sport 53 -j dnsdoctor
# test the setup, a response with IP 10.1.2.3 should be returned
dig lunatik.com
# cleanup
sudo iptables -t mangle -D PREROUTING -p udp --sport 53 -j dnsdoctor # remove the rule
sudo lunatik unload
cleanup.sh
sudo make examples_install # installs examples
examples/dnsdoctor/setup.sh # sets up the environment
# test the setup, a response with IP 192.168.10.1 should be returned
dig lunatik.com
# run the Lua kernel script
sudo lunatik run examples/dnsdoctor/nf_dnsdoctor false
# test the setup, a response with IP 10.1.2.3 should be returned
dig lunatik.com
# cleanup
sudo lunatik unload
examples/dnsdoctor/cleanup.sh
Lunatik is dual-licensed under MIT or GPL-2.0-only.
Lua submodule is licensed under MIT. For more details, see its Copyright Notice.
Klibc submodule is dual-licensed under BSD 3-Clause or GPL-2.0-only. For more details, see its LICENCE file.