PERFORCE change 167355 for review

Fang Wang fangwang at FreeBSD.org
Sat Aug 15 11:56:52 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=167355

Change 167355 by fangwang at fangwang_utobsd on 2009/08/15 11:56:45

	complete tcputo regression test code.

Affected files ...

.. //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/tcputo.c#6 edit

Differences ...

==== //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/tcputo.c#6 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/tools/regression/netinet/tcputo/tcputo.c 2009/7/4 02:54:36 fw $
+ * $FreeBSD: src/tools/regression/netinet/tcputo/tcputo.c 2009/8/11 02:54:36 fw $
  */
 
 #include <sys/types.h>
@@ -32,8 +32,7 @@
 #include <net/ethernet.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
-//#include <netinet/tcp.h>
-#include "tcp.h"
+#include <netinet/tcp.h>
 
 #include <arpa/inet.h>
 
@@ -49,36 +48,29 @@
 #include <pcap.h>
 #include <pthread.h>
 
-static void
-usage(void)
-{
-
-	fprintf(stderr, "tcpconnect [-e] server port [user timeout]\n");
-	fprintf(stderr, "tcpconnect [-e] client ip port [user timeout]\n");
-	exit(-1);
-}
-
 #define	SIZE_ETHERNET	sizeof(struct ether_header)
 
 struct tcprxt {
 	struct timeval ts;
-	u_int length;
 	u_int th_off;
 	tcp_seq th_seq;
 	tcp_seq th_ack;
+	u_short	th_win;
 	u_char th_flags;
 };
 
 #define	MAX_RXT	200
 
-struct tcprxt rxts[MAX_RXT];
+struct tcprxt	rxts[MAX_RXT];
+int	uto_intervals[13] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
+
 
 void
 parse_packet(u_char *args, const struct pcap_pkthdr *pkt_header, const u_char *packet)
 {
-	const struct ip *ip;			/* The IP header */
-	const struct tcphdr *tcp;		/* The TCP header */
-	const u_char *tcpopt;			/* Tcp option */
+	const struct ip *ip;
+	const struct tcphdr *tcp;
+	const u_char *tcpopt;
 	struct tcprxt rxt;
 	u_int opt, optlen;
 	u_int hlen;
@@ -111,11 +103,30 @@
 		optlen = *tcpopt++;
 		if (opt == TCPOPT_UTO) {
 			u_int uto = htons(*(u_short *)tcpopt);
+			struct tm *p;
 			if (uto & 1)
 				uto = (uto >> 1) * 60;
 			else
 				uto >>= 1;
-			printf("Time:%u.%u Seq:%u Ack:%u Win:%u Length:%u UTO:%u\n", pkt_header->ts.tv_sec, pkt_header->ts.tv_usec, htonl(tcp->th_seq), htonl(tcp->th_ack), htons(tcp->th_win), length, uto);
+			p = localtime(&pkt_header->ts.tv_sec);
+			printf("uto packet: ");
+			printf("%02d:%02d:%02d.%-6u ", p->tm_hour, p->tm_min, p->tm_sec,
+				pkt_header->ts.tv_usec);
+			printf("%s.%d > ", inet_ntoa(ip->ip_src), htons(tcp->th_sport));
+			printf("%s.%d, ", inet_ntoa(ip->ip_dst), htons(tcp->th_dport));
+			printf("flags [");
+			if (tcp->th_flags & TH_SYN)
+				printf("S");
+			if (tcp->th_flags & TH_RST)
+				printf("R");
+			if (tcp->th_flags & TH_PUSH)
+				printf("P");
+			if (tcp->th_flags & TH_ACK)
+				printf(".");
+			if (tcp->th_flags & TH_URG)
+				printf("U");
+			printf("], ");
+			printf("uto %u, win %u, length %u\n", uto, htons(tcp->th_win), length);
 		}
 		hlen -= optlen - 1;
 		tcpopt += optlen - 2;
@@ -123,49 +134,86 @@
 	if (length > 0 || tcp->th_flags & TH_RST) {
 		memset(&rxt, 0, sizeof(rxt));
 		memcpy(&rxt.ts, &pkt_header->ts, sizeof(rxt.ts));
-		rxt.length = length;
+		rxt.th_win = htons(tcp->th_win);
 		rxt.th_off = tcp->th_off;
-		rxt.th_ack = tcp->th_ack;
-		rxt.th_seq = tcp->th_seq;
+		rxt.th_ack = htonl(tcp->th_ack);
+		rxt.th_seq = htonl(tcp->th_seq);
 		rxt.th_flags = tcp->th_flags;
 		memcpy(&rxts[0], &rxts[1], sizeof(struct tcprxt) * (MAX_RXT - 1));
 		memcpy(&rxts[MAX_RXT - 1], &rxt, sizeof(rxt));
 	}
 }
 
-void
+void *
 dump_packet(void *arg)
 {
-	pcap_t *handle;			/* Session handle */
-	char *dev;			/* The device to sniff on */
-	//char dev[] = "le1";			/* The device to sniff on */
-	char errbuf[PCAP_ERRBUF_SIZE];	/* Error string */
-	struct bpf_program fp;		/* The compiled filter */
-	char filter_exp[] = "tcp port 8000";	/* The filter expression */
-	bpf_u_int32 mask;		/* Our netmask */
-	bpf_u_int32 net;		/* Our IP */
-	struct pcap_pkthdr header;	/* The header that pcap gives us */
-	const u_char *packet;		/* The actual packet */
+	pcap_t *handle;
+	char errbuf[PCAP_ERRBUF_SIZE];
+	struct bpf_program fp;
+	char filter_exp[128];
+	bpf_u_int32 mask;
+	bpf_u_int32 net;
+	struct pcap_pkthdr header;
+	const u_char *packet;
+	struct sockaddr_in srcaddr, dstaddr, *devaddrp;
+	int optlen;
+	pcap_if_t *alldevsp, *devp;
+	pcap_addr_t *addrp;
+	int flag;
+
+	optlen = sizeof(srcaddr);
+	if (getsockname(*((int *)arg), (struct sockaddr *)&srcaddr, &optlen) == -1)
+		err(-1, "getsockname");
+	optlen = sizeof(dstaddr);
+	if (getpeername(*((int *)arg), (struct sockaddr *)&dstaddr, &optlen) == -1)
+		err(-1, "getsockname");
+
+	if (pcap_findalldevs(&alldevsp, errbuf) == -1) {
+		fprintf(stderr, "Couldn't get all device: %s\n", errbuf);
+		exit(-1);
+	}
+
+	devp = alldevsp;
+	flag = 1;
+	while (devp != NULL) {
+		addrp = devp->addresses;
+		while (addrp != NULL && flag) {
+			devaddrp = (struct sockaddr_in *)addrp->addr;
+			if (!memcmp(&devaddrp->sin_addr, &srcaddr.sin_addr, sizeof(srcaddr.sin_addr))) {
+				flag = 0;
+				break;
+			}
+			addrp = addrp->next;
+		}
+		if (!flag)
+			break;
+		devp = devp->next;
+	}
 
-	/* Define the device */
-	dev = pcap_lookupdev(errbuf);
-	if (dev == NULL) {
-		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
+	if (devp == NULL) {
+		fprintf(stderr, "Couldn't find using device\n");
 		exit(-1);
 	}
-	/* Find the properties for the device */
-	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
-		fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
+
+	if (pcap_lookupnet(devp->name, &net, &mask, errbuf) == -1) {
+		fprintf(stderr, "Couldn't get netmask for device %s: %s\n", devp->name, errbuf);
 		net = 0;
 		mask = 0;
 	}
-	/* Open the session in promiscuous mode */
-	handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
+
+	handle = pcap_open_live(devp->name, BUFSIZ, 1, 1000, errbuf);
 	if (handle == NULL) {
-		fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
+		fprintf(stderr, "Couldn't open device %s: %s\n", devp->name, errbuf);
 		exit(-1);
 	}
-	/* Compile and apply the filter */
+
+	pcap_freealldevs(alldevsp);
+
+	snprintf(filter_exp, sizeof(filter_exp),
+		"(tcp src port %d and dst port %d) or (tcp src port %d and dst port %d)",
+		ntohs(srcaddr.sin_port), ntohs(dstaddr.sin_port),
+		ntohs(dstaddr.sin_port), ntohs(srcaddr.sin_port));
+
 	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
 		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
 		exit(-1);
@@ -174,8 +222,11 @@
 		fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
 		exit(-1);
 	}
+
 	pcap_loop(handle, -1, parse_packet, NULL);
 	pcap_close(handle);
+	
+	return NULL;
 }
 
 void print_result()
@@ -186,29 +237,68 @@
 
 	rxt_seq = rxts[MAX_RXT - 2].th_seq;
 	for (last = -1, rxt_nr = 0, i = 0; i < MAX_RXT; i++) {
-		if (rxts[i].th_seq == rxt_seq || rxts[i].th_flags & TH_RST) {
+		if (rxts[i].th_seq && (rxts[i].th_seq == rxt_seq || rxts[i].th_flags & TH_RST)) {
 			if (rxts[i].th_flags & TH_RST)
 				printf("reset packet, ");
 			else if (rxt_nr)
-				printf("retransmit %d, ", rxt_nr);
+				printf("retransmit %02d, ", rxt_nr);
 			else if (!rxt_nr)
 				printf("send packet, ");
 			p = localtime(&rxts[i].ts.tv_sec);
-			printf("time %d:%d:%d.%-6u, ", p->tm_hour, p->tm_min, p->tm_sec, rxts[i].ts.tv_usec);
-			printf("seq %u, ack %u, ", rxts[i].th_seq, rxts[i].th_ack);
+			printf("%02d:%02d:%02d.%-6u ", p->tm_hour, p->tm_min, p->tm_sec, rxts[i].ts.tv_usec);
 			if (last != -1) {
 				if (rxts[i].ts.tv_usec < rxts[last].ts.tv_usec)
-					printf("interval %u.%-6u, ", rxts[i].ts.tv_sec - rxts[last].ts.tv_sec - 1, 1000000 + rxts[i].ts.tv_usec - rxts[last].ts.tv_usec);
+					printf("(%2u.%-6u) ", rxts[i].ts.tv_sec - rxts[last].ts.tv_sec - 1, 
+						1000000 + rxts[i].ts.tv_usec - rxts[last].ts.tv_usec);
 				else
-					printf("interval %u.%-6u, ", rxts[i].ts.tv_sec - rxts[last].ts.tv_sec, rxts[i].ts.tv_usec - rxts[last].ts.tv_usec);
+					printf("(%2u.%-6u) ", rxts[i].ts.tv_sec - rxts[last].ts.tv_sec, 
+						rxts[i].ts.tv_usec - rxts[last].ts.tv_usec);
 			}
-			printf("length %u\n", rxts[i].length);
+			printf("seq %u, ack %u, ", rxts[i].th_seq, rxts[i].th_ack);
+			printf("win %u\n", rxts[i].th_win);
 			last = i;
 			rxt_nr++;
 		}
 	}
 }
 
+int
+print_uto_status(int sock, int print)
+{
+	static struct tcputo tu = {0, 0};
+	int default_uto = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 64 + 64 + 64 + 64 + 64 + 64;
+	int optlen;
+	int utoval;
+
+	optlen = sizeof(tu);
+	(void)getsockopt(sock, IPPROTO_TCP, TCP_UTO, &tu, &optlen);
+	if (print) {
+		if (tu.flags & ENABLE_UTO) {
+			printf("tcputo: enabled, ");
+			if (tu.flags & STORE_UTO) {
+				printf("user timeout(changed): %d seconds\n", tu.uto);
+				utoval = tu.uto;
+			} else {
+				printf("user timeout(default): %d seconds\n", default_uto);
+				utoval = default_uto;
+			}
+		} else {
+			printf("tcputo: disabled, default timeout: %d seconds\n", default_uto);
+			utoval = default_uto;
+		}
+	}
+
+	return utoval;
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr, "tcpconnect server port [uto [timeout seconds]]\n");
+	fprintf(stderr, "tcpconnect client ip port [uto [timeout seconds]]\n");
+	exit(-1);
+}
+
 static int
 tcputo_timer(void)
 {
@@ -219,8 +309,7 @@
 	if (start_time == 0) {
 		time(&start_time);
 		interval = 0;
-	}
-	else {
+	} else {
 		time(&end_time);
 		interval = end_time - start_time;
 		start_time = 0;
@@ -235,14 +324,14 @@
 	int listen_sock, accept_sock;
 	struct sockaddr_in sin;
 	char *dummy;
-	char buf[16*1024];
+	char buf[8*1024];
 	long port;
 	int user_timeout;
 	int optval;
 	struct tcputo uto;
 	pthread_t tid;
 
-	if (argc != 1 && argc != 2)
+	if (argc < 1 && argc > 3)
 		usage();
 
 	bzero(&sin, sizeof(sin));
@@ -269,26 +358,42 @@
 		err(-1, "listen");
 
 	accept_sock = accept(listen_sock, NULL, NULL);
+	if (accept_sock == -1)
+		err(-1, "accept");
+	close(listen_sock);
+
+	if (pthread_create(&tid, NULL, dump_packet, (void *)&accept_sock))
+		err(-1, "create thread");
+
+	if (argc >= 2) {
+		memset(&uto, 0, sizeof(uto));
+		if (!strcmp(argv[1], "uto")) {
+			uto.flags |= ENABLE_UTO;
+			uto.flags |= ENABLE_CHANGE;
+		} else
+			usage();
+		if (argc == 3) {
+			uto.uto = strtoul(argv[2], &dummy, 10);
+			if (uto.uto <= 0 || *dummy != '\0')
+				usage();
+			uto.flags |= STORE_UTO;
+			uto.flags &= ~ENABLE_CHANGE;
+		}
+		if (setsockopt(accept_sock, IPPROTO_TCP, TCP_UTO, &uto, sizeof(uto)) == -1)
+			err(-1, "setsockopt");
+	}
+
 	optval = 4*1024;
 	if (setsockopt(accept_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1)
 		err(-1, "setsockopt");
-	uto.flags = ENABLE_UTO;
-	if (argc == 2) {
-		uto.uto = atoi(argv[1]);
-		uto.flags |= STORE_UTO;
-	}
-	if (setsockopt(accept_sock, IPPROTO_TCP, TCP_UTO, &uto, sizeof(uto)) == -1)
-		err(-1, "setsockopt");
-	close(listen_sock);
-	if (pthread_create(&tid, NULL, dump_packet, NULL))
-		err(-1, "create thread");
+
 	while(1) {
 		sleep(1);
-		printf("server again %d\n", optval++);
-		(void)recv(accept_sock, buf, 16*1024, MSG_DONTWAIT);
+		while(recv(accept_sock, buf, 8*1024, MSG_DONTWAIT) > 0);
 		(void)tcputo_timer();
-		if (send(accept_sock, buf, 16*1024, MSG_NOSIGNAL) >= 0) {
+		if (send(accept_sock, buf, 8*1024, MSG_NOSIGNAL) >= 0) {
 			(void)tcputo_timer();
+			print_uto_status(accept_sock, 0);
 			continue;
 		}
 		user_timeout = tcputo_timer();
@@ -298,6 +403,7 @@
 	/* wait for the reset packet to be captured */
 	sleep(1);
 	pthread_kill(tid, SIGTERM);
+
 	close(accept_sock);
 }
 
@@ -307,14 +413,14 @@
 	struct sockaddr_in sin;
 	long port;
 	char *dummy;
-	char buf[16*1024];
+	char buf[8*1024];
 	int sock;
 	int user_timeout;
-	int optval = 4*1024;
+	int optval;
 	struct tcputo uto;
 	pthread_t tid;
 
-	if (argc != 2 && argc != 3)
+	if (argc < 2 && argc > 4)
 		usage();
 
 	bzero(&sin, sizeof(sin));
@@ -327,30 +433,45 @@
 	if (port < 1 || port > 65535 || *dummy != '\0')
 		usage();
 	sin.sin_port = htons(port);
-
 	sock = socket(PF_INET, SOCK_STREAM, 0);
 	if (sock == -1)
 		err(-1, "socket");
+
+	optval = 4*1024;
 	if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1)
 		err(-1, "setsockopt");
-	
-	if (argc == 3) {
-		uto.uto = atoi(argv[2]);
-		uto.flags = ENABLE_UTO | STORE_UTO;
+
+	if (argc >= 3) {
+		memset(&uto, 0, sizeof(uto));
+		if (!strcmp(argv[2], "uto")) {
+			uto.flags |= ENABLE_UTO;
+			uto.flags |= ENABLE_CHANGE;
+		} else
+			usage();
+		if (argc == 4) {
+			uto.uto = strtoul(argv[3], &dummy, 10);
+			if (uto.uto <= 0 || *dummy != '\0')
+				usage();
+			uto.flags |= STORE_UTO;
+			uto.flags &= ~ENABLE_CHANGE;
+		}
 		if (setsockopt(sock, IPPROTO_TCP, TCP_UTO, &uto, sizeof(uto)) == -1)
 			err(-1, "setsockopt");
 	}
+
 	if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
 		err(-1, "connect");
-	if (pthread_create(&tid, NULL, dump_packet, NULL))
+
+	if (pthread_create(&tid, NULL, dump_packet, (void *)&sock))
 		err(-1, "create thread");
+
 	while (1) {
 		sleep(1);
-		printf("client again %d\n", optval++);
-		(void)recv(sock, buf, 16*1024, MSG_DONTWAIT);
+		while(recv(sock, buf, 8*1024, MSG_DONTWAIT) > 0);
 		(void)tcputo_timer();
-		if (send(sock, buf, 16*1024, MSG_NOSIGNAL) > 0) {
+		if (send(sock, buf, 8*1024, MSG_NOSIGNAL) > 0) {
 			(void)tcputo_timer();
+			print_uto_status(sock, 0);
 			continue;
 		}
 		user_timeout = tcputo_timer();
@@ -360,12 +481,15 @@
 	/* wait for the reset packet to be captured */
 	sleep(1);
 	pthread_kill(tid, SIGTERM);
+
 	close(sock);
 }
 
 int
 main(int argc, char *argv[])
 {
+	int utoval;
+
 	if (argc < 2)
 		usage();
 
@@ -375,6 +499,10 @@
 		tcputo_client(argc - 2, argv + 2);
 	else
 		usage();
+	
+	print_uto_status(-1, 1);
 	print_result();
+
 	exit(0);
 }
+


More information about the p4-projects mailing list