1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 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//
16960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
17960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart#include "shill/icmp.h"
18960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
19960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart#include <netinet/in.h>
20960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart#include <netinet/ip_icmp.h>
21960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
22960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart#include <gtest/gtest.h>
23960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
24960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart#include "shill/mock_log.h"
258d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h"
268d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
27960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
28960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::_;
29960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::HasSubstr;
30960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::InSequence;
31960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::Return;
32960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::StrictMock;
33960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartusing testing::Test;
34960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
35960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartnamespace shill {
36960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
37f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tannamespace {
38f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan
39f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan// These binary blobs representing ICMP headers and their respective checksums
40f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan// were taken directly from Wireshark ICMP packet captures and are given in big
41f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan// endian. The checksum field is zeroed in |kIcmpEchoRequestEvenLen| and
42f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan// |kIcmpEchoRequestOddLen| so the checksum can be calculated on the header in
43f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan// IcmpTest.ComputeIcmpChecksum.
44f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tanconst uint8_t kIcmpEchoRequestEvenLen[] = {0x08, 0x00, 0x00, 0x00,
45f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                           0x71, 0x50, 0x00, 0x00};
46f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tanconst uint8_t kIcmpEchoRequestEvenLenChecksum[] = {0x86, 0xaf};
47f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tanconst uint8_t kIcmpEchoRequestOddLen[] = {0x08, 0x00, 0x00, 0x00, 0xac, 0x51,
48f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                          0x00, 0x00, 0x00, 0x00, 0x01};
49f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tanconst uint8_t kIcmpEchoRequestOddLenChecksum[] = {0x4a, 0xae};
50f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan
51f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan}  // namespace
52f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan
53960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartclass IcmpTest : public Test {
54960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart public:
55960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  IcmpTest() {}
56960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  virtual ~IcmpTest() {}
57960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
58960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  virtual void SetUp() {
59960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    sockets_ = new StrictMock<MockSockets>();
60960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    // Passes ownership.
61960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    icmp_.sockets_.reset(sockets_);
62960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  }
63960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
64960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  virtual void TearDown() {
65960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    if (icmp_.IsStarted()) {
66960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      EXPECT_CALL(*sockets_, Close(kSocketFD));
67960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      icmp_.Stop();
68960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    }
69960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_FALSE(icmp_.IsStarted());
70960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  }
71960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
72960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart protected:
73960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  static const int kSocketFD;
74960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  static const char kIPAddress[];
75960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
76960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  int GetSocket() { return icmp_.socket_; }
77960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  bool StartIcmp() { return StartIcmpWithFD(kSocketFD); }
78960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  bool StartIcmpWithFD(int fd) {
79960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP))
80960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart        .WillOnce(Return(fd));
81960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_CALL(*sockets_, SetNonBlocking(fd)).WillOnce(Return(0));
82960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    bool start_status = icmp_.Start();
83960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_TRUE(start_status);
84960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_EQ(fd, icmp_.socket_);
85960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_TRUE(icmp_.IsStarted());
86960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    return start_status;
87960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  }
88f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  uint16_t ComputeIcmpChecksum(const struct icmphdr &hdr, size_t len) {
89f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan    return Icmp::ComputeIcmpChecksum(hdr, len);
90f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  }
91960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
92960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  // Owned by Icmp, and tracked here only for mocks.
933b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockSockets* sockets_;
94960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
95960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  Icmp icmp_;
96960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart};
97960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
98960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
99960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartconst int IcmpTest::kSocketFD = 456;
100960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewartconst char IcmpTest::kIPAddress[] = "10.0.1.1";
101960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
102960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
103960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartTEST_F(IcmpTest, Constructor) {
104960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_EQ(-1, GetSocket());
105960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_FALSE(icmp_.IsStarted());
106960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
107960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
108960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartTEST_F(IcmpTest, SocketOpenFail) {
109960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  ScopedMockLog log;
110960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(log,
111960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      Log(logging::LOG_ERROR, _,
112960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart          HasSubstr("Could not create ICMP socket"))).Times(1);
113960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
114960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP))
115960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      .WillOnce(Return(-1));
116960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_FALSE(icmp_.Start());
117960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_FALSE(icmp_.IsStarted());
118960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
119960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
120960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartTEST_F(IcmpTest, SocketNonBlockingFail) {
121960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  ScopedMockLog log;
122960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(log,
123960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      Log(logging::LOG_ERROR, _,
124960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart          HasSubstr("Could not set socket to be non-blocking"))).Times(1);
125960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
126960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, Socket(_, _, _)).WillOnce(Return(kSocketFD));
127960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, SetNonBlocking(kSocketFD)).WillOnce(Return(-1));
128960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, Close(kSocketFD));
129960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_FALSE(icmp_.Start());
130960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_FALSE(icmp_.IsStarted());
131960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
132960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
133960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartTEST_F(IcmpTest, StartMultipleTimes) {
134960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  const int kFirstSocketFD = kSocketFD + 1;
135960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  StartIcmpWithFD(kFirstSocketFD);
136960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, Close(kFirstSocketFD));
137960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  StartIcmp();
138960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
139960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
140960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartMATCHER_P(IsIcmpHeader, header, "") {
141960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  return memcmp(arg, &header, sizeof(header)) == 0;
142960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
143960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
144960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
145960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartMATCHER_P(IsSocketAddress, address, "") {
1463b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct sockaddr_in* sock_addr =
1473b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      reinterpret_cast<const struct sockaddr_in*>(arg);
148960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  return sock_addr->sin_family == address.family() &&
149960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      memcmp(&sock_addr->sin_addr.s_addr, address.GetConstData(),
150960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart             address.GetLength()) == 0;
151960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
152960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
153960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul StewartTEST_F(IcmpTest, TransmitEchoRequest) {
154960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  StartIcmp();
155960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  // Address isn't valid.
156f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  EXPECT_FALSE(
157f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan      icmp_.TransmitEchoRequest(IPAddress(IPAddress::kFamilyIPv4), 1, 1));
158960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
159960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  // IPv6 adresses aren't implemented.
160960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  IPAddress ipv6_destination(IPAddress::kFamilyIPv6);
161960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_TRUE(ipv6_destination.SetAddressFromString(
162960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      "fe80::1aa9:5ff:abcd:1234"));
163f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  EXPECT_FALSE(icmp_.TransmitEchoRequest(ipv6_destination, 1, 1));
164960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
165960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  IPAddress ipv4_destination(IPAddress::kFamilyIPv4);
166960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_TRUE(ipv4_destination.SetAddressFromString(kIPAddress));
167960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
168960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  struct icmphdr icmp_header;
169a28487ec5dfca1f87871ab2b94453351c43ac8cePaul Stewart  memset(&icmp_header, 0, sizeof(icmp_header));
170960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  icmp_header.type = ICMP_ECHO;
171f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  icmp_header.code = Icmp::kIcmpEchoCode;
172960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  icmp_header.un.echo.id = 1;
173960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  icmp_header.un.echo.sequence = 1;
174f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  icmp_header.checksum = ComputeIcmpChecksum(icmp_header, sizeof(icmp_header));
175f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan
176960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  EXPECT_CALL(*sockets_, SendTo(kSocketFD,
177960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart                                IsIcmpHeader(icmp_header),
178960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart                                sizeof(icmp_header),
179960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart                                0,
180960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart                                IsSocketAddress(ipv4_destination),
181960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart                                sizeof(sockaddr_in)))
182960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      .WillOnce(Return(-1))
183960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      .WillOnce(Return(0))
184960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      .WillOnce(Return(sizeof(icmp_header) - 1))
185960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart      .WillOnce(Return(sizeof(icmp_header)));
186960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  {
187960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    InSequence seq;
188960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    ScopedMockLog log;
189960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_CALL(log,
190960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart        Log(logging::LOG_ERROR, _,
191960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart            HasSubstr("Socket sendto failed"))).Times(1);
192960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart    EXPECT_CALL(log,
193960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart        Log(logging::LOG_ERROR, _,
194960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart            HasSubstr("less than the expected result"))).Times(2);
195960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
196f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan    EXPECT_FALSE(icmp_.TransmitEchoRequest(ipv4_destination, 1, 1));
197f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan    EXPECT_FALSE(icmp_.TransmitEchoRequest(ipv4_destination, 1, 1));
198f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan    EXPECT_FALSE(icmp_.TransmitEchoRequest(ipv4_destination, 1, 1));
199f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan    EXPECT_TRUE(icmp_.TransmitEchoRequest(ipv4_destination, 1, 1));
200960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart  }
201960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}
202960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart
203f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel TanTEST_F(IcmpTest, ComputeIcmpChecksum) {
204f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  EXPECT_EQ(*reinterpret_cast<const uint16_t*>(kIcmpEchoRequestEvenLenChecksum),
205f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan            ComputeIcmpChecksum(*reinterpret_cast<const struct icmphdr*>(
206f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                    kIcmpEchoRequestEvenLen),
207f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                sizeof(kIcmpEchoRequestEvenLen)));
208f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan  EXPECT_EQ(*reinterpret_cast<const uint16_t*>(kIcmpEchoRequestOddLenChecksum),
209f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan            ComputeIcmpChecksum(*reinterpret_cast<const struct icmphdr*>(
210f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                    kIcmpEchoRequestOddLen),
211f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan                                sizeof(kIcmpEchoRequestOddLen)));
212f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan}
213f66080eb8e8826128d6ad57cce3e9722c8f5a31fSamuel Tan
214960d469ba513ff10d4b4f48c269c03b2f7f12fbfPaul Stewart}  // namespace shill
215