1 /* 2 * Bart De Schuymer <bdschuym (at) pandora.be> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * Giuseppe Longo <giuseppelng (at) gmail.com> adapted the original code to the 9 * xtables-compat environment in 2015. 10 * 11 */ 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <syslog.h> 16 #include <string.h> 17 #include <getopt.h> 18 #include <xtables.h> 19 #include <linux/netfilter_bridge/ebt_log.h> 20 21 #define LOG_DEFAULT_LEVEL LOG_INFO 22 23 #define LOG_PREFIX '1' 24 #define LOG_LEVEL '2' 25 #define LOG_ARP '3' 26 #define LOG_IP '4' 27 #define LOG_LOG '5' 28 #define LOG_IP6 '6' 29 30 typedef struct _code { 31 char *c_name; 32 int c_val; 33 } CODE; 34 35 static CODE eight_priority[] = { 36 { "emerg", LOG_EMERG }, 37 { "alert", LOG_ALERT }, 38 { "crit", LOG_CRIT }, 39 { "error", LOG_ERR }, 40 { "warning", LOG_WARNING }, 41 { "notice", LOG_NOTICE }, 42 { "info", LOG_INFO }, 43 { "debug", LOG_DEBUG } 44 }; 45 46 static int name_to_loglevel(const char *arg) 47 { 48 int i; 49 50 for (i = 0; i < 8; i++) 51 if (!strcmp(arg, eight_priority[i].c_name)) 52 return eight_priority[i].c_val; 53 54 /* return bad loglevel */ 55 return 9; 56 } 57 58 static const struct option brlog_opts[] = { 59 { .name = "log-prefix", .has_arg = true, .val = LOG_PREFIX }, 60 { .name = "log-level", .has_arg = true, .val = LOG_LEVEL }, 61 { .name = "log-arp", .has_arg = false, .val = LOG_ARP }, 62 { .name = "log-ip", .has_arg = false, .val = LOG_IP }, 63 { .name = "log", .has_arg = false, .val = LOG_LOG }, 64 { .name = "log-ip6", .has_arg = false, .val = LOG_IP6 }, 65 XT_GETOPT_TABLEEND, 66 }; 67 68 static void brlog_help(void) 69 { 70 int i; 71 72 printf( 73 "log options:\n" 74 "--log : use this if you're not specifying anything\n" 75 "--log-level level : level = [1-8] or a string\n" 76 "--log-prefix prefix : max. %d chars.\n" 77 "--log-ip : put ip info. in the log for ip packets\n" 78 "--log-arp : put (r)arp info. in the log for (r)arp packets\n" 79 "--log-ip6 : put ip6 info. in the log for ip6 packets\n" 80 , EBT_LOG_PREFIX_SIZE - 1); 81 for (i = 0; i < 8; i++) 82 printf("%d = %s\n", eight_priority[i].c_val, 83 eight_priority[i].c_name); 84 } 85 86 static void brlog_init(struct xt_entry_target *t) 87 { 88 struct ebt_log_info *loginfo = (struct ebt_log_info *)t->data; 89 90 loginfo->bitmask = 0; 91 loginfo->prefix[0] = '\0'; 92 loginfo->loglevel = LOG_NOTICE; 93 } 94 95 static int brlog_parse(int c, char **argv, int invert, unsigned int *flags, 96 const void *entry, struct xt_entry_target **target) 97 { 98 struct ebt_log_info *loginfo = (struct ebt_log_info *)(*target)->data; 99 long int i; 100 char *end; 101 102 switch (c) { 103 case LOG_PREFIX: 104 if (invert) 105 xtables_error(PARAMETER_PROBLEM, 106 "Unexpected `!` after --log-prefix"); 107 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 108 xtables_error(PARAMETER_PROBLEM, 109 "Prefix too long"); 110 if (strchr(optarg, '\"')) 111 xtables_error(PARAMETER_PROBLEM, 112 "Use of \\\" is not allowed" 113 " in the prefix"); 114 strcpy((char *)loginfo->prefix, (char *)optarg); 115 break; 116 case LOG_LEVEL: 117 i = strtol(optarg, &end, 16); 118 if (*end != '\0' || i < 0 || i > 7) 119 loginfo->loglevel = name_to_loglevel(optarg); 120 else 121 loginfo->loglevel = i; 122 123 if (loginfo->loglevel == 9) 124 xtables_error(PARAMETER_PROBLEM, 125 "Problem with the log-level"); 126 break; 127 case LOG_IP: 128 if (invert) 129 xtables_error(PARAMETER_PROBLEM, 130 "Unexpected `!' after --log-ip"); 131 loginfo->bitmask |= EBT_LOG_IP; 132 break; 133 case LOG_ARP: 134 if (invert) 135 xtables_error(PARAMETER_PROBLEM, 136 "Unexpected `!' after --log-arp"); 137 loginfo->bitmask |= EBT_LOG_ARP; 138 case LOG_LOG: 139 if (invert) 140 xtables_error(PARAMETER_PROBLEM, 141 "Unexpected `!' after --log"); 142 break; 143 case LOG_IP6: 144 if (invert) 145 xtables_error(PARAMETER_PROBLEM, 146 "Unexpected `!' after --log-ip6"); 147 loginfo->bitmask |= EBT_LOG_IP6; 148 break; 149 default: 150 return 0; 151 } 152 153 *flags |= loginfo->bitmask; 154 return 1; 155 } 156 157 static void brlog_final_check(unsigned int flags) 158 { 159 } 160 161 static void brlog_print(const void *ip, const struct xt_entry_target *target, 162 int numeric) 163 { 164 struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data; 165 166 printf("--log-level %s --log-prefix \"%s\"", 167 eight_priority[loginfo->loglevel].c_name, 168 loginfo->prefix); 169 170 if (loginfo->bitmask & EBT_LOG_IP) 171 printf(" --log-ip"); 172 if (loginfo->bitmask & EBT_LOG_ARP) 173 printf(" --log-arp"); 174 if (loginfo->bitmask & EBT_LOG_IP6) 175 printf(" --log-ip6"); 176 printf(" "); 177 } 178 179 static struct xtables_target brlog_target = { 180 .name = "log", 181 .revision = 0, 182 .version = XTABLES_VERSION, 183 .family = NFPROTO_BRIDGE, 184 .size = XT_ALIGN(sizeof(struct ebt_log_info)), 185 .userspacesize = XT_ALIGN(sizeof(struct ebt_log_info)), 186 .init = brlog_init, 187 .help = brlog_help, 188 .parse = brlog_parse, 189 .final_check = brlog_final_check, 190 .print = brlog_print, 191 .extra_opts = brlog_opts, 192 }; 193 194 void _init(void) 195 { 196 xtables_register_target(&brlog_target); 197 } 198