packetgen 3.3.3 → 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 +38 -22
- data/lib/packetgen/capture.rb +2 -2
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +14 -8
- data/lib/packetgen/header/arp.rb +17 -18
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +42 -40
- data/lib/packetgen/header/bootp.rb +35 -37
- data/lib/packetgen/header/dhcp/option.rb +21 -21
- data/lib/packetgen/header/dhcp/options.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +8 -9
- data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
- data/lib/packetgen/header/dhcpv6/option.rb +83 -61
- data/lib/packetgen/header/dhcpv6/options.rb +4 -4
- data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
- data/lib/packetgen/header/dhcpv6.rb +17 -18
- data/lib/packetgen/header/dns/name.rb +21 -16
- data/lib/packetgen/header/dns/opt.rb +5 -2
- data/lib/packetgen/header/dns/option.rb +14 -14
- data/lib/packetgen/header/dns/qdsection.rb +3 -3
- data/lib/packetgen/header/dns/question.rb +7 -8
- data/lib/packetgen/header/dns/rr.rb +56 -43
- data/lib/packetgen/header/dns/rrsection.rb +6 -6
- data/lib/packetgen/header/dns.rb +103 -90
- data/lib/packetgen/header/dot11/control.rb +12 -12
- data/lib/packetgen/header/dot11/data.rb +25 -24
- data/lib/packetgen/header/dot11/element.rb +4 -4
- data/lib/packetgen/header/dot11/management.rb +21 -18
- data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
- data/lib/packetgen/header/dot11.rb +117 -122
- data/lib/packetgen/header/dot1q.rb +12 -13
- data/lib/packetgen/header/dot1x.rb +13 -13
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +16 -8
- data/lib/packetgen/header/eap/tls.rb +18 -19
- data/lib/packetgen/header/eap/ttls.rb +22 -21
- data/lib/packetgen/header/eap.rb +73 -48
- data/lib/packetgen/header/eth.rb +41 -27
- data/lib/packetgen/header/gre.rb +33 -11
- data/lib/packetgen/header/http/headers.rb +7 -6
- data/lib/packetgen/header/http/request.rb +38 -29
- data/lib/packetgen/header/http/response.rb +35 -27
- data/lib/packetgen/header/http/verbs.rb +1 -3
- data/lib/packetgen/header/icmp.rb +14 -14
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +26 -15
- data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
- data/lib/packetgen/header/igmpv3/mq.rb +16 -18
- data/lib/packetgen/header/igmpv3/mr.rb +5 -5
- data/lib/packetgen/header/igmpv3.rb +12 -11
- data/lib/packetgen/header/ip/addr.rb +19 -15
- data/lib/packetgen/header/ip/option.rb +47 -36
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +77 -95
- data/lib/packetgen/header/ipv6/addr.rb +28 -27
- data/lib/packetgen/header/ipv6/extension.rb +13 -11
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
- data/lib/packetgen/header/ipv6.rb +42 -35
- data/lib/packetgen/header/llc.rb +28 -21
- data/lib/packetgen/header/mdns.rb +10 -3
- data/lib/packetgen/header/mld.rb +15 -13
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
- data/lib/packetgen/header/mldv2/mlq.rb +22 -24
- data/lib/packetgen/header/mldv2/mlr.rb +8 -8
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
- data/lib/packetgen/header/ospfv2/hello.rb +18 -17
- data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
- data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
- data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
- data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv2.rb +49 -46
- data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
- data/lib/packetgen/header/ospfv3/hello.rb +17 -16
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
- data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
- data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
- data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
- data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
- data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv3.rb +54 -52
- data/lib/packetgen/header/sctp/chunk.rb +80 -56
- data/lib/packetgen/header/sctp/error.rb +174 -202
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +89 -136
- data/lib/packetgen/header/sctp.rb +19 -8
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +52 -39
- data/lib/packetgen/header/tcp/options.rb +13 -5
- data/lib/packetgen/header/tcp.rb +83 -65
- data/lib/packetgen/header/tftp.rb +31 -25
- data/lib/packetgen/header/udp.rb +21 -19
- data/lib/packetgen/header.rb +23 -18
- data/lib/packetgen/headerable.rb +21 -5
- data/lib/packetgen/inspect.rb +3 -8
- data/lib/packetgen/packet.rb +146 -71
- data/lib/packetgen/pcap.rb +15 -4
- data/lib/packetgen/pcapng/block.rb +20 -18
- data/lib/packetgen/pcapng/epb.rb +13 -15
- data/lib/packetgen/pcapng/file.rb +44 -111
- data/lib/packetgen/pcapng/idb.rb +11 -12
- data/lib/packetgen/pcapng/shb.rb +15 -16
- data/lib/packetgen/pcapng/spb.rb +9 -11
- data/lib/packetgen/pcapng/unknown_block.rb +6 -17
- data/lib/packetgen/pcapng.rb +6 -4
- data/lib/packetgen/pcaprub_wrapper.rb +17 -1
- data/lib/packetgen/proto.rb +5 -1
- data/lib/packetgen/unknown_packet.rb +5 -5
- data/lib/packetgen/utils/arp_spoofer.rb +18 -19
- data/lib/packetgen/utils.rb +4 -3
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +12 -5
- metadata +29 -38
- data/lib/packetgen/types/abstract_tlv.rb +0 -278
- data/lib/packetgen/types/array.rb +0 -287
- data/lib/packetgen/types/cstring.rb +0 -109
- data/lib/packetgen/types/enum.rb +0 -171
- data/lib/packetgen/types/fieldable.rb +0 -66
- data/lib/packetgen/types/fields.rb +0 -622
- data/lib/packetgen/types/int.rb +0 -473
- data/lib/packetgen/types/int_string.rb +0 -102
- data/lib/packetgen/types/length_from.rb +0 -54
- data/lib/packetgen/types/oui.rb +0 -52
- data/lib/packetgen/types/string.rb +0 -97
- data/lib/packetgen/types/tlv.rb +0 -161
- data/lib/packetgen/types.rb +0 -26
@@ -9,30 +9,18 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class SCTP
|
12
|
-
#
|
13
|
-
#
|
14
|
-
|
15
|
-
|
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
|
-
|
29
|
-
Parameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
30
|
-
length_class: Types::Int16,
|
31
|
-
field_in_length: 'TLV')
|
12
|
+
# @!parse
|
13
|
+
# class Parameter < BinStruct::AbstractTLV; end
|
14
|
+
Parameter = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16Enum,
|
15
|
+
length_class: BinStruct::Int16,
|
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: Types::Int16,
|
93
|
-
value_class: Types::String,
|
94
|
-
field_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,59 +133,34 @@ 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 = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
162
|
-
length_class: Types::Int16,
|
163
|
-
value_class: Types::Int32,
|
164
|
-
field_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: Types::Int16,
|
181
|
-
field_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: Types::Int16,
|
198
|
-
field_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
|
-
class ArrayOfParameter <
|
163
|
+
class ArrayOfParameter < BinStruct::Array
|
211
164
|
set_of Parameter
|
212
165
|
|
213
166
|
private
|
@@ -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
|
@@ -46,25 +55,26 @@ module PacketGen
|
|
46
55
|
# @!attribute sport
|
47
56
|
# 16-bit TCP source port
|
48
57
|
# @return [Integer]
|
49
|
-
|
58
|
+
define_attr :sport, BinStruct::Int16
|
50
59
|
# @!attribute dport
|
51
60
|
# 16-bit TCP destination port
|
52
61
|
# @return [Integer]
|
53
|
-
|
62
|
+
define_attr :dport, BinStruct::Int16
|
54
63
|
# @!attribute verification_tag
|
55
64
|
# 32-bit verification tag
|
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
|
63
72
|
# List of chunks this packet transports
|
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
|
387
|
+
# accessor to data payload. Shortcut for +snmp[:data]+.
|
289
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,10 +417,10 @@ 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
|
-
return unless packet.is?
|
423
|
+
return unless packet.is?('UDP')
|
323
424
|
return unless packet.udp.sport.zero?
|
324
425
|
|
325
426
|
packet.udp.sport = packet.udp.dport
|