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. */
22 "realm v%s options:\n"
23 " --realm [!] value[/mask]\n"
25 "\n", IPTABLES_VERSION);
28 static struct option opts[] = {
29 { "realm", 1, 0, '1' },
37 struct realmname* next;
40 /* array of realms from /etc/iproute2/rt_realms */
41 static struct realmname *realms = NULL;
42 /* 1 if loading failed */
43 static int rdberr = 0;
48 const char* rfnm = "/etc/iproute2/rt_realms";
53 struct realmname *oldnm = NULL, *newnm = NULL;
55 fil = fopen(rfnm, "r");
61 while (fgets(buf, sizeof(buf), fil)) {
63 while ((*cur == ' ') || (*cur == '\t'))
65 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
68 /* iproute2 allows hex and dec format */
70 id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
71 if ((nxt == cur) || errno)
74 /* same boundaries as in iproute2 */
75 if (id < 0 || id > 255)
81 while ((*cur == ' ') || (*cur == '\t'))
83 if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
86 while ((*nxt != 0) && !isspace(*nxt))
91 /* found valid data */
92 newnm = (struct realmname*)malloc(sizeof(struct realmname));
94 perror("libipt_realm: malloc failed");
98 newnm->len = nxt - cur;
99 newnm->name = (char*)malloc(newnm->len + 1);
100 if (newnm->name == NULL) {
101 perror("libipt_realm: malloc failed");
104 strncpy(newnm->name, cur, newnm->len);
105 newnm->name[newnm->len] = 0;
118 /* get realm id for name, -1 if error/not found */
119 int realm_name2id(const char* name)
121 struct realmname* cur;
123 if ((realms == NULL) && (rdberr == 0))
129 if (!strncmp(name, cur->name, cur->len + 1))
136 /* get realm name for id, NULL if error/not found */
137 const char* realm_id2name(int id)
139 struct realmname* cur;
141 if ((realms == NULL) && (rdberr == 0))
155 /* Function which parses command options; returns true if it
158 parse(int c, char **argv, int invert, unsigned int *flags,
159 const struct ipt_entry *entry,
160 unsigned int *nfcache,
161 struct ipt_entry_match **match)
163 struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
169 check_inverse(argv[optind-1], &invert, &optind, 0);
170 end = optarg = argv[optind-1];
171 realminfo->id = strtoul(optarg, &end, 0);
172 if (end != optarg && (*end == '/' || *end == '\0')) {
174 realminfo->mask = strtoul(end+1, &end, 0);
176 realminfo->mask = 0xffffffff;
177 if (*end != '\0' || end == optarg)
178 exit_error(PARAMETER_PROBLEM,
179 "Bad realm value `%s'", optarg);
181 id = realm_name2id(optarg);
183 exit_error(PARAMETER_PROBLEM,
184 "Realm `%s' not found", optarg);
185 realminfo->id = (u_int32_t)id;
186 realminfo->mask = 0xffffffff;
189 realminfo->invert = 1;
200 print_realm(unsigned long id, unsigned long mask, int numeric)
202 const char* name = NULL;
204 if (mask != 0xffffffff)
205 printf("0x%lx/0x%lx ", id, mask);
208 name = realm_id2name(id);
212 printf("0x%lx ", id);
216 /* Prints out the matchinfo. */
218 print(const struct ipt_ip *ip,
219 const struct ipt_entry_match *match,
222 struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
228 print_realm(ri->id, ri->mask, numeric);
232 /* Saves the union ipt_matchinfo in parsable form to stdout. */
234 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
236 struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
242 print_realm(ri->id, ri->mask, 0);
245 /* Final check; must have specified --mark. */
247 final_check(unsigned int flags)
250 exit_error(PARAMETER_PROBLEM,
251 "realm match: You must specify `--realm'");
254 static struct iptables_match realm = { NULL,
256 .version = IPTABLES_VERSION,
257 .size = IPT_ALIGN(sizeof(struct ipt_realm_info)),
258 .userspacesize = IPT_ALIGN(sizeof(struct ipt_realm_info)),
261 .final_check = &final_check,
269 register_match(&realm);