libipt_ULOG.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
1/* Shared library add-on to iptables to add ULOG support. 2 * 3 * (C) 2000 by Harald Welte <laforge@gnumonks.org> 4 * 5 * multipart netlink support based on ideas by Sebastian Zander 6 * <zander@fokus.gmd.de> 7 * 8 * This software is released under the terms of GNU GPL 9 * 10 * libipt_ULOG.c,v 1.7 2001/01/30 11:55:02 laforge Exp 11 */ 12#include <stdbool.h> 13#include <stdio.h> 14#include <netdb.h> 15#include <string.h> 16#include <stdlib.h> 17#include <syslog.h> 18#include <getopt.h> 19#include <xtables.h> 20/* For 64bit kernel / 32bit userspace */ 21#include <linux/netfilter_ipv4/ipt_ULOG.h> 22 23 24static void print_groups(unsigned int gmask) 25{ 26 int b; 27 unsigned int test; 28 29 for (b = 31; b >= 0; b--) { 30 test = (1 << b); 31 if (gmask & test) 32 printf("%d ", b + 1); 33 } 34} 35 36static void ULOG_help(void) 37{ 38 printf("ULOG target options:\n" 39 " --ulog-nlgroup nlgroup NETLINK group used for logging\n" 40 " --ulog-cprange size Bytes of each packet to be passed\n" 41 " --ulog-qthreshold Threshold of in-kernel queue\n" 42 " --ulog-prefix prefix Prefix log messages with this prefix.\n"); 43} 44 45static const struct option ULOG_opts[] = { 46 {.name = "ulog-nlgroup", .has_arg = true, .val = '!'}, 47 {.name = "ulog-prefix", .has_arg = true, .val = '#'}, 48 {.name = "ulog-cprange", .has_arg = true, .val = 'A'}, 49 {.name = "ulog-qthreshold", .has_arg = true, .val = 'B'}, 50 XT_GETOPT_TABLEEND, 51}; 52 53static void ULOG_init(struct xt_entry_target *t) 54{ 55 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data; 56 57 loginfo->nl_group = ULOG_DEFAULT_NLGROUP; 58 loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD; 59 60} 61 62#define IPT_LOG_OPT_NLGROUP 0x01 63#define IPT_LOG_OPT_PREFIX 0x02 64#define IPT_LOG_OPT_CPRANGE 0x04 65#define IPT_LOG_OPT_QTHRESHOLD 0x08 66 67static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags, 68 const void *entry, struct xt_entry_target **target) 69{ 70 struct ipt_ulog_info *loginfo = 71 (struct ipt_ulog_info *) (*target)->data; 72 int group_d; 73 74 switch (c) { 75 case '!': 76 if (*flags & IPT_LOG_OPT_NLGROUP) 77 xtables_error(PARAMETER_PROBLEM, 78 "Can't specify --ulog-nlgroup twice"); 79 80 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 81 xtables_error(PARAMETER_PROBLEM, 82 "Unexpected `!' after --ulog-nlgroup"); 83 group_d = atoi(optarg); 84 if (group_d > 32 || group_d < 1) 85 xtables_error(PARAMETER_PROBLEM, 86 "--ulog-nlgroup has to be between 1 and 32"); 87 88 loginfo->nl_group = (1 << (group_d - 1)); 89 90 *flags |= IPT_LOG_OPT_NLGROUP; 91 break; 92 93 case '#': 94 if (*flags & IPT_LOG_OPT_PREFIX) 95 xtables_error(PARAMETER_PROBLEM, 96 "Can't specify --ulog-prefix twice"); 97 98 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 99 xtables_error(PARAMETER_PROBLEM, 100 "Unexpected `!' after --ulog-prefix"); 101 102 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 103 xtables_error(PARAMETER_PROBLEM, 104 "Maximum prefix length %u for --ulog-prefix", 105 (unsigned int)sizeof(loginfo->prefix) - 1); 106 107 if (strlen(optarg) == 0) 108 xtables_error(PARAMETER_PROBLEM, 109 "No prefix specified for --ulog-prefix"); 110 111 if (strlen(optarg) != strlen(strtok(optarg, "\n"))) 112 xtables_error(PARAMETER_PROBLEM, 113 "Newlines not allowed in --ulog-prefix"); 114 115 strcpy(loginfo->prefix, optarg); 116 *flags |= IPT_LOG_OPT_PREFIX; 117 break; 118 case 'A': 119 if (*flags & IPT_LOG_OPT_CPRANGE) 120 xtables_error(PARAMETER_PROBLEM, 121 "Can't specify --ulog-cprange twice"); 122 if (atoi(optarg) < 0) 123 xtables_error(PARAMETER_PROBLEM, 124 "Negative copy range?"); 125 loginfo->copy_range = atoi(optarg); 126 *flags |= IPT_LOG_OPT_CPRANGE; 127 break; 128 case 'B': 129 if (*flags & IPT_LOG_OPT_QTHRESHOLD) 130 xtables_error(PARAMETER_PROBLEM, 131 "Can't specify --ulog-qthreshold twice"); 132 if (atoi(optarg) < 1) 133 xtables_error(PARAMETER_PROBLEM, 134 "Negative or zero queue threshold ?"); 135 if (atoi(optarg) > ULOG_MAX_QLEN) 136 xtables_error(PARAMETER_PROBLEM, 137 "Maximum queue length exceeded"); 138 loginfo->qthreshold = atoi(optarg); 139 *flags |= IPT_LOG_OPT_QTHRESHOLD; 140 break; 141 default: 142 return 0; 143 } 144 return 1; 145} 146 147static void ULOG_save(const void *ip, const struct xt_entry_target *target) 148{ 149 const struct ipt_ulog_info *loginfo 150 = (const struct ipt_ulog_info *) target->data; 151 152 if (strcmp(loginfo->prefix, "") != 0) { 153 fputs("--ulog-prefix ", stdout); 154 xtables_save_string(loginfo->prefix); 155 } 156 157 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) { 158 printf("--ulog-nlgroup "); 159 print_groups(loginfo->nl_group); 160 } 161 if (loginfo->copy_range) 162 printf("--ulog-cprange %u ", (unsigned int)loginfo->copy_range); 163 164 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD) 165 printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold); 166} 167 168static void ULOG_print(const void *ip, const struct xt_entry_target *target, 169 int numeric) 170{ 171 const struct ipt_ulog_info *loginfo 172 = (const struct ipt_ulog_info *) target->data; 173 174 printf("ULOG "); 175 printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range); 176 print_groups(loginfo->nl_group); 177 if (strcmp(loginfo->prefix, "") != 0) 178 printf("prefix `%s' ", loginfo->prefix); 179 printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold); 180} 181 182static struct xtables_target ulog_tg_reg = { 183 .name = "ULOG", 184 .version = XTABLES_VERSION, 185 .family = NFPROTO_IPV4, 186 .size = XT_ALIGN(sizeof(struct ipt_ulog_info)), 187 .userspacesize = XT_ALIGN(sizeof(struct ipt_ulog_info)), 188 .help = ULOG_help, 189 .init = ULOG_init, 190 .parse = ULOG_parse, 191 .print = ULOG_print, 192 .save = ULOG_save, 193 .extra_opts = ULOG_opts, 194}; 195 196void _init(void) 197{ 198 xtables_register_target(&ulog_tg_reg); 199} 200