1//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "shill/arp_packet.h"
18
19#include <gtest/gtest.h>
20
21#include "shill/mock_log.h"
22
23using testing::_;
24using testing::HasSubstr;
25using testing::Test;
26
27namespace shill {
28
29namespace {
30const uint8_t kArpRequestV4[] =
31    { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01 };
32const uint8_t kArpRequestV6[] =
33    { 0x00, 0x01, 0x86, 0xdd, 0x06, 0x10, 0x00, 0x01 };
34const uint8_t kArpReplyV4[] =
35    { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02 };
36const uint8_t kArpReplyV6[] =
37    { 0x00, 0x01, 0x86, 0xdd, 0x06, 0x10, 0x00, 0x02 };
38const char kIPv4Address0[] = "192.168.0.1";
39const char kIPv4Address1[] = "10.0.12.13";
40const char kIPv6Address0[] = "fe80::1aa9:5ff:7ebf:14c5";
41const char kIPv6Address1[] = "1980:0:0:1000:1b02:1aa9:5ff:7ebf";
42const uint8_t kMACAddress0[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
43const uint8_t kMACAddress1[] = { 0x88, 0x87, 0x86, 0x85, 0x84, 0x83 };
44const uint8_t kInsertedByte[] = { 0x00 };
45const size_t kArpPaddingSizeV4 = 18;
46const size_t kArpPaddingSizeV6 = 0;
47}  // namespace
48
49class ArpPacketTest : public Test {
50 public:
51  ArpPacketTest()
52      : ipv4_address0_(IPAddress::kFamilyIPv4),
53        ipv4_address1_(IPAddress::kFamilyIPv4),
54        ipv6_address0_(IPAddress::kFamilyIPv6),
55        ipv6_address1_(IPAddress::kFamilyIPv6),
56        mac_address0_(kMACAddress0, arraysize(kMACAddress0)),
57        mac_address1_(kMACAddress1, arraysize(kMACAddress1)),
58        inserted_byte_(kInsertedByte, arraysize(kInsertedByte)) {}
59  virtual ~ArpPacketTest() {}
60
61  virtual void SetUp() {
62    EXPECT_TRUE(ipv4_address0_.SetAddressFromString(kIPv4Address0));
63    EXPECT_TRUE(ipv4_address1_.SetAddressFromString(kIPv4Address1));
64    EXPECT_TRUE(ipv6_address0_.SetAddressFromString(kIPv6Address0));
65    EXPECT_TRUE(ipv6_address1_.SetAddressFromString(kIPv6Address1));
66  }
67
68 protected:
69  IPAddress ipv4_address0_;
70  IPAddress ipv4_address1_;
71  IPAddress ipv6_address0_;
72  IPAddress ipv6_address1_;
73  ByteString mac_address0_;
74  ByteString mac_address1_;
75  ByteString inserted_byte_;
76  ArpPacket packet_;
77};
78
79TEST_F(ArpPacketTest, Constructor) {
80  EXPECT_FALSE(packet_.local_ip_address().IsValid());
81  EXPECT_FALSE(packet_.remote_ip_address().IsValid());
82  EXPECT_TRUE(packet_.local_mac_address().IsEmpty());
83  EXPECT_TRUE(packet_.remote_mac_address().IsEmpty());
84}
85
86TEST_F(ArpPacketTest, GettersAndSetters) {
87  packet_.set_local_ip_address(ipv4_address0_);
88  packet_.set_remote_ip_address(ipv6_address1_);
89  packet_.set_local_mac_address(mac_address0_);
90  packet_.set_remote_mac_address(mac_address1_);
91  EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
92  EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
93  EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
94  EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
95}
96
97TEST_F(ArpPacketTest, ParseTinyPacket) {
98  ScopedMockLog log;
99  EXPECT_CALL(log,
100      Log(logging::LOG_ERROR, _,
101          HasSubstr("too short to contain ARP header."))).Times(1);
102
103  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
104  arp_bytes.Resize(arp_bytes.GetLength() - 1);
105  EXPECT_FALSE(packet_.Parse(arp_bytes));
106}
107
108TEST_F(ArpPacketTest, ParseBadHRDType) {
109  ScopedMockLog log;
110  EXPECT_CALL(log,
111      Log(logging::LOG_ERROR, _,
112          HasSubstr("Packet is of unknown ARPHRD type 257"))).Times(1);
113
114  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
115  arp_bytes.GetData()[0] = 0x1;
116  EXPECT_FALSE(packet_.Parse(arp_bytes));
117}
118
119TEST_F(ArpPacketTest, ParseBadProtocol) {
120  ScopedMockLog log;
121  EXPECT_CALL(log,
122      Log(logging::LOG_ERROR, _,
123          HasSubstr("Packet has unknown protocol 2049"))).Times(1);
124
125  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
126  arp_bytes.GetData()[3] = 0x1;
127  EXPECT_FALSE(packet_.Parse(arp_bytes));
128}
129
130TEST_F(ArpPacketTest, ParseBadHardwareLength) {
131  ScopedMockLog log;
132  EXPECT_CALL(log,
133      Log(logging::LOG_ERROR, _,
134          HasSubstr("Packet has unexpected hardware address length"))).Times(1);
135
136  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
137  arp_bytes.GetData()[4] = 0x1;
138  EXPECT_FALSE(packet_.Parse(arp_bytes));
139}
140
141TEST_F(ArpPacketTest, ParseBadProtocolLength) {
142  ScopedMockLog log;
143  EXPECT_CALL(log,
144      Log(logging::LOG_ERROR, _,
145          HasSubstr("Packet has unexpected protocol address length"))).Times(1);
146
147  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
148  arp_bytes.GetData()[5] = 0x1;
149  EXPECT_FALSE(packet_.Parse(arp_bytes));
150}
151
152TEST_F(ArpPacketTest, ParseBadOpCode) {
153  ScopedMockLog log;
154  EXPECT_CALL(log,
155      Log(logging::LOG_ERROR, _,
156          HasSubstr("Packet is not an ARP reply or request but of type 258")))
157              .Times(1);
158
159  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
160  arp_bytes.GetData()[6] = 0x1;
161  EXPECT_FALSE(packet_.Parse(arp_bytes));
162}
163
164TEST_F(ArpPacketTest, ParseShortPacket) {
165  ScopedMockLog log;
166  EXPECT_CALL(log,
167      Log(logging::LOG_ERROR, _,
168          HasSubstr("is too small to contain entire ARP payload"))).Times(1);
169
170  ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
171  arp_bytes.Append(mac_address1_);
172  arp_bytes.Append(ipv6_address0_.address());
173  arp_bytes.Append(mac_address0_);
174  arp_bytes.Append(ipv6_address1_.address());
175  arp_bytes.Resize(arp_bytes.GetLength() - 1);
176  EXPECT_FALSE(packet_.Parse(arp_bytes));
177}
178
179TEST_F(ArpPacketTest, ParseIPv4) {
180  ByteString arp_bytes(kArpReplyV4, arraysize(kArpReplyV4));
181  arp_bytes.Append(mac_address0_);
182  arp_bytes.Append(ipv4_address0_.address());
183  arp_bytes.Append(mac_address1_);
184  arp_bytes.Append(ipv4_address1_.address());
185  EXPECT_TRUE(packet_.Parse(arp_bytes));
186  EXPECT_TRUE(packet_.IsReply());
187  EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
188  EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
189  EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
190  EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
191
192  // Parse should succeed with arbitrary trailing padding.
193  arp_bytes.Append(ByteString(1000));
194  EXPECT_TRUE(packet_.Parse(arp_bytes));
195}
196
197TEST_F(ArpPacketTest, ParseIPv6) {
198  ByteString arp_bytes(kArpReplyV6, arraysize(kArpReplyV6));
199  arp_bytes.Append(mac_address1_);
200  arp_bytes.Append(ipv6_address0_.address());
201  arp_bytes.Append(mac_address0_);
202  arp_bytes.Append(ipv6_address1_.address());
203  EXPECT_TRUE(packet_.Parse(arp_bytes));
204  EXPECT_TRUE(packet_.IsReply());
205  EXPECT_TRUE(ipv6_address0_.Equals(packet_.local_ip_address()));
206  EXPECT_TRUE(ipv6_address1_.Equals(packet_.remote_ip_address()));
207  EXPECT_TRUE(mac_address1_.Equals(packet_.local_mac_address()));
208  EXPECT_TRUE(mac_address0_.Equals(packet_.remote_mac_address()));
209}
210
211TEST_F(ArpPacketTest, ParseRequest) {
212  ByteString arp_bytes(kArpRequestV4, arraysize(kArpRequestV4));
213  arp_bytes.Append(mac_address0_);
214  arp_bytes.Append(ipv4_address0_.address());
215  arp_bytes.Append(mac_address1_);
216  arp_bytes.Append(ipv4_address1_.address());
217  EXPECT_TRUE(packet_.Parse(arp_bytes));
218  EXPECT_FALSE(packet_.IsReply());
219  EXPECT_TRUE(ipv4_address0_.Equals(packet_.local_ip_address()));
220  EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
221  EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
222  EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
223}
224
225TEST_F(ArpPacketTest, FormatRequestInvalidAddress) {
226  ScopedMockLog log;
227  EXPECT_CALL(log,
228      Log(logging::LOG_ERROR, _,
229          HasSubstr("Local or remote IP address is not valid"))).Times(3);
230
231  ByteString arp_bytes;
232  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
233  packet_.set_local_ip_address(ipv4_address0_);
234  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
235  packet_.set_local_ip_address(IPAddress(IPAddress::kFamilyUnknown));
236  packet_.set_remote_ip_address(ipv4_address0_);
237  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
238}
239
240TEST_F(ArpPacketTest, FormatRequestMismatchedAddresses) {
241  ScopedMockLog log;
242  EXPECT_CALL(log,
243      Log(logging::LOG_ERROR, _,
244          HasSubstr("IP address families do not match"))).Times(1);
245
246  ByteString arp_bytes;
247  packet_.set_local_ip_address(ipv4_address0_);
248  packet_.set_remote_ip_address(ipv6_address1_);
249  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
250}
251
252TEST_F(ArpPacketTest, FormatRequestBadMACAddressLength) {
253  ScopedMockLog log;
254  EXPECT_CALL(log,
255      Log(logging::LOG_ERROR, _,
256          HasSubstr("MAC address length is incorrect"))).Times(3);
257
258  ByteString arp_bytes;
259  packet_.set_local_ip_address(ipv4_address0_);
260  packet_.set_remote_ip_address(ipv4_address1_);
261  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
262  packet_.set_local_mac_address(mac_address0_);
263  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
264  packet_.set_local_mac_address(ByteString());
265  packet_.set_remote_mac_address(mac_address0_);
266  EXPECT_FALSE(packet_.FormatRequest(&arp_bytes));
267}
268
269TEST_F(ArpPacketTest, FormatRequestIPv4) {
270  ByteString arp_bytes;
271  packet_.set_local_ip_address(ipv4_address0_);
272  packet_.set_remote_ip_address(ipv4_address1_);
273  packet_.set_local_mac_address(mac_address0_);
274  packet_.set_remote_mac_address(mac_address1_);
275  EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
276
277  ByteString expected_bytes(kArpRequestV4, arraysize(kArpRequestV4));
278  expected_bytes.Append(mac_address0_);
279  expected_bytes.Append(ipv4_address0_.address());
280  expected_bytes.Append(mac_address1_);
281  expected_bytes.Append(ipv4_address1_.address());
282  expected_bytes.Append(ByteString(kArpPaddingSizeV4));
283  EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
284}
285
286TEST_F(ArpPacketTest, FormatRequestIPv6) {
287  ByteString arp_bytes;
288  packet_.set_local_ip_address(ipv6_address0_);
289  packet_.set_remote_ip_address(ipv6_address1_);
290  packet_.set_local_mac_address(mac_address1_);
291  packet_.set_remote_mac_address(mac_address0_);
292  EXPECT_TRUE(packet_.FormatRequest(&arp_bytes));
293
294  ByteString expected_bytes(kArpRequestV6, arraysize(kArpRequestV6));
295  expected_bytes.Append(mac_address1_);
296  expected_bytes.Append(ipv6_address0_.address());
297  expected_bytes.Append(mac_address0_);
298  expected_bytes.Append(ipv6_address1_.address());
299  expected_bytes.Append(ByteString(kArpPaddingSizeV6));
300  EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
301}
302
303}  // namespace shill
304