libipt_ULOG.c revision 830132ac9c0d270bf9dcfe85c2464e3fe8c73fb9
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 <stdio.h> 13#include <netdb.h> 14#include <string.h> 15#include <stdlib.h> 16#include <syslog.h> 17#include <getopt.h> 18#include <iptables.h> 19#include <linux/netfilter_ipv4/ip_tables.h> 20/* For 64bit kernel / 32bit userspace */ 21#include "../include/linux/netfilter_ipv4/ipt_ULOG.h" 22 23 24void 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 36/* Function which prints out usage message. */ 37static void help(void) 38{ 39 printf("ULOG v%s options:\n" 40 " --ulog-nlgroup nlgroup NETLINK group used for logging\n" 41 " --ulog-cprange size Bytes of each packet to be passed\n" 42 " --ulog-qthreshold Threshold of in-kernel queue\n" 43 " --ulog-prefix prefix Prefix log messages with this prefix.\n\n", 44 IPTABLES_VERSION); 45} 46 47static const struct option opts[] = { 48 {"ulog-nlgroup", 1, NULL, '!'}, 49 {"ulog-prefix", 1, NULL, '#'}, 50 {"ulog-cprange", 1, NULL, 'A'}, 51 {"ulog-qthreshold", 1, NULL, 'B'}, 52 { } 53}; 54 55/* Initialize the target. */ 56static void init(struct xt_entry_target *t) 57{ 58 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data; 59 60 loginfo->nl_group = ULOG_DEFAULT_NLGROUP; 61 loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD; 62 63} 64 65#define IPT_LOG_OPT_NLGROUP 0x01 66#define IPT_LOG_OPT_PREFIX 0x02 67#define IPT_LOG_OPT_CPRANGE 0x04 68#define IPT_LOG_OPT_QTHRESHOLD 0x08 69 70/* Function which parses command options; returns true if it 71 ate an option */ 72static int parse(int c, char **argv, int invert, unsigned int *flags, 73 const void *entry, 74 struct xt_entry_target **target) 75{ 76 struct ipt_ulog_info *loginfo = 77 (struct ipt_ulog_info *) (*target)->data; 78 int group_d; 79 80 switch (c) { 81 case '!': 82 if (*flags & IPT_LOG_OPT_NLGROUP) 83 exit_error(PARAMETER_PROBLEM, 84 "Can't specify --ulog-nlgroup twice"); 85 86 if (check_inverse(optarg, &invert, NULL, 0)) 87 exit_error(PARAMETER_PROBLEM, 88 "Unexpected `!' after --ulog-nlgroup"); 89 group_d = atoi(optarg); 90 if (group_d > 32 || group_d < 1) 91 exit_error(PARAMETER_PROBLEM, 92 "--ulog-nlgroup has to be between 1 and 32"); 93 94 loginfo->nl_group = (1 << (group_d - 1)); 95 96 *flags |= IPT_LOG_OPT_NLGROUP; 97 break; 98 99 case '#': 100 if (*flags & IPT_LOG_OPT_PREFIX) 101 exit_error(PARAMETER_PROBLEM, 102 "Can't specify --ulog-prefix twice"); 103 104 if (check_inverse(optarg, &invert, NULL, 0)) 105 exit_error(PARAMETER_PROBLEM, 106 "Unexpected `!' after --ulog-prefix"); 107 108 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 109 exit_error(PARAMETER_PROBLEM, 110 "Maximum prefix length %u for --ulog-prefix", 111 (unsigned int)sizeof(loginfo->prefix) - 1); 112 113 if (strlen(optarg) == 0) 114 exit_error(PARAMETER_PROBLEM, 115 "No prefix specified for --ulog-prefix"); 116 117 if (strlen(optarg) != strlen(strtok(optarg, "\n"))) 118 exit_error(PARAMETER_PROBLEM, 119 "Newlines not allowed in --ulog-prefix"); 120 121 strcpy(loginfo->prefix, optarg); 122 *flags |= IPT_LOG_OPT_PREFIX; 123 break; 124 case 'A': 125 if (*flags & IPT_LOG_OPT_CPRANGE) 126 exit_error(PARAMETER_PROBLEM, 127 "Can't specify --ulog-cprange twice"); 128 if (atoi(optarg) < 0) 129 exit_error(PARAMETER_PROBLEM, 130 "Negative copy range?"); 131 loginfo->copy_range = atoi(optarg); 132 *flags |= IPT_LOG_OPT_CPRANGE; 133 break; 134 case 'B': 135 if (*flags & IPT_LOG_OPT_QTHRESHOLD) 136 exit_error(PARAMETER_PROBLEM, 137 "Can't specify --ulog-qthreshold twice"); 138 if (atoi(optarg) < 1) 139 exit_error(PARAMETER_PROBLEM, 140 "Negative or zero queue threshold ?"); 141 if (atoi(optarg) > ULOG_MAX_QLEN) 142 exit_error(PARAMETER_PROBLEM, 143 "Maximum queue length exceeded"); 144 loginfo->qthreshold = atoi(optarg); 145 *flags |= IPT_LOG_OPT_QTHRESHOLD; 146 break; 147 default: 148 return 0; 149 } 150 return 1; 151} 152 153/* Saves the union ipt_targinfo in parsable form to stdout. */ 154static void save(const void *ip, 155 const struct xt_entry_target *target) 156{ 157 const struct ipt_ulog_info *loginfo 158 = (const struct ipt_ulog_info *) target->data; 159 160 if (strcmp(loginfo->prefix, "") != 0) 161 printf("--ulog-prefix \"%s\" ", loginfo->prefix); 162 163 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) { 164 printf("--ulog-nlgroup "); 165 print_groups(loginfo->nl_group); 166 } 167 if (loginfo->copy_range) 168 printf("--ulog-cprange %u ", (unsigned int)loginfo->copy_range); 169 170 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD) 171 printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold); 172} 173 174/* Prints out the targinfo. */ 175static void 176print(const void *ip, 177 const struct xt_entry_target *target, int numeric) 178{ 179 const struct ipt_ulog_info *loginfo 180 = (const struct ipt_ulog_info *) target->data; 181 182 printf("ULOG "); 183 printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range); 184 print_groups(loginfo->nl_group); 185 if (strcmp(loginfo->prefix, "") != 0) 186 printf("prefix `%s' ", loginfo->prefix); 187 printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold); 188} 189 190static struct iptables_target ulog = { 191 .name = "ULOG", 192 .version = IPTABLES_VERSION, 193 .size = IPT_ALIGN(sizeof(struct ipt_ulog_info)), 194 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ulog_info)), 195 .help = &help, 196 .init = &init, 197 .parse = &parse, 198 .print = &print, 199 .save = &save, 200 .extra_opts = opts 201}; 202 203void _init(void) 204{ 205 register_target(&ulog); 206} 207