diff options
Diffstat (limited to 'extensions/libip6t_LOG.c')
-rw-r--r-- | extensions/libip6t_LOG.c | 228 |
1 files changed, 76 insertions, 152 deletions
diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c index 423d988..4639268 100644 --- a/extensions/libip6t_LOG.c +++ b/extensions/libip6t_LOG.c @@ -1,10 +1,6 @@ -/* Shared library add-on to ip6tables to add LOG support. */ #include <stdio.h> -#include <netdb.h> #include <string.h> -#include <stdlib.h> #include <syslog.h> -#include <getopt.h> #include <xtables.h> #include <linux/netfilter_ipv6/ip6t_LOG.h> @@ -16,6 +12,16 @@ #define LOG_DEFAULT_LEVEL LOG_WARNING +enum { + O_LOG_LEVEL = 0, + O_LOG_PREFIX, + O_LOG_TCPSEQ, + O_LOG_TCPOPTS, + O_LOG_IPOPTS, + O_LOG_UID, + O_LOG_MAC, +}; + static void LOG_help(void) { printf( @@ -25,18 +31,24 @@ static void LOG_help(void) " --log-tcp-sequence Log TCP sequence numbers.\n" " --log-tcp-options Log TCP options.\n" " --log-ip-options Log IP options.\n" -" --log-uid Log UID owning the local socket.\n"); +" --log-uid Log UID owning the local socket.\n" +" --log-macdecode Decode MAC addresses and protocol.\n"); } -static const struct option LOG_opts[] = { - { .name = "log-level", .has_arg = 1, .val = '!' }, - { .name = "log-prefix", .has_arg = 1, .val = '#' }, - { .name = "log-tcp-sequence", .has_arg = 0, .val = '1' }, - { .name = "log-tcp-options", .has_arg = 0, .val = '2' }, - { .name = "log-ip-options", .has_arg = 0, .val = '3' }, - { .name = "log-uid", .has_arg = 0, .val = '4' }, - { .name = NULL } +#define s struct ip6t_log_info +static const struct xt_option_entry LOG_opts[] = { + {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, + .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, + {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, + {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, + {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, + {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, + {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, + {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; +#undef s static void LOG_init(struct xt_entry_target *t) { @@ -63,127 +75,33 @@ static const struct ip6t_log_names ip6t_log_names[] { .name = "warning", .level = LOG_WARNING } }; -static u_int8_t -parse_level(const char *level) +static void LOG_parse(struct xt_option_call *cb) { - unsigned int lev = -1; - unsigned int set = 0; - - if (!xtables_strtoui(level, NULL, &lev, 0, 7)) { - unsigned int i = 0; - - for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i) - if (strncasecmp(level, ip6t_log_names[i].name, - strlen(level)) == 0) { - if (set++) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' ambiguous", - level); - lev = ip6t_log_names[i].level; - } - - if (!set) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' unknown", level); - } - - return lev; -} - -#define IP6T_LOG_OPT_LEVEL 0x01 -#define IP6T_LOG_OPT_PREFIX 0x02 -#define IP6T_LOG_OPT_TCPSEQ 0x04 -#define IP6T_LOG_OPT_TCPOPT 0x08 -#define IP6T_LOG_OPT_IPOPT 0x10 -#define IP6T_LOG_OPT_UID 0x20 - -static int LOG_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data; - - switch (c) { - case '!': - if (*flags & IP6T_LOG_OPT_LEVEL) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-level twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-level"); - - loginfo->level = parse_level(optarg); - *flags |= IP6T_LOG_OPT_LEVEL; - break; - - case '#': - if (*flags & IP6T_LOG_OPT_PREFIX) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-prefix twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-prefix"); - - if (strlen(optarg) > sizeof(loginfo->prefix) - 1) - xtables_error(PARAMETER_PROBLEM, - "Maximum prefix length %u for --log-prefix", - (unsigned int)sizeof(loginfo->prefix) - 1); + struct ip6t_log_info *info = cb->data; - if (strlen(optarg) == 0) - xtables_error(PARAMETER_PROBLEM, - "No prefix specified for --log-prefix"); - - if (strlen(optarg) != strlen(strtok(optarg, "\n"))) + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_LOG_PREFIX: + if (strchr(cb->arg, '\n') != NULL) xtables_error(PARAMETER_PROBLEM, "Newlines not allowed in --log-prefix"); - - strcpy(loginfo->prefix, optarg); - *flags |= IP6T_LOG_OPT_PREFIX; break; - - case '1': - if (*flags & IP6T_LOG_OPT_TCPSEQ) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-sequence " - "twice"); - - loginfo->logflags |= IP6T_LOG_TCPSEQ; - *flags |= IP6T_LOG_OPT_TCPSEQ; + case O_LOG_TCPSEQ: + info->logflags |= IP6T_LOG_TCPSEQ; break; - - case '2': - if (*flags & IP6T_LOG_OPT_TCPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-options twice"); - - loginfo->logflags |= IP6T_LOG_TCPOPT; - *flags |= IP6T_LOG_OPT_TCPOPT; + case O_LOG_TCPOPTS: + info->logflags |= IP6T_LOG_TCPOPT; break; - - case '3': - if (*flags & IP6T_LOG_OPT_IPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-ip-options twice"); - - loginfo->logflags |= IP6T_LOG_IPOPT; - *flags |= IP6T_LOG_OPT_IPOPT; + case O_LOG_IPOPTS: + info->logflags |= IP6T_LOG_IPOPT; break; - - case '4': - if (*flags & IP6T_LOG_OPT_UID) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-uid twice"); - - loginfo->logflags |= IP6T_LOG_UID; - *flags |= IP6T_LOG_OPT_UID; + case O_LOG_UID: + info->logflags |= IP6T_LOG_UID; + break; + case O_LOG_MAC: + info->logflags |= IP6T_LOG_MACDECODE; break; - - default: - return 0; } - - return 1; } static void LOG_print(const void *ip, const struct xt_entry_target *target, @@ -193,32 +111,34 @@ static void LOG_print(const void *ip, const struct xt_entry_target *target, = (const struct ip6t_log_info *)target->data; unsigned int i = 0; - printf("LOG "); + printf(" LOG"); if (numeric) - printf("flags %u level %u ", + printf(" flags %u level %u", loginfo->logflags, loginfo->level); else { for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i) if (loginfo->level == ip6t_log_names[i].level) { - printf("level %s ", ip6t_log_names[i].name); + printf(" level %s", ip6t_log_names[i].name); break; } if (i == ARRAY_SIZE(ip6t_log_names)) - printf("UNKNOWN level %u ", loginfo->level); + printf(" UNKNOWN level %u", loginfo->level); if (loginfo->logflags & IP6T_LOG_TCPSEQ) - printf("tcp-sequence "); + printf(" tcp-sequence"); if (loginfo->logflags & IP6T_LOG_TCPOPT) - printf("tcp-options "); + printf(" tcp-options"); if (loginfo->logflags & IP6T_LOG_IPOPT) - printf("ip-options "); + printf(" ip-options"); if (loginfo->logflags & IP6T_LOG_UID) - printf("uid "); + printf(" uid"); + if (loginfo->logflags & IP6T_LOG_MACDECODE) + printf(" macdecode"); if (loginfo->logflags & ~(IP6T_LOG_MASK)) - printf("unknown-flags "); + printf(" unknown-flags"); } if (strcmp(loginfo->prefix, "") != 0) - printf("prefix `%s' ", loginfo->prefix); + printf(" prefix \"%s\"", loginfo->prefix); } static void LOG_save(const void *ip, const struct xt_entry_target *target) @@ -226,34 +146,38 @@ static void LOG_save(const void *ip, const struct xt_entry_target *target) const struct ip6t_log_info *loginfo = (const struct ip6t_log_info *)target->data; - if (strcmp(loginfo->prefix, "") != 0) - printf("--log-prefix \"%s\" ", loginfo->prefix); + if (strcmp(loginfo->prefix, "") != 0) { + printf(" --log-prefix"); + xtables_save_string(loginfo->prefix); + } if (loginfo->level != LOG_DEFAULT_LEVEL) - printf("--log-level %d ", loginfo->level); + printf(" --log-level %d", loginfo->level); if (loginfo->logflags & IP6T_LOG_TCPSEQ) - printf("--log-tcp-sequence "); + printf(" --log-tcp-sequence"); if (loginfo->logflags & IP6T_LOG_TCPOPT) - printf("--log-tcp-options "); + printf(" --log-tcp-options"); if (loginfo->logflags & IP6T_LOG_IPOPT) - printf("--log-ip-options "); + printf(" --log-ip-options"); if (loginfo->logflags & IP6T_LOG_UID) - printf("--log-uid "); + printf(" --log-uid"); + if (loginfo->logflags & IP6T_LOG_MACDECODE) + printf(" --log-macdecode"); } static struct xtables_target log_tg6_reg = { - .name = "LOG", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .size = XT_ALIGN(sizeof(struct ip6t_log_info)), - .userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)), - .help = LOG_help, - .init = LOG_init, - .parse = LOG_parse, - .print = LOG_print, - .save = LOG_save, - .extra_opts = LOG_opts, + .name = "LOG", + .version = XTABLES_VERSION, + .family = NFPROTO_IPV6, + .size = XT_ALIGN(sizeof(struct ip6t_log_info)), + .userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)), + .help = LOG_help, + .init = LOG_init, + .print = LOG_print, + .save = LOG_save, + .x6_parse = LOG_parse, + .x6_options = LOG_opts, }; void _init(void) |