chiark / gitweb /
Allow admin clients to filter out async messages. Send notifications
authormdw <mdw>
Sat, 30 Apr 2005 19:01:12 +0000 (19:01 +0000)
committermdw <mdw>
Sat, 30 Apr 2005 19:01:12 +0000 (19:01 +0000)
about interesting events.  Rewrite all the messages to be more easily
machine-readable and document them all.  Fix the Ethereal dissector for
the new Ethereal, and fix the build system for the new autotools.

24 files changed:
.links
Makefile.am
acconfig.h [deleted file]
admin.c
client.c
configure.in
debian/control
doc/protocol.ms
doc/tmac.rfc
doc/tripe-admin.5
doc/tripe.8
ethereal/packet-tripe.c
keyexch.c
keymgmt.c
keyset.c
mallory.c
peer.c
setup
tripe-init.in
tripe.c
tripe.h
tun-bsd.c
tun-linux.c
tun-unet.c

diff --git a/.links b/.links
index c017eca825fff8171e172ff1b693168ba0c55d65..5ecd9c64ade274e86177f1b2a526c9216aa5bbdf 100644 (file)
--- a/.links
+++ b/.links
@@ -1,6 +1 @@
 COPYING
 COPYING
-install-sh
-mkinstalldirs
-missing
-config.sub
-config.guess
index b45927eb1526d76cb2e97139e96294ce8e328dd0..cb7455a1e4501b7d57cef2e5d707f6662b15323d 100644 (file)
@@ -1,6 +1,6 @@
 ## -*-makefile-*-
 ##
 ## -*-makefile-*-
 ##
-## $Id: Makefile.am,v 1.10 2004/04/08 01:36:17 mdw Exp $
+## $Id$
 ##
 ## Makefile for TrIPE
 ##
 ##
 ## Makefile for TrIPE
 ##
@@ -43,11 +43,10 @@ tripe_SOURCES = \
        keymgmt.c keyexch.c keyset.c \
        servutil.c util.c util.h
 EXTRA_tripe_SOURCES = \
        keymgmt.c keyexch.c keyset.c \
        servutil.c util.c util.h
 EXTRA_tripe_SOURCES = \
-       tun-unet.c tun-bsd.c
+       tun-unet.c tun-bsd.c tun-linux.c
 tripe_LDADD = $(CATACOMB_LIBS)
 tripectl_SOURCES = \
        client.c util.c util.h
 tripe_LDADD = $(CATACOMB_LIBS)
 tripectl_SOURCES = \
        client.c util.c util.h
-       tun-unet.c tun-bsd.c
 tripe_mitm_SOURCES = \
        mallory.c
 tripe_mitm_LDADD = $(CATACOMB_LIBS)
 tripe_mitm_SOURCES = \
        mallory.c
 tripe_mitm_LDADD = $(CATACOMB_LIBS)
diff --git a/acconfig.h b/acconfig.h
deleted file mode 100644 (file)
index a36ff8e..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*-c-*-
- *
- * $Id: acconfig.h,v 1.6 2004/04/08 01:36:17 mdw Exp $
- *
- * Configuration header for TrIPE
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------* 
- *
- * This file is part of Trivial IP Encryption (TrIPE).
- *
- * TrIPE is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * TrIPE is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with TrIPE; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef ACCONFIG_H
-#define ACCONFIG_H
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-/*----- Autoconfiguration data --------------------------------------------*/
-@TOP@
-
-/* Package and version number.  */
-#define PACKAGE "tripe"
-#define VERSION "1.0.0"
-
-/* Define to disable the tracing options.  This might improve performance a
- * little bit, and can prevent sensitive information from being leaked if
- * you're in the habit of typing things like `tripectl trace A' by
- * accident.  */
-#undef NTRACE
-
-/* Define according to the type of tunneling interface appropriate for your
- * system.  Linux types should say `TUN_LINUX' for the TUN/TAP driver if
- * using kernel 2.4.0 or later, or say `TUN_UNET' for 2.2-series kernels and
- * build the `usernet' module.  BSD types should say `TUN_BSD' to use the
- * built-in `tun' devices.  */
-#undef TUN_TYPE
-
-/* Define this to your default configuration directory.  This is where
- * tripe searches for keys and other stuff.  */
-#define CONFIGDIR "."
-
-/* Define this to the directory in which tripe's admin socket is to be
- * placed.  Common choices are `.' -- the tripe configuration directory --
- * and /var/run.  */
-#define SOCKETDIR "."
-
-/* Define if your Ethereal plugin headers are broken (e.g., Debian 3.0) but
- * you're running some sensible ELF system, and I should try to bodge around
- * the damage.  */
-#undef ETHEREAL_BUGGERED
-
-@BOTTOM@
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif
diff --git a/admin.c b/admin.c
index b95db51c276ffe9ff8ff2f6d9725664ba7161e22..0213996a45fe27d58f916b2190cec659da57de8f 100644 (file)
--- a/admin.c
+++ b/admin.c
@@ -50,6 +50,14 @@ const trace_opt tr_opts[] = {
 unsigned tr_flags = 0;
 #endif
 
 unsigned tr_flags = 0;
 #endif
 
+static const trace_opt w_opts[] = {
+  { 't',       AF_TRACE,       "trace messages" },
+  { 'n',       AF_NOTE,        "asynchronous notifications" },
+  { 'w',       AF_WARN,        "warnings" },
+  { 'A',       AF_ALLMSGS,     "all of the above" },
+  { 0,         0,              0 }
+};
+
 /*----- Static variables --------------------------------------------------*/
 
 static admin *admins;
 /*----- Static variables --------------------------------------------------*/
 
 static admin *admins;
@@ -70,6 +78,23 @@ static void a_unlock(admin */*a*/);
 
 /*----- Output functions --------------------------------------------------*/
 
 
 /*----- Output functions --------------------------------------------------*/
 
+/* --- @mystrieq@ --- *
+ *
+ * Arguments:  @const char *x, *y@ = two strings
+ *
+ * Returns:    True if @x@ and @y are equal, up to case.
+ */
+
+static int mystrieq(const char *x, const char *y)
+{
+  for (;;) {
+    if (!*x && !*y) return (1);
+    if (tolower((unsigned char)*x) != tolower((unsigned char)*y))
+      return (0);
+    x++; y++;
+  }
+}
+
 /* --- @trywrite@ --- *
  *
  * Arguments:  @admin *a@ = pointer to an admin block
 /* --- @trywrite@ --- *
  *
  * Arguments:  @admin *a@ = pointer to an admin block
@@ -100,8 +125,7 @@ again:
       goto again;
     if (errno != EAGAIN && errno != EWOULDBLOCK) {
       a_destroy(a);
       goto again;
     if (errno != EAGAIN && errno != EWOULDBLOCK) {
       a_destroy(a);
-      a_warn("disconnecting admin client due to write errors: %s",
-            strerror(errno));
+      a_warn("ADMIN client-read-error -- %s", strerror(errno));
       return (-1);
     }
   }
       return (-1);
     }
   }
@@ -204,10 +228,12 @@ static void a_flush(int fd, unsigned mode, void *v)
 
 /*----- Utility functions -------------------------------------------------*/
 
 
 /*----- Utility functions -------------------------------------------------*/
 
-/* --- @a_write@ --- *
+/* --- @a_write@, @a_vwrite@ --- *
  *
  * Arguments:  @admin *a@ = admin connection to write to
  *
  * Arguments:  @admin *a@ = admin connection to write to
+ *             @const char *tag@ = tag prefix string, or null
  *             @const char *fmt@ = pointer to format string
  *             @const char *fmt@ = pointer to format string
+ *             @va_list ap@ = arguments in list
  *             @...@ = other arguments
  *
  * Returns:    ---
  *             @...@ = other arguments
  *
  * Returns:    ---
@@ -215,17 +241,124 @@ static void a_flush(int fd, unsigned mode, void *v)
  * Use:                Sends a message to an admin connection.
  */
 
  * Use:                Sends a message to an admin connection.
  */
 
-static void a_write(admin *a, const char *fmt, ...)
+static void a_vwrite(admin *a, const char *tag, const char *fmt, va_list ap)
 {
 {
-  va_list ap;
   dstr d = DSTR_INIT;
   dstr d = DSTR_INIT;
+  if (tag) {
+    dstr_puts(&d, tag);
+    if (fmt)
+      dstr_putc(&d, ' ');
+  }
+  if (fmt)
+    dstr_vputf(&d, fmt, &ap);
+  dstr_putc(&d, '\n');
+  dosend(a, d.buf, d.len);
+  dstr_destroy(&d);
+}
+
+static void a_write(admin *a, const char *tag, const char *fmt, ...)
+{
+  va_list ap;
   va_start(ap, fmt);
   va_start(ap, fmt);
-  dstr_vputf(&d, fmt, &ap);
+  a_vwrite(a, tag, fmt, ap);
   va_end(ap);
   va_end(ap);
-  dosend(a, d.buf, d.len);
+}
+
+/* --- @a_ok@, @a_info@, @a_fail@ --- *
+ *
+ * Arguments:  @admin *a@ = connection
+ *             @const char *fmt@ = format string
+ *             @...@ = other arguments
+ *
+ * Returns:    ---
+ *
+ * Use:                Convenience functions for @a_write@.
+ */
+
+static void a_ok(admin *a) { a_write(a, "OK", 0); }
+
+static void a_info(admin *a, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  a_vwrite(a, "INFO", fmt, ap);
+  va_end(ap);
+}
+
+static void a_fail(admin *a, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  a_vwrite(a, "FAIL", fmt, ap);
+  va_end(ap);
+}
+
+/* --- @a_alert@, @a_valert@, @a_rawalert@ --- *
+ *
+ * Arguments:  @unsigned f_and, f_eq@ = filter for connections
+ *             @const char *tag@ = tag prefix string
+ *             @const char *fmt@ = pointer to format string
+ @             @const char *p@ = pointer to raw string
+ *             @size_t sz@ = size of raw string
+ *             @va_list ap@ = arguments in list
+ *             @...@ = other arguments
+ *
+ * Returns:    ---
+ *
+ * Use:                Write a message to all admin connections matched by the given
+ *             filter.
+ */
+
+static void a_rawalert(unsigned f_and, unsigned f_eq, const char *tag,
+                      const char *p, size_t sz)
+{
+  admin *a, *aa;
+  dstr d = DSTR_INIT;
+  
+  if (!(flags & F_INIT))
+    return;
+  if (tag) {
+    dstr_puts(&d, tag);
+    if (p)
+      dstr_putc(&d, ' ');
+  }
+  if (p)
+    dstr_putm(&d, p, sz);
+  dstr_putc(&d, '\n');
+  p = d.buf;
+  sz = d.len;
+  for (a = admins; a; a = aa) {
+    aa = a->next;
+    if ((a->f & f_and) == f_eq)
+      dosend(a, d.buf, d.len);
+  }
   dstr_destroy(&d);
 }
 
   dstr_destroy(&d);
 }
 
+static void a_valert(unsigned f_and, unsigned f_eq, const char *tag,
+                    const char *fmt, va_list ap)
+{
+  dstr d = DSTR_INIT;
+
+  if (!(flags & F_INIT))
+    return;
+  if (fmt)
+    dstr_vputf(&d, fmt, &ap);
+  a_rawalert(f_and, f_eq, tag, fmt ? d.buf : 0, fmt ? d.len : 0);
+  dstr_destroy(&d);
+}
+
+#if 0 /*unused*/
+static void a_alert(unsigned f_and, unsigned f_eq, const char *tag,
+                   const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  a_valert(f_and, f_eq, tag, fmt, ap);
+  va_end(ap);
+}
+#endif
+
 /* --- @a_warn@ --- *
  *
  * Arguments:  @const char *fmt@ = pointer to format string
 /* --- @a_warn@ --- *
  *
  * Arguments:  @const char *fmt@ = pointer to format string
@@ -239,24 +372,16 @@ static void a_write(admin *a, const char *fmt, ...)
 void a_warn(const char *fmt, ...)
 {
   va_list ap;
 void a_warn(const char *fmt, ...)
 {
   va_list ap;
-  admin *a, *aa;
-  dstr d = DSTR_INIT;
 
 
-  if (flags & F_INIT)
-    dstr_puts(&d, "WARN ");
   va_start(ap, fmt);
   va_start(ap, fmt);
-  dstr_vputf(&d, fmt, &ap);
-  va_end(ap);
-  if (!(flags & F_INIT))
-    moan("%s", d.buf);
+  if (flags & F_INIT)
+    a_valert(0, 0, "WARN", fmt, ap);
   else {
   else {
-    dstr_putc(&d, '\n');
-    for (a = admins; a; a = aa) {
-      aa = a->next;
-      dosend(a, d.buf, d.len);
-    }
+    fprintf(stderr, "%s: ", QUIS);
+    vfprintf(stderr, fmt, ap);
+    fputc('\n', stderr);
   }
   }
-  dstr_destroy(&d);
+  va_end(ap);
 }
 
 /* --- @a_trace@ --- *
 }
 
 /* --- @a_trace@ --- *
@@ -267,26 +392,36 @@ void a_warn(const char *fmt, ...)
  *
  * Returns:    ---
  *
  *
  * Returns:    ---
  *
- * Use:                Custom trace output handler.
+ * Use:                Custom trace output handler.  Sends trace messages to
+ *             interested admin connections.
  */
 
 #ifndef NTRACE
 static void a_trace(const char *p, size_t sz, void *v)
 {
  */
 
 #ifndef NTRACE
 static void a_trace(const char *p, size_t sz, void *v)
 {
-  dstr d = DSTR_INIT;
-  admin *a, *aa;
-
-  dstr_puts(&d, "TRACE ");
-  dstr_putm(&d, p, sz);
-  dstr_putc(&d, '\n');
-  for (a = admins; a; a = aa) {
-    aa = a->next;
-    dosend(a, d.buf, d.len);
-  }
-  dstr_destroy(&d);  
+  a_rawalert(AF_TRACE, AF_TRACE, "TRACE", p, sz);
 }
 #endif
 
 }
 #endif
 
+/* --- @a_notify@ --- *
+ *
+ * Arguments:  @const char *fmt@ = pointer to format string
+ *             @...@ = other arguments
+ *
+ * Returns:    ---
+ *
+ * Use:                Sends a notification to interested admin connections.
+ */
+
+void a_notify(const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  a_valert(AF_NOTE, AF_NOTE, "NOTE", fmt, ap);
+  va_end(ap);
+}
+
 /* --- @a_quit@ --- *
  *
  * Arguments:  ---
 /* --- @a_quit@ --- *
  *
  * Arguments:  ---
@@ -322,11 +457,11 @@ static void a_sigdie(int sig, void *v)
     case SIGTERM:      p = "SIGTERM"; break;
     case SIGINT:       p = "SIGINT"; break;
     default:
     case SIGTERM:      p = "SIGTERM"; break;
     case SIGINT:       p = "SIGINT"; break;
     default:
-      sprintf(buf, "signal %i", sig);
+      sprintf(buf, "%i", sig);
       p = buf;
       break;
   }
       p = buf;
       break;
   }
-  a_warn("shutting down on %s", p);
+  a_warn("SERVER quit signal %s", p);
   a_quit();
 }
 
   a_quit();
 }
 
@@ -342,7 +477,7 @@ static void a_sigdie(int sig, void *v)
 
 static void a_sighup(int sig, void *v)
 {
 
 static void a_sighup(int sig, void *v)
 {
-  a_warn("received SIGHUP: ignoring");
+  a_warn("SERVER ignore signal SIGHUP");
 }
 
 /*----- Adding peers ------------------------------------------------------*/
 }
 
 /*----- Adding peers ------------------------------------------------------*/
@@ -366,15 +501,15 @@ static void a_resolve(struct hostent *h, void *v)
   TIMER;
   sel_rmtimer(&a->t);
   if (!h)
   TIMER;
   sel_rmtimer(&a->t);
   if (!h)
-    a_write(a, "FAIL couldn't resolve hostname `%s'\n", a->paddr);
+    a_fail(a, "resolve-error %s", a->paddr);
   else if (p_find(a->pname))
   else if (p_find(a->pname))
-    a_write(a, "FAIL peer `%s' already registered\n", a->pname);
+    a_fail(a, "peer-exists %s", a->pname);
   else {
     memcpy(&a->peer.sin.sin_addr, h->h_addr, sizeof(struct in_addr));
     if (!p_create(a->pname, &a->peer.sa, a->sasz))
   else {
     memcpy(&a->peer.sin.sin_addr, h->h_addr, sizeof(struct in_addr));
     if (!p_create(a->pname, &a->peer.sa, a->sasz))
-      a_write(a, "FAIL couldn't create peer\n");
+      a_fail(a, "peer-create-fail %s" a->pname);
     else
     else
-      a_write(a, "OK\n");
+      a_ok(a);
   }
   xfree(a->pname);
   xfree(a->paddr);
   }
   xfree(a->pname);
   xfree(a->paddr);
@@ -400,7 +535,7 @@ static void a_timer(struct timeval *tv, void *v)
   a_lock(a);
   T( trace(T_ADMIN, "admin: %u resolver timeout", a->seq); )
   bres_abort(&a->r);
   a_lock(a);
   T( trace(T_ADMIN, "admin: %u resolver timeout", a->seq); )
   bres_abort(&a->r);
-  a_write(a, "FAIL timeout resolving `%s'\n", a->paddr);
+  a_fail(a, "resolver-timeout %s\n", a->paddr);
   xfree(a->pname);
   xfree(a->paddr);
   a->pname = 0;
   xfree(a->pname);
   xfree(a->paddr);
   a->pname = 0;
@@ -423,42 +558,49 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
 {
   unsigned long pt;
   struct timeval tv;
 {
   unsigned long pt;
   struct timeval tv;
+  unsigned i;
   char *p;
 
   /* --- Make sure someone's not got there already --- */
 
   if (p_find(av[0])) {
   char *p;
 
   /* --- Make sure someone's not got there already --- */
 
   if (p_find(av[0])) {
-    a_write(a, "FAIL peer `%s' already registered\n", av[0]);
+    a_fail(a, "peer-exists %s", av[0]);
     return;
   }
 
   /* --- Fill in the easy bits of address --- */
 
   BURN(a->peer);
     return;
   }
 
   /* --- Fill in the easy bits of address --- */
 
   BURN(a->peer);
+  i = 1;
+  if (mystrieq(av[i], "inet")) i++;
+  if (ac - i != 2) {
+    a_fail(a, "bad-syntax -- add PEER [inet] ADDRESS PORT");
+    return;
+  }
   a->peer.sin.sin_family = AF_INET;
   a->sasz = sizeof(a->peer.sin);
   a->peer.sin.sin_family = AF_INET;
   a->sasz = sizeof(a->peer.sin);
-  pt = strtoul(av[2], &p, 0);
+  pt = strtoul(av[i + 1], &p, 0);
   if (*p) {
   if (*p) {
-    struct servent *s = getservbyname(av[2], "udp");
+    struct servent *s = getservbyname(av[i + 1], "udp");
     if (!s) {
     if (!s) {
-      a_write(a, "FAIL service `%s' not known\n", av[2]);
+      a_fail(a, "unknown-service %s", av[i + 1]);
       return;
     }
     pt = ntohs(s->s_port);
   }
   if (pt == 0 || pt >= 65536) {
       return;
     }
     pt = ntohs(s->s_port);
   }
   if (pt == 0 || pt >= 65536) {
-    a_write(a, "FAIL bad port number %lu\n", pt);
+    a_fail(a, "invalid-port %lu", pt);
     return;
   }
   a->peer.sin.sin_port = htons(pt);
 
   /* --- If the name is numeric, do it the easy way --- */
   
     return;
   }
   a->peer.sin.sin_port = htons(pt);
 
   /* --- If the name is numeric, do it the easy way --- */
   
-  if (inet_aton(av[1], &a->peer.sin.sin_addr)) {
+  if (inet_aton(av[i], &a->peer.sin.sin_addr)) {
     if (!p_create(av[0], &a->peer.sa, a->sasz))
     if (!p_create(av[0], &a->peer.sa, a->sasz))
-      a_write(a, "FAIL couldn't create peer\n");
+      a_fail(a, "peer-create-fail %s", a->pname);
     else
     else
-      a_write(a, "OK\n");
+      a_ok(a);
     return;
   }
 
     return;
   }
 
@@ -470,7 +612,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
    */
 
   a->pname = xstrdup(av[0]);
    */
 
   a->pname = xstrdup(av[0]);
-  a->paddr = xstrdup(av[1]);
+  a->paddr = xstrdup(av[i]);
   selbuf_disable(&a->b);
   gettimeofday(&tv, 0);
   tv.tv_sec += T_RESOLVE;
   selbuf_disable(&a->b);
   gettimeofday(&tv, 0);
   tv.tv_sec += T_RESOLVE;
@@ -484,21 +626,36 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
 
 /* --- Miscellaneous commands --- */
 
 
 /* --- Miscellaneous commands --- */
 
-#ifndef NTRACE
+/* --- @traceish@ --- *
+ *
+ * Arguments:  @admin *a@ = connection to complain on
+ *             @unsigned ac@ = number of arguments
+ *             @char *av[]@ = vector of arguments
+ *             @const char *what@ = what we're messing with
+ *             @const trace_opt *tt@ = options table
+ *             @unsigned *ff@ = where the flags are
+ *
+ * Returns:    Nonzero if anything changed.
+ *
+ * Use:                Guts of trace-ish commands like `trace' and `watch'.
+ */
 
 
-static void acmd_trace(admin *a, unsigned ac, char *av[])
+static int traceish(admin *a, unsigned ac, char *av[],
+                   const char *what, const trace_opt *tt, unsigned *ff)
 {
 {
+  int ch = 0;
+
   if (!ac || strcmp(av[0], "?") == 0) {
     const trace_opt *t;
   if (!ac || strcmp(av[0], "?") == 0) {
     const trace_opt *t;
-    a_write(a, "INFO Trace options:\n");
-    for (t = tr_opts; t->ch; t++) {
-      a_write(a, "INFO %c %c  %s\n",
-             t->ch, (tr_flags & t->f) == t->f ? '*' : ' ', t->help);
+    a_info(a, "Current %s status:", what);
+    for (t = tt; t->ch; t++) {
+      a_info(a, "%c %c  %s",
+            t->ch, (*ff & t->f) == t->f ? '*' : ' ', t->help);
     }
   } else {
     unsigned sense = 1;
     }
   } else {
     unsigned sense = 1;
-    unsigned f = tr_flags;
-    const trace_opt *tt;
+    unsigned f = *ff;
+    const trace_opt *t;
     char *p = av[0];
 
     while (*p) {
     char *p = av[0];
 
     while (*p) {
@@ -506,46 +663,98 @@ static void acmd_trace(admin *a, unsigned ac, char *av[])
        case '+': sense = 1; break;
        case '-': sense = 0; break;
        default:
        case '+': sense = 1; break;
        case '-': sense = 0; break;
        default:
-         for (tt = tr_opts; tt->ch; tt++) {
-           if (tt->ch == *p) {
-             if (sense) f |= tt->f;
-             else f &= ~tt->f;
+         for (t = tt; t->ch; t++) {
+           if (t->ch == *p) {
+             if (sense) f |= t->f;
+             else f &= ~t->f;
              goto tropt_ok;
            }
          }
              goto tropt_ok;
            }
          }
-         a_write(a, "FAIL unknown trace option `%c'\n", *p);
-         return;
+         a_fail(a, "bad-%s-option %c", what, *p);
+         return (0);
         tropt_ok:;
          break;
       }
       p++;
     }
         tropt_ok:;
          break;
       }
       p++;
     }
-    tr_flags = f;
-    trace_level(tr_flags);
+    *ff = f;
+    ch = 1;
   }
   }
-  a_write(a, "OK\n");
+  a_ok(a);
+  return (ch);
+}
+
+#ifndef NTRACE
+
+static void acmd_trace(admin *a, unsigned ac, char *av[])
+{
+  if (traceish(a, ac, av, "trace", tr_opts, &tr_flags))
+    trace_level(tr_flags);
 }
 
 #endif
 
 }
 
 #endif
 
+static void acmd_watch(admin *a, unsigned ac, char *av[])
+{
+  traceish(a, ac, av, "watch", w_opts, &a->f);
+}
+
+static void quotify(dstr *d, const char *p)
+{
+  if (d->len)
+    dstr_putc(d, ' ');
+  if (*p && !p[strcspn(p, "\"' \t\n\v")])
+    dstr_puts(d, p);
+  else {
+    dstr_putc(d, '\"');
+    while (*p) {
+      if (*p == '\\' || *p == '\"')
+       dstr_putc(d, '\\');
+      dstr_putc(d, *p++);
+    }
+    dstr_putc(d, '\"');
+  }
+}
+
+static void alertcmd(admin *a, unsigned f_and, unsigned f_eq,
+                    const char *tag, unsigned ac, char *av[])
+{
+  dstr d = DSTR_INIT;
+  unsigned i;
+
+  dstr_puts(&d, "USER");
+  for (i = 0; i < ac; i++)
+    quotify(&d, av[i]);
+  dstr_putz(&d);
+  a_rawalert(f_and, f_eq, tag, d.buf, d.len);
+  dstr_destroy(&d);
+  a_ok(a);
+}
+
+static void acmd_notify(admin *a, unsigned ac, char *av[])
+  { alertcmd(a, AF_NOTE, AF_NOTE, "NOTE", ac, av); }
+static void acmd_warn(admin *a, unsigned ac, char *av[])
+  { alertcmd(a, AF_WARN, AF_WARN, "WARN", ac, av); }
+
 static void acmd_port(admin *a, unsigned ac, char *av[])
 {
 static void acmd_port(admin *a, unsigned ac, char *av[])
 {
-  a_write(a, "INFO %u\nOK\n", p_port());
+  a_info(a, "%u", p_port());
+  a_ok(a);
 }
 
 static void acmd_daemon(admin *a, unsigned ac, char *av[])
 {
   if (flags & F_DAEMON)
 }
 
 static void acmd_daemon(admin *a, unsigned ac, char *av[])
 {
   if (flags & F_DAEMON)
-    a_write(a, "FAIL already running as a daemon\n");
+    a_fail(a, "already-daemon");
   else {
   else {
-    a_warn("becoming a daemon");
+    a_notify("DAEMON");
     if (a_stdin)
       a_destroy(a_stdin);
     if (u_daemon())
     if (a_stdin)
       a_destroy(a_stdin);
     if (u_daemon())
-      a_write(a, "FAIL error becoming a daemon: %s", strerror(errno));
+      a_fail(a, "daemon-error -- %s", strerror(errno));
     else {
       flags |= F_DAEMON;
     else {
       flags |= F_DAEMON;
-      a_write(a, "OK\n");
+      a_ok(a);
     }
   }
 }
     }
   }
 }
@@ -554,8 +763,8 @@ static void acmd_list(admin *a, unsigned ac, char *av[])
 {
   peer *p;
   for (p = p_first(); p; p = p_next(p))
 {
   peer *p;
   for (p = p_first(); p; p = p_next(p))
-    a_write(a, "INFO %s\n", p_name(p));
-  a_write(a, "OK\n");
+    a_info(a, "%s", p_name(p));
+  a_ok(a);
 }
 
 static void acmd_ifname(admin *a, unsigned ac, char *av[])
 }
 
 static void acmd_ifname(admin *a, unsigned ac, char *av[])
@@ -563,9 +772,11 @@ static void acmd_ifname(admin *a, unsigned ac, char *av[])
   peer *p;
 
   if ((p = p_find(av[0])) == 0)
   peer *p;
 
   if ((p = p_find(av[0])) == 0)
-    a_write(a, "FAIL peer `%s' not found\n", av[0]);
-  else
-    a_write(a, "INFO %s\nOK\n", p_ifname(p));
+    a_fail(a, "unknown-peer %s", av[0]);
+  else {
+    a_info(a, "%s", p_ifname(p));
+    a_ok(a);
+  }
 }
 
 static void acmd_addr(admin *a, unsigned ac, char *av[])
 }
 
 static void acmd_addr(admin *a, unsigned ac, char *av[])
@@ -574,13 +785,14 @@ static void acmd_addr(admin *a, unsigned ac, char *av[])
   const addr *ad;
 
   if ((p = p_find(av[0])) == 0)
   const addr *ad;
 
   if ((p = p_find(av[0])) == 0)
-    a_write(a, "FAIL peer `%s' not found\n", av[0]);
+    a_fail(a, "unknown-peer %s", av[0]);
   else {
     ad = p_addr(p);
     assert(ad->sa.sa_family == AF_INET);
   else {
     ad = p_addr(p);
     assert(ad->sa.sa_family == AF_INET);
-    a_write(a, "INFO %s %u\nOK\n",
+    a_info(a, "INET %s %u",
            inet_ntoa(ad->sin.sin_addr),
            (unsigned)ntohs(ad->sin.sin_port));
            inet_ntoa(ad->sin.sin_addr),
            (unsigned)ntohs(ad->sin.sin_port));
+    a_ok(a);
   }
 }
 
   }
 }
 
@@ -590,24 +802,25 @@ static void acmd_stats(admin *a, unsigned ac, char *av[])
   stats *st;
 
   if ((p = p_find(av[0])) == 0)
   stats *st;
 
   if ((p = p_find(av[0])) == 0)
-    a_write(a, "FAIL peer `%s' not found\n", av[0]);
+    a_fail(a, "unknown-peer %s", av[0]);
   else {
     st = p_stats(p);
   else {
     st = p_stats(p);
-    a_write(a, "INFO start-time=%s\n", timestr(st->t_start));
-    a_write(a, "INFO last-packet-time=%s\n", timestr(st->t_last));
-    a_write(a, "INFO packets-in=%lu bytes-in=%lu\n", st->n_in, st->sz_in);
-    a_write(a, "INFO packets-out=%lu bytes-out=%lu\n",
+    a_info(a, "start-time=%s", timestr(st->t_start));
+    a_info(a, "last-packet-time=%s", timestr(st->t_last));
+    a_info(a, "last-keyexch-time=%s", timestr(st->t_kx));
+    a_info(a, "packets-in=%lu bytes-in=%lu", st->n_in, st->sz_in);
+    a_info(a, "packets-out=%lu bytes-out=%lu",
            st->n_out, st->sz_out);
            st->n_out, st->sz_out);
-    a_write(a, "INFO keyexch-packets-in=%lu keyexch-bytes-in=%lu\n",
+    a_info(a, "keyexch-packets-in=%lu keyexch-bytes-in=%lu",
            st->n_kxin, st->sz_kxin);
            st->n_kxin, st->sz_kxin);
-    a_write(a, "INFO keyexch-packets-out=%lu keyexch-bytes-out=%lu\n",
+    a_info(a, "keyexch-packets-out=%lu keyexch-bytes-out=%lu",
            st->n_kxout, st->sz_kxout);
            st->n_kxout, st->sz_kxout);
-    a_write(a, "INFO ip-packets-in=%lu ip-bytes-in=%lu\n",
+    a_info(a, "ip-packets-in=%lu ip-bytes-in=%lu",
            st->n_ipin, st->sz_ipin);
            st->n_ipin, st->sz_ipin);
-    a_write(a, "INFO ip-packets-out=%lu ip-bytes-out=%lu\n",
+    a_info(a, "ip-packets-out=%lu ip-bytes-out=%lu",
            st->n_ipout, st->sz_ipout);
            st->n_ipout, st->sz_ipout);
-    a_write(a, "INFO rejected-packets=%lu\n", st->n_reject);
-    a_write(a, "OK\n");
+    a_info(a, "rejected-packets=%lu", st->n_reject);
+    a_ok(a);
   }
 }
 
   }
 }
 
@@ -615,20 +828,26 @@ static void acmd_kill(admin *a, unsigned ac, char *av[])
 {
   peer *p;
   if ((p = p_find(av[0])) == 0)
 {
   peer *p;
   if ((p = p_find(av[0])) == 0)
-    a_write(a, "FAIL peer `%s' not found\n", av[0]);
+    a_fail(a, "unknown-peer %s", av[0]);
   else {
     p_destroy(p);
   else {
     p_destroy(p);
-    a_write(a, "OK\n");
+    a_ok(a);
   }
 }
 
 static void acmd_quit(admin *a, unsigned ac, char *av[])
 {
   }
 }
 
 static void acmd_quit(admin *a, unsigned ac, char *av[])
 {
-  a_warn("closing down on admin request");
-  a_write(a, "OK\n");
+  a_warn("SERVER quit admin-request");
+  a_ok(a);
   a_quit();
 }
 
   a_quit();
 }
 
+static void acmd_version(admin *a, unsigned ac, char *av[])
+{
+  a_info(a, "%s %s", PACKAGE, VERSION);
+  a_ok(a);
+}
+
 /* --- The command table and help --- */
 
 typedef struct acmd {
 /* --- The command table and help --- */
 
 typedef struct acmd {
@@ -642,9 +861,13 @@ static void acmd_help(admin */*a*/, unsigned /*ac*/, char */*av*/[]);
 
 static const acmd acmdtab[] = {
   { "help",    "help",                 0,      0,      acmd_help },
 
 static const acmd acmdtab[] = {
   { "help",    "help",                 0,      0,      acmd_help },
+  { "version", "version",              0,      0,      acmd_version },
 #ifndef NTRACE
   { "trace",   "trace [OPTIONS]",      0,      1,      acmd_trace },
 #endif
 #ifndef NTRACE
   { "trace",   "trace [OPTIONS]",      0,      1,      acmd_trace },
 #endif
+  { "watch",   "watch [OPTIONS]",      0,      1,      acmd_watch },
+  { "notify",  "notify MESSAGE ...",   1,      0xffff, acmd_notify },
+  { "warn",    "warn MESSAGE ...",     1,      0xffff, acmd_warn },
   { "port",    "port",                 0,      0,      acmd_port },
   { "daemon",  "daemon",               0,      0,      acmd_daemon },
   { "list",    "list",                 0,      0,      acmd_list },
   { "port",    "port",                 0,      0,      acmd_port },
   { "daemon",  "daemon",               0,      0,      acmd_daemon },
   { "list",    "list",                 0,      0,      acmd_list },
@@ -652,7 +875,7 @@ static const acmd acmdtab[] = {
   { "addr",    "addr PEER",            1,      1,      acmd_addr },
   { "stats",   "stats PEER",           1,      1,      acmd_stats },
   { "kill",    "kill PEER",            1,      1,      acmd_kill },
   { "addr",    "addr PEER",            1,      1,      acmd_addr },
   { "stats",   "stats PEER",           1,      1,      acmd_stats },
   { "kill",    "kill PEER",            1,      1,      acmd_kill },
-  { "add",     "add PEER ADDR PORT",   3,      3,      acmd_add },
+  { "add",     "add PEER ADDR ...",    2,      0xffff, acmd_add },
   { "quit",    "quit",                 0,      0,      acmd_quit },
   { 0,         0,                      0,      0,      0 }
 };
   { "quit",    "quit",                 0,      0,      acmd_quit },
   { 0,         0,                      0,      0,      0 }
 };
@@ -661,8 +884,8 @@ static void acmd_help(admin *a, unsigned ac, char *av[])
 {
   const acmd *c;
   for (c = acmdtab; c->name; c++)
 {
   const acmd *c;
   for (c = acmdtab; c->name; c++)
-    a_write(a, "INFO %s\n", c->help);
-  a_write(a, "OK\n");
+    a_info(a, "%s", c->help);
+  a_ok(a);
 }
 
 /*----- Connection handling -----------------------------------------------*/
 }
 
 /*----- Connection handling -----------------------------------------------*/
@@ -781,7 +1004,7 @@ static void a_line(char *p, size_t len, void *vp)
 {
   admin *a = vp;
   const acmd *c;
 {
   admin *a = vp;
   const acmd *c;
-  char *av[4];
+  char *av[16];
   size_t ac;
 
   TIMER;
   size_t ac;
 
   TIMER;
@@ -791,15 +1014,14 @@ static void a_line(char *p, size_t len, void *vp)
     a_destroy(a);
     return;
   }
     a_destroy(a);
     return;
   }
-  ac = str_qsplit(p, av, 4, 0, STRF_QUOTE);
+  ac = str_qsplit(p, av, 16, 0, STRF_QUOTE);
   if (!ac)
     return;
   if (!ac)
     return;
-  for (p = av[0]; *p; p++) *p = tolower((unsigned char)*p);
   for (c = acmdtab; c->name; c++) {
   for (c = acmdtab; c->name; c++) {
-    if (strcmp(av[0], c->name) == 0) {
+    if (mystrieq(av[0], c->name)) {
       ac--;
       if (c->argmin > ac || ac > c->argmax)
       ac--;
       if (c->argmin > ac || ac > c->argmax)
-       a_write(a, "FAIL syntax: %s\n", c->help);
+       a_fail(a, "bad-syntax -- %s", c->help);
       else {
        a_lock(a);
        c->func(a, ac, av + 1);
       else {
        a_lock(a);
        c->func(a, ac, av + 1);
@@ -808,26 +1030,28 @@ static void a_line(char *p, size_t len, void *vp)
       return;
     }
   }
       return;
     }
   }
-  a_write(a, "FAIL unknown command `%s'\n", av[0]);
+  a_fail(a, "unknown-command %s", av[0]);
 }
 
 /* --- @a_create@ --- *
  *
  * Arguments:  @int fd_in, fd_out@ = file descriptors to use
 }
 
 /* --- @a_create@ --- *
  *
  * Arguments:  @int fd_in, fd_out@ = file descriptors to use
+ *             @unsigned f@ = initial flags to set
  *
  * Returns:    ---
  *
  * Use:                Creates a new admin connection.
  */
 
  *
  * Returns:    ---
  *
  * Use:                Creates a new admin connection.
  */
 
-void a_create(int fd_in, int fd_out)
+void a_create(int fd_in, int fd_out, unsigned f)
 {
   admin *a = CREATE(admin);
 {
   admin *a = CREATE(admin);
+
   T( static unsigned seq = 0;
      a->seq = seq++; )
   T( trace(T_ADMIN, "admin: accepted connection %u", a->seq); )
   a->pname = 0;
   T( static unsigned seq = 0;
      a->seq = seq++; )
   T( trace(T_ADMIN, "admin: accepted connection %u", a->seq); )
   a->pname = 0;
-  a->f = 0;
+  a->f = f;
   if (fd_in == STDIN_FILENO)
     a_stdin = a;
   fdflags(fd_in, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   if (fd_in == STDIN_FILENO)
     a_stdin = a;
   fdflags(fd_in, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
@@ -864,10 +1088,10 @@ static void a_accept(int fd, unsigned mode, void *v)
   if ((nfd = accept(fd, (struct sockaddr *)&sun, &sz)) < 0) {
     if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK &&
        errno != ECONNABORTED && errno != EPROTO)
   if ((nfd = accept(fd, (struct sockaddr *)&sun, &sz)) < 0) {
     if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK &&
        errno != ECONNABORTED && errno != EPROTO)
-      a_warn("accept admin connection failed: %s", strerror(errno));
+      a_warn("ADMIN accept-error -- %s", strerror(errno));
     return;
   }
     return;
   }
-  a_create(nfd, nfd);
+  a_create(nfd, nfd, 0);
 }
 
 /* --- @a_daemon@ --- *
 }
 
 /* --- @a_daemon@ --- *
@@ -963,6 +1187,7 @@ again:
 
   sig_add(&s_term, SIGTERM, a_sigdie, 0);
   sig_add(&s_hup, SIGHUP, a_sighup, 0);
 
   sig_add(&s_term, SIGTERM, a_sigdie, 0);
   sig_add(&s_hup, SIGHUP, a_sighup, 0);
+  signal(SIGPIPE, SIG_IGN);
   sigaction(SIGINT, 0, &sa);
   if (sa.sa_handler != SIG_IGN)
     sig_add(&s_int, SIGINT, a_sigdie, 0);
   sigaction(SIGINT, 0, &sa);
   if (sa.sa_handler != SIG_IGN)
     sig_add(&s_int, SIGINT, a_sigdie, 0);
index 7edc790bfb7af0a2b637b0c41ddfbc1a632b03ba..314bb87cb0241103760aa81803aa585bde680b3e 100644 (file)
--- a/client.c
+++ b/client.c
@@ -169,7 +169,48 @@ static void uline(char *p, size_t len, void *b)
     f |= f_uclose;
   } else {
     p[len] = '\n';
     f |= f_uclose;
   } else {
     p[len] = '\n';
-    write(fd, p, len + 1);
+    errno = EIO;
+    if (write(fd, p, len + 1) != len + 1)
+      moan("write failed: %s", strerror(errno));
+  }
+}
+
+static void setup(const char *cmd)
+{
+  dstr d = DSTR_INIT;
+  char ch;
+  char *p, *q;
+  int n;
+
+  dstr_puts(&d, cmd);
+  dstr_putc(&d, '\n');
+  errno = EIO; /* Relax: be vague */
+  if (write(fd, d.buf, d.len) != d.len) {
+    die(EXIT_FAILURE, "error sending setup command `%s': %s",
+       cmd, strerror(errno));
+  }
+  dstr_reset(&d);
+  for (;;) {
+    n = read(fd, &ch, 1);
+    if (!n)
+      die(EXIT_FAILURE, "unexpected EOF during setup");
+    if (n < 0) {
+      die(EXIT_FAILURE, "error receiving reply to `%s': %s",
+         cmd, strerror(errno));
+    }
+    if (d.len < 256)
+      dstr_putc(&d, ch);
+    if (ch == '\n') {
+      p = d.buf;
+      q = str_getword(&p);
+      if (!q)
+       ;
+      else if (strcmp(q, "OK") == 0)
+       return;
+      else if (strcmp(q, "FAIL") == 0)
+       die(EXIT_FAILURE, "setup command `%s' failed: %s", cmd, p);
+      dstr_reset(&d);
+    }
   }
 }
 
   }
 }
 
@@ -245,7 +286,7 @@ Options in full:\n\
 \n\
 -D, --daemon           Become a background task after connecting.\n\
 -d, --directory=DIR    Select current directory [default " CONFIGDIR "].\n\
 \n\
 -D, --daemon           Become a background task after connecting.\n\
 -d, --directory=DIR    Select current directory [default " CONFIGDIR "].\n\
--a, --admin-socket=FILE        Select socket to connect to
+-a, --admin-socket=FILE        Select socket to connect to\n\
                           [default " SOCKETDIR "/tripesock].\n\
 -P, --pidfile=FILE     Write process-id to FILE.\n\
 \n\
                           [default " SOCKETDIR "/tripesock].\n\
 -P, --pidfile=FILE     Write process-id to FILE.\n\
 \n\
@@ -440,9 +481,12 @@ int main(int argc, char *argv[])
     fprintf(pidfp, "%li\n", (long)getpid());
     fclose(pidfp);
   }
     fprintf(pidfp, "%li\n", (long)getpid());
     fclose(pidfp);
   }
+  signal(SIGPIPE, SIG_IGN);
 
   /* --- If we're meant to be interactive, do that --- */
 
 
   /* --- If we're meant to be interactive, do that --- */
 
+  if (optind == argc)
+    setup("WATCH -A+tw");
   if (!(f & f_noinput) && optind == argc) {
     sel_state sel;
     selbuf bu, bs;
   if (!(f & f_noinput) && optind == argc) {
     sel_state sel;
     selbuf bu, bs;
@@ -460,14 +504,16 @@ int main(int argc, char *argv[])
 
   if (optind < argc) {
     dstr d = DSTR_INIT;
 
   if (optind < argc) {
     dstr d = DSTR_INIT;
+    setup((f & f_warn) ? "WATCH -A+w" : "WATCH -A");
     dstr_puts(&d, argv[optind++]);
     while (optind < argc) {
       dstr_putc(&d, ' ');
       dstr_puts(&d, argv[optind++]);
     }
     dstr_putc(&d, '\n');
     dstr_puts(&d, argv[optind++]);
     while (optind < argc) {
       dstr_putc(&d, ' ');
       dstr_puts(&d, argv[optind++]);
     }
     dstr_putc(&d, '\n');
-    write(fd, d.buf, d.len);
-    shutdown(fd, 1);
+    errno = EIO;
+    if (write(fd, d.buf, d.len) != d.len || shutdown(fd, 1))
+      die(EXIT_FAILURE, "write failed: %s", strerror(errno));
     dstr_destroy(&d);
     f |= f_command;
   }
     dstr_destroy(&d);
     f |= f_command;
   }
index 03ad025c7cf8ff08d3815986d1e4548c1ec65b97..6163a8d87fed39f15e96709ade8f83f57dbf5ff5 100644 (file)
@@ -1,6 +1,6 @@
 dnl -*-autoconf-*-
 dnl
 dnl -*-autoconf-*-
 dnl
-dnl $Id: configure.in,v 1.16 2004/04/19 07:44:16 mdw Exp $
+dnl $Id$
 dnl
 dnl Configuration script for TrIPE
 dnl
 dnl
 dnl Configuration script for TrIPE
 dnl
@@ -33,6 +33,7 @@ AC_CANONICAL_HOST
 AC_PROG_MAKE_SET
 AC_PROG_CC
 AM_PROG_LIBTOOL
 AC_PROG_MAKE_SET
 AC_PROG_CC
 AM_PROG_LIBTOOL
+AC_CHECK_HEADERS([stdarg.h])
 mdw_GCC_FLAGS([-Wall])
 mdw_OPT_TRACE
 
 mdw_GCC_FLAGS([-Wall])
 mdw_OPT_TRACE
 
@@ -90,17 +91,20 @@ changequote(,)dnl
       2.[4-9].* | 2.[1-9][0-9]*.* | [3-9].* | [1-9][0-9]*.*)
 changequote([,])dnl
        tun=linux
       2.[4-9].* | 2.[1-9][0-9]*.* | [3-9].* | [1-9][0-9]*.*)
 changequote([,])dnl
        tun=linux
-       AC_DEFINE([TUN_TYPE], [TUN_LINUX])
+       AC_DEFINE([TUN_TYPE], [TUN_LINUX], 
+        [Set to the tunnel driver for your OS.  See TUN_* in tripe.h.])
        ;;
       *)
        tun=unet
        ;;
       *)
        tun=unet
-       AC_DEFINE([TUN_TYPE], [TUN_UNET])
+       AC_DEFINE([TUN_TYPE], [TUN_UNET],
+        [Set to the tunnel driver for your OS.  See TUN_* in tripe.h.])
        ;;
     esac
     ;;
   *bsd*)
     tun=bsd
        ;;
     esac
     ;;
   *bsd*)
     tun=bsd
-    AC_DEFINE([TUN_TYPE], [TUN_BSD])
+    AC_DEFINE([TUN_TYPE], [TUN_BSD],
+    [Set to the tunnel driver for your OS.  See TUN_* in tripe.h.])
     ;;
   *)
     AC_MSG_ERROR([Unsupported OS: no tunnel interface available])
     ;;
   *)
     AC_MSG_ERROR([Unsupported OS: no tunnel interface available])
@@ -118,14 +122,14 @@ if test "$ethereal" = true -a "$ETHEREAL_PLUGIN_DIR" = unknown; then
     mdw_cv_ethereal_plugin_dir="failed"
     ethprefix=none
     for i in "${prefix}" /usr/local /usr `echo $PATH | tr : " "`; do
     mdw_cv_ethereal_plugin_dir="failed"
     ethprefix=none
     for i in "${prefix}" /usr/local /usr `echo $PATH | tr : " "`; do
-      if test -x "$i/bin/ethereal"; then
+      if test -x "$i/bin/tethereal"; then
         ethprefix=$i
         break
       fi
     done
     if test "$ethprefix" != none; then
         ethprefix=$i
         break
       fi
     done
     if test "$ethprefix" != none; then
-      ethbin=$ethprefix/bin/ethereal
-      ethver=`$ethbin -v | sed 's/^[^ ]* \([0-9A-Za-z.]*\).*$/\1/'`
+      ethbin=$ethprefix/bin/tethereal
+      ethver=`$ethbin -v | sed 's/^[^ ]* \([0-9A-Za-z.]*\).*$/\1/;q'`
       dir=$ethprefix/lib/ethereal/plugins/$ethver
       if test -d "$dir"; then
         mdw_cv_ethereal_plugin_dir=$dir
       dir=$ethprefix/lib/ethereal/plugins/$ethver
       if test -d "$dir"; then
         mdw_cv_ethereal_plugin_dir=$dir
@@ -162,10 +166,11 @@ if test "$ethereal" = true; then
       AC_TRY_COMPILE([
 #include <netinet/in.h>
 #include <glib.h>
       AC_TRY_COMPILE([
 #include <netinet/in.h>
 #include <glib.h>
-#include <epan/packet.h>
+#include <ethereal/config.h>
+#include <ethereal/epan/packet.h>
 ], [
        dissector_handle_t dh;
 ], [
        dissector_handle_t dh;
-       dh = creat_dissector_handle(0, 0);
+       dh = create_dissector_handle(0, 0);
       ], [bad=false; break])
     done
     if test $bad = false; then
       ], [bad=false; break])
     done
     if test $bad = false; then
@@ -180,26 +185,6 @@ if test "$ethereal" = true; then
 fi
 
 if test "$ethereal" = true; then
 fi
 
 if test "$ethereal" = true; then
-  AC_CACHE_CHECK([whether the Ethereal headers are broken],
-    [mdw_cv_ethereal_buggered], [
-    CFLAGS="$GLIB_CFLAGS $i"
-    AC_TRY_COMPILE([
-#include <netinet/in.h>
-#include <glib.h>
-#include <epan/packet.h>
-#include <plugins/plugin_api.h>
-], [
-      G_MODULE_EXPORT void plugin_init(plugin_address_table_t *pat)
-      {
-        plugin_address_table_init(pat);
-      }
-    ], [mdw_cv_ethereal_buggered=no], [mdw_cv_ethereal_buggered=yes])
-    CFLAGS=$mdw_CFLAGS
-  ])
-  if test $mdw_cv_ethereal_buggered = yes; then
-    AC_DEFINE(ETHEREAL_BUGGERED)
-  fi
-
   ETHEREAL_CFLAGS="$CFLAGS $GLIB_CFLAGS $mdw_cv_ethereal_includes"
   AC_SUBST(ETHEREAL_CFLAGS)
   AC_SUBST(ETHEREAL_PLUGIN_DIR)
   ETHEREAL_CFLAGS="$CFLAGS $GLIB_CFLAGS $mdw_cv_ethereal_includes"
   AC_SUBST(ETHEREAL_CFLAGS)
   AC_SUBST(ETHEREAL_PLUGIN_DIR)
@@ -210,6 +195,10 @@ if test "$ethereal" = false -a "$requireethereal" = true; then
   AC_MSG_ERROR([failed to configure Ethereal plugin])
 fi
 
   AC_MSG_ERROR([failed to configure Ethereal plugin])
 fi
 
+AH_TEMPLATE([CONFIGDIR],
+            [Tripe should look here for keys and other configuration.])
+AH_TEMPLATE([SOCKETDIR],
+            [Tripe should make its administration socket here.])
 mdw_DEFINE_PATHS([
   mdw_DEFINE_PATH([CONFIGDIR], [$configdir])
   mdw_DEFINE_PATH([SOCKETDIR], [$socketdir])
 mdw_DEFINE_PATHS([
   mdw_DEFINE_PATH([CONFIGDIR], [$configdir])
   mdw_DEFINE_PATH([SOCKETDIR], [$socketdir])
index 1fb7fdf75d5235bbe0dcb27fbb3c7e5751b8a6c5..337580a5d5e15b8286da38a6809f3ac07946c967 100644 (file)
@@ -3,7 +3,7 @@ Section: net
 Priority: extra
 Maintainer: Mark Wooding <mdw@nsict.org>
 Build-Depends: catacomb-dev (>= 2.1.0), mlib-dev (>= 2.0.3),
 Priority: extra
 Maintainer: Mark Wooding <mdw@nsict.org>
 Build-Depends: catacomb-dev (>= 2.1.0), mlib-dev (>= 2.0.3),
ethereal-dev, debhelper (>= 4.0.2)
tethereal, ethereal-dev (>= 0.10.10), debhelper (>= 4.0.2)
 Standards-Version: 3.1.1
 
 Package: tripe
 Standards-Version: 3.1.1
 
 Package: tripe
index f02bb1cd1d4674186fc5d43007ae1c0275e050fb..849a6622486cdffb72f7d3dbc5c0e330ceed6ebe 100644 (file)
@@ -4,53 +4,52 @@
 .TL "Straylight/Edgeware"               "Mark Wooding"
 .TL "Request for Comments:  XXXX"       "Straylight/Edgeware"
 .TL ""                                  "11 April 2003"
 .TL "Straylight/Edgeware"               "Mark Wooding"
 .TL "Request for Comments:  XXXX"       "Straylight/Edgeware"
 .TL ""                                  "11 April 2003"
-
-
+.
 .TT XXXX Wooding "April 2003" \
   "TrIPE: The Trivial IP Encryption Protocol"
 .TT XXXX Wooding "April 2003" \
   "TrIPE: The Trivial IP Encryption Protocol"
-
-.T0 "Status of this Memo"
-
+.
+.T0 "Status of this Memo"
+.P
 This memo defines an Experimental Protocol for the Internet community.
 This memo does not specify an Internet standard of any kind.  Discussion
 and suggestions for improvement are requested.  Distribution of this
 memo is unlimited.
 This memo defines an Experimental Protocol for the Internet community.
 This memo does not specify an Internet standard of any kind.  Discussion
 and suggestions for improvement are requested.  Distribution of this
 memo is unlimited.
-
+.P
 .T0 "Introduction"
 .T0 "Introduction"
-
+.P
 TrIPE is a simple protocol which enables IP datagrams (or other data) to
 be exchanged between a pair of hosts over a hostile network while
 maintaining the properties of secrecy and authenticity; i.e., that the
 content of the datagrams cannot be determined by eavesdroppers on the
 network, and that either endpoint can determine whether a datagram
 received is an unaltered copy of one that was sent by the other.
 TrIPE is a simple protocol which enables IP datagrams (or other data) to
 be exchanged between a pair of hosts over a hostile network while
 maintaining the properties of secrecy and authenticity; i.e., that the
 content of the datagrams cannot be determined by eavesdroppers on the
 network, and that either endpoint can determine whether a datagram
 received is an unaltered copy of one that was sent by the other.
-
+.P
 While similar services are provided by other protocols (e.g., [IPSEC]),
 they tend to be very complicated and difficult to analyze (see, for
 example, [IPSEC-EVAL]).  By contrast, TrIPE attempts to get away with
 doing as little as possible.  There are no negotiations to decide which
 ciphers are to be used: these things are defined in the protocol
 specification.  There is only one key-exchange algorithm defined.
 While similar services are provided by other protocols (e.g., [IPSEC]),
 they tend to be very complicated and difficult to analyze (see, for
 example, [IPSEC-EVAL]).  By contrast, TrIPE attempts to get away with
 doing as little as possible.  There are no negotiations to decide which
 ciphers are to be used: these things are defined in the protocol
 specification.  There is only one key-exchange algorithm defined.
-
+.P
 In addition to making analysis easier, a simpler protocol also helps
 reduce the complexity of implementations: this makes implementation
 errors less likely, and makes auditing an implementation for security
 holes a more realistic proposition.
 In addition to making analysis easier, a simpler protocol also helps
 reduce the complexity of implementations: this makes implementation
 errors less likely, and makes auditing an implementation for security
 holes a more realistic proposition.
-
+.P
 .T0 "Interpretation"
 .T0 "Interpretation"
-
+.P
 The key words `MUST', `MUST NOT', `REQUIRED', `SHALL', `SHALL NOT',
 `SHOULD', `SHOULD NOT', `RECOMMENDED', `MAY', and `OPTIONAL' in this
 document are to be interpreted as described in [REQ].
 The key words `MUST', `MUST NOT', `REQUIRED', `SHALL', `SHALL NOT',
 `SHOULD', `SHOULD NOT', `RECOMMENDED', `MAY', and `OPTIONAL' in this
 document are to be interpreted as described in [REQ].
-
+.P
 .T0 "Protocol overview"
 .T0 "Protocol overview"
-
+.P
 The TrIPE protocol sets up a secure point-to-point channel between two
 peer hosts, through which IP datagrams may be passed securely.
 The TrIPE protocol sets up a secure point-to-point channel between two
 peer hosts, through which IP datagrams may be passed securely.
-
+.P
 All TrIPE messages are sent as UDP datagrams.  No UDP port has been
 registered for TrIPE yet.
 All TrIPE messages are sent as UDP datagrams.  No UDP port has been
 registered for TrIPE yet.
-
+.P
 When a pair of peer hosts are made aware of each other, they begin a key
 negotiation, using an authenticated Diffie-Hellman key exchange
 protocol.  This enables them to agree a 
 When a pair of peer hosts are made aware of each other, they begin a key
 negotiation, using an authenticated Diffie-Hellman key exchange
 protocol.  This enables them to agree a 
@@ -61,15 +60,14 @@ time, or after they have been used to encrypt a given amount of data,
 whichever happens first.  Before the current keyset expires, a new key
 negotation is started, so that the peers can seamlessly start using the
 new keys before the old ones become invalid.
 whichever happens first.  Before the current keyset expires, a new key
 negotation is started, so that the peers can seamlessly start using the
 new keys before the old ones become invalid.
-
+.P
 .T1 "Keysets"
 .T1 "Keysets"
-
+.P
 A
 .I keyset
 is a collection of symmetric keys and associated state information.  The
 items required, and the symbolic names by which they are described in
 this document are:
 A
 .I keyset
 is a collection of symmetric keys and associated state information.  The
 items required, and the symbolic names by which they are described in
 this document are:
-
 .UL
 .LI
 .B "Incoming and outgoing encryption keys"
 .UL
 .LI
 .B "Incoming and outgoing encryption keys"
@@ -77,13 +75,15 @@ this document are:
 and
 .K' c "" )
 .LE
 and
 .K' c "" )
 .LE
-
+.P
 .T1 "Key exchange"
 .T1 "Key exchange"
-
-
-
+.
+.
+.P
 .T0 "Data representation and notation"
 .T0 "Data representation and notation"
+.
 .de SD
 .de SD
+.P
 .LS
 ..
 .de SM
 .LS
 ..
 .de SM
@@ -105,7 +105,7 @@ and
 .SM "\\$1" "\\$2" "\\$3"
 .LS 2n
 ..
 .SM "\\$1" "\\$2" "\\$3"
 .LS 2n
 ..
-
+.P
 We need to deal with a number of data items during the protocol.  
 .if t \{\
 Object names are given in
 We need to deal with a number of data items during the protocol.  
 .if t \{\
 Object names are given in
@@ -115,32 +115,27 @@ A plain name indicates `our' value; a `primed' name (e.g.,
 .I alpha' )
 indicates the peer's corresponding value.  If a compound data item name
 is primed, toggle the primed-ness of the components.
 .I alpha' )
 indicates the peer's corresponding value.  If a compound data item name
 is primed, toggle the primed-ness of the components.
-
+.P
 Data objects are given types which determine their representation in
 protocol messages.  Type names are given in 
 .B UPPERCASE .
 Data objects are given types which determine their representation in
 protocol messages.  Type names are given in 
 .B UPPERCASE .
-
+.P
 .T1 "Atomic data items"
 .T1 "Atomic data items"
-
 .DL
 .DI OCTET
 A single octet, representing a value between 0 and 255.
 .DL
 .DI OCTET
 A single octet, representing a value between 0 and 255.
-
 .DI U16
 A pair of octets, representing a value between 0 and 65535.  The more
 significant octet appears first.
 .DI U16
 A pair of octets, representing a value between 0 and 65535.  The more
 significant octet appears first.
-
 .DI U32
 Four octets, representing a value between 0 and 4294967295.  More
 significant octets appear first.
 .DI U32
 Four octets, representing a value between 0 and 4294967295.  More
 significant octets appear first.
-
 .DI "STRING \fIn\fR\fB"
 A string of
 .I n
 octets.  A
 .B STRING
 does not have a numeric value.
 .DI "STRING \fIn\fR\fB"
 A string of
 .I n
 octets.  A
 .B STRING
 does not have a numeric value.
-
 .DI MP
 A nonnegative multiprecision integer.  Let
 .I n
 .DI MP
 A nonnegative multiprecision integer.  Let
 .I n
@@ -148,11 +143,12 @@ be the integer to be represented, and let
 .I z
 be the number of octets required to represent
 .I n
 .I z
 be the number of octets required to represent
 .I n
-in base-256 format with no leading zeroes; i.e., if
-.I n
-= 0, then
+in base-256 format with no leading zeroes, except that if
+.I n 
+= 0
+then 
 .I z
 .I z
-= 0; otherwise
+= 1; in other cases,
 .I z 
 is the unique integer such that
 .ie t 256\*(^(\fIz\fP\-1\*(^) \(<= \fIn\fP < 256\*(^(\fIz\fP\*(^).
 .I z 
 is the unique integer such that
 .ie t 256\*(^(\fIz\fP\-1\*(^) \(<= \fIn\fP < 256\*(^(\fIz\fP\*(^).
@@ -169,17 +165,16 @@ octets which are the base-256 digits of
 .I n ,
 most significant first.
 .LE
 .I n ,
 most significant first.
 .LE
-
+.P
 .T1 "Structured data items"
 .T1 "Structured data items"
-
+.P
 A
 .I structure
 is a compound object which is simply the concatenation of a number of
 its component objects.  Structures are used directly as messages, and
 indirectly as things to be hashed or encrypted.
 A
 .I structure
 is a compound object which is simply the concatenation of a number of
 its component objects.  Structures are used directly as messages, and
 indirectly as things to be hashed or encrypted.
-
+.P
 The notation
 The notation
-
 .SD
 .  ST STRUCT . kx-cookie
 .    SR OCTET . 0x11
 .SD
 .  ST STRUCT . kx-cookie
 .    SR OCTET . 0x11
@@ -187,21 +182,28 @@ The notation
 .    SM STRING 20 hash
 .  LE
 .LE
 .    SM STRING 20 hash
 .  LE
 .LE
-
+.P
 indicates that
 .I msg-cookie
 consists of the two items
 indicates that
 .I msg-cookie
 consists of the two items
-
-
-
-
+.
+.f
+.
+.SD
+.  ST STRUCT . msg-packet
+.    SR OCTET . 0x00
+.    br
+payload
+.  LE
+.LE
+.
 .SD
 .  ST STRUCT . kx-prechal
 .    SR OCTET . 0x10
 .    SM MP . c
 .  LE
 .LE
 .SD
 .  ST STRUCT . kx-prechal
 .    SR OCTET . 0x10
 .    SM MP . c
 .  LE
 .LE
-
+.
 .SD
 .  ST STRUCT . kx-cookie
 .    SR OCTET . 0x11
 .SD
 .  ST STRUCT . kx-cookie
 .    SR OCTET . 0x11
@@ -212,31 +214,30 @@ consists of the two items
 .    LE
 .  LE
 .LE
 .    LE
 .  LE
 .LE
-
+.P
 .T0 "Security considerations"
 .T0 "Security considerations"
-
+.P
 This memo describes a cryptographic protocol for ensuring secrecy and
 integrity of communications between network hosts.  From this point of
 view, it is entirely about security.
 This memo describes a cryptographic protocol for ensuring secrecy and
 integrity of communications between network hosts.  From this point of
 view, it is entirely about security.
-
+.P
 Before deploying TrIPE on their own systems, administrators ought to
 satisfy themselves that the cryptographic algorithms used are
 sufficiently strong for their purposes, and that their implementation of
 the TrIPE software has come from a trustworthy source.  They should also
 ensure that they have adequate procedures in place for transporting
 public keys without a risk of them being modified by adversaries.
 Before deploying TrIPE on their own systems, administrators ought to
 satisfy themselves that the cryptographic algorithms used are
 sufficiently strong for their purposes, and that their implementation of
 the TrIPE software has come from a trustworthy source.  They should also
 ensure that they have adequate procedures in place for transporting
 public keys without a risk of them being modified by adversaries.
-
+.P
 .T0 "References"
 .T0 "References"
-
 .BS IPSEC-EVAL
 .BR IPSEC
 Kent, S., Atkinson, R., `Security Architecture for the Internet
 Protocol', RFC 2401, November 1998.
 .BS IPSEC-EVAL
 .BR IPSEC
 Kent, S., Atkinson, R., `Security Architecture for the Internet
 Protocol', RFC 2401, November 1998.
-
+.
 .BR IPSEC-EVAL
 Ferguson, N., Schneier, B., `A Cryptographic Evaluation of IPsec',
 December 1999.
 .BR IPSEC-EVAL
 Ferguson, N., Schneier, B., `A Cryptographic Evaluation of IPsec',
 December 1999.
-
+.
 .BR REQ
 Bradner, S., `Key words for use in RFCs to Indicate Requirement Levels',
 BCP 14, RFC 2119, March 1997.
 .BR REQ
 Bradner, S., `Key words for use in RFCs to Indicate Requirement Levels',
 BCP 14, RFC 2119, March 1997.
index 191f4868c12c6df54fb47ecaedb6a52053e6b535..0360955036aebf78d3647072033c5c1b1000f2ad 100644 (file)
@@ -9,6 +9,8 @@
 .  if \n(.g \{\
 .    fam P
 .  \}
 .  if \n(.g \{\
 .    fam P
 .  \}
+.  ps 10
+.  vs 12
 .\}
 .el \{\
 .  po 0
 .\}
 .el \{\
 .  po 0
@@ -57,7 +59,7 @@
 .de I
 .Ff I I "\\$1" "\\$2"
 ..
 .de I
 .Ff I I "\\$1" "\\$2"
 ..
-.de P
+.de PF
 .Ff P P "\\$1" "\\$2"
 ..
 .de C
 .Ff P P "\\$1" "\\$2"
 ..
 .de C
 .Ff (HI I "\\$1" "\\$2"
 ..
 .
 .Ff (HI I "\\$1" "\\$2"
 ..
 .
+.\"----- Paragraphs ---------------------------------------------------------
+.
+.ie t \{\
+.  de P
+.  sp .67
+..
+.\}
+.el \{\
+.  de P
+.  sp 1
+..
+.\}
+.
 .\"----- Titling ------------------------------------------------------------
 .
 .\" .TL left right
 .\"----- Titling ------------------------------------------------------------
 .
 .\" .TL left right
 .de TL
 .B
 .tl '\\$1''\\$2'
 .de TL
 .B
 .tl '\\$1''\\$2'
-.P
+.PF
 ..
 .
 .\" .TT number author title
 ..
 .
 .\" .TT number author title
 .ce
 \&\\$4
 .ps
 .ce
 \&\\$4
 .ps
-.P
+.PF
 .fi
 .in +3m
 ..
 .fi
 .in +3m
 ..
 .  el \&\\$3.\ \ \c
 .\}
 \&\\$2
 .  el \&\\$3.\ \ \c
 .\}
 \&\\$2
-.P
+.PF
 .ps
 .br
 ..
 .ps
 .br
 ..
 .\" Puts in the header for a bibliography item.
 .de BR
 .ne 2
 .\" Puts in the header for a bibliography item.
 .de BR
 .ne 2
+.P
 .ti -\\n(bwu
 [\\$1]\h'\\n(bwu-\\w'[\\$1]'u'\c
 ..
 .ti -\\n(bwu
 [\\$1]\h'\\n(bwu-\\w'[\\$1]'u'\c
 ..
 .\" .DI name
 .\" Starts a definition item for `name'
 .de DI
 .\" .DI name
 .\" Starts a definition item for `name'
 .de DI
-.br
+.P
 .B
 \h'-1i'\\$1\c
 .ie \w'\\$1\h'2n''u<1i \h'1i-\w'\\$1'u'\c
 .el .br
 .B
 \h'-1i'\\$1\c
 .ie \w'\\$1\h'2n''u<1i \h'1i-\w'\\$1'u'\c
 .el .br
-.P
+.PF
 ..
 .
 .\" .LI [tag]
 .\" Starts a new list item
 .de LI
 ..
 .
 .\" .LI [tag]
 .\" Starts a new list item
 .de LI
-.br
+.P
 .ie '\\$1'' .ds LL \\*L
 .el .ds LL \\$1
 \h'-\w'\\*(LL\h'1n''u'\\*(LL\h'1n'\c
 .ie '\\$1'' .ds LL \\*L
 .el .ds LL \\$1
 \h'-\w'\\*(LL\h'1n''u'\\*(LL\h'1n'\c
 .\" .QS
 .\" Starts a display.
 .de QS
 .\" .QS
 .\" Starts a display.
 .de QS
+.P
 .in +4n
 .ll -4n
 ..
 .in +4n
 .ll -4n
 ..
index f762692e63a24f7e880fb50c82aebf32250e02cf..d39866e0a0de65093013f48351ee506f9cb131cf 100644 (file)
@@ -45,34 +45,125 @@ provides information requested in the command.  An
 .B OK
 response contains no further data.  A
 .B FAIL
 .B OK
 response contains no further data.  A
 .B FAIL
-code is followed by a human-readable explanation of why the command
+code is followed by a machine-readable explanation of why the command
 failed.
 .PP
 failed.
 .PP
-In addition, there are two types of asynchronous `responses', which
+In addition, there are three types of asynchronous messages which
 aren't associated with any particular command.  The
 .B WARN
 aren't associated with any particular command.  The
 .B WARN
-response contains a human-readable message warning of an error
+message contains a machine-readable message warning of an error
 encountered while processing a command, unexpected or unusual behaviour
 by a peer, or a possible attack by an adversary.  Under normal
 conditions, the server shouldn't emit any warnings.  The
 .B TRACE
 encountered while processing a command, unexpected or unusual behaviour
 by a peer, or a possible attack by an adversary.  Under normal
 conditions, the server shouldn't emit any warnings.  The
 .B TRACE
-response contains a human-readable tracing message containing diagnostic
+message contains a human-readable tracing message containing diagnostic
 information.  Trace messages are controlled using the
 .B \-T
 command-line option to the server, or the
 .B TRACE
 administration command (see below).  Support for tracing can be disabled
 when the package is being configured, and may not be available in your
 information.  Trace messages are controlled using the
 .B \-T
 command-line option to the server, or the
 .B TRACE
 administration command (see below).  Support for tracing can be disabled
 when the package is being configured, and may not be available in your
-version.
-.SS "Command reference"
+version.  Finally, the
+.B NOTE
+message is a machine-readable notification about some routine but
+interesting event such as creation or destruction of peers.
+.PP
+The presence of asynchronous messages can be controlled using the
+.B WATCH
+command.
+.SS "Network addresses"
+A network address is a sequence of words.  The first is a token
+identifying the network address family.  The length of an address and
+the meanings of the subsequent words depend on the address family.
+Address family tokens are not case-sensitive on input; on output, they
+are always in upper-case.
+.PP
+At present, only one address family is understood.
+.TP
+.BI "INET " address " " port
+An Internet socket, naming an IPv4 address and UDP port.  On output, the
+address is always in numeric dotted-quad form, and the port is given as
+a plain number.  On input, DNS hostnames and symbolic port names are
+permitted.  Name resolution does not block the main server, but will
+block the requesting client.  This hopefully makes life simpler for
+stupid clients.  Complex clients which don't wish to be held up can open
+extra connections or do the resolution themselves.)
+.PP
+If, on input, no recognised address family token is found, the following
+words are assumed to represent an
+.B INET
+address.
+.SH "COMMAND REFERENCE"
 The commands provided are:
 .TP
 The commands provided are:
 .TP
+.BI "ADD " peer " " address\fR...
+Adds a new peer.  The peer is given the name
+.IR peer ;
+the peer's public key is assumed to be in the file
+.B keyring.pub
+(or whatever alternative file was specified in the
+.B \-K
+option on the command line).  The
+.I address
+is the network address (see above for the format) at which the peer can
+be contacted.
+.TP
+.BI "ADDR " peer
+Emits an
+.B INFO
+line reporting the IP address and port number stored for
+.IR peer .
+.TP
+.B "DAEMON"
+Causes the server to disassociate itself from its terminal and become a
+background task.  This only works once.  A warning is issued.
+.TP
 .B "HELP"
 Causes the server to emit an
 .B INFO
 line for each command it supports.  Each line lists the command name,
 followed by the names of the arguments.  This may be helpful as a memory
 aid for interactive use, or for program clients probing for features.
 .B "HELP"
 Causes the server to emit an
 .B INFO
 line for each command it supports.  Each line lists the command name,
 followed by the names of the arguments.  This may be helpful as a memory
 aid for interactive use, or for program clients probing for features.
+.TP 
+.BI "IFNAME " peer
+Emits an
+.B INFO
+line containing the name of the network interface used to collect IP
+packets which are to be encrypted and sent to
+.IR peer .
+Used by configuration scripts so that they can set up routing tables
+appropriately after adding new peers.
+.TP
+.BI "KILL " peer
+Causes the server to forget all about
+.IR peer .
+All keys are destroyed, and no more packets are sent.  No notification
+is sent to the peer: if it's important that the peer be notified, you
+must think of a way to do that yourself.
+.TP
+.B "LIST"
+For each currently-known peer, an
+.B INFO
+line is written containing the peer's name, as given to
+.BR ADD .
+.TP
+.B "PORT"
+Emits an
+.B INFO
+line containing just the number of the UDP port used by the
+.B tripe
+server.  If you've allowed your server to allocate a port dynamically,
+this is how to find out which one it chose.
+.TP
+.B "QUIT"
+Instructs the server to exit immediately.  A warning is sent.
+.TP
+.BI "STATS " peer
+Emits a number of
+.B INFO
+lines, each containing one or more statistics in the form
+.IB name = value \fR.
+The statistics-gathering is experimental and subject to change.
 .TP
 .BR "TRACE " [\fIoptions\fP]
 A trace argument consists of a string of letters (listed below)
 .TP
 .BR "TRACE " [\fIoptions\fP]
 A trace argument consists of a string of letters (listed below)
@@ -145,72 +236,435 @@ without one of
 .B x
 or
 .BR m .
 .B x
 or
 .BR m .
+.TP
+.B A
+All of the above.
 .RE
 .TP
 .RE
 .TP
-.B "PORT"
-Emits an
+.BR "WATCH " [\fIoptions\fP]
+Enables or disables asynchronous messages
+.IR "for the current connection only" .
+This command has no effect on other connections.  A watch argument
+consists of a string of letters (listed below) selecting message types,
+optionally interspersed with
+.RB ` + '
+to enable, or
+.RB ` \- '
+to disable, the subsequently listed types, similar to
+.B trace
+above.  The default watch state for the connection the server opens
+automatically on stdin/stdout is to show warnings and trace messages;
+other connections show no asynchronous messages.  (This is done in order
+to guarantee that a program reading the server's stdout does not miss
+any warnings.)
+.RS
+.PP
+Currently, the following watch options are supported:
+.TP
+.B t
+.B TRACE
+messages.
+.TP
+.B n
+.B NOTE
+messages.
+.TP
+.B w
+.B WARN
+messages.
+.TP
+.B a
+All of the above.
+.RE
+.TP
+.B "VERSION"
+Causes the server to emit an
 .B INFO
 .B INFO
-line containing just the number of the UDP port used by the
+line stating its software version, as two words: the server name, and
+its version string.  The server name
 .B tripe
 .B tripe
-server.  If you've allowed your server to allocate a port dynamically,
-this is how to find out which one it chose.
+is reserved to the Straylight/Edgeware implementation.
+.SH "ERROR MESSAGES"
+The following
+.B FAIL
+messages are sent to clients as a result of errors during command
+processing.
 .TP
 .TP
-.B "DAEMON"
-Causes the server to disassociate itself from its terminal and become a
-background task.  This only works once.  A warning is issued.
+.BI "already-daemon"
+(For
+.BR DAEMON .)
+The
+.B tripe
+server is already running as a daemon.
 .TP
 .TP
-.B "LIST"
-For each currently-known peer, an
-.B INFO
-line is written containing the peer's name, as given to
-.BR ADD .
-.TP 
-.BI "IFNAME " peer
-Emits an
-.B INFO
-line containing the name of the network interface used to collect IP
-packets which are to be encrypted and sent to
-.IR peer .
-Used by configuration scripts so that they can set up routing tables
-appropriately after adding new peers.
+.BI "bad-syntax \-\- " message
+(For any command.)  The command couldn't be understood: e.g., the number
+of arguments was wrong.
 .TP
 .TP
-.BI "ADDR " peer
-Emits an
-.B INFO
-line reporting the IP address and port number stored for
+.BI "bad-trace-option " char
+(For
+.BR TRACE .)
+An unknown trace option was requested.
+.TP
+.BI "bad-watch-option " char
+(For
+.BR WATCH .)
+An unknown watch option was requested.
+.TP
+.BI "daemon-error \-\- " message
+(For
+.BR DAEMON .)
+An error occurred during the attempt to become a daemon, as reported by
+.IR message .
+.TP
+.BI "invalid-port " number
+(For
+.BR ADD .)
+The given port number is out of range.
+.TP
+.BI "peer-create-fail " peer
+(For
+.BR ADD .)
+Adding
+.I peer
+failed for some reason.  A warning should have been emitted explaining
+why.
+.TP
+.BI "peer-exists " peer
+(For
+.BR ADD .)
+There is already a peer named
 .IR peer .
 .TP
 .IR peer .
 .TP
-.BI "STATS " peer
-Emits a number of
-.B INFO
-lines, each containing one or more statistics in the form
-.IB name = value \fR.
-The statistics-gathering is experimental and subject to change.
+.BI "resolve-error " hostname
+(For
+.BR ADD .)
+The DNS name
+.I hostname
+could not be resolved.
+.TP
+.BI "resolver-timeout " hostname
+(For
+.BR ADD .)
+The DNS name
+.I hostname
+took too long to resolve.
+.TP
+.BI "unknown-command " token
+The command
+.B token
+was not recognised.
+.TP
+.BI "unknown-peer " name
+(For
+.BR ADDR ,
+.BR IFNAME ,
+.BR KILL ,
+and
+.BR STATS .)
+There is no peer called
+.IR name .
+.TP
+.BI "unknown-service " service
+(For
+.BR ADD .)
+The service name
+.I service
+couldn't be found in 
+.BR /etc/services .
+.SH "NOTIFICATIONS"
+The following notifications are sent to clients who request them.
+.TP
+.BI "ADD " peer " " address \fR...
+A new peer has been added.  The peer's name is
+.I peer
+and its network address is
+.IR address .
+.TP
+.BI "DAEMON"
+The server has forked off into the sunset and become a daemon.
 .TP
 .BI "KILL " peer
 .TP
 .BI "KILL " peer
-Causes the server to forget all about
-.IR peer .
-All keys are destroyed, and no more packets are sent.  No notification
-is sent to the peer: if it's important that the peer be notified, you
-must think of a way to do that yourself.
+The peer
+.I peer
+has been killed.
 .TP
 .TP
-.BI "ADD " "peer addr port"
-Adds a new peer.  The peer is given the name
-.IR peer ;
-the peer's public key is assumed to be in the file
-.B keyring.pub
-(or whatever alternative file was specified in the
-.B \-K
-option on the command line).  The peer's
+.BI "KXDONE " peer
+Key exchange with
+.I peer
+finished successfully.
+.TP
+.BI "KXSTART " peer
+Key exchange with
+.I peer
+has begun or restarted.  If key exchange keeps failing, this message
+will be repeated periodically.
+.SH "WARNINGS"
+There are many possible warnings.  They are categorized according to
+their first tokens.
+.SS "ABORT warnings"
+These all indicate that the
 .B tripe
 .B tripe
-implementation may be contacted at the given UDP port and IP address.
+server has become unable to continue.  If enabled, the server will dump
+core in its configuration directory.
 .TP
 .TP
-.B "QUIT"
-Instructs the server to exit immediately.  A warning is sent.
+.BI "ABORT repeated-select-errors"
+The main event loop is repeatedly failing.  If the server doesn't quit,
+it will probably waste all available CPU doing nothing.
+.SS "ADMIN warnings"
+These indicate a problem with the administration socket interface.
+.TP
+.BI "ADMIN accept-error \-\- " message
+There was an error while attempting to accept a connection from a new
+client.
+.TP
+.BI "ADMIN client-read-error \-\- " message
+There was an error sending data to a client.  The connection to the
+client has been closed.
+.SS "KEYMGMT warnings"
+These indicate a problem with the keyring files, or the keys stored in
+them.
+.TP
+.BI "KEYMGMT bad-private-key \-\- " message
+The private key could not be read, or failed a consistency check.  If
+there was a problem with the file, usually there will have been
+.B key-file-error
+warnings before this.
+.TP
+.BI "KEYMGMT bad-public-keyring \-\- " message
+The public keyring couldn't be read.  Usually, there will have been 
+.B key-file-error
+warnings before this.
+.TP
+.BI "KEYMGMT key-file-error " file ":" line " \-\- " message
+Reports a specific error with the named keyring file.  This probably
+indicates a bug in
+.BR key (1).
+.TP
+.BI "KEYMGMT public-key " tag " " tokens\fR...
+These messages all indicate a problem with the public key named
+.IR tag .
+.TP
+.BI "KEYMGMT public-key " tag " algorithm-mismatch"
+The algorithms specified on the public key don't match the ones for our
+private key.  All the peers in a network have to use the same
+algorithms.
+.TP
+.BI "KEYMGMT public-key " tag " bad \-\- " message
+The public key couldn't be read, or is invalid.
+.TP
+.BI "KEYMGMT public-key " tag " bad-public-group-element"
+The public key is invalid.  This may indicate a malicious attempt to
+introduce a bogus key.
+.TP
+.BI "KEYMGMT public-key " tag " bad-algorithm-selection"
+The algorithms listed on the public key couldn't be understood.  The
+algorithm selection attributes are probably malformed and need fixing.
+.TP
+.BI "KEYMGMT public-key " tag " incorrect-group"
+The public key doesn't use the same group as our private key.  All the
+peers in a network have to use the same group.
+.TP
+.BI "KEYMGMT public-key " tag " not-found"
+The public key for peer
+.I tag
+wasn't in the public keyring.
+.TP
+.BI "KEYMGMT public-key " tag " unknown-type"
+The type of the public key isn't understood.  Maybe you need to upgrade
+your copy of
+.BR tripe .
+(Even if you do, you'll have to regenerate your keys.)
+.SS "KX warnings"
+These indicate problems during key-exchange.  Many indicate either a bug
+in the server (either yours or the remote one), or some kind of attack
+in progress.  All name a
+.I peer
+as the second token: this is the peer the packet is apparently from,
+though it may have been sent by an attacker instead.
+.PP
+In the descriptions below,
+.I msgtoken
+is one of the tokens
+.BR pre-challenge ,
+.BR cookie ,
+.BR challenge ,
+.BR reply ,
+.BR switch-rq ,
+or
+.BR switch-ok .
+.TP
+.BI "KX " peer " bad-expected-reply-log"
+The challenges
+.B tripe
+uses in its protocol contain a check value which proves that the
+challenge is honest.  This message indicates that the check value
+supplied is wrong: someone is attempting to use bogus challenges to
+persuade your
+.B tripe
+server to leak private key information.  No chance!
+.TP
+.BI "KX " peer " decrypt-failed \fR[\fBreply\fR|\fBswitch-ok\fR]"
+A symmetrically-encrypted portion of a key-exchange message failed to
+decrypt.
+.TP
+.BI "KX " peer " invalid " msgtoken
+A key-exchange message was malformed.  This almost certainly indicates a
+bug somewhere.
+.TP
+.BI "KX " peer " incorrect \fR[\fBcookie\fR|\fBswitch-rq\fR|\fBswitch-ok\fR]"
+A message didn't contain the right magic data.  This may be a replay of
+some old exchange, or random packets being sent in an attempt to waste
+CPU.
+.TP
+.BI "KX " peer " public-key-expired"
+The peer's public key has expired.  It's maintainer should have given
+you a replacement before now.
+.TP
+.BI "KX " peer " sending-cookie"
+We've received too many bogus pre-challenge messages.  Someone is trying
+to flood us with key-exchange messages and make us waste CPU on doing
+hard asymmetric crypto sums.
+.TP
+.BI "KX " peer " unexpected " msgtoken
+The message received wasn't appropriate for this stage of the key
+exchange process.  This may mean that one of our previous packets got
+lost.  For 
+.BR pre-challenge ,
+it may simply mean that the peer has recently restarted.
+.TP
+.BI "KX " peer " unknown-challenge"
+The peer is asking for an answer to a challenge which we don't know
+about.  This may mean that we've been inundated with challenges from
+some malicious source
+.I who can read our messages
+and discarded the valid one.
+.TP
+.BI "KX " peer " unknown-message 0x" nn
+An unknown key-exchange message arrived.
+.SS "PEER warnings"
+These are largely concerned with management of peers and the low-level
+details of the network protocol.  The second word is usually the name of
+a peer, or 
+.RB ` \- '
+if none is relevant.
+.TP
+.BI "PEER \- unexpected-source " address\fR...
+A packet arrived from
+.I address
+(a network address \(en see above), but no peer is known at that
+address.  This may indicate a misconfiguration, or simply be a result of
+one end of a connection being set up before the other.
+.TP
+.BI "PEER " peer " bad-packet no-type"
+An empty packet arrived.  This is very strange.
+.TP
+.BI "PEER " peer " bad-packet unknown-category 0x" nn
+The message category
+.I nn
+(in hex) isn't understood.  Probably a strange random packet from
+somewhere; could be an unlikely bug.
+.TP
+.BI "PEER " peer " bad-packet unknown-type 0x" nn
+The message type
+.I nn
+(in hex) isn't understood.  Probably a strange random packet from
+somewhere; could be an unlikely bug.
+.TP
+.BI "PEER " peer " decrypt-failed"
+An encrypted IP packet failed to decrypt.  It may have been mangled in
+transit, or may be a very old packet from an expired previous session
+key.  There is usually a considerable overlap in the validity periods of
+successive session keys, so this shouldn't occur unless the key exchange
+takes ages or fails.
+.TP
+.BI "PEER " peer " packet-build-failed"
+There wasn't enough space in our buffer to put the packet we wanted to
+send.  Shouldn't happen.
+.TP
+.BI "PEER \- socket-read-error \-\- " message
+An error occurred trying to read an incoming packet.
+.TP
+.BI "PEER " peer " socket-write-error \-\- " message
+An error occurred attempting to send a network packet.  We lost that
+one.
+.SS "SERVER warnings"
+These indicate problems concerning the server process as a whole.
+.TP
+.BI "SERVER ignore signal " name
+A signal arrived, but the server ignored it.  Currently this happens for
+.B SIGHUP
+because that's a popular way of telling daemons to re-read their
+configuration files.  Since
+.B tripe
+re-reads its keyrings automatically and has no other configuration
+files, it's not relevant, but it seemed better to ignore the signal than
+let the server die.
+.TP
+.BI "SERVER quit signal " \fR[\fInn\fR|\fIname\fR]
+A signal arrived and
+.B tripe
+is going to quit.
+.TP
+.BI "SERVER quit admin-request"
+A client of the administration interface issued a
+.B QUIT
+command.
+.TP
+.BI "SERVER select-error \-\- " message
+An error occurred in the server's main event loop.  This is bad: if it
+happens too many times, the server will abort.
+.SS "SYMM warnings"
+These are concerned with the symmetric encryption and decryption
+process.
+.TP
+.BI "SYMM replay old-sequence"
+A packet was received with an old sequence number.  It may just have
+been delayed or duplicated, or it may have been an attempt at a replay
+attack.
+.TP
+.BI "SYMM replay duplicated-sequence"
+A packet was received with a sequence number we've definitely seen
+before.  It may be an accidental duplication because the 'net is like
+that, or a deliberate attempt at a replay.
+.SS "TUN warnings"
+These concern the workings of the system-specific tunnel driver.  The
+second word is the name of the tunnel interface in question, or
+.RB ` \- '
+if none.
+.TP
+.BI "TUN \- bsd no-tunnel-devices"
+The driver couldn't find an available tunnel device.  Maybe if you
+create some more 
+.BI /dev/tun nn
+files, it will work.
+.TP
+.BI "TUN - open-error " device " \-\- " message
+An attempt to open the tunnel device file
+.I device
+failed.
+.TP
+.BI "TUN " ifname " read-error \-\- " message
+Reading from the tunnel device failed.
+.TP
+.BI "TUN \- linux config-error \-\- " message
+Configuring the Linux TUN/TAP interface failed.
+.TP
+.BI "TUN \- unet config-error \-\- " message
+Configuring the Linux Unet interface failed.  Unet is obsolete and
+shouldn't be used any more.
+.TP
+.BI "TUN \- unet getinfo-error \-\- " message
+Reading information about the Unet interface failed.  Unet is obsolete
+and shouldn't be used any more.
+.TP
+.BI "TUN \- unet ifname-too-long \-\- " message
+The Unet interface's name overflowed, so we couldn't read it properly.
+Unet is obsolete and shouldn't be used any more.
 .SH "SEE ALSO"
 .BR tripectl (1),
 .BR tripe (8).
 .PP
 .SH "SEE ALSO"
 .BR tripectl (1),
 .BR tripe (8).
 .PP
-.IR "The Trivial IP Encryption Protocol" ,
+.IR "The Trivial IP Encryption Protocol" .
 .SH "AUTHOR"
 Mark Wooding, <mdw@nsict.org>
 .SH "AUTHOR"
 Mark Wooding, <mdw@nsict.org>
index 929f01910788c52fcbdbcfe68aa030880eedde6d..373271a7440920e78e8292fefea0f0a0fa288265 100644 (file)
@@ -148,6 +148,11 @@ version number to standard output and exits with status 0.
 .B "\-u, \-\-usage"
 Writes a brief usage summary to standard output and exits with status 0.
 .TP
 .B "\-u, \-\-usage"
 Writes a brief usage summary to standard output and exits with status 0.
 .TP
+.B "\-\-tunnel"
+Writes a string to standard output describing the configured tunnelling
+method and exits with status 0.  This is intended for the use of the
+start-up script, so that it can check that it will actually work.
+.TP
 .B "\-D, \-\-daemon"
 Dissociates from its terminal and starts running in the background after
 completing the initialization procedure described above.  If running as
 .B "\-D, \-\-daemon"
 Dissociates from its terminal and starts running in the background after
 completing the initialization procedure described above.  If running as
index afeb1bcc3435e0dea8960942169ef4e783d56e5a..aaad0ec9b486fabfbd0e71d8b5bbac4099a7c12a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: packet-tripe.c,v 1.4 2004/04/18 18:08:11 mdw Exp $
+ * $Id$
  *
  * TrIPE protocol dissector for Ethereal
  *
  *
  * TrIPE protocol dissector for Ethereal
  *
 
 #include <glib.h>
 #include <gmodule.h>
 
 #include <glib.h>
 #include <gmodule.h>
-#include <epan/packet.h>
-#include <prefs.h>
-
-#ifdef ETHEREAL_BUGGERED
-#  define plugin_address_table_t void
-#  define plugin_address_table_init(x)
-#else
-#  include <plugins/plugin_api.h>
-#endif
+#include <ethereal/config.h>
+#include <ethereal/epan/packet.h>
+#include <ethereal/epan/prefs.h>
 
 #include "tripe-protocol.h"
 
 
 #include "tripe-protocol.h"
 
@@ -132,13 +126,15 @@ static void dissect_tripe(tvbuff_t *b, packet_info *p, proto_tree *t)
   proto_item *ti;
   proto_tree *tt;
   guint8 ty;
   proto_item *ti;
   proto_tree *tt;
   guint8 ty;
-  gint off = tvb_raw_offset(b);
+  gint off = 0;
   guint32 seq;
 
   /* --- Initialize the summary cells --- */
 
   if (check_col(p->cinfo, COL_PROTOCOL))
     col_set_str(p->cinfo, COL_PROTOCOL, "TrIPE");
   guint32 seq;
 
   /* --- Initialize the summary cells --- */
 
   if (check_col(p->cinfo, COL_PROTOCOL))
     col_set_str(p->cinfo, COL_PROTOCOL, "TrIPE");
+  if (check_col(p->cinfo, COL_INFO))
+    col_clear(p->cinfo, COL_INFO);
   ty = tvb_get_guint8(b, 0);
   if (check_col(p->cinfo, COL_INFO)) {
     col_clear(p->cinfo, COL_INFO);
   ty = tvb_get_guint8(b, 0);
   if (check_col(p->cinfo, COL_INFO)) {
     col_clear(p->cinfo, COL_INFO);
@@ -286,111 +282,111 @@ void proto_register_tripe(void)
   };
 
   static hf_register_info hfs[] = {
   };
 
   static hf_register_info hfs[] = {
-    &hf_tripe_cat, {
+    &hf_tripe_cat, {
       "Message category", "tripe.cat",
       FT_UINT8, BASE_HEX, 0, MSG_CATMASK
       "Message category", "tripe.cat",
       FT_UINT8, BASE_HEX, 0, MSG_CATMASK
-    },
-    &hf_tripe_packet_type, {
+    } },
+    &hf_tripe_packet_type, {
       "Packet message type", "tripe.packet.type",
       FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK,
       "This is the TrIPE packet type subcode."
       "Packet message type", "tripe.packet.type",
       FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK,
       "This is the TrIPE packet type subcode."
-    },
-    &hf_tripe_ct, {
+    } },
+    &hf_tripe_ct, {
       "Encrypted ciphertext", "tripe.ct",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is an encrypted message."
       "Encrypted ciphertext", "tripe.ct",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is an encrypted message."
-    },
-    &hf_tripe_ct_seq, {
+    } },
+    &hf_tripe_ct_seq, {
       "Ciphertext sequence number", "tripe.ct.seq",
       FT_UINT32, BASE_DEC, 0, 0,
       "This is the unique sequence number for the ciphertext."
       "Ciphertext sequence number", "tripe.ct.seq",
       FT_UINT32, BASE_DEC, 0, 0,
       "This is the unique sequence number for the ciphertext."
-    },
-    &hf_tripe_ct_iv, {
+    } },
+    &hf_tripe_ct_iv, {
       "Ciphertext initialization vector", "tripe.ct.iv",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the initialization vector used for the actual encryption."
       "Ciphertext initialization vector", "tripe.ct.iv",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the initialization vector used for the actual encryption."
-    },
-    &hf_tripe_ct_ct, {
+    } },
+    &hf_tripe_ct_ct, {
       "Actual encrypted data", "tripe.ct.ct",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the encrypted message.  Reading it ought to be hard."
       "Actual encrypted data", "tripe.ct.ct",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the encrypted message.  Reading it ought to be hard."
-    },
-    &hf_tripe_ct_tag, {
+    } },
+    &hf_tripe_ct_tag, {
       "Message authentication code", "tripe.ct.tag",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the message authentication code tag for the ciphertext."
       "Message authentication code", "tripe.ct.tag",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the message authentication code tag for the ciphertext."
-    },
-    &hf_tripe_kx_type, {
+    } },
+    &hf_tripe_kx_type, {
       "Key-exchange message type", "tripe.kx.type",
       FT_UINT8, BASE_HEX, vs_kxtype, MSG_TYPEMASK,
       "This is the TrIPE key-exchange type subcode."
       "Key-exchange message type", "tripe.kx.type",
       FT_UINT8, BASE_HEX, vs_kxtype, MSG_TYPEMASK,
       "This is the TrIPE key-exchange type subcode."
-    },
-    &hf_tripe_kx_mychal.hf, {
+    } },
+    &hf_tripe_kx_mychal.hf, {
       "Sender's challenge data", "tripe.kx.mychal",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the sender's challenge."
       "Sender's challenge data", "tripe.kx.mychal",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the sender's challenge."
-    },
-    &hf_tripe_kx_mychal.hf_len, {
+    } },
+    &hf_tripe_kx_mychal.hf_len, {
       "Challenge length", "tripe.kx.mychal.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge."
       "Challenge length", "tripe.kx.mychal.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge."
-    },
-    &hf_tripe_kx_mychal.hf_val, {
+    } },
+    &hf_tripe_kx_mychal.hf_val, {
       "Challenge", "tripe.kx.mychal.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge."
       "Challenge", "tripe.kx.mychal.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge."
-    },
-    &hf_tripe_kx_mychal.hfx_len, {
+    } },
+    &hf_tripe_kx_mychal.hfx_len, {
       "Challenge x length", "tripe.kx.mychal.x.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge x-coordinate."
       "Challenge x length", "tripe.kx.mychal.x.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge x-coordinate."
-    },
-    &hf_tripe_kx_mychal.hfy_val, {
+    } },
+    &hf_tripe_kx_mychal.hfy_val, {
       "Challenge x value", "tripe.kx.mychal.x.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge x-coordinate."
       "Challenge x value", "tripe.kx.mychal.x.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge x-coordinate."
-    },
-    &hf_tripe_kx_mychal.hfy_len, {
+    } },
+    &hf_tripe_kx_mychal.hfy_len, {
       "Challenge y length", "tripe.kx.mychal.y.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge x-coordinate."
       "Challenge y length", "tripe.kx.mychal.y.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the sender's challenge x-coordinate."
-    },
-    &hf_tripe_kx_mychal.hfx_val, {
+    } },
+    &hf_tripe_kx_mychal.hfx_val, {
       "Challenge y value", "tripe.kx.mychal.y.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge x-coordinate."
       "Challenge y value", "tripe.kx.mychal.y.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the value of the sender's challenge x-coordinate."
-    },
-    &hf_tripe_kx_mycookie, {
+    } },
+    &hf_tripe_kx_mycookie, {
       "Sender's hashed cookie", "tripe.kx.mycookie",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the hash of the sender's challenge."
       "Sender's hashed cookie", "tripe.kx.mycookie",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the hash of the sender's challenge."
-    },
-    &hf_tripe_kx_yourcookie, {
+    } },
+    &hf_tripe_kx_yourcookie, {
       "Recipient's hashed cookie", "tripe.kx.yourcookie",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the hash of the recipient's challenge."
       "Recipient's hashed cookie", "tripe.kx.yourcookie",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the hash of the recipient's challenge."
-    },
-    &hf_tripe_kx_check.hf, {
+    } },
+    &hf_tripe_kx_check.hf, {
       "Challenge check-value", "tripe.kx.check",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is an encrypted check-value which proves that the sender "
       "knows the answer to the challenge, and that it is therefore honest."
       "Challenge check-value", "tripe.kx.check",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is an encrypted check-value which proves that the sender "
       "knows the answer to the challenge, and that it is therefore honest."
-    },
-    &hf_tripe_kx_check.hf_len, {
+    } },
+    &hf_tripe_kx_check.hf_len, {
       "Check-value length", "tripe.kx.check.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the encrypted check-value."
       "Check-value length", "tripe.kx.check.len",
       FT_UINT16, BASE_DEC, 0, 0,
       "This is the length of the encrypted check-value."
-    },
-    &hf_tripe_kx_check.hf_val, {
+    } },
+    &hf_tripe_kx_check.hf_val, {
       "Check-value data", "tripe.kx.check.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the actual encrypted check-value."
       "Check-value data", "tripe.kx.check.val",
       FT_BYTES, BASE_NONE, 0, 0,
       "This is the actual encrypted check-value."
-    },
-    &hf_tripe_huh, {
+    } },
+    &hf_tripe_huh, {
       "Unknown data", "tripe.huh",
       FT_BYTES, BASE_NONE, 0, 0,
       "I don't know what's meant to appear here."
       "Unknown data", "tripe.huh",
       FT_BYTES, BASE_NONE, 0, 0,
       "I don't know what's meant to appear here."
-    },
+    } },
   };
 
   static gint *tts[] = {
   };
 
   static gint *tts[] = {
@@ -429,9 +425,8 @@ G_MODULE_EXPORT void plugin_reg_handoff(void)
   proto_reg_handoff_tripe();
 }
 
   proto_reg_handoff_tripe();
 }
 
-G_MODULE_EXPORT void plugin_init(plugin_address_table_t *pat)
+G_MODULE_EXPORT void plugin_register(void)
 {
 {
-  plugin_address_table_init(pat);
   if (proto_tripe == -1)
     proto_register_tripe();
 }
   if (proto_tripe == -1)
     proto_register_tripe();
 }
index 18594cf31414447f1b37e4de6be9ae2e0a6d8a07..7c0217c5ccdae50b69af40e7fb20af3ae1768ccc 100644 (file)
--- a/keyexch.c
+++ b/keyexch.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: keyexch.c,v 1.13 2004/04/18 18:08:11 mdw Exp $
+ * $Id$
  *
  * Key exchange protocol
  *
  *
  * Key exchange protocol
  *
@@ -72,7 +72,7 @@
  *     Challenge accpeted: here's the answer.  Commit to my challenge.  Move
  *     to @KXS_COMMIT@.
  *
  *     Challenge accpeted: here's the answer.  Commit to my challenge.  Move
  *     to @KXS_COMMIT@.
  *
- * %$\cookie{kx-switch}, c_A, c_B, E_K(r_B^\alpha, w_A))$%
+ * %$\cookie{kx-switch-rq}, c_A, c_B, E_K(r_B^\alpha, w_A))$%
  *     Reply received: here's my reply.  Committed; send data; move to
  *     @KXS_SWITCH@.
  *
  *     Reply received: here's my reply.  Committed; send data; move to
  *     @KXS_SWITCH@.
  *
 #define T_VALID MIN(2)                 /* Challenge validity period */
 #define T_RETRY SEC(10)                        /* Challenge retransmit interval */
 
 #define T_VALID MIN(2)                 /* Challenge validity period */
 #define T_RETRY SEC(10)                        /* Challenge retransmit interval */
 
-#define ISVALID(kx, now) ((now) < (kx)->t_valid)
+#define VALIDP(kx, now) ((now) < (kx)->t_valid)
+
+/*----- Static tables -----------------------------------------------------*/
+
+static const char *const pkname[] = {
+  "pre-challenge", "cookie", "challenge",
+  "reply", "switch-rq", "switch-ok"
+};
 
 /*----- Various utilities -------------------------------------------------*/
 
 
 /*----- Various utilities -------------------------------------------------*/
 
@@ -423,7 +430,7 @@ static ge *getreply(keyexch *kx, ge *c, mp *ck)
   G_EXP(gg, y, gg->g, a);
   ok = G_EQ(gg, y, c);
   if (!ok) {
   G_EXP(gg, y, gg->g, a);
   ok = G_EQ(gg, y, c);
   if (!ok) {
-    a_warn("invalid expected-reply check from `%s'", p_name(kx->p));
+    a_warn("KX %s bad-expected-reply-log", p_name(kx->p));
     IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
       trace(T_CRYPTO, "crypto: computed challenge = %s", gestr(gg, y));
     }))
     IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
       trace(T_CRYPTO, "crypto: computed challenge = %s", gestr(gg, y));
     }))
@@ -457,7 +464,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b)
   /* --- Ensure that we're in a sensible state --- */
 
   if (kx->s != KXS_CHAL) {
   /* --- Ensure that we're in a sensible state --- */
 
   if (kx->s != KXS_CHAL) {
-    a_warn("unexpected challenge from `%s'", p_name(kx->p));
+    a_warn("KX %s unexpected %s", p_name(kx->p), pkname[msg]);
     goto bad;
   }
 
     goto bad;
   }
 
@@ -467,7 +474,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b)
       (msg >= KX_COOKIE && (hc = buf_get(b, algs.hashsz)) == 0) ||
       (msg >= KX_CHAL && (ck = buf_getmp(b)) == 0) ||
       BLEFT(b)) {
       (msg >= KX_COOKIE && (hc = buf_get(b, algs.hashsz)) == 0) ||
       (msg >= KX_CHAL && (ck = buf_getmp(b)) == 0) ||
       BLEFT(b)) {
-    a_warn("malformed packet from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid %s", p_name(kx->p), pkname[msg]);
     goto bad;
   }
 
     goto bad;
   }
 
@@ -484,6 +491,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b)
 
   if (!hc && kx->nr >= KX_THRESH) {
     T( trace(T_KEYEXCH, "keyexch: too many challenges -- sending cookie"); )
 
   if (!hc && kx->nr >= KX_THRESH) {
     T( trace(T_KEYEXCH, "keyexch: too many challenges -- sending cookie"); )
+    a_warn("KX %s sending-cookie", p_name(kx->p));
     b = p_txstart(kx->p, MSG_KEYEXCH | KX_COOKIE);
     G_TOBUF(gg, b, kx->c);
     h = GH_INIT(algs.h);
     b = p_txstart(kx->p, MSG_KEYEXCH | KX_COOKIE);
     G_TOBUF(gg, b, kx->c);
     h = GH_INIT(algs.h);
@@ -498,7 +506,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b)
   /* --- Discard a packet with an invalid cookie --- */
 
   if (hc && memcmp(hc, kx->hc, algs.hashsz) != 0) {
   /* --- Discard a packet with an invalid cookie --- */
 
   if (hc && memcmp(hc, kx->hc, algs.hashsz) != 0) {
-    a_warn("incorrect cookie from `%s'", p_name(kx->p));
+    a_warn("KX %s incorrect cookie", p_name(kx->p));
     goto bad;
   }
 
     goto bad;
   }
 
@@ -719,11 +727,11 @@ static kxchal *matchreply(keyexch *kx, unsigned ty, const octet *hc_in,
     if (ck) trace(T_CRYPTO, "crypto: check value = %s", mpstr(ck));
   }))
   if (memcmp(hc_out, kx->hc, algs.hashsz) != 0) {
     if (ck) trace(T_CRYPTO, "crypto: check value = %s", mpstr(ck));
   }))
   if (memcmp(hc_out, kx->hc, algs.hashsz) != 0) {
-    a_warn("incorrect cookie from `%s'", p_name(kx->p));
+    a_warn("KX %s incorrect cookie", p_name(kx->p));
     goto bad;
   }
   if ((kxc = kxc_byhc(kx, hc_in)) == 0) {
     goto bad;
   }
   if ((kxc = kxc_byhc(kx, hc_in)) == 0) {
-    a_warn("received reply for unknown challenge from `%s'", p_name(kx->p));
+    a_warn("KX %s unknown-challenge", p_name(kx->p));
     goto bad;
   }
 
     goto bad;
   }
 
@@ -731,7 +739,7 @@ static kxchal *matchreply(keyexch *kx, unsigned ty, const octet *hc_in,
 
   if (!kxc->r) {
     if (!ck) {
 
   if (!kxc->r) {
     if (!ck) {
-      a_warn("unexpected switch request from `%s'", p_name(kx->p));
+      a_warn("KX %s unexpected switch-rq", p_name(kx->p));
       goto bad;
     }
     if ((r = getreply(kx, kxc->c, ck)) == 0)
       goto bad;
     }
     if ((r = getreply(kx, kxc->c, ck)) == 0)
@@ -744,20 +752,20 @@ static kxchal *matchreply(keyexch *kx, unsigned ty, const octet *hc_in,
 
   buf_init(&bb, buf_o, sizeof(buf_o));
   if (ks_decrypt(kxc->ks, ty, b, &bb)) {
 
   buf_init(&bb, buf_o, sizeof(buf_o));
   if (ks_decrypt(kxc->ks, ty, b, &bb)) {
-    a_warn("failed to decrypt reply from `%s'", p_name(kx->p));
+    a_warn("KX %s decrypt-failed reply", p_name(kx->p));
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   r = G_CREATE(gg);
   if (G_FROMBUF(gg, b, r)) {
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   r = G_CREATE(gg);
   if (G_FROMBUF(gg, b, r)) {
-    a_warn("invalid reply packet from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid reply", p_name(kx->p));
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
     trace(T_CRYPTO, "crypto: reply = %s", gestr(gg, r));
   }))
   if (!G_EQ(gg, r, kx->rx)) {
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
     trace(T_CRYPTO, "crypto: reply = %s", gestr(gg, r));
   }))
   if (!G_EQ(gg, r, kx->rx)) {
-    a_warn("incorrect reply from `%s'", p_name(kx->p));
+    a_warn("KX %s incorrect reply", p_name(kx->p));
     goto bad;
   }
 
     goto bad;
   }
 
@@ -814,20 +822,20 @@ static int doreply(keyexch *kx, buf *b)
   kxchal *kxc;
 
   if (kx->s != KXS_CHAL && kx->s != KXS_COMMIT) {
   kxchal *kxc;
 
   if (kx->s != KXS_CHAL && kx->s != KXS_COMMIT) {
-    a_warn("unexpected reply from `%s'", p_name(kx->p));
+    a_warn("KX %s unexpected-reply", p_name(kx->p));
     goto bad;
   }
   if ((hc_in = buf_get(b, algs.hashsz)) == 0 ||
       (hc_out = buf_get(b, algs.hashsz)) == 0 ||
       (ck = buf_getmp(b)) == 0) {
     goto bad;
   }
   if ((hc_in = buf_get(b, algs.hashsz)) == 0 ||
       (hc_out = buf_get(b, algs.hashsz)) == 0 ||
       (ck = buf_getmp(b)) == 0) {
-    a_warn("invalid reply packet from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid reply", p_name(kx->p));
     goto bad;
   }
   if ((kxc = matchreply(kx, MSG_KEYEXCH | KX_REPLY,
                        hc_in, hc_out, ck, b)) == 0)
     goto bad;
   if (BLEFT(b)) {
     goto bad;
   }
   if ((kxc = matchreply(kx, MSG_KEYEXCH | KX_REPLY,
                        hc_in, hc_out, ck, b)) == 0)
     goto bad;
   if (BLEFT(b)) {
-    a_warn("invalid reply packet from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid reply", p_name(kx->p));
     goto bad;
   }
   if (kx->s == KXS_CHAL) {
     goto bad;
   }
   if (kx->s == KXS_CHAL) {
@@ -842,6 +850,25 @@ bad:
   return (-1);
 }
 
   return (-1);
 }
 
+/* --- @kxfinish@ --- *
+ *
+ * Arguments:  @keyexch *kx@ = pointer to key exchange block
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets everything up following a successful key exchange.
+ */
+
+static void kxfinish(keyexch *kx)
+{
+  kxchal *kxc = kx->r[0];
+  ks_activate(kxc->ks);
+  settimer(kx, ks_tregen(kxc->ks));
+  kx->s = KXS_SWITCH;
+  a_notify("KXDONE %s", p_name(kx->p));
+  p_stats(kx->p)->t_kx = time(0);
+}
+
 /* --- @doswitch@ --- *
  *
  * Arguments:  @keyexch *kx@ = pointer to key exchange block
 /* --- @doswitch@ --- *
  *
  * Arguments:  @keyexch *kx@ = pointer to key exchange block
@@ -859,30 +886,28 @@ static int doswitch(keyexch *kx, buf *b)
 
   if ((hc_in = buf_get(b, algs.hashsz)) == 0 ||
       (hc_out = buf_get(b, algs.hashsz)) == 0) {
 
   if ((hc_in = buf_get(b, algs.hashsz)) == 0 ||
       (hc_out = buf_get(b, algs.hashsz)) == 0) {
-    a_warn("invalid switch request from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid switch-rq", p_name(kx->p));
     goto bad;
   }
   if ((kxc = matchreply(kx, MSG_KEYEXCH | KX_SWITCH,
                        hc_in, hc_out, 0, b)) == 0)
     goto bad;
   if ((hswrq = buf_get(b, algs.hashsz)) == 0 || BLEFT(b)) {
     goto bad;
   }
   if ((kxc = matchreply(kx, MSG_KEYEXCH | KX_SWITCH,
                        hc_in, hc_out, 0, b)) == 0)
     goto bad;
   if ((hswrq = buf_get(b, algs.hashsz)) == 0 || BLEFT(b)) {
-    a_warn("invalid switch request from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid switch-rq", p_name(kx->p));
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, {
     trace_block(T_CRYPTO, "crypto: switch request hash", hswrq, algs.hashsz);
   })
   if (memcmp(hswrq, kxc->hswrq_in, algs.hashsz) != 0) {
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, {
     trace_block(T_CRYPTO, "crypto: switch request hash", hswrq, algs.hashsz);
   })
   if (memcmp(hswrq, kxc->hswrq_in, algs.hashsz) != 0) {
-    a_warn("incorrect switch request hash from `%s'", p_name(kx->p));
+    a_warn("KX %s incorrect switch-rq", p_name(kx->p));
     goto bad;
   }
   switch (kx->s) {
     case KXS_CHAL:
       commit(kx, kxc);
     case KXS_COMMIT:
     goto bad;
   }
   switch (kx->s) {
     case KXS_CHAL:
       commit(kx, kxc);
     case KXS_COMMIT:
-      ks_activate(kxc->ks);
-      settimer(kx, ks_tregen(kxc->ks));
-      kx->s = KXS_SWITCH;
+      kxfinish(kx);
       break;
   }
   resend(kx);
       break;
   }
   resend(kx);
@@ -909,18 +934,18 @@ static int doswitchok(keyexch *kx, buf *b)
   buf bb;
 
   if (kx->s < KXS_COMMIT) {
   buf bb;
 
   if (kx->s < KXS_COMMIT) {
-    a_warn("unexpected switch confirmation from `%s'", p_name(kx->p));
+    a_warn("KX %s unexpected switch-ok", p_name(kx->p));
     goto bad;
   }
   kxc = kx->r[0];
   buf_init(&bb, buf_o, sizeof(buf_o));
   if (ks_decrypt(kxc->ks, MSG_KEYEXCH | KX_SWITCHOK, b, &bb)) {
     goto bad;
   }
   kxc = kx->r[0];
   buf_init(&bb, buf_o, sizeof(buf_o));
   if (ks_decrypt(kxc->ks, MSG_KEYEXCH | KX_SWITCHOK, b, &bb)) {
-    a_warn("failed to decrypt switch confirmation from `%s'", p_name(kx->p));
+    a_warn("KX %s decrypt-failed switch-ok", p_name(kx->p));
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   if ((hswok = buf_get(b, algs.hashsz)) == 0 || BLEFT(b)) {
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   if ((hswok = buf_get(b, algs.hashsz)) == 0 || BLEFT(b)) {
-    a_warn("invalid switch confirmation from `%s'", p_name(kx->p));
+    a_warn("KX %s invalid switch-ok", p_name(kx->p));
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, {
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, {
@@ -928,14 +953,11 @@ static int doswitchok(keyexch *kx, buf *b)
                hswok, algs.hashsz);
   })
   if (memcmp(hswok, kxc->hswok_in, algs.hashsz) != 0) {
                hswok, algs.hashsz);
   })
   if (memcmp(hswok, kxc->hswok_in, algs.hashsz) != 0) {
-    a_warn("incorrect switch confirmation hash from `%s'", p_name(kx->p));
+    a_warn("KX %s incorrect switch-ok", p_name(kx->p));
     goto bad;
   }
     goto bad;
   }
-  if (kx->s < KXS_SWITCH) {
-    ks_activate(kxc->ks);
-    settimer(kx, ks_tregen(kxc->ks));
-    kx->s = KXS_SWITCH;
-  }
+  if (kx->s < KXS_SWITCH)
+    kxfinish(kx);
   return (0);
 
 bad:
   return (0);
 
 bad:
@@ -1037,7 +1059,7 @@ static int checkpub(keyexch *kx)
   now = time(0);
   if (KEY_EXPIRED(now, kx->texp_kpub)) {
     stop(kx);
   now = time(0);
   if (KEY_EXPIRED(now, kx->texp_kpub)) {
     stop(kx);
-    a_warn("public key for `%s' has expired", p_name(kx->p));
+    a_warn("KX %s public-key-expired", p_name(kx->p));
     G_COPY(gg, kx->kpub, gg->i);
     kx->f &= ~KXF_PUBKEY;
     return (-1);
     G_COPY(gg, kx->kpub, gg->i);
     kx->f &= ~KXF_PUBKEY;
     return (-1);
@@ -1062,9 +1084,10 @@ void kx_start(keyexch *kx)
 
   if (checkpub(kx))
     return;
 
   if (checkpub(kx))
     return;
-  if (!ISVALID(kx, now)) {
+  if (!VALIDP(kx, now)) {
     stop(kx);
     start(kx, now);
     stop(kx);
     start(kx, now);
+    a_notify("KXSTART %s", p_name(kx->p));
   }
   resend(kx);
 }
   }
   resend(kx);
 }
@@ -1088,17 +1111,10 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
   size_t sz = BSZ(b);
   int rc;
 
   size_t sz = BSZ(b);
   int rc;
 
-#ifndef NTRACE
-  static const char *const pkname[] = {
-    "prechallenge", "cookie", "challenge",
-    "reply", "switch request", "switch confirmation"
-  };
-#endif
-
   if (checkpub(kx))
     return;
 
   if (checkpub(kx))
     return;
 
-  if (!ISVALID(kx, now)) {
+  if (!VALIDP(kx, now)) {
     stop(kx);
     start(kx, now);
   }
     stop(kx);
     start(kx, now);
   }
@@ -1122,8 +1138,7 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
       rc = doswitchok(kx, b);
       break;
     default:
       rc = doswitchok(kx, b);
       break;
     default:
-      a_warn("unexpected key exchange message type %u from `%p'",
-            p_name(kx->p));
+      a_warn("KX %s unknown-message 0x%02x", p_name(kx->p), msg);
       rc = -1;
       break;
   }
       rc = -1;
       break;
   }
@@ -1202,6 +1217,7 @@ int kx_init(keyexch *kx, peer *p, keyset **ks)
   kx->f = KXF_DEAD | KXF_PUBKEY;
   start(kx, time(0));
   resend(kx);
   kx->f = KXF_DEAD | KXF_PUBKEY;
   start(kx, time(0));
   resend(kx);
+  a_notify("KXSTART %s", p_name(kx->p));
   return (0);
 }
 
   return (0);
 }
 
index 79945f419fd9e1fc193cdc5bc7a5dea0b8651efd..e1388e04c26b501319253518bd0fcaf5478bd7af 100644 (file)
--- a/keymgmt.c
+++ b/keymgmt.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: keymgmt.c,v 1.7 2004/04/19 08:49:40 mdw Exp $
+ * $Id$
  *
  * Key loading and storing
  *
  *
  * Key loading and storing
  *
@@ -185,12 +185,12 @@ static const char *algs_get(algswitch *a, key_file *kf, key *k)
   if ((p = key_getattr(kf, k, "cipher")) == 0)
     p = "blowfish-cbc";
   if ((a->c = gcipher_byname(p)) == 0)
   if ((p = key_getattr(kf, k, "cipher")) == 0)
     p = "blowfish-cbc";
   if ((a->c = gcipher_byname(p)) == 0)
-    FAIL("unknown cipher");
+    FAIL("unknown-cipher");
 
   if ((p = key_getattr(kf, k, "hash")) == 0)
     p = "rmd160";
   if ((a->h = ghash_byname(p)) == 0)
 
   if ((p = key_getattr(kf, k, "hash")) == 0)
     p = "rmd160";
   if ((a->h = ghash_byname(p)) == 0)
-    FAIL("unknown hash function");
+    FAIL("unknown-hash");
 
   if ((p = key_getattr(kf, k, "mgf")) == 0) {
     dstr_reset(&d);
 
   if ((p = key_getattr(kf, k, "mgf")) == 0) {
     dstr_reset(&d);
@@ -198,7 +198,7 @@ static const char *algs_get(algswitch *a, key_file *kf, key *k)
     p = d.buf;
   }
   if ((a->mgf = gcipher_byname(p)) == 0)
     p = d.buf;
   }
   if ((a->mgf = gcipher_byname(p)) == 0)
-    FAIL("unknown MGF cipher");
+    FAIL("unknown-mgf-cipher");
 
   if ((p = key_getattr(kf, k, "mac")) != 0) {
     dstr_reset(&d);
 
   if ((p = key_getattr(kf, k, "mac")) != 0) {
     dstr_reset(&d);
@@ -206,20 +206,20 @@ static const char *algs_get(algswitch *a, key_file *kf, key *k)
     if ((q = strchr(d.buf, '/')) != 0)
       *q++ = 0;
     if ((a->m = gmac_byname(d.buf)) == 0)
     if ((q = strchr(d.buf, '/')) != 0)
       *q++ = 0;
     if ((a->m = gmac_byname(d.buf)) == 0)
-      FAIL("unknown message authentication code");
+      FAIL("unknown-mac");
     if (!q)
       a->tagsz = a->m->hashsz;
     else {
       unsigned long n = strtoul(q, &q, 0);
     if (!q)
       a->tagsz = a->m->hashsz;
     else {
       unsigned long n = strtoul(q, &q, 0);
-      if (*q) FAIL("bad tag length string");
-      if (n%8 || n > ~(size_t)0) FAIL("bad tag length");
+      if (*q) FAIL("bad-tag-length-string");
+      if (n%8 || n > ~(size_t)0) FAIL("bad-tag-length");
       a->tagsz = n/8;
     }
   } else {
     dstr_reset(&d);
     dstr_putf(&d, "%s-hmac", a->h->name);
     if ((a->m = gmac_byname(d.buf)) == 0)
       a->tagsz = n/8;
     }
   } else {
     dstr_reset(&d);
     dstr_putf(&d, "%s-hmac", a->h->name);
     if ((a->m = gmac_byname(d.buf)) == 0)
-      FAIL("failed to derive HMAC from hash function");
+      FAIL("no-hmac-for-hash");
     a->tagsz = a->h->hashsz/2;
   }
 
     a->tagsz = a->h->hashsz/2;
   }
 
@@ -301,7 +301,7 @@ static int algs_samep(const algswitch *a, const algswitch *aa)
  */
 
 static void keymoan(const char *file, int line, const char *msg, void *p)
  */
 
 static void keymoan(const char *file, int line, const char *msg, void *p)
-  { a_warn("%s:%i: error: %s", file, line, msg); }
+  { a_warn("KEYMGMT key-file-error %s:%i -- %s", file, line, msg); }
 
 /* --- @loadpriv@ --- *
  *
 
 /* --- @loadpriv@ --- *
  *
@@ -471,7 +471,7 @@ int km_interval(void)
     T( trace(T_KEYMGMT, "keymgmt: private keyring updated: reloading..."); )
     DRESET(&d);
     if (loadpriv(&d))
     T( trace(T_KEYMGMT, "keymgmt: private keyring updated: reloading..."); )
     DRESET(&d);
     if (loadpriv(&d))
-      a_warn("%s -- ignoring changes", d.buf);
+      a_warn("KEYMGMT bad-private-key -- %s", d.buf);
     else
       reload = 1;
   }
     else
       reload = 1;
   }
@@ -483,7 +483,7 @@ int km_interval(void)
     kf = kf_pub;
     DRESET(&d);
     if (loadpub(&d))
     kf = kf_pub;
     DRESET(&d);
     if (loadpub(&d))
-      a_warn("%s -- ignoring changes", d.buf);
+      a_warn("KEYMGMT bad-public-keyring -- %s", d.buf);
     else {
       reload = 1;
       key_close(kf);
     else {
       reload = 1;
       key_close(kf);
@@ -558,7 +558,7 @@ int km_getpubkey(const char *tag, ge *kpub, time_t *t_exp)
   /* --- Find the key --- */
 
   if (key_qtag(kf_pub, tag, &t, &k, &kd)) {
   /* --- Find the key --- */
 
   if (key_qtag(kf_pub, tag, &t, &k, &kd)) {
-    a_warn("public key `%s' not found in keyring `%s'", tag, kr_pub);
+    a_warn("KEYMGMT public-key %s not-found", tag);
     goto done;
   }
 
     goto done;
   }
 
@@ -568,14 +568,14 @@ int km_getpubkey(const char *tag, ge *kpub, time_t *t_exp)
     if (strcmp((*ko)->ty, k->type) == 0)
       goto tymatch;
   }
     if (strcmp((*ko)->ty, k->type) == 0)
       goto tymatch;
   }
-  a_warn("public key `%s' has unknown type `%s'", t.buf, k->type);
+  a_warn("KEYMGMT public-key %s unknown-type %s", t.buf, k->type);
   goto done;
 tymatch:;
 
   /* --- Load the key --- */
 
   if ((e = (*ko)->loadpub(kd, &g, &p, &t)) != 0) {
   goto done;
 tymatch:;
 
   /* --- Load the key --- */
 
   if ((e = (*ko)->loadpub(kd, &g, &p, &t)) != 0) {
-    a_warn("error reading public key `%s': %s", t.buf, e);
+    a_warn("KEYMGMT public-key %s bad -- %s", t.buf, e);
     goto done;
   }
 
     goto done;
   }
 
@@ -586,25 +586,25 @@ tymatch:;
    */
 
   if (!group_samep(gg, g)) {
    */
 
   if (!group_samep(gg, g)) {
-    a_warn("public key `%s' has incorrect group", t.buf);
+    a_warn("KEYMGMT public-key %s incorrect-group", t.buf);
     goto done;
   }
 
   /* --- Check the public group element --- */
 
   if (group_check(gg, p)) {
     goto done;
   }
 
   /* --- Check the public group element --- */
 
   if (group_check(gg, p)) {
-    a_warn("public key `%s' has bad public group element", t.buf);
+    a_warn("KEYMGMT public-key %s bad-public-group-element", t.buf);
     goto done;
   }
 
   /* --- Check the algorithms --- */
 
   if ((e = algs_get(&a, kf_pub, k)) != 0) {
     goto done;
   }
 
   /* --- Check the algorithms --- */
 
   if ((e = algs_get(&a, kf_pub, k)) != 0) {
-    a_warn("public key `%s' has bad algorithm selection: %s", t.buf, e);
+    a_warn("KEYMGMT public-key %s bad-algorithm-selection %s", t.buf, e);
     goto done;
   }
     goto done;
   }
-  if (!algs_samep(&a, &algs)) {    
-    a_warn("public key `%s' specifies different algorithms", t.buf);
+  if (!algs_samep(&a, &algs)) {
+    a_warn("KEYMGMT public-key %s algorithm-mismatch", t.buf);
     goto done;
   }
 
     goto done;
   }
 
index 8893e6066ed7d89cb791605a8413e85464f94e3e..cdd0c99990a1106b700e2ba25814d9db169b51e5 100644 (file)
--- a/keyset.c
+++ b/keyset.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: keyset.c,v 1.11 2004/04/18 18:08:11 mdw Exp $
+ * $Id$
  *
  * Handling of symmetric keysets
  *
  *
  * Handling of symmetric keysets
  *
@@ -269,7 +269,7 @@ static int dosequence(keyset *ks, uint32 seq)
   uint32 n;
 
   if (seq < ks->iseq) {
   uint32 n;
 
   if (seq < ks->iseq) {
-    a_warn("received packet has old sequence number (possible replay)");
+    a_warn("SYMM replay old-sequence");
     return (-1);
   }
   if (seq >= ks->iseq + KS_SEQWINSZ) {
     return (-1);
   }
   if (seq >= ks->iseq + KS_SEQWINSZ) {
@@ -282,7 +282,7 @@ static int dosequence(keyset *ks, uint32 seq)
   }
   seqbit = 1 << (seq - ks->iseq);
   if (ks->iwin & seqbit) {
   }
   seqbit = 1 << (seq - ks->iseq);
   if (ks->iwin & seqbit) {
-    a_warn("received packet repeats old sequence number");
+    a_warn("SYMM replay duplicated-sequence");
     return (-1);
   }
   ks->iwin |= seqbit;
     return (-1);
   }
   ks->iwin |= seqbit;
index 5078b9b5d442f68dc72a74bb78140be40b0dde3f..970e18e7c168ae1e3502bce0373182823ed1867b 100644 (file)
--- a/mallory.c
+++ b/mallory.c
@@ -619,14 +619,14 @@ static void help(FILE *fp)
   putc('\n', fp);
   usage(fp);
   fputs("\n\
   putc('\n', fp);
   usage(fp);
   fputs("\n\
-Options:
-
--h, --help             Show this help text.
--v, --version          Show the version number.
--u, --usage            Show terse usage summary.
-
--k, --keyring=FILE     Fetch keys from FILE.
-
+Options:\n\
+\n\
+-h, --help             Show this help text.\n\
+-v, --version          Show the version number.\n\
+-u, --usage            Show terse usage summary.\n\
+\n\
+-k, --keyring=FILE     Fetch keys from FILE.\n\
+\n\
 Directives:\n\
   peer:NAME:LOCAL-PORT:REMOTE-ADDR:REMOTE-PORT\n\
   include:FILE\n\
 Directives:\n\
   peer:NAME:LOCAL-PORT:REMOTE-ADDR:REMOTE-PORT\n\
   include:FILE\n\
diff --git a/peer.c b/peer.c
index 87ea4e9e6d36856ad71ecabbbe2d85edbcaedbc0..1469a3a86340995a4baa6340d46821e1d6977e0f 100644 (file)
--- a/peer.c
+++ b/peer.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: peer.c,v 1.11 2004/04/08 01:36:17 mdw Exp $
+ * $Id$
  *
  * Communication with the peer
  *
  *
  * Communication with the peer
  *
@@ -63,7 +63,7 @@ static void p_read(int fd, unsigned mode, void *v)
   sz = sizeof(addr);
   n = recvfrom(fd, buf_i, sizeof(buf_i), 0, &a.sa, &sz);
   if (n < 0) {
   sz = sizeof(addr);
   n = recvfrom(fd, buf_i, sizeof(buf_i), 0, &a.sa, &sz);
   if (n < 0) {
-    a_warn("error reading socket: %s", strerror(errno));
+    a_warn("PEER - socket-read-error -- %s", strerror(errno));
     return;
   }
 
     return;
   }
 
@@ -75,8 +75,8 @@ static void p_read(int fd, unsigned mode, void *v)
        p->peer.sin.sin_port == a.sin.sin_port)
       goto found;
   }
        p->peer.sin.sin_port == a.sin.sin_port)
       goto found;
   }
-  a_warn("packet from unexpected peer: %s:%u",
-       inet_ntoa(a.sin.sin_addr), (unsigned)ntohs(a.sin.sin_port));
+  a_warn("PEER - unexpected-source INET %s %u",
+        inet_ntoa(a.sin.sin_addr), (unsigned)ntohs(a.sin.sin_port));
   return;
 
 found:
   return;
 
 found:
@@ -90,20 +90,20 @@ found:
   p->st.sz_in += n;
   buf_init(&b, buf_i, n);
   if ((ch = buf_getbyte(&b)) < 0) {
   p->st.sz_in += n;
   buf_init(&b, buf_i, n);
   if ((ch = buf_getbyte(&b)) < 0) {
-    a_warn("bad packet from `%s': no type byte", p->name);
+    a_warn("PEER %s bad-packet no-type", p->name);
     return;
   }
   switch (ch & MSG_CATMASK) {
     case MSG_PACKET:
       if (ch & MSG_TYPEMASK) {
     return;
   }
   switch (ch & MSG_CATMASK) {
     case MSG_PACKET:
       if (ch & MSG_TYPEMASK) {
-       a_warn("unknown packet type from `%s'", p->name);
+       a_warn("PEER %s bad-packet unknown-type 0x%02x", p->name, ch);
        p->st.n_reject++;
        return;
       }
       buf_init(&bb, buf_o, sizeof(buf_o));
       if (ksl_decrypt(&p->ks, MSG_PACKET, &b, &bb)) {
        p->st.n_reject++;
        p->st.n_reject++;
        return;
       }
       buf_init(&bb, buf_o, sizeof(buf_o));
       if (ksl_decrypt(&p->ks, MSG_PACKET, &b, &bb)) {
        p->st.n_reject++;
-       a_warn("couldn't decrypt inbound packet from `%s'", p->name);
+       a_warn("PEER %s decrypt-failed", p->name);
        return;
       }
       if (BOK(&bb)) {
        return;
       }
       if (BOK(&bb)) {
@@ -112,7 +112,7 @@ found:
        tun_inject(&p->t, &bb);
       } else {
        p->st.n_reject++;
        tun_inject(&p->t, &bb);
       } else {
        p->st.n_reject++;
-       a_warn("packet build failed");
+       a_warn("PEER %s packet-build-failed", p->name);
       }
       break;
     case MSG_KEYEXCH:
       }
       break;
     case MSG_KEYEXCH:
@@ -120,7 +120,7 @@ found:
       break;
     default:
       p->st.n_reject++;
       break;
     default:
       p->st.n_reject++;
-      a_warn("bad packet from `%s': unknown packet type", p->name);
+      a_warn("PEER %s bad-packet unknown-category 0x%02x", p->name, ch);
       break;
   }
 }
       break;
   }
 }
@@ -155,14 +155,14 @@ buf *p_txstart(peer *p, unsigned msg)
 void p_txend(peer *p)
 {
   if (!BOK(&p->b)) {
 void p_txend(peer *p)
 {
   if (!BOK(&p->b)) {
-    a_warn("packet build failed");
+    a_warn("PEER %s packet-build-failed", p->name);
     return;
   }
   IF_TRACING(T_PEER, trace_block(T_PACKET, "peer: sending packet",
                                 BBASE(&p->b), BLEN(&p->b)); )
   if (sendto(sock.fd, BBASE(&p->b), BLEN(&p->b),
             0, &p->peer.sa, p->sasz) < 0)
     return;
   }
   IF_TRACING(T_PEER, trace_block(T_PACKET, "peer: sending packet",
                                 BBASE(&p->b), BLEN(&p->b)); )
   if (sendto(sock.fd, BBASE(&p->b), BLEN(&p->b),
             0, &p->peer.sa, p->sasz) < 0)
-    a_warn("packet send to `%s' failed: %s", p->name, strerror(errno));
+    a_warn("PEER %s socket-write-error -- %s", p->name, strerror(errno));
   else {
     p->st.n_out++;
     p->st.sz_out += BLEN(&p->b);
   else {
     p->st.n_out++;
     p->st.sz_out += BLEN(&p->b);
@@ -335,6 +335,17 @@ peer *p_create(const char *name, struct sockaddr *sa, size_t sz)
   if (peers)
     peers->prev = p;
   peers = p;
   if (peers)
     peers->prev = p;
   peers = p;
+  switch (p->peer.sa.sa_family) {
+    case AF_INET:
+      a_notify("ADD %s INET %s %u",
+              name,
+              inet_ntoa(p->peer.sin.sin_addr),
+              (unsigned)ntohs(p->peer.sin.sin_port));
+      break;
+    default:
+      a_notify("ADD %s UNKNOWN", name);
+      break;
+  }
   return (p);
 
 tidy_1:
   return (p);
 
 tidy_1:
@@ -385,6 +396,7 @@ peer *p_find(const char *name)
 void p_destroy(peer *p)
 {
   T( trace(T_PEER, "peer: destroying peer `%s'", p->name); )
 void p_destroy(peer *p)
 {
   T( trace(T_PEER, "peer: destroying peer `%s'", p->name); )
+  a_notify("KILL %s", p->name);
   ksl_free(&p->ks);
   kx_free(&p->kx);
   tun_destroy(&p->t);
   ksl_free(&p->ks);
   kx_free(&p->kx);
   tun_destroy(&p->t);
diff --git a/setup b/setup
index a74f9dae895ba78565db5dbc74e5feb1c15fe887..ed80e2b017c71f162603ad8e2b61e5bf860c265a 100755 (executable)
--- a/setup
+++ b/setup
@@ -6,5 +6,5 @@ mkaclocal
 libtoolize
 autoheader
 autoconf
 libtoolize
 autoheader
 autoconf
-automake
+automake -a
 mkdir -p build
 mkdir -p build
index 8c4730e5ae2f25cd8ed93837d1ed444b029e8050..b02b8269fd03aaa7b11497a892dd724bae7c99f6 100755 (executable)
@@ -10,11 +10,19 @@ set -e
 [ -f @initconfig@ ] && . @initconfig@
 : ${prefix=@prefix@} ${exec_prefix=@exec_prefix@}
 : ${bindir=@bindir@} ${sbindir=@sbindir@}
 [ -f @initconfig@ ] && . @initconfig@
 : ${prefix=@prefix@} ${exec_prefix=@exec_prefix@}
 : ${bindir=@bindir@} ${sbindir=@sbindir@}
-: ${TRIPEDIR=@configdir@}
+: ${TRIPEDIR=@configdir@} ${tripesock=@socketdir@/tripesock}
+: ${pidfile=@pidfile@}
 : ${tripe=$sbindir/tripe} ${tripectl=$bindir/tripectl}
 PATH=/usr/bin:/usr/sbin:/bin:/sbin:$bindir
 export PATH TRIPEDIR
 
 : ${tripe=$sbindir/tripe} ${tripectl=$bindir/tripectl}
 PATH=/usr/bin:/usr/sbin:/bin:/sbin:$bindir
 export PATH TRIPEDIR
 
+# --- Give up if there's no key ---
+
+if test ! -f $TRIPEDIR/keyring || test ! -f $TRIPEDIR/keyring.pub; then
+  echo >&2 "Not starting/stopping TrIPE: keyring files missing"
+  exit 0
+fi
+
 # --- Check it will work, or at least stands a fighting chance ---
 #
 # Having loads of different tunnel types doesn't help any.
 # --- Check it will work, or at least stands a fighting chance ---
 #
 # Having loads of different tunnel types doesn't help any.
@@ -98,13 +106,13 @@ esac
 case "$1" in
   start)
     echo -n "Starting TrIPE VPN daemon:"
 case "$1" in
   start)
     echo -n "Starting TrIPE VPN daemon:"
-    if $tripectl help >/dev/null 2>/dev/null; then
+    if $tripectl version >/dev/null 2>/dev/null; then
       echo " already running"
       exit 0
     fi
     $tripectl -D -s -p$tripe \
       -f${logfile-@logfile@} \
       echo " already running"
       exit 0
     fi
     $tripectl -D -s -p$tripe \
       -f${logfile-@logfile@} \
-      -P${pidfile-@pidfile@} \
+      -P$pidfile \
       ${keytag+-S-t}$keytag \
       ${addr+-S-b}$addr \
       ${port+-S-p}${port} \
       ${keytag+-S-t}$keytag \
       ${addr+-S-b}$addr \
       ${port+-S-p}${port} \
@@ -135,8 +143,19 @@ case "$1" in
     ;;
   stop)
     echo -n "Stopping TrIPE VPN daemon:"
     ;;
   stop)
     echo -n "Stopping TrIPE VPN daemon:"
-    $tripectl quit
-    echo " done"
+    if test ! -S $tripesock; then
+      echo " not running"
+    elif $tripectl quit >/dev/null 2>&1; then
+      echo " done"
+    elif test ! -f $pidfile; then
+      echo " stale socket found: removing"
+      rm -f $tripesock
+    elif kill `cat $pidfile`; then
+      echo " done (killed violently)"
+    else
+      echo " it doesn't want do die!"
+      exit 1
+    fi
     ;;
   status)
     for i in `$tripectl list`; do
     ;;
   status)
     for i in `$tripectl list`; do
diff --git a/tripe.c b/tripe.c
index 0ba169b22cc69218aeb7cc1d61a3ffd7a188a43c..78a3d726c583f948cc387d02f3d2e4ab59906498 100644 (file)
--- a/tripe.c
+++ b/tripe.c
@@ -95,6 +95,7 @@ Options:\n\
 -h, --help             Display this help text.\n\
 -v, --version          Display version number.\n\
 -u, --usage            Display pointless usage message.\n\
 -h, --help             Display this help text.\n\
 -v, --version          Display version number.\n\
 -u, --usage            Display pointless usage message.\n\
+    --tunnel           Display IP tunnelling technique and exit.\n\
 \n\
 -D, --daemon           Run in the background.\n\
 -d, --directory=DIR    Switch to directory DIR [default " CONFIGDIR "].\n\
 \n\
 -D, --daemon           Run in the background.\n\
 -d, --directory=DIR    Switch to directory DIR [default " CONFIGDIR "].\n\
@@ -273,8 +274,13 @@ int main(int argc, char *argv[])
   signal(SIGPIPE, SIG_IGN);
   tun_init();
   p_init(baddr, port);
   signal(SIGPIPE, SIG_IGN);
   tun_init();
   p_init(baddr, port);
-  if (!(f & f_daemon))
-    a_create(STDIN_FILENO, STDOUT_FILENO);
+  if (!(f & f_daemon)) {
+#ifndef NTRACE
+    a_create(STDIN_FILENO, STDOUT_FILENO, AF_TRACE | AF_WARN);
+#else
+    a_create(STDIN_FILENO, STDOUT_FILENO, AF_WARN);
+#endif
+  }
   if (g != (gid_t)-1) {
     if (setgid(g) || (getuid() == 0 && setgroups(1, &g))) {
       die(EXIT_FAILURE, "couldn't setgid to %u: %s",
   if (g != (gid_t)-1) {
     if (setgid(g) || (getuid() == 0 && setgroups(1, &g))) {
       die(EXIT_FAILURE, "couldn't setgid to %u: %s",
@@ -308,11 +314,11 @@ int main(int argc, char *argv[])
       if (!sel_select(&sel))
         selerr = 0;
       else if (errno != EINTR && errno != EAGAIN) {
       if (!sel_select(&sel))
         selerr = 0;
       else if (errno != EINTR && errno != EAGAIN) {
-       a_warn("select failed: %s", strerror(errno));
+       a_warn("SERVER select-error -- %s", strerror(errno));
        selerr++;
        if (selerr > 8) {
        selerr++;
        if (selerr > 8) {
-         a_warn("too many select errors: bailing out");
-         a_quit();
+         a_warn("ABORT repeated-select-errors");
+         abort();
        }
       }
     }
        }
       }
     }
diff --git a/tripe.h b/tripe.h
index 7de033d3326a7015a37064d535a80e5b70745cd0..320a2ca5218f91d4672aabf6e95a8f81ba4f2895 100644 (file)
--- a/tripe.h
+++ b/tripe.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: tripe.h,v 1.20 2004/04/18 18:08:11 mdw Exp $
+ * $Id$
  *
  * Main header file for TrIPE
  *
  *
  * Main header file for TrIPE
  *
@@ -292,7 +292,7 @@ typedef struct stats {
   unsigned long sz_in, sz_out;         /* Size of all data in and out */
   unsigned long sz_kxin, sz_kxout;     /* Size of key exchange messages */
   unsigned long sz_ipin, sz_ipout;     /* Size of encapsulated IP packets */
   unsigned long sz_in, sz_out;         /* Size of all data in and out */
   unsigned long sz_kxin, sz_kxout;     /* Size of key exchange messages */
   unsigned long sz_ipin, sz_ipout;     /* Size of encapsulated IP packets */
-  time_t t_start, t_last;              /* Time peer created, last recv */
+  time_t t_start, t_last, t_kx;                /* Time peer created, last pk, kx */
   unsigned long n_reject;              /* Number of rejected packets */
   unsigned long n_in, n_out;           /* Number of packets in and out */
   unsigned long n_kxin, n_kxout;       /* Number of key exchange packets */
   unsigned long n_reject;              /* Number of rejected packets */
   unsigned long n_in, n_out;           /* Number of packets in and out */
   unsigned long n_kxin, n_kxout;       /* Number of key exchange packets */
@@ -345,6 +345,17 @@ typedef struct admin {
 
 #define AF_DEAD 1u                     /* Destroy this admin block */
 #define AF_LOCK 2u                     /* Don't destroy it yet */
 
 #define AF_DEAD 1u                     /* Destroy this admin block */
 #define AF_LOCK 2u                     /* Don't destroy it yet */
+#define AF_NOTE 4u                     /* Catch notifications */
+#ifndef NTRACE
+  #define AF_TRACE 8u                  /* Catch tracing */
+#endif
+#define AF_WARN 16u                    /* Catch warning messages */
+
+#ifndef NTRACE
+#  define AF_ALLMSGS (AF_NOTE | AF_TRACE | AF_WARN)
+#else
+#  define AF_ALLMSGS (AF_NOTE | AF_WARN)
+#endif
 
 /*----- Global variables --------------------------------------------------*/
 
 
 /*----- Global variables --------------------------------------------------*/
 
@@ -651,16 +662,29 @@ extern int ksl_decrypt(keyset **/*ksroot*/, unsigned /*ty*/,
 
 extern void a_warn(const char */*fmt*/, ...);
 
 
 extern void a_warn(const char */*fmt*/, ...);
 
+/* --- @a_notify@ --- *
+ *
+ * Arguments:  @const char *fmt@ = pointer to format string
+ *             @...@ = other arguments
+ *
+ * Returns:    ---
+ *
+ * Use:                Sends a notification to interested admin connections.
+ */
+
+extern void a_notify(const char */*fmt*/, ...);
+
 /* --- @a_create@ --- *
  *
  * Arguments:  @int fd_in, fd_out@ = file descriptors to use
 /* --- @a_create@ --- *
  *
  * Arguments:  @int fd_in, fd_out@ = file descriptors to use
+ *             @unsigned f@ = initial flags to set
  *
  * Returns:    ---
  *
  * Use:                Creates a new admin connection.
  */
 
  *
  * Returns:    ---
  *
  * Use:                Creates a new admin connection.
  */
 
-extern void a_create(int /*fd_in*/, int /*fd_out*/);
+extern void a_create(int /*fd_in*/, int /*fd_out*/, unsigned /*f*/);
 
 /* --- @a_quit@ --- *
  *
 
 /* --- @a_quit@ --- *
  *
index c9b8f7f0404d45dbdfbbe4612bba6a25ad1b0d5f..620ea987e72b764ef19f4cde933420d4d66f4406 100644 (file)
--- a/tun-bsd.c
+++ b/tun-bsd.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: tun-bsd.c,v 1.3 2004/04/08 01:36:17 mdw Exp $
+ * $Id$
  *
  * Tunnel interface for 4.4BSD-derived systems
  *
  *
  * Tunnel interface for 4.4BSD-derived systems
  *
@@ -55,7 +55,7 @@ void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("tunnel read failed (%s): %s", tun_ifname(t), strerror(errno));
+    a_warn("TUN %s read-error -- %s", tun_ifname(t), strerror(errno));
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -107,10 +107,10 @@ int tun_create(tunnel *t, peer *p)
        T( trace(T_TUNNEL, "tunnel device %u busy: skipping", n); )
        break;
       case ENOENT:
        T( trace(T_TUNNEL, "tunnel device %u busy: skipping", n); )
        break;
       case ENOENT:
-       a_warn("no suitable tunnel devices found");
+       a_warn("TUN - bsd no-tunnel-devices");
        return (-1);
       default:
        return (-1);
       default:
-       a_warn("error opening `%s': %s (skipping)", buf, strerror(errno));
+       a_warn("TUN - open-error %s -- %s", buf, strerror(errno));
        break;
     }
     n++;
        break;
     }
     n++;
index c30784d7cf91c76c61cabfd0c3e2b9904ce8b39c..6aa5adb4219da4426728aa5505e20a0944e24d5d 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: tun-linux.c,v 1.3 2004/04/08 01:36:17 mdw Exp $
+ * $Id$
  *
  * Tunnel interface based on Linux TUN/TAP driver
  *
  *
  * Tunnel interface based on Linux TUN/TAP driver
  *
@@ -57,7 +57,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("tunnel read failed (%s): %s", t->ifn, strerror(errno));
+    a_warn("TUN %s read-error -- %s", t->ifn, strerror(errno));
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -100,15 +100,14 @@ int tun_create(tunnel *t, peer *p)
   struct ifreq iff;
 
   if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
   struct ifreq iff;
 
   if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
-    a_warn("open `/dev/net/tun' failed: %s", strerror(errno));
+    a_warn("TUN - open-error /dev/net/tun -- %s", strerror(errno));
     return (-1);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   iff.ifr_name[0] = 0;
   iff.ifr_flags = IFF_TUN;
   if ((f = ioctl(fd, TUNSETIFF, &iff)) < 0) {
     return (-1);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   iff.ifr_name[0] = 0;
   iff.ifr_flags = IFF_TUN;
   if ((f = ioctl(fd, TUNSETIFF, &iff)) < 0) {
-    a_warn("couldn't set configure new TUN/TAP interface: %s",
-          strerror(errno));
+    a_warn("TUN - linux config-error -- %s", strerror(errno));
     close(fd);
     return (-1);
   }
     close(fd);
     return (-1);
   }
index 8d0225a366c776621a736f0583208ebf38548a72..1cbdf2beaa86130f51d5e08402a89dadecfb0674 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: tun-unet.c,v 1.6 2004/04/08 01:36:17 mdw Exp $
+ * $Id$
  *
  * Tunnel interface based on Linux Usernet
  *
  *
  * Tunnel interface based on Linux Usernet
  *
@@ -59,7 +59,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("tunnel read failed (%s): %s", tun_ifname(t), strerror(errno));
+    a_warn("TUN %s read-error -- %s", tun_ifname(t), strerror(errno));
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -101,13 +101,13 @@ int tun_create(tunnel *t, peer *p)
   int f;
 
   if ((fd = open("/dev/unet", O_RDWR)) < 0) {
   int f;
 
   if ((fd = open("/dev/unet", O_RDWR)) < 0) {
-    a_warn("open `/dev/unet' failed: %s", strerror(errno));
+    a_warn("TUN - open-error /dev/unet -- %s", strerror(errno));
     return (-1);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0 ||
       ioctl(fd, UNIOCSIFFLAGS, f | IFF_POINTOPOINT)) {
     return (-1);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0 ||
       ioctl(fd, UNIOCSIFFLAGS, f | IFF_POINTOPOINT)) {
-    a_warn("couldn't set point-to-point flag: %s", strerror(errno));
+    a_warn("TUN - unet config-error -- %s", strerror(errno));
     close(fd);
     return (-1);
   }
     close(fd);
     return (-1);
   }
@@ -131,11 +131,11 @@ const char *tun_ifname(tunnel *t)
   static char b[UNET_NAMEMAX];
   struct unet_info uni;
   if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
   static char b[UNET_NAMEMAX];
   struct unet_info uni;
   if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
-    a_warn("ioctl(UNIOCGINFO) failed: %s", strerror(errno));
+    a_warn("TUN - unet getinfo-error -- %s", strerror(errno));
     return ("<error>");
   }
   if (strlen(uni.uni_ifname) + 1 > sizeof(b)) {
     return ("<error>");
   }
   if (strlen(uni.uni_ifname) + 1 > sizeof(b)) {
-    a_warn("interface name too long!");
+    a_warn("TUN - unet ifname-too-long");
     return ("<error>");
   }
   strcpy(b, uni.uni_ifname);
     return ("<error>");
   }
   strcpy(b, uni.uni_ifname);