snmp整理笔记

1. snmp是什么

SNMP是英文"Simple Network Management Protocol"的缩写,中文意思是"简单网络管理协议"。SNMP 是一种简单网络管理协议,它属于 TCP/IP 五层协议中的应用层协议,用于网络管理的协议。 SNMP 主要用于网络设备的管理。由于 SNMP 协议简单可靠 ,受到了众多厂商的欢迎,成为了目前最为广泛的网管协议。

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

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

SNMP 的基本思想:为不同种类的设备、不同厂家生产的设备、不同型号的设备,定义为一个统一的接口和协议,使得管理员可以是使用统一的外观面对这些需要管理的网络设备进行管理。通过网络,管理员可以管理位于不同物理空间的设备,从而大大提高网络管理的效率,简化网络管理员的工作。

SNMP的工作方式:管理员需要向设备获取数据,所以SNMP提供了【读】操作;管理员需要向设备执行设置操作,所以SNMP提供了【写】操作;设备需要在重要状况改变的时候,向管理员通报事件的发生,所以SNMP提供了【Trap】操作。

2. snmp应用哪些场景

利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。SNMP的基本思想:为不同种类的设备、不同厂家生产的设备、不同型号的设备,定义为一个统一的接口和协议,使得管理员可以使用统一的网管面对这些需要管理的网络设备进行管理。通过网络,管理员可以管理位于不同物理空间的设备,从而大大提高网络管理的效率,简化网络管理员的工作。

3. snmp能做什么

SNMP为管理员提供了一个网管平台(NMS),又称为【管理站】,负责网管命令的发出、数据存储、及数据分析。被监管的设备上运行一个SNMP代理(Agent)),代理实现设备与管理站的SNMP通信。

网络管理员使用SNMP功能可以查询设备信息、修改设备的参数值、监控设备状态、自动发现网络故障、生成报告等。

SNMP协议之所以易于使用,这是因为它对外提供了三种用于控制MIB对象的基本操作命令。它们是:Get、Set 和 Trap。

Get:管理站读取代理者处对象的值。它是SNMP协议中使用率最高的一个命令,因为该命令是从网络设备中获得管理信息的基本方式。

Set:管理站设置代理者处对象的值。它是一个特权命令,因为可以通过它来改动设备的配置或控制设备的运转状态。它可以设置设备的名称,关掉一个端口或清除一个地址解析表中的项等。

Trap: 代理者主动向管理站通报重要事件。它的功能就是在网络管理系统没有明确要求的前提下,由管理代理通知网络管理系统有一些特别的情况或问题 发生了。如果发生意外情况,客户会向服务器的162端口发送一个消息,告知服务器指定的变量值发生了变化。通常由服务器请求而获得的数据由服务器的161 端口接收。Trap 消息可以用来通知管理站线路的故障、连接的终端和恢复、认证失败等消息。管理站可相应的作出处理。

get-next-request操作:从代理进程处提取紧跟当前参数值的下一个参数值。

get-response操作:返回的一个或多个参数值。这个操作是由代理进程发出的。

4. snmp示例Demo

4.1、 Get操作命令:

4.1.1、获得本机的信息

package me.gacl.snmp;

import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

/**
 * <p>ClassName: GetOID<p>
 * <p>Description:获得本机的信息 <p>
 */
public class GetOID {

    public static void main(String[] args) throws Exception{  
        
        try{  
            //设定CommunityTarget   
            CommunityTarget myTarget = new CommunityTarget();
            //定义远程主机的地址  
            //Address deviceAdd = GenericAddress.parse("udp:10.20.61.120/161"); 
            //定义本机的地址   
            Address localAdd = GenericAddress.parse("udp:localhost/161");
            //设定远程主机的地址 
            //myTarget.setAddress(deviceAdd); 
            //设定本地主机的地址
            myTarget.setAddress(localAdd);
            //设置snmp共同体   
            myTarget.setCommunity(new OctetString("public")); 
            //设置超时重试次数   
            myTarget.setRetries(2); 
            //设置超时的时间  
            myTarget.setTimeout(5*60);
            //设置使用的snmp版本 
            myTarget.setVersion(SnmpConstants.version2c);  
             
            //设定采取的协议   
            TransportMapping transport = new DefaultUdpTransportMapping();//设定传输协议为UDP
            //调用TransportMapping中的listen()方法,启动监听进程,接收消息,由于该监听进程是守护进程,最后应调用close()方法来释放该进程
            transport.listen();  
            //创建SNMP对象,用于发送请求PDU
            Snmp protocol = new Snmp(transport);  
            //创建请求pdu,获取mib   
            PDU request = new PDU(); 
            //调用的add方法绑定要查询的OID
            request.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1")));  
            request.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,2})));
            //调用setType()方法来确定该pdu的类型
            request.setType(PDU.GETNEXT);
            //调用 send(PDU pdu,Target target)发送pdu,返回一个ResponseEvent对象
            ResponseEvent responseEvent = protocol.send(request, myTarget);  
            //通过ResponseEvent对象来获得SNMP请求的应答pdu,方法:public PDU getResponse()
            PDU response=responseEvent.getResponse();  
            //输出   
            if(response != null){  
                System.out.println("request.size()="+request.size());  
                System.out.println("response.size()="+response.size());
                //通过应答pdu获得mib信息(之前绑定的OID的值),方法:VaribleBinding get(int index)
                VariableBinding vb1 = response.get(0);  
                VariableBinding vb2 = response.get(1);  
                System.out.println(vb1);  
                System.out.println(vb2);
                //调用close()方法释放该进程
                transport.close();  
                
                /**
                 * 输出结果:
                 * request.size()=2
                   response.size()=2
                   1.3.6.1.2.1.1.1.0 = Hardware: Intel64 Family 6 Model 60 Stepping 3 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 17134 Multiprocessor Free)
                   1.3.6.1.2.1.1.2.0 = 1.3.6.1.4.1.311.1.1.3.1.1

                 */
            }  
            
          }catch(IOException e){  
              e.printStackTrace();  
          }  
        }  
}

运行截图:

image.png

4.1.2、获取远程计算机的名称

package me.gacl.snmp;

import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
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.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class Snmp4jFirstDemo {

    private Snmp snmp = null;
    private int version ;

    public Snmp4jFirstDemo(int version) {
        try {
            this.version = version;
            TransportMapping transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            if (version == SnmpConstants.version3) {
                // 设置安全模式
                USM usm = new USM(SecurityProtocols.getInstance(),new OctetString(MPv3.createLocalEngineID()), 0);
                SecurityModels.getInstance().addSecurityModel(usm);
            }
            // 开始监听消息
            transport.listen();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(Boolean syn, final Boolean bro, PDU pdu, String addr)
            throws IOException {
        // 生成目标地址对象
        Address targetAddress = GenericAddress.parse(addr);
        Target target = null;
        if (version == SnmpConstants.version3) {
            // 添加用户
            snmp.getUSM().addUser(new OctetString("MD5DES"),new UsmUser(new OctetString("MD5DES"), AuthMD5.ID,new OctetString("MD5DESUserAuthPassword"),PrivDES.ID, new OctetString("MD5DESUserPrivPassword")));
            target = new UserTarget();
            // 设置安全级别
            ((UserTarget) target).setSecurityLevel(SecurityLevel.AUTH_PRIV);
            ((UserTarget) target).setSecurityName(new OctetString("MD5DES"));
            target.setVersion(SnmpConstants.version3);
        } else {
            target = new CommunityTarget();
            if (version == SnmpConstants.version1) {
                target.setVersion(SnmpConstants.version1);
                ((CommunityTarget) target).setCommunity(new OctetString("public"));
            } else {
                target.setVersion(SnmpConstants.version2c);
                ((CommunityTarget) target).setCommunity(new OctetString("public"));
            }

        }
        // 目标对象相关设置
        target.setAddress(targetAddress);
        target.setRetries(5);
        target.setTimeout(1000);

        if (!syn) {
            // 发送报文 并且接受响应
            ResponseEvent response = snmp.send(pdu, target);
            // 处理响应
            System.out.println("Synchronize(同步) message(消息) from(来自) "
                    + response.getPeerAddress() + "\r\n"+"request(发送的请求):"
                    + response.getRequest() + "\r\n"+"response(返回的响应):"
                    + response.getResponse());
            /**
             * 输出结果:
             * Synchronize(同步) message(消息) from(来自) 10.20.61.120/161
               request(发送的请求):GET[requestID=680783532, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = Null]]
               response(返回的响应):RESPONSE[requestID=680783532, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = IE11Win7]]

             */
        } else {
            // 设置监听对象
            ResponseListener listener = new ResponseListener() {

                public void onResponse(ResponseEvent event) {
                    if (bro.equals(false)) {
                        ((Snmp) event.getSource()).cancel(event.getRequest(),this);
                    }
                    // 处理响应
                    PDU request = event.getRequest();
                    PDU response = event.getResponse();
                    System.out.println("Asynchronise(异步) message(消息) from(来自) "
                            + event.getPeerAddress() + "\r\n"+"request(发送的请求):" + request
                            + "\r\n"+"response(返回的响应):" + response);
                }

            };
            // 发送报文
            snmp.send(pdu, target, null, listener);
        }
    }

    public static void main(String[] args) {
        //Snmp的三个版本号
        //int ver3 = SnmpConstants.version3;
        int ver2c = SnmpConstants.version2c;
        //int ver1 = SnmpConstants.version1;
        Snmp4jFirstDemo manager = new Snmp4jFirstDemo(ver2c);
        // 构造报文
        PDU pdu = new PDU();
         //PDU pdu = new ScopedPDU();
        // 设置要获取的对象ID,这个OID代表远程计算机的名称
        OID oids = new OID("1.3.6.1.2.1.1.5.0");
        pdu.add(new VariableBinding(oids));
        // 设置报文类型
        pdu.setType(PDU.GET);
        //((ScopedPDU) pdu).setContextName(new OctetString("priv"));
        try {
            // 发送消息 其中最后一个是想要发送的目标地址
            manager.sendMessage(false, true, pdu, "udp:10.20.61.120/161");//10.20.61.120 Win7虚拟机
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行截图:

image.png

4.2、 Set操作命令:

4.2.1、修改读取的远程计算机的名称

package me.gacl.snmp;

import java.io.IOException;
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.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class SnmpUtil {
 
       private Snmp snmp = null;

       private Address targetAddress = null;
 
       public void initComm() throws IOException {
             
              // 设置Agent方的IP和端口
              targetAddress = GenericAddress.parse("udp:10.20.61.120/161");

              TransportMapping transport = new DefaultUdpTransportMapping();

              snmp = new Snmp(transport);

              transport.listen();

       }
 

       public ResponseEvent sendPDU(PDU pdu) throws IOException {

              // 设置 target
              CommunityTarget target = new CommunityTarget();

              target.setCommunity(new OctetString("public"));

              target.setAddress(targetAddress);

              // 通信不成功时的重试次数
              target.setRetries(2);

              // 超时时间
              target.setTimeout(1500);

              target.setVersion(SnmpConstants.version1);

              // 向Agent发送PDU,并返回Response
              return snmp.send(pdu, target);

       }

      

       public void setPDU() throws IOException {

              // set PDU
              PDU pdu = new PDU();

              pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5, 0 }), new OctetString("SNMPTEST")));

              pdu.setType(PDU.SET);

              sendPDU(pdu);

       }

      

       public void getPDU() throws IOException {

              // get PDU
              PDU pdu = new PDU();

              pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5, 0 })));

              pdu.setType(PDU.GET);

              readResponse(sendPDU(pdu));

       }

      

       public void readResponse(ResponseEvent respEvnt) {

              // 解析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());

                     }

              }

       }
     

       public static void main(String[] args) {

              try {

                     SnmpUtil util = new SnmpUtil();

                     util.initComm();

                     util.setPDU();

                     util.getPDU();

              } catch (IOException e) {

                     e.printStackTrace();

              }

       }

}

运行截图:

image.png

4.3、 Trap操作命令:

4.3.1、发送Trap

package me.gacl.snmp;

import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
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;

public class TrapUtil {
 
       private Snmp snmp = null;

       private Address targetAddress = null;
 
       private TransportMapping transport = null;
       
       public void initComm() throws IOException {

              // 设置Agent方的IP和端口
              targetAddress = GenericAddress.parse("udp:10.20.61.109/162");
              // 设置send trap的IP和端口
              transport = new DefaultUdpTransportMapping(new UdpAddress("10.20.61.120/161"));
              snmp = new Snmp(transport);

              transport.listen();

       }
 

       public ResponseEvent sendPDU(PDU pdu) throws IOException {

              // 设置 target
              CommunityTarget target = new CommunityTarget();

              target.setCommunity(new OctetString("public"));

              target.setAddress(targetAddress);

              // 通信不成功时的重试次数
              target.setRetries(2);

              // 超时时间
              target.setTimeout(1500);

              target.setVersion(SnmpConstants.version2c);

              // 向Agent发送PDU,并返回Response
              return snmp.send(pdu, target);

       }

      

       public void setTrap() throws IOException {

           // 构造Trap PDU

           PDU pdu = new PDU();

           pdu.add(new VariableBinding(new OID(".1.3.6.1.2.3377.10.1.1.1.1"),

                         new OctetString("SnmpTrap")));

           pdu.setType(PDU.TRAP);

           sendPDU(pdu);

           System.out.println("Trap sent successfully.");

       }


       public static void main(String[] args) {

              try {

                     TrapUtil util = new TrapUtil();

                     util.initComm();

                     util.setTrap();

              } catch (IOException e) {

                     e.printStackTrace();
              }
       }
}

运行截图:

image.png

4.3.2、接收Trap

package me.gacl.snmp;

import java.io.IOException;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class Snmp4jTrapDemo {
    
      private Snmp snmp = null;
      private Address targetAddress = null;      
      private TransportMapping transport = null;
      
      public void initComm() throws IOException {

             // 设置Agent方的IP和端口
             targetAddress = GenericAddress.parse("udp:10.20.61.120/161");
             // 设置接收trap的IP和端口
             transport = new DefaultUdpTransportMapping(new UdpAddress("10.20.61.109/162"));
             snmp = new Snmp(transport);

             CommandResponder trapRec = new CommandResponder() {

                    public synchronized void processPdu(CommandResponderEvent e) {

                           // 接收trap
                           PDU command = e.getPDU();
                           if (command != null) {
                                  System.out.println(command.toString());
                           }
                    }
             };

             snmp.addCommandResponder(trapRec);
             transport.listen();
      }
    

      public synchronized void listen() {

          System.out.println("Waiting for traps..");
          
          try {
                 this.wait();//Wait for traps to come in
          } catch (InterruptedException ex) {
                 System.out.println("Interrupted while waiting for traps: " + ex);
                 System.exit(-1);
          }

   }

  

   public static void main(String[] args) {

          try {
              Snmp4jTrapDemo traputil = new Snmp4jTrapDemo();
              traputil.initComm();
              traputil.listen();
          } catch (IOException e) {
                 e.printStackTrace();
          }

   }
}

运行截图:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容