libxt_NFLOG.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
1#include <stdbool.h> 2#include <stdlib.h> 3#include <stdio.h> 4#include <string.h> 5#include <getopt.h> 6#include <xtables.h> 7 8#include <linux/netfilter/x_tables.h> 9#include <linux/netfilter/xt_NFLOG.h> 10 11enum { 12 NFLOG_GROUP = 0x1, 13 NFLOG_PREFIX = 0x2, 14 NFLOG_RANGE = 0x4, 15 NFLOG_THRESHOLD = 0x8, 16}; 17 18static const struct option NFLOG_opts[] = { 19 {.name = "nflog-group", .has_arg = true, .val = NFLOG_GROUP}, 20 {.name = "nflog-prefix", .has_arg = true, .val = NFLOG_PREFIX}, 21 {.name = "nflog-range", .has_arg = true, .val = NFLOG_RANGE}, 22 {.name = "nflog-threshold", .has_arg = true, .val = NFLOG_THRESHOLD}, 23 XT_GETOPT_TABLEEND, 24}; 25 26static void NFLOG_help(void) 27{ 28 printf("NFLOG target options:\n" 29 " --nflog-group NUM NETLINK group used for logging\n" 30 " --nflog-range NUM Number of byte to copy\n" 31 " --nflog-threshold NUM Message threshold of in-kernel queue\n" 32 " --nflog-prefix STRING Prefix string for log messages\n"); 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 size_t length; 49 50 switch (c) { 51 case NFLOG_GROUP: 52 if (*flags & NFLOG_GROUP) 53 xtables_error(PARAMETER_PROBLEM, 54 "Can't specify --nflog-group twice"); 55 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 56 xtables_error(PARAMETER_PROBLEM, 57 "Unexpected `!' after --nflog-group"); 58 59 n = atoi(optarg); 60 if (n < 0) 61 xtables_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 xtables_error(PARAMETER_PROBLEM, 68 "Can't specify --nflog-prefix twice"); 69 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 70 xtables_error(PARAMETER_PROBLEM, 71 "Unexpected `!' after --nflog-prefix"); 72 73 length = strlen(optarg); 74 if (length == 0) 75 xtables_error(PARAMETER_PROBLEM, 76 "No prefix specified for --nflog-prefix"); 77 if (length >= sizeof(info->prefix)) 78 xtables_error(PARAMETER_PROBLEM, 79 "--nflog-prefix too long, max %Zu characters", 80 sizeof(info->prefix) - 1); 81 if (length != strlen(strtok(optarg, "\n"))) 82 xtables_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 xtables_error(PARAMETER_PROBLEM, 89 "Can't specify --nflog-range twice"); 90 n = atoi(optarg); 91 if (n < 0) 92 xtables_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 xtables_error(PARAMETER_PROBLEM, 99 "Can't specify --nflog-threshold twice"); 100 n = atoi(optarg); 101 if (n < 1) 102 xtables_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 nflog_print(const struct xt_nflog_info *info, char *prefix) 114{ 115 if (info->prefix[0] != '\0') { 116 printf("%snflog-prefix ", prefix); 117 xtables_save_string(info->prefix); 118 } 119 if (info->group) 120 printf("%snflog-group %u ", prefix, info->group); 121 if (info->len) 122 printf("%snflog-range %u ", prefix, info->len); 123 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) 124 printf("%snflog-threshold %u ", prefix, info->threshold); 125} 126 127static void NFLOG_print(const void *ip, const struct xt_entry_target *target, 128 int numeric) 129{ 130 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 131 132 nflog_print(info, ""); 133} 134 135static void NFLOG_save(const void *ip, const struct xt_entry_target *target) 136{ 137 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data; 138 139 nflog_print(info, "--"); 140} 141 142static struct xtables_target nflog_target = { 143 .family = NFPROTO_UNSPEC, 144 .name = "NFLOG", 145 .version = XTABLES_VERSION, 146 .size = XT_ALIGN(sizeof(struct xt_nflog_info)), 147 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)), 148 .help = NFLOG_help, 149 .init = NFLOG_init, 150 .parse = NFLOG_parse, 151 .print = NFLOG_print, 152 .save = NFLOG_save, 153 .extra_opts = NFLOG_opts, 154}; 155 156void _init(void) 157{ 158 xtables_register_target(&nflog_target); 159} 160