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.
2533f5ff17SMilan Jurik * Copyright 2012 Milan Juri. All rights reserved.
26351128adSJason King * Copyright 2018 Joyent, Inc.
27bdc560abSJason King * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <stdarg.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/stat.h>
367c478bd9Sstevel@tonic-gate #include <fcntl.h>
377c478bd9Sstevel@tonic-gate #include <sys/sysconf.h>
387c478bd9Sstevel@tonic-gate #include <strings.h>
397c478bd9Sstevel@tonic-gate #include <ctype.h>
407c478bd9Sstevel@tonic-gate #include <errno.h>
417c478bd9Sstevel@tonic-gate #include <sys/socket.h>
427c478bd9Sstevel@tonic-gate #include <netdb.h>
437c478bd9Sstevel@tonic-gate #include <netinet/in.h>
447c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
457c478bd9Sstevel@tonic-gate #include <net/pfkeyv2.h>
467c478bd9Sstevel@tonic-gate #include <net/pfpolicy.h>
477c478bd9Sstevel@tonic-gate #include <libintl.h>
487c478bd9Sstevel@tonic-gate #include <setjmp.h>
497c478bd9Sstevel@tonic-gate #include <libgen.h>
50e3320f40Smarkfen #include <libscf.h>
51bdc560abSJason King #include <kmfapi.h>
52bdc560abSJason King #include <ber_der.h>
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate #include "ipsec_util.h"
557c478bd9Sstevel@tonic-gate #include "ikedoor.h"
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate /*
587c478bd9Sstevel@tonic-gate * This file contains support functions that are shared by the ipsec
59*bbf21555SRichard Lowe * utilities and daemons including ipseckey(8), ikeadm(8) and in.iked(8).
607c478bd9Sstevel@tonic-gate */
617c478bd9Sstevel@tonic-gate
62bb3ed8dfSpwernau
63bb3ed8dfSpwernau #define EFD(file) (((file) == stdout) ? stderr : (file))
64bb3ed8dfSpwernau
65bfe6f8f5SVladimir Kotal /* Limits for interactive mode. */
66bfe6f8f5SVladimir Kotal #define MAX_LINE_LEN IBUF_SIZE
67bfe6f8f5SVladimir Kotal #define MAX_CMD_HIST 64000 /* in bytes */
68bfe6f8f5SVladimir Kotal
697c478bd9Sstevel@tonic-gate /* Set standard default/initial values for globals... */
707c478bd9Sstevel@tonic-gate boolean_t pflag = B_FALSE; /* paranoid w.r.t. printing keying material */
717c478bd9Sstevel@tonic-gate boolean_t nflag = B_FALSE; /* avoid nameservice? */
727c478bd9Sstevel@tonic-gate boolean_t interactive = B_FALSE; /* util not running on cmdline */
737c478bd9Sstevel@tonic-gate boolean_t readfile = B_FALSE; /* cmds are being read from a file */
747c478bd9Sstevel@tonic-gate uint_t lineno = 0; /* track location if reading cmds from file */
75e3320f40Smarkfen uint_t lines_added = 0;
76e3320f40Smarkfen uint_t lines_parsed = 0;
777c478bd9Sstevel@tonic-gate jmp_buf env; /* for error recovery in interactive/readfile modes */
78e3320f40Smarkfen char *my_fmri = NULL;
79e3320f40Smarkfen FILE *debugfile = stderr;
80bfe6f8f5SVladimir Kotal static GetLine *gl = NULL; /* for interactive mode */
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate * Print errno and exit if cmdline or readfile, reset state if interactive
84a7485808Smarkfen * The error string *what should be dgettext()'d before calling bail().
857c478bd9Sstevel@tonic-gate */
867c478bd9Sstevel@tonic-gate void
bail(char * what)877c478bd9Sstevel@tonic-gate bail(char *what)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate if (errno != 0)
907c478bd9Sstevel@tonic-gate warn(what);
917c478bd9Sstevel@tonic-gate else
92e3320f40Smarkfen warnx(dgettext(TEXT_DOMAIN, "Error: %s"), what);
937c478bd9Sstevel@tonic-gate if (readfile) {
94e3320f40Smarkfen return;
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate if (interactive && !readfile)
977c478bd9Sstevel@tonic-gate longjmp(env, 2);
98e3320f40Smarkfen EXIT_FATAL(NULL);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * Print caller-supplied variable-arg error msg, then exit if cmdline or
1037c478bd9Sstevel@tonic-gate * readfile, or reset state if interactive.
1047c478bd9Sstevel@tonic-gate */
1057c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
1067c478bd9Sstevel@tonic-gate void
bail_msg(char * fmt,...)1077c478bd9Sstevel@tonic-gate bail_msg(char *fmt, ...)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate va_list ap;
1107c478bd9Sstevel@tonic-gate char msgbuf[BUFSIZ];
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate va_start(ap, fmt);
1137c478bd9Sstevel@tonic-gate (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap);
1147c478bd9Sstevel@tonic-gate va_end(ap);
1157c478bd9Sstevel@tonic-gate if (readfile)
116a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
117a7485808Smarkfen "ERROR on line %u:\n%s\n"), lineno, msgbuf);
1187c478bd9Sstevel@tonic-gate else
119a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN, "ERROR: %s\n"), msgbuf);
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate if (interactive && !readfile)
1227c478bd9Sstevel@tonic-gate longjmp(env, 1);
1237c478bd9Sstevel@tonic-gate
124e3320f40Smarkfen EXIT_FATAL(NULL);
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
127510c3f91SVladimir Kotal /*
128510c3f91SVladimir Kotal * bytecnt2str() wrapper. Zeroes out the input buffer and if the number
129510c3f91SVladimir Kotal * of bytes to be converted is more than 1K, it will produce readable string
130510c3f91SVladimir Kotal * in parentheses, store it in the original buffer and return the pointer to it.
131510c3f91SVladimir Kotal * Maximum length of the returned string is 14 characters (not including
132510c3f91SVladimir Kotal * the terminating zero).
133510c3f91SVladimir Kotal */
134510c3f91SVladimir Kotal char *
bytecnt2out(uint64_t num,char * buf,size_t bufsiz,int flags)135510c3f91SVladimir Kotal bytecnt2out(uint64_t num, char *buf, size_t bufsiz, int flags)
136510c3f91SVladimir Kotal {
137510c3f91SVladimir Kotal char *str;
138510c3f91SVladimir Kotal
139510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
140510c3f91SVladimir Kotal
141510c3f91SVladimir Kotal if (num > 1024) {
142510c3f91SVladimir Kotal /* Return empty string in case of out-of-memory. */
143510c3f91SVladimir Kotal if ((str = malloc(bufsiz)) == NULL)
144510c3f91SVladimir Kotal return (buf);
145510c3f91SVladimir Kotal
146510c3f91SVladimir Kotal (void) bytecnt2str(num, str, bufsiz);
147510c3f91SVladimir Kotal /* Detect overflow. */
148510c3f91SVladimir Kotal if (strlen(str) == 0) {
149510c3f91SVladimir Kotal free(str);
150510c3f91SVladimir Kotal return (buf);
151510c3f91SVladimir Kotal }
152510c3f91SVladimir Kotal
153510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
154510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%s(%sB)%s",
155510c3f91SVladimir Kotal flags & SPC_BEGIN ? " " : "", str,
156510c3f91SVladimir Kotal flags & SPC_END ? " " : "") >= bufsiz)
157510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
158510c3f91SVladimir Kotal
159510c3f91SVladimir Kotal free(str);
160510c3f91SVladimir Kotal }
161510c3f91SVladimir Kotal
162510c3f91SVladimir Kotal return (buf);
163510c3f91SVladimir Kotal }
164510c3f91SVladimir Kotal
165510c3f91SVladimir Kotal /*
166510c3f91SVladimir Kotal * Convert 64-bit number to human readable string. Useful mainly for the
167510c3f91SVladimir Kotal * byte lifetime counters. Returns pointer to the user supplied buffer.
168510c3f91SVladimir Kotal * Able to convert up to Exabytes. Maximum length of the string produced
169510c3f91SVladimir Kotal * is 9 characters (not counting the terminating zero).
170510c3f91SVladimir Kotal */
171510c3f91SVladimir Kotal char *
bytecnt2str(uint64_t num,char * buf,size_t buflen)172510c3f91SVladimir Kotal bytecnt2str(uint64_t num, char *buf, size_t buflen)
173510c3f91SVladimir Kotal {
174510c3f91SVladimir Kotal uint64_t n = num;
175510c3f91SVladimir Kotal char u;
176510c3f91SVladimir Kotal int index = 0;
177510c3f91SVladimir Kotal
178510c3f91SVladimir Kotal while (n >= 1024) {
179510c3f91SVladimir Kotal n /= 1024;
180510c3f91SVladimir Kotal index++;
181510c3f91SVladimir Kotal }
182510c3f91SVladimir Kotal
183510c3f91SVladimir Kotal /* The field has all units this function can represent. */
184510c3f91SVladimir Kotal u = " KMGTPE"[index];
185510c3f91SVladimir Kotal
186510c3f91SVladimir Kotal if (index == 0) {
187510c3f91SVladimir Kotal /* Less than 1K */
188510c3f91SVladimir Kotal if (snprintf(buf, buflen, "%llu ", num) >= buflen)
189510c3f91SVladimir Kotal (void) memset(buf, '\0', buflen);
190510c3f91SVladimir Kotal } else {
191510c3f91SVladimir Kotal /* Otherwise display 2 precision digits. */
192510c3f91SVladimir Kotal if (snprintf(buf, buflen, "%.2f %c",
193510c3f91SVladimir Kotal (double)num / (1ULL << index * 10), u) >= buflen)
194510c3f91SVladimir Kotal (void) memset(buf, '\0', buflen);
195510c3f91SVladimir Kotal }
196510c3f91SVladimir Kotal
197510c3f91SVladimir Kotal return (buf);
198510c3f91SVladimir Kotal }
199510c3f91SVladimir Kotal
200510c3f91SVladimir Kotal /*
201510c3f91SVladimir Kotal * secs2str() wrapper. Zeroes out the input buffer and if the number of
202510c3f91SVladimir Kotal * seconds to be converted is more than minute, it will produce readable
203510c3f91SVladimir Kotal * string in parentheses, store it in the original buffer and return the
204510c3f91SVladimir Kotal * pointer to it.
205510c3f91SVladimir Kotal */
206510c3f91SVladimir Kotal char *
secs2out(unsigned int secs,char * buf,int bufsiz,int flags)207510c3f91SVladimir Kotal secs2out(unsigned int secs, char *buf, int bufsiz, int flags)
208510c3f91SVladimir Kotal {
209510c3f91SVladimir Kotal char *str;
210510c3f91SVladimir Kotal
211510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
212510c3f91SVladimir Kotal
213510c3f91SVladimir Kotal if (secs > 60) {
214510c3f91SVladimir Kotal /* Return empty string in case of out-of-memory. */
215510c3f91SVladimir Kotal if ((str = malloc(bufsiz)) == NULL)
216510c3f91SVladimir Kotal return (buf);
217510c3f91SVladimir Kotal
218510c3f91SVladimir Kotal (void) secs2str(secs, str, bufsiz);
219510c3f91SVladimir Kotal /* Detect overflow. */
220510c3f91SVladimir Kotal if (strlen(str) == 0) {
221510c3f91SVladimir Kotal free(str);
222510c3f91SVladimir Kotal return (buf);
223510c3f91SVladimir Kotal }
224510c3f91SVladimir Kotal
225510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
226510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%s(%s)%s",
227510c3f91SVladimir Kotal flags & SPC_BEGIN ? " " : "", str,
228510c3f91SVladimir Kotal flags & SPC_END ? " " : "") >= bufsiz)
229510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
230510c3f91SVladimir Kotal
231510c3f91SVladimir Kotal free(str);
232510c3f91SVladimir Kotal }
233510c3f91SVladimir Kotal
234510c3f91SVladimir Kotal return (buf);
235510c3f91SVladimir Kotal }
236510c3f91SVladimir Kotal
237510c3f91SVladimir Kotal /*
238510c3f91SVladimir Kotal * Convert number of seconds to human readable string. Useful mainly for
239510c3f91SVladimir Kotal * the lifetime counters. Returns pointer to the user supplied buffer.
240510c3f91SVladimir Kotal * Able to convert up to days.
241510c3f91SVladimir Kotal */
242510c3f91SVladimir Kotal char *
secs2str(unsigned int secs,char * buf,int bufsiz)243510c3f91SVladimir Kotal secs2str(unsigned int secs, char *buf, int bufsiz)
244510c3f91SVladimir Kotal {
245510c3f91SVladimir Kotal double val = secs;
246510c3f91SVladimir Kotal char *unit = "second";
247510c3f91SVladimir Kotal
248510c3f91SVladimir Kotal if (val >= 24*60*60) {
249510c3f91SVladimir Kotal val /= 86400;
250510c3f91SVladimir Kotal unit = "day";
251510c3f91SVladimir Kotal } else if (val >= 60*60) {
252510c3f91SVladimir Kotal val /= 60*60;
253510c3f91SVladimir Kotal unit = "hour";
254510c3f91SVladimir Kotal } else if (val >= 60) {
255510c3f91SVladimir Kotal val /= 60;
256510c3f91SVladimir Kotal unit = "minute";
257510c3f91SVladimir Kotal }
258510c3f91SVladimir Kotal
259510c3f91SVladimir Kotal /* Emit nothing in case of overflow. */
260510c3f91SVladimir Kotal if (snprintf(buf, bufsiz, "%.2f %s%s", val, unit,
261510c3f91SVladimir Kotal val >= 2 ? "s" : "") >= bufsiz)
262510c3f91SVladimir Kotal (void) memset(buf, '\0', bufsiz);
263510c3f91SVladimir Kotal
264510c3f91SVladimir Kotal return (buf);
265510c3f91SVladimir Kotal }
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate /*
2687c478bd9Sstevel@tonic-gate * dump_XXX functions produce ASCII output from various structures.
2697c478bd9Sstevel@tonic-gate *
2707c478bd9Sstevel@tonic-gate * Because certain errors need to do this to stderr, dump_XXX functions
2717c478bd9Sstevel@tonic-gate * take a FILE pointer.
2727c478bd9Sstevel@tonic-gate *
2737c478bd9Sstevel@tonic-gate * If an error occured while writing to the specified file, these
2747c478bd9Sstevel@tonic-gate * functions return -1, zero otherwise.
2757c478bd9Sstevel@tonic-gate */
2767c478bd9Sstevel@tonic-gate
2777c478bd9Sstevel@tonic-gate int
dump_sockaddr(struct sockaddr * sa,uint8_t prefixlen,boolean_t addr_only,FILE * where,boolean_t ignore_nss)2788810c16bSdanmcd dump_sockaddr(struct sockaddr *sa, uint8_t prefixlen, boolean_t addr_only,
279bb3ed8dfSpwernau FILE *where, boolean_t ignore_nss)
2807c478bd9Sstevel@tonic-gate {
2817c478bd9Sstevel@tonic-gate struct sockaddr_in *sin;
2827c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6;
2837c478bd9Sstevel@tonic-gate char *printable_addr, *protocol;
2847c478bd9Sstevel@tonic-gate uint8_t *addrptr;
2858810c16bSdanmcd /* Add 4 chars to hold '/nnn' for prefixes. */
2868810c16bSdanmcd char storage[INET6_ADDRSTRLEN + 4];
2877c478bd9Sstevel@tonic-gate uint16_t port;
2887c478bd9Sstevel@tonic-gate boolean_t unspec;
2897c478bd9Sstevel@tonic-gate struct hostent *hp;
2907c478bd9Sstevel@tonic-gate int getipnode_errno, addrlen;
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate switch (sa->sa_family) {
2937c478bd9Sstevel@tonic-gate case AF_INET:
2947c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
2957c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)sa;
2967c478bd9Sstevel@tonic-gate addrptr = (uint8_t *)&sin->sin_addr;
2977c478bd9Sstevel@tonic-gate port = sin->sin_port;
2987c478bd9Sstevel@tonic-gate protocol = "AF_INET";
2997c478bd9Sstevel@tonic-gate unspec = (sin->sin_addr.s_addr == 0);
3007c478bd9Sstevel@tonic-gate addrlen = sizeof (sin->sin_addr);
3017c478bd9Sstevel@tonic-gate break;
3027c478bd9Sstevel@tonic-gate case AF_INET6:
3037c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
3047c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)sa;
3057c478bd9Sstevel@tonic-gate addrptr = (uint8_t *)&sin6->sin6_addr;
3067c478bd9Sstevel@tonic-gate port = sin6->sin6_port;
3077c478bd9Sstevel@tonic-gate protocol = "AF_INET6";
3087c478bd9Sstevel@tonic-gate unspec = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr);
3097c478bd9Sstevel@tonic-gate addrlen = sizeof (sin6->sin6_addr);
3107c478bd9Sstevel@tonic-gate break;
3117c478bd9Sstevel@tonic-gate default:
3127c478bd9Sstevel@tonic-gate return (0);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate if (inet_ntop(sa->sa_family, addrptr, storage, INET6_ADDRSTRLEN) ==
3167c478bd9Sstevel@tonic-gate NULL) {
317a7485808Smarkfen printable_addr = dgettext(TEXT_DOMAIN, "Invalid IP address.");
3187c478bd9Sstevel@tonic-gate } else {
3198810c16bSdanmcd char prefix[5]; /* "/nnn" with terminator. */
3208810c16bSdanmcd
3218810c16bSdanmcd (void) snprintf(prefix, sizeof (prefix), "/%d", prefixlen);
3227c478bd9Sstevel@tonic-gate printable_addr = storage;
3238810c16bSdanmcd if (prefixlen != 0) {
3248810c16bSdanmcd (void) strlcat(printable_addr, prefix,
3258810c16bSdanmcd sizeof (storage));
3268810c16bSdanmcd }
3277c478bd9Sstevel@tonic-gate }
3287c478bd9Sstevel@tonic-gate if (addr_only) {
3297c478bd9Sstevel@tonic-gate if (fprintf(where, "%s", printable_addr) < 0)
3307c478bd9Sstevel@tonic-gate return (-1);
3317c478bd9Sstevel@tonic-gate } else {
332a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
333a7485808Smarkfen "%s: port %d, %s"), protocol,
3347c478bd9Sstevel@tonic-gate ntohs(port), printable_addr) < 0)
3357c478bd9Sstevel@tonic-gate return (-1);
336bb3ed8dfSpwernau if (ignore_nss == B_FALSE) {
3377c478bd9Sstevel@tonic-gate /*
3387c478bd9Sstevel@tonic-gate * Do AF_independent reverse hostname lookup here.
3397c478bd9Sstevel@tonic-gate */
3407c478bd9Sstevel@tonic-gate if (unspec) {
3417c478bd9Sstevel@tonic-gate if (fprintf(where,
342a7485808Smarkfen dgettext(TEXT_DOMAIN,
343a7485808Smarkfen " <unspecified>")) < 0)
3447c478bd9Sstevel@tonic-gate return (-1);
3457c478bd9Sstevel@tonic-gate } else {
3467c478bd9Sstevel@tonic-gate hp = getipnodebyaddr((char *)addrptr, addrlen,
3477c478bd9Sstevel@tonic-gate sa->sa_family, &getipnode_errno);
3487c478bd9Sstevel@tonic-gate if (hp != NULL) {
3497c478bd9Sstevel@tonic-gate if (fprintf(where,
3507c478bd9Sstevel@tonic-gate " (%s)", hp->h_name) < 0)
3517c478bd9Sstevel@tonic-gate return (-1);
3527c478bd9Sstevel@tonic-gate freehostent(hp);
3537c478bd9Sstevel@tonic-gate } else {
3547c478bd9Sstevel@tonic-gate if (fprintf(where,
355a7485808Smarkfen dgettext(TEXT_DOMAIN,
356a7485808Smarkfen " <unknown>")) < 0)
3577c478bd9Sstevel@tonic-gate return (-1);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate if (fputs(".\n", where) == EOF)
3627c478bd9Sstevel@tonic-gate return (-1);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate return (0);
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate /*
368628b0c67SMark Fenwick * Dump a key, any salt and bitlen.
369628b0c67SMark Fenwick * The key is made up of a stream of bits. If the algorithm requires a salt
370628b0c67SMark Fenwick * value, this will also be part of the dumped key. The last "saltbits" of the
371628b0c67SMark Fenwick * key string, reading left to right will be the salt value. To make it easier
372628b0c67SMark Fenwick * to see which bits make up the key, the salt value is enclosed in []'s.
373*bbf21555SRichard Lowe * This function can also be called when ipseckey(8) -s is run, this "saves"
374628b0c67SMark Fenwick * the SAs, including the key to a file. When this is the case, the []'s are
375628b0c67SMark Fenwick * not printed.
376628b0c67SMark Fenwick *
377628b0c67SMark Fenwick * The implementation allows the kernel to be told about the length of the salt
378628b0c67SMark Fenwick * in whole bytes only. If this changes, this function will need to be updated.
3797c478bd9Sstevel@tonic-gate */
3807c478bd9Sstevel@tonic-gate int
dump_key(uint8_t * keyp,uint_t bitlen,uint_t saltbits,FILE * where,boolean_t separate_salt)381628b0c67SMark Fenwick dump_key(uint8_t *keyp, uint_t bitlen, uint_t saltbits, FILE *where,
382628b0c67SMark Fenwick boolean_t separate_salt)
3837c478bd9Sstevel@tonic-gate {
384628b0c67SMark Fenwick int numbytes, saltbytes;
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate numbytes = SADB_1TO8(bitlen);
387628b0c67SMark Fenwick saltbytes = SADB_1TO8(saltbits);
388628b0c67SMark Fenwick numbytes += saltbytes;
389628b0c67SMark Fenwick
3907c478bd9Sstevel@tonic-gate /* The & 0x7 is to check for leftover bits. */
3917c478bd9Sstevel@tonic-gate if ((bitlen & 0x7) != 0)
3927c478bd9Sstevel@tonic-gate numbytes++;
393628b0c67SMark Fenwick
3947c478bd9Sstevel@tonic-gate while (numbytes-- != 0) {
3957c478bd9Sstevel@tonic-gate if (pflag) {
3967c478bd9Sstevel@tonic-gate /* Print no keys if paranoid */
3977c478bd9Sstevel@tonic-gate if (fprintf(where, "XX") < 0)
3987c478bd9Sstevel@tonic-gate return (-1);
3997c478bd9Sstevel@tonic-gate } else {
4007c478bd9Sstevel@tonic-gate if (fprintf(where, "%02x", *keyp++) < 0)
4017c478bd9Sstevel@tonic-gate return (-1);
4027c478bd9Sstevel@tonic-gate }
403628b0c67SMark Fenwick if (separate_salt && saltbytes != 0 &&
404628b0c67SMark Fenwick numbytes == saltbytes) {
405628b0c67SMark Fenwick if (fprintf(where, "[") < 0)
406628b0c67SMark Fenwick return (-1);
407628b0c67SMark Fenwick }
4087c478bd9Sstevel@tonic-gate }
409628b0c67SMark Fenwick
410628b0c67SMark Fenwick if (separate_salt && saltbits != 0) {
411628b0c67SMark Fenwick if (fprintf(where, "]/%u+%u", bitlen, saltbits) < 0)
412628b0c67SMark Fenwick return (-1);
413628b0c67SMark Fenwick } else {
414628b0c67SMark Fenwick if (fprintf(where, "/%u", bitlen + saltbits) < 0)
415628b0c67SMark Fenwick return (-1);
416628b0c67SMark Fenwick }
417628b0c67SMark Fenwick
4187c478bd9Sstevel@tonic-gate return (0);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate /*
4227c478bd9Sstevel@tonic-gate * Print an authentication or encryption algorithm
4237c478bd9Sstevel@tonic-gate */
4247c478bd9Sstevel@tonic-gate static int
dump_generic_alg(uint8_t alg_num,int proto_num,FILE * where)4257c478bd9Sstevel@tonic-gate dump_generic_alg(uint8_t alg_num, int proto_num, FILE *where)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate struct ipsecalgent *alg;
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate alg = getipsecalgbynum(alg_num, proto_num, NULL);
4307c478bd9Sstevel@tonic-gate if (alg == NULL) {
431a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
432a7485808Smarkfen "<unknown %u>"), alg_num) < 0)
4337c478bd9Sstevel@tonic-gate return (-1);
4347c478bd9Sstevel@tonic-gate return (0);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate * Special-case <none> for backward output compat.
4397c478bd9Sstevel@tonic-gate * Assume that SADB_AALG_NONE == SADB_EALG_NONE.
4407c478bd9Sstevel@tonic-gate */
4417c478bd9Sstevel@tonic-gate if (alg_num == SADB_AALG_NONE) {
442a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN,
443a7485808Smarkfen "<none>"), where) == EOF)
4447c478bd9Sstevel@tonic-gate return (-1);
4457c478bd9Sstevel@tonic-gate } else {
4467c478bd9Sstevel@tonic-gate if (fputs(alg->a_names[0], where) == EOF)
4477c478bd9Sstevel@tonic-gate return (-1);
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate
4507c478bd9Sstevel@tonic-gate freeipsecalgent(alg);
4517c478bd9Sstevel@tonic-gate return (0);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate int
dump_aalg(uint8_t aalg,FILE * where)4557c478bd9Sstevel@tonic-gate dump_aalg(uint8_t aalg, FILE *where)
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate return (dump_generic_alg(aalg, IPSEC_PROTO_AH, where));
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate int
dump_ealg(uint8_t ealg,FILE * where)4617c478bd9Sstevel@tonic-gate dump_ealg(uint8_t ealg, FILE *where)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate return (dump_generic_alg(ealg, IPSEC_PROTO_ESP, where));
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gate /*
4677c478bd9Sstevel@tonic-gate * Print an SADB_IDENTTYPE string
4687c478bd9Sstevel@tonic-gate *
4697c478bd9Sstevel@tonic-gate * Also return TRUE if the actual ident may be printed, FALSE if not.
4707c478bd9Sstevel@tonic-gate *
4717c478bd9Sstevel@tonic-gate * If rc is not NULL, set its value to -1 if an error occured while writing
4727c478bd9Sstevel@tonic-gate * to the specified file, zero otherwise.
4737c478bd9Sstevel@tonic-gate */
4747c478bd9Sstevel@tonic-gate boolean_t
dump_sadb_idtype(uint8_t idtype,FILE * where,int * rc)4757c478bd9Sstevel@tonic-gate dump_sadb_idtype(uint8_t idtype, FILE *where, int *rc)
4767c478bd9Sstevel@tonic-gate {
4777c478bd9Sstevel@tonic-gate boolean_t canprint = B_TRUE;
4787c478bd9Sstevel@tonic-gate int rc_val = 0;
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate switch (idtype) {
4817c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_PREFIX:
482a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "prefix"), where) == EOF)
4837c478bd9Sstevel@tonic-gate rc_val = -1;
4847c478bd9Sstevel@tonic-gate break;
4857c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_FQDN:
486a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "FQDN"), where) == EOF)
4877c478bd9Sstevel@tonic-gate rc_val = -1;
4887c478bd9Sstevel@tonic-gate break;
4897c478bd9Sstevel@tonic-gate case SADB_IDENTTYPE_USER_FQDN:
490a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN,
491a7485808Smarkfen "user-FQDN (mbox)"), where) == EOF)
4927c478bd9Sstevel@tonic-gate rc_val = -1;
4937c478bd9Sstevel@tonic-gate break;
4947c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_DN:
495a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Distinguished Name"),
4967c478bd9Sstevel@tonic-gate where) == EOF)
4977c478bd9Sstevel@tonic-gate rc_val = -1;
4987c478bd9Sstevel@tonic-gate canprint = B_FALSE;
4997c478bd9Sstevel@tonic-gate break;
5007c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_GN:
501a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Generic Name"),
502a7485808Smarkfen where) == EOF)
5037c478bd9Sstevel@tonic-gate rc_val = -1;
5047c478bd9Sstevel@tonic-gate canprint = B_FALSE;
5057c478bd9Sstevel@tonic-gate break;
5067c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_KEY_ID:
507a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Generic key id"),
508a7485808Smarkfen where) == EOF)
5097c478bd9Sstevel@tonic-gate rc_val = -1;
5107c478bd9Sstevel@tonic-gate break;
5117c478bd9Sstevel@tonic-gate case SADB_X_IDENTTYPE_ADDR_RANGE:
512a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Address range"), where) == EOF)
5137c478bd9Sstevel@tonic-gate rc_val = -1;
5147c478bd9Sstevel@tonic-gate break;
5157c478bd9Sstevel@tonic-gate default:
516a7485808Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN,
517a7485808Smarkfen "<unknown %u>"), idtype) < 0)
5187c478bd9Sstevel@tonic-gate rc_val = -1;
5197c478bd9Sstevel@tonic-gate break;
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate if (rc != NULL)
5237c478bd9Sstevel@tonic-gate *rc = rc_val;
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate return (canprint);
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate /*
5297c478bd9Sstevel@tonic-gate * Slice an argv/argc vector from an interactive line or a read-file line.
5307c478bd9Sstevel@tonic-gate */
5317c478bd9Sstevel@tonic-gate static int
create_argv(char * ibuf,int * newargc,char *** thisargv)5327c478bd9Sstevel@tonic-gate create_argv(char *ibuf, int *newargc, char ***thisargv)
5337c478bd9Sstevel@tonic-gate {
5347c478bd9Sstevel@tonic-gate unsigned int argvlen = START_ARG;
5357c478bd9Sstevel@tonic-gate char **current;
5367c478bd9Sstevel@tonic-gate boolean_t firstchar = B_TRUE;
5377c478bd9Sstevel@tonic-gate boolean_t inquotes = B_FALSE;
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate *thisargv = malloc(sizeof (char *) * argvlen);
5407c478bd9Sstevel@tonic-gate if ((*thisargv) == NULL)
5417c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
5427c478bd9Sstevel@tonic-gate current = *thisargv;
5437c478bd9Sstevel@tonic-gate *current = NULL;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate for (; *ibuf != '\0'; ibuf++) {
5467c478bd9Sstevel@tonic-gate if (isspace(*ibuf)) {
5477c478bd9Sstevel@tonic-gate if (inquotes) {
5487c478bd9Sstevel@tonic-gate continue;
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate if (*current != NULL) {
5517c478bd9Sstevel@tonic-gate *ibuf = '\0';
5527c478bd9Sstevel@tonic-gate current++;
5537c478bd9Sstevel@tonic-gate if (*thisargv + argvlen == current) {
5547c478bd9Sstevel@tonic-gate /* Regrow ***thisargv. */
5557c478bd9Sstevel@tonic-gate if (argvlen == TOO_MANY_ARGS) {
5567c478bd9Sstevel@tonic-gate free(*thisargv);
5577c478bd9Sstevel@tonic-gate return (TOO_MANY_TOKENS);
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate /* Double the allocation. */
5607c478bd9Sstevel@tonic-gate current = realloc(*thisargv,
5617c478bd9Sstevel@tonic-gate sizeof (char *) * (argvlen << 1));
5627c478bd9Sstevel@tonic-gate if (current == NULL) {
5637c478bd9Sstevel@tonic-gate free(*thisargv);
5647c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate *thisargv = current;
5677c478bd9Sstevel@tonic-gate current += argvlen;
5687c478bd9Sstevel@tonic-gate argvlen <<= 1; /* Double the size. */
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate *current = NULL;
5717c478bd9Sstevel@tonic-gate }
5727c478bd9Sstevel@tonic-gate } else {
5737c478bd9Sstevel@tonic-gate if (firstchar) {
5747c478bd9Sstevel@tonic-gate firstchar = B_FALSE;
575e3320f40Smarkfen if (*ibuf == COMMENT_CHAR || *ibuf == '\n') {
5767c478bd9Sstevel@tonic-gate free(*thisargv);
5777c478bd9Sstevel@tonic-gate return (COMMENT_LINE);
5787c478bd9Sstevel@tonic-gate }
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate if (*ibuf == QUOTE_CHAR) {
5817c478bd9Sstevel@tonic-gate if (inquotes) {
5827c478bd9Sstevel@tonic-gate inquotes = B_FALSE;
5837c478bd9Sstevel@tonic-gate *ibuf = '\0';
5847c478bd9Sstevel@tonic-gate } else {
5857c478bd9Sstevel@tonic-gate inquotes = B_TRUE;
5867c478bd9Sstevel@tonic-gate }
5877c478bd9Sstevel@tonic-gate continue;
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate if (*current == NULL) {
5907c478bd9Sstevel@tonic-gate *current = ibuf;
5917c478bd9Sstevel@tonic-gate (*newargc)++;
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate }
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate /*
5977c478bd9Sstevel@tonic-gate * Tricky corner case...
5987c478bd9Sstevel@tonic-gate * I've parsed _exactly_ the amount of args as I have space. It
5997c478bd9Sstevel@tonic-gate * won't return NULL-terminated, and bad things will happen to
6007c478bd9Sstevel@tonic-gate * the caller.
6017c478bd9Sstevel@tonic-gate */
6027c478bd9Sstevel@tonic-gate if (argvlen == *newargc) {
6037c478bd9Sstevel@tonic-gate current = realloc(*thisargv, sizeof (char *) * (argvlen + 1));
6047c478bd9Sstevel@tonic-gate if (current == NULL) {
6057c478bd9Sstevel@tonic-gate free(*thisargv);
6067c478bd9Sstevel@tonic-gate return (MEMORY_ALLOCATION);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate *thisargv = current;
6097c478bd9Sstevel@tonic-gate current[argvlen] = NULL;
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate
6127c478bd9Sstevel@tonic-gate return (SUCCESS);
6137c478bd9Sstevel@tonic-gate }
6147c478bd9Sstevel@tonic-gate
615bfe6f8f5SVladimir Kotal /*
616bfe6f8f5SVladimir Kotal * init interactive mode if needed and not yet initialized
617bfe6f8f5SVladimir Kotal */
618bfe6f8f5SVladimir Kotal static void
init_interactive(FILE * infile,CplMatchFn * match_fn)619bfe6f8f5SVladimir Kotal init_interactive(FILE *infile, CplMatchFn *match_fn)
620bfe6f8f5SVladimir Kotal {
621bfe6f8f5SVladimir Kotal if (infile == stdin) {
622bfe6f8f5SVladimir Kotal if (gl == NULL) {
623bfe6f8f5SVladimir Kotal if ((gl = new_GetLine(MAX_LINE_LEN,
624bfe6f8f5SVladimir Kotal MAX_CMD_HIST)) == NULL)
625bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN,
626bfe6f8f5SVladimir Kotal "tecla initialization failed"));
627bfe6f8f5SVladimir Kotal
628bfe6f8f5SVladimir Kotal if (gl_customize_completion(gl, NULL,
629bfe6f8f5SVladimir Kotal match_fn) != 0) {
630bfe6f8f5SVladimir Kotal (void) del_GetLine(gl);
631bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN,
632bfe6f8f5SVladimir Kotal "tab completion failed to initialize"));
633bfe6f8f5SVladimir Kotal }
634bfe6f8f5SVladimir Kotal
635bfe6f8f5SVladimir Kotal /*
636bfe6f8f5SVladimir Kotal * In interactive mode we only want to terminate
637bfe6f8f5SVladimir Kotal * when explicitly requested (e.g. by a command).
638bfe6f8f5SVladimir Kotal */
639bfe6f8f5SVladimir Kotal (void) sigset(SIGINT, SIG_IGN);
640bfe6f8f5SVladimir Kotal }
641bfe6f8f5SVladimir Kotal } else {
642bfe6f8f5SVladimir Kotal readfile = B_TRUE;
643bfe6f8f5SVladimir Kotal }
644bfe6f8f5SVladimir Kotal }
645bfe6f8f5SVladimir Kotal
646bfe6f8f5SVladimir Kotal /*
647bfe6f8f5SVladimir Kotal * free tecla data structure
648bfe6f8f5SVladimir Kotal */
649bfe6f8f5SVladimir Kotal static void
fini_interactive(void)650bfe6f8f5SVladimir Kotal fini_interactive(void)
651bfe6f8f5SVladimir Kotal {
652bfe6f8f5SVladimir Kotal if (gl != NULL)
653bfe6f8f5SVladimir Kotal (void) del_GetLine(gl);
654bfe6f8f5SVladimir Kotal }
655bfe6f8f5SVladimir Kotal
656bfe6f8f5SVladimir Kotal /*
657bfe6f8f5SVladimir Kotal * Get single input line, wrapping around interactive and non-interactive
658bfe6f8f5SVladimir Kotal * mode.
659bfe6f8f5SVladimir Kotal */
660bfe6f8f5SVladimir Kotal static char *
do_getstr(FILE * infile,char * prompt,char * ibuf,size_t ibuf_size)661bfe6f8f5SVladimir Kotal do_getstr(FILE *infile, char *prompt, char *ibuf, size_t ibuf_size)
662bfe6f8f5SVladimir Kotal {
663bfe6f8f5SVladimir Kotal char *line;
664bfe6f8f5SVladimir Kotal
665bfe6f8f5SVladimir Kotal if (infile != stdin)
666bfe6f8f5SVladimir Kotal return (fgets(ibuf, ibuf_size, infile));
667bfe6f8f5SVladimir Kotal
668bfe6f8f5SVladimir Kotal /*
669bfe6f8f5SVladimir Kotal * If the user hits ^C then we want to catch it and
670bfe6f8f5SVladimir Kotal * start over. If the user hits EOF then we want to
671bfe6f8f5SVladimir Kotal * bail out.
672bfe6f8f5SVladimir Kotal */
673bfe6f8f5SVladimir Kotal once_again:
674bfe6f8f5SVladimir Kotal line = gl_get_line(gl, prompt, NULL, -1);
675bfe6f8f5SVladimir Kotal if (gl_return_status(gl) == GLR_SIGNAL) {
676bfe6f8f5SVladimir Kotal gl_abandon_line(gl);
677bfe6f8f5SVladimir Kotal goto once_again;
678bfe6f8f5SVladimir Kotal } else if (gl_return_status(gl) == GLR_ERROR) {
679bfe6f8f5SVladimir Kotal gl_abandon_line(gl);
680bfe6f8f5SVladimir Kotal errx(1, dgettext(TEXT_DOMAIN, "Error reading terminal: %s\n"),
681bfe6f8f5SVladimir Kotal gl_error_message(gl, NULL, 0));
682bfe6f8f5SVladimir Kotal } else {
683bfe6f8f5SVladimir Kotal if (line != NULL) {
684bfe6f8f5SVladimir Kotal if (strlcpy(ibuf, line, ibuf_size) >= ibuf_size)
685bfe6f8f5SVladimir Kotal warnx(dgettext(TEXT_DOMAIN,
686bfe6f8f5SVladimir Kotal "Line too long (max=%d chars)"),
687bfe6f8f5SVladimir Kotal ibuf_size);
688bfe6f8f5SVladimir Kotal line = ibuf;
689bfe6f8f5SVladimir Kotal }
690bfe6f8f5SVladimir Kotal }
691bfe6f8f5SVladimir Kotal
692bfe6f8f5SVladimir Kotal return (line);
693bfe6f8f5SVladimir Kotal }
694bfe6f8f5SVladimir Kotal
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate * Enter a mode where commands are read from a file. Treat stdin special.
6977c478bd9Sstevel@tonic-gate */
6987c478bd9Sstevel@tonic-gate void
do_interactive(FILE * infile,char * configfile,char * promptstring,char * my_fmri,parse_cmdln_fn parseit,CplMatchFn * match_fn)699e3320f40Smarkfen do_interactive(FILE *infile, char *configfile, char *promptstring,
700bfe6f8f5SVladimir Kotal char *my_fmri, parse_cmdln_fn parseit, CplMatchFn *match_fn)
7017c478bd9Sstevel@tonic-gate {
7027c478bd9Sstevel@tonic-gate char ibuf[IBUF_SIZE], holder[IBUF_SIZE];
70380ad54c9SToomas Soome char *volatile hptr, **thisargv, *ebuf;
7047c478bd9Sstevel@tonic-gate int thisargc;
70580ad54c9SToomas Soome volatile boolean_t continue_in_progress = B_FALSE;
706bfe6f8f5SVladimir Kotal char *s;
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate (void) setjmp(env);
7097c478bd9Sstevel@tonic-gate
710e3320f40Smarkfen ebuf = NULL;
7117c478bd9Sstevel@tonic-gate interactive = B_TRUE;
7127c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7137c478bd9Sstevel@tonic-gate
714bfe6f8f5SVladimir Kotal /* panics for us */
715bfe6f8f5SVladimir Kotal init_interactive(infile, match_fn);
7167c478bd9Sstevel@tonic-gate
717bfe6f8f5SVladimir Kotal while ((s = do_getstr(infile, promptstring, ibuf, IBUF_SIZE)) != NULL) {
7187c478bd9Sstevel@tonic-gate if (readfile)
7197c478bd9Sstevel@tonic-gate lineno++;
7207c478bd9Sstevel@tonic-gate thisargc = 0;
7217c478bd9Sstevel@tonic-gate thisargv = NULL;
7227c478bd9Sstevel@tonic-gate
7237c478bd9Sstevel@tonic-gate /*
7247c478bd9Sstevel@tonic-gate * Check byte IBUF_SIZE - 2, because byte IBUF_SIZE - 1 will
7257c478bd9Sstevel@tonic-gate * be null-terminated because of fgets().
7267c478bd9Sstevel@tonic-gate */
7277c478bd9Sstevel@tonic-gate if (ibuf[IBUF_SIZE - 2] != '\0') {
728bfe6f8f5SVladimir Kotal if (infile == stdin) {
729bfe6f8f5SVladimir Kotal /* do_getstr() issued a warning already */
730bfe6f8f5SVladimir Kotal bzero(ibuf, IBUF_SIZE);
731bfe6f8f5SVladimir Kotal continue;
732bfe6f8f5SVladimir Kotal } else {
733bfe6f8f5SVladimir Kotal ipsecutil_exit(SERVICE_FATAL, my_fmri,
734bfe6f8f5SVladimir Kotal debugfile, dgettext(TEXT_DOMAIN,
735bfe6f8f5SVladimir Kotal "Line %d too big."), lineno);
736bfe6f8f5SVladimir Kotal }
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate
7397c478bd9Sstevel@tonic-gate if (!continue_in_progress) {
7407c478bd9Sstevel@tonic-gate /* Use -2 because of \n from fgets. */
7417c478bd9Sstevel@tonic-gate if (ibuf[strlen(ibuf) - 2] == CONT_CHAR) {
7427c478bd9Sstevel@tonic-gate /*
7437c478bd9Sstevel@tonic-gate * Can use strcpy here, I've checked the
7447c478bd9Sstevel@tonic-gate * length already.
7457c478bd9Sstevel@tonic-gate */
7467c478bd9Sstevel@tonic-gate (void) strcpy(holder, ibuf);
7477c478bd9Sstevel@tonic-gate hptr = &(holder[strlen(holder)]);
7487c478bd9Sstevel@tonic-gate
7497c478bd9Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */
7507c478bd9Sstevel@tonic-gate hptr[-2] = ' ';
7517c478bd9Sstevel@tonic-gate
7527c478bd9Sstevel@tonic-gate continue_in_progress = B_TRUE;
7537c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7547c478bd9Sstevel@tonic-gate continue;
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate } else {
7577c478bd9Sstevel@tonic-gate /* Handle continuations... */
7587c478bd9Sstevel@tonic-gate (void) strncpy(hptr, ibuf,
7597c478bd9Sstevel@tonic-gate (size_t)(&(holder[IBUF_SIZE]) - hptr));
7607c478bd9Sstevel@tonic-gate if (holder[IBUF_SIZE - 1] != '\0') {
761e3320f40Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri,
762e3320f40Smarkfen debugfile, dgettext(TEXT_DOMAIN,
763e3320f40Smarkfen "Command buffer overrun."));
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate /* Use - 2 because of \n from fgets. */
7667c478bd9Sstevel@tonic-gate if (hptr[strlen(hptr) - 2] == CONT_CHAR) {
7677c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
7687c478bd9Sstevel@tonic-gate hptr += strlen(hptr);
7697c478bd9Sstevel@tonic-gate
7707c478bd9Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */
7717c478bd9Sstevel@tonic-gate hptr[-2] = ' ';
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate continue;
7747c478bd9Sstevel@tonic-gate } else {
7757c478bd9Sstevel@tonic-gate continue_in_progress = B_FALSE;
7767c478bd9Sstevel@tonic-gate /*
7777c478bd9Sstevel@tonic-gate * I've already checked the length...
7787c478bd9Sstevel@tonic-gate */
7797c478bd9Sstevel@tonic-gate (void) strcpy(ibuf, holder);
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate
783e3320f40Smarkfen /*
784e3320f40Smarkfen * Just in case the command fails keep a copy of the
785e3320f40Smarkfen * command buffer for diagnostic output.
786e3320f40Smarkfen */
787e3320f40Smarkfen if (readfile) {
788e3320f40Smarkfen /*
789e3320f40Smarkfen * The error buffer needs to be big enough to
790e3320f40Smarkfen * hold the longest command string, plus
791e3320f40Smarkfen * some extra text, see below.
792e3320f40Smarkfen */
793e3320f40Smarkfen ebuf = calloc((IBUF_SIZE * 2), sizeof (char));
794e3320f40Smarkfen if (ebuf == NULL) {
795e3320f40Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri,
796e3320f40Smarkfen debugfile, dgettext(TEXT_DOMAIN,
797e3320f40Smarkfen "Memory allocation error."));
798e3320f40Smarkfen } else {
799e3320f40Smarkfen (void) snprintf(ebuf, (IBUF_SIZE * 2),
800e3320f40Smarkfen dgettext(TEXT_DOMAIN,
801e3320f40Smarkfen "Config file entry near line %u "
802e3320f40Smarkfen "caused error(s) or warnings:\n\n%s\n\n"),
803e3320f40Smarkfen lineno, ibuf);
804e3320f40Smarkfen }
805e3320f40Smarkfen }
806e3320f40Smarkfen
8077c478bd9Sstevel@tonic-gate switch (create_argv(ibuf, &thisargc, &thisargv)) {
8087c478bd9Sstevel@tonic-gate case TOO_MANY_TOKENS:
809e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
810e3320f40Smarkfen dgettext(TEXT_DOMAIN, "Too many input tokens."));
8117c478bd9Sstevel@tonic-gate break;
8127c478bd9Sstevel@tonic-gate case MEMORY_ALLOCATION:
813e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
814e3320f40Smarkfen dgettext(TEXT_DOMAIN, "Memory allocation error."));
8157c478bd9Sstevel@tonic-gate break;
8167c478bd9Sstevel@tonic-gate case COMMENT_LINE:
8177c478bd9Sstevel@tonic-gate /* Comment line. */
818e3320f40Smarkfen free(ebuf);
8197c478bd9Sstevel@tonic-gate break;
8207c478bd9Sstevel@tonic-gate default:
821e3320f40Smarkfen if (thisargc != 0) {
822e3320f40Smarkfen lines_parsed++;
823e3320f40Smarkfen /* ebuf consumed */
82425e435e0Spwernau parseit(thisargc, thisargv, ebuf, readfile);
825e3320f40Smarkfen } else {
826e3320f40Smarkfen free(ebuf);
827e3320f40Smarkfen }
8287c478bd9Sstevel@tonic-gate free(thisargv);
8297c478bd9Sstevel@tonic-gate if (infile == stdin) {
8307c478bd9Sstevel@tonic-gate (void) printf("%s", promptstring);
8317c478bd9Sstevel@tonic-gate (void) fflush(stdout);
8327c478bd9Sstevel@tonic-gate }
8337c478bd9Sstevel@tonic-gate break;
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE);
8367c478bd9Sstevel@tonic-gate }
837e3320f40Smarkfen
838e3320f40Smarkfen /*
83925e435e0Spwernau * The following code is ipseckey specific. This should never be
84025e435e0Spwernau * used by ikeadm which also calls this function because ikeadm
84125e435e0Spwernau * only runs interactively. If this ever changes this code block
84225e435e0Spwernau * sould be revisited.
843e3320f40Smarkfen */
84425e435e0Spwernau if (readfile) {
84525e435e0Spwernau if (lines_parsed != 0 && lines_added == 0) {
846e3320f40Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile,
84725e435e0Spwernau dgettext(TEXT_DOMAIN, "Configuration file did not "
84825e435e0Spwernau "contain any valid SAs"));
84925e435e0Spwernau }
85025e435e0Spwernau
85125e435e0Spwernau /*
85225e435e0Spwernau * There were errors. Putting the service in maintenance mode.
853*bbf21555SRichard Lowe * When svc.startd(8) allows services to degrade themselves,
85425e435e0Spwernau * this should be revisited.
85525e435e0Spwernau *
85625e435e0Spwernau * If this function was called from a program running as a
857*bbf21555SRichard Lowe * smf_method(7), print a warning message. Don't spew out the
858*bbf21555SRichard Lowe * errors as these will end up in the smf(7) log file which is
85925e435e0Spwernau * publically readable, the errors may contain sensitive
86025e435e0Spwernau * information.
86125e435e0Spwernau */
86225e435e0Spwernau if ((lines_added < lines_parsed) && (configfile != NULL)) {
86325e435e0Spwernau if (my_fmri != NULL) {
86425e435e0Spwernau ipsecutil_exit(SERVICE_BADCONF, my_fmri,
86525e435e0Spwernau debugfile, dgettext(TEXT_DOMAIN,
86625e435e0Spwernau "The configuration file contained %d "
86725e435e0Spwernau "errors.\n"
86825e435e0Spwernau "Manually check the configuration with:\n"
86925e435e0Spwernau "ipseckey -c %s\n"
870*bbf21555SRichard Lowe "Use svcadm(8) to clear maintenance "
87125e435e0Spwernau "condition when errors are resolved.\n"),
87225e435e0Spwernau lines_parsed - lines_added, configfile);
87325e435e0Spwernau } else {
87425e435e0Spwernau EXIT_BADCONFIG(NULL);
87525e435e0Spwernau }
876e3320f40Smarkfen } else {
87725e435e0Spwernau if (my_fmri != NULL)
87825e435e0Spwernau ipsecutil_exit(SERVICE_EXIT_OK, my_fmri,
87925e435e0Spwernau debugfile, dgettext(TEXT_DOMAIN,
88025e435e0Spwernau "%d actions successfully processed."),
88125e435e0Spwernau lines_added);
882e3320f40Smarkfen }
883e3320f40Smarkfen } else {
884bfe6f8f5SVladimir Kotal /* no newline upon Ctrl-D */
885bfe6f8f5SVladimir Kotal if (s != NULL)
886bfe6f8f5SVladimir Kotal (void) putchar('\n');
88725e435e0Spwernau (void) fflush(stdout);
888e3320f40Smarkfen }
889bfe6f8f5SVladimir Kotal
890bfe6f8f5SVladimir Kotal fini_interactive();
891bfe6f8f5SVladimir Kotal
892e3320f40Smarkfen EXIT_OK(NULL);
8937c478bd9Sstevel@tonic-gate }
8947c478bd9Sstevel@tonic-gate
8957c478bd9Sstevel@tonic-gate /*
8967c478bd9Sstevel@tonic-gate * Functions to parse strings that represent a debug or privilege level.
8977c478bd9Sstevel@tonic-gate * These functions are copied from main.c and door.c in usr.lib/in.iked/common.
8987c478bd9Sstevel@tonic-gate * If this file evolves into a common library that may be used by in.iked
8997c478bd9Sstevel@tonic-gate * as well as the usr.sbin utilities, those duplicate functions should be
9007c478bd9Sstevel@tonic-gate * deleted.
9017c478bd9Sstevel@tonic-gate *
9027c478bd9Sstevel@tonic-gate * A privilege level may be represented by a simple keyword, corresponding
9037c478bd9Sstevel@tonic-gate * to one of the possible levels. A debug level may be represented by a
9047c478bd9Sstevel@tonic-gate * series of keywords, separated by '+' or '-', indicating categories to
9057c478bd9Sstevel@tonic-gate * be added or removed from the set of categories in the debug level.
9067c478bd9Sstevel@tonic-gate * For example, +all-op corresponds to level 0xfffffffb (all flags except
9077c478bd9Sstevel@tonic-gate * for D_OP set); while p1+p2+pfkey corresponds to level 0x38. Note that
9087c478bd9Sstevel@tonic-gate * the leading '+' is implicit; the first keyword in the list must be for
9097c478bd9Sstevel@tonic-gate * a category that is to be added.
9107c478bd9Sstevel@tonic-gate *
9117c478bd9Sstevel@tonic-gate * These parsing functions make use of a local version of strtok, strtok_d,
9127c478bd9Sstevel@tonic-gate * which includes an additional parameter, char *delim. This param is filled
9137c478bd9Sstevel@tonic-gate * in with the character which ends the returned token. In other words,
9147c478bd9Sstevel@tonic-gate * this version of strtok, in addition to returning the token, also returns
9157c478bd9Sstevel@tonic-gate * the single character delimiter from the original string which marked the
9167c478bd9Sstevel@tonic-gate * end of the token.
9177c478bd9Sstevel@tonic-gate */
9187c478bd9Sstevel@tonic-gate static char *
strtok_d(char * string,const char * sepset,char * delim)9197c478bd9Sstevel@tonic-gate strtok_d(char *string, const char *sepset, char *delim)
9207c478bd9Sstevel@tonic-gate {
9217c478bd9Sstevel@tonic-gate static char *lasts;
9227c478bd9Sstevel@tonic-gate char *q, *r;
9237c478bd9Sstevel@tonic-gate
9247c478bd9Sstevel@tonic-gate /* first or subsequent call */
9257c478bd9Sstevel@tonic-gate if (string == NULL)
9267c478bd9Sstevel@tonic-gate string = lasts;
9277c478bd9Sstevel@tonic-gate
9287c478bd9Sstevel@tonic-gate if (string == 0) /* return if no tokens remaining */
9297c478bd9Sstevel@tonic-gate return (NULL);
9307c478bd9Sstevel@tonic-gate
9317c478bd9Sstevel@tonic-gate q = string + strspn(string, sepset); /* skip leading separators */
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate if (*q == '\0') /* return if no tokens remaining */
9347c478bd9Sstevel@tonic-gate return (NULL);
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate if ((r = strpbrk(q, sepset)) == NULL) { /* move past token */
9377c478bd9Sstevel@tonic-gate lasts = 0; /* indicate that this is last token */
9387c478bd9Sstevel@tonic-gate } else {
9397c478bd9Sstevel@tonic-gate *delim = *r; /* save delimitor */
9407c478bd9Sstevel@tonic-gate *r = '\0';
9417c478bd9Sstevel@tonic-gate lasts = r + 1;
9427c478bd9Sstevel@tonic-gate }
9437c478bd9Sstevel@tonic-gate return (q);
9447c478bd9Sstevel@tonic-gate }
9457c478bd9Sstevel@tonic-gate
9467c478bd9Sstevel@tonic-gate static keywdtab_t privtab[] = {
9477c478bd9Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "base" },
9487c478bd9Sstevel@tonic-gate { IKE_PRIV_MODKEYS, "modkeys" },
9497c478bd9Sstevel@tonic-gate { IKE_PRIV_KEYMAT, "keymat" },
9507c478bd9Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "0" },
9517c478bd9Sstevel@tonic-gate };
9527c478bd9Sstevel@tonic-gate
9537c478bd9Sstevel@tonic-gate int
privstr2num(char * str)9547c478bd9Sstevel@tonic-gate privstr2num(char *str)
9557c478bd9Sstevel@tonic-gate {
9567c478bd9Sstevel@tonic-gate keywdtab_t *pp;
9577c478bd9Sstevel@tonic-gate char *endp;
9587c478bd9Sstevel@tonic-gate int priv;
9597c478bd9Sstevel@tonic-gate
9607c478bd9Sstevel@tonic-gate for (pp = privtab; pp < A_END(privtab); pp++) {
9617c478bd9Sstevel@tonic-gate if (strcasecmp(str, pp->kw_str) == 0)
9627c478bd9Sstevel@tonic-gate return (pp->kw_tag);
9637c478bd9Sstevel@tonic-gate }
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate priv = strtol(str, &endp, 0);
9667c478bd9Sstevel@tonic-gate if (*endp == '\0')
9677c478bd9Sstevel@tonic-gate return (priv);
9687c478bd9Sstevel@tonic-gate
9697c478bd9Sstevel@tonic-gate return (-1);
9707c478bd9Sstevel@tonic-gate }
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate static keywdtab_t dbgtab[] = {
9737c478bd9Sstevel@tonic-gate { D_CERT, "cert" },
9747c478bd9Sstevel@tonic-gate { D_KEY, "key" },
9757c478bd9Sstevel@tonic-gate { D_OP, "op" },
9767c478bd9Sstevel@tonic-gate { D_P1, "p1" },
9777c478bd9Sstevel@tonic-gate { D_P1, "phase1" },
9787c478bd9Sstevel@tonic-gate { D_P2, "p2" },
9797c478bd9Sstevel@tonic-gate { D_P2, "phase2" },
9807c478bd9Sstevel@tonic-gate { D_PFKEY, "pfkey" },
9817c478bd9Sstevel@tonic-gate { D_POL, "pol" },
9827c478bd9Sstevel@tonic-gate { D_POL, "policy" },
9837c478bd9Sstevel@tonic-gate { D_PROP, "prop" },
9847c478bd9Sstevel@tonic-gate { D_DOOR, "door" },
9857c478bd9Sstevel@tonic-gate { D_CONFIG, "config" },
9865d3b8cb7SBill Sommerfeld { D_LABEL, "label" },
9877c478bd9Sstevel@tonic-gate { D_ALL, "all" },
9887c478bd9Sstevel@tonic-gate { 0, "0" },
9897c478bd9Sstevel@tonic-gate };
9907c478bd9Sstevel@tonic-gate
9917c478bd9Sstevel@tonic-gate int
dbgstr2num(char * str)9927c478bd9Sstevel@tonic-gate dbgstr2num(char *str)
9937c478bd9Sstevel@tonic-gate {
9947c478bd9Sstevel@tonic-gate keywdtab_t *dp;
9957c478bd9Sstevel@tonic-gate
9967c478bd9Sstevel@tonic-gate for (dp = dbgtab; dp < A_END(dbgtab); dp++) {
9977c478bd9Sstevel@tonic-gate if (strcasecmp(str, dp->kw_str) == 0)
9987c478bd9Sstevel@tonic-gate return (dp->kw_tag);
9997c478bd9Sstevel@tonic-gate }
10007c478bd9Sstevel@tonic-gate return (D_INVALID);
10017c478bd9Sstevel@tonic-gate }
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate int
parsedbgopts(char * optarg)10047c478bd9Sstevel@tonic-gate parsedbgopts(char *optarg)
10057c478bd9Sstevel@tonic-gate {
10067c478bd9Sstevel@tonic-gate char *argp, *endp, op, nextop;
10077c478bd9Sstevel@tonic-gate int mask = 0, new;
10087c478bd9Sstevel@tonic-gate
10097c478bd9Sstevel@tonic-gate mask = strtol(optarg, &endp, 0);
10107c478bd9Sstevel@tonic-gate if (*endp == '\0')
10117c478bd9Sstevel@tonic-gate return (mask);
10127c478bd9Sstevel@tonic-gate
10137c478bd9Sstevel@tonic-gate op = optarg[0];
10147c478bd9Sstevel@tonic-gate if (op != '-')
10157c478bd9Sstevel@tonic-gate op = '+';
10167c478bd9Sstevel@tonic-gate argp = strtok_d(optarg, "+-", &nextop);
10177c478bd9Sstevel@tonic-gate do {
10187c478bd9Sstevel@tonic-gate new = dbgstr2num(argp);
10197c478bd9Sstevel@tonic-gate if (new == D_INVALID) {
10207c478bd9Sstevel@tonic-gate /* we encountered an invalid keywd */
10217c478bd9Sstevel@tonic-gate return (new);
10227c478bd9Sstevel@tonic-gate }
10237c478bd9Sstevel@tonic-gate if (op == '+') {
10247c478bd9Sstevel@tonic-gate mask |= new;
10257c478bd9Sstevel@tonic-gate } else {
10267c478bd9Sstevel@tonic-gate mask &= ~new;
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate op = nextop;
10297c478bd9Sstevel@tonic-gate } while ((argp = strtok_d(NULL, "+-", &nextop)) != NULL);
10307c478bd9Sstevel@tonic-gate
10317c478bd9Sstevel@tonic-gate return (mask);
10327c478bd9Sstevel@tonic-gate }
10337c478bd9Sstevel@tonic-gate
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate /*
10367c478bd9Sstevel@tonic-gate * functions to manipulate the kmcookie-label mapping file
10377c478bd9Sstevel@tonic-gate */
10387c478bd9Sstevel@tonic-gate
10397c478bd9Sstevel@tonic-gate /*
10407c478bd9Sstevel@tonic-gate * Open, lockf, fdopen the given file, returning a FILE * on success,
10417c478bd9Sstevel@tonic-gate * or NULL on failure.
10427c478bd9Sstevel@tonic-gate */
10437c478bd9Sstevel@tonic-gate FILE *
kmc_open_and_lock(char * name)10447c478bd9Sstevel@tonic-gate kmc_open_and_lock(char *name)
10457c478bd9Sstevel@tonic-gate {
10467c478bd9Sstevel@tonic-gate int fd, rtnerr;
10477c478bd9Sstevel@tonic-gate FILE *fp;
10487c478bd9Sstevel@tonic-gate
10497c478bd9Sstevel@tonic-gate if ((fd = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
10507c478bd9Sstevel@tonic-gate return (NULL);
10517c478bd9Sstevel@tonic-gate }
10527c478bd9Sstevel@tonic-gate if (lockf(fd, F_LOCK, 0) < 0) {
10537c478bd9Sstevel@tonic-gate return (NULL);
10547c478bd9Sstevel@tonic-gate }
10557c478bd9Sstevel@tonic-gate if ((fp = fdopen(fd, "a+")) == NULL) {
10567c478bd9Sstevel@tonic-gate return (NULL);
10577c478bd9Sstevel@tonic-gate }
10587c478bd9Sstevel@tonic-gate if (fseek(fp, 0, SEEK_SET) < 0) {
10597c478bd9Sstevel@tonic-gate /* save errno in case fclose changes it */
10607c478bd9Sstevel@tonic-gate rtnerr = errno;
10617c478bd9Sstevel@tonic-gate (void) fclose(fp);
10627c478bd9Sstevel@tonic-gate errno = rtnerr;
10637c478bd9Sstevel@tonic-gate return (NULL);
10647c478bd9Sstevel@tonic-gate }
10657c478bd9Sstevel@tonic-gate return (fp);
10667c478bd9Sstevel@tonic-gate }
10677c478bd9Sstevel@tonic-gate
10687c478bd9Sstevel@tonic-gate /*
10697c478bd9Sstevel@tonic-gate * Extract an integer cookie and string label from a line from the
10707c478bd9Sstevel@tonic-gate * kmcookie-label file. Return -1 on failure, 0 on success.
10717c478bd9Sstevel@tonic-gate */
10727c478bd9Sstevel@tonic-gate int
kmc_parse_line(char * line,int * cookie,char ** label)10737c478bd9Sstevel@tonic-gate kmc_parse_line(char *line, int *cookie, char **label)
10747c478bd9Sstevel@tonic-gate {
10757c478bd9Sstevel@tonic-gate char *cookiestr;
10767c478bd9Sstevel@tonic-gate
10777c478bd9Sstevel@tonic-gate *cookie = 0;
10787c478bd9Sstevel@tonic-gate *label = NULL;
10797c478bd9Sstevel@tonic-gate
10807c478bd9Sstevel@tonic-gate cookiestr = strtok(line, " \t\n");
10817c478bd9Sstevel@tonic-gate if (cookiestr == NULL) {
10827c478bd9Sstevel@tonic-gate return (-1);
10837c478bd9Sstevel@tonic-gate }
10847c478bd9Sstevel@tonic-gate
10857c478bd9Sstevel@tonic-gate /* Everything that follows, up to the newline, is the label. */
10867c478bd9Sstevel@tonic-gate *label = strtok(NULL, "\n");
10877c478bd9Sstevel@tonic-gate if (*label == NULL) {
10887c478bd9Sstevel@tonic-gate return (-1);
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate *cookie = atoi(cookiestr);
10927c478bd9Sstevel@tonic-gate return (0);
10937c478bd9Sstevel@tonic-gate }
10947c478bd9Sstevel@tonic-gate
10957c478bd9Sstevel@tonic-gate /*
10967c478bd9Sstevel@tonic-gate * Insert a mapping into the file (if it's not already there), given the
10977c478bd9Sstevel@tonic-gate * new label. Return the assigned cookie, or -1 on error.
10987c478bd9Sstevel@tonic-gate */
10997c478bd9Sstevel@tonic-gate int
kmc_insert_mapping(char * label)11007c478bd9Sstevel@tonic-gate kmc_insert_mapping(char *label)
11017c478bd9Sstevel@tonic-gate {
11027c478bd9Sstevel@tonic-gate FILE *map;
1103c99ab7ceSdanmcd char linebuf[IBUF_SIZE];
11047c478bd9Sstevel@tonic-gate char *cur_label;
11057c478bd9Sstevel@tonic-gate int max_cookie = 0, cur_cookie, rtn_cookie;
11067c478bd9Sstevel@tonic-gate int rtnerr = 0;
11077c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE;
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate /* open and lock the file; will sleep until lock is available */
11107c478bd9Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) {
11117c478bd9Sstevel@tonic-gate /* kmc_open_and_lock() sets errno appropriately */
11127c478bd9Sstevel@tonic-gate return (-1);
11137c478bd9Sstevel@tonic-gate }
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) {
11167c478bd9Sstevel@tonic-gate
1117c99ab7ceSdanmcd /* Skip blank lines, which often come near EOF. */
1118c99ab7ceSdanmcd if (strlen(linebuf) == 0)
1119c99ab7ceSdanmcd continue;
1120c99ab7ceSdanmcd
11217c478bd9Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) {
11227c478bd9Sstevel@tonic-gate rtnerr = EINVAL;
11237c478bd9Sstevel@tonic-gate goto error;
11247c478bd9Sstevel@tonic-gate }
11257c478bd9Sstevel@tonic-gate
11267c478bd9Sstevel@tonic-gate if (cur_cookie > max_cookie)
11277c478bd9Sstevel@tonic-gate max_cookie = cur_cookie;
11287c478bd9Sstevel@tonic-gate
11297c478bd9Sstevel@tonic-gate if ((!found) && (strcmp(cur_label, label) == 0)) {
11307c478bd9Sstevel@tonic-gate found = B_TRUE;
11317c478bd9Sstevel@tonic-gate rtn_cookie = cur_cookie;
11327c478bd9Sstevel@tonic-gate }
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate
11357c478bd9Sstevel@tonic-gate if (!found) {
11367c478bd9Sstevel@tonic-gate rtn_cookie = ++max_cookie;
11377c478bd9Sstevel@tonic-gate if ((fprintf(map, "%u\t%s\n", rtn_cookie, label) < 0) ||
11387c478bd9Sstevel@tonic-gate (fflush(map) < 0)) {
11397c478bd9Sstevel@tonic-gate rtnerr = errno;
11407c478bd9Sstevel@tonic-gate goto error;
11417c478bd9Sstevel@tonic-gate }
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate (void) fclose(map);
11447c478bd9Sstevel@tonic-gate
11457c478bd9Sstevel@tonic-gate return (rtn_cookie);
11467c478bd9Sstevel@tonic-gate
11477c478bd9Sstevel@tonic-gate error:
11487c478bd9Sstevel@tonic-gate (void) fclose(map);
11497c478bd9Sstevel@tonic-gate errno = rtnerr;
11507c478bd9Sstevel@tonic-gate return (-1);
11517c478bd9Sstevel@tonic-gate }
11527c478bd9Sstevel@tonic-gate
11537c478bd9Sstevel@tonic-gate /*
11547c478bd9Sstevel@tonic-gate * Lookup the given cookie and return its corresponding label. Return
11557c478bd9Sstevel@tonic-gate * a pointer to the label on success, NULL on error (or if the label is
11567c478bd9Sstevel@tonic-gate * not found). Note that the returned label pointer points to a static
11577c478bd9Sstevel@tonic-gate * string, so the label will be overwritten by a subsequent call to the
11587c478bd9Sstevel@tonic-gate * function; the function is also not thread-safe as a result.
1159f4a6f97eSDan McDonald *
1160f4a6f97eSDan McDonald * Because this is possibly publically exported, do not change its name,
1161f4a6f97eSDan McDonald * but this is for all intents and purposes an IKEv1/in.iked function.
11627c478bd9Sstevel@tonic-gate */
11637c478bd9Sstevel@tonic-gate char *
kmc_lookup_by_cookie(int cookie)11647c478bd9Sstevel@tonic-gate kmc_lookup_by_cookie(int cookie)
11657c478bd9Sstevel@tonic-gate {
11667c478bd9Sstevel@tonic-gate FILE *map;
1167c99ab7ceSdanmcd static char linebuf[IBUF_SIZE];
11687c478bd9Sstevel@tonic-gate char *cur_label;
11697c478bd9Sstevel@tonic-gate int cur_cookie;
11707c478bd9Sstevel@tonic-gate
11717c478bd9Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) {
11727c478bd9Sstevel@tonic-gate return (NULL);
11737c478bd9Sstevel@tonic-gate }
11747c478bd9Sstevel@tonic-gate
11757c478bd9Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) {
11767c478bd9Sstevel@tonic-gate
11777c478bd9Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) {
11787c478bd9Sstevel@tonic-gate (void) fclose(map);
11797c478bd9Sstevel@tonic-gate return (NULL);
11807c478bd9Sstevel@tonic-gate }
11817c478bd9Sstevel@tonic-gate
11827c478bd9Sstevel@tonic-gate if (cookie == cur_cookie) {
11837c478bd9Sstevel@tonic-gate (void) fclose(map);
11847c478bd9Sstevel@tonic-gate return (cur_label);
11857c478bd9Sstevel@tonic-gate }
11867c478bd9Sstevel@tonic-gate }
11877c478bd9Sstevel@tonic-gate (void) fclose(map);
11887c478bd9Sstevel@tonic-gate
11897c478bd9Sstevel@tonic-gate return (NULL);
11907c478bd9Sstevel@tonic-gate }
11917c478bd9Sstevel@tonic-gate
11927c478bd9Sstevel@tonic-gate /*
11937c478bd9Sstevel@tonic-gate * Parse basic extension headers and return in the passed-in pointer vector.
11947c478bd9Sstevel@tonic-gate * Return values include:
11957c478bd9Sstevel@tonic-gate *
11967c478bd9Sstevel@tonic-gate * KGE_OK Everything's nice and parsed out.
11977c478bd9Sstevel@tonic-gate * If there are no extensions, place NULL in extv[0].
11987c478bd9Sstevel@tonic-gate * KGE_DUP There is a duplicate extension.
11997c478bd9Sstevel@tonic-gate * First instance in appropriate bin. First duplicate in
12007c478bd9Sstevel@tonic-gate * extv[0].
12017c478bd9Sstevel@tonic-gate * KGE_UNK Unknown extension type encountered. extv[0] contains
12027c478bd9Sstevel@tonic-gate * unknown header.
12037c478bd9Sstevel@tonic-gate * KGE_LEN Extension length error.
12047c478bd9Sstevel@tonic-gate * KGE_CHK High-level reality check failed on specific extension.
12057c478bd9Sstevel@tonic-gate *
12067c478bd9Sstevel@tonic-gate * My apologies for some of the pointer arithmetic in here. I'm thinking
12077c478bd9Sstevel@tonic-gate * like an assembly programmer, yet trying to make the compiler happy.
12087c478bd9Sstevel@tonic-gate */
12097c478bd9Sstevel@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)12107c478bd9Sstevel@tonic-gate spdsock_get_ext(spd_ext_t *extv[], spd_msg_t *basehdr, uint_t msgsize,
12117c478bd9Sstevel@tonic-gate char *diag_buf, uint_t diag_buf_len)
12127c478bd9Sstevel@tonic-gate {
12137c478bd9Sstevel@tonic-gate int i;
12147c478bd9Sstevel@tonic-gate
12157c478bd9Sstevel@tonic-gate if (diag_buf != NULL)
12167c478bd9Sstevel@tonic-gate diag_buf[0] = '\0';
12177c478bd9Sstevel@tonic-gate
12187c478bd9Sstevel@tonic-gate for (i = 1; i <= SPD_EXT_MAX; i++)
12197c478bd9Sstevel@tonic-gate extv[i] = NULL;
12207c478bd9Sstevel@tonic-gate
12217c478bd9Sstevel@tonic-gate i = 0;
12227c478bd9Sstevel@tonic-gate /* Use extv[0] as the "current working pointer". */
12237c478bd9Sstevel@tonic-gate
12247c478bd9Sstevel@tonic-gate extv[0] = (spd_ext_t *)(basehdr + 1);
12257c478bd9Sstevel@tonic-gate msgsize = SPD_64TO8(msgsize);
12267c478bd9Sstevel@tonic-gate
12277c478bd9Sstevel@tonic-gate while ((char *)extv[0] < ((char *)basehdr + msgsize)) {
12287c478bd9Sstevel@tonic-gate /* Check for unknown headers. */
12297c478bd9Sstevel@tonic-gate i++;
12307c478bd9Sstevel@tonic-gate if (extv[0]->spd_ext_type == 0 ||
12317c478bd9Sstevel@tonic-gate extv[0]->spd_ext_type > SPD_EXT_MAX) {
12327c478bd9Sstevel@tonic-gate if (diag_buf != NULL) {
12337c478bd9Sstevel@tonic-gate (void) snprintf(diag_buf, diag_buf_len,
12347c478bd9Sstevel@tonic-gate "spdsock ext 0x%X unknown: 0x%X",
12357c478bd9Sstevel@tonic-gate i, extv[0]->spd_ext_type);
12367c478bd9Sstevel@tonic-gate }
12377c478bd9Sstevel@tonic-gate return (KGE_UNK);
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate
12407c478bd9Sstevel@tonic-gate /*
12417c478bd9Sstevel@tonic-gate * Check length. Use uint64_t because extlen is in units
12427c478bd9Sstevel@tonic-gate * of 64-bit words. If length goes beyond the msgsize,
12437c478bd9Sstevel@tonic-gate * return an error. (Zero length also qualifies here.)
12447c478bd9Sstevel@tonic-gate */
12457c478bd9Sstevel@tonic-gate if (extv[0]->spd_ext_len == 0 ||
12467c478bd9Sstevel@tonic-gate (uint8_t *)((uint64_t *)extv[0] + extv[0]->spd_ext_len) >
12477c478bd9Sstevel@tonic-gate (uint8_t *)((uint8_t *)basehdr + msgsize))
12487c478bd9Sstevel@tonic-gate return (KGE_LEN);
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate /* Check for redundant headers. */
12517c478bd9Sstevel@tonic-gate if (extv[extv[0]->spd_ext_type] != NULL)
12527c478bd9Sstevel@tonic-gate return (KGE_DUP);
12537c478bd9Sstevel@tonic-gate
12547c478bd9Sstevel@tonic-gate /* If I make it here, assign the appropriate bin. */
12557c478bd9Sstevel@tonic-gate extv[extv[0]->spd_ext_type] = extv[0];
12567c478bd9Sstevel@tonic-gate
12577c478bd9Sstevel@tonic-gate /* Advance pointer (See above for uint64_t ptr reasoning.) */
12587c478bd9Sstevel@tonic-gate extv[0] = (spd_ext_t *)
12597c478bd9Sstevel@tonic-gate ((uint64_t *)extv[0] + extv[0]->spd_ext_len);
12607c478bd9Sstevel@tonic-gate }
12617c478bd9Sstevel@tonic-gate
12627c478bd9Sstevel@tonic-gate /* Everything's cool. */
12637c478bd9Sstevel@tonic-gate
12647c478bd9Sstevel@tonic-gate /*
12657c478bd9Sstevel@tonic-gate * If extv[0] == NULL, then there are no extension headers in this
12667c478bd9Sstevel@tonic-gate * message. Ensure that this is the case.
12677c478bd9Sstevel@tonic-gate */
12687c478bd9Sstevel@tonic-gate if (extv[0] == (spd_ext_t *)(basehdr + 1))
12697c478bd9Sstevel@tonic-gate extv[0] = NULL;
12707c478bd9Sstevel@tonic-gate
12717c478bd9Sstevel@tonic-gate return (KGE_OK);
12727c478bd9Sstevel@tonic-gate }
12737c478bd9Sstevel@tonic-gate
12747c478bd9Sstevel@tonic-gate const char *
spdsock_diag(int diagnostic)12757c478bd9Sstevel@tonic-gate spdsock_diag(int diagnostic)
12767c478bd9Sstevel@tonic-gate {
12777c478bd9Sstevel@tonic-gate switch (diagnostic) {
12787c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NONE:
1279a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "no error"));
12807c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNKNOWN_EXT:
1281a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unknown extension"));
12827c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_EXTLEN:
1283a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad extension length"));
12847c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_RULE_EXT:
1285a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "no rule extension"));
12867c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_ADDR_LEN:
1287a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad address len"));
12887c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MIXED_AF:
1289a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "mixed address family"));
12907c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_NO_MEM:
1291a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: no memory"));
12927c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT:
1293a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: wrong action count"));
12947c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_TYPE:
1295a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad type"));
12967c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_FLAGS:
1297a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad flags"));
12987c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_INCON_FLAGS:
1299a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "add: inconsistent flags"));
13007c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLPORT:
1301a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local port"));
13027c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLPORT:
1303a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local port"));
13047c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMPORT:
1305a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote port"));
13067c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMPORT:
1307a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote port"));
13087c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_PROTO:
1309a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed proto"));
13107c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_PROTO:
1311a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate proto"));
13127c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLADDR:
1313a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local address"));
13147c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLADDR:
1315a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local address"));
13167c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMADDR:
1317a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote address"));
13187c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMADDR:
1319a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote address"));
13207c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_ACTION:
1321a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed action"));
13227c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_ACTION:
1323a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate action"));
13247c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULE:
1325a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed rule"));
13267c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULE:
1327a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate rule"));
13287c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULESET:
1329a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "malformed ruleset"));
13307c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULESET:
1331a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate ruleset"));
13327c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_INVALID_RULE_INDEX:
1333a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid rule index"));
13347c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_SPDID:
1335a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad spdid"));
13367c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_MSG_TYPE:
1337a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "bad message type"));
13387c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_ALG:
1339a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH algorithm"));
13407c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG:
1341a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1342a7485808Smarkfen "unsupported ESP encryption algorithm"));
13437c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG:
1344a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1345a7485808Smarkfen "unsupported ESP authentication algorithm"));
13467c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE:
1347a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH key size"));
13487c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE:
1349a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1350a7485808Smarkfen "unsupported ESP encryption key size"));
13517c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE:
1352a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1353a7485808Smarkfen "unsupported ESP authentication key size"));
13547c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_ACTION_EXT:
1355a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "No ACTION extension"));
13567c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_ID_RANGE:
1357a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid algorithm identifer"));
13587c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES:
1359a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1360a7485808Smarkfen "number of key sizes inconsistent"));
13617c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES:
1362a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1363a7485808Smarkfen "number of block sizes inconsistent"));
13647c478bd9Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN:
1365a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "invalid mechanism name length"));
13668810c16bSdanmcd case SPD_DIAGNOSTIC_NOT_GLOBAL_OP:
1367a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1368a7485808Smarkfen "operation not applicable to all policies"));
13698810c16bSdanmcd case SPD_DIAGNOSTIC_NO_TUNNEL_SELECTORS:
1370a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1371a7485808Smarkfen "using selectors on a transport-mode tunnel"));
13727c478bd9Sstevel@tonic-gate default:
1373a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "unknown diagnostic"));
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate }
13767c478bd9Sstevel@tonic-gate
13777c478bd9Sstevel@tonic-gate /*
13787c478bd9Sstevel@tonic-gate * PF_KEY Diagnostic table.
13797c478bd9Sstevel@tonic-gate *
13807c478bd9Sstevel@tonic-gate * PF_KEY NOTE: If you change pfkeyv2.h's SADB_X_DIAGNOSTIC_* space, this is
13817c478bd9Sstevel@tonic-gate * where you need to add new messages.
13827c478bd9Sstevel@tonic-gate */
13837c478bd9Sstevel@tonic-gate
13847c478bd9Sstevel@tonic-gate const char *
keysock_diag(int diagnostic)13857c478bd9Sstevel@tonic-gate keysock_diag(int diagnostic)
13867c478bd9Sstevel@tonic-gate {
13877c478bd9Sstevel@tonic-gate switch (diagnostic) {
13888810c16bSdanmcd case SADB_X_DIAGNOSTIC_NONE:
1389a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "No diagnostic"));
13907c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_MSG:
1391a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown message type"));
13927c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_EXT:
1393a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown extension type"));
13947c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EXTLEN:
1395a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad extension length"));
13967c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_SATYPE:
1397a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1398a7485808Smarkfen "Unknown Security Association type"));
13997c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SATYPE_NEEDED:
1400a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1401a7485808Smarkfen "Specific Security Association type needed"));
14027c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_SADBS:
1403a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1404a7485808Smarkfen "No Security Association Databases present"));
14057c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_EXT:
1406a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1407a7485808Smarkfen "No extensions needed for message"));
14087c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC_AF:
1409a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address family"));
14107c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST_AF:
1411a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1412a7485808Smarkfen "Bad destination address family"));
14137c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_PROXY_AF:
1414a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1415a7485808Smarkfen "Bad inner-source address family"));
14167c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AF_MISMATCH:
1417a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1418a7485808Smarkfen "Source/destination address family mismatch"));
14197c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC:
1420a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address value"));
14217c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST:
1422a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Bad destination address value"));
14237c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ALLOC_HSERR:
1424a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1425a7485808Smarkfen "Soft allocations limit more than hard limit"));
14267c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BYTES_HSERR:
1427a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1428a7485808Smarkfen "Soft bytes limit more than hard limit"));
14297c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ADDTIME_HSERR:
1430a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Soft add expiration time later "
14317c478bd9Sstevel@tonic-gate "than hard expiration time"));
14327c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_USETIME_HSERR:
1433a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Soft use expiration time later "
14347c478bd9Sstevel@tonic-gate "than hard expiration time"));
14357c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SRC:
1436a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing source address"));
14377c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_DST:
1438a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing destination address"));
14397c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SA:
1440a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SA extension"));
14417c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_EKEY:
1442a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing encryption key"));
14437c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_AKEY:
1444a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing authentication key"));
14457c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_RANGE:
1446a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SPI range"));
14477c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SRC:
1448a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate source address"));
14497c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_DST:
1450a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate destination address"));
14517c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SA:
1452a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SA extension"));
14537c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_EKEY:
1454a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate encryption key"));
14557c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_AKEY:
1456a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate authentication key"));
14577c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_RANGE:
1458a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SPI range"));
14597c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SRC:
1460a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed source address"));
14617c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_DST:
1462a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed destination address"));
14637c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SA:
1464a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SA extension"));
14657c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_EKEY:
1466a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed encryption key"));
14677c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_AKEY:
1468a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed authentication key"));
14697c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_RANGE:
1470a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SPI range"));
14717c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AKEY_PRESENT:
1472a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Authentication key not needed"));
14737c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_EKEY_PRESENT:
1474a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Encryption key not needed"));
14757c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_PROP_PRESENT:
1476a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Proposal extension not needed"));
14777c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SUPP_PRESENT:
1478a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1479a7485808Smarkfen "Supported algorithms extension not needed"));
14807c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AALG:
1481a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1482a7485808Smarkfen "Unsupported authentication algorithm"));
14837c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EALG:
1484a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1485a7485808Smarkfen "Unsupported encryption algorithm"));
14867c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SAFLAGS:
1487a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA flags"));
14887c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SASTATE:
1489a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA state"));
14907c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AKEYBITS:
1491a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1492a7485808Smarkfen "Bad number of authentication bits"));
14937c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EKEYBITS:
1494a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1495a7485808Smarkfen "Bad number of encryption bits"));
14967c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ENCR_NOTSUPP:
1497a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1498a7485808Smarkfen "Encryption not supported for this SA type"));
14997c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_EKEY:
1500a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Weak encryption key"));
15017c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_AKEY:
1502a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Weak authentication key"));
15037c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMP:
1504a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1505a7485808Smarkfen "Duplicate key management protocol"));
15067c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMC:
1507a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1508a7485808Smarkfen "Duplicate key management cookie"));
15097c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_LOC:
1510a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T local address"));
15117c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_REM:
1512a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T remote address"));
15137c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_LOC:
1514a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T local address"));
15157c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_REM:
1516a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1517a7485808Smarkfen "Duplicate NAT-T remote address"));
15187c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC:
1519a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed NAT-T local address"));
15207c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM:
1521a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1522a7485808Smarkfen "Malformed NAT-T remote address"));
15237c478bd9Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_PORTS:
1524a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T ports"));
15258810c16bSdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_SRC:
1526a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Missing inner source address"));
15278810c16bSdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_DST:
1528a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1529a7485808Smarkfen "Missing inner destination address"));
15308810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_SRC:
1531a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1532a7485808Smarkfen "Duplicate inner source address"));
15338810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_DST:
1534a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1535a7485808Smarkfen "Duplicate inner destination address"));
15368810c16bSdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC:
1537a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1538a7485808Smarkfen "Malformed inner source address"));
15398810c16bSdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST:
1540a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1541a7485808Smarkfen "Malformed inner destination address"));
15428810c16bSdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC:
1543a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1544a7485808Smarkfen "Invalid inner-source prefix length "));
15458810c16bSdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_DST:
1546a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1547a7485808Smarkfen "Invalid inner-destination prefix length"));
15488810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF:
1549a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1550a7485808Smarkfen "Bad inner-destination address family"));
15518810c16bSdanmcd case SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH:
1552a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
15538810c16bSdanmcd "Inner source/destination address family mismatch"));
15548810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF:
1555a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1556a7485808Smarkfen "Bad NAT-T remote address family"));
15578810c16bSdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF:
1558a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1559a7485808Smarkfen "Bad NAT-T local address family"));
15608810c16bSdanmcd case SADB_X_DIAGNOSTIC_PROTO_MISMATCH:
1561a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1562a7485808Smarkfen "Source/desination protocol mismatch"));
15638810c16bSdanmcd case SADB_X_DIAGNOSTIC_INNER_PROTO_MISMATCH:
1564a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1565a7485808Smarkfen "Inner source/desination protocol mismatch"));
15668810c16bSdanmcd case SADB_X_DIAGNOSTIC_DUAL_PORT_SETS:
1567a7485808Smarkfen return (dgettext(TEXT_DOMAIN,
1568a7485808Smarkfen "Both inner ports and outer ports are set"));
156938d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE:
157038d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157138d95a78Smarkfen "Pairing failed, target SA unsuitable for pairing"));
157238d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ADD_MISMATCH:
157338d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157438d95a78Smarkfen "Source/destination address differs from pair SA"));
157538d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ALREADY:
157638d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
157738d95a78Smarkfen "Already paired with another security association"));
157838d95a78Smarkfen case SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND:
157938d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
158038d95a78Smarkfen "Command failed, pair security association not found"));
158138d95a78Smarkfen case SADB_X_DIAGNOSTIC_BAD_SA_DIRECTION:
158238d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
158338d95a78Smarkfen "Inappropriate SA direction"));
158438d95a78Smarkfen case SADB_X_DIAGNOSTIC_SA_NOTFOUND:
158538d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
158638d95a78Smarkfen "Security association not found"));
158738d95a78Smarkfen case SADB_X_DIAGNOSTIC_SA_EXPIRED:
158838d95a78Smarkfen return (dgettext(TEXT_DOMAIN,
158938d95a78Smarkfen "Security association is not valid"));
1590a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_BAD_CTX:
1591a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1592a1ba8781SMark Fenwick "Algorithm invalid or not supported by Crypto Framework"));
1593a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_INVALID_REPLAY:
1594a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1595a1ba8781SMark Fenwick "Invalid Replay counter"));
1596a1ba8781SMark Fenwick case SADB_X_DIAGNOSTIC_MISSING_LIFETIME:
1597a1ba8781SMark Fenwick return (dgettext(TEXT_DOMAIN,
1598a1ba8781SMark Fenwick "Inappropriate lifetimes"));
15997c478bd9Sstevel@tonic-gate default:
1600a7485808Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown diagnostic code"));
16017c478bd9Sstevel@tonic-gate }
16027c478bd9Sstevel@tonic-gate }
16038810c16bSdanmcd
16048810c16bSdanmcd /*
16058810c16bSdanmcd * Convert an IPv6 mask to a prefix len. I assume all IPv6 masks are
16068810c16bSdanmcd * contiguous, so I stop at the first zero bit!
16078810c16bSdanmcd */
16088810c16bSdanmcd int
in_masktoprefix(uint8_t * mask,boolean_t is_v4mapped)16098810c16bSdanmcd in_masktoprefix(uint8_t *mask, boolean_t is_v4mapped)
16108810c16bSdanmcd {
16118810c16bSdanmcd int rc = 0;
16128810c16bSdanmcd uint8_t last;
16138810c16bSdanmcd int limit = IPV6_ABITS;
16148810c16bSdanmcd
16158810c16bSdanmcd if (is_v4mapped) {
16168810c16bSdanmcd mask += ((IPV6_ABITS - IP_ABITS)/8);
16178810c16bSdanmcd limit = IP_ABITS;
16188810c16bSdanmcd }
16198810c16bSdanmcd
16208810c16bSdanmcd while (*mask == 0xff) {
16218810c16bSdanmcd rc += 8;
16228810c16bSdanmcd if (rc == limit)
16238810c16bSdanmcd return (limit);
16248810c16bSdanmcd mask++;
16258810c16bSdanmcd }
16268810c16bSdanmcd
16278810c16bSdanmcd last = *mask;
16288810c16bSdanmcd while (last != 0) {
16298810c16bSdanmcd rc++;
16308810c16bSdanmcd last = (last << 1) & 0xff;
16318810c16bSdanmcd }
16328810c16bSdanmcd
16338810c16bSdanmcd return (rc);
16348810c16bSdanmcd }
16358810c16bSdanmcd
16368810c16bSdanmcd /*
16378810c16bSdanmcd * Expand the diagnostic code into a message.
16388810c16bSdanmcd */
16398810c16bSdanmcd void
print_diagnostic(FILE * file,uint16_t diagnostic)16408810c16bSdanmcd print_diagnostic(FILE *file, uint16_t diagnostic)
16418810c16bSdanmcd {
16428810c16bSdanmcd /* Use two spaces so above strings can fit on the line. */
1643a7485808Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN,
1644a7485808Smarkfen " Diagnostic code %u: %s.\n"),
16458810c16bSdanmcd diagnostic, keysock_diag(diagnostic));
16468810c16bSdanmcd }
16478810c16bSdanmcd
16488810c16bSdanmcd /*
16498810c16bSdanmcd * Prints the base PF_KEY message.
16508810c16bSdanmcd */
16518810c16bSdanmcd void
print_sadb_msg(FILE * file,struct sadb_msg * samsg,time_t wallclock,boolean_t vflag)1652bb3ed8dfSpwernau print_sadb_msg(FILE *file, struct sadb_msg *samsg, time_t wallclock,
1653bb3ed8dfSpwernau boolean_t vflag)
16548810c16bSdanmcd {
16558810c16bSdanmcd if (wallclock != 0)
1656bb3ed8dfSpwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN,
1657a7485808Smarkfen "%sTimestamp: %s\n"), "", NULL,
16588810c16bSdanmcd vflag);
16598810c16bSdanmcd
1660bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1661bb3ed8dfSpwernau "Base message (version %u) type "),
16628810c16bSdanmcd samsg->sadb_msg_version);
16638810c16bSdanmcd switch (samsg->sadb_msg_type) {
16648810c16bSdanmcd case SADB_RESERVED:
1665bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1666a7485808Smarkfen "RESERVED (warning: set to 0)"));
16678810c16bSdanmcd break;
16688810c16bSdanmcd case SADB_GETSPI:
1669bb3ed8dfSpwernau (void) fprintf(file, "GETSPI");
16708810c16bSdanmcd break;
16718810c16bSdanmcd case SADB_UPDATE:
1672bb3ed8dfSpwernau (void) fprintf(file, "UPDATE");
16738810c16bSdanmcd break;
167438d95a78Smarkfen case SADB_X_UPDATEPAIR:
167538d95a78Smarkfen (void) fprintf(file, "UPDATE PAIR");
167638d95a78Smarkfen break;
16778810c16bSdanmcd case SADB_ADD:
1678bb3ed8dfSpwernau (void) fprintf(file, "ADD");
16798810c16bSdanmcd break;
16808810c16bSdanmcd case SADB_DELETE:
1681bb3ed8dfSpwernau (void) fprintf(file, "DELETE");
16828810c16bSdanmcd break;
168338d95a78Smarkfen case SADB_X_DELPAIR:
168438d95a78Smarkfen (void) fprintf(file, "DELETE PAIR");
168538d95a78Smarkfen break;
16868810c16bSdanmcd case SADB_GET:
1687bb3ed8dfSpwernau (void) fprintf(file, "GET");
16888810c16bSdanmcd break;
16898810c16bSdanmcd case SADB_ACQUIRE:
1690bb3ed8dfSpwernau (void) fprintf(file, "ACQUIRE");
16918810c16bSdanmcd break;
16928810c16bSdanmcd case SADB_REGISTER:
1693bb3ed8dfSpwernau (void) fprintf(file, "REGISTER");
16948810c16bSdanmcd break;
16958810c16bSdanmcd case SADB_EXPIRE:
1696bb3ed8dfSpwernau (void) fprintf(file, "EXPIRE");
16978810c16bSdanmcd break;
16988810c16bSdanmcd case SADB_FLUSH:
1699bb3ed8dfSpwernau (void) fprintf(file, "FLUSH");
17008810c16bSdanmcd break;
17018810c16bSdanmcd case SADB_DUMP:
1702bb3ed8dfSpwernau (void) fprintf(file, "DUMP");
17038810c16bSdanmcd break;
17048810c16bSdanmcd case SADB_X_PROMISC:
1705bb3ed8dfSpwernau (void) fprintf(file, "X_PROMISC");
17068810c16bSdanmcd break;
17078810c16bSdanmcd case SADB_X_INVERSE_ACQUIRE:
1708bb3ed8dfSpwernau (void) fprintf(file, "X_INVERSE_ACQUIRE");
17098810c16bSdanmcd break;
17108810c16bSdanmcd default:
1711bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1712a7485808Smarkfen "Unknown (%u)"), samsg->sadb_msg_type);
17138810c16bSdanmcd break;
17148810c16bSdanmcd }
1715bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ", SA type "));
17168810c16bSdanmcd
17178810c16bSdanmcd switch (samsg->sadb_msg_satype) {
17188810c16bSdanmcd case SADB_SATYPE_UNSPEC:
1719bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1720bb3ed8dfSpwernau "<unspecified/all>"));
17218810c16bSdanmcd break;
17228810c16bSdanmcd case SADB_SATYPE_AH:
1723bb3ed8dfSpwernau (void) fprintf(file, "AH");
17248810c16bSdanmcd break;
17258810c16bSdanmcd case SADB_SATYPE_ESP:
1726bb3ed8dfSpwernau (void) fprintf(file, "ESP");
17278810c16bSdanmcd break;
17288810c16bSdanmcd case SADB_SATYPE_RSVP:
1729bb3ed8dfSpwernau (void) fprintf(file, "RSVP");
17308810c16bSdanmcd break;
17318810c16bSdanmcd case SADB_SATYPE_OSPFV2:
1732bb3ed8dfSpwernau (void) fprintf(file, "OSPFv2");
17338810c16bSdanmcd break;
17348810c16bSdanmcd case SADB_SATYPE_RIPV2:
1735bb3ed8dfSpwernau (void) fprintf(file, "RIPv2");
17368810c16bSdanmcd break;
17378810c16bSdanmcd case SADB_SATYPE_MIP:
1738bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Mobile IP"));
17398810c16bSdanmcd break;
17408810c16bSdanmcd default:
1741bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1742a7485808Smarkfen "<unknown %u>"), samsg->sadb_msg_satype);
17438810c16bSdanmcd break;
17448810c16bSdanmcd }
17458810c16bSdanmcd
1746bb3ed8dfSpwernau (void) fprintf(file, ".\n");
17478810c16bSdanmcd
17488810c16bSdanmcd if (samsg->sadb_msg_errno != 0) {
1749bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1750bb3ed8dfSpwernau "Error %s from PF_KEY.\n"),
17518810c16bSdanmcd strerror(samsg->sadb_msg_errno));
1752bb3ed8dfSpwernau print_diagnostic(file, samsg->sadb_x_msg_diagnostic);
17538810c16bSdanmcd }
17548810c16bSdanmcd
1755bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1756a7485808Smarkfen "Message length %u bytes, seq=%u, pid=%u.\n"),
17578810c16bSdanmcd SADB_64TO8(samsg->sadb_msg_len), samsg->sadb_msg_seq,
17588810c16bSdanmcd samsg->sadb_msg_pid);
17598810c16bSdanmcd }
17608810c16bSdanmcd
17618810c16bSdanmcd /*
17628810c16bSdanmcd * Print the SA extension for PF_KEY.
17638810c16bSdanmcd */
17648810c16bSdanmcd void
print_sa(FILE * file,char * prefix,struct sadb_sa * assoc)1765bb3ed8dfSpwernau print_sa(FILE *file, char *prefix, struct sadb_sa *assoc)
17668810c16bSdanmcd {
17678810c16bSdanmcd if (assoc->sadb_sa_len != SADB_8TO64(sizeof (*assoc))) {
1768bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1769a7485808Smarkfen "WARNING: SA info extension length (%u) is bad."),
17708810c16bSdanmcd SADB_64TO8(assoc->sadb_sa_len));
17718810c16bSdanmcd }
17728810c16bSdanmcd
1773bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
17749c2c14abSThejaswini Singarajipura "%sSADB_ASSOC spi=0x%x, replay window size=%u, state="),
17758810c16bSdanmcd prefix, ntohl(assoc->sadb_sa_spi), assoc->sadb_sa_replay);
17768810c16bSdanmcd switch (assoc->sadb_sa_state) {
17778810c16bSdanmcd case SADB_SASTATE_LARVAL:
1778bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "LARVAL"));
17798810c16bSdanmcd break;
17808810c16bSdanmcd case SADB_SASTATE_MATURE:
1781bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "MATURE"));
17828810c16bSdanmcd break;
17838810c16bSdanmcd case SADB_SASTATE_DYING:
1784bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DYING"));
17858810c16bSdanmcd break;
17868810c16bSdanmcd case SADB_SASTATE_DEAD:
1787bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DEAD"));
17888810c16bSdanmcd break;
17899c2c14abSThejaswini Singarajipura case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
17909c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
17919c2c14abSThejaswini Singarajipura "ACTIVE_ELSEWHERE"));
17929c2c14abSThejaswini Singarajipura break;
17939c2c14abSThejaswini Singarajipura case SADB_X_SASTATE_IDLE:
17949c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN, "IDLE"));
17959c2c14abSThejaswini Singarajipura break;
17968810c16bSdanmcd default:
1797bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1798a7485808Smarkfen "<unknown %u>"), assoc->sadb_sa_state);
17998810c16bSdanmcd }
18008810c16bSdanmcd
18018810c16bSdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) {
1802bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1803a7485808Smarkfen "\n%sAuthentication algorithm = "),
18048810c16bSdanmcd prefix);
1805bb3ed8dfSpwernau (void) dump_aalg(assoc->sadb_sa_auth, file);
18068810c16bSdanmcd }
18078810c16bSdanmcd
18088810c16bSdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) {
1809bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1810a7485808Smarkfen "\n%sEncryption algorithm = "), prefix);
1811bb3ed8dfSpwernau (void) dump_ealg(assoc->sadb_sa_encrypt, file);
18128810c16bSdanmcd }
18138810c16bSdanmcd
1814bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%sflags=0x%x < "), prefix,
18158810c16bSdanmcd assoc->sadb_sa_flags);
18168810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_PFS)
1817bb3ed8dfSpwernau (void) fprintf(file, "PFS ");
18188810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_NOREPLAY)
1819bb3ed8dfSpwernau (void) fprintf(file, "NOREPLAY ");
18208810c16bSdanmcd
18218810c16bSdanmcd /* BEGIN Solaris-specific flags. */
18228810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_USED)
1823bb3ed8dfSpwernau (void) fprintf(file, "X_USED ");
182438d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_PAIRED)
182538d95a78Smarkfen (void) fprintf(file, "X_PAIRED ");
182638d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_OUTBOUND)
182738d95a78Smarkfen (void) fprintf(file, "X_OUTBOUND ");
182838d95a78Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_INBOUND)
182938d95a78Smarkfen (void) fprintf(file, "X_INBOUND ");
18308810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_UNIQUE)
1831bb3ed8dfSpwernau (void) fprintf(file, "X_UNIQUE ");
18328810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG1)
1833bb3ed8dfSpwernau (void) fprintf(file, "X_AALG1 ");
18348810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG2)
1835bb3ed8dfSpwernau (void) fprintf(file, "X_AALG2 ");
18368810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG1)
1837bb3ed8dfSpwernau (void) fprintf(file, "X_EALG1 ");
18388810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG2)
1839bb3ed8dfSpwernau (void) fprintf(file, "X_EALG2 ");
18408810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_LOC)
1841bb3ed8dfSpwernau (void) fprintf(file, "X_NATT_LOC ");
18428810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_REM)
1843bb3ed8dfSpwernau (void) fprintf(file, "X_NATT_REM ");
18448810c16bSdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
1845bb3ed8dfSpwernau (void) fprintf(file, "X_TUNNEL ");
18464a179720Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATTED)
18474a179720Sdanmcd (void) fprintf(file, "X_NATTED ");
18488810c16bSdanmcd /* END Solaris-specific flags. */
18498810c16bSdanmcd
1850bb3ed8dfSpwernau (void) fprintf(file, ">\n");
18518810c16bSdanmcd }
18528810c16bSdanmcd
18538810c16bSdanmcd void
printsatime(FILE * file,int64_t lt,const char * msg,const char * pfx,const char * pfx2,boolean_t vflag)1854bb3ed8dfSpwernau printsatime(FILE *file, int64_t lt, const char *msg, const char *pfx,
1855bb3ed8dfSpwernau const char *pfx2, boolean_t vflag)
18568810c16bSdanmcd {
18578810c16bSdanmcd char tbuf[TBUF_SIZE]; /* For strftime() call. */
18588810c16bSdanmcd const char *tp = tbuf;
18598810c16bSdanmcd time_t t = lt;
18608810c16bSdanmcd struct tm res;
18618810c16bSdanmcd
18628810c16bSdanmcd if (t != lt) {
18638810c16bSdanmcd if (lt > 0)
18648810c16bSdanmcd t = LONG_MAX;
18658810c16bSdanmcd else
18668810c16bSdanmcd t = LONG_MIN;
18678810c16bSdanmcd }
18688810c16bSdanmcd
18698810c16bSdanmcd if (strftime(tbuf, TBUF_SIZE, NULL, localtime_r(&t, &res)) == 0)
1870a7485808Smarkfen tp = dgettext(TEXT_DOMAIN, "<time conversion failed>");
1871bb3ed8dfSpwernau (void) fprintf(file, msg, pfx, tp);
18728810c16bSdanmcd if (vflag && (pfx2 != NULL))
1873bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1874c51cb4bcSDan McDonald "%s\t(raw time value %" PRIu64 ")\n"), pfx2, lt);
18758810c16bSdanmcd }
18768810c16bSdanmcd
18778810c16bSdanmcd /*
18788810c16bSdanmcd * Print the SA lifetime information. (An SADB_EXT_LIFETIME_* extension.)
18798810c16bSdanmcd */
18808810c16bSdanmcd 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)1881bb3ed8dfSpwernau print_lifetimes(FILE *file, time_t wallclock, struct sadb_lifetime *current,
18829c2c14abSThejaswini Singarajipura struct sadb_lifetime *hard, struct sadb_lifetime *soft,
18839c2c14abSThejaswini Singarajipura struct sadb_lifetime *idle, boolean_t vflag)
18848810c16bSdanmcd {
18858810c16bSdanmcd int64_t scratch;
1886a7485808Smarkfen char *soft_prefix = dgettext(TEXT_DOMAIN, "SLT: ");
1887a7485808Smarkfen char *hard_prefix = dgettext(TEXT_DOMAIN, "HLT: ");
1888a7485808Smarkfen char *current_prefix = dgettext(TEXT_DOMAIN, "CLT: ");
18899c2c14abSThejaswini Singarajipura char *idle_prefix = dgettext(TEXT_DOMAIN, "ILT: ");
1890510c3f91SVladimir Kotal char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */
1891510c3f91SVladimir Kotal char secs_str[SECS_STR_SIZE]; /* buffer for seconds representation */
18928810c16bSdanmcd
18938810c16bSdanmcd if (current != NULL &&
18948810c16bSdanmcd current->sadb_lifetime_len != SADB_8TO64(sizeof (*current))) {
1895bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1896a7485808Smarkfen "WARNING: CURRENT lifetime extension length (%u) is bad."),
18978810c16bSdanmcd SADB_64TO8(current->sadb_lifetime_len));
18988810c16bSdanmcd }
18998810c16bSdanmcd
19008810c16bSdanmcd if (hard != NULL &&
19018810c16bSdanmcd hard->sadb_lifetime_len != SADB_8TO64(sizeof (*hard))) {
1902bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1903bb3ed8dfSpwernau "WARNING: HARD lifetime extension length (%u) is bad."),
19048810c16bSdanmcd SADB_64TO8(hard->sadb_lifetime_len));
19058810c16bSdanmcd }
19068810c16bSdanmcd
19078810c16bSdanmcd if (soft != NULL &&
19088810c16bSdanmcd soft->sadb_lifetime_len != SADB_8TO64(sizeof (*soft))) {
1909bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
1910bb3ed8dfSpwernau "WARNING: SOFT lifetime extension length (%u) is bad."),
19118810c16bSdanmcd SADB_64TO8(soft->sadb_lifetime_len));
19128810c16bSdanmcd }
19138810c16bSdanmcd
19149c2c14abSThejaswini Singarajipura if (idle != NULL &&
19159c2c14abSThejaswini Singarajipura idle->sadb_lifetime_len != SADB_8TO64(sizeof (*idle))) {
19169c2c14abSThejaswini Singarajipura warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
19179c2c14abSThejaswini Singarajipura "WARNING: IDLE lifetime extension length (%u) is bad."),
19189c2c14abSThejaswini Singarajipura SADB_64TO8(idle->sadb_lifetime_len));
19199c2c14abSThejaswini Singarajipura }
19209c2c14abSThejaswini Singarajipura
1921bb3ed8dfSpwernau (void) fprintf(file, " LT: Lifetime information\n");
19228810c16bSdanmcd if (current != NULL) {
19238810c16bSdanmcd /* Express values as current values. */
1924bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1925510c3f91SVladimir Kotal "%sCurrent lifetime information:\n"),
1926510c3f91SVladimir Kotal current_prefix);
1927510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN,
1928510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sprotected, %u allocations "
1929510c3f91SVladimir Kotal "used.\n"), current_prefix,
1930510c3f91SVladimir Kotal current->sadb_lifetime_bytes,
1931510c3f91SVladimir Kotal bytecnt2out(current->sadb_lifetime_bytes, byte_str,
1932510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
19338810c16bSdanmcd current->sadb_lifetime_allocations);
1934bb3ed8dfSpwernau printsatime(file, current->sadb_lifetime_addtime,
1935510c3f91SVladimir Kotal dgettext(TEXT_DOMAIN, "%sSA added at time: %s\n"),
19368810c16bSdanmcd current_prefix, current_prefix, vflag);
19378810c16bSdanmcd if (current->sadb_lifetime_usetime != 0) {
1938bb3ed8dfSpwernau printsatime(file, current->sadb_lifetime_usetime,
1939a7485808Smarkfen dgettext(TEXT_DOMAIN,
1940a7485808Smarkfen "%sSA first used at time %s\n"),
19418810c16bSdanmcd current_prefix, current_prefix, vflag);
19428810c16bSdanmcd }
1943bb3ed8dfSpwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN,
1944a7485808Smarkfen "%sTime now is %s\n"), current_prefix, current_prefix,
1945a7485808Smarkfen vflag);
19468810c16bSdanmcd }
19478810c16bSdanmcd
19488810c16bSdanmcd if (soft != NULL) {
1949bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1950510c3f91SVladimir Kotal "%sSoft lifetime information:\n"),
19518810c16bSdanmcd soft_prefix);
1952bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1953510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sof lifetime, %u allocations.\n"),
1954510c3f91SVladimir Kotal soft_prefix,
1955510c3f91SVladimir Kotal soft->sadb_lifetime_bytes,
1956510c3f91SVladimir Kotal bytecnt2out(soft->sadb_lifetime_bytes, byte_str,
1957510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
19588810c16bSdanmcd soft->sadb_lifetime_allocations);
1959bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1960510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
1961510c3f91SVladimir Kotal soft_prefix, soft->sadb_lifetime_addtime,
1962510c3f91SVladimir Kotal secs2out(soft->sadb_lifetime_addtime, secs_str,
1963510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
1964bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
1965510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
1966510c3f91SVladimir Kotal soft_prefix, soft->sadb_lifetime_usetime,
1967510c3f91SVladimir Kotal secs2out(soft->sadb_lifetime_usetime, secs_str,
1968510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
19698810c16bSdanmcd /* If possible, express values as time remaining. */
19708810c16bSdanmcd if (current != NULL) {
19718810c16bSdanmcd if (soft->sadb_lifetime_bytes != 0)
1972510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s"
1973510c3f91SVladimir Kotal "%" PRIu64 " bytes %smore can be "
1974510c3f91SVladimir Kotal "protected.\n"), soft_prefix,
1975510c3f91SVladimir Kotal (soft->sadb_lifetime_bytes >
1976510c3f91SVladimir Kotal current->sadb_lifetime_bytes) ?
1977510c3f91SVladimir Kotal soft->sadb_lifetime_bytes -
1978510c3f91SVladimir Kotal current->sadb_lifetime_bytes : 0,
19798810c16bSdanmcd (soft->sadb_lifetime_bytes >
198025e435e0Spwernau current->sadb_lifetime_bytes) ?
1981510c3f91SVladimir Kotal bytecnt2out(soft->sadb_lifetime_bytes -
1982510c3f91SVladimir Kotal current->sadb_lifetime_bytes, byte_str,
1983510c3f91SVladimir Kotal sizeof (byte_str), SPC_END) : "");
19848810c16bSdanmcd if (soft->sadb_lifetime_addtime != 0 ||
19858810c16bSdanmcd (soft->sadb_lifetime_usetime != 0 &&
198625e435e0Spwernau current->sadb_lifetime_usetime != 0)) {
19878810c16bSdanmcd int64_t adddelta, usedelta;
19888810c16bSdanmcd
19898810c16bSdanmcd if (soft->sadb_lifetime_addtime != 0) {
19908810c16bSdanmcd adddelta =
19918810c16bSdanmcd current->sadb_lifetime_addtime +
19928810c16bSdanmcd soft->sadb_lifetime_addtime -
19938810c16bSdanmcd wallclock;
19948810c16bSdanmcd } else {
19958810c16bSdanmcd adddelta = TIME_MAX;
19968810c16bSdanmcd }
19978810c16bSdanmcd
19988810c16bSdanmcd if (soft->sadb_lifetime_usetime != 0 &&
19998810c16bSdanmcd current->sadb_lifetime_usetime != 0) {
20008810c16bSdanmcd usedelta =
20018810c16bSdanmcd current->sadb_lifetime_usetime +
20028810c16bSdanmcd soft->sadb_lifetime_usetime -
20038810c16bSdanmcd wallclock;
20048810c16bSdanmcd } else {
20058810c16bSdanmcd usedelta = TIME_MAX;
20068810c16bSdanmcd }
2007bb3ed8dfSpwernau (void) fprintf(file, "%s", soft_prefix);
20088810c16bSdanmcd scratch = MIN(adddelta, usedelta);
20098810c16bSdanmcd if (scratch >= 0) {
2010bb3ed8dfSpwernau (void) fprintf(file,
2011bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2012c51cb4bcSDan McDonald "Soft expiration occurs in %"
2013510c3f91SVladimir Kotal PRId64 " seconds%s\n"), scratch,
2014510c3f91SVladimir Kotal secs2out(scratch, secs_str,
2015510c3f91SVladimir Kotal sizeof (secs_str), SPC_BEGIN));
20168810c16bSdanmcd } else {
2017bb3ed8dfSpwernau (void) fprintf(file,
2018bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2019510c3f91SVladimir Kotal "Soft expiration occurred\n"));
20208810c16bSdanmcd }
20218810c16bSdanmcd scratch += wallclock;
2022bb3ed8dfSpwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN,
2023510c3f91SVladimir Kotal "%sTime of expiration: %s.\n"),
2024510c3f91SVladimir Kotal soft_prefix, soft_prefix, vflag);
20258810c16bSdanmcd }
20268810c16bSdanmcd }
20278810c16bSdanmcd }
20288810c16bSdanmcd
20298810c16bSdanmcd if (hard != NULL) {
2030bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2031510c3f91SVladimir Kotal "%sHard lifetime information:\n"), hard_prefix);
2032bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2033510c3f91SVladimir Kotal "%s%" PRIu64 " bytes %sof lifetime, %u allocations.\n"),
2034510c3f91SVladimir Kotal hard_prefix,
2035510c3f91SVladimir Kotal hard->sadb_lifetime_bytes,
2036510c3f91SVladimir Kotal bytecnt2out(hard->sadb_lifetime_bytes, byte_str,
2037510c3f91SVladimir Kotal sizeof (byte_str), SPC_END),
2038510c3f91SVladimir Kotal hard->sadb_lifetime_allocations);
2039bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2040510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
2041510c3f91SVladimir Kotal hard_prefix, hard->sadb_lifetime_addtime,
2042510c3f91SVladimir Kotal secs2out(hard->sadb_lifetime_addtime, secs_str,
2043510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
2044bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2045510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
2046510c3f91SVladimir Kotal hard_prefix, hard->sadb_lifetime_usetime,
2047510c3f91SVladimir Kotal secs2out(hard->sadb_lifetime_usetime, secs_str,
2048510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
20498810c16bSdanmcd /* If possible, express values as time remaining. */
20508810c16bSdanmcd if (current != NULL) {
20518810c16bSdanmcd if (hard->sadb_lifetime_bytes != 0)
2052510c3f91SVladimir Kotal (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s"
2053510c3f91SVladimir Kotal "%" PRIu64 " bytes %smore can be "
2054510c3f91SVladimir Kotal "protected.\n"), hard_prefix,
2055510c3f91SVladimir Kotal (hard->sadb_lifetime_bytes >
2056510c3f91SVladimir Kotal current->sadb_lifetime_bytes) ?
2057510c3f91SVladimir Kotal hard->sadb_lifetime_bytes -
2058510c3f91SVladimir Kotal current->sadb_lifetime_bytes : 0,
20598810c16bSdanmcd (hard->sadb_lifetime_bytes >
206025e435e0Spwernau current->sadb_lifetime_bytes) ?
2061510c3f91SVladimir Kotal bytecnt2out(hard->sadb_lifetime_bytes -
2062510c3f91SVladimir Kotal current->sadb_lifetime_bytes, byte_str,
2063510c3f91SVladimir Kotal sizeof (byte_str), SPC_END) : "");
20648810c16bSdanmcd if (hard->sadb_lifetime_addtime != 0 ||
20658810c16bSdanmcd (hard->sadb_lifetime_usetime != 0 &&
206625e435e0Spwernau current->sadb_lifetime_usetime != 0)) {
20678810c16bSdanmcd int64_t adddelta, usedelta;
20688810c16bSdanmcd
20698810c16bSdanmcd if (hard->sadb_lifetime_addtime != 0) {
20708810c16bSdanmcd adddelta =
20718810c16bSdanmcd current->sadb_lifetime_addtime +
20728810c16bSdanmcd hard->sadb_lifetime_addtime -
20738810c16bSdanmcd wallclock;
20748810c16bSdanmcd } else {
20758810c16bSdanmcd adddelta = TIME_MAX;
20768810c16bSdanmcd }
20778810c16bSdanmcd
20788810c16bSdanmcd if (hard->sadb_lifetime_usetime != 0 &&
20798810c16bSdanmcd current->sadb_lifetime_usetime != 0) {
20808810c16bSdanmcd usedelta =
20818810c16bSdanmcd current->sadb_lifetime_usetime +
20828810c16bSdanmcd hard->sadb_lifetime_usetime -
20838810c16bSdanmcd wallclock;
20848810c16bSdanmcd } else {
20858810c16bSdanmcd usedelta = TIME_MAX;
20868810c16bSdanmcd }
2087bb3ed8dfSpwernau (void) fprintf(file, "%s", hard_prefix);
20888810c16bSdanmcd scratch = MIN(adddelta, usedelta);
20898810c16bSdanmcd if (scratch >= 0) {
2090bb3ed8dfSpwernau (void) fprintf(file,
2091bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2092c51cb4bcSDan McDonald "Hard expiration occurs in %"
2093510c3f91SVladimir Kotal PRId64 " seconds%s\n"), scratch,
2094510c3f91SVladimir Kotal secs2out(scratch, secs_str,
2095510c3f91SVladimir Kotal sizeof (secs_str), SPC_BEGIN));
20968810c16bSdanmcd } else {
2097bb3ed8dfSpwernau (void) fprintf(file,
2098bb3ed8dfSpwernau dgettext(TEXT_DOMAIN,
2099510c3f91SVladimir Kotal "Hard expiration occurred\n"));
21008810c16bSdanmcd }
21018810c16bSdanmcd scratch += wallclock;
2102bb3ed8dfSpwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN,
2103510c3f91SVladimir Kotal "%sTime of expiration: %s.\n"),
2104510c3f91SVladimir Kotal hard_prefix, hard_prefix, vflag);
21058810c16bSdanmcd }
21068810c16bSdanmcd }
21078810c16bSdanmcd }
21089c2c14abSThejaswini Singarajipura if (idle != NULL) {
21099c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2110510c3f91SVladimir Kotal "%sIdle lifetime information:\n"), idle_prefix);
21119c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2112510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-add lifetime.\n"),
2113510c3f91SVladimir Kotal idle_prefix, idle->sadb_lifetime_addtime,
2114510c3f91SVladimir Kotal secs2out(idle->sadb_lifetime_addtime, secs_str,
2115510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
21169c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
2117510c3f91SVladimir Kotal "%s%" PRIu64 " seconds %sof post-use lifetime.\n"),
2118510c3f91SVladimir Kotal idle_prefix, idle->sadb_lifetime_usetime,
2119510c3f91SVladimir Kotal secs2out(idle->sadb_lifetime_usetime, secs_str,
2120510c3f91SVladimir Kotal sizeof (secs_str), SPC_END));
21219c2c14abSThejaswini Singarajipura }
21228810c16bSdanmcd }
21238810c16bSdanmcd
21248810c16bSdanmcd /*
21258810c16bSdanmcd * Print an SADB_EXT_ADDRESS_* extension.
21268810c16bSdanmcd */
21278810c16bSdanmcd void
print_address(FILE * file,char * prefix,struct sadb_address * addr,boolean_t ignore_nss)2128bb3ed8dfSpwernau print_address(FILE *file, char *prefix, struct sadb_address *addr,
2129bb3ed8dfSpwernau boolean_t ignore_nss)
21308810c16bSdanmcd {
21318810c16bSdanmcd struct protoent *pe;
21328810c16bSdanmcd
2133bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
21348810c16bSdanmcd switch (addr->sadb_address_exttype) {
21358810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
2136bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source address "));
21378810c16bSdanmcd break;
21388810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
2139bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2140bb3ed8dfSpwernau "Inner source address "));
21418810c16bSdanmcd break;
21428810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
2143bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2144bb3ed8dfSpwernau "Destination address "));
21458810c16bSdanmcd break;
21468810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
2147bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2148a7485808Smarkfen "Inner destination address "));
21498810c16bSdanmcd break;
21508810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
2151bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2152bb3ed8dfSpwernau "NAT-T local address "));
21538810c16bSdanmcd break;
21548810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
2155bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2156bb3ed8dfSpwernau "NAT-T remote address "));
21578810c16bSdanmcd break;
21588810c16bSdanmcd }
21598810c16bSdanmcd
2160bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2161a7485808Smarkfen "(proto=%d"), addr->sadb_address_proto);
2162bb3ed8dfSpwernau if (ignore_nss == B_FALSE) {
21638810c16bSdanmcd if (addr->sadb_address_proto == 0) {
2164bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2165bb3ed8dfSpwernau "/<unspecified>"));
21668810c16bSdanmcd } else if ((pe = getprotobynumber(addr->sadb_address_proto))
21678810c16bSdanmcd != NULL) {
2168bb3ed8dfSpwernau (void) fprintf(file, "/%s", pe->p_name);
21698810c16bSdanmcd } else {
2170bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2171bb3ed8dfSpwernau "/<unknown>"));
21728810c16bSdanmcd }
21738810c16bSdanmcd }
2174bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ")\n%s"), prefix);
21758810c16bSdanmcd (void) dump_sockaddr((struct sockaddr *)(addr + 1),
2176bb3ed8dfSpwernau addr->sadb_address_prefixlen, B_FALSE, file, ignore_nss);
21778810c16bSdanmcd }
21788810c16bSdanmcd
21798810c16bSdanmcd /*
21808810c16bSdanmcd * Print an SADB_EXT_KEY extension.
21818810c16bSdanmcd */
21828810c16bSdanmcd void
print_key(FILE * file,char * prefix,struct sadb_key * key)2183bb3ed8dfSpwernau print_key(FILE *file, char *prefix, struct sadb_key *key)
21848810c16bSdanmcd {
2185bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
21868810c16bSdanmcd
21878810c16bSdanmcd switch (key->sadb_key_exttype) {
21888810c16bSdanmcd case SADB_EXT_KEY_AUTH:
2189bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Authentication"));
21908810c16bSdanmcd break;
21918810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
2192bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Encryption"));
21938810c16bSdanmcd break;
21948810c16bSdanmcd }
21958810c16bSdanmcd
2196bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " key.\n%s"), prefix);
2197628b0c67SMark Fenwick (void) dump_key((uint8_t *)(key + 1), key->sadb_key_bits,
2198628b0c67SMark Fenwick key->sadb_key_reserved, file, B_TRUE);
2199bb3ed8dfSpwernau (void) fprintf(file, "\n");
22008810c16bSdanmcd }
22018810c16bSdanmcd
22028810c16bSdanmcd /*
22038810c16bSdanmcd * Print an SADB_EXT_IDENTITY_* extension.
22048810c16bSdanmcd */
22058810c16bSdanmcd void
print_ident(FILE * file,char * prefix,struct sadb_ident * id)2206bb3ed8dfSpwernau print_ident(FILE *file, char *prefix, struct sadb_ident *id)
22078810c16bSdanmcd {
22088810c16bSdanmcd boolean_t canprint = B_TRUE;
22098810c16bSdanmcd
2210bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
22118810c16bSdanmcd switch (id->sadb_ident_exttype) {
22128810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
2213bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source"));
22148810c16bSdanmcd break;
22158810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
2216bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Destination"));
22178810c16bSdanmcd break;
22188810c16bSdanmcd }
22198810c16bSdanmcd
2220bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2221a7485808Smarkfen " identity, uid=%d, type "), id->sadb_ident_id);
2222bb3ed8dfSpwernau canprint = dump_sadb_idtype(id->sadb_ident_type, file, NULL);
2223bb3ed8dfSpwernau (void) fprintf(file, "\n%s", prefix);
2224a12f8217Spwernau if (canprint) {
2225bb3ed8dfSpwernau (void) fprintf(file, "%s\n", (char *)(id + 1));
2226a12f8217Spwernau } else {
2227a12f8217Spwernau print_asn1_name(file, (const unsigned char *)(id + 1),
2228a12f8217Spwernau SADB_64TO8(id->sadb_ident_len) - sizeof (sadb_ident_t));
2229a12f8217Spwernau }
22308810c16bSdanmcd }
22318810c16bSdanmcd
22325d3b8cb7SBill Sommerfeld /*
22335d3b8cb7SBill Sommerfeld * Convert sadb_sens extension into binary security label.
22345d3b8cb7SBill Sommerfeld */
22355d3b8cb7SBill Sommerfeld
22365d3b8cb7SBill Sommerfeld #include <tsol/label.h>
22375d3b8cb7SBill Sommerfeld #include <sys/tsol/tndb.h>
22385d3b8cb7SBill Sommerfeld #include <sys/tsol/label_macro.h>
22395d3b8cb7SBill Sommerfeld
22405d3b8cb7SBill Sommerfeld void
ipsec_convert_sens_to_bslabel(const struct sadb_sens * sens,bslabel_t * sl)22415d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(const struct sadb_sens *sens, bslabel_t *sl)
22425d3b8cb7SBill Sommerfeld {
22435d3b8cb7SBill Sommerfeld uint64_t *bitmap = (uint64_t *)(sens + 1);
22445d3b8cb7SBill Sommerfeld int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
22455d3b8cb7SBill Sommerfeld
22465d3b8cb7SBill Sommerfeld bsllow(sl);
22475d3b8cb7SBill Sommerfeld LCLASS_SET((_bslabel_impl_t *)sl, sens->sadb_sens_sens_level);
22485d3b8cb7SBill Sommerfeld bcopy(bitmap, &((_bslabel_impl_t *)sl)->compartments,
22495d3b8cb7SBill Sommerfeld bitmap_len);
22505d3b8cb7SBill Sommerfeld }
22515d3b8cb7SBill Sommerfeld
22525d3b8cb7SBill Sommerfeld void
ipsec_convert_bslabel_to_string(bslabel_t * sl,char ** plabel)22535d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_string(bslabel_t *sl, char **plabel)
22545d3b8cb7SBill Sommerfeld {
22555d3b8cb7SBill Sommerfeld if (label_to_str(sl, plabel, M_LABEL, DEF_NAMES) != 0) {
22565d3b8cb7SBill Sommerfeld *plabel = strdup(dgettext(TEXT_DOMAIN,
22575d3b8cb7SBill Sommerfeld "** Label conversion failed **"));
22585d3b8cb7SBill Sommerfeld }
22595d3b8cb7SBill Sommerfeld }
22605d3b8cb7SBill Sommerfeld
22615d3b8cb7SBill Sommerfeld void
ipsec_convert_bslabel_to_hex(bslabel_t * sl,char ** plabel)22625d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(bslabel_t *sl, char **plabel)
22635d3b8cb7SBill Sommerfeld {
22645d3b8cb7SBill Sommerfeld if (label_to_str(sl, plabel, M_INTERNAL, DEF_NAMES) != 0) {
22655d3b8cb7SBill Sommerfeld *plabel = strdup(dgettext(TEXT_DOMAIN,
22665d3b8cb7SBill Sommerfeld "** Label conversion failed **"));
22675d3b8cb7SBill Sommerfeld }
22685d3b8cb7SBill Sommerfeld }
22695d3b8cb7SBill Sommerfeld
22705d3b8cb7SBill Sommerfeld int
ipsec_convert_sl_to_sens(int doi,bslabel_t * sl,sadb_sens_t * sens)22715d3b8cb7SBill Sommerfeld ipsec_convert_sl_to_sens(int doi, bslabel_t *sl, sadb_sens_t *sens)
22725d3b8cb7SBill Sommerfeld {
22735d3b8cb7SBill Sommerfeld uint8_t *bitmap;
22745d3b8cb7SBill Sommerfeld int sens_len = sizeof (sadb_sens_t) + _C_LEN * 4;
22755d3b8cb7SBill Sommerfeld
22765d3b8cb7SBill Sommerfeld
22775d3b8cb7SBill Sommerfeld if (sens == NULL)
22785d3b8cb7SBill Sommerfeld return (sens_len);
22795d3b8cb7SBill Sommerfeld
22805d3b8cb7SBill Sommerfeld
22815d3b8cb7SBill Sommerfeld (void) memset(sens, 0, sens_len);
22825d3b8cb7SBill Sommerfeld
22835d3b8cb7SBill Sommerfeld sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
22845d3b8cb7SBill Sommerfeld sens->sadb_sens_len = SADB_8TO64(sens_len);
22855d3b8cb7SBill Sommerfeld sens->sadb_sens_dpd = doi;
22865d3b8cb7SBill Sommerfeld
22875d3b8cb7SBill Sommerfeld sens->sadb_sens_sens_level = LCLASS(sl);
22885d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_level = 0;
22895d3b8cb7SBill Sommerfeld sens->sadb_sens_sens_len = _C_LEN >> 1;
22905d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_len = 0;
22915d3b8cb7SBill Sommerfeld
22925d3b8cb7SBill Sommerfeld sens->sadb_x_sens_flags = 0;
22935d3b8cb7SBill Sommerfeld
22945d3b8cb7SBill Sommerfeld bitmap = (uint8_t *)(sens + 1);
22955d3b8cb7SBill Sommerfeld bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
22965d3b8cb7SBill Sommerfeld
22975d3b8cb7SBill Sommerfeld return (sens_len);
22985d3b8cb7SBill Sommerfeld }
22995d3b8cb7SBill Sommerfeld
23005d3b8cb7SBill Sommerfeld
23018810c16bSdanmcd /*
23028810c16bSdanmcd * Print an SADB_SENSITIVITY extension.
23038810c16bSdanmcd */
23048810c16bSdanmcd void
print_sens(FILE * file,char * prefix,const struct sadb_sens * sens,boolean_t ignore_nss)23055d3b8cb7SBill Sommerfeld print_sens(FILE *file, char *prefix, const struct sadb_sens *sens,
230680ad54c9SToomas Soome boolean_t ignore_nss)
23078810c16bSdanmcd {
23085d3b8cb7SBill Sommerfeld char *plabel;
23095d3b8cb7SBill Sommerfeld char *hlabel;
23108810c16bSdanmcd uint64_t *bitmap = (uint64_t *)(sens + 1);
23115d3b8cb7SBill Sommerfeld bslabel_t sl;
23128810c16bSdanmcd int i;
23135d3b8cb7SBill Sommerfeld int sens_len = sens->sadb_sens_sens_len;
23145d3b8cb7SBill Sommerfeld int integ_len = sens->sadb_sens_integ_len;
23155d3b8cb7SBill Sommerfeld boolean_t inner = (sens->sadb_sens_exttype == SADB_EXT_SENSITIVITY);
23165d3b8cb7SBill Sommerfeld const char *sensname = inner ?
23175d3b8cb7SBill Sommerfeld dgettext(TEXT_DOMAIN, "Plaintext Sensitivity") :
23185d3b8cb7SBill Sommerfeld dgettext(TEXT_DOMAIN, "Ciphertext Sensitivity");
23195d3b8cb7SBill Sommerfeld
23205d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(sens, &sl);
23218810c16bSdanmcd
2322bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
23235d3b8cb7SBill Sommerfeld "%s%s DPD %d, sens level=%d, integ level=%d, flags=%x\n"),
23245d3b8cb7SBill Sommerfeld prefix, sensname, sens->sadb_sens_dpd, sens->sadb_sens_sens_level,
23255d3b8cb7SBill Sommerfeld sens->sadb_sens_integ_level, sens->sadb_x_sens_flags);
23265d3b8cb7SBill Sommerfeld
23275d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(&sl, &hlabel);
23285d3b8cb7SBill Sommerfeld
23295d3b8cb7SBill Sommerfeld if (ignore_nss) {
23305d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
23315d3b8cb7SBill Sommerfeld "%s %s Label: %s\n"), prefix, sensname, hlabel);
23325d3b8cb7SBill Sommerfeld
23335d3b8cb7SBill Sommerfeld for (i = 0; i < sens_len; i++, bitmap++)
23345d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
23355d3b8cb7SBill Sommerfeld "%s %s BM extended word %d 0x%" PRIx64 "\n"),
23365d3b8cb7SBill Sommerfeld prefix, sensname, i, *bitmap);
23375d3b8cb7SBill Sommerfeld
23385d3b8cb7SBill Sommerfeld } else {
23395d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_string(&sl, &plabel);
23405d3b8cb7SBill Sommerfeld
23415d3b8cb7SBill Sommerfeld (void) fprintf(file, dgettext(TEXT_DOMAIN,
23425d3b8cb7SBill Sommerfeld "%s %s Label: %s (%s)\n"),
23435d3b8cb7SBill Sommerfeld prefix, sensname, plabel, hlabel);
23445d3b8cb7SBill Sommerfeld free(plabel);
23455d3b8cb7SBill Sommerfeld
23465d3b8cb7SBill Sommerfeld }
23475d3b8cb7SBill Sommerfeld free(hlabel);
23485d3b8cb7SBill Sommerfeld
23495d3b8cb7SBill Sommerfeld bitmap = (uint64_t *)(sens + 1 + sens_len);
23505d3b8cb7SBill Sommerfeld
23515d3b8cb7SBill Sommerfeld for (i = 0; i < integ_len; i++, bitmap++)
2352bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2353c51cb4bcSDan McDonald "%s Integrity BM extended word %d 0x%" PRIx64 "\n"),
2354bb3ed8dfSpwernau prefix, i, *bitmap);
23558810c16bSdanmcd }
23568810c16bSdanmcd
23578810c16bSdanmcd /*
23588810c16bSdanmcd * Print an SADB_EXT_PROPOSAL extension.
23598810c16bSdanmcd */
23608810c16bSdanmcd void
print_prop(FILE * file,char * prefix,struct sadb_prop * prop)2361bb3ed8dfSpwernau print_prop(FILE *file, char *prefix, struct sadb_prop *prop)
23628810c16bSdanmcd {
23638810c16bSdanmcd struct sadb_comb *combs;
23648810c16bSdanmcd int i, numcombs;
23658810c16bSdanmcd
2366bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2367a7485808Smarkfen "%sProposal, replay counter = %u.\n"), prefix,
23688810c16bSdanmcd prop->sadb_prop_replay);
23698810c16bSdanmcd
23708810c16bSdanmcd numcombs = prop->sadb_prop_len - SADB_8TO64(sizeof (*prop));
23718810c16bSdanmcd numcombs /= SADB_8TO64(sizeof (*combs));
23728810c16bSdanmcd
23738810c16bSdanmcd combs = (struct sadb_comb *)(prop + 1);
23748810c16bSdanmcd
23758810c16bSdanmcd for (i = 0; i < numcombs; i++) {
2376bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2377a7485808Smarkfen "%s Combination #%u "), prefix, i + 1);
23788810c16bSdanmcd if (combs[i].sadb_comb_auth != SADB_AALG_NONE) {
2379bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2380a7485808Smarkfen "Authentication = "));
2381bb3ed8dfSpwernau (void) dump_aalg(combs[i].sadb_comb_auth, file);
2382bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2383a7485808Smarkfen " minbits=%u, maxbits=%u.\n%s "),
23848810c16bSdanmcd combs[i].sadb_comb_auth_minbits,
23858810c16bSdanmcd combs[i].sadb_comb_auth_maxbits, prefix);
23868810c16bSdanmcd }
23878810c16bSdanmcd
23888810c16bSdanmcd if (combs[i].sadb_comb_encrypt != SADB_EALG_NONE) {
2389bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2390bb3ed8dfSpwernau "Encryption = "));
2391bb3ed8dfSpwernau (void) dump_ealg(combs[i].sadb_comb_encrypt, file);
2392bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2393351128adSJason King " minbits=%u, maxbits=%u, saltbits=%u.\n%s "),
23948810c16bSdanmcd combs[i].sadb_comb_encrypt_minbits,
2395351128adSJason King combs[i].sadb_comb_encrypt_maxbits,
2396351128adSJason King combs[i].sadb_x_comb_encrypt_saltbits, prefix);
23978810c16bSdanmcd }
23988810c16bSdanmcd
2399bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "HARD: "));
24008810c16bSdanmcd if (combs[i].sadb_comb_hard_allocations)
2401bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "),
24028810c16bSdanmcd combs[i].sadb_comb_hard_allocations);
24038810c16bSdanmcd if (combs[i].sadb_comb_hard_bytes)
2404c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%"
2405c51cb4bcSDan McDonald PRIu64 " "), combs[i].sadb_comb_hard_bytes);
24068810c16bSdanmcd if (combs[i].sadb_comb_hard_addtime)
2407bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2408c51cb4bcSDan McDonald "post-add secs=%" PRIu64 " "),
24098810c16bSdanmcd combs[i].sadb_comb_hard_addtime);
24108810c16bSdanmcd if (combs[i].sadb_comb_hard_usetime)
2411bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2412c51cb4bcSDan McDonald "post-use secs=%" PRIu64 ""),
24138810c16bSdanmcd combs[i].sadb_comb_hard_usetime);
24148810c16bSdanmcd
2415bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%s SOFT: "),
2416bb3ed8dfSpwernau prefix);
24178810c16bSdanmcd if (combs[i].sadb_comb_soft_allocations)
2418bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "),
24198810c16bSdanmcd combs[i].sadb_comb_soft_allocations);
24208810c16bSdanmcd if (combs[i].sadb_comb_soft_bytes)
2421c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%"
2422c51cb4bcSDan McDonald PRIu64 " "), combs[i].sadb_comb_soft_bytes);
24238810c16bSdanmcd if (combs[i].sadb_comb_soft_addtime)
2424bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2425c51cb4bcSDan McDonald "post-add secs=%" PRIu64 " "),
24268810c16bSdanmcd combs[i].sadb_comb_soft_addtime);
24278810c16bSdanmcd if (combs[i].sadb_comb_soft_usetime)
2428bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2429c51cb4bcSDan McDonald "post-use secs=%" PRIu64 ""),
24308810c16bSdanmcd combs[i].sadb_comb_soft_usetime);
2431bb3ed8dfSpwernau (void) fprintf(file, "\n");
24328810c16bSdanmcd }
24338810c16bSdanmcd }
24348810c16bSdanmcd
24358810c16bSdanmcd /*
24368810c16bSdanmcd * Print an extended proposal (SADB_X_EXT_EPROP).
24378810c16bSdanmcd */
24388810c16bSdanmcd void
print_eprop(FILE * file,char * prefix,struct sadb_prop * eprop)2439bb3ed8dfSpwernau print_eprop(FILE *file, char *prefix, struct sadb_prop *eprop)
24408810c16bSdanmcd {
24418810c16bSdanmcd uint64_t *sofar;
24428810c16bSdanmcd struct sadb_x_ecomb *ecomb;
24438810c16bSdanmcd struct sadb_x_algdesc *algdesc;
24448810c16bSdanmcd int i, j;
24458810c16bSdanmcd
2446bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2447a7485808Smarkfen "%sExtended Proposal, replay counter = %u, "), prefix,
2448a7485808Smarkfen eprop->sadb_prop_replay);
2449bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2450bb3ed8dfSpwernau "number of combinations = %u.\n"), eprop->sadb_x_prop_numecombs);
24518810c16bSdanmcd
24528810c16bSdanmcd sofar = (uint64_t *)(eprop + 1);
24538810c16bSdanmcd ecomb = (struct sadb_x_ecomb *)sofar;
24548810c16bSdanmcd
24558810c16bSdanmcd for (i = 0; i < eprop->sadb_x_prop_numecombs; ) {
2456bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2457a7485808Smarkfen "%s Extended combination #%u:\n"), prefix, ++i);
24588810c16bSdanmcd
2459bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s HARD: "),
2460bb3ed8dfSpwernau prefix);
2461bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "),
24628810c16bSdanmcd ecomb->sadb_x_ecomb_hard_allocations);
2463c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%" PRIu64
2464c51cb4bcSDan McDonald ", "), ecomb->sadb_x_ecomb_hard_bytes);
2465c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-add secs=%"
2466c51cb4bcSDan McDonald PRIu64 ", "), ecomb->sadb_x_ecomb_hard_addtime);
2467c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%"
2468c51cb4bcSDan McDonald PRIu64 "\n"), ecomb->sadb_x_ecomb_hard_usetime);
24698810c16bSdanmcd
2470bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s SOFT: "),
2471bb3ed8dfSpwernau prefix);
2472bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "),
24738810c16bSdanmcd ecomb->sadb_x_ecomb_soft_allocations);
2474bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2475c51cb4bcSDan McDonald "bytes=%" PRIu64 ", "), ecomb->sadb_x_ecomb_soft_bytes);
2476bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2477c51cb4bcSDan McDonald "post-add secs=%" PRIu64 ", "),
2478c51cb4bcSDan McDonald ecomb->sadb_x_ecomb_soft_addtime);
2479c51cb4bcSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%"
2480c51cb4bcSDan McDonald PRIu64 "\n"), ecomb->sadb_x_ecomb_soft_usetime);
24818810c16bSdanmcd
24828810c16bSdanmcd sofar = (uint64_t *)(ecomb + 1);
24838810c16bSdanmcd algdesc = (struct sadb_x_algdesc *)sofar;
24848810c16bSdanmcd
24858810c16bSdanmcd for (j = 0; j < ecomb->sadb_x_ecomb_numalgs; ) {
2486bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2487a7485808Smarkfen "%s Alg #%u "), prefix, ++j);
24888810c16bSdanmcd switch (algdesc->sadb_x_algdesc_satype) {
24898810c16bSdanmcd case SADB_SATYPE_ESP:
2490bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2491a7485808Smarkfen "for ESP "));
24928810c16bSdanmcd break;
24938810c16bSdanmcd case SADB_SATYPE_AH:
2494bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2495bb3ed8dfSpwernau "for AH "));
24968810c16bSdanmcd break;
24978810c16bSdanmcd default:
2498bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2499a7485808Smarkfen "for satype=%d "),
25008810c16bSdanmcd algdesc->sadb_x_algdesc_satype);
25018810c16bSdanmcd }
25028810c16bSdanmcd switch (algdesc->sadb_x_algdesc_algtype) {
25038810c16bSdanmcd case SADB_X_ALGTYPE_CRYPT:
2504bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2505a7485808Smarkfen "Encryption = "));
25068810c16bSdanmcd (void) dump_ealg(algdesc->sadb_x_algdesc_alg,
2507bb3ed8dfSpwernau file);
25088810c16bSdanmcd break;
25098810c16bSdanmcd case SADB_X_ALGTYPE_AUTH:
2510bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2511a7485808Smarkfen "Authentication = "));
25128810c16bSdanmcd (void) dump_aalg(algdesc->sadb_x_algdesc_alg,
2513bb3ed8dfSpwernau file);
25148810c16bSdanmcd break;
25158810c16bSdanmcd default:
2516bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2517a7485808Smarkfen "algtype(%d) = alg(%d)"),
25188810c16bSdanmcd algdesc->sadb_x_algdesc_algtype,
25198810c16bSdanmcd algdesc->sadb_x_algdesc_alg);
25208810c16bSdanmcd break;
25218810c16bSdanmcd }
25228810c16bSdanmcd
2523bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2524628b0c67SMark Fenwick " minbits=%u, maxbits=%u, saltbits=%u\n"),
25258810c16bSdanmcd algdesc->sadb_x_algdesc_minbits,
2526628b0c67SMark Fenwick algdesc->sadb_x_algdesc_maxbits,
2527351128adSJason King algdesc->sadb_x_algdesc_saltbits);
25288810c16bSdanmcd
25298810c16bSdanmcd sofar = (uint64_t *)(++algdesc);
25308810c16bSdanmcd }
25318810c16bSdanmcd ecomb = (struct sadb_x_ecomb *)sofar;
25328810c16bSdanmcd }
25338810c16bSdanmcd }
25348810c16bSdanmcd
25358810c16bSdanmcd /*
25368810c16bSdanmcd * Print an SADB_EXT_SUPPORTED extension.
25378810c16bSdanmcd */
25388810c16bSdanmcd void
print_supp(FILE * file,char * prefix,struct sadb_supported * supp)2539bb3ed8dfSpwernau print_supp(FILE *file, char *prefix, struct sadb_supported *supp)
25408810c16bSdanmcd {
25418810c16bSdanmcd struct sadb_alg *algs;
25428810c16bSdanmcd int i, numalgs;
25438810c16bSdanmcd
2544bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sSupported "), prefix);
25458810c16bSdanmcd switch (supp->sadb_supported_exttype) {
25468810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2547bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "authentication"));
25488810c16bSdanmcd break;
25498810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2550bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "encryption"));
25518810c16bSdanmcd break;
25528810c16bSdanmcd }
2553bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " algorithms.\n"));
25548810c16bSdanmcd
25558810c16bSdanmcd algs = (struct sadb_alg *)(supp + 1);
25568810c16bSdanmcd numalgs = supp->sadb_supported_len - SADB_8TO64(sizeof (*supp));
25578810c16bSdanmcd numalgs /= SADB_8TO64(sizeof (*algs));
25588810c16bSdanmcd for (i = 0; i < numalgs; i++) {
2559e70cf235Svk uint16_t exttype = supp->sadb_supported_exttype;
2560e70cf235Svk
2561bb3ed8dfSpwernau (void) fprintf(file, "%s", prefix);
2562e70cf235Svk switch (exttype) {
25638810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2564bb3ed8dfSpwernau (void) dump_aalg(algs[i].sadb_alg_id, file);
25658810c16bSdanmcd break;
25668810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2567bb3ed8dfSpwernau (void) dump_ealg(algs[i].sadb_alg_id, file);
25688810c16bSdanmcd break;
25698810c16bSdanmcd }
2570bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2571628b0c67SMark Fenwick " minbits=%u, maxbits=%u, ivlen=%u, saltbits=%u"),
25728810c16bSdanmcd algs[i].sadb_alg_minbits, algs[i].sadb_alg_maxbits,
2573628b0c67SMark Fenwick algs[i].sadb_alg_ivlen, algs[i].sadb_x_alg_saltbits);
2574e70cf235Svk if (exttype == SADB_EXT_SUPPORTED_ENCRYPT)
2575e70cf235Svk (void) fprintf(file, dgettext(TEXT_DOMAIN,
2576e70cf235Svk ", increment=%u"), algs[i].sadb_x_alg_increment);
2577e70cf235Svk (void) fprintf(file, dgettext(TEXT_DOMAIN, ".\n"));
25788810c16bSdanmcd }
25798810c16bSdanmcd }
25808810c16bSdanmcd
25818810c16bSdanmcd /*
25828810c16bSdanmcd * Print an SADB_EXT_SPIRANGE extension.
25838810c16bSdanmcd */
25848810c16bSdanmcd void
print_spirange(FILE * file,char * prefix,struct sadb_spirange * range)2585bb3ed8dfSpwernau print_spirange(FILE *file, char *prefix, struct sadb_spirange *range)
25868810c16bSdanmcd {
2587bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2588a7485808Smarkfen "%sSPI Range, min=0x%x, max=0x%x\n"), prefix,
25898810c16bSdanmcd htonl(range->sadb_spirange_min),
25908810c16bSdanmcd htonl(range->sadb_spirange_max));
25918810c16bSdanmcd }
25928810c16bSdanmcd
25938810c16bSdanmcd /*
25948810c16bSdanmcd * Print an SADB_X_EXT_KM_COOKIE extension.
25958810c16bSdanmcd */
25968810c16bSdanmcd
25978810c16bSdanmcd void
print_kmc(FILE * file,char * prefix,struct sadb_x_kmc * kmc)2598bb3ed8dfSpwernau print_kmc(FILE *file, char *prefix, struct sadb_x_kmc *kmc)
25998810c16bSdanmcd {
26008810c16bSdanmcd char *cookie_label;
26018810c16bSdanmcd
2602f4a6f97eSDan McDonald switch (kmc->sadb_x_kmc_proto) {
2603f4a6f97eSDan McDonald case SADB_X_KMP_IKE:
2604f4a6f97eSDan McDonald cookie_label = kmc_lookup_by_cookie(kmc->sadb_x_kmc_cookie);
2605f4a6f97eSDan McDonald if (cookie_label == NULL)
2606f4a6f97eSDan McDonald cookie_label =
2607f4a6f97eSDan McDonald dgettext(TEXT_DOMAIN, "<Label not found.>");
2608f4a6f97eSDan McDonald (void) fprintf(file, dgettext(TEXT_DOMAIN,
2609cbc1abb4SDan McDonald "%s Protocol %u, cookie=\"%s\" (%u)\n"), prefix,
2610f4a6f97eSDan McDonald kmc->sadb_x_kmc_proto, cookie_label,
2611f4a6f97eSDan McDonald kmc->sadb_x_kmc_cookie);
2612f4a6f97eSDan McDonald return;
2613cbc1abb4SDan McDonald case SADB_X_KMP_KINK:
2614cbc1abb4SDan McDonald cookie_label = dgettext(TEXT_DOMAIN, "KINK:");
2615cbc1abb4SDan McDonald break;
2616f4a6f97eSDan McDonald case SADB_X_KMP_MANUAL:
2617cbc1abb4SDan McDonald cookie_label = dgettext(TEXT_DOMAIN, "Manual SA with cookie:");
2618f4a6f97eSDan McDonald break;
26194c5582efSJason King case SADB_X_KMP_IKEV2:
26204c5582efSJason King cookie_label = dgettext(TEXT_DOMAIN, "IKEV2:");
26214c5582efSJason King break;
2622f4a6f97eSDan McDonald default:
2623f4a6f97eSDan McDonald cookie_label =
2624f4a6f97eSDan McDonald dgettext(TEXT_DOMAIN, "<unknown KM protocol>");
2625f4a6f97eSDan McDonald break;
2626f4a6f97eSDan McDonald }
26278810c16bSdanmcd
2628cbc1abb4SDan McDonald /*
2629cbc1abb4SDan McDonald * Assume native-byte-order printing for now. Exceptions (like
2630cbc1abb4SDan McDonald * byte-swapping) should be handled in per-KM-protocol cases above.
2631cbc1abb4SDan McDonald */
2632bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2633cbc1abb4SDan McDonald "%s Protocol %u, cookie=\"%s\" (0x%"PRIx64"/%"PRIu64")\n"),
2634f4a6f97eSDan McDonald prefix, kmc->sadb_x_kmc_proto, cookie_label,
2635f4a6f97eSDan McDonald kmc->sadb_x_kmc_cookie64, kmc->sadb_x_kmc_cookie64);
26368810c16bSdanmcd }
26379c2c14abSThejaswini Singarajipura
26389c2c14abSThejaswini Singarajipura /*
26399c2c14abSThejaswini Singarajipura * Print an SADB_X_EXT_REPLAY_CTR extension.
26409c2c14abSThejaswini Singarajipura */
26419c2c14abSThejaswini Singarajipura
26429c2c14abSThejaswini Singarajipura void
print_replay(FILE * file,char * prefix,sadb_x_replay_ctr_t * repl)26439c2c14abSThejaswini Singarajipura print_replay(FILE *file, char *prefix, sadb_x_replay_ctr_t *repl)
26449c2c14abSThejaswini Singarajipura {
26459c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
26469c2c14abSThejaswini Singarajipura "%sReplay Value "), prefix);
26479c2c14abSThejaswini Singarajipura if ((repl->sadb_x_rc_replay32 == 0) &&
26489c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay64 == 0)) {
26499c2c14abSThejaswini Singarajipura (void) fprintf(file, dgettext(TEXT_DOMAIN,
26509c2c14abSThejaswini Singarajipura "<Value not found.>"));
26519c2c14abSThejaswini Singarajipura }
26529c2c14abSThejaswini Singarajipura /*
26539c2c14abSThejaswini Singarajipura * We currently do not support a 64-bit replay value.
26549c2c14abSThejaswini Singarajipura * RFC 4301 will require one, however, and we have a field
26559c2c14abSThejaswini Singarajipura * in place when 4301 is built.
26569c2c14abSThejaswini Singarajipura */
26579c2c14abSThejaswini Singarajipura (void) fprintf(file, "% " PRIu64 "\n",
26589c2c14abSThejaswini Singarajipura ((repl->sadb_x_rc_replay32 == 0) ?
26599c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay64 : repl->sadb_x_rc_replay32));
26609c2c14abSThejaswini Singarajipura }
266138d95a78Smarkfen /*
266238d95a78Smarkfen * Print an SADB_X_EXT_PAIR extension.
266338d95a78Smarkfen */
266438d95a78Smarkfen static void
print_pair(FILE * file,char * prefix,struct sadb_x_pair * pair)266538d95a78Smarkfen print_pair(FILE *file, char *prefix, struct sadb_x_pair *pair)
266638d95a78Smarkfen {
266738d95a78Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sPaired with spi=0x%x\n"),
266838d95a78Smarkfen prefix, ntohl(pair->sadb_x_pair_spi));
266938d95a78Smarkfen }
26708810c16bSdanmcd
26718810c16bSdanmcd /*
26728810c16bSdanmcd * Take a PF_KEY message pointed to buffer and print it. Useful for DUMP
26738810c16bSdanmcd * and GET.
26748810c16bSdanmcd */
26758810c16bSdanmcd void
print_samsg(FILE * file,uint64_t * buffer,boolean_t want_timestamp,boolean_t vflag,boolean_t ignore_nss)2676bb3ed8dfSpwernau print_samsg(FILE *file, uint64_t *buffer, boolean_t want_timestamp,
2677bb3ed8dfSpwernau boolean_t vflag, boolean_t ignore_nss)
26788810c16bSdanmcd {
26798810c16bSdanmcd uint64_t *current;
26808810c16bSdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer;
26818810c16bSdanmcd struct sadb_ext *ext;
26828810c16bSdanmcd struct sadb_lifetime *currentlt = NULL, *hardlt = NULL, *softlt = NULL;
26839c2c14abSThejaswini Singarajipura struct sadb_lifetime *idlelt = NULL;
26848810c16bSdanmcd int i;
26858810c16bSdanmcd time_t wallclock;
26868810c16bSdanmcd
26878810c16bSdanmcd (void) time(&wallclock);
26888810c16bSdanmcd
2689bb3ed8dfSpwernau print_sadb_msg(file, samsg, want_timestamp ? wallclock : 0, vflag);
26908810c16bSdanmcd current = (uint64_t *)(samsg + 1);
26918810c16bSdanmcd while (current - buffer < samsg->sadb_msg_len) {
26928810c16bSdanmcd int lenbytes;
26938810c16bSdanmcd
26948810c16bSdanmcd ext = (struct sadb_ext *)current;
26958810c16bSdanmcd lenbytes = SADB_64TO8(ext->sadb_ext_len);
26968810c16bSdanmcd switch (ext->sadb_ext_type) {
26978810c16bSdanmcd case SADB_EXT_SA:
2698bb3ed8dfSpwernau print_sa(file, dgettext(TEXT_DOMAIN,
2699a7485808Smarkfen "SA: "), (struct sadb_sa *)current);
27008810c16bSdanmcd break;
27018810c16bSdanmcd /*
27028810c16bSdanmcd * Pluck out lifetimes and print them at the end. This is
27038810c16bSdanmcd * to show relative lifetimes.
27048810c16bSdanmcd */
27058810c16bSdanmcd case SADB_EXT_LIFETIME_CURRENT:
27068810c16bSdanmcd currentlt = (struct sadb_lifetime *)current;
27078810c16bSdanmcd break;
27088810c16bSdanmcd case SADB_EXT_LIFETIME_HARD:
27098810c16bSdanmcd hardlt = (struct sadb_lifetime *)current;
27108810c16bSdanmcd break;
27118810c16bSdanmcd case SADB_EXT_LIFETIME_SOFT:
27128810c16bSdanmcd softlt = (struct sadb_lifetime *)current;
27138810c16bSdanmcd break;
27149c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
27159c2c14abSThejaswini Singarajipura idlelt = (struct sadb_lifetime *)current;
27169c2c14abSThejaswini Singarajipura break;
27178810c16bSdanmcd
27188810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
2719bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "SRC: "),
2720bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27218810c16bSdanmcd break;
27228810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
2723bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "INS: "),
2724bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27258810c16bSdanmcd break;
27268810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
2727bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "DST: "),
2728bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27298810c16bSdanmcd break;
27308810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
2731bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "IND: "),
2732bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27338810c16bSdanmcd break;
27348810c16bSdanmcd case SADB_EXT_KEY_AUTH:
2735bb3ed8dfSpwernau print_key(file, dgettext(TEXT_DOMAIN,
2736a7485808Smarkfen "AKY: "), (struct sadb_key *)current);
27378810c16bSdanmcd break;
27388810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
2739bb3ed8dfSpwernau print_key(file, dgettext(TEXT_DOMAIN,
2740a7485808Smarkfen "EKY: "), (struct sadb_key *)current);
27418810c16bSdanmcd break;
27428810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
2743bb3ed8dfSpwernau print_ident(file, dgettext(TEXT_DOMAIN, "SID: "),
27448810c16bSdanmcd (struct sadb_ident *)current);
27458810c16bSdanmcd break;
27468810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
2747bb3ed8dfSpwernau print_ident(file, dgettext(TEXT_DOMAIN, "DID: "),
27488810c16bSdanmcd (struct sadb_ident *)current);
27498810c16bSdanmcd break;
27508810c16bSdanmcd case SADB_EXT_SENSITIVITY:
2751bb3ed8dfSpwernau print_sens(file, dgettext(TEXT_DOMAIN, "SNS: "),
27525d3b8cb7SBill Sommerfeld (struct sadb_sens *)current, ignore_nss);
27538810c16bSdanmcd break;
27548810c16bSdanmcd case SADB_EXT_PROPOSAL:
2755bb3ed8dfSpwernau print_prop(file, dgettext(TEXT_DOMAIN, "PRP: "),
27568810c16bSdanmcd (struct sadb_prop *)current);
27578810c16bSdanmcd break;
27588810c16bSdanmcd case SADB_EXT_SUPPORTED_AUTH:
2759bb3ed8dfSpwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUA: "),
27608810c16bSdanmcd (struct sadb_supported *)current);
27618810c16bSdanmcd break;
27628810c16bSdanmcd case SADB_EXT_SUPPORTED_ENCRYPT:
2763bb3ed8dfSpwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUE: "),
27648810c16bSdanmcd (struct sadb_supported *)current);
27658810c16bSdanmcd break;
27668810c16bSdanmcd case SADB_EXT_SPIRANGE:
2767bb3ed8dfSpwernau print_spirange(file, dgettext(TEXT_DOMAIN, "SPR: "),
27688810c16bSdanmcd (struct sadb_spirange *)current);
27698810c16bSdanmcd break;
27708810c16bSdanmcd case SADB_X_EXT_EPROP:
2771bb3ed8dfSpwernau print_eprop(file, dgettext(TEXT_DOMAIN, "EPR: "),
27728810c16bSdanmcd (struct sadb_prop *)current);
27738810c16bSdanmcd break;
27748810c16bSdanmcd case SADB_X_EXT_KM_COOKIE:
2775bb3ed8dfSpwernau print_kmc(file, dgettext(TEXT_DOMAIN, "KMC: "),
27768810c16bSdanmcd (struct sadb_x_kmc *)current);
27778810c16bSdanmcd break;
27788810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
2779bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "NRM: "),
2780bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27818810c16bSdanmcd break;
27828810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
2783bb3ed8dfSpwernau print_address(file, dgettext(TEXT_DOMAIN, "NLC: "),
2784bb3ed8dfSpwernau (struct sadb_address *)current, ignore_nss);
27858810c16bSdanmcd break;
278638d95a78Smarkfen case SADB_X_EXT_PAIR:
278738d95a78Smarkfen print_pair(file, dgettext(TEXT_DOMAIN, "OTH: "),
278838d95a78Smarkfen (struct sadb_x_pair *)current);
278938d95a78Smarkfen break;
27905d3b8cb7SBill Sommerfeld case SADB_X_EXT_OUTER_SENS:
27915d3b8cb7SBill Sommerfeld print_sens(file, dgettext(TEXT_DOMAIN, "OSN: "),
27925d3b8cb7SBill Sommerfeld (struct sadb_sens *)current, ignore_nss);
27935d3b8cb7SBill Sommerfeld break;
27949c2c14abSThejaswini Singarajipura case SADB_X_EXT_REPLAY_VALUE:
27959c2c14abSThejaswini Singarajipura (void) print_replay(file, dgettext(TEXT_DOMAIN,
27969c2c14abSThejaswini Singarajipura "RPL: "), (sadb_x_replay_ctr_t *)current);
27979c2c14abSThejaswini Singarajipura break;
27988810c16bSdanmcd default:
2799bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
28008810c16bSdanmcd "UNK: Unknown ext. %d, len %d.\n"),
28018810c16bSdanmcd ext->sadb_ext_type, lenbytes);
28028810c16bSdanmcd for (i = 0; i < ext->sadb_ext_len; i++)
2803bb3ed8dfSpwernau (void) fprintf(file, dgettext(TEXT_DOMAIN,
2804c51cb4bcSDan McDonald "UNK: 0x%" PRIx64 "\n"),
2805c51cb4bcSDan McDonald ((uint64_t *)ext)[i]);
28068810c16bSdanmcd break;
28078810c16bSdanmcd }
28088810c16bSdanmcd current += (lenbytes == 0) ?
28098810c16bSdanmcd SADB_8TO64(sizeof (struct sadb_ext)) : ext->sadb_ext_len;
28108810c16bSdanmcd }
28118810c16bSdanmcd /*
28128810c16bSdanmcd * Print lifetimes NOW.
28138810c16bSdanmcd */
28149c2c14abSThejaswini Singarajipura if (currentlt != NULL || hardlt != NULL || softlt != NULL ||
28159c2c14abSThejaswini Singarajipura idlelt != NULL)
28169c2c14abSThejaswini Singarajipura print_lifetimes(file, wallclock, currentlt, hardlt,
28179c2c14abSThejaswini Singarajipura softlt, idlelt, vflag);
28188810c16bSdanmcd
28198810c16bSdanmcd if (current - buffer != samsg->sadb_msg_len) {
2820bb3ed8dfSpwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN,
2821bb3ed8dfSpwernau "WARNING: insufficient buffer space or corrupt message."));
28228810c16bSdanmcd }
28238810c16bSdanmcd
2824bb3ed8dfSpwernau (void) fflush(file); /* Make sure our message is out there. */
28258810c16bSdanmcd }
28268810c16bSdanmcd
28278810c16bSdanmcd /*
28288810c16bSdanmcd * save_XXX functions are used when "saving" the SA tables to either a
28298810c16bSdanmcd * file or standard output. They use the dump_XXX functions where needed,
28308810c16bSdanmcd * but mostly they use the rparseXXX functions.
28318810c16bSdanmcd */
28328810c16bSdanmcd
28338810c16bSdanmcd /*
28348810c16bSdanmcd * Print save information for a lifetime extension.
28358810c16bSdanmcd *
28368810c16bSdanmcd * NOTE : It saves the lifetime in absolute terms. For example, if you
28378810c16bSdanmcd * had a hard_usetime of 60 seconds, you'll save it as 60 seconds, even though
28388810c16bSdanmcd * there may have been 59 seconds burned off the clock.
28398810c16bSdanmcd */
28408810c16bSdanmcd boolean_t
save_lifetime(struct sadb_lifetime * lifetime,FILE * ofile)28418810c16bSdanmcd save_lifetime(struct sadb_lifetime *lifetime, FILE *ofile)
28428810c16bSdanmcd {
28438810c16bSdanmcd char *prefix;
28448810c16bSdanmcd
28459c2c14abSThejaswini Singarajipura switch (lifetime->sadb_lifetime_exttype) {
28469c2c14abSThejaswini Singarajipura case SADB_EXT_LIFETIME_HARD:
28479c2c14abSThejaswini Singarajipura prefix = "hard";
28489c2c14abSThejaswini Singarajipura break;
28499c2c14abSThejaswini Singarajipura case SADB_EXT_LIFETIME_SOFT:
28509c2c14abSThejaswini Singarajipura prefix = "soft";
28519c2c14abSThejaswini Singarajipura break;
28529c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
28539c2c14abSThejaswini Singarajipura prefix = "idle";
28549c2c14abSThejaswini Singarajipura break;
28559c2c14abSThejaswini Singarajipura }
28568810c16bSdanmcd
28578810c16bSdanmcd if (putc('\t', ofile) == EOF)
28588810c16bSdanmcd return (B_FALSE);
28598810c16bSdanmcd
28608810c16bSdanmcd if (lifetime->sadb_lifetime_allocations != 0 && fprintf(ofile,
28618810c16bSdanmcd "%s_alloc %u ", prefix, lifetime->sadb_lifetime_allocations) < 0)
28628810c16bSdanmcd return (B_FALSE);
28638810c16bSdanmcd
28648810c16bSdanmcd if (lifetime->sadb_lifetime_bytes != 0 && fprintf(ofile,
2865c51cb4bcSDan McDonald "%s_bytes %" PRIu64 " ", prefix, lifetime->sadb_lifetime_bytes) < 0)
28668810c16bSdanmcd return (B_FALSE);
28678810c16bSdanmcd
28688810c16bSdanmcd if (lifetime->sadb_lifetime_addtime != 0 && fprintf(ofile,
2869c51cb4bcSDan McDonald "%s_addtime %" PRIu64 " ", prefix,
2870c51cb4bcSDan McDonald lifetime->sadb_lifetime_addtime) < 0)
28718810c16bSdanmcd return (B_FALSE);
28728810c16bSdanmcd
28738810c16bSdanmcd if (lifetime->sadb_lifetime_usetime != 0 && fprintf(ofile,
2874c51cb4bcSDan McDonald "%s_usetime %" PRIu64 " ", prefix,
2875c51cb4bcSDan McDonald lifetime->sadb_lifetime_usetime) < 0)
28768810c16bSdanmcd return (B_FALSE);
28778810c16bSdanmcd
28788810c16bSdanmcd return (B_TRUE);
28798810c16bSdanmcd }
28808810c16bSdanmcd
28818810c16bSdanmcd /*
28828810c16bSdanmcd * Print save information for an address extension.
28838810c16bSdanmcd */
28848810c16bSdanmcd boolean_t
save_address(struct sadb_address * addr,FILE * ofile)28858810c16bSdanmcd save_address(struct sadb_address *addr, FILE *ofile)
28868810c16bSdanmcd {
28878810c16bSdanmcd char *printable_addr, buf[INET6_ADDRSTRLEN];
28888810c16bSdanmcd const char *prefix, *pprefix;
28898810c16bSdanmcd struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(addr + 1);
28908810c16bSdanmcd struct sockaddr_in *sin = (struct sockaddr_in *)sin6;
28918810c16bSdanmcd int af = sin->sin_family;
28928810c16bSdanmcd
28938810c16bSdanmcd /*
28948810c16bSdanmcd * Address-family reality check.
28958810c16bSdanmcd */
28968810c16bSdanmcd if (af != AF_INET6 && af != AF_INET)
28978810c16bSdanmcd return (B_FALSE);
28988810c16bSdanmcd
28998810c16bSdanmcd switch (addr->sadb_address_exttype) {
29008810c16bSdanmcd case SADB_EXT_ADDRESS_SRC:
29018810c16bSdanmcd prefix = "src";
29028810c16bSdanmcd pprefix = "sport";
29038810c16bSdanmcd break;
29048810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
29058810c16bSdanmcd prefix = "isrc";
29068810c16bSdanmcd pprefix = "isport";
29078810c16bSdanmcd break;
29088810c16bSdanmcd case SADB_EXT_ADDRESS_DST:
29098810c16bSdanmcd prefix = "dst";
29108810c16bSdanmcd pprefix = "dport";
29118810c16bSdanmcd break;
29128810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
29138810c16bSdanmcd prefix = "idst";
29148810c16bSdanmcd pprefix = "idport";
29158810c16bSdanmcd break;
29168810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
29178810c16bSdanmcd prefix = "nat_loc ";
29188810c16bSdanmcd pprefix = "nat_lport";
29198810c16bSdanmcd break;
29208810c16bSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
29218810c16bSdanmcd prefix = "nat_rem ";
29228810c16bSdanmcd pprefix = "nat_rport";
29238810c16bSdanmcd break;
29248810c16bSdanmcd }
29258810c16bSdanmcd
29268810c16bSdanmcd if (fprintf(ofile, " %s ", prefix) < 0)
29278810c16bSdanmcd return (B_FALSE);
29288810c16bSdanmcd
29298810c16bSdanmcd /*
29308810c16bSdanmcd * Do not do address-to-name translation, given that we live in
29318810c16bSdanmcd * an age of names that explode into many addresses.
29328810c16bSdanmcd */
29338810c16bSdanmcd printable_addr = (char *)inet_ntop(af,
29348810c16bSdanmcd (af == AF_INET) ? (char *)&sin->sin_addr : (char *)&sin6->sin6_addr,
29358810c16bSdanmcd buf, sizeof (buf));
29368810c16bSdanmcd if (printable_addr == NULL)
2937a7485808Smarkfen printable_addr = "Invalid IP address.";
29388810c16bSdanmcd if (fprintf(ofile, "%s", printable_addr) < 0)
29398810c16bSdanmcd return (B_FALSE);
29408810c16bSdanmcd if (addr->sadb_address_prefixlen != 0 &&
29418810c16bSdanmcd !((addr->sadb_address_prefixlen == 32 && af == AF_INET) ||
294225e435e0Spwernau (addr->sadb_address_prefixlen == 128 && af == AF_INET6))) {
29438810c16bSdanmcd if (fprintf(ofile, "/%d", addr->sadb_address_prefixlen) < 0)
29448810c16bSdanmcd return (B_FALSE);
29458810c16bSdanmcd }
29468810c16bSdanmcd
29478810c16bSdanmcd /*
29488810c16bSdanmcd * The port is in the same position for struct sockaddr_in and
29498810c16bSdanmcd * struct sockaddr_in6. We exploit that property here.
29508810c16bSdanmcd */
29518810c16bSdanmcd if ((pprefix != NULL) && (sin->sin_port != 0))
29528810c16bSdanmcd (void) fprintf(ofile, " %s %d", pprefix, ntohs(sin->sin_port));
29538810c16bSdanmcd
29548810c16bSdanmcd return (B_TRUE);
29558810c16bSdanmcd }
29568810c16bSdanmcd
29578810c16bSdanmcd /*
29588810c16bSdanmcd * Print save information for a key extension. Returns whether writing
29598810c16bSdanmcd * to the specified output file was successful or not.
29608810c16bSdanmcd */
29618810c16bSdanmcd boolean_t
save_key(struct sadb_key * key,FILE * ofile)29628810c16bSdanmcd save_key(struct sadb_key *key, FILE *ofile)
29638810c16bSdanmcd {
29648810c16bSdanmcd char *prefix;
29658810c16bSdanmcd
29668810c16bSdanmcd if (putc('\t', ofile) == EOF)
29678810c16bSdanmcd return (B_FALSE);
29688810c16bSdanmcd
29698810c16bSdanmcd prefix = (key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ? "auth" : "encr";
29708810c16bSdanmcd
29718810c16bSdanmcd if (fprintf(ofile, "%skey ", prefix) < 0)
29728810c16bSdanmcd return (B_FALSE);
29738810c16bSdanmcd
2974628b0c67SMark Fenwick if (dump_key((uint8_t *)(key + 1), key->sadb_key_bits,
2975628b0c67SMark Fenwick key->sadb_key_reserved, ofile, B_FALSE) == -1)
29768810c16bSdanmcd return (B_FALSE);
29778810c16bSdanmcd
29788810c16bSdanmcd return (B_TRUE);
29798810c16bSdanmcd }
29808810c16bSdanmcd
29818810c16bSdanmcd /*
29828810c16bSdanmcd * Print save information for an identity extension.
29838810c16bSdanmcd */
29848810c16bSdanmcd boolean_t
save_ident(struct sadb_ident * ident,FILE * ofile)29858810c16bSdanmcd save_ident(struct sadb_ident *ident, FILE *ofile)
29868810c16bSdanmcd {
29878810c16bSdanmcd char *prefix;
29888810c16bSdanmcd
29898810c16bSdanmcd if (putc('\t', ofile) == EOF)
29908810c16bSdanmcd return (B_FALSE);
29918810c16bSdanmcd
29928810c16bSdanmcd prefix = (ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ? "src" :
29938810c16bSdanmcd "dst";
29948810c16bSdanmcd
29958810c16bSdanmcd if (fprintf(ofile, "%sidtype %s ", prefix,
29968810c16bSdanmcd rparseidtype(ident->sadb_ident_type)) < 0)
29978810c16bSdanmcd return (B_FALSE);
29988810c16bSdanmcd
29998810c16bSdanmcd if (ident->sadb_ident_type == SADB_X_IDENTTYPE_DN ||
30008810c16bSdanmcd ident->sadb_ident_type == SADB_X_IDENTTYPE_GN) {
3001a7485808Smarkfen if (fprintf(ofile, dgettext(TEXT_DOMAIN,
3002a7485808Smarkfen "<can-not-print>")) < 0)
30038810c16bSdanmcd return (B_FALSE);
30048810c16bSdanmcd } else {
30058810c16bSdanmcd if (fprintf(ofile, "%s", (char *)(ident + 1)) < 0)
30068810c16bSdanmcd return (B_FALSE);
30078810c16bSdanmcd }
30088810c16bSdanmcd
30098810c16bSdanmcd return (B_TRUE);
30108810c16bSdanmcd }
30118810c16bSdanmcd
30125d3b8cb7SBill Sommerfeld boolean_t
save_sens(struct sadb_sens * sens,FILE * ofile)30135d3b8cb7SBill Sommerfeld save_sens(struct sadb_sens *sens, FILE *ofile)
30145d3b8cb7SBill Sommerfeld {
30155d3b8cb7SBill Sommerfeld char *prefix;
30165d3b8cb7SBill Sommerfeld char *hlabel;
30175d3b8cb7SBill Sommerfeld bslabel_t sl;
30185d3b8cb7SBill Sommerfeld
30195d3b8cb7SBill Sommerfeld if (putc('\t', ofile) == EOF)
30205d3b8cb7SBill Sommerfeld return (B_FALSE);
30215d3b8cb7SBill Sommerfeld
30225d3b8cb7SBill Sommerfeld if (sens->sadb_sens_exttype == SADB_EXT_SENSITIVITY)
30235d3b8cb7SBill Sommerfeld prefix = "label";
30245d3b8cb7SBill Sommerfeld else if ((sens->sadb_x_sens_flags & SADB_X_SENS_IMPLICIT) == 0)
30255d3b8cb7SBill Sommerfeld prefix = "outer-label";
30265d3b8cb7SBill Sommerfeld else
30275d3b8cb7SBill Sommerfeld prefix = "implicit-label";
30285d3b8cb7SBill Sommerfeld
30295d3b8cb7SBill Sommerfeld ipsec_convert_sens_to_bslabel(sens, &sl);
30305d3b8cb7SBill Sommerfeld ipsec_convert_bslabel_to_hex(&sl, &hlabel);
30315d3b8cb7SBill Sommerfeld
30325d3b8cb7SBill Sommerfeld if (fprintf(ofile, "%s %s ", prefix, hlabel) < 0) {
30335d3b8cb7SBill Sommerfeld free(hlabel);
30345d3b8cb7SBill Sommerfeld return (B_FALSE);
30355d3b8cb7SBill Sommerfeld }
30365d3b8cb7SBill Sommerfeld free(hlabel);
30375d3b8cb7SBill Sommerfeld
30385d3b8cb7SBill Sommerfeld return (B_TRUE);
30395d3b8cb7SBill Sommerfeld }
30405d3b8cb7SBill Sommerfeld
30418810c16bSdanmcd /*
30428810c16bSdanmcd * "Save" a security association to an output file.
30438810c16bSdanmcd *
3044a7485808Smarkfen * NOTE the lack of calls to dgettext() because I'm outputting parseable stuff.
30458810c16bSdanmcd * ALSO NOTE that if you change keywords (see parsecmd()), you'll have to
30468810c16bSdanmcd * change them here as well.
30478810c16bSdanmcd */
30488810c16bSdanmcd void
save_assoc(uint64_t * buffer,FILE * ofile)30498810c16bSdanmcd save_assoc(uint64_t *buffer, FILE *ofile)
30508810c16bSdanmcd {
3051a7485808Smarkfen int terrno;
3052437220cdSdanmcd boolean_t seen_proto = B_FALSE, seen_iproto = B_FALSE;
30538810c16bSdanmcd uint64_t *current;
30548810c16bSdanmcd struct sadb_address *addr;
30559c2c14abSThejaswini Singarajipura struct sadb_x_replay_ctr *repl;
30568810c16bSdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer;
30578810c16bSdanmcd struct sadb_ext *ext;
30588810c16bSdanmcd
3059a7485808Smarkfen #define tidyup() \
3060a7485808Smarkfen terrno = errno; (void) fclose(ofile); errno = terrno; \
3061a7485808Smarkfen interactive = B_FALSE
3062a7485808Smarkfen
3063a7485808Smarkfen #define savenl() if (fputs(" \\\n", ofile) == EOF) \
3064a7485808Smarkfen { bail(dgettext(TEXT_DOMAIN, "savenl")); }
30658810c16bSdanmcd
30668810c16bSdanmcd if (fputs("# begin assoc\n", ofile) == EOF)
3067a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3068a7485808Smarkfen "save_assoc: Opening comment of SA"));
30698810c16bSdanmcd if (fprintf(ofile, "add %s ", rparsesatype(samsg->sadb_msg_satype)) < 0)
3070a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: First line of SA"));
30718810c16bSdanmcd savenl();
30728810c16bSdanmcd
30738810c16bSdanmcd current = (uint64_t *)(samsg + 1);
30748810c16bSdanmcd while (current - buffer < samsg->sadb_msg_len) {
30758810c16bSdanmcd struct sadb_sa *assoc;
30768810c16bSdanmcd
30778810c16bSdanmcd ext = (struct sadb_ext *)current;
3078437220cdSdanmcd addr = (struct sadb_address *)ext; /* Just in case... */
30798810c16bSdanmcd switch (ext->sadb_ext_type) {
30808810c16bSdanmcd case SADB_EXT_SA:
30818810c16bSdanmcd assoc = (struct sadb_sa *)ext;
30828810c16bSdanmcd if (assoc->sadb_sa_state != SADB_SASTATE_MATURE) {
30838810c16bSdanmcd if (fprintf(ofile, "# WARNING: SA was dying "
30848810c16bSdanmcd "or dead.\n") < 0) {
3085a7485808Smarkfen tidyup();
3086a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3087a7485808Smarkfen "save_assoc: fprintf not mature"));
30888810c16bSdanmcd }
30898810c16bSdanmcd }
30908810c16bSdanmcd if (fprintf(ofile, " spi 0x%x ",
3091a7485808Smarkfen ntohl(assoc->sadb_sa_spi)) < 0) {
3092a7485808Smarkfen tidyup();
3093a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3094a7485808Smarkfen "save_assoc: fprintf spi"));
3095a7485808Smarkfen }
30968810c16bSdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) {
30978810c16bSdanmcd if (fprintf(ofile, "encr_alg %s ",
30988810c16bSdanmcd rparsealg(assoc->sadb_sa_encrypt,
309925e435e0Spwernau IPSEC_PROTO_ESP)) < 0) {
3100a7485808Smarkfen tidyup();
3101a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3102a7485808Smarkfen "save_assoc: fprintf encrypt"));
3103a7485808Smarkfen }
31048810c16bSdanmcd }
31058810c16bSdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) {
31068810c16bSdanmcd if (fprintf(ofile, "auth_alg %s ",
31078810c16bSdanmcd rparsealg(assoc->sadb_sa_auth,
310825e435e0Spwernau IPSEC_PROTO_AH)) < 0) {
3109a7485808Smarkfen tidyup();
3110a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3111a7485808Smarkfen "save_assoc: fprintf auth"));
3112a7485808Smarkfen }
31138810c16bSdanmcd }
31148810c16bSdanmcd if (fprintf(ofile, "replay %d ",
3115a7485808Smarkfen assoc->sadb_sa_replay) < 0) {
3116a7485808Smarkfen tidyup();
3117a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3118a7485808Smarkfen "save_assoc: fprintf replay"));
3119a7485808Smarkfen }
31208810c16bSdanmcd if (assoc->sadb_sa_flags & (SADB_X_SAFLAGS_NATT_LOC |
31218810c16bSdanmcd SADB_X_SAFLAGS_NATT_REM)) {
3122a7485808Smarkfen if (fprintf(ofile, "encap udp") < 0) {
3123a7485808Smarkfen tidyup();
3124a7485808Smarkfen bail(dgettext(TEXT_DOMAIN,
3125a7485808Smarkfen "save_assoc: fprintf encap"));
3126a7485808Smarkfen }
31278810c16bSdanmcd }
31288810c16bSdanmcd savenl();
31298810c16bSdanmcd break;
31308810c16bSdanmcd case SADB_EXT_LIFETIME_HARD:
31318810c16bSdanmcd case SADB_EXT_LIFETIME_SOFT:
31329c2c14abSThejaswini Singarajipura case SADB_X_EXT_LIFETIME_IDLE:
3133a7485808Smarkfen if (!save_lifetime((struct sadb_lifetime *)ext,
3134a7485808Smarkfen ofile)) {
3135a7485808Smarkfen tidyup();
3136a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_lifetime"));
3137a7485808Smarkfen }
31388810c16bSdanmcd savenl();
31398810c16bSdanmcd break;
31408810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC:
31418810c16bSdanmcd case SADB_X_EXT_ADDRESS_INNER_DST:
3142437220cdSdanmcd if (!seen_iproto && addr->sadb_address_proto) {
3143437220cdSdanmcd (void) fprintf(ofile, " iproto %d",
3144437220cdSdanmcd addr->sadb_address_proto);
3145437220cdSdanmcd savenl();
3146437220cdSdanmcd seen_iproto = B_TRUE;
3147437220cdSdanmcd }
3148437220cdSdanmcd goto skip_srcdst; /* Hack to avoid cases below... */
3149437220cdSdanmcd /* FALLTHRU */
3150437220cdSdanmcd case SADB_EXT_ADDRESS_SRC:
3151437220cdSdanmcd case SADB_EXT_ADDRESS_DST:
31528810c16bSdanmcd if (!seen_proto && addr->sadb_address_proto) {
31538810c16bSdanmcd (void) fprintf(ofile, " proto %d",
31548810c16bSdanmcd addr->sadb_address_proto);
31558810c16bSdanmcd savenl();
3156437220cdSdanmcd seen_proto = B_TRUE;
31578810c16bSdanmcd }
3158437220cdSdanmcd /* FALLTHRU */
3159437220cdSdanmcd case SADB_X_EXT_ADDRESS_NATT_REM:
3160437220cdSdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC:
3161437220cdSdanmcd skip_srcdst:
3162a7485808Smarkfen if (!save_address(addr, ofile)) {
3163a7485808Smarkfen tidyup();
3164a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3165a7485808Smarkfen }
31668810c16bSdanmcd savenl();
31678810c16bSdanmcd break;
31688810c16bSdanmcd case SADB_EXT_KEY_AUTH:
31698810c16bSdanmcd case SADB_EXT_KEY_ENCRYPT:
3170a7485808Smarkfen if (!save_key((struct sadb_key *)ext, ofile)) {
3171a7485808Smarkfen tidyup();
3172a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3173a7485808Smarkfen }
31748810c16bSdanmcd savenl();
31758810c16bSdanmcd break;
31768810c16bSdanmcd case SADB_EXT_IDENTITY_SRC:
31778810c16bSdanmcd case SADB_EXT_IDENTITY_DST:
3178a7485808Smarkfen if (!save_ident((struct sadb_ident *)ext, ofile)) {
3179a7485808Smarkfen tidyup();
3180a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address"));
3181a7485808Smarkfen }
31828810c16bSdanmcd savenl();
31838810c16bSdanmcd break;
31849c2c14abSThejaswini Singarajipura case SADB_X_EXT_REPLAY_VALUE:
31859c2c14abSThejaswini Singarajipura repl = (sadb_x_replay_ctr_t *)ext;
31869c2c14abSThejaswini Singarajipura if ((repl->sadb_x_rc_replay32 == 0) &&
31879c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay64 == 0)) {
31889c2c14abSThejaswini Singarajipura tidyup();
31899c2c14abSThejaswini Singarajipura bail(dgettext(TEXT_DOMAIN, "Replay Value"));
31909c2c14abSThejaswini Singarajipura }
31919c2c14abSThejaswini Singarajipura if (fprintf(ofile, "replay_value %" PRIu64 "",
31929c2c14abSThejaswini Singarajipura (repl->sadb_x_rc_replay32 == 0 ?
31939c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay64 :
31949c2c14abSThejaswini Singarajipura repl->sadb_x_rc_replay32)) < 0) {
31959c2c14abSThejaswini Singarajipura tidyup();
31969c2c14abSThejaswini Singarajipura bail(dgettext(TEXT_DOMAIN,
31979c2c14abSThejaswini Singarajipura "save_assoc: fprintf replay value"));
31989c2c14abSThejaswini Singarajipura }
31999c2c14abSThejaswini Singarajipura savenl();
32009c2c14abSThejaswini Singarajipura break;
32018810c16bSdanmcd case SADB_EXT_SENSITIVITY:
32025d3b8cb7SBill Sommerfeld case SADB_X_EXT_OUTER_SENS:
32035d3b8cb7SBill Sommerfeld if (!save_sens((struct sadb_sens *)ext, ofile)) {
32045d3b8cb7SBill Sommerfeld tidyup();
32055d3b8cb7SBill Sommerfeld bail(dgettext(TEXT_DOMAIN, "save_sens"));
32065d3b8cb7SBill Sommerfeld }
32075d3b8cb7SBill Sommerfeld savenl();
32085d3b8cb7SBill Sommerfeld break;
32098810c16bSdanmcd default:
32108810c16bSdanmcd /* Skip over irrelevant extensions. */
32118810c16bSdanmcd break;
32128810c16bSdanmcd }
32138810c16bSdanmcd current += ext->sadb_ext_len;
32148810c16bSdanmcd }
32158810c16bSdanmcd
3216a7485808Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "\n# end assoc\n\n"), ofile) == EOF) {
3217a7485808Smarkfen tidyup();
3218a7485808Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: last fputs"));
3219a7485808Smarkfen }
32208810c16bSdanmcd }
32218810c16bSdanmcd
32228810c16bSdanmcd /*
32238810c16bSdanmcd * Open the output file for the "save" command.
32248810c16bSdanmcd */
32258810c16bSdanmcd FILE *
opensavefile(char * filename)32268810c16bSdanmcd opensavefile(char *filename)
32278810c16bSdanmcd {
32288810c16bSdanmcd int fd;
32298810c16bSdanmcd FILE *retval;
32308810c16bSdanmcd struct stat buf;
32318810c16bSdanmcd
32328810c16bSdanmcd /*
32338810c16bSdanmcd * If the user specifies "-" or doesn't give a filename, then
32348810c16bSdanmcd * dump to stdout. Make sure to document the dangers of files
32358810c16bSdanmcd * that are NFS, directing your output to strange places, etc.
32368810c16bSdanmcd */
32378810c16bSdanmcd if (filename == NULL || strcmp("-", filename) == 0)
32388810c16bSdanmcd return (stdout);
32398810c16bSdanmcd
32408810c16bSdanmcd /*
32418810c16bSdanmcd * open the file with the create bits set. Since I check for
32428810c16bSdanmcd * real UID == root in main(), I won't worry about the ownership
32438810c16bSdanmcd * problem.
32448810c16bSdanmcd */
32458810c16bSdanmcd fd = open(filename, O_WRONLY | O_EXCL | O_CREAT | O_TRUNC, S_IRUSR);
32468810c16bSdanmcd if (fd == -1) {
32478810c16bSdanmcd if (errno != EEXIST)
3248a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3249a7485808Smarkfen "open error"),
32508810c16bSdanmcd strerror(errno));
32518810c16bSdanmcd fd = open(filename, O_WRONLY | O_TRUNC, 0);
32528810c16bSdanmcd if (fd == -1)
3253a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3254a7485808Smarkfen "open error"), strerror(errno));
32558810c16bSdanmcd if (fstat(fd, &buf) == -1) {
32568810c16bSdanmcd (void) close(fd);
32578810c16bSdanmcd bail_msg("%s fstat: %s", filename, strerror(errno));
32588810c16bSdanmcd }
32598810c16bSdanmcd if (S_ISREG(buf.st_mode) &&
32608810c16bSdanmcd ((buf.st_mode & S_IAMB) != S_IRUSR)) {
3261a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
3262a7485808Smarkfen "WARNING: Save file already exists with "
3263a7485808Smarkfen "permission %o."), buf.st_mode & S_IAMB);
3264a7485808Smarkfen warnx(dgettext(TEXT_DOMAIN,
3265a7485808Smarkfen "Normal users may be able to read IPsec "
3266a7485808Smarkfen "keying material."));
32678810c16bSdanmcd }
32688810c16bSdanmcd }
32698810c16bSdanmcd
32708810c16bSdanmcd /* Okay, we have an FD. Assign it to a stdio FILE pointer. */
32718810c16bSdanmcd retval = fdopen(fd, "w");
32728810c16bSdanmcd if (retval == NULL) {
32738810c16bSdanmcd (void) close(fd);
3274a7485808Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN,
3275a7485808Smarkfen "fdopen error"), strerror(errno));
32768810c16bSdanmcd }
32778810c16bSdanmcd return (retval);
32788810c16bSdanmcd }
32798810c16bSdanmcd
32808810c16bSdanmcd const char *
do_inet_ntop(const void * addr,char * cp,size_t size)32818810c16bSdanmcd do_inet_ntop(const void *addr, char *cp, size_t size)
32828810c16bSdanmcd {
32838810c16bSdanmcd boolean_t isv4;
32848810c16bSdanmcd struct in6_addr *inaddr6 = (struct in6_addr *)addr;
32858810c16bSdanmcd struct in_addr inaddr;
32868810c16bSdanmcd
32878810c16bSdanmcd if ((isv4 = IN6_IS_ADDR_V4MAPPED(inaddr6)) == B_TRUE) {
32888810c16bSdanmcd IN6_V4MAPPED_TO_INADDR(inaddr6, &inaddr);
32898810c16bSdanmcd }
32908810c16bSdanmcd
32918810c16bSdanmcd return (inet_ntop(isv4 ? AF_INET : AF_INET6,
32928810c16bSdanmcd isv4 ? (void *)&inaddr : inaddr6, cp, size));
32938810c16bSdanmcd }
32948810c16bSdanmcd
32958810c16bSdanmcd char numprint[NBUF_SIZE];
32968810c16bSdanmcd
32978810c16bSdanmcd /*
32988810c16bSdanmcd * Parse and reverse parse a specific SA type (AH, ESP, etc.).
32998810c16bSdanmcd */
33008810c16bSdanmcd static struct typetable {
33018810c16bSdanmcd char *type;
33028810c16bSdanmcd int token;
33038810c16bSdanmcd } type_table[] = {
33048810c16bSdanmcd {"all", SADB_SATYPE_UNSPEC},
33058810c16bSdanmcd {"ah", SADB_SATYPE_AH},
33068810c16bSdanmcd {"esp", SADB_SATYPE_ESP},
33078810c16bSdanmcd /* PF_KEY NOTE: More to come if net/pfkeyv2.h gets updated. */
33088810c16bSdanmcd {NULL, 0} /* Token value is irrelevant for this entry. */
33098810c16bSdanmcd };
33108810c16bSdanmcd
33118810c16bSdanmcd char *
rparsesatype(int type)33128810c16bSdanmcd rparsesatype(int type)
33138810c16bSdanmcd {
33148810c16bSdanmcd struct typetable *tt = type_table;
33158810c16bSdanmcd
33168810c16bSdanmcd while (tt->type != NULL && type != tt->token)
33178810c16bSdanmcd tt++;
33188810c16bSdanmcd
33198810c16bSdanmcd if (tt->type == NULL) {
33208810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type);
33218810c16bSdanmcd } else {
33228810c16bSdanmcd return (tt->type);
33238810c16bSdanmcd }
33248810c16bSdanmcd
33258810c16bSdanmcd return (numprint);
33268810c16bSdanmcd }
33278810c16bSdanmcd
33288810c16bSdanmcd
33298810c16bSdanmcd /*
33308810c16bSdanmcd * Return a string containing the name of the specified numerical algorithm
33318810c16bSdanmcd * identifier.
33328810c16bSdanmcd */
33338810c16bSdanmcd char *
rparsealg(uint8_t alg,int proto_num)33348810c16bSdanmcd rparsealg(uint8_t alg, int proto_num)
33358810c16bSdanmcd {
33368810c16bSdanmcd static struct ipsecalgent *holder = NULL; /* we're single-threaded */
33378810c16bSdanmcd
33388810c16bSdanmcd if (holder != NULL)
33398810c16bSdanmcd freeipsecalgent(holder);
33408810c16bSdanmcd
33418810c16bSdanmcd holder = getipsecalgbynum(alg, proto_num, NULL);
33428810c16bSdanmcd if (holder == NULL) {
33438810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", alg);
33448810c16bSdanmcd return (numprint);
33458810c16bSdanmcd }
33468810c16bSdanmcd
33478810c16bSdanmcd return (*(holder->a_names));
33488810c16bSdanmcd }
33498810c16bSdanmcd
33508810c16bSdanmcd /*
33518810c16bSdanmcd * Parse and reverse parse out a source/destination ID type.
33528810c16bSdanmcd */
33538810c16bSdanmcd static struct idtypes {
33548810c16bSdanmcd char *idtype;
33558810c16bSdanmcd uint8_t retval;
33568810c16bSdanmcd } idtypes[] = {
33578810c16bSdanmcd {"prefix", SADB_IDENTTYPE_PREFIX},
33588810c16bSdanmcd {"fqdn", SADB_IDENTTYPE_FQDN},
33598810c16bSdanmcd {"domain", SADB_IDENTTYPE_FQDN},
33608810c16bSdanmcd {"domainname", SADB_IDENTTYPE_FQDN},
33618810c16bSdanmcd {"user_fqdn", SADB_IDENTTYPE_USER_FQDN},
33628810c16bSdanmcd {"mailbox", SADB_IDENTTYPE_USER_FQDN},
33638810c16bSdanmcd {"der_dn", SADB_X_IDENTTYPE_DN},
33648810c16bSdanmcd {"der_gn", SADB_X_IDENTTYPE_GN},
33658810c16bSdanmcd {NULL, 0}
33668810c16bSdanmcd };
33678810c16bSdanmcd
33688810c16bSdanmcd char *
rparseidtype(uint16_t type)33698810c16bSdanmcd rparseidtype(uint16_t type)
33708810c16bSdanmcd {
33718810c16bSdanmcd struct idtypes *idp;
33728810c16bSdanmcd
33738810c16bSdanmcd for (idp = idtypes; idp->idtype != NULL; idp++) {
33748810c16bSdanmcd if (type == idp->retval)
33758810c16bSdanmcd return (idp->idtype);
33768810c16bSdanmcd }
33778810c16bSdanmcd
33788810c16bSdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type);
33798810c16bSdanmcd return (numprint);
33808810c16bSdanmcd }
3381e3320f40Smarkfen
3382e3320f40Smarkfen /*
3383e3320f40Smarkfen * This is a general purpose exit function, calling functions can specify an
3384*bbf21555SRichard Lowe * error type. If the command calling this function was started by smf(7) the
3385e3320f40Smarkfen * error type could be used as a hint to the restarter. In the future this
3386e3320f40Smarkfen * function could be used to do something more intelligent with a process that
3387a1ba8781SMark Fenwick * encounters an error. If exit() is called with an error code other than those
3388*bbf21555SRichard Lowe * defined by smf(7), the program will just get restarted. Unless restarting
3389a1ba8781SMark Fenwick * is likely to resolve the error condition, its probably sensible to just
3390a1ba8781SMark Fenwick * log the error and keep running.
3391a1ba8781SMark Fenwick *
3392a1ba8781SMark Fenwick * The SERVICE_* exit_types mean nothing if the command was run from the
3393a1ba8781SMark Fenwick * command line, just exit(). There are two special cases:
3394a1ba8781SMark Fenwick *
3395*bbf21555SRichard Lowe * SERVICE_DEGRADE - Not implemented in smf(7), one day it could hint that
3396a1ba8781SMark Fenwick * the service is not running as well is it could. For
3397a1ba8781SMark Fenwick * now, don't do anything, just record the error.
3398a1ba8781SMark Fenwick * DEBUG_FATAL - Something happened, if the command was being run in debug
3399a1ba8781SMark Fenwick * mode, exit() as you really want to know something happened,
3400a1ba8781SMark Fenwick * otherwise just keep running. This is ignored when running
3401*bbf21555SRichard Lowe * under smf(7).
3402e3320f40Smarkfen *
3403e3320f40Smarkfen * The function will handle an optional variable args error message, this
3404e3320f40Smarkfen * will be written to the error stream, typically a log file or stderr.
3405e3320f40Smarkfen */
3406e3320f40Smarkfen void
ipsecutil_exit(exit_type_t type,char * fmri,FILE * fp,const char * fmt,...)3407e3320f40Smarkfen ipsecutil_exit(exit_type_t type, char *fmri, FILE *fp, const char *fmt, ...)
3408e3320f40Smarkfen {
3409e3320f40Smarkfen int exit_status;
3410e3320f40Smarkfen va_list args;
3411e3320f40Smarkfen
3412e3320f40Smarkfen if (fp == NULL)
3413e3320f40Smarkfen fp = stderr;
3414e3320f40Smarkfen if (fmt != NULL) {
3415e3320f40Smarkfen va_start(args, fmt);
3416e3320f40Smarkfen vwarnxfp(fp, fmt, args);
3417e3320f40Smarkfen va_end(args);
3418e3320f40Smarkfen }
3419e3320f40Smarkfen
3420e3320f40Smarkfen if (fmri == NULL) {
3421e3320f40Smarkfen /* Command being run directly from a shell. */
3422e3320f40Smarkfen switch (type) {
3423e3320f40Smarkfen case SERVICE_EXIT_OK:
3424e3320f40Smarkfen exit_status = 0;
3425e3320f40Smarkfen break;
3426e3320f40Smarkfen case SERVICE_DEGRADE:
3427e3320f40Smarkfen return;
3428e3320f40Smarkfen case SERVICE_BADPERM:
3429e3320f40Smarkfen case SERVICE_BADCONF:
3430e3320f40Smarkfen case SERVICE_MAINTAIN:
3431e3320f40Smarkfen case SERVICE_DISABLE:
3432e3320f40Smarkfen case SERVICE_FATAL:
3433e3320f40Smarkfen case SERVICE_RESTART:
3434a1ba8781SMark Fenwick case DEBUG_FATAL:
3435e3320f40Smarkfen warnxfp(fp, "Fatal error - exiting.");
3436e3320f40Smarkfen exit_status = 1;
3437e3320f40Smarkfen break;
3438e3320f40Smarkfen }
3439e3320f40Smarkfen } else {
3440*bbf21555SRichard Lowe /* Command being run as a smf(7) method. */
3441e3320f40Smarkfen switch (type) {
3442e3320f40Smarkfen case SERVICE_EXIT_OK:
3443e3320f40Smarkfen exit_status = SMF_EXIT_OK;
3444e3320f40Smarkfen break;
3445a1ba8781SMark Fenwick case SERVICE_DEGRADE: /* Not implemented yet. */
3446a1ba8781SMark Fenwick case DEBUG_FATAL:
3447a1ba8781SMark Fenwick /* Keep running, don't exit(). */
3448e3320f40Smarkfen return;
3449e3320f40Smarkfen case SERVICE_BADPERM:
3450e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3451e3320f40Smarkfen "Permission error with %s."), fmri);
3452e3320f40Smarkfen exit_status = SMF_EXIT_ERR_PERM;
3453e3320f40Smarkfen break;
3454e3320f40Smarkfen case SERVICE_BADCONF:
3455e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3456e3320f40Smarkfen "Bad configuration of service %s."), fmri);
3457e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3458e3320f40Smarkfen break;
3459e3320f40Smarkfen case SERVICE_MAINTAIN:
3460e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3461e3320f40Smarkfen "Service %s needs maintenance."), fmri);
3462e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3463e3320f40Smarkfen break;
3464e3320f40Smarkfen case SERVICE_DISABLE:
3465e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3466e3320f40Smarkfen break;
3467e3320f40Smarkfen case SERVICE_FATAL:
3468e3320f40Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN,
3469e3320f40Smarkfen "Service %s fatal error."), fmri);
3470e3320f40Smarkfen exit_status = SMF_EXIT_ERR_FATAL;
3471e3320f40Smarkfen break;
3472e3320f40Smarkfen case SERVICE_RESTART:
3473e3320f40Smarkfen exit_status = 1;
3474e3320f40Smarkfen break;
3475e3320f40Smarkfen }
3476e3320f40Smarkfen }
3477e3320f40Smarkfen (void) fflush(fp);
3478e3320f40Smarkfen (void) fclose(fp);
3479e3320f40Smarkfen exit(exit_status);
3480e3320f40Smarkfen }
3481bdc560abSJason King
3482bdc560abSJason King void
print_asn1_name(FILE * file,const unsigned char * buf,long buflen)3483bdc560abSJason King print_asn1_name(FILE *file, const unsigned char *buf, long buflen)
3484bdc560abSJason King {
3485bdc560abSJason King KMF_X509_NAME name = { 0 };
3486bdc560abSJason King KMF_DATA data = { 0 };
3487bdc560abSJason King char *str = NULL;
3488bdc560abSJason King
3489bdc560abSJason King data.Data = (unsigned char *)buf;
3490bdc560abSJason King data.Length = buflen;
3491bdc560abSJason King
3492bdc560abSJason King if (DerDecodeName(&data, &name) != KMF_OK)
3493bdc560abSJason King goto fail;
3494bdc560abSJason King
3495bdc560abSJason King if (kmf_dn_to_string(&name, &str) != KMF_OK)
3496bdc560abSJason King goto fail;
3497bdc560abSJason King
3498bdc560abSJason King (void) fprintf(file, "%s\n", str);
3499bdc560abSJason King kmf_free_dn(&name);
3500bdc560abSJason King free(str);
3501bdc560abSJason King return;
3502bdc560abSJason King fail:
3503bdc560abSJason King kmf_free_dn(&name);
3504bdc560abSJason King (void) fprintf(file, dgettext(TEXT_DOMAIN, "<cannot interpret>\n"));
3505bdc560abSJason King }
3506