HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

C# .NET getting mac-address of a local NIC that's making a connection to a particular host

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
localaddressmakinggettingnicnetthathostparticularmac

Problem

well, as said in the title: We need to get a mac-address of a NIC that is providing the connection to a particular host. We use the mac-address during the login process using MSSQL and Entity Framework.

technology: C#.NET 4.0, EF 4.1

```
private string _max_address;
public string ConnectionString { get; };

public string MacAddress {
get {
if (this._mac_address == null) {
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(this.ConnectionString);

IPAddress[] addres = Dns.GetHostAddresses(csb.DataSource.Split('\\')[0]);
//find nic interface address from routing table

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.CreateNoWindow = false;
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 routes = new List();
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; //next line
}

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;

Solution

To expand on Strilanc's answer, you can clean up a bit further with the following:

var address = addres.First(e => e.AddressFamily.Equals(AddressFamily.InterNetwork));

// Retrieve routing table
string output = string.Empty;
using (Process p = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            UseShellExecute = false,
            RedirectStandardOutput = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            CreateNoWindow = false,
            FileName = "route",
            Arguments = "PRINT"
        }
    })
{
    p.Start();
    output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();
    p.Close();
}

// Find NIC interface from table
var nicAddr = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
    .SkipWhile(e => !e.Equals("Active Routes:"))
    .Skip(1)
    .TakeWhile(e => !e.Equals("Active Routes:"))
    .TakeWhile(e => !e.StartsWith("="))
    .Where(e => !e.StartsWith("N"))
    .Select(e => new Route(e))
    .OrderByDescending(e => e.Mask)
    .ThenByDescending(e => e.Address)
    .First(e => e.IncludesHost(address))
    .ReadableInterface;

// Get MAC address of associated IP address
var macAddress = NetworkInterface.GetAllNetworkInterfaces()
    .Where(e => e.OperationalStatus.Equals(OperationalStatus.Up))
    .Where(e => e.GetIPProperties().UnicastAddresses
    .Where(a => a.Address.AddressFamily.Equals(AddressFamily.InterNetwork) &&
        a.Address.ToString().Equals(nicAddr)).FirstOrDefault() != null)
        .Select(a => a.GetPhysicalAddress()).FirstOrDefault();

Code Snippets

var address = addres.First(e => e.AddressFamily.Equals(AddressFamily.InterNetwork));

// Retrieve routing table
string output = string.Empty;
using (Process p = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            UseShellExecute = false,
            RedirectStandardOutput = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            CreateNoWindow = false,
            FileName = "route",
            Arguments = "PRINT"
        }
    })
{
    p.Start();
    output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();
    p.Close();
}

// Find NIC interface from table
var nicAddr = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
    .SkipWhile(e => !e.Equals("Active Routes:"))
    .Skip(1)
    .TakeWhile(e => !e.Equals("Active Routes:"))
    .TakeWhile(e => !e.StartsWith("="))
    .Where(e => !e.StartsWith("N"))
    .Select(e => new Route(e))
    .OrderByDescending(e => e.Mask)
    .ThenByDescending(e => e.Address)
    .First(e => e.IncludesHost(address))
    .ReadableInterface;

// Get MAC address of associated IP address
var macAddress = NetworkInterface.GetAllNetworkInterfaces()
    .Where(e => e.OperationalStatus.Equals(OperationalStatus.Up))
    .Where(e => e.GetIPProperties().UnicastAddresses
    .Where(a => a.Address.AddressFamily.Equals(AddressFamily.InterNetwork) &&
        a.Address.ToString().Equals(nicAddr)).FirstOrDefault() != null)
        .Select(a => a.GetPhysicalAddress()).FirstOrDefault();

Context

StackExchange Code Review Q#5709, answer score: 2

Revisions (0)

No revisions yet.