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 /* Function which prints out usage message. */
18 static void realm_help(void)
21 "realm match options:\n"
22 " --realm [!] value[/mask]\n"
26 static const struct option realm_opts[] = {
27 { "realm", 1, NULL, '1' },
35 struct realmname* next;
38 /* array of realms from /etc/iproute2/rt_realms */
39 static struct realmname *realms = NULL;
40 /* 1 if loading failed */
41 static int rdberr = 0;
44 static void load_realms(void)
46 const char* rfnm = "/etc/iproute2/rt_realms";
51 struct realmname *oldnm = NULL, *newnm = NULL;
53 fil = fopen(rfnm, "r");
59 while (fgets(buf, sizeof(buf), fil)) {
61 while ((*cur == ' ') || (*cur == '\t'))
63 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
66 /* iproute2 allows hex and dec format */
68 id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
69 if ((nxt == cur) || errno)
72 /* same boundaries as in iproute2 */
73 if (id < 0 || id > 255)
79 while ((*cur == ' ') || (*cur == '\t'))
81 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
84 while ((*nxt != 0) && !isspace(*nxt))
89 /* found valid data */
90 newnm = (struct realmname*)malloc(sizeof(struct realmname));
92 perror("libipt_realm: malloc failed");
96 newnm->len = nxt - cur;
97 newnm->name = (char*)malloc(newnm->len + 1);
98 if (newnm->name == NULL) {
99 perror("libipt_realm: malloc failed");
102 strncpy(newnm->name, cur, newnm->len);
103 newnm->name[newnm->len] = 0;
116 /* get realm id for name, -1 if error/not found */
117 static int realm_name2id(const char* name)
119 struct realmname* cur;
121 if ((realms == NULL) && (rdberr == 0))
127 if (!strncmp(name, cur->name, cur->len + 1))
134 /* get realm name for id, NULL if error/not found */
135 static const char *realm_id2name(int id)
137 struct realmname* cur;
139 if ((realms == NULL) && (rdberr == 0))
153 /* Function which parses command options; returns true if it
155 static int realm_parse(int c, char **argv, int invert, unsigned int *flags,
156 const void *entry, struct xt_entry_match **match)
158 struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
164 check_inverse(argv[optind-1], &invert, &optind, 0);
165 end = optarg = argv[optind-1];
166 realminfo->id = strtoul(optarg, &end, 0);
167 if (end != optarg && (*end == '/' || *end == '\0')) {
169 realminfo->mask = strtoul(end+1, &end, 0);
171 realminfo->mask = 0xffffffff;
172 if (*end != '\0' || end == optarg)
173 exit_error(PARAMETER_PROBLEM,
174 "Bad realm value `%s'", optarg);
176 id = realm_name2id(optarg);
178 exit_error(PARAMETER_PROBLEM,
179 "Realm `%s' not found", optarg);
180 realminfo->id = (u_int32_t)id;
181 realminfo->mask = 0xffffffff;
184 realminfo->invert = 1;
195 print_realm(unsigned long id, unsigned long mask, int numeric)
197 const char* name = NULL;
199 if (mask != 0xffffffff)
200 printf("0x%lx/0x%lx ", id, mask);
203 name = realm_id2name(id);
207 printf("0x%lx ", id);
211 /* Prints out the matchinfo. */
212 static void realm_print(const void *ip, const struct xt_entry_match *match,
215 struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
221 print_realm(ri->id, ri->mask, numeric);
225 /* Saves the union ipt_matchinfo in parsable form to stdout. */
226 static void realm_save(const void *ip, const struct xt_entry_match *match)
228 struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
234 print_realm(ri->id, ri->mask, 0);
237 /* Final check; must have specified --mark. */
238 static void realm_check(unsigned int flags)
241 exit_error(PARAMETER_PROBLEM,
242 "realm match: You must specify `--realm'");
245 static struct xtables_match realm_mt_reg = {
247 .version = XTABLES_VERSION,
249 .size = XT_ALIGN(sizeof(struct ipt_realm_info)),
250 .userspacesize = XT_ALIGN(sizeof(struct ipt_realm_info)),
252 .parse = realm_parse,
253 .final_check = realm_check,
254 .print = realm_print,
256 .extra_opts = realm_opts,
261 xtables_register_match(&realm_mt_reg);