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