- 论坛徽章:
- 0
|
因为工作需要需要一个可以对数据包进行过滤处理的UDP端口映射,所以就写了一个,只不过考虑到过滤部分对大家没什么用所以在贴上来的时候就去掉了。
#!/usr/bin/perl -w
use strict;
use IO::Socket::INET;
use IO::Select;
use Socket qw(unpack_sockaddr_in);
open(CONFIG,"<udp_PortMap.conf");
#
#配置文件格式:本地端口=目的IP:目的端口
#
#
my @config;
while(my $line=<CONFIG>){
$line=~s/[\n\r\b\ ]+//igs;
my @param=split /[\=\:]+/,$line;
print join(',',@param),"\n";
push(@config,\@param);
}
close(CONFIG);
foreach(@config){
if(fork()){
print join(',',@$_),"\n";
portmap(@$_);
}
}
sleep(0);
sub portmap{
my $localport=shift;
my $tagip=shift;
my $tagport=shift;
my $socket_listen=IO::Socket::INET->new(LocalPort=>$localport,
Proto=> 'UDP'
);
my $readers = IO::Select->new();
$readers->add($socket_listen);
my %client_agent;
my %agent_client;
my %timeout;
while(1){
my $buf;
my @readers = $readers->can_read(5);
foreach my $reader(@readers){
if($reader eq $socket_listen){
if(my $addr=$reader->recv($buf,4096)){
#print unpack_addr($addr),"\n";
if(!$client_agent{$addr}){
$client_agent{$addr}=IO::Socket::INET->new(
PeerAddr=>"$tagip:$tagport",
Proto=> 'udp',
) or die $@;
$agent_client{$client_agent{$addr}}=$addr;
$readers->add($client_agent{$addr});
$timeout{$client_agent{$addr}}=time();
}
send($client_agent{$addr},$buf,0);
print unpack_addr($addr),'->',
$client_agent{$addr}->sockhost(),':',$client_agent{$addr}->sockport(),'->',
$client_agent{$addr}->peerhost(),':',$client_agent{$addr}->peerport(),"\n";
}
}else{
if(my $addr=$reader->recv($buf,4096)){
if($agent_client{$reader}){
send($socket_listen,$buf,0,$agent_client{$reader});
$timeout{$reader}=time();
print unpack_addr($addr),'->';
print $reader->sockhost(),':',$reader->sockport(),'->',
unpack_addr($agent_client{$reader}),"\n";
}
}
}
}
foreach my $agent(keys %timeout){
if($timeout{$agent}+4<time()){
$readers->remove($agent);
delete $client_agent{$agent_client{$agent}};
delete $agent_client{$agent};
delete $timeout{$agent};
close($agent);
}
}
}
}
sub unpack_addr{
my $addr=shift;
my($port,$ip)=sockaddr_in($addr);
$ip=inet_ntoa($ip);
return "$ip:$port";
} |
|