Segmentation fault - agentx_check_packet

Paulo Eduardo Ostermann Filho <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <FBE823ACB6185A499D7AEF5B4E57775D0894CB02F9@excdbpoa01>
Good afternoon, everyone!

We developed the following source code (3) to get module status of our application using getnext requests. The function_class_execute_thread is a macro executed from a thread. This thread executes isGatewayRunning that send and receive variables from master agent (snmpd). Sometimes this code works fine, but on another occasions it generates valgrind error (4) (in the end of this message). It is attached to this message a work flow of this process.

Are we coding the synchronous application correctly ?

Best regards.
Thanks in advance.

	================---------------------------================---------------------------================---------------------------================---------------------------

1) SO information :
-------------------

Linux localhost.localdomain 2.6.18-308.16.1.el5 #1 SMP Tue Oct 2 22:01:37 EDT 2012 i686 i686 i386 GNU/Linux. 


2) Libraries information :
-------------------------
net-snmp-devel-5.5-37.1
net-snmp-5.5-37.1
net-snmp-perl-5.5-37.1
net-snmp-utils-5.5-37.1
net-snmp-libs-5.5-37.1


3) Source code :
---------------

class FinalizeGateway : public ThreadSingle  {
    public:
    FUNCTION_CLASS_EXECUTE_THREAD (
        int intervalSeconds = 50;
        bool gtwRunning = false;
        int count = 0;
        int attemptNumber = 5;
        netsnmp_session *sessionPtr = NULL;

        do {
            count++;
            std::cout << "Tentativa " << count << " de " << attemptNumber << ". Verificando se o gateway esta rodando em " << intervalSeconds << " segundos..." << std::endl;
            sleep(intervalSeconds);
            gtwRunning = isGatewayRunning(sessionPtr);
        } while (!gtwRunning && count != attemptNumber);

        if (!gtwRunning) {
            exit(1);
        }

        std::cout << "Finalizando o gateway..." << std::endl;
        finalize(sessionPtr);
        sleep(3);
        exit(0);
    )

    netsnmp_session *getSession() {
        netsnmp_session session;
        netsnmp_session *ss = NULL;
        const char *our_v3_passphrase = "gateway2012";
        int returned;

        snmp_sess_init( &session );/* Initialize a "session" that defines who we're going to talk to. set up defaults */
        session.retries = 10;
        session.peername = strdup("localhost");
        session.version=SNMP_VERSION_3;/* set up the authentication parameters for talking to the server.Use SNMPv3 to talk to the experimental server.set the SNMP version number. */
        session.securityName = strdup("gateway"); /* set the SNMPv3 user name */
        session.securityNameLen = strlen(session.securityName);
        session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;/* set the security level to authenticated, but not encrypted */
        session.securityAuthProto = usmHMACSHA1AuthProtocol;
        session.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid);
        session.securityAuthKeyLen = USM_AUTH_KU_LEN;
        session.timeout = 100000000;
        returned = generate_Ku(session.securityAuthProto,session.securityAuthProtoLen,(u_char *) our_v3_passphrase, strlen(our_v3_passphrase),session.securityAuthKey,&session.securityAuthKeyLen);
        CHECK(returned == SNMPERR_SUCCESS);
        if (returned != SNMPERR_SUCCESS) {
            std::cout << "Erro ao gerar a chave." << std::endl;
            return NULL;
        }
        ss = snmp_open(&session);/* establish the session */
        if (!ss) {
            char *erro = (char *)snmp_errstring(session.s_errno);
            erro = erro;
            std::cout << "Sessao nao foi aberta." << std::endl;
            std::cout << "erro=" << erro << std::endl;
            return NULL;
        }
        return ss;
    }

    bool isGatewayRunning(netsnmp_session *sessionPtrParam) {
        netsnmp_pdu *pdu = NULL;
        netsnmp_pdu *response = NULL;
        oid anOID[MAX_OID_LEN];
        oid baseOID[MAX_OID_LEN];
        size_t baseOIDLen;
        size_t anOID_len;
        int returned;
        netsnmp_variable_list *vars = NULL;
        bool running;
        bool readNode = true;
        bool found = false;
        netsnmp_session *sessionPtr;
        char *moduleTableNode = (char *) ".1.3.6.1.4.1.29809.1.2.2.1.2";

        sessionPtrParam = sessionPtrParam;

        memset(anOID,0,sizeof(anOID));
        anOID_len = MAX_OID_LEN;
        memset(baseOID,0,sizeof(baseOID));
        baseOIDLen = MAX_OID_LEN;

        if (!snmp_parse_oid(moduleTableNode, anOID, &anOID_len)) {
            std::cout << "isGatewayRunning - erro em snmp_parse_oid" << std::endl;
            return false;
        }

        memcpy(baseOID,anOID,sizeof(anOID));
        baseOIDLen = anOID_len;

        sessionPtr = getSession();
        if (!sessionPtr)
            return false;

        do {
            response = NULL;
            pdu = NULL;
            running = true;
            pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
            if (!pdu) {
                std::cout << "isGatewayRunning - erro em snmp_pdu_create" << std::endl;
                snmp_close(sessionPtr);
                return false;
            }

            if (!snmp_add_null_var(pdu, anOID, anOID_len)) {
                std::cout << "isGatewayRunning - erro em snmp_add_null_var" << std::endl;
                snmp_close(sessionPtr);
                return false;
            }

            returned = snmp_synch_response(sessionPtr, pdu, &response);
            if ((returned == STAT_SUCCESS) && (response) && (response->errstat == SNMP_ERR_NOERROR)) {
                for(vars = response->variables; vars; vars = vars->next_variable) {
                    if ((baseOIDLen <= response->variables->name_length) ) {
                        if (!snmp_oid_compare(baseOID,baseOIDLen,response->variables->name,baseOIDLen)) {
                            found = true;
                            if (*(vars->val.integer) != Running) {
                                running = false;
                                readNode = false;
                                break;
                            }
                        }
                        else {
                            readNode = false;
                            break;
                        }
                    }
                    else {
                        // (PF-20121024) Verifica se foi lido algum nodo procurado.
                        // Caso não tenha sido, a mib do gateway não foi carregada.
                        readNode = false;
                        if (!found)
                            running = false;
                        break;
                    }
                    memset(anOID,0,sizeof(anOID));
                    anOID_len = MAX_OID_LEN;
                    memcpy(anOID,response->variables->name,response->variables->name_length*sizeof(oid *));
                    anOID_len = response->variables->name_length;
                }
            }
            else {
                if (returned == STAT_ERROR) {
                    std::cout << "Verifique se snmpd está ativo..." << std::endl;
                }
                else if (returned == STAT_TIMEOUT) {
                    std::cout << "Timeout...Verifique o agente..." << std::endl;
                }
                else if (response) {
                    std::cout << "response=" << response->errstat << ".mensagem =" << snmp_errstring(response->errstat) << std::endl;
                }

                running = false;
                readNode = false;
            }

            // Clean up: 1) free the response;
            if (response)
              snmp_free_pdu(response);

            CHECK(returned == STAT_SUCCESS);
        } while (readNode);        
        snmp_close(sessionPtr);
        return running;
    }

    void finalize(netsnmp_session *sessionPtrParam) {
        netsnmp_pdu *pdu = NULL;
        netsnmp_pdu *response = NULL;
        oid anOID[MAX_OID_LEN];
        size_t anOID_len;
        int returned;
        int count = 0;
        netsnmp_session *sessionPtr;

        sessionPtrParam = sessionPtrParam;
        sessionPtr = getSession();
        if (!sessionPtr)
            return;

        do {
            pdu = snmp_pdu_create(SNMP_MSG_SET);
            if (!pdu) {
                std::cout << "finalize - erro em snmp_pdu_create" << std::endl;
                snmp_close(sessionPtr);
                return;
            }

            memset(anOID,0,sizeof(anOID));
            anOID_len = MAX_OID_LEN;

            if (!snmp_parse_oid(".1.3.6.1.4.1.29809.1.1.1.0", anOID, &anOID_len)) {
                std::cout << "finalize - erro em snmp_parse_oid" << std::endl;
                snmp_close(sessionPtr);
                return;
            }

            if (SNMPERR_SUCCESS != snmp_add_var(pdu, anOID, anOID_len, 'i', "0")) {
                std::cout << "finalize - erro em snmp_add_var" << std::endl;
                snmp_close(sessionPtr);
                return;
            }

            std::cout << "Efetuando tentativa " << count+1 << "..." << std::endl;
            returned = snmp_synch_response(sessionPtr, pdu, &response);            
            if (returned == STAT_SUCCESS) {
                if ((response) && (response->errstat == SNMP_ERR_NOERROR || response->errstat == SNMP_ERR_NOTWRITABLE || response->errstat == SNMP_ERR_GENERR)) {
                    std::cout << "Gateway finalizado..." << std::endl;
                    break;
                }
                else {
                    std::cout << "Gateway nao foi finalizado..." << std::endl;
                    std::cout << "returned=" << returned << std::endl;
                    if (response) {
                        std::cout << "response=" << response->errstat << ".mensagem =" << snmp_errstring(response->errstat) << std::endl;
                    }
                }                
            }
            else {
                std::cout << "Gateway nao foi finalizado..." << std::endl;
                std::cout << "returned=" << returned << std::endl;
                if (response) {
                    std::cout << "response=" << response->errstat << ".mensagem =" << snmp_errstring(response->errstat) << std::endl;
                }
            }
            // Clean up: 1) free the response;
            if (response) {
                snmp_free_pdu(response);                
                response = NULL;
            }
            count++;
        } while (count != 3);
        snmp_close(sessionPtr);
        CHECK(returned == STAT_SUCCESS);
    }


4) Valgrind error :
-------------------

==10560== 
==10560== Process terminating with default action of signal 11 (SIGSEGV)
==10560==  Access not within mapped region at address 0x2
==10560==    at 0x403FC5D: agentx_check_packet (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==    by 0x72E639: _sess_read (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x72EFC8: snmp_sess_read2 (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x72F093: snmp_read2 (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x72F0F6: snmp_read (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x6FE3B7: snmp_synch_response_cb (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x404A4D4: agentx_synch_response (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==    by 0x404AA4E: agentx_unregister (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==    by 0x403689E: agentx_registration_callback (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==    by 0x750A59: snmp_call_callbacks (in /usr/lib/libnetsnmp.so.20.0.0)
==10560==    by 0x402B3FF: unregister_mib_context (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==    by 0x40329C2: netsnmp_unregister_handler (in /usr/lib/libnetsnmpagent.so.20.0.0)
==10560==  If you believe this happened as a result of a stack
==10560==  overflow in your program's main thread (unlikely but
==10560==  possible), you can try to increase the size of the
==10560==  main thread stack using the --main-stacksize= flag.
==10560==  The main thread stack size used in this run was 10485760.
==10560==



AVISO LEGAL

As informações contidas neste e-mail e nos arquivos anexos são confidenciais e para uso exclusivo do destinatário aqui indicado. 
Caso não seja o destinatário desta mensagem, por favor, apague o conteúdo do e-mail e notifique o remetente imediatamente. 
Qualquer utilização indevida ou divulgação do conteúdo deste e-mail, parcial ou total, é estritamente proibida e sujeita às penalidades legais. 
A transmissão de mensagens e arquivos pela internet não garante a integridade de seu conteúdo. 
O remetente não pode ser responsabilizado pela mensagem, caso ela tenha sido modificada.

------------------------------------------------------------------------------
WINDOWS 8 is here. 
Millions of people.  Your app in 30 days.
Visit The Windows 8 Center at Sourceforge for all your go to resources.
http://windows8center.sourceforge.net/
join-generation-app-and-make-money-coding-fast/

_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
snmpandsnmpd-20121026.jpg (image/jpeg, 44 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.