1 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_helpers.h linux-2.6.5-rc1/include/linux/netfilter_helpers.h
2 --- linux-2.6.5-rc1.org/include/linux/netfilter_helpers.h 1970-01-01 00:00:00.000000000 +0000
3 +++ linux-2.6.5-rc1/include/linux/netfilter_helpers.h 2004-03-16 12:04:49.000000000 +0000
6 + * Helpers for netfiler modules. This file provides implementations for basic
7 + * functions such as strncasecmp(), etc.
9 + * gcc will warn for defined but unused functions, so we only include the
10 + * functions requested. The following macros are used:
11 + * NF_NEED_STRNCASECMP nf_strncasecmp()
12 + * NF_NEED_STRTOU16 nf_strtou16()
13 + * NF_NEED_STRTOU32 nf_strtou32()
15 +#ifndef _NETFILTER_HELPERS_H
16 +#define _NETFILTER_HELPERS_H
18 +/* Only include these functions for kernel code. */
21 +#include <linux/ctype.h>
22 +#define iseol(c) ( (c) == '\r' || (c) == '\n' )
25 + * The standard strncasecmp()
27 +#ifdef NF_NEED_STRNCASECMP
29 +nf_strncasecmp(const char* s1, const char* s2, u_int32_t len)
31 + if (s1 == NULL || s2 == NULL)
33 + if (s1 == NULL && s2 == NULL)
37 + return (s1 == NULL) ? -1 : 1;
39 + while (len > 0 && tolower(*s1) == tolower(*s2))
45 + return ( (len == 0) ? 0 : (tolower(*s1) - tolower(*s2)) );
47 +#endif /* NF_NEED_STRNCASECMP */
50 + * Parse a string containing a 16-bit unsigned integer.
51 + * Returns the number of chars used, or zero if no number is found.
53 +#ifdef NF_NEED_STRTOU16
55 +nf_strtou16(const char* pbuf, u_int16_t* pval)
60 + while (isdigit(pbuf[n]))
62 + *pval = (*pval * 10) + (pbuf[n] - '0');
68 +#endif /* NF_NEED_STRTOU16 */
71 + * Parse a string containing a 32-bit unsigned integer.
72 + * Returns the number of chars used, or zero if no number is found.
74 +#ifdef NF_NEED_STRTOU32
76 +nf_strtou32(const char* pbuf, u_int32_t* pval)
81 + while (pbuf[n] >= '0' && pbuf[n] <= '9')
83 + *pval = (*pval * 10) + (pbuf[n] - '0');
89 +#endif /* NF_NEED_STRTOU32 */
92 + * Given a buffer and length, advance to the next line and mark the current
95 +#ifdef NF_NEED_NEXTLINE
97 +nf_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
107 + while (p[off] != '\n')
118 + /* if we saw a crlf, physlen needs adjusted */
119 + if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
124 + /* advance past the newline */
128 + *plinelen = physlen;
133 +#endif /* NF_NEED_NEXTLINE */
135 +#endif /* __KERNEL__ */
137 +#endif /* _NETFILTER_HELPERS_H */
138 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
139 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 12:00:23.000000000 +0000
140 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 12:04:49.000000000 +0000
144 /* Add protocol helper include file here */
145 +#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
146 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
147 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
148 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
150 /* per expectation: application helper private data */
151 union ip_conntrack_expect_help {
152 /* insert conntrack helper private data (expect) here */
153 + struct ip_ct_rtsp_expect exp_rtsp_info;
154 + struct ip_ct_rtsp_master ct_rtsp_info;
155 struct ip_ct_amanda_expect exp_amanda_info;
156 struct ip_ct_ftp_expect exp_ftp_info;
157 struct ip_ct_irc_expect exp_irc_info;
160 #endif /* CONFIG_IP_NF_NAT_NEEDED */
162 +#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
163 + unsigned long mark;
168 /* get master conntrack via master expectation */
169 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rpc.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rpc.h
170 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 1970-01-01 00:00:00.000000000 +0000
171 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 2004-03-16 12:04:46.000000000 +0000
173 +/* RPC extension for IP 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
178 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
179 + * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
181 + * (C) 2002 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
185 + * ip_conntrack_rpc.h,v 2.2 2003/01/12 18:30:00
187 + * This program is free software; you can redistribute it and/or
188 + * modify it under the terms of the GNU General Public License
189 + * as published by the Free Software Foundation; either version
190 + * 2 of the License, or (at your option) any later version.
194 +#include <asm/param.h>
195 +#include <linux/sched.h>
196 +#include <linux/timer.h>
197 +#include <linux/stddef.h>
198 +#include <linux/list.h>
200 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
202 +#ifndef _IP_CONNTRACK_RPC_H
203 +#define _IP_CONNTRACK_RPC_H
205 +#define RPC_PORT 111
208 +/* Datum in RPC packets are encoded in XDR */
209 +#define IXDR_GET_INT32(buf) ((u_int32_t) ntohl((uint32_t)*buf))
211 +/* Fast timeout, to deny DoS atacks */
212 +#define EXP (60 * HZ)
214 +/* Normal timeouts */
215 +#define EXPIRES (180 * HZ)
217 +/* For future conections RPC, using client's cache bindings
218 + * I'll use ip_conntrack_lock to lock these lists */
220 +/* This identifies each request and stores protocol */
222 + struct list_head list;
231 + struct timer_list timeout;
234 +static inline int request_p_cmp(const struct request_p *p, u_int32_t xid,
235 + u_int32_t ip, u_int32_t port) {
236 + return (p->xid == xid && p->ip == ip && p->port);
240 +#endif /* _IP_CONNTRACK_RPC_H */
241 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h
242 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h 1970-01-01 00:00:00.000000000 +0000
243 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h 2004-03-16 12:04:49.000000000 +0000
246 + * RTSP extension for IP connection tracking.
247 + * (C) 2003 by Tom Marshall <tmarshall@real.com>
248 + * based on ip_conntrack_irc.h
250 + * This program is free software; you can redistribute it and/or
251 + * modify it under the terms of the GNU General Public License
252 + * as published by the Free Software Foundation; either version
253 + * 2 of the License, or (at your option) any later version.
255 +#ifndef _IP_CONNTRACK_RTSP_H
256 +#define _IP_CONNTRACK_RTSP_H
258 +/* #define IP_NF_RTSP_DEBUG */
259 +#define IP_NF_RTSP_VERSION "0.01"
261 +/* port block types */
263 + pb_single, /* client_port=x */
264 + pb_range, /* client_port=x-y */
265 + pb_discon /* client_port=x/y (rtspbis) */
268 +/* We record seq number and length of rtsp headers here, all in host order. */
271 + * This structure is per expected connection. It is a member of struct
272 + * ip_conntrack_expect. The TCP SEQ for the conntrack expect is stored
273 + * there and we are expected to only store the length of the data which
274 + * needs replaced. If a packet contains multiple RTSP messages, we create
275 + * one expected connection per message.
277 + * We use these variables to mark the entire header block. This may seem
278 + * like overkill, but the nature of RTSP requires it. A header may appear
279 + * multiple times in a message. We must treat two Transport headers the
280 + * same as one Transport header with two entries.
282 +struct ip_ct_rtsp_expect
284 + u_int32_t len; /* length of header block */
285 + portblock_t pbtype; /* Type of port block that was requested */
286 + u_int16_t loport; /* Port that was requested, low or first */
287 + u_int16_t hiport; /* Port that was requested, high or second */
289 + uint method; /* RTSP method */
290 + uint cseq; /* CSeq from request */
294 +/* This structure exists only once per master */
295 +struct ip_ct_rtsp_master
303 +#include <linux/netfilter_ipv4/lockhelp.h>
305 +#define RTSP_PORT 554
307 +/* Protects rtsp part of conntracks */
308 +DECLARE_LOCK_EXTERN(ip_rtsp_lock);
310 +#endif /* __KERNEL__ */
312 +#endif /* _IP_CONNTRACK_RTSP_H */
313 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h
314 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 00:00:00.000000000 +0000
315 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-03-16 12:04:09.000000000 +0000
317 +#ifndef _IPT_CONNMARK_H_target
318 +#define _IPT_CONNMARK_H_target
320 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
321 + * by Henrik Nordstrom <hno@marasystems.com>
323 + * This program is free software; you can redistribute it and/or modify
324 + * it under the terms of the GNU General Public License as published by
325 + * the Free Software Foundation; either version 2 of the License, or
326 + * (at your option) any later version.
330 + IPT_CONNMARK_SET = 0,
332 + IPT_CONNMARK_RESTORE
335 +struct ipt_connmark_target_info {
336 + unsigned long mark;
337 + unsigned long mask;
341 +#endif /*_IPT_CONNMARK_H_target*/
342 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h
343 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 00:00:00.000000000 +0000
344 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-03-16 12:04:10.000000000 +0000
346 +#ifndef _IPT_IPMARK_H_target
347 +#define _IPT_IPMARK_H_target
349 +struct ipt_ipmark_target_info {
350 + unsigned long andmask;
351 + unsigned long ormask;
355 +#define IPT_IPMARK_SRC 0
356 +#define IPT_IPMARK_DST 1
358 +#endif /*_IPT_IPMARK_H_target*/
359 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_XOR.h
360 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 00:00:00.000000000 +0000
361 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_XOR.h 2004-03-16 12:04:18.000000000 +0000
366 +struct ipt_XOR_info {
368 + u_int8_t block_size;
371 +#endif /* _IPT_XOR_H */
372 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h
373 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 00:00:00.000000000 +0000
374 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h 2004-03-16 12:04:20.000000000 +0000
376 +#ifndef _IPT_ADDRTYPE_H
377 +#define _IPT_ADDRTYPE_H
379 +struct ipt_addrtype_info {
380 + u_int16_t source; /* source-type mask */
381 + u_int16_t dest; /* dest-type mask */
387 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connmark.h
388 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 00:00:00.000000000 +0000
389 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connmark.h 2004-03-16 12:04:09.000000000 +0000
391 +#ifndef _IPT_CONNMARK_H
392 +#define _IPT_CONNMARK_H
394 +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
395 + * by Henrik Nordstrom <hno@marasystems.com>
397 + * This program is free software; you can redistribute it and/or modify
398 + * it under the terms of the GNU General Public License as published by
399 + * the Free Software Foundation; either version 2 of the License, or
400 + * (at your option) any later version.
403 +struct ipt_connmark_info {
404 + unsigned long mark, mask;
408 +#endif /*_IPT_CONNMARK_H*/
409 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_policy.h
410 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 00:00:00.000000000 +0000
411 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_policy.h 2004-03-16 12:04:45.000000000 +0000
413 +#ifndef _IPT_POLICY_H
414 +#define _IPT_POLICY_H
416 +#define POLICY_MAX_ELEM 4
418 +enum ipt_policy_flags
420 + POLICY_MATCH_IN = 0x1,
421 + POLICY_MATCH_OUT = 0x2,
422 + POLICY_MATCH_NONE = 0x4,
423 + POLICY_MATCH_STRICT = 0x8,
426 +enum ipt_policy_modes
428 + POLICY_MODE_TRANSPORT,
432 +struct ipt_policy_spec
442 +struct ipt_policy_elem
453 + struct ipt_policy_spec match;
454 + struct ipt_policy_spec invert;
457 +struct ipt_policy_info
459 + struct ipt_policy_elem pol[POLICY_MAX_ELEM];
464 +#endif /* _IPT_POLICY_H */
465 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_rpc.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_rpc.h
466 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_rpc.h 1970-01-01 00:00:00.000000000 +0000
467 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_rpc.h 2004-03-16 12:04:46.000000000 +0000
469 +/* RPC extension for IP netfilter matching, Version 2.2
470 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
471 + * - original rpc tracking module
472 + * - "recent" connection handling for kernel 2.3+ netfilter
474 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
475 + * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
477 + * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
478 + * - upgraded conntrack modules to newnat api - kernel 2.4.20+
479 + * - extended matching to support filtering on procedures
481 + * ipt_rpc.h.c,v 2.2 2003/01/12 18:30:00
483 + * This program is free software; you can redistribute it and/or
484 + * modify it under the terms of the GNU General Public License
485 + * as published by the Free Software Foundation; either version
486 + * 2 of the License, or (at your option) any later version.
493 +struct ipt_rpc_data;
495 +struct ipt_rpc_info {
498 + const char c_procs[1408];
500 + struct ipt_rpc_data *data;
503 +#endif /* _IPT_RPC_H */
504 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_string.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_string.h
505 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 00:00:00.000000000 +0000
506 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_string.h 2004-03-16 12:06:26.000000000 +0000
508 +#ifndef _IPT_STRING_H
509 +#define _IPT_STRING_H
511 +/* *** PERFORMANCE TWEAK ***
512 + * Packet size and search string threshold,
513 + * above which sublinear searches is used. */
514 +#define IPT_STRING_HAYSTACK_THRESH 100
515 +#define IPT_STRING_NEEDLE_THRESH 20
517 +#define BM_MAX_NLEN 256
518 +#define BM_MAX_HLEN 1024
520 +typedef char *(*proc_ipt_search) (char *, char *, int, int);
522 +struct ipt_string_info {
523 + char string[BM_MAX_NLEN];
528 +#endif /* _IPT_STRING_H */
529 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_owner.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_owner.h
530 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_owner.h 2004-03-16 05:46:45.000000000 +0000
531 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_owner.h 2004-03-16 12:04:42.000000000 +0000
533 #define IP6T_OWNER_GID 0x02
534 #define IP6T_OWNER_PID 0x04
535 #define IP6T_OWNER_SID 0x08
536 +#define IP6T_OWNER_COMM 0x10
538 struct ip6t_owner_info {
544 u_int8_t match, invert; /* flags */
547 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_mime.h linux-2.6.5-rc1/include/linux/netfilter_mime.h
548 --- linux-2.6.5-rc1.org/include/linux/netfilter_mime.h 1970-01-01 00:00:00.000000000 +0000
549 +++ linux-2.6.5-rc1/include/linux/netfilter_mime.h 2004-03-16 12:04:49.000000000 +0000
552 + * MIME functions for netfilter modules. This file provides implementations
553 + * for basic MIME parsing. MIME headers are used in many protocols, such as
554 + * HTTP, RTSP, SIP, etc.
556 + * gcc will warn for defined but unused functions, so we only include the
557 + * functions requested. The following macros are used:
558 + * NF_NEED_MIME_NEXTLINE nf_mime_nextline()
560 +#ifndef _NETFILTER_MIME_H
561 +#define _NETFILTER_MIME_H
563 +/* Only include these functions for kernel code. */
566 +#include <linux/ctype.h>
569 + * Given a buffer and length, advance to the next line and mark the current
570 + * line. If the current line is empty, *plinelen will be set to zero. If
571 + * not, it will be set to the actual line length (including CRLF).
573 + * 'line' in this context means logical line (includes LWS continuations).
574 + * Returns 1 on success, 0 on failure.
576 +#ifdef NF_NEED_MIME_NEXTLINE
578 +nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
582 + int is_first_line = 1;
591 + while (p[off] != '\n')
602 + /* if we saw a crlf, physlen needs adjusted */
603 + if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
608 + /* advance past the newline */
611 + /* check for an empty line */
617 + /* check for colon on the first physical line */
621 + if (memchr(p+(*poff), ':', physlen) == NULL)
627 + while (p[off] == ' ' || p[off] == '\t');
630 + *plinelen = (physlen == 0) ? 0 : (off - *poff);
635 +#endif /* NF_NEED_MIME_NEXTLINE */
637 +#endif /* __KERNEL__ */
639 +#endif /* _NETFILTER_MIME_H */
640 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/tcp.h linux-2.6.5-rc1/include/net/tcp.h
641 --- linux-2.6.5-rc1.org/include/net/tcp.h 2004-03-16 05:45:33.000000000 +0000
642 +++ linux-2.6.5-rc1/include/net/tcp.h 2004-03-16 12:04:38.000000000 +0000
644 extern void tcp_bucket_unlock(struct sock *sk);
645 extern int tcp_port_rover;
646 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
647 +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
649 /* These are AF independent. */
650 static __inline__ int tcp_bhashfn(__u16 lport)
651 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/udp.h linux-2.6.5-rc1/include/net/udp.h
652 --- linux-2.6.5-rc1.org/include/net/udp.h 2004-03-16 05:47:17.000000000 +0000
653 +++ linux-2.6.5-rc1/include/net/udp.h 2004-03-16 12:04:38.000000000 +0000
655 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
656 extern int udp_disconnect(struct sock *sk, int flags);
658 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
660 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
661 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
662 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
663 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig
664 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig 2004-03-16 12:00:23.000000000 +0000
665 +++ linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig 2004-03-16 12:06:26.000000000 +0000
667 depends on IP_NF_IPTABLES
670 +config IP_NF_CONNTRACK_MARK
671 + bool 'Connection mark tracking support'
672 +config IP_NF_TARGET_CONNMARK
673 + tristate 'CONNMARK target support'
674 + depends on IP_NF_MANGLE
675 +config IP_NF_MATCH_CONNMARK
676 + tristate ' Connection mark match support'
677 + depends on IP_NF_IPTABLES
680 +config IP_NF_TARGET_IPMARK
681 + tristate 'IPMARK target support'
682 + depends on IP_NF_MANGLE
685 +config IP_NF_TARGET_XOR
686 + tristate 'XOR target support'
687 + depends on IP_NF_MANGLE
690 +config IP_NF_MATCH_ADDRTYPE
691 + tristate 'address type match support'
692 + depends on IP_NF_IPTABLES
695 +config IP_NF_MATCH_POLICY
696 + tristate "IPsec policy match support"
697 + depends on IP_NF_IPTABLES && XFRM
699 + Policy matching allows you to match packets based on the
700 + IPsec policy that was used during decapsulation/will
701 + be used during encapsulation.
703 + To compile it as a module, choose M here. If unsure, say N.
706 +config IP_NF_MATCH_RPC
707 + tristate 'RPC match support'
708 + depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
711 +config IP_NF_NAT_RTSP
713 + depends on IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
714 + default IP_NF_NAT if IP_NF_RTSP=y
715 + default m if IP_NF_RTSP=m
717 + tristate ' RTSP protocol support'
718 + depends on IP_NF_CONNTRACK
721 +config IP_NF_MATCH_STRING
722 + tristate 'String match support'
723 + depends on IP_NF_IPTABLES
728 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc1/net/ipv4/netfilter/Makefile
729 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile 2004-03-16 12:00:23.000000000 +0000
730 +++ linux-2.6.5-rc1/net/ipv4/netfilter/Makefile 2004-03-16 12:06:26.000000000 +0000
732 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
734 # connection tracking helpers
736 +# rtsp protocol support
737 +obj-$(CONFIG_IP_NF_RTSP) += ip_conntrack_rtsp.o
738 +ifdef CONFIG_IP_NF_NAT_RTSP
739 + export-objs += ip_conntrack_rtsp.o
741 +obj-$(CONFIG_IP_NF_NAT_RTSP) += ip_nat_rtsp.o
743 obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
744 obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
745 obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
747 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
750 +obj-$(CONFIG_IP_NF_MATCH_RPC) += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o ipt_rpc.o
751 +export-objs += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o
753 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
754 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
755 obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
757 obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
758 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
759 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
760 +obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
761 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
763 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
766 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
767 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
768 +obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
769 obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
770 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
771 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
772 +obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
773 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
775 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
776 +obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
779 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
781 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
782 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
783 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
784 +obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
785 obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
786 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
787 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
789 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
790 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
791 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
792 +obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
793 +obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
794 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
795 obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
796 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
797 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c
798 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 1970-01-01 00:00:00.000000000 +0000
799 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 2004-03-16 12:04:46.000000000 +0000
801 +/* RPC extension for IP (TCP) connection tracking, Version 2.2
802 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
803 + * - original rpc tracking module
804 + * - "recent" connection handling for kernel 2.3+ netfilter
806 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
807 + * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
809 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
810 + * - upgraded conntrack modules to newnat api - kernel 2.4.20+
811 + * - extended matching to support filtering on procedures
813 + * ip_conntrack_rpc_tpc.c,v 2.2 2003/01/12 18:30:00
815 + * This program is free software; you can redistribute it and/or
816 + * modify it under the terms of the GNU General Public License
817 + * as published by the Free Software Foundation; either version
818 + * 2 of the License, or (at your option) any later version.
820 + * Module load syntax:
821 + * insmod ip_conntrack_rpc_tcp.o ports=port1,port2,...port<MAX_PORTS>
823 + * Please give the ports of all RPC servers you wish to connect to.
824 + * If you don't specify ports, the default will be port 111.
828 + * RPCs should not be exposed to the internet - ask the Pentagon;
830 + * "The unidentified crackers pleaded guilty in July to charges
831 + * of juvenile delinquency stemming from a string of Pentagon
832 + * network intrusions in February.
834 + * The youths, going by the names TooShort and Makaveli, used
835 + * a common server security hole to break in, according to
836 + * Dane Jasper, owner of the California Internet service
837 + * provider, Sonic. They used the hole, known as the 'statd'
838 + * exploit, to attempt more than 800 break-ins, Jasper said."
840 + * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
841 + * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
845 +#include <linux/module.h>
846 +#include <linux/netfilter.h>
847 +#include <linux/ip.h>
848 +#include <net/checksum.h>
849 +#include <net/tcp.h>
851 +#include <asm/param.h>
852 +#include <linux/sched.h>
853 +#include <linux/timer.h>
854 +#include <linux/stddef.h>
855 +#include <linux/list.h>
857 +#include <linux/netfilter_ipv4/lockhelp.h>
858 +#include <linux/netfilter_ipv4/ip_tables.h>
859 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
860 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
863 +static int ports[MAX_PORTS];
864 +static int ports_n_c = 0;
867 +MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
868 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
871 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
872 +MODULE_DESCRIPTION("RPC TCP connection tracking module");
873 +MODULE_LICENSE("GPL");
876 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_tcp: " \
879 +#define DEBUGP(format, args...)
882 +DECLARE_RWLOCK(ipct_rpc_tcp_lock);
883 +#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock)
884 +#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock)
885 +#include <linux/netfilter_ipv4/listhelp.h>
887 +/* For future conections RPC, using client's cache bindings
888 + * I'll use ip_conntrack_lock to lock these lists */
890 +LIST_HEAD(request_p_list_tcp);
893 +static void delete_request_p(unsigned long request_p_ul)
895 + struct request_p *p = (void *)request_p_ul;
897 + WRITE_LOCK(&ipct_rpc_tcp_lock);
898 + LIST_DELETE(&request_p_list_tcp, p);
899 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
905 +static void req_cl(struct request_p * r)
907 + WRITE_LOCK(&ipct_rpc_tcp_lock);
908 + del_timer(&r->timeout);
909 + LIST_DELETE(&request_p_list_tcp, r);
910 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
916 +static void clean_request(struct list_head *list)
918 + struct list_head *first = list->prev;
919 + struct list_head *temp = list->next;
920 + struct list_head *aux;
922 + if (list_empty(list))
925 + while (first != temp) {
927 + req_cl((struct request_p *)temp);
930 + req_cl((struct request_p *)temp);
935 +static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
938 + struct request_p *req_p;
940 + /* Verifies if entry already exists */
941 + WRITE_LOCK(&ipct_rpc_tcp_lock);
942 + req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
943 + struct request_p *, xid, ip, port);
946 + /* Refresh timeout */
947 + if (del_timer(&req_p->timeout)) {
948 + req_p->timeout.expires = jiffies + EXP;
949 + add_timer(&req_p->timeout);
951 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
955 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
957 + /* Allocate new request_p */
958 + req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
960 + DEBUGP("can't allocate request_p\n");
963 + *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
964 + { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
967 + /* Initialize timer */
968 + init_timer(&req_p->timeout);
969 + req_p->timeout.function = delete_request_p;
970 + add_timer(&req_p->timeout);
973 + WRITE_LOCK(&ipct_rpc_tcp_lock);
974 + list_prepend(&request_p_list_tcp, req_p);
975 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
981 +static int check_rpc_packet(const u_int32_t *data,
982 + int dir, struct ip_conntrack *ct,
983 + struct list_head request_p_list)
985 + struct request_p *req_p;
987 + struct ip_conntrack_expect expect, *exp = &expect;
989 + /* Translstion's buffer for XDR */
990 + u_int16_t port_buf;
996 + /* This does sanity checking on RPC payloads,
997 + * and permits only the RPC "get port" (3)
998 + * in authorised procedures in client
999 + * communications with the portmapper.
1002 + /* perform direction dependant RPC work */
1003 + if (dir == IP_CT_DIR_ORIGINAL) {
1007 + /* Get RPC requestor */
1008 + if (IXDR_GET_INT32(data) != 3) {
1009 + DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1012 + DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1016 + /* Jump Credentials and Verfifier */
1017 + data += IXDR_GET_INT32(data) + 2;
1018 + data += IXDR_GET_INT32(data) + 2;
1020 + /* Get RPC procedure */
1021 + DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
1022 + (unsigned int)IXDR_GET_INT32(data));
1024 + /* Get RPC protocol and store against client parameters */
1026 + alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
1027 + ct->tuplehash[dir].tuple.src.u.all);
1029 + DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1030 + xid, IXDR_GET_INT32(data),
1031 + NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1032 + ntohs(ct->tuplehash[dir].tuple.src.u.all));
1034 + DEBUGP("allocated RPC request for protocol %u. [done]\n",
1035 + (unsigned int)IXDR_GET_INT32(data));
1039 + /* Check for returning packet's stored counterpart */
1040 + req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
1041 + struct request_p *, xid,
1042 + ct->tuplehash[!dir].tuple.src.ip,
1043 + ct->tuplehash[!dir].tuple.src.u.all);
1045 + /* Drop unexpected packets */
1047 + DEBUGP("packet is not expected. [skip]\n");
1051 + /* Verifies if packet is really an RPC reply packet */
1053 + if (IXDR_GET_INT32(data) != 1) {
1054 + DEBUGP("packet is not a valid RPC reply. [skip]\n");
1058 + /* Is status accept? */
1060 + if (IXDR_GET_INT32(data)) {
1061 + DEBUGP("packet is not an RPC accept. [skip]\n");
1065 + /* Get Verifier length. Jump verifier */
1067 + data = data + IXDR_GET_INT32(data) + 2;
1069 + /* Is accpet status "success"? */
1070 + if (IXDR_GET_INT32(data)) {
1071 + DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1075 + /* Get server port number */
1077 + port_buf = (u_int16_t) IXDR_GET_INT32(data);
1079 + /* If a packet has made it this far then it deserves an
1080 + * expectation ... if port == 0, then this service is
1081 + * not going to be registered.
1084 + DEBUGP("port found: %u\n", port_buf);
1086 + memset(&expect, 0, sizeof(expect));
1088 + /* Watch out, Radioactive-Man! */
1089 + exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1090 + exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1091 + exp->mask.src.ip = 0xffffffff;
1092 + exp->mask.dst.ip = 0xffffffff;
1094 + switch (req_p->proto) {
1096 + exp->tuple.src.u.udp.port = 0;
1097 + exp->tuple.dst.u.udp.port = htons(port_buf);
1098 + exp->tuple.dst.protonum = IPPROTO_UDP;
1099 + exp->mask.src.u.udp.port = 0;
1100 + exp->mask.dst.u.udp.port = htons(0xffff);
1101 + exp->mask.dst.protonum = 0xffff;
1105 + exp->tuple.src.u.tcp.port = 0;
1106 + exp->tuple.dst.u.tcp.port = htons(port_buf);
1107 + exp->tuple.dst.protonum = IPPROTO_TCP;
1108 + exp->mask.src.u.tcp.port = 0;
1109 + exp->mask.dst.u.tcp.port = htons(0xffff);
1110 + exp->mask.dst.protonum = 0xffff;
1113 + exp->expectfn = NULL;
1115 + ip_conntrack_expect_related(ct, &expect);
1117 + DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1118 + NIPQUAD(exp->tuple.src.ip),
1119 + NIPQUAD(exp->tuple.dst.ip),
1120 + port_buf, req_p->proto);
1122 + DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1123 + NIPQUAD(exp->mask.src.ip),
1124 + NIPQUAD(exp->mask.dst.ip),
1125 + exp->mask.dst.protonum);
1131 + DEBUGP("packet evaluated. [expect]\n");
1140 +/* RPC TCP helper */
1141 +static int help(const struct iphdr *iph, size_t len,
1142 + struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1144 + struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
1145 + const u_int32_t *data = (const u_int32_t *)tcph + tcph->doff;
1146 + size_t tcplen = len - iph->ihl * 4;
1148 + int dir = CTINFO2DIR(ctinfo);
1152 + DEBUGP("new packet to evaluate ..\n");
1154 + /* This works for packets like handshake packets, ignore */
1155 + if (len == ((tcph->doff + iph->ihl) * 4)) {
1156 + DEBUGP("packet has no data (may still be handshaking). [skip]\n");
1160 + /* Until there's been traffic both ways, don't look in packets. */
1161 + if (ctinfo != IP_CT_ESTABLISHED
1162 + && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1163 + DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1164 + DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1165 + DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1169 + /* Not whole TCP header? */
1170 + if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
1171 + DEBUGP("TCP header length is; tcplen=%u ..\n", (unsigned) tcplen);
1172 + DEBUGP("packet does not contain a complete TCP header. [skip]\n");
1176 + /* FIXME: Source route IP option packets --RR */
1177 + if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
1178 + csum_partial((char *) tcph, tcplen, 0))) {
1179 + DEBUGP("csum; %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
1180 + tcph, tcplen, NIPQUAD(iph->saddr),
1181 + NIPQUAD(iph->daddr));
1182 + DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1183 + DEBUGP("packet contains a bad checksum. [skip]\n");
1187 + /* perform direction dependant protocol work */
1188 + if (dir == IP_CT_DIR_ORIGINAL) {
1190 + DEBUGP("packet is from the initiator. [cont]\n");
1192 + /* Tests if packet len is ok */
1193 + if ((tcplen - (tcph->doff * 4)) != 60) {
1194 + DEBUGP("packet length is not correct. [skip]\n");
1200 + DEBUGP("packet is from the receiver. [cont]\n");
1202 + /* Tests if packet len is ok */
1203 + if ((tcplen - (tcph->doff * 4)) != 32) {
1204 + DEBUGP("packet length is not correct. [skip]\n");
1209 + /* Get to the data */
1212 + /* Check the RPC data */
1213 + crp_ret = check_rpc_packet(data, dir, ct, request_p_list_tcp);
1220 +static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1222 +static void fini(void);
1225 +static int __init init(void)
1228 + static char name[10];
1231 + /* If no port given, default to standard RPC port */
1232 + if (ports[0] == 0)
1233 + ports[0] = RPC_PORT;
1235 + for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1236 + memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1238 + if (ports[port] == RPC_PORT)
1239 + sprintf(name, "rpc");
1241 + sprintf(name, "rpc-%d", port);
1243 + rpc_helpers[port].name = name;
1244 + rpc_helpers[port].me = THIS_MODULE;
1245 + rpc_helpers[port].max_expected = 1;
1246 + rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1247 + rpc_helpers[port].timeout = 0;
1249 + rpc_helpers[port].tuple.dst.protonum = IPPROTO_TCP;
1250 + rpc_helpers[port].mask.dst.protonum = 0xffff;
1252 + /* RPC can come from ports 0:65535 to ports[port] (111) */
1253 + rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1254 + rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1255 + rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1257 + rpc_helpers[port].help = help;
1259 + DEBUGP("registering helper for port #%d: %d/TCP\n", port, ports[port]);
1260 + DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1261 + NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1262 + ntohs(rpc_helpers[port].tuple.dst.u.tcp.port),
1263 + NIPQUAD(rpc_helpers[port].tuple.src.ip),
1264 + ntohs(rpc_helpers[port].tuple.src.u.tcp.port));
1265 + DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1266 + NIPQUAD(rpc_helpers[port].mask.dst.ip),
1267 + ntohs(rpc_helpers[port].mask.dst.u.tcp.port),
1268 + NIPQUAD(rpc_helpers[port].mask.src.ip),
1269 + ntohs(rpc_helpers[port].mask.src.u.tcp.port));
1271 + ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1274 + printk("ERROR registering port %d\n",
1285 +/* This function is intentionally _NOT_ defined as __exit, because
1286 + * it is needed by the init function */
1287 +static void fini(void)
1291 + DEBUGP("cleaning request list\n");
1292 + clean_request(&request_p_list_tcp);
1294 + for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1295 + DEBUGP("unregistering port %d\n", ports[port]);
1296 + ip_conntrack_helper_unregister(&rpc_helpers[port]);
1304 +struct module *ip_conntrack_rpc_tcp = THIS_MODULE;
1305 +EXPORT_SYMBOL(request_p_list_tcp);
1306 +EXPORT_SYMBOL(ip_conntrack_rpc_tcp);
1307 +EXPORT_SYMBOL(ipct_rpc_tcp_lock);
1309 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_udp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_udp.c
1310 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 1970-01-01 00:00:00.000000000 +0000
1311 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 2004-03-16 12:04:46.000000000 +0000
1313 +/* RPC extension for IP (UDP) connection tracking, Version 2.2
1314 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
1315 + * - original rpc tracking module
1316 + * - "recent" connection handling for kernel 2.3+ netfilter
1318 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
1319 + * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
1321 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
1322 + * - upgraded conntrack modules to newnat api - kernel 2.4.20+
1323 + * - extended matching to support filtering on procedures
1325 + * ip_conntrack_rpc_udp.c,v 2.2 2003/01/12 18:30:00
1327 + * This program is free software; you can redistribute it and/or
1328 + * modify it under the terms of the GNU General Public License
1329 + * as published by the Free Software Foundation; either version
1330 + * 2 of the License, or (at your option) any later version.
1332 + * Module load syntax:
1333 + * insmod ip_conntrack_rpc_udp.o ports=port1,port2,...port<MAX_PORTS>
1335 + * Please give the ports of all RPC servers you wish to connect to.
1336 + * If you don't specify ports, the default will be port 111.
1340 + * RPCs should not be exposed to the internet - ask the Pentagon;
1342 + * "The unidentified crackers pleaded guilty in July to charges
1343 + * of juvenile delinquency stemming from a string of Pentagon
1344 + * network intrusions in February.
1346 + * The youths, going by the names TooShort and Makaveli, used
1347 + * a common server security hole to break in, according to
1348 + * Dane Jasper, owner of the California Internet service
1349 + * provider, Sonic. They used the hole, known as the 'statd'
1350 + * exploit, to attempt more than 800 break-ins, Jasper said."
1352 + * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
1353 + * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
1357 +#include <linux/module.h>
1358 +#include <linux/netfilter.h>
1359 +#include <linux/ip.h>
1360 +#include <net/checksum.h>
1361 +#include <net/udp.h>
1363 +#include <asm/param.h>
1364 +#include <linux/sched.h>
1365 +#include <linux/timer.h>
1366 +#include <linux/stddef.h>
1367 +#include <linux/list.h>
1369 +#include <linux/netfilter_ipv4/lockhelp.h>
1370 +#include <linux/netfilter_ipv4/ip_tables.h>
1371 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
1372 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
1374 +#define MAX_PORTS 8
1375 +static int ports[MAX_PORTS];
1376 +static int ports_n_c = 0;
1379 +MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
1380 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
1383 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
1384 +MODULE_DESCRIPTION("RPC UDP connection tracking module");
1385 +MODULE_LICENSE("GPL");
1388 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_udp: " \
1391 +#define DEBUGP(format, args...)
1394 +DECLARE_RWLOCK(ipct_rpc_udp_lock);
1395 +#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock)
1396 +#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock)
1397 +#include <linux/netfilter_ipv4/listhelp.h>
1399 +/* For future conections RPC, using client's cache bindings
1400 + * I'll use ip_conntrack_lock to lock these lists */
1402 +LIST_HEAD(request_p_list_udp);
1405 +static void delete_request_p(unsigned long request_p_ul)
1407 + struct request_p *p = (void *)request_p_ul;
1409 + WRITE_LOCK(&ipct_rpc_udp_lock);
1410 + LIST_DELETE(&request_p_list_udp, p);
1411 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
1417 +static void req_cl(struct request_p * r)
1419 + WRITE_LOCK(&ipct_rpc_udp_lock);
1420 + del_timer(&r->timeout);
1421 + LIST_DELETE(&request_p_list_udp, r);
1422 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
1428 +static void clean_request(struct list_head *list)
1430 + struct list_head *first = list->prev;
1431 + struct list_head *temp = list->next;
1432 + struct list_head *aux;
1434 + if (list_empty(list))
1437 + while (first != temp) {
1439 + req_cl((struct request_p *)temp);
1442 + req_cl((struct request_p *)temp);
1447 +static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
1450 + struct request_p *req_p;
1452 + /* Verifies if entry already exists */
1453 + WRITE_LOCK(&ipct_rpc_udp_lock);
1454 + req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1455 + struct request_p *, xid, ip, port);
1458 + /* Refresh timeout */
1459 + if (del_timer(&req_p->timeout)) {
1460 + req_p->timeout.expires = jiffies + EXP;
1461 + add_timer(&req_p->timeout);
1463 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
1467 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
1469 + /* Allocate new request_p */
1470 + req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
1472 + DEBUGP("can't allocate request_p\n");
1475 + *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
1476 + { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
1479 + /* Initialize timer */
1480 + init_timer(&req_p->timeout);
1481 + req_p->timeout.function = delete_request_p;
1482 + add_timer(&req_p->timeout);
1485 + WRITE_LOCK(&ipct_rpc_udp_lock);
1486 + list_prepend(&request_p_list_udp, req_p);
1487 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
1493 +static int check_rpc_packet(const u_int32_t *data,
1494 + int dir, struct ip_conntrack *ct,
1495 + struct list_head request_p_list)
1497 + struct request_p *req_p;
1499 + struct ip_conntrack_expect expect, *exp = &expect;
1501 + /* Translstion's buffer for XDR */
1502 + u_int16_t port_buf;
1508 + /* This does sanity checking on RPC payloads,
1509 + * and permits only the RPC "get port" (3)
1510 + * in authorised procedures in client
1511 + * communications with the portmapper.
1514 + /* perform direction dependant RPC work */
1515 + if (dir == IP_CT_DIR_ORIGINAL) {
1519 + /* Get RPC requestor */
1520 + if (IXDR_GET_INT32(data) != 3) {
1521 + DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1524 + DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1528 + /* Jump Credentials and Verfifier */
1529 + data = data + IXDR_GET_INT32(data) + 2;
1530 + data = data + IXDR_GET_INT32(data) + 2;
1532 + /* Get RPC procedure */
1533 + DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
1534 + (unsigned int)IXDR_GET_INT32(data));
1536 + /* Get RPC protocol and store against client parameters */
1538 + alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
1539 + ct->tuplehash[dir].tuple.src.u.all);
1541 + DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1542 + xid, IXDR_GET_INT32(data),
1543 + NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1544 + ntohs(ct->tuplehash[dir].tuple.src.u.all));
1546 + DEBUGP("allocated RPC request for protocol %u. [done]\n",
1547 + (unsigned int)IXDR_GET_INT32(data));
1551 + /* Check for returning packet's stored counterpart */
1552 + req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1553 + struct request_p *, xid,
1554 + ct->tuplehash[!dir].tuple.src.ip,
1555 + ct->tuplehash[!dir].tuple.src.u.all);
1557 + /* Drop unexpected packets */
1559 + DEBUGP("packet is not expected. [skip]\n");
1563 + /* Verifies if packet is really an RPC reply packet */
1565 + if (IXDR_GET_INT32(data) != 1) {
1566 + DEBUGP("packet is not a valid RPC reply. [skip]\n");
1570 + /* Is status accept? */
1572 + if (IXDR_GET_INT32(data)) {
1573 + DEBUGP("packet is not an RPC accept. [skip]\n");
1577 + /* Get Verifier length. Jump verifier */
1579 + data = data + IXDR_GET_INT32(data) + 2;
1581 + /* Is accpet status "success"? */
1582 + if (IXDR_GET_INT32(data)) {
1583 + DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1587 + /* Get server port number */
1589 + port_buf = (u_int16_t) IXDR_GET_INT32(data);
1591 + /* If a packet has made it this far then it deserves an
1592 + * expectation ... if port == 0, then this service is
1593 + * not going to be registered.
1596 + DEBUGP("port found: %u\n", port_buf);
1598 + memset(&expect, 0, sizeof(expect));
1600 + /* Watch out, Radioactive-Man! */
1601 + exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1602 + exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1603 + exp->mask.src.ip = 0xffffffff;
1604 + exp->mask.dst.ip = 0xffffffff;
1606 + switch (req_p->proto) {
1608 + exp->tuple.src.u.udp.port = 0;
1609 + exp->tuple.dst.u.udp.port = htons(port_buf);
1610 + exp->tuple.dst.protonum = IPPROTO_UDP;
1611 + exp->mask.src.u.udp.port = 0;
1612 + exp->mask.dst.u.udp.port = htons(0xffff);
1613 + exp->mask.dst.protonum = 0xffff;
1617 + exp->tuple.src.u.tcp.port = 0;
1618 + exp->tuple.dst.u.tcp.port = htons(port_buf);
1619 + exp->tuple.dst.protonum = IPPROTO_TCP;
1620 + exp->mask.src.u.tcp.port = 0;
1621 + exp->mask.dst.u.tcp.port = htons(0xffff);
1622 + exp->mask.dst.protonum = 0xffff;
1625 + exp->expectfn = NULL;
1627 + ip_conntrack_expect_related(ct, &expect);
1629 + DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1630 + NIPQUAD(exp->tuple.src.ip),
1631 + NIPQUAD(exp->tuple.dst.ip),
1632 + port_buf, req_p->proto);
1634 + DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1635 + NIPQUAD(exp->mask.src.ip),
1636 + NIPQUAD(exp->mask.dst.ip),
1637 + exp->mask.dst.protonum);
1643 + DEBUGP("packet evaluated. [expect]\n");
1652 +/* RPC UDP helper */
1653 +static int help(const struct iphdr *iph, size_t len,
1654 + struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1656 + struct udphdr *udph = (void *) iph + iph->ihl * 4;
1657 + const u_int32_t *data = (const u_int32_t *)udph + 2;
1658 + size_t udplen = len - iph->ihl * 4;
1659 + int dir = CTINFO2DIR(ctinfo);
1663 + const u_int16_t *chsm = (const u_int16_t *)udph + 3;
1666 + DEBUGP("new packet to evaluate ..\n");
1668 + /* Not whole UDP header? */
1669 + if (udplen < sizeof(struct udphdr)) {
1670 + DEBUGP("UDP header length is; udplen=%u ..\n", (unsigned) udplen);
1671 + DEBUGP("packet does not contain a complete UDP header. [skip]\n");
1675 + /* FIXME: Source route IP option packets --RR */
1677 + if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
1678 + csum_partial((char *)udph, udplen, 0))) {
1679 + DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1680 + DEBUGP("packet contains a bad checksum. [skip]\n");
1685 + /* perform direction dependant protocol work */
1686 + if (dir == IP_CT_DIR_ORIGINAL) {
1688 + DEBUGP("packet is from the initiator. [cont]\n");
1690 + /* Tests if packet len is ok */
1691 + if ((udplen - sizeof(struct udphdr)) != 56) {
1692 + DEBUGP("packet length is not correct. [skip]\n");
1698 + DEBUGP("packet is from the receiver. [cont]\n");
1700 + /* Until there's been traffic both ways, don't look in packets. */
1701 + if (ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1702 + DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1703 + DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1704 + DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1708 + /* Tests if packet len is ok */
1709 + if ((udplen - sizeof(struct udphdr)) != 28) {
1710 + DEBUGP("packet length is not correct. [skip]\n");
1716 + /* Get to the data */
1717 + /* udp *data == *correct */
1719 + /* Check the RPC data */
1720 + crp_ret = check_rpc_packet(data, dir, ct, request_p_list_udp);
1727 +static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1729 +static void fini(void);
1732 +static int __init init(void)
1735 + static char name[10];
1738 + /* If no port given, default to standard RPC port */
1739 + if (ports[0] == 0)
1740 + ports[0] = RPC_PORT;
1742 + for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1743 + memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1745 + if (ports[port] == RPC_PORT)
1746 + sprintf(name, "rpc");
1748 + sprintf(name, "rpc-%d", port);
1750 + rpc_helpers[port].name = name;
1751 + rpc_helpers[port].me = THIS_MODULE;
1752 + rpc_helpers[port].max_expected = 1;
1753 + rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1754 + rpc_helpers[port].timeout = 0;
1756 + rpc_helpers[port].tuple.dst.protonum = IPPROTO_UDP;
1757 + rpc_helpers[port].mask.dst.protonum = 0xffff;
1759 + /* RPC can come from ports 0:65535 to ports[port] (111) */
1760 + rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1761 + rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1762 + rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1764 + rpc_helpers[port].help = help;
1766 + DEBUGP("registering helper for port #%d: %d/UDP\n", port, ports[port]);
1767 + DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1768 + NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1769 + ntohs(rpc_helpers[port].tuple.dst.u.udp.port),
1770 + NIPQUAD(rpc_helpers[port].tuple.src.ip),
1771 + ntohs(rpc_helpers[port].tuple.src.u.udp.port));
1772 + DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1773 + NIPQUAD(rpc_helpers[port].mask.dst.ip),
1774 + ntohs(rpc_helpers[port].mask.dst.u.udp.port),
1775 + NIPQUAD(rpc_helpers[port].mask.src.ip),
1776 + ntohs(rpc_helpers[port].mask.src.u.udp.port));
1778 + ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1781 + printk("ERROR registering port %d\n",
1792 +/* This function is intentionally _NOT_ defined as __exit, because
1793 + * it is needed by the init function */
1794 +static void fini(void)
1798 + DEBUGP("cleaning request list\n");
1799 + clean_request(&request_p_list_udp);
1801 + for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1802 + DEBUGP("unregistering port %d\n", ports[port]);
1803 + ip_conntrack_helper_unregister(&rpc_helpers[port]);
1811 +struct module *ip_conntrack_rpc_udp = THIS_MODULE;
1812 +EXPORT_SYMBOL(request_p_list_udp);
1813 +EXPORT_SYMBOL(ip_conntrack_rpc_udp);
1814 +EXPORT_SYMBOL(ipct_rpc_udp_lock);
1816 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rtsp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rtsp.c
1817 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rtsp.c 1970-01-01 00:00:00.000000000 +0000
1818 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rtsp.c 2004-03-16 12:04:49.000000000 +0000
1821 + * RTSP extension for IP connection tracking
1822 + * (C) 2003 by Tom Marshall <tmarshall@real.com>
1823 + * based on ip_conntrack_irc.c
1825 + * This program is free software; you can redistribute it and/or
1826 + * modify it under the terms of the GNU General Public License
1827 + * as published by the Free Software Foundation; either version
1828 + * 2 of the License, or (at your option) any later version.
1830 + * Module load syntax:
1831 + * insmod ip_conntrack_rtsp.o ports=port1,port2,...port<MAX_PORTS>
1832 + * max_outstanding=n setup_timeout=secs
1834 + * If no ports are specified, the default will be port 554.
1836 + * With max_outstanding you can define the maximum number of not yet
1837 + * answered SETUP requests per RTSP session (default 8).
1838 + * With setup_timeout you can specify how long the system waits for
1839 + * an expected data channel (default 300 seconds).
1842 +#include <linux/config.h>
1843 +#include <linux/module.h>
1844 +#include <linux/netfilter.h>
1845 +#include <linux/ip.h>
1846 +#include <net/checksum.h>
1847 +#include <net/tcp.h>
1849 +#include <linux/netfilter_ipv4/lockhelp.h>
1850 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
1851 +#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
1853 +#include <linux/ctype.h>
1854 +#define NF_NEED_STRNCASECMP
1855 +#define NF_NEED_STRTOU16
1856 +#define NF_NEED_STRTOU32
1857 +#define NF_NEED_NEXTLINE
1858 +#include <linux/netfilter_helpers.h>
1859 +#define NF_NEED_MIME_NEXTLINE
1860 +#include <linux/netfilter_mime.h>
1862 +#define MAX_SIMUL_SETUP 8 /* XXX: use max_outstanding */
1864 +#define INFOP(args...) printk(KERN_INFO __FILE__ ":" __FUNCTION__ ":" args)
1865 +#ifdef IP_NF_RTSP_DEBUG
1866 +#define DEBUGP(args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ ":" args)
1868 +#define DEBUGP(args...)
1871 +#define MAX_PORTS 8
1872 +static int ports[MAX_PORTS];
1873 +static int num_ports = 0;
1874 +static int max_outstanding = 8;
1875 +static unsigned int setup_timeout = 300;
1877 +MODULE_AUTHOR("Tom Marshall <tmarshall@real.com>");
1878 +MODULE_DESCRIPTION("RTSP connection tracking module");
1879 +MODULE_LICENSE("GPL");
1881 +MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
1882 +MODULE_PARM_DESC(ports, "port numbers of RTSP servers");
1883 +MODULE_PARM(max_outstanding, "i");
1884 +MODULE_PARM_DESC(max_outstanding, "max number of outstanding SETUP requests per RTSP session");
1885 +MODULE_PARM(setup_timeout, "i");
1886 +MODULE_PARM_DESC(setup_timeout, "timeout on for unestablished data channels");
1889 +DECLARE_LOCK(ip_rtsp_lock);
1890 +struct module* ip_conntrack_rtsp = THIS_MODULE;
1893 + * Max mappings we will allow for one RTSP connection (for RTP, the number
1894 + * of allocated ports is twice this value). Note that SMIL burns a lot of
1895 + * ports so keep this reasonably high. If this is too low, you will see a
1896 + * lot of "no free client map entries" messages.
1898 +#define MAX_PORT_MAPS 16
1900 +/*** default port list was here in the masq code: 554, 3030, 4040 ***/
1902 +#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
1905 + * Parse an RTSP packet.
1907 + * Returns zero if parsing failed.
1910 + * IN ptcp tcp data pointer
1911 + * IN tcplen tcp data len
1912 + * IN/OUT ptcpoff points to current tcp offset
1913 + * OUT phdrsoff set to offset of rtsp headers
1914 + * OUT phdrslen set to length of rtsp headers
1915 + * OUT pcseqoff set to offset of CSeq header
1916 + * OUT pcseqlen set to length of CSeq header
1919 +rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff,
1920 + uint* phdrsoff, uint* phdrslen,
1921 + uint* pcseqoff, uint* pcseqlen)
1923 + uint entitylen = 0;
1927 + if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen))
1932 + *phdrsoff = *ptcpoff;
1933 + while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen))
1937 + if (entitylen > 0)
1939 + *ptcpoff += min(entitylen, tcplen - *ptcpoff);
1943 + if (lineoff+linelen > tcplen)
1945 + INFOP("!! overrun !!\n");
1949 + if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0)
1951 + *pcseqoff = lineoff;
1952 + *pcseqlen = linelen;
1954 + if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0)
1956 + uint off = lineoff+15;
1957 + SKIP_WSPACE(ptcp+lineoff, linelen, off);
1958 + nf_strtou32(ptcp+off, &entitylen);
1961 + *phdrslen = (*ptcpoff) - (*phdrsoff);
1967 + * Find lo/hi client ports (if any) in transport header
1969 + * ptcp, tcplen = packet
1970 + * tranoff, tranlen = buffer to search
1973 + * pport_lo, pport_hi = lo/hi ports (host endian)
1975 + * Returns nonzero if any client ports found
1977 + * Note: it is valid (and expected) for the client to request multiple
1978 + * transports, so we need to parse the entire line.
1981 +rtsp_parse_transport(char* ptran, uint tranlen,
1982 + struct ip_ct_rtsp_expect* prtspexp)
1987 + if (tranlen < 10 || !iseol(ptran[tranlen-1]) ||
1988 + nf_strncasecmp(ptran, "Transport:", 10) != 0)
1990 + INFOP("sanity check failed\n");
1993 + DEBUGP("tran='%.*s'\n", (int)tranlen, ptran);
1995 + SKIP_WSPACE(ptran, tranlen, off);
1997 + /* Transport: tran;field;field=val,tran;field;field=val,... */
1998 + while (off < tranlen)
2000 + const char* pparamend;
2001 + uint nextparamoff;
2003 + pparamend = memchr(ptran+off, ',', tranlen-off);
2004 + pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
2005 + nextparamoff = pparamend-ptran;
2007 + while (off < nextparamoff)
2009 + const char* pfieldend;
2010 + uint nextfieldoff;
2012 + pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2013 + nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2015 + if (strncmp(ptran+off, "client_port=", 12) == 0)
2021 + numlen = nf_strtou16(ptran+off, &port);
2023 + if (prtspexp->loport != 0 && prtspexp->loport != port)
2025 + DEBUGP("multiple ports found, port %hu ignored\n", port);
2029 + prtspexp->loport = prtspexp->hiport = port;
2030 + if (ptran[off] == '-')
2033 + numlen = nf_strtou16(ptran+off, &port);
2035 + prtspexp->pbtype = pb_range;
2036 + prtspexp->hiport = port;
2038 + // If we have a range, assume rtp:
2039 + // loport must be even, hiport must be loport+1
2040 + if ((prtspexp->loport & 0x0001) != 0 ||
2041 + prtspexp->hiport != prtspexp->loport+1)
2043 + DEBUGP("incorrect range: %hu-%hu, correcting\n",
2044 + prtspexp->loport, prtspexp->hiport);
2045 + prtspexp->loport &= 0xfffe;
2046 + prtspexp->hiport = prtspexp->loport+1;
2049 + else if (ptran[off] == '/')
2052 + numlen = nf_strtou16(ptran+off, &port);
2054 + prtspexp->pbtype = pb_discon;
2055 + prtspexp->hiport = port;
2062 + * Note we don't look for the destination parameter here.
2063 + * If we are using NAT, the NAT module will handle it. If not,
2064 + * and the client is sending packets elsewhere, the expectation
2065 + * will quietly time out.
2068 + off = nextfieldoff;
2071 + off = nextparamoff;
2077 +/*** conntrack functions ***/
2079 +/* outbound packet: client->server */
2081 +help_out(const struct iphdr* iph, size_t pktlen,
2082 + struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2084 + int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */
2085 + struct tcphdr* tcph = (void*)iph + iph->ihl * 4;
2086 + uint tcplen = pktlen - iph->ihl * 4;
2087 + char* pdata = (char*)tcph + tcph->doff * 4;
2088 + uint datalen = tcplen - tcph->doff * 4;
2091 + struct ip_conntrack_expect exp;
2093 + while (dataoff < datalen)
2095 + uint cmdoff = dataoff;
2105 + if (!rtsp_parse_message(pdata, datalen, &dataoff,
2106 + &hdrsoff, &hdrslen,
2107 + &cseqoff, &cseqlen))
2109 + break; /* not a valid message */
2112 + if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0)
2114 + continue; /* not a SETUP message */
2116 + DEBUGP("found a setup message\n");
2118 + memset(&exp, 0, sizeof(exp));
2121 + while (nf_mime_nextline(pdata+hdrsoff, hdrslen, &off,
2122 + &lineoff, &linelen))
2128 + if (off > hdrsoff+hdrslen)
2130 + INFOP("!! overrun !!");
2134 + if (nf_strncasecmp(pdata+hdrsoff+lineoff, "Transport:", 10) == 0)
2136 + rtsp_parse_transport(pdata+hdrsoff+lineoff, linelen,
2137 + &exp.help.exp_rtsp_info);
2141 + if (exp.help.exp_rtsp_info.loport == 0)
2143 + DEBUGP("no udp transports found\n");
2144 + continue; /* no udp transports found */
2147 + DEBUGP("udp transport found, ports=(%d,%hu,%hu)\n",
2148 + (int)exp.help.exp_rtsp_info.pbtype,
2149 + exp.help.exp_rtsp_info.loport,
2150 + exp.help.exp_rtsp_info.hiport);
2152 + LOCK_BH(&ip_rtsp_lock);
2153 + exp.seq = ntohl(tcph->seq) + hdrsoff; /* mark all the headers */
2154 + exp.help.exp_rtsp_info.len = hdrslen;
2156 + exp.tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
2157 + exp.mask.src.ip = 0xffffffff;
2158 + exp.tuple.dst.ip = ct->tuplehash[dir].tuple.src.ip;
2159 + exp.mask.dst.ip = 0xffffffff;
2160 + exp.tuple.dst.u.udp.port = exp.help.exp_rtsp_info.loport;
2161 + exp.mask.dst.u.udp.port = (exp.help.exp_rtsp_info.pbtype == pb_range) ? 0xfffe : 0xffff;
2162 + exp.tuple.dst.protonum = IPPROTO_UDP;
2163 + exp.mask.dst.protonum = 0xffff;
2165 + DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
2166 + NIPQUAD(exp.tuple.src.ip),
2167 + ntohs(exp.tuple.src.u.tcp.port),
2168 + NIPQUAD(exp.tuple.dst.ip),
2169 + ntohs(exp.tuple.dst.u.tcp.port));
2171 + /* pass the request off to the nat helper */
2172 + rc = ip_conntrack_expect_related(ct, &exp);
2173 + UNLOCK_BH(&ip_rtsp_lock);
2176 + DEBUGP("ip_conntrack_expect_related succeeded\n");
2180 + INFOP("ip_conntrack_expect_related failed (%d)\n", rc);
2187 +/* inbound packet: server->client */
2189 +help_in(const struct iphdr* iph, size_t pktlen,
2190 + struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2196 +help(const struct iphdr* iph, size_t pktlen,
2197 + struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2199 + /* tcplen not negative guarenteed by ip_conntrack_tcp.c */
2200 + struct tcphdr* tcph = (void*)iph + iph->ihl * 4;
2201 + u_int32_t tcplen = pktlen - iph->ihl * 4;
2203 + /* Until there's been traffic both ways, don't look in packets. */
2204 + if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
2206 + DEBUGP("conntrackinfo = %u\n", ctinfo);
2210 + /* Not whole TCP header? */
2211 + if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4)
2213 + DEBUGP("tcplen = %u\n", (unsigned)tcplen);
2217 + /* Checksum invalid? Ignore. */
2218 + /* FIXME: Source route IP option packets --RR */
2219 + if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
2220 + csum_partial((char*)tcph, tcplen, 0)))
2222 + DEBUGP("bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
2223 + tcph, tcplen, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
2227 + switch (CTINFO2DIR(ctinfo))
2229 + case IP_CT_DIR_ORIGINAL:
2230 + help_out(iph, pktlen, ct, ctinfo);
2232 + case IP_CT_DIR_REPLY:
2233 + help_in(iph, pktlen, ct, ctinfo);
2242 +static struct ip_conntrack_helper rtsp_helpers[MAX_PORTS];
2243 +static char rtsp_names[MAX_PORTS][10];
2245 +/* This function is intentionally _NOT_ defined as __exit */
2250 + for (i = 0; i < num_ports; i++)
2252 + DEBUGP("unregistering port %d\n", ports[i]);
2253 + ip_conntrack_helper_unregister(&rtsp_helpers[i]);
2261 + struct ip_conntrack_helper *hlpr;
2264 + printk("ip_conntrack_rtsp v" IP_NF_RTSP_VERSION " loading\n");
2266 + if (max_outstanding < 1)
2268 + printk("ip_conntrack_rtsp: max_outstanding must be a positive integer\n");
2271 + if (setup_timeout < 0)
2273 + printk("ip_conntrack_rtsp: setup_timeout must be a positive integer\n");
2277 + /* If no port given, default to standard rtsp port */
2278 + if (ports[0] == 0)
2280 + ports[0] = RTSP_PORT;
2283 + for (i = 0; (i < MAX_PORTS) && ports[i]; i++)
2285 + hlpr = &rtsp_helpers[i];
2286 + memset(hlpr, 0, sizeof(struct ip_conntrack_helper));
2287 + hlpr->tuple.src.u.tcp.port = htons(ports[i]);
2288 + hlpr->tuple.dst.protonum = IPPROTO_TCP;
2289 + hlpr->mask.src.u.tcp.port = 0xFFFF;
2290 + hlpr->mask.dst.protonum = 0xFFFF;
2291 + hlpr->max_expected = max_outstanding;
2292 + hlpr->timeout = setup_timeout;
2293 + hlpr->flags = IP_CT_HELPER_F_REUSE_EXPECT;
2294 + hlpr->me = ip_conntrack_rtsp;
2295 + hlpr->help = help;
2297 + tmpname = &rtsp_names[i][0];
2298 + if (ports[i] == RTSP_PORT)
2300 + sprintf(tmpname, "rtsp");
2304 + sprintf(tmpname, "rtsp-%d", i);
2306 + hlpr->name = tmpname;
2308 + DEBUGP("port #%d: %d\n", i, ports[i]);
2310 + ret = ip_conntrack_helper_register(hlpr);
2314 + printk("ip_conntrack_rtsp: ERROR registering port %d\n", ports[i]);
2323 +#ifdef CONFIG_IP_NF_NAT_NEEDED
2324 +EXPORT_SYMBOL(ip_rtsp_lock);
2329 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c
2330 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:00:23.000000000 +0000
2331 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:04:09.000000000 +0000
2333 len += sprintf(buffer + len, "[ASSURED] ");
2334 len += sprintf(buffer + len, "use=%u ",
2335 atomic_read(&conntrack->ct_general.use));
2336 +#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
2337 + len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
2339 len += sprintf(buffer + len, "\n");
2342 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_rtsp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_rtsp.c
2343 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_rtsp.c 1970-01-01 00:00:00.000000000 +0000
2344 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_rtsp.c 2004-03-16 12:04:49.000000000 +0000
2347 + * RTSP extension for TCP NAT alteration
2348 + * (C) 2003 by Tom Marshall <tmarshall@real.com>
2349 + * based on ip_nat_irc.c
2351 + * This program is free software; you can redistribute it and/or
2352 + * modify it under the terms of the GNU General Public License
2353 + * as published by the Free Software Foundation; either version
2354 + * 2 of the License, or (at your option) any later version.
2356 + * Module load syntax:
2357 + * insmod ip_nat_rtsp.o ports=port1,port2,...port<MAX_PORTS>
2358 + * stunaddr=<address>
2359 + * destaction=[auto|strip|none]
2361 + * If no ports are specified, the default will be port 554 only.
2363 + * stunaddr specifies the address used to detect that a client is using STUN.
2364 + * If this address is seen in the destination parameter, it is assumed that
2365 + * the client has already punched a UDP hole in the firewall, so we don't
2366 + * mangle the client_port. If none is specified, it is autodetected. It
2367 + * only needs to be set if you have multiple levels of NAT. It should be
2368 + * set to the external address that the STUN clients detect. Note that in
2369 + * this case, it will not be possible for clients to use UDP with servers
2370 + * between the NATs.
2372 + * If no destaction is specified, auto is used.
2373 + * destaction=auto: strip destination parameter if it is not stunaddr.
2374 + * destaction=strip: always strip destination parameter (not recommended).
2375 + * destaction=none: do not touch destination parameter (not recommended).
2378 +#include <linux/module.h>
2379 +#include <linux/netfilter_ipv4.h>
2380 +#include <linux/ip.h>
2381 +#include <linux/tcp.h>
2382 +#include <linux/kernel.h>
2383 +#include <net/tcp.h>
2384 +#include <linux/netfilter_ipv4/ip_nat.h>
2385 +#include <linux/netfilter_ipv4/ip_nat_helper.h>
2386 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
2387 +#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
2388 +#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
2390 +#include <linux/inet.h>
2391 +#include <linux/ctype.h>
2392 +#define NF_NEED_STRNCASECMP
2393 +#define NF_NEED_STRTOU16
2394 +#include <linux/netfilter_helpers.h>
2395 +#define NF_NEED_MIME_NEXTLINE
2396 +#include <linux/netfilter_mime.h>
2398 +#define INFOP(args...) printk(KERN_INFO __FILE__ ":" __FUNCTION__ ":" args)
2399 +#ifdef IP_NF_RTSP_DEBUG
2400 +#define DEBUGP(args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ ":" args);
2402 +#define DEBUGP(args...)
2405 +#define MAX_PORTS 8
2406 +#define DSTACT_AUTO 0
2407 +#define DSTACT_STRIP 1
2408 +#define DSTACT_NONE 2
2410 +static int ports[MAX_PORTS];
2411 +static char* stunaddr = NULL;
2412 +static char* destaction = NULL;
2414 +static int num_ports = 0;
2415 +static u_int32_t extip = 0;
2416 +static int dstact = 0;
2418 +MODULE_AUTHOR("Tom Marshall <tmarshall@real.com>");
2419 +MODULE_DESCRIPTION("RTSP network address translation module");
2420 +MODULE_LICENSE("GPL");
2422 +MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
2423 +MODULE_PARM_DESC(ports, "port numbers of RTSP servers");
2424 +MODULE_PARM(stunaddr, "s");
2425 +MODULE_PARM_DESC(stunaddr, "Address for detecting STUN");
2426 +MODULE_PARM(destaction, "s");
2427 +MODULE_PARM_DESC(destaction, "Action for destination parameter (auto/strip/none)");
2430 +/* protects rtsp part of conntracks */
2431 +DECLARE_LOCK_EXTERN(ip_rtsp_lock);
2433 +#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
2435 +/*** helper functions ***/
2438 +get_skb_tcpdata(struct sk_buff* skb, char** pptcpdata, uint* ptcpdatalen)
2440 + struct iphdr* iph = (struct iphdr*)skb->nh.iph;
2441 + struct tcphdr* tcph = (struct tcphdr*)((char*)iph + iph->ihl*4);
2443 + *pptcpdata = (char*)tcph + tcph->doff*4;
2444 + *ptcpdatalen = ((char*)skb->h.raw + skb->len) - *pptcpdata;
2447 +/*** nat functions ***/
2450 + * Mangle the "Transport:" header:
2451 + * - Replace all occurences of "client_port=<spec>"
2452 + * - Handle destination parameter
2455 + * ct, ctinfo = conntrack context
2457 + * tranoff = Transport header offset from TCP data
2458 + * tranlen = Transport header length (incl. CRLF)
2459 + * rport_lo = replacement low port (host endian)
2460 + * rport_hi = replacement high port (host endian)
2462 + * Returns packet size difference.
2464 + * Assumes that a complete transport header is present, ending with CR or LF
2467 +rtsp_mangle_tran(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2468 + struct ip_conntrack_expect* exp,
2469 + struct sk_buff** pskb, uint tranoff, uint tranlen)
2474 + char rbuf1[16]; /* Replacement buffer (one port) */
2475 + uint rbuf1len; /* Replacement len (one port) */
2476 + char rbufa[16]; /* Replacement buffer (all ports) */
2477 + uint rbufalen; /* Replacement len (all ports) */
2479 + u_int16_t loport, hiport;
2481 + uint diff; /* Number of bytes we removed */
2483 + struct ip_ct_rtsp_expect* prtspexp = &exp->help.exp_rtsp_info;
2484 + struct ip_conntrack_tuple t;
2486 + char szextaddr[15+1];
2490 + get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2491 + ptran = ptcp+tranoff;
2493 + if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
2494 + tranlen < 10 || !iseol(ptran[tranlen-1]) ||
2495 + nf_strncasecmp(ptran, "Transport:", 10) != 0)
2497 + INFOP("sanity check failed\n");
2501 + SKIP_WSPACE(ptcp+tranoff, tranlen, off);
2503 + newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
2507 + extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip))
2508 + : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip));
2509 + DEBUGP("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));
2511 + rbuf1len = rbufalen = 0;
2512 + switch (prtspexp->pbtype)
2515 + for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
2517 + t.dst.u.udp.port = htons(loport);
2518 + if (ip_conntrack_change_expect(exp, &t) == 0)
2520 + DEBUGP("using port %hu\n", loport);
2526 + rbuf1len = sprintf(rbuf1, "%hu", loport);
2527 + rbufalen = sprintf(rbufa, "%hu", loport);
2531 + for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */
2533 + t.dst.u.udp.port = htons(loport);
2534 + if (ip_conntrack_change_expect(exp, &t) == 0)
2536 + hiport = loport + ~exp->mask.dst.u.udp.port;
2537 + DEBUGP("using ports %hu-%hu\n", loport, hiport);
2543 + rbuf1len = sprintf(rbuf1, "%hu", loport);
2544 + rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1);
2548 + for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
2550 + t.dst.u.udp.port = htons(loport);
2551 + if (ip_conntrack_change_expect(exp, &t) == 0)
2553 + DEBUGP("using port %hu (1 of 2)\n", loport);
2557 + for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */
2559 + t.dst.u.udp.port = htons(hiport);
2560 + if (ip_conntrack_change_expect(exp, &t) == 0)
2562 + DEBUGP("using port %hu (2 of 2)\n", hiport);
2566 + if (loport != 0 && hiport != 0)
2568 + rbuf1len = sprintf(rbuf1, "%hu", loport);
2569 + if (hiport == loport+1)
2571 + rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
2575 + rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport);
2583 + if (rbuf1len == 0)
2585 + return 0; /* cannot get replacement port(s) */
2588 + /* Transport: tran;field;field=val,tran;field;field=val,... */
2589 + while (off < tranlen)
2592 + const char* pparamend;
2593 + uint nextparamoff;
2595 + pparamend = memchr(ptran+off, ',', tranlen-off);
2596 + pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
2597 + nextparamoff = pparamend-ptcp;
2600 + * We pass over each param twice. On the first pass, we look for a
2601 + * destination= field. It is handled by the security policy. If it
2602 + * is present, allowed, and equal to our external address, we assume
2603 + * that STUN is being used and we leave the client_port= field alone.
2607 + while (off < nextparamoff)
2609 + const char* pfieldend;
2610 + uint nextfieldoff;
2612 + pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2613 + nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2615 + if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0)
2617 + if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
2621 + if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun))
2623 + diff = nextfieldoff-off;
2624 + if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
2625 + off, diff, NULL, 0))
2627 + /* mangle failed, all we can do is bail */
2630 + get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2631 + ptran = ptcp+tranoff;
2633 + nextparamoff -= diff;
2634 + nextfieldoff -= diff;
2638 + off = nextfieldoff;
2645 + while (off < nextparamoff)
2647 + const char* pfieldend;
2648 + uint nextfieldoff;
2650 + pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2651 + nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2653 + if (strncmp(ptran+off, "client_port=", 12) == 0)
2659 + char* rbuf = rbuf1;
2660 + uint rbuflen = rbuf1len;
2663 + origoff = (ptran-ptcp)+off;
2665 + numlen = nf_strtou16(ptran+off, &port);
2667 + origlen += numlen;
2668 + if (port != prtspexp->loport)
2670 + DEBUGP("multiple ports found, port %hu ignored\n", port);
2674 + if (ptran[off] == '-' || ptran[off] == '/')
2678 + numlen = nf_strtou16(ptran+off, &port);
2680 + origlen += numlen;
2682 + rbuflen = rbufalen;
2686 + * note we cannot just memcpy() if the sizes are the same.
2687 + * the mangle function does skb resizing, checks for a
2688 + * cloned skb, and updates the checksums.
2690 + * parameter 4 below is offset from start of tcp data.
2692 + diff = origlen-rbuflen;
2693 + if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
2694 + origoff, origlen, rbuf, rbuflen))
2696 + /* mangle failed, all we can do is bail */
2699 + get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2700 + ptran = ptcp+tranoff;
2702 + nextparamoff -= diff;
2703 + nextfieldoff -= diff;
2707 + off = nextfieldoff;
2710 + off = nextparamoff;
2716 +static unsigned int
2717 +expected(struct sk_buff **pskb, uint hooknum, struct ip_conntrack* ct, struct ip_nat_info* info)
2719 + struct ip_nat_multi_range mr;
2720 + u_int32_t newdstip, newsrcip, newip;
2722 + struct ip_conntrack *master = master_ct(ct);
2724 + IP_NF_ASSERT(info);
2725 + IP_NF_ASSERT(master);
2727 + IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
2729 + newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
2730 + newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
2731 + newip = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ? newsrcip : newdstip;
2733 + DEBUGP("newsrcip=%u.%u.%u.%u, newdstip=%u.%u.%u.%u, newip=%u.%u.%u.%u\n",
2734 + NIPQUAD(newsrcip), NIPQUAD(newdstip), NIPQUAD(newip));
2737 + /* We don't want to manip the per-protocol, just the IPs. */
2738 + mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
2739 + mr.range[0].min_ip = mr.range[0].max_ip = newip;
2741 + return ip_nat_setup_info(ct, &mr, hooknum);
2745 +help_out(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2746 + struct ip_conntrack_expect* exp, struct sk_buff** pskb)
2756 + struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
2757 + struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4);
2759 + struct ip_ct_rtsp_expect* prtspexp = &exp->help.exp_rtsp_info;
2761 + get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2763 + hdrsoff = exp->seq - ntohl(tcph->seq);
2764 + hdrslen = prtspexp->len;
2767 + while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen))
2773 + if (off > hdrsoff+hdrslen)
2775 + INFOP("!! overrun !!");
2778 + DEBUGP("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
2780 + if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0)
2782 + uint oldtcplen = tcplen;
2783 + if (!rtsp_mangle_tran(ct, ctinfo, exp, pskb, lineoff, linelen))
2787 + get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2788 + hdrslen -= (oldtcplen-tcplen);
2789 + off -= (oldtcplen-tcplen);
2790 + lineoff -= (oldtcplen-tcplen);
2791 + linelen -= (oldtcplen-tcplen);
2792 + DEBUGP("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
2800 +help_in(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2801 + struct ip_conntrack_expect* exp, struct sk_buff** pskb)
2803 + /* XXX: unmangle */
2808 +help(struct ip_conntrack* ct,
2809 + struct ip_conntrack_expect* exp,
2810 + struct ip_nat_info* info,
2811 + enum ip_conntrack_info ctinfo,
2812 + unsigned int hooknum,
2813 + struct sk_buff** pskb)
2815 + struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
2816 + struct tcphdr* tcph = (struct tcphdr*)((char*)iph + iph->ihl * 4);
2819 + struct ip_ct_rtsp_expect* ct_rtsp_info;
2820 + int rc = NF_ACCEPT;
2822 + if (ct == NULL || exp == NULL || info == NULL || pskb == NULL)
2824 + DEBUGP("!! null ptr (%p,%p,%p,%p) !!\n", ct, exp, info, pskb);
2828 + ct_rtsp_info = &exp->help.exp_rtsp_info;
2831 + * Only mangle things once: original direction in POST_ROUTING
2832 + * and reply direction on PRE_ROUTING.
2834 + dir = CTINFO2DIR(ctinfo);
2835 + if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
2836 + || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
2838 + DEBUGP("Not touching dir %s at hook %s\n",
2839 + dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
2840 + hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
2841 + : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
2842 + : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
2845 + DEBUGP("got beyond not touching\n");
2847 + datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
2849 + LOCK_BH(&ip_rtsp_lock);
2850 + /* Ensure the packet contains all of the marked data */
2851 + if (!between(exp->seq + ct_rtsp_info->len,
2852 + ntohl(tcph->seq), ntohl(tcph->seq) + datalen))
2854 + /* Partial retransmission? Probably a hacker. */
2855 + if (net_ratelimit())
2857 + INFOP("partial packet %u/%u in %u/%u\n",
2858 + exp->seq, ct_rtsp_info->len, ntohl(tcph->seq), ntohl(tcph->seq) + datalen);
2860 + UNLOCK_BH(&ip_rtsp_lock);
2866 + case IP_CT_DIR_ORIGINAL:
2867 + rc = help_out(ct, ctinfo, exp, pskb);
2869 + case IP_CT_DIR_REPLY:
2870 + rc = help_in(ct, ctinfo, exp, pskb);
2875 + UNLOCK_BH(&ip_rtsp_lock);
2880 +static struct ip_nat_helper ip_nat_rtsp_helpers[MAX_PORTS];
2881 +static char rtsp_names[MAX_PORTS][10];
2883 +/* This function is intentionally _NOT_ defined as __exit */
2889 + for (i = 0; i < num_ports; i++)
2891 + DEBUGP("unregistering helper for port %d\n", ports[i]);
2892 + ip_nat_helper_unregister(&ip_nat_rtsp_helpers[i]);
2901 + struct ip_nat_helper* hlpr;
2904 + printk("ip_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n");
2906 + if (ports[0] == 0)
2908 + ports[0] = RTSP_PORT;
2911 + for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++)
2913 + hlpr = &ip_nat_rtsp_helpers[i];
2914 + memset(hlpr, 0, sizeof(struct ip_nat_helper));
2916 + hlpr->tuple.dst.protonum = IPPROTO_TCP;
2917 + hlpr->tuple.src.u.tcp.port = htons(ports[i]);
2918 + hlpr->mask.src.u.tcp.port = 0xFFFF;
2919 + hlpr->mask.dst.protonum = 0xFFFF;
2920 + hlpr->help = help;
2922 + hlpr->me = THIS_MODULE;
2923 + hlpr->expect = expected;
2925 + tmpname = &rtsp_names[i][0];
2926 + if (ports[i] == RTSP_PORT)
2928 + sprintf(tmpname, "rtsp");
2932 + sprintf(tmpname, "rtsp-%d", i);
2934 + hlpr->name = tmpname;
2936 + DEBUGP("registering helper for port %d: name %s\n", ports[i], hlpr->name);
2937 + ret = ip_nat_helper_register(hlpr);
2941 + printk("ip_nat_rtsp: error registering helper for port %d\n", ports[i]);
2947 + if (stunaddr != NULL)
2949 + extip = in_aton(stunaddr);
2951 + if (destaction != NULL)
2953 + if (strcmp(destaction, "auto") == 0)
2955 + dstact = DSTACT_AUTO;
2957 + if (strcmp(destaction, "strip") == 0)
2959 + dstact = DSTACT_STRIP;
2961 + if (strcmp(destaction, "none") == 0)
2963 + dstact = DSTACT_NONE;
2971 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_tables.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_tables.c
2972 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_tables.c 2004-03-16 05:45:50.000000000 +0000
2973 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_tables.c 2004-03-16 12:04:36.000000000 +0000
2975 * it under the terms of the GNU General Public License version 2 as
2976 * published by the Free Software Foundation.
2978 + * 6 Mar 2002 Robert Olsson <robban@robtex.com>
2979 + * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
2980 + * - mark_source_chains speedup for complex chains
2982 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
2983 * - increase module usage count as soon as we have rules inside
2989 + /* keep track of where we have been: */
2990 + unsigned char *been = vmalloc(newinfo->size);
2992 /* No recursion; use packet counter to save back ptrs (reset
2993 to 0 as we leave), and comefrom to save source hook bitmask */
2994 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
2997 /* Set initial back pointer. */
2998 e->counters.pcnt = pos;
2999 + memset(been, 0, newinfo->size);
3002 struct ipt_standard_target *t
3004 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
3005 printk("iptables: loop hook %u pos %u %08X.\n",
3006 hook, pos, e->comefrom);
3011 @@ -565,10 +574,14 @@
3013 int newpos = t->verdict;
3015 - if (strcmp(t->target.u.user.name,
3016 + if ( (pos < 0 || pos >= newinfo->size
3018 + && strcmp(t->target.u.user.name,
3019 IPT_STANDARD_TARGET) == 0
3021 /* This a jump; chase it. */
3022 + if (pos >= 0 && pos < newinfo->size)
3024 duprintf("Jump rule %u -> %u\n",
3029 duprintf("Finished chain %u\n", hook);
3035 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_CONNMARK.c
3036 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 00:00:00.000000000 +0000
3037 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_CONNMARK.c 2004-03-16 12:04:09.000000000 +0000
3039 +/* This kernel module is used to modify the connection mark values, or
3040 + * to optionally restore the skb nfmark from the connection mark
3042 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
3043 + * by Henrik Nordstrom <hno@marasystems.com>
3045 + * This program is free software; you can redistribute it and/or modify
3046 + * it under the terms of the GNU General Public License as published by
3047 + * the Free Software Foundation; either version 2 of the License, or
3048 + * (at your option) any later version.
3050 + * This program is distributed in the hope that it will be useful,
3051 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3052 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3053 + * GNU General Public License for more details.
3055 + * You should have received a copy of the GNU General Public License
3056 + * along with this program; if not, write to the Free Software
3057 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3059 +#include <linux/module.h>
3060 +#include <linux/skbuff.h>
3061 +#include <linux/ip.h>
3062 +#include <net/checksum.h>
3064 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
3065 +MODULE_DESCRIPTION("IP tables CONNMARK matching module");
3066 +MODULE_LICENSE("GPL");
3068 +#include <linux/netfilter_ipv4/ip_tables.h>
3069 +#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
3070 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3072 +static unsigned int
3073 +target(struct sk_buff **pskb,
3074 + const struct net_device *in,
3075 + const struct net_device *out,
3076 + unsigned int hooknum,
3077 + const void *targinfo,
3080 + const struct ipt_connmark_target_info *markinfo = targinfo;
3081 + unsigned long diff;
3082 + unsigned long nfmark;
3083 + unsigned long newmark;
3085 + enum ip_conntrack_info ctinfo;
3086 + struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
3088 + switch(markinfo->mode) {
3089 + case IPT_CONNMARK_SET:
3090 + newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
3091 + if (newmark != ct->mark)
3092 + ct->mark = newmark;
3094 + case IPT_CONNMARK_SAVE:
3095 + newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
3096 + if (ct->mark != newmark)
3097 + ct->mark = newmark;
3099 + case IPT_CONNMARK_RESTORE:
3100 + nfmark = (*pskb)->nfmark;
3101 + diff = (ct->mark ^ nfmark & markinfo->mask);
3103 + (*pskb)->nfmark = nfmark ^ diff;
3104 + (*pskb)->nfcache |= NFC_ALTERED;
3110 + return IPT_CONTINUE;
3114 +checkentry(const char *tablename,
3115 + const struct ipt_entry *e,
3117 + unsigned int targinfosize,
3118 + unsigned int hook_mask)
3120 + struct ipt_connmark_target_info *matchinfo = targinfo;
3121 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
3122 + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
3124 + IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
3128 + if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
3129 + if (strcmp(tablename, "mangle") != 0) {
3130 + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
3138 +static struct ipt_target ipt_connmark_reg = {
3139 + .name = "CONNMARK",
3140 + .target = &target,
3141 + .checkentry = &checkentry,
3145 +static int __init init(void)
3147 + return ipt_register_target(&ipt_connmark_reg);
3150 +static void __exit fini(void)
3152 + ipt_unregister_target(&ipt_connmark_reg);
3157 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPMARK.c
3158 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 00:00:00.000000000 +0000
3159 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPMARK.c 2004-03-16 12:04:10.000000000 +0000
3161 +/* This is a module which is used for setting the NFMARK field of an skb. */
3162 +#include <linux/module.h>
3163 +#include <linux/skbuff.h>
3164 +#include <linux/ip.h>
3165 +#include <net/checksum.h>
3167 +#include <linux/netfilter_ipv4/ip_tables.h>
3168 +#include <linux/netfilter_ipv4/ipt_IPMARK.h>
3170 +MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
3171 +MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
3172 +MODULE_LICENSE("GPL");
3174 +static unsigned int
3175 +target(struct sk_buff **pskb,
3176 + const struct net_device *in,
3177 + const struct net_device *out,
3178 + unsigned int hooknum,
3179 + const void *targinfo,
3182 + const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
3183 + struct iphdr *iph = (*pskb)->nh.iph;
3184 + unsigned long mark;
3186 + if (ipmarkinfo->addr == IPT_IPMARK_SRC)
3187 + mark = (unsigned long) ntohl(iph->saddr);
3189 + mark = (unsigned long) ntohl(iph->daddr);
3191 + mark &= ipmarkinfo->andmask;
3192 + mark |= ipmarkinfo->ormask;
3194 + if ((*pskb)->nfmark != mark) {
3195 + (*pskb)->nfmark = mark;
3196 + (*pskb)->nfcache |= NFC_ALTERED;
3198 + return IPT_CONTINUE;
3202 +checkentry(const char *tablename,
3203 + const struct ipt_entry *e,
3205 + unsigned int targinfosize,
3206 + unsigned int hook_mask)
3208 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
3209 + printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
3211 + IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
3215 + if (strcmp(tablename, "mangle") != 0) {
3216 + printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
3223 +static struct ipt_target ipt_ipmark_reg = {
3226 + .checkentry = checkentry,
3230 +static int __init init(void)
3232 + return ipt_register_target(&ipt_ipmark_reg);
3235 +static void __exit fini(void)
3237 + ipt_unregister_target(&ipt_ipmark_reg);
3242 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_XOR.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_XOR.c
3243 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 00:00:00.000000000 +0000
3244 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_XOR.c 2004-03-16 12:04:18.000000000 +0000
3246 +/* XOR target for IP tables
3247 + * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
3248 + * Based on ipt_TTL.c
3252 + * This software is distributed under the terms of GNU GPL
3255 +#include <linux/module.h>
3256 +#include <linux/skbuff.h>
3257 +#include <linux/ip.h>
3258 +#include <linux/tcp.h>
3259 +#include <linux/udp.h>
3261 +#include <linux/netfilter_ipv4/ip_tables.h>
3262 +#include <linux/netfilter_ipv4/ipt_XOR.h>
3264 +MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
3265 +MODULE_DESCRIPTION("IP tables XOR module");
3266 +MODULE_LICENSE("GPL");
3268 +static unsigned int
3269 +ipt_xor_target(struct sk_buff **pskb,
3270 + const struct net_device *in, const struct net_device *out,
3271 + unsigned int hooknum, const void *targinfo, void *userinfo)
3273 + struct ipt_XOR_info *info = (void *) targinfo;
3274 + struct iphdr *iph;
3275 + struct tcphdr *tcph;
3276 + struct udphdr *udph;
3279 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
3282 + iph = (*pskb)->nh.iph;
3284 + if (iph->protocol == IPPROTO_TCP) {
3285 + tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
3286 + for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
3287 + for (k=0; k<=info->block_size; k++) {
3288 + (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
3293 + if (info->key[j] == 0x00)
3296 + } else if (iph->protocol == IPPROTO_UDP) {
3297 + udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
3298 + for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
3299 + for (k=0; k<=info->block_size; k++) {
3300 + (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
3305 + if (info->key[j] == 0x00)
3310 + return IPT_CONTINUE;
3313 +static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
3314 + void *targinfo, unsigned int targinfosize,
3315 + unsigned int hook_mask)
3317 + struct ipt_XOR_info *info = targinfo;
3319 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
3320 + printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
3321 + targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
3325 + if (strcmp(tablename, "mangle")) {
3326 + printk(KERN_WARNING "XOR: can only be called from"
3327 + "\"mangle\" table, not \"%s\"\n", tablename);
3331 + if (!strcmp(info->key, "")) {
3332 + printk(KERN_WARNING "XOR: You must specify a key");
3336 + if (info->block_size == 0) {
3337 + printk(KERN_WARNING "XOR: You must specify a block-size");
3344 +static struct ipt_target ipt_XOR = {
3346 + .target = ipt_xor_target,
3347 + .checkentry = ipt_xor_checkentry,
3348 + .me = THIS_MODULE,
3351 +static int __init init(void)
3353 + return ipt_register_target(&ipt_XOR);
3356 +static void __exit fini(void)
3358 + ipt_unregister_target(&ipt_XOR);
3363 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_addrtype.c
3364 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 00:00:00.000000000 +0000
3365 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_addrtype.c 2004-03-16 12:04:20.000000000 +0000
3368 + * iptables module to match inet_addr_type() of an ip.
3371 +#include <linux/module.h>
3372 +#include <linux/skbuff.h>
3373 +#include <linux/netdevice.h>
3374 +#include <net/route.h>
3376 +#include <linux/netfilter_ipv4/ipt_addrtype.h>
3377 +#include <linux/netfilter_ipv4/ip_tables.h>
3379 +MODULE_LICENSE("GPL");
3381 +static inline int match_type(u_int32_t addr, u_int16_t mask)
3383 + return !!(mask & (1 << inet_addr_type(addr)));
3386 +static int match(const struct sk_buff *skb, const struct net_device *in,
3387 + const struct net_device *out, const void *matchinfo,
3388 + int offset, int *hotdrop)
3390 + const struct ipt_addrtype_info *info = matchinfo;
3391 + const struct iphdr *iph = skb->nh.iph;
3395 + ret &= match_type(iph->saddr, info->source)^info->invert_source;
3397 + ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
3402 +static int checkentry(const char *tablename, const struct ipt_ip *ip,
3403 + void *matchinfo, unsigned int matchsize,
3404 + unsigned int hook_mask)
3406 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
3407 + printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
3408 + matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
3415 +static struct ipt_match addrtype_match = {
3416 + .name = "addrtype",
3418 + .checkentry = checkentry,
3422 +static int __init init(void)
3424 + return ipt_register_match(&addrtype_match);
3427 +static void __exit fini(void)
3429 + ipt_unregister_match(&addrtype_match);
3435 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connmark.c
3436 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 00:00:00.000000000 +0000
3437 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connmark.c 2004-03-16 12:04:09.000000000 +0000
3439 +/* This kernel module matches connection mark values set by the
3442 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
3443 + * by Henrik Nordstrom <hno@marasystems.com>
3445 + * This program is free software; you can redistribute it and/or modify
3446 + * it under the terms of the GNU General Public License as published by
3447 + * the Free Software Foundation; either version 2 of the License, or
3448 + * (at your option) any later version.
3450 + * This program is distributed in the hope that it will be useful,
3451 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3452 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3453 + * GNU General Public License for more details.
3455 + * You should have received a copy of the GNU General Public License
3456 + * along with this program; if not, write to the Free Software
3457 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3460 +#include <linux/module.h>
3461 +#include <linux/skbuff.h>
3463 +MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
3464 +MODULE_DESCRIPTION("IP tables connmark match module");
3465 +MODULE_LICENSE("GPL");
3467 +#include <linux/netfilter_ipv4/ip_tables.h>
3468 +#include <linux/netfilter_ipv4/ipt_connmark.h>
3469 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3472 +match(const struct sk_buff *skb,
3473 + const struct net_device *in,
3474 + const struct net_device *out,
3475 + const void *matchinfo,
3479 + const struct ipt_connmark_info *info = matchinfo;
3480 + enum ip_conntrack_info ctinfo;
3481 + struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3485 + return ((ct->mark & info->mask) == info->mark) ^ info->invert;
3489 +checkentry(const char *tablename,
3490 + const struct ipt_ip *ip,
3492 + unsigned int matchsize,
3493 + unsigned int hook_mask)
3495 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
3501 +static struct ipt_match connmark_match = {
3502 + .name = "connmark",
3504 + .checkentry = &checkentry,
3508 +static int __init init(void)
3510 + return ipt_register_match(&connmark_match);
3513 +static void __exit fini(void)
3515 + ipt_unregister_match(&connmark_match);
3520 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_owner.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_owner.c
3521 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_owner.c 2004-03-16 05:47:19.000000000 +0000
3522 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_owner.c 2004-03-16 12:04:38.000000000 +0000
3524 * This program is free software; you can redistribute it and/or modify
3525 * it under the terms of the GNU General Public License version 2 as
3526 * published by the Free Software Foundation.
3528 + * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
3531 #include <linux/module.h>
3532 #include <linux/skbuff.h>
3533 #include <linux/file.h>
3534 +#include <linux/ip.h>
3535 +#include <linux/tcp.h>
3536 +#include <linux/udp.h>
3537 #include <net/sock.h>
3538 +#include <net/tcp.h>
3539 +#include <net/udp.h>
3541 #include <linux/netfilter_ipv4/ipt_owner.h>
3542 #include <linux/netfilter_ipv4/ip_tables.h>
3544 MODULE_DESCRIPTION("iptables owner match");
3547 -match_comm(const struct sk_buff *skb, const char *comm)
3548 +match_comm(const struct sock *sk, const char *comm)
3550 struct task_struct *g, *p;
3551 struct files_struct *files;
3553 spin_lock(&files->file_lock);
3554 for (i=0; i < files->max_fds; i++) {
3555 if (fcheck_files(files, i) ==
3556 - skb->sk->sk_socket->file) {
3557 + sk->sk_socket->file) {
3558 spin_unlock(&files->file_lock);
3560 read_unlock(&tasklist_lock);
3565 -match_pid(const struct sk_buff *skb, pid_t pid)
3566 +match_pid(const struct sock *sk, pid_t pid)
3568 struct task_struct *p;
3569 struct files_struct *files;
3571 spin_lock(&files->file_lock);
3572 for (i=0; i < files->max_fds; i++) {
3573 if (fcheck_files(files, i) ==
3574 - skb->sk->sk_socket->file) {
3575 + sk->sk_socket->file) {
3576 spin_unlock(&files->file_lock);
3578 read_unlock(&tasklist_lock);
3583 -match_sid(const struct sk_buff *skb, pid_t sid)
3584 +match_sid(const struct sock *sk, pid_t sid)
3586 struct task_struct *g, *p;
3587 - struct file *file = skb->sk->sk_socket->file;
3588 + struct file *file = sk->sk_socket->file;
3591 read_lock(&tasklist_lock);
3592 @@ -129,41 +136,71 @@
3595 const struct ipt_owner_info *info = matchinfo;
3596 + struct iphdr *iph = skb->nh.iph;
3597 + struct sock *sk = NULL;
3603 + if (iph->protocol == IPPROTO_TCP) {
3604 + struct tcphdr *tcph =
3605 + (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
3606 + sk = tcp_v4_lookup(iph->saddr, tcph->source,
3607 + iph->daddr, tcph->dest,
3608 + skb->dev->ifindex);
3609 + if (sk && sk->sk_state == TCP_TIME_WAIT) {
3610 + tcp_tw_put((struct tcp_tw_bucket *)sk);
3613 + } else if (iph->protocol == IPPROTO_UDP) {
3614 + struct udphdr *udph =
3615 + (struct udphdr *)((u_int32_t *)iph + iph->ihl);
3616 + sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
3617 + udph->dest, skb->dev->ifindex);
3621 - if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
3623 + if (!sk || !sk->sk_socket || !sk->sk_socket->file)
3626 if(info->match & IPT_OWNER_UID) {
3627 - if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
3628 + if ((sk->sk_socket->file->f_uid != info->uid) ^
3629 !!(info->invert & IPT_OWNER_UID))
3634 if(info->match & IPT_OWNER_GID) {
3635 - if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
3636 + if ((sk->sk_socket->file->f_gid != info->gid) ^
3637 !!(info->invert & IPT_OWNER_GID))
3642 if(info->match & IPT_OWNER_PID) {
3643 - if (!match_pid(skb, info->pid) ^
3644 + if (!match_pid(sk, info->pid) ^
3645 !!(info->invert & IPT_OWNER_PID))
3650 if(info->match & IPT_OWNER_SID) {
3651 - if (!match_sid(skb, info->sid) ^
3652 + if (!match_sid(sk, info->sid) ^
3653 !!(info->invert & IPT_OWNER_SID))
3658 if(info->match & IPT_OWNER_COMM) {
3659 - if (!match_comm(skb, info->comm) ^
3660 + if (!match_comm(sk, info->comm) ^
3661 !!(info->invert & IPT_OWNER_COMM))
3677 @@ -173,11 +210,19 @@
3678 unsigned int matchsize,
3679 unsigned int hook_mask)
3682 - & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
3683 - printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
3687 + & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
3688 + (1 << NF_IP_LOCAL_IN))) {
3689 + printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
3690 + "or POST_ROUTING.\n");
3694 + if ((hook_mask & (1 << NF_IP_LOCAL_IN))
3695 + && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
3696 + printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
3700 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
3701 printk("Matchsize %u != %Zu\n", matchsize,
3702 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_policy.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_policy.c
3703 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 00:00:00.000000000 +0000
3704 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_policy.c 2004-03-16 12:04:45.000000000 +0000
3706 +/* IP tables module for matching IPsec policy
3708 + * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
3710 + * This program is free software; you can redistribute it and/or modify
3711 + * it under the terms of the GNU General Public License version 2 as
3712 + * published by the Free Software Foundation.
3715 +#include <linux/kernel.h>
3716 +#include <linux/config.h>
3717 +#include <linux/module.h>
3718 +#include <linux/skbuff.h>
3719 +#include <linux/init.h>
3720 +#include <net/xfrm.h>
3722 +#include <linux/netfilter_ipv4.h>
3723 +#include <linux/netfilter_ipv4/ipt_policy.h>
3724 +#include <linux/netfilter_ipv4/ip_tables.h>
3726 +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
3727 +MODULE_DESCRIPTION("IPtables IPsec policy matching module");
3728 +MODULE_LICENSE("GPL");
3732 +match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
3734 +#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
3736 + if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
3737 + MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
3738 + MISMATCH(proto, x->id.proto) ||
3739 + MISMATCH(mode, x->props.mode) ||
3740 + MISMATCH(spi, x->id.spi) ||
3741 + MISMATCH(reqid, x->props.reqid))
3747 +match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
3749 + const struct ipt_policy_elem *e;
3750 + struct sec_path *sp = skb->sp;
3751 + int strict = info->flags & POLICY_MATCH_STRICT;
3756 + if (strict && info->len != sp->len)
3759 + for (i = sp->len - 1; i >= 0; i--) {
3760 + pos = strict ? i - sp->len + 1 : 0;
3761 + if (pos >= info->len)
3763 + e = &info->pol[pos];
3765 + if (match_xfrm_state(sp->x[i].xvec, e)) {
3768 + } else if (strict)
3772 + return strict ? 1 : 0;
3776 +match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
3778 + const struct ipt_policy_elem *e;
3779 + struct dst_entry *dst = skb->dst;
3780 + int strict = info->flags & POLICY_MATCH_STRICT;
3783 + if (dst->xfrm == NULL)
3786 + for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
3787 + pos = strict ? i : 0;
3788 + if (pos >= info->len)
3790 + e = &info->pol[pos];
3792 + if (match_xfrm_state(dst->xfrm, e)) {
3795 + } else if (strict)
3799 + return strict ? 1 : 0;
3802 +static int match(const struct sk_buff *skb,
3803 + const struct net_device *in,
3804 + const struct net_device *out,
3805 + const void *matchinfo, int offset, int *hotdrop)
3807 + const struct ipt_policy_info *info = matchinfo;
3810 + if (info->flags & POLICY_MATCH_IN)
3811 + ret = match_policy_in(skb, info);
3813 + ret = match_policy_out(skb, info);
3816 + if (info->flags & POLICY_MATCH_NONE)
3820 + } else if (info->flags & POLICY_MATCH_NONE)
3826 +static int checkentry(const char *tablename, const struct ipt_ip *ip,
3827 + void *matchinfo, unsigned int matchsize,
3828 + unsigned int hook_mask)
3830 + struct ipt_policy_info *info = matchinfo;
3832 + if (matchsize != IPT_ALIGN(sizeof(*info))) {
3833 + printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
3834 + matchsize, IPT_ALIGN(sizeof(*info)));
3837 + if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
3838 + printk(KERN_ERR "ipt_policy: neither incoming nor "
3839 + "outgoing policy selected\n");
3842 + if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
3843 + && info->flags & POLICY_MATCH_OUT) {
3844 + printk(KERN_ERR "ipt_policy: output policy not valid in "
3845 + "PRE_ROUTING and INPUT\n");
3848 + if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
3849 + && info->flags & POLICY_MATCH_IN) {
3850 + printk(KERN_ERR "ipt_policy: input policy not valid in "
3851 + "POST_ROUTING and OUTPUT\n");
3854 + if (info->len > POLICY_MAX_ELEM) {
3855 + printk(KERN_ERR "ipt_policy: too many policy elements\n");
3862 +static struct ipt_match policy_match =
3866 + .checkentry = checkentry,
3867 + .me = THIS_MODULE,
3870 +static int __init init(void)
3872 + return ipt_register_match(&policy_match);
3875 +static void __exit fini(void)
3877 + ipt_unregister_match(&policy_match);
3882 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_rpc.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_rpc.c
3883 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_rpc.c 1970-01-01 00:00:00.000000000 +0000
3884 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_rpc.c 2004-03-16 12:04:46.000000000 +0000
3886 +/* RPC extension for IP connection matching, Version 2.2
3887 + * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
3888 + * - original rpc tracking module
3889 + * - "recent" connection handling for kernel 2.3+ netfilter
3891 + * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
3892 + * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
3894 + * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
3895 + * - upgraded conntrack modules to newnat api - kernel 2.4.20+
3896 + * - extended matching to support filtering on procedures
3898 + * ipt_rpc.c,v 2.2 2003/01/12 18:30:00
3900 + * This program is free software; you can redistribute it and/or
3901 + * modify it under the terms of the GNU General Public License
3902 + * as published by the Free Software Foundation; either version
3903 + * 2 of the License, or (at your option) any later version.
3905 + * Module load syntax:
3906 + * insmod ipt_rpc.o ports=port1,port2,...port<MAX_PORTS>
3908 + * Please give the ports of all RPC servers you wish to connect to.
3909 + * If you don't specify ports, the default will be port 111.
3913 + * RPCs should not be exposed to the internet - ask the Pentagon;
3915 + * "The unidentified crackers pleaded guilty in July to charges
3916 + * of juvenile delinquency stemming from a string of Pentagon
3917 + * network intrusions in February.
3919 + * The youths, going by the names TooShort and Makaveli, used
3920 + * a common server security hole to break in, according to
3921 + * Dane Jasper, owner of the California Internet service
3922 + * provider, Sonic. They used the hole, known as the 'statd'
3923 + * exploit, to attempt more than 800 break-ins, Jasper said."
3925 + * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
3926 + * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
3930 +#include <linux/module.h>
3931 +#include <linux/skbuff.h>
3932 +#include <linux/list.h>
3933 +#include <linux/udp.h>
3934 +#include <linux/tcp.h>
3935 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3936 +#include <linux/netfilter_ipv4/ip_tables.h>
3937 +#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
3938 +#include <linux/netfilter_ipv4/lockhelp.h>
3939 +#include <linux/netfilter_ipv4/ipt_rpc.h>
3941 +#define MAX_PORTS 8
3942 +static int ports[MAX_PORTS];
3943 +static int ports_n_c = 0;
3946 +MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
3947 +MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
3950 +MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
3951 +MODULE_DESCRIPTION("RPC connection matching module");
3952 +MODULE_LICENSE("GPL");
3955 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ipt_rpc: " \
3958 +#define DEBUGP(format, args...)
3963 +/* vars from ip_conntrack_rpc_tcp */
3964 +extern struct list_head request_p_list_tcp;
3965 +extern struct module *ip_conntrack_rpc_tcp;
3967 +/* vars from ip_conntrack_rpc_udp */
3968 +extern struct list_head request_p_list_udp;
3969 +extern struct module *ip_conntrack_rpc_udp;
3971 +DECLARE_RWLOCK_EXTERN(ipct_rpc_tcp_lock);
3972 +DECLARE_RWLOCK_EXTERN(ipct_rpc_udp_lock);
3974 +#define ASSERT_READ_LOCK(x) \
3976 + if (x == &request_p_list_udp) \
3977 + MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock); \
3978 + else if (x == &request_p_list_tcp) \
3979 + MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock); \
3982 +#define ASSERT_WRITE_LOCK(x) \
3984 + if (x == &request_p_list_udp) \
3985 + MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock); \
3986 + else if (x == &request_p_list_tcp) \
3987 + MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock); \
3990 +#include <linux/netfilter_ipv4/listhelp.h>
3992 +const int IPT_RPC_CHAR_LEN = 11;
3995 +static int k_atoi(char *string)
3997 + unsigned int result = 0;
3998 + int maxoctet = IPT_RPC_CHAR_LEN;
4000 + for ( ; *string != 0 && maxoctet != 0; maxoctet--, string++) {
4005 + if (*string < 48 || *string > 57) {
4008 + result = result * 10 + ( *string - 48 );
4014 +static int match_rpcs(char *c_procs, int i_procs, int proc)
4018 + unsigned int proc_num;
4020 + DEBUGP("entered match_rpcs [%i] [%i] ..\n", i_procs, proc);
4022 + if (i_procs == -1)
4025 + for (proc_ctr=0; proc_ctr <= i_procs; proc_ctr++) {
4027 + proc_ptr = c_procs;
4028 + proc_ptr += proc_ctr * IPT_RPC_CHAR_LEN;
4029 + proc_num = k_atoi(proc_ptr);
4031 + if (proc_num == proc)
4039 +static int check_rpc_packet(const u_int32_t *data, const void *matchinfo,
4040 + int *hotdrop, int dir, struct ip_conntrack *ct,
4041 + int offset, struct list_head request_p_list)
4043 + const struct ipt_rpc_info *rpcinfo = matchinfo;
4044 + struct request_p *req_p;
4051 + /* This does sanity checking on RPC payloads,
4052 + * and permits only the RPC "get port" (3)
4053 + * in authorised procedures in client
4054 + * communications with the portmapper.
4059 + /* Get RPC requestor */
4060 + if (IXDR_GET_INT32(data) != 3) {
4061 + DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
4062 + if(rpcinfo->strict == 1)
4066 + DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
4070 + /* Jump Credentials and Verfifier */
4071 + data = data + IXDR_GET_INT32(data) + 2;
4072 + data = data + IXDR_GET_INT32(data) + 2;
4074 + /* Get RPC procedure */
4075 + if (match_rpcs((char *)&rpcinfo->c_procs,
4076 + rpcinfo->i_procs, IXDR_GET_INT32(data)) == 0) {
4077 + DEBUGP("RPC packet contains illegal procedure request [%u]. [drop]\n",
4078 + (unsigned int)IXDR_GET_INT32(data));
4080 + /* If the RPC conntrack half entry already exists .. */
4082 + switch (ct->tuplehash[0].tuple.dst.protonum) {
4084 + WRITE_LOCK(&ipct_rpc_udp_lock);
4086 + WRITE_LOCK(&ipct_rpc_tcp_lock);
4088 + req_p = LIST_FIND(&request_p_list, request_p_cmp,
4089 + struct request_p *, xid,
4090 + ct->tuplehash[dir].tuple.src.ip,
4091 + ct->tuplehash[dir].tuple.src.u.all);
4094 + DEBUGP("found req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
4095 + xid, ct->tuplehash[dir].tuple.dst.protonum,
4096 + NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
4097 + ntohs(ct->tuplehash[dir].tuple.src.u.all));
4099 + /* .. remove it */
4100 + if (del_timer(&req_p->timeout))
4101 + req_p->timeout.expires = 0;
4103 + LIST_DELETE(&request_p_list, req_p);
4104 + DEBUGP("RPC req_p removed. [done]\n");
4107 + DEBUGP("no req_p found for xid=%u proto=%u %u.%u.%u.%u:%u\n",
4108 + xid, ct->tuplehash[dir].tuple.dst.protonum,
4109 + NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
4110 + ntohs(ct->tuplehash[dir].tuple.src.u.all));
4113 + switch (ct->tuplehash[0].tuple.dst.protonum) {
4115 + WRITE_UNLOCK(&ipct_rpc_udp_lock);
4117 + WRITE_UNLOCK(&ipct_rpc_tcp_lock);
4120 + if(rpcinfo->strict == 1)
4125 + DEBUGP("RPC packet contains authorised procedure request [%u]. [match]\n",
4126 + (unsigned int)IXDR_GET_INT32(data));
4127 + return (1 && (!offset));
4131 +static int match(const struct sk_buff *skb, const struct net_device *in,
4132 + const struct net_device *out, const void *matchinfo,
4133 + int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
4135 + struct ip_conntrack *ct;
4136 + enum ip_conntrack_info ctinfo;
4137 + const u_int32_t *data;
4138 + enum ip_conntrack_dir dir;
4139 + const struct tcphdr *tcp;
4140 + const struct ipt_rpc_info *rpcinfo = matchinfo;
4141 + int port, portsok;
4145 + DEBUGP("new packet to evaluate ..\n");
4147 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
4149 + DEBUGP("no ct available [skip]\n");
4153 + DEBUGP("ct detected. [cont]\n");
4154 + dir = CTINFO2DIR(ctinfo);
4156 + /* we only want the client to server packets for matching */
4157 + if (dir != IP_CT_DIR_ORIGINAL)
4160 + /* This does sanity checking on UDP or TCP packets,
4161 + * like their respective modules.
4164 + switch (ct->tuplehash[0].tuple.dst.protonum) {
4167 + DEBUGP("PROTO_UDP [cont]\n");
4168 + if (offset == 0 && datalen < sizeof(struct udphdr)) {
4169 + DEBUGP("packet does not contain a complete header. [drop]\n");
4173 + for (port=0,portsok=0; port <= ports_n_c; port++) {
4174 + if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
4179 + if (portsok == 0) {
4180 + DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
4181 + ntohs(ct->tuplehash[dir].tuple.dst.u.all));
4185 + if ((datalen - sizeof(struct udphdr)) != 56) {
4186 + DEBUGP("packet length is not correct for RPC content. [skip]\n");
4187 + if (rpcinfo->strict == 1)
4191 + DEBUGP("packet length is correct. [cont]\n");
4193 + /* Get to the data */
4194 + data = (const u_int32_t *)hdr + 2;
4196 + /* Check the RPC data */
4197 + tval = check_rpc_packet(data, matchinfo, hotdrop,
4199 + request_p_list_udp);
4205 + DEBUGP("PROTO_TCP [cont]\n");
4206 + if (offset == 0 && datalen < sizeof(struct tcphdr)) {
4207 + DEBUGP("packet does not contain a complete header. [drop]\n");
4211 + for (port=0,portsok=0; port <= ports_n_c; port++) {
4212 + if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
4217 + if (portsok == 0) {
4218 + DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
4219 + ntohs(ct->tuplehash[dir].tuple.dst.u.all));
4224 + if (datalen == (tcp->doff * 4)) {
4225 + DEBUGP("packet does not contain any data. [match]\n");
4226 + return (1 && (!offset));
4229 + /* Tests if packet len is ok */
4230 + if ((datalen - (tcp->doff * 4)) != 60) {
4231 + DEBUGP("packet length is not correct for RPC content. [skip]\n");
4232 + if(rpcinfo->strict == 1)
4236 + DEBUGP("packet length is correct. [cont]\n");
4238 + /* Get to the data */
4239 + data = (const u_int32_t *)tcp + tcp->doff + 1;
4241 + /* Check the RPC data */
4242 + tval = check_rpc_packet(data, matchinfo, hotdrop,
4244 + request_p_list_tcp);
4250 + DEBUGP("transport protocol=%u, is not supported [skip]\n",
4251 + ct->tuplehash[0].tuple.dst.protonum);
4256 +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo,
4257 + unsigned int matchsize, unsigned int hook_mask)
4260 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING)
4261 + | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_LOCAL_OUT))) {
4262 + printk("ipt_rpc: only valid for PRE_ROUTING, FORWARD, POST_ROUTING, LOCAL_IN and/or LOCAL_OUT targets.\n");
4266 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rpc_info)))
4273 +static struct ipt_match rpc_match = { { NULL, NULL }, "rpc",
4274 + &match, &checkentry, NULL,
4278 +static int __init init(void)
4282 + DEBUGP("incrementing usage counts\n");
4283 + __MOD_INC_USE_COUNT(ip_conntrack_rpc_udp);
4284 + __MOD_INC_USE_COUNT(ip_conntrack_rpc_tcp);
4286 + /* If no port given, default to standard RPC port */
4287 + if (ports[0] == 0)
4288 + ports[0] = RPC_PORT;
4290 + DEBUGP("registering match [%s] for;\n", rpc_match.name);
4291 + for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
4292 + DEBUGP(" port %i (UDP|TCP);\n", ports[port]);
4296 + return ipt_register_match(&rpc_match);
4300 +static void fini(void)
4302 + DEBUGP("unregistering match\n");
4303 + ipt_unregister_match(&rpc_match);
4305 + DEBUGP("decrementing usage counts\n");
4306 + __MOD_DEC_USE_COUNT(ip_conntrack_rpc_tcp);
4307 + __MOD_DEC_USE_COUNT(ip_conntrack_rpc_udp);
4314 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_string.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_string.c
4315 --- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 00:00:00.000000000 +0000
4316 +++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_string.c 2004-03-16 12:06:26.000000000 +0000
4318 +/* Kernel module to match a string into a packet.
4320 + * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
4323 + * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
4324 + * Fixed SMP re-entrancy problem using per-cpu data areas
4325 + * for the skip/shift tables.
4326 + * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4327 + * Fixed kernel panic, due to overrunning boyer moore string
4328 + * tables. Also slightly tweaked heuristic for deciding what
4329 + * search algo to use.
4330 + * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4331 + * Implemented Boyer Moore Sublinear search algorithm
4332 + * alongside the existing linear search based on memcmp().
4333 + * Also a quick check to decide which method to use on a per
4337 +#include <linux/smp.h>
4338 +#include <linux/module.h>
4339 +#include <linux/skbuff.h>
4340 +#include <linux/file.h>
4341 +#include <net/sock.h>
4343 +#include <linux/netfilter_ipv4/ip_tables.h>
4344 +#include <linux/netfilter_ipv4/ipt_string.h>
4346 +MODULE_LICENSE("GPL");
4348 +struct string_per_cpu {
4354 +struct string_per_cpu *bm_string_data=NULL;
4356 +/* Boyer Moore Sublinear string search - VERY FAST */
4357 +char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
4359 + int M1, right_end, sk, sh;
4362 + int *skip, *shift, *len;
4364 + /* use data suitable for this CPU */
4365 + shift=bm_string_data[smp_processor_id()].shift;
4366 + skip=bm_string_data[smp_processor_id()].skip;
4367 + len=bm_string_data[smp_processor_id()].len;
4369 + /* Setup skip/shift tables */
4370 + M1 = right_end = needle_len-1;
4371 + for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
4372 + for (i = 0; needle[i]; i++) skip[needle[i]] = M1 - i;
4374 + for (i = 1; i < needle_len; i++) {
4375 + for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
4380 + for (i = 1; i < needle_len; i++) shift[i] = needle_len;
4381 + for (i = M1; i > 0; i--) shift[len[i]] = i;
4384 + for (i = 0; i < needle_len; i++) {
4385 + if (len[i] == M1 - i) ended = i;
4386 + if (ended) shift[i] = ended;
4389 + /* Do the search*/
4390 + while (right_end < haystack_len)
4392 + for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
4393 + if (i == needle_len) {
4394 + return haystack+(right_end - M1);
4397 + sk = skip[haystack[right_end - i]];
4399 + right_end = max(right_end - i + sk, right_end + sh);
4405 +/* Linear string search based on memcmp() */
4406 +char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
4408 + char *k = haystack + (haystack_len-needle_len);
4409 + char *t = haystack;
4411 + while ( t <= k ) {
4412 + if (memcmp(t, needle, needle_len) == 0)
4422 +match(const struct sk_buff *skb,
4423 + const struct net_device *in,
4424 + const struct net_device *out,
4425 + const void *matchinfo,
4428 + u_int16_t datalen,
4431 + const struct ipt_string_info *info = matchinfo;
4432 + struct iphdr *ip = skb->nh.iph;
4434 + char *needle, *haystack;
4435 + proc_ipt_search search=search_linear;
4437 + if ( !ip ) return 0;
4439 + /* get lenghts, and validate them */
4441 + hlen=ntohs(ip->tot_len)-(ip->ihl*4);
4442 + if ( nlen > hlen ) return 0;
4444 + needle=(char *)&info->string;
4445 + haystack=(char *)ip+(ip->ihl*4);
4447 + /* The sublinear search comes in to its own
4448 + * on the larger packets */
4449 + if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
4450 + (nlen>IPT_STRING_NEEDLE_THRESH) ) {
4451 + if ( hlen < BM_MAX_HLEN ) {
4452 + search=search_sublinear;
4454 + if (net_ratelimit())
4455 + printk(KERN_INFO "ipt_string: Packet too big "
4456 + "to attempt sublinear string search "
4457 + "(%d bytes)\n", hlen );
4461 + return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
4465 +checkentry(const char *tablename,
4466 + const struct ipt_ip *ip,
4468 + unsigned int matchsize,
4469 + unsigned int hook_mask)
4472 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
4478 +void string_freeup_data(void)
4482 + if ( bm_string_data ) {
4483 + for(c=0; c<smp_num_cpus; c++) {
4484 + if ( bm_string_data[c].shift ) kfree(bm_string_data[c].shift);
4485 + if ( bm_string_data[c].skip ) kfree(bm_string_data[c].skip);
4486 + if ( bm_string_data[c].len ) kfree(bm_string_data[c].len);
4488 + kfree(bm_string_data);
4492 +static struct ipt_match string_match
4493 += { { NULL, NULL }, "string", &match, &checkentry, NULL, THIS_MODULE };
4495 +static int __init init(void)
4501 + tlen=sizeof(struct string_per_cpu)*smp_num_cpus;
4502 + alen=sizeof(int)*BM_MAX_HLEN;
4504 + /* allocate array of structures */
4505 + if ( !(bm_string_data=kmalloc(tlen,GFP_KERNEL)) ) {
4509 + memset(bm_string_data, 0, tlen);
4511 + /* allocate our skip/shift tables */
4512 + for(c=0; c<smp_num_cpus; c++) {
4513 + if ( !(bm_string_data[c].shift=kmalloc(alen, GFP_KERNEL)) )
4515 + if ( !(bm_string_data[c].skip=kmalloc(alen, GFP_KERNEL)) )
4517 + if ( !(bm_string_data[c].len=kmalloc(alen, GFP_KERNEL)) )
4521 + return ipt_register_match(&string_match);
4524 + string_freeup_data();
4528 +static void __exit fini(void)
4530 + ipt_unregister_match(&string_match);
4531 + string_freeup_data();
4536 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c
4537 --- linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c 2004-03-16 05:45:58.000000000 +0000
4538 +++ linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c 2004-03-16 12:04:38.000000000 +0000
4539 @@ -2667,6 +2667,7 @@
4540 EXPORT_SYMBOL(tcp_v4_connect);
4541 EXPORT_SYMBOL(tcp_v4_do_rcv);
4542 EXPORT_SYMBOL(tcp_v4_lookup_listener);
4543 +EXPORT_SYMBOL(tcp_v4_lookup);
4544 EXPORT_SYMBOL(tcp_v4_rebuild_header);
4545 EXPORT_SYMBOL(tcp_v4_remember_stamp);
4546 EXPORT_SYMBOL(tcp_v4_send_check);
4547 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/udp.c linux-2.6.5-rc1/net/ipv4/udp.c
4548 --- linux-2.6.5-rc1.org/net/ipv4/udp.c 2004-03-16 05:45:49.000000000 +0000
4549 +++ linux-2.6.5-rc1/net/ipv4/udp.c 2004-03-16 12:04:38.000000000 +0000
4550 @@ -1543,6 +1543,7 @@
4551 EXPORT_SYMBOL(udp_port_rover);
4552 EXPORT_SYMBOL(udp_prot);
4553 EXPORT_SYMBOL(udp_sendmsg);
4554 +EXPORT_SYMBOL(udp_v4_lookup);
4556 #ifdef CONFIG_PROC_FS
4557 EXPORT_SYMBOL(udp_proc_register);
4558 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_owner.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_owner.c
4559 --- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_owner.c 2004-03-16 05:47:17.000000000 +0000
4560 +++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_owner.c 2004-03-16 12:04:42.000000000 +0000
4562 MODULE_LICENSE("GPL");
4565 +match_comm(const struct sk_buff *skb, const char *comm)
4567 + struct task_struct *p;
4568 + struct files_struct *files;
4571 + read_lock(&tasklist_lock);
4572 + for_each_task(p) {
4573 + if(strncmp(p->comm, comm, sizeof(p->comm)))
4579 + read_lock(&files->file_lock);
4580 + for (i=0; i < files->max_fds; i++) {
4581 + if (fcheck_files(files, i) == skb->sk->socket->file) {
4582 + read_unlock(&files->file_lock);
4584 + read_unlock(&tasklist_lock);
4588 + read_unlock(&files->file_lock);
4592 + read_unlock(&tasklist_lock);
4597 match_pid(const struct sk_buff *skb, pid_t pid)
4599 struct task_struct *p;
4600 @@ -125,6 +157,12 @@
4604 + if(info->match & IP6T_OWNER_COMM) {
4605 + if (!match_comm(skb, info->comm) ^
4606 + !!(info->invert & IP6T_OWNER_COMM))