We have the following situation:
The clients are sending events / messages to the server over a webservice. The server can identify the clients according to the "Sender URI". The server must now distribute the message to the "interested listeners".
Now it can be that a client says it is e.g. http://127.0.0.1:8000/ on the server this client is configured with http://localhost:8000.
Uri.Compare( ) and Uri.Equals return both false.
Does anybody knows an algorithm who can identify the URI with all its representations? I mean Localhost == 127.0.0.1 == "Real IP" == "DNS-Name" ?
Thanks
Thomas
Because nobody has posted an answer yet, I will stay with my own made "algorithm" / method which tries to compare all different representations.
What I found out: At the server it is not possible to determine in all cases a remote URL. It can be that the user - account or the subnetwork the server is in, does not have enough privileges to determine e.g. which IP is behind the Active Directory Name.
So there will be always the problem that the server needs a manually filled file or so, which it uses as a base to determine if it knows the sender-URI.
Related
In my WCF service, I need to publish it in the Bonjour service. The reason for this is to make the customers that consume my service know which computer it is running.
This works well.
But when I have machines with special characters in HostName, customers of this service can not eat because an error occurs in time to resolve the url.
Example: "http://máchine:8888/service.svc"
One solution would be to use thought to solve here the IP of the machine in place of the hostname. But when the computer works only with IPv6, I can not publish the service because the following error occurs: "Inalid URI: Invalid port specified."
How can I solve this problem without changing the HostName?
In my experience, when mapping zeroconf services to URLs, it's best to not rely on the service's host name. Resolve the service to an IP address (for example, with avahi, using avahi_service_resolver_new) and use the IP address in the URL. This avoids all sorts of problems with fancy hostnames and system resolvers that can't resolve zeroconf names (often the case on embedded systems).
If you got an error like "Inalid URI: Invalid port specified.", it sounds like you might simply have neglected to enclose the IP address in [square brackets]. The pseudocode for forming your URL should be:
if IP address contains ":"
url = "http://[" + ip address + "]:port/whatever"
else
url = "http://" + ip address + ":port/whatever"
There are two additional complications:
If you are using HTTPS, certificate matching will probably fail because the common name on the certificate won't match. It's not clear what to do about this in general because the very nature of an autodiscovered service usually means you can't meaningfully authenticate the server anyway. So you might be able to get away with just turning off certificate verification in your HTTP client.
You might not be able to use IPv6 link local address because there is a deficiency in the standard (RFC) for URL syntax that means it is not possible to attach a % character and an interface name to the address in the URL. Some HTTP clients allow the obvious extension to the standard to support scoped addresses, but others don't (for example, all of the major web browsers don't!).
I have seen many methods for easily retrieving the internal IP address of a machine or website. However, I can't seem to find a good way to retrieve the external IP address.
To clarify, if I provide a URL like bitbucket.org, I want to get the external IP address of bitbucket. Is there a web service out there that can easily do this?
EDIT: Suppose, for this case, that I am on the same network as bitbucket.org.
I am filling a database with information about all the websites our company manages. We want to keep track of the info and note periodic changes, with specific data. This program will be deployed on one of the local servers on the same network as the servers that the websites are running from. I believe the only good way of retrieving the external IP address for each site is to use an external web service.
You can use System.Net.Dns.GetHostEntry() to get IP address by the host name.
You could query an external public DNS server, e.g. Google's one at 8.8.8.8. From the command line
nslookup bitbucket.org 8.8.8.8
or in Linux dig bitbucket.org #8.8.8.8. There's a few C# libraries out there that will let you query a specific DNS server e.g. DnsNet built on top of this CodeProject article (found searching - I haven't tried it to recommend it). This does rely on Google continuing the service, though, but that seems safe.
You can use the ping utility. In windows, open up a command window by hitting the windows key + r and type
ping bitbucket.org
I think you can just use Dns.GetHostAddresses to get the IP Address. From the MSDN Documentation:
The GetHostAddresses method queries a DNS server for the IP addresses associated with a host name.
UPDATE:
If you are looking for a web service, try looking at whoisxmpapi.com. As you can see from this sample, they do provide the name server IP Address in their XML output. You can then use something like this to get the IP address directly from the name server!
If you are trying to get your "wan" ip instead of your local IP you could try something like this.
You could also add code like this inside a webservice and add it to the PC bitbucket is on (if it is really on your network and you can have access to install webservices).
Public Shared ReadOnly Property IpAddress() As String
Get
If String.IsNullOrWhiteSpace(_ipAddress) Then
Try
Dim webClient As New WebClient
Dim result As String = webClient.DownloadString("http://checkip.dyndns.org")
Dim fields = result.Split(" ")
_ipAddress = fields.Last
_ipAddress = _ipAddress.Replace("</body></html>", "")
Catch ex As Exception
_ipAddress = "errorFindingIp"
End Try
End If
Return _ipAddress
End Get
End Property
Got an asp.net web page in c#. One thing we would like to do is track hits to the site including their IP address. I implemented some code (thanks to SO) but the logged IP address always seem to be local, ie: 192.168.x.x. I have tried it from a variety of devices, even my phone and Version MiFi just to make sure its not something weird with the ISP but the log always list the same 2-3 different internal ip addresses (seems to change a little as the day goes on).
Here is my function that gets the IP (again thanks to postings here on SO):
protected IPAddress GetIp(HttpRequest request)
{
string ipString;
if (string.IsNullOrEmpty(request.ServerVariables["HTTP_X_FORWARDED_FOR"]))
ipString = request.ServerVariables["REMOTE_ADDR"];
else
ipString = request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
IPAddress result;
if (!IPAddress.TryParse(ipString, out result))
result = IPAddress.None;
return result;
}
public void logHit()
{
IPAddress ip = GetIp(Request);
string sIP = ip.ToString();
}
I tried this as well which yields the same result:
HttpContext.Current.Request.UserHostAddress;
When I do a call on the client side using something like the service on appspot, it works just fine:
<script type="application/javascript">
function getip(json) {
//txtIP is a input box on the form
document.getElementById("txtIP").value = json.ip;
}
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"></script>
I suppose I could do a round-about way by hitting that appspot link and parse it out but that seems like a whole lot of trouble for something that should be simple.
Could it be the IIS on the server? Some kind of redirect going on? The ip addresses logged are NOT the servers. The problem is I dont have direct access to it so I have to talk to the guys that admin it and would like to give them some direction before they just start changing things.
Thanks
Ernie
If the HTTP_X_FORWARDED_FOR header is truly supported, then I think this would not be either forward or reverse proxy server causing this, but more likely Dynamic Network Address Translation or Dynamic Port Address Translation, which is happening below the application layer on the TCP/IP stack and thus would not affect an HTTP request header.
There are many ways to configure NAT, most of which would not cause these symptoms, but it is certainly possible to configure NAT in a way that would present this problem. Dynamic NAT or Dynamic PAT would be two such examples, and I would suggest this is what you ask your network administrators.
For more on Dynamic NAT/PAT, with good examples, you could review: http://www.cisco.com/en/US/docs/security/asa/asa82/configuration/guide/nat_dynamic.html
In a typical NAT scenario, the request packets reach the NAT device (firewall or router) as:
FROM - 5.5.5.5 (public address of the client)
TO - 6.6.6.6 (the public address of the server)
The "typical" NAT configuration would rewrite only the destination, as follows:
FROM - 5.5.5.5
TO - 192.168.6.6 (the private address of the server)
In this typical case, the server would still see REMOTE_ADDR as 5.5.5.5, as that is the source address on the incoming request. Then, the packets would be returned to 5.5.5.5, and the response would return to the client successfully.
Now, in the case of dynamic PAT, for example, the request would reach the NAT device as follows:
FROM - 5.5.5.5
TO - 6.6.6.6
Then, the NAT device would rewrite both source and destination packets, maintaining this "dynamic" mapping for only the lifetime of the request:
FROM - 192.168.1.1:12345 (the dynamic PAT address)
TO - 192.168.6.6 (the private address of the server)
Now, when the server sees this request, it appears to be from private address 192.168.1.1. In fact, with a strict PAT all requests will appear to be from this address. In your case, there are 2 or 3 of these addresses, probably because you may have enough traffic that you risk running out of ports if you use only a single dynamic PAT address.
So, your REMOTE_ADDR is 192.168.1.1, because that is actually the source address on the request packets. There is no HTTP_X_FORWARDED_FOR, because the Dynamic PAT is occurring at a lower TCP/IP layer (address and not application).
Finally, the response is sent back to 192.168.1.1:12345, which routs to the NAT device, which for the duration of the request/response (see the Cisco documentation above) maps it back to 5.5.5.5, and then drops the "dynamic" mapping.
Everything worked perfectly, the client gets the response back, except that you have no idea of the actual client address from the viewpoint of the server. And if it is dynamic NAT in play, I don't see how you could get this information from the server.
Fortunately, you did exactly the right thing to get the information in javascript on the client, so this likely solves your problem as well as it could be solved.
It depends on your network structure. Simply a firewall or load balancer can change the variables which you are checking.
if you are using a load balancer check this:
How to get visitor IP on load balancing machine using asp.net
if your sever is behind a firewall check this:
Find if request was forwarded from firewall to IIS
Good afternoon,
Can anyone give any examples of how to obtain the IP Address of the local machine when it's connected to a remote windows domain network via VPN (RAS)? i.e. I need the VPN address and not the remote users local network address.
For example, my Server Side Windows Service communicates with my client side application and needs to create a log of all connected users and their IP Addresses.
This solution is easy enough when using a computer on the local network, but I wondered how I can go about getting the IP addresses of the users who are connected to the server via VPN. Please note that the IP address get method will be executed client side and sent to the server.
Here's my current code that works only when locally connected to the domain network:
public static string GetLocalIPv4()
{
string ipv4Address = String.Empty;
foreach (IPAddress currrentIPAddress in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (currrentIPAddress.AddressFamily.ToString() == System.Net.Sockets.AddressFamily.InterNetwork.ToString())
{
ipv4Address = currrentIPAddress.ToString();
break;
}
}
return ipv4Address;
}
Our internal network is controlled by Windows SBS and uses a domain such as mycompany.local.
Thank you very much for your time and I look forward to reading your responses.
Rob
As the comment from #MarcB notes, cannot think of a good reason why you might want that info... so would be interesting if you could explain a use for this in an application just out of curiosity.
However, there are a lot of incorrect answers on here and online regarding enumerating IP addresses for a machine by using Dns.GetHostAddresses. It appears most people are not realizing the difference between looking up a machine name in the configured DNS resolver versus enumerating the machine address. These are very different things and while it might seem to return the right results in many cases, this is absolutely the wrong way to go about it because they are not the same thing. For example, see this link to an article on here where the original poster flagged an incorrect response as the answer but the correct response is below by #StephanCleary. See:
Get IPv4 Addresses
The difference is you want to look at the machines configuration and enumerate whatever IP address you are interested in locating from the machines own TCPIP stack. The code above and many of the incorrect responses try to lookup the name in the DNS resolver. Once you have that part correct, then you should be able to determine the VPN connection based on the network adaptor (by name or other attribute).
Im getting frustrated because of OpenDNS and other services (ie: roadrunner) that now always returns a ping even if you type any invalid url ie: lkjsdaflkjdsjf.com --- I had created software for my own use that would ping a url to verify if the site was up or not. This no longer works. Does anyone have any ideas about this?
Requirements:
It should work with any valid web site, even ones i dont control
It should be able to run from any network that has internet access
I would greatly appreciate to hear how others now handle this. I would like to add, im attempting to do this using System.Net in c#
Thank you greatly :-)
New addition: Looking for a solution that i can either buy and run on my windows machine, or program in c#. :-)
Update:
Thank you all very much for your answers. Ultimately i ended up creating a solution by doing this:
Creating a simple webclient that downloaed the specified page from the url (may change to just headers or use this to notify of page changes)
Read in xml file that simply lists the full url to the site/pages to check
Created a windows service to host the solution so it would recover server restarts.
On error an email and text message is sent to defined list of recipients
Most values (interval, smtp, to, from, etc) are defined in the .config for easy change
I will be taking some of your advice to add 'features' to this later, which includes:
AJAX page for real-time monitoring. I will use WCF to connect to the existing windows service from the asp.net page
Download Headers only (with option for page change comparison)
make more configurable (ie: retries on failure before notification)
Wget is a nice alternative. It will check not only whether the machine is active, but also whether the HTTP server is accepting connections.
You could create a simple web page with an address bar for the website and some javascript that uses AJAX to hit a site. If you get any HTTP response other than 200 on the async callback, the site isn't working.
<html>
<head>
<script language="javascript" type="text/javascript">
<!--
var ajax = new XMLHttpRequest();
function pingSite() {
ajax.onreadystatechange = stateChanged;
ajax.open('GET', document.getElementById('siteToCheck').value, true);
ajax.send(null);
}
function stateChanged() {
if (ajax.readyState == 4) {
if (ajax.status == 200) {
document.getElementById('statusLabel').innerHTML = "Success!";
}
else {
document.getElementById('statusLabel').innerHTML = "Failure!";
}
}
}
-->
</script>
</head>
<body>
Site To Check:<br />
<input type="text" id="siteToCheck" /><input type="button" onclick="javascript:pingSite()" />
<p>
<span id="statusLabel"></span>
</p>
</body>
This code depends on the browser not being IE and I haven't tested it, but it should give you a really good idea.
To see if a service is up, not only should you ping, but it's good to have scripts that will hit a service, such as a website, and get back a valid response. I've used What's Up Gold in the past, rather than write my own. I like all the features in products like that. such as sending me a page when a service is down.
For the record, lkjsdaflkjdsjf.com is a hostname (which at the moment is not registered to anyone). ping does not work with URLs, ping works with hostnames. hostnames are looked up using the Domain Name System. DNS is supposed to fail when hostnames are not registered.
The problem is that some services (apparently your ISP, and definitely OpenDNS) do NOT fail DNS requests for hostnames that aren't registered. Instead they return the IP address of a host on their network that presents a search page to any http request.
You appear to want to know two things: Is the name real (that is, is there a host with this name registered to some actual machine)? and Is that machine functioning?
If you already know that the name in question is real (for instance, you want to know if www.google.com is up), then you can use ping because you know that the name will resolve to a real address (the ISP can't return their IP for a registered name) and you'll only be measuring whether that machine is in operation.
If you don't know whether the name is real, then the problem is harder because your ISP is returning false data to your DNS request. The ONLY solution here is to find a DNS server that is not going to lie to you about unresolved names.
The only way I can think of to differentiate between your ISP's fake records and real ones is to do a reverse lookup on the IP you get back and see if that IP is in your ISP's network. The problem with this trick is that if the ISP doesn't have reverse DNS info for that IP, you won't know whether it's the ISP or just some knucklehead who didn't configure his DNS properly (I've made that mistake many times in the past).
I'm sure there are other techniques, but the fact that DNS lies underneath everything makes it hard to deal with this problem.
Don't directly know of any off the shelf options in c#, although I'd be very suprised if there aren't a few available.
I wrote something similar a few years ago, don't have the code anymore cos it belongs to someone else, but the basic idea was using a WebClient to hit the domain default page, and check for a http status code of 200.
You can then wire any notification logic around the success or fail of this operation.
If bandwidth is a concern you can trim it back to just use a HEAD request.
For more complex sites that you control, you can wire up a health monitoring page that does some more in depth testing before it sends the response, eg is DB connection up etc.
Often a machine that is dead on port 80 will still respond to a ping, so testing port 80 (or whatever other one you are interested in) will be a much more reliable way to go.
I've found ping to be very unreliable just because of all the hops you're having to jump through, and something in between can always interfere.
Trying to open up an http connection with a web server is probably the best way to go.
You could try running 'httping' if you have cygwin available or
http://freshmeat.net/projects/httping/
As far as I can see, the problem here that OpenDNS resolves invalid domains back to themselves to forward you on to something close to what you're after (so if you typo ggooggllee.com you end up at the right place via a bounce from the OpenDNS servers). (correct me if I'm wrong)
If that's the case, you should just be able to check whether the IP you've resolved == any of the IPs of OpenDNS? No more ping - no protocol (HTTP) level stuff - just checking for the exceptional case?
If you tend toward the sys-admin solution rather than the programming solution you could install a local name server and tell it not to accept anything but NS records for delegation only zones. This was the fix I (and I assumed everyone else on the internet) used when Network Solution/Verisign broke this last time. I installed BIND on a couple of local machine, told my DHCP servers to hand out those addrs as the local name servers, and set up something like the following for each of the delegation only zones that I cared about:
zone "com" { type delegation-only; };
zone "net" { type delegation-only; };
Come to think of this, I think this might be turned on by default in later BIND versions. As an added bonus you tend to get more stable DNS resolution than most ISPs provide, you control your own cache, a little patching and you don't have to rely on your ISP to fix the latest DNS attack, etc.
i like CALM for this sort of thing as it logs to a database and provides email notifications as well as a status dashboard
you can set up a test page on the site and periodically do a GET on it to receive either a 'true' result (all is well) or an error message result that gets emailed to you
caveat: i am the author of CALM