Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b3a3a329
Commit
b3a3a329
authored
Mar 30, 2003
by
Magnus Boden
Committed by
David S. Miller
Mar 30, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NETFILTER]: Add tftp conntrack + NAT support.
parent
95e329cb
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
363 additions
and
2 deletions
+363
-2
include/linux/netfilter_ipv4/ip_conntrack_tftp.h
include/linux/netfilter_ipv4/ip_conntrack_tftp.h
+13
-0
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Kconfig
+20
-2
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/Makefile
+2
-0
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_conntrack_tftp.c
+131
-0
net/ipv4/netfilter/ip_nat_tftp.c
net/ipv4/netfilter/ip_nat_tftp.c
+197
-0
No files found.
include/linux/netfilter_ipv4/ip_conntrack_tftp.h
0 → 100644
View file @
b3a3a329
#ifndef _IP_CT_TFTP
#define _IP_CT_TFTP
#define TFTP_PORT 69
struct
tftphdr
{
u_int16_t
opcode
;
};
#define TFTP_OPCODE_READ 1
#define TFTP_OPCODE_WRITE 2
#endif
/* _IP_CT_TFTP */
net/ipv4/netfilter/Kconfig
View file @
b3a3a329
...
...
@@ -44,8 +44,20 @@ config IP_NF_IRC
chats. Note that you do NOT need this extension to get files or
have others initiate chats, or everything else in IRC.
If you want to compile it as a module, say 'M' here and read
Documentation/modules.txt. If unsure, say 'N'.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `Y'.
config IP_NF_TFTP
tristate "TFTP prtocol 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.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `Y'.
config IP_NF_QUEUE
tristate "Userspace queueing via NETLINK (EXPERIMENTAL)"
...
...
@@ -380,6 +392,12 @@ config IP_NF_NAT_FTP
default IP_NF_NAT if IP_NF_FTP=y
default m if IP_NF_FTP=m
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 IP_NF_MANGLE
tristate "Packet mangling"
depends on IP_NF_IPTABLES
...
...
net/ipv4/netfilter/Makefile
View file @
b3a3a329
...
...
@@ -20,6 +20,7 @@ ipchains-objs := $(ip_nf_compat-objs) ipchains_core.o
obj-$(CONFIG_IP_NF_CONNTRACK)
+=
ip_conntrack.o
# connection tracking helpers
obj-$(CONFIG_IP_NF_TFTP)
+=
ip_conntrack_tftp.o
obj-$(CONFIG_IP_NF_FTP)
+=
ip_conntrack_ftp.o
ifdef
CONFIG_IP_NF_NAT_FTP
endif
...
...
@@ -28,6 +29,7 @@ ifdef CONFIG_IP_NF_NAT_IRC
endif
# NAT helpers
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
...
...
net/ipv4/netfilter/ip_conntrack_tftp.c
0 → 100644
View file @
b3a3a329
/*
* Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu>
* 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>
MODULE_AUTHOR
(
"Magnus Boden <mb@ozaba.mine.nu>"
);
MODULE_DESCRIPTION
(
"Netfilter connection tracking module for tftp"
);
MODULE_LICENSE
(
"GPL"
);
#define MAX_PORTS 8
static
int
ports
[
MAX_PORTS
];
static
int
ports_c
=
0
;
#ifdef MODULE_PARM
MODULE_PARM
(
ports
,
"1-"
__MODULE_STRING
(
MAX_PORTS
)
"i"
);
MODULE_PARM_DESC
(
ports
,
"port numbers of tftp servers"
);
#endif
#if 0
#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ": " \
format, ## args)
#else
#define DEBUGP(format, args...)
#endif
static
int
tftp_help
(
const
struct
iphdr
*
iph
,
size_t
len
,
struct
ip_conntrack
*
ct
,
enum
ip_conntrack_info
ctinfo
)
{
struct
udphdr
*
udph
=
(
void
*
)
iph
+
iph
->
ihl
*
4
;
struct
tftphdr
*
tftph
=
(
void
*
)
udph
+
8
;
struct
ip_conntrack_expect
exp
;
switch
(
ntohs
(
tftph
->
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
);
memset
(
&
exp
,
0
,
sizeof
(
exp
));
exp
.
tuple
=
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
;
exp
.
mask
.
src
.
ip
=
0xffffffff
;
exp
.
mask
.
dst
.
ip
=
0xffffffff
;
exp
.
mask
.
dst
.
u
.
udp
.
port
=
0xffff
;
exp
.
mask
.
dst
.
protonum
=
0xffff
;
exp
.
expectfn
=
NULL
;
DEBUGP
(
"expect: "
);
DUMP_TUPLE
(
&
exp
.
tuple
);
DUMP_TUPLE
(
&
exp
.
mask
);
ip_conntrack_expect_related
(
ct
,
&
exp
);
break
;
default:
DEBUGP
(
"Unknown opcode
\n
"
);
}
return
NF_ACCEPT
;
}
static
struct
ip_conntrack_helper
tftp
[
MAX_PORTS
];
static
char
tftp_names
[
MAX_PORTS
][
10
];
static
void
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
init
(
void
)
{
int
i
,
ret
;
char
*
tmpname
;
if
(
!
ports
[
0
])
ports
[
0
]
=
TFTP_PORT
;
for
(
i
=
0
;
(
i
<
MAX_PORTS
)
&&
ports
[
i
]
;
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
=
0xFFFF
;
tftp
[
i
].
mask
.
src
.
u
.
udp
.
port
=
0xFFFF
;
tftp
[
i
].
max_expected
=
1
;
tftp
[
i
].
timeout
=
0
;
tftp
[
i
].
flags
=
IP_CT_HELPER_F_REUSE_EXPECT
;
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
]);
fini
();
return
(
ret
);
}
ports_c
++
;
}
return
(
0
);
}
module_init
(
init
);
module_exit
(
fini
);
net/ipv4/netfilter/ip_nat_tftp.c
0 → 100644
View file @
b3a3a329
/*
* Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu>
* Version: 0.0.7
*
* Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
* - Port to newnat API
*
* This module currently supports DNAT:
* iptables -t nat -A PREROUTING -d x.x.x.x -j DNAT --to-dest x.x.x.y
*
* and SNAT:
* iptables -t nat -A POSTROUTING { -j MASQUERADE , -j SNAT --to-source x.x.x.x }
*
* It has not been tested with
* -j SNAT --to-source x.x.x.x-x.x.x.y since I only have one external ip
* If you do test this please let me know if it works or not.
*
*/
#include <linux/module.h>
#include <linux/netfilter_ipv4.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/netfilter_ipv4/ip_nat_helper.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
MODULE_AUTHOR
(
"Magnus Boden <mb@ozaba.mine.nu>"
);
MODULE_DESCRIPTION
(
"Netfilter NAT helper for tftp"
);
MODULE_LICENSE
(
"GPL"
);
#define MAX_PORTS 8
static
int
ports
[
MAX_PORTS
];
static
int
ports_c
=
0
;
#ifdef MODULE_PARM
MODULE_PARM
(
ports
,
"1-"
__MODULE_STRING
(
MAX_PORTS
)
"i"
);
MODULE_PARM_DESC
(
ports
,
"port numbers of tftp servers"
);
#endif
#if 0
#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ": " \
format, ## args)
#else
#define DEBUGP(format, args...)
#endif
static
unsigned
int
tftp_nat_help
(
struct
ip_conntrack
*
ct
,
struct
ip_conntrack_expect
*
exp
,
struct
ip_nat_info
*
info
,
enum
ip_conntrack_info
ctinfo
,
unsigned
int
hooknum
,
struct
sk_buff
**
pskb
)
{
int
dir
=
CTINFO2DIR
(
ctinfo
);
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
struct
udphdr
*
udph
=
(
void
*
)
iph
+
iph
->
ihl
*
4
;
struct
tftphdr
*
tftph
=
(
void
*
)
udph
+
8
;
struct
ip_conntrack_tuple
repl
;
if
(
!
((
hooknum
==
NF_IP_POST_ROUTING
&&
dir
==
IP_CT_DIR_ORIGINAL
)
||
(
hooknum
==
NF_IP_PRE_ROUTING
&&
dir
==
IP_CT_DIR_REPLY
)))
return
NF_ACCEPT
;
if
(
!
exp
)
{
DEBUGP
(
"no conntrack expectation to modify
\n
"
);
return
NF_ACCEPT
;
}
switch
(
ntohs
(
tftph
->
opcode
))
{
/* RRQ and WRQ works the same way */
case
TFTP_OPCODE_READ
:
case
TFTP_OPCODE_WRITE
:
repl
=
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
;
DEBUGP
(
""
);
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
);
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
);
DEBUGP
(
"expecting: "
);
DUMP_TUPLE
(
&
repl
);
DUMP_TUPLE
(
&
exp
->
mask
);
ip_conntrack_change_expect
(
exp
,
&
repl
);
break
;
default:
DEBUGP
(
"Unknown opcode
\n
"
);
}
return
NF_ACCEPT
;
}
static
unsigned
int
tftp_nat_expected
(
struct
sk_buff
**
pskb
,
unsigned
int
hooknum
,
struct
ip_conntrack
*
ct
,
struct
ip_nat_info
*
info
)
{
const
struct
ip_conntrack
*
master
=
ct
->
master
->
expectant
;
const
struct
ip_conntrack_tuple
*
orig
=
&
master
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
;
struct
ip_nat_multi_range
mr
;
#if 0
const struct ip_conntrack_tuple *repl =
&master->tuplehash[IP_CT_DIR_REPLY].tuple;
struct iphdr *iph = (*pskb)->nh.iph;
struct udphdr *udph = (void *)iph + iph->ihl*4;
#endif
IP_NF_ASSERT
(
info
);
IP_NF_ASSERT
(
master
);
IP_NF_ASSERT
(
!
(
info
->
initialized
&
(
1
<<
HOOK2MANIP
(
hooknum
))));
mr
.
rangesize
=
1
;
mr
.
range
[
0
].
flags
=
IP_NAT_RANGE_MAP_IPS
;
if
(
HOOK2MANIP
(
hooknum
)
==
IP_NAT_MANIP_SRC
)
{
mr
.
range
[
0
].
min_ip
=
mr
.
range
[
0
].
max_ip
=
orig
->
dst
.
ip
;
DEBUGP
(
"orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
"newsrc: %u.%u.%u.%u
\n
"
,
NIPQUAD
((
*
pskb
)
->
nh
.
iph
->
saddr
),
ntohs
(
udph
->
source
),
NIPQUAD
((
*
pskb
)
->
nh
.
iph
->
daddr
),
ntohs
(
udph
->
dest
),
NIPQUAD
(
orig
->
dst
.
ip
));
}
else
{
mr
.
range
[
0
].
min_ip
=
mr
.
range
[
0
].
max_ip
=
orig
->
src
.
ip
;
mr
.
range
[
0
].
min
.
udp
.
port
=
mr
.
range
[
0
].
max
.
udp
.
port
=
orig
->
src
.
u
.
udp
.
port
;
mr
.
range
[
0
].
flags
|=
IP_NAT_RANGE_PROTO_SPECIFIED
;
DEBUGP
(
"orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
"newdst: %u.%u.%u.%u:%u
\n
"
,
NIPQUAD
((
*
pskb
)
->
nh
.
iph
->
saddr
),
ntohs
(
udph
->
source
),
NIPQUAD
((
*
pskb
)
->
nh
.
iph
->
daddr
),
ntohs
(
udph
->
dest
),
NIPQUAD
(
orig
->
src
.
ip
),
ntohs
(
orig
->
src
.
u
.
udp
.
port
));
}
return
ip_nat_setup_info
(
ct
,
&
mr
,
hooknum
);
}
static
struct
ip_nat_helper
tftp
[
MAX_PORTS
];
static
char
tftp_names
[
MAX_PORTS
][
10
];
static
void
fini
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ports_c
;
i
++
)
{
DEBUGP
(
"unregistering helper for port %d
\n
"
,
ports
[
i
]);
ip_nat_helper_unregister
(
&
tftp
[
i
]);
}
}
static
int
__init
init
(
void
)
{
int
i
,
ret
;
char
*
tmpname
;
if
(
!
ports
[
0
])
ports
[
0
]
=
TFTP_PORT
;
for
(
i
=
0
;
(
i
<
MAX_PORTS
)
&&
ports
[
i
]
;
i
++
)
{
memset
(
&
tftp
[
i
],
0
,
sizeof
(
struct
ip_nat_helper
));
tftp
[
i
].
tuple
.
dst
.
protonum
=
IPPROTO_UDP
;
tftp
[
i
].
tuple
.
src
.
u
.
udp
.
port
=
htons
(
ports
[
i
]);
tftp
[
i
].
mask
.
dst
.
protonum
=
0xFFFF
;
tftp
[
i
].
mask
.
src
.
u
.
udp
.
port
=
0xFFFF
;
tftp
[
i
].
help
=
tftp_nat_help
;
tftp
[
i
].
flags
=
0
;
tftp
[
i
].
me
=
THIS_MODULE
;
tftp
[
i
].
expect
=
tftp_nat_expected
;
tmpname
=
&
tftp_names
[
i
][
0
];
if
(
ports
[
i
]
==
TFTP_PORT
)
sprintf
(
tmpname
,
"tftp"
);
else
sprintf
(
tmpname
,
"tftp-%d"
,
i
);
tftp
[
i
].
name
=
tmpname
;
DEBUGP
(
"ip_nat_tftp: registering for port %d: name %s
\n
"
,
ports
[
i
],
tftp
[
i
].
name
);
ret
=
ip_nat_helper_register
(
&
tftp
[
i
]);
if
(
ret
)
{
printk
(
"ip_nat_tftp: unable to register for port %d
\n
"
,
ports
[
i
]);
fini
();
return
ret
;
}
ports_c
++
;
}
return
ret
;
}
module_init
(
init
);
module_exit
(
fini
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment