pio 0.2.7 → 0.3.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 +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
data/spec/pio/arp_spec.rb
CHANGED
@@ -1,133 +1,125 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
]
|
25
|
-
}
|
26
|
-
|
27
|
-
its( :class ) { should be Arp::Request }
|
28
|
-
its( "destination_mac.to_s" ) { should eq "ff:ff:ff:ff:ff:ff" }
|
29
|
-
its( "source_mac.to_s" ) { should eq "00:26:82:eb:ea:d1" }
|
30
|
-
its( :ether_type ) { should eq 0x0806 }
|
31
|
-
its( :hardware_type ) { should eq 1 }
|
32
|
-
its( :protocol_type ) { should eq 0x800 }
|
33
|
-
its( :hardware_length ) { should eq 6 }
|
34
|
-
its( :protocol_length ) { should eq 4 }
|
35
|
-
its( :operation ) { should eq 1 }
|
36
|
-
its( "sender_hardware_address.to_s" ) { should eq "00:26:82:eb:ea:d1" }
|
37
|
-
its( "sender_protocol_address.to_s" ) { should eq "192.168.83.3" }
|
38
|
-
its( "target_hardware_address.to_s" ) { should eq "00:00:00:00:00:00" }
|
39
|
-
its( "target_protocol_address.to_s" ) { should eq "192.168.83.254" }
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio'
|
3
|
+
|
4
|
+
describe Pio::Arp do
|
5
|
+
context '.read' do
|
6
|
+
subject { Pio::Arp.read(data.pack('C*')) }
|
7
|
+
|
8
|
+
context 'with an ARP Request packet' do
|
9
|
+
let(:data) do
|
10
|
+
[
|
11
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
|
12
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
|
13
|
+
0x08, 0x06, # ethernet type
|
14
|
+
0x00, 0x01, # arp hardware type
|
15
|
+
0x08, 0x00, # arp protocol type
|
16
|
+
0x06, # hardware address size
|
17
|
+
0x04, # protocol address size
|
18
|
+
0x00, 0x01, # operational code
|
19
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
|
20
|
+
0xc0, 0xa8, 0x53, 0x03, # sender protocol address
|
21
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
|
22
|
+
0xc0, 0xa8, 0x53, 0xfe, # target protocol address
|
23
|
+
]
|
40
24
|
end
|
41
25
|
|
26
|
+
its(:class) { should be Pio::Arp::Request }
|
27
|
+
its('destination_mac.to_s') { should eq 'ff:ff:ff:ff:ff:ff' }
|
28
|
+
its('source_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
|
29
|
+
its(:ether_type) { should eq 0x0806 }
|
30
|
+
its(:hardware_type) { should eq 1 }
|
31
|
+
its(:protocol_type) { should eq 0x800 }
|
32
|
+
its(:hardware_length) { should eq 6 }
|
33
|
+
its(:protocol_length) { should eq 4 }
|
34
|
+
its(:operation) { should eq 1 }
|
35
|
+
its('sender_hardware_address.to_s') { should eq '00:26:82:eb:ea:d1' }
|
36
|
+
its('sender_protocol_address.to_s') { should eq '192.168.83.3' }
|
37
|
+
its('target_hardware_address.to_s') { should eq '00:00:00:00:00:00' }
|
38
|
+
its('target_protocol_address.to_s') { should eq '192.168.83.254' }
|
39
|
+
end
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
}
|
60
|
-
|
61
|
-
its( :class ) { should be Arp::Reply }
|
62
|
-
its( "destination_mac.to_s" ) { should eq "00:26:82:eb:ea:d1" }
|
63
|
-
its( "source_mac.to_s" ) { should eq "00:16:9d:1d:9c:c4" }
|
64
|
-
its( :ether_type ) { should eq 0x0806 }
|
65
|
-
its( :hardware_type ) { should eq 1 }
|
66
|
-
its( :protocol_type ) { should eq 0x800 }
|
67
|
-
its( :hardware_length ) { should eq 6 }
|
68
|
-
its( :protocol_length ) { should eq 4 }
|
69
|
-
its( :operation ) { should eq 2 }
|
70
|
-
its( "sender_hardware_address.to_s" ) { should eq "00:16:9d:1d:9c:c4" }
|
71
|
-
its( "sender_protocol_address.to_s" ) { should eq "192.168.83.254" }
|
72
|
-
its( "target_hardware_address.to_s" ) { should eq "00:26:82:eb:ea:d1" }
|
73
|
-
its( "target_protocol_address.to_s" ) { should eq "192.168.83.3" }
|
41
|
+
context 'with an ARP Reply packet' do
|
42
|
+
let(:data) do
|
43
|
+
[
|
44
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
|
45
|
+
0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # source mac address
|
46
|
+
0x08, 0x06, # ethernet type
|
47
|
+
0x00, 0x01, # arp hardware type
|
48
|
+
0x08, 0x00, # arp protocol type
|
49
|
+
0x06, # hardware address size
|
50
|
+
0x04, # protocol address size
|
51
|
+
0x00, 0x02, # operational code
|
52
|
+
0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
|
53
|
+
0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
|
54
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
|
55
|
+
0xc0, 0xa8, 0x53, 0x03, # target protocol address
|
56
|
+
]
|
74
57
|
end
|
75
58
|
|
59
|
+
its(:class) { should be Pio::Arp::Reply }
|
60
|
+
its('destination_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
|
61
|
+
its('source_mac.to_s') { should eq '00:16:9d:1d:9c:c4' }
|
62
|
+
its(:ether_type) { should eq 0x0806 }
|
63
|
+
its(:hardware_type) { should eq 1 }
|
64
|
+
its(:protocol_type) { should eq 0x800 }
|
65
|
+
its(:hardware_length) { should eq 6 }
|
66
|
+
its(:protocol_length) { should eq 4 }
|
67
|
+
its(:operation) { should eq 2 }
|
68
|
+
its('sender_hardware_address.to_s') { should eq '00:16:9d:1d:9c:c4' }
|
69
|
+
its('sender_protocol_address.to_s') { should eq '192.168.83.254' }
|
70
|
+
its('target_hardware_address.to_s') { should eq '00:26:82:eb:ea:d1' }
|
71
|
+
its('target_protocol_address.to_s') { should eq '192.168.83.3' }
|
72
|
+
end
|
76
73
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
it { expect { subject }.not_to raise_error }
|
87
|
-
}
|
74
|
+
context 'with an ARP Request captured in real environment' do
|
75
|
+
let(:data) do
|
76
|
+
[
|
77
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c, 0x9a, 0xd8, 0xea,
|
78
|
+
0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
|
79
|
+
0x00, 0x01, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
|
80
|
+
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
|
81
|
+
0x00, 0xfe
|
82
|
+
]
|
88
83
|
end
|
84
|
+
it { expect { subject }.not_to raise_error }
|
85
|
+
end
|
89
86
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
]
|
102
|
-
it { expect { subject }.not_to raise_error }
|
103
|
-
}
|
87
|
+
context 'with an ARP Request from a real OpenFlow switch' do
|
88
|
+
let(:data) do
|
89
|
+
[
|
90
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22, 0x33, 0x44,
|
91
|
+
0x55, 0x66, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
|
92
|
+
0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
|
93
|
+
0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
|
94
|
+
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
95
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
96
|
+
0x00, 0x00, 0x00, 0x00
|
97
|
+
]
|
104
98
|
end
|
99
|
+
it { expect { subject }.not_to raise_error }
|
100
|
+
end
|
105
101
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
]
|
116
|
-
it { expect { subject }.not_to raise_error }
|
117
|
-
}
|
102
|
+
context 'with an ARP Reply captured in real environment' do
|
103
|
+
let(:data) do
|
104
|
+
[
|
105
|
+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x5c, 0x9a, 0xd8, 0xea,
|
106
|
+
0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
|
107
|
+
0x00, 0x02, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
|
108
|
+
0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
|
109
|
+
0x00, 0xfe
|
110
|
+
]
|
118
111
|
end
|
112
|
+
it { expect { subject }.not_to raise_error }
|
113
|
+
end
|
119
114
|
|
115
|
+
context 'with an invalid ARP packet' do
|
116
|
+
let(:data) { [] }
|
120
117
|
|
121
|
-
|
122
|
-
let( :data ) { [] }
|
123
|
-
|
124
|
-
it { expect { subject }.to raise_error( Pio::ParseError ) }
|
125
|
-
end
|
118
|
+
it { expect { subject }.to raise_error(Pio::ParseError) }
|
126
119
|
end
|
127
120
|
end
|
128
121
|
end
|
129
122
|
|
130
|
-
|
131
123
|
### Local variables:
|
132
124
|
### mode: Ruby
|
133
125
|
### coding: utf-8-unix
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/icmp/reply'
|
3
|
+
|
4
|
+
describe Pio::Icmp::Reply do
|
5
|
+
context '.new' do
|
6
|
+
subject do
|
7
|
+
Pio::Icmp::Reply.new(
|
8
|
+
:destination_mac => '00:26:82:eb:ea:d1',
|
9
|
+
:source_mac => '24:db:ac:41:e5:5b',
|
10
|
+
:ip_source_address => '8.8.8.8',
|
11
|
+
:ip_destination_address => '192.168.1.102',
|
12
|
+
:echo_data => echo_data
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with :echo_data' do
|
17
|
+
let(:echo_data) { 'abcdefghijklmnopqrstuvwabcdefghi' }
|
18
|
+
|
19
|
+
context '#to_binary' do
|
20
|
+
it 'returns an ICMP reply binary string' do
|
21
|
+
valid_icmp_reply_dump = [
|
22
|
+
# Destination MAC
|
23
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1,
|
24
|
+
# Source MAC
|
25
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
26
|
+
# EtherType
|
27
|
+
0x08, 0x00,
|
28
|
+
# IP Version&IP Header Length
|
29
|
+
0x45,
|
30
|
+
# IP Type Of Service
|
31
|
+
0x00,
|
32
|
+
# IP Total Length
|
33
|
+
0x00, 0x3c,
|
34
|
+
# IP Identifier
|
35
|
+
0x00, 0x00,
|
36
|
+
# IP Flag&IP Fragment
|
37
|
+
0x00, 0x00,
|
38
|
+
# IP TTL
|
39
|
+
0x80,
|
40
|
+
# IP Protocol
|
41
|
+
0x01,
|
42
|
+
# IP Header Checksum
|
43
|
+
0x68, 0xa3,
|
44
|
+
# IP Source Address
|
45
|
+
0x08, 0x08, 0x08, 0x08,
|
46
|
+
# IP Destination Address
|
47
|
+
0xc0, 0xa8, 0x01, 0x66,
|
48
|
+
# ICMP Type
|
49
|
+
0x00,
|
50
|
+
# ICMP Code
|
51
|
+
0x00,
|
52
|
+
# ICMP Checksum
|
53
|
+
0x54, 0x5b,
|
54
|
+
# ICMP Identifier
|
55
|
+
0x01, 0x00,
|
56
|
+
# ICMP Sequence Number
|
57
|
+
0x00, 0x01,
|
58
|
+
# Echo Data
|
59
|
+
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
60
|
+
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
61
|
+
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
62
|
+
0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65,
|
63
|
+
0x66, 0x67, 0x68, 0x69
|
64
|
+
]
|
65
|
+
|
66
|
+
expect(subject.to_binary.unpack('C*')).to eq valid_icmp_reply_dump
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with an empty :echo_data' do
|
72
|
+
let(:echo_data) { '' }
|
73
|
+
|
74
|
+
context '#to_binary' do
|
75
|
+
it 'returns an ICMP reply binary string' do
|
76
|
+
valid_icmp_reply_dump = [
|
77
|
+
# Destination MAC
|
78
|
+
# Destination MAC
|
79
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1,
|
80
|
+
# Source MAC
|
81
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
82
|
+
# EtherType
|
83
|
+
0x08, 0x00,
|
84
|
+
# IP Version&IP Header Length
|
85
|
+
0x45,
|
86
|
+
# IP Type Of Service
|
87
|
+
0x00,
|
88
|
+
# IP Total Length
|
89
|
+
0x00, 0x32,
|
90
|
+
# IP Identifier
|
91
|
+
0x00, 0x00,
|
92
|
+
# IP Flag&IP Fragment
|
93
|
+
0x00, 0x00,
|
94
|
+
# IP TTL
|
95
|
+
0x80,
|
96
|
+
# IP Protocol
|
97
|
+
0x01,
|
98
|
+
# IP Header Checksum
|
99
|
+
0x68, 0xad,
|
100
|
+
# IP Source Address
|
101
|
+
0x08, 0x08, 0x08, 0x08,
|
102
|
+
# IP Destination Address
|
103
|
+
0xc0, 0xa8, 0x01, 0x66,
|
104
|
+
# ICMP Type
|
105
|
+
0x00,
|
106
|
+
# ICMP Code
|
107
|
+
0x00,
|
108
|
+
# ICMP Checksum
|
109
|
+
0xfe, 0xfe,
|
110
|
+
# ICMP Identifier
|
111
|
+
0x01, 0x00,
|
112
|
+
# ICMP Sequence Number
|
113
|
+
0x00, 0x01,
|
114
|
+
# Echo Data
|
115
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
116
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
117
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
118
|
+
0x00, 0x00, 0x00, 0x00
|
119
|
+
]
|
120
|
+
|
121
|
+
expect(subject.to_binary.unpack('C*')).to eq valid_icmp_reply_dump
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
### Local variables:
|
129
|
+
### mode: Ruby
|
130
|
+
### coding: utf-8-unix
|
131
|
+
### indent-tabs-mode: nil
|
132
|
+
### End:
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio/icmp/request'
|
3
|
+
|
4
|
+
describe Pio::Icmp::Request do
|
5
|
+
context '.new' do
|
6
|
+
subject do
|
7
|
+
Pio::Icmp::Request.new(
|
8
|
+
:destination_mac => '24:db:ac:41:e5:5b',
|
9
|
+
:source_mac => '74:e5:0b:2a:18:f8',
|
10
|
+
:ip_source_address => '192.168.1.101',
|
11
|
+
:ip_destination_address => '8.8.8.8',
|
12
|
+
:echo_data => echo_data
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with :echo_data' do
|
17
|
+
let(:echo_data) { 'abcdefghijklmnopqrstuvwabcdefghi' }
|
18
|
+
|
19
|
+
context '#to_binary' do
|
20
|
+
it 'returns an ICMP request binary string' do
|
21
|
+
valid_icmp_request_dump = [
|
22
|
+
# Destination MAC
|
23
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
24
|
+
# Source MAC
|
25
|
+
0x74, 0xe5, 0x0b, 0x2a, 0x18, 0xf8,
|
26
|
+
# EtherType
|
27
|
+
0x08, 0x00,
|
28
|
+
# IP Version&IP Header Length
|
29
|
+
0x45,
|
30
|
+
# IP Type Of Service
|
31
|
+
0x00,
|
32
|
+
# IP Total Length
|
33
|
+
0x00, 0x3c,
|
34
|
+
# IP Identifier
|
35
|
+
0x00, 0x00,
|
36
|
+
# IP Flag&IP Fragment
|
37
|
+
0x00, 0x00,
|
38
|
+
# IP TTL
|
39
|
+
0x80,
|
40
|
+
# IP Protocol
|
41
|
+
0x01,
|
42
|
+
# IP Header Checksum
|
43
|
+
0x68, 0xa4,
|
44
|
+
# IP Source Address
|
45
|
+
0xc0, 0xa8, 0x01, 0x65,
|
46
|
+
# IP Destination Address
|
47
|
+
0x08, 0x08, 0x08, 0x08,
|
48
|
+
# ICMP Type
|
49
|
+
0x08,
|
50
|
+
# ICMP Code
|
51
|
+
0x00,
|
52
|
+
# ICMP Checksum
|
53
|
+
0x4c, 0x5b,
|
54
|
+
# ICMP Identifier
|
55
|
+
0x01, 0x00,
|
56
|
+
# ICMP Sequence Number
|
57
|
+
0x00, 0x01,
|
58
|
+
# Echo Data
|
59
|
+
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
60
|
+
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
61
|
+
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
62
|
+
0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65,
|
63
|
+
0x66, 0x67, 0x68, 0x69
|
64
|
+
]
|
65
|
+
|
66
|
+
expect(subject.to_binary.unpack('C*')).to eq valid_icmp_request_dump
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with an emply :echo_data' do
|
72
|
+
let(:echo_data) { '' }
|
73
|
+
|
74
|
+
context '#to_binary' do
|
75
|
+
it 'returns an ICMP request binary string' do
|
76
|
+
valid_icmp_request_dump = [
|
77
|
+
# Destination MAC
|
78
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
79
|
+
# Source MAC
|
80
|
+
0x74, 0xe5, 0x0b, 0x2a, 0x18, 0xf8,
|
81
|
+
# EtherType
|
82
|
+
0x08, 0x00,
|
83
|
+
# IP Version&IP Header Length
|
84
|
+
0x45,
|
85
|
+
# IP Type Of Service
|
86
|
+
0x00,
|
87
|
+
# IP Total Length
|
88
|
+
0x00, 0x32,
|
89
|
+
# IP Identifier
|
90
|
+
0x00, 0x00,
|
91
|
+
# IP Flag&IP Fragment
|
92
|
+
0x00, 0x00,
|
93
|
+
# IP TTL
|
94
|
+
0x80,
|
95
|
+
# IP Protocol
|
96
|
+
0x01,
|
97
|
+
# IP Header Checksum
|
98
|
+
0x68, 0xae,
|
99
|
+
# IP Source Address
|
100
|
+
0xc0, 0xa8, 0x01, 0x65,
|
101
|
+
# IP Destination Address
|
102
|
+
0x08, 0x08, 0x08, 0x08,
|
103
|
+
# ICMP Type
|
104
|
+
0x08,
|
105
|
+
# ICMP Code
|
106
|
+
0x00,
|
107
|
+
# ICMP Checksum
|
108
|
+
0xf6, 0xfe,
|
109
|
+
# ICMP Identifier
|
110
|
+
0x01, 0x00,
|
111
|
+
# ICMP Sequence Number
|
112
|
+
0x00, 0x01,
|
113
|
+
# Echo Data
|
114
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
115
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
116
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
117
|
+
0x00, 0x00, 0x00, 0x00
|
118
|
+
]
|
119
|
+
|
120
|
+
expect(subject.to_binary.unpack('C*')).to eq valid_icmp_request_dump
|
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,159 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'pio'
|
3
|
+
|
4
|
+
describe Pio::Icmp do
|
5
|
+
context '.read' do
|
6
|
+
subject { Pio::Icmp.read(data.pack('C*')) }
|
7
|
+
|
8
|
+
context 'with Icmp request frame' do
|
9
|
+
let(:data) do
|
10
|
+
[
|
11
|
+
# Destination MAC
|
12
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
13
|
+
# Source MAC
|
14
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1,
|
15
|
+
# EtherType
|
16
|
+
0x08, 0x00,
|
17
|
+
# IP Version&IP Header Length
|
18
|
+
0x45,
|
19
|
+
# IP Type Of Service
|
20
|
+
0x00,
|
21
|
+
# IP Total Length
|
22
|
+
0x00, 0x3c,
|
23
|
+
# IP Identifier
|
24
|
+
0x39, 0xd3,
|
25
|
+
# IP Flag&IP Fragment
|
26
|
+
0x00, 0x00,
|
27
|
+
# IP TTL
|
28
|
+
0x80,
|
29
|
+
# IP Protocol
|
30
|
+
0x01,
|
31
|
+
# IP Header Checksum
|
32
|
+
0x2e, 0xd0,
|
33
|
+
# IP Source Address
|
34
|
+
0xc0, 0xa8, 0x01, 0x66,
|
35
|
+
# IP Destination Address
|
36
|
+
0x08, 0x08, 0x08, 0x08,
|
37
|
+
# ICMP Type
|
38
|
+
0x08,
|
39
|
+
# ICMP Code
|
40
|
+
0x00,
|
41
|
+
# ICMP Checksum
|
42
|
+
0x4c, 0x5b,
|
43
|
+
# ICMP Identifier
|
44
|
+
0x01, 0x00,
|
45
|
+
# ICMP Sequence Number
|
46
|
+
0x00, 0x01,
|
47
|
+
# Echo Data
|
48
|
+
0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
49
|
+
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
50
|
+
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
51
|
+
0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
|
52
|
+
0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
53
|
+
0x68, 0x69
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
its('destination_mac.to_s') { should eq '24:db:ac:41:e5:5b' }
|
58
|
+
its('source_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
|
59
|
+
its(:ether_type) { should eq 0x0800 }
|
60
|
+
its(:ip_version) { should eq 0x4 }
|
61
|
+
its(:ip_header_length) { should eq 0x5 }
|
62
|
+
its(:ip_type_of_service) { should eq 0x0 }
|
63
|
+
its(:ip_total_length) { should eq 60 }
|
64
|
+
its(:ip_identifier) { should eq 0x39d3 }
|
65
|
+
its(:ip_fragment) { should eq 0 }
|
66
|
+
its(:ip_ttl) { should eq 128 }
|
67
|
+
its(:ip_protocol) { should eq 1 }
|
68
|
+
its(:ip_header_checksum) { should eq 0x2ed0 }
|
69
|
+
its('ip_source_address.to_s') { should eq '192.168.1.102' }
|
70
|
+
its('ip_destination_address.to_s') { should eq '8.8.8.8' }
|
71
|
+
its(:icmp_type) { should eq 8 }
|
72
|
+
its(:icmp_code) { should eq 0 }
|
73
|
+
its(:icmp_checksum) { should eq 0x4c5b }
|
74
|
+
its(:icmp_identifier) { should eq 0x0100 }
|
75
|
+
its(:icmp_sequence_number) { should eq 0x0001 }
|
76
|
+
its(:echo_data) { should eq 'abcdefghijklmnopqrstuvwabcdefghi' }
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with Icmp reply frame' do
|
80
|
+
let(:data) do
|
81
|
+
[
|
82
|
+
# Destination MAC
|
83
|
+
0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1,
|
84
|
+
# Source MAC
|
85
|
+
0x24, 0xdb, 0xac, 0x41, 0xe5, 0x5b,
|
86
|
+
# EtherType
|
87
|
+
0x08, 0x00,
|
88
|
+
# IP Version&IP Header Length
|
89
|
+
0x45,
|
90
|
+
# IP Type Of Service
|
91
|
+
0x00,
|
92
|
+
# IP Total Length
|
93
|
+
0x00, 0x3c,
|
94
|
+
# IP Identifier
|
95
|
+
0x00, 0x00,
|
96
|
+
# IP Flag&IP Fragment
|
97
|
+
0x00, 0x00,
|
98
|
+
# IP TTL
|
99
|
+
0x2d,
|
100
|
+
# IP Protocol
|
101
|
+
0x01,
|
102
|
+
# IP Header Checksum
|
103
|
+
0xbb, 0xa3,
|
104
|
+
# IP Source Address
|
105
|
+
0x08, 0x08, 0x08, 0x08,
|
106
|
+
# IP Destination Address
|
107
|
+
0xc0, 0xa8, 0x01, 0x66,
|
108
|
+
# ICMP Type
|
109
|
+
0x00,
|
110
|
+
# ICMP Code
|
111
|
+
0x00,
|
112
|
+
# ICMP Checksum
|
113
|
+
0x54, 0x5b,
|
114
|
+
# ICMP Identifier
|
115
|
+
0x01, 0x00,
|
116
|
+
# ICMP Sequence Number
|
117
|
+
0x00, 0x01,
|
118
|
+
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
|
119
|
+
0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
|
120
|
+
0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
121
|
+
0x68, 0x69
|
122
|
+
]
|
123
|
+
end
|
124
|
+
|
125
|
+
its('destination_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
|
126
|
+
its('source_mac.to_s') { should eq '24:db:ac:41:e5:5b' }
|
127
|
+
its(:ether_type) { should eq 0x0800 }
|
128
|
+
its(:ip_version) { should eq 0x4 }
|
129
|
+
its(:ip_header_length) { should eq 0x5 }
|
130
|
+
its(:ip_type_of_service) { should eq 0 }
|
131
|
+
its(:ip_total_length) { should eq 60 }
|
132
|
+
its(:ip_identifier) { should eq 0 }
|
133
|
+
its(:ip_fragment) { should eq 0 }
|
134
|
+
its(:ip_ttl) { should eq 45 }
|
135
|
+
its(:ip_protocol) { should eq 1 }
|
136
|
+
its(:ip_header_checksum) { should eq 0xbba3 }
|
137
|
+
its('ip_source_address.to_s') { should eq '8.8.8.8' }
|
138
|
+
its('ip_destination_address.to_s') { should eq '192.168.1.102' }
|
139
|
+
its(:icmp_type) { should eq 0 }
|
140
|
+
its(:icmp_code) { should eq 0 }
|
141
|
+
its(:icmp_checksum) { should eq 0x545b }
|
142
|
+
its(:icmp_identifier) { should eq 0x0100 }
|
143
|
+
its(:icmp_sequence_number) { should eq 0x0001 }
|
144
|
+
its(:echo_data) { should eq 'abcdefghijklmnopqrstuvwabcdefghi' }
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with an invalid Icmp frame' do
|
148
|
+
let(:data) { [] }
|
149
|
+
|
150
|
+
it { expect { subject }.to raise_error(Pio::ParseError) }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
### Local variables:
|
156
|
+
### mode: Ruby
|
157
|
+
### coding: utf-8-unix
|
158
|
+
### indent-tabs-mode: nil
|
159
|
+
### End:
|