snmp_get

new topic     » topic index » view thread      » older message » newer message

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--

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu