//%LICENSE//////////////////////////////////////////////////////////////// // // Licensed to The Open Group (TOG) under one or more contributor license // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with // this work for additional information regarding copyright ownership. // Each contributor licenses this file to you under the OpenPegasus Open // Source License; you may not use this file except in compliance with the // License. // // 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 #include #include #include "snmpDeliverTrap_emanate.h" #include // 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 // 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 Uint8& snmpSecLevel, const Uint8& snmpSecAuthProto, const Array& snmpSecAuthKey, const Uint8& snmpSecPrivProto, const Array& snmpSecPrivKey, const Array& vbOids, const Array& vbTypes, const Array& 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)); } } 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 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 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)); } } // 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; char hostEntryBuffer[8192]; struct hostent hostEntryStruct; targetHostInfo = System::getHostByName(hostName, &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer)); 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