IO-Multiplex-KQueue

 view release on metacpan or  search on metacpan

contrib/portfw  view on Meta::CPAN

#!/usr/bin/perl -w

=pod

=head1 NAME

portfw - Port forwarder

=head1 SYNOPSYS

portfw [-p pidfile] [local_ip:]local_port[/proto] remote_ip[:remote_port]

=head1 DESCRIPTION

Forwards all incoming request from local_port to remote_port.  If
local_ip is not specified, all addresses on all interfaces are used.
If no remote_port is specified, then the same local_port is assumed
as the default.  If no /proto is specified, tcp is assumed.

=head1 AUTHOR

Rob Brown - bbb@cpan.org

$Id: portfw,v 1.7 2003/07/30 06:50:26 rob Exp $

=cut

use strict;
use Getopt::Long;
use IO::Multiplex::KQueue;
use IO::Socket;

my $pidfile;
GetOptions
  "pidfile=s" => \$pidfile,
  ;

my ($local_addr,$remote_addr)=@ARGV;
die "Missing local port\n" if !$local_addr;
die "Missing remote ip\n" if !$remote_addr;

my ($local_ip, $local_port, $proto,
    $remote_ip,$remote_port);
if ($local_addr =~ s%/(\w+)$%%) {
  $proto = $1;
} else {
  $proto = "tcp";
}
if ($local_addr =~ s%^([\d\.]+):%%) {
  $local_ip = $1;
} else {
  $local_ip = "0.0.0.0";
}
if ($local_addr =~ m%^(\d+)$%) {
  $local_port = $1;
} else {
  die "Invalid local port [$local_addr]\n";
}
if ($remote_addr =~ s%:(\d+)$%%) {
  $remote_port = $1;
} else {
  $remote_port = $local_port;
}
if ($remote_addr =~ m%^([\d\.]+)$%) {
  $remote_ip = $1;
} else {
  die "Invalid remote ip [$remote_addr]\n";
}

print STDERR "Forwarding $proto packets from $local_ip:$local_port to $remote_ip:$remote_port\n";

# Get ready to receive an incoming connection
my $listen = new IO::Socket::INET
  LocalAddr => $local_ip,
  LocalPort => $local_port,
  Proto     => $proto,
  ReuseAddr => 1,
  $proto eq "tcp"?(Listen => 10):(),
  or die "Could not bind local port $local_port/$proto: $!";

# Just test the remote connection once.
my $remote_connect = new IO::Socket::INET
  PeerAddr => $remote_ip,
  PeerPort => $remote_port,
  Proto    => $proto,
  or die "Could not connect to remote $remote_ip:$remote_port/$proto: $!";

if ($proto eq "tcp") {
  # Close the test tcp socket
  $remote_connect->close;
} elsif ($proto eq "udp") {
  # Keep this around for udp replies
} else {
  die "Unimplemented protocol $proto\n";
}

if ($pidfile) {
  if (my $pid = fork) {



( run in 1.358 second using v1.01-cache-2.11-cpan-8dfa8b56332 )