diff options
Diffstat (limited to 'contrib/fwd')
-rw-r--r-- | contrib/fwd/Makefile | 2 | ||||
-rw-r--r-- | contrib/fwd/src/Makefile | 18 | ||||
-rw-r--r-- | contrib/fwd/src/fwd.c | 320 | ||||
-rw-r--r-- | contrib/fwd/src/fwd.h | 182 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_addr.c | 162 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_addr.h | 50 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_config.c | 987 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_config.h | 29 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_ipc.c | 98 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_ipc.h | 61 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_rules.c | 886 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_rules.h | 32 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_utils.c | 78 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_utils.h | 50 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_xtables.c | 412 | ||||
-rw-r--r-- | contrib/fwd/src/fwd_xtables.h | 70 | ||||
-rw-r--r-- | contrib/fwd/src/ucix.c | 236 | ||||
-rw-r--r-- | contrib/fwd/src/ucix.h | 50 |
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 - |