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

📄 smux.c

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 C
📖 第 1 页 / 共 4 页
字号:
                smux_list_detach(&ActiveRegs, &rptr);                free(rptr);            }            smux_send_rrsp(sd, rpriority);            return ptr;        }        /*         * search the passive list for this registration          */        rptr =            smux_find_match(PassiveRegs, sd, oid_name, oid_name_len,                            priority);        if (rptr) {            rpriority = rptr->sr_priority;            smux_list_detach(&PassiveRegs, &rptr);            free(rptr);            smux_send_rrsp(sd, rpriority);            return ptr;        }        /*         * This peer cannot unregister the tree, it does not         * * belong to him.  Send him an error.         */        smux_send_rrsp(sd, -1);        return ptr;    } else if ((operation == SMUX_REGOP_REGISTER_RO) ||               (operation == SMUX_REGOP_REGISTER_RW)) {        if (priority < -1) {            DEBUGMSGTL(("smux",                        "[smux_rreq_process] peer fd %d invalid priority",                        sd, priority));            smux_send_rrsp(sd, -1);            return NULL;        }        if ((nrptr = malloc(sizeof(smux_reg))) == NULL) {            snmp_log_perror("[smux_rreq_process] malloc");            smux_send_rrsp(sd, -1);            return NULL;        }        nrptr->sr_priority = priority;        nrptr->sr_name_len = oid_name_len;        nrptr->sr_fd = sd;        for (i = 0; i < (int) oid_name_len; i++)            nrptr->sr_name[i] = oid_name[i];        /*         * See if this tree matches or scopes any of the         * * active trees.         */        for (rptr = ActiveRegs; rptr; rptr = rptr->sr_next) {            result =                snmp_oid_compare(oid_name, oid_name_len, rptr->sr_name,                                 rptr->sr_name_len);            if (result == 0) {                if ((oid_name_len == rptr->sr_name_len)) {                    if ((nrptr->sr_priority == -1)) {                        nrptr->sr_priority = rptr->sr_priority;                        do {                            nrptr->sr_priority++;                        } while (smux_list_add(&PassiveRegs, nrptr));                        goto done;                    } else if (nrptr->sr_priority < rptr->sr_priority) {                        /*                         * Better priority.  There are no better                         * * priorities for this tree in the passive list,                         * * so replace the current active tree.                         */                        smux_replace_active(rptr, nrptr);                        goto done;                    } else {                        /*                         * Equal or worse priority                          */                        do {                            nrptr->sr_priority++;                        } while (smux_list_add(&PassiveRegs, nrptr) == -1);                        goto done;                    }                } else if (oid_name_len < rptr->sr_name_len) {                    /*                     * This tree scopes a current active                     * * tree.  Replace the current active tree.                     */                    smux_replace_active(rptr, nrptr);                    goto done;                } else {        /* oid_name_len > rptr->sr_name_len */                    /*                     * This tree is scoped by a current                     * * active tree.                       */                    do {                        nrptr->sr_priority++;                    } while (smux_list_add(&PassiveRegs, nrptr) == -1);                    goto done;                }            }        }        /*         * We didn't find it in the active list.  Add it at         * * the requested priority.         */        if (nrptr->sr_priority == -1)            nrptr->sr_priority = 0;        smux_list_add(&ActiveRegs, nrptr);        register_mib("smux", (struct variable *)                     smux_variables, sizeof(struct variable2),                     1, nrptr->sr_name, nrptr->sr_name_len);      done:        smux_send_rrsp(sd, nrptr->sr_priority);        return ptr;    } else {        DEBUGMSGTL(("smux", "[smux_rreq_process] unknown operation\n"));        smux_send_rrsp(sd, -1);        return NULL;    }}/* * Find the registration with a matching descriptor, OID and priority.  If * the priority is -1 then find a registration with a matching descriptor, * a matching OID, and the highest priority. */static smux_reg *smux_find_match(smux_reg * regs, int sd, oid * oid_name,                size_t oid_name_len, long priority){    smux_reg       *rptr, *bestrptr;    bestrptr = NULL;    for (rptr = regs; rptr; rptr = rptr->sr_next) {        if (rptr->sr_fd != sd)            continue;        if (snmp_oid_compare            (rptr->sr_name, rptr->sr_name_len, oid_name, oid_name_len))            continue;        if (rptr->sr_priority == priority)            return rptr;        if (priority != -1)            continue;        if (bestrptr) {            if (bestrptr->sr_priority > rptr->sr_priority)                bestrptr = rptr;        } else {            bestrptr = rptr;        }    }    return bestrptr;}static voidsmux_replace_active(smux_reg * actptr, smux_reg * pasptr){    smux_list_detach(&ActiveRegs, &actptr);    unregister_mib(actptr->sr_name, actptr->sr_name_len);    smux_list_detach(&PassiveRegs, &pasptr);    (void) smux_list_add(&ActiveRegs, pasptr);    register_mib("smux", (struct variable *) smux_variables,                 sizeof(struct variable2), 1, pasptr->sr_name,                 pasptr->sr_name_len);    free(actptr);}static voidsmux_list_detach(smux_reg ** head, smux_reg ** m_remove){    smux_reg       *rptr, *rptr2;    if (*head == NULL) {        DEBUGMSGTL(("smux", "[smux_list_detach] Ouch!"));        return;    }    if (*head == *m_remove) {        *m_remove = *head;        *head = (*head)->sr_next;        return;    }    for (rptr = *head, rptr2 = rptr->sr_next; rptr2;         rptr2 = rptr2->sr_next, rptr = rptr->sr_next) {        if (rptr2 == *m_remove) {            *m_remove = rptr2;            rptr->sr_next = rptr2->sr_next;            return;        }    }}/* * Attempt to add a registration (in order) to a list.  If the * add fails (because of an existing registration with equal * priority) return -1. */static intsmux_list_add(smux_reg ** head, smux_reg * add){    smux_reg       *rptr;    int             result;    if (*head == NULL) {        *head = add;        (*head)->sr_next = NULL;        return 0;    }    for (rptr = *head; rptr->sr_next; rptr = rptr->sr_next) {        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)) {            /*             * same tree, same pri, nope              */            return -1;        } 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;        }    }    /*     * compare the last one      */    if ((snmp_oid_compare(add->sr_name, add->sr_name_len, rptr->sr_name,                          rptr->sr_name_len) == 0)        && add->sr_priority == rptr->sr_priority)        return -1;    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];    size_t          length = SMUXMAXPKTSIZE;    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) {            snmp_log_perror("[smux_snmp_process] peek failed");            smux_peer_cleanup(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          */        length = recv(sd, (char *) result, length, 0);        if (length < 0) {            snmp_log_perror("[smux_snmp_process] recv failed");            smux_peer_cleanup(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 

⌨️ 快捷键说明

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