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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
/* ebt_ulog
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* November, 2004
*/
#define __need_time_t
#define __need_suseconds_t
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
#include <sys/time.h>
#include <linux/netfilter_bridge/ebt_ulog.h>
#define CP_NO_LIMIT_S "default_cprange"
#define CP_NO_LIMIT_N 0
#define ULOG_PREFIX '1'
#define ULOG_NLGROUP '2'
#define ULOG_CPRANGE '3'
#define ULOG_QTHRESHOLD '4'
#define ULOG_ULOG '5'
static const struct option opts[] =
{
{ "ulog-prefix" , required_argument, 0, ULOG_PREFIX },
{ "ulog-nlgroup" , required_argument, 0, ULOG_NLGROUP },
{ "ulog-cprange" , required_argument, 0, ULOG_CPRANGE },
{ "ulog-qthreshold", required_argument, 0, ULOG_QTHRESHOLD },
{ "ulog" , no_argument , 0, ULOG_ULOG },
{ 0 }
};
static void print_help()
{
printf(
"ulog options:\n"
"--ulog : use the default ulog parameters\n"
"--ulog-prefix prefix : max %d characters (default is no prefix)\n"
"--ulog-nlgroup group : 0 < group number < %d (default = %d)\n"
"--ulog-cprange range : max copy range (default is " CP_NO_LIMIT_S ")\n"
"--ulog-qthreshold : 0 < queueing threshold < %d (default = %d)\n",
EBT_ULOG_PREFIX_LEN - 1, EBT_ULOG_MAXNLGROUPS + 1,
EBT_ULOG_DEFAULT_NLGROUP + 1, EBT_ULOG_MAX_QLEN + 1,
EBT_ULOG_DEFAULT_QTHRESHOLD);
}
static void init(struct ebt_entry_watcher *watcher)
{
struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;
uloginfo->prefix[0] = '\0';
uloginfo->nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
uloginfo->cprange = CP_NO_LIMIT_N; /* Use default netlink buffer size */
uloginfo->qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
}
#define OPT_PREFIX 0x01
#define OPT_NLGROUP 0x02
#define OPT_CPRANGE 0x04
#define OPT_QTHRESHOLD 0x08
#define OPT_ULOG 0x10
static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
unsigned int *flags, struct ebt_entry_watcher **watcher)
{
struct ebt_ulog_info *uloginfo;
unsigned int i;
char *end;
uloginfo = (struct ebt_ulog_info *)(*watcher)->data;
switch (c) {
case ULOG_PREFIX:
if (ebt_check_inverse2(optarg))
goto inverse_invalid;
ebt_check_option2(flags, OPT_PREFIX);
if (strlen(optarg) > EBT_ULOG_PREFIX_LEN - 1)
ebt_print_error("Prefix too long for ulog-prefix");
strcpy(uloginfo->prefix, optarg);
break;
case ULOG_NLGROUP:
if (ebt_check_inverse2(optarg))
goto inverse_invalid;
ebt_check_option2(flags, OPT_NLGROUP);
i = strtoul(optarg, &end, 10);
if (*end != '\0')
ebt_print_error2("Problem with ulog-nlgroup: %s", optarg);
if (i < 1 || i > EBT_ULOG_MAXNLGROUPS)
ebt_print_error2("the ulog-nlgroup number must be between 1 and 32");
uloginfo->nlgroup = i - 1;
break;
case ULOG_CPRANGE:
if (ebt_check_inverse2(optarg))
goto inverse_invalid;
ebt_check_option2(flags, OPT_CPRANGE);
i = strtoul(optarg, &end, 10);
if (*end != '\0') {
if (strcasecmp(optarg, CP_NO_LIMIT_S))
ebt_print_error2("Problem with ulog-cprange: %s", optarg);
i = CP_NO_LIMIT_N;
}
uloginfo->cprange = i;
break;
case ULOG_QTHRESHOLD:
if (ebt_check_inverse2(optarg))
goto inverse_invalid;
ebt_check_option2(flags, OPT_QTHRESHOLD);
i = strtoul(optarg, &end, 10);
if (*end != '\0')
ebt_print_error2("Problem with ulog-qthreshold: %s", optarg);
if (i > EBT_ULOG_MAX_QLEN)
ebt_print_error2("ulog-qthreshold argument %d exceeds the maximum of %d", i, EBT_ULOG_MAX_QLEN);
uloginfo->qthreshold = i;
break;
case ULOG_ULOG:
if (ebt_check_inverse(optarg))
goto inverse_invalid;
ebt_check_option2(flags, OPT_ULOG);
break;
default:
return 0;
}
return 1;
inverse_invalid:
ebt_print_error("The use of '!' makes no sense for the ulog watcher");
return 1;
}
static void final_check(const struct ebt_u_entry *entry,
const struct ebt_entry_watcher *watcher, const char *name,
unsigned int hookmask, unsigned int time)
{
}
static void print(const struct ebt_u_entry *entry,
const struct ebt_entry_watcher *watcher)
{
struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;
printf("--ulog-prefix \"%s\" --ulog-nlgroup %d --ulog-cprange ",
uloginfo->prefix, uloginfo->nlgroup + 1);
if (uloginfo->cprange == CP_NO_LIMIT_N)
printf(CP_NO_LIMIT_S);
else
printf("%d", uloginfo->cprange);
printf(" --ulog-qthreshold %d ", uloginfo->qthreshold);
}
static int compare(const struct ebt_entry_watcher *w1,
const struct ebt_entry_watcher *w2)
{
struct ebt_ulog_info *uloginfo1 = (struct ebt_ulog_info *)w1->data;
struct ebt_ulog_info *uloginfo2 = (struct ebt_ulog_info *)w2->data;
if (uloginfo1->nlgroup != uloginfo2->nlgroup ||
uloginfo1->cprange != uloginfo2->cprange ||
uloginfo1->qthreshold != uloginfo2->qthreshold ||
strcmp(uloginfo1->prefix, uloginfo2->prefix))
return 0;
return 1;
}
static struct ebt_u_watcher ulog_watcher =
{
.name = "ulog",
.size = sizeof(struct ebt_ulog_info),
.help = print_help,
.init = init,
.parse = parse,
.final_check = final_check,
.print = print,
.compare = compare,
.extra_ops = opts,
};
static void _INIT(void)
{
ebt_register_watcher(&ulog_watcher);
}
|