1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <getopt.h> 5#include <ip6tables.h> 6 7#include <linux/netfilter_ipv6/ip6_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 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}; 23 24static void help(void) 25{ 26 printf("NFLOG v%s options:\n" 27 " --nflog-group NUM NETLINK group used for logging\n" 28 " --nflog-range NUM Number of byte to copy\n" 29 " --nflog-threshold NUM Message threshold of in-kernel queue\n" 30 " --nflog-prefix STRING Prefix string for log messages\n\n", 31 IPTABLES_VERSION); 32} 33 34static void init(struct ip6t_entry_target *t, unsigned int *nfcache) 35{ 36 struct xt_nflog_info *info = (struct xt_nflog_info *)t->data; 37 38 info->group = 0; 39 info->threshold = XT_NFLOG_DEFAULT_THRESHOLD; 40} 41 42static int parse(int c, char **argv, int invert, unsigned int *flags, 43 const struct ip6t_entry *entry, 44 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 final_check(unsigned int flags) 113{ 114 return; 115} 116 117static void nflog_print(const struct xt_nflog_info *info, char *prefix) 118{ 119 if (info->prefix[0] != '\0') 120 printf("%snflog-prefix \"%s\" ", prefix, info->prefix); 121 if (info->group) 122 printf("%snflog-group %u ", prefix, info->group); 123 if (info->len) 124 printf("%snflog-range %u ", prefix, info->len); 125 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) 126 printf("%snflog-threshold %u ", prefix, info->threshold); 127} 128 129static void print(const struct ip6t_ip6 *ip, const struct xt_entry_target *target, 130 int numeric) 131{ 132 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 133 134 nflog_print(info, ""); 135} 136 137static void save(const struct ip6t_ip6 *ip, const struct xt_entry_target *target) 138{ 139 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 140 141 nflog_print(info, "--"); 142} 143 144static struct ip6tables_target nflog = { 145 .name = "NFLOG", 146 .version = IPTABLES_VERSION, 147 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 148 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 149 .help = help, 150 .init = init, 151 .parse = parse, 152 .final_check = final_check, 153 .print = print, 154 .save = save, 155 .extra_opts = opts, 156}; 157 158void _init(void) 159{ 160 register_target6(&nflog); 161} 162