server/admin.c: Remove spurious `ping' in usage message.
[tripe] / proxy / tripe-mitm.c
index 6acf2a1..648296e 100644 (file)
@@ -119,9 +119,17 @@ static void addpeer_common(const char *cmd, int af, unsigned ac, char **av)
 {
   struct addrinfo aihint = { 0 }, *ai0, *ai1;
   int len = PKBUFSZ, yes = 1;
+  const char *outf, *serv;
+  FILE *fp;
+  union {
+    struct sockaddr sa;
+    struct sockaddr_in sin;
+    struct sockaddr_in6 sin6;
+  } addr;
+  socklen_t salen;
   int err;
   peer *p;
-  int fd;
+  int fd, port;
 
   if (ac != 4) die(1, "syntax: %s:NAME:PORT:ADDR:PORT", cmd);
   if (!key_bytag(&keys, av[0])) die(1, "no key named `%s'", av[0]);
@@ -132,9 +140,11 @@ static void addpeer_common(const char *cmd, int af, unsigned ac, char **av)
   aihint.ai_flags = AI_ADDRCONFIG;
   if ((err = getaddrinfo(av[2], av[3], &aihint, &ai1)) != 0)
     die(1, "getaddrinfo(`%s', `%s'): %s", av[2], av[3], gai_strerror(err));
+  if (*av[1] == '?') { serv = "0"; outf = av[1] + 1; }
+  else { serv = av[1]; outf = 0; }
   aihint.ai_family = ai1->ai_family;
   aihint.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
-  if ((err = getaddrinfo(0, av[1], &aihint, &ai0)) != 0)
+  if ((err = getaddrinfo(0, serv, &aihint, &ai0)) != 0)
     die(1, "getaddrinfo(passive, `%s'): %s", av[1], gai_strerror(err));
   if ((fd = socket(ai1->ai_family, SOCK_DGRAM, ai1->ai_protocol)) < 0)
     die(1, "socket: %s", strerror(errno));
@@ -149,6 +159,20 @@ static void addpeer_common(const char *cmd, int af, unsigned ac, char **av)
     die(1, "setsockopt: %s", strerror(errno));
   if (connect(fd, ai1->ai_addr, ai1->ai_addrlen))
     die(1, "connect: %s", strerror(errno));
+  if (outf) {
+    salen = sizeof(addr);
+    if (getsockname(fd, &addr.sa, &salen))
+      die(1, "getsockname: %s", strerror(errno));
+    switch (addr.sa.sa_family) {
+      case AF_INET: port = ntohs(addr.sin.sin_port); break;
+      case AF_INET6: port = ntohs(addr.sin6.sin6_port); break;
+      default: assert(0);
+    }
+    fp = fopen(outf, "w");
+    if (!fp) die(1, "fopen(%s): %s", outf, strerror(errno));
+    fprintf(fp, "%d\n", port);
+    fclose(fp);
+  }
   sel_initfile(&sel, &p->sf, fd, SEL_READ, dopacket, p);
   sel_addfile(&p->sf);
   freeaddrinfo(ai0); freeaddrinfo(ai1);