packetgen 3.3.2 → 4.0.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 +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
|
[![Gem Version](https://badge.fury.io/rb/packetgen.svg)](https://badge.fury.io/rb/packetgen)
|
3
3
|
[![Action status](https://github.com/lemontree55/packetgen/workflows/ci/badge.svg?branch=master)](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
|