snmp的学习与snmp4j的一些api使用

最近项目在做对网络设备的管理,所以写一篇文章是项目中snmp的一些使用心得。

一、SNMP简介

SNMP指的是简单网络管理协议。它属于TCP/IP五层协议中的应用层协议。它提供了一种简单和方便的模式来管理网络中的各个元素。这里的元素就是各个被管理的对象,可以是因特网中的某个硬件,比如网卡,也可以是某些硬件和软件的配置参数的集合。由于SNMP协议简单可靠 ,受到了众多厂商的欢迎,成为了目前最为广泛的网管协议。

SNMP协议主要由两大部分构成:SNMP管理站和SNMP代理。SNMP管理站是一个中心节点,负责收集维护各个SNMP元素的信息,并对这些信息进行处理,最后反馈给网络管理员;而SNMP代理是运行在各个被管理的网络节点之上,负责统计该节点的各项信息,并且负责与SNMP管理站交互,接收并执行管理站的命令,上传各种本地的网络信息。

SNMP管理站和SNMP代理之间是松散耦合。他们之间的通信是通过UDP协议完成的。一般情况下,SNMP管理站通过UDP协议向SNMP代理发送各种命令,当SNMP代理收到命令后,返回SNMP管理站需要的参数。但是当SNMP代理检测到网络元素异常的时候,也可以主动向SNMP管理站发送消息,通告当前异常状况。

SNMP协议于1988年发布。到目前一共经历了V1V2V3三个版本。其中V1已经被废弃,而V2c虽然没有能够成为正式标准,但是已经被很多厂家所接受,V3目前是因特网的正式标准。与V1相比,V2V3更能适应大规模的网络管理,而且在安全方面有了较大的改进。

二一、Win7开启SNMP服务 

通过SNMP监控Windows主机需要在被监控的服务器上安装简单网络管理协议(SNMP)的Windows组件,以Windows 7系统为例:
首先,在控制面板中找到“卸载程序”;


在弹出的窗口中单击“打开或关闭Windows功能”;

 

勾选弹出窗口中的“简单网络管理协议(SNMP)”项后单击“确定”并根据提示完成安装即可。

 snmp的学习与snmp4j的一些api使用_第1张图片

完成SNMP服务的安装后,右键单击“计算机”选择“管理”

 snmp的学习与snmp4j的一些api使用_第2张图片


在弹出的“计算机管理”窗口中左侧导航栏中找到“服务”,并在右侧找到“SNMP Service”项;

 snmp的学习与snmp4j的一些api使用_第3张图片

鼠标双击“SNMP Service”选项,在弹出的窗口中切换到“安全”选项卡中,如上图添加“接受的社区名称”和接收那些主机发出的SNMP数据包。

 snmp的学习与snmp4j的一些api使用_第4张图片

“接受的社区名称”是自己定义的任意字符都可以,接收那些主机发出的SNMP数据包定义成你的Nagios服务器即可。到这里被监控端的Windows主机的SNMP服务就配置完成了。


二二、Linux


1、检查是否有SNMP服务,若没有,请先安装

service snmpd status  #查看是否安装snmp

yum install -y net-snmp* #若没安装,则安装

2、先编辑Snmp的配置文件,设置安全的验证方式

vi /etc/snmp/snmpd.conf

3、设置完毕,开关SNMP

service snmpd start

service snmpd stop

 

4、设置SNMP开机自动启动

chkconfig snmpd on

chkconfig snmpd off

5、增强的SNMP安全性

/etc/sysconfig/iptables 中

iptables -A INPUT  -p udp -s 192.168.2.18 --dport 161 -j ACCEPT

service iptables save

以上做的目的,就是只让指定的监控服务器(IP)才能与您的SNMP服务建立连接。

 

三、snmp4j例子

准备工作:snmp4j的jar包可以在它的官方网站http://www.snmp4j.org/上下载

1、获取CPU利用率方法

//获取cpu使用率
public static void collectCPU() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] oids = {"1.3.6.1.2.1.25.3.3.1.2"};
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);//创建snmp
snmp.listen();//监听消息
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
int percentage = 0;
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values != null) 
percentage += Integer.parseInt(values[0].getVariable().toString());
}
System.out.println("CPU利用率为:"+percentage/list.size()+"%");
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


2、获取内存信息方法

//获取内存相关信息
public static void collectMemory() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] oids = {"1.3.6.1.2.1.25.2.3.1.2",  //type 存储单元类型
     "1.3.6.1.2.1.25.2.3.1.3",  //descr
     "1.3.6.1.2.1.25.2.3.1.4",  //unit 存储单元大小
     "1.3.6.1.2.1.25.2.3.1.5",  //size 总存储单元数
     "1.3.6.1.2.1.25.2.3.1.6"}; //used 使用存储单元数;
String PHYSICAL_MEMORY_OID = "1.3.6.1.2.1.25.2.1.2";//物理存储
String VIRTUAL_MEMORY_OID = "1.3.6.1.2.1.25.2.1.3"; //虚拟存储
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);//创建snmp
snmp.listen();//监听消息
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
int unit = Integer.parseInt(values[2].getVariable().toString());//unit 存储单元大小
int totalSize = Integer.parseInt(values[3].getVariable().toString());//size 总存储单元数
int usedSize = Integer.parseInt(values[4].getVariable().toString());//used  使用存储单元数
String oid = values[0].getVariable().toString();
if (PHYSICAL_MEMORY_OID.equals(oid)){
System.out.println("PHYSICAL_MEMORY----->物理内存大小:"+(long)totalSize * unit/(1024*1024*1024)+"G   内存使用率为:"+(long)usedSize*100/totalSize+"%");
}else if (VIRTUAL_MEMORY_OID.equals(oid)) {
System.out.println("VIRTUAL_MEMORY----->虚拟内存大小:"+(long)totalSize * unit/(1024*1024*1024)+"G   内存使用率为:"+(long)usedSize*100/totalSize+"%");
}
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


 

3、获取磁盘信息方法

//获取磁盘相关信息
public static void collectDisk() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String DISK_OID = "1.3.6.1.2.1.25.2.1.4";
String[] oids = {"1.3.6.1.2.1.25.2.3.1.2",  //type 存储单元类型
     "1.3.6.1.2.1.25.2.3.1.3",  //descr
     "1.3.6.1.2.1.25.2.3.1.4",  //unit 存储单元大小
     "1.3.6.1.2.1.25.2.3.1.5",  //size 总存储单元数
     "1.3.6.1.2.1.25.2.3.1.6"}; //used 使用存储单元数;
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);//创建snmp
snmp.listen();//监听消息
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null ||!DISK_OID.equals(values[0].getVariable().toString())) 
continue;
int unit = Integer.parseInt(values[2].getVariable().toString());//unit 存储单元大小
int totalSize = Integer.parseInt(values[3].getVariable().toString());//size 总存储单元数
int usedSize = Integer.parseInt(values[4].getVariable().toString());//used  使用存储单元数
System.out.println(getChinese(values[1].getVariable().toString())+"   磁盘大小:"+(long)totalSize*unit/(1024*1024*1024)+"G   磁盘使用率为:"+(long)usedSize*100/totalSize+"%");
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


4、获取服务器进程信息方法

//服务器进程集合信息
public static void collectProcess() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] oids =
{"1.3.6.1.2.1.25.4.2.1.1",  //index
            "1.3.6.1.2.1.25.4.2.1.2",  //name
            "1.3.6.1.2.1.25.4.2.1.4",  //run path
     "1.3.6.1.2.1.25.4.2.1.6",  //type
     "1.3.6.1.2.1.25.5.1.1.1",  //cpu
     "1.3.6.1.2.1.25.5.1.1.2"}; //memory  
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
String name = values[1].getVariable().toString();//name
String cpu = values[4].getVariable().toString();//cpu
String memory = values[5].getVariable().toString();//memory
String path = values[2].getVariable().toString();//path
System.out.println("name--->"+name+"  cpu--->"+cpu+"  memory--->"+memory+"  path--->"+path);
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


5、获取服务器系统服务方法

//服务器系统服务集合
public static void collectService() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] oids =
{"1.3.6.1.4.1.77.1.2.3.1.1"};
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
String name = values[0].getVariable().toString();//name
System.out.println("名称--->"+getChinese(name));//中文乱码,需要转为utf-8编码
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


6、获取接口信息方法

//服务器接口集合
public static void collectInterface() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] IF_OIDS = 
    {"1.3.6.1.2.1.2.2.1.1",  //Index 
     "1.3.6.1.2.1.2.2.1.2",  //descr
     "1.3.6.1.2.1.2.2.1.3",  //type
     "1.3.6.1.2.1.2.2.1.5",  //speed
     "1.3.6.1.2.1.2.2.1.6",  //mac
     "1.3.6.1.2.1.2.2.1.7",  //adminStatus
     "1.3.6.1.2.1.2.2.1.8",  //operStatus   
      
     "1.3.6.1.2.1.2.2.1.10", //inOctets
     "1.3.6.1.2.1.2.2.1.16", //outOctets
     "1.3.6.1.2.1.2.2.1.14", //inError
     "1.3.6.1.2.1.2.2.1.20", //outError
     "1.3.6.1.2.1.2.2.1.13", //inDiscard
     "1.3.6.1.2.1.2.2.1.19", //outDiscard
     "1.3.6.1.2.1.2.2.1.11", //inUcastPkts
     "1.3.6.1.2.1.2.2.1.17", //outUcastPkts
     "1.3.6.1.2.1.2.2.1.12", //inNUcastPkts     
     "1.3.6.1.2.1.2.2.1.18"};//outNUcastPkts
String[] IP_OIDS =	 
    {"1.3.6.1.2.1.4.20.1.1", //ipAdEntAddr
     "1.3.6.1.2.1.4.20.1.2", //ipAdEntIfIndex
     "1.3.6.1.2.1.4.20.1.3"};//ipAdEntNetMask 
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[IF_OIDS.length];
for (int i = 0; i < IF_OIDS.length; i++)
columns[i] = new OID(IF_OIDS[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
System.out.println("interface ---Index:"+values[0].getVariable().toString()+"  descr:"+getChinese(values[1].getVariable().toString())+"  type:"+values[2].getVariable().toString()+" speed:"+values[3].getVariable().toString()+" mac:"+getChinese(values[4].getVariable().toString())+" adminStatus:"+values[5].getVariable().toString()+"  operStatus:"+values[6].getVariable().toString());
}
}
//获取ip
OID[] ipcolumns = new OID[IP_OIDS.length];
for (int i = 0; i < IP_OIDS.length; i++)
ipcolumns[i] = new OID(IP_OIDS[i]);
@SuppressWarnings("unchecked")
List iplist = tableUtils.getTable(target, ipcolumns, null, null);
if(iplist.size()==1 && iplist.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : iplist){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
System.out.println(" IP--->ipAdEntAddr:"+values[0].getVariable().toString()+"   ipAdEntIfIndex:"+values[1].getVariable().toString()+"   ipAdEntNetMask:"+values[2].getVariable().toString());
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


7、获取端口信息方法

//服务器端口集合
public static void collectPort() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] TCP_CONN = {"1.3.6.1.2.1.6.13.1.1", //status
        "1.3.6.1.2.1.6.13.1.3"}; //port
 
String[] UDP_CONN = {"1.3.6.1.2.1.7.5.1.2"};
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
//获取TCP 端口
OID[] columns = new OID[TCP_CONN.length];
for (int i = 0; i < TCP_CONN.length; i++)
columns[i] = new OID(TCP_CONN[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
int status = Integer.parseInt(values[0].getVariable().toString());
System.out.println("status--->"+status+"   TCP_port--->"+values[1].getVariable().toString());
}
}
//获取udp 端口
OID[] udpcolumns = new OID[UDP_CONN.length];
for (int i = 0; i < UDP_CONN.length; i++)
udpcolumns[i] = new OID(UDP_CONN[i]);
@SuppressWarnings("unchecked")
List udplist = tableUtils.getTable(target, udpcolumns, null, null);
if(udplist.size()==1 && udplist.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : udplist){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
String name = values[0].getVariable().toString();//name
System.out.println("UDP_port--->"+name);
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


8、获取安装的软件信息方法

//服务器安装软件集合
public static void collectSoft() {
TransportMapping transport = null ;
Snmp snmp = null ;
CommunityTarget target;
String[] oids =
{	"1.3.6.1.2.1.25.6.3.1.2",  //software
                	"1.3.6.1.2.1.25.6.3.1.4",  //type
    "1.3.6.1.2.1.25.6.3.1.5"}; //install date
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setRetries(2);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/161"));
target.setTimeout(8000);
target.setVersion(SnmpConstants.version2c);
TableUtils tableUtils = new TableUtils(snmp, new PDUFactory() {
@Override
public PDU createPDU(Target arg0) {
PDU request = new PDU();
request.setType(PDU.GET);
return request;
}
});
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
@SuppressWarnings("unchecked")
List list = tableUtils.getTable(target, columns, null, null);
if(list.size()==1 && list.get(0).getColumns()==null){
System.out.println(" null");
}else{
for(TableEvent event : list){
VariableBinding[] values = event.getColumns();
if(values == null) continue;
String software = values[0].getVariable().toString();//software
String type = values[1].getVariable().toString();//type
String date = values[2].getVariable().toString();//date
System.out.println("软件名称--->"+getChinese(software)+"  type--->"+type+"  安装时间--->"+hexToDateTime(date.replace("'", "")));
}
}
} catch(Exception e){
e.printStackTrace();
}finally{
try {
if(transport!=null)
transport.close();
if(snmp!=null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


9、其他方法

/**
 * 获取磁盘的中文名字
 * 解决snmp4j中文乱码问题
 */
public static String getChinese(String octetString){
if(octetString == null || "".equals(octetString) 
       || "null".equalsIgnoreCase(octetString)) return "";
try{
String[] temps = octetString.split(":");
if(temps.length < COLON_SIZE)
return octetString;
byte[] bs = new byte[temps.length];
for(int i=0;i= 0; index--) {
format_str[index] = (char) (48 + (temp - temp / 10 * 10));
temp /= 10;
}
format_str[4] = '-';
index = 6;
temp = month;
for (; index >= 5; index--) {
format_str[index] = (char) (48 + (temp - temp / 10 * 10));
temp /= 10;
}
format_str[7] = '-';
index = 9;
temp = day;
for (; index >= 8; index--) {
format_str[index] = (char) (48 + (temp - temp / 10 * 10));
temp /= 10;
}
format_str[10] = ' ';
index = 12;
temp = hour;
for (; index >= 11; index--) {
format_str[index] = (char) (48 + (temp - temp / 10 * 10));
temp /= 10;
}
format_str[13] = ':';
index = 15;
temp = minute;
for (; index >= 14; index--) {
format_str[index] = (char) (48 + (temp - temp / 10 * 10));
temp /= 10;
}
dateTime = new String(format_str,0,format_str.length).substring(0, 16);
} catch (Exception e) {
//LogFactory.getLog(getClass()).error(e);
}
return dateTime;
}



这就是本人对snmp的学习,有什么不足的地方还请大家提出,不断的讨论研究和晚上……


你可能感兴趣的:(java)