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