Through SNMP query the switch MAC table and an ARP core switch, for query corresponding relationship

Through SNMP query the switch MAC table and an ARP core switch, for query corresponding relationship

By MAC table SNMP query switches and ARP table core switches, to achieve a query correspondence, so that you can realize the function behind what we want, whether it is the query IP-MAC, what port connected to what switch, or to match the engine room unusual access device, can be added later MSSQL integrated database, each table plus all of the MAC history, such as when the access switch, which when switched to another switch port.

Download and references
SnmpSharpNet.dll
https://download.csdn.net/download/chscomfaner/12094545
first open the switch SNMP, open method:

#snmp-server community public ro #配置本路由器的只读字串为public
#snmp-server community public rw #配置本路由器的读写字串为public

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="community" value="public"/>
    <add key="sw" value="192.168.10.200"/>
    <add key="router" value="192.168.10.1"/>
  </appSettings>
</configuration>

Programs.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
 

namespace SNMP_SW
{
    class Program
    {
        static object locker=new object();
        static List<SW> allSW=new List<SW>();
        static List<Router> allRouter = new List<Router>();
        static void Main(string[] args)
        {
            //扫描交换机
            string[] sws = ConfigurationManager.AppSettings["sw"].Split(',');
            Console.WriteLine("共有{0}个交换机需要扫描", sws.Length);
            //Console.WriteLine("--------------------------------------------------------------------");
            foreach (string sw in sws)
            {
                if (string.IsNullOrEmpty(sw))
                    continue;
                ParameterizedThreadStart pst = new ParameterizedThreadStart(scanSw);
                Thread thread = new Thread(pst);
                thread.Name = sw + "扫描交换机线程";
                thread.Start(sw);
            }
            //扫描核心
            string[] routers = ConfigurationManager.AppSettings["router"].Split(',');
            Console.WriteLine("共有{0}个核心需要扫描", routers.Length);            
            foreach (string rou in routers)
            {
                if (string.IsNullOrEmpty(rou))
                    continue;
                ParameterizedThreadStart pst = new ParameterizedThreadStart(scanRouter);
                Thread thread = new Thread(pst);
                thread.Name = rou + "扫描核心线程";
                thread.Start(rou);
            }
            Console.WriteLine("--------------------------------------------------------------------");
            Console.ReadLine();
        }
        static void scanRouter(object host)
        {
            Console.WriteLine("启动线程:" + Thread.CurrentThread.Name);
            Dictionary<string, string> arpTable = new Dictionary<string, string>();
            Dictionary<string, string> dicArp = SimpleSnmp.getWalkValue(host.ToString(), SimpleSnmp.OID.arp);
            foreach (var item in dicArp)
            {
                string[] dip = item.Key.Split('.');
                string ip = string.Format("{0}.{1}.{2}.{3}", dip[dip.Length - 4], dip[dip.Length - 3], dip[dip.Length - 2], dip[dip.Length - 1]);
                string mac = item.Value.Replace(" ", ":").ToUpper();
                arpTable.Add(mac, ip);
            }
            Console.WriteLine("核心的ARP表");
            Console.WriteLine("--------------------------------------------------------------------");
            foreach (var item in arpTable)
            {
                Console.WriteLine("{0}-{1}", item.Key, item.Value);
            }
            Router rou = new Router(host.ToString(), arpTable);
            string json = Utils.toJson(arpTable);
            Utils.save(host.ToString() + "_ArpTable.txt", json); 
            lock (locker)
            {
                allRouter.Add(rou);
            }                     
        }
        static void scanSw(object host)
        {
            Console.WriteLine("启动线程:" + Thread.CurrentThread.Name);
            List<string> vlan = new List<string>();
            Dictionary<string, Dictionary<string, string>> macTable = new Dictionary<string, Dictionary<string, string>>();
            //Dictionary<string, string> dicPort = SimpleSnmp.getWalkValue(host.ToString(), SimpleSnmp.OID.port); //获取所有的端口           
            //if (dicPort == null)
            //{
            //    Console.WriteLine(Thread.CurrentThread.Name+"端口请求失败");                 
            //    return;
            //}
            //else
            //{
            //    //Console.WriteLine(Thread.CurrentThread.Name + "端口请求成功");        
            //}
            //foreach (var item in dicPort)
            //{
            //    if (item.Value.Contains("Vl"))
            //    {
            //        vlan.Add(item.Value.Replace("Vl",""));
            //    }
            //    Console.WriteLine("{0}:{1}:{2}", host, item.Key, item.Value);
            //}
            Dictionary<string, string> dicVlan = SimpleSnmp.getWalkValue(host.ToString(), SimpleSnmp.OID.vtp); //获取所有VLAN
            if (dicVlan == null)
            {
                Console.WriteLine(Thread.CurrentThread.Name + "VLAN请求失败");
                return;
            }
            else
            {
                //Console.WriteLine(Thread.CurrentThread.Name + "VLAN请求成功");
            }
            foreach (var item in dicVlan)
            {
                if (!vlan.Contains(item.Value.Replace("vlan", "")))
                {
                    vlan.Add(item.Value.Replace("vlan", ""));                    
                }
                //Console.WriteLine("{0}:{1}:{2}", host, item.Key, item.Value);
            }
            //Console.WriteLine("获取到了如下所有的VLAN:");
            foreach (var item in vlan)
            {   
                Dictionary<string, string> mac = SimpleSnmp.getWalkValue(host.ToString(), SimpleSnmp.OID.mac,item);
                Dictionary<string, string> mac_port = SimpleSnmp.getWalkValue(host.ToString(), SimpleSnmp.OID.mac_port, item);
                Dictionary<string, string> mac_link_port = new Dictionary<string, string>();
                foreach (var i in mac)
                {
                    foreach (var j in mac_port)
                    {
                        string t1 = j.Key.Substring(SimpleSnmp.OID.mac_port.Length - 1);
                        string t2 = i.Key.Substring(SimpleSnmp.OID.mac_port.Length - 1);
                        if (t1==t2) //找端口号
                        {
                            mac_link_port.Add(i.Value, j.Value);
                            //Console.WriteLine("{0}:vlan{1}:{2}:{3}", host, item, i.Value, j.Value);
                            break;
                        }
                    }   
                }
                if(mac_link_port.Count>0)
                macTable.Add(item, mac_link_port);
            }
            foreach (var item in macTable)
            {
                Console.WriteLine("--------------------------------------------------------------------");
                Console.WriteLine("SW{0}:VLAN{1}",host.ToString(),item.Key);
                foreach (var mp in item.Value)
                {
                    Console.WriteLine("MAC:{0}--PORT:{1}", mp.Key, mp.Value);
                }
            }
            SW sw = new SW(host.ToString(), macTable);
            string json = Utils.toJson(macTable);
            Utils.save(host.ToString() + "_MacTable.txt", json);
            lock (locker)
            {
                allSW.Add(sw);
            }            
        } 
    }
    class SW
    {
        string ip;
        Dictionary<string, Dictionary<string, string>> macTable;
        public SW(string ip, Dictionary<string, Dictionary<string, string>> macTable)
        {
            this.ip = ip;
            this.macTable = macTable;
        }
    }
    class Router
    {
        string ip;
        Dictionary<string, string> arpTable;
        public Router(string ip, Dictionary<string, string> arpTable)
        {
            this.ip = ip;
            this.arpTable = arpTable;
        }
    }
}

SimpleSnmp.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using SnmpSharpNet;
using System.Configuration; 

namespace SNMP_SW
{
    class SimpleSnmp
    {
        public static string communityString = ConfigurationManager.AppSettings["community"];
        public struct OID {
            public static string mac = ".1.3.6.1.2.1.17.4.3.1.1";
            public static string mac_port = ".1.3.6.1.2.1.17.4.3.1.2";
            public static string arp = ".1.3.6.1.2.1.4.22.1.2";
            public static string port = ".1.3.6.1.2.1.31.1.1.1.1";
            public static string vtp = ".1.3.6.1.2.1.47.1.2.1.1.2";
        }
        public SimpleSnmp()
        {
            //   
            //TODO: 在此处添加构造函数逻辑   
            //   
        }

        #region 通过oid字符数组获得相应的值
        public static Dictionary<string, string> getOIDValue(string host, string[] oid)
        {
            //返回变量   
            Dictionary<string, string> dic = new Dictionary<string, string>();
            // SNMP community name   
            OctetString community = new OctetString(communityString);
            // Define agent parameters class   
            AgentParameters param = new AgentParameters(community);
            // Set SNMP version to 1 (or 2)   
            param.Version = SnmpVersion.Ver1;
            //param.Version = SnmpVersion.Ver2;
            // Construct the agent address object   
            // IpAddress class is easy to use here because   
            //  it will try to resolve constructor parameter if it doesn't   
            //  parse to an IP address   
            IpAddress agent = new IpAddress(host);

            // Construct target   
            UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);

            // Pdu class used for all requests   
            Pdu pdu = new Pdu(PduType.Get);

            foreach (string singleoid in oid)
            {
                pdu.VbList.Add(singleoid);
            }

            // Make SNMP request   
            SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param);

            // If result is null then agent didn't reply or we couldn't parse the reply.   
            if (result != null)
            {
                // ErrorStatus other then 0 is an error returned by    
                // the Agent - see SnmpConstants for error definitions   
                if (result.Pdu.ErrorStatus == 0)
                {
                    for (int i = 0; i < result.Pdu.VbList.Count; i++)
                    {
                        dic.Add(result.Pdu.VbList[i].Oid.ToString(), result.Pdu.VbList[i].Value.ToString());
                    }
                    // Reply variables are returned in the same order as they were added   
                    //  to the VbList   
                }
            }
            target.Close();
            return dic;
        }
        #endregion

        #region 通过snmpwalk返回oid根下面的所有值
        public static Dictionary<string, string> getWalkValue(string host, string irootOid,string vlan = null )
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            // SNMP community name   
            OctetString community;
            if(vlan==null)
                community = new OctetString(communityString);
            else
                community = new OctetString(communityString+"@"+vlan);
                        
            // Define agent parameters class   
            AgentParameters param = new AgentParameters(community);
            // Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3)   
            param.Version = SnmpVersion.Ver2;
            // Construct the agent address object   
            // IpAddress class is easy to use here because   
            //  it will try to resolve constructor parameter if it doesn't   
            //  parse to an IP address   
            IpAddress agent = new IpAddress(host);

            // Construct target   
            UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);

            // Define Oid that is the root of the MIB   
            //  tree you wish to retrieve   
            Oid rootOid = new Oid(irootOid); // ifDescr   

            // This Oid represents last Oid returned by   
            //  the SNMP agent   
            Oid lastOid = (Oid)rootOid.Clone();

            // Pdu class used for all requests   
            Pdu pdu = new Pdu(PduType.GetBulk);

            // In this example, set NonRepeaters value to 0   
            pdu.NonRepeaters = 0;
            // MaxRepetitions tells the agent how many Oid/Value pairs to return   
            // in the response.   
            pdu.MaxRepetitions = 200;

            // Loop through results   
            while (lastOid != null)
            {
                // When Pdu class is first constructed, RequestId is set to 0   
                // and during encoding id will be set to the random value   
                // for subsequent requests, id will be set to a value that   
                // needs to be incremented to have unique request ids for each   
                // packet   
                if (pdu.RequestId != 0)
                {
                    pdu.RequestId += 1;
                }
                // Clear Oids from the Pdu class.   
                pdu.VbList.Clear();
                // Initialize request PDU with the last retrieved Oid   
                pdu.VbList.Add(lastOid);
                // Make SNMP request 
                SnmpV2Packet result;
                try
                {
                    result = (SnmpV2Packet)target.Request(pdu, param);
                }
                catch
                {
                    return null;
                }
                
                // You should catch exceptions in the Request if using in real application.   

                // If result is null then agent didn't reply or we couldn't parse the reply.   
                if (result != null)
                {
                    // ErrorStatus other then 0 is an error returned by    
                    // the Agent - see SnmpConstants for error definitions   
                    if (result.Pdu.ErrorStatus == 0)
                    {
                        // Walk through returned variable bindings   
                        foreach (Vb v in result.Pdu.VbList)
                        {
                            // Check that retrieved Oid is "child" of the root OID   
                            if (rootOid.IsRootOf(v.Oid))
                            {
                                dic.Add(v.Oid.ToString(), v.Value.ToString());
                            }
                            else
                            {
                                // we have reached the end of the requested   
                                // MIB tree. Set lastOid to null and exit loop   
                                lastOid = null;
                                break;
                            }
                        }
                        //lastOid = null; //取完就结束吧!
                    }
                }
            }
            target.Close();
            return dic;
        }
        #endregion   
    }
}

Utils.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
using System.IO;
namespace SNMP_SW
{
    class Utils
    {
        public static string toJson(object obj)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            string json = serializer.Serialize(obj);
            return json;
        }
        public static bool save(string filename, string json)
        {
            try
            {
                StreamWriter sw = new StreamWriter(filename, false);
                sw.Write(json);
                sw.Close();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
            
        }
    }
}

effect:
Here Insert Picture Description

Published 48 original articles · won praise 3 · views 20000 +

Guess you like

Origin blog.csdn.net/chscomfaner/article/details/103921403