aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-07-21 13:03:23 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-21 13:11:02 -0400
commitc71529e42ce39c167dc53430cb8f3d5634af77df (patch)
tree4d7d97e2f35b72ee5da618ffdf60eb53e58350d8 /net
parentdb1a75bdcc1766dc7e1fae9201ae287dcbcb6c66 (diff)
netfilter: nf_nat_sip: c= is optional for session
According to RFC2327, the connection information is optional in the session description since it can be specified in the media description instead. My provider does exactly that and does not provide any connection information in the session description. As a result the new kernel drops all invite responses. This patch makes it optional as documented. 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')
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 4334d5cabc5b..14544320c545 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -318,11 +318,11 @@ static int mangle_content_len(struct sk_buff *skb,
318 buffer, buflen); 318 buffer, buflen);
319} 319}
320 320
321static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr, 321static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
322 unsigned int dataoff, unsigned int *datalen, 322 unsigned int dataoff, unsigned int *datalen,
323 enum sdp_header_types type, 323 enum sdp_header_types type,
324 enum sdp_header_types term, 324 enum sdp_header_types term,
325 char *buffer, int buflen) 325 char *buffer, int buflen)
326{ 326{
327 enum ip_conntrack_info ctinfo; 327 enum ip_conntrack_info ctinfo;
328 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 328 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
@@ -330,9 +330,9 @@ static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
330 330
331 if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term, 331 if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term,
332 &matchoff, &matchlen) <= 0) 332 &matchoff, &matchlen) <= 0)
333 return 0; 333 return -ENOENT;
334 return mangle_packet(skb, dptr, datalen, matchoff, matchlen, 334 return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
335 buffer, buflen); 335 buffer, buflen) ? 0 : -EINVAL;
336} 336}
337 337
338static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, 338static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
@@ -346,8 +346,8 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
346 unsigned int buflen; 346 unsigned int buflen;
347 347
348 buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip)); 348 buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip));
349 if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term, 349 if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
350 buffer, buflen)) 350 buffer, buflen))
351 return 0; 351 return 0;
352 352
353 return mangle_content_len(skb, dptr, datalen); 353 return mangle_content_len(skb, dptr, datalen);
@@ -381,15 +381,27 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
381 381
382 /* Mangle session description owner and contact addresses */ 382 /* Mangle session description owner and contact addresses */
383 buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip)); 383 buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip));
384 if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, 384 if (mangle_sdp_packet(skb, dptr, dataoff, datalen,
385 SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA, 385 SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
386 buffer, buflen)) 386 buffer, buflen))
387 return 0; 387 return 0;
388 388
389 if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, 389 switch (mangle_sdp_packet(skb, dptr, dataoff, datalen,
390 SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA, 390 SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
391 buffer, buflen)) 391 buffer, buflen)) {
392 case 0:
393 /*
394 * RFC 2327:
395 *
396 * Session description
397 *
398 * c=* (connection information - not required if included in all media)
399 */
400 case -ENOENT:
401 break;
402 default:
392 return 0; 403 return 0;
404 }
393 405
394 return mangle_content_len(skb, dptr, datalen); 406 return mangle_content_len(skb, dptr, datalen);
395} 407}