packetgen 3.3.2 → 4.0.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 +37 -21
- data/lib/packetgen/capture.rb +2 -2
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +7 -7
- data/lib/packetgen/header/arp.rb +13 -13
- data/lib/packetgen/header/asn1_base.rb +1 -1
- data/lib/packetgen/header/base.rb +17 -18
- data/lib/packetgen/header/bootp.rb +32 -34
- data/lib/packetgen/header/dhcp/option.rb +19 -19
- data/lib/packetgen/header/dhcp/options.rb +1 -1
- data/lib/packetgen/header/dhcp.rb +3 -3
- data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
- data/lib/packetgen/header/dhcpv6/option.rb +53 -53
- data/lib/packetgen/header/dhcpv6/options.rb +1 -1
- data/lib/packetgen/header/dhcpv6/relay.rb +5 -5
- data/lib/packetgen/header/dhcpv6.rb +6 -6
- data/lib/packetgen/header/dns/name.rb +14 -10
- data/lib/packetgen/header/dns/opt.rb +2 -2
- data/lib/packetgen/header/dns/option.rb +11 -11
- data/lib/packetgen/header/dns/qdsection.rb +1 -1
- data/lib/packetgen/header/dns/question.rb +6 -8
- data/lib/packetgen/header/dns/rr.rb +56 -43
- data/lib/packetgen/header/dns/rrsection.rb +4 -4
- data/lib/packetgen/header/dns.rb +27 -30
- data/lib/packetgen/header/dot11/control.rb +11 -11
- data/lib/packetgen/header/dot11/data.rb +20 -20
- data/lib/packetgen/header/dot11/element.rb +4 -4
- data/lib/packetgen/header/dot11/management.rb +8 -8
- data/lib/packetgen/header/dot11/sub_mngt.rb +39 -53
- data/lib/packetgen/header/dot11.rb +88 -93
- data/lib/packetgen/header/dot1q.rb +10 -12
- data/lib/packetgen/header/dot1x.rb +9 -9
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +6 -6
- data/lib/packetgen/header/eap/tls.rb +13 -15
- data/lib/packetgen/header/eap/ttls.rb +13 -15
- data/lib/packetgen/header/eap.rb +22 -22
- data/lib/packetgen/header/eth.rb +18 -18
- data/lib/packetgen/header/gre.rb +8 -10
- data/lib/packetgen/header/http/headers.rb +2 -2
- data/lib/packetgen/header/http/request.rb +17 -16
- data/lib/packetgen/header/http/response.rb +18 -17
- data/lib/packetgen/header/http/verbs.rb +1 -3
- data/lib/packetgen/header/icmp.rb +8 -8
- data/lib/packetgen/header/icmpv6.rb +3 -3
- data/lib/packetgen/header/igmp.rb +8 -8
- data/lib/packetgen/header/igmpv3/group_record.rb +12 -12
- data/lib/packetgen/header/igmpv3/mq.rb +16 -18
- data/lib/packetgen/header/igmpv3/mr.rb +4 -4
- data/lib/packetgen/header/igmpv3.rb +7 -7
- data/lib/packetgen/header/ip/addr.rb +13 -13
- data/lib/packetgen/header/ip/option.rb +31 -33
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +37 -72
- data/lib/packetgen/header/ipv6/addr.rb +14 -14
- data/lib/packetgen/header/ipv6/extension.rb +8 -8
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +9 -9
- data/lib/packetgen/header/ipv6.rb +20 -22
- data/lib/packetgen/header/llc.rb +17 -17
- data/lib/packetgen/header/mdns.rb +1 -1
- data/lib/packetgen/header/mld.rb +6 -6
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +11 -11
- data/lib/packetgen/header/mldv2/mlq.rb +21 -23
- data/lib/packetgen/header/mldv2/mlr.rb +8 -8
- data/lib/packetgen/header/ospfv2/db_description.rb +11 -12
- data/lib/packetgen/header/ospfv2/hello.rb +11 -11
- data/lib/packetgen/header/ospfv2/ls_ack.rb +1 -1
- data/lib/packetgen/header/ospfv2/ls_request.rb +9 -9
- data/lib/packetgen/header/ospfv2/ls_update.rb +3 -3
- data/lib/packetgen/header/ospfv2/lsa.rb +54 -58
- data/lib/packetgen/header/ospfv2/lsa_header.rb +9 -9
- data/lib/packetgen/header/ospfv2.rb +27 -29
- data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
- data/lib/packetgen/header/ospfv3/hello.rb +12 -12
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +17 -19
- data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
- data/lib/packetgen/header/ospfv3/ls_request.rb +9 -9
- data/lib/packetgen/header/ospfv3/ls_update.rb +4 -4
- data/lib/packetgen/header/ospfv3/lsa.rb +48 -51
- data/lib/packetgen/header/ospfv3/lsa_header.rb +9 -9
- data/lib/packetgen/header/ospfv3.rb +25 -27
- data/lib/packetgen/header/sctp/chunk.rb +44 -41
- data/lib/packetgen/header/sctp/error.rb +52 -52
- data/lib/packetgen/header/sctp/parameter.rb +38 -38
- data/lib/packetgen/header/sctp.rb +5 -5
- data/lib/packetgen/header/snmp.rb +2 -2
- data/lib/packetgen/header/tcp/option.rb +45 -39
- data/lib/packetgen/header/tcp/options.rb +2 -2
- data/lib/packetgen/header/tcp.rb +55 -44
- data/lib/packetgen/header/tftp.rb +16 -16
- data/lib/packetgen/header/udp.rb +8 -8
- data/lib/packetgen/header.rb +9 -10
- data/lib/packetgen/headerable.rb +13 -3
- data/lib/packetgen/inspect.rb +2 -2
- data/lib/packetgen/packet.rb +54 -37
- data/lib/packetgen/pcap.rb +15 -4
- data/lib/packetgen/pcapng/block.rb +18 -17
- data/lib/packetgen/pcapng/epb.rb +13 -15
- data/lib/packetgen/pcapng/file.rb +3 -97
- data/lib/packetgen/pcapng/idb.rb +9 -11
- data/lib/packetgen/pcapng/shb.rb +13 -15
- data/lib/packetgen/pcapng/spb.rb +8 -10
- data/lib/packetgen/pcapng/unknown_block.rb +6 -17
- data/lib/packetgen/pcapng.rb +4 -4
- data/lib/packetgen/pcaprub_wrapper.rb +17 -1
- data/lib/packetgen/proto.rb +1 -1
- data/lib/packetgen/unknown_packet.rb +2 -2
- data/lib/packetgen/utils/arp_spoofer.rb +18 -19
- data/lib/packetgen/utils.rb +2 -2
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +4 -3
- metadata +34 -29
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 984125cdf335b4573a862ed481c155740f07588e10263da4a35455a9d2d4f803
|
4
|
+
data.tar.gz: 01df13a9c405ba0887a540b952eb8ddea6c1dd8f58adfc1689b8ec0c628b14f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bec2e6720c1a658f777826dc2b7ad81b3cc1addeee5dd99b147357b005151b69d4df3b9c02fd529644a9dd9634106da3fb2b5d73d892769d85d7ef480347e7d7
|
7
|
+
data.tar.gz: 897ebe8f59b88ad3b72eb8edc5a9a23f46228fda646453e2878a3b6a534d53620d58c5ec1396f5632727577a41cbab565d42f50714d9138e907a63de7e3d804d
|
data/README.md
CHANGED
@@ -1,20 +1,27 @@
|
|
1
1
|
|
2
2
|
[](https://badge.fury.io/rb/packetgen)
|
3
3
|
[](https://github.com/lemontree55/packetgen/actions?query=workflow%3Aci)
|
4
|
+
|
4
5
|
# PacketGen
|
5
6
|
|
6
7
|
PacketGen provides simple ways to generate, send and capture network packets.
|
7
8
|
|
8
9
|
## Installation
|
10
|
+
|
9
11
|
PacketGen depends on PcapRub, which needs pcap development files to install. On Debian, you have to do:
|
10
12
|
|
11
|
-
|
13
|
+
```bash
|
14
|
+
sudo apt install libpcap-dev
|
15
|
+
```
|
12
16
|
|
13
17
|
Installation using RubyGems is then easy:
|
14
18
|
|
15
|
-
|
19
|
+
```bash
|
20
|
+
gem install packetgen
|
21
|
+
```
|
16
22
|
|
17
23
|
Or add it to a Gemfile:
|
24
|
+
|
18
25
|
```ruby
|
19
26
|
gem 'packetgen'
|
20
27
|
```
|
@@ -22,6 +29,7 @@ gem 'packetgen'
|
|
22
29
|
## Usage
|
23
30
|
|
24
31
|
### Easily create packets
|
32
|
+
|
25
33
|
```ruby
|
26
34
|
PacketGen.gen('IP') # generate a IP packet object
|
27
35
|
PacketGen.gen('TCP') # generate a TCP over IP packet object
|
@@ -37,6 +45,7 @@ PacketGen.gen('IP').to_s
|
|
37
45
|
```
|
38
46
|
|
39
47
|
### Send packets on wire
|
48
|
+
|
40
49
|
```ruby
|
41
50
|
# send Ethernet packet
|
42
51
|
PacketGen.gen('Eth', src: '00:00:00:00:00:01', dst: '00:00:00:00:00:02').to_w
|
@@ -52,11 +61,13 @@ PacketGen.gen('RadioTap').
|
|
52
61
|
```
|
53
62
|
|
54
63
|
### Parse packets from binary data
|
64
|
+
|
55
65
|
```ruby
|
56
66
|
packet = PacketGen.parse(binary_data)
|
57
67
|
```
|
58
68
|
|
59
69
|
### Capture packets from wire
|
70
|
+
|
60
71
|
```ruby
|
61
72
|
# Capture packets from first network interface, action from a block
|
62
73
|
PacketGen.capture do |packet|
|
@@ -71,6 +82,7 @@ packets = PacketGen.capture(iface: 'eth0', filter: 'ip src 1.1.1.2', max: 1)
|
|
71
82
|
```
|
72
83
|
|
73
84
|
### Easily manipulate packets
|
85
|
+
|
74
86
|
```ruby
|
75
87
|
# access header fields
|
76
88
|
pkt = PacketGen.gen('IP').add('TCP')
|
@@ -96,6 +108,7 @@ pkt2.decapsulate(pkt2.ip) # pkt2 is now inner IP/TCP packet
|
|
96
108
|
```
|
97
109
|
|
98
110
|
### Read/write PcapNG files
|
111
|
+
|
99
112
|
```ruby
|
100
113
|
# read a PcapNG file, containing multiple packets
|
101
114
|
packets = PacketGen.read('file.pcapng')
|
@@ -107,14 +120,16 @@ PacketGen.write('more_packets.pcapng', packets)
|
|
107
120
|
```
|
108
121
|
|
109
122
|
### Add custom header/protocol
|
110
|
-
|
123
|
+
|
124
|
+
PacketGen permits adding your own header classes.
|
125
|
+
|
111
126
|
First, define the new header class. For example:
|
112
127
|
|
113
128
|
```ruby
|
114
129
|
module MyModule
|
115
130
|
class MyHeader < PacketGen::Header::Base
|
116
|
-
|
117
|
-
|
131
|
+
define_attr :field1, BinStruct::Int32
|
132
|
+
define_attr :field2, BinStruct::Int32
|
118
133
|
end
|
119
134
|
end
|
120
135
|
```
|
@@ -135,24 +150,27 @@ PacketGen::Header::IP.bind_header MyModule::MyHeader, protocol: 254
|
|
135
150
|
And use it:
|
136
151
|
|
137
152
|
```ruby
|
138
|
-
pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678)
|
139
|
-
pkt.
|
153
|
+
pkt = Packet.gen('IP').add('MyHeader', field1: 0x12345678, field2: 0x87654321)
|
154
|
+
pkt.to_w # Send it on wire
|
140
155
|
```
|
141
156
|
|
142
157
|
## Interactive console
|
158
|
+
|
143
159
|
PacketGen provides an interactive console: `pgconsole`.
|
144
160
|
|
145
161
|
In this console, context includes PacketGen module to give direct access to PacketGen
|
146
162
|
classes. A special `config` object gives local network configuration:
|
147
163
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
164
|
+
```text
|
165
|
+
$ pgconsole
|
166
|
+
pg(main)> config
|
167
|
+
=> #<PacketGen::Config:0x00559f27d2afe8
|
168
|
+
@hwaddr="75:74:73:72:71:70",
|
169
|
+
@iface="eth0",
|
170
|
+
@ipaddr="192.168.0.2">
|
171
|
+
pg(main)> packets = capture(max: 5)
|
172
|
+
pg(main)> exit
|
173
|
+
```
|
156
174
|
|
157
175
|
If `pry` gem is installed, it is used as backend for `pgconsole`, else IRB is used.
|
158
176
|
|
@@ -167,20 +185,18 @@ Available plugins (available as gem) are:
|
|
167
185
|
|
168
186
|
## See also
|
169
187
|
|
170
|
-
Wiki: https://github.com/lemontree55/packetgen/wiki
|
188
|
+
Wiki: <https://github.com/lemontree55/packetgen/wiki>
|
171
189
|
|
172
|
-
API documentation: http://www.rubydoc.info/gems/packetgen
|
190
|
+
API documentation: <http://www.rubydoc.info/gems/packetgen>
|
173
191
|
|
174
192
|
## Contributing
|
175
193
|
|
176
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/lemontree55/packetgen
|
194
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/lemontree55/packetgen>.
|
177
195
|
|
178
196
|
## License
|
179
197
|
|
180
198
|
MIT License (see [LICENSE](https://github.com/lemontree55/packetgen/blob/master/LICENSE))
|
181
199
|
|
182
200
|
### Other sources
|
183
|
-
All original code maintains its copyright from its original authors and licensing.
|
184
201
|
|
185
|
-
|
186
|
-
but i am the original author.
|
202
|
+
All original code maintains its copyright from its original authors and licensing.
|
data/lib/packetgen/capture.rb
CHANGED
@@ -61,7 +61,7 @@ module PacketGen
|
|
61
61
|
@packets = []
|
62
62
|
@raw_packets = []
|
63
63
|
@timestamps = []
|
64
|
-
set_options
|
64
|
+
set_options(iface, max, timeout, filter, promisc, parse, snaplen, monitor)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Start capture
|
@@ -75,7 +75,7 @@ module PacketGen
|
|
75
75
|
# @author Sylvain Daubert
|
76
76
|
# @author optix2000 - add monitor argument
|
77
77
|
def start(iface: nil, max: nil, timeout: nil, filter: nil, promisc: false, parse: true, snaplen: nil, monitor: nil, &block)
|
78
|
-
set_options
|
78
|
+
set_options(iface, max, timeout, filter, promisc, parse, snaplen, monitor)
|
79
79
|
|
80
80
|
@cap_thread = Thread.new do
|
81
81
|
PCAPRUBWrapper.capture(**capture_args) do |packet|
|
data/lib/packetgen/config.rb
CHANGED
@@ -8,7 +8,7 @@ module PacketGen
|
|
8
8
|
module Deprecation
|
9
9
|
# Default remove version for deprecated classes/methods
|
10
10
|
# @since 3.1.0
|
11
|
-
REMOVE_VERSION = '
|
11
|
+
REMOVE_VERSION = '5.0.0'
|
12
12
|
|
13
13
|
# @private
|
14
14
|
# @param [String] remove_version
|
@@ -32,10 +32,10 @@ module PacketGen
|
|
32
32
|
complete_new_method_name = "#{base_name}#{new_method}" unless new_method.nil?
|
33
33
|
|
34
34
|
file, line = caller(2..2).first.split(':')[0, 2]
|
35
|
-
message =
|
35
|
+
message = "#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
|
36
36
|
message << " in favor of #{complete_new_method_name}" unless new_method.nil?
|
37
37
|
message << '. ' << self.removed(remove_version)
|
38
|
-
warn
|
38
|
+
warn(message)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Warn when using a deprecated method
|
@@ -46,10 +46,10 @@ module PacketGen
|
|
46
46
|
# @since 3.1.0
|
47
47
|
def self.deprecated_class(klass, new_klass=nil, remove_version: REMOVE_VERSION)
|
48
48
|
file, line = caller(2..2).first.split(':')[0, 2]
|
49
|
-
message =
|
49
|
+
message = "#{file}:#{line}: #{klass} is deprecated"
|
50
50
|
message << " in favor of #{new_klass}" unless new_klass.nil?
|
51
51
|
message << '. ' << self.removed(remove_version)
|
52
|
-
warn
|
52
|
+
warn(message)
|
53
53
|
end
|
54
54
|
|
55
55
|
# Warn when using a deprecated method's option
|
@@ -64,9 +64,9 @@ module PacketGen
|
|
64
64
|
def self.deprecated_option(klass, method, option, klass_method: false, remove_version: REMOVE_VERSION)
|
65
65
|
base_name = "#{klass}#{klass_method ? '.' : '#'}"
|
66
66
|
method_name = "#{base_name}#{method}"
|
67
|
-
message =
|
67
|
+
message = "option #{option} is deprecated for method #{method_name}. "
|
68
68
|
message << self.removed(remove_version)
|
69
|
-
warn
|
69
|
+
warn(message)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
data/lib/packetgen/header/arp.rb
CHANGED
@@ -9,9 +9,9 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
# An ARP header consists of:
|
12
|
-
# * a hardware type ({#hrd} or {#htype}) field ({
|
12
|
+
# * a hardware type ({#hrd} or {#htype}) field ({BinStruct::Int16}),
|
13
13
|
# * a protocol type ({#pro} or {#ptype}) field (+Int16+),
|
14
|
-
# * a hardware address length ({#hln} or {#hlen}) field ({
|
14
|
+
# * a hardware address length ({#hln} or {#hlen}) field ({BinStruct::Int8}),
|
15
15
|
# * a protocol address length ({#pln} or {#plen}) field (+Int8+),
|
16
16
|
# * a {#opcode} (or {#op}) field (+Int16+),
|
17
17
|
# * a source hardware address ({#sha} or {#src_mac}) field ({Eth::MacAddr}),
|
@@ -33,42 +33,42 @@ module PacketGen
|
|
33
33
|
# @!attribute hrd
|
34
34
|
# 16-bit hardware protocol type
|
35
35
|
# # @return [Integer]
|
36
|
-
|
36
|
+
define_attr :hrd, BinStruct::Int16, default: 1
|
37
37
|
# @!attribute pro
|
38
38
|
# 16-bit internet protocol type
|
39
39
|
# # @return [Integer]
|
40
|
-
|
40
|
+
define_attr :pro, BinStruct::Int16, default: 0x800
|
41
41
|
# @!attribute hln
|
42
42
|
# 8-bit hardware address length
|
43
43
|
# # @return [Integer]
|
44
|
-
|
44
|
+
define_attr :hln, BinStruct::Int8, default: 6
|
45
45
|
# @!attribute pln
|
46
46
|
# 8-bit internet address length
|
47
47
|
# # @return [Integer]
|
48
|
-
|
48
|
+
define_attr :pln, BinStruct::Int8, default: 4
|
49
49
|
# @!attribute op
|
50
50
|
# 16-bit operation code
|
51
51
|
# # @return [Integer]
|
52
|
-
|
52
|
+
define_attr :op, BinStruct::Int16Enum, enum: { 'request' => 1, 'reply' => 2 }
|
53
53
|
# @!attribute sha
|
54
54
|
# source hardware address
|
55
55
|
# @return [Eth::MacAddr]
|
56
|
-
|
56
|
+
define_attr :sha, Eth::MacAddr
|
57
57
|
# @!attribute spa
|
58
58
|
# source protocol address
|
59
59
|
# @return [IP::Addr]
|
60
|
-
|
60
|
+
define_attr :spa, IP::Addr
|
61
61
|
# @!attribute tha
|
62
62
|
# target hardware address
|
63
63
|
# @return [Eth::MacAddr]
|
64
|
-
|
64
|
+
define_attr :tha, Eth::MacAddr
|
65
65
|
# @!attribute tpa
|
66
66
|
# target protocol address
|
67
67
|
# @return [IP::Addr]
|
68
|
-
|
68
|
+
define_attr :tpa, IP::Addr
|
69
69
|
# @!attribute body
|
70
|
-
# @return [
|
71
|
-
|
70
|
+
# @return [BinStruct::String,Header::Base]
|
71
|
+
define_attr :body, BinStruct::String
|
72
72
|
|
73
73
|
# @param [Hash] options
|
74
74
|
# @option options [Integer] :hrd network protocol type (default: 1)
|
@@ -21,7 +21,7 @@ module PacketGen
|
|
21
21
|
include Headerable
|
22
22
|
|
23
23
|
class << self
|
24
|
-
# Define some methods from given ASN.1
|
24
|
+
# Define some methods from given ASN.1 attributes.to mimic {Base} attributes
|
25
25
|
# @param [Array<Symbol>] attributes
|
26
26
|
# @return [void]
|
27
27
|
def define_attributes(*attributes)
|
@@ -13,28 +13,28 @@ module PacketGen
|
|
13
13
|
# * +#calc_checksum+, which computes header checksum,
|
14
14
|
# * +#calc_length+, which computes header length,
|
15
15
|
# * {#parse?},
|
16
|
-
# * +#reply!+, which inverts needed
|
16
|
+
# * +#reply!+, which inverts needed attributes.to forge a response.
|
17
17
|
# @author Sylvain Daubert
|
18
|
-
class Base <
|
18
|
+
class Base < BinStruct::Struct
|
19
19
|
include Headerable
|
20
20
|
|
21
21
|
# @api private
|
22
22
|
# Simple class to handle a header association
|
23
|
-
class Binding < Struct.new(:key, :value)
|
23
|
+
class Binding < ::Struct.new(:key, :value)
|
24
24
|
# Check +fields+ responds to binding
|
25
|
-
# @param [
|
25
|
+
# @param [BinStruct::Struct] fields
|
26
26
|
# @return [Boolean]
|
27
27
|
def check?(fields)
|
28
28
|
case self[:value]
|
29
29
|
when Proc
|
30
|
-
self[:value].call
|
30
|
+
self[:value].call(fields.send(self[:key]))
|
31
31
|
else
|
32
32
|
fields.send(self[:key]) == self[:value]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
# Set +fields+ field to binding value
|
37
|
-
# @param [
|
37
|
+
# @param [BinStruct::Struct] fields
|
38
38
|
# @return [void]
|
39
39
|
def set(fields)
|
40
40
|
case self[:value]
|
@@ -62,14 +62,14 @@ module PacketGen
|
|
62
62
|
end
|
63
63
|
|
64
64
|
# Check +fields+ responds to binding
|
65
|
-
# @param [
|
65
|
+
# @param [BinStruct::Struct] fields
|
66
66
|
# @return [Boolean]
|
67
67
|
def check?(fields)
|
68
68
|
@check.call(fields)
|
69
69
|
end
|
70
70
|
|
71
71
|
# Set +fields+ field to binding value
|
72
|
-
# @param [
|
72
|
+
# @param [BinStruct::Struct] fields
|
73
73
|
# @return [void]
|
74
74
|
def set(fields)
|
75
75
|
@set.call(fields)
|
@@ -120,22 +120,22 @@ module PacketGen
|
|
120
120
|
end
|
121
121
|
|
122
122
|
# Check +fields+ responds to set of bindings
|
123
|
-
# @param [
|
123
|
+
# @param [BinStruct::Struct] fields
|
124
124
|
# @return [Boolean]
|
125
125
|
def check?(fields)
|
126
126
|
@bindings.any? { |group| group.all? { |binding| binding.check?(fields) } }
|
127
127
|
end
|
128
128
|
|
129
129
|
# Set +fields+ to bindings value
|
130
|
-
# @param [
|
130
|
+
# @param [BinStruct::Struct] fields
|
131
131
|
# @return [void]
|
132
132
|
def set(fields)
|
133
|
-
@bindings.first.each { |b| b.set
|
133
|
+
@bindings.first.each { |b| b.set(fields) }
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
137
|
# @private
|
138
|
-
# On
|
138
|
+
# On inheritance, create +@known_header+ class variable
|
139
139
|
# @param [Class] klass
|
140
140
|
# @return [void]
|
141
141
|
def self.inherited(klass)
|
@@ -151,7 +151,7 @@ module PacketGen
|
|
151
151
|
|
152
152
|
# Bind a upper header to current one.
|
153
153
|
# @param [Class] header_klass header class to bind to current class
|
154
|
-
# @param [Hash] args current class
|
154
|
+
# @param [Hash] args current class attributes.and their value when +header_klass+
|
155
155
|
# is embedded in current class.
|
156
156
|
#
|
157
157
|
# Given value may be a lambda, whose alone argument is the value extracted
|
@@ -182,11 +182,10 @@ module PacketGen
|
|
182
182
|
# ->(hdr) { hdr.field1 == 41 && hdr.body[0..1] == "\x00\x00" }]
|
183
183
|
# @since 2.7.0
|
184
184
|
def bind(header_klass, args={})
|
185
|
-
|
185
|
+
bindings = @known_headers[header_klass]
|
186
|
+
if bindings.nil?
|
186
187
|
bindings = Bindings.new
|
187
188
|
@known_headers[header_klass] = bindings
|
188
|
-
else
|
189
|
-
bindings = @known_headers[header_klass]
|
190
189
|
end
|
191
190
|
bindings.new_set
|
192
191
|
args.each do |key, value|
|
@@ -213,7 +212,7 @@ module PacketGen
|
|
213
212
|
end
|
214
213
|
end
|
215
214
|
|
216
|
-
# @see
|
215
|
+
# @see BinStruct::Struct#initialize
|
217
216
|
def initialize(options={})
|
218
217
|
@packet = options.delete(:packet) if options.key?(:packet)
|
219
218
|
super
|
@@ -242,7 +241,7 @@ module PacketGen
|
|
242
241
|
def ip_header(header)
|
243
242
|
hid = header_id(header)
|
244
243
|
iph = packet.headers[0...hid].reverse.find { |h| h.is_a?(IP) || h.is_a?(IPv6) }
|
245
|
-
raise FormatError, 'no IP
|
244
|
+
raise FormatError, 'no IP nor IPv6 header in packet' if iph.nil?
|
246
245
|
|
247
246
|
iph
|
248
247
|
end
|
@@ -12,23 +12,23 @@ module PacketGen
|
|
12
12
|
# RFC 951}
|
13
13
|
#
|
14
14
|
# A BOOTP header consists of:
|
15
|
-
# * an operation code field ({#op} of type {
|
16
|
-
# * a hardware address type ({#htype} of type {
|
17
|
-
# * a hardware address length ({#hlen} of type {
|
18
|
-
# * a {#hops} field ({
|
19
|
-
# * a transaction ID ({#xid} of type {
|
20
|
-
# * a {#secs} field (){
|
21
|
-
# * a {#flags} field (){
|
15
|
+
# * an operation code field ({#op} of type {BinStruct::Int8Enum}),
|
16
|
+
# * a hardware address type ({#htype} of type {BinStruct::Int8}),
|
17
|
+
# * a hardware address length ({#hlen} of type {BinStruct::Int8}),
|
18
|
+
# * a {#hops} field ({BinStruct::Int8}),
|
19
|
+
# * a transaction ID ({#xid} of type {BinStruct::Int32}),
|
20
|
+
# * a {#secs} field (){BinStruct::Int16}),
|
21
|
+
# * a {#flags} field (){BinStruct::Int16}):
|
22
22
|
# * a 1-bit broadcast flag ({#b}),
|
23
23
|
# * a 15-bit Must Be Zero field ({#mbz}),
|
24
24
|
# * a {#ciaddr} field ({IP::Addr}),
|
25
25
|
# * a {#yiaddr} field ({IP::Addr}),
|
26
26
|
# * a {#siaddr} field ({IP::Addr}),
|
27
27
|
# * a {#giaddr} field ({IP::Addr}),
|
28
|
-
# * a {#chaddr} field (16-byte {
|
29
|
-
# * a {#sname} field (64-byte {
|
30
|
-
# * a {#file} field (128-byte {
|
31
|
-
# * and a body ({
|
28
|
+
# * a {#chaddr} field (16-byte {BinStruct::String}),
|
29
|
+
# * a {#sname} field (64-byte {BinStruct::CString}),
|
30
|
+
# * a {#file} field (128-byte {BinStruct::CString}),
|
31
|
+
# * and a body ({BinStruct::String}).
|
32
32
|
#
|
33
33
|
# == Create a BOOTP header
|
34
34
|
# # standalone
|
@@ -52,84 +52,82 @@ module PacketGen
|
|
52
52
|
# @!attribute op
|
53
53
|
# 8-bit opcode
|
54
54
|
# @return [Integer]
|
55
|
-
|
55
|
+
define_attr :op, BinStruct::Int8Enum, enum: OPCODES
|
56
56
|
|
57
57
|
# @!attribute htype
|
58
58
|
# 8-bit hardware address type
|
59
59
|
# @return [Integer]
|
60
|
-
|
60
|
+
define_attr :htype, BinStruct::Int8, default: 1
|
61
61
|
|
62
62
|
# @!attribute hlen
|
63
63
|
# 8-bit hardware address length
|
64
64
|
# @return [Integer]
|
65
|
-
|
65
|
+
define_attr :hlen, BinStruct::Int8, default: 6
|
66
66
|
|
67
67
|
# @!attribute hops
|
68
68
|
# @return [Integer]
|
69
|
-
|
69
|
+
define_attr :hops, BinStruct::Int8
|
70
70
|
|
71
71
|
# @!attribute xid
|
72
72
|
# 32-bit Transaction ID
|
73
73
|
# @return [Integer]
|
74
|
-
|
74
|
+
define_attr :xid, BinStruct::Int32
|
75
75
|
|
76
76
|
# @!attribute secs
|
77
77
|
# 16-bit integer: number of seconds elapsed since client began address
|
78
78
|
# acquisition or renewal process
|
79
79
|
# @return [Integer]
|
80
|
-
|
80
|
+
define_attr :secs, BinStruct::Int16
|
81
81
|
|
82
82
|
# @!attribute flags
|
83
83
|
# 16-bit flag field
|
84
84
|
# @return [Integer]
|
85
|
-
|
85
|
+
# @!attribute b
|
86
|
+
# Broadcast flag, from {#flags}
|
87
|
+
# @return [Boolean]
|
88
|
+
# @!attribute mbz
|
89
|
+
# 15-bit Must Be Zero bits, from {#flags}
|
90
|
+
# @return [Boolean]
|
91
|
+
define_bit_attr :flags, b: 1, mbz: 15
|
86
92
|
|
87
93
|
# @!attribute ciaddr
|
88
94
|
# client IP address
|
89
95
|
# @return [String]
|
90
|
-
|
96
|
+
define_attr :ciaddr, IP::Addr
|
91
97
|
|
92
98
|
# @!attribute yiaddr
|
93
99
|
# 'your' (client) IP address
|
94
100
|
# @return [String]
|
95
|
-
|
101
|
+
define_attr :yiaddr, IP::Addr
|
96
102
|
|
97
103
|
# @!attribute siaddr
|
98
104
|
# IP address of next server to use in bootstrap
|
99
105
|
# @return [String]
|
100
|
-
|
106
|
+
define_attr :siaddr, IP::Addr
|
101
107
|
|
102
108
|
# @!attribute giaddr
|
103
109
|
# Relay agent IP address, used in booting via a relay agent
|
104
110
|
# @return [String]
|
105
|
-
|
111
|
+
define_attr :giaddr, IP::Addr
|
106
112
|
|
107
113
|
# @!attribute chaddr
|
108
114
|
# client hardware address
|
109
115
|
# @return [String]
|
110
|
-
|
116
|
+
define_attr :chaddr, BinStruct::String, static_length: 16
|
111
117
|
|
112
118
|
# @!attribute sname
|
113
119
|
# optional server hostname, null-terminated string
|
114
120
|
# @return [String]
|
115
|
-
|
121
|
+
define_attr :sname, BinStruct::CString, static_length: 64
|
116
122
|
|
117
123
|
# @!attribute file
|
118
124
|
# Boot file name, null terminated string
|
119
125
|
# @return [String]
|
120
|
-
|
126
|
+
define_attr :file, BinStruct::CString, static_length: 128
|
121
127
|
|
122
128
|
# @!attribute body
|
123
129
|
# @return [String]
|
124
|
-
|
125
|
-
|
126
|
-
# @!attribute b
|
127
|
-
# Broadcast flag, from {#flags}
|
128
|
-
# @return [Boolean]
|
129
|
-
# @!attribute mbz
|
130
|
-
# 15-bit Must Be Zero bits, from {#flags}
|
131
|
-
# @return [Boolean]
|
132
|
-
define_bit_fields_on :flags, :b, :mbz, 15
|
130
|
+
define_attr :body, BinStruct::String
|
133
131
|
|
134
132
|
# @return [String]
|
135
133
|
def inspect
|
@@ -59,51 +59,51 @@ module PacketGen
|
|
59
59
|
|
60
60
|
# @!parse
|
61
61
|
# # Option class with string value. {#type #type} and {#length #length} are
|
62
|
-
# # {
|
62
|
+
# # {BinStruct::Int8}.
|
63
63
|
# #
|
64
64
|
# # See also {IPAddrOption}, {Int8Option}, {Int16Option} and {Int32Option}.
|
65
65
|
# # @since 2.2.0
|
66
|
-
# # @since 3.1.0 subclass of {
|
67
|
-
# class Option <
|
66
|
+
# # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
|
67
|
+
# class Option < BinStruct::AbstractTLV; end
|
68
68
|
# @private
|
69
|
-
Option =
|
69
|
+
Option = BinStruct::AbstractTLV.create
|
70
70
|
Option.define_type_enum DHCP_OPTIONS
|
71
71
|
# @!parse
|
72
72
|
# # {Option} class with IP address value
|
73
73
|
# # @since 2.2.0
|
74
|
-
# # @since 3.1.0 subclass of {
|
75
|
-
# class IPAddrOption <
|
74
|
+
# # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
|
75
|
+
# class IPAddrOption < BinStruct::AbstractTLV; end
|
76
76
|
# @private
|
77
|
-
IPAddrOption =
|
77
|
+
IPAddrOption = BinStruct::AbstractTLV.create(value_class: IP::Addr)
|
78
78
|
IPAddrOption.define_type_enum DHCP_OPTIONS
|
79
79
|
# @!parse
|
80
80
|
# # {Option} class with int8 value
|
81
81
|
# # @since 2.2.0
|
82
|
-
# # @since 3.1.0 subclass of {
|
83
|
-
# class Int8Option <
|
82
|
+
# # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
|
83
|
+
# class Int8Option < BinStruct::AbstractTLV; end
|
84
84
|
# @private
|
85
|
-
Int8Option =
|
85
|
+
Int8Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int8)
|
86
86
|
Int8Option.define_type_enum DHCP_OPTIONS
|
87
87
|
# @!parse
|
88
88
|
# # {Option} class with int16 value
|
89
89
|
# # @since 2.2.0
|
90
|
-
# # @since 3.1.0 subclass of {
|
91
|
-
# class Int16Option <
|
90
|
+
# # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
|
91
|
+
# class Int16Option < BinStruct::AbstractTLV; end
|
92
92
|
# @private
|
93
|
-
Int16Option =
|
93
|
+
Int16Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int16)
|
94
94
|
Int16Option.define_type_enum DHCP_OPTIONS
|
95
95
|
# @!parse
|
96
96
|
# # {Option} class with int32 value
|
97
97
|
# # @since 2.2.0
|
98
|
-
# # @since 3.1.0 subclass of {
|
99
|
-
# class Int32Option <
|
98
|
+
# # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
|
99
|
+
# class Int32Option < BinStruct::AbstractTLV; end
|
100
100
|
# @private
|
101
|
-
Int32Option =
|
101
|
+
Int32Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int32)
|
102
102
|
Int32Option.define_type_enum DHCP_OPTIONS
|
103
103
|
|
104
104
|
# Class to indicate DHCP options end
|
105
|
-
class End <
|
106
|
-
def initialize(value
|
105
|
+
class End < BinStruct::Int8
|
106
|
+
def initialize(options={ value: 255 })
|
107
107
|
super
|
108
108
|
end
|
109
109
|
|
@@ -115,7 +115,7 @@ module PacketGen
|
|
115
115
|
|
116
116
|
# Class to indicate padding after DHCP options
|
117
117
|
class Pad < End
|
118
|
-
def initialize(value
|
118
|
+
def initialize(options={ value: 0 })
|
119
119
|
super
|
120
120
|
end
|
121
121
|
end
|