2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
36 #include <netkey/key_var.h>
37 #include <netinet/in.h>
38 #include <netinet6/ipsec.h>
40 #include <arpa/inet.h>
46 #include "ipsec_strerror.h"
48 static const char *ipsp_dir_strs[] = {
52 static const char *ipsp_policy_strs[] = {
53 "discard", "none", "ipsec", "entrust", "bypass",
56 static int set_addresses __P((char *buf, caddr_t ptr));
59 * policy is sadb_x_policy buffer.
60 * Must call free() later.
61 * When delimiter == NULL, alternatively ' '(space) is applied.
64 ipsec_dump_policy(policy, delimiter)
68 struct sadb_x_policy *xpl = (struct sadb_x_policy *)policy;
69 struct sadb_x_ipsecrequest *xisr;
77 if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
78 ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
83 if (delimiter == NULL)
86 switch (xpl->sadb_x_policy_dir) {
88 case IPSEC_DIR_INBOUND:
89 case IPSEC_DIR_OUTBOUND:
92 ipsec_errcode = EIPSEC_INVAL_DIR;
96 switch (xpl->sadb_x_policy_type) {
97 case IPSEC_POLICY_DISCARD:
98 case IPSEC_POLICY_NONE:
99 case IPSEC_POLICY_IPSEC:
100 case IPSEC_POLICY_BYPASS:
101 case IPSEC_POLICY_ENTRUST:
104 ipsec_errcode = EIPSEC_INVAL_POLICY;
108 buflen = strlen(ipsp_dir_strs[xpl->sadb_x_policy_dir])
110 + strlen(ipsp_policy_strs[xpl->sadb_x_policy_type])
113 if ((buf = malloc(buflen)) == NULL) {
114 ipsec_errcode = EIPSEC_NO_BUFS;
117 strcpy(buf, ipsp_dir_strs[xpl->sadb_x_policy_dir]);
119 strcat(buf, ipsp_policy_strs[xpl->sadb_x_policy_type]);
121 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
122 ipsec_errcode = EIPSEC_NO_ERROR;
126 xtlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
127 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
129 /* count length of buffer for use */
130 /* XXX non-seriously */
133 if (xisr->sadb_x_ipsecrequest_mode ==IPSEC_MODE_TUNNEL)
135 xtlen -= xisr->sadb_x_ipsecrequest_len;
136 xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
137 + xisr->sadb_x_ipsecrequest_len);
142 ipsec_errcode = EIPSEC_INVAL_SADBMSG;
147 if ((buf = realloc(buf, buflen)) == NULL) {
148 ipsec_errcode = EIPSEC_NO_BUFS;
152 xtlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
153 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
156 strcat(buf, delimiter);
158 switch (xisr->sadb_x_ipsecrequest_proto) {
166 strcat(buf, "ipcomp");
169 ipsec_errcode = EIPSEC_INVAL_PROTO;
176 switch (xisr->sadb_x_ipsecrequest_mode) {
180 case IPSEC_MODE_TRANSPORT:
181 strcat(buf, "transport");
183 case IPSEC_MODE_TUNNEL:
184 strcat(buf, "tunnel");
187 ipsec_errcode = EIPSEC_INVAL_MODE;
194 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
195 error = set_addresses(buf, (caddr_t)(xisr + 1));
197 ipsec_errcode = EIPSEC_INVAL_MODE;
203 switch (xisr->sadb_x_ipsecrequest_level) {
204 case IPSEC_LEVEL_DEFAULT:
205 strcat(buf, "/default");
207 case IPSEC_LEVEL_USE:
210 case IPSEC_LEVEL_REQUIRE:
211 strcat(buf, "/require");
213 case IPSEC_LEVEL_UNIQUE:
214 strcat(buf, "/unique");
217 ipsec_errcode = EIPSEC_INVAL_LEVEL;
222 xtlen -= xisr->sadb_x_ipsecrequest_len;
223 xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
224 + xisr->sadb_x_ipsecrequest_len);
227 ipsec_errcode = EIPSEC_NO_ERROR;
232 set_addresses(buf, ptr)
236 char tmp[100]; /* XXX */
237 struct sockaddr *saddr = (struct sockaddr *)ptr;
239 getnameinfo(saddr, saddr->sa_len, tmp, sizeof(tmp),
240 NULL, 0, NI_NUMERICHOST);
246 saddr = (struct sockaddr *)((caddr_t)saddr + saddr->sa_len);
247 getnameinfo(saddr, saddr->sa_len, tmp, sizeof(tmp),
248 NULL, 0, NI_NUMERICHOST);