packetgen 0.1.0 → 0.2.0

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: b95374a3ba00773c1a45e0464a797b1173aa4285
4
- data.tar.gz: 4a6e2f8b12b6552de7afdca695e99221453439c1
3
+ metadata.gz: 7d79b3046c42fa081a32cbb80633d26115aa8d8a
4
+ data.tar.gz: 554c95accb7cba2eb8fd1199962b76c914d479dd
5
5
  SHA512:
6
- metadata.gz: 95ddd04f2758a1ef9f17d0b343ea9b00f718ad926adbf13bdd3bc9444e3d8a3cf980a8a8c7e3f5ebebf27a775da676f1754f86cf1dd15756c03fa76a1901184c
7
- data.tar.gz: 145591b54094dcac9690e483138f123597029b12659c95d5ee1d7c14865f654003b17c24fd75a46647fe6c0864bccdff69bfd6e7e28623e2b3024628c447d073
6
+ metadata.gz: 4543ec99fea03226b5a0acaf712f49e2683910953d852dcdff5ec1d71e3ec7e908efb32ee7a5e9707ed0bfe8ec33fba757922a7c0ae4a99e84401e8454e934f0
7
+ data.tar.gz: e4c77821a111d8d0b921c87067d3a890c2efd23d2127b0655863ca7b062ac1546746a9d2e0690b3622cc73e355b7592fbe34bbb2b75c3e7770d6ee82e2065a6a
@@ -11,4 +11,4 @@ install:
11
11
  - bundler install --path vendor/bundle --jobs=3 --retry=3
12
12
  script:
13
13
  - bundler exec rake
14
- - rvmsudo bundle exec rake spec:sudo
14
+ - rvmsudo bundle exec rake spec:sudo
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
 
2
+ [![Gem Version](https://badge.fury.io/rb/packetgen.svg)](https://badge.fury.io/rb/packetgen)
2
3
  [![Build Status](https://travis-ci.org/sdaubert/packetgen.svg?branch=master)](https://travis-ci.org/sdaubert/packetgen)
3
4
 
4
5
  # PacketGen
5
6
 
6
- PacketGen aims at generate and capture network packets easily.
7
+ PacketGen provides simple ways to generate, send and capture network packets easily.
7
8
 
8
9
  ## Why PacketGen
9
10
  Why create PacketGen ? There is already PacketFu!
@@ -17,7 +18,11 @@ Yes. But PacketFu is limited:
17
18
 
18
19
  ## use cases
19
20
 
20
- For now, PacketGen is only a concept...
21
+ These use cases are the roadmap for PacketGen.
22
+
23
+ Not yet implemented:
24
+ - encapsulation/decapsulation
25
+ - some protocols...
21
26
 
22
27
  ### Easily create packets
23
28
  ```
data/Rakefile CHANGED
@@ -8,11 +8,14 @@ RSpec::Core::RakeTask.new do |t|
8
8
  t.rspec_opts = '-t ~sudo'
9
9
  end
10
10
  RSpec::Core::RakeTask.new('spec:sudo') do |t|
11
- t.rspec_opts = '-t sudo'
11
+ if ENV['TRAVIS']
12
+ t.rspec_opts = '-t sudo -t ~notravis'
13
+ else
14
+ t.rspec_opts = '-t sudo'
15
+ end
12
16
  end
13
17
 
14
18
  YARD::Rake::YardocTask.new do |t|
15
19
  t.options = ['--no-private']
16
20
  t.files = ['lib/**/*.rb', '-', 'LICENSE']
17
21
  end
18
-
@@ -42,7 +42,7 @@ module PacketGen
42
42
  # @raise FormatError +header+ not in a packet
43
43
  def ip_header(header)
44
44
  hid = header_id(header)
45
- iph = packet.headers[0...hid].reverse.find { |h| h.is_a? IP }
45
+ iph = packet.headers[0...hid].reverse.find { |h| h.is_a? IP or h.is_a? IPv6 }
46
46
  raise FormatError, 'no IP or IPv6 header in packet' if iph.nil?
47
47
  iph
48
48
  end
@@ -1,3 +1,5 @@
1
+ require 'socket'
2
+
1
3
  module PacketGen
2
4
  module Header
3
5
 
@@ -275,6 +277,25 @@ module PacketGen
275
277
  first_byte = [(version << 4) | ihl].pack('C')
276
278
  first_byte << to_a[2..-1].map { |field| field.to_s }.join
277
279
  end
280
+
281
+ # Get IP part of pseudo header sum.
282
+ # @return [Integer]
283
+ def pseudo_header_sum
284
+ sum = self[:src].to_i + self[:dst].to_i
285
+ (sum >> 16) + (sum & 0xffff)
286
+ end
287
+
288
+ # Send IP packet on wire.
289
+ #
290
+ # When sending packet at IP level, +sum+ and +length+ fields are set by
291
+ # kernel, so bad IP packets cannot be sent this way. To do so, use {Eth#to_w}.
292
+ # @param [String,nil] iface interface name. Not used
293
+ # @return [void]
294
+ def to_w(iface=nil)
295
+ sock = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
296
+ sockaddrin = Socket.sockaddr_in(0, dst)
297
+ sock.send to_s, 0, sockaddrin
298
+ end
278
299
  end
279
300
 
280
301
  Eth.bind_header IP, proto: 0x800
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'ipaddr'
2
3
 
3
4
  module PacketGen
@@ -207,6 +208,45 @@ module PacketGen
207
208
  first32 = (version << 28) | (traffic_class << 20) | flow_label
208
209
  [first32].pack('N') << to_a[3..-1].map { |field| field.to_s }.join
209
210
  end
211
+
212
+ # Get IPv6 part of pseudo header sum.
213
+ # @return [Integer]
214
+ def pseudo_header_sum
215
+ sum = 0
216
+ self[:src].each { |word| sum += word.to_i }
217
+ self[:dst].each { |word| sum += word.to_i }
218
+ sum
219
+ end
220
+
221
+ # Send IPv6 packet on wire.
222
+ #
223
+ # When sending packet at IPv6 level, +version+, +flow_label+ and +length+
224
+ # fields are set by kernel. Source address should be a unicast address
225
+ # assigned to the host. To set any of this fields, use {Eth#to_w}.
226
+ # @param [String] iface interface name
227
+ # @return [void]
228
+ def to_w(iface=nil)
229
+ sock = Socket.new(Socket::AF_INET6, Socket::SOCK_RAW, self.next)
230
+ sockaddrin = Socket.sockaddr_in(0, dst)
231
+
232
+ # IPv6 RAW sockets don't have IPHDRINCL option to send IPv6 header.
233
+ # So, header must be built using ancillary data.
234
+ # Only src address, traffic_class and hop_limit can be set this way.
235
+ hop_limit = Socket::AncillaryData.int(Socket::AF_INET6,
236
+ Socket::IPPROTO_IPV6,
237
+ Socket::IPV6_HOPLIMIT, hop)
238
+ tc = Socket::AncillaryData.int(Socket::AF_INET6,
239
+ Socket::IPPROTO_IPV6,
240
+ Socket::IPV6_TCLASS,
241
+ traffic_class)
242
+
243
+ # src address is set through PKT_INFO, which needs interface index.
244
+ ifaddr = Socket.getifaddrs.find { |ia| ia.name == iface }
245
+ raise WireError, "unknown #{iface} interface" if ifaddr.nil?
246
+ pkt_info = Socket::AncillaryData.ipv6_pktinfo(Addrinfo.ip(src), ifaddr.ifindex)
247
+
248
+ sock.sendmsg body.to_s, 0, sockaddrin, hop_limit, tc, pkt_info
249
+ end
210
250
  end
211
251
 
212
252
  Eth.bind_header IPv6, proto: 0x86DD
@@ -45,10 +45,7 @@ module PacketGen
45
45
  # @return [Integer]
46
46
  def calc_sum
47
47
  ip = ip_header(self)
48
- sum = ip[:src].to_i >> 16
49
- sum += ip[:src].to_i & 0xffff
50
- sum += ip[:dst].to_i >> 16
51
- sum += ip[:dst].to_i & 0xffff
48
+ sum = ip.pseudo_header_sum
52
49
  sum += IP_PROTOCOL
53
50
  sum += length
54
51
  sum += sport
@@ -129,5 +126,6 @@ module PacketGen
129
126
  end
130
127
 
131
128
  IP.bind_header UDP, proto: UDP::IP_PROTOCOL
129
+ IPv6.bind_header UDP, next: UDP::IP_PROTOCOL
132
130
  end
133
131
  end
@@ -211,8 +211,8 @@ module PacketGen
211
211
  # Recalculate all calculatable fields (for now: length and sum)
212
212
  # @return [void]
213
213
  def calc
214
- calc_sum
215
214
  calc_length
215
+ calc_sum
216
216
  end
217
217
 
218
218
  # Get packet body
@@ -3,5 +3,5 @@
3
3
  # @author Sylvain Daubert
4
4
  module PacketGen
5
5
  # PacketGen version
6
- VERSION = "0.1.0"
6
+ VERSION = "0.2.0"
7
7
  end
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
22
 
23
+ spec.required_ruby_version = '>= 2.1.0'
24
+
23
25
  spec.add_dependency 'pcaprub', '~>0.12.4'
24
26
 
25
27
  spec.add_development_dependency 'bundler', '~> 1.7'
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: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-06 00:00:00.000000000 Z
11
+ date: 2016-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pcaprub
@@ -140,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
140
  requirements:
141
141
  - - ">="
142
142
  - !ruby/object:Gem::Version
143
- version: '0'
143
+ version: 2.1.0
144
144
  required_rubygems_version: !ruby/object:Gem::Requirement
145
145
  requirements:
146
146
  - - ">="