token.l revision 55505
155505Sshin/*
255505Sshin * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
355505Sshin * All rights reserved.
455505Sshin *
555505Sshin * Redistribution and use in source and binary forms, with or without
655505Sshin * modification, are permitted provided that the following conditions
755505Sshin * are met:
855505Sshin * 1. Redistributions of source code must retain the above copyright
955505Sshin *    notice, this list of conditions and the following disclaimer.
1055505Sshin * 2. Redistributions in binary form must reproduce the above copyright
1155505Sshin *    notice, this list of conditions and the following disclaimer in the
1255505Sshin *    documentation and/or other materials provided with the distribution.
1355505Sshin * 3. Neither the name of the project nor the names of its contributors
1455505Sshin *    may be used to endorse or promote products derived from this software
1555505Sshin *    without specific prior written permission.
1655505Sshin *
1755505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1855505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1955505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2055505Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2155505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2255505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2355505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2455505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2555505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2655505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2755505Sshin * SUCH DAMAGE.
2855505Sshin *
2955505Sshin * $FreeBSD: head/sbin/setkey/token.l 55505 2000-01-06 12:40:54Z shin $
3055505Sshin */
3155505Sshin
3255505Sshin%{
3355505Sshin#include <sys/types.h>
3455505Sshin#include <sys/param.h>
3555505Sshin#include <sys/socket.h>
3655505Sshin#include <net/route.h>
3755505Sshin#include <net/pfkeyv2.h>
3855505Sshin#include <netkey/keydb.h>
3955505Sshin#include <netkey/key_debug.h>
4055505Sshin#include <netinet/in.h>
4155505Sshin#include <netinet6/ipsec.h>
4255505Sshin
4355505Sshin#include <stdlib.h>
4455505Sshin#include <limits.h>
4555505Sshin#include <string.h>
4655505Sshin#include <unistd.h>
4755505Sshin#include <errno.h>
4855505Sshin#include "vchar.h"
4955505Sshin#include "y.tab.h"
5055505Sshin
5155505Sshin#define DECHO \
5255505Sshin	if (f_debug) {printf("<%d>", yy_start); ECHO ; printf("\n"); }
5355505Sshin
5455505Sshin#define CMDARG \
5555505Sshin{ \
5655505Sshin	char *__buf__ = strdup(yytext), *__p__; \
5755505Sshin	for (__p__ = __buf__; *__p__ != NULL; __p__++) \
5855505Sshin		if (*__p__ == '\n' || *__p__ == '\t') \
5955505Sshin			*__p__ = ' '; \
6055505Sshin	strcat(cmdarg, __buf__); \
6155505Sshin	free(__buf__); \
6255505Sshin}
6355505Sshin
6455505Sshin#define PREPROC	DECHO CMDARG
6555505Sshin
6655505Sshinint	lineno = 1;
6755505Sshinchar	cmdarg[8192]; /* XXX: BUFSIZ is the better ? */
6855505Sshin
6955505Sshinextern u_char	m_buf[BUFSIZ];
7055505Sshinextern u_int	m_len;
7155505Sshinextern int	f_debug;
7255505Sshin
7355505Sshinint	yylex __P((void));
7455505Sshinvoid	yyerror __P((char *s));
7555505Sshinextern void	parse_init __P((void));
7655505Sshinint	parse __P((FILE **));
7755505Sshinint	yyparse __P((void));
7855505Sshin
7955505Sshin%}
8055505Sshin
8155505Sshin/* common section */
8255505Sshinnl		\n
8355505Sshinws		[ \t]+
8455505Sshindigit		[0-9]
8555505Sshinletter		[0-9A-Za-z]
8655505Sshinhexdigit	[0-9A-Fa-f]
8755505Sshin/*octet		(([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5])))*/
8855505Sshinspecial		[()+\|\?\*,]
8955505Sshindot		\.
9055505Sshincomma		\,
9155505Sshinhyphen		\-
9255505Sshincolon		\:
9355505Sshinslash		\/
9455505Sshinbcl		\{
9555505Sshinecl		\}
9655505Sshinblcl		\[
9755505Sshinelcl		\]
9855505Sshinpercent		\%
9955505Sshinsemi		\;
10055505Sshinusec		{dot}{digit}{1,6}
10155505Sshincomment		\#.*
10255505Sshinccomment	"/*"
10355505Sshinbracketstring	\<[^>]*\>
10455505Sshinquotedstring	\"[^"]*\"
10555505Sshindecstring	{digit}+
10655505Sshinhexpair		{hexdigit}{hexdigit}
10755505Sshinhexstring	0[xX]{hexdigit}+
10855505Sshinoctetstring	{octet}({dot}{octet})+
10955505Sshinipaddress	{ipv4addr}|{ipv6addr}
11055505Sshinipv4addr	{digit}{1,3}({dot}{digit}{1,3}){0,3}
11155505Sshinipv6addr	{hexdigit}{0,4}({colon}{hexdigit}{0,4}){2,7}(@{letter}{letter}+)?
11255505Sshinipaddrmask	{slash}{digit}{1,3}
11355505Sshinipaddrport	{blcl}{decstring}{elcl}
11455505Sshinkeyword		{letter}{letter}+
11555505Sshinname		{letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))*
11655505Sshinhostname	{name}(({dot}{name})+{dot}?)?
11755505Sshin
11855505Sshin%s S_PL
11955505Sshin
12055505Sshin%%
12155505Sshin
12255505Sshinadd		{ PREPROC; return(ADD); }
12355505Sshindelete		{ PREPROC; return(DELETE); }
12455505Sshinget		{ PREPROC; return(GET); }
12555505Sshinflush		{ PREPROC; return(FLUSH); }
12655505Sshindump		{ PREPROC; return(DUMP); }
12755505Sshin
12855505Sshin	/* for management SPD */
12955505Sshinspdadd		{ PREPROC; return(SPDADD); }
13055505Sshinspddelete	{ PREPROC; return(SPDDELETE); }
13155505Sshinspddump		{ PREPROC; return(SPDDUMP); }
13255505Sshinspdflush	{ PREPROC; return(SPDFLUSH); }
13355505Sshin{hyphen}P	{ BEGIN S_PL; PREPROC; return(F_POLICY); }
13455505Sshin<S_PL>[a-zA-Z0-9:\.\-_/ \n\t][a-zA-Z0-9:\.\-_/ \n\t]* {
13555505Sshin		yymore();
13655505Sshin
13755505Sshin		/* count up for nl */
13855505Sshin		    {
13955505Sshin			char *p;
14055505Sshin			for (p = yytext; *p != NULL; p++)
14155505Sshin				if (*p == '\n')
14255505Sshin					lineno++;
14355505Sshin		    }
14455505Sshin
14555505Sshin		yylval.val.len = strlen(yytext);
14655505Sshin		yylval.val.buf = strdup(yytext);
14755505Sshin
14855505Sshin		return(PL_REQUESTS);
14955505Sshin}
15055505Sshin<S_PL>{semi}	{ PREPROC; BEGIN INITIAL; return(EOT); }
15155505Sshin
15255505Sshin	/* security protocols */
15355505Sshinah		{ PREPROC; yylval.num = 0; return(PR_AH); }
15455505Sshinesp		{ PREPROC; yylval.num = 0; return(PR_ESP); }
15555505Sshinah-old		{ PREPROC; yylval.num = 1; return(PR_AH); }
15655505Sshinesp-old		{ PREPROC; yylval.num = 1; return(PR_ESP); }
15755505Sshinipcomp		{ PREPROC; yylval.num = 0; return(PR_IPCOMP); }
15855505Sshin
15955505Sshin	/* authentication alogorithm */
16055505Sshin{hyphen}A	{ PREPROC; return(F_AUTH); }
16155505Sshinhmac-md5	{ PREPROC; yylval.num = SADB_AALG_MD5HMAC; return(ALG_AUTH); }
16255505Sshinhmac-sha1	{ PREPROC; yylval.num = SADB_AALG_SHA1HMAC; return(ALG_AUTH); }
16355505Sshinkeyed-md5	{ PREPROC; yylval.num = SADB_AALG_MD5; return(ALG_AUTH); }
16455505Sshinkeyed-sha1	{ PREPROC; yylval.num = SADB_AALG_SHA; return(ALG_AUTH); }
16555505Sshinnull		{ PREPROC; yylval.num = SADB_AALG_NULL; return(ALG_AUTH); }
16655505Sshin
16755505Sshin	/* encryption alogorithm */
16855505Sshin{hyphen}E	{ PREPROC; return(F_ENC); }
16955505Sshindes-cbc		{ PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC); }
17055505Sshin3des-cbc	{ PREPROC; yylval.num = SADB_EALG_3DESCBC; return(ALG_ENC); }
17155505Sshinsimple		{ PREPROC; yylval.num = SADB_EALG_NULL; return(ALG_ENC); }
17255505Sshinblowfish-cbc	{ PREPROC; yylval.num = SADB_EALG_BLOWFISHCBC; return(ALG_ENC); }
17355505Sshincast128-cbc	{ PREPROC; yylval.num = SADB_EALG_CAST128CBC; return(ALG_ENC); }
17455505Sshinrc5-cbc		{ PREPROC; yylval.num = SADB_EALG_RC5CBC; return(ALG_ENC); }
17555505Sshindes-deriv	{ PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DESDERIV); }
17655505Sshindes-32iv	{ PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DES32IV); }
17755505Sshin
17855505Sshin	/* compression algorithms */
17955505Sshin{hyphen}C	{ PREPROC; return(F_COMP); }
18055505Sshinoui		{ PREPROC; yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); }
18155505Sshindeflate		{ PREPROC; yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); }
18255505Sshinlzs		{ PREPROC; yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); }
18355505Sshin{hyphen}R	{ PREPROC; return(F_RAWCPI); }
18455505Sshin
18555505Sshin	/* extension */
18655505Sshin{hyphen}m	{ PREPROC; return(F_MODE); }
18755505Sshintransport	{ PREPROC; yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); }
18855505Sshintunnel		{ PREPROC; yylval.num = IPSEC_MODE_TUNNEL; return(MODE); }
18955505Sshin{hyphen}f	{ PREPROC; return(F_EXT); }
19055505Sshinrandom-pad	{ PREPROC; yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); }
19155505Sshinseq-pad		{ PREPROC; yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); }
19255505Sshinzero-pad	{ PREPROC; yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); }
19355505Sshincyclic-seq	{ PREPROC; yylval.num = SADB_X_EXT_CYCSEQ; return(EXTENSION); }
19455505Sshin{hyphen}r	{ PREPROC; return(F_REPLAY); }
19555505Sshin{hyphen}lh	{ PREPROC; return(F_LIFETIME_HARD); }
19655505Sshin{hyphen}ls	{ PREPROC; return(F_LIFETIME_SOFT); }
19755505Sshin
19855505Sshin
19955505Sshin	/* upper layer protocols */
20055505Sshinicmp		{ PREPROC; yylval.num = IPPROTO_ICMP; return(UP_PROTO); }
20155505Sshinicmp6		{ PREPROC; yylval.num = IPPROTO_ICMPV6; return(UP_PROTO); }
20255505Sshintcp		{ PREPROC; yylval.num = IPPROTO_TCP; return(UP_PROTO); }
20355505Sshinudp		{ PREPROC; yylval.num = IPPROTO_UDP; return(UP_PROTO); }
20455505Sshin
20555505Sshin	/* ... */
20655505Sshinany		{ PREPROC; return(ANY); }
20755505Sshin{ws}		{ PREPROC; }
20855505Sshin{nl}		{ lineno++; }
20955505Sshin{comment}
21055505Sshin{semi}		{ PREPROC; return(EOT); }
21155505Sshin
21255505Sshin	/* parameter */
21355505Sshin{decstring}	{
21455505Sshin			char *bp;
21555505Sshin
21655505Sshin			PREPROC;
21755505Sshin			yylval.num = strtol(yytext, &bp, 10);
21855505Sshin			return(DECSTRING);
21955505Sshin		}
22055505Sshin
22155505Sshin{ipv4addr}	{
22255505Sshin			/*
22355505Sshin			 * I can't supprt the type without dot,
22455505Sshin			 * because it's umbiguous against {decstring}.
22555505Sshin			 * e.g. 127
22655505Sshin			 */
22755505Sshin			PREPROC;
22855505Sshin
22955505Sshin			yylval.val.len = sizeof(struct sockaddr_in);
23055505Sshin			yylval.val.buf = strdup(yytext);
23155505Sshin
23255505Sshin			return(IP4_ADDRESS);
23355505Sshin		}
23455505Sshin
23555505Sshin{ipv6addr}	{
23655505Sshin#ifdef INET6
23755505Sshin			PREPROC;
23855505Sshin
23955505Sshin			yylval.val.len = sizeof(struct sockaddr_in6);
24055505Sshin			yylval.val.buf = strdup(yytext);
24155505Sshin
24255505Sshin			return(IP6_ADDRESS);
24355505Sshin#else
24455505Sshin			yyerror("IPv6 address not supported");
24555505Sshin#endif
24655505Sshin		}
24755505Sshin
24855505Sshin{ipaddrmask}	{
24955505Sshin			PREPROC;
25055505Sshin			yytext++;
25155505Sshin			yylval.num = atoi(yytext);
25255505Sshin			return(PREFIX);
25355505Sshin		}
25455505Sshin
25555505Sshin{ipaddrport}	{
25655505Sshin			char *p = yytext;
25755505Sshin			PREPROC;
25855505Sshin			while (*++p != ']') ;
25955505Sshin			*p = NULL;
26055505Sshin			yytext++;
26155505Sshin			yylval.num = atoi(yytext);
26255505Sshin			return(PORT);
26355505Sshin		}
26455505Sshin
26555505Sshin{blcl}any{elcl}	{
26655505Sshin			char *p = yytext;
26755505Sshin			PREPROC;
26855505Sshin			return(PORTANY);
26955505Sshin		}
27055505Sshin
27155505Sshin{hexstring}	{
27255505Sshin			int len = yyleng - 2; /* (str - "0x") */
27355505Sshin			PREPROC;
27455505Sshin			yylval.val.len = (len & 1) + (len / 2);
27555505Sshin			/* fixed string if length is odd. */
27655505Sshin			if (len & 1) {
27755505Sshin				yytext[1] = '0';
27855505Sshin				yylval.val.buf = strdup(yytext + 1);
27955505Sshin			} else
28055505Sshin				yylval.val.buf = strdup(yytext + 2);
28155505Sshin
28255505Sshin			return(HEXSTRING);
28355505Sshin		}
28455505Sshin
28555505Sshin{quotedstring}	{
28655505Sshin			char *p = yytext;
28755505Sshin			PREPROC;
28855505Sshin			while (*++p != '"') ;
28955505Sshin			*p = NULL;
29055505Sshin			yytext++;
29155505Sshin			yylval.val.len = yyleng - 2;
29255505Sshin			yylval.val.buf = strdup(yytext);
29355505Sshin
29455505Sshin			return(QUOTEDSTRING);
29555505Sshin		}
29655505Sshin
29755505Sshin.		{ yyerror("Syntax error"); }
29855505Sshin
29955505Sshin%%
30055505Sshin
30155505Sshinvoid
30255505Sshinyyerror(char *s)
30355505Sshin{
30455505Sshin	printf("line %d: %s at [%s]\n", lineno, s, yytext);
30555505Sshin}
30655505Sshin
30755505Sshinint
30855505Sshinparse(fp)
30955505Sshin	FILE **fp;
31055505Sshin{
31155505Sshin	yyin = *fp;
31255505Sshin
31355505Sshin	parse_init();
31455505Sshin
31555505Sshin	if (yyparse()) {
31655505Sshin		printf("parse failed, line %d.\n", lineno);
31755505Sshin		return(-1);
31855505Sshin	}
31955505Sshin
32055505Sshin	return(0);
32155505Sshin}
32255505Sshin
323