source: rtems-libbsd/freebsd/lib/libipsec/policy_parse.y @ e599318

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since e599318 was e599318, checked in by Sebastian Huber <sebastian.huber@…>, on 10/09/13 at 20:52:54

Update files to match FreeBSD layout

Add compatibility with Newlib header files. Some FreeBSD header files
are mapped by the translation script:

o rtems/bsd/sys/_types.h
o rtems/bsd/sys/errno.h
o rtems/bsd/sys/lock.h
o rtems/bsd/sys/param.h
o rtems/bsd/sys/resource.h
o rtems/bsd/sys/time.h
o rtems/bsd/sys/timespec.h
o rtems/bsd/sys/types.h
o rtems/bsd/sys/unistd.h

It is now possible to include <sys/socket.h> directly for example.

Generate one Makefile which builds everything including tests.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*      $KAME: policy_parse.y,v 1.14 2003/06/27 03:39:20 itojun Exp $   */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * IN/OUT bound policy configuration take place such below:
34 *      in <policy>
35 *      out <policy>
36 *
37 * <policy> is one of following:
38 *      "discard", "none", "ipsec <requests>", "entrust", "bypass",
39 *
40 * The following requests are accepted as <requests>:
41 *
42 *      protocol/mode/src-dst/level
43 *      protocol/mode/src-dst           parsed as protocol/mode/src-dst/default
44 *      protocol/mode/src-dst/          parsed as protocol/mode/src-dst/default
45 *      protocol/transport              parsed as protocol/mode/any-any/default
46 *      protocol/transport//level       parsed as protocol/mode/any-any/level
47 *
48 * You can concatenate these requests with either ' '(single space) or '\n'.
49 */
50
51%{
52#include <sys/cdefs.h>
53__FBSDID("$FreeBSD$");
54
55#include <sys/types.h>
56#include <sys/param.h>
57#include <sys/socket.h>
58
59#include <netinet/in.h>
60#include <netipsec/ipsec.h>
61
62#include <stdlib.h>
63#include <stdio.h>
64#include <string.h>
65#include <netdb.h>
66
67#include "ipsec_strerror.h"
68
69#define ATOX(c) \
70  (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
71
72static caddr_t pbuf = NULL;             /* sadb_x_policy buffer */
73static int tlen = 0;                    /* total length of pbuf */
74static int offset = 0;                  /* offset of pbuf */
75static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid;
76static struct sockaddr *p_src = NULL;
77static struct sockaddr *p_dst = NULL;
78
79struct _val;
80extern void yyerror(char *msg);
81static struct sockaddr *parse_sockaddr(struct _val *buf);
82static int rule_check(void);
83static int init_x_policy(void);
84static int set_x_request(struct sockaddr *src, struct sockaddr *dst);
85static int set_sockaddr(struct sockaddr *addr);
86static void policy_parse_request_init(void);
87static caddr_t policy_parse(char *msg, int msglen);
88
89extern void __policy__strbuffer__init__(char *msg);
90extern void __policy__strbuffer__free__(void);
91extern int yyparse(void);
92extern int yylex(void);
93
94extern char *__libipsecyytext;  /*XXX*/
95
96%}
97
98%union {
99        u_int num;
100        struct _val {
101                int len;
102                char *buf;
103        } val;
104}
105
106%token DIR ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY
107%token IPADDRESS
108%token ME ANY
109%token SLASH HYPHEN
110%type <num> DIR ACTION PROTOCOL MODE LEVEL
111%type <val> IPADDRESS LEVEL_SPECIFY
112
113%%
114policy_spec
115        :       DIR ACTION
116                {
117                        p_dir = $1;
118                        p_type = $2;
119
120                        if (init_x_policy())
121                                return -1;
122                }
123                rules
124        |       DIR
125                {
126                        p_dir = $1;
127                        p_type = 0;     /* ignored it by kernel */
128
129                        if (init_x_policy())
130                                return -1;
131                }
132        ;
133
134rules
135        :       /*NOTHING*/
136        |       rules rule {
137                        if (rule_check() < 0)
138                                return -1;
139
140                        if (set_x_request(p_src, p_dst) < 0)
141                                return -1;
142
143                        policy_parse_request_init();
144                }
145        ;
146
147rule
148        :       protocol SLASH mode SLASH addresses SLASH level
149        |       protocol SLASH mode SLASH addresses SLASH
150        |       protocol SLASH mode SLASH addresses
151        |       protocol SLASH mode SLASH
152        |       protocol SLASH mode SLASH SLASH level
153        |       protocol SLASH mode
154        |       protocol SLASH {
155                        __ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
156                        return -1;
157                }
158        |       protocol {
159                        __ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
160                        return -1;
161                }
162        ;
163
164protocol
165        :       PROTOCOL { p_protocol = $1; }
166        ;
167
168mode
169        :       MODE { p_mode = $1; }
170        ;
171
172level
173        :       LEVEL {
174                        p_level = $1;
175                        p_reqid = 0;
176                }
177        |       LEVEL_SPECIFY {
178                        p_level = IPSEC_LEVEL_UNIQUE;
179                        p_reqid = atol($1.buf); /* atol() is good. */
180                }
181        ;
182
183addresses
184        :       IPADDRESS {
185                        p_src = parse_sockaddr(&$1);
186                        if (p_src == NULL)
187                                return -1;
188                }
189                HYPHEN
190                IPADDRESS {
191                        p_dst = parse_sockaddr(&$4);
192                        if (p_dst == NULL)
193                                return -1;
194                }
195        |       ME HYPHEN ANY {
196                        if (p_dir != IPSEC_DIR_OUTBOUND) {
197                                __ipsec_errcode = EIPSEC_INVAL_DIR;
198                                return -1;
199                        }
200                }
201        |       ANY HYPHEN ME {
202                        if (p_dir != IPSEC_DIR_INBOUND) {
203                                __ipsec_errcode = EIPSEC_INVAL_DIR;
204                                return -1;
205                        }
206                }
207                /*
208        |       ME HYPHEN ME
209                */
210        ;
211
212%%
213
214void
215yyerror(msg)
216        char *msg;
217{
218        fprintf(stderr, "libipsec: %s while parsing \"%s\"\n",
219                msg, __libipsecyytext);
220
221        return;
222}
223
224static struct sockaddr *
225parse_sockaddr(buf)
226        struct _val *buf;
227{
228        struct addrinfo hints, *res;
229        char *serv = NULL;
230        int error;
231        struct sockaddr *newaddr = NULL;
232
233        memset(&hints, 0, sizeof(hints));
234        hints.ai_family = PF_UNSPEC;
235        hints.ai_flags = AI_NUMERICHOST;
236        error = getaddrinfo(buf->buf, serv, &hints, &res);
237        if (error != 0) {
238                yyerror("invalid IP address");
239                __ipsec_set_strerror(gai_strerror(error));
240                return NULL;
241        }
242
243        if (res->ai_addr == NULL) {
244                yyerror("invalid IP address");
245                __ipsec_set_strerror(gai_strerror(error));
246                return NULL;
247        }
248
249        newaddr = malloc(res->ai_addr->sa_len);
250        if (newaddr == NULL) {
251                __ipsec_errcode = EIPSEC_NO_BUFS;
252                freeaddrinfo(res);
253                return NULL;
254        }
255        memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len);
256
257        freeaddrinfo(res);
258
259        __ipsec_errcode = EIPSEC_NO_ERROR;
260        return newaddr;
261}
262
263static int
264rule_check()
265{
266        if (p_type == IPSEC_POLICY_IPSEC) {
267                if (p_protocol == IPPROTO_IP) {
268                        __ipsec_errcode = EIPSEC_NO_PROTO;
269                        return -1;
270                }
271
272                if (p_mode != IPSEC_MODE_TRANSPORT
273                 && p_mode != IPSEC_MODE_TUNNEL) {
274                        __ipsec_errcode = EIPSEC_INVAL_MODE;
275                        return -1;
276                }
277
278                if (p_src == NULL && p_dst == NULL) {
279                         if (p_mode != IPSEC_MODE_TRANSPORT) {
280                                __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
281                                return -1;
282                        }
283                }
284                else if (p_src->sa_family != p_dst->sa_family) {
285                        __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
286                        return -1;
287                }
288        }
289
290        __ipsec_errcode = EIPSEC_NO_ERROR;
291        return 0;
292}
293
294static int
295init_x_policy()
296{
297        struct sadb_x_policy *p;
298
299        tlen = sizeof(struct sadb_x_policy);
300
301        pbuf = malloc(tlen);
302        if (pbuf == NULL) {
303                __ipsec_errcode = EIPSEC_NO_BUFS;
304                return -1;
305        }
306        memset(pbuf, 0, tlen);
307        p = (struct sadb_x_policy *)pbuf;
308        p->sadb_x_policy_len = 0;       /* must update later */
309        p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
310        p->sadb_x_policy_type = p_type;
311        p->sadb_x_policy_dir = p_dir;
312        p->sadb_x_policy_id = 0;
313
314        offset = tlen;
315
316        __ipsec_errcode = EIPSEC_NO_ERROR;
317        return 0;
318}
319
320static int
321set_x_request(src, dst)
322        struct sockaddr *src, *dst;
323{
324        struct sadb_x_ipsecrequest *p;
325        int reqlen;
326
327        reqlen = sizeof(*p)
328                + (src ? src->sa_len : 0)
329                + (dst ? dst->sa_len : 0);
330        tlen += reqlen;         /* increment to total length */
331
332        pbuf = realloc(pbuf, tlen);
333        if (pbuf == NULL) {
334                __ipsec_errcode = EIPSEC_NO_BUFS;
335                return -1;
336        }
337        p = (struct sadb_x_ipsecrequest *)&pbuf[offset];
338        p->sadb_x_ipsecrequest_len = reqlen;
339        p->sadb_x_ipsecrequest_proto = p_protocol;
340        p->sadb_x_ipsecrequest_mode = p_mode;
341        p->sadb_x_ipsecrequest_level = p_level;
342        p->sadb_x_ipsecrequest_reqid = p_reqid;
343        offset += sizeof(*p);
344
345        if (set_sockaddr(src) || set_sockaddr(dst))
346                return -1;
347
348        __ipsec_errcode = EIPSEC_NO_ERROR;
349        return 0;
350}
351
352static int
353set_sockaddr(addr)
354        struct sockaddr *addr;
355{
356        if (addr == NULL) {
357                __ipsec_errcode = EIPSEC_NO_ERROR;
358                return 0;
359        }
360
361        /* tlen has already incremented */
362
363        memcpy(&pbuf[offset], addr, addr->sa_len);
364
365        offset += addr->sa_len;
366
367        __ipsec_errcode = EIPSEC_NO_ERROR;
368        return 0;
369}
370
371static void
372policy_parse_request_init()
373{
374        p_protocol = IPPROTO_IP;
375        p_mode = IPSEC_MODE_ANY;
376        p_level = IPSEC_LEVEL_DEFAULT;
377        p_reqid = 0;
378        if (p_src != NULL) {
379                free(p_src);
380                p_src = NULL;
381        }
382        if (p_dst != NULL) {
383                free(p_dst);
384                p_dst = NULL;
385        }
386
387        return;
388}
389
390static caddr_t
391policy_parse(msg, msglen)
392        char *msg;
393        int msglen;
394{
395        int error;
396        pbuf = NULL;
397        tlen = 0;
398
399        /* initialize */
400        p_dir = IPSEC_DIR_INVALID;
401        p_type = IPSEC_POLICY_DISCARD;
402        policy_parse_request_init();
403        __policy__strbuffer__init__(msg);
404
405        error = yyparse();      /* it must be set errcode. */
406        __policy__strbuffer__free__();
407
408        if (error) {
409                if (pbuf != NULL)
410                        free(pbuf);
411                return NULL;
412        }
413
414        /* update total length */
415        ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen);
416
417        __ipsec_errcode = EIPSEC_NO_ERROR;
418
419        return pbuf;
420}
421
422caddr_t
423ipsec_set_policy(msg, msglen)
424        char *msg;
425        int msglen;
426{
427        caddr_t policy;
428
429        policy = policy_parse(msg, msglen);
430        if (policy == NULL) {
431                if (__ipsec_errcode == EIPSEC_NO_ERROR)
432                        __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
433                return NULL;
434        }
435
436        __ipsec_errcode = EIPSEC_NO_ERROR;
437        return policy;
438}
439
Note: See TracBrowser for help on using the repository browser.