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