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