1 | #ifndef lint |
---|
2 | static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; |
---|
3 | #endif |
---|
4 | |
---|
5 | #define YYBYACC 1 |
---|
6 | #define YYMAJOR 1 |
---|
7 | #define YYMINOR 9 |
---|
8 | #define YYPATCH 20101229 |
---|
9 | |
---|
10 | #define YYEMPTY (-1) |
---|
11 | #define yyclearin (yychar = YYEMPTY) |
---|
12 | #define yyerrok (yyerrflag = 0) |
---|
13 | #define YYRECOVERING() (yyerrflag != 0) |
---|
14 | |
---|
15 | |
---|
16 | #ifndef yyparse |
---|
17 | #define yyparse __libipsecyyparse |
---|
18 | #endif /* yyparse */ |
---|
19 | |
---|
20 | #ifndef yylex |
---|
21 | #define yylex __libipsecyylex |
---|
22 | #endif /* yylex */ |
---|
23 | |
---|
24 | #ifndef yyerror |
---|
25 | #define yyerror __libipsecyyerror |
---|
26 | #endif /* yyerror */ |
---|
27 | |
---|
28 | #ifndef yychar |
---|
29 | #define yychar __libipsecyychar |
---|
30 | #endif /* yychar */ |
---|
31 | |
---|
32 | #ifndef yyval |
---|
33 | #define yyval __libipsecyyval |
---|
34 | #endif /* yyval */ |
---|
35 | |
---|
36 | #ifndef yylval |
---|
37 | #define yylval __libipsecyylval |
---|
38 | #endif /* yylval */ |
---|
39 | |
---|
40 | #ifndef yydebug |
---|
41 | #define yydebug __libipsecyydebug |
---|
42 | #endif /* yydebug */ |
---|
43 | |
---|
44 | #ifndef yynerrs |
---|
45 | #define yynerrs __libipsecyynerrs |
---|
46 | #endif /* yynerrs */ |
---|
47 | |
---|
48 | #ifndef yyerrflag |
---|
49 | #define yyerrflag __libipsecyyerrflag |
---|
50 | #endif /* yyerrflag */ |
---|
51 | |
---|
52 | #ifndef yylhs |
---|
53 | #define yylhs __libipsecyylhs |
---|
54 | #endif /* yylhs */ |
---|
55 | |
---|
56 | #ifndef yylen |
---|
57 | #define yylen __libipsecyylen |
---|
58 | #endif /* yylen */ |
---|
59 | |
---|
60 | #ifndef yydefred |
---|
61 | #define yydefred __libipsecyydefred |
---|
62 | #endif /* yydefred */ |
---|
63 | |
---|
64 | #ifndef yydgoto |
---|
65 | #define yydgoto __libipsecyydgoto |
---|
66 | #endif /* yydgoto */ |
---|
67 | |
---|
68 | #ifndef yysindex |
---|
69 | #define yysindex __libipsecyysindex |
---|
70 | #endif /* yysindex */ |
---|
71 | |
---|
72 | #ifndef yyrindex |
---|
73 | #define yyrindex __libipsecyyrindex |
---|
74 | #endif /* yyrindex */ |
---|
75 | |
---|
76 | #ifndef yygindex |
---|
77 | #define yygindex __libipsecyygindex |
---|
78 | #endif /* yygindex */ |
---|
79 | |
---|
80 | #ifndef yytable |
---|
81 | #define yytable __libipsecyytable |
---|
82 | #endif /* yytable */ |
---|
83 | |
---|
84 | #ifndef yycheck |
---|
85 | #define yycheck __libipsecyycheck |
---|
86 | #endif /* yycheck */ |
---|
87 | |
---|
88 | #ifndef yyname |
---|
89 | #define yyname __libipsecyyname |
---|
90 | #endif /* yyname */ |
---|
91 | |
---|
92 | #ifndef yyrule |
---|
93 | #define yyrule __libipsecyyrule |
---|
94 | #endif /* yyrule */ |
---|
95 | #define YYPREFIX "__libipsecyy" |
---|
96 | |
---|
97 | #define YYPURE 0 |
---|
98 | |
---|
99 | #line 52 "lib/libipsec/policy_parse.y" |
---|
100 | #include <sys/cdefs.h> |
---|
101 | __FBSDID("$FreeBSD$"); |
---|
102 | |
---|
103 | #include <sys/types.h> |
---|
104 | #include <sys/param.h> |
---|
105 | #include <sys/socket.h> |
---|
106 | |
---|
107 | #include <netinet/in.h> |
---|
108 | #ifdef __rtems__ |
---|
109 | #include <freebsd/netipsec/ipsec.h> |
---|
110 | #else |
---|
111 | #include <netipsec/ipsec.h> |
---|
112 | #endif |
---|
113 | |
---|
114 | #include <stdlib.h> |
---|
115 | #include <stdio.h> |
---|
116 | #include <string.h> |
---|
117 | #include <netdb.h> |
---|
118 | |
---|
119 | #include "ipsec_strerror.h" |
---|
120 | |
---|
121 | #define ATOX(c) \ |
---|
122 | (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) |
---|
123 | |
---|
124 | static caddr_t pbuf = NULL; /* sadb_x_policy buffer */ |
---|
125 | static int tlen = 0; /* total length of pbuf */ |
---|
126 | static int offset = 0; /* offset of pbuf */ |
---|
127 | static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid; |
---|
128 | static struct sockaddr *p_src = NULL; |
---|
129 | static struct sockaddr *p_dst = NULL; |
---|
130 | |
---|
131 | struct _val; |
---|
132 | extern void yyerror(char *msg); |
---|
133 | static struct sockaddr *parse_sockaddr(struct _val *buf); |
---|
134 | static int rule_check(void); |
---|
135 | static int init_x_policy(void); |
---|
136 | static int set_x_request(struct sockaddr *src, struct sockaddr *dst); |
---|
137 | static int set_sockaddr(struct sockaddr *addr); |
---|
138 | static void policy_parse_request_init(void); |
---|
139 | static caddr_t policy_parse(char *msg, int msglen); |
---|
140 | |
---|
141 | extern void __policy__strbuffer__init__(char *msg); |
---|
142 | extern void __policy__strbuffer__free__(void); |
---|
143 | extern int yyparse(void); |
---|
144 | extern int yylex(void); |
---|
145 | |
---|
146 | extern char *__libipsecyytext; /*XXX*/ |
---|
147 | |
---|
148 | #line 102 "lib/libipsec/policy_parse.y" |
---|
149 | #ifdef YYSTYPE |
---|
150 | #undef YYSTYPE_IS_DECLARED |
---|
151 | #define YYSTYPE_IS_DECLARED 1 |
---|
152 | #endif |
---|
153 | #ifndef YYSTYPE_IS_DECLARED |
---|
154 | #define YYSTYPE_IS_DECLARED 1 |
---|
155 | typedef union { |
---|
156 | u_int num; |
---|
157 | struct _val { |
---|
158 | int len; |
---|
159 | char *buf; |
---|
160 | } val; |
---|
161 | } YYSTYPE; |
---|
162 | #endif /* !YYSTYPE_IS_DECLARED */ |
---|
163 | #line 163 "lib/libipsec/policy_parse.i" |
---|
164 | /* compatibility with bison */ |
---|
165 | #ifdef YYPARSE_PARAM |
---|
166 | /* compatibility with FreeBSD */ |
---|
167 | # ifdef YYPARSE_PARAM_TYPE |
---|
168 | # define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) |
---|
169 | # else |
---|
170 | # define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) |
---|
171 | # endif |
---|
172 | #else |
---|
173 | # define YYPARSE_DECL() yyparse(void) |
---|
174 | #endif |
---|
175 | |
---|
176 | /* Parameters sent to lex. */ |
---|
177 | #ifdef YYLEX_PARAM |
---|
178 | # define YYLEX_DECL() yylex(void *YYLEX_PARAM) |
---|
179 | # define YYLEX yylex(YYLEX_PARAM) |
---|
180 | #else |
---|
181 | # define YYLEX_DECL() yylex(void) |
---|
182 | # define YYLEX yylex() |
---|
183 | #endif |
---|
184 | |
---|
185 | /* Parameters sent to yyerror. */ |
---|
186 | #define YYERROR_DECL() yyerror(const char *s) |
---|
187 | #define YYERROR_CALL(msg) yyerror(msg) |
---|
188 | |
---|
189 | extern int YYPARSE_DECL(); |
---|
190 | |
---|
191 | #define DIR 257 |
---|
192 | #define ACTION 258 |
---|
193 | #define PROTOCOL 259 |
---|
194 | #define MODE 260 |
---|
195 | #define LEVEL 261 |
---|
196 | #define LEVEL_SPECIFY 262 |
---|
197 | #define IPADDRESS 263 |
---|
198 | #define ME 264 |
---|
199 | #define ANY 265 |
---|
200 | #define SLASH 266 |
---|
201 | #define HYPHEN 267 |
---|
202 | #define YYERRCODE 256 |
---|
203 | static const short __libipsecyylhs[] = { -1, |
---|
204 | 2, 0, 0, 1, 1, 3, 3, 3, 3, 3, |
---|
205 | 3, 3, 3, 4, 5, 7, 7, 8, 6, 6, |
---|
206 | 6, |
---|
207 | }; |
---|
208 | static const short __libipsecyylen[] = { 2, |
---|
209 | 0, 4, 1, 0, 2, 7, 6, 5, 4, 6, |
---|
210 | 3, 2, 1, 1, 1, 1, 1, 0, 4, 3, |
---|
211 | 3, |
---|
212 | }; |
---|
213 | static const short __libipsecyydefred[] = { 0, |
---|
214 | 0, 0, 1, 4, 0, 14, 5, 0, 0, 15, |
---|
215 | 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, |
---|
216 | 16, 17, 10, 0, 0, 20, 21, 6, 19, |
---|
217 | }; |
---|
218 | static const short __libipsecyydgoto[] = { 2, |
---|
219 | 5, 4, 7, 8, 11, 17, 23, 18, |
---|
220 | }; |
---|
221 | static const short __libipsecyysindex[] = { -257, |
---|
222 | -245, 0, 0, 0, -244, 0, 0, -252, -243, 0, |
---|
223 | -248, -256, 0, -251, -247, -250, -242, -246, -240, -241, |
---|
224 | 0, 0, 0, -250, -237, 0, 0, 0, 0, |
---|
225 | }; |
---|
226 | static const short __libipsecyyrindex[] = { 0, |
---|
227 | 19, 0, 0, 0, 22, 0, 0, 1, 2, 0, |
---|
228 | 3, 4, 0, 0, 0, 0, 5, 0, 0, 0, |
---|
229 | 0, 0, 0, 6, 0, 0, 0, 0, 0, |
---|
230 | }; |
---|
231 | static const short __libipsecyygindex[] = { 0, |
---|
232 | 0, 0, 0, 0, 0, 0, 7, 0, |
---|
233 | }; |
---|
234 | #define YYTABLESIZE 265 |
---|
235 | static const short __libipsecyytable[] = { 1, |
---|
236 | 13, 12, 11, 9, 8, 7, 13, 14, 15, 16, |
---|
237 | 21, 22, 3, 9, 6, 19, 10, 12, 3, 20, |
---|
238 | 25, 2, 27, 24, 26, 29, 0, 0, 0, 0, |
---|
239 | 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
240 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
241 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
242 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
243 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
244 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
245 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
246 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
247 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
248 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
249 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
250 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
251 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
252 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
253 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
254 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
255 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
256 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
257 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
258 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
259 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
260 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
261 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, |
---|
262 | 12, 11, 9, 8, 7, |
---|
263 | }; |
---|
264 | static const short __libipsecyycheck[] = { 257, |
---|
265 | 0, 0, 0, 0, 0, 0, 263, 264, 265, 266, |
---|
266 | 261, 262, 258, 266, 259, 267, 260, 266, 0, 267, |
---|
267 | 267, 0, 264, 266, 265, 263, -1, -1, -1, -1, |
---|
268 | 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
269 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
270 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
271 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
272 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
273 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
274 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
275 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
276 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
277 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
278 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
279 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
280 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
281 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
282 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
283 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
284 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
285 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
286 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
287 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
288 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
289 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
---|
290 | -1, -1, -1, -1, -1, -1, -1, -1, -1, 259, |
---|
291 | 259, 259, 259, 259, 259, |
---|
292 | }; |
---|
293 | #define YYFINAL 2 |
---|
294 | #ifndef YYDEBUG |
---|
295 | #define YYDEBUG 0 |
---|
296 | #endif |
---|
297 | #define YYMAXTOKEN 267 |
---|
298 | #if YYDEBUG |
---|
299 | static const char *yyname[] = { |
---|
300 | |
---|
301 | "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
302 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
303 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
304 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
305 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
306 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
---|
307 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DIR","ACTION","PROTOCOL","MODE", |
---|
308 | "LEVEL","LEVEL_SPECIFY","IPADDRESS","ME","ANY","SLASH","HYPHEN", |
---|
309 | }; |
---|
310 | static const char *yyrule[] = { |
---|
311 | "$accept : policy_spec", |
---|
312 | "$$1 :", |
---|
313 | "policy_spec : DIR ACTION $$1 rules", |
---|
314 | "policy_spec : DIR", |
---|
315 | "rules :", |
---|
316 | "rules : rules rule", |
---|
317 | "rule : protocol SLASH mode SLASH addresses SLASH level", |
---|
318 | "rule : protocol SLASH mode SLASH addresses SLASH", |
---|
319 | "rule : protocol SLASH mode SLASH addresses", |
---|
320 | "rule : protocol SLASH mode SLASH", |
---|
321 | "rule : protocol SLASH mode SLASH SLASH level", |
---|
322 | "rule : protocol SLASH mode", |
---|
323 | "rule : protocol SLASH", |
---|
324 | "rule : protocol", |
---|
325 | "protocol : PROTOCOL", |
---|
326 | "mode : MODE", |
---|
327 | "level : LEVEL", |
---|
328 | "level : LEVEL_SPECIFY", |
---|
329 | "$$2 :", |
---|
330 | "addresses : IPADDRESS $$2 HYPHEN IPADDRESS", |
---|
331 | "addresses : ME HYPHEN ANY", |
---|
332 | "addresses : ANY HYPHEN ME", |
---|
333 | |
---|
334 | }; |
---|
335 | #endif |
---|
336 | /* define the initial stack-sizes */ |
---|
337 | #ifdef YYSTACKSIZE |
---|
338 | #undef YYMAXDEPTH |
---|
339 | #define YYMAXDEPTH YYSTACKSIZE |
---|
340 | #else |
---|
341 | #ifdef YYMAXDEPTH |
---|
342 | #define YYSTACKSIZE YYMAXDEPTH |
---|
343 | #else |
---|
344 | #define YYSTACKSIZE 500 |
---|
345 | #define YYMAXDEPTH 500 |
---|
346 | #endif |
---|
347 | #endif |
---|
348 | |
---|
349 | #define YYINITSTACKSIZE 500 |
---|
350 | |
---|
351 | int yydebug; |
---|
352 | int yynerrs; |
---|
353 | |
---|
354 | typedef struct { |
---|
355 | unsigned stacksize; |
---|
356 | short *s_base; |
---|
357 | short *s_mark; |
---|
358 | short *s_last; |
---|
359 | YYSTYPE *l_base; |
---|
360 | YYSTYPE *l_mark; |
---|
361 | } YYSTACKDATA; |
---|
362 | int yyerrflag; |
---|
363 | int yychar; |
---|
364 | YYSTYPE yyval; |
---|
365 | YYSTYPE yylval; |
---|
366 | |
---|
367 | /* variables for the parser stack */ |
---|
368 | static YYSTACKDATA yystack; |
---|
369 | #line 217 "lib/libipsec/policy_parse.y" |
---|
370 | |
---|
371 | void |
---|
372 | yyerror(msg) |
---|
373 | char *msg; |
---|
374 | { |
---|
375 | fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", |
---|
376 | msg, __libipsecyytext); |
---|
377 | |
---|
378 | return; |
---|
379 | } |
---|
380 | |
---|
381 | static struct sockaddr * |
---|
382 | parse_sockaddr(buf) |
---|
383 | struct _val *buf; |
---|
384 | { |
---|
385 | struct addrinfo hints, *res; |
---|
386 | char *serv = NULL; |
---|
387 | int error; |
---|
388 | struct sockaddr *newaddr = NULL; |
---|
389 | |
---|
390 | memset(&hints, 0, sizeof(hints)); |
---|
391 | hints.ai_family = PF_UNSPEC; |
---|
392 | hints.ai_flags = AI_NUMERICHOST; |
---|
393 | error = getaddrinfo(buf->buf, serv, &hints, &res); |
---|
394 | if (error != 0) { |
---|
395 | yyerror("invalid IP address"); |
---|
396 | __ipsec_set_strerror(gai_strerror(error)); |
---|
397 | return NULL; |
---|
398 | } |
---|
399 | |
---|
400 | if (res->ai_addr == NULL) { |
---|
401 | yyerror("invalid IP address"); |
---|
402 | __ipsec_set_strerror(gai_strerror(error)); |
---|
403 | return NULL; |
---|
404 | } |
---|
405 | |
---|
406 | newaddr = malloc(res->ai_addr->sa_len); |
---|
407 | if (newaddr == NULL) { |
---|
408 | __ipsec_errcode = EIPSEC_NO_BUFS; |
---|
409 | freeaddrinfo(res); |
---|
410 | return NULL; |
---|
411 | } |
---|
412 | memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len); |
---|
413 | |
---|
414 | freeaddrinfo(res); |
---|
415 | |
---|
416 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
417 | return newaddr; |
---|
418 | } |
---|
419 | |
---|
420 | static int |
---|
421 | rule_check() |
---|
422 | { |
---|
423 | if (p_type == IPSEC_POLICY_IPSEC) { |
---|
424 | if (p_protocol == IPPROTO_IP) { |
---|
425 | __ipsec_errcode = EIPSEC_NO_PROTO; |
---|
426 | return -1; |
---|
427 | } |
---|
428 | |
---|
429 | if (p_mode != IPSEC_MODE_TRANSPORT |
---|
430 | && p_mode != IPSEC_MODE_TUNNEL) { |
---|
431 | __ipsec_errcode = EIPSEC_INVAL_MODE; |
---|
432 | return -1; |
---|
433 | } |
---|
434 | |
---|
435 | if (p_src == NULL && p_dst == NULL) { |
---|
436 | if (p_mode != IPSEC_MODE_TRANSPORT) { |
---|
437 | __ipsec_errcode = EIPSEC_INVAL_ADDRESS; |
---|
438 | return -1; |
---|
439 | } |
---|
440 | } |
---|
441 | else if (p_src->sa_family != p_dst->sa_family) { |
---|
442 | __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; |
---|
443 | return -1; |
---|
444 | } |
---|
445 | } |
---|
446 | |
---|
447 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
448 | return 0; |
---|
449 | } |
---|
450 | |
---|
451 | static int |
---|
452 | init_x_policy() |
---|
453 | { |
---|
454 | struct sadb_x_policy *p; |
---|
455 | |
---|
456 | tlen = sizeof(struct sadb_x_policy); |
---|
457 | |
---|
458 | pbuf = malloc(tlen); |
---|
459 | if (pbuf == NULL) { |
---|
460 | __ipsec_errcode = EIPSEC_NO_BUFS; |
---|
461 | return -1; |
---|
462 | } |
---|
463 | memset(pbuf, 0, tlen); |
---|
464 | p = (struct sadb_x_policy *)pbuf; |
---|
465 | p->sadb_x_policy_len = 0; /* must update later */ |
---|
466 | p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; |
---|
467 | p->sadb_x_policy_type = p_type; |
---|
468 | p->sadb_x_policy_dir = p_dir; |
---|
469 | p->sadb_x_policy_id = 0; |
---|
470 | |
---|
471 | offset = tlen; |
---|
472 | |
---|
473 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
474 | return 0; |
---|
475 | } |
---|
476 | |
---|
477 | static int |
---|
478 | set_x_request(src, dst) |
---|
479 | struct sockaddr *src, *dst; |
---|
480 | { |
---|
481 | struct sadb_x_ipsecrequest *p; |
---|
482 | int reqlen; |
---|
483 | |
---|
484 | reqlen = sizeof(*p) |
---|
485 | + (src ? src->sa_len : 0) |
---|
486 | + (dst ? dst->sa_len : 0); |
---|
487 | tlen += reqlen; /* increment to total length */ |
---|
488 | |
---|
489 | pbuf = realloc(pbuf, tlen); |
---|
490 | if (pbuf == NULL) { |
---|
491 | __ipsec_errcode = EIPSEC_NO_BUFS; |
---|
492 | return -1; |
---|
493 | } |
---|
494 | p = (struct sadb_x_ipsecrequest *)&pbuf[offset]; |
---|
495 | p->sadb_x_ipsecrequest_len = reqlen; |
---|
496 | p->sadb_x_ipsecrequest_proto = p_protocol; |
---|
497 | p->sadb_x_ipsecrequest_mode = p_mode; |
---|
498 | p->sadb_x_ipsecrequest_level = p_level; |
---|
499 | p->sadb_x_ipsecrequest_reqid = p_reqid; |
---|
500 | offset += sizeof(*p); |
---|
501 | |
---|
502 | if (set_sockaddr(src) || set_sockaddr(dst)) |
---|
503 | return -1; |
---|
504 | |
---|
505 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
506 | return 0; |
---|
507 | } |
---|
508 | |
---|
509 | static int |
---|
510 | set_sockaddr(addr) |
---|
511 | struct sockaddr *addr; |
---|
512 | { |
---|
513 | if (addr == NULL) { |
---|
514 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
515 | return 0; |
---|
516 | } |
---|
517 | |
---|
518 | /* tlen has already incremented */ |
---|
519 | |
---|
520 | memcpy(&pbuf[offset], addr, addr->sa_len); |
---|
521 | |
---|
522 | offset += addr->sa_len; |
---|
523 | |
---|
524 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
525 | return 0; |
---|
526 | } |
---|
527 | |
---|
528 | static void |
---|
529 | policy_parse_request_init() |
---|
530 | { |
---|
531 | p_protocol = IPPROTO_IP; |
---|
532 | p_mode = IPSEC_MODE_ANY; |
---|
533 | p_level = IPSEC_LEVEL_DEFAULT; |
---|
534 | p_reqid = 0; |
---|
535 | if (p_src != NULL) { |
---|
536 | free(p_src); |
---|
537 | p_src = NULL; |
---|
538 | } |
---|
539 | if (p_dst != NULL) { |
---|
540 | free(p_dst); |
---|
541 | p_dst = NULL; |
---|
542 | } |
---|
543 | |
---|
544 | return; |
---|
545 | } |
---|
546 | |
---|
547 | static caddr_t |
---|
548 | policy_parse(msg, msglen) |
---|
549 | char *msg; |
---|
550 | int msglen; |
---|
551 | { |
---|
552 | int error; |
---|
553 | pbuf = NULL; |
---|
554 | tlen = 0; |
---|
555 | |
---|
556 | /* initialize */ |
---|
557 | p_dir = IPSEC_DIR_INVALID; |
---|
558 | p_type = IPSEC_POLICY_DISCARD; |
---|
559 | policy_parse_request_init(); |
---|
560 | __policy__strbuffer__init__(msg); |
---|
561 | |
---|
562 | error = yyparse(); /* it must be set errcode. */ |
---|
563 | __policy__strbuffer__free__(); |
---|
564 | |
---|
565 | if (error) { |
---|
566 | if (pbuf != NULL) |
---|
567 | free(pbuf); |
---|
568 | return NULL; |
---|
569 | } |
---|
570 | |
---|
571 | /* update total length */ |
---|
572 | ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen); |
---|
573 | |
---|
574 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
575 | |
---|
576 | return pbuf; |
---|
577 | } |
---|
578 | |
---|
579 | caddr_t |
---|
580 | ipsec_set_policy(msg, msglen) |
---|
581 | char *msg; |
---|
582 | int msglen; |
---|
583 | { |
---|
584 | caddr_t policy; |
---|
585 | |
---|
586 | policy = policy_parse(msg, msglen); |
---|
587 | if (policy == NULL) { |
---|
588 | if (__ipsec_errcode == EIPSEC_NO_ERROR) |
---|
589 | __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; |
---|
590 | return NULL; |
---|
591 | } |
---|
592 | |
---|
593 | __ipsec_errcode = EIPSEC_NO_ERROR; |
---|
594 | return policy; |
---|
595 | } |
---|
596 | |
---|
597 | #line 597 "lib/libipsec/policy_parse.i" |
---|
598 | |
---|
599 | #if YYDEBUG |
---|
600 | #include <stdio.h> /* needed for printf */ |
---|
601 | #endif |
---|
602 | |
---|
603 | #include <stdlib.h> /* needed for malloc, etc */ |
---|
604 | #include <string.h> /* needed for memset */ |
---|
605 | |
---|
606 | /* allocate initial stack or double stack size, up to YYMAXDEPTH */ |
---|
607 | static int yygrowstack(YYSTACKDATA *data) |
---|
608 | { |
---|
609 | int i; |
---|
610 | unsigned newsize; |
---|
611 | short *newss; |
---|
612 | YYSTYPE *newvs; |
---|
613 | |
---|
614 | if ((newsize = data->stacksize) == 0) |
---|
615 | newsize = YYINITSTACKSIZE; |
---|
616 | else if (newsize >= YYMAXDEPTH) |
---|
617 | return -1; |
---|
618 | else if ((newsize *= 2) > YYMAXDEPTH) |
---|
619 | newsize = YYMAXDEPTH; |
---|
620 | |
---|
621 | i = data->s_mark - data->s_base; |
---|
622 | newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); |
---|
623 | if (newss == 0) |
---|
624 | return -1; |
---|
625 | |
---|
626 | data->s_base = newss; |
---|
627 | data->s_mark = newss + i; |
---|
628 | |
---|
629 | newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); |
---|
630 | if (newvs == 0) |
---|
631 | return -1; |
---|
632 | |
---|
633 | data->l_base = newvs; |
---|
634 | data->l_mark = newvs + i; |
---|
635 | |
---|
636 | data->stacksize = newsize; |
---|
637 | data->s_last = data->s_base + newsize - 1; |
---|
638 | return 0; |
---|
639 | } |
---|
640 | |
---|
641 | #if YYPURE || defined(YY_NO_LEAKS) |
---|
642 | static void yyfreestack(YYSTACKDATA *data) |
---|
643 | { |
---|
644 | free(data->s_base); |
---|
645 | free(data->l_base); |
---|
646 | memset(data, 0, sizeof(*data)); |
---|
647 | } |
---|
648 | #else |
---|
649 | #define yyfreestack(data) /* nothing */ |
---|
650 | #endif |
---|
651 | |
---|
652 | #define YYABORT goto yyabort |
---|
653 | #define YYREJECT goto yyabort |
---|
654 | #define YYACCEPT goto yyaccept |
---|
655 | #define YYERROR goto yyerrlab |
---|
656 | |
---|
657 | int |
---|
658 | YYPARSE_DECL() |
---|
659 | { |
---|
660 | int yym, yyn, yystate; |
---|
661 | #if YYDEBUG |
---|
662 | const char *yys; |
---|
663 | |
---|
664 | if ((yys = getenv("YYDEBUG")) != 0) |
---|
665 | { |
---|
666 | yyn = *yys; |
---|
667 | if (yyn >= '0' && yyn <= '9') |
---|
668 | yydebug = yyn - '0'; |
---|
669 | } |
---|
670 | #endif |
---|
671 | |
---|
672 | yynerrs = 0; |
---|
673 | yyerrflag = 0; |
---|
674 | yychar = YYEMPTY; |
---|
675 | yystate = 0; |
---|
676 | |
---|
677 | #if YYPURE |
---|
678 | memset(&yystack, 0, sizeof(yystack)); |
---|
679 | #endif |
---|
680 | |
---|
681 | if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; |
---|
682 | yystack.s_mark = yystack.s_base; |
---|
683 | yystack.l_mark = yystack.l_base; |
---|
684 | yystate = 0; |
---|
685 | *yystack.s_mark = 0; |
---|
686 | |
---|
687 | yyloop: |
---|
688 | if ((yyn = yydefred[yystate]) != 0) goto yyreduce; |
---|
689 | if (yychar < 0) |
---|
690 | { |
---|
691 | if ((yychar = YYLEX) < 0) yychar = 0; |
---|
692 | #if YYDEBUG |
---|
693 | if (yydebug) |
---|
694 | { |
---|
695 | yys = 0; |
---|
696 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
---|
697 | if (!yys) yys = "illegal-symbol"; |
---|
698 | printf("%sdebug: state %d, reading %d (%s)\n", |
---|
699 | YYPREFIX, yystate, yychar, yys); |
---|
700 | } |
---|
701 | #endif |
---|
702 | } |
---|
703 | if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && |
---|
704 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
---|
705 | { |
---|
706 | #if YYDEBUG |
---|
707 | if (yydebug) |
---|
708 | printf("%sdebug: state %d, shifting to state %d\n", |
---|
709 | YYPREFIX, yystate, yytable[yyn]); |
---|
710 | #endif |
---|
711 | if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) |
---|
712 | { |
---|
713 | goto yyoverflow; |
---|
714 | } |
---|
715 | yystate = yytable[yyn]; |
---|
716 | *++yystack.s_mark = yytable[yyn]; |
---|
717 | *++yystack.l_mark = yylval; |
---|
718 | yychar = YYEMPTY; |
---|
719 | if (yyerrflag > 0) --yyerrflag; |
---|
720 | goto yyloop; |
---|
721 | } |
---|
722 | if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && |
---|
723 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
---|
724 | { |
---|
725 | yyn = yytable[yyn]; |
---|
726 | goto yyreduce; |
---|
727 | } |
---|
728 | if (yyerrflag) goto yyinrecovery; |
---|
729 | |
---|
730 | yyerror("syntax error"); |
---|
731 | |
---|
732 | goto yyerrlab; |
---|
733 | |
---|
734 | yyerrlab: |
---|
735 | ++yynerrs; |
---|
736 | |
---|
737 | yyinrecovery: |
---|
738 | if (yyerrflag < 3) |
---|
739 | { |
---|
740 | yyerrflag = 3; |
---|
741 | for (;;) |
---|
742 | { |
---|
743 | if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && |
---|
744 | yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) |
---|
745 | { |
---|
746 | #if YYDEBUG |
---|
747 | if (yydebug) |
---|
748 | printf("%sdebug: state %d, error recovery shifting\ |
---|
749 | to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); |
---|
750 | #endif |
---|
751 | if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) |
---|
752 | { |
---|
753 | goto yyoverflow; |
---|
754 | } |
---|
755 | yystate = yytable[yyn]; |
---|
756 | *++yystack.s_mark = yytable[yyn]; |
---|
757 | *++yystack.l_mark = yylval; |
---|
758 | goto yyloop; |
---|
759 | } |
---|
760 | else |
---|
761 | { |
---|
762 | #if YYDEBUG |
---|
763 | if (yydebug) |
---|
764 | printf("%sdebug: error recovery discarding state %d\n", |
---|
765 | YYPREFIX, *yystack.s_mark); |
---|
766 | #endif |
---|
767 | if (yystack.s_mark <= yystack.s_base) goto yyabort; |
---|
768 | --yystack.s_mark; |
---|
769 | --yystack.l_mark; |
---|
770 | } |
---|
771 | } |
---|
772 | } |
---|
773 | else |
---|
774 | { |
---|
775 | if (yychar == 0) goto yyabort; |
---|
776 | #if YYDEBUG |
---|
777 | if (yydebug) |
---|
778 | { |
---|
779 | yys = 0; |
---|
780 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
---|
781 | if (!yys) yys = "illegal-symbol"; |
---|
782 | printf("%sdebug: state %d, error recovery discards token %d (%s)\n", |
---|
783 | YYPREFIX, yystate, yychar, yys); |
---|
784 | } |
---|
785 | #endif |
---|
786 | yychar = YYEMPTY; |
---|
787 | goto yyloop; |
---|
788 | } |
---|
789 | |
---|
790 | yyreduce: |
---|
791 | #if YYDEBUG |
---|
792 | if (yydebug) |
---|
793 | printf("%sdebug: state %d, reducing by rule %d (%s)\n", |
---|
794 | YYPREFIX, yystate, yyn, yyrule[yyn]); |
---|
795 | #endif |
---|
796 | yym = yylen[yyn]; |
---|
797 | if (yym) |
---|
798 | yyval = yystack.l_mark[1-yym]; |
---|
799 | else |
---|
800 | memset(&yyval, 0, sizeof yyval); |
---|
801 | switch (yyn) |
---|
802 | { |
---|
803 | case 1: |
---|
804 | #line 120 "lib/libipsec/policy_parse.y" |
---|
805 | { |
---|
806 | p_dir = yystack.l_mark[-1].num; |
---|
807 | p_type = yystack.l_mark[0].num; |
---|
808 | |
---|
809 | if (init_x_policy()) |
---|
810 | return -1; |
---|
811 | } |
---|
812 | break; |
---|
813 | case 3: |
---|
814 | #line 129 "lib/libipsec/policy_parse.y" |
---|
815 | { |
---|
816 | p_dir = yystack.l_mark[0].num; |
---|
817 | p_type = 0; /* ignored it by kernel */ |
---|
818 | |
---|
819 | if (init_x_policy()) |
---|
820 | return -1; |
---|
821 | } |
---|
822 | break; |
---|
823 | case 5: |
---|
824 | #line 140 "lib/libipsec/policy_parse.y" |
---|
825 | { |
---|
826 | if (rule_check() < 0) |
---|
827 | return -1; |
---|
828 | |
---|
829 | if (set_x_request(p_src, p_dst) < 0) |
---|
830 | return -1; |
---|
831 | |
---|
832 | policy_parse_request_init(); |
---|
833 | } |
---|
834 | break; |
---|
835 | case 12: |
---|
836 | #line 158 "lib/libipsec/policy_parse.y" |
---|
837 | { |
---|
838 | __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; |
---|
839 | return -1; |
---|
840 | } |
---|
841 | break; |
---|
842 | case 13: |
---|
843 | #line 162 "lib/libipsec/policy_parse.y" |
---|
844 | { |
---|
845 | __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; |
---|
846 | return -1; |
---|
847 | } |
---|
848 | break; |
---|
849 | case 14: |
---|
850 | #line 169 "lib/libipsec/policy_parse.y" |
---|
851 | { p_protocol = yystack.l_mark[0].num; } |
---|
852 | break; |
---|
853 | case 15: |
---|
854 | #line 173 "lib/libipsec/policy_parse.y" |
---|
855 | { p_mode = yystack.l_mark[0].num; } |
---|
856 | break; |
---|
857 | case 16: |
---|
858 | #line 177 "lib/libipsec/policy_parse.y" |
---|
859 | { |
---|
860 | p_level = yystack.l_mark[0].num; |
---|
861 | p_reqid = 0; |
---|
862 | } |
---|
863 | break; |
---|
864 | case 17: |
---|
865 | #line 181 "lib/libipsec/policy_parse.y" |
---|
866 | { |
---|
867 | p_level = IPSEC_LEVEL_UNIQUE; |
---|
868 | p_reqid = atol(yystack.l_mark[0].val.buf); /* atol() is good. */ |
---|
869 | } |
---|
870 | break; |
---|
871 | case 18: |
---|
872 | #line 188 "lib/libipsec/policy_parse.y" |
---|
873 | { |
---|
874 | p_src = parse_sockaddr(&yystack.l_mark[0].val); |
---|
875 | if (p_src == NULL) |
---|
876 | return -1; |
---|
877 | } |
---|
878 | break; |
---|
879 | case 19: |
---|
880 | #line 194 "lib/libipsec/policy_parse.y" |
---|
881 | { |
---|
882 | p_dst = parse_sockaddr(&yystack.l_mark[0].val); |
---|
883 | if (p_dst == NULL) |
---|
884 | return -1; |
---|
885 | } |
---|
886 | break; |
---|
887 | case 20: |
---|
888 | #line 199 "lib/libipsec/policy_parse.y" |
---|
889 | { |
---|
890 | if (p_dir != IPSEC_DIR_OUTBOUND) { |
---|
891 | __ipsec_errcode = EIPSEC_INVAL_DIR; |
---|
892 | return -1; |
---|
893 | } |
---|
894 | } |
---|
895 | break; |
---|
896 | case 21: |
---|
897 | #line 205 "lib/libipsec/policy_parse.y" |
---|
898 | { |
---|
899 | if (p_dir != IPSEC_DIR_INBOUND) { |
---|
900 | __ipsec_errcode = EIPSEC_INVAL_DIR; |
---|
901 | return -1; |
---|
902 | } |
---|
903 | } |
---|
904 | break; |
---|
905 | #line 905 "lib/libipsec/policy_parse.i" |
---|
906 | } |
---|
907 | yystack.s_mark -= yym; |
---|
908 | yystate = *yystack.s_mark; |
---|
909 | yystack.l_mark -= yym; |
---|
910 | yym = yylhs[yyn]; |
---|
911 | if (yystate == 0 && yym == 0) |
---|
912 | { |
---|
913 | #if YYDEBUG |
---|
914 | if (yydebug) |
---|
915 | printf("%sdebug: after reduction, shifting from state 0 to\ |
---|
916 | state %d\n", YYPREFIX, YYFINAL); |
---|
917 | #endif |
---|
918 | yystate = YYFINAL; |
---|
919 | *++yystack.s_mark = YYFINAL; |
---|
920 | *++yystack.l_mark = yyval; |
---|
921 | if (yychar < 0) |
---|
922 | { |
---|
923 | if ((yychar = YYLEX) < 0) yychar = 0; |
---|
924 | #if YYDEBUG |
---|
925 | if (yydebug) |
---|
926 | { |
---|
927 | yys = 0; |
---|
928 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
---|
929 | if (!yys) yys = "illegal-symbol"; |
---|
930 | printf("%sdebug: state %d, reading %d (%s)\n", |
---|
931 | YYPREFIX, YYFINAL, yychar, yys); |
---|
932 | } |
---|
933 | #endif |
---|
934 | } |
---|
935 | if (yychar == 0) goto yyaccept; |
---|
936 | goto yyloop; |
---|
937 | } |
---|
938 | if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && |
---|
939 | yyn <= YYTABLESIZE && yycheck[yyn] == yystate) |
---|
940 | yystate = yytable[yyn]; |
---|
941 | else |
---|
942 | yystate = yydgoto[yym]; |
---|
943 | #if YYDEBUG |
---|
944 | if (yydebug) |
---|
945 | printf("%sdebug: after reduction, shifting from state %d \ |
---|
946 | to state %d\n", YYPREFIX, *yystack.s_mark, yystate); |
---|
947 | #endif |
---|
948 | if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) |
---|
949 | { |
---|
950 | goto yyoverflow; |
---|
951 | } |
---|
952 | *++yystack.s_mark = (short) yystate; |
---|
953 | *++yystack.l_mark = yyval; |
---|
954 | goto yyloop; |
---|
955 | |
---|
956 | yyoverflow: |
---|
957 | yyerror("yacc stack overflow"); |
---|
958 | |
---|
959 | yyabort: |
---|
960 | yyfreestack(&yystack); |
---|
961 | return (1); |
---|
962 | |
---|
963 | yyaccept: |
---|
964 | yyfreestack(&yystack); |
---|
965 | return (0); |
---|
966 | } |
---|