2020-09-30 17:12:32 +02:00

1323 lines
28 KiB
C

/*++
Copyright (c) 1992-1996 Microsoft Corporation
Module Name:
snmp.c
Abstract:
Contains routines and definitions that are independant to any SNMP API.
Environment:
User Mode - Win32
Revision History:
10-May-1996 DonRyan
Removed banner from Technology Dynamics, Inc.
--*/
#ifdef _SNMPDLL_
//--------------------------- WINDOWS DEPENDENCIES --------------------------
#ifndef DOS
#include <nt.h>
#include <windef.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#endif
//--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
#include <winsock.h>
#include <wsipx.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <ctype.h>
//--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
//--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
#include <snmp.h>
#include <snmputil.h>
#include <evtlog.h>
#include <wellknow.h>
#include <regconf.h>
//--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
DWORD g_uptimeReference = 0;
DWORD g_platformId = 0;
INT g_nLogType = SNMP_OUTPUT_TO_DEBUGGER;
INT g_nLogLevel = SNMP_LOG_SILENT;
AsnObjectIdentifier * g_enterprise = NULL;
#if DBG
DWORD g_nBytesTotal = 0;
#endif
//--------------------------- PRIVATE CONSTANTS -----------------------------
#define MAX_DEBUG_LEN 512
//--------------------------- PRIVATE STRUCTS -------------------------------
//--------------------------- PRIVATE VARIABLES -----------------------------
static UINT idsWindowsNTWorkstation[] = {1,3,6,1,4,1,311,1,1,3,1,1};
static UINT idsWindowsNTServer[] = {1,3,6,1,4,1,311,1,1,3,1,2};
static UINT idsWindowsNTDC[] = {1,3,6,1,4,1,311,1,1,3,1,3};
static UINT idsWindows[] = {1,3,6,1,4,1,311,1,1,3,2};
static AsnObjectIdentifier oidWindowsNTWorkstation = {
sizeof(idsWindowsNTWorkstation)/sizeof(UINT),
idsWindowsNTWorkstation
};
static AsnObjectIdentifier oidWindowsNTServer = {
sizeof(idsWindowsNTServer)/sizeof(UINT),
idsWindowsNTServer
};
static AsnObjectIdentifier oidWindowsNTDC = {
sizeof(idsWindowsNTDC)/sizeof(UINT),
idsWindowsNTDC
};
static AsnObjectIdentifier oidWindows = {
sizeof(idsWindows)/sizeof(UINT),
idsWindows
};
//--------------------------- PRIVATE MACROS --------------------------------
#define bcopy(slp, dlp, size) (void)memcpy(dlp, slp, size)
//--------------------------- PRIVATE PROTOTYPES ----------------------------
//--------------------------- PRIVATE PROCEDURES ----------------------------
AsnObjectIdentifier *
InitializeEnterpriseOID(
)
{
// default to generic windows enterprise oid
AsnObjectIdentifier * enterprise = &oidWindows;
// check to see if the platform is winnt
if (g_platformId == VER_PLATFORM_WIN32_NT) {
HMODULE NtDllHandle = NULL;
FARPROC lpfnRtlGetNtProductType = NULL;
NT_PRODUCT_TYPE NtProductType;
// assume this is just a workstation
enterprise = &oidWindowsNTWorkstation;
// load the internal utility library
NtDllHandle = LoadLibrary(TEXT("ntdll.dll"));
// validate handle
if (NtDllHandle) {
// resolve address
lpfnRtlGetNtProductType = GetProcAddress(
NtDllHandle,
TEXT("RtlGetNtProductType")
);
// validate pointer
if (lpfnRtlGetNtProductType) {
// let the system determine product type
(*lpfnRtlGetNtProductType)(&NtProductType);
// point to the correct enterprise oid
if (NtProductType == NtProductServer) {
// this is a stand-alone server
enterprise = &oidWindowsNTServer;
} else if (NtProductType == NtProductLanManNt) {
// this is a PDC or a BDC
enterprise = &oidWindowsNTDC;
}
}
// unload library
FreeLibrary(NtDllHandle);
}
}
SNMPDBG((
SNMP_LOG_TRACE,
"SNMP: INIT: enterprise is %s.\n",
SnmpUtilOidToA(enterprise)
));
return enterprise;
}
//--------------------------- PUBLIC PROCEDURES -----------------------------
#else // _SNMPDLL_
#include <snmp.h>
#endif // _SNMPDLL_
#ifdef _SNMPDLL_
BOOLEAN
InitializeDLL(
IN PVOID DllHandle,
IN ULONG Reason,
IN LPVOID lpReserved OPTIONAL
)
{
WSADATA wsaData;
if (Reason == DLL_PROCESS_ATTACH)
{
OSVERSIONINFO osInfo;
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osInfo))
return FALSE;
if ((osInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) &&
(osInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS))
return FALSE;
g_platformId = osInfo.dwPlatformId;
g_enterprise = InitializeEnterpriseOID();
DisableThreadLibraryCalls(DllHandle);
if (WSAStartup(0x0101, &wsaData))
{
WSACleanup();
return FALSE;
}
}
else if (Reason == DLL_PROCESS_DETACH)
{
WSACleanup();
}
return TRUE;
} // InitializeDLL
// SnmpSvcInitUptime
// Initializes global shared variable.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
DWORD
SNMP_FUNC_TYPE SnmpSvcInitUptime(
)
{
g_uptimeReference = GetCurrentTime();
return g_uptimeReference;
} // SnmpSvcInitUptime
// SnmpSvcGetUptime
// Determine uptime via global shared variable.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
DWORD
SNMP_FUNC_TYPE SnmpSvcGetUptime(
)
{
return ((GetCurrentTime() - g_uptimeReference) / 10);
} // SnmpSvcGetUptime
// SnmpSvcBufRevAndCpy
// Copy the contents of the specified buffer into the new buffer, and
// reverse the contents.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpSvcBufRevAndCpy(
OUT BYTE *szDest, // Destination buffer
IN BYTE *szSource, // Source buffer
IN UINT nLen // Length of buffers
)
{
UINT I;
I = 0;
while ( I < nLen )
{
szDest[I] = szSource[nLen - I - 1];
I++;
}
} // SnmpSvcBufRevAndCpy
// SnmpSvcBufRevInPlace
// Reverse the contents of the specified buffer.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpSvcBufRevInPlace(
IN OUT BYTE *szStr, // Buffer to reverse
IN UINT nLen // Length of buffer
)
{
UINT I;
BYTE nTemp;
for ( I=0;I < nLen/2;I++ )
{
nTemp = szStr[I];
szStr[I] = szStr[nLen - I - 1];
szStr[nLen - I - 1] = nTemp;
}
} // SnmpSvcBufRevInPlace
#endif // _SNMPDLL_
// SnmpUtilOidCpy
// Copy an object identifier.
// Notes:
// This routine is responsible for allocating enough memory to contain
// the new identifier.
// Return Codes:
// SNMPAPI_NOERROR
// SNMPAPI_ERROR
// Error Codes:
// SNMP_MEM_ALLOC_ERROR
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilOidCpy(
OUT AsnObjectIdentifier *DestObjId, // Destination OID
IN AsnObjectIdentifier *SrcObjId // Source OID
)
{
SNMPAPI nResult;
// Alloc space for new object id
if ( NULL ==
(DestObjId->ids = (UINT *) SnmpUtilMemAlloc((sizeof(UINT) * SrcObjId->idLength))) )
{
SetLastError( SNMP_MEM_ALLOC_ERROR );
nResult = SNMPAPI_ERROR;
goto Exit;
}
// Set length
DestObjId->idLength = SrcObjId->idLength;
// Copy the object id elements
memcpy( DestObjId->ids, SrcObjId->ids, DestObjId->idLength * sizeof(UINT) );
nResult = SNMPAPI_NOERROR;
Exit:
return nResult;
} // SnmpUtilOidCpy
// SnmpUtilOidAppend
// Append source OID to destination OID
// Notes:
// If memory cannot be allocated to accommodate the extended OID, then
// the original OID is lost.
// Return Codes:
// SNMPAPI_NOERROR
// SNMPAPI_ERROR
// Error Codes:
// SNMP_MEM_ALLOC_ERROR
// SNMP_BERAPI_OVERFLOW
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilOidAppend(
OUT AsnObjectIdentifier *DestObjId, // Destination OID
IN AsnObjectIdentifier *SrcObjId // Source OID
)
{
SNMPAPI nResult;
// Check for OID overflow
if ( (ULONG)DestObjId->idLength +
(ULONG)SrcObjId->idLength > SNMP_MAX_OID_LEN )
{
SetLastError( SNMP_BERAPI_OVERFLOW );
nResult = SNMPAPI_ERROR;
goto Exit;
}
// Alloc space for new object id
if ( NULL ==
(DestObjId->ids = (UINT *) SnmpUtilMemReAlloc(DestObjId->ids, (sizeof(UINT) *
(SrcObjId->idLength+DestObjId->idLength)))) )
{
SetLastError( SNMP_MEM_ALLOC_ERROR );
nResult = SNMPAPI_ERROR;
goto Exit;
}
// Append the source to destination
memcpy( &DestObjId->ids[DestObjId->idLength],
SrcObjId->ids, SrcObjId->idLength * sizeof(UINT) );
// Calculate length
DestObjId->idLength += SrcObjId->idLength;
nResult = SNMPAPI_NOERROR;
Exit:
return nResult;
} // SnmpUtilOidAppend
// SnmpUtilOidNCmp
// Compares two object identifiers.
// Notes:
// The object ids are compared from left to right (starting at the root.)
// At most the maximum length of OID sub-ids are compared.
// Return Codes:
// < 0 First parameter is 'less' than second.
// 0 Parameters are equal
// > 0 First parameter is 'greater' than second.
// Error Codes:
// None.
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilOidNCmp(
IN AsnObjectIdentifier *A, // First OID
IN AsnObjectIdentifier *B, // Second OID
IN UINT Len // Max len to compare
)
{
UINT I;
int nResult;
I = 0;
nResult = 0;
while ( !nResult && I < min(Len, min(A->idLength, B->idLength)) )
{
nResult = A->ids[I] - B->ids[I++];
}
// Check for one being a subset of the other
if ( !nResult && I < Len )
{
nResult = A->idLength - B->idLength;
}
return nResult;
} // SnmpUtilOidNCmp
// SnmpUtilOidCmp
// Compares two object identifiers.
// Notes:
// The object ids are compared from left to right (starting at the root.)
// Return Codes:
// < 0 First parameter is 'less' than second.
// 0 Parameters are equal
// > 0 First parameter is 'greater' than second.
// Error Codes:
// None.
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilOidCmp(
IN AsnObjectIdentifier *A, // First OID
IN AsnObjectIdentifier *B // Second OID
)
{
return SnmpUtilOidNCmp(A,B,max(A->idLength,B->idLength));
} // SnmpUtilOidCmp
// SnmpUtilOidFree
// Free an Object Identifier
// Notes:
// Return Codes:
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpUtilOidFree(
IN OUT AsnObjectIdentifier *Obj // OID to free
)
{
SnmpUtilMemFree( Obj->ids );
Obj->ids = NULL;
Obj->idLength = 0;
} // SnmpUtilOidFree
// SnmpUtilVarBindCpy
// Copies the variable binding.
// Notes:
// Does not allocate any memory for OID's or STRINGS. Only the pointer
// to the storage is copied.
// Return Codes:
// None.
// Error Codes:
// None.
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilVarBindCpy(
RFC1157VarBind *dst, // Destination var bind
RFC1157VarBind *src // Source var bind
)
{
SNMPAPI nResult;
// Init destination
dst->value.asnType = ASN_NULL;
// Copy var bind OID name
if ( SNMPAPI_ERROR == (nResult = SnmpUtilOidCpy(&dst->name, &src->name)) )
{
goto Exit;
}
// If the value is a var bind or a string, special handling
switch ( src->value.asnType )
{
case ASN_OBJECTIDENTIFIER:
if ( SNMPAPI_ERROR ==
(nResult = SnmpUtilOidCpy(&dst->value.asnValue.object,
&src->value.asnValue.object)) )
{
goto Exit;
}
break;
case ASN_RFC1155_IPADDRESS:
case ASN_RFC1155_OPAQUE:
case ASN_OCTETSTRING:
// Alloc storage for string
if ( NULL ==
(dst->value.asnValue.string.stream =
SnmpUtilMemAlloc((src->value.asnValue.string.length * sizeof(BYTE)))) )
{
SetLastError( SNMP_MEM_ALLOC_ERROR );
nResult = SNMPAPI_ERROR;
goto Exit;
}
// Copy string
dst->value.asnValue.string.length = src->value.asnValue.string.length;
memcpy( dst->value.asnValue.string.stream,
src->value.asnValue.string.stream,
dst->value.asnValue.string.length );
dst->value.asnValue.string.dynamic = TRUE;
break;
default:
// Copy var bind value.
// This is a non-standard copy
dst->value = src->value;
}
// Set type of asn value
dst->value.asnType = src->value.asnType;
nResult = SNMPAPI_NOERROR;
Exit:
if ( SNMPAPI_ERROR == nResult )
{
SnmpUtilVarBindFree( dst );
}
return nResult;
} // SnmpUtilVarBindCpy
// SnmpUtilVarBindListCpy
// Copies the var bind list referenced by the source into the destination.
// Notes:
// Creates memory as needed for the list.
// If an error occurs, memory is freed and the destination points to NULL.
// Return Codes:
// SNMPAPI_NOERROR
// SNMPAPI_ERROR
// Error Codes:
// SNMP_MEM_ALLOC_ERROR
SNMPAPI
SNMP_FUNC_TYPE SnmpUtilVarBindListCpy(
RFC1157VarBindList *dst, // Destination var bind
RFC1157VarBindList *src // Source var bind
)
{
UINT I;
SNMPAPI nResult;
// Initialize
dst->len = 0;
// Alloc memory for new var bind list
if ( NULL == (dst->list = SnmpUtilMemAlloc((src->len * sizeof(RFC1157VarBind)))) )
{
SetLastError( SNMP_MEM_ALLOC_ERROR );
nResult = SNMPAPI_ERROR;
goto Exit;
}
// Copy contents of each element in list
for ( I=0;I < src->len;I++ )
{
if ( SNMPAPI_ERROR ==
(nResult = SnmpUtilVarBindCpy(&dst->list[I], &src->list[I])) )
{
goto Exit;
}
// Increment successful copy count
dst->len++;
}
nResult = SNMPAPI_NOERROR;
Exit:
if ( nResult == SNMPAPI_ERROR )
{
SnmpUtilVarBindListFree( dst );
}
return nResult;
} // SnmpUtilVarBindListCpy
// SnmpUtilVarBindFree
// Releases memory associated with a particular variable binding.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpUtilVarBindFree(
RFC1157VarBind *VarBind // Variable binding to free
)
{
// Free Var Bind name
SnmpUtilOidFree( &VarBind->name );
// Free any data in the varbind value
switch ( VarBind->value.asnType )
{
case ASN_OBJECTIDENTIFIER:
SnmpUtilOidFree( &VarBind->value.asnValue.object );
break;
case ASN_RFC1155_IPADDRESS:
case ASN_RFC1155_OPAQUE:
case ASN_OCTETSTRING:
if ( VarBind->value.asnValue.string.dynamic == TRUE )
{
SnmpUtilMemFree( VarBind->value.asnValue.string.stream );
}
break;
default:
break;
// Purposefully do nothing, because no storage alloc'ed for others
}
// Set type to NULL
VarBind->value.asnType = ASN_NULL;
} // SnmpUtilVarBindFree
// SnmpUtilVarBindListFree
// Frees any memory kept by the var binds list, including object ids that
// may be in the value part of the var bind.
// Notes:
// The calling routines do not need to call this routine if the var binds
// list has not been set before. This is common sense, but just a reminder
// since it will be called by Release PDU and Release Trap.
// Even if the list has length 0, the list pointer should be set to NULL,
// if calling this routine.
// Return Codes:
// None.
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpUtilVarBindListFree(
RFC1157VarBindList *VarBindList // Variable bindings list to free
)
{
UINT I;
// Free items in varBinds list
for ( I=0;I < VarBindList->len;I++ )
{
SnmpUtilVarBindFree( &VarBindList->list[I] );
}
SnmpUtilMemFree( VarBindList->list );
VarBindList->list = NULL;
VarBindList->len = 0;
} // SnmpUtilVarBindListFree
#ifdef _SNMPDLL_
// Internal functions only after this point.
// The prototypes are in UTIL.H
// SnmpUtilPrintOid
// Display the SUBID's of an object identifier.
// Notes:
// This routine is responsible for allocating enough memory to contain
// the new identifier.
// Return Codes:
// SNMPAPI_NOERROR
// SNMPAPI_ERROR
// Error Codes:
// SNMP_MEM_ALLOC_ERROR
VOID
SNMP_FUNC_TYPE SnmpUtilPrintOid(
IN AsnObjectIdentifier *Oid // OID to display
)
{
UINT I;
// Loop through OID
for ( I=0;I < Oid->idLength;I++ )
{
if ( I )
{
printf( ".%d", Oid->ids[I] );
}
else
{
printf( "%d", Oid->ids[I] );
}
}
} // SnmpUtilPrintOid
// SnmpUtilPrintAsnAny
// Prints the value of a variable declared as type AsnAny.
// Notes:
// Return Codes:
// None.
// Error Codes:
// None.
VOID
SNMP_FUNC_TYPE SnmpUtilPrintAsnAny(
IN AsnAny *Any
)
{
switch ( Any->asnType )
{
case ASN_INTEGER:
printf( "INTEGER - %ld\n", Any->asnValue.number );
break;
case ASN_OCTETSTRING:
{
UINT J;
BOOL IsDisplayString = TRUE;
LPSTR StringFormat;
for ( J=0; J < Any->asnValue.string.length && IsDisplayString; J++ )
{
IsDisplayString = isprint( Any->asnValue.string.stream[J] );
}
StringFormat = IsDisplayString ? "%c" : "<0x%02x>" ;
printf( "OCTET STRING - " );
for ( J=0; J < Any->asnValue.string.length; J++ )
{
printf( StringFormat, Any->asnValue.string.stream[J] );
}
putchar( '\n' );
}
break;
case ASN_OBJECTIDENTIFIER:
{
UINT J;
printf( "OBJECT IDENTIFIER - " );
for ( J=0; J < Any->asnValue.object.idLength; J++ )
{
printf( ".%d", Any->asnValue.object.ids[J] );
}
putchar( '\n' );
}
break;
case ASN_NULL:
printf( "NULL - NULL\n" );
break;
case ASN_RFC1155_IPADDRESS:
{
UINT J;
printf( "IpAddress - " );
printf( "%d.%d.%d.%d ",
Any->asnValue.string.stream[0] ,
Any->asnValue.string.stream[1] ,
Any->asnValue.string.stream[2] ,
Any->asnValue.string.stream[3] );
putchar( '\n' );
}
break;
case ASN_RFC1155_COUNTER:
printf( "Counter - %lu\n", Any->asnValue.number );
break;
case ASN_RFC1155_GAUGE:
printf( "Guage - %lu\n", Any->asnValue.number );
break;
case ASN_RFC1155_TIMETICKS:
printf( "TimeTicks - %lu\n", Any->asnValue.number );
break;
case ASN_RFC1155_OPAQUE:
{
UINT J;
printf( "Opaque - " );
for ( J=0; J < Any->asnValue.string.length; J++ )
{
printf( "0x%x ", Any->asnValue.string.stream[J] );
}
putchar( '\n' );
}
break;
default:
printf( "Invalid Type\n" );
}
} // SnmpUtilPrintAsnAny
// logging and debugging output routines
VOID
SNMP_FUNC_TYPE
SnmpSvcSetLogLevel(
IN INT nLevel
)
{
g_nLogLevel = nLevel;
}
VOID
SNMP_FUNC_TYPE
SnmpSvcSetLogType(
IN INT nOutput
)
{
g_nLogType = nOutput;
}
VOID
SNMP_FUNC_TYPE
SnmpUtilOutput(INT nOutputType, LPSTR szBuffer)
{
static FILE *fd = NULL;
if (nOutputType & SNMP_OUTPUT_TO_CONSOLE)
{
printf("%s", szBuffer);
fflush(stdout);
}
if (nOutputType & SNMP_OUTPUT_TO_LOGFILE)
{
if (!fd)
{
fd = fopen("snmpdbg.log", "w");
}
if (fd)
{
fprintf(fd, "%s", szBuffer);
fflush(fd);
}
}
if (nOutputType & SNMP_OUTPUT_TO_EVENTLOG)
{
SnmpSvcReportEvent(SNMP_EVENT_DEBUG_TRACE, 1, &szBuffer, NO_ERROR);
}
if (nOutputType & SNMP_OUTPUT_TO_DEBUGGER)
{
OutputDebugString(szBuffer);
}
}
VOID
SNMP_FUNC_TYPE
SnmpUtilDbgPrint(INT nLevel, LPSTR szFormat, ...)
{
va_list arglist;
char szBuffer[MAX_DEBUG_LEN];
if (nLevel <= g_nLogLevel)
{
va_start(arglist, szFormat);
vsprintf(szBuffer, szFormat, arglist);
SnmpUtilOutput(g_nLogType, szBuffer);
}
}
LPSTR
SNMP_FUNC_TYPE
SnmpUtilOidToA(AsnObjectIdentifier *Oid)
{
return SnmpUtilIdsToA(Oid->ids, Oid->idLength);
}
LPSTR
SNMP_FUNC_TYPE
SnmpUtilIdsToA(UINT *Oid, UINT OidLen)
{
UINT I;
UINT J;
static char szBuffer[MAX_DEBUG_LEN];
if (OidLen)
{
J = sprintf(szBuffer, "%d", Oid[0]);
for ( I=1;I < OidLen;I++ )
{
J += sprintf(&szBuffer[J], ".%d", Oid[I]);
}
}
else
{
sprintf(szBuffer, "NUL");
}
return szBuffer;
}
VOID
SNMP_FUNC_TYPE
SnmpSvcReportEvent(DWORD nMsgId, DWORD cSubStrings, LPSTR *SubStrings, DWORD nErrorCode)
{
HANDLE lh;
WORD wEventType;
LPVOID lpData;
WORD cbData;
// determine type of event from message id. note that
// all debug messages regardless of their severity are
// listed under SNMP_EVENT_DEBUG_TRACE (informational).
// see evtlog.h for the entire list of event messages.
switch ( nMsgId >> 30 )
{
case STATUS_SEVERITY_INFORMATIONAL:
case STATUS_SEVERITY_SUCCESS:
wEventType = EVENTLOG_INFORMATION_TYPE;
break;
case STATUS_SEVERITY_WARNING:
wEventType = EVENTLOG_WARNING_TYPE;
break;
case STATUS_SEVERITY_ERROR:
default:
wEventType = EVENTLOG_ERROR_TYPE;
break;
}
cbData = (nErrorCode == NO_ERROR) ? 0 : sizeof(DWORD);
lpData = (nErrorCode == NO_ERROR) ? NULL : &nErrorCode;
if (lh = RegisterEventSource(NULL, "SNMP"))
{
ReportEvent(
lh,
wEventType,
0, // event category
nMsgId,
NULL, // user sids
(WORD)cSubStrings,
cbData,
SubStrings,
lpData);
DeregisterEventSource(lh);
}
}
#endif // _SNMPDLL_
VOID
SNMP_FUNC_TYPE SnmpUtilMemFree(
IN void *x
)
{
if (x != NULL) {
#if defined(DBG) && defined(_SNMPDLL_)
g_nBytesTotal -= GlobalSize(x);
SNMPDBG((
SNMP_LOG_VERBOSE,
"SNMP: MEM: releasing 0x%08lx (%d bytes, %d total).\n",
x, GlobalSize(x), g_nBytesTotal
));
#endif
GlobalFree( (HGLOBAL) x );
}
return;
}
LPVOID
SNMP_FUNC_TYPE SnmpUtilMemAlloc(
IN unsigned int x
)
{
void *addr;
addr = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, (DWORD)x );
#if defined(DBG) && defined(_SNMPDLL_)
g_nBytesTotal += (addr ? GlobalSize(addr) : 0);
SNMPDBG((
SNMP_LOG_VERBOSE,
"SNMP: MEM: allocated 0x%08lx (%d bytes, %d total).\n",
addr, addr ? GlobalSize(addr) : 0, g_nBytesTotal
));
#endif
return(addr);
}
LPVOID
SNMP_FUNC_TYPE SnmpUtilMemReAlloc(
IN void *x,
IN unsigned int y
)
{
void *addr;
if (x == NULL) {
addr = SnmpUtilMemAlloc( y );
} else {
#if defined(DBG) && defined(_SNMPDLL_)
SNMPDBG((
SNMP_LOG_VERBOSE,
"SNMP: MEM: expanding 0x%08lx (%d bytes) to %d bytes.\n",
x, GlobalSize(x), y
));
g_nBytesTotal -= GlobalSize(x);
#endif
addr = GlobalReAlloc( (HGLOBAL) x, (DWORD)y, GMEM_MOVEABLE | GMEM_ZEROINIT);
#if defined(DBG) && defined(_SNMPDLL_)
g_nBytesTotal += (addr ? GlobalSize(addr) : 0);
SNMPDBG((
SNMP_LOG_VERBOSE,
"SNMP: MEM: allocated 0x%08lx (%d bytes, %d total).\n",
addr, addr ? GlobalSize(addr) : 0, g_nBytesTotal
));
#endif
}
return(addr);
}
#ifdef _SNMPDLL_
// return true if the string contains only hex digits
BOOL isHex(LPSTR str, int strLen)
{
int ii;
for (ii=0; ii < strLen; ii++)
if (isxdigit(*str))
str++;
else
return FALSE;
return TRUE;
}
unsigned int toHex(unsigned char x)
{
if (x >= '0' && x <= '9')
return x - '0';
else if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
else if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
else
return 0;
}
// convert str to hex number of NumDigits (must be even) into pNum
void atohex(IN LPSTR str, IN int NumDigits, OUT unsigned char *pNum)
{
int i, j;
j=0;
for (i=0; i < (NumDigits>>1) ; i++)
{
pNum[i] = (toHex(str[j]) << 4) + toHex(str[j+1]);
j+=2;
}
}
// return true if addrText is of the form 123456789ABC or
// 000001.123456789abc
// if pNetNum is not null, upon successful return, pNetNum = network number
// if pNodeNum is not null, upon successful return, pNodeNum = node number
BOOL
SNMP_FUNC_TYPE
SnmpSvcAddrIsIpx(
IN LPSTR addrText,
OUT char pNetNum[4],
OUT char pNodeNum[6])
{
int addrTextLen;
addrTextLen = strlen(addrText);
if (addrTextLen == 12 && isHex(addrText, 12))
{
if (pNetNum)
*((UNALIGNED unsigned long *) pNetNum) = 0L;
if (pNodeNum)
atohex(addrText, 12, pNodeNum);
return TRUE;
}
else if (addrTextLen == 21 && addrText[8] == '.' && isHex(addrText, 8) &&
isHex(addrText+9, 12))
{
if (pNetNum)
atohex(addrText, 8, pNetNum);
if (pNodeNum)
atohex(addrText+9, 12, pNodeNum);
return TRUE;
}
else
return FALSE;
}
BOOL
SNMP_FUNC_TYPE
SnmpSvcAddrToSocket(
LPSTR addrText,
struct sockaddr *addrEncoding)
{
// --------- BEGIN: PROTOCOL SPECIFIC SOCKET CODE BEGIN... ---------
SOCKADDR_IPX mgrAddr_ipx;
if (SnmpSvcAddrIsIpx(addrText, mgrAddr_ipx.sa_netnum, mgrAddr_ipx.sa_nodenum))
{
// currently, we don't/can't do gethostbyname on IPX, so no IPX
// host name allowed.
mgrAddr_ipx.sa_family = AF_IPX;
bcopy(&mgrAddr_ipx, addrEncoding, sizeof(mgrAddr_ipx));
}
else // if not IPX, must be INET
{
struct hostent *hp;
unsigned long addr;
struct sockaddr_in mgrAddr_in;
if ((long)(addr = inet_addr(addrText)) == -1)
{
if ((hp = gethostbyname(addrText)) == NULL)
{
return FALSE;
}
else
{
bcopy((char *)hp->h_addr, (char *)&mgrAddr_in.sin_addr,
sizeof(unsigned long));
}
}
else
{
bcopy((char *)&addr, (char *)&mgrAddr_in.sin_addr,
sizeof(unsigned long));
}
mgrAddr_in.sin_family = AF_INET;
mgrAddr_in.sin_port = htons(WKSN_UDP_TRAP);
bcopy(&mgrAddr_in, addrEncoding, sizeof(mgrAddr_in));
}
// --------- END: PROTOCOL SPECIFIC SOCKET CODE END. ---------------
return TRUE;
} // end SnmpSvcAddrToSocket()
AsnObjectIdentifier *
SNMP_FUNC_TYPE
SnmpSvcGetEnterpriseOID(
)
{
// just return oid
return g_enterprise;
}
#endif // _SNMPDLL_
//-------------------------------- END --------------------------------------