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)
#include <unistd.h>
#include "protocols.h"
+#include "sockaddr.h"
/* For Mac OS X and FreeBSD */
#ifndef SOL_IP
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 */
#include "platform.h"
#include "protocols.h"
#include "timeval.h"
+#include "sockaddr.h"
#define IP_TEXT_LENGTH 64
}
/* 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;
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";
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");
{
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;
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) {
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;
}
#include "platform.h"
#include "protocols.h"
+#include "sockaddr.h"
#include "construct_unix.h"
#include "deconstruct_unix.h"
#include "timeval.h"
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;
}
}
}
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;
}
}
}
--- /dev/null
+#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;
+}
--- /dev/null
+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);