libipt_ULOG.c revision 8b7c64d6ba156a99008fcd810cba874c73294333
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 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 36/* Function which prints out usage message. */ 37static void ULOG_help(void) 38{ 39 printf("ULOG target 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"); 44} 45 46static const struct option ULOG_opts[] = { 47 {"ulog-nlgroup", 1, NULL, '!'}, 48 {"ulog-prefix", 1, NULL, '#'}, 49 {"ulog-cprange", 1, NULL, 'A'}, 50 {"ulog-qthreshold", 1, NULL, 'B'}, 51 { .name = NULL } 52}; 53 54/* Initialize the target. */ 55static void ULOG_init(struct xt_entry_target *t) 56{ 57 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data; 58 59 loginfo->nl_group = ULOG_DEFAULT_NLGROUP; 60 loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD; 61 62} 63 64#define IPT_LOG_OPT_NLGROUP 0x01 65#define IPT_LOG_OPT_PREFIX 0x02 66#define IPT_LOG_OPT_CPRANGE 0x04 67#define IPT_LOG_OPT_QTHRESHOLD 0x08 68 69/* Function which parses command options; returns true if it 70 ate an option */ 71static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags, 72 const void *entry, struct xt_entry_target **target) 73{ 74 struct ipt_ulog_info *loginfo = 75 (struct ipt_ulog_info *) (*target)->data; 76 int group_d; 77 78 switch (c) { 79 case '!': 80 if (*flags & IPT_LOG_OPT_NLGROUP) 81 exit_error(PARAMETER_PROBLEM, 82 "Can't specify --ulog-nlgroup twice"); 83 84 if (check_inverse(optarg, &invert, NULL, 0)) 85 exit_error(PARAMETER_PROBLEM, 86 "Unexpected `!' after --ulog-nlgroup"); 87 group_d = atoi(optarg); 88 if (group_d > 32 || group_d < 1) 89 exit_error(PARAMETER_PROBLEM, 90 "--ulog-nlgroup has to be between 1 and 32"); 91 92 loginfo->nl_group = (1 << (group_d - 1)); 93 94 *flags |= IPT_LOG_OPT_NLGROUP; 95 break; 96 97 case '#': 98 if (*flags & IPT_LOG_OPT_PREFIX) 99 exit_error(PARAMETER_PROBLEM, 100 "Can't specify --ulog-prefix twice"); 101 102 if (check_inverse(optarg, &invert, NULL, 0)) 103 exit_error(PARAMETER_PROBLEM, 104 "Unexpected `!' after --ulog-prefix"); 105 106 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 107 exit_error(PARAMETER_PROBLEM, 108 "Maximum prefix length %u for --ulog-prefix", 109 (unsigned int)sizeof(loginfo->prefix) - 1); 110 111 if (strlen(optarg) == 0) 112 exit_error(PARAMETER_PROBLEM, 113 "No prefix specified for --ulog-prefix"); 114 115 if (strlen(optarg) != strlen(strtok(optarg, "\n"))) 116 exit_error(PARAMETER_PROBLEM, 117 "Newlines not allowed in --ulog-prefix"); 118 119 strcpy(loginfo->prefix, optarg); 120 *flags |= IPT_LOG_OPT_PREFIX; 121 break; 122 case 'A': 123 if (*flags & IPT_LOG_OPT_CPRANGE) 124 exit_error(PARAMETER_PROBLEM, 125 "Can't specify --ulog-cprange twice"); 126 if (atoi(optarg) < 0) 127 exit_error(PARAMETER_PROBLEM, 128 "Negative copy range?"); 129 loginfo->copy_range = atoi(optarg); 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 loginfo->qthreshold = atoi(optarg); 143 *flags |= IPT_LOG_OPT_QTHRESHOLD; 144 break; 145 default: 146 return 0; 147 } 148 return 1; 149} 150 151/* Saves the union ipt_targinfo in parsable form to stdout. */ 152static void ULOG_save(const void *ip, const struct xt_entry_target *target) 153{ 154 const struct ipt_ulog_info *loginfo 155 = (const struct ipt_ulog_info *) target->data; 156 157 if (strcmp(loginfo->prefix, "") != 0) { 158 fputs("--ulog-prefix ", stdout); 159 save_string(loginfo->prefix); 160 } 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 %u ", (unsigned int)loginfo->copy_range); 168 169 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD) 170 printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold); 171} 172 173/* Prints out the targinfo. */ 174static void ULOG_print(const void *ip, const struct xt_entry_target *target, 175 int numeric) 176{ 177 const struct ipt_ulog_info *loginfo 178 = (const struct ipt_ulog_info *) target->data; 179 180 printf("ULOG "); 181 printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range); 182 print_groups(loginfo->nl_group); 183 if (strcmp(loginfo->prefix, "") != 0) 184 printf("prefix `%s' ", loginfo->prefix); 185 printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold); 186} 187 188static struct xtables_target ulog_tg_reg = { 189 .name = "ULOG", 190 .version = XTABLES_VERSION, 191 .family = PF_INET, 192 .size = XT_ALIGN(sizeof(struct ipt_ulog_info)), 193 .userspacesize = XT_ALIGN(sizeof(struct ipt_ulog_info)), 194 .help = ULOG_help, 195 .init = ULOG_init, 196 .parse = ULOG_parse, 197 .print = ULOG_print, 198 .save = ULOG_save, 199 .extra_opts = ULOG_opts, 200}; 201 202void _init(void) 203{ 204 xtables_register_target(&ulog_tg_reg); 205} 206