libxt_connlabel.c revision 51340f7b6a1103b12d86ef488f7140406d80401e
1#include <errno.h> 2#include <stdbool.h> 3#include <string.h> 4#include <stdio.h> 5#include <stdint.h> 6#include <xtables.h> 7#include <linux/netfilter/xt_connlabel.h> 8#include <libnetfilter_conntrack/libnetfilter_conntrack.h> 9 10enum { 11 O_LABEL = 0, 12 O_SET = 1, 13}; 14 15static struct nfct_labelmap *map; 16 17static void connlabel_mt_help(void) 18{ 19 puts( 20"connlabel match options:\n" 21"[!] --label name Match if label has been set on connection\n" 22" --set Set label on connection"); 23} 24 25static const struct xt_option_entry connlabel_mt_opts[] = { 26 {.name = "label", .id = O_LABEL, .type = XTTYPE_STRING, 27 .min = 1, .flags = XTOPT_MAND|XTOPT_INVERT}, 28 {.name = "set", .id = O_SET, .type = XTTYPE_NONE}, 29 XTOPT_TABLEEND, 30}; 31 32static void connlabel_mt_parse(struct xt_option_call *cb) 33{ 34 struct xt_connlabel_mtinfo *info = cb->data; 35 int tmp; 36 37 xtables_option_parse(cb); 38 39 switch (cb->entry->id) { 40 case O_LABEL: 41 tmp = nfct_labelmap_get_bit(map, cb->arg); 42 if (tmp < 0) 43 xtables_error(PARAMETER_PROBLEM, "label '%s' not found", cb->arg); 44 info->bit = tmp; 45 if (cb->invert) 46 info->options |= XT_CONNLABEL_OP_INVERT; 47 break; 48 case O_SET: 49 info->options |= XT_CONNLABEL_OP_SET; 50 break; 51 } 52 53} 54 55static const char *connlabel_get_name(int b) 56{ 57 const char *name = nfct_labelmap_get_name(map, b); 58 if (name && strcmp(name, "")) 59 return name; 60 return NULL; 61} 62 63static void 64connlabel_mt_print_op(const struct xt_connlabel_mtinfo *info, const char *prefix) 65{ 66 if (info->options & XT_CONNLABEL_OP_SET) 67 printf(" %sset", prefix); 68} 69 70static void 71connlabel_mt_print(const void *ip, const struct xt_entry_match *match, int numeric) 72{ 73 const struct xt_connlabel_mtinfo *info = (const void *)match->data; 74 const char *name = connlabel_get_name(info->bit); 75 76 printf(" connlabel"); 77 if (info->options & XT_CONNLABEL_OP_INVERT) 78 printf(" !"); 79 if (numeric || name == NULL) { 80 printf(" %u", info->bit); 81 } else { 82 printf(" '%s'", name); 83 } 84 connlabel_mt_print_op(info, ""); 85} 86 87static void 88connlabel_mt_save(const void *ip, const struct xt_entry_match *match) 89{ 90 const struct xt_connlabel_mtinfo *info = (const void *)match->data; 91 const char *name = connlabel_get_name(info->bit); 92 93 if (info->options & XT_CONNLABEL_OP_INVERT) 94 printf(" !"); 95 if (name) 96 printf(" --label \"%s\"", name); 97 else 98 printf(" --label \"%u\"", info->bit); 99 connlabel_mt_print_op(info, "--"); 100} 101 102static struct xtables_match connlabel_mt_reg = { 103 .family = NFPROTO_UNSPEC, 104 .name = "connlabel", 105 .version = XTABLES_VERSION, 106 .size = XT_ALIGN(sizeof(struct xt_connlabel_mtinfo)), 107 .userspacesize = offsetof(struct xt_connlabel_mtinfo, bit), 108 .help = connlabel_mt_help, 109 .print = connlabel_mt_print, 110 .save = connlabel_mt_save, 111 .x6_parse = connlabel_mt_parse, 112 .x6_options = connlabel_mt_opts, 113}; 114 115void _init(void) 116{ 117 map = nfct_labelmap_new(NULL); 118 if (!map) { 119 fprintf(stderr, "cannot open connlabel.conf, not registering '%s' match: %s\n", 120 connlabel_mt_reg.name, strerror(errno)); 121 return; 122 } 123 xtables_register_match(&connlabel_mt_reg); 124} 125