如何读取 SNMP OID 输出(位)(hrPrinterDetectionErrorState)



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

我正在尝试为设备设置阈值,以便在我们的一台打印机处于特定状态时提醒我们。(卡住、碳粉用完、无纸张等)我已经找到了处理此问题的特定 oid。(1.3.6.1.2.1.25.3.5.1.2.1) 特定的 oid 在 HOST-RESOURCE-MIB 下称为 hrPrinterDetectionErrorState。我已经验证了我可以通过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 时它会执行某个操作。

感谢您的帮助!

你读错了。您收到的返回数据实际上应该被解释为一个位数组,对于您的情况下,每个位都是其自己的特定警报值

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

这意味着低纸张,无碳粉,请求服务和输入托盘空。这看起来是最有可能的工作方式。

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

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

Powershell 函数,用于解释 hrPrinterDetectionErrorState 八位字节字符串。 (我觉得有一些更常用的方法可以做到这一点? 我一直在使用这个模块,但它甚至没有将主机名解析为 IP 地址。返回的数据属性只是一个字符串 (.tostring()) 而不是八进制字符串类型。 所有打印机都不是 snmp v3。https://www.powershellgallery.com/packages/SNMP/1.0.0.1(请注意,这不能很好地处理 ASCII 范围之外的字节,-gt 0x7e,替换为"?")

单个字节必须用零填充。 大多数情况下只发送一个字节。 字节是按照它记录的顺序排列的,我认为令人困惑。 将两个字节转换为整数会产生不同的顺序(取决于大端序或小端序)。

function snmpmessage {
  param($data)
  [flags()] Enum hrPrinterDetectedErrorState
  {
    # more common group
    LowPaper            = 0x0080
    NoPaper             = 0x0040
    LowToner            = 0x0020
    NoToner             = 0x0010
    DoorOpen            = 0x0008
    Jammed              = 0x0004
    Offline             = 0x0002
    ServiceRequested    = 0x0001
    InputTrayMissing    = 0x8000
    OutputTrayMissing   = 0x4000
    MarkerSupplyMissing = 0x2000
    OutputNearFull      = 0x1000
    OutputFull          = 0x0800
    InputTrayEmpty      = 0x0400
    OverduePreventMaint = 0x0200
  }
  $bytes = [byte[]][char[]]$data
  if ($bytes.count -eq 1) { $bytes = $bytes[0],0 } # pad 0
  $code = [bitconverter]::ToUInt16($bytes, ($startIndex=0))
  [hrPrinterDetectedErrorState]$code
}
snmpmessage -join [char[]](1,4)
ServiceRequested, InputTrayEmpty

snmpmessage '@' # 0x40
NoPaper

或:

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

最新更新