Lua FFI 简单封装 libpcap

来源:互联网 发布:私房照摄影师 知乎 编辑:程序博客网 时间:2024/05/12 02:34

1. 由来

最近在 LuaJit 的 FFI 封装已有功能,期间用到libpcap,这里共享一下我的简单封装

2. 代码

2.1 type.lua

这是一个类型申明的封装

module(...,package.seeall)local ffi = require("ffi")-- PCAP file format: http://wiki.wireshark.org/Development/LibpcapFileFormat/ffi.cdef[[struct pcap_file {    /* file header */    uint32_t magic_number;   /* magic number */    uint16_t version_major;  /* major version number */    uint16_t version_minor;  /* minor version number */    int32_t  thiszone;       /* GMT to local correction */    uint32_t sigfigs;        /* accuracy of timestamps */    uint32_t snaplen;        /* max length of captured packets, in octets */    uint32_t network;        /* data link type */};/* This is the header of a packet on disk.  */struct pcap_record {    /* record header */    uint32_t ts_sec;         /* timestamp seconds */    uint32_t ts_usec;        /* timestamp microseconds */    uint32_t incl_len;       /* number of octets of packet saved in file */    uint32_t orig_len;       /* actual length of packet */};/* This is the header of a packet as passed to pcap_offline_filter.  */struct pcap_pkthdr {    /* record header */    long ts_sec;             /* timestamp seconds */    long ts_usec;            /* timestamp microseconds */    uint32_t incl_len;       /* number of octets of packet saved in file */    uint32_t orig_len;       /* actual length of packet */};]]-- BPF program format.  Note: the bit module represents uint32_t values-- with the high-bit set as negative int32_t values, so we do the same-- for all of our 32-bit values including the "k" field in BPF-- instructions.ffi.cdef[[struct bpf_insn { uint16_t code; uint8_t jt, jf; int32_t k; };struct bpf_program { uint32_t bf_len; struct bpf_insn *bf_insns; };]]local bpf_program_mt = {  __len = function (program) return program.bf_len end,  __index = function (program, idx)     assert(idx >= 0 and idx < #program)     return program.bf_insns[idx]  end}bpf_insn = ffi.typeof("struct bpf_insn")bpf_program = ffi.metatype("struct bpf_program", bpf_program_mt)pcap_record = ffi.typeof("struct pcap_record")pcap_pkthdr = ffi.typeof("struct pcap_pkthdr")function selftest ()   print("selftest: ffi_types")   print("OK")end

2.2 pcap.lua

这个为主要函数的封装,暂时我只封装了我需要的,有些没有,这里提供一个例子。

module(..., package.seeall)local ffi = require("ffi")local types = require("types")local pcapffi.cdef[[    typedef struct pcap pcap_t;    typedef unsigned char u_char;    pcap_t  *pcap_open_offline(const char *, char *);    int     pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);    int     pcap_datalink(pcap_t *);]]function open_offline(pcap_name)    if not pcap then pcap = ffi.load("pcap") end    local err = ffi.new("char[128]", {})    local p = pcap.pcap_open_offline(pcap_name, err)    if p == nil then        print(ffi.string(err))        return nil    else        print(" open file " .. pcap_name .. " sucessfully")        return p    endendfunction new_pkthdr()    return ffi.new 'struct pcap_pkthdr *[1]'endfunction new_packet()    return ffi.new 'const u_char *[1]'endfunction next_ex(p, pkt_hdr, packet)    if not pcap then pcap = ffi.load("pcap") end    return pcap.pcap_next_ex(p, pkt_hdr, packet)endfunction datalink(p)    return pcap.pcap_datalink(p)end

3. 总结

封装不是太完善,但基本功能都还是有,这里只提供思路,授人以鱼,不如授人以渔(说实话就是懒)。

0 0