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/in.h> 47#include <linux/ip.h> 48#include <linux/udp.h> 49#include <net/checksum.h> 50#include <net/udp.h> 51 52#include <net/netfilter/nf_nat.h> 53#include <net/netfilter/nf_conntrack_helper.h> 54#include <net/netfilter/nf_nat_helper.h> 55 56MODULE_LICENSE("GPL"); 57MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 58MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); 59MODULE_ALIAS("ip_nat_snmp_basic"); 60 61#define SNMP_PORT 161 62#define SNMP_TRAP_PORT 162 63#define NOCT1(n) (*(u8 *)n) 64 65static int debug; 66static DEFINE_SPINLOCK(snmp_lock); 67 68/* 69 * Application layer address mapping mimics the NAT mapping, but 70 * only for the first octet in this case (a more flexible system 71 * can be implemented if needed). 72 */ 73struct oct1_map 74{ 75 u_int8_t from; 76 u_int8_t to; 77}; 78 79 80/***************************************************************************** 81 * 82 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse) 83 * 84 *****************************************************************************/ 85 86/* Class */ 87#define ASN1_UNI 0 /* Universal */ 88#define ASN1_APL 1 /* Application */ 89#define ASN1_CTX 2 /* Context */ 90#define ASN1_PRV 3 /* Private */ 91 92/* Tag */ 93#define ASN1_EOC 0 /* End Of Contents */ 94#define ASN1_BOL 1 /* Boolean */ 95#define ASN1_INT 2 /* Integer */ 96#define ASN1_BTS 3 /* Bit String */ 97#define ASN1_OTS 4 /* Octet String */ 98#define ASN1_NUL 5 /* Null */ 99#define ASN1_OJI 6 /* Object Identifier */ 100#define ASN1_OJD 7 /* Object Description */ 101#define ASN1_EXT 8 /* External */ 102#define ASN1_SEQ 16 /* Sequence */ 103#define ASN1_SET 17 /* Set */ 104#define ASN1_NUMSTR 18 /* Numerical String */ 105#define ASN1_PRNSTR 19 /* Printable String */ 106#define ASN1_TEXSTR 20 /* Teletext String */ 107#define ASN1_VIDSTR 21 /* Video String */ 108#define ASN1_IA5STR 22 /* IA5 String */ 109#define ASN1_UNITIM 23 /* Universal Time */ 110#define ASN1_GENTIM 24 /* General Time */ 111#define ASN1_GRASTR 25 /* Graphical String */ 112#define ASN1_VISSTR 26 /* Visible String */ 113#define ASN1_GENSTR 27 /* General String */ 114 115/* Primitive / Constructed methods*/ 116#define ASN1_PRI 0 /* Primitive */ 117#define ASN1_CON 1 /* Constructed */ 118 119/* 120 * Error codes. 121 */ 122#define ASN1_ERR_NOERROR 0 123#define ASN1_ERR_DEC_EMPTY 2 124#define ASN1_ERR_DEC_EOC_MISMATCH 3 125#define ASN1_ERR_DEC_LENGTH_MISMATCH 4 126#define ASN1_ERR_DEC_BADVALUE 5 127 128/* 129 * ASN.1 context. 130 */ 131struct asn1_ctx 132{ 133 int error; /* Error condition */ 134 unsigned char *pointer; /* Octet just to be decoded */ 135 unsigned char *begin; /* First octet */ 136 unsigned char *end; /* Octet after last octet */ 137}; 138 139/* 140 * Octet string (not null terminated) 141 */ 142struct asn1_octstr 143{ 144 unsigned char *data; 145 unsigned int len; 146}; 147 148static void asn1_open(struct asn1_ctx *ctx, 149 unsigned char *buf, 150 unsigned int len) 151{ 152 ctx->begin = buf; 153 ctx->end = buf + len; 154 ctx->pointer = buf; 155 ctx->error = ASN1_ERR_NOERROR; 156} 157 158static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) 159{ 160 if (ctx->pointer >= ctx->end) { 161 ctx->error = ASN1_ERR_DEC_EMPTY; 162 return 0; 163 } 164 *ch = *(ctx->pointer)++; 165 return 1; 166} 167 168static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) 169{ 170 unsigned char ch; 171 172 *tag = 0; 173 174 do 175 { 176 if (!asn1_octet_decode(ctx, &ch)) 177 return 0; 178 *tag <<= 7; 179 *tag |= ch & 0x7F; 180 } while ((ch & 0x80) == 0x80); 181 return 1; 182} 183 184static unsigned char asn1_id_decode(struct asn1_ctx *ctx, 185 unsigned int *cls, 186 unsigned int *con, 187 unsigned int *tag) 188{ 189 unsigned char ch; 190 191 if (!asn1_octet_decode(ctx, &ch)) 192 return 0; 193 194 *cls = (ch & 0xC0) >> 6; 195 *con = (ch & 0x20) >> 5; 196 *tag = (ch & 0x1F); 197 198 if (*tag == 0x1F) { 199 if (!asn1_tag_decode(ctx, tag)) 200 return 0; 201 } 202 return 1; 203} 204 205static unsigned char asn1_length_decode(struct asn1_ctx *ctx, 206 unsigned int *def, 207 unsigned int *len) 208{ 209 unsigned char ch, cnt; 210 211 if (!asn1_octet_decode(ctx, &ch)) 212 return 0; 213 214 if (ch == 0x80) 215 *def = 0; 216 else { 217 *def = 1; 218 219 if (ch < 0x80) 220 *len = ch; 221 else { 222 cnt = (unsigned char) (ch & 0x7F); 223 *len = 0; 224 225 while (cnt > 0) { 226 if (!asn1_octet_decode(ctx, &ch)) 227 return 0; 228 *len <<= 8; 229 *len |= ch; 230 cnt--; 231 } 232 } 233 } 234 return 1; 235} 236 237static unsigned char asn1_header_decode(struct asn1_ctx *ctx, 238 unsigned char **eoc, 239 unsigned int *cls, 240 unsigned int *con, 241 unsigned int *tag) 242{ 243 unsigned int def, len; 244 245 if (!asn1_id_decode(ctx, cls, con, tag)) 246 return 0; 247 248 def = len = 0; 249 if (!asn1_length_decode(ctx, &def, &len)) 250 return 0; 251 252 if (def) 253 *eoc = ctx->pointer + len; 254 else 255 *eoc = NULL; 256 return 1; 257} 258 259static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc) 260{ 261 unsigned char ch; 262 263 if (eoc == 0) { 264 if (!asn1_octet_decode(ctx, &ch)) 265 return 0; 266 267 if (ch != 0x00) { 268 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; 269 return 0; 270 } 271 272 if (!asn1_octet_decode(ctx, &ch)) 273 return 0; 274 275 if (ch != 0x00) { 276 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; 277 return 0; 278 } 279 return 1; 280 } else { 281 if (ctx->pointer != eoc) { 282 ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH; 283 return 0; 284 } 285 return 1; 286 } 287} 288 289static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc) 290{ 291 ctx->pointer = eoc; 292 return 1; 293} 294 295static unsigned char asn1_long_decode(struct asn1_ctx *ctx, 296 unsigned char *eoc, 297 long *integer) 298{ 299 unsigned char ch; 300 unsigned int len; 301 302 if (!asn1_octet_decode(ctx, &ch)) 303 return 0; 304 305 *integer = (signed char) ch; 306 len = 1; 307 308 while (ctx->pointer < eoc) { 309 if (++len > sizeof (long)) { 310 ctx->error = ASN1_ERR_DEC_BADVALUE; 311 return 0; 312 } 313 314 if (!asn1_octet_decode(ctx, &ch)) 315 return 0; 316 317 *integer <<= 8; 318 *integer |= ch; 319 } 320 return 1; 321} 322 323static unsigned char asn1_uint_decode(struct asn1_ctx *ctx, 324 unsigned char *eoc, 325 unsigned int *integer) 326{ 327 unsigned char ch; 328 unsigned int len; 329 330 if (!asn1_octet_decode(ctx, &ch)) 331 return 0; 332 333 *integer = ch; 334 if (ch == 0) len = 0; 335 else len = 1; 336 337 while (ctx->pointer < eoc) { 338 if (++len > sizeof (unsigned int)) { 339 ctx->error = ASN1_ERR_DEC_BADVALUE; 340 return 0; 341 } 342 343 if (!asn1_octet_decode(ctx, &ch)) 344 return 0; 345 346 *integer <<= 8; 347 *integer |= ch; 348 } 349 return 1; 350} 351 352static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx, 353 unsigned char *eoc, 354 unsigned long *integer) 355{ 356 unsigned char ch; 357 unsigned int len; 358 359 if (!asn1_octet_decode(ctx, &ch)) 360 return 0; 361 362 *integer = ch; 363 if (ch == 0) len = 0; 364 else len = 1; 365 366 while (ctx->pointer < eoc) { 367 if (++len > sizeof (unsigned long)) { 368 ctx->error = ASN1_ERR_DEC_BADVALUE; 369 return 0; 370 } 371 372 if (!asn1_octet_decode(ctx, &ch)) 373 return 0; 374 375 *integer <<= 8; 376 *integer |= ch; 377 } 378 return 1; 379} 380 381static unsigned char asn1_octets_decode(struct asn1_ctx *ctx, 382 unsigned char *eoc, 383 unsigned char **octets, 384 unsigned int *len) 385{ 386 unsigned char *ptr; 387 388 *len = 0; 389 390 *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC); 391 if (*octets == NULL) { 392 if (net_ratelimit()) 393 printk("OOM in bsalg (%d)\n", __LINE__); 394 return 0; 395 } 396 397 ptr = *octets; 398 while (ctx->pointer < eoc) { 399 if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) { 400 kfree(*octets); 401 *octets = NULL; 402 return 0; 403 } 404 (*len)++; 405 } 406 return 1; 407} 408 409static unsigned char asn1_subid_decode(struct asn1_ctx *ctx, 410 unsigned long *subid) 411{ 412 unsigned char ch; 413 414 *subid = 0; 415 416 do { 417 if (!asn1_octet_decode(ctx, &ch)) 418 return 0; 419 420 *subid <<= 7; 421 *subid |= ch & 0x7F; 422 } while ((ch & 0x80) == 0x80); 423 return 1; 424} 425 426static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, 427 unsigned char *eoc, 428 unsigned long **oid, 429 unsigned int *len) 430{ 431 unsigned long subid; 432 unsigned int size; 433 unsigned long *optr; 434 435 size = eoc - ctx->pointer + 1; 436 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); 437 if (*oid == NULL) { 438 if (net_ratelimit()) 439 printk("OOM in bsalg (%d)\n", __LINE__); 440 return 0; 441 } 442 443 optr = *oid; 444 445 if (!asn1_subid_decode(ctx, &subid)) { 446 kfree(*oid); 447 *oid = NULL; 448 return 0; 449 } 450 451 if (subid < 40) { 452 optr [0] = 0; 453 optr [1] = subid; 454 } else if (subid < 80) { 455 optr [0] = 1; 456 optr [1] = subid - 40; 457 } else { 458 optr [0] = 2; 459 optr [1] = subid - 80; 460 } 461 462 *len = 2; 463 optr += 2; 464 465 while (ctx->pointer < eoc) { 466 if (++(*len) > size) { 467 ctx->error = ASN1_ERR_DEC_BADVALUE; 468 kfree(*oid); 469 *oid = NULL; 470 return 0; 471 } 472 473 if (!asn1_subid_decode(ctx, optr++)) { 474 kfree(*oid); 475 *oid = NULL; 476 return 0; 477 } 478 } 479 return 1; 480} 481 482/***************************************************************************** 483 * 484 * SNMP decoding routines (gxsnmp author Dirk Wisse) 485 * 486 *****************************************************************************/ 487 488/* SNMP Versions */ 489#define SNMP_V1 0 490#define SNMP_V2C 1 491#define SNMP_V2 2 492#define SNMP_V3 3 493 494/* Default Sizes */ 495#define SNMP_SIZE_COMM 256 496#define SNMP_SIZE_OBJECTID 128 497#define SNMP_SIZE_BUFCHR 256 498#define SNMP_SIZE_BUFINT 128 499#define SNMP_SIZE_SMALLOBJECTID 16 500 501/* Requests */ 502#define SNMP_PDU_GET 0 503#define SNMP_PDU_NEXT 1 504#define SNMP_PDU_RESPONSE 2 505#define SNMP_PDU_SET 3 506#define SNMP_PDU_TRAP1 4 507#define SNMP_PDU_BULK 5 508#define SNMP_PDU_INFORM 6 509#define SNMP_PDU_TRAP2 7 510 511/* Errors */ 512#define SNMP_NOERROR 0 513#define SNMP_TOOBIG 1 514#define SNMP_NOSUCHNAME 2 515#define SNMP_BADVALUE 3 516#define SNMP_READONLY 4 517#define SNMP_GENERROR 5 518#define SNMP_NOACCESS 6 519#define SNMP_WRONGTYPE 7 520#define SNMP_WRONGLENGTH 8 521#define SNMP_WRONGENCODING 9 522#define SNMP_WRONGVALUE 10 523#define SNMP_NOCREATION 11 524#define SNMP_INCONSISTENTVALUE 12 525#define SNMP_RESOURCEUNAVAILABLE 13 526#define SNMP_COMMITFAILED 14 527#define SNMP_UNDOFAILED 15 528#define SNMP_AUTHORIZATIONERROR 16 529#define SNMP_NOTWRITABLE 17 530#define SNMP_INCONSISTENTNAME 18 531 532/* General SNMP V1 Traps */ 533#define SNMP_TRAP_COLDSTART 0 534#define SNMP_TRAP_WARMSTART 1 535#define SNMP_TRAP_LINKDOWN 2 536#define SNMP_TRAP_LINKUP 3 537#define SNMP_TRAP_AUTFAILURE 4 538#define SNMP_TRAP_EQPNEIGHBORLOSS 5 539#define SNMP_TRAP_ENTSPECIFIC 6 540 541/* SNMPv1 Types */ 542#define SNMP_NULL 0 543#define SNMP_INTEGER 1 /* l */ 544#define SNMP_OCTETSTR 2 /* c */ 545#define SNMP_DISPLAYSTR 2 /* c */ 546#define SNMP_OBJECTID 3 /* ul */ 547#define SNMP_IPADDR 4 /* uc */ 548#define SNMP_COUNTER 5 /* ul */ 549#define SNMP_GAUGE 6 /* ul */ 550#define SNMP_TIMETICKS 7 /* ul */ 551#define SNMP_OPAQUE 8 /* c */ 552 553/* Additional SNMPv2 Types */ 554#define SNMP_UINTEGER 5 /* ul */ 555#define SNMP_BITSTR 9 /* uc */ 556#define SNMP_NSAP 10 /* uc */ 557#define SNMP_COUNTER64 11 /* ul */ 558#define SNMP_NOSUCHOBJECT 12 559#define SNMP_NOSUCHINSTANCE 13 560#define SNMP_ENDOFMIBVIEW 14 561 562union snmp_syntax 563{ 564 unsigned char uc[0]; /* 8 bit unsigned */ 565 char c[0]; /* 8 bit signed */ 566 unsigned long ul[0]; /* 32 bit unsigned */ 567 long l[0]; /* 32 bit signed */ 568}; 569 570struct snmp_object 571{ 572 unsigned long *id; 573 unsigned int id_len; 574 unsigned short type; 575 unsigned int syntax_len; 576 union snmp_syntax syntax; 577}; 578 579struct snmp_request 580{ 581 unsigned long id; 582 unsigned int error_status; 583 unsigned int error_index; 584}; 585 586struct snmp_v1_trap 587{ 588 unsigned long *id; 589 unsigned int id_len; 590 unsigned long ip_address; /* pointer */ 591 unsigned int general; 592 unsigned int specific; 593 unsigned long time; 594}; 595 596/* SNMP types */ 597#define SNMP_IPA 0 598#define SNMP_CNT 1 599#define SNMP_GGE 2 600#define SNMP_TIT 3 601#define SNMP_OPQ 4 602#define SNMP_C64 6 603 604/* SNMP errors */ 605#define SERR_NSO 0 606#define SERR_NSI 1 607#define SERR_EOM 2 608 609static inline void mangle_address(unsigned char *begin, 610 unsigned char *addr, 611 const struct oct1_map *map, 612 __sum16 *check); 613struct snmp_cnv 614{ 615 unsigned int class; 616 unsigned int tag; 617 int syntax; 618}; 619 620static struct snmp_cnv snmp_conv [] = 621{ 622 {ASN1_UNI, ASN1_NUL, SNMP_NULL}, 623 {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, 624 {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, 625 {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR}, 626 {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID}, 627 {ASN1_APL, SNMP_IPA, SNMP_IPADDR}, 628 {ASN1_APL, SNMP_CNT, SNMP_COUNTER}, /* Counter32 */ 629 {ASN1_APL, SNMP_GGE, SNMP_GAUGE}, /* Gauge32 == Unsigned32 */ 630 {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS}, 631 {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE}, 632 633 /* SNMPv2 data types and errors */ 634 {ASN1_UNI, ASN1_BTS, SNMP_BITSTR}, 635 {ASN1_APL, SNMP_C64, SNMP_COUNTER64}, 636 {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT}, 637 {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE}, 638 {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW}, 639 {0, 0, -1} 640}; 641 642static unsigned char snmp_tag_cls2syntax(unsigned int tag, 643 unsigned int cls, 644 unsigned short *syntax) 645{ 646 struct snmp_cnv *cnv; 647 648 cnv = snmp_conv; 649 650 while (cnv->syntax != -1) { 651 if (cnv->tag == tag && cnv->class == cls) { 652 *syntax = cnv->syntax; 653 return 1; 654 } 655 cnv++; 656 } 657 return 0; 658} 659 660static unsigned char snmp_object_decode(struct asn1_ctx *ctx, 661 struct snmp_object **obj) 662{ 663 unsigned int cls, con, tag, len, idlen; 664 unsigned short type; 665 unsigned char *eoc, *end, *p; 666 unsigned long *lp, *id; 667 unsigned long ul; 668 long l; 669 670 *obj = NULL; 671 id = NULL; 672 673 if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag)) 674 return 0; 675 676 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) 677 return 0; 678 679 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 680 return 0; 681 682 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) 683 return 0; 684 685 if (!asn1_oid_decode(ctx, end, &id, &idlen)) 686 return 0; 687 688 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) { 689 kfree(id); 690 return 0; 691 } 692 693 if (con != ASN1_PRI) { 694 kfree(id); 695 return 0; 696 } 697 698 type = 0; 699 if (!snmp_tag_cls2syntax(tag, cls, &type)) { 700 kfree(id); 701 return 0; 702 } 703 704 l = 0; 705 switch (type) { 706 case SNMP_INTEGER: 707 len = sizeof(long); 708 if (!asn1_long_decode(ctx, end, &l)) { 709 kfree(id); 710 return 0; 711 } 712 *obj = kmalloc(sizeof(struct snmp_object) + len, 713 GFP_ATOMIC); 714 if (*obj == NULL) { 715 kfree(id); 716 if (net_ratelimit()) 717 printk("OOM in bsalg (%d)\n", __LINE__); 718 return 0; 719 } 720 (*obj)->syntax.l[0] = l; 721 break; 722 case SNMP_OCTETSTR: 723 case SNMP_OPAQUE: 724 if (!asn1_octets_decode(ctx, end, &p, &len)) { 725 kfree(id); 726 return 0; 727 } 728 *obj = kmalloc(sizeof(struct snmp_object) + len, 729 GFP_ATOMIC); 730 if (*obj == NULL) { 731 kfree(id); 732 if (net_ratelimit()) 733 printk("OOM in bsalg (%d)\n", __LINE__); 734 return 0; 735 } 736 memcpy((*obj)->syntax.c, p, len); 737 kfree(p); 738 break; 739 case SNMP_NULL: 740 case SNMP_NOSUCHOBJECT: 741 case SNMP_NOSUCHINSTANCE: 742 case SNMP_ENDOFMIBVIEW: 743 len = 0; 744 *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC); 745 if (*obj == NULL) { 746 kfree(id); 747 if (net_ratelimit()) 748 printk("OOM in bsalg (%d)\n", __LINE__); 749 return 0; 750 } 751 if (!asn1_null_decode(ctx, end)) { 752 kfree(id); 753 kfree(*obj); 754 *obj = NULL; 755 return 0; 756 } 757 break; 758 case SNMP_OBJECTID: 759 if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) { 760 kfree(id); 761 return 0; 762 } 763 len *= sizeof(unsigned long); 764 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); 765 if (*obj == NULL) { 766 kfree(lp); 767 kfree(id); 768 if (net_ratelimit()) 769 printk("OOM in bsalg (%d)\n", __LINE__); 770 return 0; 771 } 772 memcpy((*obj)->syntax.ul, lp, len); 773 kfree(lp); 774 break; 775 case SNMP_IPADDR: 776 if (!asn1_octets_decode(ctx, end, &p, &len)) { 777 kfree(id); 778 return 0; 779 } 780 if (len != 4) { 781 kfree(p); 782 kfree(id); 783 return 0; 784 } 785 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); 786 if (*obj == NULL) { 787 kfree(p); 788 kfree(id); 789 if (net_ratelimit()) 790 printk("OOM in bsalg (%d)\n", __LINE__); 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 if (net_ratelimit()) 808 printk("OOM in bsalg (%d)\n", __LINE__); 809 return 0; 810 } 811 (*obj)->syntax.ul[0] = ul; 812 break; 813 default: 814 kfree(id); 815 return 0; 816 } 817 818 (*obj)->syntax_len = len; 819 (*obj)->type = type; 820 (*obj)->id = id; 821 (*obj)->id_len = idlen; 822 823 if (!asn1_eoc_decode(ctx, eoc)) { 824 kfree(id); 825 kfree(*obj); 826 *obj = NULL; 827 return 0; 828 } 829 return 1; 830} 831 832static unsigned char snmp_request_decode(struct asn1_ctx *ctx, 833 struct snmp_request *request) 834{ 835 unsigned int cls, con, tag; 836 unsigned char *end; 837 838 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 839 return 0; 840 841 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 842 return 0; 843 844 if (!asn1_ulong_decode(ctx, end, &request->id)) 845 return 0; 846 847 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 848 return 0; 849 850 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 851 return 0; 852 853 if (!asn1_uint_decode(ctx, end, &request->error_status)) 854 return 0; 855 856 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 857 return 0; 858 859 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 860 return 0; 861 862 if (!asn1_uint_decode(ctx, end, &request->error_index)) 863 return 0; 864 865 return 1; 866} 867 868/* 869 * Fast checksum update for possibly oddly-aligned UDP byte, from the 870 * code example in the draft. 871 */ 872static void fast_csum(__sum16 *csum, 873 const unsigned char *optr, 874 const unsigned char *nptr, 875 int offset) 876{ 877 unsigned char s[4]; 878 879 if (offset & 1) { 880 s[0] = s[2] = 0; 881 s[1] = ~*optr; 882 s[3] = *nptr; 883 } else { 884 s[1] = s[3] = 0; 885 s[0] = ~*optr; 886 s[2] = *nptr; 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, (unsigned char *)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 %u.%u.%u.%u to " 919 "%u.%u.%u.%u\n", NIPQUAD(old), NIPQUAD(*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(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 printk(KERN_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 printk(KERN_DEBUG "bsalg: community: "); 1068 for (i = 0; i < comm.len; i++) 1069 printk("%c", comm.data[i]); 1070 printk("\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 unsigned char *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 printk(KERN_DEBUG "bsalg: bad pdu type %u\n", pdutype); 1095 else 1096 printk(KERN_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 printk(KERN_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 obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC); 1137 if (obj == NULL) { 1138 if (net_ratelimit()) 1139 printk(KERN_WARNING "OOM in bsalg(%d)\n", __LINE__); 1140 return 0; 1141 } 1142 1143 while (!asn1_eoc_decode(&ctx, eoc)) { 1144 unsigned int i; 1145 1146 if (!snmp_object_decode(&ctx, obj)) { 1147 if (*obj) { 1148 kfree((*obj)->id); 1149 kfree(*obj); 1150 } 1151 kfree(obj); 1152 return 0; 1153 } 1154 1155 if (debug > 1) { 1156 printk(KERN_DEBUG "bsalg: object: "); 1157 for (i = 0; i < (*obj)->id_len; i++) { 1158 if (i > 0) 1159 printk("."); 1160 printk("%lu", (*obj)->id[i]); 1161 } 1162 printk(": type=%u\n", (*obj)->type); 1163 1164 } 1165 1166 if ((*obj)->type == SNMP_IPADDR) 1167 mangle_address(ctx.begin, ctx.pointer - 4 , map, check); 1168 1169 kfree((*obj)->id); 1170 kfree(*obj); 1171 } 1172 kfree(obj); 1173 1174 if (!asn1_eoc_decode(&ctx, eoc)) 1175 return 0; 1176 1177 return 1; 1178} 1179 1180/***************************************************************************** 1181 * 1182 * NAT routines. 1183 * 1184 *****************************************************************************/ 1185 1186/* 1187 * SNMP translation routine. 1188 */ 1189static int snmp_translate(struct nf_conn *ct, 1190 enum ip_conntrack_info ctinfo, 1191 struct sk_buff **pskb) 1192{ 1193 struct iphdr *iph = ip_hdr(*pskb); 1194 struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl); 1195 u_int16_t udplen = ntohs(udph->len); 1196 u_int16_t paylen = udplen - sizeof(struct udphdr); 1197 int dir = CTINFO2DIR(ctinfo); 1198 struct oct1_map map; 1199 1200 /* 1201 * Determine mappping for application layer addresses based 1202 * on NAT manipulations for the packet. 1203 */ 1204 if (dir == IP_CT_DIR_ORIGINAL) { 1205 /* SNAT traps */ 1206 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip); 1207 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); 1208 } else { 1209 /* DNAT replies */ 1210 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip); 1211 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); 1212 } 1213 1214 if (map.from == map.to) 1215 return NF_ACCEPT; 1216 1217 if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr), 1218 paylen, &map, &udph->check)) { 1219 if (net_ratelimit()) 1220 printk(KERN_WARNING "bsalg: parser failed\n"); 1221 return NF_DROP; 1222 } 1223 return NF_ACCEPT; 1224} 1225 1226/* We don't actually set up expectations, just adjust internal IP 1227 * addresses if this is being NATted */ 1228static int help(struct sk_buff **pskb, unsigned int protoff, 1229 struct nf_conn *ct, 1230 enum ip_conntrack_info ctinfo) 1231{ 1232 int dir = CTINFO2DIR(ctinfo); 1233 unsigned int ret; 1234 struct iphdr *iph = ip_hdr(*pskb); 1235 struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); 1236 1237 /* SNMP replies and originating SNMP traps get mangled */ 1238 if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) 1239 return NF_ACCEPT; 1240 if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) 1241 return NF_ACCEPT; 1242 1243 /* No NAT? */ 1244 if (!(ct->status & IPS_NAT_MASK)) 1245 return NF_ACCEPT; 1246 1247 /* 1248 * Make sure the packet length is ok. So far, we were only guaranteed 1249 * to have a valid length IP header plus 8 bytes, which means we have 1250 * enough room for a UDP header. Just verify the UDP length field so we 1251 * can mess around with the payload. 1252 */ 1253 if (ntohs(udph->len) != (*pskb)->len - (iph->ihl << 2)) { 1254 if (net_ratelimit()) 1255 printk(KERN_WARNING "SNMP: dropping malformed packet " 1256 "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n", 1257 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); 1258 return NF_DROP; 1259 } 1260 1261 if (!skb_make_writable(pskb, (*pskb)->len)) 1262 return NF_DROP; 1263 1264 spin_lock_bh(&snmp_lock); 1265 ret = snmp_translate(ct, ctinfo, pskb); 1266 spin_unlock_bh(&snmp_lock); 1267 return ret; 1268} 1269 1270static struct nf_conntrack_helper snmp_helper __read_mostly = { 1271 .max_expected = 0, 1272 .timeout = 180, 1273 .me = THIS_MODULE, 1274 .help = help, 1275 .name = "snmp", 1276 .tuple.src.l3num = AF_INET, 1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), 1278 .tuple.dst.protonum = IPPROTO_UDP, 1279 .mask.src.l3num = 0xFFFF, 1280 .mask.src.u.udp.port = __constant_htons(0xFFFF), 1281 .mask.dst.protonum = 0xFF, 1282}; 1283 1284static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { 1285 .max_expected = 0, 1286 .timeout = 180, 1287 .me = THIS_MODULE, 1288 .help = help, 1289 .name = "snmp_trap", 1290 .tuple.src.l3num = AF_INET, 1291 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT), 1292 .tuple.dst.protonum = IPPROTO_UDP, 1293 .mask.src.l3num = 0xFFFF, 1294 .mask.src.u.udp.port = __constant_htons(0xFFFF), 1295 .mask.dst.protonum = 0xFF, 1296}; 1297 1298/***************************************************************************** 1299 * 1300 * Module stuff. 1301 * 1302 *****************************************************************************/ 1303 1304static int __init nf_nat_snmp_basic_init(void) 1305{ 1306 int ret = 0; 1307 1308 ret = nf_conntrack_helper_register(&snmp_helper); 1309 if (ret < 0) 1310 return ret; 1311 ret = nf_conntrack_helper_register(&snmp_trap_helper); 1312 if (ret < 0) { 1313 nf_conntrack_helper_unregister(&snmp_helper); 1314 return ret; 1315 } 1316 return ret; 1317} 1318 1319static void __exit nf_nat_snmp_basic_fini(void) 1320{ 1321 nf_conntrack_helper_unregister(&snmp_helper); 1322 nf_conntrack_helper_unregister(&snmp_trap_helper); 1323} 1324 1325module_init(nf_nat_snmp_basic_init); 1326module_exit(nf_nat_snmp_basic_fini); 1327 1328module_param(debug, int, 0600); 1329