1 /* Shared library add-on to iptables to add realm matching support. */
9 #if defined(__GLIBC__) && __GLIBC__ == 2
10 #include <net/ethernet.h>
12 #include <linux/if_ether.h>
15 #include <linux/netfilter_ipv4/ipt_realm.h>
17 static void realm_help(void)
20 "realm match options:\n"
21 "[!] --realm value[/mask]\n"
25 static const struct option realm_opts[] = {
26 { "realm", 1, NULL, '1' },
34 struct realmname* next;
37 /* array of realms from /etc/iproute2/rt_realms */
38 static struct realmname *realms;
39 /* 1 if loading failed */
42 static void load_realms(void)
44 const char* rfnm = "/etc/iproute2/rt_realms";
49 struct realmname *oldnm = NULL, *newnm = NULL;
51 fil = fopen(rfnm, "r");
57 while (fgets(buf, sizeof(buf), fil)) {
59 while ((*cur == ' ') || (*cur == '\t'))
61 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
64 /* iproute2 allows hex and dec format */
66 id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
67 if ((nxt == cur) || errno)
70 /* same boundaries as in iproute2 */
71 if (id < 0 || id > 255)
77 while ((*cur == ' ') || (*cur == '\t'))
79 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
82 while ((*nxt != 0) && !isspace(*nxt))
87 /* found valid data */
88 newnm = malloc(sizeof(struct realmname));
90 perror("libipt_realm: malloc failed");
94 newnm->len = nxt - cur;
95 newnm->name = malloc(newnm->len + 1);
96 if (newnm->name == NULL) {
97 perror("libipt_realm: malloc failed");
100 strncpy(newnm->name, cur, newnm->len);
101 newnm->name[newnm->len] = 0;
114 /* get realm id for name, -1 if error/not found */
115 static int realm_name2id(const char* name)
117 struct realmname* cur;
119 if ((realms == NULL) && (rdberr == 0))
125 if (!strncmp(name, cur->name, cur->len + 1))
132 /* get realm name for id, NULL if error/not found */
133 static const char *realm_id2name(int id)
135 struct realmname* cur;
137 if ((realms == NULL) && (rdberr == 0))
150 static int realm_parse(int c, char **argv, int invert, unsigned int *flags,
151 const void *entry, struct xt_entry_match **match)
153 struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
159 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
160 end = optarg = optarg;
161 realminfo->id = strtoul(optarg, &end, 0);
162 if (end != optarg && (*end == '/' || *end == '\0')) {
164 realminfo->mask = strtoul(end+1, &end, 0);
166 realminfo->mask = 0xffffffff;
167 if (*end != '\0' || end == optarg)
168 xtables_error(PARAMETER_PROBLEM,
169 "Bad realm value `%s'", optarg);
171 id = realm_name2id(optarg);
173 xtables_error(PARAMETER_PROBLEM,
174 "Realm `%s' not found", optarg);
176 realminfo->mask = 0xffffffff;
179 realminfo->invert = 1;
190 print_realm(unsigned long id, unsigned long mask, int numeric)
192 const char* name = NULL;
194 if (mask != 0xffffffff)
195 printf("0x%lx/0x%lx ", id, mask);
198 name = realm_id2name(id);
202 printf("0x%lx ", id);
206 static void realm_print(const void *ip, const struct xt_entry_match *match,
209 const struct ipt_realm_info *ri = (const void *)match->data;
215 print_realm(ri->id, ri->mask, numeric);
218 static void realm_save(const void *ip, const struct xt_entry_match *match)
220 const struct ipt_realm_info *ri = (const void *)match->data;
226 print_realm(ri->id, ri->mask, 0);
229 static void realm_check(unsigned int flags)
232 xtables_error(PARAMETER_PROBLEM,
233 "realm match: You must specify `--realm'");
236 static struct xtables_match realm_mt_reg = {
238 .version = XTABLES_VERSION,
239 .family = NFPROTO_IPV4,
240 .size = XT_ALIGN(sizeof(struct ipt_realm_info)),
241 .userspacesize = XT_ALIGN(sizeof(struct ipt_realm_info)),
243 .parse = realm_parse,
244 .final_check = realm_check,
245 .print = realm_print,
247 .extra_opts = realm_opts,
252 xtables_register_match(&realm_mt_reg);