pio 0.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.
- data/.gitignore +19 -0
- data/Gemfile +32 -0
- data/Guardfile +16 -0
- data/LICENSE +674 -0
- data/README.md +4 -0
- data/Rakefile +89 -0
- data/lib/pio/lldp.rb +45 -0
- data/lib/pio/lldp/chassis-id-tlv.rb +57 -0
- data/lib/pio/lldp/end-of-lldpdu-value.rb +21 -0
- data/lib/pio/lldp/frame.rb +38 -0
- data/lib/pio/lldp/mac-address.rb +28 -0
- data/lib/pio/lldp/management-address-value.rb +21 -0
- data/lib/pio/lldp/optional-tlv.rb +73 -0
- data/lib/pio/lldp/port-description-value.rb +21 -0
- data/lib/pio/lldp/port-id-tlv.rb +44 -0
- data/lib/pio/lldp/system-capabilities-value.rb +22 -0
- data/lib/pio/lldp/system-description-value.rb +21 -0
- data/lib/pio/lldp/system-name-value.rb +21 -0
- data/lib/pio/lldp/ttl-tlv.rb +33 -0
- data/lib/pio/version.rb +30 -0
- data/pio.gemspec +31 -0
- data/spec/pio/lldp/chassis-id-tlv_spec.rb +27 -0
- data/spec/pio/lldp/end-of-lldpdu-value_spec.rb +20 -0
- data/spec/pio/lldp/frame_spec.rb +82 -0
- data/spec/pio/lldp/mac-address_spec.rb +20 -0
- data/spec/pio/lldp/optional-tlv_spec.rb +81 -0
- data/spec/pio/lldp/port-id-tlv_spec.rb +27 -0
- data/spec/pio/lldp/ttl-tlv_spec.rb +26 -0
- data/spec/pio/lldp_spec.rb +63 -0
- data/spec/spec_helper.rb +18 -0
- metadata +96 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2013 NEC Corporation
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License, version 3, as
|
6
|
+
# published by the Free Software Foundation.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License along
|
14
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
15
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
16
|
+
#
|
17
|
+
|
18
|
+
|
19
|
+
require "bundler/gem_tasks"
|
20
|
+
require "flay"
|
21
|
+
require "rake/tasklib"
|
22
|
+
require "flay_task"
|
23
|
+
require "flog"
|
24
|
+
require "reek/rake/task"
|
25
|
+
require "rspec/core"
|
26
|
+
require "rspec/core/rake_task"
|
27
|
+
require "yard"
|
28
|
+
|
29
|
+
|
30
|
+
$ruby_source = FileList[ "lib/**/*.rb" ]
|
31
|
+
|
32
|
+
|
33
|
+
task :quality => [ :reek, :flog, :flay ]
|
34
|
+
|
35
|
+
|
36
|
+
RSpec::Core::RakeTask.new do | task |
|
37
|
+
task.rspec_opts = "--format documentation --color"
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
Reek::Rake::Task.new do | t |
|
42
|
+
t.fail_on_error = true
|
43
|
+
t.verbose = false
|
44
|
+
t.ruby_opts = [ "-rubygems" ]
|
45
|
+
t.reek_opts = "--quiet"
|
46
|
+
t.source_files = $ruby_source
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
desc "Analyze for code complexity"
|
51
|
+
task :flog do
|
52
|
+
flog = Flog.new( :continue => true )
|
53
|
+
flog.flog( *$ruby_source )
|
54
|
+
threshold = 10
|
55
|
+
|
56
|
+
bad_methods = flog.totals.select do | name, score |
|
57
|
+
( not ( /##{flog.no_method}$/=~ name ) ) and score > threshold
|
58
|
+
end
|
59
|
+
bad_methods.sort do | a, b |
|
60
|
+
a[ 1 ] <=> b[ 1 ]
|
61
|
+
end.reverse.each do | name, score |
|
62
|
+
puts "%8.1f: %s" % [ score, name ]
|
63
|
+
end
|
64
|
+
unless bad_methods.empty?
|
65
|
+
raise "#{ bad_methods.size } methods have a flog complexity > #{ threshold }"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
FlayTask.new do | t |
|
71
|
+
t.dirs = $ruby_source.collect do | each |
|
72
|
+
each[ /[^\/]+/ ]
|
73
|
+
end.uniq
|
74
|
+
t.threshold = 0
|
75
|
+
t.verbose = $trace
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
YARD::Rake::YardocTask.new do | t |
|
80
|
+
t.options = [ "--no-private" ]
|
81
|
+
t.options << "--debug" << "--verbose" if $trace
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
### Local variables:
|
86
|
+
### mode: Ruby
|
87
|
+
### coding: utf-8-unix
|
88
|
+
### indent-tabs-mode: nil
|
89
|
+
### End:
|
data/lib/pio/lldp.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
require "bindata"
|
4
|
+
require "forwardable"
|
5
|
+
require "pio/lldp/frame"
|
6
|
+
|
7
|
+
|
8
|
+
module Pio
|
9
|
+
# LLDP frame parser and generator.
|
10
|
+
class Lldp
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
|
14
|
+
def self.read raw_data
|
15
|
+
frame = Frame.read( raw_data )
|
16
|
+
new frame.dpid, frame.port_id
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def initialize dpid, port_number, destination_mac = "01:80:c2:00:00:0e"
|
21
|
+
@frame = Frame.new
|
22
|
+
@frame.destination_mac = destination_mac
|
23
|
+
@frame.source_mac = "11:22:33:44:55:66" # FIXME
|
24
|
+
@frame.chassis_id = dpid
|
25
|
+
@frame.port_id = port_number
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def_delegator :@frame, :dpid
|
30
|
+
def_delegator :@frame, :optional_tlv
|
31
|
+
def_delegator :@frame, :port_id, :port_number
|
32
|
+
|
33
|
+
|
34
|
+
def to_binary
|
35
|
+
@frame.to_binary_s + "\000" * ( 64 - @frame.num_bytes )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
### Local variables:
|
42
|
+
### mode: Ruby
|
43
|
+
### coding: utf-8-unix
|
44
|
+
### indent-tabs-mode: nil
|
45
|
+
### End:
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Lldp
|
7
|
+
# Chassis ID TLV
|
8
|
+
class ChassisIdTlv < BinData::Primitive
|
9
|
+
endian :big
|
10
|
+
|
11
|
+
bit7 :tlv_type, :value => 1
|
12
|
+
bit9 :tlv_info_length, :value => lambda { subtype.num_bytes + chassis_id.length }
|
13
|
+
uint8 :subtype, :initial_value => 7
|
14
|
+
string :chassis_id, :read_length => lambda { tlv_info_length - subtype.num_bytes }
|
15
|
+
|
16
|
+
|
17
|
+
def get
|
18
|
+
tmp_chassis_id = chassis_id
|
19
|
+
|
20
|
+
case subtype
|
21
|
+
when 4
|
22
|
+
mac_address
|
23
|
+
when 7
|
24
|
+
BinData::Uint64be.read tmp_chassis_id
|
25
|
+
else
|
26
|
+
tmp_chassis_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def set value
|
32
|
+
self.chassis_id = if value.kind_of?( Fixnum ) and subtype == 7
|
33
|
+
BinData::Uint64be.new( value ).to_binary_s
|
34
|
+
else
|
35
|
+
value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
##########################################################################
|
41
|
+
private
|
42
|
+
##########################################################################
|
43
|
+
|
44
|
+
|
45
|
+
def mac_address
|
46
|
+
chassis_id.unpack( "C6" ).collect { | each | "%02x" % each }.join( "" ).hex
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
### Local variables:
|
54
|
+
### mode: Ruby
|
55
|
+
### coding: utf-8-unix
|
56
|
+
### indent-tabs-mode: nil
|
57
|
+
### End:
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Lldp
|
7
|
+
# End Of LLDPDU
|
8
|
+
class EndOfLldpduValue < BinData::Record
|
9
|
+
endian :big
|
10
|
+
|
11
|
+
stringz :tlv_info_string, :length => 0, :value => ""
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
### Local variables:
|
18
|
+
### mode: Ruby
|
19
|
+
### coding: utf-8-unix
|
20
|
+
### indent-tabs-mode: nil
|
21
|
+
### End:
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
require "pio/lldp/chassis-id-tlv"
|
5
|
+
require "pio/lldp/mac-address"
|
6
|
+
require "pio/lldp/optional-tlv"
|
7
|
+
require "pio/lldp/port-id-tlv"
|
8
|
+
require "pio/lldp/ttl-tlv"
|
9
|
+
|
10
|
+
|
11
|
+
module Pio
|
12
|
+
class Lldp
|
13
|
+
# LLDP frame
|
14
|
+
class Frame < BinData::Record
|
15
|
+
endian :big
|
16
|
+
|
17
|
+
mac_address :destination_mac
|
18
|
+
mac_address :source_mac
|
19
|
+
uint16 :ethertype, :value => 0x88cc
|
20
|
+
chassis_id_tlv :chassis_id
|
21
|
+
port_id_tlv :port_id
|
22
|
+
ttl_tlv :ttl, :initial_value => 120
|
23
|
+
array :optional_tlv, :type => :optional_tlv, :read_until => lambda { element.end_of_lldpdu? }
|
24
|
+
|
25
|
+
|
26
|
+
def dpid
|
27
|
+
chassis_id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
### Local variables:
|
35
|
+
### mode: Ruby
|
36
|
+
### coding: utf-8-unix
|
37
|
+
### indent-tabs-mode: nil
|
38
|
+
### End:
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "bindata"
|
2
|
+
|
3
|
+
|
4
|
+
module Pio
|
5
|
+
class Lldp
|
6
|
+
# MAC address
|
7
|
+
class MacAddress < BinData::Primitive
|
8
|
+
array :octets, :type => :uint8, :initial_length => 6
|
9
|
+
|
10
|
+
|
11
|
+
def set value
|
12
|
+
self.octets = value.split( /:/ ).collect { | each | each.hex }
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def get
|
17
|
+
octets.inject( "" ) { | str, each | str + ( "%02x" % each ) }.hex
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
### Local variables:
|
25
|
+
### mode: Ruby
|
26
|
+
### coding: utf-8-unix
|
27
|
+
### indent-tabs-mode: nil
|
28
|
+
### End:
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Lldp
|
7
|
+
# TLV value field of management address TLV
|
8
|
+
class ManagementAddressValue < BinData::Record
|
9
|
+
endian :big
|
10
|
+
|
11
|
+
stringz :management_address
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
### Local variables:
|
18
|
+
### mode: Ruby
|
19
|
+
### coding: utf-8-unix
|
20
|
+
### indent-tabs-mode: nil
|
21
|
+
### End:
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "pio/lldp/port-description-value"
|
2
|
+
require "pio/lldp/system-name-value"
|
3
|
+
require "pio/lldp/system-description-value"
|
4
|
+
require "pio/lldp/system-capabilities-value"
|
5
|
+
require "pio/lldp/management-address-value"
|
6
|
+
require "pio/lldp/end-of-lldpdu-value"
|
7
|
+
|
8
|
+
|
9
|
+
module Pio
|
10
|
+
class Lldp
|
11
|
+
# Optional TLV and End Of LLDPDU
|
12
|
+
class OptionalTlv < BinData::Record
|
13
|
+
endian :big
|
14
|
+
|
15
|
+
bit7 :tlv_type
|
16
|
+
bit9 :tlv_info_length
|
17
|
+
choice :tlv_value,
|
18
|
+
:read_length => :tlv_info_length,
|
19
|
+
:onlyif => lambda { not end_of_lldpdu? },
|
20
|
+
:selection => :chooser do
|
21
|
+
end_of_lldpdu_value 0
|
22
|
+
port_description_value 4
|
23
|
+
system_name_value 5
|
24
|
+
system_description_value 6
|
25
|
+
system_capabilities_value 7
|
26
|
+
management_address_value 8
|
27
|
+
string "unknown"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def end_of_lldpdu?
|
32
|
+
tlv_type == 0
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def chooser
|
37
|
+
if valid_optional_tlv?
|
38
|
+
tlv_type
|
39
|
+
else
|
40
|
+
"unknown"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
##########################################################################
|
46
|
+
private
|
47
|
+
##########################################################################
|
48
|
+
|
49
|
+
|
50
|
+
def valid_optional_tlv?
|
51
|
+
optional_tlv? or end_of_lldpdu_tlv?
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def optional_tlv?
|
56
|
+
tmp_tlv_type = tlv_type
|
57
|
+
4 <= tmp_tlv_type and tmp_tlv_type <= 8
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def end_of_lldpdu_tlv?
|
62
|
+
tlv_type == 0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
### Local variables:
|
70
|
+
### mode: Ruby
|
71
|
+
### coding: utf-8-unix
|
72
|
+
### indent-tabs-mode: nil
|
73
|
+
### End:
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Lldp
|
7
|
+
# TLV value field of port description TLV
|
8
|
+
class PortDescriptionValue < BinData::Record
|
9
|
+
endian :big
|
10
|
+
|
11
|
+
stringz :port_description
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
### Local variables:
|
18
|
+
### mode: Ruby
|
19
|
+
### coding: utf-8-unix
|
20
|
+
### indent-tabs-mode: nil
|
21
|
+
### End:
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bindata"
|
3
|
+
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
class Lldp
|
7
|
+
# Port ID TLV
|
8
|
+
class PortIdTlv < BinData::Primitive
|
9
|
+
endian :big
|
10
|
+
|
11
|
+
bit7 :tlv_type, :value => 2
|
12
|
+
bit9 :tlv_info_length, :initial_value => lambda { port_id.num_bytes + 1 }
|
13
|
+
uint8 :subtype, :initial_value => 7
|
14
|
+
string :port_id, :read_length => lambda { tlv_info_length - 1 }
|
15
|
+
|
16
|
+
|
17
|
+
def get
|
18
|
+
tmp_id = port_id
|
19
|
+
|
20
|
+
if subtype == 7
|
21
|
+
BinData::Uint32be.read tmp_id
|
22
|
+
else
|
23
|
+
tmp_id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def set value
|
29
|
+
self.port_id = if value.kind_of?( Fixnum ) and subtype == 7
|
30
|
+
BinData::Uint32be.new( value ).to_binary_s
|
31
|
+
else
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
### Local variables:
|
41
|
+
### mode: Ruby
|
42
|
+
### coding: utf-8-unix
|
43
|
+
### indent-tabs-mode: nil
|
44
|
+
### End:
|