📄 policy_parse.tab.c
字号:
p_type = 0; /* ignored it by kernel */
if (init_x_policy())
return -1;
;}
break;
case 6:
#line 137 "policy_parse.y"
{
if (rule_check() < 0)
return -1;
if (set_x_request(p_src, p_dst) < 0)
return -1;
policy_parse_request_init();
;}
break;
case 13:
#line 155 "policy_parse.y"
{
__ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
return -1;
;}
break;
case 14:
#line 159 "policy_parse.y"
{
__ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
return -1;
;}
break;
case 15:
#line 166 "policy_parse.y"
{ p_protocol = yyvsp[0].num; ;}
break;
case 16:
#line 170 "policy_parse.y"
{ p_mode = yyvsp[0].num; ;}
break;
case 17:
#line 174 "policy_parse.y"
{
p_level = yyvsp[0].num;
p_reqid = 0;
;}
break;
case 18:
#line 178 "policy_parse.y"
{
p_level = IPSEC_LEVEL_UNIQUE;
p_reqid = atol(yyvsp[0].val.buf); /* atol() is good. */
;}
break;
case 19:
#line 185 "policy_parse.y"
{
p_src = parse_sockaddr(&yyvsp[0].val);
if (p_src == NULL)
return -1;
;}
break;
case 20:
#line 191 "policy_parse.y"
{
p_dst = parse_sockaddr(&yyvsp[0].val);
if (p_dst == NULL)
return -1;
;}
break;
case 21:
#line 196 "policy_parse.y"
{
if (p_dir != IPSEC_DIR_OUTBOUND) {
__ipsec_errcode = EIPSEC_INVAL_DIR;
return -1;
}
;}
break;
case 22:
#line 202 "policy_parse.y"
{
if (p_dir != IPSEC_DIR_INBOUND) {
__ipsec_errcode = EIPSEC_INVAL_DIR;
return -1;
}
;}
break;
}
/* Line 999 of yacc.c. */
#line 1178 "policy_parse.tab.c"
yyvsp -= yylen;
yyssp -= yylen;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if YYERROR_VERBOSE
yyn = yypact[yystate];
if (YYPACT_NINF < yyn && yyn < YYLAST)
{
YYSIZE_T yysize = 0;
int yytype = YYTRANSLATE (yychar);
char *yymsg;
int yyx, yycount;
yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
for (yyx = yyn < 0 ? -yyn : 0;
yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
yysize += yystrlen (yytname[yyx]) + 15, yycount++;
yysize += yystrlen ("syntax error, unexpected ") + 1;
yysize += yystrlen (yytname[yytype]);
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
yyp = yystpcpy (yyp, yytname[yytype]);
if (yycount < 5)
{
yycount = 0;
for (yyx = yyn < 0 ? -yyn : 0;
yyx < (int) (sizeof (yytname) / sizeof (char *));
yyx++)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
const char *yyq = ! yycount ? ", expecting " : " or ";
yyp = yystpcpy (yyp, yyq);
yyp = yystpcpy (yyp, yytname[yyx]);
yycount++;
}
}
yyerror (yymsg);
YYSTACK_FREE (yymsg);
}
else
yyerror ("syntax error; also virtual memory exhausted");
}
else
#endif /* YYERROR_VERBOSE */
yyerror ("syntax error");
}
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
/* Return failure if at end of input. */
if (yychar == YYEOF)
{
/* Pop the error token. */
YYPOPSTACK;
/* Pop the rest of the stack. */
while (yyss < yyssp)
{
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
yydestruct (yystos[*yyssp], yyvsp);
YYPOPSTACK;
}
YYABORT;
}
YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
yydestruct (yytoken, &yylval);
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token after shifting the error
token. */
goto yyerrlab1;
/*----------------------------------------------------.
| yyerrlab1 -- error raised explicitly by an action. |
`----------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
/* Pop the current state because it cannot handle the error token. */
if (yyssp == yyss)
YYABORT;
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
yydestruct (yystos[yystate], yyvsp);
yyvsp--;
yystate = *--yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
if (yyn == YYFINAL)
YYACCEPT;
YYDPRINTF ((stderr, "Shifting error token, "));
*++yyvsp = yylval;
yystate = yyn;
goto yynewstate;
/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
yyresult = 1;
goto yyreturn;
#ifndef yyoverflow
/*----------------------------------------------.
| yyoverflowlab -- parser overflow comes here. |
`----------------------------------------------*/
yyoverflowlab:
yyerror ("parser stack overflow");
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
return yyresult;
}
#line 213 "policy_parse.y"
void
yyerror(msg)
char *msg;
{
fprintf(stderr, "libipsec: %s while parsing \"%s\"\n",
msg, __libyytext);
return;
}
static struct sockaddr *
parse_sockaddr(buf)
struct _val *buf;
{
struct addrinfo hints, *res;
char *serv = NULL;
int error;
struct sockaddr *newaddr = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_NUMERICHOST;
error = getaddrinfo(buf->buf, serv, &hints, &res);
if (error != 0) {
yyerror("invalid IP address");
__ipsec_set_strerror(gai_strerror(error));
return NULL;
}
if (res->ai_addr == NULL) {
yyerror("invalid IP address");
__ipsec_set_strerror(gai_strerror(error));
return NULL;
}
newaddr = malloc(res->ai_addr->sa_len);
if (newaddr == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
freeaddrinfo(res);
return NULL;
}
memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len);
freeaddrinfo(res);
__ipsec_errcode = EIPSEC_NO_ERROR;
return newaddr;
}
static int
rule_check()
{
if (p_type == IPSEC_POLICY_IPSEC) {
if (p_protocol == IPPROTO_IP) {
__ipsec_errcode = EIPSEC_NO_PROTO;
return -1;
}
if (p_mode != IPSEC_MODE_TRANSPORT
&& p_mode != IPSEC_MODE_TUNNEL) {
__ipsec_errcode = EIPSEC_INVAL_MODE;
return -1;
}
if (p_src == NULL && p_dst == NULL) {
if (p_mode != IPSEC_MODE_TRANSPORT) {
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return -1;
}
}
else if (p_src->sa_family != p_dst->sa_family) {
__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
init_x_policy()
{
struct sadb_x_policy *p;
if (tlen < sizeof (struct sadb_x_policy))
tlen = sizeof (struct sadb_x_policy);
pbuf = malloc(tlen);
if (pbuf == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
return -1;
}
tlen = sizeof(struct sadb_x_policy);
memset(pbuf, 0, tlen);
p = (struct sadb_x_policy *)pbuf;
p->sadb_x_policy_len = 0; /* must update later */
p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
p->sadb_x_policy_type = p_type;
p->sadb_x_policy_dir = p_dir;
p->sadb_x_policy_id = 0;
offset = tlen;
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
set_x_request(src, dst)
struct sockaddr *src, *dst;
{
struct sadb_x_ipsecrequest *p;
int reqlen;
caddr_t n;
reqlen = sizeof(*p)
+ (src ? src->sa_len : 0)
+ (dst ? dst->sa_len : 0);
n = realloc(pbuf, tlen + reqlen);
if (n == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
return -1;
}
tlen += reqlen;
pbuf = n;
p = (struct sadb_x_ipsecrequest *)&pbuf[offset];
p->sadb_x_ipsecrequest_len = reqlen;
p->sadb_x_ipsecrequest_proto = p_protocol;
p->sadb_x_ipsecrequest_mode = p_mode;
p->sadb_x_ipsecrequest_level = p_level;
p->sadb_x_ipsecrequest_reqid = p_reqid;
offset += sizeof(*p);
if (set_sockaddr(src) || set_sockaddr(dst))
return -1;
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
set_sockaddr(addr)
struct sockaddr *addr;
{
if (addr == NULL) {
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
/* tlen has already incremented */
memcpy(&pbuf[offset], addr, addr->sa_len);
offset += addr->sa_len;
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static void
policy_parse_request_init()
{
p_protocol = IPPROTO_IP;
p_mode = IPSEC_MODE_ANY;
p_level = IPSEC_LEVEL_DEFAULT;
p_reqid = 0;
if (p_src != NULL) {
free(p_src);
p_src = NULL;
}
if (p_dst != NULL) {
free(p_dst);
p_dst = NULL;
}
return;
}
static caddr_t
policy_parse(msg, msglen)
char *msg;
int msglen;
{
int error;
pbuf = NULL;
tlen = 0;
/* initialize */
p_dir = IPSEC_DIR_INVALID;
p_type = IPSEC_POLICY_DISCARD;
policy_parse_request_init();
__policy__strbuffer__init__(msg);
error = yyparse(); /* it must be set errcode. */
__policy__strbuffer__free__();
if (error) {
if (pbuf != NULL)
free(pbuf);
return NULL;
}
/* update total length */
((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen);
__ipsec_errcode = EIPSEC_NO_ERROR;
return pbuf;
}
caddr_t
ipsec_set_policy(msg, msglen)
char *msg;
int msglen;
{
caddr_t policy;
policy = policy_parse(msg, msglen);
if (policy == NULL) {
if (__ipsec_errcode == EIPSEC_NO_ERROR)
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return NULL;
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return policy;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -