Automatically detect a new computer connected to the network - networking

Is there an elegant way to make a program detect a new computer that is connected to the network?
I would like my program to "auto-sense" a new computer being connected on the network (they're on the same network). Like a USB device being connected to the computer.
What I'm doing now is to save a list of all computers in the network from time to time. Another approach is to PING all available IPs on the subnet.
Are there any other elegant approaches?
Thanks!

Listening for ARP requests is the canonical way to do this. Independent of DHCP or not, any connected computer that wishes to communicate with the outside world will have to make an ARP request for the address of the default router. This request will go out as a broadcast, and contain the source interface's MAC and IP adresses.
If the other computer uses DHCP, it will make an ARP request for it's own address as part of duplicate address detection, which is also a broadcast you can snoop on.
(This works more or less the same way for IPv6, except you need to look for neighbor discovery or router soliciation packets instead.)
Like the answer alluded to, if you have a switch to which you can telnet or use SNMP on, you can extract the MAC table. That will give you a list of MAC adresses on each port in the switch. If you want the IP addresses however, you still need to listen for ARP:s.
On the other hand, if you have access to the default gateway on the network, you can also look at the ARP table there. That will give you MAC and IP addresses for anyone that has recently (for different values of recently...) communicated with it.

If you have a managed switch of some kind, you could probably connect to that, that would be a fairly elegant method.
If you're on a domain, you can can get a list of all the machines joined to the domain from the domain controller.
Failing that, all I can think of is either a challenge/response thing (e.g. pinging them) or by detecting traffic sent from them (see this question maybe as a starting point?), neither of which strike me as an elegant approach.

Related

How can I programatically set the IP address of a hardware device that doesn't already have an IP set

We have developed a hardware device that doesn't have a screen. It uses TCP/IP to communicate with the network. Currently this is configured by DHCP.
However, we'd like a way to configure it's IP statically by some app I'll have to develop. I notice for some devices like printers there are custom apps that they use to set such information. But how do they talk to the device when the device hasn't been assigned an IP already?
Are they using RAW sockets and a custom protocol? or is there a simpler method. For example, I recall many years ago using a Linux device that somehow received it's initial IP by running an arping. But I don't understand how that sets the IP for other hosts on the network. Nevertheless it seemed to work. Could I mimick that?
e.g. arp -s 191.168.2.2 00-40-9d-22-23-60
So I've got an idea how it works, but I'd like to know what is the common method of setting IP to an embedded device that has no physical screen to configure this.
To be clear, this device does not use Linux.
The standard-conformant way of doing this goes (for IPv4, but IPv6 is similar) along the lines of:
Try to obtain an IP address via DHCP, skip step (2) if that worked. This should be the default.
If no DHCP server responded, use a unique link-local address (These are addresses from the block 169.254.0.0/16 reserved for this purpose. Some parts of the chosen address should be based on something unique to the device, like the MAC address, to make sure the device always chooses the same LL address. Or, to make it fully RFC-compliant: choose a truly random address from this range and probe it - Re-use it when possible) The chosen LL address should be checked against any other use in this network before usage with an arp request on that address (That's probably what you have read). If someone responds to that request, choose a different IP and retry.
Now that you have a temporary IP address, you can use one of the various IP-Multicast-based service discovery protocols to advertise your device to the network.

Basic networking questions

I am trying to understand how exactly routing works:
if 2 computers are on the same network
if they are on different networks.
More specifically I am trying to understand this: Routing
I am also trying to understand the difference between
IP Address,
Net Address,
Mac Address.
From what I understand:
1) IP Address: is used when computers communicate on the internet only.
2) Net Address: is a local version of the IP address and each device on the network has a unique net address. It's used when devices on the same network want to communicate with each other.
3) Mac Address: is a globally unique address and no other computer in the world has the same Mac address. In reality this is not true because it can be changed. It's used when ???
When a computer wants to communicate with another on the same network, they use net address, right? If the computers are on different networks what exactly happens?
Question: Can someone please fix my mistakes if any and explain what I am missing?
Thank you very much.
There are many network types, but since the most used ones are Ethernet and IP networks (and you seem to be asking about them), I will answer shortly based on them.
IP addresses are always used. They may not be used for deciding who gets the packets directly, but they are the basis even in local networks, since it is an IP network. There can also be other network types that have their own mechanisms, but they are not that common.
In local Ethernet the machines ask via ARP protocol "who has this IP address?" and get a reply with a MAC address. After that they send and receive packets based on that MAC address. The packets still have the IP address information, otherwise the receiving machine wouldn't know what is the destination. Do note that the receiving machine might be a firewall or other middleware device, not the actual computer that has the address. Also a single machine and network card may have several IP addresses set up for it.
In IP networks the IP address is used for routing. All routing devices have a routing table that will tell where the packets should go. If it's a simple device, it usually has a local network and everything else goes via a default gw, which will know better what to do with the packets.
A home router will just push them to the operator, there another router will know what addresses go to their networks, others are pushed forward via another connection, until a bigger place is reached where there are inter-operator connections and they choose again the correct route. And then it goes to smaller and smaller pipes the other way around.

Simplest way to find my external ip address and port

I'm trying to develop an applicaton for p2p communication between two android devices. In order to punch a hole through my NAT(s), I'd need to know my external ip address and port.
To that end, I've developed a java server on GAE to report my "remote" ip address and port. The problem is that on GAE I can get my ip address, but not my port. Without it, I'm unable to successfully punch the hole.
So, my question is what's the best, free method to find out my external IP address and port?
That's a question that has no answer with TCP.
Here's the problem: your "port" is not a fixed value. You don't have "an" external port. You typically get one dynamically assigned for each outbound connection.
As answers you should see from the test sites posted in another answer clearly indicate, it's a moving target (though it may stay stationary for a short time due to the browser using HTTP/1.1 keepalives and actually reusing the same connection, not just the same port)... but if you hit the site repeatedly, you'll see it either drift around randomly, or increment. Trying it from two different web browsers on the same machine, you'd never see the same port number -- the port corresponds to the specific source connection, not the machine sourcing the connection.
Sometimes, you may find that it's the same port number as the port your machine's stack opened for the outbound connection, but even when it is, it doesn't matter, because no traffic should be able to return to your machine on that port unless it is from the IP address and port of the machine to which you made the outbound connection. Any decent network address translating device would never accept traffic from another source IP address and/or port, other than the one you addressed in the outbound connection.
There is no standard, simple, predictable, reliable, or consistent way to punch a hole in TCP NAT and then exploit that hole for a peer-to-per connection. To the extent that such things are possible in a given NAT implementation, that is an implementation that is shoddy, broken, defective, and insecure.
See also: https://www.rfc-editor.org/rfc/rfc5128
Sounds like your app could use a STUN server to get its external address.

what's needed to make hostname resolution work on a lan?

I am developing a networked application that runs on a few different computers on a LAN. One of the core needs is for the app to maintain a list of peers on the LAN with which it has communicated in the past, so that it can restore previous sessions. The naive solution would be to just remember the IP and store it in a table, but what happens when the IP of a peer changes?
Instead, I thought I'd store the hostname of the peers so even if the IP changes they will still be reachable via their hostname. (I know hostnames can change as well but that is good enough).
So my question is what exactly is needed to make hostname resolution work on a LAN with mixed Windows/Mac/Linux clients?
Without the use of a central authority the only reliable way to achieve this is through the use of zerconfiguration name resolution. This means that without a multicast router you will only be able to dynamically resolve peers on the same subnet as the resolving host. You could use something like bonjour for mac, netbios or ssdp for windows or avahi for linux but you can't assume that these are enabled. I may be overlooking some more popular protocols that perform this function well but I would personally throw together a quick udp broadcast name resolution protocol for your application. Take a look at these for some more ideas:
Zeroconf Name resolution
Universal local network name resolution method without DNS?
http://en.wikipedia.org/wiki/Zero_configuration_networking#Name_resolution
http://en.wikipedia.org/wiki/Broadcast_address#IP_networking
I would pick a specific udp port to listen on (lets say 12000) and then when you're ready to resolve hosts send a "hello" udp packet out to 255.255.255.255 on port 12000 and all of the other hosts on your network running your app should reply with a packet containing their hostname, possibly other information.

Windows 7 does not accept broadcasts from ip address 0.0.0.1

we have little network devices which are shipped with IP address 0.0.0.1 to ensure that they never collide with any other device in their new environment (thus none of the 10.x.x.x, 172.16.x.x or 192.168.x.x ranges) until configuration. DHCP is no solution since there might be no DHCP server in the field.
The devices would listen to UDP broadcasts and answer with broadcasts until they are given their new IP address this way.
This worked fine with Windows XP - but sucks with Windows 7: the config program does not receive the answer packets from the devices which still have 0.0.0.1. Wireshark sees the packets, then they are dumped by the system.
Question: Is there any reason (RFC?) that actually prohibits using this address in a local environment? Or is it just MS that was overcautious? Where can I read why they treat this address "invalid"? Which ranges are really "invalid" now, too?
Any idea of a workaround on the PC side (Win 7)?
I know that it is not recommended to use 0.xxx addresses for work places, but for this very reason - having a not-used address - it works perfectly.
Edit: there is a device out there called "Netburner" which might have faced the similar issue, according to their forum. See: http://forum.embeddedethernet.com/viewtopic.php?f=5&t=612&p=2198 Does - by coincidence - anybody know some background information?
It sounds as if your configuration application is listening for broadcast packets on all network interfaces and expecting to receive packets from foreign subnets.
That should not work - the OS should only pass-on broadcast packets from the subnets each network interface is on, not from all subnets on the same physical (e.g. Ethernet) segment. I am reasonably certain that doing otherwise is broken behaviour WRT the IP protocol.
The are two ways to deal with this:
Make sure that your network interface has an IP address in the target subnet. You can have more than one IP addresses for each network card, so that should not interfere with normal network operations.
Configure or modify you application to use raw sockets, like Wireshark. Keep in mind, however, that this overrides all normal checks and balances and should be avoided, since it can cause behaviour that is almost impossible to diagnose - which is why it is frowned upon by meny network administrators.
Can you you add new routing table entries to Windows machines easily? Windows has to know which interface to use when routing a broadcast packet to the 0.0.0.x network.
The Unix machines I'm familiar with have a routing table that maps network/netmask entries to either gateways or interfaces (if the network is a local network). The local network (192.168.0.0/16 for my home network) gets sent to interface eth0. Everything else 0.0.0.0/0 gets sent to a specific gateway machine 192.168.0.1.
If my machine sent a UDP broadcast message to network 0.0.0.0/24 (in other words, UDP broadcast sent to 0.0.0.255, then my machine would forward the packet to the gateway machine (which it can look up via arp). The switches in the middle wouldn't propagate the packet to other network devices, because the MAC address is set.
If my machine had another routing entry for 0.0.0.0/24 to the local interface, then my machine would send the packet on the wire using an ethernet broadcast group, and the switches would forward the packet to all connections. (Yay! Just like hubs in the 90s! :)
So I figure you need to add a routing entry for 0.0.0.0/24 to your client machines, so that they can properly address the broadcast packet.

Resources