libipt_ULOG.c revision a28d495285ad7dd9f286d63958cf20d74eec6bcb
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 struct option opts[] = { 48 {"ulog-nlgroup", 1, 0, '!'}, 49 {"ulog-prefix", 1, 0, '#'}, 50 {"ulog-cprange", 1, 0, 'A'}, 51 {"ulog-qthreshold", 1, 0, 'B'}, 52 {0} 53}; 54 55/* Initialize the target. */ 56static void init(struct ipt_entry_target *t, unsigned int *nfcache) 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 /* Can't cache this */ 64 *nfcache |= NFC_UNKNOWN; 65} 66 67#define IPT_LOG_OPT_NLGROUP 0x01 68#define IPT_LOG_OPT_PREFIX 0x02 69#define IPT_LOG_OPT_CPRANGE 0x04 70#define IPT_LOG_OPT_QTHRESHOLD 0x08 71 72/* Function which parses command options; returns true if it 73 ate an option */ 74static int parse(int c, char **argv, int invert, unsigned int *flags, 75 const struct ipt_entry *entry, 76 struct ipt_entry_target **target) 77{ 78 struct ipt_ulog_info *loginfo = 79 (struct ipt_ulog_info *) (*target)->data; 80 int group_d; 81 82 switch (c) { 83 case '!': 84 if (*flags & IPT_LOG_OPT_NLGROUP) 85 exit_error(PARAMETER_PROBLEM, 86 "Can't specify --ulog-nlgroup twice"); 87 88 if (check_inverse(optarg, &invert, NULL, 0)) 89 exit_error(PARAMETER_PROBLEM, 90 "Unexpected `!' after --ulog-nlgroup"); 91 group_d = atoi(optarg); 92 if (group_d > 32 || group_d < 1) 93 exit_error(PARAMETER_PROBLEM, 94 "--ulog-nlgroup has to be between 1 and 32"); 95 96 loginfo->nl_group = (1 << (group_d - 1)); 97 98 *flags |= IPT_LOG_OPT_NLGROUP; 99 break; 100 101 case '#': 102 if (*flags & IPT_LOG_OPT_PREFIX) 103 exit_error(PARAMETER_PROBLEM, 104 "Can't specify --ulog-prefix twice"); 105 106 if (check_inverse(optarg, &invert, NULL, 0)) 107 exit_error(PARAMETER_PROBLEM, 108 "Unexpected `!' after --ulog-prefix"); 109 110 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 111 exit_error(PARAMETER_PROBLEM, 112 "Maximum prefix length %u for --ulog-prefix", 113 (unsigned int)sizeof(loginfo->prefix) - 1); 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 exit_error(PARAMETER_PROBLEM, 121 "Can't specify --ulog-cprange twice"); 122 if (atoi(optarg) < 0) 123 exit_error(PARAMETER_PROBLEM, 124 "Negative copy range?"); 125#ifdef KERNEL_64_USERSPACE_32 126 loginfo->copy_range = (unsigned long long)atoll(optarg); 127#else 128 loginfo->copy_range = atoi(optarg); 129#endif 130 *flags |= IPT_LOG_OPT_CPRANGE; 131 break; 132 case 'B': 133 if (*flags & IPT_LOG_OPT_QTHRESHOLD) 134 exit_error(PARAMETER_PROBLEM, 135 "Can't specify --ulog-qthreshold twice"); 136 if (atoi(optarg) < 1) 137 exit_error(PARAMETER_PROBLEM, 138 "Negative or zero queue threshold ?"); 139 if (atoi(optarg) > ULOG_MAX_QLEN) 140 exit_error(PARAMETER_PROBLEM, 141 "Maximum queue length exceeded"); 142#ifdef KERNEL_64_USERSPACE_32 143 loginfo->qthreshold = (unsigned long long)atoll(optarg); 144#else 145 loginfo->qthreshold = atoi(optarg); 146#endif 147 *flags |= IPT_LOG_OPT_QTHRESHOLD; 148 break; 149 } 150 return 1; 151} 152 153/* Final check; nothing. */ 154static void final_check(unsigned int flags) 155{ 156} 157 158/* Saves the union ipt_targinfo in parsable form to stdout. */ 159static void save(const struct ipt_ip *ip, 160 const struct ipt_entry_target *target) 161{ 162 const struct ipt_ulog_info *loginfo 163 = (const struct ipt_ulog_info *) target->data; 164 165 if (strcmp(loginfo->prefix, "") != 0) 166 printf("--ulog-prefix \"%s\" ", loginfo->prefix); 167 168 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) { 169 printf("--ulog-nlgroup "); 170 print_groups(loginfo->nl_group); 171 } 172#ifdef KERNEL_64_USERSPACE_32 173 if (loginfo->copy_range) 174 printf("--ulog-cprange %llu ", loginfo->copy_range); 175 176 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD) 177 printf("--ulog-qthreshold %llu ", loginfo->qthreshold); 178#else 179 if (loginfo->copy_range) 180 printf("--ulog-cprange %u ", (unsigned int)loginfo->copy_range); 181 182 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD) 183 printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold); 184#endif 185} 186 187/* Prints out the targinfo. */ 188static void 189print(const struct ipt_ip *ip, 190 const struct ipt_entry_target *target, int numeric) 191{ 192 const struct ipt_ulog_info *loginfo 193 = (const struct ipt_ulog_info *) target->data; 194 195 printf("ULOG "); 196#ifdef KERNEL_64_USERSPACE_32 197 printf("copy_range %llu nlgroup ", loginfo->copy_range); 198#else 199 printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range); 200#endif 201 print_groups(loginfo->nl_group); 202 if (strcmp(loginfo->prefix, "") != 0) 203 printf("prefix `%s' ", loginfo->prefix); 204#ifdef KERNEL_64_USERSPACE_32 205 printf("queue_threshold %llu ", loginfo->qthreshold); 206#else 207 printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold); 208#endif 209} 210 211static 212struct iptables_target ulog = { NULL, 213 "ULOG", 214 IPTABLES_VERSION, 215 IPT_ALIGN(sizeof(struct ipt_ulog_info)), 216 IPT_ALIGN(sizeof(struct ipt_ulog_info)), 217 &help, 218 &init, 219 &parse, 220 &final_check, 221 &print, 222 &save, 223 opts 224}; 225 226void _init(void) 227{ 228 register_target(&ulog); 229} 230