packetgen 3.1.3 → 3.1.4

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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/lib/packetgen.rb +24 -2
  3. data/lib/packetgen/capture.rb +30 -24
  4. data/lib/packetgen/config.rb +2 -2
  5. data/lib/packetgen/deprecation.rb +33 -7
  6. data/lib/packetgen/header.rb +2 -9
  7. data/lib/packetgen/header/arp.rb +2 -2
  8. data/lib/packetgen/header/asn1_base.rb +2 -2
  9. data/lib/packetgen/header/base.rb +2 -4
  10. data/lib/packetgen/header/bootp.rb +3 -3
  11. data/lib/packetgen/header/dhcp.rb +2 -2
  12. data/lib/packetgen/header/dhcp/option.rb +2 -2
  13. data/lib/packetgen/header/dhcp/options.rb +2 -2
  14. data/lib/packetgen/header/dhcpv6.rb +12 -12
  15. data/lib/packetgen/header/dhcpv6/duid.rb +8 -4
  16. data/lib/packetgen/header/dhcpv6/option.rb +4 -4
  17. data/lib/packetgen/header/dhcpv6/options.rb +2 -2
  18. data/lib/packetgen/header/dhcpv6/relay.rb +2 -2
  19. data/lib/packetgen/header/dns.rb +9 -9
  20. data/lib/packetgen/header/dns/name.rb +2 -2
  21. data/lib/packetgen/header/dns/opt.rb +2 -2
  22. data/lib/packetgen/header/dns/option.rb +2 -2
  23. data/lib/packetgen/header/dns/qdsection.rb +2 -2
  24. data/lib/packetgen/header/dns/question.rb +35 -35
  25. data/lib/packetgen/header/dns/rr.rb +3 -3
  26. data/lib/packetgen/header/dns/rrsection.rb +2 -2
  27. data/lib/packetgen/header/dot11.rb +5 -13
  28. data/lib/packetgen/header/dot11/control.rb +5 -5
  29. data/lib/packetgen/header/dot11/data.rb +2 -2
  30. data/lib/packetgen/header/dot11/element.rb +16 -16
  31. data/lib/packetgen/header/dot11/management.rb +2 -2
  32. data/lib/packetgen/header/dot11/sub_mngt.rb +2 -12
  33. data/lib/packetgen/header/dot1q.rb +2 -2
  34. data/lib/packetgen/header/dot1x.rb +6 -6
  35. data/lib/packetgen/header/eap.rb +16 -16
  36. data/lib/packetgen/header/eap/fast.rb +2 -2
  37. data/lib/packetgen/header/eap/md5.rb +2 -2
  38. data/lib/packetgen/header/eap/tls.rb +2 -2
  39. data/lib/packetgen/header/eap/ttls.rb +2 -2
  40. data/lib/packetgen/header/eth.rb +8 -5
  41. data/lib/packetgen/header/gre.rb +2 -2
  42. data/lib/packetgen/header/http.rb +2 -0
  43. data/lib/packetgen/header/http/headers.rb +2 -2
  44. data/lib/packetgen/header/http/request.rb +5 -5
  45. data/lib/packetgen/header/http/response.rb +6 -6
  46. data/lib/packetgen/header/http/verbs.rb +2 -2
  47. data/lib/packetgen/header/icmp.rb +2 -2
  48. data/lib/packetgen/header/icmpv6.rb +2 -2
  49. data/lib/packetgen/header/igmp.rb +4 -4
  50. data/lib/packetgen/header/igmpv3.rb +3 -3
  51. data/lib/packetgen/header/igmpv3/group_record.rb +6 -6
  52. data/lib/packetgen/header/igmpv3/mq.rb +2 -2
  53. data/lib/packetgen/header/igmpv3/mr.rb +2 -2
  54. data/lib/packetgen/header/ip.rb +3 -5
  55. data/lib/packetgen/header/ip/addr.rb +7 -2
  56. data/lib/packetgen/header/ip/option.rb +4 -6
  57. data/lib/packetgen/header/ip/options.rb +3 -5
  58. data/lib/packetgen/header/ipv6.rb +2 -2
  59. data/lib/packetgen/header/ipv6/addr.rb +7 -2
  60. data/lib/packetgen/header/ipv6/extension.rb +2 -2
  61. data/lib/packetgen/header/ipv6/hop_by_hop.rb +3 -3
  62. data/lib/packetgen/header/llc.rb +2 -2
  63. data/lib/packetgen/header/mdns.rb +2 -2
  64. data/lib/packetgen/header/mld.rb +2 -2
  65. data/lib/packetgen/header/mldv2.rb +2 -2
  66. data/lib/packetgen/header/mldv2/mcast_address_record.rb +2 -2
  67. data/lib/packetgen/header/mldv2/mlq.rb +2 -2
  68. data/lib/packetgen/header/mldv2/mlr.rb +2 -2
  69. data/lib/packetgen/header/ospfv2.rb +9 -9
  70. data/lib/packetgen/header/ospfv2/db_description.rb +2 -2
  71. data/lib/packetgen/header/ospfv2/hello.rb +2 -2
  72. data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -2
  73. data/lib/packetgen/header/ospfv2/ls_request.rb +2 -2
  74. data/lib/packetgen/header/ospfv2/ls_update.rb +2 -2
  75. data/lib/packetgen/header/ospfv2/lsa.rb +3 -5
  76. data/lib/packetgen/header/ospfv2/lsa_header.rb +6 -6
  77. data/lib/packetgen/header/ospfv3.rb +2 -2
  78. data/lib/packetgen/header/ospfv3/db_description.rb +2 -2
  79. data/lib/packetgen/header/ospfv3/hello.rb +2 -2
  80. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +2 -2
  81. data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
  82. data/lib/packetgen/header/ospfv3/ls_request.rb +2 -2
  83. data/lib/packetgen/header/ospfv3/ls_update.rb +2 -2
  84. data/lib/packetgen/header/ospfv3/lsa.rb +3 -5
  85. data/lib/packetgen/header/ospfv3/lsa_header.rb +7 -7
  86. data/lib/packetgen/header/snmp.rb +31 -28
  87. data/lib/packetgen/header/tcp.rb +3 -3
  88. data/lib/packetgen/header/tcp/option.rb +3 -5
  89. data/lib/packetgen/header/tcp/options.rb +2 -2
  90. data/lib/packetgen/header/tftp.rb +6 -6
  91. data/lib/packetgen/header/udp.rb +3 -3
  92. data/lib/packetgen/headerable.rb +5 -4
  93. data/lib/packetgen/inject.rb +23 -0
  94. data/lib/packetgen/inspect.rb +24 -5
  95. data/lib/packetgen/packet.rb +76 -51
  96. data/lib/packetgen/pcap.rb +29 -0
  97. data/lib/packetgen/pcapng.rb +2 -2
  98. data/lib/packetgen/pcapng/block.rb +12 -12
  99. data/lib/packetgen/pcapng/epb.rb +3 -7
  100. data/lib/packetgen/pcapng/file.rb +134 -95
  101. data/lib/packetgen/pcapng/idb.rb +30 -30
  102. data/lib/packetgen/pcapng/shb.rb +25 -34
  103. data/lib/packetgen/pcapng/spb.rb +4 -8
  104. data/lib/packetgen/pcapng/unknown_block.rb +2 -2
  105. data/lib/packetgen/pcaprub_wrapper.rb +67 -0
  106. data/lib/packetgen/proto.rb +2 -2
  107. data/lib/packetgen/types.rb +2 -0
  108. data/lib/packetgen/types/abstract_tlv.rb +24 -6
  109. data/lib/packetgen/types/array.rb +5 -5
  110. data/lib/packetgen/types/cstring.rb +2 -2
  111. data/lib/packetgen/types/enum.rb +3 -2
  112. data/lib/packetgen/types/fields.rb +5 -7
  113. data/lib/packetgen/types/int.rb +3 -5
  114. data/lib/packetgen/types/int_string.rb +2 -2
  115. data/lib/packetgen/types/length_from.rb +3 -3
  116. data/lib/packetgen/types/oui.rb +2 -2
  117. data/lib/packetgen/types/string.rb +2 -2
  118. data/lib/packetgen/types/tlv.rb +2 -2
  119. data/lib/packetgen/utils.rb +2 -2
  120. data/lib/packetgen/utils/arp_spoofer.rb +2 -2
  121. data/lib/packetgen/version.rb +3 -3
  122. metadata +26 -50
  123. data/.gitignore +0 -13
  124. data/.rubocop.yml +0 -30
  125. data/.travis.yml +0 -19
  126. data/Gemfile +0 -4
  127. data/Rakefile +0 -21
  128. data/packetgen.gemspec +0 -36
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -197,9 +197,7 @@ module PacketGen
197
197
  private
198
198
 
199
199
  def record_from_hash(hsh)
200
- unless hsh.key? :type
201
- raise ArgumentError, 'hash should have :type key'
202
- end
200
+ raise ArgumentError, 'hash should have :type key' unless hsh.key? :type
203
201
 
204
202
  klass = if @only_headers
205
203
  LSAHeader
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class OSPFv3
@@ -31,13 +31,13 @@ module PacketGen
31
31
  class LSAHeader < Types::Fields
32
32
  # LSA known types
33
33
  TYPES = {
34
- 'Router' => 0x2001,
35
- 'Network' => 0x2002,
34
+ 'Router' => 0x2001,
35
+ 'Network' => 0x2002,
36
36
  'Inter-Area-Prefix' => 0x2003,
37
37
  'Inter-Area-Router' => 0x2004,
38
- 'AS-External' => 0x4005,
39
- 'NSSA' => 0x2007,
40
- 'Link' => 0x0008,
38
+ 'AS-External' => 0x4005,
39
+ 'NSSA' => 0x2007,
40
+ 'Link' => 0x0008,
41
41
  'Intra-Area-Prefix' => 0x2009
42
42
  }.freeze
43
43
 
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
3
+
2
4
  # This file is part of PacketGen
3
5
  # See https://github.com/sdaubert/packetgen for more informations
4
6
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
7
  # This program is published under MIT license.
6
8
 
7
- # frozen_string_literal: true
8
-
9
9
  module PacketGen
10
10
  module Header
11
11
  # Dissect error
@@ -22,6 +22,8 @@ module PacketGen
22
22
  # Configuration sinks listen to this port
23
23
  UDP_PORT2 = 162
24
24
 
25
+ # rubocop:disable Naming/ConstantName
26
+
25
27
  PDU_GET = 0
26
28
  PDU_NEXT = 1
27
29
  PDU_RESPONSE = 2
@@ -31,27 +33,28 @@ module PacketGen
31
33
  PDU_INFORM = 6
32
34
  PDU_TRAPv2 = 7
33
35
  PDU_REPORT = 8
36
+ # rubocop:enable Naming/ConstantName
34
37
 
35
38
  ERRORS = {
36
- 'no_error' => 0,
37
- 'too_big' => 1,
38
- 'no_such_name' => 2,
39
- 'bad_value' => 3,
40
- 'read_only' => 4,
41
- 'generic_error' => 5,
42
- 'no_access' => 6,
43
- 'wrong_type' => 7,
44
- 'wrong_length' => 8,
45
- 'wrong_encoding' => 9,
46
- 'wrong_value' => 10,
47
- 'no_creation' => 11,
48
- 'inconsistent_value' => 12,
39
+ 'no_error' => 0,
40
+ 'too_big' => 1,
41
+ 'no_such_name' => 2,
42
+ 'bad_value' => 3,
43
+ 'read_only' => 4,
44
+ 'generic_error' => 5,
45
+ 'no_access' => 6,
46
+ 'wrong_type' => 7,
47
+ 'wrong_length' => 8,
48
+ 'wrong_encoding' => 9,
49
+ 'wrong_value' => 10,
50
+ 'no_creation' => 11,
51
+ 'inconsistent_value' => 12,
49
52
  'ressource_unavailable' => 13,
50
- 'commit_failed' => 14,
51
- 'undo_failed' => 15,
52
- 'authorization_error' => 16,
53
- 'not_writable' => 17,
54
- 'inconsistent_name' => 18
53
+ 'commit_failed' => 14,
54
+ 'undo_failed' => 15,
55
+ 'authorization_error' => 16,
56
+ 'not_writable' => 17,
57
+ 'inconsistent_name' => 18
55
58
  }.freeze
56
59
 
57
60
  # Class to handle SNMP VarBind
@@ -162,13 +165,13 @@ module PacketGen
162
165
  implicit: SNMP::PDU_TRAPv1, constructed: true,
163
166
  content: [objectid(:enterprise),
164
167
  octet_string(:agent_addr),
165
- integer(:generic_trap, enum: { 'cold_start' => 0,
166
- 'warm_start' => 1,
167
- 'link_down' => 2,
168
- 'link_up' => 3,
169
- 'auth_failure' => 4,
168
+ integer(:generic_trap, enum: { 'cold_start' => 0,
169
+ 'warm_start' => 1,
170
+ 'link_down' => 2,
171
+ 'link_up' => 3,
172
+ 'auth_failure' => 4,
170
173
  'egp_neighbor_loss' => 5,
171
- 'specific' => 6 }),
174
+ 'specific' => 6 }),
172
175
  integer(:specific_trap),
173
176
  integer(:timestamp),
174
177
  model(:varbindlist, VariableBindings)]
@@ -291,8 +294,8 @@ module PacketGen
291
294
  str << data.chosen_value.inspect(1)
292
295
  begin
293
296
  str << Inspect.inspect_body(self[:message].to_der, 'ASN.1 DER')
294
- rescue StandardError => ex
295
- raise unless ex.message =~ /TAG.*not handled/
297
+ rescue StandardError => e
298
+ raise unless e.message =~ /TAG.*not handled/
296
299
  end
297
300
  str
298
301
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  # TCP header ({https://tools.ietf.org/html/rfc793 RFC 793})
@@ -235,7 +235,7 @@ module PacketGen
235
235
  doff = Inspect.int_dec_hex(data_offset, 1)
236
236
  str << shift << Inspect::FMT_ATTR % ['', 'data_offset', doff]
237
237
  str << shift << Inspect::FMT_ATTR % ['', 'reserved', reserved]
238
- flags = ''.dup
238
+ flags = +''
239
239
  %w[ns cwr ece urg ack psh rst syn fin].each do |fl|
240
240
  flags << (send("flag_#{fl}?") ? fl[0].upcase : '.')
241
241
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  class TCP
@@ -113,9 +113,7 @@ module PacketGen
113
113
  # @return [String]
114
114
  def to_human
115
115
  str = self.class == Option ? +"unk-#{kind}" : self.class.to_s.sub(/.*::/, '')
116
- if (length > 2) && !self[:value].to_s.empty?
117
- str << ":#{self[:value].to_s.inspect}"
118
- end
116
+ str << ":#{self[:value].to_s.inspect}" if (length > 2) && !self[:value].to_s.empty?
119
117
  str
120
118
  end
121
119
 
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  require_relative 'option'
9
9
 
10
10
  module PacketGen
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  # A TFTP (Trivial File Transfer Protocol,
@@ -49,10 +49,10 @@ module PacketGen
49
49
  class TFTP < Base
50
50
  # Known opcodes
51
51
  OPCODES = {
52
- 'RRQ' => 1,
53
- 'WRQ' => 2,
54
- 'DATA' => 3,
55
- 'ACK' => 4,
52
+ 'RRQ' => 1,
53
+ 'WRQ' => 2,
54
+ 'DATA' => 3,
55
+ 'ACK' => 4,
56
56
  'Error' => 5
57
57
  }.freeze
58
58
 
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  module Header
10
10
  # UDP header ({https://tools.ietf.org/html/rfc768 RFC 768})
@@ -71,7 +71,7 @@ module PacketGen
71
71
  # option is set.
72
72
  def initialize(options={})
73
73
  super
74
- self.length += self[:body].sz if self[:body].sz > 0
74
+ self.length += self[:body].sz if self[:body].sz.positive?
75
75
  end
76
76
 
77
77
  # Compute checksum and set +checksum+ field
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  # This mixin module defines minimal API for a class to act as a header
10
10
  # in {Packet}.
@@ -85,9 +85,10 @@ module PacketGen
85
85
  # @return [self]
86
86
  # @raise [NotImplementedError]
87
87
  def read(str)
88
+ # Do not call super and rescue NoMethodError: too slow
89
+ raise NotImplementedError, "#{self.class} should implement #read" if method(:read).super_method.nil?
90
+
88
91
  super
89
- rescue NoMethodError
90
- raise NotImplementedError, "#{self.class} should implement #read"
91
92
  end
92
93
  end
93
94
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of PacketGen
4
+ # See https://github.com/sdaubert/packetgen for more informations
5
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
6
+ # This program is published under MIT license.
7
+ require_relative 'pcaprub_wrapper'
8
+
9
+ module PacketGen
10
+ # Module to inject packets on wire
11
+ # @author Sylvain Daubert
12
+ # @api private
13
+ # @since 3.1.4
14
+ module Inject
15
+ # Inject given data onto wire
16
+ # @param [String] iface interface name
17
+ # @param [String,Packet,Header::Base] data to inject
18
+ # @return [void]
19
+ def self.inject(iface:, data:)
20
+ PCAPRUBWrapper.inject(iface: iface, data: data.to_s)
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of PacketGen
2
4
  # See https://github.com/sdaubert/packetgen for more informations
3
5
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
6
  # This program is published under MIT license.
5
7
 
6
- # frozen_string_literal: true
7
-
8
8
  module PacketGen
9
9
  # {Inspect} module provides methods to help writing +inspect+
10
10
  # @api private
@@ -37,6 +37,25 @@ module PacketGen
37
37
  "%-16s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
38
38
  end
39
39
 
40
+ # @param [String] str
41
+ # @param [Integer] int
42
+ # @param [Integer] hexsize
43
+ # @return [String]
44
+ def self.enum_human_hex(str, int, hexsize)
45
+ "%-16s (0x%0#{hexsize}x)" % [str, int]
46
+ end
47
+
48
+ # Simple formatter to inspect an attribute
49
+ # @param [String] type attribute type
50
+ # @param [String] attr attribute name
51
+ # @param [String] value
52
+ # @param [Integer] level
53
+ # @return [String]
54
+ def self.format(type, attr, value, level=1)
55
+ str = Inspect.shift_level(level)
56
+ str << Inspect::FMT_ATTR % [type, attr, value]
57
+ end
58
+
40
59
  # Format an attribute for +#inspect+.
41
60
  # 3 cases are handled:
42
61
  # * attribute value is a {Types::Int}: show value as integer and in
@@ -48,10 +67,10 @@ module PacketGen
48
67
  # @param [Integer] level
49
68
  # @return [String]
50
69
  def self.inspect_attribute(attr, value, level=1)
51
- str = shift_level(level)
70
+ type = value.class.to_s.sub(/.*::/, '')
52
71
  val = case value
53
72
  when Types::Enum
54
- "%-16s (0x%0#{value.sz * 2}x)" % [value.to_human, value.to_i]
73
+ enum_human_hex(value.to_human, value.to_i, value.sz * 2)
55
74
  when Types::Int
56
75
  int_dec_hex(value, value.sz * 2)
57
76
  when Integer
@@ -65,7 +84,7 @@ module PacketGen
65
84
  value.to_s.inspect
66
85
  end
67
86
  end
68
- str << FMT_ATTR % [value.class.to_s.sub(/.*::/, ''), attr, val]
87
+ self.format(type, attr, val, level)
69
88
  end
70
89
 
71
90
  # Format a ASN.1 attribute for +#inspect+.
@@ -1,13 +1,11 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
3
+
2
4
  # This file is part of PacketGen
3
5
  # See https://github.com/sdaubert/packetgen for more informations
4
6
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
7
  # This program is published under MIT license.
6
8
 
7
- # frozen_string_literal: true
8
-
9
- require 'pcaprub'
10
-
11
9
  module PacketGen
12
10
  # An object of type {Packet} handles a network packet. This packet may contain
13
11
  # multiple protocol headers, starting from MAC layer or from Network (OSI) layer.
@@ -89,26 +87,21 @@ module PacketGen
89
87
  capture.packets
90
88
  end
91
89
 
92
- # Read packets from +filename+. Mays read Pcap and Pcap-NG formats.
90
+ # Read packets from +filename+. May read Pcap and Pcap-NG formats.
93
91
  #
94
- # For more control, see {PcapNG::File} or +PCAPRUB::Pcap+.
92
+ # For more control (on Pcap-ng only), see {PcapNG::File}.
95
93
  # @param [String] filename PcapNG or Pcap file.
96
94
  # @return [Array<Packet>]
95
+ # @raise [ArgumentError] unknown file format
97
96
  # @author Sylvain Daubert
98
97
  # @author Kent Gruber - Pcap format
99
98
  # @since 2.0.0 Also read Pcap format.
100
99
  def self.read(filename)
101
- PcapNG::File.new.read_packets filename
100
+ PcapNG::File.new.read_packets(filename)
102
101
  rescue StandardError => e
103
102
  raise ArgumentError, e unless File.extname(filename.downcase) == '.pcap'
104
103
 
105
- packets = []
106
- PCAPRUB::Pcap.open_offline(filename).each_packet do |packet|
107
- next unless (packet = PacketGen.parse(packet.to_s))
108
-
109
- packets << packet
110
- end
111
- packets
104
+ Pcap.read(filename)
112
105
  end
113
106
 
114
107
  # Write packets to +filename+
@@ -132,11 +125,13 @@ module PacketGen
132
125
  # @param [String] protocol
133
126
  # @param [Hash] options protocol specific options
134
127
  # @return [self]
135
- # @raise [ArgumentError] unknown protocol
128
+ # @raise [BindingError] unknown protocol
136
129
  def add(protocol, options={})
137
130
  klass = check_protocol(protocol)
138
131
 
139
- header = klass.new(options.merge!(packet: self))
132
+ # options[:packet]= self is speedier than options.merge(packet: self)
133
+ options[:packet] = self
134
+ header = klass.new(options)
140
135
  add_header header
141
136
  self
142
137
  end
@@ -146,12 +141,14 @@ module PacketGen
146
141
  # @param [String] protocol protocol to insert
147
142
  # @param [Hash] options protocol specific options
148
143
  # @return [self]
149
- # @raise [ArgumentError] unknown protocol
144
+ # @raise [BindingError] unknown protocol
150
145
  def insert(prev, protocol, options={})
151
146
  klass = check_protocol(protocol)
152
147
 
153
148
  nxt = prev.body
154
- header = klass.new(options.merge!(packet: self))
149
+ # options[:packet]= self is speedier than options.merge(packet: self)
150
+ options[:packet] = self
151
+ header = klass.new(options)
155
152
  add_header header, previous_header: prev
156
153
  idx = headers.index(prev) + 1
157
154
  headers[idx, 0] = header
@@ -217,7 +214,7 @@ module PacketGen
217
214
  # @return [Array] see return from {PcapNG::File#to_file}
218
215
  # @see File
219
216
  def to_f(filename)
220
- PcapNG::File.new.array_to_file(filename: filename, array: [self])
217
+ PcapNG::File.new.array_to_file(file: filename, array: [self])
221
218
  end
222
219
  alias write to_f
223
220
 
@@ -251,10 +248,11 @@ module PacketGen
251
248
  # from binding with first other's one. Use only when current header field
252
249
  # has its value set accordingly.
253
250
  # @return [self] +self+ with new headers from +other+
251
+ # @raise [BindingError] do not known how to encapsulate
254
252
  # @since 1.1.0
255
253
  def encapsulate(other, parsing: false)
256
254
  other.headers.each_with_index do |h, i|
257
- add_header h, parsing: (i > 0) || parsing
255
+ add_header h, parsing: i.positive? || parsing
258
256
  end
259
257
  end
260
258
 
@@ -262,36 +260,32 @@ module PacketGen
262
260
  # @param [Array<Header>] hdrs
263
261
  # @return [self] +self+ with some headers removed
264
262
  # @raise [FormatError] any headers not in +self+
265
- # @raise [FormatError] removed headers result in an unknown binding
263
+ # @raise [BindingError] removed headers result in an unknown binding
266
264
  # @since 1.1.0
267
265
  def decapsulate(*hdrs)
268
266
  hdrs.each do |hdr|
269
- idx = headers.index(hdr)
270
- raise FormatError, 'header not in packet!' if idx.nil?
271
-
272
- prev_hdr = idx > 0 ? headers[idx - 1] : nil
273
- next_hdr = (idx + 1) < headers.size ? headers[idx + 1] : nil
274
- headers.delete_at(idx)
267
+ prev_hdr = previous_header(hdr)
268
+ next_hdr = next_header(hdr)
269
+ headers.delete(hdr)
275
270
  add_header(next_hdr, previous_header: prev_hdr) if prev_hdr && next_hdr
276
271
  end
277
- rescue ArgumentError => ex
278
- raise FormatError, ex.message
272
+ rescue ArgumentError => e
273
+ raise FormatError, e.message
279
274
  end
280
275
 
281
276
  # Parse a binary string and populate Packet from it.
282
277
  # @param [String] binary_str
283
278
  # @param [String,nil] first_header First protocol header. +nil+ means discover it!
284
279
  # @return [Packet] self
285
- # @raise [ArgumentError] +first_header+ is an unknown header
280
+ # @raise [ParseError] +first_header+ is an unknown header
281
+ # @raise [BindingError] unknwon binding between some headers
286
282
  def parse(binary_str, first_header: nil)
287
283
  headers.clear
288
284
 
289
285
  if first_header.nil?
290
286
  # No decoding forced for first header. Have to guess it!
291
287
  first_header = guess_first_header(binary_str)
292
- if first_header.nil?
293
- raise ParseError, 'cannot identify first header in string'
294
- end
288
+ raise ParseError, 'cannot identify first header in string' if first_header.nil?
295
289
  end
296
290
 
297
291
  add first_header
@@ -374,6 +368,35 @@ module PacketGen
374
368
  headers.last
375
369
  end
376
370
 
371
+ # Give header index in packet
372
+ # @param [Headerable] hdr
373
+ # @return [Integer]
374
+ # @raise [FormatError] +hdr+ not in packet
375
+ def header_index(hdr)
376
+ idx = headers.index(hdr)
377
+ raise FormatError, 'header not in packet!' if idx.nil?
378
+
379
+ idx
380
+ end
381
+
382
+ # Give header previous +hdr+ in packet
383
+ # @param [Headerable] hdr
384
+ # @return [Headerable,nil] May return +nil+ if +hdr+ is the first header in packet
385
+ # @raise [FormatError] +hdr+ not in packet
386
+ def previous_header(hdr)
387
+ idx = header_index(hdr)
388
+ idx.positive? ? headers[idx - 1] : nil
389
+ end
390
+
391
+ # Give header next +hdr+ in packet
392
+ # @param [Headerable] hdr
393
+ # @return [Headerable,nil] May return +nil+ if +hdr+ is the last header in packet
394
+ # @raise [FormatError] +hdr+ not in packet
395
+ def next_header(hdr)
396
+ idx = header_index(hdr)
397
+ (idx + 1) < headers.size ? headers[idx + 1] : nil
398
+ end
399
+
377
400
  # @overload header(klass, layer=1)
378
401
  # @param [Class] klass
379
402
  # @param [Integer] layer
@@ -388,9 +411,8 @@ module PacketGen
388
411
  return header unless arg.is_a? Hash
389
412
 
390
413
  arg.each do |key, value|
391
- unless header.respond_to? "#{key}="
392
- raise ArgumentError, "unknown #{key} attribute for #{klass}"
393
- end
414
+ raise ArgumentError, "unknown #{key} attribute for #{klass}" unless header.respond_to? "#{key}="
415
+
394
416
  header.send "#{key}=", value
395
417
  end
396
418
 
@@ -408,26 +430,15 @@ module PacketGen
408
430
  end
409
431
 
410
432
  # Add a header to packet
411
- # @param [Header::Base] header
412
- # @param [Header::Base] previous_header
433
+ # @param [Headerable] header
434
+ # @param [Headerable] previous_header
413
435
  # @param [Boolean] parsing
414
436
  # @return [void]
437
+ # @raise [BindingError]
415
438
  def add_header(header, previous_header: nil, parsing: false)
416
439
  prev_header = previous_header || last_header
417
- if prev_header
418
- bindings = prev_header.class.known_headers[header.class]
419
- bindings = prev_header.class.known_headers[header.class.superclass] if bindings.nil?
420
- if bindings.nil?
421
- msg = "#{prev_header.class} knowns no layer association with #{header.protocol_name}. ".dup
422
- msg << "Try #{prev_header.class}.bind_layer(#{header.class}, "
423
- msg << "#{prev_header.method_name}_proto_field: "
424
- msg << "value_for_#{header.method_name})"
425
- raise ArgumentError, msg
426
- end
440
+ add_to_previous_header(prev_header, header, parsing) if prev_header
427
441
 
428
- bindings.set(prev_header) if !bindings.empty? && !parsing
429
- prev_header[:body] = header
430
- end
431
442
  header.packet = self
432
443
  headers << header unless previous_header
433
444
 
@@ -436,6 +447,20 @@ module PacketGen
436
447
  add_magic_header_method header
437
448
  end
438
449
 
450
+ # Bind +header+ to +prev_header+.
451
+ # @param [Headerable] prev_header
452
+ # @param [Headerable] header
453
+ # @param [Boolean] parsing
454
+ # @return [void]
455
+ # @raise [BindingError]
456
+ def add_to_previous_header(prev_header, header, parsing)
457
+ bindings = prev_header.class.known_headers[header.class] || prev_header.class.known_headers[header.class.superclass]
458
+ raise BindingError.new(prev_header, header) if bindings.nil?
459
+
460
+ bindings.set(prev_header) if !bindings.empty? && !parsing
461
+ prev_header[:body] = header
462
+ end
463
+
439
464
  # Add method to access +header+
440
465
  # @param [Header::Base] header
441
466
  # @return [void]