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