/*
* Copyright (C) 2002-2008 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <ctype.h>
#include "ipf.h"
#ifdef IPFILTER_SCAN
#endif
#include <syslog.h>
#ifdef TEST_LEXER
# define NO_YACC
union {
int num;
char *str;
} yylval;
#endif
#include "lexer.h"
#include "y.tab.h"
((c) >= 'A' && (c) <= 'F'))
extern int string_start;
extern int string_end;
extern char *string_val;
extern int pos;
extern int yydebug;
int yypos = 0;
int yyexpectaddr = 0;
int yybreakondot = 0;
int yyvarnext = 0;
int yytokentype = 0;
int yysavedepth = 0;
static char *yytexttostr __P((int, int));
static void yystrtotext __P((char *));
static char *yytexttochar __P((void));
int docont;
{
int c;
if (c == '\n')
yylineNum++;
return c;
}
return TOOLONG;
yypos++;
} else {
if (docont && (c == '\\')) {
if (c == '\n') {
yylineNum++;
}
}
}
if (c == '\n')
yylineNum++;
return c;
}
static void yyunputc(c)
int c;
{
if (c == '\n')
yylineNum--;
}
int last;
{
int c;
;
if (c != EOF)
yyunputc(c);
if (c == last)
return 0;
return -1;
}
static char *yytexttochar()
{
int i;
for (i = 0; i < yypos; i++)
yychars[i] = '\0';
return yychars;
}
char *str;
{
int len;
char *s;
}
{
char *str;
int i;
offset++;
max--;
}
}
return str;
}
int yylex()
{
char *name;
isbuilding = 0;
lnext = 0;
rval = 0;
}
c = yygetc(0);
if (yydebug > 1)
yytexttochar());
switch (c)
{
case '\n' :
lnext = 0;
nokey = 0;
case '\t' :
case '\r' :
case ' ' :
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
}
yypos = 0;
lnext = 0;
nokey = 0;
goto nextchar;
case '\\' :
if (lnext == 0) {
lnext = 1;
yylast--;
yypos--;
} else
yypos--;
if (yypos == 0)
nokey = 1;
goto nextchar;
}
break;
}
if (lnext == 1) {
lnext = 0;
if ((isbuilding == 0) && !ISALNUM(c)) {
return c;
}
goto nextchar;
}
switch (c)
{
case '#' :
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
yyswallow('\n');
rval = YY_COMMENT;
goto done;
case '$' :
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
n = yygetc(0);
if (n == '{') {
rval = -2;
goto done;
}
(void) yygetc(0);
} else {
if (!ISALPHA(n)) {
yyunputc(n);
break;
}
do {
n = yygetc(1);
yyunputc(n);
}
if (string_val != NULL) {
yypos = 0;
yylast = 0;
goto nextchar;
}
}
}
break;
case '\'':
case '"' :
if (isbuilding == 1) {
goto done;
}
do {
n = yygetc(1);
rval = -2;
goto done;
}
if (n == '\n') {
yyunputc(' ');
yypos++;
}
} while (n != c);
goto done;
/* NOTREACHED */
case EOF :
yylineNum = 1;
yypos = 0;
yylast = -1;
yyexpectaddr = 0;
yybreakondot = 0;
yyvarnext = 0;
yytokentype = 0;
return 0;
}
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
rval = c;
goto done;
} else if (c == '.') {
if (isbuilding == 0) {
rval = c;
goto done;
}
if (yybreakondot != 0) {
yyunputc(c);
goto done;
}
}
switch (c)
{
case '-' :
if (yyexpectaddr)
break;
if (isbuilding == 1)
break;
n = yygetc(0);
if (n == '>') {
isbuilding = 1;
goto done;
}
yyunputc(n);
rval = '-';
goto done;
case '!' :
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
n = yygetc(0);
if (n == '=') {
goto done;
}
yyunputc(n);
rval = '!';
goto done;
case '<' :
if (yyexpectaddr)
break;
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
n = yygetc(0);
if (n == '=') {
goto done;
}
if (n == '>') {
rval = YY_RANGE_OUT;
goto done;
}
yyunputc(n);
goto done;
case '>' :
if (yyexpectaddr)
break;
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
n = yygetc(0);
if (n == '=') {
goto done;
}
if (n == '<') {
rval = YY_RANGE_IN;
goto done;
}
yyunputc(n);
goto done;
}
/*
* Now for the reason this is here...IPv6 address parsing.
* The longest string we can expect is of this form:
* 0000:0000:0000:0000:0000:0000:000.000.000.000
* not:
* 0000:0000:0000:0000:0000:0000:0000:0000
*/
#ifdef USE_INET6
int start;
s = ipv6buf;
oc = c;
/*
* Perhaps we should implement stricter controls on what we
* swallow up here, but surely it would just be duplicating
* the code in inet_pton() anyway.
*/
do {
*s++ = c;
c = yygetc(1);
(s - ipv6buf < 46));
yyunputc(c);
*s = '\0';
yyexpectaddr = 0;
goto done;
}
c = oc;
}
#endif
if (c == ':') {
if (isbuilding == 1) {
yyunputc(c);
goto done;
}
rval = ':';
goto done;
}
if (isbuilding == 0 && c == '0') {
n = yygetc(0);
if (n == 'x') {
do {
n = yygetc(1);
} while (ishex(n));
yyunputc(n);
goto done;
}
yyunputc(n);
}
/*
* No negative numbers with leading - sign..
*/
if (isbuilding == 0 && ISDIGIT(c)) {
do {
n = yygetc(1);
} while (ISDIGIT(n));
yyunputc(n);
goto done;
}
isbuilding = 1;
goto nextchar;
done:
if (yydebug)
printf("isbuilding %d yyvarnext %d nokey %d\n",
if (isbuilding == 1) {
wordtab_t *w;
w = NULL;
isbuilding = 0;
yyresetdict();
}
} else
yyvarnext = 0;
if (w != NULL)
else
}
yyresetdict();
yytokentype = rval;
if (yydebug)
switch (rval)
{
case YY_NUMBER :
break;
case YY_HEX :
break;
case YY_STR :
break;
default :
break;
}
if (yylast > 0) {
yypos = 0;
}
return rval;
}
char *key;
{
wordtab_t *w;
return NULL;
return w;
return NULL;
}
int num;
{
wordtab_t *w;
return "<unknown>";
return w->w_word;
return "<unknown>";
}
{
return save;
}
char *msg;
{
int freetxt = 0;
if (yytokentype < 256) {
letter[0] = yytokentype;
yytokentype == YY_NUMBER) {
" bailing out\n");
exit(1);
}
freetxt = 1;
} else
} else {
" bailing out\n");
exit(1);
}
}
if (freetxt == 1)
exit(1);
}
{
return;
}
if (yydebug)
}
void yyresetdict()
{
if (yydebug)
if (yysavedepth > 0) {
if (yydebug)
}
}
#ifdef TEST_LEXER
int argc;
char *argv[];
{
int n;
while ((n = yylex()) != 0)
printf("%d.n = %d [%s] %d %d\n",
}
#endif