# # Name/Address Translation Daemon # ############################################################################### $host = "localhost"; $port = 9990; $name = "DNS"; $pass = "password"; $login = "connect $name $pass\n"; ############################################################################### require 'getopts.pl'; package network; require 'sys/socket.ph'; $sockaddr = 'S n a4 x8'; chop($hostname = `hostname`); $next = 'netsocket000000'; %listening = (); sub hostname { local($who) = @_ || $hostname; local($name, $aliases, $type, $len, $addr) = gethostbyname($who); return $name; } sub ipaddr { local($who) = @_; $who = $hostname if (! $who); local($name, $aliases, $type, $len, $addr) = gethostbyname($who); return join('.', unpack('C4', $addr)); } sub resolveaddr { local($addr) = @_; if ($addr =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { return gethostbyaddr(pack('C4', $1, $2, $3, $4), &AF_INET); } else { return gethostbyname($addr); } } sub name2addr { local($name) = @_; local($addr) = &ipaddr($name); return $addr; } sub addr2name { local($addr) = @_; local($name, $aliases, $type, $len, $addr) = &resolveaddr($addr); return $name; } sub open { local($them, $port) = @_; local($name, $aliases, $proto, $type, $len, $thisaddr); if ($listening{$them}) { local(*S) = $them; *NS = ++$next; (local($addr) = accept(NS, S)) || return undef; select((select(NS), $| = 1)[0]); return $next; } $port = 'telnet' unless $port; $them = 'localhost' unless $them; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $port) = getservbyname($port, 'tcp') unless $port =~ /^\d+$/; ($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname); ($name, $aliases, $type, $len, $thataddr) = &resolveaddr($them); $this = pack($sockaddr, &AF_INET, 0, $thisaddr); $that = pack($sockaddr, &AF_INET, $port, $thataddr); *S = ++$next; socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; bind(S, $this) || return undef; connect(S, $that) || return undef; select((select(S), $| = 1)[0]); return $next; } sub listen { local($port) = @_; local($name, $aliases, $proto, $type, $len, $this, $addr); ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $port) = getservbyname($port, 'tcp') unless $port =~ /^\d+$/; $this = pack($sockaddr, &AF_INET, $port, "\0\0\0\0"); *S = ++$next; socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; bind(S, $this) || return undef; listen(S, 5) || return undef; select((select(S), $| = 1)[0]); $listening{$next} = 1; return $next; } sub read { local(*S, $bsize) = @_; return undef if (sysread(S, $_, $bsize) == 0); return $_; } sub readline { local(*S) = @_; return scalar(<S>); } sub write { local(*S, $data) = @_; return syswrite(S, $data, length($data)); } sub close { local(*S) = @_; local($sock) = @_; close(S); delete $listening{$sock} if ($listening{$sock}); } package main; &Getopts('d'); $sock = &network'open($host, $port); while (! defined($sock)) { sleep(10); $sock = &network'open($host, $port); } &network'write($sock, $login); sub send { local($_) = @_; print if ($opt_d); &network'write($sock, $_); } while ($_ = &network'readline($sock)) { print if ($opt_d); s/\r?\n?$//; if (/^NAME\? (.*)/) { $name = &network'addr2name($1); if ($name eq "") { &send("NONAME $1\n"); } else { &send("HOST $name = $name = $1\n"); } } elsif (/^ADDR\? (.*)/) { $addr = &network'name2addr($1); $name = &network'addr2name($addr); if ($name eq "") { &send("NOADDR $1\n"); } else { &send("HOST $1 = $name = $addr\n"); } } }