diff options
Diffstat (limited to 'contrib/fwd/src/fwd_config.c')
-rw-r--r-- | contrib/fwd/src/fwd_config.c | 987 |
1 files changed, 0 insertions, 987 deletions
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; -} - |