C#: Query DHCP for Client Name - c#

Final edit for clarity - In my environment, DNS will only store one record per client. If a client has multiple NICs, or changes subnets, the original IP is registered in DNS until the corresponding DHCP record expires (this is an AD environment where DHCP registers DNS addresses).
In this scenario DNS has one, incorrect, record for the client. I want to query DHCP by client name, to see all IPs that are leased to it.
The only possible solution I have found is to dump all subnet info from DHCP (supported by the below API) then query against that, but that is not feasible in my environment, since multiple people would use this application, and I don't want the additional strain on DHCP.
I cannot change any configuration for DNS or DHCP.
Thanks,
This is similar to this question, but with the referenced API (here), I can only query via IP. Is it possible with this API, or any other, to query DHCP by hostname? (The issue being, DNS gives me an old IP for MachineA, I want to retrieve any other IPs being leased by MachineA from the DHCP server).
Edit: To clarify, I want to write a program that I can type in a hostname, it will then query a DHCP server for all IPs for that hostname in any subnet administered by that DHCP server. This is to workaround the issue of a machine with multiple NICs registering an IP that is useless to me (wireless), so for instance the DNS result may be NICA (wireless) but I want NICB (wired).

From what I can tell, you've encountered the age-old problem of which IP address to use. Now-a-days many computers have multiple NICs, some virtual, some local-only, some with internet access, etc... For the application to choose is very difficult. Most of the time I simply make the IP by which the application hosts things like sockets a configuration item--simply because the application is incapable of really choosing which is the right ip address to use. e.g. two NICs both with the same network access, which do you choose? If you run the application twice, maybe one should use NIC 1 and the other should use NIC 2--how would the app make that determination? (i.e. it can't).
Having said that, depending your needs, you can go looking for the best NIC and get it's IP address. For example, if you want an IPv4 address on a non-wireless NIC, you can do something like:
var ips = from ni
in NetworkInterface.GetAllNetworkInterfaces()
where ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet
from ip in ni.GetIPProperties().UnicastAddresses
where ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && ip.IsDnsEligible
select ip;
IPAddress address = ips.First().Address;
...error checking omitted for readability--apply whatever error checking suitable for your requirements.
You can even go so far as to check whether the address is link local (i.e. can communicate out of the local network segment--which usually means an address automatically assigned by Windows instead of DNS/DHCP) by seeing if the first two bytes of an IPv4 address are 169 and 254.
But, you need to specifically define what your requirements are. simply to say "undesirable wireless IP" doesn't provide unambiguous and verifiable criteria to tell what solution will always work for your needs.

If you are trying to locate a machine on the network, then querying DNS is probably what you want to do first. i.e. Think of a machine that has a static ip address on the network. It would register its name with the name service only, it would not show up in DHCP att all if the machine's IP stack is configured with the static address only.
I'm not sure how long it should take for a new machine or a recently changed IP address to show up in DNS. But if you want to see if DHCP has something different(newer), then query DHCP after trying it from DNS first.

Related

Why does google captures a different IP address than my TcpListener?

I have a very simple http server:
TcpListener server = new TcpListener(System.Net.IPAddress.Any, 80);
server.Start();
var client = server.AcceptTcpClient();
var ip = client.Client.RemoteEndPoint;
// ip address in here is: 166.72.162.85
// etc. read request and write response....
I am making that request with my phone that is connected to AT&T 3G network. And my server detects the ip address 166.72.162.85
Now here is my question. I am asking this question primary to learn. Why is it that google captures a different IP address? How can I capture 2600:387:9:3::c7 with my TcpListener?
It looks like you're on a dual stacked network - you have both IPv4 and IPv6 connectivity, which a bit like being connected to two separate "Internets" at the same time.
Your server is probably accessible from only one of these "Internets" - the IPv4 Internet. Google is accessible from both. We can easily check that by resolving www.google.com to an IP address. Here's the result on my machine:
Note the first result - 2a00:1450:4001:821::2004. It's an IPv6 address, and that's the first address your operating system will try to connect to when accessing www.google.com because modern operating systems prefer IPv6 over IPv4. So your connection to Google goes over IPv6, which will see you coming from your IPv6 address (2600:387:9:3::c7).
When connecting to your IPv4-only sever, the connection is made over IPv4 - from your IPv4 address, which is 166.72.162.85 to the server's IPv4 address.
To reach your server using IPv6, you'd need to make it accessible via IPv6:
The machine on which you run your server must have a public IPv6 address
The client has to access the machine either directly by its IPv6 address, or a domain name which has a AAAA record, which is a DNS record for IPv6 addresses
On top of that, you need to make sure that your server software binds to the IPv6 address of the machine. Your code binds to System.Net.IPAddress.Any, which is equivalent to 0.0.0.0, meaning "any IPv4 address". Instead, you'd need to bind to IPAddress.IPv6Any, which is equivalent to 0:0:0:0:0:0:0:0 (or ::), meaning "any IPv6 address".
BTW, you can try getting your IP from the IPv4-only Google at https://ipv4.google.com/. It should return the same 166.72.162.85 that you're seeing in your server.
Google is showing an IPv6 address, your code is showing IPv4.
Note you can also see different IP on the receiving end depending on the route the traffic has taken to get there, like if there were a proxy involved you would see the IP of the proxy and not the actual IP of the source.

C# Is current network my domain

I am building an add-on for office, in which I am to open a browser and navigate to an internal site, which is also exposed through dns, so that it can be accessed from outside the network/domain.
Now, in order to access this site, I need to know whether or not I am inside or outside the domain network. If I'm inside I need to access via internal ip otherwise through the exposed dns address.
This is where I ask the clever minds of stack overflow, if any of you know of a way to see if the network a computer is currently connected to, is indeed the network of the domain to which the computer/user belongs?
I have been looking at Environment.UserDomainName and Domain.GetComputerDomain. Both of these could help me find the domain name, in theory (not tested, but expect it to work), but none of them helps me to find whether or not the current network is the domain network.
Any constructive feedback is very much appreciated!
EDIT
At some point this add-on is supposed to be sold to various customers, so I can't rely on something as simple as the IP looking in a specific way.
The solution must be something that can work regardless of the network the computer is connected to.
If your network gives computers unique names you can check the computer name by
Dns.GetHostName();
Or if your network has a specifically unique IP header (All IPs start with 10.1 or they are all on a Belkin router whose IPs start with 198.2) you can get all IP addresses using
IPAddress[] addr = Dns.GetHostAddresses(Dns.GetHostName());
UPDATE:
Something that shows my company's network is its DNS Suffix. Would this work for you?
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in adapters)
{
IPInterfaceProperties properties = adapter.GetIPProperties();
Console.WriteLine(adapter.Description);
Console.WriteLine(" DNS suffix................................. :{0}",
properties.DnsSuffix);
Console.WriteLine(" DNS enabled ............................. : {0}",
properties.IsDnsEnabled);
Console.WriteLine(" Dynamically configured DNS .............. : {0}",
properties.IsDynamicDnsEnabled);
}

Reverse IP Check Returning My Computer Name

I am trying to convert a VBScript COM component based Reverse/Forward IP checking system to C#.
This system was created to prevent the banning of SERPs like Googlebot using what was back then (becoming) the standard way of checking an IP was who it said it belonged to e.g a reverse/forward DNS check.
Although we have lists of SERP IP Ranges so we don't ban them if they come in - even with hack vectors - we cannot keep up with new ranges being added all the time.
The process is based around this short example.
It is explained simply here > http://ipadmin.junkemailfilter.com/rdns.php
This has been working fine for ages in VBScript but now I am converting to .NET I am having issues where people have set their IP to resolve to "localhost" like this one 113.168.154.182 as you just get back your own DNS server, Virgin media, or if I run it from my PC with c# I get my own computer name. The IP is from Vietnam > http://www.geoiptool.com/en/?ip=113.168.154.182
Now I am trying to use .NET and this code.
But as I am using this code to do get the hostname
IPHostEntry DNSHostIP = Dns.GetHostEntry("113.168.154.182");
hostname = DNSHostIP.HostName;
When I output the value of hostname I get my own computers name e.g std36w7.metal.mycompany.co.uk not localhost.
Then when I try and do a forward DNS check to get the list of IP addresses with this hostname I get my own IP addresses (one IPv6 one IPv4).
If I could get back "localhost" then I could have a check to skip it as a spoof along with anything starting with 10 or 192 etc.
However at the moment I cannot do this.
What is the best way of doing reverse/forward DNS checks which I thought was becoming the standard way of checking for spoofers nowadays in .NET?
And how can I handle people who have set (or some mistake might be causing it) their IP to be localhost.
Thanks
Simple. Your LOCAL DNS (guessing your router unless you have your own DNS server) is resolving it - upstream to it's INTERNET DNS server. Also if you really want it to return LOCALHOST, you'd have to literally edit your local HOSTS file and add an entry since no system ever returns the name LOCALHOST when you look up your ip even from a local DNS server. I believe the ONLY example is if you completely eliminate a DNS server to fallback on your local HOSTS file.

Find correct Ip address returned by Dns.GetHostEntry

Suppose there are 2 computers on same network, named com1 and com2.
On com1, if I call
Dns.GetHostEntry("com2")
surely enough, it returns only 1 ip address, like 192.168.1.2, which I could use it to communicate with com2. However, if I call
Dns.GetHostEntry("com1")
It will return all ip addresses (192.168.1.1(the one I want) as well as other addresses like 169.254.100.50 (vm address, I need to filter this out))
The question is, how can I get a unique "real" ip address for com1 in this case?
Thanks in advance.
After some research this question is actually hard to answer. If "com1“ has multiple NICs, it is hard to find which NIC it uses to communicate with "com2", I have found this SO link to get address on NICs that are connected to internet, VM address will not connect to internet. Obviously asking “com1" itself to find which NIC it uses to connect to "com2" is hard,should rather asking "com2" instead.
Ok then can you check the firewall settings of the "com2" or test it by turning it off.

Determining public IP in C# and comparing to a hostname

I have a program in C# that I want to get a news feed from a server I setup in my basement. I also want to setup this program so it can work locally. To do this I THINK I need to compare the resolved ip of my dyndns.biz hostname to my router's public ip (I have dynamic ip and a client on my server updating the ip of the hostname) and thus determine if the hostname needs to be used or the local ip of the server (192.168.0.100) or the hostname. I already have code to connect to the ftp server assuming I can get the right usage of the hostname versus the localized IP.
Edit: Anyways, in summary because I realized this might not look like a question, how can I determine a) the resolved IP of the hostname and b) the public IP of my router in a C# app
You're overcomplicating this.
Just open your hosts file (found in C:\Windows\System32\drivers\etc) and add your dyndns hostname routing it to loopback. That way you don't have to add any workaround code to your final application to prevent it from even asking your DNS or router:
127.0.0.1 yourhostname.dyndns.biz
To obtain the IP address of a hostname, use the following code:
IPAddress[] addresses = System.Net.Dns.GetHostAddresses("www.cnn.com");
To obtain your public IP address of your router or local network, you need to talk to an outside system that can tell you that part, and unfortunately I don't know if there is any such system that is free to use as well as easy to use from a program.

Categories