#!/usr/local/bin/perl -w # # Socket Wrapper 2 - A socket wrapper on TCP/IP. (完成版) # # Socket 通信の wrapper です.(2000/12) # Socket 通信の内容をダンプするためのラッパです. # # こういうことをしてくれます. # # (ftp プロトコルの内容が知りたいときの例) # # 通常の動作 # # host2 ソケット通信 host1 # ┌──────┐ (port 21) ┌────────┐ # │ftpdデーモン│←──────→│ftp クライアント│ # └──────┘ └────────┘ # # 間に socketwrapper をかませて,Socket 通信の内容を表示する. # # host2 host1 # ┌──────┐ ┌────────────────────┐ # │ │ソケット通信 │┌────┐ソケット通信┌──────┐│ # │ │ (port 21) ││ socket │(port 10023)│ftp ││ # │ftpdデーモン│←──────→│wrapper │←────→│クライアント││ # │ │ │└────┘ └──────┘│ # └──────┘ └──│─────────────────┘ # ↓ # 標準出力に出力 # # 使用方法: # # % socketwrapper [hostname] [port-to] [port-from] [from-to file] [to-from file] # で,[hostname] の [port-to]ポートと,自ホストの[port-from]ポートを # 接続し,その間の通信内容を [from-to file] [to-from file] というファイル名の # ファイルに出力します.(ファイル名を指定しない場合には, # from-to.wrapper, to-from.wrapper がデフォルト値になる) # # 使用例: # # たとえば,host1 というホストで, # host1> socketwrapper host2 23 10023 # host1> telnet host1 10023 (もしくは telnet localhost 10023) # のようにすれば,host2 に対して telnet 接続して,ソケット通信の内容を # 標準出力に表示します.つまり,telnet プロトコルの内容がわかります. # # たとえば,host1というホストで, # host1> socketwrapper host2 21 10023 # host1> ftp host1 10023 (もしくは ftp localhost 10023) # のようにすれば,host2に対して ftp 接続できて,ソケット通信の内容を # 標準出力に表示します.つまり,ftp プロトコルの内容がわかります. # # たとえば,host1というホストで, # host1> socketwrapper host2 80 10023 # host1> netscape http://host1:10023/index.html # (もしくは netscape http://localhost:10023/index.html) # のようにすれば,host2に対して http 接続できて,ソケット通信の内容を # 標準出力に表示します.つまり,http プロトコルの内容がわかります. # # 注1) # ホスト名(上記の host1 や,host2 や,localhost)は, # host1.xx.yy.zz.jp というように,FQDN で指定しないと # うまくいかないことがあります. # # 注2) # パスワードがまるみえにならないように注意! # # 注3) # host1> socketwrapper host2 21 10023 # host1> ftp localhost 10023 # のようにして,localhost の socketwrapper に対して # 接続しようとすると,うまくいかないときがあります. # このようなときは ftp host1 10023 のようにして,localhost ではなく # 自ホスト名を使用するとうまくいくことがあります. # # 注4) # socketwrapper 用に使用する port 番号(上記の例では 10023) は,空いている # てきとうなのを選んでください. # 10023 で一般的にうまくいくかどうかは,知りません. # use IO::Socket; use Net::hostent; my ($host_to, $port_to, $host_from, $port_from, $handle_to, $handle_from, $kidpid); $host_to = shift(@ARGV) || "localhost"; $port_to = shift(@ARGV) || "23"; $port_from = shift(@ARGV) || "10023"; $file_from_to = shift(@ARGV) || "from-to.wrapper"; $file_to_from = shift(@ARGV) || "to-from.wrapper"; $handle_to = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host_to, PeerPort => $port_to, ) || die "cannot connect to $host_to:$port_to.\n"; $handle_to->autoflush(1); # so output gets there right away print STDERR "[Connected to $host_to:$port_to]\n"; $server = IO::Socket::INET->new( Proto => 'tcp', LocalPort => $port_from, Listen => SOMAXCONN, Reuse => 1) || die "can't setup server.\n"; $handle_from = $server->accept(); $handle_from->autoflush(1); $hostinfo = gethostbyaddr($handle_from->peeraddr); $host_from = $hostinfo->name; print STDERR "[Connected from $host_from:$port_from]\n"; unless (defined($kidpid = fork())) { die "can't fork"; } if ($kidpid) { open (TO_FROM, ">$file_to_from") || die "cannot open $file_to_from.\n"; TO_FROM->autoflush(1); while (defined($line_to = getc($handle_to))) { # chomp($line_to); # print STDOUT "To $host_to:$port_to : $line_to"; print TO_FROM "$line_to"; print $handle_from $line_to; } kill("TERM", $kidpid); } else { open (FROM_TO, ">$file_from_to") || die "cannot open $file_from_to.\n"; FROM_TO->autoflush(1); while (defined($line_from = getc($handle_from))) { # chomp($line_from); # print STDOUT "From $host_from:$port_from : $line_from"; print FROM_TO "$line_from"; print $handle_to $line_from; } }