PageRenderTime 25ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/freebsd/contrib/ipfilter/tools/ipfcomp.c

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