]> git.gsnw.org Git - fping.git/commitdiff
only use getsockname() for identity with SOCK_DGRAM sockets
authorSteven Noonan <steven@uplinklabs.net>
Wed, 10 Jun 2020 02:35:03 +0000 (19:35 -0700)
committerDavid Schweikert <david@schweikert.ch>
Thu, 23 Jul 2020 21:04:15 +0000 (23:04 +0200)
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
src/fping.c
src/fping.h
src/socket4.c
src/socket6.c

index 4304531ff606e1ee46e6a090676a92f808fbfc98..233e85b46f7054a6e196cc8d475ba6b0a95a46e0 100644 (file)
@@ -260,11 +260,13 @@ char* prog;
 int ident4 = 0; /* our icmp identity field */
 int ident6 = 0;
 int socket4 = -1;
+int socktype4 = -1;
 int using_sock_dgram4 = 0;
 #ifndef IPV6
 int hints_ai_family = AF_INET;
 #else
 int socket6 = -1;
+int socktype6 = -1;
 int hints_ai_family = AF_UNSPEC;
 #endif
 
@@ -406,9 +408,16 @@ int main(int argc, char** argv)
         usage(0);
     }
 
-    socket4 = open_ping_socket_ipv4(&using_sock_dgram4);
+    socket4 = open_ping_socket_ipv4(&socktype4);
+#ifdef __linux__
+    /* We only treat SOCK_DGRAM differently on Linux, where the IPv4 header
+     * structure is missing in the message.
+     */
+    using_sock_dgram4 = (socktype4 == SOCK_DGRAM);
+#endif
+
 #ifdef IPV6
-    socket6 = open_ping_socket_ipv6();
+    socket6 = open_ping_socket_ipv6(&socktype6);
     /* if called (sym-linked) via 'fping6', imply '-6'
      * for backward compatibility */
     if (strstr(prog, "fping6")) {
@@ -428,7 +437,7 @@ int main(int argc, char** argv)
     }
 
     optparse_init(&optparse_state, argv);
-    ident4 = ident6 = getpid() & 0xFFFF;
+    ident4 = ident6 = htons(getpid() & 0xFFFF);
     verbose_flag = 1;
     backoff_flag = 1;
     opterr = 1;
@@ -1023,11 +1032,11 @@ int main(int argc, char** argv)
     }
 
     if (socket4 >= 0) {
-        socket_set_src_addr_ipv4(socket4, &src_addr, &ident4);
+        socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL);
     }
 #ifdef IPV6
     if (socket6 >= 0) {
-        socket_set_src_addr_ipv6(socket6, &src_addr6, &ident6);
+        socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL);
     }
 #endif
 
index 6c2a84bd53c076a6a9218df025f552a6e9f8a17e..bb99f60310b97aa32522010300b0b0ef835a448f 100644 (file)
@@ -14,12 +14,12 @@ int in_cksum( unsigned short *p, int n );
 extern int random_data_flag;
 
 /* socket.c */
-int  open_ping_socket_ipv4(int *using_sock_dgram);
+int  open_ping_socket_ipv4(int *socktype);
 void init_ping_buffer_ipv4(size_t ping_data_size);
 void socket_set_src_addr_ipv4(int s, struct in_addr *src_addr, int *ident);
 int  socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
 #ifdef IPV6
-int  open_ping_socket_ipv6();
+int  open_ping_socket_ipv6(int *socktype);
 void init_ping_buffer_ipv6(size_t ping_data_size);
 void socket_set_src_addr_ipv6(int s, struct in6_addr *src_addr, int *ident);
 int  socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
index 9787a9fa6310c3a5bfba45b229e28cdf8a1acada..d7c4ae359e3779ac4fbe5d2eaa18f725505d3748 100644 (file)
@@ -47,7 +47,7 @@
 char* ping_buffer_ipv4 = 0;
 size_t ping_pkt_size_ipv4;
 
-int open_ping_socket_ipv4(int *using_sock_dgram)
+int open_ping_socket_ipv4(int *socktype)
 {
     struct protoent* proto;
     int s;
@@ -56,23 +56,16 @@ int open_ping_socket_ipv4(int *using_sock_dgram)
     if ((proto = getprotobyname("icmp")) == NULL)
         crash_and_burn("icmp: unknown protocol");
 
-    *using_sock_dgram = 0;
-
     /* create raw socket for ICMP calls (ping) */
-    s = socket(AF_INET, SOCK_RAW, proto->p_proto);
+    *socktype = SOCK_RAW;
+    s = socket(AF_INET, *socktype, proto->p_proto);
     if (s < 0) {
         /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
-        s = socket(AF_INET, SOCK_DGRAM, proto->p_proto);
+        *socktype = SOCK_DGRAM;
+        s = socket(AF_INET, *socktype, proto->p_proto);
         if (s < 0) {
             return -1;
         }
-
-#ifdef __linux__
-        /* We only treat SOCK_DGRAM differently on Linux, where the IPv4 header
-         * structure is missing in the message.
-         */
-        *using_sock_dgram = 1;
-#endif
     }
 
     /* Make sure that we use non-blocking IO */
@@ -109,12 +102,14 @@ void socket_set_src_addr_ipv4(int s, struct in_addr* src_addr, int *ident)
     if (bind(s, (struct sockaddr*)&sa, len) < 0)
         errno_crash_and_burn("cannot bind source address");
 
-    memset(&sa, 0, len);
-    if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
-        errno_crash_and_burn("can't get ICMP socket identity");
+    if (ident) {
+        memset(&sa, 0, len);
+        if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
+            errno_crash_and_burn("can't get ICMP socket identity");
 
-    if (sa.sin_port)
-        *ident = sa.sin_port;
+        if (sa.sin_port)
+            *ident = sa.sin_port;
+    }
 }
 
 unsigned short calcsum(unsigned short* buffer, int length)
index 433e0e0eb1eded318c379eb5582dc5bb91e3c3ed..9ba42a34b67f6b3f53662ac25e033d9f4ce1844d 100644 (file)
@@ -46,7 +46,7 @@
 char* ping_buffer_ipv6 = 0;
 size_t ping_pkt_size_ipv6;
 
-int open_ping_socket_ipv6()
+int open_ping_socket_ipv6(int *socktype)
 {
     struct protoent* proto;
     int s;
@@ -56,10 +56,12 @@ int open_ping_socket_ipv6()
         crash_and_burn("icmp: unknown protocol");
 
     /* create raw socket for ICMP calls (ping) */
-    s = socket(AF_INET6, SOCK_RAW, proto->p_proto);
+    *socktype = SOCK_RAW;
+    s = socket(AF_INET6, *socktype, proto->p_proto);
     if (s < 0) {
         /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
-        s = socket(AF_INET6, SOCK_DGRAM, proto->p_proto);
+        *socktype = SOCK_DGRAM;
+        s = socket(AF_INET6, *socktype, proto->p_proto);
         if (s < 0) {
             return -1;
         }
@@ -99,12 +101,14 @@ void socket_set_src_addr_ipv6(int s, struct in6_addr* src_addr, int *ident)
     if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0)
         errno_crash_and_burn("cannot bind source address");
 
-    memset(&sa, 0, len);
-    if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
-        errno_crash_and_burn("can't get ICMP socket identity");
+    if (ident) {
+        memset(&sa, 0, len);
+        if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
+            errno_crash_and_burn("can't get ICMP socket identity");
 
-    if (sa.sin6_port)
-        *ident = sa.sin6_port;
+        if (sa.sin6_port)
+            *ident = sa.sin6_port;
+    }
 }
 
 int socket_sendto_ping_ipv6(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)