1 /* Copyright (C) 2000-2016 Boris Wesslowski */
2 /* $Id: ipfw.l 741 2016-02-19 14:35:50Z bw $ */
3 
4 %option prefix="ipfw"
5 %option outfile="ipfw.c"
6 %option noyywrap
7 
8 %{
9 #define YY_NO_INPUT
10 
11 #include <unistd.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include "main.h"
15 #include "utils.h"
16 
17 extern struct options opt;
18 
19 void ipfw_parse_start(char *input);
20 void ipfw_parse_proto(char *input, unsigned char mode);
21 void ipfw_parse_ips(char *input, unsigned char mode);
22 %}
23 
24 MONTH	"Jan"|"Feb"|"Mar"|"Apr"|"May"|"Jun"|"Jul"|"Aug"|"Sep"|"Oct"|"Nov"|"Dec"
25 STRING	[a-zA-Z][a-zA-Z0-9.-]*
26 LOGHOST	[0-9.a-zA-Z()_:-]*
27 DIGIT	[0-9]
28 NUMBER	{DIGIT}+
29 OCTET	{DIGIT}{1,3}
30 PORT	{DIGIT}{1,5}
31 PROTO	"TCP"|"UDP"
32 
33 %%
34 
35 {MONTH}[ ]{1,2}{DIGIT}{1,2}[ ]{DIGIT}{2}:{DIGIT}{2}:{DIGIT}{2}[ ]{LOGHOST}	ipfw_parse_start(ipfwtext);
36 " /"?"kernel: ipfw: "{NUMBER}  { xstrncpy(opt.line->chainlabel, ipfwtext+14, SHORTLEN); opt.parser=opt.parser|IPFW_CHAIN; };
37 " ipfw: "{NUMBER}		{ xstrncpy(opt.line->chainlabel, ipfwtext+7, SHORTLEN); opt.parser=opt.parser|IPFW_CHAIN; };
38 "Deny"				{ xstrncpy(opt.line->branchname, ipfwtext, SHORTLEN); opt.parser=opt.parser|IPFW_BRANCH; };
39 "Count"				{ xstrncpy(opt.line->branchname, ipfwtext, SHORTLEN); opt.parser=opt.parser|IPFW_BRANCH; };
40 "Accept"			{ xstrncpy(opt.line->branchname, ipfwtext, SHORTLEN); opt.parser=opt.parser|IPFW_BRANCH; };
41 {PROTO}				ipfw_parse_proto(ipfwtext, IPFW_OPT_NONE);
42 "ICMP:"{NUMBER}"."{NUMBER}	ipfw_parse_proto(ipfwtext+5, IPFW_OPT_ICMP);
43 {OCTET}"."{OCTET}"."{OCTET}"."{OCTET}[ ]{OCTET}"."{OCTET}"."{OCTET}"."{OCTET}			ipfw_parse_ips(ipfwtext, IPFW_OPT_NONE);
44 {OCTET}"."{OCTET}"."{OCTET}"."{OCTET}":"{PORT}[ ]{OCTET}"."{OCTET}"."{OCTET}"."{OCTET}":"{PORT}	ipfw_parse_ips(ipfwtext, IPFW_OPT_PORTS);
45 "in via "{STRING}		{ xstrncpy(opt.line->interface, ipfwtext+7, SHORTLEN); opt.parser=opt.parser|IPFW_IF; }
46 [ ]				/* ignore whitespace */
47 [\n]				return 0;
48 {STRING}			if(opt.verbose) fprintf(stderr, "Unrecognized token: %s\n", ipfwtext);
49 .				if(opt.verbose) fprintf(stderr, "Unrecognized character: %s\n", ipfwtext);
50 
51 %%
52 
53 void ipfw_parse_start(char *input)
54 {
55   int retval, day, hour, minute, second;
56   char smonth[4];
57 
58   retval = sscanf(input, "%3s %2d %2d:%2d:%2d %32s", smonth, &day, &hour, &minute, &second, opt.line->hostname);
59   if (retval != 6) {
60     return;
61   }
62 
63   build_time(smonth, day, hour, minute, second);
64 
65   opt.parser = opt.parser | IPFW_DATE;
66 }
67 
ipfw_parse_proto(char * input,unsigned char mode)68 void ipfw_parse_proto(char *input, unsigned char mode)
69 {
70   int retval;
71   char *pnt;
72 
73   if (mode == IPFW_OPT_NONE) {
74     if (strncmp(input, "TCP", 3) == 0)
75       opt.line->protocol = 6;
76     if (strncmp(input, "UDP", 3) == 0)
77       opt.line->protocol = 17;
78   } else if (mode == IPFW_OPT_ICMP) {
79     opt.line->protocol = 1;
80     pnt = strstr(input, ".");
81     *pnt = ' ';
82     retval = sscanf(input, "%2d %2d", &opt.line->sport, &opt.line->dport);
83     if (retval != 2) {
84       return;
85     }
86     opt.parser = opt.parser | IPFW_PORTS;
87   }
88   if (opt.line->protocol != 0) {
89     opt.parser = opt.parser | IPFW_PROTO;
90   }
91 }
92 
ipfw_parse_ips(char * input,unsigned char mode)93 void ipfw_parse_ips(char *input, unsigned char mode)
94 {
95   int retval;
96   char src[16], dst[16], *pnt;
97 
98   if (mode == IPFW_OPT_PORTS) {
99     pnt = strstr(input, ":");
100     *pnt = ' ';
101     pnt = strstr(input, ":");
102     *pnt = ' ';
103     retval = sscanf(input, "%16s %5d %16s %5d", src, &opt.line->sport, dst, &opt.line->dport);
104     if (retval != 4) {
105       return;
106     }
107     opt.parser = opt.parser | IPFW_PORTS;
108   } else if (mode == IPFW_OPT_NONE) {
109     retval = sscanf(input, "%16s %16s", src, dst);
110     if (retval != 2) {
111       return;
112     }
113   }
114 
115   if (convert_ip(src, &opt.line->shost) == IN_ADDR_ERROR)
116     return;
117   if (convert_ip(dst, &opt.line->dhost) == IN_ADDR_ERROR)
118     return;
119   opt.parser = opt.parser | IPFW_IPS;
120 }
121 
flex_ipfw(char * input,int linenum)122 unsigned char flex_ipfw(char *input, int linenum)
123 {
124   opt.parser = 0;
125   init_line();
126   ipfw_scan_string(input);
127   ipfwlex();
128   ipfw_delete_buffer(YY_CURRENT_BUFFER);
129 
130   opt.line->count = 1;
131 
132   if (opt.parser == (IPFW_DATE | IPFW_CHAIN | IPFW_BRANCH | IPFW_PROTO | IPFW_IPS | IPFW_PORTS | IPFW_IF)) {
133     return PARSE_OK;
134   }
135   if (opt.verbose)
136     fprintf(stderr, "ipfw parse error in line %d, ignoring.\n", linenum);
137   if (opt.verbose == 2)
138     fprintf(stderr, "input was: \"%s\"\n", input);
139   return PARSE_WRONG_FORMAT;
140 }
141