iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libipt_psd.c
1 /* 
2   Shared library add-on to iptables to add PSD support 
3    
4   Copyright (C) 2000,2001 astaro AG
5
6   This file is distributed under the terms of the GNU General Public
7   License (GPL). Copies of the GPL can be obtained from:
8      ftp://prep.ai.mit.edu/pub/gnu/GPL
9
10   2000-05-04 Markus Hennig <hennig@astaro.de> : initial
11   2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
12   2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
13   2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
14   2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
15 */
16
17 #include <stdio.h>
18 #include <netdb.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <syslog.h>
22 #include <getopt.h>
23 #include <iptables.h>
24 #include <linux/netfilter_ipv4/ip_tables.h>
25 #include <linux/netfilter_ipv4/ipt_psd.h>
26
27
28 /* Function which prints out usage message. */
29 static void
30 help(void)
31 {
32         printf(
33 "psd v%s options:\n"
34 " --psd-weight-threshold threshhold  Portscan detection weight threshold\n\n"
35 " --psd-delay-threshold  delay       Portscan detection delay threshold\n\n"
36 " --psd-lo-ports-weight  lo          Privileged ports weight\n\n"
37 " --psd-hi-ports-weight  hi          High ports weight\n\n",
38 IPTABLES_VERSION);
39 }
40
41 static struct option opts[] = {
42         { "psd-weight-threshold", 1, 0, '1' },
43         { "psd-delay-threshold", 1, 0, '2' },
44         { "psd-lo-ports-weight", 1, 0, '3' },
45         { "psd-hi-ports-weight", 1, 0, '4' },
46         { 0 }
47 };
48
49 /* Initialize the target. */
50 static void
51 init(struct ipt_entry_match *m, unsigned int *nfcache)
52 {
53         struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)m->data;
54
55         psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;  
56         psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
57         psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
58         psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
59         /* Can't cache this */
60         *nfcache |= NFC_UNKNOWN;
61 }
62
63
64 typedef struct _code {
65         char    *c_name;
66         int     c_val;
67 } CODE;
68
69
70
71 #define IPT_PSD_OPT_CTRESH 0x01
72 #define IPT_PSD_OPT_DTRESH 0x02
73 #define IPT_PSD_OPT_LPWEIGHT 0x04
74 #define IPT_PSD_OPT_HPWEIGHT 0x08
75
76 /* Function which parses command options; returns true if it
77    ate an option */
78 static int
79 parse(int c, char **argv, int invert, unsigned int *flags,
80       const struct ipt_entry *entry,
81       unsigned int *nfcache,
82       struct ipt_entry_match **match)
83 {
84         struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)(*match)->data;
85         unsigned int num;
86         
87         if (!optarg)
88                 exit_error(PARAMETER_PROBLEM, "missing optarg");
89
90         /* string_to_number needs a leading space */
91
92         switch (c) {
93         /* PSD-weight-threshold */
94         case '1':
95                 if (*flags & IPT_PSD_OPT_CTRESH)
96                         exit_error(PARAMETER_PROBLEM,
97                                    "Can't specify --psd-weight-threshold "
98                                    "twice");
99                 if (string_to_number(optarg, 0, 10000, &num) == -1)
100                         exit_error(PARAMETER_PROBLEM,
101                                    "bad --psd-weight-threshold `%s'", optarg);
102                 psdinfo->weight_threshold = num;
103                 *flags |= IPT_PSD_OPT_CTRESH;
104                 break;
105
106         /* PSD-delay-threshold */
107         case '2':
108                 if (*flags & IPT_PSD_OPT_DTRESH)
109                         exit_error(PARAMETER_PROBLEM,
110                                    "Can't specify --psd-delay-threshold twice");
111                 if (string_to_number(optarg, 0, 10000, &num) == -1)
112                         exit_error(PARAMETER_PROBLEM,
113                                    "bad --psd-delay-threshold `%s'", optarg);
114                 psdinfo->delay_threshold = num;
115                 *flags |= IPT_PSD_OPT_DTRESH;
116                 break;
117
118         /* PSD-lo-ports-weight */
119         case '3':
120                 if (*flags & IPT_PSD_OPT_LPWEIGHT)
121                         exit_error(PARAMETER_PROBLEM,
122                                    "Can't specify --psd-lo-ports-weight twice");
123                 if (string_to_number(optarg, 0, 10000, &num) == -1)
124                         exit_error(PARAMETER_PROBLEM,
125                                    "bad --psd-lo-ports-weight `%s'", optarg);
126                 psdinfo->lo_ports_weight = num;
127                 *flags |= IPT_PSD_OPT_LPWEIGHT;
128                 break;
129
130         /* PSD-hi-ports-weight */
131         case '4':
132                 if (*flags & IPT_PSD_OPT_HPWEIGHT)
133                         exit_error(PARAMETER_PROBLEM,
134                                    "Can't specify --psd-hi-ports-weight twice");
135                 if (string_to_number(optarg, 0, 10000, &num) == -1)
136                         exit_error(PARAMETER_PROBLEM,
137                                    "bad --psd-hi-ports-weight `%s'", optarg);
138                 psdinfo->hi_ports_weight = num;
139                 *flags |= IPT_PSD_OPT_HPWEIGHT;
140                 break;
141
142         default:
143                 return 0;
144         }
145
146         return 1;
147 }
148
149 /* Final check; nothing. */
150 static void final_check(unsigned int flags)
151 {
152 }
153
154 /* Prints out the targinfo. */
155 static void
156 print(const struct ipt_ip *ip,
157       const struct ipt_entry_match *match,
158       int numeric)
159 {
160         const struct ipt_psd_info *psdinfo
161                 = (const struct ipt_psd_info *)match->data;
162
163         printf("psd ");
164         printf("weight-threshold: %u ", psdinfo->weight_threshold);
165         printf("delay-threshold: %u ", psdinfo->delay_threshold);
166         printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
167         printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
168 }
169
170 /* Saves the union ipt_targinfo in parsable form to stdout. */
171 static void
172 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
173 {
174         const struct ipt_psd_info *psdinfo
175                 = (const struct ipt_psd_info *)match->data;
176
177         printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
178         printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
179         printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
180         printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
181 }
182
183 static
184 struct iptables_match psd
185 = { NULL,
186     "psd",
187     IPTABLES_VERSION,
188     IPT_ALIGN(sizeof(struct ipt_psd_info)),
189     IPT_ALIGN(sizeof(struct ipt_psd_info)),
190     &help,
191     &init,
192     &parse,
193     &final_check,
194     &print,
195     &save,
196     opts
197 };
198
199 void _init(void)
200 {
201         register_match(&psd);
202 }