packetgen 3.3.3 → 4.1.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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -22
  3. data/lib/packetgen/capture.rb +2 -2
  4. data/lib/packetgen/config.rb +0 -1
  5. data/lib/packetgen/deprecation.rb +14 -8
  6. data/lib/packetgen/header/arp.rb +17 -18
  7. data/lib/packetgen/header/asn1_base.rb +2 -1
  8. data/lib/packetgen/header/base.rb +42 -40
  9. data/lib/packetgen/header/bootp.rb +35 -37
  10. data/lib/packetgen/header/dhcp/option.rb +21 -21
  11. data/lib/packetgen/header/dhcp/options.rb +3 -3
  12. data/lib/packetgen/header/dhcp.rb +8 -9
  13. data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
  14. data/lib/packetgen/header/dhcpv6/option.rb +83 -61
  15. data/lib/packetgen/header/dhcpv6/options.rb +4 -4
  16. data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
  17. data/lib/packetgen/header/dhcpv6.rb +17 -18
  18. data/lib/packetgen/header/dns/name.rb +21 -16
  19. data/lib/packetgen/header/dns/opt.rb +5 -2
  20. data/lib/packetgen/header/dns/option.rb +14 -14
  21. data/lib/packetgen/header/dns/qdsection.rb +3 -3
  22. data/lib/packetgen/header/dns/question.rb +7 -8
  23. data/lib/packetgen/header/dns/rr.rb +56 -43
  24. data/lib/packetgen/header/dns/rrsection.rb +6 -6
  25. data/lib/packetgen/header/dns.rb +103 -90
  26. data/lib/packetgen/header/dot11/control.rb +12 -12
  27. data/lib/packetgen/header/dot11/data.rb +25 -24
  28. data/lib/packetgen/header/dot11/element.rb +4 -4
  29. data/lib/packetgen/header/dot11/management.rb +21 -18
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
  31. data/lib/packetgen/header/dot11.rb +117 -122
  32. data/lib/packetgen/header/dot1q.rb +12 -13
  33. data/lib/packetgen/header/dot1x.rb +13 -13
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +16 -8
  36. data/lib/packetgen/header/eap/tls.rb +18 -19
  37. data/lib/packetgen/header/eap/ttls.rb +22 -21
  38. data/lib/packetgen/header/eap.rb +73 -48
  39. data/lib/packetgen/header/eth.rb +41 -27
  40. data/lib/packetgen/header/gre.rb +33 -11
  41. data/lib/packetgen/header/http/headers.rb +7 -6
  42. data/lib/packetgen/header/http/request.rb +38 -29
  43. data/lib/packetgen/header/http/response.rb +35 -27
  44. data/lib/packetgen/header/http/verbs.rb +1 -3
  45. data/lib/packetgen/header/icmp.rb +14 -14
  46. data/lib/packetgen/header/icmpv6.rb +10 -9
  47. data/lib/packetgen/header/igmp.rb +26 -15
  48. data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
  49. data/lib/packetgen/header/igmpv3/mq.rb +16 -18
  50. data/lib/packetgen/header/igmpv3/mr.rb +5 -5
  51. data/lib/packetgen/header/igmpv3.rb +12 -11
  52. data/lib/packetgen/header/ip/addr.rb +19 -15
  53. data/lib/packetgen/header/ip/option.rb +47 -36
  54. data/lib/packetgen/header/ip/options.rb +1 -1
  55. data/lib/packetgen/header/ip.rb +77 -95
  56. data/lib/packetgen/header/ipv6/addr.rb +28 -27
  57. data/lib/packetgen/header/ipv6/extension.rb +13 -11
  58. data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
  59. data/lib/packetgen/header/ipv6.rb +42 -35
  60. data/lib/packetgen/header/llc.rb +28 -21
  61. data/lib/packetgen/header/mdns.rb +10 -3
  62. data/lib/packetgen/header/mld.rb +15 -13
  63. data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
  64. data/lib/packetgen/header/mldv2/mlq.rb +22 -24
  65. data/lib/packetgen/header/mldv2/mlr.rb +8 -8
  66. data/lib/packetgen/header/mldv2.rb +1 -1
  67. data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
  68. data/lib/packetgen/header/ospfv2/hello.rb +18 -17
  69. data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
  70. data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
  71. data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
  72. data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
  73. data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
  74. data/lib/packetgen/header/ospfv2.rb +49 -46
  75. data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
  76. data/lib/packetgen/header/ospfv3/hello.rb +17 -16
  77. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
  78. data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
  79. data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
  80. data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
  81. data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
  82. data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
  83. data/lib/packetgen/header/ospfv3.rb +54 -52
  84. data/lib/packetgen/header/sctp/chunk.rb +80 -56
  85. data/lib/packetgen/header/sctp/error.rb +174 -202
  86. data/lib/packetgen/header/sctp/padded32.rb +3 -3
  87. data/lib/packetgen/header/sctp/parameter.rb +89 -136
  88. data/lib/packetgen/header/sctp.rb +19 -8
  89. data/lib/packetgen/header/snmp.rb +108 -7
  90. data/lib/packetgen/header/tcp/option.rb +52 -39
  91. data/lib/packetgen/header/tcp/options.rb +13 -5
  92. data/lib/packetgen/header/tcp.rb +83 -65
  93. data/lib/packetgen/header/tftp.rb +31 -25
  94. data/lib/packetgen/header/udp.rb +21 -19
  95. data/lib/packetgen/header.rb +23 -18
  96. data/lib/packetgen/headerable.rb +21 -5
  97. data/lib/packetgen/inspect.rb +3 -8
  98. data/lib/packetgen/packet.rb +146 -71
  99. data/lib/packetgen/pcap.rb +15 -4
  100. data/lib/packetgen/pcapng/block.rb +20 -18
  101. data/lib/packetgen/pcapng/epb.rb +13 -15
  102. data/lib/packetgen/pcapng/file.rb +44 -111
  103. data/lib/packetgen/pcapng/idb.rb +11 -12
  104. data/lib/packetgen/pcapng/shb.rb +15 -16
  105. data/lib/packetgen/pcapng/spb.rb +9 -11
  106. data/lib/packetgen/pcapng/unknown_block.rb +6 -17
  107. data/lib/packetgen/pcapng.rb +6 -4
  108. data/lib/packetgen/pcaprub_wrapper.rb +17 -1
  109. data/lib/packetgen/proto.rb +5 -1
  110. data/lib/packetgen/unknown_packet.rb +5 -5
  111. data/lib/packetgen/utils/arp_spoofer.rb +18 -19
  112. data/lib/packetgen/utils.rb +4 -3
  113. data/lib/packetgen/version.rb +1 -1
  114. data/lib/packetgen.rb +12 -5
  115. metadata +29 -38
  116. data/lib/packetgen/types/abstract_tlv.rb +0 -278
  117. data/lib/packetgen/types/array.rb +0 -287
  118. data/lib/packetgen/types/cstring.rb +0 -109
  119. data/lib/packetgen/types/enum.rb +0 -171
  120. data/lib/packetgen/types/fieldable.rb +0 -66
  121. data/lib/packetgen/types/fields.rb +0 -622
  122. data/lib/packetgen/types/int.rb +0 -473
  123. data/lib/packetgen/types/int_string.rb +0 -102
  124. data/lib/packetgen/types/length_from.rb +0 -54
  125. data/lib/packetgen/types/oui.rb +0 -52
  126. data/lib/packetgen/types/string.rb +0 -97
  127. data/lib/packetgen/types/tlv.rb +0 -161
  128. data/lib/packetgen/types.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8316e4a27cffbad65cbfabe1eb42746afda43b137eeca97352201f72b1a785cf
4
- data.tar.gz: 621a076c2b6159d9a60e0842d318298cbcb5c983b358983bc9e21b2e1ec50b96
3
+ metadata.gz: ed11e05d37fb82187dbf1dc0a7dffd1e6c1931ebda0dea904da77f2731a523f8
4
+ data.tar.gz: e36705786a664ac257d1939a9c67d267a15c52f51e76b02069c923095c0d8852
5
5
  SHA512:
6
- metadata.gz: 447552efc82789c71b1f2de48059a387318471366866794b70e9318f04d53ca78e16b63ec2f8984f162b02bca2c3cbe6c0f96ccd083f86d99a5dfaddbe1daa2d
7
- data.tar.gz: 01426b4136c2084607621087fd856677c27842de93b6b266cb15056a59ba6e2f126b87a268c5369a012819a0d37e5c79866b57c8821fa80f4b7dfcbcde10f785
6
+ metadata.gz: 151754f39d113f9dbeb65cda8f62f4e378440aa567c3e528b2d8e93920e70069a55bd26e737c03818a808463a9b3406805dcb8ed92e8b5582fbbfaae7f5d8fd4
7
+ data.tar.gz: 4f61a79f28f1fe8e5f4cac45b9b8fdc06eeca4ae4a07a567334535b3e8ac7ea5cb85cb6644215656e6c0e7e2d1ba0a58bae1fe66131805af7093742dc5098bdd
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
- [![Action status](https://github.com/lemontree55/packetgen/workflows/ci/badge.svg?branch=master)](https://github.com/lemontree55/packetgen/actions?query=workflow%3Aci)
3
+ [![Action status](https://github.com/lemontree55/packetgen/actions/workflows/ci.yml/badge.svg)](https://github.com/lemontree55/packetgen/actions/workflows/ci.yml)
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
- $ sudo apt install libpcap-dev
13
+ ```bash
14
+ sudo apt install libpcap-dev
15
+ ```
12
16
 
13
17
  Installation using RubyGems is then easy:
14
18
 
15
- $ gem install packetgen
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
- Since v1.1.0, PacketGen permits adding your own header classes.
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
- define_field :field1, PacketGen::Types::Int32
117
- define_field :field2, PacketGen::Types::Int32
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.myheader.field2.read 0x01
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
- $ pgconsole
149
- pg(main)> config
150
- => #<PacketGen::Config:0x00559f27d2afe8
151
- @hwaddr="75:74:73:72:71:70",
152
- @iface="eth0",
153
- @ipaddr="192.168.0.2">
154
- pg(main)> packets = capture(max: 5)
155
- pg(main)> exit
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
- This is mainly for PcapNG (originally copied from [PacketFu](https://github.com/packetfu/packetfu),
186
- but i am the original author.
202
+ All original code maintains its copyright from its original authors and licensing.
@@ -61,7 +61,7 @@ module PacketGen
61
61
  @packets = []
62
62
  @raw_packets = []
63
63
  @timestamps = []
64
- set_options iface, max, timeout, filter, promisc, parse, snaplen, monitor
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 iface, max, timeout, filter, promisc, parse, snaplen, monitor
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|
@@ -12,7 +12,6 @@ require 'singleton'
12
12
  module PacketGen
13
13
  # Config class to provide +config+ object to pgconsole
14
14
  # @author Sylvain Daubert
15
- # @author Kent 'picat' Gruber
16
15
  # @since 1.4.1
17
16
  # @since 2.1.3 Config is singleton
18
17
  class Config
@@ -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 = '4.0.0'
11
+ REMOVE_VERSION = '5.0.0'
12
12
 
13
13
  # @private
14
14
  # @param [String] remove_version
@@ -29,13 +29,19 @@ module PacketGen
29
29
  def self.deprecated(klass, deprecated_method, new_method=nil, klass_method: false, remove_version: REMOVE_VERSION)
30
30
  base_name = "#{klass}#{klass_method ? '.' : '#'}"
31
31
  complete_deprecated_method_name = "#{base_name}#{deprecated_method}"
32
- complete_new_method_name = "#{base_name}#{new_method}" unless new_method.nil?
32
+ unless new_method.nil?
33
+ complete_new_method_name = if %w[# .].any? { |punct| new_method.include?(punct) }
34
+ new_method
35
+ else
36
+ "#{base_name}#{new_method}"
37
+ end
38
+ end
33
39
 
34
40
  file, line = caller(2..2).first.split(':')[0, 2]
35
- message = +"#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
41
+ message = "#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
36
42
  message << " in favor of #{complete_new_method_name}" unless new_method.nil?
37
43
  message << '. ' << self.removed(remove_version)
38
- warn message
44
+ warn(message)
39
45
  end
40
46
 
41
47
  # Warn when using a deprecated method
@@ -46,10 +52,10 @@ module PacketGen
46
52
  # @since 3.1.0
47
53
  def self.deprecated_class(klass, new_klass=nil, remove_version: REMOVE_VERSION)
48
54
  file, line = caller(2..2).first.split(':')[0, 2]
49
- message = +"#{file}:#{line}: #{klass} is deprecated"
55
+ message = "#{file}:#{line}: #{klass} is deprecated"
50
56
  message << " in favor of #{new_klass}" unless new_klass.nil?
51
57
  message << '. ' << self.removed(remove_version)
52
- warn message
58
+ warn(message)
53
59
  end
54
60
 
55
61
  # Warn when using a deprecated method's option
@@ -64,9 +70,9 @@ module PacketGen
64
70
  def self.deprecated_option(klass, method, option, klass_method: false, remove_version: REMOVE_VERSION)
65
71
  base_name = "#{klass}#{klass_method ? '.' : '#'}"
66
72
  method_name = "#{base_name}#{method}"
67
- message = +"option #{option} is deprecated for method #{method_name}. "
73
+ message = "option #{option} is deprecated for method #{method_name}. "
68
74
  message << self.removed(remove_version)
69
- warn message
75
+ warn(message)
70
76
  end
71
77
  end
72
78
  end
@@ -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 ({Types::Int16}),
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 ({Types::Int8}),
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}),
@@ -20,55 +20,55 @@ module PacketGen
20
20
  # * a target protocol address ({#tpa} or {#dst_ip}) field (+IP::Addr+),
21
21
  # * and a {#body}.
22
22
  #
23
- # == Create a ARP header
23
+ # @example Create a ARP header
24
24
  # # standalone
25
25
  # arp = PacketGen::Header::ARP.new
26
26
  # # in a packet
27
27
  # pkt = PacketGen.gen('Eth').add('ARP')
28
28
  # # access to ARP header
29
- # pkt.arp # => PacketGen::Header::ARP
29
+ # pkt.arp.protocol_name # => "ARP"
30
30
  #
31
31
  # @author Sylvain Daubert
32
32
  class ARP < Base
33
33
  # @!attribute hrd
34
34
  # 16-bit hardware protocol type
35
35
  # # @return [Integer]
36
- define_field :hrd, Types::Int16, default: 1
36
+ define_attr :hrd, BinStruct::Int16, default: 1
37
37
  # @!attribute pro
38
38
  # 16-bit internet protocol type
39
39
  # # @return [Integer]
40
- define_field :pro, Types::Int16, default: 0x800
40
+ define_attr :pro, BinStruct::Int16, default: 0x800
41
41
  # @!attribute hln
42
42
  # 8-bit hardware address length
43
43
  # # @return [Integer]
44
- define_field :hln, Types::Int8, default: 6
44
+ define_attr :hln, BinStruct::Int8, default: 6
45
45
  # @!attribute pln
46
46
  # 8-bit internet address length
47
47
  # # @return [Integer]
48
- define_field :pln, Types::Int8, default: 4
48
+ define_attr :pln, BinStruct::Int8, default: 4
49
49
  # @!attribute op
50
50
  # 16-bit operation code
51
51
  # # @return [Integer]
52
- define_field :op, Types::Int16Enum, enum: { 'request' => 1, 'reply' => 2 }
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
- define_field :sha, Eth::MacAddr
56
+ define_attr :sha, Eth::MacAddr
57
57
  # @!attribute spa
58
58
  # source protocol address
59
59
  # @return [IP::Addr]
60
- define_field :spa, IP::Addr
60
+ define_attr :spa, IP::Addr
61
61
  # @!attribute tha
62
62
  # target hardware address
63
63
  # @return [Eth::MacAddr]
64
- define_field :tha, Eth::MacAddr
64
+ define_attr :tha, Eth::MacAddr
65
65
  # @!attribute tpa
66
66
  # target protocol address
67
67
  # @return [IP::Addr]
68
- define_field :tpa, IP::Addr
68
+ define_attr :tpa, IP::Addr
69
69
  # @!attribute body
70
- # @return [Types::String,Header::Base]
71
- define_field :body, Types::String
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)
@@ -122,8 +122,7 @@ module PacketGen
122
122
 
123
123
  private
124
124
 
125
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
126
- def handle_options(options)
125
+ def handle_options(options)
127
126
  options[:hrd] ||= options[:htype]
128
127
  options[:pro] ||= options[:ptype]
129
128
  options[:hln] ||= options[:hlen]
@@ -134,7 +133,7 @@ module PacketGen
134
133
  options[:tha] ||= options[:dst_mac]
135
134
  options[:tpa] ||= options[:dst_ip]
136
135
  end
137
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
136
+ # rubocop:enable Metrics
138
137
 
139
138
  def invert_addresses
140
139
  self.spa, self.tpa = self.tpa, self.spa
@@ -21,7 +21,7 @@ module PacketGen
21
21
  include Headerable
22
22
 
23
23
  class << self
24
- # Define some methods from given ASN.1 fields to mimic {Base} attributes
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)
@@ -32,6 +32,7 @@ module PacketGen
32
32
  end
33
33
  end
34
34
 
35
+ # @return [Hash]
35
36
  def known_headers
36
37
  @known_headers ||= {}.freeze
37
38
  end
@@ -13,28 +13,30 @@ 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 fields to forge a response.
16
+ # * +#reply!+, which inverts needed attributes to forge a response.
17
+ # {Base} class defines {.bind} method, to bind headers to outer ones.
17
18
  # @author Sylvain Daubert
18
- class Base < Types::Fields
19
+ # @author LemonTree55
20
+ class Base < BinStruct::Struct
19
21
  include Headerable
20
22
 
21
23
  # @api private
22
24
  # Simple class to handle a header association
23
- class Binding < Struct.new(:key, :value)
25
+ class Binding < ::Struct.new(:key, :value)
24
26
  # Check +fields+ responds to binding
25
- # @param [Types::Fields] fields
27
+ # @param [BinStruct::Struct] fields
26
28
  # @return [Boolean]
27
29
  def check?(fields)
28
30
  case self[:value]
29
31
  when Proc
30
- self[:value].call fields.send(self[:key])
32
+ self[:value].call(fields.send(self[:key]))
31
33
  else
32
34
  fields.send(self[:key]) == self[:value]
33
35
  end
34
36
  end
35
37
 
36
38
  # Set +fields+ field to binding value
37
- # @param [Types::Fields] fields
39
+ # @param [BinStruct::Struct] fields
38
40
  # @return [void]
39
41
  def set(fields)
40
42
  case self[:value]
@@ -54,7 +56,7 @@ module PacketGen
54
56
  # @api private
55
57
  # Class to handle a header association from procs
56
58
  class ProcBinding
57
- # @param [Array<Proc>] procs first proc is used to set fields, second proc is
59
+ # @param [Array(Proc,Proc)] procs first proc is used to set fields, second proc is
58
60
  # used to check binding
59
61
  def initialize(procs)
60
62
  @set = procs.shift
@@ -62,14 +64,14 @@ module PacketGen
62
64
  end
63
65
 
64
66
  # Check +fields+ responds to binding
65
- # @param [Types::Fields] fields
67
+ # @param [BinStruct::Struct] fields
66
68
  # @return [Boolean]
67
69
  def check?(fields)
68
70
  @check.call(fields)
69
71
  end
70
72
 
71
73
  # Set +fields+ field to binding value
72
- # @param [Types::Fields] fields
74
+ # @param [BinStruct::Struct] fields
73
75
  # @return [void]
74
76
  def set(fields)
75
77
  @set.call(fields)
@@ -77,11 +79,11 @@ module PacketGen
77
79
  end
78
80
 
79
81
  # @api private
80
- # Class to handle header associations
82
+ # Class to handle a set of header associations ({Binding} or/and {ProcBinding})
81
83
  class Bindings
82
84
  include Enumerable
83
85
 
84
- # @return [Array<Binding>]
86
+ # @return [Array<Binding,ProcBinding>]
85
87
  attr_accessor :bindings
86
88
 
87
89
  def initialize
@@ -92,7 +94,7 @@ module PacketGen
92
94
  @bindings << []
93
95
  end
94
96
 
95
- # @param [Object] arg
97
+ # @param [Binding,ProcBinding] arg
96
98
  # @return [Bindings] self
97
99
  def <<(arg)
98
100
  @bindings.last << arg
@@ -100,6 +102,7 @@ module PacketGen
100
102
 
101
103
  # each iterator
102
104
  # @return [void]
105
+ # @yieldparam [Binding,ProcBinding] binding
103
106
  def each(&block)
104
107
  @bindings.each(&block)
105
108
  end
@@ -109,7 +112,7 @@ module PacketGen
109
112
  @bindings.empty?
110
113
  end
111
114
 
112
- # Return binding as a hash.
115
+ # Return bindings as a hash.
113
116
  # @return [Hash]
114
117
  def to_h
115
118
  hsh = {}
@@ -120,22 +123,22 @@ module PacketGen
120
123
  end
121
124
 
122
125
  # Check +fields+ responds to set of bindings
123
- # @param [Types::Fields] fields
126
+ # @param [BinStruct::Struct] fields
124
127
  # @return [Boolean]
125
128
  def check?(fields)
126
129
  @bindings.any? { |group| group.all? { |binding| binding.check?(fields) } }
127
130
  end
128
131
 
129
132
  # Set +fields+ to bindings value
130
- # @param [Types::Fields] fields
133
+ # @param [BinStruct::Struct] fields
131
134
  # @return [void]
132
135
  def set(fields)
133
- @bindings.first.each { |b| b.set fields }
136
+ @bindings.first.each { |b| b.set(fields) }
134
137
  end
135
138
  end
136
139
 
137
140
  # @private
138
- # On inheritage, create +@known_header+ class variable
141
+ # On inheritance, create +@known_header+ class variable
139
142
  # @param [Class] klass
140
143
  # @return [void]
141
144
  def self.inherited(klass)
@@ -146,12 +149,12 @@ module PacketGen
146
149
  class << self
147
150
  # @api private
148
151
  # Get known headers
149
- # @return [Hash] keys: header classes, values: hashes
152
+ # @return [Hash{Headerable => Bindings}]
150
153
  attr_reader :known_headers
151
154
 
152
155
  # Bind a upper header to current one.
153
156
  # @param [Class] header_klass header class to bind to current class
154
- # @param [Hash] args current class fields and their value when +header_klass+
157
+ # @param [Hash] args current class attributes and their value when +header_klass+
155
158
  # is embedded in current class.
156
159
  #
157
160
  # Given value may be a lambda, whose alone argument is the value extracted
@@ -163,30 +166,29 @@ module PacketGen
163
166
  # non-trivial checks should be made.
164
167
  # @return [void]
165
168
  # @example Basic examples
166
- # # Bind Header2 to Header1 when field1 from Header1 has a value of 42
167
- # Header1.bind Header2, field1: 42
168
- # # Bind Header3 to Header1 when field1 from Header1 has a value of 43
169
- # # and field2 has value 43 or 44
170
- # Header1.bind Header3, field1: 43, field2: 43
171
- # Header1.bind Header3, field1: 43, field2: 44
169
+ # # Bind TCP to IP when protocol attribute from IP has a value of 66
170
+ # PacketGen::Header::IP.bind PacketGen::Header::TCP, protocol: 66
171
+ # # Bind UDP to IP when protocol from IP has a value of 177
172
+ # # and tos has value 43 or 44
173
+ # PacketGen::Header::IP .bind PacketGen::Header::UDP, protocol: 177, tos: 43
174
+ # PacketGen::Header::IP .bind PacketGen::Header::UDP, protocol: 177, tos: 44
172
175
  # @example Defining a binding on a field using a lambda.
173
- # # Bind Header4 to Header1 when field1 from Header1 has a value
174
- # # greater or equal to 44. When adding a Header2 to a Header1
176
+ # # Bind DHCP to Eth when ethertype from Eth has a value
177
+ # # greater or equal to 44. When adding a DHCP to a Eth
175
178
  # # with Packet#add, force value to 44.
176
- # Header1.bind Header4, field1: ->(v) { v.nil? ? 44 : v >= 44 }
179
+ # PacketGen::Header::Eth.bind PacketGen::Header::DHCP, ethertype: ->(v) { v.nil? ? 44 : v >= 44 }
177
180
  # @example Defining a binding using procs key
178
- # # Bind Header5 to Header1 when field1 from Header1 has a value of 41
179
- # # and first two bytes of header1's body are null.
180
- # # When adding a Header2 to a Header1 with Packet#add, force value to 44.
181
- # Header1.bind Header5, procs: [->(hdr) { hdr.field1 = 41 }
182
- # ->(hdr) { hdr.field1 == 41 && hdr.body[0..1] == "\x00\x00" }]
181
+ # # Bind IPv6 to IP when protocol from IP has a value of 255
182
+ # # and first two bytes of IP's body are 0x6000.
183
+ # # When adding a IPv6 to a IP with Packet#add, force value to 255.
184
+ # PacketGen::Header::IP.bind PacketGen::Header::IPv6, procs: [->(hdr) { hdr.protocol = 255 },
185
+ # ->(hdr) { hdr.protocol == 255 && hdr.body[0..1] == "\x60\x00" }]
183
186
  # @since 2.7.0
184
187
  def bind(header_klass, args={})
185
- if @known_headers[header_klass].nil?
188
+ bindings = @known_headers[header_klass]
189
+ if bindings.nil?
186
190
  bindings = Bindings.new
187
191
  @known_headers[header_klass] = bindings
188
- else
189
- bindings = @known_headers[header_klass]
190
192
  end
191
193
  bindings.new_set
192
194
  args.each do |key, value|
@@ -213,7 +215,7 @@ module PacketGen
213
215
  end
214
216
  end
215
217
 
216
- # @see Types::Fields#initialize
218
+ # @see BinStruct::Struct#initialize
217
219
  def initialize(options={})
218
220
  @packet = options.delete(:packet) if options.key?(:packet)
219
221
  super
@@ -222,7 +224,7 @@ module PacketGen
222
224
  # @api private
223
225
  # Get +header+ id in {Packet#headers} array
224
226
  # @param [Header] header
225
- # @return [Integer]
227
+ # @return [Integer] header id
226
228
  # @raise [FormatError] +header+ not in a packet
227
229
  def header_id(header)
228
230
  raise FormatError, "header of type #{header.class} not in a packet" if packet.nil?
@@ -242,13 +244,13 @@ module PacketGen
242
244
  def ip_header(header)
243
245
  hid = header_id(header)
244
246
  iph = packet.headers[0...hid].reverse.find { |h| h.is_a?(IP) || h.is_a?(IPv6) }
245
- raise FormatError, 'no IP or IPv6 header in packet' if iph.nil?
247
+ raise FormatError, 'no IP nor IPv6 header in packet' if iph.nil?
246
248
 
247
249
  iph
248
250
  end
249
251
 
250
252
  # @api private
251
- # Get link layer header from given header
253
+ # Get link layer ({Eth} or {Dot11}) header from given header
252
254
  # @param [Header] header
253
255
  # @return [Header]
254
256
  # @raise [FormatError] no link layer header in packet