Get the Default Gateway - c#

I'm writing a program that shows the user their IP address, Subnet mask and Default gateway. I can get the first two, but for the last one, this is what I turned up:
GatewayIPAddressInformationCollection gwc =
System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].GetIPProperties().GatewayAddresses;
That, of course, returns a collection of GatewayIPAddressInformation. So, if a computer has multiple gateways, how can I determine which is the default gateway?
In practice, I've only ever seen this collection contain a single entry, but since it's implemented as a collection, it stands to reason that some computers contain multiple gateways, none of which are marked as "Default". So is there a way to determine the default or is it all just guesswork?

It will probably be the first valid and enabled gateway address of the first enabled network interface:
public static IPAddress GetDefaultGateway()
{
return NetworkInterface
.GetAllNetworkInterfaces()
.Where(n => n.OperationalStatus == OperationalStatus.Up)
.Where(n => n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.SelectMany(n => n.GetIPProperties()?.GatewayAddresses)
.Select(g => g?.Address)
.Where(a => a != null)
// .Where(a => a.AddressFamily == AddressFamily.InterNetwork)
// .Where(a => Array.FindIndex(a.GetAddressBytes(), b => b != 0) >= 0)
.FirstOrDefault();
}
I've also added some further commented checks which have been pointed out as useful by other people here. You can check the AddressFamily one to distinguish between IPv4 and IPv6. The latter one can be used to filter out 0.0.0.0 addresses.
The above solution will give you a valid/connected interface, and is good enough for 99% of situations. That said, if you have multiple valid interfaces that traffic can be routed through, and you need to be 100% accurate, the way to do this uses GetBestInterface to find an interface for routing to a specific IP address. This additionally handles the case where you might have a specific address range routed through a different adapter (e.g. 10.*.*.* going through a VPN, everything else going to your router)
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto)]
private static extern int GetBestInterface(UInt32 destAddr, out UInt32 bestIfIndex);
public static IPAddress GetGatewayForDestination(IPAddress destinationAddress)
{
UInt32 destaddr = BitConverter.ToUInt32(destinationAddress.GetAddressBytes(), 0);
uint interfaceIndex;
int result = GetBestInterface(destaddr, out interfaceIndex);
if (result != 0)
throw new Win32Exception(result);
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
var niprops = ni.GetIPProperties();
if (niprops == null)
continue;
var gateway = niprops.GatewayAddresses?.FirstOrDefault()?.Address;
if (gateway == null)
continue;
if (ni.Supports(NetworkInterfaceComponent.IPv4))
{
var v4props = niprops.GetIPv4Properties();
if (v4props == null)
continue;
if (v4props.Index == interfaceIndex)
return gateway;
}
if (ni.Supports(NetworkInterfaceComponent.IPv6))
{
var v6props = niprops.GetIPv6Properties();
if (v6props == null)
continue;
if (v6props.Index == interfaceIndex)
return gateway;
}
}
return null;
}
These two examples could be wrapped up into a helper class and used in the appropriate cases: that you do, or do not have a destination address in mind already.

The first IP address returned by traceroute command will be the gateway .You can use this fact for getting gateway.A nice implementation of tracerout can be found here:
TraceRoute and Ping in C#

according to #midspace's comment on #caesay's answer this is a better answer:
public static IPAddress GetDefaultGateway()
{
var gateway_address = NetworkInterface.GetAllNetworkInterfaces()
.Where(e => e.OperationalStatus == OperationalStatus.Up)
.SelectMany(e => e.GetIPProperties().GatewayAddresses)
.FirstOrDefault();
if (gateway_address == null) return null;
return gateway_address.Address;
}
I'm warning that it's not a complete solution, if your'e looking for the main interface responsible for the internet access, you should combine other approaches like using win32 API GetBestInterface to find the best interface to connect to a destination address.
you can find example usage here: http://www.pinvoke.net/default.aspx/iphlpapi.getbestinterface

I've just come across this and will be using the following code - basically it looks for interfaces that aren't loopback and are up and have gateways and unicast addresses. From the interface I then get a non transient IPV4 address.
public static class NetworkInterfaces
{
public static NetworkInterface GetDefaultInterface()
{
var interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
foreach (var intf in interfaces)
{
if (intf.OperationalStatus != OperationalStatus.Up)
{
continue;
}
if (intf.NetworkInterfaceType == NetworkInterfaceType.Loopback)
{
continue;
}
var properties = intf.GetIPProperties();
if (properties == null)
{
continue;
}
var gateways = properties.GatewayAddresses;
if ((gateways == null) || (gateways.Count == 0))
{
continue;
}
var addresses = properties.UnicastAddresses;
if ((addresses == null) || (addresses.Count == 0))
{
continue;
}
return intf;
}
return null;
}
public static IPAddress GetDefaultIPV4Address(NetworkInterface intf)
{
if (intf == null)
{
return null;
}
foreach (var address in intf.GetIPProperties().UnicastAddresses)
{
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
{
continue;
}
if (address.IsTransient)
{
continue;
}
return address.Address;
}
return null;
}
}

I know this is a slightly older question but, I had just come upon the need to retrieve the IPV4 address of the local gateway. The accepted answer doesn't quite fit the bill when it comes to my own system so, I modified it to suite and I'm sure others will be able to use this solution, too.
Since I don't yet have enough rep to comment, I'm forced to add this as a "question":
public static IPAddress GetDefaultGateway()
{
IPAddress result = null;
var cards = NetworkInterface.GetAllNetworkInterfaces().ToList();
if (cards.Any())
{
foreach (var card in cards)
{
var props = card.GetIPProperties();
if (props == null)
continue;
var gateways = props.GatewayAddresses;
if (!gateways.Any())
continue;
var gateway =
gateways.FirstOrDefault(g => g.Address.AddressFamily.ToString() == "InterNetwork");
if (gateway == null)
continue;
result = gateway.Address;
break;
};
}
return result;
}

Been looking for one weird trick to determine the local IP address?
Yet do it very robustly vs. the earlier methods?
[See end for response to #caesay]
This may be what you are looking for.
using (var s = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp))
{
s.Bind( new System.Net.IPEndPoint(System.Net.IPAddress.Any,0));
s.Connect("google.com",0);
var ipaddr = s.LocalEndPoint as System.Net.IPEndPoint;
var addr = ipaddr.Address.ToString();
Console.WriteLine(addr);
}
That will create a UDP socket, but will not send data on it.
You can then see what local interface and address the socket was bound to.
You must supply an IP address or hostname where I used google.com, that will
be used by the OS to determine which interface the socket will be bound to,
and what IP address you will find using this method.
For 99%+ of IP addresses or hostnames you use, you will get the interface+address to be used for traffic over the default route.
While this is a little obtuse, I suspect it is more reliable than the methods above where people use the PInvoke call and scan through the structures to see if they can find the interface.
I certainly found it more robust on my 3x double interface systems than scanning through the results of NetworkInterface.GetAllNetworkInterfaces() using heuristics to try to figure out the default interface address.
[Update/response to #caesay 2/6/2019]
#caesay Has made an excellent point here, so I have switched the sample from using UdpClient to Socket, and explicitly called Socket.Connect() after Bind(). I have also reviewed the Framework source for Connect() and LocalEndPoint, and both call their corresponding Win32 OS system call immediately without deferring or being lazy about calling into the OS. The Win32 bind page says "The application can use getsockname after calling bind to learn the address and the port that has been assigned to the socket. If the Internet address is equal to INADDR_ANY or in6addr_any, getsockname cannot necessarily supply the address until the socket is connected".
This condition is now explicitly addressed, and having reviewed the Framework source, the IP address should always be available after the Connect() call.

NetworkInterface[] allNICs = NetworkInterface.GetAllNetworkInterfaces();
foreach (var nic in allNICs)
{
var ipProp = nic.GetIPProperties();
var gwAddresses = ipProp.GatewayAddresses;
if (gwAddresses.Count > 0 &&
gwAddresses.FirstOrDefault(g => g.Address.AddressFamily == AddressFamily.InterNetwork) != null)
{
localIP = ipProp.UnicastAddresses.First(d => d.Address.AddressFamily == AddressFamily.InterNetwork).Address;
}
}
Debug.Print(localIP.ToString());

(Just after posting I noticed an earlier answer that mentioned the idea of using traceroute. I probably wouldn't have responded if I'd seen that. But I have included complete/compact code.)
Here's a different approach that finds the default gateway by using a traceroute type method. Ping an address on the internet (or other network you want to get to) with a TTL of 1, and let ping tell you what the first hop IP address was. That ought to be the gateway you're looking for.
I suppose this could go wrong if the gateway was configured not to reply to pings, but I don't think I've ever heard of a network set up that way.
Note: This routine kind-of even works if you pass it an IPV6 address. The potential issue is that it seems to return an IPV6 address with Global scope, rather than Link-Local scope. I don't have enough experience using IPV6 to know if that's good or bad. But I do know that the Windows ipconfig command displays the Link-Local IPV6 addresses of the interface gateway.
using System.Net
using System.Net.NetworkInformation
// ping internet address with ttl=1 and return address of host where ttl expired
public static IPAddress FindDefaultGateway(IPAddress netaddr = null)
{
// user can provide an ip address that exists on the network they want to connect to,
// or this routine will default to 1.1.1.1 (IP of a popular internet dns provider)
if (netaddr is null)
netaddr = IPAddress.Parse("1.1.1.1");
PingReply reply = default;
using var ping = new Ping();
var options = new PingOptions(1, true); // ttl=1, dont fragment=true
try {
// I arbitrarily used a 200ms timeout; tune as you see fit.
reply = ping.Send(netaddr, 200, new byte[0], options);
}
catch (PingException) {
System.Diagnostics.Debug.WriteLine("Gateway not available");
return default;
}
if (reply.Status != IPStatus.TtlExpired) {
System.Diagnostics.Debug.WriteLine("Gateway not available");
return default;
}
return reply.Address;
}

I think that you should iterate over this collection and show all the Gateways, since if there are many gateways to an adapter they are all considered Default to that adapter

Related

How to get IP and MAC addresses of the adapter that connects to the Internet?

when using System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName())to get IP addresses and
private System.Net.NetworkInformation.PhysicalAddress GetMacAddress()
{
foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
{
// Only consider Ethernet network interfaces
if (nic.NetworkInterfaceType == System.Net.NetworkInformation.NetworkInterfaceType.Ethernet &&
nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up)
{
return nic.GetPhysicalAddress();
}
}
return null;
}
to get the MAC adddress, I get all addresses. Is there a way to get only the adapter and IP that actually connects to the net?
With above calls, I also get IP's and MAC's belonging to virtual adapters, such as the created by VMWare.
Regards
Jaime
As a good approach, I am looking for the NIC that has a gateway set. This works in my case:
private static IEnumerable<System.Net.NetworkInformation.NetworkInterface> GetAllNetworkInterfaces(IEnumerable<System.Net.NetworkInformation.NetworkInterfaceType> excludeTypes)
{
var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().Where(nic => nic.GetIPProperties().GatewayAddresses.Any() && nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up);
var exclude = all.Where(i => excludeTypes.Contains(i.NetworkInterfaceType));
return all.Except(exclude);
}
And then, use it like this:
var nic = GetAllNetworkInterfaces(new[] { System.Net.NetworkInformation.NetworkInterfaceType.Tunnel, System.Net.NetworkInformation.NetworkInterfaceType.Loopback });
txtRegistro.AppendText($"Local IP -> {string.Join(", ", nic.SelectMany(n => n.GetIPProperties().UnicastAddresses).Where(i => i.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Select(i => i.Address.ToString()))}\r\n");
txtRegistro.AppendText($"MAC Address -> {string.Join(", ", nic.Select(a => string.Join(":", a.GetPhysicalAddress().GetAddressBytes().Select(b => b.ToString("X2")))))}\r\n\r\n");
With above code, I am getting which NIC has a connection to a network (LAN or WAN) as long as the connected router provides a gateway.
Regards
Jaime
My adapter network interface have 5:
{"Id":"{FD94887A-FEEB-4F0B-AE11-D3A36137976B}","Name":"Ethernet","Description":"Intel(R) Ethernet Connection I217-LM","NetworkInterfaceType":6,"OperationalStatus":2,"Speed":-1,"IsReceiveOnly":false,"SupportsMulticast":true}
{"Id":"{765A365A-6D0B-4ACB-BCC8-779F481DC5D5}","Name":"Local Area Connection* 13","Description":"Microsoft Wi-Fi Direct Virtual Adapter #5","NetworkInterfaceType":71,"OperationalStatus":2,"Speed":-1,"IsReceiveOnly":false,"SupportsMulticast":true}
{"Id":"{D888C03B-82F1-4BBB-AB99-185F21B62159}","Name":"Local Area Connection* 14","Description":"Microsoft Wi-Fi Direct Virtual Adapter #6","NetworkInterfaceType":71,"OperationalStatus":2,"Speed":-1,"IsReceiveOnly":false,"SupportsMulticast":true}
{"Id":"{56ECAAAF-8916-4358-A8DB-FB6E7448133D}","Name":"Wi-Fi 4","Description":"Intel(R) Centrino(R) Ultimate-N 6300 AGN","NetworkInterfaceType":71,"OperationalStatus":1,"Speed":135000000,"IsReceiveOnly":false,"SupportsMulticast":true}
{"Id":"{80377EDA-E86D-11E8-BA87-806E6F6E6963}","Name":"Loopback Pseudo-Interface 1","Description":"Software Loopback Interface 1","NetworkInterfaceType":24,"OperationalStatus":1,"Speed":1073741824,"IsReceiveOnly":false,"SupportsMulticast":true}
There are 3 attributes we need to care about: NetworkInterfaceType, OperationalStatus, Speed
This is my code:
private PhysicalAddress GetMacAddress()
{
var allowNetworkInterfaceType = new[] { NetworkInterfaceType.Ethernet , NetworkInterfaceType.Wireless80211 , NetworkInterfaceType.GigabitEthernet };
var networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(x=>x.OperationalStatus == OperationalStatus.Up && allowNetworkInterfaceType.Contains(x.NetworkInterfaceType) && x.Speed > 0);
return networkInterface?.GetPhysicalAddress();
}

Find Ip correctly with C#

I want to find the ip that my computer connects to the internet correctly.I have questions about a few things I have tried.
Firstly :
foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) {
var addr = ni.GetIPProperties().GatewayAddresses.FirstOrDefault();
if (addr != null && ni.OperationalStatus == OperationalStatus.Up) {
switch (ni.NetworkInterfaceType) {
case NetworkInterfaceType.Wireless80211:
case NetworkInterfaceType.Ethernet:
{
foreach(UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) {
if (ip.Address.AddressFamily == AddressFamily.InterNetwork) {
return ip.Address.ToString();
}
}
break;
}
}
}
}
When I tried the code above, if my computer has a virtual adapter installed (for example vpn), the vpn adapter is also detected as ethernet and operational status up. When I run vpn, there are two strings ip like (192.168.1.24 and 25.25.1.150).
As a result of this error, I decided to find the name of my computer and ping it and find a rope with the returned result.
like the code below:
int timeout = 10000;
Ping ping = new Ping();
try {
PingReply pingreply = ping.Send(Environment.MachineName.ToString(), timeout);
if (pingreply.Status == IPStatus.Success) {
return pingreply.Address.ToString();
}
}
catch(Exception ex) {
LogHelper.WriteErrorLog(ex);
return String.Empty;
}
return String.Empty;
The code above works fine, but there are a few things I can't be sure of. Is there a possibility that the hostname with the second code will be return null? If there are two computer names in the same domain(can be possible?), can I get the correct result from the ping result? Is there any other way than these two codes find correctly under all circumstances? Thank you.

C# multiple ip addresses on one network interface

All we know that PC can have one or more network interfaces. Each network interface can have one or two (maybe more) ip addresses. The problem is how to determine which ip address will be used to communicate with remote host.
I know how to get network interface using next code (thank's guys from pinvoke.net):
private static NetworkInterface GetNetworkInterfaceByIndex(uint index)
{
// Search in all network interfaces that support IPv4.
NetworkInterface ipv4Interface = (from thisInterface in NetworkInterface.GetAllNetworkInterfaces()
where thisInterface.Supports(NetworkInterfaceComponent.IPv4)
let ipv4Properties = thisInterface.GetIPProperties().GetIPv4Properties()
where ipv4Properties != null && ipv4Properties.Index == index
select thisInterface).SingleOrDefault();
if (ipv4Interface != null)
return ipv4Interface;
// Search in all network interfaces that support IPv6.
NetworkInterface ipv6Interface = (from thisInterface in NetworkInterface.GetAllNetworkInterfaces()
where thisInterface.Supports(NetworkInterfaceComponent.IPv6)
let ipv6Properties = thisInterface.GetIPProperties().GetIPv6Properties()
where ipv6Properties != null && ipv6Properties.Index == index
select thisInterface).SingleOrDefault();
return ipv6Interface;
}
[DllImport("iphlpapi.dll", SetLastError = true)]
static extern int GetBestInterface(uint DestAddr, out uint BestIfIndex);
static void IpAddressLogTest()
{
Console.Write("Enter IP address to choose interface: ");
IPAddress addr;
IPAddress.TryParse(Console.ReadLine(), out addr);
uint bestintf;
var res = GetBestInterface(BitConverter.ToUInt32(addr.GetAddressBytes(), 0), out bestintf);
NetworkInterface interfaceInfo = GetNetworkInterfaceByIndex(bestintf);
foreach (var a in interfaceInfo.GetIPProperties().UnicastAddresses)
if (a.Address.AddressFamily == AddressFamily.InterNetwork)
Console.WriteLine(a.Address.ToString());
Console.ReadLine();
}
This code works perfectly and i know what interface will be used to communicate with host. But interface can have two ip addresses in different networks.
How in that case to choose right ip address?
UPD1. Example of such settings:

How to check if localhost

Is there a way in c# to check if the app is running on localhost (as opposed to a production server)?
I am writing a mass mailing program that needs to use a certain mail queue is it's running on localhost.
if (Localhost)
{
Queue = QueueLocal;
}
else
{
Queue = QueueProduction;
}
As a comment has the correct solution I'm going to post it as an answer:
HttpContext.Current.Request.IsLocal
What about something like:
public static bool OnTestingServer()
{
string host = HttpContext.Current.Request.Url.Host.ToLower();
return (host == "localhost");
}
Use a value in the application configuration file that will tell you what environment you are on.
Since you are using asp.net, you can utilize config file transforms to ensure the setting is correct for each of your environments.
See if this works:
public static bool IsLocalIpAddress(string host)
{
try
{ // get host IP addresses
IPAddress[] hostIPs = Dns.GetHostAddresses(host);
// get local IP addresses
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
foreach (IPAddress hostIP in hostIPs)
{
// is localhost
if (IPAddress.IsLoopback(hostIP)) return true;
// is local address
foreach (IPAddress localIP in localIPs)
{
if (hostIP.Equals(localIP)) return true;
}
}
}
catch { }
return false;
}
Reference: http://www.csharp-examples.net/local-ip/
Localhost ip address is constant, you can use it to determines if it´s localhost or remote user.
But beware, if you are logged in the production server, it will be considered localhost too.
This covers IP v.4 and v.6:
public static bool isLocalhost( )
{
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
return (ip == "127.0.0.1" || ip == "::1");
}
To be totally sure in which server the code is running at, you can use the MAC address:
public string GetMACAddress()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sMacAddress = string.Empty;
foreach (NetworkInterface adapter in nics)
{
if (sMacAddress == String.Empty)// only return MAC Address from first card
{
IPInterfaceProperties properties = adapter.GetIPProperties();
sMacAddress = adapter.GetPhysicalAddress().ToString();
}
} return sMacAddress;
}
from: http://www.c-sharpcorner.com/uploadfile/ahsanm.m/how-to-get-the-mac-address-of-system-using-Asp-NetC-Sharp/
And compare with a MAC address in web.config for example.
public static bool isLocalhost( )
{
return GetMACAddress() == System.Configuration.ConfigurationManager.AppSettings["LocalhostMAC"].ToString();
}
Unfortunately there is no HttpContext.HttpRequest.IsLocal() anymore within core.
But after checking the original implementation in .Net, it is quite easy to reimplement the same behaviour by checking HttpContext.Connection:
private bool IsLocal(ConnectionInfo connection)
{
var remoteAddress = connection.RemoteIpAddress.ToString();
// if unknown, assume not local
if (String.IsNullOrEmpty(remoteAddress))
return false;
// check if localhost
if (remoteAddress == "127.0.0.1" || remoteAddress == "::1")
return true;
// compare with local address
if (remoteAddress == connection.LocalIpAddress.ToString())
return true;
return false;
}
Or, you could use a C# Preprocessor Directive if your simply targeting a development environment (this is assuming your app doesn't run in debug in production!):
#if debug
Queue = QueueLocal;
#else
Queue = QueueProduction;
just like this:
HttpContext.Current.Request.IsLocal
string hostName = Request.Url.Host.ToString();
I know this is the really old thread but still, someone looking for a straight solution then you can use this:
if (HttpContext.Current.Request.Url.Host == "localhost")
{
//your action when app is running on localhost
}
This is an alternative, more transparent, option:
public static bool IsLocal
{
// MVC < 6
get
{
var authority = HttpContext.Request.Url.Authority.ToLower();
return authority == "localhost" ||
authority.StartsWith("localhost:");
}
// MVC 6+
get
{
return String.Compare(HttpContext.Request.Url.Host, "localhost",
StringComparison.OrdinalIgnoreCase);
}
}
If you're not doing this in the Controller then add Current after HttpContext, as in HttpContext.Current.Request...
Also, in MVC 6, in the View, HttpContext is just Context

IPv4 remote address in WCF

Related to How to get the IP address of a WCF remote endpoint?
I am using this code to retrieve the remote IP address when a workflow method is invoked:
private static string GetRemoteIP()
{
var oc = OperationContext.Current;
var mp = oc.IncomingMessageProperties;
var remp = mp[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
return remp == null ? "(unknown)" : remp.Address;
}
However, the address I get back is "::1". I don't want the IPv6 address, I want the IPv4 one (127.0.0.1) - any way of forcing this?
No, I don't think so. You basically just read out a property set by the client at the time of the call. Your only option would be to instruct the client (through some config) to use IPv4 instead of IPv6 at all times (i.e. turn off IPv6 all together).
I'm not aware of any WCF setting to enforce that - you'd have to dig into the network stack and see if there's any way to make it use IPv4 addresses instead of IPv6.
You're seeing ::1 because you're connecting to the service by resolving the name "localhost" instead of addressing it as "127.0.0.1". Modern versions of Windows that have the IPv6 stack enabled will use IPv6 first.
You can disable the IPv6 stack, but that's roughly the same as making like an ostrich and sticking your head in the sand. IPv6 is here, and people are using it on their networks, so your application should be prepared to support it.
The workaround proposed by Murat will not work.
The MSDN says - if you pass the IP address to the GetHostAddresses method this address is returned in an array without querying the DNS.
To get it working you will need to query for the host name first, using GetHostEntry method. And then, using the host name, use GetHostAddresses. However, even the GetHostEntry may have the list of addresses that will be enough for you.
Here is a workaround: (You can store the values in a hashtable to avoid multiple DNS operations)
static string GetClientIP()
{
var context = OperationContext.Current;
var mp = context.IncomingMessageProperties;
var propName = RemoteEndpointMessageProperty.Name;
var prop = (RemoteEndpointMessageProperty) mp[propName];
string remoteIP = prop.Address;
if(remoteIP.IndexOf(":") > -1)
{
IPAddress[] addresses = Dns.GetHostAddresses(remoteIP);
for (int i = 0; i < addresses.Length; i++)
{
if(addresses[i].ToString().IndexOf(".")>-1)
return addresses[i].ToString();
}
return remoteIP;
}
else
{
return remoteIP;
}
}
You could use AddressFamily.InterNetwork == address.AddressFamily and AddressFamily.InterNetworkV6 as a test instead of looking for ":" or "." in the addresses strings.

Categories