Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Jun 2015 06:36:55 GMT
From:      btw@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r287032 - soc2015/btw/head/tools/tools/mq-testing/udp
Message-ID:  <201506130636.t5D6atfL056527@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: btw
Date: Sat Jun 13 06:36:54 2015
New Revision: 287032
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287032

Log:
  Extend mq-testing/udp to support IPv6.

Modified:
  soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c
  soc2015/btw/head/tools/tools/mq-testing/udp/server.c

Modified: soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c
==============================================================================
--- soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c	Sat Jun 13 05:55:26 2015	(r287031)
+++ soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c	Sat Jun 13 06:36:54 2015	(r287032)
@@ -45,29 +45,32 @@
 #include <net/ethernet.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#include <netinet/ip6.h>
 #include <netinet/udp.h>
 #include <arpa/inet.h>
 
 #include "common.h"
 
-/*
- * TODO:
- * #1. Add supports for IPv6;
- */
 #define IFCONFIG_BIN  "/sbin/ifconfig "
-#define IFCONFIG_ARGS "%s inet %s"
+#define IFCONFIG_ARGS "%s %s %s up"
 
 static char vmedev[MAXPATHLEN];
 static uint8_t vmeif_ether[ETHER_ADDR_LEN];
-static in_addr_t vmeif_ip;
+static char vmeif_ipstr[INET6_ADDRSTRLEN] = "";
+static struct in6_addr vmeif_ip6;
+static struct in_addr vmeif_ip;
 
 static char vmeif_name[IFNAMSIZ] = "vme0";
-static char vmeif_ipstr[256] = "192.168.10.1";
+static char vmeif_ipstr_v4[] = "192.168.10.1";
+static char vmeif_ipstr_v6[] = "fec0::1";
 static char *payload = "hello, world!";
 static int pktsize = 100;
 static int quiet = 0;
 static int cpu = -1;
 static uint64_t total_sent = 0;
+static int ipversion = 4;
+
+static void (*build_udp_packet)(uint8_t *, int);
 
 /* The checksum function is taken from tools/tools/netmap/pkt-gen.c */
 static uint16_t
@@ -109,7 +112,7 @@
 }
 
 static void
-build_udp_packet(uint8_t *buf, int pkt_size)
+build_udp_packet_v4(uint8_t *buf, int pkt_size)
 {
 	struct ether_header *eh = (struct ether_header *)buf;
 	struct ip *ip = (struct ip *)(eh + 1);
@@ -135,7 +138,7 @@
 	ip->ip_ttl = IPDEFTTL;
 	ip->ip_p = IPPROTO_UDP;
 	ip->ip_src.s_addr = htonl(0x0a000001 + (rand() % 0xfffffe));
-	ip->ip_dst.s_addr = vmeif_ip;
+	ip->ip_dst = vmeif_ip;
 
 	ip->ip_sum = 0;
 	ip->ip_sum = wrapsum(checksum(ip, sizeof(*ip), 0));
@@ -149,6 +152,42 @@
 	    pkt_size - (sizeof(*eh) + sizeof(*ip) + sizeof(*udp))));
 }
 
+static void
+build_udp_packet_v6(uint8_t *buf, int pkt_size)
+{
+	struct ether_header *eh = (struct ether_header *)buf;
+	struct ip6_hdr *ip6 = (struct ip6_hdr *)(eh + 1);
+	struct udphdr *udp = (struct udphdr *)(ip6 + 1);
+	char *data = (char *)(udp + 1);
+
+	/* Just fake an address */
+	eh->ether_shost[0] = 0x01;
+	eh->ether_shost[1] = 0xbd;
+	eh->ether_shost[2] = 0xbc;
+	eh->ether_shost[3] = 0x4d;
+	eh->ether_shost[4] = 0xfb;
+	eh->ether_shost[5] = 0xfb;
+	memcpy(eh->ether_dhost, vmeif_ether, ETHER_ADDR_LEN);
+	eh->ether_type = htons(ETHERTYPE_IPV6);
+
+	ip6->ip6_flow = 0;
+	ip6->ip6_plen = htons(pkt_size - sizeof(*eh) - sizeof(*ip6));
+	ip6->ip6_nxt = IPPROTO_UDP;
+	ip6->ip6_hlim = 0xff;
+	ip6->ip6_vfc |= IPV6_VERSION;
+	ip6->ip6_dst = vmeif_ip6;
+	for (int i = 0; i < 16; i++)
+		ip6->ip6_src.s6_addr[i] = rand();
+
+	udp->uh_sport = htons(1 + rand() % 65535);
+	udp->uh_dport = htons(SERVER_PORT);
+	udp->uh_ulen = htons(pkt_size - sizeof(*eh) - sizeof(*ip6));
+	udp->uh_sum = 1;
+
+	memcpy(data, payload, min(strlen(payload) + 1,
+	    pkt_size - (sizeof(*eh) + sizeof(*ip6) + sizeof(*udp))));
+}
+
 static int
 get_ifaddr(const char *ifname, uint8_t *ether_addr)
 {
@@ -213,7 +252,7 @@
 	uint8_t *buf;
 	int ch;
 
-	while ((ch = getopt(argc, argv, "a:b:i:l:p:q")) != -1) {
+	while ((ch = getopt(argc, argv, "a:b:i:l:p:q46")) != -1) {
 		switch (ch) {
 		case 'a':
 			strlcpy(vmeif_ipstr, optarg, sizeof(vmeif_ipstr));
@@ -233,15 +272,31 @@
 		case 'q':
 			quiet = 1;
 			break;
+		case '4':
+			ipversion = 4;
+			break;
+		case '6':
+			ipversion = 6;
+			break;
 		default:
 			usage(argv[0]);
 			break;
 		}
 	}
 
+	if (vmeif_ipstr[0] == '\0') {
+		if (ipversion == 4)
+			strlcpy(vmeif_ipstr, vmeif_ipstr_v4,
+			    sizeof(vmeif_ipstr));
+		else
+			strlcpy(vmeif_ipstr, vmeif_ipstr_v6,
+			    sizeof(vmeif_ipstr));
+	}
+
 	if (!quiet) {
 		printf("vme name: %s\n", vmeif_name);
-		printf("vme ip: %s\n", vmeif_ipstr);
+		printf("IP version: %d\n", ipversion);
+		printf("vme IP: %s\n", vmeif_ipstr);
 		printf("packet size: %d\n", pktsize);
 		printf("payload: %s\n", payload);
 		if (cpu != -1)
@@ -262,16 +317,34 @@
 		exit(EXIT_FAILURE);
 	}
 
-	snprintf(cmd, sizeof(cmd), IFCONFIG_BIN IFCONFIG_ARGS, vmeif_name,
-	    vmeif_ipstr);
-	if (system(cmd) != 0) {
-		fprintf(stderr, "Failed to setup %s\n", vmeif_name);
+	switch (ipversion) {
+	case 4:
+		if (inet_pton(AF_INET, vmeif_ipstr, &vmeif_ip) != 1) {
+			fprintf(stderr, "Malformed address %s specified\n",
+			    vmeif_ipstr);
+			exit(EXIT_FAILURE);
+		}
+		snprintf(cmd, sizeof(cmd), IFCONFIG_BIN IFCONFIG_ARGS,
+		    vmeif_name, "inet", vmeif_ipstr);
+		build_udp_packet = build_udp_packet_v4;
+		break;
+	case 6:
+		if (inet_pton(AF_INET6, vmeif_ipstr, &vmeif_ip6) != 1) {
+			fprintf(stderr, "Malformed address %s specified\n",
+			    vmeif_ipstr);
+			exit(EXIT_FAILURE);
+		}
+		snprintf(cmd, sizeof(cmd), IFCONFIG_BIN IFCONFIG_ARGS,
+		    vmeif_name, "inet6", vmeif_ipstr);
+		build_udp_packet = build_udp_packet_v6;
+		break;
+	default:
+		fprintf(stderr, "Only support ipv4 and ipv6.\n");
 		exit(EXIT_FAILURE);
 	}
 
-	if ((vmeif_ip = inet_addr(vmeif_ipstr)) == INADDR_NONE) {
-		fprintf(stderr, "Malformed address %s specified\n",
-		    vmeif_ipstr);
+	if (system(cmd) != 0) {
+		fprintf(stderr, "Failed to setup %s\n", vmeif_name);
 		exit(EXIT_FAILURE);
 	}
 

Modified: soc2015/btw/head/tools/tools/mq-testing/udp/server.c
==============================================================================
--- soc2015/btw/head/tools/tools/mq-testing/udp/server.c	Sat Jun 13 05:55:26 2015	(r287031)
+++ soc2015/btw/head/tools/tools/mq-testing/udp/server.c	Sat Jun 13 06:36:54 2015	(r287032)
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <err.h>
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -38,6 +39,7 @@
 
 #include "common.h"
 
+static int ipversion = 4;
 static int verbose = 0;
 
 static void
@@ -47,17 +49,49 @@
 	exit(EXIT_FAILURE);
 }
 
+static char *
+addr2str(int af, struct sockaddr *addr)
+{
+	static char msg[1024];
+	char addrstr[INET6_ADDRSTRLEN];
+
+	switch (af) {
+	case AF_INET:
+		snprintf(msg, sizeof(msg), "%s:%d",
+		    inet_ntoa(((struct sockaddr_in *)addr)->sin_addr),
+		    ntohs(((struct sockaddr_in *)addr)->sin_port));
+		break;
+	case AF_INET6:
+		snprintf(msg, sizeof(msg), "%s:%d",
+		    inet_ntop(AF_INET6,
+			&((struct sockaddr_in6 *)addr)->sin6_addr,
+			addrstr, sizeof(addrstr)),
+		    ntohs(((struct sockaddr_in6 *)addr)->sin6_port));
+		break;
+	}
+
+	return (msg);
+}
+
 int
 main(int argc, char **argv)
 {
-	int sd;
-	struct sockaddr_in lsin, from;
-	socklen_t length;
+	int sd, af;
+	struct sockaddr *lsin, *from;
+	struct sockaddr_in lsin4, from4;
+	struct sockaddr_in6 lsin6, from6;
+	socklen_t addrlen, length;
 	char msg[BUFSIZ];
 	int n, ch, i;
 
-	while ((ch = getopt(argc, argv, "v")) != -1) {
+	while ((ch = getopt(argc, argv, "46v")) != -1) {
 		switch (ch) {
+		case '4':
+			ipversion = 4;
+			break;
+		case '6':
+			ipversion = 6;
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -67,33 +101,43 @@
 		}
 	}
 
-	sd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sd < 0) {
-		perror("socket");
-		exit(EXIT_FAILURE);
+	if (ipversion == 4) {
+		af = AF_INET;
+		lsin = (struct sockaddr *)&lsin4;
+		from = (struct sockaddr *)&from4;
+		addrlen = sizeof(struct sockaddr_in);
+
+		memset(&lsin4, 0, sizeof(lsin4));
+		lsin4.sin_family = AF_INET;
+		lsin4.sin_addr.s_addr = INADDR_ANY;
+		lsin4.sin_port = htons(SERVER_PORT);
+	} else {
+		af = AF_INET6;
+		lsin = (struct sockaddr *)&lsin6;
+		from = (struct sockaddr *)&from6;
+		addrlen = sizeof(struct sockaddr_in6);
+
+		memset(&lsin6, 0, sizeof(lsin6));
+		lsin6.sin6_family = AF_INET6;
+		lsin6.sin6_addr = in6addr_any;
+		lsin6.sin6_port = htons(SERVER_PORT);
 	}
 
-	memset(&lsin, 0, sizeof(lsin));
-	lsin.sin_family = AF_INET;
-	lsin.sin_addr.s_addr = INADDR_ANY;
-	lsin.sin_port = htons(SERVER_PORT);
-	if (bind(sd, (struct sockaddr *)&lsin, sizeof(lsin)) < 0) {
-		perror("bind");
-		exit(EXIT_FAILURE);
-	}
+	sd = socket(af, SOCK_DGRAM, 0);
+	if (sd < 0)
+		err(EXIT_FAILURE, "socket");
+
+	if (bind(sd, lsin, addrlen) < 0)
+		err(EXIT_FAILURE, "bind");
 
 	while (1) {
-		length = sizeof(from);
-		n = recvfrom(sd, msg, sizeof(msg), 0,
-		    (struct sockaddr *)&from, &length);
-		if (n < 0) {
-			perror("recvfrom");
-			exit(EXIT_FAILURE);
-		}
+		length = addrlen;
+		n = recvfrom(sd, msg, sizeof(msg), 0, from, &length);
+		if (n < 0)
+			err(EXIT_FAILURE, "recvfrom");
 
 		if (verbose) {
-			printf("from=%s:%d len=%d  ", inet_ntoa(from.sin_addr),
-			    ntohs(from.sin_port), n);
+			printf("from=%s len=%d  ", addr2str(af, from), n);
 			for (i = 0; i < n && msg[i]; i++) {
 				if (isprint(msg[i]))
 					printf("%c", msg[i]);



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