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
);