summaryrefslogtreecommitdiffhomepage
path: root/contrib/fwd
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fwd')
-rw-r--r--contrib/fwd/Makefile2
-rw-r--r--contrib/fwd/src/Makefile18
-rw-r--r--contrib/fwd/src/fwd.c320
-rw-r--r--contrib/fwd/src/fwd.h182
-rw-r--r--contrib/fwd/src/fwd_addr.c162
-rw-r--r--contrib/fwd/src/fwd_addr.h50
-rw-r--r--contrib/fwd/src/fwd_config.c987
-rw-r--r--contrib/fwd/src/fwd_config.h29
-rw-r--r--contrib/fwd/src/fwd_ipc.c98
-rw-r--r--contrib/fwd/src/fwd_ipc.h61
-rw-r--r--contrib/fwd/src/fwd_rules.c886
-rw-r--r--contrib/fwd/src/fwd_rules.h32
-rw-r--r--contrib/fwd/src/fwd_utils.c78
-rw-r--r--contrib/fwd/src/fwd_utils.h50
-rw-r--r--contrib/fwd/src/fwd_xtables.c412
-rw-r--r--contrib/fwd/src/fwd_xtables.h70
-rw-r--r--contrib/fwd/src/ucix.c236
-rw-r--r--contrib/fwd/src/ucix.h50
18 files changed, 0 insertions, 3723 deletions
diff --git a/contrib/fwd/Makefile b/contrib/fwd/Makefile
deleted file mode 100644
index f7fac7740..000000000
--- a/contrib/fwd/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-include ../../build/config.mk
-include ../../build/module.mk
diff --git a/contrib/fwd/src/Makefile b/contrib/fwd/src/Makefile
deleted file mode 100644
index 43749124a..000000000
--- a/contrib/fwd/src/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-CFLAGS := -ggdb3 -O0 -Wall -I./uci -I./iptables-1.4.5/include
-LDFLAGS := -luci -liptc -lxtables -ldl -L./iptables-1.4.5/libiptc/.libs -L./iptables-1.4.5/.libs -Wl,--export-dynamic
-
-fwd:
- $(CC) $(CFLAGS) -c -o ucix.o ucix.c
- $(CC) $(CFLAGS) -c -o fwd_addr.o fwd_addr.c
- $(CC) $(CFLAGS) -c -o fwd_rules.o fwd_rules.c
- $(CC) $(CFLAGS) -c -o fwd_config.o fwd_config.c
- $(CC) $(CFLAGS) -c -o fwd_xtables.o fwd_xtables.c
- $(CC) $(CFLAGS) -c -o fwd_ipc.o fwd_ipc.c
- $(CC) $(CFLAGS) -c -o fwd_utils.o fwd_utils.c
- $(CC) $(CFLAGS) -c -o fwd.o fwd.c
- $(CC) $(LDFLAGS) -o fwd fwd.o fwd_addr.o fwd_rules.o fwd_config.o fwd_xtables.o fwd_ipc.o fwd_utils.o ucix.o
- ln -s fwd fw
-
-clean:
- rm -f *~ fwd fw *.o
-
diff --git a/contrib/fwd/src/fwd.c b/contrib/fwd/src/fwd.c
deleted file mode 100644
index 662524e35..000000000
--- a/contrib/fwd/src/fwd.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - main part
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_addr.h"
-#include "fwd_rules.h"
-#include "fwd_config.h"
-#include "fwd_xtables.h"
-#include "fwd_ipc.h"
-#include "fwd_utils.h"
-
-
-static void fwd_foreach_network(
- struct fwd_handle *h,
- void (*cb)(struct fwd_handle *h, struct fwd_network *net)
-) {
- struct fwd_data *data;
- struct fwd_network *net;
-
- for( data = h->conf; data; data = data->next )
- {
- if( data->type != FWD_S_ZONE )
- continue;
-
- for( net = data->section.zone.networks; net; net = net->next )
- cb(h, net);
- }
-}
-
-static void fwd_addif_all_cb(struct fwd_handle *h, struct fwd_network *net)
-{
- fwd_ipt_addif(h, net->name);
-}
-
-static void fwd_delif_all_cb(struct fwd_handle *h, struct fwd_network *net)
-{
- fwd_ipt_delif(h, net->name);
-}
-
-#define fwd_addif_all(h) fwd_foreach_network(h, fwd_addif_all_cb)
-#define fwd_delif_all(h) fwd_foreach_network(h, fwd_delif_all_cb)
-
-
-static int fwd_server_main(int argc, const char *argv[])
-{
- struct fwd_handle *h;
- struct fwd_network *net;
- struct fwd_addr *addrs;
- struct fwd_data *data;
- struct fwd_cidr *addr_old, *addr_new;
- struct sigaction sa;
- int unix_client;
-
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
-
- if( getuid() > 0 )
- fwd_fatal("Need root permissions!");
-
- if( !(h = fwd_alloc_ptr(struct fwd_handle)) )
- fwd_fatal("Out of memory");
-
- if( (h->rtnl_socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1 )
- fwd_fatal("Failed to create AF_NETLINK socket (%m)");
-
- if( (h->unix_socket = fwd_ipc_listen()) == -1 )
- fwd_fatal("Failed to create AF_UNIX socket (%m)");
-
- if( !(h->conf = fwd_read_config(h)) )
- fwd_fatal("Failed to read configuration");
-
- fwd_log_init();
-
- fwd_ipt_build_ruleset(h);
- fwd_addif_all(h);
-
- while(1)
- {
- if( (addrs = fwd_get_addrs(h->rtnl_socket, AF_INET)) != NULL )
- {
- for( data = h->conf; data; data = data->next )
- {
- if( data->type != FWD_S_ZONE )
- continue;
-
- for( net = data->section.zone.networks; net; net = net->next )
- {
- addr_new = fwd_lookup_addr(addrs, net->ifname);
- addr_old = net->addr;
-
- if( !fwd_empty_cidr(addr_new) && fwd_empty_cidr(addr_old) )
- {
- fwd_log_info(
- "Interface %s brought up - adding rules",
- net->ifname
- );
-
- fwd_update_cidr(addr_old, addr_new);
- fwd_ipt_addif(h, net->name);
- }
- else if( fwd_empty_cidr(addr_new) && !fwd_empty_cidr(addr_old) )
- {
- fwd_log_info(
- "Interface %s went down - removing rules",
- net->ifname
- );
-
- fwd_update_cidr(addr_old, NULL);
- fwd_ipt_delif(h, net->name);
- }
- else if( ! fwd_equal_cidr(addr_old, addr_new) )
- {
- fwd_log_info(
- "Interface %s changed IP - rebuilding rules",
- net->ifname
- );
-
- fwd_update_cidr(addr_old, addr_new);
- fwd_ipt_chgif(h, net->name);
- }
- }
- }
-
- fwd_free_addrs(addrs);
- }
-
-
- if( (unix_client = fwd_ipc_accept(h->unix_socket)) > -1 )
- {
- struct fwd_ipc_msg msg;
- memset(&msg, 0, sizeof(struct fwd_ipc_msg));
-
- while( fwd_ipc_recvmsg(unix_client, &msg, sizeof(struct fwd_ipc_msg)) > 0 )
- {
- fwd_log_info("Got message [%i]", msg.type);
-
- switch(msg.type)
- {
- case FWD_IPC_FLUSH:
- fwd_log_info("Flushing rules ...");
- fwd_ipt_clear_ruleset(h);
- fwd_ipc_sendtype(unix_client, FWD_IPC_OK);
- break;
-
- case FWD_IPC_BUILD:
- fwd_log_info("Building rules ...");
- fwd_ipt_clear_ruleset(h);
- fwd_ipt_build_ruleset(h);
- fwd_addif_all(h);
- fwd_ipc_sendtype(unix_client, FWD_IPC_OK);
- break;
-
- case FWD_IPC_RELOAD:
- if( (data = fwd_read_config(h)) != NULL )
- {
- fwd_log_info("Flushing rules ...");
- fwd_ipt_clear_ruleset(h);
- fwd_free_config(h->conf);
- h->conf = data;
- fwd_log_info("Building rules ...");
- fwd_ipt_build_ruleset(h);
- fwd_addif_all(h);
- fwd_ipc_sendtype(unix_client, FWD_IPC_OK);
- }
- else
- {
- fwd_log_err("Cannot reload configuration!");
- fwd_ipc_sendtype(unix_client, FWD_IPC_ERROR);
- }
- break;
-
- case FWD_IPC_ADDIF:
- case FWD_IPC_DELIF:
- if( strlen(msg.data.network) > 0 )
- {
- fwd_ipt_delif(h, msg.data.network);
-
- if( msg.type == FWD_IPC_ADDIF )
- fwd_ipt_addif(h, msg.data.network);
-
- fwd_ipc_sendtype(unix_client, FWD_IPC_OK);
- }
- else
- {
- fwd_log_err("No network name provided!");
- fwd_ipc_sendtype(unix_client, FWD_IPC_ERROR);
- }
- break;
-
- case FWD_IPC_OK:
- case FWD_IPC_ERROR:
- break;
- }
- }
-
- fwd_ipc_shutdown(unix_client);
- }
-
-
- sleep(1);
- }
-
- fwd_delif_all(h);
- fwd_ipt_clear_ruleset(h);
-
- close(h->rtnl_socket);
- fwd_free_config(h->conf);
- fwd_free_ptr(h);
-
- return 0;
-}
-
-static void fwd_client_usage(const char *msg)
-{
- printf(
- "%s\n\n"
- "Usage:\n"
- " fw flush\n"
- " Flush all rules in the firewall and reset policy\n\n"
- " fw build\n"
- " Rebuild firewall rules\n\n"
- " fw reload\n"
- " Reload configuration and rebuild firewall rules\n\n"
- " fw addif {network}\n"
- " Add rules for given network\n\n"
- " fw delif {network}\n"
- " Remove rules for given network\n\n"
- "", msg
- );
-
- exit(1);
-}
-
-static int fwd_client_main(int argc, const char *argv[])
-{
- int unix_server;
- struct fwd_ipc_msg msg;
- enum fwd_ipc_msgtype type;
-
- if( argc < 2 )
- fwd_client_usage("Command required");
-
- if( (unix_server = fwd_ipc_connect()) < 0 )
- fwd_fatal("Cannot connect to server instance (%m)");
-
-
- memset(&msg, 0, sizeof(struct fwd_ipc_msg));
-
- if( !strcmp(argv[1], "flush") )
- type = FWD_IPC_FLUSH;
-
- else if( !strcmp(argv[1], "build") )
- type = FWD_IPC_BUILD;
-
- else if( !strcmp(argv[1], "reload") )
- type = FWD_IPC_RELOAD;
-
- else if( !strcmp(argv[1], "addif") || !strcmp(argv[1], "delif") )
- {
- if( argc < 3 )
- fwd_client_usage("The command requires a parameter.");
-
- type = strcmp(argv[1], "addif") ? FWD_IPC_DELIF : FWD_IPC_ADDIF;
- strncpy(msg.data.network, argv[2], sizeof(msg.data.network));
- }
-
- else
- fwd_client_usage("Invalid command given.");
-
- msg.type = type;
- fwd_ipc_sendmsg(unix_server, &msg, sizeof(struct fwd_ipc_msg));
-
- memset(&msg, 0, sizeof(struct fwd_ipc_msg));
-
- while( fwd_ipc_recvmsg(unix_server, &msg, sizeof(struct fwd_ipc_msg)) == 0 )
- continue;
-
- switch(msg.type)
- {
- case FWD_IPC_OK:
- printf("Success\n");
- break;
-
- case FWD_IPC_ERROR:
- printf("The server reported an error, check logread!\n");
- break;
-
- default:
- fwd_fatal("Unexpected response type %i", msg.type);
- }
-
- fwd_ipc_shutdown(unix_server);
-
- return 0;
-}
-
-int main(int argc, const char *argv[])
-{
- if( strstr(argv[0], "fwd") )
- return fwd_server_main(argc, argv);
- else
- return fwd_client_main(argc, argv);
-}
-
diff --git a/contrib/fwd/src/fwd.h b/contrib/fwd/src/fwd.h
deleted file mode 100644
index 6de8b880c..000000000
--- a/contrib/fwd/src/fwd.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - data structures
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __FWD_H__
-#define __FWD_H__
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <signal.h>
-#include <netinet/in.h>
-
-
-enum fwd_policy {
- FWD_P_UNSPEC = 0,
- FWD_P_DROP = 1,
- FWD_P_REJECT = 2,
- FWD_P_ACCEPT = 3
-};
-
-enum fwd_stype {
- FWD_S_DEFAULTS = 0,
- FWD_S_ZONE = 1,
- FWD_S_FORWARD = 2,
- FWD_S_REDIRECT = 3,
- FWD_S_RULE = 4,
- FWD_S_INCLUDE = 5
-};
-
-enum fwd_ptype {
- FWD_PR_CUSTOM = 0,
- FWD_PR_TCP = 1,
- FWD_PR_UDP = 2,
- FWD_PR_TCPUDP = 3,
- FWD_PR_ICMP = 4,
- FWD_PR_ALL = 5
-};
-
-struct fwd_portrange {
- unsigned short min;
- unsigned short max;
-};
-
-struct fwd_cidr {
- struct in_addr addr;
- int prefix;
-};
-
-struct fwd_mac {
- unsigned char mac[6];
-};
-
-struct fwd_proto {
- enum fwd_ptype type;
- int proto;
-};
-
-struct fwd_icmptype {
- char name[32];
- int type;
- int code;
-};
-
-struct fwd_network {
- char *name;
- char *ifname;
- int isalias;
- struct fwd_cidr *addr;
- struct fwd_network *next;
-};
-
-struct fwd_defaults {
- enum fwd_policy input;
- enum fwd_policy forward;
- enum fwd_policy output;
- int syn_flood;
- int syn_rate;
- int syn_burst;
- int drop_invalid;
-};
-
-struct fwd_zone {
- char *name;
- struct fwd_network *networks;
- struct fwd_data *forwardings;
- struct fwd_data *redirects;
- struct fwd_data *rules;
- enum fwd_policy input;
- enum fwd_policy forward;
- enum fwd_policy output;
- int masq;
- int mtu_fix;
- int conntrack;
-};
-
-struct fwd_forwarding {
- struct fwd_zone *src;
- struct fwd_zone *dest;
- int mtu_fix; /* legacy */
- int masq; /* new */
-};
-
-struct fwd_redirect {
- struct fwd_zone *src;
- struct fwd_cidr *src_ip;
- struct fwd_mac *src_mac;
- struct fwd_portrange *src_port;
- struct fwd_portrange *src_dport;
- struct fwd_cidr *dest_ip;
- struct fwd_portrange *dest_port;
- struct fwd_proto *proto;
- int clone; /* true if rule is cloned (tcpudp -> tcp + udp) */
-};
-
-struct fwd_rule {
- struct fwd_zone *src;
- struct fwd_zone *dest;
- struct fwd_cidr *src_ip;
- struct fwd_mac *src_mac;
- struct fwd_portrange *src_port;
- struct fwd_cidr *dest_ip;
- struct fwd_portrange *dest_port;
- struct fwd_proto *proto;
- struct fwd_icmptype *icmp_type;
- enum fwd_policy target;
- int clone; /* true if rule is cloned (tcpudp -> tcp + udp) */
-};
-
-struct fwd_include {
- char *path;
-};
-
-struct fwd_data {
- enum fwd_stype type;
- struct fwd_data *next;
- union {
- struct fwd_defaults defaults;
- struct fwd_zone zone;
- struct fwd_forwarding forwarding;
- struct fwd_redirect redirect;
- struct fwd_rule rule;
- struct fwd_include include;
- } section;
-};
-
-
-struct fwd_handle {
- int rtnl_socket;
- int unix_socket;
- struct fwd_data *conf;
-};
-
-
-/* fwd_fatal(fmt, ...)
- * Prints message to stderr and termintes program. */
-#define fwd_fatal(...) do { \
- fprintf(stderr, "ERROR: "); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- exit(1); \
-} while(0)
-
-
-#endif
diff --git a/contrib/fwd/src/fwd_addr.c b/contrib/fwd/src/fwd_addr.c
deleted file mode 100644
index 62e65aa62..000000000
--- a/contrib/fwd/src/fwd_addr.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - rtnetlink communication
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_addr.h"
-#include "fwd_utils.h"
-
-struct fwd_addr * fwd_get_addrs(int fd, int family)
-{
- struct {
- struct nlmsghdr n;
- struct ifaddrmsg r;
- } req;
-
- int offlen;
- int rtattrlen;
- int dump_done;
- char buf[16384];
-
- struct rtattr *rta;
- struct rtattr *rtatp;
- struct nlmsghdr *nlmp;
- struct ifaddrmsg *rtmp;
-
- struct fwd_addr *head, *entry;
-
- /* Build request */
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
- req.n.nlmsg_type = RTM_GETADDR;
- req.r.ifa_family = family;
-
- rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
- rta->rta_len = RTA_LENGTH(family == AF_INET ? 4 : 16);
-
- head = entry = NULL;
-
- /* Send request */
- if( send(fd, &req, sizeof(req), 0) <= 0 )
- goto error;
-
- /* Receive responses */
- for( dump_done = 0; !dump_done; )
- {
- if( (offlen = recv(fd, buf, sizeof(buf), 0)) <= 0 )
- goto error;
-
- /* Parse message */
- for(nlmp = (struct nlmsghdr *)buf; offlen > sizeof(*nlmp);)
- {
- /* Dump finished? */
- if( nlmp->nlmsg_type == NLMSG_DONE )
- {
- dump_done = 1;
- break;
- }
-
- int len = nlmp->nlmsg_len;
- int req_len = len - sizeof(*nlmp);
-
- if( req_len<0 || len>offlen )
- goto error;
-
- if( !NLMSG_OK(nlmp, offlen) )
- goto error;
-
- rtmp = (struct ifaddrmsg *) NLMSG_DATA(nlmp);
- rtatp = (struct rtattr *) IFA_RTA(rtmp);
-
- if( !(entry = fwd_alloc_ptr(struct fwd_addr)) )
- goto error;
-
- entry->index = rtmp->ifa_index;
- if_indextoname(rtmp->ifa_index, (char *)&entry->ifname);
-
- rtattrlen = IFA_PAYLOAD(nlmp);
-
- for( ; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen) )
- {
- if( rtatp->rta_type == IFA_ADDRESS )
- {
- memcpy(&entry->ipaddr.addr, (char *) RTA_DATA(rtatp), rtatp->rta_len);
- entry->ipaddr.prefix = rtmp->ifa_prefixlen;
- entry->family = family;
- }
- else if( rtatp->rta_type == IFA_LABEL)
- {
- memcpy(&entry->label, (char *) RTA_DATA(rtatp), rtatp->rta_len);
- }
- }
-
- entry->next = head;
- head = entry;
-
- offlen -= NLMSG_ALIGN(len);
- nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
- }
- }
-
- return head;
-
-
- error:
-
- fwd_free_addrs(head);
- head = entry = NULL;
-
- return NULL;
-}
-
-struct fwd_cidr * fwd_lookup_addr(struct fwd_addr *head, const char *ifname)
-{
- struct fwd_addr *entry;
-
- for( entry = head; entry; entry = entry->next )
- if( !strncmp(entry->ifname, ifname, IFNAMSIZ) )
- return &entry->ipaddr;
-
- return NULL;
-}
-
-void fwd_free_addrs(struct fwd_addr *head)
-{
- struct fwd_addr *entry = head;
-
- while( entry != NULL )
- {
- head = entry->next;
- free(entry);
- entry = head;
- }
-
- head = entry = NULL;
-}
-
-struct fwd_addr * fwd_append_addrs(struct fwd_addr *head, struct fwd_addr *add)
-{
- struct fwd_addr *entry = head;
-
- while( entry->next != NULL )
- entry = entry->next;
-
- return (entry->next = add);
-}
-
diff --git a/contrib/fwd/src/fwd_addr.h b/contrib/fwd/src/fwd_addr.h
deleted file mode 100644
index 3cabe09a0..000000000
--- a/contrib/fwd/src/fwd_addr.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - header for rtnetlink communication
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __FWD_ADDR_H__
-#define __FWD_ADDR_H__
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <arpa/inet.h>
-
-
-struct fwd_addr {
- char ifname[IFNAMSIZ];
- char label[IFNAMSIZ];
- int family;
- int index;
- struct fwd_cidr ipaddr;
- struct fwd_addr *next;
-};
-
-
-struct fwd_addr * fwd_get_addrs(int, int);
-struct fwd_addr * fwd_append_addrs(struct fwd_addr *, struct fwd_addr *);
-void fwd_free_addrs(struct fwd_addr *);
-
-struct fwd_cidr * fwd_lookup_addr(struct fwd_addr *, const char *);
-
-#define fwd_foreach_addrs(head, entry) for(entry = head; entry; entry = entry->next)
-
-#endif
-
diff --git a/contrib/fwd/src/fwd_config.c b/contrib/fwd/src/fwd_config.c
deleted file mode 100644
index 320e9ffca..000000000
--- a/contrib/fwd/src/fwd_config.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - config parsing
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_addr.h"
-#include "fwd_config.h"
-#include "fwd_utils.h"
-
-#include "ucix.h"
-
-
-#define fwd_read_error(...) do { \
- fwd_log_err(__VA_ARGS__); \
- return; \
-} while(0)
-
-
-/*
- * Parse helpers
- */
-static int
-fwd_read_policy(struct uci_context *uci, const char *s, const char *o)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
-
- if( val != NULL )
- {
- switch( val[0] )
- {
- case 'D':
- case 'd':
- return FWD_P_DROP;
-
- case 'R':
- case 'r':
- return FWD_P_REJECT;
-
- case 'A':
- case 'a':
- return FWD_P_ACCEPT;
- }
- }
-
- return FWD_P_UNSPEC;
-}
-
-static int
-fwd_read_bool(struct uci_context *uci, const char *s, const char *o, int d)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
-
- if( val != NULL )
- {
- if( !strcmp(val, "yes") || !strcmp(val, "true") || !strcmp(val, "1") )
- return 1;
- else
- return 0;
- }
-
- return d;
-}
-
-static unsigned int
-fwd_read_uint(struct uci_context *uci, const char *s, const char *o, unsigned int d)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
-
- if( val != NULL )
- {
- return atoi(val);
- }
-
- return d;
-}
-
-static int
-fwd_read_cidr(struct uci_context *uci, const char *s, const char *o, struct fwd_cidr **c)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
- char ip[32], prefix[32];
- struct in_addr ina;
-
- memset(ip, 0, 32);
- memset(prefix, 0, 32);
-
- if( val == NULL )
- {
- return 0;
- }
- else if( (strlen(val) < 32) && (sscanf(val, "%[^/]/%s", ip, prefix) > 0) )
- {
- if( !(*c = fwd_alloc_ptr(struct fwd_cidr)) )
- goto inval;
-
- if( inet_aton(ip, &ina) )
- {
- (*c)->addr.s_addr = ina.s_addr;
-
- if( strchr(prefix, '.') )
- {
- if( inet_aton(prefix, &ina) )
- {
- (*c)->prefix = 32;
- ina.s_addr = ntohl(ina.s_addr);
-
- while( !(ina.s_addr & 1) )
- {
- ina.s_addr >>= 1;
- (*c)->prefix--;
- }
- }
- else
- {
- goto inval;
- }
- }
- else
- {
- (*c)->prefix = prefix[0] ? atoi(prefix) : 32;
-
- if( ((*c)->prefix < 0) || ((*c)->prefix > 32) )
- {
- goto inval;
- }
- }
-
- return 0;
- }
- }
-
- inval:
- fwd_free_ptr(*c);
- return -1;
-}
-
-static int
-fwd_read_mac(struct uci_context *uci, const char *s, const char *o, struct fwd_mac **m)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
-
- if( val == NULL )
- {
- return 0;
- }
- else
- {
- if( (*m = fwd_alloc_ptr(struct fwd_mac)) != NULL )
- {
- unsigned int i1, i2, i3, i4, i5, i6;
-
- if( sscanf(val, "%2x:%2x:%2x:%2x:%2x:%2x",
- &i1, &i2, &i3, &i4, &i5, &i6) == 6
- ) {
- (*m)->mac[0] = (unsigned char)i1;
- (*m)->mac[1] = (unsigned char)i2;
- (*m)->mac[2] = (unsigned char)i3;
- (*m)->mac[3] = (unsigned char)i4;
- (*m)->mac[4] = (unsigned char)i5;
- (*m)->mac[5] = (unsigned char)i6;
- return 0;
- }
- }
- }
-
- fwd_free_ptr(*m);
- return -1;
-}
-
-static int
-fwd_read_portrange(struct uci_context *uci, const char *s, const char *o, struct fwd_portrange **p)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
- int min = -1;
- int max = -1;
- unsigned int tmp;
-
- if( val == NULL )
- {
- return 0;
- }
- else if( sscanf(val, "%u%*[:-]%u", &min, &max) > 0 )
- {
- if( max == -1 )
- {
- max = min;
- }
- else if( min > max )
- {
- tmp = max;
- max = min;
- min = tmp;
- }
-
- if( (min >= 0) && (min <= 65535) && (max >= 0) && (max <= 65535) )
- {
- if( (*p = fwd_alloc_ptr(struct fwd_portrange)) != NULL )
- {
- (*p)->min = min;
- (*p)->max = max;
- return 0;
- }
- }
- }
-
- fwd_free_ptr(*p);
- return -1;
-}
-
-static int
-fwd_read_proto(struct uci_context *uci, const char *s, const char *o, struct fwd_proto **p)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
- int proto;
-
- if( val == NULL )
- {
- return 0;
- }
- else
- {
- if( (*p = fwd_alloc_ptr(struct fwd_proto)) != NULL )
- {
- proto = atoi(val);
-
- if( !strcasecmp(val, "all") )
- {
- (*p)->type = FWD_PR_ALL;
- (*p)->proto = 0;
- }
- else if( !strcasecmp(val, "icmp") )
- {
- (*p)->type = FWD_PR_ICMP;
- (*p)->proto = 0;
- }
- else if( !strcasecmp(val, "udp") )
- {
- (*p)->type = FWD_PR_UDP;
- (*p)->proto = 0;
- }
- else if( !strcasecmp(val, "tcp") )
- {
- (*p)->type = FWD_PR_TCP;
- (*p)->proto = 0;
- }
- else if( !strcasecmp(val, "tcpudp") )
- {
- (*p)->type = FWD_PR_TCPUDP;
- (*p)->proto = 0;
- }
- else if( proto > 0 )
- {
- (*p)->type = FWD_PR_CUSTOM;
- (*p)->proto = proto;
- }
- else
- {
- goto inval;
- }
-
- return 0;
- }
- }
-
- inval:
- fwd_free_ptr(*p);
- return -1;
-}
-
-static int
-fwd_read_icmptype(struct uci_context *uci, const char *s, const char *o, struct fwd_icmptype **i)
-{
- const char *val = ucix_get_option(uci, "firewall", s, o);
- unsigned int type, code;
-
- if( val == NULL )
- {
- return 0;
- }
- else
- {
- if( (*i = fwd_alloc_ptr(struct fwd_icmptype)) != NULL )
- {
- if( sscanf(val, "%u/%u", &type, &code) == 2 )
- {
- if( (type > 255) || (code > 255) )
- goto inval;
-
- (*i)->type = type;
- (*i)->code = code;
-
- return 0;
- }
-
- else if( sscanf(val, "%u", &type) == 1 )
- {
- if( type > 255 )
- goto inval;
-
- (*i)->type = type;
- (*i)->code = -1;
-
- return 0;
- }
-
- /* XXX: no validity check here but I do not want to
- duplicate libipt_icmp.c ... */
- else if( sscanf(val, "%31s", (*i)->name) == 1 )
- {
- return 0;
- }
- }
- }
-
- inval:
- fwd_free_ptr(*i);
- return -1;
-}
-
-static const char *
-fwd_read_string(struct uci_context *uci, const char *s, const char *o)
-{
- return ucix_get_option(uci, "firewall", s, o);
-}
-
-
-static void
-fwd_append_config(struct fwd_data *h, struct fwd_data *a)
-{
- while( h->next )
- h = h->next;
-
- h->next = a;
-}
-
-
-/*
- * config defaults
- */
-static void fwd_read_defaults_cb(
- struct uci_context *uci,
- const char *s, struct fwd_defaults *d
-) {
- d->input = fwd_read_policy(uci, s, "input");
- d->forward = fwd_read_policy(uci, s, "forward");
- d->output = fwd_read_policy(uci, s, "output");
- d->syn_flood = fwd_read_bool(uci, s, "syn_flood", 1);
- d->syn_rate = fwd_read_uint(uci, s, "syn_rate", 25);
- d->syn_burst = fwd_read_uint(uci, s, "syn_burst", 50);
- d->drop_invalid = fwd_read_bool(uci, s, "drop_invalid", 1);
-}
-
-static struct fwd_data *
-fwd_read_defaults(struct uci_context *uci)
-{
- struct fwd_data *dt;
- struct fwd_defaults d;
-
- if( (dt = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- memset(&d, 0, sizeof(d));
-
- ucix_for_each_section_type(uci, "firewall", "defaults",
- (void *)fwd_read_defaults_cb, &d);
-
- memcpy(&dt->section.defaults, &d, sizeof(d));
-
- dt->type = FWD_S_DEFAULTS;
- dt->next = NULL;
-
- return dt;
- }
-
- return NULL;
-}
-
-
-/*
- * config zone
- */
-static void fwd_read_zone_networks_cb(
- const char *net, struct fwd_network **np
-) {
- struct fwd_network *nn;
-
- if( (nn = fwd_alloc_ptr(struct fwd_network)) != NULL )
- {
- nn->name = strdup(net);
- nn->next = *np;
- *np = nn;
- }
-}
-
-static void fwd_read_zones_cb(
- struct uci_context *uci,
- const char *s, struct fwd_data_conveyor *cv
-) {
- struct fwd_data *dtn;
- struct fwd_network *net = NULL;
- const char *name;
-
- if( !(name = fwd_read_string(uci, s, "name")) )
- fwd_read_error("section '%s' is missing 'name' option!", s);
-
- if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- dtn->section.zone.name = strdup(name);
- dtn->section.zone.masq = fwd_read_bool(uci, s, "masq", 0);
- dtn->section.zone.mtu_fix = fwd_read_bool(uci, s, "mtu_fix", 0);
- dtn->section.zone.conntrack = fwd_read_bool(uci, s, "conntrack", 0);
-
- dtn->section.zone.input = fwd_read_policy(uci, s, "input")
- ?: cv->head->section.defaults.input ?: FWD_P_DROP;
-
- dtn->section.zone.forward = fwd_read_policy(uci, s, "forward")
- ?: cv->head->section.defaults.forward ?: FWD_P_DROP;
-
- dtn->section.zone.output = fwd_read_policy(uci, s, "output")
- ?: cv->head->section.defaults.output ?: FWD_P_DROP;
-
- /* try to parse option/list network ... */
- if( ucix_for_each_list(uci, "firewall", s, "network",
- (void *)&fwd_read_zone_networks_cb, &net) < 0 )
- {
- /* ... didn't work, fallback to option name */
- fwd_read_zone_networks_cb(name, &net);
- }
-
- dtn->section.zone.networks = net;
- dtn->type = FWD_S_ZONE;
- dtn->next = cv->cursor;
- cv->cursor = dtn;
- }
-}
-
-static struct fwd_data *
-fwd_read_zones(struct uci_context *uci, struct fwd_data *def)
-{
- struct fwd_data_conveyor cv;
-
- cv.cursor = NULL;
- cv.head = def;
-
- ucix_for_each_section_type(uci, "firewall", "zone",
- (void *)fwd_read_zones_cb, &cv);
-
- return cv.cursor;
-}
-
-
-/*
- * config forwarding
- */
-static void fwd_read_forwards_cb(
- struct uci_context *uci,
- const char *s, struct fwd_data_conveyor *cv
-) {
- const char *src, *dest;
- struct fwd_data *dtn;
- struct fwd_zone *zsrc = NULL;
- struct fwd_zone *zdest = NULL;
-
- if( !(src = fwd_read_string(uci, s, "src")) )
- fwd_read_error("section '%s' is missing 'src' option!", s);
- else if( !(zsrc = fwd_lookup_zone(cv->head, src)) )
- fwd_read_error("section '%s' references unknown src zone '%s'!", s, src);
- else if( !(dest = fwd_read_string(uci, s, "dest")) )
- fwd_read_error("section '%s' is missing 'dest' option!", s);
- else if( !(zdest = fwd_lookup_zone(cv->head, dest)) )
- fwd_read_error("section '%s' references unknown dest zone '%s'!", s, dest);
-
- if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- dtn->section.forwarding.src = zsrc;
- dtn->section.forwarding.dest = zdest;
- dtn->section.forwarding.mtu_fix = fwd_read_bool(uci, s, "mtu_fix", 0);
- dtn->section.forwarding.masq = fwd_read_bool(uci, s, "masq", 0);
-
- dtn->type = FWD_S_FORWARD;
-
- if( zsrc )
- {
- dtn->next = zsrc->forwardings;
- zsrc->forwardings = dtn;
- }
- else
- {
- dtn->next = cv->cursor;
- cv->cursor = dtn;
- }
- }
- else
- {
- fwd_read_error("out of memory while parsing config!");
- }
-}
-
-static struct fwd_data *
-fwd_read_forwards(struct uci_context *uci, struct fwd_data *zones)
-{
- struct fwd_data_conveyor cv;
-
- cv.cursor = NULL;
- cv.head = zones;
-
- ucix_for_each_section_type(uci, "firewall", "forwarding",
- (void *)fwd_read_forwards_cb, &cv);
-
- return cv.cursor;
-}
-
-
-/*
- * config redirect
- */
-static void fwd_read_redirects_cb(
- struct uci_context *uci,
- const char *s, struct fwd_data_conveyor *cv
-) {
- const char *src;
- struct fwd_data *dtn = NULL;
- struct fwd_data *dtn2 = NULL;
- struct fwd_zone *zsrc = NULL;
-
- /* check zone */
- if( !(src = fwd_read_string(uci, s, "src")) )
- fwd_read_error(
- "section '%s' is missing 'src' option!",
- s
- );
-
- else if( !(zsrc = fwd_lookup_zone(cv->head, src)) )
- fwd_read_error(
- "section '%s' references unknown src zone '%s'!",
- s, src
- );
-
- /* uci context, section, name, type */
- fwd_check_option(uci, s, src_ip, cidr);
- fwd_check_option(uci, s, src_mac, mac);
- fwd_check_option(uci, s, src_port, portrange);
- fwd_check_option(uci, s, src_dport, portrange);
- fwd_check_option(uci, s, dest_ip, cidr);
- fwd_check_option(uci, s, dest_port, portrange);
- fwd_check_option(uci, s, proto, proto);
-
- if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- dtn->section.redirect.proto = proto;
- dtn->section.redirect.src = zsrc;
- dtn->section.redirect.src_ip = src_ip;
- dtn->section.redirect.src_mac = src_mac;
- dtn->section.redirect.src_port = src_port;
- dtn->section.redirect.src_dport = src_dport;
- dtn->section.redirect.dest_ip = dest_ip;
- dtn->section.redirect.dest_port = dest_port;
-
- dtn->type = FWD_S_REDIRECT;
- dtn->next = zsrc->redirects;
- zsrc->redirects = dtn;
-
- if( (proto != NULL) && (proto->type == FWD_PR_TCPUDP) )
- {
- if( !(dtn2 = fwd_alloc_ptr(struct fwd_data)) ||
- !(dtn2->section.redirect.proto = fwd_alloc_ptr(struct fwd_proto))
- ) {
- fwd_free_ptr(dtn2);
- fwd_read_error("out of memory while parsing config!");
- }
-
- dtn->section.redirect.proto->type = FWD_PR_UDP;
- dtn2->section.redirect.proto->type = FWD_PR_TCP;
-
- dtn2->section.redirect.src = zsrc;
- dtn2->section.redirect.src_ip = src_ip;
- dtn2->section.redirect.src_mac = src_mac;
- dtn2->section.redirect.src_port = src_port;
- dtn2->section.redirect.src_dport = src_dport;
- dtn2->section.redirect.dest_ip = dest_ip;
- dtn2->section.redirect.dest_port = dest_port;
- dtn2->section.redirect.clone = 1;
-
- dtn2->type = FWD_S_REDIRECT;
- dtn2->next = zsrc->redirects;
- zsrc->redirects = dtn2;
- }
- }
- else
- {
- fwd_read_error("out of memory while parsing config!");
- }
-}
-
-static struct fwd_data *
-fwd_read_redirects(struct uci_context *uci, struct fwd_data *zones)
-{
- struct fwd_data_conveyor cv;
-
- cv.cursor = NULL;
- cv.head = zones;
-
- ucix_for_each_section_type(uci, "firewall", "redirect",
- (void *)fwd_read_redirects_cb, &cv);
-
- return cv.cursor;
-}
-
-
-/*
- * config rule
- */
-static void fwd_read_rules_cb(
- struct uci_context *uci,
- const char *s, struct fwd_data_conveyor *cv
-) {
- const char *src, *dest;
- struct fwd_data *dtn = NULL;
- struct fwd_data *dtn2 = NULL;
- struct fwd_zone *zsrc = NULL;
- struct fwd_zone *zdest = NULL;
-
- /* check zones */
- if( !(src = fwd_read_string(uci, s, "src")) )
- fwd_read_error(
- "section '%s' is missing 'src' option!",
- s
- );
-
- else if( !(zsrc = fwd_lookup_zone(cv->head, src)) )
- fwd_read_error(
- "section '%s' references unknown src zone '%s'!",
- s, src
- );
-
- if( (dest = fwd_read_string(uci, s, "dest")) != NULL )
- if( !(zdest = fwd_lookup_zone(cv->head, dest)) )
- fwd_read_error(
- "section '%s' references unknown dest zone '%s'!",
- s, dest
- );
-
- /* uci context, section, name, type */
- fwd_check_option(uci, s, src_ip, cidr);
- fwd_check_option(uci, s, src_mac, mac);
- fwd_check_option(uci, s, src_port, portrange);
- fwd_check_option(uci, s, dest_ip, cidr);
- fwd_check_option(uci, s, dest_port, portrange);
- fwd_check_option(uci, s, proto, proto);
- fwd_check_option(uci, s, icmptype, icmptype);
-
- if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- dtn->section.rule.proto = proto;
- dtn->section.rule.icmp_type = icmptype;
- dtn->section.rule.src = zsrc;
- dtn->section.rule.src_ip = src_ip;
- dtn->section.rule.src_mac = src_mac;
- dtn->section.rule.src_port = src_port;
- dtn->section.rule.dest = zdest;
- dtn->section.rule.dest_ip = dest_ip;
- dtn->section.rule.dest_port = dest_port;
- dtn->section.rule.target = fwd_read_policy(uci, s, "target");
-
- dtn->type = FWD_S_RULE;
- dtn->next = zsrc->rules;
- zsrc->rules = dtn;
-
- if( (proto != NULL) && (proto->type == FWD_PR_TCPUDP) )
- {
- if( !(dtn2 = fwd_alloc_ptr(struct fwd_data)) ||
- !(dtn2->section.rule.proto = fwd_alloc_ptr(struct fwd_proto))
- ) {
- fwd_free_ptr(dtn2);
- fwd_read_error("out of memory while parsing config!");
- }
-
- dtn->section.rule.proto->type = FWD_PR_UDP;
- dtn2->section.rule.proto->type = FWD_PR_TCP;
-
- dtn2->section.rule.src = zsrc;
- dtn2->section.rule.src_ip = src_ip;
- dtn2->section.rule.src_mac = src_mac;
- dtn2->section.rule.src_port = src_port;
- dtn2->section.rule.dest = zdest;
- dtn2->section.rule.dest_ip = dest_ip;
- dtn2->section.rule.dest_port = dest_port;
- dtn2->section.rule.target = dtn->section.rule.target;
- dtn2->section.rule.clone = 1;
-
- dtn2->type = FWD_S_RULE;
- dtn2->next = zsrc->rules;
- zsrc->rules = dtn2;
- }
- }
- else
- {
- fwd_read_error("out of memory while parsing config!");
- }
-}
-
-static struct fwd_data *
-fwd_read_rules(struct uci_context *uci, struct fwd_data *zones)
-{
- struct fwd_data_conveyor cv;
-
- cv.cursor = NULL;
- cv.head = zones;
-
- ucix_for_each_section_type(uci, "firewall", "rule",
- (void *)fwd_read_rules_cb, &cv);
-
- return cv.cursor;
-}
-
-
-/*
- * config include
- */
-static void fwd_read_includes_cb(
- struct uci_context *uci,
- const char *s, struct fwd_data_conveyor *cv
-) {
- const char *path = fwd_read_string(uci, s, "path");
- struct fwd_data *dtn = NULL;
-
- if( path != NULL )
- {
- if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL )
- {
- dtn->section.include.path = strdup(path);
-
- dtn->type = FWD_S_INCLUDE;
- dtn->next = cv->cursor;
- cv->cursor = dtn;
- }
- else
- {
- fwd_read_error("out of memory while parsing config!");
- }
- }
-}
-
-static struct fwd_data *
-fwd_read_includes(struct uci_context *uci)
-{
- struct fwd_data_conveyor cv;
-
- cv.cursor = NULL;
- cv.head = NULL;
-
- ucix_for_each_section_type(uci, "firewall", "include",
- (void *)fwd_read_includes_cb, &cv);
-
- return cv.cursor;
-}
-
-
-/*
- * config interface
- */
-static void fwd_read_network_data(
- struct uci_context *uci, struct fwd_network *net
-) {
- struct fwd_network *e;
- const char *type, *ifname;
-
- for( e = net; e; e = e->next )
- {
- if( (type = ucix_get_option(uci, "network", e->name, NULL)) != NULL )
- {
- if( !(ifname = ucix_get_option(uci, "network", e->name, "ifname")) )
- fwd_read_error(
- "section '%s' is missing 'ifname' option!",
- e->name
- );
-
- e->isalias = (strcmp(type, "alias") ? 0 : 1);
- e->ifname = strdup(ifname);
- }
- }
-}
-
-static void fwd_read_networks(
- struct uci_context *uci, struct fwd_data *zones
-) {
- struct fwd_data *e;
-
- for( e = zones; e; e = e->next )
- if( e->type == FWD_S_ZONE )
- fwd_read_network_data(uci, e->section.zone.networks);
-}
-
-static void fwd_free_networks(struct fwd_network *h)
-{
- struct fwd_network *e = h;
-
- while( h != NULL )
- {
- e = h->next;
-
- fwd_free_ptr(h->name);
- fwd_free_ptr(h->ifname);
- fwd_free_ptr(h->addr);
-
- free(h);
- h = e;
- }
-
- e = h = NULL;
-}
-
-static struct fwd_cidr * fwd_alloc_cidr(struct fwd_cidr *addr)
-{
- struct fwd_cidr *cidr;
-
- if( (cidr = fwd_alloc_ptr(struct fwd_cidr)) != NULL )
- {
- if( addr != NULL )
- {
- cidr->addr.s_addr = addr->addr.s_addr;
- cidr->prefix = addr->prefix;
- }
-
- return cidr;
- }
-
- return NULL;
-}
-
-
-
-struct fwd_data * fwd_read_config(struct fwd_handle *h)
-{
- struct uci_context *ctx;
- struct fwd_data *defaults, *zones, *e;
- struct fwd_addr *addrs;
- struct fwd_network *net;
- struct fwd_zone *zone;
-
- if( (ctx = ucix_init("firewall")) != NULL )
- {
- if( !(defaults = fwd_read_defaults(ctx)) )
- goto error;
-
- if( !(zones = fwd_read_zones(ctx, defaults)) )
- goto error;
-
- fwd_append_config(defaults, zones);
- fwd_append_config(defaults, fwd_read_forwards(ctx, zones));
- fwd_append_config(defaults, fwd_read_redirects(ctx, zones));
- fwd_append_config(defaults, fwd_read_rules(ctx, zones));
- fwd_append_config(defaults, fwd_read_includes(ctx));
-
- ucix_cleanup(ctx);
-
- if( (ctx = ucix_init("network")) != NULL )
- {
- fwd_read_networks(ctx, zones);
- ucix_cleanup(ctx);
-
- if( !(addrs = fwd_get_addrs(h->rtnl_socket, AF_INET)) )
- goto error;
-
- for( e = zones; e && (zone = &e->section.zone); e = e->next )
- {
- if( e->type != FWD_S_ZONE )
- break;
-
- for( net = zone->networks; net; net = net->next )
- {
- net->addr = fwd_alloc_cidr(
- fwd_lookup_addr(addrs, net->ifname)
- );
- }
- }
-
- fwd_free_addrs(addrs);
- return defaults;
- }
- }
-
- error:
- if( ctx ) ucix_cleanup(ctx);
- fwd_free_config(defaults);
- fwd_free_config(zones);
- return NULL;
-}
-
-
-void fwd_free_config(struct fwd_data *h)
-{
- struct fwd_data *e = h;
-
- while( h != NULL )
- {
- e = h->next;
-
- switch(h->type)
- {
- case FWD_S_INCLUDE:
- fwd_free_ptr(h->section.include.path);
- break;
-
- case FWD_S_ZONE:
- fwd_free_ptr(h->section.zone.name);
- fwd_free_networks(h->section.zone.networks);
- fwd_free_config(h->section.zone.rules);
- fwd_free_config(h->section.zone.redirects);
- fwd_free_config(h->section.zone.forwardings);
- break;
-
- case FWD_S_REDIRECT:
- /* Clone rules share all pointers except proto.
- Prevent a double-free here */
- if( ! h->section.redirect.clone )
- {
- fwd_free_ptr(h->section.redirect.src_ip);
- fwd_free_ptr(h->section.redirect.src_mac);
- fwd_free_ptr(h->section.redirect.src_port);
- fwd_free_ptr(h->section.redirect.src_dport);
- fwd_free_ptr(h->section.redirect.dest_ip);
- fwd_free_ptr(h->section.redirect.dest_port);
- }
- fwd_free_ptr(h->section.redirect.proto);
- break;
-
- case FWD_S_RULE:
- /* Clone rules share all pointers except proto.
- Prevent a double-free here */
- if( ! h->section.rule.clone )
- {
- fwd_free_ptr(h->section.rule.src_ip);
- fwd_free_ptr(h->section.rule.src_mac);
- fwd_free_ptr(h->section.rule.src_port);
- fwd_free_ptr(h->section.rule.dest_ip);
- fwd_free_ptr(h->section.rule.dest_port);
- fwd_free_ptr(h->section.rule.icmp_type);
- }
- fwd_free_ptr(h->section.rule.proto);
- break;
-
- case FWD_S_DEFAULTS:
- case FWD_S_FORWARD:
- /* Make gcc happy */
- break;
- }
-
- fwd_free_ptr(h);
- h = e;
- }
-
- e = h = NULL;
-}
-
-
-struct fwd_zone *
-fwd_lookup_zone(struct fwd_data *h, const char *n)
-{
- struct fwd_data *e;
-
- if( n != NULL )
- {
- for( e = h; e; e = e->next )
- {
- if( (e->type = FWD_S_ZONE) && !strcmp(e->section.zone.name, n) )
- return &e->section.zone;
- }
- }
-
- return NULL;
-}
-
diff --git a/contrib/fwd/src/fwd_config.h b/contrib/fwd/src/fwd_config.h
deleted file mode 100644
index 058cff473..000000000
--- a/contrib/fwd/src/fwd_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __FWD_CONFIG_H__
-#define __FWD_CONFIG_H__
-
-#include "fwd.h"
-#include "ucix.h"
-
-/* fwd_check_option(uci_ctx, section, name, type) */
-#define fwd_check_option(uci, sct, name, type) \
- struct fwd_##type *name = NULL; \
- if( fwd_read_##type(uci, sct, #name, &name) ) \
- { \
- printf("ERROR: section '%s' contains invalid %s in '%s'!\n", \
- sct, #type, #name); \
- return; \
- }
-
-/* structure to access fwd_data* in uci iter callbacks */
-struct fwd_data_conveyor {
- struct fwd_data *head;
- struct fwd_data *cursor;
-};
-
-/* api */
-struct fwd_data * fwd_read_config(struct fwd_handle *);
-struct fwd_zone * fwd_lookup_zone(struct fwd_data *, const char *);
-
-void fwd_free_config(struct fwd_data *);
-
-#endif
diff --git a/contrib/fwd/src/fwd_ipc.c b/contrib/fwd/src/fwd_ipc.c
deleted file mode 100644
index 83eb7d886..000000000
--- a/contrib/fwd/src/fwd_ipc.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - unix domain socket parts
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_ipc.h"
-
-
-int fwd_ipc_listen(void)
-{
- int fd;
- struct sockaddr_un addr;
-
- if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
- fwd_fatal("Cannot create AF_UNIX socket: %m");
-
- memset(&addr, 0, sizeof(struct sockaddr_un));
- strcpy(addr.sun_path, FWD_SOCKET_PATH);
- addr.sun_family = AF_UNIX;
-
- unlink(FWD_SOCKET_PATH);
-
- if( bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0 )
- fwd_fatal("Cannot bind AF_UNIX socket: %m");
-
- if( listen(fd, 1) < 0 )
- fwd_fatal("Cannot listen on AF_UNIX socket: %m");
-
- //fcntl(fd, F_SETFL, O_NONBLOCK);
-
- return fd;
-}
-
-int fwd_ipc_accept(int fd)
-{
- return accept(fd, NULL, NULL);
-}
-
-int fwd_ipc_connect(void)
-{
- int fd;
- struct sockaddr_un addr;
-
- if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
- fwd_fatal("Cannot create AF_UNIX socket: %m");
-
- memset(&addr, 0, sizeof(struct sockaddr_un));
- strcpy(addr.sun_path, FWD_SOCKET_PATH);
- addr.sun_family = AF_UNIX;
-
- if( connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0 )
- fwd_fatal("Cannot connect AF_UNIX socket: %m");
-
- fcntl(fd, F_SETFL, O_NONBLOCK);
-
- return fd;
-}
-
-int fwd_ipc_recvmsg(int fd, void *buf, int len)
-{
- return recv(fd, buf, len, 0);
-}
-
-int fwd_ipc_sendmsg(int fd, void *buf, int len)
-{
- return send(fd, buf, len, 0);
-}
-
-void fwd_ipc_shutdown(int fd)
-{
- shutdown(fd, SHUT_RDWR);
- close(fd);
-}
-
-int fwd_ipc_sendtype(int fd, enum fwd_ipc_msgtype type)
-{
- struct fwd_ipc_msg msg;
-
- memset(&msg, 0, sizeof(struct fwd_ipc_msg));
- msg.type = type;
-
- return fwd_ipc_sendmsg(fd, &msg, sizeof(struct fwd_ipc_msg));
-}
diff --git a/contrib/fwd/src/fwd_ipc.h b/contrib/fwd/src/fwd_ipc.h
deleted file mode 100644
index 4a4c9ecc7..000000000
--- a/contrib/fwd/src/fwd_ipc.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - unix domain socket headers
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __FWD_IPC_H__
-#define __FWD_IPC_H__
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#define FWD_SOCKET_PATH "/var/run/fwd.sock"
-
-
-enum fwd_ipc_msgtype {
- FWD_IPC_OK = 0,
- FWD_IPC_ERROR = 1,
- FWD_IPC_FLUSH = 2,
- FWD_IPC_BUILD = 3,
- FWD_IPC_RELOAD = 4,
- FWD_IPC_ADDIF = 5,
- FWD_IPC_DELIF = 6
-};
-
-struct fwd_ipc_msg {
- enum fwd_ipc_msgtype type;
- union {
- char network[256];
- } data;
-};
-
-int fwd_ipc_listen(void);
-int fwd_ipc_accept(int);
-
-int fwd_ipc_connect(void);
-
-int fwd_ipc_recvmsg(int, void *, int);
-int fwd_ipc_sendmsg(int, void *, int);
-
-void fwd_ipc_shutdown(int);
-
-int fwd_ipc_sendtype(int, enum fwd_ipc_msgtype);
-
-#endif
diff --git a/contrib/fwd/src/fwd_rules.c b/contrib/fwd/src/fwd_rules.c
deleted file mode 100644
index b960e62fd..000000000
--- a/contrib/fwd/src/fwd_rules.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - iptables rule set
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_addr.h"
-#include "fwd_rules.h"
-#include "fwd_xtables.h"
-#include "fwd_utils.h"
-
-
-/* -P <chain> <policy> */
-static void fwd_r_set_policy(
- struct iptc_handle *h, const char *chain, const char *policy
-) {
- iptc_set_policy(chain, policy, NULL, h);
-}
-
-/* -N <chain> */
-static void fwd_r_new_chain(struct iptc_handle *h, const char *chain)
-{
- iptc_create_chain(chain, h);
-}
-
-/* -A <chain1> -j <chain2> */
-static void fwd_r_jump_chain(
- struct iptc_handle *h, const char *chain1, const char *chain2
-) {
- struct fwd_xt_rule *r;
-
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- fwd_xt_get_target(r, chain2);
- fwd_xt_append_rule(r, chain1);
- }
-}
-
-/* -A <chain> -m state --state INVALID -j DROP */
-static void fwd_r_drop_invalid(struct iptc_handle *h, const char *chain)
-{
- struct fwd_xt_rule *r;
- struct xtables_match *m;
-
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- if( (m = fwd_xt_get_match(r, "state")) != NULL )
- {
- fwd_xt_parse_match(r, m, "--state", "INVALID");
- fwd_xt_get_target(r, "DROP");
- fwd_xt_append_rule(r, chain);
- }
- }
-}
-
-/* -A <chain> -m state --state RELATED,ESTABLISHED -j ACCEPT */
-static void fwd_r_accept_related(struct iptc_handle *h, const char *chain)
-{
- struct fwd_xt_rule *r;
- struct xtables_match *m;
-
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- if( (m = fwd_xt_get_match(r, "state")) != NULL )
- {
- fwd_xt_parse_match(r, m, "--state", "RELATED,ESTABLISHED");
- fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_append_rule(r, chain);
- }
- }
-}
-
-/* -A INPUT -i lo -j ACCEPT; -A OUTPUT -o lo -j ACCEPT */
-static void fwd_r_accept_lo(struct iptc_handle *h)
-{
- struct fwd_network n;
- struct fwd_xt_rule *r;
-
- n.ifname = "lo";
-
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- fwd_xt_parse_in(r, &n, 0);
- fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_append_rule(r, "INPUT");
- }
-
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- fwd_xt_parse_out(r, &n, 0);
- fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_append_rule(r, "OUTPUT");
- }
-}
-
-/* build syn_flood chain and jump rule */
-static void fwd_r_add_synflood(struct iptc_handle *h, struct fwd_defaults *def)
-{
- struct fwd_proto p;
- struct fwd_xt_rule *r;
- struct xtables_match *m;
- char buf[32];
-
- /* -N syn_flood */
- fwd_r_new_chain(h, "syn_flood");
-
- /* return rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -p tcp */
- p.type = FWD_PR_TCP;
- fwd_xt_parse_proto(r, &p, 0);
-
- /* -m tcp --syn */
- if( (m = fwd_xt_get_match(r, "tcp")) != NULL )
- {
- fwd_xt_parse_match(r, m, "--syn");
- }
-
- /* -m limit --limit x/second --limit-burst y */
- if( (m = fwd_xt_get_match(r, "limit")) != NULL )
- {
- sprintf(buf, "%i/second", def->syn_rate);
- fwd_xt_parse_match(r, m, "--limit", buf);
-
- sprintf(buf, "%i", def->syn_burst);
- fwd_xt_parse_match(r, m, "--limit-burst", buf);
- }
-
- /* -j RETURN; -A syn_flood */
- fwd_xt_get_target(r, "RETURN");
- fwd_xt_append_rule(r, "syn_flood");
- }
-
- /* drop rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -j DROP; -A syn_flood */
- fwd_xt_get_target(r, "DROP");
- fwd_xt_append_rule(r, "syn_flood");
- }
-
- /* jump to syn_flood rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -p tcp */
- p.type = FWD_PR_TCP;
- fwd_xt_parse_proto(r, &p, 0);
-
- /* -m tcp --syn */
- if( (m = fwd_xt_get_match(r, "tcp")) != NULL )
- {
- fwd_xt_parse_match(r, m, "--syn");
- }
-
- /* -j syn_flood; -A INPUT */
- fwd_xt_get_target(r, "syn_flood");
- fwd_xt_append_rule(r, "INPUT");
- }
-}
-
-/* build reject target chain */
-static void fwd_r_handle_reject(struct iptc_handle *h)
-{
- struct fwd_proto p;
- struct fwd_xt_rule *r;
- struct xtables_target *t;
-
- /* -N handle_reject */
- fwd_r_new_chain(h, "handle_reject");
-
- /* tcp reject rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -p tcp */
- p.type = FWD_PR_TCP;
- fwd_xt_parse_proto(r, &p, 0);
-
- /* -j REJECT --reject-with tcp-reset */
- if( (t = fwd_xt_get_target(r, "REJECT")) != NULL )
- {
- fwd_xt_parse_target(r, t, "--reject-with", "tcp-reset");
- }
-
- /* -A handle_reject */
- fwd_xt_append_rule(r, "handle_reject");
- }
-
- /* common reject rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -j REJECT --reject-with icmp-port-unreachable */
- if( (t = fwd_xt_get_target(r, "REJECT")) != NULL )
- {
- fwd_xt_parse_target(r, t, "--reject-with",
- "icmp-port-unreachable");
- }
-
- /* -A handle_reject */
- fwd_xt_append_rule(r, "handle_reject");
- }
-}
-
-/* build drop target chain */
-static void fwd_r_handle_drop(struct iptc_handle *h)
-{
- struct fwd_xt_rule *r;
-
- /* -N handle_drop */
- fwd_r_new_chain(h, "handle_drop");
-
- /* common drop rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -j DROP; -A handle_drop */
- fwd_xt_get_target(r, "DROP");
- fwd_xt_append_rule(r, "handle_drop");
- }
-}
-
-/* build accept target chain */
-static void fwd_r_handle_accept(struct iptc_handle *h)
-{
- struct fwd_xt_rule *r;
-
- /* -N handle_accept */
- fwd_r_new_chain(h, "handle_accept");
-
- /* common accept rule */
- if( (r = fwd_xt_init_rule(h)) != NULL )
- {
- /* -j ACCEPT; -A handle_accept */
- fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_append_rule(r, "handle_accept");
- }
-}
-
-/* add comment match */
-static void fwd_r_add_comment(
- struct fwd_xt_rule *r, const char *t, struct fwd_zone *z,
- struct fwd_network *n
-) {
- struct xtables_match *m;
- char buf[256];
-
- if( (m = fwd_xt_get_match(r, "comment")) != NULL )
- {
- snprintf(buf, sizeof(buf), "%s:net=%s zone=%s", t, n->name, z->name);
- fwd_xt_parse_match(r, m, "--comment", buf);
- }
-}
-
-/* add --sport (if applicable) */
-static void fwd_r_add_sport(
- struct fwd_xt_rule *r, struct fwd_portrange *p
-) {
- int proto = r->entry->ip.proto;
- char buf[12];
- struct xtables_match *m;
-
- /* have portrange and proto is tcp or udp ... */
- if( (p != NULL) && ((proto == 6) || (proto == 17)) )
- {
- /* get match ... */
- if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL )
- {
- snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max);
- fwd_xt_parse_match(r, m, "--sport", buf);
- }
- }
-}
-
-/* add --dport (if applicable) */
-static void fwd_r_add_dport(
- struct fwd_xt_rule *r, struct fwd_portrange *p
-) {
- int proto = r->entry->ip.proto;
- char buf[12];
- struct xtables_match *m;
-
- /* have portrange and proto is tcp or udp ... */
- if( (p != NULL) && ((proto == 6) || (proto == 17)) )
- {
- /* get match ... */
- if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL )
- {
- snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max);
- fwd_xt_parse_match(r, m, "--dport", buf);
- }
- }
-}
-
-/* add --icmp-type (of applicable) */
-static void fwd_r_add_icmptype(
- struct fwd_xt_rule *r, struct fwd_icmptype *i
-) {
- int proto = r->entry->ip.proto;
- struct xtables_match *m;
- char buf[32];
-
- /* have icmp-type and proto is icmp ... */
- if( (i != NULL) && (proto == 1) )
- {
- /* get match ... */
- if( (m = fwd_xt_get_match(r, "icmp")) != NULL )
- {
- if( i->name[0] )
- snprintf(buf, sizeof(buf), "%s", i->name);
- else
- snprintf(buf, sizeof(buf), "%u/%u", i->type, i->code);
-
- fwd_xt_parse_match(r, m, "--icmp-type", buf);
- }
- }
-}
-
-/* add -m mac --mac-source ... */
-static void fwd_r_add_srcmac(
- struct fwd_xt_rule *r, struct fwd_mac *mac
-) {
- struct xtables_match *m;
- char buf[18];
-
- if( mac != NULL )
- {
- if( (m = fwd_xt_get_match(r, "mac")) != NULL )
- {
- snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
- mac->mac[0], mac->mac[1], mac->mac[2],
- mac->mac[3], mac->mac[4], mac->mac[5]);
-
- fwd_xt_parse_match(r, m, "--mac-source", buf);
- }
- }
-}
-
-/* add policy target */
-static void fwd_r_add_policytarget(
- struct fwd_xt_rule *r, enum fwd_policy pol
-) {
- switch(pol)
- {
- case FWD_P_ACCEPT:
- fwd_xt_get_target(r, "handle_accept");
- break;
-
- case FWD_P_REJECT:
- fwd_xt_get_target(r, "handle_reject");
- break;
-
- case FWD_P_DROP:
- case FWD_P_UNSPEC:
- fwd_xt_get_target(r, "handle_drop");
- break;
- }
-}
-
-/* add dnat target */
-static void fwd_r_add_dnattarget(
- struct fwd_xt_rule *r, struct fwd_cidr *c, struct fwd_portrange *p
-) {
- struct xtables_target *t;
- char buf[32];
-
- if( c != NULL )
- {
- if( (t = fwd_xt_get_target(r, "DNAT")) != NULL )
- {
- if( p != NULL )
- snprintf(buf, sizeof(buf), "%s:%u-%u",
- inet_ntoa(c->addr), p->min, p->max);
- else
- snprintf(buf, sizeof(buf), "%s", inet_ntoa(c->addr));
-
- fwd_xt_parse_target(r, t, "--to-destination", buf);
- }
- }
-}
-
-/* parse comment string and look for match */
-static int fwd_r_cmp(const char *what, const char *cmt, const char *cmp)
-{
- char *match;
-
- if( (match = strstr(cmt, what)) == NULL )
- return 0;
-
- match += strlen(what);
-
- if( strncmp(match, cmp, strlen(cmp)) != 0 )
- return 0;
-
- if( (match[strlen(cmp)] != ' ') && (match[strlen(cmp)] != '\0') )
- return 0;
-
- return 1;
-}
-
-
-static void fwd_ipt_defaults_create(struct fwd_data *d)
-{
- struct fwd_defaults *def = &d->section.defaults;
- struct iptc_handle *h_filter, *h_nat;
-
- if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
- fwd_fatal("Unable to obtain libiptc handle");
-
- /* policies */
- fwd_r_set_policy(h_filter, "INPUT",
- def->input == FWD_P_ACCEPT ? "ACCEPT" : "DROP");
- fwd_r_set_policy(h_filter, "OUTPUT",
- def->output == FWD_P_ACCEPT ? "ACCEPT" : "DROP");
- fwd_r_set_policy(h_filter, "FORWARD",
- def->forward == FWD_P_ACCEPT ? "ACCEPT" : "DROP");
-
- /* invalid state drop */
- if( def->drop_invalid )
- {
- fwd_r_drop_invalid(h_filter, "INPUT");
- fwd_r_drop_invalid(h_filter, "OUTPUT");
- fwd_r_drop_invalid(h_filter, "FORWARD");
- }
-
- /* default accept related */
- fwd_r_accept_related(h_filter, "INPUT");
- fwd_r_accept_related(h_filter, "OUTPUT");
- fwd_r_accept_related(h_filter, "FORWARD");
-
- /* default accept on lo */
- fwd_r_accept_lo(h_filter);
-
- /* syn flood protection */
- if( def->syn_flood )
- {
- fwd_r_add_synflood(h_filter, def);
- }
-
- /* rule container chains */
- fwd_r_new_chain(h_filter, "mssfix");
- fwd_r_new_chain(h_filter, "zones");
- fwd_r_new_chain(h_filter, "rules");
- fwd_r_new_chain(h_filter, "redirects");
- fwd_r_new_chain(h_filter, "forwardings");
- fwd_r_jump_chain(h_filter, "INPUT", "rules");
- fwd_r_jump_chain(h_filter, "FORWARD", "mssfix");
- fwd_r_jump_chain(h_filter, "FORWARD", "zones");
- fwd_r_jump_chain(h_filter, "FORWARD", "rules");
- fwd_r_jump_chain(h_filter, "FORWARD", "redirects");
- fwd_r_jump_chain(h_filter, "FORWARD", "forwardings");
- fwd_r_new_chain(h_nat, "zonemasq");
- fwd_r_new_chain(h_nat, "redirects");
- fwd_r_new_chain(h_nat, "loopback");
- fwd_r_jump_chain(h_nat, "POSTROUTING", "zonemasq");
- fwd_r_jump_chain(h_nat, "PREROUTING", "redirects");
- fwd_r_jump_chain(h_nat, "POSTROUTING", "loopback");
-
- /* standard drop, accept, reject chain */
- fwd_r_handle_drop(h_filter);
- fwd_r_handle_accept(h_filter);
- fwd_r_handle_reject(h_filter);
-
-
- if( !iptc_commit(h_nat) )
- fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
-
- if( !iptc_commit(h_filter) )
- fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
-
- iptc_free(h_nat);
- iptc_free(h_filter);
-}
-
-
-void fwd_ipt_build_ruleset(struct fwd_handle *h)
-{
- struct fwd_data *e;
-
- fwd_xt_init();
-
- for( e = h->conf; e; e = e->next )
- {
- switch(e->type)
- {
- case FWD_S_DEFAULTS:
- fwd_log_info("Loading defaults");
- fwd_ipt_defaults_create(e);
- break;
-
- case FWD_S_INCLUDE:
- fwd_log_info("Loading include: %s",
- e->section.include.path);
- break;
-
- case FWD_S_ZONE:
- case FWD_S_FORWARD:
- case FWD_S_REDIRECT:
- case FWD_S_RULE:
- /* Make gcc happy */
- break;
- }
- }
-}
-
-
-static struct fwd_zone *
-fwd_lookup_zone(struct fwd_handle *h, const char *net)
-{
- struct fwd_data *e;
- struct fwd_network *n;
-
- for( e = h->conf; e; e = e->next )
- if( e->type == FWD_S_ZONE )
- for( n = e->section.zone.networks; n; n = n->next )
- if( !strcmp(n->name, net) )
- return &e->section.zone;
-
- return NULL;
-}
-
-static struct fwd_network *
-fwd_lookup_network(struct fwd_zone *z, const char *net)
-{
- struct fwd_network *n;
-
- for( n = z->networks; n; n = n->next )
- if( !strcmp(n->name, net) )
- return n;
-
- return NULL;
-}
-
-void fwd_ipt_addif(struct fwd_handle *h, const char *net)
-{
- struct fwd_data *e;
- struct fwd_zone *z;
- struct fwd_rule *c;
- struct fwd_redirect *r;
- struct fwd_forwarding *f;
- struct fwd_cidr *a, *a2;
- struct fwd_network *n, *n2;
- struct fwd_proto p;
-
- struct fwd_xt_rule *x;
- struct xtables_match *m;
- struct xtables_target *t;
-
- struct iptc_handle *h_filter, *h_nat;
-
- if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
- fwd_fatal("Unable to obtain libiptc handle");
-
-
- if( !(z = fwd_lookup_zone(h, net)) )
- return;
-
- if( !(n = fwd_lookup_network(z, net)) )
- return;
-
- if( !(a = n->addr) || fwd_empty_cidr(a) )
- return;
-
-
- fwd_log_info("Adding network %s (interface %s)",
- n->name, n->ifname);
-
- /* Build masquerading rule */
- if( z->masq )
- {
- if( (x = fwd_xt_init_rule(h_nat)) != NULL )
- {
- fwd_xt_parse_out(x, n, 0); /* -o ... */
- fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */
- fwd_r_add_comment(x, "masq", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "zonemasq"); /* -A zonemasq */
- }
- }
-
- /* Build MSS fix rule */
- if( z->mtu_fix )
- {
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- p.type = FWD_PR_TCP;
- fwd_xt_parse_out(x, n, 0); /* -o ... */
- fwd_xt_parse_proto(x, &p, 0); /* -p tcp */
-
- /* -m tcp --tcp-flags SYN,RST SYN */
- if( (m = fwd_xt_get_match(x, "tcp")) != NULL )
- fwd_xt_parse_match(x, m, "--tcp-flags", "SYN,RST", "SYN");
-
- /* -j TCPMSS --clamp-mss-to-pmtu */
- if( (t = fwd_xt_get_target(x, "TCPMSS")) != NULL )
- fwd_xt_parse_target(x, t, "--clamp-mss-to-pmtu");
-
- /* -m comment ... */
- fwd_r_add_comment(x, "mssfix", z, n);
-
- /* -A mssfix */
- fwd_xt_append_rule(x, "mssfix");
- }
- }
-
- /* Build intra-zone forwarding rules */
- for( n2 = z->networks; n2; n2 = n2->next )
- {
- if( (a2 = n2->addr) != NULL )
- {
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_out(x, n2, 0); /* -o ... */
- fwd_r_add_policytarget(x, z->forward); /* -j handle_... */
- fwd_r_add_comment(x, "zone", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "zones"); /* -A zones */
- }
- }
- }
-
- /* Build inter-zone forwarding rules */
- for( e = z->forwardings; e && (f = &e->section.forwarding); e = e->next )
- {
- for( n2 = f->dest->networks; n2; n2 = n2->next )
- {
- /* Build forwarding rule */
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_out(x, n2, 0); /* -o ... */
- fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_... */
- fwd_r_add_comment(x, "forward", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "forwardings"); /* -A forwardings */
- }
- }
- }
-
- /* Build DNAT rules */
- for( e = z->redirects; e && (r = &e->section.redirect); e = e->next )
- {
- /* DNAT */
- if( (x = fwd_xt_init_rule(h_nat)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */
- fwd_xt_parse_dest(x, a, 0); /* -d ... */
- fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */
- fwd_r_add_sport(x, r->src_port); /* --sport ... */
- fwd_r_add_dport(x, r->src_dport); /* --dport ... */
- fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */
- fwd_r_add_dnattarget(x, r->dest_ip, r->dest_port); /* -j DNAT ... */
- fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "redirects"); /* -A redirects */
- }
-
- /* Forward */
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */
- fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */
- fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */
- fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */
- fwd_r_add_sport(x, r->src_port); /* --sport ... */
- fwd_r_add_dport(x, r->dest_port); /* --dport ... */
- fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_accept */
- fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "redirects"); /* -A redirects */
- }
-
- /* Add loopback rule if neither src_ip nor src_mac are defined */
- if( !r->src_ip && !r->src_mac )
- {
- if( (x = fwd_xt_init_rule(h_nat)) != NULL )
- {
- fwd_xt_parse_in(x, n, 1); /* -i ! ... */
- fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */
- fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */
- fwd_r_add_sport(x, r->src_port); /* --sport ... */
- fwd_r_add_dport(x, r->src_dport); /* --dport ... */
- fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */
- fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "loopback"); /* -A loopback */
- }
- }
- }
-
- /* Build rules */
- for( e = z->rules; e && (c = &e->section.rule); e = e->next )
- {
- /* Has destination, add forward rule for each network in target zone */
- if( c->dest )
- {
- for( n2 = c->dest->networks; n2; n2 = n2->next )
- {
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_out(x, n2, 0); /* -o ... */
- fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */
- fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */
- fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */
- fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */
- fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */
- fwd_r_add_sport(x, c->src_port); /* --sport ... */
- fwd_r_add_dport(x, c->dest_port); /* --dport ... */
- fwd_r_add_policytarget(x, c->target); /* -j handle_... */
- fwd_r_add_comment(x, "rule", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "rules"); /* -A rules */
- }
- }
- }
-
- /* No destination specified, treat it as input rule */
- else
- {
- if( (x = fwd_xt_init_rule(h_filter)) != NULL )
- {
- fwd_xt_parse_in(x, n, 0); /* -i ... */
- fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */
- fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */
- fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */
- fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */
- fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */
- fwd_r_add_sport(x, c->src_port); /* --sport ... */
- fwd_r_add_dport(x, c->dest_port); /* --dport ... */
- fwd_r_add_policytarget(x, c->target); /* -j handle_... */
- fwd_r_add_comment(x, "rule", z, n); /* -m comment ... */
- fwd_xt_append_rule(x, "rules"); /* -A rules */
- }
- }
- }
-
- if( !iptc_commit(h_nat) )
- fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
-
- if( !iptc_commit(h_filter) )
- fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
-
- iptc_free(h_nat);
- iptc_free(h_filter);
-}
-
-
-static void fwd_ipt_delif_table(struct iptc_handle *h, const char *net)
-{
- const struct xt_entry_match *m;
- const struct ipt_entry *e;
- const char *chain, *comment;
- size_t off = 0, num = 0;
-
- /* iterate chains */
- for( chain = iptc_first_chain(h); chain;
- chain = iptc_next_chain(h)
- ) {
- /* iterate rules */
- for( e = iptc_first_rule(chain, h), num = 0; e;
- e = iptc_next_rule(e, h), num++
- ) {
- repeat_rule:
-
- /* skip entries w/o matches */
- if( ! e->target_offset )
- continue;
-
- /* iterate matches */
- for( off = sizeof(struct ipt_entry);
- off < e->target_offset;
- off += m->u.match_size
- ) {
- m = (void *)e + off;
-
- /* yay */
- if( ! strcmp(m->u.user.name, "comment") )
- {
- /* better use struct_xt_comment_info but well... */
- comment = (void *)m + sizeof(struct xt_entry_match);
-
- if( fwd_r_cmp("net=", comment, net) )
- {
- e = iptc_next_rule(e, h);
- iptc_delete_num_entry(chain, num, h);
-
- if( e != NULL )
- goto repeat_rule;
- else
- break;
- }
- }
- }
- }
- }
-}
-
-void fwd_ipt_delif(struct fwd_handle *h, const char *net)
-{
- struct iptc_handle *h_filter, *h_nat;
-
- if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
- fwd_fatal("Unable to obtain libiptc handle");
-
-
- fwd_log_info("Removing network %s", net);
-
- /* delete network related rules */
- fwd_ipt_delif_table(h_nat, net);
- fwd_ipt_delif_table(h_filter, net);
-
-
- if( !iptc_commit(h_nat) )
- fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
-
- if( !iptc_commit(h_filter) )
- fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
-
- iptc_free(h_nat);
- iptc_free(h_filter);
-}
-
-void fwd_ipt_chgif(struct fwd_handle *h, const char *net)
-{
- /* XXX: should alter rules in-place, tbd */
- fwd_ipt_delif(h, net);
- fwd_ipt_addif(h, net);
-}
-
-
-static void fwd_ipt_clear_ruleset_table(struct iptc_handle *h)
-{
- const char *chain;
-
- /* pass 1: flush all chains */
- for( chain = iptc_first_chain(h); chain;
- chain = iptc_next_chain(h)
- ) {
- iptc_flush_entries(chain, h);
- }
-
- /* pass 2: remove user defined chains */
- for( chain = iptc_first_chain(h); chain;
- chain = iptc_next_chain(h)
- ) {
- if( ! iptc_builtin(chain, h) )
- iptc_delete_chain(chain, h);
- }
-}
-
-void fwd_ipt_clear_ruleset(struct fwd_handle *h)
-{
- struct iptc_handle *h_filter, *h_nat;
-
- if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
- fwd_fatal("Unable to obtain libiptc handle");
-
- /* flush tables */
- fwd_ipt_clear_ruleset_table(h_nat);
- fwd_ipt_clear_ruleset_table(h_filter);
-
- /* revert policies */
- fwd_r_set_policy(h_filter, "INPUT", "ACCEPT");
- fwd_r_set_policy(h_filter, "OUTPUT", "ACCEPT");
- fwd_r_set_policy(h_filter, "FORWARD", "ACCEPT");
-
-
- if( !iptc_commit(h_nat) )
- fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
-
- if( !iptc_commit(h_filter) )
- fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
-
- iptc_free(h_nat);
- iptc_free(h_filter);
-}
-
diff --git a/contrib/fwd/src/fwd_rules.h b/contrib/fwd/src/fwd_rules.h
deleted file mode 100644
index b9eabd870..000000000
--- a/contrib/fwd/src/fwd_rules.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - header for iptables rule set
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __FWD_RULES_H__
-#define __FWD_RULES_H__
-
-#include "fwd.h"
-
-void fwd_ipt_build_ruleset(struct fwd_handle *h);
-void fwd_ipt_clear_ruleset(struct fwd_handle *h);
-
-void fwd_ipt_addif(struct fwd_handle *h, const char *net);
-void fwd_ipt_delif(struct fwd_handle *h, const char *net);
-void fwd_ipt_chgif(struct fwd_handle *h, const char *net);
-
-#endif
-
diff --git a/contrib/fwd/src/fwd_utils.c b/contrib/fwd/src/fwd_utils.c
deleted file mode 100644
index 170ecf468..000000000
--- a/contrib/fwd/src/fwd_utils.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - commmon utility functions
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd_utils.h"
-
-
-void fwd_log_init(void)
-{
- openlog("Firewall", 0, LOG_DAEMON | LOG_PERROR);
-}
-
-void __fwd_log(int prio, const char *msg, ...)
-{
- va_list ap;
- va_start(ap, msg);
- vsyslog(prio, msg, ap);
- va_end(ap);
-}
-
-
-
-int fwd_empty_cidr(struct fwd_cidr *c)
-{
- if( (c == NULL) || ((c->addr.s_addr == 0) && (c->prefix == 0)) )
- return 1;
-
- return 0;
-}
-
-int fwd_equal_cidr(struct fwd_cidr *a, struct fwd_cidr *b)
-{
- if( fwd_empty_cidr(a) && fwd_empty_cidr(b) )
- return 1;
- else if( (a->addr.s_addr == b->addr.s_addr) && (a->prefix == b->prefix) )
- return 1;
-
- return 0;
-}
-
-void fwd_update_cidr(struct fwd_cidr *a, struct fwd_cidr *b)
-{
- if( a != NULL )
- {
- a->addr.s_addr = b ? b->addr.s_addr : 0;
- a->prefix = b ? b->prefix : 0;
- }
-}
-
-
-/* fwd_zmalloc(size_t)
- * Allocates a zeroed buffer of the given size. */
-void * fwd_zmalloc(size_t s)
-{
- void *b = malloc(s);
-
- if( b != NULL )
- memset(b, 0, s);
-
- return b;
-}
-
-
diff --git a/contrib/fwd/src/fwd_utils.h b/contrib/fwd/src/fwd_utils.h
deleted file mode 100644
index 618a53784..000000000
--- a/contrib/fwd/src/fwd_utils.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - commmon utility header
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __FWD_UTILS_H__
-#define __FWD_UTILS_H__
-
-#include <syslog.h>
-
-#include "fwd.h"
-
-void fwd_log_init(void);
-void __fwd_log(int, const char *, ...);
-#define fwd_log_info(...) __fwd_log(LOG_INFO, __VA_ARGS__)
-#define fwd_log_err(...) __fwd_log(LOG_ERR, __VA_ARGS__)
-
-int fwd_empty_cidr(struct fwd_cidr *);
-int fwd_equal_cidr(struct fwd_cidr *, struct fwd_cidr *);
-void fwd_update_cidr(struct fwd_cidr *, struct fwd_cidr *);
-
-/* fwd_zmalloc(size_t)
- * Allocates a zeroed buffer of the given size. */
-void * fwd_zmalloc(size_t);
-
-/* fwd_alloc_ptr(type)
- * Allocates a buffer with the size of the given datatype
- * and returns a pointer to it. */
-#define fwd_alloc_ptr(t) (t *) fwd_zmalloc(sizeof(t))
-
-/* fwd_free_ptr(void *)
- * Frees the given pointer and sets it to NULL.
- * Safe for NULL values. */
-#define fwd_free_ptr(x) do { if(x != NULL) free(x); x = NULL; } while(0)
-
-#endif
-
diff --git a/contrib/fwd/src/fwd_xtables.c b/contrib/fwd/src/fwd_xtables.c
deleted file mode 100644
index 895715d92..000000000
--- a/contrib/fwd/src/fwd_xtables.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - libiptc/libxtables interface
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#include "fwd.h"
-#include "fwd_xtables.h"
-#include "fwd_utils.h"
-
-
-/* Required by certain extensions like SNAT and DNAT */
-int kernel_version;
-
-extern void
-get_kernel_version(void) {
- static struct utsname uts;
- int x = 0, y = 0, z = 0;
-
- if (uname(&uts) == -1) {
- fprintf(stderr, "Unable to retrieve kernel version.\n");
- xtables_free_opts(1);
- exit(1);
- }
-
- sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
- kernel_version = LINUX_VERSION(x, y, z);
-}
-
-
-static void xt_exit_error(enum xtables_exittype status, const char *msg, ...)
-{
- va_list ap;
- va_start(ap, msg);
- vprintf(msg, ap);
- va_end(ap);
- exit(1);
-}
-
-void fwd_xt_init(void)
-{
- struct xtables_globals xt_globals = {
- .option_offset = 0,
- .program_version = IPTABLES_VERSION,
- .opts = 0,
- .orig_opts = 0,
- .exit_err = (void *)&xt_exit_error,
- };
-
- xtables_init();
- xtables_set_nfproto(NFPROTO_IPV4);
- xtables_set_params(&xt_globals);
-}
-
-
-struct fwd_xt_rule * fwd_xt_init_rule(struct iptc_handle *h)
-{
- struct fwd_xt_rule *r;
-
- if( (r = fwd_alloc_ptr(struct fwd_xt_rule)) != NULL )
- {
- if( (r->entry = fwd_alloc_ptr(struct ipt_entry)) != NULL )
- {
- r->iptc = h;
- return r;
- }
- }
-
- fwd_free_ptr(r);
- return NULL;
-}
-
-void fwd_xt_parse_frag(
- struct fwd_xt_rule *r, int frag, int inv
-) {
- if( frag )
- {
- r->entry->ip.flags |= IPT_F_FRAG;
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_FRAG;
- }
-}
-
-void fwd_xt_parse_proto(
- struct fwd_xt_rule *r, struct fwd_proto *p, int inv
-) {
- if( p != NULL )
- {
- switch(p->type)
- {
- case FWD_PR_TCP:
- r->entry->ip.proto = 6;
- break;
-
- case FWD_PR_UDP:
- r->entry->ip.proto = 17;
- break;
-
- case FWD_PR_ICMP:
- r->entry->ip.proto = 1;
- break;
-
- case FWD_PR_CUSTOM:
- r->entry->ip.proto = p->proto;
- break;
-
- case FWD_PR_ALL:
- case FWD_PR_TCPUDP:
- r->entry->ip.proto = 0;
- break;
- }
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_PROTO;
- }
-}
-
-void fwd_xt_parse_in(
- struct fwd_xt_rule *r, struct fwd_network *n, int inv
-) {
- if( n != NULL )
- {
- strncpy(r->entry->ip.iniface, n->ifname, IFNAMSIZ);
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_VIA_IN;
- }
-}
-
-void fwd_xt_parse_out(
- struct fwd_xt_rule *r, struct fwd_network *n, int inv
-) {
- if( n != NULL )
- {
- strncpy(r->entry->ip.outiface, n->ifname, IFNAMSIZ);
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_VIA_OUT;
- }
-}
-
-void fwd_xt_parse_src(
- struct fwd_xt_rule *r, struct fwd_cidr *c, int inv
-) {
- if( c != NULL )
- {
- r->entry->ip.src.s_addr = c->addr.s_addr;
- r->entry->ip.smsk.s_addr = htonl(~((1 << (32 - c->prefix)) - 1));
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_SRCIP;
- }
-}
-
-void fwd_xt_parse_dest(
- struct fwd_xt_rule *r, struct fwd_cidr *c, int inv
-) {
- if( c != NULL )
- {
- r->entry->ip.dst.s_addr = c->addr.s_addr;
- r->entry->ip.dmsk.s_addr = htonl(~((1 << (32 - c->prefix)) - 1));
-
- if( inv )
- r->entry->ip.invflags |= IPT_INV_DSTIP;
- }
-}
-
-
-struct xtables_match * fwd_xt_get_match(
- struct fwd_xt_rule *r, const char *name
-) {
- struct xtables_match *m = xtables_find_match(name, XTF_TRY_LOAD, &r->matches);
- size_t s;
-
- if( m != NULL )
- {
- s = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
-
- if( (m->m = malloc(s)) != NULL )
- {
- memset(m->m, 0, s);
- strcpy(m->m->u.user.name, m->name);
- m->m->u.match_size = s;
-
- if( m->init )
- m->init(m->m);
-
- return m;
- }
- }
-
- return NULL;
-}
-
-void __fwd_xt_parse_match(
- struct fwd_xt_rule *r, struct xtables_match *m, ...
-) {
- char optc;
- char *s, **opts;
- size_t len = 1;
- int inv = 0;
-
- va_list ap;
- va_start(ap, m);
-
- opts = malloc(len * sizeof(*opts));
- opts[0] = "x";
-
- while( (s = (char *)va_arg(ap, char *)) != NULL )
- {
- opts = realloc(opts, ++len * sizeof(*opts));
- opts[len-1] = s;
- }
-
- va_end(ap);
-
- if( len > 1 )
- {
- optind = 0;
-
- while( (optc = getopt_long(len, opts, "", m->extra_opts, NULL)) > -1 )
- {
- if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') )
- {
- inv = 1;
- continue;
- }
-
- m->parse(optc, opts, inv, &m->mflags, r->entry, &m->m);
- inv = 0;
- }
- }
-
- free(opts);
-}
-
-
-struct xtables_target * fwd_xt_get_target(
- struct fwd_xt_rule *r, const char *name
-) {
- struct xtables_target *t = xtables_find_target(name, XTF_TRY_LOAD);
- size_t s;
-
- if( !t )
- t = xtables_find_target(IPT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED);
-
- if( t != NULL )
- {
- s = IPT_ALIGN(sizeof(struct ipt_entry_target)) + t->size;
-
- if( (t->t = malloc(s)) != NULL )
- {
- memset(t->t, 0, s);
- strcpy(t->t->u.user.name, name);
- t->t->u.target_size = s;
- xtables_set_revision(t->t->u.user.name, t->revision);
-
- if( t->init )
- t->init(t->t);
-
- r->target = t;
-
- return t;
- }
- }
-
- return NULL;
-}
-
-void __fwd_xt_parse_target(
- struct fwd_xt_rule *r, struct xtables_target *t, ...
-) {
- char optc;
- char *s, **opts;
- size_t len = 1;
- int inv = 0;
-
- va_list ap;
- va_start(ap, t);
-
- opts = malloc(len * sizeof(*opts));
- opts[0] = "x";
-
- while( (s = (char *)va_arg(ap, char *)) != NULL )
- {
- opts = realloc(opts, ++len * sizeof(*opts));
- opts[len-1] = s;
- }
-
- va_end(ap);
-
- if( len > 1 )
- {
- optind = 0;
-
- while( (optc = getopt_long(len, opts, "", t->extra_opts, NULL)) > -1 )
- {
- if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') )
- {
- inv = 1;
- continue;
- }
-
- t->parse(optc, opts, inv, &t->tflags, r->entry, &t->t);
- inv = 0;
- }
- }
-
- free(opts);
-}
-
-
-static int fwd_xt_exec_rule(struct fwd_xt_rule *r, const char *chain, int pos)
-{
- size_t s;
- struct xtables_rule_match *m, *next;
- struct xtables_match *em;
- struct xtables_target *et;
- struct ipt_entry *e;
- int rv = 0;
-
- s = IPT_ALIGN(sizeof(struct ipt_entry));
-
- for( m = r->matches; m; m = m->next )
- s += m->match->m->u.match_size;
-
- if( (e = malloc(s + r->target->t->u.target_size)) != NULL )
- {
- memset(e, 0, s + r->target->t->u.target_size);
- memcpy(e, r->entry, sizeof(struct ipt_entry));
-
- e->target_offset = s;
- e->next_offset = s + r->target->t->u.target_size;
-
- s = 0;
-
- for( m = r->matches; m; m = m->next )
- {
- memcpy(e->elems + s, m->match->m, m->match->m->u.match_size);
- s += m->match->m->u.match_size;
- }
-
- memcpy(e->elems + s, r->target->t, r->target->t->u.target_size);
-
- rv = (pos > -1)
- ? iptc_insert_entry(chain, e, (unsigned int) pos, r->iptc)
- : iptc_append_entry(chain, e, r->iptc)
- ;
- }
- else
- {
- errno = ENOMEM;
- }
-
-
- fwd_free_ptr(e);
- fwd_free_ptr(r->entry);
- fwd_free_ptr(r->target->t);
-
- for( m = r->matches; m; )
- {
- next = m->next;
- fwd_free_ptr(m->match->m);
-
- if( m->match == m->match->next )
- fwd_free_ptr(m->match);
-
- fwd_free_ptr(m);
- m = next;
- }
-
- fwd_free_ptr(r);
-
- /* reset all targets and matches */
- for (em = xtables_matches; em; em = em->next)
- em->mflags = 0;
-
- for (et = xtables_targets; et; et = et->next)
- {
- et->tflags = 0;
- et->used = 0;
- }
-
- return rv;
-}
-
-int fwd_xt_insert_rule(
- struct fwd_xt_rule *r, const char *chain, unsigned int pos
-) {
- return fwd_xt_exec_rule(r, chain, pos);
-}
-
-int fwd_xt_append_rule(
- struct fwd_xt_rule *r, const char *chain
-) {
- return fwd_xt_exec_rule(r, chain, -1);
-}
-
diff --git a/contrib/fwd/src/fwd_xtables.h b/contrib/fwd/src/fwd_xtables.h
deleted file mode 100644
index 1ac57bb0e..000000000
--- a/contrib/fwd/src/fwd_xtables.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * fwd - OpenWrt firewall daemon - libiptc/libxtables interface headers
- *
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The fwd program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The fwd 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 the fwd program. If not, see http://www.gnu.org/licenses/.
- */
-
-
-#ifndef __FWD_XTABLES_H__
-#define __FWD_XTABLES_H__
-
-#include <iptables.h>
-#include <xtables.h>
-#include <libiptc/libxtc.h>
-
-#include <dlfcn.h>
-#include <errno.h>
-
-#include <sys/stat.h>
-#include <sys/utsname.h>
-
-
-
-struct fwd_xt_rule {
- struct iptc_handle *iptc;
- struct ipt_entry *entry;
- struct xtables_rule_match *matches;
- struct xtables_target *target;
-};
-
-
-/* Required by certain extensions like SNAT and DNAT */
-extern int kernel_version;
-extern void get_kernel_version(void);
-
-
-void fwd_xt_init(void);
-
-struct fwd_xt_rule * fwd_xt_init_rule(struct iptc_handle *h);
-
-void fwd_xt_parse_proto(struct fwd_xt_rule *r, struct fwd_proto *p, int inv);
-void fwd_xt_parse_in(struct fwd_xt_rule *r, struct fwd_network *n, int inv);
-void fwd_xt_parse_out(struct fwd_xt_rule *r, struct fwd_network *n, int inv);
-void fwd_xt_parse_src(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv);
-void fwd_xt_parse_dest(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv);
-void fwd_xt_parse_frag(struct fwd_xt_rule *r, int frag, int inv);
-
-struct xtables_match * fwd_xt_get_match(struct fwd_xt_rule *r, const char *name);
-void __fwd_xt_parse_match(struct fwd_xt_rule *r, struct xtables_match *m, ...);
-#define fwd_xt_parse_match(r, m, ...) __fwd_xt_parse_match(r, m, __VA_ARGS__, NULL)
-
-struct xtables_target * fwd_xt_get_target(struct fwd_xt_rule *r, const char *name);
-void __fwd_xt_parse_target(struct fwd_xt_rule *r, struct xtables_target *t, ...);
-#define fwd_xt_parse_target(r, t, ...) __fwd_xt_parse_target(r, t, __VA_ARGS__, NULL)
-
-int fwd_xt_append_rule(struct fwd_xt_rule *r, const char *chain);
-int fwd_xt_insert_rule(struct fwd_xt_rule *r, const char *chain, unsigned int pos);
-
-#endif
diff --git a/contrib/fwd/src/ucix.c b/contrib/fwd/src/ucix.c
deleted file mode 100644
index 1d2d87f6d..000000000
--- a/contrib/fwd/src/ucix.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include <uci_config.h>
-#include <uci.h>
-#include "ucix.h"
-
-static struct uci_ptr ptr;
-
-static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
-{
- memset(&ptr, 0, sizeof(ptr));
- ptr.package = p;
- ptr.section = s;
- ptr.option = o;
- ptr.value = t;
- return uci_lookup_ptr(ctx, &ptr, NULL, true);
-}
-
-struct uci_context* ucix_init(const char *config_file)
-{
- struct uci_context *ctx = uci_alloc_context();
- uci_add_history_path(ctx, "/var/state");
- if(uci_load(ctx, config_file, NULL) != UCI_OK)
- {
- printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
- return NULL;
- }
- return ctx;
-}
-
-struct uci_context* ucix_init_path(const char *path, const char *config_file)
-{
- struct uci_context *ctx = uci_alloc_context();
- if(path)
- uci_set_confdir(ctx, path);
- if(uci_load(ctx, config_file, NULL) != UCI_OK)
- {
- printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
- return NULL;
- }
- return ctx;
-}
-
-int ucix_load(struct uci_context *ctx, const char *config_file)
-{
- if(uci_load(ctx, config_file, NULL) != UCI_OK)
- {
- printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
- return 0;
- }
- return 1;
-}
-
-void ucix_cleanup(struct uci_context *ctx)
-{
- uci_free_context(ctx);
-}
-
-void ucix_save(struct uci_context *ctx)
-{
- uci_set_savedir(ctx, "/tmp/.uci/");
- uci_save(ctx, NULL);
-}
-
-void ucix_save_state(struct uci_context *ctx)
-{
- uci_set_savedir(ctx, "/var/state/");
- uci_save(ctx, NULL);
-}
-
-const char* ucix_get_option(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- struct uci_element *e = NULL;
- const char *value = NULL;
- if(ucix_get_ptr(ctx, p, s, o, NULL))
- return NULL;
- if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
- return NULL;
- e = ptr.last;
- switch (e->type)
- {
- case UCI_TYPE_SECTION:
- value = uci_to_section(e)->type;
- break;
-
- case UCI_TYPE_OPTION:
- switch(ptr.o->type) {
- case UCI_TYPE_STRING:
- value = ptr.o->v.string;
- break;
- default:
- value = NULL;
- break;
- }
- break;
-
- default:
- return 0;
- }
-
- return value;
-}
-
-int ucix_for_each_list(
- struct uci_context *ctx, const char *p, const char *s, const char *o,
- void (*cb)(const char*, void*), void *priv)
-{
- struct uci_element *e = NULL;
- char *value = NULL;
- int count = 0;
- if(ucix_get_ptr(ctx, p, s, o, NULL))
- return -1;
- if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
- return -1;
- e = ptr.last;
- if(e->type == UCI_TYPE_OPTION)
- {
- switch(ptr.o->type)
- {
- case UCI_TYPE_LIST:
- uci_foreach_element(&ptr.o->v.list, e) {
- cb(e->name, priv);
- count++;
- }
- break;
-
- case UCI_TYPE_STRING:
- if( (value = strdup(ptr.o->v.string)) != NULL )
- {
- char *ts, *tt, *tp;
- for( ts = value; 1; ts = NULL )
- {
- if( (tt = strtok_r(ts, " \t", &tp)) != NULL )
- {
- cb(tt, priv);
- count++;
- }
- else
- {
- break;
- }
- }
- free(value);
- }
- break;
- }
-
- return count;
- }
-
- return -1;
-}
-
-int ucix_get_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int def)
-{
- const char *tmp = ucix_get_option(ctx, p, s, o);
- int ret = def;
-
- if (tmp)
- ret = atoi(tmp);
- return ret;
-}
-
-void ucix_add_section(struct uci_context *ctx, const char *p, const char *s, const char *t)
-{
- if(ucix_get_ptr(ctx, p, s, NULL, t))
- return;
- uci_set(ctx, &ptr);
-}
-
-void ucix_add_option(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
-{
- if(ucix_get_ptr(ctx, p, s, o, (t)?(t):("")))
- return;
- uci_set(ctx, &ptr);
-}
-
-void ucix_add_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int t)
-{
- char tmp[64];
- snprintf(tmp, 64, "%d", t);
- ucix_add_option(ctx, p, s, o, tmp);
-}
-
-void ucix_del(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- if(!ucix_get_ptr(ctx, p, s, o, NULL))
- uci_delete(ctx, &ptr);
-}
-
-void ucix_revert(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- if(!ucix_get_ptr(ctx, p, s, o, NULL))
- uci_revert(ctx, &ptr);
-}
-
-void ucix_for_each_section_type(struct uci_context *ctx,
- const char *p, const char *t,
- void (*cb)(struct uci_context *, const char*, void*), void *priv)
-{
- struct uci_element *e;
- if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
- return;
- uci_foreach_element(&ptr.p->sections, e)
- if (!strcmp(t, uci_to_section(e)->type))
- cb(ctx, e->name, priv);
-}
-
-int ucix_commit(struct uci_context *ctx, const char *p)
-{
- if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
- return 1;
- return uci_commit(ctx, &ptr.p, false);
-}
-
-
diff --git a/contrib/fwd/src/ucix.h b/contrib/fwd/src/ucix.h
deleted file mode 100644
index d77ac8530..000000000
--- a/contrib/fwd/src/ucix.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
- */
-
-#ifndef __UCIX_H__
-#define __UCIX_H_
-
-struct uci_context* ucix_init(const char *config_file);
-struct uci_context* ucix_init_path(const char *path, const char *config_file);
-int ucix_load(struct uci_context *ctx, const char *config_file);
-void ucix_cleanup(struct uci_context *ctx);
-void ucix_save(struct uci_context *ctx);
-void ucix_save_state(struct uci_context *ctx);
-const char* ucix_get_option(struct uci_context *ctx,
- const char *p, const char *s, const char *o);
-int ucix_for_each_list(struct uci_context *ctx,
- const char *p, const char *s, const char *o,
- void (*cb)(const char*, void*), void *priv);
-int ucix_get_option_int(struct uci_context *ctx,
- const char *p, const char *s, const char *o, int def);
-void ucix_add_section(struct uci_context *ctx,
- const char *p, const char *s, const char *t);
-void ucix_add_option(struct uci_context *ctx,
- const char *p, const char *s, const char *o, const char *t);
-void ucix_add_option_int(struct uci_context *ctx,
- const char *p, const char *s, const char *o, int t);
-void ucix_for_each_section_type(struct uci_context *ctx,
- const char *p, const char *t,
- void (*cb)(struct uci_context *, const char*, void*), void *priv);
-int ucix_commit(struct uci_context *ctx, const char *p);
-void ucix_revert(struct uci_context *ctx,
- const char *p, const char *s, const char *o);
-void ucix_del(struct uci_context *ctx, const char *p,
- const char *s, const char *o);
-#endif
-