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

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since d48955b was d48955b, checked in by Sebastian Huber <sebastian.huber@…>, on 11/06/13 at 08:02:16

Add and use <machine/rtems-bsd-user-space.h>

  • 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, buflen, "%s%s%s", buf, delimiter, isrbuf);
168
169                off += xisr->sadb_x_ipsecrequest_len;
170        }
171
172        __ipsec_errcode = EIPSEC_NO_ERROR;
173        return buf;
174}
175
176static char *
177ipsec_dump_ipsecrequest(buf, len, xisr, bound)
178        char *buf;
179        size_t len;
180        struct sadb_x_ipsecrequest *xisr;
181        size_t bound;   /* boundary */
182{
183        const char *proto, *mode, *level;
184        char abuf[NI_MAXHOST * 2 + 2];
185
186        if (xisr->sadb_x_ipsecrequest_len > bound) {
187                __ipsec_errcode = EIPSEC_INVAL_PROTO;
188                return NULL;
189        }
190
191        switch (xisr->sadb_x_ipsecrequest_proto) {
192        case IPPROTO_ESP:
193                proto = "esp";
194                break;
195        case IPPROTO_AH:
196                proto = "ah";
197                break;
198        case IPPROTO_IPCOMP:
199                proto = "ipcomp";
200                break;
201        case IPPROTO_TCP:
202                proto = "tcp";
203        default:
204                __ipsec_errcode = EIPSEC_INVAL_PROTO;
205                return NULL;
206        }
207
208        switch (xisr->sadb_x_ipsecrequest_mode) {
209        case IPSEC_MODE_ANY:
210                mode = "any";
211                break;
212        case IPSEC_MODE_TRANSPORT:
213                mode = "transport";
214                break;
215        case IPSEC_MODE_TUNNEL:
216                mode = "tunnel";
217                break;
218        default:
219                __ipsec_errcode = EIPSEC_INVAL_MODE;
220                return NULL;
221        }
222
223        abuf[0] = '\0';
224        if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
225                struct sockaddr *sa1, *sa2;
226                caddr_t p;
227
228                p = (caddr_t)(xisr + 1);
229                sa1 = (struct sockaddr *)p;
230                sa2 = (struct sockaddr *)(p + sa1->sa_len);
231                if (sizeof(*xisr) + sa1->sa_len + sa2->sa_len !=
232                    xisr->sadb_x_ipsecrequest_len) {
233                        __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
234                        return NULL;
235                }
236                if (set_addresses(abuf, sizeof(abuf), sa1, sa2) != 0) {
237                        __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
238                        return NULL;
239                }
240        }
241
242        switch (xisr->sadb_x_ipsecrequest_level) {
243        case IPSEC_LEVEL_DEFAULT:
244                level = "default";
245                break;
246        case IPSEC_LEVEL_USE:
247                level = "use";
248                break;
249        case IPSEC_LEVEL_REQUIRE:
250                level = "require";
251                break;
252        case IPSEC_LEVEL_UNIQUE:
253                level = "unique";
254                break;
255        default:
256                __ipsec_errcode = EIPSEC_INVAL_LEVEL;
257                return NULL;
258        }
259
260        if (xisr->sadb_x_ipsecrequest_reqid == 0)
261                snprintf(buf, len, "%s/%s/%s/%s", proto, mode, abuf, level);
262        else {
263                int ch;
264
265                if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX)
266                        ch = '#';
267                else
268                        ch = ':';
269                snprintf(buf, len, "%s/%s/%s/%s%c%u", proto, mode, abuf, level,
270                    ch, xisr->sadb_x_ipsecrequest_reqid);
271        }
272
273        return buf;
274}
275
276static int
277set_addresses(buf, len, sa1, sa2)
278        char *buf;
279        size_t len;
280        struct sockaddr *sa1;
281        struct sockaddr *sa2;
282{
283        char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST];
284
285        if (set_address(tmp1, sizeof(tmp1), sa1) == NULL ||
286            set_address(tmp2, sizeof(tmp2), sa2) == NULL)
287                return -1;
288        if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len)
289                return -1;
290        snprintf(buf, len, "%s-%s", tmp1, tmp2);
291        return 0;
292}
293
294static char *
295set_address(buf, len, sa)
296        char *buf;
297        size_t len;
298        struct sockaddr *sa;
299{
300        const int niflags = NI_NUMERICHOST;
301
302        if (len < 1)
303                return NULL;
304        buf[0] = '\0';
305        if (getnameinfo(sa, sa->sa_len, buf, len, NULL, 0, niflags) != 0)
306                return NULL;
307        return buf;
308}
Note: See TracBrowser for help on using the repository browser.