#!/usr/bin/perl -w # Not really a packet sniffer, more a proxy that dumps what it # proxies. Written in the days before I learned to write perl somewhat # cleanly. This would probably explode if you put in 'use strict'. # Waider 1996 or 1997 # 13/05/2003 Make sockets reusable and non-lingering $host = $ARGV[0] || die "Usage: $0 host listenport connectport"; $listenport = $ARGV[1] || die "Usage: $0 host listenport connectport"; $connectport = $ARGV[2] || die "Usage: $0 host listenport connectport"; $|=1; use Socket; $sockaddr = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $port) = getservbyname($listenport, 'tcp') unless $listenport =~ /^\d+$/; $this = pack($sockaddr, &AF_INET, $listenport, "\0\0\0\0"); socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!"; bind(S, $this) || die "bind: $!"; setsockopt(S, SOL_SOCKET, SO_REUSEADDR, 1 ); setsockopt(S, SOL_SOCKET, SO_LINGER, 0 ); listen(S, 5) || die "listen: $!"; select(S); $| = 1; select(STDOUT); for (;;) { print "Listening again\n"; ($addr = accept(NS,S)) || die $!; setsockopt(NS, SOL_SOCKET, SO_REUSEADDR, 1 ); setsockopt(NS, SOL_SOCKET, SO_LINGER, 0 ); print "accept ok\n"; (undef,$port,$inetaddr) = unpack($sockaddr,$addr); @inetaddr = unpack('C4',$inetaddr); print "Connection from ", join('.', @inetaddr ), ":$port\n"; (undef, undef, $cproto) = getprotobyname( 'tcp' ); $cthat = pack_sockaddr_in( $connectport, inet_aton( $host )); socket( CS, PF_INET, SOCK_STREAM, $cproto ) || die $!; warn $!, next unless ( connect( CS, $cthat ) && print "Connected.\n" ); $hexcount=0; $line=""; select( CS ); $| = 1; select( STDOUT ); select( NS ); $| = 1; select( STDOUT ); readloop: while (1) { $rin=$rout=$win=$wout=$ein=$eout=''; vec( $rin, fileno( NS ), 1) = 1; vec( $win, fileno( NS ), 1) = 1; vec( $rin, fileno( CS ), 1) = 1; vec( $win, fileno( CS ), 1) = 1; $ein=$rin|$win; $nfound=select( $rout=$rin, $wout=$win, $eout=$ein, 0 ); if ( $nfound ) { if ( vec( $rout, fileno( NS ), 1 )) { $nbytes=sysread( NS, $buf, 1024 ); if ( !defined( $nbytes )) { print "\n" . scalar( localtime(time )) . " CLIENT sysread() returned undef.\n"; last readloop; } if ( $nbytes < 1 ) { print "\n" . scalar( localtime(time )) . " CLIENT sysread() returned < 1.\n"; last readloop; } print STDOUT "\n" . scalar( localtime(time )) . " FROM CLIENT\n"; $hexcount = 0; $hextot = 0; printf( STDOUT "%06X ", $hextot ); for ($i=0;$i<$nbytes; $i++) { $x=substr($buf, $i, 1 ); printf( STDOUT "%02X ", ord($x)); $line.=(( $x ge " " ) && ( ord( $x ) <= 127 ))?$x:"."; $hexcount++; $hextot++; if ($hexcount == 16 ) { print STDOUT " $line"; $line=""; print STDOUT"\n"; printf( STDOUT "%06X ", $hextot ); $hexcount=0; } } syswrite( CS, $buf, $nbytes ); } if ( vec( $rout, fileno( CS ), 1 )) { $nbytes=sysread( CS, $buf, 1024 ); if ( !defined( $nbytes )) { print "\n" . scalar( localtime(time )) . " SERVER sysread() returned undef. $!\n"; last readloop; } if ( $nbytes < 1 ) { print "\n" . scalar( localtime(time )) . " SERVER sysread() returned < 1.\n"; last readloop; } if ( $line ne "" ) { $z = 16 - length( $line ); print " "x($z*3); print " $line"; $line = ""; } print STDOUT "\n" . scalar( localtime(time )) . " FROM SERVER\n"; $hexcount = 0; $hextot = 0; printf( STDOUT "%06X ", $hextot ); for ($i=0;$i<$nbytes; $i++) { $x=substr($buf, $i, 1 ); printf( STDOUT "%02X ", ord($x)); $line.=(( $x ge " " ) && ( ord( $x ) <= 127 ))?$x:"."; $hexcount++; $hextot++; if ($hexcount == 16 ) { print STDOUT " $line"; $line=""; print STDOUT"\n"; printf( STDOUT "%06X ", $hextot ); $hexcount=0; } } for ($i=0;$i<$nbytes;$i++) { syswrite( NS, substr($buf, $i, 1), 1 ); } } } if ( vec( $eout, fileno( NS ), 1 ) || vec( $eout, fileno( CS ), 1)) { #print "Error.\n" ; #last readloop; } } print STDOUT"\n"; # Close connections close(NS); close(CS); }