1145519Sdarrenr/*	$FreeBSD: stable/11/contrib/ipfilter/iplang/iplang_l.l 369245 2021-02-09 13:47:46Z git2svn $	*/
2145510Sdarrenr
331183Speter%{
431183Speter/*
5255332Scy * Copyright (C) 2012 by Darren Reed.
631183Speter *
7145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
831183Speter *
9255332Scy * $Id$
1031183Speter */
1131183Speter#include <stdio.h>
1231183Speter#include <string.h>
1331183Speter#include <sys/param.h>
1431183Speter#if defined(__SVR4) || defined(__sysv__)
1531183Speter#include <sys/stream.h>
1631183Speter#endif
1731183Speter#include <sys/types.h>
1831183Speter#include <netinet/in_systm.h>
1931183Speter#include <netinet/in.h>
20145510Sdarrenr#include "iplang_y.h"
2131183Speter#include "ipf.h"
2231183Speter
2331183Speter#ifndef	__P
2431183Speter#  define	__P(x)	x
2531183Speter#endif
2631183Speter
2731183Speterextern int opts;
2831183Speter
2960841Sdarrenrint lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0;
3031183Speterint *prstack = NULL, numpr = 0, state = 0, token = 0;
3131183Speter
32369245Sgit2svnvoid    yyerror(char *);
33369245Sgit2svnvoid	push_proto(void);
34369245Sgit2svnvoid	pop_proto(void);
35369245Sgit2svnint	next_state(int, int);
36369245Sgit2svnint	next_item(int);
37369245Sgit2svnint	save_token(void);
38369245Sgit2svnvoid	swallow(void);
39369245Sgit2svnint	yylex(void);
4037074Speter
41145510Sdarrenrstruct	lwordtab	{
4237074Speter	char	*word;
4337074Speter	int	state;
4437074Speter	int	next;
4537074Speter};
4637074Speter
47145510Sdarrenrstruct	lwordtab	words[] = {
4837074Speter	{ "interface",	IL_INTERFACE,		-1 },
4937074Speter	{ "iface",	IL_INTERFACE,		-1 },
5037074Speter	{ "name",	IL_IFNAME,		IL_TOKEN },
5137074Speter	{ "ifname",	IL_IFNAME,		IL_TOKEN },
5237074Speter	{ "router",	IL_DEFROUTER,		IL_TOKEN },
5337074Speter	{ "mtu",	IL_MTU,			IL_NUMBER },
5437074Speter	{ "eaddr",	IL_EADDR,		IL_TOKEN },
5537074Speter	{ "v4addr",	IL_V4ADDR,		IL_TOKEN },
5637074Speter	{ "ipv4",	IL_IPV4,		-1 },
5737074Speter	{ "v",		IL_V4V,			IL_TOKEN },
5837074Speter	{ "proto",	IL_V4PROTO,		IL_TOKEN },
5937074Speter	{ "hl",		IL_V4HL,		IL_TOKEN },
6037074Speter	{ "id",		IL_V4ID,		IL_TOKEN },
6137074Speter	{ "ttl",	IL_V4TTL,		IL_TOKEN },
6237074Speter	{ "tos",	IL_V4TOS,		IL_TOKEN },
6337074Speter	{ "src",	IL_V4SRC,		IL_TOKEN },
6437074Speter	{ "dst",	IL_V4DST,		IL_TOKEN },
6537074Speter	{ "opt",	IL_OPT,			-1 },
6637074Speter	{ "len",	IL_LEN,			IL_TOKEN },
6737074Speter	{ "off",	IL_OFF,			IL_TOKEN },
6837074Speter	{ "sum",	IL_SUM,			IL_TOKEN },
6937074Speter	{ "tcp",	IL_TCP,			-1 },
7037074Speter	{ "sport",	IL_SPORT,		IL_TOKEN },
7137074Speter	{ "dport",	IL_DPORT,		IL_TOKEN },
7237074Speter	{ "seq",	IL_TCPSEQ,		IL_TOKEN },
7337074Speter	{ "ack",	IL_TCPACK,		IL_TOKEN },
7437074Speter	{ "flags",	IL_TCPFL,		IL_TOKEN },
7537074Speter	{ "urp",	IL_TCPURP,		IL_TOKEN },
7637074Speter	{ "win",	IL_TCPWIN,		IL_TOKEN },
7737074Speter	{ "udp",	IL_UDP,			-1 },
7837074Speter	{ "send",	IL_SEND,		-1 },
7937074Speter	{ "via",	IL_VIA,			IL_TOKEN },
8037074Speter	{ "arp",	IL_ARP,			-1 },
8137074Speter	{ "data",	IL_DATA,		-1 },
8237074Speter	{ "value",	IL_DVALUE,		IL_TOKEN },
8337074Speter	{ "file",	IL_DFILE,		IL_TOKEN },
8437074Speter	{ "nop",	IL_IPO_NOP,		-1 },
8537074Speter	{ "eol",	IL_IPO_EOL,		-1 },
8637074Speter	{ "rr",		IL_IPO_RR,		-1 },
8737074Speter	{ "zsu",	IL_IPO_ZSU,		-1 },
8837074Speter	{ "mtup",	IL_IPO_MTUP,		-1 },
8937074Speter	{ "mtur",	IL_IPO_MTUR,		-1 },
9037074Speter	{ "encode",	IL_IPO_ENCODE,		-1 },
9137074Speter	{ "ts",		IL_IPO_TS,		-1 },
9237074Speter	{ "tr",		IL_IPO_TR,		-1 },
9337074Speter	{ "sec",	IL_IPO_SEC,		-1 },
9437074Speter	{ "secclass",	IL_IPO_SECCLASS,	IL_TOKEN },
9537074Speter	{ "lsrr",	IL_IPO_LSRR,		-1 },
9637074Speter	{ "esec",	IL_IPO_ESEC,		-1 },
9737074Speter	{ "cipso",	IL_IPO_CIPSO,		-1 },
9837074Speter	{ "satid",	IL_IPO_SATID,		-1 },
9937074Speter	{ "ssrr",	IL_IPO_SSRR,		-1 },
10037074Speter	{ "addext",	IL_IPO_ADDEXT,		-1 },
10137074Speter	{ "visa",	IL_IPO_VISA,		-1 },
10237074Speter	{ "imitd",	IL_IPO_IMITD,		-1 },
10337074Speter	{ "eip",	IL_IPO_EIP,		-1 },
10437074Speter	{ "finn",	IL_IPO_FINN,		-1 },
10537074Speter	{ "mss",	IL_TCPO_MSS,		IL_TOKEN },
10637074Speter	{ "wscale",	IL_TCPO_WSCALE,		IL_TOKEN },
10737074Speter	{ "reserv-4",	IL_IPS_RESERV4,		-1 },
10837074Speter	{ "topsecret",	IL_IPS_TOPSECRET,	-1 },
10937074Speter	{ "secret",	IL_IPS_SECRET,		-1 },
11037074Speter	{ "reserv-3",	IL_IPS_RESERV3,		-1 },
11137074Speter	{ "confid",	IL_IPS_CONFID,		-1 },
11237074Speter	{ "unclass",	IL_IPS_UNCLASS,		-1 },
11337074Speter	{ "reserv-2",	IL_IPS_RESERV2,		-1 },
11437074Speter	{ "reserv-1",	IL_IPS_RESERV1,		-1 },
11537074Speter	{ "icmp",	IL_ICMP,		-1 },
11637074Speter	{ "type",	IL_ICMPTYPE,		-1 },
11737074Speter	{ "code",	IL_ICMPCODE,		-1 },
11837074Speter	{ "echorep",	IL_ICMP_ECHOREPLY,	-1 },
11937074Speter	{ "unreach",	IL_ICMP_UNREACH,	-1 },
12037074Speter	{ "squench",	IL_ICMP_SOURCEQUENCH,	-1 },
12137074Speter	{ "redir",	IL_ICMP_REDIRECT,	-1 },
12237074Speter	{ "echo",	IL_ICMP_ECHO,		-1 },
12337074Speter	{ "routerad",	IL_ICMP_ROUTERADVERT,	-1 },
12437074Speter	{ "routersol",	IL_ICMP_ROUTERSOLICIT,	-1 },
12537074Speter	{ "timex",	IL_ICMP_TIMXCEED,	-1 },
12637074Speter	{ "paramprob",	IL_ICMP_PARAMPROB,	-1 },
12737074Speter	{ "timest",	IL_ICMP_TSTAMP,		-1 },
12837074Speter	{ "timestrep",	IL_ICMP_TSTAMPREPLY,	-1 },
12937074Speter	{ "inforeq",	IL_ICMP_IREQ,		-1 },
13037074Speter	{ "inforep",	IL_ICMP_IREQREPLY,	-1 },
13137074Speter	{ "maskreq",	IL_ICMP_MASKREQ,	-1 },
13237074Speter	{ "maskrep",	IL_ICMP_MASKREPLY,	-1 },
13337074Speter	{ "net-unr",	IL_ICMP_UNREACH_NET,	-1 },
13437074Speter	{ "host-unr",	IL_ICMP_UNREACH_HOST,	-1 },
13537074Speter	{ "proto-unr",	IL_ICMP_UNREACH_PROTOCOL,	-1 },
13637074Speter	{ "port-unr",	IL_ICMP_UNREACH_PORT,	-1 },
13737074Speter	{ "needfrag",	IL_ICMP_UNREACH_NEEDFRAG,	-1 },
13837074Speter	{ "srcfail",	IL_ICMP_UNREACH_SRCFAIL,	-1 },
13937074Speter	{ "net-unk",	IL_ICMP_UNREACH_NET_UNKNOWN,	-1 },
14037074Speter	{ "host-unk",	IL_ICMP_UNREACH_HOST_UNKNOWN,	-1 },
14137074Speter	{ "isolate",	IL_ICMP_UNREACH_ISOLATED,	-1 },
14237074Speter	{ "net-prohib",	IL_ICMP_UNREACH_NET_PROHIB,	-1 },
14337074Speter	{ "host-prohib",	IL_ICMP_UNREACH_HOST_PROHIB,	-1 },
14437074Speter	{ "net-tos",	IL_ICMP_UNREACH_TOSNET,	-1 },
14537074Speter	{ "host-tos",	IL_ICMP_UNREACH_TOSHOST,	-1 },
14637074Speter	{ "filter-prohib",	IL_ICMP_UNREACH_FILTER_PROHIB,	-1 },
14737074Speter	{ "host-preced",	IL_ICMP_UNREACH_HOST_PRECEDENCE,	-1 },
14837074Speter	{ "cutoff-preced",	IL_ICMP_UNREACH_PRECEDENCE_CUTOFF,	-1 },
14937074Speter	{ "net-redir",	IL_ICMP_REDIRECT_NET,	-1 },
15037074Speter	{ "host-redir",	IL_ICMP_REDIRECT_HOST,	-1 },
15137074Speter	{ "tos-net-redir",	IL_ICMP_REDIRECT_TOSNET,	-1 },
15237074Speter	{ "tos-host-redir",	IL_ICMP_REDIRECT_TOSHOST,	-1 },
15337074Speter	{ "intrans",	IL_ICMP_TIMXCEED_INTRANS,	-1 },
15437074Speter	{ "reass",	IL_ICMP_TIMXCEED_REASS,	-1 },
15537074Speter	{ "optabsent",	IL_ICMP_PARAMPROB_OPTABSENT,	-1 },
15637074Speter	{ "otime",	IL_ICMP_OTIME,		-1 },
15737074Speter	{ "rtime",	IL_ICMP_RTIME,		-1 },
15837074Speter	{ "ttime",	IL_ICMP_TTIME,		-1 },
15937074Speter	{ "icmpseq",	IL_ICMP_SEQ,		-1 },
16037074Speter	{ "icmpid",	IL_ICMP_SEQ,		-1 },
16137074Speter	{ ".",		IL_DOT,			-1 },
16237074Speter	{ NULL, 0, 0 }
16337074Speter};
16431183Speter%}
16537074Speterwhite	[ \t\r]+
16631183Speter%%
16737074Speter{white}	;
16831183Speter\n	{ lineNum++; swallow(); }
16931183Speter\{	{ push_proto(); return next_item('{'); }
17031183Speter\}	{ pop_proto(); return next_item('}'); }
17131183Speter;	{ return next_item(';'); }
17231183Speter[0-9]+	{ return next_item(IL_NUMBER); }
17331183Speter[0-9a-fA-F]	{ return next_item(IL_HEXDIGIT); }
17431183Speter:	{ return next_item(IL_COLON); }
17531183Speter#[^\n]*	{ return next_item(IL_COMMENT); }
17637074Speter[^ \{\}\n\t;:{}]*	{ return next_item(IL_TOKEN); }
17731183Speter\"[^\"]*\"	{ return next_item(IL_TOKEN); }
17831183Speter%%
17931183Spetervoid    yyerror(msg)
18031183Speterchar    *msg;
18131183Speter{
18231183Speter	fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
18331183Speter		lineNum + 1);
18431183Speter	exit(1);
18531183Speter}
18631183Speter
18731183Speter
18831183Spetervoid push_proto()
18931183Speter{
19031183Speter	numpr++;
19131183Speter	if (!prstack)
19231183Speter		prstack = (int *)malloc(sizeof(int));
19331183Speter	else
194319175Scy		prstack = (int *)reallocarray((char *)prstack, numpr,
195319175Scy		    sizeof(int));
19660841Sdarrenr	prstack[numpr - 1] = oldipproto;
19731183Speter}
19831183Speter
19931183Speter
20031183Spetervoid pop_proto()
20131183Speter{
20231183Speter	numpr--;
20360841Sdarrenr	ipproto = prstack[numpr];
20431183Speter	if (!numpr) {
20531183Speter		free(prstack);
20631183Speter		prstack = NULL;
20731183Speter		return;
20831183Speter	}
20931183Speter	prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
21031183Speter}
21131183Speter
21231183Speter
21331183Speterint save_token()
21431183Speter{
21531183Speter
216145510Sdarrenr	yylval.str = strdup((char *)yytext);
21731183Speter	return IL_TOKEN;
21831183Speter}
21931183Speter
22031183Speter
22131183Speterint next_item(nstate)
22231183Speterint nstate;
22331183Speter{
224145510Sdarrenr	struct	lwordtab	*wt;
22537074Speter
22637074Speter	if (opts & OPT_DEBUG)
22737074Speter		printf("text=[%s] id=%d next=%d\n", yytext, nstate, next);
22831183Speter	if (next == IL_TOKEN) {
22931183Speter		next = -1;
23031183Speter		return save_token();
23131183Speter	}
23237074Speter	token++;
23337074Speter
23437074Speter	for (wt = words; wt->word; wt++)
235145510Sdarrenr		if (!strcasecmp(wt->word, (char *)yytext))
23637074Speter			return next_state(wt->state, wt->next);
23737074Speter	if (opts & OPT_DEBUG)
23837074Speter		printf("unknown keyword=[%s]\n", yytext);
23931183Speter	next = -1;
24031183Speter	if (nstate == IL_NUMBER)
241145510Sdarrenr		yylval.num = atoi((char *)yytext);
24231183Speter	token++;
24331183Speter	return nstate;
24431183Speter}
24531183Speter
24631183Speter
24731183Speterint next_state(nstate, fornext)
24831183Speterint nstate, fornext;
24931183Speter{
25031183Speter	next = fornext;
25131183Speter
25231183Speter	switch (nstate)
25331183Speter	{
25431183Speter	case IL_IPV4 :
25531183Speter	case IL_TCP :
25631183Speter	case IL_UDP :
25731183Speter	case IL_ICMP :
25831183Speter	case IL_DATA :
25931183Speter	case IL_INTERFACE :
26031183Speter	case IL_ARP :
26160841Sdarrenr		oldipproto = ipproto;
26260841Sdarrenr		ipproto = nstate;
26331183Speter		break;
26431183Speter	case IL_SUM :
26560841Sdarrenr		if (ipproto == IL_IPV4)
26631183Speter			nstate = IL_V4SUM;
26760841Sdarrenr		else if (ipproto == IL_TCP)
26831183Speter			nstate = IL_TCPSUM;
26960841Sdarrenr		else if (ipproto == IL_UDP)
27031183Speter			nstate = IL_UDPSUM;
27131183Speter		break;
27231183Speter	case IL_OPT :
27360841Sdarrenr		if (ipproto == IL_IPV4)
27431183Speter			nstate = IL_V4OPT;
27560841Sdarrenr		else if (ipproto == IL_TCP)
27631183Speter			nstate = IL_TCPOPT;
27731183Speter		break;
27831183Speter	case IL_IPO_NOP :
27960841Sdarrenr		if (ipproto == IL_TCP)
28031183Speter			nstate = IL_TCPO_NOP;
28131183Speter		break;
28231183Speter	case IL_IPO_EOL :
28360841Sdarrenr		if (ipproto == IL_TCP)
28431183Speter			nstate = IL_TCPO_EOL;
28531183Speter		break;
28631183Speter	case IL_IPO_TS :
28760841Sdarrenr		if (ipproto == IL_TCP)
28831183Speter			nstate = IL_TCPO_TS;
28931183Speter		break;
29031183Speter	case IL_OFF :
29160841Sdarrenr		if (ipproto == IL_IPV4)
29231183Speter			nstate = IL_V4OFF;
29360841Sdarrenr		else if (ipproto == IL_TCP)
29431183Speter			nstate = IL_TCPOFF;
29531183Speter		break;
29631183Speter	case IL_LEN :
29760841Sdarrenr		if (ipproto == IL_IPV4)
29831183Speter			nstate = IL_V4LEN;
29960841Sdarrenr		else if (ipproto == IL_UDP)
30031183Speter			nstate = IL_UDPLEN;
30131183Speter		break;
30231183Speter	}
30331183Speter	return nstate;
30431183Speter}
30531183Speter
30631183Speter
30731183Spetervoid swallow()
30831183Speter{
30953024Sguido	int c;
31031183Speter
31153024Sguido	c = input();
31253024Sguido
31331183Speter	if (c == '#') {
31431183Speter		while ((c != '\n') && (c != EOF))
31531183Speter			c = input();
31631183Speter	}
317130887Sdarrenr	if (c != EOF)
318130887Sdarrenr		unput(c);
31931183Speter}
320