/*----- 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
void a_quit(void)
{
+ peer *p;
+
+ while ((p = p_first()) != 0)
+ p_destroy(p);
close(sock.fd);
unlink(sockname);
exit(0);
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))
+ if (!p_create(a->pname, a->tops, &a->peer.sa, a->sasz))
a_fail(a, "peer-create-fail %s", a->pname);
else
a_ok(a);
{
unsigned long pt;
struct timeval tv;
- unsigned i;
+ unsigned i, j;
+ const tunnel_ops *tops = tun_default;
char *p;
/* --- Make sure someone's not got there already --- */
return;
}
+ /* --- Parse options --- */
+
+ i = 1;
+ for (;;) {
+ if (!av[i])
+ goto bad_syntax;
+ if (mystrieq(av[i], "-tunnel")) {
+ i++;
+ if (!av[i])
+ goto bad_syntax;
+ for (j = 0;; j++) {
+ if (!tunnels[j]) {
+ a_fail(a, "unknown-tunnel %s", av[i]);
+ return;
+ }
+ if (mystrieq(av[i], tunnels[j]->name)) {
+ tops = tunnels[j];
+ break;
+ }
+ }
+ i++;
+ } else if (mystrieq(av[i], "--")) {
+ i++;
+ break;
+ } else
+ break;
+ }
+
/* --- 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");
+ a_fail(a, "bad-syntax -- add PEER [-tunnel TUN] [inet] ADDRESS PORT");
return;
}
a->peer.sin.sin_family = AF_INET;
/* --- If the name is numeric, do it the easy way --- */
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], tops, &a->peer.sa, a->sasz))
a_fail(a, "peer-create-fail %s", a->pname);
else
a_ok(a);
a->pname = xstrdup(av[0]);
a->paddr = xstrdup(av[i]);
+ a->tops = tops;
selbuf_disable(&a->b);
gettimeofday(&tv, 0);
tv.tv_sec += T_RESOLVE;
bres_byname(&a->r, a->paddr, a_resolve, a);
T( trace(T_ADMIN, "admin: %u resolving hostname `%s'",
a->seq, a->paddr); )
+ return;
+
+bad_syntax:
+ a_fail(a, "bad-syntax -- add PEER [-tunnel TUN] ADDR ...");
+ return;
}
/*----- Administration commands -------------------------------------------*/
a_ok(a);
}
+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_ok(a);
+}
+
/* --- The command table and help --- */
typedef struct acmd {
{ "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 ...", 2, 0xffff, acmd_add },
+ { "add", "add PEER [-tunnel TUN] ADDR ...",
+ 2, 0xffff, acmd_add },
+ { "tunnels", "tunnels", 0, 0, acmd_tunnels },
{ "quit", "quit", 0, 0, acmd_quit },
{ 0, 0, 0, 0, 0 }
};