I have been working on modifiying VOIPONG to be executed on-demand, so that Voipong doesn’t have to record all streams, just the ones we tell it to. Several things had to be modified for this to work properly. First off, I had to figure out a way to tell Voipong to only look at network traffic for one specific host. The easiest way to accomplish this without modification, was to simply pass in a different configuration file for each recording request. The configuration file allows to specify a startup filter which was used to simply limit the berkley packet filter to only look at traffic for a specific ip address.

startup = “host ‘ . $ip . ‘ and udp”

Secondly I had to modify Voipong to exit properly after it is done recording the phone call. Then, I also modified it to handle passing in a new filename prefix to attach to the file, so that we can pass in a specifc identifier to link the file to a particular record in a database.

I wrote a small client-server application to execute the modified Voipong executable. The back end is a C program that runs on the server through the inetd facility. Inetd handles all of the socket connections and closings. For each simultaneous connection, an instance of this program will be executed. I have tried to keep it as simple as possible so that it is easy to troubleshoot.

I have built in the following error codes in the different steps along the process to help troubleshoot potential problems.

Client Error Messages

  • 400 – Did not get propper get vars
  • 401 – Not able to connect to ldap
  • 402 – No Phone Ip Address
  • 403 – Not able to connect to server service

Server Error Messages

  • 500 – Invalid command
  • 501 – No config file for that phone ip address
  • 502 – the filename for the recording already exits
  • 503 – voipong already running or stale pid file

Protocol

Client connects -> Server at port 11200 //or whatever port you want

  • Server:HELLO
  • Client:RECORD //Or other command
  • Client:10.10.10.100 //IP Address of phone
  • Server:OK 200
  • Client:92381 //file name prefix
  • Server:OK 200
  • Server:RECORDING
  • close connection

Server

The server is a simple C program, reading and writing data through stdin and stdout. Inetd server is used to make the actual socket connections. When aconnection is made to inetd, inetd executes the compiled version of the server, and the server outputs “HELLO” to stdout which is sent to the client. The protocol is followed by the client sending a command back to the socket of what to do. So far the only valid command is RECORD. The RECORD command is sent through the inetd facility and then back into the server instance this is reading data from stdin. The protocol continues on reading and writing data or an error message through stdin/stdout, until the command set is complete. Upon the final step, execl is called to execute a modified voipong instance. Simple, right!

Client

The client can be written in any language that has network connectivity to the Voipong server, and that is able to read and write data to a socket. I used PHP to make a simple script that does just that.

<?php
$server
= ’10.10.10.10′;
$port = ’11200′;
//$debug = 1;

error_reporting(false);

/*
–Chat should go as follows–
Client connects -> Server 11200
Server:HELLO
Client:RECORD      /Or other command
Client:10.10.10.100 /IP Address of phone
Server:OK 200
Client:92381       /filename prefix
Server:OK 200
Server:RECORDING
close connection

—Client Error Messages—
400 – Did not get propper get vars
401 – Not able to connect to ldap
402 – No Phone Ip Address
403 – Not able to connect to server service

—Server Error Messages—
500 – Invalid command
501 – No config file for that phone ip address
502 – the filename for the recording already exits
503 – voipong already running or stale pid file

*/

if(!$_GET[‘tempsid’] || !$_GET[‘uid’]){
   echo
“ER 400″;
   exit();
}
include_once(
‘../ldap.inc’);
//Connect to LDAP to get users phone ip address.

if ($ds) {
   
// verify binding
   
if ($ldapbind) {
      
$filter=“(&(uid=$_GET[uid])(IsActive=TRUE))”;
      
$justthese = array(“phoneDeviceIPAddr”);
      
$sr=ldap_search($ds, $sdn, $filter, $justthese);

      //$sr=ldap_search($ds, $sdn, ‘uid=*’);
      
$entry = ldap_get_entries($ds, $sr);
      
$phoneidaddr = $entry[0][‘phonedeviceipaddr’][0];

   }
} else {
   echo
“ER 401″;
   exit();
}
$total_records = count($entry);

if(!$phoneidaddr || strlen($phoneidaddr) < 8){

   echo “ER 402″;
   exit();
}

$fp = fsockopen($server,$port, $errno, $errstr, 10);
if (!
$fp) {

   echo “ER 403″;
   exit();
} else {
   
// Initial Connection get prompt
   
$result = fgets($fp, 6);

   if($result == ‘HELLO’){

      // Send Command
      
if($debug) echo “\nSend Command: RECORD”;
      
fwrite($fp, “RECORD\r\n”);
      
$result = fgets($fp, 7);

      if($result != ‘OK 200′){
         echo
$result;
         exit();
      }

      // Send Phone IP
      
fwrite($fp, “$phoneidaddr\r\n”);

      if($debug) echo “\nPhone Ip: $phoneidaddr”;
      
$result = fgets($fp, 7);
      if(
$result != ‘OK 200′){

         echo $result;
         exit();
      }

      // Send filename prefix
      
if($debug) echo “\nSend filename:” . $_GET[‘tempsid’];
      
fwrite($fp, $_GET[‘tempsid’] . “\r\n”); // filenameprefix

      $result = fgets($fp, 7);
      if(
$result != ‘OK 200′){
         echo
$result;
         exit();

      }

      $result = fgets($fp, 10);
      if(
$debug) echo “\nFinal Result:”;
      echo
“$result”;

   }

   fclose($fp);
}
?>

Usage

For this example, all that you need to do is fetch the url that the php script exists as with the $uid and $temsid varibles defined. Of course in this example I am pulling the phone’s ip address out of ldap based on the uid, but you could obviously do this however you like.

Source

I have the source in working condition, but want to clean it up before pushing it out. I have done the modifications to the 2.0 devel version of VOIPONG. If you would like to test it, send me an email and we can work something out. [ alex -~AT~- 4devz . com ] When I get a chance, I’ll try to get a patch for voipong together, and the server I wrote.

Cheers!

PS. Here is a little php script I threw together to generate all the config files.

<?php
// PHP Script to create individual voipong configuration files.
// to be placed in 10.10.10.10:/usr/local/etc/voipong/client

for($x=11;$x<100;$x++){
    
$ip = “10.10.10.$x”;

    $filename = “./$ip.conf”;
    
$config = ‘#
# voipong.conf    
# VOIPONG konfigurasyon dosyasi
#
#    VoIPong Voice Over IP Sniffer
#    Copyright (C) 2004,2005 Murat Balaban
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the GNU General Public License
#    as published by the Free Software Foundation; either version 2
#    of the License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place – Suite 330, Boston, MA  02111-1307, USA.
#
# $Id: voipong.conf,v 1.10 2005/12/04 14:27:35 murat Exp $
#

[GENERAL]
logdir = /usr/output
logfile = voipong.log
cdrfile = voipcdr.log
networksfile = /usr/local/etc/voipong/voipongnets
pidfile = /var/run/’
. $ip . ‘.voipong.pid
mgmt_ipcpath = /tmp/voipongmgmt.sock
soxpath = /usr/local/bin/sox
soxmixpath = /usr/local/bin/soxmix
modpath = /usr/local/etc/voipong/modules
mixwaves = 1
defalg = lfp
rtp_idle_time = 10
#device = fxp0
device = bge0
promisc = 1
snaplen = 1500
readtmt = 500
outdir = /usr/output

[FILTERS]
startup = “host ‘
. $ip . ‘ and udp”
;

   $fp =fopen($filename,“w”);
   
fputs($fp,$config);
   
fclose($fp);
}

?>