linux/net/netfilter/nf_conntrack_proto_dccp.c
<<
>>
Prefs
   1/*
   2 * DCCP connection tracking protocol helper
   3 *
   4 * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/init.h>
  14#include <linux/sysctl.h>
  15#include <linux/spinlock.h>
  16#include <linux/skbuff.h>
  17#include <linux/dccp.h>
  18
  19#include <linux/netfilter/nfnetlink_conntrack.h>
  20#include <net/netfilter/nf_conntrack.h>
  21#include <net/netfilter/nf_conntrack_l4proto.h>
  22#include <net/netfilter/nf_log.h>
  23
  24static DEFINE_RWLOCK(dccp_lock);
  25
  26static int nf_ct_dccp_loose __read_mostly = 1;
  27
  28/* Timeouts are based on values from RFC4340:
  29 *
  30 * - REQUEST:
  31 *
  32 *   8.1.2. Client Request
  33 *
  34 *   A client MAY give up on its DCCP-Requests after some time
  35 *   (3 minutes, for example).
  36 *
  37 * - RESPOND:
  38 *
  39 *   8.1.3. Server Response
  40 *
  41 *   It MAY also leave the RESPOND state for CLOSED after a timeout of
  42 *   not less than 4MSL (8 minutes);
  43 *
  44 * - PARTOPEN:
  45 *
  46 *   8.1.5. Handshake Completion
  47 *
  48 *   If the client remains in PARTOPEN for more than 4MSL (8 minutes),
  49 *   it SHOULD reset the connection with Reset Code 2, "Aborted".
  50 *
  51 * - OPEN:
  52 *
  53 *   The DCCP timestamp overflows after 11.9 hours. If the connection
  54 *   stays idle this long the sequence number won't be recognized
  55 *   as valid anymore.
  56 *
  57 * - CLOSEREQ/CLOSING:
  58 *
  59 *   8.3. Termination
  60 *
  61 *   The retransmission timer should initially be set to go off in two
  62 *   round-trip times and should back off to not less than once every
  63 *   64 seconds ...
  64 *
  65 * - TIMEWAIT:
  66 *
  67 *   4.3. States
  68 *
  69 *   A server or client socket remains in this state for 2MSL (4 minutes)
  70 *   after the connection has been town down, ...
  71 */
  72
  73#define DCCP_MSL (2 * 60 * HZ)
  74
  75static unsigned int dccp_timeout[CT_DCCP_MAX + 1] __read_mostly = {
  76        [CT_DCCP_REQUEST]       = 2 * DCCP_MSL,
  77        [CT_DCCP_RESPOND]       = 4 * DCCP_MSL,
  78        [CT_DCCP_PARTOPEN]      = 4 * DCCP_MSL,
  79        [CT_DCCP_OPEN]          = 12 * 3600 * HZ,
  80        [CT_DCCP_CLOSEREQ]      = 64 * HZ,
  81        [CT_DCCP_CLOSING]       = 64 * HZ,
  82        [CT_DCCP_TIMEWAIT]      = 2 * DCCP_MSL,
  83};
  84
  85static const char * const dccp_state_names[] = {
  86        [CT_DCCP_NONE]          = "NONE",
  87        [CT_DCCP_REQUEST]       = "REQUEST",
  88        [CT_DCCP_RESPOND]       = "RESPOND",
  89        [CT_DCCP_PARTOPEN]      = "PARTOPEN",
  90        [CT_DCCP_OPEN]          = "OPEN",
  91        [CT_DCCP_CLOSEREQ]      = "CLOSEREQ",
  92        [CT_DCCP_CLOSING]       = "CLOSING",
  93        [CT_DCCP_TIMEWAIT]      = "TIMEWAIT",
  94        [CT_DCCP_IGNORE]        = "IGNORE",
  95        [CT_DCCP_INVALID]       = "INVALID",
  96};
  97
  98#define sNO     CT_DCCP_NONE
  99#define sRQ     CT_DCCP_REQUEST
 100#define sRS     CT_DCCP_RESPOND
 101#define sPO     CT_DCCP_PARTOPEN
 102#define sOP     CT_DCCP_OPEN
 103#define sCR     CT_DCCP_CLOSEREQ
 104#define sCG     CT_DCCP_CLOSING
 105#define sTW     CT_DCCP_TIMEWAIT
 106#define sIG     CT_DCCP_IGNORE
 107#define sIV     CT_DCCP_INVALID
 108
 109/*
 110 * DCCP state transistion table
 111 *
 112 * The assumption is the same as for TCP tracking:
 113 *
 114 * We are the man in the middle. All the packets go through us but might
 115 * get lost in transit to the destination. It is assumed that the destination
 116 * can't receive segments we haven't seen.
 117 *
 118 * The following states exist:
 119 *
 120 * NONE:        Initial state, expecting Request
 121 * REQUEST:     Request seen, waiting for Response from server
 122 * RESPOND:     Response from server seen, waiting for Ack from client
 123 * PARTOPEN:    Ack after Response seen, waiting for packet other than Response,
 124 *              Reset or Sync from server
 125 * OPEN:        Packet other than Response, Reset or Sync seen
 126 * CLOSEREQ:    CloseReq from server seen, expecting Close from client
 127 * CLOSING:     Close seen, expecting Reset
 128 * TIMEWAIT:    Reset seen
 129 * IGNORE:      Not determinable whether packet is valid
 130 *
 131 * Some states exist only on one side of the connection: REQUEST, RESPOND,
 132 * PARTOPEN, CLOSEREQ. For the other side these states are equivalent to
 133 * the one it was in before.
 134 *
 135 * Packets are marked as ignored (sIG) if we don't know if they're valid
 136 * (for example a reincarnation of a connection we didn't notice is dead
 137 * already) and the server may send back a connection closing Reset or a
 138 * Response. They're also used for Sync/SyncAck packets, which we don't
 139 * care about.
 140 */
 141static const u_int8_t
 142dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = {
 143        [CT_DCCP_ROLE_CLIENT] = {
 144                [DCCP_PKT_REQUEST] = {
 145                /*
 146                 * sNO -> sRQ           Regular Request
 147                 * sRQ -> sRQ           Retransmitted Request or reincarnation
 148                 * sRS -> sRS           Retransmitted Request (apparently Response
 149                 *                      got lost after we saw it) or reincarnation
 150                 * sPO -> sIG           Ignore, conntrack might be out of sync
 151                 * sOP -> sIG           Ignore, conntrack might be out of sync
 152                 * sCR -> sIG           Ignore, conntrack might be out of sync
 153                 * sCG -> sIG           Ignore, conntrack might be out of sync
 154                 * sTW -> sRQ           Reincarnation
 155                 *
 156                 *      sNO, sRQ, sRS, sPO. sOP, sCR, sCG, sTW, */
 157                        sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ,
 158                },
 159                [DCCP_PKT_RESPONSE] = {
 160                /*
 161                 * sNO -> sIV           Invalid
 162                 * sRQ -> sIG           Ignore, might be response to ignored Request
 163                 * sRS -> sIG           Ignore, might be response to ignored Request
 164                 * sPO -> sIG           Ignore, might be response to ignored Request
 165                 * sOP -> sIG           Ignore, might be response to ignored Request
 166                 * sCR -> sIG           Ignore, might be response to ignored Request
 167                 * sCG -> sIG           Ignore, might be response to ignored Request
 168                 * sTW -> sIV           Invalid, reincarnation in reverse direction
 169                 *                      goes through sRQ
 170                 *
 171                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 172                        sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV,
 173                },
 174                [DCCP_PKT_ACK] = {
 175                /*
 176                 * sNO -> sIV           No connection
 177                 * sRQ -> sIV           No connection
 178                 * sRS -> sPO           Ack for Response, move to PARTOPEN (8.1.5.)
 179                 * sPO -> sPO           Retransmitted Ack for Response, remain in PARTOPEN
 180                 * sOP -> sOP           Regular ACK, remain in OPEN
 181                 * sCR -> sCR           Ack in CLOSEREQ MAY be processed (8.3.)
 182                 * sCG -> sCG           Ack in CLOSING MAY be processed (8.3.)
 183                 * sTW -> sIV
 184                 *
 185                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 186                        sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
 187                },
 188                [DCCP_PKT_DATA] = {
 189                /*
 190                 * sNO -> sIV           No connection
 191                 * sRQ -> sIV           No connection
 192                 * sRS -> sIV           No connection
 193                 * sPO -> sIV           MUST use DataAck in PARTOPEN state (8.1.5.)
 194                 * sOP -> sOP           Regular Data packet
 195                 * sCR -> sCR           Data in CLOSEREQ MAY be processed (8.3.)
 196                 * sCG -> sCG           Data in CLOSING MAY be processed (8.3.)
 197                 * sTW -> sIV
 198                 *
 199                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 200                        sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV,
 201                },
 202                [DCCP_PKT_DATAACK] = {
 203                /*
 204                 * sNO -> sIV           No connection
 205                 * sRQ -> sIV           No connection
 206                 * sRS -> sPO           Ack for Response, move to PARTOPEN (8.1.5.)
 207                 * sPO -> sPO           Remain in PARTOPEN state
 208                 * sOP -> sOP           Regular DataAck packet in OPEN state
 209                 * sCR -> sCR           DataAck in CLOSEREQ MAY be processed (8.3.)
 210                 * sCG -> sCG           DataAck in CLOSING MAY be processed (8.3.)
 211                 * sTW -> sIV
 212                 *
 213                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 214                        sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
 215                },
 216                [DCCP_PKT_CLOSEREQ] = {
 217                /*
 218                 * CLOSEREQ may only be sent by the server.
 219                 *
 220                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 221                        sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV
 222                },
 223                [DCCP_PKT_CLOSE] = {
 224                /*
 225                 * sNO -> sIV           No connection
 226                 * sRQ -> sIV           No connection
 227                 * sRS -> sIV           No connection
 228                 * sPO -> sCG           Client-initiated close
 229                 * sOP -> sCG           Client-initiated close
 230                 * sCR -> sCG           Close in response to CloseReq (8.3.)
 231                 * sCG -> sCG           Retransmit
 232                 * sTW -> sIV           Late retransmit, already in TIME_WAIT
 233                 *
 234                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 235                        sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV
 236                },
 237                [DCCP_PKT_RESET] = {
 238                /*
 239                 * sNO -> sIV           No connection
 240                 * sRQ -> sTW           Sync received or timeout, SHOULD send Reset (8.1.1.)
 241                 * sRS -> sTW           Response received without Request
 242                 * sPO -> sTW           Timeout, SHOULD send Reset (8.1.5.)
 243                 * sOP -> sTW           Connection reset
 244                 * sCR -> sTW           Connection reset
 245                 * sCG -> sTW           Connection reset
 246                 * sTW -> sIG           Ignore (don't refresh timer)
 247                 *
 248                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 249                        sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG
 250                },
 251                [DCCP_PKT_SYNC] = {
 252                /*
 253                 * We currently ignore Sync packets
 254                 *
 255                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 256                        sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
 257                },
 258                [DCCP_PKT_SYNCACK] = {
 259                /*
 260                 * We currently ignore SyncAck packets
 261                 *
 262                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 263                        sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
 264                },
 265        },
 266        [CT_DCCP_ROLE_SERVER] = {
 267                [DCCP_PKT_REQUEST] = {
 268                /*
 269                 * sNO -> sIV           Invalid
 270                 * sRQ -> sIG           Ignore, conntrack might be out of sync
 271                 * sRS -> sIG           Ignore, conntrack might be out of sync
 272                 * sPO -> sIG           Ignore, conntrack might be out of sync
 273                 * sOP -> sIG           Ignore, conntrack might be out of sync
 274                 * sCR -> sIG           Ignore, conntrack might be out of sync
 275                 * sCG -> sIG           Ignore, conntrack might be out of sync
 276                 * sTW -> sRQ           Reincarnation, must reverse roles
 277                 *
 278                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 279                        sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ
 280                },
 281                [DCCP_PKT_RESPONSE] = {
 282                /*
 283                 * sNO -> sIV           Response without Request
 284                 * sRQ -> sRS           Response to clients Request
 285                 * sRS -> sRS           Retransmitted Response (8.1.3. SHOULD NOT)
 286                 * sPO -> sIG           Response to an ignored Request or late retransmit
 287                 * sOP -> sIG           Ignore, might be response to ignored Request
 288                 * sCR -> sIG           Ignore, might be response to ignored Request
 289                 * sCG -> sIG           Ignore, might be response to ignored Request
 290                 * sTW -> sIV           Invalid, Request from client in sTW moves to sRQ
 291                 *
 292                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 293                        sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV
 294                },
 295                [DCCP_PKT_ACK] = {
 296                /*
 297                 * sNO -> sIV           No connection
 298                 * sRQ -> sIV           No connection
 299                 * sRS -> sIV           No connection
 300                 * sPO -> sOP           Enter OPEN state (8.1.5.)
 301                 * sOP -> sOP           Regular Ack in OPEN state
 302                 * sCR -> sIV           Waiting for Close from client
 303                 * sCG -> sCG           Ack in CLOSING MAY be processed (8.3.)
 304                 * sTW -> sIV
 305                 *
 306                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 307                        sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
 308                },
 309                [DCCP_PKT_DATA] = {
 310                /*
 311                 * sNO -> sIV           No connection
 312                 * sRQ -> sIV           No connection
 313                 * sRS -> sIV           No connection
 314                 * sPO -> sOP           Enter OPEN state (8.1.5.)
 315                 * sOP -> sOP           Regular Data packet in OPEN state
 316                 * sCR -> sIV           Waiting for Close from client
 317                 * sCG -> sCG           Data in CLOSING MAY be processed (8.3.)
 318                 * sTW -> sIV
 319                 *
 320                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 321                        sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
 322                },
 323                [DCCP_PKT_DATAACK] = {
 324                /*
 325                 * sNO -> sIV           No connection
 326                 * sRQ -> sIV           No connection
 327                 * sRS -> sIV           No connection
 328                 * sPO -> sOP           Enter OPEN state (8.1.5.)
 329                 * sOP -> sOP           Regular DataAck in OPEN state
 330                 * sCR -> sIV           Waiting for Close from client
 331                 * sCG -> sCG           Data in CLOSING MAY be processed (8.3.)
 332                 * sTW -> sIV
 333                 *
 334                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 335                        sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
 336                },
 337                [DCCP_PKT_CLOSEREQ] = {
 338                /*
 339                 * sNO -> sIV           No connection
 340                 * sRQ -> sIV           No connection
 341                 * sRS -> sIV           No connection
 342                 * sPO -> sOP -> sCR    Move directly to CLOSEREQ (8.1.5.)
 343                 * sOP -> sCR           CloseReq in OPEN state
 344                 * sCR -> sCR           Retransmit
 345                 * sCG -> sCR           Simultaneous close, client sends another Close
 346                 * sTW -> sIV           Already closed
 347                 *
 348                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 349                        sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV
 350                },
 351                [DCCP_PKT_CLOSE] = {
 352                /*
 353                 * sNO -> sIV           No connection
 354                 * sRQ -> sIV           No connection
 355                 * sRS -> sIV           No connection
 356                 * sPO -> sOP -> sCG    Move direcly to CLOSING
 357                 * sOP -> sCG           Move to CLOSING
 358                 * sCR -> sIV           Close after CloseReq is invalid
 359                 * sCG -> sCG           Retransmit
 360                 * sTW -> sIV           Already closed
 361                 *
 362                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 363                        sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV
 364                },
 365                [DCCP_PKT_RESET] = {
 366                /*
 367                 * sNO -> sIV           No connection
 368                 * sRQ -> sTW           Reset in response to Request
 369                 * sRS -> sTW           Timeout, SHOULD send Reset (8.1.3.)
 370                 * sPO -> sTW           Timeout, SHOULD send Reset (8.1.3.)
 371                 * sOP -> sTW
 372                 * sCR -> sTW
 373                 * sCG -> sTW
 374                 * sTW -> sIG           Ignore (don't refresh timer)
 375                 *
 376                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW, sTW */
 377                        sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG
 378                },
 379                [DCCP_PKT_SYNC] = {
 380                /*
 381                 * We currently ignore Sync packets
 382                 *
 383                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 384                        sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
 385                },
 386                [DCCP_PKT_SYNCACK] = {
 387                /*
 388                 * We currently ignore SyncAck packets
 389                 *
 390                 *      sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
 391                        sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
 392                },
 393        },
 394};
 395
 396static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 397                              struct nf_conntrack_tuple *tuple)
 398{
 399        struct dccp_hdr _hdr, *dh;
 400
 401        dh = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
 402        if (dh == NULL)
 403                return false;
 404
 405        tuple->src.u.dccp.port = dh->dccph_sport;
 406        tuple->dst.u.dccp.port = dh->dccph_dport;
 407        return true;
 408}
 409
 410static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
 411                              const struct nf_conntrack_tuple *tuple)
 412{
 413        inv->src.u.dccp.port = tuple->dst.u.dccp.port;
 414        inv->dst.u.dccp.port = tuple->src.u.dccp.port;
 415        return true;
 416}
 417
 418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
 419                     unsigned int dataoff)
 420{
 421        struct net *net = nf_ct_net(ct);
 422        struct dccp_hdr _dh, *dh;
 423        const char *msg;
 424        u_int8_t state;
 425
 426        dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
 427        BUG_ON(dh == NULL);
 428
 429        state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
 430        switch (state) {
 431        default:
 432                if (nf_ct_dccp_loose == 0) {
 433                        msg = "nf_ct_dccp: not picking up existing connection ";
 434                        goto out_invalid;
 435                }
 436        case CT_DCCP_REQUEST:
 437                break;
 438        case CT_DCCP_INVALID:
 439                msg = "nf_ct_dccp: invalid state transition ";
 440                goto out_invalid;
 441        }
 442
 443        ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
 444        ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
 445        ct->proto.dccp.state = CT_DCCP_NONE;
 446        return true;
 447
 448out_invalid:
 449        if (LOG_INVALID(net, IPPROTO_DCCP))
 450                nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg);
 451        return false;
 452}
 453
 454static u64 dccp_ack_seq(const struct dccp_hdr *dh)
 455{
 456        const struct dccp_hdr_ack_bits *dhack;
 457
 458        dhack = (void *)dh + __dccp_basic_hdr_len(dh);
 459        return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
 460                     ntohl(dhack->dccph_ack_nr_low);
 461}
 462
 463static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
 464                       unsigned int dataoff, enum ip_conntrack_info ctinfo,
 465                       u_int8_t pf, unsigned int hooknum)
 466{
 467        struct net *net = nf_ct_net(ct);
 468        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 469        struct dccp_hdr _dh, *dh;
 470        u_int8_t type, old_state, new_state;
 471        enum ct_dccp_roles role;
 472
 473        dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
 474        BUG_ON(dh == NULL);
 475        type = dh->dccph_type;
 476
 477        if (type == DCCP_PKT_RESET &&
 478            !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 479                /* Tear down connection immediately if only reply is a RESET */
 480                nf_ct_kill_acct(ct, ctinfo, skb);
 481                return NF_ACCEPT;
 482        }
 483
 484        write_lock_bh(&dccp_lock);
 485
 486        role = ct->proto.dccp.role[dir];
 487        old_state = ct->proto.dccp.state;
 488        new_state = dccp_state_table[role][type][old_state];
 489
 490        switch (new_state) {
 491        case CT_DCCP_REQUEST:
 492                if (old_state == CT_DCCP_TIMEWAIT &&
 493                    role == CT_DCCP_ROLE_SERVER) {
 494                        /* Reincarnation in the reverse direction: reopen and
 495                         * reverse client/server roles. */
 496                        ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
 497                        ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
 498                }
 499                break;
 500        case CT_DCCP_RESPOND:
 501                if (old_state == CT_DCCP_REQUEST)
 502                        ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
 503                break;
 504        case CT_DCCP_PARTOPEN:
 505                if (old_state == CT_DCCP_RESPOND &&
 506                    type == DCCP_PKT_ACK &&
 507                    dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
 508                        set_bit(IPS_ASSURED_BIT, &ct->status);
 509                break;
 510        case CT_DCCP_IGNORE:
 511                /*
 512                 * Connection tracking might be out of sync, so we ignore
 513                 * packets that might establish a new connection and resync
 514                 * if the server responds with a valid Response.
 515                 */
 516                if (ct->proto.dccp.last_dir == !dir &&
 517                    ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
 518                    type == DCCP_PKT_RESPONSE) {
 519                        ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
 520                        ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
 521                        ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
 522                        new_state = CT_DCCP_RESPOND;
 523                        break;
 524                }
 525                ct->proto.dccp.last_dir = dir;
 526                ct->proto.dccp.last_pkt = type;
 527
 528                write_unlock_bh(&dccp_lock);
 529                if (LOG_INVALID(net, IPPROTO_DCCP))
 530                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
 531                                      "nf_ct_dccp: invalid packet ignored ");
 532                return NF_ACCEPT;
 533        case CT_DCCP_INVALID:
 534                write_unlock_bh(&dccp_lock);
 535                if (LOG_INVALID(net, IPPROTO_DCCP))
 536                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
 537                                      "nf_ct_dccp: invalid state transition ");
 538                return -NF_ACCEPT;
 539        }
 540
 541        ct->proto.dccp.last_dir = dir;
 542        ct->proto.dccp.last_pkt = type;
 543        ct->proto.dccp.state = new_state;
 544        write_unlock_bh(&dccp_lock);
 545        nf_ct_refresh_acct(ct, ctinfo, skb, dccp_timeout[new_state]);
 546
 547        return NF_ACCEPT;
 548}
 549
 550static int dccp_error(struct net *net, struct sk_buff *skb,
 551                      unsigned int dataoff, enum ip_conntrack_info *ctinfo,
 552                      u_int8_t pf, unsigned int hooknum)
 553{
 554        struct dccp_hdr _dh, *dh;
 555        unsigned int dccp_len = skb->len - dataoff;
 556        unsigned int cscov;
 557        const char *msg;
 558
 559        dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
 560        if (dh == NULL) {
 561                msg = "nf_ct_dccp: short packet ";
 562                goto out_invalid;
 563        }
 564
 565        if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
 566            dh->dccph_doff * 4 > dccp_len) {
 567                msg = "nf_ct_dccp: truncated/malformed packet ";
 568                goto out_invalid;
 569        }
 570
 571        cscov = dccp_len;
 572        if (dh->dccph_cscov) {
 573                cscov = (dh->dccph_cscov - 1) * 4;
 574                if (cscov > dccp_len) {
 575                        msg = "nf_ct_dccp: bad checksum coverage ";
 576                        goto out_invalid;
 577                }
 578        }
 579
 580        if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
 581            nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
 582                                pf)) {
 583                msg = "nf_ct_dccp: bad checksum ";
 584                goto out_invalid;
 585        }
 586
 587        if (dh->dccph_type >= DCCP_PKT_INVALID) {
 588                msg = "nf_ct_dccp: reserved packet type ";
 589                goto out_invalid;
 590        }
 591
 592        return NF_ACCEPT;
 593
 594out_invalid:
 595        if (LOG_INVALID(net, IPPROTO_DCCP))
 596                nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg);
 597        return -NF_ACCEPT;
 598}
 599
 600static int dccp_print_tuple(struct seq_file *s,
 601                            const struct nf_conntrack_tuple *tuple)
 602{
 603        return seq_printf(s, "sport=%hu dport=%hu ",
 604                          ntohs(tuple->src.u.dccp.port),
 605                          ntohs(tuple->dst.u.dccp.port));
 606}
 607
 608static int dccp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
 609{
 610        return seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
 611}
 612
 613#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 614static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
 615                          const struct nf_conn *ct)
 616{
 617        struct nlattr *nest_parms;
 618
 619        read_lock_bh(&dccp_lock);
 620        nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
 621        if (!nest_parms)
 622                goto nla_put_failure;
 623        NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state);
 624        nla_nest_end(skb, nest_parms);
 625        read_unlock_bh(&dccp_lock);
 626        return 0;
 627
 628nla_put_failure:
 629        read_unlock_bh(&dccp_lock);
 630        return -1;
 631}
 632
 633static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
 634        [CTA_PROTOINFO_DCCP_STATE]      = { .type = NLA_U8 },
 635};
 636
 637static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
 638{
 639        struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
 640        struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
 641        int err;
 642
 643        if (!attr)
 644                return 0;
 645
 646        err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
 647                               dccp_nla_policy);
 648        if (err < 0)
 649                return err;
 650
 651        if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
 652            nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE)
 653                return -EINVAL;
 654
 655        write_lock_bh(&dccp_lock);
 656        ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
 657        write_unlock_bh(&dccp_lock);
 658        return 0;
 659}
 660#endif
 661
 662#ifdef CONFIG_SYSCTL
 663static unsigned int dccp_sysctl_table_users;
 664static struct ctl_table_header *dccp_sysctl_header;
 665static ctl_table dccp_sysctl_table[] = {
 666        {
 667                .ctl_name       = CTL_UNNUMBERED,
 668                .procname       = "nf_conntrack_dccp_timeout_request",
 669                .data           = &dccp_timeout[CT_DCCP_REQUEST],
 670                .maxlen         = sizeof(unsigned int),
 671                .mode           = 0644,
 672                .proc_handler   = proc_dointvec_jiffies,
 673        },
 674        {
 675                .ctl_name       = CTL_UNNUMBERED,
 676                .procname       = "nf_conntrack_dccp_timeout_respond",
 677                .data           = &dccp_timeout[CT_DCCP_RESPOND],
 678                .maxlen         = sizeof(unsigned int),
 679                .mode           = 0644,
 680                .proc_handler   = proc_dointvec_jiffies,
 681        },
 682        {
 683                .ctl_name       = CTL_UNNUMBERED,
 684                .procname       = "nf_conntrack_dccp_timeout_partopen",
 685                .data           = &dccp_timeout[CT_DCCP_PARTOPEN],
 686                .maxlen         = sizeof(unsigned int),
 687                .mode           = 0644,
 688                .proc_handler   = proc_dointvec_jiffies,
 689        },
 690        {
 691                .ctl_name       = CTL_UNNUMBERED,
 692                .procname       = "nf_conntrack_dccp_timeout_open",
 693                .data           = &dccp_timeout[CT_DCCP_OPEN],
 694                .maxlen         = sizeof(unsigned int),
 695                .mode           = 0644,
 696                .proc_handler   = proc_dointvec_jiffies,
 697        },
 698        {
 699                .ctl_name       = CTL_UNNUMBERED,
 700                .procname       = "nf_conntrack_dccp_timeout_closereq",
 701                .data           = &dccp_timeout[CT_DCCP_CLOSEREQ],
 702                .maxlen         = sizeof(unsigned int),
 703                .mode           = 0644,
 704                .proc_handler   = proc_dointvec_jiffies,
 705        },
 706        {
 707                .ctl_name       = CTL_UNNUMBERED,
 708                .procname       = "nf_conntrack_dccp_timeout_closing",
 709                .data           = &dccp_timeout[CT_DCCP_CLOSING],
 710                .maxlen         = sizeof(unsigned int),
 711                .mode           = 0644,
 712                .proc_handler   = proc_dointvec_jiffies,
 713        },
 714        {
 715                .ctl_name       = CTL_UNNUMBERED,
 716                .procname       = "nf_conntrack_dccp_timeout_timewait",
 717                .data           = &dccp_timeout[CT_DCCP_TIMEWAIT],
 718                .maxlen         = sizeof(unsigned int),
 719                .mode           = 0644,
 720                .proc_handler   = proc_dointvec_jiffies,
 721        },
 722        {
 723                .ctl_name       = CTL_UNNUMBERED,
 724                .procname       = "nf_conntrack_dccp_loose",
 725                .data           = &nf_ct_dccp_loose,
 726                .maxlen         = sizeof(nf_ct_dccp_loose),
 727                .mode           = 0644,
 728                .proc_handler   = proc_dointvec,
 729        },
 730        {
 731                .ctl_name       = 0,
 732        }
 733};
 734#endif /* CONFIG_SYSCTL */
 735
 736static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
 737        .l3proto                = AF_INET,
 738        .l4proto                = IPPROTO_DCCP,
 739        .name                   = "dccp",
 740        .pkt_to_tuple           = dccp_pkt_to_tuple,
 741        .invert_tuple           = dccp_invert_tuple,
 742        .new                    = dccp_new,
 743        .packet                 = dccp_packet,
 744        .error                  = dccp_error,
 745        .print_tuple            = dccp_print_tuple,
 746        .print_conntrack        = dccp_print_conntrack,
 747#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 748        .to_nlattr              = dccp_to_nlattr,
 749        .from_nlattr            = nlattr_to_dccp,
 750        .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
 751        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
 752        .nla_policy             = nf_ct_port_nla_policy,
 753#endif
 754#ifdef CONFIG_SYSCTL
 755        .ctl_table_users        = &dccp_sysctl_table_users,
 756        .ctl_table_header       = &dccp_sysctl_header,
 757        .ctl_table              = dccp_sysctl_table,
 758#endif
 759};
 760
 761static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
 762        .l3proto                = AF_INET6,
 763        .l4proto                = IPPROTO_DCCP,
 764        .name                   = "dccp",
 765        .pkt_to_tuple           = dccp_pkt_to_tuple,
 766        .invert_tuple           = dccp_invert_tuple,
 767        .new                    = dccp_new,
 768        .packet                 = dccp_packet,
 769        .error                  = dccp_error,
 770        .print_tuple            = dccp_print_tuple,
 771        .print_conntrack        = dccp_print_conntrack,
 772#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 773        .to_nlattr              = dccp_to_nlattr,
 774        .from_nlattr            = nlattr_to_dccp,
 775        .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
 776        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
 777        .nla_policy             = nf_ct_port_nla_policy,
 778#endif
 779#ifdef CONFIG_SYSCTL
 780        .ctl_table_users        = &dccp_sysctl_table_users,
 781        .ctl_table_header       = &dccp_sysctl_header,
 782        .ctl_table              = dccp_sysctl_table,
 783#endif
 784};
 785
 786static int __init nf_conntrack_proto_dccp_init(void)
 787{
 788        int err;
 789
 790        err = nf_conntrack_l4proto_register(&dccp_proto4);
 791        if (err < 0)
 792                goto err1;
 793
 794        err = nf_conntrack_l4proto_register(&dccp_proto6);
 795        if (err < 0)
 796                goto err2;
 797        return 0;
 798
 799err2:
 800        nf_conntrack_l4proto_unregister(&dccp_proto4);
 801err1:
 802        return err;
 803}
 804
 805static void __exit nf_conntrack_proto_dccp_fini(void)
 806{
 807        nf_conntrack_l4proto_unregister(&dccp_proto6);
 808        nf_conntrack_l4proto_unregister(&dccp_proto4);
 809}
 810
 811module_init(nf_conntrack_proto_dccp_init);
 812module_exit(nf_conntrack_proto_dccp_fini);
 813
 814MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 815MODULE_DESCRIPTION("DCCP connection tracking protocol helper");
 816MODULE_LICENSE("GPL");
 817