packetgen 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67bab87e209f3ad1ca3adecf77be2b19c1ba17a5
4
- data.tar.gz: c5bd835c57160261677a22693e297c8b27ac3cbe
3
+ metadata.gz: ba692327da7837d4de41a002ca756a778692c74b
4
+ data.tar.gz: 38fca26934167acbd7d92981f160071c7fd1387f
5
5
  SHA512:
6
- metadata.gz: 466fadd588084aedad8c7e9fbc7ac6313f8f66d47594171fc7728c2056369ffc2e24fedb4794f4a37cd8fcc66ed4dff7db5339e1f19fefc3522d4906a8667953
7
- data.tar.gz: c8bd3cb05a61ae939f152355d45fed6ff0e26b6760dd0bea98fddff4aa86263ec1eea27b24024325ae089246cb78baad3958b9df7a949771150d65c45cba7073
6
+ metadata.gz: 80d8155ad93876fcb14c5d1d85b3a374a1eb865784b914aed802dbb0ab07e97364d10e5affc2a094f4041f695774a41dd60a65e8da2fbdd92e27ca873ad60ddd
7
+ data.tar.gz: ac325e1dae38151f1f73ca05b6604a7373060aaee4a814e9d87c98b4de4e8e8aa64ba11f39930693d9cc8f9e4abb028918237d37e99f5a1becabdf93227effe9
data/.travis.yml CHANGED
@@ -12,7 +12,7 @@ install:
12
12
  - bundler install --path vendor/bundle --jobs=3 --retry=3
13
13
  before_script:
14
14
  - openssl version
15
- - gem list openssl
15
+ - ruby -ropenssl -e 'puts OpenSSL::VERSION'
16
16
  script:
17
17
  - bundler exec rake
18
18
  - rvmsudo bundle exec rake spec:sudo
data/README.md CHANGED
@@ -131,6 +131,21 @@ pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678)
131
131
  pkt.myheader.field2.read 0x01
132
132
  ```
133
133
 
134
+ ## Interactive console
135
+ PacketGen provides an interactive console, based on `pry`: `pgconsole`.
136
+
137
+ In this console, context includes PacketGen module to give direct access to PacketGen
138
+ classes. A special `config` object gives local network configuration:
139
+
140
+ $ pgconsole
141
+ pg(main)> config
142
+ => #<PacketGen::Config:0x00559f27d2afe8
143
+ @hwaddr="75:74:73:72:71:70",
144
+ @iface="eth0",
145
+ @ipaddr="192.168.0.2">
146
+ pg(main)> packets = capture(max: 5)
147
+ pg(main)> exit
148
+
134
149
  ## Pull requests?
135
150
 
136
151
  yes
data/bin/pgconsole ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'packetgen'
5
+ require 'packetgen/config'
6
+ require 'pry'
7
+
8
+ include PacketGen
9
+
10
+ def parse(binary_str, first_header: nil)
11
+ Packet.parse binary_str, first_header: first_header
12
+ end
13
+
14
+ def capture(options={})
15
+ Packet.capture(options) { |packet| yield packet if block_given? }
16
+ end
17
+
18
+ def read(filename)
19
+ Packet.read filename
20
+ end
21
+
22
+ def write(filename, packets)
23
+ Packet.write filename, packets
24
+ end
25
+
26
+ @config = Config.new
27
+
28
+ def config
29
+ @config
30
+ end
31
+
32
+ Pry.config.prompt = [
33
+ proc { |target_self, nest_level, pry|
34
+ "#{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
35
+ },
36
+ proc { |target_self, nest_level, pry|
37
+ "#{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
38
+ }
39
+ ]
40
+ Pry.config.prompt_name = 'pg'
41
+ Pry.start
@@ -7,46 +7,83 @@ module PacketGen
7
7
 
8
8
  # Capture packets from wire
9
9
  # @author Sylvain Daubert
10
+ # @author Kent 'picat' Gruber
10
11
  class Capture
11
12
 
12
- # Default snaplen to use if :snaplen option not defined
13
+ # Default snaplen to use if :snaplen option not defined.
13
14
  DEFAULT_SNAPLEN = 0xffff
14
15
 
15
- # Get captured packets
16
+ # Get captured packets.
16
17
  # @return [Array<Packets>]
17
18
  attr_reader :packets
18
19
 
19
- # Get captured packet raw data
20
+ # Get captured packet raw data.
20
21
  # @return [Array<String>]
21
22
  attr_reader :raw_packets
22
23
 
23
- # @param [String] iface interface on which capture packets
24
- # @param [Hash] options
25
- # @option options [Integer] :max maximum number of packets to capture
26
- # @option options [Integer] :timeout maximum number of seconds before end
27
- # of capture. Default: +nil+ (no timeout)
28
- # @option options [String] :filter bpf filter
29
- # @option options [Boolean] :promiscuous (default: +false+)
30
- # @option options [Boolean] :parse parse raw data to generate packets before
31
- # yielding. Default: +true+
32
- # @option options [Integer] :snaplen maximum number of bytes to capture for
33
- # each packet
34
- def initialize(iface, options={})
35
- @packets = []
24
+ # Get interface name
25
+ # @return [String]
26
+ attr_reader :iface
27
+
28
+ # @overload initialize(iface=Pcap.lookupdev, options={})
29
+ # @param [String] iface interface on which capture packets
30
+ # @param [Hash] options
31
+ # @option options [Integer] :max maximum number of packets to capture.
32
+ # @option options [Integer] :timeout maximum number of seconds before end
33
+ # of capture. Default: +nil+ (no timeout)
34
+ # @option options [String] :filter bpf filter
35
+ # @option options [Boolean] :promiscuous (default: +false+)
36
+ # @option options [Boolean] :parse parse raw data to generate packets before
37
+ # yielding. Default: +true+
38
+ # @option options [Integer] :snaplen maximum number of bytes to capture for
39
+ # each packet.
40
+ # @overload initialize(options={})
41
+ # @param [Hash] options
42
+ # @option options [String] :iface interface on which capture
43
+ # packets on. Default: Use default interface lookup. If no interface found,
44
+ # use loopback one.
45
+ # @option options [Integer] :max maximum number of packets to capture.
46
+ # @option options [Integer] :timeout maximum number of seconds before end
47
+ # of capture. Default: +nil+ (no timeout)
48
+ # @option options [String] :filter bpf filter
49
+ # @option options [Boolean] :promiscuous (default: +false+)
50
+ # @option options [Boolean] :parse parse raw data to generate packets before
51
+ # yielding. Default: +true+
52
+ # @option options [Integer] :snaplen maximum number of bytes to capture for
53
+ # each packet.
54
+ def initialize(iface_or_options={}, options={})
55
+ begin
56
+ @iface = Pcap.lookupdev
57
+ rescue PCAPRUB::BindingError
58
+ @iface = 'lo'
59
+ end
60
+
61
+ case iface_or_options
62
+ when Hash
63
+ options = iface_or_options
64
+ else
65
+ warn "[deprecation] use of PacketGen::Capture#initialize with iface name as\n" \
66
+ " first argument is deprecated. Instead, use:\n" \
67
+ ' PacketGen::Capture.new(iface: \'name\').'
68
+ @iface = iface_or_options.to_s
69
+ end
70
+
71
+ @packets = []
36
72
  @raw_packets = []
37
- @iface = iface
73
+ @promisc = false
74
+ @snaplen = DEFAULT_SNAPLEN
75
+ @parse = true
38
76
  set_options options
39
77
  end
40
78
 
41
79
  # Start capture
42
80
  # @param [Hash] options complete see {#initialize}.
43
81
  # @yieldparam [Packet,String] packet if a block is given, yield each
44
- # captured packet (Packet or raw data String, depending on +:parse+)
82
+ # captured packet (Packet or raw data String, depending on +:parse+ option)
45
83
  def start(options={})
46
84
  set_options options
47
85
  @pcap = PCAPRUB::Pcap.open_live(@iface, @snaplen, @promisc, 1)
48
86
  set_filter
49
-
50
87
  @cap_thread = Thread.new do
51
88
  @pcap.each do |packet_data|
52
89
  @raw_packets << packet_data
@@ -57,9 +94,7 @@ module PacketGen
57
94
  else
58
95
  yield packet_data if block_given?
59
96
  end
60
- if @max
61
- break if @raw_packets.size >= @max
62
- end
97
+ break if @max and @raw_packets.size >= @max
63
98
  end
64
99
  end
65
100
  @cap_thread.join(@timeout)
@@ -80,21 +115,10 @@ module PacketGen
80
115
  @max = options[:max] if options[:max]
81
116
  @filter = options[:filter] if options[:filter]
82
117
  @timeout = options[:timeout] if options[:timeout]
83
- if options[:promisc]
84
- @promisc = options[:promisc]
85
- else
86
- @promisc ||= false
87
- end
88
- if options[:snaplen]
89
- @snaplen = options[:snaplen]
90
- else
91
- @snaplen ||= DEFAULT_SNAPLEN
92
- end
93
- if options[:parse].nil?
94
- @parse = true if @parse.nil?
95
- else
96
- @parse = options[:parse]
97
- end
118
+ @promisc = options[:promisc] if options.has_key? :promisc
119
+ @snaplen = options[:snaplen] if options[:snaplen]
120
+ @parse = options[:parse] if options.has_key? :parse
121
+ @iface = options[:iface] if options[:iface]
98
122
  end
99
123
 
100
124
  def set_filter
@@ -0,0 +1,39 @@
1
+ require 'network_interface'
2
+ require 'socket'
3
+
4
+ module PacketGen
5
+
6
+ # Config class to provide +config+ object to pgconsole
7
+ # @author Sylvain Daubert
8
+ class Config
9
+
10
+ # Default network interface
11
+ # @return [String]
12
+ attr_reader :iface
13
+ # MAC address of default interface
14
+ # @return [String]
15
+ attr_reader :hwaddr
16
+ # IP address of default interface
17
+ # @return [String]
18
+ attr_reader :ipaddr
19
+ # IPv6 address of default interface
20
+ # @return [String]
21
+ attr_reader :ip6addr
22
+
23
+ # Create a configuration object. If +iface+ is not set, get first network interface.
24
+ # If non exists, use loopback one.
25
+ # @param [String,nil] iface
26
+ def initialize(iface=nil)
27
+ if iface.nil?
28
+ iface = NetworkInterface.interfaces.select { |iface| iface != 'lo' }.first
29
+ iface = NetworkInterface.interfaces.first if iface.nil?
30
+ end
31
+ @iface = iface
32
+
33
+ addresses = NetworkInterface.addresses(iface)
34
+ @hwaddr = addresses[Socket::AF_PACKET][0]['addr'] if addresses[Socket::AF_PACKET]
35
+ @ipaddr = addresses[Socket::AF_INET][0]['addr'] if addresses[Socket::AF_INET]
36
+ @ip6addr = addresses[Socket::AF_INET6][0]['addr'] if addresses[Socket::AF_INET6]
37
+ end
38
+ end
39
+ end
@@ -33,10 +33,10 @@ module PacketGen
33
33
  #
34
34
  # == Get packets
35
35
  # Packets may be captured from wire:
36
- # Packet.capture('eth0') do |packet|
36
+ # Packet.capture do |packet|
37
37
  # do_some_stuffs
38
38
  # end
39
- # packets = Packet.capture('eth0', max: 5) # get 5 packets
39
+ # packets = Packet.capture(iface: 'eth0', max: 5) # get 5 packets from eth0
40
40
  #
41
41
  # Packets may also be read from a file:
42
42
  # packets = Packet.read(file.pcapng)
@@ -68,9 +68,10 @@ module PacketGen
68
68
  new.parse binary_str, first_header: first_header
69
69
  end
70
70
 
71
- # Capture packets from +iface+
72
- # @param [String] iface interface name
71
+ # Capture packets
73
72
  # @param [Hash] options capture options
73
+ # @option options [String] :iface interface on which capture
74
+ # packets on. Default: Use default interface lookup.
74
75
  # @option options [Integer] :max maximum number of packets to capture
75
76
  # @option options [Integer] :timeout maximum number of seconds before end
76
77
  # of capture
@@ -78,8 +79,8 @@ module PacketGen
78
79
  # @option options [Boolean] :promiscuous
79
80
  # @yieldparam [Packet] packet if a block is given, yield each captured packet
80
81
  # @return [Array<Packet>] captured packet
81
- def self.capture(iface, options={})
82
- capture = Capture.new(iface, options)
82
+ def self.capture(options={})
83
+ capture = Capture.new(options)
83
84
  if block_given?
84
85
  capture.start { |packet| yield packet }
85
86
  else
@@ -8,5 +8,5 @@
8
8
  # @author Sylvain Daubert
9
9
  module PacketGen
10
10
  # PacketGen version
11
- VERSION = "1.4.0"
11
+ VERSION = "1.4.1"
12
12
  end
data/lib/packetgen.rb CHANGED
@@ -42,8 +42,8 @@ module PacketGen
42
42
  # @param [Hash] options capture options. See {Packet.capture}.
43
43
  # @yieldparam [Packet] packet
44
44
  # @return [Array<Packet>]
45
- def self.capture(iface, options={})
46
- Packet.capture(iface, options) { |packet| yield packet if block_given? }
45
+ def self.capture(options={})
46
+ Packet.capture(options) { |packet| yield packet if block_given? }
47
47
  end
48
48
 
49
49
  # Shortcut for {Packet.read}
data/packetgen.gemspec CHANGED
@@ -16,13 +16,15 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
17
  f.match(%r{^(test|spec|features)/})
18
18
  end
19
- spec.bindir = 'exe'
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.bindir = 'bin'
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.required_ruby_version = '>= 2.1.0'
24
24
 
25
25
  spec.add_dependency 'pcaprub', '~>0.12.4'
26
+ spec.add_dependency 'pry', '~>0.10'
27
+ spec.add_dependency 'network_interface'
26
28
 
27
29
  spec.add_development_dependency 'bundler', '~> 1.7'
28
30
  spec.add_development_dependency 'rake', '~> 10.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetgen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-17 00:00:00.000000000 Z
11
+ date: 2017-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pcaprub
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.12.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.10'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: network_interface
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -97,7 +125,8 @@ dependencies:
97
125
  description:
98
126
  email:
99
127
  - sylvain.daubert@laposte.net
100
- executables: []
128
+ executables:
129
+ - pgconsole
101
130
  extensions: []
102
131
  extra_rdoc_files: []
103
132
  files:
@@ -107,8 +136,10 @@ files:
107
136
  - LICENSE
108
137
  - README.md
109
138
  - Rakefile
139
+ - bin/pgconsole
110
140
  - lib/packetgen.rb
111
141
  - lib/packetgen/capture.rb
142
+ - lib/packetgen/config.rb
112
143
  - lib/packetgen/header.rb
113
144
  - lib/packetgen/header/arp.rb
114
145
  - lib/packetgen/header/base.rb