You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
[NETFILTER]: Remove IPv4 only connection tracking/NAT
Remove the obsolete IPv4 only connection tracking/NAT as scheduled in feature-removal-schedule. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ce18afe57b
commit
587aa64163
+6
-261
@@ -30,188 +30,6 @@ config NF_CONNTRACK_PROC_COMPAT
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
# connection tracking, helpers and protocols
|
||||
config IP_NF_CT_ACCT
|
||||
bool "Connection tracking flow accounting"
|
||||
depends on IP_NF_CONNTRACK
|
||||
help
|
||||
If this option is enabled, the connection tracking code will
|
||||
keep per-flow packet and byte counters.
|
||||
|
||||
Those counters can be used for flow-based accounting or the
|
||||
`connbytes' match.
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
config IP_NF_CONNTRACK_MARK
|
||||
bool 'Connection mark tracking support'
|
||||
depends on IP_NF_CONNTRACK
|
||||
help
|
||||
This option enables support for connection marks, used by the
|
||||
`CONNMARK' target and `connmark' match. Similar to the mark value
|
||||
of packets, but this mark value is kept in the conntrack session
|
||||
instead of the individual packets.
|
||||
|
||||
config IP_NF_CONNTRACK_SECMARK
|
||||
bool 'Connection tracking security mark support'
|
||||
depends on IP_NF_CONNTRACK && NETWORK_SECMARK
|
||||
help
|
||||
This option enables security markings to be applied to
|
||||
connections. Typically they are copied to connections from
|
||||
packets using the CONNSECMARK target and copied back from
|
||||
connections to packets with the same target, with the packets
|
||||
being originally labeled via SECMARK.
|
||||
|
||||
If unsure, say 'N'.
|
||||
|
||||
config IP_NF_CONNTRACK_EVENTS
|
||||
bool "Connection tracking events (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && IP_NF_CONNTRACK
|
||||
help
|
||||
If this option is enabled, the connection tracking code will
|
||||
provide a notifier chain that can be used by other kernel code
|
||||
to get notified about changes in the connection tracking state.
|
||||
|
||||
IF unsure, say `N'.
|
||||
|
||||
config IP_NF_CONNTRACK_NETLINK
|
||||
tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
|
||||
depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK
|
||||
depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
|
||||
depends on IP_NF_NAT=n || IP_NF_NAT
|
||||
help
|
||||
This option enables support for a netlink-based userspace interface
|
||||
|
||||
|
||||
config IP_NF_CT_PROTO_SCTP
|
||||
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
|
||||
depends on IP_NF_CONNTRACK && EXPERIMENTAL
|
||||
help
|
||||
With this option enabled, the connection tracking code will
|
||||
be able to do state tracking on SCTP connections.
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config IP_NF_FTP
|
||||
tristate "FTP protocol support"
|
||||
depends on IP_NF_CONNTRACK
|
||||
help
|
||||
Tracking FTP connections is problematic: special helpers are
|
||||
required for tracking them, and doing masquerading and other forms
|
||||
of Network Address Translation on them.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_IRC
|
||||
tristate "IRC protocol support"
|
||||
depends on IP_NF_CONNTRACK
|
||||
---help---
|
||||
There is a commonly-used extension to IRC called
|
||||
Direct Client-to-Client Protocol (DCC). This enables users to send
|
||||
files to each other, and also chat to each other without the need
|
||||
of a server. DCC Sending is used anywhere you send files over IRC,
|
||||
and DCC Chat is most commonly used by Eggdrop bots. If you are
|
||||
using NAT, this extension will enable you to send files and initiate
|
||||
chats. Note that you do NOT need this extension to get files or
|
||||
have others initiate chats, or everything else in IRC.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_NETBIOS_NS
|
||||
tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
|
||||
depends on IP_NF_CONNTRACK && EXPERIMENTAL
|
||||
help
|
||||
NetBIOS name service requests are sent as broadcast messages from an
|
||||
unprivileged port and responded to with unicast messages to the
|
||||
same port. This make them hard to firewall properly because connection
|
||||
tracking doesn't deal with broadcasts. This helper tracks locally
|
||||
originating NetBIOS name service requests and the corresponding
|
||||
responses. It relies on correct IP address configuration, specifically
|
||||
netmask and broadcast address. When properly configured, the output
|
||||
of "ip address show" should look similar to this:
|
||||
|
||||
$ ip -4 address show eth0
|
||||
4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
|
||||
inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TFTP
|
||||
tristate "TFTP protocol support"
|
||||
depends on IP_NF_CONNTRACK
|
||||
help
|
||||
TFTP connection tracking helper, this is required depending
|
||||
on how restrictive your ruleset is.
|
||||
If you are using a tftp client behind -j SNAT or -j MASQUERADING
|
||||
you will need this.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_AMANDA
|
||||
tristate "Amanda backup protocol support"
|
||||
depends on IP_NF_CONNTRACK
|
||||
select TEXTSEARCH
|
||||
select TEXTSEARCH_KMP
|
||||
help
|
||||
If you are running the Amanda backup package <http://www.amanda.org/>
|
||||
on this machine or machines that will be MASQUERADED through this
|
||||
machine, then you may want to enable this feature. This allows the
|
||||
connection tracking and natting code to allow the sub-channels that
|
||||
Amanda requires for communication of the backup data, messages and
|
||||
index.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_PPTP
|
||||
tristate 'PPTP protocol support'
|
||||
depends on IP_NF_CONNTRACK
|
||||
help
|
||||
This module adds support for PPTP (Point to Point Tunnelling
|
||||
Protocol, RFC2637) connection tracking and NAT.
|
||||
|
||||
If you are running PPTP sessions over a stateful firewall or NAT
|
||||
box, you may want to enable this feature.
|
||||
|
||||
Please note that not all PPTP modes of operation are supported yet.
|
||||
For more info, read top of the file
|
||||
net/ipv4/netfilter/ip_conntrack_pptp.c
|
||||
|
||||
If you want to compile it as a module, say M here and read
|
||||
Documentation/modules.txt. If unsure, say `N'.
|
||||
|
||||
config IP_NF_H323
|
||||
tristate 'H.323 protocol support (EXPERIMENTAL)'
|
||||
depends on IP_NF_CONNTRACK && EXPERIMENTAL
|
||||
help
|
||||
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
|
||||
important VoIP protocols, it is widely used by voice hardware and
|
||||
software including voice gateways, IP phones, Netmeeting, OpenPhone,
|
||||
Gnomemeeting, etc.
|
||||
|
||||
With this module you can support H.323 on a connection tracking/NAT
|
||||
firewall.
|
||||
|
||||
This module supports RAS, Fast Start, H.245 Tunnelling, Call
|
||||
Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
|
||||
whiteboard, file transfer, etc. For more information, please
|
||||
visit http://nath323.sourceforge.net/.
|
||||
|
||||
If you want to compile it as a module, say 'M' here and read
|
||||
Documentation/modules.txt. If unsure, say 'N'.
|
||||
|
||||
config IP_NF_SIP
|
||||
tristate "SIP protocol support (EXPERIMENTAL)"
|
||||
depends on IP_NF_CONNTRACK && EXPERIMENTAL
|
||||
help
|
||||
SIP is an application-layer control protocol that can establish,
|
||||
modify, and terminate multimedia sessions (conferences) such as
|
||||
Internet telephony calls. With the ip_conntrack_sip and
|
||||
the ip_nat_sip modules you can support the protocol on a connection
|
||||
tracking/NATing firewall.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say Y.
|
||||
|
||||
config IP_NF_QUEUE
|
||||
tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
|
||||
help
|
||||
@@ -361,17 +179,6 @@ config IP_NF_TARGET_ULOG
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
# NAT + specific targets: ip_conntrack
|
||||
config IP_NF_NAT
|
||||
tristate "Full NAT"
|
||||
depends on IP_NF_IPTABLES && IP_NF_CONNTRACK
|
||||
help
|
||||
The Full NAT option allows masquerading, port forwarding and other
|
||||
forms of full Network Address Port Translation. It is controlled by
|
||||
the `nat' table in iptables: see the man page for iptables(8).
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
# NAT + specific targets: nf_conntrack
|
||||
config NF_NAT
|
||||
tristate "Full NAT"
|
||||
@@ -383,11 +190,6 @@ config NF_NAT
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_NAT_NEEDED
|
||||
bool
|
||||
depends on IP_NF_NAT
|
||||
default y
|
||||
|
||||
config NF_NAT_NEEDED
|
||||
bool
|
||||
depends on NF_NAT
|
||||
@@ -395,7 +197,7 @@ config NF_NAT_NEEDED
|
||||
|
||||
config IP_NF_TARGET_MASQUERADE
|
||||
tristate "MASQUERADE target support"
|
||||
depends on (NF_NAT || IP_NF_NAT)
|
||||
depends on NF_NAT
|
||||
help
|
||||
Masquerading is a special case of NAT: all outgoing connections are
|
||||
changed to seem to come from a particular interface's address, and
|
||||
@@ -407,7 +209,7 @@ config IP_NF_TARGET_MASQUERADE
|
||||
|
||||
config IP_NF_TARGET_REDIRECT
|
||||
tristate "REDIRECT target support"
|
||||
depends on (NF_NAT || IP_NF_NAT)
|
||||
depends on NF_NAT
|
||||
help
|
||||
REDIRECT is a special case of NAT: all incoming connections are
|
||||
mapped onto the incoming interface's address, causing the packets to
|
||||
@@ -418,7 +220,7 @@ config IP_NF_TARGET_REDIRECT
|
||||
|
||||
config IP_NF_TARGET_NETMAP
|
||||
tristate "NETMAP target support"
|
||||
depends on (NF_NAT || IP_NF_NAT)
|
||||
depends on NF_NAT
|
||||
help
|
||||
NETMAP is an implementation of static 1:1 NAT mapping of network
|
||||
addresses. It maps the network address part, while keeping the host
|
||||
@@ -429,28 +231,13 @@ config IP_NF_TARGET_NETMAP
|
||||
|
||||
config IP_NF_TARGET_SAME
|
||||
tristate "SAME target support"
|
||||
depends on (NF_NAT || IP_NF_NAT)
|
||||
depends on NF_NAT
|
||||
help
|
||||
This option adds a `SAME' target, which works like the standard SNAT
|
||||
target, but attempts to give clients the same IP for all connections.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_NAT_SNMP_BASIC
|
||||
tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && IP_NF_NAT
|
||||
---help---
|
||||
|
||||
This module implements an Application Layer Gateway (ALG) for
|
||||
SNMP payloads. In conjunction with NAT, it allows a network
|
||||
management system to access multiple private networks with
|
||||
conflicting addresses. It works by modifying IP addresses
|
||||
inside SNMP payloads to match IP-layer NAT mapping.
|
||||
|
||||
This is the "basic" form of SNMP-ALG, as described in RFC 2962
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NF_NAT_SNMP_BASIC
|
||||
tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && NF_NAT
|
||||
@@ -477,78 +264,37 @@ config NF_NAT_PROTO_GRE
|
||||
tristate
|
||||
depends on NF_NAT && NF_CT_PROTO_GRE
|
||||
|
||||
config IP_NF_NAT_FTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
|
||||
default IP_NF_NAT && IP_NF_FTP
|
||||
|
||||
config NF_NAT_FTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_FTP
|
||||
|
||||
config IP_NF_NAT_IRC
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
|
||||
default IP_NF_NAT if IP_NF_IRC=y
|
||||
default m if IP_NF_IRC=m
|
||||
|
||||
config NF_NAT_IRC
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_IRC
|
||||
|
||||
config IP_NF_NAT_TFTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
|
||||
default IP_NF_NAT if IP_NF_TFTP=y
|
||||
default m if IP_NF_TFTP=m
|
||||
|
||||
config NF_NAT_TFTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_TFTP
|
||||
|
||||
config IP_NF_NAT_AMANDA
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
|
||||
default IP_NF_NAT if IP_NF_AMANDA=y
|
||||
default m if IP_NF_AMANDA=m
|
||||
|
||||
config NF_NAT_AMANDA
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_AMANDA
|
||||
|
||||
config IP_NF_NAT_PPTP
|
||||
tristate
|
||||
depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
|
||||
default IP_NF_NAT if IP_NF_PPTP=y
|
||||
default m if IP_NF_PPTP=m
|
||||
|
||||
config NF_NAT_PPTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_PPTP
|
||||
select NF_NAT_PROTO_GRE
|
||||
|
||||
config IP_NF_NAT_H323
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
|
||||
default IP_NF_NAT if IP_NF_H323=y
|
||||
default m if IP_NF_H323=m
|
||||
|
||||
config NF_NAT_H323
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
default NF_NAT && NF_CONNTRACK_H323
|
||||
|
||||
config IP_NF_NAT_SIP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
|
||||
default IP_NF_NAT if IP_NF_SIP=y
|
||||
default m if IP_NF_SIP=m
|
||||
|
||||
config NF_NAT_SIP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
@@ -606,9 +352,8 @@ config IP_NF_TARGET_TTL
|
||||
config IP_NF_TARGET_CLUSTERIP
|
||||
tristate "CLUSTERIP target support (EXPERIMENTAL)"
|
||||
depends on IP_NF_MANGLE && EXPERIMENTAL
|
||||
depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
|
||||
select IP_NF_CONNTRACK_MARK if IP_NF_CONNTRACK
|
||||
select NF_CONNTRACK_MARK if NF_CONNTRACK_IPV4
|
||||
depends on NF_CONNTRACK_IPV4
|
||||
select NF_CONNTRACK_MARK
|
||||
help
|
||||
The CLUSTERIP target allows you to build load-balancing clusters of
|
||||
network servers without having a dedicated load-balancing
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Makefile for the netfilter modules on top of IPv4.
|
||||
#
|
||||
|
||||
# objects for the standalone - connection tracking / NAT
|
||||
ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
|
||||
# objects for l3 independent conntrack
|
||||
nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
|
||||
ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
|
||||
@@ -12,53 +10,14 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
|
||||
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
|
||||
ifneq ($(CONFIG_NF_NAT),)
|
||||
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
|
||||
iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
|
||||
else
|
||||
iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
|
||||
endif
|
||||
|
||||
ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
|
||||
ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
|
||||
|
||||
ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ../../netfilter/nf_conntrack_h323_asn1.o
|
||||
ip_nat_h323-objs := ip_nat_helper_h323.o
|
||||
|
||||
# connection tracking
|
||||
obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
|
||||
obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
|
||||
|
||||
obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
|
||||
obj-$(CONFIG_NF_NAT) += nf_nat.o
|
||||
|
||||
# conntrack netlink interface
|
||||
obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
|
||||
|
||||
|
||||
# SCTP protocol connection tracking
|
||||
obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
|
||||
|
||||
# connection tracking helpers
|
||||
obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
|
||||
obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
|
||||
obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
|
||||
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
|
||||
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
|
||||
obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
|
||||
obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
|
||||
obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
|
||||
|
||||
# NAT helpers (ip_conntrack)
|
||||
obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
|
||||
obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
|
||||
obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
|
||||
obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
|
||||
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
|
||||
obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
|
||||
obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
|
||||
|
||||
# NAT helpers (nf_conntrack)
|
||||
obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
|
||||
obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
|
||||
@@ -78,7 +37,6 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
|
||||
# the three instances of ip_tables
|
||||
obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
|
||||
obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
|
||||
obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
|
||||
obj-$(CONFIG_NF_NAT) += iptable_nat.o
|
||||
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
|
||||
|
||||
@@ -100,7 +58,6 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
|
||||
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
/* Amanda extension for IP connection tracking, Version 0.2
|
||||
* (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
|
||||
* based on HW's ip_conntrack_irc.c as well as other modules
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* Module load syntax:
|
||||
* insmod ip_conntrack_amanda.o [master_timeout=n]
|
||||
*
|
||||
* Where master_timeout is the timeout (in seconds) of the master
|
||||
* connection (port 10080). This defaults to 5 minutes but if
|
||||
* your clients take longer than 5 minutes to do their work
|
||||
* before getting back to the Amanda server, you can increase
|
||||
* this value.
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/textsearch.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
|
||||
|
||||
static unsigned int master_timeout = 300;
|
||||
static char *ts_algo = "kmp";
|
||||
|
||||
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
|
||||
MODULE_DESCRIPTION("Amanda connection tracking module");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_param(master_timeout, uint, 0600);
|
||||
MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
|
||||
module_param(ts_algo, charp, 0400);
|
||||
MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
|
||||
|
||||
unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
struct ip_conntrack_expect *exp);
|
||||
EXPORT_SYMBOL_GPL(ip_nat_amanda_hook);
|
||||
|
||||
enum amanda_strings {
|
||||
SEARCH_CONNECT,
|
||||
SEARCH_NEWLINE,
|
||||
SEARCH_DATA,
|
||||
SEARCH_MESG,
|
||||
SEARCH_INDEX,
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *string;
|
||||
size_t len;
|
||||
struct ts_config *ts;
|
||||
} search[] = {
|
||||
[SEARCH_CONNECT] = {
|
||||
.string = "CONNECT ",
|
||||
.len = 8,
|
||||
},
|
||||
[SEARCH_NEWLINE] = {
|
||||
.string = "\n",
|
||||
.len = 1,
|
||||
},
|
||||
[SEARCH_DATA] = {
|
||||
.string = "DATA ",
|
||||
.len = 5,
|
||||
},
|
||||
[SEARCH_MESG] = {
|
||||
.string = "MESG ",
|
||||
.len = 5,
|
||||
},
|
||||
[SEARCH_INDEX] = {
|
||||
.string = "INDEX ",
|
||||
.len = 6,
|
||||
},
|
||||
};
|
||||
|
||||
static int help(struct sk_buff **pskb,
|
||||
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
struct ts_state ts;
|
||||
struct ip_conntrack_expect *exp;
|
||||
unsigned int dataoff, start, stop, off, i;
|
||||
char pbuf[sizeof("65535")], *tmp;
|
||||
u_int16_t port, len;
|
||||
int ret = NF_ACCEPT;
|
||||
typeof(ip_nat_amanda_hook) ip_nat_amanda;
|
||||
|
||||
/* Only look at packets from the Amanda server */
|
||||
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* increase the UDP timeout of the master connection as replies from
|
||||
* Amanda clients to the server can be quite delayed */
|
||||
ip_ct_refresh(ct, *pskb, master_timeout * HZ);
|
||||
|
||||
/* No data? */
|
||||
dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
|
||||
if (dataoff >= (*pskb)->len) {
|
||||
if (net_ratelimit())
|
||||
printk("amanda_help: skblen = %u\n", (*pskb)->len);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
start = skb_find_text(*pskb, dataoff, (*pskb)->len,
|
||||
search[SEARCH_CONNECT].ts, &ts);
|
||||
if (start == UINT_MAX)
|
||||
goto out;
|
||||
start += dataoff + search[SEARCH_CONNECT].len;
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
stop = skb_find_text(*pskb, start, (*pskb)->len,
|
||||
search[SEARCH_NEWLINE].ts, &ts);
|
||||
if (stop == UINT_MAX)
|
||||
goto out;
|
||||
stop += start;
|
||||
|
||||
for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
off = skb_find_text(*pskb, start, stop, search[i].ts, &ts);
|
||||
if (off == UINT_MAX)
|
||||
continue;
|
||||
off += start + search[i].len;
|
||||
|
||||
len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
|
||||
if (skb_copy_bits(*pskb, off, pbuf, len))
|
||||
break;
|
||||
pbuf[len] = '\0';
|
||||
|
||||
port = simple_strtoul(pbuf, &tmp, 10);
|
||||
len = tmp - pbuf;
|
||||
if (port == 0 || len > 5)
|
||||
break;
|
||||
|
||||
exp = ip_conntrack_expect_alloc(ct);
|
||||
if (exp == NULL) {
|
||||
ret = NF_DROP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
exp->expectfn = NULL;
|
||||
exp->flags = 0;
|
||||
|
||||
exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
||||
exp->tuple.src.u.tcp.port = 0;
|
||||
exp->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
||||
exp->tuple.dst.protonum = IPPROTO_TCP;
|
||||
exp->tuple.dst.u.tcp.port = htons(port);
|
||||
|
||||
exp->mask.src.ip = htonl(0xFFFFFFFF);
|
||||
exp->mask.src.u.tcp.port = 0;
|
||||
exp->mask.dst.ip = htonl(0xFFFFFFFF);
|
||||
exp->mask.dst.protonum = 0xFF;
|
||||
exp->mask.dst.u.tcp.port = htons(0xFFFF);
|
||||
|
||||
/* RCU read locked by nf_hook_slow */
|
||||
ip_nat_amanda = rcu_dereference(ip_nat_amanda_hook);
|
||||
if (ip_nat_amanda)
|
||||
ret = ip_nat_amanda(pskb, ctinfo, off - dataoff,
|
||||
len, exp);
|
||||
else if (ip_conntrack_expect_related(exp) != 0)
|
||||
ret = NF_DROP;
|
||||
ip_conntrack_expect_put(exp);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ip_conntrack_helper amanda_helper = {
|
||||
.max_expected = 3,
|
||||
.timeout = 180,
|
||||
.me = THIS_MODULE,
|
||||
.help = help,
|
||||
.name = "amanda",
|
||||
|
||||
.tuple = { .src = { .u = { .udp = {.port = __constant_htons(10080) } } },
|
||||
.dst = { .protonum = IPPROTO_UDP },
|
||||
},
|
||||
.mask = { .src = { .u = { 0xFFFF } },
|
||||
.dst = { .protonum = 0xFF },
|
||||
},
|
||||
};
|
||||
|
||||
static void __exit ip_conntrack_amanda_fini(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
ip_conntrack_helper_unregister(&amanda_helper);
|
||||
for (i = 0; i < ARRAY_SIZE(search); i++)
|
||||
textsearch_destroy(search[i].ts);
|
||||
}
|
||||
|
||||
static int __init ip_conntrack_amanda_init(void)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
ret = -ENOMEM;
|
||||
for (i = 0; i < ARRAY_SIZE(search); i++) {
|
||||
search[i].ts = textsearch_prepare(ts_algo, search[i].string,
|
||||
search[i].len,
|
||||
GFP_KERNEL, TS_AUTOLOAD);
|
||||
if (search[i].ts == NULL)
|
||||
goto err;
|
||||
}
|
||||
ret = ip_conntrack_helper_register(&amanda_helper);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (; i >= 0; i--) {
|
||||
if (search[i].ts)
|
||||
textsearch_destroy(search[i].ts);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
module_init(ip_conntrack_amanda_init);
|
||||
module_exit(ip_conntrack_amanda_fini);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,314 +0,0 @@
|
||||
/* IRC extension for IP connection tracking, Version 1.21
|
||||
* (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
|
||||
* based on RR's ip_conntrack_ftp.c
|
||||
*
|
||||
* ip_conntrack_irc.c,v 1.21 2002/02/05 14:49:26 laforge Exp
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
**
|
||||
* Module load syntax:
|
||||
* insmod ip_conntrack_irc.o ports=port1,port2,...port<MAX_PORTS>
|
||||
* max_dcc_channels=n dcc_timeout=secs
|
||||
*
|
||||
* please give the ports of all IRC servers You wish to connect to.
|
||||
* If You don't specify ports, the default will be port 6667.
|
||||
* With max_dcc_channels you can define the maximum number of not
|
||||
* yet answered DCC channels per IRC session (default 8).
|
||||
* With dcc_timeout you can specify how long the system waits for
|
||||
* an expected DCC channel (default 300 seconds).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/ip.h>
|
||||
#include <net/checksum.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#define MAX_PORTS 8
|
||||
static unsigned short ports[MAX_PORTS];
|
||||
static int ports_c;
|
||||
static unsigned int max_dcc_channels = 8;
|
||||
static unsigned int dcc_timeout = 300;
|
||||
/* This is slow, but it's simple. --RR */
|
||||
static char *irc_buffer;
|
||||
static DEFINE_SPINLOCK(irc_buffer_lock);
|
||||
|
||||
unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
struct ip_conntrack_expect *exp);
|
||||
EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
|
||||
|
||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_param_array(ports, ushort, &ports_c, 0400);
|
||||
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
|
||||
module_param(max_dcc_channels, uint, 0400);
|
||||
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
|
||||
module_param(dcc_timeout, uint, 0400);
|
||||
MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
|
||||
|
||||
static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
|
||||
#define MINMATCHLEN 5
|
||||
|
||||
#if 0
|
||||
#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
|
||||
__FILE__, __FUNCTION__ , ## args)
|
||||
#else
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
static int parse_dcc(char *data, char *data_end, u_int32_t *ip,
|
||||
u_int16_t *port, char **ad_beg_p, char **ad_end_p)
|
||||
/* tries to get the ip_addr and port out of a dcc command
|
||||
return value: -1 on failure, 0 on success
|
||||
data pointer to first byte of DCC command data
|
||||
data_end pointer to last byte of dcc command data
|
||||
ip returns parsed ip of dcc command
|
||||
port returns parsed port of dcc command
|
||||
ad_beg_p returns pointer to first byte of addr data
|
||||
ad_end_p returns pointer to last byte of addr data */
|
||||
{
|
||||
|
||||
/* at least 12: "AAAAAAAA P\1\n" */
|
||||
while (*data++ != ' ')
|
||||
if (data > data_end - 12)
|
||||
return -1;
|
||||
|
||||
*ad_beg_p = data;
|
||||
*ip = simple_strtoul(data, &data, 10);
|
||||
|
||||
/* skip blanks between ip and port */
|
||||
while (*data == ' ') {
|
||||
if (data >= data_end)
|
||||
return -1;
|
||||
data++;
|
||||
}
|
||||
|
||||
*port = simple_strtoul(data, &data, 10);
|
||||
*ad_end_p = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int help(struct sk_buff **pskb,
|
||||
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
unsigned int dataoff;
|
||||
struct tcphdr _tcph, *th;
|
||||
char *data, *data_limit, *ib_ptr;
|
||||
int dir = CTINFO2DIR(ctinfo);
|
||||
struct ip_conntrack_expect *exp;
|
||||
u32 seq;
|
||||
u_int32_t dcc_ip;
|
||||
u_int16_t dcc_port;
|
||||
int i, ret = NF_ACCEPT;
|
||||
char *addr_beg_p, *addr_end_p;
|
||||
typeof(ip_nat_irc_hook) ip_nat_irc;
|
||||
|
||||
DEBUGP("entered\n");
|
||||
|
||||
/* If packet is coming from IRC server */
|
||||
if (dir == IP_CT_DIR_REPLY)
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* Until there's been traffic both ways, don't look in packets. */
|
||||
if (ctinfo != IP_CT_ESTABLISHED
|
||||
&& ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
||||
DEBUGP("Conntrackinfo = %u\n", ctinfo);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Not a full tcp header? */
|
||||
th = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
|
||||
sizeof(_tcph), &_tcph);
|
||||
if (th == NULL)
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* No data? */
|
||||
dataoff = ip_hdrlen(*pskb) + th->doff * 4;
|
||||
if (dataoff >= (*pskb)->len)
|
||||
return NF_ACCEPT;
|
||||
|
||||
spin_lock_bh(&irc_buffer_lock);
|
||||
ib_ptr = skb_header_pointer(*pskb, dataoff,
|
||||
(*pskb)->len - dataoff, irc_buffer);
|
||||
BUG_ON(ib_ptr == NULL);
|
||||
|
||||
data = ib_ptr;
|
||||
data_limit = ib_ptr + (*pskb)->len - dataoff;
|
||||
|
||||
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
|
||||
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
|
||||
while (data < (data_limit - (19 + MINMATCHLEN))) {
|
||||
if (memcmp(data, "\1DCC ", 5)) {
|
||||
data++;
|
||||
continue;
|
||||
}
|
||||
|
||||
data += 5;
|
||||
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
|
||||
|
||||
DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
|
||||
NIPQUAD(iph->saddr), ntohs(th->source),
|
||||
NIPQUAD(iph->daddr), ntohs(th->dest));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
|
||||
if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
|
||||
/* no match */
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUGP("DCC %s detected\n", dccprotos[i]);
|
||||
data += strlen(dccprotos[i]);
|
||||
/* we have at least
|
||||
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
|
||||
* data left (== 14/13 bytes) */
|
||||
if (parse_dcc((char *)data, data_limit, &dcc_ip,
|
||||
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
||||
/* unable to parse */
|
||||
DEBUGP("unable to parse dcc command\n");
|
||||
continue;
|
||||
}
|
||||
DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
|
||||
HIPQUAD(dcc_ip), dcc_port);
|
||||
|
||||
/* dcc_ip can be the internal OR external (NAT'ed) IP
|
||||
* Tiago Sousa <mirage@kaotik.org> */
|
||||
if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)
|
||||
&& ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != htonl(dcc_ip)) {
|
||||
if (net_ratelimit())
|
||||
printk(KERN_WARNING
|
||||
"Forged DCC command from "
|
||||
"%u.%u.%u.%u: %u.%u.%u.%u:%u\n",
|
||||
NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
|
||||
HIPQUAD(dcc_ip), dcc_port);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
exp = ip_conntrack_expect_alloc(ct);
|
||||
if (exp == NULL) {
|
||||
ret = NF_DROP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* save position of address in dcc string,
|
||||
* necessary for NAT */
|
||||
DEBUGP("tcph->seq = %u\n", th->seq);
|
||||
seq = ntohl(th->seq) + (addr_beg_p - ib_ptr);
|
||||
|
||||
/* We refer to the reverse direction ("!dir")
|
||||
* tuples here, because we're expecting
|
||||
* something in the other * direction.
|
||||
* Doesn't matter unless NAT is happening. */
|
||||
exp->tuple = ((struct ip_conntrack_tuple)
|
||||
{ { 0, { 0 } },
|
||||
{ ct->tuplehash[!dir].tuple.dst.ip,
|
||||
{ .tcp = { htons(dcc_port) } },
|
||||
IPPROTO_TCP }});
|
||||
exp->mask = ((struct ip_conntrack_tuple)
|
||||
{ { 0, { 0 } },
|
||||
{ htonl(0xFFFFFFFF),
|
||||
{ .tcp = { htons(0xFFFF) } }, 0xFF }});
|
||||
exp->expectfn = NULL;
|
||||
exp->flags = 0;
|
||||
ip_nat_irc = rcu_dereference(ip_nat_irc_hook);
|
||||
if (ip_nat_irc)
|
||||
ret = ip_nat_irc(pskb, ctinfo,
|
||||
addr_beg_p - ib_ptr,
|
||||
addr_end_p - addr_beg_p,
|
||||
exp);
|
||||
else if (ip_conntrack_expect_related(exp) != 0)
|
||||
ret = NF_DROP;
|
||||
ip_conntrack_expect_put(exp);
|
||||
goto out;
|
||||
} /* for .. NUM_DCCPROTO */
|
||||
} /* while data < ... */
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&irc_buffer_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
|
||||
static char irc_names[MAX_PORTS][sizeof("irc-65535")];
|
||||
|
||||
static void ip_conntrack_irc_fini(void);
|
||||
|
||||
static int __init ip_conntrack_irc_init(void)
|
||||
{
|
||||
int i, ret;
|
||||
struct ip_conntrack_helper *hlpr;
|
||||
char *tmpname;
|
||||
|
||||
if (max_dcc_channels < 1) {
|
||||
printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
irc_buffer = kmalloc(65536, GFP_KERNEL);
|
||||
if (!irc_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
/* If no port given, default to standard irc port */
|
||||
if (ports_c == 0)
|
||||
ports[ports_c++] = IRC_PORT;
|
||||
|
||||
for (i = 0; i < ports_c; i++) {
|
||||
hlpr = &irc_helpers[i];
|
||||
hlpr->tuple.src.u.tcp.port = htons(ports[i]);
|
||||
hlpr->tuple.dst.protonum = IPPROTO_TCP;
|
||||
hlpr->mask.src.u.tcp.port = htons(0xFFFF);
|
||||
hlpr->mask.dst.protonum = 0xFF;
|
||||
hlpr->max_expected = max_dcc_channels;
|
||||
hlpr->timeout = dcc_timeout;
|
||||
hlpr->me = THIS_MODULE;
|
||||
hlpr->help = help;
|
||||
|
||||
tmpname = &irc_names[i][0];
|
||||
if (ports[i] == IRC_PORT)
|
||||
sprintf(tmpname, "irc");
|
||||
else
|
||||
sprintf(tmpname, "irc-%d", i);
|
||||
hlpr->name = tmpname;
|
||||
|
||||
DEBUGP("port #%d: %d\n", i, ports[i]);
|
||||
|
||||
ret = ip_conntrack_helper_register(hlpr);
|
||||
|
||||
if (ret) {
|
||||
printk("ip_conntrack_irc: ERROR registering port %d\n",
|
||||
ports[i]);
|
||||
ip_conntrack_irc_fini();
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function is intentionally _NOT_ defined as __exit, because
|
||||
* it is needed by the init function */
|
||||
static void ip_conntrack_irc_fini(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ports_c; i++) {
|
||||
DEBUGP("unregistering port %d\n",
|
||||
ports[i]);
|
||||
ip_conntrack_helper_unregister(&irc_helpers[i]);
|
||||
}
|
||||
kfree(irc_buffer);
|
||||
}
|
||||
|
||||
module_init(ip_conntrack_irc_init);
|
||||
module_exit(ip_conntrack_irc_fini);
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* NetBIOS name service broadcast connection tracking helper
|
||||
*
|
||||
* (c) 2005 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
/*
|
||||
* This helper tracks locally originating NetBIOS name service
|
||||
* requests by issuing permanent expectations (valid until
|
||||
* timing out) matching all reply connections from the
|
||||
* destination network. The only NetBIOS specific thing is
|
||||
* actually the port number.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
|
||||
#define NMBD_PORT 137
|
||||
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
||||
MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int timeout = 3;
|
||||
module_param(timeout, uint, 0400);
|
||||
MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
|
||||
|
||||
static int help(struct sk_buff **pskb,
|
||||
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
struct ip_conntrack_expect *exp;
|
||||
struct iphdr *iph = ip_hdr(*pskb);
|
||||
struct rtable *rt = (struct rtable *)(*pskb)->dst;
|
||||
struct in_device *in_dev;
|
||||
__be32 mask = 0;
|
||||
|
||||
/* we're only interested in locally generated packets */
|
||||
if ((*pskb)->sk == NULL)
|
||||
goto out;
|
||||
if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
|
||||
goto out;
|
||||
if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
|
||||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get_rcu(rt->u.dst.dev);
|
||||
if (in_dev != NULL) {
|
||||
for_primary_ifa(in_dev) {
|
||||
if (ifa->ifa_broadcast == iph->daddr) {
|
||||
mask = ifa->ifa_mask;
|
||||
break;
|
||||
}
|
||||
} endfor_ifa(in_dev);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (mask == 0)
|
||||
goto out;
|
||||
|
||||
exp = ip_conntrack_expect_alloc(ct);
|
||||
if (exp == NULL)
|
||||
goto out;
|
||||
|
||||
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||
exp->tuple.src.u.udp.port = htons(NMBD_PORT);
|
||||
|
||||
exp->mask.src.ip = mask;
|
||||
exp->mask.src.u.udp.port = htons(0xFFFF);
|
||||
exp->mask.dst.ip = htonl(0xFFFFFFFF);
|
||||
exp->mask.dst.u.udp.port = htons(0xFFFF);
|
||||
exp->mask.dst.protonum = 0xFF;
|
||||
|
||||
exp->expectfn = NULL;
|
||||
exp->flags = IP_CT_EXPECT_PERMANENT;
|
||||
|
||||
ip_conntrack_expect_related(exp);
|
||||
ip_conntrack_expect_put(exp);
|
||||
|
||||
ip_ct_refresh(ct, *pskb, timeout * HZ);
|
||||
out:
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
static struct ip_conntrack_helper helper = {
|
||||
.name = "netbios-ns",
|
||||
.tuple = {
|
||||
.src = {
|
||||
.u = {
|
||||
.udp = {
|
||||
.port = __constant_htons(NMBD_PORT),
|
||||
}
|
||||
}
|
||||
},
|
||||
.dst = {
|
||||
.protonum = IPPROTO_UDP,
|
||||
},
|
||||
},
|
||||
.mask = {
|
||||
.src = {
|
||||
.u = {
|
||||
.udp = {
|
||||
.port = __constant_htons(0xFFFF),
|
||||
}
|
||||
}
|
||||
},
|
||||
.dst = {
|
||||
.protonum = 0xFF,
|
||||
},
|
||||
},
|
||||
.max_expected = 1,
|
||||
.me = THIS_MODULE,
|
||||
.help = help,
|
||||
};
|
||||
|
||||
static int __init ip_conntrack_netbios_ns_init(void)
|
||||
{
|
||||
helper.timeout = timeout;
|
||||
return ip_conntrack_helper_register(&helper);
|
||||
}
|
||||
|
||||
static void __exit ip_conntrack_netbios_ns_fini(void)
|
||||
{
|
||||
ip_conntrack_helper_unregister(&helper);
|
||||
}
|
||||
|
||||
module_init(ip_conntrack_netbios_ns_init);
|
||||
module_exit(ip_conntrack_netbios_ns_fini);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
|
||||
unsigned int ip_ct_generic_timeout __read_mostly = 600*HZ;
|
||||
|
||||
static int generic_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
tuple->src.u.all = 0;
|
||||
tuple->dst.u.all = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int generic_invert_tuple(struct ip_conntrack_tuple *tuple,
|
||||
const struct ip_conntrack_tuple *orig)
|
||||
{
|
||||
tuple->src.u.all = 0;
|
||||
tuple->dst.u.all = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print out the per-protocol part of the tuple. */
|
||||
static int generic_print_tuple(struct seq_file *s,
|
||||
const struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print out the private part of the conntrack. */
|
||||
static int generic_print_conntrack(struct seq_file *s,
|
||||
const struct ip_conntrack *state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -1 for invalid. */
|
||||
static int packet(struct ip_conntrack *conntrack,
|
||||
const struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_generic_timeout);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Called when a new connection for this protocol found. */
|
||||
static int new(struct ip_conntrack *conntrack, const struct sk_buff *skb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct ip_conntrack_protocol ip_conntrack_generic_protocol =
|
||||
{
|
||||
.proto = 0,
|
||||
.name = "unknown",
|
||||
.pkt_to_tuple = generic_pkt_to_tuple,
|
||||
.invert_tuple = generic_invert_tuple,
|
||||
.print_tuple = generic_print_tuple,
|
||||
.print_conntrack = generic_print_conntrack,
|
||||
.packet = packet,
|
||||
.new = new,
|
||||
};
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
* ip_conntrack_proto_gre.c - Version 3.0
|
||||
*
|
||||
* Connection tracking protocol helper module for GRE.
|
||||
*
|
||||
* GRE is a generic encapsulation protocol, which is generally not very
|
||||
* suited for NAT, as it has no protocol-specific part as port numbers.
|
||||
*
|
||||
* It has an optional key field, which may help us distinguishing two
|
||||
* connections between the same two hosts.
|
||||
*
|
||||
* GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
|
||||
*
|
||||
* PPTP is built on top of a modified version of GRE, and has a mandatory
|
||||
* field called "CallID", which serves us for the same purpose as the key
|
||||
* field in plain GRE.
|
||||
*
|
||||
* Documentation about PPTP can be found in RFC 2637
|
||||
*
|
||||
* (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* Development of this code funded by Astaro AG (http://www.astaro.com/)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
static DEFINE_RWLOCK(ip_ct_gre_lock);
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
||||
MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE");
|
||||
|
||||
/* shamelessly stolen from ip_conntrack_proto_udp.c */
|
||||
#define GRE_TIMEOUT (30*HZ)
|
||||
#define GRE_STREAM_TIMEOUT (180*HZ)
|
||||
|
||||
#if 0
|
||||
#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
|
||||
#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \
|
||||
NIPQUAD((x)->src.ip), ntohs((x)->src.u.gre.key), \
|
||||
NIPQUAD((x)->dst.ip), ntohs((x)->dst.u.gre.key))
|
||||
#else
|
||||
#define DEBUGP(x, args...)
|
||||
#define DUMP_TUPLE_GRE(x)
|
||||
#endif
|
||||
|
||||
/* GRE KEYMAP HANDLING FUNCTIONS */
|
||||
static LIST_HEAD(gre_keymap_list);
|
||||
|
||||
static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km,
|
||||
const struct ip_conntrack_tuple *t)
|
||||
{
|
||||
return ((km->tuple.src.ip == t->src.ip) &&
|
||||
(km->tuple.dst.ip == t->dst.ip) &&
|
||||
(km->tuple.dst.protonum == t->dst.protonum) &&
|
||||
(km->tuple.dst.u.all == t->dst.u.all));
|
||||
}
|
||||
|
||||
/* look up the source key for a given tuple */
|
||||
static __be16 gre_keymap_lookup(struct ip_conntrack_tuple *t)
|
||||
{
|
||||
struct ip_ct_gre_keymap *km;
|
||||
__be16 key = 0;
|
||||
|
||||
read_lock_bh(&ip_ct_gre_lock);
|
||||
list_for_each_entry(km, &gre_keymap_list, list) {
|
||||
if (gre_key_cmpfn(km, t)) {
|
||||
key = km->tuple.src.u.gre.key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock_bh(&ip_ct_gre_lock);
|
||||
|
||||
DEBUGP("lookup src key 0x%x up key for ", key);
|
||||
DUMP_TUPLE_GRE(t);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/* add a single keymap entry, associate with specified master ct */
|
||||
int
|
||||
ip_ct_gre_keymap_add(struct ip_conntrack *ct,
|
||||
struct ip_conntrack_tuple *t, int reply)
|
||||
{
|
||||
struct ip_ct_gre_keymap **exist_km, *km;
|
||||
|
||||
if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
|
||||
DEBUGP("refusing to add GRE keymap to non-pptp session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!reply)
|
||||
exist_km = &ct->help.ct_pptp_info.keymap_orig;
|
||||
else
|
||||
exist_km = &ct->help.ct_pptp_info.keymap_reply;
|
||||
|
||||
if (*exist_km) {
|
||||
/* check whether it's a retransmission */
|
||||
list_for_each_entry(km, &gre_keymap_list, list) {
|
||||
if (gre_key_cmpfn(km, t) && km == *exist_km)
|
||||
return 0;
|
||||
}
|
||||
DEBUGP("trying to override keymap_%s for ct %p\n",
|
||||
reply? "reply":"orig", ct);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
km = kmalloc(sizeof(*km), GFP_ATOMIC);
|
||||
if (!km)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&km->tuple, t, sizeof(*t));
|
||||
*exist_km = km;
|
||||
|
||||
DEBUGP("adding new entry %p: ", km);
|
||||
DUMP_TUPLE_GRE(&km->tuple);
|
||||
|
||||
write_lock_bh(&ip_ct_gre_lock);
|
||||
list_add_tail(&km->list, &gre_keymap_list);
|
||||
write_unlock_bh(&ip_ct_gre_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* destroy the keymap entries associated with specified master ct */
|
||||
void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct)
|
||||
{
|
||||
DEBUGP("entering for ct %p\n", ct);
|
||||
|
||||
if (!ct->helper || strcmp(ct->helper->name, "pptp")) {
|
||||
DEBUGP("refusing to destroy GRE keymap to non-pptp session\n");
|
||||
return;
|
||||
}
|
||||
|
||||
write_lock_bh(&ip_ct_gre_lock);
|
||||
if (ct->help.ct_pptp_info.keymap_orig) {
|
||||
DEBUGP("removing %p from list\n",
|
||||
ct->help.ct_pptp_info.keymap_orig);
|
||||
list_del(&ct->help.ct_pptp_info.keymap_orig->list);
|
||||
kfree(ct->help.ct_pptp_info.keymap_orig);
|
||||
ct->help.ct_pptp_info.keymap_orig = NULL;
|
||||
}
|
||||
if (ct->help.ct_pptp_info.keymap_reply) {
|
||||
DEBUGP("removing %p from list\n",
|
||||
ct->help.ct_pptp_info.keymap_reply);
|
||||
list_del(&ct->help.ct_pptp_info.keymap_reply->list);
|
||||
kfree(ct->help.ct_pptp_info.keymap_reply);
|
||||
ct->help.ct_pptp_info.keymap_reply = NULL;
|
||||
}
|
||||
write_unlock_bh(&ip_ct_gre_lock);
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
|
||||
|
||||
/* invert gre part of tuple */
|
||||
static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,
|
||||
const struct ip_conntrack_tuple *orig)
|
||||
{
|
||||
tuple->dst.u.gre.key = orig->src.u.gre.key;
|
||||
tuple->src.u.gre.key = orig->dst.u.gre.key;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* gre hdr info to tuple */
|
||||
static int gre_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
struct gre_hdr_pptp _pgrehdr, *pgrehdr;
|
||||
__be16 srckey;
|
||||
struct gre_hdr _grehdr, *grehdr;
|
||||
|
||||
/* first only delinearize old RFC1701 GRE header */
|
||||
grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
|
||||
if (!grehdr || grehdr->version != GRE_VERSION_PPTP) {
|
||||
/* try to behave like "ip_conntrack_proto_generic" */
|
||||
tuple->src.u.all = 0;
|
||||
tuple->dst.u.all = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* PPTP header is variable length, only need up to the call_id field */
|
||||
pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
|
||||
if (!pgrehdr)
|
||||
return 1;
|
||||
|
||||
if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
|
||||
DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tuple->dst.u.gre.key = pgrehdr->call_id;
|
||||
srckey = gre_keymap_lookup(tuple);
|
||||
tuple->src.u.gre.key = srckey;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* print gre part of tuple */
|
||||
static int gre_print_tuple(struct seq_file *s,
|
||||
const struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
return seq_printf(s, "srckey=0x%x dstkey=0x%x ",
|
||||
ntohs(tuple->src.u.gre.key),
|
||||
ntohs(tuple->dst.u.gre.key));
|
||||
}
|
||||
|
||||
/* print private data for conntrack */
|
||||
static int gre_print_conntrack(struct seq_file *s,
|
||||
const struct ip_conntrack *ct)
|
||||
{
|
||||
return seq_printf(s, "timeout=%u, stream_timeout=%u ",
|
||||
(ct->proto.gre.timeout / HZ),
|
||||
(ct->proto.gre.stream_timeout / HZ));
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, and may modify conntrack */
|
||||
static int gre_packet(struct ip_conntrack *ct,
|
||||
const struct sk_buff *skb,
|
||||
enum ip_conntrack_info conntrackinfo)
|
||||
{
|
||||
/* If we've seen traffic both ways, this is a GRE connection.
|
||||
* Extend timeout. */
|
||||
if (ct->status & IPS_SEEN_REPLY) {
|
||||
ip_ct_refresh_acct(ct, conntrackinfo, skb,
|
||||
ct->proto.gre.stream_timeout);
|
||||
/* Also, more likely to be important, and not a probe. */
|
||||
set_bit(IPS_ASSURED_BIT, &ct->status);
|
||||
ip_conntrack_event_cache(IPCT_STATUS, skb);
|
||||
} else
|
||||
ip_ct_refresh_acct(ct, conntrackinfo, skb,
|
||||
ct->proto.gre.timeout);
|
||||
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Called when a new connection for this protocol found. */
|
||||
static int gre_new(struct ip_conntrack *ct,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
DEBUGP(": ");
|
||||
DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||
|
||||
/* initialize to sane value. Ideally a conntrack helper
|
||||
* (e.g. in case of pptp) is increasing them */
|
||||
ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
|
||||
ct->proto.gre.timeout = GRE_TIMEOUT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called when a conntrack entry has already been removed from the hashes
|
||||
* and is about to be deleted from memory */
|
||||
static void gre_destroy(struct ip_conntrack *ct)
|
||||
{
|
||||
struct ip_conntrack *master = ct->master;
|
||||
DEBUGP(" entering\n");
|
||||
|
||||
if (!master)
|
||||
DEBUGP("no master !?!\n");
|
||||
else
|
||||
ip_ct_gre_keymap_destroy(master);
|
||||
}
|
||||
|
||||
/* protocol helper struct */
|
||||
static struct ip_conntrack_protocol gre = {
|
||||
.proto = IPPROTO_GRE,
|
||||
.name = "gre",
|
||||
.pkt_to_tuple = gre_pkt_to_tuple,
|
||||
.invert_tuple = gre_invert_tuple,
|
||||
.print_tuple = gre_print_tuple,
|
||||
.print_conntrack = gre_print_conntrack,
|
||||
.packet = gre_packet,
|
||||
.new = gre_new,
|
||||
.destroy = gre_destroy,
|
||||
.me = THIS_MODULE,
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
|
||||
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
|
||||
.tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
|
||||
.nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ip_conntrack_proto_gre initialization */
|
||||
int __init ip_ct_proto_gre_init(void)
|
||||
{
|
||||
return ip_conntrack_protocol_register(&gre);
|
||||
}
|
||||
|
||||
/* This cannot be __exit, as it is invoked from ip_conntrack_helper_pptp.c's
|
||||
* init() code on errors.
|
||||
*/
|
||||
void ip_ct_proto_gre_fini(void)
|
||||
{
|
||||
struct list_head *pos, *n;
|
||||
|
||||
/* delete all keymap entries */
|
||||
write_lock_bh(&ip_ct_gre_lock);
|
||||
list_for_each_safe(pos, n, &gre_keymap_list) {
|
||||
DEBUGP("deleting keymap %p at module unload time\n", pos);
|
||||
list_del(pos);
|
||||
kfree(pos);
|
||||
}
|
||||
write_unlock_bh(&ip_ct_gre_lock);
|
||||
|
||||
ip_conntrack_protocol_unregister(&gre);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(ip_ct_gre_keymap_add);
|
||||
EXPORT_SYMBOL(ip_ct_gre_keymap_destroy);
|
||||
@@ -1,315 +0,0 @@
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/checksum.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
|
||||
unsigned int ip_ct_icmp_timeout __read_mostly = 30*HZ;
|
||||
|
||||
#if 0
|
||||
#define DEBUGP printk
|
||||
#else
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
static int icmp_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
struct icmphdr _hdr, *hp;
|
||||
|
||||
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
|
||||
if (hp == NULL)
|
||||
return 0;
|
||||
|
||||
tuple->dst.u.icmp.type = hp->type;
|
||||
tuple->src.u.icmp.id = hp->un.echo.id;
|
||||
tuple->dst.u.icmp.code = hp->code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add 1; spaces filled with 0. */
|
||||
static const u_int8_t invmap[] = {
|
||||
[ICMP_ECHO] = ICMP_ECHOREPLY + 1,
|
||||
[ICMP_ECHOREPLY] = ICMP_ECHO + 1,
|
||||
[ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
|
||||
[ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
|
||||
[ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
|
||||
[ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
|
||||
[ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
|
||||
[ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
|
||||
};
|
||||
|
||||
static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
|
||||
const struct ip_conntrack_tuple *orig)
|
||||
{
|
||||
if (orig->dst.u.icmp.type >= sizeof(invmap)
|
||||
|| !invmap[orig->dst.u.icmp.type])
|
||||
return 0;
|
||||
|
||||
tuple->src.u.icmp.id = orig->src.u.icmp.id;
|
||||
tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
|
||||
tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print out the per-protocol part of the tuple. */
|
||||
static int icmp_print_tuple(struct seq_file *s,
|
||||
const struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
return seq_printf(s, "type=%u code=%u id=%u ",
|
||||
tuple->dst.u.icmp.type,
|
||||
tuple->dst.u.icmp.code,
|
||||
ntohs(tuple->src.u.icmp.id));
|
||||
}
|
||||
|
||||
/* Print out the private part of the conntrack. */
|
||||
static int icmp_print_conntrack(struct seq_file *s,
|
||||
const struct ip_conntrack *conntrack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, or -1 for invalid. */
|
||||
static int icmp_packet(struct ip_conntrack *ct,
|
||||
const struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
/* Try to delete connection immediately after all replies:
|
||||
won't actually vanish as we still have skb, and del_timer
|
||||
means this will only run once even if count hits zero twice
|
||||
(theoretically possible with SMP) */
|
||||
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
|
||||
if (atomic_dec_and_test(&ct->proto.icmp.count)
|
||||
&& del_timer(&ct->timeout))
|
||||
ct->timeout.function((unsigned long)ct);
|
||||
} else {
|
||||
atomic_inc(&ct->proto.icmp.count);
|
||||
ip_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
|
||||
ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
|
||||
}
|
||||
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Called when a new connection for this protocol found. */
|
||||
static int icmp_new(struct ip_conntrack *conntrack,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
static const u_int8_t valid_new[] = {
|
||||
[ICMP_ECHO] = 1,
|
||||
[ICMP_TIMESTAMP] = 1,
|
||||
[ICMP_INFO_REQUEST] = 1,
|
||||
[ICMP_ADDRESS] = 1
|
||||
};
|
||||
|
||||
if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
|
||||
|| !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
|
||||
/* Can't create a new ICMP `conn' with this. */
|
||||
DEBUGP("icmp: can't create new conn with type %u\n",
|
||||
conntrack->tuplehash[0].tuple.dst.u.icmp.type);
|
||||
DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
|
||||
return 0;
|
||||
}
|
||||
atomic_set(&conntrack->proto.icmp.count, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
icmp_error_message(struct sk_buff *skb,
|
||||
enum ip_conntrack_info *ctinfo,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
struct ip_conntrack_tuple innertuple, origtuple;
|
||||
struct {
|
||||
struct icmphdr icmp;
|
||||
struct iphdr ip;
|
||||
} _in, *inside;
|
||||
struct ip_conntrack_protocol *innerproto;
|
||||
struct ip_conntrack_tuple_hash *h;
|
||||
int dataoff;
|
||||
|
||||
IP_NF_ASSERT(skb->nfct == NULL);
|
||||
|
||||
/* Not enough header? */
|
||||
inside = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_in), &_in);
|
||||
if (inside == NULL)
|
||||
return -NF_ACCEPT;
|
||||
|
||||
/* Ignore ICMP's containing fragments (shouldn't happen) */
|
||||
if (inside->ip.frag_off & htons(IP_OFFSET)) {
|
||||
DEBUGP("icmp_error_track: fragment of proto %u\n",
|
||||
inside->ip.protocol);
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
|
||||
dataoff = ip_hdrlen(skb) + sizeof(inside->icmp) + inside->ip.ihl * 4;
|
||||
/* Are they talking about one of our connections? */
|
||||
if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
|
||||
DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
|
||||
ip_conntrack_proto_put(innerproto);
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Ordinarily, we'd expect the inverted tupleproto, but it's
|
||||
been preserved inside the ICMP. */
|
||||
if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
|
||||
DEBUGP("icmp_error_track: Can't invert tuple\n");
|
||||
ip_conntrack_proto_put(innerproto);
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
ip_conntrack_proto_put(innerproto);
|
||||
|
||||
*ctinfo = IP_CT_RELATED;
|
||||
|
||||
h = ip_conntrack_find_get(&innertuple, NULL);
|
||||
if (!h) {
|
||||
/* Locally generated ICMPs will match inverted if they
|
||||
haven't been SNAT'ed yet */
|
||||
/* FIXME: NAT code has to handle half-done double NAT --RR */
|
||||
if (hooknum == NF_IP_LOCAL_OUT)
|
||||
h = ip_conntrack_find_get(&origtuple, NULL);
|
||||
|
||||
if (!h) {
|
||||
DEBUGP("icmp_error_track: no match\n");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
/* Reverse direction from that found */
|
||||
if (DIRECTION(h) != IP_CT_DIR_REPLY)
|
||||
*ctinfo += IP_CT_IS_REPLY;
|
||||
} else {
|
||||
if (DIRECTION(h) == IP_CT_DIR_REPLY)
|
||||
*ctinfo += IP_CT_IS_REPLY;
|
||||
}
|
||||
|
||||
/* Update skb to refer to this connection */
|
||||
skb->nfct = &tuplehash_to_ctrack(h)->ct_general;
|
||||
skb->nfctinfo = *ctinfo;
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Small and modified version of icmp_rcv */
|
||||
static int
|
||||
icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
struct icmphdr _ih, *icmph;
|
||||
|
||||
/* Not enough header? */
|
||||
icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
|
||||
if (icmph == NULL) {
|
||||
if (LOG_INVALID(IPPROTO_ICMP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_icmp: short packet ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* See ip_conntrack_proto_tcp.c */
|
||||
if (ip_conntrack_checksum && hooknum == NF_IP_PRE_ROUTING &&
|
||||
nf_ip_checksum(skb, hooknum, ip_hdrlen(skb), 0)) {
|
||||
if (LOG_INVALID(IPPROTO_ICMP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_icmp: bad ICMP checksum ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/*
|
||||
* 18 is the highest 'known' ICMP type. Anything else is a mystery
|
||||
*
|
||||
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
|
||||
* discarded.
|
||||
*/
|
||||
if (icmph->type > NR_ICMP_TYPES) {
|
||||
if (LOG_INVALID(IPPROTO_ICMP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_icmp: invalid ICMP type ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Need to track icmp error message? */
|
||||
if (icmph->type != ICMP_DEST_UNREACH
|
||||
&& icmph->type != ICMP_SOURCE_QUENCH
|
||||
&& icmph->type != ICMP_TIME_EXCEEDED
|
||||
&& icmph->type != ICMP_PARAMETERPROB
|
||||
&& icmph->type != ICMP_REDIRECT)
|
||||
return NF_ACCEPT;
|
||||
|
||||
return icmp_error_message(skb, ctinfo, hooknum);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
|
||||
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
|
||||
static int icmp_tuple_to_nfattr(struct sk_buff *skb,
|
||||
const struct ip_conntrack_tuple *t)
|
||||
{
|
||||
NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(__be16),
|
||||
&t->src.u.icmp.id);
|
||||
NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
|
||||
&t->dst.u.icmp.type);
|
||||
NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
|
||||
&t->dst.u.icmp.code);
|
||||
|
||||
return 0;
|
||||
|
||||
nfattr_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int icmp_nfattr_to_tuple(struct nfattr *tb[],
|
||||
struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
if (!tb[CTA_PROTO_ICMP_TYPE-1]
|
||||
|| !tb[CTA_PROTO_ICMP_CODE-1]
|
||||
|| !tb[CTA_PROTO_ICMP_ID-1])
|
||||
return -EINVAL;
|
||||
|
||||
tuple->dst.u.icmp.type =
|
||||
*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
|
||||
tuple->dst.u.icmp.code =
|
||||
*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
|
||||
tuple->src.u.icmp.id =
|
||||
*(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
|
||||
|
||||
if (tuple->dst.u.icmp.type >= sizeof(invmap)
|
||||
|| !invmap[tuple->dst.u.icmp.type])
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ip_conntrack_protocol ip_conntrack_protocol_icmp =
|
||||
{
|
||||
.proto = IPPROTO_ICMP,
|
||||
.name = "icmp",
|
||||
.pkt_to_tuple = icmp_pkt_to_tuple,
|
||||
.invert_tuple = icmp_invert_tuple,
|
||||
.print_tuple = icmp_print_tuple,
|
||||
.print_conntrack = icmp_print_conntrack,
|
||||
.packet = icmp_packet,
|
||||
.new = icmp_new,
|
||||
.error = icmp_error,
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
|
||||
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
|
||||
.tuple_to_nfattr = icmp_tuple_to_nfattr,
|
||||
.nfattr_to_tuple = icmp_nfattr_to_tuple,
|
||||
#endif
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,148 +0,0 @@
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <net/checksum.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
||||
|
||||
unsigned int ip_ct_udp_timeout __read_mostly = 30*HZ;
|
||||
unsigned int ip_ct_udp_timeout_stream __read_mostly = 180*HZ;
|
||||
|
||||
static int udp_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
struct udphdr _hdr, *hp;
|
||||
|
||||
/* Actually only need first 8 bytes. */
|
||||
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
|
||||
if (hp == NULL)
|
||||
return 0;
|
||||
|
||||
tuple->src.u.udp.port = hp->source;
|
||||
tuple->dst.u.udp.port = hp->dest;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int udp_invert_tuple(struct ip_conntrack_tuple *tuple,
|
||||
const struct ip_conntrack_tuple *orig)
|
||||
{
|
||||
tuple->src.u.udp.port = orig->dst.u.udp.port;
|
||||
tuple->dst.u.udp.port = orig->src.u.udp.port;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print out the per-protocol part of the tuple. */
|
||||
static int udp_print_tuple(struct seq_file *s,
|
||||
const struct ip_conntrack_tuple *tuple)
|
||||
{
|
||||
return seq_printf(s, "sport=%hu dport=%hu ",
|
||||
ntohs(tuple->src.u.udp.port),
|
||||
ntohs(tuple->dst.u.udp.port));
|
||||
}
|
||||
|
||||
/* Print out the private part of the conntrack. */
|
||||
static int udp_print_conntrack(struct seq_file *s,
|
||||
const struct ip_conntrack *conntrack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns verdict for packet, and may modify conntracktype */
|
||||
static int udp_packet(struct ip_conntrack *conntrack,
|
||||
const struct sk_buff *skb,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
/* If we've seen traffic both ways, this is some kind of UDP
|
||||
stream. Extend timeout. */
|
||||
if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
|
||||
ip_ct_refresh_acct(conntrack, ctinfo, skb,
|
||||
ip_ct_udp_timeout_stream);
|
||||
/* Also, more likely to be important, and not a probe */
|
||||
if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
|
||||
ip_conntrack_event_cache(IPCT_STATUS, skb);
|
||||
} else
|
||||
ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
|
||||
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Called when a new connection for this protocol found. */
|
||||
static int udp_new(struct ip_conntrack *conntrack, const struct sk_buff *skb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
const unsigned int hdrlen = ip_hdrlen(skb);
|
||||
unsigned int udplen = skb->len - hdrlen;
|
||||
struct udphdr _hdr, *hdr;
|
||||
|
||||
/* Header is too small? */
|
||||
hdr = skb_header_pointer(skb, hdrlen, sizeof(_hdr), &_hdr);
|
||||
if (hdr == NULL) {
|
||||
if (LOG_INVALID(IPPROTO_UDP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_udp: short packet ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Truncated/malformed packets */
|
||||
if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
|
||||
if (LOG_INVALID(IPPROTO_UDP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_udp: truncated/malformed packet ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Packet with no checksum */
|
||||
if (!hdr->check)
|
||||
return NF_ACCEPT;
|
||||
|
||||
/* Checksum invalid? Ignore.
|
||||
* We skip checking packets on the outgoing path
|
||||
* because the checksum is assumed to be correct.
|
||||
* FIXME: Source route IP option packets --RR */
|
||||
if (ip_conntrack_checksum && hooknum == NF_IP_PRE_ROUTING &&
|
||||
nf_ip_checksum(skb, hooknum, hdrlen, IPPROTO_UDP)) {
|
||||
if (LOG_INVALID(IPPROTO_UDP))
|
||||
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
|
||||
"ip_ct_udp: bad UDP checksum ");
|
||||
return -NF_ACCEPT;
|
||||
}
|
||||
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
struct ip_conntrack_protocol ip_conntrack_protocol_udp =
|
||||
{
|
||||
.proto = IPPROTO_UDP,
|
||||
.name = "udp",
|
||||
.pkt_to_tuple = udp_pkt_to_tuple,
|
||||
.invert_tuple = udp_invert_tuple,
|
||||
.print_tuple = udp_print_tuple,
|
||||
.print_conntrack = udp_print_conntrack,
|
||||
.packet = udp_packet,
|
||||
.new = udp_new,
|
||||
.error = udp_error,
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
|
||||
defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
|
||||
.tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
|
||||
.nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
|
||||
#endif
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
||||
/* (C) 2001-2002 Magnus Boden <mb@ozaba.mine.nu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Version: 0.0.7
|
||||
*
|
||||
* Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
|
||||
* - port to newnat API
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
|
||||
MODULE_DESCRIPTION("tftp connection tracking helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define MAX_PORTS 8
|
||||
static unsigned short ports[MAX_PORTS];
|
||||
static int ports_c;
|
||||
module_param_array(ports, ushort, &ports_c, 0400);
|
||||
MODULE_PARM_DESC(ports, "port numbers of tftp servers");
|
||||
|
||||
#if 0
|
||||
#define DEBUGP(format, args...) printk("%s:%s:" format, \
|
||||
__FILE__, __FUNCTION__ , ## args)
|
||||
#else
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
struct ip_conntrack_expect *exp);
|
||||
EXPORT_SYMBOL_GPL(ip_nat_tftp_hook);
|
||||
|
||||
static int tftp_help(struct sk_buff **pskb,
|
||||
struct ip_conntrack *ct,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
struct tftphdr _tftph, *tfh;
|
||||
struct ip_conntrack_expect *exp;
|
||||
unsigned int ret = NF_ACCEPT;
|
||||
typeof(ip_nat_tftp_hook) ip_nat_tftp;
|
||||
|
||||
tfh = skb_header_pointer(*pskb,
|
||||
ip_hdrlen(*pskb) + sizeof(struct udphdr),
|
||||
sizeof(_tftph), &_tftph);
|
||||
if (tfh == NULL)
|
||||
return NF_ACCEPT;
|
||||
|
||||
switch (ntohs(tfh->opcode)) {
|
||||
/* RRQ and WRQ works the same way */
|
||||
case TFTP_OPCODE_READ:
|
||||
case TFTP_OPCODE_WRITE:
|
||||
DEBUGP("");
|
||||
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
||||
|
||||
exp = ip_conntrack_expect_alloc(ct);
|
||||
if (exp == NULL)
|
||||
return NF_DROP;
|
||||
|
||||
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||
exp->mask.src.ip = htonl(0xffffffff);
|
||||
exp->mask.src.u.udp.port = 0;
|
||||
exp->mask.dst.ip = htonl(0xffffffff);
|
||||
exp->mask.dst.u.udp.port = htons(0xffff);
|
||||
exp->mask.dst.protonum = 0xff;
|
||||
exp->expectfn = NULL;
|
||||
exp->flags = 0;
|
||||
|
||||
DEBUGP("expect: ");
|
||||
DUMP_TUPLE(&exp->tuple);
|
||||
DUMP_TUPLE(&exp->mask);
|
||||
ip_nat_tftp = rcu_dereference(ip_nat_tftp_hook);
|
||||
if (ip_nat_tftp)
|
||||
ret = ip_nat_tftp(pskb, ctinfo, exp);
|
||||
else if (ip_conntrack_expect_related(exp) != 0)
|
||||
ret = NF_DROP;
|
||||
ip_conntrack_expect_put(exp);
|
||||
break;
|
||||
case TFTP_OPCODE_DATA:
|
||||
case TFTP_OPCODE_ACK:
|
||||
DEBUGP("Data/ACK opcode\n");
|
||||
break;
|
||||
case TFTP_OPCODE_ERROR:
|
||||
DEBUGP("Error opcode\n");
|
||||
break;
|
||||
default:
|
||||
DEBUGP("Unknown opcode\n");
|
||||
}
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
static struct ip_conntrack_helper tftp[MAX_PORTS];
|
||||
static char tftp_names[MAX_PORTS][sizeof("tftp-65535")];
|
||||
|
||||
static void ip_conntrack_tftp_fini(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ports_c; i++) {
|
||||
DEBUGP("unregistering helper for port %d\n",
|
||||
ports[i]);
|
||||
ip_conntrack_helper_unregister(&tftp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init ip_conntrack_tftp_init(void)
|
||||
{
|
||||
int i, ret;
|
||||
char *tmpname;
|
||||
|
||||
if (ports_c == 0)
|
||||
ports[ports_c++] = TFTP_PORT;
|
||||
|
||||
for (i = 0; i < ports_c; i++) {
|
||||
/* Create helper structure */
|
||||
memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper));
|
||||
|
||||
tftp[i].tuple.dst.protonum = IPPROTO_UDP;
|
||||
tftp[i].tuple.src.u.udp.port = htons(ports[i]);
|
||||
tftp[i].mask.dst.protonum = 0xFF;
|
||||
tftp[i].mask.src.u.udp.port = htons(0xFFFF);
|
||||
tftp[i].max_expected = 1;
|
||||
tftp[i].timeout = 5 * 60; /* 5 minutes */
|
||||
tftp[i].me = THIS_MODULE;
|
||||
tftp[i].help = tftp_help;
|
||||
|
||||
tmpname = &tftp_names[i][0];
|
||||
if (ports[i] == TFTP_PORT)
|
||||
sprintf(tmpname, "tftp");
|
||||
else
|
||||
sprintf(tmpname, "tftp-%d", i);
|
||||
tftp[i].name = tmpname;
|
||||
|
||||
DEBUGP("port #%d: %d\n", i, ports[i]);
|
||||
|
||||
ret=ip_conntrack_helper_register(&tftp[i]);
|
||||
if (ret) {
|
||||
printk("ERROR registering helper for port %d\n",
|
||||
ports[i]);
|
||||
ip_conntrack_tftp_fini();
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
module_init(ip_conntrack_tftp_init);
|
||||
module_exit(ip_conntrack_tftp_fini);
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Amanda extension for TCP NAT alteration.
|
||||
* (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
|
||||
* based on a copy of HW's ip_nat_irc.c as well as other modules
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* Module load syntax:
|
||||
* insmod ip_nat_amanda.o
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/udp.h>
|
||||
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv4/ip_nat.h>
|
||||
#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
||||
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
|
||||
|
||||
|
||||
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
|
||||
MODULE_DESCRIPTION("Amanda NAT helper");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int help(struct sk_buff **pskb,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
unsigned int matchoff,
|
||||
unsigned int matchlen,
|
||||
struct ip_conntrack_expect *exp)
|
||||
{
|
||||
char buffer[sizeof("65535")];
|
||||
u_int16_t port;
|
||||
unsigned int ret;
|
||||
|
||||
/* Connection comes from client. */
|
||||
exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
|
||||
exp->dir = IP_CT_DIR_ORIGINAL;
|
||||
|
||||
/* When you see the packet, we need to NAT it the same as the
|
||||
* this one (ie. same IP: it will be TCP and master is UDP). */
|
||||
exp->expectfn = ip_nat_follow_master;
|
||||
|
||||
/* Try to get same port: if not, try to change it. */
|
||||
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
|
||||
exp->tuple.dst.u.tcp.port = htons(port);
|
||||
if (ip_conntrack_expect_related(exp) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (port == 0)
|
||||
return NF_DROP;
|
||||
|
||||
sprintf(buffer, "%u", port);
|
||||
ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
|
||||
matchoff, matchlen,
|
||||
buffer, strlen(buffer));
|
||||
if (ret != NF_ACCEPT)
|
||||
ip_conntrack_unexpect_related(exp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ip_nat_amanda_fini(void)
|
||||
{
|
||||
rcu_assign_pointer(ip_nat_amanda_hook, NULL);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
static int __init ip_nat_amanda_init(void)
|
||||
{
|
||||
BUG_ON(rcu_dereference(ip_nat_amanda_hook));
|
||||
rcu_assign_pointer(ip_nat_amanda_hook, help);
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(ip_nat_amanda_init);
|
||||
module_exit(ip_nat_amanda_fini);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user