aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-05-03 06:35:31 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-03 06:35:31 -0400
commitcfd6c38096d75c8b86782683c5f45c415a505b78 (patch)
treee89cf155ed3f19bdce288da522e5f1b7445065b9 /net/ipv4
parentc2a1910b06fed96db77bb358c18c52a1fcf2b7fe (diff)
[NETFILTER]: sip: Fix RTP address NAT
I needed to use this recently to talk to a Cisco server. In my case I only did SNAT while the Cisco server used a different address for RTP traffic than the one for SIP. I discovered that nf_nat_sip NATed the RTP address to the SIP one which was unnecessary but OK. However, in doing so it did not DNAT the destination address on the RTP traffic to the Cisco back to the original RTP address. This patch corrects this by noting down the RTP address and using it when the expectation fires. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c26
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
225static 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. */
227static unsigned int ip_nat_sdp(struct sk_buff **pskb, 250static 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++) {