📄 ip_nat_snmp_basic.c
字号:
return 0; } if (subid < 40) { optr [0] = 0; optr [1] = subid; } else if (subid < 80) { optr [0] = 1; optr [1] = subid - 40; } else { optr [0] = 2; optr [1] = subid - 80; } *len = 2; optr += 2; while (ctx->pointer < eoc) { if (++(*len) > size) { ctx->error = ASN1_ERR_DEC_BADVALUE; kfree(*oid); *oid = NULL; return 0; } if (!asn1_subid_decode(ctx, optr++)) { kfree(*oid); *oid = NULL; return 0; } } return 1;}/***************************************************************************** * * SNMP decoding routines (gxsnmp author Dirk Wisse) * *****************************************************************************//* SNMP Versions */#define SNMP_V1 0#define SNMP_V2C 1#define SNMP_V2 2#define SNMP_V3 3/* Default Sizes */#define SNMP_SIZE_COMM 256#define SNMP_SIZE_OBJECTID 128#define SNMP_SIZE_BUFCHR 256#define SNMP_SIZE_BUFINT 128#define SNMP_SIZE_SMALLOBJECTID 16/* Requests */#define SNMP_PDU_GET 0#define SNMP_PDU_NEXT 1#define SNMP_PDU_RESPONSE 2#define SNMP_PDU_SET 3#define SNMP_PDU_TRAP1 4#define SNMP_PDU_BULK 5#define SNMP_PDU_INFORM 6#define SNMP_PDU_TRAP2 7/* Errors */#define SNMP_NOERROR 0#define SNMP_TOOBIG 1#define SNMP_NOSUCHNAME 2#define SNMP_BADVALUE 3#define SNMP_READONLY 4#define SNMP_GENERROR 5#define SNMP_NOACCESS 6#define SNMP_WRONGTYPE 7#define SNMP_WRONGLENGTH 8#define SNMP_WRONGENCODING 9#define SNMP_WRONGVALUE 10#define SNMP_NOCREATION 11#define SNMP_INCONSISTENTVALUE 12#define SNMP_RESOURCEUNAVAILABLE 13#define SNMP_COMMITFAILED 14#define SNMP_UNDOFAILED 15#define SNMP_AUTHORIZATIONERROR 16#define SNMP_NOTWRITABLE 17#define SNMP_INCONSISTENTNAME 18/* General SNMP V1 Traps */#define SNMP_TRAP_COLDSTART 0#define SNMP_TRAP_WARMSTART 1#define SNMP_TRAP_LINKDOWN 2#define SNMP_TRAP_LINKUP 3#define SNMP_TRAP_AUTFAILURE 4#define SNMP_TRAP_EQPNEIGHBORLOSS 5#define SNMP_TRAP_ENTSPECIFIC 6/* SNMPv1 Types */#define SNMP_NULL 0#define SNMP_INTEGER 1 /* l */#define SNMP_OCTETSTR 2 /* c */#define SNMP_DISPLAYSTR 2 /* c */#define SNMP_OBJECTID 3 /* ul */#define SNMP_IPADDR 4 /* uc */#define SNMP_COUNTER 5 /* ul */#define SNMP_GAUGE 6 /* ul */#define SNMP_TIMETICKS 7 /* ul */#define SNMP_OPAQUE 8 /* c *//* Additional SNMPv2 Types */#define SNMP_UINTEGER 5 /* ul */#define SNMP_BITSTR 9 /* uc */#define SNMP_NSAP 10 /* uc */#define SNMP_COUNTER64 11 /* ul */#define SNMP_NOSUCHOBJECT 12#define SNMP_NOSUCHINSTANCE 13#define SNMP_ENDOFMIBVIEW 14union snmp_syntax{ unsigned char uc[0]; /* 8 bit unsigned */ char c[0]; /* 8 bit signed */ unsigned long ul[0]; /* 32 bit unsigned */ long l[0]; /* 32 bit signed */};struct snmp_object{ unsigned long *id; unsigned int id_len; unsigned short type; unsigned int syntax_len; union snmp_syntax syntax;};struct snmp_request{ unsigned long id; unsigned int error_status; unsigned int error_index;};struct snmp_v1_trap{ unsigned long *id; unsigned int id_len; unsigned long ip_address; /* pointer */ unsigned int general; unsigned int specific; unsigned long time;};/* SNMP types */#define SNMP_IPA 0#define SNMP_CNT 1#define SNMP_GGE 2#define SNMP_TIT 3#define SNMP_OPQ 4#define SNMP_C64 6/* SNMP errors */#define SERR_NSO 0#define SERR_NSI 1#define SERR_EOM 2static inline void mangle_address(unsigned char *begin, unsigned char *addr, const struct oct1_map *map, u_int16_t *check);struct snmp_cnv{ unsigned int class; unsigned int tag; int syntax;};static struct snmp_cnv snmp_conv [] ={ {ASN1_UNI, ASN1_NUL, SNMP_NULL}, {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR}, {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID}, {ASN1_APL, SNMP_IPA, SNMP_IPADDR}, {ASN1_APL, SNMP_CNT, SNMP_COUNTER}, /* Counter32 */ {ASN1_APL, SNMP_GGE, SNMP_GAUGE}, /* Gauge32 == Unsigned32 */ {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS}, {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE}, /* SNMPv2 data types and errors */ {ASN1_UNI, ASN1_BTS, SNMP_BITSTR}, {ASN1_APL, SNMP_C64, SNMP_COUNTER64}, {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT}, {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE}, {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW}, {0, 0, -1}};static unsigned char snmp_tag_cls2syntax(unsigned int tag, unsigned int cls, unsigned short *syntax){ struct snmp_cnv *cnv; cnv = snmp_conv; while (cnv->syntax != -1) { if (cnv->tag == tag && cnv->class == cls) { *syntax = cnv->syntax; return 1; } cnv++; } return 0;}static unsigned char snmp_object_decode(struct asn1_ctx *ctx, struct snmp_object **obj){ unsigned int cls, con, tag, len, idlen; unsigned short type; unsigned char *eoc, *end, *p; unsigned long *lp, *id; unsigned long ul; long l; *obj = NULL; id = NULL; if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag)) return 0; if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) return 0; if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) return 0; if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) return 0; if (!asn1_oid_decode(ctx, end, &id, &idlen)) return 0; if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) { kfree(id); return 0; } if (con != ASN1_PRI) { kfree(id); return 0; } if (!snmp_tag_cls2syntax(tag, cls, &type)) { kfree(id); return 0; } switch (type) { case SNMP_INTEGER: len = sizeof(long); if (!asn1_long_decode(ctx, end, &l)) { kfree(id); return 0; } *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } (*obj)->syntax.l[0] = l; break; case SNMP_OCTETSTR: case SNMP_OPAQUE: if (!asn1_octets_decode(ctx, end, &p, &len)) { kfree(id); return 0; } *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } memcpy((*obj)->syntax.c, p, len); kfree(p); break; case SNMP_NULL: case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: len = 0; *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC); if (*obj == NULL) { kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } if (!asn1_null_decode(ctx, end)) { kfree(id); kfree(*obj); *obj = NULL; return 0; } break; case SNMP_OBJECTID: if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) { kfree(id); return 0; } len *= sizeof(unsigned long); *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } memcpy((*obj)->syntax.ul, lp, len); kfree(lp); break; case SNMP_IPADDR: if (!asn1_octets_decode(ctx, end, &p, &len)) { kfree(id); return 0; } if (len != 4) { kfree(p); kfree(id); return 0; } *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { kfree(p); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } memcpy((*obj)->syntax.uc, p, len); kfree(p); break; case SNMP_COUNTER: case SNMP_GAUGE: case SNMP_TIMETICKS: len = sizeof(unsigned long); if (!asn1_ulong_decode(ctx, end, &ul)) { kfree(id); return 0; } *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); return 0; } (*obj)->syntax.ul[0] = ul; break; default: kfree(id); return 0; } (*obj)->syntax_len = len; (*obj)->type = type; (*obj)->id = id; (*obj)->id_len = idlen; if (!asn1_eoc_decode(ctx, eoc)) { kfree(id); kfree(*obj); *obj = NULL; return 0; } return 1;}static unsigned char snmp_request_decode(struct asn1_ctx *ctx, struct snmp_request *request){ unsigned int cls, con, tag; unsigned char *end; if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) return 0; if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) return 0; if (!asn1_ulong_decode(ctx, end, &request->id)) return 0; if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) return 0; if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) return 0; if (!asn1_uint_decode(ctx, end, &request->error_status)) return 0; if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) return 0; if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) return 0; if (!asn1_uint_decode(ctx, end, &request->error_index)) return 0; return 1;}/* * Fast checksum update for possibly oddly-aligned UDP byte, from the * code example in the draft. */static void fast_csum(unsigned char *csum, const unsigned char *optr, const unsigned char *nptr, int odd){ long x, old, new; x = csum[0] * 256 + csum[1]; x =~ x & 0xFFFF; if (odd) old = optr[0] * 256; else old = optr[0]; x -= old & 0xFFFF; if (x <= 0) { x--; x &= 0xFFFF; } if (odd) new = nptr[0] * 256; else new = nptr[0]; x += new & 0xFFFF; if (x & 0x10000) { x++; x &= 0xFFFF; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -