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