|
ページ更新: 2005-08-28 (日) (1625日前)
[編集]J2SE 5.0 #pingを行うメソッドが追加された。 [編集]J2SE 1.4まで #Javaでpingやるかもしれないので、調べてみた。 C言語での実装は、 C MAGAZINE 2003年7月号 http://www.cmagazine.jp/contents/200307.html の 特集2が使えるかも。 実装するだけなら、こうやるよなあ、たぶん。
でも、Linuxでは /bin/ping ってrootにsuidしてある→root権限が必要なわけで、 これをJavaから解決するのは大変ではないかな。 (推測だが、Echo Reply受信にroot権限が必要なのかも。)
/bin/pingをstrace, ltraceで観察。 # strace ping 127.0.0.1
: (略)
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
getuid32() = 0
setuid32(0) = 0
getpid() = 17416
setsockopt(3, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [49152], 4) = 0
# ltrace /bin/ping 127.0.0.1
__libc_start_main(0x08048d50, 2, 0xbffffb34, 0x080489cc, 0x0804a7c0 <unfinished ..
.>
__register_frame_info(0x0804c560, 0x0804c718, 0xbffffad8, 0x40046f18, 0x40132e48)
= 0x08048a24
getuid() = 0
getprotobyname("icmp") = 0x40135f28
socket(2, 3, 1) = 3
getuid() = 0
setuid(0) = 0
getopt(2, 0xbffffb34, "I:LRc:dfh:i:l:np:qrs:t:v") = -1
inet_aton("127.0.0.1", 0x0805c908) = 1
malloc(192) = 0x0805d958
getpid() = 17424
setsockopt(3, 1, 6, 0xbffffa3c, 4) = 0
setsockopt(3, 1, 8, 0xbffffa3c, 4) = 0
inet_ntoa(0x0100007f) = "127.0.0.1"
printf("PING %s (%s): %d data bytes\n", "127.0.0.1", "127.0.0.1", 56PING 127.0.0.1
(127.0.0.1): 56 data bytes
) = 42
java.net.SocketImplやjava.net.PlainSocketImplのソースコードを みてみたが、ICMPをあつかえるほどに仮想化されているかどうか、わからない。 J2SDK 1.4.2_03のコードでは、Socketへのアクセスはjava.io.FileDescriptor経由で 行われ、java.net.PlainSocketImplではOS依存の部分はnativeメソッドになっている。 Googleで 'java icmp'を検索したところ、http://w6.loria.fr/software/JDKv6/って ページを発見。 これはIPv6の実装だが、この中のjava.net.IcmpPacket/IcmpSocketという クラスでping (ICMP Echo Request/Reply) を実現できるかもしれない。 もっとも、IPv6自体はJ2SE 1.4で実装されているようなので、今後このコードは メンテナンスされないかも。 teamlinux.org.uk: saxm
|