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