packetgen 4.0.0 → 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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/packetgen/deprecation.rb +7 -1
  4. data/lib/packetgen/header/arp.rb +6 -7
  5. data/lib/packetgen/header/asn1_base.rb +2 -1
  6. data/lib/packetgen/header/base.rb +27 -24
  7. data/lib/packetgen/header/bootp.rb +14 -14
  8. data/lib/packetgen/header/dhcp/option.rb +8 -8
  9. data/lib/packetgen/header/dhcp/options.rb +2 -2
  10. data/lib/packetgen/header/dhcp.rb +6 -7
  11. data/lib/packetgen/header/dhcpv6/duid.rb +1 -1
  12. data/lib/packetgen/header/dhcpv6/option.rb +37 -15
  13. data/lib/packetgen/header/dhcpv6/options.rb +3 -3
  14. data/lib/packetgen/header/dhcpv6/relay.rb +1 -0
  15. data/lib/packetgen/header/dhcpv6.rb +13 -14
  16. data/lib/packetgen/header/dns/name.rb +9 -8
  17. data/lib/packetgen/header/dns/opt.rb +3 -0
  18. data/lib/packetgen/header/dns/option.rb +7 -7
  19. data/lib/packetgen/header/dns/qdsection.rb +2 -2
  20. data/lib/packetgen/header/dns/question.rb +1 -0
  21. data/lib/packetgen/header/dns/rrsection.rb +2 -2
  22. data/lib/packetgen/header/dns.rb +76 -60
  23. data/lib/packetgen/header/dot11/control.rb +5 -5
  24. data/lib/packetgen/header/dot11/data.rb +11 -10
  25. data/lib/packetgen/header/dot11/element.rb +1 -1
  26. data/lib/packetgen/header/dot11/management.rb +18 -15
  27. data/lib/packetgen/header/dot11/sub_mngt.rb +22 -21
  28. data/lib/packetgen/header/dot11.rb +38 -38
  29. data/lib/packetgen/header/dot1q.rb +5 -4
  30. data/lib/packetgen/header/dot1x.rb +8 -8
  31. data/lib/packetgen/header/eap/fast.rb +3 -3
  32. data/lib/packetgen/header/eap/md5.rb +11 -3
  33. data/lib/packetgen/header/eap/tls.rb +9 -8
  34. data/lib/packetgen/header/eap/ttls.rb +13 -10
  35. data/lib/packetgen/header/eap.rb +58 -33
  36. data/lib/packetgen/header/eth.rb +26 -12
  37. data/lib/packetgen/header/gre.rb +26 -2
  38. data/lib/packetgen/header/http/headers.rb +6 -5
  39. data/lib/packetgen/header/http/request.rb +24 -16
  40. data/lib/packetgen/header/http/response.rb +22 -15
  41. data/lib/packetgen/header/icmp.rb +10 -10
  42. data/lib/packetgen/header/icmpv6.rb +10 -9
  43. data/lib/packetgen/header/igmp.rb +21 -10
  44. data/lib/packetgen/header/igmpv3/group_record.rb +7 -2
  45. data/lib/packetgen/header/igmpv3/mq.rb +1 -1
  46. data/lib/packetgen/header/igmpv3/mr.rb +1 -1
  47. data/lib/packetgen/header/igmpv3.rb +11 -10
  48. data/lib/packetgen/header/ip/addr.rb +6 -2
  49. data/lib/packetgen/header/ip/option.rb +18 -5
  50. data/lib/packetgen/header/ip.rb +52 -35
  51. data/lib/packetgen/header/ipv6/addr.rb +14 -13
  52. data/lib/packetgen/header/ipv6/extension.rb +9 -7
  53. data/lib/packetgen/header/ipv6/hop_by_hop.rb +26 -7
  54. data/lib/packetgen/header/ipv6.rb +31 -22
  55. data/lib/packetgen/header/llc.rb +20 -13
  56. data/lib/packetgen/header/mdns.rb +9 -2
  57. data/lib/packetgen/header/mld.rb +11 -9
  58. data/lib/packetgen/header/mldv2/mcast_address_record.rb +6 -1
  59. data/lib/packetgen/header/mldv2/mlq.rb +8 -8
  60. data/lib/packetgen/header/mldv2/mlr.rb +4 -4
  61. data/lib/packetgen/header/mldv2.rb +1 -1
  62. data/lib/packetgen/header/ospfv2/db_description.rb +10 -10
  63. data/lib/packetgen/header/ospfv2/hello.rb +11 -10
  64. data/lib/packetgen/header/ospfv2/ls_ack.rb +5 -6
  65. data/lib/packetgen/header/ospfv2/ls_request.rb +7 -6
  66. data/lib/packetgen/header/ospfv2/ls_update.rb +7 -7
  67. data/lib/packetgen/header/ospfv2/lsa.rb +33 -10
  68. data/lib/packetgen/header/ospfv2/lsa_header.rb +3 -2
  69. data/lib/packetgen/header/ospfv2.rb +31 -26
  70. data/lib/packetgen/header/ospfv3/db_description.rb +12 -13
  71. data/lib/packetgen/header/ospfv3/hello.rb +10 -9
  72. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +6 -2
  73. data/lib/packetgen/header/ospfv3/ls_ack.rb +5 -6
  74. data/lib/packetgen/header/ospfv3/ls_request.rb +10 -10
  75. data/lib/packetgen/header/ospfv3/ls_update.rb +7 -7
  76. data/lib/packetgen/header/ospfv3/lsa.rb +23 -9
  77. data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -2
  78. data/lib/packetgen/header/ospfv3.rb +38 -34
  79. data/lib/packetgen/header/sctp/chunk.rb +38 -17
  80. data/lib/packetgen/header/sctp/error.rb +169 -197
  81. data/lib/packetgen/header/sctp/padded32.rb +3 -3
  82. data/lib/packetgen/header/sctp/parameter.rb +85 -132
  83. data/lib/packetgen/header/sctp.rb +14 -3
  84. data/lib/packetgen/header/snmp.rb +108 -7
  85. data/lib/packetgen/header/tcp/option.rb +7 -0
  86. data/lib/packetgen/header/tcp/options.rb +11 -3
  87. data/lib/packetgen/header/tcp.rb +33 -26
  88. data/lib/packetgen/header/tftp.rb +16 -10
  89. data/lib/packetgen/header/udp.rb +15 -13
  90. data/lib/packetgen/header.rb +19 -13
  91. data/lib/packetgen/headerable.rb +9 -3
  92. data/lib/packetgen/inspect.rb +2 -7
  93. data/lib/packetgen/packet.rb +94 -36
  94. data/lib/packetgen/pcapng/block.rb +2 -1
  95. data/lib/packetgen/pcapng/file.rb +41 -14
  96. data/lib/packetgen/pcapng/idb.rb +2 -1
  97. data/lib/packetgen/pcapng/shb.rb +2 -1
  98. data/lib/packetgen/pcapng/spb.rb +1 -1
  99. data/lib/packetgen/pcapng.rb +2 -0
  100. data/lib/packetgen/proto.rb +4 -0
  101. data/lib/packetgen/unknown_packet.rb +3 -3
  102. data/lib/packetgen/utils.rb +2 -1
  103. data/lib/packetgen/version.rb +1 -1
  104. data/lib/packetgen.rb +8 -2
  105. metadata +4 -4
@@ -27,32 +27,33 @@ module PacketGen
27
27
  # | Options | Padding |
28
28
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29
29
  # A IP header consists of:
30
- # * a first byte ({#u8} of {BinStruct::Int8} type) composed of:
30
+ # * a first byte ({#u8} of +BinStruct::Int8+ type) composed of:
31
31
  # * a 4-bit {#version} field,
32
32
  # * a 4-bit IP header length ({#ihl}) field,
33
- # * a Type of Service field ({#tos}, {BinStruct::Int8} type),
34
- # * a total length ({#length}, {BinStruct::Int16} type),
35
- # * a ID ({#id}, +Int16+ type),
36
- # * a {#frag} worg (+Int16+) composed of:
33
+ # * a Type of Service field ({#tos}, +BinStruct::Int8+ type),
34
+ # * a total length ({#length}, +BinStruct::Int16+ type),
35
+ # * a ID ({#id}, +BinStruct::Int16+ type),
36
+ # * a {#frag} worg (+BinStruct::Int16+) composed of:
37
37
  # * 3 1-bit flags ({#flag_rsv}, {#flag_df} and {#flag_mf}),
38
38
  # * a 13-bit {#fragment_offset} field,
39
39
  # * a Time-to-Live ({#ttl}) field (+Int8+),
40
- # * a {#protocol} field (+Int8+),
41
- # * a {#checksum} field (+Int16+),
40
+ # * a {#protocol} field (+BinStruct::Int8+),
41
+ # * a {#checksum} field (+BinStruct::Int16+),
42
42
  # * a source IP address ({#src}, {Addr} type),
43
- # * a destination IP address ({#dst}, +Addr+ type),
43
+ # * a destination IP address ({#dst}, {Addr} type),
44
44
  # * an optional {#options} field ({Options} type),
45
- # * and a {#body} ({BinStruct::String} type).
45
+ # * and a {#body} (+BinStruct::String+ type).
46
46
  #
47
- # == Create a IP header
47
+ # @example Create a IP header
48
48
  # # standalone
49
49
  # ip = PacketGen::Header::IP.new
50
50
  # # in a packet
51
51
  # pkt = PacketGen.gen('IP')
52
52
  # # access to IP header
53
- # pkt.ip # => PacketGen::Header::IP
53
+ # pkt.ip.class # => PacketGen::Header::IP
54
54
  #
55
- # == IP attributes
55
+ # @example IP attributes
56
+ # ip = PacketGen::Header::IP.new
56
57
  # ip.u8 = 0x45
57
58
  # # the same as
58
59
  # ip.version = 4
@@ -66,21 +67,20 @@ module PacketGen
66
67
  # ip.flag_mf = true
67
68
  # ip.fragment_offset = 0x31
68
69
  #
69
- # ip.flag_rsv? # => Boolean
70
- # ip.flag_df? # => Boolean
71
- # ip.flag_mf? # => Boolean
70
+ # ip.flag_rsv? # => false
71
+ # ip.flag_df? # => false
72
+ # ip.flag_mf? # => true
72
73
  #
73
74
  # ip.ttl = 0x40
74
75
  # ip.protocol = 6
75
76
  # ip.checksum = 0xffff
76
77
  # ip.src = '127.0.0.1'
77
78
  # ip.src # => "127.0.0.1"
78
- # ip[:src] # => PacketGen::Header::IP::Addr
79
+ # ip[:src].class # => PacketGen::Header::IP::Addr
79
80
  # ip.dst = '127.0.0.2'
80
- # ip.body.read 'this is a body'
81
+ # ip.body = 'this is a body'
81
82
  #
82
- # == Add IP options
83
- # IP has an {#options} attribute used to store datagram options.
83
+ # @example Add IP options
84
84
  # pkt = PacketGen.gen('IP')
85
85
  # # add option from class
86
86
  # pkt.ip.options << PacketGen::Header::IP::RA.new
@@ -101,52 +101,68 @@ module PacketGen
101
101
  # First byte of IP header. May be accessed through {#version} and {#ihl}.
102
102
  # @return [Integer] first byte of IP header.
103
103
  # @!attribute version
104
- # @return [Integer] 4-bit version attribute
104
+ # 4-bit version attribute
105
+ # @return [Integer]
105
106
  # @!attribute ihl
106
- # @return [Integer] 4-bit IP header length attribute
107
+ # 4-bit IP header length attribute, as 32-bit word count.
108
+ # Default to 5 (IP header without option).
109
+ # @return [Integer]
107
110
  define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
108
111
  # @!attribute tos
109
112
  # @return [Integer] 8-bit Type of Service self[attr]
110
113
  define_attr :tos, BinStruct::Int8, default: 0
111
114
  # @!attribute length
112
- # @return [Integer] 16-bit IP total length
115
+ # 16-bit IP total length, including this header.
116
+ # @return [Integer]
113
117
  define_attr :length, BinStruct::Int16, default: 20
114
118
  # @!attribute id
115
119
  # @return [Integer] 16-bit ID
116
120
  define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
117
121
  # @!attribute frag
118
- # @return [Integer] 16-bit frag word
122
+ # 16-bit frag word
123
+ # @return [Integer]
119
124
  # @!attribute flag_rsv
120
- # @return [Boolean] reserved bit from flags
125
+ # reserved bit from flags
126
+ # @return [Boolean]
121
127
  # @!attribute flag_df
122
- # @return [Boolean] Don't Fragment flag
128
+ # Don't Fragment flag
129
+ # @return [Boolean]
123
130
  # @!attribute flag_mf
124
- # @return [Boolean] More Fragment flags
131
+ # More Fragment flags
132
+ # @return [Boolean]
125
133
  # @!attribute fragment_offset
126
- # @return [Integer] 13-bit fragment offset
134
+ # 13-bit fragment offset
135
+ # @return [Integer]
127
136
  define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
128
137
  # @!attribute ttl
129
- # @return [Integer] 8-bit Time To Live self[attr]
138
+ # 8-bit Time To Live
139
+ # @return [Integer]
130
140
  define_attr :ttl, BinStruct::Int8, default: 64
131
141
  # @!attribute protocol
132
- # @return [Integer] 8-bit upper protocol self[attr]
142
+ # 8-bit upper protocol
143
+ # @return [Integer]
133
144
  define_attr :protocol, BinStruct::Int8
134
145
  # @!attribute checksum
135
- # @return [Integer] 16-bit IP header checksum
146
+ # 16-bit IP header checksum
147
+ # @return [Integer]
136
148
  define_attr :checksum, BinStruct::Int16, default: 0
137
149
  # @!attribute src
138
- # @return [Addr] source IP address
150
+ # source IP address
151
+ # @return [Addr]
139
152
  define_attr :src, Addr, default: '127.0.0.1'
140
153
  # @!attribute dst
141
- # @return [Addr] destination IP address
154
+ # destination IP address
155
+ # @return [Addr]
142
156
  define_attr :dst, Addr, default: '127.0.0.1'
143
157
  # @!attribute options
158
+ # IP options
144
159
  # @since 2.2.0
145
- # @return [BinStruct::String]
160
+ # @return [Options]
146
161
  define_attr :options, Options, optional: ->(h) { h.ihl > 5 },
147
162
  builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
148
163
  # @!attribute body
149
- # @return [BinStruct::String,Header::Base]
164
+ # IP body
165
+ # @return [BinStruct::String,Headerable]
150
166
  define_attr :body, BinStruct::String
151
167
 
152
168
  # Helper method to compute sum of 16-bit words. Used to compute IP-style
@@ -224,7 +240,8 @@ module PacketGen
224
240
  end
225
241
 
226
242
  # Check version field
227
- # @see [Base#parse?]
243
+ # @see Base#parse?
244
+ # @return [Boolean]
228
245
  def parse?
229
246
  (version == 4) && (ihl >= 5)
230
247
  end
@@ -14,6 +14,7 @@ module PacketGen
14
14
  class IPv6
15
15
  # IPv6 address, as a group of 8 2-byte words
16
16
  # @author Sylvain Daubert
17
+ # @author LemonTree55
17
18
  class Addr < BinStruct::Struct
18
19
  include BinStruct::Structable
19
20
 
@@ -50,11 +51,10 @@ module PacketGen
50
51
  # @return [Integer]
51
52
  define_attr :a8, BinStruct::Int16
52
53
 
53
- # rubocop:disable Metrics/AbcSize
54
-
55
54
  # Read a colon-delimited address
56
55
  # @param [String] str
57
56
  # @return [self]
57
+ # @raise [ArgumentError] not a colon-delimited IPv6 address
58
58
  def from_human(str)
59
59
  return self if str.nil?
60
60
 
@@ -62,19 +62,13 @@ module PacketGen
62
62
  raise ArgumentError, 'string is not a IPv6 address' unless addr.ipv6?
63
63
 
64
64
  addri = addr.to_i
65
- self.a1 = addri >> 112
66
- self.a2 = addri >> 96 & 0xffff
67
- self.a3 = addri >> 80 & 0xffff
68
- self.a4 = addri >> 64 & 0xffff
69
- self.a5 = addri >> 48 & 0xffff
70
- self.a6 = addri >> 32 & 0xffff
71
- self.a7 = addri >> 16 & 0xffff
72
- self.a8 = addri & 0xffff
65
+ 8.times do |i|
66
+ self.send(:"a#{i + 1}=", addri >> (16 * (7 - i)) & 0xffff)
67
+ end
73
68
  self
74
69
  end
75
- # rubocop:enable Metrics/AbcSize
76
70
 
77
- # Addr6 in human readable form (colon-delimited hex string)
71
+ # Return IPv6 address in human readable form (colon-delimited hex string)
78
72
  # @return [String]
79
73
  def to_human
80
74
  IPAddr.new(to_a.map { |a| a.to_i.to_s(16) }.join(':')).to_s
@@ -92,6 +86,9 @@ module PacketGen
92
86
  self.a1 & 0xff00 == 0xff00
93
87
  end
94
88
 
89
+ # Check equaliy to +other+.
90
+ # Equal if other has the same class, and all attributes are equal
91
+ # @return [Boolean]
95
92
  def ==(other)
96
93
  other.is_a?(self.class) &&
97
94
  attributes.all? { |attr| self[attr].value == other[attr].value }
@@ -106,7 +103,11 @@ module PacketGen
106
103
  # Push a IPv6 address to the array
107
104
  # @param [String,Addr] addr
108
105
  # @return [self]
109
- # array << '2001:1234::125'
106
+ # @example
107
+ # array = PacketGen::Header::IPv6::ArrayOfAddr.new
108
+ # # #<< uses #push internally
109
+ # array << '2001::1'
110
+ # array.push(PacketGen::Header::IPv6::Addr.new.from_human('1:2:3:abcd::1'))
110
111
  def push(addr)
111
112
  addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
112
113
  super
@@ -9,7 +9,7 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class IPv6
12
- # Base class to handle IPv6 extensions
12
+ # Base class to handle IPv6 extensions.
13
13
  # @abstract You should not use this class but its subclasses.
14
14
  # A IPv6 extension header has the following format:
15
15
  # 0 1 2 3
@@ -25,11 +25,12 @@ module PacketGen
25
25
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26
26
  #
27
27
  # Such a header consists of:
28
- # * a {#next} header field ({BinStruct::Int8}),
29
- # * a {#length} field ({BinStruct::Int8}),
30
- # * an {#options} field ({BinStruct::String}),
28
+ # * a {#next} header field (+BinStruct::Int8+),
29
+ # * a {#length} field (+BinStruct::Int8+),
30
+ # * an {#options} field (+BinStruct::String+),
31
31
  # * and a {#body}, containing next header.
32
32
  # @author Sylvain Daubert
33
+ # @since 2.4.0
33
34
  class Extension < Base
34
35
  # @!attribute next
35
36
  # 8-bit Next header field
@@ -44,9 +45,10 @@ module PacketGen
44
45
  # Specific options of extension header
45
46
  # @return [String]
46
47
  define_attr :options, BinStruct::String,
47
- builder: ->(h, t) { t.new(length_from: -> { h.real_length }) }
48
+ builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2}) }
48
49
  # @!attribute body
49
- # @return [String,Base]
50
+ # Next header in IPv6 packet
51
+ # @return [String,Headerable]
50
52
  define_attr :body, BinStruct::String
51
53
 
52
54
  # Get real extension header length
@@ -55,7 +57,7 @@ module PacketGen
55
57
  (length + 1) * 8
56
58
  end
57
59
 
58
- # Compute length and set +len+ field
60
+ # Compute length and set {#length}+ attribute
59
61
  # @return [Integer]
60
62
  def calc_length
61
63
  self.length = (options.sz + 2) / 8 - 1
@@ -11,7 +11,8 @@ module PacketGen
11
11
  class IPv6
12
12
  # @!parse
13
13
  # # Option for {HopByHop} IPv6 extension header.
14
- # # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
14
+ # # @since 2.4.0
15
+ # # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
15
16
  # class Option <AbstractTLV; end
16
17
  # @private
17
18
  Option = BinStruct::AbstractTLV.create
@@ -23,6 +24,7 @@ module PacketGen
23
24
  5 => 'router_alert'
24
25
  }.freeze
25
26
 
27
+ # Get human-readable string
26
28
  # @return [String]
27
29
  def to_human
28
30
  case type
@@ -35,13 +37,16 @@ module PacketGen
35
37
  end
36
38
  Option.define_type_enum Option::TYPES.invert
37
39
 
38
- # Special option pad1, for {HopByHop} IPv6 extension header
40
+ # Special option pad1 (one-byte option), for {HopByHop} IPv6 extension header
39
41
  # @author Sylvain Daubert
42
+ # @since 2.4.0
40
43
  class Pad1 < BinStruct::Struct
41
44
  # @!attribute pad
42
- # @return [Integer]
45
+ # Pad1 option type
46
+ # @return [Integer]
43
47
  define_attr :pad, BinStruct::Int8, default: 0
44
48
 
49
+ # Get human-readable string
45
50
  # @return [String]
46
51
  def to_human
47
52
  'pad1'
@@ -50,6 +55,7 @@ module PacketGen
50
55
 
51
56
  # Array of {Option}, for {HopByHop} IPv6 extension header
52
57
  # @author Sylvain Daubert
58
+ # @since 2.4.0
53
59
  class Options < BinStruct::Array
54
60
  set_of Option
55
61
 
@@ -96,18 +102,31 @@ module PacketGen
96
102
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97
103
  #
98
104
  # Hop-by-hop IPv6 extension header consists of:
99
- # * a {#next} header field ({BinStruct::Int8}),
100
- # * a {#length} field ({BinStruct::Int8}),
105
+ # * a {#next #next} header field (+BinStruct::Int8+),
106
+ # * a {#length #length} field (+BinStruct::Int8+),
101
107
  # * an {#options} field ({Options}),
102
- # * and a {#body}, containing next header.
108
+ # * and a {#body #body}, containing next header.
109
+ # @example
110
+ # pkt = PacketGen.gen('Eth').add('IPv6').add('IPv6::HopByHop').add('ICMPv6')
111
+ # pkt.ipv6_hopbyhop.options << { type: 'router_alert', value: "\x00\x00".b }
103
112
  # @author Sylvain Daubert
113
+ # @since 2.4.0
104
114
  class HopByHop < Extension
105
115
  # redefine options field
106
116
  remove_attr :options
107
117
  # @!attribute options
108
- # Specific options of extension header
118
+ # Specific HopByHop options
109
119
  # @return [Options]
110
120
  define_attr_before :body, :options, Options, builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2 }) }
121
+
122
+ # Generate binary string. Add padding if needed in {#options}, and update {#length} accordingly.
123
+ # @return [String]
124
+ # @since 2.4.0
125
+ # @since 4.1.0 Set {Extension#length}.
126
+ def to_s
127
+ calc_length
128
+ super
129
+ end
111
130
  end
112
131
  end
113
132
 
@@ -37,26 +37,27 @@ module PacketGen
37
37
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38
38
  #
39
39
  # A IPv6 header consists of:
40
- # * a first 32-bit word ({#u32}, of {BinStruct::Int32} type) composed of:
40
+ # * a first 32-bit word ({#u32}, of +BinStruct::Int32+ type) composed of:
41
41
  # * a 4-bit {#version} field,
42
42
  # * a 8-bit {#traffic_class} field,
43
43
  # * a 20-bit {#flow_label} field,
44
- # * a payload length field ({#length}, {BinStruct::Int16} type}),
45
- # * a next header field ({#next}, {BinStruct::Int8} type),
46
- # * a hop-limit field ({#hop}, +Int8+ type),
44
+ # * a payload length field ({#length}, +BinStruct::Int16+ type}),
45
+ # * a next header field ({#next}, +BinStruct::Int8+ type),
46
+ # * a hop-limit field ({#hop}, +BinStruct::Int8+ type),
47
47
  # * a source address field ({#src}, {IPv6::Addr} type),
48
- # * a destination address field ({#dst}, +IPv6::Addr+ type),
49
- # * and a {#body} ({BinStruct::String} type).
48
+ # * a destination address field ({#dst}, {IPv6::Addr} type),
49
+ # * and a {#body} (+BinStruct::String+ type).
50
50
  #
51
- # == Create a IPv6 header
51
+ # @example Create a IPv6 header
52
52
  # # standalone
53
53
  # ipv6 = PacketGen::Header::IPv6.new
54
54
  # # in a packet
55
55
  # pkt = PacketGen.gen('IPv6')
56
56
  # # access to IPv6 header
57
- # pkt.ipv6 # => PacketGen::Header::IPv6
57
+ # pkt.ipv6.class # => PacketGen::Header::IPv6
58
58
  #
59
- # == IPv6 attributes
59
+ # @example IPv6 attributes
60
+ # ipv6 = PacketGen::Header::IPv6.new
60
61
  # ipv6.u32 = 0x60280001
61
62
  # # the same as
62
63
  # ipv6.version = 6
@@ -68,9 +69,9 @@ module PacketGen
68
69
  # ipv6.next = 6
69
70
  # ipv6.src = '::1'
70
71
  # ipv6.src # => "::1"
71
- # ipv6[:src] # => PacketGen::Header::IPv6::Addr
72
+ # ipv6[:src].class # => PacketGen::Header::IPv6::Addr
72
73
  # ipv6.dst = '2001:1234:5678:abcd::123'
73
- # ipv6.body.read 'this is a body'
74
+ # ipv6.body ='this is a body'
74
75
  #
75
76
  # == Add IPv6 extensions
76
77
  # In IPv6, optional extensions are encoded in separate headers that
@@ -84,6 +85,7 @@ module PacketGen
84
85
  # # Add another header
85
86
  # pkt.add('UDP')
86
87
  # @author Sylvain Daubert
88
+ # @author LemonTree55
87
89
  class IPv6 < Base; end
88
90
 
89
91
  require_relative 'ipv6/addr'
@@ -96,11 +98,14 @@ module PacketGen
96
98
  # First 32-bit word of IPv6 header
97
99
  # @return [Integer]
98
100
  # @!attribute version
99
- # @return [Integer] 4-bit version attribute
101
+ # 4-bit version attribute
102
+ # @return [Integer]
100
103
  # @!attribute traffic_class
101
- # @return [Integer] 8-bit traffic_class attribute
104
+ # 8-bit traffic_class attribute
105
+ # @return [Integer]
102
106
  # @!attribute flow_label
103
- # @return [Integer] 20-bit flow_label attribute
107
+ # 20-bit flow_label attribute
108
+ # @return [Integer]
104
109
  define_bit_attr :u32, default: 0x60000000, version: 4, traffic_class: 8, flow_label: 20
105
110
  # @!attribute length
106
111
  # 16-bit word of IPv6 payload length
@@ -123,10 +128,11 @@ module PacketGen
123
128
  # @return [Addr]
124
129
  define_attr :dst, Addr, default: '::1'
125
130
  # @!attribute body
126
- # @return [BinStruct::String,Header::Base]
131
+ # IPv6 body
132
+ # @return [BinStruct::String,Headerable]
127
133
  define_attr :body, BinStruct::String
128
134
 
129
- # Compute length and set +len+ field
135
+ # Compute length and set {#length} field
130
136
  # @return [Integer]
131
137
  def calc_length
132
138
  Base.calculate_and_set_length self, header_in_size: false
@@ -141,7 +147,7 @@ module PacketGen
141
147
  sum
142
148
  end
143
149
 
144
- # Send IPv6 packet on wire. All attributes.may be set (even {#version}).
150
+ # Send IPv6 packet on wire. All attributes may be set (even {#version}).
145
151
  # @param [String] _iface interface name (not used)
146
152
  # @return [void]
147
153
  # @since 3.0.0 no more limitations on +flow_label+, +length+ and +src+ fields.
@@ -168,7 +174,7 @@ module PacketGen
168
174
  end
169
175
 
170
176
  # Check version field
171
- # @see [Base#parse?]
177
+ # @see Base#parse?
172
178
  def parse?
173
179
  version == 6
174
180
  end
@@ -197,15 +203,18 @@ module PacketGen
197
203
  module Header
198
204
  class IPv6
199
205
  class << self
206
+ # @private
200
207
  alias old_bind bind
201
208
 
202
209
  # Bind a upper header to IPv6 and its defined extension headers.
203
210
  # @see Base.bind
211
+ # @author LemonTree55
204
212
  def bind(header_klass, args={})
205
- IPv6.old_bind header_klass, args
206
- [IPv6::HopByHop].each do |klass|
207
- klass.bind header_klass, args
208
- end
213
+ IPv6.old_bind(header_klass, args)
214
+ IPv6.constants
215
+ .map { |cname| IPv6.const_get(cname) }
216
+ .select { |klass| klass.is_a?(Class) && (klass < Extension) }
217
+ .each { |klass| klass.bind(header_klass, args) }
209
218
  end
210
219
  end
211
220
  end
@@ -12,24 +12,28 @@ module PacketGen
12
12
  # Logical-Link Control header
13
13
  #
14
14
  # A LLC header consists of:
15
- # * a {#dsap} ({BinStruct::Int8}),
16
- # * a {#ssap} ({BinStruct::Int8}),
17
- # * a {#control} ({BinStruct::Int8}),
18
- # * and a {#body} (a {BinStruct::String} or another {Base} class).
15
+ # * a {#dsap} (+BinStruct::Int8+),
16
+ # * a {#ssap} (+BinStruct::Int8+),
17
+ # * a {#control} (+BinStruct::Int8+),
18
+ # * and a {#body} (a +BinStruct::String+ or another {Headerable} class).
19
19
  # @author Sylvain Daubert
20
20
  # @since 1.4.0
21
21
  class LLC < Base
22
22
  # @!attribute dsap
23
- # @return [Integer] 8-bit dsap value
23
+ # 8-bit Destination Service Access Point value
24
+ # @return [Integer]
24
25
  define_attr :dsap, BinStruct::Int8
25
26
  # @!attribute ssap
26
- # @return [Integer] 8-bit ssap value
27
+ # 8-bit Source Service Access Point value
28
+ # @return [Integer]
27
29
  define_attr :ssap, BinStruct::Int8
28
30
  # @!attribute control
29
- # @return [Integer] 8-bit control value
31
+ # 8-bit control value
32
+ # @return [Integer]
30
33
  define_attr :control, BinStruct::Int8
31
34
  # @!attribute body
32
- # @return [BinStruct::String,Header::Base]
35
+ # LLC body
36
+ # @return [BinStruct::String,Headerable]
33
37
  define_attr :body, BinStruct::String
34
38
  end
35
39
  self.add_class LLC
@@ -38,20 +42,23 @@ module PacketGen
38
42
  # Sub-Network Access Protocol
39
43
  #
40
44
  # A SNAP header consists of:
41
- # * a {#oui} ({BinStruct::OUI}),
42
- # * a {#proto_id} ({BinStruct::Int16}),
43
- # * and a {#body} (a {BinStruct::String} or another {Base} class).
45
+ # * a {#oui} (+BinStruct::OUI+),
46
+ # * a {#proto_id} (+BinStruct::Int16+),
47
+ # * and a {#body} (a +BinStruct::String+ or another {Headerable} class).
44
48
  # @author Sylvain Daubert
45
49
  # @since 1.4.0
46
50
  class SNAP < Base
47
51
  # @!attribute oui
52
+ # If +00:00:00+, {#proto_id} is an EtherType. Else, {#proto_id} is specified by organization specified BY +OUI+.
48
53
  # @return [BinStruct::OUI]
49
54
  define_attr :oui, BinStruct::OUI
50
55
  # @!attribute proto_id
51
- # @return [Integer] 16-bit protocol id
56
+ # 16-bit protocol id
57
+ # @return [Integer]
52
58
  define_attr :proto_id, BinStruct::Int16
53
59
  # @!attribute body
54
- # @return [BinStruct::String,Header::Base]
60
+ # SNAP header
61
+ # @return [BinStruct::String,Headerable]
55
62
  define_attr :body, BinStruct::String
56
63
  end
57
64
  self.add_class SNAP
@@ -21,12 +21,18 @@ module PacketGen
21
21
  # Fixup IP header according to RFC 6762:
22
22
  # * set ethernet multicast address to +01:00:5E:00:00:FB+ (for IPv4)
23
23
  # or +33:33:00:00:00:FB+ (for IPv6),
24
- # * set IPv4 address to 224.0.0.251 or IPv6 address to ff02::fb.
24
+ # * set IPv4 address to +224.0.0.251+ or IPv6 address to +ff02::fb+.
25
25
  # This method may be called as:
26
26
  # # first way
27
27
  # pkt.mdns.mdnsize
28
28
  # # second way
29
- # pkt.mdnsize
29
+ # pkt.
30
+ # @example
31
+ # pkt = PacketGen.gen('Eth').add('IP').add('UDP').add('MDNS')
32
+ # pkt.mdnsize
33
+ # pkt.eth.dst #=> "01:00:5e:00:00:fb"
34
+ # pkt.ip.dst #=> "224.0.0.251"
35
+ # @return [void]
30
36
  def mdnsize
31
37
  iph = ip_header(self)
32
38
  case iph
@@ -42,6 +48,7 @@ module PacketGen
42
48
  # @api private
43
49
  # @note This method is used internally by PacketGen and should not be
44
50
  # directly called
51
+ # Add +#mdnsize+ method to +packet+. This method calls {#mdnsize}.
45
52
  # @since 2.7.0 Set UDP sport according to bindings, only if sport is 0.
46
53
  # Needed by new bind API.
47
54
  def added_to_packet(packet)
@@ -8,7 +8,7 @@
8
8
 
9
9
  module PacketGen
10
10
  module Header
11
- # This class supports MLDv1 (RFC 2710).
11
+ # This class supports Multicast Listener Discovery for IPv6 (RFC 2710).
12
12
  #
13
13
  # From RFC 2710, a MLD header has the following format:
14
14
  # 0 1 2 3
@@ -26,23 +26,24 @@ module PacketGen
26
26
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
27
  #
28
28
  # A MLD header consists of:
29
- # * a {#max_resp_delay} field ({BinStruct::Int16} type),
30
- # * a {#reserved} field ({BinStruct::Int16} type),
29
+ # * a {#max_resp_delay} field (+BinStruct::Int16+ type),
30
+ # * a {#reserved} field (+BinStruct::Int16+ type),
31
31
  # * a {#mcast_addr} field ({Header::IPv6::Addr} type),
32
32
  # * and a {#body} (unused for MLDv1).
33
33
  #
34
- # == Create a MLD header
34
+ # @example Create a MLD header
35
35
  # # standalone
36
36
  # mld = PacketGen::Header::MLD.new
37
37
  # # in a packet
38
38
  # pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
39
39
  # # access to MLD header
40
- # pkt.mld # => PacketGen::Header::MLD
40
+ # pkt.mld.class # => PacketGen::Header::MLD
41
41
  #
42
- # == MLD attributes
43
- # pkt.icmpv6.type = 130 # ICMPv6 type 130 is MLD Multicast Listener Query
42
+ # @example MLD attributes
43
+ # pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
44
+ # pkt.icmpv6.type = 130 # ICMPv6 type 130 is MLD Multicast Listener Query
44
45
  # pkt.mld.max_resp_delay = 20
45
- # pkt.mld.group_addr = '::'
46
+ # pkt.mld.mcast_addr = '::'
46
47
  # @author Sylvain Daubert
47
48
  # @since 2.4.0
48
49
  class MLD < Base
@@ -61,12 +62,13 @@ module PacketGen
61
62
  # @return [IPv6::Addr]
62
63
  define_attr :mcast_addr, IPv6::Addr, default: '::'
63
64
  # @!attribute body
64
- # @return [String,Base]
65
+ # @return [String,Headerable]
65
66
  define_attr :body, BinStruct::String
66
67
 
67
68
  # @api private
68
69
  # @note This method is used internally by PacketGen and should not be
69
70
  # directly called
71
+ # This method adds +#mldize+ method to +packet+. This method calls {#mldize}.
70
72
  def added_to_packet(packet)
71
73
  mld_idx = packet.headers.size
72
74
  packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end" # def mldize() @headers[3].mldize; end
@@ -81,14 +81,19 @@ module PacketGen
81
81
  define_attr :source_addr, IPv6::ArrayOfAddr,
82
82
  builder: ->(h, t) { t.new(counter: h[:number_of_sources]) }
83
83
  # @!attribute aux_data
84
+ # Auxiliary data
84
85
  # @return [String]
85
86
  define_attr :aux_data, BinStruct::String,
86
87
  builder: ->(h, t) { t.new(length_from: -> { h[:aux_data_len].to_i * 4 }) }
87
88
 
89
+ # Get human-readable type
90
+ # @return [String]
88
91
  def human_type
89
92
  self[:type].to_human
90
93
  end
91
94
 
95
+ # Get human-readable description
96
+ # @return [String]
92
97
  def to_human
93
98
  "#{human_type}(ma:#{multicast_addr}|src:#{source_addr.to_human})"
94
99
  end
@@ -99,7 +104,7 @@ module PacketGen
99
104
  class McastAddressRecords < BinStruct::Array
100
105
  set_of McastAddressRecord
101
106
 
102
- # Separator used in {#to_human}.
107
+ # Separator used in +#to_human+.
103
108
  HUMAN_SEPARATOR = ';'
104
109
  end
105
110
  end