?? asn1.c
字號:
*/ mask2 = ((u_long) 0x1FF) << ((8 * (sizeof(long) - 1)) - 1); /* mask2 is 0xFF800000 on a big-endian machine */ while((((high & mask2) == 0) || ((high & mask2) == mask2)) && intsize > 1){ intsize--; high = (high << 8) | ((low & mask) >> (8 * (sizeof(long) - 1))); low <<= 8; } }#ifdef OPAQUE_SPECIAL_TYPES/* encode a Counter64 as an opaque (it also works in SNMPv1) */ /* turn into Opaque holding special tagged value */ if (type == ASN_OPAQUE_COUNTER64) { /* put the tag and length for the Opaque wrapper */ data = asn_build_header(data, datalength, ASN_OPAQUE, intsize+3); if (_asn_build_header_check("build counter u64", data, *datalength, intsize+3)) return NULL; /* put the special tag and length */ *data++ = ASN_OPAQUE_TAG1; *data++ = ASN_OPAQUE_COUNTER64; *data++ = (u_char)intsize; *datalength = *datalength - 3; } else/* Encode the Unsigned int64 in an opaque */ /* turn into Opaque holding special tagged value */ if (type == ASN_OPAQUE_U64) { /* put the tag and length for the Opaque wrapper */ data = asn_build_header(data, datalength, ASN_OPAQUE, intsize+3); if (_asn_build_header_check("build opaque u64", data, *datalength, intsize+3)) return NULL; /* put the special tag and length */ *data++ = ASN_OPAQUE_TAG1; *data++ = ASN_OPAQUE_U64; *data++ = (u_char)intsize; *datalength = *datalength - 3; } else {#endif /* OPAQUE_SPECIAL_TYPES */ data = asn_build_header(data, datalength, type, intsize); if (_asn_build_header_check("build uint64", data, *datalength, intsize)) return NULL;#ifdef OPAQUE_SPECIAL_TYPES }#endif /* OPAQUE_SPECIAL_TYPES */ *datalength -= intsize; if (add_null_byte == 1){ *data++ = '\0'; intsize--; } while(intsize--){ *data++ = (u_char)((high & mask) >> (8 * (sizeof(long) - 1))); high = (high << 8) | ((low & mask) >> (8 * (sizeof(long) - 1))); low <<= 8; } return data;}#ifdef OPAQUE_SPECIAL_TYPES/* u_char * asn_parse_signed_int64( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char *type OUT - asn type of object struct counter64 *cp IN/OUT - pointer to counter struct int countersize IN - size of output buffer */u_char *asn_parse_signed_int64(u_char *data, size_t *datalength, u_char *type, struct counter64 *cp, size_t countersize){ static const char *errpre = "parse int64"; const int int64sizelimit = (4 * 2) + 1; char ebuf[128]; register u_char *bufp = data; u_long asn_length; register u_int low = 0, high = 0; if (countersize != sizeof(struct counter64)){ _asn_size_err(errpre, countersize, sizeof(struct counter64)); return NULL; } *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (_asn_parse_length_check(errpre, bufp, data, asn_length, *datalength)) return NULL; DEBUGDUMPSETUP("dump_recv", data, bufp - data); if ((*type == ASN_OPAQUE) && (asn_length <= ASN_OPAQUE_COUNTER64_MX_BER_LEN) && (*bufp == ASN_OPAQUE_TAG1) && (*(bufp+1) == ASN_OPAQUE_I64)) { DEBUGMSG(("dump_recv", "Opaque %.2x %.2x: ", *bufp, *(bufp+1))); /* change type to Int64 */ *type = *(bufp+1); /* value is encoded as special format */ bufp = asn_parse_length(bufp + 2, &asn_length); if (_asn_parse_length_check("parse opaque int64", bufp, data, asn_length, *datalength)) return NULL; } /* this should always have been true until snmp gets int64 PDU types */ else { sprintf(ebuf, "%s: wrong type: %d, len %d, buf bytes (%02X,%02X)", errpre, *type, (int)asn_length, *bufp, *(bufp+1)); ERROR_MSG(ebuf); return NULL; } if (((int)asn_length > int64sizelimit) || (((int)asn_length == int64sizelimit) && *bufp != 0x00)){ _asn_length_err(errpre, (size_t)asn_length, int64sizelimit); return NULL; } *datalength -= (int)asn_length + (bufp - data); if (*bufp & 0x80){ low = ~low; /* integer is negative */ high = ~high; } while(asn_length--){ high = (high << 8) | ((low & 0xFF000000) >> 24); low = (low << 8) | *bufp++; } cp->low = low; cp->high = high; DEBUGIF("dump_recv") { char i64buf[I64CHARSZ+1]; printI64(i64buf, cp); } return bufp;}/* u_char * asn_build_signed_int64( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char type IN - asn type of object struct counter64 *cp IN - pointer to counter struct int countersize IN - size of input buffer */u_char *asn_build_signed_int64(u_char *data, size_t *datalength, u_char type, struct counter64 *cp, size_t countersize){/* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */ struct counter64 c64; register u_int mask, mask2; u_long low, high; size_t intsize; if (countersize != sizeof(struct counter64)){ _asn_size_err("build int64", countersize, sizeof(struct counter64)); return NULL; } intsize = 8; memcpy(&c64, cp, sizeof(struct counter64)); /* we're may modify it */ low = c64.low; high = c64.high; /* * Truncate "unnecessary" bytes off of the most significant end of this * 2's complement integer. There should be no sequence of 9 * consecutive 1's or 0's at the most significant end of the * integer. */ mask = ((u_int) 0xFF) << (8 * (sizeof(u_int) - 1)); mask2 = ((u_int) 0x1FF) << ((8 * (sizeof(u_int) - 1)) - 1); /* mask is 0xFF800000 on a big-endian machine */ while((((high & mask2) == 0) || ((high & mask2) == mask2)) && intsize > 1){ intsize--; high = (high << 8) | ((low & mask) >> (8 * (sizeof(u_int) - 1))); low <<= 8; } /* until a real int64 gets incorperated into SNMP, we are going to encode it as an opaque instead. First, we build the opaque header and then the int64 tag type we use to mark it as an int64 in the opaque string. */ data = asn_build_header(data, datalength, ASN_OPAQUE, intsize+3); if (_asn_build_header_check("build int64", data, *datalength, intsize+3)) return NULL; *data++ = ASN_OPAQUE_TAG1; *data++ = ASN_OPAQUE_I64; *data++ = (u_char)intsize; *datalength -= (3 + intsize); while(intsize--){ *data++ = (u_char)((high & mask) >> (8 * (sizeof(u_int) - 1))); high = (high << 8) | ((low & mask) >> (8 * (sizeof(u_int) - 1))); low <<= 8; } return data;}/* * asn_parse_float - pulls a single precision floating-point out of an opaque 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. u_char * asn_parse_float( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char *type OUT - asn type of object float *floatp IN/OUT - pointer to float int floatsize IN - size of output buffer */u_char *asn_parse_float(u_char *data, size_t *datalength, u_char *type, float *floatp, size_t floatsize){ register u_char *bufp = data; u_long asn_length; union { float floatVal; long longVal; u_char c[sizeof(float)]; } fu; if (floatsize != sizeof(float)){ _asn_size_err("parse float", floatsize, sizeof(float)); return NULL; } *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (_asn_parse_length_check("parse float", bufp, data, asn_length, *datalength)) return NULL; DEBUGDUMPSETUP("dump_recv", data, bufp - data + asn_length);/* the float is encoded as an opaque */ if ((*type == ASN_OPAQUE) && (asn_length == ASN_OPAQUE_FLOAT_BER_LEN) && (*bufp == ASN_OPAQUE_TAG1) && (*(bufp+1) == ASN_OPAQUE_FLOAT)) { DEBUGMSG(("dump_recv", "Opaque %.2x %.2x: ", *bufp, *(bufp+1))); /* value is encoded as special format */ bufp = asn_parse_length(bufp + 2, &asn_length); if (_asn_parse_length_check("parse opaque float", bufp, data, asn_length, *datalength)) return NULL; /* change type to Float */ *type = ASN_OPAQUE_FLOAT; } if (asn_length != sizeof(float)) { _asn_size_err("parse seq float", asn_length, sizeof(float)); return NULL; } *datalength -= (int)asn_length + (bufp - data); memcpy(&fu.c[0], bufp, asn_length); /* correct for endian differences */ fu.longVal = ntohl(fu.longVal); *floatp = fu.floatVal; DEBUGMSG(("dump_recv", "%f",*floatp)); return bufp;}/* * asn_build_float - builds an ASN object containing a single precision floating-point * number in an Opaque value. * * 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. u_char * asn_build_float( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char type IN - asn type of object float *floatp IN - pointer to float int floatsize IN - size of input buffer */u_char *asn_build_float(u_char *data, size_t *datalength, u_char type, float *floatp, size_t floatsize){ union { float floatVal; int intVal; u_char c[sizeof(float)]; } fu; if (floatsize != sizeof (float)) { _asn_size_err("build float", floatsize, sizeof(float)); return NULL; }/* encode the float as an opaque */ /* turn into Opaque holding special tagged value */ /* put the tag and length for the Opaque wrapper */ data = asn_build_header(data, datalength, ASN_OPAQUE, floatsize+3); if (_asn_build_header_check("build float", data, *datalength, (floatsize+3))) return NULL; /* put the special tag and length */ *data++ = ASN_OPAQUE_TAG1; *data++ = ASN_OPAQUE_FLOAT; *data++ = (u_char)floatsize; *datalength = *datalength - 3; fu.floatVal = *floatp; /* correct for endian differences */ fu.intVal = htonl(fu.intVal); *datalength -= floatsize; memcpy(data, &fu.c[0], floatsize); data += floatsize; return data;}/* u_char * asn_parse_double( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char *type OUT - asn type of object double *doublep IN/OUT - pointer to double int doublesize IN - size of output buffer */u_char *asn_parse_double(u_char *data, size_t *datalength, u_char *type, double *doublep, size_t doublesize){ register u_char *bufp = data; u_long asn_length; long tmp; union { double doubleVal; int intVal[2]; u_char c[sizeof(double)]; } fu; if (doublesize != sizeof(double)){ _asn_size_err("parse double", doublesize, sizeof(double)); return NULL; } *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (_asn_parse_length_check("parse double", bufp, data, asn_length, *datalength)) return NULL; DEBUGDUMPSETUP("dump_recv", data, bufp - data + asn_length);/* the double is encoded as an opaque */ if ((*type == ASN_OPAQUE) && (asn_length == ASN_OPAQUE_DOUBLE_BER_LEN) && (*bufp == ASN_OPAQUE_TAG1) && (*(bufp+1) == ASN_OPAQUE_DOUBLE)) { DEBUGMSG(("dump_recv", "Opaque %.2x %.2x: ", *bufp, *(bufp+1))); /* value is encoded as special format */ bufp = asn_parse_length(bufp + 2, &asn_length); if (_asn_parse_length_check("parse opaque double", bufp, data, asn_length, *datalength)) return NULL; /* change type to Double */ *type = ASN_OPAQUE_DOUBLE; } if (asn_length != sizeof(double)) { _asn_size_err("parse seq double", asn_length, sizeof(double)); return NULL; } *datalength -= (int)asn_length + (bufp - data); memcpy(&fu.c[0], bufp, asn_length); /* correct for endian differences */ tmp = ntohl(fu.intVal[0]); fu.intVal[0] = ntohl(fu.intVal[1]); fu.intVal[1] = tmp; *doublep = fu.doubleVal; DEBUGMSG(("dump_recv", "%d",*doublep)); return bufp;}/* u_char * asn_build_double( u_char *data IN - pointer to start of object int *datalength IN/OUT - number of valid bytes left in buffer u_char type IN - asn type of object double *doublep IN - pointer to double int doublesize IN - size of input buffer */u_char *asn_build_double(u_char *data, size_t *datalength, u_char type, double* doublep, size_t doublesize){ long tmp; union { double doubleVal; int intVal[2]; u_char c[sizeof(double)]; } fu; if (doublesize != sizeof(double)){ _asn_size_err("build double", doublesize, sizeof(double)); return NULL; }/* encode the double as an opaque */ /* turn into Opaque holding special tagged value */ /* put the tag and length for the Opaque wrapper */ data = asn_build_header(data, datalength, ASN_OPAQUE, doublesize+3); if (_asn_build_header_check("build double", data, *datalength, doublesize+3)) return NULL; /* put the special tag and length */ *data++ = ASN_OPAQUE_TAG1; *data++ = ASN_OPAQUE_DOUBLE; *data++ = (u_char)doublesize; *datalength = *datalength - 3; fu.doubleVal = *doublep; /* correct for endian differences */ tmp = htonl(fu.intVal[0]); fu.intVal[0] = htonl(fu.intVal[1]); fu.intVal[1] = tmp; *datalength -= doublesize; memcpy(data, &fu.c[0], doublesize); data += doublesize; return data;}#endif /* OPAQUE_SPECIAL_TYPES */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -