File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / racoonctl.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, v0_8_0p0, v0_8_0, HEAD
ipsec-tools

    1: /*	$NetBSD: racoonctl.c,v 1.18 2010/11/12 09:08:26 tteras Exp $	*/
    2: 
    3: /*	Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
    4: 
    5: /*
    6:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    7:  * Copyright (C) 2008 Timo Teras.
    8:  * All rights reserved.
    9:  * 
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  * 3. Neither the name of the project nor the names of its contributors
   19:  *    may be used to endorse or promote products derived from this software
   20:  *    without specific prior written permission.
   21:  * 
   22:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32:  * SUCH DAMAGE.
   33:  */
   34: 
   35: #include "config.h"
   36: 
   37: #include <sys/types.h>
   38: #include <sys/param.h>
   39: #include <sys/socket.h>
   40: #include <sys/un.h>
   41: 
   42: #include <netinet/in.h>
   43: #include <arpa/inet.h>
   44: #include <net/pfkeyv2.h>
   45: 
   46: #include <stdlib.h>
   47: #include <stdio.h>
   48: #include <string.h>
   49: #include <errno.h>
   50: #if TIME_WITH_SYS_TIME
   51: # include <sys/time.h>
   52: # include <time.h>
   53: #else
   54: # if HAVE_SYS_TIME_H
   55: #  include <sys/time.h>
   56: # else
   57: #  include <time.h>
   58: # endif
   59: #endif
   60: #include <netdb.h>
   61: #ifdef HAVE_UNISTD_H
   62: #include <unistd.h>
   63: #endif
   64: #include <err.h>
   65: #include <sys/ioctl.h> 
   66: #include <resolv.h>
   67: 
   68: #include "var.h"
   69: #include "vmbuf.h"
   70: #include "misc.h"
   71: #include "gcmalloc.h"
   72: 
   73: #include "racoonctl.h"
   74: #include "admin.h"
   75: #include "schedule.h"
   76: #include "handler.h"
   77: #include "sockmisc.h"
   78: #include "vmbuf.h"
   79: #include "plog.h"
   80: #include "isakmp_var.h"
   81: #include "isakmp.h"
   82: #include "isakmp_xauth.h"
   83: #include "isakmp_cfg.h"
   84: #include "isakmp_unity.h"
   85: #include "ipsec_doi.h"
   86: #include "evt.h"
   87: 
   88: char *adminsock_path = ADMINSOCK_PATH;
   89: 
   90: static void usage __P((void));
   91: static vchar_t *get_combuf __P((int, char **));
   92: static int handle_recv __P((vchar_t *));
   93: static vchar_t *f_reload __P((int, char **));
   94: static vchar_t *f_getsched __P((int, char **));
   95: static vchar_t *f_getsa __P((int, char **));
   96: static vchar_t *f_getsacert __P((int, char **));
   97: static vchar_t *f_flushsa __P((int, char **));
   98: static vchar_t *f_deletesa __P((int, char **));
   99: static vchar_t *f_exchangesa __P((int, char **));
  100: static vchar_t *f_vpnc __P((int, char **));
  101: static vchar_t *f_vpnd __P((int, char **));
  102: static vchar_t *f_getevt __P((int, char **));
  103: #ifdef ENABLE_HYBRID
  104: static vchar_t *f_logoutusr __P((int, char **));
  105: #endif
  106: 
  107: struct cmd_tag {
  108: 	vchar_t *(*func) __P((int, char **));
  109: 	char *str;
  110: } cmdtab[] = {
  111: 	{ f_reload,	"reload-config" },
  112: 	{ f_reload,	"rc" },
  113: 	{ f_getsched,	"show-schedule" },
  114: 	{ f_getsched,	"sc" },
  115: 	{ f_getsa,	"show-sa" },
  116: 	{ f_getsa,	"ss" },
  117: 	{ f_getsacert,	"get-cert" },
  118: 	{ f_getsacert,	"gc" },
  119: 	{ f_flushsa,	"flush-sa" },
  120: 	{ f_flushsa,	"fs" },
  121: 	{ f_deletesa,	"delete-sa" },
  122: 	{ f_deletesa,	"ds" },
  123: 	{ f_exchangesa,	"establish-sa" },
  124: 	{ f_exchangesa,	"es" },
  125: 	{ f_vpnc,	"vpn-connect" },
  126: 	{ f_vpnc,	"vc" },
  127: 	{ f_vpnd,	"vpn-disconnect" },
  128: 	{ f_vpnd,	"vd" },
  129: 	{ f_getevt,	"show-event" },
  130: 	{ f_getevt,	"se" },
  131: #ifdef ENABLE_HYBRID
  132: 	{ f_logoutusr,	"logout-user" },
  133: 	{ f_logoutusr,	"lu" },
  134: #endif
  135: 	{ NULL, NULL },
  136: };
  137: 
  138: struct evtmsg {
  139: 	int type;
  140: 	char *msg;
  141: } evtmsg[] = {
  142: 	{ EVT_RACOON_QUIT,		"Racoon terminated" },
  143: 
  144: 	{ EVT_PHASE1_UP,		"Phase 1 established" },
  145: 	{ EVT_PHASE1_DOWN,		"Phase 1 deleted" },
  146: 	{ EVT_PHASE1_NO_RESPONSE,	"Phase 1 error: peer not responding" },
  147: 	{ EVT_PHASE1_NO_PROPOSAL,	"Phase 1 error: no proposal chosen" },
  148: 	{ EVT_PHASE1_AUTH_FAILED,
  149: 	  "Phase 1 error: authentication failed (bad certificate?)" },
  150: 	{ EVT_PHASE1_DPD_TIMEOUT,	"Phase 1 error: dead peer detected" },
  151: 	{ EVT_PHASE1_MODE_CFG,		"Phase 1 mode configuration done" },
  152: 	{ EVT_PHASE1_XAUTH_SUCCESS,	"Phase 1 Xauth succeeded" },
  153: 	{ EVT_PHASE1_XAUTH_FAILED,	"Phase 1 Xauth failed" },
  154: 
  155: 	{ EVT_PHASE2_NO_PHASE1,		"Phase 2 error: no suitable phase 1" },
  156: 	{ EVT_PHASE2_UP,		"Phase 2 established" },
  157: 	{ EVT_PHASE2_DOWN,		"Phase 2 deleted" },
  158: 	{ EVT_PHASE2_NO_RESPONSE,	"Phase 2 error: no response" },
  159: };
  160: 
  161: static vchar_t *get_proto_and_index __P((int, char **, u_int16_t *));
  162: static int get_proto __P((char *));
  163: static vchar_t *get_index __P((int, char **));
  164: static int get_family __P((char *));
  165: static vchar_t *get_comindexes __P((int, int, char **));
  166: static int get_comindex __P((char *, char **, char **, char **));
  167: static int get_ulproto __P((char *));
  168: 
  169: struct proto_tag {
  170: 	int proto;
  171: 	char *str;
  172: } prototab[] = {
  173: 	{ ADMIN_PROTO_ISAKMP,	"isakmp" },
  174: 	{ ADMIN_PROTO_IPSEC,	"ipsec" },
  175: 	{ ADMIN_PROTO_AH,	"ah" },
  176: 	{ ADMIN_PROTO_ESP,	"esp" },
  177: 	{ ADMIN_PROTO_INTERNAL,	"internal" },
  178: 	{ 0, NULL },
  179: };
  180: 
  181: struct ulproto_tag {
  182: 	int ul_proto;
  183: 	char *str;
  184: } ulprototab[] = {
  185: 	{ 0,		"any" },
  186: 	{ IPPROTO_ICMP,	"icmp" },
  187: 	{ IPPROTO_TCP,	"tcp" },
  188: 	{ IPPROTO_UDP,	"udp" },
  189: 	{ IPPROTO_GRE,	"gre" },
  190: 	{ 0, NULL },
  191: };
  192: 
  193: int so;
  194: 
  195: static char _addr1_[NI_MAXHOST], _addr2_[NI_MAXHOST];
  196: 
  197: char *pname;
  198: int long_format = 0;
  199: int evt_quit_event = 0;
  200: 
  201: void dump_isakmp_sa __P((char *, int));
  202: void dump_internal __P((char *, int));
  203: char *pindex_isakmp __P((isakmp_index *));
  204: void print_schedule __P((caddr_t, int));
  205: void print_evt __P((struct evt_async *));
  206: char * fixed_addr __P((char *, char *, int));
  207: 
  208: static void
  209: usage()
  210: {
  211: 	printf(
  212: "Usage:\n"
  213: "  %s [opts] reload-config\n"
  214: "  %s [opts] show-schedule\n"
  215: "  %s [opts] show-sa [protocol]\n"
  216: "  %s [opts] flush-sa [protocol]\n"
  217: "  %s [opts] delete-sa <saopts>\n"
  218: "  %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] <saopts>\n"
  219: "  %s [opts] vpn-connect [-u identity] vpn_gateway\n"
  220: "  %s [opts] vpn-disconnect vpn_gateway\n"
  221: "  %s [opts] show-event\n"
  222: "  %s [opts] logout-user login\n"
  223: "\n"
  224: "General options:\n"
  225: "  -d		Debug: hexdump admin messages before sending\n"
  226: "  -l		Increase output verbosity (mainly for show-sa)\n"
  227: "  -s <socket>	Specify adminport socket to use (default: %s)\n"
  228: "\n"
  229: "Parameter specifications:\n"
  230: "    <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
  231: "        In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
  232: "\n"
  233: "    <saopts>: \"isakmp\" <family> <src> <dst>\n"
  234: "            : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
  235: "                              <ul_proto>\n"
  236: "    <family>: \"inet\" or \"inet6\"\n"
  237: "    <ul_proto>: \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n"
  238: "\n",
  239: 		pname, pname, pname, pname, pname, pname, pname, pname, pname, pname,
  240: 		ADMINSOCK_PATH);
  241: }
  242: 
  243: /*
  244:  * Check for proper racoonctl interface
  245:  */
  246: #if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
  247: #error	"Incompatible racoonctl interface"
  248: #endif
  249: 
  250: int
  251: main(ac, av)
  252: 	int ac;
  253: 	char **av;
  254: {
  255: 	vchar_t *combuf;
  256: 	int c;
  257: 
  258: 	pname = *av;
  259: 
  260: 	/*
  261: 	 * Check for proper racoonctl interface
  262: 	 */
  263: 	if ((racoonctl_interface_major != RACOONCTL_INTERFACE_MAJOR) ||
  264: 	    (racoonctl_interface < RACOONCTL_INTERFACE))
  265: 		errx(1, "Incompatible racoonctl interface");
  266: 
  267: #ifdef __linux__
  268: 	/*
  269: 	 * Disable GNU extensions that will prevent racoonct vc -u login
  270: 	 * from working (GNU getopt(3) does not like options after vc)
  271: 	 */
  272: 	setenv("POSIXLY_CORRECT", "1", 0);
  273: #endif
  274: 	while ((c = getopt(ac, av, "lds:")) != -1) {
  275: 		switch(c) {
  276: 		case 'l':
  277: 			long_format++;
  278: 			break;
  279: 
  280: 		case 'd':
  281: 			loglevel++;
  282: 			break;
  283: 
  284: 		case 's':
  285: 			adminsock_path = optarg;
  286: 			break;
  287: 
  288: 		default:
  289: 			usage();
  290: 			exit(0);
  291: 		}
  292: 	}
  293: 
  294: 	ac -= optind;
  295: 	av += optind;
  296: 
  297: 	combuf = get_combuf(ac, av);
  298: 	if (!combuf)
  299: 		err(1, "kmpstat");
  300: 
  301: 	if (loglevel)
  302: 		racoon_hexdump(combuf, ((struct admin_com *)combuf)->ac_len);
  303: 
  304: 	com_init();
  305: 
  306: 	if (com_send(combuf) != 0)
  307: 		goto bad;
  308: 
  309: 	vfree(combuf);
  310: 
  311: 	do {
  312: 		if (com_recv(&combuf) != 0)
  313: 			goto bad;
  314: 		if (handle_recv(combuf) != 0)
  315: 			goto bad;
  316: 		vfree(combuf);
  317: 	} while (evt_quit_event != 0);
  318: 
  319: 	close(so);
  320: 	exit(0);
  321: 
  322: bad:
  323: 	close(so);
  324: 	if (errno == EEXIST)
  325: 		exit(0);
  326: 	exit(1);
  327: }
  328: 
  329: /* %%% */
  330: /*
  331:  * return command buffer.
  332:  */
  333: static vchar_t *
  334: get_combuf(ac, av)
  335: 	int ac;
  336: 	char **av;
  337: {
  338: 	struct cmd_tag *cp;
  339: 
  340: 	if (ac == 0) {
  341: 		usage();
  342: 		exit(0);
  343: 	}
  344: 
  345: 	/* checking the string of command. */
  346: 	for (cp = &cmdtab[0]; cp->str; cp++) {
  347: 		if (strcmp(*av, cp->str) == 0) {
  348: 			break;
  349: 		}
  350: 	}
  351: 	if (!cp->str) {
  352: 		printf("Invalid command [%s]\n", *av);
  353: 		errno = EINVAL;
  354: 		return NULL;
  355: 	}
  356: 
  357: 	ac--;
  358: 	av++;
  359: 	return (cp->func)(ac, av);
  360: }
  361: 
  362: static vchar_t *
  363: make_request(u_int16_t cmd, u_int16_t proto, size_t len)
  364: {
  365: 	vchar_t *buf;
  366: 	struct admin_com *head;
  367: 
  368: 	buf = vmalloc(sizeof(struct admin_com) + len);
  369: 	if (buf == NULL)
  370: 		errx(1, "not enough core");
  371: 
  372: 	head = (struct admin_com *) buf->v;
  373: 	head->ac_len = buf->l;
  374: 	head->ac_cmd = ADMIN_FLAG_VERSION | cmd;
  375: 	head->ac_version = 1;
  376: 	head->ac_proto = proto;
  377: 
  378: 	return buf;
  379: }
  380: 
  381: static vchar_t *
  382: f_reload(ac, av)
  383: 	int ac;
  384: 	char **av;
  385: {
  386: 	return make_request(ADMIN_RELOAD_CONF, 0, 0);
  387: }
  388: 
  389: static vchar_t *
  390: f_getevt(ac, av)
  391: 	int ac;
  392: 	char **av;
  393: {
  394: 	evt_quit_event = -1;
  395: 	if (ac >= 1)
  396: 		errx(1, "too many arguments");
  397: 
  398: 	return make_request(ADMIN_SHOW_EVT, 0, 0);
  399: }
  400: 
  401: static vchar_t *
  402: f_getsched(ac, av)
  403: 	int ac;
  404: 	char **av;
  405: {
  406: 	return make_request(ADMIN_SHOW_SCHED, 0, 0);
  407: }
  408: 
  409: static vchar_t *
  410: f_getsa(ac, av)
  411: 	int ac;
  412: 	char **av;
  413: {
  414: 	int proto;
  415: 
  416: 	/* need protocol */
  417: 	if (ac != 1)
  418: 		errx(1, "insufficient arguments");
  419: 	proto = get_proto(*av);
  420: 	if (proto == -1)
  421: 		errx(1, "unknown protocol %s", *av);
  422: 
  423: 	return make_request(ADMIN_SHOW_SA, proto, 0);
  424: }
  425: 
  426: static vchar_t *
  427: f_getsacert(ac, av)
  428: 	int ac;
  429: 	char **av;
  430: {
  431: 	vchar_t *buf, *index;
  432: 	struct admin_com_indexes *com;
  433: 
  434: 	index = get_index(ac, av);
  435: 	if (index == NULL)
  436: 		return NULL;
  437: 
  438: 	com = (struct admin_com_indexes *) index->v;
  439: 	buf = make_request(ADMIN_GET_SA_CERT, ADMIN_PROTO_ISAKMP, index->l);
  440: 	if (buf == NULL)
  441: 		errx(1, "Cannot allocate buffer");
  442: 
  443: 	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
  444: 
  445: 	vfree(index);
  446: 
  447: 	return buf;
  448: }
  449: 
  450: static vchar_t *
  451: f_flushsa(ac, av)
  452: 	int ac;
  453: 	char **av;
  454: {
  455: 	vchar_t *buf;
  456: 	struct admin_com *head;
  457: 	int proto;
  458: 
  459: 	/* need protocol */
  460: 	if (ac != 1)
  461: 		errx(1, "insufficient arguments");
  462: 	proto = get_proto(*av);
  463: 	if (proto == -1)
  464: 		errx(1, "unknown protocol %s", *av);
  465: 
  466: 	return make_request(ADMIN_FLUSH_SA, proto, 0);
  467: }
  468: 
  469: static vchar_t *
  470: f_deletesa(ac, av)
  471: 	int ac;
  472: 	char **av;
  473: {
  474: 	vchar_t *buf, *index;
  475: 	int proto;
  476: 
  477: 	/* need protocol */
  478: 	if (ac < 1)
  479: 		errx(1, "insufficient arguments");
  480: 	proto = get_proto(*av);
  481: 	if (proto == -1)
  482: 		errx(1, "unknown protocol %s", *av);
  483: 
  484: 	/* get index(es) */
  485: 	av++;
  486: 	ac--;
  487: 	switch (proto) {
  488: 	case ADMIN_PROTO_ISAKMP:
  489: 		index = get_index(ac, av);
  490: 		if (index == NULL)
  491: 			return NULL;
  492: 		break;
  493: 	case ADMIN_PROTO_AH:
  494: 	case ADMIN_PROTO_ESP:
  495: 		index = get_index(ac, av);
  496: 		if (index == NULL)
  497: 			return NULL;
  498: 		break;
  499: 	default:
  500: 		errno = EPROTONOSUPPORT;
  501: 		return NULL;
  502: 	}
  503: 
  504: 	buf = make_request(ADMIN_DELETE_SA, proto, index->l);
  505: 	if (buf == NULL)
  506: 		goto out;
  507: 
  508: 	memcpy(buf->v + sizeof(struct admin_com), index->v, index->l);
  509: 
  510: out:
  511: 	if (index != NULL)
  512: 		vfree(index);
  513: 
  514: 	return buf;
  515: }
  516: 
  517: static vchar_t *
  518: f_deleteallsadst(ac, av)
  519: 	int ac;
  520: 	char **av;
  521: {
  522: 	vchar_t *buf, *index;
  523: 	u_int16_t proto;
  524: 
  525: 	index = get_proto_and_index(ac, av, &proto);
  526: 	if (index == NULL)
  527: 		return NULL;
  528: 
  529: 	buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l);
  530: 	if (buf == NULL)
  531: 		goto out;
  532: 
  533: 	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
  534: 
  535: out:
  536: 	if (index != NULL)
  537: 		vfree(index);
  538: 
  539: 	return buf;
  540: }
  541: 
  542: static vchar_t *
  543: f_exchangesa(ac, av)
  544: 	int ac;
  545: 	char **av;
  546: {
  547: 	vchar_t *buf, *index;
  548: 	u_int16_t proto;
  549: 	int cmd = ADMIN_ESTABLISH_SA;
  550: 	size_t com_len = 0;
  551: 	char *id = NULL;
  552: 	char *key = NULL;
  553: 	char *remoteconf = NULL;
  554: 	struct admin_com_psk *acp;
  555: 	int wait = 0;
  556: 
  557: 	if (ac < 1)
  558: 		errx(1, "insufficient arguments");
  559: 
  560: 	/* Optional -u identity */
  561: 	if (strcmp(av[0], "-u") == 0) {
  562: 		if (ac < 2)
  563: 			errx(1, "-u require an argument");
  564: 
  565: 		id = av[1];
  566: 		if ((key = getpass("Password: ")) == NULL)
  567: 			errx(1, "getpass() failed: %s", strerror(errno));
  568: 		
  569: 		com_len += sizeof(*acp) + strlen(id) + 1 + strlen(key) + 1;
  570: 		cmd = ADMIN_ESTABLISH_SA_PSK;
  571: 
  572: 		av += 2;
  573: 		ac -= 2;
  574: 	}
  575: 
  576: 	if (ac >= 2 && strcmp(av[0], "-n") == 0) {
  577: 		/* Remoteconf name */
  578: 		remoteconf = av[1];
  579: 		av += 2;
  580: 		ac -= 2;
  581: 	}
  582: 
  583: 	if (ac >= 1 && strcmp(av[0], "-w") == 0) {
  584: 		wait = 1;
  585: 		av++;
  586: 		ac--;
  587: 	}
  588: 
  589: 	index = get_proto_and_index(ac, av, &proto);
  590: 	if (index == NULL)
  591: 		return NULL;
  592: 
  593: 	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
  594: 	    remoteconf != NULL)
  595: 		com_len += strlen(remoteconf) + 1;
  596: 
  597: 	if (wait) {
  598: 		switch (proto) {
  599: 		case ADMIN_PROTO_ISAKMP:
  600: 			evt_quit_event = EVT_PHASE1_MODE_CFG;
  601: 			break;
  602: 		case ADMIN_PROTO_AH:
  603: 		case ADMIN_PROTO_ESP:
  604: 			evt_quit_event = EVT_PHASE2_UP;
  605: 			break;
  606: 		default:
  607: 			errno = EPROTONOSUPPORT;
  608: 			return NULL;
  609: 		}
  610: 	}
  611: 
  612: 	com_len += index->l;
  613: 	buf = make_request(cmd, proto, com_len);
  614: 	if (buf == NULL)
  615: 		errx(1, "Cannot allocate buffer");
  616: 
  617: 	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
  618: 
  619: 	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
  620: 	    remoteconf != NULL) {
  621: 		strcpy(buf->v + sizeof(struct admin_com) + index->l,
  622: 		       remoteconf);
  623: 	} else if (id && key) {
  624: 		char *data;
  625: 		acp = (struct admin_com_psk *)
  626: 		    (buf->v + sizeof(struct admin_com) + index->l);
  627: 
  628: 		acp->id_type = IDTYPE_USERFQDN;
  629: 		acp->id_len = strlen(id) + 1;
  630: 		acp->key_len = strlen(key) + 1;
  631: 
  632: 		data = (char *)(acp + 1);
  633: 		strcpy(data, id);
  634: 
  635: 		data = (char *)(data + acp->id_len);
  636: 		strcpy(data, key);
  637: 	}
  638: 
  639: 	vfree(index);
  640: 
  641: 	return buf;
  642: }
  643: 
  644: static vchar_t *
  645: f_vpnc(ac, av)
  646: 	int ac;
  647: 	char **av;
  648: {
  649: 	char *nav[] = {NULL, NULL, NULL, NULL, NULL, NULL};
  650: 	int nac = 0;
  651: 	char *isakmp = "isakmp";
  652: 	char *inet = "inet";
  653: 	char *srcaddr;
  654: 	struct addrinfo hints, *res;
  655: 	struct sockaddr *src;
  656: 	char *idx;
  657: 
  658: 	if (ac < 1)
  659: 		errx(1, "insufficient arguments");
  660: 
  661: 	evt_quit_event = EVT_PHASE1_MODE_CFG;
  662: 	
  663: 	/* Optional -u identity */
  664: 	if (strcmp(av[0], "-u") == 0) {
  665: 		if (ac < 2)
  666: 			errx(1, "-u require an argument");
  667: 
  668: 		nav[nac++] = av[0];
  669: 		nav[nac++] = av[1];
  670: 
  671: 		ac -= 2;
  672: 		av += 2;
  673: 	}
  674: 
  675: 	if (ac < 1)
  676: 		errx(1, "VPN gateway required");
  677: 	if (ac > 1)
  678: 		warnx("Extra arguments");
  679: 
  680: 	/*
  681: 	 * Find the source address
  682: 	 */
  683: 	memset(&hints, 0, sizeof(hints));
  684: 	hints.ai_family = PF_UNSPEC;
  685: 	hints.ai_socktype = SOCK_DGRAM;
  686: 	if (getaddrinfo(av[0], "4500", &hints, &res) != 0)
  687: 		errx(1, "Cannot resolve destination address");
  688: 
  689: 	if ((src = getlocaladdr(res->ai_addr)) == NULL)
  690: 		errx(1, "cannot find source address");
  691: 
  692: 	if ((srcaddr = saddr2str(src)) == NULL)
  693: 		errx(1, "cannot read source address");
  694: 
  695: 	/* We get "ip[port]" strip the port */
  696: 	if ((idx = index(srcaddr, '[')) == NULL) 
  697: 		errx(1, "unexpected source address format");
  698: 	*idx = '\0';
  699: 
  700: 	nav[nac++] = isakmp;
  701: 	nav[nac++] = inet;
  702: 	nav[nac++] = srcaddr;
  703: 	nav[nac++] = av[0];
  704: 
  705: 	return f_exchangesa(nac, nav);
  706: }
  707: 
  708: static vchar_t *
  709: f_vpnd(ac, av)
  710: 	int ac;
  711: 	char **av;
  712: {
  713: 	char *nav[] = {NULL, NULL, NULL, NULL};
  714: 	int nac = 0;
  715: 	char *isakmp = "isakmp";
  716: 	char *inet = "inet";
  717: 	char *anyaddr = "0.0.0.0";
  718: 	char *idx;
  719: 
  720: 	if (ac < 1)
  721: 		errx(1, "VPN gateway required");
  722: 	if (ac > 1)
  723: 		warnx("Extra arguments");
  724: 
  725: 	evt_quit_event = EVT_PHASE1_DOWN;
  726: 
  727: 	nav[nac++] = isakmp;
  728: 	nav[nac++] = inet;
  729: 	nav[nac++] = anyaddr;
  730: 	nav[nac++] = av[0];
  731: 
  732: 	return f_deleteallsadst(nac, nav);
  733: }
  734: 
  735: #ifdef ENABLE_HYBRID
  736: static vchar_t *
  737: f_logoutusr(ac, av)
  738: 	int ac;
  739: 	char **av;
  740: {
  741: 	vchar_t *buf;
  742: 	char *user;
  743: 	size_t userlen;
  744: 
  745: 	/* need username */
  746: 	if (ac < 1)
  747: 		errx(1, "insufficient arguments");
  748: 	user = av[0];
  749: 	userlen = strlen(user);
  750: 	if ((user == NULL) || (userlen > LOGINLEN))
  751: 		errx(1, "bad login (too long?)");
  752: 
  753: 	buf = make_request(ADMIN_LOGOUT_USER, 0, userlen);
  754: 	if (buf == NULL)
  755: 		return NULL;
  756: 
  757: 	strncpy(buf->v + sizeof(struct admin_com), user, userlen);
  758: 
  759: 	return buf;
  760: }
  761: #endif /* ENABLE_HYBRID */
  762: 
  763: static vchar_t *
  764: get_proto_and_index(ac, av, proto)
  765: 	int ac;
  766: 	char **av;
  767: 	u_int16_t *proto;
  768: {
  769: 	vchar_t *index = NULL;
  770: 
  771: 	/* need protocol */
  772: 	if (ac < 1)
  773: 		errx(1, "insufficient arguments");
  774: 	*proto = get_proto(*av);
  775: 	if (*proto == (u_int16_t) -1)
  776: 		errx(1, "unknown protocol %s", *av);
  777: 
  778: 	/* get index(es) */
  779: 	av++;
  780: 	ac--;
  781: 	switch (*proto) {
  782: 	case ADMIN_PROTO_ISAKMP:
  783: 	case ADMIN_PROTO_AH:
  784: 	case ADMIN_PROTO_ESP:
  785: 		index = get_index(ac, av);
  786: 		break;
  787: 	default:
  788: 		errno = EPROTONOSUPPORT;
  789: 		break;
  790: 	}
  791: 	return index;
  792: }
  793: 
  794: static int
  795: get_proto(str)
  796: 	char *str;
  797: {
  798: 	struct proto_tag *cp;
  799: 
  800: 	if (str == NULL) {
  801: 		errno = EINVAL;
  802: 		return -1;
  803: 	}
  804: 
  805: 	/* checking the string of command. */
  806: 	for (cp = &prototab[0]; cp->str; cp++) {
  807: 		if (strcmp(str, cp->str) == 0)
  808: 			return cp->proto;
  809: 	}
  810: 
  811: 	errno = EINVAL;
  812: 	return -1;
  813: }
  814: 
  815: static vchar_t *
  816: get_index(ac, av)
  817: 	int ac;
  818: 	char **av;
  819: {
  820: 	int family;
  821: 
  822: 	if (ac != 3 && ac != 4) {
  823: 		errno = EINVAL;
  824: 		return NULL;
  825: 	}
  826: 
  827: 	/* checking the string of family */
  828: 	family = get_family(*av);
  829: 	if (family == -1)
  830: 		return NULL;
  831: 	av++;
  832: 	ac--;
  833: 
  834: 	return get_comindexes(family, ac, av);
  835: }
  836: 
  837: static int
  838: get_family(str)
  839: 	char *str;
  840: {
  841: 	if (strcmp("inet", str) == 0)
  842: 		return AF_INET;
  843: #ifdef INET6
  844: 	else if (strcmp("inet6", str) == 0)
  845: 		return AF_INET6;
  846: #endif
  847: 	errno = EAFNOSUPPORT;
  848: 	return -1;
  849: }
  850: 
  851: static vchar_t *
  852: get_comindexes(family, ac, av)
  853: 	int family;
  854: 	int ac;
  855: 	char **av;
  856: {
  857: 	vchar_t *buf;
  858: 	struct admin_com_indexes *ci;
  859: 	char *p_name = NULL, *p_port = NULL;
  860: 	char *p_prefs = NULL, *p_prefd = NULL;
  861: 	struct sockaddr *src = NULL, *dst = NULL;
  862: 	int ulproto;
  863: 
  864: 	if (ac != 2 && ac != 3) {
  865: 		errno = EINVAL;
  866: 		return NULL;
  867: 	}
  868: 
  869: 	if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1)
  870: 		goto bad;
  871: 	src = get_sockaddr(family, p_name, p_port);
  872: 	if (p_name) {
  873: 		racoon_free(p_name);
  874: 		p_name = NULL;
  875: 	}
  876: 	if (p_port) {
  877: 		racoon_free(p_port);
  878: 		p_port = NULL;
  879: 	}
  880: 	if (src == NULL)
  881: 		goto bad;
  882: 	av++;
  883: 	ac--;
  884: 	if (get_comindex(*av, &p_name, &p_port, &p_prefd) == -1)
  885: 		goto bad;
  886: 	dst = get_sockaddr(family, p_name, p_port);
  887: 	if (p_name) {
  888: 		racoon_free(p_name);
  889: 		p_name = NULL;
  890: 	}
  891: 	if (p_port) {
  892: 		racoon_free(p_port);
  893: 		p_port = NULL;
  894: 	}
  895: 	if (dst == NULL)
  896: 		goto bad;
  897: 
  898: 	buf = vmalloc(sizeof(*ci));
  899: 	if (buf == NULL)
  900: 		goto bad;
  901: 
  902: 	av++;
  903: 	ac--;
  904: 	if(ac){
  905: 		ulproto = get_ulproto(*av);
  906: 		if (ulproto == -1)
  907: 			goto bad;
  908: 	}else
  909: 		ulproto=0;
  910: 
  911: 	ci = (struct admin_com_indexes *)buf->v;
  912: 	if(p_prefs)
  913: 		ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */
  914: 	else
  915: 		ci->prefs = 32;
  916: 	if(p_prefd)
  917: 		ci->prefd = (u_int8_t)atoi(p_prefd); /* XXX should be handled error. */
  918: 	else
  919: 		ci->prefd = 32;
  920: 	ci->ul_proto = ulproto;
  921: 	memcpy(&ci->src, src, sysdep_sa_len(src));
  922: 	memcpy(&ci->dst, dst, sysdep_sa_len(dst));
  923: 
  924: 	if (p_name)
  925: 		racoon_free(p_name);
  926: 
  927: 	return buf;
  928: 
  929:    bad:
  930: 	if (p_name)
  931: 		racoon_free(p_name);
  932: 	if (p_port)
  933: 		racoon_free(p_port);
  934: 	if (p_prefs)
  935: 		racoon_free(p_prefs);
  936: 	if (p_prefd)
  937: 		racoon_free(p_prefd);
  938: 	return NULL;
  939: }
  940: 
  941: static int
  942: get_comindex(str, name, port, pref)
  943: 	char *str, **name, **port, **pref;
  944: {
  945: 	char *p;
  946: 
  947: 	*name = *port = *pref = NULL;
  948: 
  949: 	*name = racoon_strdup(str);
  950: 	STRDUP_FATAL(*name);
  951: 	p = strpbrk(*name, "/[");
  952: 	if (p != NULL) {
  953: 		if (*(p + 1) == '\0')
  954: 			goto bad;
  955: 		if (*p == '/') {
  956: 			*p = '\0';
  957: 			*pref = racoon_strdup(p + 1);
  958: 			STRDUP_FATAL(*pref);
  959: 			p = strchr(*pref, '[');
  960: 			if (p != NULL) {
  961: 				if (*(p + 1) == '\0')
  962: 					goto bad;
  963: 				*p = '\0';
  964: 				*port = racoon_strdup(p + 1);
  965: 				STRDUP_FATAL(*port);
  966: 				p = strchr(*pref, ']');
  967: 				if (p == NULL)
  968: 					goto bad;
  969: 				*p = '\0';
  970: 			}
  971: 		} else if (*p == '[') {
  972: 			if (*pref == NULL)
  973: 				goto bad;
  974: 			*p = '\0';
  975: 			*port = racoon_strdup(p + 1);
  976: 			STRDUP_FATAL(*port);
  977: 			p = strchr(*pref, ']');
  978: 			if (p == NULL)
  979: 				goto bad;
  980: 			*p = '\0';
  981: 		} else {
  982: 			/* XXX */
  983: 		}
  984: 	}
  985: 
  986: 	return 0;
  987: 
  988:     bad:
  989: 
  990: 	if (*name)
  991: 		racoon_free(*name);
  992: 	if (*port)
  993: 		racoon_free(*port);
  994: 	if (*pref)
  995: 		racoon_free(*pref);
  996: 	*name = *port = *pref = NULL;
  997: 	return -1;
  998: }
  999: 
 1000: static int
 1001: get_ulproto(str)
 1002: 	char *str;
 1003: {
 1004: 	struct ulproto_tag *cp;
 1005: 
 1006: 	if(str == NULL){
 1007: 		errno = EINVAL;
 1008: 		return -1;
 1009: 	}
 1010: 
 1011: 	/* checking the string of upper layer protocol. */
 1012: 	for (cp = &ulprototab[0]; cp->str; cp++) {
 1013: 		if (strcmp(str, cp->str) == 0)
 1014: 			return cp->ul_proto;
 1015: 	}
 1016: 
 1017: 	errno = EINVAL;
 1018: 	return -1;
 1019: }
 1020: 
 1021: /* %%% */
 1022: void
 1023: dump_isakmp_sa(buf, len)
 1024: 	char *buf;
 1025: 	int len;
 1026: {
 1027: 	struct ph1dump *pd;
 1028: 	struct tm *tm;
 1029: 	char tbuf[56];
 1030: 	caddr_t p = NULL;
 1031: 
 1032: /* isakmp status header */
 1033: /* short header;
 1034:  1234567890123456789012 0000000000000000:0000000000000000 000000000000
 1035: */
 1036: char *header1 = 
 1037: "Destination            Cookies                           Created";
 1038: 
 1039: /* semi long header;
 1040:  1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
 1041: */
 1042: char *header2 = 
 1043: "Destination            Cookies                           ST S  V E Created             Phase2";
 1044: 
 1045: /* long header;
 1046:  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
 1047: */
 1048: char *header3 =
 1049: "Source                                        Destination                                   Cookies                           ST S  V E Created             Phase2";
 1050: 
 1051: /* phase status header */
 1052: /* short format;
 1053:    side stats source address         destination address   
 1054:    xxx  xxxxx 1234567890123456789012 1234567890123456789012
 1055: */
 1056: 
 1057: 	static char *estr[] = { "", "B", "M", "U", "A", "I", };
 1058: 
 1059: 	switch (long_format) {
 1060: 	case 0:
 1061: 		printf("%s\n", header1);
 1062: 		break;
 1063: 	case 1:
 1064: 		printf("%s\n", header2);
 1065: 		break;
 1066: 	case 2:
 1067: 	default:
 1068: 		printf("%s\n", header3);
 1069: 		break;
 1070: 	}
 1071: 
 1072: 	if (len % sizeof(*pd))
 1073: 		printf("invalid length %d\n", len);
 1074: 	len /= sizeof(*pd);
 1075: 
 1076: 	pd = (struct ph1dump *)buf;
 1077: 
 1078: 	while (len-- > 0) {
 1079: 		/* source address */
 1080: 		if (long_format >= 2) {
 1081: 			GETNAMEINFO((struct sockaddr *)&pd->local, _addr1_, _addr2_);
 1082: 			switch (long_format) {
 1083: 			case 0:
 1084: 				break;
 1085: 			case 1:
 1086: 				p = fixed_addr(_addr1_, _addr2_, 22);
 1087: 				break;
 1088: 			case 2:
 1089: 			default:
 1090: 				p = fixed_addr(_addr1_, _addr2_, 45);
 1091: 				break;
 1092: 			}
 1093: 			printf("%s ", p);
 1094: 		}
 1095: 
 1096: 		/* destination address */
 1097: 		GETNAMEINFO((struct sockaddr *)&pd->remote, _addr1_, _addr2_);
 1098: 		switch (long_format) {
 1099: 		case 0:
 1100: 		case 1:
 1101: 			p = fixed_addr(_addr1_, _addr2_, 22);
 1102: 			break;
 1103: 		case 2:
 1104: 		default:
 1105: 			p = fixed_addr(_addr1_, _addr2_, 45);
 1106: 			break;
 1107: 		}
 1108: 		printf("%s ", p);
 1109: 
 1110: 		printf("%s ", pindex_isakmp(&pd->index));
 1111: 
 1112: 		/* statuc, side and version */
 1113: 		if (long_format >= 1) {
 1114: 			printf("%2d %c %2x ",
 1115: 				pd->status,
 1116: 				pd->side == INITIATOR ? 'I' : 'R',
 1117: 				pd->version);
 1118: 			if (ARRAYLEN(estr) > pd->etype)
 1119: 				printf("%s ", estr[pd->etype]);
 1120: 		}
 1121: 
 1122: 		/* created date */
 1123: 		if (pd->created) {
 1124: 			tm = localtime(&pd->created);
 1125: 			strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
 1126: 		} else
 1127: 			snprintf(tbuf, sizeof(tbuf), "                   ");
 1128: 		printf("%s ", tbuf);
 1129: 
 1130: 		/* counter of phase 2 */
 1131: 		if (long_format >= 1)
 1132: 			printf("%6d ", pd->ph2cnt);
 1133: 
 1134: 		printf("\n");
 1135: 
 1136: 		pd++;
 1137: 	}
 1138: 
 1139: 	return;
 1140: }
 1141: 
 1142: /* %%% */
 1143: void
 1144: dump_internal(buf, tlen)
 1145: 	char *buf;
 1146: 	int tlen;
 1147: {
 1148: 	struct ph2handle *iph2;
 1149: 	struct sockaddr *addr;
 1150: 
 1151: /*
 1152: short header;
 1153:  source address         destination address    
 1154:  1234567890123456789012 1234567890123456789012 
 1155: */
 1156: char *short_h1 = 
 1157: "Source                 Destination            ";
 1158: 
 1159: /*
 1160: long header;
 1161:  source address                                destination address                           
 1162:  123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345 
 1163:  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
 1164: */
 1165: char *long_h1 = 
 1166: "Source                                        Destination                                  ";
 1167: 
 1168: 	printf("%s\n", long_format ? long_h1 : short_h1);
 1169: 
 1170: 	while (tlen > 0) {
 1171: 		iph2 = (struct ph2handle *)buf;
 1172: 		addr = (struct sockaddr *)(++iph2);
 1173: 
 1174: 		GETNAMEINFO(addr, _addr1_, _addr2_);
 1175: 		printf("%s ", long_format ?
 1176: 			  fixed_addr(_addr1_, _addr2_, 45)
 1177: 			: fixed_addr(_addr1_, _addr2_, 22));
 1178: 		addr++;
 1179: 		tlen -= sysdep_sa_len(addr);
 1180: 
 1181: 		GETNAMEINFO(addr, _addr1_, _addr2_);
 1182: 		printf("%s ", long_format ?
 1183: 			  fixed_addr(_addr1_, _addr2_, 45)
 1184: 			: fixed_addr(_addr1_, _addr2_, 22));
 1185: 		addr++;
 1186: 		tlen -= sysdep_sa_len(addr);
 1187: 
 1188: 		printf("\n");
 1189: 	}
 1190: 
 1191: 	return;
 1192: }
 1193: 
 1194: /* %%% */
 1195: char *
 1196: pindex_isakmp(index)
 1197: 	isakmp_index *index;
 1198: {
 1199: 	static char buf[64];
 1200: 	u_char *p;
 1201: 	int i, j;
 1202: 
 1203: 	memset(buf, 0, sizeof(buf));
 1204: 
 1205: 	/* copy index */
 1206: 	p = (u_char *)index;
 1207: 	for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
 1208: 		snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
 1209: 		j += 2;
 1210: 		switch (i) {
 1211: 		case 7:
 1212: #if 0
 1213: 		case 15:
 1214: #endif
 1215: 			buf[j++] = ':';
 1216: 		}
 1217: 	}
 1218: 
 1219: 	return buf;
 1220: }
 1221: 
 1222: /* print schedule */
 1223: char *str_sched_stat[] = {
 1224: "off",
 1225: "on",
 1226: "dead",
 1227: };
 1228: 
 1229: char *str_sched_id[] = {
 1230: "PH1resend",
 1231: "PH1lifetime",
 1232: "PH2resend",
 1233: "PSTacquire",
 1234: "PSTlifetime",
 1235: };
 1236: 
 1237: void
 1238: print_schedule(buf, len)
 1239: 	caddr_t buf;
 1240: 	int len;
 1241: {
 1242: 	struct scheddump *sc = (struct scheddump *)buf;
 1243: 	struct tm *tm;
 1244: 	char tbuf[56];
 1245: 
 1246: 	if (len % sizeof(*sc))
 1247: 		printf("invalid length %d\n", len);
 1248: 	len /= sizeof(*sc);
 1249: 
 1250: 	/*      00000000 00000000 00000000 xxx........*/
 1251: 	printf("index    tick     xtime    created\n");
 1252: 
 1253: 	while (len-- > 0) {
 1254: 		tm = localtime(&sc->created);
 1255: 		strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %T", tm);
 1256: 
 1257: 		printf("%-8ld %-8ld %-8ld %s\n",
 1258: 			sc->id,
 1259: 			(long)sc->tick,
 1260: 			(long)sc->xtime,
 1261: 			tbuf);
 1262: 		sc++;
 1263: 	}
 1264: 
 1265: 	return;
 1266: }
 1267: 
 1268: 
 1269: void
 1270: print_evt(evtdump)
 1271: 	struct evt_async *evtdump;
 1272: {
 1273: 	int i;
 1274: 	char *srcstr;
 1275: 	char *dststr;
 1276: 	
 1277: 	for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++)
 1278: 		if (evtmsg[i].type == evtdump->ec_type)
 1279: 			break;
 1280: 
 1281: 	if (evtmsg[i].msg == NULL)
 1282: 		printf("Event %d: ", evtdump->ec_type);
 1283: 	else
 1284: 		printf("%s : ", evtmsg[i].msg);
 1285: 
 1286: 	if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL)
 1287: 		printf("unknown");
 1288: 	else
 1289: 		printf("%s", srcstr);
 1290: 	printf(" -> ");
 1291: 	if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL)
 1292: 		printf("unknown");
 1293: 	else
 1294: 		printf("%s", dststr);
 1295: 	printf("\n");
 1296: }
 1297: 
 1298: /*
 1299:  * Print ISAKMP mode config info (IP and banner)
 1300:  */
 1301: void
 1302: print_cfg(buf, len)
 1303: 	caddr_t buf;
 1304: 	int len;
 1305: {
 1306: 	struct evt_async *evtdump = (struct evt_async *)buf;
 1307: 	struct isakmp_data *attr;
 1308: 	char *banner = NULL;
 1309: 	struct in_addr addr4;
 1310: 	
 1311: 	memset(&addr4, 0, sizeof(addr4));
 1312: 
 1313: 	if (evtdump->ec_type != EVT_PHASE1_MODE_CFG)
 1314: 		return;
 1315: 
 1316: 	len -= sizeof(*evtdump);
 1317: 	attr = (struct isakmp_data *)(evtdump + 1);
 1318: 
 1319: 	while (len > 0) {
 1320: 		if (len < sizeof(*attr)) {
 1321: 			printf("short attribute too short\n");
 1322: 			break;
 1323: 		}
 1324: 
 1325: 		if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
 1326: 			/* Short attribute, skip */
 1327: 			len -= sizeof(*attr);
 1328: 			attr++;
 1329: 		} else { /* Long attribute */
 1330: 			char *n;
 1331: 
 1332: 			if (len < (sizeof(*attr) + ntohs(attr->lorv))) {
 1333: 				printf("long attribute too long\n");
 1334: 				break;
 1335: 			}
 1336: 
 1337: 			switch (ntohs(attr->type) & ~ISAKMP_GEN_MASK) {
 1338: 			case INTERNAL_IP4_ADDRESS:
 1339: 				if (ntohs(attr->lorv) < sizeof(addr4)) {
 1340: 					printf("addr4 attribute too short\n");
 1341: 					break;
 1342: 				}
 1343: 				memcpy(&addr4, attr + 1, sizeof(addr4));
 1344: 				break;
 1345: 
 1346: 			case UNITY_BANNER:
 1347: 				banner = racoon_malloc(ntohs(attr->lorv) + 1);
 1348: 				if (banner == NULL) {
 1349: 					printf("malloc failed\n");
 1350: 					break;
 1351: 				}
 1352: 				memcpy(banner, attr + 1, ntohs(attr->lorv));
 1353: 				banner[ntohs(attr->lorv)] = '\0';
 1354: 				break;
 1355: 
 1356: 			default:
 1357: 				break;
 1358: 			}
 1359: 
 1360: 			len -= (sizeof(*attr) + ntohs(attr->lorv));
 1361: 			n = (char *)attr;
 1362: 			attr = (struct isakmp_data *)
 1363: 			    (n + sizeof(*attr) + ntohs(attr->lorv));
 1364: 		}
 1365: 	}
 1366: 
 1367: 	if (len > 0)
 1368: 		printf("Bound to address %s\n", inet_ntoa(addr4));
 1369: 	else
 1370: 		printf("VPN connexion established\n");
 1371: 
 1372: 	if (banner) {
 1373: 		struct winsize win;
 1374: 		int col = 0;
 1375: 		int i;
 1376: 
 1377: 		if (ioctl(1, TIOCGWINSZ, &win) != 1) 
 1378: 			col = win.ws_col;
 1379: 			
 1380: 		for (i = 0; i < col; i++)
 1381: 			printf("%c", '=');
 1382: 		printf("\n%s\n", banner);
 1383: 		for (i = 0; i < col; i++)
 1384: 			printf("%c", '=');
 1385: 		printf("\n");
 1386: 		racoon_free(banner);
 1387: 	}
 1388: }
 1389: 
 1390: 
 1391: char *
 1392: fixed_addr(addr, port, len)
 1393: 	char *addr, *port;
 1394: 	int len;
 1395: {
 1396: 	static char _addr_buf_[BUFSIZ];
 1397: 	char *p;
 1398: 	int plen, i;
 1399: 
 1400: 	/* initialize */
 1401: 	memset(_addr_buf_, ' ', sizeof(_addr_buf_));
 1402: 
 1403: 	plen = strlen(port);
 1404: 	if (len < plen + 1)
 1405: 		return NULL;
 1406: 
 1407: 	p = _addr_buf_;
 1408: 	for (i = 0; i < len - plen - 1 && addr[i] != '\0'; /*noting*/)
 1409: 		*p++ = addr[i++];
 1410: 	*p++ = '.';
 1411: 
 1412: 	for (i = 0; i < plen && port[i] != '\0'; /*noting*/)
 1413: 		*p++ = port[i++];
 1414: 
 1415: 	_addr_buf_[len] = '\0';
 1416: 
 1417: 	return _addr_buf_;
 1418: }
 1419: 
 1420: static int
 1421: handle_recv(combuf)
 1422: 	vchar_t *combuf;
 1423: {
 1424:         struct admin_com *com;
 1425:         caddr_t buf;
 1426:         int len;
 1427: 
 1428: 	com = (struct admin_com *)combuf->v;
 1429: 	if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY)
 1430: 		len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16);
 1431: 	else
 1432: 		len = com->ac_len;
 1433: 	len -= sizeof(*com);
 1434: 	buf = combuf->v + sizeof(*com);
 1435: 
 1436: 	switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) {
 1437: 	case ADMIN_SHOW_SCHED:
 1438: 		print_schedule(buf, len);
 1439: 		break;
 1440: 
 1441: 	case ADMIN_SHOW_EVT: {
 1442: 		struct evt_async *ec;
 1443: 
 1444: 		/* We got no event? */
 1445: 		if (len == 0)
 1446: 			break;
 1447: 
 1448: 		if (len < sizeof(struct evt_async))
 1449: 			errx(1, "Short buffer\n");
 1450: 
 1451: 		ec = (struct evt_async *) buf;
 1452: 		if (evt_quit_event <= 0)
 1453: 			print_evt(ec);
 1454: 		else if (evt_quit_event == ec->ec_type) {
 1455: 			switch (ec->ec_type) {
 1456: 			case EVT_PHASE1_MODE_CFG:
 1457: 				print_cfg(ec, len);
 1458: 				break;
 1459: 			default:
 1460: 				print_evt(ec);
 1461: 				break;
 1462: 			}
 1463: 			evt_quit_event = 0;
 1464: 		}
 1465: 		break;
 1466: 	}
 1467: 
 1468: 	case ADMIN_GET_SA_CERT:
 1469: 		fwrite(buf, len, 1, stdout);
 1470: 		break;
 1471: 
 1472: 	case ADMIN_SHOW_SA:
 1473: 	   {
 1474: 		switch (com->ac_proto) {
 1475: 		case ADMIN_PROTO_ISAKMP:
 1476: 			dump_isakmp_sa(buf, len);
 1477: 			break;
 1478: 		case ADMIN_PROTO_IPSEC:
 1479: 		case ADMIN_PROTO_AH:
 1480: 		case ADMIN_PROTO_ESP:
 1481: 		    {
 1482: 			struct sadb_msg *msg = (struct sadb_msg *)buf;
 1483: 
 1484: 			switch (msg->sadb_msg_errno) {
 1485: 			case ENOENT:
 1486: 				switch (msg->sadb_msg_type) {
 1487: 				case SADB_DELETE:
 1488: 				case SADB_GET:
 1489: 					printf("No entry.\n");
 1490: 					break;
 1491: 				case SADB_DUMP:
 1492: 					printf("No SAD entries.\n");
 1493: 					break;
 1494: 				}
 1495: 				break;
 1496: 			case 0:
 1497: 				while (1) {
 1498: 					pfkey_sadump(msg);
 1499: 					if (msg->sadb_msg_seq == 0)
 1500: 						break;
 1501: 					msg = (struct sadb_msg *)((caddr_t)msg +
 1502: 						     PFKEY_UNUNIT64(msg->sadb_msg_len));
 1503: 				}
 1504: 				break;
 1505: 			default:
 1506: 				printf("%s.\n", strerror(msg->sadb_msg_errno));
 1507: 			}
 1508: 		    }
 1509: 			break;
 1510: 		case ADMIN_PROTO_INTERNAL:
 1511: 			dump_internal(buf, len);
 1512: 			break;
 1513: 		default:
 1514: 			printf("Invalid proto [%d]\n", com->ac_proto);
 1515: 		}
 1516: 
 1517: 	    }
 1518: 		break;
 1519: 
 1520: 	default:
 1521: 		/* IGNORE */
 1522: 		break;
 1523: 	}
 1524: 
 1525: 	return 0;
 1526: 
 1527: bad:
 1528: 	return -1;
 1529: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>