Return to racoonctl.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
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: }