snmp_get
- Posted by 1evan at sbcglobal.net Jul 09, 2003
- 894 views
This is a multi-part message in MIME format. --------------010209030504050002070402 I've been working on this program for a while now. I'm stuck. If anybody wants to take a look at it, I'd be grateful. It has to be run from WinXP, NT, or 2000. It is run from the command line. i.e. exw snmp_get 127.0.0.1 public 0.1.3.6.2.1.1.1.0 It opens the session just fine, then errors on the snmp_get command. I don't know much about snmp. Saw a request for this a while ago, and thought I'd try my hand at it. Know a lot more about it now than I did then, though. -------------------------------------------------- include dll.e include machine.e include msgbox.e include get.e sequence cmd, community, IP, OID cmd = command_line() if length(cmd) != 5 then puts(1,'\n' & "Usage: exw snmp_get IP community OID" & '\n') abort(1) else IP = cmd[3] community = cmd[4] OID = cmd[5] end if procedure not_found(sequence name) puts(1,'\n' & "Couldn't find " & name & '\n') while get_key() != 'n' do end while abort(1) end procedure function link_c_func(atom dll, sequence name, sequence args, atom result) -- dynamically link a C routine as a Euphoria function integer handle handle = define_c_func(dll, name, args, result) if handle = -1 then not_found(name) else return handle end if end function function link_c_proc(atom dll, sequence name, sequence args) -- dynamically link a C routine as a Euphoria function integer handle handle = define_c_proc(dll, name, args) if handle = -1 then not_found(name) else return handle end if end function constant SNMP_PDU_GET = #A0, ASN_OCTETSTRING = #04, ASN_INTEGER32 = #02, ASN_TIMETICKS = #43, ASN_GAUGE32 = #42, ASN_COUNTER32 = #41, ASN_IPADDRESS = #40, ASN_OBJECTIDENTIFIER = #06, ASN_NULL = #05 --define function Euphoria function names to match .dll function names integer GetLastError, FormatMessage integer SnmpUtilMemReAlloc --manager functions integer SnmpMgrClose, SnmpMgrCtl, SnmpMgrGetTrap, SnmpMgrGetTrapEx, SnmpMgrOidToStr,SnmpMgrOpen, SnmpMgrRequest, SnmpMgrStrToOid, SnmpMgrTrapListen procedure link_dll_routines() -- open required .dll's atom MgmtAPI, snmpapi, kernel32 kernel32 = open_dll("kernel32.dll") if kernel32 = NULL then not_found("kernel32.dll") end if snmpapi = open_dll("snmpapi.dll") if snmpapi = NULL then not_found("snmpapi.dll") end if MgmtAPI = open_dll("MgmtAPI.dll") if MgmtAPI = NULL then not_found("MgmtAPI.dll") end if -- get handles to all dll routines that we need GetLastError = link_c_func(kernel32, "GetLastError",{},C_UINT) FormatMessage = link_c_func(kernel32, "FormatMessageA",{C_UINT,C_POINTER,C_UINT,C_UINT,C_POINTER,C_UINT,C_POINTER},C_UINT) SnmpUtilMemReAlloc = link_c_func(snmpapi, "SnmpUtilMemReAlloc",{C_POINTER,C_UINT},C_POINTER) SnmpMgrClose = link_c_func(MgmtAPI, "SnmpMgrClose",{C_POINTER},C_INT) SnmpMgrOpen = link_c_func(MgmtAPI, "SnmpMgrOpen",{C_POINTER,C_POINTER,C_INT,C_INT},C_POINTER) SnmpMgrRequest = link_c_func(MgmtAPI, "SnmpMgrRequest",{C_POINTER,C_UINT,C_POINTER,C_POINTER,C_POINTER},C_UINT) SnmpMgrStrToOid = link_c_func(MgmtAPI, "SnmpMgrStrToOid",{C_POINTER,C_POINTER},C_UINT) end procedure link_dll_routines() atom lpAgentAddress, lpAgentCommunity, session --store the IP address and community name as C-style, 0 terminated strings lpAgentAddress = allocate_string(IP) lpAgentCommunity = allocate_string(community) --initialize communications sockets and data structures, allows communications with the specified SNMP agent session = c_func(SnmpMgrOpen,{lpAgentAddress,lpAgentCommunity,1000,3}) if session = NULL then puts(1,'\n' & "Session could not be opened successfully" & '\n') printf(1,"\nError code: %d\n",c_func(GetLastError,{})) abort(1) else printf(1,"Session opened successfully.\n\n",{}) end if --look up the error code in the system error messages and display the corresponding message procedure ErrorMsg(integer error_num) atom Error_message --address of the returned error message buffer integer i Error_message = allocate(4) i = 0 if not (c_func(FormatMessage,{#1100,NULL,error_num,0,Error_message,30,NULL})) then printf(1,"Couldn't format error message. Error number: %d\n\n",error_num) else puts(1,'\n') while peek(peek4u(Error_message) + i) != NULL do --loop until the end of the string printf(1,"%s",peek(peek4u(Error_message) + i)) i += 1 end while puts(1,'\n') end if while not wait_key() do end while end procedure --close down the session, free up memory, probably not neccessary here, but better safe than sorry procedure Close(integer session) --display any system error messages before closing session integer error_num error_num = c_func(GetLastError,{}) --get error number ErrorMsg(error_num) --call routine to translate error number to error message puts(1,"Closing" & '\n') if not (c_func(SnmpMgrClose,{session})) then puts(1,'\n' & "Couldn't close down session!" & '\n') end if abort(1) end procedure atom vb, objID, errorStatus, errorIndex, pAny2, ret, pOIDstr --allocate memory for needed 'structures' vb = allocate(8) --variable bindings list objID = allocate(8) --AsnObjectIdentifier errorStatus = allocate(4) errorIndex = allocate(4) pAny2 = allocate(4) integer pAny2_asnType, pAny2_asnValue, pAny2_asnValue_length, pAny2_asnValue_type sequence asciiStr -- intialize variable bindings list poke4(vb,NULL) --variable name field is NULL poke4(vb + 4, 0) --number of variable names in list is 0 --get pointer to OID string pOIDstr = allocate_string(OID) -- convert OID string to AsnObjectIdentifier ret = c_func(SnmpMgrStrToOid,{pOIDstr, objID}) if ret = 0 then puts(1,'\n' & "Couldn't convert string OID to internal OID" & '\n') Close(session) end if --add to varible bindings list poke4(vb + 4, 1) --there will now be 1 entry in the variable bindings list poke4(vb,c_func(SnmpUtilMemReAlloc,{vb,16}))--allocate space for new entry if (peek4u(vb) = NULL) then puts(1,'\n' & "Error allocating OID" & '\n') Close(session) end if poke4(peek4u(vb),peek4u(objID)) poke4(peek4u(vb)+4,peek4u(objID+4)) poke4(peek4u(vb)+8,ASN_NULL) if not c_func(SnmpMgrRequest,{session, SNMP_PDU_GET, vb, errorStatus, errorIndex}) then printf(1,"\nError: SnmpMgrRequest could not carry out desired option\n(Error %d -- %s)\n", {peek4u(errorStatus), OID}) Close(session) elsif peek4u(errorStatus) > 0 then puts(1,'\n' & "Error: Error with Agent process" & '\n') Close(session) else pAny2 = peek4u(vb)+8 pAny2_asnType = peek(pAny2) pAny2_asnValue = peek4u(pAny2 + 1) pAny2_asnValue_length = peek4u(pAny2_asnValue) pAny2_asnValue_type = peek4u(pAny2_asnValue + 4) if pAny2_asnType = ASN_OCTETSTRING then if peek4u(pAny2_asnValue + 4) > 15 then for i = 0 to pAny2_asnValue_length - 1 do asciiStr = append(asciiStr,sprintf("%s",pAny2_asnValue_type + i)) end for else for i = 0 to peek4u(pAny2_asnValue) - 1 do asciiStr = append(asciiStr,sprintf("%02x",pAny2_asnValue_type + i)) end for end if elsif pAny2_asnType = ASN_INTEGER32 then asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_TIMETICKS then printf(1,"pAny2_asnValue_type = %d",pAny2_asnValue_type) puts(1,"Hang on, we're going to crash!" & '\n') --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_GAUGE32 then --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_COUNTER32 then --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_IPADDRESS then --asciiStr = sprintf("%d.%d.%d.%d",{peek({pAny2_asnValue + 32,4})}) elsif pAny2_asnType = ASN_OBJECTIDENTIFIER then for i = 0 to peek(pAny2 + 64) - 1 do --asciiStr = append(asciiStr,sprintf(".%d",peek(pAny2 + 96 + i))) end for else printf(1,"pAny2_asnType = %d",pAny2_asnType) end if puts(1,'\n' & asciiStr & '\n') end if while get_key() != 'n' do end while --------------010209030504050002070402 Content-Type: text/plain; name="SNMP_get.exw" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="SNMP_get.exw" include dll.e include machine.e include msgbox.e include get.e with trace sequence cmd, community, IP, OID cmd = command_line() if length(cmd) != 5 then puts(1,'\n' & "Usage: exw snmp_get IP community OID" & '\n') abort(1) else IP = cmd[3] community = cmd[4] OID = cmd[5] end if procedure not_found(sequence name) puts(1,'\n' & "Couldn't find " & name & '\n') while get_key() != 'n' do end while abort(1) end procedure function link_c_func(atom dll, sequence name, sequence args, atom result) -- dynamically link a C routine as a Euphoria function integer handle handle = define_c_func(dll, name, args, result) if handle = -1 then not_found(name) else return handle end if end function function link_c_proc(atom dll, sequence name, sequence args) -- dynamically link a C routine as a Euphoria function integer handle handle = define_c_proc(dll, name, args) if handle = -1 then not_found(name) else return handle end if end function constant SNMP_PDU_GET = #A0, ASN_OCTETSTRING = #04, ASN_INTEGER32 = #02, ASN_TIMETICKS = #43, ASN_GAUGE32 = #42, ASN_COUNTER32 = #41, ASN_IPADDRESS = #40, ASN_OBJECTIDENTIFIER = #06, ASN_NULL = #05 --define function Euphoria function names to match .dll function names integer GetLastError, FormatMessage integer SnmpUtilMemReAlloc --manager functions integer SnmpMgrClose, SnmpMgrCtl, SnmpMgrGetTrap, SnmpMgrGetTrapEx, SnmpMgrOidToStr,SnmpMgrOpen, SnmpMgrRequest, SnmpMgrStrToOid, SnmpMgrTrapListen procedure link_dll_routines() -- open required .dll's atom MgmtAPI, snmpapi, kernel32 kernel32 = open_dll("kernel32.dll") if kernel32 = NULL then not_found("kernel32.dll") end if snmpapi = open_dll("snmpapi.dll") if snmpapi = NULL then not_found("snmpapi.dll") end if MgmtAPI = open_dll("MgmtAPI.dll") if MgmtAPI = NULL then not_found("MgmtAPI.dll") end if -- get handles to all dll routines that we need GetLastError = link_c_func(kernel32, "GetLastError",{},C_UINT) FormatMessage = link_c_func(kernel32, "FormatMessageA",{C_UINT,C_POINTER,C_UINT,C_UINT,C_POINTER,C_UINT,C_POINTER},C_UINT) SnmpUtilMemReAlloc = link_c_func(snmpapi, "SnmpUtilMemReAlloc",{C_POINTER,C_UINT},C_POINTER) SnmpMgrClose = link_c_func(MgmtAPI, "SnmpMgrClose",{C_POINTER},C_INT) SnmpMgrOpen = link_c_func(MgmtAPI, "SnmpMgrOpen",{C_POINTER,C_POINTER,C_INT,C_INT},C_POINTER) SnmpMgrRequest = link_c_func(MgmtAPI, "SnmpMgrRequest",{C_POINTER,C_UINT,C_POINTER,C_POINTER,C_POINTER},C_UINT) SnmpMgrStrToOid = link_c_func(MgmtAPI, "SnmpMgrStrToOid",{C_POINTER,C_POINTER},C_UINT) end procedure link_dll_routines() atom lpAgentAddress, lpAgentCommunity, session --store the IP address and community name as C-style, 0 terminated strings lpAgentAddress = allocate_string(IP) lpAgentCommunity = allocate_string(community) --initialize communications sockets and data structures, allows communications with the specified SNMP agent session = c_func(SnmpMgrOpen,{lpAgentAddress,lpAgentCommunity,1000,3}) if session = NULL then puts(1,'\n' & "Session could not be opened successfully" & '\n') printf(1,"\nError code: %d\n",c_func(GetLastError,{})) abort(1) else printf(1,"Session opened successfully.\n\n",{}) end if --look up the error code in the system error messages and display the corresponding message procedure ErrorMsg(integer error_num) atom Error_message --address of the returned error message buffer integer i Error_message = allocate(4) i = 0 if not (c_func(FormatMessage,{#1100,NULL,error_num,0,Error_message,30,NULL})) then printf(1,"Couldn't format error message. Error number: %d\n\n",error_num) else puts(1,'\n') while peek(peek4u(Error_message) + i) != NULL do --loop until the end of the string printf(1,"%s",peek(peek4u(Error_message) + i)) i += 1 end while puts(1,'\n') end if while not wait_key() do end while end procedure --close down the session, free up memory, probably not neccessary here, but better safe than sorry procedure Close(integer session) --display any system error messages before closing session integer error_num error_num = c_func(GetLastError,{}) --get error number ErrorMsg(error_num) --call routine to translate error number to error message puts(1,"Closing" & '\n') if not (c_func(SnmpMgrClose,{session})) then puts(1,'\n' & "Couldn't close down session!" & '\n') end if abort(1) end procedure atom vb, objID, errorStatus, errorIndex, pAny2, ret, pOIDstr --allocate memory for needed 'structures' vb = allocate(8) --variable bindings list objID = allocate(8) --AsnObjectIdentifier errorStatus = allocate(4) errorIndex = allocate(4) pAny2 = allocate(4) integer pAny2_asnType, pAny2_asnValue, pAny2_asnValue_length, pAny2_asnValue_type sequence asciiStr -- intialize variable bindings list poke4(vb,NULL) --variable name field is NULL poke4(vb + 4, 0) --number of variable names in list is 0 --get pointer to OID string pOIDstr = allocate_string(OID) -- convert OID string to AsnObjectIdentifier ret = c_func(SnmpMgrStrToOid,{pOIDstr, objID}) if ret = 0 then puts(1,'\n' & "Couldn't convert string OID to internal OID" & '\n') Close(session) end if --add to varible bindings list poke4(vb + 4, 1) --there will now be 1 entry in the variable bindings list poke4(vb,c_func(SnmpUtilMemReAlloc,{vb,16}))--allocate space for new entry if (peek4u(vb) = NULL) then puts(1,'\n' & "Error allocating OID" & '\n') Close(session) end if poke4(peek4u(vb),peek4u(objID)) poke4(peek4u(vb)+4,peek4u(objID+4)) poke4(peek4u(vb)+8,ASN_NULL) if not c_func(SnmpMgrRequest,{session, SNMP_PDU_GET, vb, errorStatus, errorIndex}) then printf(1,"\nError: SnmpMgrRequest could not carry out desired option\n(Error %d -- %s)\n", {peek4u(errorStatus), OID}) Close(session) elsif peek4u(errorStatus) > 0 then puts(1,'\n' & "Error: Error with Agent process" & '\n') Close(session) else pAny2 = peek4u(vb)+8 pAny2_asnType = peek(pAny2) pAny2_asnValue = peek4u(pAny2 + 1) pAny2_asnValue_length = peek4u(pAny2_asnValue) pAny2_asnValue_type = peek4u(pAny2_asnValue + 4) if pAny2_asnType = ASN_OCTETSTRING then if peek4u(pAny2_asnValue + 4) > 15 then for i = 0 to pAny2_asnValue_length - 1 do asciiStr = append(asciiStr,sprintf("%s",pAny2_asnValue_type + i)) end for else for i = 0 to peek4u(pAny2_asnValue) - 1 do asciiStr = append(asciiStr,sprintf("%02x",pAny2_asnValue_type + i)) end for end if elsif pAny2_asnType = ASN_INTEGER32 then asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_TIMETICKS then printf(1,"pAny2_asnValue_type = %d",pAny2_asnValue_type) puts(1,"Hang on, we're going to crash!" & '\n') --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_GAUGE32 then --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_COUNTER32 then --asciiStr = sprintf("%d",pAny2_asnValue_type) elsif pAny2_asnType = ASN_IPADDRESS then --asciiStr = sprintf("%d.%d.%d.%d",{peek({pAny2_asnValue + 32,4})}) elsif pAny2_asnType = ASN_OBJECTIDENTIFIER then for i = 0 to peek(pAny2 + 64) - 1 do --asciiStr = append(asciiStr,sprintf(".%d",peek(pAny2 + 96 + i))) end for else printf(1,"pAny2_asnType = %d",pAny2_asnType) end if puts(1,'\n' & asciiStr & '\n') end if while get_key() != 'n' do end while --------------010209030504050002070402--