svn commit: r227345 - in head/tools/tools/netrate: netblast netreceive netsend

Olivier Houchard cognet at FreeBSD.org
Tue Nov 8 17:23:44 UTC 2011


Author: cognet
Date: Tue Nov  8 17:23:43 2011
New Revision: 227345
URL: http://svn.freebsd.org/changeset/base/227345

Log:
  Add IPv6 support to netblast/netsend/netreceive
  
  PR:		bin/161368
  Submitted by:	Olivier Cochard-Labbe <olivier AT cochard doT me>

Modified:
  head/tools/tools/netrate/netblast/netblast.c
  head/tools/tools/netrate/netreceive/netreceive.c
  head/tools/tools/netrate/netsend/netsend.c

Modified: head/tools/tools/netrate/netblast/netblast.c
==============================================================================
--- head/tools/tools/netrate/netblast/netblast.c	Tue Nov  8 17:08:12 2011	(r227344)
+++ head/tools/tools/netrate/netblast/netblast.c	Tue Nov  8 17:23:43 2011	(r227345)
@@ -32,13 +32,13 @@
 #include <sys/time.h>
 
 #include <netinet/in.h>
-
-#include <arpa/inet.h>
+#include <netdb.h>			/* getaddrinfo */
 
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>			/* close */
 
 static void
 usage(void)
@@ -141,26 +141,25 @@ blast_loop(int s, long duration, u_char 
 int
 main(int argc, char *argv[])
 {
-	long payloadsize, port, duration;
-	struct sockaddr_in sin;
+	long payloadsize, duration;
+	struct addrinfo hints, *res, *res0;
 	char *dummy, *packet;
-	int s;
+	int port, s, error;
+	const char *cause = NULL;
 
 	if (argc != 5)
 		usage();
 
-	bzero(&sin, sizeof(sin));
-	sin.sin_len = sizeof(sin);
-	sin.sin_family = AF_INET;
-	if (inet_aton(argv[1], &sin.sin_addr) == 0) {
-		perror(argv[1]);
-		return (-1);
-	}
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_DGRAM;
 
 	port = strtoul(argv[2], &dummy, 10);
-	if (port < 1 || port > 65535 || *dummy != '\0')
+	if (port < 1 || port > 65535 || *dummy != '\0') {
+		fprintf(stderr, "Invalid port number: %s\n", argv[2]);
 		usage();
-	sin.sin_port = htons(port);
+		/*NOTREACHED*/
+	}
 
 	payloadsize = strtoul(argv[3], &dummy, 10);
 	if (payloadsize < 0 || *dummy != '\0')
@@ -168,29 +167,55 @@ main(int argc, char *argv[])
 	if (payloadsize > 32768) {
 		fprintf(stderr, "payloadsize > 32768\n");
 		return (-1);
+		/*NOTREACHED*/
 	}
 
 	duration = strtoul(argv[4], &dummy, 10);
-	if (duration < 0 || *dummy != '\0')
+	if (duration < 0 || *dummy != '\0') {
+		fprintf(stderr, "Invalid duration time: %s\n", argv[4]);
 		usage();
+		/*NOTREACHED*/
+	}
 
 	packet = malloc(payloadsize);
 	if (packet == NULL) {
 		perror("malloc");
 		return (-1);
+		/*NOTREACHED*/
 	}
+
 	bzero(packet, payloadsize);
+	error = getaddrinfo(argv[1],argv[2], &hints, &res0);
+	if (error) {
+		perror(gai_strerror(error));
+		return (-1);
+		/*NOTREACHED*/
+	}
+	s = -1;
+	for (res = res0; res; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype, 0);
+		if (s < 0) {
+			cause = "socket";
+			continue;
+		}
 
-	s = socket(PF_INET, SOCK_DGRAM, 0);
-	if (s == -1) {
-		perror("socket");
-		return (-1);
-	}
+		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+			cause = "connect";
+			close(s);
+			s = -1;
+			continue;
+		}
 
-	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-		perror("connect");
+		break;  /* okay we got one */
+	}
+	if (s < 0) {
+		perror(cause);
 		return (-1);
+		/*NOTREACHED*/
 	}
 
+	freeaddrinfo(res0);
+
 	return (blast_loop(s, duration, packet, payloadsize));
+
 }

Modified: head/tools/tools/netrate/netreceive/netreceive.c
==============================================================================
--- head/tools/tools/netrate/netreceive/netreceive.c	Tue Nov  8 17:08:12 2011	(r227344)
+++ head/tools/tools/netrate/netreceive/netreceive.c	Tue Nov  8 17:23:43 2011	(r227345)
@@ -29,14 +29,19 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/poll.h>
 
 #include <netinet/in.h>
+#include <netdb.h>          /* getaddrinfo */
 
 #include <arpa/inet.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>         /* close */
+
+#define MAXSOCK 20
 
 static void
 usage(void)
@@ -49,23 +54,26 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	struct sockaddr_in sin;
+	struct addrinfo hints, *res, *res0;
 	char *dummy, *packet;
-	long port;
-	int s, v;
+	int port;
+	int error, v, i;
+	const char *cause = NULL;
+	int s[MAXSOCK];
+	struct pollfd fds[MAXSOCK];
+	int nsock;
 
 	if (argc != 2)
 		usage();
 
-	bzero(&sin, sizeof(sin));
-	sin.sin_len = sizeof(sin);
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(INADDR_ANY);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_DGRAM;
+	hints.ai_flags = AI_PASSIVE;
 
 	port = strtoul(argv[1], &dummy, 10);
 	if (port < 1 || port > 65535 || *dummy != '\0')
 		usage();
-	sin.sin_port = htons(port);
 
 	packet = malloc(65536);
 	if (packet == NULL) {
@@ -74,27 +82,60 @@ main(int argc, char *argv[])
 	}
 	bzero(packet, 65536);
 
-	s = socket(PF_INET, SOCK_DGRAM, 0);
-	if (s == -1) {
-		perror("socket");
+	error = getaddrinfo(NULL, argv[1], &hints, &res0);
+	if (error) {
+		perror(gai_strerror(error));
 		return (-1);
+		/*NOTREACHED*/
 	}
 
-	v = 128 * 1024;
-	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) < 0) {
-		perror("SO_RCVBUF");
-		return (-1);
-	}
+	nsock = 0;
+	for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
+		s[nsock] = socket(res->ai_family, res->ai_socktype,
+		res->ai_protocol);
+		if (s[nsock] < 0) {
+			cause = "socket";
+			continue;
+		}
+
+		v = 128 * 1024;
+		if (setsockopt(s[nsock], SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) < 0) {
+			cause = "SO_RCVBUF";
+			close(s[nsock]);
+			continue;
+		}
+		if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) {
+			cause = "bind";
+			close(s[nsock]);
+			continue;
+		}
+		(void) listen(s[nsock], 5);
+		fds[nsock].fd = s[nsock];
+		fds[nsock].events = POLLIN;
 
-	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-		perror("bind");
+		nsock++;
+	}
+	if (nsock == 0) {
+		perror(cause);
 		return (-1);
+		/*NOTREACHED*/
 	}
 
 	printf("netreceive listening on UDP port %d\n", (u_short)port);
 
 	while (1) {
-		if (recv(s, packet, 65536, 0) < 0)
-			perror("recv");
+		if (poll(fds, nsock, -1) < 0) 
+			perror("poll");
+		for (i = 0; i > nsock; i++) {
+			if (fds[i].revents & POLLIN) {
+				if (recv(s[i], packet, 65536, 0) < 0)
+					perror("recv");
+			}
+			if ((fds[i].revents &~ POLLIN) != 0)
+				perror("poll");
+		}
 	}
+	
+	/*NOTREACHED*/
+	freeaddrinfo(res0);
 }

Modified: head/tools/tools/netrate/netsend/netsend.c
==============================================================================
--- head/tools/tools/netrate/netsend/netsend.c	Tue Nov  8 17:08:12 2011	(r227344)
+++ head/tools/tools/netrate/netsend/netsend.c	Tue Nov  8 17:23:43 2011	(r227345)
@@ -29,6 +29,7 @@
 #include <sys/endian.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <net/if.h>		/* if_nametoindex() */
 #include <sys/time.h>
 
 #include <netinet/in.h>
@@ -40,13 +41,17 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <netdb.h>
+
 /* program arguments */
 struct _a {
 	int s;
+	int ipv6;
 	struct timespec interval;
 	int port, port_max;
 	long duration;
 	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
 	int packet_len;
 	void *packet;
 };
@@ -179,9 +184,16 @@ timing_loop(struct _a *a)
 	ic = gettimeofday_cycles;
 	cur_port = a->port;
 	if (a->port == a->port_max) {
-		if (connect(a->s, (struct sockaddr *)&a->sin, sizeof(a->sin))) {
-			perror("connect");
-			return (-1);
+		if (a->ipv6) {
+			if (connect(a->s, (struct sockaddr *)&a->sin6, sizeof(a->sin6))) {
+				perror("connect (ipv6)");
+				return (-1);
+			}
+		} else {
+			if (connect(a->s, (struct sockaddr *)&a->sin, sizeof(a->sin))) {
+				perror("connect (ipv4)");
+				return (-1);
+			}
 		}
 	}
 	while (1) {
@@ -215,8 +227,13 @@ timing_loop(struct _a *a)
 			a->sin.sin_port = htons(cur_port++);
 			if (cur_port > a->port_max)
 				cur_port = a->port;
+			if (a->ipv6) {
+			ret = sendto(a->s, a->packet, a->packet_len, 0,
+			    (struct sockaddr *)&a->sin6, sizeof(a->sin6));
+			} else {
 			ret = sendto(a->s, a->packet, a->packet_len, 0,
 				(struct sockaddr *)&a->sin, sizeof(a->sin));
+			}
 		}
 		if (ret < 0)
 			send_errors++;
@@ -254,25 +271,48 @@ main(int argc, char *argv[])
 	long rate, payloadsize, port;
 	char *dummy;
 	struct _a a;	/* arguments */
+	struct addrinfo hints, *res, *ressave;
 
 	bzero(&a, sizeof(a));
 
 	if (argc != 6)
 		usage();
 
-	a.sin.sin_len = sizeof(a.sin);
-	a.sin.sin_family = AF_INET;
-	if (inet_aton(argv[1], &a.sin.sin_addr) == 0) {
-		perror(argv[1]);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+
+	if (getaddrinfo(argv[1], NULL, &hints, &res) != 0) {
+		fprintf(stderr, "Couldn't resolv %s\n", argv[1]);
 		return (-1);
 	}
+	ressave = res;
+	while (res) {
+		if (res->ai_family == AF_INET) {
+			memcpy(&a.sin, res->ai_addr, res->ai_addrlen);
+			a.ipv6 = 0;
+			break;
+		} else if (res->ai_family == AF_INET6) {
+			memcpy(&a.sin6, res->ai_addr, res->ai_addrlen);
+			a.ipv6 = 1;
+			break;
+		} 
+		res = res->ai_next;
+	}
+	if (!res) {
+		fprintf(stderr, "Couldn't resolv %s\n", argv[1]);
+		exit(1);
+	}
+	freeaddrinfo(ressave);
 
 	port = strtoul(argv[2], &dummy, 10);
 	if (port < 1 || port > 65535)
 		usage();
 	if (*dummy != '\0' && *dummy != '-')
 		usage();
-	a.sin.sin_port = htons(port);
+	if (a.ipv6)
+		a.sin6.sin6_port = htons(port);
+	else
+		a.sin.sin_port = htons(port);
 	a.port = a.port_max = port;
 	if (*dummy == '-') {	/* set high port */
 		port = strtoul(dummy + 1, &dummy, 10);
@@ -328,7 +368,10 @@ main(int argc, char *argv[])
 	    "seconds\n", payloadsize, (intmax_t)a.interval.tv_sec,
 	    a.interval.tv_nsec, a.duration);
 
-	a.s = socket(PF_INET, SOCK_DGRAM, 0);
+	if (a.ipv6)
+		a.s = socket(PF_INET6, SOCK_DGRAM, 0);
+	else
+		a.s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (a.s == -1) {
 		perror("socket");
 		return (-1);


More information about the svn-src-head mailing list