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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to