socsvn commit: r287032 - soc2015/btw/head/tools/tools/mq-testing/udp
btw at FreeBSD.org
btw at FreeBSD.org
Sat Jun 13 06:36:56 UTC 2015
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]);
More information about the svn-soc-all
mailing list