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
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:
|