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
}