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