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