DHCP address 255.255.255.255 - c#

I'm using the following code to get DHCP server address from one of my network interfaces:
System.Net.NetworkInformation.NetworkInterface networkInterface;
// ... get one of the network interfaces
var properties = networkInterface.GetIPProperties();
var addresses = properties.DhcpServerAddresses;
My network interface is set to a fixed address (not assigned by DHCP) and I'm getting one address from that code, it's 255.255.255.255. Anybody can tell me why? And how can I check if a network interface uses a DHCP or fixed address.

The address 255.255.255.255 is a broadcast address, which is used by the DHCP protocol to broadcast availability packets. When you're not using DHCP this is the address assigned as a DHCP server, because it will allow the network to automatically discover any DHCP servers (usually routers) on the network.
You can use this to check for DHCP:
bool isDhcp = networkInterface.GetIPProperties()
.GetIPv4Properties()
.IsDhcpEnabled;

It isn't a 'real' IP address as it can't be assigned to a host. It simply means "broadcast everywhere".
I think it's safe to assume that when you find 255.255.255.255 as DHCP server address, the adapter you're querying has a fixed IP address, or APIPA (which happens when an adapter is set as DHCP client, but no DHCP server has responded for a preset period of time).
But the IsDhcpEnabled property that #Polynomial mentions is safer to rely on.

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.

Get IP of user in NATed virtual server

I have Windows Server in VirtualBox and NATed port 80 for that.
Request.UserHostAddress returns local IP of virtual network.
How should i get IP of user?
The problem you've got is that you can't see beyond NATing. NAT stands for Network Address Translation so in this instance, you're seeing the public IP address of the NAT device, not the client. That's just the way it works. It's possible for the client to send its local IP address but you'd need to have something on the client to do that.
A different option is to switch from NAT to Bridged networking. Bridged means that the virtual network the VM is on is joined side-by-side with the physical network the host is on. This means they'll have IP addresses which are on the same subnet and are routable from anything else on the same network. Bridges act like switches/hubs, NATs act like routers.
As long as your server / client don't have any NAT devices between them, the IPs should be readily visible using the standard mechanisms (eg context.Request.ServerVariables["REMOTE_ADDR"], Request.UserHostAddress, etc)
Do you want to get the user's public IP address?
Easiest approach is to simply create a PHP script to echo the remote address, or use an existing API that does so.
PHP:
<?php
echo $_SERVER["REMOTE_ADDR"];
?>
C#:
using (var client = new HttpClient()) {
var response = await client.GetStringAsync(new Uri("URL"));
IPAddress ip;
if (IPAddress.TryParse(response, out ip)) {
//Success
}
}

SocketException on TcpListener.Start()

I'm trying to make a basic client/server program, but when I start the TcpListener it gives me SocketException:The requested address is not valid in its context.
I actually have a method that returns my public IP, and it matches ipconfig results, so the IP address string below can't be the problem. Of course, the IP shown below isn't my real IP for security reasons. I opened the port below for general use.
Anyway, Not valid in context is vague, so I'm not sure what that means.
Here's my code (for the TcpListener):
ServerIn = new TcpListener(IpAddress.Parse("100.100.100.100"), 8000);
ServerIn.Start();
Thanks in advance.
The TcpListener can only be bound to a local IP Address of the computer that runs it. So the IP you're specifying isn't an IP of the local machine. Your public IP isn't the same IP as your local machine, especially if you're using some kind of NAT.
If I recall correctly, it's common to just do IPAddress.Any as your IP to initialise the listener.
As written in MSDN about TcpListener
IPAddress- An IPAddress that represents the
local IP address.
So it need to be a local IP address.

C#: Query DHCP for Client Name

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.

Get Server IP automatically to client

Writing a chat program (as so many do) and i have found that i would like to be able to get the clients to connect to the server automatically.
However, the IP address of the server would not be permanent, so i cannot just hard-core it into the program
In TCP, I'm looking for some sort of broadcast feature, that allows the client to know where the server is
Any ideas?
EDIT: should have said, this will be a LAN program only - no outside connections
If you are talking about a chat in a LAN and you can't or don't want to use DNS for some reason, you could implement, or find an implementation of, the discovery protocol used by UPnP. The SSDP is based on a UDP broadcast. It is, afaik, not possible to multicast via TCP, because TCP needs a session.
If you want to use the chat server over the internet you have no choice but to use DNS. Look for a dynamic dns provider (I use selfhost.bz). In C# you can then resolve the hostname to an IP address as described in the other answers. If you have a hostname to connect to it will probably be enough to pass that to the socket, though:
socket.Connect("myhostname.selfhost.bz", ...
Edit: Since you say you're in a LAN, a few more details on SSDP. The protocol does way more, than you actually need. If you're thinking of implementing it yourself, don't stick to it exactly. Just make your clients send a broadcast on a specified port. The server permanently listens on that port, answering with a predefined message, once it receives a message. When the client receives that answer, it will know that the sender is a valid server.
Use DNS. Resolve the hostname in your app and connect to the IP it resolves to. You'll need dynamic DNS since you say the IP isn't permanent.
Use the below process to find server IP address
public string GetIPAddress()
{
string strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
return ipAddress.ToString();
}
You can also use
Request.ServerVariables["LOCAL_ADDR"];
I had an idea: just get the server to write the IP address/port/whatever to a textfile somewhere on the (public) network, and the clients can read the text file
Obviously, if the text file is not there or empty, no server is running...
Is this such a bad idea?

Categories