packetgen 2.4.0 → 2.5.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 (127) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +13 -4
  3. data/lib/packetgen.rb +3 -1
  4. data/lib/packetgen/capture.rb +2 -0
  5. data/lib/packetgen/config.rb +1 -0
  6. data/lib/packetgen/header.rb +5 -0
  7. data/lib/packetgen/header/arp.rb +2 -0
  8. data/lib/packetgen/header/asn1_base.rb +2 -0
  9. data/lib/packetgen/header/base.rb +16 -0
  10. data/lib/packetgen/header/bootp.rb +2 -0
  11. data/lib/packetgen/header/crypto.rb +2 -0
  12. data/lib/packetgen/header/dhcp.rb +2 -0
  13. data/lib/packetgen/header/dhcp/option.rb +3 -0
  14. data/lib/packetgen/header/dhcp/options.rb +2 -0
  15. data/lib/packetgen/header/dhcpv6.rb +109 -0
  16. data/lib/packetgen/header/dhcpv6/duid.rb +147 -0
  17. data/lib/packetgen/header/dhcpv6/option.rb +391 -0
  18. data/lib/packetgen/header/dhcpv6/options.rb +29 -0
  19. data/lib/packetgen/header/dhcpv6/relay.rb +48 -0
  20. data/lib/packetgen/header/dns.rb +10 -2
  21. data/lib/packetgen/header/dns/name.rb +7 -0
  22. data/lib/packetgen/header/dns/opt.rb +6 -0
  23. data/lib/packetgen/header/dns/option.rb +7 -0
  24. data/lib/packetgen/header/dns/qdsection.rb +7 -1
  25. data/lib/packetgen/header/dns/question.rb +7 -0
  26. data/lib/packetgen/header/dns/rr.rb +7 -0
  27. data/lib/packetgen/header/dns/rrsection.rb +7 -0
  28. data/lib/packetgen/header/dot11.rb +4 -2
  29. data/lib/packetgen/header/dot11/control.rb +2 -0
  30. data/lib/packetgen/header/dot11/data.rb +2 -0
  31. data/lib/packetgen/header/dot11/element.rb +2 -0
  32. data/lib/packetgen/header/dot11/management.rb +2 -0
  33. data/lib/packetgen/header/dot11/sub_mngt.rb +2 -0
  34. data/lib/packetgen/header/dot1q.rb +2 -0
  35. data/lib/packetgen/header/dot1x.rb +3 -1
  36. data/lib/packetgen/header/eap.rb +3 -1
  37. data/lib/packetgen/header/eap/fast.rb +2 -0
  38. data/lib/packetgen/header/eap/md5.rb +2 -0
  39. data/lib/packetgen/header/eap/tls.rb +2 -0
  40. data/lib/packetgen/header/eap/ttls.rb +2 -0
  41. data/lib/packetgen/header/esp.rb +7 -0
  42. data/lib/packetgen/header/eth.rb +2 -0
  43. data/lib/packetgen/header/gre.rb +4 -9
  44. data/lib/packetgen/header/http/headers.rb +2 -0
  45. data/lib/packetgen/header/http/request.rb +3 -1
  46. data/lib/packetgen/header/http/response.rb +3 -1
  47. data/lib/packetgen/header/icmp.rb +4 -11
  48. data/lib/packetgen/header/icmpv6.rb +4 -11
  49. data/lib/packetgen/header/igmp.rb +4 -11
  50. data/lib/packetgen/header/igmpv3.rb +4 -11
  51. data/lib/packetgen/header/igmpv3/group_record.rb +2 -0
  52. data/lib/packetgen/header/igmpv3/mq.rb +2 -0
  53. data/lib/packetgen/header/igmpv3/mr.rb +2 -0
  54. data/lib/packetgen/header/ike.rb +13 -6
  55. data/lib/packetgen/header/ike/auth.rb +2 -0
  56. data/lib/packetgen/header/ike/cert.rb +2 -0
  57. data/lib/packetgen/header/ike/certreq.rb +2 -0
  58. data/lib/packetgen/header/ike/id.rb +2 -0
  59. data/lib/packetgen/header/ike/ke.rb +2 -0
  60. data/lib/packetgen/header/ike/nonce.rb +2 -0
  61. data/lib/packetgen/header/ike/notify.rb +7 -0
  62. data/lib/packetgen/header/ike/payload.rb +9 -0
  63. data/lib/packetgen/header/ike/sa.rb +11 -4
  64. data/lib/packetgen/header/ike/sk.rb +7 -0
  65. data/lib/packetgen/header/ike/ts.rb +2 -0
  66. data/lib/packetgen/header/ike/vendor_id.rb +2 -0
  67. data/lib/packetgen/header/ip.rb +48 -11
  68. data/lib/packetgen/header/ip/addr.rb +8 -0
  69. data/lib/packetgen/header/ip/option.rb +2 -0
  70. data/lib/packetgen/header/ip/options.rb +2 -0
  71. data/lib/packetgen/header/ipv6.rb +5 -3
  72. data/lib/packetgen/header/ipv6/addr.rb +8 -0
  73. data/lib/packetgen/header/ipv6/extension.rb +2 -0
  74. data/lib/packetgen/header/ipv6/hop_by_hop.rb +2 -0
  75. data/lib/packetgen/header/llc.rb +2 -0
  76. data/lib/packetgen/header/mld.rb +2 -0
  77. data/lib/packetgen/header/mldv2.rb +4 -2
  78. data/lib/packetgen/header/mldv2/mcast_address_record.rb +3 -1
  79. data/lib/packetgen/header/mldv2/mlq.rb +2 -0
  80. data/lib/packetgen/header/mldv2/mlr.rb +4 -2
  81. data/lib/packetgen/header/ospfv2.rb +249 -0
  82. data/lib/packetgen/header/ospfv2/db_description.rb +105 -0
  83. data/lib/packetgen/header/ospfv2/hello.rb +104 -0
  84. data/lib/packetgen/header/ospfv2/ls_ack.rb +55 -0
  85. data/lib/packetgen/header/ospfv2/ls_request.rb +90 -0
  86. data/lib/packetgen/header/ospfv2/ls_update.rb +72 -0
  87. data/lib/packetgen/header/ospfv2/lsa.rb +252 -0
  88. data/lib/packetgen/header/ospfv2/lsa_header.rb +122 -0
  89. data/lib/packetgen/header/ospfv3.rb +216 -0
  90. data/lib/packetgen/header/ospfv3/db_description.rb +114 -0
  91. data/lib/packetgen/header/ospfv3/hello.rb +104 -0
  92. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +103 -0
  93. data/lib/packetgen/header/ospfv3/ls_ack.rb +51 -0
  94. data/lib/packetgen/header/ospfv3/ls_request.rb +108 -0
  95. data/lib/packetgen/header/ospfv3/ls_update.rb +74 -0
  96. data/lib/packetgen/header/ospfv3/lsa.rb +252 -0
  97. data/lib/packetgen/header/ospfv3/lsa_header.rb +123 -0
  98. data/lib/packetgen/header/snmp.rb +2 -0
  99. data/lib/packetgen/header/tcp.rb +14 -14
  100. data/lib/packetgen/header/tcp/option.rb +7 -1
  101. data/lib/packetgen/header/tcp/options.rb +7 -0
  102. data/lib/packetgen/header/tftp.rb +2 -0
  103. data/lib/packetgen/header/udp.rb +6 -14
  104. data/lib/packetgen/inspect.rb +5 -1
  105. data/lib/packetgen/packet.rb +3 -1
  106. data/lib/packetgen/pcapng.rb +2 -0
  107. data/lib/packetgen/pcapng/block.rb +2 -0
  108. data/lib/packetgen/pcapng/epb.rb +2 -0
  109. data/lib/packetgen/pcapng/file.rb +2 -0
  110. data/lib/packetgen/pcapng/idb.rb +2 -0
  111. data/lib/packetgen/pcapng/shb.rb +2 -0
  112. data/lib/packetgen/pcapng/spb.rb +2 -0
  113. data/lib/packetgen/pcapng/unknown_block.rb +2 -0
  114. data/lib/packetgen/proto.rb +2 -0
  115. data/lib/packetgen/types/array.rb +3 -0
  116. data/lib/packetgen/types/cstring.rb +3 -1
  117. data/lib/packetgen/types/enum.rb +2 -0
  118. data/lib/packetgen/types/fields.rb +8 -4
  119. data/lib/packetgen/types/int.rb +3 -1
  120. data/lib/packetgen/types/int_string.rb +2 -0
  121. data/lib/packetgen/types/oui.rb +2 -0
  122. data/lib/packetgen/types/string.rb +3 -0
  123. data/lib/packetgen/types/tlv.rb +8 -0
  124. data/lib/packetgen/utils.rb +6 -4
  125. data/lib/packetgen/utils/arp_spoofer.rb +2 -0
  126. data/lib/packetgen/version.rb +3 -1
  127. metadata +25 -3
@@ -0,0 +1,122 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+ class OSPFv2
11
+
12
+ # This class handles {OSPFv2 OSPFv2} LSA header. A LSA header has the
13
+ # following format:
14
+ # 0 1 2 3
15
+ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17
+ # | LS age | Options | LS type |
18
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
+ # | Link State ID |
20
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21
+ # | Advertising Router |
22
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
+ # | LS sequence number |
24
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
+ # | LS checksum | length |
26
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
+ #
28
+ # == About LSA headers
29
+ # LSA headers are used as-is in {DbDescription} payload. But this class
30
+ # is also a base class for different LSA class, as {LSARouter}.
31
+ # @author Sylvain Daubert
32
+ class LSAHeader < Types::Fields
33
+ # LSA Types
34
+ TYPES = {
35
+ 'Router' => 1,
36
+ 'Network' => 2,
37
+ 'Summary-IP' => 3,
38
+ 'Summary-ABSR' => 4,
39
+ 'AS-External' => 5
40
+ }
41
+
42
+ # @!attribute age
43
+ # The time in seconds since the LSA was originated.
44
+ # @return [Integer]
45
+ define_field :age, Types::Int16
46
+ # @!macro define_options
47
+ OSPFv2.define_options(self)
48
+ # @!attribute type
49
+ # The type of the LSA.
50
+ # @return [Integer]
51
+ define_field :type, Types::Int8Enum, enum: TYPES
52
+ # @!attribute link_state_id
53
+ # This field identifies the portion of the internet environment
54
+ # that is being described by the LSA.
55
+ # @return [String]
56
+ define_field :link_state_id, IP::Addr
57
+ # @!attribute advertising_router
58
+ # The Router ID of the router that originated the LSA.
59
+ # @return [String]
60
+ define_field :advertising_router, IP::Addr
61
+ # @!attribute sequence_number
62
+ # @return [Integer]
63
+ define_field :sequence_number, Types::Int32
64
+ alias seqnum sequence_number
65
+ alias seqnum= sequence_number=
66
+ # @!attribute checksum
67
+ # The Fletcher checksum of the complete contents of the LSA,
68
+ # including the LSA header but excluding the LS age field.
69
+ # @return [Integer]
70
+ define_field :checksum, Types::Int16
71
+ # @!attribute length
72
+ # Length of the LSA, including the header.
73
+ # @return [Integer]
74
+ define_field :length, Types::Int16
75
+
76
+ # Compute and set Fletcher-16 checksum on LSA
77
+ # @return [Integer]
78
+ def calc_checksum
79
+ self.checksum = 0
80
+ bytes = to_s[2..-1].unpack('C*')
81
+
82
+ c0 = c1 = 0
83
+ bytes.each do |byte|
84
+ c0 += byte
85
+ c1 += c0
86
+ end
87
+ c0 %= 255
88
+ c1 %= 255
89
+
90
+ x = ((sz - 16 - 1) * c0 - c1) % 255
91
+ x += 255 if x <= 0
92
+ y = 255*2 - c0 - x
93
+ y -= 255 if y > 255
94
+ self.checksum = (x << 8) | y
95
+ end
96
+
97
+ # Compute length and set +length+ field
98
+ # @return [Integer]
99
+ def calc_length
100
+ self.length = Base.calculate_and_set_length(self)
101
+ end
102
+
103
+ # Get human-readable type
104
+ # @return [String]
105
+ def human_type
106
+ self[:type].to_human
107
+ end
108
+
109
+ # @return [String]
110
+ def to_human
111
+ "LSA<#{human_type},#{link_state_id},#{advertising_router}>"
112
+ end
113
+
114
+ # Extract header from current LSA
115
+ # @return [LSAHeader]
116
+ def to_lsa_header
117
+ LSAHeader.new(self.to_h)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,216 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+
11
+ # This class supports OSPFv3 (RFC 5340).
12
+ # A OSPFv3 header has the following format:
13
+ #
14
+ # 0 1 2 3
15
+ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17
+ # | Version # | Type | Packet length |
18
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
+ # | Router ID |
20
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21
+ # | Area ID |
22
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
+ # | Checksum | Instance ID | 0 |
24
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
+ #
26
+ # An OSPFv3 header consists of:
27
+ # * a {#version} field ({Types::Int8}),
28
+ # * a {#type} field ({Types::Int8Enum}),
29
+ # * a {#length} field ({Types::Int16}). The length includes the header,
30
+ # * a {#router_id} field ({Types::Int32}),
31
+ # * an {#area_id} field ({Types::Int32}),
32
+ # * a {#checksum} field ({Types::Int16}),
33
+ # * an {#instance_id} field ({Types::Int8}),
34
+ # * a {#reserved} field ({Types::Int8}),
35
+ # * and a {#body} ({Types::String}).
36
+ #
37
+ # == Create an OSPFv3 header
38
+ # # standalone
39
+ # ospf = PacketGen::Header::OSPFv3.new
40
+ # # in a packet
41
+ # pkt = PacketGen.gen('IPv6', src: source_ip).add('OSPFv3')
42
+ # # make IPv6 header correct for OSPF
43
+ # pkt.ospfize
44
+ # # or make it correct with specific destination address
45
+ # pkt.ospfize(dst: :all_spf_routers)
46
+ # # access to OSPF header
47
+ # pkt.ospfv3 # => PacketGen::Header::OSPFv3
48
+ #
49
+ # == OSPFv3 attributes
50
+ # ospf.version # => 3
51
+ # ospf.type = 'LS_ACK' # or 5
52
+ # ospf.length = 154
53
+ # ospf.router_id = 0xc0a80001
54
+ # ospf.area_id = 1
55
+ # ospf.checksum = 0xabcd
56
+ # ospf.instance_id = 0
57
+ #
58
+ # == OSPFv3 body
59
+ # OSPFv3 {#body} should contain OSPF payload for given {#type}:
60
+ # * {OSPFv3::Hello},
61
+ # * {OSPFv3::DbDescription},
62
+ # * {OSPFv3::LSRequest},
63
+ # * {OSPFv3::LSUpdate},
64
+ # * or {OSPFv3::LSAck}.
65
+ # @author Sylvain Daubert
66
+ class OSPFv3 < Base
67
+
68
+ # IP protocol number for OSPF
69
+ IP_PROTOCOL = OSPFv2::IP_PROTOCOL
70
+
71
+ # OSPF packet types
72
+ TYPES = OSPFv2::TYPES
73
+
74
+ # @!attribute version
75
+ # 8-bit OSPF version
76
+ # @return [Integer]
77
+ define_field :version, Types::Int8, default: 3
78
+ # @!attribute type
79
+ # 8-bit OSPF packet type. Types are defined in {TYPES}.
80
+ # @return [Integer]
81
+ define_field :type, Types::Int8Enum, enum: TYPES
82
+ # @!attribute length
83
+ # 16-bit OSPF packet length
84
+ # @return [Integer]
85
+ define_field :length, Types::Int16
86
+ # @!attribute router_id
87
+ # 32-bit router ID
88
+ # @return [Integer]
89
+ define_field :router_id, Types::Int32
90
+ # @!attribute area_id
91
+ # 32-bit area ID
92
+ # @return [Integer]
93
+ define_field :area_id, Types::Int32
94
+ # @!attribute checksum
95
+ # 16-bit OSPF packet checksum
96
+ # @return [Integer]
97
+ define_field :checksum, Types::Int16
98
+ # @!attribute instance_id
99
+ # 8-bit instance ID.
100
+ # @return [Integer]
101
+ define_field :instance_id, Types::Int8
102
+ # @!attribute reserved
103
+ # 8-bit reserved field.
104
+ # @return [Integer]
105
+ define_field :reserved, Types::Int8, default: 0
106
+ # @!attribute body
107
+ # @return [String,Base]
108
+ define_field :body, Types::String
109
+
110
+ # @api private
111
+ # Helper class method to define an OSPFv3 options field.
112
+ # @param [Base] hdr header on which define a OSPFv3 options field
113
+ # @return [void]
114
+ # @!macro [attach] define_ospfv3_options
115
+ # @!attribute options
116
+ # 24-bit options field. Handle {#v6_opt}, {#e_opt}, {#x_opt},
117
+ # {#n_opt}, {#r_opt} and {#dc_opt}.
118
+ # @return [Integer]
119
+ # @!attribute dc_opt
120
+ # This bit describes the router's handling of demand circuits.
121
+ # @return [Boolean]
122
+ # @!attribute r_opt
123
+ # This bit indicates whether the originator is an active router.
124
+ # @return [Boolean]
125
+ # @!attribute n_opt
126
+ # This bit indicates whether or not the router is attached to an NSSA.
127
+ # @return [Boolean]
128
+ # @!attribute x_opt
129
+ # This bit should be set to 0, and ignored when received.
130
+ # @return [Boolean]
131
+ # @!attribute e_opt
132
+ # This bit describes the way AS-external-LSAs are flooded.
133
+ # @return [Boolean]
134
+ # @!attribute v6_opt
135
+ # If this bit is clear, the router/link should be excluded from IPv6
136
+ # routing calculations.
137
+ # @return [Boolean]
138
+ def self.define_options(hdr)
139
+ hdr.define_field :options, Types::Int24
140
+ hdr.define_bit_fields_on :options, :z, 18, :dc_opt, :r_opt,
141
+ :n_opt, :x_opt, :e_opt, :v6_opt
142
+ end
143
+
144
+ # @api private
145
+ # @note This method is used internally by PacketGen and should not be
146
+ # directly called
147
+ def added_to_packet(packet)
148
+ ospf_idx = packet.headers.size
149
+ packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end"
150
+ end
151
+
152
+ # Compute checksum and set +checksum+ field
153
+ # @return [Integer]
154
+ def calc_checksum
155
+ ipv6 = ip_header(self)
156
+ sum = ipv6.pseudo_header_checksum
157
+ sum += IP_PROTOCOL
158
+ sum += self.sz
159
+ sum += IP.sum16(self)
160
+ self.checksum = IP.reduce_checksum(sum)
161
+ end
162
+
163
+ # Get human-readable type
164
+ # @return [String]
165
+ def human_type
166
+ self[:type].to_human
167
+ end
168
+
169
+ # Compute length and set +length+ field
170
+ # @return [Integer]
171
+ def calc_length
172
+ self[:length].value = Base.calculate_and_set_length(self)
173
+ end
174
+
175
+ # Fixup IPv6 header according to RFC 5340:
176
+ # * set Traffic Class field to 0xc0,
177
+ # * optionally set destination address,
178
+ # * set Hop-limit to 1 if destination is a mcast address.
179
+ # This method may be called as:
180
+ # # first way
181
+ # pkt.ospfv3.ospfize
182
+ # # second way
183
+ # pkt.ospfize
184
+ # @param [String,Symbol,nil] dst destination address. May be a dotted IP
185
+ # address (by example '224.0.0.5') or a Symbol (+:all_spf_routers+ or
186
+ # +:all_d_routers+)
187
+ # @return [void]
188
+ def ospfize(dst: nil)
189
+ ipv6 = ip_header(self)
190
+ ipv6.traffic_class = 0xc0
191
+ dst = case dst
192
+ when :all_spf_routers
193
+ 'ff02::5'
194
+ when :all_d_routers
195
+ 'ff02::6'
196
+ else
197
+ dst
198
+ end
199
+ ipv6.dst = dst unless dst.nil?
200
+ ipv6.hop = 1 if ipv6[:dst].mcast?
201
+ end
202
+ end
203
+
204
+ self.add_class OSPFv3
205
+ IPv6.bind_header OSPFv3, next: OSPFv3::IP_PROTOCOL
206
+ end
207
+ end
208
+
209
+ require_relative 'ospfv3/ipv6_prefix'
210
+ require_relative 'ospfv3/lsa_header'
211
+ require_relative 'ospfv3/lsa'
212
+ require_relative 'ospfv3/hello'
213
+ require_relative 'ospfv3/db_description'
214
+ require_relative 'ospfv3/ls_request'
215
+ require_relative 'ospfv3/ls_update'
216
+ require_relative 'ospfv3/ls_ack'
@@ -0,0 +1,114 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen
9
+ module Header
10
+ class OSPFv3
11
+
12
+ # This class handles {OSPFv3 OSPFv3} DB description packets payload.
13
+ # The DB description payload has the following format:
14
+ # 0 1 2 3
15
+ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
17
+ # | 0 | Options |
18
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
19
+ # | Interface MTU | 0 |0|0|0|0|0|I|M|MS|
20
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
21
+ # | DD sequence number |
22
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
23
+ # | |
24
+ # +- -+
25
+ # | |
26
+ # +- An LSA Header -+
27
+ # | |
28
+ # +- -+
29
+ # | |
30
+ # +- -+
31
+ # | |
32
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
33
+ # | ... |
34
+ #
35
+ # A DB description payload is composed of:
36
+ # * a 8-bit {#reserved} field ({Types::Int8}),
37
+ # * a 24-bit {#options} field ({Types::Int24}),
38
+ # * a 16-bit {#mtu} field ({Types::Int16}),
39
+ # * a 16-bit {#flags} field ({Types::Int16}). Supported flags are:
40
+ # * {i_flag},
41
+ # * {m_flag},
42
+ # * {ms_flag},
43
+ # * a 32-bit {#sequence_number} field ({Types::Int32}),
44
+ # * and an array of {LSAHeader LSAHeaders} ({#lsas}, {ArrayOfLSA}).
45
+ #
46
+ # == Create a DbDescription payload
47
+ # # standalone
48
+ # dbd = PacketGen::Header::OSPFv3::DbDescription.new
49
+ # # in a packet
50
+ # pkt = PacketGen.gen('IPv6', src: source_ip).add('OSPFv3').add('OSPFv3::DbDescription')
51
+ # # access to DbDescription payload
52
+ # pkt.ospfv3_dbdescription # => PacketGen::Header::OSPFv3::DbDescription
53
+ #
54
+ # == DbDescription attributes
55
+ # dbd.reserved = 0
56
+ # # set options. Options may also be set one by one with #v6_opt, #e_opt,
57
+ # # #n_opt, #r_opt and #dc_opt
58
+ # dbd.options = 0x33
59
+ # dbd.mtu = 1500
60
+ # dbd.flags = 0
61
+ # dbd.seqnum = 0x800001
62
+ # # add a LSA Router header
63
+ # dbd.lsas << { type: 'Router', age: 40, link_state_id: '0.0.0.1', advertising_router: '1.1.1.1', sequence_number: 42, checksum: 0x1234, length: 56 }
64
+ # # a header may also be set from an existing lsa
65
+ # dbd.lsas << existing_lsa.to_lsa_header
66
+ # @author Sylvain Daubert
67
+ class DbDescription < Base
68
+
69
+ # @!attribute reserved
70
+ # 8-bit zero field before {#options} one
71
+ # @return [Integer]
72
+ define_field :reserved, Types::Int8, default: 0
73
+
74
+ # @!macro define_options
75
+ OSPFv3.define_options(self)
76
+
77
+ # @!attribute mtu
78
+ # 16-bit interface MTU
79
+ # @return [Integer]
80
+ define_field :mtu, Types::Int16
81
+ # @!attribute flags
82
+ # 16-bit interface flags ({#i_flag}, {#m_flag} and {#ms_flag})
83
+ # @return [Integer]
84
+ define_field :flags, Types::Int16
85
+ # @!attribute i_flag
86
+ # Init bit from {#flags} field
87
+ # @return [Boolean]
88
+ # @!attribute m_flag
89
+ # More bit from {#flags} field
90
+ # @return [Boolean]
91
+ # @!attribute ms_flag
92
+ # Master/Slave bit from {#flags} field
93
+ # @return [Boolean]
94
+ define_bit_fields_on :flags, :zz, 13, :i_flag, :m_flag, :ms_flag
95
+
96
+ # @!attribute sequence_number
97
+ # 32-bit DD sequence number, used to sequence the collection of Database
98
+ # Description Packets.
99
+ # @return [Integer]
100
+ define_field :sequence_number, Types::Int32
101
+ alias seqnum sequence_number
102
+ alias seqnum= sequence_number=
103
+
104
+ # @!attribute lsas
105
+ # Array of LSA headers
106
+ # @return [ArrayOfLSAHeader]
107
+ define_field :lsas, ArrayOfLSA, builder: ->(h,t) { t.new(only_headers: true) }
108
+ end
109
+ end
110
+
111
+ self.add_class OSPFv3::DbDescription
112
+ OSPFv3.bind_header OSPFv3::DbDescription, type: OSPFv3::TYPES['DB_DESCRIPTION']
113
+ end
114
+ end