libipt_realm.c revision 09cad6470a1ef596876879c01bd8f9148e896dbe
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 13enum { 14 O_REALM = 0, 15}; 16 17static void realm_help(void) 18{ 19 printf( 20"realm match options:\n" 21"[!] --realm value[/mask]\n" 22" Match realm\n"); 23} 24 25static 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 */ 32static struct xtables_lmap *realms; 33 34static void realm_init(struct xt_entry_match *m) 35{ 36 const char file[] = "/etc/iproute2/rt_realms"; 37 38 realms = xtables_lmap_init(file); 39 if (realms == NULL && errno != ENOENT) 40 fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno)); 41} 42 43static void realm_parse(struct xt_option_call *cb) 44{ 45 struct xt_realm_info *realminfo = cb->data; 46 int id; 47 char *end; 48 49 xtables_option_parse(cb); 50 realminfo->id = strtoul(cb->arg, &end, 0); 51 if (end != cb->arg && (*end == '/' || *end == '\0')) { 52 if (*end == '/') 53 realminfo->mask = strtoul(end+1, &end, 0); 54 else 55 realminfo->mask = 0xffffffff; 56 if (*end != '\0' || end == cb->arg) 57 xtables_error(PARAMETER_PROBLEM, 58 "Bad realm value \"%s\"", cb->arg); 59 } else { 60 id = xtables_lmap_name2id(realms, cb->arg); 61 if (id == -1) 62 xtables_error(PARAMETER_PROBLEM, 63 "Realm \"%s\" not found", cb->arg); 64 realminfo->id = id; 65 realminfo->mask = 0xffffffff; 66 } 67 if (cb->invert) 68 realminfo->invert = 1; 69} 70 71static void 72print_realm(unsigned long id, unsigned long mask, int numeric) 73{ 74 const char *name = NULL; 75 76 if (mask != 0xffffffff) 77 printf(" 0x%lx/0x%lx", id, mask); 78 else { 79 if (numeric == 0) 80 name = xtables_lmap_id2name(realms, id); 81 if (name) 82 printf(" %s", name); 83 else 84 printf(" 0x%lx", id); 85 } 86} 87 88static void realm_print(const void *ip, const struct xt_entry_match *match, 89 int numeric) 90{ 91 const struct xt_realm_info *ri = (const void *)match->data; 92 93 if (ri->invert) 94 printf(" !"); 95 96 printf(" realm"); 97 print_realm(ri->id, ri->mask, numeric); 98} 99 100static void realm_save(const void *ip, const struct xt_entry_match *match) 101{ 102 const struct xt_realm_info *ri = (const void *)match->data; 103 104 if (ri->invert) 105 printf(" !"); 106 107 printf(" --realm"); 108 print_realm(ri->id, ri->mask, 0); 109} 110 111static void 112print_realm_xlate(unsigned long id, unsigned long mask, 113 int numeric, struct xt_xlate *xl, uint32_t op) 114{ 115 const char *name = NULL; 116 117 if (mask != 0xffffffff) 118 xt_xlate_add(xl, " and 0x%lx %s 0x%lx ", mask, 119 op == XT_OP_EQ ? "==" : "!=", id); 120 else { 121 if (numeric == 0) 122 name = xtables_lmap_id2name(realms, id); 123 if (name) 124 xt_xlate_add(xl, "%s%s ", 125 op == XT_OP_EQ ? "" : "!= ", name); 126 else 127 xt_xlate_add(xl, " %s0x%lx ", 128 op == XT_OP_EQ ? "" : "!= ", id); 129 } 130} 131 132static int realm_xlate(const void *ip, const struct xt_entry_match *match, 133 struct xt_xlate *xl, int numeric) 134{ 135 const struct xt_realm_info *ri = (const void *)match->data; 136 enum xt_op op = XT_OP_EQ; 137 138 if (ri->invert) 139 op = XT_OP_NEQ; 140 141 xt_xlate_add(xl, "rtclassid"); 142 print_realm_xlate(ri->id, ri->mask, 0, xl, op); 143 144 return 1; 145} 146 147static struct xtables_match realm_mt_reg = { 148 .name = "realm", 149 .version = XTABLES_VERSION, 150 .family = NFPROTO_IPV4, 151 .size = XT_ALIGN(sizeof(struct xt_realm_info)), 152 .userspacesize = XT_ALIGN(sizeof(struct xt_realm_info)), 153 .help = realm_help, 154 .init = realm_init, 155 .print = realm_print, 156 .save = realm_save, 157 .x6_parse = realm_parse, 158 .x6_options = realm_opts, 159 .xlate = realm_xlate, 160}; 161 162void _init(void) 163{ 164 xtables_register_match(&realm_mt_reg); 165} 166