Logo Search packages:      
Sourcecode: hlfl version File versions  Download package

bsd_ipfw.c

/* hlfl
 * Copyright  2000-2003 Renaud Deraison
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "includes.h"
#include "hlfl.h"

extern int icmp(char *);
extern int matched_if;
extern translator_t active_translator;

static FILE *fout;

static char *icmp_types(type)
char *type;
{
      char *ret = malloc(20);
      memset(ret, 0, 20);
      if (!strlen(type))
            return ret;
      if (!strcmp(type, "echo-reply"))
            sprintf(ret, "icmptypes 0");
      else if (!strcmp(type, "destination-unreachable"))
            sprintf(ret, "icmptypes 3");
      else if (!strcmp(type, "echo-request"))
            sprintf(ret, "icmptypes 8");
      else if (!strcmp(type, "time-exceeded"))
            sprintf(ret, "icmptypes 11");
      else
            fprintf(stderr, "Warning. Unknown icmp type '%s'\n", type);
      return ret;
}

/*------------------------------------------------------------------
 * BSD's ipfw
 *------------------------------------------------------------------*/
int translate_bsd_ipfw(op, proto, src, log, dst, sports, dports, interface)
int op;
char *proto;
char *src;
char *dst;
int log;
char *sports;
char *dports;
char *interface;
{
      char *via = strdup("");
      char *icmp_code = "";
      char *logit = "";

      if (log)
            logit = " log";

      if (icmp(proto)) {
            if (sports && strlen(sports))
                  icmp_code = icmp_types(sports);
            else if (dports && strlen(dports))
                  icmp_code = icmp_types(dports);
            else
                  icmp_code = icmp_types("");

            sports = "";
            dports = "";
      }

      if (!sports)
            sports = "";
      if (!dports)
            dports = "";

      if (interface) {
            free(via);
            via = malloc(10 + strlen(interface));
            sprintf(via, "via %s", interface);
      }
      switch (op) {
      case ACCEPT_ONE_WAY:
            fprintf(fout,
                  "$ipfw -f add allow%s %s from %s %s to %s %s out %s %s\n",
                  logit, proto, src, sports, dst, dports, icmp_code, via);
            break;
      case ACCEPT_ONE_WAY_REVERSE:
            fprintf(fout,
                  "$ipfw -f add allow%s %s from %s %s to %s %s in %s %s\n",
                  logit, proto, dst, dports, src, sports, icmp_code, via);
            break;
      case ACCEPT_TWO_WAYS:
            fprintf(fout,
                  "$ipfw -f add allow%s %s from %s %s to %s %s out %s %s\n",
                  logit, proto, src, sports, dst, dports, icmp_code, via);
            fprintf(fout,
                  "$ipfw -f add allow%s %s from %s %s to %s %s in %s %s\n",
                  logit, proto, dst, dports, src, sports, icmp_code, via);
            break;
      case ACCEPT_TWO_WAYS_ESTABLISHED:
            if (!strcmp(proto, "tcp")) {
                  fprintf(fout,
                        "$ipfw -f add allow%s %s from %s %s to %s %s out %s\n",
                        logit, proto, src, sports, dst, dports, via);
                  fprintf(fout,
                        "$ipfw -f add deny%s %s from %s %s to %s %s in setup %s\n",
                        logit, proto, dst, dports, src, sports, via);
                  fprintf(fout,
                        "$ipfw -f add accept%s %s from %s %s to %s %s in %s\n",
                        logit, proto, dst, dports, src, sports, via);
            } else {
                  if (active_translator == TRANSLATOR_IPFW4) {
                        fprintf(fout,
                              "$ipfw -f add allow%s %s from %s %s to %s %s out %s %s keep-state\n",
                              logit, proto, src, sports, dst,
                              dports, icmp_code, via);
                        fprintf(fout,
                              "$ipfw -f add allow%s %s from %s %s to %s %s in %s %s keep-state\n",
                              logit, proto, dst, dports, src,
                              sports, icmp_code, via);
                  } else {
                        /* XXX stateful needed here */
                        fprintf(fout,
                              "# (warning. A stateful firewall would be better here); you could use ipfw4.\n");
                        fprintf(fout,
                              "$ipfw -f add allow%s %s from %s %s to %s %s out %s %s\n",
                              logit, proto, src, sports, dst,
                              dports, icmp_code, via);
                        fprintf(fout,
                              "$ipfw -f add allow%s %s from %s %s to %s %s in %s %s\n",
                              logit, proto, dst, dports, src,
                              sports, icmp_code, via);
                  }
            }
            break;

      case ACCEPT_TWO_WAYS_ESTABLISHED_REVERSE:
            if (!strcmp(proto, "tcp")) {
                  fprintf(fout,
                        "$ipfw -f add allow%s %s from %s %s to %s %s in %s\n",
                        logit, proto, dst, dports, src, sports, via);
                  fprintf(fout,
                        "$ipfw -f add deny%s %s from %s %s to %s %s out setup %s\n",
                        logit, proto, src, sports, dst, dports, via);
                  fprintf(fout,
                        "$ipfw -f add accept%s %s from %s %s to %s %s out %s\n",
                        logit, proto, src, sports, dst, dports, via);
            } else {
                  /* XXX stateful needed here */
                  fprintf(fout,
                        "# (warning. A stateful firewall would be better here)\n");
                  fprintf(fout,
                        "$ipfw -f add allow%s %s from %s %s to %s %s in %s %s\n",
                        logit, proto, dst, dports, src, sports, icmp_code, via);
                  fprintf(fout,
                        "$ipfw -f add allow%s %s from %s %s to %s %s out %s %s\n",
                        logit, proto, src, sports, dst, dports, icmp_code, via);
            }
            break;
      case DENY_ALL:
            fprintf(fout,
                  "$ipfw -f add deny%s %s from %s %s to %s %s out %s %s\n",
                  logit, proto, src, sports, dst, dports, icmp_code, via);
            fprintf(fout,
                  "$ipfw -f add deny%s %s from %s %s to %s %s in %s %s\n",
                  logit, proto, dst, dports, src, sports, icmp_code, via);
            break;
      case REJECT_ALL:
            /* Add an additional rule to correctly reject tcp when rejecting all */
            if (!strcmp(proto, "all")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s tcp from %s %s to %s %s out %s %s\n",
                        logit, src, sports, dst, dports, icmp_code, via);
                  fprintf(fout,
                        "$ipfw -f add reset%s tcp from %s %s to %s %s in %s %s\n",
                        logit, dst, dports, src, sports, icmp_code, via);
            }
            /* Correctly reject tcp */
            if (!strcmp(proto, "tcp")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s %s from %s %s to %s %s out %s %s\n",
                        logit, proto, src, sports, dst, dports, icmp_code, via);
                  fprintf(fout,
                        "$ipfw -f add reset%s %s from %s %s to %s %s in %s %s\n",
                        logit, proto, dst, dports, src, sports, icmp_code, via);
            } else {
                  fprintf(fout,
                        "$ipfw -f add reject%s %s from %s %s to %s %s out %s %s\n",
                        logit, proto, src, sports, dst, dports, icmp_code, via);
                  fprintf(fout,
                        "$ipfw -f add reject%s %s from %s %s to %s %s in %s %s\n",
                        logit, proto, dst, dports, src, sports, icmp_code, via);
            }
            break;
      case DENY_OUT:
            fprintf(fout,
                  "$ipfw -f add deny%s %s from %s %s to %s %s out %s %s\n",
                  logit, proto, src, sports, dst, dports, icmp_code, via);
            break;
      case DENY_IN:
            fprintf(fout,
                  "$ipfw -f add deny%s %s from %s %s to %s %s in %s %s\n",
                  logit, proto, dst, dports, src, sports, icmp_code, via);
            break;
      case REJECT_OUT:
            /* Add an additional rule to correctly reject tcp when rejecting all */
            if (!strcmp(proto, "all")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s tcp from %s %s to %s %s out %s %s\n",
                        logit, src, sports, dst, dports, icmp_code, via);
            }
            /* Correctly reject tcp */
            if (!strcmp(proto, "tcp")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s %s from %s %s to %s %s out %s %s\n",
                        logit, proto, src, sports, dst, dports, icmp_code, via);
            } else {
                  fprintf(fout,
                        "$ipfw -f add reject%s %s from %s %s to %s %s out %s %s\n",
                        logit, proto, src, sports, dst, dports, icmp_code, via);
            }
            break;
      case REJECT_IN:
            /* Add an additional rule to correctly reject tcp when rejecting all */
            if (!strcmp(proto, "all")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s tcp from %s %s to %s %s in %s %s\n",
                        logit, dst, dports, src, sports, icmp_code, via);
            }
            /* Correctly reject tcp */
            if (!strcmp(proto, "tcp")) {
                  fprintf(fout,
                        "$ipfw -f add reset%s %s from %s %s to %s %s in %s %s\n",
                        logit, proto, dst, dports, src, sports, icmp_code, via);
            } else {
                  fprintf(fout,
                        "$ipfw -f add reject%s %s from %s %s to %s %s in %s %s\n",
                        logit, proto, dst, dports, src, sports, icmp_code, via);
            }
            break;
      }
      free(via);
      if (icmp(proto)) {
            free(icmp_code);
      }
      return 0;
}

int translate_bsd_ipfw_start(FILE * output_file)
{
      fout = output_file;

      fprintf(fout, "#!/bin/sh\n#\n");
      fprintf(fout, "# Firewall rules generated by hlfl\n\n");

      fprintf(fout, "ipfw=\"/sbin/ipfw -q\"\n\n");
      fprintf(fout, "$ipfw -f flush\n\n");

      fprintf(fout, "$ipfw -f add check-state\n\n");

      return 0;
}

void print_comment_ipfw(buffer)
char *buffer;
{
      fprintf(fout, "#%s", buffer);
}

void include_text_ipfw(c)
char *c;
{
      if (!strncmp("if(", c, 3)) {
            if (!strncmp("if(ipfw)", c, strlen("if(ipfw)"))) {
                  matched_if = 1;
                  fprintf(fout, "%s", c + strlen("if(ipfw)"));
            } else
                  matched_if = 0;
      } else
            fprintf(fout, "%s", c);
}

Generated by  Doxygen 1.6.0   Back to index