diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/nf_nat_sip.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index bfd88e4e0685..fac97cf51ae5 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c | |||
@@ -222,6 +222,29 @@ static unsigned int mangle_sdp(struct sk_buff **pskb, | |||
222 | return mangle_content_len(pskb, ctinfo, ct, dptr); | 222 | return mangle_content_len(pskb, ctinfo, ct, dptr); |
223 | } | 223 | } |
224 | 224 | ||
225 | static void ip_nat_sdp_expect(struct nf_conn *ct, | ||
226 | struct nf_conntrack_expect *exp) | ||
227 | { | ||
228 | struct nf_nat_range range; | ||
229 | |||
230 | /* This must be a fresh one. */ | ||
231 | BUG_ON(ct->status & IPS_NAT_DONE_MASK); | ||
232 | |||
233 | /* Change src to where master sends to */ | ||
234 | range.flags = IP_NAT_RANGE_MAP_IPS; | ||
235 | range.min_ip = range.max_ip | ||
236 | = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip; | ||
237 | /* hook doesn't matter, but it has to do source manip */ | ||
238 | nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING); | ||
239 | |||
240 | /* For DST manip, map port here to where it's expected. */ | ||
241 | range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED); | ||
242 | range.min = range.max = exp->saved_proto; | ||
243 | range.min_ip = range.max_ip = exp->saved_ip; | ||
244 | /* hook doesn't matter, but it has to do destination manip */ | ||
245 | nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); | ||
246 | } | ||
247 | |||
225 | /* So, this packet has hit the connection tracking matching code. | 248 | /* So, this packet has hit the connection tracking matching code. |
226 | Mangle it, and change the expectation to match the new version. */ | 249 | Mangle it, and change the expectation to match the new version. */ |
227 | static unsigned int ip_nat_sdp(struct sk_buff **pskb, | 250 | static unsigned int ip_nat_sdp(struct sk_buff **pskb, |
@@ -239,13 +262,14 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb, | |||
239 | /* Connection will come from reply */ | 262 | /* Connection will come from reply */ |
240 | newip = ct->tuplehash[!dir].tuple.dst.u3.ip; | 263 | newip = ct->tuplehash[!dir].tuple.dst.u3.ip; |
241 | 264 | ||
265 | exp->saved_ip = exp->tuple.dst.u3.ip; | ||
242 | exp->tuple.dst.u3.ip = newip; | 266 | exp->tuple.dst.u3.ip = newip; |
243 | exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port; | 267 | exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port; |
244 | exp->dir = !dir; | 268 | exp->dir = !dir; |
245 | 269 | ||
246 | /* When you see the packet, we need to NAT it the same as the | 270 | /* When you see the packet, we need to NAT it the same as the |
247 | this one. */ | 271 | this one. */ |
248 | exp->expectfn = nf_nat_follow_master; | 272 | exp->expectfn = ip_nat_sdp_expect; |
249 | 273 | ||
250 | /* Try to get same port: if not, try to change it. */ | 274 | /* Try to get same port: if not, try to change it. */ |
251 | for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) { | 275 | for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) { |