Deleted Added
full compact
policy_parse.y (55505) policy_parse.y (62583)
1/* $FreeBSD: head/lib/libipsec/policy_parse.y 62583 2000-07-04 16:22:05Z itojun $ */
2/* $KAME: policy_parse.y,v 1.10 2000/05/07 05:25:03 itojun Exp $ */
3
1/*
2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

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
27 * SUCH DAMAGE.
4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/lib/libipsec/policy_parse.y 55505 2000-01-06 12:40:54Z shin $
30 */
31 */
31/* KAME $Id: policy_parse.y,v 1.1 1999/10/20 01:26:41 sakane Exp $ */
32
33/*
34 * IN/OUT bound policy configuration take place such below:
35 * in <policy>
36 * out <policy>
37 *
38 * <policy> is one of following:
39 * "discard", "none", "ipsec <requests>", "entrust", "bypass",

--- 14 unchanged lines hidden (view full) ---

54#include <sys/param.h>
55#include <sys/socket.h>
56
57#include <netinet/in.h>
58#include <netinet6/ipsec.h>
59
60#include <stdlib.h>
61#include <stdio.h>
32
33/*
34 * IN/OUT bound policy configuration take place such below:
35 * in <policy>
36 * out <policy>
37 *
38 * <policy> is one of following:
39 * "discard", "none", "ipsec <requests>", "entrust", "bypass",

--- 14 unchanged lines hidden (view full) ---

54#include <sys/param.h>
55#include <sys/socket.h>
56
57#include <netinet/in.h>
58#include <netinet6/ipsec.h>
59
60#include <stdlib.h>
61#include <stdio.h>
62#include <errno.h>
63#include <string.h>
64#include <netdb.h>
65
66#include "ipsec_strerror.h"
67
62#include <string.h>
63#include <netdb.h>
64
65#include "ipsec_strerror.h"
66
68#define ATOX(c) \
67#define ATOX(c) \
69 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
70
71static caddr_t pbuf = NULL; /* sadb_x_policy buffer */
72static int tlen = 0; /* total length of pbuf */
73static int offset = 0; /* offset of pbuf */
68 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
69
70static caddr_t pbuf = NULL; /* sadb_x_policy buffer */
71static int tlen = 0; /* total length of pbuf */
72static int offset = 0; /* offset of pbuf */
74static int p_dir, p_type, p_protocol, p_mode, p_level;
73static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid;
75static struct sockaddr *p_src = NULL;
76static struct sockaddr *p_dst = NULL;
77
74static struct sockaddr *p_src = NULL;
75static struct sockaddr *p_dst = NULL;
76
77struct _val;
78extern void yyerror __P((char *msg));
78extern void yyerror __P((char *msg));
79static struct sockaddr *parse_sockaddr __P((/*struct _val *buf*/));
79static struct sockaddr *parse_sockaddr __P((struct _val *buf));
80static int rule_check __P((void));
81static int init_x_policy __P((void));
82static int set_x_request __P((struct sockaddr *src, struct sockaddr *dst));
83static int set_sockaddr __P((struct sockaddr *addr));
84static void policy_parse_request_init __P((void));
85static caddr_t policy_parse __P((char *msg, int msglen));
86
87extern void __policy__strbuffer__init__ __P((char *msg));
80static int rule_check __P((void));
81static int init_x_policy __P((void));
82static int set_x_request __P((struct sockaddr *src, struct sockaddr *dst));
83static int set_sockaddr __P((struct sockaddr *addr));
84static void policy_parse_request_init __P((void));
85static caddr_t policy_parse __P((char *msg, int msglen));
86
87extern void __policy__strbuffer__init__ __P((char *msg));
88extern int yyparse();
89extern int yylex();
88extern int yyparse __P((void));
89extern int yylex __P((void));
90
91%}
92
93%union {
94 u_int num;
95 struct _val {
96 int len;
97 char *buf;
98 } val;
99}
100
90
91%}
92
93%union {
94 u_int num;
95 struct _val {
96 int len;
97 char *buf;
98 } val;
99}
100
101%token DIR ACTION PROTOCOL MODE LEVEL
101%token DIR ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY
102%token IPADDRESS
103%token ME ANY
104%token SLASH HYPHEN
105%type <num> DIR ACTION PROTOCOL MODE LEVEL
102%token IPADDRESS
103%token ME ANY
104%token SLASH HYPHEN
105%type <num> DIR ACTION PROTOCOL MODE LEVEL
106%type IPADDRESS
106%type <val> IPADDRESS LEVEL_SPECIFY
107
108%%
109policy_spec
110 : DIR ACTION
111 {
112 p_dir = $1;
113 p_type = $2;
114
115 if (init_x_policy())
116 return -1;
117 }
118 rules
107
108%%
109policy_spec
110 : DIR ACTION
111 {
112 p_dir = $1;
113 p_type = $2;
114
115 if (init_x_policy())
116 return -1;
117 }
118 rules
119 | DIR
120 {
121 p_dir = $1;
122 p_type = 0; /* ignored it by kernel */
123
124 if (init_x_policy())
125 return -1;
126 }
119 ;
120
121rules
122 : /*NOTHING*/
123 | rules rule {
124 if (rule_check() < 0)
125 return -1;
126

--- 7 unchanged lines hidden (view full) ---

134rule
135 : protocol SLASH mode SLASH addresses SLASH level
136 | protocol SLASH mode SLASH addresses SLASH
137 | protocol SLASH mode SLASH addresses
138 | protocol SLASH mode SLASH
139 | protocol SLASH mode SLASH SLASH level
140 | protocol SLASH mode
141 | protocol SLASH {
127 ;
128
129rules
130 : /*NOTHING*/
131 | rules rule {
132 if (rule_check() < 0)
133 return -1;
134

--- 7 unchanged lines hidden (view full) ---

142rule
143 : protocol SLASH mode SLASH addresses SLASH level
144 | protocol SLASH mode SLASH addresses SLASH
145 | protocol SLASH mode SLASH addresses
146 | protocol SLASH mode SLASH
147 | protocol SLASH mode SLASH SLASH level
148 | protocol SLASH mode
149 | protocol SLASH {
142 ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
150 __ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
143 return -1;
144 }
145 | protocol {
151 return -1;
152 }
153 | protocol {
146 ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
154 __ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
147 return -1;
148 }
149 ;
150
151protocol
152 : PROTOCOL { p_protocol = $1; }
153 ;
154
155mode
156 : MODE { p_mode = $1; }
157 ;
158
159level
155 return -1;
156 }
157 ;
158
159protocol
160 : PROTOCOL { p_protocol = $1; }
161 ;
162
163mode
164 : MODE { p_mode = $1; }
165 ;
166
167level
160 : LEVEL { p_level = $1; }
168 : LEVEL {
169 p_level = $1;
170 p_reqid = 0;
171 }
172 | LEVEL_SPECIFY {
173 p_level = IPSEC_LEVEL_UNIQUE;
174 p_reqid = atol($1.buf); /* atol() is good. */
175 }
161 ;
162
163addresses
164 : IPADDRESS {
165 p_src = parse_sockaddr(&$1);
166 if (p_src == NULL)
167 return -1;
168 }
169 HYPHEN
170 IPADDRESS {
171 p_dst = parse_sockaddr(&$4);
172 if (p_dst == NULL)
173 return -1;
174 }
175 | ME HYPHEN ANY {
176 if (p_dir != IPSEC_DIR_OUTBOUND) {
176 ;
177
178addresses
179 : IPADDRESS {
180 p_src = parse_sockaddr(&$1);
181 if (p_src == NULL)
182 return -1;
183 }
184 HYPHEN
185 IPADDRESS {
186 p_dst = parse_sockaddr(&$4);
187 if (p_dst == NULL)
188 return -1;
189 }
190 | ME HYPHEN ANY {
191 if (p_dir != IPSEC_DIR_OUTBOUND) {
177 ipsec_errcode = EIPSEC_INVAL_DIR;
192 __ipsec_errcode = EIPSEC_INVAL_DIR;
178 return -1;
179 }
180 }
181 | ANY HYPHEN ME {
182 if (p_dir != IPSEC_DIR_INBOUND) {
193 return -1;
194 }
195 }
196 | ANY HYPHEN ME {
197 if (p_dir != IPSEC_DIR_INBOUND) {
183 ipsec_errcode = EIPSEC_INVAL_DIR;
198 __ipsec_errcode = EIPSEC_INVAL_DIR;
184 return -1;
185 }
186 }
187 /*
188 | ME HYPHEN ME
189 */
190 ;
191
192%%
193
194void
195yyerror(msg)
196 char *msg;
197{
199 return -1;
200 }
201 }
202 /*
203 | ME HYPHEN ME
204 */
205 ;
206
207%%
208
209void
210yyerror(msg)
211 char *msg;
212{
198 fprintf(stderr, "%s\n", msg);
213 extern char *__libipsecyytext; /*XXX*/
199
214
215 fprintf(stderr, "libipsec: %s while parsing \"%s\"\n",
216 msg, __libipsecyytext);
217
200 return;
201}
202
203static struct sockaddr *
204parse_sockaddr(buf)
205 struct _val *buf;
206{
207 struct addrinfo hints, *res;
208 char *serv = NULL;
209 int error;
210 struct sockaddr *newaddr = NULL;
211
212 memset(&hints, 0, sizeof(hints));
213 hints.ai_family = PF_UNSPEC;
214 hints.ai_flags = AI_NUMERICHOST;
215 error = getaddrinfo(buf->buf, serv, &hints, &res);
218 return;
219}
220
221static struct sockaddr *
222parse_sockaddr(buf)
223 struct _val *buf;
224{
225 struct addrinfo hints, *res;
226 char *serv = NULL;
227 int error;
228 struct sockaddr *newaddr = NULL;
229
230 memset(&hints, 0, sizeof(hints));
231 hints.ai_family = PF_UNSPEC;
232 hints.ai_flags = AI_NUMERICHOST;
233 error = getaddrinfo(buf->buf, serv, &hints, &res);
216 if (error != 0 || res->ai_addr == NULL) {
217 ipsec_set_strerror(error == EAI_SYSTEM ?
218 gai_strerror(error) : strerror(errno));
234 if (error != 0) {
235 yyerror("invalid IP address");
236 __ipsec_set_strerror(gai_strerror(error));
219 return NULL;
220 }
221
222 if (res->ai_addr == NULL) {
237 return NULL;
238 }
239
240 if (res->ai_addr == NULL) {
223 ipsec_set_strerror(gai_strerror(error));
241 yyerror("invalid IP address");
242 __ipsec_set_strerror(gai_strerror(error));
224 return NULL;
225 }
226
227 newaddr = malloc(res->ai_addr->sa_len);
228 if (newaddr == NULL) {
243 return NULL;
244 }
245
246 newaddr = malloc(res->ai_addr->sa_len);
247 if (newaddr == NULL) {
229 ipsec_errcode = EIPSEC_NO_BUFS;
248 __ipsec_errcode = EIPSEC_NO_BUFS;
230 freeaddrinfo(res);
231 return NULL;
232 }
233 memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len);
234
249 freeaddrinfo(res);
250 return NULL;
251 }
252 memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len);
253
235 /*
236 * XXX: If the scope of the destination is link-local,
237 * embed the scope-id(in this case, interface index)
238 * into the address.
239 */
240 if (newaddr->sa_family == AF_INET6) {
241 struct sockaddr_in6 *sin6;
242
243 sin6 = (struct sockaddr_in6 *)newaddr;
244 if(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
245 sin6->sin6_scope_id != 0)
246 *(u_short *)&sin6->sin6_addr.s6_addr[2] =
247 htons(sin6->sin6_scope_id & 0xffff);
248 }
249
250 freeaddrinfo(res);
251
254 freeaddrinfo(res);
255
252 ipsec_errcode = EIPSEC_NO_ERROR;
256 __ipsec_errcode = EIPSEC_NO_ERROR;
253 return newaddr;
254}
255
256static int
257rule_check()
258{
259 if (p_type == IPSEC_POLICY_IPSEC) {
260 if (p_protocol == IPPROTO_IP) {
257 return newaddr;
258}
259
260static int
261rule_check()
262{
263 if (p_type == IPSEC_POLICY_IPSEC) {
264 if (p_protocol == IPPROTO_IP) {
261 ipsec_errcode = EIPSEC_NO_PROTO;
265 __ipsec_errcode = EIPSEC_NO_PROTO;
262 return -1;
263 }
264
265 if (p_mode != IPSEC_MODE_TRANSPORT
266 && p_mode != IPSEC_MODE_TUNNEL) {
266 return -1;
267 }
268
269 if (p_mode != IPSEC_MODE_TRANSPORT
270 && p_mode != IPSEC_MODE_TUNNEL) {
267 ipsec_errcode = EIPSEC_INVAL_MODE;
271 __ipsec_errcode = EIPSEC_INVAL_MODE;
268 return -1;
269 }
270
271 if (p_src == NULL && p_dst == NULL) {
272 if (p_mode != IPSEC_MODE_TRANSPORT) {
272 return -1;
273 }
274
275 if (p_src == NULL && p_dst == NULL) {
276 if (p_mode != IPSEC_MODE_TRANSPORT) {
273 ipsec_errcode = EIPSEC_INVAL_ADDRESS;
277 __ipsec_errcode = EIPSEC_INVAL_ADDRESS;
274 return -1;
275 }
276 }
277 else if (p_src->sa_family != p_dst->sa_family) {
278 return -1;
279 }
280 }
281 else if (p_src->sa_family != p_dst->sa_family) {
278 ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
282 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
279 return -1;
280 }
281 }
282
283 return -1;
284 }
285 }
286
283 ipsec_errcode = EIPSEC_NO_ERROR;
287 __ipsec_errcode = EIPSEC_NO_ERROR;
284 return 0;
285}
286
287static int
288init_x_policy()
289{
290 struct sadb_x_policy *p;
291
292 tlen = sizeof(struct sadb_x_policy);
293
294 pbuf = malloc(tlen);
295 if (pbuf == NULL) {
288 return 0;
289}
290
291static int
292init_x_policy()
293{
294 struct sadb_x_policy *p;
295
296 tlen = sizeof(struct sadb_x_policy);
297
298 pbuf = malloc(tlen);
299 if (pbuf == NULL) {
296 ipsec_errcode = EIPSEC_NO_BUFS;
300 __ipsec_errcode = EIPSEC_NO_BUFS;
297 return -1;
298 }
299 p = (struct sadb_x_policy *)pbuf;
300 p->sadb_x_policy_len = 0; /* must update later */
301 p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
302 p->sadb_x_policy_type = p_type;
303 p->sadb_x_policy_dir = p_dir;
304 p->sadb_x_policy_reserved = 0;
305 offset = tlen;
306
301 return -1;
302 }
303 p = (struct sadb_x_policy *)pbuf;
304 p->sadb_x_policy_len = 0; /* must update later */
305 p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
306 p->sadb_x_policy_type = p_type;
307 p->sadb_x_policy_dir = p_dir;
308 p->sadb_x_policy_reserved = 0;
309 offset = tlen;
310
307 ipsec_errcode = EIPSEC_NO_ERROR;
311 __ipsec_errcode = EIPSEC_NO_ERROR;
308 return 0;
309}
310
311static int
312set_x_request(src, dst)
313 struct sockaddr *src, *dst;
314{
315 struct sadb_x_ipsecrequest *p;
316 int reqlen;
317
318 reqlen = sizeof(*p)
319 + (src ? src->sa_len : 0)
320 + (dst ? dst->sa_len : 0);
321 tlen += reqlen; /* increment to total length */
322
323 pbuf = realloc(pbuf, tlen);
324 if (pbuf == NULL) {
312 return 0;
313}
314
315static int
316set_x_request(src, dst)
317 struct sockaddr *src, *dst;
318{
319 struct sadb_x_ipsecrequest *p;
320 int reqlen;
321
322 reqlen = sizeof(*p)
323 + (src ? src->sa_len : 0)
324 + (dst ? dst->sa_len : 0);
325 tlen += reqlen; /* increment to total length */
326
327 pbuf = realloc(pbuf, tlen);
328 if (pbuf == NULL) {
325 ipsec_errcode = EIPSEC_NO_BUFS;
329 __ipsec_errcode = EIPSEC_NO_BUFS;
326 return -1;
327 }
328 p = (struct sadb_x_ipsecrequest *)&pbuf[offset];
329 p->sadb_x_ipsecrequest_len = reqlen;
330 p->sadb_x_ipsecrequest_proto = p_protocol;
331 p->sadb_x_ipsecrequest_mode = p_mode;
332 p->sadb_x_ipsecrequest_level = p_level;
330 return -1;
331 }
332 p = (struct sadb_x_ipsecrequest *)&pbuf[offset];
333 p->sadb_x_ipsecrequest_len = reqlen;
334 p->sadb_x_ipsecrequest_proto = p_protocol;
335 p->sadb_x_ipsecrequest_mode = p_mode;
336 p->sadb_x_ipsecrequest_level = p_level;
337 p->sadb_x_ipsecrequest_reqid = p_reqid;
333 offset += sizeof(*p);
334
335 if (set_sockaddr(src) || set_sockaddr(dst))
336 return -1;
337
338 offset += sizeof(*p);
339
340 if (set_sockaddr(src) || set_sockaddr(dst))
341 return -1;
342
338 ipsec_errcode = EIPSEC_NO_ERROR;
343 __ipsec_errcode = EIPSEC_NO_ERROR;
339 return 0;
340}
341
342static int
343set_sockaddr(addr)
344 struct sockaddr *addr;
345{
346 if (addr == NULL) {
344 return 0;
345}
346
347static int
348set_sockaddr(addr)
349 struct sockaddr *addr;
350{
351 if (addr == NULL) {
347 ipsec_errcode = EIPSEC_NO_ERROR;
352 __ipsec_errcode = EIPSEC_NO_ERROR;
348 return 0;
349 }
350
351 /* tlen has already incremented */
352
353 memcpy(&pbuf[offset], addr, addr->sa_len);
354
355 offset += addr->sa_len;
356
353 return 0;
354 }
355
356 /* tlen has already incremented */
357
358 memcpy(&pbuf[offset], addr, addr->sa_len);
359
360 offset += addr->sa_len;
361
357 ipsec_errcode = EIPSEC_NO_ERROR;
362 __ipsec_errcode = EIPSEC_NO_ERROR;
358 return 0;
359}
360
361static void
362policy_parse_request_init()
363{
364 p_protocol = IPPROTO_IP;
365 p_mode = IPSEC_MODE_ANY;
366 p_level = IPSEC_LEVEL_DEFAULT;
363 return 0;
364}
365
366static void
367policy_parse_request_init()
368{
369 p_protocol = IPPROTO_IP;
370 p_mode = IPSEC_MODE_ANY;
371 p_level = IPSEC_LEVEL_DEFAULT;
372 p_reqid = 0;
367 if (p_src != NULL) {
368 free(p_src);
369 p_src = NULL;
370 }
371 if (p_dst != NULL) {
372 free(p_dst);
373 p_dst = NULL;
374 }

--- 21 unchanged lines hidden (view full) ---

396 if (pbuf != NULL)
397 free(pbuf);
398 return NULL;
399 }
400
401 /* update total length */
402 ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen);
403
373 if (p_src != NULL) {
374 free(p_src);
375 p_src = NULL;
376 }
377 if (p_dst != NULL) {
378 free(p_dst);
379 p_dst = NULL;
380 }

--- 21 unchanged lines hidden (view full) ---

402 if (pbuf != NULL)
403 free(pbuf);
404 return NULL;
405 }
406
407 /* update total length */
408 ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen);
409
404 ipsec_errcode = EIPSEC_NO_ERROR;
410 __ipsec_errcode = EIPSEC_NO_ERROR;
405
406 return pbuf;
407}
408
409caddr_t
410ipsec_set_policy(msg, msglen)
411 char *msg;
412 int msglen;
413{
414 caddr_t policy;
415
416 policy = policy_parse(msg, msglen);
417 if (policy == NULL) {
411
412 return pbuf;
413}
414
415caddr_t
416ipsec_set_policy(msg, msglen)
417 char *msg;
418 int msglen;
419{
420 caddr_t policy;
421
422 policy = policy_parse(msg, msglen);
423 if (policy == NULL) {
418 if (ipsec_errcode == EIPSEC_NO_ERROR)
419 ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
424 if (__ipsec_errcode == EIPSEC_NO_ERROR)
425 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
420 return NULL;
421 }
422
426 return NULL;
427 }
428
423 ipsec_errcode = EIPSEC_NO_ERROR;
429 __ipsec_errcode = EIPSEC_NO_ERROR;
424 return policy;
425}
426
430 return policy;
431}
432