1
2
Fork
You've already forked packetgen
1
Ruby library to easily generate and capture network packets
  • Ruby 100%
2026年06月12日 19:37:17 +02:00
.woodpecker Remove support for Ruby 3.0 2025年12月28日 15:00:12 +01:00
bin Fix some rubocop offenses 2021年04月22日 11:21:30 +02:00
lib fix(config): default_iface returns a list 2026年06月12日 19:37:17 +02:00
spec [SNMP] Fix issue with rasn1 0.16.x 2025年08月14日 12:31:15 +02:00
.gitignore Update .gitignore 2024年10月06日 10:50:40 +02:00
.rubocop.yml Fix up rubocop offenses 2025年12月28日 16:20:32 +01:00
.yardopts [doc] Fix/update YARD documentation 2025年02月21日 12:50:02 +01:00
Changelog.md Bump version to 4.1.1 2025年08月14日 15:19:17 +02:00
doctest_helper.rb [doc] Fix/update YARD documentation 2025年02月21日 12:50:02 +01:00
Gemfile Remove support for Ruby 3.0 2025年12月28日 15:00:12 +01:00
LICENSE Update ownership 2024年07月13日 17:42:57 +02:00
packetgen.gemspec Remove support for Ruby 3.0 2025年12月28日 15:00:12 +01:00
Rakefile [CI] Add woodpecker CI 2025年08月14日 15:08:05 +02:00
README.md Update URL to codeberg.org 2025年08月14日 13:23:22 +02:00
test.rb Bump version to 4.1.1 2025年08月14日 15:19:17 +02:00

Gem Version status-badge

PacketGen

PacketGen provides simple ways to generate, send and capture network packets.

Installation

PacketGen depends on PcapRub, which needs pcap development files to install. On Debian, you have to do:

sudo apt install libpcap-dev

Installation using RubyGems is then easy:

gem install packetgen

Or add it to a Gemfile:

gem 'packetgen'

Usage

Easily create packets

PacketGen.gen('IP') # generate a IP packet object
PacketGen.gen('TCP') # generate a TCP over IP packet object
PacketGen.gen('IP').add('TCP') # the same
PacketGen.gen('Eth') # generate a Ethernet packet object
PacketGen.gen('IP').add('IP') # generate a IP-in-IP tunnel packet object
# Generate a IP packet object, specifying addresses
PacketGen.gen('IP', src: '192.168.1.1', dst: '192.168.1.2')
# get binary packet
PacketGen.gen('IP').to_s

Send packets on wire

# send Ethernet packet
PacketGen.gen('Eth', src: '00:00:00:00:00:01', dst: '00:00:00:00:00:02').to_w
# send IP packet
PacketGen.gen('IP', src: '192.168.1.1', dst: '192.168.1.2').to_w
# send forged IP packet over Ethernet
PacketGen.gen('Eth', src: '00:00:00:00:00:01', dst: '00:00:00:00:00:02').add('IP').to_w('eth1')
# send a IEEE 802.11 frame
PacketGen.gen('RadioTap').
 add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid).
 add('Dot11::DeAuth', reason: 7).
 to_w('wlan0')

Parse packets from binary data

packet = PacketGen.parse(binary_data)

Capture packets from wire

# Capture packets from first network interface, action from a block
PacketGen.capture do |packet|
 do_stuffs_with_packet
end
# Capture some packets, and act on them afterward
packets = PacketGen.capture(iface: 'eth0', max: 10) # return when 10 packets were captured
# Use filters
packets = PacketGen.capture(iface: 'eth0', filter: 'ip src 1.1.1.2', max: 1)

Easily manipulate packets

# access header fields
pkt = PacketGen.gen('IP').add('TCP')
pkt.ip.src = '192.168.1.1'
pkt.ip(src: '192.168.1.1', ttl: 4)
pkt.tcp.dport = 80
# access header fields when multiple header of one kind exist
pkt = PacketGen.gen('IP').add('IP')
pkt.ip.src = '192.168.1.1' # set outer src field
pkt.ip(2).src = '10.0.0.1' # set inner src field
# test packet types
pkt = PacketGen.gen('IP').add('TCP')
pkt.is? 'TCP' # => true
pkt.is? 'IP' # => true
pkt.is? 'UDP' # => false
# encapulsate/decapsulate packets
pkt2 = PacketGen.gen('IP')
pkt2.encapsulate pkt # pkt2 is now a IP/IP/TCP packet
pkt2.decapsulate(pkt2.ip) # pkt2 is now inner IP/TCP packet

Read/write PcapNG files

# read a PcapNG file, containing multiple packets
packets = PacketGen.read('file.pcapng')
packets.first.udp.sport = 65535
# write only one packet to a PcapNG file
pkt.write('one_packet.pcapng')
# write multiple packets to a PcapNG file
PacketGen.write('more_packets.pcapng', packets)

Add custom header/protocol

PacketGen permits adding your own header classes.

First, define the new header class. For example:

module MyModule
 class MyHeader < PacketGen::Header::Base
 define_attr :field1, BinStruct::Int32
 define_attr :field2, BinStruct::Int32
 end
end

Then, class must be declared to PacketGen:

PacketGen::Header.add_class MyModule::MyHeader

Finally, bindings must be declared:

# bind MyHeader as IP protocol number 254 (needed by Packet#parse and Packet#add)
PacketGen::Header::IP.bind_header MyModule::MyHeader, protocol: 254

And use it:

pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678, field2: 0x87654321)
pkt.to_w # Send it on wire

Interactive console

PacketGen provides an interactive console: pgconsole.

In this console, context includes PacketGen module to give direct access to PacketGen classes. A special config object gives local network configuration:

$ pgconsole
pg(main)> config
=> #<PacketGen::Config:0x00559f27d2afe8
 @hwaddr="75:74:73:72:71:70",
 @iface="eth0",
 @ipaddr="192.168.0.2">
pg(main)> packets = capture(max: 5)
pg(main)> exit

If pry gem is installed, it is used as backend for pgconsole, else IRB is used.

Plugins

PacketGen provides a plugin system (see wiki).

Available plugins (available as gem) are:

See also

Wiki: https://codeberg.org/lemontree55/packetgen/wiki

Contributing

Bug reports and pull requests are welcome on Codeberg at https://codeberg.org/lemontree55/packetgen.

License

MIT License (see LICENSE)

Other sources

All original code maintains its copyright from its original authors and licensing.