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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/packetgen/deprecation.rb +7 -1
- data/lib/packetgen/header/arp.rb +6 -7
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +27 -24
- data/lib/packetgen/header/bootp.rb +14 -14
- data/lib/packetgen/header/dhcp/option.rb +8 -8
- data/lib/packetgen/header/dhcp/options.rb +2 -2
- data/lib/packetgen/header/dhcp.rb +6 -7
- data/lib/packetgen/header/dhcpv6/duid.rb +1 -1
- data/lib/packetgen/header/dhcpv6/option.rb +37 -15
- data/lib/packetgen/header/dhcpv6/options.rb +3 -3
- data/lib/packetgen/header/dhcpv6/relay.rb +1 -0
- data/lib/packetgen/header/dhcpv6.rb +13 -14
- data/lib/packetgen/header/dns/name.rb +9 -8
- data/lib/packetgen/header/dns/opt.rb +3 -0
- data/lib/packetgen/header/dns/option.rb +7 -7
- data/lib/packetgen/header/dns/qdsection.rb +2 -2
- data/lib/packetgen/header/dns/question.rb +1 -0
- data/lib/packetgen/header/dns/rrsection.rb +2 -2
- data/lib/packetgen/header/dns.rb +76 -60
- data/lib/packetgen/header/dot11/control.rb +5 -5
- data/lib/packetgen/header/dot11/data.rb +11 -10
- data/lib/packetgen/header/dot11/element.rb +1 -1
- data/lib/packetgen/header/dot11/management.rb +18 -15
- data/lib/packetgen/header/dot11/sub_mngt.rb +22 -21
- data/lib/packetgen/header/dot11.rb +38 -38
- data/lib/packetgen/header/dot1q.rb +5 -4
- data/lib/packetgen/header/dot1x.rb +8 -8
- data/lib/packetgen/header/eap/fast.rb +3 -3
- data/lib/packetgen/header/eap/md5.rb +11 -3
- data/lib/packetgen/header/eap/tls.rb +9 -8
- data/lib/packetgen/header/eap/ttls.rb +13 -10
- data/lib/packetgen/header/eap.rb +58 -33
- data/lib/packetgen/header/eth.rb +26 -12
- data/lib/packetgen/header/gre.rb +26 -2
- data/lib/packetgen/header/http/headers.rb +6 -5
- data/lib/packetgen/header/http/request.rb +24 -16
- data/lib/packetgen/header/http/response.rb +22 -15
- data/lib/packetgen/header/icmp.rb +10 -10
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +21 -10
- data/lib/packetgen/header/igmpv3/group_record.rb +7 -2
- data/lib/packetgen/header/igmpv3/mq.rb +1 -1
- data/lib/packetgen/header/igmpv3/mr.rb +1 -1
- data/lib/packetgen/header/igmpv3.rb +11 -10
- data/lib/packetgen/header/ip/addr.rb +6 -2
- data/lib/packetgen/header/ip/option.rb +18 -5
- data/lib/packetgen/header/ip.rb +52 -35
- data/lib/packetgen/header/ipv6/addr.rb +14 -13
- data/lib/packetgen/header/ipv6/extension.rb +9 -7
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +26 -7
- data/lib/packetgen/header/ipv6.rb +31 -22
- data/lib/packetgen/header/llc.rb +20 -13
- data/lib/packetgen/header/mdns.rb +9 -2
- data/lib/packetgen/header/mld.rb +11 -9
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +6 -1
- data/lib/packetgen/header/mldv2/mlq.rb +8 -8
- data/lib/packetgen/header/mldv2/mlr.rb +4 -4
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +10 -10
- data/lib/packetgen/header/ospfv2/hello.rb +11 -10
- data/lib/packetgen/header/ospfv2/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv2/ls_request.rb +7 -6
- data/lib/packetgen/header/ospfv2/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv2/lsa.rb +33 -10
- data/lib/packetgen/header/ospfv2/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv2.rb +31 -26
- data/lib/packetgen/header/ospfv3/db_description.rb +12 -13
- data/lib/packetgen/header/ospfv3/hello.rb +10 -9
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +6 -2
- data/lib/packetgen/header/ospfv3/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv3/ls_request.rb +10 -10
- data/lib/packetgen/header/ospfv3/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv3/lsa.rb +23 -9
- data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv3.rb +38 -34
- data/lib/packetgen/header/sctp/chunk.rb +38 -17
- data/lib/packetgen/header/sctp/error.rb +169 -197
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +85 -132
- data/lib/packetgen/header/sctp.rb +14 -3
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +7 -0
- data/lib/packetgen/header/tcp/options.rb +11 -3
- data/lib/packetgen/header/tcp.rb +33 -26
- data/lib/packetgen/header/tftp.rb +16 -10
- data/lib/packetgen/header/udp.rb +15 -13
- data/lib/packetgen/header.rb +19 -13
- data/lib/packetgen/headerable.rb +9 -3
- data/lib/packetgen/inspect.rb +2 -7
- data/lib/packetgen/packet.rb +94 -36
- data/lib/packetgen/pcapng/block.rb +2 -1
- data/lib/packetgen/pcapng/file.rb +41 -14
- data/lib/packetgen/pcapng/idb.rb +2 -1
- data/lib/packetgen/pcapng/shb.rb +2 -1
- data/lib/packetgen/pcapng/spb.rb +1 -1
- data/lib/packetgen/pcapng.rb +2 -0
- data/lib/packetgen/proto.rb +4 -0
- data/lib/packetgen/unknown_packet.rb +3 -3
- data/lib/packetgen/utils.rb +2 -1
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +8 -2
- metadata +4 -4
@@ -9,30 +9,18 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class SCTP
|
12
|
-
#
|
13
|
-
#
|
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
|
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
|
-
|
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
|
-
#
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
#
|
72
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
#
|
84
|
-
#
|
85
|
-
|
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
|
-
|
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
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
#
|
115
|
-
#
|
116
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
#
|
134
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
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
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
186
|
-
|
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
|
-
|
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
|
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
|
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
|
-
#
|
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::
|
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
|
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? :
|
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)
|