packetgen 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,35 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module Header
3
8
 
4
- # UDP header class
9
+ # A UDP header consists of:
10
+ # * a source port field ({#sport}, {Int16} type),
11
+ # * a destination port field ({#dport}, +Int16+ type),
12
+ # * a UDP length field ({#length}, +Int16+ type),
13
+ # * a {#checksum} field (+Int16+ type),
14
+ # * and a {#body}.
15
+ #
16
+ # == Create a UDP header
17
+ # # standalone
18
+ # udp = PacketGen::Header::UDP.new
19
+ # # in a packet
20
+ # pkt = PAcketGen.gen('IP').eadd('UDP')
21
+ # # access to IP header
22
+ # pkt.udp # => PacketGen::Header::UDP
23
+ #
24
+ # == UDP attributes
25
+ # udp.sport = 65432
26
+ # udp.dport = 53
27
+ # udp.length = 43
28
+ # udp.checksum = 0xffff
29
+ # udp.body.read 'this is a UDP body'
30
+ #
5
31
  # @author Sylvain Daubert
6
- class UDP < Struct.new(:sport, :dport, :length, :sum, :body)
32
+ class UDP < Struct.new(:sport, :dport, :length, :checksum, :body)
7
33
  include StructFu
8
34
  include HeaderMethods
9
35
  extend HeaderClassMethods
@@ -15,12 +41,12 @@ module PacketGen
15
41
  # @option options [Integer] :sport source port
16
42
  # @option options [Integer] :dport destination port
17
43
  # @option options [Integer] :length UDP length. Default: calculated
18
- # @option options [Integer] :sum. UDP checksum. Default: 0
44
+ # @option options [Integer] :checksum. UDP checksum. Default: 0
19
45
  def initialize(options={})
20
46
  super Int16.new(options[:sport]),
21
47
  Int16.new(options[:dport]),
22
48
  Int16.new(options[:length]),
23
- Int16.new(options[:sum]),
49
+ Int16.new(options[:checksum]),
24
50
  StructFu::String.new.read(options[:body])
25
51
  unless options[:length]
26
52
  calc_length
@@ -32,20 +58,20 @@ module PacketGen
32
58
  # @return [self]
33
59
  def read(str)
34
60
  return self if str.nil?
35
- raise ParseError, 'string too short for Eth' if str.size < self.sz
61
+ raise ParseError, 'string too short for UDP' if str.size < self.sz
36
62
  force_binary str
37
63
  self[:sport].read str[0, 2]
38
64
  self[:dport].read str[2, 2]
39
65
  self[:length].read str[4, 2]
40
- self[:sum].read str[6, 2]
66
+ self[:checksum].read str[6, 2]
41
67
  self[:body].read str[8..-1]
42
68
  end
43
69
 
44
- # Compute checksum and set +sum+ field
70
+ # Compute checksum and set +checksum+ field
45
71
  # @return [Integer]
46
- def calc_sum
72
+ def calc_checksum
47
73
  ip = ip_header(self)
48
- sum = ip.pseudo_header_sum
74
+ sum = ip.pseudo_header_checksum
49
75
  sum += IP_PROTOCOL
50
76
  sum += length
51
77
  sum += sport
@@ -59,7 +85,7 @@ module PacketGen
59
85
  sum = (sum & 0xffff) + (sum >> 16)
60
86
  end
61
87
  sum = ~sum & 0xffff
62
- self[:sum].value = (sum == 0) ? 0xffff : sum
88
+ self[:checksum].value = (sum == 0) ? 0xffff : sum
63
89
  end
64
90
 
65
91
  # Compute length and set +length+ field
@@ -105,27 +131,27 @@ module PacketGen
105
131
  end
106
132
 
107
133
  # Setter for length attribuute
108
- # @param [Integer] port
134
+ # @param [Integer] len
109
135
  # @return [Integer]
110
136
  def length=(len)
111
137
  self[:length].read len
112
138
  end
113
139
 
114
- # Getter for sum attribuute
140
+ # Getter for checksum attribuute
115
141
  # @return [Integer]
116
- def sum
117
- self[:sum].to_i
142
+ def checksum
143
+ self[:checksum].to_i
118
144
  end
119
145
 
120
- # Setter for sum attribuute
121
- # @param [Integer] sum
146
+ # Setter for checksum attribuute
147
+ # @param [Integer] checksum
122
148
  # @return [Integer]
123
- def sum=(sum)
124
- self[:sum].read sum
149
+ def checksum=(checksum)
150
+ self[:checksum].read checksum
125
151
  end
126
152
  end
127
153
 
128
- IP.bind_header UDP, proto: UDP::IP_PROTOCOL
154
+ IP.bind_header UDP, protocol: UDP::IP_PROTOCOL
129
155
  IPv6.bind_header UDP, next: UDP::IP_PROTOCOL
130
156
  end
131
157
  end
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  # Namespace for protocol header classes
3
8
  # @author Sylvain Daubert
@@ -21,3 +26,4 @@ require_relative 'header/arp'
21
26
  require_relative 'header/ipv6'
22
27
  require_relative 'header/icmpv6'
23
28
  require_relative 'header/udp'
29
+ require_relative 'header/tcp'
@@ -0,0 +1,76 @@
1
+ module PacketGen
2
+
3
+ # {Inspect} module provides methods to help writing +inspect+
4
+ # @api private
5
+ # @author Sylvain Daubert
6
+ module Inspect
7
+
8
+ # Maximum number of characters on a line for INSPECT
9
+ INSPECT_MAX_WIDTH = 70
10
+
11
+ # Format to inspect attribute
12
+ INSPECT_FMT_ATTR = "%7s %12s: %s\n"
13
+
14
+ # Create a dashed line with +obj+ class writing in it
15
+ # @param [String] name
16
+ # @param [Integer] level
17
+ # @return [String]
18
+ def self.dashed_line(name, level=1)
19
+ str = '--' * level << " #{name} "
20
+ str << '-' * (INSPECT_MAX_WIDTH - str.length) << "\n"
21
+ end
22
+
23
+ # @return [String]
24
+ def self.shift_level(level=1)
25
+ ' ' + ' ' * level
26
+ end
27
+
28
+ # @param [#to_i] value
29
+ # @param [Integer] hex_size
30
+ # @return [String]
31
+ def self.int_dec_hex(value, hexsize)
32
+ "%-10s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
33
+ end
34
+
35
+ # Format an attribute for +#inspect+.
36
+ # 3 cases are handled:
37
+ # * attribute value is a {StructFu::Int}: show value as integer and in
38
+ # hexdecimal format,
39
+ # * attribute value responds to +#to_human+: call it,
40
+ # * else, +#to_s+ is used to format attribute value.
41
+ # @param [Symbol] attr attribute name
42
+ # @param [Object] value attribute value
43
+ # @param [Integer] level
44
+ # @return [String]
45
+ def self.inspect_attribute(attr, value, level=1)
46
+ str = shift_level(level)
47
+ val = if value.is_a? StructFu::Int
48
+ int_dec_hex(value, value.to_s.size * 2)
49
+ elsif value.respond_to? :to_human
50
+ value.to_human
51
+ else
52
+ value.to_s
53
+ end
54
+ str << INSPECT_FMT_ATTR % [value.class.to_s.sub(/.*::/, ''), attr, val]
55
+ end
56
+
57
+ # @param [#to_s] body
58
+ # @return [String]
59
+ def self.inspect_body(body)
60
+ str = dashed_line('Body', 2)
61
+ str << (0..15).to_a.map { |v| " %02d" % v}.join << "\n"
62
+ str << '-' * INSPECT_MAX_WIDTH << "\n"
63
+ if body.size > 0
64
+ (body.size / 16 + 1).times do |i|
65
+ octets = body.to_s[i*16, 16].unpack('C*')
66
+ o_str = octets.map { |v| " %02x" % v}.join
67
+ str << o_str
68
+ str << ' ' * (3*16 - o_str.size) unless o_str.size >= 3*16
69
+ str << ' ' << octets.map { |v| v < 128 && v > 13 ? v.chr : '.' }.join
70
+ str << "\n"
71
+ end
72
+ end
73
+ str << '-' * INSPECT_MAX_WIDTH << "\n"
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,7 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
1
5
  require 'pcaprub'
2
6
 
3
7
  module PacketGen
@@ -42,9 +46,6 @@ module PacketGen
42
46
  # @return [Array<Header::Base]
43
47
  attr_reader :headers
44
48
 
45
- # @private maximum number of characters on a line for INSPECT
46
- INSPECT_MAX_WIDTH = 70
47
-
48
49
  # Create a new Packet
49
50
  # @param [String] protocol base protocol for packet
50
51
  # @param [Hash] options specific options for +protocol+
@@ -194,9 +195,9 @@ module PacketGen
194
195
 
195
196
  # Recalculate all packet checksums
196
197
  # @return [void]
197
- def calc_sum
198
+ def calc_checksum
198
199
  @headers.reverse.each do |header|
199
- header.calc_sum if header.respond_to? :calc_sum
200
+ header.calc_checksum if header.respond_to? :calc_checksum
200
201
  end
201
202
  end
202
203
 
@@ -208,11 +209,11 @@ module PacketGen
208
209
  end
209
210
  end
210
211
 
211
- # Recalculate all calculatable fields (for now: length and sum)
212
+ # Recalculate all calculatable fields (for now: length and checksum)
212
213
  # @return [void]
213
214
  def calc
214
215
  calc_length
215
- calc_sum
216
+ calc_checksum
216
217
  end
217
218
 
218
219
  # Get packet body
@@ -222,7 +223,7 @@ module PacketGen
222
223
  end
223
224
 
224
225
  # Set packet body
225
- # @param [String]
226
+ # @param [String] str
226
227
  # @return [void]
227
228
  def body=(str)
228
229
  @headers.last.body = str
@@ -258,15 +259,11 @@ module PacketGen
258
259
 
259
260
  # @return [String]
260
261
  def inspect
261
- str = dashed_line(self.class)
262
+ str = Inspect.dashed_line(self.class)
262
263
  @headers.each do |header|
263
- str << dashed_line(header.class, 2)
264
- header.to_h.each do |attr, value|
265
- next if attr == :body
266
- str << inspect_line(attr, value, 2)
267
- end
264
+ str << header.inspect
268
265
  end
269
- str << inspect_body
266
+ str << Inspect.inspect_body(body)
270
267
  end
271
268
 
272
269
  # @param [Packet] other
@@ -315,42 +312,6 @@ module PacketGen
315
312
  raise ArgumentError, "unknown #{protocol} protocol" unless klass.is_a? Class
316
313
  klass
317
314
  end
318
-
319
- def dashed_line(name, level=1)
320
- str = '--' * level << " #{name} "
321
- str << '-' * (INSPECT_MAX_WIDTH - str.length) << "\n"
322
- end
323
-
324
- def inspect_line(attr, value, level=1)
325
- str = ' ' + ' ' * level
326
- val = if value.is_a? StructFu::Int
327
- sz = value.to_s.size
328
- "%-10s (0x%0#{2*sz}x)" % [value.to_i, value.to_i]
329
- elsif value.respond_to? :to_x
330
- value.to_x
331
- else
332
- value.to_s
333
- end
334
- str << "%7s %10s: %s" % [value.class.to_s.sub(/.*::/, ''), attr, val]
335
- str << "\n"
336
- end
337
-
338
- def inspect_body
339
- str = dashed_line('Body', 2)
340
- str << (0..15).to_a.map { |v| " %02d" % v}.join << "\n"
341
- str << '-' * INSPECT_MAX_WIDTH << "\n"
342
- if body.size > 0
343
- (body.size / 16 + 1).times do |i|
344
- octets = body.to_s[i*16, 16].unpack('C*')
345
- o_str = octets.map { |v| " %02x" % v}.join
346
- str << o_str
347
- str << ' ' * (3*16 - o_str.size) unless o_str.size >= 3*16
348
- str << ' ' << octets.map { |v| v < 128 && v > 13 ? v.chr : '.' }.join
349
- str << "\n"
350
- end
351
- end
352
- str << '-' * INSPECT_MAX_WIDTH << "\n"
353
- end
354
315
  end
355
316
  end
356
317
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,8 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  module PacketGen
2
7
  module PcapNG
3
8
 
@@ -1,3 +1,7 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
1
5
  require 'stringio'
2
6
 
3
7
  module PacketGen
@@ -1,10 +1,10 @@
1
- # -*- coding: binary -*-
1
+ # -*- coding: utf-8 -*-
2
2
  module PacketGen
3
+ # Copied from PacketFu:
4
+ #
3
5
  # StructFu, a nifty way to leverage Ruby's built in Struct class
4
6
  # to create meaningful binary data.
5
7
  #
6
- # Copied from PacketFu:
7
- #
8
8
  # Copyright (c) 2008-2014, Tod Beardsley
9
9
  # All rights reserved.
10
10
  #
@@ -30,6 +30,7 @@ module PacketGen
30
30
  # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
31
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
32
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ # @author Tod Beardsley
33
34
  module StructFu
34
35
 
35
36
  # Normally, self.size and self.length will refer to the Struct
@@ -82,6 +83,7 @@ module PacketGen
82
83
 
83
84
  # Get binary string
84
85
  # @return [String]
86
+ # @author Sylvain Daubert
85
87
  def to_s
86
88
  to_a.map { |field| field.to_s }.join
87
89
  end
@@ -1,7 +1,12 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
1
6
  # PacketGen is a network packet generator and analyzor.
2
7
  #
3
8
  # @author Sylvain Daubert
4
9
  module PacketGen
5
10
  # PacketGen version
6
- VERSION = "0.3.0"
11
+ VERSION = "1.0.0"
7
12
  end
data/lib/packetgen.rb CHANGED
@@ -1,5 +1,10 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
1
5
  require 'packetgen/version'
2
6
 
7
+ # PacketGen is a network packet generator and analyzor.
3
8
  # @author Sylvain Daubert
4
9
  module PacketGen
5
10
 
@@ -28,7 +33,7 @@ module PacketGen
28
33
  # @param [String] first_header First protocol header
29
34
  # @return [Packet]
30
35
  def self.parse(binary_str, first_header: nil)
31
- Packet.parse binary_str, first_header
36
+ Packet.parse binary_str, first_header: first_header
32
37
  end
33
38
 
34
39
  # Shortcut for {Packet.capture}
@@ -78,6 +83,7 @@ module PacketGen
78
83
  end
79
84
 
80
85
  require 'packetgen/structfu'
86
+ require 'packetgen/inspect'
81
87
  require 'packetgen/packet'
82
88
  require 'packetgen/capture'
83
89
  require 'packetgen/pcapng'
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.3.0
4
+ version: 1.0.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-10 00:00:00.000000000 Z
11
+ date: 2016-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pcaprub
@@ -118,7 +118,11 @@ files:
118
118
  - lib/packetgen/header/icmpv6.rb
119
119
  - lib/packetgen/header/ip.rb
120
120
  - lib/packetgen/header/ipv6.rb
121
+ - lib/packetgen/header/tcp.rb
122
+ - lib/packetgen/header/tcp/option.rb
123
+ - lib/packetgen/header/tcp/options.rb
121
124
  - lib/packetgen/header/udp.rb
125
+ - lib/packetgen/inspect.rb
122
126
  - lib/packetgen/packet.rb
123
127
  - lib/packetgen/pcapng.rb
124
128
  - lib/packetgen/pcapng/block.rb
@@ -150,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
154
  version: '0'
151
155
  requirements: []
152
156
  rubyforge_project:
153
- rubygems_version: 2.5.1
157
+ rubygems_version: 2.5.2
154
158
  signing_key:
155
159
  specification_version: 4
156
160
  summary: Network packet generator and analyzor