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

import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.PDUv1;
import org.snmp4j.SNMP4JSettings;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
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.Priv3DES;
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.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 org.springframework.stereotype.Service;

@Service
public class SnmpTrapSender {
   private Snmp snmp = null;
   private Address targetAddress = null;
   private TransportMapping<UdpAddress> transport = null;
   private String username1 = "user1";
   private String authPassword = "password1";
   private String privPassword = "password2";

   public static void main(String[] args) {
      SnmpTrapSender poc = new SnmpTrapSender();

      try {
         poc.init();
         poc.sendV1Trap();
         poc.sendV2cTrap();
         poc.sendV3TrapNoAuthNoPriv();
         poc.sendV3();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }

   public void sendSnpm(String snmp_server_ip, Integer port) {
      SnmpTrapSender poc = new SnmpTrapSender();

      try {
         poc.init(snmp_server_ip, port);
         poc.sendV1Trap();
         poc.sendV2cTrap();
         poc.sendV3TrapNoAuthNoPriv();
         poc.sendV3();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }

   public void init(String snmp_server_ip, int port) throws IOException {
      this.targetAddress = GenericAddress.parse("udp:" + snmp_server_ip + "/" + port);
      this.transport = new DefaultUdpTransportMapping();
      this.snmp = new Snmp(this.transport);
      this.transport.listen();
   }

   public void init() throws IOException {
      this.targetAddress = GenericAddress.parse("udp:192.168.2.111/162");
      this.transport = new DefaultUdpTransportMapping();
      this.snmp = new Snmp(this.transport);
      this.transport.listen();
   }

   public ResponseEvent sendV1Trap() throws IOException {
      PDUv1 pdu = new PDUv1();
      VariableBinding v = new VariableBinding();
      v.setOid(SnmpConstants.sysName);
      v.setVariable(new OctetString("Snmp Trap V1 Test"));
      pdu.add(v);
      pdu.setType(-92);
      CommunityTarget target = new CommunityTarget();
      target.setCommunity(new OctetString("public"));
      target.setAddress(this.targetAddress);
      target.setRetries(2);
      target.setTimeout(1500L);
      target.setVersion(0);
      return this.snmp.send(pdu, target);
   }

   public ResponseEvent sendV2cTrap() throws IOException {
      PDU pdu = new PDU();
      VariableBinding v = new VariableBinding();
      v.setOid(SnmpConstants.sysName);
      v.setVariable(new OctetString("Snmp Trap V2 Test"));
      pdu.add(v);
      pdu.setType(-89);
      CommunityTarget target = new CommunityTarget();
      target.setCommunity(new OctetString("public"));
      target.setAddress(this.targetAddress);
      target.setRetries(2);
      target.setTimeout(1500L);
      target.setVersion(1);
      return this.snmp.send(pdu, target);
   }

   public ResponseEvent sendV3TrapNoAuthNoPriv() throws IOException {
      SNMP4JSettings.setExtensibilityEnabled(true);
      SecurityProtocols.getInstance().addDefaultProtocols();
      UserTarget target = new UserTarget();
      target.setVersion(3);

      try {
         this.transport = new DefaultUdpTransportMapping();
      } catch (IOException e1) {
         e1.printStackTrace();
      }

      byte[] enginId = "TEO_ID".getBytes();
      USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(enginId), 500);
      SecurityModels secModels = SecurityModels.getInstance();
      if (this.snmp.getUSM() == null) {
         secModels.addSecurityModel(usm);
      }

      target.setSecurityLevel(1);
      target.setAddress(this.targetAddress);
      ScopedPDU pdu = new ScopedPDU();
      pdu.setType(-89);
      VariableBinding v = new VariableBinding();
      v.setOid(SnmpConstants.sysName);
      v.setVariable(new OctetString("Snmp Trap V3 Test sendV3TrapNoAuthNoPriv"));
      pdu.add(v);
      this.snmp.setLocalEngine(enginId, 500, 1);
      return this.snmp.send(pdu, target);
   }

   public ResponseEvent sendV3Auth() throws IOException {
      SNMP4JSettings.setExtensibilityEnabled(true);
      SecurityProtocols.getInstance().addDefaultProtocols();
      UserTarget target = new UserTarget();
      target.setSecurityName(new OctetString(this.username1));
      target.setVersion(3);

      try {
         this.transport = new DefaultUdpTransportMapping();
      } catch (IOException e1) {
         e1.printStackTrace();
      }

      byte[] enginId = "TEO_ID".getBytes();
      USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(enginId), 500);
      SecurityModels secModels = SecurityModels.getInstance();
      synchronized(secModels) {
         if (this.snmp.getUSM() == null) {
            secModels.addSecurityModel(usm);
         }

         this.snmp.getUSM().addUser(new OctetString(this.username1), new OctetString(enginId), new UsmUser(new OctetString(this.username1), AuthMD5.ID, new OctetString(this.authPassword), Priv3DES.ID, new OctetString(this.privPassword)));
         target.setSecurityLevel(3);
         target.setAddress(this.targetAddress);
         ScopedPDU pdu = new ScopedPDU();
         pdu.setType(-89);
         VariableBinding v = new VariableBinding();
         v.setOid(SnmpConstants.sysName);
         v.setVariable(new OctetString("Snmp Trap V3 Test sendV3Auth"));
         pdu.add(v);
         this.snmp.setLocalEngine(enginId, 500, 1);
         ResponseEvent send = this.snmp.send(pdu, target);
         return send;
      }
   }

   public ResponseEvent sendV3() throws IOException {
      OctetString userName = new OctetString(this.username1);
      OctetString authPass = new OctetString(this.authPassword);
      OctetString privPass = new OctetString("privPassword");
      TransportMapping<?> transport = new DefaultUdpTransportMapping();
      Snmp snmp = new Snmp(transport);
      USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 500);
      SecurityModels.getInstance().addSecurityModel(usm);
      UserTarget target = new UserTarget();
      byte[] enginId = "TEO_ID".getBytes();
      SecurityModels secModels = SecurityModels.getInstance();
      synchronized(secModels) {
         if (snmp.getUSM() == null) {
            secModels.addSecurityModel(usm);
         }

         snmp.getUSM().addUser(userName, new UsmUser(userName, AuthMD5.ID, authPass, PrivDES.ID, privPass));
         target.setAddress(this.targetAddress);
         target.setRetries(2);
         target.setTimeout(3000L);
         target.setVersion(3);
         target.setSecurityLevel(2);
         target.setSecurityName(userName);
         ScopedPDU pdu = new ScopedPDU();
         pdu.setType(-89);
         VariableBinding v = new VariableBinding();
         v.setOid(SnmpConstants.sysName);
         v.setVariable(new OctetString("Snmp Trap V3 Test sendV3Auth----------"));
         pdu.add(v);
         snmp.setLocalEngine(enginId, 500, 1);
         ResponseEvent send = snmp.send(pdu, target);
         return send;
      }
   }
}
