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

📄 smux.c

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
        } else if (result < 0) {            /*             * this can only happen if we go before the head              */            add->sr_next = *head;            *head = add;            return 0;        } else if ((snmp_oid_compare(add->sr_name, add->sr_name_len,                                     rptr->sr_next->sr_name,                                     rptr->sr_next->sr_name_len)) < 0) {            /*             * insert here              */            add->sr_next = rptr->sr_next;            rptr->sr_next = add;            return 0;        }        prev = rptr;    }    /*     * compare the last one      */    result = snmp_oid_compare(add->sr_name, add->sr_name_len, rptr->sr_name, rptr->sr_name_len);    if ((result == 0) && add->sr_priority == rptr->sr_priority)        return -1;    else  if (result < 0 ) {        add->sr_next = rptr;        if ( prev ) {            prev->sr_next = add;        } else {            *head = add;        }    } else {        rptr->sr_next = add;        add->sr_next = NULL;    }    return 0;}/* * Find a replacement for this registration.  In order * of preference: * *      - Least difference in subtree length *      - Best (lowest) priority * * For example, if we need to replace .1.3.6.1.69,  * we would pick .1.3.6.1.69.1 instead of .1.3.6.69.1.1 * */static smux_reg *smux_find_replacement(oid * name, size_t name_len){    smux_reg       *rptr, *bestptr;    int             bestlen, difflen;    bestlen = SMUX_MAX_PRIORITY;    bestptr = NULL;    for (rptr = PassiveRegs; rptr; rptr = rptr->sr_next) {        if (!snmp_oidtree_compare(rptr->sr_name, rptr->sr_name_len,                                  name, name_len)) {            if ((difflen = rptr->sr_name_len - name_len)                < bestlen) {                bestlen = difflen;                bestptr = rptr;            } else if ((difflen == bestlen) &&                       (rptr->sr_priority < bestptr->sr_priority))                bestptr = rptr;        }    }    return bestptr;}u_char         *smux_snmp_process(int exact,                  oid * objid,                  size_t * len,                  size_t * return_len, u_char * return_type, int sd){    u_char          packet[SMUXMAXPKTSIZE], *ptr, result[SMUXMAXPKTSIZE];    int             length = SMUXMAXPKTSIZE;    int             tmp_length;    u_char          type;    size_t          packet_len;    /*     * Send the query to the peer     */    smux_reqid++;    if (exact)        type = SMUX_GET;    else        type = SMUX_GETNEXT;    if (smux_build(type, smux_reqid, objid, len, 0, NULL,                   *len, packet, &length) < 0) {        snmp_log(LOG_ERR, "[smux_snmp_process]: smux_build failed\n");        return NULL;    }    DEBUGMSGTL(("smux", "[smux_snmp_process] oid from build: "));    DEBUGMSGOID(("smux", objid, *len));    DEBUGMSG(("smux", "\n"));    if (send(sd, (char *) packet, length, 0) < 0) {        snmp_log_perror("[smux_snmp_process] send failed");    }    DEBUGMSGTL(("smux",                "[smux_snmp_process] Sent %d request to peer; %d bytes\n",                (int) type, length));    while (1) {        /*         * peek at what's received          */        length = recv(sd, (char *) result, SMUXMAXPKTSIZE, MSG_PEEK);        if (length <= 0) {            if ((length == -1) && ((errno == EINTR) || (errno == EAGAIN)))            {               continue;            }            else            {               snmp_log_perror("[smux_snmp_process] peek failed");               smux_peer_cleanup(sd);               smux_snmp_select_list_del(sd);               return NULL;            }        }        DEBUGMSGTL(("smux", "[smux_snmp_process] Peeked at %d bytes\n",                    length));        DEBUGDUMPSETUP("smux_snmp_process", result, length);        /*         * determine if we received more than one packet          */        packet_len = length;        ptr = asn_parse_header(result, &packet_len, &type);        packet_len += (ptr - result);        if (length > packet_len) {            /*             * set length to receive only the first packet              */            length = packet_len;        }        /*         * receive the first packet          */        tmp_length = length;        do        {           length = tmp_length;           length = recv(sd, (char *) result, length, 0);        }        while((length == -1) && ((errno == EINTR) || (errno == EAGAIN)));        if (length <= 0) {           snmp_log_perror("[smux_snmp_process] recv failed");           smux_peer_cleanup(sd);           smux_snmp_select_list_del(sd);           return NULL;        }        DEBUGMSGTL(("smux", "[smux_snmp_process] Received %d bytes\n",                    length));        if (result[0] == SMUX_TRAP) {            DEBUGMSGTL(("smux", "[smux_snmp_process] Received trap\n"));            snmp_log(LOG_INFO, "Got trap from peer on fd %d\n", sd);            ptr = asn_parse_header(result, &length, &type);            smux_trap_process(ptr, &length);            /*             * go and peek at received data again              */            /*             * we could receive the reply or another trap              */        } else {            /*             * Interpret reply              */            ptr = smux_parse(result, objid, len, return_len, return_type);            /*             * ptr will point to query result or NULL if error              */            break;        }    }                           /* while (1) */    return ptr;}static u_char  *smux_parse(u_char * rsp,           oid * objid,           size_t * oidlen, size_t * return_len, u_char * return_type){    size_t          length = SMUXMAXPKTSIZE;    u_char         *ptr, type;    long            reqid, errstat, errindex;    ptr = rsp;    /*     * Return pointer to the snmp/smux return value.     * return_len should contain the number of bytes in the value     * returned above.     * objid is the next object, with len for GETNEXT.     * objid and len are not changed for GET     */    ptr = asn_parse_header(ptr, &length, &type);    if (ptr == NULL || type != SNMP_MSG_RESPONSE)        return NULL;    if ((ptr = asn_parse_int(ptr, &length, &type, &reqid,                             sizeof(reqid))) == NULL) {        DEBUGMSGTL(("smux", "[smux_parse] parse of reqid failed\n"));        return NULL;    }    if ((ptr = asn_parse_int(ptr, &length, &type, &errstat,                             sizeof(errstat))) == NULL) {        DEBUGMSGTL(("smux",                    "[smux_parse] parse of error status failed\n"));        return NULL;    }    if ((ptr = asn_parse_int(ptr, &length, &type, &errindex,                             sizeof(errindex))) == NULL) {        DEBUGMSGTL(("smux", "[smux_parse] parse of error index failed\n"));        return NULL;    }    /*     * XXX How to send something intelligent back in case of an error      */    DEBUGMSGTL(("smux",                "[smux_parse] Message type %d, reqid %d, errstat %d, \n\terrindex %d\n",                (int) type, reqid, errstat, errindex));    if (ptr == NULL || errstat != SNMP_ERR_NOERROR)        return NULL;    /*     * stuff to return      */    return (smux_parse_var            (ptr, &length, objid, oidlen, return_len, return_type));}static u_char  *smux_parse_var(u_char * varbind,               size_t * varbindlength,               oid * objid,               size_t * oidlen, size_t * varlength, u_char * vartype){    oid             var_name[MAX_OID_LEN];    size_t          var_name_len;    size_t          var_val_len;    u_char         *var_val;    size_t          str_len, objid_len;    size_t          len;    u_char         *ptr;    u_char          type;    ptr = varbind;    len = *varbindlength;    DEBUGMSGTL(("smux", "[smux_parse_var] before any processing: "));    DEBUGMSGOID(("smux", objid, *oidlen));    DEBUGMSG(("smux", "\n"));    ptr = asn_parse_header(ptr, &len, &type);    if (ptr == NULL || type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) {        snmp_log(LOG_NOTICE, "[smux_parse_var] Panic: type %d\n",                 (int) type);        return NULL;    }    /*     * get hold of the objid and the asn1 coded value      */    var_name_len = MAX_OID_LEN;    ptr = snmp_parse_var_op(ptr, var_name, &var_name_len, vartype,                            &var_val_len, &var_val, &len);    *oidlen = var_name_len;    memcpy(objid, var_name, var_name_len * sizeof(oid));    DEBUGMSGTL(("smux", "[smux_parse_var] returning oid : "));    DEBUGMSGOID(("smux", objid, *oidlen));    DEBUGMSG(("smux", "\n"));    /*     * XXX      */    len = SMUXMAXPKTSIZE;    DEBUGMSGTL(("smux",                "[smux_parse_var] Asn coded len of var %d, type %d\n",                var_val_len, (int) *vartype));    switch ((short) *vartype) {    case ASN_INTEGER:        *varlength = sizeof(long);        asn_parse_int(var_val, &len, vartype,                      (long *) &smux_long, *varlength);        return (u_char *) & smux_long;        break;    case ASN_COUNTER:    case ASN_GAUGE:    case ASN_TIMETICKS:    case ASN_UINTEGER:        *varlength = sizeof(u_long);        asn_parse_unsigned_int(var_val, &len, vartype,                               (u_long *) & smux_ulong, *varlength);        return (u_char *) & smux_ulong;        break;    case ASN_COUNTER64:        *varlength = sizeof(smux_counter64);        asn_parse_unsigned_int64(var_val, &len, vartype,                                 (struct counter64 *) &smux_counter64,                                 *varlength);        return (u_char *) & smux_counter64;        break;    case ASN_IPADDRESS:        *varlength = 4;        /*         * consume the tag and length, but just copy here         * because we know it is an ip address         */        if ((var_val = asn_parse_header(var_val, &len, &type)) == NULL)            return NULL;        memcpy((u_char *) & (smux_sa.sin_addr.s_addr), var_val,               *varlength);        return (u_char *) & (smux_sa.sin_addr.s_addr);        break;    case ASN_OCTET_STR:        /*         * XXX          */        if (len == 0)            return NULL;        str_len = SMUXMAXSTRLEN;        asn_parse_string(var_val, &len, vartype, smux_str, &str_len);        *varlength = str_len;        return smux_str;        break;    case ASN_OPAQUE:    case ASN_NSAP:    case ASN_OBJECT_ID:        objid_len = MAX_OID_LEN;        asn_parse_objid(var_val, &len, vartype, smux_objid, &objid_len);        *varlength = objid_len * sizeof(oid);        return (u_char *) smux_objid;        break;    case SNMP_NOSUCHOBJECT:    case SNMP_NOSUCHINSTANCE:    case SNMP_ENDOFMIBVIEW:    case ASN_NULL:        return NULL;        break;    case ASN_BIT_STR:        /*         * XXX          */        if (len == 0)            return NULL;        str_len = SMUXMAXSTRLEN;        asn_parse_bitstring(var_val, &len, vartype, smux_str, &str_len);        *varlength = str_len;        return (u_char *) smux_str;        break;    default:        snmp_log(LOG_ERR, "bad type returned (%x)\n", *vartype);        return NULL;        break;    }}/* * XXX This is a bad hack - do not want to muck with ucd code  */static intsmux_build(u_char type,           long reqid,           oid * objid,           size_t * oidlen,           u_char val_type,           u_char * val, size_t val_len, u_char * packet, size_t * length){    u_char         *ptr, *save1, *save2;    size_t          len;    long            errstat = 0;    long            errindex = 0;    /*     * leave space for Seq and length      */    save1 = packet;    ptr = packet + 4;    len = *length - 4;    /*     * build reqid      */    ptr = asn_build_int(ptr, &len,                                 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |                                           ASN_INTEGER), &reqid,                                 sizeof(reqid));    if (ptr == NULL) {        return -1;    }    /*

⌨️ 快捷键说明

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