1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
16ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
17ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include "shill/arp_client.h"
18ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
19ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include <linux/if_packet.h>
20ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include <net/ethernet.h>
21ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include <net/if_arp.h>
22ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include <netinet/in.h>
23ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
24ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include <gtest/gtest.h>
25ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
26ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include "shill/arp_packet.h"
27ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart#include "shill/mock_log.h"
288d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h"
298d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
30ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
31ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::_;
32ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::AnyNumber;
33ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::HasSubstr;
34ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::InSequence;
35ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::Invoke;
36ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::Mock;
37ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::Return;
38ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::StrictMock;
39ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartusing testing::Test;
40ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
41ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartnamespace shill {
42ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
43ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartclass ArpClientTest : public Test {
44ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart public:
45ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ArpClientTest() : client_(kInterfaceIndex) {}
46ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  virtual ~ArpClientTest() {}
47ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
48ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  virtual void SetUp() {
49ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    sockets_ = new StrictMock<MockSockets>();
50ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    // Passes ownership.
51ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    client_.sockets_.reset(sockets_);
52ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    memset(&recvfrom_sender_, 0, sizeof(recvfrom_sender_));
53ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  }
54ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
55ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  virtual void TearDown() {
56ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    if (GetSocket() == kSocketFD) {
57ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      EXPECT_CALL(*sockets_, Close(kSocketFD));
58ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      client_.Stop();
59ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    }
60ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  }
61ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
623b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  ssize_t SimulateRecvFrom(int sockfd, void* buf, size_t len, int flags,
633b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                           struct sockaddr* src_addr, socklen_t* addrlen);
64ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
65ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart protected:
66ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  static const int kInterfaceIndex;
67ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  static const int kSocketFD;
68ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  static const char kLocalIPAddress[];
697fab89734d88724a288e96a9996b15548c5294c7Ben Chan  static const uint8_t kLocalMACAddress[];
70ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  static const char kRemoteIPAddress[];
717fab89734d88724a288e96a9996b15548c5294c7Ben Chan  static const uint8_t kRemoteMACAddress[];
72ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  static const int kArpOpOffset;
73ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
74417e5f079a1ccbc068c67f9cbf34f13c40330abcPaul Stewart  bool CreateSocket() { return client_.CreateSocket(ARPOP_REPLY); }
75ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  int GetInterfaceIndex() { return client_.interface_index_; }
76ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  size_t GetMaxArpPacketLength() { return ArpClient::kMaxArpPacketLength; }
77ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  int GetSocket() { return client_.socket_; }
783b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void SetupValidPacket(ArpPacket* packet);
79ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  void StartClient() { StartClientWithFD(kSocketFD); }
80ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  void StartClientWithFD(int fd);
81ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
82ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  // Owned by ArpClient, and tracked here only for mocks.
833b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockSockets* sockets_;
84ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ArpClient client_;
85ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString recvfrom_reply_data_;
86ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  sockaddr_ll recvfrom_sender_;
87ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart};
88ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
89ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
90ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartconst int ArpClientTest::kInterfaceIndex = 123;
91ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartconst int ArpClientTest::kSocketFD = 456;
92ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartconst char ArpClientTest::kLocalIPAddress[] = "10.0.1.1";
937fab89734d88724a288e96a9996b15548c5294c7Ben Chanconst uint8_t ArpClientTest::kLocalMACAddress[] = { 0, 1, 2, 3, 4, 5 };
94ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartconst char ArpClientTest::kRemoteIPAddress[] = "10.0.1.2";
957fab89734d88724a288e96a9996b15548c5294c7Ben Chanconst uint8_t ArpClientTest::kRemoteMACAddress[] = { 6, 7, 8, 9, 10, 11 };
96ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartconst int ArpClientTest::kArpOpOffset = 7;
97ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
98ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
99ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartMATCHER_P2(IsLinkAddress, interface_index, destination_mac, "") {
1003b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct sockaddr_ll* socket_address =
1013b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      reinterpret_cast<const struct sockaddr_ll*>(arg);
102ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString socket_mac(
1033b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      reinterpret_cast<const unsigned char*>(&socket_address->sll_addr),
104ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      destination_mac.GetLength());
105ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  return socket_address->sll_family == AF_PACKET &&
106ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      socket_address->sll_protocol == htons(ETHERTYPE_ARP) &&
107ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      socket_address->sll_ifindex == interface_index &&
108ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      destination_mac.Equals(socket_mac);
109ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
110ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
111ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartMATCHER_P(IsByteData, byte_data, "") {
1123b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  return ByteString(reinterpret_cast<const unsigned char*>(arg),
113ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                    byte_data.GetLength()).Equals(byte_data);
114ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
115ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
1163b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartvoid ArpClientTest::SetupValidPacket(ArpPacket* packet) {
117ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  IPAddress local_ip(IPAddress::kFamilyIPv4);
118ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_TRUE(local_ip.SetAddressFromString(kLocalIPAddress));
119ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  packet->set_local_ip_address(local_ip);
120ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  IPAddress remote_ip(IPAddress::kFamilyIPv4);
121ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_TRUE(remote_ip.SetAddressFromString(kRemoteIPAddress));
122ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  packet->set_remote_ip_address(remote_ip);
123ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString local_mac(kLocalMACAddress, arraysize(kLocalMACAddress));
124ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  packet->set_local_mac_address(local_mac);
125ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString remote_mac(kRemoteMACAddress, arraysize(kRemoteMACAddress));
126ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  packet->set_remote_mac_address(remote_mac);
127ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
128ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
1293b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartssize_t ArpClientTest::SimulateRecvFrom(int sockfd, void* buf, size_t len,
1303b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                        int flags, struct sockaddr* src_addr,
1313b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                        socklen_t* addrlen) {
132ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  memcpy(buf, recvfrom_reply_data_.GetConstData(),
133ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart         recvfrom_reply_data_.GetLength());
134ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  memcpy(src_addr, &recvfrom_sender_, sizeof(recvfrom_sender_));
135ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  return recvfrom_reply_data_.GetLength();
136ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
137ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
138ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewartvoid ArpClientTest::StartClientWithFD(int fd) {
139ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Socket(PF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_ARP)))
140ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(fd));
141ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, AttachFilter(fd, _)).WillOnce(Return(0));
142ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, SetNonBlocking(fd)).WillOnce(Return(0));
143ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Bind(fd,
144ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                              IsLinkAddress(kInterfaceIndex, ByteString()),
145ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                              sizeof(sockaddr_ll))).WillOnce(Return(0));
146ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_TRUE(CreateSocket());
147ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_EQ(fd, client_.socket_);
148ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
149ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
150ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, Constructor) {
151ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_EQ(kInterfaceIndex, GetInterfaceIndex());
152ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_EQ(-1, GetSocket());
153ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
154ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
155ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, SocketOpenFail) {
156ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ScopedMockLog log;
157ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(log,
158ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      Log(logging::LOG_ERROR, _,
159ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart          HasSubstr("Could not create ARP socket"))).Times(1);
160ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
161ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Socket(PF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_ARP)))
162ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(-1));
163ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_FALSE(CreateSocket());
164ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
165ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
166ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, SocketFilterFail) {
167ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ScopedMockLog log;
168ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(log,
169ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      Log(logging::LOG_ERROR, _,
170ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart          HasSubstr("Could not attach packet filter"))).Times(1);
171ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
172ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(kSocketFD));
173ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, AttachFilter(kSocketFD, _)).WillOnce(Return(-1));
174ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_FALSE(CreateSocket());
175ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
176ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
177ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, SocketNonBlockingFail) {
178ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ScopedMockLog log;
179ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(log,
180ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      Log(logging::LOG_ERROR, _,
181ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart          HasSubstr("Could not set socket to be non-blocking"))).Times(1);
182ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
183ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(kSocketFD));
184ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, AttachFilter(kSocketFD, _)).WillOnce(Return(0));
185ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, SetNonBlocking(kSocketFD)).WillOnce(Return(-1));
186ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_FALSE(CreateSocket());
187ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
188ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
189ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, SocketBindFail) {
190ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ScopedMockLog log;
191ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(log,
192ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      Log(logging::LOG_ERROR, _,
193ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart          HasSubstr("Could not bind socket to interface"))).Times(1);
194ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
195ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(kSocketFD));
196ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, AttachFilter(kSocketFD, _)).WillOnce(Return(0));
197ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, SetNonBlocking(kSocketFD)).WillOnce(Return(0));
198ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Bind(kSocketFD, _, _)).WillOnce(Return(-1));
199ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_FALSE(CreateSocket());
200ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
201ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
202ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, StartSuccess) {
203ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  StartClient();
204ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
205ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
206ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, StartMultipleTimes) {
207ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  const int kFirstSocketFD = kSocketFD + 1;
208ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  StartClientWithFD(kFirstSocketFD);
209ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, Close(kFirstSocketFD));
210ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  StartClient();
211ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
212ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
213ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, Receive) {
214ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  StartClient();
215ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_,
216ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart              RecvFrom(kSocketFD, _, GetMaxArpPacketLength(), 0, _, _))
217ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(-1))
218ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillRepeatedly(Invoke(this, &ArpClientTest::SimulateRecvFrom));
219ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ArpPacket reply;
220ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString sender;
221ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
222ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ScopedMockLog log;
223ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
224ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  {
225ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    InSequence seq;
226ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
227ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    // RecvFrom returns an error.
228ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_CALL(log,
229ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart        Log(logging::LOG_ERROR, _,
230ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart            HasSubstr("Socket recvfrom failed"))).Times(1);
231417e5f079a1ccbc068c67f9cbf34f13c40330abcPaul Stewart    EXPECT_FALSE(client_.ReceivePacket(&reply, &sender));
232ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
233ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    // RecvFrom returns an empty response which fails to parse.
234ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_CALL(log,
235ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart        Log(logging::LOG_ERROR, _,
236417e5f079a1ccbc068c67f9cbf34f13c40330abcPaul Stewart            HasSubstr("Failed to parse ARP packet"))).Times(1);
237417e5f079a1ccbc068c67f9cbf34f13c40330abcPaul Stewart    EXPECT_FALSE(client_.ReceivePacket(&reply, &sender));
238ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
239ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    ArpPacket packet;
240ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    SetupValidPacket(&packet);
241ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    packet.FormatRequest(&recvfrom_reply_data_);
242ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
243ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    // Hack: Force this packet to be an ARP repsonse instead of an ARP request.
244ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    recvfrom_reply_data_.GetData()[kArpOpOffset] = ARPOP_REPLY;
245ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
2467fab89734d88724a288e96a9996b15548c5294c7Ben Chan    static const uint8_t kSenderBytes[] = { 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };
247ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    memcpy(&recvfrom_sender_.sll_addr, kSenderBytes, sizeof(kSenderBytes));
248ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    recvfrom_sender_.sll_halen = sizeof(kSenderBytes);
249417e5f079a1ccbc068c67f9cbf34f13c40330abcPaul Stewart    EXPECT_TRUE(client_.ReceivePacket(&reply, &sender));
250ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(reply.local_ip_address().Equals(packet.local_ip_address()));
251ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(reply.local_mac_address().Equals(packet.local_mac_address()));
252ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(reply.remote_ip_address().Equals(packet.remote_ip_address()));
253ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(reply.remote_mac_address().Equals(packet.remote_mac_address()));
254ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(
255ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart        sender.Equals(ByteString(kSenderBytes, arraysize(kSenderBytes))));
256ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  }
257ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
258ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
259ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul StewartTEST_F(ArpClientTest, Transmit) {
260ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ArpPacket packet;
261ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  StartClient();
262ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  // Packet isn't valid.
263ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_FALSE(client_.TransmitRequest(packet));
264ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
265ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  SetupValidPacket(&packet);
2663b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const ByteString& remote_mac = packet.remote_mac_address();
267ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString packet_bytes;
268ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ASSERT_TRUE(packet.FormatRequest(&packet_bytes));
269ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, SendTo(kSocketFD,
270ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                IsByteData(packet_bytes),
271ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                packet_bytes.GetLength(),
272ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                0,
273ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                IsLinkAddress(kInterfaceIndex, remote_mac),
274ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                sizeof(sockaddr_ll)))
275ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(-1))
276ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(0))
277ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(packet_bytes.GetLength() - 1))
278ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(packet_bytes.GetLength()));
279ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  {
280ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    InSequence seq;
281ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    ScopedMockLog log;
282ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_CALL(log,
283ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart        Log(logging::LOG_ERROR, _,
284ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart            HasSubstr("Socket sendto failed"))).Times(1);
285ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_CALL(log,
286ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart        Log(logging::LOG_ERROR, _,
287ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart            HasSubstr("different from expected result"))).Times(2);
288ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
289ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_FALSE(client_.TransmitRequest(packet));
290ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_FALSE(client_.TransmitRequest(packet));
291ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_FALSE(client_.TransmitRequest(packet));
292ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart    EXPECT_TRUE(client_.TransmitRequest(packet));
293ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  }
294ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
295ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  // If the destination MAC address is unset, it should be sent to the
296ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  // broadcast MAC address.
2977fab89734d88724a288e96a9996b15548c5294c7Ben Chan  static const uint8_t kZeroBytes[] = { 0, 0, 0, 0, 0, 0 };
298ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  packet.set_remote_mac_address(ByteString(kZeroBytes, arraysize(kZeroBytes)));
299ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ASSERT_TRUE(packet.FormatRequest(&packet_bytes));
3007fab89734d88724a288e96a9996b15548c5294c7Ben Chan  static const uint8_t kBroadcastBytes[] =
3017fab89734d88724a288e96a9996b15548c5294c7Ben Chan      { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
302ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  ByteString broadcast_mac(kBroadcastBytes, arraysize(kBroadcastBytes));
303ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_CALL(*sockets_, SendTo(kSocketFD,
304ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                IsByteData(packet_bytes),
305ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                packet_bytes.GetLength(),
306ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                0,
307ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                IsLinkAddress(kInterfaceIndex, broadcast_mac),
308ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart                                sizeof(sockaddr_ll)))
309ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart      .WillOnce(Return(packet_bytes.GetLength()));
310ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart  EXPECT_TRUE(client_.TransmitRequest(packet));
311ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}
312ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart
313ac1328e5143f6ee0054d5cb2f7d17754c16a3814Paul Stewart}  // namespace shill
314