Replaced shift operations on IP addresses to an endian-safer approach
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 6 Aug 2011 19:33:09 +0000 (16:33 -0300)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 6 Aug 2011 19:39:57 +0000 (16:39 -0300)
- Instead of shifts on sockaddr.sa_data, uses a cast to sockaddr_in.sin_addr.s_addr.
  And as long as the two structures have the same memory layout, the cast is safe.
- Reinterpret four chars (8 bits) as one integer (32 bits), and make it endian safe.

src/tcp/tcppinger.cpp

index c35655b..e4d6b38 100644 (file)
@@ -125,21 +125,20 @@ uint32_t TcpPinger::get_source_address()
     if ( network_interface_name_limit > SourceNetworkInterfaceName.size() )
     {
         strncpy( ifr.ifr_name, SourceNetworkInterfaceName.c_str(), network_interface_name_limit );
-        ifr.ifr_addr.sa_family = AF_INET;
+        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)
         {
-            return ((uint32_t) ifr.ifr_addr.sa_data[2] & 0xFF) << 24 |
-                    ((uint32_t) ifr.ifr_addr.sa_data[3] & 0xFF) << 16 |
-                    ((uint32_t) ifr.ifr_addr.sa_data[4] & 0xFF) << 8 |
-                    ((uint32_t) ifr.ifr_addr.sa_data[5] & 0xFF);
+            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;
         }
     }
     else
     {
-        GlobalLogger.error() << "Error: network interface name truncated"
-            << endl;
+        GlobalLogger.error() << "Error: network interface name truncated" << endl;
     }
 
     return 0;
@@ -147,10 +146,10 @@ uint32_t TcpPinger::get_source_address()
 
 uint32_t TcpPinger::get_destination_address() const
 {
-    return ((uint32_t) DestinationEndpoint.data()->sa_data[2] & 0xFF) << 24 |
-           ((uint32_t) DestinationEndpoint.data()->sa_data[3] & 0xFF) << 16 |
-           ((uint32_t) DestinationEndpoint.data()->sa_data[4] & 0xFF) << 8 |
-           ((uint32_t) DestinationEndpoint.data()->sa_data[5] & 0xFF);
+    const sockaddr_in *destination_sockaddr = reinterpret_cast<const sockaddr_in *>( DestinationEndpoint.data() );
+    uint32_t destination_ipv4_address = htonl( destination_sockaddr->sin_addr.s_addr );
+
+    return destination_ipv4_address;
 }
 
 void TcpPinger::set_destination_endpoint( const string &destination_ip )