iptables-1.3.2-20050720
[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 }
60
61
62 typedef struct _code {
63         char    *c_name;
64         int     c_val;
65 } CODE;
66
67
68
69 #define IPT_PSD_OPT_CTRESH 0x01
70 #define IPT_PSD_OPT_DTRESH 0x02
71 #define IPT_PSD_OPT_LPWEIGHT 0x04
72 #define IPT_PSD_OPT_HPWEIGHT 0x08
73
74 /* Function which parses command options; returns true if it
75    ate an option */
76 static int
77 parse(int c, char **argv, int invert, unsigned int *flags,
78       const struct ipt_entry *entry,
79       unsigned int *nfcache,
80       struct ipt_entry_match **match)
81 {
82         struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)(*match)->data;
83         unsigned int num;
84         
85         switch (c) {
86         /* PSD-weight-threshold */
87         case '1':
88                 if (*flags & IPT_PSD_OPT_CTRESH)
89                         exit_error(PARAMETER_PROBLEM,
90                                    "Can't specify --psd-weight-threshold "
91                                    "twice");
92                 if (string_to_number(optarg, 0, 10000, &num) == -1)
93                         exit_error(PARAMETER_PROBLEM,
94                                    "bad --psd-weight-threshold `%s'", optarg);
95                 psdinfo->weight_threshold = num;
96                 *flags |= IPT_PSD_OPT_CTRESH;
97                 break;
98
99         /* PSD-delay-threshold */
100         case '2':
101                 if (*flags & IPT_PSD_OPT_DTRESH)
102                         exit_error(PARAMETER_PROBLEM,
103                                    "Can't specify --psd-delay-threshold twice");
104                 if (string_to_number(optarg, 0, 10000, &num) == -1)
105                         exit_error(PARAMETER_PROBLEM,
106                                    "bad --psd-delay-threshold `%s'", optarg);
107                 psdinfo->delay_threshold = num;
108                 *flags |= IPT_PSD_OPT_DTRESH;
109                 break;
110
111         /* PSD-lo-ports-weight */
112         case '3':
113                 if (*flags & IPT_PSD_OPT_LPWEIGHT)
114                         exit_error(PARAMETER_PROBLEM,
115                                    "Can't specify --psd-lo-ports-weight twice");
116                 if (string_to_number(optarg, 0, 10000, &num) == -1)
117                         exit_error(PARAMETER_PROBLEM,
118                                    "bad --psd-lo-ports-weight `%s'", optarg);
119                 psdinfo->lo_ports_weight = num;
120                 *flags |= IPT_PSD_OPT_LPWEIGHT;
121                 break;
122
123         /* PSD-hi-ports-weight */
124         case '4':
125                 if (*flags & IPT_PSD_OPT_HPWEIGHT)
126                         exit_error(PARAMETER_PROBLEM,
127                                    "Can't specify --psd-hi-ports-weight twice");
128                 if (string_to_number(optarg, 0, 10000, &num) == -1)
129                         exit_error(PARAMETER_PROBLEM,
130                                    "bad --psd-hi-ports-weight `%s'", optarg);
131                 psdinfo->hi_ports_weight = num;
132                 *flags |= IPT_PSD_OPT_HPWEIGHT;
133                 break;
134
135         default:
136                 return 0;
137         }
138
139         return 1;
140 }
141
142 /* Final check; nothing. */
143 static void final_check(unsigned int flags)
144 {
145 }
146
147 /* Prints out the targinfo. */
148 static void
149 print(const struct ipt_ip *ip,
150       const struct ipt_entry_match *match,
151       int numeric)
152 {
153         const struct ipt_psd_info *psdinfo
154                 = (const struct ipt_psd_info *)match->data;
155
156         printf("psd ");
157         printf("weight-threshold: %u ", psdinfo->weight_threshold);
158         printf("delay-threshold: %u ", psdinfo->delay_threshold);
159         printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
160         printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
161 }
162
163 /* Saves the union ipt_targinfo in parsable form to stdout. */
164 static void
165 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
166 {
167         const struct ipt_psd_info *psdinfo
168                 = (const struct ipt_psd_info *)match->data;
169
170         printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
171         printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
172         printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
173         printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
174 }
175
176 static struct iptables_match psd = { 
177         .next           = NULL,
178         .name           = "psd",
179         .version        = IPTABLES_VERSION,
180         .size           = IPT_ALIGN(sizeof(struct ipt_psd_info)),
181         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_psd_info)),
182         .help           = &help,
183         .init           = &init,
184         .parse          = &parse,
185         .final_check    = &final_check,
186         .print          = &print,
187         .save           = &save,
188         .extra_opts     = opts
189 };
190
191 void _init(void)
192 {
193         register_match(&psd);
194 }