From 3b668576768070344c9c0346cafcf876f3083fd9 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Sat, 20 Aug 2011 12:19:13 -0300 Subject: [PATCH] The C's low level socket handling functions were encapsulated in the NetworkInterface class --- src/host/networkinterface.hpp | 2 +- src/icmp/icmppinger.cpp | 17 +------------- src/icmp/icmppinger.h | 19 ++++++++++------- src/tcp/tcppinger.cpp | 45 ++-------------------------------------- src/tcp/tcppinger.h | 5 ++- 5 files changed, 20 insertions(+), 68 deletions(-) diff --git a/src/host/networkinterface.hpp b/src/host/networkinterface.hpp index 53b543d..03dff0d 100644 --- a/src/host/networkinterface.hpp +++ b/src/host/networkinterface.hpp @@ -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; }; diff --git a/src/icmp/icmppinger.cpp b/src/icmp/icmppinger.cpp index ac33b70..c96416a 100644 --- a/src/icmp/icmppinger.cpp +++ b/src/icmp/icmppinger.cpp @@ -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(); } diff --git a/src/icmp/icmppinger.h b/src/icmp/icmppinger.h index e8083f7..1cbc339 100644 --- a/src/icmp/icmppinger.h +++ b/src/icmp/icmppinger.h @@ -12,6 +12,7 @@ #include #include +#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 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; diff --git a/src/tcp/tcppinger.cpp b/src/tcp/tcppinger.cpp index e68ae86..3b91cdd 100644 --- a/src/tcp/tcppinger.cpp +++ b/src/tcp/tcppinger.cpp @@ -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( &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(); } diff --git a/src/tcp/tcppinger.h b/src/tcp/tcppinger.h index 7157fb8..68d64ac 100644 --- a/src/tcp/tcppinger.h +++ b/src/tcp/tcppinger.h @@ -26,6 +26,7 @@ on this file might be covered by the GNU General Public License. #include #include +#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 NetInterface; /// the timer of TCP segment receive, triggers the timeout to avoid infinite /// wait boost::asio::deadline_timer TcpSegmentReceiveTimer; -- 1.7.1