blob: 952bbd4ea490b5f280a5e1c156dffdb0b0104afb [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 {
18const uint8 kArpRequestV4[] =
19 { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01 };
20const uint8 kArpRequestV6[] =
21 { 0x00, 0x01, 0x86, 0xdd, 0x06, 0x10, 0x00, 0x01 };
22const uint8 kArpReplyV4[] =
23 { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02 };
24const uint8 kArpReplyV6[] =
25 { 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";
30const uint8 kMACAddress0[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
31const uint8 kMACAddress1[] = { 0x88, 0x87, 0x86, 0x85, 0x84, 0x83 };
32const uint8 kMACBroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
33const uint8 kInsertedByte[] = { 0x00 };
Paul Stewartac1328e2012-07-20 11:55:40 -070034const size_t kArpPaddingSizeV4 = 18;
35const size_t kArpPaddingSizeV6 = 0;
Paul Stewart91a5aac2012-07-20 11:55:40 -070036} // namespace {}
37
38class ArpPacketTest : public Test {
39 public:
40 ArpPacketTest()
41 : ipv4_address0_(IPAddress::kFamilyIPv4),
42 ipv4_address1_(IPAddress::kFamilyIPv4),
43 ipv6_address0_(IPAddress::kFamilyIPv6),
44 ipv6_address1_(IPAddress::kFamilyIPv6),
45 mac_address0_(kMACAddress0, arraysize(kMACAddress0)),
46 mac_address1_(kMACAddress1, arraysize(kMACAddress1)),
47 inserted_byte_(kInsertedByte, arraysize(kInsertedByte)) {}
48 virtual ~ArpPacketTest() {}
49
50 virtual void SetUp() {
51 EXPECT_TRUE(ipv4_address0_.SetAddressFromString(kIPv4Address0));
52 EXPECT_TRUE(ipv4_address1_.SetAddressFromString(kIPv4Address1));
53 EXPECT_TRUE(ipv6_address0_.SetAddressFromString(kIPv6Address0));
54 EXPECT_TRUE(ipv6_address1_.SetAddressFromString(kIPv6Address1));
55 }
56
57 protected:
58 IPAddress ipv4_address0_;
59 IPAddress ipv4_address1_;
60 IPAddress ipv6_address0_;
61 IPAddress ipv6_address1_;
62 ByteString mac_address0_;
63 ByteString mac_address1_;
64 ByteString inserted_byte_;
65 ArpPacket packet_;
66};
67
68TEST_F(ArpPacketTest, Constructor) {
69 EXPECT_FALSE(packet_.local_ip_address().IsValid());
70 EXPECT_FALSE(packet_.remote_ip_address().IsValid());
71 EXPECT_TRUE(packet_.local_mac_address().IsEmpty());
72 EXPECT_TRUE(packet_.remote_mac_address().IsEmpty());
73}
74
75TEST_F(ArpPacketTest, GettersAndSetters) {
76 packet_.set_local_ip_address(ipv4_address0_);
77 packet_.set_remote_ip_address(ipv6_address1_);
78 packet_.set_local_mac_address(mac_address0_);
79 packet_.set_remote_mac_address(mac_address1_);
80 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
81 EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
82 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
83 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
84}
85
86TEST_F(ArpPacketTest, ParseReplyTinyPacket) {
87 ScopedMockLog log;
88 EXPECT_CALL(log,
89 Log(logging::LOG_ERROR, _,
90 HasSubstr("too short to contain ARP header."))).Times(1);
91
92 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
93 arp_bytes.Resize(arp_bytes.GetLength() - 1);
94 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
95}
96
97TEST_F(ArpPacketTest, ParseReplyBadHRDType) {
98 ScopedMockLog log;
99 EXPECT_CALL(log,
100 Log(logging::LOG_ERROR, _,
101 HasSubstr("Packet is of unknown ARPHRD type 257"))).Times(1);
102
103 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
104 arp_bytes.GetData()[0] = 0x1;
105 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
106}
107
108TEST_F(ArpPacketTest, ParseReplyBadProtocol) {
109 ScopedMockLog log;
110 EXPECT_CALL(log,
111 Log(logging::LOG_ERROR, _,
112 HasSubstr("Packet has unknown protocol 2049"))).Times(1);
113
114 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
115 arp_bytes.GetData()[3] = 0x1;
116 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
117}
118
119TEST_F(ArpPacketTest, ParseReplyBadHardwareLength) {
120 ScopedMockLog log;
121 EXPECT_CALL(log,
122 Log(logging::LOG_ERROR, _,
123 HasSubstr("Packet has unexpected hardware address length"))).Times(1);
124
125 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
126 arp_bytes.GetData()[4] = 0x1;
127 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
128}
129
130TEST_F(ArpPacketTest, ParseReplyBadProtocolLength) {
131 ScopedMockLog log;
132 EXPECT_CALL(log,
133 Log(logging::LOG_ERROR, _,
134 HasSubstr("Packet has unexpected protocol address length"))).Times(1);
135
136 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
137 arp_bytes.GetData()[5] = 0x1;
138 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
139}
140
141TEST_F(ArpPacketTest, ParseReplyBadOpCode) {
142 ScopedMockLog log;
143 EXPECT_CALL(log,
144 Log(logging::LOG_ERROR, _,
145 HasSubstr("Packet is not an ARP reply but of type 258"))).Times(1);
146
147 ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
148 arp_bytes.GetData()[6] = 0x1;
149 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
150}
151
152TEST_F(ArpPacketTest, ParseReplyShortPacket) {
153 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);
164 EXPECT_FALSE(packet_.ParseReply(arp_bytes));
165}
166
167TEST_F(ArpPacketTest, ParseReplyIPv4) {
168 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());
173 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
174 EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
175 EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
176 EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
177 EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
Paul Stewartac1328e2012-07-20 11:55:40 -0700178
179 // Parse should succeed with arbitrary trailing padding.
180 arp_bytes.Append(ByteString(1000));
181 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700182}
183
184TEST_F(ArpPacketTest, ParseReplyIPv6) {
185 ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
186 arp_bytes.Append(mac_address1_);
187 arp_bytes.Append(ipv6_address0_.address());
188 arp_bytes.Append(mac_address0_);
189 arp_bytes.Append(ipv6_address1_.address());
190 EXPECT_TRUE(packet_.ParseReply(arp_bytes));
191 EXPECT_TRUE(ipv6_address0_.Equals(packet_.local_ip_address()));
192 EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
193 EXPECT_TRUE(mac_address1_.Equals(packet_.local_mac_address()));
194 EXPECT_TRUE(mac_address0_.Equals(packet_.remote_mac_address()));
195}
196
197TEST_F(ArpPacketTest, FormatRequestInvalidAddress) {
198 ScopedMockLog log;
199 EXPECT_CALL(log,
200 Log(logging::LOG_ERROR, _,
201 HasSubstr("Local or remote IP address is not valid"))).Times(3);
202
203 ByteString arp_bytes;
204 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
205 packet_.set_local_ip_address(ipv4_address0_);
206 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
207 packet_.set_local_ip_address(IPAddress(IPAddress::kFamilyUnknown));
208 packet_.set_remote_ip_address(ipv4_address0_);
209 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
210}
211
212TEST_F(ArpPacketTest, FormatRequestMismatchedAddresses) {
213 ScopedMockLog log;
214 EXPECT_CALL(log,
215 Log(logging::LOG_ERROR, _,
216 HasSubstr("IP address families do not match"))).Times(1);
217
218 ByteString arp_bytes;
219 packet_.set_local_ip_address(ipv4_address0_);
220 packet_.set_remote_ip_address(ipv6_address1_);
221 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
222}
223
224TEST_F(ArpPacketTest, FormatRequestBadMACAddressLength) {
225 ScopedMockLog log;
226 EXPECT_CALL(log,
227 Log(logging::LOG_ERROR, _,
228 HasSubstr("MAC address length is incorrect"))).Times(3);
229
230 ByteString arp_bytes;
231 packet_.set_local_ip_address(ipv4_address0_);
232 packet_.set_remote_ip_address(ipv4_address1_);
233 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
234 packet_.set_local_mac_address(mac_address0_);
235 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
236 packet_.set_local_mac_address(ByteString());
237 packet_.set_remote_mac_address(mac_address0_);
238 EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
239}
240
241TEST_F(ArpPacketTest, FormatRequestIPv4) {
242 ByteString arp_bytes;
243 packet_.set_local_ip_address(ipv4_address0_);
244 packet_.set_remote_ip_address(ipv4_address1_);
245 packet_.set_local_mac_address(mac_address0_);
246 packet_.set_remote_mac_address(mac_address1_);
247 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
248
249 ByteString expected_bytes(kArpRequestV4, arraysize(kArpRequestV4));
250 expected_bytes.Append(mac_address0_);
251 expected_bytes.Append(ipv4_address0_.address());
252 expected_bytes.Append(mac_address1_);
253 expected_bytes.Append(ipv4_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700254 expected_bytes.Append(ByteString(kArpPaddingSizeV4));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700255 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
256}
257
258TEST_F(ArpPacketTest, FormatRequestIPv6) {
259 ByteString arp_bytes;
260 packet_.set_local_ip_address(ipv6_address0_);
261 packet_.set_remote_ip_address(ipv6_address1_);
262 packet_.set_local_mac_address(mac_address1_);
263 packet_.set_remote_mac_address(mac_address0_);
264 EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
265
266 ByteString expected_bytes(kArpRequestV6, arraysize(kArpRequestV6));
267 expected_bytes.Append(mac_address1_);
268 expected_bytes.Append(ipv6_address0_.address());
269 expected_bytes.Append(mac_address0_);
270 expected_bytes.Append(ipv6_address1_.address());
Paul Stewartac1328e2012-07-20 11:55:40 -0700271 expected_bytes.Append(ByteString(kArpPaddingSizeV6));
Paul Stewart91a5aac2012-07-20 11:55:40 -0700272 EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
273}
274
275} // namespace shill