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>