Skip to content
Portable native Erlang raw socket interface using pcap
C Erlang Makefile
Find file
New pull request
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

ewpcap is a native Erlang interface to PCAP that can be used for reading and writing packets from the network.

ewpcap is an experiment, meant to be a portable raw socket interface to all the platforms that support Erlang and libpcap.


ewpcap was written and tested under Linux. But if you are using a Unix system, it is much safer to use one of these projects:

The ewpcap interface will still go through some changes. For example, the function names may change as may the packet tuple.

ewpcap hasn't been heavily tested. It will probably segfault.


  • libpcap/winpcap

    On Ubuntu: sudo apt-get install libpcap-dev

These libraries are not required but can be used with ewpcap:

ewpcap requires beam to be running with root privileges:

* using sudo

    sudo erl -smp -pa ebin

* using capabilities

    setcap cap_net_raw=ep /path/to/beam.smp
  • SMP

SMP erlang must be enabled (erl -smp -pa ebin).




open() -> {ok, Socket} | {error, Error}
open(Dev) -> {ok, Socket} | {error, Error}
open(Dev, Options) -> {ok, Socket} | {error, Error}

    Types   Dev = binary() | string()
            Error = enomem | pcap_error_string()
            Socket = resource()
            Options = [ Option ]
            Option = {promisc, boolean()}
                | {snaplen, integer()}
                | {to_ms, integer()}
                | {filter, binary() | string()}
                | FilterOpts

    Open a network interface and begin receiving packets.

    Dev is the name of the network device. If an empty binary (<<>>)
    is passed in, pcap will select a default interface.

    If an error occurs, the PCAP string describing the error is
    returned to the caller.

    open/1 and open/2 default to:

        * promiscuous mode disabled

        * a snaplen (packet length) of 65535 bytes

        * timeout set to 500 ms

        * no filter (all packets are received)

    For filter options, see filter/3.

    Packets are returned as messages to the caller:

        {ewpcap, Ref, DatalinkType, Time, Length, Packet}

    Ref is a reference identifying the socket handle.

    The DataLinkType is an integer representing the link layer,
    e.g., ethernet, Linux cooked socket.

    The Time is a tuple in the same format as erlang:now/0, {MegaSecs,
    Secs, MicroSecs}.

    The Length corresponds to the actual packet length on the
    wire. The captured packet may have been truncated. To get the
    captured packet length, use byte_size(Packet).

    The Packet is a binary holding the captured data.

close(Socket) -> ok

    Closes the pcap descriptor.

filter(Socket, Filter) -> ok | {error, Error}
filter(Socket, Filter, Options) -> ok | {error, Error}

    Types   Socket = resource()
            Error = enomem | pcap_error_string()
            Options = [ Option ]
            Option = {optimize, boolean()}
                | {netmask, integer()}

    Compile a PCAP filter and apply it to the PCAP descriptor.

read(Socket) -> {ok, Packet}
read(Socket, Timeout) -> {ok, Packet} | {error, eagain}

    Types   Socket = resource()
            Timeout = uint() | infinity
            Packet = binary()

    Convenience function wrapping receive, returning the packet

write(Socket) -> ok | {error, pcap_error_string()}

    Types   Socket = resource()

    Write the packet to the network. See pcap_sendpacket(3PCAP).

getifaddrs() -> {ok, Iflist} | {error, posix()}

    Types   Iflist = [{Ifname, [Ifopt]}]
            Ifname = string()
            Ifopt = {flag, [Flag]}
                | {addr, Addr}
                | {netmask, Netmask}
                | {broadaddr, Broadaddr}
                | {dstaddr, Dstaddr}
                | {description, string()}
            Flag = loopback
            Addr = Netmask = Broadaddr = Dstaddr = ip_address()

    Returns a list of interfaces. Ifname can be used as the first
    parameter to open/1 and open/2.

    This function is modelled on inet:getifaddrs/0 but uses
    pcap_findalldevs(3PCAP) to look up the interface attributes:

        * getifaddrs/0 may return pseudo devices, such as the "any"
          device on Linux

        * getifaddrs/0 will only return the list of devices that
          can be used with open/1 and open/2. An empty list ({ok,
          []}) may be returned if the user does not have permission
          to open any of the system interfaces



    % icmp_resend:start("eth0").
    start(Dev) ->
        {ok, Socket} = ewpcap:open(Dev, [{filter, "icmp"}]),

    resend(Socket) ->
        {ok, Packet} = ewpcap:read(Socket),
        ok = ewpcap:write(Socket, Packet),


  • ewpcap, epcap, epcap_compile ... confusing!

  • pcap_sendpacket may block

  • pcap_findalldevices blocks

  • re-write as a port driver?

Something went wrong with that request. Please try again.