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