diff options
-rw-r--r-- | include/net/netfilter/nf_nat_helper.h | 32 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_helper.c | 39 |
2 files changed, 48 insertions, 23 deletions
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h index 4222220920a5..02bb6c29dc3d 100644 --- a/include/net/netfilter/nf_nat_helper.h +++ b/include/net/netfilter/nf_nat_helper.h | |||
@@ -7,13 +7,27 @@ | |||
7 | struct sk_buff; | 7 | struct sk_buff; |
8 | 8 | ||
9 | /* These return true or false. */ | 9 | /* These return true or false. */ |
10 | extern int nf_nat_mangle_tcp_packet(struct sk_buff *skb, | 10 | extern int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, |
11 | struct nf_conn *ct, | 11 | struct nf_conn *ct, |
12 | enum ip_conntrack_info ctinfo, | 12 | enum ip_conntrack_info ctinfo, |
13 | unsigned int match_offset, | 13 | unsigned int match_offset, |
14 | unsigned int match_len, | 14 | unsigned int match_len, |
15 | const char *rep_buffer, | 15 | const char *rep_buffer, |
16 | unsigned int rep_len); | 16 | unsigned int rep_len, bool adjust); |
17 | |||
18 | static inline int nf_nat_mangle_tcp_packet(struct sk_buff *skb, | ||
19 | struct nf_conn *ct, | ||
20 | enum ip_conntrack_info ctinfo, | ||
21 | unsigned int match_offset, | ||
22 | unsigned int match_len, | ||
23 | const char *rep_buffer, | ||
24 | unsigned int rep_len) | ||
25 | { | ||
26 | return __nf_nat_mangle_tcp_packet(skb, ct, ctinfo, | ||
27 | match_offset, match_len, | ||
28 | rep_buffer, rep_len, true); | ||
29 | } | ||
30 | |||
17 | extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, | 31 | extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, |
18 | struct nf_conn *ct, | 32 | struct nf_conn *ct, |
19 | enum ip_conntrack_info ctinfo, | 33 | enum ip_conntrack_info ctinfo, |
@@ -21,6 +35,10 @@ extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, | |||
21 | unsigned int match_len, | 35 | unsigned int match_len, |
22 | const char *rep_buffer, | 36 | const char *rep_buffer, |
23 | unsigned int rep_len); | 37 | unsigned int rep_len); |
38 | |||
39 | extern void nf_nat_set_seq_adjust(struct nf_conn *ct, | ||
40 | enum ip_conntrack_info ctinfo, | ||
41 | __be32 seq, s16 off); | ||
24 | extern int nf_nat_seq_adjust(struct sk_buff *skb, | 42 | extern int nf_nat_seq_adjust(struct sk_buff *skb, |
25 | struct nf_conn *ct, | 43 | struct nf_conn *ct, |
26 | enum ip_conntrack_info ctinfo); | 44 | enum ip_conntrack_info ctinfo); |
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 7f10a6be0191..4b6af4bb1f50 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -141,6 +141,17 @@ static int enlarge_skb(struct sk_buff *skb, unsigned int extra) | |||
141 | return 1; | 141 | return 1; |
142 | } | 142 | } |
143 | 143 | ||
144 | void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo, | ||
145 | __be32 seq, s16 off) | ||
146 | { | ||
147 | if (!off) | ||
148 | return; | ||
149 | set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); | ||
150 | adjust_tcp_sequence(ntohl(seq), off, ct, ctinfo); | ||
151 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); | ||
152 | } | ||
153 | EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust); | ||
154 | |||
144 | /* Generic function for mangling variable-length address changes inside | 155 | /* Generic function for mangling variable-length address changes inside |
145 | * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX | 156 | * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX |
146 | * command in FTP). | 157 | * command in FTP). |
@@ -149,14 +160,13 @@ static int enlarge_skb(struct sk_buff *skb, unsigned int extra) | |||
149 | * skb enlargement, ... | 160 | * skb enlargement, ... |
150 | * | 161 | * |
151 | * */ | 162 | * */ |
152 | int | 163 | int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, |
153 | nf_nat_mangle_tcp_packet(struct sk_buff *skb, | 164 | struct nf_conn *ct, |
154 | struct nf_conn *ct, | 165 | enum ip_conntrack_info ctinfo, |
155 | enum ip_conntrack_info ctinfo, | 166 | unsigned int match_offset, |
156 | unsigned int match_offset, | 167 | unsigned int match_len, |
157 | unsigned int match_len, | 168 | const char *rep_buffer, |
158 | const char *rep_buffer, | 169 | unsigned int rep_len, bool adjust) |
159 | unsigned int rep_len) | ||
160 | { | 170 | { |
161 | struct rtable *rt = skb_rtable(skb); | 171 | struct rtable *rt = skb_rtable(skb); |
162 | struct iphdr *iph; | 172 | struct iphdr *iph; |
@@ -202,16 +212,13 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
202 | inet_proto_csum_replace2(&tcph->check, skb, | 212 | inet_proto_csum_replace2(&tcph->check, skb, |
203 | htons(oldlen), htons(datalen), 1); | 213 | htons(oldlen), htons(datalen), 1); |
204 | 214 | ||
205 | if (rep_len != match_len) { | 215 | if (adjust && rep_len != match_len) |
206 | set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); | 216 | nf_nat_set_seq_adjust(ct, ctinfo, tcph->seq, |
207 | adjust_tcp_sequence(ntohl(tcph->seq), | 217 | (int)rep_len - (int)match_len); |
208 | (int)rep_len - (int)match_len, | 218 | |
209 | ct, ctinfo); | ||
210 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); | ||
211 | } | ||
212 | return 1; | 219 | return 1; |
213 | } | 220 | } |
214 | EXPORT_SYMBOL(nf_nat_mangle_tcp_packet); | 221 | EXPORT_SYMBOL(__nf_nat_mangle_tcp_packet); |
215 | 222 | ||
216 | /* Generic function for mangling variable-length address changes inside | 223 | /* Generic function for mangling variable-length address changes inside |
217 | * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX | 224 | * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX |