Listing 1 use strict; use Math::VecStat qw(sum); use Crypt::CBC; use IO::Socket::INET; use Getopt::Std; use vars qw($opt_i $opt_r $opt_p $opt_t); getopts("i:r:p:t:"); use constant PORTMIN => 745; use constant KEY => "knock"; # keyphrase for the encryption use constant CIPHER => "Blowfish"; # encryption algorithm $opt_i || die "specify local IP"; $opt_r || die "specify remote IP"; $opt_p || die "specify remote port"; defined $opt_t || die "specify time flag"; my $cipher = Crypt::CBC->new({key=>KEY,cipher=>CIPHER, iv=>"01234567",prepend_iv => 0}); # data to encrypt will be our IP address + port + time + checksum my @data = (split(/\./,$opt_i),$opt_p,$opt_t); # compute checksum and push it onto the data array push(@data,sum(@data) % 255); print "encrypting data ",join(" ",@data),"\n"; # encrypt the packed data my $ciphertext = $cipher->encrypt(pack("C*",@data)); # unpack the ciphered data into unsigned char values 0-255 my @cipherpack = unpack("C*",$ciphertext); # create the knock sequence by mapping to ports PORTMIN-PORTMIN+255 my @knocks = map {PORTMIN+$_} @cipherpack; print "knock sequence ",int(@cipherpack)," knocks ",join(" ",@knocks),"\n"; # create TCP connections for each port in the sequence for my $port (@knocks) { my $sock = IO::Socket::INET->new(PeerAddr => $opt_r, PeerPort => $port, Timeout => 0.5, Proto => 'tcp'); print " knocked on $opt_r:$port\n"; } exit 0; ### end of Listing 1