Erlang packet capture interface using pcap
  • C 58.6%
  • Erlang 38%
  • Makefile 3.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-03-20 07:39:04 -04:00
c_src rlimit: fix resource limits 2025-02-09 08:19:43 -05:00
examples example: fix typo in option keyword 2023-02-02 06:24:32 -05:00
src 1.1.5 2026-02-23 15:37:46 -05:00
test Merge branch 'timeout' of https://github.com/erlbeck/epcap into erlbeck-timeout 2021-05-31 06:56:13 -04:00
.gitignore doc: add edoc from README 2023-08-28 06:19:12 -04:00
LICENSE doc: update copyright date 2026-03-20 07:39:04 -04:00
README.md doc: README: docs moved to edoc 2026-03-19 07:39:52 -04:00
rebar.config build: hex: add ex_doc configuration 2023-08-29 06:53:24 -04:00
rebar.config.script build: include PID in test file 2025-08-18 07:26:44 -04:00
rebar.lock deps: pkt 0.6.0 2023-02-03 07:43:26 -05:00

Package Version Hex Docs

An Erlang port interface to libpcap.

epcap includes a small example program called sniff.

DOCUMENTATION

https://hexdocs.pm/epcap/

QUICK SETUP

$ rebar3 compile

To compile the examples:

$ mkdir -p ebin
$ erlc +debug_info -I _build/default/lib -o ebin examples/*.erl

# Allow your user to epcap with root privs
sudo visudo
youruser ALL = NOPASSWD: /path/to/epcap/priv/epcap
# And if requiretty is enabled, disable it by using one of these
Defaults!/path/to/epcap/priv/epcap !requiretty
Defaults:youruser !requiretty

rebar3 shell

% Start the sniffer process
sniff:start_link().

% Use your interface, or leave it out and trust in pcap
sniff:start([{interface, "eth0"}]).

% To change the filter
sniff:start([{filter, "icmp or (tcp and port 80)"},{interface, "eth0"}]).

% To stop sniffing
sniff:stop().

PF_RING

In case you want to compile epcap with PF_RING support, just specify the path to the libpfring and modified libpcap libraries via shell variable PFRING.

PFRING=/home/user/pfring rebar3 do clean, compile

To complete the configuration you need to set up the cluster_id option. The value of the cluster_id option is integer and should be in range between 0 and 255.

epcap:start_link([{interface, "lo"}, {cluster_id, 2}]).

You can also specify the option cpu_affinity to set up CPU affinity for epcap port:

epcap:start_link([{interface, "lo"}, {cluster_id, 2}, {cpu_affinity, "1,3,5-7"}]).

PROCESS RESTRICTIONS

Setting the RESTRICT_PROCESS environment variable controls which mode of process restriction is used. The available modes are:

  • seccomp: linux

  • pledge: openbsd (default)

  • capsicum: freebsd (default)

  • rlimit: all (default: linux)

  • null: all

For example, to force using the seccomp process restriction on linux:

RESTRICT_PROCESS=rlimit rebar3 do clean, compile

The null mode disables process restrictions and can be used for debugging.

RESTRICT_PROCESS=null rebar3 do clean, compile

epcap:start([{exec, "sudo strace -f -s 4096 -o rlimit.trace"}, {filter, "port 9997"}]).

RESTRICT_PROCESS=seccomp rebar3 do clean, compile

epcap:start([{exec, "sudo strace -f -s 4096 -o seccomp.trace"}, {filter, "port 9997"}]).

SCREENSHOT

=INFO REPORT==== 27-Oct-2013::11:47:43 ===
    pcap: [{time,"2013-10-27 11:47:43"},
           {caplen,653},
           {len,653},
           {datalink,en10mb}]
    ether: [{source_macaddr,"F0:BD:4F:AA:BB:CC"},
            {destination_macaddr,"B3:4B:19:00:11:22"}]
    ipv6: [{protocol,tcp},
           {source_address,"2607:F8B0:400B:80B::1000"},
           {destination_address,"2002:26F:92:AE::123"}]
    tcp: [{source_port,80},
          {destination_port,47980},
          {flags,[ack,psh]},
          {seq,686139900},
          {ack,725208397},
          {win,224}]
    payload_size: 567
    payload: "HTTP/1.0 301 Moved Permanently..Location: http://www.google.ca/..Content-Type: text/html; charset=UTF-8..Date: Sun, 27 Oct 2013 15:47:49 GMT..Expires: Tue, 26 Nov 2013 15:47:49 GMT..Cache-Control: public, max-age=2592000..Server: gws..Content-Length: 218..X-XSS-Protection: 1; mode=block..X-Frame-Options: SAMEORIGIN..Alternate-Protocol: 80:quic....<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">.<TITLE>301 Moved</TITLE></HEAD><BODY>.<H1>301 Moved</H1>.The document has moved.<A HREF=\"http://www.google.ca/\">here</A>...</BODY></HTML>.." 

And a screenshot of the number of packets epcap is processing on a production system:

IPTraf Screenshot

TODO

  • return error atoms/tuples instead of using errx

  • add support for retrieving packet statistics using pcap_stats(3PCAP)