ip_nat_snmp_basic.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:32k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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