patterncsharpMinor
C# .NET getting mac-address of a local NIC that's making a connection to a particular host
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;
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.