Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

fw-ipchains.c

Go to the documentation of this file.
00001 /*
00002  * fw-ipchains.c
00003  *
00004  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: fw-ipchains.c,v 1.8 2004/05/05 21:25:20 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include <sys/types.h>
00012 #include <sys/socket.h>
00013 
00014 #include <netinet/in.h>
00015 #include <netinet/ip.h>
00016 #include <netinet/tcp.h>
00017 #include <netinet/udp.h>
00018 #undef __USE_BSD
00019 #include <netinet/ip_icmp.h>
00020 #include <linux/if.h>
00021 #ifdef HAVE_LINUX_IP_FW_H
00022 #include <linux/ip_fw.h>
00023 #elif defined(HAVE_LINUX_IP_FWCHAINS_H)
00024 #include <linux/ip_fwchains.h>
00025 #elif defined(HAVE_LINUX_NETFILTER_IPV4_IPCHAINS_CORE_H)
00026 #include <linux/netfilter_ipv4/ipchains_core.h>
00027 #endif
00028 
00029 #include <assert.h>
00030 #include <errno.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035 
00036 #include "dnet.h"
00037 
00038 #define PROC_IPCHAINS_FILE      "/proc/net/ip_fwchains"
00039 
00040 struct fw_handle {
00041         int     fd;
00042 };
00043 
00044 static void
00045 fr_to_fwc(const struct fw_rule *fr, struct ip_fwchange *fwc)
00046 {
00047         memset(fwc, 0, sizeof(*fwc));
00048 
00049         strlcpy(fwc->fwc_rule.ipfw.fw_vianame, fr->fw_device, IFNAMSIZ);
00050         
00051         if (fr->fw_op == FW_OP_ALLOW)
00052                 strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_ACCEPT, 
00053                     sizeof(fwc->fwc_rule.label));
00054         else
00055                 strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_BLOCK,
00056                     sizeof(fwc->fwc_rule.label));
00057 
00058         if (fr->fw_dir == FW_DIR_IN)
00059                 strlcpy(fwc->fwc_label, IP_FW_LABEL_INPUT,
00060                     sizeof(fwc->fwc_label));
00061         else
00062                 strlcpy(fwc->fwc_label, IP_FW_LABEL_OUTPUT,
00063                     sizeof(fwc->fwc_label));
00064         
00065         fwc->fwc_rule.ipfw.fw_proto = fr->fw_proto;
00066         fwc->fwc_rule.ipfw.fw_src.s_addr = fr->fw_src.addr_ip;
00067         fwc->fwc_rule.ipfw.fw_dst.s_addr = fr->fw_dst.addr_ip;
00068         addr_btom(fr->fw_src.addr_bits, &fwc->fwc_rule.ipfw.fw_smsk.s_addr,
00069             IP_ADDR_LEN);
00070         addr_btom(fr->fw_dst.addr_bits, &fwc->fwc_rule.ipfw.fw_dmsk.s_addr,
00071             IP_ADDR_LEN);
00072 
00073         /* XXX - ICMP? */
00074         fwc->fwc_rule.ipfw.fw_spts[0] = fr->fw_sport[0];
00075         fwc->fwc_rule.ipfw.fw_spts[1] = fr->fw_sport[1];
00076         fwc->fwc_rule.ipfw.fw_dpts[0] = fr->fw_dport[0];
00077         fwc->fwc_rule.ipfw.fw_dpts[1] = fr->fw_dport[1];
00078 }
00079 
00080 static void
00081 fwc_to_fr(const struct ip_fwchange *fwc, struct fw_rule *fr)
00082 {
00083         memset(fr, 0, sizeof(*fr));
00084 
00085         strlcpy(fr->fw_device, fwc->fwc_rule.ipfw.fw_vianame,
00086             sizeof(fr->fw_device));
00087 
00088         if (strcmp(fwc->fwc_rule.label, IP_FW_LABEL_ACCEPT) == 0)
00089                 fr->fw_op = FW_OP_ALLOW;
00090         else
00091                 fr->fw_op = FW_OP_BLOCK;
00092 
00093         if (strcmp(fwc->fwc_label, IP_FW_LABEL_INPUT) == 0)
00094                 fr->fw_dir = FW_DIR_IN;
00095         else
00096                 fr->fw_dir = FW_DIR_OUT;
00097 
00098         fr->fw_proto = fwc->fwc_rule.ipfw.fw_proto;
00099         fr->fw_src.addr_type = fr->fw_dst.addr_type = ADDR_TYPE_IP;
00100         fr->fw_src.addr_ip = fwc->fwc_rule.ipfw.fw_src.s_addr;
00101         fr->fw_dst.addr_ip = fwc->fwc_rule.ipfw.fw_dst.s_addr;
00102         addr_mtob(&fwc->fwc_rule.ipfw.fw_smsk.s_addr, IP_ADDR_LEN,
00103             &fr->fw_src.addr_bits);
00104         addr_mtob(&fwc->fwc_rule.ipfw.fw_dmsk.s_addr, IP_ADDR_LEN,
00105             &fr->fw_dst.addr_bits);
00106 
00107         /* XXX - ICMP? */
00108         fr->fw_sport[0] = fwc->fwc_rule.ipfw.fw_spts[0];
00109         fr->fw_sport[1] = fwc->fwc_rule.ipfw.fw_spts[1];
00110         fr->fw_dport[0] = fwc->fwc_rule.ipfw.fw_dpts[0];
00111         fr->fw_dport[1] = fwc->fwc_rule.ipfw.fw_dpts[1];
00112 }
00113 
00114 fw_t *
00115 fw_open(void)
00116 {
00117         fw_t *fw;
00118 
00119         if ((fw = calloc(1, sizeof(*fw))) != NULL) {
00120                 if ((fw->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
00121                         return (fw_close(fw));
00122         }
00123         return (fw);
00124 }
00125 
00126 int
00127 fw_add(fw_t *fw, const struct fw_rule *rule)
00128 {
00129         struct ip_fwchange fwc;
00130 
00131         fr_to_fwc(rule, &fwc);
00132         
00133         return (setsockopt(fw->fd, IPPROTO_IP, IP_FW_APPEND,
00134             &fwc, sizeof(fwc)));
00135 }
00136 
00137 int
00138 fw_delete(fw_t *fw, const struct fw_rule *rule)
00139 {
00140         struct ip_fwchange fwc;
00141 
00142         fr_to_fwc(rule, &fwc);
00143         
00144         return (setsockopt(fw->fd, IPPROTO_IP, IP_FW_DELETE,
00145             &fwc, sizeof(fwc)));
00146 }
00147 
00148 int
00149 fw_loop(fw_t *fw, fw_handler callback, void *arg)
00150 {
00151         FILE *fp;
00152         struct ip_fwchange fwc;
00153         struct fw_rule fr;
00154         char buf[BUFSIZ];
00155         u_int phi, plo, bhi, blo, tand, txor;
00156         int ret;
00157         
00158         if ((fp = fopen(PROC_IPCHAINS_FILE, "r")) == NULL)
00159                 return (-1);
00160 
00161         while (fgets(buf, sizeof(buf), fp) != NULL) {
00162                 if (sscanf(buf,
00163                     "%8s %X/%X->%X/%X %s %hX %hX %hu %u %u %u %u "
00164                     "%hu-%hu %hu-%hu A%X X%X %hX %u %hu %s\n",
00165                     fwc.fwc_label,
00166                     &fwc.fwc_rule.ipfw.fw_src.s_addr,
00167                     &fwc.fwc_rule.ipfw.fw_smsk.s_addr,
00168                     &fwc.fwc_rule.ipfw.fw_dst.s_addr,
00169                     &fwc.fwc_rule.ipfw.fw_dmsk.s_addr,
00170                     fwc.fwc_rule.ipfw.fw_vianame,
00171                     &fwc.fwc_rule.ipfw.fw_flg,
00172                     &fwc.fwc_rule.ipfw.fw_invflg,
00173                     &fwc.fwc_rule.ipfw.fw_proto,
00174                     &phi, &plo, &bhi, &blo,
00175                     &fwc.fwc_rule.ipfw.fw_spts[0],
00176                     &fwc.fwc_rule.ipfw.fw_spts[1],
00177                     &fwc.fwc_rule.ipfw.fw_dpts[0],
00178                     &fwc.fwc_rule.ipfw.fw_dpts[1],
00179                     &tand, &txor,
00180                     &fwc.fwc_rule.ipfw.fw_redirpt,
00181                     &fwc.fwc_rule.ipfw.fw_mark,
00182                     &fwc.fwc_rule.ipfw.fw_outputsize,
00183                     fwc.fwc_rule.label) != 23)
00184                         break;
00185 
00186                 if (strcmp(fwc.fwc_rule.label, IP_FW_LABEL_ACCEPT) != 0 &&
00187                     strcmp(fwc.fwc_rule.label, IP_FW_LABEL_BLOCK) != 0 &&
00188                     strcmp(fwc.fwc_rule.label, IP_FW_LABEL_REJECT) != 0)
00189                         continue;
00190                 if (strcmp(fwc.fwc_label, IP_FW_LABEL_INPUT) != 0 &&
00191                     strcmp(fwc.fwc_label, IP_FW_LABEL_OUTPUT) != 0)
00192                         continue;
00193                 if (strcmp(fwc.fwc_rule.label, "-") == 0)
00194                         (fwc.fwc_rule.label)[0] = '\0';
00195                 if (strcmp(fwc.fwc_rule.ipfw.fw_vianame, "-") == 0)
00196                         (fwc.fwc_rule.ipfw.fw_vianame)[0] = '\0';
00197                 fwc.fwc_rule.ipfw.fw_src.s_addr =
00198                     htonl(fwc.fwc_rule.ipfw.fw_src.s_addr);
00199                 fwc.fwc_rule.ipfw.fw_dst.s_addr =
00200                     htonl(fwc.fwc_rule.ipfw.fw_dst.s_addr);
00201                 fwc.fwc_rule.ipfw.fw_smsk.s_addr =
00202                     htonl(fwc.fwc_rule.ipfw.fw_smsk.s_addr);
00203                 fwc.fwc_rule.ipfw.fw_dmsk.s_addr =
00204                     htonl(fwc.fwc_rule.ipfw.fw_dmsk.s_addr);
00205                 
00206                 fwc_to_fr(&fwc, &fr);
00207                 
00208                 if ((ret = callback(&fr, arg)) != 0) {
00209                         fclose(fp);
00210                         return (ret);
00211                 }
00212         }
00213         fclose(fp);
00214         
00215         return (0);
00216 }
00217 
00218 fw_t *
00219 fw_close(fw_t *fw)
00220 {
00221         if (fw != NULL) {
00222                 if (fw->fd >= 0)
00223                         close(fw->fd);
00224                 free(fw);
00225         }
00226         return (NULL);
00227 }

Generated on Sun May 14 14:51:11 2006 by  doxygen 1.4.2