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