xref: /freebsd/sbin/ipf/iplang/iplang_l.l (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
141edb306SCy Schubert 
241edb306SCy Schubert %{
341edb306SCy Schubert /*
441edb306SCy Schubert  * Copyright (C) 2012 by Darren Reed.
541edb306SCy Schubert  *
641edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
741edb306SCy Schubert  *
841edb306SCy Schubert  * $Id$
941edb306SCy Schubert  */
1041edb306SCy Schubert #include <stdio.h>
1141edb306SCy Schubert #include <string.h>
1241edb306SCy Schubert #include <sys/param.h>
1341edb306SCy Schubert #if defined(__SVR4) || defined(__sysv__)
1441edb306SCy Schubert #include <sys/stream.h>
1541edb306SCy Schubert #endif
1641edb306SCy Schubert #include <sys/types.h>
1741edb306SCy Schubert #include <netinet/in_systm.h>
1841edb306SCy Schubert #include <netinet/in.h>
1941edb306SCy Schubert #include "iplang_y.h"
2041edb306SCy Schubert #include "ipf.h"
2141edb306SCy Schubert 
2241edb306SCy Schubert #ifndef	__P
2341edb306SCy Schubert #  define	__P(x)	x
2441edb306SCy Schubert #endif
2541edb306SCy Schubert 
2641edb306SCy Schubert extern int opts;
2741edb306SCy Schubert 
2841edb306SCy Schubert int lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0;
2941edb306SCy Schubert int *prstack = NULL, numpr = 0, state = 0, token = 0;
3041edb306SCy Schubert 
3141edb306SCy Schubert void    yyerror(char *);
3241edb306SCy Schubert void	push_proto(void);
3341edb306SCy Schubert void	pop_proto(void);
3441edb306SCy Schubert int	next_state(int, int);
3541edb306SCy Schubert int	next_item(int);
3641edb306SCy Schubert int	save_token(void);
3741edb306SCy Schubert void	swallow(void);
3841edb306SCy Schubert int	yylex(void);
3941edb306SCy Schubert 
4041edb306SCy Schubert struct	lwordtab	{
4141edb306SCy Schubert 	char	*word;
4241edb306SCy Schubert 	int	state;
4341edb306SCy Schubert 	int	next;
4441edb306SCy Schubert };
4541edb306SCy Schubert 
4641edb306SCy Schubert struct	lwordtab	words[] = {
4741edb306SCy Schubert 	{ "interface",	IL_INTERFACE,		-1 },
4841edb306SCy Schubert 	{ "iface",	IL_INTERFACE,		-1 },
4941edb306SCy Schubert 	{ "name",	IL_IFNAME,		IL_TOKEN },
5041edb306SCy Schubert 	{ "ifname",	IL_IFNAME,		IL_TOKEN },
5141edb306SCy Schubert 	{ "router",	IL_DEFROUTER,		IL_TOKEN },
5241edb306SCy Schubert 	{ "mtu",	IL_MTU,			IL_NUMBER },
5341edb306SCy Schubert 	{ "eaddr",	IL_EADDR,		IL_TOKEN },
5441edb306SCy Schubert 	{ "v4addr",	IL_V4ADDR,		IL_TOKEN },
5541edb306SCy Schubert 	{ "ipv4",	IL_IPV4,		-1 },
5641edb306SCy Schubert 	{ "v",		IL_V4V,			IL_TOKEN },
5741edb306SCy Schubert 	{ "proto",	IL_V4PROTO,		IL_TOKEN },
5841edb306SCy Schubert 	{ "hl",		IL_V4HL,		IL_TOKEN },
5941edb306SCy Schubert 	{ "id",		IL_V4ID,		IL_TOKEN },
6041edb306SCy Schubert 	{ "ttl",	IL_V4TTL,		IL_TOKEN },
6141edb306SCy Schubert 	{ "tos",	IL_V4TOS,		IL_TOKEN },
6241edb306SCy Schubert 	{ "src",	IL_V4SRC,		IL_TOKEN },
6341edb306SCy Schubert 	{ "dst",	IL_V4DST,		IL_TOKEN },
6441edb306SCy Schubert 	{ "opt",	IL_OPT,			-1 },
6541edb306SCy Schubert 	{ "len",	IL_LEN,			IL_TOKEN },
6641edb306SCy Schubert 	{ "off",	IL_OFF,			IL_TOKEN },
6741edb306SCy Schubert 	{ "sum",	IL_SUM,			IL_TOKEN },
6841edb306SCy Schubert 	{ "tcp",	IL_TCP,			-1 },
6941edb306SCy Schubert 	{ "sport",	IL_SPORT,		IL_TOKEN },
7041edb306SCy Schubert 	{ "dport",	IL_DPORT,		IL_TOKEN },
7141edb306SCy Schubert 	{ "seq",	IL_TCPSEQ,		IL_TOKEN },
7241edb306SCy Schubert 	{ "ack",	IL_TCPACK,		IL_TOKEN },
7341edb306SCy Schubert 	{ "flags",	IL_TCPFL,		IL_TOKEN },
7441edb306SCy Schubert 	{ "urp",	IL_TCPURP,		IL_TOKEN },
7541edb306SCy Schubert 	{ "win",	IL_TCPWIN,		IL_TOKEN },
7641edb306SCy Schubert 	{ "udp",	IL_UDP,			-1 },
7741edb306SCy Schubert 	{ "send",	IL_SEND,		-1 },
7841edb306SCy Schubert 	{ "via",	IL_VIA,			IL_TOKEN },
7941edb306SCy Schubert 	{ "arp",	IL_ARP,			-1 },
8041edb306SCy Schubert 	{ "data",	IL_DATA,		-1 },
8141edb306SCy Schubert 	{ "value",	IL_DVALUE,		IL_TOKEN },
8241edb306SCy Schubert 	{ "file",	IL_DFILE,		IL_TOKEN },
8341edb306SCy Schubert 	{ "nop",	IL_IPO_NOP,		-1 },
8441edb306SCy Schubert 	{ "eol",	IL_IPO_EOL,		-1 },
8541edb306SCy Schubert 	{ "rr",		IL_IPO_RR,		-1 },
8641edb306SCy Schubert 	{ "zsu",	IL_IPO_ZSU,		-1 },
8741edb306SCy Schubert 	{ "mtup",	IL_IPO_MTUP,		-1 },
8841edb306SCy Schubert 	{ "mtur",	IL_IPO_MTUR,		-1 },
8941edb306SCy Schubert 	{ "encode",	IL_IPO_ENCODE,		-1 },
9041edb306SCy Schubert 	{ "ts",		IL_IPO_TS,		-1 },
9141edb306SCy Schubert 	{ "tr",		IL_IPO_TR,		-1 },
9241edb306SCy Schubert 	{ "sec",	IL_IPO_SEC,		-1 },
9341edb306SCy Schubert 	{ "secclass",	IL_IPO_SECCLASS,	IL_TOKEN },
9441edb306SCy Schubert 	{ "lsrr",	IL_IPO_LSRR,		-1 },
9541edb306SCy Schubert 	{ "esec",	IL_IPO_ESEC,		-1 },
9641edb306SCy Schubert 	{ "cipso",	IL_IPO_CIPSO,		-1 },
9741edb306SCy Schubert 	{ "satid",	IL_IPO_SATID,		-1 },
9841edb306SCy Schubert 	{ "ssrr",	IL_IPO_SSRR,		-1 },
9941edb306SCy Schubert 	{ "addext",	IL_IPO_ADDEXT,		-1 },
10041edb306SCy Schubert 	{ "visa",	IL_IPO_VISA,		-1 },
10141edb306SCy Schubert 	{ "imitd",	IL_IPO_IMITD,		-1 },
10241edb306SCy Schubert 	{ "eip",	IL_IPO_EIP,		-1 },
10341edb306SCy Schubert 	{ "finn",	IL_IPO_FINN,		-1 },
10441edb306SCy Schubert 	{ "mss",	IL_TCPO_MSS,		IL_TOKEN },
10541edb306SCy Schubert 	{ "wscale",	IL_TCPO_WSCALE,		IL_TOKEN },
10641edb306SCy Schubert 	{ "reserv-4",	IL_IPS_RESERV4,		-1 },
10741edb306SCy Schubert 	{ "topsecret",	IL_IPS_TOPSECRET,	-1 },
10841edb306SCy Schubert 	{ "secret",	IL_IPS_SECRET,		-1 },
10941edb306SCy Schubert 	{ "reserv-3",	IL_IPS_RESERV3,		-1 },
11041edb306SCy Schubert 	{ "confid",	IL_IPS_CONFID,		-1 },
11141edb306SCy Schubert 	{ "unclass",	IL_IPS_UNCLASS,		-1 },
11241edb306SCy Schubert 	{ "reserv-2",	IL_IPS_RESERV2,		-1 },
11341edb306SCy Schubert 	{ "reserv-1",	IL_IPS_RESERV1,		-1 },
11441edb306SCy Schubert 	{ "icmp",	IL_ICMP,		-1 },
11541edb306SCy Schubert 	{ "type",	IL_ICMPTYPE,		-1 },
11641edb306SCy Schubert 	{ "code",	IL_ICMPCODE,		-1 },
11741edb306SCy Schubert 	{ "echorep",	IL_ICMP_ECHOREPLY,	-1 },
11841edb306SCy Schubert 	{ "unreach",	IL_ICMP_UNREACH,	-1 },
11941edb306SCy Schubert 	{ "squench",	IL_ICMP_SOURCEQUENCH,	-1 },
12041edb306SCy Schubert 	{ "redir",	IL_ICMP_REDIRECT,	-1 },
12141edb306SCy Schubert 	{ "echo",	IL_ICMP_ECHO,		-1 },
12241edb306SCy Schubert 	{ "routerad",	IL_ICMP_ROUTERADVERT,	-1 },
12341edb306SCy Schubert 	{ "routersol",	IL_ICMP_ROUTERSOLICIT,	-1 },
12441edb306SCy Schubert 	{ "timex",	IL_ICMP_TIMXCEED,	-1 },
12541edb306SCy Schubert 	{ "paramprob",	IL_ICMP_PARAMPROB,	-1 },
12641edb306SCy Schubert 	{ "timest",	IL_ICMP_TSTAMP,		-1 },
12741edb306SCy Schubert 	{ "timestrep",	IL_ICMP_TSTAMPREPLY,	-1 },
12841edb306SCy Schubert 	{ "inforeq",	IL_ICMP_IREQ,		-1 },
12941edb306SCy Schubert 	{ "inforep",	IL_ICMP_IREQREPLY,	-1 },
13041edb306SCy Schubert 	{ "maskreq",	IL_ICMP_MASKREQ,	-1 },
13141edb306SCy Schubert 	{ "maskrep",	IL_ICMP_MASKREPLY,	-1 },
13241edb306SCy Schubert 	{ "net-unr",	IL_ICMP_UNREACH_NET,	-1 },
13341edb306SCy Schubert 	{ "host-unr",	IL_ICMP_UNREACH_HOST,	-1 },
13441edb306SCy Schubert 	{ "proto-unr",	IL_ICMP_UNREACH_PROTOCOL,	-1 },
13541edb306SCy Schubert 	{ "port-unr",	IL_ICMP_UNREACH_PORT,	-1 },
13641edb306SCy Schubert 	{ "needfrag",	IL_ICMP_UNREACH_NEEDFRAG,	-1 },
13741edb306SCy Schubert 	{ "srcfail",	IL_ICMP_UNREACH_SRCFAIL,	-1 },
13841edb306SCy Schubert 	{ "net-unk",	IL_ICMP_UNREACH_NET_UNKNOWN,	-1 },
13941edb306SCy Schubert 	{ "host-unk",	IL_ICMP_UNREACH_HOST_UNKNOWN,	-1 },
14041edb306SCy Schubert 	{ "isolate",	IL_ICMP_UNREACH_ISOLATED,	-1 },
14141edb306SCy Schubert 	{ "net-prohib",	IL_ICMP_UNREACH_NET_PROHIB,	-1 },
14241edb306SCy Schubert 	{ "host-prohib",	IL_ICMP_UNREACH_HOST_PROHIB,	-1 },
14341edb306SCy Schubert 	{ "net-tos",	IL_ICMP_UNREACH_TOSNET,	-1 },
14441edb306SCy Schubert 	{ "host-tos",	IL_ICMP_UNREACH_TOSHOST,	-1 },
14541edb306SCy Schubert 	{ "filter-prohib",	IL_ICMP_UNREACH_FILTER_PROHIB,	-1 },
14641edb306SCy Schubert 	{ "host-preced",	IL_ICMP_UNREACH_HOST_PRECEDENCE,	-1 },
14741edb306SCy Schubert 	{ "cutoff-preced",	IL_ICMP_UNREACH_PRECEDENCE_CUTOFF,	-1 },
14841edb306SCy Schubert 	{ "net-redir",	IL_ICMP_REDIRECT_NET,	-1 },
14941edb306SCy Schubert 	{ "host-redir",	IL_ICMP_REDIRECT_HOST,	-1 },
15041edb306SCy Schubert 	{ "tos-net-redir",	IL_ICMP_REDIRECT_TOSNET,	-1 },
15141edb306SCy Schubert 	{ "tos-host-redir",	IL_ICMP_REDIRECT_TOSHOST,	-1 },
15241edb306SCy Schubert 	{ "intrans",	IL_ICMP_TIMXCEED_INTRANS,	-1 },
15341edb306SCy Schubert 	{ "reass",	IL_ICMP_TIMXCEED_REASS,	-1 },
15441edb306SCy Schubert 	{ "optabsent",	IL_ICMP_PARAMPROB_OPTABSENT,	-1 },
15541edb306SCy Schubert 	{ "otime",	IL_ICMP_OTIME,		-1 },
15641edb306SCy Schubert 	{ "rtime",	IL_ICMP_RTIME,		-1 },
15741edb306SCy Schubert 	{ "ttime",	IL_ICMP_TTIME,		-1 },
15841edb306SCy Schubert 	{ "icmpseq",	IL_ICMP_SEQ,		-1 },
15941edb306SCy Schubert 	{ "icmpid",	IL_ICMP_SEQ,		-1 },
16041edb306SCy Schubert 	{ ".",		IL_DOT,			-1 },
16141edb306SCy Schubert 	{ NULL, 0, 0 }
16241edb306SCy Schubert };
16341edb306SCy Schubert %}
16441edb306SCy Schubert white	[ \t\r]+
16541edb306SCy Schubert %%
16641edb306SCy Schubert {white}	;
16741edb306SCy Schubert \n	{ lineNum++; swallow(); }
168*2582ae57SCy Schubert \{	{( push_proto(); return next_item('{'); });
169*2582ae57SCy Schubert \}	{( pop_proto(); return next_item('}'); });
170*2582ae57SCy Schubert ;	{( return next_item(';'); });
171*2582ae57SCy Schubert [0-9]+	{( return next_item(IL_NUMBER); });
172*2582ae57SCy Schubert [0-9a-fA-F]	{( return next_item(IL_HEXDIGIT); });
173*2582ae57SCy Schubert :	{( return next_item(IL_COLON); });
174*2582ae57SCy Schubert #[^\n]*	{( return next_item(IL_COMMENT); });
175*2582ae57SCy Schubert [^( \{\}\n\t;:{}]*	{ return next_item(IL_TOKEN); });
176*2582ae57SCy Schubert \"[^\"]*\"	{( return next_item(IL_TOKEN); });
17741edb306SCy Schubert %%
17841edb306SCy Schubert void    yyerror(msg)
17941edb306SCy Schubert char    *msg;
18041edb306SCy Schubert {
18141edb306SCy Schubert 	fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
18241edb306SCy Schubert 		lineNum + 1);
18341edb306SCy Schubert 	exit(1);
18441edb306SCy Schubert }
18541edb306SCy Schubert 
18641edb306SCy Schubert 
187efeb8bffSCy Schubert void push_proto(void)
18841edb306SCy Schubert {
18941edb306SCy Schubert 	numpr++;
19041edb306SCy Schubert 	if (!prstack)
19141edb306SCy Schubert 		prstack = (int *)malloc(sizeof(int));
19241edb306SCy Schubert 	else
19341edb306SCy Schubert 		prstack = (int *)reallocarray((char *)prstack, numpr,
19441edb306SCy Schubert 		    sizeof(int));
19541edb306SCy Schubert 	prstack[numpr - 1] = oldipproto;
19641edb306SCy Schubert }
19741edb306SCy Schubert 
19841edb306SCy Schubert 
199efeb8bffSCy Schubert void pop_proto(void)
20041edb306SCy Schubert {
20141edb306SCy Schubert 	numpr--;
20241edb306SCy Schubert 	ipproto = prstack[numpr];
20341edb306SCy Schubert 	if (!numpr) {
20441edb306SCy Schubert 		free(prstack);
20541edb306SCy Schubert 		prstack = NULL;
20641edb306SCy Schubert 		return;
20741edb306SCy Schubert 	}
20841edb306SCy Schubert 	prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
20941edb306SCy Schubert }
21041edb306SCy Schubert 
21141edb306SCy Schubert 
212efeb8bffSCy Schubert int save_token(void)
21341edb306SCy Schubert {
21441edb306SCy Schubert 
21541edb306SCy Schubert 	yylval.str = strdup((char *)yytext);
216*2582ae57SCy Schubert 	return(IL_TOKEN);
21741edb306SCy Schubert }
21841edb306SCy Schubert 
21941edb306SCy Schubert 
220efeb8bffSCy Schubert int next_item(int nstate)
22141edb306SCy Schubert {
22241edb306SCy Schubert 	struct	lwordtab	*wt;
22341edb306SCy Schubert 
22441edb306SCy Schubert 	if (opts & OPT_DEBUG)
22541edb306SCy Schubert 		printf("text=[%s] id=%d next=%d\n", yytext, nstate, next);
22641edb306SCy Schubert 	if (next == IL_TOKEN) {
22741edb306SCy Schubert 		next = -1;
228*2582ae57SCy Schubert 		return(save_token());
22941edb306SCy Schubert 	}
23041edb306SCy Schubert 	token++;
23141edb306SCy Schubert 
23241edb306SCy Schubert 	for (wt = words; wt->word; wt++)
23341edb306SCy Schubert 		if (!strcasecmp(wt->word, (char *)yytext))
234*2582ae57SCy Schubert 			return(next_state(wt->state, wt->next));
23541edb306SCy Schubert 	if (opts & OPT_DEBUG)
23641edb306SCy Schubert 		printf("unknown keyword=[%s]\n", yytext);
23741edb306SCy Schubert 	next = -1;
23841edb306SCy Schubert 	if (nstate == IL_NUMBER)
23941edb306SCy Schubert 		yylval.num = atoi((char *)yytext);
24041edb306SCy Schubert 	token++;
241*2582ae57SCy Schubert 	return(nstate);
24241edb306SCy Schubert }
24341edb306SCy Schubert 
24441edb306SCy Schubert 
245efeb8bffSCy Schubert int next_state(int nstate, int fornext)
24641edb306SCy Schubert {
24741edb306SCy Schubert 	next = fornext;
24841edb306SCy Schubert 
24941edb306SCy Schubert 	switch (nstate)
25041edb306SCy Schubert 	{
25141edb306SCy Schubert 	case IL_IPV4 :
25241edb306SCy Schubert 	case IL_TCP :
25341edb306SCy Schubert 	case IL_UDP :
25441edb306SCy Schubert 	case IL_ICMP :
25541edb306SCy Schubert 	case IL_DATA :
25641edb306SCy Schubert 	case IL_INTERFACE :
25741edb306SCy Schubert 	case IL_ARP :
25841edb306SCy Schubert 		oldipproto = ipproto;
25941edb306SCy Schubert 		ipproto = nstate;
26041edb306SCy Schubert 		break;
26141edb306SCy Schubert 	case IL_SUM :
26241edb306SCy Schubert 		if (ipproto == IL_IPV4)
26341edb306SCy Schubert 			nstate = IL_V4SUM;
26441edb306SCy Schubert 		else if (ipproto == IL_TCP)
26541edb306SCy Schubert 			nstate = IL_TCPSUM;
26641edb306SCy Schubert 		else if (ipproto == IL_UDP)
26741edb306SCy Schubert 			nstate = IL_UDPSUM;
26841edb306SCy Schubert 		break;
26941edb306SCy Schubert 	case IL_OPT :
27041edb306SCy Schubert 		if (ipproto == IL_IPV4)
27141edb306SCy Schubert 			nstate = IL_V4OPT;
27241edb306SCy Schubert 		else if (ipproto == IL_TCP)
27341edb306SCy Schubert 			nstate = IL_TCPOPT;
27441edb306SCy Schubert 		break;
27541edb306SCy Schubert 	case IL_IPO_NOP :
27641edb306SCy Schubert 		if (ipproto == IL_TCP)
27741edb306SCy Schubert 			nstate = IL_TCPO_NOP;
27841edb306SCy Schubert 		break;
27941edb306SCy Schubert 	case IL_IPO_EOL :
28041edb306SCy Schubert 		if (ipproto == IL_TCP)
28141edb306SCy Schubert 			nstate = IL_TCPO_EOL;
28241edb306SCy Schubert 		break;
28341edb306SCy Schubert 	case IL_IPO_TS :
28441edb306SCy Schubert 		if (ipproto == IL_TCP)
28541edb306SCy Schubert 			nstate = IL_TCPO_TS;
28641edb306SCy Schubert 		break;
28741edb306SCy Schubert 	case IL_OFF :
28841edb306SCy Schubert 		if (ipproto == IL_IPV4)
28941edb306SCy Schubert 			nstate = IL_V4OFF;
29041edb306SCy Schubert 		else if (ipproto == IL_TCP)
29141edb306SCy Schubert 			nstate = IL_TCPOFF;
29241edb306SCy Schubert 		break;
29341edb306SCy Schubert 	case IL_LEN :
29441edb306SCy Schubert 		if (ipproto == IL_IPV4)
29541edb306SCy Schubert 			nstate = IL_V4LEN;
29641edb306SCy Schubert 		else if (ipproto == IL_UDP)
29741edb306SCy Schubert 			nstate = IL_UDPLEN;
29841edb306SCy Schubert 		break;
29941edb306SCy Schubert 	}
300*2582ae57SCy Schubert 	return(nstate);
30141edb306SCy Schubert }
30241edb306SCy Schubert 
30341edb306SCy Schubert 
304efeb8bffSCy Schubert void swallow(void)
30541edb306SCy Schubert {
30641edb306SCy Schubert 	int c;
30741edb306SCy Schubert 
30841edb306SCy Schubert 	c = input();
30941edb306SCy Schubert 
31041edb306SCy Schubert 	if (c == '#') {
31141edb306SCy Schubert 		while ((c != '\n') && (c != EOF))
31241edb306SCy Schubert 			c = input();
31341edb306SCy Schubert 	}
31441edb306SCy Schubert 	if (c != EOF)
31541edb306SCy Schubert 		unput(c);
31641edb306SCy Schubert }
317