1############################################################################ 2# 3# Standalone nathelper which can be used with SIP proxy 4# for transferring RTP data between networks/through a firewall.. 5# uses Net::SIP::NAT::NATHelper::Server which communicates 6# with Net::SIP::NAT::NATHelper::Client 7# 8# Communication is via sock_stream sockets (unix domain or tcp) and the 9# commands are are an array-ref consisting of the command name 10# and the arguments. Commands are 'allocate','activate' and 'close'. 11# For the arguments of the command and the return values see the 12# methods in Net::SIP::NATHelper::Base. 13# For transport the requests and responses will be packet with 14# Storable::nfreeze and prefixed with a long in network format containing 15# the length of the freezed packet (necessary, because stream sockets 16# are used). 17# 18############################################################################ 19 20use strict; 21use warnings; 22use Getopt::Long qw(:config posix_default bundling); 23use File::Path; 24use IO::Socket; 25use Net::SIP ':debug'; 26use Net::SIP::NATHelper::Server; 27 28############################################################################ 29# USAGE 30############################################################################ 31 32sub usage { 33 print STDERR "ERROR: @_\n" if @_; 34 print STDERR <<USAGE; 35 36NAT Helper for SIP proxy. 37Reads cmds from cmd-socket, allocates sockets for RTP and send 38information about sockets back to caller, which then rewrites the 39SDP bodies in the SIP packets. 40 41$0 [options] cmd-socket+ 42Options: 43 -d|--debug [level] Enable debugging 44 -h|--help Help (this info) 45 -R|--chroot cage-dir run chrooted (after opening sockets) 46 47cmd-socket is a UNIX domain socket if it contains '/'. If it points 48to an existing directory or contains a trailing '/' cmd-socket will be 49interpreted as a directory name and a file 'socket' will be created below 50the directory. 51If the syntax is 'host:port' a TCP socket will be created. 52Multiple cmd-sockets can be specified. 53 54USAGE 55 exit( @_ ? 1:0 ); 56} 57 58############################################################################ 59# Read Options 60############################################################################ 61 62my ($debug,$chroot); 63GetOptions( 64 'd|debug:i' => \$debug, 65 'h|help' => sub { usage() }, 66 'R|chroot=s' => \$chroot, 67) || usage( 'bad option' ); 68Net::SIP::Debug->level( $debug || 1 ) if defined $debug; 69 70my @sockets = @ARGV; 71@sockets or usage( "no command sockets" ); 72 73my @cfd; 74foreach my $socket ( @sockets ) { 75 DEBUG( $socket ); 76 if ( $socket =~ m{/} ) { 77 if ( $socket =~m{/$} or -d $socket ) { 78 -d $socket or mkpath( $socket, 0,0700 ) 79 or die $!; 80 $socket = $socket."/socket"; 81 } 82 push @cfd, IO::Socket::UNIX->new( Type => SOCK_STREAM, Local => $socket ) 83 || die $!; 84 } elsif ( $socket =~ m{^(.*):(\d+)$} ) { 85 push @cfd, IO::Socket::INET->new( 86 LocalAddr => $1, 87 LocalPort => $2, 88 Listen => 10, 89 Reuse => 1, 90 ) || die $!; 91 } 92} 93 94# all sockets allocated, now we can change root if necessary 95if ( $chroot ) { 96 # load Storable::* by eval if chroot 97 eval { Storable::thaw() }; 98 eval { Storable::nfreeze() }; 99 100 chdir( $chroot ) || die $!; 101 chroot( '.' ) || die $!; 102} 103 104# create wrapper and run 105Net::SIP::NATHelper::Server->new( @cfd )->loop; 106