]> git.pld-linux.org Git - packages/kernel.git/blob - pom-ng-rpc-20061213.patch
- use CUBIC by default:
[packages/kernel.git] / pom-ng-rpc-20061213.patch
1 diff -NurpP --minimal linux-2.6.19-pom-ng/include/linux/netfilter_ipv4/ip_conntrack_rpc.h linux-2.6.19/include/linux/netfilter_ipv4/ip_conntrack_rpc.h
2 --- linux-2.6.19-pom-ng/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.19/include/linux/netfilter_ipv4/ip_conntrack_rpc.h        2006-12-14 11:25:47.000000000 +0100
4 @@ -0,0 +1,71 @@
5 +/* RPC extension for IP connection tracking, Version 2.2
6 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
7 + *     - original rpc tracking module
8 + *     - "recent" connection handling for kernel 2.3+ netfilter
9 + *
10 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
11 + *     - upgraded conntrack modules to oldnat api - kernel 2.4.0+
12 + *
13 + * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
14 + *     - upgraded conntrack modules to newnat api - kernel 2.4.20+
15 + *     - extended matching to support filtering on procedures
16 + *
17 + * (C) 2005 by David Stes <stes@pandora.be>
18 + *      - upgraded to 2.6.13 API
19 + *
20 + * ip_conntrack_rpc.h,v 2.2 2003/01/12 18:30:00
21 + *
22 + *     This program is free software; you can redistribute it and/or
23 + *     modify it under the terms of the GNU General Public License
24 + *     as published by the Free Software Foundation; either version
25 + *     2 of the License, or (at your option) any later version.
26 + **
27 + */
28 +
29 +#include <asm/param.h>
30 +#include <linux/sched.h>
31 +#include <linux/timer.h>
32 +#include <linux/stddef.h>
33 +#include <linux/list.h>
34 +
35 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
36 +
37 +#ifndef _IP_CONNTRACK_RPC_H
38 +#define _IP_CONNTRACK_RPC_H
39 +
40 +#define RPC_PORT       111
41 +
42 +
43 +/* Datum in RPC packets are encoded in XDR */
44 +#define IXDR_GET_INT32(buf) ((u_int32_t) ntohl((uint32_t)*buf))
45 +
46 +/* Fast timeout, to deny DoS atacks */
47 +#define EXP (60 * HZ)
48 +
49 +/* Normal timeouts */
50 +#define EXPIRES (180 * HZ)
51 +
52 +/* For future conections RPC, using client's cache bindings
53 + * I'll use ip_conntrack_lock to lock these lists      */
54 +
55 +/* This identifies each request and stores protocol */
56 +struct request_p {
57 +       struct list_head list;
58 +
59 +       u_int32_t xid;   
60 +       u_int32_t ip;
61 +       u_int16_t port;
62 +       
63 +       /* Protocol */
64 +       u_int16_t proto;
65 +
66 +       struct timer_list timeout;
67 +};
68 +
69 +static inline int request_p_cmp(const struct request_p *p, u_int32_t xid, 
70 +                               u_int32_t ip, u_int32_t port) {
71 +       return (p->xid == xid && p->ip == ip && p->port);
72 +
73 +}
74 +
75 +#endif /* _IP_CONNTRACK_RPC_H */
76 diff -NurpP --minimal linux-2.6.19-pom-ng/include/linux/netfilter_ipv4/ipt_rpc.h linux-2.6.19/include/linux/netfilter_ipv4/ipt_rpc.h
77 --- linux-2.6.19-pom-ng/include/linux/netfilter_ipv4/ipt_rpc.h  1970-01-01 01:00:00.000000000 +0100
78 +++ linux-2.6.19/include/linux/netfilter_ipv4/ipt_rpc.h 2006-12-14 11:25:47.000000000 +0100
79 @@ -0,0 +1,35 @@
80 +/* RPC extension for IP netfilter matching, Version 2.2
81 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
82 + *     - original rpc tracking module
83 + *     - "recent" connection handling for kernel 2.3+ netfilter
84 + *
85 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
86 + *     - upgraded conntrack modules to oldnat api - kernel 2.4.0+
87 + *
88 + * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
89 + *     - upgraded conntrack modules to newnat api - kernel 2.4.20+
90 + *     - extended matching to support filtering on procedures
91 + *
92 + * ipt_rpc.h.c,v 2.2 2003/01/12 18:30:00
93 + *
94 + *     This program is free software; you can redistribute it and/or
95 + *     modify it under the terms of the GNU General Public License
96 + *     as published by the Free Software Foundation; either version
97 + *     2 of the License, or (at your option) any later version.
98 + **
99 + */
100 +
101 +#ifndef _IPT_RPC_H
102 +#define _IPT_RPC_H
103 +
104 +struct ipt_rpc_data;
105 +
106 +struct ipt_rpc_info {
107 +       int inverse;
108 +       int strict;
109 +       const char c_procs[1408];
110 +       int i_procs;
111 +       struct ipt_rpc_data *data;
112 +};
113 +
114 +#endif /* _IPT_RPC_H */
115 diff -NurpP --minimal linux-2.6.19-pom-ng/net/ipv4/netfilter/Kconfig linux-2.6.19/net/ipv4/netfilter/Kconfig
116 --- linux-2.6.19-pom-ng/net/ipv4/netfilter/Kconfig      2006-12-14 11:13:22.000000000 +0100
117 +++ linux-2.6.19/net/ipv4/netfilter/Kconfig     2006-12-14 11:25:47.000000000 +0100
118 @@ -820,5 +820,37 @@ config IP_NF_MMS
119           If you want to compile it as a module, say M here and read
120           <file:Documentation/modules.txt>.  If unsure, say `Y'.
121  
122 +config IP_NF_MATCH_RPC
123 +       tristate  'RPC match support'
124 +       depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
125 +       help
126 +         This adds CONFIG_IP_NF_MATCH_RPC, which is the RPC connection
127 +         matcher and tracker.
128 +       
129 +         This option supplies two connection tracking modules;
130 +         ip_conntrack_rpc_udp and ip_conntrack_rpc_tcp, which track
131 +         portmapper requests using UDP and TCP respectively.
132 +       
133 +         This option also adds an RPC match module for iptables, which
134 +         matches both via the old "record match" method and a new
135 +         "procedure match" method. The older method matches all RPC
136 +         procedure packets that relate to previously recorded packets
137 +         seen querying a portmapper. The newer method matches only
138 +         those RPC procedure packets explicitly specified by the user,
139 +         and that can then be related to previously recorded packets
140 +         seen querying a portmapper.
141 +       
142 +         These three modules are required if RPCs are to be filtered
143 +         accurately; as RPCs are allocated pseudo-randomly to UDP and
144 +         TCP ports as they register with the portmapper.
145 +       
146 +         Up to 8 portmapper ports per module, and up to 128 RPC
147 +         procedures per iptables rule, may be specified by the user,
148 +         to enable effective RPC management.
149 +       
150 +       
151 +         If you want to compile it as a module, say M here and read
152 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
153 +
154  endmenu
155  
156 diff -NurpP --minimal linux-2.6.19-pom-ng/net/ipv4/netfilter/Makefile linux-2.6.19/net/ipv4/netfilter/Makefile
157 --- linux-2.6.19-pom-ng/net/ipv4/netfilter/Makefile     2006-12-14 11:13:22.000000000 +0100
158 +++ linux-2.6.19/net/ipv4/netfilter/Makefile    2006-12-14 11:25:47.000000000 +0100
159 @@ -55,6 +55,9 @@ obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
160  obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
161  
162  # matches
163 +obj-$(CONFIG_IP_NF_MATCH_RPC) += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o ipt_rpc.o
164 +export-objs += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o
165 +
166  obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
167  obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
168  obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
169 diff -NurpP --minimal linux-2.6.19-pom-ng/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c linux-2.6.19/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c
170 --- linux-2.6.19-pom-ng/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c       1970-01-01 01:00:00.000000000 +0100
171 +++ linux-2.6.19/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c      2006-12-14 11:25:47.000000000 +0100
172 @@ -0,0 +1,554 @@
173 +/* RPC extension for IP (TCP) connection tracking, Version 2.2
174 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
175 + *     - original rpc tracking module
176 + *     - "recent" connection handling for kernel 2.3+ netfilter
177 + *
178 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
179 + *     - upgraded conntrack modules to oldnat api - kernel 2.4.0+
180 + *
181 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
182 + *     - upgraded conntrack modules to newnat api - kernel 2.4.20+
183 + *     - extended matching to support filtering on procedures
184 + * 
185 + * (c) 2004,2005 by David Stes <stes@pandora.be>
186 + *      - add nsrexec option for Legato NetWorker
187 + *     - upgraded to 2.6.12+ conntrack module api
188 + *
189 + * (c) 2005 by David Stes <stes@pandora.be>
190 + *      - upgraded to 2.6.13 conntrack module api
191 + *
192 + * ip_conntrack_rpc_tpc.c,v 2.2 2003/01/12 18:30:00
193 + *
194 + *     This program is free software; you can redistribute it and/or
195 + *     modify it under the terms of the GNU General Public License
196 + *     as published by the Free Software Foundation; either version
197 + *     2 of the License, or (at your option) any later version.
198 + **
199 + *     Module load syntax:
200 + *     insmod ip_conntrack_rpc_tcp.o nsrexec=<n> ports=port1,...port<MAX_PORTS>
201 + *
202 + *     Please give the ports of all RPC servers you wish to connect to.
203 + *      For example, ports=111,7938 for Legato NetWorker's portmapper on 7938.
204 + *     If you don't specify ports, the default will be port 111 (SUN portmap).
205 + *
206 + *      Please specify nsrexec, the TCP port of the rexec() service of
207 + *      Legato NetWorker.  For example, nsrexec=7937
208 + *
209 + **
210 + *     Note to all:
211 + *
212 + *     RPCs should not be exposed to the internet - ask the Pentagon;
213 + *
214 + *       "The unidentified crackers pleaded guilty in July to charges
215 + *        of juvenile delinquency stemming from a string of Pentagon
216 + *        network intrusions in February.
217 + *
218 + *        The youths, going by the names TooShort and Makaveli, used
219 + *        a common server security hole to break in, according to
220 + *        Dane Jasper, owner of the California Internet service
221 + *        provider, Sonic. They used the hole, known as the 'statd'
222 + *        exploit, to attempt more than 800 break-ins, Jasper said."
223 + *
224 + *     From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
225 + *     URL:  http://www.wired.com/news/politics/0,1283,16098,00.html
226 + **
227 + */
228 +
229 +#include <linux/module.h>
230 +#include <linux/netfilter.h>
231 +#include <linux/ip.h>
232 +#include <net/checksum.h>
233 +#include <net/tcp.h>
234 +
235 +#include <asm/param.h>
236 +#include <linux/sched.h>
237 +#include <linux/timer.h>
238 +#include <linux/stddef.h>
239 +#include <linux/list.h>
240 +
241 +#include <linux/netfilter_ipv4/ip_tables.h>
242 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
243 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
244 +
245 +#define MAX_PORTS 8
246 +static int ports[MAX_PORTS];
247 +static int ports_n_c = 0;
248 +static int nsrexec = 0;
249 +
250 +#ifdef MODULE_PARM
251 +module_param(nsrexec,int, 0400);
252 +MODULE_PARM_DESC(nsrexec, "TCP port of Legato NetWorker's rexec service");
253 +module_param_array(ports, int, &ports_n_c, 0400);
254 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
255 +#endif
256 +
257 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
258 +MODULE_DESCRIPTION("RPC TCP connection tracking module");
259 +MODULE_LICENSE("GPL");
260 +
261 +#define PRINTK(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_tcp: " \
262 +                                       format, ## args)
263 +
264 +#if 0
265 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_tcp: " \
266 +                                       format, ## args)
267 +#else
268 +#define DEBUGP(format, args...)
269 +#endif
270 +
271 +DEFINE_RWLOCK(ipct_rpc_tcp_lock);
272 +
273 +#define ASSERT_READ_LOCK(x)
274 +#define ASSERT_WRITE_LOCK(x)
275 +
276 +#include <linux/netfilter_ipv4/listhelp.h>
277 +
278 +/* For future conections RPC, using client's cache bindings
279 + * I'll use ip_conntrack_lock to lock these lists         */
280 +
281 +LIST_HEAD(request_p_list_tcp);
282 +
283 +
284 +static void delete_request_p(unsigned long request_p_ul) 
285 +{
286 +       struct request_p *p = (void *)request_p_ul;
287 +       
288 +       write_lock_bh(&ipct_rpc_tcp_lock);
289 +       LIST_DELETE(&request_p_list_tcp, p);
290 +       write_unlock_bh(&ipct_rpc_tcp_lock);
291 +       kfree(p);
292 +       return;
293 +}
294 +
295 +
296 +static void req_cl(struct request_p * r)
297 +{
298 +       write_lock_bh(&ipct_rpc_tcp_lock);
299 +       del_timer(&r->timeout);
300 +       LIST_DELETE(&request_p_list_tcp, r);
301 +       write_unlock_bh(&ipct_rpc_tcp_lock);
302 +       kfree(r);
303 +       return;
304 +}
305 +
306 +
307 +static void clean_request(struct list_head *list)
308 +{
309 +       struct list_head *first = list->prev;
310 +       struct list_head *temp = list->next;
311 +       struct list_head *aux;
312 +
313 +       if (list_empty(list))
314 +               return;
315 +
316 +       while (first != temp) {
317 +               aux = temp->next;
318 +               req_cl((struct request_p *)temp);
319 +               temp = aux;     
320 +       }
321 +       req_cl((struct request_p *)temp);
322 +       return;
323 +}
324 +
325 +
326 +static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
327 +                    u_int16_t port)
328 +{
329 +       struct request_p *req_p;
330 +       
331 +       /* Verifies if entry already exists */
332 +       write_lock_bh(&ipct_rpc_tcp_lock);
333 +       req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
334 +               struct request_p *, xid, ip, port);
335 +
336 +       if (req_p) {
337 +               /* Refresh timeout */
338 +               if (del_timer(&req_p->timeout)) {
339 +                       req_p->timeout.expires = jiffies + EXP;
340 +                       add_timer(&req_p->timeout);     
341 +               } 
342 +               write_unlock_bh(&ipct_rpc_tcp_lock);
343 +               return; 
344 +
345 +       }
346 +       write_unlock_bh(&ipct_rpc_tcp_lock);
347 +       
348 +       /* Allocate new request_p */
349 +       req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
350 +       if (!req_p) {
351 +               DEBUGP("can't allocate request_p\n");
352 +               return;                 
353 +       }
354 +
355 +        req_p->list.next = NULL;
356 +        req_p->list.prev = NULL;
357 +        req_p->xid = xid;
358 +        req_p->ip = ip;
359 +        req_p->port = port;
360 +        req_p->proto = proto;
361 +      
362 +       /* Initialize timer */
363 +       init_timer(&req_p->timeout);
364 +        req_p->timeout.expires = jiffies + EXP;
365 +       req_p->timeout.data = (unsigned long)req_p;
366 +       req_p->timeout.function = delete_request_p;
367 +       add_timer(&req_p->timeout); 
368 +
369 +       /* Put in list */
370 +       write_lock_bh(&ipct_rpc_tcp_lock);
371 +       list_prepend(&request_p_list_tcp, req_p);
372 +       write_unlock_bh(&ipct_rpc_tcp_lock); 
373 +       return; 
374 +}
375 +
376 +
377 +static int check_rpc_packet(const u_int32_t *data,
378 +                       int dir, struct ip_conntrack *ct,
379 +                       struct list_head request_p_list)
380 +{
381 +       u_int32_t xid;
382 +        int ret = NF_ACCEPT;
383 +       struct request_p *req_p;
384 +       struct ip_conntrack_expect *exp;
385 +
386 +
387 +       if (ct == NULL) {
388 +               DEBUGP("ct is NULL");
389 +               return ret;
390 +       }
391 +
392 +        /* Translstion's buffer for XDR */
393 +        u_int16_t port_buf;
394 +
395 +       /* Get XID */
396 +       xid = *data;
397 +
398 +       /* This does sanity checking on RPC payloads,
399 +        * and permits only the RPC "get port" (3)
400 +        * in authorised procedures in client
401 +        * communications with the portmapper.
402 +        */
403 +
404 +       /* perform direction dependant RPC work */
405 +       if (dir == IP_CT_DIR_ORIGINAL) {
406 +
407 +               data += 5;
408 +
409 +               /* Get RPC requestor */
410 +               if (IXDR_GET_INT32(data) != 3) {
411 +                       DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
412 +                       return NF_ACCEPT;
413 +               }
414 +               DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
415 +
416 +               data++;
417 +
418 +               /* Jump Credentials and Verfifier */
419 +               data += IXDR_GET_INT32(data) + 2;
420 +               data += IXDR_GET_INT32(data) + 2;
421 +
422 +               /* Get RPC procedure */
423 +               DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
424 +                       (unsigned int)IXDR_GET_INT32(data));
425 +
426 +               /* Get RPC protocol and store against client parameters */
427 +               data = data + 2;
428 +               alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
429 +                               ct->tuplehash[dir].tuple.src.u.all);
430 +
431 +               DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
432 +                       xid, IXDR_GET_INT32(data),
433 +                       NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
434 +                       ntohs(ct->tuplehash[dir].tuple.src.u.all));
435 +
436 +               DEBUGP("allocated RPC request for protocol %u. [done]\n",
437 +                       (unsigned int)IXDR_GET_INT32(data));
438 +
439 +       } else {
440 +
441 +               /* Check for returning packet's stored counterpart */
442 +               req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
443 +                                 struct request_p *, xid,
444 +                                 ct->tuplehash[!dir].tuple.src.ip,
445 +                                 ct->tuplehash[!dir].tuple.src.u.all);
446 +
447 +               /* Drop unexpected packets */
448 +               if (!req_p) {
449 +                       DEBUGP("packet is not expected. [skip]\n");
450 +                       return NF_ACCEPT;
451 +               }
452 +
453 +               /* Verifies if packet is really an RPC reply packet */
454 +               data++;
455 +               if (IXDR_GET_INT32(data) != 1) {
456 +                       DEBUGP("packet is not a valid RPC reply. [skip]\n");
457 +                       return NF_ACCEPT;
458 +               }
459 +
460 +               /* Is status accept? */
461 +               data++;
462 +               if (IXDR_GET_INT32(data)) {
463 +                       DEBUGP("packet is not an RPC accept. [skip]\n");
464 +                       return NF_ACCEPT;
465 +               }
466 +
467 +               /* Get Verifier length. Jump verifier */
468 +               data++;
469 +               data = data + IXDR_GET_INT32(data) + 2;
470 +
471 +               /* Is accpet status "success"? */
472 +               if (IXDR_GET_INT32(data)) {
473 +                       DEBUGP("packet is not an RPC accept status of success. [skip]\n");
474 +                       return NF_ACCEPT;
475 +               }
476 +
477 +               /* Get server port number */      
478 +               data++;
479 +               port_buf = (u_int16_t) IXDR_GET_INT32(data);
480 +
481 +               /* If a packet has made it this far then it deserves an
482 +                * expectation ...  if port == 0, then this service is 
483 +                * not going to be registered.
484 +                */
485 +               if (port_buf && port_buf != nsrexec) {
486 +                       DEBUGP("port found: %u\n", port_buf);
487 +
488 +                        exp = ip_conntrack_expect_alloc(ct);
489 +                        if (!exp) {
490 +                          ret = NF_DROP;
491 +                          goto out;
492 +                        }
493 +
494 +                       /* Watch out, Radioactive-Man! */
495 +                       exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
496 +                       exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
497 +                       exp->mask.src.ip = 0xffffffff;
498 +                       exp->mask.dst.ip = 0xffffffff;
499 +
500 +                       switch (req_p->proto) {
501 +                               case IPPROTO_UDP:
502 +                                       exp->tuple.src.u.udp.port = 0;
503 +                                       exp->tuple.dst.u.udp.port = htons(port_buf);
504 +                                       exp->tuple.dst.protonum = IPPROTO_UDP;
505 +                                       exp->mask.src.u.udp.port = 0;
506 +                                       exp->mask.dst.u.udp.port = htons(0xffff);
507 +                                       exp->mask.dst.protonum = 0xff;
508 +                                       break;
509 +
510 +                               case IPPROTO_TCP:
511 +                                       exp->tuple.src.u.tcp.port = 0;
512 +                                       exp->tuple.dst.u.tcp.port = htons(port_buf);
513 +                                       exp->tuple.dst.protonum = IPPROTO_TCP;
514 +                                       exp->mask.src.u.tcp.port = 0;
515 +                                       exp->mask.dst.u.tcp.port = htons(0xffff);
516 +                                       exp->mask.dst.protonum = 0xff;
517 +                                       break;
518 +                       }
519 +                       exp->expectfn = NULL;
520 +                       exp->master = ct;
521 +
522 +                       if (exp->master->helper == NULL) {
523 +                               DEBUGP("master helper NULL");
524 +                               ret = NF_ACCEPT;
525 +                       }
526 +                       
527 +                       DEBUGP("expect related ip   %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
528 +                               NIPQUAD(exp->tuple.src.ip),
529 +                               NIPQUAD(exp->tuple.dst.ip),
530 +                               port_buf, req_p->proto);
531 +
532 +                       DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
533 +                               NIPQUAD(exp->mask.src.ip),
534 +                               NIPQUAD(exp->mask.dst.ip),
535 +                               exp->mask.dst.protonum);
536 +
537 +                       if (ip_conntrack_expect_related(exp) != 0) {
538 +                               ret = NF_DROP;
539 +                       }
540 +
541 +               }
542 +
543 +out:
544 +               req_cl(req_p);
545 +
546 +               DEBUGP("packet evaluated. [expect]\n");
547 +       }
548 +
549 +       return ret;
550 +
551 +}
552 +
553 +
554 +/* RPC TCP helper */
555 +/* static int help(const struct iphdr *iph, size_t len,
556 +               struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) */
557 +static int help(struct sk_buff **pskb,
558 +               struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
559 +{
560 +       int dir;
561 +       int crp_ret;
562 +       struct tcphdr _tcph, *tcph;
563 +       const u_int32_t *data;
564 +       size_t tcplen;
565 +        struct iphdr *iph;
566 +        size_t len;
567 +
568 +       /* Not whole TCP header? */
569 +        iph=(*pskb)->nh.iph;
570 +       tcph = skb_header_pointer(*pskb,iph->ihl*4,sizeof(_tcph),&_tcph);
571 +       if (!tcph)
572 +               return NF_ACCEPT;
573 +
574 +       len = (*pskb)->len; /* stes */
575 +       data = (const u_int32_t *)tcph + tcph->doff;
576 +        tcplen = len - iph->ihl * 4;
577 +       dir = CTINFO2DIR(ctinfo);
578 +
579 +       DEBUGP("new packet to evaluate ..\n");
580 +
581 +       /* This works for packets like handshake packets, ignore */
582 +       if (len == ((tcph->doff + iph->ihl) * 4)) {
583 +               DEBUGP("packet has no data (may still be handshaking). [skip]\n");
584 +               return NF_ACCEPT;
585 +       }
586 +
587 +       /* Until there's been traffic both ways, don't look in packets. */
588 +       if (ctinfo != IP_CT_ESTABLISHED
589 +           && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
590 +               DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
591 +               DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
592 +               DEBUGP("packet is not yet part of a two way stream. [skip]\n");
593 +               return NF_ACCEPT;
594 +       }
595 +
596 +       /* Not whole TCP header? */
597 +       if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
598 +               DEBUGP("TCP header length is; tcplen=%u ..\n", (unsigned) tcplen);
599 +               DEBUGP("packet does not contain a complete TCP header. [skip]\n");
600 +               return NF_ACCEPT;
601 +       }
602 +
603 +       /* perform direction dependant protocol work */
604 +       if (dir == IP_CT_DIR_ORIGINAL) {
605 +
606 +               DEBUGP("packet is from the initiator. [cont]\n");
607 +
608 +               /* Tests if packet len is ok */
609 +               if ((tcplen - (tcph->doff * 4)) != 60) {
610 +                       DEBUGP("packet length is not correct. [skip]\n");
611 +                       return NF_ACCEPT;
612 +               }
613 +
614 +       } else {
615 +
616 +               DEBUGP("packet is from the receiver. [cont]\n");
617 +
618 +               /* Tests if packet len is ok */
619 +               if ((tcplen - (tcph->doff * 4)) != 32) {
620 +                       DEBUGP("packet length is not correct. [skip]\n");
621 +                       return NF_ACCEPT;
622 +               }
623 +       }
624 +
625 +       /* Get to the data */
626 +       data++;
627 +
628 +       /* Check the RPC data */
629 +       crp_ret = check_rpc_packet(data, dir, ct, request_p_list_tcp);
630 +
631 +       return crp_ret;
632 +
633 +}
634 +
635 +
636 +static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
637 +static char rpc_names[MAX_PORTS][10];
638 +
639 +static void fini(void);
640 +
641 +static int __init init(void)
642 +{
643 +       int port, ret;
644 +       char *tmpname;
645 +
646 +       /* If no port given, default to standard RPC port */
647 +       if (ports[0] == 0)
648 +               ports[0] = RPC_PORT;
649 +
650 +       for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
651 +               memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
652 +
653 +               tmpname = &rpc_names[port][0];
654 +               if (ports[port] == RPC_PORT)
655 +                       sprintf(tmpname, "rpc");
656 +               else
657 +                       sprintf(tmpname, "rpc-%d", ports[port]);
658 +               rpc_helpers[port].name = tmpname;
659 +
660 +               rpc_helpers[port].me = THIS_MODULE;
661 +               rpc_helpers[port].max_expected = 1;
662 +               rpc_helpers[port].timeout = 5 * 60; /* stes */
663 +
664 +               rpc_helpers[port].tuple.dst.protonum = IPPROTO_TCP;
665 +               rpc_helpers[port].mask.dst.protonum = 0xff;
666 +
667 +               /* RPC can come from ports 0:65535 to ports[port] (111) */
668 +               rpc_helpers[port].tuple.src.u.tcp.port = htons(ports[port]);
669 +               rpc_helpers[port].mask.src.u.tcp.port = htons(0xffff);
670 +               rpc_helpers[port].mask.dst.u.tcp.port = htons(0x0);
671 +
672 +               rpc_helpers[port].help = help;
673 +
674 +               PRINTK("registering helper for port #%d: %d/TCP\n", port, ports[port]);
675 +               PRINTK("helper match ip   %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
676 +                       NIPQUAD(rpc_helpers[port].tuple.dst.ip),
677 +                       ntohs(rpc_helpers[port].tuple.dst.u.tcp.port),
678 +                       NIPQUAD(rpc_helpers[port].tuple.src.ip),
679 +                       ntohs(rpc_helpers[port].tuple.src.u.tcp.port));
680 +               PRINTK("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
681 +                       NIPQUAD(rpc_helpers[port].mask.dst.ip),
682 +                       ntohs(rpc_helpers[port].mask.dst.u.tcp.port),
683 +                       NIPQUAD(rpc_helpers[port].mask.src.ip),
684 +                       ntohs(rpc_helpers[port].mask.src.u.tcp.port));
685 +
686 +               ret = ip_conntrack_helper_register(&rpc_helpers[port]);
687 +
688 +               if (ret) {
689 +                       printk("ERROR registering port %d\n",
690 +                               ports[port]);
691 +                       fini();
692 +                       return -EBUSY;
693 +               }
694 +               ports_n_c++;
695 +       }
696 +
697 +       PRINTK("%s Legato NetWorker support for port %d/TCP\n", (nsrexec)?"enabling":"disabling", nsrexec);
698 +
699 +       return 0;
700 +}
701 +
702 +
703 +/* This function is intentionally _NOT_ defined as __exit, because 
704 + * it is needed by the init function */
705 +static void fini(void)
706 +{
707 +       int port;
708 +
709 +       DEBUGP("cleaning request list\n");
710 +       clean_request(&request_p_list_tcp);
711 +
712 +       for (port = 0; (port < ports_n_c) && ports[port]; port++) {
713 +               DEBUGP("unregistering port %d\n", ports[port]);
714 +               ip_conntrack_helper_unregister(&rpc_helpers[port]);
715 +       }
716 +}
717 +
718 +
719 +module_init(init);
720 +module_exit(fini);
721 +
722 +struct module *ip_conntrack_rpc_tcp = THIS_MODULE;
723 +EXPORT_SYMBOL(request_p_list_tcp);
724 +EXPORT_SYMBOL(ip_conntrack_rpc_tcp);
725 +EXPORT_SYMBOL(ipct_rpc_tcp_lock);
726 +
727 diff -NurpP --minimal linux-2.6.19-pom-ng/net/ipv4/netfilter/ip_conntrack_rpc_udp.c linux-2.6.19/net/ipv4/netfilter/ip_conntrack_rpc_udp.c
728 --- linux-2.6.19-pom-ng/net/ipv4/netfilter/ip_conntrack_rpc_udp.c       1970-01-01 01:00:00.000000000 +0100
729 +++ linux-2.6.19/net/ipv4/netfilter/ip_conntrack_rpc_udp.c      2006-12-14 11:25:47.000000000 +0100
730 @@ -0,0 +1,527 @@
731 +/* RPC extension for IP (UDP) connection tracking, Version 2.2
732 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
733 + *     - original rpc tracking module
734 + *     - "recent" connection handling for kernel 2.3+ netfilter
735 + *
736 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
737 + *     - upgraded conntrack modules to oldnat api - kernel 2.4.0+
738 + *
739 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
740 + *     - upgraded conntrack modules to newnat api - kernel 2.4.20+
741 + *     - extended matching to support filtering on procedures
742 + * 
743 + * (c) 2004,2005 by David Stes <stes@pandora.be>
744 + *     - upgraded to 2.6.12+ conntrack module api
745 + *
746 + * (c) 2005 by David Stes <stes@pandora.be>
747 + *      - upgraded to 2.6.13 api
748 + *
749 + * ip_conntrack_rpc_udp.c,v 2.2 2003/01/12 18:30:00
750 + *
751 + *     This program is free software; you can redistribute it and/or
752 + *     modify it under the terms of the GNU General Public License
753 + *     as published by the Free Software Foundation; either version
754 + *     2 of the License, or (at your option) any later version.
755 + **
756 + *     Module load syntax:
757 + *     insmod ip_conntrack_rpc_udp.o ports=port1,port2,...port<MAX_PORTS>
758 + *
759 + *     Please give the ports of all RPC servers you wish to connect to.
760 + *     If you don't specify ports, the default will be port 111.
761 + **
762 + *     Note to all:
763 + *
764 + *     RPCs should not be exposed to the internet - ask the Pentagon;
765 + *
766 + *       "The unidentified crackers pleaded guilty in July to charges
767 + *        of juvenile delinquency stemming from a string of Pentagon
768 + *        network intrusions in February.
769 + *
770 + *        The youths, going by the names TooShort and Makaveli, used
771 + *        a common server security hole to break in, according to
772 + *        Dane Jasper, owner of the California Internet service
773 + *        provider, Sonic. They used the hole, known as the 'statd'
774 + *        exploit, to attempt more than 800 break-ins, Jasper said."
775 + *
776 + *     From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
777 + *     URL:  http://www.wired.com/news/politics/0,1283,16098,00.html
778 + **
779 + */
780 +
781 +#include <linux/module.h>
782 +#include <linux/netfilter.h>
783 +#include <linux/ip.h>
784 +#include <net/checksum.h>
785 +#include <net/udp.h>
786 +
787 +#include <asm/param.h>
788 +#include <linux/sched.h>
789 +#include <linux/timer.h>
790 +#include <linux/stddef.h>
791 +#include <linux/list.h>
792 +
793 +#include <linux/netfilter_ipv4/ip_tables.h>
794 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
795 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
796 +
797 +#define MAX_PORTS 8
798 +static int ports[MAX_PORTS];
799 +static int ports_n_c = 0;
800 +
801 +#ifdef MODULE_PARM
802 +module_param_array(ports, int, &ports_n_c, 0400);
803 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
804 +#endif
805 +
806 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
807 +MODULE_DESCRIPTION("RPC UDP connection tracking module");
808 +MODULE_LICENSE("GPL");
809 +
810 +#define PRINTK(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_udp: " \
811 +                                       format, ## args)
812 +
813 +#if 0
814 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_udp: " \
815 +                                       format, ## args)
816 +#else
817 +#define DEBUGP(format, args...)
818 +#endif
819 +
820 +DEFINE_RWLOCK(ipct_rpc_udp_lock);
821 +#define ASSERT_READ_LOCK(x) 
822 +#define ASSERT_WRITE_LOCK(x)
823 +#include <linux/netfilter_ipv4/listhelp.h>
824 +
825 +/* For future conections RPC, using client's cache bindings
826 + * I'll use ip_conntrack_lock to lock these lists           */
827 +
828 +LIST_HEAD(request_p_list_udp);
829 +
830 +
831 +static void delete_request_p(unsigned long request_p_ul)
832 +{
833 +       struct request_p *p = (void *)request_p_ul;
834 +       
835 +       write_lock_bh(&ipct_rpc_udp_lock);
836 +       LIST_DELETE(&request_p_list_udp, p);
837 +       write_unlock_bh(&ipct_rpc_udp_lock);
838 +       kfree(p);
839 +       return;
840 +}
841 +
842 +
843 +static void req_cl(struct request_p * r)
844 +{
845 +       write_lock_bh(&ipct_rpc_udp_lock);
846 +       del_timer(&r->timeout);
847 +       LIST_DELETE(&request_p_list_udp, r);
848 +       write_unlock_bh(&ipct_rpc_udp_lock);
849 +       kfree(r);
850 +       return;
851 +}
852 +
853 +
854 +static void clean_request(struct list_head *list)
855 +{
856 +       struct list_head *first = list->prev;
857 +       struct list_head *temp = list->next;
858 +       struct list_head *aux;
859 +
860 +       if (list_empty(list))
861 +               return;
862 +
863 +       while (first != temp) {
864 +               aux = temp->next;
865 +               req_cl((struct request_p *)temp);
866 +               temp = aux;     
867 +       }
868 +       req_cl((struct request_p *)temp);
869 +       return;
870 +}
871 +
872 +
873 +static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
874 +                    u_int16_t port)
875 +{
876 +       struct request_p *req_p;
877 +        
878 +       /* Verifies if entry already exists */
879 +       write_lock_bh(&ipct_rpc_udp_lock);
880 +       req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
881 +               struct request_p *, xid, ip, port);
882 +
883 +       if (req_p) {
884 +               /* Refresh timeout */
885 +               if (del_timer(&req_p->timeout)) {
886 +                       req_p->timeout.expires = jiffies + EXP;
887 +                       add_timer(&req_p->timeout);     
888 +               } 
889 +               write_unlock_bh(&ipct_rpc_udp_lock);
890 +               return; 
891 +
892 +       }
893 +       write_unlock_bh(&ipct_rpc_udp_lock);
894 +       
895 +       /* Allocate new request_p */
896 +       req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
897 +       if (!req_p) {
898 +               DEBUGP("can't allocate request_p\n");
899 +               return;                 
900 +       }
901 +
902 +        req_p->list.next = NULL;
903 +        req_p->list.prev = NULL;
904 +        req_p->xid = xid;
905 +        req_p->ip = ip;
906 +        req_p->port = port;
907 +        req_p->proto = proto;
908 +      
909 +       /* Initialize timer */
910 +       init_timer(&req_p->timeout);
911 +        req_p->timeout.expires = jiffies + EXP;
912 +       req_p->timeout.data = (unsigned long)req_p;
913 +       req_p->timeout.function = delete_request_p;
914 +       add_timer(&req_p->timeout); 
915 +
916 +       /* Put in list */
917 +       write_lock_bh(&ipct_rpc_udp_lock);
918 +       list_prepend(&request_p_list_udp, req_p);
919 +       write_unlock_bh(&ipct_rpc_udp_lock); 
920 +       return; 
921 +
922 +}
923 +
924 +
925 +static int check_rpc_packet(const u_int32_t *data,
926 +                       int dir, struct ip_conntrack *ct,
927 +                       struct list_head request_p_list)
928 +{
929 +        int ret = NF_ACCEPT;
930 +       u_int32_t xid;
931 +       struct request_p *req_p;
932 +       struct ip_conntrack_expect *exp;
933 +
934 +       /* Translstion's buffer for XDR */
935 +       u_int16_t port_buf;
936 +
937 +
938 +       /* Get XID */
939 +       xid = *data;
940 +
941 +       /* This does sanity checking on RPC payloads,
942 +        * and permits only the RPC "get port" (3)
943 +        * in authorised procedures in client
944 +        * communications with the portmapper.
945 +        */
946 +
947 +       /* perform direction dependant RPC work */
948 +       if (dir == IP_CT_DIR_ORIGINAL) {
949 +
950 +               data += 5;
951 +
952 +               /* Get RPC requestor */
953 +               if (IXDR_GET_INT32(data) != 3) {
954 +                       DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
955 +                       return NF_ACCEPT;
956 +               }
957 +               DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
958 +
959 +               data++;
960 +
961 +               /* Jump Credentials and Verfifier */
962 +               data = data + IXDR_GET_INT32(data) + 2;
963 +               data = data + IXDR_GET_INT32(data) + 2;
964 +
965 +               /* Get RPC procedure */
966 +               DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
967 +                       (unsigned int)IXDR_GET_INT32(data));
968 +
969 +               /* Get RPC protocol and store against client parameters */
970 +               data = data + 2;
971 +               alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
972 +                               ct->tuplehash[dir].tuple.src.u.all);
973 +
974 +               DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
975 +                       xid, IXDR_GET_INT32(data),
976 +                       NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
977 +                       ntohs(ct->tuplehash[dir].tuple.src.u.all));
978 +
979 +               DEBUGP("allocated RPC request for protocol %u. [done]\n",
980 +                       (unsigned int)IXDR_GET_INT32(data));
981 +
982 +       } else {
983 +
984 +               /* Check for returning packet's stored counterpart */
985 +               req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
986 +                                 struct request_p *, xid,
987 +                                 ct->tuplehash[!dir].tuple.src.ip,
988 +                                 ct->tuplehash[!dir].tuple.src.u.all);
989 +
990 +               /* Drop unexpected packets */
991 +               if (!req_p) {
992 +                       DEBUGP("packet is not expected. [skip]\n");
993 +                       return NF_ACCEPT;
994 +               }
995 +
996 +               /* Verifies if packet is really an RPC reply packet */
997 +               data++;
998 +               if (IXDR_GET_INT32(data) != 1) {
999 +                       DEBUGP("packet is not a valid RPC reply. [skip]\n");
1000 +                       return NF_ACCEPT;
1001 +               }
1002 +
1003 +               /* Is status accept? */
1004 +               data++;
1005 +               if (IXDR_GET_INT32(data)) {
1006 +                       DEBUGP("packet is not an RPC accept. [skip]\n");
1007 +                       return NF_ACCEPT;
1008 +               }
1009 +
1010 +               /* Get Verifier length. Jump verifier */
1011 +               data++;
1012 +               data = data + IXDR_GET_INT32(data) + 2;
1013 +
1014 +               /* Is accpet status "success"? */
1015 +               if (IXDR_GET_INT32(data)) {
1016 +                       DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1017 +                       return NF_ACCEPT;
1018 +               }
1019 +
1020 +               /* Get server port number */      
1021 +               data++;
1022 +               port_buf = (u_int16_t) IXDR_GET_INT32(data);
1023 +
1024 +               /* If a packet has made it this far then it deserves an
1025 +                * expectation ...  if port == 0, then this service is 
1026 +                * not going to be registered.
1027 +                */
1028 +               if (port_buf) {
1029 +                       DEBUGP("port found: %u\n", port_buf);
1030 +
1031 +                        exp = ip_conntrack_expect_alloc(ct);
1032 +                        if (!exp) {
1033 +                          ret = NF_DROP;
1034 +                          goto out;
1035 +                        }
1036 +
1037 +                       /* Watch out, Radioactive-Man! */
1038 +                       exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1039 +                       exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1040 +                       exp->mask.src.ip = 0xffffffff;
1041 +                       exp->mask.dst.ip = 0xffffffff;
1042 +
1043 +                       switch (req_p->proto) {
1044 +                               case IPPROTO_UDP:
1045 +                                       exp->tuple.src.u.udp.port = 0;
1046 +                                       exp->tuple.dst.u.udp.port = htons(port_buf);
1047 +                                       exp->tuple.dst.protonum = IPPROTO_UDP;
1048 +                                       exp->mask.src.u.udp.port = 0;
1049 +                                       exp->mask.dst.u.udp.port = htons(0xffff);
1050 +                                       exp->mask.dst.protonum = 0xff;
1051 +                                       break;
1052 +
1053 +                               case IPPROTO_TCP:
1054 +                                       exp->tuple.src.u.tcp.port = 0;
1055 +                                       exp->tuple.dst.u.tcp.port = htons(port_buf);
1056 +                                       exp->tuple.dst.protonum = IPPROTO_TCP;
1057 +                                       exp->mask.src.u.tcp.port = 0;
1058 +                                       exp->mask.dst.u.tcp.port = htons(0xffff);
1059 +                                       exp->mask.dst.protonum = 0xff;
1060 +                                       break;
1061 +                       }
1062 +                       exp->expectfn = NULL;
1063 +                       exp->master = ct;
1064 +
1065 +                       DEBUGP("expect related ip   %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1066 +                               NIPQUAD(exp->tuple.src.ip),
1067 +                               NIPQUAD(exp->tuple.dst.ip),
1068 +                               port_buf, req_p->proto);
1069 +
1070 +                       DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1071 +                               NIPQUAD(exp->mask.src.ip),
1072 +                               NIPQUAD(exp->mask.dst.ip),
1073 +                               exp->mask.dst.protonum);
1074 +
1075 +                       if (ip_conntrack_expect_related(exp) != 0) {
1076 +                               ret = NF_DROP;
1077 +                       }
1078 +               }
1079 +
1080 +out:
1081 +               req_cl(req_p);
1082 +
1083 +               DEBUGP("packet evaluated. [expect]\n");
1084 +       }
1085 +
1086 +       return ret;
1087 +}
1088 +
1089 +
1090 +/* RPC UDP helper */
1091 +/* static int help(const struct iphdr *iph, size_t len,
1092 +               struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) */
1093 +static int help(struct sk_buff **pskb,
1094 +               struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1095 +{
1096 +       int dir;
1097 +       int crp_ret;
1098 +       struct udphdr _udph, *udph;
1099 +       const u_int32_t *data;
1100 +       size_t udplen;
1101 +        struct iphdr *iph;
1102 +        size_t len;
1103 +       const u_int16_t *chsm;
1104 +
1105 +       /* Not whole UDP header? */
1106 +        iph=(*pskb)->nh.iph;
1107 +       udph = skb_header_pointer(*pskb,iph->ihl*4,sizeof(_udph),&_udph);
1108 +       if (!udph)
1109 +               return NF_ACCEPT;
1110 +
1111 +       len = (*pskb)->len; /* stes */
1112 +       data = (const u_int32_t *)udph + 2;
1113 +        udplen = len - iph->ihl * 4;
1114 +       dir = CTINFO2DIR(ctinfo);
1115 +
1116 +       /* Checksum */
1117 +        chsm = (const u_int16_t *)udph + 3;
1118 +
1119 +       DEBUGP("new packet to evaluate ..\n");
1120 +
1121 +       /* Not whole UDP header? */
1122 +       if (udplen < sizeof(struct udphdr)) {
1123 +               DEBUGP("UDP header length is; udplen=%u ..\n", (unsigned) udplen);
1124 +               DEBUGP("packet does not contain a complete UDP header. [skip]\n");
1125 +               return NF_ACCEPT;
1126 +       }
1127 +
1128 +       /* perform direction dependant protocol work */
1129 +       if (dir == IP_CT_DIR_ORIGINAL) {
1130 +
1131 +               DEBUGP("packet is from the initiator. [cont]\n");
1132 +
1133 +               /* Tests if packet len is ok */
1134 +               if ((udplen - sizeof(struct udphdr)) != 56) {
1135 +                       DEBUGP("packet length is not correct. [skip]\n");
1136 +                       return NF_ACCEPT;
1137 +               }
1138 +
1139 +       } else {
1140 +
1141 +               DEBUGP("packet is from the receiver. [cont]\n");
1142 +
1143 +               /* Until there's been traffic both ways, don't look in packets. */
1144 +               if (ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1145 +                       DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1146 +                       DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1147 +                       DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1148 +                       return NF_ACCEPT;
1149 +               }
1150 +
1151 +               /* Tests if packet len is ok */
1152 +                       if ((udplen - sizeof(struct udphdr)) != 28) {
1153 +                       DEBUGP("packet length is not correct. [skip]\n");
1154 +                       return NF_ACCEPT;
1155 +               }
1156 +
1157 +       }
1158 +
1159 +       /* Get to the data */
1160 +       /* udp *data == *correct */
1161 +
1162 +       /* Check the RPC data */
1163 +       crp_ret = check_rpc_packet(data, dir, ct, request_p_list_udp);
1164 +
1165 +       return crp_ret;
1166 +
1167 +}
1168 +
1169 +
1170 +static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1171 +static char rpc_names[MAX_PORTS][10];
1172 +
1173 +static void fini(void);
1174 +
1175 +static int __init init(void)
1176 +{
1177 +       int port, ret;
1178 +       char *tmpname;
1179 +
1180 +       /* If no port given, default to standard RPC port */
1181 +       if (ports[0] == 0)
1182 +               ports[0] = RPC_PORT;
1183 +
1184 +       for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1185 +               memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1186 +
1187 +               tmpname = &rpc_names[port][0];
1188 +               if (ports[port] == RPC_PORT)
1189 +                       sprintf(tmpname, "rpc");
1190 +               else
1191 +                       sprintf(tmpname, "rpc-%d", ports[port]);
1192 +               rpc_helpers[port].name = tmpname;
1193 +
1194 +               rpc_helpers[port].me = THIS_MODULE;
1195 +               rpc_helpers[port].max_expected = 1;
1196 +               rpc_helpers[port].timeout = 5 * 60; /* stes */
1197 +
1198 +               rpc_helpers[port].tuple.dst.protonum = IPPROTO_UDP;
1199 +               rpc_helpers[port].mask.dst.protonum = 0xff;
1200 +
1201 +               /* RPC can come from ports 0:65535 to ports[port] (111) */
1202 +               rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1203 +               rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1204 +               rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1205 +
1206 +               rpc_helpers[port].help = help;
1207 +
1208 +               PRINTK("registering helper for port #%d: %d/UDP\n", port, ports[port]);
1209 +               PRINTK("helper match ip   %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1210 +                       NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1211 +                       ntohs(rpc_helpers[port].tuple.dst.u.udp.port),
1212 +                       NIPQUAD(rpc_helpers[port].tuple.src.ip),
1213 +                       ntohs(rpc_helpers[port].tuple.src.u.udp.port));
1214 +               PRINTK("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1215 +                       NIPQUAD(rpc_helpers[port].mask.dst.ip),
1216 +                       ntohs(rpc_helpers[port].mask.dst.u.udp.port),
1217 +                       NIPQUAD(rpc_helpers[port].mask.src.ip),
1218 +                       ntohs(rpc_helpers[port].mask.src.u.udp.port));
1219 +
1220 +               ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1221 +
1222 +               if (ret) {
1223 +                       printk("ERROR registering port %d\n",
1224 +                               ports[port]);
1225 +                       fini();
1226 +                       return -EBUSY;
1227 +               }
1228 +               ports_n_c++;
1229 +       }
1230 +       return 0;
1231 +}
1232 +
1233 +
1234 +/* This function is intentionally _NOT_ defined as __exit, because 
1235 + * it is needed by the init function */
1236 +static void fini(void)
1237 +{
1238 +       int port;
1239 +
1240 +       DEBUGP("cleaning request list\n");
1241 +       clean_request(&request_p_list_udp);
1242 +
1243 +       for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1244 +               DEBUGP("unregistering port %d\n", ports[port]);
1245 +               ip_conntrack_helper_unregister(&rpc_helpers[port]);
1246 +       }
1247 +}
1248 +
1249 +
1250 +module_init(init);
1251 +module_exit(fini);
1252 +
1253 +struct module *ip_conntrack_rpc_udp = THIS_MODULE;
1254 +EXPORT_SYMBOL(request_p_list_udp);
1255 +EXPORT_SYMBOL(ip_conntrack_rpc_udp);
1256 +EXPORT_SYMBOL(ipct_rpc_udp_lock);
1257 +
1258 diff -NurpP --minimal linux-2.6.19-pom-ng/net/ipv4/netfilter/ipt_rpc.c linux-2.6.19/net/ipv4/netfilter/ipt_rpc.c
1259 --- linux-2.6.19-pom-ng/net/ipv4/netfilter/ipt_rpc.c    1970-01-01 01:00:00.000000000 +0100
1260 +++ linux-2.6.19/net/ipv4/netfilter/ipt_rpc.c   2006-12-14 11:25:47.000000000 +0100
1261 @@ -0,0 +1,443 @@
1262 +/* RPC extension for IP connection matching, Version 2.2
1263 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
1264 + *     - original rpc tracking module
1265 + *     - "recent" connection handling for kernel 2.3+ netfilter
1266 + *
1267 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
1268 + *     - upgraded conntrack modules to oldnat api - kernel 2.4.0+
1269 + *
1270 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
1271 + *     - upgraded conntrack modules to newnat api - kernel 2.4.20+
1272 + *     - extended matching to support filtering on procedures
1273 + * 
1274 + * (c) 2004,2005 by David Stes <stes@pandora.be>
1275 + *     - upgraded to 2.6.12+ conntrack module api
1276 + *      - upgraded to 2.6.13 api
1277 + *
1278 + * ipt_rpc.c,v 2.2 2003/01/12 18:30:00
1279 + *
1280 + *     This program is free software; you can redistribute it and/or
1281 + *     modify it under the terms of the GNU General Public License
1282 + *     as published by the Free Software Foundation; either version
1283 + *     2 of the License, or (at your option) any later version.
1284 + **
1285 + *     Module load syntax:
1286 + *     insmod ipt_rpc.o ports=port1,port2,...port<MAX_PORTS>
1287 + *
1288 + *     Please give the ports of all RPC servers you wish to connect to.
1289 + *     If you don't specify ports, the default will be port 111.
1290 + **
1291 + *     Note to all:
1292 + *
1293 + *     RPCs should not be exposed to the internet - ask the Pentagon;
1294 + *
1295 + *       "The unidentified crackers pleaded guilty in July to charges
1296 + *        of juvenile delinquency stemming from a string of Pentagon
1297 + *        network intrusions in February.
1298 + *
1299 + *        The youths, going by the names TooShort and Makaveli, used
1300 + *        a common server security hole to break in, according to
1301 + *        Dane Jasper, owner of the California Internet service
1302 + *        provider, Sonic. They used the hole, known as the 'statd'
1303 + *        exploit, to attempt more than 800 break-ins, Jasper said."
1304 + *
1305 + *     From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
1306 + *     URL:  http://www.wired.com/news/politics/0,1283,16098,00.html
1307 + **
1308 + */
1309 +
1310 +#include <linux/module.h>
1311 +#include <linux/skbuff.h>
1312 +#include <linux/list.h>
1313 +#include <linux/udp.h>
1314 +#include <linux/tcp.h>
1315 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1316 +#include <linux/netfilter_ipv4/ip_tables.h>
1317 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
1318 +#include <linux/netfilter_ipv4/ipt_rpc.h>
1319 +
1320 +#define MAX_PORTS 8
1321 +static int ports[MAX_PORTS];
1322 +static int ports_n_c = 0;
1323 +
1324 +#ifdef MODULE_PARM
1325 +module_param_array(ports, int, &ports_n_c, 0400);
1326 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
1327 +#endif
1328 +
1329 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
1330 +MODULE_DESCRIPTION("RPC connection matching module");
1331 +MODULE_LICENSE("GPL");
1332 +
1333 +#define PRINTK(format, args...) printk(KERN_DEBUG "ipt_rpc: " \
1334 +                                       format, ## args)
1335 +
1336 +#if 0
1337 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ipt_rpc: " \
1338 +                                       format, ## args)
1339 +#else
1340 +#define DEBUGP(format, args...)
1341 +#endif
1342 +
1343 +/* EXPORT_NO_SYMBOLS; */
1344 +
1345 +/* vars from ip_conntrack_rpc_tcp */
1346 +extern struct list_head request_p_list_tcp;
1347 +extern struct module *ip_conntrack_rpc_tcp;
1348 +
1349 +/* vars from ip_conntrack_rpc_udp */
1350 +extern struct list_head request_p_list_udp;
1351 +extern struct module *ip_conntrack_rpc_udp;
1352 +
1353 +extern rwlock_t ipct_rpc_tcp_lock;
1354 +extern rwlock_t ipct_rpc_udp_lock;
1355 +
1356 +#define ASSERT_READ_LOCK(x)
1357 +#define ASSERT_WRITE_LOCK(x)
1358 +
1359 +#if 0
1360 +#define ASSERT_READ_LOCK(x)                                    \
1361 +do {                                                           \
1362 +       if (x == &request_p_list_udp)                           \
1363 +               MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock);        \
1364 +       else if (x == &request_p_list_tcp)                      \
1365 +               MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock);        \
1366 +} while (0)
1367 +
1368 +#define ASSERT_WRITE_LOCK(x)                                   \
1369 +do {                                                           \
1370 +       if (x == &request_p_list_udp)                           \
1371 +               MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock);       \
1372 +       else if (x == &request_p_list_tcp)                      \
1373 +               MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock);       \
1374 +} while (0)
1375 +#endif
1376 +
1377 +#include <linux/netfilter_ipv4/listhelp.h>
1378 +
1379 +const int IPT_RPC_CHAR_LEN = 11;
1380 +
1381 +static int k_atoi(char *string)
1382 +{
1383 +       unsigned int result = 0;
1384 +       int maxoctet = IPT_RPC_CHAR_LEN;
1385 +
1386 +       for ( ; *string != 0 && maxoctet != 0; maxoctet--, string++) {
1387 +               if (*string < 0)
1388 +                       return(0);
1389 +               if (*string == 0)
1390 +                       break;
1391 +               if (*string < 48 || *string > 57) {
1392 +                       return(0);
1393 +               }
1394 +               result = result * 10 + ( *string - 48 );
1395 +       }
1396 +       return(result);
1397 +}
1398 +
1399 +
1400 +static int match_rpcs(char *c_procs, int i_procs, int proc)
1401 +{
1402 +       int   proc_ctr;
1403 +       char *proc_ptr;
1404 +       unsigned int proc_num;
1405 +
1406 +       DEBUGP("entered match_rpcs [%i] [%i] ..\n", i_procs, proc);
1407 +
1408 +       if (i_procs == -1)
1409 +               return 1;
1410 +
1411 +       for (proc_ctr=0; proc_ctr <= i_procs; proc_ctr++) {
1412 +
1413 +               proc_ptr = c_procs;
1414 +               proc_ptr += proc_ctr * IPT_RPC_CHAR_LEN;
1415 +               proc_num = k_atoi(proc_ptr);
1416 +
1417 +               if (proc_num == proc)
1418 +                       return 1;
1419 +       }
1420 +
1421 +       return 0;
1422 +}
1423 +
1424 +
1425 +static int check_rpc_packet(const u_int32_t *data, const void *matchinfo,
1426 +                       int *hotdrop, int dir, struct ip_conntrack *ct,
1427 +                       int offset, struct list_head request_p_list)
1428 +{
1429 +       const struct ipt_rpc_info *rpcinfo = matchinfo;
1430 +       struct request_p *req_p;
1431 +       u_int32_t xid;
1432 +
1433 +
1434 +       /* Get XID */
1435 +       xid = *data;
1436 +
1437 +       /* This does sanity checking on RPC payloads,
1438 +        * and permits only the RPC "get port" (3)
1439 +        * in authorised procedures in client
1440 +        * communications with the portmapper.
1441 +        */
1442 +
1443 +       data += 5;
1444 +
1445 +       /* Get RPC requestor */
1446 +       if (IXDR_GET_INT32(data) != 3) {
1447 +               DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1448 +               if(rpcinfo->strict == 1)
1449 +                       *hotdrop = 1;
1450 +               return 0;
1451 +       }
1452 +       DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1453 +
1454 +       data++;
1455 +
1456 +       /* Jump Credentials and Verfifier */
1457 +       data = data + IXDR_GET_INT32(data) + 2;
1458 +       data = data + IXDR_GET_INT32(data) + 2;
1459 +
1460 +       /* Get RPC procedure */
1461 +       if (match_rpcs((char *)&rpcinfo->c_procs,
1462 +           rpcinfo->i_procs, IXDR_GET_INT32(data)) == 0) {
1463 +               DEBUGP("RPC packet contains illegal procedure request [%u]. [drop]\n",
1464 +                       (unsigned int)IXDR_GET_INT32(data));
1465 +
1466 +               /* If the RPC conntrack half entry already exists .. */
1467 +
1468 +               switch (ct->tuplehash[0].tuple.dst.protonum) {
1469 +                       case IPPROTO_UDP:
1470 +                               write_lock_bh(&ipct_rpc_udp_lock);
1471 +                       case IPPROTO_TCP:
1472 +                               write_lock_bh(&ipct_rpc_tcp_lock);
1473 +               }
1474 +               req_p = LIST_FIND(&request_p_list, request_p_cmp,
1475 +                                 struct request_p *, xid,
1476 +                                 ct->tuplehash[dir].tuple.src.ip,
1477 +                                 ct->tuplehash[dir].tuple.src.u.all);
1478 +
1479 +               if (req_p) {
1480 +                       DEBUGP("found req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1481 +                               xid, ct->tuplehash[dir].tuple.dst.protonum,
1482 +                               NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1483 +                               ntohs(ct->tuplehash[dir].tuple.src.u.all));
1484 +
1485 +                       /* .. remove it */
1486 +                       if (del_timer(&req_p->timeout))
1487 +                               req_p->timeout.expires = 0;
1488 +
1489 +                               LIST_DELETE(&request_p_list, req_p);
1490 +                       DEBUGP("RPC req_p removed. [done]\n");
1491 +
1492 +               } else {
1493 +                       DEBUGP("no req_p found for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1494 +                               xid, ct->tuplehash[dir].tuple.dst.protonum,
1495 +                               NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1496 +                               ntohs(ct->tuplehash[dir].tuple.src.u.all));
1497 +
1498 +               }
1499 +               switch (ct->tuplehash[0].tuple.dst.protonum) {
1500 +                       case IPPROTO_UDP:
1501 +                               write_unlock_bh(&ipct_rpc_udp_lock);
1502 +                       case IPPROTO_TCP:
1503 +                               write_unlock_bh(&ipct_rpc_tcp_lock);
1504 +               }
1505 +
1506 +               if(rpcinfo->strict == 1)
1507 +                       *hotdrop = 1;
1508 +               return 0;
1509 +       }
1510 +
1511 +       DEBUGP("RPC packet contains authorised procedure request [%u]. [match]\n",
1512 +               (unsigned int)IXDR_GET_INT32(data));
1513 +       return (1 && (!offset));
1514 +}
1515 +
1516 +
1517 +
1518 +/* static int match(const struct sk_buff *skb, const struct net_device *in,
1519 +                const struct net_device *out, const void *matchinfo,
1520 +                int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
1521 +*/
1522 +static int match(const struct sk_buff *skb, const struct net_device *in,
1523 +                const struct net_device *out, const void *matchinfo,
1524 +                int offset, int *hotdrop)
1525 +{
1526 +       struct ip_conntrack *ct;
1527 +       enum ip_conntrack_info ctinfo;
1528 +       const u_int32_t *data;
1529 +       enum ip_conntrack_dir dir;
1530 +       const struct tcphdr *tcp;
1531 +       const struct ipt_rpc_info *rpcinfo = matchinfo;
1532 +       int port, portsok;
1533 +       int tval;
1534 +       struct iphdr *ip; /* stes */
1535 +        void *hdr; /* stes */
1536 +        u_int16_t datalen; /* stes */
1537 +
1538 +       /* Initialization stes - see 2.4 ip_tables.c ipt_do_table() */
1539 +       ip = skb->nh.iph;
1540 +       hdr = (u_int32_t *)ip + ip->ihl;
1541 +       datalen = skb->len - ip->ihl * 4;
1542 +
1543 +       DEBUGP("new packet to evaluate ..\n");
1544 +
1545 +       ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
1546 +       if (!ct) {
1547 +               DEBUGP("no ct available [skip]\n");
1548 +               return 0;
1549 +       }
1550 +
1551 +       DEBUGP("ct detected. [cont]\n");
1552 +       dir = CTINFO2DIR(ctinfo);
1553 +
1554 +       /* we only want the client to server packets for matching */
1555 +       if (dir != IP_CT_DIR_ORIGINAL)
1556 +               return 0;
1557 +
1558 +       /* This does sanity checking on UDP or TCP packets,
1559 +        * like their respective modules.
1560 +        */
1561 +
1562 +       switch (ct->tuplehash[0].tuple.dst.protonum) {
1563 +
1564 +               case IPPROTO_UDP:
1565 +                       DEBUGP("PROTO_UDP [cont]\n");
1566 +                       if (offset == 0 && datalen < sizeof(struct udphdr)) {
1567 +                               DEBUGP("packet does not contain a complete header. [drop]\n");
1568 +                               return 0;
1569 +                       }
1570 +
1571 +                       for (port=0,portsok=0; port <= ports_n_c; port++) {
1572 +                               if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
1573 +                                       portsok++;
1574 +                                       break;
1575 +                               }
1576 +                       }
1577 +                       if (portsok == 0) {
1578 +                               DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
1579 +                                       ntohs(ct->tuplehash[dir].tuple.dst.u.all));
1580 +                               return 0;
1581 +                       }
1582 +
1583 +                       if ((datalen - sizeof(struct udphdr)) != 56) {
1584 +                               DEBUGP("packet length is not correct for RPC content. [skip]\n");
1585 +                               if (rpcinfo->strict == 1)
1586 +                                       *hotdrop = 1;
1587 +                               return 0;
1588 +                       }
1589 +                       DEBUGP("packet length is correct. [cont]\n");
1590 +
1591 +                       /* Get to the data */
1592 +                       data = (const u_int32_t *)hdr + 2;
1593 +
1594 +                       /* Check the RPC data */
1595 +                       tval = check_rpc_packet(data, matchinfo, hotdrop,
1596 +                                               dir, ct, offset,
1597 +                                               request_p_list_udp);
1598 +
1599 +                       return tval;
1600 +                       
1601 +               
1602 +               case IPPROTO_TCP:
1603 +                       DEBUGP("PROTO_TCP [cont]\n");
1604 +                       if (offset == 0 && datalen < sizeof(struct tcphdr)) {
1605 +                               DEBUGP("packet does not contain a complete header. [drop]\n");
1606 +                               return 0;
1607 +                       }
1608 +       
1609 +                       for (port=0,portsok=0; port <= ports_n_c; port++) {
1610 +                               if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
1611 +                                       portsok++;
1612 +                                       break;
1613 +                               }
1614 +                       }
1615 +                       if (portsok == 0) {
1616 +                               DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
1617 +                                       ntohs(ct->tuplehash[dir].tuple.dst.u.all));
1618 +                               return 0;
1619 +                       }
1620 +
1621 +                       tcp = hdr;
1622 +                       if (datalen == (tcp->doff * 4)) {
1623 +                               DEBUGP("packet does not contain any data. [match]\n");
1624 +                               return (1 && (!offset));
1625 +                       }
1626 +
1627 +                       /* Tests if packet len is ok */
1628 +                       if ((datalen - (tcp->doff * 4)) != 60) {
1629 +                               DEBUGP("packet length is not correct for RPC content. [skip]\n");
1630 +                               if(rpcinfo->strict == 1)
1631 +                                       *hotdrop = 1;
1632 +                               return 0;
1633 +                       }
1634 +                       DEBUGP("packet length is correct. [cont]\n");
1635 +
1636 +                       /* Get to the data */
1637 +                       data = (const u_int32_t *)tcp + tcp->doff + 1;  
1638 +
1639 +                       /* Check the RPC data */
1640 +                       tval = check_rpc_packet(data, matchinfo, hotdrop,
1641 +                                               dir, ct, offset,
1642 +                                               request_p_list_tcp);
1643 +
1644 +                       return tval;
1645 +
1646 +       }
1647 +
1648 +       DEBUGP("transport protocol=%u, is not supported [skip]\n",
1649 +               ct->tuplehash[0].tuple.dst.protonum);
1650 +       return 0;
1651 +}
1652 +
1653 +
1654 +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo,
1655 +                  unsigned int matchsize, unsigned int hook_mask)
1656 +{
1657 +       if (hook_mask
1658 +           & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING)
1659 +               | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_LOCAL_OUT))) {
1660 +               printk("ipt_rpc: only valid for PRE_ROUTING, FORWARD, POST_ROUTING, LOCAL_IN and/or LOCAL_OUT targets.\n");
1661 +               return 0;
1662 +       }
1663 +
1664 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_rpc_info)))
1665 +               return 0;
1666 +
1667 +       return 1;
1668 +}
1669 +
1670 +static struct ipt_match rpc_match = {
1671 +        .name           = "rpc",
1672 +        .match          = &match,
1673 +        .checkentry     = &checkentry,
1674 +        .me             = THIS_MODULE,
1675 +};
1676 +
1677 +static int __init init(void)
1678 +{
1679 +       int port;
1680 +
1681 +       /* If no port given, default to standard RPC port */
1682 +       if (ports[0] == 0)
1683 +               ports[0] = RPC_PORT;
1684 +
1685 +       PRINTK("registering match [%s] for;\n", rpc_match.name);
1686 +       for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1687 +               PRINTK("  port %i (UDP|TCP);\n", ports[port]);
1688 +               ports_n_c++;
1689 +       }
1690 +       
1691 +       return ipt_register_match(&rpc_match);
1692 +}
1693 +
1694 +
1695 +static void fini(void)
1696 +{
1697 +       DEBUGP("unregistering match\n");
1698 +       ipt_unregister_match(&rpc_match);
1699 +}
1700 +
1701 +
1702 +module_init(init);
1703 +module_exit(fini);
1704 +
This page took 0.163026 seconds and 3 git commands to generate.