linux/net/netfilter/nf_conntrack_sip.c
<<
>>
Prefs
   1/* SIP extension for IP connection tracking.
   2 *
   3 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
   4 * based on RR's ip_conntrack_ftp.c and other modules.
   5 * (C) 2007 United Security Providers
   6 * (C) 2007, 2008 Patrick McHardy <kaber@trash.net>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/ctype.h>
  15#include <linux/skbuff.h>
  16#include <linux/inet.h>
  17#include <linux/in.h>
  18#include <linux/udp.h>
  19#include <linux/tcp.h>
  20#include <linux/netfilter.h>
  21
  22#include <net/netfilter/nf_conntrack.h>
  23#include <net/netfilter/nf_conntrack_core.h>
  24#include <net/netfilter/nf_conntrack_expect.h>
  25#include <net/netfilter/nf_conntrack_helper.h>
  26#include <net/netfilter/nf_conntrack_zones.h>
  27#include <linux/netfilter/nf_conntrack_sip.h>
  28
  29MODULE_LICENSE("GPL");
  30MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
  31MODULE_DESCRIPTION("SIP connection tracking helper");
  32MODULE_ALIAS("ip_conntrack_sip");
  33MODULE_ALIAS_NFCT_HELPER("sip");
  34
  35#define MAX_PORTS       8
  36static unsigned short ports[MAX_PORTS];
  37static unsigned int ports_c;
  38module_param_array(ports, ushort, &ports_c, 0400);
  39MODULE_PARM_DESC(ports, "port numbers of SIP servers");
  40
  41static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
  42module_param(sip_timeout, uint, 0600);
  43MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
  44
  45static int sip_direct_signalling __read_mostly = 1;
  46module_param(sip_direct_signalling, int, 0600);
  47MODULE_PARM_DESC(sip_direct_signalling, "expect incoming calls from registrar "
  48                                        "only (default 1)");
  49
  50static int sip_direct_media __read_mostly = 1;
  51module_param(sip_direct_media, int, 0600);
  52MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
  53                                   "endpoints only (default 1)");
  54
  55unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int dataoff,
  56                                const char **dptr,
  57                                unsigned int *datalen) __read_mostly;
  58EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
  59
  60void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, s16 off) __read_mostly;
  61EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook);
  62
  63unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
  64                                       unsigned int dataoff,
  65                                       const char **dptr,
  66                                       unsigned int *datalen,
  67                                       struct nf_conntrack_expect *exp,
  68                                       unsigned int matchoff,
  69                                       unsigned int matchlen) __read_mostly;
  70EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
  71
  72unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int dataoff,
  73                                     const char **dptr,
  74                                     unsigned int *datalen,
  75                                     unsigned int sdpoff,
  76                                     enum sdp_header_types type,
  77                                     enum sdp_header_types term,
  78                                     const union nf_inet_addr *addr)
  79                                     __read_mostly;
  80EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
  81
  82unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int dataoff,
  83                                     const char **dptr,
  84                                     unsigned int *datalen,
  85                                     unsigned int matchoff,
  86                                     unsigned int matchlen,
  87                                     u_int16_t port) __read_mostly;
  88EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
  89
  90unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
  91                                        unsigned int dataoff,
  92                                        const char **dptr,
  93                                        unsigned int *datalen,
  94                                        unsigned int sdpoff,
  95                                        const union nf_inet_addr *addr)
  96                                        __read_mostly;
  97EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
  98
  99unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int dataoff,
 100                                      const char **dptr,
 101                                      unsigned int *datalen,
 102                                      struct nf_conntrack_expect *rtp_exp,
 103                                      struct nf_conntrack_expect *rtcp_exp,
 104                                      unsigned int mediaoff,
 105                                      unsigned int medialen,
 106                                      union nf_inet_addr *rtp_addr)
 107                                      __read_mostly;
 108EXPORT_SYMBOL_GPL(nf_nat_sdp_media_hook);
 109
 110static int string_len(const struct nf_conn *ct, const char *dptr,
 111                      const char *limit, int *shift)
 112{
 113        int len = 0;
 114
 115        while (dptr < limit && isalpha(*dptr)) {
 116                dptr++;
 117                len++;
 118        }
 119        return len;
 120}
 121
 122static int digits_len(const struct nf_conn *ct, const char *dptr,
 123                      const char *limit, int *shift)
 124{
 125        int len = 0;
 126        while (dptr < limit && isdigit(*dptr)) {
 127                dptr++;
 128                len++;
 129        }
 130        return len;
 131}
 132
 133static int iswordc(const char c)
 134{
 135        if (isalnum(c) || c == '!' || c == '"' || c == '%' ||
 136            (c >= '(' && c <= '/') || c == ':' || c == '<' || c == '>' ||
 137            c == '?' || (c >= '[' && c <= ']') || c == '_' || c == '`' ||
 138            c == '{' || c == '}' || c == '~')
 139                return 1;
 140        return 0;
 141}
 142
 143static int word_len(const char *dptr, const char *limit)
 144{
 145        int len = 0;
 146        while (dptr < limit && iswordc(*dptr)) {
 147                dptr++;
 148                len++;
 149        }
 150        return len;
 151}
 152
 153static int callid_len(const struct nf_conn *ct, const char *dptr,
 154                      const char *limit, int *shift)
 155{
 156        int len, domain_len;
 157
 158        len = word_len(dptr, limit);
 159        dptr += len;
 160        if (!len || dptr == limit || *dptr != '@')
 161                return len;
 162        dptr++;
 163        len++;
 164
 165        domain_len = word_len(dptr, limit);
 166        if (!domain_len)
 167                return 0;
 168        return len + domain_len;
 169}
 170
 171/* get media type + port length */
 172static int media_len(const struct nf_conn *ct, const char *dptr,
 173                     const char *limit, int *shift)
 174{
 175        int len = string_len(ct, dptr, limit, shift);
 176
 177        dptr += len;
 178        if (dptr >= limit || *dptr != ' ')
 179                return 0;
 180        len++;
 181        dptr++;
 182
 183        return len + digits_len(ct, dptr, limit, shift);
 184}
 185
 186static int sip_parse_addr(const struct nf_conn *ct, const char *cp,
 187                          const char **endp, union nf_inet_addr *addr,
 188                          const char *limit, bool delim)
 189{
 190        const char *end;
 191        int ret;
 192
 193        if (!ct)
 194                return 0;
 195
 196        memset(addr, 0, sizeof(*addr));
 197        switch (nf_ct_l3num(ct)) {
 198        case AF_INET:
 199                ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
 200                if (ret == 0)
 201                        return 0;
 202                break;
 203        case AF_INET6:
 204                if (cp < limit && *cp == '[')
 205                        cp++;
 206                else if (delim)
 207                        return 0;
 208
 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;
 217                break;
 218        default:
 219                BUG();
 220        }
 221
 222        if (endp)
 223                *endp = end;
 224        return 1;
 225}
 226
 227/* skip ip address. returns its length. */
 228static int epaddr_len(const struct nf_conn *ct, const char *dptr,
 229                      const char *limit, int *shift)
 230{
 231        union nf_inet_addr addr;
 232        const char *aux = dptr;
 233
 234        if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) {
 235                pr_debug("ip: %s parse failed.!\n", dptr);
 236                return 0;
 237        }
 238
 239        /* Port number */
 240        if (*dptr == ':') {
 241                dptr++;
 242                dptr += digits_len(ct, dptr, limit, shift);
 243        }
 244        return dptr - aux;
 245}
 246
 247/* get address length, skiping user info. */
 248static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr,
 249                          const char *limit, int *shift)
 250{
 251        const char *start = dptr;
 252        int s = *shift;
 253
 254        /* Search for @, but stop at the end of the line.
 255         * We are inside a sip: URI, so we don't need to worry about
 256         * continuation lines. */
 257        while (dptr < limit &&
 258               *dptr != '@' && *dptr != '\r' && *dptr != '\n') {
 259                (*shift)++;
 260                dptr++;
 261        }
 262
 263        if (dptr < limit && *dptr == '@') {
 264                dptr++;
 265                (*shift)++;
 266        } else {
 267                dptr = start;
 268                *shift = s;
 269        }
 270
 271        return epaddr_len(ct, dptr, limit, shift);
 272}
 273
 274/* Parse a SIP request line of the form:
 275 *
 276 * Request-Line = Method SP Request-URI SP SIP-Version CRLF
 277 *
 278 * and return the offset and length of the address contained in the Request-URI.
 279 */
 280int ct_sip_parse_request(const struct nf_conn *ct,
 281                         const char *dptr, unsigned int datalen,
 282                         unsigned int *matchoff, unsigned int *matchlen,
 283                         union nf_inet_addr *addr, __be16 *port)
 284{
 285        const char *start = dptr, *limit = dptr + datalen, *end;
 286        unsigned int mlen;
 287        unsigned int p;
 288        int shift = 0;
 289
 290        /* Skip method and following whitespace */
 291        mlen = string_len(ct, dptr, limit, NULL);
 292        if (!mlen)
 293                return 0;
 294        dptr += mlen;
 295        if (++dptr >= limit)
 296                return 0;
 297
 298        /* Find SIP URI */
 299        for (; dptr < limit - strlen("sip:"); dptr++) {
 300                if (*dptr == '\r' || *dptr == '\n')
 301                        return -1;
 302                if (strnicmp(dptr, "sip:", strlen("sip:")) == 0) {
 303                        dptr += strlen("sip:");
 304                        break;
 305                }
 306        }
 307        if (!skp_epaddr_len(ct, dptr, limit, &shift))
 308                return 0;
 309        dptr += shift;
 310
 311        if (!sip_parse_addr(ct, dptr, &end, addr, limit, true))
 312                return -1;
 313        if (end < limit && *end == ':') {
 314                end++;
 315                p = simple_strtoul(end, (char **)&end, 10);
 316                if (p < 1024 || p > 65535)
 317                        return -1;
 318                *port = htons(p);
 319        } else
 320                *port = htons(SIP_PORT);
 321
 322        if (end == dptr)
 323                return 0;
 324        *matchoff = dptr - start;
 325        *matchlen = end - dptr;
 326        return 1;
 327}
 328EXPORT_SYMBOL_GPL(ct_sip_parse_request);
 329
 330/* SIP header parsing: SIP headers are located at the beginning of a line, but
 331 * may span several lines, in which case the continuation lines begin with a
 332 * whitespace character. RFC 2543 allows lines to be terminated with CR, LF or
 333 * CRLF, RFC 3261 allows only CRLF, we support both.
 334 *
 335 * Headers are followed by (optionally) whitespace, a colon, again (optionally)
 336 * whitespace and the values. Whitespace in this context means any amount of
 337 * tabs, spaces and continuation lines, which are treated as a single whitespace
 338 * character.
 339 *
 340 * Some headers may appear multiple times. A comma separated list of values is
 341 * equivalent to multiple headers.
 342 */
 343static const struct sip_header ct_sip_hdrs[] = {
 344        [SIP_HDR_CSEQ]                  = SIP_HDR("CSeq", NULL, NULL, digits_len),
 345        [SIP_HDR_FROM]                  = SIP_HDR("From", "f", "sip:", skp_epaddr_len),
 346        [SIP_HDR_TO]                    = SIP_HDR("To", "t", "sip:", skp_epaddr_len),
 347        [SIP_HDR_CONTACT]               = SIP_HDR("Contact", "m", "sip:", skp_epaddr_len),
 348        [SIP_HDR_VIA_UDP]               = SIP_HDR("Via", "v", "UDP ", epaddr_len),
 349        [SIP_HDR_VIA_TCP]               = SIP_HDR("Via", "v", "TCP ", epaddr_len),
 350        [SIP_HDR_EXPIRES]               = SIP_HDR("Expires", NULL, NULL, digits_len),
 351        [SIP_HDR_CONTENT_LENGTH]        = SIP_HDR("Content-Length", "l", NULL, digits_len),
 352        [SIP_HDR_CALL_ID]               = SIP_HDR("Call-Id", "i", NULL, callid_len),
 353};
 354
 355static const char *sip_follow_continuation(const char *dptr, const char *limit)
 356{
 357        /* Walk past newline */
 358        if (++dptr >= limit)
 359                return NULL;
 360
 361        /* Skip '\n' in CR LF */
 362        if (*(dptr - 1) == '\r' && *dptr == '\n') {
 363                if (++dptr >= limit)
 364                        return NULL;
 365        }
 366
 367        /* Continuation line? */
 368        if (*dptr != ' ' && *dptr != '\t')
 369                return NULL;
 370
 371        /* skip leading whitespace */
 372        for (; dptr < limit; dptr++) {
 373                if (*dptr != ' ' && *dptr != '\t')
 374                        break;
 375        }
 376        return dptr;
 377}
 378
 379static const char *sip_skip_whitespace(const char *dptr, const char *limit)
 380{
 381        for (; dptr < limit; dptr++) {
 382                if (*dptr == ' ')
 383                        continue;
 384                if (*dptr != '\r' && *dptr != '\n')
 385                        break;
 386                dptr = sip_follow_continuation(dptr, limit);
 387                if (dptr == NULL)
 388                        return NULL;
 389        }
 390        return dptr;
 391}
 392
 393/* Search within a SIP header value, dealing with continuation lines */
 394static const char *ct_sip_header_search(const char *dptr, const char *limit,
 395                                        const char *needle, unsigned int len)
 396{
 397        for (limit -= len; dptr < limit; dptr++) {
 398                if (*dptr == '\r' || *dptr == '\n') {
 399                        dptr = sip_follow_continuation(dptr, limit);
 400                        if (dptr == NULL)
 401                                break;
 402                        continue;
 403                }
 404
 405                if (strnicmp(dptr, needle, len) == 0)
 406                        return dptr;
 407        }
 408        return NULL;
 409}
 410
 411int ct_sip_get_header(const struct nf_conn *ct, const char *dptr,
 412                      unsigned int dataoff, unsigned int datalen,
 413                      enum sip_header_types type,
 414                      unsigned int *matchoff, unsigned int *matchlen)
 415{
 416        const struct sip_header *hdr = &ct_sip_hdrs[type];
 417        const char *start = dptr, *limit = dptr + datalen;
 418        int shift = 0;
 419
 420        for (dptr += dataoff; dptr < limit; dptr++) {
 421                /* Find beginning of line */
 422                if (*dptr != '\r' && *dptr != '\n')
 423                        continue;
 424                if (++dptr >= limit)
 425                        break;
 426                if (*(dptr - 1) == '\r' && *dptr == '\n') {
 427                        if (++dptr >= limit)
 428                                break;
 429                }
 430
 431                /* Skip continuation lines */
 432                if (*dptr == ' ' || *dptr == '\t')
 433                        continue;
 434
 435                /* Find header. Compact headers must be followed by a
 436                 * non-alphabetic character to avoid mismatches. */
 437                if (limit - dptr >= hdr->len &&
 438                    strnicmp(dptr, hdr->name, hdr->len) == 0)
 439                        dptr += hdr->len;
 440                else if (hdr->cname && limit - dptr >= hdr->clen + 1 &&
 441                         strnicmp(dptr, hdr->cname, hdr->clen) == 0 &&
 442                         !isalpha(*(dptr + hdr->clen)))
 443                        dptr += hdr->clen;
 444                else
 445                        continue;
 446
 447                /* Find and skip colon */
 448                dptr = sip_skip_whitespace(dptr, limit);
 449                if (dptr == NULL)
 450                        break;
 451                if (*dptr != ':' || ++dptr >= limit)
 452                        break;
 453
 454                /* Skip whitespace after colon */
 455                dptr = sip_skip_whitespace(dptr, limit);
 456                if (dptr == NULL)
 457                        break;
 458
 459                *matchoff = dptr - start;
 460                if (hdr->search) {
 461                        dptr = ct_sip_header_search(dptr, limit, hdr->search,
 462                                                    hdr->slen);
 463                        if (!dptr)
 464                                return -1;
 465                        dptr += hdr->slen;
 466                }
 467
 468                *matchlen = hdr->match_len(ct, dptr, limit, &shift);
 469                if (!*matchlen)
 470                        return -1;
 471                *matchoff = dptr - start + shift;
 472                return 1;
 473        }
 474        return 0;
 475}
 476EXPORT_SYMBOL_GPL(ct_sip_get_header);
 477
 478/* Get next header field in a list of comma separated values */
 479static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr,
 480                              unsigned int dataoff, unsigned int datalen,
 481                              enum sip_header_types type,
 482                              unsigned int *matchoff, unsigned int *matchlen)
 483{
 484        const struct sip_header *hdr = &ct_sip_hdrs[type];
 485        const char *start = dptr, *limit = dptr + datalen;
 486        int shift = 0;
 487
 488        dptr += dataoff;
 489
 490        dptr = ct_sip_header_search(dptr, limit, ",", strlen(","));
 491        if (!dptr)
 492                return 0;
 493
 494        dptr = ct_sip_header_search(dptr, limit, hdr->search, hdr->slen);
 495        if (!dptr)
 496                return 0;
 497        dptr += hdr->slen;
 498
 499        *matchoff = dptr - start;
 500        *matchlen = hdr->match_len(ct, dptr, limit, &shift);
 501        if (!*matchlen)
 502                return -1;
 503        *matchoff += shift;
 504        return 1;
 505}
 506
 507/* Walk through headers until a parsable one is found or no header of the
 508 * given type is left. */
 509static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
 510                               unsigned int dataoff, unsigned int datalen,
 511                               enum sip_header_types type, int *in_header,
 512                               unsigned int *matchoff, unsigned int *matchlen)
 513{
 514        int ret;
 515
 516        if (in_header && *in_header) {
 517                while (1) {
 518                        ret = ct_sip_next_header(ct, dptr, dataoff, datalen,
 519                                                 type, matchoff, matchlen);
 520                        if (ret > 0)
 521                                return ret;
 522                        if (ret == 0)
 523                                break;
 524                        dataoff += *matchoff;
 525                }
 526                *in_header = 0;
 527        }
 528
 529        while (1) {
 530                ret = ct_sip_get_header(ct, dptr, dataoff, datalen,
 531                                        type, matchoff, matchlen);
 532                if (ret > 0)
 533                        break;
 534                if (ret == 0)
 535                        return ret;
 536                dataoff += *matchoff;
 537        }
 538
 539        if (in_header)
 540                *in_header = 1;
 541        return 1;
 542}
 543
 544/* Locate a SIP header, parse the URI and return the offset and length of
 545 * the address as well as the address and port themselves. A stream of
 546 * headers can be parsed by handing in a non-NULL datalen and in_header
 547 * pointer.
 548 */
 549int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
 550                            unsigned int *dataoff, unsigned int datalen,
 551                            enum sip_header_types type, int *in_header,
 552                            unsigned int *matchoff, unsigned int *matchlen,
 553                            union nf_inet_addr *addr, __be16 *port)
 554{
 555        const char *c, *limit = dptr + datalen;
 556        unsigned int p;
 557        int ret;
 558
 559        ret = ct_sip_walk_headers(ct, dptr, dataoff ? *dataoff : 0, datalen,
 560                                  type, in_header, matchoff, matchlen);
 561        WARN_ON(ret < 0);
 562        if (ret == 0)
 563                return ret;
 564
 565        if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true))
 566                return -1;
 567        if (*c == ':') {
 568                c++;
 569                p = simple_strtoul(c, (char **)&c, 10);
 570                if (p < 1024 || p > 65535)
 571                        return -1;
 572                *port = htons(p);
 573        } else
 574                *port = htons(SIP_PORT);
 575
 576        if (dataoff)
 577                *dataoff = c - dptr;
 578        return 1;
 579}
 580EXPORT_SYMBOL_GPL(ct_sip_parse_header_uri);
 581
 582static int ct_sip_parse_param(const struct nf_conn *ct, const char *dptr,
 583                              unsigned int dataoff, unsigned int datalen,
 584                              const char *name,
 585                              unsigned int *matchoff, unsigned int *matchlen)
 586{
 587        const char *limit = dptr + datalen;
 588        const char *start;
 589        const char *end;
 590
 591        limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
 592        if (!limit)
 593                limit = dptr + datalen;
 594
 595        start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
 596        if (!start)
 597                return 0;
 598        start += strlen(name);
 599
 600        end = ct_sip_header_search(start, limit, ";", strlen(";"));
 601        if (!end)
 602                end = limit;
 603
 604        *matchoff = start - dptr;
 605        *matchlen = end - start;
 606        return 1;
 607}
 608
 609/* Parse address from header parameter and return address, offset and length */
 610int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
 611                               unsigned int dataoff, unsigned int datalen,
 612                               const char *name,
 613                               unsigned int *matchoff, unsigned int *matchlen,
 614                               union nf_inet_addr *addr, bool delim)
 615{
 616        const char *limit = dptr + datalen;
 617        const char *start, *end;
 618
 619        limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
 620        if (!limit)
 621                limit = dptr + datalen;
 622
 623        start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
 624        if (!start)
 625                return 0;
 626
 627        start += strlen(name);
 628        if (!sip_parse_addr(ct, start, &end, addr, limit, delim))
 629                return 0;
 630        *matchoff = start - dptr;
 631        *matchlen = end - start;
 632        return 1;
 633}
 634EXPORT_SYMBOL_GPL(ct_sip_parse_address_param);
 635
 636/* Parse numerical header parameter and return value, offset and length */
 637int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
 638                                 unsigned int dataoff, unsigned int datalen,
 639                                 const char *name,
 640                                 unsigned int *matchoff, unsigned int *matchlen,
 641                                 unsigned int *val)
 642{
 643        const char *limit = dptr + datalen;
 644        const char *start;
 645        char *end;
 646
 647        limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
 648        if (!limit)
 649                limit = dptr + datalen;
 650
 651        start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
 652        if (!start)
 653                return 0;
 654
 655        start += strlen(name);
 656        *val = simple_strtoul(start, &end, 0);
 657        if (start == end)
 658                return 0;
 659        if (matchoff && matchlen) {
 660                *matchoff = start - dptr;
 661                *matchlen = end - start;
 662        }
 663        return 1;
 664}
 665EXPORT_SYMBOL_GPL(ct_sip_parse_numerical_param);
 666
 667static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
 668                                  unsigned int dataoff, unsigned int datalen,
 669                                  u8 *proto)
 670{
 671        unsigned int matchoff, matchlen;
 672
 673        if (ct_sip_parse_param(ct, dptr, dataoff, datalen, "transport=",
 674                               &matchoff, &matchlen)) {
 675                if (!strnicmp(dptr + matchoff, "TCP", strlen("TCP")))
 676                        *proto = IPPROTO_TCP;
 677                else if (!strnicmp(dptr + matchoff, "UDP", strlen("UDP")))
 678                        *proto = IPPROTO_UDP;
 679                else
 680                        return 0;
 681
 682                if (*proto != nf_ct_protonum(ct))
 683                        return 0;
 684        } else
 685                *proto = nf_ct_protonum(ct);
 686
 687        return 1;
 688}
 689
 690static 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. */
 717static 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
 731/* SDP header parsing: a SDP session description contains an ordered set of
 732 * headers, starting with a section containing general session parameters,
 733 * optionally followed by multiple media descriptions.
 734 *
 735 * SDP headers always start at the beginning of a line. According to RFC 2327:
 736 * "The sequence CRLF (0x0d0a) is used to end a record, although parsers should
 737 * be tolerant and also accept records terminated with a single newline
 738 * character". We handle both cases.
 739 */
 740static const struct sip_header ct_sdp_hdrs[] = {
 741        [SDP_HDR_VERSION]               = SDP_HDR("v=", NULL, digits_len),
 742        [SDP_HDR_OWNER_IP4]             = SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
 743        [SDP_HDR_CONNECTION_IP4]        = SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
 744        [SDP_HDR_OWNER_IP6]             = SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
 745        [SDP_HDR_CONNECTION_IP6]        = SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
 746        [SDP_HDR_MEDIA]                 = SDP_HDR("m=", NULL, media_len),
 747};
 748
 749/* Linear string search within SDP header values */
 750static const char *ct_sdp_header_search(const char *dptr, const char *limit,
 751                                        const char *needle, unsigned int len)
 752{
 753        for (limit -= len; dptr < limit; dptr++) {
 754                if (*dptr == '\r' || *dptr == '\n')
 755                        break;
 756                if (strncmp(dptr, needle, len) == 0)
 757                        return dptr;
 758        }
 759        return NULL;
 760}
 761
 762/* Locate a SDP header (optionally a substring within the header value),
 763 * optionally stopping at the first occurrence of the term header, parse
 764 * it and return the offset and length of the data we're interested in.
 765 */
 766int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr,
 767                          unsigned int dataoff, unsigned int datalen,
 768                          enum sdp_header_types type,
 769                          enum sdp_header_types term,
 770                          unsigned int *matchoff, unsigned int *matchlen)
 771{
 772        const struct sip_header *hdr = &ct_sdp_hdrs[type];
 773        const struct sip_header *thdr = &ct_sdp_hdrs[term];
 774        const char *start = dptr, *limit = dptr + datalen;
 775        int shift = 0;
 776
 777        for (dptr += dataoff; dptr < limit; dptr++) {
 778                /* Find beginning of line */
 779                if (*dptr != '\r' && *dptr != '\n')
 780                        continue;
 781                if (++dptr >= limit)
 782                        break;
 783                if (*(dptr - 1) == '\r' && *dptr == '\n') {
 784                        if (++dptr >= limit)
 785                                break;
 786                }
 787
 788                if (term != SDP_HDR_UNSPEC &&
 789                    limit - dptr >= thdr->len &&
 790                    strnicmp(dptr, thdr->name, thdr->len) == 0)
 791                        break;
 792                else if (limit - dptr >= hdr->len &&
 793                         strnicmp(dptr, hdr->name, hdr->len) == 0)
 794                        dptr += hdr->len;
 795                else
 796                        continue;
 797
 798                *matchoff = dptr - start;
 799                if (hdr->search) {
 800                        dptr = ct_sdp_header_search(dptr, limit, hdr->search,
 801                                                    hdr->slen);
 802                        if (!dptr)
 803                                return -1;
 804                        dptr += hdr->slen;
 805                }
 806
 807                *matchlen = hdr->match_len(ct, dptr, limit, &shift);
 808                if (!*matchlen)
 809                        return -1;
 810                *matchoff = dptr - start + shift;
 811                return 1;
 812        }
 813        return 0;
 814}
 815EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header);
 816
 817static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr,
 818                                 unsigned int dataoff, unsigned int datalen,
 819                                 enum sdp_header_types type,
 820                                 enum sdp_header_types term,
 821                                 unsigned int *matchoff, unsigned int *matchlen,
 822                                 union nf_inet_addr *addr)
 823{
 824        int ret;
 825
 826        ret = ct_sip_get_sdp_header(ct, dptr, dataoff, datalen, type, term,
 827                                    matchoff, matchlen);
 828        if (ret <= 0)
 829                return ret;
 830
 831        if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr,
 832                            dptr + *matchoff + *matchlen))
 833                return -1;
 834        return 1;
 835}
 836
 837static int refresh_signalling_expectation(struct nf_conn *ct,
 838                                          union nf_inet_addr *addr,
 839                                          u8 proto, __be16 port,
 840                                          unsigned int expires)
 841{
 842        struct nf_conn_help *help = nfct_help(ct);
 843        struct nf_conntrack_expect *exp;
 844        struct hlist_node *n, *next;
 845        int found = 0;
 846
 847        spin_lock_bh(&nf_conntrack_lock);
 848        hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
 849                if (exp->class != SIP_EXPECT_SIGNALLING ||
 850                    !nf_inet_addr_cmp(&exp->tuple.dst.u3, addr) ||
 851                    exp->tuple.dst.protonum != proto ||
 852                    exp->tuple.dst.u.udp.port != port)
 853                        continue;
 854                if (!del_timer(&exp->timeout))
 855                        continue;
 856                exp->flags &= ~NF_CT_EXPECT_INACTIVE;
 857                exp->timeout.expires = jiffies + expires * HZ;
 858                add_timer(&exp->timeout);
 859                found = 1;
 860                break;
 861        }
 862        spin_unlock_bh(&nf_conntrack_lock);
 863        return found;
 864}
 865
 866static void flush_expectations(struct nf_conn *ct, bool media)
 867{
 868        struct nf_conn_help *help = nfct_help(ct);
 869        struct nf_conntrack_expect *exp;
 870        struct hlist_node *n, *next;
 871
 872        spin_lock_bh(&nf_conntrack_lock);
 873        hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
 874                if ((exp->class != SIP_EXPECT_SIGNALLING) ^ media)
 875                        continue;
 876                if (!del_timer(&exp->timeout))
 877                        continue;
 878                nf_ct_unlink_expect(exp);
 879                nf_ct_expect_put(exp);
 880                if (!media)
 881                        break;
 882        }
 883        spin_unlock_bh(&nf_conntrack_lock);
 884}
 885
 886static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff,
 887                                 const char **dptr, unsigned int *datalen,
 888                                 union nf_inet_addr *daddr, __be16 port,
 889                                 enum sip_expectation_classes class,
 890                                 unsigned int mediaoff, unsigned int medialen)
 891{
 892        struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp;
 893        enum ip_conntrack_info ctinfo;
 894        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
 895        struct net *net = nf_ct_net(ct);
 896        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 897        union nf_inet_addr *saddr;
 898        struct nf_conntrack_tuple tuple;
 899        int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
 900        u_int16_t base_port;
 901        __be16 rtp_port, rtcp_port;
 902        typeof(nf_nat_sdp_port_hook) nf_nat_sdp_port;
 903        typeof(nf_nat_sdp_media_hook) nf_nat_sdp_media;
 904
 905        saddr = NULL;
 906        if (sip_direct_media) {
 907                if (!nf_inet_addr_cmp(daddr, &ct->tuplehash[dir].tuple.src.u3))
 908                        return NF_ACCEPT;
 909                saddr = &ct->tuplehash[!dir].tuple.src.u3;
 910        }
 911
 912        /* We need to check whether the registration exists before attempting
 913         * to register it since we can see the same media description multiple
 914         * times on different connections in case multiple endpoints receive
 915         * the same call.
 916         *
 917         * RTP optimization: if we find a matching media channel expectation
 918         * and both the expectation and this connection are SNATed, we assume
 919         * both sides can reach each other directly and use the final
 920         * destination address from the expectation. We still need to keep
 921         * the NATed expectations for media that might arrive from the
 922         * outside, and additionally need to expect the direct RTP stream
 923         * in case it passes through us even without NAT.
 924         */
 925        memset(&tuple, 0, sizeof(tuple));
 926        if (saddr)
 927                tuple.src.u3 = *saddr;
 928        tuple.src.l3num         = nf_ct_l3num(ct);
 929        tuple.dst.protonum      = IPPROTO_UDP;
 930        tuple.dst.u3            = *daddr;
 931        tuple.dst.u.udp.port    = port;
 932
 933        rcu_read_lock();
 934        do {
 935                exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
 936
 937                if (!exp || exp->master == ct ||
 938                    nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
 939                    exp->class != class)
 940                        break;
 941#ifdef CONFIG_NF_NAT_NEEDED
 942                if (exp->tuple.src.l3num == AF_INET && !direct_rtp &&
 943                    (exp->saved_ip != exp->tuple.dst.u3.ip ||
 944                     exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) &&
 945                    ct->status & IPS_NAT_MASK) {
 946                        daddr->ip               = exp->saved_ip;
 947                        tuple.dst.u3.ip         = exp->saved_ip;
 948                        tuple.dst.u.udp.port    = exp->saved_proto.udp.port;
 949                        direct_rtp = 1;
 950                } else
 951#endif
 952                        skip_expect = 1;
 953        } while (!skip_expect);
 954        rcu_read_unlock();
 955
 956        base_port = ntohs(tuple.dst.u.udp.port) & ~1;
 957        rtp_port = htons(base_port);
 958        rtcp_port = htons(base_port + 1);
 959
 960        if (direct_rtp) {
 961                nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook);
 962                if (nf_nat_sdp_port &&
 963                    !nf_nat_sdp_port(skb, dataoff, dptr, datalen,
 964                                     mediaoff, medialen, ntohs(rtp_port)))
 965                        goto err1;
 966        }
 967
 968        if (skip_expect)
 969                return NF_ACCEPT;
 970
 971        rtp_exp = nf_ct_expect_alloc(ct);
 972        if (rtp_exp == NULL)
 973                goto err1;
 974        nf_ct_expect_init(rtp_exp, class, nf_ct_l3num(ct), saddr, daddr,
 975                          IPPROTO_UDP, NULL, &rtp_port);
 976
 977        rtcp_exp = nf_ct_expect_alloc(ct);
 978        if (rtcp_exp == NULL)
 979                goto err2;
 980        nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
 981                          IPPROTO_UDP, NULL, &rtcp_port);
 982
 983        nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
 984        if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp)
 985                ret = nf_nat_sdp_media(skb, dataoff, dptr, datalen,
 986                                       rtp_exp, rtcp_exp,
 987                                       mediaoff, medialen, daddr);
 988        else {
 989                if (nf_ct_expect_related(rtp_exp) == 0) {
 990                        if (nf_ct_expect_related(rtcp_exp) != 0)
 991                                nf_ct_unexpect_related(rtp_exp);
 992                        else
 993                                ret = NF_ACCEPT;
 994                }
 995        }
 996        nf_ct_expect_put(rtcp_exp);
 997err2:
 998        nf_ct_expect_put(rtp_exp);
 999err1:
1000        return ret;
1001}
1002
1003static const struct sdp_media_type sdp_media_types[] = {
1004        SDP_MEDIA_TYPE("audio ", SIP_EXPECT_AUDIO),
1005        SDP_MEDIA_TYPE("video ", SIP_EXPECT_VIDEO),
1006        SDP_MEDIA_TYPE("image ", SIP_EXPECT_IMAGE),
1007};
1008
1009static const struct sdp_media_type *sdp_media_type(const char *dptr,
1010                                                   unsigned int matchoff,
1011                                                   unsigned int matchlen)
1012{
1013        const struct sdp_media_type *t;
1014        unsigned int i;
1015
1016        for (i = 0; i < ARRAY_SIZE(sdp_media_types); i++) {
1017                t = &sdp_media_types[i];
1018                if (matchlen < t->len ||
1019                    strncmp(dptr + matchoff, t->name, t->len))
1020                        continue;
1021                return t;
1022        }
1023        return NULL;
1024}
1025
1026static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
1027                       const char **dptr, unsigned int *datalen,
1028                       unsigned int cseq)
1029{
1030        enum ip_conntrack_info ctinfo;
1031        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1032        unsigned int matchoff, matchlen;
1033        unsigned int mediaoff, medialen;
1034        unsigned int sdpoff;
1035        unsigned int caddr_len, maddr_len;
1036        unsigned int i;
1037        union nf_inet_addr caddr, maddr, rtp_addr;
1038        unsigned int port;
1039        enum sdp_header_types c_hdr;
1040        const struct sdp_media_type *t;
1041        int ret = NF_ACCEPT;
1042        typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr;
1043        typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
1044
1045        nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook);
1046        c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 :
1047                                             SDP_HDR_CONNECTION_IP6;
1048
1049        /* Find beginning of session description */
1050        if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
1051                                  SDP_HDR_VERSION, SDP_HDR_UNSPEC,
1052                                  &matchoff, &matchlen) <= 0)
1053                return NF_ACCEPT;
1054        sdpoff = matchoff;
1055
1056        /* The connection information is contained in the session description
1057         * and/or once per media description. The first media description marks
1058         * the end of the session description. */
1059        caddr_len = 0;
1060        if (ct_sip_parse_sdp_addr(ct, *dptr, sdpoff, *datalen,
1061                                  c_hdr, SDP_HDR_MEDIA,
1062                                  &matchoff, &matchlen, &caddr) > 0)
1063                caddr_len = matchlen;
1064
1065        mediaoff = sdpoff;
1066        for (i = 0; i < ARRAY_SIZE(sdp_media_types); ) {
1067                if (ct_sip_get_sdp_header(ct, *dptr, mediaoff, *datalen,
1068                                          SDP_HDR_MEDIA, SDP_HDR_UNSPEC,
1069                                          &mediaoff, &medialen) <= 0)
1070                        break;
1071
1072                /* Get media type and port number. A media port value of zero
1073                 * indicates an inactive stream. */
1074                t = sdp_media_type(*dptr, mediaoff, medialen);
1075                if (!t) {
1076                        mediaoff += medialen;
1077                        continue;
1078                }
1079                mediaoff += t->len;
1080                medialen -= t->len;
1081
1082                port = simple_strtoul(*dptr + mediaoff, NULL, 10);
1083                if (port == 0)
1084                        continue;
1085                if (port < 1024 || port > 65535)
1086                        return NF_DROP;
1087
1088                /* The media description overrides the session description. */
1089                maddr_len = 0;
1090                if (ct_sip_parse_sdp_addr(ct, *dptr, mediaoff, *datalen,
1091                                          c_hdr, SDP_HDR_MEDIA,
1092                                          &matchoff, &matchlen, &maddr) > 0) {
1093                        maddr_len = matchlen;
1094                        memcpy(&rtp_addr, &maddr, sizeof(rtp_addr));
1095                } else if (caddr_len)
1096                        memcpy(&rtp_addr, &caddr, sizeof(rtp_addr));
1097                else
1098                        return NF_DROP;
1099
1100                ret = set_expected_rtp_rtcp(skb, dataoff, dptr, datalen,
1101                                            &rtp_addr, htons(port), t->class,
1102                                            mediaoff, medialen);
1103                if (ret != NF_ACCEPT)
1104                        return ret;
1105
1106                /* Update media connection address if present */
1107                if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
1108                        ret = nf_nat_sdp_addr(skb, dataoff, dptr, datalen,
1109                                              mediaoff, c_hdr, SDP_HDR_MEDIA,
1110                                              &rtp_addr);
1111                        if (ret != NF_ACCEPT)
1112                                return ret;
1113                }
1114                i++;
1115        }
1116
1117        /* Update session connection and owner addresses */
1118        nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook);
1119        if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
1120                ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff,
1121                                         &rtp_addr);
1122
1123        return ret;
1124}
1125static int process_invite_response(struct sk_buff *skb, unsigned int dataoff,
1126                                   const char **dptr, unsigned int *datalen,
1127                                   unsigned int cseq, unsigned int code)
1128{
1129        enum ip_conntrack_info ctinfo;
1130        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1131        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1132
1133        if ((code >= 100 && code <= 199) ||
1134            (code >= 200 && code <= 299))
1135                return process_sdp(skb, dataoff, dptr, datalen, cseq);
1136        else if (ct_sip_info->invite_cseq == cseq)
1137                flush_expectations(ct, true);
1138        return NF_ACCEPT;
1139}
1140
1141static int process_update_response(struct sk_buff *skb, unsigned int dataoff,
1142                                   const char **dptr, unsigned int *datalen,
1143                                   unsigned int cseq, unsigned int code)
1144{
1145        enum ip_conntrack_info ctinfo;
1146        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1147        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1148
1149        if ((code >= 100 && code <= 199) ||
1150            (code >= 200 && code <= 299))
1151                return process_sdp(skb, dataoff, dptr, datalen, cseq);
1152        else if (ct_sip_info->invite_cseq == cseq)
1153                flush_expectations(ct, true);
1154        return NF_ACCEPT;
1155}
1156
1157static int process_prack_response(struct sk_buff *skb, unsigned int dataoff,
1158                                  const char **dptr, unsigned int *datalen,
1159                                  unsigned int cseq, unsigned int code)
1160{
1161        enum ip_conntrack_info ctinfo;
1162        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1163        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1164
1165        if ((code >= 100 && code <= 199) ||
1166            (code >= 200 && code <= 299))
1167                return process_sdp(skb, dataoff, dptr, datalen, cseq);
1168        else if (ct_sip_info->invite_cseq == cseq)
1169                flush_expectations(ct, true);
1170        return NF_ACCEPT;
1171}
1172
1173static int process_invite_request(struct sk_buff *skb, unsigned int dataoff,
1174                                  const char **dptr, unsigned int *datalen,
1175                                  unsigned int cseq)
1176{
1177        enum ip_conntrack_info ctinfo;
1178        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1179        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1180        unsigned int ret;
1181
1182        flush_expectations(ct, true);
1183        ret = process_sdp(skb, dataoff, dptr, datalen, cseq);
1184        if (ret == NF_ACCEPT)
1185                ct_sip_info->invite_cseq = cseq;
1186        return ret;
1187}
1188
1189static int process_bye_request(struct sk_buff *skb, unsigned int dataoff,
1190                               const char **dptr, unsigned int *datalen,
1191                               unsigned int cseq)
1192{
1193        enum ip_conntrack_info ctinfo;
1194        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1195
1196        flush_expectations(ct, true);
1197        return NF_ACCEPT;
1198}
1199
1200/* Parse a REGISTER request and create a permanent expectation for incoming
1201 * signalling connections. The expectation is marked inactive and is activated
1202 * when receiving a response indicating success from the registrar.
1203 */
1204static int process_register_request(struct sk_buff *skb, unsigned int dataoff,
1205                                    const char **dptr, unsigned int *datalen,
1206                                    unsigned int cseq)
1207{
1208        enum ip_conntrack_info ctinfo;
1209        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1210        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1211        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1212        unsigned int matchoff, matchlen;
1213        struct nf_conntrack_expect *exp;
1214        union nf_inet_addr *saddr, daddr;
1215        __be16 port;
1216        u8 proto;
1217        unsigned int expires = 0;
1218        int ret;
1219        typeof(nf_nat_sip_expect_hook) nf_nat_sip_expect;
1220
1221        /* Expected connections can not register again. */
1222        if (ct->status & IPS_EXPECTED)
1223                return NF_ACCEPT;
1224
1225        /* We must check the expiration time: a value of zero signals the
1226         * registrar to release the binding. We'll remove our expectation
1227         * when receiving the new bindings in the response, but we don't
1228         * want to create new ones.
1229         *
1230         * The expiration time may be contained in Expires: header, the
1231         * Contact: header parameters or the URI parameters.
1232         */
1233        if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES,
1234                              &matchoff, &matchlen) > 0)
1235                expires = simple_strtoul(*dptr + matchoff, NULL, 10);
1236
1237        ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
1238                                      SIP_HDR_CONTACT, NULL,
1239                                      &matchoff, &matchlen, &daddr, &port);
1240        if (ret < 0)
1241                return NF_DROP;
1242        else if (ret == 0)
1243                return NF_ACCEPT;
1244
1245        /* We don't support third-party registrations */
1246        if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &daddr))
1247                return NF_ACCEPT;
1248
1249        if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen, *datalen,
1250                                   &proto) == 0)
1251                return NF_ACCEPT;
1252
1253        if (ct_sip_parse_numerical_param(ct, *dptr,
1254                                         matchoff + matchlen, *datalen,
1255                                         "expires=", NULL, NULL, &expires) < 0)
1256                return NF_DROP;
1257
1258        if (expires == 0) {
1259                ret = NF_ACCEPT;
1260                goto store_cseq;
1261        }
1262
1263        exp = nf_ct_expect_alloc(ct);
1264        if (!exp)
1265                return NF_DROP;
1266
1267        saddr = NULL;
1268        if (sip_direct_signalling)
1269                saddr = &ct->tuplehash[!dir].tuple.src.u3;
1270
1271        nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct),
1272                          saddr, &daddr, proto, NULL, &port);
1273        exp->timeout.expires = sip_timeout * HZ;
1274        exp->helper = nfct_help(ct)->helper;
1275        exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
1276
1277        nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook);
1278        if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK)
1279                ret = nf_nat_sip_expect(skb, dataoff, dptr, datalen, exp,
1280                                        matchoff, matchlen);
1281        else {
1282                if (nf_ct_expect_related(exp) != 0)
1283                        ret = NF_DROP;
1284                else
1285                        ret = NF_ACCEPT;
1286        }
1287        nf_ct_expect_put(exp);
1288
1289store_cseq:
1290        if (ret == NF_ACCEPT)
1291                ct_sip_info->register_cseq = cseq;
1292        return ret;
1293}
1294
1295static int process_register_response(struct sk_buff *skb, unsigned int dataoff,
1296                                     const char **dptr, unsigned int *datalen,
1297                                     unsigned int cseq, unsigned int code)
1298{
1299        enum ip_conntrack_info ctinfo;
1300        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1301        struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1302        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1303        union nf_inet_addr addr;
1304        __be16 port;
1305        u8 proto;
1306        unsigned int matchoff, matchlen, coff = 0;
1307        unsigned int expires = 0;
1308        int in_contact = 0, ret;
1309
1310        /* According to RFC 3261, "UAs MUST NOT send a new registration until
1311         * they have received a final response from the registrar for the
1312         * previous one or the previous REGISTER request has timed out".
1313         *
1314         * However, some servers fail to detect retransmissions and send late
1315         * responses, so we store the sequence number of the last valid
1316         * request and compare it here.
1317         */
1318        if (ct_sip_info->register_cseq != cseq)
1319                return NF_ACCEPT;
1320
1321        if (code >= 100 && code <= 199)
1322                return NF_ACCEPT;
1323        if (code < 200 || code > 299)
1324                goto flush;
1325
1326        if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES,
1327                              &matchoff, &matchlen) > 0)
1328                expires = simple_strtoul(*dptr + matchoff, NULL, 10);
1329
1330        while (1) {
1331                unsigned int c_expires = expires;
1332
1333                ret = ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
1334                                              SIP_HDR_CONTACT, &in_contact,
1335                                              &matchoff, &matchlen,
1336                                              &addr, &port);
1337                if (ret < 0)
1338                        return NF_DROP;
1339                else if (ret == 0)
1340                        break;
1341
1342                /* We don't support third-party registrations */
1343                if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, &addr))
1344                        continue;
1345
1346                if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen,
1347                                           *datalen, &proto) == 0)
1348                        continue;
1349
1350                ret = ct_sip_parse_numerical_param(ct, *dptr,
1351                                                   matchoff + matchlen,
1352                                                   *datalen, "expires=",
1353                                                   NULL, NULL, &c_expires);
1354                if (ret < 0)
1355                        return NF_DROP;
1356                if (c_expires == 0)
1357                        break;
1358                if (refresh_signalling_expectation(ct, &addr, proto, port,
1359                                                   c_expires))
1360                        return NF_ACCEPT;
1361        }
1362
1363flush:
1364        flush_expectations(ct, false);
1365        return NF_ACCEPT;
1366}
1367
1368static const struct sip_handler sip_handlers[] = {
1369        SIP_HANDLER("INVITE", process_invite_request, process_invite_response),
1370        SIP_HANDLER("UPDATE", process_sdp, process_update_response),
1371        SIP_HANDLER("ACK", process_sdp, NULL),
1372        SIP_HANDLER("PRACK", process_sdp, process_prack_response),
1373        SIP_HANDLER("BYE", process_bye_request, NULL),
1374        SIP_HANDLER("REGISTER", process_register_request, process_register_response),
1375};
1376
1377static int process_sip_response(struct sk_buff *skb, unsigned int dataoff,
1378                                const char **dptr, unsigned int *datalen)
1379{
1380        enum ip_conntrack_info ctinfo;
1381        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1382        unsigned int matchoff, matchlen, matchend;
1383        unsigned int code, cseq, i;
1384
1385        if (*datalen < strlen("SIP/2.0 200"))
1386                return NF_ACCEPT;
1387        code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10);
1388        if (!code)
1389                return NF_DROP;
1390
1391        if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1392                              &matchoff, &matchlen) <= 0)
1393                return NF_DROP;
1394        cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1395        if (!cseq)
1396                return NF_DROP;
1397        matchend = matchoff + matchlen + 1;
1398
1399        for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1400                const struct sip_handler *handler;
1401
1402                handler = &sip_handlers[i];
1403                if (handler->response == NULL)
1404                        continue;
1405                if (*datalen < matchend + handler->len ||
1406                    strnicmp(*dptr + matchend, handler->method, handler->len))
1407                        continue;
1408                return handler->response(skb, dataoff, dptr, datalen,
1409                                         cseq, code);
1410        }
1411        return NF_ACCEPT;
1412}
1413
1414static int process_sip_request(struct sk_buff *skb, unsigned int dataoff,
1415                               const char **dptr, unsigned int *datalen)
1416{
1417        enum ip_conntrack_info ctinfo;
1418        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1419        unsigned int matchoff, matchlen;
1420        unsigned int cseq, i;
1421
1422        for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1423                const struct sip_handler *handler;
1424
1425                handler = &sip_handlers[i];
1426                if (handler->request == NULL)
1427                        continue;
1428                if (*datalen < handler->len ||
1429                    strnicmp(*dptr, handler->method, handler->len))
1430                        continue;
1431
1432                if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1433                                      &matchoff, &matchlen) <= 0)
1434                        return NF_DROP;
1435                cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1436                if (!cseq)
1437                        return NF_DROP;
1438
1439                return handler->request(skb, dataoff, dptr, datalen, cseq);
1440        }
1441        return NF_ACCEPT;
1442}
1443
1444static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
1445                           unsigned int dataoff, const char **dptr,
1446                           unsigned int *datalen)
1447{
1448        typeof(nf_nat_sip_hook) nf_nat_sip;
1449        int ret;
1450
1451        if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
1452                ret = process_sip_request(skb, dataoff, dptr, datalen);
1453        else
1454                ret = process_sip_response(skb, dataoff, dptr, datalen);
1455
1456        if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1457                nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
1458                if (nf_nat_sip && !nf_nat_sip(skb, dataoff, dptr, datalen))
1459                        ret = NF_DROP;
1460        }
1461
1462        return ret;
1463}
1464
1465static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
1466                        struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1467{
1468        struct tcphdr *th, _tcph;
1469        unsigned int dataoff, datalen;
1470        unsigned int matchoff, matchlen, clen;
1471        unsigned int msglen, origlen;
1472        const char *dptr, *end;
1473        s16 diff, tdiff = 0;
1474        int ret = NF_ACCEPT;
1475        bool term;
1476        typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
1477
1478        if (ctinfo != IP_CT_ESTABLISHED &&
1479            ctinfo != IP_CT_ESTABLISHED_REPLY)
1480                return NF_ACCEPT;
1481
1482        /* No Data ? */
1483        th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
1484        if (th == NULL)
1485                return NF_ACCEPT;
1486        dataoff = protoff + th->doff * 4;
1487        if (dataoff >= skb->len)
1488                return NF_ACCEPT;
1489
1490        nf_ct_refresh(ct, skb, sip_timeout * HZ);
1491
1492        if (unlikely(skb_linearize(skb)))
1493                return NF_DROP;
1494
1495        dptr = skb->data + dataoff;
1496        datalen = skb->len - dataoff;
1497        if (datalen < strlen("SIP/2.0 200"))
1498                return NF_ACCEPT;
1499
1500        while (1) {
1501                if (ct_sip_get_header(ct, dptr, 0, datalen,
1502                                      SIP_HDR_CONTENT_LENGTH,
1503                                      &matchoff, &matchlen) <= 0)
1504                        break;
1505
1506                clen = simple_strtoul(dptr + matchoff, (char **)&end, 10);
1507                if (dptr + matchoff == end)
1508                        break;
1509
1510                term = false;
1511                for (; end + strlen("\r\n\r\n") <= dptr + datalen; end++) {
1512                        if (end[0] == '\r' && end[1] == '\n' &&
1513                            end[2] == '\r' && end[3] == '\n') {
1514                                term = true;
1515                                break;
1516                        }
1517                }
1518                if (!term)
1519                        break;
1520                end += strlen("\r\n\r\n") + clen;
1521
1522                msglen = origlen = end - dptr;
1523                if (msglen > datalen)
1524                        return NF_DROP;
1525
1526                ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen);
1527                if (ret != NF_ACCEPT)
1528                        break;
1529                diff     = msglen - origlen;
1530                tdiff   += diff;
1531
1532                dataoff += msglen;
1533                dptr    += msglen;
1534                datalen  = datalen + diff - msglen;
1535        }
1536
1537        if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1538                nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook);
1539                if (nf_nat_sip_seq_adjust)
1540                        nf_nat_sip_seq_adjust(skb, tdiff);
1541        }
1542
1543        return ret;
1544}
1545
1546static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
1547                        struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1548{
1549        unsigned int dataoff, datalen;
1550        const char *dptr;
1551
1552        /* No Data ? */
1553        dataoff = protoff + sizeof(struct udphdr);
1554        if (dataoff >= skb->len)
1555                return NF_ACCEPT;
1556
1557        nf_ct_refresh(ct, skb, sip_timeout * HZ);
1558
1559        if (unlikely(skb_linearize(skb)))
1560                return NF_DROP;
1561
1562        dptr = skb->data + dataoff;
1563        datalen = skb->len - dataoff;
1564        if (datalen < strlen("SIP/2.0 200"))
1565                return NF_ACCEPT;
1566
1567        return process_sip_msg(skb, ct, dataoff, &dptr, &datalen);
1568}
1569
1570static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly;
1571
1572static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
1573        [SIP_EXPECT_SIGNALLING] = {
1574                .name           = "signalling",
1575                .max_expected   = 1,
1576                .timeout        = 3 * 60,
1577        },
1578        [SIP_EXPECT_AUDIO] = {
1579                .name           = "audio",
1580                .max_expected   = 2 * IP_CT_DIR_MAX,
1581                .timeout        = 3 * 60,
1582        },
1583        [SIP_EXPECT_VIDEO] = {
1584                .name           = "video",
1585                .max_expected   = 2 * IP_CT_DIR_MAX,
1586                .timeout        = 3 * 60,
1587        },
1588        [SIP_EXPECT_IMAGE] = {
1589                .name           = "image",
1590                .max_expected   = IP_CT_DIR_MAX,
1591                .timeout        = 3 * 60,
1592        },
1593};
1594
1595static void nf_conntrack_sip_fini(void)
1596{
1597        int i, j;
1598
1599        for (i = 0; i < ports_c; i++) {
1600                for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
1601                        if (sip[i][j].me == NULL)
1602                                continue;
1603                        nf_conntrack_helper_unregister(&sip[i][j]);
1604                }
1605        }
1606}
1607
1608static int __init nf_conntrack_sip_init(void)
1609{
1610        int i, j, ret;
1611
1612        if (ports_c == 0)
1613                ports[ports_c++] = SIP_PORT;
1614
1615        for (i = 0; i < ports_c; i++) {
1616                memset(&sip[i], 0, sizeof(sip[i]));
1617
1618                sip[i][0].tuple.src.l3num = AF_INET;
1619                sip[i][0].tuple.dst.protonum = IPPROTO_UDP;
1620                sip[i][0].help = sip_help_udp;
1621                sip[i][1].tuple.src.l3num = AF_INET;
1622                sip[i][1].tuple.dst.protonum = IPPROTO_TCP;
1623                sip[i][1].help = sip_help_tcp;
1624
1625                sip[i][2].tuple.src.l3num = AF_INET6;
1626                sip[i][2].tuple.dst.protonum = IPPROTO_UDP;
1627                sip[i][2].help = sip_help_udp;
1628                sip[i][3].tuple.src.l3num = AF_INET6;
1629                sip[i][3].tuple.dst.protonum = IPPROTO_TCP;
1630                sip[i][3].help = sip_help_tcp;
1631
1632                for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
1633                        sip[i][j].data_len = sizeof(struct nf_ct_sip_master);
1634                        sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
1635                        sip[i][j].expect_policy = sip_exp_policy;
1636                        sip[i][j].expect_class_max = SIP_EXPECT_MAX;
1637                        sip[i][j].me = THIS_MODULE;
1638
1639                        if (ports[i] == SIP_PORT)
1640                                sprintf(sip[i][j].name, "sip");
1641                        else
1642                                sprintf(sip[i][j].name, "sip-%u", i);
1643
1644                        pr_debug("port #%u: %u\n", i, ports[i]);
1645
1646                        ret = nf_conntrack_helper_register(&sip[i][j]);
1647                        if (ret) {
1648                                printk(KERN_ERR "nf_ct_sip: failed to register"
1649                                       " helper for pf: %u port: %u\n",
1650                                       sip[i][j].tuple.src.l3num, ports[i]);
1651                                nf_conntrack_sip_fini();
1652                                return ret;
1653                        }
1654                }
1655        }
1656        return 0;
1657}
1658
1659module_init(nf_conntrack_sip_init);
1660module_exit(nf_conntrack_sip_fini);
1661
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.