f705d2fccd60f91e80f28ad56bf532081a4db7e1
[sip-router] / cfg.lex
1 /*
2  * $Id$
3  *
4  * scanner for cfg files
5  *
6  * Copyright (C) 2001-2003 Fhg Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License 
26  * along with this program; if not, write to the Free Software 
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  * History:
30  * -------
31  *  2003-01-29  src_port added (jiri)
32  *  2003-01-23  mhomed added (jiri)
33  *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
34  *  2003-04-01  added dst_port, proto (tcp, udp, tls), af(inet, inet6) (andrei)
35  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
36  *  2003-04-12  added force_rport, chdir and wdir (andrei)
37  */
38
39
40 %{
41         #include "cfg.tab.h"
42         #include "dprint.h"
43         #include "globals.h"
44         #include "mem/mem.h"
45         #include <string.h>
46         #include <stdlib.h>
47         #include "ip_addr.h"
48
49
50         /* states */
51         #define INITIAL_S               0
52         #define COMMENT_S               1
53         #define COMMENT_LN_S    2
54         #define STRING_S                3
55
56         
57         static int comment_nest=0;
58         static int state=0;
59         static char* tstr=0;
60         int line=1;
61         int column=1;
62         int startcolumn=1;
63
64         static char* addstr(char*, char**);
65         static void count();
66
67
68 %}
69
70 /* start conditions */
71 %x STRING1 STRING2 COMMENT COMMENT_LN
72
73 /* action keywords */
74 FORWARD forward
75 FORWARD_TCP     forward_tcp
76 FORWARD_UDP     forward_udp
77 DROP    "drop"|"break"
78 SEND    send
79 SEND_TCP        send_tcp
80 LOG             log
81 ERROR   error
82 ROUTE   route
83 ROUTE_FAILURE failure_route
84 ROUTE_ONREPLY onreply_route
85 EXEC    exec
86 FORCE_RPORT             "force_rport"|"add_rport"
87 SETFLAG         setflag
88 RESETFLAG       resetflag
89 ISFLAGSET       isflagset
90 LEN_GT          len_gt
91 SET_HOST                "rewritehost"|"sethost"|"seth"
92 SET_HOSTPORT    "rewritehostport"|"sethostport"|"sethp"
93 SET_USER                "rewriteuser"|"setuser"|"setu"
94 SET_USERPASS    "rewriteuserpass"|"setuserpass"|"setup"
95 SET_PORT                "rewriteport"|"setport"|"setp"
96 SET_URI                 "rewriteuri"|"seturi"
97 REVERT_URI              "revert_uri"
98 PREFIX                  "prefix"
99 STRIP                   "strip"
100 APPEND_BRANCH   "append_branch"
101 IF                              "if"
102 ELSE                    "else"
103
104 /*ACTION LVALUES*/
105 URIHOST                 "uri:host"
106 URIPORT                 "uri:port"
107
108 MAX_LEN                 "max_len"
109
110
111 /* condition keywords */
112 METHOD  method
113 /* hack -- the second element in first line is referrable
114    as either uri or status; it only would makes sense to
115    call it "uri" from route{} and status from onreply_route{}
116 */
117 URI             "uri"|"status"
118 SRCIP   src_ip
119 SRCPORT src_port
120 DSTIP   dst_ip
121 DSTPORT dst_port
122 PROTO   proto
123 AF              af
124 MYSELF  myself
125 /* operators */
126 EQUAL   =
127 EQUAL_T ==
128 MATCH   =~
129 NOT             !|"not"
130 AND             "and"|"&&"|"&"
131 OR              "or"|"||"|"|"
132
133 /* config vars. */
134 DEBUG   debug
135 FORK    fork
136 LOGSTDERROR     log_stderror
137 LISTEN          listen
138 ALIAS           alias
139 DNS              dns
140 REV_DNS  rev_dns
141 PORT    port
142 STAT    statistics
143 MAXBUFFER maxbuffer
144 CHILDREN children
145 CHECK_VIA       check_via
146 SYN_BRANCH syn_branch
147 MEMLOG  memlog
148 SIP_WARNING sip_warning
149 FIFO fifo
150 FIFO_MODE fifo_mode
151 SERVER_SIGNATURE server_signature
152 REPLY_TO_VIA reply_to_via
153 USER            "user"|"uid"
154 GROUP           "group"|"gid"
155 CHROOT          "chroot"
156 WDIR            "workdir"|"wdir"
157 MHOMED          mhomed
158 DISABLE_TCP             "disable_tcp"
159 TCP_CHILDREN    "tcp_children"
160
161 LOADMODULE      loadmodule
162 MODPARAM        modparam
163
164 /* values */
165 YES                     "yes"|"true"|"on"|"enable"
166 NO                      "no"|"false"|"off"|"disable"
167 UDP                     "udp"
168 TCP                     "tcp"
169 TLS                     "tls"
170 INET            "inet"
171 INET6           "inet6"
172
173 LETTER          [a-zA-Z]
174 DIGIT           [0-9]
175 ALPHANUM        {LETTER}|{DIGIT}|[_]
176 NUMBER          {DIGIT}+
177 ID                      {LETTER}{ALPHANUM}*
178 HEX                     [0-9a-fA-F]
179 HEX4            {HEX}{1,4}
180 IPV6ADDR        ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
181 QUOTES          \"
182 TICK            \'
183 SLASH           "/"
184 SEMICOLON       ;
185 RPAREN          \)
186 LPAREN          \(
187 LBRACE          \{
188 RBRACE          \}
189 LBRACK          \[
190 RBRACK          \]
191 COMMA           ","
192 DOT                     \.
193 CR                      \n
194
195
196
197 COM_LINE        #
198 COM_START       "/\*"
199 COM_END         "\*/"
200
201 EAT_ABLE        [\ \t\b\r]
202
203 %%
204
205
206 <INITIAL>{EAT_ABLE}     { count(); }
207
208 <INITIAL>{FORWARD}      {count(); yylval.strval=yytext; return FORWARD; }
209 <INITIAL>{FORWARD_TCP}  {count(); yylval.strval=yytext; return FORWARD_TCP; }
210 <INITIAL>{FORWARD_UDP}  {count(); yylval.strval=yytext; return FORWARD_UDP; }
211 <INITIAL>{DROP} { count(); yylval.strval=yytext; return DROP; }
212 <INITIAL>{SEND} { count(); yylval.strval=yytext; return SEND; }
213 <INITIAL>{SEND_TCP}     { count(); yylval.strval=yytext; return SEND_TCP; }
214 <INITIAL>{LOG}  { count(); yylval.strval=yytext; return LOG_TOK; }
215 <INITIAL>{ERROR}        { count(); yylval.strval=yytext; return ERROR; }
216 <INITIAL>{SETFLAG}      { count(); yylval.strval=yytext; return SETFLAG; }
217 <INITIAL>{RESETFLAG}    { count(); yylval.strval=yytext; return RESETFLAG; }
218 <INITIAL>{ISFLAGSET}    { count(); yylval.strval=yytext; return ISFLAGSET; }
219 <INITIAL>{LEN_GT}       { count(); yylval.strval=yytext; return LEN_GT; }
220 <INITIAL>{ROUTE}        { count(); yylval.strval=yytext; return ROUTE; }
221 <INITIAL>{ROUTE_ONREPLY}        { count(); yylval.strval=yytext;
222                                                                 return ROUTE_ONREPLY; }
223 <INITIAL>{ROUTE_FAILURE}        { count(); yylval.strval=yytext;
224                                                                 return ROUTE_FAILURE; }
225 <INITIAL>{EXEC} { count(); yylval.strval=yytext; return EXEC; }
226 <INITIAL>{SET_HOST}     { count(); yylval.strval=yytext; return SET_HOST; }
227 <INITIAL>{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; }
228 <INITIAL>{SET_USER}     { count(); yylval.strval=yytext; return SET_USER; }
229 <INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; }
230 <INITIAL>{SET_PORT}     { count(); yylval.strval=yytext; return SET_PORT; }
231 <INITIAL>{SET_URI}      { count(); yylval.strval=yytext; return SET_URI; }
232 <INITIAL>{REVERT_URI}   { count(); yylval.strval=yytext; return REVERT_URI; }
233 <INITIAL>{PREFIX}       { count(); yylval.strval=yytext; return PREFIX; }
234 <INITIAL>{STRIP}        { count(); yylval.strval=yytext; return STRIP; }
235 <INITIAL>{APPEND_BRANCH}        { count(); yylval.strval=yytext; 
236                                                                 return APPEND_BRANCH; }
237 <INITIAL>{FORCE_RPORT}  { count(); yylval.strval=yytext; return FORCE_RPORT; }
238         
239 <INITIAL>{IF}   { count(); yylval.strval=yytext; return IF; }
240 <INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; }
241
242 <INITIAL>{URIHOST}      { count(); yylval.strval=yytext; return URIHOST; }
243 <INITIAL>{URIPORT}      { count(); yylval.strval=yytext; return URIPORT; }
244
245 <INITIAL>{MAX_LEN}      { count(); yylval.strval=yytext; return MAX_LEN; }
246
247 <INITIAL>{METHOD}       { count(); yylval.strval=yytext; return METHOD; }
248 <INITIAL>{URI}  { count(); yylval.strval=yytext; return URI; }
249 <INITIAL>{SRCIP}        { count(); yylval.strval=yytext; return SRCIP; }
250 <INITIAL>{SRCPORT}      { count(); yylval.strval=yytext; return SRCPORT; }
251 <INITIAL>{DSTIP}        { count(); yylval.strval=yytext; return DSTIP; }
252 <INITIAL>{DSTPORT}      { count(); yylval.strval=yytext; return DSTPORT; }
253 <INITIAL>{PROTO}        { count(); yylval.strval=yytext; return PROTO; }
254 <INITIAL>{AF}   { count(); yylval.strval=yytext; return AF; }
255 <INITIAL>{MYSELF}       { count(); yylval.strval=yytext; return MYSELF; }
256
257 <INITIAL>{DEBUG}        { count(); yylval.strval=yytext; return DEBUG; }
258 <INITIAL>{FORK}         { count(); yylval.strval=yytext; return FORK; }
259 <INITIAL>{LOGSTDERROR}  { yylval.strval=yytext; return LOGSTDERROR; }
260 <INITIAL>{LISTEN}       { count(); yylval.strval=yytext; return LISTEN; }
261 <INITIAL>{ALIAS}        { count(); yylval.strval=yytext; return ALIAS; }
262 <INITIAL>{DNS}  { count(); yylval.strval=yytext; return DNS; }
263 <INITIAL>{REV_DNS}      { count(); yylval.strval=yytext; return REV_DNS; }
264 <INITIAL>{PORT} { count(); yylval.strval=yytext; return PORT; }
265 <INITIAL>{STAT} { count(); yylval.strval=yytext; return STAT; }
266 <INITIAL>{MAXBUFFER}    { count(); yylval.strval=yytext; return MAXBUFFER; }
267 <INITIAL>{CHILDREN}     { count(); yylval.strval=yytext; return CHILDREN; }
268 <INITIAL>{CHECK_VIA}    { count(); yylval.strval=yytext; return CHECK_VIA; }
269 <INITIAL>{SYN_BRANCH}   { count(); yylval.strval=yytext; return SYN_BRANCH; }
270 <INITIAL>{MEMLOG}       { count(); yylval.strval=yytext; return MEMLOG; }
271 <INITIAL>{SIP_WARNING}  { count(); yylval.strval=yytext; return SIP_WARNING; }
272 <INITIAL>{USER}         { count(); yylval.strval=yytext; return USER; }
273 <INITIAL>{GROUP}        { count(); yylval.strval=yytext; return GROUP; }
274 <INITIAL>{CHROOT}       { count(); yylval.strval=yytext; return CHROOT; }
275 <INITIAL>{WDIR} { count(); yylval.strval=yytext; return WDIR; }
276 <INITIAL>{MHOMED}       { count(); yylval.strval=yytext; return MHOMED; }
277 <INITIAL>{DISABLE_TCP}  { count(); yylval.strval=yytext; return DISABLE_TCP; }
278 <INITIAL>{TCP_CHILDREN} { count(); yylval.strval=yytext; return TCP_CHILDREN; }
279 <INITIAL>{FIFO} { count(); yylval.strval=yytext; return FIFO; }
280 <INITIAL>{FIFO_MODE}    { count(); yylval.strval=yytext; return FIFO_MODE; }
281 <INITIAL>{SERVER_SIGNATURE}     { count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
282 <INITIAL>{REPLY_TO_VIA} { count(); yylval.strval=yytext; return REPLY_TO_VIA; }
283 <INITIAL>{LOADMODULE}   { count(); yylval.strval=yytext; return LOADMODULE; }
284 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
285
286 <INITIAL>{EQUAL}        { count(); return EQUAL; }
287 <INITIAL>{EQUAL_T}      { count(); return EQUAL_T; }
288 <INITIAL>{MATCH}        { count(); return MATCH; }
289 <INITIAL>{NOT}          { count(); return NOT; }
290 <INITIAL>{AND}          { count(); return AND; }
291 <INITIAL>{OR}           { count(); return OR;  }
292
293
294
295 <INITIAL>{IPV6ADDR}             { count(); yylval.strval=yytext; return IPV6ADDR; }
296 <INITIAL>{NUMBER}               { count(); yylval.intval=atoi(yytext);return NUMBER; }
297 <INITIAL>{YES}                  { count(); yylval.intval=1; return NUMBER; }
298 <INITIAL>{NO}                   { count(); yylval.intval=0; return NUMBER; }
299 <INITIAL>{TCP}                  { count(); yylval.intval=PROTO_TCP; return NUMBER; }
300 <INITIAL>{UDP}                  { count(); yylval.intval=PROTO_UDP; return NUMBER; }
301 <INITIAL>{TLS}                  { count(); yylval.intval=PROTO_TLS; return NUMBER; }
302 <INITIAL>{INET}                 { count(); yylval.intval=AF_INET; return NUMBER; }
303 <INITIAL>{INET6}                { count();
304                                                 #ifdef USE_IPV6
305                                                   yylval.intval=AF_INET6;
306                                                 #else
307                                                   yylval.intval=-1; /* no match*/
308                                                 #endif
309                                                   return NUMBER; }
310
311 <INITIAL>{COMMA}                { count(); return COMMA; }
312 <INITIAL>{SEMICOLON}    { count(); return SEMICOLON; }
313 <INITIAL>{RPAREN}       { count(); return RPAREN; }
314 <INITIAL>{LPAREN}       { count(); return LPAREN; }
315 <INITIAL>{LBRACE}       { count(); return LBRACE; }
316 <INITIAL>{RBRACE}       { count(); return RBRACE; }
317 <INITIAL>{LBRACK}       { count(); return LBRACK; }
318 <INITIAL>{RBRACK}       { count(); return RBRACK; }
319 <INITIAL>{SLASH}        { count(); return SLASH; }
320 <INITIAL>{DOT}          { count(); return DOT; }
321 <INITIAL>\\{CR}         {count(); } /* eat the escaped CR */
322 <INITIAL>{CR}           { count();/* return CR;*/ }
323
324
325 <INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); }
326 <INITIAL>{TICK} { count(); state=STRING_S; BEGIN(STRING2); }
327
328
329 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
330                                                 yytext[yyleng-1]=0; yyleng--;
331                                                 addstr(yytext, &tstr);
332                                                 yylval.strval=tstr; tstr=0;
333                                                 return STRING;
334                                         }
335 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
336                                                 yytext[yyleng-1]=0; yyleng--;
337                                                 addstr(yytext, &tstr);
338                                                 yylval.strval=tstr;
339                                                 tstr=0;
340                                                 return STRING;
341                                         }
342 <STRING2>.|{EAT_ABLE}|{CR}      { yymore(); }
343
344 <STRING1>\\n            { count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
345                                                 yyleng--; addstr(yytext, &tstr); }
346 <STRING1>\\r            { count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
347                                                 yyleng--; addstr(yytext, &tstr); }
348 <STRING1>\\a            { count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
349                                                 yyleng--; addstr(yytext, &tstr); }
350 <STRING1>\\t            { count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
351                                                 yyleng--; addstr(yytext, &tstr); }
352 <STRING1>\\\\           { count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
353                                                 yyleng--; addstr(yytext, &tstr); } 
354 <STRING1>.|{EAT_ABLE}|{CR}      { yymore(); }
355
356
357 <INITIAL,COMMENT>{COM_START}    { count(); comment_nest++; state=COMMENT_S;
358                                                                                 BEGIN(COMMENT); }
359 <COMMENT>{COM_END}                              { count(); comment_nest--;
360                                                                                 if (comment_nest==0){
361                                                                                         state=INITIAL_S;
362                                                                                         BEGIN(INITIAL);
363                                                                                 }
364                                                                 }
365 <COMMENT>.|{EAT_ABLE}|{CR}                              { count(); };
366
367 <INITIAL>{COM_LINE}.*{CR}       { count(); } 
368
369 <INITIAL>{ID}                   { count(); addstr(yytext, &tstr);
370                                                   yylval.strval=tstr; tstr=0; return ID; }
371
372
373 <<EOF>>                                                 {
374                                                                         switch(state){
375                                                                                 case STRING_S: 
376                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
377                                                                                                                 " unclosed string\n");
378                                                                                         if (tstr) {pkg_free(tstr);tstr=0;}
379                                                                                         break;
380                                                                                 case COMMENT_S:
381                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
382                                                                                                                 " %d comments open\n", comment_nest);
383                                                                                         break;
384                                                                                 case COMMENT_LN_S:
385                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF:"
386                                                                                                                 "comment line open\n");
387                                                                                         break;
388                                                                         }
389                                                                         return 0;
390                                                                 }
391                         
392 %%
393
394 static char* addstr(char * src, char ** dest)
395 {
396         char *tmp;
397         unsigned len1, len2;
398         
399         if (*dest==0){
400                 len1 = strlen(src);
401                 *dest = pkg_malloc(len1 + 1);
402                 if (*dest == 0) goto error;
403                 memcpy(*dest, src, len1 + 1);
404         }else{
405                 len1=strlen(*dest);
406                 len2=strlen(src);
407                 tmp=pkg_malloc(len1+len2+1);
408                 if (tmp==0) goto error;
409                 memcpy(tmp, *dest, len1);
410                 memcpy(tmp+len1, src, len2);
411                 tmp[len1+len2]=0;
412                 pkg_free(*dest);
413                 *dest=tmp;
414         }
415         return *dest;
416 error:
417         LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
418         return 0;
419 }
420
421
422
423 static void count()
424 {
425         int i;
426         
427         startcolumn=column;
428         for (i=0; i<yyleng;i++){
429                 if (yytext[i]=='\n'){
430                         line++;
431                         column=startcolumn=1;
432                 }else if (yytext[i]=='\t'){
433                         column++;
434                         /*column+=8 -(column%8);*/
435                 }else{
436                         column++;
437                 }
438         }
439 }
440
441