pio 0.1.1 → 0.2.1

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.
@@ -0,0 +1,131 @@
1
+ require File.join( File.dirname( __FILE__ ), "..", "..", "spec_helper" )
2
+ require "pio/arp/request"
3
+
4
+
5
+ module Pio
6
+ class Arp
7
+ describe Request do
8
+ context ".new" do
9
+ subject {
10
+ Arp::Request.new(
11
+ :source_mac => source_mac,
12
+ :sender_protocol_address => sender_protocol_address,
13
+ :target_protocol_address => target_protocol_address
14
+ )
15
+ }
16
+
17
+ let( :arp_request_dump ) {
18
+ [
19
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
20
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
21
+ 0x08, 0x06, # ethernet type
22
+ 0x00, 0x01, # arp hardware type
23
+ 0x08, 0x00, # arp protocol type
24
+ 0x06, # hardware address size
25
+ 0x04, # protocol address size
26
+ 0x00, 0x01, # operational code
27
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
28
+ 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
29
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
30
+ 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
31
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # padding
32
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34
+ 0x00, 0x00, 0x00, 0x00,
35
+ ].pack( "C*" )
36
+ }
37
+
38
+
39
+ context "with Integer MAC and IP address" do
40
+ let( :source_mac ) { 0x002682ebead1 }
41
+ let( :sender_protocol_address ) { 0xc0a85303 }
42
+ let( :target_protocol_address ) { 0xc0a853fe }
43
+
44
+ context "#to_binary" do
45
+ it "returns an Arp Request binary String" do
46
+ expect( subject.to_binary ).to eq arp_request_dump
47
+ end
48
+
49
+ it "returns a valid ether frame with size = 64" do
50
+ expect( subject.to_binary.size ).to eq 64
51
+ end
52
+ end
53
+ end
54
+
55
+
56
+ context "with String MAC and IP address" do
57
+ let( :source_mac ) { "00:26:82:eb:ea:d1" }
58
+ let( :sender_protocol_address ) { 0xc0a85303 }
59
+ let( :target_protocol_address ) { 0xc0a853fe }
60
+
61
+ context "#to_binary" do
62
+ it "returns an Arp Request binary String" do
63
+ expect( subject.to_binary ).to eq arp_request_dump
64
+ end
65
+
66
+ it "returns a valid ether frame with size = 64" do
67
+ expect( subject.to_binary.size ).to eq 64
68
+ end
69
+ end
70
+ end
71
+
72
+
73
+ context "with Integer MAC and String IP address" do
74
+ let( :source_mac ) { 0x002682ebead1 }
75
+ let( :sender_protocol_address ) { "192.168.83.3" }
76
+ let( :target_protocol_address ) { "192.168.83.254" }
77
+
78
+ context "#to_binary" do
79
+ it "returns an Arp Request binary String" do
80
+ expect( subject.to_binary ).to eq arp_request_dump
81
+ end
82
+
83
+ it "returns a valid ether frame with size = 64" do
84
+ expect( subject.to_binary.size ).to eq 64
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ context "when :source_mac is not set" do
91
+ let( :source_mac ) { nil }
92
+ let( :sender_protocol_address ) { "192.168.83.3" }
93
+ let( :target_protocol_address ) { "192.168.83.254" }
94
+
95
+ it "raises an invalid MAC address error" do
96
+ expect { subject }.to raise_error( "Invalid MAC address: nil" )
97
+ end
98
+ end
99
+
100
+
101
+ context "when :sender_protocol_address is not set" do
102
+ let( :source_mac ) { 0x002682ebead1 }
103
+ let( :sender_protocol_address ) { nil }
104
+ let( :target_protocol_address ) { "192.168.83.254" }
105
+
106
+ it "raises an invalid IP address error" do
107
+ expect { subject }.to raise_error( "Invalid IP address: nil" )
108
+ end
109
+ end
110
+
111
+
112
+ context "when :target_protocol_address is not set" do
113
+ let( :source_mac ) { 0x002682ebead1 }
114
+ let( :sender_protocol_address ) { "192.168.83.254" }
115
+ let( :target_protocol_address ) { nil }
116
+
117
+ it "raises an invalid IP address error" do
118
+ expect { subject }.to raise_error( "Invalid IP address: nil" )
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ ### Local variables:
128
+ ### mode: Ruby
129
+ ### coding: utf-8-unix
130
+ ### indent-tabs-mode: nil
131
+ ### End:
@@ -0,0 +1,136 @@
1
+ require File.join( File.dirname( __FILE__ ), "..", "spec_helper" )
2
+ require "pio"
3
+
4
+
5
+ module Pio
6
+ describe Arp do
7
+ context ".read" do
8
+ subject { Arp.read( data.pack( "C*" ) ) }
9
+
10
+ context "with an ARP Request packet" do
11
+ let( :data ) {
12
+ [
13
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
14
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
15
+ 0x08, 0x06, # ethernet type
16
+ 0x00, 0x01, # arp hardware type
17
+ 0x08, 0x00, # arp protocol type
18
+ 0x06, # hardware address size
19
+ 0x04, # protocol address size
20
+ 0x00, 0x01, # operational code
21
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
22
+ 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
23
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
24
+ 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
25
+ ]
26
+ }
27
+
28
+ its( :class ) { should be Arp::Request }
29
+ its( "destination_mac.to_s" ) { should eq "ff:ff:ff:ff:ff:ff" }
30
+ its( "source_mac.to_s" ) { should eq "00:26:82:eb:ea:d1" }
31
+ its( :ether_type ) { should eq 0x0806 }
32
+ its( :hardware_type ) { should eq 1 }
33
+ its( :protocol_type ) { should eq 0x800 }
34
+ its( :hardware_length ) { should eq 6 }
35
+ its( :protocol_length ) { should eq 4 }
36
+ its( :operation ) { should eq 1 }
37
+ its( "sender_hardware_address.to_s" ) { should eq "00:26:82:eb:ea:d1" }
38
+ its( "sender_protocol_address.to_s" ) { should eq "192.168.83.3" }
39
+ its( "target_hardware_address.to_s" ) { should eq "00:00:00:00:00:00" }
40
+ its( "target_protocol_address.to_s" ) { should eq "192.168.83.254" }
41
+ end
42
+
43
+
44
+ context "with an ARP Reply packet" do
45
+ let( :data ) {
46
+ [
47
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
48
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # source mac address
49
+ 0x08, 0x06, # ethernet type
50
+ 0x00, 0x01, # arp hardware type
51
+ 0x08, 0x00, # arp protocol type
52
+ 0x06, # hardware address size
53
+ 0x04, # protocol address size
54
+ 0x00, 0x02, # operational code
55
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
56
+ 0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
57
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
58
+ 0xc0, 0xa8, 0x53, 0x03, # target protocol address
59
+ ]
60
+ }
61
+
62
+ its( :class ) { should be Arp::Reply }
63
+ its( "destination_mac.to_s" ) { should eq "00:26:82:eb:ea:d1" }
64
+ its( "source_mac.to_s" ) { should eq "00:16:9d:1d:9c:c4" }
65
+ its( :ether_type ) { should eq 0x0806 }
66
+ its( :hardware_type ) { should eq 1 }
67
+ its( :protocol_type ) { should eq 0x800 }
68
+ its( :hardware_length ) { should eq 6 }
69
+ its( :protocol_length ) { should eq 4 }
70
+ its( :operation ) { should eq 2 }
71
+ its( "sender_hardware_address.to_s" ) { should eq "00:16:9d:1d:9c:c4" }
72
+ its( "sender_protocol_address.to_s" ) { should eq "192.168.83.254" }
73
+ its( "target_hardware_address.to_s" ) { should eq "00:26:82:eb:ea:d1" }
74
+ its( "target_protocol_address.to_s" ) { should eq "192.168.83.3" }
75
+ end
76
+
77
+
78
+ context "with an ARP Request captured in real environment" do
79
+ let( :data ) {
80
+ [
81
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c, 0x9a, 0xd8, 0xea,
82
+ 0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
83
+ 0x00, 0x01, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
84
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
85
+ 0x00, 0xfe
86
+ ]
87
+ it { expect { subject }.not_to raise_error }
88
+ }
89
+ end
90
+
91
+
92
+ context "with an ARP Request from a real OpenFlow switch" do
93
+ let( :data ) {
94
+ [
95
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22, 0x33, 0x44,
96
+ 0x55, 0x66, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
97
+ 0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
98
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
99
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101
+ 0x00, 0x00, 0x00, 0x00
102
+ ]
103
+ it { expect { subject }.not_to raise_error }
104
+ }
105
+ end
106
+
107
+
108
+ context "with an ARP Reply captured in real environment" do
109
+ let( :data ) {
110
+ [
111
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x5c, 0x9a, 0xd8, 0xea,
112
+ 0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
113
+ 0x00, 0x02, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
114
+ 0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
115
+ 0x00, 0xfe
116
+ ]
117
+ it { expect { subject }.not_to raise_error }
118
+ }
119
+ end
120
+
121
+
122
+ context "with an invalid ARP packet" do
123
+ let( :data ) { [] }
124
+
125
+ it { expect { subject }.to raise_error( Pio::ParseError ) }
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+
132
+ ### Local variables:
133
+ ### mode: Ruby
134
+ ### coding: utf-8-unix
135
+ ### indent-tabs-mode: nil
136
+ ### End:
@@ -0,0 +1,38 @@
1
+ require File.join( File.dirname( __FILE__ ), "..", "spec_helper" )
2
+ require "pio/ip"
3
+
4
+
5
+ module Pio
6
+ describe IP do
7
+ context ".new" do
8
+ subject { IP.new( ip_address, prefixlen ) }
9
+
10
+
11
+ context %{with "192.168.1.1", 32} do
12
+ let( :ip_address ) { "192.168.1.1" }
13
+ let( :prefixlen ) { 32 }
14
+
15
+ its( :to_s ) { should eq "192.168.1.1" }
16
+ its( :to_i ) { should eq 3232235777 }
17
+ its( :to_a ) { should eq [ 0xc0, 0xa8, 0x01, 0x01 ] }
18
+ end
19
+
20
+
21
+ context %{with "10.1.1.1", 8} do
22
+ let( :ip_address ) { "10.1.1.1" }
23
+ let( :prefixlen ) { 8 }
24
+
25
+ its( :to_s ) { should eq "10.0.0.0" }
26
+ its( :to_i ) { should eq 10 * 256 * 256 * 256 }
27
+ its( :to_a ) { should eq [ 0x0a, 0x00, 0x00, 0x00 ] }
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:
@@ -1,55 +1,212 @@
1
1
  require File.join( File.dirname( __FILE__ ), "..", "spec_helper" )
2
- require "pio/lldp"
2
+ require "pio"
3
3
 
4
4
 
5
5
  module Pio
6
6
  describe Lldp do
7
- subject { Lldp.read( data.pack( "C*" ) ) }
8
-
9
- context "parsing a minimal LLDP frame" do
10
- let( :data ) {
11
- [
12
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
13
- 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Source MAC
14
- 0x88, 0xcc, # Ethertype
15
- 0x02, 0x07, 0x04, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
16
- 0x04, 0x0d, 0x01, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x31, # Port ID TLV
17
- 0x06, 0x02, 0x00, 0x78, # Time to live TLV
18
- 0x00, 0x00 # End of LLDPDU TLV
19
- ]
7
+ context ".new" do
8
+ subject {
9
+ Lldp.new(
10
+ :dpid => dpid,
11
+ :port_number => port_number,
12
+ :source_mac => source_mac,
13
+ :destination_mac => destination_mac
14
+ )
20
15
  }
21
16
 
22
- its( :dpid ) { should eq 108173701773 }
23
17
 
24
- it "should successfully parse the data" do
25
- lambda { subject }.should_not raise_error
18
+ context "with :dpid and :port_number" do
19
+ let( :dpid ) { 108173701773 }
20
+ let( :port_number ) { 1 }
21
+ let( :source_mac ) { nil }
22
+ let( :destination_mac ) { nil }
23
+ let( :lldp_dump ) {
24
+ [
25
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
26
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, # Source MAC
27
+ 0x88, 0xcc, # Ethertype
28
+ 0x02, 0x09, 0x07, 0x00, 0x00, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
29
+ 0x04, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, # Port ID TLV
30
+ 0x06, 0x02, 0x00, 0x78, # Time to live TLV
31
+ 0x00, 0x00, # End of LLDPDU TLV
32
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Padding
33
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34
+ 0x00, 0x00
35
+ ]
36
+ }
37
+
38
+ context "#to_binary" do
39
+ it "returns an LLDP binary string" do
40
+ expect( subject.to_binary.unpack( "C*" ) ).to eq lldp_dump
41
+ end
42
+
43
+ it "returns a valid ether frame with size = 64" do
44
+ expect( subject.to_binary.size ).to eq 64
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ context "with :dpid, :port_number and :source_mac" do
51
+ let( :dpid ) { 108173701773 }
52
+ let( :port_number ) { 1 }
53
+ let( :source_mac ) { "06:05:04:03:02:01" }
54
+ let( :destination_mac ) { nil }
55
+ let( :lldp_dump ) {
56
+ [
57
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
58
+ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, # Source MAC
59
+ 0x88, 0xcc, # Ethertype
60
+ 0x02, 0x09, 0x07, 0x00, 0x00, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
61
+ 0x04, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, # Port ID TLV
62
+ 0x06, 0x02, 0x00, 0x78, # Time to live TLV
63
+ 0x00, 0x00, # End of LLDPDU TLV
64
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Padding
65
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66
+ 0x00, 0x00
67
+ ]
68
+ }
69
+
70
+ context "#to_binary" do
71
+ it "returns an LLDP binary string" do
72
+ expect( subject.to_binary.unpack( "C*" ) ).to eq lldp_dump
73
+ end
74
+
75
+ it "returns a valid ether frame with size = 64" do
76
+ expect( subject.to_binary.size ).to eq 64
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ context "with :dpid, :port_number, :source_mac and :destination_mac" do
83
+ let( :dpid ) { 108173701773 }
84
+ let( :port_number ) { 1 }
85
+ let( :source_mac ) { "06:05:04:03:02:01" }
86
+ let( :destination_mac ) { "01:02:03:04:05:06" }
87
+ let( :lldp_dump ) {
88
+ [
89
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, # Destination MAC
90
+ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, # Source MAC
91
+ 0x88, 0xcc, # Ethertype
92
+ 0x02, 0x09, 0x07, 0x00, 0x00, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
93
+ 0x04, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, # Port ID TLV
94
+ 0x06, 0x02, 0x00, 0x78, # Time to live TLV
95
+ 0x00, 0x00, # End of LLDPDU TLV
96
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Padding
97
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98
+ 0x00, 0x00
99
+ ]
100
+ }
101
+
102
+ context "#to_binary" do
103
+ it "returns an LLDP binary string" do
104
+ expect( subject.to_binary.unpack( "C*" ) ).to eq lldp_dump
105
+ end
106
+
107
+ it "returns a valid ether frame with size = 64" do
108
+ expect( subject.to_binary.size ).to eq 64
109
+ end
110
+ end
111
+ end
112
+
113
+
114
+ context "when :dpid is not set" do
115
+ let( :dpid ) { nil }
116
+ let( :port_number ) { 1 }
117
+ let( :source_mac ) { nil }
118
+ let( :destination_mac ) { nil }
119
+
120
+ it { expect { subject }.to raise_error( "Invalid DPID: nil" ) }
121
+ end
122
+
123
+
124
+ context "when :port_number is not set" do
125
+ let( :dpid ) { 108173701773 }
126
+ let( :port_number ) { nil }
127
+ let( :source_mac ) { nil }
128
+ let( :destination_mac ) { nil }
129
+
130
+ it { expect { subject }.to raise_error( "Invalid port number: nil" ) }
26
131
  end
27
132
  end
28
133
 
29
134
 
30
- context "parsing a detailed LLDP frame" do
31
- let( :data ) {
32
- [
33
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
34
- 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Source MAC
35
- 0x88, 0xcc, # Ethertype
36
- 0x02, 0x07, 0x04, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
37
- 0x04, 0x0d, 0x01, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x31, # Port ID TLV
38
- 0x06, 0x02, 0x00, 0x78, # Time to live TLV
39
- 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, # Port Description
40
- 0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x00, # System Name
41
- 0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x20, 0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, 0x31, 0x20, 0x28, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, 0x35, 0x33, 0x3a, 0x31, 0x31, 0x00, # System Description
42
- 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, # System Capabilities
43
- 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00,
44
- 0xfe, 0x07, 0x00, 0x12, 0x0f, 0x02, 0x07, 0x01, 0x00,
45
- 0x00, 0x00 # End of LLDPDU TLV
46
- ]
47
- }
135
+ context ".read" do
136
+ subject { Lldp.read( data.pack( "C*" ) ) }
137
+
138
+ context "with a minimal LLDP frame" do
139
+ let( :data ) {
140
+ [
141
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
142
+ 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Source MAC
143
+ 0x88, 0xcc, # Ethertype
144
+ 0x02, 0x07, 0x04, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
145
+ 0x04, 0x0d, 0x01, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x31, # Port ID TLV
146
+ 0x06, 0x02, 0x00, 0x78, # Time to live TLV
147
+ 0x00, 0x00 # End of LLDPDU TLV
148
+ ]
149
+ }
150
+
151
+ its( "destination_mac.to_s" ) { should eq "01:80:c2:00:00:0e" }
152
+ its( "source_mac.to_s" ) { should eq "00:19:2f:a7:b2:8d" }
153
+ its( :ether_type ) { should eq 0x88cc }
154
+ its( :dpid ) { should eq 108173701773 }
155
+ its( :chassis_id ) { should eq 108173701773 }
156
+ its( :port_id ) { should eq "Uplink to S1" }
157
+ its( :port_number ) { should eq "Uplink to S1" }
158
+ its( :ttl ) { should eq 120 }
159
+ its( :port_description ) { should be_nil }
160
+ its( :system_name ) { should be_nil }
161
+ its( :system_description ) { should be_nil }
162
+ its( :system_capabilities ) { should be_nil }
163
+ its( :management_address ) { should be_nil }
164
+ end
165
+
166
+
167
+ context "with a detailed LLDP frame" do
168
+ let( :data ) {
169
+ [
170
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, # Destination MAC
171
+ 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Source MAC
172
+ 0x88, 0xcc, # Ethertype
173
+ 0x02, 0x07, 0x04, 0x00, 0x19, 0x2f, 0xa7, 0xb2, 0x8d, # Chassis ID TLV
174
+ 0x04, 0x0d, 0x01, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x31, # Port ID TLV
175
+ 0x06, 0x02, 0x00, 0x78, # Time to live TLV
176
+ 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, # Port Description
177
+ 0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x00, # System Name
178
+ 0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x20, 0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, 0x31, 0x20, 0x28, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, 0x35, 0x33, 0x3a, 0x31, 0x31, 0x00, # System Description
179
+ 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, # System Capabilities
180
+ 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00, # Management Address
181
+ 0xfe, 0x07, 0x00, 0x12, 0x0f, 0x02, 0x07, 0x01, 0x00, # Organizationally Specific
182
+ 0x00, 0x00 # End of LLDPDU TLV
183
+ ]
184
+ }
185
+
186
+ its( "destination_mac.to_s" ) { should eq "01:80:c2:00:00:0e" }
187
+ its( "source_mac.to_s" ) { should eq "00:19:2f:a7:b2:8d" }
188
+ its( :ether_type ) { should eq 0x88cc }
189
+ its( :dpid ) { should eq 108173701773 }
190
+ its( :chassis_id ) { should eq 108173701773 }
191
+ its( :port_id ) { should eq "Uplink to S1" }
192
+ its( :port_number ) { should eq "Uplink to S1" }
193
+ its( :ttl ) { should eq 120 }
194
+ its( :port_description ) { should eq "Summit300-48-Port 1001" }
195
+ its( :system_name ) { should eq "Summit300-48" }
196
+ its( :system_description ) { should eq "Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11" }
197
+ its( "system_capabilities.system_capabilities" ) { should eq 20 }
198
+ its( "system_capabilities.enabled_capabilities" ) { should eq 20 }
199
+ its( :management_address ) { should eq [ 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0 ].pack( "C*" ) }
200
+ its( "organizationally_specific.oui" ) { should eq 4623 }
201
+ its( "organizationally_specific.subtype" ) { should eq 2 }
202
+ its( "organizationally_specific.information" ) { should eq "\a\x01" }
203
+ end
204
+
48
205
 
49
- its( :dpid ) { should eq 108173701773 }
206
+ context "with an invalid Lldp frame" do
207
+ let( :data ) { [] }
50
208
 
51
- it "should successfully parse the data" do
52
- lambda { subject }.should_not raise_error
209
+ it { expect { subject }.to raise_error( Pio::ParseError ) }
53
210
  end
54
211
  end
55
212
  end