chiark / gitweb /
admin: Initialize reference counter for client blocks.
[tripe] / pkstream.c
index 176192a861faf1682d1eaf353409f8a64dafac76..e291a9bd446850728343f95945f49c16a111b1e1 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: pkstream.c,v 1.1 2003/04/23 12:53:28 mdw Exp $
+ * $Id: pkstream.c,v 1.3 2004/04/08 01:36:17 mdw Exp $
  *
  * Forwarding UDP packets over a stream
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: pkstream.c,v $
- * Revision 1.1  2003/04/23 12:53:28  mdw
- * New pkstream program.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include "config.h"
@@ -277,8 +269,8 @@ static void dolisten(void)
   int opt = 1;
 
   if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ||
-      bind(fd, (struct sockaddr *)&cw.me, sizeof(cw.me)) ||
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ||
+      bind(fd, (struct sockaddr *)&cw.me, sizeof(cw.me)) ||
       listen(fd, 1) || nonblockify(fd) || cloexec(fd))
     die(1, "couldn't set up listening socket: %s", strerror(errno));
   sel_initfile(&sel, &cw.a, fd, SEL_READ, doaccept, 0);
@@ -321,7 +313,8 @@ static void parseaddr(const char *pp, struct in_addr *a, unsigned short *pt)
 static void usage(FILE *fp)
 {
   pquis(fp,
-       "Usage: $ [-l PORT] [-p ADDR] [-c ADDR:PORT] ADDR:PORT ADDR:PORT\n");
+       "Usage: $ [-l PORT] [-b ADDR] [-p ADDR] [-c ADDR:PORT]\n\
+       ADDR:PORT ADDR:PORT\n");
 }
 
 static void version(FILE *fp)
@@ -342,7 +335,8 @@ Options:\n\
 -u, --usage            Display pointless usage message.\n\
 \n\
 -l, --listen=PORT      Listen for connections to TCP PORT.\n\
--p, --peer=PORT                Only accept connections from IP ADDR.\n\
+-p, --peer=ADDR                Only accept connections from IP ADDR.\n\
+-b, --bind=ADDR                Bind to ADDR before connecting.\n\
 -c, --connect=ADDR:PORT        Connect to IP ADDR, TCP PORT.\n\
 \n\
 Forwards UDP packets over a reliable stream.  By default, uses stdin and\n\
@@ -354,14 +348,18 @@ int main(int argc, char *argv[])
 {
   unsigned f = 0;
   unsigned short pt;
-  struct sockaddr_in connaddr;
+  struct sockaddr_in connaddr, bindaddr;
   struct sockaddr_in udp_me, udp_peer;
   int len = 65536;
 
 #define f_bogus 1u
 
   ego(argv[0]);
+  bindaddr.sin_family = AF_INET;
+  bindaddr.sin_addr.s_addr = INADDR_ANY;
+  bindaddr.sin_port = 0;
   connaddr.sin_family = AF_INET;
+  connaddr.sin_addr.s_addr = INADDR_ANY;
   cw.me.sin_family = AF_INET;
   cw.me.sin_addr.s_addr = INADDR_ANY;
   cw.me.sin_port = 0;
@@ -374,12 +372,13 @@ int main(int argc, char *argv[])
       { "usage",               0,              0,      'u' },
       { "listen",              OPTF_ARGREQ,    0,      'l' },
       { "peer",                        OPTF_ARGREQ,    0,      'p' },
+      { "bind",                        OPTF_ARGREQ,    0,      'b' },
       { "connect",             OPTF_ARGREQ,    0,      'c' },
       { 0,                     0,              0,      0 }
     };
     int i;
 
-    i = mdwopt(argc, argv, "hvul:p:c:", opt, 0, 0, 0);
+    i = mdwopt(argc, argv, "hvul:p:b:c:", opt, 0, 0, 0);
     if (i < 0)
       break;
     switch (i) {
@@ -399,6 +398,9 @@ int main(int argc, char *argv[])
       case 'p':
        parseaddr(optarg, &cw.peer, 0);
        break;
+      case 'b':
+       parseaddr(optarg, &bindaddr.sin_addr, 0);
+       break;
       case 'c':
        parseaddr(optarg, &connaddr.sin_addr, &pt);
        connaddr.sin_port = pt;
@@ -432,6 +434,7 @@ int main(int argc, char *argv[])
   else if (connaddr.sin_addr.s_addr != INADDR_ANY) {
     int fd;
     if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ||
+       bind(fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) ||
        connect(fd, (struct sockaddr *)&connaddr, sizeof(connaddr)) ||
        nonblockify(fd) || cloexec(fd))
       die(1, "couldn't connect to TCP server: %s", strerror(errno));