blob: 94f5005cbbe832fed463cb8181359712f83e892c [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
Paul Stewart417e5f02014-10-09 08:52:35 -070085TEST_F(ArpPacketTest, ParseTinyPacket) {
Paul Stewart91a5aac2012-07-20 11:55:40 -070086 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);
Paul Stewart417e5f02014-10-09 08:52:35 -070093 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -070094}
95
Paul Stewart417e5f02014-10-09 08:52:35 -070096TEST_F(ArpPacketTest, ParseBadHRDType) {
Paul Stewart91a5aac2012-07-20 11:55:40 -070097 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;
Paul Stewart417e5f02014-10-09 08:52:35 -0700104 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700105}
106
Paul Stewart417e5f02014-10-09 08:52:35 -0700107TEST_F(ArpPacketTest, ParseBadProtocol) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700108 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;
Paul Stewart417e5f02014-10-09 08:52:35 -0700115 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700116}
117
Paul Stewart417e5f02014-10-09 08:52:35 -0700118TEST_F(ArpPacketTest, ParseBadHardwareLength) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700119 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;
Paul Stewart417e5f02014-10-09 08:52:35 -0700126 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700127}
128
Paul Stewart417e5f02014-10-09 08:52:35 -0700129TEST_F(ArpPacketTest, ParseBadProtocolLength) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700130 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;
Paul Stewart417e5f02014-10-09 08:52:35 -0700137 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700138}
139
Paul Stewart417e5f02014-10-09 08:52:35 -0700140TEST_F(ArpPacketTest, ParseBadOpCode) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700141 ScopedMockLog log;
142 EXPECT_CALL(log,
143 Log(logging::LOG_ERROR, _,
Paul Stewart417e5f02014-10-09 08:52:35 -0700144 HasSubstr("Packet is not an ARP reply or request but of type 258")))
145 .Times(1);
Paul Stewart91a5aac2012-07-20 11:55:40 -0700146
147 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
148 arp_bytes.GetData()[6] = 0x1;
Paul Stewart417e5f02014-10-09 08:52:35 -0700149 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700150}
151
Paul Stewart417e5f02014-10-09 08:52:35 -0700152TEST_F(ArpPacketTest, ParseShortPacket) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700153 ScopedMockLog log;
154 EXPECT_CALL(log,
155 Log(logging::LOG_ERROR, _,
156 HasSubstr("is too small to contain entire ARP payload"))).Times(1);
157
158 ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
159 arp_bytes.Append(mac_address1_);
160 arp_bytes.Append(ipv6_address0_.address());
161 arp_bytes.Append(mac_address0_);
162 arp_bytes.Append(ipv6_address1_.address());
163 arp_bytes.Resize(arp_bytes.GetLength() - 1);
Paul Stewart417e5f02014-10-09 08:52:35 -0700164 EXPECT_FALSE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700165}
166
Paul Stewart417e5f02014-10-09 08:52:35 -0700167TEST_F(ArpPacketTest, ParseIPv4) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700168 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
169 arp_bytes.Append(mac_address0_);
170 arp_bytes.Append(ipv4_address0_.address());
171 arp_bytes.Append(mac_address1_);
172 arp_bytes.Append(ipv4_address1_.address());
Paul Stewart417e5f02014-10-09 08:52:35 -0700173 EXPECT_TRUE(packet_.Parse(arp_bytes));
174 EXPECT_TRUE(packet_.IsReply());
Paul Stewart91a5aac2012-07-20 11:55:40 -0700175 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
176 EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
177 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
178 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
Paul Stewartac1328e2012-07-20 11:55:40 -0700179
180 // Parse should succeed with arbitrary trailing padding.
181 arp_bytes.Append(ByteString(1000));
Paul Stewart417e5f02014-10-09 08:52:35 -0700182 EXPECT_TRUE(packet_.Parse(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700183}
184
Paul Stewart417e5f02014-10-09 08:52:35 -0700185TEST_F(ArpPacketTest, ParseIPv6) {
Paul Stewart91a5aac2012-07-20 11:55:40 -0700186 ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
187 arp_bytes.Append(mac_address1_);
188 arp_bytes.Append(ipv6_address0_.address());
189 arp_bytes.Append(mac_address0_);
190 arp_bytes.Append(ipv6_address1_.address());
Paul Stewart417e5f02014-10-09 08:52:35 -0700191 EXPECT_TRUE(packet_.Parse(arp_bytes));
192 EXPECT_TRUE(packet_.IsReply());
Paul Stewart91a5aac2012-07-20 11:55:40 -0700193 EXPECT_TRUE(ipv6_address0_.Equals(packet_.local_ip_address()));
194 EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
195 EXPECT_TRUE(mac_address1_.Equals(packet_.local_mac_address()));
196 EXPECT_TRUE(mac_address0_.Equals(packet_.remote_mac_address()));
197}
198
Paul Stewart417e5f02014-10-09 08:52:35 -0700199TEST_F(ArpPacketTest, ParseRequest) {
200 ByteString arp_bytes(kArpRequestV4, arraysize(kArpRequestV4));
201 arp_bytes.Append(mac_address0_);
202 arp_bytes.Append(ipv4_address0_.address());
203 arp_bytes.Append(mac_address1_);
204 arp_bytes.Append(ipv4_address1_.address());
205 EXPECT_TRUE(packet_.Parse(arp_bytes));
206 EXPECT_FALSE(packet_.IsReply());
207 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
208 EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
209 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
210 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
211}
212
Paul Stewart91a5aac2012-07-20 11:55:40 -0700213TEST_F(ArpPacketTest, FormatRequestInvalidAddress) {
214 ScopedMockLog log;
215 EXPECT_CALL(log,
216 Log(logging::LOG_ERROR, _,
217 HasSubstr("Local or remote IP address is not valid"))).Times(3);
218
219 ByteString arp_bytes;
220 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
221 packet_.set_local_ip_address(ipv4_address0_);
222 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
223 packet_.set_local_ip_address(IPAddress(IPAddress::kFamilyUnknown));
224 packet_.set_remote_ip_address(ipv4_address0_);
225 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
226}
227
228TEST_F(ArpPacketTest, FormatRequestMismatchedAddresses) {
229 ScopedMockLog log;
230 EXPECT_CALL(log,
231 Log(logging::LOG_ERROR, _,
232 HasSubstr("IP address families do not match"))).Times(1);
233
234 ByteString arp_bytes;
235 packet_.set_local_ip_address(ipv4_address0_);
236 packet_.set_remote_ip_address(ipv6_address1_);
237 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
238}
239
240TEST_F(ArpPacketTest, FormatRequestBadMACAddressLength) {
241 ScopedMockLog log;
242 EXPECT_CALL(log,
243 Log(logging::LOG_ERROR, _,
244 HasSubstr("MAC address length is incorrect"))).Times(3);
245
246 ByteString arp_bytes;
247 packet_.set_local_ip_address(ipv4_address0_);
248 packet_.set_remote_ip_address(ipv4_address1_);
249 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
250 packet_.set_local_mac_address(mac_address0_);
251 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
252 packet_.set_local_mac_address(ByteString());
253 packet_.set_remote_mac_address(mac_address0_);
254 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
255}
256
257TEST_F(ArpPacketTest, FormatRequestIPv4) {
258 ByteString arp_bytes;
259 packet_.set_local_ip_address(ipv4_address0_);
260 packet_.set_remote_ip_address(ipv4_address1_);
261 packet_.set_local_mac_address(mac_address0_);
262 packet_.set_remote_mac_address(mac_address1_);
263 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
264
265 ByteString expected_bytes(kArpRequestV4, arraysize(kArpRequestV4));
266 expected_bytes.Append(mac_address0_);
267 expected_bytes.Append(ipv4_address0_.address());
268 expected_bytes.Append(mac_address1_);
269 expected_bytes.Append(ipv4_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700270 expected_bytes.Append(ByteString(kArpPaddingSizeV4));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700271 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
272}
273
274TEST_F(ArpPacketTest, FormatRequestIPv6) {
275 ByteString arp_bytes;
276 packet_.set_local_ip_address(ipv6_address0_);
277 packet_.set_remote_ip_address(ipv6_address1_);
278 packet_.set_local_mac_address(mac_address1_);
279 packet_.set_remote_mac_address(mac_address0_);
280 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
281
282 ByteString expected_bytes(kArpRequestV6, arraysize(kArpRequestV6));
283 expected_bytes.Append(mac_address1_);
284 expected_bytes.Append(ipv6_address0_.address());
285 expected_bytes.Append(mac_address0_);
286 expected_bytes.Append(ipv6_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700287 expected_bytes.Append(ByteString(kArpPaddingSizeV6));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700288 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
289}
290
291} // namespace shill