📄 decode.c
字号:
/* * Copyright 2000-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//* * Copyright 1986-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. *//* * $Log: decode.c,v $ * Revision 1.4 2002/03/01 18:33:03 josh * don't allow object ids with more than 128 subids * * Revision 1.3 2002/02/26 21:36:11 josh * we only have 16 bits for length -- discard anything longer * * Revision 1.2 2001/11/06 21:20:07 josh * revised new path hacking * * Revision 1.1.1.1 2001/11/05 17:47:42 tneale * Tornado shuffle * * Revision 9.3 2001/01/19 22:22:20 paul * Update copyright. * * Revision 9.2 2000/03/17 00:19:03 meister * Update copyright message * * Revision 9.1 1999/11/03 18:42:21 sar * Add some more checks for odd asn.1 encodings such as overlong integers * or broken object ids. * * Revision 9.0 1998/10/16 22:11:21 sar * Update version stamp to match release * * Revision 8.6 1998/06/22 03:11:11 sar * Changed the type used for lengths in localio. We now use ALENGTH_Ts * to make it match the rest of the code and keep compilers happy * * Revision 8.5 1998/06/19 20:13:50 sar * make sure all files include asn1conf.h and snmp.h to pick up all of * the common code * * Revision 8.4 1998/06/05 18:53:11 sra * "#include <foo.h>" => "#include <envoy/h/foo.h>". * * Revision 8.3 1998/05/29 04:31:10 sar * Add and use defines for v2 types and v2 protocol pieces. This allows * us to include the types and pieces for other versions, such as v3, * without having to touch all of the seperate files that use the * types or pieces. * * Revision 8.2 1998/05/24 04:42:21 sar * Fixed a possible memory leak in a_decodeOctetStringData - if the asn1 length * field exceeded the remaining packet length we could leak memory. * * Revision 8.1 1998/02/25 04:51:41 sra * Update copyrights. * * Revision 8.0 1997/11/18 00:56:47 sar * Updated revision to 8.0 * * Revision 7.2 1997/03/20 06:48:51 sra * DFARS-safe copyright text. Zap! * * Revision 7.1 1997/02/25 10:49:26 sra * Update copyright notice, dust under the bed. * * Revision 7.0 1996/03/18 20:01:11 sar * Updated revision to 7.0 and copyright to 96 * * Revision 6.1 1995/10/20 23:02:48 sar * removed no_pp stuff, casts of zero and bitstring routines * * Revision 6.0 1995/05/31 21:47:20 sra * Release 6.0. * * Revision 5.1 1994/09/29 18:37:21 sar * If we aren't using the v2 types remove the code to handle them mostly * this means ifdef the code. In mibutils.c and snmp_d.c we need to * examine the version of the packet in some cases to reject v2 types for * a v1 packet when both v1 and v2 are installed. * * Revision 5.0 1994/05/16 15:42:42 sar * Updated revision to 5.0 and copyright to include 1994 * * Revision 4.4 1994/05/04 22:45:43 sar * Corrected name of a routine, the WTC had been left off. * * Revision 4.3 1994/05/02 17:02:30 sar * Added new decode routines *WTC (with type check) to type check the string * as it is being decoded. Mostly these will be used in snmp_d.c * * Revision 4.2 1994/04/29 21:30:03 sar * Added a check in the decode integer data routine to make sure that * the 5th byte of unsigned integers == 0. * * Revision 4.1 1993/09/30 20:41:13 sar * Corrected the test for acceptable number of unused bits in decoding * a bit string. * * Revision 4.0 1993/06/24 15:45:46 sar * Updated revision to 4.0 and copyright to 93 * * Revision 3.5 1993/06/17 23:33:44 sar * Fixed the decodebitstring routine. * * Revision 3.4 1993/06/13 02:41:25 sar * fixed a BISTRING to be BITSTRING. * * Revision 3.3 1993/04/26 20:37:09 sar * Added ifdefs to allow clean makes of version 1 and 2, added bit strings, * arrange for deletion of acls with the party or context they refer to * is deleted. * * Revision 3.2 1993/03/25 21:18:09 sar * Added routines to encode/decode 64 bit integers/counter64s * * Revision 3.1 1992/06/16 15:58:41 dab * Got rid of the "then"s. * * Revision 3.0 92/04/03 19:52:37 dab * Release 3.0 * * Revision 2.104 92/02/05 18:46:19 dab * More casting to keep MSC happy. * * Revision 2.103 91/10/30 20:41:56 dab * Directly include asn1conf.h, snmpdefs.h, and snmpstat.h (if needed). * * Revision 2.102 91/09/18 12:32:13 dab * Updated to use new macros from <asn1conf.h> and <snmpconf.h>. * * Revision 2.101 91/08/15 12:30:58 dab * Removed <libfuncs.h>. * * Revision 2.100 91/08/09 14:08:19 dab * Update version. * * Revision 1.1 91/07/30 02:23:35 romkey * Initial revision * * * Rev 2.0 31 Mar 1990 15:06:44 * Release 2.00 * * Rev 1.9 14 Dec 1989 16:00:48 * Added support for Borland Turbo C compiler * * Rev 1.8 04 Jul 1989 12:03:38 * DecodeIntegerData() was improperly decoding negative integers * when the length was less than 4 bytes. * * Rev 1.7 27 Apr 1989 15:56:00 * Removed unused variables * * Rev 1.6 12 Apr 1989 12:02:40 * Added cast on value returned by SNMP_mem_alloc(). * * Rev 1.5 23 Mar 1989 11:55:56 * Merged the decode helper into the one routine that used it. * * Rev 1.4 18 Mar 1989 11:56:42 * Unused octet string handling code removed. * Octet string decoding simplified and hardened against zero length strings. * * Rev 1.3 17 Mar 1989 21:41:56 * Calls to memcpy/memset protected against zero lengths * * Rev 1.2 19 Sep 1988 17:26:54 * Made changes to make the Sun C compiler happy. * * Rev 1.1 14 Sep 1988 17:54:20 * Removed improper casts in calls to SNMP_mem_alloc(). * Also moved includes of system includes into libfunc.h. * * Rev 1.0 12 Sep 1988 10:46:56 * Initial revision.*//* [clearcase]modification history-------------------01d,20may05,job need a more lenient decode on length fields01c,12may05,job fix apigen comments01b,18apr05,job update copyright notices01a,24nov03,job update copyright information*/#include <wrn/wm/snmp/engine/asn1conf.h>#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/localio.h>#include <wrn/wm/snmp/engine/decode.h>#include <wrn/wm/snmp/engine/buffer.h>/****************************************************************************NAME: A_DecodeTypeValuePURPOSE: Decode the numeric part of an ASN.1 type from a stream. The data stream is read using the local I/O package. On exit, the stream pointer will be positioned to the byte *AFTER* the type.NOTE: The Class portion of the type is NOT decoded here, only the value portion. The user should call A_DecodeTypeClass *BEFORE* calling this routine in order to get the class.PARAMETERS: LCL_FILE * A stream descriptor (already open) int * Receives an error code, if any.RETURNS: ATVALUE_T The type valueRESTRICTIONS: It is assumed that the stream does not reach EOF before the end of the field.****************************************************************************/ATVALUE_T A_DecodeTypeValue(LCL_FILE * lfile, int * errp){ register OCTET_T oct; oct = (OCTET_T) (Lcl_Getc(lfile) & ~A_IDCF_MASK); if (Lcl_Eof(lfile)) { *errp = AE_PREMATURE_END; return (ATVALUE_T) 0; } if (oct != 0x1F) { /* Are there extension bytes? */ /* No extensions, type is in oct */ return (ATVALUE_T) oct; } else { /* Type is in extension octets */ register ATVALUE_T t = 0; for(;;) { oct = (OCTET_T)Lcl_Getc(lfile); if (Lcl_Eof(lfile)) { *errp = AE_PREMATURE_END; return t; } if (!(oct & 0x80)) break; /* Hit final byte, we'll use*/ /* it at the end of the loop*/ t |= (ATVALUE_T)(oct & 0x7F); /* Deal with a non-final byte */ t <<= 7; } t |= (ATVALUE_T) oct; /* Take care of the final byte (the one */ /* without the 0x80 continuation bit.) */ return t; }/*NOTREACHED*/}/****************************************************************************NAME: A_DecodeLengthPURPOSE: Decode an ASN.1 length from a stream. The data stream is read using the local I/O package. On exit, the stream pointer will be positioned to the byte *AFTER* the length.PARAMETERS: LCL_FILE * Stream descriptor int * Receives an error code, if any.RETURNS: ALENGTH_T -- the length. If the length is indefinite, (ALENGTH_T)-1 is returned.RESTRICTIONS: The stream must be open. It is assumed that the stream will not reach EOF before the length is decoded.****************************************************************************/ALENGTH_T A_DecodeLength(LCL_FILE * lfile, int * errp){ OCTET_T oct; oct = (OCTET_T)Lcl_Getc(lfile); if (Lcl_Eof(lfile)) { *errp = AE_PREMATURE_END; return (ALENGTH_T) 0; } /* Indefinite form? */ if (oct == 0x80) { *errp = AE_INDEFINITE_LENGTH; return (ALENGTH_T) -1; } if (!(oct & 0x80)) /* Short or long format? */ return (ALENGTH_T) oct; /* Short format */ else { /* Long format */ register OCTET_T lsize; register ALENGTH_T len = 0; lsize = oct & (OCTET_T)0x7F; /* Get # of bytes comprising length field */ while (lsize-- != 0) { /* We need to prevent the length field from overflowing */ if (len == (len & 0xff)) { len <<= 8; len |= (OCTET_T)Lcl_Getc(lfile); if (Lcl_Eof(lfile)) { *errp = AE_PREMATURE_END; return (ALENGTH_T) 0; } } else { *errp = AE_INDEFINITE_LENGTH; return (ALENGTH_T) -1; } } return len; } /*NOTREACHED*/}/********************A_DecodeOctetStringDataPURPOSE: Pull an octet string 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 octet string, from its ASN.1 header EBUFFER_T * Control structure to receive the data. int * Receives an error code, if any.Returns: NothingNote: On return, the "start_bp" component of the buffer structure points to a "malloc"-ed area in which the octet string is held. Note that the octet string is NOT null terminated, may contain internal nulls. A null pointer, (char *)0, is used if no area is malloc-ed. If the string is of zero length, a dummy buffer is established which appears to be have a static buffer of length zero at address zero.********************/void A_DecodeOctetStringData(LCL_FILE *stream, ALENGTH_T length, EBUFFER_T *ebuffp, int *errp){bits8_t *buffp;ALENGTH_T got;if ((length != 0) && (length != (ALENGTH_T) -1)) { if ((buffp = (OCTET_T *)SNMP_memory_alloc(length)) == 0) { *errp = AE_ALLOC_FAILURE; EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); return; } got = Lcl_Read(stream, buffp, length); if (got == length) { EBufferPreLoad(BFL_IS_DYNAMIC, ebuffp, buffp, length); return; } else { SNMP_memory_free(buffp); *errp = AE_PREMATURE_END; EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); } }else { /* Length is either zero or indeterminate */ EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); }}/********************A_DecodeOctetStringPURPOSE: Pull an octet string 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 octet string's 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 EBUFFER_T * Control structure to receive the data. int * Receives an error code, if any.Returns: NothingNote: On return, the "start_bp" component of the buffer structure points to a "malloc"-ed area in which the octet string is held. Note that the octet string is NOT null terminated, may contain internal nulls. A null pointer, (char *)0, is used if no area is malloc-ed.********************/void A_DecodeOctetString(LCL_FILE *stream, EBUFFER_T *ebuffp, int *errp){ ALENGTH_T os_length; (void) A_DecodeTypeValue(stream, errp); os_length = A_DecodeLength(stream, errp); if (*errp == 0) { A_DecodeOctetStringData(stream, os_length, ebuffp, errp); } else { /* On a decoding error, pretend we have a zero length string */ EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); }}/********************A_DecodeOctetStringWTCPURPOSE: Pull an octet string 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 octet string's 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 EBUFFER_T * Control structure to receive the data. int * Receives an error code, if any. ATVALUE_T The type value OCTET_T A_IDC_MASK flag valuesReturns: NothingNote: On return, the "start_bp" component of the buffer structure points to a "malloc"-ed area in which the octet string is held. Note that the octet string is NOT null terminated, may contain internal nulls. A null pointer, (char *)0, is used if no area is malloc-ed.********************/void A_DecodeOctetStringWTC(LCL_FILE * stream, EBUFFER_T * ebuffp, int * errp, ATVALUE_T id, OCTET_T flags){ ALENGTH_T os_length; if ((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id)) { if (*errp == 0) *errp = AE_WRONG_TYPE; /* On a decoding error, pretend we have a zero length string */ EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); return; } os_length = A_DecodeLength(stream, errp); if (*errp == 0) { A_DecodeOctetStringData(stream, os_length, ebuffp, errp); } else { /* On a decoding error, pretend we have a zero length string */ EBufferPreLoad(BFL_IS_STATIC, ebuffp, 0, 0); }}/********************A_DecodeOctetWTCPURPOSE: Pull a single octet 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 octet string's 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. An error will be generated if the octet string is longer than 1.PARAMETERS LCL_FILE * Stream descriptor int * Receives an error code, if any. ATVALUE_T The type value bits8_t A_IDC_MASK flag valuesReturns: bits8_t the octet from the stream.********************/bits8_t A_DecodeOctetWTC(LCL_FILE * stream, int * errp,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -