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