blob: 4487c83304ab7aeef16b9ffb62e1705c2c9a654b [file] [log] [blame]
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +01001/* Shared library add-on to iptables to add devgroup matching support.
2 *
3 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
4 */
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +01005#include <stdio.h>
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +01006#include <string.h>
7#include <stdlib.h>
8#include <errno.h>
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +01009#include <xtables.h>
10#include <linux/netfilter/xt_devgroup.h>
11
12static void devgroup_help(void)
13{
14 printf(
15"devgroup match options:\n"
16"[!] --src-group value[/mask] Match device group of incoming device\n"
17"[!] --dst-group value[/mask] Match device group of outgoing device\n"
18 );
19}
20
21enum {
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010022 O_SRC_GROUP = 0,
23 O_DST_GROUP,
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010024};
25
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010026static const struct xt_option_entry devgroup_opts[] = {
27 {.name = "src-group", .id = O_SRC_GROUP, .type = XTTYPE_STRING,
28 .flags = XTOPT_INVERT},
29 {.name = "dst-group", .id = O_DST_GROUP, .type = XTTYPE_STRING,
30 .flags = XTOPT_INVERT},
31 XTOPT_TABLEEND,
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010032};
33
34/* array of devgroups from /etc/iproute2/group_map */
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010035static struct xtables_lmap *devgroups;
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010036
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010037static void devgroup_init(struct xt_entry_match *match)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010038{
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010039 const char file[] = "/etc/iproute2/group_map";
40 devgroups = xtables_lmap_init(file);
41 if (devgroups == NULL && errno != ENOENT)
42 fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010043}
44
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010045static void devgroup_parse(struct xt_option_call *cb)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010046{
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010047 struct xt_devgroup_info *info = cb->data;
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010048 unsigned int id;
49 char *end;
50
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010051 xtables_option_parse(cb);
52 switch (cb->entry->id) {
53 case O_SRC_GROUP:
54 info->src_group = strtoul(cb->arg, &end, 0);
55 if (end != cb->arg && (*end == '/' || *end == '\0')) {
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010056 if (*end == '/')
57 info->src_mask = strtoul(end+1, &end, 0);
58 else
59 info->src_mask = 0xffffffff;
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010060 if (*end != '\0' || end == cb->arg)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010061 xtables_error(PARAMETER_PROBLEM,
62 "Bad src-group value `%s'",
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010063 cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010064 } else {
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010065 id = xtables_lmap_name2id(devgroups, cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010066 if (id == -1)
67 xtables_error(PARAMETER_PROBLEM,
68 "Device group `%s' not found",
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010069 cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010070 info->src_group = id;
71 info->src_mask = 0xffffffff;
72 }
Lutz Jaenicke17f79372011-05-23 16:28:25 +020073 info->flags |= XT_DEVGROUP_MATCH_SRC;
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010074 if (cb->invert)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010075 info->flags |= XT_DEVGROUP_INVERT_SRC;
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010076 break;
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010077 case O_DST_GROUP:
78 info->dst_group = strtoul(cb->arg, &end, 0);
79 if (end != cb->arg && (*end == '/' || *end == '\0')) {
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010080 if (*end == '/')
81 info->dst_mask = strtoul(end+1, &end, 0);
82 else
83 info->dst_mask = 0xffffffff;
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010084 if (*end != '\0' || end == cb->arg)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010085 xtables_error(PARAMETER_PROBLEM,
86 "Bad dst-group value `%s'",
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010087 cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010088 } else {
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010089 id = xtables_lmap_name2id(devgroups, cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010090 if (id == -1)
91 xtables_error(PARAMETER_PROBLEM,
92 "Device group `%s' not found",
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010093 cb->arg);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010094 info->dst_group = id;
95 info->dst_mask = 0xffffffff;
96 }
Lutz Jaenicke17f79372011-05-23 16:28:25 +020097 info->flags |= XT_DEVGROUP_MATCH_DST;
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +010098 if (cb->invert)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +010099 info->flags |= XT_DEVGROUP_INVERT_DST;
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100100 break;
101 }
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100102}
103
104static void
105print_devgroup(unsigned int id, unsigned int mask, int numeric)
106{
107 const char *name = NULL;
108
109 if (mask != 0xffffffff)
Jan Engelhardtc0f6d172011-02-16 02:42:21 +0100110 printf("0x%x/0x%x", id, mask);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100111 else {
112 if (numeric == 0)
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +0100113 name = xtables_lmap_id2name(devgroups, id);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100114 if (name)
Jan Engelhardtc0f6d172011-02-16 02:42:21 +0100115 printf("%s", name);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100116 else
Jan Engelhardtc0f6d172011-02-16 02:42:21 +0100117 printf("0x%x", id);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100118 }
119}
120
121static void devgroup_show(const char *pfx, const struct xt_devgroup_info *info,
122 int numeric)
123{
124 if (info->flags & XT_DEVGROUP_MATCH_SRC) {
125 if (info->flags & XT_DEVGROUP_INVERT_SRC)
Jan Engelhardtc0f6d172011-02-16 02:42:21 +0100126 printf(" !");
127 printf(" %ssrc-group ", pfx);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100128 print_devgroup(info->src_group, info->src_mask, numeric);
129 }
130
131 if (info->flags & XT_DEVGROUP_MATCH_DST) {
132 if (info->flags & XT_DEVGROUP_INVERT_DST)
Jan Engelhardtc0f6d172011-02-16 02:42:21 +0100133 printf(" !");
134 printf(" %sdst-group ", pfx);
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100135 print_devgroup(info->src_group, info->src_mask, numeric);
136 }
137}
138
139static void devgroup_print(const void *ip, const struct xt_entry_match *match,
140 int numeric)
141{
142 const struct xt_devgroup_info *info = (const void *)match->data;
143
144 devgroup_show("", info, numeric);
145}
146
147static void devgroup_save(const void *ip, const struct xt_entry_match *match)
148{
149 const struct xt_devgroup_info *info = (const void *)match->data;
150
151 devgroup_show("--", info, 0);
152}
153
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +0100154static void devgroup_check(struct xt_fcheck_call *cb)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100155{
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +0100156 if (cb->xflags == 0)
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100157 xtables_error(PARAMETER_PROBLEM,
158 "devgroup match: You must specify either "
159 "'--src-group' or '--dst-group'");
160}
161
162static struct xtables_match devgroup_mt_reg = {
163 .name = "devgroup",
164 .version = XTABLES_VERSION,
165 .family = NFPROTO_UNSPEC,
166 .size = XT_ALIGN(sizeof(struct xt_devgroup_info)),
167 .userspacesize = XT_ALIGN(sizeof(struct xt_devgroup_info)),
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +0100168 .init = devgroup_init,
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100169 .help = devgroup_help,
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100170 .print = devgroup_print,
171 .save = devgroup_save,
Jan Engelhardt5d8e61e2011-03-06 16:02:03 +0100172 .x6_parse = devgroup_parse,
173 .x6_fcheck = devgroup_check,
174 .x6_options = devgroup_opts,
Patrick McHardy9ee2a9f2011-02-03 06:10:41 +0100175};
176
177void _init(void)
178{
179 xtables_register_match(&devgroup_mt_reg);
180}