views:

82

answers:

5

Suppose I'm running several servers serving basic requests on my local network (say a home network, where all machines generally have an IP in the form K.K.K.x, where x is variable). Is there an easy way to discover all such servers? I would need to find each IP on the network running a particular java server application.

+1  A: 

So you have a class C network... just attempt to open the particular server applications port on each IP address between 1 and 254. If you want to get fancy, you can do some checks to verify that if the port actually opens, it does what you expect for that application.

John Weldon
I'm not too keen on the networking. I can run 1-254, but how do I get the first 3 bytes of the IP address in a cross platform manner? My gut says that there's some tool like ipconfig/ifconfig that, with proper params, would return the local IPV4 address (which would give me the bytes I need), but I was wondering if there was a more java-ish way.
Stefan Kendall
Duh. I just googled "Get IP Address Java". This should work nicely.
Stefan Kendall
A: 

Since not every webserver listens on a fixed port of 80, you'll need to scan ports. Open (and close!) in a loop a socket on every port, you can use java.net.Socket for this. If success, then fire a simple GET request on / on the IP/port in question, you can use java.net.URLConnection for this. If you receive a valid HTTP response (regardless of the status code), then it's a webserver. You can determine the server type by the Server header in the HTTP response. You however need to take into account that the default response header can be spoofed/removed/changed by the server admin.

Note that some firewalls may recognize the scanning pattern of a port scanner and block this.

BalusC
A: 

I would scan IP range and test Socket connection to port 80 with a code like this:

try {
       s = new Socket(addr,80);
       System.out.println("Webserver found on IP:" + addr );
       s.close();
     }
catch (IOException ex) {
       System.out.println("Webserver NOT found on IP:" + addr );
    }
systempuntoout
Don't forget the `s.close()`.
jweyrich
+1  A: 

Are you looking for a solution within your Java application? If you are simply looking for a one-time solution, nmap should work.

If your local network is of the form 192.*.*.* try this (I added sudo because it must be run as root):

sudo nmap -vv -sS -O -n "192.168.1.1/24"
Trey
+1 - fast and very powerful.
Thorbjørn Ravn Andersen
Requires root because the options you provided perform a SYN scanning, which rely on RAW sockets, and these can be only created by a superuser.
jweyrich
+1  A: 

There are 2 basic ways to achieve this, and both require you to send/receive packets to/from each host you want to check.

  • The simplest approach is trying to establish the TCP connection to the desired port, as you'd normally do.

  • A more complicated and fancy approach, but faster in terms of execution, is sending a SYN packet, and waiting for a response packet. If the response is a SYN/ACK, it means the port is open (waiting for a connection), otherwise, it isn't. However, Java doesn't provide the necessary API (see raw socket) for this. You'd have to find a library/wrapper or write one using C and JNI.

For more insights to the 2nd option, read this.

jweyrich
Doing that requires the ability to push a raw packet which is generally A) not doable from Java, B) inadvisable, since sending raw packets requires additional system privileges. If people didn't run Windows as Administrator there would be far fewer cases of malware infestations.
Devon_C_Miller
@Devon correct, I was updating my answer to mention that Java doesn't have the necessary API. Microsoft removed support for raw socket creation on XP-SP2, but you can still create/send ethernet frames.
jweyrich