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