summaryrefslogtreecommitdiffabout
path: root/shared-code/SNMPExtDll.h
Side-by-side diff
Diffstat (limited to 'shared-code/SNMPExtDll.h') (more/less context) (ignore whitespace changes)
-rw-r--r--shared-code/SNMPExtDll.h252
1 files changed, 252 insertions, 0 deletions
diff --git a/shared-code/SNMPExtDll.h b/shared-code/SNMPExtDll.h
new file mode 100644
index 0000000..14c920d
--- a/dev/null
+++ b/shared-code/SNMPExtDll.h
@@ -0,0 +1,252 @@
+#ifndef __SNMPEXTDLL_H
+#define __SNMPEXTDLL_H
+
+#include "snmpeer.h"
+
+#include <snmp.h>
+
+namespace Klever {
+
+class CSNMPExtDLL : public CSNMPeer {
+public:
+ HINSTANCE m_hInstance;
+ HANDLE m_hEvent;
+ AsnObjectIdentifier m_OID;
+ BOOL (SNMP_FUNC_TYPE *m_extInit)(DWORD dw,HANDLE h,AsnObjectIdentifier* aoid);
+ BOOL (SNMP_FUNC_TYPE *m_extQuery)(BYTE b,RFC1157VarBindList* rvbl,AsnInteger* ai1,AsnInteger* ai2);
+ BOOL (SNMP_FUNC_TYPE *m_extTrap)(AsnObjectIdentifier*,AsnNetworkAddress*,AsnInteger*,AsnInteger*,AsnTimeticks*,RFC1157VarBindList*);
+
+ HINSTANCE m_hSNMPAPI;
+ void (SNMP_FUNC_TYPE *m_snmpOIDFree)(AsnObjectIdentifier*);
+ LPVOID (SNMP_FUNC_TYPE *m_snmpAlloc)(UINT);
+ void (SNMP_FUNC_TYPE *m_snmpFree)(LPVOID);
+ void (SNMP_FUNC_TYPE *m_snmpVBLFree)(RFC1157VarBindList* vbl);
+ void InitSNMP() {
+ m_hSNMPAPI = ::LoadLibraryEx("SNMPAPI",NULL,0);
+ if(!m_hSNMPAPI)
+ return;
+ *(FARPROC*)&m_snmpOIDFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilOidFree");
+ *(FARPROC*)&m_snmpAlloc = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilMemAlloc");
+ *(FARPROC*)&m_snmpFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilMemFree");
+ *(FARPROC*)&m_snmpVBLFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilVarBindListFree");
+ if(
+ (m_snmpFree && !m_snmpAlloc) ||
+ (m_snmpAlloc && !m_snmpFree)
+ )
+ DeinitSNMP();
+ }
+ void DeinitSNMP() {
+ if(!m_hSNMPAPI)
+ return;
+ ::FreeLibrary(m_hSNMPAPI);
+ m_hSNMPAPI=NULL;
+ }
+ void SNMPFreeOID(AsnObjectIdentifier* oid) {
+ if(m_hSNMPAPI && m_snmpOIDFree)
+ (*m_snmpOIDFree)(oid);
+ else
+ ::GlobalFree((HGLOBAL)oid->ids);
+ }
+ LPVOID SNMPAlloc(UINT size) {
+ if(m_hSNMPAPI && m_snmpAlloc)
+ return (*m_snmpAlloc)(size);
+ else
+ return ::GlobalAlloc(GMEM_FIXED,size);
+ }
+ void SNMPFree(LPVOID addr) {
+ if(m_hSNMPAPI && m_snmpFree)
+ (*m_snmpFree)(addr);
+ else
+ :: GlobalFree((HGLOBAL)addr);
+ }
+ void SNMPFreeVBL(RFC1157VarBindList& vbl) {
+ if(m_hSNMPAPI && m_snmpVBLFree)
+ (*m_snmpVBLFree)(&vbl);
+ else{
+ for(UINT tmp=0;tmp<vbl.len;tmp++) {
+ SNMPFree(vbl.list[tmp].name.ids);
+ switch(vbl.list[tmp].value.asnType){
+ case ASN_OCTETSTRING:
+ case ASN_SEQUENCE:
+ case ASN_RFC1155_IPADDRESS:
+ case ASN_RFC1155_OPAQUE:
+// case ASN_RFC1213_DISPSTRING:
+ if(vbl.list[tmp].value.asnValue.arbitrary.dynamic)
+ SNMPFree(vbl.list[tmp].value.asnValue.arbitrary.stream);
+ break;
+ case ASN_OBJECTIDENTIFIER:
+ SNMPFree(vbl.list[tmp].value.asnValue.object.ids);
+ break;
+ default:
+ break;
+ }
+ }
+ SNMPFree(vbl.list);
+ }
+ }
+
+ BOOL SNMPBuildVBL(RFC1157VarBindList& vbl,CSNMPVarBindList& in) {
+ vbl.len = in.GetCount();
+ vbl.list = (RFC1157VarBind*)SNMPAlloc(sizeof(RFC1157VarBind)*vbl.len);
+ POSITION p = in.GetHeadPosition();
+ UINT ptr = 0;
+ while(p){
+ CSNMPVarBind& vb = in.GetNext(p);
+ ASSERT(ptr<vbl.len);
+ SNMPBuildVB(vbl.list[ptr++],vb);
+ }
+ return TRUE;
+ }
+ BOOL SNMPBuildVB(RFC1157VarBind& vb,CSNMPVarBind& in) {
+ ASSERT(in.name.type==CASNAny::typeASNOID);
+ return SNMPBuildOID(vb.name,in.name.value.oid) && SNMPBuildAA(vb.value,in.value);
+ }
+ BOOL SNMPBuildAA(AsnAny& aa,CASNAny& in) {
+ aa.asnType=in.type;
+ switch(in.type) {
+ case CASNAny::typeASNInteger:
+ aa.asnValue.number=in.value.number; break;
+ case CASNAny::typeASNOctetString:
+// case CASNAny::typeASNDispString:
+ SNMPBuildOS(aa.asnValue.string,in.value.string); break;
+ case CASNAny::typeASNNull:
+ break;
+ case CASNAny::typeASNOID:
+ SNMPBuildOID(aa.asnValue.object,in.value.oid); break;
+ case CASNAny::typeASNSequence:
+// case CASNAny::typeASNSequenceOf:
+ SNMPBuildOS(aa.asnValue.sequence,in.value.sequence); break;
+ case CASNAny::typeASNIP:
+ SNMPBuildFLOS(aa.asnValue.address,(LPBYTE)&in.value.ip,sizeof(in.value.ip)); break;
+ case CASNAny::typeASNCounter:
+ aa.asnValue.counter = in.value.counter; break;
+ case CASNAny::typeASNGauge:
+ aa.asnValue.gauge = in.value.gauge; break;
+ case CASNAny::typeASNTicks:
+ aa.asnValue.ticks = in.value.ticks; break;
+ case CASNAny::typeASNOpaque:
+ ASSERT(in.storeType==CASNAny::storeDynamic);
+ SNMPBuildOS(aa.asnValue.arbitrary,in.value.data); break;
+ break;
+ default:
+ ASSERT(FALSE);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ BOOL SNMPBuildOS(AsnOctetString& os,CASNAny::asnOctetString& in) {
+ return SNMPBuildFLOS(os,in.data,in.size);
+ }
+ BOOL SNMPBuildOID(AsnObjectIdentifier& oid,CASNAny::asnOID& in) {
+ oid.idLength = in.size/sizeof(UINT);
+ ASSERT(!(in.size%sizeof(UINT)));
+ VERIFY(oid.ids = (UINT*)SNMPAlloc(in.size));
+ memmove(oid.ids,in.data,in.size);
+ return TRUE;
+ }
+ BOOL SNMPBuildFLOS(AsnOctetString& os,LPBYTE data,UINT size) {
+ os.length = size;
+ VERIFY(os.stream = (BYTE*)SNMPAlloc(os.length));
+ os.dynamic=TRUE;
+ memmove(os.stream,data,size);
+ return TRUE;
+ }
+ BOOL SNMPParseVBL(RFC1157VarBindList& vbl,CSNMPVarBindList& ou) {
+ for(UINT tmp=0;tmp<vbl.len;tmp++){
+ CSNMPVarBind vb;
+ SNMPParseVB(vbl.list[tmp],vb);
+ ou.AddTail(vb);
+ }
+ return TRUE;
+ }
+ BOOL SNMPParseVB(RFC1157VarBind& vb,CSNMPVarBind& ou) {
+ ou.name.Set(CASNAny::typeASNOID,(LPBYTE)vb.name.ids,vb.name.idLength*sizeof(UINT));
+ return SNMPParseAA(vb.value,ou.value);
+ }
+ BOOL SNMPParseAA(AsnAny& aa,CASNAny& ou) {
+ switch(aa.asnType){
+ case ASN_INTEGER:
+ ou.Set(CASNAny::typeASNInteger,aa.asnValue.number); break;
+ case ASN_OCTETSTRING:
+// case ASN_RFC1213_DISPSTRING:
+ ou.Set(CASNAny::typeASNOctetString,aa.asnValue.string.stream,aa.asnValue.string.length); break;
+ case ASN_OBJECTIDENTIFIER:
+ ou.Set(CASNAny::typeASNOID,(LPBYTE)aa.asnValue.object.ids,aa.asnValue.object.idLength);
+ SNMPParseOID(aa.asnValue.object,ou.value.oid); break;
+ case ASN_SEQUENCE:
+ ou.Set(CASNAny::typeASNSequence,aa.asnValue.sequence.stream,aa.asnValue.sequence.length); break;
+ case ASN_RFC1155_IPADDRESS:
+ SNMPParseIP(aa.asnValue.address,ou); break;
+ case ASN_RFC1155_COUNTER:
+ ou.Set(CASNAny::typeASNCounter,(LONG)aa.asnValue.counter); break;
+ case ASN_RFC1155_GAUGE:
+ ou.Set(CASNAny::typeASNGauge,(LONG)aa.asnValue.gauge); break;
+ case ASN_RFC1155_TIMETICKS:
+ ou.Set(CASNAny::typeASNTicks,(LONG)aa.asnValue.ticks); break;
+ case ASN_RFC1155_OPAQUE:
+ ou.Set(CASNAny::typeASNOpaque,aa.asnValue.arbitrary.stream,aa.asnValue.arbitrary.length); break;
+ case ASN_NULL:
+ ou.Free(); break;
+ default:
+ ASSERT(FALSE);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ BOOL SNMPParseOID(AsnObjectIdentifier& oid,CASNAny::asnOID& ou) {
+ ASSERT(ou.size==(oid.idLength*sizeof(UINT)));
+ memmove(ou.data,oid.ids,ou.size);
+ return TRUE;
+ }
+ BOOL SNMPParseIP(AsnIPAddress& ip,CASNAny& ou) {
+ in_addr i;
+ if(ip.length>sizeof(i))
+ return FALSE;
+ i.s_addr=0;
+ memmove(&i,ip.stream,ip.length);
+ ou.Set(i);
+ return TRUE;
+ }
+
+
+ CSNMPExtDLL(LPCTSTR dllName) : m_hInstance(NULL) { InitSNMP(); Init(dllName); }
+ ~CSNMPExtDLL() { Deinit(); DeinitSNMP(); }
+
+ BOOL Init(LPCTSTR dllName) {
+ Deinit();
+ m_hInstance = ::LoadLibraryEx(dllName,NULL,0);
+ if(!m_hInstance)
+ return FALSE;
+ *(FARPROC*)&m_extInit = ::GetProcAddress(m_hInstance,"SnmpExtensionInit");
+ *(FARPROC*)&m_extQuery = ::GetProcAddress(m_hInstance,"SnmpExtensionQuery");
+ *(FARPROC*)&m_extTrap = ::GetProcAddress(m_hInstance,"SnmpExtensionTrap");
+ if(!(m_extInit && m_extQuery && m_extTrap)){
+ Deinit();
+ return FALSE;
+ }
+ if(!((*m_extInit)(GetCurrentTime(),&m_hEvent,&m_OID))){
+ Deinit();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ void Deinit() {
+ if(!m_hInstance)
+ return;
+ ::FreeLibrary(m_hInstance);
+ }
+ virtual BOOL Request(BYTE type,CSNMPVarBindList& in,CSNMPVarBindList& ou) {
+ RFC1157VarBindList vbl;
+ SNMPBuildVBL(vbl,in);
+ AsnInteger errorStatus, errorIndex;
+ (*m_extQuery)(type,&vbl,&errorStatus,&errorIndex);
+ ou.RemoveAll();
+ SNMPParseVBL(vbl,ou);
+ SNMPFreeVBL(vbl);
+ return TRUE;
+ }
+};
+
+};
+
+#endif // __SNMPEXTDLL_H