(file) Return to snmpDeliverTrap_emanate.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Handler / snmpIndicationHandler

File: [Pegasus] / pegasus / src / Pegasus / Handler / snmpIndicationHandler / snmpDeliverTrap_emanate.cpp (download)
Revision: 1.26, Fri Sep 7 19:08:39 2007 UTC (16 years, 9 months ago) by dmitry.mikulin
Branch: MAIN
CVS Tags: TASK-PEP305_VXWORKS-root, TASK-PEP305_VXWORKS-branch-pre-solaris-port, TASK-PEP305_VXWORKS-branch-post-solaris-port, TASK-PEP305_VXWORKS-branch-beta2, TASK-PEP305_VXWORKS-branch, TASK-PEP305_VXWORKS-2008-10-23
Changes since 1.25: +26 -4 lines
BUG#: 5082
TITLE: gethostbyname/gethostbyaddr may fail with TRY_AGAIN error
DESCRIPTION: backing out the changes due to a small bug.

//%2006////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
// IBM Corp.; EMC Corporation, The Open Group.
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; Symantec Corporation; The Open Group.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//==============================================================================
//
//%/////////////////////////////////////////////////////////////////////////////

#include <Pegasus/Common/System.h>
#include <Pegasus/Common/ArrayInternal.h>
#include <Pegasus/Common/InternalException.h>
#include "snmpDeliverTrap_emanate.h"

#include <Pegasus/Common/MessageLoader.h>

// EMANATE specific declarations and entry points - MUST be in begining
// and outside NAMESPACE.

// master agent needs these two declarations for communication with sub-agent.
// Following two declarations must be in the CODE.

#include <prnt_lib.h>  // MUST be at the end in include list.

static const char* sr_filename = __FILE__;

IPCFunctionP IPCfp;  /* IPC functions pointer */

// This code would normally be generated by Emanate from defined MIB objects.
// Since we do not have MIB objects defined, just defined here to load
// subagent as library. OidList[] provides objects for entry point to master
// agent.

// The objects internal to the agent
ObjectInfo OidList[] =
{
    {
        { 0, NULL },
#ifndef LIGHT
        NULL,
#endif /* LIGHT */
        0, 0, 0, 0,
        NULL, NULL
    }
};

// This code would normally be generated by Emanate in k_* routine from
// defined MIB objects.  Since we do not have MIB objects defined, just
// define here to pass compile and enable entry point for master agent to
// start communication with library.

// Called by the master agent during initialization */
int k_initialize()
{
    return 1;
}

// END EMANATE specific declarations.

PEGASUS_NAMESPACE_BEGIN

PEGASUS_USING_STD;

snmpDeliverTrap_emanate::snmpDeliverTrap_emanate()
{
}

snmpDeliverTrap_emanate::~snmpDeliverTrap_emanate()
{
}


// initialize sub-agent

// This also defines the communication protocol to be used between master
// and sub-agent.

void snmpDeliverTrap_emanate::initialize()
{
#ifndef SR_UDS_IPC
    InitIPCArrayTCP(&IPCfp);
#else /* SR_UDS_IPC */
    InitIPCArrayUDS(&IPCfp);
#endif /* SR_UDS_IPC */

    if (InitSubagent() == -1)
    {
        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
            _MSG_INITSUBAGENT_FAILED_KEY,
            _MSG_INITSUBAGENT_FAILED));

    }
}

void snmpDeliverTrap_emanate::terminate()
{
    //
    // Close the connection to the Master Agent and shut down the
    // Subagent
    //
    EndSubagent();
}


void snmpDeliverTrap_emanate::deliverTrap(
        const String& trapOid,
        const String& securityName,
        const String& targetHost,
        const Uint16& targetHostFormat,
        const String& otherTargetHostFormat,
        const Uint32& portNumber,
        const Uint16& snmpVersion,
        const String& engineID,
        const Array<String>& vbOids,
        const Array<String>& vbTypes,
        const Array<String>& vbValues)
{
    VarBind* vbhead = NULL;
    VarBind* vb = NULL;
    VarBind* vblast = NULL;

    OID* object = NULL;

    // Translate a string into an OID
    OID* sendtrapOid = MakeOIDFromDot(trapOid.getCString());

    if (sendtrapOid == NULL)
    {
        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
            _MSG_INVALID_KEY,
            _MSG_INVALID_TRAPOID));
    }

    // Destination : convert targetHost into Transport

    CString trap_dest = targetHost.getCString();

    TransportInfo global_ti;
    global_ti.type = SR_IP_TRANSPORT;

    switch (targetHostFormat)
    {
        case _HOST_NAME:
        {
            char* ipAddr = _getIPAddress(trap_dest);

            if (ipAddr == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                       _MSG_DESTINATION_NOT_FOUND_KEY,
                       _MSG_DESTINATION_NOT_FOUND));

            }
            global_ti.t_ipAddr = inet_addr(trap_dest);
            break;
        }
        case _IPV4_ADDRESS:
        {
            global_ti.t_ipAddr = inet_addr(trap_dest);
            break;
        }
        default:
        {
            throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
                MessageLoaderParms(
                    _MSG_TARGETHOSTFORMAT_NOT_SUPPORTED_KEY,
                    _MSG_TARGETHOSTFORMAT_NOT_SUPPORTED));
            break;
        }
    }

    global_ti.t_ipPort = htons((unsigned short)portNumber);

    // Community Name, default is public
    CString _community;
    if (securityName.size() == 0)
    {
        String community;
        community.assign("public");
        _community = community.getCString();
    }
    else
    {
        _community = securityName.getCString();
    }

    OctetString* community_name = MakeOctetStringFromText(_community);

    if (community_name == NULL)
    {
        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
            _MSG_INVALID_SECURITY_NAME_KEY,
            _MSG_INVALID_SECURITY_NAME));
    }

    // getting IP address of the host

    CString hostname = System::getHostName().getCString();
    char* IP_string = _getIPAddress(hostname);

    // formatting agent(host) address into OctetString format

    OctetString* agent_addr;

    SR_INT32 s1, s2, s3, s4;
    SR_UINT32 ipaddr;

    // pull out each of the 4 octet values from IP address

    sscanf(IP_string,"%d.%d.%d.%d", &s1, &s2, &s3, &s4);

    // validate the values for s1, s2, s3, and s4 to make sure values are
    // between 0 and 255
    if (!_isValidOctet(s1) || !_isValidOctet(s2) ||
        !_isValidOctet(s3) || !_isValidOctet(s4))
    {
        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
            _MSG_INVALID_OCTET_VALUE_KEY,
            _MSG_INVALID_OCTET_VALUE));
    }

    // create an empty 4 length OctetString

    agent_addr = MakeOctetString(NULL,4);

    if (agent_addr == NULL)
    {
        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
            _MSG_CREATE_OCTET_FAILED_KEY,
            _MSG_CREATE_OCTET_FAILED));
    }

    // fill in values for OctetString

    agent_addr->octet_ptr[0] = (unsigned char)s1;
    agent_addr->octet_ptr[1] = (unsigned char)s2;
    agent_addr->octet_ptr[2] = (unsigned char)s3;
    agent_addr->octet_ptr[3] = (unsigned char)s4;

    // specTrap from trapOid.

    SR_INT32 genTrap = 0;
    SR_INT32 specTrap = 0;

    OID* enterpriseOid ;

    Array<String> standard_traps;

    standard_traps.append(String("1.3.6.1.6.3.1.1.5.1"));
    standard_traps.append(String("1.3.6.1.6.3.1.1.5.2"));
    standard_traps.append(String("1.3.6.1.6.3.1.1.5.3"));
    standard_traps.append(String("1.3.6.1.6.3.1.1.5.4"));
    standard_traps.append(String("1.3.6.1.6.3.1.1.5.5"));
    standard_traps.append(String("1.3.6.1.6.3.1.1.5.6"));

    Array<String> oids;
    String tmpoid = trapOid;

    while(tmpoid.find(".") != PEG_NOT_FOUND)
    {
        oids.append(tmpoid.subString(0, tmpoid.find(".")));
        tmpoid = tmpoid.subString(tmpoid.find(".") + 1);
    }

    oids.append(tmpoid);

    String ent;
    if (Contains(standard_traps, trapOid))
    {
        //
        // if the trapOid is one of the standard traps,
        // then the SNMPV1 enterprise parameter must be set
        // to the value of the trapOid, the generic-trap
        // parameter must be set to one of (0 - 5), and the
        // specific-trap parameter must be set to 0
        //

        enterpriseOid = sendtrapOid;

        // the generic trap is last sub-identifier of the
        // trapOid minus 1
        genTrap = atoi(oids[oids.size() - 1].getCString()) - 1;
        specTrap = 0;
    }
    else
    {
        //
        // if the trapOid is not one of the standard traps:
        // then 1) the generic-trap parameter must be set to 6,
        // 2) if the next-to-last sub-identifier of the
        // trapOid is zero, then the SNMPV1 enterprise
        // parameter is the trapOid with the last 2
        // sub-identifiers removed, otherwise, the
        // SNMPV1 enterprise parameter is the trapOid
        // with the last sub-identifier removed;
        // 3) the SNMPv1 specific-trap parameter is the last
        // sub-identifier of the trapOid;
        //

        genTrap = 6;

        specTrap = atoi(oids[oids.size()-1].getCString());

        ent = oids[0];
        for (Uint8 i = 1; i < oids.size()-2; i++)
        {
            ent = ent + "." + oids[i];
        }

        if (oids[oids.size()-2] != "0")
        {
            ent = ent + "." + oids[oids.size()-2];
        }

        enterpriseOid = MakeOIDFromDot(ent.getCString());

        if (enterpriseOid == NULL)
        {
            throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
                _MSG_INVALID_ENTERPRISEOID_KEY,
                _MSG_INVALID_ENTERPRISEOID));
        }
    }

    // creates VarBind
    for (Uint32 i = 0; i < vbOids.size(); i++)
    {
        CString _vbOid = vbOids[i].getCString();
        CString _vbValue = vbValues[i].getCString();

        if ((object = MakeOIDFromDot(_vbOid)) == NULL)
        {
            throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
                _MSG_INVALID_PROPERTYOID_KEY,
                _MSG_INVALID_PROPERTYOID));
        }

        if (String::equalNoCase(vbTypes[i], "OctetString"))
        {
            OctetString* value;

            value = CloneOctetString(MakeOctetStringFromText(_vbValue));
            if (value == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_INVALID_PROPERTYVALUE_KEY,
                        _MSG_INVALID_PROPERTYVALUE));
            }

            if ((vb = MakeVarBindWithValue(
                     object,
                     (OID*) NULL,
                     OCTET_PRIM_TYPE,
                     value)) == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_MAKE_VARBIND_FAILED_FOR_OCTET_PRIM_TYPE_KEY,
                        _MSG_MAKE_VARBIND_FAILED_FOR_OCTET_PRIM_TYPE));
            }
        }
        else if (String::equalNoCase(vbTypes[i], "OID"))
        {
            void* value = MakeOIDFromDot(_vbValue);
            if (value == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_INVALID_PROPERTYVALUE_KEY,
                        _MSG_INVALID_PROPERTYVALUE));
            }

            if ((vb = MakeVarBindWithValue(
                     object,
                     (OID*) NULL,
                     OBJECT_ID_TYPE,
                     value)) == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_MAKE_VARBIND_FAILED_FOR_OBJECT_ID_TYPE_KEY,
                        _MSG_MAKE_VARBIND_FAILED_FOR_OBJECT_ID_TYPE));
            }
        }
        else
        {
            int vbvalue = atoi(_vbValue);
            void* value = &vbvalue;

            if (value == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_INVALID_PROPERTYVALUE_KEY,
                        _MSG_INVALID_PROPERTYVALUE));
            }

            if ((vb = MakeVarBindWithValue(
                     object,
                     (OID*) NULL,
                     INTEGER_TYPE,
                     value)) == NULL)
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        _MSG_MAKE_VARBIND_FAILED_FOR_INTEGER_TYPE_KEY,
                        _MSG_MAKE_VARBIND_FAILED_FOR_INTEGER_TYPE));
            }
        }

        if (i == 0)
        {
            vbhead = vb;
            vblast = vb;
        }
        else
        {
            vblast->next_var = vb;
            vblast = vblast->next_var;
        }

    }

    vblast->next_var = NULL;

    // Now send the trap
    switch (snmpVersion)
    {
        case _SNMPv1_TRAP:
        {
            SendNotificationToDestSMIv1Params(
            1,                                  // notifyType - TRAP
            genTrap,                            // genTrap
            specTrap,                           // specTrap
            enterpriseOid,                      // enterprise
            agent_addr,                         // agent_addr
            vbhead,                             // vb
            NULL,                               // contextName
            1,                                  // retryCount
            1,                                  // timeout
            community_name,                     // securityName,
            SR_SECURITY_LEVEL_NOAUTH,           // securityLevel
            SR_SECURITY_MODEL_V1,               // securityModel
            &global_ti,                         // Transport Info
            0);                                 // cfg_chk
            break;
        }
        case _SNMPv2C_TRAP:
        {
            SendNotificationToDestSMIv2Params(
            (SR_INT32)SNMPv2_TRAP_TYPE,         // notifyType - NOTIFICATION
            sendtrapOid,                        // snmpTrapOID
            agent_addr,                         // agent_addr
            vbhead,                             // vb
            NULL,                               // contextName
            1,                                  // retryCount
            100,                                // timeout
            community_name,                     // securityName or community
            SR_SECURITY_LEVEL_NOAUTH,           // securityLevel
            SR_SECURITY_MODEL_V2C,              // securityModel
            &global_ti,                         // TransportInfo
            0);                                 // cfg_chk
            break;
        }
        default:
        {
            throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
                MessageLoaderParms(
                    _MSG_VERSION_NOT_SUPPORTED_KEY,
                    _MSG_VERSION_NOT_SUPPORTED));
            break;
        }
    }

    // Free OID built by calls MakeOIDFromDot()
    FreeOID(sendtrapOid);
    FreeOID(enterpriseOid);
    FreeOID(object);

    // Free the data structures allocated and built by calls
    // MakeOctetString() and MakeOctetStringFrom Text()
    FreeOctetString(community_name);
    FreeOctetString(agent_addr);

    // Free the VarBind data structures allocated and built
    // by calls MakeVarBindWithValue()
    FreeVarBindList(vbhead);
    FreeVarBindList(vb);
    FreeVarBindList(vblast);
}

// get the IP address of a host
char* snmpDeliverTrap_emanate::_getIPAddress(const CString& hostName)
{
    struct hostent* targetHostInfo;
    struct in_addr in;

#if defined(PEGASUS_OS_LINUX)
        char hostEntryBuffer[8192];
        struct hostent hostEntryStruct;
        int hostEntryErrno;

        gethostbyname_r(
            hostName,
            &hostEntryStruct,
            hostEntryBuffer,
            sizeof(hostEntryBuffer),
            &targetHostInfo,
            &hostEntryErrno);
#elif defined(PEGASUS_OS_SOLARIS)
        char hostEntryBuffer[8192];
        struct hostent hostEntryStruct;
        int hostEntryErrno;

        targetHostInfo = gethostbyname_r(
            (char*)hostName,
            &hostEntryStruct,
            hostEntryBuffer,
            sizeof(hostEntryBuffer),
            &hostEntryErrno);
#else
    targetHostInfo = gethostbyname(hostName);
#endif

    if (targetHostInfo == NULL)
    {
        return NULL;
    }

    char** networkAddr;
    networkAddr = targetHostInfo->h_addr_list;
    (void)memcpy(&in.s_addr, *networkAddr, sizeof(in.s_addr));
    char* ipAddr = inet_ntoa(in);
    return(ipAddr);
}

// check the value of each part of an IP address which should be
// between 0 and 255
Boolean snmpDeliverTrap_emanate::_isValidOctet(const Uint32& octetValue)
{
    if (octetValue > 0 && octetValue < 255)
    {
        return true;
    }
    else
    {
        return false;
    }
}

PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2