home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
lnsnmp.zip
/
LNVDATA.CPP
next >
Wrap
C/C++ Source or Header
|
1994-02-26
|
14KB
|
438 lines
/*************************************************************************/
/* Program Name: LNVDATA.CPP Title: Support Module for SNMP LAN NetView */
/* OS/2 Developer Magazine, Issue: March-April '94 */
/* Article Title: Network Management: Using SNMP for LAN NetView */
/* Author: Stacey Taylor CompuServe ID: 73670,3235 */
/* Phone: (818) 878-7300 Fax: (818) 878-7313 */
/* Description: */
/* This simple program demonstrates the programming techniques required */
/* when retrieving data from an SNMP agent via the LAN NetView platform. */
/* Output from this program (i.e. tracing/debugging data), is written to */
/* a file called, SNMPDATA. */
/* */
/* Program Requirements: */
/* C/Set++ */
/* LAN NetView, Manage Module with Development Toolkit */
/*************************************************************************/
//---------------------------------------------------------
// System Include Files
//---------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <xom.h> // from LAN NetView include directory
#include <xmp.h> // from LAN NetView include directory
#include <xmp_snmp.h> // from LAN NetView include directory
// define a array to describe all the syntaxes.
// This could be used for CMIP operations also.
typedef struct
{
int SyntaxID;
char *SyntaxDesc;
} SNMP_SYNTAX;
static SNMP_SYNTAX SNMPSyntax[] =
{
{ OM_S_BIT_STRING, "OM_S_BIT_STRING" },
{ OM_S_BOOLEAN, "OM_S_BOOLEAN" },
{ OM_S_ENCODING_STRING, "OM_S_ENCODING_STRING" },
{ OM_S_ENUMERATION, "OM_S_ENUMERATION" },
{ OM_S_GENERAL_STRING, "OM_S_GENERAL_STRING" },
{ OM_S_GENERALISED_TIME_STRING, "OM_S_GENERALIZED_TIME_STRING" },
{ OM_S_GRAPHIC_STRING, "OM_S_GRAPHIC_STRING" },
{ OM_S_IA5_STRING, "OM_S_IA5_STRING" },
{ OM_S_INTEGER, "OM_S_INTEGER" },
{ OM_S_NO_MORE_SYNTAXES, "OM_S_NO_MORE_SYNTAXES" },
{ OM_S_NULL, "OM_S_NULL" },
{ OM_S_NUMERIC_STRING, "OM_S_NUMERIC_STRING" },
{ OM_S_OBJECT, "OM_S_OBJECT" },
{ OM_S_OBJECT_DESCRIPTOR_STRING, "OM_S_OBJECT_DESCRIPTOR_STRING" },
{ OM_S_OBJECT_IDENTIFIER_STRING, "OM_S_OBJECT_IDENTIFIER_STRING" },
{ OM_S_OCTET_STRING, "OM_S_OCTET_STRING" },
{ OM_S_PRINTABLE_STRING, "OM_S_PRINTABLE_STRING" },
{ OM_S_TELETEX_STRING, "OM_S_TELETEX_STRING" },
{ OM_S_UTC_TIME_STRING, "OM_S_UTC_TIME_STRING" },
{ OM_S_VIDEOTEX_STRING, "OM_S_VIDEOTEX_STRING" },
{ OM_S_VISIBLE_STRING, "OM_S_VISIBLE_STRING" }
};
// File handle to SNMPDATA.OUT file
static FILE *hOutput;
// Prototype internal functions
static void RecurseSNMPStruct ( OM_workspace, OM_public_object, int );
static void ExtractValue ( OM_workspace, OM_public_object, char * );
//------------------------------------------------------------------------
// Function: DecomposeSNMPStruct
//
// This routine will output the SNMP structure
// (in a more readable form) to a file called,
// SNMPDATA.OUT.
//------------------------------------------------------------------------
void DecomposeSNMPStruct ( OM_workspace Workspace,
OM_public_object SNMPStruct )
{
// open the file in attach mode.
hOutput = fopen ( "SNMPDATA", "a" );
if (hOutput == NULL)
{
return;
}
RecurseSNMPStruct ( Workspace, SNMPStruct, 0 );
fprintf ( hOutput, "________________________________________________\n" );
fclose ( hOutput );
return;
}
//-------------------------------------------------------------------------
// Function: RecurseSNMPStruct
//
// Recursive routine to examine the SNMP Structure
//-------------------------------------------------------------------------
static void RecurseSNMPStruct ( OM_workspace Workspace,
OM_public_object SNMPStruct,
int Indent )
{
OM_public_object CurrentClass;
OM_return_code OMRet;
char * TypeDesc;
int i;
char ValueDesc[128];
CurrentClass = SNMPStruct;
while ( SNMPStruct->type != OM_NO_MORE_TYPES )
{
// indent the output
fprintf ( hOutput, "%*.*s", Indent, Indent, "" );
// output the type description
OMRet = at_type_to_label ( Workspace, &CurrentClass->value.string,
SNMPStruct->type, &TypeDesc );
if ( OMRet == OM_SUCCESS )
{
fprintf ( hOutput, "%s ", TypeDesc);
at_free ( TypeDesc );
}
else
{
fprintf ( hOutput, "Error in determining type! ");
}
// output the syntax description. Loop through the array
// of possible syntaxes, looking for a match.
for ( i = 0; i < sizeof (SNMPSyntax) / sizeof (SNMPSyntax[0]); i++ )
{
if ( (SNMPStruct->syntax & OM_S_SYNTAX) == SNMPSyntax[i].SyntaxID )
{
fprintf ( hOutput, "%s ", SNMPSyntax[i].SyntaxDesc );
break;
}
}
// output the value
ExtractValue ( Workspace, SNMPStruct, ValueDesc );
fprintf ( hOutput, "%s", ValueDesc );
fprintf ( hOutput, "\n");
// If this is a pointer to an object, then recurse
// using the object's pointer.
if ( (SNMPStruct->syntax & OM_S_OBJECT) == OM_S_OBJECT )
{
RecurseSNMPStruct ( Workspace, SNMPStruct->value.object.object,
Indent + 4 );
}
// increment to the next object in the SNMP structure
SNMPStruct++;
} // while loop
}
//-----------------------------------------------------------------------
// Function: ExtractValue
//
// This routine finds and formats the SNMP value
//-----------------------------------------------------------------------
static void ExtractValue ( OM_workspace Workspace,
OM_public_object SNMPStruct,
char *ValueDesc )
{
OM_return_code OMRet;
char *OIDDesc;
char *PackageName;
OM_uint32 TypeDesc;
int i; // loop variable
switch ( SNMPStruct->syntax & OM_S_SYNTAX )
{
case OM_S_BOOLEAN:
if ( SNMPStruct->value.boolean == 0)
{
strcpy ( ValueDesc, "True");
}
else
{
strcpy ( ValueDesc, "False");
}
break;
case OM_S_INTEGER:
case OM_S_ENUMERATION:
sprintf ( ValueDesc, "%d", SNMPStruct->value.integer );
break;
case OM_S_NULL:
strcpy ( ValueDesc, "Null" );
break;
case OM_S_OBJECT:
sprintf ( ValueDesc, "%X", SNMPStruct->value.object.object );
break;
case OM_S_BIT_STRING:
case OM_S_OBJECT_DESCRIPTOR_STRING:
case OM_S_ENCODING_STRING:
for ( i = 0; i < SNMPStruct->value.string.length; i++ )
{
sprintf ( &ValueDesc[i*2], "2.2%X",
((char *)(SNMPStruct->value.string.elements))[i] );
}
break;
case OM_S_GENERAL_STRING:
case OM_S_GENERALISED_TIME_STRING:
case OM_S_GRAPHIC_STRING:
case OM_S_IA5_STRING:
case OM_S_NUMERIC_STRING:
case OM_S_PRINTABLE_STRING:
case OM_S_TELETEX_STRING:
case OM_S_UTC_TIME_STRING:
case OM_S_VIDEOTEX_STRING:
case OM_S_VISIBLE_STRING:
memcpy ( ValueDesc, (char *)SNMPStruct->value.string.elements,
SNMPStruct->value.string.length );
ValueDesc[SNMPStruct->value.string.length] = '\0';
break;
case OM_S_OBJECT_IDENTIFIER_STRING:
OMRet = at_oid_to_label ( Workspace, &SNMPStruct->value.string,
&PackageName, &OIDDesc, &TypeDesc );
if ( OMRet == OM_SUCCESS )
{
sprintf ( ValueDesc, "%s", OIDDesc );
at_free ( PackageName );
at_free ( OIDDesc );
}
else
{
OMRet = at_oid_to_str ( SNMPStruct->value.string, &OIDDesc );
if ( OMRet == OM_SUCCESS )
{
strcpy ( ValueDesc, OIDDesc );
at_free ( OIDDesc );
}
else
{
strcpy ( ValueDesc, "Unknown OID" );
}
}
break;
case OM_S_OCTET_STRING:
{
int i;
// Special formatting for IP Addresses
if (SNMPStruct->type == MP_IP_ADDRESS)
{
sprintf (ValueDesc,"%i.%i.%i.%i",
(int)((char *)SNMPStruct->value.string.elements)[0],
(int)((char *)SNMPStruct->value.string.elements)[1],
(int)((char *)SNMPStruct->value.string.elements)[2],
(int)((char *)SNMPStruct->value.string.elements)[3] );
}
else
{
int Ascii = 1; // assume readable ascii
// determine if the data is readable ascii.
for (i = 0; i < SNMPStruct->value.string.length; i++)
{
if (!isprint(((char *)SNMPStruct->value.string.elements)[i]))
{
Ascii = 0; // not readable ascii
break;
}
}
if ( !Ascii )
{
for (i = 0; i < SNMPStruct->value.string.length; i++)
{
sprintf (&ValueDesc[i*2],"%02X",
((char *)SNMPStruct->value.string.elements)[i]);
}
}
else
{
memcpy(ValueDesc, (char *)SNMPStruct->value.string.elements,
SNMPStruct->value.string.length );
ValueDesc[SNMPStruct->value.string.length] = '\0';
}
}
}
break;
default:
strcpy ( ValueDesc, "Unknown Syntax" );
break;
} // switch
return;
}
//------------------------------------------------------------------------
// Function: GetSNMPData
//
// This routine will search the SNMP structure looking for a
// match with the desired ID. When found, the ID's data is
// returned in Data parameter.
//------------------------------------------------------------------------
int GetSNMPData ( OM_workspace Workspace,
OM_public_object SNMPStruct,
char *ID, char *Data )
{
int Found = 0;
OM_object_identifier OID;
Data[0] = '\0';
while ( SNMPStruct->type != OM_NO_MORE_TYPES && Found == 0 )
{
switch ( SNMPStruct->type )
{
// This can be though of as a 'Header' for SNMP data that
// will follow (recursive).
case MP_VAR_BIND_LIST:
Found = GetSNMPData ( Workspace, SNMPStruct->value.object.object,
ID, Data );
if ( Found == 1 )
{
return Found;
}
break;
// If MP_NAME, then this contains the ID of the value returned.
// If the IDs match, then the next element must be the value,
// which therefore must have the type MP_VALUE. If this is
// true, then recurse to get the value. We will then be looking
// for MP_SIMPLE elements.
case MP_NAME:
at_str_to_oid ( ID, &OID );
if ( at_oid_match ( &OID, &SNMPStruct->value.string ) == OM_TRUE )
{
SNMPStruct++;
if ( SNMPStruct->type == MP_VALUE )
{
Found = GetSNMPData ( Workspace,
SNMPStruct->value.object.object,
ID, Data );
if ( Found == 1 )
{
at_free ( OID.elements );
return Found;
}
}
}
at_free ( OID.elements );
break;
// 'Header' that means data following is of simple or
// application type
case MP_APPLICATION_WIDE:
case MP_SIMPLE:
Found = GetSNMPData ( Workspace, SNMPStruct->value.object.object,
ID, Data );
if ( Found == 1 )
{
return Found;
}
break;
// This is the data !!
case MP_STRING:
case MP_COUNTER:
Found = 1;
break;
} // type switch
if ( Found == 0)
{
SNMPStruct++;
}
} // while loop
if ( Found == 1 )
{
ExtractValue ( Workspace, SNMPStruct, Data );
}
return Found;
}