source: rtems-libbsd/freebsd/lib/libipsec/ipsec_dump_policy.c @ 66659ff

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 66659ff was 66659ff, checked in by Sebastian Huber <sebastian.huber@…>, on 11/06/13 at 15:20:21

Update to FreeBSD 9.2

  • Property mode set to 100644
File size: 7.5 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*      $KAME: ipsec_dump_policy.c,v 1.13 2002/06/27 14:35:11 itojun Exp $      */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD$");
36
37#include <rtems/bsd/sys/types.h>
38#include <rtems/bsd/sys/param.h>
39#include <sys/socket.h>
40
41#include <netipsec/key_var.h>
42#include <netinet/in.h>
43#include <netipsec/ipsec.h>
44
45#include <arpa/inet.h>
46
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <netdb.h>
51
52#include "ipsec_strerror.h"
53
54static const char *ipsp_dir_strs[] = {
55        "any", "in", "out",
56};
57
58static const char *ipsp_policy_strs[] = {
59        "discard", "none", "ipsec", "entrust", "bypass",
60};
61
62static char *ipsec_dump_ipsecrequest(char *, size_t,
63        struct sadb_x_ipsecrequest *, size_t);
64static int set_addresses(char *, size_t, struct sockaddr *, struct sockaddr *);
65static char *set_address(char *, size_t, struct sockaddr *);
66
67/*
68 * policy is sadb_x_policy buffer.
69 * Must call free() later.
70 * When delimiter == NULL, alternatively ' '(space) is applied.
71 */
72char *
73ipsec_dump_policy(policy, delimiter)
74        caddr_t policy;
75        char *delimiter;
76{
77        struct sadb_x_policy *xpl = (struct sadb_x_policy *)policy;
78        struct sadb_x_ipsecrequest *xisr;
79        size_t off, buflen;
80        char *buf;
81        char isrbuf[1024];
82        char *newbuf;
83
84        /* sanity check */
85        if (policy == NULL)
86                return NULL;
87        if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
88                __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
89                return NULL;
90        }
91
92        /* set delimiter */
93        if (delimiter == NULL)
94                delimiter = " ";
95
96        switch (xpl->sadb_x_policy_dir) {
97        case IPSEC_DIR_ANY:
98        case IPSEC_DIR_INBOUND:
99        case IPSEC_DIR_OUTBOUND:
100                break;
101        default:
102                __ipsec_errcode = EIPSEC_INVAL_DIR;
103                return NULL;
104        }
105
106        switch (xpl->sadb_x_policy_type) {
107        case IPSEC_POLICY_DISCARD:
108        case IPSEC_POLICY_NONE:
109        case IPSEC_POLICY_IPSEC:
110        case IPSEC_POLICY_BYPASS:
111        case IPSEC_POLICY_ENTRUST:
112                break;
113        default:
114                __ipsec_errcode = EIPSEC_INVAL_POLICY;
115                return NULL;
116        }
117
118        buflen = strlen(ipsp_dir_strs[xpl->sadb_x_policy_dir])
119                + 1     /* space */
120                + strlen(ipsp_policy_strs[xpl->sadb_x_policy_type])
121                + 1;    /* NUL */
122
123        if ((buf = malloc(buflen)) == NULL) {
124                __ipsec_errcode = EIPSEC_NO_BUFS;
125                return NULL;
126        }
127        snprintf(buf, buflen, "%s %s", ipsp_dir_strs[xpl->sadb_x_policy_dir],
128            ipsp_policy_strs[xpl->sadb_x_policy_type]);
129
130        if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
131                __ipsec_errcode = EIPSEC_NO_ERROR;
132                return buf;
133        }
134
135        /* count length of buffer for use */
136        off = sizeof(*xpl);
137        while (off < PFKEY_EXTLEN(xpl)) {
138                xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off);
139                off += xisr->sadb_x_ipsecrequest_len;
140        }
141
142        /* validity check */
143        if (off != PFKEY_EXTLEN(xpl)) {
144                __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
145                free(buf);
146                return NULL;
147        }
148
149        off = sizeof(*xpl);
150        while (off < PFKEY_EXTLEN(xpl)) {
151                xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off);
152
153                if (ipsec_dump_ipsecrequest(isrbuf, sizeof(isrbuf), xisr,
154                    PFKEY_EXTLEN(xpl) - off) == NULL) {
155                        free(buf);
156                        return NULL;
157                }
158
159                buflen = strlen(buf) + strlen(delimiter) + strlen(isrbuf) + 1;
160                newbuf = (char *)realloc(buf, buflen);
161                if (newbuf == NULL) {
162                        __ipsec_errcode = EIPSEC_NO_BUFS;
163                        free(buf);
164                        return NULL;
165                }
166                buf = newbuf;
167                snprintf(buf + strlen(buf), buflen - strlen(buf),
168                    "%s%s", delimiter, isrbuf);
169
170                off += xisr->sadb_x_ipsecrequest_len;
171        }
172
173        __ipsec_errcode = EIPSEC_NO_ERROR;
174        return buf;
175}
176
177static char *
178ipsec_dump_ipsecrequest(buf, len, xisr, bound)
179        char *buf;
180        size_t len;
181        struct sadb_x_ipsecrequest *xisr;
182        size_t bound;   /* boundary */
183{
184        const char *proto, *mode, *level;
185        char abuf[NI_MAXHOST * 2 + 2];
186
187        if (xisr->sadb_x_ipsecrequest_len > bound) {
188                __ipsec_errcode = EIPSEC_INVAL_PROTO;
189                return NULL;
190        }
191
192        switch (xisr->sadb_x_ipsecrequest_proto) {
193        case IPPROTO_ESP:
194                proto = "esp";
195                break;
196        case IPPROTO_AH:
197                proto = "ah";
198                break;
199        case IPPROTO_IPCOMP:
200                proto = "ipcomp";
201                break;
202        case IPPROTO_TCP:
203                proto = "tcp";
204        default:
205                __ipsec_errcode = EIPSEC_INVAL_PROTO;
206                return NULL;
207        }
208
209        switch (xisr->sadb_x_ipsecrequest_mode) {
210        case IPSEC_MODE_ANY:
211                mode = "any";
212                break;
213        case IPSEC_MODE_TRANSPORT:
214                mode = "transport";
215                break;
216        case IPSEC_MODE_TUNNEL:
217                mode = "tunnel";
218                break;
219        default:
220                __ipsec_errcode = EIPSEC_INVAL_MODE;
221                return NULL;
222        }
223
224        abuf[0] = '\0';
225        if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
226                struct sockaddr *sa1, *sa2;
227                caddr_t p;
228
229                p = (caddr_t)(xisr + 1);
230                sa1 = (struct sockaddr *)p;
231                sa2 = (struct sockaddr *)(p + sa1->sa_len);
232                if (sizeof(*xisr) + sa1->sa_len + sa2->sa_len !=
233                    xisr->sadb_x_ipsecrequest_len) {
234                        __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
235                        return NULL;
236                }
237                if (set_addresses(abuf, sizeof(abuf), sa1, sa2) != 0) {
238                        __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
239                        return NULL;
240                }
241        }
242
243        switch (xisr->sadb_x_ipsecrequest_level) {
244        case IPSEC_LEVEL_DEFAULT:
245                level = "default";
246                break;
247        case IPSEC_LEVEL_USE:
248                level = "use";
249                break;
250        case IPSEC_LEVEL_REQUIRE:
251                level = "require";
252                break;
253        case IPSEC_LEVEL_UNIQUE:
254                level = "unique";
255                break;
256        default:
257                __ipsec_errcode = EIPSEC_INVAL_LEVEL;
258                return NULL;
259        }
260
261        if (xisr->sadb_x_ipsecrequest_reqid == 0)
262                snprintf(buf, len, "%s/%s/%s/%s", proto, mode, abuf, level);
263        else {
264                int ch;
265
266                if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX)
267                        ch = '#';
268                else
269                        ch = ':';
270                snprintf(buf, len, "%s/%s/%s/%s%c%u", proto, mode, abuf, level,
271                    ch, xisr->sadb_x_ipsecrequest_reqid);
272        }
273
274        return buf;
275}
276
277static int
278set_addresses(buf, len, sa1, sa2)
279        char *buf;
280        size_t len;
281        struct sockaddr *sa1;
282        struct sockaddr *sa2;
283{
284        char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST];
285
286        if (set_address(tmp1, sizeof(tmp1), sa1) == NULL ||
287            set_address(tmp2, sizeof(tmp2), sa2) == NULL)
288                return -1;
289        if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len)
290                return -1;
291        snprintf(buf, len, "%s-%s", tmp1, tmp2);
292        return 0;
293}
294
295static char *
296set_address(buf, len, sa)
297        char *buf;
298        size_t len;
299        struct sockaddr *sa;
300{
301        const int niflags = NI_NUMERICHOST;
302
303        if (len < 1)
304                return NULL;
305        buf[0] = '\0';
306        if (getnameinfo(sa, sa->sa_len, buf, len, NULL, 0, niflags) != 0)
307                return NULL;
308        return buf;
309}
Note: See TracBrowser for help on using the repository browser.