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

📄 asn1.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 5 页
字号:
         * 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 {        snprintf(ebuf, sizeof(ebuf),                "%s: wrong type: %d, len %d, buf bytes (%02X,%02X)",                errpre, *type, (int) asn_length, *bufp, *(bufp + 1));        ebuf[ sizeof(ebuf)-1 ] = 0;        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("dumpv_recv") {        char            i64buf[I64CHARSZ + 1];        printI64(i64buf, cp);        DEBUGMSG(("dumpv_recv", "Integer64: %s", i64buf));    }    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;#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    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;    }    DEBUGDUMPSETUP("send", initdatap, data - initdatap);    DEBUGIF("dumpv_send") {        char            i64buf[I64CHARSZ + 1];        printU64(i64buf, cp);        DEBUGMSG(("dumpv_send", i64buf));    }    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("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)) {        /*         * 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(("dumpv_recv", "Opaque float: %f\n", *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;#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    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);    DEBUGDUMPSETUP("send", initdatap, data - initdatap);    DEBUGMSG(("dumpv_send", "Opaque float: %f\n", *floatp));    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("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)) {        /*         * 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(("dumpv_recv", "  Opaque Double:\t%f\n", *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;#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    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;    /*     *

⌨️ 快捷键说明

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