snmp协议开发之 SNMP4J-SNMPv3

转载 2015年07月09日 14:18:29
对于SNMPv3,不同点有
1) 需要创建USM对象并添加User, 
关于USM->http://blog.csdn.net/fw0124/article/details/8557029
2) 需要创建UserTarget对象,而不是创建CommunityTarget对象。
3) 需要创建ScopedPDU对象,而不是PDU对象。

使用SNMP4J进行SNMPv3编程的步骤如下:
1) 创建Snmp对象snmp

2) 创建USM对象,并创建User,添加到USM对象中。
创建User是需要指定securityName,认证协议MD5/SHA1,认证密钥,加密算法DES/AES,加密密钥。
添加User到USM对象中时候,可以指定engineID也可以不指定。

3) 创建UserTarget对象target,并指定version, address, timeout, retry等参数,这些和SNMPv1/v2相同。
另外还必须指定SNMPv3特有的两个参数SecurityLevel和SecurityName。
SNMP4J会根据这个SecurityName到USM的UserTable中查找匹配的User,用这个User的信息进行认证加密处理。
查找的时候必须同时匹配SecurityName和engineID,但是如果添加User到USM对象中时候,没有指定engineID,那么SecurityName相同即匹配成功。

4) 创建ScopedPDU对象pdu,并指定操作类型(GET/GETNEXT/GETBULK/SET), 添加VariableBinding(也就是待操作的OID),
如果是GETBULK操作,还可以指定MaxRepetitions和NonRepeaters。
注意一定要指定MaxRepetitions,默认值是0,那样不会返回任何结果。
如果agent上设定的contextEngineId和snmpEngineId不一致,那么需要调用ScopedPDU.setContextEngineID()方法设定contextEngineId。
如果agent上设定了contextName,那么需要调用ScopedPDU.setContextName()方法设定contextName。
 
5) 调用snmp.send(pdu, target)方法,发送请求请返回结果。

对于SNMPv3,仍然可以调用TableUtils类实现一个SNMP Walk的功能。
但是如果需要指定contextEngineId和contextName, 那么不能使用DefaultPDUFactory,可以从它继承并覆盖它的createPDU方法。
异步的send方法支持和SNMPv1/v2类似。

下面的代码实例实现了GET, Walk操作, 其他GETNEXT, GETBULK, SET操作类似。

import java.io.IOException;
import java.util.List;
import java.util.Vector;

import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
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.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TableEvent;
import org.snmp4j.util.TableUtils;

public class SNMPv3Test {
	public static void main(String[] args) throws IOException, InterruptedException {
		
		Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
		USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
		SecurityModels.getInstance().addSecurityModel(usm);
		snmp.listen();
		
		// Add User
		UsmUser user = new UsmUser(
				new OctetString("nmsAdmin"),
				AuthMD5.ID, new OctetString("nmsAuthKey"),
				PrivDES.ID, new OctetString("nmsPrivKey"));
		//If the specified SNMP engine id is specified, this user can only be used with the specified engine ID
		//So if it's not correct, will get an error that can't find a user from the user table.
		//snmp.getUSM().addUser(new OctetString("nmsAdmin"), new OctetString("0002651100"), user);
		snmp.getUSM().addUser(new OctetString("nmsAdmin"), user);
		
		UserTarget target = new UserTarget();
		target.setVersion(SnmpConstants.version3);
		target.setAddress(new UdpAddress("192.168.0.100/161"));
		target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
		target.setSecurityName(new OctetString("nmsAdmin"));
		target.setTimeout(3000);	//3s
		target.setRetries(0);
				
		OctetString contextEngineId = new OctetString("0002651100[02]");
		sendRequest(snmp, createGetPdu(contextEngineId), target);
		snmpWalk(snmp, target, contextEngineId);
	}
	
	private static PDU createGetPdu(OctetString contextEngineId) {
		ScopedPDU pdu = new ScopedPDU();
		pdu.setType(PDU.GET);
		pdu.setContextEngineID(contextEngineId);	//if not set, will be SNMP engine id
		//pdu.setContextName(contextName);  //must be same as SNMP agent
		
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.3.0")));	//sysUpTime
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.5.0")));	//sysName
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.5")));	//expect an no_such_instance error
		return pdu;
	}
	
	private static void sendRequest(Snmp snmp, PDU pdu, UserTarget target)
	throws IOException {
		ResponseEvent responseEvent = snmp.send(pdu, target);
		PDU response = responseEvent.getResponse();
		
		if (response == null) {
			System.out.println("TimeOut...");
		} else {
			if (response.getErrorStatus() == PDU.noError) {
				Vector<? extends VariableBinding> vbs = response.getVariableBindings();
				for (VariableBinding vb : vbs) {
					System.out.println(vb + " ," + vb.getVariable().getSyntaxString());
				}
			} else {
				System.out.println("Error:" + response.getErrorStatusText());
			}
		}
	}
	
	private static void snmpWalk(Snmp snmp, UserTarget target, OctetString contextEngineId) {
		TableUtils utils = new TableUtils(snmp,
				new MyDefaultPDUFactory(PDU.GETNEXT, //GETNEXT or GETBULK)
										contextEngineId));
		utils.setMaxNumRowsPerPDU(5);	//only for GETBULK, set max-repetitions, default is 10
		OID[] columnOids = new OID[] {
				new OID("1.3.6.1.2.1.1.9.1.2"),	//sysORID
				new OID("1.3.6.1.2.1.1.9.1.3")	//sysORDescr
		};
		// If not null, all returned rows have an index in a range (lowerBoundIndex, upperBoundIndex]
		List<TableEvent> l = utils.getTable(target, columnOids, new OID("3"), new OID("10"));
		for (TableEvent e : l) {
			System.out.println(e);
		}
	}
	
	private static class MyDefaultPDUFactory extends DefaultPDUFactory {
		private OctetString contextEngineId = null;
		
		public MyDefaultPDUFactory(int pduType, OctetString contextEngineId) {
			super(pduType);
			this.contextEngineId = contextEngineId;
		}

		@Override
		public PDU createPDU(Target target) {
			PDU pdu = super.createPDU(target);
			if (target.getVersion() == SnmpConstants.version3) {
				((ScopedPDU)pdu).setContextEngineID(contextEngineId);
			}
			return pdu;
		}		
	}
}


使用Java进行SNMP编程-SNMP4J-SNMPv3-代码实例

使用SNMP4J可以很方便的实现一个SNMP NMS的功能。 前一篇介绍了SNMPv1/v2的编程 http://blog.csdn.net/fw0124/article/details/85595...
  • fw0124
  • fw0124
  • 2013年01月31日 15:12
  • 16220

SNMP4J 发送Trap v1 v2c v3

import java.io.IOException; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import ...
  • Raysen
  • Raysen
  • 2014年10月11日 04:36
  • 2102

Snmp学习总结(三)-SNMP4J介绍

一、SNMP4J介绍     SNMP4J是一个用Java来实现SNMP(简单网络管理协议)协议的开源项目.它支持以命令行的形式进行管理与响应。SNMP4J是纯面向对象设计与SNMP++(用C+...
  • xiaomu709421487
  • xiaomu709421487
  • 2016年03月28日 16:03
  • 707

使用Java进行SNMP编程-SNMP4J-SNMPv3-代码实例

转载:http://blog.csdn.net/fw0124/article/details/8559803 使用SNMP4J可以很方便的实现一个SNMP NMS的功能。 前一篇介绍了SNMP...
  • u010046887
  • u010046887
  • 2015年05月20日 08:53
  • 1016

专业级的SNMP框架---SNMP4J

SNMP4J简介 相比SNMP PACKAGE API 比较低的门槛和简单的功能,SNMP4J则是完全专业级的框架.他的SNMP-TARGET-PDU的三点结构更科学更严谨,完善的PDU数据引擎也...
  • ytzyg
  • ytzyg
  • 2011年09月21日 11:29
  • 1693

snmp4j介绍

snmp4j介绍
  • DaveBobo
  • DaveBobo
  • 2016年05月31日 23:17
  • 850

SNMP4J编程最重要的三个类之Snmp

 Snmp类是SNMP4J的核心,它提供了发送和接收SNMP PDUs的方法,所有的SNMP PDU类型都可以采用同步或者异步的方式被发送。 Snmp采用独立的传输协议,通过Transport...
  • jijian_jinan
  • jijian_jinan
  • 2015年01月22日 10:46
  • 584

SNMPv3基于用户的安全模型USM(2)

SNMPv3 Message Format 一个SNMPv3的Message包括以下部分: 1) msgVersion 2) msgID 3) msgMaxSize 发送方支持的最大消息长度/the...
  • fw0124
  • fw0124
  • 2013年01月31日 13:18
  • 8152

snmpv3 java实现

  • 2013年10月03日 10:30
  • 3.36MB
  • 下载

使用Java进行SNMP编程-SNMP4J-代码实例

  • 2018年01月18日 15:51
  • 121KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:snmp协议开发之 SNMP4J-SNMPv3
举报原因:
原因补充:

(最多只允许输入30个字)