| @@ -183,12 +183,12 @@ static int media_len(const struct nf_conn *ct, const char *dptr, · 182 unmodified lines |
| 183 | return len + digits_len(ct, dptr, limit, shift); | 183 | return len + digits_len(ct, dptr, limit, shift); |
| 184 | } | 184 | } |
| 185 | | 185 | |
| 186 | static int parse_addr(const struct nf_conn *ct, const char *cp, | 186 | static int sip_parse_addr(const struct nf_conn *ct, const char *cp, |
| 187 | const char **endp, union nf_inet_addr *addr, | 187 | const char **endp, union nf_inet_addr *addr, |
| 188 | const char *limit) | 188 | const char *limit, bool delim) |
| 189 | { | 189 | { |
| 190 | const char *end; | 190 | const char *end; |
| 191 | int ret = 0; | 191 | int ret; |
| 192 | | 192 | |
| 193 | if (!ct) | 193 | if (!ct) |
| 194 | return 0; | 194 | return 0; |
| @@ -197,16 +197,28 @@ static int parse_addr(const struct nf_conn *ct, const char *cp, · 2 unmodified lines |
| 197 | switch (nf_ct_l3num(ct)) { | 197 | switch (nf_ct_l3num(ct)) { |
| 198 | case AF_INET: | 198 | case AF_INET: |
| 199 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); | 199 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); |
| | 200 | if (ret == 0) |
| | 201 | return 0; |
| 200 | break; | 202 | break; |
| 201 | case AF_INET6: | 203 | case AF_INET6: |
| | 204 | if (cp < limit && *cp == '[') |
| | 205 | cp++; |
| | 206 | else if (delim) |
| | 207 | return 0; |
| | 208 | |
| 202 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); | 209 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); |
| | 210 | if (ret == 0) |
| | 211 | return 0; |
| | 212 | |
| | 213 | if (end < limit && *end == ']') |
| | 214 | end++; |
| | 215 | else if (delim) |
| | 216 | return 0; |
| 203 | break; | 217 | break; |
| 204 | default: | 218 | default: |
| 205 | BUG(); | 219 | BUG(); |
| 206 | } | 220 | } |
| 207 | | 221 | |
| 208 | if (ret == 0 || end == cp) | | |
| 209 | return 0; | | |
| 210 | if (endp) | 222 | if (endp) |
| 211 | *endp = end; | 223 | *endp = end; |
| 212 | return 1; | 224 | return 1; |
| @@ -219,7 +231,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr, · 6 unmodified lines |
| 219 | union nf_inet_addr addr; | 231 | union nf_inet_addr addr; |
| 220 | const char *aux = dptr; | 232 | const char *aux = dptr; |
| 221 | | 233 | |
| 222 | if (!parse_addr(ct, dptr, &dptr, &addr, limit)) { | 234 | if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) { |
| 223 | pr_debug("ip: %s parse failed.!\n", dptr); | 235 | pr_debug("ip: %s parse failed.!\n", dptr); |
| 224 | return 0; | 236 | return 0; |
| 225 | } | 237 | } |
| @@ -296,7 +308,7 @@ int ct_sip_parse_request(const struct nf_conn *ct, · 70 unmodified lines |
| 296 | return 0; | 308 | return 0; |
| 297 | dptr += shift; | 309 | dptr += shift; |
| 298 | | 310 | |
| 299 | if (!parse_addr(ct, dptr, &end, addr, limit)) | 311 | if (!sip_parse_addr(ct, dptr, &end, addr, limit, true)) |
| 300 | return -1; | 312 | return -1; |
| 301 | if (end < limit && *end == ':') { | 313 | if (end < limit && *end == ':') { |
| 302 | end++; | 314 | end++; |
| @@ -550,7 +562,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr, · 247 unmodified lines |
| 550 | if (ret == 0) | 562 | if (ret == 0) |
| 551 | return ret; | 563 | return ret; |
| 552 | | 564 | |
| 553 | if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit)) | 565 | if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true)) |
| 554 | return -1; | 566 | return -1; |
| 555 | if (*c == ':') { | 567 | if (*c == ':') { |
| 556 | c++; | 568 | c++; |
| @@ -599,7 +611,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr, · 42 unmodified lines |
| 599 | unsigned int dataoff, unsigned int datalen, | 611 | unsigned int dataoff, unsigned int datalen, |
| 600 | const char *name, | 612 | const char *name, |
| 601 | unsigned int *matchoff, unsigned int *matchlen, | 613 | unsigned int *matchoff, unsigned int *matchlen, |
| 602 | union nf_inet_addr *addr) | 614 | union nf_inet_addr *addr, bool delim) |
| 603 | { | 615 | { |
| 604 | const char *limit = dptr + datalen; | 616 | const char *limit = dptr + datalen; |
| 605 | const char *start, *end; | 617 | const char *start, *end; |
| @@ -613,7 +625,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr, · 7 unmodified lines |
| 613 | return 0; | 625 | return 0; |
| 614 | | 626 | |
| 615 | start += strlen(name); | 627 | start += strlen(name); |
| 616 | if (!parse_addr(ct, start, &end, addr, limit)) | 628 | if (!sip_parse_addr(ct, start, &end, addr, limit, delim)) |
| 617 | return 0; | 629 | return 0; |
| 618 | *matchoff = start - dptr; | 630 | *matchoff = start - dptr; |
| 619 | *matchlen = end - start; | 631 | *matchlen = end - start; |
| @@ -675,6 +687,47 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, · 55 unmodified lines |
| 675 | return 1; | 687 | return 1; |
| 676 | } | 688 | } |
| 677 | | 689 | |
| | 690 | static int sdp_parse_addr(const struct nf_conn *ct, const char *cp, |
| | 691 | const char **endp, union nf_inet_addr *addr, |
| | 692 | const char *limit) |
| | 693 | { |
| | 694 | const char *end; |
| | 695 | int ret; |
| | 696 | |
| | 697 | memset(addr, 0, sizeof(*addr)); |
| | 698 | switch (nf_ct_l3num(ct)) { |
| | 699 | case AF_INET: |
| | 700 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); |
| | 701 | break; |
| | 702 | case AF_INET6: |
| | 703 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); |
| | 704 | break; |
| | 705 | default: |
| | 706 | BUG(); |
| | 707 | } |
| | 708 | |
| | 709 | if (ret == 0) |
| | 710 | return 0; |
| | 711 | if (endp) |
| | 712 | *endp = end; |
| | 713 | return 1; |
| | 714 | } |
| | 715 | |
| | 716 | /* skip ip address. returns its length. */ |
| | 717 | static int sdp_addr_len(const struct nf_conn *ct, const char *dptr, |
| | 718 | const char *limit, int *shift) |
| | 719 | { |
| | 720 | union nf_inet_addr addr; |
| | 721 | const char *aux = dptr; |
| | 722 | |
| | 723 | if (!sdp_parse_addr(ct, dptr, &dptr, &addr, limit)) { |
| | 724 | pr_debug("ip: %s parse failed.!\n", dptr); |
| | 725 | return 0; |
| | 726 | } |
| | 727 | |
| | 728 | return dptr - aux; |
| | 729 | } |
| | 730 | |
| 678 | /* SDP header parsing: a SDP session description contains an ordered set of | 731 | /* SDP header parsing: a SDP session description contains an ordered set of |
| 679 | * headers, starting with a section containing general session parameters, | 732 | * headers, starting with a section containing general session parameters, |
| 680 | * optionally followed by multiple media descriptions. | 733 | * optionally followed by multiple media descriptions. |
| @@ -686,10 +739,10 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, · 5 unmodified lines |
| 686 | */ | 739 | */ |
| 687 | static const struct sip_header ct_sdp_hdrs[] = { | 740 | static const struct sip_header ct_sdp_hdrs[] = { |
| 688 | [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len), | 741 | [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len), |
| 689 | [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len), | 742 | [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", sdp_addr_len), |
| 690 | [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len), | 743 | [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", sdp_addr_len), |
| 691 | [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len), | 744 | [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", sdp_addr_len), |
| 692 | [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len), | 745 | [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", sdp_addr_len), |
| 693 | [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len), | 746 | [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len), |
| 694 | }; | 747 | }; |
| 695 | | 748 | |
| @@ -775,8 +828,8 @@ static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr, · 79 unmodified lines |
| 775 | if (ret <= 0) | 828 | if (ret <= 0) |
| 776 | return ret; | 829 | return ret; |
| 777 | | 830 | |
| 778 | if (!parse_addr(ct, dptr + *matchoff, NULL, addr, | 831 | if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr, |
| 779 | dptr + *matchoff + *matchlen)) | 832 | dptr + *matchoff + *matchlen)) |
| 780 | return -1; | 833 | return -1; |
| 781 | return 1; | 834 | return 1; |
| 782 | } | 835 | } |