Home | History | Annotate | Download | only in extensions
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <errno.h>
      5 #if defined(__GLIBC__) && __GLIBC__ == 2
      6 #include <net/ethernet.h>
      7 #else
      8 #include <linux/if_ether.h>
      9 #endif
     10 #include <xtables.h>
     11 #include <linux/netfilter_ipv4/ipt_realm.h>
     12 
     13 enum {
     14 	O_REALM = 0,
     15 };
     16 
     17 static void realm_help(void)
     18 {
     19 	printf(
     20 "realm match options:\n"
     21 "[!] --realm value[/mask]\n"
     22 "				Match realm\n");
     23 }
     24 
     25 static const struct xt_option_entry realm_opts[] = {
     26 	{.name = "realm", .id = O_REALM, .type = XTTYPE_STRING,
     27 	 .flags = XTOPT_MAND | XTOPT_INVERT},
     28 	XTOPT_TABLEEND,
     29 };
     30 
     31 /* array of realms from /etc/iproute2/rt_realms */
     32 static struct xtables_lmap *realms;
     33 
     34 static void realm_init(struct xt_entry_match *m)
     35 {
     36 	const char file[] = "/etc/iproute2/rt_realms";
     37 	realms = xtables_lmap_init(file);
     38 	if (realms == NULL && errno != ENOENT)
     39 		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
     40 }
     41 
     42 static void realm_parse(struct xt_option_call *cb)
     43 {
     44 	struct ipt_realm_info *realminfo = cb->data;
     45 	int id;
     46 	char *end;
     47 
     48 	xtables_option_parse(cb);
     49 	realminfo->id = strtoul(cb->arg, &end, 0);
     50 	if (end != cb->arg && (*end == '/' || *end == '\0')) {
     51 		if (*end == '/')
     52 			realminfo->mask = strtoul(end+1, &end, 0);
     53 		else
     54 			realminfo->mask = 0xffffffff;
     55 		if (*end != '\0' || end == cb->arg)
     56 			xtables_error(PARAMETER_PROBLEM,
     57 				   "Bad realm value \"%s\"", cb->arg);
     58 	} else {
     59 		id = xtables_lmap_name2id(realms, cb->arg);
     60 		if (id == -1)
     61 			xtables_error(PARAMETER_PROBLEM,
     62 				   "Realm \"%s\" not found", cb->arg);
     63 		realminfo->id = id;
     64 		realminfo->mask = 0xffffffff;
     65 	}
     66 	if (cb->invert)
     67 		realminfo->invert = 1;
     68 }
     69 
     70 static void
     71 print_realm(unsigned long id, unsigned long mask, int numeric)
     72 {
     73 	const char* name = NULL;
     74 
     75 	if (mask != 0xffffffff)
     76 		printf(" 0x%lx/0x%lx", id, mask);
     77 	else {
     78 		if (numeric == 0)
     79 			name = xtables_lmap_id2name(realms, id);
     80 		if (name)
     81 			printf(" %s", name);
     82 		else
     83 			printf(" 0x%lx", id);
     84 	}
     85 }
     86 
     87 static void realm_print(const void *ip, const struct xt_entry_match *match,
     88                         int numeric)
     89 {
     90 	const struct ipt_realm_info *ri = (const void *)match->data;
     91 
     92 	if (ri->invert)
     93 		printf(" !");
     94 
     95 	printf(" realm");
     96 	print_realm(ri->id, ri->mask, numeric);
     97 }
     98 
     99 static void realm_save(const void *ip, const struct xt_entry_match *match)
    100 {
    101 	const struct ipt_realm_info *ri = (const void *)match->data;
    102 
    103 	if (ri->invert)
    104 		printf(" !");
    105 
    106 	printf(" --realm");
    107 	print_realm(ri->id, ri->mask, 0);
    108 }
    109 
    110 static struct xtables_match realm_mt_reg = {
    111 	.name		= "realm",
    112 	.version	= XTABLES_VERSION,
    113 	.family		= NFPROTO_IPV4,
    114 	.size		= XT_ALIGN(sizeof(struct ipt_realm_info)),
    115 	.userspacesize	= XT_ALIGN(sizeof(struct ipt_realm_info)),
    116 	.help		= realm_help,
    117 	.init		= realm_init,
    118 	.print		= realm_print,
    119 	.save		= realm_save,
    120 	.x6_parse	= realm_parse,
    121 	.x6_options	= realm_opts,
    122 };
    123 
    124 void _init(void)
    125 {
    126 	xtables_register_match(&realm_mt_reg);
    127 }
    128