summaryrefslogtreecommitdiffstats
path: root/extensions/libipt_addrtype.c
diff options
context:
space:
mode:
authorLaszlo Attila Toth <panther@balabit.hu>2008-06-06 14:17:53 +0200
committerPatrick McHardy <kaber@trash.net>2008-06-06 14:17:53 +0200
commit4dfd25a405199c03fc694b9a43efdae6a91d8ae8 (patch)
tree69159dd97395ccc6dd127525dc46f70779b9b208 /extensions/libipt_addrtype.c
parente2562c8207dcb730ef2406faccf1d55ec42994f6 (diff)
addrtype match: added revision 1
In revision 1 address type checking can be limited to either the incoming or outgoing interface depending on the current chain. In the FORWARD chain only one of them is allowed at the same time. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'extensions/libipt_addrtype.c')
-rw-r--r--extensions/libipt_addrtype.c188
1 files changed, 173 insertions, 15 deletions
diff --git a/extensions/libipt_addrtype.c b/extensions/libipt_addrtype.c
index 9611c39a..97ad8044 100644
--- a/extensions/libipt_addrtype.c
+++ b/extensions/libipt_addrtype.c
@@ -36,7 +36,7 @@ static void addrtype_help_types(void)
printf(" %s\n", rtn_names[i]);
}
-static void addrtype_help(void)
+static void addrtype_help_v0(void)
{
printf(
"Address type match options:\n"
@@ -47,6 +47,19 @@ static void addrtype_help(void)
addrtype_help_types();
}
+static void addrtype_help_v1(void)
+{
+ printf(
+"Address type match options:\n"
+" [!] --src-type type[,...] Match source address type\n"
+" [!] --dst-type type[,...] Match destination address type\n"
+" --limit-iface-in Match only on the packet's incoming device\n"
+" --limit-iface-out Match only on the packet's incoming device\n"
+"\n"
+"Valid types: \n");
+ addrtype_help_types();
+}
+
static int
parse_type(const char *name, size_t len, u_int16_t *mask)
{
@@ -79,10 +92,12 @@ static void parse_types(const char *arg, u_int16_t *mask)
#define IPT_ADDRTYPE_OPT_SRCTYPE 0x1
#define IPT_ADDRTYPE_OPT_DSTTYPE 0x2
+#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN 0x4
+#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT 0x8
static int
-addrtype_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
+addrtype_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
{
struct ipt_addrtype_info *info =
(struct ipt_addrtype_info *) (*match)->data;
@@ -115,11 +130,72 @@ addrtype_parse(int c, char **argv, int invert, unsigned int *flags,
return 1;
}
-static void addrtype_check(unsigned int flags)
+static int
+addrtype_parse_v1(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct ipt_addrtype_info_v1 *info =
+ (struct ipt_addrtype_info_v1 *) (*match)->data;
+
+ switch (c) {
+ case '1':
+ if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify src-type twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->source);
+ if (invert)
+ info->flags |= IPT_ADDRTYPE_INVERT_SOURCE;
+ *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
+ break;
+ case '2':
+ if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify dst-type twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->dest);
+ if (invert)
+ info->flags |= IPT_ADDRTYPE_INVERT_DEST;
+ *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
+ break;
+ case '3':
+ if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify limit-iface-in twice");
+ info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN;
+ *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN;
+ break;
+ case '4':
+ if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify limit-iface-out twice");
+ info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT;
+ *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void addrtype_check_v0(unsigned int flags)
+{
+ if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you must specify --src-type or --dst-type");
+}
+
+static void addrtype_check_v1(unsigned int flags)
{
if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
exit_error(PARAMETER_PROBLEM,
"addrtype: you must specify --src-type or --dst-type");
+ if (flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN &&
+ flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you can't specify both --limit-iface-in "
+ "and --limit-iface-out");
}
static void print_types(u_int16_t mask)
@@ -136,8 +212,8 @@ static void print_types(u_int16_t mask)
printf(" ");
}
-static void addrtype_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
+static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match,
+ int numeric)
{
const struct ipt_addrtype_info *info =
(struct ipt_addrtype_info *) match->data;
@@ -157,7 +233,34 @@ static void addrtype_print(const void *ip, const struct xt_entry_match *match,
}
}
-static void addrtype_save(const void *ip, const struct xt_entry_match *match)
+static void addrtype_print_v1(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ const struct ipt_addrtype_info_v1 *info =
+ (struct ipt_addrtype_info_v1 *) match->data;
+
+ printf("ADDRTYPE match ");
+ if (info->source) {
+ printf("src-type ");
+ if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+ printf("!");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("dst-type ");
+ if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+ printf("!");
+ print_types(info->dest);
+ }
+ if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+ printf("limit-in ");
+ }
+ if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+ printf("limit-out ");
+ }
+}
+
+static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match)
{
const struct ipt_addrtype_info *info =
(struct ipt_addrtype_info *) match->data;
@@ -176,28 +279,83 @@ static void addrtype_save(const void *ip, const struct xt_entry_match *match)
}
}
+static void addrtype_save_v1(const void *ip, const struct xt_entry_match *match)
+{
+ const struct ipt_addrtype_info_v1 *info =
+ (struct ipt_addrtype_info_v1 *) match->data;
+
+ if (info->source) {
+ printf("--src-type ");
+ if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+ printf("! ");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("--dst-type ");
+ if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+ printf("! ");
+ print_types(info->dest);
+ }
+ if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+ printf("--limit-iface-in ");
+ }
+ if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+ printf("--limit-iface-out ");
+ }
+}
+
static const struct option addrtype_opts[] = {
{ "src-type", 1, NULL, '1' },
{ "dst-type", 1, NULL, '2' },
{ .name = NULL }
};
-static struct xtables_match addrtype_mt_reg = {
+static const struct option addrtype_opts_v0[] = {
+ { "src-type", 1, NULL, '1' },
+ { "dst-type", 1, NULL, '2' },
+ { .name = NULL }
+};
+
+static const struct option addrtype_opts_v1[] = {
+ { "src-type", 1, NULL, '1' },
+ { "dst-type", 1, NULL, '2' },
+ { "limit-iface-in", 0, NULL, '3' },
+ { "limit-iface-out", 0, NULL, '4' },
+ { .name = NULL }
+};
+
+static struct xtables_match addrtype_mt_reg_v0 = {
.name = "addrtype",
.version = XTABLES_VERSION,
.family = PF_INET,
.size = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
.userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
- .help = addrtype_help,
- .parse = addrtype_parse,
- .final_check = addrtype_check,
- .print = addrtype_print,
- .save = addrtype_save,
- .extra_opts = addrtype_opts,
+ .help = addrtype_help_v0,
+ .parse = addrtype_parse_v0,
+ .final_check = addrtype_check_v0,
+ .print = addrtype_print_v0,
+ .save = addrtype_save_v0,
+ .extra_opts = addrtype_opts_v0,
+};
+
+static struct xtables_match addrtype_mt_reg_v1 = {
+ .name = "addrtype",
+ .version = XTABLES_VERSION,
+ .family = PF_INET,
+ .size = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
+ .userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
+ .help = addrtype_help_v1,
+ .parse = addrtype_parse_v1,
+ .final_check = addrtype_check_v1,
+ .print = addrtype_print_v1,
+ .save = addrtype_save_v1,
+ .extra_opts = addrtype_opts_v1,
+ .revision = 1,
};
void _init(void)
{
- xtables_register_match(&addrtype_mt_reg);
+ xtables_register_match(&addrtype_mt_reg_v0);
+ xtables_register_match(&addrtype_mt_reg_v1);
}