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