]> Zhao Yanbai Git Server - minix.git/commitdiff
Added tcpstat and udpstat.
authorPhilip Homburg <philip@cs.vu.nl>
Tue, 8 Nov 2005 14:02:36 +0000 (14:02 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Tue, 8 Nov 2005 14:02:36 +0000 (14:02 +0000)
commands/simple/Makefile
commands/simple/tcpstat.c [new file with mode: 0644]
commands/simple/udpstat.c [new file with mode: 0644]

index 4b5da6a6eedd629b82c333c610a454093d0cd2ac..65fbce5d7abc0d9878bd92c8f6968ee55fd08a07 100755 (executable)
@@ -2,6 +2,7 @@
 
 CFLAGS = -D_MINIX -D_POSIX_SOURCE
 SYS    = ../..
+SERVERS = ../../servers
 CCLD   = $(CC) -i $(CFLAGS)
 CC     = exec cc
 
@@ -175,6 +176,7 @@ ALL = \
        tar \
        tcpd \
        tcpdp \
+       tcpstat \
        tee \
        term \
        termcap \
@@ -186,6 +188,7 @@ ALL = \
        tsort \
        ttt \
        tty \
+       udpstat \
        umount \
        uname \
        unexpand \
@@ -751,6 +754,10 @@ tcpdp:     tcpd.c
        $(CCLD) -o $@ -DPARANOID=1 tcpd.c
        @install -S 8kw $@
 
+tcpstat:       tcpstat.c
+       $(CCLD) -o $@ -I$(SERVERS) tcpstat.c
+       @install -S 8kw $@
+
 tee:   tee.c
        $(CCLD) -o $@ $?
        @install -S 4kw $@
@@ -795,6 +802,10 @@ tty:       tty.c
        $(CCLD) -o $@ $?
        @install -S 4kw $@
 
+udpstat:       udpstat.c
+       $(CCLD) -o $@ -I$(SERVERS) $?
+       @install -S 32k $@
+
 umount:        umount.c
        $(CCLD) -o $@ $?
        @install -S 4kw $@
@@ -1025,6 +1036,7 @@ install:  \
        /usr/bin/tar \
        /usr/bin/tcpd \
        /usr/bin/tcpdp \
+       /usr/bin/tcpstat \
        /usr/bin/tee \
        /usr/bin/term \
        /usr/bin/termcap \
@@ -1036,6 +1048,7 @@ install:  \
        /usr/bin/tsort \
        /usr/bin/ttt \
        /usr/bin/tty \
+       /usr/bin/udpstat \
        /usr/bin/umount \
        /usr/bin/uname \
                /usr/bin/arch \
@@ -1056,6 +1069,7 @@ install:  \
        /usr/bin/writeisofs \
        /usr/bin/xargs \
        /usr/bin/yes \
+       /usr/bin/udpstat \
        /bin/cat \
        /bin/date \
        /bin/fsck \
@@ -1527,6 +1541,9 @@ install:  \
 /usr/bin/tcpdp:        tcpdp
        install -cs -o bin $? $@
 
+/usr/bin/tcpstat:      tcpstat
+       install -cs -o bin $? $@
+
 /usr/bin/tee:  tee
        install -cs -o bin $? $@
 
@@ -1560,6 +1577,9 @@ install:  \
 /usr/bin/tty:  tty
        install -cs -o bin $? $@
 
+/usr/bin/udpstat:      udpstat
+       install -cs -o bin $? $@
+
 /usr/bin/umount:       umount
        install -cs -o root -m 4755 $? $@
 
diff --git a/commands/simple/tcpstat.c b/commands/simple/tcpstat.c
new file mode 100644 (file)
index 0000000..94d44d7
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+tcpstat.c
+
+Created:       June 1995 by Philip Homburg <philip@f-mnx.phicoh.com>
+*/
+
+#define _MINIX_SOURCE
+#define _POSIX_C_SOURCE 2
+
+#include <inet/inet.h>
+#undef printf
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/svrctl.h>
+#ifndef __minix_vmd
+#include <sys/times.h>
+#endif
+#include <net/netlib.h>
+#include <net/gen/inet.h>
+#include <net/gen/netdb.h>
+#include <net/gen/socket.h>
+#include <minix/queryparam.h>
+
+#include <inet/generic/buf.h>
+#include <inet/generic/clock.h>
+#include <inet/generic/event.h>
+#include <inet/generic/type.h>
+#include <inet/generic/tcp.h>
+#include <inet/generic/tcp_int.h>
+
+char *prog_name;
+tcp_conn_t tcp_conn_table[TCP_CONN_NR];
+char values[2 * sizeof(tcp_conn_table) + 1];
+int inclListen, numerical, verbose;
+
+void print_conn(int i, clock_t now);
+void usage(void);
+
+int main(int argc, char*argv[])
+{
+       char *tcp_device;
+       int fd, i;
+       struct svrqueryparam qpar;
+       char *pval;
+       struct timeval uptime;
+       clock_t now;
+       int fl;
+       int a_flag, n_flag, v_flag;
+
+       (prog_name=strrchr(argv[0], '/')) ? prog_name++ : (prog_name=argv[0]);
+
+       a_flag= 0;
+       n_flag= 0;
+       v_flag= 0;
+       while ((fl= getopt(argc, argv, "?anv")) != -1)
+       {
+               switch(fl)
+               {
+               case '?':
+                       usage();
+               case 'a':
+                       a_flag= 1;
+                       break;
+               case 'n':
+                       n_flag= 1;
+                       break;
+               case 'v':
+                       v_flag= 1;
+                       break;
+               default:
+                       fprintf(stderr, "%s: getopt failed: '%c'\n", 
+                               prog_name, fl);
+                       exit(1);
+               }
+       }
+       inclListen= !!a_flag;
+       numerical= !!n_flag;
+       verbose= !!v_flag;
+
+       tcp_device= TCP_DEVICE;
+       if ((fd= open(tcp_device, O_RDWR)) == -1)
+       {
+               fprintf(stderr, "%s: unable to open '%s': %s\n", prog_name,
+                       tcp_device, strerror(errno));
+               exit(1);
+       }
+
+       qpar.param = "tcp_conn_table";
+       qpar.psize = strlen(qpar.param);
+       qpar.value = values;
+       qpar.vsize = sizeof(values);
+       if (ioctl(fd, NWIOQUERYPARAM, &qpar) == -1)
+       {
+               fprintf(stderr, "%s: queryparam failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       pval= values;
+       if (paramvalue(&pval, tcp_conn_table, sizeof(tcp_conn_table)) !=
+               sizeof(tcp_conn_table))
+       {
+               fprintf(stderr,
+                       "%s: unable to decode the results from queryparam\n",
+                       prog_name);
+               exit(1);
+       }
+
+#ifdef __minix_vmd
+       /* Get the uptime in clock ticks. */
+       if (sysutime(UTIME_UPTIME, &uptime) == -1)
+       {
+               fprintf(stderr, "%s: sysutime failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       now= uptime.tv_sec * HZ + (uptime.tv_usec*HZ/1000000);
+#else  /* Minix 3 */
+       now= times(NULL);
+#endif
+
+       for (i= 0; i<TCP_CONN_NR; i++)
+               print_conn(i, now);
+       exit(0);
+}
+
+void print_conn(int i, clock_t now)
+{
+       tcp_conn_t *tcp_conn;
+       char *addr_str;
+       struct hostent *hostent;
+       struct servent *servent;
+       ipaddr_t a1, a2;
+       tcpport_t p1, p2;
+       unsigned flags;
+       int no_verbose;
+       clock_t rtt, artt, drtt;
+
+       tcp_conn= &tcp_conn_table[i];
+       if (!(tcp_conn->tc_flags & TCF_INUSE))
+               return;
+       if (tcp_conn->tc_state == TCS_LISTEN && !inclListen)
+               return;
+       if (tcp_conn->tc_state == TCS_CLOSED && tcp_conn->tc_fd == NULL &&
+               tcp_conn->tc_senddis < now)
+       {
+               return;
+       }
+       
+       printf("%3d", i);
+
+       a1= tcp_conn->tc_locaddr;
+       p1= tcp_conn->tc_locport;
+       a2= tcp_conn->tc_remaddr;
+       p2= tcp_conn->tc_remport;
+
+       if (a1 == 0)
+               addr_str= "*";
+       else if (!numerical &&
+               (hostent= gethostbyaddr((char *)&a1,
+               sizeof(a1), AF_INET)) != NULL)
+       {
+               addr_str= hostent->h_name;
+       }
+       else
+               addr_str= inet_ntoa(a1);
+       printf(" %s:", addr_str);
+
+       if (p1 == 0)
+               printf("*");
+       else if ((servent= getservbyport(p1, "tcp")) != NULL)
+       {
+               printf("%s", servent->s_name);
+       }
+       else
+               printf("%u", ntohs(p1));
+
+       if (tcp_conn->tc_orglisten)
+               printf(" <- ");
+       else
+               printf(" -> ");
+
+       if (a2 == 0)
+               addr_str= "*";
+       else if (!numerical &&
+               (hostent= gethostbyaddr((char *)&a2,
+               sizeof(a2), AF_INET)) != NULL)
+       {
+               addr_str= hostent->h_name;
+       }
+       else
+               addr_str= inet_ntoa(a2);
+       printf("%s:", addr_str);
+
+       if (p2 == 0)
+               printf("*");
+       else if ((servent= getservbyport(p2, "tcp")) !=
+               NULL)
+       {
+               printf("%s", servent->s_name);
+       }
+       else
+               printf("%u", ntohs(p2));
+
+       printf(" ");
+       no_verbose= 0;
+       switch(tcp_conn->tc_state)
+       {
+       case TCS_CLOSED:        printf("CLOSED");
+                               if (tcp_conn->tc_senddis >= now)
+                               {
+                                       printf("(time wait %ld s)",
+                                               (tcp_conn->tc_senddis-now)/HZ);
+                               }
+                               no_verbose= 1;
+                               break;
+       case TCS_LISTEN:        printf("LISTEN"); no_verbose= 1; break;
+       case TCS_SYN_RECEIVED:  printf("SYN_RECEIVED"); break;
+       case TCS_SYN_SENT:      printf("SYN_SENT"); break;
+       case TCS_ESTABLISHED:   printf("ESTABLISHED"); break;
+       case TCS_CLOSING:       printf("CLOSING"); break;
+       default:                printf("state(%d)", tcp_conn->tc_state);
+                               break;
+       }
+
+       if (tcp_conn->tc_flags & TCF_FIN_RECV)
+               printf(" F<");
+       if (tcp_conn->tc_flags & TCF_FIN_SENT)
+       {
+               printf(" F>");
+               if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT)
+                       printf("+");
+       }
+       if (tcp_conn->tc_state != TCS_CLOSED &&
+               tcp_conn->tc_state != TCS_LISTEN)
+       {
+               printf("\n\t");
+               printf("RQ: %lu, SQ: %lu, RWnd: %u, SWnd: %lu, SWThresh: %lu",
+                       tcp_conn->tc_RCV_NXT - tcp_conn->tc_RCV_LO,
+                       tcp_conn->tc_SND_NXT - tcp_conn->tc_SND_UNA,
+                       tcp_conn->tc_rcv_wnd,
+                       tcp_conn->tc_snd_cwnd - tcp_conn->tc_SND_UNA,
+                       tcp_conn->tc_snd_cthresh);
+       }
+
+       printf("\n");
+
+       if (!verbose || no_verbose)
+               return;
+       rtt= tcp_conn->tc_rtt;
+       artt= tcp_conn->tc_artt;
+       drtt= tcp_conn->tc_drtt;
+       printf("\tmss %u, mtu %u%s, rtt %.3f (%.3f+%d*%.3f) s\n",
+               tcp_conn->tc_max_mtu-IP_TCP_MIN_HDR_SIZE,
+               tcp_conn->tc_mtu,
+               (tcp_conn->tc_flags & TCF_PMTU) ? "" : " (no PMTU)",
+               rtt/(HZ+0.0),
+               artt/(HZ+0.0)/TCP_RTT_SCALE, TCP_DRTT_MULT,
+               drtt/(HZ+0.0)/TCP_RTT_SCALE);
+       flags= tcp_conn->tc_flags;
+       printf("\tflags:");
+       if (!flags)
+               printf(" TCF_EMPTY");
+       if (flags & TCF_INUSE)
+               flags &= ~TCF_INUSE;
+       if (flags & TCF_FIN_RECV)
+       {
+               printf(" TCF_FIN_RECV");
+               flags &= ~TCF_FIN_RECV;
+       }
+       if (flags & TCF_RCV_PUSH)
+       {
+               printf(" TCF_RCV_PUSH");
+               flags &= ~TCF_RCV_PUSH;
+       }
+       if (flags & TCF_MORE2WRITE)
+       {
+               printf(" TCF_MORE2WRITE");
+               flags &= ~TCF_MORE2WRITE;
+       }
+       if (flags & TCF_SEND_ACK)
+       {
+               printf(" TCF_SEND_ACK");
+               flags &= ~TCF_SEND_ACK;
+       }
+       if (flags & TCF_FIN_SENT)
+       {
+               printf(" TCF_FIN_SENT");
+               flags &= ~TCF_FIN_SENT;
+       }
+       if (flags & TCF_BSD_URG)
+       {
+               printf(" TCF_BSD_URG");
+               flags &= ~TCF_BSD_URG;
+       }
+       if (flags & TCF_NO_PUSH)
+       {
+               printf(" TCF_NO_PUSH");
+               flags &= ~TCF_NO_PUSH;
+       }
+       if (flags & TCF_PUSH_NOW)
+       {
+               printf(" TCF_PUSH_NOW");
+               flags &= ~TCF_PUSH_NOW;
+       }
+       if (flags & TCF_PMTU)
+               flags &= ~TCF_PMTU;
+       if (flags)
+               printf(" 0x%x", flags);
+       printf("\n");
+       printf("\ttimer: ref %d, time %f, active %d\n",
+               tcp_conn->tc_transmit_timer.tim_ref,
+               (0.0+tcp_conn->tc_transmit_timer.tim_time-now)/HZ,
+               tcp_conn->tc_transmit_timer.tim_active);
+}
+
+void usage(void)
+{
+       fprintf(stderr, "Usage: %s [-anv]\n", prog_name);
+       exit(1);
+}
+
+/*
+ * $PchId: tcpstat.c,v 1.8 2005/01/30 01:04:38 philip Exp $
+ */
diff --git a/commands/simple/udpstat.c b/commands/simple/udpstat.c
new file mode 100644 (file)
index 0000000..baf1b5f
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+udpstat.c
+
+Created:       March 2001 by Philip Homburg <philip@f-mnx.phicoh.com>
+*/
+
+#define _MINIX_SOURCE
+#define _POSIX_C_SOURCE 2
+
+#include <inet/inet.h>
+#undef printf
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/svrctl.h>
+#ifndef __minix_vmd
+#include <sys/times.h>
+#endif
+#include <net/netlib.h>
+#include <net/gen/inet.h>
+#include <net/gen/netdb.h>
+#include <net/gen/socket.h>
+#include <minix/queryparam.h>
+
+#include <inet/generic/buf.h>
+#include <inet/generic/clock.h>
+#include <inet/generic/event.h>
+#include <inet/generic/type.h>
+#include <inet/generic/udp_int.h>
+
+char *prog_name;
+udp_fd_t udp_fd_table[UDP_FD_NR];
+udp_port_t *udp_port_table;
+udp_port_t *udp_port_tablep;
+size_t udp_port_table_s;
+size_t udp_port_table_rs;
+int udp_port_nr;
+char values[6 * sizeof(void *) + 3];
+char *valuesl= NULL;
+size_t v_size;
+int inclSel, numerical;
+
+void print_fd(int i, clock_t now);
+void usage(void);
+
+int main(int argc, char*argv[])
+{
+       char *udp_device;
+       int fd, i;
+       struct svrqueryparam qpar;
+       char *pval;
+       struct timeval uptime;
+       clock_t now;
+       int fl;
+       int a_flag, n_flag;
+
+       (prog_name=strrchr(argv[0], '/')) ? prog_name++ : (prog_name=argv[0]);
+
+       a_flag= 0;
+       n_flag= 0;
+       while ((fl= getopt(argc, argv, "?an")) != -1)
+       {
+               switch(fl)
+               {
+               case '?':
+                       usage();
+               case 'a':
+                       a_flag= 1;
+                       break;
+               case 'n':
+                       n_flag= 1;
+                       break;
+               default:
+                       fprintf(stderr, "%s: getopt failed: '%c'\n", 
+                               prog_name, fl);
+                       exit(1);
+               }
+       }
+       inclSel= !!a_flag;
+       numerical= !!n_flag;
+
+       udp_device= UDP_DEVICE;
+       if ((fd= open(udp_device, O_RDWR)) == -1)
+       {
+               fprintf(stderr, "%s: unable to open '%s': %s\n", prog_name,
+                       udp_device, strerror(errno));
+               exit(1);
+       }
+
+       v_size= 2*sizeof(udp_fd_table)+1;
+       valuesl= realloc(valuesl, v_size);
+       if (!valuesl)
+       {
+               fprintf(stderr, "%s: unable to malloc %u bytes for valuesl\n",
+                       prog_name, v_size);
+               exit(1);
+       }
+
+       qpar.param = "udp_fd_table";
+       qpar.psize = strlen(qpar.param);
+       qpar.value = valuesl;
+       qpar.vsize = v_size;
+       if (ioctl(fd, NWIOQUERYPARAM, &qpar) == -1)
+       {
+               fprintf(stderr, "%s: queryparam failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       pval= valuesl;
+       if (paramvalue(&pval, udp_fd_table, sizeof(udp_fd_table)) !=
+               sizeof(udp_fd_table))
+       {
+               fprintf(stderr,
+       "%s: unable to decode the results from queryparam (udp_fd_table)\n",
+                       prog_name);
+               exit(1);
+       }
+
+       /* Get address, size, and element size of the UDP port table */
+       qpar.param = "&udp_port_table,$udp_port_table,$udp_port_table[0]";
+       qpar.psize = strlen(qpar.param);
+       qpar.value = values;
+       qpar.vsize = sizeof(values);
+       if (ioctl(fd, NWIOQUERYPARAM, &qpar) == -1)
+       {
+               fprintf(stderr, "%s: queryparam failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       pval= values;
+       if (paramvalue(&pval, &udp_port_tablep, sizeof(udp_port_tablep)) !=
+               sizeof(udp_port_tablep) ||
+               paramvalue(&pval, &udp_port_table_s, sizeof(udp_port_table_s))
+                       != sizeof(udp_port_table_s) ||
+               paramvalue(&pval, &udp_port_table_rs, sizeof(udp_port_table_rs))
+                       != sizeof(udp_port_table_rs))
+       {
+               fprintf(stderr,
+"%s: unable to decode the results from queryparam (&udp_port_table, ...)\n",
+                       prog_name);
+               exit(1);
+       }
+
+       if (udp_port_table_rs != sizeof(udp_port_table[0]))
+       {
+               fprintf(stderr,
+       "%s: size mismatch in udp_port_table (different version of inet?)\n",
+                       prog_name);
+               exit(1);
+       }
+       udp_port_nr= udp_port_table_s/udp_port_table_rs;
+       assert(udp_port_table_s == udp_port_nr*udp_port_table_rs);
+       udp_port_table= malloc(udp_port_table_s);
+       if (!udp_port_table)
+       {
+               fprintf(stderr,
+       "%s: unable to malloc %u bytes for udp_port_table\n",
+                       prog_name, udp_port_table_s);
+               exit(1);
+       }
+       v_size= 2*udp_port_table_s+1;
+       valuesl= realloc(valuesl, v_size);
+       if (!valuesl)
+       {
+               fprintf(stderr, "%s: unable to malloc %u bytes for valuesl\n",
+                       prog_name, v_size);
+               exit(1);
+       }
+
+       qpar.param = "udp_port_table";
+       qpar.psize = strlen(qpar.param);
+       qpar.value = valuesl;
+       qpar.vsize = v_size;
+       if (ioctl(fd, NWIOQUERYPARAM, &qpar) == -1)
+       {
+               fprintf(stderr, "%s: queryparam failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       pval= valuesl;
+       if (paramvalue(&pval, udp_port_table, udp_port_table_s) !=
+               udp_port_table_s)
+       {
+               fprintf(stderr,
+       "%s: unable to decode the results from queryparam (udp_port_table)\n",
+                       prog_name);
+               exit(1);
+       }
+
+       /* Get the uptime in clock ticks. */
+#ifdef __minix_vmd
+       if (sysutime(UTIME_UPTIME, &uptime) == -1)
+       {
+               fprintf(stderr, "%s: sysutime failed: %s\n", prog_name,
+                       strerror(errno));
+               exit(1);
+       }
+       now= uptime.tv_sec * HZ + (uptime.tv_usec*HZ/1000000);
+#else  /* Minix 3 */
+       now= times(NULL);
+#endif
+
+       for (i= 0; i<UDP_FD_NR; i++)
+               print_fd(i, now);
+       exit(0);
+}
+
+void print_fd(int i, clock_t now)
+{
+       unsigned long nwuo_flags;
+       int port_nr;
+       udp_fd_t *udp_fd;
+       udp_port_t *udp_port;
+       char *locaddr_str, *remaddr_str;
+       struct hostent *hostent;
+       struct servent *servent;
+       nwio_udpopt_t uf_udpopt;
+
+       udp_fd= &udp_fd_table[i];
+       if (!(udp_fd->uf_flags & UFF_INUSE))
+               return;
+       uf_udpopt= udp_fd->uf_udpopt;
+       nwuo_flags= uf_udpopt.nwuo_flags;
+       if (((nwuo_flags & NWUO_LOCPORT_MASK) != NWUO_LP_SET) && !inclSel)
+               return;
+
+       port_nr= udp_fd->uf_port-udp_port_tablep;
+       udp_port= &udp_port_table[port_nr];
+       
+       printf("%3d", i);
+
+       if (nwuo_flags & NWUO_EN_LOC)
+       {
+               if (!numerical && (hostent=
+                       gethostbyaddr((char *)&udp_port->up_ipaddr,
+                       sizeof(ipaddr_t), AF_INET)) != NULL)
+               {
+                       locaddr_str= hostent->h_name;
+               }
+               else
+                       locaddr_str= inet_ntoa(udp_port->up_ipaddr);
+       }
+       else if (nwuo_flags & NWUO_EN_BROAD)
+               locaddr_str= "255.255.255.255";
+       else
+               locaddr_str= "0.0.0.0";
+
+       printf(" %s:", locaddr_str);
+
+       if ((nwuo_flags & NWUO_LOCPORT_MASK) != NWUO_LP_SEL &&
+               (nwuo_flags & NWUO_LOCPORT_MASK) != NWUO_LP_SET)
+       {
+               printf("*");
+       }
+       else if ((servent= getservbyport(uf_udpopt.nwuo_locport, "udp")) !=
+               NULL)
+       {
+               printf("%s", servent->s_name);
+       }
+       else
+               printf("%u", ntohs(uf_udpopt.nwuo_locport));
+
+       printf(" -> ");
+
+       if (!(nwuo_flags & NWUO_RA_SET))
+               remaddr_str= "*";
+       else if (!numerical &&
+               (hostent= gethostbyaddr((char *)&uf_udpopt.nwuo_remaddr,
+               sizeof(ipaddr_t), AF_INET)) != NULL)
+       {
+               remaddr_str= hostent->h_name;
+       }
+       else
+               remaddr_str= inet_ntoa(uf_udpopt.nwuo_remaddr);
+       printf("%s:", remaddr_str);
+
+       if (!(nwuo_flags & NWUO_RP_SET))
+               printf("*");
+       else if ((servent= getservbyport(uf_udpopt.nwuo_remport, "udp")) !=
+               NULL)
+       {
+               printf("%s", servent->s_name);
+       }
+       else
+               printf("%u", ntohs(uf_udpopt.nwuo_remport));
+       printf("\n");
+}
+
+void usage(void)
+{
+       fprintf(stderr, "Usage: %s [-a] [-n]\n", prog_name);
+       exit(1);
+}
+
+/*
+ * $PchId: udpstat.c,v 1.4 2005/01/30 01:04:57 philip Exp $
+ */