1 2 /* 3 * Copyright (C) 2012 by Darren Reed. 4 * 5 * See the IPFILTER.LICENCE file for details on licencing. 6 */ 7 #if !defined(lint) 8 static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 9 static const char rcsid[] = "@(#)$Id$"; 10 #endif 11 12 #include "ipf.h" 13 14 15 typedef struct { 16 int c; 17 int e; 18 int n; 19 int p; 20 int s; 21 } mc_t; 22 23 24 static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" }; 25 static int count = 0; 26 27 int intcmp(const void *, const void *); 28 static void indent(FILE *, int); 29 static void printeq(FILE *, char *, int, int, int); 30 static void printipeq(FILE *, char *, int, int, int); 31 static void addrule(FILE *, frentry_t *); 32 static void printhooks(FILE *, int, int, frgroup_t *); 33 static void emitheader(frgroup_t *, u_int, u_int); 34 static void emitGroup(int, int, void *, frentry_t *, char *, 35 u_int, u_int); 36 static void emittail(void); 37 static void printCgroup(int, frentry_t *, mc_t *, char *); 38 39 #define FRC_IFN 0 40 #define FRC_V 1 41 #define FRC_P 2 42 #define FRC_FL 3 43 #define FRC_TOS 4 44 #define FRC_TTL 5 45 #define FRC_SRC 6 46 #define FRC_DST 7 47 #define FRC_TCP 8 48 #define FRC_SP 9 49 #define FRC_DP 10 50 #define FRC_OPT 11 51 #define FRC_SEC 12 52 #define FRC_ATH 13 53 #define FRC_ICT 14 54 #define FRC_ICC 15 55 #define FRC_MAX 16 56 57 58 static FILE *cfile = NULL; 59 60 /* 61 * This is called once per filter rule being loaded to emit data structures 62 * required. 63 */ 64 void 65 printc(frentry_t *fr) 66 { 67 u_long *ulp; 68 char *and; 69 FILE *fp; 70 int i; 71 72 if (fr->fr_family == 6) 73 return; 74 if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) 75 return; 76 if ((fr->fr_type == FR_T_IPF) && 77 ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL))) 78 return; 79 80 if (cfile == NULL) 81 cfile = fopen("ip_rules.c", "w"); 82 if (cfile == NULL) 83 return; 84 fp = cfile; 85 if (count == 0) { 86 fprintf(fp, "/*\n"); 87 fprintf(fp, "* Copyright (C) 2012 by Darren Reed.\n"); 88 fprintf(fp, "*\n"); 89 fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); 90 fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); 91 fprintf(fp, "* to the original author and the contributors.\n"); 92 fprintf(fp, "*/\n\n"); 93 94 fprintf(fp, "#include <sys/param.h>\n"); 95 fprintf(fp, "#include <sys/types.h>\n"); 96 fprintf(fp, "#include <sys/time.h>\n"); 97 fprintf(fp, "#include <sys/socket.h>\n"); 98 fprintf(fp, "#if (__FreeBSD_version >= 40000)\n"); 99 fprintf(fp, "# if defined(_KERNEL)\n"); 100 fprintf(fp, "# include <sys/libkern.h>\n"); 101 fprintf(fp, "# else\n"); 102 fprintf(fp, "# include <sys/unistd.h>\n"); 103 fprintf(fp, "# endif\n"); 104 fprintf(fp, "#endif\n"); 105 fprintf(fp, "#if (__NetBSD_Version__ >= 399000000)\n"); 106 fprintf(fp, "#else\n"); 107 fprintf(fp, "# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n"); 108 fprintf(fp, "# include <sys/systm.h>\n"); 109 fprintf(fp, "# endif\n"); 110 fprintf(fp, "#endif\n"); 111 fprintf(fp, "#include <sys/errno.h>\n"); 112 fprintf(fp, "#include <sys/param.h>\n"); 113 fprintf(fp, 114 "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n"); 115 fprintf(fp, "# include <sys/mbuf.h>\n"); 116 fprintf(fp, "#endif\n"); 117 fprintf(fp, 118 "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n"); 119 fprintf(fp, "# include <sys/sockio.h>\n"); 120 fprintf(fp, "#else\n"); 121 fprintf(fp, "# include <sys/ioctl.h>\n"); 122 fprintf(fp, "#endif /* FreeBSD */\n"); 123 fprintf(fp, "#include <net/if.h>\n"); 124 fprintf(fp, "#include <netinet/in.h>\n"); 125 fprintf(fp, "#include <netinet/in_systm.h>\n"); 126 fprintf(fp, "#include <netinet/ip.h>\n"); 127 fprintf(fp, "#include <netinet/tcp.h>\n"); 128 fprintf(fp, "#include \"netinet/ip_compat.h\"\n"); 129 fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n"); 130 fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n"); 131 fprintf(fp, "#ifndef _KERNEL\n"); 132 fprintf(fp, "# include <string.h>\n"); 133 fprintf(fp, "#endif /* _KERNEL */\n"); 134 fprintf(fp, "\n"); 135 fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); 136 fprintf(fp, "\n"); 137 fprintf(fp, "extern ipf_main_softc_t ipfmain;\n"); 138 fprintf(fp, "\n"); 139 } 140 141 addrule(fp, fr); 142 fr->fr_type |= FR_T_BUILTIN; 143 and = ""; 144 fr->fr_ref = 1; 145 i = sizeof(*fr); 146 if (i & -(1 - sizeof(*ulp))) 147 i += sizeof(u_long); 148 for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) { 149 fprintf(fp, "%s%#lx", and, *ulp++); 150 and = ", "; 151 } 152 fprintf(fp, "\n};\n"); 153 fr->fr_type &= ~FR_T_BUILTIN; 154 155 count++; 156 157 fflush(fp); 158 } 159 160 161 static frgroup_t *groups = NULL; 162 163 164 static void 165 addrule(FILE *fp, frentry_t *fr) 166 { 167 frentry_t *f, **fpp; 168 frgroup_t *g; 169 u_long *ulp; 170 char *ghead; 171 char *gname; 172 char *and; 173 int i; 174 175 f = (frentry_t *)malloc(sizeof(*f)); 176 bcopy((char *)fr, (char *)f, sizeof(*fr)); 177 if (fr->fr_ipf) { 178 f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf)); 179 bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf, 180 sizeof(*fr->fr_ipf)); 181 } 182 183 f->fr_next = NULL; 184 gname = FR_NAME(fr, fr_group); 185 186 for (g = groups; g != NULL; g = g->fg_next) 187 if ((strncmp(g->fg_name, gname, FR_GROUPLEN) == 0) && 188 (g->fg_flags == (f->fr_flags & FR_INOUT))) 189 break; 190 191 if (g == NULL) { 192 g = (frgroup_t *)calloc(1, sizeof(*g)); 193 g->fg_next = groups; 194 groups = g; 195 g->fg_head = f; 196 strncpy(g->fg_name, gname, FR_GROUPLEN); 197 g->fg_ref = 0; 198 g->fg_flags = f->fr_flags & FR_INOUT; 199 } 200 201 for (fpp = &g->fg_start; *fpp != NULL; ) 202 fpp = &((*fpp)->fr_next); 203 *fpp = f; 204 205 if (fr->fr_dsize > 0) { 206 fprintf(fp, "\ 207 static u_long ipf%s_rule_data_%s_%u[] = {\n", 208 f->fr_flags & FR_INQUE ? "in" : "out", 209 g->fg_name, g->fg_ref); 210 and = ""; 211 i = fr->fr_dsize; 212 ulp = fr->fr_data; 213 for (i /= sizeof(u_long); i > 0; i--) { 214 fprintf(fp, "%s%#lx", and, *ulp++); 215 and = ", "; 216 } 217 fprintf(fp, "\n};\n"); 218 } 219 220 fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n", 221 f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); 222 223 g->fg_ref++; 224 225 if (f->fr_grhead != -1) { 226 ghead = FR_NAME(f, fr_grhead); 227 for (g = groups; g != NULL; g = g->fg_next) 228 if ((strncmp(g->fg_name, ghead, FR_GROUPLEN) == 0) && 229 g->fg_flags == (f->fr_flags & FR_INOUT)) 230 break; 231 if (g == NULL) { 232 g = (frgroup_t *)calloc(1, sizeof(*g)); 233 g->fg_next = groups; 234 groups = g; 235 g->fg_head = f; 236 strncpy(g->fg_name, ghead, FR_GROUPLEN); 237 g->fg_ref = 0; 238 g->fg_flags = f->fr_flags & FR_INOUT; 239 } 240 } 241 } 242 243 244 int 245 intcmp(const void *c1, const void *c2) 246 { 247 const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; 248 249 if (i1->n == i2->n) { 250 return (i1->c - i2->c); 251 } 252 return (i2->n - i1->n); 253 } 254 255 256 static void 257 indent(FILE *fp, int in) 258 { 259 for (; in; in--) 260 fputc('\t', fp); 261 } 262 263 static void 264 printeq(FILE *fp, char *var, int m, int max, int v) 265 { 266 if (m == max) 267 fprintf(fp, "%s == %#x) {\n", var, v); 268 else 269 fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v); 270 } 271 272 /* 273 * Parameters: var - IP# being compared 274 * fl - 0 for positive match, 1 for negative match 275 * m - netmask 276 * v - required address 277 */ 278 static void 279 printipeq(FILE *fp, char *var, int fl, int m, int v) 280 { 281 if (m == 0xffffffff) 282 fprintf(fp, "%s ", var); 283 else 284 fprintf(fp, "(%s & %#x) ", var, m); 285 fprintf(fp, "%c", fl ? '!' : '='); 286 fprintf(fp, "= %#x) {\n", v); 287 } 288 289 290 void 291 emit(int num, int dir, void *v, frentry_t *fr) 292 { 293 u_int incnt, outcnt; 294 frgroup_t *g; 295 frentry_t *f; 296 297 for (g = groups; g != NULL; g = g->fg_next) { 298 if (dir == 0 || dir == -1) { 299 if ((g->fg_flags & FR_INQUE) == 0) 300 continue; 301 for (incnt = 0, f = g->fg_start; f != NULL; 302 f = f->fr_next) 303 incnt++; 304 emitGroup(num, dir, v, fr, g->fg_name, incnt, 0); 305 } 306 if (dir == 1 || dir == -1) { 307 if ((g->fg_flags & FR_OUTQUE) == 0) 308 continue; 309 for (outcnt = 0, f = g->fg_start; f != NULL; 310 f = f->fr_next) 311 outcnt++; 312 emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt); 313 } 314 } 315 316 if (num == -1 && dir == -1) { 317 for (g = groups; g != NULL; g = g->fg_next) { 318 if ((g->fg_flags & FR_INQUE) != 0) { 319 for (incnt = 0, f = g->fg_start; f != NULL; 320 f = f->fr_next) 321 incnt++; 322 if (incnt > 0) 323 emitheader(g, incnt, 0); 324 } 325 if ((g->fg_flags & FR_OUTQUE) != 0) { 326 for (outcnt = 0, f = g->fg_start; f != NULL; 327 f = f->fr_next) 328 outcnt++; 329 if (outcnt > 0) 330 emitheader(g, 0, outcnt); 331 } 332 } 333 emittail(); 334 fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n"); 335 } 336 337 } 338 339 340 static void 341 emitheader(frgroup_t *grp, u_int incount, u_int outcount) 342 { 343 static FILE *fph = NULL; 344 frgroup_t *g; 345 346 if (fph == NULL) { 347 fph = fopen("ip_rules.h", "w"); 348 if (fph == NULL) 349 return; 350 351 fprintf(fph, "extern int ipfrule_add(void));\n"); 352 fprintf(fph, "extern int ipfrule_remove(void));\n"); 353 } 354 355 printhooks(cfile, incount, outcount, grp); 356 357 if (incount) { 358 fprintf(fph, "\n\ 359 extern frentry_t *ipfrule_match_in_%s(fr_info_t *, u_32_t *));\n\ 360 extern frentry_t *ipf_rules_in_%s[%d];\n", 361 grp->fg_name, grp->fg_name, incount); 362 363 for (g = groups; g != grp; g = g->fg_next) 364 if ((strncmp(g->fg_name, grp->fg_name, 365 FR_GROUPLEN) == 0) && 366 g->fg_flags == grp->fg_flags) 367 break; 368 if (g == grp) { 369 fprintf(fph, "\n\ 370 extern int ipfrule_add_in_%s(void));\n\ 371 extern int ipfrule_remove_in_%s(void));\n", grp->fg_name, grp->fg_name); 372 } 373 } 374 if (outcount) { 375 fprintf(fph, "\n\ 376 extern frentry_t *ipfrule_match_out_%s(fr_info_t *, u_32_t *));\n\ 377 extern frentry_t *ipf_rules_out_%s[%d];\n", 378 grp->fg_name, grp->fg_name, outcount); 379 380 for (g = groups; g != grp; g = g->fg_next) 381 if ((strncmp(g->fg_name, grp->fg_name, 382 FR_GROUPLEN) == 0) && 383 g->fg_flags == grp->fg_flags) 384 break; 385 if (g == grp) { 386 fprintf(fph, "\n\ 387 extern int ipfrule_add_out_%s(void));\n\ 388 extern int ipfrule_remove_out_%s(void));\n", 389 grp->fg_name, grp->fg_name); 390 } 391 } 392 } 393 394 static void 395 emittail(void) 396 { 397 frgroup_t *g; 398 399 fprintf(cfile, "\n\ 400 int ipfrule_add()\n\ 401 {\n\ 402 int err;\n\ 403 \n"); 404 for (g = groups; g != NULL; g = g->fg_next) 405 fprintf(cfile, "\ 406 err = ipfrule_add_%s_%s();\n\ 407 if (err != 0)\n\ 408 return (err);\n", 409 (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 410 fprintf(cfile, "\ 411 return (0);\n"); 412 fprintf(cfile, "}\n\ 413 \n"); 414 415 fprintf(cfile, "\n\ 416 int ipfrule_remove()\n\ 417 {\n\ 418 int err;\n\ 419 \n"); 420 for (g = groups; g != NULL; g = g->fg_next) 421 fprintf(cfile, "\ 422 err = ipfrule_remove_%s_%s();\n\ 423 if (err != 0)\n\ 424 return (err);\n", 425 (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 426 fprintf(cfile, "\ 427 return (0);\n"); 428 fprintf(cfile, "}\n"); 429 } 430 431 432 static void 433 emitGroup(int num, int dir, void *v, frentry_t *fr, char *group, 434 u_int incount, u_int outcount) 435 { 436 static FILE *fp = NULL; 437 static int header[2] = { 0, 0 }; 438 static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 439 static int openfunc = 0; 440 static mc_t *n = NULL; 441 static int sin = 0; 442 frentry_t *f; 443 frgroup_t *g; 444 fripf_t *ipf; 445 int i, in, j; 446 mc_t *m = v; 447 448 if (fp == NULL) 449 fp = cfile; 450 if (fp == NULL) 451 return; 452 if (strncmp(egroup, group, FR_GROUPLEN)) { 453 for (sin--; sin > 0; sin--) { 454 indent(fp, sin); 455 fprintf(fp, "}\n"); 456 } 457 if (openfunc == 1) { 458 fprintf(fp, "\treturn (fr);\n}\n"); 459 openfunc = 0; 460 if (n != NULL) { 461 free(n); 462 n = NULL; 463 } 464 } 465 sin = 0; 466 header[0] = 0; 467 header[1] = 0; 468 strncpy(egroup, group, FR_GROUPLEN); 469 } else if (openfunc == 1 && num < 0) { 470 if (n != NULL) { 471 free(n); 472 n = NULL; 473 } 474 for (sin--; sin > 0; sin--) { 475 indent(fp, sin); 476 fprintf(fp, "}\n"); 477 } 478 if (openfunc == 1) { 479 fprintf(fp, "\treturn (fr);\n}\n"); 480 openfunc = 0; 481 } 482 } 483 484 if (dir == -1) 485 return; 486 487 for (g = groups; g != NULL; g = g->fg_next) { 488 if (dir == 0 && (g->fg_flags & FR_INQUE) == 0) 489 continue; 490 else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0) 491 continue; 492 if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0) 493 continue; 494 break; 495 } 496 497 /* 498 * Output the array of pointers to rules for this group. 499 */ 500 if (g != NULL && num == -2 && dir == 0 && header[0] == 0 && 501 incount != 0) { 502 fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {", 503 group, incount); 504 for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 505 if ((f->fr_flags & FR_INQUE) == 0) 506 continue; 507 if ((i & 1) == 0) { 508 fprintf(fp, "\n\t"); 509 } 510 fprintf(fp, "(frentry_t *)&in_rule_%s_%d", 511 FR_NAME(f, fr_group), i); 512 if (i + 1 < incount) 513 fprintf(fp, ", "); 514 i++; 515 } 516 fprintf(fp, "\n};\n"); 517 } 518 519 if (g != NULL && num == -2 && dir == 1 && header[0] == 0 && 520 outcount != 0) { 521 fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {", 522 group, outcount); 523 for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 524 if ((f->fr_flags & FR_OUTQUE) == 0) 525 continue; 526 if ((i & 1) == 0) { 527 fprintf(fp, "\n\t"); 528 } 529 fprintf(fp, "(frentry_t *)&out_rule_%s_%d", 530 FR_NAME(f, fr_group), i); 531 if (i + 1 < outcount) 532 fprintf(fp, ", "); 533 i++; 534 } 535 fprintf(fp, "\n};\n"); 536 fp = NULL; 537 } 538 539 if (num < 0) 540 return; 541 542 in = 0; 543 ipf = fr->fr_ipf; 544 545 /* 546 * If the function header has not been printed then print it now. 547 */ 548 if (g != NULL && header[dir] == 0) { 549 int pdst = 0, psrc = 0; 550 551 openfunc = 1; 552 fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n", 553 (dir == 0) ? "in" : "out", group); 554 fprintf(fp, "fr_info_t *fin;\n"); 555 fprintf(fp, "u_32_t *passp;\n"); 556 fprintf(fp, "{\n"); 557 fprintf(fp, "\tfrentry_t *fr = NULL;\n"); 558 559 /* 560 * Print out any variables that need to be declared. 561 */ 562 for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 563 if (incount + outcount > m[FRC_SRC].e + 1) 564 psrc = 1; 565 if (incount + outcount > m[FRC_DST].e + 1) 566 pdst = 1; 567 } 568 if (psrc == 1) 569 fprintf(fp, "\tu_32_t src = ntohl(%s);\n", 570 "fin->fin_fi.fi_saddr"); 571 if (pdst == 1) 572 fprintf(fp, "\tu_32_t dst = ntohl(%s);\n", 573 "fin->fin_fi.fi_daddr"); 574 } 575 576 for (i = 0; i < FRC_MAX; i++) { 577 switch(m[i].c) 578 { 579 case FRC_IFN : 580 if (fr->fr_ifnames[0] != -1) 581 m[i].s = 1; 582 break; 583 case FRC_V : 584 if (ipf != NULL && ipf->fri_mip.fi_v != 0) 585 m[i].s = 1; 586 break; 587 case FRC_FL : 588 if (ipf != NULL && ipf->fri_mip.fi_flx != 0) 589 m[i].s = 1; 590 break; 591 case FRC_P : 592 if (ipf != NULL && ipf->fri_mip.fi_p != 0) 593 m[i].s = 1; 594 break; 595 case FRC_TTL : 596 if (ipf != NULL && ipf->fri_mip.fi_ttl != 0) 597 m[i].s = 1; 598 break; 599 case FRC_TOS : 600 if (ipf != NULL && ipf->fri_mip.fi_tos != 0) 601 m[i].s = 1; 602 break; 603 case FRC_TCP : 604 if (ipf == NULL) 605 break; 606 if ((ipf->fri_ip.fi_p == IPPROTO_TCP) && 607 fr->fr_tcpfm != 0) 608 m[i].s = 1; 609 break; 610 case FRC_SP : 611 if (ipf == NULL) 612 break; 613 if (fr->fr_scmp == FR_INRANGE) 614 m[i].s = 1; 615 else if (fr->fr_scmp == FR_OUTRANGE) 616 m[i].s = 1; 617 else if (fr->fr_scmp != 0) 618 m[i].s = 1; 619 break; 620 case FRC_DP : 621 if (ipf == NULL) 622 break; 623 if (fr->fr_dcmp == FR_INRANGE) 624 m[i].s = 1; 625 else if (fr->fr_dcmp == FR_OUTRANGE) 626 m[i].s = 1; 627 else if (fr->fr_dcmp != 0) 628 m[i].s = 1; 629 break; 630 case FRC_SRC : 631 if (ipf == NULL) 632 break; 633 if (fr->fr_satype == FRI_LOOKUP) { 634 ; 635 } else if ((fr->fr_smask != 0) || 636 (fr->fr_flags & FR_NOTSRCIP) != 0) 637 m[i].s = 1; 638 break; 639 case FRC_DST : 640 if (ipf == NULL) 641 break; 642 if (fr->fr_datype == FRI_LOOKUP) { 643 ; 644 } else if ((fr->fr_dmask != 0) || 645 (fr->fr_flags & FR_NOTDSTIP) != 0) 646 m[i].s = 1; 647 break; 648 case FRC_OPT : 649 if (ipf == NULL) 650 break; 651 if (fr->fr_optmask != 0) 652 m[i].s = 1; 653 break; 654 case FRC_SEC : 655 if (ipf == NULL) 656 break; 657 if (fr->fr_secmask != 0) 658 m[i].s = 1; 659 break; 660 case FRC_ATH : 661 if (ipf == NULL) 662 break; 663 if (fr->fr_authmask != 0) 664 m[i].s = 1; 665 break; 666 case FRC_ICT : 667 if (ipf == NULL) 668 break; 669 if ((fr->fr_icmpm & 0xff00) != 0) 670 m[i].s = 1; 671 break; 672 case FRC_ICC : 673 if (ipf == NULL) 674 break; 675 if ((fr->fr_icmpm & 0xff) != 0) 676 m[i].s = 1; 677 break; 678 } 679 } 680 681 if (!header[dir]) { 682 fprintf(fp, "\n"); 683 header[dir] = 1; 684 sin = 0; 685 } 686 687 qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 688 689 if (n) { 690 /* 691 * Calculate the indentation interval upto the last common 692 * common comparison being made. 693 */ 694 for (i = 0, in = 1; i < FRC_MAX; i++) { 695 if (n[i].c != m[i].c) 696 break; 697 if (n[i].s != m[i].s) 698 break; 699 if (n[i].s) { 700 if (n[i].n && (n[i].n > n[i].e)) { 701 m[i].p++; 702 in += m[i].p; 703 break; 704 } 705 if (n[i].e > 0) { 706 in++; 707 } else 708 break; 709 } 710 } 711 if (sin != in) { 712 for (j = sin - 1; j >= in; j--) { 713 indent(fp, j); 714 fprintf(fp, "}\n"); 715 } 716 } 717 } else { 718 in = 1; 719 i = 0; 720 } 721 722 /* 723 * print out C code that implements a filter rule. 724 */ 725 for (; i < FRC_MAX; i++) { 726 switch(m[i].c) 727 { 728 case FRC_IFN : 729 if (m[i].s) { 730 indent(fp, in); 731 fprintf(fp, "if (fin->fin_ifp == "); 732 fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n", 733 dir ? "out" : "in", group, num); 734 in++; 735 } 736 break; 737 case FRC_V : 738 if (m[i].s) { 739 indent(fp, in); 740 fprintf(fp, "if (fin->fin_v == %d) {\n", 741 ipf->fri_ip.fi_v); 742 in++; 743 } 744 break; 745 case FRC_FL : 746 if (m[i].s) { 747 indent(fp, in); 748 fprintf(fp, "if ("); 749 printeq(fp, "fin->fin_flx", 750 ipf->fri_mip.fi_flx, 0xf, 751 ipf->fri_ip.fi_flx); 752 in++; 753 } 754 break; 755 case FRC_P : 756 if (m[i].s) { 757 indent(fp, in); 758 fprintf(fp, "if (fin->fin_p == %d) {\n", 759 ipf->fri_ip.fi_p); 760 in++; 761 } 762 break; 763 case FRC_TTL : 764 if (m[i].s) { 765 indent(fp, in); 766 fprintf(fp, "if ("); 767 printeq(fp, "fin->fin_ttl", 768 ipf->fri_mip.fi_ttl, 0xff, 769 ipf->fri_ip.fi_ttl); 770 in++; 771 } 772 break; 773 case FRC_TOS : 774 if (m[i].s) { 775 indent(fp, in); 776 fprintf(fp, "if (fin->fin_tos"); 777 printeq(fp, "fin->fin_tos", 778 ipf->fri_mip.fi_tos, 0xff, 779 ipf->fri_ip.fi_tos); 780 in++; 781 } 782 break; 783 case FRC_TCP : 784 if (m[i].s) { 785 indent(fp, in); 786 fprintf(fp, "if ("); 787 printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm, 788 0xff, fr->fr_tcpf); 789 in++; 790 } 791 break; 792 case FRC_SP : 793 if (!m[i].s) 794 break; 795 if (fr->fr_scmp == FR_INRANGE) { 796 indent(fp, in); 797 fprintf(fp, "if ((fin->fin_data[0] > %d) && ", 798 fr->fr_sport); 799 fprintf(fp, "(fin->fin_data[0] < %d)", 800 fr->fr_stop); 801 fprintf(fp, ") {\n"); 802 in++; 803 } else if (fr->fr_scmp == FR_OUTRANGE) { 804 indent(fp, in); 805 fprintf(fp, "if ((fin->fin_data[0] < %d) || ", 806 fr->fr_sport); 807 fprintf(fp, "(fin->fin_data[0] > %d)", 808 fr->fr_stop); 809 fprintf(fp, ") {\n"); 810 in++; 811 } else if (fr->fr_scmp) { 812 indent(fp, in); 813 fprintf(fp, "if (fin->fin_data[0] %s %d)", 814 portcmp[fr->fr_scmp], fr->fr_sport); 815 fprintf(fp, " {\n"); 816 in++; 817 } 818 break; 819 case FRC_DP : 820 if (!m[i].s) 821 break; 822 if (fr->fr_dcmp == FR_INRANGE) { 823 indent(fp, in); 824 fprintf(fp, "if ((fin->fin_data[1] > %d) && ", 825 fr->fr_dport); 826 fprintf(fp, "(fin->fin_data[1] < %d)", 827 fr->fr_dtop); 828 fprintf(fp, ") {\n"); 829 in++; 830 } else if (fr->fr_dcmp == FR_OUTRANGE) { 831 indent(fp, in); 832 fprintf(fp, "if ((fin->fin_data[1] < %d) || ", 833 fr->fr_dport); 834 fprintf(fp, "(fin->fin_data[1] > %d)", 835 fr->fr_dtop); 836 fprintf(fp, ") {\n"); 837 in++; 838 } else if (fr->fr_dcmp) { 839 indent(fp, in); 840 fprintf(fp, "if (fin->fin_data[1] %s %d)", 841 portcmp[fr->fr_dcmp], fr->fr_dport); 842 fprintf(fp, " {\n"); 843 in++; 844 } 845 break; 846 case FRC_SRC : 847 if (!m[i].s) 848 break; 849 if (fr->fr_satype == FRI_LOOKUP) { 850 ; 851 } else if ((fr->fr_smask != 0) || 852 (fr->fr_flags & FR_NOTSRCIP) != 0) { 853 indent(fp, in); 854 fprintf(fp, "if ("); 855 printipeq(fp, "src", 856 fr->fr_flags & FR_NOTSRCIP, 857 fr->fr_smask, fr->fr_saddr); 858 in++; 859 } 860 break; 861 case FRC_DST : 862 if (!m[i].s) 863 break; 864 if (fr->fr_datype == FRI_LOOKUP) { 865 ; 866 } else if ((fr->fr_dmask != 0) || 867 (fr->fr_flags & FR_NOTDSTIP) != 0) { 868 indent(fp, in); 869 fprintf(fp, "if ("); 870 printipeq(fp, "dst", 871 fr->fr_flags & FR_NOTDSTIP, 872 fr->fr_dmask, fr->fr_daddr); 873 in++; 874 } 875 break; 876 case FRC_OPT : 877 if (m[i].s) { 878 indent(fp, in); 879 fprintf(fp, "if ("); 880 printeq(fp, "fin->fin_fi.fi_optmsk", 881 fr->fr_optmask, 0xffffffff, 882 fr->fr_optbits); 883 in++; 884 } 885 break; 886 case FRC_SEC : 887 if (m[i].s) { 888 indent(fp, in); 889 fprintf(fp, "if ("); 890 printeq(fp, "fin->fin_fi.fi_secmsk", 891 fr->fr_secmask, 0xffff, 892 fr->fr_secbits); 893 in++; 894 } 895 break; 896 case FRC_ATH : 897 if (m[i].s) { 898 indent(fp, in); 899 fprintf(fp, "if ("); 900 printeq(fp, "fin->fin_fi.fi_authmsk", 901 fr->fr_authmask, 0xffff, 902 fr->fr_authbits); 903 in++; 904 } 905 break; 906 case FRC_ICT : 907 if (m[i].s) { 908 indent(fp, in); 909 fprintf(fp, "if ("); 910 printeq(fp, "fin->fin_data[0]", 911 fr->fr_icmpm & 0xff00, 0xffff, 912 fr->fr_icmp & 0xff00); 913 in++; 914 } 915 break; 916 case FRC_ICC : 917 if (m[i].s) { 918 indent(fp, in); 919 fprintf(fp, "if ("); 920 printeq(fp, "fin->fin_data[0]", 921 fr->fr_icmpm & 0xff, 0xffff, 922 fr->fr_icmp & 0xff); 923 in++; 924 } 925 break; 926 } 927 928 } 929 930 indent(fp, in); 931 if (fr->fr_flags & FR_QUICK) { 932 fprintf(fp, "return ((frentry_t *)&%s_rule_%s_%d);\n", 933 fr->fr_flags & FR_INQUE ? "in" : "out", 934 FR_NAME(fr, fr_group), num); 935 } else { 936 fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", 937 fr->fr_flags & FR_INQUE ? "in" : "out", 938 FR_NAME(fr, fr_group), num); 939 } 940 if (n == NULL) 941 n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); 942 bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX); 943 sin = in; 944 } 945 946 947 void 948 printC(int dir) 949 { 950 static mc_t *m = NULL; 951 frgroup_t *g; 952 953 if (m == NULL) 954 m = (mc_t *)calloc(FRC_MAX, sizeof(*m)); 955 956 for (g = groups; g != NULL; g = g->fg_next) { 957 if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0)) 958 printCgroup(dir, g->fg_start, m, g->fg_name); 959 if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0)) 960 printCgroup(dir, g->fg_start, m, g->fg_name); 961 } 962 963 emit(-1, dir, m, NULL); 964 } 965 966 967 /* 968 * Now print out code to implement all of the rules. 969 */ 970 static void 971 printCgroup(int dir, frentry_t *top, mc_t *m, char *group) 972 { 973 frentry_t *fr, *fr1; 974 int i, n, rn; 975 u_int count; 976 977 for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) { 978 if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0)) 979 count++; 980 else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0)) 981 count++; 982 } 983 984 if (dir == 0) 985 emitGroup(-2, dir, m, fr1, group, count, 0); 986 else if (dir == 1) 987 emitGroup(-2, dir, m, fr1, group, 0, count); 988 989 /* 990 * Before printing each rule, check to see how many of its fields are 991 * matched by subsequent rules. 992 */ 993 for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) { 994 if (!dir && !(fr1->fr_flags & FR_INQUE)) 995 continue; 996 if (dir && !(fr1->fr_flags & FR_OUTQUE)) 997 continue; 998 n = 0xfffffff; 999 1000 for (i = 0; i < FRC_MAX; i++) 1001 m[i].e = 0; 1002 qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 1003 1004 for (i = 0; i < FRC_MAX; i++) { 1005 m[i].c = i; 1006 m[i].e = 0; 1007 m[i].n = 0; 1008 m[i].s = 0; 1009 } 1010 1011 for (fr = fr1->fr_next; fr; fr = fr->fr_next) { 1012 if (!dir && !(fr->fr_flags & FR_INQUE)) 1013 continue; 1014 if (dir && !(fr->fr_flags & FR_OUTQUE)) 1015 continue; 1016 1017 if ((n & 0x0001) && 1018 !strcmp(fr1->fr_names + fr1->fr_ifnames[0], 1019 fr->fr_names + fr->fr_ifnames[0])) { 1020 m[FRC_IFN].e++; 1021 m[FRC_IFN].n++; 1022 } else 1023 n &= ~0x0001; 1024 1025 if ((n & 0x0002) && (fr1->fr_family == fr->fr_family)) { 1026 m[FRC_V].e++; 1027 m[FRC_V].n++; 1028 } else 1029 n &= ~0x0002; 1030 1031 if ((n & 0x0004) && 1032 (fr->fr_type == fr1->fr_type) && 1033 (fr->fr_type == FR_T_IPF) && 1034 (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) && 1035 (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) { 1036 m[FRC_FL].e++; 1037 m[FRC_FL].n++; 1038 } else 1039 n &= ~0x0004; 1040 1041 if ((n & 0x0008) && 1042 (fr->fr_type == fr1->fr_type) && 1043 (fr->fr_type == FR_T_IPF) && 1044 (fr1->fr_proto == fr->fr_proto)) { 1045 m[FRC_P].e++; 1046 m[FRC_P].n++; 1047 } else 1048 n &= ~0x0008; 1049 1050 if ((n & 0x0010) && 1051 (fr->fr_type == fr1->fr_type) && 1052 (fr->fr_type == FR_T_IPF) && 1053 (fr1->fr_ttl == fr->fr_ttl)) { 1054 m[FRC_TTL].e++; 1055 m[FRC_TTL].n++; 1056 } else 1057 n &= ~0x0010; 1058 1059 if ((n & 0x0020) && 1060 (fr->fr_type == fr1->fr_type) && 1061 (fr->fr_type == FR_T_IPF) && 1062 (fr1->fr_tos == fr->fr_tos)) { 1063 m[FRC_TOS].e++; 1064 m[FRC_TOS].n++; 1065 } else 1066 n &= ~0x0020; 1067 1068 if ((n & 0x0040) && 1069 (fr->fr_type == fr1->fr_type) && 1070 (fr->fr_type == FR_T_IPF) && 1071 ((fr1->fr_tcpfm == fr->fr_tcpfm) && 1072 (fr1->fr_tcpf == fr->fr_tcpf))) { 1073 m[FRC_TCP].e++; 1074 m[FRC_TCP].n++; 1075 } else 1076 n &= ~0x0040; 1077 1078 if ((n & 0x0080) && 1079 (fr->fr_type == fr1->fr_type) && 1080 (fr->fr_type == FR_T_IPF) && 1081 ((fr1->fr_scmp == fr->fr_scmp) && 1082 (fr1->fr_stop == fr->fr_stop) && 1083 (fr1->fr_sport == fr->fr_sport))) { 1084 m[FRC_SP].e++; 1085 m[FRC_SP].n++; 1086 } else 1087 n &= ~0x0080; 1088 1089 if ((n & 0x0100) && 1090 (fr->fr_type == fr1->fr_type) && 1091 (fr->fr_type == FR_T_IPF) && 1092 ((fr1->fr_dcmp == fr->fr_dcmp) && 1093 (fr1->fr_dtop == fr->fr_dtop) && 1094 (fr1->fr_dport == fr->fr_dport))) { 1095 m[FRC_DP].e++; 1096 m[FRC_DP].n++; 1097 } else 1098 n &= ~0x0100; 1099 1100 if ((n & 0x0200) && 1101 (fr->fr_type == fr1->fr_type) && 1102 (fr->fr_type == FR_T_IPF) && 1103 ((fr1->fr_satype == FRI_LOOKUP) && 1104 (fr->fr_satype == FRI_LOOKUP) && 1105 (fr1->fr_srcnum == fr->fr_srcnum))) { 1106 m[FRC_SRC].e++; 1107 m[FRC_SRC].n++; 1108 } else if ((n & 0x0200) && 1109 (fr->fr_type == fr1->fr_type) && 1110 (fr->fr_type == FR_T_IPF) && 1111 (((fr1->fr_flags & FR_NOTSRCIP) == 1112 (fr->fr_flags & FR_NOTSRCIP)))) { 1113 if ((fr1->fr_smask == fr->fr_smask) && 1114 (fr1->fr_saddr == fr->fr_saddr)) 1115 m[FRC_SRC].e++; 1116 else 1117 n &= ~0x0200; 1118 if (fr1->fr_smask && 1119 (fr1->fr_saddr & fr1->fr_smask) == 1120 (fr->fr_saddr & fr1->fr_smask)) { 1121 m[FRC_SRC].n++; 1122 n |= 0x0200; 1123 } 1124 } else { 1125 n &= ~0x0200; 1126 } 1127 1128 if ((n & 0x0400) && 1129 (fr->fr_type == fr1->fr_type) && 1130 (fr->fr_type == FR_T_IPF) && 1131 ((fr1->fr_datype == FRI_LOOKUP) && 1132 (fr->fr_datype == FRI_LOOKUP) && 1133 (fr1->fr_dstnum == fr->fr_dstnum))) { 1134 m[FRC_DST].e++; 1135 m[FRC_DST].n++; 1136 } else if ((n & 0x0400) && 1137 (fr->fr_type == fr1->fr_type) && 1138 (fr->fr_type == FR_T_IPF) && 1139 (((fr1->fr_flags & FR_NOTDSTIP) == 1140 (fr->fr_flags & FR_NOTDSTIP)))) { 1141 if ((fr1->fr_dmask == fr->fr_dmask) && 1142 (fr1->fr_daddr == fr->fr_daddr)) 1143 m[FRC_DST].e++; 1144 else 1145 n &= ~0x0400; 1146 if (fr1->fr_dmask && 1147 (fr1->fr_daddr & fr1->fr_dmask) == 1148 (fr->fr_daddr & fr1->fr_dmask)) { 1149 m[FRC_DST].n++; 1150 n |= 0x0400; 1151 } 1152 } else { 1153 n &= ~0x0400; 1154 } 1155 1156 if ((n & 0x0800) && 1157 (fr->fr_type == fr1->fr_type) && 1158 (fr->fr_type == FR_T_IPF) && 1159 (fr1->fr_optmask == fr->fr_optmask) && 1160 (fr1->fr_optbits == fr->fr_optbits)) { 1161 m[FRC_OPT].e++; 1162 m[FRC_OPT].n++; 1163 } else 1164 n &= ~0x0800; 1165 1166 if ((n & 0x1000) && 1167 (fr->fr_type == fr1->fr_type) && 1168 (fr->fr_type == FR_T_IPF) && 1169 (fr1->fr_secmask == fr->fr_secmask) && 1170 (fr1->fr_secbits == fr->fr_secbits)) { 1171 m[FRC_SEC].e++; 1172 m[FRC_SEC].n++; 1173 } else 1174 n &= ~0x1000; 1175 1176 if ((n & 0x10000) && 1177 (fr->fr_type == fr1->fr_type) && 1178 (fr->fr_type == FR_T_IPF) && 1179 (fr1->fr_authmask == fr->fr_authmask) && 1180 (fr1->fr_authbits == fr->fr_authbits)) { 1181 m[FRC_ATH].e++; 1182 m[FRC_ATH].n++; 1183 } else 1184 n &= ~0x10000; 1185 1186 if ((n & 0x20000) && 1187 (fr->fr_type == fr1->fr_type) && 1188 (fr->fr_type == FR_T_IPF) && 1189 ((fr1->fr_icmpm & 0xff00) == 1190 (fr->fr_icmpm & 0xff00)) && 1191 ((fr1->fr_icmp & 0xff00) == 1192 (fr->fr_icmp & 0xff00))) { 1193 m[FRC_ICT].e++; 1194 m[FRC_ICT].n++; 1195 } else 1196 n &= ~0x20000; 1197 1198 if ((n & 0x40000) && 1199 (fr->fr_type == fr1->fr_type) && 1200 (fr->fr_type == FR_T_IPF) && 1201 ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) && 1202 ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) { 1203 m[FRC_ICC].e++; 1204 m[FRC_ICC].n++; 1205 } else 1206 n &= ~0x40000; 1207 } 1208 /*msort(m);*/ 1209 1210 if (dir == 0) 1211 emitGroup(rn, dir, m, fr1, group, count, 0); 1212 else if (dir == 1) 1213 emitGroup(rn, dir, m, fr1, group, 0, count); 1214 } 1215 } 1216 1217 static void 1218 printhooks(FILE *fp, int in, int out, frgroup_t *grp) 1219 { 1220 frentry_t *fr; 1221 char *group; 1222 int dogrp, i; 1223 char *instr; 1224 1225 group = grp->fg_name; 1226 dogrp = 0; 1227 1228 if (in && out) { 1229 fprintf(stderr, 1230 "printhooks called with both in and out set\n"); 1231 exit(1); 1232 } 1233 1234 if (in) { 1235 instr = "in"; 1236 } else if (out) { 1237 instr = "out"; 1238 } else { 1239 instr = "???"; 1240 } 1241 fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group); 1242 1243 fprintf(fp, "\ 1244 \n\ 1245 int ipfrule_add_%s_%s()\n", instr, group); 1246 fprintf(fp, "\ 1247 {\n\ 1248 int i, j, err = 0, max;\n\ 1249 frentry_t *fp;\n"); 1250 1251 if (dogrp) 1252 fprintf(fp, "\ 1253 frgroup_t *fg;\n"); 1254 1255 fprintf(fp, "\n"); 1256 1257 for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next) 1258 if (fr->fr_dsize > 0) { 1259 fprintf(fp, "\ 1260 ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n", 1261 instr, grp->fg_name, i, 1262 instr, grp->fg_name, i); 1263 } 1264 fprintf(fp, "\ 1265 max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\ 1266 for (i = 0; i < max; i++) {\n\ 1267 fp = ipf_rules_%s_%s[i];\n\ 1268 fp->fr_next = NULL;\n", instr, group, instr, group); 1269 1270 fprintf(fp, "\ 1271 for (j = i + 1; j < max; j++)\n\ 1272 if (strncmp(fp->fr_names + fp->fr_group,\n\ 1273 ipf_rules_%s_%s[j]->fr_names +\n\ 1274 ipf_rules_%s_%s[j]->fr_group,\n\ 1275 FR_GROUPLEN) == 0) {\n\ 1276 if (ipf_rules_%s_%s[j] != NULL)\n\ 1277 ipf_rules_%s_%s[j]->fr_pnext =\n\ 1278 &fp->fr_next;\n\ 1279 fp->fr_pnext = &ipf_rules_%s_%s[j];\n\ 1280 fp->fr_next = ipf_rules_%s_%s[j];\n\ 1281 break;\n\ 1282 }\n", instr, group, instr, group, instr, group, 1283 instr, group, instr, group, instr, group); 1284 if (dogrp) 1285 fprintf(fp, "\ 1286 \n\ 1287 if (fp->fr_grhead != -1) {\n\ 1288 fg = fr_addgroup(fp->fr_names + fp->fr_grhead,\n\ 1289 fp, FR_INQUE, IPL_LOGIPF, 0);\n\ 1290 if (fg != NULL)\n\ 1291 fp->fr_grp = &fg->fg_start;\n\ 1292 }\n"); 1293 fprintf(fp, "\ 1294 }\n\ 1295 \n\ 1296 fp = &ipfrule_%s_%s;\n", instr, group); 1297 fprintf(fp, "\ 1298 bzero((char *)fp, sizeof(*fp));\n\ 1299 fp->fr_type = FR_T_CALLFUNC_BUILTIN;\n\ 1300 fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ 1301 fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", 1302 (in != 0) ? "IN" : "OUT", instr, group); 1303 fprintf(fp, "\ 1304 fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n", 1305 instr, group); 1306 1307 fprintf(fp, "\ 1308 fp->fr_family = AF_INET;\n\ 1309 fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ 1310 err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,\n\ 1311 ipfmain.ipf_active, 0);\n", 1312 instr, group); 1313 fprintf(fp, "\treturn (err);\n}\n"); 1314 1315 fprintf(fp, "\n\n\ 1316 int ipfrule_remove_%s_%s()\n", instr, group); 1317 fprintf(fp, "\ 1318 {\n\ 1319 int err = 0, i;\n\ 1320 frentry_t *fp;\n\ 1321 \n\ 1322 /*\n\ 1323 * Try to remove the %sbound rule.\n", instr); 1324 1325 fprintf(fp, "\ 1326 */\n\ 1327 if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group); 1328 1329 fprintf(fp, "\ 1330 err = EBUSY;\n\ 1331 } else {\n"); 1332 1333 fprintf(fp, "\ 1334 i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\ 1335 for (; i >= 0; i--) {\n\ 1336 fp = ipf_rules_%s_%s[i];\n\ 1337 if (fp->fr_ref > 1) {\n\ 1338 err = EBUSY;\n\ 1339 break;\n\ 1340 }\n\ 1341 }\n\ 1342 }\n\ 1343 if (err == 0)\n\ 1344 err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,\n\ 1345 (caddr_t)&ipfrule_%s_%s,\n\ 1346 ipfmain.ipf_active, 0);\n", 1347 instr, group, instr, group, instr, group); 1348 fprintf(fp, "\ 1349 if (err)\n\ 1350 return (err);\n\ 1351 \n\n"); 1352 1353 fprintf(fp, "\treturn (err);\n}\n"); 1354 } 1355