Message to require sudo access to open raw sockets.
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 10 Dec 2011 13:56:45 +0000 (11:56 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 10 Dec 2011 13:56:45 +0000 (11:56 -0200)
src/host/pingerfactory.cpp

index 51a87f0..0171e03 100644 (file)
 
 #include "host/pingerfactory.h"
 
+#include <cstdlib>
+
+#include <iostream>
+
 #include <boost/asio/ip/tcp_raw_protocol.hpp>
+#include <boost/system/system_error.hpp>
 
 #include "icmp/icmppinger.h"
 #include "tcp/tcppinger.h"
@@ -30,6 +35,7 @@ using boost::shared_ptr;
 using boost::asio::io_service;
 using boost::asio::ip::icmp;
 using boost::asio::ip::tcp_raw_protocol;
+using boost::system::system_error;
 
 //-----------------------------------------------------------------------------
 // PingerFactory
@@ -70,26 +76,38 @@ shared_ptr<Pinger> PingerFactory::createPinger(
     // Ping reply timeout. Could be made a configuration variable
     const int ping_reply_timeout_in_sec = 30; // TODO
 
-    switch ( protocol )
+    try
     {
-    case PingProtocol_ICMP:
-        return shared_ptr<Pinger>(
-                new IcmpPinger( io_serv, icmp::v4(), network_interface, ping_reply_timeout_in_sec )
-        );
-    case PingProtocol_ICMPv6:
-        return shared_ptr<Pinger>(
-                new IcmpPinger( io_serv, icmp::v6(), network_interface, ping_reply_timeout_in_sec )
-        );
-    case PingProtocol_TCP:
-        return shared_ptr<Pinger>(
-                new TcpPinger( io_serv, tcp_raw_protocol::v4(), network_interface, ping_reply_timeout_in_sec )
-        );
-    case PingProtocol_TCP_IPv6:
-        return shared_ptr<Pinger>(
-                new TcpPinger( io_serv, tcp_raw_protocol::v6(), network_interface, ping_reply_timeout_in_sec )
-        );
-    default:
-        BOOST_ASSERT( !"Try to create a pinger from an invalid protocol" );
-        return shared_ptr<Pinger>();
+        switch ( protocol )
+        {
+        case PingProtocol_ICMP:
+            return shared_ptr<Pinger>(
+                    new IcmpPinger( io_serv, icmp::v4(), network_interface, ping_reply_timeout_in_sec )
+            );
+        case PingProtocol_ICMPv6:
+            return shared_ptr<Pinger>(
+                    new IcmpPinger( io_serv, icmp::v6(), network_interface, ping_reply_timeout_in_sec )
+            );
+        case PingProtocol_TCP:
+            return shared_ptr<Pinger>(
+                    new TcpPinger( io_serv, tcp_raw_protocol::v4(), network_interface, ping_reply_timeout_in_sec )
+            );
+        case PingProtocol_TCP_IPv6:
+            return shared_ptr<Pinger>(
+                    new TcpPinger( io_serv, tcp_raw_protocol::v6(), network_interface, ping_reply_timeout_in_sec )
+            );
+        default:
+            BOOST_ASSERT( !"Try to create a pinger from an invalid protocol" );
+            return shared_ptr<Pinger>();
+        }
     }
+    catch ( const system_error &ex )
+    {
+        // Raw sockets are locked down by Unix operating systems to prevent
+        // malware and security holes, thus it requires root access to use it.
+        cerr << "Error: pingcheck must run as root (" << ex.what() << ")" << endl;
+        exit( EXIT_FAILURE );
+    }
+
+    return shared_ptr<Pinger>();
 }