Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
ipv4
netfilter
nf_nat_proto_gre.c
Go to the documentation of this file.
1
/*
2
* nf_nat_proto_gre.c
3
*
4
* NAT protocol helper module for GRE.
5
*
6
* GRE is a generic encapsulation protocol, which is generally not very
7
* suited for NAT, as it has no protocol-specific part as port numbers.
8
*
9
* It has an optional key field, which may help us distinguishing two
10
* connections between the same two hosts.
11
*
12
* GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
13
*
14
* PPTP is built on top of a modified version of GRE, and has a mandatory
15
* field called "CallID", which serves us for the same purpose as the key
16
* field in plain GRE.
17
*
18
* Documentation about PPTP can be found in RFC 2637
19
*
20
* (C) 2000-2005 by Harald Welte <
[email protected]
>
21
*
22
* Development of this code funded by Astaro AG (http://www.astaro.com/)
23
*
24
*/
25
26
#include <linux/module.h>
27
#include <
linux/skbuff.h
>
28
#include <linux/ip.h>
29
30
#include <
net/netfilter/nf_nat.h
>
31
#include <
net/netfilter/nf_nat_l4proto.h
>
32
#include <
linux/netfilter/nf_conntrack_proto_gre.h
>
33
34
MODULE_LICENSE
(
"GPL"
);
35
MODULE_AUTHOR
(
"Harald Welte <
[email protected]
>"
);
36
MODULE_DESCRIPTION
(
"Netfilter NAT protocol helper module for GRE"
);
37
38
/* generate unique tuple ... */
39
static
void
40
gre_unique_tuple(
const
struct
nf_nat_l3proto
*l3proto,
41
struct
nf_conntrack_tuple
*tuple,
42
const
struct
nf_nat_range
*
range
,
43
enum
nf_nat_manip_type
maniptype,
44
const
struct
nf_conn
*
ct
)
45
{
46
static
u_int16_t
key
;
47
__be16
*keyptr;
48
unsigned
int
min
,
i
,
range_size
;
49
50
/* If there is no master conntrack we are not PPTP,
51
do not change tuples */
52
if
(!ct->
master
)
53
return
;
54
55
if
(maniptype ==
NF_NAT_MANIP_SRC
)
56
keyptr = &tuple->
src
.u.gre.key;
57
else
58
keyptr = &tuple->
dst
.u.gre.key;
59
60
if
(!(range->
flags
&
NF_NAT_RANGE_PROTO_SPECIFIED
)) {
61
pr_debug
(
"%p: NATing GRE PPTP\n"
, ct);
62
min = 1;
63
range_size = 0xffff;
64
}
else
{
65
min =
ntohs
(range->
min_proto
.
gre
.key);
66
range_size =
ntohs
(range->
max_proto
.
gre
.key) - min + 1;
67
}
68
69
pr_debug
(
"min = %u, range_size = %u\n"
, min, range_size);
70
71
for
(i = 0; ; ++
key
) {
72
*keyptr =
htons
(min + key % range_size);
73
if
(++i == range_size || !
nf_nat_used_tuple
(tuple, ct))
74
return
;
75
}
76
77
pr_debug
(
"%p: no NAT mapping\n"
, ct);
78
return
;
79
}
80
81
/* manipulate a GRE packet according to maniptype */
82
static
bool
83
gre_manip_pkt(
struct
sk_buff
*
skb
,
84
const
struct
nf_nat_l3proto
*l3proto,
85
unsigned
int
iphdroff,
unsigned
int
hdroff,
86
const
struct
nf_conntrack_tuple
*tuple,
87
enum
nf_nat_manip_type
maniptype)
88
{
89
const
struct
gre_hdr
*greh;
90
struct
gre_hdr_pptp
*pgreh;
91
92
/* pgreh includes two optional 32bit fields which are not required
93
* to be there. That's where the magic '8' comes from */
94
if
(!
skb_make_writable
(skb, hdroff +
sizeof
(*pgreh) - 8))
95
return
false
;
96
97
greh = (
void
*)skb->
data
+ hdroff;
98
pgreh = (
struct
gre_hdr_pptp
*)greh;
99
100
/* we only have destination manip of a packet, since 'source key'
101
* is not present in the packet itself */
102
if
(maniptype !=
NF_NAT_MANIP_DST
)
103
return
true
;
104
switch
(greh->version) {
105
case
GRE_VERSION_1701
:
106
/* We do not currently NAT any GREv0 packets.
107
* Try to behave like "nf_nat_proto_unknown" */
108
break
;
109
case
GRE_VERSION_PPTP
:
110
pr_debug
(
"call_id -> 0x%04x\n"
,
ntohs
(tuple->
dst
.u.gre.key));
111
pgreh->
call_id
= tuple->
dst
.u.gre.key;
112
break
;
113
default
:
114
pr_debug
(
"can't nat unknown GRE version\n"
);
115
return
false
;
116
}
117
return
true
;
118
}
119
120
static
const
struct
nf_nat_l4proto
gre = {
121
.l4proto =
IPPROTO_GRE
,
122
.manip_pkt = gre_manip_pkt,
123
.in_range =
nf_nat_l4proto_in_range
,
124
.unique_tuple = gre_unique_tuple,
125
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
126
.nlattr_to_range =
nf_nat_l4proto_nlattr_to_range
,
127
#endif
128
};
129
130
static
int
__init
nf_nat_proto_gre_init(
void
)
131
{
132
return
nf_nat_l4proto_register
(
NFPROTO_IPV4
, &gre);
133
}
134
135
static
void
__exit
nf_nat_proto_gre_fini(
void
)
136
{
137
nf_nat_l4proto_unregister
(
NFPROTO_IPV4
, &gre);
138
}
139
140
module_init
(nf_nat_proto_gre_init);
141
module_exit
(nf_nat_proto_gre_fini);
142
143
void
nf_nat_need_gre
(
void
)
144
{
145
return
;
146
}
147
EXPORT_SYMBOL_GPL
(
nf_nat_need_gre
);
Generated on Thu Jan 10 2013 14:58:42 for Linux Kernel by
1.8.2