diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/nf_nat_sip.c | 38 |
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 | ||
321 | static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr, | 321 | static 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 | ||
338 | static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, | 338 | static 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 | } |