2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
6 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
7 * Use is subject to license terms.
8 * Copyright 2017 Gary Mills
23 static char *portcmp
[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" };
26 int intcmp
__P((const void *, const void *));
27 static void indent
__P((FILE *, int));
28 static void printeq
__P((FILE *, char *, int, int, int));
29 static void printipeq
__P((FILE *, char *, int, int, int));
30 static void addrule
__P((FILE *, frentry_t
*));
31 static void printhooks
__P((FILE *, int, int, frgroup_t
*));
32 static void emitheader
__P((frgroup_t
*, u_int
, u_int
));
33 static void emitGroup
__P((int, int, void *, frentry_t
*, char *,
35 static void emittail
__P((void));
36 static void printCgroup
__P((int, frentry_t
*, mc_t
*, char *));
57 static FILE *cfile
= NULL
;
60 * This is called once per filter rule being loaded to emit data structures
73 if ((fr
->fr_type
!= FR_T_IPF
) && (fr
->fr_type
!= FR_T_NONE
))
75 if ((fr
->fr_type
== FR_T_IPF
) &&
76 ((fr
->fr_datype
!= FRI_NORMAL
) || (fr
->fr_satype
!= FRI_NORMAL
)))
80 cfile
= fopen("ip_rules.c", "w");
86 fprintf(fp
, "* Copyright (C) 1993-2000 by Darren Reed.\n");
88 fprintf(fp
, "* Redistribution and use in source and binary forms are permitted\n");
89 fprintf(fp
, "* provided that this notice is preserved and due credit is given\n");
90 fprintf(fp
, "* to the original author and the contributors.\n");
91 fprintf(fp
, "*/\n\n");
93 fprintf(fp
, "#include <sys/types.h>\n");
94 fprintf(fp
, "#include <sys/time.h>\n");
95 fprintf(fp
, "#include <sys/socket.h>\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
, "#include <sys/errno.h>\n");
100 fprintf(fp
, "#include <sys/param.h>\n");
102 "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n");
103 fprintf(fp
, "# include <sys/mbuf.h>\n");
104 fprintf(fp
, "#endif\n");
106 "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n");
107 fprintf(fp
, "# include <sys/sockio.h>\n");
108 fprintf(fp
, "#else\n");
109 fprintf(fp
, "# include <sys/ioctl.h>\n");
110 fprintf(fp
, "#endif /* FreeBSD */\n");
111 fprintf(fp
, "#include <net/if.h>\n");
112 fprintf(fp
, "#include <netinet/in.h>\n");
113 fprintf(fp
, "#include <netinet/in_systm.h>\n");
114 fprintf(fp
, "#include <netinet/ip.h>\n");
115 fprintf(fp
, "#include <netinet/tcp.h>\n");
116 fprintf(fp
, "#include \"netinet/ip_compat.h\"\n");
117 fprintf(fp
, "#include \"netinet/ip_fil.h\"\n\n");
118 fprintf(fp
, "#include \"netinet/ip_rules.h\"\n\n");
119 fprintf(fp
, "#ifndef _KERNEL\n");
120 fprintf(fp
, "# include <string.h>\n");
121 fprintf(fp
, "#endif /* _KERNEL */\n");
123 fprintf(fp
, "#ifdef IPFILTER_COMPILED\n");
127 fr
->fr_type
|= FR_T_BUILTIN
;
131 if (i
& -(1 - sizeof(*ulp
)))
133 for (i
/= sizeof(u_long
), ulp
= (u_long
*)fr
; i
> 0; i
--) {
134 fprintf(fp
, "%s%#lx", and, *ulp
++);
137 fprintf(fp
, "\n};\n");
138 fr
->fr_type
&= ~FR_T_BUILTIN
;
146 static frgroup_t
*groups
= NULL
;
149 static void addrule(fp
, fr
)
159 f
= (frentry_t
*)malloc(sizeof(*f
));
161 fprintf(stderr
, "out of memory\n");
164 bcopy((char *)fr
, (char *)f
, sizeof(*fr
));
166 f
->fr_ipf
= (fripf_t
*)malloc(sizeof(*f
->fr_ipf
));
167 if (f
->fr_ipf
== NULL
) {
168 fprintf(stderr
, "out of memory\n");
171 bcopy((char *)fr
->fr_ipf
, (char *)f
->fr_ipf
,
172 sizeof(*fr
->fr_ipf
));
176 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
)
177 if ((strncmp(g
->fg_name
, f
->fr_group
, FR_GROUPLEN
) == 0) &&
178 (g
->fg_flags
== (f
->fr_flags
& FR_INOUT
)))
182 g
= (frgroup_t
*)calloc(1, sizeof(*g
));
184 fprintf(stderr
, "out of memory\n");
190 bcopy(f
->fr_group
, g
->fg_name
, FR_GROUPLEN
);
192 g
->fg_flags
= f
->fr_flags
& FR_INOUT
;
195 for (fpp
= &g
->fg_start
; *fpp
!= NULL
; )
196 fpp
= &((*fpp
)->fr_next
);
199 if (fr
->fr_dsize
> 0) {
201 static u_long ipf%s_rule_data_%s_%u[] = {\n",
202 f
->fr_flags
& FR_INQUE
? "in" : "out",
203 g
->fg_name
, g
->fg_ref
);
207 for (i
/= sizeof(u_long
); i
> 0; i
--) {
208 fprintf(fp
, "%s%#lx", and, *ulp
++);
211 fprintf(fp
, "\n};\n");
214 fprintf(fp
, "\nstatic u_long %s_rule_%s_%d[] = {\n",
215 f
->fr_flags
& FR_INQUE
? "in" : "out", g
->fg_name
, g
->fg_ref
);
219 if (f
->fr_grhead
!= 0) {
220 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
)
221 if ((strncmp(g
->fg_name
, f
->fr_grhead
,
222 FR_GROUPLEN
) == 0) &&
223 g
->fg_flags
== (f
->fr_flags
& FR_INOUT
))
226 g
= (frgroup_t
*)calloc(1, sizeof(*g
));
228 fprintf(stderr
, "out of memory\n");
234 bcopy(f
->fr_grhead
, g
->fg_name
, FR_GROUPLEN
);
236 g
->fg_flags
= f
->fr_flags
& FR_INOUT
;
245 const mc_t
*i1
= (const mc_t
*)c1
, *i2
= (const mc_t
*)c2
;
247 if (i1
->n
== i2
->n
) {
248 return i1
->c
- i2
->c
;
250 return i2
->n
- i1
->n
;
254 static void indent(fp
, in
)
262 static void printeq(fp
, var
, m
, max
, v
)
268 fprintf(fp
, "%s == %#x) {\n", var
, v
);
270 fprintf(fp
, "(%s & %#x) == %#x) {\n", var
, m
, v
);
274 * Parameters: var - IP# being compared
275 * fl - 0 for positive match, 1 for negative match
277 * v - required address
279 static void printipeq(fp
, var
, fl
, m
, v
)
285 fprintf(fp
, "%s ", var
);
287 fprintf(fp
, "(%s & %#x) ", var
, m
);
288 fprintf(fp
, "%c", fl
? '!' : '=');
289 fprintf(fp
, "= %#x) {\n", v
);
293 void emit(num
, dir
, v
, fr
)
302 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
) {
303 if (dir
== 0 || dir
== -1) {
304 if ((g
->fg_flags
& FR_INQUE
) == 0)
306 for (incnt
= 0, f
= g
->fg_start
; f
!= NULL
;
309 emitGroup(num
, dir
, v
, fr
, g
->fg_name
, incnt
, 0);
311 if (dir
== 1 || dir
== -1) {
312 if ((g
->fg_flags
& FR_OUTQUE
) == 0)
314 for (outcnt
= 0, f
= g
->fg_start
; f
!= NULL
;
317 emitGroup(num
, dir
, v
, fr
, g
->fg_name
, 0, outcnt
);
321 if (num
== -1 && dir
== -1) {
322 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
) {
323 if ((g
->fg_flags
& FR_INQUE
) != 0) {
324 for (incnt
= 0, f
= g
->fg_start
; f
!= NULL
;
328 emitheader(g
, incnt
, 0);
330 if ((g
->fg_flags
& FR_OUTQUE
) != 0) {
331 for (outcnt
= 0, f
= g
->fg_start
; f
!= NULL
;
335 emitheader(g
, 0, outcnt
);
339 fprintf(cfile
, "#endif /* IPFILTER_COMPILED */\n");
345 static void emitheader(grp
, incount
, outcount
)
347 u_int incount
, outcount
;
349 static FILE *fph
= NULL
;
353 fph
= fopen("ip_rules.h", "w");
357 fprintf(fph
, "extern int ipfrule_add __P((void));\n");
358 fprintf(fph
, "extern int ipfrule_remove __P((void));\n");
361 printhooks(cfile
, incount
, outcount
, grp
);
365 extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\
366 extern frentry_t *ipf_rules_in_%s[%d];\n",
367 grp
->fg_name
, grp
->fg_name
, incount
);
369 for (g
= groups
; g
!= grp
; g
= g
->fg_next
)
370 if ((strncmp(g
->fg_name
, grp
->fg_name
,
371 FR_GROUPLEN
) == 0) &&
372 g
->fg_flags
== grp
->fg_flags
)
376 extern int ipfrule_add_in_%s __P((void));\n\
377 extern int ipfrule_remove_in_%s __P((void));\n", grp
->fg_name
, grp
->fg_name
);
382 extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
383 extern frentry_t *ipf_rules_out_%s[%d];\n",
384 grp
->fg_name
, grp
->fg_name
, outcount
);
386 for (g
= groups
; g
!= grp
; g
= g
->fg_next
)
387 if ((strncmp(g
->fg_name
, grp
->fg_name
,
388 FR_GROUPLEN
) == 0) &&
389 g
->fg_flags
== grp
->fg_flags
)
393 extern int ipfrule_add_out_%s __P((void));\n\
394 extern int ipfrule_remove_out_%s __P((void));\n",
395 grp
->fg_name
, grp
->fg_name
);
400 static void emittail()
409 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
)
411 err = ipfrule_add_%s_%s();\n\
414 (g
->fg_flags
& FR_INQUE
) ? "in" : "out", g
->fg_name
);
421 int ipfrule_remove()\n\
425 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
)
427 err = ipfrule_remove_%s_%s();\n\
430 (g
->fg_flags
& FR_INQUE
) ? "in" : "out", g
->fg_name
);
433 fprintf(cfile
, "}\n");
437 static void emitGroup(num
, dir
, v
, fr
, group
, incount
, outcount
)
442 u_int incount
, outcount
;
444 static FILE *fp
= NULL
;
445 static int header
[2] = { 0, 0 };
446 static char egroup
[FR_GROUPLEN
] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
447 static int openfunc
= 0;
448 static mc_t
*n
= NULL
;
460 if (strncmp(egroup
, group
, FR_GROUPLEN
)) {
461 for (sin
--; sin
> 0; sin
--) {
466 fprintf(fp
, "\treturn fr;\n}\n");
476 strncpy(egroup
, group
, FR_GROUPLEN
);
477 } else if (openfunc
== 1 && num
< 0) {
482 for (sin
--; sin
> 0; sin
--) {
487 fprintf(fp
, "\treturn fr;\n}\n");
495 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
) {
496 if (dir
== 0 && (g
->fg_flags
& FR_INQUE
) == 0)
498 else if (dir
== 1 && (g
->fg_flags
& FR_OUTQUE
) == 0)
500 if (strncmp(g
->fg_name
, group
, FR_GROUPLEN
) != 0)
506 * Output the array of pointers to rules for this group.
508 if (num
== -2 && dir
== 0 && header
[0] == 0 && incount
!= 0) {
509 fprintf(fp
, "\nfrentry_t *ipf_rules_in_%s[%d] = {",
511 for (f
= g
->fg_start
, i
= 0; f
!= NULL
; f
= f
->fr_next
) {
512 if ((f
->fr_flags
& FR_INQUE
) == 0)
518 "(frentry_t *)&in_rule_%s_%d",
524 fprintf(fp
, "\n};\n");
527 if (num
== -2 && dir
== 1 && header
[1] == 0 && outcount
!= 0) {
528 fprintf(fp
, "\nfrentry_t *ipf_rules_out_%s[%d] = {",
530 for (f
= g
->fg_start
, i
= 0; f
!= NULL
; f
= f
->fr_next
) {
531 if ((f
->fr_flags
& FR_OUTQUE
) == 0)
537 "(frentry_t *)&out_rule_%s_%d",
539 if (i
+ 1 < outcount
)
543 fprintf(fp
, "\n};\n");
554 * If the function header has not been printed then print it now.
556 if (header
[dir
] == 0) {
557 int pdst
= 0, psrc
= 0;
560 fprintf(fp
, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n",
561 (dir
== 0) ? "in" : "out", group
);
562 fprintf(fp
, "fr_info_t *fin;\n");
563 fprintf(fp
, "u_32_t *passp;\n");
565 fprintf(fp
, "\tfrentry_t *fr = NULL;\n");
568 * Print out any variables that need to be declared.
570 for (f
= g
->fg_start
, i
= 0; f
!= NULL
; f
= f
->fr_next
) {
571 if (incount
+ outcount
> m
[FRC_SRC
].e
+ 1)
573 if (incount
+ outcount
> m
[FRC_DST
].e
+ 1)
577 fprintf(fp
, "\tu_32_t src = ntohl(%s);\n",
578 "fin->fin_fi.fi_saddr");
580 fprintf(fp
, "\tu_32_t dst = ntohl(%s);\n",
581 "fin->fin_fi.fi_daddr");
584 for (i
= 0; i
< FRC_MAX
; i
++) {
592 if (ipf
!= NULL
&& ipf
->fri_mip
.fi_v
!= 0)
596 if (ipf
!= NULL
&& ipf
->fri_mip
.fi_flx
!= 0)
600 if (ipf
!= NULL
&& ipf
->fri_mip
.fi_p
!= 0)
604 if (ipf
!= NULL
&& ipf
->fri_mip
.fi_ttl
!= 0)
608 if (ipf
!= NULL
&& ipf
->fri_mip
.fi_tos
!= 0)
614 if ((ipf
->fri_ip
.fi_p
== IPPROTO_TCP
) &&
621 if (fr
->fr_scmp
== FR_INRANGE
)
623 else if (fr
->fr_scmp
== FR_OUTRANGE
)
625 else if (fr
->fr_scmp
!= 0)
631 if (fr
->fr_dcmp
== FR_INRANGE
)
633 else if (fr
->fr_dcmp
== FR_OUTRANGE
)
635 else if (fr
->fr_dcmp
!= 0)
641 if (fr
->fr_satype
== FRI_LOOKUP
) {
643 } else if ((fr
->fr_smask
!= 0) ||
644 (fr
->fr_flags
& FR_NOTSRCIP
) != 0)
650 if (fr
->fr_datype
== FRI_LOOKUP
) {
652 } else if ((fr
->fr_dmask
!= 0) ||
653 (fr
->fr_flags
& FR_NOTDSTIP
) != 0)
659 if (fr
->fr_optmask
!= 0)
665 if (fr
->fr_secmask
!= 0)
671 if (fr
->fr_authmask
!= 0)
677 if ((fr
->fr_icmpm
& 0xff00) != 0)
683 if ((fr
->fr_icmpm
& 0xff) != 0)
695 qsort(m
, FRC_MAX
, sizeof(mc_t
), intcmp
);
699 * Calculate the indentation interval upto the last common
700 * common comparison being made.
702 for (i
= 0, in
= 1; i
< FRC_MAX
; i
++) {
703 if (n
[i
].c
!= m
[i
].c
)
705 if (n
[i
].s
!= m
[i
].s
)
708 if (n
[i
].n
&& (n
[i
].n
> n
[i
].e
)) {
720 for (j
= sin
- 1; j
>= in
; j
--) {
731 * print out C code that implements a filter rule.
733 for (; i
< FRC_MAX
; i
++) {
739 fprintf(fp
, "if (fin->fin_ifp == ");
740 fprintf(fp
, "ipf_rules_%s_%s[%d]->fr_ifa) {\n",
741 dir
? "out" : "in", group
, num
);
748 fprintf(fp
, "if (fin->fin_v == %d) {\n",
757 printeq(fp
, "fin->fin_flx",
758 ipf
->fri_mip
.fi_flx
, 0xf,
766 fprintf(fp
, "if (fin->fin_p == %d) {\n",
775 printeq(fp
, "fin->fin_ttl",
776 ipf
->fri_mip
.fi_ttl
, 0xff,
784 fprintf(fp
, "if (fin->fin_tos");
785 printeq(fp
, "fin->fin_tos",
786 ipf
->fri_mip
.fi_tos
, 0xff,
795 printeq(fp
, "fin->fin_tcpf", fr
->fr_tcpfm
,
803 if (fr
->fr_scmp
== FR_INRANGE
) {
805 fprintf(fp
, "if ((fin->fin_data[0] > %d) && ",
807 fprintf(fp
, "(fin->fin_data[0] < %d)",
809 fprintf(fp
, ") {\n");
811 } else if (fr
->fr_scmp
== FR_OUTRANGE
) {
813 fprintf(fp
, "if ((fin->fin_data[0] < %d) || ",
815 fprintf(fp
, "(fin->fin_data[0] > %d)",
817 fprintf(fp
, ") {\n");
819 } else if (fr
->fr_scmp
) {
821 fprintf(fp
, "if (fin->fin_data[0] %s %d)",
822 portcmp
[fr
->fr_scmp
], fr
->fr_sport
);
830 if (fr
->fr_dcmp
== FR_INRANGE
) {
832 fprintf(fp
, "if ((fin->fin_data[1] > %d) && ",
834 fprintf(fp
, "(fin->fin_data[1] < %d)",
836 fprintf(fp
, ") {\n");
838 } else if (fr
->fr_dcmp
== FR_OUTRANGE
) {
840 fprintf(fp
, "if ((fin->fin_data[1] < %d) || ",
842 fprintf(fp
, "(fin->fin_data[1] > %d)",
844 fprintf(fp
, ") {\n");
846 } else if (fr
->fr_dcmp
) {
848 fprintf(fp
, "if (fin->fin_data[1] %s %d)",
849 portcmp
[fr
->fr_dcmp
], fr
->fr_dport
);
857 if (fr
->fr_satype
== FRI_LOOKUP
) {
859 } else if ((fr
->fr_smask
!= 0) ||
860 (fr
->fr_flags
& FR_NOTSRCIP
) != 0) {
864 fr
->fr_flags
& FR_NOTSRCIP
,
865 fr
->fr_smask
, fr
->fr_saddr
);
872 if (fr
->fr_datype
== FRI_LOOKUP
) {
874 } else if ((fr
->fr_dmask
!= 0) ||
875 (fr
->fr_flags
& FR_NOTDSTIP
) != 0) {
879 fr
->fr_flags
& FR_NOTDSTIP
,
880 fr
->fr_dmask
, fr
->fr_daddr
);
888 printeq(fp
, "fin->fin_fi.fi_optmsk",
889 fr
->fr_optmask
, 0xffffffff,
898 printeq(fp
, "fin->fin_fi.fi_secmsk",
899 fr
->fr_secmask
, 0xffff,
908 printeq(fp
, "fin->fin_fi.fi_authmsk",
909 fr
->fr_authmask
, 0xffff,
918 printeq(fp
, "fin->fin_data[0]",
919 fr
->fr_icmpm
& 0xff00, 0xffff,
920 fr
->fr_icmp
& 0xff00);
928 printeq(fp
, "fin->fin_data[0]",
929 fr
->fr_icmpm
& 0xff, 0xffff,
939 if (fr
->fr_flags
& FR_QUICK
) {
940 fprintf(fp
, "return (frentry_t *)&%s_rule_%s_%d;\n",
941 fr
->fr_flags
& FR_INQUE
? "in" : "out",
944 fprintf(fp
, "fr = (frentry_t *)&%s_rule_%s_%d;\n",
945 fr
->fr_flags
& FR_INQUE
? "in" : "out",
949 n
= (mc_t
*)malloc(sizeof(*n
) * FRC_MAX
);
951 fprintf(stderr
, "out of memory\n");
955 bcopy((char *)m
, (char *)n
, sizeof(*n
) * FRC_MAX
);
963 static mc_t
*m
= NULL
;
967 m
= (mc_t
*)calloc(1, sizeof(*m
) * FRC_MAX
);
969 fprintf(stderr
, "out of memory\n");
974 for (g
= groups
; g
!= NULL
; g
= g
->fg_next
) {
975 if ((dir
== 0) && ((g
->fg_flags
& FR_INQUE
) != 0))
976 printCgroup(dir
, g
->fg_start
, m
, g
->fg_name
);
977 if ((dir
== 1) && ((g
->fg_flags
& FR_OUTQUE
) != 0))
978 printCgroup(dir
, g
->fg_start
, m
, g
->fg_name
);
981 emit(-1, dir
, m
, NULL
);
986 * Now print out code to implement all of the rules.
988 static void printCgroup(dir
, top
, m
, group
)
998 for (count
= 0, fr1
= top
; fr1
!= NULL
; fr1
= fr1
->fr_next
) {
999 if ((dir
== 0) && ((fr1
->fr_flags
& FR_INQUE
) != 0))
1001 else if ((dir
== 1) && ((fr1
->fr_flags
& FR_OUTQUE
) != 0))
1006 emitGroup(-2, dir
, m
, fr1
, group
, count
, 0);
1008 emitGroup(-2, dir
, m
, fr1
, group
, 0, count
);
1011 * Before printing each rule, check to see how many of its fields are
1012 * matched by subsequent rules.
1014 for (fr1
= top
, rn
= 0; fr1
!= NULL
; fr1
= fr1
->fr_next
, rn
++) {
1015 if (!dir
&& !(fr1
->fr_flags
& FR_INQUE
))
1017 if (dir
&& !(fr1
->fr_flags
& FR_OUTQUE
))
1021 for (i
= 0; i
< FRC_MAX
; i
++)
1023 qsort(m
, FRC_MAX
, sizeof(mc_t
), intcmp
);
1025 for (i
= 0; i
< FRC_MAX
; i
++) {
1032 for (fr
= fr1
->fr_next
; fr
; fr
= fr
->fr_next
) {
1033 if (!dir
&& !(fr
->fr_flags
& FR_INQUE
))
1035 if (dir
&& !(fr
->fr_flags
& FR_OUTQUE
))
1039 !strcmp(fr1
->fr_ifname
, fr
->fr_ifname
)) {
1045 if ((n
& 0x0002) && (fr1
->fr_v
== fr
->fr_v
)) {
1052 (fr
->fr_type
== fr1
->fr_type
) &&
1053 (fr
->fr_type
== FR_T_IPF
) &&
1054 (fr1
->fr_mip
.fi_flx
== fr
->fr_mip
.fi_flx
) &&
1055 (fr1
->fr_ip
.fi_flx
== fr
->fr_ip
.fi_flx
)) {
1062 (fr
->fr_type
== fr1
->fr_type
) &&
1063 (fr
->fr_type
== FR_T_IPF
) &&
1064 (fr1
->fr_proto
== fr
->fr_proto
)) {
1071 (fr
->fr_type
== fr1
->fr_type
) &&
1072 (fr
->fr_type
== FR_T_IPF
) &&
1073 (fr1
->fr_ttl
== fr
->fr_ttl
)) {
1080 (fr
->fr_type
== fr1
->fr_type
) &&
1081 (fr
->fr_type
== FR_T_IPF
) &&
1082 (fr1
->fr_tos
== fr
->fr_tos
)) {
1089 (fr
->fr_type
== fr1
->fr_type
) &&
1090 (fr
->fr_type
== FR_T_IPF
) &&
1091 ((fr1
->fr_tcpfm
== fr
->fr_tcpfm
) &&
1092 (fr1
->fr_tcpf
== fr
->fr_tcpf
))) {
1099 (fr
->fr_type
== fr1
->fr_type
) &&
1100 (fr
->fr_type
== FR_T_IPF
) &&
1101 ((fr1
->fr_scmp
== fr
->fr_scmp
) &&
1102 (fr1
->fr_stop
== fr
->fr_stop
) &&
1103 (fr1
->fr_sport
== fr
->fr_sport
))) {
1110 (fr
->fr_type
== fr1
->fr_type
) &&
1111 (fr
->fr_type
== FR_T_IPF
) &&
1112 ((fr1
->fr_dcmp
== fr
->fr_dcmp
) &&
1113 (fr1
->fr_dtop
== fr
->fr_dtop
) &&
1114 (fr1
->fr_dport
== fr
->fr_dport
))) {
1121 (fr
->fr_type
== fr1
->fr_type
) &&
1122 (fr
->fr_type
== FR_T_IPF
) &&
1123 ((fr1
->fr_satype
== FRI_LOOKUP
) &&
1124 (fr
->fr_satype
== FRI_LOOKUP
) &&
1125 (fr1
->fr_srcnum
== fr
->fr_srcnum
))) {
1128 } else if ((n
& 0x0200) &&
1129 (fr
->fr_type
== fr1
->fr_type
) &&
1130 (fr
->fr_type
== FR_T_IPF
) &&
1131 (((fr1
->fr_flags
& FR_NOTSRCIP
) ==
1132 (fr
->fr_flags
& FR_NOTSRCIP
)))) {
1133 if ((fr1
->fr_smask
== fr
->fr_smask
) &&
1134 (fr1
->fr_saddr
== fr
->fr_saddr
))
1138 if (fr1
->fr_smask
&&
1139 (fr1
->fr_saddr
& fr1
->fr_smask
) ==
1140 (fr
->fr_saddr
& fr1
->fr_smask
)) {
1149 (fr
->fr_type
== fr1
->fr_type
) &&
1150 (fr
->fr_type
== FR_T_IPF
) &&
1151 ((fr1
->fr_datype
== FRI_LOOKUP
) &&
1152 (fr
->fr_datype
== FRI_LOOKUP
) &&
1153 (fr1
->fr_dstnum
== fr
->fr_dstnum
))) {
1156 } else if ((n
& 0x0400) &&
1157 (fr
->fr_type
== fr1
->fr_type
) &&
1158 (fr
->fr_type
== FR_T_IPF
) &&
1159 (((fr1
->fr_flags
& FR_NOTDSTIP
) ==
1160 (fr
->fr_flags
& FR_NOTDSTIP
)))) {
1161 if ((fr1
->fr_dmask
== fr
->fr_dmask
) &&
1162 (fr1
->fr_daddr
== fr
->fr_daddr
))
1166 if (fr1
->fr_dmask
&&
1167 (fr1
->fr_daddr
& fr1
->fr_dmask
) ==
1168 (fr
->fr_daddr
& fr1
->fr_dmask
)) {
1177 (fr
->fr_type
== fr1
->fr_type
) &&
1178 (fr
->fr_type
== FR_T_IPF
) &&
1179 (fr1
->fr_optmask
== fr
->fr_optmask
) &&
1180 (fr1
->fr_optbits
== fr
->fr_optbits
)) {
1187 (fr
->fr_type
== fr1
->fr_type
) &&
1188 (fr
->fr_type
== FR_T_IPF
) &&
1189 (fr1
->fr_secmask
== fr
->fr_secmask
) &&
1190 (fr1
->fr_secbits
== fr
->fr_secbits
)) {
1196 if ((n
& 0x10000) &&
1197 (fr
->fr_type
== fr1
->fr_type
) &&
1198 (fr
->fr_type
== FR_T_IPF
) &&
1199 (fr1
->fr_authmask
== fr
->fr_authmask
) &&
1200 (fr1
->fr_authbits
== fr
->fr_authbits
)) {
1206 if ((n
& 0x20000) &&
1207 (fr
->fr_type
== fr1
->fr_type
) &&
1208 (fr
->fr_type
== FR_T_IPF
) &&
1209 ((fr1
->fr_icmpm
& 0xff00) ==
1210 (fr
->fr_icmpm
& 0xff00)) &&
1211 ((fr1
->fr_icmp
& 0xff00) ==
1212 (fr
->fr_icmp
& 0xff00))) {
1218 if ((n
& 0x40000) &&
1219 (fr
->fr_type
== fr1
->fr_type
) &&
1220 (fr
->fr_type
== FR_T_IPF
) &&
1221 ((fr1
->fr_icmpm
& 0xff) == (fr
->fr_icmpm
& 0xff)) &&
1222 ((fr1
->fr_icmp
& 0xff) == (fr
->fr_icmp
& 0xff))) {
1231 emitGroup(rn
, dir
, m
, fr1
, group
, count
, 0);
1233 emitGroup(rn
, dir
, m
, fr1
, group
, 0, count
);
1237 static void printhooks(fp
, in
, out
, grp
)
1248 group
= grp
->fg_name
;
1253 "printhooks called with both in and out set\n");
1264 fprintf(fp
, "static frentry_t ipfrule_%s_%s;\n", instr
, group
);
1268 int ipfrule_add_%s_%s()\n", instr
, group
);
1271 int i, j, err = 0, max;\n\
1280 for (i
= 0, fr
= grp
->fg_start
; fr
!= NULL
; i
++, fr
= fr
->fr_next
)
1281 if (fr
->fr_dsize
> 0) {
1283 ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n",
1284 instr
, grp
->fg_name
, i
,
1285 instr
, grp
->fg_name
, i
);
1288 max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\
1289 for (i = 0; i < max; i++) {\n\
1290 fp = ipf_rules_%s_%s[i];\n\
1291 fp->fr_next = NULL;\n", instr
, group
, instr
, group
);
1294 for (j = i + 1; j < max; j++)\n\
1295 if (strncmp(fp->fr_group,\n\
1296 ipf_rules_%s_%s[j]->fr_group,\n\
1297 FR_GROUPLEN) == 0) {\n\
1298 fp->fr_next = ipf_rules_%s_%s[j];\n\
1300 }\n", instr
, group
, instr
, group
);
1304 if (fp->fr_grhead != 0) {\n\
1305 fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\
1308 fp->fr_grp = &fg->fg_start;\n\
1313 fp = &ipfrule_%s_%s;\n", instr
, group
);
1315 bzero((char *)fp, sizeof(*fp));\n\
1316 fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\
1317 fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
1318 fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
1319 (in
!= 0) ? "IN" : "OUT", instr
, group
);
1321 fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n",
1326 fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\
1327 err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n",
1329 fprintf(fp
, "\treturn err;\n}\n");
1332 int ipfrule_remove_%s_%s()\n", instr
, group
);
1339 * Try to remove the %sbound rule.\n", instr
);
1343 if (ipfrule_%s_%s.fr_ref > 0) {\n", instr
, group
);
1350 i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\
1351 for (; i >= 0; i--) {\n\
1352 fp = ipf_rules_%s_%s[i];\n\
1353 if (fp->fr_ref > 1) {\n\
1360 err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\
1361 (caddr_t)&ipfrule_%s_%s, fr_active, 0);\n",
1362 instr
, group
, instr
, group
, instr
, group
);
1368 fprintf(fp
, "\treturn err;\n}\n");