ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - Cobenian/expcap: Elixir PCAP library
Elixir PCAP library. Contribute to Cobenian/expcap development by creating an account on GitHub.
Visit Site

GitHub - Cobenian/expcap: Elixir PCAP library

GitHub - Cobenian/expcap: Elixir PCAP library

ExPcap

hex.pm Custom hex.pm Version hex.pm License

A PCAP library written in Elixir. This does not wrap a C or Erlang PCAP library, rather it attempts to be an idiomatic Elixir library.

This library parses pcap files, however it does not yet support most protocols that can be contained within a pcap file. The only supported protocols at the moment are:

  • Ethernet
  • IPv4
  • UDP
  • DNS

Add Dependency

In mix.exs add a dependency:

{:expcap, "~> 0.1.0"}

Documentation

Documentation can be found at http://cobenian.github.io/expcap

Documentation

You must have run mix deps.get and mix deps.compile first.

mix docs

Build

You must have Elixir 1.0.0+ installed along with mix.

mix deps.get
mix deps.compile
mix compile
mix escript.build

Test

You must have run mix deps.get and mix deps.compile first.

mix test

Run via Escript

Once the project has been built, the following escript can be run:

./expcap -f <path-file-pcap-file>

A sample DNS cap file can be found in test/data/dns.cap. This file is provided by Wireshark as a sample capture.

./expcap -f test/data/dns.cap

Programmatic Use

Here is a sample using mix:

iex -S mix
iex> ExPcap.from_file "test/data/dns.cap"

If you want to print the string in a more user friendly format:

iex -S mix
iex> "test/data/dns.cap" |> ExPcap.from_file |> String.Chars.to_string

Windows

Escript does not run on Windows so the expcap escript will not work. However, the code in this library should work on Windows if used as an Elixir library. This has not been tested that we are aware of.

Adding Support For Additional Protocols

Adding support for additional protocols is not difficult. Any protocol that may contain your protocol in its body should be updated to indicate that your protocol is supported.

  • Update encapsulating protocols to be aware of the new protocol

For example, if we are adding the UDP protocol and it can be encapsulated in IPv4 packets, we need to modify the IPv4 PayloadType protocol. In this case we would add the following line:

    <<17>> -> Protocol.Udp

Note that each protocol is different in this regard. For example, in IPv4 the header contains a 'protocol' field that indicates the content type of the body. The new IPv4 PayloadType implementation would look like:

    defimpl PayloadType, for: Protocol.Ipv4 do
      @doc """
      Returns the parser that will parse the body of this IPv4 packet.
      """
      @spec payload_parser(binary) :: PayloadParser.t
      def payload_parser(data) do
        case data.header.protocol do
          <<06>> -> Protocol.Tcp
          <<17>> -> Protocol.Udp
        end
      end
    end

Bare Bones:

    defimpl PayloadType, for: Protocol.Ipv4 do
      def payload_parser(data) do
        case data.header.protocol do
          <<06>> -> Protocol.Tcp
          <<17>> -> Protocol.Udp
        end
      end
    end
  • Create a module and struct for your protocol

For many protocols this means having header and data sections only. You may want to include a "parsed data" element as well. Here is an example:

    defmodule Protocol.Udp do
      @moduledoc """
      A parsed UDP packet
      """

      @bytes_in_header 8

      defstruct header: %Protocol.Udp.Header{},
                data: <<>>

      @type t :: %Protocol.Udp{
        header: Protocol.Udp.Header.t,
        data: binary
      }
    end

Bare Bones:

    defmodule Protocol.Udp do
      defstruct header: %Protocol.Udp.Header{},
                data: <<>>
    end
  • Create a struct for your protocol's header (optional)

This is not strictly required, but is generally a good practice.

Here is an example:

    defmodule Protocol.Udp.Header do
      @moduledoc """
      A parsed UDP packet header
      """
      defstruct srcport:     <<>>,
                destport:    <<>>,
                length:      <<>>,
                checksum:    <<>>

      @type t :: %Protocol.Udp.Header{
        srcport:  non_neg_integer,
        destport: non_neg_integer,
        length:   binary,
        checksum: binary
      }
    end

Bare Bones:

    defmodule Protocol.Udp.Header do
      defstruct srcport:     <<>>,
                destport:    <<>>,
                length:      <<>>,
                checksum:    <<>>
    end
  • Implement the PayloadType protocol

Example:

    defimpl PayloadType, for: Protocol.Udp do
      @doc """
      Returns the parser that will parse the body of the UDP packet
      """
      @spec payload_parser(binary) :: Protocol.Udp.t
      def payload_parser(_data) do
        Protocol.Dns
      end
    end

Bare Bones:

    defimpl PayloadType, for: Protocol.Udp do
      def payload_parser(_data) do
        Protocol.Dns
      end
    end
  • Implement the PayloadParser protocol

Example:

    defimpl PayloadParser, for: Protocol.Udp do
      @doc """
      Returns the parsed body of the UDP packet
      """
      @spec from_data(binary) :: any
      def from_data(data) do
        Protocol.Udp.from_data data
      end
    end

Bare Bones:

    defimpl PayloadParser, for: Protocol.Udp do
      def from_data(data) do
        Protocol.Udp.from_data data
      end
    end
  • Add support for parsing your header (optional if you do not have a header)

Example:

    @doc """
    Parses the header of a UDP packet
    """
    @spec header(binary) :: Protocol.Udp.Header.t
    def header(data) do
      <<
      srcport       :: unsigned-integer-size(16),
      destport      :: unsigned-integer-size(16),
      length        :: bytes-size(2),
      checksum      :: bytes-size(2),
      _payload       :: binary
      >> = data
      %Protocol.Udp.Header{
        srcport: srcport,
        destport: destport,
        length: length,
        checksum: checksum
      }
    end

Bare Bones:

    def header(data) do
      <<
        srcport       :: unsigned-integer-size(16),
        destport      :: unsigned-integer-size(16),
        length        :: bytes-size(2),
        checksum      :: bytes-size(2),
        _payload       :: binary
      >> = data
      %Protocol.Udp.Header{
        srcport: srcport,
        destport: destport,
        length: length,
        checksum: checksum
      }
    end
  • Add support for parsing your protocol

Example:

    @doc """
    Returns a parsed UDP packet
    """
    @spec from_data(binary) :: Protocol.Udp.t
    def from_data(data) do
      << _header :: bytes-size(@bytes_in_header), payload :: binary >> = data
      %Protocol.Udp{
        header: header(data),
        data: payload
      }
    end

Bare Bones:

    def from_data(data) do
      << _header :: bytes-size(@bytes_in_header), payload :: binary >> = data
      %Protocol.Udp{
        header: header(data),
        data: payload
      }
    end
  • Add support for printing your header to string (optional if you do not have a header)

Example:

    defimpl String.Chars, for: Protocol.Udp.Header do
      @doc """
      Prints a UDP packet header to a human readable string
      """
      @spec to_string(Protocol.Udp.t) :: String.t
      def to_string(udp) do
        String.trim("""
        srcport:          #{udp.srcport}
        srcport:          #{udp.destport}
        length:           #{ExPcap.Binaries.to_uint16(udp.length)}
        checksum:         #{ExPcap.Binaries.to_hex(udp.checksum)}
        """)
      end
    end

Bare Bones:

    defimpl String.Chars, for: Protocol.Udp.Header do
      def to_string(udp) do
        String.trim("""
        srcport:          #{udp.srcport}
        srcport:          #{udp.destport}
        length:           #{ExPcap.Binaries.to_uint16(udp.length)}
        checksum:         #{ExPcap.Binaries.to_hex(udp.checksum)}
        """)
      end
    end
  • Add support for printing your protocol to string

Example:

    defimpl String.Chars, for: Protocol.Udp do
      @doc """
      Prints a UDP packet to a human readable string
      """
      @spec to_string(Protocol.Udp.t) :: String.t
      def to_string(udp) do
        String.trim("""
        Udp:
        #{udp.header}
        Length:           #{byte_size(udp.data)}
        Raw:              #{ExPcap.Binaries.to_raw(udp.data)}
        """)
      end
    end

Bare Bones:

    defimpl String.Chars, for: Protocol.Udp do
      def to_string(udp) do
        String.trim("""
        Udp:
        #{udp.header}
        Length:           #{byte_size(udp.data)}
        Raw:              #{ExPcap.Binaries.to_raw(udp.data)}
        """)
      end
    end

Limitations

  • Very few protocols are supported at this time.
  • Well formed pcap files can be parsed properly, however corrupted pcap files may not have helpful error messages.
  • Escript will not run on Windows, but the code should.

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory