42 #include <linux/module.h>
44 #include <linux/types.h>
45 #include <linux/kernel.h>
46 #include <linux/slab.h>
49 #include <linux/udp.h>
65 #define SNMP_TRAP_PORT 162
66 #define NOCT1(n) (*(u8 *)(n))
107 #define ASN1_NUMSTR 18
108 #define ASN1_PRNSTR 19
109 #define ASN1_TEXSTR 20
110 #define ASN1_VIDSTR 21
111 #define ASN1_IA5STR 22
112 #define ASN1_UNITIM 23
113 #define ASN1_GENTIM 24
114 #define ASN1_GRASTR 25
115 #define ASN1_VISSTR 26
116 #define ASN1_GENSTR 27
125 #define ASN1_ERR_NOERROR 0
126 #define ASN1_ERR_DEC_EMPTY 2
127 #define ASN1_ERR_DEC_EOC_MISMATCH 3
128 #define ASN1_ERR_DEC_LENGTH_MISMATCH 4
129 #define ASN1_ERR_DEC_BADVALUE 5
138 unsigned char *
begin;
156 ctx->
end = buf + len;
161 static unsigned char asn1_octet_decode(
struct asn1_ctx *
ctx,
unsigned char *ch)
171 static unsigned char asn1_tag_decode(
struct asn1_ctx *ctx,
unsigned int *
tag)
179 if (!asn1_octet_decode(ctx, &ch))
183 }
while ((ch & 0x80) == 0x80);
187 static unsigned char asn1_id_decode(
struct asn1_ctx *ctx,
194 if (!asn1_octet_decode(ctx, &ch))
197 *cls = (ch & 0xC0) >> 6;
198 *con = (ch & 0x20) >> 5;
202 if (!asn1_tag_decode(ctx, tag))
208 static unsigned char asn1_length_decode(
struct asn1_ctx *ctx,
212 unsigned char ch,
cnt;
214 if (!asn1_octet_decode(ctx, &ch))
229 if (!asn1_octet_decode(ctx, &ch))
245 static unsigned char asn1_header_decode(
struct asn1_ctx *ctx,
251 unsigned int def, len;
253 if (!asn1_id_decode(ctx, cls, con, tag))
257 if (!asn1_length_decode(ctx, &def, &len))
271 static unsigned char asn1_eoc_decode(
struct asn1_ctx *ctx,
unsigned char *eoc)
276 if (!asn1_octet_decode(ctx, &ch))
284 if (!asn1_octet_decode(ctx, &ch))
301 static unsigned char asn1_null_decode(
struct asn1_ctx *ctx,
unsigned char *eoc)
307 static unsigned char asn1_long_decode(
struct asn1_ctx *ctx,
314 if (!asn1_octet_decode(ctx, &ch))
317 *integer = (
signed char) ch;
321 if (++len >
sizeof (
long)) {
326 if (!asn1_octet_decode(ctx, &ch))
335 static unsigned char asn1_uint_decode(
struct asn1_ctx *ctx,
337 unsigned int *integer)
342 if (!asn1_octet_decode(ctx, &ch))
346 if (ch == 0) len = 0;
350 if (++len >
sizeof (
unsigned int)) {
355 if (!asn1_octet_decode(ctx, &ch))
364 static unsigned char asn1_ulong_decode(
struct asn1_ctx *ctx,
366 unsigned long *integer)
371 if (!asn1_octet_decode(ctx, &ch))
375 if (ch == 0) len = 0;
379 if (++len >
sizeof (
unsigned long)) {
384 if (!asn1_octet_decode(ctx, &ch))
393 static unsigned char asn1_octets_decode(
struct asn1_ctx *ctx,
395 unsigned char **octets,
408 if (!asn1_octet_decode(ctx, ptr++)) {
418 static unsigned char asn1_subid_decode(
struct asn1_ctx *ctx,
419 unsigned long *subid)
426 if (!asn1_octet_decode(ctx, &ch))
431 }
while ((ch & 0x80) == 0x80);
435 static unsigned char asn1_oid_decode(
struct asn1_ctx *ctx,
447 if (size < 2 || size >
ULONG_MAX/
sizeof(
unsigned long))
456 if (!asn1_subid_decode(ctx, &subid)) {
465 }
else if (subid < 80) {
467 optr [1] = subid - 40;
470 optr [1] = subid - 80;
477 if (++(*len) > size) {
484 if (!asn1_subid_decode(ctx, optr++)) {
506 #define SNMP_SIZE_COMM 256
507 #define SNMP_SIZE_OBJECTID 128
508 #define SNMP_SIZE_BUFCHR 256
509 #define SNMP_SIZE_BUFINT 128
510 #define SNMP_SIZE_SMALLOBJECTID 16
513 #define SNMP_PDU_GET 0
514 #define SNMP_PDU_NEXT 1
515 #define SNMP_PDU_RESPONSE 2
516 #define SNMP_PDU_SET 3
517 #define SNMP_PDU_TRAP1 4
518 #define SNMP_PDU_BULK 5
519 #define SNMP_PDU_INFORM 6
520 #define SNMP_PDU_TRAP2 7
523 #define SNMP_NOERROR 0
524 #define SNMP_TOOBIG 1
525 #define SNMP_NOSUCHNAME 2
526 #define SNMP_BADVALUE 3
527 #define SNMP_READONLY 4
528 #define SNMP_GENERROR 5
529 #define SNMP_NOACCESS 6
530 #define SNMP_WRONGTYPE 7
531 #define SNMP_WRONGLENGTH 8
532 #define SNMP_WRONGENCODING 9
533 #define SNMP_WRONGVALUE 10
534 #define SNMP_NOCREATION 11
535 #define SNMP_INCONSISTENTVALUE 12
536 #define SNMP_RESOURCEUNAVAILABLE 13
537 #define SNMP_COMMITFAILED 14
538 #define SNMP_UNDOFAILED 15
539 #define SNMP_AUTHORIZATIONERROR 16
540 #define SNMP_NOTWRITABLE 17
541 #define SNMP_INCONSISTENTNAME 18
544 #define SNMP_TRAP_COLDSTART 0
545 #define SNMP_TRAP_WARMSTART 1
546 #define SNMP_TRAP_LINKDOWN 2
547 #define SNMP_TRAP_LINKUP 3
548 #define SNMP_TRAP_AUTFAILURE 4
549 #define SNMP_TRAP_EQPNEIGHBORLOSS 5
550 #define SNMP_TRAP_ENTSPECIFIC 6
554 #define SNMP_INTEGER 1
555 #define SNMP_OCTETSTR 2
556 #define SNMP_DISPLAYSTR 2
557 #define SNMP_OBJECTID 3
558 #define SNMP_IPADDR 4
559 #define SNMP_COUNTER 5
561 #define SNMP_TIMETICKS 7
562 #define SNMP_OPAQUE 8
565 #define SNMP_UINTEGER 5
566 #define SNMP_BITSTR 9
568 #define SNMP_COUNTER64 11
569 #define SNMP_NOSUCHOBJECT 12
570 #define SNMP_NOSUCHINSTANCE 13
571 #define SNMP_ENDOFMIBVIEW 14
620 static inline void mangle_address(
unsigned char *begin,
631 static const struct snmp_cnv snmp_conv[] = {
652 static unsigned char snmp_tag_cls2syntax(
unsigned int tag,
660 while (cnv->
syntax != -1) {
661 if (cnv->
tag == tag && cnv->
class == cls) {
670 static unsigned char snmp_object_decode(
struct asn1_ctx *ctx,
673 unsigned int cls,
con,
tag, len, idlen;
675 unsigned char *eoc, *
end, *
p;
676 unsigned long *
lp, *
id;
683 if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag))
689 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
695 if (!asn1_oid_decode(ctx, end, &
id, &idlen))
698 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) {
709 if (!snmp_tag_cls2syntax(tag, cls, &type)) {
718 if (!asn1_long_decode(ctx, end, &l)) {
727 (*obj)->syntax.l[0] =
l;
731 if (!asn1_octets_decode(ctx, end, &p, &len)) {
741 memcpy((*obj)->syntax.c, p, len);
754 if (!asn1_null_decode(ctx, end)) {
762 if (!asn1_oid_decode(ctx, end, &lp, &len)) {
766 len *=
sizeof(
unsigned long);
773 memcpy((*obj)->syntax.ul, lp, len);
777 if (!asn1_octets_decode(ctx, end, &p, &len)) {
792 memcpy((*obj)->syntax.uc, p, len);
798 len =
sizeof(
unsigned long);
799 if (!asn1_ulong_decode(ctx, end, &ul)) {
808 (*obj)->syntax.ul[0] = ul;
815 (*obj)->syntax_len = len;
818 (*obj)->id_len = idlen;
820 if (!asn1_eoc_decode(ctx, eoc)) {
829 static unsigned char snmp_request_decode(
struct asn1_ctx *ctx,
832 unsigned int cls,
con,
tag;
835 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
841 if (!asn1_ulong_decode(ctx, end, &request->
id))
844 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
850 if (!asn1_uint_decode(ctx, end, &request->
error_status))
853 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
859 if (!asn1_uint_decode(ctx, end, &request->
error_index))
870 const unsigned char *optr,
871 const unsigned char *nptr,
888 *csum = csum_fold(
csum_partial(s, 4, ~csum_unfold(*csum)));
896 static inline void mangle_address(
unsigned char *begin,
905 memcpy(&old, addr,
sizeof(old));
912 &map->
from, &map->
to, addr - begin);
922 static unsigned char snmp_trap_decode(
struct asn1_ctx *ctx,
927 unsigned int cls,
con,
tag, len;
930 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
936 if (!asn1_oid_decode(ctx, end, &trap->
id, &trap->
id_len))
939 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
946 if (!asn1_octets_decode(ctx, end, (
unsigned char **)&trap->
ip_address, &len))
953 mangle_address(ctx->
begin, ctx->
pointer - 4, map, check);
955 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
961 if (!asn1_uint_decode(ctx, end, &trap->
general))
964 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
970 if (!asn1_uint_decode(ctx, end, &trap->
specific))
973 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
980 if (!asn1_ulong_decode(ctx, end, &trap->
time))
1000 static void hex_dump(
const unsigned char *
buf,
size_t len)
1004 for (i = 0; i < len; i++) {
1007 printk(
"%02x ", *(buf + i));
1016 static int snmp_parse_mangle(
unsigned char *
msg,
1021 unsigned char *eoc, *
end;
1022 unsigned int cls,
con,
tag, vers, pdutype;
1030 asn1_open(&ctx, msg, len);
1035 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1043 if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag))
1047 if (!asn1_uint_decode (&ctx, end, &vers))
1057 if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag))
1061 if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len))
1067 for (i = 0; i < comm.len; i++)
1068 printk(
"%c", comm.data[i]);
1076 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype))
1081 static const unsigned char *
const pdus[] = {
1106 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
1117 if (!snmp_request_decode(&ctx, &
req))
1122 "error_index=%u\n",
req.id,
req.error_status,
1129 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1135 while (!asn1_eoc_decode(&ctx, eoc)) {
1138 if (!snmp_object_decode(&ctx, &obj)) {
1148 for (i = 0; i < obj->
id_len; i++) {
1158 mangle_address(ctx.
begin, ctx.
pointer - 4 , map, check);
1164 if (!asn1_eoc_decode(&ctx, eoc))
1179 static int snmp_translate(
struct nf_conn *
ct,
1183 struct iphdr *iph = ip_hdr(skb);
1207 if (!snmp_parse_mangle((
unsigned char *)udph +
sizeof(
struct udphdr),
1208 paylen, &map, &udph->
check)) {
1217 static int help(
struct sk_buff *skb,
unsigned int protoff,
1223 const struct iphdr *iph = ip_hdr(skb);
1242 if (
ntohs(udph->
len) != skb->
len - (iph->ihl << 2)) {
1251 spin_lock_bh(&snmp_lock);
1252 ret = snmp_translate(ct, ctinfo, skb);
1253 spin_unlock_bh(&snmp_lock);
1265 .expect_policy = &snmp_exp_policy,
1275 .expect_policy = &snmp_exp_policy,
1276 .
name =
"snmp_trap",
1288 static int __init nf_nat_snmp_basic_init(
void)
1303 static void __exit nf_nat_snmp_basic_fini(
void)