用snmp4j開發網管應用(二) -- 使用snmp4j
SNMP協議還算簡單
其實針對協議的開發我們隻要知道協議的內容,然後架起Socket服務器,然後用字符串拚出協議內容格式的字符串,使用Socket進行通信就好了。
針對協議的開源包主要把這些過程封裝了。比如SNMP協議。
我們隻需要針對PDU對象編程,然後SNMP4j就會把PDU對象轉化為SNMP4j協議的格式,進行BER編碼,然後傳輸,最後解碼,再翻譯為PDU對象。
先看一下SNMP協議要傳輸的內容:
https://www.cnpaf.net/Class/SNMP/200408/43.html
這個文章中說的很全和好了。接下來就是用SNMP4J協議的jar包來完成各個功能。
https://www.snmp4j.org/html/download.html
在這個網址中下載最新的SNMP4J的jar包,
或者是這個鏈接下載https://download.csdn.net/detail/three_man/7478029
順便可以把SNMP4J-Agent-2.2-Instrumentation-Guide.pdf 這個文檔描述了對Agent進行開發。
這個文檔的下載鏈接:https://download.csdn.net/detail/three_man/7477953
SNMP4J把開發包分為了兩個,一個SNMP4J.jar主要負責get,trap,set,一個是SNMP4J-Agent.jar主要負責作為一個網元被管理。
1 首先說一下怎麼開發一個Agent.
需要用到兩個配置文件bc和cfg文件,可以在這裏下載:https://download.csdn.net/detail/three_man/7477991
大概的代碼為:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.snmp4j.agent.BaseAgent;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.io.ImportModes;
import org.snmp4j.agent.mo.DefaultMOTable;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.snmp.RowStatus;
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
import org.snmp4j.agent.mo.snmp.StorageType;
import org.snmp4j.agent.mo.snmp.VacmMIB;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;
public class MyAgent extends BaseAgent {
private List<DefaultMOTable> moTables = new ArrayList<DefaultMOTable>();
private String community;
protected MyAgent(File bootCounterFile, File configFile, List<DefaultMOTable> moTables, String community) {
super(bootCounterFile, configFile, new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
this.moTables = moTables;
this.community = community;
}
@Override
protected void registerManagedObjects() {
try {
for (DefaultMOTable table : moTables) {
server.register(table, null);
}
} catch (DuplicateRegistrationException e) {
e.printStackTrace();
}
}
public void startUp(){
try {
this.init();
} catch (IOException e) {
e.printStackTrace();
}
this.loadConfig(ImportModes.REPLACE_CREATE);
this.addShutdownHook();
this.getServer().addContext(new OctetString(community));
this.finishInit();
this.run();
this.sendColdStartNotification();
}
/**
* to set community
*/
@Override
protected void addCommunities(SnmpCommunityMIB communityMIB) {
Variable[] com2sec = new Variable[] {
new OctetString(community), // community name
new OctetString("cpublic"), // security name
getAgent().getContextEngineID(), // local engine ID
new OctetString(community), // default context name
new OctetString(), // transport tag
new Integer32(StorageType.nonVolatile), // storage type
new Integer32(RowStatus.active) // row status
};
MOTableRow row =
communityMIB.getSnmpCommunityEntry().createRow(
new OctetString("public2public").toSubIndex(true), com2sec);
communityMIB.getSnmpCommunityEntry().addRow(row);
}
}
- 主要的代碼是需要繼承BaseAgent
- 需要設置community
- 需要注冊Table,這個注冊中的內容將是供給get和walk的內容。
- 可以從MIB直接構建Agent,可能需要的包為:mibble-mibs是能夠獨MIB結構。這個也提供個下載地址吧: https://download.csdn.net/detail/three_man/7478061
2. Trap Receiver
import java.io.IOException;
import java.util.logging.Logger;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.util.Configure;
import com.prince.snmp.tool.util.Const;
/**
* 構建一個多線程的Trap Receiver
* @author wangzijian
*
*/
public class SnmpReceiver implements Command{
private final Logger log = Logger.getLogger(SnmpReceiver.class.getName());
@Override
public void startUp() throws IOException {
log.info("Snmp Trap Receiver Start");
log.info("listened on " + Configure.getInstance().getUdpTrapIpPort());
ThreadPool pool = ThreadPool.create(Const.THREAD_POOL_NAME, Const.AGENT_THREAD_NUM);
MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(pool, new MessageDispatcherImpl());
Address listenAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
TransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);
// 構建SNMP,並且使其開始監聽
Snmp snmp = new Snmp(dispatcher, transport);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.listen();
snmp.addCommandResponder(new CommandResponderImpl());
}
}
package com.prince.snmp.tool.receiver;
import java.util.List;
import java.util.logging.Logger;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.PDU;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
public class CommandResponderImpl implements CommandResponder {
private final Logger log = Logger.getLogger(CommandResponderImpl.class.getName());
@Override
public void processPdu(CommandResponderEvent event) {
PDU pdu = event.getPDU();
if(PDU.TRAP == pdu.getType()){
operate(pdu);
}else{
log.info("pdu method is:" + pdu.getType() + " not a trap");
}
}
private void operate(PDU pdu) {
List<VariableBinding> bindings = pdu.getBindingList(new OID(".1"));
for (VariableBinding binding : bindings) {
System.out.println(binding.getOid() + "====" + binding.getVariable().toString());
}
}
}
- 需要一個多線程的服務器MultiThreadedMessageDispatcher
- 還需要一個處理類 CommandResponderImpl snmp.addCommandResponder
- 在處理類中能夠得到PDU,這個類不隻可以作為Receiver還能夠開發為Agent,但是需要自己來寫很多邏輯,還有可能用到文件或者內存數據庫
package com.prince.snmp.tool.trap;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Vector;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.trap.dataGenerator.ITrapGenerator;
import com.prince.snmp.tool.util.Configure;
public class TrapSender implements Command{
private Snmp snmp;
private Address targetAddress;
private ITrapGenerator generator;
public TrapSender(ITrapGenerator generator) {
this.generator = generator;
targetAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
TransportMapping<UdpAddress> transport = null;
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
transport.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendTrap(){
CommunityTarget target = new CommunityTarget();
target.setAddress(targetAddress);
target.setRetries(Configure.getInstance().getRetries());
target.setTimeout(Configure.getInstance().getTimeOut());
target.setCommunity(new OctetString(Configure.getInstance().getCommunity()));
target.setVersion(Configure.getInstance().getSnmpVersion());
List<TrapData> datas = generator.generateTrapData();
try {
for (TrapData trapData : datas) {
sendPdu(trapData, target);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendPdu(TrapData trapData, CommunityTarget target) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException {
PDU pdu = MoToPdu.moToPdu(trapData);
ResponseEvent respEvnt = snmp.send(pdu, target);
// 解析Response
if (respEvnt != null && respEvnt.getResponse() != null) {
Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
}
- trap主要注意必須設置兩個VariableBingding
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(trap.getSysUpTime())));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(trap.getTrapOid())))
4. getprivate static void simpleGet() throws IOException {
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
transport.listen();
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("CONV"));
Address targetAddress = GenericAddress.parse("udp:10.141.43.237/161");
target.setAddress(targetAddress);
target.setRetries(3);
target.setTimeout(3000);
target.setVersion(SnmpConstants.version2c);
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.7569.1.2.1.23.3.1")));
pdu.setType(PDU.GETBULK);
pdu.setMaxRepetitions(20);
pdu.setNonRepeaters(0);
ResponseEvent respEvnt = snmp.send(pdu, target);
if (respEvnt != null && respEvnt.getResponse() != null) {
Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
- get相對於比較簡單,資料也比較多。主要是設定pdu.setType(PDU.GETBULK);
- 利用getnext和一些判斷可以實現walk.
- https://blog .sina.com.cn/s/blog_6cb15f8f0100yx4p.html 這個哥們兒寫得非常好
具體的代碼沒有寫,因為下一篇會共享一個小的工具,可以以配置文件為基礎來構建Receiver,發送Trap,構建Agent等。
最後更新:2017-04-03 07:56:58
上一篇:
HTTPS (HTTP Secure)
下一篇:
linux c語言 select函數用法
HD文件管理器 v0.1.3----- 一款界麵簡約,功能強大的免費文件管理器(Android)
開發人員和設計師應該安裝的10個Android應用
??????????????????????????????Oracle Sharding????????????????????????-??????-????????????-?????????
Shark簡介、部署及編譯小結
如何修複Kindle頻繁自動鎖屏和解鎖
簡單的Android之apk包反編譯方法
雲台與廣角,網絡攝像頭的技術之爭
【java設計模式初探】之單例模式
Eclipse插件開發 獲取Workspace下所有的項目
HiStore:阿裏巴巴海量數據場景下的OLAP解決方案