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.
- checksums.yaml +5 -5
- data/.travis.yml +13 -4
- data/lib/packetgen.rb +3 -1
- data/lib/packetgen/capture.rb +2 -0
- data/lib/packetgen/config.rb +1 -0
- data/lib/packetgen/header.rb +5 -0
- data/lib/packetgen/header/arp.rb +2 -0
- data/lib/packetgen/header/asn1_base.rb +2 -0
- data/lib/packetgen/header/base.rb +16 -0
- data/lib/packetgen/header/bootp.rb +2 -0
- data/lib/packetgen/header/crypto.rb +2 -0
- data/lib/packetgen/header/dhcp.rb +2 -0
- data/lib/packetgen/header/dhcp/option.rb +3 -0
- data/lib/packetgen/header/dhcp/options.rb +2 -0
- data/lib/packetgen/header/dhcpv6.rb +109 -0
- data/lib/packetgen/header/dhcpv6/duid.rb +147 -0
- data/lib/packetgen/header/dhcpv6/option.rb +391 -0
- data/lib/packetgen/header/dhcpv6/options.rb +29 -0
- data/lib/packetgen/header/dhcpv6/relay.rb +48 -0
- data/lib/packetgen/header/dns.rb +10 -2
- data/lib/packetgen/header/dns/name.rb +7 -0
- data/lib/packetgen/header/dns/opt.rb +6 -0
- data/lib/packetgen/header/dns/option.rb +7 -0
- data/lib/packetgen/header/dns/qdsection.rb +7 -1
- data/lib/packetgen/header/dns/question.rb +7 -0
- data/lib/packetgen/header/dns/rr.rb +7 -0
- data/lib/packetgen/header/dns/rrsection.rb +7 -0
- data/lib/packetgen/header/dot11.rb +4 -2
- data/lib/packetgen/header/dot11/control.rb +2 -0
- data/lib/packetgen/header/dot11/data.rb +2 -0
- data/lib/packetgen/header/dot11/element.rb +2 -0
- data/lib/packetgen/header/dot11/management.rb +2 -0
- data/lib/packetgen/header/dot11/sub_mngt.rb +2 -0
- data/lib/packetgen/header/dot1q.rb +2 -0
- data/lib/packetgen/header/dot1x.rb +3 -1
- data/lib/packetgen/header/eap.rb +3 -1
- data/lib/packetgen/header/eap/fast.rb +2 -0
- data/lib/packetgen/header/eap/md5.rb +2 -0
- data/lib/packetgen/header/eap/tls.rb +2 -0
- data/lib/packetgen/header/eap/ttls.rb +2 -0
- data/lib/packetgen/header/esp.rb +7 -0
- data/lib/packetgen/header/eth.rb +2 -0
- data/lib/packetgen/header/gre.rb +4 -9
- data/lib/packetgen/header/http/headers.rb +2 -0
- data/lib/packetgen/header/http/request.rb +3 -1
- data/lib/packetgen/header/http/response.rb +3 -1
- data/lib/packetgen/header/icmp.rb +4 -11
- data/lib/packetgen/header/icmpv6.rb +4 -11
- data/lib/packetgen/header/igmp.rb +4 -11
- data/lib/packetgen/header/igmpv3.rb +4 -11
- data/lib/packetgen/header/igmpv3/group_record.rb +2 -0
- data/lib/packetgen/header/igmpv3/mq.rb +2 -0
- data/lib/packetgen/header/igmpv3/mr.rb +2 -0
- data/lib/packetgen/header/ike.rb +13 -6
- data/lib/packetgen/header/ike/auth.rb +2 -0
- data/lib/packetgen/header/ike/cert.rb +2 -0
- data/lib/packetgen/header/ike/certreq.rb +2 -0
- data/lib/packetgen/header/ike/id.rb +2 -0
- data/lib/packetgen/header/ike/ke.rb +2 -0
- data/lib/packetgen/header/ike/nonce.rb +2 -0
- data/lib/packetgen/header/ike/notify.rb +7 -0
- data/lib/packetgen/header/ike/payload.rb +9 -0
- data/lib/packetgen/header/ike/sa.rb +11 -4
- data/lib/packetgen/header/ike/sk.rb +7 -0
- data/lib/packetgen/header/ike/ts.rb +2 -0
- data/lib/packetgen/header/ike/vendor_id.rb +2 -0
- data/lib/packetgen/header/ip.rb +48 -11
- data/lib/packetgen/header/ip/addr.rb +8 -0
- data/lib/packetgen/header/ip/option.rb +2 -0
- data/lib/packetgen/header/ip/options.rb +2 -0
- data/lib/packetgen/header/ipv6.rb +5 -3
- data/lib/packetgen/header/ipv6/addr.rb +8 -0
- data/lib/packetgen/header/ipv6/extension.rb +2 -0
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +2 -0
- data/lib/packetgen/header/llc.rb +2 -0
- data/lib/packetgen/header/mld.rb +2 -0
- data/lib/packetgen/header/mldv2.rb +4 -2
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +3 -1
- data/lib/packetgen/header/mldv2/mlq.rb +2 -0
- data/lib/packetgen/header/mldv2/mlr.rb +4 -2
- data/lib/packetgen/header/ospfv2.rb +249 -0
- data/lib/packetgen/header/ospfv2/db_description.rb +105 -0
- data/lib/packetgen/header/ospfv2/hello.rb +104 -0
- data/lib/packetgen/header/ospfv2/ls_ack.rb +55 -0
- data/lib/packetgen/header/ospfv2/ls_request.rb +90 -0
- data/lib/packetgen/header/ospfv2/ls_update.rb +72 -0
- data/lib/packetgen/header/ospfv2/lsa.rb +252 -0
- data/lib/packetgen/header/ospfv2/lsa_header.rb +122 -0
- data/lib/packetgen/header/ospfv3.rb +216 -0
- data/lib/packetgen/header/ospfv3/db_description.rb +114 -0
- data/lib/packetgen/header/ospfv3/hello.rb +104 -0
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +103 -0
- data/lib/packetgen/header/ospfv3/ls_ack.rb +51 -0
- data/lib/packetgen/header/ospfv3/ls_request.rb +108 -0
- data/lib/packetgen/header/ospfv3/ls_update.rb +74 -0
- data/lib/packetgen/header/ospfv3/lsa.rb +252 -0
- data/lib/packetgen/header/ospfv3/lsa_header.rb +123 -0
- data/lib/packetgen/header/snmp.rb +2 -0
- data/lib/packetgen/header/tcp.rb +14 -14
- data/lib/packetgen/header/tcp/option.rb +7 -1
- data/lib/packetgen/header/tcp/options.rb +7 -0
- data/lib/packetgen/header/tftp.rb +2 -0
- data/lib/packetgen/header/udp.rb +6 -14
- data/lib/packetgen/inspect.rb +5 -1
- data/lib/packetgen/packet.rb +3 -1
- data/lib/packetgen/pcapng.rb +2 -0
- data/lib/packetgen/pcapng/block.rb +2 -0
- data/lib/packetgen/pcapng/epb.rb +2 -0
- data/lib/packetgen/pcapng/file.rb +2 -0
- data/lib/packetgen/pcapng/idb.rb +2 -0
- data/lib/packetgen/pcapng/shb.rb +2 -0
- data/lib/packetgen/pcapng/spb.rb +2 -0
- data/lib/packetgen/pcapng/unknown_block.rb +2 -0
- data/lib/packetgen/proto.rb +2 -0
- data/lib/packetgen/types/array.rb +3 -0
- data/lib/packetgen/types/cstring.rb +3 -1
- data/lib/packetgen/types/enum.rb +2 -0
- data/lib/packetgen/types/fields.rb +8 -4
- data/lib/packetgen/types/int.rb +3 -1
- data/lib/packetgen/types/int_string.rb +2 -0
- data/lib/packetgen/types/oui.rb +2 -0
- data/lib/packetgen/types/string.rb +3 -0
- data/lib/packetgen/types/tlv.rb +8 -0
- data/lib/packetgen/utils.rb +6 -4
- data/lib/packetgen/utils/arp_spoofer.rb +2 -0
- data/lib/packetgen/version.rb +3 -1
- metadata +25 -3
@@ -0,0 +1,104 @@
|
|
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} HELLO packets payload. The HELLO
|
13
|
+
# 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
|
+
# | Network Mask |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | HelloInterval | Options | Rtr Pri |
|
20
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
|
+
# | RouterDeadInterval |
|
22
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
23
|
+
# | Designated Router |
|
24
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
25
|
+
# | Backup Designated Router |
|
26
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
+
# | Neighbor |
|
28
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
|
+
# | ... |
|
30
|
+
# A HELLO payload consists of:
|
31
|
+
# * a {#network_mask} field ({IP::Addr}),
|
32
|
+
# * a {#hello_interval} field ({Types::Int16}),
|
33
|
+
# * an {#options} field ({Types::Int8}),
|
34
|
+
# * a {#priority} field ({Types::Int8}),
|
35
|
+
# * a {#dead_interval} field ({Types::Int32}),
|
36
|
+
# * a {#designated_router} field ({IP::Addr}),
|
37
|
+
# * a {#backup_designated_router} field ({IP::Addr}),
|
38
|
+
# * a {#neighbors} array containing neighbors as {IP::Addr}.
|
39
|
+
#
|
40
|
+
# == Create a HELLO payload
|
41
|
+
# # standalone
|
42
|
+
# hello = PacketGen::Header::OSPFv2::Hello.new
|
43
|
+
# # in a packet
|
44
|
+
# pkt = PacketGen.gen('IP', src: source_ip).add('OSPFv2').add('OSPFv2::Hello')
|
45
|
+
# # make IP header correct for OSPF
|
46
|
+
# pkt.ospfize
|
47
|
+
# # access to Hello payload
|
48
|
+
# pkt.ospfv2_hello # => PacketGen::Header::OSPFv2::Hello
|
49
|
+
#
|
50
|
+
# == HELLO attributes
|
51
|
+
# hello.network_mask = '255.255.255.0'
|
52
|
+
# hello.hello_interval = 10
|
53
|
+
# hello.options = 0
|
54
|
+
# hello.priority = 1
|
55
|
+
# hello.dead_interval = 300
|
56
|
+
# hello.designated_router = '10.0.0.1'
|
57
|
+
# hello.backup_designated_router = '0.0.0.0'
|
58
|
+
# # set neighbors identifiers
|
59
|
+
# hello.neighbors << '10.0.1.1'
|
60
|
+
# hello.neighbors << '10.0.2.1'
|
61
|
+
# @author Sylvain Daubert
|
62
|
+
class Hello < Base
|
63
|
+
# @!attribute network_mask
|
64
|
+
# The network mask associated with this interface.
|
65
|
+
# @return [String]
|
66
|
+
define_field :network_mask, IP::Addr
|
67
|
+
# @!attribute hello_interval
|
68
|
+
# The number of seconds between this router's Hello packets.
|
69
|
+
# @return [Integer]
|
70
|
+
define_field :hello_interval, Types::Int16
|
71
|
+
|
72
|
+
# @!macro define_options
|
73
|
+
OSPFv2.define_options(self)
|
74
|
+
|
75
|
+
# @!attribute priority
|
76
|
+
# This router's Router Priority. Used in (Backup) Designated
|
77
|
+
# Router election.
|
78
|
+
# @return [Integer]
|
79
|
+
define_field :priority, Types::Int8
|
80
|
+
# @!attribute dead_interval
|
81
|
+
# The number of seconds before declaring a silent router down.
|
82
|
+
# @return [Integer]
|
83
|
+
define_field :dead_interval, Types::Int32
|
84
|
+
# @!attribute designated_router
|
85
|
+
# The identity of the Designated Router for this network, in the
|
86
|
+
# view of the sending router.
|
87
|
+
# @return [String]
|
88
|
+
define_field :designated_router, IP::Addr
|
89
|
+
# @!attribute backup_designated_router
|
90
|
+
# The identity of the Backup Designated Router for this network,
|
91
|
+
# in the view of the sending router.
|
92
|
+
# @return [String]
|
93
|
+
define_field :backup_designated_router, IP::Addr
|
94
|
+
# @!attribute neighbors
|
95
|
+
# Array of neighbors
|
96
|
+
# @return [IP::ArrayOfAddr]
|
97
|
+
define_field :neighbors, IP::ArrayOfAddr
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
self.add_class OSPFv2::Hello
|
102
|
+
OSPFv2.bind_header OSPFv2::Hello, type: OSPFv2::TYPES['HELLO']
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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} LS Acknowledgment packets payload.
|
13
|
+
# The LS Acknowledgment 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
|
+
# | |
|
18
|
+
# +- -+
|
19
|
+
# | |
|
20
|
+
# +- An LSA Header -+
|
21
|
+
# | |
|
22
|
+
# +- -+
|
23
|
+
# | |
|
24
|
+
# +- -+
|
25
|
+
# | |
|
26
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
+
# | ... |
|
28
|
+
# This paylod is implemented as a unique field: {#lsas}, which is an
|
29
|
+
# {ArrayOfLSAHeader} object.
|
30
|
+
#
|
31
|
+
# == Create a LSAck payload
|
32
|
+
# # standalone
|
33
|
+
# lsack = PacketGen::Header::OSPFv2::LSAck.new
|
34
|
+
# # in a packet
|
35
|
+
# pkt = PacketGen.gen('IP', src: source_ip).add('OSPFv2').add('OSPFv2::LSAck')
|
36
|
+
# # access to LSAck payload
|
37
|
+
# lasck = pkt.ospfv2_lsack # => PacketGen::Header::OSPFv2::LSAck
|
38
|
+
#
|
39
|
+
# == Adding LSA headers to a LSAck payload
|
40
|
+
# lsack.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 }
|
41
|
+
# # a header may also be set from an existing lsa
|
42
|
+
# lasck.lsas << existing_lsa.to_lsa_header
|
43
|
+
# @author Sylvain Daubert
|
44
|
+
class LSAck < Base
|
45
|
+
# @!attribute lsas
|
46
|
+
# Array of LSA headers
|
47
|
+
# @return [ArrayOfLSAHeader]
|
48
|
+
define_field :lsas, ArrayOfLSA, builder: ->(h, t) { t.new(only_headers: true) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
self.add_class OSPFv2::LSAck
|
53
|
+
OSPFv2.bind_header OSPFv2::LSAck, type: OSPFv2::TYPES['LS_ACK']
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,90 @@
|
|
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 handle a LS request, which is composed 3 {Types::Int32} fields:
|
13
|
+
# * {#type},
|
14
|
+
# * {#link_state_id},
|
15
|
+
# * and {#advertising_router}.
|
16
|
+
# @author Sylvain Daubert
|
17
|
+
class LSR < Types::Fields
|
18
|
+
# @!attribute type
|
19
|
+
# The type of the LSA to request.
|
20
|
+
# @return [Integer]
|
21
|
+
define_field :type, Types::Int32Enum, enum: LSAHeader::TYPES
|
22
|
+
# @!attribute link_state_id
|
23
|
+
# This field identifies the portion of the internet environment
|
24
|
+
# that is being described by the LSA to request.
|
25
|
+
# @return [String]
|
26
|
+
define_field :link_state_id, IP::Addr
|
27
|
+
# @!attribute advertising_router
|
28
|
+
# The Router ID of the requested LSA.
|
29
|
+
# @return [String]
|
30
|
+
define_field :advertising_router, IP::Addr
|
31
|
+
|
32
|
+
# Get human-readable type
|
33
|
+
# @return [String]
|
34
|
+
def human_type
|
35
|
+
self[:type].to_human
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String]
|
39
|
+
def to_human
|
40
|
+
"LSR<#{human_type},#{link_state_id},#{advertising_router}>"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# This class defines a specialized {Types::Array array} to handle series
|
45
|
+
# of {LSR LSRs}.
|
46
|
+
# @author Sylvain Daubert
|
47
|
+
class ArrayOfLSR < Types::Array
|
48
|
+
set_of LSR
|
49
|
+
end
|
50
|
+
|
51
|
+
# This class handles {OSPFv2 OSPFv2} Link State Request packets
|
52
|
+
# payload. The LSR payload has the following format:
|
53
|
+
# 0 1 2 3
|
54
|
+
# 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
|
55
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
56
|
+
# | LS type |
|
57
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
58
|
+
# | Link State ID |
|
59
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
60
|
+
# | Advertising Router |
|
61
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
62
|
+
# | ... |
|
63
|
+
# This paylod is implemented as a unique field: {#lsrs}, which is an
|
64
|
+
# {ArrayOfLSR} object.
|
65
|
+
#
|
66
|
+
# == Create a LSRequest payload
|
67
|
+
# # standalone
|
68
|
+
# lsr = PacketGen::Header::OSPFv2::LSRequest.new
|
69
|
+
# # in a packet
|
70
|
+
# pkt = PacketGen.gen('IP', src: source_ip).add('OSPFv2').add('OSPFv2::LSRequest')
|
71
|
+
# # make IP header correct for OSPF
|
72
|
+
# pkt.ospfize
|
73
|
+
# # access to LSRequest payload
|
74
|
+
# pkt.ospfv2_lsrequest # => PacketGen::Header::OSPFv2::LSRequest
|
75
|
+
#
|
76
|
+
# == Add LSA requests to a LSRequest
|
77
|
+
# lsr.lsrs << { type: 'Router', link_state_id: '0.0.0.1', advertising_router: '1.1.1.1'}
|
78
|
+
# @author Sylvain Daubert
|
79
|
+
class LSRequest < Base
|
80
|
+
# @!attribute lsrs
|
81
|
+
# Array of {LSR}
|
82
|
+
# @return [ArrayOfLSR]
|
83
|
+
define_field :lsrs, ArrayOfLSR
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
self.add_class OSPFv2::LSRequest
|
88
|
+
OSPFv2.bind_header OSPFv2::LSRequest, type: OSPFv2::TYPES['LS_REQUEST']
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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} Link State Update packets
|
13
|
+
# payload. The LSU 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
|
+
# | # LSAs |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | |
|
20
|
+
# +- +-+
|
21
|
+
# | LSAs |
|
22
|
+
# +- +-+
|
23
|
+
# | ... |
|
24
|
+
# This paylod is implemented with two fields:
|
25
|
+
# * {#lsas_count}, a {Types::Int32} field,
|
26
|
+
# * and {#lsas}, an {ArrayOfLSA} object.
|
27
|
+
#
|
28
|
+
# == Create a LSUpdate payload
|
29
|
+
# # standalone
|
30
|
+
# lsu = PacketGen::Header::OSPFv2::LSUpdate.new
|
31
|
+
# # in a packet
|
32
|
+
# pkt = PacketGen.gen('IP', src: source_ip).add('OSPFv2').add('OSPFv2::LSUpdate')
|
33
|
+
# # make IP header correct for OSPF
|
34
|
+
# pkt.ospfize
|
35
|
+
# # access to LSUpdate payload
|
36
|
+
# lsu = pkt.ospfv2_lsupdate # => PacketGen::Header::OSPFv2::LSUpdate
|
37
|
+
#
|
38
|
+
# == Add LSAs to a LSUpdate payload
|
39
|
+
# Adding LSAs with {ArrayOfLSA#<< ArrayOfLSA#<<} automagically update
|
40
|
+
# {#lsas_count}. To not update it, use {ArrayOfLSA#push ArrayOfLSA#push}.
|
41
|
+
# lsu.lsas << { type: 'Router', age: 40, link_state_id: '0.0.0.1', advertising_router: '1.1.1.1', sequence_number: 42 }
|
42
|
+
# lsu.lsas_count #=> 1
|
43
|
+
# # add a link to Router LSA
|
44
|
+
# lsu.lsas.first.links << { type: 1, metric: 10, id: '1.1.1.1' }
|
45
|
+
# @author Sylvain Daubert
|
46
|
+
class LSUpdate < Base
|
47
|
+
# @!attribute lsas_count
|
48
|
+
# Count of LSAs included in this update
|
49
|
+
# @return [Integer]
|
50
|
+
define_field :lsas_count, Types::Int32
|
51
|
+
# @!attribute lsas
|
52
|
+
# Array of {LSA LSAs}
|
53
|
+
# @return [ArrayOfLSA]
|
54
|
+
define_field :lsas, ArrayOfLSA, builder: ->(h, t) { t.new(counter: h[:lsas_count]) }
|
55
|
+
|
56
|
+
# Calculate checksums of all LSAs
|
57
|
+
# @return [void]
|
58
|
+
def calc_checksum
|
59
|
+
lsas.each { |lsa| lsa.calc_checksum }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calculate length of all LSAs
|
63
|
+
def calc_length
|
64
|
+
lsas.each { |lsa| lsa.calc_length }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
self.add_class OSPFv2::LSUpdate
|
70
|
+
OSPFv2.bind_header OSPFv2::LSUpdate, type: OSPFv2::TYPES['LS_UPDATE']
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,252 @@
|
|
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 unsupported {OSPFv2 OSPFv2} LSA payloads.
|
13
|
+
# A LSA payload is a {LSAHeader} with a {#body} field.
|
14
|
+
# @author Sylvain Daubert
|
15
|
+
class LSA < LSAHeader
|
16
|
+
# @!attribute body
|
17
|
+
# LSA body
|
18
|
+
# @return [String]
|
19
|
+
define_field :body, Types::String,
|
20
|
+
builder: ->(h,t) { t.new(length_from: ->() { h.length - 20 }) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# This class handles TOS metrics for {Link links} in a {LSARouter
|
24
|
+
# LSA router payload}.
|
25
|
+
# @author Sylvain Daubert
|
26
|
+
class TosMetric < Types::Fields
|
27
|
+
# @!attribute tos
|
28
|
+
# 8-bit IP Type of Service that this metric refers to.
|
29
|
+
# @return [Integer]
|
30
|
+
define_field :tos, Types::Int8
|
31
|
+
# @!attribute reserved
|
32
|
+
# 8-bit reserved field.
|
33
|
+
# @return [Integer]
|
34
|
+
define_field :reserved, Types::Int8, default: 0
|
35
|
+
# @!attribute tos_metric
|
36
|
+
# 16-bit TOS-specific metric information..
|
37
|
+
# @return [Integer]
|
38
|
+
define_field :tos_metric, Types::Int16
|
39
|
+
|
40
|
+
# @return [String]
|
41
|
+
def to_human
|
42
|
+
"TOS<type:#{type},metric:#{tos_metric}>"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# This class defines a specialized {Types::Array array} to handle series
|
47
|
+
# of {TosMetric TOS metrics}.
|
48
|
+
# @author Sylvain Daubert
|
49
|
+
class ArrayOfTosMetric < Types::Array
|
50
|
+
set_of TosMetric
|
51
|
+
end
|
52
|
+
|
53
|
+
# This class handles links in a {LSARouter LSA router payload}.
|
54
|
+
# @author Sylvain Daubert
|
55
|
+
class Link < Types::Fields
|
56
|
+
# @!attribute id
|
57
|
+
# @return [IP::Addr]
|
58
|
+
define_field :id, IP::Addr
|
59
|
+
# @!attribute data
|
60
|
+
# @return [IP::Addr]
|
61
|
+
define_field :data, IP::Addr
|
62
|
+
# @!attribute type
|
63
|
+
# @return [Integer]
|
64
|
+
define_field :type, Types::Int8
|
65
|
+
# @!attribute tos_count
|
66
|
+
# @return [Integer]
|
67
|
+
define_field :tos_count, Types::Int8
|
68
|
+
# @!attribute metric
|
69
|
+
# @return [Integer]
|
70
|
+
define_field :metric, Types::Int16
|
71
|
+
# @!attribute tos
|
72
|
+
# Additionnal TOS metrics
|
73
|
+
# @return [ArrayOfTosMetric]
|
74
|
+
define_field :tos, ArrayOfTosMetric, builder: ->(h,t) { t.new(counter: h[:tos_count]) }
|
75
|
+
|
76
|
+
# @return [String]
|
77
|
+
def to_human
|
78
|
+
"Link<type:#{type},metric:#{metric},id:#{id},data:#{data}>"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# This class defines a specialized {Types::Array array} to handle series
|
83
|
+
# of {Link Links}.
|
84
|
+
# @author Sylvain Daubert
|
85
|
+
class ArrayOfLink < Types::Array
|
86
|
+
set_of Link
|
87
|
+
end
|
88
|
+
|
89
|
+
# This class handles LSA Router payloads.
|
90
|
+
#
|
91
|
+
# A LSA router payload is composed of:
|
92
|
+
# * a header (see methods inherited from {LSAHeader}),
|
93
|
+
# * a 16-bit flag word {#u16} ({Types::Int16}),
|
94
|
+
# * a 16-bit {#link_count} field ({Types::Int16}),
|
95
|
+
# * an array of {#links} ({ArrayOfLink}).
|
96
|
+
# @author Sylvain Daubert
|
97
|
+
class LSARouter < LSAHeader
|
98
|
+
# @attribute u16
|
99
|
+
# 16-bit flag word
|
100
|
+
# @return [Integer]
|
101
|
+
define_field :u16, Types::Int16
|
102
|
+
# @attribute link_count
|
103
|
+
# Number of links
|
104
|
+
# @return [Integer]
|
105
|
+
define_field :link_count, Types::Int16
|
106
|
+
# @attribute links
|
107
|
+
# @return [ArrayOfLink]
|
108
|
+
define_field :links, ArrayOfLink, builder: ->(h, t) { t.new(counter: h[:link_count]) }
|
109
|
+
|
110
|
+
# @attribute v_flag
|
111
|
+
# @return [Boolean]
|
112
|
+
# @attribute e_flag
|
113
|
+
# @return [Boolean]
|
114
|
+
# @attribute b_flag
|
115
|
+
# @return [Boolean]
|
116
|
+
define_bit_fields_on :u16, :z, 5, :v_flag, :e_flag, :b_flag, :zz, 8
|
117
|
+
end
|
118
|
+
|
119
|
+
# This class handles LSA Network payloads.
|
120
|
+
#
|
121
|
+
# A LSA network payload is composed of:
|
122
|
+
# * a header (see methods inherited from {LSAHeader}),
|
123
|
+
# * a 32-bit {#netmask} field ({IP::Addr}),
|
124
|
+
# * an array of router addresses ({#routers}, {IP::ArrayOfAddr}).
|
125
|
+
# @author Sylvain Daubert
|
126
|
+
class LSANetwork < LSAHeader
|
127
|
+
# @!attribute netmask
|
128
|
+
# @return [IP::Addr]
|
129
|
+
define_field :netmask, IP::Addr
|
130
|
+
# @!attribute routers
|
131
|
+
# List of routers in network
|
132
|
+
# @return [IP::ArrayOfAddr]
|
133
|
+
define_field :routers, IP::ArrayOfAddr
|
134
|
+
end
|
135
|
+
|
136
|
+
# This class handles external links in {LSAASExternal LSA AS-External payloads}.
|
137
|
+
# @author Sylvain Daubert
|
138
|
+
class External < Types::Fields
|
139
|
+
# @!attribute u8
|
140
|
+
# @return [Integer]
|
141
|
+
define_field :u8, Types::Int8
|
142
|
+
# @!attribute metric
|
143
|
+
# @return [Integer]
|
144
|
+
define_field :metric, Types::Int24
|
145
|
+
# @!attribute forwarding_addr
|
146
|
+
# @return [IP::Addr]
|
147
|
+
define_field :forwarding_addr, IP::Addr
|
148
|
+
# @!attribute ext_route_tag
|
149
|
+
# @return [Integer]
|
150
|
+
define_field :ext_route_tag, Types::Int32
|
151
|
+
|
152
|
+
# @!attribute e_flag
|
153
|
+
# @return [Boolean]
|
154
|
+
# @!attribute tos
|
155
|
+
# @return [Integer]
|
156
|
+
define_bit_fields_on :u8, :e_flag, :tos, 7
|
157
|
+
end
|
158
|
+
|
159
|
+
# This class defines a specialized {Types::Array array} to handle series
|
160
|
+
# of {External Externals}.
|
161
|
+
# @author Sylvain Daubert
|
162
|
+
class ArrayOfExternal < Types::Array
|
163
|
+
set_of External
|
164
|
+
end
|
165
|
+
|
166
|
+
# This class handles LSA AS-External payloads.
|
167
|
+
#
|
168
|
+
# A LSA network payload is composed of:
|
169
|
+
# * a header (see methods inherited from {LSAHeader}),
|
170
|
+
# * a 32-bit {#netmask} field ({IP::Addr}),
|
171
|
+
# * an array of external destinations ({#externals}, {ArrayOfExternal}).
|
172
|
+
# @author Sylvain Daubert
|
173
|
+
class LSAASExternal < LSAHeader
|
174
|
+
# @!attribute netmask
|
175
|
+
# @return [IP::Addr]
|
176
|
+
define_field :netmask, IP::Addr
|
177
|
+
# @!attribute externals
|
178
|
+
# List of external destinations
|
179
|
+
# @return [ArrayOfExternal]
|
180
|
+
define_field :externals, ArrayOfExternal
|
181
|
+
end
|
182
|
+
|
183
|
+
# This class defines a specialized {Types::Array array} to handle series
|
184
|
+
# of {LSA LSAs}. It recognizes known LSA types and infers correct type.
|
185
|
+
# @author Sylvain Daubert
|
186
|
+
class ArrayOfLSA < Types::Array
|
187
|
+
set_of LSA
|
188
|
+
|
189
|
+
# @param [Hash] options
|
190
|
+
# @option options [Types::Int] counter Int object used as a counter for this set
|
191
|
+
# @option options [Boolean] only_headers if +true+, only {LSAHeader LSAHeaders}
|
192
|
+
# will be added to this array.
|
193
|
+
def initialize(options={})
|
194
|
+
super()
|
195
|
+
@only_headers = options[:only_headers] || false
|
196
|
+
end
|
197
|
+
|
198
|
+
# Populate object from a string
|
199
|
+
# @param [String] str
|
200
|
+
# @return [self]
|
201
|
+
def read(str)
|
202
|
+
clear
|
203
|
+
return self if str.nil?
|
204
|
+
return self if @counter and @counter.to_i == 0
|
205
|
+
force_binary str
|
206
|
+
while str.length > 0
|
207
|
+
lsa = LSAHeader.new.read(str)
|
208
|
+
if !@only_headers
|
209
|
+
klass = get_lsa_class_by_human_type(lsa.human_type)
|
210
|
+
lsa = klass.new.read(str[0...lsa.length])
|
211
|
+
end
|
212
|
+
self.push lsa
|
213
|
+
str.slice!(0, lsa.sz)
|
214
|
+
break if @counter and self.size == @counter.to_i
|
215
|
+
end
|
216
|
+
self
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
def record_from_hash(hsh)
|
222
|
+
unless hsh.has_key? :type
|
223
|
+
raise ArgumentError, "hash should have :type key"
|
224
|
+
end
|
225
|
+
|
226
|
+
klass = if @only_headers
|
227
|
+
LSAHeader
|
228
|
+
else
|
229
|
+
case hsh[:type]
|
230
|
+
when String
|
231
|
+
get_lsa_class_by_human_type(hsh[:type])
|
232
|
+
when Integer
|
233
|
+
get_lsa_class_by_human_type(LSAHeader::TYPES.key(hsh[:type]))
|
234
|
+
else
|
235
|
+
LSA
|
236
|
+
end
|
237
|
+
end
|
238
|
+
klass.new(hsh)
|
239
|
+
end
|
240
|
+
|
241
|
+
def get_lsa_class_by_human_type(htype)
|
242
|
+
klassname = "LSA#{htype.to_s.gsub(/-/, '')}"
|
243
|
+
if OSPFv2.const_defined? klassname
|
244
|
+
OSPFv2.const_get klassname
|
245
|
+
else
|
246
|
+
LSA
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|