Date: Sat, 15 Aug 2009 11:56:51 GMT From: Fang Wang <fangwang@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167355 for review Message-ID: <200908151156.n7FBupLV051996@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167355 Change 167355 by fangwang@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); } +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908151156.n7FBupLV051996>