/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#if !defined(lint)
#endif
#include "ipf.h"
typedef struct {
int c;
int e;
int n;
int p;
int s;
} mc_t;
static int count = 0;
#define FRC_IFN 0
/*
* This is called once per filter rule being loaded to emit data structures
* required.
*/
{
char *and;
int i;
return;
return;
return;
return;
if (count == 0) {
"#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n");
"#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n");
}
and = "";
i = sizeof(*fr);
if (i & -(1 - sizeof(*ulp)))
i += sizeof(u_long);
and = ", ";
}
count++;
}
{
frgroup_t *g;
char *and;
int i;
if (f == NULL) {
exit(1);
}
exit(1);
}
}
break;
if (g == NULL) {
if (g == NULL) {
exit(1);
}
groups = g;
g->fg_head = f;
g->fg_ref = 0;
}
*fpp = f;
static u_long ipf%s_rule_data_%s_%u[] = {\n",
and = "";
for (i /= sizeof(u_long); i > 0; i--) {
and = ", ";
}
}
g->fg_ref++;
if (f->fr_grhead != 0) {
FR_GROUPLEN) == 0) &&
break;
if (g == NULL) {
if (g == NULL) {
exit(1);
}
groups = g;
g->fg_head = f;
g->fg_ref = 0;
}
}
}
{
}
}
int in;
{
}
char *var;
int m, max, v;
{
if (m == max)
else
}
/*
* Parameters: var - IP# being compared
* fl - 0 for positive match, 1 for negative match
* m - netmask
* v - required address
*/
char *var;
int fl, m, v;
{
if (m == 0xffffffff)
else
}
void *v;
{
frgroup_t *g;
frentry_t *f;
continue;
f = f->fr_next)
incnt++;
}
continue;
f = f->fr_next)
outcnt++;
}
}
f = f->fr_next)
incnt++;
if (incnt > 0)
emitheader(g, incnt, 0);
}
f = f->fr_next)
outcnt++;
if (outcnt > 0)
emitheader(g, 0, outcnt);
}
}
emittail();
}
}
{
frgroup_t *g;
return;
}
if (incount) {
extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\
extern frentry_t *ipf_rules_in_%s[%d];\n",
FR_GROUPLEN) == 0) &&
break;
if (g == grp) {
extern int ipfrule_add_in_%s __P((void));\n\
}
}
if (outcount) {
extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
extern frentry_t *ipf_rules_out_%s[%d];\n",
FR_GROUPLEN) == 0) &&
break;
if (g == grp) {
extern int ipfrule_add_out_%s __P((void));\n\
extern int ipfrule_remove_out_%s __P((void));\n",
}
}
}
static void emittail()
{
frgroup_t *g;
int ipfrule_add()\n\
{\n\
int err;\n\
\n");
err = ipfrule_add_%s_%s();\n\
if (err != 0)\n\
return err;\n",
return 0;\n");
\n");
int ipfrule_remove()\n\
{\n\
int err;\n\
\n");
err = ipfrule_remove_%s_%s();\n\
if (err != 0)\n\
return err;\n",
return 0;\n");
}
void *v;
char *group;
{
static int openfunc = 0;
static int sin = 0;
frentry_t *f;
frgroup_t *g;
int i, in, j;
mc_t *m = v;
return;
}
if (openfunc == 1) {
openfunc = 0;
if (n != NULL) {
free(n);
n = NULL;
}
}
sin = 0;
header[0] = 0;
header[1] = 0;
if (n != NULL) {
free(n);
n = NULL;
}
}
if (openfunc == 1) {
openfunc = 0;
}
}
if (dir == -1)
return;
continue;
continue;
continue;
break;
}
/*
* Output the array of pointers to rules for this group.
*/
continue;
if ((i & 1) == 0) {
}
"(frentry_t *)&in_rule_%s_%d",
f->fr_group, i);
if (i + 1 < incount)
i++;
}
}
continue;
if ((i & 1) == 0) {
}
"(frentry_t *)&out_rule_%s_%d",
f->fr_group, i);
if (i + 1 < outcount)
i++;
}
}
if (num < 0)
return;
in = 0;
/*
* If the function header has not been printed then print it now.
*/
openfunc = 1;
/*
* Print out any variables that need to be declared.
*/
psrc = 1;
pdst = 1;
}
if (psrc == 1)
"fin->fin_fi.fi_saddr");
if (pdst == 1)
"fin->fin_fi.fi_daddr");
}
for (i = 0; i < FRC_MAX; i++) {
switch(m[i].c)
{
case FRC_IFN :
m[i].s = 1;
break;
case FRC_V :
m[i].s = 1;
break;
case FRC_FL :
m[i].s = 1;
break;
case FRC_P :
m[i].s = 1;
break;
case FRC_TTL :
m[i].s = 1;
break;
case FRC_TOS :
m[i].s = 1;
break;
case FRC_TCP :
break;
m[i].s = 1;
break;
case FRC_SP :
break;
m[i].s = 1;
m[i].s = 1;
m[i].s = 1;
break;
case FRC_DP :
break;
m[i].s = 1;
m[i].s = 1;
m[i].s = 1;
break;
case FRC_SRC :
break;
;
m[i].s = 1;
break;
case FRC_DST :
break;
;
m[i].s = 1;
break;
case FRC_OPT :
break;
if (fr->fr_optmask != 0)
m[i].s = 1;
break;
case FRC_SEC :
break;
if (fr->fr_secmask != 0)
m[i].s = 1;
break;
case FRC_ATH :
break;
if (fr->fr_authmask != 0)
m[i].s = 1;
break;
case FRC_ICT :
break;
m[i].s = 1;
break;
case FRC_ICC :
break;
m[i].s = 1;
break;
}
}
sin = 0;
}
if (n) {
/*
* Calculate the indentation interval upto the last common
* common comparison being made.
*/
if (n[i].c != m[i].c)
break;
if (n[i].s != m[i].s)
break;
if (n[i].s) {
if (n[i].n && (n[i].n > n[i].e)) {
m[i].p++;
in += m[i].p;
break;
}
if (n[i].e > 0) {
in++;
} else
break;
}
}
}
}
} else {
in = 1;
i = 0;
}
/*
* print out C code that implements a filter rule.
*/
for (; i < FRC_MAX; i++) {
switch(m[i].c)
{
case FRC_IFN :
if (m[i].s) {
in++;
}
break;
case FRC_V :
if (m[i].s) {
in++;
}
break;
case FRC_FL :
if (m[i].s) {
in++;
}
break;
case FRC_P :
if (m[i].s) {
in++;
}
break;
case FRC_TTL :
if (m[i].s) {
in++;
}
break;
case FRC_TOS :
if (m[i].s) {
in++;
}
break;
case FRC_TCP :
if (m[i].s) {
in++;
}
break;
case FRC_SP :
if (!m[i].s)
break;
in++;
in++;
in++;
}
break;
case FRC_DP :
if (!m[i].s)
break;
in++;
in++;
in++;
}
break;
case FRC_SRC :
if (!m[i].s)
break;
;
in++;
}
break;
case FRC_DST :
if (!m[i].s)
break;
;
in++;
}
break;
case FRC_OPT :
if (m[i].s) {
fr->fr_optbits);
in++;
}
break;
case FRC_SEC :
if (m[i].s) {
fr->fr_secbits);
in++;
}
break;
case FRC_ATH :
if (m[i].s) {
fr->fr_authbits);
in++;
}
break;
case FRC_ICT :
if (m[i].s) {
in++;
}
break;
case FRC_ICC :
if (m[i].s) {
in++;
}
break;
}
}
} else {
}
if (n == NULL) {
if (n == NULL) {
exit(1);
}
}
}
int dir;
{
frgroup_t *g;
if (m == NULL) {
if (m == NULL) {
exit(1);
}
}
}
}
/*
* Now print out code to implement all of the rules.
*/
int dir;
mc_t *m;
char *group;
{
int i, n, rn;
count++;
count++;
}
if (dir == 0)
else if (dir == 1)
/*
* Before printing each rule, check to see how many of its fields are
* matched by subsequent rules.
*/
continue;
continue;
n = 0xfffffff;
for (i = 0; i < FRC_MAX; i++)
m[i].e = 0;
for (i = 0; i < FRC_MAX; i++) {
m[i].c = i;
m[i].e = 0;
m[i].n = 0;
m[i].s = 0;
}
continue;
continue;
if ((n & 0x0001) &&
m[FRC_IFN].e++;
m[FRC_IFN].n++;
} else
n &= ~0x0001;
m[FRC_V].e++;
m[FRC_V].n++;
} else
n &= ~0x0002;
if ((n & 0x0004) &&
m[FRC_FL].e++;
m[FRC_FL].n++;
} else
n &= ~0x0004;
if ((n & 0x0008) &&
m[FRC_P].e++;
m[FRC_P].n++;
} else
n &= ~0x0008;
if ((n & 0x0010) &&
m[FRC_TTL].e++;
m[FRC_TTL].n++;
} else
n &= ~0x0010;
if ((n & 0x0020) &&
m[FRC_TOS].e++;
m[FRC_TOS].n++;
} else
n &= ~0x0020;
if ((n & 0x0040) &&
m[FRC_TCP].e++;
m[FRC_TCP].n++;
} else
n &= ~0x0040;
if ((n & 0x0080) &&
m[FRC_SP].e++;
m[FRC_SP].n++;
} else
n &= ~0x0080;
if ((n & 0x0100) &&
m[FRC_DP].e++;
m[FRC_DP].n++;
} else
n &= ~0x0100;
if ((n & 0x0200) &&
m[FRC_SRC].e++;
m[FRC_SRC].n++;
} else if ((n & 0x0200) &&
m[FRC_SRC].e++;
else
n &= ~0x0200;
m[FRC_SRC].n++;
n |= 0x0200;
}
} else {
n &= ~0x0200;
}
if ((n & 0x0400) &&
m[FRC_DST].e++;
m[FRC_DST].n++;
} else if ((n & 0x0400) &&
m[FRC_DST].e++;
else
n &= ~0x0400;
m[FRC_DST].n++;
n |= 0x0400;
}
} else {
n &= ~0x0400;
}
if ((n & 0x0800) &&
m[FRC_OPT].e++;
m[FRC_OPT].n++;
} else
n &= ~0x0800;
if ((n & 0x1000) &&
m[FRC_SEC].e++;
m[FRC_SEC].n++;
} else
n &= ~0x1000;
if ((n & 0x10000) &&
m[FRC_ATH].e++;
m[FRC_ATH].n++;
} else
n &= ~0x10000;
if ((n & 0x20000) &&
m[FRC_ICT].e++;
m[FRC_ICT].n++;
} else
n &= ~0x20000;
if ((n & 0x40000) &&
m[FRC_ICC].e++;
m[FRC_ICC].n++;
} else
n &= ~0x40000;
}
/*msort(m);*/
if (dir == 0)
else if (dir == 1)
}
}
int in;
int out;
{
char *group;
int dogrp, i;
char *instr;
dogrp = 0;
"printhooks called with both in and out set\n");
exit(1);
}
if (in) {
instr = "in";
} else if (out) {
instr = "out";
} else {
instr = "???";
}
\n\
{\n\
int i, j, err = 0, max;\n\
frentry_t *fp;\n");
if (dogrp)
frgroup_t *fg;\n");
ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n",
}
max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\
for (i = 0; i < max; i++) {\n\
fp = ipf_rules_%s_%s[i];\n\
for (j = i + 1; j < max; j++)\n\
if (strncmp(fp->fr_group,\n\
ipf_rules_%s_%s[j]->fr_group,\n\
FR_GROUPLEN) == 0) {\n\
fp->fr_next = ipf_rules_%s_%s[j];\n\
break;\n\
if (dogrp)
\n\
if (fp->fr_grhead != 0) {\n\
fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\
IPL_LOGIPF, 0);\n\
if (fg != NULL)\n\
fp->fr_grp = &fg->fg_start;\n\
}\n");
}\n\
\n\
bzero((char *)fp, sizeof(*fp));\n\
fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\
fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n",
fp->fr_v = 4;\n\
fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\
err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n",
{\n\
int err = 0, i;\n\
frentry_t *fp;\n\
\n\
/*\n\
* Try to remove the %sbound rule.\n", instr);
*/\n\
err = EBUSY;\n\
} else {\n");
i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\
for (; i >= 0; i--) {\n\
fp = ipf_rules_%s_%s[i];\n\
if (fp->fr_ref > 1) {\n\
err = EBUSY;\n\
break;\n\
}\n\
}\n\
}\n\
if (err == 0)\n\
err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\
(caddr_t)&ipfrule_%s_%s, fr_active, 0);\n",
if (err)\n\
return err;\n\
\n\n");
}