shill: implement ping in shill in IcmpSession

Add IcmpSession, a class which wraps around Icmp to allow us to
perform ping in shill. When an object of this class is created
and started via IcmpSession::Start, it keeps sending ICMP echo
requests to a given destination at 1 second intervals until 3
echo requests are succesfully sent. IcmpSession then waits until
all echo replies are received (or a timeout occurs) before
reporting the latency for each echo reply to the caller.

BUG=chromium:216691
TEST=Compile shill and run unit tests.

Change-Id: Ia7e4e9381b6a496daf2fdc4df3008599ce1b312f
Reviewed-on: https://chromium-review.googlesource.com/272513
Trybot-Ready: Samuel Tan <samueltan@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Queue: Samuel Tan <samueltan@chromium.org>
Tested-by: Samuel Tan <samueltan@chromium.org>
diff --git a/icmp.h b/icmp.h
index 615dc90..6c34e3b 100644
--- a/icmp.h
+++ b/icmp.h
@@ -5,6 +5,8 @@
 #ifndef SHILL_ICMP_H_
 #define SHILL_ICMP_H_
 
+#include <netinet/ip_icmp.h>
+
 #include <memory>
 
 #include <base/macros.h>
@@ -18,6 +20,8 @@
 // The Icmp class encapsulates the task of sending ICMP frames.
 class Icmp {
  public:
+  static const int kIcmpEchoCode;
+
   Icmp();
   virtual ~Icmp();
 
@@ -30,12 +34,21 @@
   // Returns whether an ICMP socket is open.
   virtual bool IsStarted() const;
 
-  // Send an ICMP Echo Request (Ping) packet to |destination|.
-  virtual bool TransmitEchoRequest(const IPAddress& destinaton);
+  // Send an ICMP Echo Request (Ping) packet to |destination|. The ID and
+  // sequence number fields of the echo request will be set to |id| and
+  // |seq_num| respectively.
+  virtual bool TransmitEchoRequest(const IPAddress& destination, uint16_t id,
+                                   uint16_t seq_num);
+
+  int socket() { return socket_; }
 
  private:
   friend class IcmpTest;
 
+  // Compute the checksum for Echo Request |hdr| of length |len| according to
+  // specifications in RFC 792.
+  static uint16_t ComputeIcmpChecksum(const struct icmphdr& hdr, size_t len);
+
   std::unique_ptr<Sockets> sockets_;
   std::unique_ptr<ScopedSocketCloser> socket_closer_;
   int socket_;