SNMP基于java的最详细实现

简介

简单网络管理协议 (SNMP) 是一种互联网标准协议,用于收集和组织有关 IP 网络上托管设备的信息,并修改该信息以更改设备行为。通常支持 SNMP 的设备包括电缆调制解调器、路由器、交换机、服务器、工作站、打印机等

在这里插入图片描述

引入

通常使用snmp4j进行操作,JDK8最高支持2.8.18

       <dependency>
            <groupId>org.snmp4j</groupId>
            <artifactId>snmp4j</artifactId>
            <version>2.8.18</version>
        </dependency>

Get/Walk

  • v1/v2c
        UdpAddress udpAddress = new UdpAddress(InetAddress.getByName(host), 161);
        CommunityTarget target = new CommunityTarget();
        //SnmpConstants.version1或SnmpConstants.version2c
        target.setVersion(SnmpConstants.version1);
        target.setAddress(udpAddress);
        target.setCommunity(new OctetString(community));
        target.setTimeout(5000);
        target.setRetries(3);
        PDU pdu = new PDU();
        pdu.setType(PDU.GET);
        //要查询的oid
        pdu.add(new VariableBinding(new OID(oid)));
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
        try {
            snmp.listen();
            ResponseEvent respEvent = snmp.send(pdu, target);
            PDU response = respEvent.getResponse();
            //get或是walk
            response.getVariableBindings().forEach(variableBinding -> {
                ...variableBinding
            });
        } finally {
            snmp.close();
        }
  • v3
        UdpAddress udpAddress = new UdpAddress(InetAddress.getByName(host), 161);
        UserTarget target = new UserTarget();
        target.setVersion(SnmpConstants.version3);
        target.setAddress(udpAddress);
        //SecurityLevel.NOAUTH_NOPRIV无认证与加密 SecurityLevel.AUTH_NOPRIV 有认证无加密 SecurityLevel.AUTH_PRIV有认证有加密
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(new OctetString(username));
        target.setTimeout(5000);
        target.setRetries(3);
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
        try {
            //如果存在多次调用的情况需要提取为静态代码
            SecurityModels.getInstance().addSecurityModel(new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0));
            snmp.listen();
            snmp.getUSM().addUser(new OctetString(username), new UsmUser(new OctetString(username),
                    AuthMD5.ID, new OctetString(password), PrivDES.ID, new OctetString(privPassword)));
            PDU pdu = new ScopedPDU();
            //要查询的oid
            pdu.add(new VariableBinding(new OID(oid)));
            pdu.setType(PDU.GET);
            ResponseEvent respEvent = snmp.send(pdu, target);
            PDU response = respEvent.getResponse();
            //get或是walk
            response.getVariableBindings().forEach(variableBinding -> {
                ...variableBinding
           });
        } finally {
           snmp.close();
        }

请注意,v3版本需要添加安全模型,但如果存在多次或多线程调用的情况,每次创建snmp对象都添加安全模型有概率出现异常:

Message processing model 3 returned error: Unknown security name

原因是多次创建绑定了安全模型,因此,可以通过静态代码块中绑定来避免此问题(问题方案

    private static final USM USM;
    static {
        USM = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
        SecurityModels.getInstance().addSecurityModel(USM);
    }

Trap

  • 发送
    trap发送基本与get/walk代码相同,只是发送的类型转变为了PDU.TRAP
        pdu.setType(PDU.TRAP)
  • 接收
        ThreadPool threadPool = ThreadPool.create("Trap", 2);
        MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());
        Snmp snmp = new Snmp(dispatcher);
        try {
            UdpAddress address = new UdpAddress(InetAddress.getByName(host), 162);;
            TransportMapping<?> transport = new DefaultUdpTransportMapping(address);
            snmp.addTransportMapping(transport);
            USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
            SecurityProtocols.getInstance().addDefaultProtocols();
            //v3版本需要配置
            snmp.getUSM().addUser(new OctetString(username), new UsmUser(new OctetString(username),
                    AuthMD5.ID, new OctetString(password), PrivDES.ID, new OctetString(privPassword)));
            snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
            snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
            snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3(usm));
            snmp.listen();
            snmp.addCommandResponder((event) -> {
                //解析event获取trap
                event.getPDU()...
            });
        } finally {
            snmp.close();
        }

目前常用的加密协议有DES,AES128,AES192,AES256,如果需要使用超过128位的AES加密,需将local_policy.jarUS_export_policy.jar下载地址)放置到jre的目录内(/usr/java/jdk1.8.x_xx/jre/lib/security/)问题方案

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值