📄 decode.c
字号:
ATVALUE_T id, bits8_t flags){bits8_t buff;if ((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id)) { if (*errp == 0) *errp = AE_WRONG_TYPE; return(0); }if ((A_DecodeLength(stream, errp) != 1) || *errp) { if (*errp == 0) *errp = AE_WRONG_LENGTH; return(0); }if (Lcl_Read(stream, &buff, 1) != 1) { *errp = AE_WRONG_LENGTH; return(0); }return(buff);}/********************A_DecodeIntegerDataPURPOSE: Pull an integer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the data field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor ALENGTH_T Length of contents field, from the ASN.1 header int * Receives an error code, if any.Returns: INT_32_T (See note below)NOTE: If the received value is really unsigned, then the caller shouldmerely cast the value returned by this procedure to an UINT_32_T.WARNING: If the integer occupies more than 4 octets, then high order precisionwill be lost, including the sign bit. For unsigned values in which thebasic value occupies all 4 octets, the sign octet, containing a zero signbit, will be lost but will not damage the returned value.********************/INT_32_T A_DecodeIntegerData(LCL_FILE *stream, ALENGTH_T length, int *errp){ INT_32_T ivalue = 0; int firstone = 1; OCTET_T oct; while(length-- != 0) { oct = (OCTET_T) Lcl_Getc(stream); if (Lcl_Eof(stream)) { *errp = AE_PREMATURE_END; return ivalue; } /* See whether we are receiving something that has the sign bit set, or if this is a 5 byte unsigned int check the first byte, it must be 0 */ if (firstone) { firstone = 0; if ((length == 4) && (oct != 0)) { *errp = AE_WRONG_VALUE; return ivalue; } if (oct & (OCTET_T)0x80) ivalue = (INT_32_T)-1; }/*lint -e703 */ ivalue <<= 8;/*lint +e703 */ ivalue |= oct; /* 'oct' better not be sign extended!!! */ } return ivalue;}/********************A_DecodeIntegerPURPOSE: Pull an integer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the integer's ASN.1 type field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor int * Receives an error code, if any.Returns: INT_32_T;********************/INT_32_T A_DecodeInteger(LCL_FILE *stream, int *errp){ ALENGTH_T int_length; (void) A_DecodeTypeValue(stream, errp); int_length = A_DecodeLength(stream, errp); if (*errp == 0) { if (int_length > 5) *errp = AE_WRONG_VALUE; else return A_DecodeIntegerData(stream, int_length, errp); } return(0);}/********************A_DecodeIntegerWTCPURPOSE: Pull an integer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the integer's ASN.1 type field. As we pull off the class and type we check them against the arguments to make sure they are correct. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor int * Receives an error code, if any. ATVALUE_T The type value OCTET_T A_IDC_MASK flag valuesReturns: INT_32_T;********************/INT_32_T A_DecodeIntegerWTC(LCL_FILE * stream, int * errp, ATVALUE_T id, OCTET_T flags){ ALENGTH_T int_length; if ((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id)) { if (*errp == 0) *errp = AE_WRONG_TYPE; return (0); } int_length = A_DecodeLength(stream, errp); if (*errp == 0) { if (int_length > 5) *errp = AE_WRONG_VALUE; else return A_DecodeIntegerData(stream, int_length, errp); } return(0);}/********************A_DecodeObjectIdDataPURPOSE: Pull an object identifier from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the data field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor ALENGTH_T Length of contents field, from the ASN.1 header OBJ_ID_T * Object identifier structure to receive the object id. The "component_list" will be "malloc"ed. component_list == (OIDC_T *)0 indicates that there is no component_list. int * Receives an error code, if any.Returns: Nothing********************/void A_DecodeObjectIdData(LCL_FILE *stream, ALENGTH_T length, OBJ_ID_T *objp, int *errp){ ALENGTH_T content_offset; /* Offset in stream where contents begins */ int left; /* Count of unused contents bytes */ int subids; /* Number of subidentifiers */ int subid_num; OIDC_T subid_val; /* Value of a subidentifier */ OIDC_T *cp; unsigned char c, first_c; objp->num_components = 0; objp->component_list = 0; /* Remember where the contents begins */ content_offset = Lcl_Tell(stream); /* Count the number of components */ for(subids = 0, left = (int)length; left > 0;) { first_c = (unsigned char)Lcl_Getc(stream); if (Lcl_Eof(stream)) { *errp = AE_PREMATURE_END; return; } left--; /* if its not the last (only) byte, step through the rest of the bytes */ if (first_c & 0x80) { int subid_bytes; /* number of bytes in this sub id */ int subid_done; /* flag to see if the sub id is finished */ for(subid_bytes = 2, subid_done = 0; left; subid_bytes++) { c = (unsigned char)Lcl_Getc(stream); if (Lcl_Eof(stream)) { *errp = AE_PREMATURE_END; return; } left--; if ((c & 0x80) == 0) { subid_done = 1; break; } } if ((subid_done == 0) || (subid_bytes > 5) || ((subid_bytes == 5) && (first_c > 0x8f))) { *errp = AE_WRONG_LENGTH; return; } } /* finally update the count of the subids */ subids++; if (subids > 128) { *errp = AE_WRONG_LENGTH; return; } } (void) Lcl_Seek(stream, content_offset, 0); /* Null object id if no subidentifier fields */ if (subids == 0) return; /* Try to get space for the components list */ cp = (OIDC_T *)SNMP_memory_alloc((unsigned int)(sizeof(OIDC_T) * (subids + 1))); if (cp == 0) { *errp = AE_ALLOC_FAILURE; return; } objp->num_components = subids + 1; objp->component_list = cp; /* Decode the subids and components */ for (subid_num = 0; subid_num < subids; subid_num++) { /* Decode the subidentifier */ for (subid_val = 0;;) { c = (unsigned char)Lcl_Getc(stream); if (Lcl_Eof(stream)) { *errp = AE_PREMATURE_END; SNMP_memory_free(objp->component_list); objp->component_list = 0; objp->num_components = 0; return; } subid_val <<= 7; subid_val |= (OIDC_T)(c & 0x7F); if (!(c & 0x80)) break; } /* Is this the first subidentifier? */ /* i.e. the one that contains TWO components? */ if (subid_num == 0) { if (subid_val < 40) { *cp++ = 0; *cp++ = subid_val; } else { if (subid_val < 80) { *cp++ = 1; *cp++ = subid_val - 40; } else { *cp++ = 2; *cp++ = subid_val - 80; } } } else { /* subid_num != 0, i.e. this is not the first subidentifier */ *cp++ = subid_val; } } return;}/********************A_DecodeObjectIdPURPOSE: Pull an object identifer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the object identifier's ASN.1 type field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor OBJ_ID_T * Object identifier structure to receive the object id. The "component_list" will be "malloc"ed. component_list == (OIDC_T *)0 indicates that there is no component_list. int * Receives an error code, if any. Returns: Nothing********************/void A_DecodeObjectId(LCL_FILE *stream, OBJ_ID_T *objp, int *errp){ ALENGTH_T leng; (void) A_DecodeTypeValue(stream, errp); leng = A_DecodeLength(stream, errp); if (*errp == 0) A_DecodeObjectIdData(stream, leng, objp, errp); return;}/********************A_DecodeObjectIdWTCPURPOSE: Pull an object identifer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the object identifier's ASN.1 type field. This version does type checking On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor OBJ_ID_T * Object identifier structure to receive the object id. The "component_list" will be "malloc"ed. component_list == (OIDC_T *)0 indicates that there is no component_list. int * Receives an error code, if any. ATVALUE_T The type value OCTET_T A_IDC_MASK flag values Returns: Nothing********************/void A_DecodeObjectIdWTC(LCL_FILE *stream, OBJ_ID_T *objp, int *errp, ATVALUE_T id, OCTET_T flags){ ALENGTH_T leng; if ((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id)) { if (*errp == 0) *errp = AE_WRONG_TYPE; return; } leng = A_DecodeLength(stream, errp); if (*errp == 0) A_DecodeObjectIdData(stream, leng, objp, errp); return;}/* We only install ui64 routine if the type is installed */#if (ENVOY_USE_V2_TYPES)/********************A_DecodeInteger64DataPURPOSE: Pull up to a 64 bit integer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the data field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor ALENGTH_T Length of contents field, from the ASN.1 header UINT_64_T * Space for the received int int * Receives an error code, if any.Returns: voidWARNING: If the integer occupies more than 8 octets, then high order precisionwill be lost, including the sign bit. For unsigned values in which thebasic value occupies all 8 octets, the sign octet, containing a zero signbit, will be lost but will not damage the returned value.********************/void A_DecodeInteger64Data(LCL_FILE *stream, ALENGTH_T length, UINT_64_T *value, int *errp){ int firstone = 1; OCTET_T oct; value->high = value->low = 0; while(length-- != 0) { oct = (OCTET_T) Lcl_Getc(stream); if (Lcl_Eof(stream)) { *errp = AE_PREMATURE_END; return; } /* See whether we are receiving something that has the sign bit set */ if (firstone) { firstone = 0; if ((length == 8) && (oct != 0)) { *errp = AE_WRONG_VALUE; return; } if (oct & (OCTET_T)0x80) { value->high = (UINT_32_T)0xFFFFFFFFL; value->low = (UINT_32_T)0xFFFFFFFFL; } } /* Decide which of the two words to put the octet into */ /* if length >= 4 we are working on the high order bytes */ /* equal sign is because we already decremented length */ if (length >= 4) { value->high <<= 8; value->high |= oct; /* 'oct' better not be sign extended!!! */ } else { value->low <<= 8; value->low |= oct; /* 'oct' better not be sign extended!!! */ } } return;}/********************A_DecodeInteger64PURPOSE: Pull up to a 64 bit integer from an ASN.1 stream. The data stream is read using the local I/O package. On entry stream pointer should be positioned to the first byte of the integer's ASN.1 type field. On exit, the stream pointer will be positioned to at the start of the next ASN.1 type field.PARAMETERS LCL_FILE * Stream descriptor UINT_64_T * Space to receive the int int * Receives an error code, if any.Returns: INT_32_T;********************/void A_DecodeInteger64(LCL_FILE * stream, UINT_64_T * value, int * errp){ ALENGTH_T int_length; (void) A_DecodeTypeValue(stream, errp); int_length = A_DecodeLength(stream, errp); if (*errp == 0) { if (int_length > 9) *errp = AE_WRONG_VALUE; else A_DecodeInteger64Data(stream, int_length, value, errp); } return;}#endif /* #if (ENVOY_USE_V2_TYPES) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -