]>
Commit | Line | Data |
---|---|---|
43fa63f7 | 1 | diff -Nur linux-2.6.1-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.1-rc2/include/linux/netfilter_ipv4/ipt_psd.h |
2 | --- linux-2.6.1-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100 | |
3 | +++ linux-2.6.1-rc2/include/linux/netfilter_ipv4/ipt_psd.h 2004-01-07 18:17:50.030389768 +0100 | |
4 | @@ -0,0 +1,40 @@ | |
5 | +#ifndef _IPT_PSD_H | |
6 | +#define _IPT_PSD_H | |
7 | + | |
8 | +#include <linux/param.h> | |
9 | +#include <linux/types.h> | |
10 | + | |
11 | +/* | |
12 | + * High port numbers have a lower weight to reduce the frequency of false | |
13 | + * positives, such as from passive mode FTP transfers. | |
14 | + */ | |
15 | +#define PORT_WEIGHT_PRIV 3 | |
16 | +#define PORT_WEIGHT_HIGH 1 | |
17 | + | |
18 | +/* | |
19 | + * Port scan detection thresholds: at least COUNT ports need to be scanned | |
20 | + * from the same source, with no longer than DELAY ticks between ports. | |
21 | + */ | |
22 | +#define SCAN_MIN_COUNT 7 | |
23 | +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV) | |
24 | +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT | |
25 | +#define SCAN_DELAY_THRESHOLD (HZ * 3) | |
26 | + | |
27 | +/* | |
28 | + * Keep track of up to LIST_SIZE source addresses, using a hash table of | |
29 | + * HASH_SIZE entries for faster lookups, but limiting hash collisions to | |
30 | + * HASH_MAX source addresses per the same hash value. | |
31 | + */ | |
32 | +#define LIST_SIZE 0x100 | |
33 | +#define HASH_LOG 9 | |
34 | +#define HASH_SIZE (1 << HASH_LOG) | |
35 | +#define HASH_MAX 0x10 | |
36 | + | |
37 | +struct ipt_psd_info { | |
38 | + unsigned int weight_threshold; | |
39 | + unsigned int delay_threshold; | |
40 | + unsigned short lo_ports_weight; | |
41 | + unsigned short hi_ports_weight; | |
42 | +}; | |
43 | + | |
44 | +#endif /*_IPT_PSD_H*/ | |
45 | diff -Nur linux-2.6.1-rc2.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.1-rc2/net/ipv4/netfilter/ipt_psd.c | |
46 | --- linux-2.6.1-rc2.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100 | |
47 | +++ linux-2.6.1-rc2/net/ipv4/netfilter/ipt_psd.c 2004-01-07 18:17:50.031389616 +0100 | |
48 | @@ -0,0 +1,361 @@ | |
49 | +/* | |
50 | + This is a module which is used for PSD (portscan detection) | |
51 | + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com> | |
52 | + and LOG target module. | |
53 | + | |
54 | + Copyright (C) 2000,2001 astaro AG | |
55 | + | |
56 | + This file is distributed under the terms of the GNU General Public | |
57 | + License (GPL). Copies of the GPL can be obtained from: | |
58 | + ftp://prep.ai.mit.edu/pub/gnu/GPL | |
59 | + | |
60 | + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial | |
61 | + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release | |
62 | + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added | |
63 | + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified | |
64 | + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match | |
65 | +*/ | |
66 | + | |
67 | +#include <linux/module.h> | |
68 | +#include <linux/skbuff.h> | |
69 | +#include <linux/ip.h> | |
70 | +#include <net/tcp.h> | |
71 | +#include <linux/spinlock.h> | |
72 | +#include <linux/netfilter_ipv4/ip_tables.h> | |
73 | +#include <linux/netfilter_ipv4/ipt_psd.h> | |
74 | + | |
75 | +#if 0 | |
76 | +#define DEBUGP printk | |
77 | +#else | |
78 | +#define DEBUGP(format, args...) | |
79 | +#endif | |
80 | + | |
81 | +MODULE_LICENSE("GPL"); | |
82 | +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>"); | |
83 | + | |
84 | +#define HF_DADDR_CHANGING 0x01 | |
85 | +#define HF_SPORT_CHANGING 0x02 | |
86 | +#define HF_TOS_CHANGING 0x04 | |
87 | +#define HF_TTL_CHANGING 0x08 | |
88 | + | |
89 | +/* | |
90 | + * Information we keep per each target port | |
91 | + */ | |
92 | +struct port { | |
93 | + u_int16_t number; /* port number */ | |
94 | + u_int8_t proto; /* protocol number */ | |
95 | + u_int8_t and_flags; /* tcp ANDed flags */ | |
96 | + u_int8_t or_flags; /* tcp ORed flags */ | |
97 | +}; | |
98 | + | |
99 | +/* | |
100 | + * Information we keep per each source address. | |
101 | + */ | |
102 | +struct host { | |
103 | + struct host *next; /* Next entry with the same hash */ | |
104 | + clock_t timestamp; /* Last update time */ | |
105 | + struct in_addr src_addr; /* Source address */ | |
106 | + struct in_addr dest_addr; /* Destination address */ | |
107 | + unsigned short src_port; /* Source port */ | |
108 | + int count; /* Number of ports in the list */ | |
109 | + int weight; /* Total weight of ports in the list */ | |
110 | + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */ | |
111 | + unsigned char tos; /* TOS */ | |
112 | + unsigned char ttl; /* TTL */ | |
113 | + unsigned char flags; /* HF_ flags bitmask */ | |
114 | +}; | |
115 | + | |
116 | +/* | |
117 | + * State information. | |
118 | + */ | |
119 | +static struct { | |
120 | + spinlock_t lock; | |
121 | + struct host list[LIST_SIZE]; /* List of source addresses */ | |
122 | + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */ | |
123 | + int index; /* Oldest entry to be replaced */ | |
124 | +} state; | |
125 | + | |
126 | +/* | |
127 | + * Convert an IP address into a hash table index. | |
128 | + */ | |
129 | +static inline int hashfunc(struct in_addr addr) | |
130 | +{ | |
131 | + unsigned int value; | |
132 | + int hash; | |
133 | + | |
134 | + value = addr.s_addr; | |
135 | + hash = 0; | |
136 | + do { | |
137 | + hash ^= value; | |
138 | + } while ((value >>= HASH_LOG)); | |
139 | + | |
140 | + return hash & (HASH_SIZE - 1); | |
141 | +} | |
142 | + | |
143 | +static int | |
144 | +ipt_psd_match(const struct sk_buff *pskb, | |
145 | + const struct net_device *in, | |
146 | + const struct net_device *out, | |
147 | + const void *matchinfo, | |
148 | + int offset, | |
149 | + const void *hdr, | |
150 | + u_int16_t datalen, | |
151 | + int *hotdrop) | |
152 | +{ | |
153 | + struct iphdr *ip_hdr; | |
154 | + struct tcphdr *tcp_hdr; | |
155 | + struct in_addr addr; | |
156 | + u_int16_t src_port,dest_port; | |
157 | + u_int8_t tcp_flags, proto; | |
158 | + clock_t now; | |
159 | + struct host *curr, *last, **head; | |
160 | + int hash, index, count; | |
161 | + | |
162 | + /* Parameters from userspace */ | |
163 | + const struct ipt_psd_info *psdinfo = matchinfo; | |
164 | + | |
165 | + /* IP header */ | |
166 | + ip_hdr = pskb->nh.iph; | |
167 | + | |
168 | + /* Sanity check */ | |
169 | + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) { | |
170 | + DEBUGP("PSD: sanity check failed\n"); | |
171 | + return 0; | |
172 | + } | |
173 | + | |
174 | + /* TCP or UDP ? */ | |
175 | + proto = ip_hdr->protocol; | |
176 | + | |
177 | + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) { | |
178 | + DEBUGP("PSD: protocol not supported\n"); | |
179 | + return 0; | |
180 | + } | |
181 | + | |
182 | + /* Get the source address, source & destination ports, and TCP flags */ | |
183 | + | |
184 | + addr.s_addr = ip_hdr->saddr; | |
185 | + | |
186 | + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl); | |
187 | + | |
188 |