%{
/*
 *  ippl.l - functions parsing the configuration file
 *
 *  Copyright (C) 1998 Etienne Bernard
 *  *Small* modifications for UDP by Hugo Haas, 1999
 *  Added a "detailed" and a "noresolve" rule. Hugo Haas 1999
 *  Added a "log-in" rule. Hugo Haas 1999
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <string.h>

#include "filter.h"
#include "y.tab.h"

void yyerror(char *);

int line_number;

%}

white     [ \t]+

octdigit  [0-7]
hexdigit  [0-9A-Fa-f]
decdigit  [0-9]

octchar   {octdigit}+
hexchar   {hexdigit}+
decchar   {decdigit}+

char      {octchar}|{hexchar}|{decchar}
integer   {decdigit}+

ip        {char}"."{char}"."{char}"."{char}

letter    [A-Za-z]
digit     [0-9]
letdig    {letter}|{digit}
hyp       "-"|"_"
letdighyp {letdig}|{hyp}
label     {letdig}+({hyp}{letdig}+)*

hostmask  ({label}|"*")("."({label}|"*"))*"."?
ident     {letter}("-"?{letdig}+)*

letfile   {letdighyp}|"\\"|"."
file      ("/"{letfile}+)("/"{letfile}+)+

%%

{white}               { /* Ignore */ }
"#".*$                { /* Ignore */ }
"\n"                  { line_number++; return EOL; }

[lL][oO][gG][fF][oO][rR][mM][aA][tT] return LOGFORMAT;
[dD][eE][tT][aA][iI][lL][eE][dD] return DETAILED;
[sS][hH][oO][rR][tT] return SHORT;
[nN][oO][rR][mM][aA][lL] return NORMAL;

[lL][oO][gG][cC][lL][oO][sS][iI][nN][gG] return LOGCLOSING;
[nN][oO][lL][oO][gG][cC][lL][oO][sS][iI][nN][gG] return NOLOGCLOSING;

[nN][oO][rR][eE][sS][oO][lL][vV][eE] return NORESOLVE;
[rR][eE][sS][oO][lL][vV][eE] return RESOLVE;

[nN][oO][iI][dD][eE][nN][tT] return NOIDENT;
[iI][dD][eE][nN][tT] return IDENT;

[oO][pP][tT][iI][oO][nN]     return OPTION;
[oO][pP][tT][iI][oO][nN][sS] return OPTION;

[eE][xX][pP][iI][rR][eE]   return EXPIRE;
[lL][oO][gG]-[iI][nN]      return LOG_IN;
[rR][uU][nN]               return RUN;
[rR][uU][nN][aA][sS]       return RUNAS;

[lL][oO][gG]               return LOG;
[iI][gG][nN][oO][rR][eE]   return IGNORE;

[fF][rR][oO][mM]           return FROM;
[tT][oO]		   return TO;

[tT][yY][pP][eE]           return TYPE;
[pP][oO][rR][tT]           return PORT;
[sS][rR][cC][pP][oO][rR][tT] return SRCPORT;

[iI][cC][mM][pP]      return ICMP;
[tT][cC][pP]          return TCP;
[uU][dD][pP]          return UDP;
[aA][lL][lL]          return ALL;

{integer}             {
                        yylval.longval = atol(yytext);
                        return NUMBER;
                      }

"--"                  return RANGE;
"/"                   return SLASH;
","                   return COMMA;

"echo_reply"          { yylval.longval = 0; return NUMBER; }
"dest_unreach"        { yylval.longval = 3; return NUMBER; }
"src_quench"          { yylval.longval = 4; return NUMBER; }
"redirect"            { yylval.longval = 5; return NUMBER; }
"echo_req"            { yylval.longval = 8; return NUMBER; }
"router_advert"       { yylval.longval = 9; return NUMBER; }
"router_solicit"      { yylval.longval = 10; return NUMBER; }
"time_exceeded"       { yylval.longval = 11; return NUMBER; }
"param_problem"       { yylval.longval = 12; return NUMBER; }
"ts_req"              { yylval.longval = 13; return NUMBER; }
"ts_reply"            { yylval.longval = 14; return NUMBER; }
"info_req"            { yylval.longval = 15; return NUMBER; }
"info_reply"          { yylval.longval = 16; return NUMBER; }
"addr_mask_req"       { yylval.longval = 17; return NUMBER; }
"addr_mask_reply"     { yylval.longval = 18; return NUMBER; }

{ip}                  {
                        yylval.stringval = strdup(yytext);
                        return IP;
                      }

{ident}               {
                        yylval.stringval = strdup(yytext);
                        return IDENTIFIER;
                      }

{hostmask}            {
                        if (yytext[strlen(yytext)-1] == '.')
                          yytext[strlen(yytext)-1] = '\0';
                        yylval.stringval = strdup(yytext);
                        return HOSTMASK;
                      }

{file}                {
                        yylval.stringval = strdup(yytext);
                        return FILENAME;
                      }

.                     { yyerror("unexpected token."); }

%%

int yywrap() {
  return 1;
}
