📄 snmp_d.c
字号:
* * Revision 2.106 91/11/07 09:34:05 dab * Moved where SNMP_validate_community() is called from. It's now after * we've determined what type the PDU is. * * Revision 2.105 91/11/05 10:59:51 dab * Removed the 'then's. * * Revision 2.104 91/10/30 20:42:11 dab * Directly include asn1conf.h, snmpdefs.h, and snmpstat.h (if needed). * * Revision 2.103 91/09/18 12:32:37 dab * Updated to use new macros from <asn1conf.h> and <snmpconf.h>. * * Revision 2.102 91/08/15 12:31:11 dab * Removed <libfuncs.h>. * * Revision 2.101 91/08/12 12:47:39 dab * Cast arguments to memcpy() and memset() to PTR_T. * * Revision 2.100 91/08/09 14:08:26 dab * Update version. * * Revision 1.1 91/07/30 02:23:54 romkey * Initial revision * * * Rev 2.0 31 Mar 1990 15:06:56 * Release 2.00 * * Rev 1.12 16 Dec 1989 14:07:48 * A check added to snmp_free() to avoid freeing a non-allocated block. * * Rev 1.11 14 Dec 1989 16:01:00 * Added support for Borland Turbo C compiler * * Rev 1.10 27 Apr 1989 15:56:30 * Removed unused variables * * Rev 1.9 24 Mar 1989 17:26:30 * Module "copyrite.c" included to create in-core image of Epilogue * copyright notice. Old method via "snmp.h" did not work for all * compilers. * * Rev 1.8 23 Mar 1989 12:03:58 * Added more checks to protect against mis-encoded ASN.1. * * Rev 1.7 19 Mar 1989 13:04:52 * Added protection against zero length, short, or overlength IP addresses. * * Rev 1.6 18 Mar 1989 11:58:42 * Made changes to conform to string decoding simplification in decode.c. * * Rev 1.5 17 Mar 1989 21:41:46 * Calls to memcpy/memset protected against zero lengths * * Rev 1.4 04 Mar 1989 10:35:06 * Added cast to actual parameter on call to memset to avoid warnings on * some compilers. * * Rev 1.3 11 Jan 1989 12:46:42 * Moved Clean_Obj_ID() to objectid.c * * Rev 1.2 19 Sep 1988 17:26:50 * Made changes to make the Sun C compiler happy. * * Rev 1.1 14 Sep 1988 17:57:22 * Moved includes of system include files into libfuncs.h. * * Rev 1.0 12 Sep 1988 10:47:06 * Initial revision.*//* [clearcase]modification history-------------------01d,12may05,job fix apigen comments01c,18apr05,job update copyright notices01b,16feb05,job apigen for documented APIs01a,24nov03,job update copyright information*//*DESCRIPTIONThis library contains snmp_d.c routines.INCLUDE FILES: snmp.h*/#include <wrn/wm/snmp/engine/asn1conf.h>#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/localio.h>#include <wrn/wm/snmp/engine/buffer.h>#include <wrn/wm/snmp/engine/decode.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/snmpdefs.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/snmpstat.h>#include <wrn/wm/common/bug.h>#include <wrn/wm/common/dyncfg.h>DYNCFG_VBL_DECLARE_EXTERN(snmpv3_component) DYNCFG_VBL_DECLARE_EXTERN(envoy_use_v2_types) DYNCFG_EXTERN_FUNCPTR6(SNMP_Decode_V3_Packet,SNMP_PKT_T*,SNMP_PKT_T *,LCL_FILE *,SNMPADDR_T *, SNMPADDR_T *, ALENGTH_T, int *)DYNCFG_EXTERN_FUNCPTR3(SNMP_community_coexistence_lookup,int,SNMP_PKT_T *, SNMPADDR_T *, SNMPADDR_T *)#if INSTALL_ENVOY_SNMP_VERSION_3extern SNMP_PKT_T * SNMP_Decode_V3_Packet __((SNMP_PKT_T *, LCL_FILE *, SNMPADDR_T *, SNMPADDR_T *, ALENGTH_T, int *));#endif/* * Internal Functions */#if !defined(SNMP_AUTH_DECODE_VIOLATION)#define SNMP_AUTH_DECODE_VIOLATION(pkt, x)#endif /*lint -e617 */#include "copyrite.c"/*lint +e617 *//****************************************************************************NAME: count_var_bindsPURPOSE: To figure out how many VarBind items are in a VarBindList On entry, the input stream should be positioned to the start of the data (contents) part of the VarBindList. On exit, the input stream will be positioned to the start of the data (contents) part of the VarBindList.PARAMETERS: LCL_FILE * The input streamRETURNS: int Count of the entries DECODE_ASN_PARSE_ERROR on errorNote: This routine correctly handles the case where the VarBindList is empty.****************************************************************************/static int count_var_binds(LCL_FILE * stream, ALENGTH_T leng){/* tell_place is the offset in stream to VarBind data */ALENGTH_T used, tell_place;int items;int asn1err = 0;tell_place = Lcl_Tell(stream);for(items = 0, used = 0; used < leng;) { ALENGTH_T alength, start_place, end_place; start_place = Lcl_Tell(stream); if (Lcl_Eof(stream)) break; /* Skip over the VarBind sequence */ (void) A_DecodeTypeValue(stream, &asn1err); alength = A_DecodeLength(stream, &asn1err); if (asn1err || (Lcl_Seek(stream, alength, 1) == -1)) { items = (DECODE_ASN_PARSE_ERROR); break; } end_place = Lcl_Tell(stream); used = used + end_place - start_place; items++; }(void) Lcl_Seek(stream, tell_place, 0);return items;}/****************************************************************************NAME: decode_pkt_to_vbPURPOSE: Decode a VarBind from a packet On entry the input stream should be positioned to the tag field of the VarBind entry. On exit, the stream pointer will be positioned to at the start of the ASN.1 type field of AFTER the VarBind.PARAMETERS: LCL_FILE * The input stream VB_T * The VB_T element to be filled. SNMP_PKT_T * The packet being decoded.RETURNS: success: 0 Failures: DECODE_ASN_PARSE_ERROR ****************************************************************************/static int decode_pkt_to_vb(LCL_FILE *stream, VB_T *vbp, SNMP_PKT_T *pkt){OCTET_T flags;ATVALUE_T id;ALENGTH_T leng;int asn1err = 0;A_DecodeObjectIdWTC(stream, &(vbp->vb_obj_id), &asn1err, A_OBJECTID, A_UNIVERSAL | A_PRIMITIVE);flags = A_DecodeTypeClass(stream);id = A_DecodeTypeValue(stream, &asn1err);leng = A_DecodeLength(stream, &asn1err);if (asn1err) { return (DECODE_ASN_PARSE_ERROR); }vbp->vb_data_length = leng;vbp->vb_data_flags_n_type = flags | (OCTET_T)id;switch (vbp->vb_data_flags_n_type) { case VT_NUMBER: vbp->value_u.v_number = A_DecodeIntegerData(stream, leng, &asn1err); break; case VT_COUNTER: case VT_GAUGE: case VT_TIMETICKS: vbp->value_u.v_counter = (UINT_32_T)A_DecodeIntegerData(stream, leng, &asn1err); break; case VT_STRING: case VT_OPAQUE: A_DecodeOctetStringData(stream, leng, &(vbp->value_u.v_string), &asn1err); break; case VT_OBJECT: A_DecodeObjectIdData(stream, leng, &(vbp->value_u.v_object), &asn1err); break; case VT_NOSUCHOBJ: case VT_NOSUCHINS: case VT_ENDOFMIB: case VT_EMPTY: /* Empty has no contents to be decoded */ break; case VT_IPADDRESS: { EBUFFER_T ipbuff; unsigned int used; MEMSET(vbp->value_u.v_network_address, 0, 4); EBufferInitialize(&ipbuff); A_DecodeOctetStringData(stream, leng, &ipbuff, &asn1err); used = min(4, EBufferUsed(&ipbuff)); if (used != 0) { MEMCPY(vbp->value_u.v_network_address, ipbuff.start_bp, used); EBufferClean(&ipbuff); } } break;/* If we are using v2 types in general or we only have v2 installed we allow the following types all the time. Otherwise if we have v2 and v1 installed but not v2 types we need to check the type of the packet and if it's v1 reject these types. If we don't have v2 or v2 types installed the types will be rejected as the default case */#if ((INSTALL_ENVOY_SNMP_USE_V2_TYPES) || \ ((ENVOY_USE_V2_TYPES) && !(INSTALL_ENVOY_SNMP_VERSION_1))) case VT_COUNTER64: DYNCFG_IFCFGVBL_BEGIN(envoy_use_v2_types) A_DecodeInteger64Data (stream, leng, &(vbp->value_u.v_counter64), &asn1err); break; DYNCFG_IFCFGVBL_END(envoy_use_v2_types)#else#if ((ENVOY_USE_V2_TYPES) && (INSTALL_ENVOY_SNMP_VERSION_1)) case VT_COUNTER64: DYNCFG_IFCFGVBL_BEGIN(envoy_use_v2_types) if (pkt->snmp_version == SNMP_VERSION_1) { return (DECODE_ASN_PARSE_ERROR); } A_DecodeInteger64Data (stream, leng, &(vbp->value_u.v_counter64), &asn1err); break; DYNCFG_IFCFGVBL_END(envoy_use_v2_types)#endif /* ((ENVOY_USE_V2_TYPES) && (INSTALL_ENVOY_SNMP_VERSION_1)) */#endif /* (INSTALL_ENVOY_SNMP_USE_V2_TYPES) */ default: return (DECODE_ASN_PARSE_ERROR); }if (asn1err) return (DECODE_ASN_PARSE_ERROR);else return (0);/*NOTREACHED*/}/****************************************************************************NAME: decode_pkt_to_vblistPURPOSE: Decode a packet's VarBindList On entry the input stream should be positioned to the tag field of the first VarBind entry. On exit, the stream pointer will be positioned to at the start of the ASN.1 type field of AFTER the VarBindList, normally this will be at the end of the packet.PARAMETERS: LCL_FILE * The input stream VBL_T * The VarBindList header to be filled-in SNMP_PKT_T * The packet being decodedRETURNS: success: 0 failure: DECODE_ASN_PARSE_ERROR DECODE_ALLOCATION_FAILURE****************************************************************************/static int decode_pkt_to_vblist(LCL_FILE * stream, VBL_T * vblp, SNMP_PKT_T * pkt){VB_T *vbp;int vbcnt, i, asn1err = 0;/* Now deal with the VarBindList and sanity check the length field */(void) A_DecodeTypeValue(stream, &asn1err);vblp->vbl_length = A_DecodeLength(stream, &asn1err);if (asn1err || (vblp->vbl_length != Lcl_Size(stream))) { return (DECODE_ASN_PARSE_ERROR); }/* Count the number of VarBinds. */vblp->vbl_count = 0; /* Just in case things fail */if ((vbcnt = count_var_binds(stream, vblp->vbl_length)) == -1) { return (DECODE_ASN_PARSE_ERROR); }if (vbcnt == 0) { /* Handle case where the VarBindList is empty */ vblp->vblist = 0; }else { /* The VarBindList has contents */ vblp->vbl_count = vbcnt; if ((vblp->vblist = VarBindList_Allocate(vblp->vbl_count)) == 0) { return (DECODE_ALLOCATION_FAILURE); } for (vbp = vblp->vblist, i = 0; i < vblp->vbl_count; i++, vbp++) { (void) A_DecodeTypeValue(stream, &asn1err); vbp->vb_seq_size = A_DecodeLength(stream, &asn1err); if (asn1err || decode_pkt_to_vb(stream, vbp, pkt)) { return (DECODE_ASN_PARSE_ERROR); } } }return(0);}/****************************************************************************\NOMANUALNAME: SNMP_Decode_PDUPURPOSE: Decode a pdu, starting from the byte after the length field of the pdu type.PARAMETERS: SNMP_PKT_T * Packet we're filling in. LCL_FILE * Stream to decode packet from. The stream is positioned after the length field of the pdu tag.RETURNS: Success: 0 Failure: DECODE_ASN_PARSE_ERROR DECODE_ALLOCATION_FAILURE:****************************************************************************/int SNMP_Decode_PDU(SNMP_PKT_T * rp,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -