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

📄 asn1.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 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.  u_char * asn_parse_length( u_char     *data         IN - pointer to start of length field u_long     *length       OUT - value of length field */u_char         *asn_parse_length(u_char * data, u_long * length){    static const char *errpre = "parse length";    char            ebuf[128];    register u_char lengthbyte;    if (!data || !length) {        ERROR_MSG("parse length: NULL pointer");        return NULL;    }    lengthbyte = *data;    if (lengthbyte & ASN_LONG_LEN) {        lengthbyte &= ~ASN_LONG_LEN;    /* turn MSb off */        if (lengthbyte == 0) {            snprintf(ebuf, sizeof(ebuf),                     "%s: indefinite length not supported", errpre);            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        if (lengthbyte > sizeof(long)) {            snprintf(ebuf, sizeof(ebuf),                    "%s: data length %d > %d not supported", errpre,                    lengthbyte, sizeof(long));            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        data++;        *length = 0;            /* protect against short lengths */        while (lengthbyte--) {            *length <<= 8;            *length |= *data++;        }        if ((long) *length < 0) {            snprintf(ebuf, sizeof(ebuf),                     "%s: negative data length %ld\n", errpre,                     (long) *length);            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        return data;    } else {                    /* short asnlength */        *length = (long) lengthbyte;        return data + 1;    }}/* *  * u_char * asn_build_length( * u_char     *data         IN - pointer to start of object * int        *datalength   IN/OUT - number of valid bytes left in buffer * int         length       IN - length of object */u_char         *asn_build_length(u_char * data, size_t * datalength, size_t length){    static const char *errpre = "build length";    char            ebuf[128];    u_char         *start_data = data;    /*     * no indefinite lengths sent      */    if (length < 0x80) {        if (*datalength < 1) {            snprintf(ebuf, sizeof(ebuf),                    "%s: bad length < 1 :%d, %d", errpre,                    *datalength, length);            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        *data++ = (u_char) length;    } else if (length <= 0xFF) {        if (*datalength < 2) {            snprintf(ebuf, sizeof(ebuf),                    "%s: bad length < 2 :%d, %d", errpre,                    *datalength, length);            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        *data++ = (u_char) (0x01 | ASN_LONG_LEN);        *data++ = (u_char) length;    } else {                    /* 0xFF < length <= 0xFFFF */        if (*datalength < 3) {            snprintf(ebuf, sizeof(ebuf),                    "%s: bad length < 3 :%d, %d", errpre,                    *datalength, length);            ebuf[ sizeof(ebuf)-1 ] = 0;            ERROR_MSG(ebuf);            return NULL;        }        *data++ = (u_char) (0x02 | ASN_LONG_LEN);        *data++ = (u_char) ((length >> 8) & 0xFF);        *data++ = (u_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.  u_char * asn_parse_objid( 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 oid        *objid        IN/OUT - pointer to start of output buffer int        *objidlength  IN/OUT - number of sub-id's in objid */u_char         *asn_parse_objid(u_char * data,                size_t * datalength,                u_char * type, oid * objid, size_t * objidlength){    /*     * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*     * subidentifier ::= {leadingbyte}* lastbyte     * leadingbyte ::= 1 7bitvalue     * lastbyte ::= 0 7bitvalue     */    register u_char *bufp = data;    register oid   *oidp = objid + 1;    register u_long subidentifier;    register long   length;    u_long          asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (_asn_parse_length_check("parse objid", bufp, data,                                asn_length, *datalength))        return NULL;    *datalength -= (int) asn_length + (bufp - data);    DEBUGDUMPSETUP("recv", data, bufp - data + asn_length);    /*     * 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) + (*(u_char *) bufp & ~ASN_BIT8);            length--;        } while (*(u_char *) bufp++ & ASN_BIT8);        /* last byte has high bit clear */        /*         * ?? note, this test will never be true, since the largest value         * of subidentifier is the value of MAX_SUBID!          */        if (subidentifier > (u_long) MAX_SUBID) {            ERROR_MSG("subidentifier too large");            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 = (u_long) objid[1];    if (subidentifier == 0x2B) {        objid[0] = 1;        objid[1] = 3;    } else {        if (subidentifier < 40) {            objid[0] = 0;            objid[1] = subidentifier;        } else if (subidentifier < 80) {            objid[0] = 1;            objid[1] = subidentifier - 40;        } else {            objid[0] = 2;            objid[1] = subidentifier - 80;        }    }    *objidlength = (int) (oidp - objid);    DEBUGMSG(("dumpv_recv", "  ObjID: "));    DEBUGMSGOID(("dumpv_recv", objid, *objidlength));    DEBUGMSG(("dumpv_recv", "\n"));    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.  u_char * asn_build_objid( u_char     *data         IN - pointer to start of object int        *datalength   IN/OUT - number of valid bytes left in buffer int        type         IN - asn type of object oid        *objid        IN - pointer to start of input buffer int         objidlength  IN - number of sub-id's in objid */u_char         *asn_build_objid(u_char * data,                size_t * datalength,                u_char type, oid * objid, size_t objidlength){    /*     * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*     * subidentifier ::= {leadingbyte}* lastbyte     * leadingbyte ::= 1 7bitvalue     * lastbyte ::= 0 7bitvalue     */    size_t          asnlength;    register oid   *op = objid;    u_char          objid_size[MAX_OID_LEN];    register u_long objid_val;    u_long          first_objid_val;    register int    i;#ifndef SNMP_NO_DEBUGGING    u_char         *initdatap = data;#endif    /*     * check if there are at least 2 sub-identifiers      */    if (objidlength == 0) {        /*         * there are not, so make OID have two with value of zero          */        objid_val = 0;        objidlength = 2;    } else if (objid[0] > 2) {        ERROR_MSG("build objid: bad first subidentifier");        return NULL;    } else if (objidlength == 1) {        /*         * encode the first value          */        objid_val = (op[0] * 40);        objidlength = 2;        op++;    } else {        /*         * combine the first two values          */        if ((op[1] > 40) &&            (op[0] < 2)) {            ERROR_MSG("build objid: bad second subidentifier");            return NULL;        }        objid_val = (op[0] * 40) + op[1];        op += 2;    }    first_objid_val = objid_val;    /*     * ditch illegal calls now      */    if (objidlength > MAX_OID_LEN)        return NULL;    /*     * calculate the number of bytes needed to store the encoded value      */    for (i = 1, asnlength = 0;;) {        if (objid_val < (unsigned) 0x80) {            objid_size[i] = 1;            asnlength += 1;        } else if (objid_val < (unsigned) 0x4000) {            objid_size[i] = 2;            asnlength += 2;        } else if (objid_val < (unsigned) 0x200000) {            objid_size[i] = 3;            asnlength += 3;        } else if (objid_val < (unsigned) 0x10000000) {            objid_size[i] = 4;            asnlength += 4;        } else {            objid_size[i] = 5;            asnlength += 5;        }        i++;        if (i >= (int) objidlength)            break;        objid_val = *op++;	/* XXX - doesn't handle 2.X (X > 40) */    }    /*     * store the ASN.1 tag and length      */    data = asn_build_header(data, datalength, type, asnlength);    if (_asn_build_header_check        ("build objid", data, *datalength, asnlength))        return NULL;    /*     * store the encoded OID value      */    for (i = 1, objid_val = first_objid_val, op = objid + 2;         i < (int) objidlength; i++) {        if (i != 1)            objid_val = *op++;        switch (objid_size[i]) {        case 1:            *data++ = (u_char) objid_val;            break;        case 2:            *data++ = (u_char) ((objid_val >> 7) | 0x80);            *data++ = (u_char) (objid_val & 0x07f);            break;        case 3:            *data++ = (u_char) ((objid_val >> 14) | 0x80);            *data++ = (u_char) ((objid_val >> 7 & 0x7f) | 0x80);            *data++ = (u_char) (objid_val & 0x07f);            break;        case 4:            *data++ = (u_char) ((objid_val >> 21) | 0x80);            *data++ = (u_char) ((objid_val >> 14 & 0x7f) | 0x80);            *data++ = (u_char) ((objid_val >> 7 & 0x7f) | 0x80);            *data++ = (u_char) (objid_val & 0x07f);            break;        case 5:            *data++ = (u_char) ((objid_val >> 28) | 0x80);            *data++ = (u_char) ((objid_val >> 21 & 0x7f) | 0x80);            *data++ = (u_char) ((objid_val >> 14 & 0x7f) | 0x80);            *data++ = (u_char) ((objid_val >> 7 & 0x7f) | 0x80);            *data++ = (u_char) (objid_val & 0x07f);            break;        }    }    /*     * return the length and data ptr      */    *datalength -= asnlength;    DEBUGDUMPSETUP("send", initdatap, data - initdatap);    DEBUGMSG(("dumpv_send", "  ObjID: "));    DEBUGMSGOID(("dumpv_send", objid, objidlength));    DEBUGMSG(("dumpv_send", "\n"));    return data;}/* * 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.  u_char * asn_parse_null( 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 */u_char         *asn_parse_null(u_char * data, size_t * datalength, u_char * type){    /*     * ASN.1 null ::= 0x05 0x00     */    register u_char *bufp = data;    u_long          asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL) {        ERROR_MSG("parse null: bad length");        return NULL;    }    if (asn_length != 0) {        ERROR_MSG("parse null: malformed ASN.1 null");        return NULL;    }    *datalength -= (bufp - data);    DEBUGDUMPSETUP("recv", data, bufp - data);    DEBUGMSG(("dumpv_recv", "  NULL\n"));    return bufp + asn_length;

⌨️ 快捷键说明

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