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

📄 asn1.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* * 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.  u_char * asn_build_null( 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 */u_char         *asn_build_null(u_char * data, size_t * datalength, u_char type){    /*     * ASN.1 null ::= 0x05 0x00     */#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    data = asn_build_header(data, datalength, type, 0);    DEBUGDUMPSETUP("send", initdatap, data - initdatap);    DEBUGMSG(("dumpv_send", "  NULL\n"));    return data;}/* * 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.  u_char * asn_parse_bitstring( u_char     *data         IN - pointer to start of object size_t     *datalength   IN/OUT - number of valid bytes left in buffer u_char     *type         OUT - asn type of object u_char     *string       IN/OUT - pointer to start of output buffer size_t     *strlength    IN/OUT - size of output buffer */u_char         *asn_parse_bitstring(u_char * data,                    size_t * datalength,                    u_char * type, u_char * string, size_t * strlength){    /*     * bitstring ::= 0x03 asnlength unused {byte}*     */    static const char *errpre = "parse bitstring";    register u_char *bufp = data;    u_long          asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (_asn_parse_length_check(errpre, bufp, data,                                asn_length, *datalength))        return NULL;    if ((size_t) asn_length > *strlength) {        _asn_length_err(errpre, (size_t) asn_length, *strlength);        return NULL;    }    if (_asn_bitstring_check(errpre, asn_length, *bufp))        return NULL;    DEBUGDUMPSETUP("recv", data, bufp - data);    DEBUGMSG(("dumpv_recv", "  Bitstring: "));    DEBUGMSGHEX(("dumpv_recv", data, asn_length));    DEBUGMSG(("dumpv_recv", "\n"));    memmove(string, bufp, 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.  u_char * asn_build_bitstring( 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 u_char     *string       IN - pointer to start of input buffer int         strlength    IN - size of input buffer */u_char         *asn_build_bitstring(u_char * data,                    size_t * datalength,                    u_char type, u_char * string, size_t strlength){    /*     * ASN.1 bit string ::= 0x03 asnlength unused {byte}*     */    static const char *errpre = "build bitstring";    if (_asn_bitstring_check        (errpre, strlength, ((string) ? *string : (u_char) 0)))        return NULL;    data = asn_build_header(data, datalength, type, strlength);    if (_asn_build_header_check(errpre, data, *datalength, strlength))        return NULL;    if (strlength > 0 && string)        memmove(data, string, strlength);    else if (strlength > 0 && !string) {        ERROR_MSG("no string passed into asn_build_bitstring\n");        return NULL;    }    *datalength -= strlength;    DEBUGDUMPSETUP("send", data, strlength);    DEBUGMSG(("dumpv_send", "  Bitstring: "));    DEBUGMSGHEX(("dumpv_send", data, strlength));    DEBUGMSG(("dumpv_send", "\n"));    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.  u_char * asn_parse_unsigned_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_unsigned_int64(u_char * data,                         size_t * datalength,                         u_char * type,                         struct counter64 * cp, size_t countersize){    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    static const char *errpre = "parse uint64";    const int       uint64sizelimit = (4 * 2) + 1;    register u_char *bufp = data;    u_long          asn_length;    register u_long 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("recv", data, bufp - data);#ifdef OPAQUE_SPECIAL_TYPES    /*     * 64 bit counters as opaque      */    if ((*type == ASN_OPAQUE) &&        (asn_length <= ASN_OPAQUE_COUNTER64_MX_BER_LEN) &&        (*bufp == ASN_OPAQUE_TAG1) &&        ((*(bufp + 1) == ASN_OPAQUE_COUNTER64) ||         (*(bufp + 1) == ASN_OPAQUE_U64))) {        /*         * change type to Counter64 or U64          */        *type = *(bufp + 1);        /*         * value is encoded as special format          */        bufp = asn_parse_length(bufp + 2, &asn_length);        if (_asn_parse_length_check("parse opaque uint64", bufp, data,                                    asn_length, *datalength))            return NULL;    }#endif                          /* OPAQUE_SPECIAL_TYPES */    if (((int) asn_length > uint64sizelimit) ||        (((int) asn_length == uint64sizelimit) && *bufp != 0x00)) {        _asn_length_err(errpre, (size_t) asn_length, uint64sizelimit);        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];        printU64(i64buf, cp);        DEBUGMSG(("dumpv_recv", "Counter64: ", i64buf));    }    return bufp;}/* * asn_build_unsigned_int64 - builds an ASN object containing a 64 bit integer. *  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_unsigned_int64( u_char     *data         IN - pointer to start of output buffer size_t     *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 size_t      countersize  IN - size of input buffer */u_char         *asn_build_unsigned_int64(u_char * data,                         size_t * datalength,                         u_char type,                         struct counter64 * cp, size_t countersize){    /*     * ASN.1 integer ::= 0x02 asnlength byte {byte}*     */    register u_long low, high;    register u_long mask, mask2;    int             add_null_byte = 0;    size_t          intsize;#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    if (countersize != sizeof(struct counter64)) {        _asn_size_err("build uint64", countersize,                      sizeof(struct counter64));        return NULL;    }    intsize = 8;    low = cp->low;    high = cp->high;    mask = ((u_long) 0xFF) << (8 * (sizeof(long) - 1));    /*     * mask is 0xFF000000 on a big-endian machine      */    if ((u_char) ((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80) {        /*         * if MSB is set          */        add_null_byte = 1;        intsize++;    } else {        /*         * 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.         */        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;    }    DEBUGDUMPSETUP("send", initdatap, data - initdatap);    DEBUGIF("dumpv_send") {        char            i64buf[I64CHARSZ + 1];        printU64(i64buf, cp);        DEBUGMSG(("dumpv_send", i64buf));    }    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("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)) {        /*         * change type to Int64          */        *type = *(bufp + 1);        /*

⌨️ 快捷键说明

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