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