News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Win SNMP API

Started by SideSwipe, February 07, 2006, 06:10:42 AM

Previous topic - Next topic

SideSwipe

Hello:

I am trying to write a small app in asm that uses the winsnmpapi to retrieve uptime or something from a server.
I am using http://msdn.microsoft.com/library/default.asp?url=/library/en-us/snmp/snmp/winsnmp_functions.asp for docs.

The docs have a programming task list as follows:

1) Open the WinSNMP application. (a no brainer)
2) Open one or more WinSNMP sessions. (Use SnmpCreateSession)
3) Register to receive traps or notifications. (Use SnmpRegister) I dont need to do this part.
4) Create one or more variable binding lists for incorporation in a PDU. (Use SnmpCreateVbl)
5) Create one or more PDUs for transmission and processing. (Use SnmpCreatePDU)
6) Submit one or more SNMP operation requests. (Use SnmpSendMsg)
7) Retrieve the response to the SNMP operation request. (Use SnmpRecvMsg)

I am stuck on step 4 and 5. I have googled around for source code and found some in c++ and c# but dont have the skills to port it over to asm. Could someone please show me how to create a variable binding list, or perhaps even a code snippet in asm? Once a variable binding list is created, how does this get used in making a PDU? A tutorial or example on sending a snmp get in asm would be ideal.

Below is how far I have gotten on my own.

invoke SnmpStartup,nMajorVersion,nMinorVersion,nLevel,nTranslateMode,nRetransmitMode
.if eax==SNMPAPI_FAILURE
   ;<error occured>
   invoke MessageBox,hWin,ADDR snmp_startup_err,ADDR AppName,MB_OK
   invoke SendMessage,hWin,WM_CLOSE,0,0
.endif

invoke SnmpCreateSession,hWin,WM_SNMP,0,0
.if eax==SNMPAPI_FAILURE
   ;<error occured>
   invoke MessageBox,hWin,ADDR snmp_session_err,ADDR AppName,MB_OK
   invoke SendMessage,hWin,WM_CLOSE,0,0
.endif
mov hSession,eax      ;save session handle

invoke SnmpStrToEntity, hSession, ADDR managerIP
.if eax==SNMPAPI_FAILURE
   ;<error occured>
   invoke MessageBox,hWin,ADDR snmp_strtoentity_err,ADDR AppName,MB_OK
   invoke SendMessage,hWin,WM_CLOSE,0,0
.endif
mov hManagerEntity,eax

invoke SnmpStrToEntity, hSession, ADDR agentIP
.if eax==SNMPAPI_FAILURE
   ;<error occured>
   invoke MessageBox,hWin,ADDR snmp_strtoentity_err,ADDR AppName,MB_OK
   invoke SendMessage,hWin,WM_CLOSE,0,0
.endif
mov hAgentEntity,eax


A C# snmp api example:

      /// <summary>
      /// FUNCTION: Send
      /// PURPOSE : To send a pdu in order to set the MIB values
      /// </summary>
      public bool Send()
      {
         bool Success = false; // init success to failure
         try
         {
            if(VBLInit)
            {

               if(Vbl.Item.Count > 0)
               {
                  SNMPAPI_STATUS Result = new SNMPAPI_STATUS(); // set up a result item

                  // create entities for the source and destination addresses
                  IntPtr Source = SnmpAPI.SnmpStrToEntity(Session,LocalAddr);
                  IntPtr Destin = SnmpAPI.SnmpStrToEntity(Session,RemoteAddr);

                  // create arrays to hold Variable Info
                  WinSnmp.SMIOID[] OID = new SMIOID[Vbl.Item.Count];         // an array of oids
                  WinSnmp.SMIVALUE[] Val = new SMIVALUE[Vbl.Item.Count];      // an array of values
                  WinSnmp.SMIOCTETS[] Oct = new SMIOCTETS[Vbl.Item.Count];   // an array of octets
                  WinSnmp.SMIOCTETS DestOct = new SMIOCTETS();            // the destination octect
                  GCHandle[] PinnedArray = new GCHandle[Vbl.Item.Count];      // an array of pinned memory
                  byte[][] ba = new byte[Vbl.Item.Count][];               // a multi-dimensional byte array
                  IntPtr VbL1 = new IntPtr();                           // pointer to variable bindings list
                  IntPtr Context = new IntPtr();                        // pointer to a context object
                  
                  // start looping through all items in the variable bindings list
                  for(int i=0;i<Vbl.Item.Count;i++)
                  {

                     ba = new byte[((VARIABLE_ITEM)Vbl.Item).Value.Length]; // new byte array

                     // check to see if the user has passed the separator
                     if(Vbl.ParentEntity.Substring(Vbl.ParentEntity.Length-1,1) != "."
                        && ((VARIABLE_ITEM)Vbl.Item).Entity.Substring(0,1) !=".")
                        Result = SnmpAPI.SnmpStrToOid(Vbl.ParentEntity + "." + ((VARIABLE_ITEM)Vbl.Item).Entity,ref OID);
                     else
                        Result = SnmpAPI.SnmpStrToOid(Vbl.ParentEntity + ((VARIABLE_ITEM)Vbl.Item).Entity,ref OID);

                     // check result
                     if (Result == SNMPAPI_STATUS.SNMPAPI_FAILURE)
                        throw new Exception("SNMP OID Creation Failure");

                     // create the octet and value for this variable
                     Oct.size = (uint)((VARIABLE_ITEM)Vbl.Item).Value.Length;         // set the octet size
                     ba = Encoding.ASCII.GetBytes(((VARIABLE_ITEM)Vbl.Item).Value);   // encode string to byte array
                     PinnedArray = GCHandle.Alloc(ba,GCHandleType.Pinned);            // this creates a static memory location
                     Oct.octets = PinnedArray.AddrOfPinnedObject();               // set the octet pointer

                     // now, check what type of variable this is and set the value accordingly
                     switch(((VARIABLE_ITEM)Vbl.Item).Type)
                     {
                        case VARIABLE_TYPE.VARIABLE_TYPE_INT:
                           Val.type = WinSnmp.SNMPAPI_SYNTAX.SNMP_SYNTAX_INT;
                           Val.val.sNumber = int.Parse(((VARIABLE_ITEM)Vbl.Item).Value);
                           break;
                        case VARIABLE_TYPE.VARIABLE_TYPE_INT32:
                           Val.type = WinSnmp.SNMPAPI_SYNTAX.SNMP_SYNTAX_INT32;
                           Val.val.hNumber = long.Parse(((VARIABLE_ITEM)Vbl.Item).Value);
                           break;
                        case VARIABLE_TYPE.VARIABLE_TYPE_OCTECT:
                           Val.type = WinSnmp.SNMPAPI_SYNTAX.SNMP_SYNTAX_OCTETS;
                           Val.val.str = Oct;
                           break;
                     }
         
                     // check to see if this is the first item, or an item to append
                     if(i==0)
                        VbL1 = SnmpAPI.SnmpCreateVbl(Session,ref OID,ref Val);
                     else
                        Result = SnmpAPI.SnmpSetVb(VbL1,0,ref OID,ref Val);


                  }
                  // now, set up the protocol description unit
                  IntPtr Pdu = SnmpAPI.SnmpCreatePdu(Session,(int)WinSnmp.SNMPAPI_PDU.SNMP_PDU_SET,Vbl.RequestID,0,0,VbL1);

                  // set the destination octet (we only need to set the first one, the rest will flow accordingly)
                  DestOct.size = (uint)((VARIABLE_ITEM)Vbl.Item[0]).Value.Length;
                  DestOct.octets = PinnedArray[0].AddrOfPinnedObject();
                  Context = SnmpAPI.SnmpStrToContext(Session,ref DestOct);

                  // set the port to 162
                  Result = SnmpAPI.SnmpSetPort(Destin,162);

                  // now send the messages
                  Result = SnmpAPI.SnmpSendMsg(Session,Source,Destin,Context,Pdu);


                  // SNMPAPI use requires us to handle some garbage collecting ourselves, else suffer memory leakage.

                  // free the context
                  Result = SnmpAPI.SnmpFreeContext(Context);

                  // free the pdu
                  Result = SnmpAPI.SnmpFreePdu(Pdu);

                  // free the variable lists
                  SnmpAPI.SnmpFreeVbl(VbL1);

                  for(int t=0;t<Vbl.Item.Count;t++)
                  {
                     // free the pinned arrays
                     PinnedArray[t].Free();

                     // free the oids
                     SnmpAPI.SnmpFreeDescriptor((int)WinSnmp.SNMPAPI_SYNTAX.SNMP_SYNTAX_OID,ref OID[t]);
                  }

                  // finally, free the entities
                  SnmpAPI.SnmpFreeEntity(Source);
                  SnmpAPI.SnmpFreeEntity(Destin);

                  Success = true;
               }
               else
               {
                  throw new Exception("Variable Binding List Empty.");
               }
            }
            else
            {
               throw new Exception("Variable Binding Does Not Exist.");
            }
         }
         catch(Exception Err)
         {
            ErrMess = Err.Message;
         }
         return Success; // return success flag
      }




"Crashing through life !"