/*	$NetBSD: racoonctl.c,v 1.18 2010/11/12 09:08:26 tteras Exp $	*/

/*	Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */

/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 * Copyright (C) 2008 Timo Teras.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config.h"

#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/pfkeyv2.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#include <netdb.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <err.h>
#include <sys/ioctl.h> 
#include <resolv.h>

#include "var.h"
#include "vmbuf.h"
#include "misc.h"
#include "gcmalloc.h"

#include "racoonctl.h"
#include "admin.h"
#include "schedule.h"
#include "handler.h"
#include "sockmisc.h"
#include "vmbuf.h"
#include "plog.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "isakmp_xauth.h"
#include "isakmp_cfg.h"
#include "isakmp_unity.h"
#include "ipsec_doi.h"
#include "evt.h"

char *adminsock_path = ADMINSOCK_PATH;

static void usage __P((void));
static vchar_t *get_combuf __P((int, char **));
static int handle_recv __P((vchar_t *));
static vchar_t *f_reload __P((int, char **));
static vchar_t *f_getsched __P((int, char **));
static vchar_t *f_getsa __P((int, char **));
static vchar_t *f_getsacert __P((int, char **));
static vchar_t *f_flushsa __P((int, char **));
static vchar_t *f_deletesa __P((int, char **));
static vchar_t *f_exchangesa __P((int, char **));
static vchar_t *f_vpnc __P((int, char **));
static vchar_t *f_vpnd __P((int, char **));
static vchar_t *f_getevt __P((int, char **));
#ifdef ENABLE_HYBRID
static vchar_t *f_logoutusr __P((int, char **));
#endif

struct cmd_tag {
	vchar_t *(*func) __P((int, char **));
	char *str;
} cmdtab[] = {
	{ f_reload,	"reload-config" },
	{ f_reload,	"rc" },
	{ f_getsched,	"show-schedule" },
	{ f_getsched,	"sc" },
	{ f_getsa,	"show-sa" },
	{ f_getsa,	"ss" },
	{ f_getsacert,	"get-cert" },
	{ f_getsacert,	"gc" },
	{ f_flushsa,	"flush-sa" },
	{ f_flushsa,	"fs" },
	{ f_deletesa,	"delete-sa" },
	{ f_deletesa,	"ds" },
	{ f_exchangesa,	"establish-sa" },
	{ f_exchangesa,	"es" },
	{ f_vpnc,	"vpn-connect" },
	{ f_vpnc,	"vc" },
	{ f_vpnd,	"vpn-disconnect" },
	{ f_vpnd,	"vd" },
	{ f_getevt,	"show-event" },
	{ f_getevt,	"se" },
#ifdef ENABLE_HYBRID
	{ f_logoutusr,	"logout-user" },
	{ f_logoutusr,	"lu" },
#endif
	{ NULL, NULL },
};

struct evtmsg {
	int type;
	char *msg;
} evtmsg[] = {
	{ EVT_RACOON_QUIT,		"Racoon terminated" },

	{ EVT_PHASE1_UP,		"Phase 1 established" },
	{ EVT_PHASE1_DOWN,		"Phase 1 deleted" },
	{ EVT_PHASE1_NO_RESPONSE,	"Phase 1 error: peer not responding" },
	{ EVT_PHASE1_NO_PROPOSAL,	"Phase 1 error: no proposal chosen" },
	{ EVT_PHASE1_AUTH_FAILED,
	  "Phase 1 error: authentication failed (bad certificate?)" },
	{ EVT_PHASE1_DPD_TIMEOUT,	"Phase 1 error: dead peer detected" },
	{ EVT_PHASE1_MODE_CFG,		"Phase 1 mode configuration done" },
	{ EVT_PHASE1_XAUTH_SUCCESS,	"Phase 1 Xauth succeeded" },
	{ EVT_PHASE1_XAUTH_FAILED,	"Phase 1 Xauth failed" },

	{ EVT_PHASE2_NO_PHASE1,		"Phase 2 error: no suitable phase 1" },
	{ EVT_PHASE2_UP,		"Phase 2 established" },
	{ EVT_PHASE2_DOWN,		"Phase 2 deleted" },
	{ EVT_PHASE2_NO_RESPONSE,	"Phase 2 error: no response" },
};

static vchar_t *get_proto_and_index __P((int, char **, u_int16_t *));
static int get_proto __P((char *));
static vchar_t *get_index __P((int, char **));
static int get_family __P((char *));
static vchar_t *get_comindexes __P((int, int, char **));
static int get_comindex __P((char *, char **, char **, char **));
static int get_ulproto __P((char *));

struct proto_tag {
	int proto;
	char *str;
} prototab[] = {
	{ ADMIN_PROTO_ISAKMP,	"isakmp" },
	{ ADMIN_PROTO_IPSEC,	"ipsec" },
	{ ADMIN_PROTO_AH,	"ah" },
	{ ADMIN_PROTO_ESP,	"esp" },
	{ ADMIN_PROTO_INTERNAL,	"internal" },
	{ 0, NULL },
};

struct ulproto_tag {
	int ul_proto;
	char *str;
} ulprototab[] = {
	{ 0,		"any" },
	{ IPPROTO_ICMP,	"icmp" },
	{ IPPROTO_TCP,	"tcp" },
	{ IPPROTO_UDP,	"udp" },
	{ IPPROTO_GRE,	"gre" },
	{ 0, NULL },
};

int so;

static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST];

char *pname;
int long_format = 0;
int evt_quit_event = 0;

void dump_isakmp_sa __P((char *, int));
void dump_internal __P((char *, int));
char *pindex_isakmp __P((isakmp_index *));
void print_schedule __P((caddr_t, int));
void print_evt __P((struct evt_async *));
char * fixed_addr __P((char *, char *, int));

static void
usage()
{
	printf(
"Usage:\n"
"  %s [opts] reload-config\n"
"  %s [opts] show-schedule\n"
"  %s [opts] show-sa [protocol]\n"
"  %s [opts] flush-sa [protocol]\n"
"  %s [opts] delete-sa <saopts>\n"
"  %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] <saopts>\n"
"  %s [opts] vpn-connect [-u identity] vpn_gateway\n"
"  %s [opts] vpn-disconnect vpn_gateway\n"
"  %s [opts] show-event\n"
"  %s [opts] logout-user login\n"
"\n"
"General options:\n"
"  -d		Debug: hexdump admin messages before sending\n"
"  -l		Increase output verbosity (mainly for show-sa)\n"
"  -s <socket>	Specify adminport socket to use (default: %s)\n"
"\n"
"Parameter specifications:\n"
"    <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
"        In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
"\n"
"    <saopts>: \"isakmp\" <family> <src> <dst>\n"
"            : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
"                              <ul_proto>\n"
"    <family>: \"inet\" or \"inet6\"\n"
"    <ul_proto>: \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n"
"\n",
		pname, pname, pname, pname, pname, pname, pname, pname, pname, pname,
		ADMINSOCK_PATH);
}

/*
 * Check for proper racoonctl interface
 */
#if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
#error	"Incompatible racoonctl interface"
#endif

int
main(ac, av)
	int ac;
	char **av;
{
	vchar_t *combuf;
	int c;

	pname = *av;

	/*
	 * Check for proper racoonctl interface
	 */
	if ((racoonctl_interface_major != RACOONCTL_INTERFACE_MAJOR) ||
	    (racoonctl_interface < RACOONCTL_INTERFACE))
		errx(1, "Incompatible racoonctl interface");

#ifdef __linux__
	/*
	 * Disable GNU extensions that will prevent racoonct vc -u login
	 * from working (GNU getopt(3) does not like options after vc)
	 */
	setenv("POSIXLY_CORRECT", "1", 0);
#endif
	while ((c = getopt(ac, av, "lds:")) != -1) {
		switch(c) {
		case 'l':
			long_format++;
			break;

		case 'd':
			loglevel++;
			break;

		case 's':
			adminsock_path = optarg;
			break;

		default:
			usage();
			exit(0);
		}
	}

	ac -= optind;
	av += optind;

	combuf = get_combuf(ac, av);
	if (!combuf)
		err(1, "kmpstat");

	if (loglevel)
		racoon_hexdump(combuf, ((struct admin_com *)combuf)->ac_len);

	com_init();

	if (com_send(combuf) != 0)
		goto bad;

	vfree(combuf);

	do {
		if (com_recv(&combuf) != 0)
			goto bad;
		if (handle_recv(combuf) != 0)
			goto bad;
		vfree(combuf);
	} while (evt_quit_event != 0);

	close(so);
	exit(0);

bad:
	close(so);
	if (errno == EEXIST)
		exit(0);
	exit(1);
}

/* %%% */
/*
 * return command buffer.
 */
static vchar_t *
get_combuf(ac, av)
	int ac;
	char **av;
{
	struct cmd_tag *cp;

	if (ac == 0) {
		usage();
		exit(0);
	}

	/* checking the string of command. */
	for (cp = &cmdtab[0]; cp->str; cp++) {
		if (strcmp(*av, cp->str) == 0) {
			break;
		}
	}
	if (!cp->str) {
		printf("Invalid command [%s]\n", *av);
		errno = EINVAL;
		return NULL;
	}

	ac--;
	av++;
	return (cp->func)(ac, av);
}

static vchar_t *
make_request(u_int16_t cmd, u_int16_t proto, size_t len)
{
	vchar_t *buf;
	struct admin_com *head;

	buf = vmalloc(sizeof(struct admin_com) + len);
	if (buf == NULL)
		errx(1, "not enough core");

	head = (struct admin_com *) buf->v;
	head->ac_len = buf->l;
	head->ac_cmd = ADMIN_FLAG_VERSION | cmd;
	head->ac_version = 1;
	head->ac_proto = proto;

	return buf;
}

static vchar_t *
f_reload(ac, av)
	int ac;
	char **av;
{
	return make_request(ADMIN_RELOAD_CONF, 0, 0);
}

static vchar_t *
f_getevt(ac, av)
	int ac;
	char **av;
{
	evt_quit_event = -1;
	if (ac >= 1)
		errx(1, "too many arguments");

	return make_request(ADMIN_SHOW_EVT, 0, 0);
}

static vchar_t *
f_getsched(ac, av)
	int ac;
	char **av;
{
	return make_request(ADMIN_SHOW_SCHED, 0, 0);
}

static vchar_t *
f_getsa(ac, av)
	int ac;
	char **av;
{
	int proto;

	/* need protocol */
	if (ac != 1)
		errx(1, "insufficient arguments");
	proto = get_proto(*av);
	if (proto == -1)
		errx(1, "unknown protocol %s", *av);

	return make_request(ADMIN_SHOW_SA, proto, 0);
}

static vchar_t *
f_getsacert(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf, *index;
	struct admin_com_indexes *com;

	index = get_index(ac, av);
	if (index == NULL)
		return NULL;

	com = (struct admin_com_indexes *) index->v;
	buf = make_request(ADMIN_GET_SA_CERT, ADMIN_PROTO_ISAKMP, index->l);
	if (buf == NULL)
		errx(1, "Cannot allocate buffer");

	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);

	vfree(index);

	return buf;
}

static vchar_t *
f_flushsa(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf;
	struct admin_com *head;
	int proto;

	/* need protocol */
	if (ac != 1)
		errx(1, "insufficient arguments");
	proto = get_proto(*av);
	if (proto == -1)
		errx(1, "unknown protocol %s", *av);

	return make_request(ADMIN_FLUSH_SA, proto, 0);
}

static vchar_t *
f_deletesa(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf, *index;
	int proto;

	/* need protocol */
	if (ac < 1)
		errx(1, "insufficient arguments");
	proto = get_proto(*av);
	if (proto == -1)
		errx(1, "unknown protocol %s", *av);

	/* get index(es) */
	av++;
	ac--;
	switch (proto) {
	case ADMIN_PROTO_ISAKMP:
		index = get_index(ac, av);
		if (index == NULL)
			return NULL;
		break;
	case ADMIN_PROTO_AH:
	case ADMIN_PROTO_ESP:
		index = get_index(ac, av);
		if (index == NULL)
			return NULL;
		break;
	default:
		errno = EPROTONOSUPPORT;
		return NULL;
	}

	buf = make_request(ADMIN_DELETE_SA, proto, index->l);
	if (buf == NULL)
		goto out;

	memcpy(buf->v + sizeof(struct admin_com), index->v, index->l);

out:
	if (index != NULL)
		vfree(index);

	return buf;
}

static vchar_t *
f_deleteallsadst(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf, *index;
	u_int16_t proto;

	index = get_proto_and_index(ac, av, &proto);
	if (index == NULL)
		return NULL;

	buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l);
	if (buf == NULL)
		goto out;

	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);

out:
	if (index != NULL)
		vfree(index);

	return buf;
}

static vchar_t *
f_exchangesa(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf, *index;
	u_int16_t proto;
	int cmd = ADMIN_ESTABLISH_SA;
	size_t com_len = 0;
	char *id = NULL;
	char *key = NULL;
	char *remoteconf = NULL;
	struct admin_com_psk *acp;
	int wait = 0;

	if (ac < 1)
		errx(1, "insufficient arguments");

	/* Optional -u identity */
	if (strcmp(av[0], "-u") == 0) {
		if (ac < 2)
			errx(1, "-u require an argument");

		id = av[1];
		if ((key = getpass("Password: ")) == NULL)
			errx(1, "getpass() failed: %s", strerror(errno));
		
		com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1;
		cmd = ADMIN_ESTABLISH_SA_PSK;

		av += 2;
		ac -= 2;
	}

	if (ac >= 2 && strcmp(av[0], "-n") == 0) {
		/* Remoteconf name */
		remoteconf = av[1];
		av += 2;
		ac -= 2;
	}

	if (ac >= 1 && strcmp(av[0], "-w") == 0) {
		wait = 1;
		av++;
		ac--;
	}

	index = get_proto_and_index(ac, av, &proto);
	if (index == NULL)
		return NULL;

	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
	    remoteconf != NULL)
		com_len += strlen(remoteconf) + 1;

	if (wait) {
		switch (proto) {
		case ADMIN_PROTO_ISAKMP:
			evt_quit_event = EVT_PHASE1_MODE_CFG;
			break;
		case ADMIN_PROTO_AH:
		case ADMIN_PROTO_ESP:
			evt_quit_event = EVT_PHASE2_UP;
			break;
		default:
			errno = EPROTONOSUPPORT;
			return NULL;
		}
	}

	com_len += index->l;
	buf = make_request(cmd, proto, com_len);
	if (buf == NULL)
		errx(1, "Cannot allocate buffer");

	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);

	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
	    remoteconf != NULL) {
		strcpy(buf->v + sizeof(struct admin_com) + index->l,
		       remoteconf);
	} else if (id && key) {
		char *data;
		acp = (struct admin_com_psk *)
		    (buf->v + sizeof(struct admin_com) + index->l);

		acp->id_type = IDTYPE_USERFQDN;
		acp->id_len = strlen(id) + 1;
		acp->key_len = strlen(key) + 1;

		data = (char *)(acp + 1);
		strcpy(data, id);

		data = (char *)(data + acp->id_len);
		strcpy(data, key);
	}

	vfree(index);

	return buf;
}

static vchar_t *
f_vpnc(ac, av)
	int ac;
	char **av;
{
	char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL};
	int nac = 0;
	char *isakmp = "isakmp";
	char *inet = "inet";
	char *srcaddr;
	struct addrinfo hints, *res;
	struct sockaddr *src;
	char *idx;

	if (ac < 1)
		errx(1, "insufficient arguments");

	evt_quit_event = EVT_PHASE1_MODE_CFG;
	
	/* Optional -u identity */
	if (strcmp(av[0], "-u") == 0) {
		if (ac < 2)
			errx(1, "-u require an argument");

		nav[nac++] = av[0];
		nav[nac++] = av[1];

		ac -= 2;
		av += 2;
	}

	if (ac < 1)
		errx(1, "VPN gateway required");
	if (ac > 1)
		warnx("Extra arguments");

	/*
	 * Find the source address
	 */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	if (getaddrinfo(av[0], "4500", &hints, &res) != 0)
		errx(1, "Cannot resolve destination address");

	if ((src = getlocaladdr(res->ai_addr)) == NULL)
		errx(1, "cannot find source address");

	if ((srcaddr = saddr2str(src)) == NULL)
		errx(1, "cannot read source address");

	/* We get "ip[port]" strip the port */
	if ((idx = index(srcaddr, '[')) == NULL) 
		errx(1, "unexpected source address format");
	*idx = '\0';

	nav[nac++] = isakmp;
	nav[nac++] = inet;
	nav[nac++] = srcaddr;
	nav[nac++] = av[0];

	return f_exchangesa(nac, nav);
}

static vchar_t *
f_vpnd(ac, av)
	int ac;
	char **av;
{
	char *nav[] = {NULL, NULL, NULL, NULL};
	int nac = 0;
	char *isakmp = "isakmp";
	char *inet = "inet";
	char *anyaddr = "0.0.0.0";
	char *idx;

	if (ac < 1)
		errx(1, "VPN gateway required");
	if (ac > 1)
		warnx("Extra arguments");

	evt_quit_event = EVT_PHASE1_DOWN;

	nav[nac++] = isakmp;
	nav[nac++] = inet;
	nav[nac++] = anyaddr;
	nav[nac++] = av[0];

	return f_deleteallsadst(nac, nav);
}

#ifdef ENABLE_HYBRID
static vchar_t *
f_logoutusr(ac, av)
	int ac;
	char **av;
{
	vchar_t *buf;
	char *user;
	size_t userlen;

	/* need username */
	if (ac < 1)
		errx(1, "insufficient arguments");
	user = av[0];
	userlen = strlen(user);
	if ((user == NULL) || (userlen > LOGINLEN))
		errx(1, "bad login (too long?)");

	buf = make_request(ADMIN_LOGOUT_USER, 0, userlen);
	if (buf == NULL)
		return NULL;

	strncpy(buf->v + sizeof(struct admin_com), user, userlen);

	return buf;
}
#endif /* ENABLE_HYBRID */

static vchar_t *
get_proto_and_index(ac, av, proto)
	int ac;
	char **av;
	u_int16_t *proto;
{
	vchar_t *index = NULL;

	/* need protocol */
	if (ac < 1)
		errx(1, "insufficient arguments");
	*proto = get_proto(*av);
	if (*proto == (u_int16_t) -1)
		errx(1, "unknown protocol %s", *av);

	/* get index(es) */
	av++;
	ac--;
	switch (*proto) {
	case ADMIN_PROTO_ISAKMP:
	case ADMIN_PROTO_AH:
	case ADMIN_PROTO_ESP:
		index = get_index(ac, av);
		break;
	default:
		errno = EPROTONOSUPPORT;
		break;
	}
	return index;
}

static int
get_proto(str)
	char *str;
{
	struct proto_tag *cp;

	if (str == NULL) {
		errno = EINVAL;
		return -1;
	}

	/* checking the string of command. */
	for (cp = &prototab[0]; cp->str; cp++) {
		if (strcmp(str, cp->str) == 0)
			return cp->proto;
	}

	errno = EINVAL;
	return -1;
}

static vchar_t *
get_index(ac, av)
	int ac;
	char **av;
{
	int family;

	if (ac != 3 && ac != 4) {
		errno = EINVAL;
		return NULL;
	}

	/* checking the string of family */
	family = get_family(*av);
	if (family == -1)
		return NULL;
	av++;
	ac--;

	return get_comindexes(family, ac, av);
}

static int
get_family(str)
	char *str;
{
	if (strcmp("inet", str) == 0)
		return AF_INET;
#ifdef INET6
	else if (strcmp("inet6", str) == 0)
		return AF_INET6;
#endif
	errno = EAFNOSUPPORT;
	return -1;
}

static vchar_t *
get_comindexes(family, ac, av)
	int family;
	int ac;
	char **av;
{
	vchar_t *buf;
	struct admin_com_indexes *ci;
	char *p_name = NULL, *p_port = NULL;
	char *p_prefs = NULL, *p_prefd = NULL;
	struct sockaddr *src = NULL, *dst = NULL;
	int ulproto;

	if (ac != 2 && ac != 3) {
		errno = EINVAL;
		return NULL;
	}

	if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1)
		goto bad;
	src = get_sockaddr(family, p_name, p_port);
	if (p_name) {
		racoon_free(p_name);
		p_name = NULL;
	}
	if (p_port) {
		racoon_free(p_port);
		p_port = NULL;
	}
	if (src == NULL)
		goto bad;
	av++;
	ac--;
	if (get_comindex(*av, &p_name, &p_port, &p_prefd) == -1)
		goto bad;
	dst = get_sockaddr(family, p_name, p_port);
	if (p_name) {
		racoon_free(p_name);
		p_name = NULL;
	}
	if (p_port) {
		racoon_free(p_port);
		p_port = NULL;
	}
	if (dst == NULL)
		goto bad;

	buf = vmalloc(sizeof(*ci));
	if (buf == NULL)
		goto bad;

	av++;
	ac--;
	if(ac){
		ulproto = get_ulproto(*av);
		if (ulproto == -1)
			goto bad;
	}else
		ulproto=0;

	ci = (struct admin_com_indexes *)buf->v;
	if(p_prefs)
		ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */
	else
		ci->prefs = 32;
	if(p_prefd)
		ci->prefd = (u_int8_t)atoi(p_prefd); /* XXX should be handled error. */
	else
		ci->prefd = 32;
	ci->ul_proto = ulproto;
	memcpy(&ci->src, src, sysdep_sa_len(src));
	memcpy(&ci->dst, dst, sysdep_sa_len(dst));

	if (p_name)
		racoon_free(p_name);

	return buf;

   bad:
	if (p_name)
		racoon_free(p_name);
	if (p_port)
		racoon_free(p_port);
	if (p_prefs)
		racoon_free(p_prefs);
	if (p_prefd)
		racoon_free(p_prefd);
	return NULL;
}

static int
get_comindex(str, name, port, pref)
	char *str, **name, **port, **pref;
{
	char *p;

	*name = *port = *pref = NULL;

	*name = racoon_strdup(str);
	STRDUP_FATAL(*name);
	p = strpbrk(*name, "/[");
	if (p != NULL) {
		if (*(p + 1) == '\0')
			goto bad;
		if (*p == '/') {
			*p = '\0';
			*pref = racoon_strdup(p + 1);
			STRDUP_FATAL(*pref);
			p = strchr(*pref, '[');
			if (p != NULL) {
				if (*(p + 1) == '\0')
					goto bad;
				*p = '\0';
				*port = racoon_strdup(p + 1);
				STRDUP_FATAL(*port);
				p = strchr(*pref, ']');
				if (p == NULL)
					goto bad;
				*p = '\0';
			}
		} else if (*p == '[') {
			if (*pref == NULL)
				goto bad;
			*p = '\0';
			*port = racoon_strdup(p + 1);
			STRDUP_FATAL(*port);
			p = strchr(*pref, ']');
			if (p == NULL)
				goto bad;
			*p = '\0';
		} else {
			/* XXX */
		}
	}

	return 0;

    bad:

	if (*name)
		racoon_free(*name);
	if (*port)
		racoon_free(*port);
	if (*pref)
		racoon_free(*pref);
	*name = *port = *pref = NULL;
	return -1;
}

static int
get_ulproto(str)
	char *str;
{
	struct ulproto_tag *cp;

	if(str == NULL){
		errno = EINVAL;
		return -1;
	}

	/* checking the string of upper layer protocol. */
	for (cp = &ulprototab[0]; cp->str; cp++) {
		if (strcmp(str, cp->str) == 0)
			return cp->ul_proto;
	}

	errno = EINVAL;
	return -1;
}

/* %%% */
void
dump_isakmp_sa(buf, len)
	char *buf;
	int len;
{
	struct ph1dump *pd;
	struct tm *tm;
	char tbuf[56];
	caddr_t p = NULL;

/* isakmp status header */
/* short header;
 1234567890123456789012 0000000000000000:0000000000000000 000000000000
*/
char *header1 = 
"Destination            Cookies                           Created";

/* semi long header;
 1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
*/
char *header2 = 
"Destination            Cookies                           ST S  V E Created             Phase2";

/* long header;
 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
*/
char *header3 =
"Source                                        Destination                                   Cookies                           ST S  V E Created             Phase2";

/* phase status header */
/* short format;
   side stats source address         destination address   
   xxx  xxxxx 1234567890123456789012 1234567890123456789012
*/

	static char *estr[] = { "", "B", "M", "U", "A", "I", };

	switch (long_format) {
	case 0:
		printf("%s\n", header1);
		break;
	case 1:
		printf("%s\n", header2);
		break;
	case 2:
	default:
		printf("%s\n", header3);
		break;
	}

	if (len % sizeof(*pd))
		printf("invalid length %d\n", len);
	len /= sizeof(*pd);

	pd = (struct ph1dump *)buf;

	while (len-- > 0) {
		/* source address */
		if (long_format >= 2) {
			GETNAMEINFO((struct sockaddr *)&pd->local, _addr1_, _addr2_);
			switch (long_format) {
			case 0:
				break;
			case 1:
				p = fixed_addr(_addr1_, _addr2_, 22);
				break;
			case 2:
			default:
				p = fixed_addr(_addr1_, _addr2_, 45);
				break;
			}
			printf("%s ", p);
		}

		/* destination address */
		GETNAMEINFO((struct sockaddr *)&pd->remote, _addr1_, _addr2_);
		switch (long_format) {
		case 0:
		case 1:
			p = fixed_addr(_addr1_, _addr2_, 22);
			break;
		case 2:
		default:
			p = fixed_addr(_addr1_, _addr2_, 45);
			break;
		}
		printf("%s ", p);

		printf("%s ", pindex_isakmp(&pd->index));

		/* statuc, side and version */
		if (long_format >= 1) {
			printf("%2d %c %2x ",
				pd->status,
				pd->side == INITIATOR ? 'I' : 'R',
				pd->version);
			if (ARRAYLEN(estr) > pd->etype)
				printf("%s ", estr[pd->etype]);
		}

		/* created date */
		if (pd->created) {
			tm = localtime(&pd->created);
			strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
		} else
			snprintf(tbuf, sizeof(tbuf), "                   ");
		printf("%s ", tbuf);

		/* counter of phase 2 */
		if (long_format >= 1)
			printf("%6d ", pd->ph2cnt);

		printf("\n");

		pd++;
	}

	return;
}

/* %%% */
void
dump_internal(buf, tlen)
	char *buf;
	int tlen;
{
	struct ph2handle *iph2;
	struct sockaddr *addr;

/*
short header;
 source address         destination address    
 1234567890123456789012 1234567890123456789012 
*/
char *short_h1 = 
"Source                 Destination            ";

/*
long header;
 source address                                destination address                           
 123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345 
 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000
*/
char *long_h1 = 
"Source                                        Destination                                  ";

	printf("%s\n", long_format ? long_h1 : short_h1);

	while (tlen > 0) {
		iph2 = (struct ph2handle *)buf;
		addr = (struct sockaddr *)(++iph2);

		GETNAMEINFO(addr, _addr1_, _addr2_);
		printf("%s ", long_format ?
			  fixed_addr(_addr1_, _addr2_, 45)
			: fixed_addr(_addr1_, _addr2_, 22));
		addr++;
		tlen -= sysdep_sa_len(addr);

		GETNAMEINFO(addr, _addr1_, _addr2_);
		printf("%s ", long_format ?
			  fixed_addr(_addr1_, _addr2_, 45)
			: fixed_addr(_addr1_, _addr2_, 22));
		addr++;
		tlen -= sysdep_sa_len(addr);

		printf("\n");
	}

	return;
}

/* %%% */
char *
pindex_isakmp(index)
	isakmp_index *index;
{
	static char buf[64];
	u_char *p;
	int i, j;

	memset(buf, 0, sizeof(buf));

	/* copy index */
	p = (u_char *)index;
	for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
		snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
		j += 2;
		switch (i) {
		case 7:
#if 0
		case 15:
#endif
			buf[j++] = ':';
		}
	}

	return buf;
}

/* print schedule */
char *str_sched_stat[] = {
"off",
"on",
"dead",
};

char *str_sched_id[] = {
"PH1resend",
"PH1lifetime",
"PH2resend",
"PSTacquire",
"PSTlifetime",
};

void
print_schedule(buf, len)
	caddr_t buf;
	int len;
{
	struct scheddump *sc = (struct scheddump *)buf;
	struct tm *tm;
	char tbuf[56];

	if (len % sizeof(*sc))
		printf("invalid length %d\n", len);
	len /= sizeof(*sc);

	/*      00000000 00000000 00000000 xxx........*/
	printf("index    tick     xtime    created\n");

	while (len-- > 0) {
		tm = localtime(&sc->created);
		strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);

		printf("%-8ld %-8ld %-8ld %s\n",
			sc->id,
			(long)sc->tick,
			(long)sc->xtime,
			tbuf);
		sc++;
	}

	return;
}


void
print_evt(evtdump)
	struct evt_async *evtdump;
{
	int i;
	char *srcstr;
	char *dststr;
	
	for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++)
		if (evtmsg[i].type == evtdump->ec_type)
			break;

	if (evtmsg[i].msg == NULL)
		printf("Event %d: ", evtdump->ec_type);
	else
		printf("%s : ", evtmsg[i].msg);

	if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL)
		printf("unknown");
	else
		printf("%s", srcstr);
	printf(" -> ");
	if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL)
		printf("unknown");
	else
		printf("%s", dststr);
	printf("\n");
}

/*
 * Print ISAKMP mode config info (IP and banner)
 */
void
print_cfg(buf, len)
	caddr_t buf;
	int len;
{
	struct evt_async *evtdump = (struct evt_async *)buf;
	struct isakmp_data *attr;
	char *banner = NULL;
	struct in_addr addr4;
	
	memset(&addr4, 0, sizeof(addr4));

	if (evtdump->ec_type != EVT_PHASE1_MODE_CFG)
		return;

	len -= sizeof(*evtdump);
	attr = (struct isakmp_data *)(evtdump + 1);

	while (len > 0) {
		if (len < sizeof(*attr)) {
			printf("short attribute too short\n");
			break;
		}

		if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
			/* Short attribute, skip */
			len -= sizeof(*attr);
			attr++;
		} else { /* Long attribute */
			char *n;

			if (len < (sizeof(*attr) + ntohs(attr->lorv))) {
				printf("long attribute too long\n");
				break;
			}

			switch (ntohs(attr->type) & ~ISAKMP_GEN_MASK) {
			case INTERNAL_IP4_ADDRESS:
				if (ntohs(attr->lorv) < sizeof(addr4)) {
					printf("addr4 attribute too short\n");
					break;
				}
				memcpy(&addr4, attr + 1, sizeof(addr4));
				break;

			case UNITY_BANNER:
				banner = racoon_malloc(ntohs(attr->lorv) + 1);
				if (banner == NULL) {
					printf("malloc failed\n");
					break;
				}
				memcpy(banner, attr + 1, ntohs(attr->lorv));
				banner[ntohs(attr->lorv)] = '\0';
				break;

			default:
				break;
			}

			len -= (sizeof(*attr) + ntohs(attr->lorv));
			n = (char *)attr;
			attr = (struct isakmp_data *)
			    (n + sizeof(*attr) + ntohs(attr->lorv));
		}
	}

	if (len > 0)
		printf("Bound to address %s\n", inet_ntoa(addr4));
	else
		printf("VPN connexion established\n");

	if (banner) {
		struct winsize win;
		int col = 0;
		int i;

		if (ioctl(1, TIOCGWINSZ, &win) != 1) 
			col = win.ws_col;
			
		for (i = 0; i < col; i++)
			printf("%c", '=');
		printf("\n%s\n", banner);
		for (i = 0; i < col; i++)
			printf("%c", '=');
		printf("\n");
		racoon_free(banner);
	}
}


char *
fixed_addr(addr, port, len)
	char *addr, *port;
	int len;
{
	static char _addr_buf_[BUFSIZ];
	char *p;
	int plen, i;

	/* initialize */
	memset(_addr_buf_, ' ', sizeof(_addr_buf_));

	plen = strlen(port);
	if (len < plen + 1)
		return NULL;

	p = _addr_buf_;
	for (i = 0; i < len - plen - 1 && addr[i] != '\0'; /*noting*/)
		*p++ = addr[i++];
	*p++ = '.';

	for (i = 0; i < plen && port[i] != '\0'; /*noting*/)
		*p++ = port[i++];

	_addr_buf_[len] = '\0';

	return _addr_buf_;
}

static int
handle_recv(combuf)
	vchar_t *combuf;
{
        struct admin_com *com;
        caddr_t buf;
        int len;

	com = (struct admin_com *)combuf->v;
	if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY)
		len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16);
	else
		len = com->ac_len;
	len -= sizeof(*com);
	buf = combuf->v + sizeof(*com);

	switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) {
	case ADMIN_SHOW_SCHED:
		print_schedule(buf, len);
		break;

	case ADMIN_SHOW_EVT: {
		struct evt_async *ec;

		/* We got no event? */
		if (len == 0)
			break;

		if (len < sizeof(struct evt_async))
			errx(1, "Short buffer\n");

		ec = (struct evt_async *) buf;
		if (evt_quit_event <= 0)
			print_evt(ec);
		else if (evt_quit_event == ec->ec_type) {
			switch (ec->ec_type) {
			case EVT_PHASE1_MODE_CFG:
				print_cfg(ec, len);
				break;
			default:
				print_evt(ec);
				break;
			}
			evt_quit_event = 0;
		}
		break;
	}

	case ADMIN_GET_SA_CERT:
		fwrite(buf, len, 1, stdout);
		break;

	case ADMIN_SHOW_SA:
	   {
		switch (com->ac_proto) {
		case ADMIN_PROTO_ISAKMP:
			dump_isakmp_sa(buf, len);
			break;
		case ADMIN_PROTO_IPSEC:
		case ADMIN_PROTO_AH:
		case ADMIN_PROTO_ESP:
		    {
			struct sadb_msg *msg = (struct sadb_msg *)buf;

			switch (msg->sadb_msg_errno) {
			case ENOENT:
				switch (msg->sadb_msg_type) {
				case SADB_DELETE:
				case SADB_GET:
					printf("No entry.\n");
					break;
				case SADB_DUMP:
					printf("No SAD entries.\n");
					break;
				}
				break;
			case 0:
				while (1) {
					pfkey_sadump(msg);
					if (msg->sadb_msg_seq == 0)
						break;
					msg = (struct sadb_msg *)((caddr_t)msg +
						     PFKEY_UNUNIT64(msg->sadb_msg_len));
				}
				break;
			default:
				printf("%s.\n", strerror(msg->sadb_msg_errno));
			}
		    }
			break;
		case ADMIN_PROTO_INTERNAL:
			dump_internal(buf, len);
			break;
		default:
			printf("Invalid proto [%d]\n", com->ac_proto);
		}

	    }
		break;

	default:
		/* IGNORE */
		break;
	}

	return 0;

bad:
	return -1;
}
