【问题标题】:How to read SNMP OID Output (bits)如何读取 SNMP OID 输出(位)
【发布时间】:2015-01-19 04:49:40
【问题描述】:

我有一个简单的问题。它最有可能是用户错误,所以我在开始之前道歉。

我正在尝试为设备设置阈值,以便当我们的一台打印机处于某种状态时它会提醒我们。 (卡纸、无碳粉、无纸等)我找到了处理此问题的特定 oid。 (1.3.6.1.2.1.25.3.5.1.2.1) 具体的oid在HOST-RESOURCE-MIB下叫做hrPrinterDetectedErrorState。我已经验证我可以通过 SNMPWALK 看到 oid。我的问题是解释它吐出的数据。我在 MIB 中阅读的内容与通过 SNMPWALK 看到的内容不同。

这是 MIB 中对 oid 的描述:

     "This object represents any error conditions detected
      by the printer.  The error conditions are encoded as
      bits in an octet string, with the following
      definitions:

            Condition        Bit #

            lowPaper              0

            noPaper              1
            lowToner              2
            noToner              3
            doorOpen              4
            jammed                5
            offline              6
            serviceRequested      7
            inputTrayMissing      8
            outputTrayMissing    9
            markerSupplyMissing  10
            outputNearFull      11
            outputFull          12
            inputTrayEmpty      13
            overduePreventMaint  14

      Bits are numbered starting with the most significant
      bit of the first byte being bit 0, the least
      significant bit of the first byte being bit 7, the
      most significant bit of the second byte being bit 8,
      and so on.  A one bit encodes that the condition was
      detected, while a zero bit encodes that the condition
      was not detected.

      This object is useful for alerting an operator to
      specific warning or error conditions that may occur,
      especially those requiring human intervention."

奇怪的是 SNMPWALK 说 oid 是一个十六进制字符串,而 MIB 指定它应该是一个八进制字符串。两者有区别吗?我是否需要以某种方式转换 SNMPWALK 输出的数据以使其与 MIB 所说的内容相匹配?

为了测试所有内容,我将打印机设置为几个不同的“状态”。然后我在设备上运行 SNMPWALK 以查看 oid 输出。这是结果。正如您将看到的,这些结果与 MIB 指定的不匹配。

Case 1: Opened the toner door

Expected Output based on MIB: 4
SNMP Output: 08

Case 2: Removed Toner & Closed the door

Expected Output based on MIB:  1
SNMP Output:  10

Case 3: Placed 1 sheet of paper and printed a 2 page document. The printer ran out of paper.

Expected Output based on MIB: 0 or 1
SNMP Output: @

我对输出感到困惑。我只需要知道如何读取 oid,这样我就可以设置阈值,以便当它看到例如 08 时执行特定操作。

感谢您的帮助!

【问题讨论】:

  • 当墨粉(“标记补给”)丢失时,为什么会出现1

标签: powershell printing snmp mib oid


【解决方案1】:

你读错了。您收到的数据实际上应该被解释为一个位数组,每个位都是您案例中特定警报的自己的值

Expected Output based on MIB: 4
SNMP Output: 08

你实际上得到了输出:

00001000 00000000

这里的第一个字节涵盖了这些值

lowPaper             0
noPaper              1
lowToner             2
noToner              3
doorOpen             4
jammed               5
offline              6
serviceRequested     7

所以lowPaper是第0位,noPaper是第1位,lowToner是第2位等等。而doorOpen是第4位,你可以看到那个位被设置,表明门是开着的.

编辑:

这非常依赖于设备和实现。要知道如何正确解析它需要大量的试验和错误(至少从我的经验来看)。例如,如果您收到消息 9104,则可能是

91 and 04 are separate so you first translate 91 to binary from hex and then the 
same thing with 04
91: 10010001
04: 00000100

这意味着纸张不足、无墨粉、服务请求和 inputTrayEmpty。这看起来是最有可能的工作方式。

如果您只返回一个字节,则意味着您应该只在前 8 位中查找警报。作为您需要注意的事情的示例:如果存在的唯一警报是 doorOpen,您可能只会返回 08,但实际上是 0008,其中前 2 个十六进制字符实际上是警报的第二部分,但不是显示,因为它们不存在。因此,在您的情况下,您实际上首先必须切换字节(如果有 4 个)自行解析前两个和后两个,然后得到实际结果。

正如我所说,从我所看到的来看,这里没有真正的标准,你必须使用它,直到你确定你知道数据是如何发送的以及如何解析它。

【讨论】:

  • 还是没搞定,所以我得先把08转成Binary格式,对吧? “08”是十六进制格式,对吗?所以转换的结果是00001000,但是第二个字节在哪里呢?那么我应该使用设置为 1 的位数吗?但是如果我的打印机返回给我 SNMP 9104 怎么办?它给了我一个二进制的 10010001 00000100,我该怎么办?
  • 我认为在“SNMP 输出:08”的情况下,您只收到一个字节,从左到右解释为“00001000”。
  • 令人困惑的是字节以大端顺序排列,与典型的电脑相反。
【解决方案2】:

用于解释 hrPrinterDetectedErrorState 八位字符串的 Powershell 函数。 (我觉得有一些更常用的方法可以做到这一点?)我一直在使用这个模块,但它甚至不能将主机名解析为 IP 地址。 返回的数据属性只是一个字符串,而不是八位字符串类型。这些打印机都不是 snmp v3。 https://www.powershellgallery.com/packages/SNMP/1.0.0.1

字节以大端顺序排列。对于 [bitconverter] 方法,它们必须被反转。必须填充单个字节。

[flags()] Enum hrPrinterDetectedErrorState
{
  lowPaper            = 0x8000
  noPaper             = 0x4000
  lowToner            = 0x2000
  noToner             = 0x1000
  doorOpen            = 0x0800
  jammed              = 0x0400
  Offline             = 0x0200
  serviceRequested    = 0x0100

  inputTrayMissing    = 0x0080
  outputTrayMissing   = 0x0040
  markerSupplyMissing = 0x0020
  outputNearFull      = 0x0010
  outputFull          = 0x0008
  inputTrayEmpty      = 0x0004
  overduePreventMaint = 0x0002
  notUsed             = 0x0001
}

function snmpmessage($data) {

  $bytes = [byte[]][char[]]$data

  #if ($bytes.count -eq 1) { $bytes = 0,$bytes[0] }
  #if ([BitConverter]::IsLittleEndian) { [Array]::Reverse($bytes) }
  #$code = [bitconverter]::ToUInt16($bytes, 0)

  $code = [int]$bytes[0]
  $code = $code -shl 8  # or $code = $code * 256
  if ($bytes[1]) { $code = $code + $bytes[1] }

  [hrPrinterDetectedErrorState]$code

}

snmpmessage -join [char[]](0x91,0x04)

inputTrayEmpty, serviceRequested, noToner, lowPaper

或者:

$hrPrinterDetectedErrorState = '1.3.6.1.2.1.25.3.5.1.2.1'
$hostname = 'myprinter01'
$ip = (Resolve-DnsName $hostname).ipaddress
$result = Get-SnmpData -ip $ip -oid $hrPrinterDetectedErrorState -v v1
snmpmessage $result.data

LowToner

# ?
# $octetstring = [Lextm.SharpSnmpLib.OctetString]::new($result.data)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多