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

📄 smux.c

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (send(rptr->sr_fd, buf, len, 0) < 0) {            DEBUGMSGTL(("smux", "[var_smux_write] send failed\n"));            return SNMP_ERR_GENERR;        }        while (1) {            /*             * peek at what's received              */            if ((len = recv(rptr->sr_fd, buf,                            SMUXMAXPKTSIZE, MSG_PEEK)) <= 0) {                if ((len == -1) && ((errno == EINTR) || (errno == EAGAIN)))                {                   continue;                }                DEBUGMSGTL(("smux",                            "[var_smux_write] peek failed or timed out\n"));                /*                 * do we need to do a peer cleanup in this case??                  */                smux_peer_cleanup(rptr->sr_fd);                smux_snmp_select_list_del(rptr->sr_fd);                return SNMP_ERR_GENERR;            }            DEBUGMSGTL(("smux", "[var_smux_write] Peeked at %d bytes\n",                        len));            DEBUGDUMPSETUP("var_smux_write", buf, len);            /*             * determine if we received more than one packet              */            packet_len = len;            ptr = asn_parse_header(buf, &packet_len, &type);            packet_len += (ptr - buf);            if (len > (ssize_t)packet_len) {                /*                 * set length to receive only the first packet                  */                len = packet_len;            }            /*             * receive the first packet              */            tmp_len = len;            do            {               len = tmp_len;               len = recv(rptr->sr_fd, buf, len, 0);            }            while((len == -1) && ((errno == EINTR) || (errno == EAGAIN)));            if (len <= 0) {                DEBUGMSGTL(("smux",                            "[var_smux_write] recv failed or timed out\n"));                smux_peer_cleanup(rptr->sr_fd);                smux_snmp_select_list_del(rptr->sr_fd);                return SNMP_ERR_GENERR;            }            DEBUGMSGTL(("smux", "[var_smux_write] Received %d bytes\n",                        len));            if (buf[0] == SMUX_TRAP) {                DEBUGMSGTL(("smux", "[var_smux_write] Received trap\n"));                snmp_log(LOG_INFO, "Got trap from peer on fd %d\n",                         rptr->sr_fd);                ptr = asn_parse_header(buf, &len, &type);                smux_trap_process(ptr, &len);                /*                 * go and peek at received data again                  */                /*                 * we could receive the reply or another trap                  */            } else {                ptr = buf;                ptr = asn_parse_header(ptr, &len, &type);                if ((ptr == NULL) || type != SNMP_MSG_RESPONSE)                    return SNMP_ERR_GENERR;                ptr =                    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          */        do        {           length = recv(fd, (char *) data, SMUXMAXPKTSIZE, 0);        }        while((length == -1) && ((errno == EINTR) || (errno == EAGAIN)));        if (length <= 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, tmp_length;    u_char          data[SMUXMAXPKTSIZE];    u_char          type, *ptr;    size_t          packet_len;    do    {       length = recv(fd, (char *) data, SMUXMAXPKTSIZE, MSG_PEEK);    }    while((length == -1) && ((errno == EINTR) || (errno == EAGAIN)));    if (length <= 0)    {       snmp_log_perror("[smux_process] peek failed");       smux_peer_cleanup(fd);       return -1;    }    /*     * determine if we received more than one packet      */    packet_len = length;    ptr = asn_parse_header(data, &packet_len, &type);    packet_len += (ptr - data);    if (length > packet_len) {        /*         * set length to receive only the first packet          */        length = packet_len;    }    tmp_length = length;    do    {       length = tmp_length;       length = recv(fd, (char *) data, length, 0);    }    while((length == -1) && ((errno == EINTR) || (errno == EAGAIN)));    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);            if (ptr != 0)            {               DEBUGMSGTL(("smux", "[smux_pdu_process] call smux_trap_process.\n"));               ptr = smux_trap_process(ptr, &len);            }            else            {               DEBUGMSGTL(("smux", "[smux_pdu_process] smux_trap_process not called: ptr=NULL.\n"));               DEBUGMSGTL(("smux", "[smux_pdu_process] Error: \n%s\n", snmp_api_errstring(0)));            }            /*             * watch out for close on top of this...should return correct end              */            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,

⌨️ 快捷键说明

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