Jump to content

SNMP_UDF for SNMPv1 and SNMPv2c


enaiman
 Share

Recommended Posts

  • 2 months later...

Hello Enaiman, first of all, thanks for the UDF and congratulations for the work.

I´m trying to get a value from a network device and I managed to get what I want in the $result array, but when I want to pass the array value to a variable I get the error:

Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

Here is the code in case you can help me:

Func _StartListener()

If $Start = 1 Then

$i = 0

While (1)

$srcv = UDPRecv($Socket, 2048)

Local $value

If ($srcv <> "") Then

$result = _ShowSNMPReceived($srcv)

_ArrayDisplay($result)

$value=$result[1] ;<=====

ExitLoop

EndIf

sleep(100)

WEnd

EndIf

EndFunc

Thanks a lot.

Link to comment
Share on other sites

  • 1 month later...

Seek help !

Using examples, $SNMP_OID = "1.3.6.1.2.1.4.22.1.2"

. iso.org.dod.internet.mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress

0x308205800201010409796E63636272656164A282056E020101020100020100308205613019060F2B06010201041601021

E4610817E2904060025847C5EC03019060F2B06010201041601021F461081792904060025847C60403019060F2B0601020

10416010221461022810704060019D19E60903019060F2B06010201041601022146102281080406008087EECEC83019060

F2B06010201041601022146102281110406000C6EE451DE3019060F2B06010201041601022146102281190406000B00168

9653019060F2B060102010416010221461034810104060080874E43523019060F2B06010201041601022146103481160406

003138402D463019060F2B060102010416010221461034811C0406000B000630603019060F2B0601020104160102214610

34811D0406000B000748F43019060F2B060102010416010221461034811E0406000B000743093019060F2B060102010416

01022146103481200406000B001A87CE3019060F2B06010201041601022146103481210406000B001757D33019060F2B06

010201041601022146103481240406000B001ADDEE3019060F2B06010201041601022146103481520406000B001A87C130

19060F2B06010201041601022146103481530406000B001A87BC3019060F2B06010201041601022146103481550406001AA

920037D3019060F2B06010201041601022146103481560406001AA950EF453019060F2B0601020104160102214610348159

0406000B001A878D3019060F2B060102010416010221461034815A040600E0B40326DC3019060F2B060102010416010221461034815B04064487FCC32C213019060F2B060102010416010221461034815C040600D0F81F0DB03019060F2B060102010416010221461034815E040620CF30B9CCE2301A06102B0601020104160102224610813B8102040600226431E1F8301A06102B0601020104160102224610813B810404066C626D7C7980301A06102B0601020104160102224610813B810604060017A4F8FAD8301A06102B0601020104160102224610813B81070406004551E36CF8301A06102B0601020104160102224610813B81080406000B001A87E0301A06102B0601020104160102224610813B810E0406000BCD072CD8301A06102B0601020104160102224610813B811104066C626D0B686B301A06102B0601020104160102224610813B811204066C626D0B689C301A06102B0601020104160102224610813B811504060017A4F922D1301A06102B0601020104160102224610813B812004060019DB2FF12D301A06102B0601020104160102224610813B8121040618A9052A3092301A06102B0601020104160102224610813B812604060017A4F8F88C301A06102B0601020104160102224610813B812A04064437E639A634301A06102B0601020104160102224610813B813D04060017A4F8FC57301A06102B0601020104160102224610813B814804060019DB30FE13301A06102B0601020104160102224610813B81490406000FFE1E486B301A06102B0601020104160102224610813B814B04060019BB43CD20301A06102B0601020104160102224610813B814C0406000BCDB98946301A06102B0601020104160102224610813B814D04060019DB2FF076301A06102B0601020104160102224610813B815C0406D4856498FAB3301A06102B0601020104160102224610813B816504064437E620A47A301A06102B0601020104160102224610813B816E04060019DB30741C301A06102B0601020104160102224610813B81700406080037867756301A06102B0601020104160102224610813B817104066C626D7B003B301A06102B0601020104160102224610813B8172040600237D4A3CD9301A06102B0601020104160102224610813B8179040600E00000509D301A06102B0601020104160102224610813B817B0406E839354FC7E6

Back to MAC address, the result is garbled

Edited by tvro
Link to comment
Share on other sites

  • 1 month later...

@tvro

This is what you get back from the device you are interogating so you'll need to do something about that.

The type of data returned is "04" which is interpreted as text and the "garbled text" is what the data is translated to from Hex to ASCII.

The very last OID returned is in this section at the end of the output:

04 06 E839354FC7E6
 

04 = type of data returned = String

06 = length of data sequence

E839354FC7E6 = data returned

In this case, the data returned is a MAC address and it should be: E8:39:35:4F:C7:E6
 

In this case, what you need to do is: get the "garbled" text returned and transform it back in hex code (each character will have a Hex value) then split the string in groups of two by ":" and you have your MAC addresses.

@jcpetu

The array returned is multi dimensional and you are trying to use an uni-dimensional array.

You need to use $result [1][1] or whatever you need - look closely at the _ArrayDisplay result.
 

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

@ enaiman

Thank you for your guidance, I have been successfully applied to the function _ExtractData

Add:
If StringLen ($ tmpOUT) = 12 Then Return StringRegExpReplace (BinaryToString ($ tmpOUT), '( S {2}) ( S {2}) ( S {2}) ( S {2}) ( S {2}) ( S {2}) ',' $ 1: $ 2: $ 3: $ 4: $ 5: $ 6 ')

Only for the MAC address

Link to comment
Share on other sites

  • 1 month later...

Hi enaiman,

in version 1.6.2 you added the feature that the script exits on an occured error.

Yet in the function _ShowSNMPReceived you are using a Return SetError(1) after throwing the error.

Maybe this is by design in version 1.7.4. ;-)

I would prefer that the pachet yout be output to any place set by user and that the _ThrowError function did not exit the whole script.

Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]
Link to comment
Share on other sites

  • 4 weeks later...

@hannes08:

hi,

It may be a bit late to answer, but in my opinion what you can try is to comment out the last "Exit" command of the UDF ( line : 465 ). This will normally resume the script.

Concerning the packet, it will be stored in the clipboard. so a simple "clipget" call should let you retrieve it.

best regards.

@enaiman:

that's truly something odd in the code: _ThowError is only used once in the UDF and it is followed by a "return seterror(1)".

Is that not some remains of a debug session ?

Link to comment
Share on other sites

  • 4 months later...

Hi Einaman  and Nobur,

first of all thx for your work.

Then I got a little problem but for sure it's because of my noobness in Autoit.

I'm trying to get some oid values on a Cisco Switch.

A start I just tried this:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.1
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here


#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <SNMPWALK.au3>



;~ $snmp = _SNMPBuildPacket("1.3.6.1.4.1.9.5.1.9.3.1.3.1.1","public", 1, 1, "A1")

$walk = _SnmpWalk("10.33.0.253","1.3.6.1.4.1.9.5.1.9.3.1.3.1.1","public",1,161)
$array = _ArrayDisplay($walk,'SNMP')

So of course I got an SNMPWALK.au3 file in the includes folder as a SNMP-UDF.au3 file (Renamed also in nobur SNMPWALK.au3)

The upper script just return a table with a 0 for the first col in the fisrt row, which basically means : "No Data".

I'm sure of the OID i'm using as I can get the searched data with snmpwalk.exe.

Many thx by advance for your help.

regards

Processor

Link to comment
Share on other sites

  • 2 months later...

Hi Processor!

sorry for the late answer but i don't come here so often now.
The problem you face is not really a problem.
I did the test on my side with a cisco switch.

You can't walk thru a single value like 1.3.6.1.4.1.9.5.1.9.3.1.3.1.1
The snmpwalk command handle this case by executing a simple "get" query instead of a "getnext"
 
If you want handle this as the snmpwalk command does, you will have to :
1/ edit the snmp_udf.au3 to remove following lines

If $_sErr_ <> "00" Then
        _ThrowError($_sErr_, $_sPacketRecv_)
        Return SetError(1)
    EndIf

2/ use this modified snmpwalk function

#include-once
#include 'SNMP_UDF.au3'

Func _SnmpWalk($S_srvIP,$S_OID,$S_COM,$S_Ver=2,$S_Port=161)
;~  Init variables
Dim $S_ReqID = Random(10000,20000,1)
Dim $S_socket,$SNMP_Command,$OIDwalk,$OIDwalk_len,$rslt
Dim $resultTab[1][2]
$resultTab[0][0]=0
;~  open Udp socket to target
UDPStartUp()
$S_socket = UDPopen($S_srvIP, $S_Port)
$OIDwalk=$S_OID
$OIDwalk_len=StringLen ( $OIDwalk )

; try to query  as a single value if the query oid is a leaf
$SNMP_Command = _SNMPBuildPacket($S_OID, $S_COM,$S_Ver, $S_ReqID, "A0")
UDPSend($S_socket, $SNMP_Command)
$rslt= _StartListener($S_socket)
;~ Timeout ?
if $rslt=-1 Then
    $resultab=-1
ElseIf $rslt[0][1]="02" Then ;not a leaf start walk
    ;~  Cycle through Child OID's
    While (StringLeft($S_OID,$OIDwalk_len)=$OIDwalk)
      $SNMP_Command = _SNMPBuildPacket($S_OID, $S_COM,$S_Ver, $S_ReqID, "A1")
      UDPSend($S_socket, $SNMP_Command)
      $rslt= _StartListener($S_socket)
    ;~   if answer didn't come before timeout then exit and return -1
      if $rslt=-1 and @error=-1 Then
       $resultab=-1
       ExitLoop
      EndIf
      if StringLeft($rslt [1][0],$OIDwalk_len)<>$OIDwalk Then ExitLoop
      $resultTab[0][0] += 1
      ReDim $resultTab[$resultTab[0][0]+1][2]
    ;~   $resultTab[$resultTab[0][0]][0] = StringRight($rslt[1][0],StringLen($rslt[1][0]) - StringInStr($rslt[1][0], ".", 2, -2) + 1)
      $resultTab[$resultTab[0][0]][0] = $rslt[1][0]
      $resultTab[$resultTab[0][0]][1]=$rslt[1][1]
      $S_OID = $rslt [1][0]
      $S_ReqID+=1
    WEnd
Else        ; should be a leaf so get the value
    $resultTab[0][0] += 1
    ReDim $resultTab[$resultTab[0][0]+1][2]
    $resultTab[$resultTab[0][0]][0] = $rslt[1][0]
    $resultTab[$resultTab[0][0]][1]=$rslt[1][1]
EndIf

;~  close connection and return results
UDPCloseSocket($S_socket)
    UDPShutdown()
Return $resultTab
EndFunc

Func _StartListener($sock,$timeOut=500)
dim $sleepDelay=30 ; millisecond
Dim $TOCycles=$timeOut/$sleepDelay
$i = 0
While ($i<=$TOCycles)
  $srcv = UDPRecv($sock, 2048)
  If ($srcv <> "") Then
   $result = _ShowSNMPReceived ($srcv)
;~    ConsoleWrite($result)
    Return $result
   Exit
  EndIf
  Sleep(30)
  $i+=1
WEnd
;~  fallback condition on timeout
return -1
EndFunc

Be aware that this disable the error message boxes so you have to handle them by yourself in your code
(see the end of snmp_udf.au3 for list of error codes)
 
 
regards

Edited by nobur
Link to comment
Share on other sites

  • 4 months later...

some CleanUp

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7
#Tidy_Parameters=/reel
#include-once
#include <String.au3>
#include <Array.au3>
;-----------------------------------------------------
;Credit for idea of this UDF and alot of work on it:    @ptrex
;Credit for fixing the version 1.7.3:   @nobur
;version 1.7.3-nobur - (12.09.2012)
;OID Arrays are no longer supported: they didn't add anything to UDF's value and were only complicating the scripts
;-----------------------------------------------------
Global Const $__SNMP_DATA_INT = "02"
Global Const $__SNMP_DATA_STR = "04"
Global Const $__SNMP_DATA_NULL = "05"
Global Const $__SNMP_DATA_OID = "06"
Global Const $__SNMP_DATA_SEQ = "30"
Global Const $__SNMP_DATA_IP = "40"
Global Const $__SNMP_DATA_COUNTER = "41"
Global Const $__SNMP_DATA_GAUGE = "42"
Global Const $__SNMP_DATA_TIME = "43"
Global Const $__SNMP_DATA_COUNTER64 = "46"

Global $__SNMP_Received[1500][3]
Global $__VarBindContent[1000]
Global $__SNMP_Util[1000][3]

#Region ~~~~~~~~~~~~~~~~~~~~ BUILD SNMP Packet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;===============================================================================
; Description:      Build SNMP Message
; Syntax:          _SNMP_BuildPacket($snmpOID, $snmpCOMM, $snmpVER, $snmpReqID, $PDUType = "A1")
; Parameter(s):     $snmpOID - Object ID (OID) ex: "1.3.6.1.2.1.1.1"
;                   $snmpCOMM - Community String -> the default values are "public" for read-only and "private" for read-write
;                   $snmpVER - SNMP Version (3 versions available, 1, 2 and 3 - this UDF handles only SNMP v1 and v2c)
;                       1 = SNMP v1
;                       2 = SNMP v2c
;                       3 = SNMP v3 -> NOT WORKING
;                   $snmpReqID - Request ID - an Integer that identifies a particular SNMP request.
;                   $PDUType - PDU type ("A0"= GetRequest, "A1"= GetNext, "A2"= GetResponse, "A3"= SetRequest, "A5"= Get Bulk))
;                   $GetBulk - (hex) how many OIDs to return (50 MAXIMUM recommended) - if you request too many OIDs you will get an error.
;                   $dataTYPE - data TYPE to be written     (for SetRequest) - refer to "const" values at the top
;                   $dataVALUE - data VALUE to be written   (for SetRequest)
; Requirement(s):   Must be used from withing this UDF (calls other functions)
; Return Value(s):  On Success - Returns a hex string which is to be send
; Error Code:       1 = SNMP version error (GetBulk request used with SNMP v1)
;                   2 = wrong data type for SetRequest
;                   3 = $snmpOID is an array (arrays are no longer supported)
; Author(s):        enaiman <naimane at yahoo dot com>
; Note(s):          None
;===============================================================================
Func _SNMP_BuildPacket($snmpOID, $snmpCOMM = "public", $snmpVER = 1, $snmpReqID = 1, $PDUType = "A1", $GetBulk = "32", $dataTYPE = "05", $dataVALUE = "00")

;~~~~~~~~~~~~~~~~~~~~~~~~~~~ building the packet backwards ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _SNMP_Init() ;resets global variables

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If IsArray($snmpOID) Then
        MsgBox(16, "OID Array", "OID Arrays are no longer supported.")
        Return SetError(3)

    EndIf
    Local $_SNMP_Req_Varbind, $_SNMP_Req_Message, $_SNMP_Req_PDU
    Switch $snmpVER
        Case 1, 2
            $_SNMP_Req_Varbind = _SNMP_Build_Varbind($snmpOID, $dataTYPE, $dataVALUE)
            If @error Then
                MsgBox(16, "Unknown Data Type", "Unknown Data Type: " & $dataTYPE)
                Return SetError(2)

            EndIf
            If $PDUType = "A5" And $snmpVER = 1 Then
                MsgBox(16, "Wrong SNMP Version", "GetBulk request cannot be used with SNMP v1.")
                Return SetError(1)

            EndIf
            $_SNMP_Req_PDU = _SNMP_Build_PDU($snmpReqID, $PDUType, $GetBulk, $_SNMP_Req_Varbind)
            $_SNMP_Req_Message = _SNMP_Build_Message($snmpVER, $snmpCOMM, $_SNMP_Req_PDU)
            _SNMP_WriteArrayValues($__SNMP_Received, 1, "SNMP Command", $_SNMP_Req_Message)
            Return $_SNMP_Req_Message

        Case 3
            MsgBox(16, "SNMP v3 Not Supported", "SNMP v3 is not supported yet.")
            Return SetError(1)

        Case Else
            MsgBox(16, "Wrong SNMP Version", "Unknown SNMP Version: " & $snmpVER)
            Return SetError(1)

    EndSwitch
EndFunc   ;==>_SNMP_BuildPacket
#EndRegion ~~~~~~~~~~~~~~~~~~~~ BUILD SNMP Packet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ EXTRACT SNMP Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Returned Data in is 2 Arrays
;$__SNMP_Received = Contains a more detailed range of data (educational purpose)
;   << NEW >> - now $__SNMP_Received has an extra row, showing raw data for each PDU (delimited string)
;$__SNMP_Util       = Util information received:
;       $__SNMP_Util[0][0] = "Error Code"
;       $__SNMP_Util[0][1] = error value
;       $__SNMP_Util[1][0] = OID
;       $__SNMP_Util[1][1] = Value read from OID
;   If more that 1x OID were requested then the next results will be added
;       $__SNMP_Util[2][0] = OID
;       $__SNMP_Util[2][1] = Value read from OID
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SNMP_ShowReceived($rcvDATA)
    Global $__SNMP_Util[1000][3]
    Local $_sPacketRecv_ = $rcvDATA
    Local $_PDUcontent = ""
    Local $_ExtractedDATA
    Local $_IsError = 0
    #forceref $_PDUcontent, $_ExtractedDATA, $_IsError
    Local $_PDU_content = ""
    Local $_delimSTR_ = ""
    _SNMP_WriteArrayValues($__SNMP_Received, 1, "SNMP Answer", $rcvDATA)
    $rcvDATA = StringTrimLeft($rcvDATA, 4) ;strip 0x30
    Local $_l_pl = _SNMP_GetPacLen(StringLeft($rcvDATA, 6))
    Local $_pacLen_ = StringLeft($rcvDATA, $_l_pl)
    $rcvDATA = StringTrimLeft($rcvDATA, $_l_pl) ;strip packet length
    _SNMP_WriteArrayValues($__SNMP_Received, 2, "(Total) PDU Length", $_pacLen_)

    ;------------- SNMP Version Block -------------------------------------------------
    _SNMP_WriteArrayValues($__SNMP_Received, 3, "SNMP Version Block", StringLeft($rcvDATA, 6))
    $rcvDATA = StringTrimLeft($rcvDATA, 4) ;strip 0201 from SNMP ver block
    Local $_SNMP_Version = StringLeft($rcvDATA, 2) + 1 ;SNMP Version
    #forceref $_SNMP_Version
    $rcvDATA = StringTrimLeft($rcvDATA, 2) ;strip SNMP Version

    ;------------- Community String ---------------------------------------------------
    $rcvDATA = StringTrimLeft($rcvDATA, 2) ;strip 04 from community block
    Local $_commLen_ = Dec(StringLeft($rcvDATA, 2)) * 2 ;Length of community string
    $rcvDATA = StringTrimLeft($rcvDATA, 2) ;strip community length
    Local $_commHex_ = StringLeft($rcvDATA, $_commLen_) ;community string (hex)
    Local $_commTex_ = _HexToString($_commHex_)
    $rcvDATA = StringTrimLeft($rcvDATA, $_commLen_)
    _SNMP_WriteArrayValues($__SNMP_Received, 4, "Community String", $_commTex_)

    ;------------- PDU Type -----------------------------------------------------------
    Local $_pduT_ = StringLeft($rcvDATA, 2)
    _SNMP_WriteArrayValues($__SNMP_Received, 5, "PDU Type", $_pduT_)
    $rcvDATA = StringTrimLeft($rcvDATA, 2)
    $rcvDATA = _SNMP_StripPacket($rcvDATA)

    ;------------- Request ID ---------------------------------------------------------
    $rcvDATA = _SNMP_StripBlocks($rcvDATA, 6, "Request ID Block")

    ;------------- Error Block --------------------------------------------------------
    Local $_sErr_ = StringMid($rcvDATA, 5, 2)
    If $_sErr_ <> "00" Then
        _SNMP_ThrowError($_sErr_, $_sPacketRecv_)
        Return SetError(1)

    EndIf
    _SNMP_WriteArrayValues($__SNMP_Util, 0, "SNMP Error Value:", $_sErr_)
    $rcvDATA = _SNMP_StripBlocks($rcvDATA, 7, "Error Block")

    ;------------- Error Index --------------------------------------------------------
    $rcvDATA = _SNMP_StripBlocks($rcvDATA, 8, "Error Index Block")

    ;------------- PDU Total Len ------------------------------------------------------
    $rcvDATA = StringTrimLeft($rcvDATA, 2)
    $_l_pl = _SNMP_GetPacLen(StringLeft($rcvDATA, 6))
    Local $_pacTotLen_ = StringLeft($rcvDATA, $_l_pl)
    #forceref $_pacTotLen_
    $rcvDATA = StringTrimLeft($rcvDATA, $_l_pl) ;strip packet length

    ;------------- PDU Data -----------------------------------------------------------
    Local $_snmpR_idx = 9, $_snmpA_idx = 1
    Do
        $rcvDATA = StringTrimLeft($rcvDATA, 2) ;cut "30" (data type: SEQ)
        $_l_pl = _SNMP_GetPacLen(StringLeft($rcvDATA, 6)) ;length of Data PDU
        $_pacLen_ = StringLeft($rcvDATA, $_l_pl)
        $rcvDATA = StringTrimLeft($rcvDATA, $_l_pl) ;cut length
        $_PDU_content = StringLeft($rcvDATA, Dec($_pacLen_) * 2) ;get what is left from PDU
        $rcvDATA = StringTrimLeft($rcvDATA, Dec($_pacLen_) * 2) ;remove that from message
        $_delimSTR_ = "30|" & $_pacLen_ & "|" ;build delimited string
        If StringLeft($_PDU_content, 2) = "06" Then
            $_delimSTR_ &= "06|"
            $_PDU_content = StringTrimLeft($_PDU_content, 2) ;cut "06" (data type: OID)
            $_l_pl = _SNMP_GetPacLen(StringLeft($_PDU_content, 6)) ;Length of OID sequence
            $_pacLen_ = StringLeft($_PDU_content, $_l_pl)
            $_PDU_content = StringTrimLeft($_PDU_content, $_l_pl) ;cut length
            Local $_OID_val = StringLeft($_PDU_content, Dec($_pacLen_) * 2) ;OID (hex)
            $_delimSTR_ &= $_pacLen_ & "|" & $_OID_val & "|"
            Local $_SNMP_Decoded_OID = _SNMP_TranslateOID($_OID_val, "2d") ;OID (dec)
            $_PDU_content = StringTrimLeft($_PDU_content, Dec($_pacLen_) * 2)
            Local $_data_type = StringLeft($_PDU_content, 2) ;returned data type
            $_PDU_content = StringTrimLeft($_PDU_content, 2)
            If StringLen($_PDU_content) >= 6 Then
                $_l_pl = _SNMP_GetPacLen(StringLeft($_PDU_content, 6)) ;Length of data sequence
            Else
                $_l_pl = _SNMP_GetPacLen(StringLeft($_PDU_content, 4)) ;Length of data sequence
            EndIf
            Local $_raw_data = StringTrimLeft($_PDU_content, $_l_pl)
            Local $_RealData = _SNMP_ExtractData($_data_type, $_raw_data)
            _SNMP_WriteArrayValues($__SNMP_Received, $_snmpR_idx, $_SNMP_Decoded_OID, $_RealData)
            $_snmpR_idx += 1
            $_delimSTR_ &= $_data_type & "|" & StringLeft($_PDU_content, $_l_pl) & "|" & $_raw_data
            _SNMP_WriteArrayValues($__SNMP_Received, $_snmpR_idx, "Raw PDU (delimited string)", $_delimSTR_)
            $_snmpR_idx += 1
            _SNMP_WriteArrayValues($__SNMP_Util, $_snmpA_idx, $_SNMP_Decoded_OID, $_RealData)
            $_snmpA_idx += 1
            $_delimSTR_ = ""
        Else
            Return SetError(2) ;bad SNMP Packet

        EndIf
    Until Int(StringLen($rcvDATA)) = 0

    ReDim $__SNMP_Received[$_snmpR_idx][3]
    ReDim $__SNMP_Util[$_snmpA_idx][3]
    Return $__SNMP_Util
EndFunc   ;==>_SNMP_ShowReceived
#EndRegion ~~~~~~~~~~~~~~~~~~~~ EXTRACT SNMP Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ Add Packet Layers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Func _SNMP_Build_Varbind($p_OID, $p_dTYPE, $p_dVALUE)
    Local $_result_
    Local $oidarr
    Switch $p_dTYPE
        Case $__SNMP_DATA_INT, $__SNMP_DATA_COUNTER, $__SNMP_DATA_GAUGE, $__SNMP_DATA_TIME
            $p_dVALUE = Hex($p_dVALUE, 8)
            For $_j = 1 To 3
                If StringLeft($p_dVALUE, 2) = "00" Then
                    $p_dVALUE = StringTrimLeft($p_dVALUE, 2)
                EndIf
            Next
        Case $__SNMP_DATA_STR ;STR
            $p_dVALUE = _StringToHex($p_dVALUE)
        Case $__SNMP_DATA_NULL ;NULL
            $p_dVALUE = "00"
        Case $__SNMP_DATA_OID ;OID
            $p_dVALUE = _SNMP_TranslateOID($p_dVALUE, "2h")
        Case $__SNMP_DATA_IP ;IP
            $p_dVALUE = _SNMP_EncodeIP($p_dVALUE)
        Case Else
            Return SetError(1)

    EndSwitch

    Local $_sl_ = Int(StringLen($p_dVALUE) / 2)
    Local $_p_dLen = Hex($_sl_, 2)
    If Number($p_dTYPE) = 05 Then
        $_result_ = $p_dTYPE & "00" ;if null send null data type and  null data value
    Else
        $_result_ = $p_dTYPE & $_p_dLen & $p_dVALUE ;if not null, send data type, data lenght and data value
    EndIf
    $oidarr = _SNMP_TranslateOID($p_OID, "2h")
    $_result_ = $oidarr & $_result_
    $_result_ = Hex(Int(StringLen($_result_) / 2), 2) & $_result_
    $_result_ = $__SNMP_DATA_SEQ & $_result_
    $_result_ = Hex(Int(StringLen($_result_) / 2), 2) & $_result_
    $_result_ = $__SNMP_DATA_SEQ & $_result_
    Return $_result_
EndFunc   ;==>_SNMP_Build_Varbind

Func _SNMP_Build_PDU($p_ReqID, $p_PDUType, $p_bulk, $p_varbind)
    Local $_result_
    $_result_ = $p_varbind
    If $p_PDUType = "A5" Then ;error Index
        $_result_ = "0201" & $p_bulk & $_result_
    Else
        $_result_ = "020100" & $_result_
    EndIf
    $_result_ = "020100" & $_result_ ;error
    $_result_ = "020200" & Hex($p_ReqID, 2) & $_result_ ;request ID
    $_result_ = Hex(Int(StringLen($_result_) / 2), 2) & $_result_
    $_result_ = $p_PDUType & $_result_
    Return $_result_
EndFunc   ;==>_SNMP_Build_PDU

Func _SNMP_Build_Message($p_VER, $p_COMM, $p_PDU)
    Local $_result_
    $_result_ = $p_PDU
    $_result_ = _SNMP_Build_COM($p_COMM) & $_result_
    $_result_ = "0201" & Hex($p_VER - 1, 2) & $_result_
    $_result_ = Hex(Int(StringLen($_result_) / 2), 2) & $_result_
    $_result_ = "0x" & $__SNMP_DATA_SEQ & $_result_
    Return $_result_
EndFunc   ;==>_SNMP_Build_Message

Func _SNMP_TranslateOID($input, $dir)
    Local $l_OID = ""
    Switch $dir
        Case "2d"
            Local $_dex_OID = _SNMP_ExtractOID($input)
            Return $_dex_OID

        Case "2h"
            Local $hex_OID = _SysObjIDToHexString($input) ;transform the OID in a hex value
            $hex_OID = "2B" & $hex_OID ;add "2B" in front of the string
            Local $len_OID = Hex(Int(StringLen($hex_OID) / 2), 2) ;calculate the length
            $l_OID = $__SNMP_DATA_OID ;1st element Object ID = ASN.1 type "06"
            $l_OID &= $len_OID ;2nd element = length
            $l_OID &= $hex_OID
            Return $l_OID

    EndSwitch
EndFunc   ;==>_SNMP_TranslateOID

Func _SNMP_Build_COM($comm)
    Local $hex_COMM = _StringToHex($comm) ;transform the community string in a hex value
    Local $len_COMM = Hex(Int(StringLen($hex_COMM) / 2), 2) ;calculate the length
    Local $_comm_ = "04" & $len_COMM & $hex_COMM
    Return $_comm_
EndFunc   ;==>_SNMP_Build_COM

Func _SNMP_GetPacLen($sPkt)
    Local $pacl = 0
    Switch StringLeft($sPkt, 2)
        Case "81"
            $pacl = 4
        Case "82"
            $pacl = 6
        Case Else
            $pacl = 2
    EndSwitch
    Return $pacl
EndFunc   ;==>_SNMP_GetPacLen

Func _SNMP_StripPacket($sPkt)
    Local $_l_pl = _SNMP_GetPacLen(StringLeft($sPkt, 6))
    Local $_pacLen_ = StringLeft($sPkt, $_l_pl)
    #forceref $_pacLen_
    $sPkt = StringTrimLeft($sPkt, $_l_pl) ;strip packet length
    Return $sPkt
EndFunc   ;==>_SNMP_StripPacket

Func _SNMP_StripBlocks($sPkt, $_el, $_eltxt)
    Select
        Case StringLeft($sPkt, 4) = "0202"
            _SNMP_WriteArrayValues($__SNMP_Received, $_el, $_eltxt, StringLeft($sPkt, 8))
            $sPkt = StringTrimLeft($sPkt, 8)
        Case StringLeft($sPkt, 4) = "0201"
            _SNMP_WriteArrayValues($__SNMP_Received, $_el, $_eltxt, StringLeft($sPkt, 6))
            $sPkt = StringTrimLeft($sPkt, 6)
    EndSelect
    Return $sPkt
EndFunc   ;==>_SNMP_StripBlocks
#EndRegion ~~~~~~~~~~~~~~~~~~~~ Add Packet Layers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ Encode IP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SNMP_EncodeIP($strIP)
    Local $encoded_IP = ""
    Local $encoded_IParr
    $encoded_IParr = StringSplit($strIP, ".")
    If $encoded_IParr[0] <> 4 Then
        ConsoleWrite("ERROR: Wrong IP Format " & $strIP & @CRLF)
        Return SetError(1)

    EndIf
    $encoded_IP = Hex($encoded_IParr[1], 2) & Hex($encoded_IParr[2], 2) & Hex($encoded_IParr[3], 2) & Hex($encoded_IParr[4], 2)
    Return $encoded_IP
EndFunc   ;==>_SNMP_EncodeIP
#EndRegion ~~~~~~~~~~~~~~~~~~~~ Encode IP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ Encode OID ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SNMP_BuildOID($oid)
    Local $hex_OID = _SysObjIDToHexString($oid) ;transform the OID in a hex value
    Local $SNMP_hexOID = $hex_OID
    #forceref $SNMP_hexOID
    $hex_OID = "2B" & $hex_OID ;add "2B" in front of the string
    Local $len_OID = Hex(Int(StringLen($hex_OID) / 2), 2) ;calculate the length
    Local $OID_Arr[Dec($len_OID) + 2] ;build array to store values
    $OID_Arr[0] = $__SNMP_DATA_OID ;1st element Object ID = ASN.1 type "06"
    $OID_Arr[1] = $len_OID ;2nd element = length
    For $i = 2 To Dec($len_OID) + 1 ;2digit OID parts
        $OID_Arr[$i] = StringMid($hex_OID, 2 * $i - 3, 2)
    Next
    Return $OID_Arr
EndFunc   ;==>_SNMP_BuildOID

Func _SysObjIDToHexString($input) ;convert OID to hex form
    Local $Output
    If StringLeft($input, 4) = "1.3." Then $input = StringTrimLeft($input, 4)
    Local $aInput = StringSplit($input, ".")
    For $x = 1 To $aInput[0]
        If Number($aInput[$x]) > 127 Then
            $Output &= _SNMP_Encode(Number($aInput[$x]))
        Else
            $Output &= Hex(Number($aInput[$x]), 2)
        EndIf
    Next
    Return $Output
EndFunc   ;==>_SysObjIDToHexString

Func _SNMP_Encode($d, $r = 0)
    Local $Op_Result = ""
    Local $t1 = Int($d / 128)
    Local $t2 = Int($d - $t1 * 128)
    If $t1 Then $Op_Result &= _SNMP_Encode($t1, 1)
    If $r Then $t2 += 128
    $Op_Result &= Hex($t2, 2)
    Return $Op_Result
EndFunc   ;==>_SNMP_Encode
#EndRegion ~~~~~~~~~~~~~~~~~~~~ Encode OID ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ Initialize Variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SNMP_Init()
    Dim $__SNMP_Received[1500][3]
    Dim $__VarBindContent[1000]
    Dim $__SNMP_Util[1000][3]
EndFunc   ;==>_SNMP_Init
#EndRegion ~~~~~~~~~~~~~~~~~~~~ Initialize Variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ~~~~~~~~~~~~~~~~~~~~ MISC Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;memo: improve _DeleteIndexes - it takes too long to delete/redim the array everytime !!!
Func _SNMP_ExtractData($dtype, $tmpOUT) ;Extract clear data
    Switch $dtype
        Case "04" ;string
            Return BinaryToString("0x" & $tmpOUT)

        Case "02" ;number
            Return _SNMP_HexToDec($tmpOUT)

        Case "06" ;OID
            Return _SNMP_ExtractOID($tmpOUT)

        Case "40" ;IP Address
            Return _SNMP_ExtractIP($tmpOUT)

        Case "41" ;Counter
            Return _SNMP_HexToDec($tmpOUT)

        Case "42" ;Gauge
            Return _SNMP_HexToDec($tmpOUT)

        Case "43"
            Return _SNMP_HexToDec($tmpOUT) / 100 & " sec."

        Case "46" ;Counter64
            Return _SNMP_HexToDec($tmpOUT)

    EndSwitch
EndFunc   ;==>_SNMP_ExtractData

Func _SNMP_ExtractIP($strIP)
    Local $extractedIParray[5]
    Local $extractedIP = ""
    For $i = 1 To 4
        $extractedIParray[$i] = Dec(StringMid($strIP, 2 * $i - 1, 2))
        If $i = 4 Then
            $extractedIP &= $extractedIParray[$i]
        Else
            $extractedIP &= $extractedIParray[$i] & "."
        EndIf
    Next
    Return $extractedIP
EndFunc   ;==>_SNMP_ExtractIP

Func _SNMP_ExtractOID($strOID)
    Local $extractedOIDarray[StringLen($strOID) / 2 + 1]
    Local $extractedOID = "1.3."
    Local $aA
    For $i = 2 To StringLen($strOID) / 2
        Local $OIDtoDecode = ""
        $extractedOIDarray[$i] = StringMid($strOID, 2 * $i - 1, 2)
        If Dec($extractedOIDarray[$i]) > 128 Then
            $OIDtoDecode &= $extractedOIDarray[$i]
            $aA = 0
            While Dec(StringMid($strOID, 2 * ($i + $aA) - 1, 2)) > 128
                $OIDtoDecode &= " + " & StringMid($strOID, 2 * ($i + $aA) + 1, 2)
                $aA += 1
            WEnd
            $extractedOID &= _SNMP_Decode($OIDtoDecode)
            $i += $aA
        Else
            $extractedOID &= Dec($extractedOIDarray[$i])
        EndIf
        If $i < StringLen($strOID) / 2 Then
            $extractedOID &= "."
        EndIf
    Next
    Return $extractedOID
EndFunc   ;==>_SNMP_ExtractOID

Func _SNMP_HexToDec($nbr)
    Local $extractedHEXarray[StringLen($nbr) + 1]
    Local $extractedNBR = 0
    For $i = 1 To StringLen($nbr)
        $extractedHEXarray[$i] = StringMid($nbr, $i, 1)
        $extractedNBR += 16 ^ (StringLen($nbr) - $i) * Dec($extractedHEXarray[$i])
    Next
    Return $extractedNBR
EndFunc   ;==>_SNMP_HexToDec

Func _SNMP_Decode($s, $d = 0)
    Local $a = StringSplit($s, " + ", 1)
    Local $d1
    For $j = 1 To $a[0]
        $d1 = Dec($a[$j])
        If $d1 > 127 Then $d1 = $d1 - 128
        $d = ($d * 128) + $d1
    Next
    Return $d
EndFunc   ;==>_SNMP_Decode

Func _SNMP_WriteArrayValues(ByRef $ArrRet, $idx, $val0, $val1, $val2 = "") ;write entries in returned arrays
    ;_ArrayDisplay($ArrRet)
    $ArrRet[$idx][0] = $val0
    $ArrRet[$idx][1] = $val1
    If $val2 <> "" Then $ArrRet[$idx][2] = $val2
EndFunc   ;==>_SNMP_WriteArrayValues

Func _SNMP_ThrowError($sErr, $sPkt)
    Switch $sErr
        Case "00"
            Return
        Case "01"
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: 1", "Error Message:  Response message too large to transport." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
        Case "02"
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: 2", "Error Message:   The name of the requested object was not found." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
        Case "03"
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: 3", "Error Message:   A data type in the request did not match the data type in the SNMP agent." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
        Case "04"
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: 4", "Error Message:    The SNMP manager attempted to set a read-only parameter." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
        Case "05"
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: 5", "Error Message:   General Error (some error other than the ones listed above)." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
        Case Else
            ClipPut($sPkt)
            MsgBox(16, "SNMP Error Code: " & $sPkt, "Error Message:   No Error message for this one." & @CRLF & @CRLF & "                (packet received placed in clipboard)")
    EndSwitch
    Exit
EndFunc   ;==>_SNMP_ThrowError

#EndRegion ~~~~~~~~~~~~~~~~~~~~ MISC Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#cs
    0
    noError
    No error occurred. This code is also used in all request PDUs, since they have no error status to report.

    1
    tooBig
    The size of the Response-PDU would be too large to transport.

    2
    noSuchName
    The name of a requested object was not found.

    3
    badValue
    A value in the request didn't match the structure that the recipient of the request had for the object. For example, an object in the request was specified with an incorrect length or type.

    4
    readOnly
    An attempt was made to set a variable that has an Access value indicating that it is read-only.

    5
    genErr
    An error occurred other than one indicated by a more specific error code in this table.

    6
    noAccess
    Access was denied to the object for security reasons.

    7
    wrongType
    The object type in a variable binding is incorrect for the object.

    8
    wrongLength
    A variable binding specifies a length incorrect for the object.

    9
    wrongEncoding
    A variable binding specifies an encoding incorrect for the object.

    10
    wrongValue
    The value given in a variable binding is not possible for the object.

    11
    noCreation
    A specified variable does not exist and cannot be created.

    12
    inconsistentValue
    A variable binding specifies a value that could be held by the variable but cannot be assigned to it at this time.

    13
    resourceUnavailable
    An attempt to set a variable required a resource that is not available.

    14
    commitFailed
    An attempt to set a particular variable failed.

    15
    undoFailed
    An attempt to set a particular variable as part of a group of variables failed, and the attempt to then undo the setting of other variables was not successful.

    16
    authorizationError
    A problem occurred in authorization.

    17
    notWritable
    The variable cannot be written or created.

    18
    inconsistentName
    The name in a variable binding specifies a variable that does not exist

#ce

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

  • 8 months later...

I was trying to get the all the ipAdEntAddr using bulk but it only returned the first one...to fix this, you need to first GetRequest (A0) and then repeat GetNext (A1)
 
Took me a bit to understand how this works but here is an example

#include "snmp_UDF-v1.7.4.au3"
Global $Port = 161 ; UDP 161 = SNMP port
Global $SNMP_Version = 2 ; SNMP v2c (1 for SNMP v1)
Global $SNMP_Community = "public" ; SNMPString(Community) (change it)
Global $SNMP_ReqID = 1
Global $SNMP_Command
Global $result
Global $Timeout_msec = 900
Global $oid = "1.3.6.1.2.1.4.20.1.1"
Global $oidLength = StringLen($oid)
Global $_first = $oid&'.0.0.0.0'
UDPStartup()
$Socket = UDPOpen('192.168.1.1', $Port)
While 1
    If $SNMP_ReqID > 0 Then $_first = $result[1][0]
    $SNMP_ReqID +=1
    $SNMP_Command = _SNMPBuildPacket($_first, $SNMP_Community, $SNMP_Version, $SNMP_ReqID, "A1")
    UDPSend($Socket, $SNMP_Command)
    _StartListener()
    If StringMid($result[1][0],1,$oidLength) <> $oid Then ExitLoop ;checkin if you're out of your desired MIB SubTree
    ConsoleWrite("Iteration:"&$SNMP_ReqID&@TAB&$result[1][0] &@TAB&$result[1][1]&@LF)
WEnd
UDPCloseSocket($Socket)
UDPShutdown()
Exit

Func _StartListener()
    $Timeout = TimerInit()
    While 1
        $srcv = UDPRecv($Socket, 100)
        If $srcv <> "" Then $result = _ShowSNMPReceived($srcv)
        If @error Or TimerDiff($Timeout) > $Timeout_msec Then ExitLoop
        Sleep(50)
    WEnd
EndFunc   ;==>_StartListener

 
EDIT: Speed boost.
EDIT2: Need to find a way to read this value, avoiding the last unnecessary query (it would speedup 170ms this function)
EDIT3: Can somebody help me interpret the outputs?
There're some strings I don't know what they mean

nvm

EDIT4: Still didn't decode those hex values, RFC docs are a mess...
Found another problem, it cannot retrieve mac addresses properly, output:

Row|Col 0|Col 1
[0]||
[1]|1.3.6.1.2.1.4.22.1.2.1.192.168.1.4|
[2]|1.3.6.1.2.1.4.22.1.2.1.192.168.1.255|ÿÿÿÿÿÿ
Edited by Kyan

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Link to comment
Share on other sites

  • 2 weeks later...

What's in a mac address packet (sorry I used wordpad for this):

aMrJXDt.png

There are some values I don't know what they are.

*sigh* 0x8140=192=(Dec(0x81)+Dec(40))-1, same goes to 168, don't know why they made it like that -_- looks stupid, if someone already saw this way of coding ip addresses please tell :D

EDIT:

0x04 = OCTET STRING

0x06 = OID (with ber encodings https://msdn.microsoft.com/en-us/library/bb540809(v=vs.85).aspx )

0x2B =>First OID byte, represents .1.3 (see msdn doc above)

0x10 =>Still blank about what kind of length is that..

Edited by Kyan

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Link to comment
Share on other sites

  • 1 year later...

Just recently came across this clever UDF, and I quickly managed to get it working for get and bulk. But how do you specify multiple OID for a single run? (as opposed to having to run it once for each OID)

I do realize it doesn't support arrays anymore like mentioned in the comments... but does that mean multiple OID support is gone as well? I've spent a few hours sifting through the script code, trying to see if there are any functions/features for combining several OID in one packet (does the protocol even support that?), but still no luck figuring out how or if it can do that. And no clues in this thread either, so I hope someone here might have an answer, or maybe give a quick example of how to do it if it's possible.

 

FYI I'm not looking for a way to do bulk/walk, but a way to specify two or more OIDs to retrieve.

 

 

863nP4W.png discord.me/autoit  (unofficial)

Link to comment
Share on other sites

  • 3 years later...

this function is wrong:

 

Func _SNMPExtractOID($strOID)
    Local $extractedOIDarray [StringLen($strOID)/2 + 1]
    Local $extractedOID = "1.3."
    For $i = 2 To StringLen($strOID)/2
        Local $OIDtoDecode=""
        $extractedOIDarray[$i] = StringMid($strOID, 2*$i - 1, 2)
        If Dec($extractedOIDarray[$i]) > 128 Then
            $OIDtoDecode &=$extractedOIDarray[$i]
            $aA=0
            While dec(StringMid($strOID, 2*($i + $aA)-1, 2))>128
                $OIDtoDecode &=" + "&StringMid($strOID, 2*($i + $aA)+1, 2)
                $aA+=1
            WEnd
            $extractedOID &= _decode($OIDtoDecode)
            $i += $aA
        Else
            $extractedOID &= Dec($extractedOIDarray[$i])
        EndIf
        If $i < StringLen($strOID)/2 Then
            $extractedOID &="."
        EndIf
    Next
    Return $extractedOID

 

It works fine with an OID walk like:

1.3.6.1.2.1.31.1.1.1.1.1
1.3.6.1.2.1.31.1.1.1.1.2
1.3.6.1.2.1.31.1.1.1.1.3
1.3.6.1.2.1.31.1.1.1.1.4

It doesn't work when there's a big number behind the dot:

1.3.6.1.2.1.31.1.1.1.1.83886080
1.3.6.1.2.1.31.1.1.1.1.151060481
1.3.6.1.2.1.31.1.1.1.1.151060648 
1.3.6.1.2.1.31.1.1.1.1.151060649

 

For some reason it turns 1.3.6.1.2.1.31.1.1.1.1.83886080 into 1.3.6.1.2.1.31.1.1.1.1.5120.128.0

 

apparently it turns A8808000 into 5120.128.0 instead of 83886080

 

Edited by crackdonalds
Link to comment
Share on other sites

I've changed the function to this to make it work with big numbers:
 

Func _SNMPExtractOID($strOID)
    Local $extractedOIDarray [StringLen($strOID)/2 + 1]
    Local $extractedOID = "1.3."
    For $i = 2 To StringLen($strOID)/2 
        Local $OIDtoDecode="" 
        $extractedOIDarray[$i] = StringMid($strOID, 2*$i - 1, 2)
        If Dec($extractedOIDarray[$i]) > 128 Then
            $OIDtoDecode &=$extractedOIDarray[$i] 
            $aA=0
            While dec(StringMid($strOID, 2*($i + $aA)-1, 2))>128
               $bytecount = StringLen($strOID) - 2*($i)
              ;If $bytecount > 2 AND Mod(($bytecount - 2) / 2, 2) = 1 Then
                ;  $bytecount = $bytecount - 1
                 ; EndIf
               $counter = 0
               If $bytecount > 2 Then
                  While $bytecount > 1
                  $OIDtoDecode &=" + "&StringMid($strOID, 2*($i + $counter)+1, 2)
                  If Dec(StringMid($strOID, 2*($i + $counter)+1, 2)) < 128 Then
                  $counter = $counter + 1
                     ExitLoop
                     EndIf
                  $counter = $counter + 1
                  $bytecount = $bytecount - 1
               WEnd
               $i = $i + $counter
               ExitLoop
               Else
                $OIDtoDecode &=" + "&StringMid($strOID, 2*($i + $aA)+1, 2)
                $aA+=1
                EndIf
             WEnd
            $extractedOID &= _decode($OIDtoDecode)
            $i += $aA
        Else
            $extractedOID &= Dec($extractedOIDarray[$i])
         EndIf
        If $i < StringLen($strOID)/2 Then
            $extractedOID &="."
        EndIf
    Next
    Return $extractedOID
EndFunc     ;==>_SNMPExtractOID

 

I've also changed the _ExtractData function. Case 02 was causing problems.

Func _ExtractData($dtype, $tmpOUT)                                      ;Extract clear data
    Switch $dtype
        Case "04"           ;string
            Return BinaryToString("0x"&$tmpOUT)
        Case "02"           ;number
            Return Dec ($tmpOUT)
        Case "06"           ;OID
            Return _SNMPExtractOID($tmpOUT)
        Case "40"           ;IP Address
            Return _SNMPExtractIP ($tmpOUT)
        Case "41"           ;Counter
            Return _SNMPHexToDec ($tmpOUT)
        Case "42"           ;Gauge
            Return _SNMPHexToDec ($tmpOUT)
        Case "43"
            Return _SNMPHexToDec($tmpOUT)/100 &" sec."
        Case "46"           ;Counter64
            Return _SNMPHexToDec ($tmpOUT)
    EndSwitch
EndFunc     ;==>_ExtractData

 

Edited by crackdonalds
Changed the _SNMPExtractOID function and added the modified _ExtractData function
Link to comment
Share on other sites

  • 4 years later...

How's it going,
Looking for help working with this UDF, with Negative numbers
I am making an SNMP request to my agent for fiber tx and rx values in a loop, although some of these results should be negative although the udf is not interpreting these correctly, 
For example the values would be like "341" "- 62", "-400"  and they would be reported as "341", "192", "65136"
I know the values are correct as I am sniffing the packets with Wireshark and can see the response is -400 
I cannot provide running code as there is far to much extra setup and without an agent it wouldn't be easily tested but its just a standard snmp packet 

i have tried converting to a signed INT, Number and checking hex, all report the same 65136 number, wireshark shows its a Integer32 

Any information or ideas would be great, Thanks and have a great weekend!

I Love It When a *Autoit Script* Comes Together

Link to comment
Share on other sites

  • 2 weeks later...
On 3/22/2024 at 12:00 PM, A-Team said:

 although some of these results should be negative although the udf is not interpreting these correctly, 


 

of course it is!, it interprets the values with Two complement here
I don't know the time I spent trying to troubleshoot this, I am learning data structures in college, but I learned more trying to figure this out..
 

 

I Love It When a *Autoit Script* Comes Together

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...