r4775 - developers/werner/owping

werner at docs.openmoko.org werner at docs.openmoko.org
Sun Nov 9 20:39:21 CET 2008


Author: werner
Date: 2008-11-09 20:39:20 +0100 (Sun, 09 Nov 2008)
New Revision: 4775

Modified:
   developers/werner/owping/README
   developers/werner/owping/owping.c
   developers/werner/owping/owping.h
   developers/werner/owping/rx.c
   developers/werner/owping/tx.c
Log:
Make it a bit more convenient to use.

- the host can now be by specified by name
- new option  -p port  to set the port number by name or number
- receiver prints statistics if interrupted by SIGINT



Modified: developers/werner/owping/README
===================================================================
--- developers/werner/owping/README	2008-11-08 11:42:57 UTC (rev 4774)
+++ developers/werner/owping/README	2008-11-09 19:39:20 UTC (rev 4775)
@@ -10,11 +10,11 @@
 
 Receiver:
 
-% owping
+% owping [-p port]
 
 Sender:
 
-% owping [-c count] ip_address
+% owping [-c count] [-p port] ipv4_address
 
 
 Known issues
@@ -30,10 +30,4 @@
   the time between transmissions in the packet data and the receiver
   compares this with the inter-arrival time it measures.
 
-- receiver should also handle SIGINT, and print statistics
-
 - receiver should count gaps in the sequence numbers
-
-- should support host name resolution
-
-- should support setting the port number

Modified: developers/werner/owping/owping.c
===================================================================
--- developers/werner/owping/owping.c	2008-11-08 11:42:57 UTC (rev 4774)
+++ developers/werner/owping/owping.c	2008-11-09 19:39:20 UTC (rev 4775)
@@ -15,17 +15,19 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <string.h>
+#include <netdb.h>
 #include <arpa/inet.h>
 
 #include "owping.h"
 
 
-#define PORT 23867
+#define DEFAULT_PORT 23867
 
 
 static void usage(const char *name)
 {
-    fprintf(stderr, "usage: %s [[-c count] ip_address]\n", name);
+    fprintf(stderr, "usage: %s [-p port] [[-c count] ipv4_address]\n", name);
     exit(1);
 }
 
@@ -33,32 +35,62 @@
 int main(int argc, char **argv)
 {
     struct sockaddr_in addr;
-    int count = -1;
+    long count = -1;
+    unsigned long port = DEFAULT_PORT;
     int c;
     char *end;
 
-    while ((c = getopt(argc, argv, "c:")) != EOF)
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = INADDR_ANY;
+    addr.sin_port = htons(DEFAULT_PORT);
+
+    while ((c = getopt(argc, argv, "c:p:")) != EOF)
 	switch (c) {
 	case 'c':
 	    count = strtoul(optarg, &end, 10);
-	    if (*end)
-		usage(*argv);
+	    if (*end || count < 0 || count > INT_MAX) {
+		fprintf(stderr, "%s: invalid port\n", optarg);
+		exit(1);
+	    }
 	    break;
+	case 'p':
+	    port = strtoul(optarg, &end, 10);
+	    if (!*end && port && port <= 0xffff)
+		addr.sin_port = htons(port);
+	    else {
+		struct servent *se;
+
+		se = getservbyname(optarg, "udp");
+		if (!se) {
+		    fprintf(stderr, "%s: unknown port\n", optarg);
+		    exit(1);
+		}
+		addr.sin_port = se->s_port;
+	    }
+	    break;
 	default:
 	    usage(*argv);
 	}
 
     switch (argc-optind) {
     case 0:
-	rx(PORT);
+	rx((const struct sockaddr_in *) &addr);
 	break;
     case 1:
 	addr.sin_family = AF_INET;
 	addr.sin_addr.s_addr = inet_addr(argv[optind]);
-	addr.sin_port = htons(PORT);
-	if (addr.sin_addr.s_addr == (in_addr_t) -1)
-	    usage(*argv);
-	tx(addr, count);
+	addr.sin_port = htons(port);
+	if (addr.sin_addr.s_addr == (in_addr_t) -1) {
+	    struct hostent *he;
+
+	    he = gethostbyname(argv[optind]);
+	    if (!he || he->h_addrtype != AF_INET) {
+		fprintf(stderr, "%s: unknown host\n", argv[optind]);
+		exit(1);
+	    }
+	    memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length);
+	}
+	tx((const struct sockaddr_in *) &addr, count);
 	break;
     default:
 	usage(*argv);

Modified: developers/werner/owping/owping.h
===================================================================
--- developers/werner/owping/owping.h	2008-11-08 11:42:57 UTC (rev 4774)
+++ developers/werner/owping/owping.h	2008-11-09 19:39:20 UTC (rev 4775)
@@ -26,7 +26,7 @@
 };
 
 
-void tx(struct sockaddr_in addr, int num);
-void rx(int port);
+void tx(const struct sockaddr_in *addr, int num);
+void rx(const struct sockaddr_in *addr);
 
 #endif /* OWPING_H */

Modified: developers/werner/owping/rx.c
===================================================================
--- developers/werner/owping/rx.c	2008-11-08 11:42:57 UTC (rev 4774)
+++ developers/werner/owping/rx.c	2008-11-09 19:39:20 UTC (rev 4775)
@@ -14,8 +14,10 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 #include <math.h>
+#include <signal.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
@@ -28,7 +30,7 @@
     long min, max;
     double sum, sq;
     int n;
-};
+} stats_itf, stats_user;
 
 
 static void stats_init(struct stats *stats)
@@ -41,11 +43,10 @@
 {
     double avg = stats->sum/stats->n;
 
-    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms (%d packets)\n",
+    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms\n",
       label,
       stats->min/1000.0, avg/1000.0, stats->max/1000.0,
-      sqrt(stats->sq/stats->n-avg*avg)/1000.0,
-      stats->n);
+      sqrt(stats->sq/stats->n-avg*avg)/1000.0);
 }
 
 
@@ -77,10 +78,43 @@
 }
 
 
-void rx(int port)
+static void finish(void)
 {
-    struct stats stats_itf, stats_user;
-    struct sockaddr_in addr;
+    printf("received %d packets\n", stats_itf.n);
+    stats_print("itf:", &stats_itf);
+    stats_print("app:", &stats_user);
+}
+
+
+static void handler(int sig)
+{
+    finish();
+    _exit(0);
+}
+
+
+static void block(int how)
+{
+    sigset_t set;
+
+    if (sigemptyset(&set) < 0) {
+	perror("sigemptyset");
+	exit(1);
+    }
+    if (sigaddset(&set, SIGINT) < 0) {
+	perror("sigaddset");
+	exit(1);
+    }
+    if (sigprocmask(how, &set, NULL) < 0) {
+	perror("sigprocmask");
+	exit(1);
+    }
+}
+
+
+void rx(const struct sockaddr_in *addr)
+{
+    struct sockaddr_in src;
     int s;
 
     s = socket(PF_INET, SOCK_DGRAM, 0);
@@ -89,10 +123,7 @@
 	exit(1);
     }
 
-    addr.sin_family = AF_INET;
-    addr.sin_addr.s_addr = INADDR_ANY;
-    addr.sin_port = htons(port);
-    if (bind(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if (bind(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) {
 	perror("bind");
 	exit(1);
     }
@@ -100,15 +131,24 @@
     stats_init(&stats_itf);
     stats_init(&stats_user);
 
+    if (atexit(finish)) {
+	perror("atexit");
+	exit(1);
+    }
+    if (signal(SIGINT, handler) == SIG_ERR) {
+	perror("signal(SIGINT)");
+	exit(1);
+    }
+
     while (1) {
 	struct owping buf;
 	socklen_t addr_len;
 	ssize_t got;
 	struct timeval t_src, t_itf, t_user;
 
-	addr_len = sizeof(addr);
+	addr_len = sizeof(src);
 	got = recvfrom(s, &buf, sizeof(buf), 0,
-	  (struct sockaddr *) &addr, &addr_len);
+	  (struct sockaddr *) &src, &addr_len);
 	if (got < 0) {
 	    perror("recvmsg");
 	    exit(1);
@@ -128,15 +168,14 @@
 	    perror("ioctl(SIOCGSTAMP)");
 	    exit(1);
 	}
+	block(SIG_BLOCK);
 	printf("seq=%u from %s:", (unsigned) ntohl(buf.seq),
-	  inet_ntoa(addr.sin_addr));
+	  inet_ntoa(src.sin_addr));
 	t_src.tv_sec = ntohl(buf.tv_sec);
 	t_src.tv_usec = ntohl(buf.tv_usec);
 	delta(t_src, t_itf, &stats_itf);
 	delta(t_src, t_user, &stats_user);
 	putchar('\n');
+	block(SIG_UNBLOCK);
     }
-    stats_print("itf:", &stats_itf);
-    stats_print("app:", &stats_user);
-
 }

Modified: developers/werner/owping/tx.c
===================================================================
--- developers/werner/owping/tx.c	2008-11-08 11:42:57 UTC (rev 4774)
+++ developers/werner/owping/tx.c	2008-11-09 19:39:20 UTC (rev 4775)
@@ -39,7 +39,7 @@
 }
 
 
-void tx(struct sockaddr_in addr, int num)
+void tx(const struct sockaddr_in *addr, int num)
 {
     ssize_t sent;
     int seq;
@@ -50,7 +50,7 @@
 	exit(1);
     }
 
-    if (connect(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if (connect(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) {
 	perror("connect");
 	exit(1);
     }




More information about the commitlog mailing list