linux/net/ipv4/netfilter/nf_nat_snmp_basic.c
<<
>>
Prefs
   1/*
   2 * nf_nat_snmp_basic.c
   3 *
   4 * Basic SNMP Application Layer Gateway
   5 *
   6 * This IP NAT module is intended for use with SNMP network
   7 * discovery and monitoring applications where target networks use
   8 * conflicting private address realms.
   9 *
  10 * Static NAT is used to remap the networks from the view of the network
  11 * management system at the IP layer, and this module remaps some application
  12 * layer addresses to match.
  13 *
  14 * The simplest form of ALG is performed, where only tagged IP addresses
  15 * are modified.  The module does not need to be MIB aware and only scans
  16 * messages at the ASN.1/BER level.
  17 *
  18 * Currently, only SNMPv1 and SNMPv2 are supported.
  19 *
  20 * More information on ALG and associated issues can be found in
  21 * RFC 2962
  22 *
  23 * The ASB.1/BER parsing code is derived from the gxsnmp package by Gregory
  24 * McLean & Jochen Friedrich, stripped down for use in the kernel.
  25 *
  26 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
  27 *
  28 * This program is free software; you can redistribute it and/or modify
  29 * it under the terms of the GNU General Public License as published by
  30 * the Free Software Foundation; either version 2 of the License, or
  31 * (at your option) any later version.
  32 * This program is distributed in the hope that it will be useful,
  33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  35 * GNU General Public License for more details.
  36 * You should have received a copy of the GNU General Public License
  37 * along with this program; if not, see <http://www.gnu.org/licenses/>.
  38 *
  39 * Author: James Morris <jmorris@intercode.com.au>
  40 *
  41 * Copyright (c) 2006-2010 Patrick McHardy <kaber@trash.net>
  42 */
  43#include <linux/module.h>
  44#include <linux/moduleparam.h>
  45#include <linux/types.h>
  46#include <linux/kernel.h>
  47#include <linux/slab.h>
  48#include <linux/in.h>
  49#include <linux/ip.h>
  50#include <linux/udp.h>
  51#include <net/checksum.h>
  52#include <net/udp.h>
  53
  54#include <net/netfilter/nf_nat.h>
  55#include <net/netfilter/nf_conntrack_expect.h>
  56#include <net/netfilter/nf_conntrack_helper.h>
  57#include <net/netfilter/nf_nat_helper.h>
  58#include <linux/netfilter/nf_conntrack_snmp.h>
  59
  60MODULE_LICENSE("GPL");
  61MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
  62MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");
  63MODULE_ALIAS("ip_nat_snmp_basic");
  64
  65#define SNMP_PORT 161
  66#define SNMP_TRAP_PORT 162
  67#define NOCT1(n) (*(u8 *)(n))
  68
  69static int debug;
  70static DEFINE_SPINLOCK(snmp_lock);
  71
  72/*
  73 * Application layer address mapping mimics the NAT mapping, but
  74 * only for the first octet in this case (a more flexible system
  75 * can be implemented if needed).
  76 */
  77struct oct1_map
  78{
  79        u_int8_t from;
  80        u_int8_t to;
  81};
  82
  83
  84/*****************************************************************************
  85 *
  86 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
  87 *
  88 *****************************************************************************/
  89
  90/* Class */
  91#define ASN1_UNI        0       /* Universal */
  92#define ASN1_APL        1       /* Application */
  93#define ASN1_CTX        2       /* Context */
  94#define ASN1_PRV        3       /* Private */
  95
  96/* Tag */
  97#define ASN1_EOC        0       /* End Of Contents */
  98#define ASN1_BOL        1       /* Boolean */
  99#define ASN1_INT        2       /* Integer */
 100#define ASN1_BTS        3       /* Bit String */
 101#define ASN1_OTS        4       /* Octet String */
 102#define ASN1_NUL        5       /* Null */
 103#define ASN1_OJI        6       /* Object Identifier  */
 104#define ASN1_OJD        7       /* Object Description */
 105#define ASN1_EXT        8       /* External */
 106#define ASN1_SEQ        16      /* Sequence */
 107#define ASN1_SET        17      /* Set */
 108#define ASN1_NUMSTR     18      /* Numerical String */
 109#define ASN1_PRNSTR     19      /* Printable String */
 110#define ASN1_TEXSTR     20      /* Teletext String */
 111#define ASN1_VIDSTR     21      /* Video String */
 112#define ASN1_IA5STR     22      /* IA5 String */
 113#define ASN1_UNITIM     23      /* Universal Time */
 114#define ASN1_GENTIM     24      /* General Time */
 115#define ASN1_GRASTR     25      /* Graphical String */
 116#define ASN1_VISSTR     26      /* Visible String */
 117#define ASN1_GENSTR     27      /* General String */
 118
 119/* Primitive / Constructed methods*/
 120#define ASN1_PRI        0       /* Primitive */
 121#define ASN1_CON        1       /* Constructed */
 122
 123/*
 124 * Error codes.
 125 */
 126#define ASN1_ERR_NOERROR                0
 127#define ASN1_ERR_DEC_EMPTY              2
 128#define ASN1_ERR_DEC_EOC_MISMATCH       3
 129#define ASN1_ERR_DEC_LENGTH_MISMATCH    4
 130#define ASN1_ERR_DEC_BADVALUE           5
 131
 132/*
 133 * ASN.1 context.
 134 */
 135struct asn1_ctx
 136{
 137        int error;                      /* Error condition */
 138        unsigned char *pointer;         /* Octet just to be decoded */
 139        unsigned char *begin;           /* First octet */
 140        unsigned char *end;             /* Octet after last octet */
 141};
 142
 143/*
 144 * Octet string (not null terminated)
 145 */
 146struct asn1_octstr
 147{
 148        unsigned char *data;
 149        unsigned int len;
 150};
 151
 152static void asn1_open(struct asn1_ctx *ctx,
 153                      unsigned char *buf,
 154                      unsigned int len)
 155{
 156        ctx->begin = buf;
 157        ctx->end = buf + len;
 158        ctx->pointer = buf;
 159        ctx->error = ASN1_ERR_NOERROR;
 160}
 161
 162static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
 163{
 164        if (ctx->pointer >= ctx->end) {
 165                ctx->error = ASN1_ERR_DEC_EMPTY;
 166                return 0;
 167        }
 168        *ch = *(ctx->pointer)++;
 169        return 1;
 170}
 171
 172static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
 173{
 174        unsigned char ch;
 175
 176        *tag = 0;
 177
 178        do
 179        {
 180                if (!asn1_octet_decode(ctx, &ch))
 181                        return 0;
 182                *tag <<= 7;
 183                *tag |= ch & 0x7F;
 184        } while ((ch & 0x80) == 0x80);
 185        return 1;
 186}
 187
 188static unsigned char asn1_id_decode(struct asn1_ctx *ctx,
 189                                    unsigned int *cls,
 190                                    unsigned int *con,
 191                                    unsigned int *tag)
 192{
 193        unsigned char ch;
 194
 195        if (!asn1_octet_decode(ctx, &ch))
 196                return 0;
 197
 198        *cls = (ch & 0xC0) >> 6;
 199        *con = (ch & 0x20) >> 5;
 200        *tag = (ch & 0x1F);
 201
 202        if (*tag == 0x1F) {
 203                if (!asn1_tag_decode(ctx, tag))
 204                        return 0;
 205        }
 206        return 1;
 207}
 208
 209static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
 210                                        unsigned int *def,
 211                                        unsigned int *len)
 212{
 213        unsigned char ch, cnt;
 214
 215        if (!asn1_octet_decode(ctx, &ch))
 216                return 0;
 217
 218        if (ch == 0x80)
 219                *def = 0;
 220        else {
 221                *def = 1;
 222
 223                if (ch < 0x80)
 224                        *len = ch;
 225                else {
 226                        cnt = ch & 0x7F;
 227                        *len = 0;
 228
 229                        while (cnt > 0) {
 230                                if (!asn1_octet_decode(ctx, &ch))
 231                                        return 0;
 232                                *len <<= 8;
 233                                *len |= ch;
 234                                cnt--;
 235                        }
 236                }
 237        }
 238
 239        /* don't trust len bigger than ctx buffer */
 240        if (*len > ctx->end - ctx->pointer)
 241                return 0;
 242
 243        return 1;
 244}
 245
 246static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
 247                                        unsigned char **eoc,
 248                                        unsigned int *cls,
 249                                        unsigned int *con,
 250                                        unsigned int *tag)
 251{
 252        unsigned int def, len;
 253
 254        if (!asn1_id_decode(ctx, cls, con, tag))
 255                return 0;
 256
 257        def = len = 0;
 258        if (!asn1_length_decode(ctx, &def, &len))
 259                return 0;
 260
 261        /* primitive shall be definite, indefinite shall be constructed */
 262        if (*con == ASN1_PRI && !def)
 263                return 0;
 264
 265        if (def)
 266                *eoc = ctx->pointer + len;
 267        else
 268                *eoc = NULL;
 269        return 1;
 270}
 271
 272static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
 273{
 274        unsigned char ch;
 275
 276        if (eoc == NULL) {
 277                if (!asn1_octet_decode(ctx, &ch))
 278                        return 0;
 279
 280                if (ch != 0x00) {
 281                        ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
 282                        return 0;
 283                }
 284
 285                if (!asn1_octet_decode(ctx, &ch))
 286                        return 0;
 287
 288                if (ch != 0x00) {
 289                        ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
 290                        return 0;
 291                }
 292                return 1;
 293        } else {
 294                if (ctx->pointer != eoc) {
 295                        ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
 296                        return 0;
 297                }
 298                return 1;
 299        }
 300}
 301
 302static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc)
 303{
 304        ctx->pointer = eoc;
 305        return 1;
 306}
 307
 308static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
 309                                      unsigned char *eoc,
 310                                      long *integer)
 311{
 312        unsigned char ch;
 313        unsigned int  len;
 314
 315        if (!asn1_octet_decode(ctx, &ch))
 316                return 0;
 317
 318        *integer = (signed char) ch;
 319        len = 1;
 320
 321        while (ctx->pointer < eoc) {
 322                if (++len > sizeof (long)) {
 323                        ctx->error = ASN1_ERR_DEC_BADVALUE;
 324                        return 0;
 325                }
 326
 327                if (!asn1_octet_decode(ctx, &ch))
 328                        return 0;
 329
 330                *integer <<= 8;
 331                *integer |= ch;
 332        }
 333        return 1;
 334}
 335
 336static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
 337                                      unsigned char *eoc,
 338                                      unsigned int *integer)
 339{
 340        unsigned char ch;
 341        unsigned int  len;
 342
 343        if (!asn1_octet_decode(ctx, &ch))
 344                return 0;
 345
 346        *integer = ch;
 347        if (ch == 0) len = 0;
 348        else len = 1;
 349
 350        while (ctx->pointer < eoc) {
 351                if (++len > sizeof (unsigned int)) {
 352                        ctx->error = ASN1_ERR_DEC_BADVALUE;
 353                        return 0;
 354                }
 355
 356                if (!asn1_octet_decode(ctx, &ch))
 357                        return 0;
 358
 359                *integer <<= 8;
 360                *integer |= ch;
 361        }
 362        return 1;
 363}
 364
 365static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
 366                                       unsigned char *eoc,
 367                                       unsigned long *integer)
 368{
 369        unsigned char ch;
 370        unsigned int  len;
 371
 372        if (!asn1_octet_decode(ctx, &ch))
 373                return 0;
 374
 375        *integer = ch;
 376        if (ch == 0) len = 0;
 377        else len = 1;
 378
 379        while (ctx->pointer < eoc) {
 380                if (++len > sizeof (unsigned long)) {
 381                        ctx->error = ASN1_ERR_DEC_BADVALUE;
 382                        return 0;
 383                }
 384
 385                if (!asn1_octet_decode(ctx, &ch))
 386                        return 0;
 387
 388                *integer <<= 8;
 389                *integer |= ch;
 390        }
 391        return 1;
 392}
 393
 394static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
 395                                        unsigned char *eoc,
 396                                        unsigned char **octets,
 397                                        unsigned int *len)
 398{
 399        unsigned char *ptr;
 400
 401        *len = 0;
 402
 403        *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
 404        if (*octets == NULL)
 405                return 0;
 406
 407        ptr = *octets;
 408        while (ctx->pointer < eoc) {
 409                if (!asn1_octet_decode(ctx, ptr++)) {
 410                        kfree(*octets);
 411                        *octets = NULL;
 412                        return 0;
 413                }
 414                (*len)++;
 415        }
 416        return 1;
 417}
 418
 419static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,
 420                                       unsigned long *subid)
 421{
 422        unsigned char ch;
 423
 424        *subid = 0;
 425
 426        do {
 427                if (!asn1_octet_decode(ctx, &ch))
 428                        return 0;
 429
 430                *subid <<= 7;
 431                *subid |= ch & 0x7F;
 432        } while ((ch & 0x80) == 0x80);
 433        return 1;
 434}
 435
 436static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
 437                                     unsigned char *eoc,
 438                                     unsigned long **oid,
 439                                     unsigned int *len)
 440{
 441        unsigned long subid;
 442        unsigned long *optr;
 443        size_t size;
 444
 445        size = eoc - ctx->pointer + 1;
 446
 447        /* first subid actually encodes first two subids */
 448        if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
 449                return 0;
 450
 451        *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
 452        if (*oid == NULL)
 453                return 0;
 454
 455        optr = *oid;
 456
 457        if (!asn1_subid_decode(ctx, &subid)) {
 458                kfree(*oid);
 459                *oid = NULL;
 460                return 0;
 461        }
 462
 463        if (subid < 40) {
 464                optr[0] = 0;
 465                optr[1] = subid;
 466        } else if (subid < 80) {
 467                optr[0] = 1;
 468                optr[1] = subid - 40;
 469        } else {
 470                optr[0] = 2;
 471                optr[1] = subid - 80;
 472        }
 473
 474        *len = 2;
 475        optr += 2;
 476
 477        while (ctx->pointer < eoc) {
 478                if (++(*len) > size) {
 479                        ctx->error = ASN1_ERR_DEC_BADVALUE;
 480                        kfree(*oid);
 481                        *oid = NULL;
 482                        return 0;
 483                }
 484
 485                if (!asn1_subid_decode(ctx, optr++)) {
 486                        kfree(*oid);
 487                        *oid = NULL;
 488                        return 0;
 489                }
 490        }
 491        return 1;
 492}
 493
 494/*****************************************************************************
 495 *
 496 * SNMP decoding routines (gxsnmp author Dirk Wisse)
 497 *
 498 *****************************************************************************/
 499
 500/* SNMP Versions */
 501#define SNMP_V1                         0
 502#define SNMP_V2C                        1
 503#define SNMP_V2                         2
 504#define SNMP_V3                         3
 505
 506/* Default Sizes */
 507#define SNMP_SIZE_COMM                  256
 508#define SNMP_SIZE_OBJECTID              128
 509#define SNMP_SIZE_BUFCHR                256
 510#define SNMP_SIZE_BUFINT                128
 511#define SNMP_SIZE_SMALLOBJECTID         16
 512
 513/* Requests */
 514#define SNMP_PDU_GET                    0
 515#define SNMP_PDU_NEXT                   1
 516#define SNMP_PDU_RESPONSE               2
 517#define SNMP_PDU_SET                    3
 518#define SNMP_PDU_TRAP1                  4
 519#define SNMP_PDU_BULK                   5
 520#define SNMP_PDU_INFORM                 6
 521#define SNMP_PDU_TRAP2                  7
 522
 523/* Errors */
 524#define SNMP_NOERROR                    0
 525#define SNMP_TOOBIG                     1
 526#define SNMP_NOSUCHNAME                 2
 527#define SNMP_BADVALUE                   3
 528#define SNMP_READONLY                   4
 529#define SNMP_GENERROR                   5
 530#define SNMP_NOACCESS                   6
 531#define SNMP_WRONGTYPE                  7
 532#define SNMP_WRONGLENGTH                8
 533#define SNMP_WRONGENCODING              9
 534#define SNMP_WRONGVALUE                 10
 535#define SNMP_NOCREATION                 11
 536#define SNMP_INCONSISTENTVALUE          12
 537#define SNMP_RESOURCEUNAVAILABLE        13
 538#define SNMP_COMMITFAILED               14
 539#define SNMP_UNDOFAILED                 15
 540#define SNMP_AUTHORIZATIONERROR         16
 541#define SNMP_NOTWRITABLE                17
 542#define SNMP_INCONSISTENTNAME           18
 543
 544/* General SNMP V1 Traps */
 545#define SNMP_TRAP_COLDSTART             0
 546#define SNMP_TRAP_WARMSTART             1
 547#define SNMP_TRAP_LINKDOWN              2
 548#define SNMP_TRAP_LINKUP                3
 549#define SNMP_TRAP_AUTFAILURE            4
 550#define SNMP_TRAP_EQPNEIGHBORLOSS       5
 551#define SNMP_TRAP_ENTSPECIFIC           6
 552
 553/* SNMPv1 Types */
 554#define SNMP_NULL                0
 555#define SNMP_INTEGER             1    /* l  */
 556#define SNMP_OCTETSTR            2    /* c  */
 557#define SNMP_DISPLAYSTR          2    /* c  */
 558#define SNMP_OBJECTID            3    /* ul */
 559#define SNMP_IPADDR              4    /* uc */
 560#define SNMP_COUNTER             5    /* ul */
 561#define SNMP_GAUGE               6    /* ul */
 562#define SNMP_TIMETICKS           7    /* ul */
 563#define SNMP_OPAQUE              8    /* c  */
 564
 565/* Additional SNMPv2 Types */
 566#define SNMP_UINTEGER            5    /* ul */
 567#define SNMP_BITSTR              9    /* uc */
 568#define SNMP_NSAP               10    /* uc */
 569#define SNMP_COUNTER64          11    /* ul */
 570#define SNMP_NOSUCHOBJECT       12
 571#define SNMP_NOSUCHINSTANCE     13
 572#define SNMP_ENDOFMIBVIEW       14
 573
 574union snmp_syntax
 575{
 576        unsigned char uc[0];    /* 8 bit unsigned */
 577        char c[0];              /* 8 bit signed */
 578        unsigned long ul[0];    /* 32 bit unsigned */
 579        long l[0];              /* 32 bit signed */
 580};
 581
 582struct snmp_object
 583{
 584        unsigned long *id;
 585        unsigned int id_len;
 586        unsigned short type;
 587        unsigned int syntax_len;
 588        union snmp_syntax syntax;
 589};
 590
 591struct snmp_request
 592{
 593        unsigned long id;
 594        unsigned int error_status;
 595        unsigned int error_index;
 596};
 597
 598struct snmp_v1_trap
 599{
 600        unsigned long *id;
 601        unsigned int id_len;
 602        unsigned long ip_address;       /* pointer  */
 603        unsigned int general;
 604        unsigned int specific;
 605        unsigned long time;
 606};
 607
 608/* SNMP types */
 609#define SNMP_IPA    0
 610#define SNMP_CNT    1
 611#define SNMP_GGE    2
 612#define SNMP_TIT    3
 613#define SNMP_OPQ    4
 614#define SNMP_C64    6
 615
 616/* SNMP errors */
 617#define SERR_NSO    0
 618#define SERR_NSI    1
 619#define SERR_EOM    2
 620
 621static inline void mangle_address(unsigned char *begin,
 622                                  unsigned char *addr,
 623                                  const struct oct1_map *map,
 624                                  __sum16 *check);
 625struct snmp_cnv
 626{
 627        unsigned int class;
 628        unsigned int tag;
 629        int syntax;
 630};
 631
 632static const struct snmp_cnv snmp_conv[] = {
 633        {ASN1_UNI, ASN1_NUL, SNMP_NULL},
 634        {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
 635        {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
 636        {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
 637        {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
 638        {ASN1_APL, SNMP_IPA, SNMP_IPADDR},
 639        {ASN1_APL, SNMP_CNT, SNMP_COUNTER},     /* Counter32 */
 640        {ASN1_APL, SNMP_GGE, SNMP_GAUGE},       /* Gauge32 == Unsigned32  */
 641        {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
 642        {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
 643
 644        /* SNMPv2 data types and errors */
 645        {ASN1_UNI, ASN1_BTS, SNMP_BITSTR},
 646        {ASN1_APL, SNMP_C64, SNMP_COUNTER64},
 647        {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT},
 648        {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE},
 649        {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW},
 650        {0,       0,       -1}
 651};
 652
 653static unsigned char snmp_tag_cls2syntax(unsigned int tag,
 654                                         unsigned int cls,
 655                                         unsigned short *syntax)
 656{
 657        const struct snmp_cnv *cnv;
 658
 659        cnv = snmp_conv;
 660
 661        while (cnv->syntax != -1) {
 662                if (cnv->tag == tag && cnv->class == cls) {
 663                        *syntax = cnv->syntax;
 664                        return 1;
 665                }
 666                cnv++;
 667        }
 668        return 0;
 669}
 670
 671static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
 672                                        struct snmp_object **obj)
 673{
 674        unsigned int cls, con, tag, len, idlen;
 675        unsigned short type;
 676        unsigned char *eoc, *end, *p;
 677        unsigned long *lp, *id;
 678        unsigned long ul;
 679        long l;
 680
 681        *obj = NULL;
 682        id = NULL;
 683
 684        if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag))
 685                return 0;
 686
 687        if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
 688                return 0;
 689
 690        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 691                return 0;
 692
 693        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
 694                return 0;
 695
 696        if (!asn1_oid_decode(ctx, end, &id, &idlen))
 697                return 0;
 698
 699        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) {
 700                kfree(id);
 701                return 0;
 702        }
 703
 704        if (con != ASN1_PRI) {
 705                kfree(id);
 706                return 0;
 707        }
 708
 709        type = 0;
 710        if (!snmp_tag_cls2syntax(tag, cls, &type)) {
 711                kfree(id);
 712                return 0;
 713        }
 714
 715        l = 0;
 716        switch (type) {
 717        case SNMP_INTEGER:
 718                len = sizeof(long);
 719                if (!asn1_long_decode(ctx, end, &l)) {
 720                        kfree(id);
 721                        return 0;
 722                }
 723                *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
 724                if (*obj == NULL) {
 725                        kfree(id);
 726                        return 0;
 727                }
 728                (*obj)->syntax.l[0] = l;
 729                break;
 730        case SNMP_OCTETSTR:
 731        case SNMP_OPAQUE:
 732                if (!asn1_octets_decode(ctx, end, &p, &len)) {
 733                        kfree(id);
 734                        return 0;
 735                }
 736                *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
 737                if (*obj == NULL) {
 738                        kfree(p);
 739                        kfree(id);
 740                        return 0;
 741                }
 742                memcpy((*obj)->syntax.c, p, len);
 743                kfree(p);
 744                break;
 745        case SNMP_NULL:
 746        case SNMP_NOSUCHOBJECT:
 747        case SNMP_NOSUCHINSTANCE:
 748        case SNMP_ENDOFMIBVIEW:
 749                len = 0;
 750                *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
 751                if (*obj == NULL) {
 752                        kfree(id);
 753                        return 0;
 754                }
 755                if (!asn1_null_decode(ctx, end)) {
 756                        kfree(id);
 757                        kfree(*obj);
 758                        *obj = NULL;
 759                        return 0;
 760                }
 761                break;
 762        case SNMP_OBJECTID:
 763                if (!asn1_oid_decode(ctx, end, &lp, &len)) {
 764                        kfree(id);
 765                        return 0;
 766                }
 767                len *= sizeof(unsigned long);
 768                *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
 769                if (*obj == NULL) {
 770                        kfree(lp);
 771                        kfree(id);
 772                        return 0;
 773                }
 774                memcpy((*obj)->syntax.ul, lp, len);
 775                kfree(lp);
 776                break;
 777        case SNMP_IPADDR:
 778                if (!asn1_octets_decode(ctx, end, &p, &len)) {
 779                        kfree(id);
 780                        return 0;
 781                }
 782                if (len != 4) {
 783                        kfree(p);
 784                        kfree(id);
 785                        return 0;
 786                }
 787                *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
 788                if (*obj == NULL) {
 789                        kfree(p);
 790                        kfree(id);
 791                        return 0;
 792                }
 793                memcpy((*obj)->syntax.uc, p, len);
 794                kfree(p);
 795                break;
 796        case SNMP_COUNTER:
 797        case SNMP_GAUGE:
 798        case SNMP_TIMETICKS:
 799                len = sizeof(unsigned long);
 800                if (!asn1_ulong_decode(ctx, end, &ul)) {
 801                        kfree(id);
 802                        return 0;
 803                }
 804                *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
 805                if (*obj == NULL) {
 806                        kfree(id);
 807                        return 0;
 808                }
 809                (*obj)->syntax.ul[0] = ul;
 810                break;
 811        default:
 812                kfree(id);
 813                return 0;
 814        }
 815
 816        (*obj)->syntax_len = len;
 817        (*obj)->type = type;
 818        (*obj)->id = id;
 819        (*obj)->id_len = idlen;
 820
 821        if (!asn1_eoc_decode(ctx, eoc)) {
 822                kfree(id);
 823                kfree(*obj);
 824                *obj = NULL;
 825                return 0;
 826        }
 827        return 1;
 828}
 829
 830static unsigned char snmp_request_decode(struct asn1_ctx *ctx,
 831                                         struct snmp_request *request)
 832{
 833        unsigned int cls, con, tag;
 834        unsigned char *end;
 835
 836        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 837                return 0;
 838
 839        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
 840                return 0;
 841
 842        if (!asn1_ulong_decode(ctx, end, &request->id))
 843                return 0;
 844
 845        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 846                return 0;
 847
 848        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
 849                return 0;
 850
 851        if (!asn1_uint_decode(ctx, end, &request->error_status))
 852                return 0;
 853
 854        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 855                return 0;
 856
 857        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
 858                return 0;
 859
 860        if (!asn1_uint_decode(ctx, end, &request->error_index))
 861                return 0;
 862
 863        return 1;
 864}
 865
 866/*
 867 * Fast checksum update for possibly oddly-aligned UDP byte, from the
 868 * code example in the draft.
 869 */
 870static void fast_csum(__sum16 *csum,
 871                      const unsigned char *optr,
 872                      const unsigned char *nptr,
 873                      int offset)
 874{
 875        unsigned char s[4];
 876
 877        if (offset & 1) {
 878                s[0] = ~0;
 879                s[1] = ~*optr;
 880                s[2] = 0;
 881                s[3] = *nptr;
 882        } else {
 883                s[0] = ~*optr;
 884                s[1] = ~0;
 885                s[2] = *nptr;
 886                s[3] = 0;
 887        }
 888
 889        *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
 890}
 891
 892/*
 893 * Mangle IP address.
 894 *      - begin points to the start of the snmp messgae
 895 *      - addr points to the start of the address
 896 */
 897static inline void mangle_address(unsigned char *begin,
 898                                  unsigned char *addr,
 899                                  const struct oct1_map *map,
 900                                  __sum16 *check)
 901{
 902        if (map->from == NOCT1(addr)) {
 903                u_int32_t old;
 904
 905                if (debug)
 906                        memcpy(&old, addr, sizeof(old));
 907
 908                *addr = map->to;
 909
 910                /* Update UDP checksum if being used */
 911                if (*check) {
 912                        fast_csum(check,
 913                                  &map->from, &map->to, addr - begin);
 914
 915                }
 916
 917                if (debug)
 918                        printk(KERN_DEBUG "bsalg: mapped %pI4 to %pI4\n",
 919                               &old, addr);
 920        }
 921}
 922
 923static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
 924                                      struct snmp_v1_trap *trap,
 925                                      const struct oct1_map *map,
 926                                      __sum16 *check)
 927{
 928        unsigned int cls, con, tag, len;
 929        unsigned char *end;
 930
 931        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 932                return 0;
 933
 934        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
 935                return 0;
 936
 937        if (!asn1_oid_decode(ctx, end, &trap->id, &trap->id_len))
 938                return 0;
 939
 940        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 941                goto err_id_free;
 942
 943        if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_IPA) ||
 944              (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)))
 945                goto err_id_free;
 946
 947        if (!asn1_octets_decode(ctx, end, (unsigned char **)&trap->ip_address, &len))
 948                goto err_id_free;
 949
 950        /* IPv4 only */
 951        if (len != 4)
 952                goto err_addr_free;
 953
 954        mangle_address(ctx->begin, ctx->pointer - 4, map, check);
 955
 956        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 957                goto err_addr_free;
 958
 959        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
 960                goto err_addr_free;
 961
 962        if (!asn1_uint_decode(ctx, end, &trap->general))
 963                goto err_addr_free;
 964
 965        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 966                goto err_addr_free;
 967
 968        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
 969                goto err_addr_free;
 970
 971        if (!asn1_uint_decode(ctx, end, &trap->specific))
 972                goto err_addr_free;
 973
 974        if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
 975                goto err_addr_free;
 976
 977        if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) ||
 978              (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT)))
 979                goto err_addr_free;
 980
 981        if (!asn1_ulong_decode(ctx, end, &trap->time))
 982                goto err_addr_free;
 983
 984        return 1;
 985
 986err_addr_free:
 987        kfree((unsigned long *)trap->ip_address);
 988
 989err_id_free:
 990        kfree(trap->id);
 991
 992        return 0;
 993}
 994
 995/*****************************************************************************
 996 *
 997 * Misc. routines
 998 *
 999 *****************************************************************************/
1000
1001static void hex_dump(const unsigned char *buf, size_t len)
1002{
1003        size_t i;
1004
1005        for (i = 0; i < len; i++) {
1006                if (i && !(i % 16))
1007                        printk("\n");
1008                printk("%02x ", *(buf + i));
1009        }
1010        printk("\n");
1011}
1012
1013/*
1014 * Parse and mangle SNMP message according to mapping.
1015 * (And this is the fucking 'basic' method).
1016 */
1017static int snmp_parse_mangle(unsigned char *msg,
1018                             u_int16_t len,
1019                             const struct oct1_map *map,
1020                             __sum16 *check)
1021{
1022        unsigned char *eoc, *end;
1023        unsigned int cls, con, tag, vers, pdutype;
1024        struct asn1_ctx ctx;
1025        struct asn1_octstr comm;
1026        struct snmp_object *obj;
1027
1028        if (debug > 1)
1029                hex_dump(msg, len);
1030
1031        asn1_open(&ctx, msg, len);
1032
1033        /*
1034         * Start of SNMP message.
1035         */
1036        if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1037                return 0;
1038        if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1039                return 0;
1040
1041        /*
1042         * Version 1 or 2 handled.
1043         */
1044        if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag))
1045                return 0;
1046        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
1047                return 0;
1048        if (!asn1_uint_decode (&ctx, end, &vers))
1049                return 0;
1050        if (debug > 1)
1051                pr_debug("bsalg: snmp version: %u\n", vers + 1);
1052        if (vers > 1)
1053                return 1;
1054
1055        /*
1056         * Community.
1057         */
1058        if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag))
1059                return 0;
1060        if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS)
1061                return 0;
1062        if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len))
1063                return 0;
1064        if (debug > 1) {
1065                unsigned int i;
1066
1067                pr_debug("bsalg: community: ");
1068                for (i = 0; i < comm.len; i++)
1069                        pr_cont("%c", comm.data[i]);
1070                pr_cont("\n");
1071        }
1072        kfree(comm.data);
1073
1074        /*
1075         * PDU type
1076         */
1077        if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype))
1078                return 0;
1079        if (cls != ASN1_CTX || con != ASN1_CON)
1080                return 0;
1081        if (debug > 1) {
1082                static const unsigned char *const pdus[] = {
1083                        [SNMP_PDU_GET] = "get",
1084                        [SNMP_PDU_NEXT] = "get-next",
1085                        [SNMP_PDU_RESPONSE] = "response",
1086                        [SNMP_PDU_SET] = "set",
1087                        [SNMP_PDU_TRAP1] = "trapv1",
1088                        [SNMP_PDU_BULK] = "bulk",
1089                        [SNMP_PDU_INFORM] = "inform",
1090                        [SNMP_PDU_TRAP2] = "trapv2"
1091                };
1092
1093                if (pdutype > SNMP_PDU_TRAP2)
1094                        pr_debug("bsalg: bad pdu type %u\n", pdutype);
1095                else
1096                        pr_debug("bsalg: pdu: %s\n", pdus[pdutype]);
1097        }
1098        if (pdutype != SNMP_PDU_RESPONSE &&
1099            pdutype != SNMP_PDU_TRAP1 && pdutype != SNMP_PDU_TRAP2)
1100                return 1;
1101
1102        /*
1103         * Request header or v1 trap
1104         */
1105        if (pdutype == SNMP_PDU_TRAP1) {
1106                struct snmp_v1_trap trap;
1107                unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
1108
1109                if (ret) {
1110                        kfree(trap.id);
1111                        kfree((unsigned long *)trap.ip_address);
1112                } else
1113                        return ret;
1114
1115        } else {
1116                struct snmp_request req;
1117
1118                if (!snmp_request_decode(&ctx, &req))
1119                        return 0;
1120
1121                if (debug > 1)
1122                        pr_debug("bsalg: request: id=0x%lx error_status=%u "
1123                        "error_index=%u\n", req.id, req.error_status,
1124                        req.error_index);
1125        }
1126
1127        /*
1128         * Loop through objects, look for IP addresses to mangle.
1129         */
1130        if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1131                return 0;
1132
1133        if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1134                return 0;
1135
1136        while (!asn1_eoc_decode(&ctx, eoc)) {
1137                unsigned int i;
1138
1139                if (!snmp_object_decode(&ctx, &obj)) {
1140                        if (obj) {
1141                                kfree(obj->id);
1142                                kfree(obj);
1143                        }
1144                        return 0;
1145                }
1146
1147                if (debug > 1) {
1148                        pr_debug("bsalg: object: ");
1149                        for (i = 0; i < obj->id_len; i++) {
1150                                if (i > 0)
1151                                        pr_cont(".");
1152                                pr_cont("%lu", obj->id[i]);
1153                        }
1154                        pr_cont(": type=%u\n", obj->type);
1155
1156                }
1157
1158                if (obj->type == SNMP_IPADDR)
1159                        mangle_address(ctx.begin, ctx.pointer - 4, map, check);
1160
1161                kfree(obj->id);
1162                kfree(obj);
1163        }
1164
1165        if (!asn1_eoc_decode(&ctx, eoc))
1166                return 0;
1167
1168        return 1;
1169}
1170
1171/*****************************************************************************
1172 *
1173 * NAT routines.
1174 *
1175 *****************************************************************************/
1176
1177/*
1178 * SNMP translation routine.
1179 */
1180static int snmp_translate(struct nf_conn *ct,
1181                          enum ip_conntrack_info ctinfo,
1182                          struct sk_buff *skb)
1183{
1184        struct iphdr *iph = ip_hdr(skb);
1185        struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1186        u_int16_t udplen = ntohs(udph->len);
1187        u_int16_t paylen = udplen - sizeof(struct udphdr);
1188        int dir = CTINFO2DIR(ctinfo);
1189        struct oct1_map map;
1190
1191        /*
1192         * Determine mappping for application layer addresses based
1193         * on NAT manipulations for the packet.
1194         */
1195        if (dir == IP_CT_DIR_ORIGINAL) {
1196                /* SNAT traps */
1197                map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1198                map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1199        } else {
1200                /* DNAT replies */
1201                map.from = NOCT1(&ct->tuplehash[!dir].tuple.src.u3.ip);
1202                map.to = NOCT1(&ct->tuplehash[dir].tuple.dst.u3.ip);
1203        }
1204
1205        if (map.from == map.to)
1206                return NF_ACCEPT;
1207
1208        if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr),
1209                               paylen, &map, &udph->check)) {
1210                net_warn_ratelimited("bsalg: parser failed\n");
1211                return NF_DROP;
1212        }
1213        return NF_ACCEPT;
1214}
1215
1216/* We don't actually set up expectations, just adjust internal IP
1217 * addresses if this is being NATted */
1218static int help(struct sk_buff *skb, unsigned int protoff,
1219                struct nf_conn *ct,
1220                enum ip_conntrack_info ctinfo)
1221{
1222        int dir = CTINFO2DIR(ctinfo);
1223        unsigned int ret;
1224        const struct iphdr *iph = ip_hdr(skb);
1225        const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1226
1227        /* SNMP replies and originating SNMP traps get mangled */
1228        if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
1229                return NF_ACCEPT;
1230        if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
1231                return NF_ACCEPT;
1232
1233        /* No NAT? */
1234        if (!(ct->status & IPS_NAT_MASK))
1235                return NF_ACCEPT;
1236
1237        /*
1238         * Make sure the packet length is ok.  So far, we were only guaranteed
1239         * to have a valid length IP header plus 8 bytes, which means we have
1240         * enough room for a UDP header.  Just verify the UDP length field so we
1241         * can mess around with the payload.
1242         */
1243        if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) {
1244                net_warn_ratelimited("SNMP: dropping malformed packet src=%pI4 dst=%pI4\n",
1245                                     &iph->saddr, &iph->daddr);
1246                 return NF_DROP;
1247        }
1248
1249        if (!skb_make_writable(skb, skb->len))
1250                return NF_DROP;
1251
1252        spin_lock_bh(&snmp_lock);
1253        ret = snmp_translate(ct, ctinfo, skb);
1254        spin_unlock_bh(&snmp_lock);
1255        return ret;
1256}
1257
1258static const struct nf_conntrack_expect_policy snmp_exp_policy = {
1259        .max_expected   = 0,
1260        .timeout        = 180,
1261};
1262
1263static struct nf_conntrack_helper snmp_helper __read_mostly = {
1264        .me                     = THIS_MODULE,
1265        .help                   = help,
1266        .expect_policy          = &snmp_exp_policy,
1267        .name                   = "snmp",
1268        .tuple.src.l3num        = AF_INET,
1269        .tuple.src.u.udp.port   = cpu_to_be16(SNMP_PORT),
1270        .tuple.dst.protonum     = IPPROTO_UDP,
1271};
1272
1273static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1274        .me                     = THIS_MODULE,
1275        .help                   = help,
1276        .expect_policy          = &snmp_exp_policy,
1277        .name                   = "snmp_trap",
1278        .tuple.src.l3num        = AF_INET,
1279        .tuple.src.u.udp.port   = cpu_to_be16(SNMP_TRAP_PORT),
1280        .tuple.dst.protonum     = IPPROTO_UDP,
1281};
1282
1283/*****************************************************************************
1284 *
1285 * Module stuff.
1286 *
1287 *****************************************************************************/
1288
1289static int __init nf_nat_snmp_basic_init(void)
1290{
1291        int ret = 0;
1292
1293        BUG_ON(nf_nat_snmp_hook != NULL);
1294        RCU_INIT_POINTER(nf_nat_snmp_hook, help);
1295
1296        ret = nf_conntrack_helper_register(&snmp_trap_helper);
1297        if (ret < 0) {
1298                nf_conntrack_helper_unregister(&snmp_helper);
1299                return ret;
1300        }
1301        return ret;
1302}
1303
1304static void __exit nf_nat_snmp_basic_fini(void)
1305{
1306        RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
1307        nf_conntrack_helper_unregister(&snmp_trap_helper);
1308}
1309
1310module_init(nf_nat_snmp_basic_init);
1311module_exit(nf_nat_snmp_basic_fini);
1312
1313module_param(debug, int, 0600);
1314