packetgen 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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