pio 0.2.7 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.travis.yml +1 -0
- data/CONTRIBUTING.md +12 -0
- data/Gemfile +26 -23
- data/Guardfile +5 -0
- data/README.md +61 -19
- data/Rakefile +54 -56
- data/lib/pio/arp/frame.rb +8 -6
- data/lib/pio/arp/message.rb +9 -23
- data/lib/pio/arp/reply.rb +6 -15
- data/lib/pio/arp/request.rb +7 -16
- data/lib/pio/arp.rb +14 -17
- data/lib/pio/icmp/frame.rb +131 -0
- data/lib/pio/icmp/message.rb +100 -0
- data/lib/pio/icmp/reply.rb +17 -0
- data/lib/pio/icmp/request.rb +17 -0
- data/lib/pio/icmp.rb +27 -0
- data/lib/pio/ipv4_address.rb +22 -39
- data/lib/pio/lldp/chassis_id_tlv.rb +13 -16
- data/lib/pio/lldp/end_of_lldpdu_value.rb +4 -5
- data/lib/pio/lldp/frame.rb +21 -32
- data/lib/pio/lldp/management_address_value.rb +3 -4
- data/lib/pio/lldp/optional_tlv.rb +13 -22
- data/lib/pio/lldp/organizationally_specific_value.rb +3 -4
- data/lib/pio/lldp/port_description_value.rb +3 -4
- data/lib/pio/lldp/port_id_tlv.rb +6 -9
- data/lib/pio/lldp/system_capabilities_value.rb +3 -4
- data/lib/pio/lldp/system_description_value.rb +3 -4
- data/lib/pio/lldp/system_name_value.rb +3 -4
- data/lib/pio/lldp/ttl_tlv.rb +6 -9
- data/lib/pio/lldp.rb +20 -36
- data/lib/pio/mac.rb +30 -53
- data/lib/pio/message_util.rb +19 -0
- data/lib/pio/type/config.reek +4 -0
- data/lib/pio/type/ethernet_header.rb +7 -4
- data/lib/pio/type/ip_address.rb +5 -8
- data/lib/pio/type/ipv4_header.rb +37 -0
- data/lib/pio/type/mac_address.rb +7 -8
- data/lib/pio/util.rb +21 -0
- data/lib/pio/version.rb +2 -2
- data/lib/pio.rb +4 -4
- data/pio.gemspec +15 -17
- data/pio.org +499 -76
- data/pio.org_archive +86 -0
- data/rubocop-todo.yml +9 -0
- data/spec/pio/arp/reply_spec.rb +106 -118
- data/spec/pio/arp/request_spec.rb +90 -101
- data/spec/pio/arp_spec.rb +105 -113
- data/spec/pio/icmp/reply_spec.rb +132 -0
- data/spec/pio/icmp/request_spec.rb +131 -0
- data/spec/pio/icmp_spec.rb +159 -0
- data/spec/pio/ipv4_address_spec.rb +87 -97
- data/spec/pio/lldp_spec.rb +237 -186
- data/spec/pio/mac_spec.rb +82 -93
- data/spec/spec_helper.rb +10 -13
- metadata +20 -2
@@ -0,0 +1,131 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/type/ethernet_header'
|
3
|
+
require 'pio/type/ipv4_header'
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Icmp
|
7
|
+
# Icmp frame parser.
|
8
|
+
class Frame < BinData::Record
|
9
|
+
PADDED_PACKET_LENGTH = 50
|
10
|
+
MINIMUM_PACKET_LENGTH = 36
|
11
|
+
MINIMUM_FRAME_LENGTH = 64
|
12
|
+
|
13
|
+
extend Type::EthernetHeader
|
14
|
+
extend Type::IPv4Header
|
15
|
+
|
16
|
+
endian :big
|
17
|
+
ethernet_header :ether_type => 0x0800
|
18
|
+
ipv4_header :ip_protocol => 1,
|
19
|
+
:ip_header_checksum => lambda { ip_sum },
|
20
|
+
:ip_total_length => lambda { ip_packet_length }
|
21
|
+
uint8 :icmp_type
|
22
|
+
uint8 :icmp_code, :initial_value => 0
|
23
|
+
uint16 :icmp_checksum, :value => lambda { icmp_sum }
|
24
|
+
uint16 :icmp_identifier, :initial_value => 0x0100
|
25
|
+
uint16 :icmp_sequence_number, :initial_value => 0x0001
|
26
|
+
string :echo_data,
|
27
|
+
:initial_value => 'DEADBEEF',
|
28
|
+
:read_length => lambda { echo_data_length }
|
29
|
+
|
30
|
+
def message_type
|
31
|
+
icmp_type
|
32
|
+
end
|
33
|
+
|
34
|
+
def echo_data_length
|
35
|
+
ip_total_length - (ip_header_length * 4 + 8)
|
36
|
+
end
|
37
|
+
|
38
|
+
def ip_packet_length
|
39
|
+
icmpsize = (ip_header_length * 4) + (8 + echo_data.bytesize)
|
40
|
+
if icmpsize < MINIMUM_PACKET_LENGTH
|
41
|
+
PADDED_PACKET_LENGTH
|
42
|
+
else
|
43
|
+
icmpsize
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def icmp_sum
|
48
|
+
~((icmp_csum & 0xffff) + (icmp_csum >> 16)) & 0xffff
|
49
|
+
end
|
50
|
+
|
51
|
+
def icmp_csum
|
52
|
+
icmp_2bytewise_slices.reduce(0) do |acc, each|
|
53
|
+
acc + each
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def ip_sum
|
58
|
+
~((ip_csum & 0xffff) + (ip_csum >> 16)) & 0xffff
|
59
|
+
end
|
60
|
+
|
61
|
+
def ip_csum
|
62
|
+
ipv4_header_2bytewise_slices.reduce(0) do |acc, each|
|
63
|
+
acc + each
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def icmp_2bytewise_slices
|
68
|
+
[
|
69
|
+
icmp_type * 0x100 + icmp_code,
|
70
|
+
icmp_identifier,
|
71
|
+
icmp_sequence_number,
|
72
|
+
*echo_data.unpack('n*')
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
def ipv4_header_2bytewise_slices
|
77
|
+
[
|
78
|
+
ipversion_ipheaderlength_iptypeofservice, ip_total_length,
|
79
|
+
ip_identifier, ipflag_ipfragment,
|
80
|
+
ipttl_ipproto,
|
81
|
+
ip_source_address_upper,
|
82
|
+
ip_source_address_lower,
|
83
|
+
ip_destination_address_upper,
|
84
|
+
ip_destination_address_lower
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
def ip_source_address_upper
|
89
|
+
ip_source_address.get.to_i >> 16
|
90
|
+
end
|
91
|
+
|
92
|
+
def ip_source_address_lower
|
93
|
+
ip_source_address.get.to_i & 0xffff
|
94
|
+
end
|
95
|
+
|
96
|
+
def ip_destination_address_upper
|
97
|
+
ip_destination_address.get.to_i >> 16
|
98
|
+
end
|
99
|
+
|
100
|
+
def ip_destination_address_lower
|
101
|
+
ip_destination_address.get.to_i & 0xffff
|
102
|
+
end
|
103
|
+
|
104
|
+
def ipversion_ipheaderlength_iptypeofservice
|
105
|
+
ip_version << 12 | ip_header_length << 8 | ip_type_of_service
|
106
|
+
end
|
107
|
+
|
108
|
+
def ipflag_ipfragment
|
109
|
+
ip_flag << 13 | ip_fragment
|
110
|
+
end
|
111
|
+
|
112
|
+
def ipttl_ipproto
|
113
|
+
ip_ttl << 8 | ip_protocol
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_binary
|
117
|
+
if num_bytes < MINIMUM_FRAME_LENGTH
|
118
|
+
to_binary_s + "\000" * (MINIMUM_FRAME_LENGTH - num_bytes)
|
119
|
+
else
|
120
|
+
to_binary_s
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
### Local variables:
|
128
|
+
### mode: Ruby
|
129
|
+
### coding: utf-8-unix
|
130
|
+
### indent-tabs-mode: nil
|
131
|
+
### End:
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/icmp/frame'
|
3
|
+
require 'pio/message_util'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
module Pio
|
7
|
+
class Icmp
|
8
|
+
# Base class of Request, Reply, TTL Exceeded and destination unreachable.
|
9
|
+
class Message
|
10
|
+
extend Forwardable
|
11
|
+
include MessageUtil
|
12
|
+
|
13
|
+
def self.create_from(frame)
|
14
|
+
message = allocate
|
15
|
+
message.instance_variable_set :@frame, frame
|
16
|
+
message
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(options)
|
20
|
+
@options = options
|
21
|
+
@frame = Icmp::Frame.new(option_hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
def_delegators :@frame, :destination_mac
|
25
|
+
def_delegators :@frame, :source_mac
|
26
|
+
def_delegators :@frame, :ether_type
|
27
|
+
def_delegators :@frame, :ip_version
|
28
|
+
def_delegators :@frame, :ip_header_length
|
29
|
+
def_delegators :@frame, :ip_type_of_service
|
30
|
+
def_delegators :@frame, :ip_total_length
|
31
|
+
def_delegators :@frame, :ip_identifier
|
32
|
+
def_delegators :@frame, :ip_flag
|
33
|
+
def_delegators :@frame, :ip_fragment
|
34
|
+
def_delegators :@frame, :ip_ttl
|
35
|
+
def_delegators :@frame, :ip_protocol
|
36
|
+
def_delegators :@frame, :ip_header_checksum
|
37
|
+
def_delegators :@frame, :ip_source_address
|
38
|
+
def_delegators :@frame, :ip_destination_address
|
39
|
+
def_delegators :@frame, :icmp_type
|
40
|
+
def_delegators :@frame, :icmp_code
|
41
|
+
def_delegators :@frame, :icmp_checksum
|
42
|
+
def_delegators :@frame, :icmp_identifier
|
43
|
+
def_delegators :@frame, :icmp_sequence_number
|
44
|
+
def_delegators :@frame, :echo_data
|
45
|
+
def_delegators :@frame, :to_binary
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# rubocop:disable MethodLength
|
50
|
+
def default_options
|
51
|
+
{
|
52
|
+
:ip_type_of_service => @options[:ip_type_of_service],
|
53
|
+
:ip_identifier => @options[:ip_identifier],
|
54
|
+
:ip_flag => @options[:ip_flag],
|
55
|
+
:ip_fragment => @options[:ip_fragment],
|
56
|
+
:ip_ttl => @options[:ip_ttl],
|
57
|
+
:icmp_type => self.class::TYPE,
|
58
|
+
:icmp_code => @options[:icmp_code],
|
59
|
+
:icmp_identifier => @options[:icmp_identifier],
|
60
|
+
:icmp_sequence_number => @options[:icmp_sequence_number],
|
61
|
+
:echo_data => @options[:echo_data]
|
62
|
+
}
|
63
|
+
end
|
64
|
+
# rubocop:enable MethodLength
|
65
|
+
|
66
|
+
def user_options
|
67
|
+
@options.merge(
|
68
|
+
:source_mac => @options[:source_mac],
|
69
|
+
:destination_mac => @options[:destination_mac],
|
70
|
+
:ip_source_address => @options[:ip_source_address],
|
71
|
+
:ip_destination_address => @options[:ip_destination_address]
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def mandatory_options
|
76
|
+
[
|
77
|
+
:source_mac,
|
78
|
+
:destination_mac,
|
79
|
+
:ip_source_address,
|
80
|
+
:ip_destination_address
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def option_to_klass
|
85
|
+
{
|
86
|
+
:source_mac => Mac,
|
87
|
+
:destination_mac => Mac,
|
88
|
+
:ip_source_address => IPv4Address,
|
89
|
+
:ip_destination_address => IPv4Address
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
### Local variables:
|
97
|
+
### mode: Ruby
|
98
|
+
### coding: utf-8-unix
|
99
|
+
### indent-tabs-mode: nil
|
100
|
+
### End:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/icmp/message'
|
3
|
+
|
4
|
+
module Pio
|
5
|
+
class Icmp
|
6
|
+
# ICMP Reply packet generator
|
7
|
+
class Reply < Message
|
8
|
+
TYPE = 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
### Local variables:
|
14
|
+
### mode: Ruby
|
15
|
+
### coding: utf-8-unix
|
16
|
+
### indent-tabs-mode: nil
|
17
|
+
### End:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/icmp/message'
|
3
|
+
|
4
|
+
module Pio
|
5
|
+
class Icmp
|
6
|
+
# ICMP Request packet generator
|
7
|
+
class Request < Message
|
8
|
+
TYPE = 8
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
### Local variables:
|
14
|
+
### mode: Ruby
|
15
|
+
### coding: utf-8-unix
|
16
|
+
### indent-tabs-mode: nil
|
17
|
+
### End:
|
data/lib/pio/icmp.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bindata'
|
4
|
+
|
5
|
+
require 'pio/icmp/frame'
|
6
|
+
require 'pio/icmp/request'
|
7
|
+
require 'pio/icmp/reply'
|
8
|
+
require 'pio/util'
|
9
|
+
|
10
|
+
module Pio
|
11
|
+
# Icmp parser and generator.
|
12
|
+
class Icmp
|
13
|
+
MESSAGE_TYPE = {
|
14
|
+
Request::TYPE => Request,
|
15
|
+
Reply::TYPE => Reply
|
16
|
+
}
|
17
|
+
class << self
|
18
|
+
include Util
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
### Local variables:
|
24
|
+
### mode: Ruby
|
25
|
+
### coding: utf-8-unix
|
26
|
+
### indent-tabs-mode: nil
|
27
|
+
### End:
|
data/lib/pio/ipv4_address.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'forwardable'
|
3
|
+
require 'ipaddr'
|
4
4
|
|
5
5
|
module Pio
|
6
6
|
#
|
@@ -9,13 +9,11 @@ module Pio
|
|
9
9
|
class IPv4Address
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
|
13
12
|
#
|
14
13
|
# @return [IPAddr] value object instance of proxied IPAddr.
|
15
14
|
#
|
16
15
|
attr_reader :value
|
17
16
|
|
18
|
-
|
19
17
|
#
|
20
18
|
# Creates a {IPv4Address} instance object as a proxy to IPAddr class.
|
21
19
|
#
|
@@ -29,62 +27,56 @@ module Pio
|
|
29
27
|
# @return [IPv4Address] self
|
30
28
|
# a proxy to IPAddr.
|
31
29
|
#
|
32
|
-
def initialize
|
30
|
+
def initialize(addr)
|
33
31
|
case addr
|
34
32
|
when Integer
|
35
|
-
@value = IPAddr.new(
|
33
|
+
@value = IPAddr.new(addr, Socket::AF_INET)
|
36
34
|
when String
|
37
|
-
@value = IPAddr.new(
|
35
|
+
@value = IPAddr.new(addr)
|
38
36
|
when IPv4Address
|
39
37
|
@value = addr.value
|
40
38
|
else
|
41
|
-
|
39
|
+
fail TypeError, "Invalid IPv4 address: #{ addr.inspect }"
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
|
-
|
46
43
|
#
|
47
44
|
# @return [String] the IPv4 address in its text representation.
|
48
45
|
#
|
49
46
|
def_delegator :value, :to_s
|
50
47
|
|
51
|
-
|
52
48
|
#
|
53
49
|
# @return [Number] the IPv4 address in its numeric representation.
|
54
50
|
#
|
55
51
|
def_delegator :value, :to_i
|
56
52
|
|
57
|
-
|
58
53
|
#
|
59
54
|
# @return [Range] Creates a Range object for the network address.
|
60
55
|
#
|
61
56
|
def_delegator :value, :to_range
|
62
57
|
|
63
|
-
|
64
58
|
#
|
65
59
|
# @return [Number] prefix length of IPv4 address.
|
66
60
|
#
|
67
61
|
def prefixlen
|
68
62
|
netmask = to_range.first.to_i ^ to_range.last.to_i
|
69
63
|
if netmask > 0
|
70
|
-
32 - (
|
64
|
+
32 - sprintf('%b', netmask).length
|
71
65
|
else
|
72
66
|
32
|
73
67
|
end
|
74
68
|
end
|
75
69
|
|
76
|
-
|
77
70
|
#
|
78
71
|
# @return [Array]
|
79
72
|
# an array of decimal numbers converted from IPv4 address.
|
80
73
|
#
|
81
74
|
def to_a
|
82
|
-
to_s.split(
|
75
|
+
to_s.split('.').map do | each |
|
83
76
|
each.to_i
|
84
77
|
end
|
85
78
|
end
|
86
79
|
|
87
|
-
|
88
80
|
#
|
89
81
|
# @return [Array]
|
90
82
|
# an array of decimal numbers converted from IPv4 address.
|
@@ -93,85 +85,76 @@ module Pio
|
|
93
85
|
to_a
|
94
86
|
end
|
95
87
|
|
96
|
-
|
97
88
|
#
|
98
89
|
# @return [IPv4Address]
|
99
90
|
# Returns the IPv4 address masked with masklen.
|
100
91
|
#
|
101
|
-
def mask!
|
102
|
-
@value = @value.mask(
|
92
|
+
def mask!(masklen)
|
93
|
+
@value = @value.mask(masklen)
|
103
94
|
self
|
104
95
|
end
|
105
|
-
|
106
|
-
|
96
|
+
alias_method :prefix!, :mask!
|
107
97
|
|
108
98
|
#
|
109
99
|
# @return [IPv4Address]
|
110
100
|
# Returns the IPv4 address masked with masklen.
|
111
101
|
#
|
112
|
-
def mask
|
113
|
-
|
102
|
+
def mask(masklen)
|
103
|
+
clone.mask!(masklen)
|
114
104
|
end
|
115
|
-
|
116
|
-
|
105
|
+
alias_method :prefix, :mask
|
117
106
|
|
118
107
|
#
|
119
108
|
# @return [bool]
|
120
109
|
# Returns true if the address belongs to class A.
|
121
110
|
#
|
122
111
|
def class_a?
|
123
|
-
mask(
|
112
|
+
mask(1).to_s == '0.0.0.0'
|
124
113
|
end
|
125
114
|
|
126
|
-
|
127
115
|
#
|
128
116
|
# @return [bool]
|
129
117
|
# Returns true if the address belongs to class B.
|
130
118
|
#
|
131
119
|
def class_b?
|
132
|
-
mask(
|
120
|
+
mask(2).to_s == '128.0.0.0'
|
133
121
|
end
|
134
122
|
|
135
|
-
|
136
123
|
#
|
137
124
|
# @return [bool]
|
138
125
|
# Returns true if the address belongs to class C.
|
139
126
|
#
|
140
127
|
def class_c?
|
141
|
-
mask(
|
128
|
+
mask(3).to_s == '192.0.0.0'
|
142
129
|
end
|
143
130
|
|
144
|
-
|
145
131
|
#
|
146
132
|
# @return [bool]
|
147
133
|
# Returns true if the address belongs to class D.
|
148
134
|
#
|
149
135
|
def class_d?
|
150
|
-
mask(
|
136
|
+
mask(4).to_s == '224.0.0.0'
|
151
137
|
end
|
152
|
-
|
153
|
-
|
138
|
+
alias_method :multicast?, :class_d?
|
154
139
|
|
155
140
|
#
|
156
141
|
# @return [bool]
|
157
142
|
# Returns true if the address belongs to class E.
|
158
143
|
#
|
159
144
|
def class_e?
|
160
|
-
mask(
|
145
|
+
mask(4).to_s == '240.0.0.0'
|
161
146
|
end
|
162
147
|
|
163
|
-
|
164
148
|
#
|
165
149
|
# @return [bool]
|
166
150
|
# Returns true if the address is unicast address.
|
167
151
|
#
|
168
152
|
def unicast?
|
169
|
-
class_a?
|
153
|
+
class_a? || class_b? || class_c?
|
170
154
|
end
|
171
155
|
end
|
172
156
|
end
|
173
157
|
|
174
|
-
|
175
158
|
### Local variables:
|
176
159
|
### mode: Ruby
|
177
160
|
### coding: utf-8-unix
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bindata'
|
4
4
|
|
5
5
|
module Pio
|
6
6
|
class Lldp
|
@@ -9,10 +9,11 @@ module Pio
|
|
9
9
|
endian :big
|
10
10
|
|
11
11
|
bit7 :tlv_type, :value => 1
|
12
|
-
bit9
|
12
|
+
bit9(:tlv_info_length,
|
13
|
+
:value => lambda { subtype.num_bytes + chassis_id.length })
|
13
14
|
uint8 :subtype, :initial_value => 7
|
14
|
-
string
|
15
|
-
|
15
|
+
string(:chassis_id,
|
16
|
+
:read_length => lambda { tlv_info_length - subtype.num_bytes })
|
16
17
|
|
17
18
|
def get
|
18
19
|
tmp_chassis_id = chassis_id
|
@@ -27,29 +28,25 @@ module Pio
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
BinData::Uint64be.new( value ).to_binary_s
|
31
|
+
def set(value)
|
32
|
+
self.chassis_id = if subtype == 7
|
33
|
+
BinData::Uint64be.new(value).to_binary_s
|
34
34
|
else
|
35
35
|
value
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
##########################################################################
|
41
39
|
private
|
42
|
-
##########################################################################
|
43
|
-
|
44
40
|
|
45
41
|
def mac_address
|
46
|
-
chassis_id.unpack(
|
42
|
+
chassis_id.unpack('C6').map do |each|
|
43
|
+
sprintf '%02x', each
|
44
|
+
end.join('').hex
|
47
45
|
end
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
52
|
-
|
53
50
|
### Local variables:
|
54
51
|
### mode: Ruby
|
55
52
|
### coding: utf-8-unix
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bindata'
|
4
4
|
|
5
5
|
module Pio
|
6
6
|
class Lldp
|
@@ -8,12 +8,11 @@ module Pio
|
|
8
8
|
class EndOfLldpduValue < BinData::Record
|
9
9
|
endian :big
|
10
10
|
|
11
|
-
stringz :tlv_info_string, :length => 0, :value =>
|
11
|
+
stringz :tlv_info_string, :length => 0, :value => ''
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
16
|
### Local variables:
|
18
17
|
### mode: Ruby
|
19
18
|
### coding: utf-8-unix
|
data/lib/pio/lldp/frame.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
4
|
-
require "pio/lldp/chassis_id_tlv"
|
5
|
-
require "pio/lldp/optional_tlv"
|
6
|
-
require "pio/lldp/port_id_tlv"
|
7
|
-
require "pio/lldp/ttl_tlv"
|
8
|
-
require "pio/type/ethernet_header"
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bindata'
|
9
4
|
|
5
|
+
require 'pio/lldp/chassis_id_tlv'
|
6
|
+
require 'pio/lldp/optional_tlv'
|
7
|
+
require 'pio/lldp/port_id_tlv'
|
8
|
+
require 'pio/lldp/ttl_tlv'
|
9
|
+
require 'pio/type/ethernet_header'
|
10
10
|
|
11
11
|
module Pio
|
12
12
|
class Lldp
|
@@ -20,66 +20,55 @@ module Pio
|
|
20
20
|
chassis_id_tlv :chassis_id
|
21
21
|
port_id_tlv :port_id
|
22
22
|
ttl_tlv :ttl, :initial_value => 120
|
23
|
-
array
|
24
|
-
|
23
|
+
array(:optional_tlv,
|
24
|
+
:type => :optional_tlv,
|
25
|
+
:read_until => lambda { element.end_of_lldpdu? })
|
25
26
|
|
26
27
|
def dpid
|
27
28
|
chassis_id.to_i
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
31
|
def port_description
|
32
|
-
get_tlv_field 4,
|
32
|
+
get_tlv_field 4, 'port_description'
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
35
|
def system_name
|
37
|
-
get_tlv_field 5,
|
36
|
+
get_tlv_field 5, 'system_name'
|
38
37
|
end
|
39
38
|
|
40
|
-
|
41
39
|
def system_description
|
42
|
-
get_tlv_field 6,
|
40
|
+
get_tlv_field 6, 'system_description'
|
43
41
|
end
|
44
42
|
|
45
|
-
|
46
43
|
def system_capabilities
|
47
44
|
get_tlv 7
|
48
45
|
end
|
49
46
|
|
50
|
-
|
51
47
|
def management_address
|
52
|
-
get_tlv_field 8,
|
48
|
+
get_tlv_field 8, 'management_address'
|
53
49
|
end
|
54
50
|
|
55
|
-
|
56
51
|
def organizationally_specific
|
57
52
|
get_tlv 127
|
58
53
|
end
|
59
54
|
|
60
|
-
|
61
|
-
##########################################################################
|
62
55
|
private
|
63
|
-
##########################################################################
|
64
56
|
|
65
|
-
|
66
|
-
def get_tlv tlv_type
|
57
|
+
def get_tlv(tlv_type)
|
67
58
|
tlv = optional_tlv.find do | each |
|
68
|
-
each[
|
59
|
+
each['tlv_type'] == tlv_type
|
69
60
|
end
|
70
|
-
tlv[
|
61
|
+
tlv['tlv_value'] if tlv
|
71
62
|
end
|
72
63
|
|
73
|
-
|
74
|
-
|
75
|
-
tlv
|
76
|
-
tlv[ name ] if tlv
|
64
|
+
def get_tlv_field(tlv_type, name)
|
65
|
+
tlv = get_tlv(tlv_type)
|
66
|
+
tlv[name] if tlv
|
77
67
|
end
|
78
68
|
end
|
79
69
|
end
|
80
70
|
end
|
81
71
|
|
82
|
-
|
83
72
|
### Local variables:
|
84
73
|
### mode: Ruby
|
85
74
|
### coding: utf-8-unix
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bindata'
|
4
4
|
|
5
5
|
module Pio
|
6
6
|
class Lldp
|
@@ -19,7 +19,6 @@ module Pio
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
22
|
### Local variables:
|
24
23
|
### mode: Ruby
|
25
24
|
### coding: utf-8-unix
|