libxt_NFLOG.c revision 932e648f38ac16b1ea14c1f66f23951388448c5a
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 NFLOG_opts[] = { 18 { "nflog-group", 1, NULL, NFLOG_GROUP }, 19 { "nflog-prefix", 1, NULL, NFLOG_PREFIX }, 20 { "nflog-range", 1, NULL, NFLOG_RANGE }, 21 { "nflog-threshold", 1, NULL, NFLOG_THRESHOLD }, 22 {NULL}, 23}; 24 25static void NFLOG_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 NFLOG_init(struct xt_entry_target *t) 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 NFLOG_parse(int c, char **argv, int invert, unsigned int *flags, 44 const void *entry, struct xt_entry_target **target) 45{ 46 struct xt_nflog_info *info = (struct xt_nflog_info *)(*target)->data; 47 int n; 48 49 switch (c) { 50 case NFLOG_GROUP: 51 if (*flags & NFLOG_GROUP) 52 exit_error(PARAMETER_PROBLEM, 53 "Can't specify --nflog-group twice"); 54 if (check_inverse(optarg, &invert, NULL, 0)) 55 exit_error(PARAMETER_PROBLEM, 56 "Unexpected `!' after --nflog-group"); 57 58 n = atoi(optarg); 59 if (n < 0) 60 exit_error(PARAMETER_PROBLEM, 61 "--nflog-group can not be negative"); 62 info->group = n; 63 break; 64 case NFLOG_PREFIX: 65 if (*flags & NFLOG_PREFIX) 66 exit_error(PARAMETER_PROBLEM, 67 "Can't specify --nflog-prefix twice"); 68 if (check_inverse(optarg, &invert, NULL, 0)) 69 exit_error(PARAMETER_PROBLEM, 70 "Unexpected `!' after --nflog-prefix"); 71 72 n = strlen(optarg); 73 if (n == 0) 74 exit_error(PARAMETER_PROBLEM, 75 "No prefix specified for --nflog-prefix"); 76 if (n >= sizeof(info->prefix)) 77 exit_error(PARAMETER_PROBLEM, 78 "--nflog-prefix too long, max %Zu characters", 79 sizeof(info->prefix) - 1); 80 if (n != strlen(strtok(optarg, "\n"))) 81 exit_error(PARAMETER_PROBLEM, 82 "Newlines are not allowed in --nflog-prefix"); 83 strcpy(info->prefix, optarg); 84 break; 85 case NFLOG_RANGE: 86 if (*flags & NFLOG_RANGE) 87 exit_error(PARAMETER_PROBLEM, 88 "Can't specify --nflog-range twice"); 89 n = atoi(optarg); 90 if (n < 0) 91 exit_error(PARAMETER_PROBLEM, 92 "Invalid --nflog-range, must be >= 0"); 93 info->len = n; 94 break; 95 case NFLOG_THRESHOLD: 96 if (*flags & NFLOG_THRESHOLD) 97 exit_error(PARAMETER_PROBLEM, 98 "Can't specify --nflog-threshold twice"); 99 n = atoi(optarg); 100 if (n < 1) 101 exit_error(PARAMETER_PROBLEM, 102 "Invalid --nflog-threshold, must be >= 1"); 103 info->threshold = n; 104 break; 105 default: 106 return 0; 107 } 108 *flags |= c; 109 return 1; 110} 111 112static void nflog_print(const struct xt_nflog_info *info, char *prefix) 113{ 114 if (info->prefix[0] != '\0') 115 printf("%snflog-prefix \"%s\" ", prefix, info->prefix); 116 if (info->group) 117 printf("%snflog-group %u ", prefix, info->group); 118 if (info->len) 119 printf("%snflog-range %u ", prefix, info->len); 120 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) 121 printf("%snflog-threshold %u ", prefix, info->threshold); 122} 123 124static void NFLOG_print(const void *ip, const struct xt_entry_target *target, 125 int numeric) 126{ 127 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 128 129 nflog_print(info, ""); 130} 131 132static void NFLOG_save(const void *ip, const struct xt_entry_target *target) 133{ 134 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 135 136 nflog_print(info, "--"); 137} 138 139static struct xtables_target nflog_target = { 140 .family = AF_INET, 141 .name = "NFLOG", 142 .version = IPTABLES_VERSION, 143 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 144 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 145 .help = NFLOG_help, 146 .init = NFLOG_init, 147 .parse = NFLOG_parse, 148 .print = NFLOG_print, 149 .save = NFLOG_save, 150 .extra_opts = NFLOG_opts, 151}; 152 153static struct xtables_target nflog_target6 = { 154 .family = AF_INET6, 155 .name = "NFLOG", 156 .version = IPTABLES_VERSION, 157 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 158 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 159 .help = NFLOG_help, 160 .init = NFLOG_init, 161 .parse = NFLOG_parse, 162 .print = NFLOG_print, 163 .save = NFLOG_save, 164 .extra_opts = NFLOG_opts, 165}; 166 167void _init(void) 168{ 169 xtables_register_target(&nflog_target); 170 xtables_register_target(&nflog_target6); 171} 172