Sign in

    pcap

    MoonBit 抓包绑定层:运行时动态加载 wpcap.dll(Npcap)

    pcap
    npcap
    packet-capture
    windows
    ffi
    Download zip
    Author
    Version
    0.1.1
    License
    MIT
    Last updated
    2 months ago
    Downloads
    21

    No dependencies

    #moonbit-pcap

    MoonBit 抓包绑定层:运行时动态加载 wpcap.dll(Npcap),提供设备枚举、打开设备、轮询收包等 pcap API 的 MoonBit 封装。

    仅支持 Windows(x86_64)。构建时零依赖(不需要 Npcap SDK),运行时才要求安装 Npcap。

    #特性

    • 运行时动态加载:C stub 用 LoadLibraryW("wpcap.dll") + GetProcAddress 取函数指针,编译期不链接任何 pcap 库
    • 零拷贝收包:PacketRaw.data 是拷贝副本,不持有 C 缓冲区,收包后可安全持有
    • 明确错误映射:load() 区分"未安装 Npcap / 系统加载失败 / 版本不兼容"三种原因
    • stdout 约定:stdout_unbuffered() + eprint() 配合,stdout 专供数据流、日志走 stderr

    #环境要求

    项要求
    操作系统Windows 10 / 11(x86_64)
    Npcap必须安装(https://npcap.com),保持默认安装
    运行权限管理员权限(抓包硬前提)

    #安装

    moon add chensuiyi/pcap

    #快速开始

    // moon.pkg: import "chensuiyi/pcap"
    fn main {
    match pcap.load() {
    Err(msg) => {
    pcap.eprint(msg)
    return
    }
    Ok(_) => ()
    }
    pcap.stdout_unbuffered()
    let devs = pcap.devices()
    if devs.is_empty() {
    pcap.eprint("未找到网络设备")
    return
    }
    match pcap.open(devs[0].name, 65535, true, 1000) {
    Err(msg) => pcap.eprint("打开设备失败: \{msg}")
    Ok(pc) => {
    while true {
    match pcap.next(pc) {
    Some(pkt) => pcap.eprint(
    "\{pkt.ts_sec}.\{pkt.ts_usec} len=\{pkt.len} caplen=\{pkt.caplen}",
    )
    None => () // 超时或错误,继续轮询
    }
    }
    }
    }
    }

    #API 一览

    函数说明
    load() -> Result[Unit, String]加载 wpcap.dll(进程只需一次)
    devices() -> Array[Device]枚举本机网卡(Device { name, description })
    open(dev, snaplen, promisc, timeout_ms) -> Result[Pcap, String]打开设备
    next(p) -> PacketRaw?轮询收包:Some = 数据包,None = 超时或错误
    datalink(p) -> Int链路层类型(1 = Ethernet / DLT_EN10MB)
    geterr(p) -> String最近一次操作的错误信息
    close(p) -> Unit停止收包循环并关闭设备
    local_ips() -> Array[(Bool, Bytes)]枚举本机 IP(GetAdaptersAddresses,v4=4 字节 / v6=16 字节)
    stdout_unbuffered() -> Unitstdout 设为无缓冲(管道/重定向时立即输出)
    eprint(msg) -> Unit日志输出到 stderr

    PacketRaw 字段:ts_sec : Int64(时间戳秒)、ts_usec : Int(微秒)、caplen : Int(实际捕获长度)、len : Int(原始包长)、data : Bytes(包数据副本)。

    #与解析层配合

    抓到的原始包交由 chensuiyi/packet(纯 MoonBit 解析层)提取五元组、方向与协议;完整采集服务见 chensuiyi/monitor。

    #License

    MIT

    Device

    pub struct Device {
    name : String
    description : String
    }

    网卡设备

    PacketRaw

    pub struct PacketRaw {
    ts_sec : Int64
    ts_usec : Int
    caplen : Int
    len : Int
    data : Bytes
    }

    原始数据包(data 是拷贝副本,不持有 C 缓冲区)

    Pcap

    pub struct Pcap {
    handle : Int64
    }

    pcap 句柄

    close

    fn close(p : Pcap) -> Unit

    停止收包循环并关闭设备
    fn datalink(p : Pcap) -> Int

    链路层类型(1 = Ethernet / DLT_EN10MB)

    devices

    fn devices() -> Array[Device]

    枚举本机网卡(无设备或失败返回空数组)

    eprint

    fn eprint(msg : String) -> Unit

    日志输出到 stderr(stdout 专供 JSON 流)

    geterr

    fn geterr(p : Pcap) -> String

    最近一次操作的错误信息

    load

    fn load() -> Result[Unit, String]

    加载 wpcap.dll(进程只需一次;失败原因映射见 npcap_load 返回值约定)

    local_ips

    fn local_ips() -> Array[(Bool, Bytes)]

    枚举本机 IP 地址(GetAdaptersAddresses):(是否 IPv4, 地址字节),v4=4 字节 v6=16 字节
    fn next(p : Pcap) -> PacketRaw?

    轮询收包:Some = 数据包,None = 超时或错误

    open

    fn open(dev : String, snaplen : Int, promisc : Bool, timeout_ms : Int) -> Result[Pcap, String]

    打开设备(snaplen 抓包长度上限,promisc 混杂模式,timeout_ms 收包超时)

    stdout_unbuffered

    fn stdout_unbuffered() -> Unit

    stdout 设为无缓冲(管道/重定向时 JSON 行立即输出)

    Source Files