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