`
xumingyong
  • 浏览: 184062 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Use Erlang NIF to snoop, capture packets.

阅读更多

 

1. Overview

 

In Erlang/OTP R13B03, there is new feature called Native Implementation Function, Here I use NIF and libpcap library to have implemented a simple sniffer to real-time capturing packet from one interface.

 

简述:使用NIF实现简单的抓包程序。

 

2. Developing enviroment:

 

- Ubuntu 9.10: 2.6.31-14-generic

- gcc: 4.4.1

- libpcap.so.1.0.0

- Erlang/OTP R13B03

 

3. nif.erl

 

%%% nif sniffer

-module(nif).
-on_load(on_load/0).

-export([opendevice/1, capture/0, loop/1]).

on_load() ->
    ok = erlang:load_nif("./nif", 0),
    true.

opendevice(_Interface) ->
    error.

capture() ->
    error.

loop(0) ->
    ok;
loop(Count) ->
    Pkt = capture(),
    io:format("~p~n", [Pkt]),
    loop(Count-1).

 

 

4. nif.c

 

 

/* This file used to create a Erlang NIF which sniffer network packets. */

#include <erl_nif.h>
#include <stdio.h>
#include <pcap.h>
#include <string.h>
#include <ctype.h>


pcap_t *devHandler = NULL;

static int my_enif_get_string(ErlNifEnv *env, ERL_NIF_TERM list, char* buf)
{
    ERL_NIF_TERM cell, head, tail;
    int val;

    while (enif_get_list_cell(env, list, &head, &tail))
    {
        if (!enif_get_int(env, head, &val)) return 1;
        *buf = (char)val;
        buf++;
        list = tail;
    }
    *buf = '\0';
    return 0;
}


static ERL_NIF_TERM opendevice(ErlNifEnv* env, ERL_NIF_TERM device)
{
    char dev[64];
    char errbuf[PCAP_ERRBUF_SIZE];

    memset(errbuf, 0, PCAP_ERRBUF_SIZE);

    my_enif_get_string(env, device, dev);
    /* return enif_make_string(env, dev); */

    /* Parms: dev,snaplen,promisc,timeout_ms,errbuf
     * Notes: if timeout_ms is set by non-zero, system give "segment fault" error ?
     * to_ms=0 means wait enough packet to arrive.
     */
    devHandler = pcap_open_live(dev, 65535, 1, 0, errbuf);
    if(devHandler != NULL)
        return enif_make_string(env, "ok");
    else
        return enif_make_string(env, errbuf);
}


static ERL_NIF_TERM capture(ErlNifEnv* env)
{
    int i;
    struct pcap_pkthdr pkthdr;
    const u_char *packet = NULL;
    ErlNifBinary bin;

    packet = pcap_next(devHandler, &pkthdr);
    if(packet != NULL)
    {
        enif_alloc_binary(env, pkthdr.len, &bin);
        for(i = 0; i < pkthdr.len; i++)
        {
            bin.data[i] = packet[i];
        }
    }
    else
    {
        bin.size = sizeof("NULL");
        bin.data = "NULL";
    }
    return enif_make_binary(env, &bin);
}


static ErlNifFunc nif_funcs[] =
{
    {"capture", 0, capture},
    {"opendevice", 1, opendevice}
};

ERL_NIF_INIT(nif,nif_funcs,NULL,NULL,NULL,NULL)

 

 5. 编译nif.c程序

 

gcc -fPIC -shared -o nif.so nif.c /usr/lib/libpcap.so -I/usr/local/lib/erlang/usr/include/

 

6. 开始测试

 

xumingyong@ubuntu:~/workspace/sniffer_nif$ sudo erl
Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> c(nif).
{ok,nif}
2> nif:opendevice("eth0").
"ok"
3> nif:loop(5).
<<255,255,255,255,255,255,0,12,41,66,42,16,8,6,0,1,8,0,6,4,0,1,0,12,41,66,42,16,192,168,0,200,0,0,0,0,0,0,192,168,0,1>>
<<0,12,41,66,42,16,0,80,86,192,0,1,8,6,0,1,8,0,6,4,0,2,0,80,86,192,0,1,192,168,0,1,0,12,41,66,42,16,192,168,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>
<<0,80,86,192,0,1,0,12,41,66,42,16,8,0,69,0,0,84,0,0,64,0,64,1,184,143,192,168,0,200,192,168,0,1,8,0,68,170,146,13,0,1,86,157,102,75,108,91,13,0,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55>>
<<0,12,41,66,42,16,0,80,86,192,0,1,8,0,69,0,0,84,178,130,64,0,128,1,198,12,192,168,0,1,192,168,0,200,0,0,76,170,146,13,0,1,86,157,102,75,108,91,13,0,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55>>
<<0,80,86,192,0,1,0,12,41,66,42,16,8,0,69,0,0,84,0,0,64,0,64,1,184,143,192,168,0,200,192,168,0,1,8,0,121,143,146,13,0,2,87,157,102,75,54,117,13,0,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55>>
ok
4> 

 

 

7. 注意

 

- Must be root user when start "erl" command, or you cannot open the network adapter interface.

- The output of "nif:loop(5)" command is 5 ARP packet, 1st is broadcast, 2nd is request, 3rd is reply, 4th is request, 5th is reply.

- Because the erlang/OTP NIF is experimental, the new erlang/OTP may be incompatible with this version, please check the newest online documentation.

 

 

 

 

0
0
分享到:
评论
1 楼 mryufeng 2010-02-25  
很有创意哦...

相关推荐

    erlang-23.2.3-1.el7.x86_64.rpm和erlang-23.2.1-1.el7.x86_64.rpm.rar

    Erlang是一种高级编程语言,特别适用于并发、分布式和实时计算系统。它的设计目标是创建一个高度可靠且容错的环境,广泛应用于电信、金融、在线游戏和消息队列服务等领域。Erlang由爱立信开发,其核心概念包括进程...

    rustler编写erlang nif

    【标题】:“rustler编写erlang nif” 在Erlang生态系统中,Native Implemented Functions (NIFs) 是一种机制,允许开发者用其他语言(如C、C++或Rust)编写性能关键部分的代码,然后在Erlang虚拟机(VM)中调用。...

    Erlang的Git开发包Geef.zip

    Geef is an example of an Erlang NIF binding to libgit2. A bit out of date, but basically works. Best as a proof of concept of what you could do with Erlang and NIFs with libgit2. 标签:Geef

    erlang-22.3-1.el7.x86_64.rpm

    Erlang是一种高级编程语言,特别为并发、分布式和实时计算设计,由Ericsson公司开发,主要用于构建大规模、高可用性的系统。在标题"erlang-22.3-1.el7.x86_64.rpm"中,我们可以解读出几个关键信息: 1. **版本号**...

    erlang nif test

    Erlang NIF(Native Implemented Functions)是Erlang虚拟机提供的一种机制,允许开发者用C语言或者其他低级语言编写性能关键部分的代码,并在Erlang系统中无缝调用。这种方式可以充分利用C语言的高效性,同时保持...

    erlang-20.3-1.el7.centos.x86_64.rpm

    erlang-20.3-1.el7.centos.x86_64.rpm

    erlang-18.3-1.el7.centos.x86_64.zip

    Erlang是一种高级编程语言,特别为构建分布式、并发、实时和容错系统而设计。在标题中的"erlang-18.3-1.el7.centos.x86_64.zip",我们看到的是Erlang的一个特定版本,18.3,针对64位的CentOS 7操作系统(el7)的...

    erlang-21.3-1.el7.x86_64.rpm

    erlang-21.3-1.el7.x86_64.rpm rabbitmq基础语言环境。

    erlang-24.0.3-1.el8.x86_64.rpm资源

    erlang-24.0.3-1.el8.x86_64.rpm资源

    erlang-25.0-1.el8.x86_64.rpm

    erlang 安装包。 rabbitmq 安装所需要的

    erlang-19.0.4-1.el7.centos.x86_64

    erlang-19.0.4-1.el7.centos.x86_64.rpm ,官网的正式包

    erlang-24.3.3-1.el9.x86_64.rpm

    erlang-24.3.3-1.el9.x86_64.rpm centos

    erlang-23.1-1.el8.x86_64.rpm

    erlang-23.1-1.el8.x86_ ,erlang官网下载很慢,所以提供该下载链接。

    erlang-asn1-19.3.6.4-1.el7.x86_64.rpm

    erlang-asn1-19.3.6.4-1.el7.x86_64.rpm

    erlang-23.2.1-1.el7.x86_64.rpm

    erlang-23.2.1-1.el7.x86_64.rpm

    erlang-23.2.3-1.el7.x86_64.rpm

    erlang23.2安装包

    最新版erlang-23.3.4.3-1.el7.x86_64.rpm(CentOS7)

    Erlang是一种高级编程语言,特别为并发、分布式计算和容错设计,广泛应用于网络通信、实时系统和大型分布式计算环境中。最新版的Erlang是23.3.4.3-1.el7.x86_64.rpm,这个版本针对CentOS 7进行了优化。Erlang以其轻...

    erlang-21.3.1-1.el7.x86_64.rpm

    rabbitMQ安装需要依赖erlang环境,这里提供centOS erlang21.3.1版本免费下载,适用于rabbitMQ对应版本

    erlang-23.1.1-1.el7.x86_64.rpm

    Erlang是一种通用的面向并发的编程语言,它由瑞典电信设备制造商爱立信所辖的CS-Lab开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。文件(erlang-23.1.1-1.el7.x86_64.rpm)是Erlang语言是安装包,...

Global site tag (gtag.js) - Google Analytics