Java 带有snmpv3响应且错误为空的SNMP4j

Java 带有snmpv3响应且错误为空的SNMP4j,java,snmp4j,Java,Snmp4j,我正在java应用程序中使用snmp4j 3.4.2(下面是完整代码) 我正在尝试使用snmpv3、securityDES和authMD5以及自定义OID(由snmp的扩展功能执行的python脚本)执行一个snmpget。为了更好地理解,我在下面的示例中使用了SnmpConstants.sysUpTime SNMP资源已配置此用户: defSecurityName demo defSecurityLevel authPriv defAuthType MD5 defPrivType DES de

我正在java应用程序中使用snmp4j 3.4.2(下面是完整代码)

我正在尝试使用snmpv3、securityDES和authMD5以及自定义OID(由snmp的扩展功能执行的python脚本)执行一个snmpget。为了更好地理解,我在下面的示例中使用了SnmpConstants.sysUpTime

SNMP资源已配置此用户:

defSecurityName demo
defSecurityLevel authPriv
defAuthType MD5
defPrivType DES
defAuthPassphrase pass
defPrivPassphrase pass
我已经在使用这个用户和资源成功地使用python(pysnmp)和bash(snmpget)执行snmpget,因此我可以肯定地说我的设置是有效的,java代码是问题所在

我有两个java类(Listener.java和ServerStatusHelper.java)

java包含main并在ServerStatusHelper.java内调用snmpGet,其他监听器代码因不必要而被排除在外

import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivDES;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;

public class Listener {

    public static void main(String[] args) {

        ServerStatusHelper agent = new ServerStatusHelper("host.tld", "udp", 161, "demo", "demo",
                "pass", "pass", new AuthMD5(), new PrivDES(), true);

        try {
            agent.startAgent();
            ResponseEvent response = agent.snmpGetOperation(SnmpConstants.sysUpTime);
            if (response != null) {
                System.out.println(
                        "response null - error: "+ response.getError() +
                        "peerAddress: " + response.getPeerAddress() +
                        "source: " + response.getSource().toString() +
                        "request: " + response.getRequest());
            }

        } catch (

        IOException e) {
            e.printStackTrace();

        }
    }

}
ServerStatusHelper.java

import java.io.IOException;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthGeneric;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.PrivacyGeneric;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class ServerStatusHelper {

    private Address nmsIP;
    private String user;
    private String securityName;
    private String privacyPassword;
    private String authorizationPassword;
    private AuthGeneric authProtocol;
    private PrivacyGeneric privacyProtocol;
    private String protocol;
    private boolean encryption;

    private long timeOut = 1000;
    private int noOfRetries = 10;

    private Snmp snmp;
    private UserTarget target;
    private CommunityTarget v1target;
    
    ServerStatusHelper(String ip, String protocol, int snmpPort, String username, String securityName,
            String privacyPassword, String authPassowrd, AuthGeneric authProtocol, PrivacyGeneric privacyProtocol,
            boolean encryption) {

        nmsIP = GenericAddress.parse(protocol + ":" + ip + "/" + snmpPort);
        System.out.println("NMS IP set : " + nmsIP.toString());

        this.protocol = protocol;
        this.user = username;
        this.securityName = securityName;
        this.privacyPassword = privacyPassword;
        this.authorizationPassword = authPassowrd;
        this.authProtocol = authProtocol;
        this.privacyProtocol = privacyProtocol;
        this.encryption = encryption;
        
        SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthMD5());
        SecurityProtocols.getInstance().addPrivacyProtocol(new PrivDES());

    }

    public void startAgent() throws IOException {
        if (snmp == null) {

            TransportMapping<? extends TransportIpAddress> transport = null;

            if (protocol.equalsIgnoreCase("udp")) {
                System.out.println("UDP Protocol selected.");
                transport = new DefaultUdpTransportMapping();
            } else {
                System.out.println("TCP Protocol selected.");
                transport = new DefaultTcpTransportMapping();
            }

            snmp = new Snmp(transport);

            USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
            SecurityModels.getInstance().addSecurityModel(usm);

            transport.listen();

            snmp.getUSM().addUser(new OctetString(user),
                    new UsmUser(new OctetString(securityName), authProtocol.getID(),
                            new OctetString(authorizationPassword), privacyProtocol.getID(),
                            new OctetString(privacyPassword)));

            if (encryption)
                target = createUserTarget();
            else
                v1target = createUserTargetWithoutEncryption();
        }

    }

    public ResponseEvent snmpSetOperation(VariableBinding[] vars) throws IOException {
        PDU setPdu = new ScopedPDU();
        for (VariableBinding variableBinding : vars) {
            setPdu.add(variableBinding);
        }
        return snmp.send(setPdu, target);
    }

    public ResponseEvent snmpGetOperation(OID oid) throws IOException {

        if (encryption) {
            PDU getPdu = new ScopedPDU();
            getPdu.add(new VariableBinding(oid));
            getPdu.setType(ScopedPDU.GET);
            return snmp.get(getPdu, target);

        } else {
            PDU getPdu = new PDU();
            getPdu.add(new VariableBinding(oid));
            getPdu.setType(PDU.GET);
            return snmp.get(getPdu, v1target);

        }

    }

    private UserTarget createUserTarget() {
        UserTarget target = new UserTarget();
        target.setAddress(nmsIP);
        target.setRetries(noOfRetries);
        target.setTimeout(timeOut);
        target.setVersion(SnmpConstants.version3);
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(new OctetString(securityName));
        return target;
    }

    private CommunityTarget createUserTargetWithoutEncryption() {
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(nmsIP);
        target.setRetries(noOfRetries);
        target.setTimeout(timeOut);
        target.setVersion(SnmpConstants.version1);
        return target;
    }

    public long getTimeOut() {
        return timeOut;
    }

    public void setTimeOut(long timeOut) {
        this.timeOut = timeOut;
    }

    public int getNoOfRetries() {
        return noOfRetries;
    }

    public void setNoOfRetries(int noOfRetries) {
        this.noOfRetries = noOfRetries;
    }
}
有人知道我做错了什么吗

编辑:

从servers syslog中,我可以看到请求到达了资源:

Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161
Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161

@我觉得你做的一切都很好

代码中唯一的问题可能就是计算
响应
变量的行。您正在指示
响应!=空
当它实际上应该是
响应==null时
。我的意思是:

import org.snmp4j.PDU;
导入org.snmp4j.ScopedPDU;
导入org.snmp4j.Snmp;
导入org.snmp4j.Target;
导入org.snmp4j.event.ResponseEvent;
导入org.snmp4j.mp.SnmpConstants;
导入org.snmp4j.security.AuthMD5;
导入org.snmp4j.security.AuthSHA;
导入org.snmp4j.security.PrivAES128;
导入org.snmp4j.security.PrivDES;
导入org.snmp4j.smi.OID;
导入org.snmp4j.smi.VariableBinding;
公共类侦听器{
公共静态void main(字符串[]args){
ServerStatusHelper代理=新的ServerStatusHelper(“host.tld”、“udp”、161、“demo”、“demo”,
“通过”、“通过”、新AuthMD5()、新PrivDES()、true);
试一试{
agent.startAgent();
ResponseEvent事件=agent.snmpGetOperation(SnmpConstants.sysUpTime);
最终PDU响应=event.getResponse();
如果(响应==null){
System.out.println(
响应null-错误:“+event.getError()+
“peerAddress:+事件。getPeerAddress()+
“源:”+event.getSource().toString()+
请求:“+event.getRequest());
}否则{
System.out.println(“Response PDU:+Response.toString());
//根据需要处理响应,可能是这样的:
long sysUpTime=response.get(0.getVariable().toLong();
//您可以在图书馆的javadocs中找到相关信息:
// https://agentpp.com/doc/snmp4j/index.html?org/snmp4j/package-summary.html
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}

这就是为什么您在java代码中没有收到错误,并且您的系统日志表明请求实际上已发送。

不幸的是,这并不能解决问题。响应对象不包含错误或实际的snmp响应。但是@I.Shm,程序输出是什么?出现任何异常?如原始问题中所述,程序输出为以下NMS IP集:*IPREMOVED**/161 UDP协议selected。响应null-错误:nullpeer地址:**IPREMOVED**/161source:org.snmp4j。Snmp@e580929请求:GET[{contextEngineID=80:00:1f:88:80:5e:2e:49:07:2f:68:44:57:00:00:00:00:00,contextName=},requestID=588252045,errorStatus=0,errorIndex=0,VBS[1.3.6.1.2.1.3.0=Null]]
Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161
Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161