Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Oct 2011 14:08:27 GMT
From:      Olivier Cochard-Labbe <olivier@cochard.me>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/161368: [netrate] IPv6 patches for netblast/netsend/netreceive
Message-ID:  <201110071408.p97E8R6O091237@red.freebsd.org>
Resent-Message-ID: <201110071410.p97EA7g9084206@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         161368
>Category:       bin
>Synopsis:       [netrate] IPv6 patches for netblast/netsend/netreceive
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 07 14:10:07 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Olivier Cochard-Labbe
>Release:        -current
>Organization:
BSD Router Project
>Environment:
>Description:
Here are some patches that brings IPv6 support to netrate/[netblast|netsend|netreceive].
There are based on the -current (Revision 226095) code source.

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -ruN netrate.orig/netblast/netblast.c netrate/netblast/netblast.c
--- netrate.orig/netblast/netblast.c	2011-10-07 11:28:43.000000000 +0200
+++ netrate/netblast/netblast.c	2011-10-07 14:55:49.000000000 +0200
@@ -143,8 +143,9 @@
 {
 	long payloadsize, port, duration;
 	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
 	char *dummy, *packet;
-	int s;
+	int s, ipv6;
 
 	if (argc != 5)
 		usage();
@@ -152,15 +153,38 @@
 	bzero(&sin, sizeof(sin));
 	sin.sin_len = sizeof(sin);
 	sin.sin_family = AF_INET;
-	if (inet_aton(argv[1], &sin.sin_addr) == 0) {
+
+	bzero(&sin6, sizeof(sin6));
+    sin6.sin6_len = sizeof(sin6);
+    sin6.sin6_family = AF_INET6;
+
+	if (inet_aton(argv[1], &sin.sin_addr) == 1) {
+		ipv6 = 0;
+	} else if (inet_pton(AF_INET6, argv[1], &sin6.sin6_addr) == 1) {
+		ipv6 = 1;
+		char *i;
+
+		i = strchr(argv[1], '%');
+		if (i != NULL) {
+			sin6.sin6_scope_id = if_nametoindex(i + 1);
+		}
+	} else {
 		perror(argv[1]);
+		fprintf(stderr, "Can't determine IP address type\n");
 		return (-1);
 	}
 
 	port = strtoul(argv[2], &dummy, 10);
-	if (port < 1 || port > 65535 || *dummy != '\0')
+	if (port < 1 || port > 65535 || *dummy != '\0') {
+		fprintf(stderr, "bad port number\n");
 		usage();
-	sin.sin_port = htons(port);
+	}
+
+	if (ipv6) {
+		sin6.sin6_port = htons(port);
+	} else {
+		sin.sin_port = htons(port);
+	}
 
 	payloadsize = strtoul(argv[3], &dummy, 10);
 	if (payloadsize < 0 || *dummy != '\0')
@@ -171,25 +195,39 @@
 	}
 
 	duration = strtoul(argv[4], &dummy, 10);
-	if (duration < 0 || *dummy != '\0')
+	if (duration < 0 || *dummy != '\0') {
+		fprintf(stderr, "bad duration\n");
 		usage();
+	}
 
 	packet = malloc(payloadsize);
 	if (packet == NULL) {
 		perror("malloc");
 		return (-1);
 	}
+
 	bzero(packet, payloadsize);
+	if (ipv6) {
+		s = socket(PF_INET6, SOCK_DGRAM, 0);
+	} else {
+		s = socket(PF_INET, SOCK_DGRAM, 0);
+	}
 
-	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s == -1) {
 		perror("socket");
 		return (-1);
 	}
 
-	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-		perror("connect");
-		return (-1);
+	if (ipv6) {
+		if (connect(s, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
+            perror("ipv6 connect");
+            return (-1);
+        }
+	} else {
+		if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+			perror("ipv4 connect");
+			return (-1);
+		}
 	}
 
 	return (blast_loop(s, duration, packet, payloadsize));
diff -ruN netrate.orig/netreceive/netreceive.c netrate/netreceive/netreceive.c
--- netrate.orig/netreceive/netreceive.c	2011-10-07 15:18:48.000000000 +0200
+++ netrate/netreceive/netreceive.c	2011-10-07 15:45:28.000000000 +0200
@@ -50,9 +50,10 @@
 main(int argc, char *argv[])
 {
 	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
 	char *dummy, *packet;
 	long port;
-	int s, v;
+	int s, s6, v;
 
 	if (argc != 2)
 		usage();
@@ -62,10 +63,16 @@
 	sin.sin_family = AF_INET;
 	sin.sin_addr.s_addr = htonl(INADDR_ANY);
 
+	bzero(&sin6, sizeof(sin6));
+    sin6.sin6_len = sizeof(sin6);
+    sin6.sin6_family = AF_INET6;
+    sin6.sin6_addr = in6addr_any;
+	
 	port = strtoul(argv[1], &dummy, 10);
 	if (port < 1 || port > 65535 || *dummy != '\0')
 		usage();
 	sin.sin_port = htons(port);
+	sin6.sin6_port = htons(port);
 
 	packet = malloc(65536);
 	if (packet == NULL) {
@@ -76,26 +83,43 @@
 
 	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s == -1) {
-		perror("socket");
+		perror("socket (ipv4)");
 		return (-1);
 	}
 
+	s6 = socket(PF_INET6, SOCK_DGRAM, 0);
+    if (s == -1) {
+        perror("socket (ipv6)");
+        return (-1);
+    }
+
 	v = 128 * 1024;
 	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) < 0) {
-		perror("SO_RCVBUF");
+		perror("SO_RCVBUF (ipv4)");
 		return (-1);
 	}
+	if (setsockopt(s6, SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) < 0) {
+        perror("SO_RCVBUF (ipv6)");
+        return (-1);
+    }
 
 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-		perror("bind");
+		perror("bind (ipv4)");
 		return (-1);
 	}
 
+	if (bind(s6, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
+        perror("bind (ipv6)");
+        return (-1);
+    }
+
 	printf("netreceive listening on UDP port %d\n", (u_short)port);
 
 	while (1) {
 		if (recv(s, packet, 65536, 0) < 0)
-			perror("recv");
+			perror("recv (ipv4)");
+		if (recv(s6, packet, 65536, 0) < 0)
+            perror("recv (ipv6)");
 	}
 }
 
Files netrate.orig/netsend/netsend and netrate/netsend/netsend differ
diff -ruN netrate.orig/netsend/netsend.c netrate/netsend/netsend.c
--- netrate.orig/netsend/netsend.c	2011-10-07 14:48:07.000000000 +0200
+++ netrate/netsend/netsend.c	2011-10-07 15:12:49.000000000 +0200
@@ -43,10 +43,12 @@
 /* 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 +181,16 @@
 	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 +224,13 @@
 			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++;
@@ -262,8 +276,24 @@
 
 	a.sin.sin_len = sizeof(a.sin);
 	a.sin.sin_family = AF_INET;
-	if (inet_aton(argv[1], &a.sin.sin_addr) == 0) {
+
+	a.sin6.sin6_len = sizeof(a.sin6);
+    a.sin6.sin6_family = AF_INET6;
+
+	if (inet_aton(argv[1], &a.sin.sin_addr) == 1) {
+		a.ipv6 = 0;
+	} else if (inet_pton(AF_INET6, argv[1], &a.sin6.sin6_addr) == 1) {
+		a.ipv6 = 1;
+		char *i;
+
+        i = strchr(argv[1], '%');
+        if (i != NULL) {
+            a.sin6.sin6_scope_id = if_nametoindex(i + 1);
+        }
+
+	} else {
 		perror(argv[1]);
+		fprintf(stderr, "Can't determine IP address type\n");
 		return (-1);
 	}
 
@@ -272,7 +302,11 @@
 		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 +362,11 @@
 	    "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);


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110071408.p97E8R6O091237>