#!/usr/bin/perl

# ====================================================================
# The Vovida Software License, Version 1.0 
# 
# Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
#    and "Vovida Open Communication Application Library (VOCAL)" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact vocal\@vovida.org.
# 
# 4. Products derived from this software may not be called "VOCAL", nor
#    may "VOCAL" appear in their name, without prior written
#    permission of Vovida Networks, Inc.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# ====================================================================
# 
# This software consists of voluntary contributions made by Vovida
# Networks, Inc. and many individuals on behalf of Vovida Networks,
# Inc.  For more information on Vovida Networks, Inc., please see
# <http://www.vovida.org/>.


use Socket;
require "getopts.pl";

&Getopts("n:");

$number = $opt_n;

if($#ARGV < 1) {
#  print "Usage:\n";
#  print "$0 a:b:c d:e:f g\n";
#  print "where,\n";
#  print "a = agent host e.g. 192.168.5.1\n";
#  print "b = gateway sends to this port e.g. 2427\n";
#  print "c = agent listens to this port e.g. 5010\n";
#  print "d = gateway host e.g. 192.168.5.171\n";
#  print "e = agent sends to this port e.g. 5050\n";
#  print "f = gateway listens to this port e.g. 2427\n";
#  print "g = filter file\n";
#  print "e.g.\n$0 192.168.22.17:2427:5011 192.168.5.146:5051:2427\n";
#  exit(-1);
  $ARGV[0] = "172.19.175.195:2427:5011";
  $ARGV[1] = "172.19.175.222:5051:2427";
}

open(F, $ARGV[0]);
while(<F>) {
  chomp;
  if(/^listener/) {
    #listener  name        port     filter            default-sender
    ($file, $in_name, $in_port, $in_filter_name, $in_default_sender) = split(/\s+/);
    &mksocket($in_port, "IN_$in_name");

    $in_port{$in_name} = $in_port;
    $in_filter{$in_name} = $in_filter_name;
    $in_sender{$in_name} = $in_default_sender;

    
  } elsif(/^sender/) {
    #sender   sender-name   destination-ip   destination-port   listener-name

    ($file, $in_name, $in_port, $in_filter_name, $in_default_sender) = split(/\s+/);
  }

}
close(F);


($host1, $local_port1, $remote_port1) = split(/:/, $ARGV[0]);
($host2, $local_port2, $remote_port2) = split(/:/, $ARGV[1]);

&mksocket($local_port1, S1);
&mksocket($local_port2, S2);

($name,$aliases,$type,$len,$host1_addr) = gethostbyname($host1);
($name,$aliases,$type,$len,$host2_addr) = gethostbyname($host2);

$them_S1 = pack($sockaddr,PF_INET, $remote_port1, $host1_addr);
$them_S2 = pack($sockaddr,PF_INET, $remote_port2, $host2_addr);

# ($name,$aliases,$type,$len,$host3_addr) = gethostbyname("192.168.5.1");
# $them_agent1 = pack($sockaddr,PF_INET, "5012", $host3_addr);
# $them_agent2= pack($sockaddr,PF_INET, "5011", $host3_addr);

sub mksocket {
  local($port, $socket) = @_;
  
  $sockaddr = "S n a4 x8";($name,$aliases,$proto) = getprotobyname('udp');
  chomp($hostname  = `hostname`);
  #$hostname  = "192.168.10.12";
  
  ($name,$aliases,$type,$len,$myaddr) = gethostbyname($hostname);
  
  $me   = pack($sockaddr,PF_INET, $port, $myaddr);
  
  print "myaddr: $myaddr\n";
  print "port: $port\n";
  
  socket($socket, PF_INET, SOCK_DGRAM, $proto) || die $!;
  bind($socket , $me) || die "died with port $port $!";
  
}


while(1) {
  $rin = '';
  vec($rin, fileno(S1), 1) = 1;
  vec($rin, fileno(S2), 1) = 1;
  #        @bits = split(//, unpack("b*", $rin));
  #	if($bits[fileno(S)]) {
  #		print "got S\n";
  #	}
  if(select($rin, undef, undef, undef)) {
    @bits = split(//, unpack("b*", $rin));
    undef($data);
    undef($new_data);
    if($bits[fileno(S1)]) {
      print "got S1\n";
      $data = "";
      $his_address = recv(S1, $data, 60000, 0);
      if($data) {
	print "-----------------------------\n";
	print "$data";
	print "-----------------------------\n";
        $new_data = &rewrite_S1($data);
        if($new_data) {
	  print "$new_data";
	  print "-----------------------------\n";
	  defined(send(S2,$new_data,0,$them_S1)) || die $!;
        }
      }
    } elsif($bits[fileno(S2)]) {
      print "got S2\n";
      $data = "";
      $his_address = recv(S2, $data, 60000, 0);
      if($data) {
	print "-----------------------------\n";
	print "$data";
	print "-----------------------------\n";
        $new_data = &rewrite_S2($data);
        if($new_data) {
	  print "$new_data";
	  print "-----------------------------\n";
	  defined(send(S1,$new_data,0,$them_S2)) || die $!;
        }
      }
    }
  }
}
#$them = pack($sockaddr,PF_INET, $port, $myaddr);
#send(S,$msg,0,$them) || die $!;


sub renumber_S2 {
  local($_) = $_[0];
  
  s/^([0-9]*)\s([0-9]*)\s/$1 $map{$2} /;
  $map{$number} = $2;
  
  return $_;
}


sub renumber_S1 {
  local($_) = $_[0];
  if(s/^([a-zA-Z]*)\s([0-9]*)\s/$1 $number /) {
    $map{$number} = $2;
    $number++;
  }
  return $_;
}


# incoming messages to the call agent
sub rewrite_S1
{
  local($_) = $_[0];
#  if(y/\0//d) {
#    print "killed \\0!\n";
#  }

  # pretend a wild card is actually for the first endpoint
#  s/\*\@ubr/aaln\/0\@ubr/;
  # Use _ instead of / due to parsing problems (also change ubr924 to galileo)

  # split up dialed digits
#  s/O: D\/9/o: d\/5\,d\/0\,d\/0\,d\//;
#  s/O: D\/9([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])/o: d\/9\,d\/\1\,d\/\2\,d\/\3\,d\/\4\,d\/\5\,d\/\6\,d\/\7/;
#  s/O: D\/([0-9])([0-9])([0-9])([0-9])/o: d\/\1\,d\/\2\,d\/\3\,d\/\4/;

#  s/\*\@MGCP-2600.private.vovida.com/6243\@192.168.22.17/g;
#  s/\*\@MGCP-2600.private.vovida.com/aaln\/S1\/SU0\/0\@MGCP-2600.private.vovida.com/g;

#  s/aaln\/S1\/SU0\/0\@MGCP-2600.private.vovida.com/6243\@192.168.22.17/g;  
#  s/aaln\/S1\/SU0\/1\@MGCP-2600.private.vovida.com/5501\@192.168.22.17/g;
   
   return $_;
}


# outgoing messages to the MGCP gateways
sub rewrite_S2 
{
  local($_) = $_[0];
 if(y/\0//d)
  {
    print "killed \\0!\n";
  }


  # Change _ back to /   (also change galileo back to ubr924)

  # change the use of wildcard x to explicit [0-9#*T], but it T needed here?
  s/d\/x\(d\)/d\/\[0-9\#\*T\]\(D\)/;


#  s/d\/x\(n\)/d\/\[0-9\#\*\]\(n\)/; 
#  if (/crcx/)
#  {
#      if (!/v=0/)
#      {
#          s/M: sendrecv/M: recvonly/;
#      }
#  }

#  s/\r\n\r\n/\r\n/g;
#
#  if (/mdcx/)
#  {
#      s/v=0/\r\nv=0/;
#  }
#  if(/RQNT/)
#  {
#    s/S: l\/dl/S: l\/wt/g;
#   }

#
#s/o=- 0 0 IN IP4 192.168.22.17\r\ns=Vovida Gateway\r\n//;

#s/o=CiscoSystemsSIP-GW-UserAgent [0-9]+ [0-9]+ IN IP4 192.168.6.210\r\ns=SIP Call\r\n//;

#s/o=[^\r\n]*\r?\n[^\r\n]*\r?\n//g;
#s/s=[^\r\n]*\r?\n//g;

 #changes here 
#  s/IN IP4 hera.private.vovida.com/IN IP4 192.168.22.17/g;
#  s/2600\@192.168.5.146/\*\@MGCP-2600.private.vovida.com/g;
# s/6243\@192.168.22.17/aaln\/S1\/SU0\/0\@MGCP-2600.private.vovida.com/g;
#  s/5501\@192.168.22.17/aaln\/S1\/SU0\/1\@MGCP-2600.private.vovida.com/g;
   
   s/a=fmtp*\r?\n[^\r\n]*\r?\n//g;
   s/a=fmtp:101 0-11//g;
   s/a=fmtp:100 0-11//g;

  return $_;

}

