libipt_ULOG.c revision 67f23b2b40e937b3a20b4de4aa7bad7d2768e68e
1/* Shared library add-on to iptables to add ULOG support. 2 * 3 * (C) 2000 by Harald Welte <laforge@sunbeam.franken.de> 4 * 5 * This software is released under the terms of GNU GPL 6 * 7 * libipt_ULOG.c,v 1.3 2000/07/31 11:51:50 laforge Exp 8 */ 9#include <stdio.h> 10#include <netdb.h> 11#include <string.h> 12#include <stdlib.h> 13#include <syslog.h> 14#include <getopt.h> 15#include <iptables.h> 16#include <linux/netfilter_ipv4/ip_tables.h> 17#include <linux/netfilter_ipv4/ipt_ULOG.h> 18 19#define ULOG_DEFAULT_NLGROUP 1 20 21 22void print_groups(unsigned int gmask) 23{ 24 int b; 25 unsigned int test; 26 27 for (b = 31; b >= 0; b--) { 28 test = (1 << b); 29 if (gmask & test) 30 printf("%d ", b + 1); 31 } 32} 33 34/* Function which prints out usage message. */ 35static void help(void) 36{ 37 printf("ULOG v%s 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-prefix prefix Prefix log messages with this prefix.\n\n", 41 NETFILTER_VERSION); 42} 43 44static struct option opts[] = { 45 {"ulog-nlgroup", 1, 0, '!'}, 46 {"ulog-prefix", 1, 0, '#'}, 47 {"ulog-cprange", 1, 0, 'A'}, 48 {0} 49}; 50 51/* Initialize the target. */ 52static void init(struct ipt_entry_target *t, unsigned int *nfcache) 53{ 54 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data; 55 56 loginfo->nl_group = ULOG_DEFAULT_NLGROUP; 57 58 /* Can't cache this */ 59 *nfcache |= NFC_UNKNOWN; 60} 61 62#define IPT_LOG_OPT_NLGROUP 0x01 63#define IPT_LOG_OPT_PREFIX 0x02 64#define IPT_LOG_OPT_CPRANGE 0x04 65 66/* Function which parses command options; returns true if it 67 ate an option */ 68static int parse(int c, char **argv, int invert, unsigned int *flags, 69 const struct ipt_entry *entry, 70 struct ipt_entry_target **target) 71{ 72 struct ipt_ulog_info *loginfo = 73 (struct ipt_ulog_info *) (*target)->data; 74 int group_d; 75 76 switch (c) { 77 case '!': 78 if (*flags & IPT_LOG_OPT_NLGROUP) 79 exit_error(PARAMETER_PROBLEM, 80 "Can't specify --ulog-nlgroup twice"); 81 82 if (check_inverse(optarg, &invert)) 83 exit_error(PARAMETER_PROBLEM, 84 "Unexpected `!' after --ulog-nlgroup"); 85 group_d = atoi(optarg); 86 if (group_d > 32 || group_d < 1) 87 exit_error(PARAMETER_PROBLEM, 88 "--ulog-nlgroup has to be between 1 and 32"); 89 90 loginfo->nl_group = (1 << (group_d - 1)); 91 92 *flags |= IPT_LOG_OPT_NLGROUP; 93 break; 94 95 case '#': 96 if (*flags & IPT_LOG_OPT_PREFIX) 97 exit_error(PARAMETER_PROBLEM, 98 "Can't specify --ulog-prefix twice"); 99 100 if (check_inverse(optarg, &invert)) 101 exit_error(PARAMETER_PROBLEM, 102 "Unexpected `!' after --ulog-prefix"); 103 104 if (strlen(optarg) > sizeof(loginfo->prefix) - 1) 105 exit_error(PARAMETER_PROBLEM, 106 "Maximum prefix length %u for --ulog-prefix", 107 sizeof(loginfo->prefix) - 1); 108 109 strcpy(loginfo->prefix, optarg); 110 *flags |= IPT_LOG_OPT_PREFIX; 111 break; 112 case 'A': 113 if (*flags & IPT_LOG_OPT_CPRANGE) 114 exit_error(PARAMETER_PROBLEM, 115 "Can't specify --ulog-cprange twice"); 116 if (atoi(optarg) < 0) 117 exit_error(PARAMETER_PROBLEM, 118 "Negative copy range?"); 119 loginfo->copy_range = atoi(optarg); 120 *flags |= IPT_LOG_OPT_CPRANGE; 121 break; 122 } 123 return 1; 124} 125 126/* Final check; nothing. */ 127static void final_check(unsigned int flags) 128{ 129} 130 131/* Saves the union ipt_targinfo in parsable form to stdout. */ 132static void save(const struct ipt_ip *ip, 133 const struct ipt_entry_target *target) 134{ 135 const struct ipt_ulog_info *loginfo 136 = (const struct ipt_ulog_info *) target->data; 137 138 if (strcmp(loginfo->prefix, "") != 0) 139 printf("--ulog-prefix %s ", loginfo->prefix); 140 141 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) { 142 printf("--ulog-nlgroup "); 143 print_groups(loginfo->nl_group); 144 printf("\n"); 145 } 146 if (loginfo->copy_range) 147 printf("--ulog-cprange %d", loginfo->copy_range); 148} 149 150/* Prints out the targinfo. */ 151static void 152print(const struct ipt_ip *ip, 153 const struct ipt_entry_target *target, int numeric) 154{ 155 const struct ipt_ulog_info *loginfo 156 = (const struct ipt_ulog_info *) target->data; 157 158 printf("ULOG "); 159 printf("copy_range %d nlgroup ", loginfo->copy_range); 160 print_groups(loginfo->nl_group); 161 if (strcmp(loginfo->prefix, "") != 0) 162 printf("prefix `%s' ", loginfo->prefix); 163} 164 165struct iptables_target ulog = { NULL, 166 "ULOG", 167 NETFILTER_VERSION, 168 IPT_ALIGN(sizeof(struct ipt_ulog_info)), 169 IPT_ALIGN(sizeof(struct ipt_ulog_info)), 170 &help, 171 &init, 172 &parse, 173 &final_check, 174 &print, 175 &save, 176 opts 177}; 178 179void _init(void) 180{ 181 register_target(&ulog); 182} 183