kernelthread.com

TCP/IP Server

The Towers of Hanoi as a TCP/IP Server.

#! /usr/bin/perl -w # # The Towers Of Hanoi # Network Server (TCP/IP) Implementation # Copyright (C) 1998 Amit Singh. All Rights Reserved. # http://hanoi.kernelthread.com # # Tested on Linux # # Check against $PATH `tricks' # BEGIN { $ENV{PATH} = '/sbin:/bin' } # --- configurable section --- my $TRUSTED_USER = "root"; # only this username trusted my $TRUSTED_HOST = "localhost"; # requests from this hostname only my $TRUSTED_ADDR = "127.0.0.1"; # requests from this IP addr only my $HANOID_LOG = "/tmp/hanoid.log"; # path to the logfile my $HANOID_PORT = "1234"; # port to listen on # --- end of configurable section --- use strict; use Socket; use Carp; # Setup and start # my $port = $HANOID_PORT; my $proto = getprotobyname('tcp'); $port = $1 if $port =~ /(\d+)/; socket(S, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; setsockopt(S, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; bind(S, sockaddr_in($port, INADDR_ANY)) || die "bind: $!"; listen(S, SOMAXCONN) || die "listen: $!"; logmsg("server started on port $port\n"); $SIG{CHLD} = \&REAPER; my ($t_paddr, $t_port, $t_iaddr, $t_host, $t_addr, $t_user); for ( ; $t_paddr = accept(Client, S); close Client) { ($t_port, $t_iaddr) = sockaddr_in($t_paddr); $t_host = gethostbyaddr($t_iaddr, AF_INET); $t_addr = inet_ntoa($t_iaddr); logmsg("query $t_port, $port, $t_host\n"); $t_user = auth_rfc931($t_port, $port, $t_host); if ( ($t_addr eq $TRUSTED_ADDR) && ($t_host eq $TRUSTED_HOST) #&& #($t_user eq $TRUSTED_USER) ) { print Client "Trusted username/hostname/IP combination: OK\n"; my $N = <Client>; chomp($N); if (($N < 1) || ($N > 9)) { print Client "*** Illegal number of disks\n"; print Client "*** Only an integer N (0 < N < 10) permitted\n\n"; } else { hanoi($N, 3, 1, 2); } } else { print Client "Untrusted username/hostname/IP combination: sorry\n"; } } sub auth_rfc931 { my $PORT_IDENTD = 113; my ($local_port, $remote_port, $check_host) = @_; my ($remote, $port, $iaddr, $paddr, $proto, $line); my ($f1, $f2, @rest); $port = $PORT_IDENTD; $remote = $check_host; if ($port =~ /\D/) { $port = getservbyname($port, 'tcp'); } $iaddr = inet_aton($remote) || return(undef); $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname("tcp"); socket(SOCK, PF_INET, SOCK_STREAM, $proto) || return(undef); connect(SOCK, $paddr) || return(undef); my $request = "$local_port, $remote_port\r\n"; syswrite SOCK, $request, length($request); my $n = sysread SOCK, $line, 128; close (SOCK) || return(undef); chomp($line); logmsg("identd reply $line\n"); ($f1, $f2, @rest) = split(/:/, $line); if (not($f2 =~ /[ \t]*USERID[ \t]*/)) { return(undef); } my $user = $rest[-1]; return($user); exit; } sub logmsg { $|=1; open(LOG, ">>$HANOID_LOG") || die "open: $!"; my $ctime = localtime(); print LOG "$0 $$: at $ctime @_"; close(LOG); } sub hanoi { my ($n, $to, $from, $using) = @_; if ($n > 0) { hanoi($n-1, $using, $from, $to); print Client "move $from --> $to\n"; hanoi($n-1, $to, $using, $from); } } #__END__

Download

hanoi.srv