packetgen 4.0.0 → 4.1.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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/packetgen/deprecation.rb +7 -1
  4. data/lib/packetgen/header/arp.rb +6 -7
  5. data/lib/packetgen/header/asn1_base.rb +2 -1
  6. data/lib/packetgen/header/base.rb +27 -24
  7. data/lib/packetgen/header/bootp.rb +14 -14
  8. data/lib/packetgen/header/dhcp/option.rb +8 -8
  9. data/lib/packetgen/header/dhcp/options.rb +2 -2
  10. data/lib/packetgen/header/dhcp.rb +6 -7
  11. data/lib/packetgen/header/dhcpv6/duid.rb +1 -1
  12. data/lib/packetgen/header/dhcpv6/option.rb +37 -15
  13. data/lib/packetgen/header/dhcpv6/options.rb +3 -3
  14. data/lib/packetgen/header/dhcpv6/relay.rb +1 -0
  15. data/lib/packetgen/header/dhcpv6.rb +13 -14
  16. data/lib/packetgen/header/dns/name.rb +9 -8
  17. data/lib/packetgen/header/dns/opt.rb +3 -0
  18. data/lib/packetgen/header/dns/option.rb +7 -7
  19. data/lib/packetgen/header/dns/qdsection.rb +2 -2
  20. data/lib/packetgen/header/dns/question.rb +1 -0
  21. data/lib/packetgen/header/dns/rrsection.rb +2 -2
  22. data/lib/packetgen/header/dns.rb +76 -60
  23. data/lib/packetgen/header/dot11/control.rb +5 -5
  24. data/lib/packetgen/header/dot11/data.rb +11 -10
  25. data/lib/packetgen/header/dot11/element.rb +1 -1
  26. data/lib/packetgen/header/dot11/management.rb +18 -15
  27. data/lib/packetgen/header/dot11/sub_mngt.rb +22 -21
  28. data/lib/packetgen/header/dot11.rb +38 -38
  29. data/lib/packetgen/header/dot1q.rb +5 -4
  30. data/lib/packetgen/header/dot1x.rb +8 -8
  31. data/lib/packetgen/header/eap/fast.rb +3 -3
  32. data/lib/packetgen/header/eap/md5.rb +11 -3
  33. data/lib/packetgen/header/eap/tls.rb +9 -8
  34. data/lib/packetgen/header/eap/ttls.rb +13 -10
  35. data/lib/packetgen/header/eap.rb +58 -33
  36. data/lib/packetgen/header/eth.rb +26 -12
  37. data/lib/packetgen/header/gre.rb +26 -2
  38. data/lib/packetgen/header/http/headers.rb +6 -5
  39. data/lib/packetgen/header/http/request.rb +24 -16
  40. data/lib/packetgen/header/http/response.rb +22 -15
  41. data/lib/packetgen/header/icmp.rb +10 -10
  42. data/lib/packetgen/header/icmpv6.rb +10 -9
  43. data/lib/packetgen/header/igmp.rb +21 -10
  44. data/lib/packetgen/header/igmpv3/group_record.rb +7 -2
  45. data/lib/packetgen/header/igmpv3/mq.rb +1 -1
  46. data/lib/packetgen/header/igmpv3/mr.rb +1 -1
  47. data/lib/packetgen/header/igmpv3.rb +11 -10
  48. data/lib/packetgen/header/ip/addr.rb +6 -2
  49. data/lib/packetgen/header/ip/option.rb +18 -5
  50. data/lib/packetgen/header/ip.rb +52 -35
  51. data/lib/packetgen/header/ipv6/addr.rb +14 -13
  52. data/lib/packetgen/header/ipv6/extension.rb +9 -7
  53. data/lib/packetgen/header/ipv6/hop_by_hop.rb +26 -7
  54. data/lib/packetgen/header/ipv6.rb +31 -22
  55. data/lib/packetgen/header/llc.rb +20 -13
  56. data/lib/packetgen/header/mdns.rb +9 -2
  57. data/lib/packetgen/header/mld.rb +11 -9
  58. data/lib/packetgen/header/mldv2/mcast_address_record.rb +6 -1
  59. data/lib/packetgen/header/mldv2/mlq.rb +8 -8
  60. data/lib/packetgen/header/mldv2/mlr.rb +4 -4
  61. data/lib/packetgen/header/mldv2.rb +1 -1
  62. data/lib/packetgen/header/ospfv2/db_description.rb +10 -10
  63. data/lib/packetgen/header/ospfv2/hello.rb +11 -10
  64. data/lib/packetgen/header/ospfv2/ls_ack.rb +5 -6
  65. data/lib/packetgen/header/ospfv2/ls_request.rb +7 -6
  66. data/lib/packetgen/header/ospfv2/ls_update.rb +7 -7
  67. data/lib/packetgen/header/ospfv2/lsa.rb +33 -10
  68. data/lib/packetgen/header/ospfv2/lsa_header.rb +3 -2
  69. data/lib/packetgen/header/ospfv2.rb +31 -26
  70. data/lib/packetgen/header/ospfv3/db_description.rb +12 -13
  71. data/lib/packetgen/header/ospfv3/hello.rb +10 -9
  72. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +6 -2
  73. data/lib/packetgen/header/ospfv3/ls_ack.rb +5 -6
  74. data/lib/packetgen/header/ospfv3/ls_request.rb +10 -10
  75. data/lib/packetgen/header/ospfv3/ls_update.rb +7 -7
  76. data/lib/packetgen/header/ospfv3/lsa.rb +23 -9
  77. data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -2
  78. data/lib/packetgen/header/ospfv3.rb +38 -34
  79. data/lib/packetgen/header/sctp/chunk.rb +38 -17
  80. data/lib/packetgen/header/sctp/error.rb +169 -197
  81. data/lib/packetgen/header/sctp/padded32.rb +3 -3
  82. data/lib/packetgen/header/sctp/parameter.rb +85 -132
  83. data/lib/packetgen/header/sctp.rb +14 -3
  84. data/lib/packetgen/header/snmp.rb +108 -7
  85. data/lib/packetgen/header/tcp/option.rb +7 -0
  86. data/lib/packetgen/header/tcp/options.rb +11 -3
  87. data/lib/packetgen/header/tcp.rb +33 -26
  88. data/lib/packetgen/header/tftp.rb +16 -10
  89. data/lib/packetgen/header/udp.rb +15 -13
  90. data/lib/packetgen/header.rb +19 -13
  91. data/lib/packetgen/headerable.rb +9 -3
  92. data/lib/packetgen/inspect.rb +2 -7
  93. data/lib/packetgen/packet.rb +94 -36
  94. data/lib/packetgen/pcapng/block.rb +2 -1
  95. data/lib/packetgen/pcapng/file.rb +41 -14
  96. data/lib/packetgen/pcapng/idb.rb +2 -1
  97. data/lib/packetgen/pcapng/shb.rb +2 -1
  98. data/lib/packetgen/pcapng/spb.rb +1 -1
  99. data/lib/packetgen/pcapng.rb +2 -0
  100. data/lib/packetgen/proto.rb +4 -0
  101. data/lib/packetgen/unknown_packet.rb +3 -3
  102. data/lib/packetgen/utils.rb +2 -1
  103. data/lib/packetgen/version.rb +1 -1
  104. data/lib/packetgen.rb +8 -2
  105. metadata +4 -4
@@ -9,30 +9,18 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class SCTP
12
- # Common methods to Init and InitAck parameters
13
- # @author Sylvain Daubert
14
- module ParameterMixin
15
- include Padded32
16
-
17
- # Get parameter name
18
- # @return [String]
19
- def parameter_name
20
- self.class.name.split('::').last.delete_suffix('Parameter')
21
- end
22
-
23
- # @return [String]
24
- def to_human
25
- "<#{parameter_name}: #{value}>"
26
- end
27
- end
28
-
12
+ # @!parse
13
+ # class Parameter < BinStruct::AbstractTLV; end
29
14
  Parameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
30
15
  length_class: BinStruct::Int16,
31
16
  attr_in_length: 'TLV')
32
17
  # Base class/factory for {InitChunk} and {InitAckChunk} parameters
33
18
  # @author Sylvain Daubert
19
+ # @author LemonTree55
20
+ # @since 3.4.0
21
+ # @since 4.1.0 No more include +ParamterMixin+.
34
22
  class Parameter
35
- include ParameterMixin
23
+ include Padded32
36
24
 
37
25
  # Paramter Types
38
26
  TYPES = {
@@ -46,12 +34,19 @@ module PacketGen
46
34
  'ECN' => 32_768
47
35
  }.freeze
48
36
 
37
+ # Get human-readable descriptiob
49
38
  # @return [::String]
50
39
  def to_human
51
- "<#{human_type}: #{self[:value].inspect}>"
40
+ value = if self[:value].is_a?(BinStruct::String)
41
+ self[:value].inspect
42
+ else
43
+ self[:value].to_human
44
+ end
45
+ "<#{human_type}: #{value}>"
52
46
  end
53
47
 
54
- # @param [Object] value
48
+ # Populate parameter from a human-readable string or a Parameter.
49
+ # @param [Parameter,String] value
55
50
  def from_human(value)
56
51
  if value.is_a?(self[:value].class)
57
52
  self[:value] = value
@@ -59,94 +54,77 @@ module PacketGen
59
54
  self[:value].from_human(value)
60
55
  end
61
56
  end
57
+
58
+ # Get parameter name
59
+ # @return [String]
60
+ def parameter_name
61
+ self.class.name.split('::').last.delete_suffix('Parameter')
62
+ end
62
63
  end
63
64
  Parameter.define_type_enum(Parameter::TYPES)
64
65
 
65
- IPv4Parameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
66
- length_class: BinStruct::Int16,
67
- value_class: IP::Addr,
68
- attr_in_length: 'TLV')
69
-
70
- # IPv4 address parameter
71
- # @author Sylvain Daubert
72
- class IPv4Parameter
73
- include ParameterMixin
74
- end
75
- IPv4Parameter.define_type_enum(Parameter::TYPES)
66
+ # @!parse
67
+ # # IPv4 address parameter. A {Parameter} whose value is a {IP::Addr}.
68
+ # # @author Sylvain Daubert
69
+ # # @author LemonTree55
70
+ # # @since 3.4.0
71
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
72
+ # class IPv4Parameter < Parameter; end
73
+ IPv4Parameter = Parameter.derive(value_class: IP::Addr)
76
74
  IPv4Parameter.define_type_default('IPv4')
77
75
 
78
- IPv6Parameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
79
- length_class: BinStruct::Int16,
80
- value_class: IPv6::Addr,
81
- attr_in_length: 'TLV')
82
-
83
- # IPv6 address parameter
84
- # @author Sylvain Daubert
85
- class IPv6Parameter
86
- include ParameterMixin
87
- end
88
- IPv6Parameter.define_type_enum(Parameter::TYPES)
76
+ # @!parse
77
+ # # IPv6 address parameter. A {Parameter} whose value is a {IPv6::Addr}.
78
+ # # @author Sylvain Daubert
79
+ # # @author LemonTree55
80
+ # # @since 3.4.0
81
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
82
+ # class IPv6Parameter < Parameter; end
83
+ IPv6Parameter = Parameter.derive(value_class: IPv6::Addr)
89
84
  IPv6Parameter.define_type_default('IPv6')
90
85
 
91
- StateCookieParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
92
- length_class: BinStruct::Int16,
93
- value_class: BinStruct::String,
94
- attr_in_length: 'TLV')
95
-
96
- # State Cookie parameter
86
+ # State Cookie parameter. A {Parameter} whose value is a cookie string.
97
87
  # @author Sylvain Daubert
98
- class StateCookieParameter
99
- include ParameterMixin
100
-
101
- # @return [::String]
102
- def to_human
103
- "<#{parameter_name}: #{self[:value].inspect}>"
104
- end
88
+ # @author LemonTree55
89
+ # @since 3.4.0
90
+ # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
91
+ class StateCookieParameter < Parameter
105
92
  end
106
- StateCookieParameter.define_type_enum(Parameter::TYPES)
107
93
  StateCookieParameter.define_type_default('StateCookie')
108
94
 
109
- UnrecognizedParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
110
- length_class: BinStruct::Int16,
111
- value_class: Parameter,
112
- attr_in_length: 'TLV')
113
-
114
- # Unrecognized parameter
115
- # @author Sylvain Daubert
116
- class UnrecognizedParameter
117
- include ParameterMixin
118
-
119
- # @return [::String]
120
- def to_human
121
- "<#{parameter_name}: #{self[:value].to_human}"
122
- end
123
- end
124
- UnrecognizedParameter.define_type_enum(Parameter::TYPES)
95
+ # @!parse
96
+ # # Unrecognized parameter. A {Parameter} whose value is a {Parameter}.
97
+ # # @author Sylvain Daubert
98
+ # # @author LemonTree55
99
+ # # @since 3.4.0
100
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
101
+ # class UnrecognizedParameter < Parameter; end
102
+ UnrecognizedParameter = Parameter.derive(value_class: Parameter)
125
103
  UnrecognizedParameter.define_type_default('Unrecognized')
126
104
 
127
- HostnameParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
128
- length_class: BinStruct::Int16,
129
- value_class: BinStruct::CString,
130
- attr_in_length: 'TLV')
131
-
132
- # Hostname address parameter
133
- # @author Sylvain Daubert
134
- class HostnameParameter
135
- include ParameterMixin
136
- end
137
- HostnameParameter.define_type_enum(Parameter::TYPES)
105
+ # @!parse
106
+ # # Hostname address parameter. A {Parameter} whose value is a null-terminated string.
107
+ # # @author Sylvain Daubert
108
+ # # @author LemonTree55
109
+ # # @since 3.4.0
110
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
111
+ # class HostnameParameter < Parameter; end
112
+ HostnameParameter = Parameter.derive(value_class: BinStruct::CString)
138
113
  HostnameParameter.define_type_default('Hostname')
139
114
 
140
- SupportedAddrTypesParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
141
- length_class: BinStruct::Int16,
142
- value_class: BinStruct::ArrayOfInt16,
143
- attr_in_length: 'TLV')
115
+ # @!parse
116
+ # # Supported address types parameter. æ {Parameter} whose value is an array of supported address types
117
+ # # (as +BinStruct::Int16+).
118
+ # # @author Sylvain Daubert
119
+ # # @author LemonTree55
120
+ # # @since 3.4.0
121
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
122
+ # class SupportedAddrTypesParameter < Parameter; end
123
+ SupportedAddrTypesParameter = Parameter.derive(value_class: BinStruct::ArrayOfInt16)
124
+ SupportedAddrTypesParameter.define_type_default('SupportedAddrTypes')
144
125
 
145
- # Supported address types parameter
146
- # @author Sylvain Daubert
147
126
  class SupportedAddrTypesParameter
148
- include ParameterMixin
149
-
127
+ # Get human-readable description
150
128
  # @return [::String]
151
129
  def to_human
152
130
  types = self[:value].map(&:to_i).map do |int16|
@@ -155,57 +133,32 @@ module PacketGen
155
133
  "<#{parameter_name}: #{types}>"
156
134
  end
157
135
  end
158
- SupportedAddrTypesParameter.define_type_enum(Parameter::TYPES)
159
- SupportedAddrTypesParameter.define_type_default('SupportedAddrTypes')
160
-
161
- CookiePreservativeParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
162
- length_class: BinStruct::Int16,
163
- value_class: BinStruct::Int32,
164
- attr_in_length: 'TLV')
165
-
166
- # Cookie Preservative parameter
167
- # @author Sylvain Daubert
168
- class CookiePreservativeParameter
169
- include ParameterMixin
170
136
 
171
- # @return [::String]
172
- def to_human
173
- "<#{parameter_name}: #{value}>"
174
- end
175
- end
176
- CookiePreservativeParameter.define_type_enum(Parameter::TYPES)
137
+ # @!parse
138
+ # # Cookie preservative parameter. A {Parameter} whose value is a +BinStruct::Int32+.
139
+ # # @author Sylvain Daubert
140
+ # # @author LemonTree55
141
+ # # @since 3.4.0
142
+ # # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
143
+ # class CookiePreservativeParameter < Parameter; end
144
+ CookiePreservativeParameter = Parameter.derive(value_class: BinStruct::Int32)
177
145
  CookiePreservativeParameter.define_type_default('CookiePreservative')
178
146
 
179
- ECNParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
180
- length_class: BinStruct::Int16,
181
- attr_in_length: 'TLV')
182
-
183
- # ECN parameter
147
+ # ECN parameter. A {Parameter} who has no value.
184
148
  # @author Sylvain Daubert
185
- class ECNParameter
186
- include ParameterMixin
187
-
149
+ # @author LemonTree55
150
+ # @since 3.4.0
151
+ # @since 4.1.0 Subclass of {Parameter}. No more include +ParameterMixin+.
152
+ class ECNParameter < Parameter
153
+ # Get human readable description
188
154
  # @return [::String]
189
155
  def to_human
190
156
  "<#{parameter_name}>"
191
157
  end
192
158
  end
193
- ECNParameter.define_type_enum(Parameter::TYPES)
194
159
  ECNParameter.define_type_default('ECN')
195
160
 
196
- HearbeatInfoParameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
197
- length_class: BinStruct::Int16,
198
- attr_in_length: 'TLV')
199
-
200
- # Heartbeat Information parameter
201
- # @author Sylvain Daubert
202
- class HearbeatInfoParameter
203
- include ParameterMixin
204
- end
205
- HearbeatInfoParameter.define_type_enum({ 'HearbeatInfo' => 1 }.freeze)
206
- HearbeatInfoParameter.define_type_default('HearbeatInfo')
207
-
208
- # Array of {Parameter}s and {ParameterMixin}.
161
+ # Array of {Parameter parameters}.
209
162
  # @author Sylvain Daubert
210
163
  class ArrayOfParameter < BinStruct::Array
211
164
  set_of Parameter
@@ -221,7 +174,7 @@ module PacketGen
221
174
  end
222
175
 
223
176
  def real_klass_name(type_name)
224
- type_name + 'Parameter' # rubocop:disable Style/StringConcatenation
177
+ "#{type_name}Parameter"
225
178
  end
226
179
  end
227
180
  end
@@ -26,8 +26,17 @@ module PacketGen
26
26
  # | Chunk #n |
27
27
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28
28
  #
29
+ # A SCTP header is composed of:
30
+ # * {#sport}, source port number (+BinStruct::Int16+),
31
+ # * {#dport}, destination port number (+BinStruct::Int16+),
32
+ # * {#verification_tag} (+BinStruct::Int32+),
33
+ # * {#checksum} (+BinStruct::Int32le+),
34
+ # * {#chunks}, list of {BaseChunk chunks} ({ArrayOfChunk}).
35
+ #
29
36
  # @author Sylvain Daubert
37
+ # @author LemonTree55
30
38
  # @since 3.4.0
39
+ # @since 4.1.0 Remove +ErrorMixin+ and +ParameterMixin+
31
40
  class SCTP < Base; end
32
41
  end
33
42
  end
@@ -56,7 +65,7 @@ module PacketGen
56
65
  # @return [Integer]
57
66
  define_attr :verification_tag, BinStruct::Int32
58
67
  # @!attribute checksum
59
- # 32-bit TCP checksum
68
+ # 32-bit TCP checksum. This is a CRC32C checkum, computed on SCTP header and all its chunks.
60
69
  # @return [Integer]
61
70
  define_attr :checksum, BinStruct::Int32le
62
71
  # @!attribute chunks
@@ -64,7 +73,8 @@ module PacketGen
64
73
  # @return [ArrayOfChunk]
65
74
  define_attr :chunks, ArrayOfChunk
66
75
 
67
- # Compute SCTP checksum
76
+ # Compute SCTP checksum and set {#checksum} attribute.
77
+ # @return [Integer]
68
78
  def calc_checksum
69
79
  self.checksum = 0
70
80
  crc32c = Digest::CRC32c.new
@@ -72,7 +82,8 @@ module PacketGen
72
82
  self.checksum = crc32c.checksum
73
83
  end
74
84
 
75
- # Compute SCTP chunks length
85
+ # Compute SCTP chunk lengths
86
+ # @return [void]
76
87
  def calc_length
77
88
  self.chunks.each(&:calc_length)
78
89
  end
@@ -15,7 +15,44 @@ module PacketGen
15
15
  # Simple Network Management Protocol (SNMP)
16
16
  #
17
17
  # See https://github.com/lemontree55/packetgen/wiki/SNMP
18
+ #
19
+ # SNMP is defined from ASN.1:
20
+ # Message ::=
21
+ # SEQUENCE {
22
+ # version
23
+ # INTEGER {
24
+ # version-1(0)
25
+ # },
26
+ # community -- community name
27
+ # OCTET STRING,
28
+ # data -- e.g., PDUs if trivial
29
+ # ANY -- authentication is being used
30
+ # }
31
+ # It has 3 attributes, accessible through +#[]+:
32
+ # * +:version+, SNMP protocol version (type +RASN1::Types::Integer+ with enumeration),
33
+ # * +:community+ (type +RASN1::Types::OctetString+),
34
+ # * +:data+ (type {PDUs}).
35
+ #
36
+ # @!attribute version
37
+ # version attribute. Shortcut for +snmp[:version].value+.
38
+ # String values are: +v1+, +v2+, +v2c+ and +v3+.
39
+ # @return [String]
40
+ # @!attribute community
41
+ # community attribute. Shortcut for +snmp[:community].value+.
42
+ # @return [String]
43
+ #
44
+ # @example
45
+ # snmp = PacketGen::Header::SNMP.new(version: "v3",
46
+ # chosen_pdu: PacketGen::Header::SNMP::PDU_SET,
47
+ # pdu: { id: 1, varbindlist: [{ name: '1.2.3.4' }] })
48
+ # snmp.version #=> "v3"
49
+ # snmp.community #=> "public"
50
+ # snmp.pdu.class #=> PacketGen::Header::SNMP::SetRequest
51
+ # snmp.pdu[:id].value #=> 1
52
+ # snmp.pdu[:varbindlist][0][:name].inspect #=> 'name OBJECT ID: "1.2.3.4"'
53
+ # snmp.pdu[:varbindlist][0][:name].value #=> "1.2.3.4"
18
54
  # @author Sylvain Daubert
55
+ # @author LemonTree55
19
56
  # @since 2.0.0
20
57
  class SNMP < ASN1Base
21
58
  # Agents listen to this port
@@ -23,19 +60,26 @@ module PacketGen
23
60
  # Configuration sinks listen to this port
24
61
  UDP_PORT2 = 162
25
62
 
26
- # rubocop:disable Naming/ConstantName
27
-
63
+ # Implicit tag number for GetRequest PDU type
28
64
  PDU_GET = 0
65
+ # Implicit tag number for GetNextRequest PDU type
29
66
  PDU_NEXT = 1
67
+ # Implicit tag number for GetResponse PDU type
30
68
  PDU_RESPONSE = 2
69
+ # Implicit tag number for SetRequest PDU type
31
70
  PDU_SET = 3
71
+ # Implicit tag number for Trapv1 PDU type
32
72
  PDU_TRAPv1 = 4
73
+ # Implicit tag number for Bulk PDU type
33
74
  PDU_BULK = 5
75
+ # Implicit tag number for InformRequest PDU type
34
76
  PDU_INFORM = 6
77
+ # Implicit tag number for Trapv2 PDU type
35
78
  PDU_TRAPv2 = 7
79
+ # Implicit tag number for Report PDU type
36
80
  PDU_REPORT = 8
37
- # rubocop:enable Naming/ConstantName
38
81
 
82
+ # Error types
39
83
  ERRORS = {
40
84
  'no_error' => 0,
41
85
  'too_big' => 1,
@@ -63,7 +107,13 @@ module PacketGen
63
107
  # name OBJECT IDENTIFIER,
64
108
  # value ANY -- depends on name
65
109
  # }
110
+ # This class associates a +:name+ (type +RASN1::Types::ObjectId+) to a +:value+ (any RASN1 type).
111
+ # @example
112
+ # vb = PacketGen::Header::SNMP::VarBind.new(name: "1.2.3.4", value: RASN1::Types::OctetString.new(value: "abc"))
113
+ # vb[:name].class # => RASN1::Types::ObjectId
114
+ # vb[:name].value # => "1.2.3.4"
66
115
  # @author Sylvain Daubert
116
+ # @author LemonTree55
67
117
  class VarBind < RASN1::Model
68
118
  sequence :varbind,
69
119
  content: [objectid(:name),
@@ -72,7 +122,12 @@ module PacketGen
72
122
 
73
123
  # Class to handle SNMP VariableBindingsList
74
124
  # VarBindList ::= SEQUENCE (SIZE (0..max-bindings)) OF VarBind
125
+ # This is a sequence of {VarBind}.
126
+ # @example
127
+ # bindings = PacketGen::Header::SNMP::VariableBindings.new
128
+ # bindings << { name: "1.2.3.4", value: RASN1::Types::OctetString.new(value: "abc") }
75
129
  # @author Sylvain Daubert
130
+ # @author LemonTree55
76
131
  class VariableBindings < RASN1::Model
77
132
  sequence_of :bindings, VarBind
78
133
 
@@ -124,7 +179,20 @@ module PacketGen
124
179
  # variable-bindings -- values are sometimes ignored
125
180
  # VarBindList
126
181
  # }
182
+ # This class defines a GetRequest SNMP PDU. It defines 4 attributes:
183
+ # * an +:id+ (request-id, type +RASN1::Types::Integer+),
184
+ # * an +:error+ (error-status, type +RASN1::Types::Integer with enumeration definition from {ERRORS}),
185
+ # * an +:error_index+ (type +RASN1::Types::Integer+),
186
+ # * a +:barbindlist+ (variable-bindings, type {VariableBindings}).
187
+ #
188
+ # @example
189
+ # req = PacketGen::Header::SNMP::GetRequest.new(id: 1, error: "no_error")
190
+ # req[:id].value #=> 1
191
+ # req[:error].value #=> "no_error"
192
+ # req[:error].to_i #=> 0
193
+ # req[:varbindlist] << { name: "1.2.3.4", value: RASN1::Types::OctetString.new(value: "abcd") }
127
194
  # @author Sylvain Daubert
195
+ # @author LemonTree55
128
196
  class GetRequest < RASN1::Model
129
197
  sequence :pdu,
130
198
  implicit: SNMP::PDU_GET, constructed: true,
@@ -140,6 +208,7 @@ module PacketGen
140
208
 
141
209
  # Class to handle GetNextRequest PDU
142
210
  # GetNextRequest-PDU ::= [1] IMPLICIT PDU -- PDU definition: see GetRequest
211
+ # @see GetRequest
143
212
  # @author Sylvain Daubert
144
213
  class GetNextRequest < GetRequest
145
214
  root_options implicit: SNMP::PDU_NEXT
@@ -147,6 +216,7 @@ module PacketGen
147
216
 
148
217
  # Class to handle GetResponse PDU
149
218
  # GetResponse-PDU ::= [2] IMPLICIT PDU -- PDU definition: see GetRequest
219
+ # @see GetRequest
150
220
  # @author Sylvain Daubert
151
221
  class GetResponse < GetRequest
152
222
  root_options implicit: SNMP::PDU_RESPONSE
@@ -154,6 +224,7 @@ module PacketGen
154
224
 
155
225
  # Class to handle SetRequest PDU
156
226
  # SetRequest-PDU ::= [3] IMPLICIT PDU -- PDU definition: see GetRequest
227
+ # @see GetRequest
157
228
  # @author Sylvain Daubert
158
229
  class SetRequest < GetRequest
159
230
  root_options implicit: SNMP::PDU_SET
@@ -177,6 +248,15 @@ module PacketGen
177
248
  # time-stamp TimeTicks,
178
249
  # variable-bindings VarBindList
179
250
  # }
251
+ # This class defines 6 attributes accessibles through +#[]+:
252
+ # * +:enterprise+ for request-id (type +RASN1::Types::ObjectId+),
253
+ # * +:agent_addr+ (type +RASN1::Types::Integer+),
254
+ # * +:generic_trap+ (type +RASN1::Types::Integer+),
255
+ # * +:specific_trap+ (type +RASN1::Types::Integer+),
256
+ # * +:timestamp+ (type +RASN1::Types::Integer+),
257
+ # * +:varbindlist+ for variable-bindings (type {VariableBindings}).
258
+ # @author Sylvain Daubert
259
+ # @author LemonTree55
180
260
  class Trapv1 < RASN1::Model
181
261
  sequence :trap,
182
262
  implicit: SNMP::PDU_TRAPv1, constructed: true,
@@ -205,7 +285,20 @@ module PacketGen
205
285
  # variable-bindings -- values are ignored
206
286
  # VarBindList
207
287
  # }
288
+ #
289
+ # This class defines 4 values accessibles through +#[]+:
290
+ # * +:id+ for request-id (type +RASN1::Types::Integer+),
291
+ # * +:non_repeaters+ (type +RASN1::Types::Integer+),
292
+ # * +:max_repetitions+ (type +RASN1::Types::Integer+),
293
+ # * +varbindlist+ for variable-bindings (type {VariableBindings}).
294
+ # @example
295
+ # bulk = PacketGen::Header::SNMP::Bulk.new(id: 1, non_repeaters: 2, max_repetitions: 2)
296
+ # bulk[:varbindlist] << { name: '1.2.3.4', value: RASN1::Types::OctetString.new(value: "abcd") }
297
+ # bulk[:id].inspect # => "id INTEGER: 1"
298
+ # bulk[:id].value # => 1
299
+ # bulk[:varbindlist][0][:name].value # => "1.2.3.4"
208
300
  # @author Sylvain Daubert
301
+ # @author LemonTree55
209
302
  class Bulk < RASN1::Model
210
303
  sequence :bulkpdu,
211
304
  implicit: SNMP::PDU_BULK, constructed: true,
@@ -217,6 +310,7 @@ module PacketGen
217
310
 
218
311
  # Class to handle InformRequest PDU
219
312
  # InformRequest-PDU ::= [6] IMPLICIT PDU -- PDU definition: see GetRequest
313
+ # @see GetRequest
220
314
  # @author Sylvain Daubert
221
315
  class InformRequest < GetRequest
222
316
  root_options implicit: SNMP::PDU_INFORM
@@ -224,6 +318,7 @@ module PacketGen
224
318
 
225
319
  # Class to handle Trapv2 PDU
226
320
  # SNMPv2-Trap-PDU ::= [7] IMPLICIT PDU -- PDU definition: see GetRequest
321
+ # @see GetRequest
227
322
  # @author Sylvain Daubert
228
323
  class Trapv2 < GetRequest
229
324
  root_options implicit: SNMP::PDU_TRAPv2
@@ -231,6 +326,7 @@ module PacketGen
231
326
 
232
327
  # Class to handle Report PDU
233
328
  # Report-PDU ::= [8] IMPLICIT PDU -- PDU definition: see GetRequest
329
+ # @see GetRequest
234
330
  # @author Sylvain Daubert
235
331
  class Report < GetRequest
236
332
  root_options implicit: SNMP::PDU_REPORT
@@ -248,7 +344,10 @@ module PacketGen
248
344
  # snmpV2-trap [7] IMPLICIT PDU,
249
345
  # report [8] IMPLICIT PDU
250
346
  # }
347
+ # This class is a wrapper. It contains one of {GetRequest}, {GetNextRequest}, {GetResponse}, {SetRequest},
348
+ # {Trapv1}, {Bulk}, {InformRequest}, {Trapv2} or {Report}.
251
349
  # @author Sylvain Daubert
350
+ # @author LemonTree55
252
351
  class PDUs < RASN1::Model
253
352
  choice :pdus,
254
353
  content: [model(:get_request, GetRequest),
@@ -285,13 +384,13 @@ module PacketGen
285
384
  data.root.value[data.chosen] = klass.new(options[:pdu])
286
385
  end
287
386
 
288
- # accessor to data payload
289
- # @return [ASN1::BinStruct::Choice]
387
+ # accessor to data payload. Shortcut for +snmp[:data]+.
388
+ # @return [ASN1::Types::Choice]
290
389
  def data
291
390
  @elements[:data]
292
391
  end
293
392
 
294
- # shortcut to PDU
393
+ # shortcut to PDU (+snmp[:data].chosen_value+).
295
394
  # @return [GetRequest, Bulk, Trapv1, nil] return `nil` if no CHOICE was done
296
395
  def pdu
297
396
  if data.chosen.nil?
@@ -301,6 +400,8 @@ module PacketGen
301
400
  end
302
401
  end
303
402
 
403
+ # Inspect SNMP header
404
+ # @return [String]
304
405
  def inspect
305
406
  str = super
306
407
  str << Inspect.shift_level
@@ -316,7 +417,7 @@ module PacketGen
316
417
  # directly called
317
418
  # @param [Packet] packet
318
419
  # @return [void]
319
- # @since 2.7.0 Set UDP sport according to bindings, only if sport is 0.
420
+ # @since 2.7.0 Set UDP sport according to bindings, only if sport is not set yet (i.e. is zero).
320
421
  # Needed by new bind API.
321
422
  def added_to_packet(packet)
322
423
  return unless packet.is?('UDP')
@@ -90,7 +90,9 @@ module PacketGen
90
90
  end
91
91
  end
92
92
 
93
+ # @private
93
94
  alias old_set_value value=
95
+
94
96
  # Setter for value attribute
95
97
  # @param[String,Integer] val
96
98
  # @return [String, Integer]
@@ -159,6 +161,7 @@ module PacketGen
159
161
  self[:value] = BinStruct::Int16.new(value: options[:value])
160
162
  end
161
163
 
164
+ # Get human-readable description
162
165
  # @return [String]
163
166
  def to_human
164
167
  "MSS:#{value}"
@@ -177,6 +180,7 @@ module PacketGen
177
180
  self[:value] = BinStruct::Int8.new(value: options[:value])
178
181
  end
179
182
 
183
+ # Get human-readable description
180
184
  # @return [String]
181
185
  def to_human
182
186
  "WS:#{value}"
@@ -208,6 +212,7 @@ module PacketGen
208
212
  self[:value] = BinStruct::Int32.new(value: options[:value])
209
213
  end
210
214
 
215
+ # Get human-readable description
211
216
  # @return [String]
212
217
  def to_human
213
218
  "WS:#{value}"
@@ -226,6 +231,7 @@ module PacketGen
226
231
  self[:value] = BinStruct::Int32.new(value: options[:value])
227
232
  end
228
233
 
234
+ # Get human-readable description
229
235
  # @return [String]
230
236
  def to_human
231
237
  "WS:#{value}"
@@ -244,6 +250,7 @@ module PacketGen
244
250
  self[:value].read(options[:value] || "\0" * 8)
245
251
  end
246
252
 
253
+ # Get human-readable description
247
254
  # @return [String]
248
255
  def to_human
249
256
  value, echo_reply = self[:value].unpack('NN')
@@ -11,8 +11,16 @@ require_relative 'option'
11
11
  module PacketGen
12
12
  module Header
13
13
  class TCP
14
- # Container for TCP options in {TCP TCP header}.
14
+ # Container for TCP {Option options} in {TCP TCP header}.
15
15
  # @author Sylvain Daubert
16
+ # @since 1.0.0
17
+ # @since 4.1.0 +#<<+ accepts +:kind+ parameter in hash
18
+ # @example Add an option from a hash
19
+ # opts = PacketGen::Header::TCP::Options.new
20
+ # # Option kind may be set using :opt
21
+ # opts << { opt: 'MSS', value: 1250 }
22
+ # # It may aldo be set using :kind
23
+ # opts << { kind: 'EOL' }
16
24
  class Options < BinStruct::Array
17
25
  set_of Option
18
26
 
@@ -34,8 +42,8 @@ module PacketGen
34
42
  private
35
43
 
36
44
  def record_from_hash(hsh)
37
- if hsh.key? :opt
38
- klassname = hsh.delete(:opt)
45
+ if hsh.key?(:opt) || hsh.key?(:kind)
46
+ klassname = hsh.delete(:opt) || hsh.delete(:kind)
39
47
  raise ArgumentError, 'opt should be a TCP::Option subclass' unless TCP.const_defined?(klassname)
40
48
 
41
49
  klass = TCP.const_get(klassname)