17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate */ 67c478bd9Sstevel@tonic-gate #if !defined(lint) 77c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 8*ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.2 2004/04/28 10:34:44 darrenr Exp $"; 97c478bd9Sstevel@tonic-gate #endif 107c478bd9Sstevel@tonic-gate 117c478bd9Sstevel@tonic-gate #include "ipf.h" 127c478bd9Sstevel@tonic-gate 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate typedef struct { 157c478bd9Sstevel@tonic-gate int c; 167c478bd9Sstevel@tonic-gate int e; 177c478bd9Sstevel@tonic-gate int n; 187c478bd9Sstevel@tonic-gate int p; 197c478bd9Sstevel@tonic-gate int s; 207c478bd9Sstevel@tonic-gate } mc_t; 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" }; 247c478bd9Sstevel@tonic-gate static int count = 0; 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate int intcmp __P((const void *, const void *)); 277c478bd9Sstevel@tonic-gate static void indent __P((FILE *, int)); 287c478bd9Sstevel@tonic-gate static void printeq __P((FILE *, char *, int, int, int)); 297c478bd9Sstevel@tonic-gate static void printipeq __P((FILE *, char *, int, int, int)); 307c478bd9Sstevel@tonic-gate static void addrule __P((FILE *, frentry_t *)); 317c478bd9Sstevel@tonic-gate static void printhooks __P((FILE *, int, int, frgroup_t *)); 327c478bd9Sstevel@tonic-gate static void emitheader __P((frgroup_t *, u_int, u_int)); 337c478bd9Sstevel@tonic-gate static void emitGroup __P((int, int, void *, frentry_t *, char *, 347c478bd9Sstevel@tonic-gate u_int, u_int)); 357c478bd9Sstevel@tonic-gate static void emittail __P((void)); 367c478bd9Sstevel@tonic-gate static void printCgroup __P((int, frentry_t *, mc_t *, char *)); 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #define FRC_IFN 0 397c478bd9Sstevel@tonic-gate #define FRC_V 1 407c478bd9Sstevel@tonic-gate #define FRC_P 2 417c478bd9Sstevel@tonic-gate #define FRC_FL 3 427c478bd9Sstevel@tonic-gate #define FRC_TOS 4 437c478bd9Sstevel@tonic-gate #define FRC_TTL 5 447c478bd9Sstevel@tonic-gate #define FRC_SRC 6 457c478bd9Sstevel@tonic-gate #define FRC_DST 7 467c478bd9Sstevel@tonic-gate #define FRC_TCP 8 477c478bd9Sstevel@tonic-gate #define FRC_SP 9 487c478bd9Sstevel@tonic-gate #define FRC_DP 10 497c478bd9Sstevel@tonic-gate #define FRC_OPT 11 507c478bd9Sstevel@tonic-gate #define FRC_SEC 12 517c478bd9Sstevel@tonic-gate #define FRC_ATH 13 527c478bd9Sstevel@tonic-gate #define FRC_ICT 14 537c478bd9Sstevel@tonic-gate #define FRC_ICC 15 547c478bd9Sstevel@tonic-gate #define FRC_MAX 16 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static FILE *cfile = NULL; 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate /* 607c478bd9Sstevel@tonic-gate * This is called once per filter rule being loaded to emit data structures 617c478bd9Sstevel@tonic-gate * required. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate void printc(fr) 647c478bd9Sstevel@tonic-gate frentry_t *fr; 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate fripf_t *ipf; 677c478bd9Sstevel@tonic-gate u_long *ulp; 687c478bd9Sstevel@tonic-gate char *and; 697c478bd9Sstevel@tonic-gate FILE *fp; 707c478bd9Sstevel@tonic-gate int i; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate if (fr->fr_v != 4) 737c478bd9Sstevel@tonic-gate return; 747c478bd9Sstevel@tonic-gate if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) 757c478bd9Sstevel@tonic-gate return; 767c478bd9Sstevel@tonic-gate if ((fr->fr_type == FR_T_IPF) && 777c478bd9Sstevel@tonic-gate ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL))) 787c478bd9Sstevel@tonic-gate return; 797c478bd9Sstevel@tonic-gate ipf = fr->fr_ipf; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if (cfile == NULL) 827c478bd9Sstevel@tonic-gate cfile = fopen("ip_rules.c", "w"); 837c478bd9Sstevel@tonic-gate if (cfile == NULL) 847c478bd9Sstevel@tonic-gate return; 857c478bd9Sstevel@tonic-gate fp = cfile; 867c478bd9Sstevel@tonic-gate if (count == 0) { 877c478bd9Sstevel@tonic-gate fprintf(fp, "/*\n"); 887c478bd9Sstevel@tonic-gate fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n"); 897c478bd9Sstevel@tonic-gate fprintf(fp, "*\n"); 907c478bd9Sstevel@tonic-gate fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); 917c478bd9Sstevel@tonic-gate fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); 927c478bd9Sstevel@tonic-gate fprintf(fp, "* to the original author and the contributors.\n"); 937c478bd9Sstevel@tonic-gate fprintf(fp, "*/\n\n"); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate fprintf(fp, "#include <sys/types.h>\n"); 967c478bd9Sstevel@tonic-gate fprintf(fp, "#include <sys/time.h>\n"); 977c478bd9Sstevel@tonic-gate fprintf(fp, "#include <sys/socket.h>\n"); 98*ab25eeb5Syz fprintf(fp, "#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n"); 99*ab25eeb5Syz fprintf(fp, "# include <sys/systm.h>\n"); 100*ab25eeb5Syz fprintf(fp, "#endif\n"); 1017c478bd9Sstevel@tonic-gate fprintf(fp, "#include <sys/errno.h>\n"); 1027c478bd9Sstevel@tonic-gate fprintf(fp, "#include <sys/param.h>\n"); 1037c478bd9Sstevel@tonic-gate fprintf(fp, 1047c478bd9Sstevel@tonic-gate "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n"); 1057c478bd9Sstevel@tonic-gate fprintf(fp, "# include <sys/mbuf.h>\n"); 1067c478bd9Sstevel@tonic-gate fprintf(fp, "#endif\n"); 1077c478bd9Sstevel@tonic-gate fprintf(fp, 1087c478bd9Sstevel@tonic-gate "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n"); 1097c478bd9Sstevel@tonic-gate fprintf(fp, "# include <sys/sockio.h>\n"); 1107c478bd9Sstevel@tonic-gate fprintf(fp, "#else\n"); 1117c478bd9Sstevel@tonic-gate fprintf(fp, "# include <sys/ioctl.h>\n"); 1127c478bd9Sstevel@tonic-gate fprintf(fp, "#endif /* FreeBSD */\n"); 1137c478bd9Sstevel@tonic-gate fprintf(fp, "#include <net/if.h>\n"); 1147c478bd9Sstevel@tonic-gate fprintf(fp, "#include <netinet/in.h>\n"); 1157c478bd9Sstevel@tonic-gate fprintf(fp, "#include <netinet/in_systm.h>\n"); 1167c478bd9Sstevel@tonic-gate fprintf(fp, "#include <netinet/ip.h>\n"); 1177c478bd9Sstevel@tonic-gate fprintf(fp, "#include <netinet/tcp.h>\n"); 118*ab25eeb5Syz fprintf(fp, "#include \"netinet/ip_compat.h\"\n"); 119*ab25eeb5Syz fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n"); 120*ab25eeb5Syz fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n"); 121*ab25eeb5Syz fprintf(fp, "#ifndef _KERNEL\n"); 122*ab25eeb5Syz fprintf(fp, "# include <string.h>\n"); 123*ab25eeb5Syz fprintf(fp, "#endif /* _KERNEL */\n"); 124*ab25eeb5Syz fprintf(fp, "\n"); 125*ab25eeb5Syz fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate addrule(fp, fr); 1297c478bd9Sstevel@tonic-gate fr->fr_type |= FR_T_BUILTIN; 1307c478bd9Sstevel@tonic-gate and = ""; 1317c478bd9Sstevel@tonic-gate fr->fr_ref = 1; 1327c478bd9Sstevel@tonic-gate i = sizeof(*fr); 1337c478bd9Sstevel@tonic-gate if (i & -(1 - sizeof(*ulp))) 1347c478bd9Sstevel@tonic-gate i += sizeof(u_long); 1357c478bd9Sstevel@tonic-gate for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) { 1367c478bd9Sstevel@tonic-gate fprintf(fp, "%s%#lx", and, *ulp++); 1377c478bd9Sstevel@tonic-gate and = ", "; 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate fprintf(fp, "\n};\n"); 1407c478bd9Sstevel@tonic-gate fr->fr_type &= ~FR_T_BUILTIN; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate count++; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate fflush(fp); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate static frgroup_t *groups = NULL; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate static void addrule(fp, fr) 1527c478bd9Sstevel@tonic-gate FILE *fp; 1537c478bd9Sstevel@tonic-gate frentry_t *fr; 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate frentry_t *f, **fpp; 1567c478bd9Sstevel@tonic-gate frgroup_t *g; 1577c478bd9Sstevel@tonic-gate u_long *ulp; 1587c478bd9Sstevel@tonic-gate char *and; 1597c478bd9Sstevel@tonic-gate int i; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate f = (frentry_t *)malloc(sizeof(*f)); 1627c478bd9Sstevel@tonic-gate bcopy((char *)fr, (char *)f, sizeof(*fr)); 1637c478bd9Sstevel@tonic-gate if (fr->fr_ipf) { 1647c478bd9Sstevel@tonic-gate f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf)); 1657c478bd9Sstevel@tonic-gate bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf, 1667c478bd9Sstevel@tonic-gate sizeof(*fr->fr_ipf)); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate f->fr_next = NULL; 1707c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) 1717c478bd9Sstevel@tonic-gate if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) && 1727c478bd9Sstevel@tonic-gate (g->fg_flags == (f->fr_flags & FR_INOUT))) 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if (g == NULL) { 1767c478bd9Sstevel@tonic-gate g = (frgroup_t *)calloc(1, sizeof(*g)); 1777c478bd9Sstevel@tonic-gate g->fg_next = groups; 1787c478bd9Sstevel@tonic-gate groups = g; 1797c478bd9Sstevel@tonic-gate g->fg_head = f; 1807c478bd9Sstevel@tonic-gate bcopy(f->fr_group, g->fg_name, FR_GROUPLEN); 1817c478bd9Sstevel@tonic-gate g->fg_ref = 0; 1827c478bd9Sstevel@tonic-gate g->fg_flags = f->fr_flags & FR_INOUT; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate for (fpp = &g->fg_start; *fpp != NULL; ) 1867c478bd9Sstevel@tonic-gate fpp = &((*fpp)->fr_next); 1877c478bd9Sstevel@tonic-gate *fpp = f; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate if (fr->fr_dsize > 0) { 1907c478bd9Sstevel@tonic-gate fprintf(fp, "\ 1917c478bd9Sstevel@tonic-gate static u_long ipf%s_rule_data_%s_%u[] = {\n", 1927c478bd9Sstevel@tonic-gate f->fr_flags & FR_INQUE ? "in" : "out", 1937c478bd9Sstevel@tonic-gate g->fg_name, g->fg_ref); 1947c478bd9Sstevel@tonic-gate and = ""; 1957c478bd9Sstevel@tonic-gate i = fr->fr_dsize; 1967c478bd9Sstevel@tonic-gate ulp = fr->fr_data; 1977c478bd9Sstevel@tonic-gate for (i /= sizeof(u_long); i > 0; i--) { 1987c478bd9Sstevel@tonic-gate fprintf(fp, "%s%#lx", and, *ulp++); 1997c478bd9Sstevel@tonic-gate and = ", "; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate fprintf(fp, "\n};\n"); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n", 2057c478bd9Sstevel@tonic-gate f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate g->fg_ref++; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (f->fr_grhead != 0) { 2107c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) 2117c478bd9Sstevel@tonic-gate if ((strncmp(g->fg_name, f->fr_grhead, 2127c478bd9Sstevel@tonic-gate FR_GROUPLEN) == 0) && 2137c478bd9Sstevel@tonic-gate g->fg_flags == (f->fr_flags & FR_INOUT)) 2147c478bd9Sstevel@tonic-gate break; 2157c478bd9Sstevel@tonic-gate if (g == NULL) { 2167c478bd9Sstevel@tonic-gate g = (frgroup_t *)calloc(1, sizeof(*g)); 2177c478bd9Sstevel@tonic-gate g->fg_next = groups; 2187c478bd9Sstevel@tonic-gate groups = g; 2197c478bd9Sstevel@tonic-gate g->fg_head = f; 2207c478bd9Sstevel@tonic-gate bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN); 2217c478bd9Sstevel@tonic-gate g->fg_ref = 0; 2227c478bd9Sstevel@tonic-gate g->fg_flags = f->fr_flags & FR_INOUT; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate int intcmp(c1, c2) 2297c478bd9Sstevel@tonic-gate const void *c1, *c2; 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate if (i1->n == i2->n) { 2347c478bd9Sstevel@tonic-gate return i1->c - i2->c; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate return i2->n - i1->n; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate static void indent(fp, in) 2417c478bd9Sstevel@tonic-gate FILE *fp; 2427c478bd9Sstevel@tonic-gate int in; 2437c478bd9Sstevel@tonic-gate { 2447c478bd9Sstevel@tonic-gate for (; in; in--) 2457c478bd9Sstevel@tonic-gate fputc('\t', fp); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate static void printeq(fp, var, m, max, v) 2497c478bd9Sstevel@tonic-gate FILE *fp; 2507c478bd9Sstevel@tonic-gate char *var; 2517c478bd9Sstevel@tonic-gate int m, max, v; 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate if (m == max) 2547c478bd9Sstevel@tonic-gate fprintf(fp, "%s == %#x) {\n", var, v); 2557c478bd9Sstevel@tonic-gate else 2567c478bd9Sstevel@tonic-gate fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * Parameters: var - IP# being compared 2617c478bd9Sstevel@tonic-gate * fl - 0 for positive match, 1 for negative match 2627c478bd9Sstevel@tonic-gate * m - netmask 2637c478bd9Sstevel@tonic-gate * v - required address 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate static void printipeq(fp, var, fl, m, v) 2667c478bd9Sstevel@tonic-gate FILE *fp; 2677c478bd9Sstevel@tonic-gate char *var; 2687c478bd9Sstevel@tonic-gate int fl, m, v; 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate if (m == 0xffffffff) 2717c478bd9Sstevel@tonic-gate fprintf(fp, "%s ", var); 2727c478bd9Sstevel@tonic-gate else 2737c478bd9Sstevel@tonic-gate fprintf(fp, "(%s & %#x) ", var, m); 2747c478bd9Sstevel@tonic-gate fprintf(fp, "%c", fl ? '!' : '='); 2757c478bd9Sstevel@tonic-gate fprintf(fp, "= %#x) {\n", v); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate void emit(num, dir, v, fr) 2807c478bd9Sstevel@tonic-gate int num, dir; 2817c478bd9Sstevel@tonic-gate void *v; 2827c478bd9Sstevel@tonic-gate frentry_t *fr; 2837c478bd9Sstevel@tonic-gate { 2847c478bd9Sstevel@tonic-gate u_int incnt, outcnt; 2857c478bd9Sstevel@tonic-gate frgroup_t *g; 2867c478bd9Sstevel@tonic-gate frentry_t *f; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) { 2897c478bd9Sstevel@tonic-gate if (dir == 0 || dir == -1) { 2907c478bd9Sstevel@tonic-gate if ((g->fg_flags & FR_INQUE) == 0) 2917c478bd9Sstevel@tonic-gate continue; 2927c478bd9Sstevel@tonic-gate for (incnt = 0, f = g->fg_start; f != NULL; 2937c478bd9Sstevel@tonic-gate f = f->fr_next) 2947c478bd9Sstevel@tonic-gate incnt++; 2957c478bd9Sstevel@tonic-gate emitGroup(num, dir, v, fr, g->fg_name, incnt, 0); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate if (dir == 1 || dir == -1) { 2987c478bd9Sstevel@tonic-gate if ((g->fg_flags & FR_OUTQUE) == 0) 2997c478bd9Sstevel@tonic-gate continue; 3007c478bd9Sstevel@tonic-gate for (outcnt = 0, f = g->fg_start; f != NULL; 3017c478bd9Sstevel@tonic-gate f = f->fr_next) 3027c478bd9Sstevel@tonic-gate outcnt++; 3037c478bd9Sstevel@tonic-gate emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if (num == -1 && dir == -1) { 3087c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) { 3097c478bd9Sstevel@tonic-gate if ((g->fg_flags & FR_INQUE) != 0) { 3107c478bd9Sstevel@tonic-gate for (incnt = 0, f = g->fg_start; f != NULL; 3117c478bd9Sstevel@tonic-gate f = f->fr_next) 3127c478bd9Sstevel@tonic-gate incnt++; 3137c478bd9Sstevel@tonic-gate if (incnt > 0) 3147c478bd9Sstevel@tonic-gate emitheader(g, incnt, 0); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate if ((g->fg_flags & FR_OUTQUE) != 0) { 3177c478bd9Sstevel@tonic-gate for (outcnt = 0, f = g->fg_start; f != NULL; 3187c478bd9Sstevel@tonic-gate f = f->fr_next) 3197c478bd9Sstevel@tonic-gate outcnt++; 3207c478bd9Sstevel@tonic-gate if (outcnt > 0) 3217c478bd9Sstevel@tonic-gate emitheader(g, 0, outcnt); 3227c478bd9Sstevel@tonic-gate } 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate emittail(); 325*ab25eeb5Syz fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n"); 3267c478bd9Sstevel@tonic-gate } 327*ab25eeb5Syz 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate static void emitheader(grp, incount, outcount) 3327c478bd9Sstevel@tonic-gate frgroup_t *grp; 3337c478bd9Sstevel@tonic-gate u_int incount, outcount; 3347c478bd9Sstevel@tonic-gate { 3357c478bd9Sstevel@tonic-gate static FILE *fph = NULL; 3367c478bd9Sstevel@tonic-gate frgroup_t *g; 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate if (fph == NULL) { 3397c478bd9Sstevel@tonic-gate fph = fopen("ip_rules.h", "w"); 3407c478bd9Sstevel@tonic-gate if (fph == NULL) 3417c478bd9Sstevel@tonic-gate return; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate fprintf(fph, "extern int ipfrule_add __P((void));\n"); 3447c478bd9Sstevel@tonic-gate fprintf(fph, "extern int ipfrule_remove __P((void));\n"); 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate printhooks(cfile, incount, outcount, grp); 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate if (incount) { 3507c478bd9Sstevel@tonic-gate fprintf(fph, "\n\ 3517c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\ 3527c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_in_%s[%d];\n", 3537c478bd9Sstevel@tonic-gate grp->fg_name, grp->fg_name, incount); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate for (g = groups; g != grp; g = g->fg_next) 3567c478bd9Sstevel@tonic-gate if ((strncmp(g->fg_name, grp->fg_name, 3577c478bd9Sstevel@tonic-gate FR_GROUPLEN) == 0) && 3587c478bd9Sstevel@tonic-gate g->fg_flags == grp->fg_flags) 3597c478bd9Sstevel@tonic-gate break; 3607c478bd9Sstevel@tonic-gate if (g == grp) { 3617c478bd9Sstevel@tonic-gate fprintf(fph, "\n\ 3627c478bd9Sstevel@tonic-gate extern int ipfrule_add_in_%s __P((void));\n\ 3637c478bd9Sstevel@tonic-gate extern int ipfrule_remove_in_%s __P((void));\n", grp->fg_name, grp->fg_name); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate if (outcount) { 3677c478bd9Sstevel@tonic-gate fprintf(fph, "\n\ 3687c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\ 3697c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_out_%s[%d];\n", 3707c478bd9Sstevel@tonic-gate grp->fg_name, grp->fg_name, outcount); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate for (g = groups; g != g; g = g->fg_next) 3737c478bd9Sstevel@tonic-gate if ((strncmp(g->fg_name, grp->fg_name, 3747c478bd9Sstevel@tonic-gate FR_GROUPLEN) == 0) && 3757c478bd9Sstevel@tonic-gate g->fg_flags == grp->fg_flags) 3767c478bd9Sstevel@tonic-gate break; 3777c478bd9Sstevel@tonic-gate if (g == grp) { 3787c478bd9Sstevel@tonic-gate fprintf(fph, "\n\ 3797c478bd9Sstevel@tonic-gate extern int ipfrule_add_out_%s __P((void));\n\ 3807c478bd9Sstevel@tonic-gate extern int ipfrule_remove_out_%s __P((void));\n", 3817c478bd9Sstevel@tonic-gate grp->fg_name, grp->fg_name); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate static void emittail() 3877c478bd9Sstevel@tonic-gate { 3887c478bd9Sstevel@tonic-gate frgroup_t *g; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate fprintf(cfile, "\n\ 3917c478bd9Sstevel@tonic-gate int ipfrule_add()\n\ 3927c478bd9Sstevel@tonic-gate {\n\ 3937c478bd9Sstevel@tonic-gate int err;\n\ 3947c478bd9Sstevel@tonic-gate \n"); 3957c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) 3967c478bd9Sstevel@tonic-gate fprintf(cfile, "\ 3977c478bd9Sstevel@tonic-gate err = ipfrule_add_%s_%s();\n\ 3987c478bd9Sstevel@tonic-gate if (err != 0)\n\ 3997c478bd9Sstevel@tonic-gate return err;\n", 4007c478bd9Sstevel@tonic-gate (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 4017c478bd9Sstevel@tonic-gate fprintf(cfile, "\ 4027c478bd9Sstevel@tonic-gate return 0;\n"); 4037c478bd9Sstevel@tonic-gate fprintf(cfile, "}\n\ 4047c478bd9Sstevel@tonic-gate \n"); 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate fprintf(cfile, "\n\ 4077c478bd9Sstevel@tonic-gate int ipfrule_remove()\n\ 4087c478bd9Sstevel@tonic-gate {\n\ 4097c478bd9Sstevel@tonic-gate int err;\n\ 4107c478bd9Sstevel@tonic-gate \n"); 4117c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) 4127c478bd9Sstevel@tonic-gate fprintf(cfile, "\ 4137c478bd9Sstevel@tonic-gate err = ipfrule_remove_%s_%s();\n\ 4147c478bd9Sstevel@tonic-gate if (err != 0)\n\ 4157c478bd9Sstevel@tonic-gate return err;\n", 4167c478bd9Sstevel@tonic-gate (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); 4177c478bd9Sstevel@tonic-gate fprintf(cfile, "\ 4187c478bd9Sstevel@tonic-gate return 0;\n"); 4197c478bd9Sstevel@tonic-gate fprintf(cfile, "}\n"); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate static void emitGroup(num, dir, v, fr, group, incount, outcount) 4247c478bd9Sstevel@tonic-gate int num, dir; 4257c478bd9Sstevel@tonic-gate void *v; 4267c478bd9Sstevel@tonic-gate frentry_t *fr; 4277c478bd9Sstevel@tonic-gate char *group; 4287c478bd9Sstevel@tonic-gate u_int incount, outcount; 4297c478bd9Sstevel@tonic-gate { 4307c478bd9Sstevel@tonic-gate static FILE *fp = NULL; 4317c478bd9Sstevel@tonic-gate static int header[2] = { 0, 0 }; 4327c478bd9Sstevel@tonic-gate static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 4337c478bd9Sstevel@tonic-gate static int openfunc = 0; 4347c478bd9Sstevel@tonic-gate static mc_t *n = NULL; 4357c478bd9Sstevel@tonic-gate static int sin = 0; 4367c478bd9Sstevel@tonic-gate frentry_t *f; 4377c478bd9Sstevel@tonic-gate frgroup_t *g; 4387c478bd9Sstevel@tonic-gate fripf_t *ipf; 4397c478bd9Sstevel@tonic-gate int i, in, j; 4407c478bd9Sstevel@tonic-gate mc_t *m = v; 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate if (fp == NULL) 4437c478bd9Sstevel@tonic-gate fp = cfile; 4447c478bd9Sstevel@tonic-gate if (fp == NULL) 4457c478bd9Sstevel@tonic-gate return; 4467c478bd9Sstevel@tonic-gate if (strncmp(egroup, group, FR_GROUPLEN)) { 4477c478bd9Sstevel@tonic-gate for (sin--; sin > 0; sin--) { 4487c478bd9Sstevel@tonic-gate indent(fp, sin); 4497c478bd9Sstevel@tonic-gate fprintf(fp, "}\n"); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate if (openfunc == 1) { 4527c478bd9Sstevel@tonic-gate fprintf(fp, "\treturn fr;\n}\n"); 4537c478bd9Sstevel@tonic-gate openfunc = 0; 4547c478bd9Sstevel@tonic-gate if (n != NULL) { 4557c478bd9Sstevel@tonic-gate free(n); 4567c478bd9Sstevel@tonic-gate n = NULL; 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate sin = 0; 4607c478bd9Sstevel@tonic-gate header[0] = 0; 4617c478bd9Sstevel@tonic-gate header[1] = 0; 4627c478bd9Sstevel@tonic-gate strncpy(egroup, group, FR_GROUPLEN); 4637c478bd9Sstevel@tonic-gate } else if (openfunc == 1 && num < 0) { 4647c478bd9Sstevel@tonic-gate if (n != NULL) { 4657c478bd9Sstevel@tonic-gate free(n); 4667c478bd9Sstevel@tonic-gate n = NULL; 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate for (sin--; sin > 0; sin--) { 4697c478bd9Sstevel@tonic-gate indent(fp, sin); 4707c478bd9Sstevel@tonic-gate fprintf(fp, "}\n"); 4717c478bd9Sstevel@tonic-gate } 4727c478bd9Sstevel@tonic-gate if (openfunc == 1) { 4737c478bd9Sstevel@tonic-gate fprintf(fp, "\treturn fr;\n}\n"); 4747c478bd9Sstevel@tonic-gate openfunc = 0; 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate if (dir == -1) 4797c478bd9Sstevel@tonic-gate return; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) { 4827c478bd9Sstevel@tonic-gate if (dir == 0 && (g->fg_flags & FR_INQUE) == 0) 4837c478bd9Sstevel@tonic-gate continue; 4847c478bd9Sstevel@tonic-gate else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0) 4857c478bd9Sstevel@tonic-gate continue; 4867c478bd9Sstevel@tonic-gate if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0) 4877c478bd9Sstevel@tonic-gate continue; 4887c478bd9Sstevel@tonic-gate break; 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* 4927c478bd9Sstevel@tonic-gate * Output the array of pointers to rules for this group. 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate if (num == -2 && dir == 0 && header[0] == 0 && incount != 0) { 4957c478bd9Sstevel@tonic-gate fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {", 4967c478bd9Sstevel@tonic-gate group, incount); 4977c478bd9Sstevel@tonic-gate for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 4987c478bd9Sstevel@tonic-gate if ((f->fr_flags & FR_INQUE) == 0) 4997c478bd9Sstevel@tonic-gate continue; 5007c478bd9Sstevel@tonic-gate if ((i & 1) == 0) { 5017c478bd9Sstevel@tonic-gate fprintf(fp, "\n\t"); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate fprintf(fp, 5047c478bd9Sstevel@tonic-gate "(frentry_t *)&in_rule_%s_%d", 5057c478bd9Sstevel@tonic-gate f->fr_group, i); 5067c478bd9Sstevel@tonic-gate if (i + 1 < incount) 5077c478bd9Sstevel@tonic-gate fprintf(fp, ", "); 5087c478bd9Sstevel@tonic-gate i++; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate fprintf(fp, "\n};\n"); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate if (num == -2 && dir == 1 && header[1] == 0 && outcount != 0) { 5147c478bd9Sstevel@tonic-gate fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {", 5157c478bd9Sstevel@tonic-gate group, outcount); 5167c478bd9Sstevel@tonic-gate for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 5177c478bd9Sstevel@tonic-gate if ((f->fr_flags & FR_OUTQUE) == 0) 5187c478bd9Sstevel@tonic-gate continue; 5197c478bd9Sstevel@tonic-gate if ((i & 1) == 0) { 5207c478bd9Sstevel@tonic-gate fprintf(fp, "\n\t"); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate fprintf(fp, 5237c478bd9Sstevel@tonic-gate "(frentry_t *)&out_rule_%s_%d", 5247c478bd9Sstevel@tonic-gate f->fr_group, i); 5257c478bd9Sstevel@tonic-gate if (i + 1 < outcount) 5267c478bd9Sstevel@tonic-gate fprintf(fp, ", "); 5277c478bd9Sstevel@tonic-gate i++; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate fprintf(fp, "\n};\n"); 5307c478bd9Sstevel@tonic-gate fp = NULL; 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate if (num < 0) 5347c478bd9Sstevel@tonic-gate return; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate in = 0; 5377c478bd9Sstevel@tonic-gate ipf = fr->fr_ipf; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /* 5407c478bd9Sstevel@tonic-gate * If the function header has not been printed then print it now. 5417c478bd9Sstevel@tonic-gate */ 5427c478bd9Sstevel@tonic-gate if (header[dir] == 0) { 5437c478bd9Sstevel@tonic-gate int pdst = 0, psrc = 0; 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate openfunc = 1; 5467c478bd9Sstevel@tonic-gate fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n", 5477c478bd9Sstevel@tonic-gate (dir == 0) ? "in" : "out", group); 5487c478bd9Sstevel@tonic-gate fprintf(fp, "fr_info_t *fin;\n"); 5497c478bd9Sstevel@tonic-gate fprintf(fp, "u_32_t *passp;\n"); 5507c478bd9Sstevel@tonic-gate fprintf(fp, "{\n"); 5517c478bd9Sstevel@tonic-gate fprintf(fp, "\tfrentry_t *fr = NULL;\n"); 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate /* 5547c478bd9Sstevel@tonic-gate * Print out any variables that need to be declared. 5557c478bd9Sstevel@tonic-gate */ 5567c478bd9Sstevel@tonic-gate for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { 5577c478bd9Sstevel@tonic-gate if (incount + outcount > m[FRC_SRC].e + 1) 5587c478bd9Sstevel@tonic-gate psrc = 1; 5597c478bd9Sstevel@tonic-gate if (incount + outcount > m[FRC_DST].e + 1) 5607c478bd9Sstevel@tonic-gate pdst = 1; 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate if (psrc == 1) 5637c478bd9Sstevel@tonic-gate fprintf(fp, "\tu_32_t src = ntohl(%s);\n", 5647c478bd9Sstevel@tonic-gate "fin->fin_fi.fi_saddr"); 5657c478bd9Sstevel@tonic-gate if (pdst == 1) 5667c478bd9Sstevel@tonic-gate fprintf(fp, "\tu_32_t dst = ntohl(%s);\n", 5677c478bd9Sstevel@tonic-gate "fin->fin_fi.fi_daddr"); 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate for (i = 0; i < FRC_MAX; i++) { 5717c478bd9Sstevel@tonic-gate switch(m[i].c) 5727c478bd9Sstevel@tonic-gate { 5737c478bd9Sstevel@tonic-gate case FRC_IFN : 5747c478bd9Sstevel@tonic-gate if (*fr->fr_ifname) 5757c478bd9Sstevel@tonic-gate m[i].s = 1; 5767c478bd9Sstevel@tonic-gate break; 5777c478bd9Sstevel@tonic-gate case FRC_V : 5787c478bd9Sstevel@tonic-gate if (ipf != NULL && ipf->fri_mip.fi_v != 0) 5797c478bd9Sstevel@tonic-gate m[i].s = 1; 5807c478bd9Sstevel@tonic-gate break; 5817c478bd9Sstevel@tonic-gate case FRC_FL : 5827c478bd9Sstevel@tonic-gate if (ipf != NULL && ipf->fri_mip.fi_flx != 0) 5837c478bd9Sstevel@tonic-gate m[i].s = 1; 5847c478bd9Sstevel@tonic-gate break; 5857c478bd9Sstevel@tonic-gate case FRC_P : 5867c478bd9Sstevel@tonic-gate if (ipf != NULL && ipf->fri_mip.fi_p != 0) 5877c478bd9Sstevel@tonic-gate m[i].s = 1; 5887c478bd9Sstevel@tonic-gate break; 5897c478bd9Sstevel@tonic-gate case FRC_TTL : 5907c478bd9Sstevel@tonic-gate if (ipf != NULL && ipf->fri_mip.fi_ttl != 0) 5917c478bd9Sstevel@tonic-gate m[i].s = 1; 5927c478bd9Sstevel@tonic-gate break; 5937c478bd9Sstevel@tonic-gate case FRC_TOS : 5947c478bd9Sstevel@tonic-gate if (ipf != NULL && ipf->fri_mip.fi_tos != 0) 5957c478bd9Sstevel@tonic-gate m[i].s = 1; 5967c478bd9Sstevel@tonic-gate break; 5977c478bd9Sstevel@tonic-gate case FRC_TCP : 5987c478bd9Sstevel@tonic-gate if (ipf == NULL) 5997c478bd9Sstevel@tonic-gate break; 6007c478bd9Sstevel@tonic-gate if ((ipf->fri_ip.fi_p == IPPROTO_TCP) && 6017c478bd9Sstevel@tonic-gate fr->fr_tcpfm != 0) 6027c478bd9Sstevel@tonic-gate m[i].s = 1; 6037c478bd9Sstevel@tonic-gate break; 6047c478bd9Sstevel@tonic-gate case FRC_SP : 6057c478bd9Sstevel@tonic-gate if (ipf == NULL) 6067c478bd9Sstevel@tonic-gate break; 6077c478bd9Sstevel@tonic-gate if (fr->fr_scmp == FR_INRANGE) 6087c478bd9Sstevel@tonic-gate m[i].s = 1; 6097c478bd9Sstevel@tonic-gate else if (fr->fr_scmp == FR_OUTRANGE) 6107c478bd9Sstevel@tonic-gate m[i].s = 1; 6117c478bd9Sstevel@tonic-gate else if (fr->fr_scmp != 0) 6127c478bd9Sstevel@tonic-gate m[i].s = 1; 6137c478bd9Sstevel@tonic-gate break; 6147c478bd9Sstevel@tonic-gate case FRC_DP : 6157c478bd9Sstevel@tonic-gate if (ipf == NULL) 6167c478bd9Sstevel@tonic-gate break; 6177c478bd9Sstevel@tonic-gate if (fr->fr_dcmp == FR_INRANGE) 6187c478bd9Sstevel@tonic-gate m[i].s = 1; 6197c478bd9Sstevel@tonic-gate else if (fr->fr_dcmp == FR_OUTRANGE) 6207c478bd9Sstevel@tonic-gate m[i].s = 1; 6217c478bd9Sstevel@tonic-gate else if (fr->fr_dcmp != 0) 6227c478bd9Sstevel@tonic-gate m[i].s = 1; 6237c478bd9Sstevel@tonic-gate break; 6247c478bd9Sstevel@tonic-gate case FRC_SRC : 6257c478bd9Sstevel@tonic-gate if (ipf == NULL) 6267c478bd9Sstevel@tonic-gate break; 6277c478bd9Sstevel@tonic-gate if (fr->fr_satype == FRI_LOOKUP) { 6287c478bd9Sstevel@tonic-gate ; 6297c478bd9Sstevel@tonic-gate } else if ((fr->fr_smask != 0) || 6307c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTSRCIP) != 0) 6317c478bd9Sstevel@tonic-gate m[i].s = 1; 6327c478bd9Sstevel@tonic-gate break; 6337c478bd9Sstevel@tonic-gate case FRC_DST : 6347c478bd9Sstevel@tonic-gate if (ipf == NULL) 6357c478bd9Sstevel@tonic-gate break; 6367c478bd9Sstevel@tonic-gate if (fr->fr_datype == FRI_LOOKUP) { 6377c478bd9Sstevel@tonic-gate ; 6387c478bd9Sstevel@tonic-gate } else if ((fr->fr_dmask != 0) || 6397c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTDSTIP) != 0) 6407c478bd9Sstevel@tonic-gate m[i].s = 1; 6417c478bd9Sstevel@tonic-gate break; 6427c478bd9Sstevel@tonic-gate case FRC_OPT : 6437c478bd9Sstevel@tonic-gate if (ipf == NULL) 6447c478bd9Sstevel@tonic-gate break; 6457c478bd9Sstevel@tonic-gate if (fr->fr_optmask != 0) 6467c478bd9Sstevel@tonic-gate m[i].s = 1; 6477c478bd9Sstevel@tonic-gate break; 6487c478bd9Sstevel@tonic-gate case FRC_SEC : 6497c478bd9Sstevel@tonic-gate if (ipf == NULL) 6507c478bd9Sstevel@tonic-gate break; 6517c478bd9Sstevel@tonic-gate if (fr->fr_secmask != 0) 6527c478bd9Sstevel@tonic-gate m[i].s = 1; 6537c478bd9Sstevel@tonic-gate break; 6547c478bd9Sstevel@tonic-gate case FRC_ATH : 6557c478bd9Sstevel@tonic-gate if (ipf == NULL) 6567c478bd9Sstevel@tonic-gate break; 6577c478bd9Sstevel@tonic-gate if (fr->fr_authmask != 0) 6587c478bd9Sstevel@tonic-gate m[i].s = 1; 6597c478bd9Sstevel@tonic-gate break; 6607c478bd9Sstevel@tonic-gate case FRC_ICT : 6617c478bd9Sstevel@tonic-gate if (ipf == NULL) 6627c478bd9Sstevel@tonic-gate break; 6637c478bd9Sstevel@tonic-gate if ((fr->fr_icmpm & 0xff00) != 0) 6647c478bd9Sstevel@tonic-gate m[i].s = 1; 6657c478bd9Sstevel@tonic-gate break; 6667c478bd9Sstevel@tonic-gate case FRC_ICC : 6677c478bd9Sstevel@tonic-gate if (ipf == NULL) 6687c478bd9Sstevel@tonic-gate break; 6697c478bd9Sstevel@tonic-gate if ((fr->fr_icmpm & 0xff) != 0) 6707c478bd9Sstevel@tonic-gate m[i].s = 1; 6717c478bd9Sstevel@tonic-gate break; 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate if (!header[dir]) { 6767c478bd9Sstevel@tonic-gate fprintf(fp, "\n"); 6777c478bd9Sstevel@tonic-gate header[dir] = 1; 6787c478bd9Sstevel@tonic-gate sin = 0; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate if (n) { 6847c478bd9Sstevel@tonic-gate /* 6857c478bd9Sstevel@tonic-gate * Calculate the indentation interval upto the last common 6867c478bd9Sstevel@tonic-gate * common comparison being made. 6877c478bd9Sstevel@tonic-gate */ 6887c478bd9Sstevel@tonic-gate for (i = 0, in = 1; i < FRC_MAX; i++) { 6897c478bd9Sstevel@tonic-gate if (n[i].c != m[i].c) 6907c478bd9Sstevel@tonic-gate break; 6917c478bd9Sstevel@tonic-gate if (n[i].s != m[i].s) 6927c478bd9Sstevel@tonic-gate break; 6937c478bd9Sstevel@tonic-gate if (n[i].s) { 6947c478bd9Sstevel@tonic-gate if (n[i].n && (n[i].n > n[i].e)) { 6957c478bd9Sstevel@tonic-gate m[i].p++; 6967c478bd9Sstevel@tonic-gate in += m[i].p; 6977c478bd9Sstevel@tonic-gate break; 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate if (n[i].e > 0) { 7007c478bd9Sstevel@tonic-gate in++; 7017c478bd9Sstevel@tonic-gate } else 7027c478bd9Sstevel@tonic-gate break; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate } 7057c478bd9Sstevel@tonic-gate if (sin != in) { 7067c478bd9Sstevel@tonic-gate for (j = sin - 1; j >= in; j--) { 7077c478bd9Sstevel@tonic-gate indent(fp, j); 7087c478bd9Sstevel@tonic-gate fprintf(fp, "}\n"); 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate } else { 7127c478bd9Sstevel@tonic-gate in = 1; 7137c478bd9Sstevel@tonic-gate i = 0; 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate /* 7177c478bd9Sstevel@tonic-gate * print out C code that implements a filter rule. 718*ab25eeb5Syz */ 7197c478bd9Sstevel@tonic-gate for (; i < FRC_MAX; i++) { 7207c478bd9Sstevel@tonic-gate switch(m[i].c) 7217c478bd9Sstevel@tonic-gate { 7227c478bd9Sstevel@tonic-gate case FRC_IFN : 7237c478bd9Sstevel@tonic-gate if (m[i].s) { 7247c478bd9Sstevel@tonic-gate indent(fp, in); 7257c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_ifp == "); 7267c478bd9Sstevel@tonic-gate fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n", 7277c478bd9Sstevel@tonic-gate dir ? "out" : "in", group, num); 7287c478bd9Sstevel@tonic-gate in++; 7297c478bd9Sstevel@tonic-gate } 7307c478bd9Sstevel@tonic-gate break; 7317c478bd9Sstevel@tonic-gate case FRC_V : 7327c478bd9Sstevel@tonic-gate if (m[i].s) { 7337c478bd9Sstevel@tonic-gate indent(fp, in); 7347c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_v == %d) {\n", 7357c478bd9Sstevel@tonic-gate ipf->fri_ip.fi_v); 7367c478bd9Sstevel@tonic-gate in++; 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate break; 7397c478bd9Sstevel@tonic-gate case FRC_FL : 7407c478bd9Sstevel@tonic-gate if (m[i].s) { 7417c478bd9Sstevel@tonic-gate indent(fp, in); 7427c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 7437c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_flx", 7447c478bd9Sstevel@tonic-gate ipf->fri_mip.fi_flx, 0xf, 7457c478bd9Sstevel@tonic-gate ipf->fri_ip.fi_flx); 7467c478bd9Sstevel@tonic-gate in++; 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate break; 7497c478bd9Sstevel@tonic-gate case FRC_P : 7507c478bd9Sstevel@tonic-gate if (m[i].s) { 7517c478bd9Sstevel@tonic-gate indent(fp, in); 7527c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_p == %d) {\n", 7537c478bd9Sstevel@tonic-gate ipf->fri_ip.fi_p); 7547c478bd9Sstevel@tonic-gate in++; 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate break; 7577c478bd9Sstevel@tonic-gate case FRC_TTL : 7587c478bd9Sstevel@tonic-gate if (m[i].s) { 7597c478bd9Sstevel@tonic-gate indent(fp, in); 7607c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 7617c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_ttl", 7627c478bd9Sstevel@tonic-gate ipf->fri_mip.fi_ttl, 0xff, 7637c478bd9Sstevel@tonic-gate ipf->fri_ip.fi_ttl); 7647c478bd9Sstevel@tonic-gate in++; 7657c478bd9Sstevel@tonic-gate } 7667c478bd9Sstevel@tonic-gate break; 7677c478bd9Sstevel@tonic-gate case FRC_TOS : 7687c478bd9Sstevel@tonic-gate if (m[i].s) { 7697c478bd9Sstevel@tonic-gate indent(fp, in); 7707c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_tos"); 7717c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_tos", 7727c478bd9Sstevel@tonic-gate ipf->fri_mip.fi_tos, 0xff, 7737c478bd9Sstevel@tonic-gate ipf->fri_ip.fi_tos); 7747c478bd9Sstevel@tonic-gate in++; 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate break; 7777c478bd9Sstevel@tonic-gate case FRC_TCP : 7787c478bd9Sstevel@tonic-gate if (m[i].s) { 7797c478bd9Sstevel@tonic-gate indent(fp, in); 7807c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 7817c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm, 7827c478bd9Sstevel@tonic-gate 0xff, fr->fr_tcpf); 7837c478bd9Sstevel@tonic-gate in++; 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate break; 7867c478bd9Sstevel@tonic-gate case FRC_SP : 7877c478bd9Sstevel@tonic-gate if (!m[i].s) 7887c478bd9Sstevel@tonic-gate break; 7897c478bd9Sstevel@tonic-gate if (fr->fr_scmp == FR_INRANGE) { 7907c478bd9Sstevel@tonic-gate indent(fp, in); 7917c478bd9Sstevel@tonic-gate fprintf(fp, "if ((fin->fin_data[0] > %d) && ", 7927c478bd9Sstevel@tonic-gate fr->fr_sport); 7937c478bd9Sstevel@tonic-gate fprintf(fp, "(fin->fin_data[0] < %d)", 7947c478bd9Sstevel@tonic-gate fr->fr_stop); 7957c478bd9Sstevel@tonic-gate fprintf(fp, ") {\n"); 7967c478bd9Sstevel@tonic-gate in++; 7977c478bd9Sstevel@tonic-gate } else if (fr->fr_scmp == FR_OUTRANGE) { 7987c478bd9Sstevel@tonic-gate indent(fp, in); 7997c478bd9Sstevel@tonic-gate fprintf(fp, "if ((fin->fin_data[0] < %d) || ", 8007c478bd9Sstevel@tonic-gate fr->fr_sport); 8017c478bd9Sstevel@tonic-gate fprintf(fp, "(fin->fin_data[0] > %d)", 8027c478bd9Sstevel@tonic-gate fr->fr_stop); 8037c478bd9Sstevel@tonic-gate fprintf(fp, ") {\n"); 8047c478bd9Sstevel@tonic-gate in++; 8057c478bd9Sstevel@tonic-gate } else if (fr->fr_scmp) { 8067c478bd9Sstevel@tonic-gate indent(fp, in); 8077c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_data[0] %s %d)", 8087c478bd9Sstevel@tonic-gate portcmp[fr->fr_scmp], fr->fr_sport); 8097c478bd9Sstevel@tonic-gate fprintf(fp, " {\n"); 8107c478bd9Sstevel@tonic-gate in++; 8117c478bd9Sstevel@tonic-gate } 8127c478bd9Sstevel@tonic-gate break; 8137c478bd9Sstevel@tonic-gate case FRC_DP : 8147c478bd9Sstevel@tonic-gate if (!m[i].s) 8157c478bd9Sstevel@tonic-gate break; 8167c478bd9Sstevel@tonic-gate if (fr->fr_dcmp == FR_INRANGE) { 8177c478bd9Sstevel@tonic-gate indent(fp, in); 8187c478bd9Sstevel@tonic-gate fprintf(fp, "if ((fin->fin_data[1] > %d) && ", 8197c478bd9Sstevel@tonic-gate fr->fr_dport); 8207c478bd9Sstevel@tonic-gate fprintf(fp, "(fin->fin_data[1] < %d)", 8217c478bd9Sstevel@tonic-gate fr->fr_dtop); 8227c478bd9Sstevel@tonic-gate fprintf(fp, ") {\n"); 8237c478bd9Sstevel@tonic-gate in++; 8247c478bd9Sstevel@tonic-gate } else if (fr->fr_dcmp == FR_OUTRANGE) { 8257c478bd9Sstevel@tonic-gate indent(fp, in); 8267c478bd9Sstevel@tonic-gate fprintf(fp, "if ((fin->fin_data[1] < %d) || ", 8277c478bd9Sstevel@tonic-gate fr->fr_dport); 8287c478bd9Sstevel@tonic-gate fprintf(fp, "(fin->fin_data[1] > %d)", 8297c478bd9Sstevel@tonic-gate fr->fr_dtop); 8307c478bd9Sstevel@tonic-gate fprintf(fp, ") {\n"); 8317c478bd9Sstevel@tonic-gate in++; 8327c478bd9Sstevel@tonic-gate } else if (fr->fr_dcmp) { 8337c478bd9Sstevel@tonic-gate indent(fp, in); 8347c478bd9Sstevel@tonic-gate fprintf(fp, "if (fin->fin_data[1] %s %d)", 8357c478bd9Sstevel@tonic-gate portcmp[fr->fr_dcmp], fr->fr_dport); 8367c478bd9Sstevel@tonic-gate fprintf(fp, " {\n"); 8377c478bd9Sstevel@tonic-gate in++; 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate break; 8407c478bd9Sstevel@tonic-gate case FRC_SRC : 8417c478bd9Sstevel@tonic-gate if (!m[i].s) 8427c478bd9Sstevel@tonic-gate break; 8437c478bd9Sstevel@tonic-gate if (fr->fr_satype == FRI_LOOKUP) { 8447c478bd9Sstevel@tonic-gate ; 8457c478bd9Sstevel@tonic-gate } else if ((fr->fr_smask != 0) || 8467c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTSRCIP) != 0) { 8477c478bd9Sstevel@tonic-gate indent(fp, in); 8487c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 8497c478bd9Sstevel@tonic-gate printipeq(fp, "src", 8507c478bd9Sstevel@tonic-gate fr->fr_flags & FR_NOTSRCIP, 8517c478bd9Sstevel@tonic-gate fr->fr_smask, fr->fr_saddr); 8527c478bd9Sstevel@tonic-gate in++; 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate break; 8557c478bd9Sstevel@tonic-gate case FRC_DST : 8567c478bd9Sstevel@tonic-gate if (!m[i].s) 8577c478bd9Sstevel@tonic-gate break; 8587c478bd9Sstevel@tonic-gate if (fr->fr_datype == FRI_LOOKUP) { 8597c478bd9Sstevel@tonic-gate ; 8607c478bd9Sstevel@tonic-gate } else if ((fr->fr_dmask != 0) || 8617c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTDSTIP) != 0) { 8627c478bd9Sstevel@tonic-gate indent(fp, in); 8637c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 8647c478bd9Sstevel@tonic-gate printipeq(fp, "dst", 8657c478bd9Sstevel@tonic-gate fr->fr_flags & FR_NOTDSTIP, 8667c478bd9Sstevel@tonic-gate fr->fr_dmask, fr->fr_daddr); 8677c478bd9Sstevel@tonic-gate in++; 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate break; 8707c478bd9Sstevel@tonic-gate case FRC_OPT : 8717c478bd9Sstevel@tonic-gate if (m[i].s) { 8727c478bd9Sstevel@tonic-gate indent(fp, in); 8737c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 8747c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_fi.fi_optmsk", 8757c478bd9Sstevel@tonic-gate fr->fr_optmask, 0xffffffff, 8767c478bd9Sstevel@tonic-gate fr->fr_optbits); 8777c478bd9Sstevel@tonic-gate in++; 8787c478bd9Sstevel@tonic-gate } 8797c478bd9Sstevel@tonic-gate break; 8807c478bd9Sstevel@tonic-gate case FRC_SEC : 8817c478bd9Sstevel@tonic-gate if (m[i].s) { 8827c478bd9Sstevel@tonic-gate indent(fp, in); 8837c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 8847c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_fi.fi_secmsk", 8857c478bd9Sstevel@tonic-gate fr->fr_secmask, 0xffff, 8867c478bd9Sstevel@tonic-gate fr->fr_secbits); 8877c478bd9Sstevel@tonic-gate in++; 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate break; 8907c478bd9Sstevel@tonic-gate case FRC_ATH : 8917c478bd9Sstevel@tonic-gate if (m[i].s) { 8927c478bd9Sstevel@tonic-gate indent(fp, in); 8937c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 8947c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_fi.fi_authmsk", 8957c478bd9Sstevel@tonic-gate fr->fr_authmask, 0xffff, 8967c478bd9Sstevel@tonic-gate fr->fr_authbits); 8977c478bd9Sstevel@tonic-gate in++; 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate break; 9007c478bd9Sstevel@tonic-gate case FRC_ICT : 9017c478bd9Sstevel@tonic-gate if (m[i].s) { 9027c478bd9Sstevel@tonic-gate indent(fp, in); 9037c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 9047c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_data[0]", 9057c478bd9Sstevel@tonic-gate fr->fr_icmpm & 0xff00, 0xffff, 9067c478bd9Sstevel@tonic-gate fr->fr_icmp & 0xff00); 9077c478bd9Sstevel@tonic-gate in++; 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate break; 9107c478bd9Sstevel@tonic-gate case FRC_ICC : 9117c478bd9Sstevel@tonic-gate if (m[i].s) { 9127c478bd9Sstevel@tonic-gate indent(fp, in); 9137c478bd9Sstevel@tonic-gate fprintf(fp, "if ("); 9147c478bd9Sstevel@tonic-gate printeq(fp, "fin->fin_data[0]", 9157c478bd9Sstevel@tonic-gate fr->fr_icmpm & 0xff, 0xffff, 9167c478bd9Sstevel@tonic-gate fr->fr_icmp & 0xff); 9177c478bd9Sstevel@tonic-gate in++; 9187c478bd9Sstevel@tonic-gate } 9197c478bd9Sstevel@tonic-gate break; 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate indent(fp, in); 9257c478bd9Sstevel@tonic-gate if (fr->fr_flags & FR_QUICK) { 9267c478bd9Sstevel@tonic-gate fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n", 9277c478bd9Sstevel@tonic-gate fr->fr_flags & FR_INQUE ? "in" : "out", 9287c478bd9Sstevel@tonic-gate fr->fr_group, num); 9297c478bd9Sstevel@tonic-gate } else { 9307c478bd9Sstevel@tonic-gate fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", 9317c478bd9Sstevel@tonic-gate fr->fr_flags & FR_INQUE ? "in" : "out", 9327c478bd9Sstevel@tonic-gate fr->fr_group, num); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate if (n == NULL) 9357c478bd9Sstevel@tonic-gate n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); 9367c478bd9Sstevel@tonic-gate bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX); 9377c478bd9Sstevel@tonic-gate sin = in; 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate void printC(dir) 9427c478bd9Sstevel@tonic-gate int dir; 9437c478bd9Sstevel@tonic-gate { 9447c478bd9Sstevel@tonic-gate static mc_t *m = NULL; 9457c478bd9Sstevel@tonic-gate frgroup_t *g; 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate if (m == NULL) 9487c478bd9Sstevel@tonic-gate m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX); 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate for (g = groups; g != NULL; g = g->fg_next) { 9517c478bd9Sstevel@tonic-gate if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0)) 9527c478bd9Sstevel@tonic-gate printCgroup(dir, g->fg_start, m, g->fg_name); 9537c478bd9Sstevel@tonic-gate if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0)) 9547c478bd9Sstevel@tonic-gate printCgroup(dir, g->fg_start, m, g->fg_name); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate emit(-1, dir, m, NULL); 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate /* 9627c478bd9Sstevel@tonic-gate * Now print out code to implement all of the rules. 9637c478bd9Sstevel@tonic-gate */ 9647c478bd9Sstevel@tonic-gate static void printCgroup(dir, top, m, group) 9657c478bd9Sstevel@tonic-gate int dir; 9667c478bd9Sstevel@tonic-gate frentry_t *top; 9677c478bd9Sstevel@tonic-gate mc_t *m; 9687c478bd9Sstevel@tonic-gate char *group; 9697c478bd9Sstevel@tonic-gate { 9707c478bd9Sstevel@tonic-gate frentry_t *fr, *fr1; 9717c478bd9Sstevel@tonic-gate int i, n, rn; 9727c478bd9Sstevel@tonic-gate u_int count; 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) { 9757c478bd9Sstevel@tonic-gate if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0)) 9767c478bd9Sstevel@tonic-gate count++; 9777c478bd9Sstevel@tonic-gate else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0)) 9787c478bd9Sstevel@tonic-gate count++; 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate if (dir == 0) 9827c478bd9Sstevel@tonic-gate emitGroup(-2, dir, m, fr1, group, count, 0); 9837c478bd9Sstevel@tonic-gate else if (dir == 1) 9847c478bd9Sstevel@tonic-gate emitGroup(-2, dir, m, fr1, group, 0, count); 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate /* 9877c478bd9Sstevel@tonic-gate * Before printing each rule, check to see how many of its fields are 9887c478bd9Sstevel@tonic-gate * matched by subsequent rules. 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) { 9917c478bd9Sstevel@tonic-gate if (!dir && !(fr1->fr_flags & FR_INQUE)) 9927c478bd9Sstevel@tonic-gate continue; 9937c478bd9Sstevel@tonic-gate if (dir && !(fr1->fr_flags & FR_OUTQUE)) 9947c478bd9Sstevel@tonic-gate continue; 9957c478bd9Sstevel@tonic-gate n = 0xfffffff; 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate for (i = 0; i < FRC_MAX; i++) 9987c478bd9Sstevel@tonic-gate m[i].e = 0; 9997c478bd9Sstevel@tonic-gate qsort(m, FRC_MAX, sizeof(mc_t), intcmp); 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate for (i = 0; i < FRC_MAX; i++) { 10027c478bd9Sstevel@tonic-gate m[i].c = i; 10037c478bd9Sstevel@tonic-gate m[i].e = 0; 10047c478bd9Sstevel@tonic-gate m[i].n = 0; 10057c478bd9Sstevel@tonic-gate m[i].s = 0; 10067c478bd9Sstevel@tonic-gate } 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate for (fr = fr1->fr_next; fr; fr = fr->fr_next) { 10097c478bd9Sstevel@tonic-gate if (!dir && !(fr->fr_flags & FR_INQUE)) 10107c478bd9Sstevel@tonic-gate continue; 10117c478bd9Sstevel@tonic-gate if (dir && !(fr->fr_flags & FR_OUTQUE)) 10127c478bd9Sstevel@tonic-gate continue; 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate if ((n & 0x0001) && 10157c478bd9Sstevel@tonic-gate !strcmp(fr1->fr_ifname, fr->fr_ifname)) { 10167c478bd9Sstevel@tonic-gate m[FRC_IFN].e++; 10177c478bd9Sstevel@tonic-gate m[FRC_IFN].n++; 10187c478bd9Sstevel@tonic-gate } else 10197c478bd9Sstevel@tonic-gate n &= ~0x0001; 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) { 10227c478bd9Sstevel@tonic-gate m[FRC_V].e++; 10237c478bd9Sstevel@tonic-gate m[FRC_V].n++; 10247c478bd9Sstevel@tonic-gate } else 10257c478bd9Sstevel@tonic-gate n &= ~0x0002; 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate if ((n & 0x0004) && 10287c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10297c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10307c478bd9Sstevel@tonic-gate (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) && 10317c478bd9Sstevel@tonic-gate (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) { 10327c478bd9Sstevel@tonic-gate m[FRC_FL].e++; 10337c478bd9Sstevel@tonic-gate m[FRC_FL].n++; 10347c478bd9Sstevel@tonic-gate } else 10357c478bd9Sstevel@tonic-gate n &= ~0x0004; 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate if ((n & 0x0008) && 10387c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10397c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10407c478bd9Sstevel@tonic-gate (fr1->fr_proto == fr->fr_proto)) { 10417c478bd9Sstevel@tonic-gate m[FRC_P].e++; 10427c478bd9Sstevel@tonic-gate m[FRC_P].n++; 10437c478bd9Sstevel@tonic-gate } else 10447c478bd9Sstevel@tonic-gate n &= ~0x0008; 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate if ((n & 0x0010) && 10477c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10487c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10497c478bd9Sstevel@tonic-gate (fr1->fr_ttl == fr->fr_ttl)) { 10507c478bd9Sstevel@tonic-gate m[FRC_TTL].e++; 10517c478bd9Sstevel@tonic-gate m[FRC_TTL].n++; 10527c478bd9Sstevel@tonic-gate } else 10537c478bd9Sstevel@tonic-gate n &= ~0x0010; 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate if ((n & 0x0020) && 10567c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10577c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10587c478bd9Sstevel@tonic-gate (fr1->fr_tos == fr->fr_tos)) { 10597c478bd9Sstevel@tonic-gate m[FRC_TOS].e++; 10607c478bd9Sstevel@tonic-gate m[FRC_TOS].n++; 10617c478bd9Sstevel@tonic-gate } else 10627c478bd9Sstevel@tonic-gate n &= ~0x0020; 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate if ((n & 0x0040) && 10657c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10667c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10677c478bd9Sstevel@tonic-gate ((fr1->fr_tcpfm == fr->fr_tcpfm) && 10687c478bd9Sstevel@tonic-gate (fr1->fr_tcpf == fr->fr_tcpf))) { 10697c478bd9Sstevel@tonic-gate m[FRC_TCP].e++; 10707c478bd9Sstevel@tonic-gate m[FRC_TCP].n++; 10717c478bd9Sstevel@tonic-gate } else 10727c478bd9Sstevel@tonic-gate n &= ~0x0040; 10737c478bd9Sstevel@tonic-gate 10747c478bd9Sstevel@tonic-gate if ((n & 0x0080) && 10757c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10767c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10777c478bd9Sstevel@tonic-gate ((fr1->fr_scmp == fr->fr_scmp) && 10787c478bd9Sstevel@tonic-gate (fr1->fr_stop == fr->fr_stop) && 10797c478bd9Sstevel@tonic-gate (fr1->fr_sport == fr->fr_sport))) { 10807c478bd9Sstevel@tonic-gate m[FRC_SP].e++; 10817c478bd9Sstevel@tonic-gate m[FRC_SP].n++; 10827c478bd9Sstevel@tonic-gate } else 10837c478bd9Sstevel@tonic-gate n &= ~0x0080; 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate if ((n & 0x0100) && 10867c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10877c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10887c478bd9Sstevel@tonic-gate ((fr1->fr_dcmp == fr->fr_dcmp) && 10897c478bd9Sstevel@tonic-gate (fr1->fr_dtop == fr->fr_dtop) && 10907c478bd9Sstevel@tonic-gate (fr1->fr_dport == fr->fr_dport))) { 10917c478bd9Sstevel@tonic-gate m[FRC_DP].e++; 10927c478bd9Sstevel@tonic-gate m[FRC_DP].n++; 10937c478bd9Sstevel@tonic-gate } else 10947c478bd9Sstevel@tonic-gate n &= ~0x0100; 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate if ((n & 0x0200) && 10977c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 10987c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 10997c478bd9Sstevel@tonic-gate ((fr1->fr_satype == FRI_LOOKUP) && 11007c478bd9Sstevel@tonic-gate (fr->fr_satype == FRI_LOOKUP) && 11017c478bd9Sstevel@tonic-gate (fr1->fr_srcnum == fr->fr_srcnum))) { 11027c478bd9Sstevel@tonic-gate m[FRC_SRC].e++; 11037c478bd9Sstevel@tonic-gate m[FRC_SRC].n++; 11047c478bd9Sstevel@tonic-gate } else if ((n & 0x0200) && 11057c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11067c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11077c478bd9Sstevel@tonic-gate (((fr1->fr_flags & FR_NOTSRCIP) == 11087c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTSRCIP)))) { 11097c478bd9Sstevel@tonic-gate if ((fr1->fr_smask == fr->fr_smask) && 11107c478bd9Sstevel@tonic-gate (fr1->fr_saddr == fr->fr_saddr)) 11117c478bd9Sstevel@tonic-gate m[FRC_SRC].e++; 11127c478bd9Sstevel@tonic-gate else 11137c478bd9Sstevel@tonic-gate n &= ~0x0200; 11147c478bd9Sstevel@tonic-gate if (fr1->fr_smask && 11157c478bd9Sstevel@tonic-gate (fr1->fr_saddr & fr1->fr_smask) == 11167c478bd9Sstevel@tonic-gate (fr->fr_saddr & fr1->fr_smask)) { 11177c478bd9Sstevel@tonic-gate m[FRC_SRC].n++; 11187c478bd9Sstevel@tonic-gate n |= 0x0200; 11197c478bd9Sstevel@tonic-gate } 11207c478bd9Sstevel@tonic-gate } else { 11217c478bd9Sstevel@tonic-gate n &= ~0x0200; 11227c478bd9Sstevel@tonic-gate } 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate if ((n & 0x0400) && 11257c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11267c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11277c478bd9Sstevel@tonic-gate ((fr1->fr_datype == FRI_LOOKUP) && 11287c478bd9Sstevel@tonic-gate (fr->fr_datype == FRI_LOOKUP) && 11297c478bd9Sstevel@tonic-gate (fr1->fr_dstnum == fr->fr_dstnum))) { 11307c478bd9Sstevel@tonic-gate m[FRC_DST].e++; 11317c478bd9Sstevel@tonic-gate m[FRC_DST].n++; 11327c478bd9Sstevel@tonic-gate } else if ((n & 0x0400) && 11337c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11347c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11357c478bd9Sstevel@tonic-gate (((fr1->fr_flags & FR_NOTDSTIP) == 11367c478bd9Sstevel@tonic-gate (fr->fr_flags & FR_NOTDSTIP)))) { 11377c478bd9Sstevel@tonic-gate if ((fr1->fr_dmask == fr->fr_dmask) && 11387c478bd9Sstevel@tonic-gate (fr1->fr_daddr == fr->fr_daddr)) 11397c478bd9Sstevel@tonic-gate m[FRC_DST].e++; 11407c478bd9Sstevel@tonic-gate else 11417c478bd9Sstevel@tonic-gate n &= ~0x0400; 11427c478bd9Sstevel@tonic-gate if (fr1->fr_dmask && 11437c478bd9Sstevel@tonic-gate (fr1->fr_daddr & fr1->fr_dmask) == 11447c478bd9Sstevel@tonic-gate (fr->fr_daddr & fr1->fr_dmask)) { 11457c478bd9Sstevel@tonic-gate m[FRC_DST].n++; 11467c478bd9Sstevel@tonic-gate n |= 0x0400; 11477c478bd9Sstevel@tonic-gate } 11487c478bd9Sstevel@tonic-gate } else { 11497c478bd9Sstevel@tonic-gate n &= ~0x0400; 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate 11527c478bd9Sstevel@tonic-gate if ((n & 0x0800) && 11537c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11547c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11557c478bd9Sstevel@tonic-gate (fr1->fr_optmask == fr->fr_optmask) && 11567c478bd9Sstevel@tonic-gate (fr1->fr_optbits == fr->fr_optbits)) { 11577c478bd9Sstevel@tonic-gate m[FRC_OPT].e++; 11587c478bd9Sstevel@tonic-gate m[FRC_OPT].n++; 11597c478bd9Sstevel@tonic-gate } else 11607c478bd9Sstevel@tonic-gate n &= ~0x0800; 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate if ((n & 0x1000) && 11637c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11647c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11657c478bd9Sstevel@tonic-gate (fr1->fr_secmask == fr->fr_secmask) && 11667c478bd9Sstevel@tonic-gate (fr1->fr_secbits == fr->fr_secbits)) { 11677c478bd9Sstevel@tonic-gate m[FRC_SEC].e++; 11687c478bd9Sstevel@tonic-gate m[FRC_SEC].n++; 11697c478bd9Sstevel@tonic-gate } else 11707c478bd9Sstevel@tonic-gate n &= ~0x1000; 11717c478bd9Sstevel@tonic-gate 11727c478bd9Sstevel@tonic-gate if ((n & 0x10000) && 11737c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11747c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11757c478bd9Sstevel@tonic-gate (fr1->fr_authmask == fr->fr_authmask) && 11767c478bd9Sstevel@tonic-gate (fr1->fr_authbits == fr->fr_authbits)) { 11777c478bd9Sstevel@tonic-gate m[FRC_ATH].e++; 11787c478bd9Sstevel@tonic-gate m[FRC_ATH].n++; 11797c478bd9Sstevel@tonic-gate } else 11807c478bd9Sstevel@tonic-gate n &= ~0x10000; 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate if ((n & 0x20000) && 11837c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11847c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11857c478bd9Sstevel@tonic-gate ((fr1->fr_icmpm & 0xff00) == 11867c478bd9Sstevel@tonic-gate (fr->fr_icmpm & 0xff00)) && 11877c478bd9Sstevel@tonic-gate ((fr1->fr_icmp & 0xff00) == 11887c478bd9Sstevel@tonic-gate (fr->fr_icmp & 0xff00))) { 11897c478bd9Sstevel@tonic-gate m[FRC_ICT].e++; 11907c478bd9Sstevel@tonic-gate m[FRC_ICT].n++; 11917c478bd9Sstevel@tonic-gate } else 11927c478bd9Sstevel@tonic-gate n &= ~0x20000; 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate if ((n & 0x40000) && 11957c478bd9Sstevel@tonic-gate (fr->fr_type == fr1->fr_type) && 11967c478bd9Sstevel@tonic-gate (fr->fr_type == FR_T_IPF) && 11977c478bd9Sstevel@tonic-gate ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) && 11987c478bd9Sstevel@tonic-gate ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) { 11997c478bd9Sstevel@tonic-gate m[FRC_ICC].e++; 12007c478bd9Sstevel@tonic-gate m[FRC_ICC].n++; 12017c478bd9Sstevel@tonic-gate } else 12027c478bd9Sstevel@tonic-gate n &= ~0x40000; 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate /*msort(m);*/ 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate if (dir == 0) 12077c478bd9Sstevel@tonic-gate emitGroup(rn, dir, m, fr1, group, count, 0); 12087c478bd9Sstevel@tonic-gate else if (dir == 1) 12097c478bd9Sstevel@tonic-gate emitGroup(rn, dir, m, fr1, group, 0, count); 12107c478bd9Sstevel@tonic-gate } 12117c478bd9Sstevel@tonic-gate } 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate static void printhooks(fp, in, out, grp) 12147c478bd9Sstevel@tonic-gate FILE *fp; 12157c478bd9Sstevel@tonic-gate int in; 12167c478bd9Sstevel@tonic-gate int out; 12177c478bd9Sstevel@tonic-gate frgroup_t *grp; 12187c478bd9Sstevel@tonic-gate { 12197c478bd9Sstevel@tonic-gate frentry_t *fr; 12207c478bd9Sstevel@tonic-gate char *group; 12217c478bd9Sstevel@tonic-gate int dogrp, i; 12227c478bd9Sstevel@tonic-gate char *instr; 12237c478bd9Sstevel@tonic-gate 12247c478bd9Sstevel@tonic-gate group = grp->fg_name; 12257c478bd9Sstevel@tonic-gate dogrp = 0; 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate if (in && out) { 12287c478bd9Sstevel@tonic-gate fprintf(stderr, 12297c478bd9Sstevel@tonic-gate "printhooks called with both in and out set\n"); 12307c478bd9Sstevel@tonic-gate exit(1); 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate if (in) { 12347c478bd9Sstevel@tonic-gate instr = "in"; 12357c478bd9Sstevel@tonic-gate } else if (out) { 12367c478bd9Sstevel@tonic-gate instr = "out"; 12377c478bd9Sstevel@tonic-gate } else { 12387c478bd9Sstevel@tonic-gate instr = "???"; 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group); 12417c478bd9Sstevel@tonic-gate 12427c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12437c478bd9Sstevel@tonic-gate \n\ 12447c478bd9Sstevel@tonic-gate int ipfrule_add_%s_%s()\n", instr, group); 12457c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12467c478bd9Sstevel@tonic-gate {\n\ 12477c478bd9Sstevel@tonic-gate int i, j, err = 0, max;\n\ 12487c478bd9Sstevel@tonic-gate frentry_t *fp;\n"); 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate if (dogrp) 12517c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12527c478bd9Sstevel@tonic-gate frgroup_t *fg;\n"); 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate fprintf(fp, "\n"); 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next) 12577c478bd9Sstevel@tonic-gate if (fr->fr_dsize > 0) { 12587c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12597c478bd9Sstevel@tonic-gate ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n", 12607c478bd9Sstevel@tonic-gate instr, grp->fg_name, i, 12617c478bd9Sstevel@tonic-gate instr, grp->fg_name, i); 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12647c478bd9Sstevel@tonic-gate max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\ 12657c478bd9Sstevel@tonic-gate for (i = 0; i < max; i++) {\n\ 12667c478bd9Sstevel@tonic-gate fp = ipf_rules_%s_%s[i];\n\ 12677c478bd9Sstevel@tonic-gate fp->fr_next = NULL;\n", instr, group, instr, group); 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12707c478bd9Sstevel@tonic-gate for (j = i + 1; j < max; j++)\n\ 12717c478bd9Sstevel@tonic-gate if (strncmp(fp->fr_group,\n\ 12727c478bd9Sstevel@tonic-gate ipf_rules_%s_%s[j]->fr_group,\n\ 12737c478bd9Sstevel@tonic-gate FR_GROUPLEN) == 0) {\n\ 12747c478bd9Sstevel@tonic-gate fp->fr_next = ipf_rules_%s_%s[j];\n\ 12757c478bd9Sstevel@tonic-gate break;\n\ 12767c478bd9Sstevel@tonic-gate }\n", instr, group, instr, group); 12777c478bd9Sstevel@tonic-gate if (dogrp) 12787c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12797c478bd9Sstevel@tonic-gate \n\ 12807c478bd9Sstevel@tonic-gate if (fp->fr_grhead != 0) {\n\ 12817c478bd9Sstevel@tonic-gate fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\ 12827c478bd9Sstevel@tonic-gate IPL_LOGIPF, 0);\n\ 12837c478bd9Sstevel@tonic-gate if (fg != NULL)\n\ 12847c478bd9Sstevel@tonic-gate fp->fr_grp = &fg->fg_start;\n\ 12857c478bd9Sstevel@tonic-gate }\n"); 12867c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12877c478bd9Sstevel@tonic-gate }\n\ 12887c478bd9Sstevel@tonic-gate \n\ 12897c478bd9Sstevel@tonic-gate fp = &ipfrule_%s_%s;\n", instr, group); 12907c478bd9Sstevel@tonic-gate fprintf(fp, "\ 12917c478bd9Sstevel@tonic-gate bzero((char *)fp, sizeof(*fp));\n\ 12927c478bd9Sstevel@tonic-gate fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\ 12937c478bd9Sstevel@tonic-gate fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ 12947c478bd9Sstevel@tonic-gate fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", 12957c478bd9Sstevel@tonic-gate (in != 0) ? "IN" : "OUT", instr, group); 1296*ab25eeb5Syz fprintf(fp, "\ 1297*ab25eeb5Syz fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n", 1298*ab25eeb5Syz instr, group); 12997c478bd9Sstevel@tonic-gate 13007c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13017c478bd9Sstevel@tonic-gate fp->fr_v = 4;\n\ 13027c478bd9Sstevel@tonic-gate fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ 13037c478bd9Sstevel@tonic-gate err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n", 13047c478bd9Sstevel@tonic-gate instr, group); 13057c478bd9Sstevel@tonic-gate fprintf(fp, "\treturn err;\n}\n"); 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate fprintf(fp, "\n\n\ 13087c478bd9Sstevel@tonic-gate int ipfrule_remove_%s_%s()\n", instr, group); 13097c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13107c478bd9Sstevel@tonic-gate {\n\ 13117c478bd9Sstevel@tonic-gate int err = 0, i;\n\ 13127c478bd9Sstevel@tonic-gate frentry_t *fp;\n\ 13137c478bd9Sstevel@tonic-gate \n\ 13147c478bd9Sstevel@tonic-gate /*\n\ 13157c478bd9Sstevel@tonic-gate * Try to remove the %sbound rule.\n", instr); 13167c478bd9Sstevel@tonic-gate 13177c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13187c478bd9Sstevel@tonic-gate */\n\ 13197c478bd9Sstevel@tonic-gate if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group); 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13227c478bd9Sstevel@tonic-gate err = EBUSY;\n\ 13237c478bd9Sstevel@tonic-gate } else {\n"); 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13267c478bd9Sstevel@tonic-gate i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\ 13277c478bd9Sstevel@tonic-gate for (; i >= 0; i--) {\n\ 13287c478bd9Sstevel@tonic-gate fp = ipf_rules_%s_%s[i];\n\ 13297c478bd9Sstevel@tonic-gate if (fp->fr_ref > 1) {\n\ 13307c478bd9Sstevel@tonic-gate err = EBUSY;\n\ 13317c478bd9Sstevel@tonic-gate break;\n\ 13327c478bd9Sstevel@tonic-gate }\n\ 13337c478bd9Sstevel@tonic-gate }\n\ 13347c478bd9Sstevel@tonic-gate }\n\ 13357c478bd9Sstevel@tonic-gate if (err == 0)\n\ 13367c478bd9Sstevel@tonic-gate err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\ 13377c478bd9Sstevel@tonic-gate (caddr_t)&ipfrule_%s_%s, fr_active, 0);\n", 13387c478bd9Sstevel@tonic-gate instr, group, instr, group, instr, group); 13397c478bd9Sstevel@tonic-gate fprintf(fp, "\ 13407c478bd9Sstevel@tonic-gate if (err)\n\ 13417c478bd9Sstevel@tonic-gate return err;\n\ 13427c478bd9Sstevel@tonic-gate \n\n"); 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate fprintf(fp, "\treturn err;\n}\n"); 13457c478bd9Sstevel@tonic-gate } 1346