Beispiel #1
0
static void setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
    UINT item)
{
    UINT id;
    AsnObjectIdentifier oid;

    SnmpUtilOidCpy(dst, base);
    oid.idLength = 1;
    oid.ids = &id;
    id = item;
    SnmpUtilOidAppend(dst, &oid);
}
Beispiel #2
0
static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
    AsnInteger32 *pErrorStatus)
{
    AsnObjectIdentifier numberOid = DEFINE_OID(mib2IfNumber);
    BOOL ret = TRUE;

    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
        pErrorStatus);

    switch (bPduType)
    {
    case SNMP_PDU_GET:
    case SNMP_PDU_GETNEXT:
        if ((bPduType == SNMP_PDU_GET &&
            !SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength))
            || SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength)
            < 0)
        {
            DWORD numIfs = ifTable ? ifTable->dwNumEntries : 0;

            copyInt(&pVarBind->value, &numIfs);
            if (bPduType == SNMP_PDU_GETNEXT)
            {
                SnmpUtilOidFree(&pVarBind->name);
                SnmpUtilOidCpy(&pVarBind->name, &numberOid);
            }
            *pErrorStatus = SNMP_ERRORSTATUS_NOERROR;
        }
        else
        {
            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
            /* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't
             * need to set it here.
             */
        }
        break;
    case SNMP_PDU_SET:
        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
        ret = FALSE;
        break;
    default:
        FIXME("0x%02x: unsupported PDU type\n", bPduType);
        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
    }
    return ret;
}
Beispiel #3
0
static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
    UINT item)
{
    UINT id;
    AsnObjectIdentifier oid;
    INT ret;

    SnmpUtilOidFree(dst);
    ret = SnmpUtilOidCpy(dst, base);
    if (ret)
    {
        oid.idLength = 1;
        oid.ids = &id;
        id = item;
        ret = SnmpUtilOidAppend(dst, &oid);
    }
    return ret;
}
Beispiel #4
0
/*****************************************************************************
 * SnmpExtensionInit [INETMIB1.@]
 */
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
    HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
{
    AsnObjectIdentifier myOid = DEFINE_OID(mib2System);
    UINT i;

    TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
        pFirstSupportedRegion);

    minSupportedIDLength = UINT_MAX;
    for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
    {
        if (supportedIDs[i].init)
            supportedIDs[i].init();
        if (supportedIDs[i].name.idLength < minSupportedIDLength)
            minSupportedIDLength = supportedIDs[i].name.idLength;
    }
    *phSubagentTrapEvent = NULL;
    SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
    return TRUE;
}
//通过SNMP(简单网络访问协议)
bool GetMacAddressBySNMP(std::string &mac_address)
{
	bool ret = false;
	WSADATA winsock_data;
	if (WSAStartup(MAKEWORD(2, 0), &winsock_data) != 0) 
		return false;

	// Load the SNMP dll and get the addresses of the functions necessary
	const HINSTANCE m_dll = LoadLibrary(L"inetmib1.dll");
	if (m_dll < (HINSTANCE) HINSTANCE_ERROR)
		return false;

	const PFNSNMPEXTENSIONINIT f_SnmpExtensionInit = (PFNSNMPEXTENSIONINIT) GetProcAddress(m_dll, "SnmpExtensionInit");
//	const PFNSNMPEXTENSIONINITEX f_SnmpExtensionInitEx = (PFNSNMPEXTENSIONINITEX) GetProcAddress(m_dll, "SnmpExtensionInitEx");
 	const PFNSNMPEXTENSIONQUERY f_SnmpExtensionQuery = (PFNSNMPEXTENSIONQUERY) GetProcAddress(m_dll, "SnmpExtensionQuery");
// 	const PFNSNMPEXTENSIONTRAP f_SnmpExtensionTrap = (PFNSNMPEXTENSIONTRAP) GetProcAddress(m_dll, "SnmpExtensionTrap");
	HANDLE poll_for_trap_event;
	AsnObjectIdentifier supported_view;
	f_SnmpExtensionInit(GetTickCount(), &poll_for_trap_event, &supported_view);

	// Initialize the variable list to be retrieved by f_SnmpExtensionQuery
	const AsnObjectIdentifier MIB_NULL = { 0, 0 };

	RFC1157VarBind var_bind[2];
	var_bind[0].name = MIB_NULL;
	var_bind[1].name = MIB_NULL;

	RFC1157VarBindList var_bind_list;
	var_bind_list.list = var_bind;

	UINT OID_ifEntryType[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 3 };
	UINT OID_ifEntryNum[] = { 1, 3, 6, 1, 2, 1, 2, 1 };
	UINT OID_ipMACEntAddr[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 6 };
	AsnObjectIdentifier MIB_ifMACEntAddr = { sizeof(OID_ipMACEntAddr) / sizeof(UINT), OID_ipMACEntAddr };
	AsnObjectIdentifier MIB_ifEntryType = { sizeof(OID_ifEntryType) / sizeof(UINT), OID_ifEntryType };
	AsnObjectIdentifier MIB_ifEntryNum = { sizeof(OID_ifEntryNum) / sizeof(UINT), OID_ifEntryNum };

	// Copy in the OID to find the number of entries in the Inteface table
	var_bind_list.len = 1;        // Only retrieving one item
	SnmpUtilOidCpy(&var_bind[0].name, &MIB_ifEntryNum);
	AsnInteger errorStatus;
	AsnInteger errorIndex;
	f_SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &var_bind_list, &errorStatus, &errorIndex);
	var_bind_list.len = 2;

	// Copy in the OID of ifType, the type of interface
	SnmpUtilOidCpy(&var_bind[0].name, &MIB_ifEntryType);

	// Copy in the OID of ifPhysAddress, the address
	SnmpUtilOidCpy(&var_bind[1].name, &MIB_ifMACEntAddr);

	for(int j = 0; j < var_bind[0].value.asnValue.number; j++)
	{
		// Submit the query.  Responses will be loaded into var_bind_list.
		// We can expect this call to succeed a # of times corresponding to the # of adapters reported to be in the system
		if(f_SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &var_bind_list, &errorStatus, &errorIndex) == FALSE)
			continue;
		// Confirm that the proper type has been returned
		if(SnmpUtilOidNCmp(&var_bind[0].name, &MIB_ifEntryType, MIB_ifEntryType.idLength) != 0)
			continue;
		// Type 6 describes ethernet interfaces
		if(var_bind[0].value.asnValue.number != 6) 
			continue;
		// Confirm that we have an address here
		if(SnmpUtilOidNCmp(&var_bind[1].name, &MIB_ifMACEntAddr, MIB_ifMACEntAddr.idLength) != 0)
			continue;
		if(var_bind[1].value.asnValue.address.stream == NULL)
			continue;
		// Ignore all dial-up networking adapters
		if ((var_bind[1].value.asnValue.address.stream[0] == 0x44)
			&& (var_bind[1].value.asnValue.address.stream[1] == 0x45)
			&& (var_bind[1].value.asnValue.address.stream[2] == 0x53)
			&& (var_bind[1].value.asnValue.address.stream[3] == 0x54)
			&& (var_bind[1].value.asnValue.address.stream[4] == 0x00)) 
			continue;
		// Ignore NULL addresses returned by other network interfaces
		if ((var_bind[1].value.asnValue.address.stream[0] == 0x00)
			&& (var_bind[1].value.asnValue.address.stream[1] == 0x00)
			&& (var_bind[1].value.asnValue.address.stream[2] == 0x00)
			&& (var_bind[1].value.asnValue.address.stream[3] == 0x00)
			&& (var_bind[1].value.asnValue.address.stream[4] == 0x00)
			&& (var_bind[1].value.asnValue.address.stream[5] == 0x00)) 
			continue;

		StringPrintf(mac_address, "%02x-%02x-%02x-%02x-%02x-%02x",
			var_bind[1].value.asnValue.address.stream[0],
			var_bind[1].value.asnValue.address.stream[1],
			var_bind[1].value.asnValue.address.stream[2],
			var_bind[1].value.asnValue.address.stream[3],
			var_bind[1].value.asnValue.address.stream[4],
			var_bind[1].value.asnValue.address.stream[5]);

		ret = true;
		break;
	}

	// Free the bindings
	SnmpUtilVarBindFree(&var_bind[0]);
	SnmpUtilVarBindFree(&var_bind[1]);
	return ret;
}
Beispiel #6
0
int _cdecl main(
    IN int  argumentCount,
    IN char *argumentVector[])
{
    HANDLE  hExtension;
    FARPROC initAddr;
    FARPROC queryAddr;
    FARPROC trapAddr;

    DWORD  timeZeroReference;
    HANDLE hPollForTrapEvent;
    View   supportedView;

    INT numQueries = 10;

    // avoid compiler warning...
    UNREFERENCED_PARAMETER(argumentCount);
    UNREFERENCED_PARAMETER(argumentVector);

    timeZeroReference = GetCurrentTime();

    // load the extension agent dll and resolve the entry points...
    if (GetModuleHandle("testdll.dll") == NULL)
    {
        if ((hExtension = LoadLibrary("testdll.dll")) == NULL)
        {
            dbgprintf(1, "error on LoadLibrary %d\n", GetLastError());

        }
        else if ((initAddr = GetProcAddress(hExtension,
                                            "SnmpExtensionInit")) == NULL)
        {
            dbgprintf(1, "error on GetProcAddress %d\n", GetLastError());
        }
        else if ((queryAddr = GetProcAddress(hExtension,
                                             "SnmpExtensionQuery")) == NULL)
        {
            dbgprintf(1, "error on GetProcAddress %d\n",
                      GetLastError());

        }
        else if ((trapAddr = GetProcAddress(hExtension,
                                            "SnmpExtensionTrap")) == NULL)
        {
            dbgprintf(1, "error on GetProcAddress %d\n",
                      GetLastError());

        }
        else
        {
            // initialize the extension agent via its init entry point...
            (*initAddr)(
                timeZeroReference,
                &hPollForTrapEvent,
                &supportedView);
        }
    } // end if (Already loaded)

    // create a trap thread to respond to traps from the extension agent...

    //rather than oomplicate this test routine, will poll for these events
    //below.  normally this would be done by another thread in the extendible
    //agent.


    // loop here doing repetitive extension agent get queries...
    // poll for potential traps each iteration (see note above)...

    //block...
    printf( "SET on toasterManufacturer - shouldn't work\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 1, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_OCTETSTRING;
        varBinds.list[0].value.asnValue.string.length = 0;
        varBinds.list[0].value.asnValue.string.stream = NULL;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterControl with invalid value\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 500;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterControl with invalid type\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_NULL;
        varBinds.list[0].value.asnValue.number = 500;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterControl\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 3, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 2;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterDoneness with invalid value\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 1000;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterDoneness with invalid type\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_NULL;
        varBinds.list[0].value.asnValue.number = 1000;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterDoneness\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 4, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 10;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterToastType with invalid value\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 10;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterToastType with invalid type\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_NULL;
        varBinds.list[0].value.asnValue.number = 10;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    printf( "SET on toasterToastType\n" );

    {
        UINT itemn[]                 = { 1, 3, 6, 1, 4, 1, 12, 2, 5, 0 };
        RFC1157VarBindList varBinds;
        AsnInteger errorStatus       = 0;
        AsnInteger errorIndex        = 0;

        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        varBinds.list[0].name.idLength = sizeof itemn / sizeof(UINT);
        varBinds.list[0].name.ids = (UINT *)SnmpUtilMemAlloc( sizeof(UINT)*
                                    varBinds.list[0].name.idLength );
        memcpy( varBinds.list[0].name.ids, &itemn,
                sizeof(UINT)*varBinds.list[0].name.idLength );
        varBinds.list[0].value.asnType = ASN_INTEGER;
        varBinds.list[0].value.asnValue.number = 7;

        printf( "SET:  " );
        SnmpUtilPrintOid( &varBinds.list[0].name );
        printf( " to " );
        SnmpUtilPrintAsnAny( &varBinds.list[0].value );
        (*queryAddr)( ASN_RFC1157_SETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        printf( "\nSET Errorstatus:  %lu\n\n", errorStatus );

        (*queryAddr)( ASN_RFC1157_GETREQUEST,
                      &varBinds,
                      &errorStatus,
                      &errorIndex
                    );
        if ( errorStatus == SNMP_ERRORSTATUS_NOERROR )
        {
            printf( "New Value:  " );
            SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            putchar( '\n' );
        }
        printf( "\nGET Errorstatus:  %lu\n\n", errorStatus );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );

        printf( "\n\n" );
    }

    {
        RFC1157VarBindList varBinds;
        AsnInteger         errorStatus;
        AsnInteger         errorIndex;
        UINT OID_Prefix[] = { 1, 3, 6, 1, 4, 1, 12 };
        AsnObjectIdentifier MIB_OidPrefix = { OID_SIZEOF(OID_Prefix), OID_Prefix };


        errorStatus = 0;
        errorIndex  = 0;
        varBinds.list = (RFC1157VarBind *)SnmpUtilMemAlloc( sizeof(RFC1157VarBind) );
        varBinds.len = 1;
        SnmpUtilOidCpy( &varBinds.list[0].name, &MIB_OidPrefix );
        varBinds.list[0].value.asnType = ASN_NULL;

        do
        {
            printf( "GET-NEXT of:  " );
            SnmpUtilPrintOid( &varBinds.list[0].name );
            printf( "   " );
            (*queryAddr)( (AsnInteger)ASN_RFC1157_GETNEXTREQUEST,
                          &varBinds,
                          &errorStatus,
                          &errorIndex
                        );
            printf( "\n  is  " );
            SnmpUtilPrintOid( &varBinds.list[0].name );
            if ( errorStatus )
            {
                printf( "\nErrorstatus:  %lu\n\n", errorStatus );
            }
            else
            {
                printf( "\n  =  " );
                SnmpUtilPrintAsnAny( &varBinds.list[0].value );
            }
            putchar( '\n' );

            // query potential traps (see notes above)
            if ( NULL != hPollForTrapEvent )
            {
                DWORD dwResult;


                if ( 0xffffffff ==
                        (dwResult = WaitForSingleObject(hPollForTrapEvent,
                                                        1000)) )
                {
                    dbgprintf(1, "error on WaitForSingleObject %d\n",
                              GetLastError());
                }
                else
                {
                    if ( dwResult == 0 /*signaled*/ )
                    {
                        AsnObjectIdentifier enterprise;
                        AsnInteger          genericTrap;
                        AsnInteger          specificTrap;
                        AsnTimeticks        timeStamp;
                        RFC1157VarBindList  variableBindings;


                        while( (*trapAddr)(&enterprise,
                                           &genericTrap,
                                           &specificTrap,
                                           &timeStamp,
                                           &variableBindings) )
                        {
                            printf("trap: gen=%d spec=%d time=%d\n",
                                   genericTrap, specificTrap, timeStamp);

                            //also print data
                        } // end while ()
                    } // end if (trap ready)
                }
            } // end if (handling traps)
        }
        while ( varBinds.list[0].name.ids[MIB_PREFIX_LEN-1] == 12 );

        // Free the memory
        SnmpUtilVarBindListFree( &varBinds );
    } // block


    return 0;

} // end main()
Beispiel #7
0
BOOL CSNMP::SnmpQueryTable( LPCTSTR apColumnOidList[], UINT nListLen, std::vector<std::pair<CString, std::vector<AsnAny>>> *pTable )
{
	if (!apColumnOidList || !pTable)
	{
		m_strLastError = L"[SnmpQueryTable] : Verify the arguments failed. ";
		return FALSE;
	}

	pTable->clear();

	if (!nListLen)
		return TRUE;

	typedef std::map<CString, AsnAny> RELATIVE_OID_TO_VALUE_MAP;

	std::vector<RELATIVE_OID_TO_VALUE_MAP> vColumnRelativeOidToValue(nListLen);

	SnmpVarBindList CurrentVarBindList;
	CurrentVarBindList.len = 0;
	CurrentVarBindList.list = NULL;

	AsnObjectIdentifier TargetObjectIdentifier;
	TargetObjectIdentifier.idLength = 0;
	TargetObjectIdentifier.ids = NULL;

	BOOL bRes = FALSE;
	do 
	{
		UINT i = 0;
		for (; i < nListLen; i++)
		{
			SnmpUtilVarBindListFree(&CurrentVarBindList);

			CurrentVarBindList.len = 1;
			CurrentVarBindList.list = (SnmpVarBind *)SnmpUtilMemAlloc(sizeof(SnmpVarBind));
			CurrentVarBindList.list->name.idLength = 0;
			CurrentVarBindList.list->name.ids = NULL;
			CurrentVarBindList.list->value.asnType = ASN_NULL;

#ifdef _UNICODE
			CStringA strOIDA = XLibS::StringCode::ConvertWideStrToAnsiStr(apColumnOidList[i]); 
#else
			CStringA strOIDA = apColumnOidList[i];
#endif

			if(!::SnmpMgrStrToOid(strOIDA.GetBuffer(), &CurrentVarBindList.list->name) || !CurrentVarBindList.list->name.ids || !CurrentVarBindList.list->name.idLength)
			{

#ifdef _UNICODE
				CStringW strOIDW = apColumnOidList[i];
#else
				CStringW strOIDW = XLibS::StringCode::ConvertAnsiStrToWideStr(apColumnOidList[i]);
#endif
				m_strLastError.Format(L"[SnmpQueryTable] : Bad OID string \"%s\". ", (LPCWSTR)strOIDW);

				strOIDA.ReleaseBuffer();

				break;
			}
			strOIDA.ReleaseBuffer();

			SnmpUtilOidFree(&TargetObjectIdentifier);
			TargetObjectIdentifier.idLength = 0;
			TargetObjectIdentifier.ids = NULL;

			if (!SnmpUtilOidCpy(&TargetObjectIdentifier, &CurrentVarBindList.list->name) || !TargetObjectIdentifier.ids || !TargetObjectIdentifier.idLength)
			{
				m_strLastError.Format(L"[SnmpQueryTable] : Copy OID failed. ");
				break;
			}

			BOOL bFailFlag = FALSE;
			while(1)
			{
				AsnInteger nSNMPErrorCode = 0;
				AsnInteger nSNMPErrorIndex = 0;
				if(!::SnmpMgrRequest(m_SnmpSession, SNMP_PDU_GETNEXT, &CurrentVarBindList, &nSNMPErrorCode, &nSNMPErrorIndex))
				{
					DWORD dwLastWinError = ::GetLastError();
					assert(nSNMPErrorIndex == 0);

					const WCHAR * SNMP_ERROR_MESSAGE[] = { L"The agent reports that no errors occurred during transmission. ", 
						L"The agent could not place the results of the requested operation into a single SNMP message. ", 
						L"The requested operation identified an unknown variable. ", 
						L"The requested operation tried to change a variable but it specified either a syntax or value error. ", 
						L"The requested operation tried to change a variable that was not allowed to change according to the community profile of the variable. "
					};

					const WCHAR * WIN_ERROR_MESSAGE[] = {L"The request timed-out.",
						L"Unexpected error file descriptors indicated by the Windows Sockets select function."
					};

					const WCHAR *pSNMPError = NULL;
					if (nSNMPErrorIndex < ARRAYSIZE(SNMP_ERROR_MESSAGE))
						pSNMPError = SNMP_ERROR_MESSAGE[nSNMPErrorIndex];
					else
						pSNMPError = L"Unknown error. ";

					const WCHAR *pWinError = NULL;
					if (dwLastWinError - 40 < ARRAYSIZE(WIN_ERROR_MESSAGE))
						pWinError = WIN_ERROR_MESSAGE[dwLastWinError - 40];
					else
						pWinError = L"Unknown error. ";

					m_strLastError.Format(L"SNMP requesting failed. SNMP ERROR : %s (%ld). WIN ERROR : %s (%lu). ", 
						pSNMPError, nSNMPErrorIndex, pWinError, dwLastWinError);
	
//					LPCWSTR pSysError = NULL;
//					m_strLastError.Format(L"SNMP requesting failed. SNMP ERROR : %s (%ld). ", pError, nErrorIndex);
//					if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 
//						NULL, dwLastError, 0, (LPTSTR)&pSysError, 0, NULL) && pSysError)
//					{
//						m_strLastError.AppendFormat(L"Windows ERROR: %s (%lu). ", pSysError, dwLastError);
//
//						::LocalFree((HLOCAL)pSysError);
//						pSysError = NULL;
//					}

					
					bFailFlag = TRUE;
					break;
				}

				assert(SNMP_ERRORSTATUS_NOERROR == nSNMPErrorCode);
				
				if (!CurrentVarBindList.list || (!CurrentVarBindList.list->name.ids && CurrentVarBindList.list->name.idLength))
				{
#ifdef _UNICODE
					CStringW strOIDW = apColumnOidList[i];
#else
					CStringW strOIDW = XLibS::StringCode::ConvertAnsiStrToWideStr(apColumnOidList[i]);
#endif
					m_strLastError.Format(L"[SnmpQueryTable] : GetNext returned a bad OID during the request for %s. ", (LPCWSTR)strOIDW);

					bFailFlag = TRUE;
					break;
				}

				if (CurrentVarBindList.list->name.idLength < TargetObjectIdentifier.idLength)
					break;

				if (SnmpUtilOidNCmp(&CurrentVarBindList.list->name, &TargetObjectIdentifier, TargetObjectIdentifier.idLength))
					break;

				CStringA strOIDTarget = ThreadSafeSnmpUtilOidToA(&TargetObjectIdentifier);
				CStringA strOIDCurrent = ThreadSafeSnmpUtilOidToA(&CurrentVarBindList.list->name);

				assert(strOIDCurrent.Find(strOIDTarget) == 0);



				AsnAny value;
				SnmpUtilAsnAnyCpy(&value, &CurrentVarBindList.list->value);

#ifdef _UNICODE
				CString strRelativeOID = 
					XLibS::StringCode::ConvertAnsiStrToWideStr(strOIDCurrent.Mid(strOIDTarget.GetLength()));
#else
				CString strRelativeOID = strOIDCurrent.Mid(strOIDTarget.GetLength());
#endif

				vColumnRelativeOidToValue[i].insert(std::make_pair(strRelativeOID, value));
			}
			if (bFailFlag)
				break;

		}

		if (i < nListLen)
			break;

		const RELATIVE_OID_TO_VALUE_MAP & FirstCol = vColumnRelativeOidToValue[0];
		for (RELATIVE_OID_TO_VALUE_MAP::const_iterator itFirstCol = FirstCol.begin();
			itFirstCol != FirstCol.end(); itFirstCol++)
		{
			std::vector<RELATIVE_OID_TO_VALUE_MAP::const_iterator> vItFind;

			UINT i = 1;
			for (; i < nListLen; i++)
			{
				const RELATIVE_OID_TO_VALUE_MAP & CurrentCol = 
					vColumnRelativeOidToValue[i];

				RELATIVE_OID_TO_VALUE_MAP::const_iterator itFind =
					 CurrentCol.find(itFirstCol->first);

				if (itFind == CurrentCol.end())
					break;

				vItFind.push_back(itFind);
			}

			if (i < nListLen)
				continue;

			pTable->push_back(make_pair(itFirstCol->first, std::vector<AsnAny>(1, itFirstCol->second)));

			for (std::vector<RELATIVE_OID_TO_VALUE_MAP::const_iterator>::size_type i = 0;
				i < vItFind.size(); i++)
			{
				pTable->back().second.push_back(vItFind[i]->second);
			}
		}

		bRes = TRUE;

	} while (FALSE);

	SnmpUtilOidFree(&TargetObjectIdentifier);
	SnmpUtilVarBindListFree(&CurrentVarBindList);

	if (!bRes)
	{
		ClearQueryTableResult(*pTable);
		pTable->clear();
	}

	return bRes;
}
Beispiel #8
0
static void testQuery(void)
{
    BOOL (WINAPI *pQuery)(BYTE, SnmpVarBindList *, AsnInteger32 *,
        AsnInteger32 *);
    BOOL ret, moreData, noChange;
    SnmpVarBindList list;
    AsnInteger32 error, index;
    UINT bogus[] = { 1,2,3,4 };
    UINT mib2System[] = { 1,3,6,1,2,1,1 };
    UINT mib2If[] = { 1,3,6,1,2,1,2 };
    UINT mib2IfTable[] = { 1,3,6,1,2,1,2,2 };
    UINT mib2IfDescr[] = { 1,3,6,1,2,1,2,2,1,2 };
    UINT mib2IfAdminStatus[] = { 1,3,6,1,2,1,2,2,1,7 };
    UINT mib2IfOperStatus[] = { 1,3,6,1,2,1,2,2,1,8 };
    UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1,1 };
    UINT mib2IpRouteTable[] = { 1,3,6,1,2,1,4,21,1,1 };
    UINT mib2UdpTable[] = { 1,3,6,1,2,1,7,5,1,1 };
    SnmpVarBind vars[3], vars2[3], vars3[3];
    UINT entry;

    pQuery = (void *)GetProcAddress(inetmib1, "SnmpExtensionQuery");
    if (!pQuery)
    {
        win_skip("couldn't find SnmpExtensionQuery\n");
        return;
    }
    /* Crash
    ret = pQuery(0, NULL, NULL, NULL);
    ret = pQuery(0, NULL, &error, NULL);
    ret = pQuery(0, NULL, NULL, &index);
    ret = pQuery(0, &list, NULL, NULL);
    ret = pQuery(0, &list, &error, NULL);
     */

    /* An empty list succeeds */
    list.len = 0;
    error = 0xdeadbeef;
    index = 0xdeadbeef;
    ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
    ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
    ok(error == SNMP_ERRORSTATUS_NOERROR,
        "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
    ok(index == 0, "expected index 0, got %d\n", index);

    /* Oddly enough, this "succeeds," even though the OID is clearly
     * unsupported.
     */
    vars[0].name.idLength = sizeof(bogus) / sizeof(bogus[0]);
    vars[0].name.ids = bogus;
    vars[0].value.asnType = 0;
    list.len = 1;
    list.list = vars;
    SetLastError(0xdeadbeef);
    error = 0xdeadbeef;
    index = 0xdeadbeef;
    ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
    ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
    ok(error == SNMP_ERRORSTATUS_NOERROR ||
        error == ERROR_FILE_NOT_FOUND /* Win9x */,
        "expected SNMP_ERRORSTATUS_NOERROR or ERROR_FILE_NOT_FOUND, got %d\n",
        error);
    if (error == SNMP_ERRORSTATUS_NOERROR)
        ok(index == 0, "expected index 0, got %d\n", index);
    else if (error == ERROR_FILE_NOT_FOUND)
        ok(index == 1, "expected index 1, got %d\n", index);
    /* The OID isn't changed either: */
    ok(!strcmp("1.2.3.4", SnmpUtilOidToA(&vars[0].name)),
        "expected 1.2.3.4, got %s\n", SnmpUtilOidToA(&vars[0].name));

    /* The table is not an accessible variable, so it fails */
    vars[0].name.idLength = sizeof(mib2IfTable) / sizeof(mib2IfTable[0]);
    vars[0].name.ids = mib2IfTable;
    SetLastError(0xdeadbeef);
    error = 0xdeadbeef;
    index = 0xdeadbeef;
    ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
    ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
    ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
        "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
    /* The index is 1-based rather than 0-based */
    ok(index == 1, "expected index 1, got %d\n", index);

    /* A Get fails on something that specifies a table (but not a particular
     * entry in it)...
     */
    vars[0].name.idLength = sizeof(mib2IfDescr) / sizeof(mib2IfDescr[0]);
    vars[0].name.ids = mib2IfDescr;
    vars[1].name.idLength =
        sizeof(mib2IfAdminStatus) / sizeof(mib2IfAdminStatus[0]);
    vars[1].name.ids = mib2IfAdminStatus;
    vars[2].name.idLength =
        sizeof(mib2IfOperStatus) / sizeof(mib2IfOperStatus[0]);
    vars[2].name.ids = mib2IfOperStatus;
    list.len = 3;
    SetLastError(0xdeadbeef);
    error = 0xdeadbeef;
    index = 0xdeadbeef;
    ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
    ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
    ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
        "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
    ok(index == 1, "expected index 1, got %d\n", index);
    /* but a GetNext succeeds with the same values, because GetNext gets the
     * entry after the specified OID, not the entry specified by it.  The
     * successor to the table is the first entry in the table.
     * The OIDs need to be allocated, because GetNext modifies them to indicate
     * the end of data.
     */
    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
    SnmpUtilOidCpy(&vars2[1].name, &vars[1].name);
    SnmpUtilOidCpy(&vars2[2].name, &vars[2].name);
    list.list = vars2;
    moreData = TRUE;
    noChange = FALSE;
    entry = 0;
    do {
        SetLastError(0xdeadbeef);
        error = 0xdeadbeef;
        index = 0xdeadbeef;
        ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
        ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
        ok(error == SNMP_ERRORSTATUS_NOERROR,
            "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
        ok(index == 0, "expected index 0, got %d\n", index);
        if (!ret)
            moreData = FALSE;
        else if (error)
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
            vars[0].name.idLength))
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[1].name, &vars[1].name,
            vars[1].name.idLength))
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[2].name, &vars[2].name,
            vars[2].name.idLength))
            moreData = FALSE;
        else if (!SnmpUtilOidCmp(&vars[0].name, &vars2[0].name) ||
         !SnmpUtilOidCmp(&vars[1].name, &vars2[1].name) ||
         !SnmpUtilOidCmp(&vars[2].name, &vars2[2].name))
        {
            /* If the OID isn't modified, the function isn't implemented on this
             * platform, skip the remaining tests.
             */
            noChange = TRUE;
        }
        if (moreData)
        {
            UINT lastID;

            /* Check the OIDs.  For these types of values (display strings and
             * integers) they should increase by 1 for each element of the table
             * according to RFC 1158.  Windows sometimes has a weird value in the
             * table, so allow any value as long as it's greater than the previous
             * value on Windows.
             */
            ok(vars2[0].name.idLength == vars[0].name.idLength + 1,
                "expected length %d, got %d\n", vars[0].name.idLength + 1,
                vars2[0].name.idLength);
            lastID = vars2[0].name.ids[vars2[0].name.idLength - 1];
            ok(lastID == entry + 1 || broken(lastID > entry),
                "expected %d, got %d\n", entry + 1, lastID);
            ok(vars2[1].name.idLength == vars[1].name.idLength + 1,
                "expected length %d, got %d\n", vars[1].name.idLength + 1,
                vars2[1].name.idLength);
            lastID = vars2[1].name.ids[vars2[1].name.idLength - 1];
            ok(lastID == entry + 1 || broken(lastID > entry),
                "expected %d, got %d\n", entry + 1, lastID);
            ok(vars2[2].name.idLength == vars[2].name.idLength + 1,
                "expected length %d, got %d\n", vars[2].name.idLength + 1,
                vars2[2].name.idLength);
            lastID = vars2[2].name.ids[vars2[2].name.idLength - 1];
            ok(lastID == entry + 1 || broken(lastID > entry),
                "expected %d, got %d\n", entry + 1, lastID);
            entry = lastID;
            /* Check the types while we're at it */
            ok(vars2[0].value.asnType == ASN_OCTETSTRING,
                "expected ASN_OCTETSTRING, got %02x\n", vars2[0].value.asnType);
            ok(vars2[1].value.asnType == ASN_INTEGER,
                "expected ASN_INTEGER, got %02x\n", vars2[1].value.asnType);
            ok(vars2[2].value.asnType == ASN_INTEGER,
                "expected ASN_INTEGER, got %02x\n", vars2[2].value.asnType);
        }
        else if (noChange)
            skip("no change in OID, no MIB2 IF table implementation\n");
    } while (moreData && !noChange);
    SnmpUtilVarBindFree(&vars2[0]);
    SnmpUtilVarBindFree(&vars2[1]);
    SnmpUtilVarBindFree(&vars2[2]);

    /* Even though SnmpExtensionInit says this DLL supports the MIB2 system
     * variables, on recent systems (at least Win2k) the first variable it
     * returns a value for is the first interface.
     */
    vars[0].name.idLength = sizeof(mib2System) / sizeof(mib2System[0]);
    vars[0].name.ids = mib2System;
    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
    vars2[0].value.asnType = 0;
    list.len = 1;
    list.list = vars2;
    moreData = TRUE;
    noChange = FALSE;
    ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
    ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
    ok(error == SNMP_ERRORSTATUS_NOERROR,
        "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
    ok(index == 0, "expected index 0, got %d\n", index);
    vars3[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]);
    vars3[0].name.ids = mib2If;
    ok(!SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, vars[0].name.idLength) ||
       !SnmpUtilOidNCmp(&vars2[0].name, &vars3[0].name, vars3[0].name.idLength),
        "expected 1.3.6.1.2.1.1 or 1.3.6.1.2.1.2, got %s\n",
        SnmpUtilOidToA(&vars2[0].name));
    SnmpUtilVarBindFree(&vars2[0]);

    /* Check the type and OIDs of the IP address table */
    vars[0].name.idLength = sizeof(mib2IpAddr) / sizeof(mib2IpAddr[0]);
    vars[0].name.ids = mib2IpAddr;
    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
    vars2[0].value.asnType = 0;
    list.len = 1;
    list.list = vars2;
    moreData = TRUE;
    do {
        ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
        ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
        ok(error == SNMP_ERRORSTATUS_NOERROR,
            "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
        ok(index == 0, "expected index 0, got %d\n", index);
        if (!ret)
            moreData = FALSE;
        else if (error)
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
            vars[0].name.idLength))
            moreData = FALSE;
        else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name))
        {
            /* If the OID isn't modified, the function isn't implemented on this
             * platform, skip the remaining tests.
             */
            noChange = TRUE;
        }
        if (moreData)
        {
            /* Make sure the size of the OID is right.
             * FIXME: don't know if IPv6 addrs are shared with this table.
             * Don't think so, but I'm not certain.
             */
            ok(vars2[0].name.idLength == vars[0].name.idLength + 4,
                "expected length %d, got %d\n", vars[0].name.idLength + 4,
                vars2[0].name.idLength);
            /* Make sure the type is right */
            ok(vars2[0].value.asnType == ASN_IPADDRESS,
                "expected type ASN_IPADDRESS, got %02x\n",
                vars2[0].value.asnType);
            if (vars2[0].value.asnType == ASN_IPADDRESS)
            {
                UINT i;

                /* This looks uglier than it is:  the base OID for the IP
                 * address, 1.3.6.1.2.1.4.20.1.1, is appended with the IP
                 * address of the entry.  So e.g. the loopback address is
                 * identified in MIB2 as 1.3.6.1.2.1.4.20.1.1.127.0.0.1
                 */
                for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
                {
                    ok(vars2[0].value.asnValue.address.stream[i] ==
                        vars2[0].name.ids[vars2[0].name.idLength - 4 + i],
                        "expected ident byte %d to be %d, got %d\n", i,
                        vars2[0].value.asnValue.address.stream[i],
                        vars2[0].name.ids[vars2[0].name.idLength - 4 + i]);
                }
            }
        }
        else if (noChange)
            skip("no change in OID, no MIB2 IP address table implementation\n");
    } while (moreData && !noChange);
    SnmpUtilVarBindFree(&vars2[0]);

    /* Check the type and OIDs of the IP route table */
    vars[0].name.idLength = DEFINE_SIZEOF(mib2IpRouteTable);
    vars[0].name.ids = mib2IpRouteTable;
    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
    vars2[0].value.asnType = 0;
    list.len = 1;
    list.list = vars2;
    moreData = TRUE;
    noChange = FALSE;
    do {
        ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
        ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
        ok(error == SNMP_ERRORSTATUS_NOERROR,
            "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
        ok(index == 0, "expected index 0, got %d\n", index);
        if (!ret)
            moreData = FALSE;
        else if (error)
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
            vars[0].name.idLength))
            moreData = FALSE;
        else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name))
        {
            /* If the OID isn't modified, the function isn't implemented on this
             * platform, skip the remaining tests.
             */
            noChange = TRUE;
        }
        if (moreData)
        {
            /* Make sure the size of the OID is right.
             * FIXME: don't know if IPv6 addrs are shared with this table.
             * Don't think so, but I'm not certain.
             */
            ok(vars2[0].name.idLength == vars[0].name.idLength + 4,
                "expected length %d, got %d\n", vars[0].name.idLength + 4,
                vars2[0].name.idLength);
            /* Make sure the type is right */
            ok(vars2[0].value.asnType == ASN_IPADDRESS,
                "expected type ASN_IPADDRESS, got %02x\n",
                vars2[0].value.asnType);
            if (vars2[0].value.asnType == ASN_IPADDRESS)
            {
                UINT i;

                /* The base OID for the route table, 1.3.6.1.2.1.4.21.1.1, is
                 * appended with the dest IP address of the entry.  So e.g. a
                 * route entry for 224.0.0.0 is identified in MIB2 as
                 * 1.3.6.1.2.1.4.21.1.1.224.0.0.0
                 */
                for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
                {
                    ok(vars2[0].value.asnValue.address.stream[i] ==
                        vars2[0].name.ids[vars2[0].name.idLength - 4 + i],
                        "expected ident byte %d to be %d, got %d\n", i,
                        vars2[0].value.asnValue.address.stream[i],
                        vars2[0].name.ids[vars2[0].name.idLength - 4 + i]);
                }
            }
        }
        else if (noChange)
            skip("no change in OID, no MIB2 IP route table implementation\n");
    } while (moreData && !noChange);
    SnmpUtilVarBindFree(&vars2[0]);

    /* Check the type and OIDs of the UDP table */
    vars[0].name.idLength = DEFINE_SIZEOF(mib2UdpTable);
    vars[0].name.ids = mib2UdpTable;
    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
    vars2[0].value.asnType = 0;
    list.len = 1;
    list.list = vars2;
    moreData = TRUE;
    noChange = FALSE;
    do {
        ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
        ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index);
        /* FIXME:  error and index aren't checked here because the UDP table is
         * the last OID currently supported by Wine, so the last GetNext fails.
         * todo_wine is also not effective because it will succeed for all but
         * the last GetNext.  Remove the if (0) if any later OID is supported
         * by Wine.
         */
        if (0) {
        ok(error == SNMP_ERRORSTATUS_NOERROR,
            "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
        ok(index == 0, "expected index 0, got %d\n", index);
        }
        if (!ret)
            moreData = FALSE;
        else if (error)
            moreData = FALSE;
        else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
            vars[0].name.idLength))
            moreData = FALSE;
        else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name))
        {
            /* If the OID isn't modified, the function isn't implemented on this
             * platform, skip the remaining tests.
             */
            noChange = TRUE;
        }
        if (moreData)
        {
            /* Make sure the size of the OID is right. */
            ok(vars2[0].name.idLength == vars[0].name.idLength + 5,
                "expected length %d, got %d\n", vars[0].name.idLength + 5,
                vars2[0].name.idLength);
            /* Make sure the type is right */
            ok(vars2[0].value.asnType == ASN_IPADDRESS,
                "expected type ASN_IPADDRESS, got %02x\n",
                vars2[0].value.asnType);
            if (vars2[0].value.asnType == ASN_IPADDRESS)
            {
                UINT i;

                /* Again with the ugly:  the base OID for the UDP table,
                 * 1.3.6.1.2.1.7.5.1, is appended with the local IP address and
                 * port number of the entry.  So e.g. an entry for
                 * 192.168.1.1:4000 is identified in MIB2 as
                 * 1.3.6.1.2.1.7.5.1.192.168.1.1.4000
                 */
                for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
                {
                    ok(vars2[0].value.asnValue.address.stream[i] ==
                        vars2[0].name.ids[vars2[0].name.idLength - 5 + i],
                        "expected ident byte %d to be %d, got %d\n", i,
                        vars2[0].value.asnValue.address.stream[i],
                        vars2[0].name.ids[vars2[0].name.idLength - 5 + i]);
                }
            }
        }
        else if (noChange)
            skip("no change in OID, no MIB2 UDP table implementation\n");
    } while (moreData && !noChange);
    SnmpUtilVarBindFree(&vars2[0]);
}
BOOL WINAPI SnmpExtensionQuery(
    IN BYTE                   requestType,
    IN OUT RFC1157VarBindList *variableBindings,
    OUT AsnInteger            *errorStatus,
    OUT AsnInteger            *errorIndex)
    {
    static unsigned long requestCount = 0;  // Supports the trap simulation.
    UINT    I;


    // Iterate through the variable bindings list to resolve individual
    // variable bindings.

    for ( I=0;I < variableBindings->len;I++ )
        {
        *errorStatus = ResolveVarBind( &variableBindings->list[I],
                                       requestType );


        // Test and handle case where Get Next past end of MIB view supported
        // by this Extension Agent occurs.  Special processing is required to 
        // communicate this situation to the Extendible Agent so it can take 
        // appropriate action, possibly querying other Extension Agents.

        if ( *errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME &&
             requestType == MIB_ACTION_GETNEXT )
           {
           *errorStatus = SNMP_ERRORSTATUS_NOERROR;


           // Modify variable binding of such variables so the OID points
           // just outside the MIB view supported by this Extension Agent.
           // The Extendible Agent tests for this, and takes appropriate
           // action.

           SnmpUtilOidFree( &variableBindings->list[I].name );
           SnmpUtilOidCpy( &variableBindings->list[I].name, &MIB_OidPrefix );
           variableBindings->list[I].name.ids[MIB_PREFIX_LEN-1] ++;
           }


        // If an error was indicated, communicate error status and error
        // index to the Extendible Agent.  The Extendible Agent will ensure
        // that the origional variable bindings are returned in the response
        // packet.

        if ( *errorStatus != SNMP_ERRORSTATUS_NOERROR )
           {
	   *errorIndex = I+1;
	   goto Exit;
	   }
        }

Exit:


    // Supports the trap simulation.

    if (++requestCount % 3 == 0 && hSimulateTrap != NULL)
        SetEvent(hSimulateTrap);


    // Indicate that Extension Agent processing was sucessfull.

    return SNMPAPI_NOERROR;

    } // end SnmpExtensionQuery()
Beispiel #10
0
/*****************************************************************************
 * SnmpExtensionQuery [INETMIB1.@]
 */
BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
    AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
{
    AsnObjectIdentifier mib2oid = DEFINE_OID(mib2);
    AsnInteger32 error = SNMP_ERRORSTATUS_NOERROR, errorIndex = 0;
    UINT i;
    BOOL ret = TRUE;

    TRACE("(0x%02x, %p, %p, %p)\n", bPduType, pVarBindList,
        pErrorStatus, pErrorIndex);

    for (i = 0; !error && i < pVarBindList->len; i++)
    {
        /* Ignore any OIDs not in MIB2 */
        if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
            mib2oid.idLength))
        {
            struct mibImplementation *impl = NULL;
            UINT len, matchingIndex = 0;

            TRACE("%s\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
            /* Search for an implementation matching as many octets as possible
             */
            for (len = pVarBindList->list[i].name.idLength;
                len >= minSupportedIDLength && !impl; len--)
                impl = findSupportedQuery(pVarBindList->list[i].name.ids, len,
                    &matchingIndex);
            if (impl && impl->query)
                ret = impl->query(bPduType, &pVarBindList->list[i], &error);
            else
                error = SNMP_ERRORSTATUS_NOSUCHNAME;
            if (error == SNMP_ERRORSTATUS_NOSUCHNAME &&
                bPduType == SNMP_PDU_GETNEXT)
            {
                /* GetNext is special: it finds the successor to the given OID,
                 * so we have to continue until an implementation handles the
                 * query or we exhaust the table of supported OIDs.
                 */
                for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
                    matchingIndex < DEFINE_SIZEOF(supportedIDs);
                    matchingIndex++)
                {
                    error = SNMP_ERRORSTATUS_NOERROR;
                    impl = &supportedIDs[matchingIndex];
                    if (impl->query)
                        ret = impl->query(bPduType, &pVarBindList->list[i],
                            &error);
                    else
                        error = SNMP_ERRORSTATUS_NOSUCHNAME;
                }
                /* If the query still isn't resolved, set the OID to the
                 * successor to the last entry in the table.
                 */
                if (error == SNMP_ERRORSTATUS_NOSUCHNAME)
                {
                    SnmpUtilOidFree(&pVarBindList->list[i].name);
                    ret = SnmpUtilOidCpy(&pVarBindList->list[i].name,
                        &supportedIDs[matchingIndex - 1].name);
                    pVarBindList->list[i].name.ids[
                        pVarBindList->list[i].name.idLength - 1] += 1;
                }
            }
            if (error)
                errorIndex = i + 1;
        }
    }
    *pErrorStatus = error;
    *pErrorIndex = errorIndex;
    return ret;
}
Beispiel #11
0
//
// MIB_sess_func
//    High level routine for handling operations on the session table
//
// Notes:
//
// Return Codes:
//    None.
//
// Error Codes:
//    None.
//
UINT MIB_sess_func(
        IN UINT Action,
        IN MIB_ENTRY *MibPtr,
        IN OUT RFC1157VarBind *VarBind
        )

{
int     Found;
UINT    Entry;
UINT    Field;
UINT    ErrStat;


   switch ( Action )
      {
      case MIB_ACTION_GETFIRST:
         // Fill the Session table with the info from server
         if ( SNMPAPI_ERROR == MIB_sess_lmget() )
            {
            ErrStat = SNMP_ERRORSTATUS_GENERR;
            goto Exit;
            }

         // If no elements in table, then return next MIB var, if one
         if ( MIB_SessionTable.Len == 0 )
            {
            if ( MibPtr->MibNext == NULL )
               {
               ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
               goto Exit;
               }

            // Do get first on the next MIB var
            ErrStat = (*MibPtr->MibNext->MibFunc)( Action, MibPtr->MibNext,
                                                   VarBind );
            break;
            }

         //
         // Place correct OID in VarBind
         // Assuming the first field in the first record is the "start"
         {
         UINT temp_subs[] = { SESS_FIRST_FIELD };
         AsnObjectIdentifier FieldOid = { 1, temp_subs };


         SnmpUtilOidFree( &VarBind->name );
         SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
         SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix );
         SnmpUtilOidAppend( &VarBind->name, &FieldOid );
         SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[0].Oid );
         }

         //
         // Let fall through on purpose
         //

      case MIB_ACTION_GET:
         ErrStat = MIB_sess_get( VarBind );
         break;

      case MIB_ACTION_GETNEXT:
         // Fill the Session table with the info from server
         if ( SNMPAPI_ERROR == MIB_sess_lmget() )
            {
            ErrStat = SNMP_ERRORSTATUS_GENERR;
            goto Exit;
            }

         // Lookup OID in table
         Found = MIB_sess_match( &VarBind->name, &Entry, TRUE );

         // Determine which field
         Field = VarBind->name.ids[SESS_FIELD_SUBID];

         // Index not found, but could be more fields to base GET on
         if ( Found == MIB_TBL_POS_END )
            {
            // Index not found in table, get next from field
//            Field ++;

            // Make sure not past last field
//            if ( Field > SESS_LAST_FIELD )
//               {
               // Get next VAR in MIB
               ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
                                                      MibPtr->MibNext,
                                                      VarBind );
               break;
//               }
            }

         // Get next TABLE entry
         if ( Found == MIB_TBL_POS_FOUND )
            {
            Entry ++;
            if ( Entry > MIB_SessionTable.Len-1 )
               {
               Entry = 0;
               Field ++;

               /* item not implemented. Skip */

               if (Field == SESS_NUMCONS_FIELD) {
                   Field++;
               }

               if ( Field > SESS_LAST_FIELD )
                  {
                  // Get next VAR in MIB
                  ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
                                                         MibPtr->MibNext,
                                                         VarBind );
                  break;
                  }
               }
            }

         //
         // Place correct OID in VarBind
         // Assuming the first field in the first record is the "start"
         {
         UINT temp_subs[1];
         AsnObjectIdentifier FieldOid;

         temp_subs[0]      = Field;
         FieldOid.idLength = 1;
         FieldOid.ids      = temp_subs;

         SnmpUtilOidFree( &VarBind->name );
         SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
         SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix );
         SnmpUtilOidAppend( &VarBind->name, &FieldOid );
         SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[Entry].Oid );
         }

         ErrStat = MIB_sess_copyfromtable( Entry, Field, VarBind );

         break;

      case MIB_ACTION_SET:
         // Make sure OID is long enough
         if ( SESS_FIELD_SUBID + 1 > VarBind->name.idLength )
            {
            ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
            goto Exit;
            }

         // Get field number
         Field = VarBind->name.ids[SESS_FIELD_SUBID];

         // If the field being set is not the STATE field, error
         if ( Field != SESS_STATE_FIELD )
            {
            ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
            goto Exit;
            }

         // Check for proper type before setting
         if ( ASN_INTEGER != VarBind->value.asnType )
            {
            ErrStat = SNMP_ERRORSTATUS_BADVALUE;
            goto Exit;
            }

         // Make sure that the value is valid
         if ( VarBind->value.asnValue.number < SESS_STATE_ACTIVE &&
              VarBind->value.asnValue.number > SESS_STATE_DELETED )
            {
            ErrStat = SNMP_ERRORSTATUS_BADVALUE;
            goto Exit;
            }

         ErrStat = MIB_sess_lmset( &VarBind->name, Field, &VarBind->value );

         break;

      default:
         ErrStat = SNMP_ERRORSTATUS_GENERR;
      }

Exit:
   return ErrStat;
} // MIB_sess_func
// Main program.
INT _CRTAPI1 main(
    IN int  argumentCount,
    IN char *argumentVector[])
    {
    INT                operation;
    LPSTR              agent = NULL;
    LPSTR              community = NULL;
    RFC1157VarBindList variableBindings;
    LPSNMP_MGR_SESSION session = NULL;

    INT        timeout = TIMEOUT;
    INT        retries = RETRIES;

    BYTE       requestType;
    AsnInteger errorStatus;
    AsnInteger errorIndex;


    // Parse command line arguments to determine requested operation.

    // Verify number of arguments...
    if      (argumentCount < 5 && argumentCount != 2)
        {
        printf("Error:  Incorrect number of arguments specified.\n");
        printf(
"\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
        printf(
  "        snmputil trap\n");

        return 1;
        }

    // Get/verify operation...
    argumentVector++;
    argumentCount--;
    if      (!strcmp(*argumentVector, "get"))
        operation = GET;
    else if (!strcmp(*argumentVector, "getnext"))
        operation = GETNEXT;
    else if (!strcmp(*argumentVector, "walk"))
        operation = WALK;
    else if (!strcmp(*argumentVector, "trap"))
        operation = TRAP;
    else
        {
        printf("Error:  Invalid operation, '%s', specified.\n",
               *argumentVector);

        return 1;
        }

    if (operation != TRAP)
        {
        if (argumentCount < 4)
            {
            printf("Error:  Incorrect number of arguments specified.\n");
            printf(
"\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
            printf(
  "        snmputil trap\n");

            return 1;
            }

        // Get agent address...
        argumentVector++;
        argumentCount--;
        agent = (LPSTR)SnmpUtilMemAlloc((UINT)(strlen(*argumentVector) + 1));
        if (agent != NULL)
            StringCchCopyA(agent, strlen(*argumentVector) + 1, *argumentVector);
        else
            {
            printf("Error: SnmpUtilMemAlloc failed to allocate memory.\n");
            return 1;
            }

        // Get agent community...
        argumentVector++;
        argumentCount--;
        community = (LPSTR)SnmpUtilMemAlloc((UINT)(strlen(*argumentVector) + 1));
        if (community != NULL)
            StringCchCopyA(community, strlen(*argumentVector) + 1, *argumentVector);
        else
            {
            printf("Error: SnmpUtilMemAlloc failed to allocate memory.\n");
            SnmpUtilMemFree(agent);
            return 1;
            }

        // Get oid's...
        variableBindings.list = NULL;
        variableBindings.len = 0;

        while(--argumentCount)
            {
            AsnObjectIdentifier reqObject;
            RFC1157VarBind * tmpVb;

            argumentVector++;

            // Convert the string representation to an internal representation.
            if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
                {
                printf("Error: Invalid oid, %s, specified.\n", *argumentVector);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            else
                {
                // Since sucessfull, add to the variable bindings list.
                variableBindings.len++;
                if ((tmpVb = (RFC1157VarBind *)SnmpUtilMemReAlloc(
                    variableBindings.list, sizeof(RFC1157VarBind) *
                    variableBindings.len)) == NULL)
                    {
                    printf("Error: Error allocating oid, %s.\n",
                           *argumentVector);
                    SnmpUtilMemFree(agent);
                    SnmpUtilMemFree(community);
                    SnmpUtilOidFree(&reqObject);
                    variableBindings.len--;
                    SnmpUtilVarBindListFree(&variableBindings);

                    return 1;
                    }
                variableBindings.list = tmpVb;

                variableBindings.list[variableBindings.len - 1].name =
                    reqObject; // NOTE!  structure copy
                variableBindings.list[variableBindings.len - 1].value.asnType =
                    ASN_NULL;
                }
            } // end while()

        // Make sure only one variable binding was specified if operation
        // is WALK.
        if (operation == WALK && variableBindings.len != 1)
            {
            printf("Error: Multiple oids specified for WALK.\n");
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);
            return 1;
            }

        // Establish a SNMP session to communicate with the remote agent.  The
        // community, communications timeout, and communications retry count
        // for the session are also required.

        if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL)
            {
            printf("error on SnmpMgrOpen %d\n", GetLastError());
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);

            return 1;
            }

        } // end if(TRAP)


    // Determine and perform the requested operation.

    if      (operation == GET || operation == GETNEXT)
        {
        // Get and GetNext are relatively simple operations to perform.
        // Simply initiate the request and process the result and/or
        // possible error conditions.


        if (operation == GET)
            requestType = ASN_RFC1157_GETREQUEST;
        else
            requestType = ASN_RFC1157_GETNEXTREQUEST;


        // Request that the API carry out the desired operation.

        if (!SnmpMgrRequest(session, requestType, &variableBindings,
                            &errorStatus, &errorIndex))
            {
            // The API is indicating an error.

            printf("error on SnmpMgrRequest %d\n", GetLastError());
            }
        else
            {
            // The API succeeded, errors may be indicated from the remote
            // agent.

            if (errorStatus > 0)
                {
                printf("Error: errorStatus=%d, errorIndex=%d\n",
                       errorStatus, errorIndex);
                }
            else
                {
                // Display the resulting variable bindings.

                UINT i;
                
                for(i=0; i < variableBindings.len; i++)
                    {
                    char *string = NULL;
                    
                    if (SnmpMgrOidToStr(&variableBindings.list[i].name, &string))
                        {
                        printf("Variable = %s\n", string);
                        if (string) SnmpUtilMemFree(string);
                        }
                    printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[i].value);

                    printf("\n");
                    } // end for()
                }
            }

        // Free the variable bindings that have been allocated.
        
        SnmpUtilVarBindListFree(&variableBindings);
        
        // Free other allocated resources 

        SnmpUtilMemFree(agent);
        SnmpUtilMemFree(community);


        }
    else if (operation == WALK)
        {
        // Walk is a common term used to indicate that all MIB variables
        // under a given OID are to be traversed and displayed.  This is
        // a more complex operation requiring tests and looping in addition
        // to the steps for get/getnext above.
        
        
        AsnObjectIdentifier root;
        AsnObjectIdentifier tempOid;
        
        
        if (!SnmpUtilOidCpy(&root, &variableBindings.list[0].name))
            {
            printf("error on SnmpUtilOidCpy\n");
            SnmpUtilMemFree(agent);
            SnmpUtilMemFree(community);
            SnmpUtilVarBindListFree(&variableBindings);
            return 1;
            }
        
        requestType = ASN_RFC1157_GETNEXTREQUEST;
        
        
        while(1)
            {
            if (!SnmpMgrRequest(session, requestType, &variableBindings,
                &errorStatus, &errorIndex))
                {
                // The API is indicating an error.
                
                printf("error on SnmpMgrRequest %d\n", GetLastError());
                
                break;
                }
            else
                {
                // The API succeeded, errors may be indicated from the remote
                // agent.
                
                
                // Test for end of subtree or end of MIB.
                
                if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
                    SnmpUtilOidNCmp(&variableBindings.list[0].name,
                    &root, root.idLength))
                    {
                    printf("End of MIB subtree.\n\n");
                    
                    break;
                    }
                
                
                // Test for general error conditions or sucesss.
                
                if (errorStatus > 0)
                    {
                    printf("Error: errorStatus=%d, errorIndex=%d \n",
                        errorStatus, errorIndex);
                    
                    break;
                    }
                else
                    {
                    // Display resulting variable binding for this iteration.
                    
                    char *string = NULL;
                    
                    if (SnmpMgrOidToStr(&variableBindings.list[0].name, &string))
                        {
                        printf("Variable = %s\n", string);
                        if (string) SnmpUtilMemFree(string);
                        }
                    printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[0].value);
                    
                    printf("\n");
                    }
                } // end if()
            
            
            // Prepare for the next iteration.  Make sure returned oid is
            // preserved and the returned value is freed.
            
            if (!SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name))
                {
                printf("error on SnmpUtilOidCpy\n");
                SnmpUtilOidFree(&root);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            
            SnmpUtilVarBindFree(&variableBindings.list[0]);
            
            if (!SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid))
                {
                printf("error on SnmpUtilOidCpy\n");
                SnmpUtilOidFree(&tempOid);
                SnmpUtilOidFree(&root);
                SnmpUtilMemFree(agent);
                SnmpUtilMemFree(community);
                SnmpUtilVarBindListFree(&variableBindings);
                return 1;
                }
            variableBindings.list[0].value.asnType = ASN_NULL;
            
            SnmpUtilOidFree(&tempOid);
            
        } // end while()
        
        
        // Free the variable bindings that have been allocated.
        
        SnmpUtilVarBindListFree(&variableBindings);
        
        // Free other allocated resources

        SnmpUtilOidFree(&root);
        SnmpUtilMemFree(agent);
        SnmpUtilMemFree(community);
        
        
    }
    else if (operation == TRAP)
        {
        // Trap handling can be done two different ways: event driven or
        // polled.  The following code illustrates the steps to use event
        // driven trap reception in a management application.


        HANDLE hNewTraps = NULL;


        if (!SnmpMgrTrapListen(&hNewTraps))
            {
            printf("error on SnmpMgrTrapListen %d\n", GetLastError());
            return 1;
            }
        else
            {
            printf("snmputil: listening for traps...\n");
            }


        while(1)
            {
            DWORD dwResult;

            if ((dwResult = WaitForSingleObject(hNewTraps, INFINITE))
                == WAIT_FAILED)
                {
                printf("error on WaitForSingleObject %d\n",
                       GetLastError());
                }
            else if (dwResult != WAIT_OBJECT_0)
                {
                    printf("hNewTraps is not signaled\n");
                }
            else if (!ResetEvent(hNewTraps))
                {
                printf("error on ResetEvent %d\n", GetLastError());
                }
            else
                {
                AsnObjectIdentifier enterprise;
                AsnNetworkAddress   agentAddress;
                AsnNetworkAddress   sourceAddress;
                AsnInteger          genericTrap;
                AsnInteger          specificTrap;
                AsnOctetString      communityTrap;
                AsnTimeticks        timeStamp;
                RFC1157VarBindList  variableBindingsTrap;

                UINT i;
                
                while(SnmpMgrGetTrapEx(
                        &enterprise,
                        &agentAddress,
                        &sourceAddress,
                        &genericTrap,
                        &specificTrap,
                        &communityTrap,
                        &timeStamp,
                        &variableBindingsTrap))
                    {

                    LPSTR string = NULL;

                    printf("Incoming Trap:\n"
                           "  generic    = %d\n"
                           "  specific   = %d\n"
                           "  timeStamp  = %u\n",
                           genericTrap,
                           specificTrap,
                           timeStamp);

                    if (SnmpMgrOidToStr(&enterprise, &string))
                        {
                        printf ("  enterprise = %s\n", string);
                        if (string) 
                            SnmpUtilMemFree(string);
                        }
                    SnmpUtilOidFree(&enterprise);

                    if (agentAddress.length == 4) 
                        {
                        printf ("  agent      = %d.%d.%d.%d\n",
                             (int)agentAddress.stream[0],
                             (int)agentAddress.stream[1],
                             (int)agentAddress.stream[2],
                             (int)agentAddress.stream[3]);
                        }
                    if (agentAddress.dynamic) 
                        {
                        SnmpUtilMemFree(agentAddress.stream);
                        }

                    if (sourceAddress.length == 4) 
                        {
                        printf ("  source IP  = %d.%d.%d.%d\n",
                             (int)sourceAddress.stream[0],
                             (int)sourceAddress.stream[1],
                             (int)sourceAddress.stream[2],
                             (int)sourceAddress.stream[3]);
                        }
                    else if (sourceAddress.length == 10) 
                        {
                        printf ("  source IPX = %.2x%.2x%.2x%.2x."
                                "%.2x%.2x%.2x%.2x%.2x%.2x\n",
                             (int)sourceAddress.stream[0],
                             (int)sourceAddress.stream[1],
                             (int)sourceAddress.stream[2],
                             (int)sourceAddress.stream[3],
                             (int)sourceAddress.stream[4],
                             (int)sourceAddress.stream[5],
                             (int)sourceAddress.stream[6],
                             (int)sourceAddress.stream[7],
                             (int)sourceAddress.stream[8],
                             (int)sourceAddress.stream[9]);
                        }
                    if (sourceAddress.dynamic) 
                        {
                        SnmpUtilMemFree(sourceAddress.stream);
                        }

                    if (communityTrap.length)
                        {
                        string = (LPSTR)SnmpUtilMemAlloc (communityTrap.length + 1);
                        if (string)
                            {
                            memcpy (string, communityTrap.stream, communityTrap.length);
                            string[communityTrap.length] = '\0';
                            printf ("  community  = %s\n", string);
                            SnmpUtilMemFree(string);
                            }
                        }
                    if (communityTrap.dynamic) 
                        {
                        SnmpUtilMemFree(communityTrap.stream);
                        }

                    for(i=0; i < variableBindingsTrap.len; i++)
                        {

                        string = NULL;
                        if (SnmpMgrOidToStr(&variableBindingsTrap.list[i].name, &string))
                            {
                            printf("  variable   = %s\n", string);
                            if (string) SnmpUtilMemFree(string);
                            }

                        printf("  value      = ");
                        SnmpUtilPrintAsnAny(&variableBindingsTrap.list[i].value);
                        } // end for()
                    printf("\n");


                    SnmpUtilVarBindListFree(&variableBindingsTrap);
                    }

                dwResult = GetLastError(); // check for errors...

                if ((dwResult != NOERROR) && (dwResult != SNMP_MGMTAPI_NOTRAPS))
                    {
                    printf("error on SnmpMgrGetTrap %d\n", dwResult);
                    }
                }

            } // end while()


        } // end if(operation)

    if (operation != TRAP)
        {
        // Close SNMP session with the remote agent.

        if (!SnmpMgrClose(session))
            {
            printf("error on SnmpMgrClose %d\n", GetLastError());

            return 1;
            }
        }


    // Let the command interpreter know things went ok.

    return 0;

    } // end main()
void _php3_snmp(INTERNAL_FUNCTION_PARAMETERS, int st) {
	pval *a1, *a2, *a3;
	INT	operation;
    LPSTR              agent;
    LPSTR              community;
    RFC1157VarBindList variableBindings;
    LPSNMP_MGR_SESSION session;

    INT        timeout = TIMEOUT;
    INT        retries = RETRIES;

    BYTE       requestType;
    AsnInteger errorStatus;
    AsnInteger errorIndex;
    AsnObjectIdentifier oid;
   char        *chkPtr = NULL;

	if (getParameters(ht, 3, &a1, &a2, &a3) == FAILURE) {
		WRONG_PARAM_COUNT;
	}
	convert_to_string(a1);
	convert_to_string(a2);
	convert_to_string(a3);

	agent=a1->value.str.val;
	community=a2->value.str.val;
	operation=st;
	SnmpMgrStrToOid(a3->value.str.val, &oid);

/* 
   I've limited this to only one oid, but we can create a
   list of oid's here, and expand the function to take multiple
   oid's
*/
    variableBindings.list->name = oid; 
    variableBindings.list->value.asnType = ASN_NULL;
    variableBindings.len = 1;

/* Establish a SNMP session to communicate with the remote agent.  The
   community, communications timeout, and communications retry count
   for the session are also required.
*/
	if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL){
		php_error(E_WARNING,"error on SnmpMgrOpen %d\n", GetLastError());
	}

    /* Determine and perform the requested operation.*/
    if (operation == GET || operation == GETNEXT){
        /* Get and GetNext are relatively simple operations to perform.
           Simply initiate the request and process the result and/or
           possible error conditions. */

        if (operation == GET){
            requestType = ASN_RFC1157_GETREQUEST;
		} else {
            requestType = ASN_RFC1157_GETNEXTREQUEST;
		}

        /* Request that the API carry out the desired operation.*/
		if (!SnmpMgrRequest(session, requestType, &variableBindings,
                            &errorStatus, &errorIndex)){
            /* The API is indicating an error. */
            php_error(E_WARNING,"error on SnmpMgrRequest %d\n", GetLastError());
        } else {
            /* The API succeeded, errors may be indicated from the remote
               agent. */
            if (errorStatus > 0){
                php_error(E_WARNING,"Error: errorStatus=%d, errorIndex=%d\n",
                       errorStatus, errorIndex);
            } else {
                /* Display the resulting variable bindings.*/
				UINT i;
                char *str = NULL;

                for(i=0; i < variableBindings.len; i++)
                    {
                    SnmpMgrOidToStr(&variableBindings.list[i].name, &str);
                    php_printf("Variable = %s\n", str);
                    if (str) SNMP_free(str);

                    php_printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[i].value);

                    php_printf("\n");
                    } /* end for() */
                }
            }

        /* Free the variable bindings that have been allocated.*/
        SnmpUtilVarBindListFree(&variableBindings);
        }
    else if (operation == WALK)
        {
        /* Walk is a common term used to indicate that all MIB variables
           under a given OID are to be traversed and displayed.  This is
           a more complex operation requiring tests and looping in addition
           to the steps for get/getnext above. */
        AsnObjectIdentifier root;
        AsnObjectIdentifier tempOid;

        SnmpUtilOidCpy(&root, &variableBindings.list[0].name);
        requestType = ASN_RFC1157_GETNEXTREQUEST;

        while(1)
            {
            if (!SnmpMgrRequest(session, requestType, &variableBindings,
                                &errorStatus, &errorIndex)){
                /* The API is indicating an error.*/
                php_error(E_WARNING,"error on SnmpMgrRequest %d\n", GetLastError());
                break;
                }
            else
                {
                /* The API succeeded, errors may be indicated from the remote
                   agent.
                   Test for end of subtree or end of MIB. */
                if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
                    SnmpUtilOidNCmp(&variableBindings.list[0].name,
                                    &root, root.idLength))
                    {
                    PUTS("End of MIB subtree.\n\n");
                    break;
                    }

                /* Test for general error conditions or sucesss. */
                if (errorStatus > 0){
                    php_error(E_ERROR,"Error: errorStatus=%d, errorIndex=%d \n",
                           errorStatus, errorIndex);
                    break;
                    }
                else
                    {
                    /* Display resulting variable binding for this iteration. */
                    char *str = NULL;

                    SnmpMgrOidToStr(&variableBindings.list[0].name, &str);
                    php_printf("Variable = %s\n", str);
                    if (str) SNMP_free(str);

                    php_printf("Value    = ");
                    SnmpUtilPrintAsnAny(&variableBindings.list[0].value);

                    php_printf("\n");
                    }
                } /* end if () */
            /* Prepare for the next iteration.  Make sure returned oid is
               preserved and the returned value is freed.
			*/
            SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);
            SnmpUtilVarBindFree(&variableBindings.list[0]);
            SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
            variableBindings.list[0].value.asnType = ASN_NULL;
            SnmpUtilOidFree(&tempOid);
            } /* end while() */
        /* Free the variable bindings that have been allocated.*/
        SnmpUtilVarBindListFree(&variableBindings);
        SnmpUtilOidFree(&root);
	} /* end if (operation) */


	/* Close SNMP session with the remote agent.*/
	if (!SnmpMgrClose(session)){
		php_error(E_WARNING,"error on SnmpMgrClose %d\n", GetLastError());
	}
}