* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#define _GNU_SOURCE
#include "utils.h"
#include "options.h"
fprintf(stderr, "\n");
}
+void *
+fw3_alloc(size_t size)
+{
+ void *mem;
+
+ mem = calloc(1, size);
+
+ if (!mem)
+ error("Out of memory while allocating %d bytes", size);
+
+ return mem;
+}
+
+char *
+fw3_strdup(const char *s)
+{
+ char *ns;
+
+ ns = strdup(s);
+
+ if (!ns)
+ error("Out of memory while duplicating string '%s'", s);
+
+ return ns;
+}
+
const char *
fw3_find_command(const char *cmd)
{
return false;
argn = 2;
- args = malloc(argn * sizeof(arg));
+ args = calloc(argn, sizeof(arg));
if (!args)
return false;
if (!sub)
continue;
- ptr.value = fw3_address_to_string(sub, true);
+ ptr.value = fw3_address_to_string(sub, true, false);
uci_add_list(ctx, &ptr);
}
struct uci_ptr ptr = { .p = dest };
- if (!s->enabled || (s->external && *s->external))
+ if (!s->enabled || s->external)
return;
uci_add_section(ctx, dest, "ipset", &ptr.s);
list_for_each_entry(type, &s->datatypes, list)
{
- sprintf(buf, "%s_%s", type->dest ? "dst" : "src",
- fw3_ipset_type_names[type->type]);
-
+ sprintf(buf, "%s_%s", type->dir, fw3_ipset_type_names[type->type]);
ptr.o = NULL;
ptr.option = "match";
ptr.value = buf;
{
ptr.o = NULL;
ptr.option = "iprange";
- ptr.value = fw3_address_to_string(&s->iprange, false);
+ ptr.value = fw3_address_to_string(&s->iprange, false, false);
uci_set(ctx, &ptr);
}
uci_unload(s->uci, p);
}
+ fsync(fileno(sf));
fclose(sf);
}
}
free(obj);
}
-
-bool
-fw3_pr_rulespec(int table, int family, uint32_t *flags, uint32_t mask,
- const struct fw3_rule_spec *r, const char *fmt, ...)
+void
+fw3_free_list(struct list_head *head)
{
- char buf[256];
- bool rv = false;
+ struct list_head *entry, *tmp;
- va_list ap;
- uint32_t f = flags ? flags[family == FW3_FAMILY_V6] : 0;
-
- if (mask)
- f &= mask;
+ if (!head)
+ return;
- for (; r->format; r++)
+ list_for_each_safe(entry, tmp, head)
{
- if (!fw3_is_family(r, family))
- continue;
-
- if (r->table != table)
- continue;
-
- if ((r->flag != 0) && !hasbit(f, r->flag))
- continue;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), r->format, ap);
- va_end(ap);
-
- fw3_pr(fmt, buf);
-
- rv = true;
+ list_del(entry);
+ free(entry);
}
- return rv;
+ free(head);
}
-
bool
fw3_hotplug(bool add, void *zone, void *device)
{
close(0);
close(1);
close(2);
- chdir("/");
+ if (chdir("/")) {};
clearenv();
setenv("ACTION", add ? "add" : "remove", 1);
/* unreached */
return false;
}
+
+int
+fw3_netmask2bitlen(int family, void *mask)
+{
+ int bits;
+ struct in_addr *v4;
+ struct in6_addr *v6;
+
+ if (family == FW3_FAMILY_V6)
+ for (bits = 0, v6 = mask;
+ bits < 128 && (v6->s6_addr[bits / 8] << (bits % 8)) & 128;
+ bits++);
+ else
+ for (bits = 0, v4 = mask;
+ bits < 32 && (ntohl(v4->s_addr) << bits) & 0x80000000;
+ bits++);
+
+ return bits;
+}
+
+bool
+fw3_bitlen2netmask(int family, int bits, void *mask)
+{
+ int i;
+ struct in_addr *v4;
+ struct in6_addr *v6;
+
+ if (family == FW3_FAMILY_V6)
+ {
+ if (bits < -128 || bits > 128)
+ return false;
+
+ v6 = mask;
+ i = abs(bits);
+
+ memset(v6->s6_addr, 0xff, i / 8);
+ memset(v6->s6_addr + (i / 8) + 1, 0, (128 - i) / 8);
+ v6->s6_addr[i / 8] = 0xff << (8 - (i & 7));
+
+ if (bits < 0)
+ for (i = 0; i < 16; i++)
+ v6->s6_addr[i] = ~v6->s6_addr[i];
+ }
+ else
+ {
+ if (bits < -32 || bits > 32)
+ return false;
+
+ v4 = mask;
+ v4->s_addr = htonl(~((1 << (32 - abs(bits))) - 1));
+
+ if (bits < 0)
+ v4->s_addr = ~v4->s_addr;
+ }
+
+ return true;
+}