package com.chenyang.nse.bussiness.tools.trapServer;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Vector;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.security.UsmUserEntry;
import org.snmp4j.security.UsmUserTable;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

public class MultiThreadedTrapReceiver implements CommandResponder {
   private String username1 = "user1";
   private String username2 = "user2";
   private String username3 = "user3";
   private String username4 = "user4";
   private String authPassword = "password1";
   private String privPassword = "password2";
   private MultiThreadedMessageDispatcher dispatcher;
   private Snmp snmp = null;
   private Address listenAddress;
   private ThreadPool threadPool;

   private void init() throws UnknownHostException, IOException {
      this.threadPool = ThreadPool.create("Trap", 2);
      this.dispatcher = new MultiThreadedMessageDispatcher(this.threadPool, new MessageDispatcherImpl());
      this.listenAddress = GenericAddress.parse(System.getProperty("snmp4j.listenAddress", "udp:192.168.2.212/162"));
      TransportMapping<?> transport;
      if (this.listenAddress instanceof UdpAddress) {
         transport = new DefaultUdpTransportMapping((UdpAddress)this.listenAddress);
      } else {
         transport = new DefaultTcpTransportMapping((TcpAddress)this.listenAddress);
      }

      this.snmp = new Snmp(this.dispatcher, transport);
      this.snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
      this.snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
      this.snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
      USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
      SecurityModels.getInstance().addSecurityModel(usm);
      SecurityProtocols.getInstance().addDefaultProtocols();
      OctetString userName1 = new OctetString(this.username1);
      OctetString userName2 = new OctetString(this.username2);
      OctetString authPass = new OctetString(this.authPassword);
      OctetString privPass = new OctetString("privPassword");
      UsmUser usmUser1 = new UsmUser(userName1, AuthMD5.ID, authPass, PrivDES.ID, privPass);
      UsmUser usmUser2 = new UsmUser(userName2, AuthMD5.ID, authPass, PrivDES.ID, privPass);
      UsmUserEntry userEnty1 = new UsmUserEntry(userName1, usmUser1);
      UsmUserEntry userEnty2 = new UsmUserEntry(userName2, usmUser2);
      UsmUserTable userTable = this.snmp.getUSM().getUserTable();
      userTable.addUser(userEnty1);
      userTable.addUser(userEnty2);
      this.snmp.listen();
   }

   public void run() {
      try {
         this.init();
         this.snmp.addCommandResponder(this);
         System.out.println("开始监听Trap信息!");
      } catch (Exception ex) {
         ex.printStackTrace();
      }

   }

   public void processPdu(CommandResponderEvent respEvnt) {
      if (respEvnt != null && respEvnt.getPDU() != null) {
         Vector<? extends VariableBinding> recVBs = respEvnt.getPDU().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) {
      MultiThreadedTrapReceiver multithreadedtrapreceiver = new MultiThreadedTrapReceiver();
      multithreadedtrapreceiver.run();
   }
}
