blob: 11141a8f43b9ab46ae6a096d3523d9dd3437ff96 [file] [log] [blame]
Paul Stewart91a5aac2012-07-20 11:55:40 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/arp_packet.h"
6
7#include <gtest/gtest.h>
8
9#include "shill/mock_log.h"
10
11using testing::_;
12using testing::HasSubstr;
13using testing::Test;
14
15namespace shill {
16
17namespace {
Ben Chan7fab8972014-08-10 17:14:46 -070018const uint8_t kArpRequestV4[] =
Paul Stewart91a5aac2012-07-20 11:55:40 -070019 { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01 };
Ben Chan7fab8972014-08-10 17:14:46 -070020const uint8_t kArpRequestV6[] =
Paul Stewart91a5aac2012-07-20 11:55:40 -070021 { 0x00, 0x01, 0x86, 0xdd, 0x06, 0x10, 0x00, 0x01 };
Ben Chan7fab8972014-08-10 17:14:46 -070022const uint8_t kArpReplyV4[] =
Paul Stewart91a5aac2012-07-20 11:55:40 -070023 { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02 };
Ben Chan7fab8972014-08-10 17:14:46 -070024const uint8_t kArpReplyV6[] =
Paul Stewart91a5aac2012-07-20 11:55:40 -070025 { 0x00, 0x01, 0x86, 0xdd, 0x06, 0x10, 0x00, 0x02 };
26const char kIPv4Address0[] = "192.168.0.1";
27const char kIPv4Address1[] = "10.0.12.13";
28const char kIPv6Address0[] = "fe80::1aa9:5ff:7ebf:14c5";
29const char kIPv6Address1[] = "1980:0:0:1000:1b02:1aa9:5ff:7ebf";
Ben Chan7fab8972014-08-10 17:14:46 -070030const uint8_t kMACAddress0[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
31const uint8_t kMACAddress1[] = { 0x88, 0x87, 0x86, 0x85, 0x84, 0x83 };
32const uint8_t kInsertedByte[] = { 0x00 };
Paul Stewartac1328e2012-07-20 11:55:40 -070033const size_t kArpPaddingSizeV4 = 18;
34const size_t kArpPaddingSizeV6 = 0;
Alex Vakulenko8a532292014-06-16 17:18:44 -070035} // namespace
Paul Stewart91a5aac2012-07-20 11:55:40 -070036
37class ArpPacketTest : public Test {
38 public:
39 ArpPacketTest()
40 : ipv4_address0_(IPAddress::kFamilyIPv4),
41 ipv4_address1_(IPAddress::kFamilyIPv4),
42 ipv6_address0_(IPAddress::kFamilyIPv6),
43 ipv6_address1_(IPAddress::kFamilyIPv6),
44 mac_address0_(kMACAddress0, arraysize(kMACAddress0)),
45 mac_address1_(kMACAddress1, arraysize(kMACAddress1)),
46 inserted_byte_(kInsertedByte, arraysize(kInsertedByte)) {}
47 virtual ~ArpPacketTest() {}
48
49 virtual void SetUp() {
50 EXPECT_TRUE(ipv4_address0_.SetAddressFromString(kIPv4Address0));
51 EXPECT_TRUE(ipv4_address1_.SetAddressFromString(kIPv4Address1));
52 EXPECT_TRUE(ipv6_address0_.SetAddressFromString(kIPv6Address0));
53 EXPECT_TRUE(ipv6_address1_.SetAddressFromString(kIPv6Address1));
54 }
55
56 protected:
57 IPAddress ipv4_address0_;
58 IPAddress ipv4_address1_;
59 IPAddress ipv6_address0_;
60 IPAddress ipv6_address1_;
61 ByteString mac_address0_;
62 ByteString mac_address1_;
63 ByteString inserted_byte_;
64 ArpPacket packet_;
65};
66
67TEST_F(ArpPacketTest, Constructor) {
68 EXPECT_FALSE(packet_.local_ip_address().IsValid());
69 EXPECT_FALSE(packet_.remote_ip_address().IsValid());
70 EXPECT_TRUE(packet_.local_mac_address().IsEmpty());
71 EXPECT_TRUE(packet_.remote_mac_address().IsEmpty());
72}
73
74TEST_F(ArpPacketTest, GettersAndSetters) {
75 packet_.set_local_ip_address(ipv4_address0_);
76 packet_.set_remote_ip_address(ipv6_address1_);
77 packet_.set_local_mac_address(mac_address0_);
78 packet_.set_remote_mac_address(mac_address1_);
79 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
80 EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
81 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
82 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
83}
84
85TEST_F(ArpPacketTest, ParseReplyTinyPacket) {
86 ScopedMockLog log;
87 EXPECT_CALL(log,
88 Log(logging::LOG_ERROR, _,
89 HasSubstr("too short to contain ARP header."))).Times(1);
90
91 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
92 arp_bytes.Resize(arp_bytes.GetLength() - 1);
93 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
94}
95
96TEST_F(ArpPacketTest, ParseReplyBadHRDType) {
97 ScopedMockLog log;
98 EXPECT_CALL(log,
99 Log(logging::LOG_ERROR, _,
100 HasSubstr("Packet is of unknown ARPHRD type 257"))).Times(1);
101
102 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
103 arp_bytes.GetData()[0] = 0x1;
104 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
105}
106
107TEST_F(ArpPacketTest, ParseReplyBadProtocol) {
108 ScopedMockLog log;
109 EXPECT_CALL(log,
110 Log(logging::LOG_ERROR, _,
111 HasSubstr("Packet has unknown protocol 2049"))).Times(1);
112
113 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
114 arp_bytes.GetData()[3] = 0x1;
115 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
116}
117
118TEST_F(ArpPacketTest, ParseReplyBadHardwareLength) {
119 ScopedMockLog log;
120 EXPECT_CALL(log,
121 Log(logging::LOG_ERROR, _,
122 HasSubstr("Packet has unexpected hardware address length"))).Times(1);
123
124 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
125 arp_bytes.GetData()[4] = 0x1;
126 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
127}
128
129TEST_F(ArpPacketTest, ParseReplyBadProtocolLength) {
130 ScopedMockLog log;
131 EXPECT_CALL(log,
132 Log(logging::LOG_ERROR, _,
133 HasSubstr("Packet has unexpected protocol address length"))).Times(1);
134
135 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
136 arp_bytes.GetData()[5] = 0x1;
137 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
138}
139
140TEST_F(ArpPacketTest, ParseReplyBadOpCode) {
141 ScopedMockLog log;
142 EXPECT_CALL(log,
143 Log(logging::LOG_ERROR, _,
144 HasSubstr("Packet is not an ARP reply but of type 258"))).Times(1);
145
146 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
147 arp_bytes.GetData()[6] = 0x1;
148 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
149}
150
151TEST_F(ArpPacketTest, ParseReplyShortPacket) {
152 ScopedMockLog log;
153 EXPECT_CALL(log,
154 Log(logging::LOG_ERROR, _,
155 HasSubstr("is too small to contain entire ARP payload"))).Times(1);
156
157 ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
158 arp_bytes.Append(mac_address1_);
159 arp_bytes.Append(ipv6_address0_.address());
160 arp_bytes.Append(mac_address0_);
161 arp_bytes.Append(ipv6_address1_.address());
162 arp_bytes.Resize(arp_bytes.GetLength() - 1);
163 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
164}
165
166TEST_F(ArpPacketTest, ParseReplyIPv4) {
167 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
168 arp_bytes.Append(mac_address0_);
169 arp_bytes.Append(ipv4_address0_.address());
170 arp_bytes.Append(mac_address1_);
171 arp_bytes.Append(ipv4_address1_.address());
172 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
173 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
174 EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
175 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
176 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
Paul Stewartac1328e2012-07-20 11:55:40 -0700177
178 // Parse should succeed with arbitrary trailing padding.
179 arp_bytes.Append(ByteString(1000));
180 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700181}
182
183TEST_F(ArpPacketTest, ParseReplyIPv6) {
184 ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
185 arp_bytes.Append(mac_address1_);
186 arp_bytes.Append(ipv6_address0_.address());
187 arp_bytes.Append(mac_address0_);
188 arp_bytes.Append(ipv6_address1_.address());
189 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
190 EXPECT_TRUE(ipv6_address0_.Equals(packet_.local_ip_address()));
191 EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
192 EXPECT_TRUE(mac_address1_.Equals(packet_.local_mac_address()));
193 EXPECT_TRUE(mac_address0_.Equals(packet_.remote_mac_address()));
194}
195
196TEST_F(ArpPacketTest, FormatRequestInvalidAddress) {
197 ScopedMockLog log;
198 EXPECT_CALL(log,
199 Log(logging::LOG_ERROR, _,
200 HasSubstr("Local or remote IP address is not valid"))).Times(3);
201
202 ByteString arp_bytes;
203 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
204 packet_.set_local_ip_address(ipv4_address0_);
205 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
206 packet_.set_local_ip_address(IPAddress(IPAddress::kFamilyUnknown));
207 packet_.set_remote_ip_address(ipv4_address0_);
208 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
209}
210
211TEST_F(ArpPacketTest, FormatRequestMismatchedAddresses) {
212 ScopedMockLog log;
213 EXPECT_CALL(log,
214 Log(logging::LOG_ERROR, _,
215 HasSubstr("IP address families do not match"))).Times(1);
216
217 ByteString arp_bytes;
218 packet_.set_local_ip_address(ipv4_address0_);
219 packet_.set_remote_ip_address(ipv6_address1_);
220 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
221}
222
223TEST_F(ArpPacketTest, FormatRequestBadMACAddressLength) {
224 ScopedMockLog log;
225 EXPECT_CALL(log,
226 Log(logging::LOG_ERROR, _,
227 HasSubstr("MAC address length is incorrect"))).Times(3);
228
229 ByteString arp_bytes;
230 packet_.set_local_ip_address(ipv4_address0_);
231 packet_.set_remote_ip_address(ipv4_address1_);
232 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
233 packet_.set_local_mac_address(mac_address0_);
234 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
235 packet_.set_local_mac_address(ByteString());
236 packet_.set_remote_mac_address(mac_address0_);
237 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
238}
239
240TEST_F(ArpPacketTest, FormatRequestIPv4) {
241 ByteString arp_bytes;
242 packet_.set_local_ip_address(ipv4_address0_);
243 packet_.set_remote_ip_address(ipv4_address1_);
244 packet_.set_local_mac_address(mac_address0_);
245 packet_.set_remote_mac_address(mac_address1_);
246 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
247
248 ByteString expected_bytes(kArpRequestV4, arraysize(kArpRequestV4));
249 expected_bytes.Append(mac_address0_);
250 expected_bytes.Append(ipv4_address0_.address());
251 expected_bytes.Append(mac_address1_);
252 expected_bytes.Append(ipv4_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700253 expected_bytes.Append(ByteString(kArpPaddingSizeV4));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700254 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
255}
256
257TEST_F(ArpPacketTest, FormatRequestIPv6) {
258 ByteString arp_bytes;
259 packet_.set_local_ip_address(ipv6_address0_);
260 packet_.set_remote_ip_address(ipv6_address1_);
261 packet_.set_local_mac_address(mac_address1_);
262 packet_.set_remote_mac_address(mac_address0_);
263 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
264
265 ByteString expected_bytes(kArpRequestV6, arraysize(kArpRequestV6));
266 expected_bytes.Append(mac_address1_);
267 expected_bytes.Append(ipv6_address0_.address());
268 expected_bytes.Append(mac_address0_);
269 expected_bytes.Append(ipv6_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700270 expected_bytes.Append(ByteString(kArpPaddingSizeV6));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700271 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
272}
273
274} // namespace shill