libxt_NFLOG.c revision a16e11418405980334734e9edda6b705aea31f8e
1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <getopt.h> 5#include <xtables.h> 6 7#include <linux/netfilter/x_tables.h> 8#include <linux/netfilter/xt_NFLOG.h> 9 10enum { 11 NFLOG_GROUP = 0x1, 12 NFLOG_PREFIX = 0x2, 13 NFLOG_RANGE = 0x4, 14 NFLOG_THRESHOLD = 0x8, 15}; 16 17static const struct option opts[] = { 18 { "nflog-group", 1, 0, NFLOG_GROUP }, 19 { "nflog-prefix", 1, 0, NFLOG_PREFIX }, 20 { "nflog-range", 1, 0, NFLOG_RANGE }, 21 { "nflog-threshold", 1, 0, NFLOG_THRESHOLD }, 22 {NULL}, 23}; 24 25static void help(void) 26{ 27 printf("NFLOG v%s options:\n" 28 " --nflog-group NUM NETLINK group used for logging\n" 29 " --nflog-range NUM Number of byte to copy\n" 30 " --nflog-threshold NUM Message threshold of in-kernel queue\n" 31 " --nflog-prefix STRING Prefix string for log messages\n\n", 32 IPTABLES_VERSION); 33} 34 35static void init(struct xt_entry_target *t, unsigned int *nfcache) 36{ 37 struct xt_nflog_info *info = (struct xt_nflog_info *)t->data; 38 39 info->group = 0; 40 info->threshold = XT_NFLOG_DEFAULT_THRESHOLD; 41} 42 43static int parse(int c, char **argv, int invert, unsigned int *flags, 44 const void *entry, 45 struct xt_entry_target **target) 46{ 47 struct xt_nflog_info *info = (struct xt_nflog_info *)(*target)->data; 48 int n; 49 50 switch (c) { 51 case NFLOG_GROUP: 52 if (*flags & NFLOG_GROUP) 53 exit_error(PARAMETER_PROBLEM, 54 "Can't specify --nflog-group twice"); 55 if (check_inverse(optarg, &invert, NULL, 0)) 56 exit_error(PARAMETER_PROBLEM, 57 "Unexpected `!' after --nflog-group"); 58 59 n = atoi(optarg); 60 if (n < 0) 61 exit_error(PARAMETER_PROBLEM, 62 "--nflog-group can not be negative"); 63 info->group = n; 64 break; 65 case NFLOG_PREFIX: 66 if (*flags & NFLOG_PREFIX) 67 exit_error(PARAMETER_PROBLEM, 68 "Can't specify --nflog-prefix twice"); 69 if (check_inverse(optarg, &invert, NULL, 0)) 70 exit_error(PARAMETER_PROBLEM, 71 "Unexpected `!' after --nflog-prefix"); 72 73 n = strlen(optarg); 74 if (n == 0) 75 exit_error(PARAMETER_PROBLEM, 76 "No prefix specified for --nflog-prefix"); 77 if (n >= sizeof(info->prefix)) 78 exit_error(PARAMETER_PROBLEM, 79 "--nflog-prefix too long, max %Zu characters", 80 sizeof(info->prefix) - 1); 81 if (n != strlen(strtok(optarg, "\n"))) 82 exit_error(PARAMETER_PROBLEM, 83 "Newlines are not allowed in --nflog-prefix"); 84 strcpy(info->prefix, optarg); 85 break; 86 case NFLOG_RANGE: 87 if (*flags & NFLOG_RANGE) 88 exit_error(PARAMETER_PROBLEM, 89 "Can't specify --nflog-range twice"); 90 n = atoi(optarg); 91 if (n < 0) 92 exit_error(PARAMETER_PROBLEM, 93 "Invalid --nflog-range, must be >= 0"); 94 info->len = n; 95 break; 96 case NFLOG_THRESHOLD: 97 if (*flags & NFLOG_THRESHOLD) 98 exit_error(PARAMETER_PROBLEM, 99 "Can't specify --nflog-threshold twice"); 100 n = atoi(optarg); 101 if (n < 1) 102 exit_error(PARAMETER_PROBLEM, 103 "Invalid --nflog-threshold, must be >= 1"); 104 info->threshold = n; 105 break; 106 default: 107 return 0; 108 } 109 *flags |= c; 110 return 1; 111} 112 113static void final_check(unsigned int flags) 114{ 115 return; 116} 117 118static void nflog_print(const struct xt_nflog_info *info, char *prefix) 119{ 120 if (info->prefix[0] != '\0') 121 printf("%snflog-prefix \"%s\" ", prefix, info->prefix); 122 if (info->group) 123 printf("%snflog-group %u ", prefix, info->group); 124 if (info->len) 125 printf("%snflog-range %u ", prefix, info->len); 126 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) 127 printf("%snflog-threshold %u ", prefix, info->threshold); 128} 129 130static void print(const void *ip, const struct xt_entry_target *target, 131 int numeric) 132{ 133 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 134 135 nflog_print(info, ""); 136} 137 138static void save(const void *ip, const struct xt_entry_target *target) 139{ 140 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 141 142 nflog_print(info, "--"); 143} 144 145static struct xtables_target nflog = { 146 .family = AF_INET, 147 .name = "NFLOG", 148 .version = IPTABLES_VERSION, 149 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 150 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 151 .help = help, 152 .init = init, 153 .parse = parse, 154 .final_check = final_check, 155 .print = print, 156 .save = save, 157 .extra_opts = opts, 158}; 159 160static struct xtables_target nflog6 = { 161 .family = AF_INET6, 162 .name = "NFLOG", 163 .version = IPTABLES_VERSION, 164 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 165 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 166 .help = help, 167 .init = init, 168 .parse = parse, 169 .final_check = final_check, 170 .print = print, 171 .save = save, 172 .extra_opts = opts, 173}; 174 175void _init(void) 176{ 177 xtables_register_target(&nflog); 178 xtables_register_target(&nflog6); 179} 180