OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [ipsec/] [libipsec/] [current/] [src/] [policy_parse.y] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.