1/* 2 * ip_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 * Updates: 43 * 2000-08-06: Convert to new helper API (Harald Welte). 44 * 45 */ 46#include <linux/config.h> 47#include <linux/module.h> 48#include <linux/types.h> 49#include <linux/kernel.h> 50#include <linux/netfilter_ipv4.h> 51#include <linux/netfilter_ipv4/ip_nat.h> 52#include <linux/netfilter_ipv4/ip_nat_helper.h> 53#include <linux/brlock.h> 54#include <linux/types.h> 55#include <linux/ip.h> 56#include <net/udp.h> 57#include <asm/uaccess.h> 58#include <asm/checksum.h> 59 60 61 62#define SNMP_PORT 161 63#define SNMP_TRAP_PORT 162 64#define NOCT1(n) (u_int8_t )((n) & 0xff) 65 66static int debug = 0; 67static spinlock_t snmp_lock = SPIN_LOCK_UNLOCKED; 68 69/* 70 * Application layer address mapping mimics the NAT mapping, but 71 * only for the first octet in this case (a more flexible system 72 * can be implemented if needed). 73 */ 74struct oct1_map 75{ 76 u_int8_t from; 77 u_int8_t to; 78}; 79 80 81/***************************************************************************** 82 * 83 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse) 84 * 85 *****************************************************************************/ 86 87/* Class */ 88#define ASN1_UNI 0 /* Universal */ 89#define ASN1_APL 1 /* Application */ 90#define ASN1_CTX 2 /* Context */ 91#define ASN1_PRV 3 /* Private */ 92 93/* Tag */ 94#define ASN1_EOC 0 /* End Of Contents */ 95#define ASN1_BOL 1 /* Boolean */ 96#define ASN1_INT 2 /* Integer */ 97#define ASN1_BTS 3 /* Bit String */ 98#define ASN1_OTS 4 /* Octet String */ 99#define ASN1_NUL 5 /* Null */ 100#define ASN1_OJI 6 /* Object Identifier */ 101#define ASN1_OJD 7 /* Object Description */ 102#define ASN1_EXT 8 /* External */ 103#define ASN1_SEQ 16 /* Sequence */ 104#define ASN1_SET 17 /* Set */ 105#define ASN1_NUMSTR 18 /* Numerical String */ 106#define ASN1_PRNSTR 19 /* Printable String */ 107#define ASN1_TEXSTR 20 /* Teletext String */ 108#define ASN1_VIDSTR 21 /* Video String */ 109#define ASN1_IA5STR 22 /* IA5 String */ 110#define ASN1_UNITIM 23 /* Universal Time */ 111#define ASN1_GENTIM 24 /* General Time */ 112#define ASN1_GRASTR 25 /* Graphical String */ 113#define ASN1_VISSTR 26 /* Visible String */ 114#define ASN1_GENSTR 27 /* General String */ 115 116/* Primitive / Constructed methods*/ 117#define ASN1_PRI 0 /* Primitive */ 118#define ASN1_CON 1 /* Constructed */ 119 120/* 121 * Error codes. 122 */ 123#define ASN1_ERR_NOERROR 0 124#define ASN1_ERR_DEC_EMPTY 2 125#define ASN1_ERR_DEC_EOC_MISMATCH 3 126#define ASN1_ERR_DEC_LENGTH_MISMATCH 4 127#define ASN1_ERR_DEC_BADVALUE 5 128 129/* 130 * ASN.1 context. 131 */ 132struct asn1_ctx 133{ 134 int error; /* Error condition */ 135 unsigned char *pointer; /* Octet just to be decoded */ 136 unsigned char *begin; /* First octet */ 137 unsigned char *end; /* Octet after last octet */ 138}; 139 140/* 141 * Octet string (not null terminated) 142 */ 143struct asn1_octstr 144{ 145 unsigned char *data; 146 unsigned int len; 147}; 148 149static void asn1_open(struct asn1_ctx *ctx, 150 unsigned char *buf, 151 unsigned int len) 152{ 153 ctx->begin = buf; 154 ctx->end = buf + len; 155 ctx->pointer = buf; 156 ctx->error = ASN1_ERR_NOERROR; 157} 158 159static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) 160{ 161 if (ctx->pointer >= ctx->end) { 162 ctx->error = ASN1_ERR_DEC_EMPTY; 163 return 0; 164 } 165 *ch = *(ctx->pointer)++; 166 return 1; 167} 168 169static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) 170{ 171 unsigned char ch; 172 173 *tag = 0; 174 175 do 176 { 177 if (!asn1_octet_decode(ctx, &ch)) 178 return 0; 179 *tag <<= 7; 180 *tag |= ch & 0x7F; 181 } while ((ch & 0x80) == 0x80); 182 return 1; 183} 184 185static unsigned char asn1_id_decode(struct asn1_ctx *ctx, 186 unsigned int *cls, 187 unsigned int *con, 188 unsigned int *tag) 189{ 190 unsigned char ch; 191 192 if (!asn1_octet_decode(ctx, &ch)) 193 return 0; 194 195 *cls = (ch & 0xC0) >> 6; 196 *con = (ch & 0x20) >> 5; 197 *tag = (ch & 0x1F); 198 199 if (*tag == 0x1F) { 200 if (!asn1_tag_decode(ctx, tag)) 201 return 0; 202 } 203 return 1; 204} 205 206static unsigned char asn1_length_decode(struct asn1_ctx *ctx, 207 unsigned int *def, 208 unsigned int *len) 209{ 210 unsigned char ch, cnt; 211 212 if (!asn1_octet_decode(ctx, &ch)) 213 return 0; 214 215 if (ch == 0x80) 216 *def = 0; 217 else { 218 *def = 1; 219 220 if (ch < 0x80) 221 *len = ch; 222 else { 223 cnt = (unsigned char) (ch & 0x7F); 224 *len = 0; 225 226 while (cnt > 0) { 227 if (!asn1_octet_decode(ctx, &ch)) 228 return 0; 229 *len <<= 8; 230 *len |= ch; 231 cnt--; 232 } 233 } 234 } 235 return 1; 236} 237 238static unsigned char asn1_header_decode(struct asn1_ctx *ctx, 239 unsigned char **eoc, 240 unsigned int *cls, 241 unsigned int *con, 242 unsigned int *tag) 243{ 244 unsigned int def, len; 245 246 if (!asn1_id_decode(ctx, cls, con, tag)) 247 return 0; 248 249 if (!asn1_length_decode(ctx, &def, &len)) 250 return 0; 251 252 if (def) 253 *eoc = ctx->pointer + len; 254 else 255 *eoc = 0; 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 void inline mangle_address(unsigned char *begin, 610 unsigned char *addr, 611 const struct oct1_map *map, 612 u_int16_t *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 if (!snmp_tag_cls2syntax(tag, cls, &type)) { 699 kfree(id); 700 return 0; 701 } 702 703 switch (type) { 704 case SNMP_INTEGER: 705 len = sizeof(long); 706 if (!asn1_long_decode(ctx, end, &l)) { 707 kfree(id); 708 return 0; 709 } 710 *obj = kmalloc(sizeof(struct snmp_object) + len, 711 GFP_ATOMIC); 712 if (*obj == NULL) { 713 kfree(id); 714 if (net_ratelimit()) 715 printk("OOM in bsalg (%d)\n", __LINE__); 716 return 0; 717 } 718 (*obj)->syntax.l[0] = l; 719 break; 720 case SNMP_OCTETSTR: 721 case SNMP_OPAQUE: 722 if (!asn1_octets_decode(ctx, end, &p, &len)) { 723 kfree(id); 724 return 0; 725 } 726 *obj = kmalloc(sizeof(struct snmp_object) + len, 727 GFP_ATOMIC); 728 if (*obj == NULL) { 729 kfree(id); 730 if (net_ratelimit()) 731 printk("OOM in bsalg (%d)\n", __LINE__); 732 return 0; 733 } 734 memcpy((*obj)->syntax.c, p, len); 735 kfree(p); 736 break; 737 case SNMP_NULL: 738 case SNMP_NOSUCHOBJECT: 739 case SNMP_NOSUCHINSTANCE: 740 case SNMP_ENDOFMIBVIEW: 741 len = 0; 742 *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC); 743 if (*obj == NULL) { 744 kfree(id); 745 if (net_ratelimit()) 746 printk("OOM in bsalg (%d)\n", __LINE__); 747 return 0; 748 } 749 if (!asn1_null_decode(ctx, end)) { 750 kfree(id); 751 kfree(*obj); 752 *obj = NULL; 753 return 0; 754 } 755 break; 756 case SNMP_OBJECTID: 757 if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) { 758 kfree(id); 759 return 0; 760 } 761 len *= sizeof(unsigned long); 762 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); 763 if (*obj == NULL) { 764 kfree(id); 765 if (net_ratelimit()) 766 printk("OOM in bsalg (%d)\n", __LINE__); 767 return 0; 768 } 769 memcpy((*obj)->syntax.ul, lp, len); 770 kfree(lp); 771 break; 772 case SNMP_IPADDR: 773 if (!asn1_octets_decode(ctx, end, &p, &len)) { 774 kfree(id); 775 return 0; 776 } 777 if (len != 4) { 778 kfree(p); 779 kfree(id); 780 return 0; 781 } 782 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); 783 if (*obj == NULL) { 784 kfree(p); 785 kfree(id); 786 if (net_ratelimit()) 787 printk("OOM in bsalg (%d)\n", __LINE__); 788 return 0; 789 } 790 memcpy((*obj)->syntax.uc, p, len); 791 kfree(p); 792 break; 793 case SNMP_COUNTER: 794 case SNMP_GAUGE: 795 case SNMP_TIMETICKS: 796 len = sizeof(unsigned long); 797 if (!asn1_ulong_decode(ctx, end, &ul)) { 798 kfree(id); 799 return 0; 800 } 801 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); 802 if (*obj == NULL) { 803 kfree(id); 804 if (net_ratelimit()) 805 printk("OOM in bsalg (%d)\n", __LINE__); 806 return 0; 807 } 808 (*obj)->syntax.ul[0] = ul; 809 break; 810 default: 811 kfree(id); 812 return 0; 813 } 814 815 (*obj)->syntax_len = len; 816 (*obj)->type = type; 817 (*obj)->id = id; 818 (*obj)->id_len = idlen; 819 820 if (!asn1_eoc_decode(ctx, eoc)) { 821 kfree(id); 822 kfree(*obj); 823 *obj = NULL; 824 return 0; 825 } 826 return 1; 827} 828 829static unsigned char snmp_request_decode(struct asn1_ctx *ctx, 830 struct snmp_request *request) 831{ 832 unsigned int cls, con, tag; 833 unsigned char *end; 834 835 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 836 return 0; 837 838 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 839 return 0; 840 841 if (!asn1_ulong_decode(ctx, end, &request->id)) 842 return 0; 843 844 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 845 return 0; 846 847 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 848 return 0; 849 850 if (!asn1_uint_decode(ctx, end, &request->error_status)) 851 return 0; 852 853 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 854 return 0; 855 856 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 857 return 0; 858 859 if (!asn1_uint_decode(ctx, end, &request->error_index)) 860 return 0; 861 862 return 1; 863} 864 865static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, 866 struct snmp_v1_trap *trap, 867 const struct oct1_map *map, 868 u_int16_t *check) 869{ 870 unsigned int cls, con, tag, len; 871 unsigned char *end; 872 873 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 874 return 0; 875 876 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) 877 return 0; 878 879 if (!asn1_oid_decode(ctx, end, &trap->id, &trap->id_len)) 880 return 0; 881 882 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 883 goto err_id_free; 884 885 if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_IPA) || 886 (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS))) 887 goto err_id_free; 888 889 if (!asn1_octets_decode(ctx, end, (unsigned char **)&trap->ip_address, &len)) 890 goto err_id_free; 891 892 /* IPv4 only */ 893 if (len != 4) 894 goto err_addr_free; 895 896 mangle_address(ctx->begin, ctx->pointer - 4, map, check); 897 898 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 899 goto err_addr_free; 900 901 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 902 goto err_addr_free;; 903 904 if (!asn1_uint_decode(ctx, end, &trap->general)) 905 goto err_addr_free;; 906 907 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 908 goto err_addr_free; 909 910 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 911 goto err_addr_free; 912 913 if (!asn1_uint_decode(ctx, end, &trap->specific)) 914 goto err_addr_free; 915 916 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) 917 goto err_addr_free; 918 919 if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) || 920 (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT))) 921 goto err_addr_free; 922 923 if (!asn1_ulong_decode(ctx, end, &trap->time)) 924 goto err_addr_free; 925 926 return 1; 927 928err_id_free: 929 kfree(trap->id); 930 931err_addr_free: 932 kfree((unsigned long *)trap->ip_address); 933 934 return 0; 935} 936 937/***************************************************************************** 938 * 939 * Misc. routines 940 * 941 *****************************************************************************/ 942 943static void hex_dump(unsigned char *buf, size_t len) 944{ 945 size_t i; 946 947 for (i = 0; i < len; i++) { 948 if (i && !(i % 16)) 949 printk("\n"); 950 printk("%02x ", *(buf + i)); 951 } 952 printk("\n"); 953} 954 955/* 956 * Fast checksum update for possibly oddly-aligned UDP byte, from the 957 * code example in the draft. 958 */ 959static void fast_csum(unsigned char *csum, 960 const unsigned char *optr, 961 const unsigned char *nptr, 962 int odd) 963{ 964 long x, old, new; 965 966 x = csum[0] * 256 + csum[1]; 967 968 x =~ x & 0xFFFF; 969 970 if (odd) old = optr[0] * 256; 971 else old = optr[0]; 972 973 x -= old & 0xFFFF; 974 if (x <= 0) { 975 x--; 976 x &= 0xFFFF; 977 } 978 979 if (odd) new = nptr[0] * 256; 980 else new = nptr[0]; 981 982 x += new & 0xFFFF; 983 if (x & 0x10000) { 984 x++; 985 x &= 0xFFFF; 986 } 987 988 x =~ x & 0xFFFF; 989 csum[0] = x / 256; 990 csum[1] = x & 0xFF; 991} 992 993/* 994 * Mangle IP address. 995 * - begin points to the start of the snmp messgae 996 * - addr points to the start of the address 997 */ 998static void inline mangle_address(unsigned char *begin, 999 unsigned char *addr, 1000 const struct oct1_map *map, 1001 u_int16_t *check) 1002{ 1003 if (map->from == NOCT1(*addr)) { 1004 u_int32_t old; 1005 1006 if (debug) 1007 memcpy(&old, (unsigned char *)addr, sizeof(old)); 1008 1009 *addr = map->to; 1010 1011 /* Update UDP checksum if being used */ 1012 if (*check) { 1013 unsigned char odd = !((addr - begin) % 2); 1014 1015 fast_csum((unsigned char *)check, 1016 &map->from, &map->to, odd); 1017 1018 } 1019 1020 if (debug) 1021 printk(KERN_DEBUG "bsalg: mapped %u.%u.%u.%u to " 1022 "%u.%u.%u.%u\n", NIPQUAD(old), NIPQUAD(*addr)); 1023 } 1024} 1025 1026/* 1027 * Parse and mangle SNMP message according to mapping. 1028 * (And this is the fucking 'basic' method). 1029 */ 1030static int snmp_parse_mangle(unsigned char *msg, 1031 u_int16_t len, 1032 const struct oct1_map *map, 1033 u_int16_t *check) 1034{ 1035 unsigned char *eoc, *end; 1036 unsigned int cls, con, tag, vers, pdutype; 1037 struct asn1_ctx ctx; 1038 struct asn1_octstr comm; 1039 struct snmp_object **obj; 1040 1041 if (debug > 1) 1042 hex_dump(msg, len); 1043 1044 asn1_open(&ctx, msg, len); 1045 1046 /* 1047 * Start of SNMP message. 1048 */ 1049 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag)) 1050 return 0; 1051 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) 1052 return 0; 1053 1054 /* 1055 * Version 1 or 2 handled. 1056 */ 1057 if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag)) 1058 return 0; 1059 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) 1060 return 0; 1061 if (!asn1_uint_decode (&ctx, end, &vers)) 1062 return 0; 1063 if (debug > 1) 1064 printk(KERN_DEBUG "bsalg: snmp version: %u\n", vers + 1); 1065 if (vers > 1) 1066 return 1; 1067 1068 /* 1069 * Community. 1070 */ 1071 if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag)) 1072 return 0; 1073 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS) 1074 return 0; 1075 if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len)) 1076 return 0; 1077 if (debug > 1) { 1078 unsigned int i; 1079 1080 printk(KERN_DEBUG "bsalg: community: "); 1081 for (i = 0; i < comm.len; i++) 1082 printk("%c", comm.data[i]); 1083 printk("\n"); 1084 } 1085 kfree(comm.data); 1086 1087 /* 1088 * PDU type 1089 */ 1090 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype)) 1091 return 0; 1092 if (cls != ASN1_CTX || con != ASN1_CON) 1093 return 0; 1094 if (debug > 1) { 1095 unsigned char *pdus[] = { 1096 [SNMP_PDU_GET] = "get", 1097 [SNMP_PDU_NEXT] = "get-next", 1098 [SNMP_PDU_RESPONSE] = "response", 1099 [SNMP_PDU_SET] = "set", 1100 [SNMP_PDU_TRAP1] = "trapv1", 1101 [SNMP_PDU_BULK] = "bulk", 1102 [SNMP_PDU_INFORM] = "inform", 1103 [SNMP_PDU_TRAP2] = "trapv2" 1104 }; 1105 1106 if (pdutype > SNMP_PDU_TRAP2) 1107 printk(KERN_DEBUG "bsalg: bad pdu type %u\n", pdutype); 1108 else 1109 printk(KERN_DEBUG "bsalg: pdu: %s\n", pdus[pdutype]); 1110 } 1111 if (pdutype != SNMP_PDU_RESPONSE && 1112 pdutype != SNMP_PDU_TRAP1 && pdutype != SNMP_PDU_TRAP2) 1113 return 1; 1114 1115 /* 1116 * Request header or v1 trap 1117 */ 1118 if (pdutype == SNMP_PDU_TRAP1) { 1119 struct snmp_v1_trap trap; 1120 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check); 1121 1122 /* Discard trap allocations regardless */ 1123 kfree(trap.id); 1124 kfree((unsigned long *)trap.ip_address); 1125 1126 if (!ret) 1127 return ret; 1128 1129 } else { 1130 struct snmp_request req; 1131 1132 if (!snmp_request_decode(&ctx, &req)) 1133 return 0; 1134 1135 if (debug > 1) 1136 printk(KERN_DEBUG "bsalg: request: id=0x%lx error_status=%u " 1137 "error_index=%u\n", req.id, req.error_status, 1138 req.error_index); 1139 } 1140 1141 /* 1142 * Loop through objects, look for IP addresses to mangle. 1143 */ 1144 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag)) 1145 return 0; 1146 1147 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) 1148 return 0; 1149 1150 obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC); 1151 if (obj == NULL) { 1152 if (net_ratelimit()) 1153 printk(KERN_WARNING "OOM in bsalg(%d)\n", __LINE__); 1154 return 0; 1155 } 1156 1157 while (!asn1_eoc_decode(&ctx, eoc)) { 1158 unsigned int i; 1159 1160 if (!snmp_object_decode(&ctx, obj)) { 1161 if (*obj) { 1162 if ((*obj)->id) 1163 kfree((*obj)->id); 1164 kfree(*obj); 1165 } 1166 kfree(obj); 1167 return 0; 1168 } 1169 1170 if (debug > 1) { 1171 printk(KERN_DEBUG "bsalg: object: "); 1172 for (i = 0; i < (*obj)->id_len; i++) { 1173 if (i > 0) 1174 printk("."); 1175 printk("%lu", (*obj)->id[i]); 1176 } 1177 printk(": type=%u\n", (*obj)->type); 1178 1179 } 1180 1181 if ((*obj)->type == SNMP_IPADDR) 1182 mangle_address(ctx.begin, ctx.pointer - 4 , map, check); 1183 1184 kfree((*obj)->id); 1185 kfree(*obj); 1186 } 1187 kfree(obj); 1188 1189 if (!asn1_eoc_decode(&ctx, eoc)) 1190 return 0; 1191 1192 return 1; 1193} 1194 1195/***************************************************************************** 1196 * 1197 * NAT routines. 1198 * 1199 *****************************************************************************/ 1200 1201/* 1202 * SNMP translation routine. 1203 */ 1204static int snmp_translate(struct ip_conntrack *ct, 1205 struct ip_nat_info *info, 1206 enum ip_conntrack_info ctinfo, 1207 unsigned int hooknum, 1208 struct sk_buff **pskb) 1209{ 1210 struct iphdr *iph = (*pskb)->nh.iph; 1211 struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); 1212 u_int16_t udplen = ntohs(udph->len); 1213 u_int16_t paylen = udplen - sizeof(struct udphdr); 1214 int dir = CTINFO2DIR(ctinfo); 1215 struct oct1_map map; 1216 1217 /* 1218 * Determine mappping for application layer addresses based 1219 * on NAT manipulations for the packet. 1220 */ 1221 if (dir == IP_CT_DIR_ORIGINAL) { 1222 /* SNAT traps */ 1223 map.from = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); 1224 map.to = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); 1225 } else { 1226 /* DNAT replies */ 1227 map.from = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); 1228 map.to = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); 1229 } 1230 1231 if (map.from == map.to) 1232 return NF_ACCEPT; 1233 1234 if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr), 1235 paylen, &map, &udph->check)) { 1236 printk(KERN_WARNING "bsalg: parser failed\n"); 1237 return NF_DROP; 1238 } 1239 return NF_ACCEPT; 1240} 1241 1242/* 1243 * NAT helper function, packets arrive here from NAT code. 1244 */ 1245static unsigned int nat_help(struct ip_conntrack *ct, 1246 struct ip_conntrack_expect *exp, 1247 struct ip_nat_info *info, 1248 enum ip_conntrack_info ctinfo, 1249 unsigned int hooknum, 1250 struct sk_buff **pskb) 1251{ 1252 int dir = CTINFO2DIR(ctinfo); 1253 struct iphdr *iph = (*pskb)->nh.iph; 1254 struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); 1255 1256 spin_lock_bh(&snmp_lock); 1257 1258 /* 1259 * Translate snmp replies on pre-routing (DNAT) and snmp traps 1260 * on post routing (SNAT). 1261 */ 1262 if (!((dir == IP_CT_DIR_REPLY && hooknum == NF_IP_PRE_ROUTING && 1263 udph->source == ntohs(SNMP_PORT)) || 1264 (dir == IP_CT_DIR_ORIGINAL && hooknum == NF_IP_POST_ROUTING && 1265 udph->dest == ntohs(SNMP_TRAP_PORT)))) { 1266 spin_unlock_bh(&snmp_lock); 1267 return NF_ACCEPT; 1268 } 1269 1270 if (debug > 1) { 1271 printk(KERN_DEBUG "bsalg: dir=%s hook=%d manip=%s len=%d " 1272 "src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u " 1273 "osrc=%u.%u.%u.%u odst=%u.%u.%u.%u " 1274 "rsrc=%u.%u.%u.%u rdst=%u.%u.%u.%u " 1275 "\n", 1276 dir == IP_CT_DIR_REPLY ? "reply" : "orig", hooknum, 1277 HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC ? "snat" : 1278 "dnat", (*pskb)->len, 1279 NIPQUAD(iph->saddr), ntohs(udph->source), 1280 NIPQUAD(iph->daddr), ntohs(udph->dest), 1281 NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), 1282 NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip), 1283 NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip), 1284 NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip)); 1285 } 1286 1287 /* 1288 * Make sure the packet length is ok. So far, we were only guaranteed 1289 * to have a valid length IP header plus 8 bytes, which means we have 1290 * enough room for a UDP header. Just verify the UDP length field so we 1291 * can mess around with the payload. 1292 */ 1293 if (ntohs(udph->len) == (*pskb)->len - (iph->ihl << 2)) { 1294 int ret = snmp_translate(ct, info, ctinfo, hooknum, pskb); 1295 spin_unlock_bh(&snmp_lock); 1296 return ret; 1297 } 1298 1299 if (net_ratelimit()) 1300 printk(KERN_WARNING "bsalg: dropping malformed packet " 1301 "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n", 1302 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); 1303 spin_unlock_bh(&snmp_lock); 1304 return NF_DROP; 1305} 1306 1307static struct ip_nat_helper snmp = { 1308 { NULL, NULL }, 1309 "snmp", 1310 IP_NAT_HELPER_F_STANDALONE, 1311 THIS_MODULE, 1312 { { 0, { __constant_htons(SNMP_PORT) } }, 1313 { 0, { 0 }, IPPROTO_UDP } }, 1314 { { 0, { 0xFFFF } }, 1315 { 0, { 0 }, 0xFFFF } }, 1316 nat_help, NULL }; 1317 1318static struct ip_nat_helper snmp_trap = { 1319 { NULL, NULL }, 1320 "snmp_trap", 1321 IP_NAT_HELPER_F_STANDALONE, 1322 THIS_MODULE, 1323 { { 0, { __constant_htons(SNMP_TRAP_PORT) } }, 1324 { 0, { 0 }, IPPROTO_UDP } }, 1325 { { 0, { 0xFFFF } }, 1326 { 0, { 0 }, 0xFFFF } }, 1327 nat_help, NULL }; 1328 1329/***************************************************************************** 1330 * 1331 * Module stuff. 1332 * 1333 *****************************************************************************/ 1334 1335static int __init init(void) 1336{ 1337 int ret = 0; 1338 1339 ret = ip_nat_helper_register(&snmp); 1340 if (ret < 0) 1341 return ret; 1342 ret = ip_nat_helper_register(&snmp_trap); 1343 if (ret < 0) { 1344 ip_nat_helper_unregister(&snmp); 1345 return ret; 1346 } 1347 return ret; 1348} 1349 1350static void __exit fini(void) 1351{ 1352 ip_nat_helper_unregister(&snmp); 1353 ip_nat_helper_unregister(&snmp_trap); 1354 br_write_lock_bh(BR_NETPROTO_LOCK); 1355 br_write_unlock_bh(BR_NETPROTO_LOCK); 1356} 1357 1358module_init(init); 1359module_exit(fini); 1360 1361MODULE_PARM(debug, "i"); 1362MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); 1363MODULE_LICENSE("GPL"); 1364