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