1bd9f52d5SHajimu UMEMOTO /* $KAME: policy_parse.y,v 1.14 2003/06/27 03:39:20 itojun Exp $ */ 23c62e87aSJun-ichiro itojun Hagino 38a16b7a1SPedro F. Giffuni /*- 48a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 58a16b7a1SPedro F. Giffuni * 69a4365d0SYoshinobu Inoue * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 79a4365d0SYoshinobu Inoue * All rights reserved. 89a4365d0SYoshinobu Inoue * 99a4365d0SYoshinobu Inoue * Redistribution and use in source and binary forms, with or without 109a4365d0SYoshinobu Inoue * modification, are permitted provided that the following conditions 119a4365d0SYoshinobu Inoue * are met: 129a4365d0SYoshinobu Inoue * 1. Redistributions of source code must retain the above copyright 139a4365d0SYoshinobu Inoue * notice, this list of conditions and the following disclaimer. 149a4365d0SYoshinobu Inoue * 2. Redistributions in binary form must reproduce the above copyright 159a4365d0SYoshinobu Inoue * notice, this list of conditions and the following disclaimer in the 169a4365d0SYoshinobu Inoue * documentation and/or other materials provided with the distribution. 179a4365d0SYoshinobu Inoue * 3. Neither the name of the project nor the names of its contributors 189a4365d0SYoshinobu Inoue * may be used to endorse or promote products derived from this software 199a4365d0SYoshinobu Inoue * without specific prior written permission. 209a4365d0SYoshinobu Inoue * 219a4365d0SYoshinobu Inoue * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 229a4365d0SYoshinobu Inoue * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239a4365d0SYoshinobu Inoue * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249a4365d0SYoshinobu Inoue * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 259a4365d0SYoshinobu Inoue * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269a4365d0SYoshinobu Inoue * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279a4365d0SYoshinobu Inoue * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289a4365d0SYoshinobu Inoue * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299a4365d0SYoshinobu Inoue * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309a4365d0SYoshinobu Inoue * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319a4365d0SYoshinobu Inoue * SUCH DAMAGE. 329a4365d0SYoshinobu Inoue */ 339a4365d0SYoshinobu Inoue 349a4365d0SYoshinobu Inoue /* 359a4365d0SYoshinobu Inoue * IN/OUT bound policy configuration take place such below: 369a4365d0SYoshinobu Inoue * in <policy> 379a4365d0SYoshinobu Inoue * out <policy> 389a4365d0SYoshinobu Inoue * 399a4365d0SYoshinobu Inoue * <policy> is one of following: 409a4365d0SYoshinobu Inoue * "discard", "none", "ipsec <requests>", "entrust", "bypass", 419a4365d0SYoshinobu Inoue * 429a4365d0SYoshinobu Inoue * The following requests are accepted as <requests>: 439a4365d0SYoshinobu Inoue * 449a4365d0SYoshinobu Inoue * protocol/mode/src-dst/level 459a4365d0SYoshinobu Inoue * protocol/mode/src-dst parsed as protocol/mode/src-dst/default 469a4365d0SYoshinobu Inoue * protocol/mode/src-dst/ parsed as protocol/mode/src-dst/default 479a4365d0SYoshinobu Inoue * protocol/transport parsed as protocol/mode/any-any/default 489a4365d0SYoshinobu Inoue * protocol/transport//level parsed as protocol/mode/any-any/level 499a4365d0SYoshinobu Inoue * 509a4365d0SYoshinobu Inoue * You can concatenate these requests with either ' '(single space) or '\n'. 519a4365d0SYoshinobu Inoue */ 529a4365d0SYoshinobu Inoue 539a4365d0SYoshinobu Inoue %{ 54a2f733abSWarner Losh 559a4365d0SYoshinobu Inoue #include <sys/types.h> 569a4365d0SYoshinobu Inoue #include <sys/param.h> 579a4365d0SYoshinobu Inoue #include <sys/socket.h> 589a4365d0SYoshinobu Inoue 599a4365d0SYoshinobu Inoue #include <netinet/in.h> 608409aedfSGeorge V. Neville-Neil #include <netipsec/ipsec.h> 619a4365d0SYoshinobu Inoue 629a4365d0SYoshinobu Inoue #include <stdlib.h> 639a4365d0SYoshinobu Inoue #include <stdio.h> 649a4365d0SYoshinobu Inoue #include <string.h> 659a4365d0SYoshinobu Inoue #include <netdb.h> 669a4365d0SYoshinobu Inoue 679a4365d0SYoshinobu Inoue #include "ipsec_strerror.h" 689a4365d0SYoshinobu Inoue 699a4365d0SYoshinobu Inoue #define ATOX(c) \ 709a4365d0SYoshinobu Inoue (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) 719a4365d0SYoshinobu Inoue 729a4365d0SYoshinobu Inoue static caddr_t pbuf = NULL; /* sadb_x_policy buffer */ 739a4365d0SYoshinobu Inoue static int tlen = 0; /* total length of pbuf */ 749a4365d0SYoshinobu Inoue static int offset = 0; /* offset of pbuf */ 753c62e87aSJun-ichiro itojun Hagino static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid; 769a4365d0SYoshinobu Inoue static struct sockaddr *p_src = NULL; 779a4365d0SYoshinobu Inoue static struct sockaddr *p_dst = NULL; 789a4365d0SYoshinobu Inoue 793c62e87aSJun-ichiro itojun Hagino struct _val; 80*50ecbc51SLexi Winter extern void yyerror(const char *msg); 81*50ecbc51SLexi Winter static struct sockaddr *parse_sockaddr(const struct _val *buf); 8269160b1eSDavid E. O'Brien static int rule_check(void); 8369160b1eSDavid E. O'Brien static int init_x_policy(void); 8469160b1eSDavid E. O'Brien static int set_x_request(struct sockaddr *src, struct sockaddr *dst); 85*50ecbc51SLexi Winter static int set_sockaddr(const struct sockaddr *addr); 8669160b1eSDavid E. O'Brien static void policy_parse_request_init(void); 87*50ecbc51SLexi Winter static caddr_t policy_parse(const char *msg, int msglen); 889a4365d0SYoshinobu Inoue 89*50ecbc51SLexi Winter extern void __policy__strbuffer__init__(const char *msg); 90bd9f52d5SHajimu UMEMOTO extern void __policy__strbuffer__free__(void); 9169160b1eSDavid E. O'Brien extern int yylex(void); 929a4365d0SYoshinobu Inoue 93bd9f52d5SHajimu UMEMOTO extern char *__libipsecyytext; /*XXX*/ 94bd9f52d5SHajimu UMEMOTO 959a4365d0SYoshinobu Inoue %} 969a4365d0SYoshinobu Inoue 979a4365d0SYoshinobu Inoue %union { 989a4365d0SYoshinobu Inoue u_int num; 999a4365d0SYoshinobu Inoue struct _val { 1009a4365d0SYoshinobu Inoue int len; 1019a4365d0SYoshinobu Inoue char *buf; 1029a4365d0SYoshinobu Inoue } val; 1039a4365d0SYoshinobu Inoue } 1049a4365d0SYoshinobu Inoue 1053c62e87aSJun-ichiro itojun Hagino %token DIR ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY 1069a4365d0SYoshinobu Inoue %token IPADDRESS 1079a4365d0SYoshinobu Inoue %token ME ANY 1089a4365d0SYoshinobu Inoue %token SLASH HYPHEN 1099a4365d0SYoshinobu Inoue %type <num> DIR ACTION PROTOCOL MODE LEVEL 1103c62e87aSJun-ichiro itojun Hagino %type <val> IPADDRESS LEVEL_SPECIFY 1119a4365d0SYoshinobu Inoue 1129a4365d0SYoshinobu Inoue %% 1139a4365d0SYoshinobu Inoue policy_spec 1149a4365d0SYoshinobu Inoue : DIR ACTION 1159a4365d0SYoshinobu Inoue { 1169a4365d0SYoshinobu Inoue p_dir = $1; 1179a4365d0SYoshinobu Inoue p_type = $2; 1189a4365d0SYoshinobu Inoue 1199a4365d0SYoshinobu Inoue if (init_x_policy()) 1209a4365d0SYoshinobu Inoue return -1; 1219a4365d0SYoshinobu Inoue } 1229a4365d0SYoshinobu Inoue rules 1233c62e87aSJun-ichiro itojun Hagino | DIR 1243c62e87aSJun-ichiro itojun Hagino { 1253c62e87aSJun-ichiro itojun Hagino p_dir = $1; 1263c62e87aSJun-ichiro itojun Hagino p_type = 0; /* ignored it by kernel */ 1273c62e87aSJun-ichiro itojun Hagino 1283c62e87aSJun-ichiro itojun Hagino if (init_x_policy()) 1293c62e87aSJun-ichiro itojun Hagino return -1; 1303c62e87aSJun-ichiro itojun Hagino } 1319a4365d0SYoshinobu Inoue ; 1329a4365d0SYoshinobu Inoue 1339a4365d0SYoshinobu Inoue rules 1349a4365d0SYoshinobu Inoue : /*NOTHING*/ 1359a4365d0SYoshinobu Inoue | rules rule { 1369a4365d0SYoshinobu Inoue if (rule_check() < 0) 1379a4365d0SYoshinobu Inoue return -1; 1389a4365d0SYoshinobu Inoue 1399a4365d0SYoshinobu Inoue if (set_x_request(p_src, p_dst) < 0) 1409a4365d0SYoshinobu Inoue return -1; 1419a4365d0SYoshinobu Inoue 1429a4365d0SYoshinobu Inoue policy_parse_request_init(); 1439a4365d0SYoshinobu Inoue } 1449a4365d0SYoshinobu Inoue ; 1459a4365d0SYoshinobu Inoue 1469a4365d0SYoshinobu Inoue rule 1479a4365d0SYoshinobu Inoue : protocol SLASH mode SLASH addresses SLASH level 1489a4365d0SYoshinobu Inoue | protocol SLASH mode SLASH addresses SLASH 1499a4365d0SYoshinobu Inoue | protocol SLASH mode SLASH addresses 1509a4365d0SYoshinobu Inoue | protocol SLASH mode SLASH 1519a4365d0SYoshinobu Inoue | protocol SLASH mode SLASH SLASH level 1529a4365d0SYoshinobu Inoue | protocol SLASH mode 1539a4365d0SYoshinobu Inoue | protocol SLASH { 1543c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; 1559a4365d0SYoshinobu Inoue return -1; 1569a4365d0SYoshinobu Inoue } 1579a4365d0SYoshinobu Inoue | protocol { 1583c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; 1599a4365d0SYoshinobu Inoue return -1; 1609a4365d0SYoshinobu Inoue } 1619a4365d0SYoshinobu Inoue ; 1629a4365d0SYoshinobu Inoue 1639a4365d0SYoshinobu Inoue protocol 1649a4365d0SYoshinobu Inoue : PROTOCOL { p_protocol = $1; } 1659a4365d0SYoshinobu Inoue ; 1669a4365d0SYoshinobu Inoue 1679a4365d0SYoshinobu Inoue mode 1689a4365d0SYoshinobu Inoue : MODE { p_mode = $1; } 1699a4365d0SYoshinobu Inoue ; 1709a4365d0SYoshinobu Inoue 1719a4365d0SYoshinobu Inoue level 1723c62e87aSJun-ichiro itojun Hagino : LEVEL { 1733c62e87aSJun-ichiro itojun Hagino p_level = $1; 1743c62e87aSJun-ichiro itojun Hagino p_reqid = 0; 1753c62e87aSJun-ichiro itojun Hagino } 1763c62e87aSJun-ichiro itojun Hagino | LEVEL_SPECIFY { 1773c62e87aSJun-ichiro itojun Hagino p_level = IPSEC_LEVEL_UNIQUE; 1783c62e87aSJun-ichiro itojun Hagino p_reqid = atol($1.buf); /* atol() is good. */ 1793c62e87aSJun-ichiro itojun Hagino } 1809a4365d0SYoshinobu Inoue ; 1819a4365d0SYoshinobu Inoue 1829a4365d0SYoshinobu Inoue addresses 1839a4365d0SYoshinobu Inoue : IPADDRESS { 1849a4365d0SYoshinobu Inoue p_src = parse_sockaddr(&$1); 1859a4365d0SYoshinobu Inoue if (p_src == NULL) 1869a4365d0SYoshinobu Inoue return -1; 1879a4365d0SYoshinobu Inoue } 1889a4365d0SYoshinobu Inoue HYPHEN 1899a4365d0SYoshinobu Inoue IPADDRESS { 1909a4365d0SYoshinobu Inoue p_dst = parse_sockaddr(&$4); 1919a4365d0SYoshinobu Inoue if (p_dst == NULL) 1929a4365d0SYoshinobu Inoue return -1; 1939a4365d0SYoshinobu Inoue } 1949a4365d0SYoshinobu Inoue | ME HYPHEN ANY { 1959a4365d0SYoshinobu Inoue if (p_dir != IPSEC_DIR_OUTBOUND) { 1963c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_INVAL_DIR; 1979a4365d0SYoshinobu Inoue return -1; 1989a4365d0SYoshinobu Inoue } 1999a4365d0SYoshinobu Inoue } 2009a4365d0SYoshinobu Inoue | ANY HYPHEN ME { 2019a4365d0SYoshinobu Inoue if (p_dir != IPSEC_DIR_INBOUND) { 2023c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_INVAL_DIR; 2039a4365d0SYoshinobu Inoue return -1; 2049a4365d0SYoshinobu Inoue } 2059a4365d0SYoshinobu Inoue } 2069a4365d0SYoshinobu Inoue /* 2079a4365d0SYoshinobu Inoue | ME HYPHEN ME 2089a4365d0SYoshinobu Inoue */ 2099a4365d0SYoshinobu Inoue ; 2109a4365d0SYoshinobu Inoue 2119a4365d0SYoshinobu Inoue %% 2129a4365d0SYoshinobu Inoue 2139a4365d0SYoshinobu Inoue void 214*50ecbc51SLexi Winter yyerror(const char *msg) 2159a4365d0SYoshinobu Inoue { 2163c62e87aSJun-ichiro itojun Hagino fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", 2173c62e87aSJun-ichiro itojun Hagino msg, __libipsecyytext); 2189a4365d0SYoshinobu Inoue 2199a4365d0SYoshinobu Inoue return; 2209a4365d0SYoshinobu Inoue } 2219a4365d0SYoshinobu Inoue 2229a4365d0SYoshinobu Inoue static struct sockaddr * 223*50ecbc51SLexi Winter parse_sockaddr(const struct _val *buf) 2249a4365d0SYoshinobu Inoue { 2259a4365d0SYoshinobu Inoue struct addrinfo hints, *res; 2269a4365d0SYoshinobu Inoue char *serv = NULL; 2279a4365d0SYoshinobu Inoue int error; 2289a4365d0SYoshinobu Inoue struct sockaddr *newaddr = NULL; 2299a4365d0SYoshinobu Inoue 2309a4365d0SYoshinobu Inoue memset(&hints, 0, sizeof(hints)); 2319a4365d0SYoshinobu Inoue hints.ai_family = PF_UNSPEC; 2329a4365d0SYoshinobu Inoue hints.ai_flags = AI_NUMERICHOST; 2339a4365d0SYoshinobu Inoue error = getaddrinfo(buf->buf, serv, &hints, &res); 2343c62e87aSJun-ichiro itojun Hagino if (error != 0) { 2353c62e87aSJun-ichiro itojun Hagino yyerror("invalid IP address"); 2363c62e87aSJun-ichiro itojun Hagino __ipsec_set_strerror(gai_strerror(error)); 2379a4365d0SYoshinobu Inoue return NULL; 2389a4365d0SYoshinobu Inoue } 2399a4365d0SYoshinobu Inoue 2409a4365d0SYoshinobu Inoue if (res->ai_addr == NULL) { 2413c62e87aSJun-ichiro itojun Hagino yyerror("invalid IP address"); 2423c62e87aSJun-ichiro itojun Hagino __ipsec_set_strerror(gai_strerror(error)); 2439a4365d0SYoshinobu Inoue return NULL; 2449a4365d0SYoshinobu Inoue } 2459a4365d0SYoshinobu Inoue 2469a4365d0SYoshinobu Inoue newaddr = malloc(res->ai_addr->sa_len); 2479a4365d0SYoshinobu Inoue if (newaddr == NULL) { 2483c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_BUFS; 2499a4365d0SYoshinobu Inoue freeaddrinfo(res); 2509a4365d0SYoshinobu Inoue return NULL; 2519a4365d0SYoshinobu Inoue } 2529a4365d0SYoshinobu Inoue memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len); 2539a4365d0SYoshinobu Inoue 2549a4365d0SYoshinobu Inoue freeaddrinfo(res); 2559a4365d0SYoshinobu Inoue 2563c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 2579a4365d0SYoshinobu Inoue return newaddr; 2589a4365d0SYoshinobu Inoue } 2599a4365d0SYoshinobu Inoue 2609a4365d0SYoshinobu Inoue static int 26158436df3SMateusz Guzik rule_check(void) 2629a4365d0SYoshinobu Inoue { 2639a4365d0SYoshinobu Inoue if (p_type == IPSEC_POLICY_IPSEC) { 2649a4365d0SYoshinobu Inoue if (p_protocol == IPPROTO_IP) { 2653c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_PROTO; 2669a4365d0SYoshinobu Inoue return -1; 2679a4365d0SYoshinobu Inoue } 2689a4365d0SYoshinobu Inoue 2699a4365d0SYoshinobu Inoue if (p_mode != IPSEC_MODE_TRANSPORT 2709a4365d0SYoshinobu Inoue && p_mode != IPSEC_MODE_TUNNEL) { 2713c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_INVAL_MODE; 2729a4365d0SYoshinobu Inoue return -1; 2739a4365d0SYoshinobu Inoue } 2749a4365d0SYoshinobu Inoue 2759a4365d0SYoshinobu Inoue if (p_src == NULL && p_dst == NULL) { 2769a4365d0SYoshinobu Inoue if (p_mode != IPSEC_MODE_TRANSPORT) { 2773c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_INVAL_ADDRESS; 2789a4365d0SYoshinobu Inoue return -1; 2799a4365d0SYoshinobu Inoue } 2809a4365d0SYoshinobu Inoue } 2819a4365d0SYoshinobu Inoue else if (p_src->sa_family != p_dst->sa_family) { 2823c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 2839a4365d0SYoshinobu Inoue return -1; 2849a4365d0SYoshinobu Inoue } 2859a4365d0SYoshinobu Inoue } 2869a4365d0SYoshinobu Inoue 2873c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 2889a4365d0SYoshinobu Inoue return 0; 2899a4365d0SYoshinobu Inoue } 2909a4365d0SYoshinobu Inoue 2919a4365d0SYoshinobu Inoue static int 29258436df3SMateusz Guzik init_x_policy(void) 2939a4365d0SYoshinobu Inoue { 2949a4365d0SYoshinobu Inoue struct sadb_x_policy *p; 2959a4365d0SYoshinobu Inoue 2969a4365d0SYoshinobu Inoue tlen = sizeof(struct sadb_x_policy); 2979a4365d0SYoshinobu Inoue 2989a4365d0SYoshinobu Inoue pbuf = malloc(tlen); 2999a4365d0SYoshinobu Inoue if (pbuf == NULL) { 3003c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_BUFS; 3019a4365d0SYoshinobu Inoue return -1; 3029a4365d0SYoshinobu Inoue } 303bd9f52d5SHajimu UMEMOTO memset(pbuf, 0, tlen); 3049a4365d0SYoshinobu Inoue p = (struct sadb_x_policy *)pbuf; 3059a4365d0SYoshinobu Inoue p->sadb_x_policy_len = 0; /* must update later */ 3069a4365d0SYoshinobu Inoue p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 3079a4365d0SYoshinobu Inoue p->sadb_x_policy_type = p_type; 3089a4365d0SYoshinobu Inoue p->sadb_x_policy_dir = p_dir; 309bd9f52d5SHajimu UMEMOTO p->sadb_x_policy_id = 0; 310bd9f52d5SHajimu UMEMOTO 3119a4365d0SYoshinobu Inoue offset = tlen; 3129a4365d0SYoshinobu Inoue 3133c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 3149a4365d0SYoshinobu Inoue return 0; 3159a4365d0SYoshinobu Inoue } 3169a4365d0SYoshinobu Inoue 3179a4365d0SYoshinobu Inoue static int 31858436df3SMateusz Guzik set_x_request(struct sockaddr *src, struct sockaddr *dst) 3199a4365d0SYoshinobu Inoue { 3209a4365d0SYoshinobu Inoue struct sadb_x_ipsecrequest *p; 3219a4365d0SYoshinobu Inoue int reqlen; 3229a4365d0SYoshinobu Inoue 3239a4365d0SYoshinobu Inoue reqlen = sizeof(*p) 3249a4365d0SYoshinobu Inoue + (src ? src->sa_len : 0) 3259a4365d0SYoshinobu Inoue + (dst ? dst->sa_len : 0); 3269a4365d0SYoshinobu Inoue tlen += reqlen; /* increment to total length */ 3279a4365d0SYoshinobu Inoue 3289a4365d0SYoshinobu Inoue pbuf = realloc(pbuf, tlen); 3299a4365d0SYoshinobu Inoue if (pbuf == NULL) { 3303c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_BUFS; 3319a4365d0SYoshinobu Inoue return -1; 3329a4365d0SYoshinobu Inoue } 3339a4365d0SYoshinobu Inoue p = (struct sadb_x_ipsecrequest *)&pbuf[offset]; 3349a4365d0SYoshinobu Inoue p->sadb_x_ipsecrequest_len = reqlen; 3359a4365d0SYoshinobu Inoue p->sadb_x_ipsecrequest_proto = p_protocol; 3369a4365d0SYoshinobu Inoue p->sadb_x_ipsecrequest_mode = p_mode; 3379a4365d0SYoshinobu Inoue p->sadb_x_ipsecrequest_level = p_level; 3383c62e87aSJun-ichiro itojun Hagino p->sadb_x_ipsecrequest_reqid = p_reqid; 3399a4365d0SYoshinobu Inoue offset += sizeof(*p); 3409a4365d0SYoshinobu Inoue 3419a4365d0SYoshinobu Inoue if (set_sockaddr(src) || set_sockaddr(dst)) 3429a4365d0SYoshinobu Inoue return -1; 3439a4365d0SYoshinobu Inoue 3443c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 3459a4365d0SYoshinobu Inoue return 0; 3469a4365d0SYoshinobu Inoue } 3479a4365d0SYoshinobu Inoue 3489a4365d0SYoshinobu Inoue static int 349*50ecbc51SLexi Winter set_sockaddr(const struct sockaddr *addr) 3509a4365d0SYoshinobu Inoue { 3519a4365d0SYoshinobu Inoue if (addr == NULL) { 3523c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 3539a4365d0SYoshinobu Inoue return 0; 3549a4365d0SYoshinobu Inoue } 3559a4365d0SYoshinobu Inoue 3569a4365d0SYoshinobu Inoue /* tlen has already incremented */ 3579a4365d0SYoshinobu Inoue 3589a4365d0SYoshinobu Inoue memcpy(&pbuf[offset], addr, addr->sa_len); 3599a4365d0SYoshinobu Inoue 3609a4365d0SYoshinobu Inoue offset += addr->sa_len; 3619a4365d0SYoshinobu Inoue 3623c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 3639a4365d0SYoshinobu Inoue return 0; 3649a4365d0SYoshinobu Inoue } 3659a4365d0SYoshinobu Inoue 3669a4365d0SYoshinobu Inoue static void 36758436df3SMateusz Guzik policy_parse_request_init(void) 3689a4365d0SYoshinobu Inoue { 3699a4365d0SYoshinobu Inoue p_protocol = IPPROTO_IP; 3709a4365d0SYoshinobu Inoue p_mode = IPSEC_MODE_ANY; 3719a4365d0SYoshinobu Inoue p_level = IPSEC_LEVEL_DEFAULT; 3723c62e87aSJun-ichiro itojun Hagino p_reqid = 0; 3739a4365d0SYoshinobu Inoue if (p_src != NULL) { 3749a4365d0SYoshinobu Inoue free(p_src); 3759a4365d0SYoshinobu Inoue p_src = NULL; 3769a4365d0SYoshinobu Inoue } 3779a4365d0SYoshinobu Inoue if (p_dst != NULL) { 3789a4365d0SYoshinobu Inoue free(p_dst); 3799a4365d0SYoshinobu Inoue p_dst = NULL; 3809a4365d0SYoshinobu Inoue } 3819a4365d0SYoshinobu Inoue 3829a4365d0SYoshinobu Inoue return; 3839a4365d0SYoshinobu Inoue } 3849a4365d0SYoshinobu Inoue 3859a4365d0SYoshinobu Inoue static caddr_t 386*50ecbc51SLexi Winter policy_parse(const char *msg, int msglen) 3879a4365d0SYoshinobu Inoue { 3889a4365d0SYoshinobu Inoue int error; 3899a4365d0SYoshinobu Inoue pbuf = NULL; 3909a4365d0SYoshinobu Inoue tlen = 0; 3919a4365d0SYoshinobu Inoue 3929a4365d0SYoshinobu Inoue /* initialize */ 3939a4365d0SYoshinobu Inoue p_dir = IPSEC_DIR_INVALID; 3949a4365d0SYoshinobu Inoue p_type = IPSEC_POLICY_DISCARD; 3959a4365d0SYoshinobu Inoue policy_parse_request_init(); 3969a4365d0SYoshinobu Inoue __policy__strbuffer__init__(msg); 3979a4365d0SYoshinobu Inoue 3989a4365d0SYoshinobu Inoue error = yyparse(); /* it must be set errcode. */ 399bd9f52d5SHajimu UMEMOTO __policy__strbuffer__free__(); 400bd9f52d5SHajimu UMEMOTO 4019a4365d0SYoshinobu Inoue if (error) { 4029a4365d0SYoshinobu Inoue if (pbuf != NULL) 4039a4365d0SYoshinobu Inoue free(pbuf); 4049a4365d0SYoshinobu Inoue return NULL; 4059a4365d0SYoshinobu Inoue } 4069a4365d0SYoshinobu Inoue 4079a4365d0SYoshinobu Inoue /* update total length */ 4089a4365d0SYoshinobu Inoue ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen); 4099a4365d0SYoshinobu Inoue 4103c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 4119a4365d0SYoshinobu Inoue 4129a4365d0SYoshinobu Inoue return pbuf; 4139a4365d0SYoshinobu Inoue } 4149a4365d0SYoshinobu Inoue 4159a4365d0SYoshinobu Inoue caddr_t 416*50ecbc51SLexi Winter ipsec_set_policy(const char *msg, int msglen) 4179a4365d0SYoshinobu Inoue { 4189a4365d0SYoshinobu Inoue caddr_t policy; 4199a4365d0SYoshinobu Inoue 4209a4365d0SYoshinobu Inoue policy = policy_parse(msg, msglen); 4219a4365d0SYoshinobu Inoue if (policy == NULL) { 4223c62e87aSJun-ichiro itojun Hagino if (__ipsec_errcode == EIPSEC_NO_ERROR) 4233c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 4249a4365d0SYoshinobu Inoue return NULL; 4259a4365d0SYoshinobu Inoue } 4269a4365d0SYoshinobu Inoue 4273c62e87aSJun-ichiro itojun Hagino __ipsec_errcode = EIPSEC_NO_ERROR; 4289a4365d0SYoshinobu Inoue return policy; 4299a4365d0SYoshinobu Inoue } 4309a4365d0SYoshinobu Inoue 431