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

📄 smux.c

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 C
📖 第 1 页 / 共 4 页
字号:
                    asn_parse_int(ptr, &len, &type, &reqid, sizeof(reqid));                if ((ptr == NULL) || type != ASN_INTEGER)                    return SNMP_ERR_GENERR;                ptr =                    asn_parse_int(ptr, &len, &type, &errsts,                                  sizeof(errsts));                if ((ptr == NULL) || type != ASN_INTEGER)                    return SNMP_ERR_GENERR;                if (errsts) {                    DEBUGMSGTL(("smux",                                "[var_smux_write] errsts returned\n"));                    return (errsts);                }                ptr =                    asn_parse_int(ptr, &len, &type, &erridx,                                  sizeof(erridx));                if ((ptr == NULL) || type != ASN_INTEGER)                    return SNMP_ERR_GENERR;                reterr = SNMP_ERR_NOERROR;                break;            }        }                       /* while (1) */        break;                  /* case Action == RESERVE1 */    case RESERVE2:        DEBUGMSGTL(("smux", "[var_smux_write] entering RESERVE2\n"));        reterr = SNMP_ERR_NOERROR;        break;                  /* case Action == RESERVE2 */    case FREE:    case COMMIT:        ptr = sout;        *(ptr++) = (u_char) SMUX_SOUT;        *(ptr++) = (u_char) 1;        if (action == FREE) {            *ptr = (u_char) 1;  /* rollback */            DEBUGMSGTL(("smux",                        "[var_smux_write] entering FREE - sending RollBack \n"));        } else {            *ptr = (u_char) 0;  /* commit */            DEBUGMSGTL(("smux",                        "[var_smux_write] entering FREE - sending Commit \n"));        }        if ((send(rptr->sr_fd, sout, 3, 0)) < 0) {            DEBUGMSGTL(("smux",                        "[var_smux_write] send rollback/commit failed\n"));            return SNMP_ERR_GENERR;        }        reterr = SNMP_ERR_NOERROR;        break;                  /* case Action == COMMIT */    default:        break;    }    return reterr;}intsmux_accept(int sd){    u_char          data[SMUXMAXPKTSIZE], *ptr, type;    struct sockaddr_in in_socket;    struct timeval  tv;    int             fail, fd, alen;    int             length;    ssize_t         len;    alen = sizeof(struct sockaddr_in);    /*     * this may be too high      */    tv.tv_sec = 5;    tv.tv_usec = 0;    /*     * connection request      */    DEBUGMSGTL(("smux", "[smux_accept] Calling accept()\n"));    errno = 0;    if ((fd = accept(sd, (struct sockaddr *) &in_socket, &alen)) < 0) {        snmp_log_perror("[smux_accept] accept failed");        return -1;    } else {        snmp_log(LOG_INFO, "[smux_accept] accepted fd %d from %s:%d\n",                 fd, inet_ntoa(in_socket.sin_addr),                 ntohs(in_socket.sin_port));        if (npeers + 1 == SMUXMAXPEERS) {            snmp_log(LOG_ERR,                     "[smux_accept] denied peer on fd %d, limit %d reached",                     fd, SMUXMAXPEERS);            close(sd);            return -1;        }        /*         * now block for an OpenPDU          */        if ((length = recv(fd, (char *) data, SMUXMAXPKTSIZE, 0)) <= 0) {            DEBUGMSGTL(("smux",                        "[smux_accept] peer on fd %d died or timed out\n",                        fd));            close(fd);            return -1;        }        /*         * try to authorize him          */        ptr = data;        len = length;        if ((ptr = asn_parse_header(ptr, &len, &type)) == NULL) {            smux_send_close(fd, SMUXC_PACKETFORMAT);            close(fd);            DEBUGMSGTL(("smux", "[smux_accept] peer on %d sent bad open"));            return -1;        } else if (type != (u_char) SMUX_OPEN) {            smux_send_close(fd, SMUXC_PROTOCOLERROR);            close(fd);            DEBUGMSGTL(("smux",                        "[smux_accept] peer on %d did not send open: (%d)\n",                        type));            return -1;        }        ptr = smux_open_process(fd, ptr, &len, &fail);        if (fail) {            smux_send_close(fd, SMUXC_AUTHENTICATIONFAILURE);            close(fd);            DEBUGMSGTL(("smux",                        "[smux_accept] peer on %d failed authentication\n",                        fd));            return -1;        }        /*         * he's OK          */#ifdef SO_RCVTIMEO        if (setsockopt            (fd, SOL_SOCKET, SO_RCVTIMEO, (void *) &tv, sizeof(tv)) < 0) {            DEBUGMSGTL(("smux",                        "[smux_accept] setsockopt(SO_RCVTIMEO) failed fd %d\n",                        fd));            snmp_log_perror("smux_accept: setsockopt SO_RCVTIMEO");        }#endif        npeers++;        DEBUGMSGTL(("smux", "[smux_accept] fd %d\n", fd));        /*         * Process other PDUs already read, e.g. a registerRequest.          */        len = length - (ptr - data);        if (smux_pdu_process(fd, ptr, len) < 0) {            /*             * Easy come, easy go.  Clean-up is already done.              */            return -1;        }    }    return fd;}intsmux_process(int fd){    int             length;    u_char          data[SMUXMAXPKTSIZE];    length = recv(fd, (char *) data, SMUXMAXPKTSIZE, 0);    if (length <= 0) {        /*         * the peer went away, close this descriptor          * * and delete it from the list         */        DEBUGMSGTL(("smux",                    "[smux_process] peer on fd %d died or timed out\n",                    fd));        smux_peer_cleanup(fd);        return -1;    }    return smux_pdu_process(fd, data, length);}static intsmux_pdu_process(int fd, u_char * data, size_t length){    int             error;    size_t          len;    u_char         *ptr, type;    DEBUGMSGTL(("smux", "[smux_pdu_process] Processing %d bytes\n",                length));    error = 0;    ptr = data;    while (error == 0 && ptr != NULL && ptr < data + length) {        len = length - (ptr - data);        ptr = asn_parse_header(ptr, &len, &type);        DEBUGMSGTL(("smux", "[smux_pdu_process] type is %d\n",                    (int) type));        switch (type) {        case SMUX_OPEN:            smux_send_close(fd, SMUXC_PROTOCOLERROR);            DEBUGMSGTL(("smux",                        "[smux_pdu_process] peer on fd %d sent duplicate open?\n",                        fd));            smux_peer_cleanup(fd);            error = -1;            break;        case SMUX_CLOSE:            ptr = smux_close_process(fd, ptr, &len);            smux_peer_cleanup(fd);            error = -1;            break;        case SMUX_RREQ:            ptr = smux_rreq_process(fd, ptr, &len);            break;        case SMUX_RRSP:            error = -1;            smux_send_close(fd, SMUXC_PROTOCOLERROR);            smux_peer_cleanup(fd);            DEBUGMSGTL(("smux",                        "[smux_pdu_process] peer on fd %d sent RRSP!\n",                        fd));            break;        case SMUX_SOUT:            error = -1;            smux_send_close(fd, SMUXC_PROTOCOLERROR);            smux_peer_cleanup(fd);            DEBUGMSGTL(("smux", "This shouldn't have happened!\n"));            break;        case SMUX_TRAP:            snmp_log(LOG_INFO, "Got trap from peer on fd %d\n", fd);            ptr = smux_trap_process(ptr, &len);            /*             * watch out for close on top of this...should return correct end              */            /*             * debug this...              */            ptr = NULL;            break;        default:            smux_send_close(fd, SMUXC_PACKETFORMAT);            smux_peer_cleanup(fd);            DEBUGMSGTL(("smux", "[smux_pdu_process] Wrong type %d\n",                        (int) type));            error = -1;            break;        }    }    return error;}static u_char  *smux_open_process(int fd, u_char * ptr, size_t * len, int *fail){    u_char          type;    long            version;    oid             oid_name[MAX_OID_LEN];    char            passwd[SMUXMAXSTRLEN];    char            descr[SMUXMAXSTRLEN];    char            oid_print[SMUXMAXSTRLEN];    int             i;    size_t          oid_name_len, string_len;    if (!(ptr = asn_parse_int(ptr, len, &type, &version, sizeof(version)))) {        DEBUGMSGTL(("smux", "[smux_open_process] version parse failed\n"));        *fail = TRUE;        return ((ptr += *len));    }    DEBUGMSGTL(("smux",                "[smux_open_process] version %d, len %d, type %d\n",                version, *len, (int) type));    oid_name_len = MAX_OID_LEN;    if ((ptr = asn_parse_objid(ptr, len, &type, oid_name,                               &oid_name_len)) == NULL) {        DEBUGMSGTL(("smux", "[smux_open_process] oid parse failed\n"));        *fail = TRUE;        return ((ptr += *len));    }    snprint_objid(oid_print, sizeof(oid_print), oid_name, oid_name_len);    if (snmp_get_do_debugging()) {        DEBUGMSGTL(("smux", "[smux_open_process] smux peer: %s\n",                    oid_print));        DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len,                    (int) type));    }    string_len = SMUXMAXSTRLEN;    if ((ptr = asn_parse_string(ptr, len, &type, (u_char *) descr,                                &string_len)) == NULL) {        DEBUGMSGTL(("smux", "[smux_open_process] descr parse failed\n"));        *fail = TRUE;        return ((ptr += *len));    }    if (snmp_get_do_debugging()) {        DEBUGMSGTL(("smux", "[smux_open_process] smux peer descr: "));        for (i = 0; i < (int) string_len; i++)            DEBUGMSG(("smux", "%c", descr[i]));        DEBUGMSG(("smux", "\n"));        DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len,                    (int) type));    }    descr[string_len] = 0;    string_len = SMUXMAXSTRLEN;    if ((ptr = asn_parse_string(ptr, len, &type, (u_char *) passwd,                                &string_len)) == NULL) {        DEBUGMSGTL(("smux", "[smux_open_process] passwd parse failed\n"));        *fail = TRUE;        return ((ptr += *len));    }    if (snmp_get_do_debugging()) {        DEBUGMSGTL(("smux", "[smux_open_process] smux peer passwd: "));        for (i = 0; i < (int) string_len; i++)            DEBUGMSG(("smux", "%c", passwd[i]));        DEBUGMSG(("smux", "\n"));        DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len,                    (int) type));    }    passwd[string_len] = '\0';    if (!smux_auth_peer(oid_name, oid_name_len, passwd, fd)) {        snmp_log(LOG_WARNING,                 "refused smux peer: oid %s, descr %s\n",                 oid_print, descr);        *fail = TRUE;        return ptr;    }    snmp_log(LOG_INFO,             "accepted smux peer: oid %s, descr %s\n",             oid_print, descr);    *fail = FALSE;    return ptr;}static voidsmux_send_close(int fd, int reason){    u_char          outpacket[3], *ptr;    ptr = outpacket;    *(ptr++) = (u_char) SMUX_CLOSE;    *(ptr++) = (u_char) 1;    *ptr = (u_char) (reason & 0xFF);    if (snmp_get_do_debugging())        DEBUGMSGTL(("smux",                    "[smux_close] sending close to fd %d, reason %d\n", fd,                    reason));    /*     * send a response back      */    if (send(fd, (char *) outpacket, 3, 0) < 0) {        snmp_log_perror("[smux_snmp_close] send failed");    }}static intsmux_auth_peer(oid * name, size_t namelen, char *passwd, int fd){    int             i;    for (i = 0; i < nauths; i++) {        if (snmp_oid_compare(Auths[i]->sa_oid, Auths[i]->sa_oid_len,                             name, namelen) == 0) {            if (!(strcmp(Auths[i]->sa_passwd, passwd)) &&                (Auths[i]->sa_active_fd == -1)) {                /*                 * matched, mark the auth                  */                Auths[i]->sa_active_fd = fd;                return 1;            }        }    }    /*     * did not match oid and passwd      */    return 0;}/* * XXX - Bells and Whistles: * Need to catch signal when snmpd goes down and send close pdu to gated  */static u_char  *smux_close_process(int fd, u_char * ptr, size_t * len){    long            down = 0;    int             length = *len;    /*     * This is the integer part of the close pdu      */    while (length--) {        down = (down << 8) | (long) *ptr;        ptr++;    }    DEBUGMSGTL(("smux",                "[smux_close_process] close from peer on fd %d reason %d\n",                fd, down));    smux_peer_cleanup(fd);    return NULL;}static u_char  *smux_rreq_process(int sd, u_char * ptr, size_t * len){    long            priority, rpriority;    long            operation;    oid             oid_name[MAX_OID_LEN];    size_t          oid_name_len;    int             i, result;    u_char          type;    smux_reg       *rptr, *nrptr;    oid_name_len = MAX_OID_LEN;    ptr = asn_parse_objid(ptr, len, &type, oid_name, &oid_name_len);    DEBUGMSGTL(("smux", "[smux_rreq_process] smux subtree: "));    DEBUGMSGOID(("smux", oid_name, oid_name_len));    DEBUGMSG(("smux", "\n"));    if ((ptr = asn_parse_int(ptr, len, &type, &priority,                             sizeof(priority))) == NULL) {        DEBUGMSGTL(("smux",                    "[smux_rreq_process] priority parse failed\n"));        smux_send_rrsp(sd, -1);        return NULL;    }    DEBUGMSGTL(("smux", "[smux_rreq_process] priority %d\n", priority));    if ((ptr = asn_parse_int(ptr, len, &type, &operation,                             sizeof(operation))) == NULL) {        DEBUGMSGTL(("smux",                    "[smux_rreq_process] operation parse failed\n"));        smux_send_rrsp(sd, -1);        return NULL;    }    DEBUGMSGTL(("smux", "[smux_rreq_process] operation %d\n", operation));    if (operation == SMUX_REGOP_DELETE) {        /*         * search the active list for this registration          */        rptr =            smux_find_match(ActiveRegs, sd, oid_name, oid_name_len,                            priority);        if (rptr) {            rpriority = rptr->sr_priority;            /*             * unregister the mib              */            unregister_mib(rptr->sr_name, rptr->sr_name_len);            /*             * find a replacement              */            nrptr =                smux_find_replacement(rptr->sr_name, rptr->sr_name_len);            if (nrptr) {                /*                 * found one                  */                smux_replace_active(rptr, nrptr);            } else {                /*                 * no replacement found                  */

⌨️ 快捷键说明

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