10Sstevel@tonic-gate /* 26119Spwernau * 30Sstevel@tonic-gate * CDDL HEADER START 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * The contents of this file are subject to the terms of the 63055Sdanmcd * Common Development and Distribution License (the "License"). 73055Sdanmcd * You may not use this file except in compliance with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 239086SVladimir.Kotal@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <unistd.h> 280Sstevel@tonic-gate #include <stdio.h> 290Sstevel@tonic-gate #include <stdlib.h> 300Sstevel@tonic-gate #include <stdarg.h> 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/stat.h> 330Sstevel@tonic-gate #include <fcntl.h> 340Sstevel@tonic-gate #include <sys/sysconf.h> 350Sstevel@tonic-gate #include <strings.h> 360Sstevel@tonic-gate #include <ctype.h> 370Sstevel@tonic-gate #include <errno.h> 380Sstevel@tonic-gate #include <sys/socket.h> 390Sstevel@tonic-gate #include <netdb.h> 400Sstevel@tonic-gate #include <netinet/in.h> 410Sstevel@tonic-gate #include <arpa/inet.h> 420Sstevel@tonic-gate #include <net/pfkeyv2.h> 430Sstevel@tonic-gate #include <net/pfpolicy.h> 440Sstevel@tonic-gate #include <libintl.h> 450Sstevel@tonic-gate #include <setjmp.h> 460Sstevel@tonic-gate #include <libgen.h> 474235Smarkfen #include <libscf.h> 480Sstevel@tonic-gate 490Sstevel@tonic-gate #include "ipsec_util.h" 500Sstevel@tonic-gate #include "ikedoor.h" 510Sstevel@tonic-gate 520Sstevel@tonic-gate /* 530Sstevel@tonic-gate * This file contains support functions that are shared by the ipsec 544867Spwernau * utilities and daemons including ipseckey(1m), ikeadm(1m) and in.iked(1m). 550Sstevel@tonic-gate */ 560Sstevel@tonic-gate 574867Spwernau 584867Spwernau #define EFD(file) (((file) == stdout) ? stderr : (file)) 594867Spwernau 609086SVladimir.Kotal@Sun.COM /* Limits for interactive mode. */ 619086SVladimir.Kotal@Sun.COM #define MAX_LINE_LEN IBUF_SIZE 629086SVladimir.Kotal@Sun.COM #define MAX_CMD_HIST 64000 /* in bytes */ 639086SVladimir.Kotal@Sun.COM 640Sstevel@tonic-gate /* Set standard default/initial values for globals... */ 650Sstevel@tonic-gate boolean_t pflag = B_FALSE; /* paranoid w.r.t. printing keying material */ 660Sstevel@tonic-gate boolean_t nflag = B_FALSE; /* avoid nameservice? */ 670Sstevel@tonic-gate boolean_t interactive = B_FALSE; /* util not running on cmdline */ 680Sstevel@tonic-gate boolean_t readfile = B_FALSE; /* cmds are being read from a file */ 690Sstevel@tonic-gate uint_t lineno = 0; /* track location if reading cmds from file */ 704235Smarkfen uint_t lines_added = 0; 714235Smarkfen uint_t lines_parsed = 0; 720Sstevel@tonic-gate jmp_buf env; /* for error recovery in interactive/readfile modes */ 734235Smarkfen char *my_fmri = NULL; 744235Smarkfen FILE *debugfile = stderr; 759086SVladimir.Kotal@Sun.COM static GetLine *gl = NULL; /* for interactive mode */ 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* 780Sstevel@tonic-gate * Print errno and exit if cmdline or readfile, reset state if interactive 794064Smarkfen * The error string *what should be dgettext()'d before calling bail(). 800Sstevel@tonic-gate */ 810Sstevel@tonic-gate void 820Sstevel@tonic-gate bail(char *what) 830Sstevel@tonic-gate { 840Sstevel@tonic-gate if (errno != 0) 850Sstevel@tonic-gate warn(what); 860Sstevel@tonic-gate else 874235Smarkfen warnx(dgettext(TEXT_DOMAIN, "Error: %s"), what); 880Sstevel@tonic-gate if (readfile) { 894235Smarkfen return; 900Sstevel@tonic-gate } 910Sstevel@tonic-gate if (interactive && !readfile) 920Sstevel@tonic-gate longjmp(env, 2); 934235Smarkfen EXIT_FATAL(NULL); 940Sstevel@tonic-gate } 950Sstevel@tonic-gate 960Sstevel@tonic-gate /* 970Sstevel@tonic-gate * Print caller-supplied variable-arg error msg, then exit if cmdline or 980Sstevel@tonic-gate * readfile, or reset state if interactive. 990Sstevel@tonic-gate */ 1000Sstevel@tonic-gate /*PRINTFLIKE1*/ 1010Sstevel@tonic-gate void 1020Sstevel@tonic-gate bail_msg(char *fmt, ...) 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate va_list ap; 1050Sstevel@tonic-gate char msgbuf[BUFSIZ]; 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate va_start(ap, fmt); 1080Sstevel@tonic-gate (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap); 1090Sstevel@tonic-gate va_end(ap); 1100Sstevel@tonic-gate if (readfile) 1114064Smarkfen warnx(dgettext(TEXT_DOMAIN, 1124064Smarkfen "ERROR on line %u:\n%s\n"), lineno, msgbuf); 1130Sstevel@tonic-gate else 1144064Smarkfen warnx(dgettext(TEXT_DOMAIN, "ERROR: %s\n"), msgbuf); 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate if (interactive && !readfile) 1170Sstevel@tonic-gate longjmp(env, 1); 1180Sstevel@tonic-gate 1194235Smarkfen EXIT_FATAL(NULL); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate /* 1240Sstevel@tonic-gate * dump_XXX functions produce ASCII output from various structures. 1250Sstevel@tonic-gate * 1260Sstevel@tonic-gate * Because certain errors need to do this to stderr, dump_XXX functions 1270Sstevel@tonic-gate * take a FILE pointer. 1280Sstevel@tonic-gate * 1290Sstevel@tonic-gate * If an error occured while writing to the specified file, these 1300Sstevel@tonic-gate * functions return -1, zero otherwise. 1310Sstevel@tonic-gate */ 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate int 1343055Sdanmcd dump_sockaddr(struct sockaddr *sa, uint8_t prefixlen, boolean_t addr_only, 1354867Spwernau FILE *where, boolean_t ignore_nss) 1360Sstevel@tonic-gate { 1370Sstevel@tonic-gate struct sockaddr_in *sin; 1380Sstevel@tonic-gate struct sockaddr_in6 *sin6; 1390Sstevel@tonic-gate char *printable_addr, *protocol; 1400Sstevel@tonic-gate uint8_t *addrptr; 1413055Sdanmcd /* Add 4 chars to hold '/nnn' for prefixes. */ 1423055Sdanmcd char storage[INET6_ADDRSTRLEN + 4]; 1430Sstevel@tonic-gate uint16_t port; 1440Sstevel@tonic-gate boolean_t unspec; 1450Sstevel@tonic-gate struct hostent *hp; 1460Sstevel@tonic-gate int getipnode_errno, addrlen; 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate switch (sa->sa_family) { 1490Sstevel@tonic-gate case AF_INET: 1500Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */ 1510Sstevel@tonic-gate sin = (struct sockaddr_in *)sa; 1520Sstevel@tonic-gate addrptr = (uint8_t *)&sin->sin_addr; 1530Sstevel@tonic-gate port = sin->sin_port; 1540Sstevel@tonic-gate protocol = "AF_INET"; 1550Sstevel@tonic-gate unspec = (sin->sin_addr.s_addr == 0); 1560Sstevel@tonic-gate addrlen = sizeof (sin->sin_addr); 1570Sstevel@tonic-gate break; 1580Sstevel@tonic-gate case AF_INET6: 1590Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */ 1600Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)sa; 1610Sstevel@tonic-gate addrptr = (uint8_t *)&sin6->sin6_addr; 1620Sstevel@tonic-gate port = sin6->sin6_port; 1630Sstevel@tonic-gate protocol = "AF_INET6"; 1640Sstevel@tonic-gate unspec = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr); 1650Sstevel@tonic-gate addrlen = sizeof (sin6->sin6_addr); 1660Sstevel@tonic-gate break; 1670Sstevel@tonic-gate default: 1680Sstevel@tonic-gate return (0); 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate if (inet_ntop(sa->sa_family, addrptr, storage, INET6_ADDRSTRLEN) == 1720Sstevel@tonic-gate NULL) { 1734064Smarkfen printable_addr = dgettext(TEXT_DOMAIN, "Invalid IP address."); 1740Sstevel@tonic-gate } else { 1753055Sdanmcd char prefix[5]; /* "/nnn" with terminator. */ 1763055Sdanmcd 1773055Sdanmcd (void) snprintf(prefix, sizeof (prefix), "/%d", prefixlen); 1780Sstevel@tonic-gate printable_addr = storage; 1793055Sdanmcd if (prefixlen != 0) { 1803055Sdanmcd (void) strlcat(printable_addr, prefix, 1813055Sdanmcd sizeof (storage)); 1823055Sdanmcd } 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate if (addr_only) { 1850Sstevel@tonic-gate if (fprintf(where, "%s", printable_addr) < 0) 1860Sstevel@tonic-gate return (-1); 1870Sstevel@tonic-gate } else { 1884064Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN, 1894064Smarkfen "%s: port %d, %s"), protocol, 1900Sstevel@tonic-gate ntohs(port), printable_addr) < 0) 1910Sstevel@tonic-gate return (-1); 1924867Spwernau if (ignore_nss == B_FALSE) { 1930Sstevel@tonic-gate /* 1940Sstevel@tonic-gate * Do AF_independent reverse hostname lookup here. 1950Sstevel@tonic-gate */ 1960Sstevel@tonic-gate if (unspec) { 1970Sstevel@tonic-gate if (fprintf(where, 1984064Smarkfen dgettext(TEXT_DOMAIN, 1994064Smarkfen " <unspecified>")) < 0) 2000Sstevel@tonic-gate return (-1); 2010Sstevel@tonic-gate } else { 2020Sstevel@tonic-gate hp = getipnodebyaddr((char *)addrptr, addrlen, 2030Sstevel@tonic-gate sa->sa_family, &getipnode_errno); 2040Sstevel@tonic-gate if (hp != NULL) { 2050Sstevel@tonic-gate if (fprintf(where, 2060Sstevel@tonic-gate " (%s)", hp->h_name) < 0) 2070Sstevel@tonic-gate return (-1); 2080Sstevel@tonic-gate freehostent(hp); 2090Sstevel@tonic-gate } else { 2100Sstevel@tonic-gate if (fprintf(where, 2114064Smarkfen dgettext(TEXT_DOMAIN, 2124064Smarkfen " <unknown>")) < 0) 2130Sstevel@tonic-gate return (-1); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate if (fputs(".\n", where) == EOF) 2180Sstevel@tonic-gate return (-1); 2190Sstevel@tonic-gate } 2200Sstevel@tonic-gate return (0); 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* 2240Sstevel@tonic-gate * Dump a key and bitlen 2250Sstevel@tonic-gate */ 2260Sstevel@tonic-gate int 2270Sstevel@tonic-gate dump_key(uint8_t *keyp, uint_t bitlen, FILE *where) 2280Sstevel@tonic-gate { 2290Sstevel@tonic-gate int numbytes; 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate numbytes = SADB_1TO8(bitlen); 2320Sstevel@tonic-gate /* The & 0x7 is to check for leftover bits. */ 2330Sstevel@tonic-gate if ((bitlen & 0x7) != 0) 2340Sstevel@tonic-gate numbytes++; 2350Sstevel@tonic-gate while (numbytes-- != 0) { 2360Sstevel@tonic-gate if (pflag) { 2370Sstevel@tonic-gate /* Print no keys if paranoid */ 2380Sstevel@tonic-gate if (fprintf(where, "XX") < 0) 2390Sstevel@tonic-gate return (-1); 2400Sstevel@tonic-gate } else { 2410Sstevel@tonic-gate if (fprintf(where, "%02x", *keyp++) < 0) 2420Sstevel@tonic-gate return (-1); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate if (fprintf(where, "/%u", bitlen) < 0) 2460Sstevel@tonic-gate return (-1); 2470Sstevel@tonic-gate return (0); 2480Sstevel@tonic-gate } 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate /* 2510Sstevel@tonic-gate * Print an authentication or encryption algorithm 2520Sstevel@tonic-gate */ 2530Sstevel@tonic-gate static int 2540Sstevel@tonic-gate dump_generic_alg(uint8_t alg_num, int proto_num, FILE *where) 2550Sstevel@tonic-gate { 2560Sstevel@tonic-gate struct ipsecalgent *alg; 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate alg = getipsecalgbynum(alg_num, proto_num, NULL); 2590Sstevel@tonic-gate if (alg == NULL) { 2604064Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN, 2614064Smarkfen "<unknown %u>"), alg_num) < 0) 2620Sstevel@tonic-gate return (-1); 2630Sstevel@tonic-gate return (0); 2640Sstevel@tonic-gate } 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate /* 2670Sstevel@tonic-gate * Special-case <none> for backward output compat. 2680Sstevel@tonic-gate * Assume that SADB_AALG_NONE == SADB_EALG_NONE. 2690Sstevel@tonic-gate */ 2700Sstevel@tonic-gate if (alg_num == SADB_AALG_NONE) { 2714064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, 2724064Smarkfen "<none>"), where) == EOF) 2730Sstevel@tonic-gate return (-1); 2740Sstevel@tonic-gate } else { 2750Sstevel@tonic-gate if (fputs(alg->a_names[0], where) == EOF) 2760Sstevel@tonic-gate return (-1); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate freeipsecalgent(alg); 2800Sstevel@tonic-gate return (0); 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate int 2840Sstevel@tonic-gate dump_aalg(uint8_t aalg, FILE *where) 2850Sstevel@tonic-gate { 2860Sstevel@tonic-gate return (dump_generic_alg(aalg, IPSEC_PROTO_AH, where)); 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate int 2900Sstevel@tonic-gate dump_ealg(uint8_t ealg, FILE *where) 2910Sstevel@tonic-gate { 2920Sstevel@tonic-gate return (dump_generic_alg(ealg, IPSEC_PROTO_ESP, where)); 2930Sstevel@tonic-gate } 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate /* 2960Sstevel@tonic-gate * Print an SADB_IDENTTYPE string 2970Sstevel@tonic-gate * 2980Sstevel@tonic-gate * Also return TRUE if the actual ident may be printed, FALSE if not. 2990Sstevel@tonic-gate * 3000Sstevel@tonic-gate * If rc is not NULL, set its value to -1 if an error occured while writing 3010Sstevel@tonic-gate * to the specified file, zero otherwise. 3020Sstevel@tonic-gate */ 3030Sstevel@tonic-gate boolean_t 3040Sstevel@tonic-gate dump_sadb_idtype(uint8_t idtype, FILE *where, int *rc) 3050Sstevel@tonic-gate { 3060Sstevel@tonic-gate boolean_t canprint = B_TRUE; 3070Sstevel@tonic-gate int rc_val = 0; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate switch (idtype) { 3100Sstevel@tonic-gate case SADB_IDENTTYPE_PREFIX: 3114064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "prefix"), where) == EOF) 3120Sstevel@tonic-gate rc_val = -1; 3130Sstevel@tonic-gate break; 3140Sstevel@tonic-gate case SADB_IDENTTYPE_FQDN: 3154064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "FQDN"), where) == EOF) 3160Sstevel@tonic-gate rc_val = -1; 3170Sstevel@tonic-gate break; 3180Sstevel@tonic-gate case SADB_IDENTTYPE_USER_FQDN: 3194064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, 3204064Smarkfen "user-FQDN (mbox)"), where) == EOF) 3210Sstevel@tonic-gate rc_val = -1; 3220Sstevel@tonic-gate break; 3230Sstevel@tonic-gate case SADB_X_IDENTTYPE_DN: 3244064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Distinguished Name"), 3250Sstevel@tonic-gate where) == EOF) 3260Sstevel@tonic-gate rc_val = -1; 3270Sstevel@tonic-gate canprint = B_FALSE; 3280Sstevel@tonic-gate break; 3290Sstevel@tonic-gate case SADB_X_IDENTTYPE_GN: 3304064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "ASN.1 DER Generic Name"), 3314064Smarkfen where) == EOF) 3320Sstevel@tonic-gate rc_val = -1; 3330Sstevel@tonic-gate canprint = B_FALSE; 3340Sstevel@tonic-gate break; 3350Sstevel@tonic-gate case SADB_X_IDENTTYPE_KEY_ID: 3364064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Generic key id"), 3374064Smarkfen where) == EOF) 3380Sstevel@tonic-gate rc_val = -1; 3390Sstevel@tonic-gate break; 3400Sstevel@tonic-gate case SADB_X_IDENTTYPE_ADDR_RANGE: 3414064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "Address range"), where) == EOF) 3420Sstevel@tonic-gate rc_val = -1; 3430Sstevel@tonic-gate break; 3440Sstevel@tonic-gate default: 3454064Smarkfen if (fprintf(where, dgettext(TEXT_DOMAIN, 3464064Smarkfen "<unknown %u>"), idtype) < 0) 3470Sstevel@tonic-gate rc_val = -1; 3480Sstevel@tonic-gate break; 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate if (rc != NULL) 3520Sstevel@tonic-gate *rc = rc_val; 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate return (canprint); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate /* 3580Sstevel@tonic-gate * Slice an argv/argc vector from an interactive line or a read-file line. 3590Sstevel@tonic-gate */ 3600Sstevel@tonic-gate static int 3610Sstevel@tonic-gate create_argv(char *ibuf, int *newargc, char ***thisargv) 3620Sstevel@tonic-gate { 3630Sstevel@tonic-gate unsigned int argvlen = START_ARG; 3640Sstevel@tonic-gate char **current; 3650Sstevel@tonic-gate boolean_t firstchar = B_TRUE; 3660Sstevel@tonic-gate boolean_t inquotes = B_FALSE; 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate *thisargv = malloc(sizeof (char *) * argvlen); 3690Sstevel@tonic-gate if ((*thisargv) == NULL) 3700Sstevel@tonic-gate return (MEMORY_ALLOCATION); 3710Sstevel@tonic-gate current = *thisargv; 3720Sstevel@tonic-gate *current = NULL; 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate for (; *ibuf != '\0'; ibuf++) { 3750Sstevel@tonic-gate if (isspace(*ibuf)) { 3760Sstevel@tonic-gate if (inquotes) { 3770Sstevel@tonic-gate continue; 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate if (*current != NULL) { 3800Sstevel@tonic-gate *ibuf = '\0'; 3810Sstevel@tonic-gate current++; 3820Sstevel@tonic-gate if (*thisargv + argvlen == current) { 3830Sstevel@tonic-gate /* Regrow ***thisargv. */ 3840Sstevel@tonic-gate if (argvlen == TOO_MANY_ARGS) { 3850Sstevel@tonic-gate free(*thisargv); 3860Sstevel@tonic-gate return (TOO_MANY_TOKENS); 3870Sstevel@tonic-gate } 3880Sstevel@tonic-gate /* Double the allocation. */ 3890Sstevel@tonic-gate current = realloc(*thisargv, 3900Sstevel@tonic-gate sizeof (char *) * (argvlen << 1)); 3910Sstevel@tonic-gate if (current == NULL) { 3920Sstevel@tonic-gate free(*thisargv); 3930Sstevel@tonic-gate return (MEMORY_ALLOCATION); 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate *thisargv = current; 3960Sstevel@tonic-gate current += argvlen; 3970Sstevel@tonic-gate argvlen <<= 1; /* Double the size. */ 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate *current = NULL; 4000Sstevel@tonic-gate } 4010Sstevel@tonic-gate } else { 4020Sstevel@tonic-gate if (firstchar) { 4030Sstevel@tonic-gate firstchar = B_FALSE; 4044235Smarkfen if (*ibuf == COMMENT_CHAR || *ibuf == '\n') { 4050Sstevel@tonic-gate free(*thisargv); 4060Sstevel@tonic-gate return (COMMENT_LINE); 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate if (*ibuf == QUOTE_CHAR) { 4100Sstevel@tonic-gate if (inquotes) { 4110Sstevel@tonic-gate inquotes = B_FALSE; 4120Sstevel@tonic-gate *ibuf = '\0'; 4130Sstevel@tonic-gate } else { 4140Sstevel@tonic-gate inquotes = B_TRUE; 4150Sstevel@tonic-gate } 4160Sstevel@tonic-gate continue; 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate if (*current == NULL) { 4190Sstevel@tonic-gate *current = ibuf; 4200Sstevel@tonic-gate (*newargc)++; 4210Sstevel@tonic-gate } 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate } 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate /* 4260Sstevel@tonic-gate * Tricky corner case... 4270Sstevel@tonic-gate * I've parsed _exactly_ the amount of args as I have space. It 4280Sstevel@tonic-gate * won't return NULL-terminated, and bad things will happen to 4290Sstevel@tonic-gate * the caller. 4300Sstevel@tonic-gate */ 4310Sstevel@tonic-gate if (argvlen == *newargc) { 4320Sstevel@tonic-gate current = realloc(*thisargv, sizeof (char *) * (argvlen + 1)); 4330Sstevel@tonic-gate if (current == NULL) { 4340Sstevel@tonic-gate free(*thisargv); 4350Sstevel@tonic-gate return (MEMORY_ALLOCATION); 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate *thisargv = current; 4380Sstevel@tonic-gate current[argvlen] = NULL; 4390Sstevel@tonic-gate } 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate return (SUCCESS); 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate /* 4459086SVladimir.Kotal@Sun.COM * init interactive mode if needed and not yet initialized 4469086SVladimir.Kotal@Sun.COM */ 4479086SVladimir.Kotal@Sun.COM static void 4489086SVladimir.Kotal@Sun.COM init_interactive(FILE *infile, CplMatchFn *match_fn) 4499086SVladimir.Kotal@Sun.COM { 4509086SVladimir.Kotal@Sun.COM if (infile == stdin) { 4519086SVladimir.Kotal@Sun.COM if (gl == NULL) { 4529086SVladimir.Kotal@Sun.COM if ((gl = new_GetLine(MAX_LINE_LEN, 4539086SVladimir.Kotal@Sun.COM MAX_CMD_HIST)) == NULL) 4549086SVladimir.Kotal@Sun.COM errx(1, dgettext(TEXT_DOMAIN, 4559086SVladimir.Kotal@Sun.COM "tecla initialization failed")); 4569086SVladimir.Kotal@Sun.COM 4579086SVladimir.Kotal@Sun.COM if (gl_customize_completion(gl, NULL, 4589086SVladimir.Kotal@Sun.COM match_fn) != 0) { 4599086SVladimir.Kotal@Sun.COM (void) del_GetLine(gl); 4609086SVladimir.Kotal@Sun.COM errx(1, dgettext(TEXT_DOMAIN, 4619086SVladimir.Kotal@Sun.COM "tab completion failed to initialize")); 4629086SVladimir.Kotal@Sun.COM } 4639086SVladimir.Kotal@Sun.COM 4649086SVladimir.Kotal@Sun.COM /* 4659086SVladimir.Kotal@Sun.COM * In interactive mode we only want to terminate 4669086SVladimir.Kotal@Sun.COM * when explicitly requested (e.g. by a command). 4679086SVladimir.Kotal@Sun.COM */ 4689086SVladimir.Kotal@Sun.COM (void) sigset(SIGINT, SIG_IGN); 4699086SVladimir.Kotal@Sun.COM } 4709086SVladimir.Kotal@Sun.COM } else { 4719086SVladimir.Kotal@Sun.COM readfile = B_TRUE; 4729086SVladimir.Kotal@Sun.COM } 4739086SVladimir.Kotal@Sun.COM } 4749086SVladimir.Kotal@Sun.COM 4759086SVladimir.Kotal@Sun.COM /* 4769086SVladimir.Kotal@Sun.COM * free tecla data structure 4779086SVladimir.Kotal@Sun.COM */ 4789086SVladimir.Kotal@Sun.COM static void 4799086SVladimir.Kotal@Sun.COM fini_interactive(void) 4809086SVladimir.Kotal@Sun.COM { 4819086SVladimir.Kotal@Sun.COM if (gl != NULL) 4829086SVladimir.Kotal@Sun.COM (void) del_GetLine(gl); 4839086SVladimir.Kotal@Sun.COM } 4849086SVladimir.Kotal@Sun.COM 4859086SVladimir.Kotal@Sun.COM /* 4869086SVladimir.Kotal@Sun.COM * Get single input line, wrapping around interactive and non-interactive 4879086SVladimir.Kotal@Sun.COM * mode. 4889086SVladimir.Kotal@Sun.COM */ 4899086SVladimir.Kotal@Sun.COM static char * 4909086SVladimir.Kotal@Sun.COM do_getstr(FILE *infile, char *prompt, char *ibuf, size_t ibuf_size) 4919086SVladimir.Kotal@Sun.COM { 4929086SVladimir.Kotal@Sun.COM char *line; 4939086SVladimir.Kotal@Sun.COM 4949086SVladimir.Kotal@Sun.COM if (infile != stdin) 4959086SVladimir.Kotal@Sun.COM return (fgets(ibuf, ibuf_size, infile)); 4969086SVladimir.Kotal@Sun.COM 4979086SVladimir.Kotal@Sun.COM /* 4989086SVladimir.Kotal@Sun.COM * If the user hits ^C then we want to catch it and 4999086SVladimir.Kotal@Sun.COM * start over. If the user hits EOF then we want to 5009086SVladimir.Kotal@Sun.COM * bail out. 5019086SVladimir.Kotal@Sun.COM */ 5029086SVladimir.Kotal@Sun.COM once_again: 5039086SVladimir.Kotal@Sun.COM line = gl_get_line(gl, prompt, NULL, -1); 5049086SVladimir.Kotal@Sun.COM if (gl_return_status(gl) == GLR_SIGNAL) { 5059086SVladimir.Kotal@Sun.COM gl_abandon_line(gl); 5069086SVladimir.Kotal@Sun.COM goto once_again; 5079086SVladimir.Kotal@Sun.COM } else if (gl_return_status(gl) == GLR_ERROR) { 5089086SVladimir.Kotal@Sun.COM gl_abandon_line(gl); 5099086SVladimir.Kotal@Sun.COM errx(1, dgettext(TEXT_DOMAIN, "Error reading terminal: %s\n"), 5109086SVladimir.Kotal@Sun.COM gl_error_message(gl, NULL, 0)); 5119086SVladimir.Kotal@Sun.COM } else { 5129086SVladimir.Kotal@Sun.COM if (line != NULL) { 5139086SVladimir.Kotal@Sun.COM if (strlcpy(ibuf, line, ibuf_size) >= ibuf_size) 5149086SVladimir.Kotal@Sun.COM warnx(dgettext(TEXT_DOMAIN, 5159086SVladimir.Kotal@Sun.COM "Line too long (max=%d chars)"), 5169086SVladimir.Kotal@Sun.COM ibuf_size); 5179086SVladimir.Kotal@Sun.COM line = ibuf; 5189086SVladimir.Kotal@Sun.COM } 5199086SVladimir.Kotal@Sun.COM } 5209086SVladimir.Kotal@Sun.COM 5219086SVladimir.Kotal@Sun.COM return (line); 5229086SVladimir.Kotal@Sun.COM } 5239086SVladimir.Kotal@Sun.COM 5249086SVladimir.Kotal@Sun.COM /* 5250Sstevel@tonic-gate * Enter a mode where commands are read from a file. Treat stdin special. 5260Sstevel@tonic-gate */ 5270Sstevel@tonic-gate void 5284235Smarkfen do_interactive(FILE *infile, char *configfile, char *promptstring, 5299086SVladimir.Kotal@Sun.COM char *my_fmri, parse_cmdln_fn parseit, CplMatchFn *match_fn) 5300Sstevel@tonic-gate { 5310Sstevel@tonic-gate char ibuf[IBUF_SIZE], holder[IBUF_SIZE]; 5324235Smarkfen char *hptr, **thisargv, *ebuf; 5330Sstevel@tonic-gate int thisargc; 5340Sstevel@tonic-gate boolean_t continue_in_progress = B_FALSE; 5359086SVladimir.Kotal@Sun.COM char *s; 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate (void) setjmp(env); 5380Sstevel@tonic-gate 5394235Smarkfen ebuf = NULL; 5400Sstevel@tonic-gate interactive = B_TRUE; 5410Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE); 5420Sstevel@tonic-gate 5439086SVladimir.Kotal@Sun.COM /* panics for us */ 5449086SVladimir.Kotal@Sun.COM init_interactive(infile, match_fn); 5450Sstevel@tonic-gate 5469086SVladimir.Kotal@Sun.COM while ((s = do_getstr(infile, promptstring, ibuf, IBUF_SIZE)) != NULL) { 5470Sstevel@tonic-gate if (readfile) 5480Sstevel@tonic-gate lineno++; 5490Sstevel@tonic-gate thisargc = 0; 5500Sstevel@tonic-gate thisargv = NULL; 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate /* 5530Sstevel@tonic-gate * Check byte IBUF_SIZE - 2, because byte IBUF_SIZE - 1 will 5540Sstevel@tonic-gate * be null-terminated because of fgets(). 5550Sstevel@tonic-gate */ 5560Sstevel@tonic-gate if (ibuf[IBUF_SIZE - 2] != '\0') { 5579086SVladimir.Kotal@Sun.COM if (infile == stdin) { 5589086SVladimir.Kotal@Sun.COM /* do_getstr() issued a warning already */ 5599086SVladimir.Kotal@Sun.COM bzero(ibuf, IBUF_SIZE); 5609086SVladimir.Kotal@Sun.COM continue; 5619086SVladimir.Kotal@Sun.COM } else { 5629086SVladimir.Kotal@Sun.COM ipsecutil_exit(SERVICE_FATAL, my_fmri, 5639086SVladimir.Kotal@Sun.COM debugfile, dgettext(TEXT_DOMAIN, 5649086SVladimir.Kotal@Sun.COM "Line %d too big."), lineno); 5659086SVladimir.Kotal@Sun.COM } 5660Sstevel@tonic-gate } 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate if (!continue_in_progress) { 5690Sstevel@tonic-gate /* Use -2 because of \n from fgets. */ 5700Sstevel@tonic-gate if (ibuf[strlen(ibuf) - 2] == CONT_CHAR) { 5710Sstevel@tonic-gate /* 5720Sstevel@tonic-gate * Can use strcpy here, I've checked the 5730Sstevel@tonic-gate * length already. 5740Sstevel@tonic-gate */ 5750Sstevel@tonic-gate (void) strcpy(holder, ibuf); 5760Sstevel@tonic-gate hptr = &(holder[strlen(holder)]); 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */ 5790Sstevel@tonic-gate hptr[-2] = ' '; 5800Sstevel@tonic-gate 5810Sstevel@tonic-gate continue_in_progress = B_TRUE; 5820Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE); 5830Sstevel@tonic-gate continue; 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate } else { 5860Sstevel@tonic-gate /* Handle continuations... */ 5870Sstevel@tonic-gate (void) strncpy(hptr, ibuf, 5880Sstevel@tonic-gate (size_t)(&(holder[IBUF_SIZE]) - hptr)); 5890Sstevel@tonic-gate if (holder[IBUF_SIZE - 1] != '\0') { 5904235Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri, 5914235Smarkfen debugfile, dgettext(TEXT_DOMAIN, 5924235Smarkfen "Command buffer overrun.")); 5930Sstevel@tonic-gate } 5940Sstevel@tonic-gate /* Use - 2 because of \n from fgets. */ 5950Sstevel@tonic-gate if (hptr[strlen(hptr) - 2] == CONT_CHAR) { 5960Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE); 5970Sstevel@tonic-gate hptr += strlen(hptr); 5980Sstevel@tonic-gate 5990Sstevel@tonic-gate /* Remove the CONT_CHAR from the string. */ 6000Sstevel@tonic-gate hptr[-2] = ' '; 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate continue; 6030Sstevel@tonic-gate } else { 6040Sstevel@tonic-gate continue_in_progress = B_FALSE; 6050Sstevel@tonic-gate /* 6060Sstevel@tonic-gate * I've already checked the length... 6070Sstevel@tonic-gate */ 6080Sstevel@tonic-gate (void) strcpy(ibuf, holder); 6090Sstevel@tonic-gate } 6100Sstevel@tonic-gate } 6110Sstevel@tonic-gate 6124235Smarkfen /* 6134235Smarkfen * Just in case the command fails keep a copy of the 6144235Smarkfen * command buffer for diagnostic output. 6154235Smarkfen */ 6164235Smarkfen if (readfile) { 6174235Smarkfen /* 6184235Smarkfen * The error buffer needs to be big enough to 6194235Smarkfen * hold the longest command string, plus 6204235Smarkfen * some extra text, see below. 6214235Smarkfen */ 6224235Smarkfen ebuf = calloc((IBUF_SIZE * 2), sizeof (char)); 6234235Smarkfen if (ebuf == NULL) { 6244235Smarkfen ipsecutil_exit(SERVICE_FATAL, my_fmri, 6254235Smarkfen debugfile, dgettext(TEXT_DOMAIN, 6264235Smarkfen "Memory allocation error.")); 6274235Smarkfen } else { 6284235Smarkfen (void) snprintf(ebuf, (IBUF_SIZE * 2), 6294235Smarkfen dgettext(TEXT_DOMAIN, 6304235Smarkfen "Config file entry near line %u " 6314235Smarkfen "caused error(s) or warnings:\n\n%s\n\n"), 6324235Smarkfen lineno, ibuf); 6334235Smarkfen } 6344235Smarkfen } 6354235Smarkfen 6360Sstevel@tonic-gate switch (create_argv(ibuf, &thisargc, &thisargv)) { 6370Sstevel@tonic-gate case TOO_MANY_TOKENS: 6384235Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile, 6394235Smarkfen dgettext(TEXT_DOMAIN, "Too many input tokens.")); 6400Sstevel@tonic-gate break; 6410Sstevel@tonic-gate case MEMORY_ALLOCATION: 6424235Smarkfen ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile, 6434235Smarkfen dgettext(TEXT_DOMAIN, "Memory allocation error.")); 6440Sstevel@tonic-gate break; 6450Sstevel@tonic-gate case COMMENT_LINE: 6460Sstevel@tonic-gate /* Comment line. */ 6474235Smarkfen free(ebuf); 6480Sstevel@tonic-gate break; 6490Sstevel@tonic-gate default: 6504235Smarkfen if (thisargc != 0) { 6514235Smarkfen lines_parsed++; 6524235Smarkfen /* ebuf consumed */ 6534342Spwernau parseit(thisargc, thisargv, ebuf, readfile); 6544235Smarkfen } else { 6554235Smarkfen free(ebuf); 6564235Smarkfen } 6570Sstevel@tonic-gate free(thisargv); 6580Sstevel@tonic-gate if (infile == stdin) { 6590Sstevel@tonic-gate (void) printf("%s", promptstring); 6600Sstevel@tonic-gate (void) fflush(stdout); 6610Sstevel@tonic-gate } 6620Sstevel@tonic-gate break; 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate bzero(ibuf, IBUF_SIZE); 6650Sstevel@tonic-gate } 6664342Spwernau 6674342Spwernau /* 6684342Spwernau * The following code is ipseckey specific. This should never be 6694342Spwernau * used by ikeadm which also calls this function because ikeadm 6704342Spwernau * only runs interactively. If this ever changes this code block 6714342Spwernau * sould be revisited. 6724342Spwernau */ 6734342Spwernau if (readfile) { 6744342Spwernau if (lines_parsed != 0 && lines_added == 0) { 6754342Spwernau ipsecutil_exit(SERVICE_BADCONF, my_fmri, debugfile, 6764342Spwernau dgettext(TEXT_DOMAIN, "Configuration file did not " 6774342Spwernau "contain any valid SAs")); 6784342Spwernau } 6794342Spwernau 6804342Spwernau /* 6814342Spwernau * There were errors. Putting the service in maintenance mode. 6824342Spwernau * When svc.startd(1M) allows services to degrade themselves, 6834342Spwernau * this should be revisited. 6844342Spwernau * 6854342Spwernau * If this function was called from a program running as a 6864342Spwernau * smf_method(5), print a warning message. Don't spew out the 6874342Spwernau * errors as these will end up in the smf(5) log file which is 6884342Spwernau * publically readable, the errors may contain sensitive 6894342Spwernau * information. 6904342Spwernau */ 6914342Spwernau if ((lines_added < lines_parsed) && (configfile != NULL)) { 6924342Spwernau if (my_fmri != NULL) { 6934342Spwernau ipsecutil_exit(SERVICE_BADCONF, my_fmri, 6944342Spwernau debugfile, dgettext(TEXT_DOMAIN, 6954342Spwernau "The configuration file contained %d " 6964342Spwernau "errors.\n" 6974342Spwernau "Manually check the configuration with:\n" 6984342Spwernau "ipseckey -c %s\n" 6994342Spwernau "Use svcadm(1M) to clear maintenance " 7004342Spwernau "condition when errors are resolved.\n"), 7014342Spwernau lines_parsed - lines_added, configfile); 7024342Spwernau } else { 7034342Spwernau EXIT_BADCONFIG(NULL); 7044342Spwernau } 7054342Spwernau } else { 7064342Spwernau if (my_fmri != NULL) 7074342Spwernau ipsecutil_exit(SERVICE_EXIT_OK, my_fmri, 7084342Spwernau debugfile, dgettext(TEXT_DOMAIN, 7094342Spwernau "%d actions successfully processed."), 7104342Spwernau lines_added); 7114342Spwernau } 7124342Spwernau } else { 7139086SVladimir.Kotal@Sun.COM /* no newline upon Ctrl-D */ 7149086SVladimir.Kotal@Sun.COM if (s != NULL) 7159086SVladimir.Kotal@Sun.COM (void) putchar('\n'); 7160Sstevel@tonic-gate (void) fflush(stdout); 7170Sstevel@tonic-gate } 7189086SVladimir.Kotal@Sun.COM 7199086SVladimir.Kotal@Sun.COM fini_interactive(); 7209086SVladimir.Kotal@Sun.COM 7214235Smarkfen EXIT_OK(NULL); 7220Sstevel@tonic-gate } 7230Sstevel@tonic-gate 7240Sstevel@tonic-gate /* 7250Sstevel@tonic-gate * Functions to parse strings that represent a debug or privilege level. 7260Sstevel@tonic-gate * These functions are copied from main.c and door.c in usr.lib/in.iked/common. 7270Sstevel@tonic-gate * If this file evolves into a common library that may be used by in.iked 7280Sstevel@tonic-gate * as well as the usr.sbin utilities, those duplicate functions should be 7290Sstevel@tonic-gate * deleted. 7300Sstevel@tonic-gate * 7310Sstevel@tonic-gate * A privilege level may be represented by a simple keyword, corresponding 7320Sstevel@tonic-gate * to one of the possible levels. A debug level may be represented by a 7330Sstevel@tonic-gate * series of keywords, separated by '+' or '-', indicating categories to 7340Sstevel@tonic-gate * be added or removed from the set of categories in the debug level. 7350Sstevel@tonic-gate * For example, +all-op corresponds to level 0xfffffffb (all flags except 7360Sstevel@tonic-gate * for D_OP set); while p1+p2+pfkey corresponds to level 0x38. Note that 7370Sstevel@tonic-gate * the leading '+' is implicit; the first keyword in the list must be for 7380Sstevel@tonic-gate * a category that is to be added. 7390Sstevel@tonic-gate * 7400Sstevel@tonic-gate * These parsing functions make use of a local version of strtok, strtok_d, 7410Sstevel@tonic-gate * which includes an additional parameter, char *delim. This param is filled 7420Sstevel@tonic-gate * in with the character which ends the returned token. In other words, 7430Sstevel@tonic-gate * this version of strtok, in addition to returning the token, also returns 7440Sstevel@tonic-gate * the single character delimiter from the original string which marked the 7450Sstevel@tonic-gate * end of the token. 7460Sstevel@tonic-gate */ 7470Sstevel@tonic-gate static char * 7480Sstevel@tonic-gate strtok_d(char *string, const char *sepset, char *delim) 7490Sstevel@tonic-gate { 7500Sstevel@tonic-gate static char *lasts; 7510Sstevel@tonic-gate char *q, *r; 7520Sstevel@tonic-gate 7530Sstevel@tonic-gate /* first or subsequent call */ 7540Sstevel@tonic-gate if (string == NULL) 7550Sstevel@tonic-gate string = lasts; 7560Sstevel@tonic-gate 7570Sstevel@tonic-gate if (string == 0) /* return if no tokens remaining */ 7580Sstevel@tonic-gate return (NULL); 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate q = string + strspn(string, sepset); /* skip leading separators */ 7610Sstevel@tonic-gate 7620Sstevel@tonic-gate if (*q == '\0') /* return if no tokens remaining */ 7630Sstevel@tonic-gate return (NULL); 7640Sstevel@tonic-gate 7650Sstevel@tonic-gate if ((r = strpbrk(q, sepset)) == NULL) { /* move past token */ 7660Sstevel@tonic-gate lasts = 0; /* indicate that this is last token */ 7670Sstevel@tonic-gate } else { 7680Sstevel@tonic-gate *delim = *r; /* save delimitor */ 7690Sstevel@tonic-gate *r = '\0'; 7700Sstevel@tonic-gate lasts = r + 1; 7710Sstevel@tonic-gate } 7720Sstevel@tonic-gate return (q); 7730Sstevel@tonic-gate } 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate static keywdtab_t privtab[] = { 7760Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "base" }, 7770Sstevel@tonic-gate { IKE_PRIV_MODKEYS, "modkeys" }, 7780Sstevel@tonic-gate { IKE_PRIV_KEYMAT, "keymat" }, 7790Sstevel@tonic-gate { IKE_PRIV_MINIMUM, "0" }, 7800Sstevel@tonic-gate }; 7810Sstevel@tonic-gate 7820Sstevel@tonic-gate int 7830Sstevel@tonic-gate privstr2num(char *str) 7840Sstevel@tonic-gate { 7850Sstevel@tonic-gate keywdtab_t *pp; 7860Sstevel@tonic-gate char *endp; 7870Sstevel@tonic-gate int priv; 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate for (pp = privtab; pp < A_END(privtab); pp++) { 7900Sstevel@tonic-gate if (strcasecmp(str, pp->kw_str) == 0) 7910Sstevel@tonic-gate return (pp->kw_tag); 7920Sstevel@tonic-gate } 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate priv = strtol(str, &endp, 0); 7950Sstevel@tonic-gate if (*endp == '\0') 7960Sstevel@tonic-gate return (priv); 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate return (-1); 7990Sstevel@tonic-gate } 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate static keywdtab_t dbgtab[] = { 8020Sstevel@tonic-gate { D_CERT, "cert" }, 8030Sstevel@tonic-gate { D_KEY, "key" }, 8040Sstevel@tonic-gate { D_OP, "op" }, 8050Sstevel@tonic-gate { D_P1, "p1" }, 8060Sstevel@tonic-gate { D_P1, "phase1" }, 8070Sstevel@tonic-gate { D_P2, "p2" }, 8080Sstevel@tonic-gate { D_P2, "phase2" }, 8090Sstevel@tonic-gate { D_PFKEY, "pfkey" }, 8100Sstevel@tonic-gate { D_POL, "pol" }, 8110Sstevel@tonic-gate { D_POL, "policy" }, 8120Sstevel@tonic-gate { D_PROP, "prop" }, 8130Sstevel@tonic-gate { D_DOOR, "door" }, 8140Sstevel@tonic-gate { D_CONFIG, "config" }, 8150Sstevel@tonic-gate { D_ALL, "all" }, 8160Sstevel@tonic-gate { 0, "0" }, 8170Sstevel@tonic-gate }; 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate int 8200Sstevel@tonic-gate dbgstr2num(char *str) 8210Sstevel@tonic-gate { 8220Sstevel@tonic-gate keywdtab_t *dp; 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate for (dp = dbgtab; dp < A_END(dbgtab); dp++) { 8250Sstevel@tonic-gate if (strcasecmp(str, dp->kw_str) == 0) 8260Sstevel@tonic-gate return (dp->kw_tag); 8270Sstevel@tonic-gate } 8280Sstevel@tonic-gate return (D_INVALID); 8290Sstevel@tonic-gate } 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate int 8320Sstevel@tonic-gate parsedbgopts(char *optarg) 8330Sstevel@tonic-gate { 8340Sstevel@tonic-gate char *argp, *endp, op, nextop; 8350Sstevel@tonic-gate int mask = 0, new; 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate mask = strtol(optarg, &endp, 0); 8380Sstevel@tonic-gate if (*endp == '\0') 8390Sstevel@tonic-gate return (mask); 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate op = optarg[0]; 8420Sstevel@tonic-gate if (op != '-') 8430Sstevel@tonic-gate op = '+'; 8440Sstevel@tonic-gate argp = strtok_d(optarg, "+-", &nextop); 8450Sstevel@tonic-gate do { 8460Sstevel@tonic-gate new = dbgstr2num(argp); 8470Sstevel@tonic-gate if (new == D_INVALID) { 8480Sstevel@tonic-gate /* we encountered an invalid keywd */ 8490Sstevel@tonic-gate return (new); 8500Sstevel@tonic-gate } 8510Sstevel@tonic-gate if (op == '+') { 8520Sstevel@tonic-gate mask |= new; 8530Sstevel@tonic-gate } else { 8540Sstevel@tonic-gate mask &= ~new; 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate op = nextop; 8570Sstevel@tonic-gate } while ((argp = strtok_d(NULL, "+-", &nextop)) != NULL); 8580Sstevel@tonic-gate 8590Sstevel@tonic-gate return (mask); 8600Sstevel@tonic-gate } 8610Sstevel@tonic-gate 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate /* 8640Sstevel@tonic-gate * functions to manipulate the kmcookie-label mapping file 8650Sstevel@tonic-gate */ 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate /* 8680Sstevel@tonic-gate * Open, lockf, fdopen the given file, returning a FILE * on success, 8690Sstevel@tonic-gate * or NULL on failure. 8700Sstevel@tonic-gate */ 8710Sstevel@tonic-gate FILE * 8720Sstevel@tonic-gate kmc_open_and_lock(char *name) 8730Sstevel@tonic-gate { 8740Sstevel@tonic-gate int fd, rtnerr; 8750Sstevel@tonic-gate FILE *fp; 8760Sstevel@tonic-gate 8770Sstevel@tonic-gate if ((fd = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { 8780Sstevel@tonic-gate return (NULL); 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate if (lockf(fd, F_LOCK, 0) < 0) { 8810Sstevel@tonic-gate return (NULL); 8820Sstevel@tonic-gate } 8830Sstevel@tonic-gate if ((fp = fdopen(fd, "a+")) == NULL) { 8840Sstevel@tonic-gate return (NULL); 8850Sstevel@tonic-gate } 8860Sstevel@tonic-gate if (fseek(fp, 0, SEEK_SET) < 0) { 8870Sstevel@tonic-gate /* save errno in case fclose changes it */ 8880Sstevel@tonic-gate rtnerr = errno; 8890Sstevel@tonic-gate (void) fclose(fp); 8900Sstevel@tonic-gate errno = rtnerr; 8910Sstevel@tonic-gate return (NULL); 8920Sstevel@tonic-gate } 8930Sstevel@tonic-gate return (fp); 8940Sstevel@tonic-gate } 8950Sstevel@tonic-gate 8960Sstevel@tonic-gate /* 8970Sstevel@tonic-gate * Extract an integer cookie and string label from a line from the 8980Sstevel@tonic-gate * kmcookie-label file. Return -1 on failure, 0 on success. 8990Sstevel@tonic-gate */ 9000Sstevel@tonic-gate int 9010Sstevel@tonic-gate kmc_parse_line(char *line, int *cookie, char **label) 9020Sstevel@tonic-gate { 9030Sstevel@tonic-gate char *cookiestr; 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate *cookie = 0; 9060Sstevel@tonic-gate *label = NULL; 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate cookiestr = strtok(line, " \t\n"); 9090Sstevel@tonic-gate if (cookiestr == NULL) { 9100Sstevel@tonic-gate return (-1); 9110Sstevel@tonic-gate } 9120Sstevel@tonic-gate 9130Sstevel@tonic-gate /* Everything that follows, up to the newline, is the label. */ 9140Sstevel@tonic-gate *label = strtok(NULL, "\n"); 9150Sstevel@tonic-gate if (*label == NULL) { 9160Sstevel@tonic-gate return (-1); 9170Sstevel@tonic-gate } 9180Sstevel@tonic-gate 9190Sstevel@tonic-gate *cookie = atoi(cookiestr); 9200Sstevel@tonic-gate return (0); 9210Sstevel@tonic-gate } 9220Sstevel@tonic-gate 9230Sstevel@tonic-gate /* 9240Sstevel@tonic-gate * Insert a mapping into the file (if it's not already there), given the 9250Sstevel@tonic-gate * new label. Return the assigned cookie, or -1 on error. 9260Sstevel@tonic-gate */ 9270Sstevel@tonic-gate int 9280Sstevel@tonic-gate kmc_insert_mapping(char *label) 9290Sstevel@tonic-gate { 9300Sstevel@tonic-gate FILE *map; 9314757Sdanmcd char linebuf[IBUF_SIZE]; 9320Sstevel@tonic-gate char *cur_label; 9330Sstevel@tonic-gate int max_cookie = 0, cur_cookie, rtn_cookie; 9340Sstevel@tonic-gate int rtnerr = 0; 9350Sstevel@tonic-gate boolean_t found = B_FALSE; 9360Sstevel@tonic-gate 9370Sstevel@tonic-gate /* open and lock the file; will sleep until lock is available */ 9380Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) { 9390Sstevel@tonic-gate /* kmc_open_and_lock() sets errno appropriately */ 9400Sstevel@tonic-gate return (-1); 9410Sstevel@tonic-gate } 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) { 9440Sstevel@tonic-gate 9454757Sdanmcd /* Skip blank lines, which often come near EOF. */ 9464757Sdanmcd if (strlen(linebuf) == 0) 9474757Sdanmcd continue; 9484757Sdanmcd 9490Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) { 9500Sstevel@tonic-gate rtnerr = EINVAL; 9510Sstevel@tonic-gate goto error; 9520Sstevel@tonic-gate } 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate if (cur_cookie > max_cookie) 9550Sstevel@tonic-gate max_cookie = cur_cookie; 9560Sstevel@tonic-gate 9570Sstevel@tonic-gate if ((!found) && (strcmp(cur_label, label) == 0)) { 9580Sstevel@tonic-gate found = B_TRUE; 9590Sstevel@tonic-gate rtn_cookie = cur_cookie; 9600Sstevel@tonic-gate } 9610Sstevel@tonic-gate } 9620Sstevel@tonic-gate 9630Sstevel@tonic-gate if (!found) { 9640Sstevel@tonic-gate rtn_cookie = ++max_cookie; 9650Sstevel@tonic-gate if ((fprintf(map, "%u\t%s\n", rtn_cookie, label) < 0) || 9660Sstevel@tonic-gate (fflush(map) < 0)) { 9670Sstevel@tonic-gate rtnerr = errno; 9680Sstevel@tonic-gate goto error; 9690Sstevel@tonic-gate } 9700Sstevel@tonic-gate } 9710Sstevel@tonic-gate (void) fclose(map); 9720Sstevel@tonic-gate 9730Sstevel@tonic-gate return (rtn_cookie); 9740Sstevel@tonic-gate 9750Sstevel@tonic-gate error: 9760Sstevel@tonic-gate (void) fclose(map); 9770Sstevel@tonic-gate errno = rtnerr; 9780Sstevel@tonic-gate return (-1); 9790Sstevel@tonic-gate } 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate /* 9820Sstevel@tonic-gate * Lookup the given cookie and return its corresponding label. Return 9830Sstevel@tonic-gate * a pointer to the label on success, NULL on error (or if the label is 9840Sstevel@tonic-gate * not found). Note that the returned label pointer points to a static 9850Sstevel@tonic-gate * string, so the label will be overwritten by a subsequent call to the 9860Sstevel@tonic-gate * function; the function is also not thread-safe as a result. 9870Sstevel@tonic-gate */ 9880Sstevel@tonic-gate char * 9890Sstevel@tonic-gate kmc_lookup_by_cookie(int cookie) 9900Sstevel@tonic-gate { 9910Sstevel@tonic-gate FILE *map; 9924757Sdanmcd static char linebuf[IBUF_SIZE]; 9930Sstevel@tonic-gate char *cur_label; 9940Sstevel@tonic-gate int cur_cookie; 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate if ((map = kmc_open_and_lock(KMCFILE)) == NULL) { 9970Sstevel@tonic-gate return (NULL); 9980Sstevel@tonic-gate } 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate while (fgets(linebuf, sizeof (linebuf), map) != NULL) { 10010Sstevel@tonic-gate 10020Sstevel@tonic-gate if (kmc_parse_line(linebuf, &cur_cookie, &cur_label) < 0) { 10030Sstevel@tonic-gate (void) fclose(map); 10040Sstevel@tonic-gate return (NULL); 10050Sstevel@tonic-gate } 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate if (cookie == cur_cookie) { 10080Sstevel@tonic-gate (void) fclose(map); 10090Sstevel@tonic-gate return (cur_label); 10100Sstevel@tonic-gate } 10110Sstevel@tonic-gate } 10120Sstevel@tonic-gate (void) fclose(map); 10130Sstevel@tonic-gate 10140Sstevel@tonic-gate return (NULL); 10150Sstevel@tonic-gate } 10160Sstevel@tonic-gate 10170Sstevel@tonic-gate /* 10180Sstevel@tonic-gate * Parse basic extension headers and return in the passed-in pointer vector. 10190Sstevel@tonic-gate * Return values include: 10200Sstevel@tonic-gate * 10210Sstevel@tonic-gate * KGE_OK Everything's nice and parsed out. 10220Sstevel@tonic-gate * If there are no extensions, place NULL in extv[0]. 10230Sstevel@tonic-gate * KGE_DUP There is a duplicate extension. 10240Sstevel@tonic-gate * First instance in appropriate bin. First duplicate in 10250Sstevel@tonic-gate * extv[0]. 10260Sstevel@tonic-gate * KGE_UNK Unknown extension type encountered. extv[0] contains 10270Sstevel@tonic-gate * unknown header. 10280Sstevel@tonic-gate * KGE_LEN Extension length error. 10290Sstevel@tonic-gate * KGE_CHK High-level reality check failed on specific extension. 10300Sstevel@tonic-gate * 10310Sstevel@tonic-gate * My apologies for some of the pointer arithmetic in here. I'm thinking 10320Sstevel@tonic-gate * like an assembly programmer, yet trying to make the compiler happy. 10330Sstevel@tonic-gate */ 10340Sstevel@tonic-gate int 10350Sstevel@tonic-gate spdsock_get_ext(spd_ext_t *extv[], spd_msg_t *basehdr, uint_t msgsize, 10360Sstevel@tonic-gate char *diag_buf, uint_t diag_buf_len) 10370Sstevel@tonic-gate { 10380Sstevel@tonic-gate int i; 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate if (diag_buf != NULL) 10410Sstevel@tonic-gate diag_buf[0] = '\0'; 10420Sstevel@tonic-gate 10430Sstevel@tonic-gate for (i = 1; i <= SPD_EXT_MAX; i++) 10440Sstevel@tonic-gate extv[i] = NULL; 10450Sstevel@tonic-gate 10460Sstevel@tonic-gate i = 0; 10470Sstevel@tonic-gate /* Use extv[0] as the "current working pointer". */ 10480Sstevel@tonic-gate 10490Sstevel@tonic-gate extv[0] = (spd_ext_t *)(basehdr + 1); 10500Sstevel@tonic-gate msgsize = SPD_64TO8(msgsize); 10510Sstevel@tonic-gate 10520Sstevel@tonic-gate while ((char *)extv[0] < ((char *)basehdr + msgsize)) { 10530Sstevel@tonic-gate /* Check for unknown headers. */ 10540Sstevel@tonic-gate i++; 10550Sstevel@tonic-gate if (extv[0]->spd_ext_type == 0 || 10560Sstevel@tonic-gate extv[0]->spd_ext_type > SPD_EXT_MAX) { 10570Sstevel@tonic-gate if (diag_buf != NULL) { 10580Sstevel@tonic-gate (void) snprintf(diag_buf, diag_buf_len, 10590Sstevel@tonic-gate "spdsock ext 0x%X unknown: 0x%X", 10600Sstevel@tonic-gate i, extv[0]->spd_ext_type); 10610Sstevel@tonic-gate } 10620Sstevel@tonic-gate return (KGE_UNK); 10630Sstevel@tonic-gate } 10640Sstevel@tonic-gate 10650Sstevel@tonic-gate /* 10660Sstevel@tonic-gate * Check length. Use uint64_t because extlen is in units 10670Sstevel@tonic-gate * of 64-bit words. If length goes beyond the msgsize, 10680Sstevel@tonic-gate * return an error. (Zero length also qualifies here.) 10690Sstevel@tonic-gate */ 10700Sstevel@tonic-gate if (extv[0]->spd_ext_len == 0 || 10710Sstevel@tonic-gate (uint8_t *)((uint64_t *)extv[0] + extv[0]->spd_ext_len) > 10720Sstevel@tonic-gate (uint8_t *)((uint8_t *)basehdr + msgsize)) 10730Sstevel@tonic-gate return (KGE_LEN); 10740Sstevel@tonic-gate 10750Sstevel@tonic-gate /* Check for redundant headers. */ 10760Sstevel@tonic-gate if (extv[extv[0]->spd_ext_type] != NULL) 10770Sstevel@tonic-gate return (KGE_DUP); 10780Sstevel@tonic-gate 10790Sstevel@tonic-gate /* If I make it here, assign the appropriate bin. */ 10800Sstevel@tonic-gate extv[extv[0]->spd_ext_type] = extv[0]; 10810Sstevel@tonic-gate 10820Sstevel@tonic-gate /* Advance pointer (See above for uint64_t ptr reasoning.) */ 10830Sstevel@tonic-gate extv[0] = (spd_ext_t *) 10840Sstevel@tonic-gate ((uint64_t *)extv[0] + extv[0]->spd_ext_len); 10850Sstevel@tonic-gate } 10860Sstevel@tonic-gate 10870Sstevel@tonic-gate /* Everything's cool. */ 10880Sstevel@tonic-gate 10890Sstevel@tonic-gate /* 10900Sstevel@tonic-gate * If extv[0] == NULL, then there are no extension headers in this 10910Sstevel@tonic-gate * message. Ensure that this is the case. 10920Sstevel@tonic-gate */ 10930Sstevel@tonic-gate if (extv[0] == (spd_ext_t *)(basehdr + 1)) 10940Sstevel@tonic-gate extv[0] = NULL; 10950Sstevel@tonic-gate 10960Sstevel@tonic-gate return (KGE_OK); 10970Sstevel@tonic-gate } 10980Sstevel@tonic-gate 10990Sstevel@tonic-gate const char * 11000Sstevel@tonic-gate spdsock_diag(int diagnostic) 11010Sstevel@tonic-gate { 11020Sstevel@tonic-gate switch (diagnostic) { 11030Sstevel@tonic-gate case SPD_DIAGNOSTIC_NONE: 11044064Smarkfen return (dgettext(TEXT_DOMAIN, "no error")); 11050Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNKNOWN_EXT: 11064064Smarkfen return (dgettext(TEXT_DOMAIN, "unknown extension")); 11070Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_EXTLEN: 11084064Smarkfen return (dgettext(TEXT_DOMAIN, "bad extension length")); 11090Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_RULE_EXT: 11104064Smarkfen return (dgettext(TEXT_DOMAIN, "no rule extension")); 11110Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_ADDR_LEN: 11124064Smarkfen return (dgettext(TEXT_DOMAIN, "bad address len")); 11130Sstevel@tonic-gate case SPD_DIAGNOSTIC_MIXED_AF: 11144064Smarkfen return (dgettext(TEXT_DOMAIN, "mixed address family")); 11150Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_NO_MEM: 11164064Smarkfen return (dgettext(TEXT_DOMAIN, "add: no memory")); 11170Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT: 11184064Smarkfen return (dgettext(TEXT_DOMAIN, "add: wrong action count")); 11190Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_TYPE: 11204064Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad type")); 11210Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_BAD_FLAGS: 11224064Smarkfen return (dgettext(TEXT_DOMAIN, "add: bad flags")); 11230Sstevel@tonic-gate case SPD_DIAGNOSTIC_ADD_INCON_FLAGS: 11244064Smarkfen return (dgettext(TEXT_DOMAIN, "add: inconsistent flags")); 11250Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLPORT: 11264064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local port")); 11270Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLPORT: 11284064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local port")); 11290Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMPORT: 11304064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote port")); 11310Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMPORT: 11324064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote port")); 11330Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_PROTO: 11344064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed proto")); 11350Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_PROTO: 11364064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate proto")); 11370Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_LCLADDR: 11384064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed local address")); 11390Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_LCLADDR: 11404064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate local address")); 11410Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_REMADDR: 11424064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed remote address")); 11430Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_REMADDR: 11444064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate remote address")); 11450Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_ACTION: 11464064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed action")); 11470Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_ACTION: 11484064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate action")); 11490Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULE: 11504064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed rule")); 11510Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULE: 11524064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate rule")); 11530Sstevel@tonic-gate case SPD_DIAGNOSTIC_MALFORMED_RULESET: 11544064Smarkfen return (dgettext(TEXT_DOMAIN, "malformed ruleset")); 11550Sstevel@tonic-gate case SPD_DIAGNOSTIC_DUPLICATE_RULESET: 11564064Smarkfen return (dgettext(TEXT_DOMAIN, "duplicate ruleset")); 11570Sstevel@tonic-gate case SPD_DIAGNOSTIC_INVALID_RULE_INDEX: 11584064Smarkfen return (dgettext(TEXT_DOMAIN, "invalid rule index")); 11590Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_SPDID: 11604064Smarkfen return (dgettext(TEXT_DOMAIN, "bad spdid")); 11610Sstevel@tonic-gate case SPD_DIAGNOSTIC_BAD_MSG_TYPE: 11624064Smarkfen return (dgettext(TEXT_DOMAIN, "bad message type")); 11630Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_ALG: 11644064Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH algorithm")); 11650Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG: 11664064Smarkfen return (dgettext(TEXT_DOMAIN, 11674064Smarkfen "unsupported ESP encryption algorithm")); 11680Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG: 11694064Smarkfen return (dgettext(TEXT_DOMAIN, 11704064Smarkfen "unsupported ESP authentication algorithm")); 11710Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE: 11724064Smarkfen return (dgettext(TEXT_DOMAIN, "unsupported AH key size")); 11730Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE: 11744064Smarkfen return (dgettext(TEXT_DOMAIN, 11754064Smarkfen "unsupported ESP encryption key size")); 11760Sstevel@tonic-gate case SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE: 11774064Smarkfen return (dgettext(TEXT_DOMAIN, 11784064Smarkfen "unsupported ESP authentication key size")); 11790Sstevel@tonic-gate case SPD_DIAGNOSTIC_NO_ACTION_EXT: 11804064Smarkfen return (dgettext(TEXT_DOMAIN, "No ACTION extension")); 11810Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_ID_RANGE: 11824064Smarkfen return (dgettext(TEXT_DOMAIN, "invalid algorithm identifer")); 11830Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES: 11844064Smarkfen return (dgettext(TEXT_DOMAIN, 11854064Smarkfen "number of key sizes inconsistent")); 11860Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES: 11874064Smarkfen return (dgettext(TEXT_DOMAIN, 11884064Smarkfen "number of block sizes inconsistent")); 11890Sstevel@tonic-gate case SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN: 11904064Smarkfen return (dgettext(TEXT_DOMAIN, "invalid mechanism name length")); 11913055Sdanmcd case SPD_DIAGNOSTIC_NOT_GLOBAL_OP: 11924064Smarkfen return (dgettext(TEXT_DOMAIN, 11934064Smarkfen "operation not applicable to all policies")); 11943055Sdanmcd case SPD_DIAGNOSTIC_NO_TUNNEL_SELECTORS: 11954064Smarkfen return (dgettext(TEXT_DOMAIN, 11964064Smarkfen "using selectors on a transport-mode tunnel")); 11970Sstevel@tonic-gate default: 11984064Smarkfen return (dgettext(TEXT_DOMAIN, "unknown diagnostic")); 11990Sstevel@tonic-gate } 12000Sstevel@tonic-gate } 12010Sstevel@tonic-gate 12020Sstevel@tonic-gate /* 12030Sstevel@tonic-gate * PF_KEY Diagnostic table. 12040Sstevel@tonic-gate * 12050Sstevel@tonic-gate * PF_KEY NOTE: If you change pfkeyv2.h's SADB_X_DIAGNOSTIC_* space, this is 12060Sstevel@tonic-gate * where you need to add new messages. 12070Sstevel@tonic-gate */ 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate const char * 12100Sstevel@tonic-gate keysock_diag(int diagnostic) 12110Sstevel@tonic-gate { 12120Sstevel@tonic-gate switch (diagnostic) { 12133055Sdanmcd case SADB_X_DIAGNOSTIC_NONE: 12144064Smarkfen return (dgettext(TEXT_DOMAIN, "No diagnostic")); 12150Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_MSG: 12164064Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown message type")); 12170Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_EXT: 12184064Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown extension type")); 12190Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EXTLEN: 12204064Smarkfen return (dgettext(TEXT_DOMAIN, "Bad extension length")); 12210Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_UNKNOWN_SATYPE: 12224064Smarkfen return (dgettext(TEXT_DOMAIN, 12234064Smarkfen "Unknown Security Association type")); 12240Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SATYPE_NEEDED: 12254064Smarkfen return (dgettext(TEXT_DOMAIN, 12264064Smarkfen "Specific Security Association type needed")); 12270Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_SADBS: 12284064Smarkfen return (dgettext(TEXT_DOMAIN, 12294064Smarkfen "No Security Association Databases present")); 12300Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_NO_EXT: 12314064Smarkfen return (dgettext(TEXT_DOMAIN, 12324064Smarkfen "No extensions needed for message")); 12330Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC_AF: 12344064Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address family")); 12350Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST_AF: 12364064Smarkfen return (dgettext(TEXT_DOMAIN, 12374064Smarkfen "Bad destination address family")); 12380Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_PROXY_AF: 12394064Smarkfen return (dgettext(TEXT_DOMAIN, 12404064Smarkfen "Bad inner-source address family")); 12410Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AF_MISMATCH: 12424064Smarkfen return (dgettext(TEXT_DOMAIN, 12434064Smarkfen "Source/destination address family mismatch")); 12440Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SRC: 12454064Smarkfen return (dgettext(TEXT_DOMAIN, "Bad source address value")); 12460Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_DST: 12474064Smarkfen return (dgettext(TEXT_DOMAIN, "Bad destination address value")); 12480Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ALLOC_HSERR: 12494064Smarkfen return (dgettext(TEXT_DOMAIN, 12504064Smarkfen "Soft allocations limit more than hard limit")); 12510Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BYTES_HSERR: 12524064Smarkfen return (dgettext(TEXT_DOMAIN, 12534064Smarkfen "Soft bytes limit more than hard limit")); 12540Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ADDTIME_HSERR: 12554064Smarkfen return (dgettext(TEXT_DOMAIN, "Soft add expiration time later " 12560Sstevel@tonic-gate "than hard expiration time")); 12570Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_USETIME_HSERR: 12584064Smarkfen return (dgettext(TEXT_DOMAIN, "Soft use expiration time later " 12590Sstevel@tonic-gate "than hard expiration time")); 12600Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SRC: 12614064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing source address")); 12620Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_DST: 12634064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing destination address")); 12640Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_SA: 12654064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SA extension")); 12660Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_EKEY: 12674064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing encryption key")); 12680Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_AKEY: 12694064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing authentication key")); 12700Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_RANGE: 12714064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing SPI range")); 12720Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SRC: 12734064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate source address")); 12740Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_DST: 12754064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate destination address")); 12760Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_SA: 12774064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SA extension")); 12780Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_EKEY: 12794064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate encryption key")); 12800Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_AKEY: 12814064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate authentication key")); 12820Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_RANGE: 12834064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate SPI range")); 12840Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SRC: 12854064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed source address")); 12860Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_DST: 12874064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed destination address")); 12880Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_SA: 12894064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SA extension")); 12900Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_EKEY: 12914064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed encryption key")); 12920Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_AKEY: 12934064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed authentication key")); 12940Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_RANGE: 12954064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed SPI range")); 12960Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_AKEY_PRESENT: 12974064Smarkfen return (dgettext(TEXT_DOMAIN, "Authentication key not needed")); 12980Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_EKEY_PRESENT: 12994064Smarkfen return (dgettext(TEXT_DOMAIN, "Encryption key not needed")); 13000Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_PROP_PRESENT: 13014064Smarkfen return (dgettext(TEXT_DOMAIN, "Proposal extension not needed")); 13020Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_SUPP_PRESENT: 13034064Smarkfen return (dgettext(TEXT_DOMAIN, 13044064Smarkfen "Supported algorithms extension not needed")); 13050Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AALG: 13064064Smarkfen return (dgettext(TEXT_DOMAIN, 13074064Smarkfen "Unsupported authentication algorithm")); 13080Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EALG: 13094064Smarkfen return (dgettext(TEXT_DOMAIN, 13104064Smarkfen "Unsupported encryption algorithm")); 13110Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SAFLAGS: 13124064Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA flags")); 13130Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_SASTATE: 13144064Smarkfen return (dgettext(TEXT_DOMAIN, "Invalid SA state")); 13150Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_AKEYBITS: 13164064Smarkfen return (dgettext(TEXT_DOMAIN, 13174064Smarkfen "Bad number of authentication bits")); 13180Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_BAD_EKEYBITS: 13194064Smarkfen return (dgettext(TEXT_DOMAIN, 13204064Smarkfen "Bad number of encryption bits")); 13210Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_ENCR_NOTSUPP: 13224064Smarkfen return (dgettext(TEXT_DOMAIN, 13234064Smarkfen "Encryption not supported for this SA type")); 13240Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_EKEY: 13254064Smarkfen return (dgettext(TEXT_DOMAIN, "Weak encryption key")); 13260Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_WEAK_AKEY: 13274064Smarkfen return (dgettext(TEXT_DOMAIN, "Weak authentication key")); 13280Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMP: 13294064Smarkfen return (dgettext(TEXT_DOMAIN, 13304064Smarkfen "Duplicate key management protocol")); 13310Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_KMC: 13324064Smarkfen return (dgettext(TEXT_DOMAIN, 13334064Smarkfen "Duplicate key management cookie")); 13340Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_LOC: 13354064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T local address")); 13360Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MISSING_NATT_REM: 13374064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing NAT-T remote address")); 13380Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_LOC: 13394064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T local address")); 13400Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_REM: 13414064Smarkfen return (dgettext(TEXT_DOMAIN, 13424064Smarkfen "Duplicate NAT-T remote address")); 13430Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC: 13444064Smarkfen return (dgettext(TEXT_DOMAIN, "Malformed NAT-T local address")); 13450Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM: 13464064Smarkfen return (dgettext(TEXT_DOMAIN, 13474064Smarkfen "Malformed NAT-T remote address")); 13480Sstevel@tonic-gate case SADB_X_DIAGNOSTIC_DUPLICATE_NATT_PORTS: 13494064Smarkfen return (dgettext(TEXT_DOMAIN, "Duplicate NAT-T ports")); 13503055Sdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_SRC: 13514064Smarkfen return (dgettext(TEXT_DOMAIN, "Missing inner source address")); 13523055Sdanmcd case SADB_X_DIAGNOSTIC_MISSING_INNER_DST: 13534064Smarkfen return (dgettext(TEXT_DOMAIN, 13544064Smarkfen "Missing inner destination address")); 13553055Sdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_SRC: 13564064Smarkfen return (dgettext(TEXT_DOMAIN, 13574064Smarkfen "Duplicate inner source address")); 13583055Sdanmcd case SADB_X_DIAGNOSTIC_DUPLICATE_INNER_DST: 13594064Smarkfen return (dgettext(TEXT_DOMAIN, 13604064Smarkfen "Duplicate inner destination address")); 13613055Sdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC: 13624064Smarkfen return (dgettext(TEXT_DOMAIN, 13634064Smarkfen "Malformed inner source address")); 13643055Sdanmcd case SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST: 13654064Smarkfen return (dgettext(TEXT_DOMAIN, 13664064Smarkfen "Malformed inner destination address")); 13673055Sdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC: 13684064Smarkfen return (dgettext(TEXT_DOMAIN, 13694064Smarkfen "Invalid inner-source prefix length ")); 13703055Sdanmcd case SADB_X_DIAGNOSTIC_PREFIX_INNER_DST: 13714064Smarkfen return (dgettext(TEXT_DOMAIN, 13724064Smarkfen "Invalid inner-destination prefix length")); 13733055Sdanmcd case SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF: 13744064Smarkfen return (dgettext(TEXT_DOMAIN, 13754064Smarkfen "Bad inner-destination address family")); 13763055Sdanmcd case SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH: 13774064Smarkfen return (dgettext(TEXT_DOMAIN, 13783055Sdanmcd "Inner source/destination address family mismatch")); 13793055Sdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF: 13804064Smarkfen return (dgettext(TEXT_DOMAIN, 13814064Smarkfen "Bad NAT-T remote address family")); 13823055Sdanmcd case SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF: 13834064Smarkfen return (dgettext(TEXT_DOMAIN, 13844064Smarkfen "Bad NAT-T local address family")); 13853055Sdanmcd case SADB_X_DIAGNOSTIC_PROTO_MISMATCH: 13864064Smarkfen return (dgettext(TEXT_DOMAIN, 13874064Smarkfen "Source/desination protocol mismatch")); 13883055Sdanmcd case SADB_X_DIAGNOSTIC_INNER_PROTO_MISMATCH: 13894064Smarkfen return (dgettext(TEXT_DOMAIN, 13904064Smarkfen "Inner source/desination protocol mismatch")); 13913055Sdanmcd case SADB_X_DIAGNOSTIC_DUAL_PORT_SETS: 13924064Smarkfen return (dgettext(TEXT_DOMAIN, 13934064Smarkfen "Both inner ports and outer ports are set")); 13946668Smarkfen case SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE: 13956668Smarkfen return (dgettext(TEXT_DOMAIN, 13966668Smarkfen "Pairing failed, target SA unsuitable for pairing")); 13976668Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ADD_MISMATCH: 13986668Smarkfen return (dgettext(TEXT_DOMAIN, 13996668Smarkfen "Source/destination address differs from pair SA")); 14006668Smarkfen case SADB_X_DIAGNOSTIC_PAIR_ALREADY: 14016668Smarkfen return (dgettext(TEXT_DOMAIN, 14026668Smarkfen "Already paired with another security association")); 14036668Smarkfen case SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND: 14046668Smarkfen return (dgettext(TEXT_DOMAIN, 14056668Smarkfen "Command failed, pair security association not found")); 14066668Smarkfen case SADB_X_DIAGNOSTIC_BAD_SA_DIRECTION: 14076668Smarkfen return (dgettext(TEXT_DOMAIN, 14086668Smarkfen "Inappropriate SA direction")); 14096668Smarkfen case SADB_X_DIAGNOSTIC_SA_NOTFOUND: 14106668Smarkfen return (dgettext(TEXT_DOMAIN, 14116668Smarkfen "Security association not found")); 14126668Smarkfen case SADB_X_DIAGNOSTIC_SA_EXPIRED: 14136668Smarkfen return (dgettext(TEXT_DOMAIN, 14146668Smarkfen "Security association is not valid")); 1415*10019SMark.Fenwick@Sun.COM case SADB_X_DIAGNOSTIC_BAD_CTX: 1416*10019SMark.Fenwick@Sun.COM return (dgettext(TEXT_DOMAIN, 1417*10019SMark.Fenwick@Sun.COM "Algorithm invalid or not supported by Crypto Framework")); 1418*10019SMark.Fenwick@Sun.COM case SADB_X_DIAGNOSTIC_INVALID_REPLAY: 1419*10019SMark.Fenwick@Sun.COM return (dgettext(TEXT_DOMAIN, 1420*10019SMark.Fenwick@Sun.COM "Invalid Replay counter")); 1421*10019SMark.Fenwick@Sun.COM case SADB_X_DIAGNOSTIC_MISSING_LIFETIME: 1422*10019SMark.Fenwick@Sun.COM return (dgettext(TEXT_DOMAIN, 1423*10019SMark.Fenwick@Sun.COM "Inappropriate lifetimes")); 14240Sstevel@tonic-gate default: 14254064Smarkfen return (dgettext(TEXT_DOMAIN, "Unknown diagnostic code")); 14260Sstevel@tonic-gate } 14270Sstevel@tonic-gate } 14283055Sdanmcd 14293055Sdanmcd /* 14303055Sdanmcd * Convert an IPv6 mask to a prefix len. I assume all IPv6 masks are 14313055Sdanmcd * contiguous, so I stop at the first zero bit! 14323055Sdanmcd */ 14333055Sdanmcd int 14343055Sdanmcd in_masktoprefix(uint8_t *mask, boolean_t is_v4mapped) 14353055Sdanmcd { 14363055Sdanmcd int rc = 0; 14373055Sdanmcd uint8_t last; 14383055Sdanmcd int limit = IPV6_ABITS; 14393055Sdanmcd 14403055Sdanmcd if (is_v4mapped) { 14413055Sdanmcd mask += ((IPV6_ABITS - IP_ABITS)/8); 14423055Sdanmcd limit = IP_ABITS; 14433055Sdanmcd } 14443055Sdanmcd 14453055Sdanmcd while (*mask == 0xff) { 14463055Sdanmcd rc += 8; 14473055Sdanmcd if (rc == limit) 14483055Sdanmcd return (limit); 14493055Sdanmcd mask++; 14503055Sdanmcd } 14513055Sdanmcd 14523055Sdanmcd last = *mask; 14533055Sdanmcd while (last != 0) { 14543055Sdanmcd rc++; 14553055Sdanmcd last = (last << 1) & 0xff; 14563055Sdanmcd } 14573055Sdanmcd 14583055Sdanmcd return (rc); 14593055Sdanmcd } 14603055Sdanmcd 14613055Sdanmcd /* 14623055Sdanmcd * Expand the diagnostic code into a message. 14633055Sdanmcd */ 14643055Sdanmcd void 14653055Sdanmcd print_diagnostic(FILE *file, uint16_t diagnostic) 14663055Sdanmcd { 14673055Sdanmcd /* Use two spaces so above strings can fit on the line. */ 14684064Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN, 14694064Smarkfen " Diagnostic code %u: %s.\n"), 14703055Sdanmcd diagnostic, keysock_diag(diagnostic)); 14713055Sdanmcd } 14723055Sdanmcd 14733055Sdanmcd /* 14743055Sdanmcd * Prints the base PF_KEY message. 14753055Sdanmcd */ 14763055Sdanmcd void 14774867Spwernau print_sadb_msg(FILE *file, struct sadb_msg *samsg, time_t wallclock, 14784867Spwernau boolean_t vflag) 14793055Sdanmcd { 14803055Sdanmcd if (wallclock != 0) 14814867Spwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN, 14824064Smarkfen "%sTimestamp: %s\n"), "", NULL, 14833055Sdanmcd vflag); 14843055Sdanmcd 14854867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 14864867Spwernau "Base message (version %u) type "), 14873055Sdanmcd samsg->sadb_msg_version); 14883055Sdanmcd switch (samsg->sadb_msg_type) { 14893055Sdanmcd case SADB_RESERVED: 14904867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 14914064Smarkfen "RESERVED (warning: set to 0)")); 14923055Sdanmcd break; 14933055Sdanmcd case SADB_GETSPI: 14944867Spwernau (void) fprintf(file, "GETSPI"); 14953055Sdanmcd break; 14963055Sdanmcd case SADB_UPDATE: 14974867Spwernau (void) fprintf(file, "UPDATE"); 14983055Sdanmcd break; 14996668Smarkfen case SADB_X_UPDATEPAIR: 15006668Smarkfen (void) fprintf(file, "UPDATE PAIR"); 15016668Smarkfen break; 15023055Sdanmcd case SADB_ADD: 15034867Spwernau (void) fprintf(file, "ADD"); 15043055Sdanmcd break; 15053055Sdanmcd case SADB_DELETE: 15064867Spwernau (void) fprintf(file, "DELETE"); 15073055Sdanmcd break; 15086668Smarkfen case SADB_X_DELPAIR: 15096668Smarkfen (void) fprintf(file, "DELETE PAIR"); 15106668Smarkfen break; 15113055Sdanmcd case SADB_GET: 15124867Spwernau (void) fprintf(file, "GET"); 15133055Sdanmcd break; 15143055Sdanmcd case SADB_ACQUIRE: 15154867Spwernau (void) fprintf(file, "ACQUIRE"); 15163055Sdanmcd break; 15173055Sdanmcd case SADB_REGISTER: 15184867Spwernau (void) fprintf(file, "REGISTER"); 15193055Sdanmcd break; 15203055Sdanmcd case SADB_EXPIRE: 15214867Spwernau (void) fprintf(file, "EXPIRE"); 15223055Sdanmcd break; 15233055Sdanmcd case SADB_FLUSH: 15244867Spwernau (void) fprintf(file, "FLUSH"); 15253055Sdanmcd break; 15263055Sdanmcd case SADB_DUMP: 15274867Spwernau (void) fprintf(file, "DUMP"); 15283055Sdanmcd break; 15293055Sdanmcd case SADB_X_PROMISC: 15304867Spwernau (void) fprintf(file, "X_PROMISC"); 15313055Sdanmcd break; 15323055Sdanmcd case SADB_X_INVERSE_ACQUIRE: 15334867Spwernau (void) fprintf(file, "X_INVERSE_ACQUIRE"); 15343055Sdanmcd break; 15353055Sdanmcd default: 15364867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15374064Smarkfen "Unknown (%u)"), samsg->sadb_msg_type); 15383055Sdanmcd break; 15393055Sdanmcd } 15404867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ", SA type ")); 15413055Sdanmcd 15423055Sdanmcd switch (samsg->sadb_msg_satype) { 15433055Sdanmcd case SADB_SATYPE_UNSPEC: 15444867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15454867Spwernau "<unspecified/all>")); 15463055Sdanmcd break; 15473055Sdanmcd case SADB_SATYPE_AH: 15484867Spwernau (void) fprintf(file, "AH"); 15493055Sdanmcd break; 15503055Sdanmcd case SADB_SATYPE_ESP: 15514867Spwernau (void) fprintf(file, "ESP"); 15523055Sdanmcd break; 15533055Sdanmcd case SADB_SATYPE_RSVP: 15544867Spwernau (void) fprintf(file, "RSVP"); 15553055Sdanmcd break; 15563055Sdanmcd case SADB_SATYPE_OSPFV2: 15574867Spwernau (void) fprintf(file, "OSPFv2"); 15583055Sdanmcd break; 15593055Sdanmcd case SADB_SATYPE_RIPV2: 15604867Spwernau (void) fprintf(file, "RIPv2"); 15613055Sdanmcd break; 15623055Sdanmcd case SADB_SATYPE_MIP: 15634867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Mobile IP")); 15643055Sdanmcd break; 15653055Sdanmcd default: 15664867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15674064Smarkfen "<unknown %u>"), samsg->sadb_msg_satype); 15683055Sdanmcd break; 15693055Sdanmcd } 15703055Sdanmcd 15714867Spwernau (void) fprintf(file, ".\n"); 15723055Sdanmcd 15733055Sdanmcd if (samsg->sadb_msg_errno != 0) { 15744867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15754867Spwernau "Error %s from PF_KEY.\n"), 15763055Sdanmcd strerror(samsg->sadb_msg_errno)); 15774867Spwernau print_diagnostic(file, samsg->sadb_x_msg_diagnostic); 15783055Sdanmcd } 15793055Sdanmcd 15804867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15814064Smarkfen "Message length %u bytes, seq=%u, pid=%u.\n"), 15823055Sdanmcd SADB_64TO8(samsg->sadb_msg_len), samsg->sadb_msg_seq, 15833055Sdanmcd samsg->sadb_msg_pid); 15843055Sdanmcd } 15853055Sdanmcd 15863055Sdanmcd /* 15873055Sdanmcd * Print the SA extension for PF_KEY. 15883055Sdanmcd */ 15893055Sdanmcd void 15904867Spwernau print_sa(FILE *file, char *prefix, struct sadb_sa *assoc) 15913055Sdanmcd { 15923055Sdanmcd if (assoc->sadb_sa_len != SADB_8TO64(sizeof (*assoc))) { 15934867Spwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 15944064Smarkfen "WARNING: SA info extension length (%u) is bad."), 15953055Sdanmcd SADB_64TO8(assoc->sadb_sa_len)); 15963055Sdanmcd } 15973055Sdanmcd 15984867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 15997749SThejaswini.Singarajipura@Sun.COM "%sSADB_ASSOC spi=0x%x, replay window size=%u, state="), 16003055Sdanmcd prefix, ntohl(assoc->sadb_sa_spi), assoc->sadb_sa_replay); 16013055Sdanmcd switch (assoc->sadb_sa_state) { 16023055Sdanmcd case SADB_SASTATE_LARVAL: 16034867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "LARVAL")); 16043055Sdanmcd break; 16053055Sdanmcd case SADB_SASTATE_MATURE: 16064867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "MATURE")); 16073055Sdanmcd break; 16083055Sdanmcd case SADB_SASTATE_DYING: 16094867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DYING")); 16103055Sdanmcd break; 16113055Sdanmcd case SADB_SASTATE_DEAD: 16124867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "DEAD")); 16133055Sdanmcd break; 16147749SThejaswini.Singarajipura@Sun.COM case SADB_X_SASTATE_ACTIVE_ELSEWHERE: 16157749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 16167749SThejaswini.Singarajipura@Sun.COM "ACTIVE_ELSEWHERE")); 16177749SThejaswini.Singarajipura@Sun.COM break; 16187749SThejaswini.Singarajipura@Sun.COM case SADB_X_SASTATE_IDLE: 16197749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, "IDLE")); 16207749SThejaswini.Singarajipura@Sun.COM break; 16213055Sdanmcd default: 16224867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 16234064Smarkfen "<unknown %u>"), assoc->sadb_sa_state); 16243055Sdanmcd } 16253055Sdanmcd 16263055Sdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) { 16274867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 16284064Smarkfen "\n%sAuthentication algorithm = "), 16293055Sdanmcd prefix); 16304867Spwernau (void) dump_aalg(assoc->sadb_sa_auth, file); 16313055Sdanmcd } 16323055Sdanmcd 16333055Sdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) { 16344867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 16354064Smarkfen "\n%sEncryption algorithm = "), prefix); 16364867Spwernau (void) dump_ealg(assoc->sadb_sa_encrypt, file); 16373055Sdanmcd } 16383055Sdanmcd 16394867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%sflags=0x%x < "), prefix, 16403055Sdanmcd assoc->sadb_sa_flags); 16413055Sdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_PFS) 16424867Spwernau (void) fprintf(file, "PFS "); 16433055Sdanmcd if (assoc->sadb_sa_flags & SADB_SAFLAGS_NOREPLAY) 16444867Spwernau (void) fprintf(file, "NOREPLAY "); 16453055Sdanmcd 16463055Sdanmcd /* BEGIN Solaris-specific flags. */ 16473055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_USED) 16484867Spwernau (void) fprintf(file, "X_USED "); 16496668Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_PAIRED) 16506668Smarkfen (void) fprintf(file, "X_PAIRED "); 16516668Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_OUTBOUND) 16526668Smarkfen (void) fprintf(file, "X_OUTBOUND "); 16536668Smarkfen if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_INBOUND) 16546668Smarkfen (void) fprintf(file, "X_INBOUND "); 16553055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_UNIQUE) 16564867Spwernau (void) fprintf(file, "X_UNIQUE "); 16573055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG1) 16584867Spwernau (void) fprintf(file, "X_AALG1 "); 16593055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_AALG2) 16604867Spwernau (void) fprintf(file, "X_AALG2 "); 16613055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG1) 16624867Spwernau (void) fprintf(file, "X_EALG1 "); 16633055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_EALG2) 16644867Spwernau (void) fprintf(file, "X_EALG2 "); 16653055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_LOC) 16664867Spwernau (void) fprintf(file, "X_NATT_LOC "); 16673055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATT_REM) 16684867Spwernau (void) fprintf(file, "X_NATT_REM "); 16693055Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) 16704867Spwernau (void) fprintf(file, "X_TUNNEL "); 16717066Sdanmcd if (assoc->sadb_sa_flags & SADB_X_SAFLAGS_NATTED) 16727066Sdanmcd (void) fprintf(file, "X_NATTED "); 16733055Sdanmcd /* END Solaris-specific flags. */ 16743055Sdanmcd 16754867Spwernau (void) fprintf(file, ">\n"); 16763055Sdanmcd } 16773055Sdanmcd 16783055Sdanmcd void 16794867Spwernau printsatime(FILE *file, int64_t lt, const char *msg, const char *pfx, 16804867Spwernau const char *pfx2, boolean_t vflag) 16813055Sdanmcd { 16823055Sdanmcd char tbuf[TBUF_SIZE]; /* For strftime() call. */ 16833055Sdanmcd const char *tp = tbuf; 16843055Sdanmcd time_t t = lt; 16853055Sdanmcd struct tm res; 16863055Sdanmcd 16873055Sdanmcd if (t != lt) { 16883055Sdanmcd if (lt > 0) 16893055Sdanmcd t = LONG_MAX; 16903055Sdanmcd else 16913055Sdanmcd t = LONG_MIN; 16923055Sdanmcd } 16933055Sdanmcd 16943055Sdanmcd if (strftime(tbuf, TBUF_SIZE, NULL, localtime_r(&t, &res)) == 0) 16954064Smarkfen tp = dgettext(TEXT_DOMAIN, "<time conversion failed>"); 16964867Spwernau (void) fprintf(file, msg, pfx, tp); 16973055Sdanmcd if (vflag && (pfx2 != NULL)) 16984867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 16997320Sdanmcd@sun.com "%s\t(raw time value %" PRIu64 ")\n"), pfx2, lt); 17003055Sdanmcd } 17013055Sdanmcd 17023055Sdanmcd /* 17033055Sdanmcd * Print the SA lifetime information. (An SADB_EXT_LIFETIME_* extension.) 17043055Sdanmcd */ 17053055Sdanmcd void 17064867Spwernau print_lifetimes(FILE *file, time_t wallclock, struct sadb_lifetime *current, 17077749SThejaswini.Singarajipura@Sun.COM struct sadb_lifetime *hard, struct sadb_lifetime *soft, 17087749SThejaswini.Singarajipura@Sun.COM struct sadb_lifetime *idle, boolean_t vflag) 17093055Sdanmcd { 17103055Sdanmcd int64_t scratch; 17114064Smarkfen char *soft_prefix = dgettext(TEXT_DOMAIN, "SLT: "); 17124064Smarkfen char *hard_prefix = dgettext(TEXT_DOMAIN, "HLT: "); 17134064Smarkfen char *current_prefix = dgettext(TEXT_DOMAIN, "CLT: "); 17147749SThejaswini.Singarajipura@Sun.COM char *idle_prefix = dgettext(TEXT_DOMAIN, "ILT: "); 17153055Sdanmcd 17163055Sdanmcd if (current != NULL && 17173055Sdanmcd current->sadb_lifetime_len != SADB_8TO64(sizeof (*current))) { 17184867Spwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 17194064Smarkfen "WARNING: CURRENT lifetime extension length (%u) is bad."), 17203055Sdanmcd SADB_64TO8(current->sadb_lifetime_len)); 17213055Sdanmcd } 17223055Sdanmcd 17233055Sdanmcd if (hard != NULL && 17243055Sdanmcd hard->sadb_lifetime_len != SADB_8TO64(sizeof (*hard))) { 17254867Spwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 17264867Spwernau "WARNING: HARD lifetime extension length (%u) is bad."), 17273055Sdanmcd SADB_64TO8(hard->sadb_lifetime_len)); 17283055Sdanmcd } 17293055Sdanmcd 17303055Sdanmcd if (soft != NULL && 17313055Sdanmcd soft->sadb_lifetime_len != SADB_8TO64(sizeof (*soft))) { 17324867Spwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 17334867Spwernau "WARNING: SOFT lifetime extension length (%u) is bad."), 17343055Sdanmcd SADB_64TO8(soft->sadb_lifetime_len)); 17353055Sdanmcd } 17363055Sdanmcd 17377749SThejaswini.Singarajipura@Sun.COM if (idle != NULL && 17387749SThejaswini.Singarajipura@Sun.COM idle->sadb_lifetime_len != SADB_8TO64(sizeof (*idle))) { 17397749SThejaswini.Singarajipura@Sun.COM warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 17407749SThejaswini.Singarajipura@Sun.COM "WARNING: IDLE lifetime extension length (%u) is bad."), 17417749SThejaswini.Singarajipura@Sun.COM SADB_64TO8(idle->sadb_lifetime_len)); 17427749SThejaswini.Singarajipura@Sun.COM } 17437749SThejaswini.Singarajipura@Sun.COM 17444867Spwernau (void) fprintf(file, " LT: Lifetime information\n"); 17453055Sdanmcd 17463055Sdanmcd if (current != NULL) { 17473055Sdanmcd /* Express values as current values. */ 17484867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 17497320Sdanmcd@sun.com "%s%" PRIu64 " bytes protected, %u allocations used.\n"), 17503055Sdanmcd current_prefix, current->sadb_lifetime_bytes, 17513055Sdanmcd current->sadb_lifetime_allocations); 17524867Spwernau printsatime(file, current->sadb_lifetime_addtime, 17534064Smarkfen dgettext(TEXT_DOMAIN, "%sSA added at time %s\n"), 17543055Sdanmcd current_prefix, current_prefix, vflag); 17553055Sdanmcd if (current->sadb_lifetime_usetime != 0) { 17564867Spwernau printsatime(file, current->sadb_lifetime_usetime, 17574064Smarkfen dgettext(TEXT_DOMAIN, 17584064Smarkfen "%sSA first used at time %s\n"), 17593055Sdanmcd current_prefix, current_prefix, vflag); 17603055Sdanmcd } 17614867Spwernau printsatime(file, wallclock, dgettext(TEXT_DOMAIN, 17624064Smarkfen "%sTime now is %s\n"), current_prefix, current_prefix, 17634064Smarkfen vflag); 17643055Sdanmcd } 17653055Sdanmcd 17663055Sdanmcd if (soft != NULL) { 17674867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 17684064Smarkfen "%sSoft lifetime information: "), 17693055Sdanmcd soft_prefix); 17704867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 17717320Sdanmcd@sun.com "%" PRIu64 " bytes of lifetime, %u " 17723055Sdanmcd "allocations.\n"), soft->sadb_lifetime_bytes, 17733055Sdanmcd soft->sadb_lifetime_allocations); 17744867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 17757320Sdanmcd@sun.com "%s%" PRIu64 " seconds of post-add lifetime.\n"), 17763055Sdanmcd soft_prefix, soft->sadb_lifetime_addtime); 17774867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 17787320Sdanmcd@sun.com "%s%" PRIu64 " seconds of post-use lifetime.\n"), 17793055Sdanmcd soft_prefix, soft->sadb_lifetime_usetime); 17803055Sdanmcd /* If possible, express values as time remaining. */ 17813055Sdanmcd if (current != NULL) { 17823055Sdanmcd if (soft->sadb_lifetime_bytes != 0) 17837320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s%" 17847320Sdanmcd@sun.com PRIu64 " more bytes can be protected.\n"), 17853055Sdanmcd soft_prefix, 17863055Sdanmcd (soft->sadb_lifetime_bytes > 17874342Spwernau current->sadb_lifetime_bytes) ? 17883055Sdanmcd (soft->sadb_lifetime_bytes - 17894342Spwernau current->sadb_lifetime_bytes) : (0)); 17903055Sdanmcd if (soft->sadb_lifetime_addtime != 0 || 17913055Sdanmcd (soft->sadb_lifetime_usetime != 0 && 17924342Spwernau current->sadb_lifetime_usetime != 0)) { 17933055Sdanmcd int64_t adddelta, usedelta; 17943055Sdanmcd 17953055Sdanmcd if (soft->sadb_lifetime_addtime != 0) { 17963055Sdanmcd adddelta = 17973055Sdanmcd current->sadb_lifetime_addtime + 17983055Sdanmcd soft->sadb_lifetime_addtime - 17993055Sdanmcd wallclock; 18003055Sdanmcd } else { 18013055Sdanmcd adddelta = TIME_MAX; 18023055Sdanmcd } 18033055Sdanmcd 18043055Sdanmcd if (soft->sadb_lifetime_usetime != 0 && 18053055Sdanmcd current->sadb_lifetime_usetime != 0) { 18063055Sdanmcd usedelta = 18073055Sdanmcd current->sadb_lifetime_usetime + 18083055Sdanmcd soft->sadb_lifetime_usetime - 18093055Sdanmcd wallclock; 18103055Sdanmcd } else { 18113055Sdanmcd usedelta = TIME_MAX; 18123055Sdanmcd } 18134867Spwernau (void) fprintf(file, "%s", soft_prefix); 18143055Sdanmcd scratch = MIN(adddelta, usedelta); 18153055Sdanmcd if (scratch >= 0) { 18164867Spwernau (void) fprintf(file, 18174867Spwernau dgettext(TEXT_DOMAIN, 18187320Sdanmcd@sun.com "Soft expiration occurs in %" 18197320Sdanmcd@sun.com PRId64 " seconds, "), scratch); 18203055Sdanmcd } else { 18214867Spwernau (void) fprintf(file, 18224867Spwernau dgettext(TEXT_DOMAIN, 18233055Sdanmcd "Soft expiration occurred ")); 18243055Sdanmcd } 18253055Sdanmcd scratch += wallclock; 18264867Spwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN, 18274064Smarkfen "%sat %s.\n"), "", soft_prefix, vflag); 18283055Sdanmcd } 18293055Sdanmcd } 18303055Sdanmcd } 18313055Sdanmcd 18323055Sdanmcd if (hard != NULL) { 18334867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 18344064Smarkfen "%sHard lifetime information: "), hard_prefix); 18354867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 18367320Sdanmcd@sun.com "%" PRIu64 " bytes of lifetime, %u allocations.\n"), 18374867Spwernau hard->sadb_lifetime_bytes, hard->sadb_lifetime_allocations); 18384867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 18397320Sdanmcd@sun.com "%s%" PRIu64 " seconds of post-add lifetime.\n"), 18403055Sdanmcd hard_prefix, hard->sadb_lifetime_addtime); 18414867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 18427320Sdanmcd@sun.com "%s%" PRIu64 " seconds of post-use lifetime.\n"), 18433055Sdanmcd hard_prefix, hard->sadb_lifetime_usetime); 18443055Sdanmcd /* If possible, express values as time remaining. */ 18453055Sdanmcd if (current != NULL) { 18463055Sdanmcd if (hard->sadb_lifetime_bytes != 0) 18477320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s%" 18487320Sdanmcd@sun.com PRIu64 " more bytes can be protected.\n"), 18493055Sdanmcd hard_prefix, 18503055Sdanmcd (hard->sadb_lifetime_bytes > 18514342Spwernau current->sadb_lifetime_bytes) ? 18523055Sdanmcd (hard->sadb_lifetime_bytes - 18534342Spwernau current->sadb_lifetime_bytes) : (0)); 18543055Sdanmcd if (hard->sadb_lifetime_addtime != 0 || 18553055Sdanmcd (hard->sadb_lifetime_usetime != 0 && 18564342Spwernau current->sadb_lifetime_usetime != 0)) { 18573055Sdanmcd int64_t adddelta, usedelta; 18583055Sdanmcd 18593055Sdanmcd if (hard->sadb_lifetime_addtime != 0) { 18603055Sdanmcd adddelta = 18613055Sdanmcd current->sadb_lifetime_addtime + 18623055Sdanmcd hard->sadb_lifetime_addtime - 18633055Sdanmcd wallclock; 18643055Sdanmcd } else { 18653055Sdanmcd adddelta = TIME_MAX; 18663055Sdanmcd } 18673055Sdanmcd 18683055Sdanmcd if (hard->sadb_lifetime_usetime != 0 && 18693055Sdanmcd current->sadb_lifetime_usetime != 0) { 18703055Sdanmcd usedelta = 18713055Sdanmcd current->sadb_lifetime_usetime + 18723055Sdanmcd hard->sadb_lifetime_usetime - 18733055Sdanmcd wallclock; 18743055Sdanmcd } else { 18753055Sdanmcd usedelta = TIME_MAX; 18763055Sdanmcd } 18774867Spwernau (void) fprintf(file, "%s", hard_prefix); 18783055Sdanmcd scratch = MIN(adddelta, usedelta); 18793055Sdanmcd if (scratch >= 0) { 18804867Spwernau (void) fprintf(file, 18814867Spwernau dgettext(TEXT_DOMAIN, 18827320Sdanmcd@sun.com "Hard expiration occurs in %" 18837320Sdanmcd@sun.com PRId64 " seconds, "), scratch); 18843055Sdanmcd } else { 18854867Spwernau (void) fprintf(file, 18864867Spwernau dgettext(TEXT_DOMAIN, 18873055Sdanmcd "Hard expiration occured ")); 18883055Sdanmcd } 18893055Sdanmcd scratch += wallclock; 18904867Spwernau printsatime(file, scratch, dgettext(TEXT_DOMAIN, 18914064Smarkfen "%sat %s.\n"), "", hard_prefix, vflag); 18923055Sdanmcd } 18933055Sdanmcd } 18943055Sdanmcd } 18957749SThejaswini.Singarajipura@Sun.COM if (idle != NULL) { 18967749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 18977749SThejaswini.Singarajipura@Sun.COM "%sIdle lifetime information: "), idle_prefix); 18987749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 18997749SThejaswini.Singarajipura@Sun.COM "%s%llu seconds of post-add lifetime.\n"), 19007749SThejaswini.Singarajipura@Sun.COM idle_prefix, idle->sadb_lifetime_addtime); 19017749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 19027749SThejaswini.Singarajipura@Sun.COM "%s%llu seconds of post-use lifetime.\n"), 19037749SThejaswini.Singarajipura@Sun.COM idle_prefix, idle->sadb_lifetime_usetime); 19047749SThejaswini.Singarajipura@Sun.COM } 19053055Sdanmcd } 19063055Sdanmcd 19073055Sdanmcd /* 19083055Sdanmcd * Print an SADB_EXT_ADDRESS_* extension. 19093055Sdanmcd */ 19103055Sdanmcd void 19114867Spwernau print_address(FILE *file, char *prefix, struct sadb_address *addr, 19124867Spwernau boolean_t ignore_nss) 19133055Sdanmcd { 19143055Sdanmcd struct protoent *pe; 19153055Sdanmcd 19164867Spwernau (void) fprintf(file, "%s", prefix); 19173055Sdanmcd switch (addr->sadb_address_exttype) { 19183055Sdanmcd case SADB_EXT_ADDRESS_SRC: 19194867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source address ")); 19203055Sdanmcd break; 19213055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC: 19224867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19234867Spwernau "Inner source address ")); 19243055Sdanmcd break; 19253055Sdanmcd case SADB_EXT_ADDRESS_DST: 19264867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19274867Spwernau "Destination address ")); 19283055Sdanmcd break; 19293055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_DST: 19304867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19314064Smarkfen "Inner destination address ")); 19323055Sdanmcd break; 19333055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC: 19344867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19354867Spwernau "NAT-T local address ")); 19363055Sdanmcd break; 19373055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_REM: 19384867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19394867Spwernau "NAT-T remote address ")); 19403055Sdanmcd break; 19413055Sdanmcd } 19423055Sdanmcd 19434867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19444064Smarkfen "(proto=%d"), addr->sadb_address_proto); 19454867Spwernau if (ignore_nss == B_FALSE) { 19463055Sdanmcd if (addr->sadb_address_proto == 0) { 19474867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19484867Spwernau "/<unspecified>")); 19493055Sdanmcd } else if ((pe = getprotobynumber(addr->sadb_address_proto)) 19503055Sdanmcd != NULL) { 19514867Spwernau (void) fprintf(file, "/%s", pe->p_name); 19523055Sdanmcd } else { 19534867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 19544867Spwernau "/<unknown>")); 19553055Sdanmcd } 19563055Sdanmcd } 19574867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, ")\n%s"), prefix); 19583055Sdanmcd (void) dump_sockaddr((struct sockaddr *)(addr + 1), 19594867Spwernau addr->sadb_address_prefixlen, B_FALSE, file, ignore_nss); 19603055Sdanmcd } 19613055Sdanmcd 19623055Sdanmcd /* 19633055Sdanmcd * Print an SADB_EXT_KEY extension. 19643055Sdanmcd */ 19653055Sdanmcd void 19664867Spwernau print_key(FILE *file, char *prefix, struct sadb_key *key) 19673055Sdanmcd { 19684867Spwernau (void) fprintf(file, "%s", prefix); 19693055Sdanmcd 19703055Sdanmcd switch (key->sadb_key_exttype) { 19713055Sdanmcd case SADB_EXT_KEY_AUTH: 19724867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Authentication")); 19733055Sdanmcd break; 19743055Sdanmcd case SADB_EXT_KEY_ENCRYPT: 19754867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Encryption")); 19763055Sdanmcd break; 19773055Sdanmcd } 19783055Sdanmcd 19794867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " key.\n%s"), prefix); 19804867Spwernau (void) dump_key((uint8_t *)(key + 1), key->sadb_key_bits, file); 19814867Spwernau (void) fprintf(file, "\n"); 19823055Sdanmcd } 19833055Sdanmcd 19843055Sdanmcd /* 19853055Sdanmcd * Print an SADB_EXT_IDENTITY_* extension. 19863055Sdanmcd */ 19873055Sdanmcd void 19884867Spwernau print_ident(FILE *file, char *prefix, struct sadb_ident *id) 19893055Sdanmcd { 19903055Sdanmcd boolean_t canprint = B_TRUE; 19913055Sdanmcd 19924867Spwernau (void) fprintf(file, "%s", prefix); 19933055Sdanmcd switch (id->sadb_ident_exttype) { 19943055Sdanmcd case SADB_EXT_IDENTITY_SRC: 19954867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Source")); 19963055Sdanmcd break; 19973055Sdanmcd case SADB_EXT_IDENTITY_DST: 19984867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "Destination")); 19993055Sdanmcd break; 20003055Sdanmcd } 20013055Sdanmcd 20024867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20034064Smarkfen " identity, uid=%d, type "), id->sadb_ident_id); 20044867Spwernau canprint = dump_sadb_idtype(id->sadb_ident_type, file, NULL); 20054867Spwernau (void) fprintf(file, "\n%s", prefix); 20066119Spwernau if (canprint) { 20074867Spwernau (void) fprintf(file, "%s\n", (char *)(id + 1)); 20086119Spwernau } else { 20096119Spwernau print_asn1_name(file, (const unsigned char *)(id + 1), 20106119Spwernau SADB_64TO8(id->sadb_ident_len) - sizeof (sadb_ident_t)); 20116119Spwernau } 20123055Sdanmcd } 20133055Sdanmcd 20143055Sdanmcd /* 20153055Sdanmcd * Print an SADB_SENSITIVITY extension. 20163055Sdanmcd */ 20173055Sdanmcd void 20184867Spwernau print_sens(FILE *file, char *prefix, struct sadb_sens *sens) 20193055Sdanmcd { 20203055Sdanmcd uint64_t *bitmap = (uint64_t *)(sens + 1); 20213055Sdanmcd int i; 20223055Sdanmcd 20234867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20244064Smarkfen "%sSensitivity DPD %d, sens level=%d, integ level=%d\n"), 20253055Sdanmcd prefix, sens->sadb_sens_dpd, sens->sadb_sens_sens_level, 20263055Sdanmcd sens->sadb_sens_integ_level); 20273055Sdanmcd for (i = 0; sens->sadb_sens_sens_len-- > 0; i++, bitmap++) 20284867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20297320Sdanmcd@sun.com "%s Sensitivity BM extended word %d 0x%" PRIx64 "\n"), 20304867Spwernau prefix, i, *bitmap); 20313055Sdanmcd for (i = 0; sens->sadb_sens_integ_len-- > 0; i++, bitmap++) 20324867Spwernau (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 20337320Sdanmcd@sun.com "%s Integrity BM extended word %d 0x%" PRIx64 "\n"), 20344867Spwernau prefix, i, *bitmap); 20353055Sdanmcd } 20363055Sdanmcd 20373055Sdanmcd /* 20383055Sdanmcd * Print an SADB_EXT_PROPOSAL extension. 20393055Sdanmcd */ 20403055Sdanmcd void 20414867Spwernau print_prop(FILE *file, char *prefix, struct sadb_prop *prop) 20423055Sdanmcd { 20433055Sdanmcd struct sadb_comb *combs; 20443055Sdanmcd int i, numcombs; 20453055Sdanmcd 20464867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20474064Smarkfen "%sProposal, replay counter = %u.\n"), prefix, 20483055Sdanmcd prop->sadb_prop_replay); 20493055Sdanmcd 20503055Sdanmcd numcombs = prop->sadb_prop_len - SADB_8TO64(sizeof (*prop)); 20513055Sdanmcd numcombs /= SADB_8TO64(sizeof (*combs)); 20523055Sdanmcd 20533055Sdanmcd combs = (struct sadb_comb *)(prop + 1); 20543055Sdanmcd 20553055Sdanmcd for (i = 0; i < numcombs; i++) { 20564867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20574064Smarkfen "%s Combination #%u "), prefix, i + 1); 20583055Sdanmcd if (combs[i].sadb_comb_auth != SADB_AALG_NONE) { 20594867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20604064Smarkfen "Authentication = ")); 20614867Spwernau (void) dump_aalg(combs[i].sadb_comb_auth, file); 20624867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20634064Smarkfen " minbits=%u, maxbits=%u.\n%s "), 20643055Sdanmcd combs[i].sadb_comb_auth_minbits, 20653055Sdanmcd combs[i].sadb_comb_auth_maxbits, prefix); 20663055Sdanmcd } 20673055Sdanmcd 20683055Sdanmcd if (combs[i].sadb_comb_encrypt != SADB_EALG_NONE) { 20694867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20704867Spwernau "Encryption = ")); 20714867Spwernau (void) dump_ealg(combs[i].sadb_comb_encrypt, file); 20724867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20734064Smarkfen " minbits=%u, maxbits=%u.\n%s "), 20743055Sdanmcd combs[i].sadb_comb_encrypt_minbits, 20753055Sdanmcd combs[i].sadb_comb_encrypt_maxbits, prefix); 20763055Sdanmcd } 20773055Sdanmcd 20784867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "HARD: ")); 20793055Sdanmcd if (combs[i].sadb_comb_hard_allocations) 20804867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "), 20813055Sdanmcd combs[i].sadb_comb_hard_allocations); 20823055Sdanmcd if (combs[i].sadb_comb_hard_bytes) 20837320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%" 20847320Sdanmcd@sun.com PRIu64 " "), combs[i].sadb_comb_hard_bytes); 20853055Sdanmcd if (combs[i].sadb_comb_hard_addtime) 20864867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20877320Sdanmcd@sun.com "post-add secs=%" PRIu64 " "), 20883055Sdanmcd combs[i].sadb_comb_hard_addtime); 20893055Sdanmcd if (combs[i].sadb_comb_hard_usetime) 20904867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 20917320Sdanmcd@sun.com "post-use secs=%" PRIu64 ""), 20923055Sdanmcd combs[i].sadb_comb_hard_usetime); 20933055Sdanmcd 20944867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "\n%s SOFT: "), 20954867Spwernau prefix); 20963055Sdanmcd if (combs[i].sadb_comb_soft_allocations) 20974867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u "), 20983055Sdanmcd combs[i].sadb_comb_soft_allocations); 20993055Sdanmcd if (combs[i].sadb_comb_soft_bytes) 21007320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%" 21017320Sdanmcd@sun.com PRIu64 " "), combs[i].sadb_comb_soft_bytes); 21023055Sdanmcd if (combs[i].sadb_comb_soft_addtime) 21034867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21047320Sdanmcd@sun.com "post-add secs=%" PRIu64 " "), 21053055Sdanmcd combs[i].sadb_comb_soft_addtime); 21063055Sdanmcd if (combs[i].sadb_comb_soft_usetime) 21074867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21087320Sdanmcd@sun.com "post-use secs=%" PRIu64 ""), 21093055Sdanmcd combs[i].sadb_comb_soft_usetime); 21104867Spwernau (void) fprintf(file, "\n"); 21113055Sdanmcd } 21123055Sdanmcd } 21133055Sdanmcd 21143055Sdanmcd /* 21153055Sdanmcd * Print an extended proposal (SADB_X_EXT_EPROP). 21163055Sdanmcd */ 21173055Sdanmcd void 21184867Spwernau print_eprop(FILE *file, char *prefix, struct sadb_prop *eprop) 21193055Sdanmcd { 21203055Sdanmcd uint64_t *sofar; 21213055Sdanmcd struct sadb_x_ecomb *ecomb; 21223055Sdanmcd struct sadb_x_algdesc *algdesc; 21233055Sdanmcd int i, j; 21243055Sdanmcd 21254867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21264064Smarkfen "%sExtended Proposal, replay counter = %u, "), prefix, 21274064Smarkfen eprop->sadb_prop_replay); 21284867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21294867Spwernau "number of combinations = %u.\n"), eprop->sadb_x_prop_numecombs); 21303055Sdanmcd 21313055Sdanmcd sofar = (uint64_t *)(eprop + 1); 21323055Sdanmcd ecomb = (struct sadb_x_ecomb *)sofar; 21333055Sdanmcd 21343055Sdanmcd for (i = 0; i < eprop->sadb_x_prop_numecombs; ) { 21354867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21364064Smarkfen "%s Extended combination #%u:\n"), prefix, ++i); 21373055Sdanmcd 21384867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s HARD: "), 21394867Spwernau prefix); 21404867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "), 21413055Sdanmcd ecomb->sadb_x_ecomb_hard_allocations); 21427320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "bytes=%" PRIu64 21437320Sdanmcd@sun.com ", "), ecomb->sadb_x_ecomb_hard_bytes); 21447320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-add secs=%" 21457320Sdanmcd@sun.com PRIu64 ", "), ecomb->sadb_x_ecomb_hard_addtime); 21467320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%" 21477320Sdanmcd@sun.com PRIu64 "\n"), ecomb->sadb_x_ecomb_hard_usetime); 21483055Sdanmcd 21494867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%s SOFT: "), 21504867Spwernau prefix); 21514867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "alloc=%u, "), 21523055Sdanmcd ecomb->sadb_x_ecomb_soft_allocations); 21537320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, 21547320Sdanmcd@sun.com "bytes=%" PRIu64 ", "), ecomb->sadb_x_ecomb_soft_bytes); 21554867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21567320Sdanmcd@sun.com "post-add secs=%" PRIu64 ", "), 21573055Sdanmcd ecomb->sadb_x_ecomb_soft_addtime); 21587320Sdanmcd@sun.com (void) fprintf(file, dgettext(TEXT_DOMAIN, "post-use secs=%" 21597320Sdanmcd@sun.com PRIu64 "\n"), ecomb->sadb_x_ecomb_soft_usetime); 21603055Sdanmcd 21613055Sdanmcd sofar = (uint64_t *)(ecomb + 1); 21623055Sdanmcd algdesc = (struct sadb_x_algdesc *)sofar; 21633055Sdanmcd 21643055Sdanmcd for (j = 0; j < ecomb->sadb_x_ecomb_numalgs; ) { 21654867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21664064Smarkfen "%s Alg #%u "), prefix, ++j); 21673055Sdanmcd switch (algdesc->sadb_x_algdesc_satype) { 21683055Sdanmcd case SADB_SATYPE_ESP: 21694867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21704064Smarkfen "for ESP ")); 21713055Sdanmcd break; 21723055Sdanmcd case SADB_SATYPE_AH: 21734867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21744867Spwernau "for AH ")); 21753055Sdanmcd break; 21763055Sdanmcd default: 21774867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21784064Smarkfen "for satype=%d "), 21793055Sdanmcd algdesc->sadb_x_algdesc_satype); 21803055Sdanmcd } 21813055Sdanmcd switch (algdesc->sadb_x_algdesc_algtype) { 21823055Sdanmcd case SADB_X_ALGTYPE_CRYPT: 21834867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21844064Smarkfen "Encryption = ")); 21853055Sdanmcd (void) dump_ealg(algdesc->sadb_x_algdesc_alg, 21864867Spwernau file); 21873055Sdanmcd break; 21883055Sdanmcd case SADB_X_ALGTYPE_AUTH: 21894867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21904064Smarkfen "Authentication = ")); 21913055Sdanmcd (void) dump_aalg(algdesc->sadb_x_algdesc_alg, 21924867Spwernau file); 21933055Sdanmcd break; 21943055Sdanmcd default: 21954867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 21964064Smarkfen "algtype(%d) = alg(%d)"), 21973055Sdanmcd algdesc->sadb_x_algdesc_algtype, 21983055Sdanmcd algdesc->sadb_x_algdesc_alg); 21993055Sdanmcd break; 22003055Sdanmcd } 22013055Sdanmcd 22024867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 22034064Smarkfen " minbits=%u, maxbits=%u.\n"), 22043055Sdanmcd algdesc->sadb_x_algdesc_minbits, 22053055Sdanmcd algdesc->sadb_x_algdesc_maxbits); 22063055Sdanmcd 22073055Sdanmcd sofar = (uint64_t *)(++algdesc); 22083055Sdanmcd } 22093055Sdanmcd ecomb = (struct sadb_x_ecomb *)sofar; 22103055Sdanmcd } 22113055Sdanmcd } 22123055Sdanmcd 22133055Sdanmcd /* 22143055Sdanmcd * Print an SADB_EXT_SUPPORTED extension. 22153055Sdanmcd */ 22163055Sdanmcd void 22174867Spwernau print_supp(FILE *file, char *prefix, struct sadb_supported *supp) 22183055Sdanmcd { 22193055Sdanmcd struct sadb_alg *algs; 22203055Sdanmcd int i, numalgs; 22213055Sdanmcd 22224867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sSupported "), prefix); 22233055Sdanmcd switch (supp->sadb_supported_exttype) { 22243055Sdanmcd case SADB_EXT_SUPPORTED_AUTH: 22254867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "authentication")); 22263055Sdanmcd break; 22273055Sdanmcd case SADB_EXT_SUPPORTED_ENCRYPT: 22284867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "encryption")); 22293055Sdanmcd break; 22303055Sdanmcd } 22314867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, " algorithms.\n")); 22323055Sdanmcd 22333055Sdanmcd algs = (struct sadb_alg *)(supp + 1); 22343055Sdanmcd numalgs = supp->sadb_supported_len - SADB_8TO64(sizeof (*supp)); 22353055Sdanmcd numalgs /= SADB_8TO64(sizeof (*algs)); 22363055Sdanmcd for (i = 0; i < numalgs; i++) { 22375906Svk199839 uint16_t exttype = supp->sadb_supported_exttype; 22385906Svk199839 22394867Spwernau (void) fprintf(file, "%s", prefix); 22405906Svk199839 switch (exttype) { 22413055Sdanmcd case SADB_EXT_SUPPORTED_AUTH: 22424867Spwernau (void) dump_aalg(algs[i].sadb_alg_id, file); 22433055Sdanmcd break; 22443055Sdanmcd case SADB_EXT_SUPPORTED_ENCRYPT: 22454867Spwernau (void) dump_ealg(algs[i].sadb_alg_id, file); 22463055Sdanmcd break; 22473055Sdanmcd } 22484867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 22495906Svk199839 " minbits=%u, maxbits=%u, ivlen=%u"), 22503055Sdanmcd algs[i].sadb_alg_minbits, algs[i].sadb_alg_maxbits, 22513055Sdanmcd algs[i].sadb_alg_ivlen); 22525906Svk199839 if (exttype == SADB_EXT_SUPPORTED_ENCRYPT) 22535906Svk199839 (void) fprintf(file, dgettext(TEXT_DOMAIN, 22545906Svk199839 ", increment=%u"), algs[i].sadb_x_alg_increment); 22555906Svk199839 (void) fprintf(file, dgettext(TEXT_DOMAIN, ".\n")); 22563055Sdanmcd } 22573055Sdanmcd } 22583055Sdanmcd 22593055Sdanmcd /* 22603055Sdanmcd * Print an SADB_EXT_SPIRANGE extension. 22613055Sdanmcd */ 22623055Sdanmcd void 22634867Spwernau print_spirange(FILE *file, char *prefix, struct sadb_spirange *range) 22643055Sdanmcd { 22654867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 22664064Smarkfen "%sSPI Range, min=0x%x, max=0x%x\n"), prefix, 22673055Sdanmcd htonl(range->sadb_spirange_min), 22683055Sdanmcd htonl(range->sadb_spirange_max)); 22693055Sdanmcd } 22703055Sdanmcd 22713055Sdanmcd /* 22723055Sdanmcd * Print an SADB_X_EXT_KM_COOKIE extension. 22733055Sdanmcd */ 22743055Sdanmcd 22753055Sdanmcd void 22764867Spwernau print_kmc(FILE *file, char *prefix, struct sadb_x_kmc *kmc) 22773055Sdanmcd { 22783055Sdanmcd char *cookie_label; 22793055Sdanmcd 22803055Sdanmcd if ((cookie_label = kmc_lookup_by_cookie(kmc->sadb_x_kmc_cookie)) == 22813055Sdanmcd NULL) 22824064Smarkfen cookie_label = dgettext(TEXT_DOMAIN, "<Label not found.>"); 22833055Sdanmcd 22844867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 22854064Smarkfen "%sProtocol %u, cookie=\"%s\" (%u)\n"), prefix, 22863055Sdanmcd kmc->sadb_x_kmc_proto, cookie_label, kmc->sadb_x_kmc_cookie); 22873055Sdanmcd } 22887749SThejaswini.Singarajipura@Sun.COM 22897749SThejaswini.Singarajipura@Sun.COM /* 22907749SThejaswini.Singarajipura@Sun.COM * Print an SADB_X_EXT_REPLAY_CTR extension. 22917749SThejaswini.Singarajipura@Sun.COM */ 22927749SThejaswini.Singarajipura@Sun.COM 22937749SThejaswini.Singarajipura@Sun.COM void 22947749SThejaswini.Singarajipura@Sun.COM print_replay(FILE *file, char *prefix, sadb_x_replay_ctr_t *repl) 22957749SThejaswini.Singarajipura@Sun.COM { 22967749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 22977749SThejaswini.Singarajipura@Sun.COM "%sReplay Value "), prefix); 22987749SThejaswini.Singarajipura@Sun.COM if ((repl->sadb_x_rc_replay32 == 0) && 22997749SThejaswini.Singarajipura@Sun.COM (repl->sadb_x_rc_replay64 == 0)) { 23007749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, dgettext(TEXT_DOMAIN, 23017749SThejaswini.Singarajipura@Sun.COM "<Value not found.>")); 23027749SThejaswini.Singarajipura@Sun.COM } 23037749SThejaswini.Singarajipura@Sun.COM /* 23047749SThejaswini.Singarajipura@Sun.COM * We currently do not support a 64-bit replay value. 23057749SThejaswini.Singarajipura@Sun.COM * RFC 4301 will require one, however, and we have a field 23067749SThejaswini.Singarajipura@Sun.COM * in place when 4301 is built. 23077749SThejaswini.Singarajipura@Sun.COM */ 23087749SThejaswini.Singarajipura@Sun.COM (void) fprintf(file, "% " PRIu64 "\n", 23097749SThejaswini.Singarajipura@Sun.COM ((repl->sadb_x_rc_replay32 == 0) ? 23107749SThejaswini.Singarajipura@Sun.COM repl->sadb_x_rc_replay64 : repl->sadb_x_rc_replay32)); 23117749SThejaswini.Singarajipura@Sun.COM } 23126668Smarkfen /* 23136668Smarkfen * Print an SADB_X_EXT_PAIR extension. 23146668Smarkfen */ 23156668Smarkfen static void 23166668Smarkfen print_pair(FILE *file, char *prefix, struct sadb_x_pair *pair) 23176668Smarkfen { 23186668Smarkfen (void) fprintf(file, dgettext(TEXT_DOMAIN, "%sPaired with spi=0x%x\n"), 23196668Smarkfen prefix, ntohl(pair->sadb_x_pair_spi)); 23206668Smarkfen } 23213055Sdanmcd 23223055Sdanmcd /* 23233055Sdanmcd * Take a PF_KEY message pointed to buffer and print it. Useful for DUMP 23243055Sdanmcd * and GET. 23253055Sdanmcd */ 23263055Sdanmcd void 23274867Spwernau print_samsg(FILE *file, uint64_t *buffer, boolean_t want_timestamp, 23284867Spwernau boolean_t vflag, boolean_t ignore_nss) 23293055Sdanmcd { 23303055Sdanmcd uint64_t *current; 23313055Sdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer; 23323055Sdanmcd struct sadb_ext *ext; 23333055Sdanmcd struct sadb_lifetime *currentlt = NULL, *hardlt = NULL, *softlt = NULL; 23347749SThejaswini.Singarajipura@Sun.COM struct sadb_lifetime *idlelt = NULL; 23353055Sdanmcd int i; 23363055Sdanmcd time_t wallclock; 23373055Sdanmcd 23383055Sdanmcd (void) time(&wallclock); 23393055Sdanmcd 23404867Spwernau print_sadb_msg(file, samsg, want_timestamp ? wallclock : 0, vflag); 23413055Sdanmcd current = (uint64_t *)(samsg + 1); 23423055Sdanmcd while (current - buffer < samsg->sadb_msg_len) { 23433055Sdanmcd int lenbytes; 23443055Sdanmcd 23453055Sdanmcd ext = (struct sadb_ext *)current; 23463055Sdanmcd lenbytes = SADB_64TO8(ext->sadb_ext_len); 23473055Sdanmcd switch (ext->sadb_ext_type) { 23483055Sdanmcd case SADB_EXT_SA: 23494867Spwernau print_sa(file, dgettext(TEXT_DOMAIN, 23504064Smarkfen "SA: "), (struct sadb_sa *)current); 23513055Sdanmcd break; 23523055Sdanmcd /* 23533055Sdanmcd * Pluck out lifetimes and print them at the end. This is 23543055Sdanmcd * to show relative lifetimes. 23553055Sdanmcd */ 23563055Sdanmcd case SADB_EXT_LIFETIME_CURRENT: 23573055Sdanmcd currentlt = (struct sadb_lifetime *)current; 23583055Sdanmcd break; 23593055Sdanmcd case SADB_EXT_LIFETIME_HARD: 23603055Sdanmcd hardlt = (struct sadb_lifetime *)current; 23613055Sdanmcd break; 23623055Sdanmcd case SADB_EXT_LIFETIME_SOFT: 23633055Sdanmcd softlt = (struct sadb_lifetime *)current; 23643055Sdanmcd break; 23657749SThejaswini.Singarajipura@Sun.COM case SADB_X_EXT_LIFETIME_IDLE: 23667749SThejaswini.Singarajipura@Sun.COM idlelt = (struct sadb_lifetime *)current; 23677749SThejaswini.Singarajipura@Sun.COM break; 23683055Sdanmcd 23693055Sdanmcd case SADB_EXT_ADDRESS_SRC: 23704867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "SRC: "), 23714867Spwernau (struct sadb_address *)current, ignore_nss); 23723055Sdanmcd break; 23733055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC: 23744867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "INS: "), 23754867Spwernau (struct sadb_address *)current, ignore_nss); 23763055Sdanmcd break; 23773055Sdanmcd case SADB_EXT_ADDRESS_DST: 23784867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "DST: "), 23794867Spwernau (struct sadb_address *)current, ignore_nss); 23803055Sdanmcd break; 23813055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_DST: 23824867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "IND: "), 23834867Spwernau (struct sadb_address *)current, ignore_nss); 23843055Sdanmcd break; 23853055Sdanmcd case SADB_EXT_KEY_AUTH: 23864867Spwernau print_key(file, dgettext(TEXT_DOMAIN, 23874064Smarkfen "AKY: "), (struct sadb_key *)current); 23883055Sdanmcd break; 23893055Sdanmcd case SADB_EXT_KEY_ENCRYPT: 23904867Spwernau print_key(file, dgettext(TEXT_DOMAIN, 23914064Smarkfen "EKY: "), (struct sadb_key *)current); 23923055Sdanmcd break; 23933055Sdanmcd case SADB_EXT_IDENTITY_SRC: 23944867Spwernau print_ident(file, dgettext(TEXT_DOMAIN, "SID: "), 23953055Sdanmcd (struct sadb_ident *)current); 23963055Sdanmcd break; 23973055Sdanmcd case SADB_EXT_IDENTITY_DST: 23984867Spwernau print_ident(file, dgettext(TEXT_DOMAIN, "DID: "), 23993055Sdanmcd (struct sadb_ident *)current); 24003055Sdanmcd break; 24013055Sdanmcd case SADB_EXT_SENSITIVITY: 24024867Spwernau print_sens(file, dgettext(TEXT_DOMAIN, "SNS: "), 24033055Sdanmcd (struct sadb_sens *)current); 24043055Sdanmcd break; 24053055Sdanmcd case SADB_EXT_PROPOSAL: 24064867Spwernau print_prop(file, dgettext(TEXT_DOMAIN, "PRP: "), 24073055Sdanmcd (struct sadb_prop *)current); 24083055Sdanmcd break; 24093055Sdanmcd case SADB_EXT_SUPPORTED_AUTH: 24104867Spwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUA: "), 24113055Sdanmcd (struct sadb_supported *)current); 24123055Sdanmcd break; 24133055Sdanmcd case SADB_EXT_SUPPORTED_ENCRYPT: 24144867Spwernau print_supp(file, dgettext(TEXT_DOMAIN, "SUE: "), 24153055Sdanmcd (struct sadb_supported *)current); 24163055Sdanmcd break; 24173055Sdanmcd case SADB_EXT_SPIRANGE: 24184867Spwernau print_spirange(file, dgettext(TEXT_DOMAIN, "SPR: "), 24193055Sdanmcd (struct sadb_spirange *)current); 24203055Sdanmcd break; 24213055Sdanmcd case SADB_X_EXT_EPROP: 24224867Spwernau print_eprop(file, dgettext(TEXT_DOMAIN, "EPR: "), 24233055Sdanmcd (struct sadb_prop *)current); 24243055Sdanmcd break; 24253055Sdanmcd case SADB_X_EXT_KM_COOKIE: 24264867Spwernau print_kmc(file, dgettext(TEXT_DOMAIN, "KMC: "), 24273055Sdanmcd (struct sadb_x_kmc *)current); 24283055Sdanmcd break; 24293055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_REM: 24304867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "NRM: "), 24314867Spwernau (struct sadb_address *)current, ignore_nss); 24323055Sdanmcd break; 24333055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC: 24344867Spwernau print_address(file, dgettext(TEXT_DOMAIN, "NLC: "), 24354867Spwernau (struct sadb_address *)current, ignore_nss); 24363055Sdanmcd break; 24376668Smarkfen case SADB_X_EXT_PAIR: 24386668Smarkfen print_pair(file, dgettext(TEXT_DOMAIN, "OTH: "), 24396668Smarkfen (struct sadb_x_pair *)current); 24406668Smarkfen break; 24417749SThejaswini.Singarajipura@Sun.COM case SADB_X_EXT_REPLAY_VALUE: 24427749SThejaswini.Singarajipura@Sun.COM (void) print_replay(file, dgettext(TEXT_DOMAIN, 24437749SThejaswini.Singarajipura@Sun.COM "RPL: "), (sadb_x_replay_ctr_t *)current); 24447749SThejaswini.Singarajipura@Sun.COM break; 24453055Sdanmcd default: 24464867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 24473055Sdanmcd "UNK: Unknown ext. %d, len %d.\n"), 24483055Sdanmcd ext->sadb_ext_type, lenbytes); 24493055Sdanmcd for (i = 0; i < ext->sadb_ext_len; i++) 24504867Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 24517320Sdanmcd@sun.com "UNK: 0x%" PRIx64 "\n"), 24527320Sdanmcd@sun.com ((uint64_t *)ext)[i]); 24533055Sdanmcd break; 24543055Sdanmcd } 24553055Sdanmcd current += (lenbytes == 0) ? 24563055Sdanmcd SADB_8TO64(sizeof (struct sadb_ext)) : ext->sadb_ext_len; 24573055Sdanmcd } 24583055Sdanmcd /* 24593055Sdanmcd * Print lifetimes NOW. 24603055Sdanmcd */ 24617749SThejaswini.Singarajipura@Sun.COM if (currentlt != NULL || hardlt != NULL || softlt != NULL || 24627749SThejaswini.Singarajipura@Sun.COM idlelt != NULL) 24637749SThejaswini.Singarajipura@Sun.COM print_lifetimes(file, wallclock, currentlt, hardlt, 24647749SThejaswini.Singarajipura@Sun.COM softlt, idlelt, vflag); 24653055Sdanmcd 24663055Sdanmcd if (current - buffer != samsg->sadb_msg_len) { 24674867Spwernau warnxfp(EFD(file), dgettext(TEXT_DOMAIN, 24684867Spwernau "WARNING: insufficient buffer space or corrupt message.")); 24693055Sdanmcd } 24703055Sdanmcd 24714867Spwernau (void) fflush(file); /* Make sure our message is out there. */ 24723055Sdanmcd } 24733055Sdanmcd 24743055Sdanmcd /* 24753055Sdanmcd * save_XXX functions are used when "saving" the SA tables to either a 24763055Sdanmcd * file or standard output. They use the dump_XXX functions where needed, 24773055Sdanmcd * but mostly they use the rparseXXX functions. 24783055Sdanmcd */ 24793055Sdanmcd 24803055Sdanmcd /* 24813055Sdanmcd * Print save information for a lifetime extension. 24823055Sdanmcd * 24833055Sdanmcd * NOTE : It saves the lifetime in absolute terms. For example, if you 24843055Sdanmcd * had a hard_usetime of 60 seconds, you'll save it as 60 seconds, even though 24853055Sdanmcd * there may have been 59 seconds burned off the clock. 24863055Sdanmcd */ 24873055Sdanmcd boolean_t 24883055Sdanmcd save_lifetime(struct sadb_lifetime *lifetime, FILE *ofile) 24893055Sdanmcd { 24903055Sdanmcd char *prefix; 24913055Sdanmcd 24927749SThejaswini.Singarajipura@Sun.COM switch (lifetime->sadb_lifetime_exttype) { 24937749SThejaswini.Singarajipura@Sun.COM case SADB_EXT_LIFETIME_HARD: 24947749SThejaswini.Singarajipura@Sun.COM prefix = "hard"; 24957749SThejaswini.Singarajipura@Sun.COM break; 24967749SThejaswini.Singarajipura@Sun.COM case SADB_EXT_LIFETIME_SOFT: 24977749SThejaswini.Singarajipura@Sun.COM prefix = "soft"; 24987749SThejaswini.Singarajipura@Sun.COM break; 24997749SThejaswini.Singarajipura@Sun.COM case SADB_X_EXT_LIFETIME_IDLE: 25007749SThejaswini.Singarajipura@Sun.COM prefix = "idle"; 25017749SThejaswini.Singarajipura@Sun.COM break; 25027749SThejaswini.Singarajipura@Sun.COM } 25033055Sdanmcd 25043055Sdanmcd if (putc('\t', ofile) == EOF) 25053055Sdanmcd return (B_FALSE); 25063055Sdanmcd 25073055Sdanmcd if (lifetime->sadb_lifetime_allocations != 0 && fprintf(ofile, 25083055Sdanmcd "%s_alloc %u ", prefix, lifetime->sadb_lifetime_allocations) < 0) 25093055Sdanmcd return (B_FALSE); 25103055Sdanmcd 25113055Sdanmcd if (lifetime->sadb_lifetime_bytes != 0 && fprintf(ofile, 25127320Sdanmcd@sun.com "%s_bytes %" PRIu64 " ", prefix, lifetime->sadb_lifetime_bytes) < 0) 25133055Sdanmcd return (B_FALSE); 25143055Sdanmcd 25153055Sdanmcd if (lifetime->sadb_lifetime_addtime != 0 && fprintf(ofile, 25167320Sdanmcd@sun.com "%s_addtime %" PRIu64 " ", prefix, 25177320Sdanmcd@sun.com lifetime->sadb_lifetime_addtime) < 0) 25183055Sdanmcd return (B_FALSE); 25193055Sdanmcd 25203055Sdanmcd if (lifetime->sadb_lifetime_usetime != 0 && fprintf(ofile, 25217320Sdanmcd@sun.com "%s_usetime %" PRIu64 " ", prefix, 25227320Sdanmcd@sun.com lifetime->sadb_lifetime_usetime) < 0) 25233055Sdanmcd return (B_FALSE); 25243055Sdanmcd 25253055Sdanmcd return (B_TRUE); 25263055Sdanmcd } 25273055Sdanmcd 25283055Sdanmcd /* 25293055Sdanmcd * Print save information for an address extension. 25303055Sdanmcd */ 25313055Sdanmcd boolean_t 25323055Sdanmcd save_address(struct sadb_address *addr, FILE *ofile) 25333055Sdanmcd { 25343055Sdanmcd char *printable_addr, buf[INET6_ADDRSTRLEN]; 25353055Sdanmcd const char *prefix, *pprefix; 25363055Sdanmcd struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(addr + 1); 25373055Sdanmcd struct sockaddr_in *sin = (struct sockaddr_in *)sin6; 25383055Sdanmcd int af = sin->sin_family; 25393055Sdanmcd 25403055Sdanmcd /* 25413055Sdanmcd * Address-family reality check. 25423055Sdanmcd */ 25433055Sdanmcd if (af != AF_INET6 && af != AF_INET) 25443055Sdanmcd return (B_FALSE); 25453055Sdanmcd 25463055Sdanmcd switch (addr->sadb_address_exttype) { 25473055Sdanmcd case SADB_EXT_ADDRESS_SRC: 25483055Sdanmcd prefix = "src"; 25493055Sdanmcd pprefix = "sport"; 25503055Sdanmcd break; 25513055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC: 25523055Sdanmcd prefix = "isrc"; 25533055Sdanmcd pprefix = "isport"; 25543055Sdanmcd break; 25553055Sdanmcd case SADB_EXT_ADDRESS_DST: 25563055Sdanmcd prefix = "dst"; 25573055Sdanmcd pprefix = "dport"; 25583055Sdanmcd break; 25593055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_DST: 25603055Sdanmcd prefix = "idst"; 25613055Sdanmcd pprefix = "idport"; 25623055Sdanmcd break; 25633055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC: 25643055Sdanmcd prefix = "nat_loc "; 25653055Sdanmcd pprefix = "nat_lport"; 25663055Sdanmcd break; 25673055Sdanmcd case SADB_X_EXT_ADDRESS_NATT_REM: 25683055Sdanmcd prefix = "nat_rem "; 25693055Sdanmcd pprefix = "nat_rport"; 25703055Sdanmcd break; 25713055Sdanmcd } 25723055Sdanmcd 25733055Sdanmcd if (fprintf(ofile, " %s ", prefix) < 0) 25743055Sdanmcd return (B_FALSE); 25753055Sdanmcd 25763055Sdanmcd /* 25773055Sdanmcd * Do not do address-to-name translation, given that we live in 25783055Sdanmcd * an age of names that explode into many addresses. 25793055Sdanmcd */ 25803055Sdanmcd printable_addr = (char *)inet_ntop(af, 25813055Sdanmcd (af == AF_INET) ? (char *)&sin->sin_addr : (char *)&sin6->sin6_addr, 25823055Sdanmcd buf, sizeof (buf)); 25833055Sdanmcd if (printable_addr == NULL) 25844064Smarkfen printable_addr = "Invalid IP address."; 25853055Sdanmcd if (fprintf(ofile, "%s", printable_addr) < 0) 25863055Sdanmcd return (B_FALSE); 25873055Sdanmcd if (addr->sadb_address_prefixlen != 0 && 25883055Sdanmcd !((addr->sadb_address_prefixlen == 32 && af == AF_INET) || 25894342Spwernau (addr->sadb_address_prefixlen == 128 && af == AF_INET6))) { 25903055Sdanmcd if (fprintf(ofile, "/%d", addr->sadb_address_prefixlen) < 0) 25913055Sdanmcd return (B_FALSE); 25923055Sdanmcd } 25933055Sdanmcd 25943055Sdanmcd /* 25953055Sdanmcd * The port is in the same position for struct sockaddr_in and 25963055Sdanmcd * struct sockaddr_in6. We exploit that property here. 25973055Sdanmcd */ 25983055Sdanmcd if ((pprefix != NULL) && (sin->sin_port != 0)) 25993055Sdanmcd (void) fprintf(ofile, " %s %d", pprefix, ntohs(sin->sin_port)); 26003055Sdanmcd 26013055Sdanmcd return (B_TRUE); 26023055Sdanmcd } 26033055Sdanmcd 26043055Sdanmcd /* 26053055Sdanmcd * Print save information for a key extension. Returns whether writing 26063055Sdanmcd * to the specified output file was successful or not. 26073055Sdanmcd */ 26083055Sdanmcd boolean_t 26093055Sdanmcd save_key(struct sadb_key *key, FILE *ofile) 26103055Sdanmcd { 26113055Sdanmcd char *prefix; 26123055Sdanmcd 26133055Sdanmcd if (putc('\t', ofile) == EOF) 26143055Sdanmcd return (B_FALSE); 26153055Sdanmcd 26163055Sdanmcd prefix = (key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ? "auth" : "encr"; 26173055Sdanmcd 26183055Sdanmcd if (fprintf(ofile, "%skey ", prefix) < 0) 26193055Sdanmcd return (B_FALSE); 26203055Sdanmcd 26213055Sdanmcd if (dump_key((uint8_t *)(key + 1), key->sadb_key_bits, ofile) == -1) 26223055Sdanmcd return (B_FALSE); 26233055Sdanmcd 26243055Sdanmcd return (B_TRUE); 26253055Sdanmcd } 26263055Sdanmcd 26273055Sdanmcd /* 26283055Sdanmcd * Print save information for an identity extension. 26293055Sdanmcd */ 26303055Sdanmcd boolean_t 26313055Sdanmcd save_ident(struct sadb_ident *ident, FILE *ofile) 26323055Sdanmcd { 26333055Sdanmcd char *prefix; 26343055Sdanmcd 26353055Sdanmcd if (putc('\t', ofile) == EOF) 26363055Sdanmcd return (B_FALSE); 26373055Sdanmcd 26383055Sdanmcd prefix = (ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ? "src" : 26393055Sdanmcd "dst"; 26403055Sdanmcd 26413055Sdanmcd if (fprintf(ofile, "%sidtype %s ", prefix, 26423055Sdanmcd rparseidtype(ident->sadb_ident_type)) < 0) 26433055Sdanmcd return (B_FALSE); 26443055Sdanmcd 26453055Sdanmcd if (ident->sadb_ident_type == SADB_X_IDENTTYPE_DN || 26463055Sdanmcd ident->sadb_ident_type == SADB_X_IDENTTYPE_GN) { 26474064Smarkfen if (fprintf(ofile, dgettext(TEXT_DOMAIN, 26484064Smarkfen "<can-not-print>")) < 0) 26493055Sdanmcd return (B_FALSE); 26503055Sdanmcd } else { 26513055Sdanmcd if (fprintf(ofile, "%s", (char *)(ident + 1)) < 0) 26523055Sdanmcd return (B_FALSE); 26533055Sdanmcd } 26543055Sdanmcd 26553055Sdanmcd return (B_TRUE); 26563055Sdanmcd } 26573055Sdanmcd 26583055Sdanmcd /* 26593055Sdanmcd * "Save" a security association to an output file. 26603055Sdanmcd * 26614064Smarkfen * NOTE the lack of calls to dgettext() because I'm outputting parseable stuff. 26623055Sdanmcd * ALSO NOTE that if you change keywords (see parsecmd()), you'll have to 26633055Sdanmcd * change them here as well. 26643055Sdanmcd */ 26653055Sdanmcd void 26663055Sdanmcd save_assoc(uint64_t *buffer, FILE *ofile) 26673055Sdanmcd { 26684064Smarkfen int terrno; 26694987Sdanmcd boolean_t seen_proto = B_FALSE, seen_iproto = B_FALSE; 26703055Sdanmcd uint64_t *current; 26713055Sdanmcd struct sadb_address *addr; 26727749SThejaswini.Singarajipura@Sun.COM struct sadb_x_replay_ctr *repl; 26733055Sdanmcd struct sadb_msg *samsg = (struct sadb_msg *)buffer; 26743055Sdanmcd struct sadb_ext *ext; 26753055Sdanmcd 26764064Smarkfen #define tidyup() \ 26774064Smarkfen terrno = errno; (void) fclose(ofile); errno = terrno; \ 26784064Smarkfen interactive = B_FALSE 26794064Smarkfen 26804064Smarkfen #define savenl() if (fputs(" \\\n", ofile) == EOF) \ 26814064Smarkfen { bail(dgettext(TEXT_DOMAIN, "savenl")); } 26823055Sdanmcd 26833055Sdanmcd if (fputs("# begin assoc\n", ofile) == EOF) 26844064Smarkfen bail(dgettext(TEXT_DOMAIN, 26854064Smarkfen "save_assoc: Opening comment of SA")); 26863055Sdanmcd if (fprintf(ofile, "add %s ", rparsesatype(samsg->sadb_msg_satype)) < 0) 26874064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: First line of SA")); 26883055Sdanmcd savenl(); 26893055Sdanmcd 26903055Sdanmcd current = (uint64_t *)(samsg + 1); 26913055Sdanmcd while (current - buffer < samsg->sadb_msg_len) { 26923055Sdanmcd struct sadb_sa *assoc; 26933055Sdanmcd 26943055Sdanmcd ext = (struct sadb_ext *)current; 26954987Sdanmcd addr = (struct sadb_address *)ext; /* Just in case... */ 26963055Sdanmcd switch (ext->sadb_ext_type) { 26973055Sdanmcd case SADB_EXT_SA: 26983055Sdanmcd assoc = (struct sadb_sa *)ext; 26993055Sdanmcd if (assoc->sadb_sa_state != SADB_SASTATE_MATURE) { 27003055Sdanmcd if (fprintf(ofile, "# WARNING: SA was dying " 27013055Sdanmcd "or dead.\n") < 0) { 27024064Smarkfen tidyup(); 27034064Smarkfen bail(dgettext(TEXT_DOMAIN, 27044064Smarkfen "save_assoc: fprintf not mature")); 27053055Sdanmcd } 27063055Sdanmcd } 27073055Sdanmcd if (fprintf(ofile, " spi 0x%x ", 27084064Smarkfen ntohl(assoc->sadb_sa_spi)) < 0) { 27094064Smarkfen tidyup(); 27104064Smarkfen bail(dgettext(TEXT_DOMAIN, 27114064Smarkfen "save_assoc: fprintf spi")); 27124064Smarkfen } 27133055Sdanmcd if (assoc->sadb_sa_encrypt != SADB_EALG_NONE) { 27143055Sdanmcd if (fprintf(ofile, "encr_alg %s ", 27153055Sdanmcd rparsealg(assoc->sadb_sa_encrypt, 27164342Spwernau IPSEC_PROTO_ESP)) < 0) { 27174064Smarkfen tidyup(); 27184064Smarkfen bail(dgettext(TEXT_DOMAIN, 27194064Smarkfen "save_assoc: fprintf encrypt")); 27204064Smarkfen } 27213055Sdanmcd } 27223055Sdanmcd if (assoc->sadb_sa_auth != SADB_AALG_NONE) { 27233055Sdanmcd if (fprintf(ofile, "auth_alg %s ", 27243055Sdanmcd rparsealg(assoc->sadb_sa_auth, 27254342Spwernau IPSEC_PROTO_AH)) < 0) { 27264064Smarkfen tidyup(); 27274064Smarkfen bail(dgettext(TEXT_DOMAIN, 27284064Smarkfen "save_assoc: fprintf auth")); 27294064Smarkfen } 27303055Sdanmcd } 27313055Sdanmcd if (fprintf(ofile, "replay %d ", 27324064Smarkfen assoc->sadb_sa_replay) < 0) { 27334064Smarkfen tidyup(); 27344064Smarkfen bail(dgettext(TEXT_DOMAIN, 27354064Smarkfen "save_assoc: fprintf replay")); 27364064Smarkfen } 27373055Sdanmcd if (assoc->sadb_sa_flags & (SADB_X_SAFLAGS_NATT_LOC | 27383055Sdanmcd SADB_X_SAFLAGS_NATT_REM)) { 27394064Smarkfen if (fprintf(ofile, "encap udp") < 0) { 27404064Smarkfen tidyup(); 27414064Smarkfen bail(dgettext(TEXT_DOMAIN, 27424064Smarkfen "save_assoc: fprintf encap")); 27434064Smarkfen } 27443055Sdanmcd } 27453055Sdanmcd savenl(); 27463055Sdanmcd break; 27473055Sdanmcd case SADB_EXT_LIFETIME_HARD: 27483055Sdanmcd case SADB_EXT_LIFETIME_SOFT: 27497749SThejaswini.Singarajipura@Sun.COM case SADB_X_EXT_LIFETIME_IDLE: 27504064Smarkfen if (!save_lifetime((struct sadb_lifetime *)ext, 27514064Smarkfen ofile)) { 27524064Smarkfen tidyup(); 27534064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_lifetime")); 27544064Smarkfen } 27553055Sdanmcd savenl(); 27563055Sdanmcd break; 27573055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_SRC: 27583055Sdanmcd case SADB_X_EXT_ADDRESS_INNER_DST: 27594987Sdanmcd if (!seen_iproto && addr->sadb_address_proto) { 27604987Sdanmcd (void) fprintf(ofile, " iproto %d", 27614987Sdanmcd addr->sadb_address_proto); 27624987Sdanmcd savenl(); 27634987Sdanmcd seen_iproto = B_TRUE; 27644987Sdanmcd } 27654987Sdanmcd goto skip_srcdst; /* Hack to avoid cases below... */ 27664987Sdanmcd /* FALLTHRU */ 27674987Sdanmcd case SADB_EXT_ADDRESS_SRC: 27684987Sdanmcd case SADB_EXT_ADDRESS_DST: 27693055Sdanmcd if (!seen_proto && addr->sadb_address_proto) { 27703055Sdanmcd (void) fprintf(ofile, " proto %d", 27713055Sdanmcd addr->sadb_address_proto); 27723055Sdanmcd savenl(); 27734987Sdanmcd seen_proto = B_TRUE; 27743055Sdanmcd } 27754987Sdanmcd /* FALLTHRU */ 27764987Sdanmcd case SADB_X_EXT_ADDRESS_NATT_REM: 27774987Sdanmcd case SADB_X_EXT_ADDRESS_NATT_LOC: 27784987Sdanmcd skip_srcdst: 27794064Smarkfen if (!save_address(addr, ofile)) { 27804064Smarkfen tidyup(); 27814064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address")); 27824064Smarkfen } 27833055Sdanmcd savenl(); 27843055Sdanmcd break; 27853055Sdanmcd case SADB_EXT_KEY_AUTH: 27863055Sdanmcd case SADB_EXT_KEY_ENCRYPT: 27874064Smarkfen if (!save_key((struct sadb_key *)ext, ofile)) { 27884064Smarkfen tidyup(); 27894064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address")); 27904064Smarkfen } 27913055Sdanmcd savenl(); 27923055Sdanmcd break; 27933055Sdanmcd case SADB_EXT_IDENTITY_SRC: 27943055Sdanmcd case SADB_EXT_IDENTITY_DST: 27954064Smarkfen if (!save_ident((struct sadb_ident *)ext, ofile)) { 27964064Smarkfen tidyup(); 27974064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_address")); 27984064Smarkfen } 27993055Sdanmcd savenl(); 28003055Sdanmcd break; 28017749SThejaswini.Singarajipura@Sun.COM case SADB_X_EXT_REPLAY_VALUE: 28027749SThejaswini.Singarajipura@Sun.COM repl = (sadb_x_replay_ctr_t *)ext; 28037749SThejaswini.Singarajipura@Sun.COM if ((repl->sadb_x_rc_replay32 == 0) && 28047749SThejaswini.Singarajipura@Sun.COM (repl->sadb_x_rc_replay64 == 0)) { 28057749SThejaswini.Singarajipura@Sun.COM tidyup(); 28067749SThejaswini.Singarajipura@Sun.COM bail(dgettext(TEXT_DOMAIN, "Replay Value")); 28077749SThejaswini.Singarajipura@Sun.COM } 28087749SThejaswini.Singarajipura@Sun.COM if (fprintf(ofile, "replay_value %" PRIu64 "", 28097749SThejaswini.Singarajipura@Sun.COM (repl->sadb_x_rc_replay32 == 0 ? 28107749SThejaswini.Singarajipura@Sun.COM repl->sadb_x_rc_replay64 : 28117749SThejaswini.Singarajipura@Sun.COM repl->sadb_x_rc_replay32)) < 0) { 28127749SThejaswini.Singarajipura@Sun.COM tidyup(); 28137749SThejaswini.Singarajipura@Sun.COM bail(dgettext(TEXT_DOMAIN, 28147749SThejaswini.Singarajipura@Sun.COM "save_assoc: fprintf replay value")); 28157749SThejaswini.Singarajipura@Sun.COM } 28167749SThejaswini.Singarajipura@Sun.COM savenl(); 28177749SThejaswini.Singarajipura@Sun.COM break; 28183055Sdanmcd case SADB_EXT_SENSITIVITY: 28193055Sdanmcd default: 28203055Sdanmcd /* Skip over irrelevant extensions. */ 28213055Sdanmcd break; 28223055Sdanmcd } 28233055Sdanmcd current += ext->sadb_ext_len; 28243055Sdanmcd } 28253055Sdanmcd 28264064Smarkfen if (fputs(dgettext(TEXT_DOMAIN, "\n# end assoc\n\n"), ofile) == EOF) { 28274064Smarkfen tidyup(); 28284064Smarkfen bail(dgettext(TEXT_DOMAIN, "save_assoc: last fputs")); 28294064Smarkfen } 28303055Sdanmcd } 28313055Sdanmcd 28323055Sdanmcd /* 28333055Sdanmcd * Open the output file for the "save" command. 28343055Sdanmcd */ 28353055Sdanmcd FILE * 28363055Sdanmcd opensavefile(char *filename) 28373055Sdanmcd { 28383055Sdanmcd int fd; 28393055Sdanmcd FILE *retval; 28403055Sdanmcd struct stat buf; 28413055Sdanmcd 28423055Sdanmcd /* 28433055Sdanmcd * If the user specifies "-" or doesn't give a filename, then 28443055Sdanmcd * dump to stdout. Make sure to document the dangers of files 28453055Sdanmcd * that are NFS, directing your output to strange places, etc. 28463055Sdanmcd */ 28473055Sdanmcd if (filename == NULL || strcmp("-", filename) == 0) 28483055Sdanmcd return (stdout); 28493055Sdanmcd 28503055Sdanmcd /* 28513055Sdanmcd * open the file with the create bits set. Since I check for 28523055Sdanmcd * real UID == root in main(), I won't worry about the ownership 28533055Sdanmcd * problem. 28543055Sdanmcd */ 28553055Sdanmcd fd = open(filename, O_WRONLY | O_EXCL | O_CREAT | O_TRUNC, S_IRUSR); 28563055Sdanmcd if (fd == -1) { 28573055Sdanmcd if (errno != EEXIST) 28584064Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN, 28594064Smarkfen "open error"), 28603055Sdanmcd strerror(errno)); 28613055Sdanmcd fd = open(filename, O_WRONLY | O_TRUNC, 0); 28623055Sdanmcd if (fd == -1) 28634064Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN, 28644064Smarkfen "open error"), strerror(errno)); 28653055Sdanmcd if (fstat(fd, &buf) == -1) { 28663055Sdanmcd (void) close(fd); 28673055Sdanmcd bail_msg("%s fstat: %s", filename, strerror(errno)); 28683055Sdanmcd } 28693055Sdanmcd if (S_ISREG(buf.st_mode) && 28703055Sdanmcd ((buf.st_mode & S_IAMB) != S_IRUSR)) { 28714064Smarkfen warnx(dgettext(TEXT_DOMAIN, 28724064Smarkfen "WARNING: Save file already exists with " 28734064Smarkfen "permission %o."), buf.st_mode & S_IAMB); 28744064Smarkfen warnx(dgettext(TEXT_DOMAIN, 28754064Smarkfen "Normal users may be able to read IPsec " 28764064Smarkfen "keying material.")); 28773055Sdanmcd } 28783055Sdanmcd } 28793055Sdanmcd 28803055Sdanmcd /* Okay, we have an FD. Assign it to a stdio FILE pointer. */ 28813055Sdanmcd retval = fdopen(fd, "w"); 28823055Sdanmcd if (retval == NULL) { 28833055Sdanmcd (void) close(fd); 28844064Smarkfen bail_msg("%s %s: %s", filename, dgettext(TEXT_DOMAIN, 28854064Smarkfen "fdopen error"), strerror(errno)); 28863055Sdanmcd } 28873055Sdanmcd return (retval); 28883055Sdanmcd } 28893055Sdanmcd 28903055Sdanmcd const char * 28913055Sdanmcd do_inet_ntop(const void *addr, char *cp, size_t size) 28923055Sdanmcd { 28933055Sdanmcd boolean_t isv4; 28943055Sdanmcd struct in6_addr *inaddr6 = (struct in6_addr *)addr; 28953055Sdanmcd struct in_addr inaddr; 28963055Sdanmcd 28973055Sdanmcd if ((isv4 = IN6_IS_ADDR_V4MAPPED(inaddr6)) == B_TRUE) { 28983055Sdanmcd IN6_V4MAPPED_TO_INADDR(inaddr6, &inaddr); 28993055Sdanmcd } 29003055Sdanmcd 29013055Sdanmcd return (inet_ntop(isv4 ? AF_INET : AF_INET6, 29023055Sdanmcd isv4 ? (void *)&inaddr : inaddr6, cp, size)); 29033055Sdanmcd } 29043055Sdanmcd 29053055Sdanmcd char numprint[NBUF_SIZE]; 29063055Sdanmcd 29073055Sdanmcd /* 29083055Sdanmcd * Parse and reverse parse a specific SA type (AH, ESP, etc.). 29093055Sdanmcd */ 29103055Sdanmcd static struct typetable { 29113055Sdanmcd char *type; 29123055Sdanmcd int token; 29133055Sdanmcd } type_table[] = { 29143055Sdanmcd {"all", SADB_SATYPE_UNSPEC}, 29153055Sdanmcd {"ah", SADB_SATYPE_AH}, 29163055Sdanmcd {"esp", SADB_SATYPE_ESP}, 29173055Sdanmcd /* PF_KEY NOTE: More to come if net/pfkeyv2.h gets updated. */ 29183055Sdanmcd {NULL, 0} /* Token value is irrelevant for this entry. */ 29193055Sdanmcd }; 29203055Sdanmcd 29213055Sdanmcd char * 29223055Sdanmcd rparsesatype(int type) 29233055Sdanmcd { 29243055Sdanmcd struct typetable *tt = type_table; 29253055Sdanmcd 29263055Sdanmcd while (tt->type != NULL && type != tt->token) 29273055Sdanmcd tt++; 29283055Sdanmcd 29293055Sdanmcd if (tt->type == NULL) { 29303055Sdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type); 29313055Sdanmcd } else { 29323055Sdanmcd return (tt->type); 29333055Sdanmcd } 29343055Sdanmcd 29353055Sdanmcd return (numprint); 29363055Sdanmcd } 29373055Sdanmcd 29383055Sdanmcd 29393055Sdanmcd /* 29403055Sdanmcd * Return a string containing the name of the specified numerical algorithm 29413055Sdanmcd * identifier. 29423055Sdanmcd */ 29433055Sdanmcd char * 29443055Sdanmcd rparsealg(uint8_t alg, int proto_num) 29453055Sdanmcd { 29463055Sdanmcd static struct ipsecalgent *holder = NULL; /* we're single-threaded */ 29473055Sdanmcd 29483055Sdanmcd if (holder != NULL) 29493055Sdanmcd freeipsecalgent(holder); 29503055Sdanmcd 29513055Sdanmcd holder = getipsecalgbynum(alg, proto_num, NULL); 29523055Sdanmcd if (holder == NULL) { 29533055Sdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", alg); 29543055Sdanmcd return (numprint); 29553055Sdanmcd } 29563055Sdanmcd 29573055Sdanmcd return (*(holder->a_names)); 29583055Sdanmcd } 29593055Sdanmcd 29603055Sdanmcd /* 29613055Sdanmcd * Parse and reverse parse out a source/destination ID type. 29623055Sdanmcd */ 29633055Sdanmcd static struct idtypes { 29643055Sdanmcd char *idtype; 29653055Sdanmcd uint8_t retval; 29663055Sdanmcd } idtypes[] = { 29673055Sdanmcd {"prefix", SADB_IDENTTYPE_PREFIX}, 29683055Sdanmcd {"fqdn", SADB_IDENTTYPE_FQDN}, 29693055Sdanmcd {"domain", SADB_IDENTTYPE_FQDN}, 29703055Sdanmcd {"domainname", SADB_IDENTTYPE_FQDN}, 29713055Sdanmcd {"user_fqdn", SADB_IDENTTYPE_USER_FQDN}, 29723055Sdanmcd {"mailbox", SADB_IDENTTYPE_USER_FQDN}, 29733055Sdanmcd {"der_dn", SADB_X_IDENTTYPE_DN}, 29743055Sdanmcd {"der_gn", SADB_X_IDENTTYPE_GN}, 29753055Sdanmcd {NULL, 0} 29763055Sdanmcd }; 29773055Sdanmcd 29783055Sdanmcd char * 29793055Sdanmcd rparseidtype(uint16_t type) 29803055Sdanmcd { 29813055Sdanmcd struct idtypes *idp; 29823055Sdanmcd 29833055Sdanmcd for (idp = idtypes; idp->idtype != NULL; idp++) { 29843055Sdanmcd if (type == idp->retval) 29853055Sdanmcd return (idp->idtype); 29863055Sdanmcd } 29873055Sdanmcd 29883055Sdanmcd (void) snprintf(numprint, NBUF_SIZE, "%d", type); 29893055Sdanmcd return (numprint); 29903055Sdanmcd } 29914235Smarkfen 29924235Smarkfen /* 29934235Smarkfen * This is a general purpose exit function, calling functions can specify an 29944235Smarkfen * error type. If the command calling this function was started by smf(5) the 29954235Smarkfen * error type could be used as a hint to the restarter. In the future this 29964235Smarkfen * function could be used to do something more intelligent with a process that 2997*10019SMark.Fenwick@Sun.COM * encounters an error. If exit() is called with an error code other than those 2998*10019SMark.Fenwick@Sun.COM * defined by smf(5), the program will just get restarted. Unless restarting 2999*10019SMark.Fenwick@Sun.COM * is likely to resolve the error condition, its probably sensible to just 3000*10019SMark.Fenwick@Sun.COM * log the error and keep running. 3001*10019SMark.Fenwick@Sun.COM * 3002*10019SMark.Fenwick@Sun.COM * The SERVICE_* exit_types mean nothing if the command was run from the 3003*10019SMark.Fenwick@Sun.COM * command line, just exit(). There are two special cases: 3004*10019SMark.Fenwick@Sun.COM * 3005*10019SMark.Fenwick@Sun.COM * SERVICE_DEGRADE - Not implemented in smf(5), one day it could hint that 3006*10019SMark.Fenwick@Sun.COM * the service is not running as well is it could. For 3007*10019SMark.Fenwick@Sun.COM * now, don't do anything, just record the error. 3008*10019SMark.Fenwick@Sun.COM * DEBUG_FATAL - Something happened, if the command was being run in debug 3009*10019SMark.Fenwick@Sun.COM * mode, exit() as you really want to know something happened, 3010*10019SMark.Fenwick@Sun.COM * otherwise just keep running. This is ignored when running 3011*10019SMark.Fenwick@Sun.COM * under smf(5). 30124235Smarkfen * 30134235Smarkfen * The function will handle an optional variable args error message, this 30144235Smarkfen * will be written to the error stream, typically a log file or stderr. 30154235Smarkfen */ 30164235Smarkfen void 30174235Smarkfen ipsecutil_exit(exit_type_t type, char *fmri, FILE *fp, const char *fmt, ...) 30184235Smarkfen { 30194235Smarkfen int exit_status; 30204235Smarkfen va_list args; 30214235Smarkfen 30224235Smarkfen if (fp == NULL) 30234235Smarkfen fp = stderr; 30244235Smarkfen if (fmt != NULL) { 30254235Smarkfen va_start(args, fmt); 30264235Smarkfen vwarnxfp(fp, fmt, args); 30274235Smarkfen va_end(args); 30284235Smarkfen } 30294235Smarkfen 30304235Smarkfen if (fmri == NULL) { 30314235Smarkfen /* Command being run directly from a shell. */ 30324235Smarkfen switch (type) { 30334235Smarkfen case SERVICE_EXIT_OK: 30344235Smarkfen exit_status = 0; 30354235Smarkfen break; 30364235Smarkfen case SERVICE_DEGRADE: 30374235Smarkfen return; 30384235Smarkfen break; 30394235Smarkfen case SERVICE_BADPERM: 30404235Smarkfen case SERVICE_BADCONF: 30414235Smarkfen case SERVICE_MAINTAIN: 30424235Smarkfen case SERVICE_DISABLE: 30434235Smarkfen case SERVICE_FATAL: 30444235Smarkfen case SERVICE_RESTART: 3045*10019SMark.Fenwick@Sun.COM case DEBUG_FATAL: 30464235Smarkfen warnxfp(fp, "Fatal error - exiting."); 30474235Smarkfen exit_status = 1; 30484235Smarkfen break; 30494235Smarkfen } 30504235Smarkfen } else { 30514235Smarkfen /* Command being run as a smf(5) method. */ 30524235Smarkfen switch (type) { 30534235Smarkfen case SERVICE_EXIT_OK: 30544235Smarkfen exit_status = SMF_EXIT_OK; 30554235Smarkfen break; 3056*10019SMark.Fenwick@Sun.COM case SERVICE_DEGRADE: /* Not implemented yet. */ 3057*10019SMark.Fenwick@Sun.COM case DEBUG_FATAL: 3058*10019SMark.Fenwick@Sun.COM /* Keep running, don't exit(). */ 30594235Smarkfen return; 30604235Smarkfen break; 30614235Smarkfen case SERVICE_BADPERM: 30624235Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN, 30634235Smarkfen "Permission error with %s."), fmri); 30644235Smarkfen exit_status = SMF_EXIT_ERR_PERM; 30654235Smarkfen break; 30664235Smarkfen case SERVICE_BADCONF: 30674235Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN, 30684235Smarkfen "Bad configuration of service %s."), fmri); 30694235Smarkfen exit_status = SMF_EXIT_ERR_FATAL; 30704235Smarkfen break; 30714235Smarkfen case SERVICE_MAINTAIN: 30724235Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN, 30734235Smarkfen "Service %s needs maintenance."), fmri); 30744235Smarkfen exit_status = SMF_EXIT_ERR_FATAL; 30754235Smarkfen break; 30764235Smarkfen case SERVICE_DISABLE: 30774235Smarkfen exit_status = SMF_EXIT_ERR_FATAL; 30784235Smarkfen break; 30794235Smarkfen case SERVICE_FATAL: 30804235Smarkfen warnxfp(fp, dgettext(TEXT_DOMAIN, 30814235Smarkfen "Service %s fatal error."), fmri); 30824235Smarkfen exit_status = SMF_EXIT_ERR_FATAL; 30834235Smarkfen break; 30844235Smarkfen case SERVICE_RESTART: 30854235Smarkfen exit_status = 1; 30864235Smarkfen break; 30874235Smarkfen } 30884235Smarkfen } 30894235Smarkfen (void) fflush(fp); 30904235Smarkfen (void) fclose(fp); 30914235Smarkfen exit(exit_status); 30924235Smarkfen } 3093