嵌入式 SNMP4j 日志访问失败和成功

Embedded SNMP4j log access fail and success

我正在使用 SNMP4j 在 java 中编写一个代理,并且进展顺利。我可以获取和设置值(目前仅支持 SNMPv1,但 v3 即将推出)。

我的下一个要求是登录我的应用程序日志(不是 SNMP4J 日志),特别是这三件事:

  1. 新用户从
  2. 登录
  3. 来自
  4. 的用户的新失败 SNMP 连接尝试
  5. SNMP SET 用于写入值 from .

我已经使用 org.snmp4j.log.LogAdapter 将 SNMP4j 日志记录到我的调试日志中,但这不是我想要的特定日志记录。

我玩过 org.snmp4j.event.AuthenticationFailureListener 以在身份验证失败时进行记录。这似乎只是 SNMPv3,它没有给我失败的用户名。

有人知道怎么做吗? Listener 架构似乎已经部分到位,还有更多我找不到的吗?我可以使用源代码并在需要的地方添加我自己的日志记录,但是这对许可有何影响? SNMP 使用 Apache 2.0 许可证

我执行了以下操作以完全访问请求和响应 PDU:

对于身份验证失败 日志记录:

  1. 延长 AuthenticationFailureEvent.class。在我的例子中,我将安全名称和状态信息添加到事件 class.
  2. 的构造函数中
  3. 扩展 MessageDispatcherImpl.class 并覆盖方法 dispatchMessage():

    switch (status) {
      case SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_ERROR :
      case SnmpConstants.SNMPv3_USM_NOT_IN_TIME_WINDOW :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID :
      case SnmpConstants.SNMP_MP_WRONG_USER_NAME :
      case SnmpConstants.SNMPv3_TSM_INADEQUATE_SECURITY_LEVELS :
      case SnmpConstants.SNMP_MP_USM_ERROR : {
        // create an extended version of the failure event
        AuthenticationFailureEvent event = new ExtendedAuthenticationFailureEvent(this,incomingAddress,securityName.getValue(),sourceTransport, status, statusInfo, wholeMessage);
        fireAuthenticationFailure(event);
        break;
      }
    }
    
  4. 在您的代理中 class 覆盖 initMessageDispatcher() 方法:

    protected void initMessageDispatcher() {
      ...
      dispatcher = new ExtendedMessageDispatcherImpl();
      ...
    }
    
  5. 将您的日志 class 添加为此调度程序的侦听器(例如在您代理的 finishInit() 方法中):

    dispatcher.addAuthenticationFailureListener(loggingHandler);
    

对于请求记录:

只需在您的日志 class 中实现 CommandResponder 接口并将其添加到您的会话中:

getSession().addCommandResponder(loggingHandler);

对于响应记录:

  1. 创建一个方法,例如logResponsePdu(PDU pdu) 在您的日志中 class.

  2. 扩展 MessageDispatcherImpl.class 并覆盖方法 returnResponsePdu()

    public int returnResponsePdu(int messageProcessingModel, int securityModel, byte[] securityName, int securityLevel, PDU pdu, int maxSizeResponseScopedPDU, StateReference stateReference, StatusInformation statusInformation) throws MessageException {
      int result = super.returnResponsePdu(messageProcessingModel, securityModel, securityName, securityLevel, pdu, maxSizeResponseScopedPDU, stateReference, statusInformation);
      // log response message
      loggingHandler.logResponsePdu(pdu);
      return result;
    }
    

在我的案例中,结果以以下形式登录:

Request received! From: (ip removed), security name: (login name), PDU type: SET, OID: 1.3.6.1.2.1.1.5.0 = 'Test Name'

Request PDU: SET[{contextEngineID=(data removed), contextName=private}, requestID=(data removed), errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = Test Name]]

Response sent! Error status: Success, PDU type: RESPONSE, OID: 1.3.6.1.2.1.1.5.0 = 'Test Name'

Response PDU! PDU: RESPONSE[{contextEngineID=(data removed), contextName=private}, requestID=(data removed), errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = Test Name]]

也许这不是最好的方法,但它works.I希望我能帮到你。