#include <arpa/inet.h>
#include <errno.h>
#include <getopt.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <sys/resource.h>
#include "client.h"
#include "logging.h"
#include "server.h"
-static int parse_address(const char* string, struct in6_addr* address6) {
- // Try parsing this address
- int r = inet_pton(AF_INET6, string, address6);
-
- // Success!
- if (r == 1)
- return 0;
-
- // Try parsing this as an IPv4 address
- struct in_addr address4;
- r = inet_pton(AF_INET, string, &address4);
- if (r == 1) {
- // Convert to IPv6-mapped address
- address6->s6_addr32[0] = htonl(0x0000);
- address6->s6_addr32[1] = htonl(0x0000);
- address6->s6_addr32[2] = htonl(0xffff);
- address6->s6_addr32[3] = address4.s_addr;
-
- return 0;
+static int parse_address(struct fireperf_config* conf, const char* string, struct in6_addr* address6) {
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ };
+
+ struct addrinfo* results;
+
+ int r = getaddrinfo(string, NULL, &hints, &results);
+ if (r) {
+ ERROR(conf, "getaddrinfo() failed: %s\n", gai_strerror(r));
+ return 1;
}
- // Could not parse this
- return 1;
+ for (struct addrinfo* result = results; result; result = result->ai_next) {
+ address6 = malloc(result->ai_addrlen);
+ if (!address6)
+ return 1;
+
+ memcpy(address6, result->ai_addr, result->ai_addrlen);
+ break;
+ }
+
+ freeaddrinfo(results);
+
+ return 0;
}
static int set_limits(struct fireperf_config* conf) {
conf->mode = FIREPERF_MODE_CLIENT;
// Parse the given IP address
- int r = parse_address(optarg, &conf->address);
+ int r = parse_address(conf, optarg, &conf->address);
if (r) {
fprintf(stderr, "Could not parse IP address %s\n", optarg);
return 2;