📄 v3_ber.c
字号:
+ A_SizeOfInt(rp->msg_sec_boots) + 2 /* Tag and length of time field */ + A_SizeOfInt(rp->msg_sec_time) + 2 /* Tag and length of user name */ + A_SizeOfOctetString(EBufferUsed(&(rp->msg_sec_name))) + 1 /* Tag of auth information */ + A_SizeOfLength(auth_length) + auth_length + 1 /* Tag of priv information */ + A_SizeOfLength(priv_length) + priv_length;rp->security_length_2 = 1 /* Tag for security data */ + A_SizeOfLength(rp->security_length) + rp->security_length;rp->global_length = 2 /* Tag and length of message id */ + A_SizeOfInt(rp->msg_id) + 2 /* Tag and length of max message size */ + A_SizeOfInt(rp->msg_max_size) + 3 /* Tag, length and space for flags (1 octet) */ + 2 /* Tag and length of security model */ + A_SizeOfInt(rp->msg_sec_model);overall_length = 2 /* Tag and length of snmp_version (an integer) */ + A_SizeOfInt(rp->snmp_version) + 1 /* Tag for global data */ + A_SizeOfLength(rp->global_length) + rp->global_length + 1 /* Tag for security data */ + A_SizeOfLength(rp->security_length_2) + A_SizeOfOctetString(rp->security_length_2) + scoped_length;if ((overall_length & 0xffff) == overall_length) rp->overall_length = overall_length;else rp->overall_length = 0;buffer_needed = 1 + A_SizeOfLength(rp->overall_length) + overall_length;if ((buffer_needed & 0xffff) == buffer_needed) rp->buffer_needed = buffer_needed;else rp->buffer_needed = 0;return(rp->buffer_needed);}/************************************************************************NAME: encode_snmp_scoped_pduPURPOSE: encode a snmp packet in structure form into a byte string according to the snmp v3 rulesPARAMETERS: SNMP_PKT_T * the packet to encode EBUFFER_T * the buffer to write the byte string toRETURNS: void************************************************************************/void encode_snmp_scoped_pdu(SNMP_PKT_T *rp, EBUFFER_T *ebuffp){/* The scoped pdu sequence header */A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeLength(rp->scoped_pdu_length, A_EncodeHelper, (OCTET_T *)ebuffp);/* The context engine id */A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, EBufferStart(&(rp->msg_con_id)), EBufferUsed(&(rp->msg_con_id)), A_EncodeHelper, (OCTET_T *)ebuffp);/* The context name */A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, EBufferStart(&(rp->community)), EBufferUsed(&(rp->community)), A_EncodeHelper, (OCTET_T *)ebuffp);/* The pdu proper */encode_snmp_normal_pdu(rp, ebuffp);}/************************************************************************NAME: encode_snmp_v3PURPOSE: encode a snmp packet in structure form into a byte string according to the snmp v3 rulesPARAMETERS: SNMP_PKT_T * the packet to encode EBUFFER_T * the buffer to write the byte string toRETURNS: int 0 success, -1 error************************************************************************/int encode_snmp_v3(SNMP_PKT_T *rp, EBUFFER_T *ebuffp){bits8_t *digest_ptr, *start_ptr;ALENGTH_T start_len;/* save a pointer to the start of the packet for digesting */start_ptr = EBufferNext(ebuffp);start_len = EBufferUsed(ebuffp);/* The main sequence header */A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeLength(rp->overall_length, A_EncodeHelper, (OCTET_T *)ebuffp);/* The version tag */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->snmp_version, A_EncodeHelper, (OCTET_T *)ebuffp);/* The global data */A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeLength(rp->global_length, A_EncodeHelper, (OCTET_T *)ebuffp);/* the message id */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->msg_id, A_EncodeHelper, (OCTET_T *)ebuffp);/* the max message size */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->msg_max_size, A_EncodeHelper, (OCTET_T *)ebuffp);/* the message flags */A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, &rp->msg_flags, 1, A_EncodeHelper, (OCTET_T *)ebuffp);/* the security model */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->msg_sec_model, A_EncodeHelper, (OCTET_T *)ebuffp);/* The security parameters */A_EncodeType(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeLength(rp->security_length_2, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, A_EncodeHelper, (OCTET_T *)ebuffp);A_EncodeLength(rp->security_length, A_EncodeHelper, (OCTET_T *)ebuffp);/* the security engine id */A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, EBufferStart(&(rp->msg_sec_id)), EBufferUsed(&(rp->msg_sec_id)), A_EncodeHelper, (OCTET_T *)ebuffp);/* the boots field */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->msg_sec_boots, A_EncodeHelper, (OCTET_T *)ebuffp);/* the time field */A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->msg_sec_time, A_EncodeHelper, (OCTET_T *)ebuffp);/* The user name */A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, EBufferStart(&(rp->msg_sec_name)), EBufferUsed(&(rp->msg_sec_name)), A_EncodeHelper, (OCTET_T *)ebuffp);/* Encode the type for the auth string */A_EncodeType(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, A_EncodeHelper, (OCTET_T *)ebuffp);/* if we are authenticating save space for the digest, otherwise we have a 0 length string */if (rp->msg_flags & ETC_V3_AUTH) { A_EncodeLength(SNMP_Auth_Get_Need(rp->auth), A_EncodeHelper, (OCTET_T *)ebuffp); digest_ptr = EBufferNext(ebuffp); EBufferSeek(ebuffp, SNMP_Auth_Get_Need(rp->auth), 1); }else { digest_ptr = 0; A_EncodeLength(0, A_EncodeHelper, (OCTET_T *)ebuffp); }/* if we are encrypting save space for the encryption info, otherwise we have a 0 length string */if (rp->msg_flags & ETC_V3_PRIV) { bits8_t *security_ptr, *sec_buf; EBUFFER_T sec_ebuffp; /* allocate memory and construct the scoped pdu */ sec_buf = (bits8_t *)SNMP_memory_alloc(rp->encrypted_pdu_length); if (sec_buf == 0) return(-1); EBufferSetup(BFL_IS_DYNAMIC, &sec_ebuffp, sec_buf, rp->encrypted_pdu_length); encode_snmp_scoped_pdu(rp, &sec_ebuffp); /* and zero out any remaining space */ if (EBufferRemaining(&sec_ebuffp)) MEMSET(EBufferNext(&sec_ebuffp), 0, EBufferRemaining(&sec_ebuffp)); /* Encode the type and length for the encryption info, then save a pointer and skip the space. */ A_EncodeType(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, A_EncodeHelper, (OCTET_T *)ebuffp); A_EncodeLength(SNMP_Priv_Get_Need(rp->priv), A_EncodeHelper, (OCTET_T *)ebuffp); security_ptr = EBufferNext(ebuffp); EBufferSeek(ebuffp, SNMP_Priv_Get_Need(rp->priv), 1); /* Encode the type and length for the encrypted data then call the encryption routine, finally adjust the ebuff pointer and get rid of the security ebuffp */ A_EncodeType(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, A_EncodeHelper, (OCTET_T *)ebuffp); A_EncodeLength(rp->encrypted_pdu_length, A_EncodeHelper, (OCTET_T *)ebuffp); SNMP_Priv_Encode(rp->priv, rp->msg_sec_priv, SNMP_Priv_Get_KeySize(rp->priv), rp->msg_sec_boots, EBufferStart(&sec_ebuffp), rp->encrypted_pdu_length, security_ptr, EBufferNext(ebuffp)); EBufferSeek(ebuffp, rp->encrypted_pdu_length, 1); EBufferClean(&sec_ebuffp); }else { A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE, 0, 0, A_EncodeHelper, (OCTET_T *)ebuffp); encode_snmp_scoped_pdu(rp, ebuffp); }/* if we are digesting call the digest routine */if (rp->msg_flags & ETC_V3_AUTH) { (void) (SNMP_Auth_Digest(rp->auth, rp->msg_sec_auth, SNMP_Auth_Get_KeySize(rp->auth), start_ptr, (ALENGTH_T)(EBufferUsed(ebuffp) - start_len), digest_ptr)); }return(0);}/****************************************************************************NAME: Send_Report_PDUPURPOSE: Fill in the appropriate fields for a report pduPARAMETERS:RETURNS: SNMP_PKT_T * SNMP Packet structure, 0 on failure****************************************************************************/SNMP_PKT_T * Send_Report_PDU(SNMP_PKT_T *rp, LCL_FILE *in_stream, bits8_t auth_flag, OIDC_T *obj, int objlen, bits32_t value, int *error_ret, SNMPADDR_T *pktsrc, SNMPADDR_T *pktdst){/* have the user set the address information in case we do need to send a packet */if (SNMP_validate_address(rp, pktsrc, pktdst)) return(0);/* See if we can dig out the request id and pdu type, if we can we use them to decide what to do otherwise we use the report flag */if (auth_flag & 2) { /* The request id and pdu type have already been extracted */ if ((rp->pdu_type != GET_REQUEST_PDU) && (rp->pdu_type != GET_NEXT_REQUEST_PDU) && (rp->pdu_type != SET_REQUEST_PDU) && (rp->pdu_type != GET_BULK_REQUEST_PDU) && (rp->pdu_type != INFORM_REQUEST_PDU)) return(0); EBufferClean(&rp->msg_con_id); EBufferClean(&rp->community); }else if (in_stream && ((rp->msg_flags & ETC_V3_PRIV) == 0)) { ATVALUE_T asn_value; bits8_t asn_flag; ALENGTH_T asn_length; int asn_err = 0; /* Skip the context information */ if ((A_DecodeTypeClass(in_stream) != (A_UNIVERSAL | A_CONSTRUCTOR)) || (A_DecodeTypeValue(in_stream, &asn_err) != A_SEQUENCE)) asn_err = 1; asn_length = A_DecodeLength(in_stream, &asn_err); /* context engine id */ if ((A_DecodeTypeClass(in_stream) != (A_UNIVERSAL | A_PRIMITIVE)) || (A_DecodeTypeValue(in_stream, &asn_err) != A_OCTETSTRING)) asn_err = 1; asn_length = A_DecodeLength(in_stream, &asn_err); if (Lcl_Seek(in_stream, asn_length, 1)) asn_err = 1; /* context name */ if ((A_DecodeTypeClass(in_stream) != (A_UNIVERSAL | A_PRIMITIVE)) || (A_DecodeTypeValue(in_stream, &asn_err) != A_OCTETSTRING)) asn_err = 1; asn_length = A_DecodeLength(in_stream, &asn_err); if (Lcl_Seek(in_stream, asn_length, 1)) asn_err = 1; asn_flag = A_DecodeTypeClass(in_stream); asn_value = A_DecodeTypeValue(in_stream, &asn_err); asn_length = A_DecodeLength(in_stream, &asn_err); if ((asn_flag == (A_DEFAULT_SCOPE | A_CONSTRUCTOR)) && (asn_err == 0)){ if ((asn_value != GET_REQUEST_PDU) && (asn_value != GET_NEXT_REQUEST_PDU) && (asn_value != SET_REQUEST_PDU) && (asn_value != GET_BULK_REQUEST_PDU) && (asn_value != INFORM_REQUEST_PDU)) return(0); else rp->pdu.std_pdu.request_id = A_DecodeIntegerWTC(in_stream, &asn_err, A_INTEGER, A_UNIVERSAL | A_PRIMITIVE); } else { if ((rp->msg_flags & ETC_V3_REPORT) == 0) return(0); } }else { if ((rp->msg_flags & ETC_V3_REPORT) == 0) return(0); }/* Clean up any information about the current packet that we won't need, currently the engine id and the var bind list */EBufferClean(&rp->msg_sec_id);Clean_vb_list(&(rp->pdu.std_pdu.std_vbl));/* set up the packet as a report pdu, add our engine id, our mms, correct info for the auth stuff and, if necessary our context info */EBufferPreLoad(BFL_IS_STATIC, &rp->msg_sec_id, SNMP_Engine_Get_My_ID(), SNMP_Engine_Get_My_ID_Length());rp->msg_max_size = SNMP_MAX_PACKET_SIZE;if (auth_flag & 1) { rp->msg_flags = ETC_V3_AUTH; }else rp->msg_flags = 0;if (EBufferUsed(&rp->msg_con_id) == 0) { EBufferPreLoad(BFL_IS_STATIC, &rp->msg_con_id, SNMP_Engine_Get_My_ID(), SNMP_Engine_Get_My_ID_Length()); }rp->pdu_type = REPORT_PDU;rp->pdu.std_pdu.error_status = 0;rp->pdu.std_pdu.error_index = 0;/* allocate space for the var bind list and stuff the counter in */if ((rp->pdu.std_pdu.std_vbl.vblist = VarBindList_Allocate(1)) == 0) return(0);rp->pdu.std_pdu.std_vbl.vbl_count = 1;if (SNMP_Bind_Unsigned_Integer(rp, 0, objlen, obj, VT_COUNTER, value)) return(0);/* tag this as requiring a response to be sent */*error_ret = 1;return(rp);}/************************************************************************NAME: decode_scoped_pduPURPOSE: decode a scoped pdu packet the localio will point to the first byte of the scoped pdu.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -