Annotation of embedaddon/ipsec-tools/src/racoon/racoonctl.c, revision 1.1
1.1 ! misho 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>