Click here to Skip to main content
15,900,713 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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?
Posted
Comments
fuximus 27-Oct-11 21:33pm    
Apparently there is a WMI class to get a route, not sure how to go about it

1 solution

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:
C#
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;



actual property is public string MacAddress { get; } defined as follows:
C#
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>


and the small Route class, not sure if it was necessary:
C#
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;
        }
    }
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900