version 1.1.2.3, 2001/12/10 13:09:42
|
version 1.30, 2008/12/16 18:56:44
|
|
|
//%///////////////////////////////////////////////////////////////////////////// |
//%LICENSE//////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001 BMC Software, Hewlett Packard, IBM, The Open Group, |
// Licensed to The Open Group (TOG) under one or more contributor license |
// Tivoli Systems |
// 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 |
// Permission is hereby granted, free of charge, to any person obtaining a |
// of this software and associated documentation files (the "Software"), to |
// copy of this software and associated documentation files (the "Software"), |
// deal in the Software without restriction, including without limitation the |
// to deal in the Software without restriction, including without limitation |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
// sell copies of the Software, and to permit persons to whom the Software is |
// and/or sell copies of the Software, and to permit persons to whom the |
// furnished to do so, subject to the following conditions: |
// 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. |
|
// | // |
//============================================================================== |
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
// | // |
// Author: Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com) |
// 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. |
// | // |
// Modified By: |
////////////////////////////////////////////////////////////////////////// |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/Config.h> |
#include <Pegasus/Common/System.h> |
#include <fcntl.h> |
#include <Pegasus/Common/ArrayInternal.h> |
#include <unistd.h> |
#include <Pegasus/Common/InternalException.h> |
#include <sys/stat.h> |
|
#include "snmpDeliverTrap_emanate.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_NAMESPACE_BEGIN |
| |
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
void snmpDeliverTrap_emanate::deliverTrap(const String& trapOid, |
snmpDeliverTrap_emanate::snmpDeliverTrap_emanate() |
const String& enterprise, |
{ |
const String& destination, |
} |
const String& trapType, |
|
Array<String>& vbOids, |
snmpDeliverTrap_emanate::~snmpDeliverTrap_emanate() |
Array<String>& vbTypes, |
{ |
Array<String>& vbValues) |
} |
{ |
|
int fifo_fd; |
|
struct stat sbuf; |
// 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(); |
| |
trapHeader myTrapHeader; |
TransportInfo global_ti; |
trapHeader myTrapData; |
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; |
|
} |
|
} |
| |
cout << "NITIN: calling deliverTrap()" << endl; |
global_ti.t_ipPort = htons((unsigned short)portNumber); |
| |
if (stat(_SNMP_FIFO, &sbuf) == -1) |
// Community Name, default is public |
cout << "The fifo is not opened by EMANATE subagent" << endl; |
CString _community; |
|
if (securityName.size() == 0) |
|
{ |
|
String community; |
|
community.assign("public"); |
|
_community = community.getCString(); |
|
} |
else | else |
{ | { |
if ((fifo_fd = open (_SNMP_FIFO, O_WRONLY|O_NONBLOCK)) == -1) |
_community = securityName.getCString(); |
cout << "The fifo is not opened for reading. Subagent is not running" << endl; |
} |
|
|
|
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 | else |
{ | { |
strcpy(myTrapHeader.destination, _CString(destination)); |
// |
strcpy(myTrapHeader.snmpType, "SNMPV2"); |
// if the trapOid is not one of the standard traps: |
strcpy(myTrapHeader.enterprise, _CString(enterprise)); |
// then 1) the generic-trap parameter must be set to 6, |
strcpy(myTrapHeader.trapOid, _CString(trapOid)); |
// 2) if the next-to-last sub-identifier of the |
myTrapHeader.variable_packets = vbOids.size(); |
// 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 (write(fifo_fd, &myTrapHeader, sizeof(myTrapHeader)) <=0) |
if (String::equalNoCase(vbTypes[i], "OctetString")) |
cout << "Error in writing" << endl; |
{ |
|
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 | else |
{ | { |
for(int packets = 0; packets<vbOids.size(); packets++) |
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 |
{ | { |
trapData myTrapData; |
vblast->next_var = vb; |
strcpy(myTrapData.vbOid, _CString(vbOids[packets])); |
vblast = vblast->next_var; |
strcpy(myTrapData.vbType, _CString(vbTypes[packets])); |
|
strcpy(myTrapData.vbValue, _CString(vbValues[packets])); |
|
write(fifo_fd, &myTrapData, sizeof(myTrapData)); |
|
} | } |
|
|
} | } |
|
|
|
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; |
} | } |
close (fifo_fd); |
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; |
|
|
|
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; |
} | } |
} | } |
| |