]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
sockaddr - unify access to sockaddr_in/6 port & address
authorMarkus Kötter <koetter@luis.uni-hannover.de>
Thu, 1 Nov 2018 10:08:03 +0000 (11:08 +0100)
committerMarkus Kötter <koetter@luis.uni-hannover.de>
Thu, 1 Nov 2018 10:08:03 +0000 (11:08 +0100)
Makefile.am
packet/construct_unix.c
packet/probe.c
packet/probe_unix.c
packet/sockaddr.c [new file with mode: 0644]
packet/sockaddr.h [new file with mode: 0644]

index 23ac1fc6e78a46305297989e655bcb6106663674..5a5997d4e6caf3c45a045aa19f6e8c9f59f9764d 100644 (file)
@@ -98,7 +98,8 @@ mtr_packet_SOURCES = \
        packet/probe.c packet/probe.h \
        packet/protocols.h \
        packet/timeval.c packet/timeval.h \
-       packet/wait.h
+       packet/wait.h \
+       packet/sockaddr.c packet/sockaddr.h
 
 mtr_packet_LDADD = $(CAP_LIBS)
 
index d31cba0d6ba98a01fce8a753f5e6bfb8d3b1c783..9b3359625631b6e046034aad5a41c56e97a206a1 100644 (file)
@@ -25,6 +25,7 @@
 #include <unistd.h>
 
 #include "protocols.h"
+#include "sockaddr.h"
 
 /* For Mac OS X and FreeBSD */
 #ifndef SOL_IP
@@ -90,18 +91,8 @@ void construct_addr_port(
     const struct sockaddr_storage *addr,
     int port)
 {
-    struct sockaddr_in *addr4;
-    struct sockaddr_in6 *addr6;
-
     memcpy(addr_with_port, addr, sizeof(struct sockaddr_storage));
-
-    if (addr->ss_family == AF_INET6) {
-        addr6 = (struct sockaddr_in6 *) addr_with_port;
-        addr6->sin6_port = htons(port);
-    } else {
-        addr4 = (struct sockaddr_in *) addr_with_port;
-        addr4->sin_port = htons(port);
-    }
+    *(uint16_t *)sockaddr_port_offset(addr) = htons(port);
 }
 
 /*  Construct a header for IP version 4  */
index cf95f8a3f1f3f6d655f60ecd85098ff3fb956e39..a3609d095b02dd33399659214663a357ceabe969 100644 (file)
@@ -31,6 +31,7 @@
 #include "platform.h"
 #include "protocols.h"
 #include "timeval.h"
+#include "sockaddr.h"
 
 #define IP_TEXT_LENGTH 64
 
@@ -109,19 +110,9 @@ int resolve_probe_addresses(
     }
     /* DGRAM ICMP id is taken from src_port not from ICMP header */
     if (param->protocol == IPPROTO_ICMP) {
-        if (src_sockaddr->ss_family == AF_INET) {
-            if (!net_state->platform.ip4_socket_raw) {
-                struct sockaddr_in *sin_src =
-                    (struct sockaddr_in *) src_sockaddr;
-                sin_src->sin_port = htons(getpid());
-            }
-        } else if (src_sockaddr->ss_family == AF_INET6) {
-            if (!net_state->platform.ip6_socket_raw) {
-                struct sockaddr_in6 *sin6_src =
-                    (struct sockaddr_in6 *) src_sockaddr;
-                sin6_src->sin6_port = htons(getpid());
-            }
-        }
+        if ( (src_sockaddr->ss_family == AF_INET && !net_state->platform.ip4_socket_raw) ||
+             (src_sockaddr->ss_family == AF_INET6 && !net_state->platform.ip6_socket_raw) )
+            *(uint16_t *)sockaddr_port_offset(src_sockaddr) = htons(getpid());
     }
 
     return 0;
@@ -259,9 +250,6 @@ void respond_to_probe(
     int remaining_size;
     const char *result;
     const char *ip_argument;
-    struct sockaddr_in *sockaddr4;
-    struct sockaddr_in6 *sockaddr6;
-    void *addr;
 
     if (icmp_type == ICMP_TIME_EXCEEDED) {
         result = "ttl-expired";
@@ -274,15 +262,11 @@ void respond_to_probe(
 
     if (remote_addr->ss_family == AF_INET6) {
         ip_argument = "ip-6";
-        sockaddr6 = (struct sockaddr_in6 *) remote_addr;
-        addr = &sockaddr6->sin6_addr;
     } else {
         ip_argument = "ip-4";
-        sockaddr4 = (struct sockaddr_in *) remote_addr;
-        addr = &sockaddr4->sin_addr;
     }
 
-    if (inet_ntop(remote_addr->ss_family, addr, ip_text, IP_TEXT_LENGTH) ==
+    if (inet_ntop(remote_addr->ss_family, sockaddr_addr_offset(remote_addr), ip_text, IP_TEXT_LENGTH) ==
         NULL) {
 
         perror("inet_ntop failure");
@@ -325,8 +309,6 @@ int find_source_addr(
 {
     int sock;
     int len;
-    struct sockaddr_in *destaddr4;
-    struct sockaddr_in6 *destaddr6;
     struct sockaddr_storage dest_with_port;
     struct sockaddr_in *srcaddr4;
     struct sockaddr_in6 *srcaddr6;
@@ -339,17 +321,8 @@ int find_source_addr(
        the connect will fail.  We aren't actually sending
        anything to the port.
      */
-    if (destaddr->ss_family == AF_INET6) {
-        destaddr6 = (struct sockaddr_in6 *) &dest_with_port;
-        destaddr6->sin6_port = htons(1);
-
-        len = sizeof(struct sockaddr_in6);
-    } else {
-        destaddr4 = (struct sockaddr_in *) &dest_with_port;
-        destaddr4->sin_port = htons(1);
-
-        len = sizeof(struct sockaddr_in);
-    }
+    *(uint16_t *)sockaddr_port_offset(&dest_with_port) = htons(1);
+    len = sockaddr_addr_size(&dest_with_port);
 
     sock = socket(destaddr->ss_family, SOCK_DGRAM, IPPROTO_UDP);
     if (sock == -1) {
@@ -390,15 +363,7 @@ int find_source_addr(
        Zero the port, as we may later use this address to finding, and
        we don't want to use the port from the socket we just created.
      */
-    if (destaddr->ss_family == AF_INET6) {
-        srcaddr6 = (struct sockaddr_in6 *) srcaddr;
-
-        srcaddr6->sin6_port = 0;
-    } else {
-        srcaddr4 = (struct sockaddr_in *) srcaddr;
-
-        srcaddr4->sin_port = 0;
-    }
+    *(uint16_t *)sockaddr_port_offset(&srcaddr) = 0;
 
     return 0;
 }
index 2804ecbfc5ae1907a8d32d222d3b49b9749936ac..046229d3654441babaa2e277c10bdf3cef26483f 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "platform.h"
 #include "protocols.h"
+#include "sockaddr.h"
 #include "construct_unix.h"
 #include "deconstruct_unix.h"
 #include "timeval.h"
@@ -62,13 +63,11 @@ int send_packet(
             if (net_state->platform.ip6_socket_raw) {
                 send_socket = net_state->platform.udp6_send_socket;
             } else {
-                struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)sockaddr;
-
                 send_socket = net_state->platform.ip6_txrx_udp_socket;
                 if (param->dest_port) {
-                    addr_in6->sin6_port = htons(param->dest_port);
+                    *(uint16_t *)sockaddr_port_offset(sockaddr) = htons(param->dest_port);
                 } else {
-                    addr_in6->sin6_port = sequence;
+                    *(uint16_t *)sockaddr_port_offset(sockaddr) = sequence;
                 }
             }
         }
@@ -85,13 +84,11 @@ int send_packet(
                     send_socket = net_state->platform.ip4_txrx_icmp_socket;
                 }
             } else if (param->protocol == IPPROTO_UDP) {
-                struct sockaddr_in *addr_in = (struct sockaddr_in *)sockaddr;
-
                 send_socket = net_state->platform.ip4_txrx_udp_socket;
                 if (param->dest_port) {
-                    addr_in->sin_port = htons(param->dest_port);
+                    *(uint16_t *)sockaddr_port_offset(sockaddr) = htons(param->dest_port);
                 } else {
-                    addr_in->sin_port = sequence;
+                    *(uint16_t *)sockaddr_port_offset(sockaddr) = sequence;
                 }
             }
         }
diff --git a/packet/sockaddr.c b/packet/sockaddr.c
new file mode 100644 (file)
index 0000000..c897da2
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stddef.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+void *sockaddr_addr_offset(const void *x)
+{
+       if( x == NULL )
+               return NULL;
+
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET )
+       {
+               return ((void *)(x) + offsetof(struct sockaddr_in, sin_addr));
+       }else
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET6 )
+       {
+               return ((void *)(x) + offsetof(struct sockaddr_in6, sin6_addr));
+       }
+
+       return NULL;
+}
+
+unsigned int sockaddr_addr_size(const void *x)
+{
+       if( x == NULL )
+               return 0;
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET )
+       {
+               return sizeof(struct in_addr);
+       }else
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET6 )
+       {
+               return sizeof(struct in6_addr);
+       }
+       return 0;
+}
+
+
+unsigned int sockaddr_size(const void *x)
+{
+       if( x == NULL )
+               return 0;
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET )
+       {
+               return sizeof(struct sockaddr_in);
+       }else
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET6 )
+       {
+               return sizeof(struct sockaddr_in6);
+       }
+       return 0;
+}
+
+void *sockaddr_port_offset(const void *x)
+{
+       if( x == NULL )
+               return NULL;
+
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET )
+       {
+               return ((void *)(x) + offsetof(struct sockaddr_in, sin_port));
+       }else
+       if( ((struct sockaddr *)(x))->sa_family == AF_INET6 )
+       {
+               return ((void *)(x) + offsetof(struct sockaddr_in6, sin6_port));
+       }
+
+       return NULL;
+}
diff --git a/packet/sockaddr.h b/packet/sockaddr.h
new file mode 100644 (file)
index 0000000..ae7fc19
--- /dev/null
@@ -0,0 +1,6 @@
+unsigned int sockaddr_size(const void *x);
+
+void *sockaddr_addr_offset(const void *x);
+unsigned int sockaddr_addr_size(const void *x);
+
+void *sockaddr_port_offset(const void *x);