17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50f2065ccSmarkfen  * Common Development and Distribution License (the "License").
60f2065ccSmarkfen  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  *
215d01c172SVladimir Kotal  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate #include <unistd.h>
257c478bd9Sstevel@tonic-gate #include <stdio.h>
267c478bd9Sstevel@tonic-gate #include <stdarg.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <sys/sysconf.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <strings.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <ctype.h>
347c478bd9Sstevel@tonic-gate #include <time.h>
357c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include <sys/mman.h>
387c478bd9Sstevel@tonic-gate #include <fcntl.h>
397c478bd9Sstevel@tonic-gate #include <sys/socket.h>
407c478bd9Sstevel@tonic-gate #include <netdb.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <assert.h>
437c478bd9Sstevel@tonic-gate #include <netinet/in.h>
447c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
457c478bd9Sstevel@tonic-gate #include <door.h>
467c478bd9Sstevel@tonic-gate #include <setjmp.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #include <ipsec_util.h>
497c478bd9Sstevel@tonic-gate #include <ikedoor.h>
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate static int	doorfd = -1;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate  * These are additional return values for the command line parsing
557c478bd9Sstevel@tonic-gate  * function (parsecmd()).  They are specific to this utility, but
567c478bd9Sstevel@tonic-gate  * need to share the same space as the IKE_SVC_* defs, without conflicts.
577c478bd9Sstevel@tonic-gate  * So they're defined relative to the end of that range.
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_GENERAL	IKE_SVC_MAX + 1
607c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_GET		IKE_SVC_MAX + 2
617c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_SET		IKE_SVC_MAX + 3
627c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_ADD		IKE_SVC_MAX + 4
637c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_DEL		IKE_SVC_MAX + 5
647c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_DUMP	IKE_SVC_MAX + 6
657c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_FLUSH	IKE_SVC_MAX + 7
667c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_READ	IKE_SVC_MAX + 8
677c478bd9Sstevel@tonic-gate #define	IKEADM_HELP_WRITE	IKE_SVC_MAX + 9
68c7777ac8SPaul Wernau #define	IKEADM_HELP_TOKEN	IKE_SVC_MAX + 10
69c7777ac8SPaul Wernau #define	IKEADM_HELP_HELP	IKE_SVC_MAX + 11
70c7777ac8SPaul Wernau #define	IKEADM_EXIT		IKE_SVC_MAX + 12
717c478bd9Sstevel@tonic-gate 
72bfe6f8f5SVladimir Kotal /*
73bfe6f8f5SVladimir Kotal  * Disable default TAB completion for now (until some brave soul tackles it).
74bfe6f8f5SVladimir Kotal  */
75bfe6f8f5SVladimir Kotal /* ARGSUSED */
76bfe6f8f5SVladimir Kotal static
CPL_MATCH_FN(no_match)77bfe6f8f5SVladimir Kotal CPL_MATCH_FN(no_match)
78bfe6f8f5SVladimir Kotal {
79bfe6f8f5SVladimir Kotal 	return (0);
80bfe6f8f5SVladimir Kotal }
81bfe6f8f5SVladimir Kotal 
820fddcadbSToomas Soome static void command_complete(int s) __NORETURN;
830fddcadbSToomas Soome static void usage(void) __NORETURN;
840fddcadbSToomas Soome 
857c478bd9Sstevel@tonic-gate static void
command_complete(int s)867c478bd9Sstevel@tonic-gate command_complete(int s)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	if (interactive) {
897c478bd9Sstevel@tonic-gate 		longjmp(env, 1);
907c478bd9Sstevel@tonic-gate 	} else {
917c478bd9Sstevel@tonic-gate 		exit(s);
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate static void
usage(void)960fddcadbSToomas Soome usage(void)
977c478bd9Sstevel@tonic-gate {
987c478bd9Sstevel@tonic-gate 	if (!interactive) {
997c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Usage:\t"
1007c478bd9Sstevel@tonic-gate 		    "ikeadm [ -hnp ] cmd obj [cmd-specific options]\n"));
1017c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("      \tikeadm help\n"));
102bfe6f8f5SVladimir Kotal 	} else {
103bfe6f8f5SVladimir Kotal 		(void) fprintf(stderr,
104bfe6f8f5SVladimir Kotal 		    gettext("\nType help for usage info\n"));
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	command_complete(1);
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate static void
print_help()1117c478bd9Sstevel@tonic-gate print_help()
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Valid commands and objects:\n"));
1140f2065ccSmarkfen 	(void) printf(
1150f2065ccSmarkfen 	    "\tget   debug|priv|stats|p1|rule|preshared|defaults [%s]\n",
1167c478bd9Sstevel@tonic-gate 	    gettext("identifier"));
1177c478bd9Sstevel@tonic-gate 	(void) printf("\tset   priv %s\n", gettext("level"));
1187c478bd9Sstevel@tonic-gate 	(void) printf("\tset   debug %s [%s]\n",
1197c478bd9Sstevel@tonic-gate 	    gettext("level"), gettext("filename"));
1207c478bd9Sstevel@tonic-gate 	(void) printf("\tadd   rule|preshared {%s}|%s\n",
1217c478bd9Sstevel@tonic-gate 	    gettext("definition"), gettext("filename"));
1227c478bd9Sstevel@tonic-gate 	(void) printf("\tdel   p1|rule|preshared %s\n", gettext("identifier"));
1235d01c172SVladimir Kotal 	(void) printf("\tdump  p1|rule|preshared|certcache|groups|"
1245d01c172SVladimir Kotal 	    "encralgs|authalgs\n");
125c7777ac8SPaul Wernau 	(void) printf("\tflush p1|certcache\n");
1267c478bd9Sstevel@tonic-gate 	(void) printf("\tread  rule|preshared [%s]\n", gettext("filename"));
1277c478bd9Sstevel@tonic-gate 	(void) printf("\twrite rule|preshared %s\n", gettext("filename"));
128c7777ac8SPaul Wernau 	(void) printf("\ttoken <login|logout> %s\n",
129c7777ac8SPaul Wernau 	    gettext("<PKCS#11 Token Object>"));
1307c478bd9Sstevel@tonic-gate 	(void) printf(
131c7777ac8SPaul Wernau 	    "\thelp  [get|set|add|del|dump|flush|read|write|token|help]\n");
1327c478bd9Sstevel@tonic-gate 	(void) printf("\texit  %s\n", gettext("exit the program"));
1337c478bd9Sstevel@tonic-gate 	(void) printf("\tquit  %s\n", gettext("exit the program"));
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	command_complete(0);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate static void
print_get_help()1397c478bd9Sstevel@tonic-gate print_get_help()
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate 	(void) printf(
1427c478bd9Sstevel@tonic-gate 	    gettext("This command gets information from in.iked.\n\n"));
1437c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Objects that may be retrieved include:\n"));
1447c478bd9Sstevel@tonic-gate 	(void) printf("\tdebug\t\t");
1457c478bd9Sstevel@tonic-gate 	(void) printf(gettext("the current debug level\n"));
1467c478bd9Sstevel@tonic-gate 	(void) printf("\tpriv\t\t");
1477c478bd9Sstevel@tonic-gate 	(void) printf(gettext("the current privilege level\n"));
1487c478bd9Sstevel@tonic-gate 	(void) printf("\tstats\t\t");
1497c478bd9Sstevel@tonic-gate 	(void) printf(gettext("current usage statistics\n"));
1507c478bd9Sstevel@tonic-gate 	(void) printf("\tp1\t\t");
1517c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a phase 1 SA, identified by\n"));
1527c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_ip remote_ip OR\n"));
1537c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  init_cookie resp_cookie\n"));
1547c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
1557c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a phase 1 rule, identified by its label\n"));
1567c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
1577c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a preshared key, identified by\n"));
1587c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_ip remote_ip OR\n"));
1597c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_id remote_id\n"));
1607c478bd9Sstevel@tonic-gate 	(void) printf("\n");
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	command_complete(0);
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate static void
print_set_help()1667c478bd9Sstevel@tonic-gate print_set_help()
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate 	(void) printf(gettext("This command sets values in in.iked.\n\n"));
1697c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Objects that may be set include:\n"));
1707c478bd9Sstevel@tonic-gate 	(void) printf("\tdebug\t\t");
1717c478bd9Sstevel@tonic-gate 	(void) printf(gettext("change the debug level\n"));
1727c478bd9Sstevel@tonic-gate 	(void) printf("\tpriv\t\t");
1737c478bd9Sstevel@tonic-gate 	(void) printf(
1747c478bd9Sstevel@tonic-gate 	    gettext("change the privilege level (may only be lowered)\n"));
1757c478bd9Sstevel@tonic-gate 	(void) printf("\n");
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	command_complete(0);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate static void
print_add_help()1817c478bd9Sstevel@tonic-gate print_add_help()
1827c478bd9Sstevel@tonic-gate {
1837c478bd9Sstevel@tonic-gate 	(void) printf(
1847c478bd9Sstevel@tonic-gate 	    gettext("This command adds items to in.iked's tables.\n\n"));
1857c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Objects that may be set include:\n"));
1867c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
1877c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a phase 1 policy rule\n"));
1887c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
1897c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a preshared key\n"));
1907c478bd9Sstevel@tonic-gate 	(void) printf(
1917c478bd9Sstevel@tonic-gate 	    gettext("\nObjects may be entered on the command-line, as a\n"));
1927c478bd9Sstevel@tonic-gate 	(void) printf(
1937c478bd9Sstevel@tonic-gate 	    gettext("series of keywords and tokens contained in curly\n"));
1947c478bd9Sstevel@tonic-gate 	(void) printf(
1957c478bd9Sstevel@tonic-gate 	    gettext("braces ('{', '}'); or the name of a file containing\n"));
1967c478bd9Sstevel@tonic-gate 	(void) printf(gettext("the object definition may be provided.\n\n"));
1977c478bd9Sstevel@tonic-gate 	(void) printf(
1987c478bd9Sstevel@tonic-gate 	    gettext("For security purposes, preshared keys may only be\n"));
1997c478bd9Sstevel@tonic-gate 	(void) printf(
2007c478bd9Sstevel@tonic-gate 	    gettext("entered on the command-line if ikeadm is running in\n"));
2017c478bd9Sstevel@tonic-gate 	(void) printf(gettext("interactive mode.\n"));
2027c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	command_complete(0);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate static void
print_del_help()2087c478bd9Sstevel@tonic-gate print_del_help()
2097c478bd9Sstevel@tonic-gate {
2107c478bd9Sstevel@tonic-gate 	(void) printf(
2117c478bd9Sstevel@tonic-gate 	    gettext("This command deletes an item from in.iked's tables.\n\n"));
2127c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Objects that may be deleted include:\n"));
2137c478bd9Sstevel@tonic-gate 	(void) printf("\tp1\t\t");
2147c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a phase 1 SA, identified by\n"));
2157c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_ip remote_ip OR\n"));
2167c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  init_cookie resp_cookie\n"));
2177c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
2187c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a phase 1 rule, identified by its label\n"));
2197c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
2207c478bd9Sstevel@tonic-gate 	(void) printf(gettext("a preshared key, identified by\n"));
2217c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_ip remote_ip OR\n"));
2227c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\t\t\t  local_id remote_id\n"));
2237c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	command_complete(0);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate static void
print_dump_help()2297c478bd9Sstevel@tonic-gate print_dump_help()
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate 	(void) printf(
2327c478bd9Sstevel@tonic-gate 	    gettext("This command dumps one of in.iked's tables.\n\n"));
2337c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Tables that may be dumped include:\n"));
2347c478bd9Sstevel@tonic-gate 	(void) printf("\tp1\t\t");
2357c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all phase 1 SAs\n"));
2367c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
2377c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all phase 1 rules\n"));
2387c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
2397c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all preshared keys\n"));
240c7777ac8SPaul Wernau 	(void) printf("\tcertcache\t");
241c7777ac8SPaul Wernau 	(void) printf(gettext("all cached certificates\n"));
2425d01c172SVladimir Kotal 	(void) printf("\tgroups\t\t");
2435d01c172SVladimir Kotal 	(void) printf(gettext("all implemented Diffie-Hellman groups\n"));
2445d01c172SVladimir Kotal 	(void) printf("\tencralgs\t");
2455d01c172SVladimir Kotal 	(void) printf(gettext("all encryption algorithms for IKE\n"));
2465d01c172SVladimir Kotal 	(void) printf("\tauthalgs\t");
2475d01c172SVladimir Kotal 	(void) printf(gettext("all authentication algorithms IKE\n"));
2487c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	command_complete(0);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate static void
print_flush_help()2547c478bd9Sstevel@tonic-gate print_flush_help()
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate 	(void) printf(
2577c478bd9Sstevel@tonic-gate 	    gettext("This command clears one of in.iked's tables.\n\n"));
2587c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Tables that may be flushed include:\n"));
2597c478bd9Sstevel@tonic-gate 	(void) printf("\tp1\t\t");
2607c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all phase 1 SAs\n"));
261c7777ac8SPaul Wernau 	(void) printf("\tcertcache\t");
262c7777ac8SPaul Wernau 	(void) printf(gettext("all cached certificates\n"));
2637c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	command_complete(0);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate static void
print_read_help()2697c478bd9Sstevel@tonic-gate print_read_help()
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate 	(void) printf(
2727c478bd9Sstevel@tonic-gate 	    gettext("This command reads a new configuration file into\n"));
2737c478bd9Sstevel@tonic-gate 	(void) printf(
2747c478bd9Sstevel@tonic-gate 	    gettext("in.iked, discarding the old configuration info.\n\n"));
2757c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Sets of data that may be read include:\n"));
2767c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
2777c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all phase 1 rules\n"));
2787c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
2797c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all preshared keys\n\n"));
2807c478bd9Sstevel@tonic-gate 	(void) printf(
2817c478bd9Sstevel@tonic-gate 	    gettext("A filename may be provided to specify a source file\n"));
2827c478bd9Sstevel@tonic-gate 	(void) printf(gettext("other than the default.\n"));
2837c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	command_complete(0);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate static void
print_write_help()2897c478bd9Sstevel@tonic-gate print_write_help()
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate 	(void) printf(
2927c478bd9Sstevel@tonic-gate 	    gettext("This command writes in.iked's current configuration\n"));
2937c478bd9Sstevel@tonic-gate 	(void) printf(gettext("out to a config file.\n\n"));
2947c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Sets of data that may be written include:\n"));
2957c478bd9Sstevel@tonic-gate 	(void) printf("\trule\t\t");
2967c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all phase 1 rules\n"));
2977c478bd9Sstevel@tonic-gate 	(void) printf("\tpreshared\t");
2987c478bd9Sstevel@tonic-gate 	(void) printf(gettext("all preshared keys\n\n"));
2997c478bd9Sstevel@tonic-gate 	(void) printf(
3007c478bd9Sstevel@tonic-gate 	    gettext("A filename must be provided to specify the file to\n"));
3017c478bd9Sstevel@tonic-gate 	(void) printf(gettext("which the information should be written.\n"));
3027c478bd9Sstevel@tonic-gate 	(void) printf("\n");
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	command_complete(0);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
307c7777ac8SPaul Wernau static void
print_token_help()308c7777ac8SPaul Wernau print_token_help()
309c7777ac8SPaul Wernau {
310c7777ac8SPaul Wernau 	(void) printf(gettext(
311c7777ac8SPaul Wernau 	    "This command logs IKE into and out of PKCS#11 tokens.\n\n"));
312c7777ac8SPaul Wernau 	(void) printf(gettext("Commands include:\n"));
313c7777ac8SPaul Wernau 	(void) printf("\tlogin <PKCS#11 Token Object>\t");
314c7777ac8SPaul Wernau 	(void) printf(gettext("log into token\n"));
315c7777ac8SPaul Wernau 	(void) printf("\tlogout <PKCS#11 Token Object>\t");
316c7777ac8SPaul Wernau 	(void) printf(gettext("log out of token\n\n"));
317c7777ac8SPaul Wernau 	(void) printf(
318c7777ac8SPaul Wernau 	    gettext("The PKCS#11 Token Object name must be "
319c7777ac8SPaul Wernau 	    "enclosed in quotation marks.\n"));
320c7777ac8SPaul Wernau 	(void) printf("\n");
321c7777ac8SPaul Wernau 
322c7777ac8SPaul Wernau 	command_complete(0);
323c7777ac8SPaul Wernau }
324c7777ac8SPaul Wernau 
3257c478bd9Sstevel@tonic-gate static void
print_help_help()3267c478bd9Sstevel@tonic-gate print_help_help()
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate 	(void) printf(
3297c478bd9Sstevel@tonic-gate 	    gettext("This command provides information about commands.\n\n"));
3307c478bd9Sstevel@tonic-gate 	(void) printf(
3317c478bd9Sstevel@tonic-gate 	    gettext("The 'help' command alone provides a list of valid\n"));
3327c478bd9Sstevel@tonic-gate 	(void) printf(
3337c478bd9Sstevel@tonic-gate 	    gettext("commands, along with the valid objects for each.\n"));
3347c478bd9Sstevel@tonic-gate 	(void) printf(
3357c478bd9Sstevel@tonic-gate 	    gettext("'help' followed by a valid command name provides\n"));
3367c478bd9Sstevel@tonic-gate 	(void) printf(gettext("further information about that command.\n"));
3377c478bd9Sstevel@tonic-gate 	(void) printf("\n");
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	command_complete(0);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
3437c478bd9Sstevel@tonic-gate static void
message(char * fmt,...)3447c478bd9Sstevel@tonic-gate message(char *fmt, ...)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate 	va_list	ap;
3477c478bd9Sstevel@tonic-gate 	char	msgbuf[BUFSIZ];
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
3507c478bd9Sstevel@tonic-gate 	(void) vsnprintf(msgbuf, BUFSIZ, fmt, ap);
3517c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("ikeadm: %s\n"), msgbuf);
3527c478bd9Sstevel@tonic-gate 	va_end(ap);
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate static int
open_door(void)3567c478bd9Sstevel@tonic-gate open_door(void)
3577c478bd9Sstevel@tonic-gate {
3587c478bd9Sstevel@tonic-gate 	if (doorfd >= 0)
3597c478bd9Sstevel@tonic-gate 		(void) close(doorfd);
360c7777ac8SPaul Wernau 	doorfd = open(DOORNM, O_RDONLY);
3617c478bd9Sstevel@tonic-gate 	return (doorfd);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate static ike_service_t *
ikedoor_call(char * reqp,int size,door_desc_t * descp,int ndesc)3657c478bd9Sstevel@tonic-gate ikedoor_call(char *reqp, int size, door_desc_t *descp, int ndesc)
3667c478bd9Sstevel@tonic-gate {
3677c478bd9Sstevel@tonic-gate 	door_arg_t	arg;
3687c478bd9Sstevel@tonic-gate 	int retries = 0;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	arg.data_ptr = reqp;
3717c478bd9Sstevel@tonic-gate 	arg.data_size = size;
3727c478bd9Sstevel@tonic-gate 	arg.desc_ptr = descp;
3737c478bd9Sstevel@tonic-gate 	arg.desc_num = ndesc;
3747c478bd9Sstevel@tonic-gate 	arg.rbuf = (char *)NULL;
3757c478bd9Sstevel@tonic-gate 	arg.rsize = 0;
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate retry:
3787c478bd9Sstevel@tonic-gate 	if (door_call(doorfd, &arg) < 0) {
3797c478bd9Sstevel@tonic-gate 		if ((errno == EBADF) && ((++retries < 2) &&
3807c478bd9Sstevel@tonic-gate 		    (open_door() >= 0)))
3817c478bd9Sstevel@tonic-gate 			goto retry;
382c8393ed7Smarkfen 		(void) fprintf(stderr,
383c8393ed7Smarkfen 		    gettext("Unable to communicate with in.iked\n"));
3847c478bd9Sstevel@tonic-gate 		Bail("door_call failed");
3857c478bd9Sstevel@tonic-gate 	}
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	if ((ndesc > 0) && (descp->d_attributes & DOOR_RELEASE) &&
3887c478bd9Sstevel@tonic-gate 	    ((errno == EBADF) || (errno == EFAULT))) {
3897c478bd9Sstevel@tonic-gate 		/* callers assume passed fds will be closed no matter what */
3907c478bd9Sstevel@tonic-gate 		(void) close(descp->d_data.d_desc.d_descriptor);
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	/* LINTED E_BAD_PTR_CAST_ALIGN */
3947c478bd9Sstevel@tonic-gate 	return ((ike_service_t *)arg.rbuf);
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate /*
3987c478bd9Sstevel@tonic-gate  * Parsing functions
3997c478bd9Sstevel@tonic-gate  */
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /* stolen from ipseckey.c, with a second tier added */
4027c478bd9Sstevel@tonic-gate static int
parsecmd(char * cmdstr,char * objstr)4037c478bd9Sstevel@tonic-gate parsecmd(char *cmdstr, char *objstr)
4047c478bd9Sstevel@tonic-gate {
405c7777ac8SPaul Wernau #define	MAXOBJS		11
406c8393ed7Smarkfen 	struct objtbl {
4077c478bd9Sstevel@tonic-gate 		char	*obj;
4087c478bd9Sstevel@tonic-gate 		int	token;
4097c478bd9Sstevel@tonic-gate 	};
4107c478bd9Sstevel@tonic-gate 	static struct cmdtbl {
4117c478bd9Sstevel@tonic-gate 		char		*cmd;
4127c478bd9Sstevel@tonic-gate 		int		null_obj_token;
4137c478bd9Sstevel@tonic-gate 		struct objtbl	objt[MAXOBJS];
4147c478bd9Sstevel@tonic-gate 	} table[] = {
4157c478bd9Sstevel@tonic-gate 		{"get", IKE_SVC_ERROR, {
4167c478bd9Sstevel@tonic-gate 				{"debug",	IKE_SVC_GET_DBG},
4177c478bd9Sstevel@tonic-gate 				{"priv",	IKE_SVC_GET_PRIV},
4187c478bd9Sstevel@tonic-gate 				{"stats",	IKE_SVC_GET_STATS},
4197c478bd9Sstevel@tonic-gate 				{"p1",		IKE_SVC_GET_P1},
4207c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_GET_RULE},
4217c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_GET_PS},
4220f2065ccSmarkfen 				{"defaults",	IKE_SVC_GET_DEFS},
4234b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4247c478bd9Sstevel@tonic-gate 			}
4257c478bd9Sstevel@tonic-gate 		},
4267c478bd9Sstevel@tonic-gate 		{"set", IKE_SVC_ERROR, {
4277c478bd9Sstevel@tonic-gate 				{"debug",	IKE_SVC_SET_DBG},
4287c478bd9Sstevel@tonic-gate 				{"priv",	IKE_SVC_SET_PRIV},
4294b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4307c478bd9Sstevel@tonic-gate 			}
4317c478bd9Sstevel@tonic-gate 		},
432c7777ac8SPaul Wernau 		{"token", IKE_SVC_ERROR, {
433c7777ac8SPaul Wernau 				{"login",	IKE_SVC_SET_PIN},
434c7777ac8SPaul Wernau 				{"logout",	IKE_SVC_DEL_PIN},
435c7777ac8SPaul Wernau 				{NULL,		IKE_SVC_ERROR},
436c7777ac8SPaul Wernau 			}
437c7777ac8SPaul Wernau 		},
4387c478bd9Sstevel@tonic-gate 		{"add", IKE_SVC_ERROR, {
4397c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_NEW_RULE},
4407c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_NEW_PS},
4414b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4427c478bd9Sstevel@tonic-gate 			}
4437c478bd9Sstevel@tonic-gate 		},
4447c478bd9Sstevel@tonic-gate 		{"del", IKE_SVC_ERROR, {
4457c478bd9Sstevel@tonic-gate 				{"p1",		IKE_SVC_DEL_P1},
4467c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_DEL_RULE},
4477c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_DEL_PS},
4484b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4497c478bd9Sstevel@tonic-gate 			}
4507c478bd9Sstevel@tonic-gate 		},
4517c478bd9Sstevel@tonic-gate 		{"dump", IKE_SVC_ERROR, {
4527c478bd9Sstevel@tonic-gate 				{"p1",		IKE_SVC_DUMP_P1S},
4537c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_DUMP_RULES},
4547c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_DUMP_PS},
455c7777ac8SPaul Wernau 				{"certcache",	IKE_SVC_DUMP_CERTCACHE},
4565d01c172SVladimir Kotal 				{"groups",	IKE_SVC_DUMP_GROUPS},
4575d01c172SVladimir Kotal 				{"encralgs",	IKE_SVC_DUMP_ENCRALGS},
4585d01c172SVladimir Kotal 				{"authalgs",	IKE_SVC_DUMP_AUTHALGS},
4594b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4607c478bd9Sstevel@tonic-gate 			}
4617c478bd9Sstevel@tonic-gate 		},
4627c478bd9Sstevel@tonic-gate 		{"flush", IKE_SVC_ERROR, {
4637c478bd9Sstevel@tonic-gate 				{"p1",		IKE_SVC_FLUSH_P1S},
464c7777ac8SPaul Wernau 				{"certcache",	IKE_SVC_FLUSH_CERTCACHE},
4654b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4667c478bd9Sstevel@tonic-gate 			}
4677c478bd9Sstevel@tonic-gate 		},
4687c478bd9Sstevel@tonic-gate 		{"read", IKE_SVC_ERROR, {
4697c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_READ_RULES},
4707c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_READ_PS},
4714b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4727c478bd9Sstevel@tonic-gate 			}
4737c478bd9Sstevel@tonic-gate 		},
4747c478bd9Sstevel@tonic-gate 		{"write", IKE_SVC_ERROR, {
4757c478bd9Sstevel@tonic-gate 				{"rule",	IKE_SVC_WRITE_RULES},
4767c478bd9Sstevel@tonic-gate 				{"preshared",	IKE_SVC_WRITE_PS},
4774b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4787c478bd9Sstevel@tonic-gate 			}
4797c478bd9Sstevel@tonic-gate 		},
4807c478bd9Sstevel@tonic-gate 		{"help", IKEADM_HELP_GENERAL, {
4817c478bd9Sstevel@tonic-gate 				{"get",		IKEADM_HELP_GET},
4827c478bd9Sstevel@tonic-gate 				{"set",		IKEADM_HELP_SET},
4837c478bd9Sstevel@tonic-gate 				{"add",		IKEADM_HELP_ADD},
4847c478bd9Sstevel@tonic-gate 				{"del",		IKEADM_HELP_DEL},
4857c478bd9Sstevel@tonic-gate 				{"dump",	IKEADM_HELP_DUMP},
4867c478bd9Sstevel@tonic-gate 				{"flush",	IKEADM_HELP_FLUSH},
4877c478bd9Sstevel@tonic-gate 				{"read",	IKEADM_HELP_READ},
4887c478bd9Sstevel@tonic-gate 				{"write",	IKEADM_HELP_WRITE},
489c7777ac8SPaul Wernau 				{"token",	IKEADM_HELP_TOKEN},
4907c478bd9Sstevel@tonic-gate 				{"help",	IKEADM_HELP_HELP},
4914b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4927c478bd9Sstevel@tonic-gate 			}
4937c478bd9Sstevel@tonic-gate 		},
4947c478bd9Sstevel@tonic-gate 		{"exit", IKEADM_EXIT, {
4954b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
4967c478bd9Sstevel@tonic-gate 			}
4977c478bd9Sstevel@tonic-gate 		},
4987c478bd9Sstevel@tonic-gate 		{"quit", IKEADM_EXIT, {
4994b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
5007c478bd9Sstevel@tonic-gate 			}
5017c478bd9Sstevel@tonic-gate 		},
5027c478bd9Sstevel@tonic-gate 		{"dbg", IKE_SVC_ERROR, {
5037c478bd9Sstevel@tonic-gate 				{"rbdump",	IKE_SVC_DBG_RBDUMP},
5044b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
5057c478bd9Sstevel@tonic-gate 			}
5067c478bd9Sstevel@tonic-gate 		},
5077c478bd9Sstevel@tonic-gate 		{NULL,	IKE_SVC_ERROR, {
5084b56a003SDaniel Anderson 				{NULL,		IKE_SVC_ERROR}
5097c478bd9Sstevel@tonic-gate 			}
5104b56a003SDaniel Anderson 		}
5117c478bd9Sstevel@tonic-gate 	};
5127c478bd9Sstevel@tonic-gate 	struct cmdtbl	*ct = table;
5137c478bd9Sstevel@tonic-gate 	struct objtbl	*ot;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	if (cmdstr == NULL) {
5167c478bd9Sstevel@tonic-gate 		return (IKE_SVC_ERROR);
5177c478bd9Sstevel@tonic-gate 	}
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 	while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0)
5207c478bd9Sstevel@tonic-gate 		ct++;
5217c478bd9Sstevel@tonic-gate 	ot = ct->objt;
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	if (ct->cmd == NULL) {
5247c478bd9Sstevel@tonic-gate 		message(gettext("Unrecognized command '%s'"), cmdstr);
5257c478bd9Sstevel@tonic-gate 		return (ot->token);
5267c478bd9Sstevel@tonic-gate 	}
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	if (objstr == NULL) {
5297c478bd9Sstevel@tonic-gate 		return (ct->null_obj_token);
5307c478bd9Sstevel@tonic-gate 	}
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 	while (ot->obj != NULL && strcmp(ot->obj, objstr) != 0)
5337c478bd9Sstevel@tonic-gate 		ot++;
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	if (ot->obj == NULL)
5367c478bd9Sstevel@tonic-gate 		message(gettext("Unrecognized object '%s'"), objstr);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	return (ot->token);
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate  * Parsing functions:
5437c478bd9Sstevel@tonic-gate  * Parse command-line identification info.  All return -1 on failure,
5447c478bd9Sstevel@tonic-gate  * or the number of cmd-line args "consumed" on success (though argc
5457c478bd9Sstevel@tonic-gate  * and argv params are not actually modified).
5467c478bd9Sstevel@tonic-gate  */
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate static int
parse_label(int argc,char ** argv,char * label)5497c478bd9Sstevel@tonic-gate parse_label(int argc, char **argv, char *label)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	if ((argc < 1) || (argv == NULL))
5527c478bd9Sstevel@tonic-gate 		return (-1);
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	if (strlcpy(label, argv[0], MAX_LABEL_LEN) >= MAX_LABEL_LEN)
5557c478bd9Sstevel@tonic-gate 		return (-1);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	return (1);
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate 
560c7777ac8SPaul Wernau /*
561c7777ac8SPaul Wernau  * Parse a PKCS#11 token get the label.
562c7777ac8SPaul Wernau  */
563c7777ac8SPaul Wernau static int
parse_token(int argc,char ** argv,char * token_label)564c7777ac8SPaul Wernau parse_token(int argc, char **argv, char *token_label)
565c7777ac8SPaul Wernau {
566c7777ac8SPaul Wernau 	if ((argc < 1) || (argv == NULL))
567c7777ac8SPaul Wernau 		return (-1);
568c7777ac8SPaul Wernau 
569c7777ac8SPaul Wernau 	if (strlcpy(token_label, argv[0], PKCS11_TOKSIZE) >= PKCS11_TOKSIZE)
570c7777ac8SPaul Wernau 		return (-1);
571c7777ac8SPaul Wernau 
572c7777ac8SPaul Wernau 	return (0);
573c7777ac8SPaul Wernau }
574c7777ac8SPaul Wernau 
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate  * Parse an address off the command line. In the hpp param, either
5777c478bd9Sstevel@tonic-gate  * return a hostent pointer (caller frees) or a pointer to a dummy_he_t
5787c478bd9Sstevel@tonic-gate  * (must also be freed by the caller; both cases are handled by the
5797c478bd9Sstevel@tonic-gate  * macro FREE_HE).  The new getipnodebyname() call does the Right Thing
5807c478bd9Sstevel@tonic-gate  * (TM), even with raw addresses (colon-separated IPv6 or dotted decimal
5817c478bd9Sstevel@tonic-gate  * IPv4).
5827c478bd9Sstevel@tonic-gate  * (mostly stolen from ipseckey.c, though some tweaks were made
5837c478bd9Sstevel@tonic-gate  * to better serve our purposes here.)
5847c478bd9Sstevel@tonic-gate  */
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate typedef struct {
5877c478bd9Sstevel@tonic-gate 	struct hostent	he;
5887c478bd9Sstevel@tonic-gate 	char		*addtl[2];
5897c478bd9Sstevel@tonic-gate } dummy_he_t;
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate static int
parse_addr(int argc,char ** argv,struct hostent ** hpp)5927c478bd9Sstevel@tonic-gate parse_addr(int argc, char **argv, struct hostent **hpp)
5937c478bd9Sstevel@tonic-gate {
5947c478bd9Sstevel@tonic-gate 	int		hp_errno;
5957c478bd9Sstevel@tonic-gate 	struct hostent	*hp = NULL;
5967c478bd9Sstevel@tonic-gate 	dummy_he_t	*dhp;
5977c478bd9Sstevel@tonic-gate 	char		*addr1;
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	if ((argc < 1) || (argv == NULL) || (argv[0] == NULL))
6007c478bd9Sstevel@tonic-gate 		return (-1);
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	if (!nflag) {
6037c478bd9Sstevel@tonic-gate 		/*
6047c478bd9Sstevel@tonic-gate 		 * Try name->address first.  Assume AF_INET6, and
6057c478bd9Sstevel@tonic-gate 		 * get IPV4s, plus IPv6s iff IPv6 is configured.
6067c478bd9Sstevel@tonic-gate 		 */
6077c478bd9Sstevel@tonic-gate 		hp = getipnodebyname(argv[0], AF_INET6, AI_DEFAULT | AI_ALL,
6087c478bd9Sstevel@tonic-gate 		    &hp_errno);
6097c478bd9Sstevel@tonic-gate 	} else {
6107c478bd9Sstevel@tonic-gate 		/*
6117c478bd9Sstevel@tonic-gate 		 * Try a normal address conversion only.  malloc a
6127c478bd9Sstevel@tonic-gate 		 * dummy_he_t to construct a fake hostent.  Caller
6137c478bd9Sstevel@tonic-gate 		 * will know to free this one using free_he().
6147c478bd9Sstevel@tonic-gate 		 */
6157c478bd9Sstevel@tonic-gate 		dhp = (dummy_he_t *)malloc(sizeof (dummy_he_t));
6167c478bd9Sstevel@tonic-gate 		addr1 = (char *)malloc(sizeof (struct in6_addr));
6177c478bd9Sstevel@tonic-gate 		if (inet_pton(AF_INET6, argv[0], addr1) == 1) {
6187c478bd9Sstevel@tonic-gate 			dhp->he.h_addr_list = dhp->addtl;
6197c478bd9Sstevel@tonic-gate 			dhp->addtl[0] = addr1;
6207c478bd9Sstevel@tonic-gate 			dhp->addtl[1] = NULL;
6217c478bd9Sstevel@tonic-gate 			hp = &dhp->he;
6227c478bd9Sstevel@tonic-gate 			dhp->he.h_addrtype = AF_INET6;
6237c478bd9Sstevel@tonic-gate 			dhp->he.h_length = sizeof (struct in6_addr);
6247c478bd9Sstevel@tonic-gate 		} else if (inet_pton(AF_INET, argv[0], addr1) == 1) {
6257c478bd9Sstevel@tonic-gate 			dhp->he.h_addr_list = dhp->addtl;
6267c478bd9Sstevel@tonic-gate 			dhp->addtl[0] = addr1;
6277c478bd9Sstevel@tonic-gate 			dhp->addtl[1] = NULL;
6287c478bd9Sstevel@tonic-gate 			hp = &dhp->he;
6297c478bd9Sstevel@tonic-gate 			dhp->he.h_addrtype = AF_INET;
6307c478bd9Sstevel@tonic-gate 			dhp->he.h_length = sizeof (struct in_addr);
6317c478bd9Sstevel@tonic-gate 		} else {
6327c478bd9Sstevel@tonic-gate 			hp = NULL;
6337c478bd9Sstevel@tonic-gate 		}
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	*hpp = hp;
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 	if (hp == NULL) {
6397c478bd9Sstevel@tonic-gate 		message(gettext("Unknown address %s."), argv[0]);
6407c478bd9Sstevel@tonic-gate 		return (-1);
6417c478bd9Sstevel@tonic-gate 	}
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	return (1);
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate /*
6477c478bd9Sstevel@tonic-gate  * Free a dummy_he_t structure that was malloc'd in parse_addr().
6487c478bd9Sstevel@tonic-gate  * Unfortunately, callers of parse_addr don't want to know about
6497c478bd9Sstevel@tonic-gate  * dummy_he_t structs, so all they have is a pointer to the struct
6507c478bd9Sstevel@tonic-gate  * hostent; so that's what's passed in.  To manage this, we make
6517c478bd9Sstevel@tonic-gate  * the assumption that the struct hostent is the first field in
6527c478bd9Sstevel@tonic-gate  * the dummy_he_t, and therefore a pointer to it is a pointer to
6537c478bd9Sstevel@tonic-gate  * the dummy_he_t.
6547c478bd9Sstevel@tonic-gate  */
6557c478bd9Sstevel@tonic-gate static void
free_he(struct hostent * hep)6567c478bd9Sstevel@tonic-gate free_he(struct hostent *hep)
6577c478bd9Sstevel@tonic-gate {
6587c478bd9Sstevel@tonic-gate 	dummy_he_t	*p = (dummy_he_t *)hep;
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	assert(p != NULL);
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 	if (p->addtl[0])
6637c478bd9Sstevel@tonic-gate 		free(p->addtl[0]);
6647c478bd9Sstevel@tonic-gate 	if (p->addtl[1])
6657c478bd9Sstevel@tonic-gate 		free(p->addtl[1]);
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 	free(p);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate #define	FREE_HE(x) \
6717c478bd9Sstevel@tonic-gate 	if (nflag) \
6727c478bd9Sstevel@tonic-gate 		free_he(x); \
6737c478bd9Sstevel@tonic-gate 	else \
6747c478bd9Sstevel@tonic-gate 		freehostent(x)
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate static void
headdr2sa(char * hea,struct sockaddr_storage * sa,int len)6777c478bd9Sstevel@tonic-gate headdr2sa(char *hea, struct sockaddr_storage *sa, int len)
6787c478bd9Sstevel@tonic-gate {
6797c478bd9Sstevel@tonic-gate 	struct sockaddr_in	*sin;
6807c478bd9Sstevel@tonic-gate 	struct sockaddr_in6	*sin6;
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 	if (len == sizeof (struct in6_addr)) {
6837c478bd9Sstevel@tonic-gate 		/* LINTED E_BAD_PTR_CAST_ALIGN */
6847c478bd9Sstevel@tonic-gate 		if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)hea)) {
6857c478bd9Sstevel@tonic-gate 			sin = (struct sockaddr_in *)sa;
6867c478bd9Sstevel@tonic-gate 			(void) memset(sin, 0, sizeof (*sin));
6877c478bd9Sstevel@tonic-gate 			/* LINTED E_BAD_PTR_CAST_ALIGN */
6887c478bd9Sstevel@tonic-gate 			IN6_V4MAPPED_TO_INADDR((struct in6_addr *)hea,
6897c478bd9Sstevel@tonic-gate 			    &sin->sin_addr);
6907c478bd9Sstevel@tonic-gate 			sin->sin_family = AF_INET;
6917c478bd9Sstevel@tonic-gate 		} else {
6927c478bd9Sstevel@tonic-gate 			sin6 = (struct sockaddr_in6 *)sa;
6937c478bd9Sstevel@tonic-gate 			(void) memset(sin6, 0, sizeof (*sin6));
6947c478bd9Sstevel@tonic-gate 			(void) memcpy(&sin6->sin6_addr, hea,
6957c478bd9Sstevel@tonic-gate 			    sizeof (struct in6_addr));
6967c478bd9Sstevel@tonic-gate 			sin6->sin6_family = AF_INET6;
6977c478bd9Sstevel@tonic-gate 		}
6987c478bd9Sstevel@tonic-gate 	} else {
6997c478bd9Sstevel@tonic-gate 		sin = (struct sockaddr_in *)sa;
7007c478bd9Sstevel@tonic-gate 		(void) memset(sin, 0, sizeof (*sin));
7017c478bd9Sstevel@tonic-gate 		(void) memcpy(&sin->sin_addr, hea, sizeof (struct in_addr));
7027c478bd9Sstevel@tonic-gate 		sin->sin_family = AF_INET;
7037c478bd9Sstevel@tonic-gate 	}
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate  * The possible ident-type keywords that might be used on the command
7087c478bd9Sstevel@tonic-gate  * line.  This is a superset of the ones supported by ipseckey, those
7097c478bd9Sstevel@tonic-gate  * in the ike config file, and those in ike.preshared.
7107c478bd9Sstevel@tonic-gate  */
7117c478bd9Sstevel@tonic-gate static keywdtab_t	idtypes[] = {
7127c478bd9Sstevel@tonic-gate 	/* ip, ipv4, and ipv6 are valid for preshared keys... */
7137c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_RESERVED,	"ip"},
7147c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_RESERVED,	"ipv4"},
7157c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_RESERVED,	"ipv6"},
7167c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"prefix"},
7177c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"ipv4-prefix"},
7187c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"ipv6-prefix"},
7197c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"subnet"},
7207c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"subnetv4"},
7217c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_PREFIX,		"subnetv6"},
7227c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_FQDN,		"fqdn"},
7237c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_FQDN,		"dns"},
7247c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_FQDN,		"domain"},
7257c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_FQDN,		"domainname"},
7267c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_USER_FQDN,	"user_fqdn"},
7277c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_USER_FQDN,	"mbox"},
7287c478bd9Sstevel@tonic-gate 	{SADB_IDENTTYPE_USER_FQDN,	"mailbox"},
7297c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_DN,		"dn"},
7307c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_DN,		"asn1dn"},
7317c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_GN,		"gn"},
7327c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_GN,		"asn1gn"},
7337c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_ADDR_RANGE,	"ipv4-range"},
7347c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_ADDR_RANGE,	"ipv6-range"},
7357c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_ADDR_RANGE,	"rangev4"},
7367c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_ADDR_RANGE,	"rangev6"},
7377c478bd9Sstevel@tonic-gate 	{SADB_X_IDENTTYPE_KEY_ID,	"keyid"},
73895c74518SToomas Soome 	{0,				NULL}
7397c478bd9Sstevel@tonic-gate };
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate static int
parse_idtype(char * type,uint16_t * idnum)7427c478bd9Sstevel@tonic-gate parse_idtype(char *type, uint16_t *idnum)
7437c478bd9Sstevel@tonic-gate {
7447c478bd9Sstevel@tonic-gate 	keywdtab_t	*idp;
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 	if (type == NULL)
7477c478bd9Sstevel@tonic-gate 		return (-1);
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 	for (idp = idtypes; idp->kw_str != NULL; idp++) {
7507c478bd9Sstevel@tonic-gate 		if (strcasecmp(idp->kw_str, type) == 0) {
7517c478bd9Sstevel@tonic-gate 			if (idnum != NULL)
7527c478bd9Sstevel@tonic-gate 				*idnum = idp->kw_tag;
7537c478bd9Sstevel@tonic-gate 			return (1);
7547c478bd9Sstevel@tonic-gate 		}
7557c478bd9Sstevel@tonic-gate 	}
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	return (-1);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate /*
7617c478bd9Sstevel@tonic-gate  * The sadb_ident_t is malloc'd, since its length varies;
7627c478bd9Sstevel@tonic-gate  * so the caller must free() it when done with the data.
7637c478bd9Sstevel@tonic-gate  */
7647c478bd9Sstevel@tonic-gate static int
parse_ident(int argc,char ** argv,sadb_ident_t ** idpp)7657c478bd9Sstevel@tonic-gate parse_ident(int argc, char **argv, sadb_ident_t **idpp)
7667c478bd9Sstevel@tonic-gate {
7677c478bd9Sstevel@tonic-gate 	int		alloclen, consumed;
7687c478bd9Sstevel@tonic-gate 	sadb_ident_t	*idp;
7697c478bd9Sstevel@tonic-gate 	if ((argc < 2) || (argv == NULL) || (argv[0] == NULL) ||
7707c478bd9Sstevel@tonic-gate 	    (argv[1] == NULL))
7717c478bd9Sstevel@tonic-gate 		return (-1);
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	alloclen = sizeof (sadb_ident_t) + IKEDOORROUNDUP(strlen(argv[1]) + 1);
7747c478bd9Sstevel@tonic-gate 	*idpp = idp = (sadb_ident_t *)malloc(alloclen);
7757c478bd9Sstevel@tonic-gate 	if (idp == NULL)
7767c478bd9Sstevel@tonic-gate 		Bail("parsing identity");
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	if ((consumed = parse_idtype(argv[0], &idp->sadb_ident_type)) < 0) {
7797c478bd9Sstevel@tonic-gate 		message(gettext("unknown identity type %s."), argv[0]);
7807c478bd9Sstevel@tonic-gate 		return (-1);
7817c478bd9Sstevel@tonic-gate 	}
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	idp->sadb_ident_len = SADB_8TO64(alloclen);
7847c478bd9Sstevel@tonic-gate 	idp->sadb_ident_reserved = 0;
7857c478bd9Sstevel@tonic-gate 	idp->sadb_ident_id = 0;
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	/* now copy in identity param */
788e3320f40Smarkfen 	(void) strlcpy((char *)(idp + 1), argv[1],
789e3320f40Smarkfen 	    alloclen - (sizeof (sadb_ident_t)));
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 	return (++consumed);
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate static int
parse_cky(int argc,char ** argv,uint64_t * ckyp)7957c478bd9Sstevel@tonic-gate parse_cky(int argc, char **argv, uint64_t *ckyp)
7967c478bd9Sstevel@tonic-gate {
7977c478bd9Sstevel@tonic-gate 	u_longlong_t	arg;
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 	if ((argc < 1) || (argv[0] == NULL))
8007c478bd9Sstevel@tonic-gate 		return (-1);
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate 	errno = 0;
8037c478bd9Sstevel@tonic-gate 	arg = strtoull(argv[0], NULL, 0);
8047c478bd9Sstevel@tonic-gate 	if (errno != 0) {
8057c478bd9Sstevel@tonic-gate 		message(gettext("failed to parse cookie %s."), argv[0]);
8067c478bd9Sstevel@tonic-gate 		return (-1);
8077c478bd9Sstevel@tonic-gate 	}
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	*ckyp = (uint64_t)arg;
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	return (1);
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate static int
parse_addr_pr(int argc,char ** argv,struct hostent ** h1pp,struct hostent ** h2pp)8157c478bd9Sstevel@tonic-gate parse_addr_pr(int argc, char **argv, struct hostent **h1pp,
8160fddcadbSToomas Soome     struct hostent **h2pp)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate 	int	rtn, consumed = 0;
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	if ((rtn = parse_addr(argc, argv, h1pp)) < 0) {
8217c478bd9Sstevel@tonic-gate 		return (-1);
8227c478bd9Sstevel@tonic-gate 	}
8237c478bd9Sstevel@tonic-gate 	consumed = rtn;
8247c478bd9Sstevel@tonic-gate 	argc -= rtn;
8257c478bd9Sstevel@tonic-gate 	argv += rtn;
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	if ((rtn = parse_addr(argc, argv, h2pp)) < 0) {
8287c478bd9Sstevel@tonic-gate 		FREE_HE(*h1pp);
8297c478bd9Sstevel@tonic-gate 		return (-1);
8307c478bd9Sstevel@tonic-gate 	}
8317c478bd9Sstevel@tonic-gate 	consumed += rtn;
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	return (consumed);
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate /*
8377c478bd9Sstevel@tonic-gate  * The sadb_ident_ts are malloc'd, since their length varies;
8387c478bd9Sstevel@tonic-gate  * so the caller must free() them when done with the data.
8397c478bd9Sstevel@tonic-gate  */
8407c478bd9Sstevel@tonic-gate static int
parse_ident_pr(int argc,char ** argv,sadb_ident_t ** id1pp,sadb_ident_t ** id2pp)8417c478bd9Sstevel@tonic-gate parse_ident_pr(int argc, char **argv, sadb_ident_t **id1pp,
8427c478bd9Sstevel@tonic-gate     sadb_ident_t **id2pp)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate 	int	rtn, consumed = 0;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 	if ((rtn = parse_ident(argc, argv, id1pp)) < 0) {
8477c478bd9Sstevel@tonic-gate 		return (-1);
8487c478bd9Sstevel@tonic-gate 	}
8497c478bd9Sstevel@tonic-gate 	consumed = rtn;
8507c478bd9Sstevel@tonic-gate 	argc -= rtn;
8517c478bd9Sstevel@tonic-gate 	argv += rtn;
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	(*id1pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate 	if ((rtn = parse_ident(argc, argv, id2pp)) < 0) {
8567c478bd9Sstevel@tonic-gate 		free(*id1pp);
8577c478bd9Sstevel@tonic-gate 		return (-1);
8587c478bd9Sstevel@tonic-gate 	}
8597c478bd9Sstevel@tonic-gate 	consumed += rtn;
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 	(*id2pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 	return (consumed);
8647c478bd9Sstevel@tonic-gate }
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate static int
parse_cky_pr(int argc,char ** argv,ike_cky_pr_t * cpr)8677c478bd9Sstevel@tonic-gate parse_cky_pr(int argc, char **argv, ike_cky_pr_t *cpr)
8687c478bd9Sstevel@tonic-gate {
8697c478bd9Sstevel@tonic-gate 	int	rtn, consumed = 0;
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	if ((rtn = parse_cky(argc, argv, &cpr->cky_i)) < 0) {
8727c478bd9Sstevel@tonic-gate 		return (-1);
8737c478bd9Sstevel@tonic-gate 	}
8747c478bd9Sstevel@tonic-gate 	consumed = rtn;
8757c478bd9Sstevel@tonic-gate 	argc -= rtn;
8767c478bd9Sstevel@tonic-gate 	argv += rtn;
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	if ((rtn = parse_cky(argc, argv, &cpr->cky_r)) < 0) {
8797c478bd9Sstevel@tonic-gate 		return (-1);
8807c478bd9Sstevel@tonic-gate 	}
8817c478bd9Sstevel@tonic-gate 	consumed += rtn;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	return (consumed);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate /*
8877c478bd9Sstevel@tonic-gate  * Preshared key field types...used for parsing preshared keys that
8887c478bd9Sstevel@tonic-gate  * have been entered on the command line.  The code to parse preshared
8897c478bd9Sstevel@tonic-gate  * keys (parse_ps, parse_key, parse_psfldid, parse_ikmtype, ...) is
8907c478bd9Sstevel@tonic-gate  * mostly duplicated from in.iked's readps.c.
8917c478bd9Sstevel@tonic-gate  */
8927c478bd9Sstevel@tonic-gate #define	PSFLD_LOCID	1
8937c478bd9Sstevel@tonic-gate #define	PSFLD_LOCIDTYPE	2
8947c478bd9Sstevel@tonic-gate #define	PSFLD_REMID	3
8957c478bd9Sstevel@tonic-gate #define	PSFLD_REMIDTYPE	4
8967c478bd9Sstevel@tonic-gate #define	PSFLD_MODE	5
8977c478bd9Sstevel@tonic-gate #define	PSFLD_KEY	6
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate static keywdtab_t	psfldtypes[] = {
9007c478bd9Sstevel@tonic-gate 	{PSFLD_LOCID,		"localid"},
9017c478bd9Sstevel@tonic-gate 	{PSFLD_LOCIDTYPE,	"localidtype"},
9027c478bd9Sstevel@tonic-gate 	{PSFLD_REMID,		"remoteid"},
9037c478bd9Sstevel@tonic-gate 	{PSFLD_REMIDTYPE,	"remoteidtype"},
9047c478bd9Sstevel@tonic-gate 	{PSFLD_MODE,		"ike_mode"},
9057c478bd9Sstevel@tonic-gate 	{PSFLD_KEY,		"key"},
90695c74518SToomas Soome 	{0,			NULL}
9077c478bd9Sstevel@tonic-gate };
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate static int
parse_psfldid(char * type,uint16_t * idnum)9107c478bd9Sstevel@tonic-gate parse_psfldid(char *type, uint16_t *idnum)
9117c478bd9Sstevel@tonic-gate {
9127c478bd9Sstevel@tonic-gate 	keywdtab_t	*pfp;
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 	if (type == NULL)
9157c478bd9Sstevel@tonic-gate 		return (-1);
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 	for (pfp = psfldtypes; pfp->kw_str != NULL; pfp++) {
9187c478bd9Sstevel@tonic-gate 		if (strcasecmp(pfp->kw_str, type) == 0) {
9197c478bd9Sstevel@tonic-gate 			if (idnum != NULL)
9207c478bd9Sstevel@tonic-gate 				*idnum = pfp->kw_tag;
9217c478bd9Sstevel@tonic-gate 			return (1);
9227c478bd9Sstevel@tonic-gate 		}
9237c478bd9Sstevel@tonic-gate 	}
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	return (-1);
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate static keywdtab_t	ikemodes[] = {
9297c478bd9Sstevel@tonic-gate 	{IKE_XCHG_IDENTITY_PROTECT,	"main"},
9307c478bd9Sstevel@tonic-gate 	{IKE_XCHG_AGGRESSIVE,		"aggressive"},
9317c478bd9Sstevel@tonic-gate 	{IKE_XCHG_IP_AND_AGGR,		"both"},
93295c74518SToomas Soome 	{0,				NULL}
9337c478bd9Sstevel@tonic-gate };
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate static int
parse_ikmtype(char * mode,uint16_t * modenum)9367c478bd9Sstevel@tonic-gate parse_ikmtype(char *mode, uint16_t *modenum)
9377c478bd9Sstevel@tonic-gate {
9387c478bd9Sstevel@tonic-gate 	keywdtab_t	*ikmp;
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	if (mode == NULL)
9417c478bd9Sstevel@tonic-gate 		return (-1);
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 	for (ikmp = ikemodes; ikmp->kw_str != NULL; ikmp++) {
9447c478bd9Sstevel@tonic-gate 		if (strcasecmp(ikmp->kw_str, mode) == 0) {
9457c478bd9Sstevel@tonic-gate 			if (modenum != NULL)
9467c478bd9Sstevel@tonic-gate 				*modenum = ikmp->kw_tag;
9477c478bd9Sstevel@tonic-gate 			return (1);
9487c478bd9Sstevel@tonic-gate 		}
9497c478bd9Sstevel@tonic-gate 	}
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate 	return (-1);
9527c478bd9Sstevel@tonic-gate }
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate #define	hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \
9557c478bd9Sstevel@tonic-gate 	(((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10)))
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate static uint8_t *
parse_key(char * input,uint_t * keybuflen,uint_t * lbits)9587c478bd9Sstevel@tonic-gate parse_key(char *input, uint_t *keybuflen, uint_t *lbits)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate 	uint8_t	*keyp, *keybufp;
9617c478bd9Sstevel@tonic-gate 	uint_t	i, hexlen = 0, bits, alloclen;
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 	for (i = 0; input[i] != '\0' && input[i] != '/'; i++)
9647c478bd9Sstevel@tonic-gate 		hexlen++;
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	if (input[i] == '\0') {
9677c478bd9Sstevel@tonic-gate 		bits = 0;
9687c478bd9Sstevel@tonic-gate 	} else {
9697c478bd9Sstevel@tonic-gate 		/* Have /nn. */
9707c478bd9Sstevel@tonic-gate 		input[i] = '\0';
9717c478bd9Sstevel@tonic-gate 		if (sscanf((input + i + 1), "%u", &bits) != 1)
9727c478bd9Sstevel@tonic-gate 			return (NULL);
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 		/* hexlen is in nibbles */
9757c478bd9Sstevel@tonic-gate 		if (((bits + 3) >> 2) > hexlen)
9767c478bd9Sstevel@tonic-gate 			return (NULL);
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 		/*
9797c478bd9Sstevel@tonic-gate 		 * Adjust hexlen down if user gave us too small of a bit
9807c478bd9Sstevel@tonic-gate 		 * count.
9817c478bd9Sstevel@tonic-gate 		 */
9827c478bd9Sstevel@tonic-gate 		if ((hexlen << 2) > bits + 3) {
9837c478bd9Sstevel@tonic-gate 			hexlen = (bits + 3) >> 2;
9847c478bd9Sstevel@tonic-gate 			input[hexlen] = '\0';
9857c478bd9Sstevel@tonic-gate 		}
9867c478bd9Sstevel@tonic-gate 	}
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	/*
9897c478bd9Sstevel@tonic-gate 	 * Allocate.  Remember, hexlen is in nibbles.
9907c478bd9Sstevel@tonic-gate 	 */
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 	alloclen = (hexlen/2 + (hexlen & 0x1));
9937c478bd9Sstevel@tonic-gate 	keyp = malloc(alloclen);
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	if (keyp == NULL)
9967c478bd9Sstevel@tonic-gate 		return (NULL);
9977c478bd9Sstevel@tonic-gate 
9987c478bd9Sstevel@tonic-gate 	keybufp = keyp;
9997c478bd9Sstevel@tonic-gate 	*keybuflen = alloclen;
10007c478bd9Sstevel@tonic-gate 	if (bits == 0)
10017c478bd9Sstevel@tonic-gate 		*lbits = (hexlen + (hexlen & 0x1)) << 2;
10027c478bd9Sstevel@tonic-gate 	else
10037c478bd9Sstevel@tonic-gate 		*lbits = bits;
10047c478bd9Sstevel@tonic-gate 
10057c478bd9Sstevel@tonic-gate 	/*
10067c478bd9Sstevel@tonic-gate 	 * Read in nibbles.  Read in odd-numbered as shifted high.
10077c478bd9Sstevel@tonic-gate 	 * (e.g. 123 becomes 0x1230).
10087c478bd9Sstevel@tonic-gate 	 */
10097c478bd9Sstevel@tonic-gate 	for (i = 0; input[i] != '\0'; i += 2) {
10107c478bd9Sstevel@tonic-gate 		boolean_t second = (input[i + 1] != '\0');
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 		if (!isxdigit(input[i]) ||
10137c478bd9Sstevel@tonic-gate 		    (!isxdigit(input[i + 1]) && second)) {
10147c478bd9Sstevel@tonic-gate 			free(keyp);
10157c478bd9Sstevel@tonic-gate 			return (NULL);
10167c478bd9Sstevel@tonic-gate 		}
10177c478bd9Sstevel@tonic-gate 		*keyp = (hd2num(input[i]) << 4);
10187c478bd9Sstevel@tonic-gate 		if (second)
10197c478bd9Sstevel@tonic-gate 			*keyp |= hd2num(input[i + 1]);
10207c478bd9Sstevel@tonic-gate 		else
10217c478bd9Sstevel@tonic-gate 			break; /* out of for loop. */
10227c478bd9Sstevel@tonic-gate 		keyp++;
10237c478bd9Sstevel@tonic-gate 	}
10247c478bd9Sstevel@tonic-gate 
10257c478bd9Sstevel@tonic-gate 	/* zero the remaining bits if we're a non-octet amount. */
10267c478bd9Sstevel@tonic-gate 	if (bits & 0x7)
10277c478bd9Sstevel@tonic-gate 		*((input[i] == '\0') ? keyp - 1 : keyp) &=
10287c478bd9Sstevel@tonic-gate 		    0xff << (8 - (bits & 0x7));
10297c478bd9Sstevel@tonic-gate 	return (keybufp);
10307c478bd9Sstevel@tonic-gate }
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate /*
10337c478bd9Sstevel@tonic-gate  * the ike_ps_t struct (plus trailing data) will be allocated here,
10347c478bd9Sstevel@tonic-gate  * so it will need to be freed by the caller.
10357c478bd9Sstevel@tonic-gate  */
10367c478bd9Sstevel@tonic-gate static int
parse_ps(int argc,char ** argv,ike_ps_t ** presharedpp,int * len)10377c478bd9Sstevel@tonic-gate parse_ps(int argc, char **argv, ike_ps_t **presharedpp, int *len)
10387c478bd9Sstevel@tonic-gate {
10397c478bd9Sstevel@tonic-gate 	uint_t		c = 0, locidlen, remidlen, keylen, keybits;
10407c478bd9Sstevel@tonic-gate 	uint_t		a_locidtotal = 0, a_remidtotal = 0;
104141c215c2SPaul Wernau 	char		*locid, *remid, *locpfx = NULL, *rempfx = NULL;
10427c478bd9Sstevel@tonic-gate 	uint8_t		*keyp = NULL;
10437c478bd9Sstevel@tonic-gate 	uint16_t	fldid, locidtype, remidtype, mtype;
10447c478bd9Sstevel@tonic-gate 	struct hostent	*loche = NULL, *remhe = NULL;
10457c478bd9Sstevel@tonic-gate 	ike_ps_t	*psp = NULL;
10467c478bd9Sstevel@tonic-gate 	sadb_ident_t	*sidp;
104715b07f80Spwernau 	boolean_t	whacked = B_FALSE;
104841c215c2SPaul Wernau 	int pfxlen = 0;
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate 	if ((argv[c] == NULL) || (argv[c][0] != '{'))
10517c478bd9Sstevel@tonic-gate 		return (-1);
10527c478bd9Sstevel@tonic-gate 	if (argv[c][1] != 0) {
10537c478bd9Sstevel@tonic-gate 		/* no space between '{' and first token */
10547c478bd9Sstevel@tonic-gate 		argv[c]++;
10557c478bd9Sstevel@tonic-gate 	} else {
10567c478bd9Sstevel@tonic-gate 		c++;
10577c478bd9Sstevel@tonic-gate 	}
105815b07f80Spwernau 	if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') &&
105915b07f80Spwernau 	    (argv[argc - 1][0] != '}')) {
106015b07f80Spwernau 		/*
106115b07f80Spwernau 		 * whack '}' without a space before it or parsers break.
106215b07f80Spwernau 		 * Remember this trailing character for later
106315b07f80Spwernau 		 */
106415b07f80Spwernau 		argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0';
106515b07f80Spwernau 		whacked = B_TRUE;
106615b07f80Spwernau 	}
10677c478bd9Sstevel@tonic-gate 
106841c215c2SPaul Wernau 	/* Default to type IP */
106941c215c2SPaul Wernau 	locidtype = remidtype = SADB_IDENTTYPE_RESERVED;
107041c215c2SPaul Wernau 	/* Default to base exchanges */
107141c215c2SPaul Wernau 	mtype = IKE_XCHG_BASE;
107241c215c2SPaul Wernau 
10737c478bd9Sstevel@tonic-gate 	while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) {
107415b07f80Spwernau 		if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}'))
107515b07f80Spwernau 			goto bail;
10767c478bd9Sstevel@tonic-gate 		if (parse_psfldid(argv[c++], &fldid) < 0)
10777c478bd9Sstevel@tonic-gate 			goto bail;
10787c478bd9Sstevel@tonic-gate 		switch (fldid) {
10797c478bd9Sstevel@tonic-gate 		case PSFLD_LOCID:
10807c478bd9Sstevel@tonic-gate 			locid = argv[c++];
10817c478bd9Sstevel@tonic-gate 			locidlen = strlen(locid) + 1;
10827c478bd9Sstevel@tonic-gate 			break;
10837c478bd9Sstevel@tonic-gate 		case PSFLD_LOCIDTYPE:
10847c478bd9Sstevel@tonic-gate 			if (parse_idtype(argv[c++], &locidtype) < 0)
10857c478bd9Sstevel@tonic-gate 				goto bail;
10867c478bd9Sstevel@tonic-gate 			break;
10877c478bd9Sstevel@tonic-gate 		case PSFLD_REMID:
10887c478bd9Sstevel@tonic-gate 			remid = argv[c++];
10897c478bd9Sstevel@tonic-gate 			remidlen = strlen(remid) + 1;
10907c478bd9Sstevel@tonic-gate 			break;
10917c478bd9Sstevel@tonic-gate 		case PSFLD_REMIDTYPE:
10927c478bd9Sstevel@tonic-gate 			if (parse_idtype(argv[c++], &remidtype) < 0)
10937c478bd9Sstevel@tonic-gate 				goto bail;
10947c478bd9Sstevel@tonic-gate 			break;
10957c478bd9Sstevel@tonic-gate 		case PSFLD_MODE:
10967c478bd9Sstevel@tonic-gate 			if (parse_ikmtype(argv[c++], &mtype) < 0)
10977c478bd9Sstevel@tonic-gate 				goto bail;
10987c478bd9Sstevel@tonic-gate 			break;
10997c478bd9Sstevel@tonic-gate 		case PSFLD_KEY:
11007c478bd9Sstevel@tonic-gate 			keyp  = parse_key(argv[c++], &keylen, &keybits);
11017c478bd9Sstevel@tonic-gate 			if (keyp == NULL)
11027c478bd9Sstevel@tonic-gate 				goto bail;
11037c478bd9Sstevel@tonic-gate 			break;
11047c478bd9Sstevel@tonic-gate 		}
11057c478bd9Sstevel@tonic-gate 	}
110615b07f80Spwernau 
110715b07f80Spwernau 	/* Make sure the line was terminated with '}' */
110815b07f80Spwernau 	if (argv[c] == NULL) {
110915b07f80Spwernau 		if (!whacked)
111015b07f80Spwernau 			goto bail;
111115b07f80Spwernau 	} else if (argv[c][0] != '}') {
111215b07f80Spwernau 		goto bail;
111315b07f80Spwernau 	}
111415b07f80Spwernau 
11157c478bd9Sstevel@tonic-gate 	/*
11167c478bd9Sstevel@tonic-gate 	 * make sure we got all the required fields.  If no idtype, assume
11177c478bd9Sstevel@tonic-gate 	 * ip addr; if that translation fails, we'll catch the error then.
11187c478bd9Sstevel@tonic-gate 	 */
11197c478bd9Sstevel@tonic-gate 	if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0)
11207c478bd9Sstevel@tonic-gate 		goto bail;
11217c478bd9Sstevel@tonic-gate 
11227c478bd9Sstevel@tonic-gate 	/* figure out the size buffer we need */
11237c478bd9Sstevel@tonic-gate 	*len = sizeof (ike_ps_t);
11247c478bd9Sstevel@tonic-gate 	if (locidtype != SADB_IDENTTYPE_RESERVED) {
11257c478bd9Sstevel@tonic-gate 		a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen);
11267c478bd9Sstevel@tonic-gate 		*len += a_locidtotal;
11277c478bd9Sstevel@tonic-gate 	}
11287c478bd9Sstevel@tonic-gate 	if (remidtype != SADB_IDENTTYPE_RESERVED) {
11297c478bd9Sstevel@tonic-gate 		a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen);
11307c478bd9Sstevel@tonic-gate 		*len += a_remidtotal;
11317c478bd9Sstevel@tonic-gate 	}
11327c478bd9Sstevel@tonic-gate 	*len += keylen;
11337c478bd9Sstevel@tonic-gate 
11347c478bd9Sstevel@tonic-gate 	psp = malloc(*len);
11357c478bd9Sstevel@tonic-gate 	if (psp == NULL)
11367c478bd9Sstevel@tonic-gate 		goto bail;
11377c478bd9Sstevel@tonic-gate 	(void) memset(psp, 0, *len);
11387c478bd9Sstevel@tonic-gate 
11397c478bd9Sstevel@tonic-gate 	psp->ps_ike_mode = mtype;
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	psp->ps_localid_off = sizeof (ike_ps_t);
11427c478bd9Sstevel@tonic-gate 	if (locidtype == SADB_IDENTTYPE_RESERVED) {
114341c215c2SPaul Wernau 		locpfx = strchr(locid, '/');
114441c215c2SPaul Wernau 		if (locpfx != NULL) {
114541c215c2SPaul Wernau 			*locpfx = '\0';
114641c215c2SPaul Wernau 			locpfx++;
114741c215c2SPaul Wernau 		}
114841c215c2SPaul Wernau 
11497c478bd9Sstevel@tonic-gate 		/*
11507c478bd9Sstevel@tonic-gate 		 * this is an ip address, store in the sockaddr field;
11517c478bd9Sstevel@tonic-gate 		 * we won't use an sadb_ident_t.
11527c478bd9Sstevel@tonic-gate 		 */
11537c478bd9Sstevel@tonic-gate 		psp->ps_localid_len = 0;
11547c478bd9Sstevel@tonic-gate 		if (parse_addr(1, &locid, &loche) < 0)
11557c478bd9Sstevel@tonic-gate 			goto bail;
11567c478bd9Sstevel@tonic-gate 		if (loche->h_addr_list[1] != NULL) {
11577c478bd9Sstevel@tonic-gate 			message(gettext("preshared key identifier cannot "
11587c478bd9Sstevel@tonic-gate 			    "match multiple IP addresses"));
11597c478bd9Sstevel@tonic-gate 			goto bail;
11607c478bd9Sstevel@tonic-gate 		}
11617c478bd9Sstevel@tonic-gate 		headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr,
11627c478bd9Sstevel@tonic-gate 		    loche->h_length);
11637c478bd9Sstevel@tonic-gate 		FREE_HE(loche);
11647c478bd9Sstevel@tonic-gate 	} else {
11657c478bd9Sstevel@tonic-gate 		psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen;
11667c478bd9Sstevel@tonic-gate 		sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off);
11677c478bd9Sstevel@tonic-gate 		sidp->sadb_ident_len = psp->ps_localid_len;
11687c478bd9Sstevel@tonic-gate 		sidp->sadb_ident_type = locidtype;
1169e3320f40Smarkfen 		(void) strlcpy((char *)(sidp + 1), locid, a_locidtotal);
11707c478bd9Sstevel@tonic-gate 	}
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 	psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal;
11737c478bd9Sstevel@tonic-gate 	if (remidtype == SADB_IDENTTYPE_RESERVED) {
117441c215c2SPaul Wernau 		rempfx = strchr(remid, '/');
117541c215c2SPaul Wernau 		if (rempfx != NULL) {
117641c215c2SPaul Wernau 			*rempfx = '\0';
117741c215c2SPaul Wernau 			rempfx++;
117841c215c2SPaul Wernau 		}
117941c215c2SPaul Wernau 
11807c478bd9Sstevel@tonic-gate 		/*
11817c478bd9Sstevel@tonic-gate 		 * this is an ip address, store in the sockaddr field;
11827c478bd9Sstevel@tonic-gate 		 * we won't use an sadb_ident_t.
11837c478bd9Sstevel@tonic-gate 		 */
11847c478bd9Sstevel@tonic-gate 		psp->ps_remoteid_len = 0;
11857c478bd9Sstevel@tonic-gate 		if (parse_addr(1, &remid, &remhe) < 0)
11867c478bd9Sstevel@tonic-gate 			goto bail;
11877c478bd9Sstevel@tonic-gate 		if (remhe->h_addr_list[1] != NULL) {
11887c478bd9Sstevel@tonic-gate 			message(gettext("preshared key identifier cannot "
11897c478bd9Sstevel@tonic-gate 			    "match multiple IP addresses"));
11907c478bd9Sstevel@tonic-gate 			goto bail;
11917c478bd9Sstevel@tonic-gate 		}
11927c478bd9Sstevel@tonic-gate 		headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr,
11937c478bd9Sstevel@tonic-gate 		    remhe->h_length);
11947c478bd9Sstevel@tonic-gate 		FREE_HE(remhe);
11957c478bd9Sstevel@tonic-gate 	} else {
11967c478bd9Sstevel@tonic-gate 		/* make sure we have at least 16-bit alignment */
11977c478bd9Sstevel@tonic-gate 		if (remidlen & 0x1)
11987c478bd9Sstevel@tonic-gate 			remidlen++;
11997c478bd9Sstevel@tonic-gate 		psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen;
12007c478bd9Sstevel@tonic-gate 		sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off);
12017c478bd9Sstevel@tonic-gate 		sidp->sadb_ident_len = psp->ps_remoteid_len;
12027c478bd9Sstevel@tonic-gate 		sidp->sadb_ident_type = remidtype;
1203e3320f40Smarkfen 		(void) strlcpy((char *)(sidp + 1), remid, a_remidtotal);
12047c478bd9Sstevel@tonic-gate 	}
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal;
12077c478bd9Sstevel@tonic-gate 	psp->ps_key_len = keylen;
12087c478bd9Sstevel@tonic-gate 	psp->ps_key_bits = keybits;
12097c478bd9Sstevel@tonic-gate 	(void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen);
121041c215c2SPaul Wernau 	if (locpfx != NULL && ((pfxlen = atoi(locpfx)) > 0))
121141c215c2SPaul Wernau 		psp->ps_localid_plen = pfxlen;
121241c215c2SPaul Wernau 	if (rempfx != NULL && ((pfxlen = atoi(rempfx)) > 0))
121341c215c2SPaul Wernau 		psp->ps_remoteid_plen = pfxlen;
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	*presharedpp = psp;
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate 	return (c);
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate bail:
12207c478bd9Sstevel@tonic-gate 	if (loche != NULL)
12217c478bd9Sstevel@tonic-gate 		FREE_HE(loche);
12227c478bd9Sstevel@tonic-gate 	if (remhe != NULL)
12237c478bd9Sstevel@tonic-gate 		FREE_HE(remhe);
12247c478bd9Sstevel@tonic-gate 	if (keyp != NULL)
12257c478bd9Sstevel@tonic-gate 		free(keyp);
12267c478bd9Sstevel@tonic-gate 	if (psp != NULL)
12277c478bd9Sstevel@tonic-gate 		free(psp);
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 	*presharedpp = NULL;
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 	return (-1);
12327c478bd9Sstevel@tonic-gate }
12337c478bd9Sstevel@tonic-gate 
12347c478bd9Sstevel@tonic-gate /*
12357c478bd9Sstevel@tonic-gate  * Printing functions
12367c478bd9Sstevel@tonic-gate  *
12377c478bd9Sstevel@tonic-gate  * A potential point of confusion here is that the ikeadm-specific string-
12387c478bd9Sstevel@tonic-gate  * producing functions do not match the ipsec_util.c versions in style: the
12397c478bd9Sstevel@tonic-gate  * ikeadm-specific functions return a string (and are named foostr), while
12407c478bd9Sstevel@tonic-gate  * the ipsec_util.c functions actually print the string to the file named
12417c478bd9Sstevel@tonic-gate  * in the second arg to the function (and are named dump_foo).
12427c478bd9Sstevel@tonic-gate  *
12434b56a003SDaniel Anderson  * Localization for ikeadm seems more straightforward when complete
12444b56a003SDaniel Anderson  * phrases are translated rather than: a part of a phrase, a call to
12454b56a003SDaniel Anderson  * dump_foo(), and more of the phrase.  It could also accommodate
12464b56a003SDaniel Anderson  * non-English grammar more easily.
12477c478bd9Sstevel@tonic-gate  */
12487c478bd9Sstevel@tonic-gate 
12497c478bd9Sstevel@tonic-gate static char *
errstr(int err)12507c478bd9Sstevel@tonic-gate errstr(int err)
12517c478bd9Sstevel@tonic-gate {
12527c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate 	switch (err) {
12557c478bd9Sstevel@tonic-gate 	case IKE_ERR_NO_OBJ:
12567c478bd9Sstevel@tonic-gate 		return (gettext("No data returned"));
12577c478bd9Sstevel@tonic-gate 	case IKE_ERR_NO_DESC:
12587c478bd9Sstevel@tonic-gate 		return (gettext("No destination provided"));
12597c478bd9Sstevel@tonic-gate 	case IKE_ERR_ID_INVALID:
12607c478bd9Sstevel@tonic-gate 		return (gettext("Id info invalid"));
12617c478bd9Sstevel@tonic-gate 	case IKE_ERR_LOC_INVALID:
12627c478bd9Sstevel@tonic-gate 		return (gettext("Destination invalid"));
12637c478bd9Sstevel@tonic-gate 	case IKE_ERR_CMD_INVALID:
12647c478bd9Sstevel@tonic-gate 		return (gettext("Command invalid"));
12657c478bd9Sstevel@tonic-gate 	case IKE_ERR_DATA_INVALID:
12667c478bd9Sstevel@tonic-gate 		return (gettext("Supplied data invalid"));
12677c478bd9Sstevel@tonic-gate 	case IKE_ERR_CMD_NOTSUP:
12687c478bd9Sstevel@tonic-gate 		return (gettext("Unknown command"));
12697c478bd9Sstevel@tonic-gate 	case IKE_ERR_REQ_INVALID:
12707c478bd9Sstevel@tonic-gate 		return (gettext("Request invalid"));
12717c478bd9Sstevel@tonic-gate 	case IKE_ERR_NO_PRIV:
12727c478bd9Sstevel@tonic-gate 		return (gettext("Not allowed at current privilege level"));
1273c7777ac8SPaul Wernau 	case IKE_ERR_NO_AUTH:
1274c7777ac8SPaul Wernau 		return (gettext("User not authorized"));
12757c478bd9Sstevel@tonic-gate 	case IKE_ERR_SYS_ERR:
12767c478bd9Sstevel@tonic-gate 		return (gettext("System error"));
127715b07f80Spwernau 	case IKE_ERR_DUP_IGNORED:
127815b07f80Spwernau 		return (gettext("One or more duplicate entries ignored"));
1279c7777ac8SPaul Wernau 	case IKE_ERR_NO_TOKEN:
1280c7777ac8SPaul Wernau 		return (gettext(
1281c7777ac8SPaul Wernau 		    "token login failed or no objects on device"));
1282c7777ac8SPaul Wernau 	case IKE_ERR_IN_PROGRESS:
1283c7777ac8SPaul Wernau 		return (gettext(
1284c7777ac8SPaul Wernau 		    "Duplicate operation already in progress"));
1285c7777ac8SPaul Wernau 	case IKE_ERR_NO_MEM:
1286c7777ac8SPaul Wernau 		return (gettext(
1287c7777ac8SPaul Wernau 		    "Insufficient memory"));
12887c478bd9Sstevel@tonic-gate 	default:
12897c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
12907c478bd9Sstevel@tonic-gate 		    gettext("<unknown error %d>"), err);
12917c478bd9Sstevel@tonic-gate 		return (rtn);
12927c478bd9Sstevel@tonic-gate 	}
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate static char *
dbgstr(int bit)12967c478bd9Sstevel@tonic-gate dbgstr(int bit)
12977c478bd9Sstevel@tonic-gate {
12987c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	switch (bit) {
13017c478bd9Sstevel@tonic-gate 	case D_CERT:
13027c478bd9Sstevel@tonic-gate 		return (gettext("Certificate management"));
13037c478bd9Sstevel@tonic-gate 	case D_KEY:
13047c478bd9Sstevel@tonic-gate 		return (gettext("Key management"));
13057c478bd9Sstevel@tonic-gate 	case D_OP:
13067c478bd9Sstevel@tonic-gate 		return (gettext("Operational"));
13077c478bd9Sstevel@tonic-gate 	case D_P1:
13087c478bd9Sstevel@tonic-gate 		return (gettext("Phase 1 SA creation"));
13097c478bd9Sstevel@tonic-gate 	case D_P2:
13107c478bd9Sstevel@tonic-gate 		return (gettext("Phase 2 SA creation"));
13117c478bd9Sstevel@tonic-gate 	case D_PFKEY:
13127c478bd9Sstevel@tonic-gate 		return (gettext("PF_KEY interface"));
13137c478bd9Sstevel@tonic-gate 	case D_POL:
13147c478bd9Sstevel@tonic-gate 		return (gettext("Policy management"));
13157c478bd9Sstevel@tonic-gate 	case D_PROP:
13167c478bd9Sstevel@tonic-gate 		return (gettext("Proposal construction"));
13177c478bd9Sstevel@tonic-gate 	case D_DOOR:
13187c478bd9Sstevel@tonic-gate 		return (gettext("Door interface"));
13197c478bd9Sstevel@tonic-gate 	case D_CONFIG:
13207c478bd9Sstevel@tonic-gate 		return (gettext("Config file processing"));
13215d3b8cb7SBill Sommerfeld 	case D_LABEL:
13225d3b8cb7SBill Sommerfeld 		return (gettext("MAC label processing"));
13237c478bd9Sstevel@tonic-gate 	default:
13247c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
13257c478bd9Sstevel@tonic-gate 		    gettext("<unknown flag 0x%x>"), bit);
13267c478bd9Sstevel@tonic-gate 		return (rtn);
13277c478bd9Sstevel@tonic-gate 	}
13287c478bd9Sstevel@tonic-gate }
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate static char *
privstr(int priv)13317c478bd9Sstevel@tonic-gate privstr(int priv)
13327c478bd9Sstevel@tonic-gate {
13337c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 	switch (priv) {
13367c478bd9Sstevel@tonic-gate 	case IKE_PRIV_MINIMUM:
13377c478bd9Sstevel@tonic-gate 		return (gettext("base privileges"));
13387c478bd9Sstevel@tonic-gate 	case IKE_PRIV_MODKEYS:
13397c478bd9Sstevel@tonic-gate 		return (gettext("access to preshared key information"));
13407c478bd9Sstevel@tonic-gate 	case IKE_PRIV_KEYMAT:
13417c478bd9Sstevel@tonic-gate 		return (gettext("access to keying material"));
13427c478bd9Sstevel@tonic-gate 	default:
13437c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
13447c478bd9Sstevel@tonic-gate 		    gettext("<unknown level %d>"), priv);
13457c478bd9Sstevel@tonic-gate 		return (rtn);
13467c478bd9Sstevel@tonic-gate 	}
13477c478bd9Sstevel@tonic-gate }
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate static char *
xchgstr(int xchg)13507c478bd9Sstevel@tonic-gate xchgstr(int xchg)
13517c478bd9Sstevel@tonic-gate {
13527c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
13537c478bd9Sstevel@tonic-gate 
13547c478bd9Sstevel@tonic-gate 	switch (xchg) {
13557c478bd9Sstevel@tonic-gate 	case IKE_XCHG_NONE:
13567c478bd9Sstevel@tonic-gate 		return (gettext("<unspecified>"));
13577c478bd9Sstevel@tonic-gate 	case IKE_XCHG_BASE:
13587c478bd9Sstevel@tonic-gate 		return (gettext("base"));
13597c478bd9Sstevel@tonic-gate 	case IKE_XCHG_IDENTITY_PROTECT:
13607c478bd9Sstevel@tonic-gate 		return (gettext("main mode (identity protect)"));
13617c478bd9Sstevel@tonic-gate 	case IKE_XCHG_AUTH_ONLY:
13627c478bd9Sstevel@tonic-gate 		return (gettext("authentication only"));
13637c478bd9Sstevel@tonic-gate 	case IKE_XCHG_AGGRESSIVE:
13647c478bd9Sstevel@tonic-gate 		return (gettext("aggressive mode"));
13657c478bd9Sstevel@tonic-gate 	case IKE_XCHG_IP_AND_AGGR:
13667c478bd9Sstevel@tonic-gate 		return (gettext("main and aggressive mode"));
13677c478bd9Sstevel@tonic-gate 	case IKE_XCHG_ANY:
13687c478bd9Sstevel@tonic-gate 		return (gettext("any mode"));
13697c478bd9Sstevel@tonic-gate 	default:
13707c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
13717c478bd9Sstevel@tonic-gate 		    gettext("<unknown %d>"), xchg);
13727c478bd9Sstevel@tonic-gate 		return (rtn);
13737c478bd9Sstevel@tonic-gate 	}
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate static char *
statestr(int state)13777c478bd9Sstevel@tonic-gate statestr(int state)
13787c478bd9Sstevel@tonic-gate {
13797c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate 	switch (state) {
13827c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_INIT:
13837c478bd9Sstevel@tonic-gate 		return (gettext("INITIALIZING"));
13847c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_SENT_SA:
13857c478bd9Sstevel@tonic-gate 		return (gettext("SENT FIRST MSG (SA)"));
13867c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_SENT_KE:
13877c478bd9Sstevel@tonic-gate 		return (gettext("SENT SECOND MSG (KE)"));
13887c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_SENT_LAST:
13897c478bd9Sstevel@tonic-gate 		return (gettext("SENT FINAL MSG"));
13907c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_DONE:
13917c478bd9Sstevel@tonic-gate 		return (gettext("ACTIVE"));
13927c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_DELETED:
13937c478bd9Sstevel@tonic-gate 		return (gettext("DELETED"));
13947c478bd9Sstevel@tonic-gate 	case IKE_SA_STATE_INVALID:
13957c478bd9Sstevel@tonic-gate 		return (gettext("<invalid>"));
13967c478bd9Sstevel@tonic-gate 	default:
13977c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
13987c478bd9Sstevel@tonic-gate 		    gettext("<unknown %d>"), state);
13997c478bd9Sstevel@tonic-gate 		return (rtn);
14007c478bd9Sstevel@tonic-gate 	}
14017c478bd9Sstevel@tonic-gate }
14027c478bd9Sstevel@tonic-gate 
14037c478bd9Sstevel@tonic-gate static char *
authmethstr(int meth)14047c478bd9Sstevel@tonic-gate authmethstr(int meth)
14057c478bd9Sstevel@tonic-gate {
14067c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	switch (meth) {
14097c478bd9Sstevel@tonic-gate 	case IKE_AUTH_METH_PRE_SHARED_KEY:
14107c478bd9Sstevel@tonic-gate 		return (gettext("pre-shared key"));
14117c478bd9Sstevel@tonic-gate 	case IKE_AUTH_METH_DSS_SIG:
14127c478bd9Sstevel@tonic-gate 		return (gettext("DSS signatures"));
14137c478bd9Sstevel@tonic-gate 	case IKE_AUTH_METH_RSA_SIG:
14147c478bd9Sstevel@tonic-gate 		return (gettext("RSA signatures"));
14157c478bd9Sstevel@tonic-gate 	case IKE_AUTH_METH_RSA_ENCR:
14167c478bd9Sstevel@tonic-gate 		return (gettext("RSA Encryption"));
14177c478bd9Sstevel@tonic-gate 	case IKE_AUTH_METH_RSA_ENCR_REVISED:
14187c478bd9Sstevel@tonic-gate 		return (gettext("Revised RSA Encryption"));
14197c478bd9Sstevel@tonic-gate 	default:
14207c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
14217c478bd9Sstevel@tonic-gate 		    gettext("<unknown %d>"), meth);
14227c478bd9Sstevel@tonic-gate 		return (rtn);
14237c478bd9Sstevel@tonic-gate 	}
14247c478bd9Sstevel@tonic-gate }
14257c478bd9Sstevel@tonic-gate 
14267c478bd9Sstevel@tonic-gate static char *
prfstr(int prf)14277c478bd9Sstevel@tonic-gate prfstr(int prf)
14287c478bd9Sstevel@tonic-gate {
14297c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 	switch (prf) {
14327c478bd9Sstevel@tonic-gate 	case IKE_PRF_NONE:
1433349233acSpwernau 		return (gettext("<none/unavailable>"));
14347c478bd9Sstevel@tonic-gate 	case IKE_PRF_HMAC_MD5:
14357c478bd9Sstevel@tonic-gate 		return ("HMAC MD5");
14367c478bd9Sstevel@tonic-gate 	case IKE_PRF_HMAC_SHA1:
14377c478bd9Sstevel@tonic-gate 		return ("HMAC SHA1");
14380358d3a6Sdanmcd 	case IKE_PRF_HMAC_SHA256:
14390358d3a6Sdanmcd 		return ("HMAC SHA256");
14400358d3a6Sdanmcd 	case IKE_PRF_HMAC_SHA384:
14410358d3a6Sdanmcd 		return ("HMAC SHA384");
14420358d3a6Sdanmcd 	case IKE_PRF_HMAC_SHA512:
14430358d3a6Sdanmcd 		return ("HMAC SHA512");
14447c478bd9Sstevel@tonic-gate 	default:
14457c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE,
14467c478bd9Sstevel@tonic-gate 		    gettext("<unknown %d>"), prf);
14477c478bd9Sstevel@tonic-gate 		return (rtn);
14487c478bd9Sstevel@tonic-gate 	}
14497c478bd9Sstevel@tonic-gate }
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate static char *
dhstr(int grp)14527c478bd9Sstevel@tonic-gate dhstr(int grp)
14537c478bd9Sstevel@tonic-gate {
14547c478bd9Sstevel@tonic-gate 	static char	rtn[MAXLINESIZE];
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate 	switch (grp) {
14577c478bd9Sstevel@tonic-gate 	case 0:
1458020bf065Smarkfen 		return (gettext("<unavailable>"));
14597c478bd9Sstevel@tonic-gate 	case IKE_GRP_DESC_MODP_768:
1460020bf065Smarkfen 		return (gettext("768-bit MODP (group 1)"));
14617c478bd9Sstevel@tonic-gate 	case IKE_GRP_DESC_MODP_1024:
1462020bf065Smarkfen 		return (gettext("1024-bit MODP (group 2)"));
14637c478bd9Sstevel@tonic-gate 	case IKE_GRP_DESC_EC2N_155:
14647c478bd9Sstevel@tonic-gate 		return (gettext("EC2N group on GP[2^155]"));
14657c478bd9Sstevel@tonic-gate 	case IKE_GRP_DESC_EC2N_185:
14667c478bd9Sstevel@tonic-gate 		return (gettext("EC2N group on GP[2^185]"));
14677c478bd9Sstevel@tonic-gate 	case IKE_GRP_DESC_MODP_1536:
1468020bf065Smarkfen 		return (gettext("1536-bit MODP (group 5)"));
1469020bf065Smarkfen 	case IKE_GRP_DESC_MODP_2048:
1470020bf065Smarkfen 		return (gettext("2048-bit MODP (group 14)"));
1471020bf065Smarkfen 	case IKE_GRP_DESC_MODP_3072:
1472020bf065Smarkfen 		return (gettext("3072-bit MODP (group 15)"));
1473020bf065Smarkfen 	case IKE_GRP_DESC_MODP_4096:
1474020bf065Smarkfen 		return (gettext("4096-bit MODP (group 16)"));
1475020bf065Smarkfen 	case IKE_GRP_DESC_MODP_6144:
1476020bf065Smarkfen 		return (gettext("6144-bit MODP (group 17)"));
1477020bf065Smarkfen 	case IKE_GRP_DESC_MODP_8192:
1478020bf065Smarkfen 		return (gettext("8192-bit MODP (group 18)"));
147946c08a97SBill Sommerfeld 	case IKE_GRP_DESC_ECP_256:
148046c08a97SBill Sommerfeld 		return (gettext("256-bit ECP (group 19)"));
148146c08a97SBill Sommerfeld 	case IKE_GRP_DESC_ECP_384:
148246c08a97SBill Sommerfeld 		return (gettext("384-bit ECP (group 20)"));
148346c08a97SBill Sommerfeld 	case IKE_GRP_DESC_ECP_521:
148446c08a97SBill Sommerfeld 		return (gettext("521-bit ECP (group 21)"));
148546c08a97SBill Sommerfeld 	case IKE_GRP_DESC_MODP_1024_160:
148646c08a97SBill Sommerfeld 		return (
148746c08a97SBill Sommerfeld 		    gettext("1024-bit MODP with 160-bit subprime (group 22)"));
148846c08a97SBill Sommerfeld 	case IKE_GRP_DESC_MODP_2048_224:
148946c08a97SBill Sommerfeld 		return (
149046c08a97SBill Sommerfeld 		    gettext("2048-bit MODP with 224-bit subprime (group 23)"));
149146c08a97SBill Sommerfeld 	case IKE_GRP_DESC_MODP_2048_256:
149246c08a97SBill Sommerfeld 		return (
149346c08a97SBill Sommerfeld 		    gettext("2048-bit MODP with 256-bit subprime (group 24)"));
149446c08a97SBill Sommerfeld 	case IKE_GRP_DESC_ECP_192:
149546c08a97SBill Sommerfeld 		return (gettext("192-bit ECP (group 25)"));
149646c08a97SBill Sommerfeld 	case IKE_GRP_DESC_ECP_224:
149746c08a97SBill Sommerfeld 		return (gettext("224-bit ECP (group 26)"));
14987c478bd9Sstevel@tonic-gate 	default:
14997c478bd9Sstevel@tonic-gate 		(void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp);
15007c478bd9Sstevel@tonic-gate 		return (rtn);
15017c478bd9Sstevel@tonic-gate 	}
15027c478bd9Sstevel@tonic-gate }
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate static void
print_hdr(char * prefix,ike_p1_hdr_t * hdrp)15057c478bd9Sstevel@tonic-gate print_hdr(char *prefix, ike_p1_hdr_t *hdrp)
15067c478bd9Sstevel@tonic-gate {
15079c2c14abSThejaswini Singarajipura 	char sbuf[TBUF_SIZE];
15089c2c14abSThejaswini Singarajipura 	char tbuf[TBUF_SIZE];
1509dc739cedSDan McDonald 	time_t ltime = (time_t)hdrp->p1hdr_dpd_time;
15109c2c14abSThejaswini Singarajipura 
15117c478bd9Sstevel@tonic-gate 	(void) printf(
15127c478bd9Sstevel@tonic-gate 	    gettext("%s Cookies: Initiator 0x%llx  Responder 0x%llx\n"),
15134b56a003SDaniel Anderson 	    prefix, ntohll(hdrp->p1hdr_cookies.cky_i),
15144b56a003SDaniel Anderson 	    ntohll(hdrp->p1hdr_cookies.cky_r));
15157c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s The local host is the %s.\n"), prefix,
15167c478bd9Sstevel@tonic-gate 	    hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder"));
15177c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix,
15187c478bd9Sstevel@tonic-gate 	    hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg));
15199c2c14abSThejaswini Singarajipura 	(void) printf(gettext("%s Current state is %s\n"), prefix,
15207c478bd9Sstevel@tonic-gate 	    statestr(hdrp->p1hdr_state));
15219c2c14abSThejaswini Singarajipura 	if (hdrp->p1hdr_support_dpd == B_FALSE) {
15229c2c14abSThejaswini Singarajipura 		return;
15239c2c14abSThejaswini Singarajipura 	}
15249c2c14abSThejaswini Singarajipura 	(void) printf(gettext("%s Dead Peer Detection (RFC 3706)"
15259c2c14abSThejaswini Singarajipura 	    " enabled"), prefix);
15269c2c14abSThejaswini Singarajipura 	if (hdrp->p1hdr_dpd_state < DPD_IN_PROGRESS) {
15279c2c14abSThejaswini Singarajipura 		(void) printf("\n");
15289c2c14abSThejaswini Singarajipura 		return;
15299c2c14abSThejaswini Singarajipura 	}
15309c2c14abSThejaswini Singarajipura 	if (strftime(tbuf, TBUF_SIZE, NULL,
1531dc739cedSDan McDonald 	    localtime(&ltime)) == 0) {
15329c2c14abSThejaswini Singarajipura 		(void) strlcpy(tbuf, gettext("<time conversion failed>"),
15339c2c14abSThejaswini Singarajipura 		    TBUF_SIZE);
15349c2c14abSThejaswini Singarajipura 	}
15359c2c14abSThejaswini Singarajipura 	(void) printf(gettext("\n%s Dead Peer Detection handshake "), prefix);
15369c2c14abSThejaswini Singarajipura 	switch (hdrp->p1hdr_dpd_state) {
15379c2c14abSThejaswini Singarajipura 	case DPD_SUCCESSFUL:
15389c2c14abSThejaswini Singarajipura 		(void) strlcpy(sbuf, gettext("was successful at "), TBUF_SIZE);
15399c2c14abSThejaswini Singarajipura 		break;
15409c2c14abSThejaswini Singarajipura 	case DPD_FAILURE:
15419c2c14abSThejaswini Singarajipura 		(void) strlcpy(sbuf, gettext("failed at "), TBUF_SIZE);
15429c2c14abSThejaswini Singarajipura 		break;
15439c2c14abSThejaswini Singarajipura 	case DPD_IN_PROGRESS:
15449c2c14abSThejaswini Singarajipura 		(void) strlcpy(sbuf, gettext("is in progress."), TBUF_SIZE);
15459c2c14abSThejaswini Singarajipura 		break;
15469c2c14abSThejaswini Singarajipura 	}
1547a14de6c8SDan McDonald 	(void) printf("%s %s", sbuf,
1548a14de6c8SDan McDonald 	    (hdrp->p1hdr_dpd_state == DPD_IN_PROGRESS) ? "" : tbuf);
15497c478bd9Sstevel@tonic-gate 	(void) printf("\n");
15507c478bd9Sstevel@tonic-gate }
15517c478bd9Sstevel@tonic-gate 
15527c478bd9Sstevel@tonic-gate static void
print_lt_limits(char * prefix,ike_p1_xform_t * xfp)15537c478bd9Sstevel@tonic-gate print_lt_limits(char *prefix, ike_p1_xform_t *xfp)
15547c478bd9Sstevel@tonic-gate {
1555510c3f91SVladimir Kotal 	char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */
1556510c3f91SVladimir Kotal 	char secs_str[SECS_STR_SIZE]; /* lifetime string representation */
1557510c3f91SVladimir Kotal 
15587c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Lifetime limits:\n"), prefix);
1559510c3f91SVladimir Kotal 	(void) printf(gettext("%s %u seconds%s; %u kbytes %sprotected\n"),
1560510c3f91SVladimir Kotal 	    prefix, xfp->p1xf_max_secs, secs2out(xfp->p1xf_max_secs,
1561510c3f91SVladimir Kotal 	    secs_str, sizeof (secs_str), SPC_BEGIN), xfp->p1xf_max_kbytes,
1562510c3f91SVladimir Kotal 	    bytecnt2out((uint64_t)xfp->p1xf_max_kbytes << 10, byte_str,
1563510c3f91SVladimir Kotal 	    sizeof (byte_str), SPC_END));
1564510c3f91SVladimir Kotal 	(void) printf(gettext("%s keying material for IPsec SAs can be "
1565510c3f91SVladimir Kotal 	    "provided %u times%s\n"), prefix, xfp->p1xf_max_keyuses,
1566510c3f91SVladimir Kotal 	    xfp->p1xf_max_keyuses == 0 ? " (no limit)" : "");
15677c478bd9Sstevel@tonic-gate }
15687c478bd9Sstevel@tonic-gate 
15697c478bd9Sstevel@tonic-gate #define	LT_USAGE_LEN	16	/* 1 uint64 + 2 uint32s */
15707c478bd9Sstevel@tonic-gate static void
print_lt_usage(char * prefix,ike_p1_stats_t * sp)15717c478bd9Sstevel@tonic-gate print_lt_usage(char *prefix, ike_p1_stats_t *sp)
15727c478bd9Sstevel@tonic-gate {
15737c478bd9Sstevel@tonic-gate 	time_t	scratch;
15747c478bd9Sstevel@tonic-gate 	char	tbuf[TBUF_SIZE];
1575510c3f91SVladimir Kotal 	char	bytestr[BYTE_STR_SIZE]; /* byte lifetime representation */
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Current usage:\n"), prefix);
15787c478bd9Sstevel@tonic-gate 	scratch = (time_t)sp->p1stat_start;
15797c478bd9Sstevel@tonic-gate 	if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0)
15807c478bd9Sstevel@tonic-gate 		(void) strlcpy(tbuf, gettext("<time conversion failed>"),
15817c478bd9Sstevel@tonic-gate 		    TBUF_SIZE);
15827c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf);
1583510c3f91SVladimir Kotal 	(void) printf(gettext("%s %u kbytes %sprotected\n"),
1584510c3f91SVladimir Kotal 	    prefix, sp->p1stat_kbytes,
1585510c3f91SVladimir Kotal 	    bytecnt2out((uint64_t)sp->p1stat_kbytes << 10, bytestr,
1586510c3f91SVladimir Kotal 	    sizeof (bytestr), SPC_END));
1587510c3f91SVladimir Kotal 	(void) printf(gettext("%s keying material for IPsec SAs provided "
1588510c3f91SVladimir Kotal 	    "%u times\n"), prefix, sp->p1stat_keyuses);
15897c478bd9Sstevel@tonic-gate }
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate static void
print_xform(char * prefix,ike_p1_xform_t * xfp,boolean_t print_lifetimes)15927c478bd9Sstevel@tonic-gate print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes)
15937c478bd9Sstevel@tonic-gate {
15947c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Authentication method: %s"), prefix,
15957c478bd9Sstevel@tonic-gate 	    authmethstr(xfp->p1xf_auth_meth));
15967c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\n%s Encryption alg: "), prefix);
15977c478bd9Sstevel@tonic-gate 	(void) dump_ealg(xfp->p1xf_encr_alg, stdout);
159820dc9b2eSvk 	if (xfp->p1xf_encr_low_bits != 0) {
159920dc9b2eSvk 		(void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits,
160020dc9b2eSvk 		    xfp->p1xf_encr_high_bits);
1601349233acSpwernau 	} else if ((xfp->p1xf_encr_low_bits == 0) &&
1602349233acSpwernau 	    (xfp->p1xf_encr_high_bits != 0)) {
1603349233acSpwernau 		/*
1604349233acSpwernau 		 * High bits is a placeholder for
1605349233acSpwernau 		 * negotiated algorithm strength
1606349233acSpwernau 		 */
1607349233acSpwernau 		(void) printf(gettext("(%d)"), xfp->p1xf_encr_high_bits);
160820dc9b2eSvk 	}
16097c478bd9Sstevel@tonic-gate 	(void) printf(gettext("; Authentication alg: "));
16107c478bd9Sstevel@tonic-gate 	(void) dump_aalg(xfp->p1xf_auth_alg, stdout);
1611349233acSpwernau 	(void) printf("\n%s ", prefix);
1612349233acSpwernau 	if (xfp->p1xf_prf != 0)
1613349233acSpwernau 		(void) printf(gettext("PRF: %s ; "), prfstr(xfp->p1xf_prf));
1614349233acSpwernau 	(void) printf(gettext("Oakley Group: %s\n"),
16157c478bd9Sstevel@tonic-gate 	    dhstr(xfp->p1xf_dh_group));
16167c478bd9Sstevel@tonic-gate 	if (xfp->p1xf_pfs == 0) {
16177c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix);
16187c478bd9Sstevel@tonic-gate 	} else {
16197c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
16207c478bd9Sstevel@tonic-gate 		    "%s Phase 2 PFS is required (Oakley Group: %s)\n"),
16217c478bd9Sstevel@tonic-gate 		    prefix, dhstr(xfp->p1xf_pfs));
16227c478bd9Sstevel@tonic-gate 	}
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate 	if (print_lifetimes)
16257c478bd9Sstevel@tonic-gate 		print_lt_limits(prefix, xfp);
16267c478bd9Sstevel@tonic-gate }
16277c478bd9Sstevel@tonic-gate 
16287c478bd9Sstevel@tonic-gate static void
print_lifetime(char * prefix,ike_p1_xform_t * xfp,ike_p1_stats_t * sp,int statlen)16297c478bd9Sstevel@tonic-gate print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp,
16307c478bd9Sstevel@tonic-gate     int statlen)
16317c478bd9Sstevel@tonic-gate {
16327c478bd9Sstevel@tonic-gate 	time_t	current, remain, exp;
16337c478bd9Sstevel@tonic-gate 	char	tbuf[TBUF_SIZE];
1634510c3f91SVladimir Kotal 	char	byte_str[BYTE_STR_SIZE]; /* byte lifetime representation */
1635510c3f91SVladimir Kotal 	char	secs_str[SECS_STR_SIZE]; /* seconds lifetime representation */
16367c478bd9Sstevel@tonic-gate 
16377c478bd9Sstevel@tonic-gate 	current = time(NULL);
16387c478bd9Sstevel@tonic-gate 
16397c478bd9Sstevel@tonic-gate 	print_lt_limits(prefix, xfp);
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate 	/*
16427c478bd9Sstevel@tonic-gate 	 * make sure the stats struct we've been passed is as big
16437c478bd9Sstevel@tonic-gate 	 * as we expect it to be.  The usage stats are at the end,
16447c478bd9Sstevel@tonic-gate 	 * so anything less than the size we expect won't work.
16457c478bd9Sstevel@tonic-gate 	 */
16467c478bd9Sstevel@tonic-gate 	if (statlen >= sizeof (ike_p1_stats_t)) {
16477c478bd9Sstevel@tonic-gate 		print_lt_usage(prefix, sp);
16487c478bd9Sstevel@tonic-gate 	} else {
16497c478bd9Sstevel@tonic-gate 		return;
16507c478bd9Sstevel@tonic-gate 	}
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Expiration info:\n"), prefix);
16537c478bd9Sstevel@tonic-gate 
16547c478bd9Sstevel@tonic-gate 	if (xfp->p1xf_max_kbytes != 0)
1655510c3f91SVladimir Kotal 		(void) printf(gettext("%s %u more bytes %scan be "
1656510c3f91SVladimir Kotal 		    "protected.\n"),
1657510c3f91SVladimir Kotal 		    prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes,
1658510c3f91SVladimir Kotal 		    bytecnt2out((uint64_t)(xfp->p1xf_max_kbytes -
1659510c3f91SVladimir Kotal 		    sp->p1stat_kbytes) << 10, byte_str, sizeof (byte_str),
1660510c3f91SVladimir Kotal 		    SPC_END));
16617c478bd9Sstevel@tonic-gate 
16627c478bd9Sstevel@tonic-gate 	if (xfp->p1xf_max_keyuses != 0)
16637c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s Keying material can be provided "
16647c478bd9Sstevel@tonic-gate 		    "%u more times.\n"), prefix,
16657c478bd9Sstevel@tonic-gate 		    xfp->p1xf_max_keyuses - sp->p1stat_keyuses);
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate 	if (xfp->p1xf_max_secs != 0) {
16687c478bd9Sstevel@tonic-gate 		exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs;
16697c478bd9Sstevel@tonic-gate 		remain = exp - current;
16707c478bd9Sstevel@tonic-gate 		if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0)
16717c478bd9Sstevel@tonic-gate 			(void) strlcpy(tbuf,
16727c478bd9Sstevel@tonic-gate 			    gettext("<time conversion failed>"), TBUF_SIZE);
1673c8393ed7Smarkfen 		/*
1674c8393ed7Smarkfen 		 * The SA may have expired but still exist because libike
1675c8393ed7Smarkfen 		 * has not freed it yet.
1676c8393ed7Smarkfen 		 */
1677510c3f91SVladimir Kotal 		if (remain > 0) {
1678c8393ed7Smarkfen 			(void) printf(gettext(
1679510c3f91SVladimir Kotal 			    "%s SA expires in %lu seconds%s\n"),
1680510c3f91SVladimir Kotal 			    prefix, remain, secs2out(remain, secs_str,
1681510c3f91SVladimir Kotal 			    sizeof (secs_str), SPC_BEGIN));
1682510c3f91SVladimir Kotal 			(void) printf(gettext("%s Time of expiration: %s\n"),
1683510c3f91SVladimir Kotal 			    prefix, tbuf);
1684510c3f91SVladimir Kotal 		} else {
1685c8393ed7Smarkfen 			(void) printf(gettext("%s SA Expired at %s\n"),
1686c8393ed7Smarkfen 			    prefix, tbuf);
1687510c3f91SVladimir Kotal 		}
16887c478bd9Sstevel@tonic-gate 	}
16897c478bd9Sstevel@tonic-gate }
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate /* used to verify structure lengths... */
16927c478bd9Sstevel@tonic-gate #define	COUNTER_32BIT	4
16937c478bd9Sstevel@tonic-gate #define	COUNTER_PAIR	8
16947c478bd9Sstevel@tonic-gate 
16957c478bd9Sstevel@tonic-gate static void
print_p1stats(char * prefix,ike_p1_stats_t * sp,int statlen,boolean_t print_lifetimes)16967c478bd9Sstevel@tonic-gate print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen,
16977c478bd9Sstevel@tonic-gate     boolean_t print_lifetimes)
16987c478bd9Sstevel@tonic-gate {
16997c478bd9Sstevel@tonic-gate 	if (statlen < COUNTER_PAIR)
17007c478bd9Sstevel@tonic-gate 		return;
17017c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s %u Quick Mode SAs created; "), prefix,
17027c478bd9Sstevel@tonic-gate 	    sp->p1stat_new_qm_sas);
17037c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%u Quick Mode SAs deleted\n"),
17047c478bd9Sstevel@tonic-gate 	    sp->p1stat_del_qm_sas);
17057c478bd9Sstevel@tonic-gate 	statlen -= COUNTER_PAIR;
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate 	if ((print_lifetimes) && (statlen >= LT_USAGE_LEN))
17087c478bd9Sstevel@tonic-gate 		print_lt_usage(prefix, sp);
17097c478bd9Sstevel@tonic-gate }
17107c478bd9Sstevel@tonic-gate 
17117c478bd9Sstevel@tonic-gate static void
print_errs(char * prefix,ike_p1_errors_t * errp,int errlen)17127c478bd9Sstevel@tonic-gate print_errs(char *prefix, ike_p1_errors_t *errp, int errlen)
17137c478bd9Sstevel@tonic-gate {
17147c478bd9Sstevel@tonic-gate 	/*
17157c478bd9Sstevel@tonic-gate 	 * Don't try to break this one up; it's either all or nothing!
17167c478bd9Sstevel@tonic-gate 	 */
17177c478bd9Sstevel@tonic-gate 	if (errlen < sizeof (ike_p1_errors_t))
17187c478bd9Sstevel@tonic-gate 		return;
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s %u RX errors: "), prefix,
17217c478bd9Sstevel@tonic-gate 	    errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx);
17227c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%u decryption, %u hash, %u other\n"),
17237c478bd9Sstevel@tonic-gate 	    errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx);
17247c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx);
17257c478bd9Sstevel@tonic-gate }
17267c478bd9Sstevel@tonic-gate 
17277c478bd9Sstevel@tonic-gate static void
print_addr_range(char * prefix,ike_addr_pr_t * pr)17287c478bd9Sstevel@tonic-gate print_addr_range(char *prefix, ike_addr_pr_t *pr)
17297c478bd9Sstevel@tonic-gate {
17307c478bd9Sstevel@tonic-gate 	boolean_t	range = B_TRUE;
17317c478bd9Sstevel@tonic-gate 	struct sockaddr_storage	*beg, *end;
17327c478bd9Sstevel@tonic-gate 	struct sockaddr_in	*bsin, *esin;
17337c478bd9Sstevel@tonic-gate 	struct sockaddr_in6	*bsin6, *esin6;
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 	beg = &pr->beg_iprange;
17367c478bd9Sstevel@tonic-gate 	end = &pr->end_iprange;
17377c478bd9Sstevel@tonic-gate 
17387c478bd9Sstevel@tonic-gate 	if (beg->ss_family != end->ss_family) {
17397c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s invalid address range\n"), prefix);
17407c478bd9Sstevel@tonic-gate 		return;
17417c478bd9Sstevel@tonic-gate 	}
17427c478bd9Sstevel@tonic-gate 
17437c478bd9Sstevel@tonic-gate 	switch (beg->ss_family) {
17447c478bd9Sstevel@tonic-gate 	case AF_INET:
17457c478bd9Sstevel@tonic-gate 		bsin = (struct sockaddr_in *)beg;
17467c478bd9Sstevel@tonic-gate 		esin = (struct sockaddr_in *)end;
17477c478bd9Sstevel@tonic-gate 		if ((uint32_t)bsin->sin_addr.s_addr ==
17487c478bd9Sstevel@tonic-gate 		    (uint32_t)esin->sin_addr.s_addr)
17497c478bd9Sstevel@tonic-gate 			range = B_FALSE;
17507c478bd9Sstevel@tonic-gate 		break;
17517c478bd9Sstevel@tonic-gate 	case AF_INET6:
17527c478bd9Sstevel@tonic-gate 		bsin6 = (struct sockaddr_in6 *)beg;
17537c478bd9Sstevel@tonic-gate 		esin6 = (struct sockaddr_in6 *)end;
17547c478bd9Sstevel@tonic-gate 		if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr))
17557c478bd9Sstevel@tonic-gate 			range = B_FALSE;
17567c478bd9Sstevel@tonic-gate 		break;
17577c478bd9Sstevel@tonic-gate 	default:
17587c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s invalid address range\n"), prefix);
17597c478bd9Sstevel@tonic-gate 		return;
17607c478bd9Sstevel@tonic-gate 	}
17617c478bd9Sstevel@tonic-gate 
17627c478bd9Sstevel@tonic-gate 	(void) printf("%s ", prefix);
1763bb3ed8dfSpwernau 	(void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag);
17647c478bd9Sstevel@tonic-gate 	if (range) {
17657c478bd9Sstevel@tonic-gate 		(void) printf(" - ");
1766bb3ed8dfSpwernau 		(void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout,
1767bb3ed8dfSpwernau 		    nflag);
17687c478bd9Sstevel@tonic-gate 	}
17697c478bd9Sstevel@tonic-gate 	(void) printf("\n");
17707c478bd9Sstevel@tonic-gate 
17717c478bd9Sstevel@tonic-gate }
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate /*
17747c478bd9Sstevel@tonic-gate  * used to tell printing function if info should be identified
17757c478bd9Sstevel@tonic-gate  * as belonging to initiator, responder, or neither
17767c478bd9Sstevel@tonic-gate  */
17777c478bd9Sstevel@tonic-gate #define	IS_INITIATOR	1
17787c478bd9Sstevel@tonic-gate #define	IS_RESPONDER	2
17797c478bd9Sstevel@tonic-gate #define	DONT_PRINT_INIT	3
17807c478bd9Sstevel@tonic-gate 
17817c478bd9Sstevel@tonic-gate static void
print_addr(char * prefix,struct sockaddr_storage * sa,int init_instr,int mask)178241c215c2SPaul Wernau print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr,
178341c215c2SPaul Wernau     int mask)
17847c478bd9Sstevel@tonic-gate {
17857c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Address"), prefix);
17867c478bd9Sstevel@tonic-gate 
17877c478bd9Sstevel@tonic-gate 	if (init_instr != DONT_PRINT_INIT)
17887c478bd9Sstevel@tonic-gate 		(void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ?
17897c478bd9Sstevel@tonic-gate 		    gettext("Initiator") : gettext("Responder"));
17907c478bd9Sstevel@tonic-gate 	else
17917c478bd9Sstevel@tonic-gate 		(void) printf(":\n");
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate 	(void) printf("%s ", prefix);
179441c215c2SPaul Wernau 	(void) dump_sockaddr((struct sockaddr *)sa, mask, B_FALSE, stdout,
179541c215c2SPaul Wernau 	    nflag);
17967c478bd9Sstevel@tonic-gate }
17977c478bd9Sstevel@tonic-gate 
17987c478bd9Sstevel@tonic-gate static void
print_id(char * prefix,sadb_ident_t * idp,int init_instr)17997c478bd9Sstevel@tonic-gate print_id(char *prefix, sadb_ident_t *idp, int init_instr)
18007c478bd9Sstevel@tonic-gate {
18017c478bd9Sstevel@tonic-gate 	boolean_t	canprint;
18027c478bd9Sstevel@tonic-gate 
18037c478bd9Sstevel@tonic-gate 	switch (init_instr) {
18047c478bd9Sstevel@tonic-gate 	case IS_INITIATOR:
18057c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s Initiator identity, "), prefix);
18067c478bd9Sstevel@tonic-gate 		break;
18077c478bd9Sstevel@tonic-gate 	case IS_RESPONDER:
18087c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s Responder identity, "), prefix);
18097c478bd9Sstevel@tonic-gate 		break;
18107c478bd9Sstevel@tonic-gate 	case DONT_PRINT_INIT:
18117c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s Identity, "), prefix);
18127c478bd9Sstevel@tonic-gate 		break;
18137c478bd9Sstevel@tonic-gate 	default:
18147c478bd9Sstevel@tonic-gate 		(void) printf(gettext("<invalid identity>\n"));
18157c478bd9Sstevel@tonic-gate 		return;
18167c478bd9Sstevel@tonic-gate 	}
18177c478bd9Sstevel@tonic-gate 	(void) printf(gettext("uid=%d, type "), idp->sadb_ident_id);
18187c478bd9Sstevel@tonic-gate 	canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL);
1819a12f8217Spwernau 	if (canprint) {
18207c478bd9Sstevel@tonic-gate 		(void) printf("\n%s %s\n", prefix, (char *)(idp + 1));
1821a12f8217Spwernau 	} else {
1822a12f8217Spwernau 		(void) printf(gettext("\n%s "), prefix);
1823a12f8217Spwernau 		print_asn1_name(stdout,
1824a12f8217Spwernau 		    (const unsigned char *)(idp + 1),
1825a12f8217Spwernau 		    SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t));
1826a12f8217Spwernau 	}
18277c478bd9Sstevel@tonic-gate }
18287c478bd9Sstevel@tonic-gate 
18297c478bd9Sstevel@tonic-gate static void
print_idspec(char * prefix,char * idp,int icnt,int ecnt)18307c478bd9Sstevel@tonic-gate print_idspec(char *prefix, char *idp, int icnt, int ecnt)
18317c478bd9Sstevel@tonic-gate {
18327c478bd9Sstevel@tonic-gate 	int	i;
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate 	(void) printf(gettext("%s Identity descriptors:\n"), prefix);
18357c478bd9Sstevel@tonic-gate 
18367c478bd9Sstevel@tonic-gate 	for (i = 0; i < icnt; i++) {
18377c478bd9Sstevel@tonic-gate 		if (i == 0)
18387c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s Includes:\n"), prefix);
18397c478bd9Sstevel@tonic-gate 		(void) printf("%s    %s\n", prefix, idp);
18407c478bd9Sstevel@tonic-gate 		idp += strlen(idp) + 1;
18417c478bd9Sstevel@tonic-gate 	}
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate 	for (i = 0; i < ecnt; i++) {
18447c478bd9Sstevel@tonic-gate 		if (i == 0)
18457c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s Excludes:\n"), prefix);
18467c478bd9Sstevel@tonic-gate 		(void) printf("%s    %s\n", prefix, idp);
18477c478bd9Sstevel@tonic-gate 		idp += strlen(idp) + 1;
18487c478bd9Sstevel@tonic-gate 	}
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate static void
print_keys(char * prefix,ike_p1_key_t * keyp,int size)18527c478bd9Sstevel@tonic-gate print_keys(char *prefix, ike_p1_key_t *keyp, int size)
18537c478bd9Sstevel@tonic-gate {
18547c478bd9Sstevel@tonic-gate 	uint32_t	*curp;
18557c478bd9Sstevel@tonic-gate 	ike_p1_key_t	*p;
18567c478bd9Sstevel@tonic-gate 	int		ssize;
18577c478bd9Sstevel@tonic-gate 
18587c478bd9Sstevel@tonic-gate 	curp = (uint32_t *)keyp;
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate 	ssize = sizeof (ike_p1_key_t);
18617c478bd9Sstevel@tonic-gate 
18627c478bd9Sstevel@tonic-gate 	while ((intptr_t)curp - (intptr_t)keyp < size) {
18637c478bd9Sstevel@tonic-gate 		size_t p1klen, len;
18647c478bd9Sstevel@tonic-gate 
18657c478bd9Sstevel@tonic-gate 		p = (ike_p1_key_t *)curp;
18667c478bd9Sstevel@tonic-gate 		p1klen = p->p1key_len;
18677c478bd9Sstevel@tonic-gate 		len = p1klen - ssize;
18687c478bd9Sstevel@tonic-gate 
18697c478bd9Sstevel@tonic-gate 		p1klen = roundup(p1klen, sizeof (ike_p1_key_t));
18707c478bd9Sstevel@tonic-gate 		if (p1klen < ssize) {
18717c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Short key\n"));
18727c478bd9Sstevel@tonic-gate 			break;
18737c478bd9Sstevel@tonic-gate 		}
18747c478bd9Sstevel@tonic-gate 
18757c478bd9Sstevel@tonic-gate 		switch (p->p1key_type) {
18767c478bd9Sstevel@tonic-gate 		case IKE_KEY_PRESHARED:
18777c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s Pre-shared key (%d bytes): "),
18787c478bd9Sstevel@tonic-gate 			    prefix, len);
18797c478bd9Sstevel@tonic-gate 			break;
18807c478bd9Sstevel@tonic-gate 		case IKE_KEY_SKEYID:
18817c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s SKEYID (%d bytes): "),
18827c478bd9Sstevel@tonic-gate 			    prefix, len);
18837c478bd9Sstevel@tonic-gate 			break;
18847c478bd9Sstevel@tonic-gate 		case IKE_KEY_SKEYID_D:
18857c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s SKEYID_d (%d bytes): "),
18867c478bd9Sstevel@tonic-gate 			    prefix, len);
18877c478bd9Sstevel@tonic-gate 			break;
18887c478bd9Sstevel@tonic-gate 		case IKE_KEY_SKEYID_A:
18897c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s SKEYID_a (%d bytes): "),
18907c478bd9Sstevel@tonic-gate 			    prefix, len);
18917c478bd9Sstevel@tonic-gate 			break;
18927c478bd9Sstevel@tonic-gate 		case IKE_KEY_SKEYID_E:
18937c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s SKEYID_e (%d bytes): "),
18947c478bd9Sstevel@tonic-gate 			    prefix, len);
18957c478bd9Sstevel@tonic-gate 			break;
18967c478bd9Sstevel@tonic-gate 		case IKE_KEY_ENCR:
18977c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s Encryption key (%d bytes): "),
18987c478bd9Sstevel@tonic-gate 			    prefix, len);
18997c478bd9Sstevel@tonic-gate 			break;
19007c478bd9Sstevel@tonic-gate 		case IKE_KEY_IV:
19017c478bd9Sstevel@tonic-gate 			(void) printf(
19027c478bd9Sstevel@tonic-gate 			    gettext("%s Initialization vector (%d bytes): "),
19037c478bd9Sstevel@tonic-gate 			    prefix, len);
19047c478bd9Sstevel@tonic-gate 			break;
19057c478bd9Sstevel@tonic-gate 		default:
19067c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s Unidentified key info %p %d"),
19077c478bd9Sstevel@tonic-gate 			    prefix, p, p1klen);
1908d0115d88SMark Fenwick 			goto badkey;
19097c478bd9Sstevel@tonic-gate 		}
1910d0115d88SMark Fenwick 		(void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 0,
1911d0115d88SMark Fenwick 		    stdout, B_FALSE);
1912d0115d88SMark Fenwick badkey:
19137c478bd9Sstevel@tonic-gate 		(void) printf("\n");
19147c478bd9Sstevel@tonic-gate 		assert(IS_P2ALIGNED(p1klen, 8));
19157c478bd9Sstevel@tonic-gate 		curp += (p1klen >> 2);
19167c478bd9Sstevel@tonic-gate 	}
19177c478bd9Sstevel@tonic-gate }
19187c478bd9Sstevel@tonic-gate 
19195d01c172SVladimir Kotal static void
print_group_header(void)19205d01c172SVladimir Kotal print_group_header(void)
19215d01c172SVladimir Kotal {
19225d01c172SVladimir Kotal 	(void) printf(gettext("\nList of Diffie-Hellman groups for setting "
19235d01c172SVladimir Kotal 	    "up IKE SAs"));
19245d01c172SVladimir Kotal 	(void) printf(gettext("\nThe values match the IPsec attribute "
19255d01c172SVladimir Kotal 	    "assigned numbers published by IANA\n\n"));
19265d01c172SVladimir Kotal 	(void) printf("%-6s%-9s%-50s\n",
19275d01c172SVladimir Kotal 	    gettext("Value"), gettext("Strength"), gettext("Description"));
19285d01c172SVladimir Kotal }
19295d01c172SVladimir Kotal 
19305d01c172SVladimir Kotal static void
print_group(ike_group_t * gp)19315d01c172SVladimir Kotal print_group(ike_group_t *gp)
19325d01c172SVladimir Kotal {
19335d01c172SVladimir Kotal 	(void) printf("%-6u%-9u%-50s\n",
19345d01c172SVladimir Kotal 	    gp->group_number, gp->group_bits, gp->group_label);
19355d01c172SVladimir Kotal }
19365d01c172SVladimir Kotal 
19375d01c172SVladimir Kotal static void
print_encralg_header(void)19385d01c172SVladimir Kotal print_encralg_header(void)
19395d01c172SVladimir Kotal {
19405d01c172SVladimir Kotal 	(void) printf(gettext("\nList of encryption algorithms for IKE"));
19415d01c172SVladimir Kotal 	(void) printf(gettext("\nThe values match the IPsec attribute "
19425d01c172SVladimir Kotal 	    "assigned numbers published by IANA\n\n"));
19435d01c172SVladimir Kotal 	(void) printf("%-6s%-20s%-15s\n", gettext("Value"),
19445d01c172SVladimir Kotal 	    gettext("Name"), gettext("Keylen range"));
19455d01c172SVladimir Kotal }
19465d01c172SVladimir Kotal 
19475d01c172SVladimir Kotal static void
print_encralg(ike_encralg_t * ep)19485d01c172SVladimir Kotal print_encralg(ike_encralg_t *ep)
19495d01c172SVladimir Kotal {
19505d01c172SVladimir Kotal 	char keylen_str[16];
19515d01c172SVladimir Kotal 
19525d01c172SVladimir Kotal 	(void) strlcpy(keylen_str, "N/A", sizeof (keylen_str));
19535d01c172SVladimir Kotal 	if (ep->encr_keylen_min != 0 || ep->encr_keylen_max != 0)
19545d01c172SVladimir Kotal 		(void) snprintf(keylen_str, sizeof (keylen_str), "%d-%d",
19555d01c172SVladimir Kotal 		    ep->encr_keylen_min, ep->encr_keylen_max);
19565d01c172SVladimir Kotal 	(void) printf("%-6u%-20s%-15s\n",
19575d01c172SVladimir Kotal 	    ep->encr_value, ep->encr_name, keylen_str);
19585d01c172SVladimir Kotal }
19595d01c172SVladimir Kotal 
19605d01c172SVladimir Kotal static void
print_authalg_header(void)19615d01c172SVladimir Kotal print_authalg_header(void)
19625d01c172SVladimir Kotal {
19635d01c172SVladimir Kotal 	(void) printf(gettext("\nList of authentication algorithms for IKE"));
19645d01c172SVladimir Kotal 	(void) printf(gettext("\nThe values match the IPsec attribute "
19655d01c172SVladimir Kotal 	    "assigned numbers published by IANA\n\n"));
19665d01c172SVladimir Kotal 	(void) printf("%-6s%-20s\n", gettext("Value"), gettext("Name"));
19675d01c172SVladimir Kotal }
19685d01c172SVladimir Kotal 
19695d01c172SVladimir Kotal static void
print_authalg(ike_authalg_t * ap)19705d01c172SVladimir Kotal print_authalg(ike_authalg_t *ap)
19715d01c172SVladimir Kotal {
19725d01c172SVladimir Kotal 	(void) printf("%-6u%-20s\n",
19735d01c172SVladimir Kotal 	    ap->auth_value, ap->auth_name);
19745d01c172SVladimir Kotal }
19755d01c172SVladimir Kotal 
19767c478bd9Sstevel@tonic-gate static void
print_p1(ike_p1_sa_t * p1)19777c478bd9Sstevel@tonic-gate print_p1(ike_p1_sa_t *p1)
19787c478bd9Sstevel@tonic-gate {
19797c478bd9Sstevel@tonic-gate 	ike_p1_stats_t	*sp;
19807c478bd9Sstevel@tonic-gate 	ike_p1_errors_t	*ep;
19817c478bd9Sstevel@tonic-gate 	ike_p1_key_t	*kp;
19827c478bd9Sstevel@tonic-gate 	sadb_ident_t	*lidp, *ridp;
19837c478bd9Sstevel@tonic-gate 	int		lstat, rstat;
19847c478bd9Sstevel@tonic-gate 
19857c478bd9Sstevel@tonic-gate 	(void) printf("\n");
19867c478bd9Sstevel@tonic-gate 	print_hdr("IKESA:", &p1->p1sa_hdr);
19877c478bd9Sstevel@tonic-gate 	print_xform("XFORM:", &p1->p1sa_xform, B_FALSE);
19887c478bd9Sstevel@tonic-gate 
19897c478bd9Sstevel@tonic-gate 	if (p1->p1sa_hdr.p1hdr_isinit) {
19907c478bd9Sstevel@tonic-gate 		lstat = IS_INITIATOR;
19917c478bd9Sstevel@tonic-gate 		rstat = IS_RESPONDER;
19927c478bd9Sstevel@tonic-gate 	} else {
19937c478bd9Sstevel@tonic-gate 		lstat = IS_RESPONDER;
19947c478bd9Sstevel@tonic-gate 		rstat = IS_INITIATOR;
19957c478bd9Sstevel@tonic-gate 	}
199641c215c2SPaul Wernau 	print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat, 0);
199741c215c2SPaul Wernau 	print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat, 0);
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate 	/*
20007c478bd9Sstevel@tonic-gate 	 * the stat len might be 0; but still make the call
20017c478bd9Sstevel@tonic-gate 	 * to print_lifetime() to pick up the xform info
20027c478bd9Sstevel@tonic-gate 	 */
20037c478bd9Sstevel@tonic-gate 	sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off);
20047c478bd9Sstevel@tonic-gate 	print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len);
20057c478bd9Sstevel@tonic-gate 
20067c478bd9Sstevel@tonic-gate 	if (p1->p1sa_stat_len > 0) {
20077c478bd9Sstevel@tonic-gate 		print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE);
20087c478bd9Sstevel@tonic-gate 	}
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate 	if (p1->p1sa_error_len > 0) {
20117c478bd9Sstevel@tonic-gate 		ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off);
20127c478bd9Sstevel@tonic-gate 		print_errs("ERRS: ", ep, p1->p1sa_error_len);
20137c478bd9Sstevel@tonic-gate 	}
20147c478bd9Sstevel@tonic-gate 
20157c478bd9Sstevel@tonic-gate 	if (p1->p1sa_localid_len > 0) {
20167c478bd9Sstevel@tonic-gate 		lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off);
20177c478bd9Sstevel@tonic-gate 		print_id("LOCID:", lidp, lstat);
20187c478bd9Sstevel@tonic-gate 	}
20197c478bd9Sstevel@tonic-gate 
20207c478bd9Sstevel@tonic-gate 	if (p1->p1sa_remoteid_len > 0) {
20217c478bd9Sstevel@tonic-gate 		ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off);
20227c478bd9Sstevel@tonic-gate 		print_id("REMID:", ridp, rstat);
20237c478bd9Sstevel@tonic-gate 	}
20247c478bd9Sstevel@tonic-gate 
20257c478bd9Sstevel@tonic-gate 	if (p1->p1sa_key_len > 0) {
20267c478bd9Sstevel@tonic-gate 		kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off);
20277c478bd9Sstevel@tonic-gate 		print_keys("KEY:  ", kp, p1->p1sa_key_len);
20287c478bd9Sstevel@tonic-gate 	}
20297c478bd9Sstevel@tonic-gate }
20307c478bd9Sstevel@tonic-gate 
2031c7777ac8SPaul Wernau static void
print_certcache(ike_certcache_t * c)2032c7777ac8SPaul Wernau print_certcache(ike_certcache_t *c)
2033c7777ac8SPaul Wernau {
2034c7777ac8SPaul Wernau 	(void) printf("\n");
2035c7777ac8SPaul Wernau 
2036c7777ac8SPaul Wernau 	(void) printf(gettext("CERTIFICATE CACHE ID: %d\n"), c->cache_id);
2037c7777ac8SPaul Wernau 	(void) printf(gettext("\tSubject Name: <%s>\n"),
203878af48deSToomas Soome 	    (*c->subject != '\0') ? c->subject : gettext("Name unavailable"));
2039c7777ac8SPaul Wernau 	(void) printf(gettext("\t Issuer Name: <%s>\n"),
204078af48deSToomas Soome 	    (*c->issuer != '\0') ? c->issuer : gettext("Name unavailable"));
2041510c3f91SVladimir Kotal 	if ((int)c->certclass == -1)
2042c7777ac8SPaul Wernau 		(void) printf(gettext("\t\t[trusted certificate]\n"));
2043c7777ac8SPaul Wernau 	switch (c->linkage) {
2044c7777ac8SPaul Wernau 	case CERT_OFF_WIRE:
2045c7777ac8SPaul Wernau 		(void) printf(gettext("\t\t[Public certificate only]\n"));
2046c7777ac8SPaul Wernau 		(void) printf(gettext(
2047c7777ac8SPaul Wernau 		    "\t\t[Obtained via certificate payload]\n"));
2048c7777ac8SPaul Wernau 		break;
2049c7777ac8SPaul Wernau 	case CERT_NO_PRIVKEY:
2050c7777ac8SPaul Wernau 		(void) printf(gettext("\t\t[Public certificate only]\n"));
2051c7777ac8SPaul Wernau 		break;
2052c7777ac8SPaul Wernau 	case CERT_PRIVKEY_LOCKED:
2053c7777ac8SPaul Wernau 		(void) printf(gettext(
2054c7777ac8SPaul Wernau 		    "\t\t[Private key linked but locked]\n"));
2055c7777ac8SPaul Wernau 		break;
2056c7777ac8SPaul Wernau 	case CERT_PRIVKEY_AVAIL:
2057c7777ac8SPaul Wernau 		(void) printf(gettext("\t\t[Private key available]\n"));
2058c7777ac8SPaul Wernau 		break;
2059c7777ac8SPaul Wernau 	}
2060c7777ac8SPaul Wernau }
2061c7777ac8SPaul Wernau 
20627c478bd9Sstevel@tonic-gate static void
print_ps(ike_ps_t * ps)20637c478bd9Sstevel@tonic-gate print_ps(ike_ps_t *ps)
20647c478bd9Sstevel@tonic-gate {
20657c478bd9Sstevel@tonic-gate 	sadb_ident_t	*lidp, *ridp;
20667c478bd9Sstevel@tonic-gate 	uint8_t		*keyp;
20677c478bd9Sstevel@tonic-gate 
20687c478bd9Sstevel@tonic-gate 	(void) printf("\n");
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 	(void) printf(gettext("PSKEY: For %s exchanges\n"),
20717c478bd9Sstevel@tonic-gate 	    xchgstr(ps->ps_ike_mode));
20727c478bd9Sstevel@tonic-gate 
20737c478bd9Sstevel@tonic-gate 	if (ps->ps_key_len > 0) {
20747c478bd9Sstevel@tonic-gate 		keyp = (uint8_t *)((int)(ps) + ps->ps_key_off);
20757c478bd9Sstevel@tonic-gate 		(void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "),
20767c478bd9Sstevel@tonic-gate 		    ps->ps_key_len);
2077628b0c67SMark Fenwick 		(void) dump_key(keyp, ps->ps_key_bits, 0, stdout, B_FALSE);
20787c478bd9Sstevel@tonic-gate 		(void) printf("\n");
20797c478bd9Sstevel@tonic-gate 	}
20807c478bd9Sstevel@tonic-gate 
20817c478bd9Sstevel@tonic-gate 	/*
20827c478bd9Sstevel@tonic-gate 	 * We get *either* and address or an ident, never both.  So if
20837c478bd9Sstevel@tonic-gate 	 * the ident is there, don't try printing an address.
20847c478bd9Sstevel@tonic-gate 	 */
20857c478bd9Sstevel@tonic-gate 	if (ps->ps_localid_len > 0) {
20867c478bd9Sstevel@tonic-gate 		lidp = (sadb_ident_t *)
20877c478bd9Sstevel@tonic-gate 		    ((int)(ps) + ps->ps_localid_off);
20887c478bd9Sstevel@tonic-gate 		print_id("LOCID:", lidp, DONT_PRINT_INIT);
20897c478bd9Sstevel@tonic-gate 	} else {
209041c215c2SPaul Wernau 		print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT,
209141c215c2SPaul Wernau 		    ps->ps_localid_plen > 0 ? ps->ps_localid_plen : 0);
20927c478bd9Sstevel@tonic-gate 	}
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate 	if (ps->ps_remoteid_len > 0) {
20957c478bd9Sstevel@tonic-gate 		ridp = (sadb_ident_t *)
20967c478bd9Sstevel@tonic-gate 		    ((int)(ps) + ps->ps_remoteid_off);
20977c478bd9Sstevel@tonic-gate 		print_id("REMID:", ridp, DONT_PRINT_INIT);
20987c478bd9Sstevel@tonic-gate 	} else {
209941c215c2SPaul Wernau 		print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT,
210041c215c2SPaul Wernau 		    ps->ps_remoteid_plen > 0 ? ps->ps_remoteid_plen : 0);
21017c478bd9Sstevel@tonic-gate 	}
21027c478bd9Sstevel@tonic-gate }
21037c478bd9Sstevel@tonic-gate 
21047c478bd9Sstevel@tonic-gate #define	PREFIXLEN	16
21057c478bd9Sstevel@tonic-gate 
21067c478bd9Sstevel@tonic-gate static void
print_rule(ike_rule_t * rp)21077c478bd9Sstevel@tonic-gate print_rule(ike_rule_t *rp)
21087c478bd9Sstevel@tonic-gate {
21097c478bd9Sstevel@tonic-gate 	char		prefix[PREFIXLEN];
21107c478bd9Sstevel@tonic-gate 	int		i;
21117c478bd9Sstevel@tonic-gate 	ike_p1_xform_t	*xfp;
21127c478bd9Sstevel@tonic-gate 	ike_addr_pr_t	*lipp, *ripp;
21137c478bd9Sstevel@tonic-gate 	char		*lidp, *ridp;
2114510c3f91SVladimir Kotal 	char byte_str[BYTE_STR_SIZE]; /* kbyte string representation */
2115510c3f91SVladimir Kotal 	char secs_str[SECS_STR_SIZE]; /* seconds string representation */
21167c478bd9Sstevel@tonic-gate 
21177c478bd9Sstevel@tonic-gate 	(void) printf("\n");
21187c478bd9Sstevel@tonic-gate 	(void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"),
21197c478bd9Sstevel@tonic-gate 	    rp->rule_label, rp->rule_kmcookie);
21207c478bd9Sstevel@tonic-gate 	(void) printf(gettext("GLOBL: local_idtype="));
21217c478bd9Sstevel@tonic-gate 	(void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL);
21227c478bd9Sstevel@tonic-gate 	(void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode));
21230f2065ccSmarkfen 	(void) printf(gettext(
21240f2065ccSmarkfen 	    "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"),
21250f2065ccSmarkfen 	    rp->rule_p1_nonce_len, rp->rule_p2_nonce_len,
21267c478bd9Sstevel@tonic-gate 	    (rp->rule_p2_pfs) ? gettext("true") : gettext("false"),
21270f2065ccSmarkfen 	    rp->rule_p2_pfs);
21280f2065ccSmarkfen 	(void) printf(
2129510c3f91SVladimir Kotal 	    gettext("GLOBL: p2_lifetime=%u seconds%s\n"),
2130510c3f91SVladimir Kotal 	    rp->rule_p2_lifetime_secs, secs2out(rp->rule_p2_lifetime_secs,
2131510c3f91SVladimir Kotal 	    secs_str, sizeof (secs_str), SPC_BEGIN));
2132510c3f91SVladimir Kotal 	(void) printf(
2133510c3f91SVladimir Kotal 	    gettext("GLOBL: p2_softlife=%u seconds%s\n"),
2134510c3f91SVladimir Kotal 	    rp->rule_p2_softlife_secs, secs2out(rp->rule_p2_softlife_secs,
2135510c3f91SVladimir Kotal 	    secs_str, sizeof (secs_str), SPC_BEGIN));
2136510c3f91SVladimir Kotal 	(void) printf(
2137510c3f91SVladimir Kotal 	    gettext("GLOBL: p2_idletime=%u seconds%s\n"),
2138510c3f91SVladimir Kotal 	    rp->rule_p2_idletime_secs, secs2out(rp->rule_p2_idletime_secs,
2139510c3f91SVladimir Kotal 	    secs_str, sizeof (secs_str), SPC_BEGIN));
2140510c3f91SVladimir Kotal 	/*
2141510c3f91SVladimir Kotal 	 * Perform explicit conversion before passing to bytecnt2out()
2142510c3f91SVladimir Kotal 	 * to avoid integer overflow.
2143510c3f91SVladimir Kotal 	 */
21449c2c14abSThejaswini Singarajipura 	(void) printf(
2145510c3f91SVladimir Kotal 	    gettext("GLOBL: p2_lifetime_kb=%u kilobytes%s\n"),
2146510c3f91SVladimir Kotal 	    rp->rule_p2_lifetime_kb,
2147510c3f91SVladimir Kotal 	    bytecnt2out((uint64_t)(rp->rule_p2_lifetime_kb) << 10,
2148510c3f91SVladimir Kotal 	    byte_str, sizeof (byte_str), SPC_BEGIN));
21490f2065ccSmarkfen 	(void) printf(
2150510c3f91SVladimir Kotal 	    gettext("GLOBL: p2_softlife_kb=%u kilobytes%s\n"),
2151510c3f91SVladimir Kotal 	    rp->rule_p2_softlife_kb,
2152510c3f91SVladimir Kotal 	    bytecnt2out(((uint64_t)(rp->rule_p2_softlife_kb)) << 10,
2153510c3f91SVladimir Kotal 	    byte_str, sizeof (byte_str), SPC_BEGIN));
21547c478bd9Sstevel@tonic-gate 
21557c478bd9Sstevel@tonic-gate 	if (rp->rule_locip_cnt > 0) {
21567c478bd9Sstevel@tonic-gate 		(void) printf(gettext("LOCIP: IP address range(s):\n"));
21577c478bd9Sstevel@tonic-gate 		lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off);
21587c478bd9Sstevel@tonic-gate 		for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) {
21597c478bd9Sstevel@tonic-gate 			print_addr_range("LOCIP:", lipp);
21607c478bd9Sstevel@tonic-gate 		}
21617c478bd9Sstevel@tonic-gate 	}
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 	if (rp->rule_remip_cnt > 0) {
21647c478bd9Sstevel@tonic-gate 		(void) printf(gettext("REMIP: IP address range(s):\n"));
21657c478bd9Sstevel@tonic-gate 		ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off);
21667c478bd9Sstevel@tonic-gate 		for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) {
21677c478bd9Sstevel@tonic-gate 			print_addr_range("REMIP:", ripp);
21687c478bd9Sstevel@tonic-gate 		}
21697c478bd9Sstevel@tonic-gate 	}
21707c478bd9Sstevel@tonic-gate 
21717c478bd9Sstevel@tonic-gate 	if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) {
21727c478bd9Sstevel@tonic-gate 		lidp = (char *)((int)rp + rp->rule_locid_off);
21737c478bd9Sstevel@tonic-gate 		print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt,
21747c478bd9Sstevel@tonic-gate 		    rp->rule_locid_exclcnt);
21757c478bd9Sstevel@tonic-gate 	}
21767c478bd9Sstevel@tonic-gate 
21777c478bd9Sstevel@tonic-gate 	if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) {
21787c478bd9Sstevel@tonic-gate 		ridp = (char *)((int)rp + rp->rule_remid_off);
21797c478bd9Sstevel@tonic-gate 		print_idspec("REMID:", ridp, rp->rule_remid_inclcnt,
21807c478bd9Sstevel@tonic-gate 		    rp->rule_remid_exclcnt);
21817c478bd9Sstevel@tonic-gate 	}
21827c478bd9Sstevel@tonic-gate 
21837c478bd9Sstevel@tonic-gate 	if (rp->rule_xform_cnt > 0) {
21847c478bd9Sstevel@tonic-gate 		(void) printf(gettext("XFRMS: Available Transforms:\n"));
21857c478bd9Sstevel@tonic-gate 		xfp = (ike_p1_xform_t *)((int)rp +  rp->rule_xform_off);
21867c478bd9Sstevel@tonic-gate 		for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) {
21877c478bd9Sstevel@tonic-gate 			(void) snprintf(prefix, PREFIXLEN, "XF %2u:", i);
21887c478bd9Sstevel@tonic-gate 			print_xform(prefix, xfp, B_TRUE);
21897c478bd9Sstevel@tonic-gate 		}
21907c478bd9Sstevel@tonic-gate 	}
21917c478bd9Sstevel@tonic-gate }
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate #undef	PREFIXLEN
21947c478bd9Sstevel@tonic-gate 
21957c478bd9Sstevel@tonic-gate #define	PRSACNTS(init, resp) \
21967c478bd9Sstevel@tonic-gate 		(void) printf(gettext("initiator: %10u   responder: %10u\n"), \
21977c478bd9Sstevel@tonic-gate 		    (init), (resp))
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate static void
print_stats(ike_stats_t * sp,int len)22007c478bd9Sstevel@tonic-gate print_stats(ike_stats_t *sp, int len)
22017c478bd9Sstevel@tonic-gate {
22027c478bd9Sstevel@tonic-gate 	/*
22037c478bd9Sstevel@tonic-gate 	 * before printing each line, make sure the structure we were
22047c478bd9Sstevel@tonic-gate 	 * given is big enough to include the fields needed.
22057c478bd9Sstevel@tonic-gate 	 */
22067c478bd9Sstevel@tonic-gate 	if (len < COUNTER_PAIR)
22077c478bd9Sstevel@tonic-gate 		return;
22087c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Phase 1 SA counts:\n"));
22097c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Current:   "));
22107c478bd9Sstevel@tonic-gate 	PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current);
22117c478bd9Sstevel@tonic-gate 	len -= COUNTER_PAIR;
22127c478bd9Sstevel@tonic-gate 
22137c478bd9Sstevel@tonic-gate 	if (len < COUNTER_PAIR)
22147c478bd9Sstevel@tonic-gate 		return;
22157c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Total:     "));
22167c478bd9Sstevel@tonic-gate 	PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total);
22177c478bd9Sstevel@tonic-gate 	len -= COUNTER_PAIR;
22187c478bd9Sstevel@tonic-gate 
22197c478bd9Sstevel@tonic-gate 	if (len < COUNTER_PAIR)
22207c478bd9Sstevel@tonic-gate 		return;
22217c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Attempted: "));
22227c478bd9Sstevel@tonic-gate 	PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts);
22237c478bd9Sstevel@tonic-gate 	len -= COUNTER_PAIR;
22247c478bd9Sstevel@tonic-gate 
22257c478bd9Sstevel@tonic-gate 	if (len < (COUNTER_PAIR + COUNTER_32BIT))
22267c478bd9Sstevel@tonic-gate 		return;
22277c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Failed:    "));
22287c478bd9Sstevel@tonic-gate 	PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail,
22297c478bd9Sstevel@tonic-gate 	    sp->st_resp_p1_fail);
22307c478bd9Sstevel@tonic-gate 	(void) printf(
22317c478bd9Sstevel@tonic-gate 	    gettext("           initiator fails include %u time-out(s)\n"),
22327c478bd9Sstevel@tonic-gate 	    sp->st_init_p1_noresp);
22337c478bd9Sstevel@tonic-gate 
22347c478bd9Sstevel@tonic-gate 	if (len < PATH_MAX)
22357c478bd9Sstevel@tonic-gate 		return;
22367c478bd9Sstevel@tonic-gate 	if (*(sp->st_pkcs11_libname) != '\0')
22377c478bd9Sstevel@tonic-gate 		(void) printf(gettext("PKCS#11 library linked in from %s\n"),
22387c478bd9Sstevel@tonic-gate 		    sp->st_pkcs11_libname);
22397c478bd9Sstevel@tonic-gate }
22407c478bd9Sstevel@tonic-gate 
2241510c3f91SVladimir Kotal /* Print one line of 'get defaults' output (i.e. single value). */
22420f2065ccSmarkfen static void
print_defaults(char * label,char * description,char * unit,uint_t current,uint_t def)2243510c3f91SVladimir Kotal print_defaults(char *label, char *description, char *unit,
22440f2065ccSmarkfen     uint_t current, uint_t def)
22450f2065ccSmarkfen {
2246510c3f91SVladimir Kotal 	(void) printf("%-18s%-10s%11u %-10s%-26s\n", label,
22470f2065ccSmarkfen 	    (current != def) ? gettext("config") : gettext("default"),
2248510c3f91SVladimir Kotal 	    current, unit, description);
22490f2065ccSmarkfen }
22500f2065ccSmarkfen 
22510f2065ccSmarkfen /*
22520f2065ccSmarkfen  * Print out defaults used by in.iked, the argument is a buffer containing
22530f2065ccSmarkfen  * two ike_defaults_t's, the first contains the hard coded defaults, the second
22540f2065ccSmarkfen  * contains the actual values used. If these differ, then the defaults have been
22550f2065ccSmarkfen  * changed via a config file entry. Note that "-" indicates this default
2256bbf21555SRichard Lowe  * is not tunable via ike.config(5) or is system wide tunable.
22570f2065ccSmarkfen  */
22580f2065ccSmarkfen static void
do_print_defaults(ike_defaults_t * dp)22590f2065ccSmarkfen do_print_defaults(ike_defaults_t *dp)
22600f2065ccSmarkfen {
22610f2065ccSmarkfen 	ike_defaults_t *ddp;
22620f2065ccSmarkfen 	ddp = (ike_defaults_t *)(dp + 1);
22630f2065ccSmarkfen 
22640f2065ccSmarkfen 	(void) printf(gettext("\nGlobal defaults. Some values can be"
2265510c3f91SVladimir Kotal 	    " over-ridden on a per rule basis.\n"));
2266510c3f91SVladimir Kotal 	(void) printf(gettext("\nSystem defaults are time delayed.\n\n"));
22670f2065ccSmarkfen 
2268510c3f91SVladimir Kotal 	(void) printf("%-18s%-10s%-12s%-10s%-26s\n\n",
22690f2065ccSmarkfen 	    gettext("Token:"), gettext("Source:"), gettext("Value:"),
22700f2065ccSmarkfen 	    gettext("Unit:"), gettext("Description:"));
22710f2065ccSmarkfen 
2272510c3f91SVladimir Kotal 	/* iked tunables */
22730f2065ccSmarkfen 	print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"),
2274510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p1_lifetime_secs,
22750f2065ccSmarkfen 	    dp->rule_p1_lifetime_secs);
22760f2065ccSmarkfen 
22770f2065ccSmarkfen 	print_defaults("-", gettext("minimum phase 1 lifetime"),
2278510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p1_minlife,
22790f2065ccSmarkfen 	    dp->rule_p1_minlife);
22800f2065ccSmarkfen 
22810f2065ccSmarkfen 	print_defaults("p1_nonce_len", gettext("phase 1 nonce length"),
2282510c3f91SVladimir Kotal 	    gettext("bytes"), ddp->rule_p1_nonce_len,
22830f2065ccSmarkfen 	    dp->rule_p1_nonce_len);
22840f2065ccSmarkfen 
22850f2065ccSmarkfen 	print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"),
2286510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_lifetime_secs,
22870f2065ccSmarkfen 	    dp->rule_p2_lifetime_secs);
22880f2065ccSmarkfen 
22890f2065ccSmarkfen 	print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"),
2290510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_softlife_secs,
22910f2065ccSmarkfen 	    dp->rule_p2_softlife_secs);
22920f2065ccSmarkfen 
22939c2c14abSThejaswini Singarajipura 	print_defaults("p2_idletime_secs", gettext("phase 2 idle time"),
2294510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_idletime_secs,
22959c2c14abSThejaswini Singarajipura 	    dp->rule_p2_idletime_secs);
22969c2c14abSThejaswini Singarajipura 
2297510c3f91SVladimir Kotal 	print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"),
2298510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_lifetime_kb,
2299510c3f91SVladimir Kotal 	    dp->rule_p2_lifetime_kb);
2300510c3f91SVladimir Kotal 
2301510c3f91SVladimir Kotal 	print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"),
2302510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_softlife_kb,
2303510c3f91SVladimir Kotal 	    dp->rule_p2_softlife_kb);
2304510c3f91SVladimir Kotal 
2305510c3f91SVladimir Kotal 	/* system wide tunables */
23061a6921e0Smarkfen 	print_defaults("-", gettext("system phase 2 lifetime"),
2307510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->sys_p2_lifetime_secs,
23081a6921e0Smarkfen 	    dp->sys_p2_lifetime_secs);
23091a6921e0Smarkfen 
23101a6921e0Smarkfen 	print_defaults("-", gettext("system phase 2 soft lifetime"),
2311510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->sys_p2_softlife_secs,
23121a6921e0Smarkfen 	    dp->sys_p2_softlife_secs);
23131a6921e0Smarkfen 
23149c2c14abSThejaswini Singarajipura 	print_defaults("-", gettext("system phase 2 idle time"),
2315510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->sys_p2_idletime_secs,
23169c2c14abSThejaswini Singarajipura 	    dp->sys_p2_idletime_secs);
23179c2c14abSThejaswini Singarajipura 
23181a6921e0Smarkfen 	print_defaults("-", gettext("system phase 2 lifetime"),
2319510c3f91SVladimir Kotal 	    gettext("bytes"), ddp->sys_p2_lifetime_bytes,
23201a6921e0Smarkfen 	    dp->sys_p2_lifetime_bytes);
23211a6921e0Smarkfen 
23221a6921e0Smarkfen 	print_defaults("-", gettext("system phase 2 soft lifetime"),
2323510c3f91SVladimir Kotal 	    gettext("bytes"), ddp->sys_p2_softlife_bytes,
23241a6921e0Smarkfen 	    dp->sys_p2_softlife_bytes);
23251a6921e0Smarkfen 
2326510c3f91SVladimir Kotal 	/* minimum and maximum values */
2327510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 hard lifetime"),
2328510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_minlife_hard_secs,
2329510c3f91SVladimir Kotal 	    dp->rule_p2_minlife_hard_secs);
23300f2065ccSmarkfen 
2331510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 soft lifetime"),
2332510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_minlife_soft_secs,
2333510c3f91SVladimir Kotal 	    dp->rule_p2_minlife_soft_secs);
2334510c3f91SVladimir Kotal 
2335510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 idle lifetime"),
2336510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_minlife_idle_secs,
2337510c3f91SVladimir Kotal 	    dp->rule_p2_minlife_idle_secs);
23380f2065ccSmarkfen 
2339510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 hard lifetime"),
2340510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_minlife_hard_kb,
2341510c3f91SVladimir Kotal 	    dp->rule_p2_minlife_hard_kb);
23420f2065ccSmarkfen 
2343510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 soft lifetime"),
2344510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_minlife_soft_kb,
2345510c3f91SVladimir Kotal 	    dp->rule_p2_minlife_soft_kb);
2346510c3f91SVladimir Kotal 
2347510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 delta"),
2348510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_mindiff_secs,
2349510c3f91SVladimir Kotal 	    dp->rule_p2_mindiff_secs);
2350510c3f91SVladimir Kotal 
2351510c3f91SVladimir Kotal 	print_defaults("-", gettext("minimum phase 2 delta"),
2352510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_mindiff_kb,
2353510c3f91SVladimir Kotal 	    dp->rule_p2_mindiff_kb);
2354510c3f91SVladimir Kotal 
2355510c3f91SVladimir Kotal 	print_defaults("-", gettext("maximum phase 2 lifetime"),
2356510c3f91SVladimir Kotal 	    gettext("seconds"), ddp->rule_p2_maxlife_secs,
2357510c3f91SVladimir Kotal 	    dp->rule_p2_maxlife_secs);
2358510c3f91SVladimir Kotal 
2359510c3f91SVladimir Kotal 	print_defaults("-", gettext("conversion factor"),
2360510c3f91SVladimir Kotal 	    gettext("kbytes/s"), ddp->conversion_factor,
2361510c3f91SVladimir Kotal 	    dp->conversion_factor);
2362510c3f91SVladimir Kotal 
2363510c3f91SVladimir Kotal 	print_defaults("-", gettext("maximum phase 2 lifetime"),
2364510c3f91SVladimir Kotal 	    gettext("kilobytes"), ddp->rule_p2_maxlife_kb,
2365510c3f91SVladimir Kotal 	    dp->rule_p2_maxlife_kb);
2366510c3f91SVladimir Kotal 
2367510c3f91SVladimir Kotal 	/* other values */
2368510c3f91SVladimir Kotal 	print_defaults("p2_nonce_len", gettext("phase 2 nonce length"),
2369510c3f91SVladimir Kotal 	    gettext("bytes"), ddp->rule_p2_nonce_len,
2370510c3f91SVladimir Kotal 	    dp->rule_p2_nonce_len);
23710f2065ccSmarkfen 
23720f2065ccSmarkfen 	print_defaults("p2_pfs", gettext("phase 2 PFS"),
2373510c3f91SVladimir Kotal 	    " ", ddp->rule_p2_pfs, dp->rule_p2_pfs);
23740f2065ccSmarkfen 
23750f2065ccSmarkfen 	print_defaults("max_certs", gettext("max certificates"),
2376510c3f91SVladimir Kotal 	    " ", ddp->rule_max_certs, dp->rule_max_certs);
23770f2065ccSmarkfen 
23780f2065ccSmarkfen 	print_defaults("-", gettext("IKE port number"),
2379510c3f91SVladimir Kotal 	    " ", ddp->rule_ike_port, dp->rule_ike_port);
23800f2065ccSmarkfen 
23810f2065ccSmarkfen 	print_defaults("-", gettext("NAT-T port number"),
2382510c3f91SVladimir Kotal 	    " ", ddp->rule_natt_port, dp->rule_natt_port);
23830f2065ccSmarkfen }
23840f2065ccSmarkfen 
23857c478bd9Sstevel@tonic-gate static void
print_categories(int level)23867c478bd9Sstevel@tonic-gate print_categories(int level)
23877c478bd9Sstevel@tonic-gate {
23887c478bd9Sstevel@tonic-gate 	int	mask;
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate 	if (level == 0) {
23917c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No debug categories enabled.\n"));
23927c478bd9Sstevel@tonic-gate 		return;
23937c478bd9Sstevel@tonic-gate 	}
23947c478bd9Sstevel@tonic-gate 
23957c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Debug categories enabled:"));
23967c478bd9Sstevel@tonic-gate 	for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) {
23977c478bd9Sstevel@tonic-gate 		if (level & mask)
23987c478bd9Sstevel@tonic-gate 			(void) printf("\n\t%s", dbgstr(mask));
23997c478bd9Sstevel@tonic-gate 	}
24007c478bd9Sstevel@tonic-gate 	(void) printf("\n");
24017c478bd9Sstevel@tonic-gate }
24027c478bd9Sstevel@tonic-gate 
24037c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/
24047c478bd9Sstevel@tonic-gate static void
ikeadm_err_exit(ike_err_t * err,char * fmt,...)24057c478bd9Sstevel@tonic-gate ikeadm_err_exit(ike_err_t *err, char *fmt, ...)
24067c478bd9Sstevel@tonic-gate {
24077c478bd9Sstevel@tonic-gate 	va_list	ap;
24087c478bd9Sstevel@tonic-gate 	char	bailbuf[BUFSIZ];
24097c478bd9Sstevel@tonic-gate 
24107c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
24117c478bd9Sstevel@tonic-gate 	(void) vsnprintf(bailbuf, BUFSIZ, fmt, ap);
24127c478bd9Sstevel@tonic-gate 	va_end(ap);
24137c478bd9Sstevel@tonic-gate 	if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) {
24147c478bd9Sstevel@tonic-gate 		bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ?
24157c478bd9Sstevel@tonic-gate 		    gettext("<unknown error>") : strerror(err->ike_err_unix));
24167c478bd9Sstevel@tonic-gate 	} else {
24177c478bd9Sstevel@tonic-gate 		bail_msg("%s: %s", bailbuf, (err == NULL) ?
24187c478bd9Sstevel@tonic-gate 		    gettext("<unknown error>") : errstr(err->ike_err));
24197c478bd9Sstevel@tonic-gate 	}
24207c478bd9Sstevel@tonic-gate }
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/
24237c478bd9Sstevel@tonic-gate static void
ikeadm_err_msg(ike_err_t * err,char * fmt,...)24247c478bd9Sstevel@tonic-gate ikeadm_err_msg(ike_err_t *err, char *fmt, ...)
24257c478bd9Sstevel@tonic-gate {
24267c478bd9Sstevel@tonic-gate 	va_list	ap;
24277c478bd9Sstevel@tonic-gate 	char	mbuf[BUFSIZ];
24287c478bd9Sstevel@tonic-gate 
24297c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
24307c478bd9Sstevel@tonic-gate 	(void) vsnprintf(mbuf, BUFSIZ, fmt, ap);
24317c478bd9Sstevel@tonic-gate 	va_end(ap);
24327c478bd9Sstevel@tonic-gate 	if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) {
24337c478bd9Sstevel@tonic-gate 		message("%s: %s", mbuf, (err->ike_err_unix == 0) ?
243415b07f80Spwernau 		    gettext("<unknown error>") :
243515b07f80Spwernau 		    ((err->ike_err_unix == EEXIST) ?
243615b07f80Spwernau 		    gettext("Duplicate entry") :
243715b07f80Spwernau 		    strerror(err->ike_err_unix)));
24387c478bd9Sstevel@tonic-gate 	} else {
24397c478bd9Sstevel@tonic-gate 		message("%s: %s", mbuf, (err == NULL) ?
24407c478bd9Sstevel@tonic-gate 		    gettext("<unknown error>") : errstr(err->ike_err));
24417c478bd9Sstevel@tonic-gate 	}
24427c478bd9Sstevel@tonic-gate }
24437c478bd9Sstevel@tonic-gate 
24447c478bd9Sstevel@tonic-gate 
24457c478bd9Sstevel@tonic-gate /*
24467c478bd9Sstevel@tonic-gate  * Command functions
24477c478bd9Sstevel@tonic-gate  */
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate /*
24507c478bd9Sstevel@tonic-gate  * Exploit the fact that ike_dbg_t and ike_priv_t have identical
24517c478bd9Sstevel@tonic-gate  * formats in the following two functions.
24527c478bd9Sstevel@tonic-gate  */
24537c478bd9Sstevel@tonic-gate static void
do_getvar(int cmd)24547c478bd9Sstevel@tonic-gate do_getvar(int cmd)
24557c478bd9Sstevel@tonic-gate {
24567c478bd9Sstevel@tonic-gate 	ike_service_t	req, *rtn;
24577c478bd9Sstevel@tonic-gate 	ike_dbg_t	*dreq;
24587c478bd9Sstevel@tonic-gate 	char		*varname;
24597c478bd9Sstevel@tonic-gate 
24607c478bd9Sstevel@tonic-gate 	switch (cmd) {
24617c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_DBG:
24627c478bd9Sstevel@tonic-gate 		varname = gettext("debug");
24637c478bd9Sstevel@tonic-gate 		break;
24647c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_PRIV:
24657c478bd9Sstevel@tonic-gate 		varname = gettext("privilege");
24667c478bd9Sstevel@tonic-gate 		break;
24677c478bd9Sstevel@tonic-gate 	default:
24687c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized get command (%d)"), cmd);
24697c478bd9Sstevel@tonic-gate 	}
24707c478bd9Sstevel@tonic-gate 
24717c478bd9Sstevel@tonic-gate 	dreq = &req.svc_dbg;
24727c478bd9Sstevel@tonic-gate 	dreq->cmd = cmd;
24737c478bd9Sstevel@tonic-gate 	dreq->dbg_level = 0;
24747c478bd9Sstevel@tonic-gate 
24757c478bd9Sstevel@tonic-gate 	rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0);
24767c478bd9Sstevel@tonic-gate 
24777c478bd9Sstevel@tonic-gate 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
24787c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtn->svc_err,
24797c478bd9Sstevel@tonic-gate 		    gettext("error getting %s level"), varname);
24807c478bd9Sstevel@tonic-gate 	}
24817c478bd9Sstevel@tonic-gate 	dreq = &rtn->svc_dbg;
24827c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Current %s level is 0x%x"),
24837c478bd9Sstevel@tonic-gate 	    varname, dreq->dbg_level);
24847c478bd9Sstevel@tonic-gate 
24857c478bd9Sstevel@tonic-gate 	if (cmd == IKE_SVC_GET_DBG) {
24867c478bd9Sstevel@tonic-gate 		(void) printf("\n");
24877c478bd9Sstevel@tonic-gate 		print_categories(dreq->dbg_level);
24887c478bd9Sstevel@tonic-gate 	} else {
24897c478bd9Sstevel@tonic-gate 		(void) printf(gettext(", %s enabled\n"),
24907c478bd9Sstevel@tonic-gate 		    privstr(dreq->dbg_level));
24917c478bd9Sstevel@tonic-gate 	}
24927c478bd9Sstevel@tonic-gate }
24937c478bd9Sstevel@tonic-gate 
2494c7777ac8SPaul Wernau /*
2495c7777ac8SPaul Wernau  * Log into a token and unlock all objects
2496c7777ac8SPaul Wernau  * referenced by PKCS#11 hint files.
2497c7777ac8SPaul Wernau  */
2498c7777ac8SPaul Wernau static void
do_setdel_pin(int cmd,int argc,char ** argv)2499c7777ac8SPaul Wernau do_setdel_pin(int cmd, int argc, char **argv)
2500c7777ac8SPaul Wernau {
2501c7777ac8SPaul Wernau 	ike_service_t	req, *rtn;
2502c7777ac8SPaul Wernau 	ike_pin_t	*preq;
2503c7777ac8SPaul Wernau 	char		token_label[PKCS11_TOKSIZE];
2504c7777ac8SPaul Wernau 	char		*token_pin;
2505c7777ac8SPaul Wernau 	char		prompt[80];
2506c7777ac8SPaul Wernau 
2507c7777ac8SPaul Wernau 	if (argc < 1)
2508c7777ac8SPaul Wernau 		Bail(gettext("Must specify PKCS#11 token object."));
2509c7777ac8SPaul Wernau 
2510c7777ac8SPaul Wernau 	preq = &req.svc_pin;
2511c7777ac8SPaul Wernau 	preq->cmd = cmd;
2512c7777ac8SPaul Wernau 
2513c7777ac8SPaul Wernau 	switch (cmd) {
2514c7777ac8SPaul Wernau 	case IKE_SVC_SET_PIN:
2515c7777ac8SPaul Wernau 		if (parse_token(argc, argv, token_label) != 0)
2516c7777ac8SPaul Wernau 			Bail("Invalid syntax for \"token login\"");
2517c7777ac8SPaul Wernau 		(void) snprintf(prompt, sizeof (prompt),
2518c7777ac8SPaul Wernau 		    "Enter PIN for PKCS#11 token \'%s\': ", token_label);
2519c7777ac8SPaul Wernau 		token_pin =
2520c7777ac8SPaul Wernau 		    getpassphrase(prompt);
2521c7777ac8SPaul Wernau 		(void) strlcpy((char *)preq->token_pin, token_pin, MAX_PIN_LEN);
2522c7777ac8SPaul Wernau 		bzero(token_pin, strlen(token_pin));
2523c7777ac8SPaul Wernau 		break;
2524c7777ac8SPaul Wernau 	case IKE_SVC_DEL_PIN:
2525c7777ac8SPaul Wernau 		if (parse_token(argc, argv, token_label) != 0)
2526c7777ac8SPaul Wernau 			Bail("Invalid syntax for \"token logout\"");
2527c7777ac8SPaul Wernau 		break;
2528c7777ac8SPaul Wernau 	default:
2529c7777ac8SPaul Wernau 		bail_msg(gettext("unrecognized token command (%d)"), cmd);
2530c7777ac8SPaul Wernau 	}
2531c7777ac8SPaul Wernau 
2532c7777ac8SPaul Wernau 	(void) strlcpy(preq->pkcs11_token, token_label, PKCS11_TOKSIZE);
2533c7777ac8SPaul Wernau 
2534c7777ac8SPaul Wernau 	rtn = ikedoor_call((char *)&req, sizeof (ike_pin_t), NULL, 0);
2535c7777ac8SPaul Wernau 	if (cmd == IKE_SVC_SET_PIN)
2536c7777ac8SPaul Wernau 		bzero(preq->token_pin, sizeof (preq->token_pin));
2537c7777ac8SPaul Wernau 
2538c7777ac8SPaul Wernau 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
2539c7777ac8SPaul Wernau 		ikeadm_err_exit(&rtn->svc_err,
2540c7777ac8SPaul Wernau 		    gettext("PKCS#11 operation"));
2541c7777ac8SPaul Wernau 	}
2542c7777ac8SPaul Wernau 	preq = &rtn->svc_pin;
2543c7777ac8SPaul Wernau 	message(gettext("PKCS#11 operation successful"));
2544c7777ac8SPaul Wernau }
2545c7777ac8SPaul Wernau 
25467c478bd9Sstevel@tonic-gate static void
do_setvar(int cmd,int argc,char ** argv)25477c478bd9Sstevel@tonic-gate do_setvar(int cmd, int argc, char **argv)
25487c478bd9Sstevel@tonic-gate {
25497c478bd9Sstevel@tonic-gate 	ike_service_t	req, *rtn;
25507c478bd9Sstevel@tonic-gate 	ike_dbg_t	*dreq;
25517c478bd9Sstevel@tonic-gate 	door_desc_t	*descp = NULL, desc;
25527c478bd9Sstevel@tonic-gate 	int		fd, ndesc = 0;
25537c478bd9Sstevel@tonic-gate 	uint32_t	reqlevel;
25547c478bd9Sstevel@tonic-gate 	char		*varname;
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate 	if (argc < 1)
25577c478bd9Sstevel@tonic-gate 		Bail("unspecified level");
25587c478bd9Sstevel@tonic-gate 	reqlevel = strtoul(argv[0], NULL, 0);
25597c478bd9Sstevel@tonic-gate 
25607c478bd9Sstevel@tonic-gate 	switch (cmd) {
25617c478bd9Sstevel@tonic-gate 	case IKE_SVC_SET_DBG:
25627c478bd9Sstevel@tonic-gate 		if (argc > 2)
25637c478bd9Sstevel@tonic-gate 			Bail("Too many arguments to \"set debug\"");
25647c478bd9Sstevel@tonic-gate 		varname = gettext("debug");
25657c478bd9Sstevel@tonic-gate 		if (reqlevel == 0) {
25667c478bd9Sstevel@tonic-gate 			/* check for a string... */
25677c478bd9Sstevel@tonic-gate 			reqlevel = parsedbgopts(argv[0]);
25687c478bd9Sstevel@tonic-gate 		}
25697c478bd9Sstevel@tonic-gate 		if (reqlevel == D_INVALID)
25707c478bd9Sstevel@tonic-gate 			bail_msg(gettext("Bad debug flag: %s"), argv[0]);
25717c478bd9Sstevel@tonic-gate 		break;
25727c478bd9Sstevel@tonic-gate 	case IKE_SVC_SET_PRIV:
25737c478bd9Sstevel@tonic-gate 		if (argc > 1)
25747c478bd9Sstevel@tonic-gate 			Bail("Too many arguments to \"set priv\"");
25757c478bd9Sstevel@tonic-gate 
25767c478bd9Sstevel@tonic-gate 		varname = gettext("privilege");
25777c478bd9Sstevel@tonic-gate 		if (reqlevel == 0) {
25787c478bd9Sstevel@tonic-gate 			/* check for a string... */
25797c478bd9Sstevel@tonic-gate 			reqlevel = privstr2num(argv[0]);
25807c478bd9Sstevel@tonic-gate 		}
25817c478bd9Sstevel@tonic-gate 		if (reqlevel > IKE_PRIV_MAXIMUM)
25827c478bd9Sstevel@tonic-gate 			bail_msg(gettext("Bad privilege flag: %s"), argv[0]);
25837c478bd9Sstevel@tonic-gate 		break;
25847c478bd9Sstevel@tonic-gate 	default:
25857c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized set command (%d)"), cmd);
25867c478bd9Sstevel@tonic-gate 	}
25877c478bd9Sstevel@tonic-gate 
25887c478bd9Sstevel@tonic-gate 	dreq = &req.svc_dbg;
25897c478bd9Sstevel@tonic-gate 	dreq->cmd = cmd;
25907c478bd9Sstevel@tonic-gate 	dreq->dbg_level = reqlevel;
25917c478bd9Sstevel@tonic-gate 
25927c478bd9Sstevel@tonic-gate 	if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) {
25937c478bd9Sstevel@tonic-gate 		fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND,
25947c478bd9Sstevel@tonic-gate 		    S_IRUSR | S_IWUSR);
25957c478bd9Sstevel@tonic-gate 		if (fd < 0)
25967c478bd9Sstevel@tonic-gate 			Bail("open debug file");
25977c478bd9Sstevel@tonic-gate 		desc.d_data.d_desc.d_descriptor = fd;
25987c478bd9Sstevel@tonic-gate 		desc.d_attributes = DOOR_DESCRIPTOR;
25997c478bd9Sstevel@tonic-gate 		descp = &desc;
26007c478bd9Sstevel@tonic-gate 		ndesc = 1;
26017c478bd9Sstevel@tonic-gate 	}
26027c478bd9Sstevel@tonic-gate 
26037c478bd9Sstevel@tonic-gate 	rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc);
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26067c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtn->svc_err,
26077c478bd9Sstevel@tonic-gate 		    gettext("error setting %s level"), varname);
26087c478bd9Sstevel@tonic-gate 	}
26097c478bd9Sstevel@tonic-gate 	dreq = &rtn->svc_dbg;
26107c478bd9Sstevel@tonic-gate 	(void) printf(
26117c478bd9Sstevel@tonic-gate 	    gettext("Successfully changed %s level from 0x%x to 0x%x\n"),
26127c478bd9Sstevel@tonic-gate 	    varname, dreq->dbg_level, reqlevel);
26137c478bd9Sstevel@tonic-gate 
26147c478bd9Sstevel@tonic-gate 	if (cmd == IKE_SVC_SET_DBG) {
26157c478bd9Sstevel@tonic-gate 		print_categories(reqlevel);
26167c478bd9Sstevel@tonic-gate 	} else {
26177c478bd9Sstevel@tonic-gate 		(void) printf(gettext("New privilege level 0x%x enables %s\n"),
26187c478bd9Sstevel@tonic-gate 		    reqlevel, privstr(reqlevel));
26197c478bd9Sstevel@tonic-gate 	}
26207c478bd9Sstevel@tonic-gate }
26217c478bd9Sstevel@tonic-gate 
26227c478bd9Sstevel@tonic-gate static void
do_getstats(int cmd)26237c478bd9Sstevel@tonic-gate do_getstats(int cmd)
26247c478bd9Sstevel@tonic-gate {
26257c478bd9Sstevel@tonic-gate 	ike_service_t	*rtn;
26267c478bd9Sstevel@tonic-gate 	ike_statreq_t	sreq, *sreqp;
26277c478bd9Sstevel@tonic-gate 	ike_stats_t	*sp;
26287c478bd9Sstevel@tonic-gate 
26297c478bd9Sstevel@tonic-gate 	sreq.cmd = cmd;
26307c478bd9Sstevel@tonic-gate 
26317c478bd9Sstevel@tonic-gate 	rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0);
26327c478bd9Sstevel@tonic-gate 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26337c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats"));
26347c478bd9Sstevel@tonic-gate 	}
26357c478bd9Sstevel@tonic-gate 
26367c478bd9Sstevel@tonic-gate 	sreqp = &rtn->svc_stats;
26377c478bd9Sstevel@tonic-gate 	sp = (ike_stats_t *)(sreqp + 1);
26387c478bd9Sstevel@tonic-gate 	print_stats(sp, sreqp->stat_len);
26397c478bd9Sstevel@tonic-gate }
26407c478bd9Sstevel@tonic-gate 
26410f2065ccSmarkfen static void
do_getdefs(int cmd)26420f2065ccSmarkfen do_getdefs(int cmd)
26430f2065ccSmarkfen {
26440f2065ccSmarkfen 	ike_service_t	*rtn;
26450f2065ccSmarkfen 	ike_defreq_t	dreq, *dreqp;
26460f2065ccSmarkfen 	ike_defaults_t	*dp;
26470f2065ccSmarkfen 
26480f2065ccSmarkfen 	dreq.cmd = cmd;
26490f2065ccSmarkfen 
26500f2065ccSmarkfen 	rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0);
26510f2065ccSmarkfen 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26520f2065ccSmarkfen 		ikeadm_err_exit(&rtn->svc_err,
26530f2065ccSmarkfen 		    gettext("error getting defaults"));
26540f2065ccSmarkfen 	}
26550f2065ccSmarkfen 
26560f2065ccSmarkfen 	dreqp = &rtn->svc_defaults;
26570f2065ccSmarkfen 	dp = (ike_defaults_t *)(dreqp + 1);
26580f2065ccSmarkfen 
26590f2065ccSmarkfen 	/*
26600f2065ccSmarkfen 	 * Before printing each line, make sure the structure we were
26610f2065ccSmarkfen 	 * given is big enough to include the fields needed.
26620f2065ccSmarkfen 	 * Silently bail out of there is a version mismatch.
26630f2065ccSmarkfen 	 */
26640f2065ccSmarkfen 	if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t))
26650f2065ccSmarkfen 	    + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) {
26660f2065ccSmarkfen 		return;
26670f2065ccSmarkfen 	}
26680f2065ccSmarkfen 	do_print_defaults(dp);
26690f2065ccSmarkfen }
26700f2065ccSmarkfen 
26717c478bd9Sstevel@tonic-gate static void
do_dump(int cmd)26727c478bd9Sstevel@tonic-gate do_dump(int cmd)
26737c478bd9Sstevel@tonic-gate {
26747c478bd9Sstevel@tonic-gate 	char		*name;
26757c478bd9Sstevel@tonic-gate 	ike_service_t	req, *rtn;
26767c478bd9Sstevel@tonic-gate 	ike_dump_t	*dreq, *dump;
26777c478bd9Sstevel@tonic-gate 
26787c478bd9Sstevel@tonic-gate 	switch (cmd) {
26797c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_P1S:
26807c478bd9Sstevel@tonic-gate 		name = gettext("phase 1 SA info");
26817c478bd9Sstevel@tonic-gate 		break;
26827c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_RULES:
26837c478bd9Sstevel@tonic-gate 		name = gettext("policy rules");
26847c478bd9Sstevel@tonic-gate 		break;
26857c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_PS:
26867c478bd9Sstevel@tonic-gate 		name = gettext("preshared keys");
26877c478bd9Sstevel@tonic-gate 		break;
2688c7777ac8SPaul Wernau 	case IKE_SVC_DUMP_CERTCACHE:
2689c7777ac8SPaul Wernau 		name = gettext("certcache");
2690c7777ac8SPaul Wernau 		break;
26915d01c172SVladimir Kotal 	case IKE_SVC_DUMP_GROUPS:
26925d01c172SVladimir Kotal 		name = gettext("groups");
26935d01c172SVladimir Kotal 		print_group_header();
26945d01c172SVladimir Kotal 		break;
26955d01c172SVladimir Kotal 	case IKE_SVC_DUMP_ENCRALGS:
26965d01c172SVladimir Kotal 		name = gettext("encralgs");
26975d01c172SVladimir Kotal 		print_encralg_header();
26985d01c172SVladimir Kotal 		break;
26995d01c172SVladimir Kotal 	case IKE_SVC_DUMP_AUTHALGS:
27005d01c172SVladimir Kotal 		name = gettext("authalgs");
27015d01c172SVladimir Kotal 		print_authalg_header();
27025d01c172SVladimir Kotal 		break;
27037c478bd9Sstevel@tonic-gate 	default:
27047c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized dump command (%d)"), cmd);
27057c478bd9Sstevel@tonic-gate 	}
27067c478bd9Sstevel@tonic-gate 
27077c478bd9Sstevel@tonic-gate 	dreq = &req.svc_dump;
27087c478bd9Sstevel@tonic-gate 	dreq->cmd = cmd;
27097c478bd9Sstevel@tonic-gate 	dreq->dump_len = 0;
27107c478bd9Sstevel@tonic-gate 	dreq->dump_next = 0;
27117c478bd9Sstevel@tonic-gate 	do {
27127c478bd9Sstevel@tonic-gate 		rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t),
27137c478bd9Sstevel@tonic-gate 		    NULL, 0);
27147c478bd9Sstevel@tonic-gate 		if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
27157c478bd9Sstevel@tonic-gate 			if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
27167c478bd9Sstevel@tonic-gate 				/* no entries to print */
27177c478bd9Sstevel@tonic-gate 				break;
27187c478bd9Sstevel@tonic-gate 			}
27197c478bd9Sstevel@tonic-gate 			ikeadm_err_exit(&rtn->svc_err,
27207c478bd9Sstevel@tonic-gate 			    gettext("error getting %s"), name);
27217c478bd9Sstevel@tonic-gate 		}
27227c478bd9Sstevel@tonic-gate 		dump = &rtn->svc_dump;
27237c478bd9Sstevel@tonic-gate 
27247c478bd9Sstevel@tonic-gate 		switch (cmd) {
27257c478bd9Sstevel@tonic-gate 		case IKE_SVC_DUMP_P1S:
27267c478bd9Sstevel@tonic-gate 			print_p1((ike_p1_sa_t *)(dump + 1));
27277c478bd9Sstevel@tonic-gate 			break;
27287c478bd9Sstevel@tonic-gate 		case IKE_SVC_DUMP_RULES:
27297c478bd9Sstevel@tonic-gate 			print_rule((ike_rule_t *)(dump + 1));
27307c478bd9Sstevel@tonic-gate 			break;
27317c478bd9Sstevel@tonic-gate 		case IKE_SVC_DUMP_PS:
27327c478bd9Sstevel@tonic-gate 			print_ps((ike_ps_t *)(dump + 1));
27337c478bd9Sstevel@tonic-gate 			break;
2734c7777ac8SPaul Wernau 		case IKE_SVC_DUMP_CERTCACHE:
2735c7777ac8SPaul Wernau 			print_certcache((ike_certcache_t *)(dump + 1));
2736c7777ac8SPaul Wernau 			break;
27375d01c172SVladimir Kotal 		case IKE_SVC_DUMP_GROUPS:
27385d01c172SVladimir Kotal 			print_group((ike_group_t *)(dump + 1));
27395d01c172SVladimir Kotal 			break;
27405d01c172SVladimir Kotal 		case IKE_SVC_DUMP_ENCRALGS:
27415d01c172SVladimir Kotal 			print_encralg((ike_encralg_t *)(dump + 1));
27425d01c172SVladimir Kotal 			break;
27435d01c172SVladimir Kotal 		case IKE_SVC_DUMP_AUTHALGS:
27445d01c172SVladimir Kotal 			print_authalg((ike_authalg_t *)(dump + 1));
27455d01c172SVladimir Kotal 			break;
27467c478bd9Sstevel@tonic-gate 		}
27477c478bd9Sstevel@tonic-gate 
27487c478bd9Sstevel@tonic-gate 		dreq->dump_next = dump->dump_next;
27497c478bd9Sstevel@tonic-gate 
27507c478bd9Sstevel@tonic-gate 		(void) munmap((char *)rtn, dump->dump_len);
27517c478bd9Sstevel@tonic-gate 
27527c478bd9Sstevel@tonic-gate 	} while (dreq->dump_next);
27537c478bd9Sstevel@tonic-gate 
27547c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nCompleted dump of %s\n"), name);
27557c478bd9Sstevel@tonic-gate }
27567c478bd9Sstevel@tonic-gate 
27577c478bd9Sstevel@tonic-gate static void
do_getdel_doorcall(int cmd,int idlen,int idtype,char * idp,char * name)27587c478bd9Sstevel@tonic-gate do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name)
27597c478bd9Sstevel@tonic-gate {
27607c478bd9Sstevel@tonic-gate 	int		totallen;
27617c478bd9Sstevel@tonic-gate 	char		*p;
27627c478bd9Sstevel@tonic-gate 	ike_service_t	*reqp, *rtnp;
27637c478bd9Sstevel@tonic-gate 	ike_get_t	*getp;
27647c478bd9Sstevel@tonic-gate 	boolean_t	getcmd;
27657c478bd9Sstevel@tonic-gate 
27667c478bd9Sstevel@tonic-gate 	getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) ||
27677c478bd9Sstevel@tonic-gate 	    (cmd == IKE_SVC_GET_PS));
27687c478bd9Sstevel@tonic-gate 
27697c478bd9Sstevel@tonic-gate 	/*
27707c478bd9Sstevel@tonic-gate 	 * WARNING: to avoid being redundant, this code takes advantage
27717c478bd9Sstevel@tonic-gate 	 * of the fact that the ike_get_t and ike_del_t structures are
27727c478bd9Sstevel@tonic-gate 	 * identical (only the field names differ, their function and
27737c478bd9Sstevel@tonic-gate 	 * size are the same).  If for some reason those structures
27747c478bd9Sstevel@tonic-gate 	 * change, this code will need to be re-written to accomodate
27757c478bd9Sstevel@tonic-gate 	 * that difference.
27767c478bd9Sstevel@tonic-gate 	 */
27777c478bd9Sstevel@tonic-gate 	totallen = sizeof (ike_get_t) + idlen;
27787c478bd9Sstevel@tonic-gate 	if ((reqp = (ike_service_t *)malloc(totallen)) == NULL)
27797c478bd9Sstevel@tonic-gate 		Bail("malloc(id)");
27807c478bd9Sstevel@tonic-gate 
27817c478bd9Sstevel@tonic-gate 	getp = &reqp->svc_get;
27827c478bd9Sstevel@tonic-gate 	getp->cmd = cmd;
27837c478bd9Sstevel@tonic-gate 	getp->get_len = totallen;
27847c478bd9Sstevel@tonic-gate 	getp->get_idtype = idtype;
27857c478bd9Sstevel@tonic-gate 	p = (char *)(getp + 1);
27867c478bd9Sstevel@tonic-gate 
27877c478bd9Sstevel@tonic-gate 	(void) memcpy(p, idp, idlen);
27887c478bd9Sstevel@tonic-gate 
27897c478bd9Sstevel@tonic-gate 	rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0);
27907c478bd9Sstevel@tonic-gate 	if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
27917c478bd9Sstevel@tonic-gate 		if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
27927c478bd9Sstevel@tonic-gate 			message(gettext("Could not find requested %s."), name);
27937c478bd9Sstevel@tonic-gate 		} else {
27947c478bd9Sstevel@tonic-gate 			ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"),
27957c478bd9Sstevel@tonic-gate 			    (getcmd) ? gettext("getting") : gettext("deleting"),
27967c478bd9Sstevel@tonic-gate 			    name);
27977c478bd9Sstevel@tonic-gate 		}
27987c478bd9Sstevel@tonic-gate 		free(reqp);
27997c478bd9Sstevel@tonic-gate 		return;
28007c478bd9Sstevel@tonic-gate 	}
28017c478bd9Sstevel@tonic-gate 	getp = &rtnp->svc_get;
28027c478bd9Sstevel@tonic-gate 
28037c478bd9Sstevel@tonic-gate 	if (getcmd) {
28047c478bd9Sstevel@tonic-gate 		switch (cmd) {
28057c478bd9Sstevel@tonic-gate 		case IKE_SVC_GET_P1:
28067c478bd9Sstevel@tonic-gate 			print_p1((ike_p1_sa_t *)(getp + 1));
28077c478bd9Sstevel@tonic-gate 			break;
28087c478bd9Sstevel@tonic-gate 		case IKE_SVC_GET_PS:
28097c478bd9Sstevel@tonic-gate 			print_ps((ike_ps_t *)(getp + 1));
28107c478bd9Sstevel@tonic-gate 			break;
28117c478bd9Sstevel@tonic-gate 		case IKE_SVC_GET_RULE:
28127c478bd9Sstevel@tonic-gate 			print_rule((ike_rule_t *)(getp + 1));
28137c478bd9Sstevel@tonic-gate 			break;
28147c478bd9Sstevel@tonic-gate 		}
28157c478bd9Sstevel@tonic-gate 	} else {
28167c478bd9Sstevel@tonic-gate 		message(gettext("Successfully deleted selected %s."), name);
28177c478bd9Sstevel@tonic-gate 	}
28187c478bd9Sstevel@tonic-gate 
28197c478bd9Sstevel@tonic-gate 	(void) munmap((char *)rtnp, getp->get_len);
28207c478bd9Sstevel@tonic-gate 	free(reqp);
28217c478bd9Sstevel@tonic-gate }
28227c478bd9Sstevel@tonic-gate 
28237c478bd9Sstevel@tonic-gate static void
do_getdel(int cmd,int argc,char ** argv)28247c478bd9Sstevel@tonic-gate do_getdel(int cmd, int argc, char **argv)
28257c478bd9Sstevel@tonic-gate {
28267c478bd9Sstevel@tonic-gate 	int		idlen, idtype = 0, i, j;
28277c478bd9Sstevel@tonic-gate 	int		bytelen1, bytelen2;
28287c478bd9Sstevel@tonic-gate 	char		*name, *idp, *p, *p1, *p2;
28297c478bd9Sstevel@tonic-gate 	ike_addr_pr_t	apr;
28307c478bd9Sstevel@tonic-gate 	ike_cky_pr_t	cpr;
28317c478bd9Sstevel@tonic-gate 	sadb_ident_t	*sid1p, *sid2p;
28327c478bd9Sstevel@tonic-gate 	struct hostent	*he1p, *he2p;
28337c478bd9Sstevel@tonic-gate 	char		label[MAX_LABEL_LEN];
28347c478bd9Sstevel@tonic-gate 
28357c478bd9Sstevel@tonic-gate 	if ((argc < 1) || (argv[0] == NULL)) {
28367c478bd9Sstevel@tonic-gate 		Bail("not enough identification info");
28377c478bd9Sstevel@tonic-gate 	}
28387c478bd9Sstevel@tonic-gate 
28397c478bd9Sstevel@tonic-gate 	switch (cmd) {
28407c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_P1:
28417c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_P1:
28427c478bd9Sstevel@tonic-gate 		name = gettext("phase 1 SA");
28437c478bd9Sstevel@tonic-gate 		/*
28447c478bd9Sstevel@tonic-gate 		 * The first token must either be an address (or hostname)
28457c478bd9Sstevel@tonic-gate 		 * or a cookie.  We require cookies to be entered as hex
28467c478bd9Sstevel@tonic-gate 		 * numbers, beginning with 0x; so if our token starts with
28477c478bd9Sstevel@tonic-gate 		 * that, it's a cookie.
28487c478bd9Sstevel@tonic-gate 		 */
28497c478bd9Sstevel@tonic-gate 		if (strncmp(argv[0], "0x", 2) == 0) {
28507c478bd9Sstevel@tonic-gate 			if (parse_cky_pr(argc, argv, &cpr) >= 0) {
28517c478bd9Sstevel@tonic-gate 				idtype = IKE_ID_CKY_PAIR;
28527c478bd9Sstevel@tonic-gate 				idlen = sizeof (ike_cky_pr_t);
28537c478bd9Sstevel@tonic-gate 				idp = (char *)&cpr;
28547c478bd9Sstevel@tonic-gate 			}
28557c478bd9Sstevel@tonic-gate 		} else {
28567c478bd9Sstevel@tonic-gate 			if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) {
28577c478bd9Sstevel@tonic-gate 				idtype = IKE_ID_ADDR_PAIR;
28587c478bd9Sstevel@tonic-gate 				idlen = sizeof (ike_addr_pr_t);
28597c478bd9Sstevel@tonic-gate 			}
28607c478bd9Sstevel@tonic-gate 		}
28617c478bd9Sstevel@tonic-gate 		break;
28627c478bd9Sstevel@tonic-gate 
28637c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_RULE:
28647c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_RULE:
28657c478bd9Sstevel@tonic-gate 		name = gettext("policy rule");
28667c478bd9Sstevel@tonic-gate 		if (parse_label(argc, argv, label) >= 0) {
28677c478bd9Sstevel@tonic-gate 			idtype = IKE_ID_LABEL;
28687c478bd9Sstevel@tonic-gate 			idlen = MAX_LABEL_LEN;
28697c478bd9Sstevel@tonic-gate 			idp = label;
28707c478bd9Sstevel@tonic-gate 		}
28717c478bd9Sstevel@tonic-gate 		break;
28727c478bd9Sstevel@tonic-gate 
28737c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_PS:
28747c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_PS:
28757c478bd9Sstevel@tonic-gate 		name = gettext("preshared key");
28767c478bd9Sstevel@tonic-gate 		/*
28777c478bd9Sstevel@tonic-gate 		 * The first token must either be an address or an ident
28787c478bd9Sstevel@tonic-gate 		 * type.  Check for an ident type to determine which it is.
28797c478bd9Sstevel@tonic-gate 		 */
28807c478bd9Sstevel@tonic-gate 		if (parse_idtype(argv[0], NULL) >= 0) {
28817c478bd9Sstevel@tonic-gate 			if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) {
28827c478bd9Sstevel@tonic-gate 				idtype = IKE_ID_IDENT_PAIR;
28837c478bd9Sstevel@tonic-gate 				idlen = SADB_64TO8(sid1p->sadb_ident_len) +
28847c478bd9Sstevel@tonic-gate 				    SADB_64TO8(sid2p->sadb_ident_len);
28857c478bd9Sstevel@tonic-gate 			}
28867c478bd9Sstevel@tonic-gate 		} else {
28877c478bd9Sstevel@tonic-gate 			if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) {
28887c478bd9Sstevel@tonic-gate 				idtype = IKE_ID_ADDR_PAIR;
28897c478bd9Sstevel@tonic-gate 				idlen = sizeof (ike_addr_pr_t);
28907c478bd9Sstevel@tonic-gate 			}
28917c478bd9Sstevel@tonic-gate 		}
28927c478bd9Sstevel@tonic-gate 		break;
28937c478bd9Sstevel@tonic-gate 
28947c478bd9Sstevel@tonic-gate 	default:
28957c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized get/del command (%d)"), cmd);
28967c478bd9Sstevel@tonic-gate 	}
28977c478bd9Sstevel@tonic-gate 
28987c478bd9Sstevel@tonic-gate 	switch (idtype) {
28997c478bd9Sstevel@tonic-gate 	case IKE_ID_ADDR_PAIR:
29007c478bd9Sstevel@tonic-gate 		/*
29017c478bd9Sstevel@tonic-gate 		 * we might have exploding addrs here; do every possible
29027c478bd9Sstevel@tonic-gate 		 * combination.
29037c478bd9Sstevel@tonic-gate 		 */
29047c478bd9Sstevel@tonic-gate 		i = 0;
29057c478bd9Sstevel@tonic-gate 		j = 0;
29067c478bd9Sstevel@tonic-gate 		while ((p1 = he1p->h_addr_list[i++]) != NULL) {
29077c478bd9Sstevel@tonic-gate 			headdr2sa(p1, &apr.loc_addr, he1p->h_length);
29087c478bd9Sstevel@tonic-gate 
29097c478bd9Sstevel@tonic-gate 			while ((p2 = he2p->h_addr_list[j++]) != NULL) {
29107c478bd9Sstevel@tonic-gate 				headdr2sa(p2, &apr.rem_addr, he2p->h_length);
29117c478bd9Sstevel@tonic-gate 				do_getdel_doorcall(cmd, idlen, idtype,
29127c478bd9Sstevel@tonic-gate 				    (char *)&apr, name);
29137c478bd9Sstevel@tonic-gate 			}
29147c478bd9Sstevel@tonic-gate 		}
29157c478bd9Sstevel@tonic-gate 		FREE_HE(he1p);
29167c478bd9Sstevel@tonic-gate 		FREE_HE(he2p);
29177c478bd9Sstevel@tonic-gate 		break;
29187c478bd9Sstevel@tonic-gate 
29197c478bd9Sstevel@tonic-gate 	case IKE_ID_IDENT_PAIR:
29207c478bd9Sstevel@tonic-gate 		bytelen1 = SADB_64TO8(sid1p->sadb_ident_len);
29217c478bd9Sstevel@tonic-gate 		bytelen2 = SADB_64TO8(sid2p->sadb_ident_len);
29227c478bd9Sstevel@tonic-gate 		if (idlen != bytelen1 + bytelen2)
29237c478bd9Sstevel@tonic-gate 			Bail("ident syntax error");
29247c478bd9Sstevel@tonic-gate 		idp = p = (char *)malloc(idlen);
29257c478bd9Sstevel@tonic-gate 		if (p == NULL)
29267c478bd9Sstevel@tonic-gate 			Bail("malloc(id)");
29277c478bd9Sstevel@tonic-gate 		(void) memcpy(p, (char *)sid1p, bytelen1);
29287c478bd9Sstevel@tonic-gate 		p += bytelen1;
29297c478bd9Sstevel@tonic-gate 		(void) memcpy(p, (char *)sid2p, bytelen2);
29307c478bd9Sstevel@tonic-gate 		do_getdel_doorcall(cmd, idlen, idtype, idp, name);
29317c478bd9Sstevel@tonic-gate 		free(idp);
29327c478bd9Sstevel@tonic-gate 		free(sid1p);
29337c478bd9Sstevel@tonic-gate 		free(sid2p);
29347c478bd9Sstevel@tonic-gate 		break;
29357c478bd9Sstevel@tonic-gate 
29367c478bd9Sstevel@tonic-gate 	case IKE_ID_CKY_PAIR:
29377c478bd9Sstevel@tonic-gate 	case IKE_ID_LABEL:
29387c478bd9Sstevel@tonic-gate 		do_getdel_doorcall(cmd, idlen, idtype, idp, name);
29397c478bd9Sstevel@tonic-gate 		break;
29407c478bd9Sstevel@tonic-gate 
29417c478bd9Sstevel@tonic-gate 	case 0:
29427c478bd9Sstevel@tonic-gate 	default:
29437c478bd9Sstevel@tonic-gate 		bail_msg(gettext("invalid %s identification\n"), name);
29447c478bd9Sstevel@tonic-gate 	}
29457c478bd9Sstevel@tonic-gate }
29467c478bd9Sstevel@tonic-gate 
29477c478bd9Sstevel@tonic-gate /*
29487c478bd9Sstevel@tonic-gate  * Copy source into target, inserting an escape character ('\') before
29497c478bd9Sstevel@tonic-gate  * any quotes that appear.  Return true on success, false on failure.
29507c478bd9Sstevel@tonic-gate  */
29517c478bd9Sstevel@tonic-gate static boolean_t
escapequotes(char * target,char * source,int tlen)29527c478bd9Sstevel@tonic-gate escapequotes(char *target, char *source, int tlen)
29537c478bd9Sstevel@tonic-gate {
29547c478bd9Sstevel@tonic-gate 	int	s, t, len = strlen(source) + 1;
29557c478bd9Sstevel@tonic-gate 
29567c478bd9Sstevel@tonic-gate 	if (tlen < len)
29577c478bd9Sstevel@tonic-gate 		return (B_FALSE);
29587c478bd9Sstevel@tonic-gate 
29597c478bd9Sstevel@tonic-gate 	for (s = 0, t = 0; s < len && t < tlen; s++) {
29607c478bd9Sstevel@tonic-gate 		if (source[s] == '\"')
29617c478bd9Sstevel@tonic-gate 			target[t++] = '\\';
29627c478bd9Sstevel@tonic-gate 		target[t++] = source[s];
29637c478bd9Sstevel@tonic-gate 	}
29647c478bd9Sstevel@tonic-gate 
29657c478bd9Sstevel@tonic-gate 	if ((t == tlen) && (s < len))
29667c478bd9Sstevel@tonic-gate 		return (B_FALSE);
29677c478bd9Sstevel@tonic-gate 
29687c478bd9Sstevel@tonic-gate 	return (B_TRUE);
29697c478bd9Sstevel@tonic-gate }
29707c478bd9Sstevel@tonic-gate 
29717c478bd9Sstevel@tonic-gate /*
29727c478bd9Sstevel@tonic-gate  * Return true if the arg following the given keyword should
29737c478bd9Sstevel@tonic-gate  * be in quotes (i.e. is a string), false if not.
29747c478bd9Sstevel@tonic-gate  */
29757c478bd9Sstevel@tonic-gate static boolean_t
quotedfield(char * keywd)29767c478bd9Sstevel@tonic-gate quotedfield(char *keywd)
29777c478bd9Sstevel@tonic-gate {
29787c478bd9Sstevel@tonic-gate 	if ((strncmp(keywd, "label", strlen("label") + 1) == 0) ||
29797c478bd9Sstevel@tonic-gate 	    (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) ||
29807c478bd9Sstevel@tonic-gate 	    (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0))
29817c478bd9Sstevel@tonic-gate 		return (B_TRUE);
29827c478bd9Sstevel@tonic-gate 
29837c478bd9Sstevel@tonic-gate 	return (B_FALSE);
29847c478bd9Sstevel@tonic-gate }
29857c478bd9Sstevel@tonic-gate 
29867c478bd9Sstevel@tonic-gate static void
do_new(int cmd,int argc,char ** argv)29877c478bd9Sstevel@tonic-gate do_new(int cmd, int argc, char **argv)
29887c478bd9Sstevel@tonic-gate {
29897c478bd9Sstevel@tonic-gate 	ike_service_t	*rtn;
29907c478bd9Sstevel@tonic-gate 	ike_new_t	new, *newp = NULL;
29917c478bd9Sstevel@tonic-gate 	door_desc_t	desc, *descp = NULL;
29927c478bd9Sstevel@tonic-gate 	int		i, fd, ndesc = 0, buflen;
29937c478bd9Sstevel@tonic-gate 	char		*name, tmpfilepath[32];
29947c478bd9Sstevel@tonic-gate 	FILE		*tmpfile;
29957c478bd9Sstevel@tonic-gate 
29967c478bd9Sstevel@tonic-gate 	switch (cmd) {
29977c478bd9Sstevel@tonic-gate 	case IKE_SVC_NEW_PS:
29987c478bd9Sstevel@tonic-gate 		name = gettext("preshared key");
29997c478bd9Sstevel@tonic-gate 		break;
30007c478bd9Sstevel@tonic-gate 	case IKE_SVC_NEW_RULE:
30017c478bd9Sstevel@tonic-gate 		name = gettext("policy rule");
30027c478bd9Sstevel@tonic-gate 		break;
30037c478bd9Sstevel@tonic-gate 	default:
30047c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized new command (%d)"), cmd);
30057c478bd9Sstevel@tonic-gate 	}
30067c478bd9Sstevel@tonic-gate 
30077c478bd9Sstevel@tonic-gate 	if (argc == 1) {
30087c478bd9Sstevel@tonic-gate 		/* We've been given a file to read from */
30097c478bd9Sstevel@tonic-gate 		fd = open(argv[0], O_RDONLY);
30107c478bd9Sstevel@tonic-gate 		if (fd < 0)
30117c478bd9Sstevel@tonic-gate 			Bail("open source file");
30127c478bd9Sstevel@tonic-gate 
30137c478bd9Sstevel@tonic-gate 		desc.d_data.d_desc.d_descriptor = fd;
30147c478bd9Sstevel@tonic-gate 		desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
30157c478bd9Sstevel@tonic-gate 		descp = &desc;
30167c478bd9Sstevel@tonic-gate 		ndesc = 1;
30177c478bd9Sstevel@tonic-gate 
30187c478bd9Sstevel@tonic-gate 		new.cmd = cmd;
30197c478bd9Sstevel@tonic-gate 		new.new_len = 0;
30207c478bd9Sstevel@tonic-gate 		newp = &new;
30217c478bd9Sstevel@tonic-gate 		buflen = sizeof (ike_new_t);
30227c478bd9Sstevel@tonic-gate 
30237c478bd9Sstevel@tonic-gate 	} else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) {
30247c478bd9Sstevel@tonic-gate 		/*
30257c478bd9Sstevel@tonic-gate 		 * This is an alternative to using the tmpfile method
30267c478bd9Sstevel@tonic-gate 		 * for preshared keys.  It means we're duplicating the
30277c478bd9Sstevel@tonic-gate 		 * parsing effort that happens in readps.c; but it
30287c478bd9Sstevel@tonic-gate 		 * does avoid having the key sitting in a file.
30297c478bd9Sstevel@tonic-gate 		 */
30307c478bd9Sstevel@tonic-gate 		ike_ps_t	*psp;
30317c478bd9Sstevel@tonic-gate 		int		pslen;
30327c478bd9Sstevel@tonic-gate 
30337c478bd9Sstevel@tonic-gate 		/*
30347c478bd9Sstevel@tonic-gate 		 * must be in interactive mode; don't want keys in
30357c478bd9Sstevel@tonic-gate 		 * the process args.
30367c478bd9Sstevel@tonic-gate 		 */
30377c478bd9Sstevel@tonic-gate 		if (!interactive)
30387c478bd9Sstevel@tonic-gate 			Bail("Must be in interactive mode to add key info.");
30397c478bd9Sstevel@tonic-gate 		if (parse_ps(argc, argv, &psp, &pslen) < 0) {
30407c478bd9Sstevel@tonic-gate 			errno = 0;
30417c478bd9Sstevel@tonic-gate 			Bail("invalid preshared key definition");
30427c478bd9Sstevel@tonic-gate 		}
30437c478bd9Sstevel@tonic-gate 		newp = malloc(sizeof (ike_new_t) + pslen);
30447c478bd9Sstevel@tonic-gate 		if (newp == NULL)
30457c478bd9Sstevel@tonic-gate 			Bail("alloc pskey");
30467c478bd9Sstevel@tonic-gate 		newp->cmd = cmd;
30477c478bd9Sstevel@tonic-gate 		newp->new_len = sizeof (ike_new_t) + pslen;
30487c478bd9Sstevel@tonic-gate 		(void) memcpy((char *)(newp + 1), psp, pslen);
30497c478bd9Sstevel@tonic-gate 		buflen = newp->new_len;
30507c478bd9Sstevel@tonic-gate 		/* parse_ps allocated the ike_ps_t buffer; free it now */
30517c478bd9Sstevel@tonic-gate 		free(psp);
30527c478bd9Sstevel@tonic-gate 
30537c478bd9Sstevel@tonic-gate 	} else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) {
30547c478bd9Sstevel@tonic-gate 		/*
30557c478bd9Sstevel@tonic-gate 		 * We've been given the item in argv.  However, parsing
30567c478bd9Sstevel@tonic-gate 		 * rules can get more than a little messy, and in.iked
30577c478bd9Sstevel@tonic-gate 		 * already has a great parser for this stuff!  So don't
30587c478bd9Sstevel@tonic-gate 		 * fool around with trying to do the parsing here. Just
30597c478bd9Sstevel@tonic-gate 		 * write it out to a tempfile, and send the fd to in.iked.
30607c478bd9Sstevel@tonic-gate 		 *
30617c478bd9Sstevel@tonic-gate 		 * We could conceivably do this for preshared keys,
30627c478bd9Sstevel@tonic-gate 		 * rather than duplicating the parsing effort; but that
30637c478bd9Sstevel@tonic-gate 		 * would mean the key would be written out to a file,
30647c478bd9Sstevel@tonic-gate 		 * which isn't such a good idea.
30657c478bd9Sstevel@tonic-gate 		 */
30667c478bd9Sstevel@tonic-gate 		boolean_t	doquotes = B_FALSE;
30677c478bd9Sstevel@tonic-gate 		int		rtn;
30687c478bd9Sstevel@tonic-gate 
30697c478bd9Sstevel@tonic-gate 		if ((argv[0][0] != '{') ||
30707c478bd9Sstevel@tonic-gate 		    (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}'))
30717c478bd9Sstevel@tonic-gate 			bail_msg(gettext("improperly formatted %s"), name);
30727c478bd9Sstevel@tonic-gate 
30737c478bd9Sstevel@tonic-gate 		/* attempt to use a fairly unpredictable file name... */
30747c478bd9Sstevel@tonic-gate 		(void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime());
30757c478bd9Sstevel@tonic-gate 		fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL,
30767c478bd9Sstevel@tonic-gate 		    S_IRUSR | S_IWUSR);
30777c478bd9Sstevel@tonic-gate 		if (fd < 0)
30787c478bd9Sstevel@tonic-gate 			Bail("cannot open tmpfile");
30797c478bd9Sstevel@tonic-gate 
30807c478bd9Sstevel@tonic-gate 		/* and make it inaccessible asap */
30817c478bd9Sstevel@tonic-gate 		if (unlink(tmpfilepath) < 0) {
30827c478bd9Sstevel@tonic-gate 			(void) close(fd);
30837c478bd9Sstevel@tonic-gate 			Bail("tmpfile error");
30847c478bd9Sstevel@tonic-gate 		}
30857c478bd9Sstevel@tonic-gate 
30867c478bd9Sstevel@tonic-gate 		tmpfile = fdopen(fd, "w");
30877c478bd9Sstevel@tonic-gate 		if (tmpfile == NULL) {
30887c478bd9Sstevel@tonic-gate 			(void) close(fd);
30897c478bd9Sstevel@tonic-gate 			Bail("cannot write to tmpfile");
30907c478bd9Sstevel@tonic-gate 		}
30917c478bd9Sstevel@tonic-gate 
30927c478bd9Sstevel@tonic-gate 		for (i = 0; i < argc; i++) {
30937c478bd9Sstevel@tonic-gate 			/*
30947c478bd9Sstevel@tonic-gate 			 * We have to do some gyrations with our string here,
30957c478bd9Sstevel@tonic-gate 			 * to properly handle quotes.  There are two issues:
30967c478bd9Sstevel@tonic-gate 			 * - some of the fields of a rule may have embedded
30977c478bd9Sstevel@tonic-gate 			 *   whitespace, and thus must be quoted on the cmd
30987c478bd9Sstevel@tonic-gate 			 *   line.  The shell removes the quotes, and gives
30997c478bd9Sstevel@tonic-gate 			 *   us a single argv string; but we need to put the
31007c478bd9Sstevel@tonic-gate 			 *   quotes back in when we write the string out to
31017c478bd9Sstevel@tonic-gate 			 *   file.  The doquotes boolean is set when we
31027c478bd9Sstevel@tonic-gate 			 *   process a keyword which will be followed by a
31037c478bd9Sstevel@tonic-gate 			 *   string value (so the NEXT argv element will be
31047c478bd9Sstevel@tonic-gate 			 *   quoted).
31057c478bd9Sstevel@tonic-gate 			 * - there might be a quote character in a field,
31067c478bd9Sstevel@tonic-gate 			 *   that was escaped on the cmdline.  The shell
31077c478bd9Sstevel@tonic-gate 			 *   removes the escape char, and leaves the quote
31087c478bd9Sstevel@tonic-gate 			 *   in the string it gives us.  We need to put the
31097c478bd9Sstevel@tonic-gate 			 *   escape char back in before writing to file.
31107c478bd9Sstevel@tonic-gate 			 */
31117c478bd9Sstevel@tonic-gate 			char	field[MAXLINESIZE];
31127c478bd9Sstevel@tonic-gate 			if (!escapequotes(field, argv[i], MAXLINESIZE))
31137c478bd9Sstevel@tonic-gate 				Bail("write to tmpfile failed (arg too big)");
31147c478bd9Sstevel@tonic-gate 			if (doquotes) {
31157c478bd9Sstevel@tonic-gate 				rtn = fprintf(tmpfile, "\"%s\"\n", field);
31167c478bd9Sstevel@tonic-gate 				doquotes = B_FALSE;
31177c478bd9Sstevel@tonic-gate 			} else {
31187c478bd9Sstevel@tonic-gate 				rtn = fprintf(tmpfile, "%s\n", field);
31197c478bd9Sstevel@tonic-gate 			}
31207c478bd9Sstevel@tonic-gate 			if (rtn < 0)
31217c478bd9Sstevel@tonic-gate 				Bail("write to tmpfile failed");
31227c478bd9Sstevel@tonic-gate 			/*
31237c478bd9Sstevel@tonic-gate 			 * check if this is a keyword identifying
31247c478bd9Sstevel@tonic-gate 			 * a field that needs to be quoted.
31257c478bd9Sstevel@tonic-gate 			 */
31267c478bd9Sstevel@tonic-gate 			doquotes = quotedfield(argv[i]);
31277c478bd9Sstevel@tonic-gate 		}
31287c478bd9Sstevel@tonic-gate 		if (fflush(tmpfile) == EOF)
31297c478bd9Sstevel@tonic-gate 			Bail("write to tmpfile failed");
31307c478bd9Sstevel@tonic-gate 		/* rewind so that the daemon will get the beginning */
31317c478bd9Sstevel@tonic-gate 		rewind(tmpfile);
31327c478bd9Sstevel@tonic-gate 
31337c478bd9Sstevel@tonic-gate 		desc.d_data.d_desc.d_descriptor = fd;
31347c478bd9Sstevel@tonic-gate 		desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
31357c478bd9Sstevel@tonic-gate 		descp = &desc;
31367c478bd9Sstevel@tonic-gate 		ndesc = 1;
31377c478bd9Sstevel@tonic-gate 
31387c478bd9Sstevel@tonic-gate 		new.cmd = cmd;
31397c478bd9Sstevel@tonic-gate 		new.new_len = 0;
31407c478bd9Sstevel@tonic-gate 		newp = &new;
31417c478bd9Sstevel@tonic-gate 		buflen = sizeof (ike_new_t);
31427c478bd9Sstevel@tonic-gate 
31437c478bd9Sstevel@tonic-gate 	} else {
31447c478bd9Sstevel@tonic-gate 		/* not enough information! */
31457c478bd9Sstevel@tonic-gate 		bail_msg(gettext("missing %s description or file name"), name);
31467c478bd9Sstevel@tonic-gate 	}
31477c478bd9Sstevel@tonic-gate 
31487c478bd9Sstevel@tonic-gate 	rtn = ikedoor_call((char *)newp, buflen, descp, ndesc);
31497c478bd9Sstevel@tonic-gate 
31507c478bd9Sstevel@tonic-gate 	if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
31517c478bd9Sstevel@tonic-gate 		ikeadm_err_msg(&rtn->svc_err,
31527c478bd9Sstevel@tonic-gate 		    gettext("error creating new %s"), name);
31537c478bd9Sstevel@tonic-gate 	} else {
31547c478bd9Sstevel@tonic-gate 		message(gettext("Successfully created new %s."), name);
31557c478bd9Sstevel@tonic-gate 	}
31567c478bd9Sstevel@tonic-gate }
31577c478bd9Sstevel@tonic-gate 
31587c478bd9Sstevel@tonic-gate static void
do_flush(int cmd)31597c478bd9Sstevel@tonic-gate do_flush(int cmd)
31607c478bd9Sstevel@tonic-gate {
31617c478bd9Sstevel@tonic-gate 	ike_service_t	*rtnp;
31627c478bd9Sstevel@tonic-gate 	ike_flush_t	flush;
31637c478bd9Sstevel@tonic-gate 
3164c7777ac8SPaul Wernau 	if (cmd != IKE_SVC_FLUSH_P1S && cmd != IKE_SVC_FLUSH_CERTCACHE) {
31657c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized flush command (%d)."), cmd);
31667c478bd9Sstevel@tonic-gate 	}
31677c478bd9Sstevel@tonic-gate 
31687c478bd9Sstevel@tonic-gate 	flush.cmd = cmd;
31697c478bd9Sstevel@tonic-gate 
31707c478bd9Sstevel@tonic-gate 	rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0);
31717c478bd9Sstevel@tonic-gate 	if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
31727c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush"));
31737c478bd9Sstevel@tonic-gate 	}
3174c7777ac8SPaul Wernau 	if (cmd == IKE_SVC_FLUSH_P1S)
3175c7777ac8SPaul Wernau 		message(gettext("Successfully flushed P1 SAs."));
3176c7777ac8SPaul Wernau 	else
3177c7777ac8SPaul Wernau 		message(gettext("Successfully flushed cert cache."));
31787c478bd9Sstevel@tonic-gate }
31797c478bd9Sstevel@tonic-gate 
31807c478bd9Sstevel@tonic-gate static void
do_rw(int cmd,int argc,char ** argv)31817c478bd9Sstevel@tonic-gate do_rw(int cmd, int argc, char **argv)
31827c478bd9Sstevel@tonic-gate {
31837c478bd9Sstevel@tonic-gate 	ike_service_t	*rtnp;
31847c478bd9Sstevel@tonic-gate 	ike_rw_t	rw;
31857c478bd9Sstevel@tonic-gate 	door_desc_t	desc, *descp = NULL;
31867c478bd9Sstevel@tonic-gate 	int		oflag, omode, fd, ndesc = 0;
31877c478bd9Sstevel@tonic-gate 	char		*op, *obj = NULL;
31887c478bd9Sstevel@tonic-gate 	boolean_t	writing = B_FALSE;
31897c478bd9Sstevel@tonic-gate 
31907c478bd9Sstevel@tonic-gate 	switch (cmd) {
31917c478bd9Sstevel@tonic-gate 	case IKE_SVC_READ_PS:
31927c478bd9Sstevel@tonic-gate 		obj = gettext("preshared key");
31937c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
31947c478bd9Sstevel@tonic-gate 	case IKE_SVC_READ_RULES:
31957c478bd9Sstevel@tonic-gate 		if (obj == NULL)
31967c478bd9Sstevel@tonic-gate 			obj = gettext("policy rule");
31977c478bd9Sstevel@tonic-gate 		op = gettext("read");
31987c478bd9Sstevel@tonic-gate 		oflag = O_RDONLY;
31997c478bd9Sstevel@tonic-gate 		omode = 0;
32007c478bd9Sstevel@tonic-gate 		break;
32017c478bd9Sstevel@tonic-gate 
32027c478bd9Sstevel@tonic-gate 	case IKE_SVC_WRITE_PS:
32037c478bd9Sstevel@tonic-gate 		obj = gettext("preshared key");
32047c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
32057c478bd9Sstevel@tonic-gate 	case IKE_SVC_WRITE_RULES:
32067c478bd9Sstevel@tonic-gate 		if (obj == NULL)
32077c478bd9Sstevel@tonic-gate 			obj = gettext("policy rule");
32087c478bd9Sstevel@tonic-gate 		op = gettext("write");
32097c478bd9Sstevel@tonic-gate 		oflag = O_RDWR | O_CREAT | O_EXCL;
32107c478bd9Sstevel@tonic-gate 		omode = S_IRUSR | S_IWUSR;
32117c478bd9Sstevel@tonic-gate 
32127c478bd9Sstevel@tonic-gate 		/* for write commands, dest location must be specified */
32137c478bd9Sstevel@tonic-gate 		if (argc < 1) {
32147c478bd9Sstevel@tonic-gate 			bail_msg(gettext("destination location required "
32157c478bd9Sstevel@tonic-gate 			    "to write %ss"), obj);
32167c478bd9Sstevel@tonic-gate 		}
32177c478bd9Sstevel@tonic-gate 		writing = B_TRUE;
32187c478bd9Sstevel@tonic-gate 		break;
32197c478bd9Sstevel@tonic-gate 
32207c478bd9Sstevel@tonic-gate 	default:
32217c478bd9Sstevel@tonic-gate 		bail_msg(gettext("unrecognized read/write command (%d)."), cmd);
32227c478bd9Sstevel@tonic-gate 	}
32237c478bd9Sstevel@tonic-gate 
32247c478bd9Sstevel@tonic-gate 	rw.cmd = cmd;
32257c478bd9Sstevel@tonic-gate 
32267c478bd9Sstevel@tonic-gate 	if (argc >= 1) {
32277c478bd9Sstevel@tonic-gate 		rw.rw_loc = IKE_RW_LOC_USER_SPEC;
32287c478bd9Sstevel@tonic-gate 		fd = open(argv[0], oflag, omode);
32297c478bd9Sstevel@tonic-gate 		if (fd < 0)
32307c478bd9Sstevel@tonic-gate 			Bail("open user-specified file");
32317c478bd9Sstevel@tonic-gate 
32327c478bd9Sstevel@tonic-gate 		desc.d_data.d_desc.d_descriptor = fd;
32337c478bd9Sstevel@tonic-gate 		desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
32347c478bd9Sstevel@tonic-gate 		descp = &desc;
32357c478bd9Sstevel@tonic-gate 		ndesc = 1;
32367c478bd9Sstevel@tonic-gate 	} else {
32377c478bd9Sstevel@tonic-gate 		rw.rw_loc = IKE_RW_LOC_DEFAULT;
32387c478bd9Sstevel@tonic-gate 	}
32397c478bd9Sstevel@tonic-gate 
32407c478bd9Sstevel@tonic-gate 	rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc);
32417c478bd9Sstevel@tonic-gate 	if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
32427c478bd9Sstevel@tonic-gate 		/*
32437c478bd9Sstevel@tonic-gate 		 * Need to remove the target file in the
32447c478bd9Sstevel@tonic-gate 		 * case of a failed write command.
32457c478bd9Sstevel@tonic-gate 		 */
32467c478bd9Sstevel@tonic-gate 		if (writing) {
32477c478bd9Sstevel@tonic-gate 			/*
32487c478bd9Sstevel@tonic-gate 			 * argv[0] must be valid if we're writing; we
32497c478bd9Sstevel@tonic-gate 			 * exit before setting this boolean if not.
32507c478bd9Sstevel@tonic-gate 			 */
32517c478bd9Sstevel@tonic-gate 			(void) unlink(argv[0]);
32527c478bd9Sstevel@tonic-gate 			(void) close(fd);
32537c478bd9Sstevel@tonic-gate 
32547c478bd9Sstevel@tonic-gate 			if ((rtnp != NULL) &&
32557c478bd9Sstevel@tonic-gate 			    (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
32567c478bd9Sstevel@tonic-gate 				message(gettext("No %s information to write."),
32577c478bd9Sstevel@tonic-gate 				    obj);
32587c478bd9Sstevel@tonic-gate 				return;
32597c478bd9Sstevel@tonic-gate 			}
32607c478bd9Sstevel@tonic-gate 		}
32617c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op);
32627c478bd9Sstevel@tonic-gate 	}
32637c478bd9Sstevel@tonic-gate 	message(gettext("Completed %s of %s configuration information."),
32647c478bd9Sstevel@tonic-gate 	    op, obj);
32657c478bd9Sstevel@tonic-gate }
32667c478bd9Sstevel@tonic-gate 
32677c478bd9Sstevel@tonic-gate static void
do_rbdump()32687c478bd9Sstevel@tonic-gate do_rbdump()
32697c478bd9Sstevel@tonic-gate {
32707c478bd9Sstevel@tonic-gate 	ike_cmd_t	req;
32717c478bd9Sstevel@tonic-gate 	ike_service_t	*rtnp;
32727c478bd9Sstevel@tonic-gate 
32737c478bd9Sstevel@tonic-gate 	req.cmd = IKE_SVC_DBG_RBDUMP;
32747c478bd9Sstevel@tonic-gate 
32757c478bd9Sstevel@tonic-gate 	rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0);
32767c478bd9Sstevel@tonic-gate 	if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
32777c478bd9Sstevel@tonic-gate 		ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush"));
32787c478bd9Sstevel@tonic-gate 	}
32797c478bd9Sstevel@tonic-gate 	message(gettext("Successfully dumped rulebase; check iked dbg"));
32807c478bd9Sstevel@tonic-gate }
32817c478bd9Sstevel@tonic-gate 
32827c478bd9Sstevel@tonic-gate #define	REQ_ARG_CNT	1
32837c478bd9Sstevel@tonic-gate 
3284e3320f40Smarkfen /*ARGSUSED*/
32857c478bd9Sstevel@tonic-gate static void
parseit(int argc,char ** argv,char * notused,boolean_t notused_either)328625e435e0Spwernau parseit(int argc, char **argv, char *notused, boolean_t notused_either)
32877c478bd9Sstevel@tonic-gate {
32887c478bd9Sstevel@tonic-gate 	int	cmd, cmd_obj_args = 1;
32897c478bd9Sstevel@tonic-gate 	char	*cmdstr, *objstr;
32907c478bd9Sstevel@tonic-gate 
32917c478bd9Sstevel@tonic-gate 	if (interactive) {
32927c478bd9Sstevel@tonic-gate 		if (argc == 0)
32937c478bd9Sstevel@tonic-gate 			return;
32947c478bd9Sstevel@tonic-gate 	}
32957c478bd9Sstevel@tonic-gate 
32967c478bd9Sstevel@tonic-gate 	if (argc < REQ_ARG_CNT) {
32977c478bd9Sstevel@tonic-gate 		usage();
32987c478bd9Sstevel@tonic-gate 	}
32997c478bd9Sstevel@tonic-gate 
33007c478bd9Sstevel@tonic-gate 	cmdstr = argv[0];
33017c478bd9Sstevel@tonic-gate 	if (argc > REQ_ARG_CNT) {
33027c478bd9Sstevel@tonic-gate 		cmd_obj_args++;
33037c478bd9Sstevel@tonic-gate 		objstr = argv[1];
33047c478bd9Sstevel@tonic-gate 	} else {
33057c478bd9Sstevel@tonic-gate 		objstr = NULL;
33067c478bd9Sstevel@tonic-gate 	}
33077c478bd9Sstevel@tonic-gate 	cmd = parsecmd(cmdstr, objstr);
33087c478bd9Sstevel@tonic-gate 
33097c478bd9Sstevel@tonic-gate 	/* skip over args specifying command/object */
33107c478bd9Sstevel@tonic-gate 	argc -= cmd_obj_args;
33117c478bd9Sstevel@tonic-gate 	argv += cmd_obj_args;
33127c478bd9Sstevel@tonic-gate 
33137c478bd9Sstevel@tonic-gate 	switch (cmd) {
33140f2065ccSmarkfen 	case IKE_SVC_GET_DEFS:
3315bfe6f8f5SVladimir Kotal 		if (argc != 0) {
3316bfe6f8f5SVladimir Kotal 			print_get_help();
3317bfe6f8f5SVladimir Kotal 			break;
3318bfe6f8f5SVladimir Kotal 		}
33190f2065ccSmarkfen 		do_getdefs(cmd);
33200f2065ccSmarkfen 		break;
33217c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_DBG:
33227c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_PRIV:
3323bfe6f8f5SVladimir Kotal 		if (argc != 0) {
3324bfe6f8f5SVladimir Kotal 			print_get_help();
3325bfe6f8f5SVladimir Kotal 			break;
3326bfe6f8f5SVladimir Kotal 		}
33277c478bd9Sstevel@tonic-gate 		do_getvar(cmd);
33287c478bd9Sstevel@tonic-gate 		break;
33297c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_STATS:
3330bfe6f8f5SVladimir Kotal 		if (argc != 0) {
3331bfe6f8f5SVladimir Kotal 			print_get_help();
3332bfe6f8f5SVladimir Kotal 			break;
3333bfe6f8f5SVladimir Kotal 		}
33347c478bd9Sstevel@tonic-gate 		do_getstats(cmd);
33357c478bd9Sstevel@tonic-gate 		break;
33367c478bd9Sstevel@tonic-gate 	case IKE_SVC_SET_DBG:
33377c478bd9Sstevel@tonic-gate 	case IKE_SVC_SET_PRIV:
33387c478bd9Sstevel@tonic-gate 		do_setvar(cmd, argc, argv);
33397c478bd9Sstevel@tonic-gate 		break;
3340c7777ac8SPaul Wernau 	case IKE_SVC_SET_PIN:
3341c7777ac8SPaul Wernau 	case IKE_SVC_DEL_PIN:
3342c7777ac8SPaul Wernau 		do_setdel_pin(cmd, argc, argv);
3343c7777ac8SPaul Wernau 		break;
33447c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_P1S:
33457c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_RULES:
33465d01c172SVladimir Kotal 	case IKE_SVC_DUMP_GROUPS:
33475d01c172SVladimir Kotal 	case IKE_SVC_DUMP_ENCRALGS:
33485d01c172SVladimir Kotal 	case IKE_SVC_DUMP_AUTHALGS:
33497c478bd9Sstevel@tonic-gate 	case IKE_SVC_DUMP_PS:
3350c7777ac8SPaul Wernau 	case IKE_SVC_DUMP_CERTCACHE:
335195c74518SToomas Soome 		if (argc != 0) {
3352bfe6f8f5SVladimir Kotal 			print_dump_help();
3353bfe6f8f5SVladimir Kotal 			break;
3354bfe6f8f5SVladimir Kotal 		}
33557c478bd9Sstevel@tonic-gate 		do_dump(cmd);
33567c478bd9Sstevel@tonic-gate 		break;
33577c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_P1:
33587c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_RULE:
33597c478bd9Sstevel@tonic-gate 	case IKE_SVC_GET_PS:
33607c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_P1:
33617c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_RULE:
33627c478bd9Sstevel@tonic-gate 	case IKE_SVC_DEL_PS:
33637c478bd9Sstevel@tonic-gate 		do_getdel(cmd, argc, argv);
33647c478bd9Sstevel@tonic-gate 		break;
33657c478bd9Sstevel@tonic-gate 	case IKE_SVC_NEW_RULE:
33667c478bd9Sstevel@tonic-gate 	case IKE_SVC_NEW_PS:
33677c478bd9Sstevel@tonic-gate 		do_new(cmd, argc, argv);
33687c478bd9Sstevel@tonic-gate 		break;
33697c478bd9Sstevel@tonic-gate 	case IKE_SVC_FLUSH_P1S:
3370c7777ac8SPaul Wernau 	case IKE_SVC_FLUSH_CERTCACHE:
3371bfe6f8f5SVladimir Kotal 		if (argc != 0) {
3372bfe6f8f5SVladimir Kotal 			print_flush_help();
3373bfe6f8f5SVladimir Kotal 			break;
3374bfe6f8f5SVladimir Kotal 		}
33757c478bd9Sstevel@tonic-gate 		do_flush(cmd);
33767c478bd9Sstevel@tonic-gate 		break;
33777c478bd9Sstevel@tonic-gate 	case IKE_SVC_READ_RULES:
33787c478bd9Sstevel@tonic-gate 	case IKE_SVC_READ_PS:
33797c478bd9Sstevel@tonic-gate 	case IKE_SVC_WRITE_RULES:
33807c478bd9Sstevel@tonic-gate 	case IKE_SVC_WRITE_PS:
33817c478bd9Sstevel@tonic-gate 		do_rw(cmd, argc, argv);
33827c478bd9Sstevel@tonic-gate 		break;
33837c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_GENERAL:
33847c478bd9Sstevel@tonic-gate 		print_help();
33857c478bd9Sstevel@tonic-gate 		break;
33867c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_GET:
33877c478bd9Sstevel@tonic-gate 		print_get_help();
33887c478bd9Sstevel@tonic-gate 		break;
33897c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_SET:
33907c478bd9Sstevel@tonic-gate 		print_set_help();
33917c478bd9Sstevel@tonic-gate 		break;
33927c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_ADD:
33937c478bd9Sstevel@tonic-gate 		print_add_help();
33947c478bd9Sstevel@tonic-gate 		break;
33957c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_DEL:
33967c478bd9Sstevel@tonic-gate 		print_del_help();
33977c478bd9Sstevel@tonic-gate 		break;
33987c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_DUMP:
33997c478bd9Sstevel@tonic-gate 		print_dump_help();
34007c478bd9Sstevel@tonic-gate 		break;
34017c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_FLUSH:
34027c478bd9Sstevel@tonic-gate 		print_flush_help();
34037c478bd9Sstevel@tonic-gate 		break;
34047c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_READ:
34057c478bd9Sstevel@tonic-gate 		print_read_help();
34067c478bd9Sstevel@tonic-gate 		break;
34077c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_WRITE:
34087c478bd9Sstevel@tonic-gate 		print_write_help();
34097c478bd9Sstevel@tonic-gate 		break;
3410c7777ac8SPaul Wernau 	case IKEADM_HELP_TOKEN:
3411c7777ac8SPaul Wernau 		print_token_help();
3412c7777ac8SPaul Wernau 		break;
34137c478bd9Sstevel@tonic-gate 	case IKEADM_HELP_HELP:
34147c478bd9Sstevel@tonic-gate 		print_help_help();
34157c478bd9Sstevel@tonic-gate 		break;
34167c478bd9Sstevel@tonic-gate 	case IKEADM_EXIT:
34177c478bd9Sstevel@tonic-gate 		if (interactive)
34187c478bd9Sstevel@tonic-gate 			exit(0);
34197c478bd9Sstevel@tonic-gate 		break;
34207c478bd9Sstevel@tonic-gate 	case IKE_SVC_DBG_RBDUMP:
34217c478bd9Sstevel@tonic-gate 		do_rbdump();
34227c478bd9Sstevel@tonic-gate 		break;
34237c478bd9Sstevel@tonic-gate 	case IKE_SVC_ERROR:
34247c478bd9Sstevel@tonic-gate 		usage();
34257c478bd9Sstevel@tonic-gate 	default:
34267c478bd9Sstevel@tonic-gate 		exit(0);
34277c478bd9Sstevel@tonic-gate 	}
34287c478bd9Sstevel@tonic-gate }
34297c478bd9Sstevel@tonic-gate 
34307c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)34317c478bd9Sstevel@tonic-gate main(int argc, char **argv)
34327c478bd9Sstevel@tonic-gate {
3433*ef150c2bSRichard Lowe 	int	ch;
34347c478bd9Sstevel@tonic-gate 
34357c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
34367c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
34377c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
34387c478bd9Sstevel@tonic-gate #endif
34397c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
34407c478bd9Sstevel@tonic-gate 
34417c478bd9Sstevel@tonic-gate 	while ((ch = getopt(argc, argv, "hpn")) != EOF) {
34427c478bd9Sstevel@tonic-gate 		switch (ch) {
34437c478bd9Sstevel@tonic-gate 		case 'h':
34447c478bd9Sstevel@tonic-gate 			print_help();
34457c478bd9Sstevel@tonic-gate 			return (0);
34467c478bd9Sstevel@tonic-gate 		case 'p':
34477c478bd9Sstevel@tonic-gate 			pflag = B_TRUE;
34487c478bd9Sstevel@tonic-gate 			break;
34497c478bd9Sstevel@tonic-gate 		case 'n':
34507c478bd9Sstevel@tonic-gate 			nflag = B_TRUE;
34517c478bd9Sstevel@tonic-gate 			break;
34527c478bd9Sstevel@tonic-gate 		default:
34537c478bd9Sstevel@tonic-gate 			usage();
34547c478bd9Sstevel@tonic-gate 		}
34557c478bd9Sstevel@tonic-gate 	}
34567c478bd9Sstevel@tonic-gate 	argc -= optind;
34577c478bd9Sstevel@tonic-gate 	argv += optind;
34587c478bd9Sstevel@tonic-gate 
3459c8393ed7Smarkfen 	if (open_door() < 0) {
3460c8393ed7Smarkfen 		(void) fprintf(stderr,
3461c8393ed7Smarkfen 		    gettext("Unable to communicate with in.iked\n"));
3462c8393ed7Smarkfen 		Bail("open_door failed");
3463c8393ed7Smarkfen 	}
34647c478bd9Sstevel@tonic-gate 
34657c478bd9Sstevel@tonic-gate 	if (*argv == NULL) {
34667c478bd9Sstevel@tonic-gate 		/* no cmd-line args, do interactive mode */
3467bfe6f8f5SVladimir Kotal 		do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit,
3468bfe6f8f5SVladimir Kotal 		    no_match);
34697c478bd9Sstevel@tonic-gate 	}
34707c478bd9Sstevel@tonic-gate 
347125e435e0Spwernau 	parseit(argc, argv, NULL, B_FALSE);
34727c478bd9Sstevel@tonic-gate 
34737c478bd9Sstevel@tonic-gate 	return (0);
34747c478bd9Sstevel@tonic-gate }
3475