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