chiark / gitweb /
Correctly tokenize output to admin clients.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 19 Feb 2006 15:03:19 +0000 (15:03 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 21 Feb 2006 23:55:15 +0000 (23:55 +0000)
This is a wide ranging change, and there may well be bugs in some of the
message reporting code.

14 files changed:
admin.c
chal.c
doc/tripe-admin.5
keyexch.c
keymgmt.c
keyset.c
peer.c
servutil.c
tripe.c
tripe.h
tun-bsd.c
tun-linux.c
tun-slip.c
tun-unet.c

diff --git a/admin.c b/admin.c
index da7ccad..bc2bdf3 100644 (file)
--- a/admin.c
+++ b/admin.c
@@ -112,7 +112,7 @@ again:
       goto again;
     if (errno != EAGAIN && errno != EWOULDBLOCK) {
       a_destroy(a);
-      a_warn("ADMIN client-read-error -- %s", strerror(errno));
+      a_warn("ADMIN", "client-write-error", "?ERRNO", A_END);
       return (-1);
     }
   }
@@ -231,6 +231,95 @@ static void a_flush(int fd, unsigned mode, void *v)
 
 /*----- Utility functions -------------------------------------------------*/
 
+/* --- @quotify@ --- *
+ *
+ * Arguments:  @dstr *d@ = where to write the answer
+ *             @const char *p@ = string to quotify
+ *
+ * Returns:    ---
+ *
+ * Use:                Quotes the given string if necessary, according to our
+ *             quoting rules.
+ */
+
+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, '\"');
+  }
+}
+
+/* --- @a_vformat@ --- *
+ *
+ * Arguments:  @dstr *d@ = where to leave the formatted message
+ *             @const char *fmt@ = pointer to format string
+ *             @va_list ap@ = arguments in list
+ *
+ * Returns:    ---
+ *
+ * Use:                Main message token formatting driver.
+ */
+
+static void a_vformat(dstr *d, const char *fmt, va_list ap)
+{
+  dstr dd = DSTR_INIT;
+
+  while (fmt) {
+    if (*fmt == '*') {
+      dstr_putc(d, ' ');
+      dstr_vputf(d, fmt + 1, &ap);
+    } else if (*fmt == '?') {
+      if (strcmp(fmt, "?ADDR") == 0) {
+       const addr *a = va_arg(ap, const addr *);
+       switch (a->sa.sa_family) {
+         case AF_INET:
+           quotify(d, "INET");
+           quotify(d, inet_ntoa(a->sin.sin_addr));
+           dstr_putf(d, " %u", (unsigned)ntohs(a->sin.sin_port));
+           break;
+         default:
+           abort();
+       }
+      } else if (strcmp(fmt, "?B64") == 0) {
+       const octet *p = va_arg(ap, const octet *);
+       size_t n = va_arg(ap, size_t);
+       base64_ctx b64;
+       dstr_putc(d, ' ');
+       base64_init(&b64);
+       b64.indent = "";
+       b64.maxline = 0;
+       base64_encode(&b64, p, n, d);
+       base64_encode(&b64, 0, 0, d);
+       while (d->len && d->buf[d->len - 1] == '=') d->len--;
+      } else if (strcmp(fmt, "?PEER") == 0)
+       quotify(d, p_name(va_arg(ap, peer *)));
+      else if (strcmp(fmt, "?ERRNO") == 0) {
+       dstr_putf(d, " E%d", errno);
+       quotify(d, strerror(errno));
+      } else
+       abort();
+    } else {
+      if (*fmt == '!') fmt++;
+      DRESET(&dd);
+      dstr_vputf(&dd, fmt, &ap);
+      quotify(d, dd.buf);
+    }
+    fmt = va_arg(ap, const char *);
+  }
+
+  dstr_destroy(&dd);
+}
+
 /* --- @a_write@, @a_vwrite@ --- *
  *
  * Arguments:  @admin *a@ = admin connection to write to
@@ -249,17 +338,10 @@ static void a_vwrite(admin *a, const char *status, const char *tag,
                     const char *fmt, va_list ap)
 {
   dstr d = DSTR_INIT;
-
   if (tag) dstr_puts(&d, "BG");
   dstr_puts(&d, status);
-  if (tag) {
-    dstr_putc(&d, ' ');
-    dstr_puts(&d, tag);
-  }
-  if (fmt) {
-    dstr_putc(&d, ' ');
-    dstr_vputf(&d, fmt, &ap);
-  }
+  if (tag) quotify(&d, tag);
+  a_vformat(&d, fmt, ap);
   dstr_putc(&d, '\n');
   dosend(a, d.buf, d.len);
   dstr_destroy(&d);
@@ -285,7 +367,7 @@ static void a_write(admin *a, const char *status, const char *tag,
  * Use:                Convenience functions for @a_write@.
  */
 
-static void a_ok(admin *a) { a_write(a, "OK", 0, 0); }
+static void a_ok(admin *a) { a_write(a, "OK", 0, A_END); }
 
 static void a_info(admin *a, const char *fmt, ...)
 {
@@ -350,8 +432,7 @@ static void a_valert(unsigned f_and, unsigned f_eq, const char *tag,
 
   if (!(flags & F_INIT))
     return;
-  if (fmt)
-    dstr_vputf(&d, fmt, &ap);
+  a_vformat(&d, fmt, ap);
   a_rawalert(f_and, f_eq, tag, fmt ? d.buf : 0, fmt ? d.len : 0);
   dstr_destroy(&d);
 }
@@ -385,9 +466,12 @@ void a_warn(const char *fmt, ...)
   if (flags & F_INIT)
     a_valert(0, 0, "WARN", fmt, ap);
   else {
+    dstr d = DSTR_INIT;
     fprintf(stderr, "%s: ", QUIS);
-    vfprintf(stderr, fmt, ap);
-    fputc('\n', stderr);
+    a_vformat(&d, fmt, ap);
+    dstr_putc(&d, '\n');
+    dstr_write(&d, stderr);
+    dstr_destroy(&d);
   }
   va_end(ap);
 }
@@ -471,7 +555,7 @@ static void a_sigdie(int sig, void *v)
       p = buf;
       break;
   }
-  a_warn("SERVER quit signal %s", p);
+  a_warn("SERVER", "quit", "signal", "%s", p, A_END);
   a_quit();
 }
 
@@ -487,7 +571,7 @@ static void a_sigdie(int sig, void *v)
 
 static void a_sighup(int sig, void *v)
 {
-  a_warn("SERVER ignore signal SIGHUP");
+  a_warn("SERVER", "ignore", "signal", "SIGHUP", A_END);
 }
 
 /* --- @a_parsetime@ --- *
@@ -528,7 +612,7 @@ static peer *a_findpeer(admin *a, const char *pn)
   peer *p;
 
   if ((p = p_find(pn)) == 0)
-    a_fail(a, "unknown-peer %s", pn);
+    a_fail(a, "unknown-peer", "%s", pn, A_END);
   return (p);
 }
 
@@ -574,7 +658,7 @@ static void a_bgrelease(admin_bgop *bg)
  */
 
 static void a_bgok(admin_bgop *bg)
-  { a_write(bg->a, "OK", bg->tag, 0); }
+  { a_write(bg->a, "OK", bg->tag, A_END); }
 
 static void a_bginfo(admin_bgop *bg, const char *fmt, ...)
 {
@@ -621,7 +705,7 @@ static void a_bgadd(admin *a, admin_bgop *bg, const char *tag,
   a->bg = bg;
   a_lock(a);
   T( trace(T_ADMIN, "admin: add bgop %s", BGTAG(bg)); )
-  if (tag) a_write(a, "DETACH", tag, 0);
+  if (tag) a_write(a, "DETACH", tag, A_END);
 }
 
 /*----- Name resolution operations ----------------------------------------*/
@@ -643,7 +727,7 @@ static void a_resolved(struct hostent *h, void *v)
   T( trace(T_ADMIN, "admin: resop %s resolved", BGTAG(r)); )
   TIMER;
   if (!h) {
-    a_bgfail(&r->bg, "resolve-error %s", r->addr);
+    a_bgfail(&r->bg, "resolve-error", "%s", r->addr, A_END);
     r->func(r, ARES_FAIL);
   } else {
     memcpy(&r->sa.sin.sin_addr, h->h_addr, sizeof(struct in_addr));
@@ -669,7 +753,7 @@ static void a_restimer(struct timeval *tv, void *v)
   admin_resop *r = v;
 
   T( trace(T_ADMIN, "admin: resop %s timeout", BGTAG(r)); )
-  a_bgfail(&r->bg, "resolver-timeout %s\n", r->addr);
+  a_bgfail(&r->bg, "resolver-timeout", "%s", r->addr, A_END);
   r->func(r, ARES_FAIL);
   bres_abort(&r->r);
   xfree(r->addr);
@@ -725,7 +809,7 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
   r->func = func;
   if (mystrieq(av[i], "inet")) i++;
   if (ac - i != 2) {
-    a_fail(a, "bad-addr-syntax [inet] ADDRESS PORT");
+    a_fail(a, "bad-addr-syntax", "[inet] ADDRESS PORT", A_END);
     goto fail;
   }
   r->sa.sin.sin_family = AF_INET;
@@ -735,13 +819,13 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
   if (*p) {
     struct servent *s = getservbyname(av[i + 1], "udp");
     if (!s) {
-      a_fail(a, "unknown-service %s", av[i + 1]);
+      a_fail(a, "unknown-service", "%s", av[i + 1], A_END);
       goto fail;
     }
     pt = ntohs(s->s_port);
   }
   if (pt == 0 || pt >= 65536) {
-    a_fail(a, "invalid-port %lu", pt);
+    a_fail(a, "invalid-port", "%lu", pt, A_END);
     goto fail;
   }
   r->sa.sin.sin_port = htons(pt);
@@ -802,9 +886,9 @@ static void a_doadd(admin_resop *r, int rc)
     add->peer.sasz = add->r.sasz;
     add->peer.sa = add->r.sa;
     if (p_find(add->peer.name))
-      a_bgfail(&add->r.bg, "peer-exists %s", add->peer.name);
+      a_bgfail(&add->r.bg, "peer-exists", "%s", add->peer.name, A_END);
     else if (!p_create(&add->peer))
-      a_bgfail(&add->r.bg, "peer-create-fail %s", add->peer.name);
+      a_bgfail(&add->r.bg, "peer-create-fail", "%s", add->peer.name, A_END);
     else
       a_bgok(&add->r.bg);
   }
@@ -839,7 +923,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
   /* --- Make sure someone's not got there already --- */
 
   if (p_find(av[0])) {
-    a_fail(a, "peer-exists %s", av[0]);
+    a_fail(a, "peer-exists", "%s", av[0], A_END);
     goto fail;
   }
 
@@ -856,7 +940,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
       if (!av[++i]) goto bad_syntax;
       for (j = 0;; j++) {
        if (!tunnels[j]) {
-         a_fail(a, "unknown-tunnel %s", av[i]);
+         a_fail(a, "unknown-tunnel", "%s", av[i], A_END);
          goto fail;
        }
        if (mystrieq(av[i], tunnels[j]->name)) {
@@ -868,7 +952,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
       long t;
       if (!av[++i]) goto bad_syntax;
       if ((t = a_parsetime(av[i])) < 0) {
-       a_fail(a, "bad-time-spec %s", av[i]);
+       a_fail(a, "bad-time-spec", "%s", av[i], A_END);
        goto fail;
       }
       add->peer.t_ka = t;
@@ -888,7 +972,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
   /* --- Clearing up --- */
 
 bad_syntax:
-  a_fail(a, "bad-syntax -- add PEER [OPTIONS] ADDR ...");
+  a_fail(a, "bad-syntax", "add", "PEER [OPTIONS] ADDR ...", A_END);
 fail:
   xfree(add->peer.name);
   xfree(add);
@@ -934,15 +1018,15 @@ static void a_pong(int rc, void *v)
       gettimeofday(&tv, 0);
       tv_sub(&tv, &tv, &pg->pingtime);
       millis = (double)tv.tv_sec * 1000 + (double)tv.tv_usec/1000;
-      a_bginfo(&pg->bg, "ping-ok %.1f", millis);
+      a_bginfo(&pg->bg, "ping-ok", "%.1f", millis, A_END);
       a_bgok(&pg->bg);
       break;
     case PING_TIMEOUT:
-      a_bginfo(&pg->bg, "ping-timeout");
+      a_bginfo(&pg->bg, "ping-timeout", A_END);
       a_bgok(&pg->bg);
       break;
     case PING_PEERDIED:
-      a_bginfo(&pg->bg, "ping-peer-died");
+      a_bginfo(&pg->bg, "ping-peer-died", A_END);
       a_bgok(&pg->bg);
       break;
     default:
@@ -982,7 +1066,7 @@ static void a_ping(admin *a, unsigned ac, char *av[],
     } else if (mystrieq(av[i], "-timeout")) {
       if (!av[++i]) goto bad_syntax;
       if ((t = a_parsetime(av[i])) < 0) {
-       a_fail(a, "bad-time-spec %s", av[i]);
+       a_fail(a, "bad-time-spec", "%s", av[i], A_END);
        return;
       }
     } else if (mystrieq(av[i], "--")) {
@@ -1002,13 +1086,13 @@ static void a_ping(admin *a, unsigned ac, char *av[],
   T( trace(T_ADMIN, "admin: ping op %s: %s to %s",
           BGTAG(pg), cmd, p_name(p)); )
   if (p_pingsend(p, &pg->ping, msg, t, a_pong, pg)) {
-    a_bgfail(&pg->bg, "ping-send-failed");
+    a_bgfail(&pg->bg, "ping-send-failed", A_END);
     a_bgrelease(&pg->bg);
   }
   return;
     
 bad_syntax:
-  a_fail(a, "bad-syntax -- %s [OPTIONS] PEER", cmd);
+  a_fail(a, "bad-syntax", "%s", cmd, "[OPTIONS] PEER", cmd, A_END);
   return;
 }
 
@@ -1043,8 +1127,8 @@ static int traceish(admin *a, unsigned ac, char *av[],
   if (!ac || strcmp(av[0], "?") == 0) {
     const trace_opt *t;
     for (t = tt; t->ch; t++) {
-      a_info(a, "%c%c %s",
-            t->ch, (*ff & t->f) == t->f ? '+' : ' ', t->help);
+      a_info(a, "*%c%c %s",
+            t->ch, (*ff & t->f) == t->f ? '+' : ' ', t->help, A_END);
     }
   } else {
     unsigned sense = 1;
@@ -1064,7 +1148,7 @@ static int traceish(admin *a, unsigned ac, char *av[],
              goto tropt_ok;
            }
          }
-         a_fail(a, "bad-%s-option %c", what, *p);
+         a_fail(a, "bad-%s-option", what, "%c", *p, A_END);
          return (0);
         tropt_ok:;
          break;
@@ -1093,23 +1177,6 @@ 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[])
 {
@@ -1132,20 +1199,20 @@ static void acmd_warn(admin *a, unsigned ac, char *av[])
 
 static void acmd_port(admin *a, unsigned ac, char *av[])
 {
-  a_info(a, "%u", p_port());
+  a_info(a, "%u", p_port(), A_END);
   a_ok(a);
 }
 
 static void acmd_daemon(admin *a, unsigned ac, char *av[])
 {
   if (flags & F_DAEMON)
-    a_fail(a, "already-daemon");
+    a_fail(a, "already-daemon", A_END);
   else {
-    a_notify("DAEMON");
+    a_notify("DAEMON", A_END);
     if (a_stdin)
       a_destroy(a_stdin);
     if (u_daemon())
-      a_fail(a, "daemon-error -- %s", strerror(errno));
+      a_fail(a, "daemon-error", "?ERRNO", A_END);
     else {
       flags |= F_DAEMON;
       a_ok(a);
@@ -1157,7 +1224,7 @@ static void acmd_list(admin *a, unsigned ac, char *av[])
 {
   peer *p;
   for (p = p_first(); p; p = p_next(p))
-    a_info(a, "%s", p_name(p));
+    a_info(a, "%s", p_name(p), A_END);
   a_ok(a);
 }
 
@@ -1166,7 +1233,7 @@ static void acmd_ifname(admin *a, unsigned ac, char *av[])
   peer *p;
 
   if ((p = a_findpeer(a, av[0])) != 0) {
-    a_info(a, "%s", p_ifname(p));
+    a_info(a, "%s", p_ifname(p), A_END);
     a_ok(a);
   }
 }
@@ -1177,7 +1244,7 @@ static void acmd_getchal(admin *a, unsigned ac, char *av[])
 
   buf_init(&b, buf_i, PKBUFSZ);
   c_new(&b);
-  a_info(a, "%s", b64_encode(BBASE(&b), BLEN(&b)));
+  a_info(a, "?B64", BBASE(&b), (size_t)BLEN(&b), A_END);
   a_ok(a);
 }
 
@@ -1192,7 +1259,7 @@ static void acmd_checkchal(admin *a, unsigned ac, char *av[])
   base64_decode(&b64, 0, 0, &d);
   buf_init(&b, d.buf, d.len);
   if (c_check(&b) || BBAD(&b) || BLEFT(&b))
-    a_fail(a, "invalid-challenge");
+    a_fail(a, "invalid-challenge", A_END);
   else
     a_ok(a);
   dstr_destroy(&d);
@@ -1222,9 +1289,7 @@ static void acmd_addr(admin *a, unsigned ac, char *av[])
   if ((p = a_findpeer(a, av[0])) != 0) {
     ad = p_addr(p);
     assert(ad->sa.sa_family == AF_INET);
-    a_info(a, "INET %s %u",
-           inet_ntoa(ad->sin.sin_addr),
-           (unsigned)ntohs(ad->sin.sin_port));
+    a_info(a, "?ADDR", ad, A_END);
     a_ok(a);
   }
 }
@@ -1236,17 +1301,17 @@ static void acmd_peerinfo(admin *a, unsigned ac, char *av[])
 
   if ((p = a_findpeer(a, av[0])) != 0) {
     ps = p_spec(p);
-    a_info(a, "tunnel=%s", ps->tops->name);
-    a_info(a, "keepalive=%lu", ps->t_ka);
+    a_info(a, "tunnel=%s", ps->tops->name, A_END);
+    a_info(a, "keepalive=%lu", ps->t_ka, A_END);
     a_ok(a);
   }
 }
 
 static void acmd_servinfo(admin *a, unsigned ac, char *av[])
 {
-  a_info(a, "implementation=edgeware-tripe");
-  a_info(a, "version=%s", VERSION);
-  a_info(a, "daemon=%s", BOOL(flags & F_DAEMON));
+  a_info(a, "implementation=edgeware-tripe", A_END);
+  a_info(a, "version=%s", VERSION, A_END);
+  a_info(a, "daemon=%s", BOOL(flags & F_DAEMON), A_END);
   a_ok(a);
 }
 
@@ -1259,21 +1324,21 @@ static void acmd_stats(admin *a, unsigned ac, char *av[])
     return;
 
   st = p_stats(p);
-  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, "start-time=%s", timestr(st->t_start), A_END);
+  a_info(a, "last-packet-time=%s", timestr(st->t_last), A_END);
+  a_info(a, "last-keyexch-time=%s", timestr(st->t_kx), A_END);
+  a_info(a, "packets-in=%lu bytes-in=%lu", st->n_in, st->sz_in, A_END);
   a_info(a, "packets-out=%lu bytes-out=%lu",
-        st->n_out, st->sz_out);
+        st->n_out, st->sz_out, A_END);
   a_info(a, "keyexch-packets-in=%lu keyexch-bytes-in=%lu",
-        st->n_kxin, st->sz_kxin);
+        st->n_kxin, st->sz_kxin, A_END);
   a_info(a, "keyexch-packets-out=%lu keyexch-bytes-out=%lu",
-        st->n_kxout, st->sz_kxout);
+        st->n_kxout, st->sz_kxout, A_END);
   a_info(a, "ip-packets-in=%lu ip-bytes-in=%lu",
-        st->n_ipin, st->sz_ipin);
+        st->n_ipin, st->sz_ipin, A_END);
   a_info(a, "ip-packets-out=%lu ip-bytes-out=%lu",
-        st->n_ipout, st->sz_ipout);
-  a_info(a, "rejected-packets=%lu", st->n_reject);
+        st->n_ipout, st->sz_ipout, A_END);
+  a_info(a, "rejected-packets=%lu", st->n_reject, A_END);
   a_ok(a);
 }
 
@@ -1300,7 +1365,7 @@ static void acmd_reload(admin *a, unsigned ac, char *av[])
 
 static void acmd_quit(admin *a, unsigned ac, char *av[])
 {
-  a_warn("SERVER quit admin-request");
+  a_warn("SERVER", "quit", "admin-request", A_END);
   a_ok(a);
   a_unlock(a);
   a_quit();
@@ -1308,7 +1373,7 @@ static void acmd_quit(admin *a, unsigned ac, char *av[])
 
 static void acmd_version(admin *a, unsigned ac, char *av[])
 {
-  a_info(a, "%s %s", PACKAGE, VERSION);
+  a_info(a, "%s", PACKAGE, "%s", VERSION, A_END);
   a_ok(a);
 }
 
@@ -1316,7 +1381,7 @@ static void acmd_tunnels(admin *a, unsigned ac, char *av[])
 {
   int i;
   for (i = 0; tunnels[i]; i++)
-    a_info(a, "%s", tunnels[i]->name);
+    a_info(a, "%s", tunnels[i]->name, A_END);
   a_ok(a);
 }
 
@@ -1332,42 +1397,45 @@ typedef struct acmd {
 static void acmd_help(admin */*a*/, unsigned /*ac*/, char */*av*/[]);
 
 static const acmd acmdtab[] = {
-  { "add",     "add PEER [OPTIONS] ADDR ...",
-                                       2,      0xffff, acmd_add },
-  { "addr",    "addr PEER",            1,      1,      acmd_addr },
-  { "checkchal", "checkchal CHAL",     1,      1,      acmd_checkchal },
-  { "daemon",  "daemon",               0,      0,      acmd_daemon },
-  { "eping",   "eping [OPTIONS] PEER", 1,      0xffff, acmd_eping },
-  { "forcekx", "forcekx PEER",         1,      1,      acmd_forcekx },
-  { "getchal", "getchal",              0,      0,      acmd_getchal },
-  { "greet",   "greet PEER CHAL",      2,      2,      acmd_greet },
-  { "help",    "help",                 0,      0,      acmd_help },
-  { "ifname",  "ifname PEER",          1,      1,      acmd_ifname },
-  { "kill",    "kill PEER",            1,      1,      acmd_kill },
-  { "list",    "list",                 0,      0,      acmd_list },
-  { "notify",  "notify MESSAGE ...",   1,      0xffff, acmd_notify },
-  { "peerinfo",        "peerinfo PEER",        1,      1,      acmd_peerinfo },
-  { "ping",    "ping [OPTIONS] PEER",  1,      0xffff, acmd_ping },
-  { "port",    "port",                 0,      0,      acmd_port },
-  { "quit",    "quit",                 0,      0,      acmd_quit },
-  { "reload",  "reload",               0,      0,      acmd_reload },
-  { "servinfo",        "servinfo",             0,      0,      acmd_servinfo },
-  { "stats",   "stats PEER",           1,      1,      acmd_stats },
+  { "add",     "PEER [OPTIONS] ADDR ...", 2,   0xffff, acmd_add },
+  { "addr",    "PEER",                 1,      1,      acmd_addr },
+  { "checkchal", "CHAL",               1,      1,      acmd_checkchal },
+  { "daemon",  0,                      0,      0,      acmd_daemon },
+  { "eping",   "[OPTIONS] PEER",       1,      0xffff, acmd_eping },
+  { "forcekx", "PEER",                 1,      1,      acmd_forcekx },
+  { "getchal", 0,                      0,      0,      acmd_getchal },
+  { "greet",   "PEER CHAL",            2,      2,      acmd_greet },
+  { "help",    0,                      0,      0,      acmd_help },
+  { "ifname",  "PEER",                 1,      1,      acmd_ifname },
+  { "kill",    "PEER",                 1,      1,      acmd_kill },
+  { "list",    0,                      0,      0,      acmd_list },
+  { "notify",  "MESSAGE ...",          1,      0xffff, acmd_notify },
+  { "peerinfo",        "PEER",                 1,      1,      acmd_peerinfo },
+  { "ping",    "[OPTIONS] PEER",       1,      0xffff, acmd_ping },
+  { "port",    0,                      0,      0,      acmd_port },
+  { "quit",    0,                      0,      0,      acmd_quit },
+  { "reload",  0,                      0,      0,      acmd_reload },
+  { "servinfo",        0,                      0,      0,      acmd_servinfo },
+  { "stats",   "PEER",                 1,      1,      acmd_stats },
 #ifndef NTRACE
-  { "trace",   "trace [OPTIONS]",      0,      1,      acmd_trace },
+  { "trace",   "[OPTIONS]",            0,      1,      acmd_trace },
 #endif
-  { "tunnels", "tunnels",              0,      0,      acmd_tunnels },
-  { "version", "version",              0,      0,      acmd_version },
-  { "warn",    "warn MESSAGE ...",     1,      0xffff, acmd_warn },
-  { "watch",   "watch [OPTIONS]",      0,      1,      acmd_watch },
+  { "tunnels", 0,                      0,      0,      acmd_tunnels },
+  { "version", 0,                      0,      0,      acmd_version },
+  { "warn",    "MESSAGE ...",          1,      0xffff, acmd_warn },
+  { "watch",   "[OPTIONS]",            0,      1,      acmd_watch },
   { 0,         0,                      0,      0,      0 }
 };
 
 static void acmd_help(admin *a, unsigned ac, char *av[])
 {
   const acmd *c;
-  for (c = acmdtab; c->name; c++)
-    a_info(a, "%s", c->help);
+  for (c = acmdtab; c->name; c++) {
+    if (c->help)
+      a_info(a, "%s", c->name, "*%s", c->help, A_END);
+    else 
+      a_info(a, "%s", c->name, A_END);
+  }
   a_ok(a);
 }
 
@@ -1522,9 +1590,12 @@ static void a_line(char *p, size_t len, void *vp)
   for (c = acmdtab; c->name; c++) {
     if (mystrieq(av[0], c->name)) {
       ac--;
-      if (c->argmin > ac || ac > c->argmax)
-       a_fail(a, "bad-syntax -- %s", c->help);
-      else {
+      if (c->argmin > ac || ac > c->argmax) {
+       if (!c->help)
+         a_fail(a, "bad-syntax", "%s", c->name, "", A_END);
+       else 
+         a_fail(a, "bad-syntax", "%s", c->name, "%s", c->help, A_END);
+      } else {
        a_lock(a);
        c->func(a, ac, av + 1);
        a_unlock(a);
@@ -1532,7 +1603,7 @@ static void a_line(char *p, size_t len, void *vp)
       return;
     }
   }
-  a_fail(a, "unknown-command %s", av[0]);
+  a_fail(a, "unknown-command", "%s", av[0], A_END);
 }
 
 /* --- @a_create@ --- *
@@ -1587,7 +1658,7 @@ 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)
-      a_warn("ADMIN accept-error -- %s", strerror(errno));
+      a_warn("ADMIN", "accept-error", "?ERRNO", A_END);
     return;
   }
   a_create(nfd, nfd, 0);
diff --git a/chal.c b/chal.c
index a8cd4a4..5258cf9 100644 (file)
--- a/chal.c
+++ b/chal.c
@@ -109,12 +109,12 @@ int c_check(buf *b)
   int ok;
 
   if ((p = buf_get(b, sz)) == 0) {
-    a_warn("CHAL invalid-challenge");
+    a_warn("CHAL", "invalid-challenge", A_END);
     goto fail;
   }
   IF_TRACING(T_CHAL, trace_block(T_CRYPTO, "chal: check challenge", p, sz); )
   if (!mac) {
-    a_warn("CHAL impossible-challenge");
+    a_warn("CHAL", "impossible-challenge", A_END);
     goto fail;
   }
   h = GM_INIT(mac);
@@ -122,16 +122,12 @@ int c_check(buf *b)
   ok = (memcmp(GH_DONE(h, 0), p + 4, algs.tagsz) == 0);
   GH_DESTROY(h);
   if (!ok) {
-    a_warn("CHAL incorrect-tag");
+    a_warn("CHAL", "incorrect-tag", A_END);
     goto fail;
   }
   seq = LOAD32(p);
-  switch (seq_check(&iseq, LOAD32(p))) {
-    case SEQ_OK: break;
-    case SEQ_OLD: a_warn("CHAL replay old-sequence"); goto fail;
-    case SEQ_REPLAY: a_warn("CHAL replay duplicated-sequence"); goto fail;
-    default: abort();
-  }
+  if (seq_check(&iseq, LOAD32(p), "CHAL"))
+    goto fail;
   T( trace(T_CHAL, "chal: checked challenge %lu", (unsigned long)seq); )
   return (0);
 
index 4afa6a9..5d07d69 100644 (file)
@@ -554,11 +554,11 @@ The
 .B tripe
 server is already running as a daemon.
 .TP
-.BI "bad-addr-syntax \-\- " message
+.BI "bad-addr-syntax " message
 (For commands accepting socket addresses.)  The address couldn't be
 understood.
 .TP
-.BI "bad-syntax \-\- " message
+.BI "bad-syntax " cmd " " message
 (For any command.)  The command couldn't be understood: e.g., the number
 of arguments was wrong.
 .TP
@@ -584,7 +584,7 @@ An unknown trace option was requested.
 .BR WATCH .)
 An unknown watch option was requested.
 .TP
-.BI "daemon-error \-\- " message
+.BI "daemon-error " ecode " " message
 (For
 .BR DAEMON .)
 An error occurred during the attempt to become a daemon, as reported by
@@ -692,6 +692,22 @@ command.
 .SH "WARNINGS"
 There are many possible warnings.  They are categorized according to
 their first tokens.
+.PP
+Many of these warnings report system errors.  These are reported as a
+pair of tokens, described below as
+.I ecode
+and
+.IR message .
+The
+.I ecode
+is a string of the form
+.BI E number
+giving the
+.BR errno (3)
+value of the error; the
+.I message
+is the `human-readable' form of the message, as reported by
+.BR strerror (3).
 .SS "ABORT warnings"
 These all indicate that the
 .B tripe
@@ -704,11 +720,11 @@ 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
+.BI "ADMIN accept-error " ecode " " message
 There was an error while attempting to accept a connection from a new
 client.
 .TP
-.BI "ADMIN client-read-error \-\- " message
+.BI "ADMIN client-write-error " ecode " " message
 There was an error sending data to a client.  The connection to the
 client has been closed.
 .SS "CHAL warnings"
@@ -738,18 +754,18 @@ Challenge received was old, but maybe not actually a replay.  Try again.
 These indicate a problem with the keyring files, or the keys stored in
 them.
 .TP
-.BI "KEYMGMT bad-private-key \-\- " message
+.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
+.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
+.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).
@@ -763,7 +779,7 @@ 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
+.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"
@@ -905,10 +921,10 @@ Either there's a bug, or the bad guys are playing tricks on you.
 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
+.BI "PEER \- socket-read-error " ecode " " message
 An error occurred trying to read an incoming packet.
 .TP
-.BI "PEER " peer " socket-write-error \-\- " message
+.BI "PEER " peer " socket-write-error " ecode " " message
 An error occurred attempting to send a network packet.  We lost that
 one.
 .TP
@@ -952,7 +968,7 @@ A client of the administration interface issued a
 .B QUIT
 command.
 .TP
-.BI "SERVER select-error \-\- " message
+.BI "SERVER select-error " ecode " " 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"
@@ -980,15 +996,15 @@ create some more
 .BI /dev/tun nn
 files, it will work.
 .TP
-.BI "TUN - open-error " device " \-\- " message
+.BI "TUN - " tun-name " open-error " device " " ecode " " message
 An attempt to open the tunnel device file
 .I device
 failed.
 .TP
-.BI "TUN \- linux config-error \-\- " message
+.BI "TUN \- linux config-error " ecode " " message
 Configuring the Linux TUN/TAP interface failed.
 .TP
-.BI "TUN " ifname " read-error \-\- " message
+.BI "TUN " ifname " " tun-name " read-error " ecode " " message
 Reading from the tunnel device failed.
 .TP
 .BI "TUN " ifname " slip bad-escape"
@@ -1005,7 +1021,7 @@ The SLIP driver encountered an escaped `end' marker.  This probably
 means that someone's been sending it junk.  The erroneous packet is
 discarded, and we hope that we've rediscovered synchronization.
 .TP
-.BI "TUN \- slip fork-error \-\- " message
+.BI "TUN \- slip fork-error " ecode " " message
 The SLIP driver encountered an error forking a child process while
 allocating a new dynamic interface.
 .TP
@@ -1016,23 +1032,23 @@ or use dynamic SLIP interface allocation.
 .BI "TUN " ifname " slip overflow"
 The SLIP driver gave up reading a packet because it got too large.
 .TP
-.BI "TUN \- slip pipe-error \-\- " message
+.BI "TUN \- slip pipe-error " ecode " " message
 The SLIP driver encountered an error creating pipes while allocating a
 new dynamic interface.
 .TP
-.BI "TUN \- slip read-ifname-failed \-\- " message
+.BI "TUN \- slip read-ifname-failed " ecode " " message
 The SLIP driver encountered an error reading the name of a dynamically
 allocated interface.  Maybe the allocation script is broken.
 .TP
-.BI "TUN \- unet config-error \-\- " message
+.BI "TUN \- unet config-error " ecode " " message
 Configuring the Linux Unet interface failed.  Unet is obsolete and
 shouldn't be used any more.
 .TP
-.BI "TUN \- unet getinfo-error \-\- " message
+.BI "TUN \- unet getinfo-error " ecode " " 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
+.BI "TUN \- unet ifname-too-long"
 The Unet interface's name overflowed, so we couldn't read it properly.
 Unet is obsolete and shouldn't be used any more.
 .SS "USER warnings"
index e62809e..ea4748e 100644 (file)
--- a/keyexch.c
+++ b/keyexch.c
@@ -430,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) {
-    a_warn("KX %s bad-expected-reply-log", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "bad-expected-reply-log", A_END);
     IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
       trace(T_CRYPTO, "crypto: computed challenge = %s", gestr(gg, y));
     }))
@@ -464,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) {
-    a_warn("KX %s unexpected %s", p_name(kx->p), pkname[msg]);
+    a_warn("KX", "?PEER", kx->p, "unexpected", "%s", pkname[msg], A_END);
     goto bad;
   }
 
@@ -474,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)) {
-    a_warn("KX %s invalid %s", p_name(kx->p), pkname[msg]);
+    a_warn("KX", "?PEER", kx->p, "invalid", "%s", pkname[msg], A_END);
     goto bad;
   }
 
@@ -491,7 +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"); )
-    a_warn("KX %s sending-cookie", p_name(kx->p));
+    a_warn("KX", "?PEER", p_name, "sending-cookie", A_END);
     b = p_txstart(kx->p, MSG_KEYEXCH | KX_COOKIE);
     G_TOBUF(gg, b, kx->c);
     h = GH_INIT(algs.h);
@@ -506,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) {
-    a_warn("KX %s incorrect cookie", p_name(kx->p));
+    a_warn("KX", "?PEER", "incorrect", "cookie", A_END);
     goto bad;
   }
 
@@ -727,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) {
-    a_warn("KX %s incorrect cookie", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "incorrect", "cookie", A_END);
     goto bad;
   }
   if ((kxc = kxc_byhc(kx, hc_in)) == 0) {
-    a_warn("KX %s unknown-challenge", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "unknown-challenge", A_END);
     goto bad;
   }
 
@@ -739,7 +739,7 @@ static kxchal *matchreply(keyexch *kx, unsigned ty, const octet *hc_in,
 
   if (!kxc->r) {
     if (!ck) {
-      a_warn("KX %s unexpected switch-rq", p_name(kx->p));
+      a_warn("KX", "?PEER", kx->p, "unexpected", "switch-rq", A_END);
       goto bad;
     }
     if ((r = getreply(kx, kxc->c, ck)) == 0)
@@ -752,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)) {
-    a_warn("KX %s decrypt-failed reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "decrypt-failed", "reply", A_END);
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   r = G_CREATE(gg);
   if (G_FROMBUF(gg, b, r)) {
-    a_warn("KX %s invalid reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "invalid", "reply", A_END);
     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("KX %s incorrect reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "incorrect", "reply", A_END);
     goto bad;
   }
 
@@ -822,20 +822,20 @@ static int doreply(keyexch *kx, buf *b)
   kxchal *kxc;
 
   if (kx->s != KXS_CHAL && kx->s != KXS_COMMIT) {
-    a_warn("KX %s unexpected-reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "unexpected", "reply", A_END);
     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("KX %s invalid reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "invalid", "reply", A_END);
     goto bad;
   }
   if ((kxc = matchreply(kx, MSG_KEYEXCH | KX_REPLY,
                        hc_in, hc_out, ck, b)) == 0)
     goto bad;
   if (BLEFT(b)) {
-    a_warn("KX %s invalid reply", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "invalid", "reply", A_END);
     goto bad;
   }
   if (kx->s == KXS_CHAL) {
@@ -865,7 +865,7 @@ static void kxfinish(keyexch *kx)
   ks_activate(kxc->ks);
   settimer(kx, ks_tregen(kxc->ks));
   kx->s = KXS_SWITCH;
-  a_notify("KXDONE %s", p_name(kx->p));
+  a_notify("KXDONE", "?PEER", kx->p, A_END);
   p_stats(kx->p)->t_kx = time(0);
 }
 
@@ -886,21 +886,21 @@ static int doswitch(keyexch *kx, buf *b)
 
   if ((hc_in = buf_get(b, algs.hashsz)) == 0 ||
       (hc_out = buf_get(b, algs.hashsz)) == 0) {
-    a_warn("KX %s invalid switch-rq", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "invalid", "switch-rq", A_END);
     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("KX %s invalid switch-rq", p_name(kx->p));
+    a_warn("KX", "?PEER", "invalid", "switch-rq", A_END);
     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("KX %s incorrect switch-rq", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "incorrect", "switch-rq", A_END);
     goto bad;
   }
   switch (kx->s) {
@@ -934,18 +934,18 @@ static int doswitchok(keyexch *kx, buf *b)
   buf bb;
 
   if (kx->s < KXS_COMMIT) {
-    a_warn("KX %s unexpected switch-ok", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "unexpected", "switch-ok", A_END);
     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("KX %s decrypt-failed switch-ok", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "decrypt-failed", "switch-ok", A_END);
     goto bad;
   }
   buf_init(b, BBASE(&bb), BLEN(&bb));
   if ((hswok = buf_get(b, algs.hashsz)) == 0 || BLEFT(b)) {
-    a_warn("KX %s invalid switch-ok", p_name(kx->p));
+    a_warn("KX", "?PEER", "invalid", "switch-ok", A_END);
     goto bad;
   }
   IF_TRACING(T_KEYEXCH, {
@@ -953,7 +953,7 @@ static int doswitchok(keyexch *kx, buf *b)
                hswok, algs.hashsz);
   })
   if (memcmp(hswok, kxc->hswok_in, algs.hashsz) != 0) {
-    a_warn("KX %s incorrect switch-ok", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "incorrect", "switch-ok", A_END);
     goto bad;
   }
   if (kx->s < KXS_SWITCH)
@@ -1059,7 +1059,7 @@ static int checkpub(keyexch *kx)
   now = time(0);
   if (KEY_EXPIRED(now, kx->texp_kpub)) {
     stop(kx);
-    a_warn("KX %s public-key-expired", p_name(kx->p));
+    a_warn("KX", "?PEER", kx->p, "public-key-expired", A_END);
     G_COPY(gg, kx->kpub, gg->i);
     kx->f &= ~KXF_PUBKEY;
     return (-1);
@@ -1088,7 +1088,7 @@ void kx_start(keyexch *kx, int forcep)
   if (forcep || !VALIDP(kx, now)) {
     stop(kx);
     start(kx, now);
-    a_notify("KXSTART %s", p_name(kx->p));
+    a_notify("KXSTART", "?PEER", kx->p, A_END);
   }
   resend(kx);
 }
@@ -1139,7 +1139,7 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
       rc = doswitchok(kx, b);
       break;
     default:
-      a_warn("KX %s unknown-message 0x%02x", p_name(kx->p), msg);
+      a_warn("KX", "?PEER", kx->p, "unknown-message", "0x%02x", msg, A_END);
       rc = -1;
       break;
   }
index c7199e5..7163ddd 100644 (file)
--- a/keymgmt.c
+++ b/keymgmt.c
@@ -301,7 +301,13 @@ static int algs_samep(const algswitch *a, const algswitch *aa)
  */
 
 static void keymoan(const char *file, int line, const char *msg, void *p)
-  { a_warn("KEYMGMT key-file-error %s:%i -- %s", file, line, msg); }
+{
+  a_warn("KEYMGMT",
+        "key-file-error",
+        "%s:%i", file, line,
+        "%s", msg,
+        A_END);
+}
 
 /* --- @loadpriv@ --- *
  *
@@ -471,7 +477,7 @@ int km_reload(void)
     T( trace(T_KEYMGMT, "keymgmt: private keyring updated: reloading..."); )
     DRESET(&d);
     if (loadpriv(&d))
-      a_warn("KEYMGMT bad-private-key -- %s", d.buf);
+      a_warn("KEYMGMT", "bad-private-key", "%s", d.buf, A_END);
     else
       reload = 1;
   }
@@ -483,7 +489,7 @@ int km_reload(void)
     kf = kf_pub;
     DRESET(&d);
     if (loadpub(&d))
-      a_warn("KEYMGMT bad-public-keyring -- %s", d.buf);
+      a_warn("KEYMGMT", "bad-public-keyring", "%s", d.buf, A_END);
     else {
       reload = 1;
       key_close(kf);
@@ -558,7 +564,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)) {
-    a_warn("KEYMGMT public-key %s not-found", tag);
+    a_warn("KEYMGMT", "public-key", "%s", tag, "not-found", A_END);
     goto done;
   }
 
@@ -568,14 +574,17 @@ int km_getpubkey(const char *tag, ge *kpub, time_t *t_exp)
     if (strcmp((*ko)->ty, k->type) == 0)
       goto tymatch;
   }
-  a_warn("KEYMGMT public-key %s unknown-type %s", t.buf, k->type);
+  a_warn("KEYMGMT",
+        "public-key", "%s", t.buf,
+        "unknown-type", "%s", k->type,
+        A_END);
   goto done;
 tymatch:;
 
   /* --- Load the key --- */
 
   if ((e = (*ko)->loadpub(*kd, &g, &p, &t)) != 0) {
-    a_warn("KEYMGMT public-key %s bad -- %s", t.buf, e);
+    a_warn("KEYMGMT", "public-key", "%s", t.buf, "bad", "%s", e, A_END);
     goto done;
   }
 
@@ -586,25 +595,34 @@ tymatch:;
    */
 
   if (!group_samep(gg, g)) {
-    a_warn("KEYMGMT public-key %s incorrect-group", t.buf);
+    a_warn("KEYMGMT", "public-key", "%s", t.buf, "incorrect-group", A_END);
     goto done;
   }
 
   /* --- Check the public group element --- */
 
   if (group_check(gg, p)) {
-    a_warn("KEYMGMT public-key %s bad-public-group-element", t.buf);
+    a_warn("KEYMGMT",
+          "public-key", "%s", t.buf,
+          "bad-public-group-element",
+          A_END);
     goto done;
   }
 
   /* --- Check the algorithms --- */
 
   if ((e = algs_get(&a, kf_pub, k)) != 0) {
-    a_warn("KEYMGMT public-key %s bad-algorithm-selection %s", t.buf, e);
+    a_warn("KEYMGMT",
+          "public-key", "%s", t.buf,
+          "bad-algorithm-selection", e,
+          A_END);
     goto done;
   }
   if (!algs_samep(&a, &algs)) {
-    a_warn("KEYMGMT public-key %s algorithm-mismatch", t.buf);
+    a_warn("KEYMGMT",
+          "public-key", "%s", t.buf,
+          "algorithm-mismatch",
+          A_END);
     goto done;
   }
 
index 9b804ea..bb2397f 100644 (file)
--- a/keyset.c
+++ b/keyset.c
@@ -250,30 +250,6 @@ static int dodecrypt(keyset *ks, unsigned ty, buf *b, buf *bb, uint32 *seq)
   return (0);
 }
 
-/* --- @dosequence@ --- *
- *
- * Arguments:  @keyset *ks@ = pointer to a keyset
- *             @uint32 seq@ = a sequence number from a packet
- *
- * Returns:    Zero if the sequence number is OK, nonzero if it's not.
- *
- * Use:                Checks a sequence number.  The data in the keyset which keeps
- *             track of valid sequence numbers is updated if the sequence
- *             number given is good.  It's assumed that the sequence number
- *             has already been checked for authenticity.
- */
-
-static int dosequence(keyset *ks, uint32 seq)
-{
-  switch (seq_check(&ks->iseq, seq)) {
-    case SEQ_OK: break;
-    case SEQ_OLD: a_warn("SYMM replay old-sequence"); return (-1);
-    case SEQ_REPLAY: a_warn("SYMM replay duplicated-sequence"); return (-1);
-    default: abort();
-  }
-  return (0);
-}
-
 /*----- Operations on a single keyset -------------------------------------*/
 
 /* --- @ks_drop@ --- *
@@ -468,7 +444,7 @@ int ks_decrypt(keyset *ks, unsigned ty, buf *b, buf *bb)
   if (!KEYOK(ks, now) ||
       buf_ensure(bb, BLEN(b)) ||
       dodecrypt(ks, ty, b, bb, &seq) ||
-      dosequence(ks, seq))
+      seq_check(&ks->iseq, seq, "SYMM"))
     return (-1);
   return (0);
 }
@@ -612,7 +588,7 @@ int ksl_decrypt(keyset **ksroot, unsigned ty, buf *b, buf *bb)
                 ks->seq); )
        ks->f &= ~KSF_LISTEN;
       }
-      return (dosequence(ks, seq));
+      return (seq_check(&ks->iseq, seq, "SYMM"));
     }
   }
   T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
diff --git a/peer.c b/peer.c
index 6b746dd..50dec93 100644 (file)
--- a/peer.c
+++ b/peer.c
@@ -100,7 +100,7 @@ static void p_ponged(peer *p, unsigned msg, buf *b)
   if (buf_getu32(b, &id) ||
       (magic = buf_get(b, sizeof(pg->magic))) == 0 ||
       BLEFT(b)) {
-    a_warn("PEER %s malformed-%s", p->spec.name, p_pingtype(msg));
+    a_warn("PEER", "?PEER", p, "malformed-%s", p_pingtype(msg), A_END);
     return;
   }
 
@@ -108,13 +108,16 @@ static void p_ponged(peer *p, unsigned msg, buf *b)
     if (pg->id == id)
       goto found;
   }
-  a_warn("PEER %s unexpected-%s 0x%08lx",
-        p->spec.name, p_pingtype(msg), (unsigned long)id);
+  a_warn("PEER",
+        "?PEER", p,
+        "unexpected-%s", p_pingtype(msg),
+        "0x%08lx", (unsigned long)id,
+        A_END);
   return;
 
 found:
   if (memcmp(magic, pg->magic, sizeof(pg->magic)) != 0) {
-    a_warn("PEER %s corrupt-%s", p->spec.name, p_pingtype(msg));
+    a_warn("PEER", "?PEER", p, "corrupt-%s", p_pingtype(msg), A_END);
     return;
   }
   p_pingdone(pg, PING_OK);
@@ -146,7 +149,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) {
-    a_warn("PEER - socket-read-error -- %s", strerror(errno));
+    a_warn("PEER", "-", "socket-read-error", "?ERRNO", A_END);
     return;
   }
 
@@ -162,13 +165,13 @@ static void p_read(int fd, unsigned mode, void *v)
     buf_init(&b, buf_i, n);
     buf_getbyte(&b);
     if (c_check(&b) || BLEFT(&b)) {
-      a_warn("PEER - invalid-greeting");
+      a_warn("PEER", "-", "invalid-greeting", A_END);
       return;
     }
-    a_notify("GREET %s INET %s %u",
-            b64_encode(buf_i + 1, n - 1),
-            inet_ntoa(a.sin.sin_addr),
-            (unsigned)ntohs(a.sin.sin_port));
+    a_notify("GREET",
+            "?B64", buf_i + 1, (size_t)(n - 1),
+            "?ADDR", &a,
+            A_END);
     return;
   }
 
@@ -180,8 +183,7 @@ static void p_read(int fd, unsigned mode, void *v)
        p->spec.sa.sin.sin_port == a.sin.sin_port)
       goto found;
   }
-  a_warn("PEER - unexpected-source INET %s %u",
-        inet_ntoa(a.sin.sin_addr), (unsigned)ntohs(a.sin.sin_port));
+  a_warn("PEER", "-", "unexpected-source", "?ADDR", &a, A_END);
   return;
 
 found:
@@ -197,20 +199,24 @@ found:
   p->st.sz_in += n;
   buf_init(&b, buf_i, n);
   if ((ch = buf_getbyte(&b)) < 0) {
-    a_warn("PEER %s bad-packet no-type", p->spec.name);
+    a_warn("PEER", "?PEER", p, "bad-packet", "no-type", A_END);
     return;
   }
   switch (ch & MSG_CATMASK) {
     case MSG_PACKET:
       if (ch & MSG_TYPEMASK) {
-       a_warn("PEER %s bad-packet unknown-type 0x%02x", p->spec.name, ch);
+       a_warn("PEER",
+              "?PEER", p,
+              "bad-packet",
+              "unknown-type", "0x%02x", ch,
+              A_END);
        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("PEER %s decrypt-failed", p->spec.name);
+       a_warn("PEER", "?PEER", p, "decrypt-failed", A_END);
        return;
       }
       if (BOK(&bb)) {
@@ -219,7 +225,7 @@ found:
        p->t->ops->inject(p->t, &bb);
       } else {
        p->st.n_reject++;
-       a_warn("PEER %s packet-build-failed", p->spec.name);
+       a_warn("PEER", "?PEER", p, "packet-build-failed", A_END);
       }
       break;
     case MSG_KEYEXCH:
@@ -241,7 +247,7 @@ found:
          buf_init(&bb, buf_t, sizeof(buf_t));
          if (ksl_decrypt(&p->ks, ch, &b, &bb)) {
            p->st.n_reject++;
-           a_warn("PEER %s decrypt-failed", p->spec.name);
+           a_warn("PEER", "?PEER", "decrypt-failed", A_END);
            return;
          }
          if (BOK(&bb)) {
@@ -256,7 +262,7 @@ found:
          buf_init(&bb, buf_t, sizeof(buf_t));
          if (ksl_decrypt(&p->ks, ch, &b, &bb)) {
            p->st.n_reject++;
-           a_warn("PEER %s decrypt-failed", p->spec.name);
+           a_warn("PEER", "?PEER", p, "decrypt-failed", A_END);
            return;
          }
          if (BOK(&bb)) {
@@ -268,7 +274,11 @@ found:
       break;
     default:
       p->st.n_reject++;
-      a_warn("PEER %s bad-packet unknown-category 0x%02x", p->spec.name, ch);
+      a_warn("PEER",
+            "?PEER", p,
+            "bad-packet",
+            "unknown-category" "0x%02x", ch,
+            A_END);
       break;
   }
 }
@@ -305,15 +315,14 @@ static void p_setkatimer(peer *);
 static int p_dotxend(peer *p)
 {
   if (!BOK(&p->b)) {
-    a_warn("PEER %s packet-build-failed", p->spec.name);
+    a_warn("PEER", "?PEER", p, "packet-build-failed", A_END);
     return (0);
   }
   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->spec.sa.sa, p->spec.sasz) < 0) {
-    a_warn("PEER %s socket-write-error -- %s",
-          p->spec.name, strerror(errno));
+    a_warn("PEER", "?PEER", p, "socket-write-error", "?ERRNO", A_END);
     return (0);
   } else {
     p->st.n_out++;
@@ -686,19 +695,13 @@ peer *p_create(peerspec *spec)
   if (peers)
     peers->prev = p;
   peers = p;
-  switch (p->spec.sa.sa.sa_family) {
-    case AF_INET:
-      a_notify("ADD %s %s INET %s %u",
-              spec->name,
-              p->t->ops->ifname(p->t),
-              inet_ntoa(p->spec.sa.sin.sin_addr),
-              (unsigned)ntohs(p->spec.sa.sin.sin_port));
-      break;
-    default:
-      a_notify("ADD %s %s UNKNOWN", spec->name, p->t->ops->ifname(p->t));
-      break;
-  }
-  a_notify("KXSTART %s", spec->name);  /* Couldn't tell anyone before */
+  a_notify("ADD",
+           "?PEER", p,
+           "%s", p->t->ops->ifname(p->t),
+           "?ADDR", &p->spec.sa,
+           A_END);
+  a_notify("KXSTART", "?PEER", p, A_END);
+    /* Couldn't tell anyone before */
   return (p);
 
 tidy_1:
@@ -762,7 +765,7 @@ void p_destroy(peer *p)
   ping *pg, *ppg;
 
   T( trace(T_PEER, "peer: destroying peer `%s'", p->spec.name); )
-  a_notify("KILL %s", p->spec.name);
+  a_notify("KILL", "%s", p->spec.name, A_END);
   ksl_free(&p->ks);
   kx_free(&p->kx);
   p->t->ops->destroy(p->t);
index f4ab92e..92a5f77 100644 (file)
@@ -91,32 +91,6 @@ const char *timestr(time_t t)
   return ((const char *)buf_t);
 }
 
-/* --- @b64_encode@ --- *
- *
- * Arguments:  @const void *p@ = pointer to some gorp
- *             @size_t sz@ = size of the gorp
- *
- * Returns:    Pointer to base64-encoded version in @buf_t@.
- */
-
-const char *b64_encode(const void *p, size_t sz)
-{
-  base64_ctx b64;
-  dstr d = DSTR_INIT;
-
-  base64_init(&b64);
-  b64.indent = "";
-  b64.maxline = 0;
-  base64_encode(&b64, p, sz, &d);
-  base64_encode(&b64, 0, 0, &d);
-  while (d.len && d.buf[d.len - 1] == '=') d.len--;
-  assert(d.len < sizeof(buf_t));
-  memcpy(buf_t, d.buf, d.len);
-  buf_t[d.len] = 0;
-  dstr_destroy(&d);
-  return ((const char *)buf_t);
-}
-
 /* --- @seq_reset@ --- *
  *
  * Arguments:  @seqwin *s@ = sequence-checking window
@@ -132,20 +106,23 @@ void seq_reset(seqwin *s) { s->seq = 0; s->win = 0; }
  *
  * Arguments:  @seqwin *s@ = sequence-checking window
  *             @uint32 q@ = sequence number to check
+ *             @const char *service@ = service to report message from
  *
- * Returns:    A @SEQ_@ code.
+ * Returns:    Zero on success, nonzero if the sequence number was bad.
  *
  * Use:                Checks a sequence number against the window, updating things
  *             as necessary.
  */
 
-int seq_check(seqwin *s, uint32 q)
+int seq_check(seqwin *s, uint32 q, const char *service)
 {
   uint32 qbit;
   uint32 n;
 
-  if (q < s->seq)
-    return (SEQ_OLD);
+  if (q < s->seq) {
+    a_warn(service, "replay", "old-sequence", A_END);
+    return (-1);
+  }
   if (q >= s->seq + SEQ_WINSZ) {
     n = q - (s->seq + SEQ_WINSZ - 1);
     if (n < SEQ_WINSZ)
@@ -155,8 +132,10 @@ int seq_check(seqwin *s, uint32 q)
     s->seq += n;
   }
   qbit = 1 << (q - s->seq);
-  if (s->win & qbit)
-    return (SEQ_REPLAY);
+  if (s->win & qbit) {
+    a_warn(service, "replay", "duplicated-sequence", A_END);
+    return (-1);
+  }
   s->win |= qbit;
   return (0);
 }
diff --git a/tripe.c b/tripe.c
index 202a843..be37617 100644 (file)
--- a/tripe.c
+++ b/tripe.c
@@ -344,10 +344,10 @@ int main(int argc, char *argv[])
     if (!sel_select(&sel))
       selerr = 0;
     else if (errno != EINTR && errno != EAGAIN) {
-      a_warn("SERVER select-error -- %s", strerror(errno));
+      a_warn("SERVER", "select-error", "?ERRNO", A_END);
       selerr++;
       if (selerr > 8) {
-       a_warn("ABORT repeated-select-errors");
+       a_warn("ABORT", "repeated-select-errors", A_END);
        abort();
       }
     }
diff --git a/tripe.h b/tripe.h
index eec4093..25255f3 100644 (file)
--- a/tripe.h
+++ b/tripe.h
@@ -171,12 +171,6 @@ typedef struct seqwin {
 
 #define SEQ_WINSZ 32                   /* Bits in sequence number window */
 
-#define SEQ_RESET(iseq) { 
-
-#define SEQ_OK 0                       /* Sequence number valid */
-#define SEQ_OLD -1                     /* Sequence number too old */
-#define SEQ_REPLAY -2                  /* Definitely replayed */
-
 /* --- A symmetric keyset --- *
  *
  * A keyset contains a set of symmetric keys for encrypting and decrypting
@@ -747,6 +741,8 @@ extern int c_check(buf */*b*/);
 
 /*----- Administration interface ------------------------------------------*/
 
+#define A_END ((char *)0)
+
 /* --- @a_warn@ --- *
  *
  * Arguments:  @const char *fmt@ = pointer to format string
@@ -1098,16 +1094,6 @@ extern const char *timestr(time_t /*t*/);
 
 extern int mystrieq(const char */*x*/, const char */*y*/);
 
-/* --- @b64_encode@ --- *
- *
- * Arguments:  @const void *p@ = pointer to some gorp
- *             @size_t sz@ = size of the gorp
- *
- * Returns:    Pointer to base64-encoded version in @buf_t@.
- */
-
-extern const char *b64_encode(const void */*p*/, size_t /*sz*/);
-
 /* --- @seq_reset@ --- *
  *
  * Arguments:  @seqwin *s@ = sequence-checking window
@@ -1123,6 +1109,7 @@ extern void seq_reset(seqwin */*s*/);
  *
  * Arguments:  @seqwin *s@ = sequence-checking window
  *             @uint32 q@ = sequence number to check
+ *             @const char *service@ = service to report message from
  *
  * Returns:    A @SEQ_@ code.
  *
@@ -1130,7 +1117,7 @@ extern void seq_reset(seqwin */*s*/);
  *             as necessary.
  */
 
-extern int seq_check(seqwin */*s*/, uint32 /*q*/);
+extern int seq_check(seqwin */*s*/, uint32 /*q*/, const char */*service*/);
 
 /*----- That's all, folks -------------------------------------------------*/
 
index 22f01e6..4e8c0bd 100644 (file)
--- a/tun-bsd.c
+++ b/tun-bsd.c
@@ -76,7 +76,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN %s read-error -- %s", t_ifname(t), strerror(errno));
+    a_warn("TUN", "%s", t_ifname(t), "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -125,10 +125,10 @@ static tunnel *t_create(peer *p)
        T( trace(T_TUNNEL, "tunnel device %u busy: skipping", n); )
        break;
       case ENOENT:
-       a_warn("TUN - bsd no-tunnel-devices");
+       a_warn("TUN", "-", "bsd", "no-tunnel-devices", A_END);
        return (0);
       default:
-       a_warn("TUN - open-error %s -- %s", buf, strerror(errno));
+       a_warn("TUN", "-", "open-error", "%s", buf, "?ERRNO", A_END);
        break;
     }
     n++;
index bf44930..3cfa5d7 100644 (file)
@@ -68,7 +68,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN %s read-error -- %s", t->ifn, strerror(errno));
+    a_warn("TUN", "%s", t->ifn, "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -108,7 +108,9 @@ static tunnel *t_create(peer *p)
   tunnel *t;
 
   if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
-    a_warn("TUN - open-error /dev/net/tun -- %s", strerror(errno));
+    a_warn("TUN", "-", "linux",
+           "open-error", "/dev/net/tun", "?ERRNO",
+           A_END);
     return (0);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
@@ -116,7 +118,7 @@ static tunnel *t_create(peer *p)
   iff.ifr_name[0] = 0;
   iff.ifr_flags = IFF_TUN | IFF_NO_PI;
   if ((f = ioctl(fd, TUNSETIFF, &iff)) < 0) {
-    a_warn("TUN - linux config-error -- %s", strerror(errno));
+    a_warn("TUN", "-", "linux", "config-error", "?ERRNO", A_END);
     close(fd);
     return (0);
   }
index 2b74a77..2efda89 100644 (file)
@@ -100,11 +100,11 @@ static void t_read(int fd, unsigned mode, void *v)
 #endif
        errno == EAGAIN)
       return;
-    a_warn("TUN %s read-error -- %s", t->sl->name, strerror(errno));
+    a_warn("TUN", "%s", t->sl->name, "read-error", "?ERRNO", A_END);
     return;
   }
   if (!n) {
-    a_warn("TUN %s slip eof", t->sl->name);
+    a_warn("TUN", "%s", t->sl->name, "slip", "eof", A_END);
     t->st = ST_EOF;
     sel_rmfile(&t->f);
     return;
@@ -126,7 +126,7 @@ static void t_read(int fd, unsigned mode, void *v)
        if (st & ST_BAD)
          ;
        else if (st & ST_ESC)
-         a_warn("TUN %s slip escape-end", t->sl->name);
+         a_warn("TUN", "%s", t->sl->name, "slip", "escape-end", A_END);
        else if (q == t->buf) {
          T( trace(T_TUNNEL, "tun-slip: empty packet"); )
        } else {
@@ -143,7 +143,7 @@ static void t_read(int fd, unsigned mode, void *v)
        break;
       case SL_ESC:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
-         a_warn("TUN %s slip bad-escape", t->sl->name);
+         a_warn("TUN", "%s", t->sl->name, "slip", "bad-escape", A_END);
          st |= ST_BAD;
        } else
          st |= ST_ESC;
@@ -158,7 +158,7 @@ static void t_read(int fd, unsigned mode, void *v)
        goto emit;
       default:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
-         a_warn("TUN %s slip bad-escape", t->sl->name);
+         a_warn("TUN", "%s", t->sl->name, "slip", "bad-escape", A_END);
          st |= ST_BAD;
        }
       emit:
@@ -166,7 +166,7 @@ static void t_read(int fd, unsigned mode, void *v)
          if (q < ll)
            *q++ = o;
          else {
-           a_warn("TUN %s slip overflow", t->sl->name);
+           a_warn("TUN", "%s", t->sl->name, "slip", "overflow", A_END);
            st |= ST_BAD;
          }
        }
@@ -282,18 +282,18 @@ static tunnel *t_create(peer *p)
   /* --- If no dynamic interfaces are available, give up --- */
 
   if (!slipcmd) {
-    a_warn("TUN - slip no-slip-interfaces");
+    a_warn("TUN", "-", "slip", "no-slip-interfaces", A_END);
     goto fail;
   }
 
   /* --- Fork off a child process to create a dynamic SLIP interface --- */
 
   if (pipe(pin) || pipe(pout)) {
-    a_warn("TUN - slip pipe-error -- %s", strerror(errno));
+    a_warn("TUN", "-", "slip", "pipe-error", "?ERRNO", A_END);
     goto fail;
   }
   if ((kid = fork()) < 0) {
-    a_warn("TUN - slip fork-error -- %s", strerror(errno));
+    a_warn("TUN", "-", "slip", "fork-error", "?ERRNO", A_END);
     goto fail;
   }
   if (!kid) {
@@ -313,7 +313,7 @@ static tunnel *t_create(peer *p)
   for (;;) {
     errno = EIO;
     if (read(pout[0], &ch, 1) != 1 || ch == SL_END) {
-      a_warn("TUN - slip read-ifname-failed -- %s", strerror(errno));
+      a_warn("TUN", "-", "slip", "read-ifname-failed", "?ERRNO", A_END);
       goto fail;
     }
     if (ch == '\n')
index c93803e..c2b6e77 100644 (file)
@@ -60,11 +60,11 @@ static const char *t_ifname(tunnel *t)
   static char b[UNET_NAMEMAX];
   struct unet_info uni;
   if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
-    a_warn("TUN - unet getinfo-error -- %s", strerror(errno));
+    a_warn("TUN", "-", "unet", "getinfo-error", "?ERRNO", A_END);
     return ("<error>");
   }
   if (strlen(uni.uni_ifname) + 1 > sizeof(b)) {
-    a_warn("TUN - unet ifname-too-long");
+    a_warn("TUN", "-", "unet", "ifname-too-long", A_END);
     return ("<error>");
   }
   strcpy(b, uni.uni_ifname);
@@ -90,7 +90,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN %s read-error -- %s", t_ifname(t), strerror(errno));
+    a_warn("TUN", "%s", t_ifname(t), "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -130,13 +130,13 @@ static tunnel *t_create(peer *p)
   int f;
 
   if ((fd = open("/dev/unet", O_RDWR)) < 0) {
-    a_warn("TUN - open-error /dev/unet -- %s", strerror(errno));
+    a_warn("TUN", "-", "unet", "open-error", "/dev/unet", "?ERRNO", A_END);
     return (0);
   }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0 ||
       ioctl(fd, UNIOCSIFFLAGS, f | IFF_POINTOPOINT)) {
-    a_warn("TUN - unet config-error -- %s", strerror(errno));
+    a_warn("TUN", "-", "unet", "config-error", "?ERRNO", A_END);
     close(fd);
     return (0);
   }