packetgen 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -41
- data/lib/packetgen.rb +1 -1
- data/lib/packetgen/header.rb +14 -9
- data/lib/packetgen/header/arp.rb +1 -0
- data/lib/packetgen/header/base.rb +50 -1
- data/lib/packetgen/header/dot11.rb +349 -0
- data/lib/packetgen/header/dot11/control.rb +59 -0
- data/lib/packetgen/header/dot11/data.rb +43 -0
- data/lib/packetgen/header/dot11/element.rb +35 -0
- data/lib/packetgen/header/dot11/management.rb +25 -0
- data/lib/packetgen/header/dot11/sub_mngt.rb +178 -0
- data/lib/packetgen/header/dot1q.rb +42 -0
- data/lib/packetgen/header/dot1x.rb +78 -0
- data/lib/packetgen/header/esp.rb +2 -2
- data/lib/packetgen/header/eth.rb +1 -8
- data/lib/packetgen/header/ip.rb +13 -2
- data/lib/packetgen/header/ipv6.rb +12 -1
- data/lib/packetgen/header/llc.rb +56 -0
- data/lib/packetgen/inspect.rb +1 -1
- data/lib/packetgen/packet.rb +12 -8
- data/lib/packetgen/pcapng.rb +11 -0
- data/lib/packetgen/pcapng/file.rb +5 -2
- data/lib/packetgen/types.rb +1 -0
- data/lib/packetgen/types/fields.rb +80 -10
- data/lib/packetgen/types/int_string.rb +1 -1
- data/lib/packetgen/types/oui.rb +48 -0
- data/lib/packetgen/types/string.rb +9 -4
- data/lib/packetgen/types/tlv.rb +83 -6
- data/lib/packetgen/version.rb +1 -1
- metadata +12 -2
@@ -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
|