当前位置: 首页 > 工具软件 > SNMP4J > 使用案例 >

3.x版本snmp4j实例

公西承
2023-12-01

3.x版本snmp4j实例

3.x版本之后使用v3协议总是会报错,提示not support Security level。查询资料发现是作者考虑安全性,去掉了一些默认设置,需要手动添加。

        // 3.x版本之后默认不开启,需要手动开启,否则会报not support Security level,手动加入加密密码和加密协议
        SecurityProtocols instance = SecurityProtocols.getInstance();
        instance.addAuthenticationProtocol(new AuthSHA());
        instance.addAuthenticationProtocol(new AuthMD5());
        instance.addPrivacyProtocol(new PrivAES128());
        instance.addPrivacyProtocol(new PrivAES256());

实例代码:

package com.test.boot.bean;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 演示
 *
 * @author DELL
 * @date 2022/12/23
 */
@Slf4j
public class MultiThreadedWalkDemo {
    private static final Logger LOGGER = LogManager.getLogger(MultiThreadedWalkDemo.class);
    /**
     * 用户名
     */
    private String username = "m********er";
    /**
     * 身份验证密码,鉴权密码
     */
    private String authPassword = "Te****************";
    /**
     * 数据加密密码
     */
    private String privPassword = "T********!";
    /**
     * trap地址
     */
    private String address = "udp:********/162";
    /**
     * get 地址
     */
    private String addressGet = "udp:********/161";

    /**
     * 团体名
     */
    private String publicName = "*********";
//    private String publicName = "********";

    public Snmp snmp;

    public MultiThreadedWalkDemo() {

    }


    public void initSnmp() throws IOException {
        //1、初始化多线程消息转发类
        MessageDispatcher messageDispatcher = new MessageDispatcherImpl();
        //其中要增加三种处理模型。如果snmp初始化使用的是Snmp(TransportMapping<? extends Address> transportMapping) ,就不需要增加
        messageDispatcher.addMessageProcessingModel(new MPv1());
        messageDispatcher.addMessageProcessingModel(new MPv2c());

        // 3.x版本之后默认不开启,需要手动开启,否则会报not support Security level,手动加入加密密码和加密协议
        SecurityProtocols instance = SecurityProtocols.getInstance();
        instance.addAuthenticationProtocol(new AuthSHA());
        instance.addAuthenticationProtocol(new AuthMD5());
        instance.addPrivacyProtocol(new PrivAES128());
        instance.addPrivacyProtocol(new PrivAES256());


        //当要支持snmpV3版本时,需要配置user
        OctetString localEngineID = new OctetString(MPv3.createLocalEngineID());
        USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), localEngineID, 0);

        OctetString userName1 = new OctetString(username);
        OctetString authPass = new OctetString(authPassword);
        OctetString privPass = new OctetString(privPassword);
//        UsmUser user = new UsmUser(userName1, AuthMD5.ID, authPass, PrivAES128.ID, privPass);
        // 根据自己的加密协议设置需要的认证协议和加密协议
        UsmUser user = new UsmUser(userName1, AuthSHA.ID, authPass, PrivAES128.ID, privPass);

        usm.addUser(user.getSecurityName(), user);
        messageDispatcher.addMessageProcessingModel(new MPv3(usm));
        //2、创建transportMapping  ip为本地ip,可以不设置
        TransportMapping<?> transportMapping = new DefaultUdpTransportMapping();
//        UdpAddress updAddr = (UdpAddress) GenericAddress.parse("udp:172.29.12.95/161");
//        TransportMapping<?> transportMapping = new DefaultUdpTransportMapping(updAddr);
        //3、正式创建snmp
        snmp = new Snmp(messageDispatcher, transportMapping);
        //开启监听
        snmp.listen();

    }

    private Target createTarget(String oid, int version) {
        Target target = null;
//        int version = 1;
        if (!(version == SnmpConstants.version3 || version == SnmpConstants.version2c || version == SnmpConstants.version1)) {
            //log.error("参数version异常");
            return target;
        }
        if (version == SnmpConstants.version3) {
            target = new UserTarget();
            //snmpV3需要设置安全级别和安全名称,其中安全名称是创建snmp指定user设置的new OctetString("SNMPV3")
            target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
            target.setSecurityName(new OctetString(this.username));
        } else {
            //snmpV1和snmpV2需要指定团体名名称
            target = new CommunityTarget();
//            ((CommunityTarget) target).setCommunity(new OctetString(this.username));
            ((CommunityTarget) target).setCommunity(new OctetString(publicName));
            if (version == SnmpConstants.version2c) {
                target.setVersion(SnmpConstants.version2c);
                target.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv2c);
            }
        }
        target.setVersion(version);
        //必须指定,没有设置就会报错。
        target.setAddress(GenericAddress.parse(this.addressGet));
        target.setRetries(3);
        target.setTimeout(2000);
        return target;
    }

    private static PDU createPDU(int version, int type, String oid) {
        PDU pdu = null;
        if (version == SnmpConstants.version3) {
            pdu = new ScopedPDU();
        } else {
            pdu = new PDUv1();
        }
        pdu.setType(type);
        //可以添加多个变量oid
        /*for(String oid:oids){
            pdu.add(new VariableBinding(new OID(oid)));
        }*/
        pdu.add(new VariableBinding(new OID(oid)));
        return pdu;
    }


    /**
     * WALK方式请求
     *
     * @param oid
     */
    public void snmpWalk(String oid, int version) {
        try {
            LOGGER.info("first way:");
            List<Map> list = new ArrayList<Map>();
            //1、初始化snmp,并开启监听
            initSnmp();
            //2、创建目标对象
            Target target = createTarget(oid, version);
            //3、创建报文
//            PDU pdu = createPDU(1, PDU.GETNEXT, oid);
            PDU pdu = createPDU(version, PDU.GETNEXT, oid);
            //4、发送报文,并获取返回结果
            boolean matched = true;
            while (matched) {
                ResponseEvent responseEvent = snmp.send(pdu, target);
//                ResponseEvent responseEvent = snmp.getNext(pdu, target);
                if (responseEvent == null || responseEvent.getResponse() == null) {
                    System.out.println("TimeOut...");
                    break;
                }
                PDU response = responseEvent.getResponse();
                String nextOid = null;
                List<? extends VariableBinding> vbs = response.getVariableBindings();
                for (VariableBinding variableBinding : vbs) {
                    Map map = new HashMap();
                    Variable variable = variableBinding.getVariable();
                    nextOid = variableBinding.getOid().toDottedString();
//                    System.out.println("oid:" + nextOid + ",value:"  + variable);
                    //如果不是这个节点下的oid则终止遍历,否则会输出很多,直到整个遍历完。
                    if (!nextOid.startsWith(oid)) {
                        matched = false;
                        break;
                    }
                    map.put("oid", nextOid);
                    map.put("value", variable);
                    list.add(map);
                    System.out.println("oid:" + nextOid + ",value:" + variable);
                    LOGGER.info("oid:" + nextOid + ",value:" + variable);
                }
                if (!matched) {
                    break;
                }
                pdu.clear();
                pdu.add(new VariableBinding(new OID(nextOid)));
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //开启监控的main方法。
    public static void main(String[] args) throws IOException, InterruptedException {
        MultiThreadedWalkDemo multithreadedtrapreceiver = new MultiThreadedWalkDemo();
        multithreadedtrapreceiver.run();
//        Thread.sleep(5000);
//        multithreadedtrapreceiver.run();
    }

    public void run() {
        try {
            LOGGER.info("开始监听walk信息!");
//            LOGGER.info("开始获取端口名称!");
//              String healthOID1 = "1.3.6.1.2.1.2.2.1.2.0";
            String healthOID1 = "1.3.6.1.2.1.2.2.1.2";
//            this.snmpWalk(healthOID1);
//            LOGGER.info("网口流量");
//            String healthOID2 = "1.3.6.1.2.1.2.2.1.10.0";
//            this.snmpWalk(healthOID2);
//            LOGGER.info("网口状态");
//            String healthOID3 = "1.3.6.1.2.1.2.2.1.16.0";
//            this.snmpWalk(healthOID3);
//            LOGGER.info("网口速率");
            String healthOID4 = "1.3.6.1.2.1.2.2.1.16";
//            String healthOID4 = "1.3.6.1.2.1.2.2.1.5";
//            String healthOID4 = "1.3.6.1.2.1.2.2.1.16";
//            String healthOID4 = "1.3.6.1.2.1.2.2.1.3";
            // v3版本
            this.snmpWalk(healthOID4, 3);
//            LOGGER.info("网口速率");
//            String healthOID5 = "1.3.6.1.2.1.31.1.1.1.15";
//            this.snmpWalk(healthOID5);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


}
 类似资料: