#!/usr/bin/perl use Getopt::Long; use IO::Socket; use IO::Select; package NetTool; #use strict; sub new{ my $self = {}; bless($self); return $self; } sub run { my ($self) = @_; $self->parse_options(); $self->connect_socket(); $self->forward_data(); } sub usage{ print "net_tool.pl [options]\n"; print " --connect connect to remote host.\n"; print " --listen listen for connection.\n"; print " --remote-host HOST host to connect to.\n"; print " --port PORT specify TCP port.\n"; print " --help print this message.\n" } sub parse_options{ my ($self) = @_; my $result = Getopt::Long::GetOptions("connect"=> \$self->{connect}, "listen" => sub { $self->{connect} = 0}, "remote-host=s" => \$self->{hostname}, "port=i" => \$self->{port}, "help" => sub {usage(); exit(0);}); if(!$result){ usage(); exit(1); } if(!defined($self->{connect})){ print("must specify either --connect or --listen\n"); usage(); exit(1); } if(!$self->{port}){ print("must specify a TCP port\n"); usage(); exit(1); } if($self->{connect} && !defined($self->{hostname})){ print("connect type requires a hostname\n"); usage(); exit(1); } } sub connect_socket{ my ($self) = @_; if($self->{connect}){ $self->{socket} = new IO::Socket::INET ( PeerAddr => $self->{hostname}, PeerPort => $self->{port}, Proto => 'tcp' ); die "Could not connect: $!\n" unless $self->{socket}; }else{ my $server = new IO::Socket::INET ( LocalHost => 'localhost', LocalPort => $self->{port}, Listen => 1, Reuse => 1); die "Could not listen on port $self->{port}: $!\n" unless $server; $self->{socket} = $server->accept(); } } sub forward_data{ my ($self) = @_; my $set = new IO::Select(); $set->add($self->{socket}); $set->add(STDIN); my $socket_set = new IO::Select(); $socket_set->add($self->{socket}); my $stdin_set = new IO::Select(); $stdin_set->add(STDIN); $self->{socket}->blocking(0) or die("unable to set socket to nonblocking"); STDIN->blocking(0) or die("unable to set stdin to nonblocking"); while(1){ my $select_set = IO::Select->select($set, undef, undef); my $buffer = '0'; while( $socket_set->can_read(0) ){ my $bytes = $self->{socket}->read($buffer, 100) or return; STDOUT->write($buffer); } $buffer = '0'; while( $stdin_set->can_read(0) ){ STDIN->read($buffer, 100) or return; $self->{socket}->write($buffer); } } } package main; $main::tool = NetTool->new(); $main::tool->run();