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