From: Markus Kötter Date: Thu, 1 Nov 2018 10:08:03 +0000 (+0100) Subject: sockaddr - unify access to sockaddr_in/6 port & address X-Git-Tag: v0.93~1^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0321e91ebd8461a8ad40efbb64105167a03f37d;p=thirdparty%2Fmtr.git sockaddr - unify access to sockaddr_in/6 port & address --- diff --git a/Makefile.am b/Makefile.am index 23ac1fc..5a5997d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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) diff --git a/packet/construct_unix.c b/packet/construct_unix.c index d31cba0..9b33596 100644 --- a/packet/construct_unix.c +++ b/packet/construct_unix.c @@ -25,6 +25,7 @@ #include #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 */ diff --git a/packet/probe.c b/packet/probe.c index cf95f8a..a3609d0 100644 --- a/packet/probe.c +++ b/packet/probe.c @@ -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; } diff --git a/packet/probe_unix.c b/packet/probe_unix.c index 2804ecb..046229d 100644 --- a/packet/probe_unix.c +++ b/packet/probe_unix.c @@ -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 index 0000000..c897da2 --- /dev/null +++ b/packet/sockaddr.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +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 index 0000000..ae7fc19 --- /dev/null +++ b/packet/sockaddr.h @@ -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);