Question

Comment puis-je déterminer l’IP de mon routeur/passerelle en Java ?Je peux obtenir mon IP assez facilement.Je peux obtenir mon adresse IP Internet en utilisant un service sur un site Web.Mais comment puis-je déterminer l’IP de ma passerelle ?

C'est un peu facile dans .NET si vous connaissez votre chemin.Mais comment faire en Java ?

Était-ce utile?

La solution

Java ne rend malheureusement pas cela aussi agréable que d’autres langages.Voici ce que j'ai fait :

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);
    }
}

Cela suppose que la passerelle est le deuxième jeton et non le troisième.Si c'est le cas, vous devez ajouter un supplément st.nextToken(); pour avancer le tokenizer d'une place supplémentaire.

Autres conseils

Sous Windows, OSX, Linux, etc., la réponse de Chris Bunch peut être grandement améliorée en utilisant

netstat -rn

à la place d'un traceroute commande.

L'adresse IP de votre passerelle apparaîtra dans le deuxième champ de la ligne commençant soit default ou 0.0.0.0.

Cela permet d'éviter un certain nombre de problèmes liés à l'utilisation traceroute:

  1. sous Windows traceroute est en fait tracert.exe, il n'y a donc pas besoin de dépendances O/S dans le code
  2. c'est une commande rapide à exécuter - elle obtient des informations du système d'exploitation, pas du réseau
  3. traceroute est parfois bloqué par le réseau

Le seul bémol est qu'il faudra continuer à lire les lignes du netstat sortie jusqu'à ce que la bonne ligne soit trouvée, car il y aura plus d'une ligne de sortie.

MODIFIER: L'adresse IP de la passerelle par défaut se trouve dans le deuxième champ de la ligne qui commence par 'default' si vous êtes sur un MAC (testé sur Lion), ou dans le troisième champ de la ligne qui commence par '0.0.0.0' (testé sous Windows 7)

Les fenêtres:

Métrique d'interface de passerelle de masque de réseau de destination du réseau

0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10

Mac:

Les références des indicateurs de passerelle de destination utilisent Netif Expire

défaut 192.168.2.254 UGSc 104 4 en1

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();
}

Sous Windows, l'analyse de la sortie d'IPConfig vous donnera la passerelle par défaut, sans attendre de trace.

Vous feriez peut-être mieux d'utiliser quelque chose comme checkmyip.org, qui déterminera votre adresse IP publique - pas nécessairement votre premier routeur :à l'université, j'ai une "vraie" adresse IP, alors qu'à la maison, c'est l'adresse IP publique de mon routeur local.

Vous pouvez analyser la page qui renvoie ou trouver un autre site qui vous permet de récupérer simplement l'adresse IP comme seule chaîne.

(Je veux dire charger cette URL en Java/quoi que ce soit, puis obtenir les informations dont vous avez besoin).

Cela devrait être totalement indépendant de la plate-forme.

Concernant l'UPnP :sachez que tous les routeurs ne prennent pas en charge UPnP.Et s'ils le font, il pourrait être désactivé (pour des raisons de sécurité).Votre solution pourrait donc ne pas toujours fonctionner.

Vous devriez également jeter un œil à NatPMP.

Une bibliothèque simple pour UPnP peut être trouvée sur http://miniupnp.free.fr/, même si c'est en C...

Pour surmonter les problèmes mentionnés avec traceroute (accès étendu basé sur ICMP), vous pouvez envisager :

  1. traceroute vers votre IP publique (évite les attaques sur une zone étendue, mais toujours ICMP)
  2. Utilisez un utilitaire non-ICMP comme ifconfig/ipconfig (cependant, des problèmes de portabilité).
  3. Ce qui semble être la solution la meilleure et la plus portable pour le moment est de shell et d'analyser netstat (voir l'exemple de code ici)

la sortie de netstat -rn est spécifique aux paramètres régionaux.sur mon système (locale=de), le résultat ressemble à :...Passerelle standard :10.22.0.1

il n'y a donc pas de ligne commençant par « default ».

donc utiliser netstat n'est peut-être pas une bonne idée.

Cette version se connecte à www.whatismyip.com, lit le contenu du site et recherche via des expressions régulières l'adresse IP et l'imprime dans le cmd.C'est une petite amélioration du code MosheElishas

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader; 
import java.net.URL;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

public class Main {

    public static void main(String[] args) {
        BufferedReader buffer = null;
        try {
            URL url = new URL(
                    "http://www.whatismyip.com/tools/ip-address-lookup.asp");
            InputStreamReader in = new InputStreamReader(url.openStream());
            buffer = new BufferedReader(in);
            String line = buffer.readLine();
            Pattern pattern = Pattern
                    .compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
            Matcher matcher;
            while (line != null) {
                matcher = pattern.matcher(line);
                if (matcher.matches()) {
                    line = matcher.group(2) + "." + matcher.group(3) + "."
                            + matcher.group(4) + "." + matcher.group(5);
                    System.out.println(line);
                }
                line = buffer.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (buffer != null) {
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader; 
import java.net.URL;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

public class Main {

    public static void main(String[] args) {
        BufferedReader buffer = null;
        try {
            URL url = new URL(
                    "http://www.whatismyip.com/tools/ip-address-lookup.asp");
            InputStreamReader in = new InputStreamReader(url.openStream());
            buffer = new BufferedReader(in);
            String line = buffer.readLine();
            Pattern pattern = Pattern
                    .compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
            Matcher matcher;
            while (line != null) {
                matcher = pattern.matcher(line);
                if (matcher.matches()) {
                    line = matcher.group(2) + "." + matcher.group(3) + "."
                            + matcher.group(4) + "." + matcher.group(5);
                    System.out.println(line);
                }
                line = buffer.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (buffer != null) {
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Ce n’est pas aussi simple qu’il y paraît.Java est indépendant de la plate-forme, donc je ne sais pas comment le faire en Java.Je suis devinant que .NET contacte un site Web qui le signale.Il y a plusieurs façons de procéder.Tout d’abord, un examen plus approfondi du protocole ICMP peut vous fournir les informations dont vous avez besoin.Vous pouvez également tracer l'IP que vous traversez (votre itinéraire).Lorsque vous rencontrez une adresse IP qui ne se situe pas dans les plages suivantes :

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

c'est l'adresse IP à un saut de la vôtre et partage probablement quelques octets d'informations avec votre IP.

Bonne chance.Je serai curieux d'entendre une réponse définitive à cette question.

Essayez de bombarder traceroute si vous l'avez.

'traceroute -m 1 www.amazon.com' émettra quelque chose comme ceci :

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

Analysez la deuxième ligne.Oui, c'est moche, mais ça vous fera avancer jusqu'à ce que quelqu'un publie quelque chose de plus sympa.

Matthieu:Oui, c'est ce que je voulais dire par "Je peux obtenir mon IP Internet en utilisant un service sur un site Web". Désolé d'être glib.

Brian/Nick :Traceroute conviendrait, sauf que beaucoup de ces routeurs ont ICMP désactivé et qu'il se bloque donc toujours.

Je pense qu'une combinaison de traceroute et uPnP fonctionnera.C'est ce que j'avais l'intention de faire, j'espérais juste qu'il me manquait quelque chose d'évident.

Merci à tous pour vos commentaires, il semble donc que je ne manque rien d'évident.J'ai commencé à implémenter quelques éléments d'uPnP afin de découvrir la passerelle.

Vous pouvez interroger l'URL "http://whatismyip.com/automation/n09230945.asp".Par exemple:

    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();
        }
    }

Sous Windows, vous pouvez simplement utiliser la commande suivante :

ipconfig | findstr /i "Gateway"

Ce qui vous donnera un résultat comme :

Default Gateway . . . . . . . . . : 192.168.2.1
Default Gateway . . . . . . . . . : ::

Cependant, je ne peux pas exécuter cette commande avec Java, je la publierai quand j'aurai compris cela.

Vous pouvez utiliser netstat -rn commande disponible sur les plateformes Windows, OSX, Linux, etc.Voici mon code :

private String getDefaultAddress() {
        String defaultAddress = "";
        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.contains("0.0.0.0")) {

                    StringTokenizer stringTokenizer = new StringTokenizer(line);
                    stringTokenizer.nextElement(); // first element is 0.0.0.0
                    stringTokenizer.nextElement(); // second element is 0.0.0.0
                    defaultAddress = (String) stringTokenizer.nextElement();
                    break;
                }

                line = output.readLine();

            } // while
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return defaultAddress;

} // getDefaultAddress

Je ne suis pas sûr que cela fonctionne sur tous les systèmes, mais au moins ici, j'ai trouvé ceci :

import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main
{
    public static void main(String[] args)
    {
        try
        {
            //Variables to find out the Default Gateway IP(s)
            String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
            String hostName = InetAddress.getLocalHost().getHostName();

            //"subtract" the hostName from the canonicalHostName, +1 due to the "." in there
            String defaultGatewayLeftover = canonicalHostName.substring(hostName.length() + 1);

            //Info printouts
            System.out.println("Info:\nCanonical Host Name: " + canonicalHostName + "\nHost Name: " + hostName + "\nDefault Gateway Leftover: " + defaultGatewayLeftover + "\n");
            System.out.println("Default Gateway Addresses:\n" + printAddresses(InetAddress.getAllByName(defaultGatewayLeftover)));
        } catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
    }
    //simple combined string out of the address array
    private static String printAddresses(InetAddress[] allByName)
    {
        if (allByName.length == 0)
        {
            return "";
        } else
        {
            String str = "";
            int i = 0;
            while (i < allByName.length - 1)
            {
                str += allByName[i] + "\n";
                i++;
            }
            return str + allByName[i];
        }
    }
}

Pour moi cela donne :

Info:
Canonical Host Name: PCK4D-PC.speedport.ip
Host Name: PCK4D-PC
Default Gateway Leftover: speedport.ip

Default Gateway Addresses:
speedport.ip/192.168.2.1
speedport.ip/fe80:0:0:0:0:0:0:1%12

J'aurais besoin de plus de tests sur d'autres systèmes/configurations/installations de passerelle PC pour confirmer si cela fonctionne partout.J'en doute un peu, mais c'est le premier que j'ai trouvé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top