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>