View Source ExShark

Hex.pm Documentation Build Status License

ExShark is an Elixir wrapper for tshark (Wireshark's command-line interface) that enables packet capture and analysis using Wireshark's powerful dissectors.

Features

  • ๐Ÿš€ Live packet capture with streaming support
  • ๐Ÿ“ฆ PCAP file analysis
  • ๐Ÿ” Lazy packet loading for memory efficiency
  • โšก Async packet processing
  • ๐Ÿ›  Full access to Wireshark dissectors
  • ๐Ÿ“Š Rich packet information including raw data access
  • ๐Ÿงช Comprehensive test suite

Installation

  1. Ensure you have Wireshark/tshark installed on your system:
# Ubuntu/Debian
sudo apt-get install tshark

# macOS
brew install wireshark
  1. Add exshark to your dependencies in mix.exs:
def deps do
  [
    {:exshark, "~> 0.1.0"},
    {:jason, "~> 1.2"}
  ]
end
  1. Install dependencies:
mix deps.get

Quick Start

Analyzing a PCAP File

# Read all packets from a PCAP file
packets = ExShark.read_file("capture.pcap")

# Access packet information
first_packet = Enum.at(packets, 0)
IO.puts "Protocol: #{first_packet.highest_layer}"

# Access protocol fields (multiple methods available)
source_ip = ExShark.Packet.get_field(first_packet, {:ip, :src})
# OR
source_ip = ExShark.PacketAccess.get(first_packet, {:ip, :src})

Live Capture

# Start a live capture
ExShark.capture(interface: "eth0", filter: "tcp port 80")
|> Stream.each(fn packet ->
  IO.puts "Captured: #{packet.highest_layer}"
  
  # Access source and destination addresses
  src = ExShark.Packet.get_field(packet, {:eth, :src})
  dst = ExShark.Packet.get_field(packet, {:eth, :dst})
  IO.puts "#{src} -> #{dst}"
end)
|> Stream.run()

Lazy Loading

# Start a lazy capture
{:ok, capture} = ExShark.LazyCapture.start_link("large_capture.pcap")

# Load specific packets on demand
packet = ExShark.LazyCapture.get_packet(capture, 1000)
IO.puts "Packet #{packet.frame_info.number}: #{packet.highest_layer}"

Async Processing

callback = fn packet ->
  protocol = packet.highest_layer
  src = ExShark.Packet.get_field(packet, {:ip, :src})
  dst = ExShark.Packet.get_field(packet, {:ip, :dst})
  IO.puts "Processing #{protocol} packet: #{src} -> #{dst}"
  {:ok, nil}
end

ExShark.AsyncCapture.apply_on_packets("capture.pcap", callback, timeout: 5000)

Advanced Usage

Protocol Field Access

There are multiple ways to access packet fields:

# Using the Packet module (recommended)
src_ip = ExShark.Packet.get_field(packet, {:ip, :src})
dst_ip = ExShark.Packet.get_field(packet, {:ip, :dst})

# Using the PacketAccess protocol directly
src_port = ExShark.PacketAccess.get(packet, {:tcp, :srcport})

# Accessing frame info directly
IO.puts "Protocol Stack: #{packet.frame_info.protocols}"

# Getting entire protocol layer
layer = ExShark.Packet.get_layer(packet, :tcp)

Raw Data Access

# Access raw packet data
packet = ExShark.read_file("capture.pcap") |> Enum.at(0)
layer = ExShark.Packet.get_layer(packet, :tcp)

# Enable raw mode for hex/binary data
raw_layer = %{layer | raw_mode: true}
raw_payload = ExShark.Packet.Layer.get_field(raw_layer, :payload)

Documentation

Full documentation can be found at https://hexdocs.pm/tshark_ex.

Development

Prerequisites

  • Elixir 1.14 or later
  • Erlang/OTP 25 or later
  • tshark/Wireshark

Running Tests

Run all tests

mix test

Run with coverage

mix coveralls

Run specific test file

mix test test/exshark/async_capture_test.exs

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Inspired by the Python pyshark library
  • Built on top of the excellent Wireshark project

Support

If you have any questions or run into issues, please open an issue on GitHub.