#include "windows.h"
#include "stdio.h"
#include "snmp.h"
#include "winsock.h"
BOOL NTmode=FALSE; //this will be set to true by an other function if we
are on NT
BOOL (__stdcall *pSnmpExtensionInit)(
IN DWORD dwTimeZeroReference,
OUT HANDLE *hPollForTrapEvent,
OUT AsnObjectIdentifier *supportedView);
BOOL (__stdcall *pSnmpExtensionQuery)(
IN BYTE requestType,
IN OUT RFC1157VarBindList *variableBindings,
OUT AsnInteger *errorStatus,
OUT AsnInteger *errorIndex);
LPVOID ( *pSnmpUtilMemAlloc)(IN UINT Size);
VOID ( *pSnmpUtilMemFree)(IN OUT LPVOID Addr);
VOID ( *pSnmpUtilVarBindFree)(IN OUT RFC1157VarBind *VarBind);
BOOLEAN LoadInetMibEntryPoints(void)
{
HINSTANCE hInetLib;
HINSTANCE hdll_util;
if( (hInetLib = LoadLibrary("inetmib1.dll"))==NULL)
return FALSE;
if( (pSnmpExtensionInit = (void *) GetProcAddress(
hInetLib,"SnmpExtensionInit"))==NULL )
return FALSE;
if( (pSnmpExtensionQuery = (void *) GetProcAddress(
hInetLib,"SnmpExtensionQuery"))==NULL )
{
return FALSE;
}
hdll_util = LoadLibraryEx("SNMPAPI",NULL,0);
pSnmpUtilMemAlloc = NULL;
pSnmpUtilMemFree = NULL;
pSnmpUtilVarBindFree = NULL;
if (hdll_util)
{
pSnmpUtilMemAlloc = (void
*)GetProcAddress(hdll_util,"SnmpUtilMemAlloc");
pSnmpUtilMemFree = (void
*)GetProcAddress(hdll_util,"SnmpUtilMemFree");
pSnmpUtilVarBindFree = (void
*)GetProcAddress(hdll_util,"SnmpUtilVarBindFree");
}
return TRUE;
}
void free_var(RFC1157VarBind* var)
{
if(pSnmpUtilMemFree)
{
if (NTmode)
pSnmpUtilMemFree(var->name.ids);
else
GlobalFree(var->name.ids);
// Free the mem block in the value bit depending on what it is...
switch(var->value.asnType)
{
case ASN_SEQUENCE:
case ASN_OCTETSTRING:
case ASN_RFC1155_IPADDRESS:
case ASN_RFC1155_OPAQUE:
// AsnOctetString is the base type for all the complex types.
if(var->value.asnValue.string.dynamic)
if (NTmode)
pSnmpUtilMemFree(var->value.asnValue.string.stream);
else
GlobalFree(var->value.asnValue.string.stream);
}
}
else
{
GlobalFree(var->name.ids);
}
}
int ipnow=0;
BOOLEAN user_does_tcp_data_transfer(void)
{
RFC1157VarBindList bindList;
RFC1157VarBind bindEntry;
UINT ipindelivers[] = { 1,3,6,1,2,1,4,9};
if (pSnmpExtensionInit==NULL && pSnmpExtensionQuery==NULL)
{
if( !LoadInetMibEntryPoints())
return FALSE;
if( !pSnmpExtensionInit( GetCurrentTime(), &hTrapEvent,
&hIdentifier ))
return FALSE;
}
bindEntry.name.idLength = 0x8;
bindEntry.name.ids = ipindelivers;
bindList.list = &bindEntry;
bindList.len = 1;
if( !pSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
&bindList, &errorStatus, &errorIndex ))
{
free_var(&bindEntry);
return FALSE;
}
if (!(bindEntry.value.asnType == ASN_GAUGE32 ||
bindEntry.value.asnType == ASN_INTEGER ||
bindEntry.value.asnType == ASN_INTEGER32 ||
bindEntry.value.asnType == ASN_COUNTER32 ||
bindEntry.value.asnType == ASN_UNSIGNED32))
{
free_var(&bindEntry);
return FALSE;
}
ipnow=bindEntry.value.asnValue.counter;
free_var(&bindEntry);
//some evaluation of ipnow here which can return TRUE or FALSE
}
I call user_does_tcp_data_transfer() in a timer loop at every 3 secs.
It works on win95 (maybe with a little memory leak) but it makes
Access Violation on NT.
What's wrong ?
Leo
Lajos Kelemen <lkel...@koti.tpo.fi> schrieb in im Newsbeitrag:
38DC84E5...@koti.tpo.fi...
> Hi
> I try to get the info when the user is active on the net by SNMP.
> I do something like this.
>
> #include "windows.h"
> #include "stdio.h"
> #include "snmp.h"
> #include "winsock.h"
>
> BOOL NTmode=FALSE; file://this will be set to true by an other function if
> file://some evaluation of ipnow here which can return TRUE or
Is the NT SNMP service running? The other question I have is why are you
trying to get information from SNMP this way? I think these interfaces are
intended primarily for people to produce SNMP extension DLLs that run from
the resident agent. It would be simpler to make a SNMP request through the
some API like WinSNMP or our SNMP control, using the loopback address (if
the agent is local which I presume it is) and a particular SNMP object OID
which provides the information you need.
BTW, the reason I asked the first question is that I'm not sure any
developer of an extension DLL for SNMP would consider the possibility that
requests could come from the SNMP agent and another application
simultaneously.
Have fun,
Brian
URL www.NuDesignTeam.com
Lajos Kelemen wrote:
> Hi
> I try to get the info when the user is active on the net by SNMP.
> I do something like this.
>
> #include "windows.h"
> #include "stdio.h"
> #include "snmp.h"
> #include "winsock.h"
>
> BOOL NTmode=FALSE; //this will be set to true by an other function if we
> //some evaluation of ipnow here which can return TRUE or FALSE
> }
>
> I call user_does_tcp_data_transfer() in a timer loop at every 3 secs.
> It works on win95 (maybe with a little memory leak) but it makes
> Access Violation on NT.
> What's wrong ?
>
> Leo
--
Brian Munshaw
URL www.NuDesignTeam.com
e-mail: bmun...@NuDesignTeam.com
> The problem is in the pSnmpUtilMemFree() call.
I have a working sample on http://mvps.org/win32/network/snmp.html. The
memory management is mostly done in wrapper classes around AsnAny and
AsnObjectIdentifier.
Differences that immediately caught my eye are:
- You use GlobalFree(). Why?
- You do not handle the case of freeing an AsnAny containing an OID.
- But most of all, free_var() calls Snmp...Free() on the name.ids of
the bindEntry, which you never allocated: you are, effectively,
trying to free a chunk of stack.
--
Cheers,
Felix.
If you post a reply, kindly refrain from emailing it, too.
Please consider migrating to microsoft.public.platformsdk.*
where the MS folks plan on hanging around. See you there!
> The other question I have is why are you
> trying to get information from SNMP this way?
Querying the inetmib1.dll SNMP extension agent directly has two major
advantages: the SNMP service need not be installed, much less running;
and it's free.
> - You use GlobalFree(). Why?
I suppose my var->name.ids is overwritten with some dynamically allocated
variable and for this variable GlobalAlloc was used
> - You do not handle the case of freeing an AsnAny containing an OID.
> - But most of all, free_var() calls Snmp...Free() on the name.ids of
> the bindEntry, which you never allocated: you are, effectively,
> trying to free a chunk of stack.
Presently free_var looks like this:
void free_var(RFC1157VarBind* var)
{
if(pSnmpUtilMemFree && pSnmpUtilOidFree)
{
if (NTmode)
{
// pSnmpUtilMemFree(var->name.ids);
pSnmpUtilOidFree(&var->name);
}
else
GlobalFree(var->name.ids);
// Free the mem block in the value bit depending on what it is...
switch(var->value.asnType)
{
case ASN_SEQUENCE:
case ASN_OCTETSTRING:
case ASN_RFC1155_IPADDRESS:
case ASN_RFC1155_OPAQUE:
// AsnOctetString is the base type for all the complex types.
if(var->value.asnValue.string.dynamic)
if (NTmode)
{
pSnmpUtilMemFree(var->value.asnValue.string.stream);
}
else
GlobalFree(var->value.asnValue.string.stream);
}
}
else
{
GlobalFree(var->name.ids);
}
}
Is this OK in your opinion ? It seems to work without access
violation and memory leaks.
Lajos