Lunatik은 LUA로 Linux 커널을 스크립팅하기위한 프레임 워크입니다. 커널에서 실행되도록 수정 된 LUA 통역사에 의해 구성됩니다. 장치 드라이버 (LUA =) 및 사용자 공간에서 스크립트를로드 및 실행하고 실행하는 명령 줄 도구; 커널에서 스크립트를로드 및 실행하고 런타임 환경을 관리하는 C API; 커널 시설을 LUA 스크립트에 바인딩하기위한 LUA API.
다음은 Lunatik을 사용하여 LUA로 작성된 캐릭터 장치 드라이버의 예입니다. 무작위 ASCII 인쇄용 문자를 생성합니다.
-- /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 )의존성을 설치하십시오 (여기서 Debian/Ubuntu의 경우, 분포에 적합) :
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 컴파일하고 설치하십시오.
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 일단 완료되면 debian_kernel_postinst_lunatik.sh script의 도구 /etc/kernel/postinst.d/ 에 복사 될 수 있습니다. : lunatik (및 xdp 필요한 Libs)이 커널 업그레이드에서 컴파일됩니다.
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 : Lunatik 커널 모듈을로드하십시오unload : 언로드 Lunatik 커널 모듈reload : Reload Lunatik 커널 모듈status : 현재로드 된 Lunatik 커널 모듈 표시list : 현재 실행중인 런타임 환경을 보여주십시오run : 스크립트 /lib/modules/lua/<script>.lua lua/<script> .lua를 실행하기 위해 새로운 런타임 환경을 만듭니다.spawn : 새 런타임 환경을 만들고 스크립트를 스폰하여 스크립트 /lib/modules/lua/<script>.lua <script> .lua를 실행합니다.stop : 스크립트 <script> 를 실행하기 위해 생성 된 런타임 환경 중지default : REPL 시작 (읽기 – EVAL - 프린트 루프) Lunatik 3.4는 커널에서 실행되도록 조정 된 LUA 5.4를 기반으로합니다.
Lunatik은 부동 소수점 산술을 지원 하지 않으므로 __div 또는 __pow metamethods를 지원 하지 않으며 유형 번호는 하위 유형 정수 만 있습니다.
Lunatik은 IO 및 OS 라이브러리와 다음 라이브러리에서 주어진 식별자를 모두 지원 하지 않습니다 .
Lunatik은 다음 식별자를 수정합니다 .
"Lua 5.4-kernel" 으로 정의됩니다."/lib/modules/lua/?.lua;/lib/modules/lua/?/init.lua" 로 정의됩니다.Lunatik은 lual_stream, lual_execresult, lual_fileresult, luaopen_io 및 luaopen_os를 지원 하지 않습니다 .
lunatik은 luaopen_io 및 luaopen_os를 제거하기 위해 lual_openlibs를 수정합니다 .
#include <lunatik.h> int lunatik_runtime ( lunatik_object_t * * pruntime , const char * script , bool sleep ); lunatik_runtime ()은 새로운 runtime 환경을 생성 한 다음이 환경의 진입 점으로 스크립트 /lib/modules/lua/<script>.lua lua/<script> .lua를로드하고 실행합니다. 프로세스 컨텍스트 에서만 호출되어야 합니다 . runtime 환경은 LUA 상태를 유지하는 Lunatik 객체입니다. Lunatik 객체는 잠금 유형과 참조 카운터를 보유하는 특수 LUA userData입니다. sleep 이 사실 이면 Lunatik_runtime ()은 runtime 환경을 잠그기 위해 Mutx를 사용하고 gfp_kernel 플래그는 나중에 lunatik_run () 호출에 새 메모리를 할당합니다. 그렇지 않으면 스핀 락과 gfp_atomic을 사용합니다. lunatik_runtime ()은 Lunatik에있는 LUA 표준 라이브러리를 엽니 다. 성공하면 Lunatik_runtime ()은 새로운 생성 된 runtime 환경에 대한 포인터로 pruntime 과 Lua의 추가 공간을 가리키는 주소를 설정하고 참조 카운터를 1 으로 설정 한 다음 0 반환합니다. 그렇지 않으면 메모리가 불충분 한 경우 -ENOMEM 반환합니다. 또는 -EINVAL , script 로드하거나 실행하지 못한 경우.
-- /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 () 은이 runtime 환경을 위해 생성 된 LUA 상태를 닫고 참조 카운터를 줄입니다. 참조 카운터가 0으로 감소되면 잠금 유형과 runtime 환경에 할당 된 메모리가 해제됩니다. runtime 환경이 릴리스되면 1 반환됩니다. 그렇지 않으면 0 반환합니다.
void lunatik_run ( lunatik_object_t * runtime , < inttype > ( * handler )(...), < inttype > & ret , ...); lunatik_run ()은 runtime 환경을 잠그고 관련 LUA 상태를 전달한 handler 첫 번째 인수와 변형 인수로 호출합니다. Lua 상태가 폐쇄 된 경우 ret -ENXIO 로 설정됩니다. 그렇지 않으면 ret handler(L, ...) 호출 결과로 설정됩니다. 그런 다음 LUA 스택을 복원하고 runtime 환경을 잠금 해제합니다. 매크로로 정의됩니다.
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 ()는 이 object 의 참조 카운터 (예 : runtime 환경)를 증가시킵니다.
int lunatik_putobject ( lunatik_object_t * object ); lunatik_putoBject ()는 이 object 의 참조 카운터 (예 : runtime 환경)를 줄입니다. object 가 해제되면 1 반환합니다. 그렇지 않으면 0 반환합니다.
lunatik_object_t * lunatik_toruntime ( lua_State * L ); lunatik_toruntime ()은 L '의 추가 공간에서 언급 한 runtime 환경을 반환합니다.
lunatik 라이브러리는 LUA에서 스크립트를로드 및 실행하고 런타임 환경을 관리하는 지원을 제공합니다.
lunatik.runtime(script [, sleep]) lunatik.runtime ()은 새로운 런타임 환경을 생성 한 다음이 환경의 진입 점으로 스크립트 /lib/modules/lua/<script>.lua 로드하고 실행합니다. runtime 환경을 나타내는 Lunatik 객체를 반환합니다. sleep 이 사실 이거나 생략되면 Mutex 및 GFP_Kernel을 사용합니다. 그렇지 않으면 스핀 락과 gfp_atomic을 사용합니다. Lunatik.runtime ()은 Lunatik에있는 LUA 표준 라이브러리를 엽니 다.
runtime:stop() 런타임 : stop ()는 runtime 환경을 중지하고 런타임 객체에서 참조를 지우십시오.
runtime:resume([obj1, ...]) 런타임 : resume ()은 runtime 실행을 재개합니다. 값 obj1, ... runtime 생성에서 반환 된 함수에 대한 인수로 전달됩니다. runtime 산출 된 경우 resume() 을 다시 시작합니다. 값 obj1, ... 수율의 결과로 전달됩니다.
device 라이브러리는 LUA의 문자 장치 드라이버 작성을 지원합니다.
device.new(driver) device.new () 새 device 객체를 반환하고 시스템에 driver 설치합니다. driver 다음 필드를 포함하는 테이블로 정의 되어야 합니다.
name : 문자열 장치 이름을 정의합니다. 장치 파일을 작성하는 데 사용됩니다 (예 : /dev/<name> ). driver 테이블에는 선택적으로 다음 필드가 포함될 수 있습니다.
read : 콜백 함수 장치 파일에서 읽기 작업을 처리합니다. driver 테이블을 첫 번째 인수와 두 개의 정수, 읽기 length 및 파일 offset 으로 수신합니다. 문자열을 반환하고 선택적으로 updated offset 반환해야합니다. 반환 된 문자열의 길이가 요청 된 length 보다 크면 문자열이 해당 length 로 수정됩니다. updated offset 반환되지 않으면 offset offset + length 로 업데이트됩니다.write : 콜백 함수 장치 파일에서 쓰기 작업을 처리합니다. driver 테이블을 첫 번째 인수로 작성하고 문자열이 쓸 수 있고 파일 offset 으로 정수를받습니다. 선택적으로 서면 length 와 updated offset 반환 될 수 있습니다. 반환 된 길이가 요청 된 length 보다 크면 반환 된 길이가 수정됩니다. updated offset 반환되지 않으면 offset offset + length 로 업데이트됩니다.open : 콜백 함수 장치 파일에서 열기 작업을 처리합니다. driver 테이블을 받고 아무것도 반환 할 것으로 예상됩니다.release : 콜백 함수 장치 파일의 릴리스 작업을 처리합니다. driver 테이블을 받고 아무것도 반환 할 것으로 예상됩니다.mode : 장치 파일 모드를 지정하는 정수. 작동 콜백이 정의되지 않으면 device 액세스 할 때 -ENXIO VFS로 반환합니다.
device.stop(dev) , dev:stop() Device.stop () 시스템에서 dev 객체에서 지정된 장치 driver 제거합니다.
linux 라이브러리는 일부 Linux 커널 시설을 지원합니다.
linux.random([m [, n]])Linux.random ()은 Math.random의 동작을 모방하지만 <linux/random.h> 의 get_random_u32 () 및 get_random_u64 () API를 바인딩합니다.
인수없이 호출되면 모든 비트 (Pseudo) 임의의 정수를 생성합니다. 두 개의 정수 m 과 n 으로 호출되면 linux.random ()은 [m, n] 범위에서 균일 한 분포를 가진 의사 랜덤 정수를 반환합니다. POCITAL n 의 CALL math.random(n) 은 math.random(1, n) 과 같습니다.
linux.statLinux.stat 는 <linux/stat.h> 정수 플래그를 LUA로 내보내는 테이블입니다.
"IRWXUGO" : 사용자 , 그룹 및 기타를 위해 읽고 , 쓰기 및 실행할 수있는 권한."IRUGO" : 사용자 , 그룹 및 기타를 위해 읽을 수있는 권한."IWUGO" : 사용자 , 그룹 및 기타를 위해서만 쓸 수있는 권한."IXUGO" : 사용자 , 그룹 및 기타를 위해 실행할 수있는 권한. linux.schedule([timeout [, state]]) Linux.schedule ()은 현재 작업 state 설정하고 timeout 밀리 초가 경과 할 때까지 IT 잠을 자게 만듭니다. timeout 생략되면 MAX_SCHEDULE_TIMEOUT 사용합니다. state 생략되면 task.INTERRUPTIBLE 사용합니다.
linux.taskLinux.task 는 작업 상태 플래그를 LUA로 내보내는 테이블입니다.
"RUNNING" : 작업이 CPU에서 실행되거나 실행되기를 기다리고 있습니다."INTERRUPTIBLE" : 작업이 신호 또는 자원 (수면)을 기다리고 있습니다."UNINTERRUPTIBLE" : 신호가 작업을 깨우지 않는다는 점을 제외하고 "인터럽 가능한"처럼 행동합니다."KILLABLE" : 치명적인 신호가 작업을 깨우는 것을 제외하고 "무질서 수준"처럼 행동합니다."IDLE" : LoadAVG 회계를 피하는 것을 제외하고 "무질서 수준"처럼 행동합니다. linux.time()Linux.time ()은 현재 시간을 epoch 이후 나노초로 반환합니다.
linux.errnoLinux.errno는 <uapi/asm-generic/errno-base.h> 플래그를 lua로 내보내는 테이블입니다.
"PERM" : 작동하지 않습니다."NOENT" : 그러한 파일이나 디렉토리가 없습니다."SRCH" : 그러한 과정이 없습니다."INTR" : 방해 시스템 호출."IO" : I/O 오류."NXIO" : 그러한 장치 나 주소가 없습니다."2BIG" :, 인수 목록이 너무 길다."NOEXEC" : EXEC 형식 오류."BADF" : 잘못된 파일 번호."CHILD" : 아동 과정이 없습니다."AGAIN" : 다시 시도하십시오."NOMEM" : 기억이 나지 않습니다."ACCES" : 허가 거부."FAULT" : 나쁜 주소."NOTBLK" : 블록 장치가 필요합니다."BUSY" : 장치 또는 자원이 바쁘다."EXIST" : 파일이 존재합니다."XDEV" : 교차 기기 링크."NODEV" : 그러한 장치가 없습니다."NOTDIR" : 디렉토리가 아닙니다."ISDIR" : 디렉토리입니다."INVAL" : 잘못된 인수."NFILE" : 파일 테이블 오버플로."MFILE" : 너무 많은 파일."NOTTY" : 타자기가 아닙니다."TXTBSY" : 텍스트 파일이 바쁘다."FBIG" : 파일이 너무 큽니다."NOSPC" : 장치에 남은 공간이 없습니다."SPIPE" : 불법 추구."ROFS" : 읽기 전용 파일 시스템."MLINK" : 너무 많은 링크."PIPE" : 파장이 깨진 파이프."DOM" : Func의 영역에서 수학 논쟁."RANGE" : 수학 결과는 표현되지 않습니다. linux.hton16(num)linux.hton16 ()는 호스트 바이트 오더를 16 비트 정수의 네트워크 바이트 순서로 변환합니다.
linux.hton32(num)Linux.hton32 ()는 32 비트 정수의 경우 호스트 바이트 오더를 네트워크 바이트 순서로 변환합니다.
linux.hton64(num)Linux.hton64 ()는 호스트 바이트 오더를 64 비트 정수의 네트워크 바이트 순서로 변환합니다.
linux.ntoh16(num)linux.ntoh16 () 네트워크 바이트 오더를 16 비트 정수의 바이트 오더로 변환합니다.
linux.ntoh32(num)linux.ntoh32 () 네트워크 바이트 오더를 32 비트 정수의 바이트 오더로 변환합니다.
linux.ntoh64(num)linux.ntoh64 () 네트워크 바이트 오더를 64 비트 정수의 바이트 오더로 변환합니다.
linux.htobe16(num)Linux.htobe16 ()는 16 비트 정수를 위해 호스트 바이트 순서를 Big-Endian Byte Order로 변환합니다.
linux.htobe32(num)Linux.htobe32 ()는 32 비트 정수를 위해 호스트 바이트 순서를 대기업 바이트 순서로 변환합니다.
linux.htobe64(num)Linux.htobe64 ()는 64 비트 정수를 위해 호스트 바이트 순서를 Big-Endian Byte Order로 변환합니다.
linux.be16toh(num)Linux.be16toh ()는 16 비트 정수의 바이트 오더를 호스팅하도록 대기업 바이트 오더를 변환합니다.
linux.be32toh(num)Linux.be32toh ()는 Big-Endian 바이트 오더를 32 비트 정수의 바이트 오더로 전환합니다.
linux.be64toh(num)Linux.be64toh ()는 Big-Endian Byte Order를 64 비트 정수의 바이트 오더로 변환합니다.
linux.htole16(num)Linux.htole16 ()는 16 비트 정수의 경우 호스트 바이트 순서를 Little-Endian 바이트 순서로 변환합니다.
linux.htole32(num)Linux.htole32 ()는 32 비트 정수를 위해 호스트 바이트 순서를 Little-Endian 바이트 순서로 변환합니다.
linux.htole64(num)Linux.htole64 ()는 64 비트 정수를 위해 호스트 바이트 순서를 Little-Endian Byte Order로 변환합니다.
linux.le16toh(num)Linux.le16toh ()는 Little-Endian Byte Order를 16 비트 정수의 바이트 순서로 전환합니다.
linux.le32toh(num)Linux.le32toh ()는 Little-Endian Byte Order를 32 비트 정수의 바이트 순서로 변환합니다.
linux.le64toh(num)Linux.le64toh ()는 Little-Endian Byte Order를 64 비트 정수의 바이트 오더로 전환합니다.
notifier 라이브러리는 커널 알림 체인을 지원합니다.
notifier.keyboard(callback) Notifier.keyboard () 새 키보드 notifier 객체를 반환하여 시스템에 설치합니다. callback 함수는 콘솔 키보드 이벤트가 발생할 때마다 호출됩니다 (예 : 키가 눌림 또는 해제되었습니다). 이 callback 다음과 같은 주장을받습니다.
event : 사용 가능한 이벤트는 Notifier.kbd 테이블로 정의됩니다.down : true , 키를 누르면; false , 그것이 릴리스되면.shift : true , Shift 키가 유지되면; false , 그렇지 않으면.key : event 에 따라 키 코드 또는 키 코드 . callback 함수는 Notifier.notify 테이블에 의해 정의 된 값을 반환 할 수 있습니다.
notifier.kbdNotifier.kbd 는 KBD 플래그를 LUA로 내보내는 테이블입니다.
"KEYCODE" : 키보드 키 코드는 다른 어떤 것보다 먼저 호출됩니다."UNBOUND_KEYCODE" : 키보드 키 코드 는 다른 사람에게 바인딩되지 않습니다."UNICODE" : 키보드 유니 코드."KEYSYM" : 키보드 키시임 ."POST_KEYSYM" : 키보드 키스 령 해석 후 호출. notifier.netdevice(callback) notifier.netDevice () 새 netDevice notifier 객체를 반환하여 시스템에 설치합니다. callback 함수는 콘솔 NetDevice 이벤트가 발생할 때마다 호출됩니다 (예 : 네트워크 인터페이스가 연결 또는 연결이 끊어졌습니다). 이 callback 다음과 같은 주장을받습니다.
event : 사용 가능한 이벤트는 notifier.netdev 테이블로 정의됩니다.name : 장치 이름. callback 함수는 Notifier.notify 테이블에 의해 정의 된 값을 반환 할 수 있습니다.
notifier.netdevNotifier.netDev 는 NetDev 플래그를 LUA로 내보내는 테이블입니다.
notifier.notifyNotifier.notify는 플래그를 LUA로 내보내는 테이블입니다.
"DONE" : 신경 쓰지 마세요."OK" : 나에게 어울립니다."BAD" : 나쁜/거부권 행동."STOP" : Notifier에서 돌아와서 추가 통화를 중지하는 깨끗한 방법. notfr:delete() NOTFR : Delete ()는 시스템에서 notfr 객체로 지정된 notifier 제거합니다.
socket 라이브러리는 커널 네트워킹 처리를 지원합니다. 이 라이브러리는 Chengzhi Tan의 GSOC 프로젝트에서 영감을 받았습니다.
socket.new(family, type, protocol) socket.new ()는 새로운 socket 객체를 만듭니다. 이 기능은 다음과 같은 주장을받습니다.
family : 사용 가능한 주소 패밀리는 소켓으로 정의됩니다.sock : 사용 가능한 유형은 소켓에 있습니다.protocol : 사용 가능한 프로토콜은 Socket.ipproto 테이블로 정의됩니다. socket.afSocket.af 는 Families (AF)를 Lua로 수출하는 테이블입니다.
"UNSPEC" : 지정되지 않은."UNIX" : UNIX 도메인 소켓."LOCAL" : af_unix의 posix 이름."INET" : 인터넷 IP 프로토콜."AX25" : 아마추어 라디오 도끼 .25."IPX" : Novell IPX."APPLETALK" : Appletalk DDP."NETROM" : 아마추어 라디오 네트/ROM."BRIDGE" : 멀티 프로토콜 브리지."ATMPVC" : ATM PVC."X25" : X.25 프로젝트를 위해 예약되었습니다."INET6" : IP 버전 6."ROSE" : 아마추어 라디오 X.25 PLP."DEC" : DECNET 프로젝트를 위해 예약되었습니다."NETBEUI" : 802.2llc 프로젝트에 예약되었습니다."SECURITY" : 보안 콜백 의사 AF."KEY" : pf_key 키 관리 API."NETLINK" : NetLink."ROUTE" : 4.4bsd를 모방하는 별칭."PACKET" : 패킷 패밀리."ASH" : Ash."ECONET" : Acorn Econet."ATMSVC" : ATM SVC."RDS" : RDS 소켓."SNA" : Linux SNA 프로젝트 (Nutters!)."IRDA" : IRDA 소켓."PPPOX" : pppox 소켓."WANPIPE" : Wanpipe API 소켓."LLC" : Linux LLC."IB" : 네이티브 인피니본 주소."MPLS" : MPLS."CAN" : 컨트롤러 영역 네트워크."TIPC" : TIPC 소켓."BLUETOOTH" : Bluetooth 소켓."IUCV" : IUCV 소켓."RXRPC" : rxrpc 소켓."ISDN" : misdn 소켓."PHONET" : 포넷 소켓."IEEE802154" : IEEE802154 소켓."CAIF" : CAIF 소켓."ALG" : 알고리즘 소켓."NFC" : NFC 소켓."VSOCK" : vsockets."KCM" : 커널 연결 멀티플렉서."QIPCRTR" : Qualcomm IPC 라우터."SMC" : AF_INET 주소 제품군을 재사용하는 PF_SMC 프로토콜 패밀리의 예약 번호."XDP" : XDP 소켓."MCTP" : 관리 구성 요소 전송 프로토콜."MAX" : 최대. socket.sockSocket.sock 은 소켓 유형 (양말)을 내보내는 테이블입니다.
"STREAM" : 스트림 (연결) 소켓."DGRAM" : 데이터 그램 (Conn.less) 소켓."RAW" : 원시 소켓."RDM" : 안정적으로 배달 된 메시지."SEQPACKET" : 순차적 패킷 소켓."DCCP" : 데이터 그램 혼잡 제어 프로토콜 소켓."PACKET" : Linux Dev 레벨에서 패킷을 가져 오는 특정 방법.그리고 깃발 (양말) :
"CLOEXEC" : N/A."NONBLOCK" : N/A. socket.ipprotoSocket.ipproto 는 IP 프로토콜 (IPProto)을 LUA로 내보내는 테이블입니다.
"IP" : TCP 용 더미 프로토콜."ICMP" : 인터넷 제어 메시지 프로토콜."IGMP" : 인터넷 그룹 관리 프로토콜."IPIP" : IPIP 터널 (이전 KA9Q 터널 사용 94)."TCP" : 전송 제어 프로토콜."EGP" : 외부 게이트웨이 프로토콜."PUP" : 강아지 프로토콜."UDP" : 사용자 데이터 그램 프로토콜."IDP" : XNS IDP 프로토콜."TP" : 따라서 전송 프로토콜 클래스 4."DCCP" : 데이터 그램 혼잡 제어 프로토콜."IPV6" : IPv6-in-IPV4 터널링."RSVP" : RSVP 프로토콜."GRE" : Cisco Gre Tunnels (RFC 1701,1702)."ESP" : 캡슐화 보안 페이로드 프로토콜."AH" : 인증 헤더 프로토콜."MTP" : 멀티 캐스트 전송 프로토콜."BEETPH" : Beet 용 IP 옵션 의사 헤더."ENCAP" : 캡슐화 헤더."PIM" : 프로토콜 독립 멀티 캐스트."COMP" : 압축 헤더 프로토콜."SCTP" : 스트림 제어 전송 프로토콜."UDPLITE" : udp-lite (RFC 3828)."MPLS" : IP의 MPLS (RFC 4023)."ETHERNET" : Ethernet-Within-IPV6 캡슐화."RAW" : 원시 IP 패킷."MPTCP" : 다중 경로 TCP 연결. sock:close() 양말 : Close () 시스템에서 sock 개체를 제거합니다.
sock:send(message, [addr [, port]]) 양말 : send ()는 소켓 sock 통해 문자열 message 보냅니다. sock 주소가 af.INET 이면 다음과 같은 주장을 기대합니다.
addr : 대상 IPv4 주소를 설명하는 integer .port : 대상 IPv4 포트를 설명하는 integer .그렇지 않으면:
addr : 대상 주소를 설명하는 포장 문자열. sock:receive(length, [flags [, from]]) 양말 : 수신 ()은 소켓 sock 통해 최대 length 바이트가있는 문자열을 수신합니다. 사용 가능한 메시지 플래그는 socket.msg 테이블로 정의됩니다. from true 수신 된 메시지와 피어의 주소를 반환합니다. 그렇지 않으면 수신 된 메시지 만 반환합니다.
socket.msgsocket.msg 는 메시지 플래그를 LUA로 내보내는 테이블입니다.
"OOB" : N/A."PEEK" : N/A."DONTROUTE" : N/A."TRYHARD" : Decnet의 "DONTROUTE" 의 동의어."CTRUNC" : N/A."PROBE" : 보내지 마십시오. MTU에 대한 프로브 경로 FE 만."TRUNC" : N/A."DONTWAIT" : Nonblocking IO."EOR" : 레코드 종료."WAITALL" : 전체 요청을 기다리십시오."FIN" : 해당 없음."SYN" : N/A."CONFIRM" : 경로 유효성을 확인하십시오."RST" : N/A."ERRQUEUE" : 오류 큐에서 메시지를 가져 오십시오."NOSIGNAL" : SIGPIPE를 생성하지 마십시오."MORE" : 발신자는 더 많은 것을 보낼 것입니다."WAITFORONE" : recvmmsg () : 1+ 패킷이 이용 될 때까지 차단하십시오."SENDPAGE_NOPOLICY" : SendPage () 내부 : 정책을 적용하지 마십시오."SENDPAGE_NOTLAST" : SendPage () 내부 : 마지막 페이지가 아닙니다."BATCH" : sendmmsg () : 더 많은 메시지가 나옵니다."EOF" : 해당 없음."NO_SHARED_FRAGS" : sendPage () 내부 : 페이지 조각은 공유되지 않습니다."SENDPAGE_DECRYPTED" : sendPage () 내부 : 페이지는 일반 텍스트를 가지고 있으며 암호화가 필요할 수 있습니다."ZEROCOPY" : 커널 경로에서 사용자 데이터를 사용하십시오."FASTOPEN" : TCP Syn에서 데이터를 보내십시오."CMSG_CLOEXEC" : scm_rights를 통해 수신 된 파일 디스크립터에 대해 close_on_exec을 설정하십시오. sock:bind(addr [, port]) 양말 : bind ()는 소켓 sock 주어진 주소에 바인딩합니다. sock 주소가 af.INET 이면 다음과 같은 주장을 기대합니다.
addr : 호스트 IPv4 주소를 설명하는 integer .port : 호스트 IPv4 포트를 설명하는 integer .그렇지 않으면:
addr : 호스트 주소를 설명하는 포장 문자열. sock:listen([backlog]) 양말 : 듣기 () 소켓 sock 청취 상태로 움직입니다.
backlog : 보류중인 연결 대기열 크기. 생략하면 SomaxConn을 기본값으로 사용합니다. sock:accept([flags]) 양말 : accept () 소켓 sock 의 연결을 수락합니다. 새로운 socket 객체를 반환합니다. 사용 가능한 플래그는 Socket.Sock 테이블에 있습니다.
sock:connect(addr [, port] [, flags]) 양말 : Connect () 소켓 sock 주소 addr 에 연결합니다. sock 주소가 af.INET 이면 다음과 같은 주장을 기대합니다.
addr : 대상 IPv4 주소를 설명하는 integer .port : 대상 IPv4 포트를 설명하는 integer .그렇지 않으면:
addr : 대상 주소를 설명하는 포장 문자열.사용 가능한 플래그는 Socket.Sock 테이블에 있습니다.
데이터 그램 소켓의 경우 addr 은 기본적으로 데이터 그램이 전송되는 주소와 데이터 그램이 수신되는 유일한 주소입니다. 스트림 소켓의 경우 addr 에 연결하려고 시도합니다.
sock:getsockname() 양말 : getsockname () 소켓 sock 바인딩 된 주소를 가져옵니다. sock 주소가 af.INET 이면 다음을 반환합니다.
addr : 경계 IPv4 주소를 설명하는 integer .port : 경계 IPv4 포트를 설명하는 integer .그렇지 않으면:
addr : 경계 주소를 설명하는 포장 문자열. sock:getpeername() 양말 : getpeername () 소켓 sock 이 연결된 주소를 가져옵니다. sock 주소가 af.INET 이면 다음을 반환합니다.
addr : 피어의 IPv4 주소를 설명하는 integer .port : 피어의 IPv4 포트를 설명하는 integer .그렇지 않으면:
addr : 피어의 주소를 설명하는 포장 문자열. socket.inet 라이브러리는 고급 IPv4 소켓을 지원합니다.
inet.tcp() inet.tcp ()는 af.inet 주소 패밀리, sock.stream 유형 및 ipproto.tcp 프로토콜을 사용하여 새로운 socket 만듭니다. 정수 대신 주소를 숫자 및 도트 표기법 (예 : "127.0.0.1" )으로 사용하도록 socket 메소드를 무시합니다.
inet.udp() inet.udp ()는 af.inet 주소 패밀리, sock.dgram 유형 및 ipproto.udp 프로토콜을 사용하여 새로운 socket 만듭니다. 정수 대신 주소를 숫자 및 도트 표기법 (예 : "127.0.0.1" )으로 사용하도록 socket 메소드를 무시합니다.
udp:receivefrom(length [, flags]) udp : leceptfrom ()은 sock:receive(length, flags, true) .
rcu 라이브러리는 커널 읽기 -Copy 업데이트 (RCU) 동기화 메커니즘을 지원합니다. 이 라이브러리는 Caio Messias의 GSOC 프로젝트에서 영감을 받았습니다.
rcu.table([size]) rcu.table ()는 커널 일반 해시 테이블을 바인딩하는 새로운 rcu.table 객체를 만듭니다. 이 함수는 다음의 다음 전력으로 반올림 된 버킷 수를 인수로 받아들입니다. 기본 크기는 1024 입니다. 키는 문자열이어야하며 값은 Lunatik 객체 또는 nil이어야합니다.
thread 라이브러리는 커널 스레드 프리미티브를 지원합니다.
thread.run(runtime, name) Thread.run ()은 새 thread 객체를 생성하여 깨어납니다. 이 기능은 다음과 같은 주장을받습니다.
runtime : 생성 된 커널 스레드에서 작업을 실행하기위한 런타임 환경. runtime 환경에로드 된 스크립트에서 함수를 반환하여 작업을 지정해야합니다.name : 스레드의 이름을 나타내는 문자열 (예 : ps 에 표시된대로). thread.shouldstop() Thread.shouldStop () 이 true 반환합니다. 그렇지 않으면 false 반환합니다.
thread.current() Thread.Current ()는 현재 작업을 나타내는 thread 개체를 반환합니다.
thrd:stop() thrd : stop ()는 스레드에서 스레드를 설정하여 스레드 thrd 에서 true를 반환하고 thrd 깨우고 종료 될 때까지 기다립니다.
thrd:task() THRD : TASK ()는 이 thread 의 작업 정보가 포함 된 테이블을 반환합니다 (예 : "CPU", "Command", "PID"및 "TGID").
fib 라이브러리는 커널 전달 정보 기반을 지원합니다.
fib.newrule(table, priority)fib.newrule ()는 커널 fib_nl_newrule api를 바인딩합니다. 지정된 라우팅 테이블 과 지정된 Priorioty 와 일치하는 새 FIB 규칙을 만듭니다. 이 기능은 iproute2에서 제공 한 사용자 공간 명령 IP 규칙과 유사합니다.
fib.delrule(table, priority)fib.delrule ()는 커널 fib_nl_delrule api를 바인딩합니다. 지정된 라우팅 테이블 과 지정된 Priorioty 와 일치하는 FIB 규칙을 제거합니다. 이 기능은 iproute2에서 제공하는 사용자 공간 명령 IP 규칙 델과 유사합니다.
data 라이브러리는 시스템 메모리를 LUA에 바인딩하는 것을 지원합니다.
data.new(size) data.new ()는 size 바이트를 할당하는 새 data 객체를 만듭니다.
d:getnumber(offset) D : getNumber ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 lua_integer를 추출합니다.
d:setnumber(offset, number) d : setNumber ()는 ZERO부터 시작하여 data 객체와 바이트 offset 에서 참조 된 메모리에 lua_integer number 메모리에 삽입합니다.
d:getbyte(offset) D : getByte ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 바이트를 추출합니다.
d:setbyte(offset, byte) D : setByte ()는 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 바이트를 삽입합니다.
d:getstring(offset[, length]) D : getString ()은 0에서 시작하여 data 객체와 바이트 offset 에서 참조 된 메모리에서 length 바이트가있는 문자열을 추출합니다. length 생략되면 모든 바이트를 offset 에서 data 끝까지 추출합니다.
d:setstring(offset, s) D : setString ()은 제로부터 시작하여 data 객체와 바이트 offset 에서 참조 된 메모리에 문자열 s 삽입합니다.
d:getint8(offset) D : getInt8 (d, 오프셋)은 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명 된 8 비트 정수를 추출합니다.
d:setint8(offset, number) d : setInt8 ()는 부호가있는 8 비트 번호를 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 삽입됩니다.
d:getuint8(offset) D : getuint8 ()은 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명되지 않은 8 비트 정수를 추출합니다.
d:setuint8(offset, number) d : setuint8 ()는 부호없는 8 비트 번호를 0부터 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 삽입됩니다.
d:getint16(offset) D : getInt16 ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명 된 16 비트 정수를 추출합니다.
d:setint16(offset, number) d : setInt16 ()는 부호가있는 16 비트 번호를 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 삽입됩니다.
d:getuint16(offset) D : getuint16 ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명되지 않은 16 비트 정수를 추출합니다.
d:setuint16(offset, number) d : setuint16 ()는 부호없는 16 비트 번호를 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 삽입됩니다.
d:getint32(offset) D : getInt32 ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명 된 32 비트 정수를 추출합니다.
d:setint32(offset, number) d : setInt32 ()는 부호가있는 32 비트 번호를 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 삽입됩니다.
d:getuint32(offset) D : getUint32 ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명되지 않은 32 비트 정수를 추출합니다.
d:setuint32(offset, number) d : setuint32 ()는 0부터 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 서명되지 않은 32 비트 번호를 삽입합니다.
d:getint64(offset) D : getInt64 ()는 0에서 시작하여 data 객체와 바이트 offset 으로 참조 된 메모리에서 서명 된 64 비트 정수를 추출합니다.
d:setint64(offset, number) d : setInt64 ()는 0에서 시작하여 data 객체와 바이트 offset 에 의해 참조 된 메모리에 서명 된 64 비트 번호를 삽입합니다.
probe 라이브러리는 커널 프로브를 지원합니다.
probe.new(symbol|address, handlers) probe.new ()는 커널 symbol (문자열) 또는 address (Light UserData)를 모니터링하기 위해 새 probe 객체를 반환하고 시스템에 handlers 설치합니다. handler 다음 필드를 포함하는 테이블로 정의 되어야 합니다.
pre : 조사 된 지시 전에 호출 할 기능. symbol 또는 address 수신 한 다음 시스템 로그에 CPU 레지스터를 표시하고 스택을 표시하기 위해 호출 될 수있는 폐쇄가 이어집니다.post : 조사 된 지시 후에 호출 할 기능. symbol 또는 address 수신 한 다음 시스템 로그에 CPU 레지스터를 표시하고 스택을 표시하기 위해 호출 될 수있는 폐쇄가 이어집니다. p:stop() P : STOP ()는 시스템에서 probe 핸들러를 제거합니다.
p:enable(bool) p : enable ()는 bool 에 따라 probe 핸들러를 활성화하거나 비활성화합니다.
syscall 라이브러리는 시스템 통화 주소 및 번호를 지원합니다.
syscall.address(number) syscall.address () 주어진 number 로 참조 된 시스템 호출 주소 (Light UserData)를 반환합니다.
syscall.number(name) syscall.number () 주어진 name 으로 참조 된 시스템 호출 번호를 반환합니다.
syscall.table 라이브러리는 주소 (Light UserData)로 시스템 호출 이름을 변환하는 것을 지원합니다.
xdp 라이브러리는 커널 Express Data Path (XDP) 서브 시스템을 지원합니다. 이 도서관은 Victor Nogueira의 GSOC 프로젝트에서 영감을 받았습니다.
xdp.attach(callback) xdp.attach () 는 BPF_LUAXDP_RUN KFUNC를 호출 할 때마다 XDP/EBPF 프로그램에서 호출 할 현재 runtime 에 callback 함수를 등록합니다. 이 callback 다음과 같은 주장을받습니다.
buffer : 네트워크 버퍼를 나타내는 data 객체.argument : XDP/EBPF 프로그램이 통과 한 인수를 포함하는 data 객체. callback 함수는 XDP.Action 테이블에 의해 정의 된 값을 반환 할 수 있습니다.
xdp.detach() xdp.detach ()는 현재 runtime 과 관련된 callback 등록 해제합니다.
xdp.actionXDP.Action 은 XDP_Action 플래그를 LUA로 내보내는 테이블입니다.
"ABORTED" : XDP 프로그램이 일반적으로 오류로 인해 중단되었음을 나타냅니다."DROP" : 패킷을 떨어 뜨려서 완전히 폐기해야합니다."PASS" : 패킷이 Linux 네트워크 스택으로 전달할 수 있습니다."TX" : 수신 된 동일한 인터페이스에서 패킷을 다시 전송합니다."REDIRECT" : 패킷을 다른 인터페이스 또는 처리 컨텍스트로 리디렉션합니다. xtable Library는 NetFilter Xtable 확장을 개발할 수 있도록 지원합니다.
xtable.match(opts)xtable.match () 매치 연장에 대한 새 xtable 객체를 반환합니다. 이 기능은 다음과 같은 주장을받습니다.
opts : 다음 필드가 포함 된 테이블 :name : xtable 확장자 이름을 나타내는 문자열.revision : xtable 확장 개정을 나타내는 정수.family : 주소 가족, NetFilter.Family 중 하나입니다.proto : 프로토콜 번호, Socket.ipproto 중 하나.hooks : 훅스 테이블 중 하나에서 하나의 값을 첨부하는 후크 - netfilter.inet_hooks, netfilter.bridge_hooks 및 netfilter.arp_hooks (참고 : netfilter.netdev_hooks는 레거시 x_tables에 사용할 수 없습니다). (예 : 1 << inet_hooks.LOCAL_OUT ).match : 매칭 패킷을 위해 호출되는 기능. 다음과 같은 주장을받습니다.skb (Readonly) : 소켓 버퍼를 나타내는 data 객체.par : hotdrop , thoff (Transport Header Offset) 및 fragoff (Fragment Offset) 필드가 포함 된 테이블.userargs : userpace xtable 모듈에서 전달되는 LUA 문자열.true 반환해야합니다. 그렇지 않으면 false 반환해야합니다.checkentry : 항목을 확인하기 위해 호출되는 기능. 이 함수는 userargs 인수로받습니다.destroy : xtable 확장을 파괴하기 위해 요구되는 기능. 이 함수는 userargs 인수로받습니다. xtable.target(opts)xtable.target () 대상 확장에 대한 새 xtable 객체를 반환합니다. 이 기능은 다음과 같은 주장을받습니다.
opts : 다음 필드가 포함 된 테이블 :name : xtable 확장자 이름을 나타내는 문자열.revision : xtable 확장 개정을 나타내는 정수.family : 주소 가족, NetFilter.Family 중 하나입니다.proto : 프로토콜 번호, Socket.ipproto 중 하나.hooks : 훅스 테이블 중 하나에서 하나의 값을 첨부하는 후크 - netfilter.inet_hooks, netfilter.bridge_hooks 및 netfilter.arp_hooks (참고 : netfilter.netdev_hooks는 레거시 x_tables에 사용할 수 없습니다). (예 : 1 << inet_hooks.LOCAL_OUT ).target : 타겟팅 패킷을 위해 호출되는 기능. 다음과 같은 주장을받습니다.skb : 소켓 버퍼를 나타내는 data 객체.par (Readonly) : hotdrop , thoff (Transport Header Offset) 및 fragoff (Fragment Offset) 필드를 포함하는 테이블.userargs : userpace xtable 모듈에서 전달되는 LUA 문자열.checkentry : 항목을 확인하기 위해 호출되는 기능. 이 함수는 userargs 인수로받습니다.destroy : xtable 확장을 파괴하기 위해 요구되는 기능. 이 함수는 userargs 인수로받습니다. netfilter Library는 새로운 NetFilter Hook 시스템을 지원합니다.
netfilter.register(ops) NetFilter.register ()는 주어진 ops 테이블과 함께 새로운 NetFilter 후크를 등록합니다. 이 기능은 다음과 같은 주장을받습니다.
ops : 다음 필드가 포함 된 테이블 :pf : 프로토콜 패밀리, NetFilter.Family 중 하나hooknum : Hooks Filter를 연결하여 Hooks 테이블 중 하나에서 하나의 값을 연결합니다 -NetFilter.inet_hooks, netfilter.bridge_hooks, netfilter.arp_hooks 및 netfilter.netdev_hooks. (예 : inet_hooks.LOCAL_OUT + 11 ).priority : 후크의 우선 순위. netfilter.ip_priority 또는 netfilter.bridge_priority 테이블의 값 중 하나입니다.hook : 후크를 요구할 기능. 다음과 같은 주장을받습니다.skb : 소켓 버퍼를 나타내는 data 객체.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.