The C's low level socket handling functions were encapsulated in the NetworkInterface...
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 20 Aug 2011 15:19:13 +0000 (12:19 -0300)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 20 Aug 2011 15:19:13 +0000 (12:19 -0300)
src/host/networkinterface.hpp
src/icmp/icmppinger.cpp
src/icmp/icmppinger.h
src/tcp/tcppinger.cpp
src/tcp/tcppinger.h

index 53b543d..03dff0d 100644 (file)
@@ -61,7 +61,7 @@ public:
 private:
     /// The network interface name which the socket is attached
     const std::string Name;
-    /// The native socket descriptor
+    /// The socket used in this network interface
     SocketType &Socket;
 
 };
index ac33b70..c96416a 100644 (file)
@@ -52,6 +52,7 @@ IcmpPinger::IcmpPinger(
     IoService( io_serv ),
     DestinationEndpoint(),
     Socket( IoService, icmp::v4() ),
+    NetInterface( source_network_interface, Socket ),
     IcmpPacketReceiveTimer( IoService ),
     Identifier( 0 ),
     SequenceNumber( 0 ),
@@ -373,19 +374,5 @@ bool IcmpPinger::select_source_network_interface(
 {
     BOOST_ASSERT( !source_network_interface.empty() );
 
-    int ret = ::setsockopt(
-            Socket.native(),
-            SOL_SOCKET,
-            SO_BINDTODEVICE,
-            source_network_interface.c_str(),
-            source_network_interface.size()
-    );
-    if ( ret == -1 )
-    {
-        GlobalLogger.error() << "Error: could not bind pinger to interface "
-            << source_network_interface << endl;
-        return false;
-    }
-
-    return true;
+    return NetInterface.bind();
 }
index e8083f7..1cbc339 100644 (file)
@@ -12,6 +12,7 @@
 #include <boost/asio.hpp>
 #include <boost/function.hpp>
 
+#include "host/networkinterface.hpp"
 #include "host/pinger.h"
 #include "host/pingstatus.h"
 
@@ -67,29 +68,31 @@ private:
     );
 
 private:
-    /// io service object, which has the loop event
+    /// The IO service object, which has the loop event
     boost::asio::io_service &IoService;
-    /// the destination host
+    /// The destination host
     boost::asio::ip::icmp::endpoint DestinationEndpoint;
-    /// the socket object
+    /// The socket object
     boost::asio::ip::icmp::socket Socket;
-    /// the timer of ICMP packet receive, triggers the timeout to avoid infinite
+    /// This object represents the network interface
+    NetworkInterface<boost::asio::ip::icmp::socket> NetInterface;
+    /// The timer of ICMP packet receive, triggers the timeout to avoid infinite
     /// wait
     boost::asio::deadline_timer IcmpPacketReceiveTimer;
     /// ICMP packet identifier
     uint16_t Identifier;
     /// ICMP packet sequence_number
     uint16_t SequenceNumber;
-    /// the time when the last ICMP packet was sent
+    /// The time when the last ICMP packet was sent
     boost::posix_time::ptime TimeSent;
-    /// the buffer where the data received will be placed
+    /// The buffer where the data received will be placed
     boost::asio::streambuf ReplyBuffer;
     /// Flag to indicate if we got a reply or not
     /// number of replies to the ICMP echo request
     bool ReceivedReply;
-    /// the amount of time to wait for the reply
+    /// The amount of time to wait for the reply
     int EchoReplyTimeoutInSec;
-    /// the status of the pinger
+    /// The status of the pinger
     PingStatus PingerStatus;
     /// Callback to notify when the ping is done (got reply/timeout)
     boost::function< void(bool) > PingDoneCallback;
index e68ae86..3b91cdd 100644 (file)
@@ -60,7 +60,7 @@ TcpPinger::TcpPinger(
     IoService( io_serv ),
     DestinationEndpoint(),
     Socket( IoService, tcp_raw_protocol::v4() ),
-    SourceNetworkInterfaceName( source_network_interface_name ),
+    NetInterface( source_network_interface_name, Socket ),
     TcpSegmentReceiveTimer( IoService ),
     Identifier( 0 ),
     SequenceNumber( 0 ),
@@ -116,32 +116,7 @@ void TcpPinger::ping(
 
 uint32_t TcpPinger::get_source_address()
 {
-    struct ifreq ifr;
-    memset( &ifr, 0, sizeof(ifr) );
-
-    // make sure the ifr.ifr_name has enough room to receive the network
-    // interface name
-    size_t network_interface_name_limit = sizeof(ifr.ifr_name);
-    if ( network_interface_name_limit <= SourceNetworkInterfaceName.size() )
-    {
-        GlobalLogger.error() << "Error: network interface name truncated" << endl;
-        return 0;
-    }
-
-    strncpy( ifr.ifr_name, SourceNetworkInterfaceName.c_str(), network_interface_name_limit );
-    ifr.ifr_addr.sa_family = AF_INET; // TODO change to AF_INET6 when IPv6
-
-    int ioctl_resp = ioctl( Socket.native(), SIOCGIFADDR, &ifr );
-    if ( ioctl_resp != 0)
-    {
-        GlobalLogger.error() << "Error: could not retrieve IP address from network interface" << endl;
-        return 0;
-    }
-
-    const sockaddr_in *source_sockaddr = reinterpret_cast<const sockaddr_in *>( &ifr.ifr_addr );
-    uint32_t source_ipv4_address = htonl( source_sockaddr->sin_addr.s_addr );
-
-    return source_ipv4_address;
+    return NetInterface.get_address();
 }
 
 uint32_t TcpPinger::get_destination_address() const
@@ -372,19 +347,5 @@ bool TcpPinger::select_source_network_interface(
 {
     BOOST_ASSERT( !source_network_interface_name.empty() );
 
-    int ret = ::setsockopt(
-            Socket.native(),
-            SOL_SOCKET,
-            SO_BINDTODEVICE,
-            source_network_interface_name.c_str(),
-            source_network_interface_name.size()
-    );
-    if ( ret == -1 )
-    {
-        GlobalLogger.error() << "Error: could not bind pinger to interface "
-            << source_network_interface_name << endl;
-        return false;
-    }
-
-    return true;
+    return NetInterface.bind();
 }
index 7157fb8..68d64ac 100644 (file)
@@ -26,6 +26,7 @@ on this file might be covered by the GNU General Public License.
 #include <boost/asio/ip/tcp_raw_protocol.hpp>
 #include <boost/function.hpp>
 
+#include "host/networkinterface.hpp"
 #include "host/pinger.h"
 #include "host/pingstatus.h"
 #include "ip/ipv4header.h"
@@ -90,8 +91,8 @@ private:
     boost::asio::ip::tcp_raw_protocol::endpoint DestinationEndpoint;
     /// the socket object
     boost::asio::ip::tcp_raw_protocol::socket Socket;
-    /// the network interface name which the socket is attached
-    std::string SourceNetworkInterfaceName;
+    /// This object represents the network interface
+    NetworkInterface<boost::asio::ip::tcp_raw_protocol::socket> NetInterface;
     /// the timer of TCP segment receive, triggers the timeout to avoid infinite
     /// wait
     boost::asio::deadline_timer TcpSegmentReceiveTimer;