%{
/*
* Copyright (C) 2001-2008 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __FreeBSD__
# ifndef __FreeBSD_cc_version
# include <osreldate.h>
# else
# if __FreeBSD_cc_version < 430000
# include <osreldate.h>
# endif
# endif
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <strings.h>
#endif
#include <stdlib.h>
#include <stddef.h>
#include <netinet/in_systm.h>
#include <syslog.h>
#if __FreeBSD_version >= 300000
#endif
#include <netdb.h>
#include <resolv.h>
#include "ipf.h"
#include "ipnat_l.h"
#define YYDEBUG 1
extern int yydebug;
extern int yylineNum;
static int natfd = -1;
static void newnatrule __P((void));
static void setnatproto __P((int));
%}
%union {
char *str;
struct {
i6addr_t a;
int v;
} ipa;
struct {
int pc;
} pc;
struct {
i6addr_t a;
i6addr_t m;
int v;
} ipp;
};
%%
| assign
;
}
resetlexer();
}
;
resetlexer();
free($1);
free($3);
}
;
;
;
;
;
{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
yyerror("1.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
yyerror("2.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
{ if ($3 != 0 && $3 != $5.v && $5.v != 0)
yyerror("3.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
{ if ($3 != 0 && $3 != $5.v && $5.v != 0)
yyerror("4.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
;
{ if ($3.v != 0 && $3.v != $5.v && $5.v != 0)
yyerror("5.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
;
{ if ($6 != 0 && $3.v != 0 && $6 != $3.v)
yyerror("6.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
{ if ($5 != 0 && $3 != 0 && $5 != $3)
yyerror("7.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
{ if ($5 != 0 && $3.v != 0 && $5 != $3.v)
yyerror("8.address family mismatch");
nat->in_ifnames[0],
sizeof(nat->in_ifnames[0]));
}
;
yyerror("proxy port numbers not consistant");
}
setnatproto($6);
free($4);
}
{ int pnum;
if (pnum == -1)
yyerror("invalid port number");
setnatproto($6);
free($3);
free($4);
}
;
yyerror("protocol set twice");
setnatproto($1);
}
yyerror("protocol set twice");
}
yyerror("protocol set twice");
}
;
$$.m = $1.m;
$$.v = $1.v;
if ($$.v == 0)
yyexpectaddr = 0; }
{ if ($2.v != 0 && $4.v != 0 && $4.v != $2.v)
yyerror("9.address family "
"mismatch");
$$.v = $2.v;
$$.a = $2.a;
$$.m = $4.a;
yyexpectaddr = 0; }
;
dip:
sizeof($1.a));
if ($1.v == 0)
if ($1.v == 4) {
} else {
}
$$ = $1.v;
}
if ($1.v == 4 &&
($3 != 0 && $3 != 32)))
yyerror("Invalid mask for dip");
else if ($1.v == 6 &&
($3 != 0 && $3 != 128)))
yyerror("Invalid mask for dip");
else if ($1.v == 0 ) {
($3 == 32 || $3 == 0))
$1.v = 4;
else if ($3 == 128)
$1.v = 6;
}
sizeof($1.a));
$$ = $1.v;
}
{ if ($1.v != $4.v)
yyerror("10.address family "
"mismatch");
$$ = $1.v;
sizeof($1.a));
sizeof($4.a));
yyexpectaddr = 0; }
;
yyerror("invalid port number");
else
$$ = $1;
}
yyerror("invalid port number");
$$ = ntohs($$);
}
;
;
}
;
;
;
;
;
yyerror("11.address family "
"mismatch");
$$ = $2;
}
{ if ($2 != 0 && $5 != 0 && $2 != $5)
yyerror("12.address family "
"mismatch");
$$ = $2;
}
;
yyerror("13.address family "
"mismatch");
$$ = $2;
}
{ if ($3 != 0 && $5 != 0 && $3 != $5)
yyerror("14.address family "
"mismatch");
$$ = $3;
}
;
yyexpectaddr = 1; }
;
;
sizeof(nat->in_ifnames[0]));
free($1);
}
;
free($1);
}
;
}
}
yyerror("icmpidmap not followed by icmp");
}
free($2);
if ($3 < 0 || $3 > 65535)
yyerror("invalid ICMP Id number");
if ($5 < 0 || $5 > 65535)
yyerror("invalid ICMP Id number");
}
;
;
saddr { $$ = $1; }
$$ = $1;
}
;
sizeof($1.a));
sizeof($1.a));
} else {
sizeof($1.a));
sizeof($1.a));
}
$$ = $1.v;
}
;
daddr { $$ = $1; }
}
;
sizeof($1.a));
sizeof($1.a));
} else {
sizeof($1.a));
sizeof($1.a));
}
$$ = $1.v;
}
;
bzero(&$$.a, sizeof($$.a));
bzero(&$$.m, sizeof($$.a));
}
| hostname { $$.a = $1.a;
$$.v = $1.v;
if ($$.v == 4) {
} else {
$$.m.i6[0] = 0xffffffff;
}
yyexpectaddr = 0;
}
if ($1.v == 0) {
yyerror("invalid addr");
if ($3 == 0 || $3 == 32)
$1.v = 4;
else if ($3 == 128)
$1.v = 6;
else
yyerror("invalid mask");
}
$$.v = $1.v;
yyexpectaddr = 0;
}
yyerror("1.address family "
"mismatch");
}
$$.a = $1.a;
$$.m = $3.a;
$$.v = $1.v;
yyexpectaddr = 0;
}
$$.v = 4;
}
yyerror("2.address family "
"mismatch");
}
$$.a = $1.a;
$$.m = $3.a;
$$.v = $1.v;
yyexpectaddr = 0;
}
$$.v = 4;
}
;
;
;
;
}
;
;
;
"'sticky' for use with round-robin/IP splitting only\n");
} else
}
;
;
}
}
;
free($2);
}
}
}
;
| IPNY_TCP { $$ = IPPROTO_TCP; }
| IPNY_UDP { $$ = IPPROTO_UDP; }
;
YY_HEX { $$ = $1; }
;
$$.a = addr;
$$.v = 4;
} else
$$.a = addr;
$$.v = 6;
} else {
yyerror("Unknown hostname");
}
if ($$.v != 0)
free($1);
}
$$.v = 4;
else
if ($$.v != 0)
}
| ipv4 { $$ = $1;
}
| YY_IPV6 { $$.a = $1;
$$.v = 6;
}
$$.v = 6;
}
;
'=' { $$ = FR_EQUAL; }
| YY_CMP_GT { $$ = FR_GREATERT; }
| YY_CMP_GE { $$ = FR_GREATERTE; }
YY_RANGE_OUT { $$ = FR_OUTRANGE; }
| YY_RANGE_IN { $$ = FR_INRANGE; }
;
| YY_IPV6 { $$.a = $1;
$$.v = 6;
}
;
{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
yyerror("Invalid octet string for IP address");
return 0;
}
$$.v = 4;
}
;
%%
{ "age", IPNY_AGE },
{ "any", IPNY_ANY },
{ "auto", IPNY_AUTO },
{ "bimap", IPNY_BIMAP },
{ "frag", IPNY_FRAG },
{ "from", IPNY_FROM },
{ "icmpidmap", IPNY_ICMPIDMAP },
{ "mask", IPNY_MASK },
{ "map", IPNY_MAP },
{ "map-block", IPNY_MAPBLOCK },
{ "mssclamp", IPNY_MSSCLAMP },
{ "netmask", IPNY_MASK },
{ "port", IPNY_PORT },
{ "portmap", IPNY_PORTMAP },
{ "ports", IPNY_PORTS },
{ "proxy", IPNY_PROXY },
{ "range", IPNY_RANGE },
{ "rdr", IPNY_RDR },
{ "round-robin",IPNY_ROUNDROBIN },
{ "sequential", IPNY_SEQUENTIAL },
{ "sticky", IPNY_STICKY },
{ "tag", IPNY_TAG },
{ "tcp", IPNY_TCP },
{ "tcpudp", IPNY_TCPUDP },
{ "to", IPNY_TO },
{ "udp", IPNY_UDP },
{ "-", '-' },
{ "->", IPNY_TLATE },
{ "eq", YY_CMP_EQ },
{ "ne", YY_CMP_NE },
{ "lt", YY_CMP_LT },
{ "gt", YY_CMP_GT },
{ "le", YY_CMP_LE },
{ "ge", YY_CMP_GE },
{ NULL, 0 }
};
int fd;
char *filename;
{
char *s;
s = getenv("YYDEBUG");
if (s)
else
yydebug = 0;
if (!fp) {
return -1;
}
} else
;
return 0;
}
int fd;
{
char *s;
int i;
yylineNum = 1;
return 0;
if (i == EOF)
return 0;
return 0;
return 0;
s = getenv("YYDEBUG");
if (s)
else
yydebug = 0;
yyparse();
return 1;
}
static void newnatrule()
{
ipnat_t *n;
n = calloc(1, sizeof(*n));
if (n == NULL)
return;
else {
nat = n;
}
}
static void setnatproto(p)
int p;
{
switch (p)
{
case IPPROTO_TCP :
break;
case IPPROTO_UDP :
break;
case IPPROTO_ICMP :
}
break;
default :
}
break;
}
}
int fd;
void *ptr;
{
add = 0;
del = 0;
if ((opts & OPT_DONOTHING) != 0)
fd = -1;
if (opts & OPT_ZERORULEST) {
} else if (opts & OPT_INACTIVE) {
} else {
}
if ((opts & OPT_ZERORULEST) != 0) {
if ((opts & OPT_DONOTHING) == 0) {
perror("ioctl(SIOCZRLST)");
}
} else {
#ifdef USE_QUAD_T
/*
printf("hits %qd bytes %qd ",
(long long)fr->fr_hits,
(long long)fr->fr_bytes);
*/
#else
/*
printf("hits %ld bytes %ld ",
fr->fr_hits, fr->fr_bytes);
*/
#endif
}
} else if ((opts & OPT_REMOVE) != 0) {
if ((opts & OPT_DONOTHING) == 0) {
perror("ioctl(delete nat rule)");
}
}
} else {
if ((opts & OPT_DONOTHING) == 0) {
}
}
}
}