C#.NET 4.0,如何获取连接到远程主机的本地NIC的mac地址. [英] C# .NET 4.0, how to get mac address of a local NIC connecting to a remote host.

查看:86
本文介绍了C#.NET 4.0,如何获取连接到远程主机的本地NIC的mac地址.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的情况:
我们需要连接到特定的MSSQL主机,我们知道它的实例名称,我们正在使用ADO.NET连接字符串生成EntityConnection字符串.

因此,我们可以获得MSSQL服务器的主机名.

连接到它之后,我们需要调用sp_login存储过程,该过程使用3个参数:用户名密码和mac地址.

到目前为止,我已经能够检索服务器的IP地址,使所有当前的NIC在客户端上运行.

当前解决方案:
获取MSSQL服务器的IP地址(ip4和ip6),
获取客户端计算机的路由表,
交叉检查路由表以及MSSQL服务器的IP地址,
找到界面,
获取接口的mac地址.

问题1:
我一直在寻找可以为我提供当前IP路由表的API或.NET类,还没有运气

问题2:
这是正确的方法吗?我的意思是,是否存在服务器端Transact SQL函数/解决方案,该功能/解决方案从客户端建立的连接中获取mac地址.
或是否有一个单一功能可获取与任何连接相关的所有信息,例如:提供一个主机名或ip,它返回NIC,路由,ip,端口以及其他内容?

我敢肯定,如果我花更多的时间进行谷歌搜索,我将完成所有必要的步骤.但是,执行所有这些步骤并分别搜索每个步骤,使我想知道是否有更短的解决方案.
任何指针有人吗?

Well here''s the situation:
There''s a particular MSSQL host we need to connect to, we know it''s instance name, we''re generating a EntityConnection string using ADO.NET connection string.

So, we can get the Hostname of the MSSQL server.

right after connecting to it, we need to call sp_login stored procedure that takes in 3 arguments: username password and mac address.

So far, I''ve been able to to retrieve ip address of the server, get all the current NICs running on client.

current solution:
get the IP addresses of MSSQL server(ip4 and ip6),
get the routing table of the client computer,
cross check routing table with the IP addresses of the MSSQL server,
find the interface,
get the interface mac address.

problem 1:
I''ve been looking for an API or .NET class that would provide me with current IP Routing Table, no luck yet

problem 2:
Is this the correct way to go about it? I mean, is there a server side Transact SQL function/solution that gets the mac address from the connection made from the client.
OR is there a 1 single function that gets all the information associated with any connection, for example: provide a hostname or ip and it returns NIC, route, ips, ports and what not?

I''m sure if I spend more time googling, I''d get all the necessary steps done. But doing all of those steps and googling each one separately makes me wonder whether there''s a shorter solution.
any pointers anyone?

推荐答案

这里是我到目前为止提出的解决方案,请注意:要获取路由表,请参见使用Windows提供的"route PRINT" cmd提示符命令,我知道这是完成工作的非常不可靠的方法,我应该使用Iphlpapi.dll API库来获取路由表.要做简单的事情太麻烦了,好在这里的代码

包括:
well here''s the solution i''ve come up with so far, note: to get the routing table i''ve used the windows provided "route PRINT" cmd prompt command, which I know to be very unreliable way to get the job done, what I should have done is used the Iphlpapi.dll API library to get the routing table. It''s just too much of a hassle to get something simple done, well here''s the code

includes:
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using Microsoft.Win32;




实际属性是公共字符串MacAddress {get; }定义如下:




actual property is public string MacAddress { get; } defined as follows:

public class Config
{
    public Config(string conn_string = "")
    {
        this.ConnectionString = conn_string;
    }

    private string _mac_address = null;
    public string ConnectionString { get; set; }

    public string MacAddress {
        get
        {
            if (this._mac_address == null)
            {
                SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(this.ConnectionString);
                
                //address of the host server
                IPAddress[] addres = Dns.GetHostAddresses(csb.DataSource.Split('\\')[0]);
                
                //execute cmd command "route PRINT" and get the output into a string
                Process p = new Process();
                // Redirect the output stream of the child process.
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                p.StartInfo.FileName = "route";
                p.StartInfo.Arguments = "PRINT";
                p.Start();
                string output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                p.Close();
                p.Dispose();

                
                string[] lines = output.Split(new string[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries);

                List<route> routes = new List<route>();
                bool found = false;
                foreach (string line in lines) {
                    if (line == "Active Routes:") {
                        if (found) { //if routes have already been found exit loop, meaning this is IPv6 routes, should never reach this point
                            break;
                        }
                        found = true;
                        continue;
                    }

                    if (found) {
                        if (line[0] == 'N') { //if the line is headers skip it
                            continue;
                        }
                        else if (line[0] == '=') { //if the routes have ended exit loop
                            break;
                        }
                        routes.Add(new Route(line)); //read route, custom class
                    }
                }
                routes.Sort(); //sort routes by Mask, then by Address
                string nic_addr = "";

                foreach (IPAddress addr in addres) {
                    if (addr.AddressFamily == AddressFamily.InterNetwork) { //if IPv4
                        for (int i = routes.Count - 1; i >= 0; i--) { //start from the largest Mask
                            if(routes[i].IncludesHost(addr)) { //whether the ip fits in the subnet
                                nic_addr = routes[i].ReadableInterface;
                                break; //if so, save interface name, exit loop
                            }
                        }
                        break;
                    }
                }



                //Get NIC of found Interface by IP
                foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
                    if (nic.OperationalStatus == OperationalStatus.Up) {
                        IPInterfaceProperties properties = nic.GetIPProperties();
                        foreach (UnicastIPAddressInformation addr_info in properties.UnicastAddresses) {
                            if (addr_info.Address.AddressFamily == AddressFamily.InterNetwork && addr_info.Address.ToString()==nic_addr) {
                                this._mac_address = nic.GetPhysicalAddress().ToString();
                                break;  //if address matches that of the routing table interface address then save MAC and exit loop
                            }
                        }

                        if (this._mac_address != null)
                            break; //if mac address is found exit loop;       
                    }
                }

            }
            return this._mac_address;
        }
    }
}
</route></route>



和小型Route类,不确定是否有必要:



and the small Route class, not sure if it was necessary:

public class Route : IComparable
{
    private uint _address;
    private uint _mask;
    private uint _interface;
    private int _metric;

    public uint Address { get { return this._address; } }
    public uint Mask { get { return this._mask; } }
    public uint Interface { get { return this._interface; } }

    public string ReadableAddress { get { return Route.IPLongToString(this._address); } }
    public string ReadableMask { get { return Route.IPLongToString(this._mask); } }
    public string ReadableInterface { get { return Route.IPLongToString(this._interface); } }

    public Route(string[] route)
    {
        this._address=IPStringToLong(route[0]);
        this._mask=IPStringToLong(route[1]);
        this._interface=IPStringToLong(route[3]);
        this._metric=UInt16.Parse(route[4]);
    }

    public Route(string line)
        : this(line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries))
    {
    }

    public static uint IPStringToLong(string str)
    {
        string[] values = str.Split(new char[]{'.'});
        uint multiplier = 1;
        uint value = 0;
        for(int i=3;i>=0;i--) {
            value+=UInt32.Parse(values[i])*multiplier;
            multiplier*=256;
        }
        return value;
    }

    public static string IPLongToString(uint addr)
    {
        byte[] bytes = BitConverter.GetBytes(addr);
        string[] bs = new string[]{"","","",""};

        for(int i=0;i<4;i++) {
             bs[i] = bytes[3-i].ToString();
        }
        return String.Join(".",bs);
    }

    public bool IncludesHost(IPAddress addr)
    {
        if (addr.AddressFamily == AddressFamily.InterNetwork)
            return this.IncludesHost(Route.IPStringToLong(addr.ToString()));
        else
            return false;
    }

    public bool IncludesHost(string addr)
    {
        return this.IncludesHost(Route.IPStringToLong(addr));
    }

    public bool IncludesHost(long addr)
    {
        return (this._mask&this._address) == (this._mask&addr);
    }

    public int CompareTo(object _y)
    {
        Route y = (Route)_y;
        if (y == null) 
            return 1;
        else
        {
            int retval = this.Mask.CompareTo(y.Mask);
            if (retval != 0) 
                return retval;
            else 
                return this.CompareToByAddress(y);
        }
    }

    public int CompareToByAddress( Route y)
    {
        if (y == null)
            return 1;
        else {
            int retval = this.Address.CompareTo(y.Address);
            if (retval != 0) 
                return retval;
            else // should never reach this point, if it does means there are duplicate network address and mask
                return 0;
        }
    }
}


这篇关于C#.NET 4.0,如何获取连接到远程主机的本地NIC的mac地址.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆