/*
* firewall3 - 3rd OpenWrt UCI firewall implementation
*
- * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright (C) 2013-2014 Jo-Philipp Wich <jo@mein.io>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
+#define _LINUX_IN_H
+#define _LINUX_IN6_H
#include <netinet/in.h>
#include <netinet/ether.h>
+#include <time.h>
+
#include <uci.h>
#include <libubox/list.h>
#include <libubox/utils.h>
+#include <libubox/blobmsg.h>
#include "icmp_codes.h"
#include "utils.h"
FW3_FAMILY_V6 = 5,
};
-enum fw3_target
-{
- FW3_TARGET_UNSPEC = 0,
- FW3_TARGET_ACCEPT = 6,
- FW3_TARGET_REJECT = 7,
- FW3_TARGET_DROP = 8,
- FW3_TARGET_NOTRACK = 9,
- FW3_TARGET_DNAT = 10,
- FW3_TARGET_SNAT = 11,
-};
-
-enum fw3_default
+enum fw3_flag
{
- FW3_DEFAULT_UNSPEC = 0,
- FW3_DEFAULT_CUSTOM_CHAINS = 12,
- FW3_DEFAULT_SYN_FLOOD = 13,
- FW3_DEFAULT_MTU_FIX = 14,
- FW3_DEFAULT_DROP_INVALID = 15,
+ FW3_FLAG_UNSPEC = 0,
+ FW3_FLAG_ACCEPT = 6,
+ FW3_FLAG_REJECT = 7,
+ FW3_FLAG_DROP = 8,
+ FW3_FLAG_NOTRACK = 9,
+ FW3_FLAG_MARK = 10,
+ FW3_FLAG_DNAT = 11,
+ FW3_FLAG_SNAT = 12,
+ FW3_FLAG_MASQUERADE = 13,
+ FW3_FLAG_SRC_ACCEPT = 14,
+ FW3_FLAG_SRC_REJECT = 15,
+ FW3_FLAG_SRC_DROP = 16,
+ FW3_FLAG_CUSTOM_CHAINS = 17,
+ FW3_FLAG_SYN_FLOOD = 18,
+ FW3_FLAG_MTU_FIX = 19,
+ FW3_FLAG_DROP_INVALID = 20,
+ FW3_FLAG_HOTPLUG = 21,
+
+ __FW3_FLAG_MAX
};
-extern const char *fw3_flag_names[FW3_DEFAULT_DROP_INVALID + 1];
+extern const char *fw3_flag_names[__FW3_FLAG_MAX];
enum fw3_limit_unit
FW3_LIMIT_UNIT_MINUTE = 1,
FW3_LIMIT_UNIT_HOUR = 2,
FW3_LIMIT_UNIT_DAY = 3,
+
+ __FW3_LIMIT_UNIT_MAX
};
+extern const char *fw3_limit_units[__FW3_LIMIT_UNIT_MAX];
+
+
enum fw3_ipset_method
{
FW3_IPSET_METHOD_UNSPEC = 0,
FW3_IPSET_METHOD_BITMAP = 1,
FW3_IPSET_METHOD_HASH = 2,
FW3_IPSET_METHOD_LIST = 3,
+
+ __FW3_IPSET_METHOD_MAX
};
enum fw3_ipset_type
FW3_IPSET_TYPE_MAC = 3,
FW3_IPSET_TYPE_NET = 4,
FW3_IPSET_TYPE_SET = 5,
+
+ __FW3_IPSET_TYPE_MAX
+};
+
+extern const char *fw3_ipset_method_names[__FW3_IPSET_METHOD_MAX];
+extern const char *fw3_ipset_type_names[__FW3_IPSET_TYPE_MAX];
+
+
+enum fw3_include_type
+{
+ FW3_INC_TYPE_SCRIPT = 0,
+ FW3_INC_TYPE_RESTORE = 1,
+};
+
+enum fw3_reflection_source
+{
+ FW3_REFLECTION_INTERNAL = 0,
+ FW3_REFLECTION_EXTERNAL = 1,
};
struct fw3_ipset_datatype
{
struct list_head list;
enum fw3_ipset_type type;
- bool dest;
+ const char *dir;
+};
+
+struct fw3_setmatch
+{
+ bool set;
+ bool invert;
+ char name[32];
+ const char *dir[3];
+ struct fw3_ipset *ptr;
};
struct fw3_device
bool any;
bool invert;
char name[32];
+ char network[32];
};
struct fw3_address
struct list_head list;
bool set;
+ bool range;
bool invert;
+ bool resolved;
enum fw3_family family;
- int mask;
union {
struct in_addr v4;
struct in6_addr v6;
struct ether_addr mac;
} address;
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ struct ether_addr mac;
+ } mask;
};
struct fw3_mac
bool any;
bool invert;
- uint16_t protocol;
+ uint32_t protocol;
};
struct fw3_port
enum fw3_limit_unit unit;
};
+struct fw3_time
+{
+ bool utc;
+ struct tm datestart;
+ struct tm datestop;
+ uint32_t timestart;
+ uint32_t timestop;
+ uint32_t monthdays; /* bit 0 is invert + 1 .. 31 */
+ uint8_t weekdays; /* bit 0 is invert + 1 .. 7 */
+};
+
+struct fw3_mark
+{
+ bool set;
+ bool invert;
+ uint32_t mark;
+ uint32_t mask;
+};
+
struct fw3_defaults
{
- enum fw3_target policy_input;
- enum fw3_target policy_output;
- enum fw3_target policy_forward;
+ enum fw3_flag policy_input;
+ enum fw3_flag policy_output;
+ enum fw3_flag policy_forward;
bool drop_invalid;
struct fw3_limit syn_flood_rate;
bool tcp_syncookies;
- bool tcp_ecn;
- bool tcp_westwood;
+ int tcp_ecn;
bool tcp_window_scaling;
bool accept_redirects;
bool disable_ipv6;
- uint16_t flags;
+ uint32_t flags[2];
};
struct fw3_zone
{
struct list_head list;
- struct list_head running_list;
+ bool enabled;
const char *name;
enum fw3_family family;
- enum fw3_target policy_input;
- enum fw3_target policy_output;
- enum fw3_target policy_forward;
+ enum fw3_flag policy_input;
+ enum fw3_flag policy_output;
+ enum fw3_flag policy_forward;
struct list_head networks;
struct list_head devices;
const char *extra_dest;
bool masq;
+ bool masq_allow_invalid;
struct list_head masq_src;
struct list_head masq_dest;
- bool conntrack;
bool mtu_fix;
bool log;
bool custom_chains;
- uint16_t src_flags;
- uint16_t dst_flags;
+ uint32_t flags[2];
+
+ struct list_head old_addrs;
};
struct fw3_rule
{
struct list_head list;
+ bool enabled;
const char *name;
enum fw3_family family;
struct fw3_zone *_src;
struct fw3_zone *_dest;
+ const char *device;
+ bool direction_out;
+
struct fw3_device src;
struct fw3_device dest;
-
- struct fw3_ipset *_ipset;
- struct fw3_device ipset;
+ struct fw3_setmatch ipset;
struct list_head proto;
struct list_head icmp_type;
- enum fw3_target target;
-
struct fw3_limit limit;
+ struct fw3_time time;
+ struct fw3_mark mark;
+
+ enum fw3_flag target;
+ struct fw3_mark set_mark;
+ struct fw3_mark set_xmark;
const char *extra;
};
{
struct list_head list;
+ bool enabled;
const char *name;
enum fw3_family family;
struct fw3_device src;
struct fw3_device dest;
-
- struct fw3_ipset *_ipset;
- struct fw3_device ipset;
+ struct fw3_setmatch ipset;
struct list_head proto;
struct fw3_address ip_redir;
struct fw3_port port_redir;
- enum fw3_target target;
+ struct fw3_limit limit;
+ struct fw3_time time;
+ struct fw3_mark mark;
+
+ enum fw3_flag target;
const char *extra;
+ bool local;
bool reflection;
+ enum fw3_reflection_source reflection_src;
+};
+
+struct fw3_snat
+{
+ struct list_head list;
+
+ bool enabled;
+ const char *name;
+
+ enum fw3_family family;
+
+ struct fw3_zone *_src;
+
+ struct fw3_device src;
+ struct fw3_setmatch ipset;
+ const char *device;
+
+ struct list_head proto;
+
+ struct fw3_address ip_src;
+ struct fw3_port port_src;
+
+ struct fw3_address ip_dest;
+ struct fw3_port port_dest;
+
+ struct fw3_address ip_snat;
+ struct fw3_port port_snat;
+
+ struct fw3_limit limit;
+ struct fw3_time time;
+ struct fw3_mark mark;
+ bool connlimit_ports;
+
+ enum fw3_flag target;
+
+ const char *extra;
};
struct fw3_forward
{
struct list_head list;
+ bool enabled;
const char *name;
enum fw3_family family;
struct fw3_ipset
{
struct list_head list;
- struct list_head running_list;
+ bool enabled;
const char *name;
enum fw3_family family;
enum fw3_ipset_method method;
struct list_head datatypes;
- struct list_head iprange;
+ struct fw3_address iprange;
struct fw3_port portrange;
int netmask;
const char *external;
- uint16_t flags;
+ uint32_t flags[2];
+};
+
+struct fw3_include
+{
+ struct list_head list;
+
+ bool enabled;
+ const char *name;
+ enum fw3_family family;
+
+ const char *path;
+ enum fw3_include_type type;
+
+ bool reload;
};
struct fw3_state
struct list_head zones;
struct list_head rules;
struct list_head redirects;
+ struct list_head snats;
struct list_head forwards;
struct list_head ipsets;
-
- struct fw3_defaults running_defaults;
- struct list_head running_zones;
- struct list_head running_ipsets;
+ struct list_head includes;
bool disable_ipsets;
bool statefile;
};
+struct fw3_chain_spec {
+ int family;
+ int table;
+ int flag;
+ const char *format;
+};
+
struct fw3_option
{
const char *name;
- bool (*parse)(void *, const char *);
+ bool (*parse)(void *, const char *, bool);
uintptr_t offset;
size_t elem_size;
};
{ name, fw3_parse_##parse, offsetof(struct fw3_##structure, member), \
sizeof(struct fw3_##structure) }
-
-bool fw3_parse_bool(void *ptr, const char *val);
-bool fw3_parse_int(void *ptr, const char *val);
-bool fw3_parse_string(void *ptr, const char *val);
-bool fw3_parse_target(void *ptr, const char *val);
-bool fw3_parse_limit(void *ptr, const char *val);
-bool fw3_parse_device(void *ptr, const char *val);
-bool fw3_parse_address(void *ptr, const char *val);
-bool fw3_parse_mac(void *ptr, const char *val);
-bool fw3_parse_port(void *ptr, const char *val);
-bool fw3_parse_family(void *ptr, const char *val);
-bool fw3_parse_icmptype(void *ptr, const char *val);
-bool fw3_parse_protocol(void *ptr, const char *val);
-bool fw3_parse_ipset_method(void *ptr, const char *val);
-bool fw3_parse_ipset_datatype(void *ptr, const char *val);
-
-void fw3_parse_options(void *s, const struct fw3_option *opts,
+bool fw3_parse_bool(void *ptr, const char *val, bool is_list);
+bool fw3_parse_int(void *ptr, const char *val, bool is_list);
+bool fw3_parse_string(void *ptr, const char *val, bool is_list);
+bool fw3_parse_target(void *ptr, const char *val, bool is_list);
+bool fw3_parse_limit(void *ptr, const char *val, bool is_list);
+bool fw3_parse_device(void *ptr, const char *val, bool is_list);
+bool fw3_parse_address(void *ptr, const char *val, bool is_list);
+bool fw3_parse_network(void *ptr, const char *val, bool is_list);
+bool fw3_parse_mac(void *ptr, const char *val, bool is_list);
+bool fw3_parse_port(void *ptr, const char *val, bool is_list);
+bool fw3_parse_family(void *ptr, const char *val, bool is_list);
+bool fw3_parse_icmptype(void *ptr, const char *val, bool is_list);
+bool fw3_parse_protocol(void *ptr, const char *val, bool is_list);
+
+bool fw3_parse_ipset_method(void *ptr, const char *val, bool is_list);
+bool fw3_parse_ipset_datatype(void *ptr, const char *val, bool is_list);
+
+bool fw3_parse_include_type(void *ptr, const char *val, bool is_list);
+bool fw3_parse_reflection_source(void *ptr, const char *val, bool is_list);
+
+bool fw3_parse_date(void *ptr, const char *val, bool is_list);
+bool fw3_parse_time(void *ptr, const char *val, bool is_list);
+bool fw3_parse_weekdays(void *ptr, const char *val, bool is_list);
+bool fw3_parse_monthdays(void *ptr, const char *val, bool is_list);
+bool fw3_parse_mark(void *ptr, const char *val, bool is_list);
+bool fw3_parse_setmatch(void *ptr, const char *val, bool is_list);
+bool fw3_parse_direction(void *ptr, const char *val, bool is_list);
+
+bool fw3_parse_options(void *s, const struct fw3_option *opts,
struct uci_section *section);
+bool fw3_parse_blob_options(void *s, const struct fw3_option *opts,
+ struct blob_attr *a, const char *name);
-void fw3_format_in_out(struct fw3_device *in, struct fw3_device *out);
-void fw3_format_src_dest(struct fw3_address *src, struct fw3_address *dest);
-void fw3_format_sport_dport(struct fw3_port *sp, struct fw3_port *dp);
-void fw3_format_mac(struct fw3_mac *mac);
-void fw3_format_protocol(struct fw3_protocol *proto, enum fw3_family family);
-void fw3_format_icmptype(struct fw3_icmptype *icmp, enum fw3_family family);
-void fw3_format_limit(struct fw3_limit *limit);
-void fw3_format_ipset(struct fw3_ipset *ipset, bool invert);
-
-void __fw3_format_comment(const char *comment, ...);
-#define fw3_format_comment(...) __fw3_format_comment(__VA_ARGS__, NULL)
-
-void fw3_format_extra(const char *extra);
+const char * fw3_address_to_string(struct fw3_address *address,
+ bool allow_invert, bool as_cidr);
#endif