packetgen 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c68cb5128a07a395378b28ecf7ab5711be938cbc5fb2807d42b7cb9a946ed5d
4
- data.tar.gz: cb5d764d681dcda886a0fd2b5c3d852aa1eb477edb116286e8ac449e7170c5bd
3
+ metadata.gz: 05c4708dc2f5da405247b3dbc37d2ff96180086949587f1a7027ef65a9bc8b5d
4
+ data.tar.gz: 323d1b0810e378ac564b260ddfa182b7d7f4e3ca1504f2e03d46ac7511f4c3db
5
5
  SHA512:
6
- metadata.gz: de785e82d0bc1d5d1a00d6069a74e120fdd6323bd68ab1c06e285967e2d6ab6c32caec8a8079e393cd52076d81d7ab0ccbbb2522d4212264181a7c5033a8718a
7
- data.tar.gz: fa91feb360719d3a10a7b984cc89c1cb1c842ec69b41121029f68b374e0a2db03f02ea50898b78fb1ce439dd0aed3a2e60635acb8242e71a01184faaece91c99
6
+ metadata.gz: 1e96208217d2e909db2d2cfd5ffc4eed7180b9c9cde98f20af34e7cd7b28404c744eb6a51851b4e0ad5aba79ec91cb39ae6f21292bee2a6ec60d423fd8bbdece
7
+ data.tar.gz: 9f59f2ecc4f409b43a38c9a16e0d632182af19fa958687599db5ce719e3776b4a24e48384a432e8e2f4a6bc6312f96e2ed0c474d6ebc7db13f4ccdcbdb71666a
data/.travis.yml CHANGED
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
  sudo: required
3
3
  rvm:
4
- - 2.2
5
4
  - 2.3
6
5
  - 2.4
7
6
  - 2.5
@@ -11,54 +11,10 @@ module PacketGen
11
11
  # @author Sylvain Daubert
12
12
  # @since 2.5.1
13
13
  module NetBIOS
14
- # NetBIOS Session Service messages.
15
- # @author Sylvain Daubert
16
- class Session < Base
17
- # Port number for NetBIOS Session Service over TCP
18
- TCP_PORT = 139
19
-
20
- # Session packet types
21
- TYPES = {
22
- 'message' => 0,
23
- 'request' => 0x81,
24
- 'positive_response' => 0x82,
25
- 'negative_response' => 0x83,
26
- 'retarget_response' => 0x84,
27
- 'keep_alive' => 0x85,
28
- }.freeze
29
-
30
- # @!attribute type
31
- # 8-bit session packet type
32
- # @return [Integer]
33
- define_field :type, Types::Int8Enum, enum: TYPES
34
- # @!attribute length
35
- # 17-bit session packet length
36
- # @return [Integer]
37
- define_field :length, Types::Int24
38
- # @!attribute body
39
- # @return [String]
40
- define_field :body, Types::String
41
-
42
- # Compute and set {#length} field
43
- # @return [Integer] calculated length
44
- def calc_length
45
- Base.calculate_and_set_length(self, header_in_size: false)
46
- end
47
-
48
- # @api private
49
- # @note This method is used internally by PacketGen and should not be
50
- # directly called
51
- # @since 2.7.0 Set TCP sport according to bindings, only if sport is 0.
52
- # Needed by new bind API.
53
- def added_to_packet(packet)
54
- return unless packet.is? 'TCP'
55
- return unless packet.tcp.sport.zero?
56
- packet.tcp.sport = TCP_PORT
57
- end
58
- end
59
14
  end
60
- self.add_class NetBIOS::Session
61
- TCP.bind NetBIOS::Session, dport: NetBIOS::Session::TCP_PORT
62
- TCP.bind NetBIOS::Session, sport: NetBIOS::Session::TCP_PORT
63
15
  end
64
16
  end
17
+
18
+ require_relative 'netbios/name'
19
+ require_relative 'netbios/session'
20
+ require_relative 'netbios/datagram'
@@ -0,0 +1,105 @@
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
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+ # Module to group all NetBIOS headers
11
+ # @author Sylvain Daubert
12
+ # @since 2.5.1
13
+ module NetBIOS
14
+ # NetBIOS Session Service messages.
15
+ # @author Sylvain Daubert
16
+ class Datagram < Base
17
+ # Port number for NetBIOS Session Service over TCP
18
+ UDP_PORT = 138
19
+
20
+ # Datagram packet types
21
+ TYPES = {
22
+ 'direct_unique' => 0x10,
23
+ 'direct_group' => 0x11,
24
+ 'broadcast' => 0x12,
25
+ 'error' => 0x13,
26
+ 'query_request' => 0x14,
27
+ 'positive_query_resp' => 0x15,
28
+ 'negative_query_resp' => 0x16,
29
+ }.freeze
30
+
31
+ # @!attribute type
32
+ # 8-bit session packet type
33
+ # @return [Integer]
34
+ define_field :type, Types::Int8Enum, enum: TYPES
35
+ # @!attribute flags
36
+ # 8-bit flags
37
+ # @return [Integer]
38
+ define_field :flags, Types::Int8
39
+ # @!attribute dgm_id
40
+ # 16-bit next transaction ID for datagrams
41
+ # @return [Integer]
42
+ define_field :dgm_id, Types::Int16
43
+ # @!attribute src_ip
44
+ # Source IP address
45
+ # @return [IP::Addr]
46
+ define_field :src_ip, IP::Addr
47
+ # @!attribute src_port
48
+ # Source port
49
+ # @return [IP::Addr]
50
+ define_field :src_port, Types::Int16
51
+ # @!attribute dgm_length
52
+ # Length of data + second level of encoded names. Not present in error datagram.
53
+ # @return [Integer]
54
+ define_field :dgm_length, Types::Int16, optional: ->(h) { h.type != 0x13 }
55
+ # @!attribute packet_offset
56
+ # Not present in error datagram.
57
+ # @return [Integer]
58
+ define_field :packet_offset, Types::Int16, optional: ->(h) { h.type != 0x13 }
59
+ # @!attribute error_code
60
+ # Error code. Only present in error datagrams.
61
+ # @return [Integer]
62
+ define_field :error_code, Types::Int16, optional: ->(h) { h.type == 0x13 }
63
+ # @!attribute src_name
64
+ # NetBIOS source name. Only present in direct_unique, direct_group and broadcast datagrams.
65
+ # @return []
66
+ define_field :src_name, Name, default: '', optional: ->(h) { (h.type >= 0x10) && (h.type <= 0x12) }
67
+ # @!attribute dst_name
68
+ # NetBIOS destination name. Present in all but error datagrams.
69
+ # @return []
70
+ define_field :dst_name, Name, default: '', optional: ->(h) { h.type != 0x13 }
71
+ # @!attribute body
72
+ # User data. Ony present in direct_unique, direct_group and broadcast datagrams.
73
+ # @return [String]
74
+ define_field :body, Types::String, optional: ->(h) { (h.type >= 0x10) && (h.type <= 0x12) }
75
+
76
+ # @!attribute :rsv
77
+ # 4-bit rsv field. 4 upper bits of {#flags}
78
+ # @return [Integer]
79
+ # @!attribute :snt
80
+ # 2-bit SNT (Source end-Node Type) field from {#flags}.
81
+ # @return [Integer]
82
+ # @!attribute f
83
+ # First packet flag. If set then this is first
84
+ # (and possibly only) fragment of NetBIOS datagram.
85
+ # @return [Boolean]
86
+ # @!attribute m
87
+ # More flag. If set then more NetBIOS datagram
88
+ # fragments follow.
89
+ # @return [Boolean]
90
+ define_bit_fields_on :flags, :rsv, 4, :snt, 2, :f, :m
91
+
92
+ # Compute and set {#dgm_length} field
93
+ # @return [Integer] calculated length
94
+ def calc_length
95
+ length = self[:body].sz
96
+ length += self[:src_name].sz if is_present?(:src_name)
97
+ length += self[:dst_name].sz if is_present?(:dst_name)
98
+ self.dgm_length = length
99
+ end
100
+ end
101
+ Header.add_class Datagram
102
+ UDP.bind Datagram, dport: Datagram::UDP_PORT, sport: Datagram::UDP_PORT
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,67 @@
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
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+ # Module to group all NetBIOS headers
11
+ # @author Sylvain Daubert
12
+ # @since 2.5.1
13
+ module NetBIOS
14
+ # NetBIOS Name.
15
+ # @author Sylvain Daubert
16
+ class Name < DNS::Name
17
+ # Size, in bytes, of an encoded NetBIOS name
18
+ ENCODED_NAME_SIZE = 32
19
+
20
+ # Read a NetBIOS name from a string
21
+ # @param [String] str
22
+ # @return [Name] self
23
+ def from_human(str)
24
+ clear
25
+ return self if str.nil?
26
+ encoded_name = encode_name(str)
27
+
28
+ super(encoded_name)
29
+ end
30
+
31
+ # Get a human readable string
32
+ # @return [String]
33
+ def to_human
34
+ encoded_name = super
35
+ decode_name(encoded_name)
36
+ end
37
+
38
+ private
39
+
40
+ def encode_name(name)
41
+ basename, *scope_id = name.split('.')
42
+ basename = '' if basename.nil?
43
+ scope_id = scope_id.join('.')
44
+ encoded_name = +''
45
+ basename.each_byte do |byte|
46
+ a = (byte >> 4) + 0x41
47
+ b = (byte & 0xf) + 0x41
48
+ encoded_name << [a, b].pack('C2')
49
+ end
50
+ encoded_name << 'CA' * ((ENCODED_NAME_SIZE - encoded_name.size) / 2) if encoded_name.size < ENCODED_NAME_SIZE
51
+ encoded_name << ".#{scope_id}" if scope_id
52
+ encoded_name
53
+ end
54
+
55
+ def decode_name(encoded_name)
56
+ name = +''
57
+ encoded_name.partition('.').first.scan(/../).map do |duo|
58
+ a = (duo[0].ord - 0x41) & 0xf
59
+ b = (duo[1].ord - 0x41) & 0xf
60
+ name << (a << 4 | b).chr
61
+ end
62
+ name.strip
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,64 @@
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
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+ # Module to group all NetBIOS headers
11
+ # @author Sylvain Daubert
12
+ # @since 2.5.1
13
+ module NetBIOS
14
+ # NetBIOS Session Service messages.
15
+ # @author Sylvain Daubert
16
+ class Session < Base
17
+ # Port number for NetBIOS Session Service over TCP
18
+ TCP_PORT = 139
19
+
20
+ # Session packet types
21
+ TYPES = {
22
+ 'message' => 0,
23
+ 'request' => 0x81,
24
+ 'positive_response' => 0x82,
25
+ 'negative_response' => 0x83,
26
+ 'retarget_response' => 0x84,
27
+ 'keep_alive' => 0x85,
28
+ }.freeze
29
+
30
+ # @!attribute type
31
+ # 8-bit session packet type
32
+ # @return [Integer]
33
+ define_field :type, Types::Int8Enum, enum: TYPES
34
+ # @!attribute length
35
+ # 17-bit session packet length
36
+ # @return [Integer]
37
+ define_field :length, Types::Int24
38
+ # @!attribute body
39
+ # @return [String]
40
+ define_field :body, Types::String
41
+
42
+ # Compute and set {#length} field
43
+ # @return [Integer] calculated length
44
+ def calc_length
45
+ Base.calculate_and_set_length(self, header_in_size: false)
46
+ end
47
+
48
+ # @api private
49
+ # @note This method is used internally by PacketGen and should not be
50
+ # directly called
51
+ # @since 2.7.0 Set TCP sport according to bindings, only if sport is 0.
52
+ # Needed by new bind API.
53
+ def added_to_packet(packet)
54
+ return unless packet.is? 'TCP'
55
+ return unless packet.tcp.sport.zero?
56
+ packet.tcp.sport = TCP_PORT
57
+ end
58
+ end
59
+ Header.add_class Session
60
+ TCP.bind Session, dport: Session::TCP_PORT
61
+ TCP.bind Session, sport: Session::TCP_PORT
62
+ end
63
+ end
64
+ end
@@ -8,12 +8,6 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
11
- # Array of 32-bit words.
12
- # @author Sylvain Daubert
13
- class ArrayOfInt32 < Types::Array
14
- set_of Types::Int32
15
- end
16
-
17
11
  # This class handles IPv6 prefixes, as defined in RFC 5340 §A.4.1.
18
12
  # A IPv6 prefix consists of:
19
13
  # * a 8-bit {#length} field (length of the prefix, in bits),
@@ -39,7 +33,7 @@ module PacketGen
39
33
  # @!attribute prefix
40
34
  # IPv6 Prefix as an array of 32-bit words
41
35
  # @return [Prefix]
42
- define_field :prefix, ArrayOfInt32
36
+ define_field :prefix, Types::ArrayOfInt32
43
37
 
44
38
  # @!attribute dn_opt
45
39
  # This bit controls an inter-area-prefix-LSAs or AS-external-LSAs
@@ -210,5 +210,26 @@ module PacketGen
210
210
  end
211
211
  end
212
212
  end
213
+
214
+ # Specialized array to handle serie of {Int8}.
215
+ class ArrayOfInt8 < Array
216
+ set_of Int8
217
+ end
218
+ # Specialized array to handle serie of {Int16}.
219
+ class ArrayOfInt16 < Array
220
+ set_of Int16
221
+ end
222
+ # Specialized array to handle serie of {Int16le}.
223
+ class ArrayOfInt16le < Array
224
+ set_of Int16le
225
+ end
226
+ # Specialized array to handle serie of {Int32}.
227
+ class ArrayOfInt32 < Types::Array
228
+ set_of Types::Int32
229
+ end
230
+ # Specialized array to handle serie of {Int32le}.
231
+ class ArrayOfInt32le < Types::Array
232
+ set_of Types::Int32le
233
+ end
213
234
  end
214
235
  end
@@ -35,13 +35,13 @@ module PacketGen
35
35
  if @static_length.is_a? Integer
36
36
  if self.size >= @static_length
37
37
  s = self[0, @static_length]
38
- s[-1] = 0.chr
38
+ s[-1] = "\x00".encode(s.encoding)
39
39
  PacketGen.force_binary s
40
40
  else
41
41
  PacketGen.force_binary(self + "\0" * (@static_length - self.length))
42
42
  end
43
43
  else
44
- PacketGen.force_binary(self + 0.chr)
44
+ PacketGen.force_binary(self + +"\x00".encode(self.encoding))
45
45
  end
46
46
  end
47
47
 
@@ -56,7 +56,7 @@ module PacketGen
56
56
 
57
57
  # @return [String]
58
58
  def to_human
59
- idx = self.index(0.chr) || self.sz
59
+ idx = self.index(+"\x00".encode(self.encoding)) || self.sz
60
60
  self[0, idx]
61
61
  end
62
62
  end
@@ -70,11 +70,13 @@ module PacketGen
70
70
  # # object will have a different value.
71
71
  # define_field :id, PacketGen::Types::Int16, default: ->{ rand(65535) }
72
72
  # # a size field
73
- # define_field :body_size, PacketGen::Type::Int16
73
+ # define_field :body_size, PacketGen::Types::Int16
74
74
  # # String field which length is taken from body_size field
75
- # define_field :body, PacketGen::Type::String, builder: ->(obj, type) { type.new('', length_from: obj[:body_size]) }
75
+ # define_field :body, PacketGen::Types::String, builder: ->(obj, type) { type.new('', length_from: obj[:body_size]) }
76
76
  # # 16-bit enumeration type. As :default not specified, default to first value of enum
77
- # define_field :type_class, PacketGen::Type::Int16Enum, enum: { 'class1' => 1, 'class2' => 2}
77
+ # define_field :type_class, PacketGen::Types::Int16Enum, enum: { 'class1' => 1, 'class2' => 2}
78
+ # # optional field. Only present if another field has a certain value
79
+ # define_field :opt1, PacketGen::Types::Int16, optional: ->(h) { h.type == 42 }
78
80
  #
79
81
  # {.define_field_before} and {.define_field_after} are also defined to relatively
80
82
  # create a field from anoher one (for example, when adding a field in a subclass).
@@ -452,6 +454,20 @@ module PacketGen
452
454
  PacketGen.force_binary(str)
453
455
  end
454
456
 
457
+ # Get offset of given field in {Fields} structure.
458
+ # @param [Symbol] field
459
+ # @return [Integer]
460
+ # @raise [ArgumentError] unknown field
461
+ def offset_of(field)
462
+ raise ArgumentError, "#{field} is an unknown field of #{self.class}" unless @fields.include?(field)
463
+ offset = 0
464
+ fields.each do |f|
465
+ break offset if f == field
466
+ next unless is_present?(f)
467
+ offset += self[f].sz
468
+ end
469
+ end
470
+
455
471
  private
456
472
 
457
473
  # Deeply duplicate +@fields+
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '2.7.0'
13
+ VERSION = '2.8.0'
14
14
  end
data/packetgen.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.required_ruby_version = '>= 2.2.0'
25
+ spec.required_ruby_version = '>= 2.3.0'
26
26
 
27
27
  spec.add_dependency 'interfacez', '~>1.0'
28
28
  spec.add_dependency 'pcaprub', '~>0.12.4'
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: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-29 00:00:00.000000000 Z
11
+ date: 2018-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez
@@ -227,6 +227,9 @@ files:
227
227
  - lib/packetgen/header/mldv2/mlq.rb
228
228
  - lib/packetgen/header/mldv2/mlr.rb
229
229
  - lib/packetgen/header/netbios.rb
230
+ - lib/packetgen/header/netbios/datagram.rb
231
+ - lib/packetgen/header/netbios/name.rb
232
+ - lib/packetgen/header/netbios/session.rb
230
233
  - lib/packetgen/header/ospfv2.rb
231
234
  - lib/packetgen/header/ospfv2/db_description.rb
232
235
  - lib/packetgen/header/ospfv2/hello.rb
@@ -287,7 +290,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
287
290
  requirements:
288
291
  - - ">="
289
292
  - !ruby/object:Gem::Version
290
- version: 2.2.0
293
+ version: 2.3.0
291
294
  required_rubygems_version: !ruby/object:Gem::Requirement
292
295
  requirements:
293
296
  - - ">="