17c478bd9Sstevel@tonic-gate /*
2a12f8217Spwernau *
37c478bd9Sstevel@tonic-gate * CDDL HEADER START
47c478bd9Sstevel@tonic-gate *
57c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
68810c16bSdanmcd * Common Development and Distribution License (the "License").
78810c16bSdanmcd * You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
23bfe6f8f5SVladimir Kotal * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*33f5ff17SMilan Jurik * Copyright 2012 Milan Juri. All rights reserved.
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <unistd.h>
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <stdarg.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/stat.h>
347c478bd9Sstevel@tonic-gate #include <fcntl.h>
357c478bd9Sstevel@tonic-gate #include <sys/sysconf.h>
367c478bd9Sstevel@tonic-gate #include <strings.h>
377c478bd9Sstevel@tonic-gate #include <ctype.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
397c478bd9Sstevel@tonic-gate #include <sys/socket.h>
407c478bd9Sstevel@tonic-gate #include <netdb.h>
417c478bd9Sstevel@tonic-gate #include <netinet/in.h>
427c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
437c478bd9Sstevel@tonic-gate #include <net/pfkeyv2.h>
447c478bd9Sstevel@tonic-gate #include <net/pfpolicy.h>
457c478bd9Sstevel@tonic-gate #include <libintl.h>
467c478bd9Sstevel@tonic-gate #include <setjmp.h>
477c478bd9Sstevel@tonic-gate #include <libgen.h>
48e3320f40Smarkfen #include <libscf.h>
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate #include "ipsec_util.h"
517c478bd9Sstevel@tonic-gate #include "ikedoor.h"
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate * This file contains support functions that are shared by the ipsec
55bb3ed8dfSpwernau * utilities and daemons including ipseckey(1m), ikeadm(1m) and in.iked(1m).
567c478bd9Sstevel@tonic-gate */
577c478bd9Sstevel@tonic-gate
58bb3ed8dfSpwernau
59bb3ed8dfSpwernau #define EFD(file) (((file) == stdout) ? stderr : (file))
60bb3ed8dfSpwernau
61bfe6f8f5SVladimir Kotal /* Limits for interactive mode. */
62bfe6f8f5SVladimir Kotal #define MAX_LINE_LEN IBUF_SIZE
63bfe6f8f5SVladimir Kotal #define MAX_CMD_HIST 64000 /* in bytes */
64bfe6f8f5SVladimir Kotal
657c478bd9Sstevel@tonic-gate /* Set standard default/initial values for globals... */
667c478bd9Sstevel@tonic-gate boolean_t pflag = B_FALSE; /* paranoid w.r.t. printing keying material */
677c478bd9Sstevel@tonic-gate boolean_t nflag = B_FALSE; /* avoid nameservice? */
687c478bd9Sstevel@tonic-gate boolean_t interactive = B_FALSE; /* util not running on cmdline */
697c478bd9Sstevel@tonic-gate boolean_t readfile = B_FALSE; /* cmds are being read from a file */
707c478bd9Sstevel@tonic-gate uint_t lineno = 0; /* track location if reading cmds from file */
71e3320f40Smarkfen uint_t lines_added = 0;
72e3320f40Smarkfen uint_t lines_parsed = 0;
737c478bd9Sstevel@tonic-gate jmp_buf env; /* for error recovery in interactive/readfile modes */
74e3320f40Smarkfen char *my_fmri = NULL;
75e3320f40Smarkfen FILE *debugfile = stderr;
76bfe6f8f5SVladimir Kotal static GetLine *gl = NULL; /* for interactive mode */
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate /*
797c478bd9Sstevel@tonic-gate * Print errno and exit if cmdline or readfile, reset state if interactive
80a7485808Smarkfen * The error string *what should be dgettext()'d before calling bail().
817c478bd9Sstevel@tonic-gate */
827c478bd9Sstevel@tonic-gate void
bail(char * what)837c478bd9Sstevel@tonic-gate bail(char *what)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate if (errno != 0)
867c478bd9Sstevel@tonic-gate warn(what);
877c478bd9Sstevel@tonic-gate else
88e3320f40Smarkfen warnx(dgettext(TEXT_DOMAIN, "Error: %s"), what);
897c478bd9Sstevel@tonic-gate if (readfile) {
90e3320f40Smarkfen return;
917c478bd9Sstevel@tonic-gate }
927c478bd9Sstevel@tonic-gate if (interactive && !readfile)
937c478bd9Sstevel@tonic-gate longjmp(env, 2);
94e3320f40Smarkfen EXIT_FATAL(NULL);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate /*
987c478bd9Sstevel@tonic-gate * Print caller-supplied variable-arg error msg, then exit if cmdline or
997c478bd9Sstevel@tonic-gate * readfile, or reset state if interactive.
1007c478bd9Sstevel@tonic-gate */
1017c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
1027c478bd9Sstevel@tonic-gate void
bail_msg(char * fmt,...)1037c478bd9Sstevel@tonic-gate bail_msg(char *fmt, ...)
1047c478bd9Sstevel@tonic-gate {
1057c478bd9Sstevel@tonic-gate va_list ap;
1067c478bd9Sstevel@tonic-gate char msgbuf[BUFSIZ];
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate va_start(ap, fmt);
1097c478bd9Sstevel@tonic-gate (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap);
1107c478bd9Sstevel@tonic-gate va_end(ap);
1117c478bd9Sstevel@tonic-gate if (readfile)
112a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
113a7485808Smarkfen "ERROR on line %u:\n%s\n"), lineno, msgbuf);
1147c478bd9Sstevel@tonic-gate else
115a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN, "ERROR: %s\n"), msgbuf);
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate if (interactive && !readfile)
1187c478bd9Sstevel@tonic-gate longjmp(env, 1);
1197c478bd9Sstevel@tonic-gate
120e3320f40Smarkfen EXIT_FATAL(NULL);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate
123510c3f91SVladimir Kotal /*
124510c3f91SVladimir Kotal * bytecnt2str() wrapper. Zeroes out the input buffer and if the number
125510c3f91SVladimir Kotal * of bytes to be converted is more than 1K, it will produce readable string
126510c3f91SVladimir Kotal * in parentheses, store it in the original buffer and return the pointer to it.
127510c3f91SVladimir Kotal * Maximum length of the returned string is 14 characters (not including
128510c3f91SVladimir Kotal * the terminating zero).
129510c3f91SVladimir Kotal */
130510c3f91SVladimir Kotal char *
bytecnt2out(uint64_t num,char * buf,size_t bufsiz,int flags)131510c3f91SVladimir Kotal bytecnt2out(uint64_t num, char *buf, size_t bufsiz, int flags)
132510c3f91SVladimir Kotal {
133510c3f91SVladimir Kotal char *str;
134510c3f91SVladimir Kotal
135510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
136510c3f91SVladimir Kotal
137510c3f91SVladimir Kotal if (num > 1024) {
138510c3f91SVladimir Kotal /* Return empty string in case of out-of-memory. */
139510c3f91SVladimir Kotal if ((str = malloc(bufsiz)) == NULL)
140510c3f91SVladimir Kotal return (buf);
141510c3f91SVladimir Kotal
142510c3f91SVladimir Kotal (void) bytecnt2str(num, str, bufsiz);
143510c3f91SVladimir Kotal /* Detect overflow. */
144510c3f91SVladimir Kotal if (strlen(str) == 0) {
145510c3f91SVladimir Kotal free(str);
146510c3f91SVladimir Kotal return (buf);
147510c3f91SVladimir Kotal }
148510c3f91SVladimir Kotal
149510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
150510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%s(%sB)%s",
151510c3f91SVladimir Kotal flags & SPC_BEGIN ? " " : "", str,
152510c3f91SVladimir Kotal flags & SPC_END ? " " : "") >= bufsiz)
153510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
154510c3f91SVladimir Kotal
155510c3f91SVladimir Kotal free(str);
156510c3f91SVladimir Kotal }
157510c3f91SVladimir Kotal
158510c3f91SVladimir Kotal return (buf);
159510c3f91SVladimir Kotal }
160510c3f91SVladimir Kotal
161510c3f91SVladimir Kotal /*
162510c3f91SVladimir Kotal * Convert 64-bit number to human readable string. Useful mainly for the
163510c3f91SVladimir Kotal * byte lifetime counters. Returns pointer to the user supplied buffer.
164510c3f91SVladimir Kotal * Able to convert up to Exabytes. Maximum length of the string produced
165510c3f91SVladimir Kotal * is 9 characters (not counting the terminating zero).
166510c3f91SVladimir Kotal */
167510c3f91SVladimir Kotal char *
bytecnt2str(uint64_t num,char * buf,size_t buflen)168510c3f91SVladimir Kotal bytecnt2str(uint64_t num, char *buf, size_t buflen)
169510c3f91SVladimir Kotal {
170510c3f91SVladimir Kotal uint64_t n = num;
171510c3f91SVladimir Kotal char u;
172510c3f91SVladimir Kotal int index = 0;
173510c3f91SVladimir Kotal
174510c3f91SVladimir Kotal while (n >= 1024) {
175510c3f91SVladimir Kotal n /= 1024;
176510c3f91SVladimir Kotal index++;
177510c3f91SVladimir Kotal }
178510c3f91SVladimir Kotal
179510c3f91SVladimir Kotal /* The field has all units this function can represent. */
180510c3f91SVladimir Kotal u = " KMGTPE"[index];
181510c3f91SVladimir Kotal
182510c3f91SVladimir Kotal if (index == 0) {
183510c3f91SVladimir Kotal /* Less than 1K */
184510c3f91SVladimir Kotal if (snprintf(buf, buflen, "%llu ", num) >= buflen)
185510c3f91SVladimir Kotal (void) memset(buf, '\0', buflen);
186510c3f91SVladimir Kotal } else {
187510c3f91SVladimir Kotal /* Otherwise display 2 precision digits. */
188510c3f91SVladimir Kotal if (snprintf(buf, buflen, "%.2f %c",
189510c3f91SVladimir Kotal (double)num / (1ULL << index * 10), u) >= buflen)
190510c3f91SVladimir Kotal (void) memset(buf, '\0', buflen);
191510c3f91SVladimir Kotal }
192510c3f91SVladimir Kotal
193510c3f91SVladimir Kotal return (buf);
194510c3f91SVladimir Kotal }
195510c3f91SVladimir Kotal
196510c3f91SVladimir Kotal /*
197510c3f91SVladimir Kotal * secs2str() wrapper. Zeroes out the input buffer and if the number of
198510c3f91SVladimir Kotal * seconds to be converted is more than minute, it will produce readable
199510c3f91SVladimir Kotal * string in parentheses, store it in the original buffer and return the
200510c3f91SVladimir Kotal * pointer to it.
201510c3f91SVladimir Kotal */
202510c3f91SVladimir Kotal char *
secs2out(unsigned int secs,char * buf,int bufsiz,int flags)203510c3f91SVladimir Kotal secs2out(unsigned int secs, char *buf, int bufsiz, int flags)
204510c3f91SVladimir Kotal {
205510c3f91SVladimir Kotal char *str;
206510c3f91SVladimir Kotal
207510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
208510c3f91SVladimir Kotal
209510c3f91SVladimir Kotal if (secs > 60) {
210510c3f91SVladimir Kotal /* Return empty string in case of out-of-memory. */
211510c3f91SVladimir Kotal if ((str = malloc(bufsiz)) == NULL)
212510c3f91SVladimir Kotal return (buf);
213510c3f91SVladimir Kotal
214510c3f91SVladimir Kotal (void) secs2str(secs, str, bufsiz);
215510c3f91SVladimir Kotal /* Detect overflow. */
216510c3f91SVladimir Kotal if (strlen(str) == 0) {
217510c3f91SVladimir Kotal free(str);
218510c3f91SVladimir Kotal return (buf);
219510c3f91SVladimir Kotal }
220510c3f91SVladimir Kotal
221510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
222510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%s(%s)%s",
223510c3f91SVladimir Kotal flags & SPC_BEGIN ? " " : "", str,
224510c3f91SVladimir Kotal flags & SPC_END ? " " : "") >= bufsiz)
225510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
226510c3f91SVladimir Kotal
227510c3f91SVladimir Kotal free(str);
228510c3f91SVladimir Kotal }
229510c3f91SVladimir Kotal
230510c3f91SVladimir Kotal return (buf);
231510c3f91SVladimir Kotal }
232510c3f91SVladimir Kotal
233510c3f91SVladimir Kotal /*
234510c3f91SVladimir Kotal * Convert number of seconds to human readable string. Useful mainly for
235510c3f91SVladimir Kotal * the lifetime counters. Returns pointer to the user supplied buffer.
236510c3f91SVladimir Kotal * Able to convert up to days.
237510c3f91SVladimir Kotal */
238510c3f91SVladimir Kotal char *
secs2str(unsigned int secs,char * buf,int bufsiz)239510c3f91SVladimir Kotal secs2str(unsigned int secs, char *buf, int bufsiz)
240510c3f91SVladimir Kotal {
241510c3f91SVladimir Kotal double val = secs;
242510c3f91SVladimir Kotal char *unit = "second";
243510c3f91SVladimir Kotal
244510c3f91SVladimir Kotal if (val >= 24*60*60) {
245510c3f91SVladimir Kotal val /= 86400;
246510c3f91SVladimir Kotal unit = "day";
247510c3f91SVladimir Kotal } else if (val >= 60*60) {
248510c3f91SVladimir Kotal val /= 60*60;
249510c3f91SVladimir Kotal unit = "hour";
250510c3f91SVladimir Kotal } else if (val >= 60) {
251510c3f91SVladimir Kotal val /= 60;
252510c3f91SVladimir Kotal unit = "minute";
253510c3f91SVladimir Kotal }
254510c3f91SVladimir Kotal
255510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
256510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%.2f %s%s", val, unit,
257510c3f91SVladimir Kotal val >= 2 ? "s" : "") >= bufsiz)
258510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
259510c3f91SVladimir Kotal
260510c3f91SVladimir Kotal return (buf);
261510c3f91SVladimir Kotal }
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate * dump_XXX functions produce ASCII output from various structures.
2657c478bd9Sstevel@tonic-gate *
2667c478bd9Sstevel@tonic-gate * Because certain errors need to do this to stderr, dump_XXX functions
2677c478bd9Sstevel@tonic-gate * take a FILE pointer.
2687c478bd9Sstevel@tonic-gate *
2697c478bd9Sstevel@tonic-gate * If an error occured while writing to the specified file, these
2707c478bd9Sstevel@tonic-gate * functions return -1, zero otherwise.
2717c478bd9Sstevel@tonic-gate */
2727c478bd9Sstevel@tonic-gate
2737c478bd9Sstevel@tonic-gate int
dump_sockaddr(struct sockaddr * sa,uint8_t prefixlen,boolean_t addr_only,FILE * where,boolean_t ignore_nss)2748810c16bSdanmcd dump_sockaddr(struct sockaddr *sa, uint8_t prefixlen, boolean_t addr_only,
275bb3ed8dfSpwernau FILE *where, boolean_t ignore_nss)
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate struct sockaddr_in *sin;
2787c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6;
2797c478bd9Sstevel@tonic-gate char *printable_addr, *protocol;
2807c478bd9Sstevel@tonic-gate uint8_t *addrptr;
2818810c16bSdanmcd /* Add 4 chars to hold '/nnn' for prefixes. */
2828810c16bSdanmcd char storage[INET6_ADDRSTRLEN + 4];
2837c478bd9Sstevel@tonic-gate uint16_t port;
2847c478bd9Sstevel@tonic-gate boolean_t unspec;
2857c478bd9Sstevel@tonic-gate struct hostent *hp;
2867c478bd9Sstevel@tonic-gate int getipnode_errno, addrlen;
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate switch (sa->sa_family) {
2897c478bd9Sstevel@tonic-gate case AF_INET:
2907c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
2917c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)sa;
2927c478bd9Sstevel@tonic-gate addrptr = (uint8_t *)&sin->sin_addr;
2937c478bd9Sstevel@tonic-gate port = sin->sin_port;
2947c478bd9Sstevel@tonic-gate protocol = "AF_INET";
2957c478bd9Sstevel@tonic-gate unspec = (sin->sin_addr.s_addr == 0);
2967c478bd9Sstevel@tonic-gate addrlen = sizeof (sin->sin_addr);
2977c478bd9Sstevel@tonic-gate break;
2987c478bd9Sstevel@tonic-gate case AF_INET6:
2997c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
3007c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)sa;
3017c478bd9Sstevel@tonic-gate addrptr = (uint8_t *)&sin6->sin6_addr;
3027c478bd9Sstevel@tonic-gate port = sin6->sin6_port;
3037c478bd9Sstevel@tonic-gate protocol = "AF_INET6";
3047c478bd9Sstevel@tonic-gate unspec = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr);
3057c478bd9Sstevel@tonic-gate addrlen = sizeof (sin6->sin6_addr);
3067c478bd9Sstevel@tonic-gate break;
3077c478bd9Sstevel@tonic-gate default:
3087c478bd9Sstevel@tonic-gate return (0);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate if (inet_ntop(sa->sa_family, addrptr, storage, INET6_ADDRSTRLEN) ==
3127c478bd9Sstevel@tonic-gate NULL) {
313a7485808Smarkfen printable_addr = dgettext(TEXT_DOMAIN, "Invalid IP address.");
3147c478bd9Sstevel@tonic-gate } else {
3158810c16bSdanmcd char prefix[5]; /* "/nnn" with terminator. */
3168810c16bSdanmcd
3178810c16bSdanmcd (void) snprintf(prefix, sizeof (prefix), "/%d", prefixlen);
3187c478bd9Sstevel@tonic-gate printable_addr = storage;
3198810c16bSdanmcd if (prefixlen != 0) {
3208810c16bSdanmcd (void) strlcat(printable_addr, prefix,
3218810c16bSdanmcd sizeof (storage));
3228810c16bSdanmcd }
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate if (addr_only) {
3257c478bd9Sstevel@tonic-gate if (fprintf(where, "%s", printable_addr) < 0)
3267c478bd9Sstevel@tonic-gate return (-1);
3277c478bd9Sstevel@tonic-gate } else {
328a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
329a7485808Smarkfen "%s: port %d, %s"), protocol,
3307c478bd9Sstevel@tonic-gate ntohs(port), printable_addr) < 0)
3317c478bd9Sstevel@tonic-gate return (-1);
332bb3ed8dfSpwernau if (ignore_nss == B_FALSE) {
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate * Do AF_independent reverse hostname lookup here.
3357c478bd9Sstevel@tonic-gate */
3367c478bd9Sstevel@tonic-gate if (unspec) {
3377c478bd9Sstevel@tonic-gate if (fprintf(where,
338a7485808Smarkfen dgettext(TEXT_DOMAIN,
339a7485808Smarkfen " <unspecified>")) < 0)
3407c478bd9Sstevel@tonic-gate return (-1);
3417c478bd9Sstevel@tonic-gate } else {
3427c478bd9Sstevel@tonic-gate hp = getipnodebyaddr((char *)addrptr, addrlen,
3437c478bd9Sstevel@tonic-gate sa->sa_family, &getipnode_errno);
3447c478bd9Sstevel@tonic-gate if (hp != NULL) {
3457c478bd9Sstevel@tonic-gate if (fprintf(where,
3467c478bd9Sstevel@tonic-gate " (%s)", hp->h_name) < 0)
3477c478bd9Sstevel@tonic-gate return (-1);
3487c478bd9Sstevel@tonic-gate freehostent(hp);
3497c478bd9Sstevel@tonic-gate } else {
3507c478bd9Sstevel@tonic-gate if (fprintf(where,
351a7485808Smarkfen dgettext(TEXT_DOMAIN,
352a7485808Smarkfen " <unknown>")) < 0)
3537c478bd9Sstevel@tonic-gate return (-1);
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate if (fputs(".\n", where) == EOF)
3587c478bd9Sstevel@tonic-gate return (-1);
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate return (0);
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate /*
364628b0c67SMark Fenwick * Dump a key, any salt and bitlen.
365628b0c67SMark Fenwick * The key is made up of a stream of bits. If the algorithm requires a salt
366628b0c67SMark Fenwick * value, this will also be part of the dumped key. The last "saltbits" of the
367628b0c67SMark Fenwick * key string, reading left to right will be the salt value. To make it easier
368628b0c67SMark Fenwick * to see which bits make up the key, the salt value is enclosed in []'s.
369628b0c67SMark Fenwick * This function can also be called when ipseckey(1m) -s is run, this "saves"
370628b0c67SMark Fenwick * the SAs, including the key to a file. When this is the case, the []'s are
371628b0c67SMark Fenwick * not printed.
372628b0c67SMark Fenwick *
373628b0c67SMark Fenwick * The implementation allows the kernel to be told about the length of the salt
374628b0c67SMark Fenwick * in whole bytes only. If this changes, this function will need to be updated.
3757c478bd9Sstevel@tonic-gate */
3767c478bd9Sstevel@tonic-gate int
dump_key(uint8_t * keyp,uint_t bitlen,uint_t saltbits,FILE * where,boolean_t separate_salt)377628b0c67SMark Fenwick dump_key(uint8_t *keyp, uint_t bitlen, uint_t saltbits, FILE *where,
378628b0c67SMark Fenwick boolean_t separate_salt)
3797c478bd9Sstevel@tonic-gate {
380628b0c67SMark Fenwick int numbytes, saltbytes;
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate numbytes = SADB_1TO8(bitlen);
383628b0c67SMark Fenwick saltbytes = SADB_1TO8(saltbits);
384628b0c67SMark Fenwick numbytes += saltbytes;
385628b0c67SMark Fenwick
3867c478bd9Sstevel@tonic-gate /* The & 0x7 is to check for leftover bits. */
3877c478bd9Sstevel@tonic-gate if ((bitlen & 0x7) != 0)
3887c478bd9Sstevel@tonic-gate numbytes++;
389628b0c67SMark Fenwick
3907c478bd9Sstevel@tonic-gate while (numbytes-- != 0) {
3917c478bd9Sstevel@tonic-gate if (pflag) {
3927c478bd9Sstevel@tonic-gate /* Print no keys if paranoid */
3937c478bd9Sstevel@tonic-gate if (fprintf(where, "XX") < 0)
3947c478bd9Sstevel@tonic-gate return (-1);
3957c478bd9Sstevel@tonic-gate } else {
3967c478bd9Sstevel@tonic-gate if (fprintf(where, "%02x", *keyp++) < 0)
3977c478bd9Sstevel@tonic-gate return (-1);
3987c478bd9Sstevel@tonic-gate }
399628b0c67SMark Fenwick if (separate_salt && saltbytes != 0 &&
400628b0c67SMark Fenwick numbytes == saltbytes) {
401628b0c67SMark Fenwick if (fprintf(where, "[") < 0)
4027c478bd9Sstevel@tonic-gate return (-1);
403628b0c67SMark Fenwick }
404628b0c67SMark Fenwick }
405628b0c67SMark Fenwick
406628b0c67SMark Fenwick if (separate_salt && saltbits != 0) {
407628b0c67SMark Fenwick if (fprintf(where, "]/%u+%u", bitlen, saltbits) < 0)
408628b0c67SMark Fenwick return (-1);
409628b0c67SMark Fenwick } else {
410628b0c67SMark Fenwick if (fprintf(where, "/%u", bitlen + saltbits) < 0)
411628b0c67SMark Fenwick return (-1);
412628b0c67SMark Fenwick }
413628b0c67SMark Fenwick
4147c478bd9Sstevel@tonic-gate return (0);
4157c478bd9Sstevel@tonic-gate }
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate * Print an authentication or encryption algorithm
4197c478bd9Sstevel@tonic-gate */
4207c478bd9Sstevel@tonic-gate static int
dump_generic_alg(uint8_t alg_num,int proto_num,FILE * where)4217c478bd9Sstevel@tonic-gate dump_generic_alg(uint8_t alg_num, int proto_num, FILE *where)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate struct ipsecalgent *alg;
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate alg = getipsecalgbynum(alg_num, proto_num, NULL);
4267c478bd9Sstevel@tonic-gate if (alg == NULL) {
427a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
428a7485808Smarkfen "<unknown %u>"), alg_num) < 0)
4297c478bd9Sstevel@tonic-gate return (-1);
4307c478bd9Sstevel@tonic-gate return (0);
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate /*
4347c478bd9Sstevel@tonic-gate * Special-case <none> for backward output compat.
4357c478bd9Sstevel@tonic-gate * Assume that SADB_AALG_NONE == SADB_EALG_NONE.
4367c478bd9Sstevel@tonic-gate */
4377c478bd9Sstevel@tonic-gate if (alg_num == SADB_AALG_NONE) {
438a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN,
439a7485808Smarkfen "<none>"), where) == EOF)
4407c478bd9Sstevel@tonic-gate return (-1);
4417c478bd9Sstevel@tonic-gate } else {
4427c478bd9Sstevel@tonic-gate if (fputs(alg->a_names[0], where) == EOF)
4437c478bd9Sstevel@tonic-gate return (-1);
4447c478bd9Sstevel@tonic-gate }
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate freeipsecalgent(alg);
4477c478bd9Sstevel@tonic-gate return (0);
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate
4507c478bd9Sstevel@tonic-gate int
dump_aalg(uint8_t aalg,FILE * where)4517c478bd9Sstevel@tonic-gate dump_aalg(uint8_t aalg, FILE *where)
4527c478bd9Sstevel@tonic-gate {
4537c478bd9Sstevel@tonic-gate return (dump_generic_alg(aalg, IPSEC_PROTO_AH, where));
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate int
dump_ealg(uint8_t ealg,FILE * where)4577c478bd9Sstevel@tonic-gate dump_ealg(uint8_t ealg, FILE *where)
4587c478bd9Sstevel@tonic-gate {
4597c478bd9Sstevel@tonic-gate return (dump_generic_alg(ealg, IPSEC_PROTO_ESP, where));
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate
4627c478bd9Sstevel@tonic-gate /*
4637c478bd9Sstevel@tonic-gate * Print an SADB_IDENTTYPE string
4647c478bd9Sstevel@tonic-gate *
4657c478bd9Sstevel@tonic-gate * Also return TRUE if the actual ident may be printed, FALSE if not.
4667c478bd9Sstevel@tonic-gate *
4677c478bd9Sstevel@tonic-gate * If rc is not NULL, set its value to -1 if an error occured while writing
4687c478bd9Sstevel@tonic-gate * to the specified file, zero otherwise.
4697c478bd9Sstevel@tonic-gate */
4707c478bd9Sstevel@tonic-gate boolean_t
dump_sadb_idtype(uint8_t idtype,FILE * where,int * rc)4717c478bd9Sstevel@tonic-gate dump_sadb_idtype(uint8_t idtype, FILE *where, int *rc)
4727c478bd9Sstevel@tonic-gate {
4737c478bd9Sstevel@tonic-gate boolean_t canprint = B_TRUE;
4747c478bd9Sstevel@tonic-gate int rc_val = 0;
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gate switch (idtype) {
4777c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_PREFIX:
478a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "prefix"), where) == EOF)
4797c478bd9Sstevel@tonic-gate rc_val = -1;
4807c478bd9Sstevel@tonic-gate break;
4817c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_FQDN:
482a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "FQDN"), where) == EOF)
4837c478bd9Sstevel@tonic-gate rc_val = -1;
4847c478bd9Sstevel@tonic-gate break;
4857c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_USER_FQDN:
486a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN,
487a7485808Smarkfen "user-FQDN (mbox)"), where) == EOF)
4887c478bd9Sstevel@tonic-gate rc_val = -1;
4897c478bd9Sstevel@tonic-gate break;
4907c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_DN:
491a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Distinguished Name"),
4927c478bd9Sstevel@tonic-gate where) == EOF)
4937c478bd9Sstevel@tonic-gate rc_val = -1;
4947c478bd9Sstevel@tonic-gate canprint = B_FALSE;
4957c478bd9Sstevel@tonic-gate break;
4967c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_GN:
497a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Generic Name"),
498a7485808Smarkfen where) == EOF)
4997c478bd9Sstevel@tonic-gate rc_val = -1;
5007c478bd9Sstevel@tonic-gate canprint = B_FALSE;
5017c478bd9Sstevel@tonic-gate break;
5027c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_KEY_ID:
503a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Generic key id"),
504a7485808Smarkfen where) == EOF)
5057c478bd9Sstevel@tonic-gate rc_val = -1;
5067c478bd9Sstevel@tonic-gate break;
5077c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_ADDR_RANGE:
508a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Address range"), where) == EOF)
5097c478bd9Sstevel@tonic-gate rc_val = -1;
5107c478bd9Sstevel@tonic-gate break;
5117c478bd9Sstevel@tonic-gate default:
512a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
513a7485808Smarkfen "<unknown %u>"), idtype) < 0)
5147c478bd9Sstevel@tonic-gate rc_val = -1;
5157c478bd9Sstevel@tonic-gate break;
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate if (rc != NULL)
5197c478bd9Sstevel@tonic-gate *rc = rc_val;
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate return (canprint);
5227c478bd9Sstevel@tonic-gate }
5237c478bd9Sstevel@tonic-gate
5247c478bd9Sstevel@tonic-gate /*
5257c478bd9Sstevel@tonic-gate * Slice an argv/argc vector from an interactive line or a read-file line.
5267c478bd9Sstevel@tonic-gate */
5277c478bd9Sstevel@tonic-gate static int
create_argv(char * ibuf,int * newargc,char *** thisargv)5287c478bd9Sstevel@tonic-gate create_argv(char *ibuf, int *newargc, char ***thisargv)
5297c478bd9Sstevel@tonic-gate {
5307c478bd9Sstevel@tonic-gate unsigned int argvlen = START_ARG;
5317c478bd9Sstevel@tonic-gate char **current;
5327c478bd9Sstevel@tonic-gate boolean_t firstchar = B_TRUE;
5337c478bd9Sstevel@tonic-gate boolean_t inquotes = B_FALSE;
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate *thisargv = malloc(sizeof (char *) * argvlen);
5367c478bd9Sstevel@tonic-gate if ((*thisargv) == NULL)
5377c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
5387c478bd9Sstevel@tonic-gate current = *thisargv;
5397c478bd9Sstevel@tonic-gate *current = NULL;
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate for (; *ibuf != '\0'; ibuf++) {
5427c478bd9Sstevel@tonic-gate if (isspace(*ibuf)) {
5437c478bd9Sstevel@tonic-gate if (inquotes) {
5447c478bd9Sstevel@tonic-gate continue;
5457c478bd9Sstevel@tonic-gate }
5467c478bd9Sstevel@tonic-gate if (*current != NULL) {
5477c478bd9Sstevel@tonic-gate *ibuf = '\0';
5487c478bd9Sstevel@tonic-gate current++;
5497c478bd9Sstevel@tonic-gate if (*thisargv + argvlen == current) {
5507c478bd9Sstevel@tonic-gate /* Regrow ***thisargv. */
5517c478bd9Sstevel@tonic-gate if (argvlen == TOO_MANY_ARGS) {
5527c478bd9Sstevel@tonic-gate free(*thisargv);
5537c478bd9Sstevel@tonic-gate return (TOO_MANY_TOKENS);
5547c478bd9Sstevel@tonic-gate }
5557c478bd9Sstevel@tonic-gate /* Double the allocation. */
5567c478bd9Sstevel@tonic-gate current = realloc(*thisargv,
5577c478bd9Sstevel@tonic-gate sizeof (char *) * (argvlen << 1));
5587c478bd9Sstevel@tonic-gate if (current == NULL) {
5597c478bd9Sstevel@tonic-gate free(*thisargv);
5607c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate *thisargv = current;
5637c478bd9Sstevel@tonic-gate current += argvlen;
5647c478bd9Sstevel@tonic-gate argvlen <<= 1; /* Double the size. */
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate *current = NULL;
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate } else {
5697c478bd9Sstevel@tonic-gate if (firstchar) {
5707c478bd9Sstevel@tonic-gate firstchar = B_FALSE;
571e3320f40Smarkfen if (*ibuf == COMMENT_CHAR || *ibuf == '\n') {
5727c478bd9Sstevel@tonic-gate free(*thisargv);
5737c478bd9Sstevel@tonic-gate return (COMMENT_LINE);
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate if (*ibuf == QUOTE_CHAR) {
5777c478bd9Sstevel@tonic-gate if (inquotes) {
5787c478bd9Sstevel@tonic-gate inquotes = B_FALSE;
5797c478bd9Sstevel@tonic-gate *ibuf = '\0';
5807c478bd9Sstevel@tonic-gate } else {
5817c478bd9Sstevel@tonic-gate inquotes = B_TRUE;
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate continue;
5847c478bd9Sstevel@tonic-gate }
5857c478bd9Sstevel@tonic-gate if (*current == NULL) {
5867c478bd9Sstevel@tonic-gate *current = ibuf;
5877c478bd9Sstevel@tonic-gate (*newargc)++;
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate
5927c478bd9Sstevel@tonic-gate /*
5937c478bd9Sstevel@tonic-gate * Tricky corner case...
5947c478bd9Sstevel@tonic-gate * I've parsed _exactly_ the amount of args as I have space. It
5957c478bd9Sstevel@tonic-gate * won't return NULL-terminated, and bad things will happen to
5967c478bd9Sstevel@tonic-gate * the caller.
5977c478bd9Sstevel@tonic-gate */
5987c478bd9Sstevel@tonic-gate if (argvlen == *newargc) {
5997c478bd9Sstevel@tonic-gate current = realloc(*thisargv, sizeof (char *) * (argvlen + 1));
6007c478bd9Sstevel@tonic-gate if (current == NULL) {
6017c478bd9Sstevel@tonic-gate free(*thisargv);
6027c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
6037c478bd9Sstevel@tonic-gate }
6047c478bd9Sstevel@tonic-gate *thisargv = current;
6057c478bd9Sstevel@tonic-gate current[argvlen] = NULL;
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate return (SUCCESS);
6097c478bd9Sstevel@tonic-gate }
6107c478bd9Sstevel@tonic-gate
6117c478bd9Sstevel@tonic-gate /*
612bfe6f8f5SVladimir Kotal * init interactive mode if needed and not yet initialized
613bfe6f8f5SVladimir Kotal */
614bfe6f8f5SVladimir Kotal static void
init_interactive(FILE * infile,CplMatchFn * match_fn)615bfe6f8f5SVladimir Kotal init_interactive(FILE *infile, CplMatchFn *match_fn)
616bfe6f8f5SVladimir Kotal {
617bfe6f8f5SVladimir Kotal if (infile == stdin) {
618bfe6f8f5SVladimir Kotal if (gl == NULL) {
619bfe6f8f5SVladimir Kotal if ((gl = new_GetLine(MAX_LINE_LEN,
620bfe6f8f5SVladimir Kotal MAX_CMD_HIST)) == NULL)
621bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN,
622bfe6f8f5SVladimir Kotal "tecla initialization failed"));
623bfe6f8f5SVladimir Kotal
624bfe6f8f5SVladimir Kotal if (gl_customize_completion(gl, NULL,
625bfe6f8f5SVladimir Kotal match_fn) != 0) {
626bfe6f8f5SVladimir Kotal (void) del_GetLine(gl);
627bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN,
628bfe6f8f5SVladimir Kotal "tab completion failed to initialize"));
629bfe6f8f5SVladimir Kotal }
630bfe6f8f5SVladimir Kotal
631bfe6f8f5SVladimir Kotal /*
632bfe6f8f5SVladimir Kotal * In interactive mode we only want to terminate
633bfe6f8f5SVladimir Kotal * when explicitly requested (e.g. by a command).
634bfe6f8f5SVladimir Kotal */
635bfe6f8f5SVladimir Kotal (void) sigset(SIGINT, SIG_IGN);
636bfe6f8f5SVladimir Kotal }
637bfe6f8f5SVladimir Kotal } else {
638bfe6f8f5SVladimir Kotal readfile = B_TRUE;
639bfe6f8f5SVladimir Kotal }
640bfe6f8f5SVladimir Kotal }
641bfe6f8f5SVladimir Kotal
642bfe6f8f5SVladimir Kotal /*
643bfe6f8f5SVladimir Kotal * free tecla data structure
644bfe6f8f5SVladimir Kotal */
645bfe6f8f5SVladimir Kotal static void
fini_interactive(void)646bfe6f8f5SVladimir Kotal fini_interactive(void)
647bfe6f8f5SVladimir Kotal {
648bfe6f8f5SVladimir Kotal if (gl != NULL)
649bfe6f8f5SVladimir Kotal (void) del_GetLine(gl);
650bfe6f8f5SVladimir Kotal }
651bfe6f8f5SVladimir Kotal
652bfe6f8f5SVladimir Kotal /*
653bfe6f8f5SVladimir Kotal * Get single input line, wrapping around interactive and non-interactive
654bfe6f8f5SVladimir Kotal * mode.
655bfe6f8f5SVladimir Kotal */
656bfe6f8f5SVladimir Kotal static char *
do_getstr(FILE * infile,char * prompt,char * ibuf,size_t ibuf_size)657bfe6f8f5SVladimir Kotal do_getstr(FILE *infile, char *prompt, char *ibuf, size_t ibuf_size)
658bfe6f8f5SVladimir Kotal {
659bfe6f8f5SVladimir Kotal char *line;
660bfe6f8f5SVladimir Kotal
661bfe6f8f5SVladimir Kotal if (infile != stdin)
662bfe6f8f5SVladimir Kotal return (fgets(ibuf, ibuf_size, infile));
663bfe6f8f5SVladimir Kotal
664bfe6f8f5SVladimir Kotal /*
665bfe6f8f5SVladimir Kotal * If the user hits ^C then we want to catch it and
666bfe6f8f5SVladimir Kotal * start over. If the user hits EOF then we want to
667bfe6f8f5SVladimir Kotal * bail out.
668bfe6f8f5SVladimir Kotal */
669bfe6f8f5SVladimir Kotal once_again:
670bfe6f8f5SVladimir Kotal line = gl_get_line(gl, prompt, NULL, -1);
671bfe6f8f5SVladimir Kotal if (gl_return_status(gl) == GLR_SIGNAL) {
672bfe6f8f5SVladimir Kotal gl_abandon_line(gl);
673bfe6f8f5SVladimir Kotal goto once_again;
674bfe6f8f5SVladimir Kotal } else if (gl_return_status(gl) == GLR_ERROR) {
675bfe6f8f5SVladimir Kotal gl_abandon_line(gl);
676bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN, "Error reading terminal: %s\n"),
677bfe6f8f5SVladimir Kotal gl_error_message(gl, NULL, 0));
678bfe6f8f5SVladimir Kotal } else {
679bfe6f8f5SVladimir Kotal if (line != NULL) {
680bfe6f8f5SVladimir Kotal if (strlcpy(ibuf, line, ibuf_size) >= ibuf_size)
681bfe6f8f5SVladimir Kotal warnx(dgettext(TEXT_DOMAIN,
682bfe6f8f5SVladimir Kotal "Line too long (max=%d chars)"),
683bfe6f8f5SVladimir Kotal ibuf_size);
684bfe6f8f5SVladimir Kotal line = ibuf;
685bfe6f8f5SVladimir Kotal }
686bfe6f8f5SVladimir Kotal }
687bfe6f8f5SVladimir Kotal
688bfe6f8f5SVladimir Kotal return (line);
689bfe6f8f5SVladimir Kotal }
690bfe6f8f5SVladimir Kotal
691bfe6f8f5SVladimir Kotal /*
6927c478bd9Sstevel@tonic-gate * Enter a mode where commands are read from a file. Treat stdin special.
6937c478bd9Sstevel@tonic-gate */
6947c478bd9Sstevel@tonic-gate void
do_interactive(FILE * infile,char * configfile,char * promptstring,char * my_fmri,parse_cmdln_fn parseit,CplMatchFn * match_fn)695e3320f40Smarkfen do_interactive(FILE *infile, char *configfile, char *promptstring,
696bfe6f8f5SVladimir Kotal char *my_fmri, parse_cmdln_fn parseit, CplMatchFn *match_fn)
6977c478bd9Sstevel@tonic-gate {
6987c478bd9Sstevel@tonic-gate char ibuf[IBUF_SIZE], holder[IBUF_SIZE];
699e3320f40Smarkfen char *hptr, **thisargv, *ebuf;
7007c478bd9Sstevel@tonic-gate int thisargc;
7017c478bd9Sstevel@tonic-gate boolean_t continue_in_progress = B_FALSE;
702bfe6f8f5SVladimir Kotal char *s;
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate (void) setjmp(env);
7057c478bd9Sstevel@tonic-gate
706e3320f40Smarkfen ebuf = NULL;
7077c478bd9Sstevel@tonic-gate interactive = B_TRUE;
7087c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7097c478bd9Sstevel@tonic-gate
710bfe6f8f5SVladimir Kotal /* panics for us */
711bfe6f8f5SVladimir Kotal init_interactive(infile, match_fn);
7127c478bd9Sstevel@tonic-gate
713bfe6f8f5SVladimir Kotal while ((s = do_getstr(infile, promptstring, ibuf, IBUF_SIZE)) != NULL) {
7147c478bd9Sstevel@tonic-gate if (readfile)
7157c478bd9Sstevel@tonic-gate lineno++;
7167c478bd9Sstevel@tonic-gate thisargc = 0;
7177c478bd9Sstevel@tonic-gate thisargv = NULL;
7187c478bd9Sstevel@tonic-gate
7197c478bd9Sstevel@tonic-gate /*
7207c478bd9Sstevel@tonic-gate * Check byte IBUF_SIZE - 2, because byte IBUF_SIZE - 1 will
7217c478bd9Sstevel@tonic-gate * be null-terminated because of fgets().
7227c478bd9Sstevel@tonic-gate */
7237c478bd9Sstevel@tonic-gate if (ibuf[IBUF_SIZE - 2] != '\0') {
724bfe6f8f5SVladimir Kotal if (infile == stdin) {
725bfe6f8f5SVladimir Kotal /* do_getstr() issued a warning already */
726bfe6f8f5SVladimir Kotal bzero(ibuf, IBUF_SIZE);
727bfe6f8f5SVladimir Kotal continue;
728bfe6f8f5SVladimir Kotal } else {
729bfe6f8f5SVladimir Kotal ipsecutil_exit(SERVICE_FATAL, my_fmri,
730bfe6f8f5SVladimir Kotal debugfile, dgettext(TEXT_DOMAIN,
731bfe6f8f5SVladimir Kotal "Line %d too big."), lineno);
732bfe6f8f5SVladimir Kotal }
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate
7357c478bd9Sstevel@tonic-gate if (!continue_in_progress) {
7367c478bd9Sstevel@tonic-gate /* Use -2 because of \n from fgets. */
7377c478bd9Sstevel@tonic-gate if (ibuf[strlen(ibuf) - 2] == CONT_CHAR) {
7387c478bd9Sstevel@tonic-gate /*
7397c478bd9Sstevel@tonic-gate * Can use strcpy here, I've checked the
7407c478bd9Sstevel@tonic-gate * length already.
7417c478bd9Sstevel@tonic-gate */
7427c478bd9Sstevel@tonic-gate (void) strcpy(holder, ibuf);
7437c478bd9Sstevel@tonic-gate hptr = &(holder[strlen(holder)]);
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */
7467c478bd9Sstevel@tonic-gate hptr[-2] = ' ';
7477c478bd9Sstevel@tonic-gate
7487c478bd9Sstevel@tonic-gate continue_in_progress = B_TRUE;
7497c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7507c478bd9Sstevel@tonic-gate continue;
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate } else {
7537c478bd9Sstevel@tonic-gate /* Handle continuations... */
7547c478bd9Sstevel@tonic-gate (void) strncpy(hptr, ibuf,
7557c478bd9Sstevel@tonic-gate (size_t)(&(holder[IBUF_SIZE]) - hptr));
7567c478bd9Sstevel@tonic-gate if (holder[IBUF_SIZE - 1] != '\0') {
757e3320f40Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri,
758e3320f40Smarkfen debugfile, dgettext(TEXT_DOMAIN,
759e3320f40Smarkfen "Command buffer overrun."));
7607c478bd9Sstevel@tonic-gate }
7617c478bd9Sstevel@tonic-gate /* Use - 2 because of \n from fgets. */
7627c478bd9Sstevel@tonic-gate if (hptr[strlen(hptr) - 2] == CONT_CHAR) {
7637c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7647c478bd9Sstevel@tonic-gate hptr += strlen(hptr);
7657c478bd9Sstevel@tonic-gate
7667c478bd9Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */
7677c478bd9Sstevel@tonic-gate hptr[-2] = ' ';
7687c478bd9Sstevel@tonic-gate
7697c478bd9Sstevel@tonic-gate continue;
7707c478bd9Sstevel@tonic-gate } else {
7717c478bd9Sstevel@tonic-gate continue_in_progress = B_FALSE;
7727c478bd9Sstevel@tonic-gate /*
7737c478bd9Sstevel@tonic-gate * I've already checked the length...
7747c478bd9Sstevel@tonic-gate */
7757c478bd9Sstevel@tonic-gate (void) strcpy(ibuf, holder);
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate }
7787c478bd9Sstevel@tonic-gate
779e3320f40Smarkfen /*
780e3320f40Smarkfen * Just in case the command fails keep a copy of the
781e3320f40Smarkfen * command buffer for diagnostic output.
782e3320f40Smarkfen */
783e3320f40Smarkfen if (readfile) {
784e3320f40Smarkfen /*
785e3320f40Smarkfen * The error buffer needs to be big enough to
786e3320f40Smarkfen * hold the longest command string, plus
787e3320f40Smarkfen * some extra text, see below.
788e3320f40Smarkfen */
789e3320f40Smarkfen ebuf = calloc((IBUF_SIZE * 2), sizeof (char));
790e3320f40Smarkfen if (ebuf == NULL) {
791e3320f40Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri,
792e3320f40Smarkfen debugfile, dgettext(TEXT_DOMAIN,
793e3320f40Smarkfen "Memory allocation error."));
794e3320f40Smarkfen } else {
795e3320f40Smarkfen (void) snprintf(ebuf, (IBUF_SIZE * 2),
796e3320f40Smarkfen dgettext(TEXT_DOMAIN,
797e3320f40Smarkfen "Config file entry near line %u "
798e3320f40Smarkfen "caused error(s) or warnings:\n\n%s\n\n"),
799e3320f40Smarkfen lineno, ibuf);
800e3320f40Smarkfen }
801e3320f40Smarkfen }
802e3320f40Smarkfen
8037c478bd9Sstevel@tonic-gate switch (create_argv(ibuf, &thisargc, &thisargv)) {
8047c478bd9Sstevel@tonic-gate case TOO_MANY_TOKENS:
805e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
806e3320f40Smarkfen dgettext(TEXT_DOMAIN, "Too many input tokens."));
8077c478bd9Sstevel@tonic-gate break;
8087c478bd9Sstevel@tonic-gate case MEMORY_ALLOCATION:
809e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
810e3320f40Smarkfen dgettext(TEXT_DOMAIN, "Memory allocation error."));
8117c478bd9Sstevel@tonic-gate break;
8127c478bd9Sstevel@tonic-gate case COMMENT_LINE:
8137c478bd9Sstevel@tonic-gate /* Comment line. */
814e3320f40Smarkfen free(ebuf);
8157c478bd9Sstevel@tonic-gate break;
8167c478bd9Sstevel@tonic-gate default:
817e3320f40Smarkfen if (thisargc != 0) {
818e3320f40Smarkfen lines_parsed++;
819e3320f40Smarkfen /* ebuf consumed */
82025e435e0Spwernau parseit(thisargc, thisargv, ebuf, readfile);
821e3320f40Smarkfen } else {
822e3320f40Smarkfen free(ebuf);
823e3320f40Smarkfen }
8247c478bd9Sstevel@tonic-gate free(thisargv);
8257c478bd9Sstevel@tonic-gate if (infile == stdin) {
8267c478bd9Sstevel@tonic-gate (void) printf("%s", promptstring);
8277c478bd9Sstevel@tonic-gate (void) fflush(stdout);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate break;
8307c478bd9Sstevel@tonic-gate }
8317c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
8327c478bd9Sstevel@tonic-gate }
83325e435e0Spwernau
83425e435e0Spwernau /*
83525e435e0Spwernau * The following code is ipseckey specific. This should never be
83625e435e0Spwernau * used by ikeadm which also calls this function because ikeadm
83725e435e0Spwernau * only runs interactively. If this ever changes this code block
83825e435e0Spwernau * sould be revisited.
83925e435e0Spwernau */
84025e435e0Spwernau if (readfile) {
84125e435e0Spwernau if (lines_parsed != 0 && lines_added == 0) {
842e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
843e3320f40Smarkfen dgettext(TEXT_DOMAIN, "Configuration file did not "
844e3320f40Smarkfen "contain any valid SAs"));
84525e435e0Spwernau }
846e3320f40Smarkfen
847e3320f40Smarkfen /*
84825e435e0Spwernau * There were errors. Putting the service in maintenance mode.
849e3320f40Smarkfen * When svc.startd(1M) allows services to degrade themselves,
850e3320f40Smarkfen * this should be revisited.
851e3320f40Smarkfen *
852e3320f40Smarkfen * If this function was called from a program running as a
853e3320f40Smarkfen * smf_method(5), print a warning message. Don't spew out the
854e3320f40Smarkfen * errors as these will end up in the smf(5) log file which is
85525e435e0Spwernau * publically readable, the errors may contain sensitive
85625e435e0Spwernau * information.
857e3320f40Smarkfen */
858e3320f40Smarkfen if ((lines_added < lines_parsed) && (configfile != NULL)) {
859e3320f40Smarkfen if (my_fmri != NULL) {
86025e435e0Spwernau ipsecutil_exit(SERVICE_BADCONF, my_fmri,
86125e435e0Spwernau debugfile, dgettext(TEXT_DOMAIN,
86225e435e0Spwernau "The configuration file contained %d "
86325e435e0Spwernau "errors.\n"
864e3320f40Smarkfen "Manually check the configuration with:\n"
865e3320f40Smarkfen "ipseckey -c %s\n"
86625e435e0Spwernau "Use svcadm(1M) to clear maintenance "
86725e435e0Spwernau "condition when errors are resolved.\n"),
868e3320f40Smarkfen lines_parsed - lines_added, configfile);
869e3320f40Smarkfen } else {
870e3320f40Smarkfen EXIT_BADCONFIG(NULL);
871e3320f40Smarkfen }
872e3320f40Smarkfen } else {
873e3320f40Smarkfen if (my_fmri != NULL)
87425e435e0Spwernau ipsecutil_exit(SERVICE_EXIT_OK, my_fmri,
87525e435e0Spwernau debugfile, dgettext(TEXT_DOMAIN,
87625e435e0Spwernau "%d actions successfully processed."),
87725e435e0Spwernau lines_added);
87825e435e0Spwernau }
87925e435e0Spwernau } else {
880bfe6f8f5SVladimir Kotal /* no newline upon Ctrl-D */
881bfe6f8f5SVladimir Kotal if (s != NULL)
88225e435e0Spwernau (void) putchar('\n');
88325e435e0Spwernau (void) fflush(stdout);
884e3320f40Smarkfen }
885bfe6f8f5SVladimir Kotal
886bfe6f8f5SVladimir Kotal fini_interactive();
887bfe6f8f5SVladimir Kotal
888e3320f40Smarkfen EXIT_OK(NULL);
8897c478bd9Sstevel@tonic-gate }
8907c478bd9Sstevel@tonic-gate
8917c478bd9Sstevel@tonic-gate /*
8927c478bd9Sstevel@tonic-gate * Functions to parse strings that represent a debug or privilege level.
8937c478bd9Sstevel@tonic-gate * These functions are copied from main.c and door.c in usr.lib/in.iked/common.
8947c478bd9Sstevel@tonic-gate * If this file evolves into a common library that may be used by in.iked
8957c478bd9Sstevel@tonic-gate * as well as the usr.sbin utilities, those duplicate functions should be
8967c478bd9Sstevel@tonic-gate * deleted.
8977c478bd9Sstevel@tonic-gate *
8987c478bd9Sstevel@tonic-gate * A privilege level may be represented by a simple keyword, corresponding
8997c478bd9Sstevel@tonic-gate * to one of the possible levels. A debug level may be represented by a
9007c478bd9Sstevel@tonic-gate * series of keywords, separated by '+' or '-', indicating categories to
9017c478bd9Sstevel@tonic-gate * be added or removed from the set of categories in the debug level.
9027c478bd9Sstevel@tonic-gate * For example, +all-op corresponds to level 0xfffffffb (all flags except
9037c478bd9Sstevel@tonic-gate * for D_OP set); while p1+p2+pfkey corresponds to level 0x38. Note that
9047c478bd9Sstevel@tonic-gate * the leading '+' is implicit; the first keyword in the list must be for
9057c478bd9Sstevel@tonic-gate * a category that is to be added.
9067c478bd9Sstevel@tonic-gate *
9077c478bd9Sstevel@tonic-gate * These parsing functions make use of a local version of strtok, strtok_d,
9087c478bd9Sstevel@tonic-gate * which includes an additional parameter, char *delim. This param is filled
9097c478bd9Sstevel@tonic-gate * in with the character which ends the returned token. In other words,
9107c478bd9Sstevel@tonic-gate * this version of strtok, in addition to returning the token, also returns
9117c478bd9Sstevel@tonic-gate * the single character delimiter from the original string which marked the
9127c478bd9Sstevel@tonic-gate * end of the token.
9137c478bd9Sstevel@tonic-gate */
9147c478bd9Sstevel@tonic-gate static char *
strtok_d(char * string,const char * sepset,char * delim)9157c478bd9Sstevel@tonic-gate strtok_d(char *string, const char *sepset, char *delim)
9167c478bd9Sstevel@tonic-gate {
9177c478bd9Sstevel@tonic-gate static char *lasts;
9187c478bd9Sstevel@tonic-gate char *q, *r;
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate /* first or subsequent call */
9217c478bd9Sstevel@tonic-gate if (string == NULL)
9227c478bd9Sstevel@tonic-gate string = lasts;
9237c478bd9Sstevel@tonic-gate
9247c478bd9Sstevel@tonic-gate if (string == 0) /* return if no tokens remaining */
9257c478bd9Sstevel@tonic-gate return (NULL);
9267c478bd9Sstevel@tonic-gate
9277c478bd9Sstevel@tonic-gate q = string + strspn(string, sepset); /* skip leading separators */
9287c478bd9Sstevel@tonic-gate
9297c478bd9Sstevel@tonic-gate if (*q == '\0') /* return if no tokens remaining */
9307c478bd9Sstevel@tonic-gate return (NULL);
9317c478bd9Sstevel@tonic-gate
9327c478bd9Sstevel@tonic-gate if ((r = strpbrk(q, sepset)) == NULL) { /* move past token */
9337c478bd9Sstevel@tonic-gate lasts = 0; /* indicate that this is last token */
9347c478bd9Sstevel@tonic-gate } else {
9357c478bd9Sstevel@tonic-gate *delim = *r; /* save delimitor */
9367c478bd9Sstevel@tonic-gate *r = '\0';
9377c478bd9Sstevel@tonic-gate lasts = r + 1;
9387c478bd9Sstevel@tonic-gate }
9397c478bd9Sstevel@tonic-gate return (q);
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate static keywdtab_t privtab[] = {
9437c478bd9Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "base" },
9447c478bd9Sstevel@tonic-gate { IKE_PRIV_MODKEYS, "modkeys" },
9457c478bd9Sstevel@tonic-gate { IKE_PRIV_KEYMAT, "keymat" },
9467c478bd9Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "0" },
9477c478bd9Sstevel@tonic-gate };
9487c478bd9Sstevel@tonic-gate
9497c478bd9Sstevel@tonic-gate int
privstr2num(char * str)9507c478bd9Sstevel@tonic-gate privstr2num(char *str)
9517c478bd9Sstevel@tonic-gate {
9527c478bd9Sstevel@tonic-gate keywdtab_t *pp;
9537c478bd9Sstevel@tonic-gate char *endp;
9547c478bd9Sstevel@tonic-gate int priv;
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate for (pp = privtab; pp < A_END(privtab); pp++) {
9577c478bd9Sstevel@tonic-gate if (strcasecmp(str, pp->kw_str) == 0)
9587c478bd9Sstevel@tonic-gate return (pp->kw_tag);
9597c478bd9Sstevel@tonic-gate }
9607c478bd9Sstevel@tonic-gate
9617c478bd9Sstevel@tonic-gate priv = strtol(str, &endp, 0);
9627c478bd9Sstevel@tonic-gate if (*endp == '\0')
9637c478bd9Sstevel@tonic-gate return (priv);
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate return (-1);
9667c478bd9Sstevel@tonic-gate }
9677c478bd9Sstevel@tonic-gate
9687c478bd9Sstevel@tonic-gate static keywdtab_t dbgtab[] = {
9697c478bd9Sstevel@tonic-gate { D_CERT, "cert" },
9707c478bd9Sstevel@tonic-gate { D_KEY, "key" },
9717c478bd9Sstevel@tonic-gate { D_OP, "op" },
9727c478bd9Sstevel@tonic-gate { D_P1, "p1" },
9737c478bd9Sstevel@tonic-gate { D_P1, "phase1" },
9747c478bd9Sstevel@tonic-gate { D_P2, "p2" },
9757c478bd9Sstevel@tonic-gate { D_P2, "phase2" },
9767c478bd9Sstevel@tonic-gate { D_PFKEY, "pfkey" },
9777c478bd9Sstevel@tonic-gate { D_POL, "pol" },
9787c478bd9Sstevel@tonic-gate { D_POL, "policy" },
9797c478bd9Sstevel@tonic-gate { D_PROP, "prop" },
9807c478bd9Sstevel@tonic-gate { D_DOOR, "door" },
9817c478bd9Sstevel@tonic-gate { D_CONFIG, "config" },
9825d3b8cb7SBill Sommerfeld { D_LABEL, "label" },
9837c478bd9Sstevel@tonic-gate { D_ALL, "all" },
9847c478bd9Sstevel@tonic-gate { 0, "0" },
9857c478bd9Sstevel@tonic-gate };
9867c478bd9Sstevel@tonic-gate
9877c478bd9Sstevel@tonic-gate int
dbgstr2num(char * str)9887c478bd9Sstevel@tonic-gate dbgstr2num(char *str)
9897c478bd9Sstevel@tonic-gate {
9907c478bd9Sstevel@tonic-gate keywdtab_t *dp;
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate for (dp = dbgtab; dp < A_END(dbgtab); dp++) {
9937c478bd9Sstevel@tonic-gate if (strcasecmp(str, dp->kw_str) == 0)
9947c478bd9Sstevel@tonic-gate return (dp->kw_tag);
9957c478bd9Sstevel@tonic-gate }
9967c478bd9Sstevel@tonic-gate return (D_INVALID);
9977c478bd9Sstevel@tonic-gate }
9987c478bd9Sstevel@tonic-gate
9997c478bd9Sstevel@tonic-gate int
parsedbgopts(char * optarg)10007c478bd9Sstevel@tonic-gate parsedbgopts(char *optarg)
10017c478bd9Sstevel@tonic-gate {
10027c478bd9Sstevel@tonic-gate char *argp, *endp, op, nextop;
10037c478bd9Sstevel@tonic-gate int mask = 0, new;
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate mask = strtol(optarg, &endp, 0);
10067c478bd9Sstevel@tonic-gate if (*endp == '\0')
10077c478bd9Sstevel@tonic-gate return (mask);
10087c478bd9Sstevel@tonic-gate
10097c478bd9Sstevel@tonic-gate op = optarg[0];
10107c478bd9Sstevel@tonic-gate if (op != '-')
10117c478bd9Sstevel@tonic-gate op = '+';
10127c478bd9Sstevel@tonic-gate argp = strtok_d(optarg, "+-", &nextop);
10137c478bd9Sstevel@tonic-gate do {
10147c478bd9Sstevel@tonic-gate new = dbgstr2num(argp);
10157c478bd9Sstevel@tonic-gate if (new == D_INVALID) {
10167c478bd9Sstevel@tonic-gate /* we encountered an invalid keywd */
10177c478bd9Sstevel@tonic-gate return (new);
10187c478bd9Sstevel@tonic-gate }
10197c478bd9Sstevel@tonic-gate if (op == '+') {
10207c478bd9Sstevel@tonic-gate mask |= new;
10217c478bd9Sstevel@tonic-gate } else {
10227c478bd9Sstevel@tonic-gate mask &= ~new;
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate op = nextop;
10257c478bd9Sstevel@tonic-gate } while ((argp = strtok_d(NULL, "+-", &nextop)) != NULL);
10267c478bd9Sstevel@tonic-gate
10277c478bd9Sstevel@tonic-gate return (mask);
10287c478bd9Sstevel@tonic-gate }
10297c478bd9Sstevel@tonic-gate
10307c478bd9Sstevel@tonic-gate
10317c478bd9Sstevel@tonic-gate /*
10327c478bd9Sstevel@tonic-gate * functions to manipulate the kmcookie-label mapping file
10337c478bd9Sstevel@tonic-gate */
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate /*
10367c478bd9Sstevel@tonic-gate * Open, lockf, fdopen the given file, returning a FILE * on success,
10377c478bd9Sstevel@tonic-gate * or NULL on failure.
10387c478bd9Sstevel@tonic-gate */
10397c478bd9Sstevel@tonic-gate FILE *
kmc_open_and_lock(char * name)10407c478bd9Sstevel@tonic-gate kmc_open_and_lock(char *name)
10417c478bd9Sstevel@tonic-gate {
10427c478bd9Sstevel@tonic-gate int fd, rtnerr;
10437c478bd9Sstevel@tonic-gate FILE *fp;
10447c478bd9Sstevel@tonic-gate
10457c478bd9Sstevel@tonic-gate if ((fd = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
10467c478bd9Sstevel@tonic-gate return (NULL);
10477c478bd9Sstevel@tonic-gate }
10487c478bd9Sstevel@tonic-gate if (lockf(fd, F_LOCK, 0) < 0) {
10497c478bd9Sstevel@tonic-gate return (NULL);
10507c478bd9Sstevel@tonic-gate }
10517c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "a+")) == NULL) {
10527c478bd9Sstevel@tonic-gate return (NULL);
10537c478bd9Sstevel@tonic-gate }
10547c478bd9Sstevel@tonic-gate if (fseek(fp, 0, SEEK_SET) < 0) {
10557c478bd9Sstevel@tonic-gate /* save errno in case fclose changes it */
10567c478bd9Sstevel@tonic-gate rtnerr = errno;
10577c478bd9Sstevel@tonic-gate (void) fclose(fp);
10587c478bd9Sstevel@tonic-gate errno = rtnerr;
10597c478bd9Sstevel@tonic-gate return (NULL);
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate return (fp);
10627c478bd9Sstevel@tonic-gate }
10637c478bd9Sstevel@tonic-gate
10647c478bd9Sstevel@tonic-gate /*
10657c478bd9Sstevel@tonic-gate * Extract an integer cookie and string label from a line from the
10667c478bd9Sstevel@tonic-gate * kmcookie-label file. Return -1 on failure, 0 on success.
10677c478bd9Sstevel@tonic-gate */
10687c478bd9Sstevel@tonic-gate int
kmc_parse_line(char * line,int * cookie,char ** label)10697c478bd9Sstevel@tonic-gate kmc_parse_line(char *line, int *cookie, char **label)
10707c478bd9Sstevel@tonic-gate {
10717c478bd9Sstevel@tonic-gate char *cookiestr;
10727c478bd9Sstevel@tonic-gate
10737c478bd9Sstevel@tonic-gate *cookie = 0;
10747c478bd9Sstevel@tonic-gate *label = NULL;
10757c478bd9Sstevel@tonic-gate
10767c478bd9Sstevel@tonic-gate cookiestr = strtok(line, " \t\n");
10777c478bd9Sstevel@tonic-gate if (cookiestr == NULL) {
10787c478bd9Sstevel@tonic-gate return (-1);
10797c478bd9Sstevel@tonic-gate }
10807c478bd9Sstevel@tonic-gate
10817c478bd9Sstevel@tonic-gate /* Everything that follows, up to the newline, is the label. */
10827c478bd9Sstevel@tonic-gate *label = strtok(NULL, "\n");
10837c478bd9Sstevel@tonic-gate if (*label == NULL) {
10847c478bd9Sstevel@tonic-gate return (-1);
10857c478bd9Sstevel@tonic-gate }
10867c478bd9Sstevel@tonic-gate
10877c478bd9Sstevel@tonic-gate *cookie = atoi(cookiestr);
10887c478bd9Sstevel@tonic-gate return (0);
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate /*
10927c478bd9Sstevel@tonic-gate * Insert a mapping into the file (if it's not already there), given the
10937c478bd9Sstevel@tonic-gate * new label. Return the assigned cookie, or -1 on error.
10947c478bd9Sstevel@tonic-gate */
10957c478bd9Sstevel@tonic-gate int
kmc_insert_mapping(char * label)10967c478bd9Sstevel@tonic-gate kmc_insert_mapping(char *label)
10977c478bd9Sstevel@tonic-gate {
10987c478bd9Sstevel@tonic-gate FILE *map;
1099c99ab7ceSdanmcd char linebuf[IBUF_SIZE];
11007c478bd9Sstevel@tonic-gate char *cur_label;
11017c478bd9Sstevel@tonic-gate int max_cookie = 0, cur_cookie, rtn_cookie;
11027c478bd9Sstevel@tonic-gate int rtnerr = 0;
11037c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE;
11047c478bd9Sstevel@tonic-gate
11057c478bd9Sstevel@tonic-gate /* open and lock the file; will sleep until lock is available */
11067c478bd9Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) {
11077c478bd9Sstevel@tonic-gate /* kmc_open_and_lock() sets errno appropriately */
11087c478bd9Sstevel@tonic-gate return (-1);
11097c478bd9Sstevel@tonic-gate }
11107c478bd9Sstevel@tonic-gate
11117c478bd9Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) {
11127c478bd9Sstevel@tonic-gate
1113c99ab7ceSdanmcd /* Skip blank lines, which often come near EOF. */
1114c99ab7ceSdanmcd if (strlen(linebuf) == 0)
1115c99ab7ceSdanmcd continue;
1116c99ab7ceSdanmcd
11177c478bd9Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) {
11187c478bd9Sstevel@tonic-gate rtnerr = EINVAL;
11197c478bd9Sstevel@tonic-gate goto error;
11207c478bd9Sstevel@tonic-gate }
11217c478bd9Sstevel@tonic-gate
11227c478bd9Sstevel@tonic-gate if (cur_cookie > max_cookie)
11237c478bd9Sstevel@tonic-gate max_cookie = cur_cookie;
11247c478bd9Sstevel@tonic-gate
11257c478bd9Sstevel@tonic-gate if ((!found) && (strcmp(cur_label, label) == 0)) {
11267c478bd9Sstevel@tonic-gate found = B_TRUE;
11277c478bd9Sstevel@tonic-gate rtn_cookie = cur_cookie;
11287c478bd9Sstevel@tonic-gate }
11297c478bd9Sstevel@tonic-gate }
11307c478bd9Sstevel@tonic-gate
11317c478bd9Sstevel@tonic-gate if (!found) {
11327c478bd9Sstevel@tonic-gate rtn_cookie = ++max_cookie;
11337c478bd9Sstevel@tonic-gate if ((fprintf(map, "%u\t%s\n", rtn_cookie, label) < 0) ||
11347c478bd9Sstevel@tonic-gate (fflush(map) < 0)) {
11357c478bd9Sstevel@tonic-gate rtnerr = errno;
11367c478bd9Sstevel@tonic-gate goto error;
11377c478bd9Sstevel@tonic-gate }
11387c478bd9Sstevel@tonic-gate }
11397c478bd9Sstevel@tonic-gate (void) fclose(map);
11407c478bd9Sstevel@tonic-gate
11417c478bd9Sstevel@tonic-gate return (rtn_cookie);
11427c478bd9Sstevel@tonic-gate
11437c478bd9Sstevel@tonic-gate error:
11447c478bd9Sstevel@tonic-gate (void) fclose(map);
11457c478bd9Sstevel@tonic-gate errno = rtnerr;
11467c478bd9Sstevel@tonic-gate return (-1);
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate
11497c478bd9Sstevel@tonic-gate /*
11507c478bd9Sstevel@tonic-gate * Lookup the given cookie and return its corresponding label. Return
11517c478bd9Sstevel@tonic-gate * a pointer to the label on success, NULL on error (or if the label is
11527c478bd9Sstevel@tonic-gate * not found). Note that the returned label pointer points to a static
11537c478bd9Sstevel@tonic-gate * string, so the label will be overwritten by a subsequent call to the
11547c478bd9Sstevel@tonic-gate * function; the function is also not thread-safe as a result.
11557c478bd9Sstevel@tonic-gate */
11567c478bd9Sstevel@tonic-gate char *
kmc_lookup_by_cookie(int cookie)11577c478bd9Sstevel@tonic-gate kmc_lookup_by_cookie(int cookie)
11587c478bd9Sstevel@tonic-gate {
11597c478bd9Sstevel@tonic-gate FILE *map;
1160c99ab7ceSdanmcd static char linebuf[IBUF_SIZE];
11617c478bd9Sstevel@tonic-gate char *cur_label;
11627c478bd9Sstevel@tonic-gate int cur_cookie;
11637c478bd9Sstevel@tonic-gate
11647c478bd9Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) {
11657c478bd9Sstevel@tonic-gate return (NULL);
11667c478bd9Sstevel@tonic-gate }
11677c478bd9Sstevel@tonic-gate
11687c478bd9Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) {
11697c478bd9Sstevel@tonic-gate
11707c478bd9Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) {
11717c478bd9Sstevel@tonic-gate (void) fclose(map);
11727c478bd9Sstevel@tonic-gate return (NULL);
11737c478bd9Sstevel@tonic-gate }
11747c478bd9Sstevel@tonic-gate
11757c478bd9Sstevel@tonic-gate if (cookie == cur_cookie) {
11767c478bd9Sstevel@tonic-gate (void) fclose(map);
11777c478bd9Sstevel@tonic-gate return (cur_label);
11787c478bd9Sstevel@tonic-gate }
11797c478bd9Sstevel@tonic-gate }
11807c478bd9Sstevel@tonic-gate (void) fclose(map);
11817c478bd9Sstevel@tonic-gate
11827c478bd9Sstevel@tonic-gate return (NULL);
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate
11857c478bd9Sstevel@tonic-gate /*
11867c478bd9Sstevel@tonic-gate * Parse basic extension headers and return in the passed-in pointer vector.
11877c478bd9Sstevel@tonic-gate * Return values include:
11887c478bd9Sstevel@tonic-gate *
11897c478bd9Sstevel@tonic-gate * KGE_OK Everything's nice and parsed out.
11907c478bd9Sstevel@tonic-gate * If there are no extensions, place NULL in extv[0].
11917c478bd9Sstevel@tonic-gate * KGE_DUP There is a duplicate extension.
11927c478bd9Sstevel@tonic-gate * First instance in appropriate bin. First duplicate in
11937c478bd9Sstevel@tonic-gate * extv[0].
11947c478bd9Sstevel@tonic-gate * KGE_UNK Unknown extension type encountered. extv[0] contains
11957c478bd9Sstevel@tonic-gate * unknown header.
11967c478bd9Sstevel@tonic-gate * KGE_LEN Extension length error.
11977c478bd9Sstevel@tonic-gate * KGE_CHK High-level reality check failed on specific extension.
11987c478bd9Sstevel@tonic-gate *
11997c478bd9Sstevel@tonic-gate * My apologies for some of the pointer arithmetic in here. I'm thinking
12007c478bd9Sstevel@tonic-gate * like an assembly programmer, yet trying to make the compiler happy.
12017c478bd9Sstevel@tonic-gate */
12027c478bd9Sstevel@tonic-gate int
spdsock_get_ext(spd_ext_t * extv[],spd_msg_t * basehdr,uint_t msgsize,char * diag_buf,uint_t diag_buf_len)12037c478bd9Sstevel@tonic-gate spdsock_get_ext(spd_ext_t *extv[], spd_msg_t *basehdr, uint_t msgsize,
12047c478bd9Sstevel@tonic-gate char *diag_buf, uint_t diag_buf_len)
12057c478bd9Sstevel@tonic-gate {
12067c478bd9Sstevel@tonic-gate int i;
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate if (diag_buf != NULL)
12097c478bd9Sstevel@tonic-gate diag_buf[0] = '\0';
12107c478bd9Sstevel@tonic-gate
12117c478bd9Sstevel@tonic-gate for (i = 1; i <= SPD_EXT_MAX; i++)
12127c478bd9Sstevel@tonic-gate extv[i] = NULL;
12137c478bd9Sstevel@tonic-gate
12147c478bd9Sstevel@tonic-gate i = 0;
12157c478bd9Sstevel@tonic-gate /* Use extv[0] as the "current working pointer". */
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate extv[0] = (spd_ext_t *)(basehdr + 1);
12187c478bd9Sstevel@tonic-gate msgsize = SPD_64TO8(msgsize);
12197c478bd9Sstevel@tonic-gate
12207c478bd9Sstevel@tonic-gate while ((char *)extv[0] < ((char *)basehdr + msgsize)) {
12217c478bd9Sstevel@tonic-gate /* Check for unknown headers. */
12227c478bd9Sstevel@tonic-gate i++;
12237c478bd9Sstevel@tonic-gate if (extv[0]->spd_ext_type == 0 ||
12247c478bd9Sstevel@tonic-gate extv[0]->spd_ext_type > SPD_EXT_MAX) {
12257c478bd9Sstevel@tonic-gate if (diag_buf != NULL) {
12267c478bd9Sstevel@tonic-gate (void) snprintf(diag_buf, diag_buf_len,
12277c478bd9Sstevel@tonic-gate "spdsock ext 0x%X unknown: 0x%X",
12287c478bd9Sstevel@tonic-gate i, extv[0]->spd_ext_type);
12297c478bd9Sstevel@tonic-gate }
12307c478bd9Sstevel@tonic-gate return (KGE_UNK);
12317c478bd9Sstevel@tonic-gate }
12327c478bd9Sstevel@tonic-gate
12337c478bd9Sstevel@tonic-gate /*
12347c478bd9Sstevel@tonic-gate * Check length. Use uint64_t because extlen is in units
12357c478bd9Sstevel@tonic-gate * of 64-bit words. If length goes beyond the msgsize,
12367c478bd9Sstevel@tonic-gate * return an error. (Zero length also qualifies here.)
12377c478bd9Sstevel@tonic-gate */
12387c478bd9Sstevel@tonic-gate if (extv[0]->spd_ext_len == 0 ||
12397c478bd9Sstevel@tonic-gate (uint8_t *)((uint64_t *)extv[0] + extv[0]->spd_ext_len) >
12407c478bd9Sstevel@tonic-gate (uint8_t *)((uint8_t *)basehdr + msgsize))
12417c478bd9Sstevel@tonic-gate return (KGE_LEN);
12427c478bd9Sstevel@tonic-gate
12437c478bd9Sstevel@tonic-gate /* Check for redundant headers. */
12447c478bd9Sstevel@tonic-gate if (extv[extv[0]->spd_ext_type] != NULL)
12457c478bd9Sstevel@tonic-gate return (KGE_DUP);
12467c478bd9Sstevel@tonic-gate
12477c478bd9Sstevel@tonic-gate /* If I make it here, assign the appropriate bin. */
12487c478bd9Sstevel@tonic-gate extv[extv[0]->spd_ext_type] = extv[0];
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate /* Advance pointer (See above for uint64_t ptr reasoning.) */
12517c478bd9Sstevel@tonic-gate extv[0] = (spd_ext_t *)
12527c478bd9Sstevel@tonic-gate ((uint64_t *)extv[0] + extv[0]->spd_ext_len);
12537c478bd9Sstevel@tonic-gate }
12547c478bd9Sstevel@tonic-gate
12557c478bd9Sstevel@tonic-gate /* Everything's cool. */
12567c478bd9Sstevel@tonic-gate
12577c478bd9Sstevel@tonic-gate /*
12587c478bd9Sstevel@tonic-gate * If extv[0] == NULL, then there are no extension headers in this
12597c478bd9Sstevel@tonic-gate * message. Ensure that this is the case.
12607c478bd9Sstevel@tonic-gate */
12617c478bd9Sstevel@tonic-gate if (extv[0] == (spd_ext_t *)(basehdr + 1))
12627c478bd9Sstevel@tonic-gate extv[0] = NULL;
12637c478bd9Sstevel@tonic-gate
12647c478bd9Sstevel@tonic-gate return (KGE_OK);
12657c478bd9Sstevel@tonic-gate }
12667c478bd9Sstevel@tonic-gate
12677c478bd9Sstevel@tonic-gate const char *
spdsock_diag(int diagnostic)12687c478bd9Sstevel@tonic-gate spdsock_diag(int diagnostic)
12697c478bd9Sstevel@tonic-gate {
12707c478bd9Sstevel@tonic-gate switch (diagnostic) {
12717c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NONE:
1272a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "no error"));
12737c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNKNOWN_EXT:
1274a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unknown extension"));
12757c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_EXTLEN:
1276a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad extension length"));
12777c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_RULE_EXT:
1278a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "no rule extension"));
12797c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_ADDR_LEN:
1280a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad address len"));
12817c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MIXED_AF:
1282a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "mixed address family"));
12837c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_NO_MEM:
1284a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: no memory"));
12857c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT:
1286a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: wrong action count"));
12877c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_TYPE:
1288a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad type"));
12897c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_FLAGS:
1290a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad flags"));
12917c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_INCON_FLAGS:
1292a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: inconsistent flags"));
12937c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLPORT:
1294a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local port"));
12957c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLPORT:
1296a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local port"));
12977c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMPORT:
1298a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote port"));
12997c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMPORT:
1300a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote port"));
13017c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_PROTO:
1302a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed proto"));
13037c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_PROTO:
1304a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate proto"));
13057c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLADDR:
1306a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local address"));
13077c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLADDR:
1308a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local address"));
13097c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMADDR:
1310a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote address"));
13117c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMADDR:
1312a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote address"));
13137c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_ACTION:
1314a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed action"));
13157c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_ACTION:
1316a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate action"));
13177c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULE:
1318a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed rule"));
13197c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULE:
1320a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate rule"));
13217c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULESET:
1322a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed ruleset"));
13237c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULESET:
1324a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate ruleset"));
13257c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_INVALID_RULE_INDEX:
1326a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid rule index"));
13277c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_SPDID:
1328a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad spdid"));
13297c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_MSG_TYPE:
1330a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad message type"));
13317c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_ALG:
1332a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH algorithm"));
13337c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG:
1334a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1335a7485808Smarkfen "unsupported ESP encryption algorithm"));
13367c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG:
1337a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1338a7485808Smarkfen "unsupported ESP authentication algorithm"));
13397c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE:
1340a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH key size"));
13417c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE:
1342a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1343a7485808Smarkfen "unsupported ESP encryption key size"));
13447c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE:
1345a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1346a7485808Smarkfen "unsupported ESP authentication key size"));
13477c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_ACTION_EXT:
1348a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "No ACTION extension"));
13497c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_ID_RANGE:
1350a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid algorithm identifer"));
13517c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES:
1352a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1353a7485808Smarkfen "number of key sizes inconsistent"));
13547c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES:
1355a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1356a7485808Smarkfen "number of block sizes inconsistent"));
13577c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN:
1358a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid mechanism name length"));
13598810c16bSdanmcd case SPD_DIAGNOSTIC_NOT_GLOBAL_OP:
1360a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1361a7485808Smarkfen "operation not applicable to all policies"));
13628810c16bSdanmcd case SPD_DIAGNOSTIC_NO_TUNNEL_SELECTORS:
1363a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1364a7485808Smarkfen "using selectors on a transport-mode tunnel"));
13657c478bd9Sstevel@tonic-gate default:
1366a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unknown diagnostic"));
13677c478bd9Sstevel@tonic-gate }
13687c478bd9Sstevel@tonic-gate }
13697c478bd9Sstevel@tonic-gate
13707c478bd9Sstevel@tonic-gate /*
13717c478bd9Sstevel@tonic-gate * PF_KEY Diagnostic table.
13727c478bd9Sstevel@tonic-gate *
13737c478bd9Sstevel@tonic-gate * PF_KEY NOTE: If you change pfkeyv2.h's SADB_X_DIAGNOSTIC_* space, this is
13747c478bd9Sstevel@tonic-gate * where you need to add new messages.
13757c478bd9Sstevel@tonic-gate */
13767c478bd9Sstevel@tonic-gate
13777c478bd9Sstevel@tonic-gate const char *
keysock_diag(int diagnostic)13787c478bd9Sstevel@tonic-gate keysock_diag(int diagnostic)
13797c478bd9Sstevel@tonic-gate {
13807c478bd9Sstevel@tonic-gate switch (diagnostic) {
13817c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NONE:
1382a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "No diagnostic"));
13837c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_MSG:
1384a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown message type"));
13857c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_EXT:
1386a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown extension type"));
13877c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EXTLEN:
1388a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad extension length"));
13897c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_SATYPE:
1390a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1391a7485808Smarkfen "Unknown Security Association type"));
13927c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SATYPE_NEEDED:
1393a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1394a7485808Smarkfen "Specific Security Association type needed"));
13957c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_SADBS:
1396a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1397a7485808Smarkfen "No Security Association Databases present"));
13987c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_EXT:
1399a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1400a7485808Smarkfen "No extensions needed for message"));
14017c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC_AF:
1402a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address family"));
14037c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST_AF:
1404a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1405a7485808Smarkfen "Bad destination address family"));
14067c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_PROXY_AF:
1407a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1408a7485808Smarkfen "Bad inner-source address family"));
14097c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AF_MISMATCH:
1410a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1411a7485808Smarkfen "Source/destination address family mismatch"));
14127c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC:
1413a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address value"));
14147c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST:
1415a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad destination address value"));
14167c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ALLOC_HSERR:
1417a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1418a7485808Smarkfen "Soft allocations limit more than hard limit"));
14197c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BYTES_HSERR:
1420a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1421a7485808Smarkfen "Soft bytes limit more than hard limit"));
14227c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ADDTIME_HSERR:
1423a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Soft add expiration time later "
14247c478bd9Sstevel@tonic-gate "than hard expiration time"));
14257c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_USETIME_HSERR:
1426a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Soft use expiration time later "
14277c478bd9Sstevel@tonic-gate "than hard expiration time"));
14287c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SRC:
1429a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing source address"));
14307c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_DST:
1431a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing destination address"));
14327c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SA:
1433a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SA extension"));
14347c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_EKEY:
1435a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing encryption key"));
14367c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_AKEY:
1437a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing authentication key"));
14387c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_RANGE:
1439a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SPI range"));
14407c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SRC:
1441a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate source address"));
14427c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_DST:
1443a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate destination address"));
14447c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SA:
1445a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SA extension"));
14467c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_EKEY:
1447a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate encryption key"));
14487c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_AKEY:
1449a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate authentication key"));
14507c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_RANGE:
1451a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SPI range"));
14527c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SRC:
1453a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed source address"));
14547c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_DST:
1455a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed destination address"));
14567c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SA:
1457a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SA extension"));
14587c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_EKEY:
1459a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed encryption key"));
14607c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_AKEY:
1461a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed authentication key"));
14627c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_RANGE:
1463a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SPI range"));
14647c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AKEY_PRESENT:
1465a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Authentication key not needed"));
14667c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_EKEY_PRESENT:
1467a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Encryption key not needed"));
14687c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_PROP_PRESENT:
1469a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Proposal extension not needed"));
14707c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SUPP_PRESENT:
1471a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1472a7485808Smarkfen "Supported algorithms extension not needed"));
14737c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AALG:
1474a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1475a7485808Smarkfen "Unsupported authentication algorithm"));
14767c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EALG:
1477a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1478a7485808Smarkfen "Unsupported encryption algorithm"));
14797c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SAFLAGS:
1480a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA flags"));
14817c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SASTATE:
1482a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA state"));
14837c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AKEYBITS:
1484a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1485a7485808Smarkfen "Bad number of authentication bits"));
14867c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EKEYBITS:
1487a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1488a7485808Smarkfen "Bad number of encryption bits"));
14897c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ENCR_NOTSUPP:
1490a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1491a7485808Smarkfen "Encryption not supported for this SA type"));
14927c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_EKEY:
1493a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Weak encryption key"));
14947c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_AKEY:
1495a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Weak authentication key"));
14967c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMP:
1497a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1498a7485808Smarkfen "Duplicate key management protocol"));
14997c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMC:
1500a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1501a7485808Smarkfen "Duplicate key management cookie"));
15027c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_LOC:
1503a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T local address"));
15047c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_REM:
1505a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T remote address"));
15067c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_LOC:
1507a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T local address"));
15087c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_REM:
1509a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1510a7485808Smarkfen "Duplicate NAT-T remote address"));
15117c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC:
1512a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed NAT-T local address"));
15137c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM:
1514a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1515a7485808Smarkfen "Malformed NAT-T remote address"));
15167c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_PORTS:
1517a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T ports"));
15188810c16bSdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_SRC:
1519a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing inner source address"));
15208810c16bSdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_DST:
1521a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1522a7485808Smarkfen "Missing inner destination address"));
15238810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_SRC:
1524a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1525a7485808Smarkfen "Duplicate inner source address"));
15268810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_DST:
1527a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1528a7485808Smarkfen "Duplicate inner destination address"));
15298810c16bSdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC:
1530a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1531a7485808Smarkfen "Malformed inner source address"));
15328810c16bSdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST:
1533a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1534a7485808Smarkfen "Malformed inner destination address"));
15358810c16bSdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC:
1536a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1537a7485808Smarkfen "Invalid inner-source prefix length "));
15388810c16bSdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_DST:
1539a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1540a7485808Smarkfen "Invalid inner-destination prefix length"));
15418810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF:
1542a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1543a7485808Smarkfen "Bad inner-destination address family"));
15448810c16bSdanmcd case SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH:
1545a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
15468810c16bSdanmcd "Inner source/destination address family mismatch"));
15478810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF:
1548a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1549a7485808Smarkfen "Bad NAT-T remote address family"));
15508810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF:
1551a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1552a7485808Smarkfen "Bad NAT-T local address family"));
15538810c16bSdanmcd case SADB_X_DIAGNOSTIC_PROTO_MISMATCH:
1554a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1555a7485808Smarkfen "Source/desination protocol mismatch"));
15568810c16bSdanmcd case SADB_X_DIAGNOSTIC_INNER_PROTO_MISMATCH:
1557a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1558a7485808Smarkfen "Inner source/desination protocol mismatch"));
15598810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUAL_PORT_SETS:
1560a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1561a7485808Smarkfen "Both inner ports and outer ports are set"));
156238d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE:
156338d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
156438d95a78Smarkfen "Pairing failed, target SA unsuitable for pairing"));
156538d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ADD_MISMATCH:
156638d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
156738d95a78Smarkfen "Source/destination address differs from pair SA"));
156838d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ALREADY:
156938d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157038d95a78Smarkfen "Already paired with another security association"));
157138d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND:
157238d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157338d95a78Smarkfen "Command failed, pair security association not found"));
157438d95a78Smarkfen case SADB_X_DIAGNOSTIC_BAD_SA_DIRECTION:
157538d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157638d95a78Smarkfen "Inappropriate SA direction"));
157738d95a78Smarkfen case SADB_X_DIAGNOSTIC_SA_NOTFOUND:
157838d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157938d95a78Smarkfen "Security association not found"));
158038d95a78Smarkfen case SADB_X_DIAGNOSTIC_SA_EXPIRED:
158138d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
158238d95a78Smarkfen "Security association is not valid"));
1583a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_BAD_CTX:
1584a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1585a1ba8781SMark Fenwick "Algorithm invalid or not supported by Crypto Framework"));
1586a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_INVALID_REPLAY:
1587a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1588a1ba8781SMark Fenwick "Invalid Replay counter"));
1589a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_MISSING_LIFETIME:
1590a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1591a1ba8781SMark Fenwick "Inappropriate lifetimes"));
15927c478bd9Sstevel@tonic-gate default:
1593a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown diagnostic code"));
15947c478bd9Sstevel@tonic-gate }
15957c478bd9Sstevel@tonic-gate }
15968810c16bSdanmcd
15978810c16bSdanmcd /*
15988810c16bSdanmcd * Convert an IPv6 mask to a prefix len. I assume all IPv6 masks are
15998810c16bSdanmcd * contiguous, so I stop at the first zero bit!
16008810c16bSdanmcd */
16018810c16bSdanmcd int
in_masktoprefix(uint8_t * mask,boolean_t is_v4mapped)16028810c16bSdanmcd in_masktoprefix(uint8_t *mask, boolean_t is_v4mapped)
16038810c16bSdanmcd {
16048810c16bSdanmcd int rc = 0;
16058810c16bSdanmcd uint8_t last;
16068810c16bSdanmcd int limit = IPV6_ABITS;
16078810c16bSdanmcd
16088810c16bSdanmcd if (is_v4mapped) {
16098810c16bSdanmcd mask += ((IPV6_ABITS - IP_ABITS)/8);
16108810c16bSdanmcd limit = IP_ABITS;
16118810c16bSdanmcd }
16128810c16bSdanmcd
16138810c16bSdanmcd while (*mask == 0xff) {
16148810c16bSdanmcd rc += 8;
16158810c16bSdanmcd if (rc == limit)
16168810c16bSdanmcd return (limit);
16178810c16bSdanmcd mask++;
16188810c16bSdanmcd }
16198810c16bSdanmcd
16208810c16bSdanmcd last = *mask;
16218810c16bSdanmcd while (last != 0) {
16228810c16bSdanmcd rc++;
16238810c16bSdanmcd last = (last << 1) & 0xff;
16248810c16bSdanmcd }
16258810c16bSdanmcd
16268810c16bSdanmcd return (rc);
16278810c16bSdanmcd }
16288810c16bSdanmcd
16298810c16bSdanmcd /*
16308810c16bSdanmcd * Expand the diagnostic code into a message.
16318810c16bSdanmcd */
16328810c16bSdanmcd void
print_diagnostic(FILE * file,uint16_t diagnostic)16338810c16bSdanmcd print_diagnostic(FILE *file, uint16_t diagnostic)
16348810c16bSdanmcd {
16358810c16bSdanmcd /* Use two spaces so above strings can fit on the line. */
1636a7485808Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN,
1637a7485808Smarkfen " Diagnostic code %u: %s.\n"),
16388810c16bSdanmcd diagnostic, keysock_diag(diagnostic));
16398810c16bSdanmcd }
16408810c16bSdanmcd
16418810c16bSdanmcd /*
16428810c16bSdanmcd * Prints the base PF_KEY message.
16438810c16bSdanmcd */
16448810c16bSdanmcd void
print_sadb_msg(FILE * file,struct sadb_msg * samsg,time_t wallclock,boolean_t vflag)1645bb3ed8dfSpwernau print_sadb_msg(FILE *file, struct sadb_msg *samsg, time_t wallclock,
1646bb3ed8dfSpwernau boolean_t vflag)
16478810c16bSdanmcd {
16488810c16bSdanmcd if (wallclock != 0)
1649bb3ed8dfSpwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN,
1650a7485808Smarkfen "%sTimestamp: %s\n"), "", NULL,
16518810c16bSdanmcd vflag);
16528810c16bSdanmcd
1653bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1654bb3ed8dfSpwernau "Base message (version %u) type "),
16558810c16bSdanmcd samsg->sadb_msg_version);
16568810c16bSdanmcd switch (samsg->sadb_msg_type) {
16578810c16bSdanmcd case SADB_RESERVED:
1658bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1659a7485808Smarkfen "RESERVED (warning: set to 0)"));
16608810c16bSdanmcd break;
16618810c16bSdanmcd case SADB_GETSPI:
1662bb3ed8dfSpwernau (void) fprintf(file, "GETSPI");
16638810c16bSdanmcd break;
16648810c16bSdanmcd case SADB_UPDATE:
1665bb3ed8dfSpwernau (void) fprintf(file, "UPDATE");
16668810c16bSdanmcd break;
166738d95a78Smarkfen case SADB_X_UPDATEPAIR:
166838d95a78Smarkfen (void) fprintf(file, "UPDATE PAIR");
166938d95a78Smarkfen break;
16708810c16bSdanmcd case SADB_ADD:
1671bb3ed8dfSpwernau (void) fprintf(file, "ADD");
16728810c16bSdanmcd break;
16738810c16bSdanmcd case SADB_DELETE:
1674bb3ed8dfSpwernau (void) fprintf(file, "DELETE");
16758810c16bSdanmcd break;
167638d95a78Smarkfen case SADB_X_DELPAIR:
167738d95a78Smarkfen (void) fprintf(file, "DELETE PAIR");
167838d95a78Smarkfen break;
16798810c16bSdanmcd case SADB_GET:
1680bb3ed8dfSpwernau (void) fprintf(file, "GET");
16818810c16bSdanmcd break;
16828810c16bSdanmcd case SADB_ACQUIRE:
1683bb3ed8dfSpwernau (void) fprintf(file, "ACQUIRE");
16848810c16bSdanmcd break;
16858810c16bSdanmcd case SADB_REGISTER:
1686bb3ed8dfSpwernau (void) fprintf(file, "REGISTER");
16878810c16bSdanmcd break;
16888810c16bSdanmcd case SADB_EXPIRE:
1689bb3ed8dfSpwernau (void) fprintf(file, "EXPIRE");
16908810c16bSdanmcd break;
16918810c16bSdanmcd case SADB_FLUSH:
1692bb3ed8dfSpwernau (void) fprintf(file, "FLUSH");
16938810c16bSdanmcd break;
16948810c16bSdanmcd case SADB_DUMP:
1695bb3ed8dfSpwernau (void) fprintf(file, "DUMP");
16968810c16bSdanmcd break;
16978810c16bSdanmcd case SADB_X_PROMISC:
1698bb3ed8dfSpwernau (void) fprintf(file, "X_PROMISC");
16998810c16bSdanmcd break;
17008810c16bSdanmcd case SADB_X_INVERSE_ACQUIRE:
1701bb3ed8dfSpwernau (void) fprintf(file, "X_INVERSE_ACQUIRE");
17028810c16bSdanmcd break;
17038810c16bSdanmcd default:
1704bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1705a7485808Smarkfen "Unknown (%u)"), samsg->sadb_msg_type);
17068810c16bSdanmcd break;
17078810c16bSdanmcd }
1708bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ", SA type "));
17098810c16bSdanmcd
17108810c16bSdanmcd switch (samsg->sadb_msg_satype) {
17118810c16bSdanmcd case SADB_SATYPE_UNSPEC:
1712bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1713bb3ed8dfSpwernau "<unspecified/all>"));
17148810c16bSdanmcd break;
17158810c16bSdanmcd case SADB_SATYPE_AH:
1716bb3ed8dfSpwernau (void) fprintf(file, "AH");
17178810c16bSdanmcd break;
17188810c16bSdanmcd case SADB_SATYPE_ESP:
1719bb3ed8dfSpwernau (void) fprintf(file, "ESP");
17208810c16bSdanmcd break;
17218810c16bSdanmcd case SADB_SATYPE_RSVP:
1722bb3ed8dfSpwernau (void) fprintf(file, "RSVP");
17238810c16bSdanmcd break;
17248810c16bSdanmcd case SADB_SATYPE_OSPFV2:
1725bb3ed8dfSpwernau (void) fprintf(file, "OSPFv2");
17268810c16bSdanmcd break;
17278810c16bSdanmcd case SADB_SATYPE_RIPV2:
1728bb3ed8dfSpwernau (void) fprintf(file, "RIPv2");
17298810c16bSdanmcd break;
17308810c16bSdanmcd case SADB_SATYPE_MIP:
1731bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Mobile IP"));
17328810c16bSdanmcd break;
17338810c16bSdanmcd default:
1734bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1735a7485808Smarkfen "<unknown %u>"), samsg->sadb_msg_satype);
17368810c16bSdanmcd break;
17378810c16bSdanmcd }
17388810c16bSdanmcd
1739bb3ed8dfSpwernau (void) fprintf(file, ".\n");
17408810c16bSdanmcd
17418810c16bSdanmcd if (samsg->sadb_msg_errno != 0) {
1742bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1743bb3ed8dfSpwernau "Error %s from PF_KEY.\n"),
17448810c16bSdanmcd strerror(samsg->sadb_msg_errno));
1745bb3ed8dfSpwernau print_diagnostic(file, samsg->sadb_x_msg_diagnostic);
17468810c16bSdanmcd }
17478810c16bSdanmcd
1748bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1749a7485808Smarkfen "Message length %u bytes, seq=%u, pid=%u.\n"),
17508810c16bSdanmcd SADB_64TO8(samsg->sadb_msg_len), samsg->sadb_msg_seq,
17518810c16bSdanmcd samsg->sadb_msg_pid);
17528810c16bSdanmcd }
17538810c16bSdanmcd
17548810c16bSdanmcd /*
17558810c16bSdanmcd * Print the SA extension for PF_KEY.
17568810c16bSdanmcd */
17578810c16bSdanmcd void
print_sa(FILE * file,char * prefix,struct sadb_sa * assoc)1758bb3ed8dfSpwernau print_sa(FILE *file, char *prefix, struct sadb_sa *assoc)
17598810c16bSdanmcd {
17608810c16bSdanmcd if (assoc->sadb_sa_len != SADB_8TO64(sizeof (*assoc))) {
1761bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1762a7485808Smarkfen "WARNING: SA info extension length (%u) is bad."),
17638810c16bSdanmcd SADB_64TO8(assoc->sadb_sa_len));
17648810c16bSdanmcd }
17658810c16bSdanmcd
1766bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
17679c2c14abSThejaswini Singarajipura "%sSADB_ASSOC spi=0x%x, replay window size=%u, state="),
17688810c16bSdanmcd prefix, ntohl(assoc->sadb_sa_spi), assoc->sadb_sa_replay);
17698810c16bSdanmcd switch (assoc->sadb_sa_state) {
17708810c16bSdanmcd case SADB_SASTATE_LARVAL:
1771bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "LARVAL"));
17728810c16bSdanmcd break;
17738810c16bSdanmcd case SADB_SASTATE_MATURE:
1774bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "MATURE"));
17758810c16bSdanmcd break;
17768810c16bSdanmcd case SADB_SASTATE_DYING:
1777bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DYING"));
17788810c16bSdanmcd break;
17798810c16bSdanmcd case SADB_SASTATE_DEAD:
1780bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DEAD"));
17818810c16bSdanmcd break;
17829c2c14abSThejaswini Singarajipura case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
17839c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
17849c2c14abSThejaswini Singarajipura "ACTIVE_ELSEWHERE"));
17859c2c14abSThejaswini Singarajipura break;
17869c2c14abSThejaswini Singarajipura case SADB_X_SASTATE_IDLE:
17879c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN, "IDLE"));
17889c2c14abSThejaswini Singarajipura break;
17898810c16bSdanmcd default:
1790bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1791a7485808Smarkfen "<unknown %u>"), assoc->sadb_sa_state);
17928810c16bSdanmcd }
17938810c16bSdanmcd
17948810c16bSdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) {
1795bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1796a7485808Smarkfen "\n%sAuthentication algorithm = "),
17978810c16bSdanmcd prefix);
1798bb3ed8dfSpwernau (void) dump_aalg(assoc->sadb_sa_auth, file);
17998810c16bSdanmcd }
18008810c16bSdanmcd
18018810c16bSdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) {
1802bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1803a7485808Smarkfen "\n%sEncryption algorithm = "), prefix);
1804bb3ed8dfSpwernau (void) dump_ealg(assoc->sadb_sa_encrypt, file);
18058810c16bSdanmcd }
18068810c16bSdanmcd
1807bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%sflags=0x%x < "), prefix,
18088810c16bSdanmcd assoc->sadb_sa_flags);
18098810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_PFS)
1810bb3ed8dfSpwernau (void) fprintf(file, "PFS ");
18118810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_NOREPLAY)
1812bb3ed8dfSpwernau (void) fprintf(file, "NOREPLAY ");
18138810c16bSdanmcd
18148810c16bSdanmcd /* BEGIN Solaris-specific flags. */
18158810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_USED)
1816bb3ed8dfSpwernau (void) fprintf(file, "X_USED ");
181738d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_PAIRED)
181838d95a78Smarkfen (void) fprintf(file, "X_PAIRED ");
181938d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_OUTBOUND)
182038d95a78Smarkfen (void) fprintf(file, "X_OUTBOUND ");
182138d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_INBOUND)
182238d95a78Smarkfen (void) fprintf(file, "X_INBOUND ");
18238810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_UNIQUE)
1824bb3ed8dfSpwernau (void) fprintf(file, "X_UNIQUE ");
18258810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG1)
1826bb3ed8dfSpwernau (void) fprintf(file, "X_AALG1 ");
18278810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG2)
1828bb3ed8dfSpwernau (void) fprintf(file, "X_AALG2 ");
18298810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG1)
1830bb3ed8dfSpwernau (void) fprintf(file, "X_EALG1 ");
18318810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG2)
1832bb3ed8dfSpwernau (void) fprintf(file, "X_EALG2 ");
18338810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_LOC)
1834bb3ed8dfSpwernau (void) fprintf(file, "X_NATT_LOC ");
18358810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_REM)
1836bb3ed8dfSpwernau (void) fprintf(file, "X_NATT_REM ");
18378810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
1838bb3ed8dfSpwernau (void) fprintf(file, "X_TUNNEL ");
18394a179720Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATTED)
18404a179720Sdanmcd (void) fprintf(file, "X_NATTED ");
18418810c16bSdanmcd /* END Solaris-specific flags. */
18428810c16bSdanmcd
1843bb3ed8dfSpwernau (void) fprintf(file, ">\n");
18448810c16bSdanmcd }
18458810c16bSdanmcd
18468810c16bSdanmcd void
printsatime(FILE * file,int64_t lt,const char * msg,const char * pfx,const char * pfx2,boolean_t vflag)1847bb3ed8dfSpwernau printsatime(FILE *file, int64_t lt, const char *msg, const char *pfx,
1848bb3ed8dfSpwernau const char *pfx2, boolean_t vflag)
18498810c16bSdanmcd {
18508810c16bSdanmcd char tbuf[TBUF_SIZE]; /* For strftime() call. */
18518810c16bSdanmcd const char *tp = tbuf;
18528810c16bSdanmcd time_t t = lt;
18538810c16bSdanmcd struct tm res;
18548810c16bSdanmcd
18558810c16bSdanmcd if (t != lt) {
18568810c16bSdanmcd if (lt > 0)
18578810c16bSdanmcd t = LONG_MAX;
18588810c16bSdanmcd else
18598810c16bSdanmcd t = LONG_MIN;
18608810c16bSdanmcd }
18618810c16bSdanmcd
18628810c16bSdanmcd if (strftime(tbuf, TBUF_SIZE, NULL, localtime_r(&t, &res)) == 0)
1863a7485808Smarkfen tp = dgettext(TEXT_DOMAIN, "<time conversion failed>");
1864bb3ed8dfSpwernau (void) fprintf(file, msg, pfx, tp);
18658810c16bSdanmcd if (vflag && (pfx2 != NULL))
1866bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1867c51cb4bcSDan McDonald "%s\t(raw time value %" PRIu64 ")\n"), pfx2, lt);
18688810c16bSdanmcd }
18698810c16bSdanmcd
18708810c16bSdanmcd /*
18718810c16bSdanmcd * Print the SA lifetime information. (An SADB_EXT_LIFETIME_* extension.)
18728810c16bSdanmcd */
18738810c16bSdanmcd void
print_lifetimes(FILE * file,time_t wallclock,struct sadb_lifetime * current,struct sadb_lifetime * hard,struct sadb_lifetime * soft,struct sadb_lifetime * idle,boolean_t vflag)1874bb3ed8dfSpwernau print_lifetimes(FILE *file, time_t wallclock, struct sadb_lifetime *current,
18759c2c14abSThejaswini Singarajipura struct sadb_lifetime *hard, struct sadb_lifetime *soft,
18769c2c14abSThejaswini Singarajipura struct sadb_lifetime *idle, boolean_t vflag)
18778810c16bSdanmcd {
18788810c16bSdanmcd int64_t scratch;
1879a7485808Smarkfen char *soft_prefix = dgettext(TEXT_DOMAIN, "SLT: ");
1880a7485808Smarkfen char *hard_prefix = dgettext(TEXT_DOMAIN, "HLT: ");
1881a7485808Smarkfen char *current_prefix = dgettext(TEXT_DOMAIN, "CLT: ");
18829c2c14abSThejaswini Singarajipura char *idle_prefix = dgettext(TEXT_DOMAIN, "ILT: ");
1883510c3f91SVladimir Kotal char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */
1884510c3f91SVladimir Kotal char secs_str[SECS_STR_SIZE]; /* buffer for seconds representation */
18858810c16bSdanmcd
18868810c16bSdanmcd if (current != NULL &&
18878810c16bSdanmcd current->sadb_lifetime_len != SADB_8TO64(sizeof (*current))) {
1888bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1889a7485808Smarkfen "WARNING: CURRENT lifetime extension length (%u) is bad."),
18908810c16bSdanmcd SADB_64TO8(current->sadb_lifetime_len));
18918810c16bSdanmcd }
18928810c16bSdanmcd
18938810c16bSdanmcd if (hard != NULL &&
18948810c16bSdanmcd hard->sadb_lifetime_len != SADB_8TO64(sizeof (*hard))) {
1895bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1896bb3ed8dfSpwernau "WARNING: HARD lifetime extension length (%u) is bad."),
18978810c16bSdanmcd SADB_64TO8(hard->sadb_lifetime_len));
18988810c16bSdanmcd }
18998810c16bSdanmcd
19008810c16bSdanmcd if (soft != NULL &&
19018810c16bSdanmcd soft->sadb_lifetime_len != SADB_8TO64(sizeof (*soft))) {
1902bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1903bb3ed8dfSpwernau "WARNING: SOFT lifetime extension length (%u) is bad."),
19048810c16bSdanmcd SADB_64TO8(soft->sadb_lifetime_len));
19058810c16bSdanmcd }
19068810c16bSdanmcd
19079c2c14abSThejaswini Singarajipura if (idle != NULL &&
19089c2c14abSThejaswini Singarajipura idle->sadb_lifetime_len != SADB_8TO64(sizeof (*idle))) {
19099c2c14abSThejaswini Singarajipura warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
19109c2c14abSThejaswini Singarajipura "WARNING: IDLE lifetime extension length (%u) is bad."),
19119c2c14abSThejaswini Singarajipura SADB_64TO8(idle->sadb_lifetime_len));
19129c2c14abSThejaswini Singarajipura }
19139c2c14abSThejaswini Singarajipura
1914bb3ed8dfSpwernau (void) fprintf(file, " LT: Lifetime information\n");
19158810c16bSdanmcd if (current != NULL) {
19168810c16bSdanmcd /* Express values as current values. */
1917bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1918510c3f91SVladimir Kotal "%sCurrent lifetime information:\n"),
1919510c3f91SVladimir Kotal current_prefix);
1920510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN,
1921510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sprotected, %u allocations "
1922510c3f91SVladimir Kotal "used.\n"), current_prefix,
1923510c3f91SVladimir Kotal current->sadb_lifetime_bytes,
1924510c3f91SVladimir Kotal bytecnt2out(current->sadb_lifetime_bytes, byte_str,
1925510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
19268810c16bSdanmcd current->sadb_lifetime_allocations);
1927bb3ed8dfSpwernau printsatime(file, current->sadb_lifetime_addtime,
1928510c3f91SVladimir Kotal dgettext(TEXT_DOMAIN, "%sSA added at time: %s\n"),
19298810c16bSdanmcd current_prefix, current_prefix, vflag);
19308810c16bSdanmcd if (current->sadb_lifetime_usetime != 0) {
1931bb3ed8dfSpwernau printsatime(file, current->sadb_lifetime_usetime,
1932a7485808Smarkfen dgettext(TEXT_DOMAIN,
1933a7485808Smarkfen "%sSA first used at time %s\n"),
19348810c16bSdanmcd current_prefix, current_prefix, vflag);
19358810c16bSdanmcd }
1936bb3ed8dfSpwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN,
1937a7485808Smarkfen "%sTime now is %s\n"), current_prefix, current_prefix,
1938a7485808Smarkfen vflag);
19398810c16bSdanmcd }
19408810c16bSdanmcd
19418810c16bSdanmcd if (soft != NULL) {
1942bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1943510c3f91SVladimir Kotal "%sSoft lifetime information:\n"),
19448810c16bSdanmcd soft_prefix);
1945bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1946510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sof lifetime, %u allocations.\n"),
1947510c3f91SVladimir Kotal soft_prefix,
1948510c3f91SVladimir Kotal soft->sadb_lifetime_bytes,
1949510c3f91SVladimir Kotal bytecnt2out(soft->sadb_lifetime_bytes, byte_str,
1950510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
19518810c16bSdanmcd soft->sadb_lifetime_allocations);
1952bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1953510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
1954510c3f91SVladimir Kotal soft_prefix, soft->sadb_lifetime_addtime,
1955510c3f91SVladimir Kotal secs2out(soft->sadb_lifetime_addtime, secs_str,
1956510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
1957bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1958510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
1959510c3f91SVladimir Kotal soft_prefix, soft->sadb_lifetime_usetime,
1960510c3f91SVladimir Kotal secs2out(soft->sadb_lifetime_usetime, secs_str,
1961510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
19628810c16bSdanmcd /* If possible, express values as time remaining. */
19638810c16bSdanmcd if (current != NULL) {
19648810c16bSdanmcd if (soft->sadb_lifetime_bytes != 0)
1965510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s"
1966510c3f91SVladimir Kotal "%" PRIu64 " bytes %smore can be "
1967510c3f91SVladimir Kotal "protected.\n"), soft_prefix,
19688810c16bSdanmcd (soft->sadb_lifetime_bytes >
19698810c16bSdanmcd current->sadb_lifetime_bytes) ?
1970510c3f91SVladimir Kotal soft->sadb_lifetime_bytes -
1971510c3f91SVladimir Kotal current->sadb_lifetime_bytes : 0,
1972510c3f91SVladimir Kotal (soft->sadb_lifetime_bytes >
1973510c3f91SVladimir Kotal current->sadb_lifetime_bytes) ?
1974510c3f91SVladimir Kotal bytecnt2out(soft->sadb_lifetime_bytes -
1975510c3f91SVladimir Kotal current->sadb_lifetime_bytes, byte_str,
1976510c3f91SVladimir Kotal sizeof (byte_str), SPC_END) : "");
19778810c16bSdanmcd if (soft->sadb_lifetime_addtime != 0 ||
19788810c16bSdanmcd (soft->sadb_lifetime_usetime != 0 &&
19798810c16bSdanmcd current->sadb_lifetime_usetime != 0)) {
19808810c16bSdanmcd int64_t adddelta, usedelta;
19818810c16bSdanmcd
19828810c16bSdanmcd if (soft->sadb_lifetime_addtime != 0) {
19838810c16bSdanmcd adddelta =
19848810c16bSdanmcd current->sadb_lifetime_addtime +
19858810c16bSdanmcd soft->sadb_lifetime_addtime -
19868810c16bSdanmcd wallclock;
19878810c16bSdanmcd } else {
19888810c16bSdanmcd adddelta = TIME_MAX;
19898810c16bSdanmcd }
19908810c16bSdanmcd
19918810c16bSdanmcd if (soft->sadb_lifetime_usetime != 0 &&
19928810c16bSdanmcd current->sadb_lifetime_usetime != 0) {
19938810c16bSdanmcd usedelta =
19948810c16bSdanmcd current->sadb_lifetime_usetime +
19958810c16bSdanmcd soft->sadb_lifetime_usetime -
19968810c16bSdanmcd wallclock;
19978810c16bSdanmcd } else {
19988810c16bSdanmcd usedelta = TIME_MAX;
19998810c16bSdanmcd }
2000bb3ed8dfSpwernau (void) fprintf(file, "%s", soft_prefix);
20018810c16bSdanmcd scratch = MIN(adddelta, usedelta);
20028810c16bSdanmcd if (scratch >= 0) {
2003bb3ed8dfSpwernau (void) fprintf(file,
2004bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2005c51cb4bcSDan McDonald "Soft expiration occurs in %"
2006510c3f91SVladimir Kotal PRId64 " seconds%s\n"), scratch,
2007510c3f91SVladimir Kotal secs2out(scratch, secs_str,
2008510c3f91SVladimir Kotal sizeof (secs_str), SPC_BEGIN));
20098810c16bSdanmcd } else {
2010bb3ed8dfSpwernau (void) fprintf(file,
2011bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2012510c3f91SVladimir Kotal "Soft expiration occurred\n"));
20138810c16bSdanmcd }
20148810c16bSdanmcd scratch += wallclock;
2015bb3ed8dfSpwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN,
2016510c3f91SVladimir Kotal "%sTime of expiration: %s.\n"),
2017510c3f91SVladimir Kotal soft_prefix, soft_prefix, vflag);
20188810c16bSdanmcd }
20198810c16bSdanmcd }
20208810c16bSdanmcd }
20218810c16bSdanmcd
20228810c16bSdanmcd if (hard != NULL) {
2023bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2024510c3f91SVladimir Kotal "%sHard lifetime information:\n"), hard_prefix);
2025bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2026510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sof lifetime, %u allocations.\n"),
2027510c3f91SVladimir Kotal hard_prefix,
2028510c3f91SVladimir Kotal hard->sadb_lifetime_bytes,
2029510c3f91SVladimir Kotal bytecnt2out(hard->sadb_lifetime_bytes, byte_str,
2030510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
2031510c3f91SVladimir Kotal hard->sadb_lifetime_allocations);
2032bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2033510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
2034510c3f91SVladimir Kotal hard_prefix, hard->sadb_lifetime_addtime,
2035510c3f91SVladimir Kotal secs2out(hard->sadb_lifetime_addtime, secs_str,
2036510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
2037bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2038510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
2039510c3f91SVladimir Kotal hard_prefix, hard->sadb_lifetime_usetime,
2040510c3f91SVladimir Kotal secs2out(hard->sadb_lifetime_usetime, secs_str,
2041510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
20428810c16bSdanmcd /* If possible, express values as time remaining. */
20438810c16bSdanmcd if (current != NULL) {
20448810c16bSdanmcd if (hard->sadb_lifetime_bytes != 0)
2045510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s"
2046510c3f91SVladimir Kotal "%" PRIu64 " bytes %smore can be "
2047510c3f91SVladimir Kotal "protected.\n"), hard_prefix,
20488810c16bSdanmcd (hard->sadb_lifetime_bytes >
20498810c16bSdanmcd current->sadb_lifetime_bytes) ?
2050510c3f91SVladimir Kotal hard->sadb_lifetime_bytes -
2051510c3f91SVladimir Kotal current->sadb_lifetime_bytes : 0,
2052510c3f91SVladimir Kotal (hard->sadb_lifetime_bytes >
2053510c3f91SVladimir Kotal current->sadb_lifetime_bytes) ?
2054510c3f91SVladimir Kotal bytecnt2out(hard->sadb_lifetime_bytes -
2055510c3f91SVladimir Kotal current->sadb_lifetime_bytes, byte_str,
2056510c3f91SVladimir Kotal sizeof (byte_str), SPC_END) : "");
20578810c16bSdanmcd if (hard->sadb_lifetime_addtime != 0 ||
20588810c16bSdanmcd (hard->sadb_lifetime_usetime != 0 &&
20598810c16bSdanmcd current->sadb_lifetime_usetime != 0)) {
20608810c16bSdanmcd int64_t adddelta, usedelta;
20618810c16bSdanmcd
20628810c16bSdanmcd if (hard->sadb_lifetime_addtime != 0) {
20638810c16bSdanmcd adddelta =
20648810c16bSdanmcd current->sadb_lifetime_addtime +
20658810c16bSdanmcd hard->sadb_lifetime_addtime -
20668810c16bSdanmcd wallclock;
20678810c16bSdanmcd } else {
20688810c16bSdanmcd adddelta = TIME_MAX;
20698810c16bSdanmcd }
20708810c16bSdanmcd
20718810c16bSdanmcd if (hard->sadb_lifetime_usetime != 0 &&
20728810c16bSdanmcd current->sadb_lifetime_usetime != 0) {
20738810c16bSdanmcd usedelta =
20748810c16bSdanmcd current->sadb_lifetime_usetime +
20758810c16bSdanmcd hard->sadb_lifetime_usetime -
20768810c16bSdanmcd wallclock;
20778810c16bSdanmcd } else {
20788810c16bSdanmcd usedelta = TIME_MAX;
20798810c16bSdanmcd }
2080bb3ed8dfSpwernau (void) fprintf(file, "%s", hard_prefix);
20818810c16bSdanmcd scratch = MIN(adddelta, usedelta);
20828810c16bSdanmcd if (scratch >= 0) {
2083bb3ed8dfSpwernau (void) fprintf(file,
2084bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2085c51cb4bcSDan McDonald "Hard expiration occurs in %"
2086510c3f91SVladimir Kotal PRId64 " seconds%s\n"), scratch,
2087510c3f91SVladimir Kotal secs2out(scratch, secs_str,
2088510c3f91SVladimir Kotal sizeof (secs_str), SPC_BEGIN));
20898810c16bSdanmcd } else {
2090bb3ed8dfSpwernau (void) fprintf(file,
2091bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2092510c3f91SVladimir Kotal "Hard expiration occurred\n"));
20938810c16bSdanmcd }
20948810c16bSdanmcd scratch += wallclock;
2095bb3ed8dfSpwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN,
2096510c3f91SVladimir Kotal "%sTime of expiration: %s.\n"),
2097510c3f91SVladimir Kotal hard_prefix, hard_prefix, vflag);
20988810c16bSdanmcd }
20998810c16bSdanmcd }
21008810c16bSdanmcd }
21019c2c14abSThejaswini Singarajipura if (idle != NULL) {
21029c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2103510c3f91SVladimir Kotal "%sIdle lifetime information:\n"), idle_prefix);
21049c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2105510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
2106510c3f91SVladimir Kotal idle_prefix, idle->sadb_lifetime_addtime,
2107510c3f91SVladimir Kotal secs2out(idle->sadb_lifetime_addtime, secs_str,
2108510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
21099c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2110510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
2111510c3f91SVladimir Kotal idle_prefix, idle->sadb_lifetime_usetime,
2112510c3f91SVladimir Kotal secs2out(idle->sadb_lifetime_usetime, secs_str,
2113510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
21149c2c14abSThejaswini Singarajipura }
21158810c16bSdanmcd }
21168810c16bSdanmcd
21178810c16bSdanmcd /*
21188810c16bSdanmcd * Print an SADB_EXT_ADDRESS_* extension.
21198810c16bSdanmcd */
21208810c16bSdanmcd void
print_address(FILE * file,char * prefix,struct sadb_address * addr,boolean_t ignore_nss)2121bb3ed8dfSpwernau print_address(FILE *file, char *prefix, struct sadb_address *addr,
2122bb3ed8dfSpwernau boolean_t ignore_nss)
21238810c16bSdanmcd {
21248810c16bSdanmcd struct protoent *pe;
21258810c16bSdanmcd
2126bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
21278810c16bSdanmcd switch (addr->sadb_address_exttype) {
21288810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
2129bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source address "));
21308810c16bSdanmcd break;
21318810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
2132bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2133bb3ed8dfSpwernau "Inner source address "));
21348810c16bSdanmcd break;
21358810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
2136bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2137bb3ed8dfSpwernau "Destination address "));
21388810c16bSdanmcd break;
21398810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
2140bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2141a7485808Smarkfen "Inner destination address "));
21428810c16bSdanmcd break;
21438810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
2144bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2145bb3ed8dfSpwernau "NAT-T local address "));
21468810c16bSdanmcd break;
21478810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
2148bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2149bb3ed8dfSpwernau "NAT-T remote address "));
21508810c16bSdanmcd break;
21518810c16bSdanmcd }
21528810c16bSdanmcd
2153bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2154a7485808Smarkfen "(proto=%d"), addr->sadb_address_proto);
2155bb3ed8dfSpwernau if (ignore_nss == B_FALSE) {
21568810c16bSdanmcd if (addr->sadb_address_proto == 0) {
2157bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2158bb3ed8dfSpwernau "/<unspecified>"));
21598810c16bSdanmcd } else if ((pe = getprotobynumber(addr->sadb_address_proto))
21608810c16bSdanmcd != NULL) {
2161bb3ed8dfSpwernau (void) fprintf(file, "/%s", pe->p_name);
21628810c16bSdanmcd } else {
2163bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2164bb3ed8dfSpwernau "/<unknown>"));
21658810c16bSdanmcd }
21668810c16bSdanmcd }
2167bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ")\n%s"), prefix);
21688810c16bSdanmcd (void) dump_sockaddr((struct sockaddr *)(addr + 1),
2169bb3ed8dfSpwernau addr->sadb_address_prefixlen, B_FALSE, file, ignore_nss);
21708810c16bSdanmcd }
21718810c16bSdanmcd
21728810c16bSdanmcd /*
21738810c16bSdanmcd * Print an SADB_EXT_KEY extension.
21748810c16bSdanmcd */
21758810c16bSdanmcd void
print_key(FILE * file,char * prefix,struct sadb_key * key)2176bb3ed8dfSpwernau print_key(FILE *file, char *prefix, struct sadb_key *key)
21778810c16bSdanmcd {
2178bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
21798810c16bSdanmcd
21808810c16bSdanmcd switch (key->sadb_key_exttype) {
21818810c16bSdanmcd case SADB_EXT_KEY_AUTH:
2182bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Authentication"));
21838810c16bSdanmcd break;
21848810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
2185bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Encryption"));
21868810c16bSdanmcd break;
21878810c16bSdanmcd }
21888810c16bSdanmcd
2189bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " key.\n%s"), prefix);
2190628b0c67SMark Fenwick (void) dump_key((uint8_t *)(key + 1), key->sadb_key_bits,
2191628b0c67SMark Fenwick key->sadb_key_reserved, file, B_TRUE);
2192bb3ed8dfSpwernau (void) fprintf(file, "\n");
21938810c16bSdanmcd }
21948810c16bSdanmcd
21958810c16bSdanmcd /*
21968810c16bSdanmcd * Print an SADB_EXT_IDENTITY_* extension.
21978810c16bSdanmcd */
21988810c16bSdanmcd void
print_ident(FILE * file,char * prefix,struct sadb_ident * id)2199bb3ed8dfSpwernau print_ident(FILE *file, char *prefix, struct sadb_ident *id)
22008810c16bSdanmcd {
22018810c16bSdanmcd boolean_t canprint = B_TRUE;
22028810c16bSdanmcd
2203bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
22048810c16bSdanmcd switch (id->sadb_ident_exttype) {
22058810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
2206bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source"));
22078810c16bSdanmcd break;
22088810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
2209bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Destination"));
22108810c16bSdanmcd break;
22118810c16bSdanmcd }
22128810c16bSdanmcd
2213bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2214a7485808Smarkfen " identity, uid=%d, type "), id->sadb_ident_id);
2215bb3ed8dfSpwernau canprint = dump_sadb_idtype(id->sadb_ident_type, file, NULL);
2216bb3ed8dfSpwernau (void) fprintf(file, "\n%s", prefix);
2217a12f8217Spwernau if (canprint) {
2218bb3ed8dfSpwernau (void) fprintf(file, "%s\n", (char *)(id + 1));
2219a12f8217Spwernau } else {
2220a12f8217Spwernau print_asn1_name(file, (const unsigned char *)(id + 1),
2221a12f8217Spwernau SADB_64TO8(id->sadb_ident_len) - sizeof (sadb_ident_t));
2222a12f8217Spwernau }
22238810c16bSdanmcd }
22248810c16bSdanmcd
22258810c16bSdanmcd /*
22265d3b8cb7SBill Sommerfeld * Convert sadb_sens extension into binary security label.
22275d3b8cb7SBill Sommerfeld */
22285d3b8cb7SBill Sommerfeld
22295d3b8cb7SBill Sommerfeld #include <tsol/label.h>
22305d3b8cb7SBill Sommerfeld #include <sys/tsol/tndb.h>
22315d3b8cb7SBill Sommerfeld #include <sys/tsol/label_macro.h>
22325d3b8cb7SBill Sommerfeld
22335d3b8cb7SBill Sommerfeld void
ipsec_convert_sens_to_bslabel(const struct sadb_sens * sens,bslabel_t * sl)22345d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(const struct sadb_sens *sens, bslabel_t *sl)
22355d3b8cb7SBill Sommerfeld {
22365d3b8cb7SBill Sommerfeld uint64_t *bitmap = (uint64_t *)(sens + 1);
22375d3b8cb7SBill Sommerfeld int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
22385d3b8cb7SBill Sommerfeld
22395d3b8cb7SBill Sommerfeld bsllow(sl);
22405d3b8cb7SBill Sommerfeld LCLASS_SET((_bslabel_impl_t *)sl, sens->sadb_sens_sens_level);
22415d3b8cb7SBill Sommerfeld bcopy(bitmap, &((_bslabel_impl_t *)sl)->compartments,
22425d3b8cb7SBill Sommerfeld bitmap_len);
22435d3b8cb7SBill Sommerfeld }
22445d3b8cb7SBill Sommerfeld
22455d3b8cb7SBill Sommerfeld void
ipsec_convert_bslabel_to_string(bslabel_t * sl,char ** plabel)22465d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_string(bslabel_t *sl, char **plabel)
22475d3b8cb7SBill Sommerfeld {
22485d3b8cb7SBill Sommerfeld if (label_to_str(sl, plabel, M_LABEL, DEF_NAMES) != 0) {
22495d3b8cb7SBill Sommerfeld *plabel = strdup(dgettext(TEXT_DOMAIN,
22505d3b8cb7SBill Sommerfeld "** Label conversion failed **"));
22515d3b8cb7SBill Sommerfeld }
22525d3b8cb7SBill Sommerfeld }
22535d3b8cb7SBill Sommerfeld
22545d3b8cb7SBill Sommerfeld void
ipsec_convert_bslabel_to_hex(bslabel_t * sl,char ** plabel)22555d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(bslabel_t *sl, char **plabel)
22565d3b8cb7SBill Sommerfeld {
22575d3b8cb7SBill Sommerfeld if (label_to_str(sl, plabel, M_INTERNAL, DEF_NAMES) != 0) {
22585d3b8cb7SBill Sommerfeld *plabel = strdup(dgettext(TEXT_DOMAIN,
22595d3b8cb7SBill Sommerfeld "** Label conversion failed **"));
22605d3b8cb7SBill Sommerfeld }
22615d3b8cb7SBill Sommerfeld }
22625d3b8cb7SBill Sommerfeld
22635d3b8cb7SBill Sommerfeld int
ipsec_convert_sl_to_sens(int doi,bslabel_t * sl,sadb_sens_t * sens)22645d3b8cb7SBill Sommerfeld ipsec_convert_sl_to_sens(int doi, bslabel_t *sl, sadb_sens_t *sens)
22655d3b8cb7SBill Sommerfeld {
22665d3b8cb7SBill Sommerfeld uint8_t *bitmap;
22675d3b8cb7SBill Sommerfeld int sens_len = sizeof (sadb_sens_t) + _C_LEN * 4;
22685d3b8cb7SBill Sommerfeld
22695d3b8cb7SBill Sommerfeld
22705d3b8cb7SBill Sommerfeld if (sens == NULL)
22715d3b8cb7SBill Sommerfeld return (sens_len);
22725d3b8cb7SBill Sommerfeld
22735d3b8cb7SBill Sommerfeld
22745d3b8cb7SBill Sommerfeld (void) memset(sens, 0, sens_len);
22755d3b8cb7SBill Sommerfeld
22765d3b8cb7SBill Sommerfeld sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
22775d3b8cb7SBill Sommerfeld sens->sadb_sens_len = SADB_8TO64(sens_len);
22785d3b8cb7SBill Sommerfeld sens->sadb_sens_dpd = doi;
22795d3b8cb7SBill Sommerfeld
22805d3b8cb7SBill Sommerfeld sens->sadb_sens_sens_level = LCLASS(sl);
22815d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_level = 0;
22825d3b8cb7SBill Sommerfeld sens->sadb_sens_sens_len = _C_LEN >> 1;
22835d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_len = 0;
22845d3b8cb7SBill Sommerfeld
22855d3b8cb7SBill Sommerfeld sens->sadb_x_sens_flags = 0;
22865d3b8cb7SBill Sommerfeld
22875d3b8cb7SBill Sommerfeld bitmap = (uint8_t *)(sens + 1);
22885d3b8cb7SBill Sommerfeld bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
22895d3b8cb7SBill Sommerfeld
22905d3b8cb7SBill Sommerfeld return (sens_len);
22915d3b8cb7SBill Sommerfeld }
22925d3b8cb7SBill Sommerfeld
22935d3b8cb7SBill Sommerfeld
22945d3b8cb7SBill Sommerfeld /*
22958810c16bSdanmcd * Print an SADB_SENSITIVITY extension.
22968810c16bSdanmcd */
22978810c16bSdanmcd void
print_sens(FILE * file,char * prefix,const struct sadb_sens * sens,boolean_t ignore_nss)22985d3b8cb7SBill Sommerfeld print_sens(FILE *file, char *prefix, const struct sadb_sens *sens,
22995d3b8cb7SBill Sommerfeld boolean_t ignore_nss)
23008810c16bSdanmcd {
23015d3b8cb7SBill Sommerfeld char *plabel;
23025d3b8cb7SBill Sommerfeld char *hlabel;
23038810c16bSdanmcd uint64_t *bitmap = (uint64_t *)(sens + 1);
23045d3b8cb7SBill Sommerfeld bslabel_t sl;
23058810c16bSdanmcd int i;
23065d3b8cb7SBill Sommerfeld int sens_len = sens->sadb_sens_sens_len;
23075d3b8cb7SBill Sommerfeld int integ_len = sens->sadb_sens_integ_len;
23085d3b8cb7SBill Sommerfeld boolean_t inner = (sens->sadb_sens_exttype == SADB_EXT_SENSITIVITY);
23095d3b8cb7SBill Sommerfeld const char *sensname = inner ?
23105d3b8cb7SBill Sommerfeld dgettext(TEXT_DOMAIN, "Plaintext Sensitivity") :
23115d3b8cb7SBill Sommerfeld dgettext(TEXT_DOMAIN, "Ciphertext Sensitivity");
23125d3b8cb7SBill Sommerfeld
23135d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(sens, &sl);
23148810c16bSdanmcd
2315bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
23165d3b8cb7SBill Sommerfeld "%s%s DPD %d, sens level=%d, integ level=%d, flags=%x\n"),
23175d3b8cb7SBill Sommerfeld prefix, sensname, sens->sadb_sens_dpd, sens->sadb_sens_sens_level,
23185d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_level, sens->sadb_x_sens_flags);
23195d3b8cb7SBill Sommerfeld
23205d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(&sl, &hlabel);
23215d3b8cb7SBill Sommerfeld
23225d3b8cb7SBill Sommerfeld if (ignore_nss) {
2323bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
23245d3b8cb7SBill Sommerfeld "%s %s Label: %s\n"), prefix, sensname, hlabel);
23255d3b8cb7SBill Sommerfeld
23265d3b8cb7SBill Sommerfeld for (i = 0; i < sens_len; i++, bitmap++)
23275d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
23285d3b8cb7SBill Sommerfeld "%s %s BM extended word %d 0x%" PRIx64 "\n"),
23295d3b8cb7SBill Sommerfeld prefix, sensname, i, *bitmap);
23305d3b8cb7SBill Sommerfeld
23315d3b8cb7SBill Sommerfeld } else {
23325d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_string(&sl, &plabel);
23335d3b8cb7SBill Sommerfeld
23345d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
23355d3b8cb7SBill Sommerfeld "%s %s Label: %s (%s)\n"),
23365d3b8cb7SBill Sommerfeld prefix, sensname, plabel, hlabel);
23375d3b8cb7SBill Sommerfeld free(plabel);
23385d3b8cb7SBill Sommerfeld
23395d3b8cb7SBill Sommerfeld }
23405d3b8cb7SBill Sommerfeld free(hlabel);
23415d3b8cb7SBill Sommerfeld
23425d3b8cb7SBill Sommerfeld bitmap = (uint64_t *)(sens + 1 + sens_len);
23435d3b8cb7SBill Sommerfeld
23445d3b8cb7SBill Sommerfeld for (i = 0; i < integ_len; i++, bitmap++)
23455d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
2346c51cb4bcSDan McDonald "%s Integrity BM extended word %d 0x%" PRIx64 "\n"),
2347bb3ed8dfSpwernau prefix, i, *bitmap);
23488810c16bSdanmcd }
23498810c16bSdanmcd
23508810c16bSdanmcd /*
23518810c16bSdanmcd * Print an SADB_EXT_PROPOSAL extension.
23528810c16bSdanmcd */
23538810c16bSdanmcd void
print_prop(FILE * file,char * prefix,struct sadb_prop * prop)2354bb3ed8dfSpwernau print_prop(FILE *file, char *prefix, struct sadb_prop *prop)
23558810c16bSdanmcd {
23568810c16bSdanmcd struct sadb_comb *combs;
23578810c16bSdanmcd int i, numcombs;
23588810c16bSdanmcd
2359bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2360a7485808Smarkfen "%sProposal, replay counter = %u.\n"), prefix,
23618810c16bSdanmcd prop->sadb_prop_replay);
23628810c16bSdanmcd
23638810c16bSdanmcd numcombs = prop->sadb_prop_len - SADB_8TO64(sizeof (*prop));
23648810c16bSdanmcd numcombs /= SADB_8TO64(sizeof (*combs));
23658810c16bSdanmcd
23668810c16bSdanmcd combs = (struct sadb_comb *)(prop + 1);
23678810c16bSdanmcd
23688810c16bSdanmcd for (i = 0; i < numcombs; i++) {
2369bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2370a7485808Smarkfen "%s Combination #%u "), prefix, i + 1);
23718810c16bSdanmcd if (combs[i].sadb_comb_auth != SADB_AALG_NONE) {
2372bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2373a7485808Smarkfen "Authentication = "));
2374bb3ed8dfSpwernau (void) dump_aalg(combs[i].sadb_comb_auth, file);
2375bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2376a7485808Smarkfen " minbits=%u, maxbits=%u.\n%s "),
23778810c16bSdanmcd combs[i].sadb_comb_auth_minbits,
23788810c16bSdanmcd combs[i].sadb_comb_auth_maxbits, prefix);
23798810c16bSdanmcd }
23808810c16bSdanmcd
23818810c16bSdanmcd if (combs[i].sadb_comb_encrypt != SADB_EALG_NONE) {
2382bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2383bb3ed8dfSpwernau "Encryption = "));
2384bb3ed8dfSpwernau (void) dump_ealg(combs[i].sadb_comb_encrypt, file);
2385bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2386a7485808Smarkfen " minbits=%u, maxbits=%u.\n%s "),
23878810c16bSdanmcd combs[i].sadb_comb_encrypt_minbits,
23888810c16bSdanmcd combs[i].sadb_comb_encrypt_maxbits, prefix);
23898810c16bSdanmcd }
23908810c16bSdanmcd
2391bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "HARD: "));
23928810c16bSdanmcd if (combs[i].sadb_comb_hard_allocations)
2393bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "),
23948810c16bSdanmcd combs[i].sadb_comb_hard_allocations);
23958810c16bSdanmcd if (combs[i].sadb_comb_hard_bytes)
2396c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%"
2397c51cb4bcSDan McDonald PRIu64 " "), combs[i].sadb_comb_hard_bytes);
23988810c16bSdanmcd if (combs[i].sadb_comb_hard_addtime)
2399bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2400c51cb4bcSDan McDonald "post-add secs=%" PRIu64 " "),
24018810c16bSdanmcd combs[i].sadb_comb_hard_addtime);
24028810c16bSdanmcd if (combs[i].sadb_comb_hard_usetime)
2403bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2404c51cb4bcSDan McDonald "post-use secs=%" PRIu64 ""),
24058810c16bSdanmcd combs[i].sadb_comb_hard_usetime);
24068810c16bSdanmcd
2407bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%s SOFT: "),
2408bb3ed8dfSpwernau prefix);
24098810c16bSdanmcd if (combs[i].sadb_comb_soft_allocations)
2410bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "),
24118810c16bSdanmcd combs[i].sadb_comb_soft_allocations);
24128810c16bSdanmcd if (combs[i].sadb_comb_soft_bytes)
2413c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%"
2414c51cb4bcSDan McDonald PRIu64 " "), combs[i].sadb_comb_soft_bytes);
24158810c16bSdanmcd if (combs[i].sadb_comb_soft_addtime)
2416bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2417c51cb4bcSDan McDonald "post-add secs=%" PRIu64 " "),
24188810c16bSdanmcd combs[i].sadb_comb_soft_addtime);
24198810c16bSdanmcd if (combs[i].sadb_comb_soft_usetime)
2420bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2421c51cb4bcSDan McDonald "post-use secs=%" PRIu64 ""),
24228810c16bSdanmcd combs[i].sadb_comb_soft_usetime);
2423bb3ed8dfSpwernau (void) fprintf(file, "\n");
24248810c16bSdanmcd }
24258810c16bSdanmcd }
24268810c16bSdanmcd
24278810c16bSdanmcd /*
24288810c16bSdanmcd * Print an extended proposal (SADB_X_EXT_EPROP).
24298810c16bSdanmcd */
24308810c16bSdanmcd void
print_eprop(FILE * file,char * prefix,struct sadb_prop * eprop)2431bb3ed8dfSpwernau print_eprop(FILE *file, char *prefix, struct sadb_prop *eprop)
24328810c16bSdanmcd {
24338810c16bSdanmcd uint64_t *sofar;
24348810c16bSdanmcd struct sadb_x_ecomb *ecomb;
24358810c16bSdanmcd struct sadb_x_algdesc *algdesc;
24368810c16bSdanmcd int i, j;
24378810c16bSdanmcd
2438bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2439a7485808Smarkfen "%sExtended Proposal, replay counter = %u, "), prefix,
2440a7485808Smarkfen eprop->sadb_prop_replay);
2441bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2442bb3ed8dfSpwernau "number of combinations = %u.\n"), eprop->sadb_x_prop_numecombs);
24438810c16bSdanmcd
24448810c16bSdanmcd sofar = (uint64_t *)(eprop + 1);
24458810c16bSdanmcd ecomb = (struct sadb_x_ecomb *)sofar;
24468810c16bSdanmcd
24478810c16bSdanmcd for (i = 0; i < eprop->sadb_x_prop_numecombs; ) {
2448bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2449a7485808Smarkfen "%s Extended combination #%u:\n"), prefix, ++i);
24508810c16bSdanmcd
2451bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s HARD: "),
2452bb3ed8dfSpwernau prefix);
2453bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "),
24548810c16bSdanmcd ecomb->sadb_x_ecomb_hard_allocations);
2455c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%" PRIu64
2456c51cb4bcSDan McDonald ", "), ecomb->sadb_x_ecomb_hard_bytes);
2457c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-add secs=%"
2458c51cb4bcSDan McDonald PRIu64 ", "), ecomb->sadb_x_ecomb_hard_addtime);
2459c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%"
2460c51cb4bcSDan McDonald PRIu64 "\n"), ecomb->sadb_x_ecomb_hard_usetime);
24618810c16bSdanmcd
2462bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s SOFT: "),
2463bb3ed8dfSpwernau prefix);
2464bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "),
24658810c16bSdanmcd ecomb->sadb_x_ecomb_soft_allocations);
2466bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2467c51cb4bcSDan McDonald "bytes=%" PRIu64 ", "), ecomb->sadb_x_ecomb_soft_bytes);
2468c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN,
2469c51cb4bcSDan McDonald "post-add secs=%" PRIu64 ", "),
24708810c16bSdanmcd ecomb->sadb_x_ecomb_soft_addtime);
2471c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%"
2472c51cb4bcSDan McDonald PRIu64 "\n"), ecomb->sadb_x_ecomb_soft_usetime);
24738810c16bSdanmcd
24748810c16bSdanmcd sofar = (uint64_t *)(ecomb + 1);
24758810c16bSdanmcd algdesc = (struct sadb_x_algdesc *)sofar;
24768810c16bSdanmcd
24778810c16bSdanmcd for (j = 0; j < ecomb->sadb_x_ecomb_numalgs; ) {
2478bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2479a7485808Smarkfen "%s Alg #%u "), prefix, ++j);
24808810c16bSdanmcd switch (algdesc->sadb_x_algdesc_satype) {
24818810c16bSdanmcd case SADB_SATYPE_ESP:
2482bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2483a7485808Smarkfen "for ESP "));
24848810c16bSdanmcd break;
24858810c16bSdanmcd case SADB_SATYPE_AH:
2486bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2487bb3ed8dfSpwernau "for AH "));
24888810c16bSdanmcd break;
24898810c16bSdanmcd default:
2490bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2491a7485808Smarkfen "for satype=%d "),
24928810c16bSdanmcd algdesc->sadb_x_algdesc_satype);
24938810c16bSdanmcd }
24948810c16bSdanmcd switch (algdesc->sadb_x_algdesc_algtype) {
24958810c16bSdanmcd case SADB_X_ALGTYPE_CRYPT:
2496bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2497a7485808Smarkfen "Encryption = "));
24988810c16bSdanmcd (void) dump_ealg(algdesc->sadb_x_algdesc_alg,
2499bb3ed8dfSpwernau file);
25008810c16bSdanmcd break;
25018810c16bSdanmcd case SADB_X_ALGTYPE_AUTH:
2502bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2503a7485808Smarkfen "Authentication = "));
25048810c16bSdanmcd (void) dump_aalg(algdesc->sadb_x_algdesc_alg,
2505bb3ed8dfSpwernau file);
25068810c16bSdanmcd break;
25078810c16bSdanmcd default:
2508bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2509a7485808Smarkfen "algtype(%d) = alg(%d)"),
25108810c16bSdanmcd algdesc->sadb_x_algdesc_algtype,
25118810c16bSdanmcd algdesc->sadb_x_algdesc_alg);
25128810c16bSdanmcd break;
25138810c16bSdanmcd }
25148810c16bSdanmcd
2515bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2516628b0c67SMark Fenwick " minbits=%u, maxbits=%u, saltbits=%u\n"),
25178810c16bSdanmcd algdesc->sadb_x_algdesc_minbits,
2518628b0c67SMark Fenwick algdesc->sadb_x_algdesc_maxbits,
2519628b0c67SMark Fenwick algdesc->sadb_x_algdesc_reserved);
25208810c16bSdanmcd
25218810c16bSdanmcd sofar = (uint64_t *)(++algdesc);
25228810c16bSdanmcd }
25238810c16bSdanmcd ecomb = (struct sadb_x_ecomb *)sofar;
25248810c16bSdanmcd }
25258810c16bSdanmcd }
25268810c16bSdanmcd
25278810c16bSdanmcd /*
25288810c16bSdanmcd * Print an SADB_EXT_SUPPORTED extension.
25298810c16bSdanmcd */
25308810c16bSdanmcd void
print_supp(FILE * file,char * prefix,struct sadb_supported * supp)2531bb3ed8dfSpwernau print_supp(FILE *file, char *prefix, struct sadb_supported *supp)
25328810c16bSdanmcd {
25338810c16bSdanmcd struct sadb_alg *algs;
25348810c16bSdanmcd int i, numalgs;
25358810c16bSdanmcd
2536bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sSupported "), prefix);
25378810c16bSdanmcd switch (supp->sadb_supported_exttype) {
25388810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2539bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "authentication"));
25408810c16bSdanmcd break;
25418810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2542bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "encryption"));
25438810c16bSdanmcd break;
25448810c16bSdanmcd }
2545bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " algorithms.\n"));
25468810c16bSdanmcd
25478810c16bSdanmcd algs = (struct sadb_alg *)(supp + 1);
25488810c16bSdanmcd numalgs = supp->sadb_supported_len - SADB_8TO64(sizeof (*supp));
25498810c16bSdanmcd numalgs /= SADB_8TO64(sizeof (*algs));
25508810c16bSdanmcd for (i = 0; i < numalgs; i++) {
2551e70cf235Svk199839 uint16_t exttype = supp->sadb_supported_exttype;
2552e70cf235Svk199839
2553bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
2554e70cf235Svk199839 switch (exttype) {
25558810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2556bb3ed8dfSpwernau (void) dump_aalg(algs[i].sadb_alg_id, file);
25578810c16bSdanmcd break;
25588810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2559bb3ed8dfSpwernau (void) dump_ealg(algs[i].sadb_alg_id, file);
25608810c16bSdanmcd break;
25618810c16bSdanmcd }
2562bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2563628b0c67SMark Fenwick " minbits=%u, maxbits=%u, ivlen=%u, saltbits=%u"),
25648810c16bSdanmcd algs[i].sadb_alg_minbits, algs[i].sadb_alg_maxbits,
2565628b0c67SMark Fenwick algs[i].sadb_alg_ivlen, algs[i].sadb_x_alg_saltbits);
2566e70cf235Svk199839 if (exttype == SADB_EXT_SUPPORTED_ENCRYPT)
2567e70cf235Svk199839 (void) fprintf(file, dgettext(TEXT_DOMAIN,
2568e70cf235Svk199839 ", increment=%u"), algs[i].sadb_x_alg_increment);
2569e70cf235Svk199839 (void) fprintf(file, dgettext(TEXT_DOMAIN, ".\n"));
25708810c16bSdanmcd }
25718810c16bSdanmcd }
25728810c16bSdanmcd
25738810c16bSdanmcd /*
25748810c16bSdanmcd * Print an SADB_EXT_SPIRANGE extension.
25758810c16bSdanmcd */
25768810c16bSdanmcd void
print_spirange(FILE * file,char * prefix,struct sadb_spirange * range)2577bb3ed8dfSpwernau print_spirange(FILE *file, char *prefix, struct sadb_spirange *range)
25788810c16bSdanmcd {
2579bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2580a7485808Smarkfen "%sSPI Range, min=0x%x, max=0x%x\n"), prefix,
25818810c16bSdanmcd htonl(range->sadb_spirange_min),
25828810c16bSdanmcd htonl(range->sadb_spirange_max));
25838810c16bSdanmcd }
25848810c16bSdanmcd
25858810c16bSdanmcd /*
25868810c16bSdanmcd * Print an SADB_X_EXT_KM_COOKIE extension.
25878810c16bSdanmcd */
25888810c16bSdanmcd
25898810c16bSdanmcd void
print_kmc(FILE * file,char * prefix,struct sadb_x_kmc * kmc)2590bb3ed8dfSpwernau print_kmc(FILE *file, char *prefix, struct sadb_x_kmc *kmc)
25918810c16bSdanmcd {
25928810c16bSdanmcd char *cookie_label;
25938810c16bSdanmcd
25948810c16bSdanmcd if ((cookie_label = kmc_lookup_by_cookie(kmc->sadb_x_kmc_cookie)) ==
25958810c16bSdanmcd NULL)
2596a7485808Smarkfen cookie_label = dgettext(TEXT_DOMAIN, "<Label not found.>");
25978810c16bSdanmcd
2598bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2599a7485808Smarkfen "%sProtocol %u, cookie=\"%s\" (%u)\n"), prefix,
26008810c16bSdanmcd kmc->sadb_x_kmc_proto, cookie_label, kmc->sadb_x_kmc_cookie);
26018810c16bSdanmcd }
26029c2c14abSThejaswini Singarajipura
26039c2c14abSThejaswini Singarajipura /*
26049c2c14abSThejaswini Singarajipura * Print an SADB_X_EXT_REPLAY_CTR extension.
26059c2c14abSThejaswini Singarajipura */
26069c2c14abSThejaswini Singarajipura
26079c2c14abSThejaswini Singarajipura void
print_replay(FILE * file,char * prefix,sadb_x_replay_ctr_t * repl)26089c2c14abSThejaswini Singarajipura print_replay(FILE *file, char *prefix, sadb_x_replay_ctr_t *repl)
26099c2c14abSThejaswini Singarajipura {
26109c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
26119c2c14abSThejaswini Singarajipura "%sReplay Value "), prefix);
26129c2c14abSThejaswini Singarajipura if ((repl->sadb_x_rc_replay32 == 0) &&
26139c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay64 == 0)) {
26149c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
26159c2c14abSThejaswini Singarajipura "<Value not found.>"));
26169c2c14abSThejaswini Singarajipura }
26179c2c14abSThejaswini Singarajipura /*
26189c2c14abSThejaswini Singarajipura * We currently do not support a 64-bit replay value.
26199c2c14abSThejaswini Singarajipura * RFC 4301 will require one, however, and we have a field
26209c2c14abSThejaswini Singarajipura * in place when 4301 is built.
26219c2c14abSThejaswini Singarajipura */
26229c2c14abSThejaswini Singarajipura (void) fprintf(file, "% " PRIu64 "\n",
26239c2c14abSThejaswini Singarajipura ((repl->sadb_x_rc_replay32 == 0) ?
26249c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay64 : repl->sadb_x_rc_replay32));
26259c2c14abSThejaswini Singarajipura }
262638d95a78Smarkfen /*
262738d95a78Smarkfen * Print an SADB_X_EXT_PAIR extension.
262838d95a78Smarkfen */
262938d95a78Smarkfen static void
print_pair(FILE * file,char * prefix,struct sadb_x_pair * pair)263038d95a78Smarkfen print_pair(FILE *file, char *prefix, struct sadb_x_pair *pair)
263138d95a78Smarkfen {
263238d95a78Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sPaired with spi=0x%x\n"),
263338d95a78Smarkfen prefix, ntohl(pair->sadb_x_pair_spi));
263438d95a78Smarkfen }
26358810c16bSdanmcd
26368810c16bSdanmcd /*
26378810c16bSdanmcd * Take a PF_KEY message pointed to buffer and print it. Useful for DUMP
26388810c16bSdanmcd * and GET.
26398810c16bSdanmcd */
26408810c16bSdanmcd void
print_samsg(FILE * file,uint64_t * buffer,boolean_t want_timestamp,boolean_t vflag,boolean_t ignore_nss)2641bb3ed8dfSpwernau print_samsg(FILE *file, uint64_t *buffer, boolean_t want_timestamp,
2642bb3ed8dfSpwernau boolean_t vflag, boolean_t ignore_nss)
26438810c16bSdanmcd {
26448810c16bSdanmcd uint64_t *current;
26458810c16bSdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer;
26468810c16bSdanmcd struct sadb_ext *ext;
26478810c16bSdanmcd struct sadb_lifetime *currentlt = NULL, *hardlt = NULL, *softlt = NULL;
26489c2c14abSThejaswini Singarajipura struct sadb_lifetime *idlelt = NULL;
26498810c16bSdanmcd int i;
26508810c16bSdanmcd time_t wallclock;
26518810c16bSdanmcd
26528810c16bSdanmcd (void) time(&wallclock);
26538810c16bSdanmcd
2654bb3ed8dfSpwernau print_sadb_msg(file, samsg, want_timestamp ? wallclock : 0, vflag);
26558810c16bSdanmcd current = (uint64_t *)(samsg + 1);
26568810c16bSdanmcd while (current - buffer < samsg->sadb_msg_len) {
26578810c16bSdanmcd int lenbytes;
26588810c16bSdanmcd
26598810c16bSdanmcd ext = (struct sadb_ext *)current;
26608810c16bSdanmcd lenbytes = SADB_64TO8(ext->sadb_ext_len);
26618810c16bSdanmcd switch (ext->sadb_ext_type) {
26628810c16bSdanmcd case SADB_EXT_SA:
2663bb3ed8dfSpwernau print_sa(file, dgettext(TEXT_DOMAIN,
2664a7485808Smarkfen "SA: "), (struct sadb_sa *)current);
26658810c16bSdanmcd break;
26668810c16bSdanmcd /*
26678810c16bSdanmcd * Pluck out lifetimes and print them at the end. This is
26688810c16bSdanmcd * to show relative lifetimes.
26698810c16bSdanmcd */
26708810c16bSdanmcd case SADB_EXT_LIFETIME_CURRENT:
26718810c16bSdanmcd currentlt = (struct sadb_lifetime *)current;
26728810c16bSdanmcd break;
26738810c16bSdanmcd case SADB_EXT_LIFETIME_HARD:
26748810c16bSdanmcd hardlt = (struct sadb_lifetime *)current;
26758810c16bSdanmcd break;
26768810c16bSdanmcd case SADB_EXT_LIFETIME_SOFT:
26778810c16bSdanmcd softlt = (struct sadb_lifetime *)current;
26788810c16bSdanmcd break;
26799c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
26809c2c14abSThejaswini Singarajipura idlelt = (struct sadb_lifetime *)current;
26819c2c14abSThejaswini Singarajipura break;
26828810c16bSdanmcd
26838810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
2684bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "SRC: "),
2685bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
26868810c16bSdanmcd break;
26878810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
2688bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "INS: "),
2689bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
26908810c16bSdanmcd break;
26918810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
2692bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "DST: "),
2693bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
26948810c16bSdanmcd break;
26958810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
2696bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "IND: "),
2697bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
26988810c16bSdanmcd break;
26998810c16bSdanmcd case SADB_EXT_KEY_AUTH:
2700bb3ed8dfSpwernau print_key(file, dgettext(TEXT_DOMAIN,
2701a7485808Smarkfen "AKY: "), (struct sadb_key *)current);
27028810c16bSdanmcd break;
27038810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
2704bb3ed8dfSpwernau print_key(file, dgettext(TEXT_DOMAIN,
2705a7485808Smarkfen "EKY: "), (struct sadb_key *)current);
27068810c16bSdanmcd break;
27078810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
2708bb3ed8dfSpwernau print_ident(file, dgettext(TEXT_DOMAIN, "SID: "),
27098810c16bSdanmcd (struct sadb_ident *)current);
27108810c16bSdanmcd break;
27118810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
2712bb3ed8dfSpwernau print_ident(file, dgettext(TEXT_DOMAIN, "DID: "),
27138810c16bSdanmcd (struct sadb_ident *)current);
27148810c16bSdanmcd break;
27158810c16bSdanmcd case SADB_EXT_SENSITIVITY:
2716bb3ed8dfSpwernau print_sens(file, dgettext(TEXT_DOMAIN, "SNS: "),
27175d3b8cb7SBill Sommerfeld (struct sadb_sens *)current, ignore_nss);
27188810c16bSdanmcd break;
27198810c16bSdanmcd case SADB_EXT_PROPOSAL:
2720bb3ed8dfSpwernau print_prop(file, dgettext(TEXT_DOMAIN, "PRP: "),
27218810c16bSdanmcd (struct sadb_prop *)current);
27228810c16bSdanmcd break;
27238810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2724bb3ed8dfSpwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUA: "),
27258810c16bSdanmcd (struct sadb_supported *)current);
27268810c16bSdanmcd break;
27278810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2728bb3ed8dfSpwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUE: "),
27298810c16bSdanmcd (struct sadb_supported *)current);
27308810c16bSdanmcd break;
27318810c16bSdanmcd case SADB_EXT_SPIRANGE:
2732bb3ed8dfSpwernau print_spirange(file, dgettext(TEXT_DOMAIN, "SPR: "),
27338810c16bSdanmcd (struct sadb_spirange *)current);
27348810c16bSdanmcd break;
27358810c16bSdanmcd case SADB_X_EXT_EPROP:
2736bb3ed8dfSpwernau print_eprop(file, dgettext(TEXT_DOMAIN, "EPR: "),
27378810c16bSdanmcd (struct sadb_prop *)current);
27388810c16bSdanmcd break;
27398810c16bSdanmcd case SADB_X_EXT_KM_COOKIE:
2740bb3ed8dfSpwernau print_kmc(file, dgettext(TEXT_DOMAIN, "KMC: "),
27418810c16bSdanmcd (struct sadb_x_kmc *)current);
27428810c16bSdanmcd break;
27438810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
2744bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "NRM: "),
2745bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27468810c16bSdanmcd break;
27478810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
2748bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "NLC: "),
2749bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27508810c16bSdanmcd break;
275138d95a78Smarkfen case SADB_X_EXT_PAIR:
275238d95a78Smarkfen print_pair(file, dgettext(TEXT_DOMAIN, "OTH: "),
275338d95a78Smarkfen (struct sadb_x_pair *)current);
275438d95a78Smarkfen break;
27555d3b8cb7SBill Sommerfeld case SADB_X_EXT_OUTER_SENS:
27565d3b8cb7SBill Sommerfeld print_sens(file, dgettext(TEXT_DOMAIN, "OSN: "),
27575d3b8cb7SBill Sommerfeld (struct sadb_sens *)current, ignore_nss);
27585d3b8cb7SBill Sommerfeld break;
27599c2c14abSThejaswini Singarajipura case SADB_X_EXT_REPLAY_VALUE:
27609c2c14abSThejaswini Singarajipura (void) print_replay(file, dgettext(TEXT_DOMAIN,
27619c2c14abSThejaswini Singarajipura "RPL: "), (sadb_x_replay_ctr_t *)current);
27629c2c14abSThejaswini Singarajipura break;
27638810c16bSdanmcd default:
2764bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
27658810c16bSdanmcd "UNK: Unknown ext. %d, len %d.\n"),
27668810c16bSdanmcd ext->sadb_ext_type, lenbytes);
27678810c16bSdanmcd for (i = 0; i < ext->sadb_ext_len; i++)
2768bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2769c51cb4bcSDan McDonald "UNK: 0x%" PRIx64 "\n"),
2770c51cb4bcSDan McDonald ((uint64_t *)ext)[i]);
27718810c16bSdanmcd break;
27728810c16bSdanmcd }
27738810c16bSdanmcd current += (lenbytes == 0) ?
27748810c16bSdanmcd SADB_8TO64(sizeof (struct sadb_ext)) : ext->sadb_ext_len;
27758810c16bSdanmcd }
27768810c16bSdanmcd /*
27778810c16bSdanmcd * Print lifetimes NOW.
27788810c16bSdanmcd */
27799c2c14abSThejaswini Singarajipura if (currentlt != NULL || hardlt != NULL || softlt != NULL ||
27809c2c14abSThejaswini Singarajipura idlelt != NULL)
27819c2c14abSThejaswini Singarajipura print_lifetimes(file, wallclock, currentlt, hardlt,
27829c2c14abSThejaswini Singarajipura softlt, idlelt, vflag);
27838810c16bSdanmcd
27848810c16bSdanmcd if (current - buffer != samsg->sadb_msg_len) {
2785bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
2786bb3ed8dfSpwernau "WARNING: insufficient buffer space or corrupt message."));
27878810c16bSdanmcd }
27888810c16bSdanmcd
2789bb3ed8dfSpwernau (void) fflush(file); /* Make sure our message is out there. */
27908810c16bSdanmcd }
27918810c16bSdanmcd
27928810c16bSdanmcd /*
27938810c16bSdanmcd * save_XXX functions are used when "saving" the SA tables to either a
27948810c16bSdanmcd * file or standard output. They use the dump_XXX functions where needed,
27958810c16bSdanmcd * but mostly they use the rparseXXX functions.
27968810c16bSdanmcd */
27978810c16bSdanmcd
27988810c16bSdanmcd /*
27998810c16bSdanmcd * Print save information for a lifetime extension.
28008810c16bSdanmcd *
28018810c16bSdanmcd * NOTE : It saves the lifetime in absolute terms. For example, if you
28028810c16bSdanmcd * had a hard_usetime of 60 seconds, you'll save it as 60 seconds, even though
28038810c16bSdanmcd * there may have been 59 seconds burned off the clock.
28048810c16bSdanmcd */
28058810c16bSdanmcd boolean_t
save_lifetime(struct sadb_lifetime * lifetime,FILE * ofile)28068810c16bSdanmcd save_lifetime(struct sadb_lifetime *lifetime, FILE *ofile)
28078810c16bSdanmcd {
28088810c16bSdanmcd char *prefix;
28098810c16bSdanmcd
28109c2c14abSThejaswini Singarajipura switch (lifetime->sadb_lifetime_exttype) {
28119c2c14abSThejaswini Singarajipura case SADB_EXT_LIFETIME_HARD:
28129c2c14abSThejaswini Singarajipura prefix = "hard";
28139c2c14abSThejaswini Singarajipura break;
28149c2c14abSThejaswini Singarajipura case SADB_EXT_LIFETIME_SOFT:
28159c2c14abSThejaswini Singarajipura prefix = "soft";
28169c2c14abSThejaswini Singarajipura break;
28179c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
28189c2c14abSThejaswini Singarajipura prefix = "idle";
28199c2c14abSThejaswini Singarajipura break;
28209c2c14abSThejaswini Singarajipura }
28218810c16bSdanmcd
28228810c16bSdanmcd if (putc('\t', ofile) == EOF)
28238810c16bSdanmcd return (B_FALSE);
28248810c16bSdanmcd
28258810c16bSdanmcd if (lifetime->sadb_lifetime_allocations != 0 && fprintf(ofile,
28268810c16bSdanmcd "%s_alloc %u ", prefix, lifetime->sadb_lifetime_allocations) < 0)
28278810c16bSdanmcd return (B_FALSE);
28288810c16bSdanmcd
28298810c16bSdanmcd if (lifetime->sadb_lifetime_bytes != 0 && fprintf(ofile,
2830c51cb4bcSDan McDonald "%s_bytes %" PRIu64 " ", prefix, lifetime->sadb_lifetime_bytes) < 0)
28318810c16bSdanmcd return (B_FALSE);
28328810c16bSdanmcd
28338810c16bSdanmcd if (lifetime->sadb_lifetime_addtime != 0 && fprintf(ofile,
2834c51cb4bcSDan McDonald "%s_addtime %" PRIu64 " ", prefix,
2835c51cb4bcSDan McDonald lifetime->sadb_lifetime_addtime) < 0)
28368810c16bSdanmcd return (B_FALSE);
28378810c16bSdanmcd
28388810c16bSdanmcd if (lifetime->sadb_lifetime_usetime != 0 && fprintf(ofile,
2839c51cb4bcSDan McDonald "%s_usetime %" PRIu64 " ", prefix,
2840c51cb4bcSDan McDonald lifetime->sadb_lifetime_usetime) < 0)
28418810c16bSdanmcd return (B_FALSE);
28428810c16bSdanmcd
28438810c16bSdanmcd return (B_TRUE);
28448810c16bSdanmcd }
28458810c16bSdanmcd
28468810c16bSdanmcd /*
28478810c16bSdanmcd * Print save information for an address extension.
28488810c16bSdanmcd */
28498810c16bSdanmcd boolean_t
save_address(struct sadb_address * addr,FILE * ofile)28508810c16bSdanmcd save_address(struct sadb_address *addr, FILE *ofile)
28518810c16bSdanmcd {
28528810c16bSdanmcd char *printable_addr, buf[INET6_ADDRSTRLEN];
28538810c16bSdanmcd const char *prefix, *pprefix;
28548810c16bSdanmcd struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(addr + 1);
28558810c16bSdanmcd struct sockaddr_in *sin = (struct sockaddr_in *)sin6;
28568810c16bSdanmcd int af = sin->sin_family;
28578810c16bSdanmcd
28588810c16bSdanmcd /*
28598810c16bSdanmcd * Address-family reality check.
28608810c16bSdanmcd */
28618810c16bSdanmcd if (af != AF_INET6 && af != AF_INET)
28628810c16bSdanmcd return (B_FALSE);
28638810c16bSdanmcd
28648810c16bSdanmcd switch (addr->sadb_address_exttype) {
28658810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
28668810c16bSdanmcd prefix = "src";
28678810c16bSdanmcd pprefix = "sport";
28688810c16bSdanmcd break;
28698810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
28708810c16bSdanmcd prefix = "isrc";
28718810c16bSdanmcd pprefix = "isport";
28728810c16bSdanmcd break;
28738810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
28748810c16bSdanmcd prefix = "dst";
28758810c16bSdanmcd pprefix = "dport";
28768810c16bSdanmcd break;
28778810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
28788810c16bSdanmcd prefix = "idst";
28798810c16bSdanmcd pprefix = "idport";
28808810c16bSdanmcd break;
28818810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
28828810c16bSdanmcd prefix = "nat_loc ";
28838810c16bSdanmcd pprefix = "nat_lport";
28848810c16bSdanmcd break;
28858810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
28868810c16bSdanmcd prefix = "nat_rem ";
28878810c16bSdanmcd pprefix = "nat_rport";
28888810c16bSdanmcd break;
28898810c16bSdanmcd }
28908810c16bSdanmcd
28918810c16bSdanmcd if (fprintf(ofile, " %s ", prefix) < 0)
28928810c16bSdanmcd return (B_FALSE);
28938810c16bSdanmcd
28948810c16bSdanmcd /*
28958810c16bSdanmcd * Do not do address-to-name translation, given that we live in
28968810c16bSdanmcd * an age of names that explode into many addresses.
28978810c16bSdanmcd */
28988810c16bSdanmcd printable_addr = (char *)inet_ntop(af,
28998810c16bSdanmcd (af == AF_INET) ? (char *)&sin->sin_addr : (char *)&sin6->sin6_addr,
29008810c16bSdanmcd buf, sizeof (buf));
29018810c16bSdanmcd if (printable_addr == NULL)
2902a7485808Smarkfen printable_addr = "Invalid IP address.";
29038810c16bSdanmcd if (fprintf(ofile, "%s", printable_addr) < 0)
29048810c16bSdanmcd return (B_FALSE);
29058810c16bSdanmcd if (addr->sadb_address_prefixlen != 0 &&
29068810c16bSdanmcd !((addr->sadb_address_prefixlen == 32 && af == AF_INET) ||
29078810c16bSdanmcd (addr->sadb_address_prefixlen == 128 && af == AF_INET6))) {
29088810c16bSdanmcd if (fprintf(ofile, "/%d", addr->sadb_address_prefixlen) < 0)
29098810c16bSdanmcd return (B_FALSE);
29108810c16bSdanmcd }
29118810c16bSdanmcd
29128810c16bSdanmcd /*
29138810c16bSdanmcd * The port is in the same position for struct sockaddr_in and
29148810c16bSdanmcd * struct sockaddr_in6. We exploit that property here.
29158810c16bSdanmcd */
29168810c16bSdanmcd if ((pprefix != NULL) && (sin->sin_port != 0))
29178810c16bSdanmcd (void) fprintf(ofile, " %s %d", pprefix, ntohs(sin->sin_port));
29188810c16bSdanmcd
29198810c16bSdanmcd return (B_TRUE);
29208810c16bSdanmcd }
29218810c16bSdanmcd
29228810c16bSdanmcd /*
29238810c16bSdanmcd * Print save information for a key extension. Returns whether writing
29248810c16bSdanmcd * to the specified output file was successful or not.
29258810c16bSdanmcd */
29268810c16bSdanmcd boolean_t
save_key(struct sadb_key * key,FILE * ofile)29278810c16bSdanmcd save_key(struct sadb_key *key, FILE *ofile)
29288810c16bSdanmcd {
29298810c16bSdanmcd char *prefix;
29308810c16bSdanmcd
29318810c16bSdanmcd if (putc('\t', ofile) == EOF)
29328810c16bSdanmcd return (B_FALSE);
29338810c16bSdanmcd
29348810c16bSdanmcd prefix = (key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ? "auth" : "encr";
29358810c16bSdanmcd
29368810c16bSdanmcd if (fprintf(ofile, "%skey ", prefix) < 0)
29378810c16bSdanmcd return (B_FALSE);
29388810c16bSdanmcd
2939628b0c67SMark Fenwick if (dump_key((uint8_t *)(key + 1), key->sadb_key_bits,
2940628b0c67SMark Fenwick key->sadb_key_reserved, ofile, B_FALSE) == -1)
29418810c16bSdanmcd return (B_FALSE);
29428810c16bSdanmcd
29438810c16bSdanmcd return (B_TRUE);
29448810c16bSdanmcd }
29458810c16bSdanmcd
29468810c16bSdanmcd /*
29478810c16bSdanmcd * Print save information for an identity extension.
29488810c16bSdanmcd */
29498810c16bSdanmcd boolean_t
save_ident(struct sadb_ident * ident,FILE * ofile)29508810c16bSdanmcd save_ident(struct sadb_ident *ident, FILE *ofile)
29518810c16bSdanmcd {
29528810c16bSdanmcd char *prefix;
29538810c16bSdanmcd
29548810c16bSdanmcd if (putc('\t', ofile) == EOF)
29558810c16bSdanmcd return (B_FALSE);
29568810c16bSdanmcd
29578810c16bSdanmcd prefix = (ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ? "src" :
29588810c16bSdanmcd "dst";
29598810c16bSdanmcd
29608810c16bSdanmcd if (fprintf(ofile, "%sidtype %s ", prefix,
29618810c16bSdanmcd rparseidtype(ident->sadb_ident_type)) < 0)
29628810c16bSdanmcd return (B_FALSE);
29638810c16bSdanmcd
29648810c16bSdanmcd if (ident->sadb_ident_type == SADB_X_IDENTTYPE_DN ||
29658810c16bSdanmcd ident->sadb_ident_type == SADB_X_IDENTTYPE_GN) {
2966a7485808Smarkfen if (fprintf(ofile, dgettext(TEXT_DOMAIN,
2967a7485808Smarkfen "<can-not-print>")) < 0)
29688810c16bSdanmcd return (B_FALSE);
29698810c16bSdanmcd } else {
29708810c16bSdanmcd if (fprintf(ofile, "%s", (char *)(ident + 1)) < 0)
29718810c16bSdanmcd return (B_FALSE);
29728810c16bSdanmcd }
29738810c16bSdanmcd
29748810c16bSdanmcd return (B_TRUE);
29758810c16bSdanmcd }
29768810c16bSdanmcd
29775d3b8cb7SBill Sommerfeld boolean_t
save_sens(struct sadb_sens * sens,FILE * ofile)29785d3b8cb7SBill Sommerfeld save_sens(struct sadb_sens *sens, FILE *ofile)
29795d3b8cb7SBill Sommerfeld {
29805d3b8cb7SBill Sommerfeld char *prefix;
29815d3b8cb7SBill Sommerfeld char *hlabel;
29825d3b8cb7SBill Sommerfeld bslabel_t sl;
29835d3b8cb7SBill Sommerfeld
29845d3b8cb7SBill Sommerfeld if (putc('\t', ofile) == EOF)
29855d3b8cb7SBill Sommerfeld return (B_FALSE);
29865d3b8cb7SBill Sommerfeld
29875d3b8cb7SBill Sommerfeld if (sens->sadb_sens_exttype == SADB_EXT_SENSITIVITY)
29885d3b8cb7SBill Sommerfeld prefix = "label";
29895d3b8cb7SBill Sommerfeld else if ((sens->sadb_x_sens_flags & SADB_X_SENS_IMPLICIT) == 0)
29905d3b8cb7SBill Sommerfeld prefix = "outer-label";
29915d3b8cb7SBill Sommerfeld else
29925d3b8cb7SBill Sommerfeld prefix = "implicit-label";
29935d3b8cb7SBill Sommerfeld
29945d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(sens, &sl);
29955d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(&sl, &hlabel);
29965d3b8cb7SBill Sommerfeld
29975d3b8cb7SBill Sommerfeld if (fprintf(ofile, "%s %s ", prefix, hlabel) < 0) {
29985d3b8cb7SBill Sommerfeld free(hlabel);
29995d3b8cb7SBill Sommerfeld return (B_FALSE);
30005d3b8cb7SBill Sommerfeld }
30015d3b8cb7SBill Sommerfeld free(hlabel);
30025d3b8cb7SBill Sommerfeld
30035d3b8cb7SBill Sommerfeld return (B_TRUE);
30045d3b8cb7SBill Sommerfeld }
30055d3b8cb7SBill Sommerfeld
30068810c16bSdanmcd /*
30078810c16bSdanmcd * "Save" a security association to an output file.
30088810c16bSdanmcd *
3009a7485808Smarkfen * NOTE the lack of calls to dgettext() because I'm outputting parseable stuff.
30108810c16bSdanmcd * ALSO NOTE that if you change keywords (see parsecmd()), you'll have to
30118810c16bSdanmcd * change them here as well.
30128810c16bSdanmcd */
30138810c16bSdanmcd void
save_assoc(uint64_t * buffer,FILE * ofile)30148810c16bSdanmcd save_assoc(uint64_t *buffer, FILE *ofile)
30158810c16bSdanmcd {
3016a7485808Smarkfen int terrno;
3017437220cdSdanmcd boolean_t seen_proto = B_FALSE, seen_iproto = B_FALSE;
30188810c16bSdanmcd uint64_t *current;
30198810c16bSdanmcd struct sadb_address *addr;
30209c2c14abSThejaswini Singarajipura struct sadb_x_replay_ctr *repl;
30218810c16bSdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer;
30228810c16bSdanmcd struct sadb_ext *ext;
30238810c16bSdanmcd
3024a7485808Smarkfen #define tidyup() \
3025a7485808Smarkfen terrno = errno; (void) fclose(ofile); errno = terrno; \
3026a7485808Smarkfen interactive = B_FALSE
3027a7485808Smarkfen
3028a7485808Smarkfen #define savenl() if (fputs(" \\\n", ofile) == EOF) \
3029a7485808Smarkfen { bail(dgettext(TEXT_DOMAIN, "savenl")); }
30308810c16bSdanmcd
30318810c16bSdanmcd if (fputs("# begin assoc\n", ofile) == EOF)
3032a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3033a7485808Smarkfen "save_assoc: Opening comment of SA"));
30348810c16bSdanmcd if (fprintf(ofile, "add %s ", rparsesatype(samsg->sadb_msg_satype)) < 0)
3035a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: First line of SA"));
30368810c16bSdanmcd savenl();
30378810c16bSdanmcd
30388810c16bSdanmcd current = (uint64_t *)(samsg + 1);
30398810c16bSdanmcd while (current - buffer < samsg->sadb_msg_len) {
30408810c16bSdanmcd struct sadb_sa *assoc;
30418810c16bSdanmcd
30428810c16bSdanmcd ext = (struct sadb_ext *)current;
3043437220cdSdanmcd addr = (struct sadb_address *)ext; /* Just in case... */
30448810c16bSdanmcd switch (ext->sadb_ext_type) {
30458810c16bSdanmcd case SADB_EXT_SA:
30468810c16bSdanmcd assoc = (struct sadb_sa *)ext;
30478810c16bSdanmcd if (assoc->sadb_sa_state != SADB_SASTATE_MATURE) {
30488810c16bSdanmcd if (fprintf(ofile, "# WARNING: SA was dying "
30498810c16bSdanmcd "or dead.\n") < 0) {
3050a7485808Smarkfen tidyup();
3051a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3052a7485808Smarkfen "save_assoc: fprintf not mature"));
30538810c16bSdanmcd }
30548810c16bSdanmcd }
30558810c16bSdanmcd if (fprintf(ofile, " spi 0x%x ",
3056a7485808Smarkfen ntohl(assoc->sadb_sa_spi)) < 0) {
3057a7485808Smarkfen tidyup();
3058a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3059a7485808Smarkfen "save_assoc: fprintf spi"));
3060a7485808Smarkfen }
30618810c16bSdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) {
30628810c16bSdanmcd if (fprintf(ofile, "encr_alg %s ",
30638810c16bSdanmcd rparsealg(assoc->sadb_sa_encrypt,
3064a7485808Smarkfen IPSEC_PROTO_ESP)) < 0) {
3065a7485808Smarkfen tidyup();
3066a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3067a7485808Smarkfen "save_assoc: fprintf encrypt"));
3068a7485808Smarkfen }
30698810c16bSdanmcd }
30708810c16bSdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) {
30718810c16bSdanmcd if (fprintf(ofile, "auth_alg %s ",
30728810c16bSdanmcd rparsealg(assoc->sadb_sa_auth,
3073a7485808Smarkfen IPSEC_PROTO_AH)) < 0) {
3074a7485808Smarkfen tidyup();
3075a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3076a7485808Smarkfen "save_assoc: fprintf auth"));
3077a7485808Smarkfen }
30788810c16bSdanmcd }
30798810c16bSdanmcd if (fprintf(ofile, "replay %d ",
3080a7485808Smarkfen assoc->sadb_sa_replay) < 0) {
3081a7485808Smarkfen tidyup();
3082a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3083a7485808Smarkfen "save_assoc: fprintf replay"));
3084a7485808Smarkfen }
30858810c16bSdanmcd if (assoc->sadb_sa_flags & (SADB_X_SAFLAGS_NATT_LOC |
30868810c16bSdanmcd SADB_X_SAFLAGS_NATT_REM)) {
3087a7485808Smarkfen if (fprintf(ofile, "encap udp") < 0) {
3088a7485808Smarkfen tidyup();
3089a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3090a7485808Smarkfen "save_assoc: fprintf encap"));
30918810c16bSdanmcd }
3092a7485808Smarkfen }
30938810c16bSdanmcd savenl();
30948810c16bSdanmcd break;
30958810c16bSdanmcd case SADB_EXT_LIFETIME_HARD:
30968810c16bSdanmcd case SADB_EXT_LIFETIME_SOFT:
30979c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
3098a7485808Smarkfen if (!save_lifetime((struct sadb_lifetime *)ext,
3099a7485808Smarkfen ofile)) {
3100a7485808Smarkfen tidyup();
3101a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_lifetime"));
3102a7485808Smarkfen }
31038810c16bSdanmcd savenl();
31048810c16bSdanmcd break;
31058810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
31068810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
3107437220cdSdanmcd if (!seen_iproto && addr->sadb_address_proto) {
3108437220cdSdanmcd (void) fprintf(ofile, " iproto %d",
3109437220cdSdanmcd addr->sadb_address_proto);
3110437220cdSdanmcd savenl();
3111437220cdSdanmcd seen_iproto = B_TRUE;
3112437220cdSdanmcd }
3113437220cdSdanmcd goto skip_srcdst; /* Hack to avoid cases below... */
3114437220cdSdanmcd /* FALLTHRU */
3115437220cdSdanmcd case SADB_EXT_ADDRESS_SRC:
3116437220cdSdanmcd case SADB_EXT_ADDRESS_DST:
31178810c16bSdanmcd if (!seen_proto && addr->sadb_address_proto) {
31188810c16bSdanmcd (void) fprintf(ofile, " proto %d",
31198810c16bSdanmcd addr->sadb_address_proto);
31208810c16bSdanmcd savenl();
3121437220cdSdanmcd seen_proto = B_TRUE;
31228810c16bSdanmcd }
3123437220cdSdanmcd /* FALLTHRU */
3124437220cdSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
3125437220cdSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
3126437220cdSdanmcd skip_srcdst:
3127a7485808Smarkfen if (!save_address(addr, ofile)) {
3128a7485808Smarkfen tidyup();
3129a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3130a7485808Smarkfen }
31318810c16bSdanmcd savenl();
31328810c16bSdanmcd break;
31338810c16bSdanmcd case SADB_EXT_KEY_AUTH:
31348810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
3135a7485808Smarkfen if (!save_key((struct sadb_key *)ext, ofile)) {
3136a7485808Smarkfen tidyup();
3137a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3138a7485808Smarkfen }
31398810c16bSdanmcd savenl();
31408810c16bSdanmcd break;
31418810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
31428810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
3143a7485808Smarkfen if (!save_ident((struct sadb_ident *)ext, ofile)) {
3144a7485808Smarkfen tidyup();
3145a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3146a7485808Smarkfen }
31478810c16bSdanmcd savenl();
31488810c16bSdanmcd break;
31499c2c14abSThejaswini Singarajipura case SADB_X_EXT_REPLAY_VALUE:
31509c2c14abSThejaswini Singarajipura repl = (sadb_x_replay_ctr_t *)ext;
31519c2c14abSThejaswini Singarajipura if ((repl->sadb_x_rc_replay32 == 0) &&
31529c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay64 == 0)) {
31539c2c14abSThejaswini Singarajipura tidyup();
31549c2c14abSThejaswini Singarajipura bail(dgettext(TEXT_DOMAIN, "Replay Value"));
31559c2c14abSThejaswini Singarajipura }
31569c2c14abSThejaswini Singarajipura if (fprintf(ofile, "replay_value %" PRIu64 "",
31579c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay32 == 0 ?
31589c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay64 :
31599c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay32)) < 0) {
31609c2c14abSThejaswini Singarajipura tidyup();
31619c2c14abSThejaswini Singarajipura bail(dgettext(TEXT_DOMAIN,
31629c2c14abSThejaswini Singarajipura "save_assoc: fprintf replay value"));
31639c2c14abSThejaswini Singarajipura }
31649c2c14abSThejaswini Singarajipura savenl();
31659c2c14abSThejaswini Singarajipura break;
31668810c16bSdanmcd case SADB_EXT_SENSITIVITY:
31675d3b8cb7SBill Sommerfeld case SADB_X_EXT_OUTER_SENS:
31685d3b8cb7SBill Sommerfeld if (!save_sens((struct sadb_sens *)ext, ofile)) {
31695d3b8cb7SBill Sommerfeld tidyup();
31705d3b8cb7SBill Sommerfeld bail(dgettext(TEXT_DOMAIN, "save_sens"));
31715d3b8cb7SBill Sommerfeld }
31725d3b8cb7SBill Sommerfeld savenl();
31735d3b8cb7SBill Sommerfeld break;
31748810c16bSdanmcd default:
31758810c16bSdanmcd /* Skip over irrelevant extensions. */
31768810c16bSdanmcd break;
31778810c16bSdanmcd }
31788810c16bSdanmcd current += ext->sadb_ext_len;
31798810c16bSdanmcd }
31808810c16bSdanmcd
3181a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "\n# end assoc\n\n"), ofile) == EOF) {
3182a7485808Smarkfen tidyup();
3183a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: last fputs"));
3184a7485808Smarkfen }
31858810c16bSdanmcd }
31868810c16bSdanmcd
31878810c16bSdanmcd /*
31888810c16bSdanmcd * Open the output file for the "save" command.
31898810c16bSdanmcd */
31908810c16bSdanmcd FILE *
opensavefile(char * filename)31918810c16bSdanmcd opensavefile(char *filename)
31928810c16bSdanmcd {
31938810c16bSdanmcd int fd;
31948810c16bSdanmcd FILE *retval;
31958810c16bSdanmcd struct stat buf;
31968810c16bSdanmcd
31978810c16bSdanmcd /*
31988810c16bSdanmcd * If the user specifies "-" or doesn't give a filename, then
31998810c16bSdanmcd * dump to stdout. Make sure to document the dangers of files
32008810c16bSdanmcd * that are NFS, directing your output to strange places, etc.
32018810c16bSdanmcd */
32028810c16bSdanmcd if (filename == NULL || strcmp("-", filename) == 0)
32038810c16bSdanmcd return (stdout);
32048810c16bSdanmcd
32058810c16bSdanmcd /*
32068810c16bSdanmcd * open the file with the create bits set. Since I check for
32078810c16bSdanmcd * real UID == root in main(), I won't worry about the ownership
32088810c16bSdanmcd * problem.
32098810c16bSdanmcd */
32108810c16bSdanmcd fd = open(filename, O_WRONLY | O_EXCL | O_CREAT | O_TRUNC, S_IRUSR);
32118810c16bSdanmcd if (fd == -1) {
32128810c16bSdanmcd if (errno != EEXIST)
3213a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3214a7485808Smarkfen "open error"),
32158810c16bSdanmcd strerror(errno));
32168810c16bSdanmcd fd = open(filename, O_WRONLY | O_TRUNC, 0);
32178810c16bSdanmcd if (fd == -1)
3218a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3219a7485808Smarkfen "open error"), strerror(errno));
32208810c16bSdanmcd if (fstat(fd, &buf) == -1) {
32218810c16bSdanmcd (void) close(fd);
32228810c16bSdanmcd bail_msg("%s fstat: %s", filename, strerror(errno));
32238810c16bSdanmcd }
32248810c16bSdanmcd if (S_ISREG(buf.st_mode) &&
32258810c16bSdanmcd ((buf.st_mode & S_IAMB) != S_IRUSR)) {
3226a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
3227a7485808Smarkfen "WARNING: Save file already exists with "
32288810c16bSdanmcd "permission %o."), buf.st_mode & S_IAMB);
3229a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
3230a7485808Smarkfen "Normal users may be able to read IPsec "
32318810c16bSdanmcd "keying material."));
32328810c16bSdanmcd }
32338810c16bSdanmcd }
32348810c16bSdanmcd
32358810c16bSdanmcd /* Okay, we have an FD. Assign it to a stdio FILE pointer. */
32368810c16bSdanmcd retval = fdopen(fd, "w");
32378810c16bSdanmcd if (retval == NULL) {
32388810c16bSdanmcd (void) close(fd);
3239a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3240a7485808Smarkfen "fdopen error"), strerror(errno));
32418810c16bSdanmcd }
32428810c16bSdanmcd return (retval);
32438810c16bSdanmcd }
32448810c16bSdanmcd
32458810c16bSdanmcd const char *
do_inet_ntop(const void * addr,char * cp,size_t size)32468810c16bSdanmcd do_inet_ntop(const void *addr, char *cp, size_t size)
32478810c16bSdanmcd {
32488810c16bSdanmcd boolean_t isv4;
32498810c16bSdanmcd struct in6_addr *inaddr6 = (struct in6_addr *)addr;
32508810c16bSdanmcd struct in_addr inaddr;
32518810c16bSdanmcd
32528810c16bSdanmcd if ((isv4 = IN6_IS_ADDR_V4MAPPED(inaddr6)) == B_TRUE) {
32538810c16bSdanmcd IN6_V4MAPPED_TO_INADDR(inaddr6, &inaddr);
32548810c16bSdanmcd }
32558810c16bSdanmcd
32568810c16bSdanmcd return (inet_ntop(isv4 ? AF_INET : AF_INET6,
32578810c16bSdanmcd isv4 ? (void *)&inaddr : inaddr6, cp, size));
32588810c16bSdanmcd }
32598810c16bSdanmcd
32608810c16bSdanmcd char numprint[NBUF_SIZE];
32618810c16bSdanmcd
32628810c16bSdanmcd /*
32638810c16bSdanmcd * Parse and reverse parse a specific SA type (AH, ESP, etc.).
32648810c16bSdanmcd */
32658810c16bSdanmcd static struct typetable {
32668810c16bSdanmcd char *type;
32678810c16bSdanmcd int token;
32688810c16bSdanmcd } type_table[] = {
32698810c16bSdanmcd {"all", SADB_SATYPE_UNSPEC},
32708810c16bSdanmcd {"ah", SADB_SATYPE_AH},
32718810c16bSdanmcd {"esp", SADB_SATYPE_ESP},
32728810c16bSdanmcd /* PF_KEY NOTE: More to come if net/pfkeyv2.h gets updated. */
32738810c16bSdanmcd {NULL, 0} /* Token value is irrelevant for this entry. */
32748810c16bSdanmcd };
32758810c16bSdanmcd
32768810c16bSdanmcd char *
rparsesatype(int type)32778810c16bSdanmcd rparsesatype(int type)
32788810c16bSdanmcd {
32798810c16bSdanmcd struct typetable *tt = type_table;
32808810c16bSdanmcd
32818810c16bSdanmcd while (tt->type != NULL && type != tt->token)
32828810c16bSdanmcd tt++;
32838810c16bSdanmcd
32848810c16bSdanmcd if (tt->type == NULL) {
32858810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type);
32868810c16bSdanmcd } else {
32878810c16bSdanmcd return (tt->type);
32888810c16bSdanmcd }
32898810c16bSdanmcd
32908810c16bSdanmcd return (numprint);
32918810c16bSdanmcd }
32928810c16bSdanmcd
32938810c16bSdanmcd
32948810c16bSdanmcd /*
32958810c16bSdanmcd * Return a string containing the name of the specified numerical algorithm
32968810c16bSdanmcd * identifier.
32978810c16bSdanmcd */
32988810c16bSdanmcd char *
rparsealg(uint8_t alg,int proto_num)32998810c16bSdanmcd rparsealg(uint8_t alg, int proto_num)
33008810c16bSdanmcd {
33018810c16bSdanmcd static struct ipsecalgent *holder = NULL; /* we're single-threaded */
33028810c16bSdanmcd
33038810c16bSdanmcd if (holder != NULL)
33048810c16bSdanmcd freeipsecalgent(holder);
33058810c16bSdanmcd
33068810c16bSdanmcd holder = getipsecalgbynum(alg, proto_num, NULL);
33078810c16bSdanmcd if (holder == NULL) {
33088810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", alg);
33098810c16bSdanmcd return (numprint);
33108810c16bSdanmcd }
33118810c16bSdanmcd
33128810c16bSdanmcd return (*(holder->a_names));
33138810c16bSdanmcd }
33148810c16bSdanmcd
33158810c16bSdanmcd /*
33168810c16bSdanmcd * Parse and reverse parse out a source/destination ID type.
33178810c16bSdanmcd */
33188810c16bSdanmcd static struct idtypes {
33198810c16bSdanmcd char *idtype;
33208810c16bSdanmcd uint8_t retval;
33218810c16bSdanmcd } idtypes[] = {
33228810c16bSdanmcd {"prefix", SADB_IDENTTYPE_PREFIX},
33238810c16bSdanmcd {"fqdn", SADB_IDENTTYPE_FQDN},
33248810c16bSdanmcd {"domain", SADB_IDENTTYPE_FQDN},
33258810c16bSdanmcd {"domainname", SADB_IDENTTYPE_FQDN},
33268810c16bSdanmcd {"user_fqdn", SADB_IDENTTYPE_USER_FQDN},
33278810c16bSdanmcd {"mailbox", SADB_IDENTTYPE_USER_FQDN},
33288810c16bSdanmcd {"der_dn", SADB_X_IDENTTYPE_DN},
33298810c16bSdanmcd {"der_gn", SADB_X_IDENTTYPE_GN},
33308810c16bSdanmcd {NULL, 0}
33318810c16bSdanmcd };
33328810c16bSdanmcd
33338810c16bSdanmcd char *
rparseidtype(uint16_t type)33348810c16bSdanmcd rparseidtype(uint16_t type)
33358810c16bSdanmcd {
33368810c16bSdanmcd struct idtypes *idp;
33378810c16bSdanmcd
33388810c16bSdanmcd for (idp = idtypes; idp->idtype != NULL; idp++) {
33398810c16bSdanmcd if (type == idp->retval)
33408810c16bSdanmcd return (idp->idtype);
33418810c16bSdanmcd }
33428810c16bSdanmcd
33438810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type);
33448810c16bSdanmcd return (numprint);
33458810c16bSdanmcd }
3346e3320f40Smarkfen
3347e3320f40Smarkfen /*
3348e3320f40Smarkfen * This is a general purpose exit function, calling functions can specify an
3349e3320f40Smarkfen * error type. If the command calling this function was started by smf(5) the
3350e3320f40Smarkfen * error type could be used as a hint to the restarter. In the future this
3351e3320f40Smarkfen * function could be used to do something more intelligent with a process that
3352a1ba8781SMark Fenwick * encounters an error. If exit() is called with an error code other than those
3353a1ba8781SMark Fenwick * defined by smf(5), the program will just get restarted. Unless restarting
3354a1ba8781SMark Fenwick * is likely to resolve the error condition, its probably sensible to just
3355a1ba8781SMark Fenwick * log the error and keep running.
3356a1ba8781SMark Fenwick *
3357a1ba8781SMark Fenwick * The SERVICE_* exit_types mean nothing if the command was run from the
3358a1ba8781SMark Fenwick * command line, just exit(). There are two special cases:
3359a1ba8781SMark Fenwick *
3360a1ba8781SMark Fenwick * SERVICE_DEGRADE - Not implemented in smf(5), one day it could hint that
3361a1ba8781SMark Fenwick * the service is not running as well is it could. For
3362a1ba8781SMark Fenwick * now, don't do anything, just record the error.
3363a1ba8781SMark Fenwick * DEBUG_FATAL - Something happened, if the command was being run in debug
3364a1ba8781SMark Fenwick * mode, exit() as you really want to know something happened,
3365a1ba8781SMark Fenwick * otherwise just keep running. This is ignored when running
3366a1ba8781SMark Fenwick * under smf(5).
3367e3320f40Smarkfen *
3368e3320f40Smarkfen * The function will handle an optional variable args error message, this
3369e3320f40Smarkfen * will be written to the error stream, typically a log file or stderr.
3370e3320f40Smarkfen */
3371e3320f40Smarkfen void
ipsecutil_exit(exit_type_t type,char * fmri,FILE * fp,const char * fmt,...)3372e3320f40Smarkfen ipsecutil_exit(exit_type_t type, char *fmri, FILE *fp, const char *fmt, ...)
3373e3320f40Smarkfen {
3374e3320f40Smarkfen int exit_status;
3375e3320f40Smarkfen va_list args;
3376e3320f40Smarkfen
3377e3320f40Smarkfen if (fp == NULL)
3378e3320f40Smarkfen fp = stderr;
3379e3320f40Smarkfen if (fmt != NULL) {
3380e3320f40Smarkfen va_start(args, fmt);
3381e3320f40Smarkfen vwarnxfp(fp, fmt, args);
3382e3320f40Smarkfen va_end(args);
3383e3320f40Smarkfen }
3384e3320f40Smarkfen
3385e3320f40Smarkfen if (fmri == NULL) {
3386e3320f40Smarkfen /* Command being run directly from a shell. */
3387e3320f40Smarkfen switch (type) {
3388e3320f40Smarkfen case SERVICE_EXIT_OK:
3389e3320f40Smarkfen exit_status = 0;
3390e3320f40Smarkfen break;
3391e3320f40Smarkfen case SERVICE_DEGRADE:
3392e3320f40Smarkfen return;
3393e3320f40Smarkfen case SERVICE_BADPERM:
3394e3320f40Smarkfen case SERVICE_BADCONF:
3395e3320f40Smarkfen case SERVICE_MAINTAIN:
3396e3320f40Smarkfen case SERVICE_DISABLE:
3397e3320f40Smarkfen case SERVICE_FATAL:
3398e3320f40Smarkfen case SERVICE_RESTART:
3399a1ba8781SMark Fenwick case DEBUG_FATAL:
3400e3320f40Smarkfen warnxfp(fp, "Fatal error - exiting.");
3401e3320f40Smarkfen exit_status = 1;
3402e3320f40Smarkfen break;
3403e3320f40Smarkfen }
3404e3320f40Smarkfen } else {
3405e3320f40Smarkfen /* Command being run as a smf(5) method. */
3406e3320f40Smarkfen switch (type) {
3407e3320f40Smarkfen case SERVICE_EXIT_OK:
3408e3320f40Smarkfen exit_status = SMF_EXIT_OK;
3409e3320f40Smarkfen break;
3410a1ba8781SMark Fenwick case SERVICE_DEGRADE: /* Not implemented yet. */
3411a1ba8781SMark Fenwick case DEBUG_FATAL:
3412a1ba8781SMark Fenwick /* Keep running, don't exit(). */
3413e3320f40Smarkfen return;
3414e3320f40Smarkfen case SERVICE_BADPERM:
3415e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3416e3320f40Smarkfen "Permission error with %s."), fmri);
3417e3320f40Smarkfen exit_status = SMF_EXIT_ERR_PERM;
3418e3320f40Smarkfen break;
3419e3320f40Smarkfen case SERVICE_BADCONF:
3420e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3421e3320f40Smarkfen "Bad configuration of service %s."), fmri);
3422e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3423e3320f40Smarkfen break;
3424e3320f40Smarkfen case SERVICE_MAINTAIN:
3425e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3426e3320f40Smarkfen "Service %s needs maintenance."), fmri);
3427e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3428e3320f40Smarkfen break;
3429e3320f40Smarkfen case SERVICE_DISABLE:
3430e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3431e3320f40Smarkfen break;
3432e3320f40Smarkfen case SERVICE_FATAL:
3433e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3434e3320f40Smarkfen "Service %s fatal error."), fmri);
3435e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3436e3320f40Smarkfen break;
3437e3320f40Smarkfen case SERVICE_RESTART:
3438e3320f40Smarkfen exit_status = 1;
3439e3320f40Smarkfen break;
3440e3320f40Smarkfen }
3441e3320f40Smarkfen }
3442e3320f40Smarkfen (void) fflush(fp);
3443e3320f40Smarkfen (void) fclose(fp);
3444e3320f40Smarkfen exit(exit_status);
3445e3320f40Smarkfen }
3446