Java でルーター/ゲートウェイの IP を確認するにはどうすればよいですか?
質問
Java でルーター/ゲートウェイの IP を確認するにはどうすればよいですか?IP は簡単に取得できます。Web サイト上のサービスを使用してインターネット IP を取得できます。しかし、ゲートウェイの IP を確認するにはどうすればよいでしょうか?
.NET では、やり方を知っていれば、これはある程度簡単です。しかし、Java ではどうやってそれを行うのでしょうか?
解決
残念ながら、Java ではこれが他の言語ほど快適ではありません。私がやったことは次のとおりです。
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);
}
}
これは、ゲートウェイが 3 番目ではなく 2 番目のトークンであることを前提としています。その場合は、追加する必要があります st.nextToken();
トークナイザーをもう 1 つ進めます。
他のヒント
Windows、OSX、Linuxなどでは、Chris Bunchの答えは次のようにすることで大幅に改善できます。
netstat -rn
の代わりに traceroute
指示。
ゲートウェイの IP アドレスは、次のいずれかで始まる行の 2 番目のフィールドに表示されます。 default
または 0.0.0.0
.
これにより、使用しようとする際の多くの問題が回避されます traceroute
:
- Windowsの場合
traceroute
実はtracert.exe
, したがって、コード内に O/S 依存関係が必要ありません。 - これは実行するのが簡単なコマンドです。ネットワークからではなく、O/S から情報を取得します。
traceroute
ネットワークによってブロックされる場合があります
唯一の欠点は、次の行を読み続ける必要があることです。 netstat
出力は複数行になるため、正しい行が見つかるまで出力します。
編集: デフォルト ゲートウェイの IP アドレスは、MAC (Lion でテスト済み) を使用している場合は「default」で始まる行の 2 番目のフィールドにあります。 3番目のフィールド 「0.0.0.0」で始まる行 (Windows 7 でテスト済み)
ウィンドウズ:
ネットワーク宛先ネットマスク ゲートウェイ インターフェイス メトリック
0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10
マック:
宛先ゲートウェイのフラグ参照 Netif の期限切れを使用
デフォルト 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();
}
Windows では、IPConfig の出力を解析すると、トレースを待たずにデフォルト ゲートウェイが取得されます。
checkmyip.org のようなものを使用したほうが良いかもしれません。これは、必ずしも最初のホップのルーターではなく、パブリック IP アドレスを決定します。大学では「実際の」IP アドレスを持っていますが、自宅ではローカル ルーターのパブリック IP アドレスです。
返されたページを解析することも、IP アドレスを唯一の文字列として取得できる別のサイトを見つけることもできます。
(この URL を Java などでロードして、必要な情報を取得するという意味です)。
これは完全にプラットフォームに依存しない必要があります。
UPnPについて:すべてのルーターが UPnP をサポートしているわけではないことに注意してください。そして、もしそうなら、(セキュリティ上の理由から)スイッチがオフになる可能性があります。したがって、ソリューションが常に機能するとは限りません。
NatPMP も参照してください。
UPnP 用の単純なライブラリは次の場所にあります。 http://miniupnp.free.fr/, 、C言語ですが...
トレースルート (ICMP ベース、広域ヒット) に関する前述の問題を解決するには、次のことを検討できます。
- パブリックIPへのtraceroute (広範囲のヒットを回避しますが、それでもICMP)
- ifconfig/ipconfig などの非 ICMP ユーティリティを使用します (ただし、これには移植性の問題があります)。
- 現時点で最良かつ最も移植性の高い解決策と思われるのは、netstat をシェルおよび解析することです (コード例を参照) ここ)
netstat -rn の出力はロケール固有です。私のシステム (locale=de) では、出力は次のようになります。...標準ゲートウェイ:10.22.0.1
したがって、「default」で始まる行はありません。
したがって、netstat を使用するのは得策ではない可能性があります。
このバージョンは、www.whatismyip.com に接続し、サイトのコンテンツを読み取り、正規表現で IP アドレスを検索し、それを cmd に出力します。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();
}
}
}
}
それは思っているほど簡単ではありません。Java はプラットフォームに依存しないため、Java でそれを行う方法がわかりません。私は 推測する .NET が何らかの Web サイトに接続し、その Web サイトがそれを報告します。いくつかの方法があります。まず、ICMP プロトコルを詳しく調べると、必要な情報が得られる可能性があります。経由する IP (ルート) を追跡することもできます。次の範囲にない IP が見つかった場合:
- 10.0.0.0 – 10.255.255.255
- 172.16.0.0 – 172.31.255.255
- 192.168.0.0 – 192.168.255.255
これはあなたの IP から 1 ホップ離れた IP であり、おそらくあなたの IP と数オクテットの情報を共有しています。
幸運を祈ります。この質問に対する明確な答えを知りたいと思っています。
ある場合は、traceroute にシェルアウトしてみてください。
「traceroute -m 1 www.amazon.com」は次のような内容を出力します。
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
2行目を解析します。確かに、それは醜いですが、誰かがもっと良いものを投稿するまでは続けるでしょう。
マシュー:はい、それは「ウェブサイトでサービスを使用してインターネットIPを取得できる」という意味です。グリブになってすみません。
ブライアン/ニック:Traceroute は、これらのルーターの多くで ICMP が無効になっているため、常に停止するという事実を除けば、問題ありません。
トレースルートとuPnPの組み合わせがうまくいくと思います。それが私がやろうと計画していたことであり、明らかな何かが欠けていることを願っていただけです。
みなさん、コメントありがとうございます。明らかな点は何も見逃していないようです。ゲートウェイを検出するために、いくつかの uPnP の実装を開始しました。
URL をクエリできます。http://whatismyip.com/automation/n09230945.asp」。例えば:
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();
}
}
Windows では、次のコマンドを使用するだけです。
ipconfig | findstr /i "Gateway"
これにより、次のような出力が得られます。
Default Gateway . . . . . . . . . : 192.168.2.1
Default Gateway . . . . . . . . . : ::
ただし、このコマンドは Java では実行できません。これがわかったら投稿する予定です。
使用できます netstat -rn
Windows、OSX、Linuxなどのプラットフォームで利用できるコマンド。これが私のコードです:
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
すべてのシステムで動作するかどうかはわかりませんが、少なくともここで次のことを見つけました。
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];
}
}
}
私にとって、これは次のことを生み出します。
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
どこでも動作するかどうかを確認するには、他のシステム/構成/PC ゲートウェイ セットアップでさらにテストが必要です。半信半疑ですが、初めて見つけました。