libxt_NFLOG.c revision c5e85736c207f211d82d2878a5781f512327dfce
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 { .name = NULL } 23}; 24 25static void NFLOG_help(void) 26{ 27 printf("NFLOG target 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"); 32} 33 34static void NFLOG_init(struct xt_entry_target *t) 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 NFLOG_parse(int c, char **argv, int invert, unsigned int *flags, 43 const void *entry, struct xt_entry_target **target) 44{ 45 struct xt_nflog_info *info = (struct xt_nflog_info *)(*target)->data; 46 int n; 47 size_t length; 48 49 switch (c) { 50 case NFLOG_GROUP: 51 if (*flags & NFLOG_GROUP) 52 xtables_error(PARAMETER_PROBLEM, 53 "Can't specify --nflog-group twice"); 54 if (xtables_check_inverse(optarg, &invert, NULL, 0)) 55 xtables_error(PARAMETER_PROBLEM, 56 "Unexpected `!' after --nflog-group"); 57 58 n = atoi(optarg); 59 if (n < 0) 60 xtables_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 xtables_error(PARAMETER_PROBLEM, 67 "Can't specify --nflog-prefix twice"); 68 if (xtables_check_inverse(optarg, &invert, NULL, 0)) 69 xtables_error(PARAMETER_PROBLEM, 70 "Unexpected `!' after --nflog-prefix"); 71 72 length = strlen(optarg); 73 if (length == 0) 74 xtables_error(PARAMETER_PROBLEM, 75 "No prefix specified for --nflog-prefix"); 76 if (length >= sizeof(info->prefix)) 77 xtables_error(PARAMETER_PROBLEM, 78 "--nflog-prefix too long, max %Zu characters", 79 sizeof(info->prefix) - 1); 80 if (length != strlen(strtok(optarg, "\n"))) 81 xtables_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 xtables_error(PARAMETER_PROBLEM, 88 "Can't specify --nflog-range twice"); 89 n = atoi(optarg); 90 if (n < 0) 91 xtables_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 xtables_error(PARAMETER_PROBLEM, 98 "Can't specify --nflog-threshold twice"); 99 n = atoi(optarg); 100 if (n < 1) 101 xtables_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 ", prefix); 116 xtables_save_string(info->prefix); 117 } 118 if (info->group) 119 printf("%snflog-group %u ", prefix, info->group); 120 if (info->len) 121 printf("%snflog-range %u ", prefix, info->len); 122 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) 123 printf("%snflog-threshold %u ", prefix, info->threshold); 124} 125 126static void NFLOG_print(const void *ip, const struct xt_entry_target *target, 127 int numeric) 128{ 129 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 130 131 nflog_print(info, ""); 132} 133 134static void NFLOG_save(const void *ip, const struct xt_entry_target *target) 135{ 136 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 137 138 nflog_print(info, "--"); 139} 140 141static struct xtables_target nflog_target = { 142 .family = NFPROTO_UNSPEC, 143 .name = "NFLOG", 144 .version = XTABLES_VERSION, 145 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 146 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 147 .help = NFLOG_help, 148 .init = NFLOG_init, 149 .parse = NFLOG_parse, 150 .print = NFLOG_print, 151 .save = NFLOG_save, 152 .extra_opts = NFLOG_opts, 153}; 154 155void _init(void) 156{ 157 xtables_register_target(&nflog_target); 158} 159