⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1.cpp

📁 SNMP++程序源码 for ll .8snmp++2_8.tar.Z 嵌入式linux环境下的SNMP开发代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                                  int length){    if (*datalength < 1)	return NULL;    *data++ = type;    (*datalength)--;    return asn_build_length(data, datalength, length);    };/* * asn_build_sequence - builds an ASN header for a sequence with the ID and * length specified. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   in this object following the id and length. * *  This only works on data types < 30, i.e. no extension octets. *  The maximum length is 0xFFFF; * *  Returns a pointer to the first byte of the contents of this object. *  Returns NULL on any error. */unsigned char * asn_build_sequence( unsigned char *data,                                    int *datalength,                                    unsigned char type,                                    int length){    *datalength -= 4;    if (*datalength < 0){	*datalength += 4;	/* fix up before punting */	return NULL;    }    *data++ = type;    *data++ = (unsigned char)(0x02 | ASN_LONG_LEN);    *data++ = (unsigned char)((length >> 8) & 0xFF);    *data++ = (unsigned char)(length & 0xFF);    return data;};/* * asn_parse_length - interprets the length of the current object. *  On exit, length contains the value of this length field. * *  Returns a pointer to the first byte after this length *  field (aka: the start of the data field). *  Returns NULL on any error. */unsigned char * asn_parse_length( unsigned char *data,                                  unsigned long  *length){    unsigned char lengthbyte = *data;    if (lengthbyte & ASN_LONG_LEN){	lengthbyte &= ~ASN_LONG_LEN;	/* turn MSb off */	if (lengthbyte == 0){	    ASNERROR("We don't support indefinite lengths");	    return NULL;	}	if (lengthbyte > sizeof(long)){	    ASNERROR("we can't support data lengths that long");	    return NULL;	}	// fixed	memcpy((char *)length, (char *)data + 1, (int)lengthbyte);	*length = ntohl(*length);	*length >>= (8 * ((sizeof *length) - lengthbyte));	return data + lengthbyte + 1;    } else { /* short asnlength */	*length = (long)lengthbyte;	return data + 1;    }};unsigned char *asn_build_length( unsigned char *data,                                 int *datalength,                                 int length){    unsigned char    *start_data = data;    /* no indefinite lengths sent */    if (length < 0x80){	if (*datalength < 1){	    ASNERROR("build_length");	    return NULL;	}	    	*data++ = (unsigned char)length;    } else if (length <= 0xFF){	if (*datalength < 2){	    ASNERROR("build_length");	    return NULL;	}	    	*data++ = (unsigned char)(0x01 | ASN_LONG_LEN);	*data++ = (unsigned char)length;    } else { /* 0xFF < length <= 0xFFFF */	if (*datalength < 3){	    ASNERROR("build_length");	    return NULL;	}	    	*data++ = (unsigned char)(0x02 | ASN_LONG_LEN);	*data++ = (unsigned char)((length >> 8) & 0xFF);	*data++ = (unsigned char)(length & 0xFF);    }    *datalength -= (data - start_data);    return data;};/* * asn_parse_objid - pulls an object indentifier out of an ASN object identifier type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  "objid" is filled with the object identifier. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_parse_objid( unsigned char *data,                                int *datalength,                                unsigned char *type,                                oid *objid,                                int *objidlength){/* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */    unsigned char *bufp = data;    oid *oidp = objid + 1;    unsigned long subidentifier;    long   length;    unsigned long	    asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL)	return NULL;    if ((int)asn_length + (bufp - data) > *datalength){	ASNERROR("overflow of message");	return NULL;    }    *datalength -= (int)asn_length + (bufp - data);    /* Handle invalid object identifier encodings of the form 06 00 robustly */    if (asn_length == 0)	objid[0] = objid[1] = 0;    length = asn_length;    (*objidlength)--;	/* account for expansion of first byte */    while (length > 0 && (*objidlength)-- > 0){	subidentifier = 0;	do {	/* shift and add in low order 7 bits */	    subidentifier = (subidentifier << 7) + (*(unsigned char *)bufp & ~ASN_BIT8);	    length--;	} while (*(unsigned char *)bufp++ & ASN_BIT8);	/* last byte has high bit clear */	if (subidentifier > (unsigned long)MAX_SUBID){	    ASNERROR("subidentifier too long");	    return NULL;	}	*oidp++ = (oid)subidentifier;    }    /*     * The first two subidentifiers are encoded into the first component     * with the value (X * 40) + Y, where:     *	X is the value of the first subidentifier.     *  Y is the value of the second subidentifier.     */    subidentifier = (unsigned long)objid[1];    if (subidentifier == 0x2B){	objid[0] = 1;	objid[1] = 3;    } else {	objid[1] = (unsigned char)(subidentifier % 40);	objid[0] = (unsigned char)((subidentifier - objid[1]) / 40);    }    *objidlength = (int)(oidp - objid);    return bufp;};/* * asn_build_objid - Builds an ASN object identifier object containing the * input string. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_build_objid( unsigned char *data,                                int *datalength,                                unsigned char type,                                oid *objid,                                int objidlength){/* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */    unsigned char buf[MAX_OID_LEN];    unsigned char *bp = buf;    oid *op = objid;    int    asnlength;    unsigned long subid, mask, testmask;    int bits, testbits;    if (objidlength < 2){	*bp++ = 0;	objidlength = 0;    } else {	*bp++ = (unsigned char) (op[1] + (op[0] * 40));	objidlength -= 2;	op += 2;    }    while(objidlength-- > 0){	subid = *op++;	if (subid < 127){ /* off by one? */	    *bp++ = (unsigned char )subid;	} else {	    mask = 0x7F; /* handle subid == 0 case */	    bits = 0;	    /* testmask *MUST* !!!! be of an unsigned type */	    for(testmask = 0x7F, testbits = 0; testmask != 0;		testmask <<= 7, testbits += 7){		if (subid & testmask){	/* if any bits set */		    mask = testmask;		    bits = testbits;		}	    }	    /* mask can't be zero here */	    for(;mask != 0x7F; mask >>= 7, bits -= 7){		/* fix a mask that got truncated above */		if (mask == 0x1E00000)  		    mask = 0xFE00000;		*bp++ = (unsigned char)(((subid & mask) >> bits) | ASN_BIT8);	    }	    *bp++ = (unsigned char)(subid & mask);	}    }    asnlength = bp - buf;    data = asn_build_header(data, datalength, type, asnlength);    if (data == NULL)	return NULL;    if (*datalength < asnlength)	return NULL;	// fixed    memcpy((char *)data, (char *)buf,  asnlength);    *datalength -= asnlength;    return data + asnlength;};/* * asn_parse_null - Interprets an ASN null type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_parse_null(unsigned char	*data,                              int *datalength,                              unsigned char *type){/* * ASN.1 null ::= 0x05 0x00 */    unsigned char   *bufp = data;    unsigned long	    asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL)	return NULL;    if (asn_length != 0){	ASNERROR("Malformed NULL");	return NULL;    }    *datalength -= (bufp - data);    return bufp + asn_length;};/* * asn_build_null - Builds an ASN null object. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_build_null( unsigned char *data,                               int *datalength,                               unsigned char type){/* * ASN.1 null ::= 0x05 0x00 */    return asn_build_header(data, datalength, type, 0);};/* * asn_parse_bitstring - pulls a bitstring out of an ASN bitstring type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  "string" is filled with the bit string. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_parse_bitstring( unsigned char *data,                                    int *datalength,                                    unsigned char *type,                                    unsigned char *string,                                    int *strlength){/* * bitstring ::= 0x03 asnlength unused {byte}* */    unsigned char *bufp = data;    unsigned long	    asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL)	return NULL;    if ((int)(asn_length + (bufp - data)) > *datalength){	ASNERROR("overflow of message");	return NULL;    }    if ((int) asn_length > *strlength){	ASNERROR("I don't support such long bitstrings");	return NULL;    }    if (asn_length < 1){	ASNERROR("Invalid bitstring");	return NULL;    }    //if (*bufp < 0 || *bufp > 7){	//ASNERROR("Invalid bitstring");	//return NULL;    //}	// fixed    memcpy((char *)string,(char *)bufp,  (int)asn_length);    *strlength = (int)asn_length;    *datalength -= (int)asn_length + (bufp - data);    return bufp + asn_length;};/* * asn_build_bitstring - Builds an ASN bit string object containing the * input string. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_build_bitstring( unsigned char *data,                                    int *datalength,                                    unsigned char type,	                                    unsigned char *string,                                    int strlength){/* * ASN.1 bit string ::= 0x03 asnlength unused {byte}* */    //if (strlength < 1 || *string < 0 || *string > 7){	//ASNERROR("Building invalid bitstring");	//return NULL;    //}    data = asn_build_header(data, datalength, type, strlength);    if (data == NULL)	return NULL;    if (*datalength < strlength)	return NULL;	// fixed    memcpy((char *)data,(char *)string, strlength);    *datalength -= strlength;    return data + strlength;};/* * asn_parse_unsigned_int64 - pulls a 64 bit unsigned long out of an ASN int * type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char * asn_parse_unsigned_int64(  unsigned char *data,                                           int *datalength,                                           unsigned char *type,                                           struct counter64 *cp,                                           int countersize){/* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */    unsigned char *bufp = data;    unsigned long	    asn_length;    unsigned long low = 0, high = 0;    int intsize = 4;        if (countersize != sizeof(struct counter64)){	ASNERROR("not right size");	return NULL;    }    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL){	ASNERROR("bad length");	return NULL;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -