views:

4267

answers:

12

How can I determine the IP of my router/gateway in Java? I can get my IP easily enough. I can get my internet IP using a service on a website. But how can I determine my gateway's IP?

This is somewhat easy in .NET if you know your way around. But how do you do it in Java?

A: 

That is not as easy as it sounds. Java is platform independent, so I am not sure how to do it in Java. I am guessing that .NET contacts some web site which reports it back. There are a couple ways to go. First, a deeper look into the ICMP protocol may give you the information you need. You can also trace the IP you go through (your route). When you encounter an IP that is not in the following ranges:

  • 10.0.0.0 – 10.255.255.255
  • 172.16.0.0 – 172.31.255.255
  • 192.168.0.0 – 192.168.255.255

it is the IP one hop away from yours, and probably shares a few octets of information with your IP.

Best of luck. I'll be curious to hear a definitive answer to this question.

Brian
A: 

Try shelling out to traceroute if you have it.

'traceroute -m 1 www.amazon.com' will emit something like this:

traceroute to www.amazon.com (72.21.203.1), 1 hops max, 40 byte packets
 1  10.0.1.1 (10.0.1.1)  0.694 ms  0.445 ms  0.398 ms

Parse the second line. Yes, it's ugly, but it'll get you going until someone posts something nicer.

Nick Brosnahan
Why the downvote?
Rydell
A: 

You may be better off using something like checkmyip.org, which will determine your public IP address - not necessarily your first hop router: at Uni I have a "real" IP address, whereas at home it is my local router's public IP address.

You can parse the page that returns, or find another site that allows you to just get the IP address back as the only string.

(I'm meaning load this URL in Java/whatever, and then get the info you need).

This should be totally platform independent.

Matthew Schinckel
A: 

Matthew: Yes, that is what I meant by "I can get my internet IP using a service on a website." Sorry about being glib.

Brian/Nick: Traceroute would be fine except for the fact that lots of these routers have ICMP disabled and thus it always stalls.

I think a combination of traceroute and uPnP will work out. That is what I was planning on doing, I as just hoping I was missing something obvious.

Thank you everyone for your comments, so it sounds like I'm not missing anything obvious. I have begun implementing some bits of uPnP in order to discover the gateway.

Frank Krueger
+2  A: 

Java doesn't make this as pleasant as other languages, unfortunately. Here's what I did:

import java.io.*;
import java.util.*;

public class ExecTest {
    public static void main(String[] args) throws IOException {
        Process result = Runtime.getRuntime().exec("traceroute -m 1 www.amazon.com");

        BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
        String thisLine = output.readLine();
        StringTokenizer st = new StringTokenizer(thisLine);
        st.nextToken();
        String gateway = st.nextToken();
        System.out.printf("The gateway is %s\n", gateway);
    }
}

This presumes that the gateway is the second token and not the third. If it is, you need to add an extra st.nextToken(); to advance the tokenizer one more spot.

Chris Bunch
-1: This doesn't work for a non-windows os.
Martijn Courteaux
Actually it doesn't work for a Windows-OS, as traceroute is called tracert there.
Thorbjørn Ravn Andersen
+1  A: 

Regarding UPnP: be aware that not all routers support UPnP. And if they do it could be switched off (for security reasons). So your solution might not always work.

You should also have a look at NatPMP.

A simple library for UPnP can be found at http://miniupnp.free.fr/, though it's in C...

akr
+1  A: 

Hi Frank. To overcome the issues mentioned with traceroute (ICMP-based, wide area hit) you could consider:

  1. traceroute to your public IP (avoids wide-area hit, but still ICMP)
  2. Use a non-ICMP utility like ifconfig/ipconfig (portability issues with this though).
  3. What seems the best and most portable solution for now is to shell & parse netstat (see the code example here)
tardate
+1  A: 

On windows parsing the output of IPConfig will get you the default gateway, without waiting for a trace.

bruceatk
+11  A: 

On Windows, OSX, Linux, etc then Chris Bunch's answer can be much improved by using

netstat -rn

in place of a traceroute command.

Your gateway's IP address will appear in the second field of the line that starts either default or 0.0.0.0.

This gets around a number of problems with trying to use traceroute:

  1. on Windows traceroute is actually tracert.exe, so there's no need for O/S dependencies in the code
  2. it's a quick command to run - it gets information from the O/S, not from the network
  3. traceroute is sometimes blocked by the network

The only downside is that it will be necessary to keep reading lines from the netstat output until the right line is found, since there'll be more than one line of output.

Alnitak
+1  A: 
try{

    Process result = Runtime.getRuntime().exec("netstat -rn");

    BufferedReader output = new BufferedReader
 (new InputStreamReader(result.getInputStream()));

    String line = output.readLine();
    while(line != null){
 if ( line.startsWith("default") == true )
     break;  
 line = output.readLine();
    }


    StringTokenizer st = new StringTokenizer( line );
    st.nextToken();
    gateway = st.nextToken();

    st.nextToken();
    st.nextToken();
    st.nextToken();

    adapter = st.nextToken();

}catch( Exception e ) { 
    System.out.println( e.toString() );
    gateway = new String();
    adapter = new String();
}
Hamza Yerlikaya
+1  A: 

You can query the URL "http://whatismyip.com/automation/n09230945.asp". For example:

 BufferedReader buffer = null;
 try {
  URL url = new URL("http://whatismyip.com/automation/n09230945.asp");
  InputStreamReader in = new InputStreamReader(url.openStream());
  buffer = new BufferedReader(in);

  String line = buffer.readLine();
  System.out.println(line);
 } catch (IOException e) {
  e.printStackTrace();
 } finally {
  try {
   if (buffer != null) {
    buffer.close();
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
+1  A: 

output of netstat -rn is locale specific. on my system (locale=de) the output looks like: ... Standardgateway: 10.22.0.1

so there is no line starting with 'default'.

so using netstat might be no good idea.

what OS is that? On OSX there's no locale difference in the output.
Alnitak