1145519Sdarrenr/* $FreeBSD: stable/11/contrib/ipfilter/tools/ipfcomp.c 369245 2021-02-09 13:47:46Z git2svn $ */ 2145510Sdarrenr 3145510Sdarrenr/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr */ 8145510Sdarrenr#if !defined(lint) 9145510Sdarrenrstatic const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 10255332Scystatic const char rcsid[] = "@(#)$Id$"; 11145510Sdarrenr#endif 12145510Sdarrenr 13145510Sdarrenr#include "ipf.h" 14145510Sdarrenr 15145510Sdarrenr 16145510Sdarrenrtypedef struct { 17145510Sdarrenr int c; 18145510Sdarrenr int e; 19145510Sdarrenr int n; 20145510Sdarrenr int p; 21145510Sdarrenr int s; 22145510Sdarrenr} mc_t; 23145510Sdarrenr 24145510Sdarrenr 25145510Sdarrenrstatic char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" }; 26145510Sdarrenrstatic int count = 0; 27145510Sdarrenr 28369245Sgit2svnint intcmp(const void *, const void *); 29369245Sgit2svnstatic void indent(FILE *, int); 30369245Sgit2svnstatic void printeq(FILE *, char *, int, int, int); 31369245Sgit2svnstatic void printipeq(FILE *, char *, int, int, int); 32369245Sgit2svnstatic void addrule(FILE *, frentry_t *); 33369245Sgit2svnstatic void printhooks(FILE *, int, int, frgroup_t *); 34369245Sgit2svnstatic void emitheader(frgroup_t *, u_int, u_int); 35369245Sgit2svnstatic void emitGroup(int, int, void *, frentry_t *, char *, 36369245Sgit2svn u_int, u_int); 37369245Sgit2svnstatic void emittail(void); 38369245Sgit2svnstatic void printCgroup(int, frentry_t *, mc_t *, char *); 39145510Sdarrenr 40145510Sdarrenr#define FRC_IFN 0 41145510Sdarrenr#define FRC_V 1 42145510Sdarrenr#define FRC_P 2 43145510Sdarrenr#define FRC_FL 3 44145510Sdarrenr#define FRC_TOS 4 45145510Sdarrenr#define FRC_TTL 5 46145510Sdarrenr#define FRC_SRC 6 47145510Sdarrenr#define FRC_DST 7 48145510Sdarrenr#define FRC_TCP 8 49145510Sdarrenr#define FRC_SP 9 50145510Sdarrenr#define FRC_DP 10 51145510Sdarrenr#define FRC_OPT 11 52145510Sdarrenr#define FRC_SEC 12 53145510Sdarrenr#define FRC_ATH 13 54145510Sdarrenr#define FRC_ICT 14 55145510Sdarrenr#define FRC_ICC 15 56145510Sdarrenr#define FRC_MAX 16 57145510Sdarrenr 58145510Sdarrenr 59145510Sdarrenrstatic FILE *cfile = NULL; 60145510Sdarrenr 61145510Sdarrenr/* 62145510Sdarrenr * This is called once per filter rule being loaded to emit data structures 63145510Sdarrenr * required. 64145510Sdarrenr */ 65145510Sdarrenrvoid printc(fr) 66255332Scy frentry_t *fr; 67145510Sdarrenr{ 68145510Sdarrenr fripf_t *ipf; 69145510Sdarrenr u_long *ulp; 70145510Sdarrenr char *and; 71145510Sdarrenr FILE *fp; 72145510Sdarrenr int i; 73145510Sdarrenr 74255332Scy if (fr->fr_family == 6) 75145510Sdarrenr return; 76145510Sdarrenr if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) 77145510Sdarrenr return; 78145510Sdarrenr if ((fr->fr_type == FR_T_IPF) && 79145510Sdarrenr ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL))) 80145510Sdarrenr return; 81145510Sdarrenr ipf = fr->fr_ipf; 82145510Sdarrenr 83145510Sdarrenr if (cfile == NULL) 84145510Sdarrenr cfile = fopen("ip_rules.c", "w"); 85145510Sdarrenr if (cfile == NULL) 86145510Sdarrenr return; 87145510Sdarrenr fp = cfile; 88145510Sdarrenr if (count == 0) { 89145510Sdarrenr fprintf(fp, "/*\n"); 90255332Scy fprintf(fp, "* Copyright (C) 2012 by Darren Reed.\n"); 91145510Sdarrenr fprintf(fp, "*\n"); 92145510Sdarrenr fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); 93145510Sdarrenr fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); 94145510Sdarrenr fprintf(fp, "* to the original author and the contributors.\n"); 95145510Sdarrenr fprintf(fp, "*/\n\n"); 96145510Sdarrenr 97170268Sdarrenr fprintf(fp, "#include <sys/param.h>\n"); 98145510Sdarrenr fprintf(fp, "#include <sys/types.h>\n"); 99145510Sdarrenr fprintf(fp, "#include <sys/time.h>\n"); 100145510Sdarrenr fprintf(fp, "#include <sys/socket.h>\n"); 101170268Sdarrenr fprintf(fp, "#if (__FreeBSD_version >= 40000)\n"); 102170268Sdarrenr fprintf(fp, "# if defined(_KERNEL)\n"); 103170268Sdarrenr fprintf(fp, "# include <sys/libkern.h>\n"); 104170268Sdarrenr fprintf(fp, "# else\n"); 105170268Sdarrenr fprintf(fp, "# include <sys/unistd.h>\n"); 106170268Sdarrenr fprintf(fp, "# endif\n"); 107145510Sdarrenr fprintf(fp, "#endif\n"); 108170268Sdarrenr fprintf(fp, "#if (__NetBSD_Version__ >= 399000000)\n"); 109170268Sdarrenr fprintf(fp, "#else\n"); 110170268Sdarrenr fprintf(fp, "# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n"); 111170268Sdarrenr fprintf(fp, "# include <sys/systm.h>\n"); 112170268Sdarrenr fprintf(fp, "# endif\n"); 113170268Sdarrenr fprintf(fp, "#endif\n"); 114145510Sdarrenr fprintf(fp, "#include <sys/errno.h>\n"); 115145510Sdarrenr fprintf(fp, "#include <sys/param.h>\n"); 116145510Sdarrenr fprintf(fp, 117145510Sdarrenr"#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n"); 118145510Sdarrenr fprintf(fp, "# include <sys/mbuf.h>\n"); 119145510Sdarrenr fprintf(fp, "#endif\n"); 120145510Sdarrenr fprintf(fp, 121145510Sdarrenr"#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n"); 122145510Sdarrenr fprintf(fp, "# include <sys/sockio.h>\n"); 123145510Sdarrenr fprintf(fp, "#else\n"); 124145510Sdarrenr fprintf(fp, "# include <sys/ioctl.h>\n"); 125145510Sdarrenr fprintf(fp, "#endif /* FreeBSD */\n"); 126145510Sdarrenr fprintf(fp, "#include <net/if.h>\n"); 127145510Sdarrenr fprintf(fp, "#include <netinet/in.h>\n"); 128145510Sdarrenr fprintf(fp, "#include <netinet/in_systm.h>\n"); 129145510Sdarrenr fprintf(fp, "#include <netinet/ip.h>\n"); 130145510Sdarrenr fprintf(fp, "#include <netinet/tcp.h>\n"); 131145510Sdarrenr fprintf(fp, "#include \"netinet/ip_compat.h\"\n"); 132145510Sdarrenr fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n"); 133145510Sdarrenr fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n"); 134145510Sdarrenr fprintf(fp, "#ifndef _KERNEL\n"); 135145510Sdarrenr fprintf(fp, "# include <string.h>\n"); 136145510Sdarrenr fprintf(fp, "#endif /* _KERNEL */\n"); 137145510Sdarrenr fprintf(fp, "\n"); 138145510Sdarrenr fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); 139255332Scy fprintf(fp, "\n"); 140255332Scy fprintf(fp, "extern ipf_main_softc_t ipfmain;\n"); 141255332Scy fprintf(fp, "\n"); 142145510Sdarrenr } 143145510Sdarrenr 144145510Sdarrenr addrule(fp, fr); 145145510Sdarrenr fr->fr_type |= FR_T_BUILTIN; 146145510Sdarrenr and = ""; 147145510Sdarrenr fr->fr_ref = 1; 148145510Sdarrenr i = sizeof(*fr); 149145510Sdarrenr if (i & -(1 - sizeof(*ulp))) 150145510Sdarrenr i += sizeof(u_long); 151145510Sdarrenr for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) { 152145510Sdarrenr fprintf(fp, "%s%#lx", and, *ulp++); 153145510Sdarrenr and = ", "; 154145510Sdarrenr } 155145510Sdarrenr fprintf(fp, "\n};\n"); 156145510Sdarrenr fr->fr_type &= ~FR_T_BUILTIN; 157145510Sdarrenr 158145510Sdarrenr count++; 159145510Sdarrenr 160145510Sdarrenr fflush(fp); 161145510Sdarrenr} 162145510Sdarrenr 163145510Sdarrenr 164145510Sdarrenrstatic frgroup_t *groups = NULL; 165145510Sdarrenr 166145510Sdarrenr 167145510Sdarrenrstatic void addrule(fp, fr) 168255332Scy FILE *fp; 169255332Scy frentry_t *fr; 170145510Sdarrenr{ 171145510Sdarrenr frentry_t *f, **fpp; 172145510Sdarrenr frgroup_t *g; 173145510Sdarrenr u_long *ulp; 174255332Scy char *ghead; 175255332Scy char *gname; 176145510Sdarrenr char *and; 177145510Sdarrenr int i; 178145510Sdarrenr 179145510Sdarrenr f = (frentry_t *)malloc(sizeof(*f)); 180145510Sdarrenr bcopy((char *)fr, (char *)f, sizeof(*fr)); 181145510Sdarrenr if (fr->fr_ipf) { 182145510Sdarrenr f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf)); 183145510Sdarrenr bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf, 184145510Sdarrenr sizeof(*fr->fr_ipf)); 185145510Sdarrenr } 186145510Sdarrenr 187145510Sdarrenr f->fr_next = NULL; 188255332Scy gname = FR_NAME(fr, fr_group); 189255332Scy 190145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) 191255332Scy if ((strncmp(g->fg_name, gname, FR_GROUPLEN) == 0) && 192145510Sdarrenr (g->fg_flags == (f->fr_flags & FR_INOUT))) 193145510Sdarrenr break; 194145510Sdarrenr 195145510Sdarrenr if (g == NULL) { 196145510Sdarrenr g = (frgroup_t *)calloc(1, sizeof(*g)); 197145510Sdarrenr g->fg_next = groups; 198145510Sdarrenr groups = g; 199145510Sdarrenr g->fg_head = f; 200255332Scy strncpy(g->fg_name, gname, FR_GROUPLEN); 201145510Sdarrenr g->fg_ref = 0; 202145510Sdarrenr g->fg_flags = f->fr_flags & FR_INOUT; 203145510Sdarrenr } 204145510Sdarrenr 205145510Sdarrenr for (fpp = &g->fg_start; *fpp != NULL; ) 206145510Sdarrenr fpp = &((*fpp)->fr_next); 207145510Sdarrenr *fpp = f; 208145510Sdarrenr 209145510Sdarrenr if (fr->fr_dsize > 0) { 210145510Sdarrenr fprintf(fp, "\ 211145510Sdarrenrstatic u_long ipf%s_rule_data_%s_%u[] = {\n", 212145510Sdarrenr f->fr_flags & FR_INQUE ? "in" : "out", 213145510Sdarrenr g->fg_name, g->fg_ref); 214145510Sdarrenr and = ""; 215145510Sdarrenr i = fr->fr_dsize; 216145510Sdarrenr ulp = fr->fr_data; 217145510Sdarrenr for (i /= sizeof(u_long); i > 0; i--) { 218145510Sdarrenr fprintf(fp, "%s%#lx", and, *ulp++); 219145510Sdarrenr and = ", "; 220145510Sdarrenr } 221145510Sdarrenr fprintf(fp, "\n};\n"); 222145510Sdarrenr } 223145510Sdarrenr 224145510Sdarrenr fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n", 225145510Sdarrenr f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); 226145510Sdarrenr 227145510Sdarrenr g->fg_ref++; 228145510Sdarrenr 229255332Scy if (f->fr_grhead != -1) { 230255332Scy ghead = FR_NAME(f, fr_grhead); 231145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) 232255332Scy if ((strncmp(g->fg_name, ghead, FR_GROUPLEN) == 0) && 233145510Sdarrenr g->fg_flags == (f->fr_flags & FR_INOUT)) 234145510Sdarrenr break; 235145510Sdarrenr if (g == NULL) { 236145510Sdarrenr g = (frgroup_t *)calloc(1, sizeof(*g)); 237145510Sdarrenr g->fg_next = groups; 238145510Sdarrenr groups = g; 239145510Sdarrenr g->fg_head = f; 240255332Scy strncpy(g->fg_name, ghead, FR_GROUPLEN); 241145510Sdarrenr g->fg_ref = 0; 242145510Sdarrenr g->fg_flags = f->fr_flags & FR_INOUT; 243145510Sdarrenr } 244145510Sdarrenr } 245145510Sdarrenr} 246145510Sdarrenr 247145510Sdarrenr 248145510Sdarrenrint intcmp(c1, c2) 249255332Scy const void *c1, *c2; 250145510Sdarrenr{ 251145510Sdarrenr const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; 252145510Sdarrenr 253145510Sdarrenr if (i1->n == i2->n) { 254145510Sdarrenr return i1->c - i2->c; 255145510Sdarrenr } 256145510Sdarrenr return i2->n - i1->n; 257145510Sdarrenr} 258145510Sdarrenr 259145510Sdarrenr 260145510Sdarrenrstatic void indent(fp, in) 261255332Scy FILE *fp; 262255332Scy int in; 263145510Sdarrenr{ 264145510Sdarrenr for (; in; in--) 265145510Sdarrenr fputc('\t', fp); 266145510Sdarrenr} 267145510Sdarrenr 268145510Sdarrenrstatic void printeq(fp, var, m, max, v) 269255332Scy FILE *fp; 270255332Scy char *var; 271255332Scy int m, max, v; 272145510Sdarrenr{ 273145510Sdarrenr if (m == max) 274145510Sdarrenr fprintf(fp, "%s == %#x) {\n", var, v); 275145510Sdarrenr else 276145510Sdarrenr fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v); 277145510Sdarrenr} 278145510Sdarrenr 279145510Sdarrenr/* 280145510Sdarrenr * Parameters: var - IP# being compared 281145510Sdarrenr * fl - 0 for positive match, 1 for negative match 282145510Sdarrenr * m - netmask 283145510Sdarrenr * v - required address 284145510Sdarrenr */ 285145510Sdarrenrstatic void printipeq(fp, var, fl, m, v) 286255332Scy FILE *fp; 287255332Scy char *var; 288255332Scy int fl, m, v; 289145510Sdarrenr{ 290145510Sdarrenr if (m == 0xffffffff) 291145510Sdarrenr fprintf(fp, "%s ", var); 292145510Sdarrenr else 293145510Sdarrenr fprintf(fp, "(%s & %#x) ", var, m); 294145510Sdarrenr fprintf(fp, "%c", fl ? '!' : '='); 295145510Sdarrenr fprintf(fp, "= %#x) {\n", v); 296145510Sdarrenr} 297145510Sdarrenr 298145510Sdarrenr 299145510Sdarrenrvoid emit(num, dir, v, fr) 300255332Scy int num, dir; 301255332Scy void *v; 302255332Scy frentry_t *fr; 303145510Sdarrenr{ 304145510Sdarrenr u_int incnt, outcnt; 305145510Sdarrenr frgroup_t *g; 306145510Sdarrenr frentry_t *f; 307145510Sdarrenr 308145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) { 309145510Sdarrenr if (dir == 0 || dir == -1) { 310145510Sdarrenr if ((g->fg_flags & FR_INQUE) == 0) 311145510Sdarrenr continue; 312145510Sdarrenr for (incnt = 0, f = g->fg_start; f != NULL; 313145510Sdarrenr f = f->fr_next) 314145510Sdarrenr incnt++; 315145510Sdarrenr emitGroup(num, dir, v, fr, g->fg_name, incnt, 0); 316145510Sdarrenr } 317145510Sdarrenr if (dir == 1 || dir == -1) { 318145510Sdarrenr if ((g->fg_flags & FR_OUTQUE) == 0) 319145510Sdarrenr continue; 320145510Sdarrenr for (outcnt = 0, f = g->fg_start; f != NULL; 321145510Sdarrenr f = f->fr_next) 322145510Sdarrenr outcnt++; 323145510Sdarrenr emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt); 324145510Sdarrenr } 325145510Sdarrenr } 326145510Sdarrenr 327145510Sdarrenr if (num == -1 && dir == -1) { 328145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) { 329145510Sdarrenr if ((g->fg_flags & FR_INQUE) != 0) { 330145510Sdarrenr for (incnt = 0, f = g->fg_start; f != NULL; 331145510Sdarrenr f = f->fr_next) 332145510Sdarrenr incnt++; 333145510Sdarrenr if (incnt > 0) 334145510Sdarrenr emitheader(g, incnt, 0); 335145510Sdarrenr } 336145510Sdarrenr if ((g->fg_flags & FR_OUTQUE) != 0) { 337145510Sdarrenr for (outcnt = 0, f = g->fg_start; f != NULL; 338145510Sdarrenr f = f->fr_next) 339145510Sdarrenr outcnt++; 340145510Sdarrenr if (outcnt > 0) 341145510Sdarrenr emitheader(g, 0, outcnt); 342145510Sdarrenr } 343145510Sdarrenr } 344145510Sdarrenr emittail(); 345145510Sdarrenr fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n"); 346145510Sdarrenr } 347145510Sdarrenr 348145510Sdarrenr} 349145510Sdarrenr 350145510Sdarrenr 351145510Sdarrenrstatic void emitheader(grp, incount, outcount) 352255332Scy frgroup_t *grp; 353255332Scy u_int incount, outcount; 354145510Sdarrenr{ 355145510Sdarrenr static FILE *fph = NULL; 356145510Sdarrenr frgroup_t *g; 357145510Sdarrenr 358145510Sdarrenr if (fph == NULL) { 359145510Sdarrenr fph = fopen("ip_rules.h", "w"); 360145510Sdarrenr if (fph == NULL) 361145510Sdarrenr return; 362145510Sdarrenr 363369245Sgit2svn fprintf(fph, "extern int ipfrule_add(void));\n"); 364369245Sgit2svn fprintf(fph, "extern int ipfrule_remove(void));\n"); 365145510Sdarrenr } 366145510Sdarrenr 367145510Sdarrenr printhooks(cfile, incount, outcount, grp); 368145510Sdarrenr 369145510Sdarrenr if (incount) { 370145510Sdarrenr fprintf(fph, "\n\ 371369245Sgit2svnextern frentry_t *ipfrule_match_in_%s(fr_info_t *, u_32_t *));\n\ 372145510Sdarrenrextern frentry_t *ipf_rules_in_%s[%d];\n", 373145510Sdarrenr grp->fg_name, grp->fg_name, incount); 374145510Sdarrenr 375145510Sdarrenr for (g = groups; g != grp; g = g->fg_next) 376145510Sdarrenr if ((strncmp(g->fg_name, grp->fg_name, 377145510Sdarrenr FR_GROUPLEN) == 0) && 378145510Sdarrenr g->fg_flags == grp->fg_flags) 379145510Sdarrenr break; 380145510Sdarrenr if (g == grp) { 381145510Sdarrenr fprintf(fph, "\n\ 382369245Sgit2svnextern int ipfrule_add_in_%s(void));\n\ 383369245Sgit2svnextern int ipfrule_remove_in_%s(void));\n", grp->fg_name, grp->fg_name); 384145510Sdarrenr } 385145510Sdarrenr } 386145510Sdarrenr if (outcount) { 387145510Sdarrenr fprintf(fph, "\n\ 388369245Sgit2svnextern frentry_t *ipfrule_match_out_%s(fr_info_t *, u_32_t *));\n\ 389145510Sdarrenrextern frentry_t *ipf_rules_out_%s[%d];\n", 390145510Sdarrenr grp->fg_name, grp->fg_name, outcount); 391145510Sdarrenr 392194290Srdivacky for (g = groups; g != grp; g = g->fg_next) 393145510Sdarrenr if ((strncmp(g->fg_name, grp->fg_name, 394145510Sdarrenr FR_GROUPLEN) == 0) && 395145510Sdarrenr g->fg_flags == grp->fg_flags) 396145510Sdarrenr break; 397145510Sdarrenr if (g == grp) { 398145510Sdarrenr fprintf(fph, "\n\ 399369245Sgit2svnextern int ipfrule_add_out_%s(void));\n\ 400369245Sgit2svnextern int ipfrule_remove_out_%s(void));\n", 401145510Sdarrenr grp->fg_name, grp->fg_name); 402145510Sdarrenr } 403145510Sdarrenr } 404145510Sdarrenr} 405145510Sdarrenr 406145510Sdarrenrstatic void emittail() 407145510Sdarrenr{ 408145510Sdarrenr frgroup_t *g; 409145510Sdarrenr 410145510Sdarrenr fprintf(cfile, "\n\ 411145510Sdarrenrint ipfrule_add()\n\ 412145510Sdarrenr{\n\ 413145510Sdarrenr int err;\n\ 414145510Sdarrenr\n"); 415145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) 416145510Sdarrenr fprintf(cfile, "\ 417145510Sdarrenr err = ipfrule_add_%s_%s();\n\ 418145510Sdarrenr if (err != 0)\n\ 419145510Sdarrenr return err;\n", 420145510Sdarrenr (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 421145510Sdarrenr fprintf(cfile, "\ 422145510Sdarrenr return 0;\n"); 423145510Sdarrenr fprintf(cfile, "}\n\ 424145510Sdarrenr\n"); 425145510Sdarrenr 426145510Sdarrenr fprintf(cfile, "\n\ 427145510Sdarrenrint ipfrule_remove()\n\ 428145510Sdarrenr{\n\ 429145510Sdarrenr int err;\n\ 430145510Sdarrenr\n"); 431145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) 432145510Sdarrenr fprintf(cfile, "\ 433145510Sdarrenr err = ipfrule_remove_%s_%s();\n\ 434145510Sdarrenr if (err != 0)\n\ 435145510Sdarrenr return err;\n", 436145510Sdarrenr (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 437145510Sdarrenr fprintf(cfile, "\ 438145510Sdarrenr return 0;\n"); 439145510Sdarrenr fprintf(cfile, "}\n"); 440145510Sdarrenr} 441145510Sdarrenr 442145510Sdarrenr 443145510Sdarrenrstatic void emitGroup(num, dir, v, fr, group, incount, outcount) 444255332Scy int num, dir; 445255332Scy void *v; 446255332Scy frentry_t *fr; 447255332Scy char *group; 448255332Scy u_int incount, outcount; 449145510Sdarrenr{ 450145510Sdarrenr static FILE *fp = NULL; 451145510Sdarrenr static int header[2] = { 0, 0 }; 452145510Sdarrenr static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 453145510Sdarrenr static int openfunc = 0; 454145510Sdarrenr static mc_t *n = NULL; 455145510Sdarrenr static int sin = 0; 456145510Sdarrenr frentry_t *f; 457145510Sdarrenr frgroup_t *g; 458145510Sdarrenr fripf_t *ipf; 459145510Sdarrenr int i, in, j; 460145510Sdarrenr mc_t *m = v; 461145510Sdarrenr 462145510Sdarrenr if (fp == NULL) 463145510Sdarrenr fp = cfile; 464145510Sdarrenr if (fp == NULL) 465145510Sdarrenr return; 466145510Sdarrenr if (strncmp(egroup, group, FR_GROUPLEN)) { 467145510Sdarrenr for (sin--; sin > 0; sin--) { 468145510Sdarrenr indent(fp, sin); 469145510Sdarrenr fprintf(fp, "}\n"); 470145510Sdarrenr } 471145510Sdarrenr if (openfunc == 1) { 472145510Sdarrenr fprintf(fp, "\treturn fr;\n}\n"); 473145510Sdarrenr openfunc = 0; 474145510Sdarrenr if (n != NULL) { 475145510Sdarrenr free(n); 476145510Sdarrenr n = NULL; 477145510Sdarrenr } 478145510Sdarrenr } 479145510Sdarrenr sin = 0; 480145510Sdarrenr header[0] = 0; 481145510Sdarrenr header[1] = 0; 482145510Sdarrenr strncpy(egroup, group, FR_GROUPLEN); 483145510Sdarrenr } else if (openfunc == 1 && num < 0) { 484145510Sdarrenr if (n != NULL) { 485145510Sdarrenr free(n); 486145510Sdarrenr n = NULL; 487145510Sdarrenr } 488145510Sdarrenr for (sin--; sin > 0; sin--) { 489145510Sdarrenr indent(fp, sin); 490145510Sdarrenr fprintf(fp, "}\n"); 491145510Sdarrenr } 492145510Sdarrenr if (openfunc == 1) { 493145510Sdarrenr fprintf(fp, "\treturn fr;\n}\n"); 494145510Sdarrenr openfunc = 0; 495145510Sdarrenr } 496145510Sdarrenr } 497145510Sdarrenr 498145510Sdarrenr if (dir == -1) 499145510Sdarrenr return; 500145510Sdarrenr 501145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) { 502145510Sdarrenr if (dir == 0 && (g->fg_flags & FR_INQUE) == 0) 503145510Sdarrenr continue; 504145510Sdarrenr else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0) 505145510Sdarrenr continue; 506145510Sdarrenr if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0) 507145510Sdarrenr continue; 508145510Sdarrenr break; 509145510Sdarrenr } 510145510Sdarrenr 511145510Sdarrenr /* 512145510Sdarrenr * Output the array of pointers to rules for this group. 513145510Sdarrenr */ 514170268Sdarrenr if (g != NULL && num == -2 && dir == 0 && header[0] == 0 && 515170268Sdarrenr incount != 0) { 516145510Sdarrenr fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {", 517145510Sdarrenr group, incount); 518145510Sdarrenr for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 519145510Sdarrenr if ((f->fr_flags & FR_INQUE) == 0) 520145510Sdarrenr continue; 521145510Sdarrenr if ((i & 1) == 0) { 522145510Sdarrenr fprintf(fp, "\n\t"); 523145510Sdarrenr } 524255332Scy fprintf(fp, "(frentry_t *)&in_rule_%s_%d", 525255332Scy FR_NAME(f, fr_group), i); 526145510Sdarrenr if (i + 1 < incount) 527145510Sdarrenr fprintf(fp, ", "); 528145510Sdarrenr i++; 529145510Sdarrenr } 530145510Sdarrenr fprintf(fp, "\n};\n"); 531145510Sdarrenr } 532145510Sdarrenr 533170268Sdarrenr if (g != NULL && num == -2 && dir == 1 && header[0] == 0 && 534170268Sdarrenr outcount != 0) { 535145510Sdarrenr fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {", 536145510Sdarrenr group, outcount); 537145510Sdarrenr for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 538145510Sdarrenr if ((f->fr_flags & FR_OUTQUE) == 0) 539145510Sdarrenr continue; 540145510Sdarrenr if ((i & 1) == 0) { 541145510Sdarrenr fprintf(fp, "\n\t"); 542145510Sdarrenr } 543255332Scy fprintf(fp, "(frentry_t *)&out_rule_%s_%d", 544255332Scy FR_NAME(f, fr_group), i); 545145510Sdarrenr if (i + 1 < outcount) 546145510Sdarrenr fprintf(fp, ", "); 547145510Sdarrenr i++; 548145510Sdarrenr } 549145510Sdarrenr fprintf(fp, "\n};\n"); 550145510Sdarrenr fp = NULL; 551145510Sdarrenr } 552145510Sdarrenr 553145510Sdarrenr if (num < 0) 554145510Sdarrenr return; 555145510Sdarrenr 556145510Sdarrenr in = 0; 557145510Sdarrenr ipf = fr->fr_ipf; 558145510Sdarrenr 559145510Sdarrenr /* 560145510Sdarrenr * If the function header has not been printed then print it now. 561145510Sdarrenr */ 562170268Sdarrenr if (g != NULL && header[dir] == 0) { 563145510Sdarrenr int pdst = 0, psrc = 0; 564145510Sdarrenr 565145510Sdarrenr openfunc = 1; 566145510Sdarrenr fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n", 567145510Sdarrenr (dir == 0) ? "in" : "out", group); 568145510Sdarrenr fprintf(fp, "fr_info_t *fin;\n"); 569145510Sdarrenr fprintf(fp, "u_32_t *passp;\n"); 570145510Sdarrenr fprintf(fp, "{\n"); 571145510Sdarrenr fprintf(fp, "\tfrentry_t *fr = NULL;\n"); 572145510Sdarrenr 573145510Sdarrenr /* 574145510Sdarrenr * Print out any variables that need to be declared. 575145510Sdarrenr */ 576145510Sdarrenr for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 577145510Sdarrenr if (incount + outcount > m[FRC_SRC].e + 1) 578145510Sdarrenr psrc = 1; 579145510Sdarrenr if (incount + outcount > m[FRC_DST].e + 1) 580145510Sdarrenr pdst = 1; 581145510Sdarrenr } 582145510Sdarrenr if (psrc == 1) 583145510Sdarrenr fprintf(fp, "\tu_32_t src = ntohl(%s);\n", 584145510Sdarrenr "fin->fin_fi.fi_saddr"); 585145510Sdarrenr if (pdst == 1) 586145510Sdarrenr fprintf(fp, "\tu_32_t dst = ntohl(%s);\n", 587145510Sdarrenr "fin->fin_fi.fi_daddr"); 588145510Sdarrenr } 589145510Sdarrenr 590145510Sdarrenr for (i = 0; i < FRC_MAX; i++) { 591145510Sdarrenr switch(m[i].c) 592145510Sdarrenr { 593145510Sdarrenr case FRC_IFN : 594255332Scy if (fr->fr_ifnames[0] != -1) 595145510Sdarrenr m[i].s = 1; 596145510Sdarrenr break; 597145510Sdarrenr case FRC_V : 598145510Sdarrenr if (ipf != NULL && ipf->fri_mip.fi_v != 0) 599145510Sdarrenr m[i].s = 1; 600145510Sdarrenr break; 601145510Sdarrenr case FRC_FL : 602145510Sdarrenr if (ipf != NULL && ipf->fri_mip.fi_flx != 0) 603145510Sdarrenr m[i].s = 1; 604145510Sdarrenr break; 605145510Sdarrenr case FRC_P : 606145510Sdarrenr if (ipf != NULL && ipf->fri_mip.fi_p != 0) 607145510Sdarrenr m[i].s = 1; 608145510Sdarrenr break; 609145510Sdarrenr case FRC_TTL : 610145510Sdarrenr if (ipf != NULL && ipf->fri_mip.fi_ttl != 0) 611145510Sdarrenr m[i].s = 1; 612145510Sdarrenr break; 613145510Sdarrenr case FRC_TOS : 614145510Sdarrenr if (ipf != NULL && ipf->fri_mip.fi_tos != 0) 615145510Sdarrenr m[i].s = 1; 616145510Sdarrenr break; 617145510Sdarrenr case FRC_TCP : 618145510Sdarrenr if (ipf == NULL) 619145510Sdarrenr break; 620145510Sdarrenr if ((ipf->fri_ip.fi_p == IPPROTO_TCP) && 621145510Sdarrenr fr->fr_tcpfm != 0) 622145510Sdarrenr m[i].s = 1; 623145510Sdarrenr break; 624145510Sdarrenr case FRC_SP : 625145510Sdarrenr if (ipf == NULL) 626145510Sdarrenr break; 627145510Sdarrenr if (fr->fr_scmp == FR_INRANGE) 628145510Sdarrenr m[i].s = 1; 629145510Sdarrenr else if (fr->fr_scmp == FR_OUTRANGE) 630145510Sdarrenr m[i].s = 1; 631145510Sdarrenr else if (fr->fr_scmp != 0) 632145510Sdarrenr m[i].s = 1; 633145510Sdarrenr break; 634145510Sdarrenr case FRC_DP : 635145510Sdarrenr if (ipf == NULL) 636145510Sdarrenr break; 637145510Sdarrenr if (fr->fr_dcmp == FR_INRANGE) 638145510Sdarrenr m[i].s = 1; 639145510Sdarrenr else if (fr->fr_dcmp == FR_OUTRANGE) 640145510Sdarrenr m[i].s = 1; 641145510Sdarrenr else if (fr->fr_dcmp != 0) 642145510Sdarrenr m[i].s = 1; 643145510Sdarrenr break; 644145510Sdarrenr case FRC_SRC : 645145510Sdarrenr if (ipf == NULL) 646145510Sdarrenr break; 647145510Sdarrenr if (fr->fr_satype == FRI_LOOKUP) { 648145510Sdarrenr ; 649145510Sdarrenr } else if ((fr->fr_smask != 0) || 650145510Sdarrenr (fr->fr_flags & FR_NOTSRCIP) != 0) 651145510Sdarrenr m[i].s = 1; 652145510Sdarrenr break; 653145510Sdarrenr case FRC_DST : 654145510Sdarrenr if (ipf == NULL) 655145510Sdarrenr break; 656145510Sdarrenr if (fr->fr_datype == FRI_LOOKUP) { 657145510Sdarrenr ; 658145510Sdarrenr } else if ((fr->fr_dmask != 0) || 659145510Sdarrenr (fr->fr_flags & FR_NOTDSTIP) != 0) 660145510Sdarrenr m[i].s = 1; 661145510Sdarrenr break; 662145510Sdarrenr case FRC_OPT : 663145510Sdarrenr if (ipf == NULL) 664145510Sdarrenr break; 665145510Sdarrenr if (fr->fr_optmask != 0) 666145510Sdarrenr m[i].s = 1; 667145510Sdarrenr break; 668145510Sdarrenr case FRC_SEC : 669145510Sdarrenr if (ipf == NULL) 670145510Sdarrenr break; 671145510Sdarrenr if (fr->fr_secmask != 0) 672145510Sdarrenr m[i].s = 1; 673145510Sdarrenr break; 674145510Sdarrenr case FRC_ATH : 675145510Sdarrenr if (ipf == NULL) 676145510Sdarrenr break; 677145510Sdarrenr if (fr->fr_authmask != 0) 678145510Sdarrenr m[i].s = 1; 679145510Sdarrenr break; 680145510Sdarrenr case FRC_ICT : 681145510Sdarrenr if (ipf == NULL) 682145510Sdarrenr break; 683145510Sdarrenr if ((fr->fr_icmpm & 0xff00) != 0) 684145510Sdarrenr m[i].s = 1; 685145510Sdarrenr break; 686145510Sdarrenr case FRC_ICC : 687145510Sdarrenr if (ipf == NULL) 688145510Sdarrenr break; 689145510Sdarrenr if ((fr->fr_icmpm & 0xff) != 0) 690145510Sdarrenr m[i].s = 1; 691145510Sdarrenr break; 692145510Sdarrenr } 693145510Sdarrenr } 694145510Sdarrenr 695145510Sdarrenr if (!header[dir]) { 696145510Sdarrenr fprintf(fp, "\n"); 697145510Sdarrenr header[dir] = 1; 698145510Sdarrenr sin = 0; 699145510Sdarrenr } 700145510Sdarrenr 701145510Sdarrenr qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 702145510Sdarrenr 703145510Sdarrenr if (n) { 704145510Sdarrenr /* 705145510Sdarrenr * Calculate the indentation interval upto the last common 706145510Sdarrenr * common comparison being made. 707145510Sdarrenr */ 708145510Sdarrenr for (i = 0, in = 1; i < FRC_MAX; i++) { 709145510Sdarrenr if (n[i].c != m[i].c) 710145510Sdarrenr break; 711145510Sdarrenr if (n[i].s != m[i].s) 712145510Sdarrenr break; 713145510Sdarrenr if (n[i].s) { 714145510Sdarrenr if (n[i].n && (n[i].n > n[i].e)) { 715145510Sdarrenr m[i].p++; 716145510Sdarrenr in += m[i].p; 717145510Sdarrenr break; 718145510Sdarrenr } 719145510Sdarrenr if (n[i].e > 0) { 720145510Sdarrenr in++; 721145510Sdarrenr } else 722145510Sdarrenr break; 723145510Sdarrenr } 724145510Sdarrenr } 725145510Sdarrenr if (sin != in) { 726145510Sdarrenr for (j = sin - 1; j >= in; j--) { 727145510Sdarrenr indent(fp, j); 728145510Sdarrenr fprintf(fp, "}\n"); 729145510Sdarrenr } 730145510Sdarrenr } 731145510Sdarrenr } else { 732145510Sdarrenr in = 1; 733145510Sdarrenr i = 0; 734145510Sdarrenr } 735145510Sdarrenr 736145510Sdarrenr /* 737145510Sdarrenr * print out C code that implements a filter rule. 738145510Sdarrenr */ 739145510Sdarrenr for (; i < FRC_MAX; i++) { 740145510Sdarrenr switch(m[i].c) 741145510Sdarrenr { 742145510Sdarrenr case FRC_IFN : 743145510Sdarrenr if (m[i].s) { 744145510Sdarrenr indent(fp, in); 745145510Sdarrenr fprintf(fp, "if (fin->fin_ifp == "); 746145510Sdarrenr fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n", 747145510Sdarrenr dir ? "out" : "in", group, num); 748145510Sdarrenr in++; 749145510Sdarrenr } 750145510Sdarrenr break; 751145510Sdarrenr case FRC_V : 752145510Sdarrenr if (m[i].s) { 753145510Sdarrenr indent(fp, in); 754145510Sdarrenr fprintf(fp, "if (fin->fin_v == %d) {\n", 755145510Sdarrenr ipf->fri_ip.fi_v); 756145510Sdarrenr in++; 757145510Sdarrenr } 758145510Sdarrenr break; 759145510Sdarrenr case FRC_FL : 760145510Sdarrenr if (m[i].s) { 761145510Sdarrenr indent(fp, in); 762145510Sdarrenr fprintf(fp, "if ("); 763145510Sdarrenr printeq(fp, "fin->fin_flx", 764145510Sdarrenr ipf->fri_mip.fi_flx, 0xf, 765145510Sdarrenr ipf->fri_ip.fi_flx); 766145510Sdarrenr in++; 767145510Sdarrenr } 768145510Sdarrenr break; 769145510Sdarrenr case FRC_P : 770145510Sdarrenr if (m[i].s) { 771145510Sdarrenr indent(fp, in); 772145510Sdarrenr fprintf(fp, "if (fin->fin_p == %d) {\n", 773145510Sdarrenr ipf->fri_ip.fi_p); 774145510Sdarrenr in++; 775145510Sdarrenr } 776145510Sdarrenr break; 777145510Sdarrenr case FRC_TTL : 778145510Sdarrenr if (m[i].s) { 779145510Sdarrenr indent(fp, in); 780145510Sdarrenr fprintf(fp, "if ("); 781145510Sdarrenr printeq(fp, "fin->fin_ttl", 782145510Sdarrenr ipf->fri_mip.fi_ttl, 0xff, 783145510Sdarrenr ipf->fri_ip.fi_ttl); 784145510Sdarrenr in++; 785145510Sdarrenr } 786145510Sdarrenr break; 787145510Sdarrenr case FRC_TOS : 788145510Sdarrenr if (m[i].s) { 789145510Sdarrenr indent(fp, in); 790145510Sdarrenr fprintf(fp, "if (fin->fin_tos"); 791145510Sdarrenr printeq(fp, "fin->fin_tos", 792145510Sdarrenr ipf->fri_mip.fi_tos, 0xff, 793145510Sdarrenr ipf->fri_ip.fi_tos); 794145510Sdarrenr in++; 795145510Sdarrenr } 796145510Sdarrenr break; 797145510Sdarrenr case FRC_TCP : 798145510Sdarrenr if (m[i].s) { 799145510Sdarrenr indent(fp, in); 800145510Sdarrenr fprintf(fp, "if ("); 801145510Sdarrenr printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm, 802145510Sdarrenr 0xff, fr->fr_tcpf); 803145510Sdarrenr in++; 804145510Sdarrenr } 805145510Sdarrenr break; 806145510Sdarrenr case FRC_SP : 807145510Sdarrenr if (!m[i].s) 808145510Sdarrenr break; 809145510Sdarrenr if (fr->fr_scmp == FR_INRANGE) { 810145510Sdarrenr indent(fp, in); 811145510Sdarrenr fprintf(fp, "if ((fin->fin_data[0] > %d) && ", 812145510Sdarrenr fr->fr_sport); 813145510Sdarrenr fprintf(fp, "(fin->fin_data[0] < %d)", 814145510Sdarrenr fr->fr_stop); 815145510Sdarrenr fprintf(fp, ") {\n"); 816145510Sdarrenr in++; 817145510Sdarrenr } else if (fr->fr_scmp == FR_OUTRANGE) { 818145510Sdarrenr indent(fp, in); 819145510Sdarrenr fprintf(fp, "if ((fin->fin_data[0] < %d) || ", 820145510Sdarrenr fr->fr_sport); 821145510Sdarrenr fprintf(fp, "(fin->fin_data[0] > %d)", 822145510Sdarrenr fr->fr_stop); 823145510Sdarrenr fprintf(fp, ") {\n"); 824145510Sdarrenr in++; 825145510Sdarrenr } else if (fr->fr_scmp) { 826145510Sdarrenr indent(fp, in); 827145510Sdarrenr fprintf(fp, "if (fin->fin_data[0] %s %d)", 828145510Sdarrenr portcmp[fr->fr_scmp], fr->fr_sport); 829145510Sdarrenr fprintf(fp, " {\n"); 830145510Sdarrenr in++; 831145510Sdarrenr } 832145510Sdarrenr break; 833145510Sdarrenr case FRC_DP : 834145510Sdarrenr if (!m[i].s) 835145510Sdarrenr break; 836145510Sdarrenr if (fr->fr_dcmp == FR_INRANGE) { 837145510Sdarrenr indent(fp, in); 838145510Sdarrenr fprintf(fp, "if ((fin->fin_data[1] > %d) && ", 839145510Sdarrenr fr->fr_dport); 840145510Sdarrenr fprintf(fp, "(fin->fin_data[1] < %d)", 841145510Sdarrenr fr->fr_dtop); 842145510Sdarrenr fprintf(fp, ") {\n"); 843145510Sdarrenr in++; 844145510Sdarrenr } else if (fr->fr_dcmp == FR_OUTRANGE) { 845145510Sdarrenr indent(fp, in); 846145510Sdarrenr fprintf(fp, "if ((fin->fin_data[1] < %d) || ", 847145510Sdarrenr fr->fr_dport); 848145510Sdarrenr fprintf(fp, "(fin->fin_data[1] > %d)", 849145510Sdarrenr fr->fr_dtop); 850145510Sdarrenr fprintf(fp, ") {\n"); 851145510Sdarrenr in++; 852145510Sdarrenr } else if (fr->fr_dcmp) { 853145510Sdarrenr indent(fp, in); 854145510Sdarrenr fprintf(fp, "if (fin->fin_data[1] %s %d)", 855145510Sdarrenr portcmp[fr->fr_dcmp], fr->fr_dport); 856145510Sdarrenr fprintf(fp, " {\n"); 857145510Sdarrenr in++; 858145510Sdarrenr } 859145510Sdarrenr break; 860145510Sdarrenr case FRC_SRC : 861145510Sdarrenr if (!m[i].s) 862145510Sdarrenr break; 863145510Sdarrenr if (fr->fr_satype == FRI_LOOKUP) { 864145510Sdarrenr ; 865145510Sdarrenr } else if ((fr->fr_smask != 0) || 866145510Sdarrenr (fr->fr_flags & FR_NOTSRCIP) != 0) { 867145510Sdarrenr indent(fp, in); 868145510Sdarrenr fprintf(fp, "if ("); 869145510Sdarrenr printipeq(fp, "src", 870145510Sdarrenr fr->fr_flags & FR_NOTSRCIP, 871145510Sdarrenr fr->fr_smask, fr->fr_saddr); 872145510Sdarrenr in++; 873145510Sdarrenr } 874145510Sdarrenr break; 875145510Sdarrenr case FRC_DST : 876145510Sdarrenr if (!m[i].s) 877145510Sdarrenr break; 878145510Sdarrenr if (fr->fr_datype == FRI_LOOKUP) { 879145510Sdarrenr ; 880145510Sdarrenr } else if ((fr->fr_dmask != 0) || 881145510Sdarrenr (fr->fr_flags & FR_NOTDSTIP) != 0) { 882145510Sdarrenr indent(fp, in); 883145510Sdarrenr fprintf(fp, "if ("); 884145510Sdarrenr printipeq(fp, "dst", 885145510Sdarrenr fr->fr_flags & FR_NOTDSTIP, 886145510Sdarrenr fr->fr_dmask, fr->fr_daddr); 887145510Sdarrenr in++; 888145510Sdarrenr } 889145510Sdarrenr break; 890145510Sdarrenr case FRC_OPT : 891145510Sdarrenr if (m[i].s) { 892145510Sdarrenr indent(fp, in); 893145510Sdarrenr fprintf(fp, "if ("); 894145510Sdarrenr printeq(fp, "fin->fin_fi.fi_optmsk", 895145510Sdarrenr fr->fr_optmask, 0xffffffff, 896145510Sdarrenr fr->fr_optbits); 897145510Sdarrenr in++; 898145510Sdarrenr } 899145510Sdarrenr break; 900145510Sdarrenr case FRC_SEC : 901145510Sdarrenr if (m[i].s) { 902145510Sdarrenr indent(fp, in); 903145510Sdarrenr fprintf(fp, "if ("); 904145510Sdarrenr printeq(fp, "fin->fin_fi.fi_secmsk", 905145510Sdarrenr fr->fr_secmask, 0xffff, 906145510Sdarrenr fr->fr_secbits); 907145510Sdarrenr in++; 908145510Sdarrenr } 909145510Sdarrenr break; 910145510Sdarrenr case FRC_ATH : 911145510Sdarrenr if (m[i].s) { 912145510Sdarrenr indent(fp, in); 913145510Sdarrenr fprintf(fp, "if ("); 914145510Sdarrenr printeq(fp, "fin->fin_fi.fi_authmsk", 915145510Sdarrenr fr->fr_authmask, 0xffff, 916145510Sdarrenr fr->fr_authbits); 917145510Sdarrenr in++; 918145510Sdarrenr } 919145510Sdarrenr break; 920145510Sdarrenr case FRC_ICT : 921145510Sdarrenr if (m[i].s) { 922145510Sdarrenr indent(fp, in); 923145510Sdarrenr fprintf(fp, "if ("); 924145510Sdarrenr printeq(fp, "fin->fin_data[0]", 925145510Sdarrenr fr->fr_icmpm & 0xff00, 0xffff, 926145510Sdarrenr fr->fr_icmp & 0xff00); 927145510Sdarrenr in++; 928145510Sdarrenr } 929145510Sdarrenr break; 930145510Sdarrenr case FRC_ICC : 931145510Sdarrenr if (m[i].s) { 932145510Sdarrenr indent(fp, in); 933145510Sdarrenr fprintf(fp, "if ("); 934145510Sdarrenr printeq(fp, "fin->fin_data[0]", 935145510Sdarrenr fr->fr_icmpm & 0xff, 0xffff, 936145510Sdarrenr fr->fr_icmp & 0xff); 937145510Sdarrenr in++; 938145510Sdarrenr } 939145510Sdarrenr break; 940145510Sdarrenr } 941145510Sdarrenr 942145510Sdarrenr } 943145510Sdarrenr 944145510Sdarrenr indent(fp, in); 945145510Sdarrenr if (fr->fr_flags & FR_QUICK) { 946145510Sdarrenr fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n", 947145510Sdarrenr fr->fr_flags & FR_INQUE ? "in" : "out", 948255332Scy FR_NAME(fr, fr_group), num); 949145510Sdarrenr } else { 950145510Sdarrenr fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", 951145510Sdarrenr fr->fr_flags & FR_INQUE ? "in" : "out", 952255332Scy FR_NAME(fr, fr_group), num); 953145510Sdarrenr } 954145510Sdarrenr if (n == NULL) 955145510Sdarrenr n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); 956145510Sdarrenr bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX); 957145510Sdarrenr sin = in; 958145510Sdarrenr} 959145510Sdarrenr 960145510Sdarrenr 961145510Sdarrenrvoid printC(dir) 962255332Scy int dir; 963145510Sdarrenr{ 964145510Sdarrenr static mc_t *m = NULL; 965145510Sdarrenr frgroup_t *g; 966145510Sdarrenr 967145510Sdarrenr if (m == NULL) 968319175Scy m = (mc_t *)calloc(FRC_MAX, sizeof(*m)); 969145510Sdarrenr 970145510Sdarrenr for (g = groups; g != NULL; g = g->fg_next) { 971145510Sdarrenr if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0)) 972145510Sdarrenr printCgroup(dir, g->fg_start, m, g->fg_name); 973145510Sdarrenr if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0)) 974145510Sdarrenr printCgroup(dir, g->fg_start, m, g->fg_name); 975145510Sdarrenr } 976145510Sdarrenr 977145510Sdarrenr emit(-1, dir, m, NULL); 978145510Sdarrenr} 979145510Sdarrenr 980145510Sdarrenr 981145510Sdarrenr/* 982145510Sdarrenr * Now print out code to implement all of the rules. 983145510Sdarrenr */ 984145510Sdarrenrstatic void printCgroup(dir, top, m, group) 985255332Scy int dir; 986255332Scy frentry_t *top; 987255332Scy mc_t *m; 988255332Scy char *group; 989145510Sdarrenr{ 990145510Sdarrenr frentry_t *fr, *fr1; 991145510Sdarrenr int i, n, rn; 992145510Sdarrenr u_int count; 993145510Sdarrenr 994145510Sdarrenr for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) { 995145510Sdarrenr if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0)) 996145510Sdarrenr count++; 997145510Sdarrenr else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0)) 998145510Sdarrenr count++; 999145510Sdarrenr } 1000145510Sdarrenr 1001145510Sdarrenr if (dir == 0) 1002145510Sdarrenr emitGroup(-2, dir, m, fr1, group, count, 0); 1003145510Sdarrenr else if (dir == 1) 1004145510Sdarrenr emitGroup(-2, dir, m, fr1, group, 0, count); 1005145510Sdarrenr 1006145510Sdarrenr /* 1007145510Sdarrenr * Before printing each rule, check to see how many of its fields are 1008145510Sdarrenr * matched by subsequent rules. 1009145510Sdarrenr */ 1010145510Sdarrenr for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) { 1011145510Sdarrenr if (!dir && !(fr1->fr_flags & FR_INQUE)) 1012145510Sdarrenr continue; 1013145510Sdarrenr if (dir && !(fr1->fr_flags & FR_OUTQUE)) 1014145510Sdarrenr continue; 1015145510Sdarrenr n = 0xfffffff; 1016145510Sdarrenr 1017145510Sdarrenr for (i = 0; i < FRC_MAX; i++) 1018145510Sdarrenr m[i].e = 0; 1019145510Sdarrenr qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 1020145510Sdarrenr 1021145510Sdarrenr for (i = 0; i < FRC_MAX; i++) { 1022145510Sdarrenr m[i].c = i; 1023145510Sdarrenr m[i].e = 0; 1024145510Sdarrenr m[i].n = 0; 1025145510Sdarrenr m[i].s = 0; 1026145510Sdarrenr } 1027145510Sdarrenr 1028145510Sdarrenr for (fr = fr1->fr_next; fr; fr = fr->fr_next) { 1029145510Sdarrenr if (!dir && !(fr->fr_flags & FR_INQUE)) 1030145510Sdarrenr continue; 1031145510Sdarrenr if (dir && !(fr->fr_flags & FR_OUTQUE)) 1032145510Sdarrenr continue; 1033145510Sdarrenr 1034145510Sdarrenr if ((n & 0x0001) && 1035255332Scy !strcmp(fr1->fr_names + fr1->fr_ifnames[0], 1036255332Scy fr->fr_names + fr->fr_ifnames[0])) { 1037145510Sdarrenr m[FRC_IFN].e++; 1038145510Sdarrenr m[FRC_IFN].n++; 1039145510Sdarrenr } else 1040145510Sdarrenr n &= ~0x0001; 1041145510Sdarrenr 1042255332Scy if ((n & 0x0002) && (fr1->fr_family == fr->fr_family)) { 1043145510Sdarrenr m[FRC_V].e++; 1044145510Sdarrenr m[FRC_V].n++; 1045145510Sdarrenr } else 1046145510Sdarrenr n &= ~0x0002; 1047145510Sdarrenr 1048145510Sdarrenr if ((n & 0x0004) && 1049145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1050145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1051145510Sdarrenr (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) && 1052145510Sdarrenr (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) { 1053145510Sdarrenr m[FRC_FL].e++; 1054145510Sdarrenr m[FRC_FL].n++; 1055145510Sdarrenr } else 1056145510Sdarrenr n &= ~0x0004; 1057145510Sdarrenr 1058145510Sdarrenr if ((n & 0x0008) && 1059145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1060145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1061145510Sdarrenr (fr1->fr_proto == fr->fr_proto)) { 1062145510Sdarrenr m[FRC_P].e++; 1063145510Sdarrenr m[FRC_P].n++; 1064145510Sdarrenr } else 1065145510Sdarrenr n &= ~0x0008; 1066145510Sdarrenr 1067145510Sdarrenr if ((n & 0x0010) && 1068145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1069145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1070145510Sdarrenr (fr1->fr_ttl == fr->fr_ttl)) { 1071145510Sdarrenr m[FRC_TTL].e++; 1072145510Sdarrenr m[FRC_TTL].n++; 1073145510Sdarrenr } else 1074145510Sdarrenr n &= ~0x0010; 1075145510Sdarrenr 1076145510Sdarrenr if ((n & 0x0020) && 1077145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1078145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1079145510Sdarrenr (fr1->fr_tos == fr->fr_tos)) { 1080145510Sdarrenr m[FRC_TOS].e++; 1081145510Sdarrenr m[FRC_TOS].n++; 1082145510Sdarrenr } else 1083145510Sdarrenr n &= ~0x0020; 1084145510Sdarrenr 1085145510Sdarrenr if ((n & 0x0040) && 1086145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1087145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1088145510Sdarrenr ((fr1->fr_tcpfm == fr->fr_tcpfm) && 1089145510Sdarrenr (fr1->fr_tcpf == fr->fr_tcpf))) { 1090145510Sdarrenr m[FRC_TCP].e++; 1091145510Sdarrenr m[FRC_TCP].n++; 1092145510Sdarrenr } else 1093145510Sdarrenr n &= ~0x0040; 1094145510Sdarrenr 1095145510Sdarrenr if ((n & 0x0080) && 1096145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1097145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1098145510Sdarrenr ((fr1->fr_scmp == fr->fr_scmp) && 1099145510Sdarrenr (fr1->fr_stop == fr->fr_stop) && 1100145510Sdarrenr (fr1->fr_sport == fr->fr_sport))) { 1101145510Sdarrenr m[FRC_SP].e++; 1102145510Sdarrenr m[FRC_SP].n++; 1103145510Sdarrenr } else 1104145510Sdarrenr n &= ~0x0080; 1105145510Sdarrenr 1106145510Sdarrenr if ((n & 0x0100) && 1107145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1108145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1109145510Sdarrenr ((fr1->fr_dcmp == fr->fr_dcmp) && 1110145510Sdarrenr (fr1->fr_dtop == fr->fr_dtop) && 1111145510Sdarrenr (fr1->fr_dport == fr->fr_dport))) { 1112145510Sdarrenr m[FRC_DP].e++; 1113145510Sdarrenr m[FRC_DP].n++; 1114145510Sdarrenr } else 1115145510Sdarrenr n &= ~0x0100; 1116145510Sdarrenr 1117145510Sdarrenr if ((n & 0x0200) && 1118145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1119145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1120145510Sdarrenr ((fr1->fr_satype == FRI_LOOKUP) && 1121145510Sdarrenr (fr->fr_satype == FRI_LOOKUP) && 1122145510Sdarrenr (fr1->fr_srcnum == fr->fr_srcnum))) { 1123145510Sdarrenr m[FRC_SRC].e++; 1124145510Sdarrenr m[FRC_SRC].n++; 1125145510Sdarrenr } else if ((n & 0x0200) && 1126145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1127145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1128145510Sdarrenr (((fr1->fr_flags & FR_NOTSRCIP) == 1129145510Sdarrenr (fr->fr_flags & FR_NOTSRCIP)))) { 1130145510Sdarrenr if ((fr1->fr_smask == fr->fr_smask) && 1131145510Sdarrenr (fr1->fr_saddr == fr->fr_saddr)) 1132145510Sdarrenr m[FRC_SRC].e++; 1133145510Sdarrenr else 1134145510Sdarrenr n &= ~0x0200; 1135145510Sdarrenr if (fr1->fr_smask && 1136145510Sdarrenr (fr1->fr_saddr & fr1->fr_smask) == 1137145510Sdarrenr (fr->fr_saddr & fr1->fr_smask)) { 1138145510Sdarrenr m[FRC_SRC].n++; 1139145510Sdarrenr n |= 0x0200; 1140145510Sdarrenr } 1141145510Sdarrenr } else { 1142145510Sdarrenr n &= ~0x0200; 1143145510Sdarrenr } 1144145510Sdarrenr 1145145510Sdarrenr if ((n & 0x0400) && 1146145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1147145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1148145510Sdarrenr ((fr1->fr_datype == FRI_LOOKUP) && 1149145510Sdarrenr (fr->fr_datype == FRI_LOOKUP) && 1150145510Sdarrenr (fr1->fr_dstnum == fr->fr_dstnum))) { 1151145510Sdarrenr m[FRC_DST].e++; 1152145510Sdarrenr m[FRC_DST].n++; 1153145510Sdarrenr } else if ((n & 0x0400) && 1154145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1155145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1156145510Sdarrenr (((fr1->fr_flags & FR_NOTDSTIP) == 1157145510Sdarrenr (fr->fr_flags & FR_NOTDSTIP)))) { 1158145510Sdarrenr if ((fr1->fr_dmask == fr->fr_dmask) && 1159145510Sdarrenr (fr1->fr_daddr == fr->fr_daddr)) 1160145510Sdarrenr m[FRC_DST].e++; 1161145510Sdarrenr else 1162145510Sdarrenr n &= ~0x0400; 1163145510Sdarrenr if (fr1->fr_dmask && 1164145510Sdarrenr (fr1->fr_daddr & fr1->fr_dmask) == 1165145510Sdarrenr (fr->fr_daddr & fr1->fr_dmask)) { 1166145510Sdarrenr m[FRC_DST].n++; 1167145510Sdarrenr n |= 0x0400; 1168145510Sdarrenr } 1169145510Sdarrenr } else { 1170145510Sdarrenr n &= ~0x0400; 1171145510Sdarrenr } 1172145510Sdarrenr 1173145510Sdarrenr if ((n & 0x0800) && 1174145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1175145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1176145510Sdarrenr (fr1->fr_optmask == fr->fr_optmask) && 1177145510Sdarrenr (fr1->fr_optbits == fr->fr_optbits)) { 1178145510Sdarrenr m[FRC_OPT].e++; 1179145510Sdarrenr m[FRC_OPT].n++; 1180145510Sdarrenr } else 1181145510Sdarrenr n &= ~0x0800; 1182145510Sdarrenr 1183145510Sdarrenr if ((n & 0x1000) && 1184145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1185145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1186145510Sdarrenr (fr1->fr_secmask == fr->fr_secmask) && 1187145510Sdarrenr (fr1->fr_secbits == fr->fr_secbits)) { 1188145510Sdarrenr m[FRC_SEC].e++; 1189145510Sdarrenr m[FRC_SEC].n++; 1190145510Sdarrenr } else 1191145510Sdarrenr n &= ~0x1000; 1192145510Sdarrenr 1193145510Sdarrenr if ((n & 0x10000) && 1194145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1195145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1196145510Sdarrenr (fr1->fr_authmask == fr->fr_authmask) && 1197145510Sdarrenr (fr1->fr_authbits == fr->fr_authbits)) { 1198145510Sdarrenr m[FRC_ATH].e++; 1199145510Sdarrenr m[FRC_ATH].n++; 1200145510Sdarrenr } else 1201145510Sdarrenr n &= ~0x10000; 1202145510Sdarrenr 1203145510Sdarrenr if ((n & 0x20000) && 1204145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1205145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1206145510Sdarrenr ((fr1->fr_icmpm & 0xff00) == 1207145510Sdarrenr (fr->fr_icmpm & 0xff00)) && 1208145510Sdarrenr ((fr1->fr_icmp & 0xff00) == 1209145510Sdarrenr (fr->fr_icmp & 0xff00))) { 1210145510Sdarrenr m[FRC_ICT].e++; 1211145510Sdarrenr m[FRC_ICT].n++; 1212145510Sdarrenr } else 1213145510Sdarrenr n &= ~0x20000; 1214145510Sdarrenr 1215145510Sdarrenr if ((n & 0x40000) && 1216145510Sdarrenr (fr->fr_type == fr1->fr_type) && 1217145510Sdarrenr (fr->fr_type == FR_T_IPF) && 1218145510Sdarrenr ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) && 1219145510Sdarrenr ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) { 1220145510Sdarrenr m[FRC_ICC].e++; 1221145510Sdarrenr m[FRC_ICC].n++; 1222145510Sdarrenr } else 1223145510Sdarrenr n &= ~0x40000; 1224145510Sdarrenr } 1225145510Sdarrenr /*msort(m);*/ 1226145510Sdarrenr 1227145510Sdarrenr if (dir == 0) 1228145510Sdarrenr emitGroup(rn, dir, m, fr1, group, count, 0); 1229145510Sdarrenr else if (dir == 1) 1230145510Sdarrenr emitGroup(rn, dir, m, fr1, group, 0, count); 1231145510Sdarrenr } 1232145510Sdarrenr} 1233145510Sdarrenr 1234145510Sdarrenrstatic void printhooks(fp, in, out, grp) 1235255332Scy FILE *fp; 1236255332Scy int in; 1237255332Scy int out; 1238255332Scy frgroup_t *grp; 1239145510Sdarrenr{ 1240145510Sdarrenr frentry_t *fr; 1241145510Sdarrenr char *group; 1242145510Sdarrenr int dogrp, i; 1243145510Sdarrenr char *instr; 1244145510Sdarrenr 1245145510Sdarrenr group = grp->fg_name; 1246255332Scy dogrp = 0; 1247145510Sdarrenr 1248145510Sdarrenr if (in && out) { 1249145510Sdarrenr fprintf(stderr, 1250145510Sdarrenr "printhooks called with both in and out set\n"); 1251145510Sdarrenr exit(1); 1252145510Sdarrenr } 1253145510Sdarrenr 1254145510Sdarrenr if (in) { 1255145510Sdarrenr instr = "in"; 1256145510Sdarrenr } else if (out) { 1257145510Sdarrenr instr = "out"; 1258145510Sdarrenr } else { 1259145510Sdarrenr instr = "???"; 1260145510Sdarrenr } 1261145510Sdarrenr fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group); 1262145510Sdarrenr 1263145510Sdarrenr fprintf(fp, "\ 1264145510Sdarrenr\n\ 1265145510Sdarrenrint ipfrule_add_%s_%s()\n", instr, group); 1266145510Sdarrenr fprintf(fp, "\ 1267145510Sdarrenr{\n\ 1268145510Sdarrenr int i, j, err = 0, max;\n\ 1269145510Sdarrenr frentry_t *fp;\n"); 1270145510Sdarrenr 1271145510Sdarrenr if (dogrp) 1272145510Sdarrenr fprintf(fp, "\ 1273145510Sdarrenr frgroup_t *fg;\n"); 1274145510Sdarrenr 1275145510Sdarrenr fprintf(fp, "\n"); 1276145510Sdarrenr 1277145510Sdarrenr for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next) 1278145510Sdarrenr if (fr->fr_dsize > 0) { 1279145510Sdarrenr fprintf(fp, "\ 1280145510Sdarrenr ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n", 1281145510Sdarrenr instr, grp->fg_name, i, 1282145510Sdarrenr instr, grp->fg_name, i); 1283145510Sdarrenr } 1284145510Sdarrenr fprintf(fp, "\ 1285145510Sdarrenr max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\ 1286145510Sdarrenr for (i = 0; i < max; i++) {\n\ 1287145510Sdarrenr fp = ipf_rules_%s_%s[i];\n\ 1288145510Sdarrenr fp->fr_next = NULL;\n", instr, group, instr, group); 1289145510Sdarrenr 1290145510Sdarrenr fprintf(fp, "\ 1291145510Sdarrenr for (j = i + 1; j < max; j++)\n\ 1292255332Scy if (strncmp(fp->fr_names + fp->fr_group,\n\ 1293255332Scy ipf_rules_%s_%s[j]->fr_names +\n\ 1294145510Sdarrenr ipf_rules_%s_%s[j]->fr_group,\n\ 1295145510Sdarrenr FR_GROUPLEN) == 0) {\n\ 1296255332Scy if (ipf_rules_%s_%s[j] != NULL)\n\ 1297255332Scy ipf_rules_%s_%s[j]->fr_pnext =\n\ 1298255332Scy &fp->fr_next;\n\ 1299255332Scy fp->fr_pnext = &ipf_rules_%s_%s[j];\n\ 1300145510Sdarrenr fp->fr_next = ipf_rules_%s_%s[j];\n\ 1301145510Sdarrenr break;\n\ 1302255332Scy }\n", instr, group, instr, group, instr, group, 1303255332Scy instr, group, instr, group, instr, group); 1304145510Sdarrenr if (dogrp) 1305145510Sdarrenr fprintf(fp, "\ 1306145510Sdarrenr\n\ 1307255332Scy if (fp->fr_grhead != -1) {\n\ 1308255332Scy fg = fr_addgroup(fp->fr_names + fp->fr_grhead,\n\ 1309255332Scy fp, FR_INQUE, IPL_LOGIPF, 0);\n\ 1310145510Sdarrenr if (fg != NULL)\n\ 1311145510Sdarrenr fp->fr_grp = &fg->fg_start;\n\ 1312145510Sdarrenr }\n"); 1313145510Sdarrenr fprintf(fp, "\ 1314145510Sdarrenr }\n\ 1315145510Sdarrenr\n\ 1316145510Sdarrenr fp = &ipfrule_%s_%s;\n", instr, group); 1317145510Sdarrenr fprintf(fp, "\ 1318145510Sdarrenr bzero((char *)fp, sizeof(*fp));\n\ 1319255332Scy fp->fr_type = FR_T_CALLFUNC_BUILTIN;\n\ 1320145510Sdarrenr fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ 1321145510Sdarrenr fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", 1322145510Sdarrenr (in != 0) ? "IN" : "OUT", instr, group); 1323145510Sdarrenr fprintf(fp, "\ 1324145510Sdarrenr fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n", 1325145510Sdarrenr instr, group); 1326145510Sdarrenr 1327145510Sdarrenr fprintf(fp, "\ 1328255332Scy fp->fr_family = AF_INET;\n\ 1329145510Sdarrenr fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ 1330255332Scy err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,\n\ 1331255332Scy ipfmain.ipf_active, 0);\n", 1332145510Sdarrenr instr, group); 1333145510Sdarrenr fprintf(fp, "\treturn err;\n}\n"); 1334145510Sdarrenr 1335145510Sdarrenr fprintf(fp, "\n\n\ 1336145510Sdarrenrint ipfrule_remove_%s_%s()\n", instr, group); 1337145510Sdarrenr fprintf(fp, "\ 1338145510Sdarrenr{\n\ 1339145510Sdarrenr int err = 0, i;\n\ 1340145510Sdarrenr frentry_t *fp;\n\ 1341145510Sdarrenr\n\ 1342145510Sdarrenr /*\n\ 1343145510Sdarrenr * Try to remove the %sbound rule.\n", instr); 1344145510Sdarrenr 1345145510Sdarrenr fprintf(fp, "\ 1346145510Sdarrenr */\n\ 1347145510Sdarrenr if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group); 1348145510Sdarrenr 1349145510Sdarrenr fprintf(fp, "\ 1350145510Sdarrenr err = EBUSY;\n\ 1351145510Sdarrenr } else {\n"); 1352145510Sdarrenr 1353145510Sdarrenr fprintf(fp, "\ 1354145510Sdarrenr i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\ 1355145510Sdarrenr for (; i >= 0; i--) {\n\ 1356145510Sdarrenr fp = ipf_rules_%s_%s[i];\n\ 1357145510Sdarrenr if (fp->fr_ref > 1) {\n\ 1358145510Sdarrenr err = EBUSY;\n\ 1359145510Sdarrenr break;\n\ 1360145510Sdarrenr }\n\ 1361145510Sdarrenr }\n\ 1362145510Sdarrenr }\n\ 1363145510Sdarrenr if (err == 0)\n\ 1364255332Scy err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,\n\ 1365255332Scy (caddr_t)&ipfrule_%s_%s,\n\ 1366255332Scy ipfmain.ipf_active, 0);\n", 1367145510Sdarrenr instr, group, instr, group, instr, group); 1368145510Sdarrenr fprintf(fp, "\ 1369145510Sdarrenr if (err)\n\ 1370145510Sdarrenr return err;\n\ 1371145510Sdarrenr\n\n"); 1372145510Sdarrenr 1373145510Sdarrenr fprintf(fp, "\treturn err;\n}\n"); 1374145510Sdarrenr} 1375