packetgen 1.3.0 → 1.4.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.
@@ -0,0 +1,59 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ module PacketGen
8
+ module Header
9
+ class Dot11
10
+
11
+ # IEEE 802.11 control frame header
12
+ # @author Sylvain Daubert
13
+ class Control < Dot11
14
+
15
+ # Control subtypes
16
+ SUBTYPES = {
17
+ 7 => 'Wrapper',
18
+ 8 => 'Block Ack Request',
19
+ 9 => 'Block Ack',
20
+ 10 => 'PS-Poll',
21
+ 11 => 'RTS',
22
+ 12 => 'CTS',
23
+ 13 => 'Ack',
24
+ 14 => 'CF-End',
25
+ 15 => 'CF-End+CF-Ack'
26
+ }.freeze
27
+
28
+ # Control subtypes with mac2 field
29
+ SUBTYPES_WITH_MAC2 = [9, 10, 11, 14, 15].freeze
30
+
31
+ # @param [Hash] options
32
+ # @see Base#initialize
33
+ def initialize(options={})
34
+ super({type: 1}.merge!(options))
35
+ @applicable_fields -= %i(mac3 sequence_ctrl mac4 qos_ctrl ht_ctrl)
36
+ define_applicable_fields
37
+ end
38
+
39
+ # Get human readable subtype
40
+ # @return [String]
41
+ def human_subtype
42
+ SUBTYPES[subtype] || subtype.to_s
43
+ end
44
+
45
+ private
46
+
47
+ def define_applicable_fields
48
+ super
49
+ if @applicable_fields.include? :mac2
50
+ @applicable_fields -= %i(mac2) unless SUBTYPES_WITH_MAC2.include? self.subtype
51
+ elsif SUBTYPES_WITH_MAC2.include? self.subtype
52
+ sz = self.sz
53
+ @applicable_fields[3, 0] = :mac2
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ module PacketGen
8
+ module Header
9
+ class Dot11
10
+
11
+ # IEEE 802.11 data frame header
12
+ # @author Sylvain Daubert
13
+ class Data < Dot11
14
+
15
+ # @param [Hash] options
16
+ # @see Base#initialize
17
+ def initialize(options={})
18
+ super({type: 2}.merge!(options))
19
+ @applicable_fields -= %i(mac4 qos_ctrl ht_ctrl)
20
+ define_applicable_fields
21
+ end
22
+
23
+ private
24
+
25
+ def define_applicable_fields
26
+ super
27
+ if subtype >= 8 and !@applicable_fields.include? :qos_ctrl
28
+ # Insert after mac4, if present
29
+ # else insert after sequence_ctrl
30
+ if @applicable_fields.include? :mac4
31
+ idx = @applicable_fields.index(:mac4)
32
+ @applicable_fields[idx, 0] = :qos_ctrl
33
+ else
34
+ @applicable_fields[6, 0] = :qos_ctrl
35
+ end
36
+ elsif subtype < 8
37
+ @applicable_fields -= %i(qos_ctrl)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ module PacketGen
8
+ module Header
9
+ class Dot11
10
+
11
+ # IEEE 802.11 information element
12
+ # @author Sylvain Daubert
13
+ class Element < Types::TLV
14
+ # Known element types
15
+ TYPES = {
16
+ 0 => 'SSID',
17
+ 1 => 'Rates',
18
+ 2 => 'FHset',
19
+ 3 => 'DSset',
20
+ 4 => 'CFset',
21
+ 5 => 'TIM',
22
+ 6 => 'IBSSset',
23
+ 16 => 'challenge',
24
+ 42 => 'ERPinfo',
25
+ 46 => 'QoS Cap.',
26
+ 47 => 'ERPinfo',
27
+ 48 => 'RSNinfo',
28
+ 50 => 'ESRates',
29
+ 68 => 'reserved',
30
+ 221 => 'vendor'
31
+ }.freeze
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ module PacketGen
8
+ module Header
9
+ class Dot11
10
+
11
+ # IEEE 802.11 management frame header
12
+ # @author Sylvain Daubert
13
+ class Management < Dot11
14
+
15
+ # @param [Hash] options
16
+ # @see Base#initialize
17
+ def initialize(options={})
18
+ super({type: 0}.merge!(options))
19
+ @applicable_fields -= %i(mac4 qos_ctrl ht_ctrl)
20
+ define_applicable_fields
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,178 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ module PacketGen
8
+ module Header
9
+ class Dot11
10
+
11
+ # @abstract Base class for all subtype management frames
12
+ # @author Sylvain Daubert
13
+ class SubMngt < Base
14
+ # @return [Array<Element>]
15
+ attr_accessor :elements
16
+
17
+ # @param [Hash] options
18
+ # @see Base#initialize
19
+ def initialize(options={})
20
+ super
21
+ @elements = []
22
+ end
23
+
24
+ # Populate object from binary string
25
+ # @param [String] str
26
+ # @return [SubMngt] self
27
+ def read(str)
28
+ super
29
+ read_elements str[sz, str.size] || ''
30
+ self
31
+ end
32
+
33
+ # @return [String]
34
+ def to_s
35
+ super + @elements.map(&:to_s).join
36
+ end
37
+
38
+ # @return [String]
39
+ def inspect
40
+ str = super
41
+ str << Inspect.dashed_line('Dot11 Elements', level=3)
42
+ @elements.each do |el|
43
+ str << Inspect.shift_level(4) << el.to_human << "\n"
44
+ end
45
+ str
46
+ end
47
+
48
+ private
49
+
50
+ def read_elements(str)
51
+ start = 0
52
+ elsz = Element.new.sz
53
+ while str.size - start >= elsz do
54
+ el = Element.new.read(str[start, str.size])
55
+ @elements << el
56
+ start += el.sz
57
+ end
58
+ end
59
+ end
60
+
61
+ # IEEE 802.11 Association Request frame
62
+ class AssoReq < SubMngt
63
+ # @!attribute cap
64
+ # @return [Integer] 16-bit capabillities word
65
+ define_field :cap, Types::Int16le
66
+ # @!attribute listen_interval
67
+ # @return [Integer] 16-bit listen interval value
68
+ define_field :listen_interval, Types::Int16le, default: 0x00c8
69
+ end
70
+ Header.add_class AssoReq
71
+ Management.bind_header AssoReq, op: :and, type: 0, subtype: 0
72
+
73
+ # IEEE 802.11 Association Response frame
74
+ class AssoResp < SubMngt
75
+ # @!attribute cap
76
+ # @return [Integer] 16-bit capabillities word
77
+ define_field :cap, Types::Int16le
78
+ # @!attribute status
79
+ # @return [Integer] 16-bit status word
80
+ define_field :status, Types::Int16le
81
+ # @!attribute aid
82
+ # @return [Integer] 16-bit AID word
83
+ define_field :aid, Types::Int16le
84
+ end
85
+ Header.add_class AssoResp
86
+ Management.bind_header AssoResp, op: :and, type: 0, subtype: 1
87
+
88
+ # IEEE 802.11 ReAssociation Request frame
89
+ class ReAssoReq < AssoReq
90
+ # @!attribute current_ap
91
+ # @return [Eth::MAcAddr]
92
+ define_field :current_ap, Eth::MacAddr
93
+ end
94
+ Header.add_class ReAssoReq
95
+ Management.bind_header ReAssoReq, op: :and, type: 0, subtype: 2
96
+
97
+ # IEEE 802.11 ReAssociation Response frame
98
+ class ReAssoResp < AssoResp
99
+ end
100
+ Header.add_class ReAssoResp
101
+ Management.bind_header ReAssoResp, op: :and, type: 0, subtype: 3
102
+
103
+ # IEEE 802.11 Probe Request frame
104
+ class ProbeReq < SubMngt
105
+ end
106
+ Header.add_class ProbeReq
107
+ Management.bind_header ProbeReq, op: :and, type: 0, subtype: 4
108
+
109
+ # IEEE 802.11 Probe Response frame
110
+ class ProbeResp < SubMngt
111
+ # @!attribute timestamp
112
+ # @return [Integer] 64-bit timestamp
113
+ define_field :timestamp, Types::Int64le
114
+ # @!attribute beacon_interval
115
+ # @return [Integer] 16-bit beacon interval value
116
+ define_field :beacon_interval, Types::Int16le, default: 0x0064
117
+ # @!attribute cap
118
+ # @return [Integer] 16-bit capabillities word
119
+ define_field :cap, Types::Int16le
120
+ end
121
+ Header.add_class ProbeResp
122
+ Management.bind_header ProbeResp, op: :and, type: 0, subtype: 5
123
+
124
+ # IEEE 802.11 Beacon frame
125
+ class Beacon < SubMngt
126
+ # @!attribute timestamp
127
+ # @return [Integer] 64-bit timestamp
128
+ define_field :timestamp, Types::Int64le
129
+ # @!attribute interval
130
+ # @return [Integer] 16-bit interval value
131
+ define_field :interval, Types::Int16le, default: 0x64
132
+ # @!attribute cap
133
+ # @return [Integer] 16-bit capabillities word
134
+ define_field :cap, Types::Int16le
135
+ end
136
+ Header.add_class Beacon
137
+ Management.bind_header Beacon, op: :and, type: 0, subtype: 8
138
+
139
+ # IEEE 802.11 ATIM frame
140
+ class ATIM < SubMngt; end
141
+ Header.add_class ATIM
142
+ Management.bind_header ATIM, op: :and, type: 0, subtype: 9
143
+
144
+ # IEEE 802.11 Disassociation frame
145
+ class Disas < SubMngt
146
+ # @!attribute reason
147
+ # @return [Integer] 16-bit reason value
148
+ define_field :reason, Types::Int16le
149
+ end
150
+ Header.add_class Disas
151
+ Management.bind_header Disas, op: :and, type: 0, subtype: 10
152
+
153
+ # IEEE 802.11 Authentication frame
154
+ class Auth < SubMngt
155
+ # @!attribute algo
156
+ # @return [Integer] 16-bit algo value
157
+ define_field :algo, Types::Int16le
158
+ # @!attribute seqnum
159
+ # @return [Integer] 16-bit seqnum value
160
+ define_field :seqnum, Types::Int16le
161
+ # @!attribute status
162
+ # @return [Integer] 16-bit status word
163
+ define_field :status, Types::Int16le
164
+ end
165
+ Header.add_class Auth
166
+ Management.bind_header Auth, op: :and, type: 0, subtype: 11
167
+
168
+ # IEEE 802.11 Deauthentication frame
169
+ class DeAuth < SubMngt
170
+ # @!attribute reason
171
+ # @return [Integer] 16-bit reason value
172
+ define_field :reason, Types::Int16le
173
+ end
174
+ Header.add_class DeAuth
175
+ Management.bind_header DeAuth, op: :and, type: 0, subtype: 12
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,42 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ module PacketGen
7
+ module Header
8
+
9
+ # IEEE 802.1Q VLAN tagging
10
+ #
11
+ # A VLAN tag consists of:
12
+ # * a {#tci Tag Control Information} ({Types::Int16}),
13
+ # * a {#ethertype} ({Types::Int16}),
14
+ # * and a body (a {Types::String} or another Header class).
15
+ #
16
+ # == Create a Dot1q header
17
+ # # Create a IP packet in VLAN #43
18
+ # pkt = PacketGen.gen('Eth').add('Dot1q', vid: 43).add('IP')
19
+ # @author Sylvain Daubert
20
+ class Dot1q < Base
21
+ # @!attribute tci
22
+ # @return [Integer] 16-bit Tag Control Information
23
+ define_field :tci, Types::Int16
24
+ # @!attribute ethertype
25
+ # @return [Integer] 16-bit EtherType
26
+ define_field :ethertype, Types::Int16
27
+ # @!attribute body
28
+ # @return [Types::String,Header::Base]
29
+ define_field :body, Types::String
30
+
31
+ # @!attribute pcp
32
+ # @return [Integer] 3-bit Priority Code Point from {#tci}
33
+ # @!attribute dei
34
+ # @return [Boolean] Drop Eligible Indicator from {#tci}
35
+ # @!attribute vid
36
+ # @return [Integer] 12-bit VLAN ID from {#tci}
37
+ define_bit_fields_on :tci, :pcp, 3, :dei, :vid, 12
38
+ end
39
+
40
+ Eth.bind_header Dot1q, ethertype: 0x8100
41
+ end
42
+ end
@@ -0,0 +1,78 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ module PacketGen
7
+ module Header
8
+
9
+ # IEEE 802.1X / EAPOL
10
+ #
11
+ # A IEEE 802.1X header consists of:
12
+ # * a {#version} ({Types::Int8}),
13
+ # * a packet {#type} ({Types::Int8}),
14
+ # * a {#length} ({Types::Int16}),
15
+ # * and a body (a {Types::String} or another Header class).
16
+ # == Create a Dot1x header
17
+ # pkt1 = PacketGen.gen('Eth').add('Dot1x', type: 1)
18
+ # pkt2 = PacketGen.gen('Eth').add('Dot1x')
19
+ # pkt2.dot1x.type = 'EAP Packet'
20
+ # pkt2.dot1x.body.read 'body'
21
+ # @author Sylvain Daubert
22
+ class Dot1x < Base
23
+
24
+ # IEEE 802.1x Ether type
25
+ ETHERTYPE = 0x888e
26
+
27
+ # IEEE 802.1X packet types
28
+ TYPES = {
29
+ 0 => 'EAP Packet',
30
+ 1 => 'Start',
31
+ 2 => 'Logoff',
32
+ 3 => 'Key',
33
+ 4 => 'Encap-ASF-Alert'
34
+ }
35
+
36
+ # @!attribute version
37
+ # @return [Integer] 8-bit Protocol Version
38
+ define_field :version, Types::Int8, default: 1
39
+ # @!attribute type
40
+ # @return [Integer] 8-bit Packet Type
41
+ define_field :type, Types::Int8
42
+ # @!attribute length
43
+ # @return [Integer] 16-bit body length
44
+ define_field :length, Types::Int16
45
+ # @!attribute body
46
+ # @return [Types::String,Header::Base]
47
+ define_field :body, Types::String
48
+
49
+ # @private
50
+ alias old_type= type=
51
+
52
+ # Set type attribute
53
+ # @param [String,Integer] type
54
+ # @return [Integer]
55
+ def type=(type)
56
+ case type
57
+ when Integer
58
+ self.old_type = type
59
+ else
60
+ v = TYPES.key(type.to_s)
61
+ raise ArgumentError, "unknown type #{type}" if v.nil?
62
+ self.old_type = v
63
+ end
64
+ end
65
+
66
+ # Get human readable type
67
+ # @return [String]
68
+ def human_type
69
+ v = TYPES[self.type]
70
+ v = self.type if v.nil?
71
+ v.to_s
72
+ end
73
+ end
74
+
75
+ Eth.bind_header Dot1x, ethertype: Dot1x::ETHERTYPE
76
+ SNAP.bind_header Dot1x, proto_id: Dot1x::ETHERTYPE
77
+ end
78
+ end