/* ebt_ulog * * Authors: * Bart De Schuymer * * November, 2004 */ #define __need_time_t #define __need_suseconds_t #include #include #include #include #include "../include/ebtables_u.h" #include #include #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, }; __attribute__((constructor)) static void extension_init(void) { ebt_register_watcher(&ulog_watcher); }