📄 snmp_d.c
字号:
LCL_FILE * in_stream){int asn1err = 0;#if (INSTALL_ENVOY_SNMP_VERSION_1)if (rp->pdu_type == TRAP_PDU) { EBUFFER_T net_addr; unsigned int used; rp->pdu.trap_pdu.trap_vbl.vblist = 0; EBufferInitialize(&net_addr); A_DecodeObjectIdWTC(in_stream, &(rp->pdu.trap_pdu.enterprise_objid), &asn1err, A_OBJECTID, A_UNIVERSAL | A_PRIMITIVE); A_DecodeOctetStringWTC(in_stream, &net_addr, &asn1err, VT_IPADDRESS & ~A_IDCF_MASK, VT_IPADDRESS & A_IDCF_MASK); rp->pdu.trap_pdu.generic_trap = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE); rp->pdu.trap_pdu.specific_trap = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE); rp->pdu.trap_pdu.trap_time_ticks = (UINT_32_T) A_DecodeIntegerWTC(in_stream, &asn1err, VT_TIMETICKS & ~A_IDCF_MASK, VT_TIMETICKS & A_IDCF_MASK); if (asn1err) { EBufferClean(&net_addr); return(DECODE_ASN_PARSE_ERROR); } MEMSET(rp->pdu.trap_pdu.net_address, 0, 4); used = min(4, EBufferUsed(&net_addr)); if (used != 0) { MEMCPY(rp->pdu.trap_pdu.net_address, net_addr.start_bp, used); EBufferClean(&net_addr); } /* Now deal with the VarBindList */ return (decode_pkt_to_vblist(in_stream, &(rp->pdu.trap_pdu.trap_vbl), rp)); } /* if (ptype == TRAP_PDU) */#endif /* (INSTALL_ENVOY_SNMP_VERSION_1) *//* if we get here it's a non-trap form of pdu */rp->pdu.std_pdu.request_id = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE);rp->pdu.std_pdu.error_status = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE);rp->pdu.std_pdu.error_index = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE);if (asn1err) { return(DECODE_ASN_PARSE_ERROR); }/* Now deal with the VarBindList */return(decode_pkt_to_vblist(in_stream, &(rp->pdu.std_pdu.std_vbl), rp));}#if (INSTALL_ENVOY_SNMP_VERSION_1 || INSTALL_ENVOY_SNMP_VERSION_2)/****************************************************************************NAME: SNMP_Decode_V1_PacketPURPOSE: Decode an V1 (RFC1157) or V2 SNMP packet.PARAMETERS: SNMP_PKT_T * Packet we're filling in. LCL_FILE * Stream to decode packet from. The stream is positioned after the first tag field (the tag that says it's an V1 (RFC1157) packet). SNMPADDR_T * Source of the packet SNMPADDR_T * Destination of the packet (most likely the address of the machine on which this code is running.) ALENGTH_T asn1 lengthRETURNS: SNMP_PKT_T * SNMP Packet structure, 0 on failure****************************************************************************/static SNMP_PKT_T * SNMP_Decode_V1_Packet(SNMP_PKT_T * rp, LCL_FILE * in_stream, SNMPADDR_T * pktsrc, SNMPADDR_T * pktdst, ALENGTH_T asn1leng){ATVALUE_T ptype;ALENGTH_T plength;int asn1err = 0;/* Extract the community string */A_DecodeOctetStringWTC(in_stream, &rp->community, &asn1err, A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE);if (asn1err) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return 0; }/* Decode the packet type *//* Since all of the PDUs follow the same form, we can decode them *//* without being concerned as to which PDU we are decoding. *//* Furthermore, since the VarBindList is the last thing in the PDU, *//* we can ignore the overall length of the sequence forming the PDU. */if (A_DecodeTypeClass(in_stream) != (A_DEFAULT_SCOPE | A_CONSTRUCTOR)) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return 0; }/* Decode the pdu type */ ptype = A_DecodeTypeValue(in_stream, &asn1err);plength = A_DecodeLength(in_stream, &asn1err);if (asn1err) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return 0; }/* Determine if we support the given pdu for the given version */switch(rp->snmp_version) {#if INSTALL_ENVOY_SNMP_VERSION_1 case SNMP_VERSION_1: if (ptype > MAX_V1_PDU) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return 0; } break;#endif /* INSTALL_ENVOY_SNMP_VERSION_1 */#if INSTALL_ENVOY_SNMP_VERSION_2 case SNMP_VERSION_2: /* The trap type is not allowed in version 2 */ if ((ptype > MAX_PDU) || (ptype == TRAP_PDU)) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return 0; } break;#endif /* INSTALL_ENVOY_SNMP_VERSION_2 */ default: SGRPv1v2_INC_COUNTER(snmp_stats.snmpInBadVersions); return(0); }/* Check whether there is an inconsistency between the PDU length and *//* the overall length indicated by the outermost ASN.1 wrapper. *//* If so, the packet is ill-formed and must be rejected. */if (asn1leng != (Lcl_Tell(in_stream) + plength)) { SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); }rp->pdu_type = ptype;rp->pdu_length = plength;/* Check that the community string is valid. This also gets the *//* view mask for this transaction from the community string. The *//* source and destination addresses are passed through for the user *//* routine to deal with. It may just copy them into the snmp packet *//* structure. */switch(DYNCFG_FUNCALL(SNMP_community_coexistence_lookup)(rp, pktsrc, pktdst)) { case 0: break; case 1: default: return(0); case 2: SGRPv1v2_INC_COUNTER(snmp_stats.snmpInBadCommunityNames); return(0); case 3: SGRPv1v2_INC_COUNTER(snmp_stats.snmpInBadCommunityUses); return(0); }switch(SNMP_Decode_PDU(rp, in_stream)) { case 0: return rp; case DECODE_ASN_PARSE_ERROR: SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); case DECODE_ALLOCATION_FAILURE: default: return(0); }}#endif /* #if (INSTALL_ENVOY_SNMP_VERSION_1 || INSTALL_ENVOY_SNMP_VERSION_2) *//********************************************************************************* SNMP_Decode_Packet_WER - decode a packet into an in-memory packet structure* SYNOPSIS** \cs* SNMP_PKT_T * SNMP_Decode_Packet_WER * ( * unsigned char * pktp, * int pktl, * SNMPADDR_T * pktsrc, * SNMPADDR_T * pktdst, * int * error_ret * )* \ce** DESCRIPTION** This routine decodes a buffer containing an SNMP packet into an in-memory * packet structure. When compiled for SNMPv1, SNMPv2, or SNMPV3, this routine * is able to decode the version and correctly set the version field in the * packet.** \&NOTE: Use this routine only for SNMP management stations (clients). For * SNMP agents or servers, use Process_Rcvd_SNMP_Packet_Async().** PARAMETERS* \is* \i <*pktp>* Specify a pointer to the packet.* \i <pktl>* Specify the length of the packet.* \i <*pktsrc>* Reference the source of the packet. This information is passed to the * customer-supplied routines SNMP_validate_community() and * SNMP_validate_address().* \i <*pktdst>* Reference the destination of the packet. This information is passed to the * customer-supplied routines SNMP_validate_community() and * SNMP_validate_address().* \i <*error_ret>* Indicate that the packet was decoded but an incident occurred while decoding * that requires an error response be sent. If an error response is requested, * it is up to the calling routine whether or not to send the response. It is * the calling routine\抯 responsibility to encode the packet and choose the * appropriate source and destination addresses. If the error code is set, the * PDU type, error status, and error index are set appropriately.* \ie** RETURNS: If successful, this routine returns a pointer to a dynamically * allocated packet structure. If the decoding fails, this routine returns 0. * When returning a valid pointer, this routine sets <error_ret>. If <error_ret> * is 0, processing should continue. If <error_ret> is 1, then an error response * should be returned to the requestor.** ERRNO: N/A** SEE ALSO: Process_Rcvd_SNMP_Packet_Async(), SNMP_Encode_Packet(), * SNMP_validate_address(), SNMP_validate_community()*/SNMP_PKT_T * SNMP_Decode_Packet_WER(unsigned char * pktp, int pktl, SNMPADDR_T * pktsrc, SNMPADDR_T * pktdst, int * error_ret){ SNMP_PKT_T *rp, *ret_rp; ATVALUE_T type; ALENGTH_T overall_length, asn1leng; OCTET_T flags; LCL_FILE *in_stream, in_pkt_stream; int temperror, asn1err = 0; INT_32_T snmp_version; /* if the caller did not supply error_ret set that up and init it to the no error state */ if (error_ret == 0) error_ret = &temperror; *error_ret = 0; /* Make sure the size is within range and then Set up packet as a local stream. */ if ((pktl > MAX_ALENGTH) || ((in_stream = Lcl_Open(&in_pkt_stream, pktp, (ALENGTH_T)pktl)) == 0)) return 0; /* Decode the top-level message sequence... */ flags = A_DecodeTypeClass(in_stream); type = A_DecodeTypeValue(in_stream, &asn1err); overall_length = A_DecodeLength(in_stream, &asn1err); if (asn1err) { Lcl_Close(in_stream); SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); } /* Validate that the length provided by the caller is consistent with */ /* the length given by the ASN.1 wrapper... */ /* If necessary, shrink the local I/O buffer to match. */ asn1leng = Lcl_Tell(in_stream) + overall_length; if (asn1leng < (ALENGTH_T)pktl) { (void) Lcl_Resize(in_stream, asn1leng, 0); } else { if (asn1leng > (ALENGTH_T)pktl) { Lcl_Close(in_stream); SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); } } /* Test the flags & type info to see if we have something that looks like the right kind of packet */ if ((flags | type) != (A_UNIVERSAL | A_CONSTRUCTOR | A_SEQUENCE)) { /* oh well, this isn't an snmp packet, bail out */ Lcl_Close(in_stream); SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); } /* get the version stamp */ snmp_version = A_DecodeIntegerWTC(in_stream, &asn1err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE); if (asn1err) { Lcl_Close(in_stream); SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); return(0); } /* Get the SNMP packet structure. */ if ((rp = SNMP_Allocate()) == 0) { Lcl_Close(in_stream); return(0); } /* If the lock code is installed acquire the generic read lock */#if (INSTALL_ENVOY_SNMP_LOCK) if (ENVOY_SNMP_GET_READ_LOCK(SNMP_CoarseLock)) { BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0, (BUG_OUT, "SNMP_Decode_Packet_WER: coarse lock is broken", 0)); SNMP_Free(rp); Lcl_Close(in_stream); return(0); } rp->coarse_lock = &SNMP_CoarseLock; rp->lockflags = LOCK_READ;#endif rp->snmp_version = snmp_version; switch(snmp_version) {#if INSTALL_ENVOY_SNMP_VERSION_1 case SNMP_VERSION_1: ret_rp = SNMP_Decode_V1_Packet(rp, in_stream, pktsrc, pktdst, asn1leng); break;#endif#if INSTALL_ENVOY_SNMP_VERSION_2 case SNMP_VERSION_2: ret_rp = SNMP_Decode_V1_Packet(rp, in_stream, pktsrc, pktdst, asn1leng); break;#endif#if INSTALL_ENVOY_SNMP_VERSION_3 case SNMP_VERSION_3: DYNCFG_IFCFGVBL_BEGIN(snmpv3_component) ret_rp = DYNCFG_FUNCALL(SNMP_Decode_V3_Packet) (rp, in_stream, pktsrc, pktdst, asn1leng, error_ret); break; DYNCFG_IFCFGVBL_END(snmpv3_component)#endif default: if ((snmp_version < SNMP_VERSION_MIN) || (snmp_version > SNMP_VERSION_MAX)) SGRPv1v2_INC_COUNTER(snmp_stats.snmpInASNParseErrs); else SGRPv1v2_INC_COUNTER(snmp_stats.snmpInBadVersions); ret_rp = 0; break; } if (ret_rp == 0){ SNMP_Free(rp); } Lcl_Close(in_stream); return(ret_rp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -