packetgen 2.1.2 → 2.1.3
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/.gitignore +1 -1
- data/README.md +10 -3
- data/bin/pgconsole +25 -28
- data/lib/packetgen/config.rb +47 -31
- data/lib/packetgen/header/arp.rb +1 -2
- data/lib/packetgen/header/asn1_base.rb +4 -0
- data/lib/packetgen/header/dns/question.rb +16 -30
- data/lib/packetgen/header/dot11.rb +73 -8
- data/lib/packetgen/header/dot11/control.rb +11 -1
- data/lib/packetgen/header/dot11/data.rb +14 -0
- data/lib/packetgen/header/dot11/element.rb +2 -0
- data/lib/packetgen/header/dot11/management.rb +43 -0
- data/lib/packetgen/header/dot11/sub_mngt.rb +84 -1
- data/lib/packetgen/header/dot1x.rb +8 -27
- data/lib/packetgen/header/ike.rb +10 -25
- data/lib/packetgen/header/ike/cert.rb +15 -31
- data/lib/packetgen/header/ike/notify.rb +35 -78
- data/lib/packetgen/header/ike/sa.rb +13 -25
- data/lib/packetgen/header/ike/ts.rb +4 -3
- data/lib/packetgen/inspect.rb +6 -4
- data/lib/packetgen/packet.rb +1 -1
- data/lib/packetgen/pcapng/epb.rb +1 -1
- data/lib/packetgen/pcapng/idb.rb +2 -2
- data/lib/packetgen/pcapng/shb.rb +1 -1
- data/lib/packetgen/pcapng/spb.rb +1 -1
- data/lib/packetgen/pcapng/unknown_block.rb +2 -2
- data/lib/packetgen/proto.rb +1 -1
- data/lib/packetgen/types.rb +1 -0
- data/lib/packetgen/types/enum.rb +165 -0
- data/lib/packetgen/types/fields.rb +29 -9
- data/lib/packetgen/types/int.rb +4 -0
- data/lib/packetgen/utils.rb +101 -0
- data/lib/packetgen/utils/arp_spoofer.rb +191 -0
- data/lib/packetgen/version.rb +1 -1
- data/packetgen.gemspec +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e306dbee54d246dd2044db6610ba27e3fb539215
|
4
|
+
data.tar.gz: 1103a3a6429fb2b4c8391750cdefa8c7d87ac323
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 592a69c18ea009c84374aa79125134ee136f0ed9050aefb8610ff484447f9cddc66685fcc3449733d2f6a1160de403d51a4465689029090815db45cdf292e12f
|
7
|
+
data.tar.gz: cf57d3f41ea4eaa30964086ec2a1127a0f2aae14a291b2fc7476819484aaa0a14a5c0681bda1f68ad7ba4aa84edc6196cb7684054ea94c22c91a5626eb2ac533
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -41,6 +41,11 @@ PacketGen.gen('Eth', src: '00:00:00:00:00:01', dst: '00:00:00:00:00:02').to_w
|
|
41
41
|
PacketGen.gen('IP', src: '192.168.1.1', dst: '192.168.1.2').to_w
|
42
42
|
# send forged IP packet over Ethernet
|
43
43
|
PacketGen.gen('Eth', src: '00:00:00:00:00:01', dst: '00:00:00:00:00:02').add('IP').to_w('eth1')
|
44
|
+
# send a IEEE 802.11 frame
|
45
|
+
PacketGen.gen('RadioTap').
|
46
|
+
add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid).
|
47
|
+
add('Dot11::DeAuth', reason: 7).
|
48
|
+
to_w('wlan0')
|
44
49
|
```
|
45
50
|
|
46
51
|
### Parse packets from binary data
|
@@ -148,9 +153,11 @@ classes. A special `config` object gives local network configuration:
|
|
148
153
|
|
149
154
|
If `pry` gem is installed, it is used as backend for `pgconsole`, else IRB is used.
|
150
155
|
|
151
|
-
##
|
156
|
+
## See also
|
152
157
|
|
153
|
-
|
158
|
+
Wiki: https://github.com/sdaubert/packetgen/wiki
|
159
|
+
|
160
|
+
API documentation: http://www.rubydoc.info/gems/packetgen
|
154
161
|
|
155
162
|
## Pull requests?
|
156
163
|
|
@@ -165,4 +172,4 @@ Copyright © 2016 Sylvain Daubert
|
|
165
172
|
All original code maintains its copyright from its original authors and licensing.
|
166
173
|
|
167
174
|
This is mainly for PcapNG (originally copied from [PacketFu](https://github.com/packetfu/packetfu),
|
168
|
-
but i am the original author
|
175
|
+
but i am the original author.
|
data/bin/pgconsole
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'packetgen'
|
4
4
|
require 'packetgen/config'
|
5
|
+
require 'packetgen/utils'
|
5
6
|
|
6
7
|
use_pry = false
|
7
8
|
begin
|
@@ -13,28 +14,25 @@ rescue LoadError
|
|
13
14
|
require 'irb/completion'
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
class PgConsole
|
18
|
+
include PacketGen
|
19
|
+
include Utils
|
17
20
|
|
18
|
-
def
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
def capture(options={})
|
23
|
-
Packet.capture(options) { |packet| yield packet if block_given? }
|
24
|
-
end
|
25
|
-
|
26
|
-
def read(filename)
|
27
|
-
Packet.read filename
|
28
|
-
end
|
29
|
-
|
30
|
-
def write(filename, packets)
|
31
|
-
Packet.write filename, packets
|
32
|
-
end
|
21
|
+
def config
|
22
|
+
PacketGen::Config.instance
|
23
|
+
end
|
33
24
|
|
34
|
-
|
25
|
+
PacketGen.singleton_methods.each do |m|
|
26
|
+
define_method m, PacketGen.method(m).to_proc
|
27
|
+
end
|
35
28
|
|
36
|
-
|
37
|
-
|
29
|
+
Utils.singleton_methods.each do |m|
|
30
|
+
define_method m, Utils.method(m).to_proc
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_binding
|
34
|
+
binding
|
35
|
+
end
|
38
36
|
end
|
39
37
|
|
40
38
|
def start_message(use_pry)
|
@@ -47,21 +45,21 @@ if use_pry
|
|
47
45
|
Pry.config.prompt = [
|
48
46
|
proc { |target_self, nest_level, pry|
|
49
47
|
"#{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
|
50
|
-
},
|
51
|
-
proc { |target_self, nest_level, pry|
|
52
|
-
"#{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
|
48
|
+
},
|
49
|
+
proc { |target_self, nest_level, pry|
|
50
|
+
"#{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
|
53
51
|
}
|
54
52
|
]
|
55
53
|
Pry.config.prompt_name = 'pg'
|
56
|
-
|
54
|
+
PgConsole.new.get_binding.pry
|
57
55
|
else
|
58
56
|
IRB.setup nil
|
59
|
-
irb = IRB::Irb.new(IRB::WorkSpace.new(
|
57
|
+
irb = IRB::Irb.new(IRB::WorkSpace.new(PgConsole.new.get_binding))
|
60
58
|
IRB.conf[:MAIN_CONTEXT] = irb.context
|
61
59
|
irb.context.auto_indent_mode = true
|
62
|
-
irb.context.prompt_i = "pg
|
63
|
-
irb.context.prompt_s = "pg
|
64
|
-
irb.context.prompt_c = "pg
|
60
|
+
irb.context.prompt_i = "pg> "
|
61
|
+
irb.context.prompt_s = "pg* "
|
62
|
+
irb.context.prompt_c = "pg* "
|
65
63
|
|
66
64
|
trap("SIGINT") do
|
67
65
|
irb.signal_handle
|
@@ -75,4 +73,3 @@ else
|
|
75
73
|
IRB.irb_at_exit
|
76
74
|
end
|
77
75
|
end
|
78
|
-
|
data/lib/packetgen/config.rb
CHANGED
@@ -3,52 +3,68 @@
|
|
3
3
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
4
|
# This program is published under MIT license.
|
5
5
|
|
6
|
-
require 'network_interface'
|
7
6
|
require 'socket'
|
7
|
+
require 'singleton'
|
8
|
+
require 'network_interface'
|
8
9
|
|
9
10
|
module PacketGen
|
10
11
|
|
11
12
|
# Config class to provide +config+ object to pgconsole
|
12
13
|
# @author Sylvain Daubert
|
13
14
|
# @author Kent 'picat' Gruber
|
15
|
+
# @since 2.1.3 Config is singleton
|
14
16
|
class Config
|
17
|
+
include Singleton
|
15
18
|
|
16
19
|
# Default network interface
|
17
20
|
# @return [String]
|
18
|
-
attr_reader :
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
attr_reader :default_iface
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
begin
|
25
|
+
default_iface = Pcap.lookupdev
|
26
|
+
rescue PCAPRUB::BindingError
|
27
|
+
default_iface = NetworkInterface.interfaces.select { |i| i =~ /lo/ }.first
|
28
|
+
end
|
29
|
+
@default_iface = default_iface
|
30
|
+
@hwaddr = {}
|
31
|
+
@ipaddr = {}
|
32
|
+
@ip6addr = {}
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
NetworkInterface.interfaces.each do |iface|
|
35
|
+
addresses = NetworkInterface.addresses(iface)
|
36
|
+
@hwaddr[iface] = case RbConfig::CONFIG['target_os']
|
37
|
+
when /darwin/
|
38
|
+
addresses[Socket::AF_LINK][0]['addr'] if addresses[Socket::AF_LINK]
|
39
|
+
else
|
40
|
+
addresses[Socket::AF_PACKET][0]['addr'] if addresses[Socket::AF_PACKET]
|
41
|
+
end
|
42
|
+
@ipaddr[iface] = addresses[Socket::AF_INET][0]['addr'] if addresses[Socket::AF_INET]
|
43
|
+
if addresses[Socket::AF_INET6]
|
44
|
+
@ip6addr[iface] = addresses[Socket::AF_INET6].map { |hsh| hsh['addr'] }
|
39
45
|
end
|
40
46
|
end
|
41
|
-
|
47
|
+
end
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
# Get MAC address for given network interface
|
50
|
+
# @param [String,nil] iface network interface. Il +nil+, use default one.
|
51
|
+
# @return [String]
|
52
|
+
def hwaddr(iface=nil)
|
53
|
+
@hwaddr[iface || @default_iface]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get IP address for given network interface
|
57
|
+
# @param [String,nil] iface network interface. Il +nil+, use default one.
|
58
|
+
# @return [String]
|
59
|
+
def ipaddr(iface=nil)
|
60
|
+
@ipaddr[iface || @default_iface]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get IPv6 addresses for given network interface
|
64
|
+
# @param [String,nil] iface network interface. Il +nil+, use default one.
|
65
|
+
# @return [Array<String>]
|
66
|
+
def ip6addr(iface=nil)
|
67
|
+
@ip6addr[iface || @default_iface]
|
52
68
|
end
|
53
69
|
end
|
54
70
|
end
|
data/lib/packetgen/header/arp.rb
CHANGED
@@ -48,7 +48,7 @@ module PacketGen
|
|
48
48
|
# @!attribute op
|
49
49
|
# 16-bit operation code
|
50
50
|
# # @return [Integer]
|
51
|
-
define_field :op, Types::
|
51
|
+
define_field :op, Types::Int16Enum, enum: { 'request' => 1, 'reply' => 2 }
|
52
52
|
# @!attribute sha
|
53
53
|
# source hardware address
|
54
54
|
# @return [Eth::MacAddr]
|
@@ -119,4 +119,3 @@ module PacketGen
|
|
119
119
|
Dot1q.bind_header ARP, ethertype: 0x806
|
120
120
|
end
|
121
121
|
end
|
122
|
-
|
@@ -8,6 +8,8 @@ module PacketGen
|
|
8
8
|
module Header
|
9
9
|
|
10
10
|
# @abstract Base class for ASN.1 header types.
|
11
|
+
# This class implement minimal {Base} API to mimic a {Base} object.
|
12
|
+
#
|
11
13
|
# Subclasses may define magic methods:
|
12
14
|
# * {#parse?}.
|
13
15
|
# @author Sylvain Daubert
|
@@ -56,6 +58,8 @@ module PacketGen
|
|
56
58
|
@method_name = protocol_name.downcase.sub(/::/, '_')
|
57
59
|
end
|
58
60
|
|
61
|
+
# Called by {Packet#parse} when guessing first header to check if header
|
62
|
+
# is correct
|
59
63
|
# @return [true]
|
60
64
|
def parse?
|
61
65
|
true
|
@@ -6,19 +6,6 @@ module PacketGen
|
|
6
6
|
# @author Sylvain Daubert
|
7
7
|
class Question < Base
|
8
8
|
|
9
|
-
# @!attribute name
|
10
|
-
# Question domain name
|
11
|
-
# @return [String]
|
12
|
-
define_field :name, Name, default: '.'
|
13
|
-
# @!attribute type
|
14
|
-
# 16-bit question type
|
15
|
-
# @return [Integer]
|
16
|
-
define_field :type, Types::Int16, default: 1
|
17
|
-
# @!attribute rrclass
|
18
|
-
# 16-bit question class
|
19
|
-
# @return [Integer]
|
20
|
-
define_field :rrclass, Types::Int16, default: 1
|
21
|
-
|
22
9
|
# Ressource Record types
|
23
10
|
TYPES = {
|
24
11
|
'A' => 1,
|
@@ -49,7 +36,7 @@ module PacketGen
|
|
49
36
|
'TKEY' => 249,
|
50
37
|
'TSIG' => 250,
|
51
38
|
'*' => 255
|
52
|
-
}
|
39
|
+
}.freeze
|
53
40
|
|
54
41
|
# Ressource Record classes
|
55
42
|
CLASSES = {
|
@@ -58,7 +45,20 @@ module PacketGen
|
|
58
45
|
'HS' => 4,
|
59
46
|
'NONE' => 254,
|
60
47
|
'*' => 255
|
61
|
-
}
|
48
|
+
}.freeze
|
49
|
+
|
50
|
+
# @!attribute name
|
51
|
+
# Question domain name
|
52
|
+
# @return [String]
|
53
|
+
define_field :name, Name, default: '.'
|
54
|
+
# @!attribute type
|
55
|
+
# 16-bit question type
|
56
|
+
# @return [Integer]
|
57
|
+
define_field :type, Types::Int16Enum, default: 1, enum: TYPES
|
58
|
+
# @!attribute rrclass
|
59
|
+
# 16-bit question class
|
60
|
+
# @return [Integer]
|
61
|
+
define_field :rrclass, Types::Int16Enum, default: 1, enum: CLASSES
|
62
62
|
|
63
63
|
# @param [DNS] dns
|
64
64
|
# @param [Hash] options
|
@@ -72,20 +72,6 @@ module PacketGen
|
|
72
72
|
self.rrclass = options[:rrclass] if options[:rrclass]
|
73
73
|
end
|
74
74
|
|
75
|
-
# Setter for type
|
76
|
-
# @param [Integer] val
|
77
|
-
# @return [Integer,String]
|
78
|
-
def type=(val)
|
79
|
-
v = case val
|
80
|
-
when String
|
81
|
-
self.class::TYPES[val.upcase]
|
82
|
-
else
|
83
|
-
val
|
84
|
-
end
|
85
|
-
raise ArgumentError, "unknown type #{val.inspect}" unless v
|
86
|
-
self[:type].read v
|
87
|
-
end
|
88
|
-
|
89
75
|
# Setter for class
|
90
76
|
# @param [Integer] val
|
91
77
|
# @return [Integer,String]
|
@@ -109,7 +95,7 @@ module PacketGen
|
|
109
95
|
|
110
96
|
# Get human readable type
|
111
97
|
# @return [String]
|
112
|
-
|
98
|
+
def human_type
|
113
99
|
self.class::TYPES.key(type) || "0x%04x" % type
|
114
100
|
end
|
115
101
|
|
@@ -50,7 +50,14 @@ module PacketGen
|
|
50
50
|
# Check version field
|
51
51
|
# @see [Base#parse?]
|
52
52
|
def parse?
|
53
|
-
version == 0
|
53
|
+
version == 0 and length >= 8
|
54
|
+
end
|
55
|
+
|
56
|
+
# Calculate length field
|
57
|
+
# @return [Integer] calculated length
|
58
|
+
# @since 2.1.3
|
59
|
+
def calc_length
|
60
|
+
self[:length].value = self.sz - self[:body].sz
|
54
61
|
end
|
55
62
|
|
56
63
|
# send PPI packet on wire. Dot11 FCS trailer should be set.
|
@@ -64,7 +71,7 @@ module PacketGen
|
|
64
71
|
end
|
65
72
|
self.add_class PPI
|
66
73
|
|
67
|
-
# Radiotap header
|
74
|
+
# Radiotap header (see http://www.radiotap.org/)
|
68
75
|
# @author Sylvain Daubert
|
69
76
|
class RadioTap < Base
|
70
77
|
# @!attribute version
|
@@ -75,7 +82,7 @@ module PacketGen
|
|
75
82
|
define_field :pad, Types::Int8, default: 0
|
76
83
|
# @!attribute length
|
77
84
|
# @return [Integer] 16-bit RadioTap header length
|
78
|
-
define_field :length, Types::Int16le
|
85
|
+
define_field :length, Types::Int16le, default: 8
|
79
86
|
# @!attribute present_flags
|
80
87
|
# @return [Integer] 32-bit integer
|
81
88
|
define_field :present_flags, Types::Int32le
|
@@ -103,7 +110,14 @@ module PacketGen
|
|
103
110
|
# Check version field
|
104
111
|
# @see [Base#parse?]
|
105
112
|
def parse?
|
106
|
-
version == 0
|
113
|
+
version == 0 and length >= 8
|
114
|
+
end
|
115
|
+
|
116
|
+
# Calculate length field
|
117
|
+
# @return [Integer] calculated length
|
118
|
+
# @since 2.1.3
|
119
|
+
def calc_length
|
120
|
+
self[:length].value = self.sz - self[:body].sz
|
107
121
|
end
|
108
122
|
|
109
123
|
# send RadioTap packet on wire. Dot11 FCS trailer should be set.
|
@@ -120,7 +134,7 @@ module PacketGen
|
|
120
134
|
# IEEE 802.11 header
|
121
135
|
# @abstract This is a base class to demultiplex different IEEE 802.11 frames when
|
122
136
|
# parsing.
|
123
|
-
# A IEEE 802.11 header may
|
137
|
+
# A IEEE 802.11 header may consist of at least:
|
124
138
|
# * a {#frame_ctrl} ({Types::Int16}),
|
125
139
|
# * a {#id}/duration ({Types::Int16le}),
|
126
140
|
# * and a {#mac1} ({Eth::MacAddr}).
|
@@ -134,10 +148,52 @@ module PacketGen
|
|
134
148
|
# * a {#body} (a {Types::String} or another {Base} class),
|
135
149
|
# * a Frame check sequence ({#fcs}, of type {Types::Int32le})
|
136
150
|
#
|
137
|
-
# ==
|
151
|
+
# == Header accessors
|
138
152
|
# As Dot11 header types are defined under Dot11 namespace, Dot11 header accessors
|
139
153
|
# have a specific name. By example, to access to a {Dot11::Beacon} header,
|
140
154
|
# accessor is +#dot11_beacon+.
|
155
|
+
#
|
156
|
+
# == Create Dot11 packets
|
157
|
+
# As {Dot11} is an abstract class, you have to use one of its subclasses to
|
158
|
+
# instanciate a IEEE802.11 header.
|
159
|
+
#
|
160
|
+
# === IEEE802.11 control frames
|
161
|
+
# Control frames may be created this way:
|
162
|
+
# pkt = PacketGen.gen('Dot11::Control', subtype: 13) # Ack control frame
|
163
|
+
# pkt.dot11_control # => PacketGen::Header::Dot11::Control
|
164
|
+
#
|
165
|
+
# === IEEE802.11 management frames
|
166
|
+
# Management frames may be created this way:
|
167
|
+
# pkt = PacketGen.gen('Dot11::Management')
|
168
|
+
# pkt.dot11_management # => PacketGen::Header::Dot11::Management
|
169
|
+
# Management frames are usually specialized, AssociationRequest by example:
|
170
|
+
# pkt.add('Dot11::AssoReq')
|
171
|
+
# pkt.dot11_assoreq # => PacketGen::Header::Dot11::AssoReq
|
172
|
+
# Management frames also may contain some elements (see IEEE 802.11 standard):
|
173
|
+
# pkt.dot11_assoreq.add_elements(type: 'SSID', value: "My SSID")
|
174
|
+
# pkt.dot11_assoreq.add_elements(type: 'Rates', value: supported_rates)
|
175
|
+
#
|
176
|
+
# === IEEE802.11 data frames
|
177
|
+
# Data frames may be created this way:
|
178
|
+
# pkt = PacketGen.gen('Dot11::Data')
|
179
|
+
# pkt.dot11_data # => PacketGen::Header::Dot11::Data
|
180
|
+
#
|
181
|
+
# == Parse Dot11 packets
|
182
|
+
# When parsing a Dot11 packet, Dot11 subclass is created from +type+ value.
|
183
|
+
# Dot11 header should then be accessed through +Packet#dot11_management+,
|
184
|
+
# +Packet#dot11_control+ or +Packet#dot11_data+.
|
185
|
+
#
|
186
|
+
# A +Packet#dot11+ may exist for unknown types.
|
187
|
+
#
|
188
|
+
# == Send Dot11 packets
|
189
|
+
# To send a Dot11 packet, a RadioTap header is needed:
|
190
|
+
# pkt = PacketGen.gen('RadioTap')
|
191
|
+
# pkt.add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid)
|
192
|
+
# pkt.add('Dot11::Beacon')
|
193
|
+
# pkt.dot11_beacon.add_element(type: 'SSID', value: 'My SSID')
|
194
|
+
# pkt.dot11_beacon.add_element(type: 'Rates', value: "\x85\x0c")
|
195
|
+
# pkt.calc
|
196
|
+
# pkt.to_w('wlan0')
|
141
197
|
# @author Sylvain Daubert
|
142
198
|
class Dot11 < Base
|
143
199
|
|
@@ -211,6 +267,15 @@ module PacketGen
|
|
211
267
|
define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
|
212
268
|
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds
|
213
269
|
|
270
|
+
|
271
|
+
# @!attribute sequence_number (12-bit field from {#sequence_ctrl})
|
272
|
+
# @return [Integer]
|
273
|
+
# @since 2.1.3
|
274
|
+
# @!attribute fragment_number (4-bit field from {#sequence_ctrl})
|
275
|
+
# @return [Integer]
|
276
|
+
# @since 2.1.3
|
277
|
+
define_bit_fields_on :sequence_ctrl, :sequence_number, 12, :fragment_number, 4
|
278
|
+
|
214
279
|
alias duration id
|
215
280
|
# @private
|
216
281
|
alias old_fields fields
|
@@ -302,7 +367,7 @@ module PacketGen
|
|
302
367
|
pcap = PCAPRUB::Pcap.open_live(iface, PCAP_SNAPLEN, PCAP_PROMISC,
|
303
368
|
PCAP_TIMEOUT)
|
304
369
|
str = self.to_s
|
305
|
-
pcap.inject str
|
370
|
+
pcap.inject str
|
306
371
|
end
|
307
372
|
|
308
373
|
private
|
@@ -317,7 +382,7 @@ module PacketGen
|
|
317
382
|
unless @applicable_fields.include? :ht_ctrl
|
318
383
|
idx = @applicable_fields.index(:body)
|
319
384
|
@applicable_fields[idx, 0] = :ht_ctrl
|
320
|
-
|
385
|
+
end
|
321
386
|
else
|
322
387
|
@applicable_fields -= %i(ht_ctrl)
|
323
388
|
end
|