/* -*-c-*-
*
- * $Id: admin.c,v 1.3 2001/02/04 01:17:12 mdw Exp $
+ * $Id: admin.c,v 1.5 2001/02/16 21:22:51 mdw Exp $
*
* Admin interface for configuration
*
/*----- Revision history --------------------------------------------------*
*
* $Log: admin.c,v $
+ * Revision 1.5 2001/02/16 21:22:51 mdw
+ * Support for displaying statistics. Make client connections blocking, so
+ * that things don't get dropped. (This might change again if I add
+ * buffering.)
+ *
+ * Revision 1.4 2001/02/06 09:34:53 mdw
+ * Change ERR response to FAIL for consistency with other programs.
+ *
* Revision 1.3 2001/02/04 01:17:12 mdw
* The `DAEMON' notification to stdout is replaced by a warning. The
* `DAEMON' and `QUIT' command send `OK' on successful completion. Put
TIMER;
sel_rmtimer(&a->t);
if (!h)
- a_write(a, "ERR couldn't resolve hostname `%s'\n", a->paddr);
+ a_write(a, "FAIL couldn't resolve hostname `%s'\n", a->paddr);
else if (p_find(a->pname))
- a_write(a, "ERR peer `%s' already registered\n", a->pname);
+ a_write(a, "FAIL peer `%s' already registered\n", 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))
- a_write(a, "ERR couldn't create peer\n");
+ a_write(a, "FAIL couldn't create peer\n");
else
a_write(a, "OK\n");
}
admin *a = v;
T( trace(T_ADMIN, "admin: %u resolver timeout", a->seq); )
bres_abort(&a->r);
- a_write(a, "ERR timeout resolving `%s'\n", a->paddr);
+ a_write(a, "FAIL timeout resolving `%s'\n", a->paddr);
xfree(a->pname);
xfree(a->paddr);
a->pname = 0;
/* --- Make sure someone's not got there already --- */
if (p_find(av[0])) {
- a_write(a, "ERR peer `%s' already registered\n", av[0]);
+ a_write(a, "FAIL peer `%s' already registered\n", av[0]);
return;
}
if (*p) {
struct servent *s = getservbyname(av[2], "udp");
if (!s) {
- a_write(a, "ERR service `%s' not known\n", av[2]);
+ a_write(a, "FAIL service `%s' not known\n", av[2]);
return;
}
pt = ntohs(s->s_port);
}
if (pt == 0 || pt >= 65536) {
- a_write(a, "ERR bad port number %lu\n", pt);
+ a_write(a, "FAIL bad port number %lu\n", pt);
return;
}
a->peer.sin.sin_port = htons(pt);
if (inet_aton(av[1], &a->peer.sin.sin_addr)) {
if (!p_create(av[0], &a->peer.sa, a->sasz))
- a_write(a, "ERR couldn't create peer\n");
+ a_write(a, "FAIL couldn't create peer\n");
else
a_write(a, "OK\n");
return;
goto tropt_ok;
}
}
- a_write(a, "ERR unknown trace option `%c'\n", *p);
+ a_write(a, "FAIL unknown trace option `%c'\n", *p);
return;
tropt_ok:;
break;
static void acmd_daemon(admin *a, unsigned ac, char *av[])
{
if (flags & F_DAEMON)
- a_write(a, "ERR already running as a daemon\n");
+ a_write(a, "FAIL already running as a daemon\n");
else {
a_warn("becoming a daemon");
if (a_stdin)
a_destroy(a_stdin);
if (u_daemon())
- a_write(a, "ERR error becoming a daemon: %s", strerror(errno));
+ a_write(a, "FAIL error becoming a daemon: %s", strerror(errno));
else {
flags |= F_DAEMON;
a_write(a, "OK\n");
peer *p;
if ((p = p_find(av[0])) == 0)
- a_write(a, "ERR peer `%s' not found\n", av[0]);
+ a_write(a, "FAIL peer `%s' not found\n", av[0]);
else
a_write(a, "INFO %s\nOK\n", p_ifname(p));
}
const addr *ad;
if ((p = p_find(av[0])) == 0)
- a_write(a, "ERR peer `%s' not found\n", av[0]);
+ a_write(a, "FAIL peer `%s' not found\n", av[0]);
else {
ad = p_addr(p);
assert(ad->sa.sa_family == AF_INET);
}
}
+static void acmd_stats(admin *a, unsigned ac, char *av[])
+{
+ peer *p;
+ stats *st;
+
+ if ((p = p_find(av[0])) == 0)
+ a_write(a, "FAIL peer `%s' not found\n", av[0]);
+ 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",
+ st->n_out, st->sz_out);
+ a_write(a, "INFO keyexch-packets-in=%lu keyexch-bytes-in=%lu\n",
+ st->n_kxin, st->sz_kxin);
+ a_write(a, "INFO keyexch-packets-out=%lu keyexch-bytes-out=%lu\n",
+ st->n_kxout, st->sz_kxout);
+ a_write(a, "INFO ip-packets-in=%lu ip-bytes-in=%lu\n",
+ st->n_ipin, st->sz_ipin);
+ a_write(a, "INFO ip-packets-out=%lu ip-bytes-out=%lu\n",
+ st->n_ipout, st->sz_ipout);
+ a_write(a, "INFO rejected-packets=%lu\n", st->n_reject);
+ a_write(a, "OK\n");
+ }
+}
+
static void acmd_kill(admin *a, unsigned ac, char *av[])
{
peer *p;
if ((p = p_find(av[0])) == 0)
- a_write(a, "ERR peer `%s' not found\n", av[0]);
+ a_write(a, "FAIL peer `%s' not found\n", av[0]);
else {
p_destroy(p);
a_write(a, "OK\n");
{ "list", "LIST", 0, 0, acmd_list },
{ "ifname", "IFNAME peer", 1, 1, acmd_ifname },
{ "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 },
{ "quit", "QUIT", 0, 0, acmd_quit },
if (strcmp(av[0], c->name) == 0) {
ac--;
if (c->argmin > ac || ac > c->argmax)
- a_write(a, "ERR syntax: %s\n", c->help);
+ a_write(a, "FAIL syntax: %s\n", c->help);
else
c->func(a, ac, av + 1);
return;
}
}
- a_write(a, "ERR unknown command `%s'\n", av[0]);
+ a_write(a, "FAIL unknown command `%s'\n", av[0]);
}
/* --- @a_create@ --- *
a->pname = 0;
if (fd_in == STDIN_FILENO)
a_stdin = a;
- fdflags(fd_in, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+ fdflags(fd_in, O_NONBLOCK, 0, FD_CLOEXEC, FD_CLOEXEC);
if (fd_out != fd_in)
- fdflags(fd_out, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+ fdflags(fd_out, O_NONBLOCK, 0, FD_CLOEXEC, FD_CLOEXEC);
a->fd = fd_out;
selbuf_init(&a->b, &sel, fd_in, a_line, a);
a->next = admins;
}
if (!S_ISSOCK(st.st_mode))
die(EXIT_FAILURE, "object `%s' isn't a socket", sun.sun_path);
- T( trace(T_ADMIN, "stale socket found; removing it"); )
+ T( trace(T_ADMIN, "admin: stale socket found; removing it"); )
unlink(sun.sun_path);
close(fd);
goto again;