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