voipong-2.0/0040755000175400000000000000000010346323236012047 5ustar muratwheelvoipong-2.0/docs/0040755000175400000000000000000010346320213012767 5ustar muratwheelvoipong-2.0/docs/CVS/0040755000175400000000000000000010346320213013422 5ustar muratwheelvoipong-2.0/docs/CVS/Root0100644000175400000000000000001310346320213014257 0ustar muratwheel/cvsup/cvs voipong-2.0/docs/CVS/Repository0100644000175400000000000000001510346320213015515 0ustar muratwheelvoipong/docs voipong-2.0/docs/CVS/Entries0100644000175400000000000000003510346320213014751 0ustar muratwheelD/src//// D/users-manual//// voipong-2.0/docs/src/0040755000175400000000000000000010346322342013563 5ustar muratwheelvoipong-2.0/docs/src/CVS/0040755000175400000000000000000010346322336014221 5ustar muratwheelvoipong-2.0/docs/src/CVS/Root0100644000175400000000000000001310346320213015046 0ustar muratwheel/cvsup/cvs voipong-2.0/docs/src/CVS/Repository0100644000175400000000000000002110346320213016301 0ustar muratwheelvoipong/docs/src voipong-2.0/docs/src/CVS/Entries0100644000175400000000000000102110346322336015544 0ustar muratwheel/Makefile/1.3/Sun Nov 20 15:11:09 2005// /book.sgml/1.6/Wed Dec 7 11:15:44 2005// /chapters.ent/1.4/Wed Dec 7 11:15:44 2005// /config.sgml/1.3/Wed Dec 7 11:15:44 2005// /dsom.sgml/1.2/Wed Dec 7 11:38:46 2005// /examples.sgml/1.3/Tue Dec 6 09:29:25 2005// /faq.sgml/1.1/Sun Nov 20 14:51:02 2005// /features.sgml/1.2/Sun Dec 4 14:58:40 2005// /intro.sgml/1.2/Sun Dec 4 14:58:40 2005// /thanks.sgml/1.1/Sun Nov 20 14:51:02 2005// /usage.sgml/1.8/Wed Dec 7 13:35:35 2005// /installation.sgml/1.4/Fri Dec 9 15:36:56 2005// D voipong-2.0/docs/src/Makefile0100644000175400000000000000036510340111015015207 0ustar muratwheelDOC?= book FORMATS?= html-split html MAINTAINER= murat@enderunix.org INSTALL_COMPRESSED?=gz SRCS= book.sgml DOC_PREFIX?= /usr/doc #DESTDIR= /home/murat/public_html/ DESTDIR= ../users-manual .include "${DOC_PREFIX}/share/mk/doc.project.mk" voipong-2.0/docs/src/book.sgml0100644000175400000000000000232110345542140015373 0ustar muratwheel %man; %chapters; ]> VoIPong User's Manual Murat Balaban
murat ~ enderunix.org
$Id: book.sgml,v 1.6 2005/12/07 11:15:44 murat Exp $ 2004 2005 Murat Balaban. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
&chap.intro; &chap.features; &chap.install; &chap.dsom; &chap.config; &chap.usage; &chap.examples; &chap.faq; &chap.thanks;
voipong-2.0/docs/src/chapters.ent0100644000175400000000000000062710345542140016105 0ustar muratwheel voipong-2.0/docs/src/config.sgml0100644000175400000000000001640410345542140015715 0ustar muratwheel Configuration Configuration files are all installed into VoIPong directory: /usr/local/etc/voipong. Main configuration parameters are included in voipong.conf file. voipongnets file maps network addresses to their proper algorithms. DSOM modules for g711-ulaw and g711-alaw (modvocoder_pcmu.so, modvocoder_pcma.so) are installed to the path given with the modpath configuration file directive. Configuration file: voipong.conf Runtime configuration parameters vital to the smoothly operation of VoIPong server are defined in voipong.conf, formatted as a standart .ini file. There are two sections: GENERAL for general server settings, and FILTERS for setting up startup filters. GENERAL section logdir: specifies the log directory where voipong will save its logs e.g. /var/log logfile: name of the main server log file e.g. voipong.log outdir: path where output .WAV and/or .RAW files are to be written. e.g. /var/log/voipoutput cdrfile: name of the CDR (Common Data Record) log file e.g. cdr.log networksfile: path to the network/algorithm mappings file e.g. /usr/local/etc/voipong/voipongnets pidfile: path to the pidfile e.g. /var/run/voipong.pid soxpath: path to the sox executable e.g. /usr/local/bin/sox modpath: path to the directory where vocoder DSOM modules are installed. e.g. /usr/local/etc/voipong/modules soxmixpath: path to the soxmix executable e.g. /usr/local/bin/soxmix mgmt_ipcpath: path to the UNIX domain socket for management console e.g. /tmp/voipongmgmt.sock defalg: Default packet matching algorithm. This can currently only be lfp. Other algorithms are to be developed. e.g. lfp rtp_idle_time: (in seconds) when this amount of time elapses and no RTP traffic is received for the call, the call is considered to be finished. e.g. 10 device: network device to sniff packets from e.g. eth0 promisc: set this to true 1 if you want VoIpong to set your sniffing device to promiscious mode. e.g. set this to 1 for true, 0 for false. mixwaves: set this to true 1 if you want VoIPong to mix the seperate .WAV files into a single .WAV file. e.g. set this to 1 for true, 0 for false. snaplen: maximum number of bytes to capture e.g. 1500 readtmt: specifies the read-from-device timeout in milliseconds. e.g. 500 FILTERS section startup: Pcap filter string. This filter will be set during startup procedures. To see detailed usage of pcap filters, see pcap(3) manual page. e.g. "udp" Network - Algorithm mappings: voipongnets Sniffing out voice is a tough task. You cannot design an algorithm and expect to catch all the VoIP calls. VoIP is relatively new and it is not a highly standardized technology. So there have to be several call catching algorithms for various setups. VoIPong provides a framework where you can set the call catching algorithm which you think will best suit your VoIP infrastructure. This results in a much more specialized and successful call sniffing. Least False Positive (LFP) algorithm This algorithm tries to detect calls generated via VoIP devices conforming to RTP and RTCP RFCs. This algorithm should detect and record a broad range of calls. The most obvious advantage of this algorithm is that you'll have barely no false positives. This is why this method is named as LFP. The #1 disadvantage will be that this will not be able to catch calls if there are no RTCP packets or the devices do not conform to RFCs. To use this algorithm, you will need to specify a network to use with it in your voipongnets file. 172.16.1.0/255.255.255.0 lfp 10.30.0.0/255.255.252.0 lfp Fixed (Fixed Port) algorithm Some VoIP devices (e.g. Grandstream(TM) IP adapters) use a fixed port to send and receive RTP datagrams, and they do not conform to RFCs, and do not send any link control information (RTCP packets). If you have such devices in your network, you can specify their algorithm as fixed in the voipongnets file. This algorithm cannot be used with networks, it can only be used with hosts, so netmask address should always be 255.255.255.255. Please note that, after the fixed keyword, you are expected to set the fixed port number the device is using. For example, suppose that you have a device which uses port 40000 to send RTP packets, you should add this line to your voipongnets file: 172.16.1.101/255.255.255.255 fixed 40000 LRA-SIP Algorithm LRA-SIP will follow SIP signalling packets, and will spot the RTP/RTCP session from the SDP packets. This algorithm is not implemented yet, however I will be working on it for the next release (probably 2.1.?) voipong-2.0/docs/src/dsom.sgml0100644000175400000000000000405310345544706015421 0ustar muratwheel Dynamic Shared Object Modules (DSOM) Since release 2.0 upwards, VoIPong provides a powerful dynamic framework for loading of 3rd party voice decoders into the running voipong executable at runtime. This is called Dynamic Shared Object Modules (DSOM) Framework. Simply put, DSOM vocoder modules are shared libraries with the .so extension. VoIPong looks for those shared libraries in the preconfigured modpath directory, loads them one by one. DSOM engine resident at VoIPong core, spots the initialization method in the shared module and invokes it allowing the module to register itself inside VoIPong runtime environment: 07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2813e370) 07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x28140390) 07/12/05 13:29:25: loaded 2 module(s) For security reasons, the DSOMs are expected to be owned by the same user and group who is running the core VoIPong executable. For instance, if the user running the program has uid 1000 and gid 10; the modules should also be owned by uid 1000 and gid 10. The naming convention is that the modules should start with the modvocoder_ keyword, and should include the name of the decoder in the module, followed by the .so extension. For example, the correct name for the g711 (u-law) module can be modvocoder_pcmu.so. There are two pre-written voice decoder modules with VoIPong release 2.0: modvocoder_pcmu.so: g711 (u-law) decoder (payload type 0) modvocoder_pcma.so: g711 (a-law) decoder (payload type 8) To code and install your own vocoder module (i.e. for g726), VoIPong DSOM Decoder Writer's Guide will be available soon. voipong-2.0/docs/src/examples.sgml0100644000175400000000000000731010345254765016277 0ustar muratwheel Example Scenarios You can try VoIPong with Microsoft Netmeeting. Set up netmeeting so that it uses G711 at both ends, and make a voice call. You'll see the calls captured and wave files created after your call finishes. If you do not have a testbed, do not want so much pain to test VoIPong, you can replay a test capture file in your machine and see if it is catched. Replaying a previous capture file Download this test call capture, where me and Baris are talking about EnderUNIX team. Download and install tcpreplay tool. Tcpreplay tool reads pcap capture files, and re-injects the packets into a live network. Start VoIPong 04/12/05 16:27:20: EnderUNIX VOIPONG Voice Over IP Sniffer starting... 04/12/05 16:27:20: Release 2.0-DEVEL running on efe.enderunix.org [FreeBSD 5.4-STABLE FreeBSD 5.4-STABLE #0: Sun Oct 23 16:39:41 EEST 2005 mb@efe.enderunix.org:/usr/src/sys/i386/compile/EFE i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 1075] 04/12/05 16:27:20: Default matching algorithm: lfp 04/12/05 16:27:20: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc) 04/12/05 16:27:20: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0) 04/12/05 16:27:20: loaded 2 module(s) 04/12/05 16:27:20: loadnet(10.30.0.11/255.255.255.255) method: fixed 40000 04/12/05 16:27:20: em0 has been opened in promisc mode. (192.168.1.0/255.255.255.0) Start tcpreplay with the test capture you just downloaded at step 1. [root@efe ~/calls/ok]$ /usr/local/sbin/tcpreplay -i em0 endercall2.pcap sending on: em0 4534 packets (1344595 bytes) sent in 141.44 seconds 9506.2 bytes/sec 0.07 megabits/sec 32 packets/sec You will see that VoIPong immediately starts monitoring your call. Following lines will appear in your voipong.log file: 24/10/05 20:47:23: created a call recording instance! 24/10/05 20:47:23: [68826] VoIP call has been detected. 24/10/05 20:47:23: [68826] 10.0.0.145:49604 < -- > 10.0.0.200:49606 24/10/05 20:47:23: [68826] Encoding 0-PCMU-8KHz, recording....... At the end of the call, you'll see that two .WAV files are created: 24/10/05 20:52:52: [68826] maximum idle time [10 secs] has been elapsed for this call, the call might have been ended. 24/10/05 20:52:52: [68826] .WAV file output/20051204/session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav has been created successfully 24/10/05 20:52:52: [68826] .WAV file output/20051204/session-enc0-PCMU-8KHz-10.0.0.200,49606-10.0.0.145,49604.wav has been created successfully &prompt.root; ls /var/log/output/20051024/ session-enc0-PCMU-8KHz-10.0.0.200,49606-10.0.0.145,49604.wav session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav You can play output files with several utilities including play, xmms etc.: &prompt.root; play /var/log/voipoutput/20051025/session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav Capturing a <trademark>Microsoft</trademark> Netmeeting call Not written yet. voipong-2.0/docs/src/faq.sgml0100644000175400000000000000060410340106526015211 0ustar muratwheel Frequently Asked Questions This is a a non-complete list of questions frequently asked at voipong mailing list. You can have a more recent and updated one within the FAQ at VoIPong web site. voipong-2.0/docs/src/features.sgml0100644000175400000000000000227110344602040016256 0ustar muratwheel Features Simple, optimized, extendable, fast code Easy debugging Easy installation and administration Powerful management console (voipctl) for run-time server administration Detailed logging CSV style CDR (Call Detail Record) logs Dynamic framework for multiple call-catching algorithms to co-exist together Dynamic Shared Object Modules (DSOM) for loading of third party voice codec modules at runtime. Users can choose the best algorithm to suit their networks. Produces audible output (.wav) for G711 (u-law) and G711 (a-law) codecs. Output can be merged into one single file via soxmix. voipong-2.0/docs/src/installation.sgml0100644000175400000000000000656410346322230017154 0ustar muratwheel Installation Before you proceed: Prerequisites You should have pcap library installed beforehand. Please download libpcap from tcpdump.org and install it if you don't have it in your system. Please note that most Operating Systems and Linux distributions provide this library in their default installations. Also, for .WAV file creation, you should have sox and soxmix tools installed. If you don't have those, please download them from sox.sourceforge.net and install it in your system. Compilation & Installation Download the latest VoIPong tarball from EnderUNIX and uncompress it: &prompt.root; tar zxvf voipong-version.tar.gz There are several pre-written Makefile files in the source directory. Examine each of them and choose the one which most suits your system. If you're running of the the BSD type Operating Systems (i.e. FreeBSD, OpenBSD, NetBSD, Mac OSX) copy Makefile.bsd as Makefile; if you're using a Linux distribution then, copy Makefile.linux as Makefile. You might need to change CFLAGS and LDFLAGS variables accordingly: &prompt.root; cp Makefile.bsd Makefile Type make to compile voipong, voipctl and voice decoder modules: &prompt.root; make Type make install to copy compiled binaries, shared modules, configuration files, manual pages and related documentation into the proper locations: &prompt.root; make install Installation via BSD ports system BSD Operating Systems (FreeBSD, NetBSD, OpenBSD, Darwin etc.) has a ports system for easy package administration. VoIPong is a FreeBSD port, so you can install it from FreeBSD ports tree. VoIPong is located in /usr/ports/audio/voipong directory: Change your current working directory to /usr/ports/audio/voipong and type: &prompt.root; cd /usr/ports/audio/voipong &prompt.root; make install clean FreeBSD will fetch the tarball, uncompress it, compile the sources and install VoIPong for you. Alternatively, you can install VoIPong .tbz package with pkg_add (1) command: &prompt.root; fetch \ ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/audio/voipong-2.0.tbz &prompt.root; pkg_add voipong-2.0.tbz voipong-2.0/docs/src/intro.sgml0100644000175400000000000000304710344602040015575 0ustar muratwheel Introduction VoIPong is a sniffer utility which tries to detects Voice Over IP calls on a pipeline, and for those which have vocoder modules loaded, dumps actual conversation to seperate wave files. Currently it can catch calls made via a wide variety of protocols including SIP, H323, Cisco's Skinny Client Protocol. It can also catch calls made through dummy IP adapters which do not do any signalling but transport voice payload via RTP protocol. It's been written in C language for performance reasons, proved to be running on Solaris, Linux and FreeBSD; though it's thought to compile and run on other platforms as well. On a 45 Mbit/sec actual network traffic, it's been verified that VoIPong successfully detected all VoIP gateways and the VoIP calls. CPU utilization during the run has been found ranging between 66% - 80% on a 256MB RAM, Celeron 1700 Mhz Toshiba notebook. With its powerful and extensible Dynamic Shared Object Modules (DSOM) subsystem, and its related API (will be documented later), new third party voice decoder modules can be coded and installed, resulting in a great flexibility. By default, VoIPong comes with two pre-written voice decoder modules for calls encoded with G711 (u-law) and G711 (a-law) . Audible output can be generated for calls encoded with any one of them. voipong-2.0/docs/src/thanks.sgml0100644000175400000000000000037210340106526015734 0ustar muratwheel Thanks Please find a list of people and organizations who contributed or gave support to VoIPong here . voipong-2.0/docs/src/usage.sgml0100644000175400000000000003135710345562447015574 0ustar muratwheel Usage Similar to other sniffer tools at the market, VoIPong needs to get a copy of the voice traffic you're interested in. If you're sharing a hub with one of the endpoints of the voice conversation, you will not need to do anything, since hub devices inherently copy traffic to all its ports. If you are in a switched environment, some network administration will be needed. Most modern switch devices has a handy "monitor port" which you can use for copying traffic going through one or more switch ports. So you'll need to copy one of the endpoints' traffic to that monitor port, and connect the computer on which VoIPong is running. If you're running VoIPong on a gateway machine, where this machine has already access to all the voice traffic, you will not need to do anything. Startup Parameters You can use -h switch to see available startup parameters: [murat@efe ~/voipong]$ ./voipong -h usage: voipong [options] options: -h this screen -v version info -f run in foreground (don't become a daemon) -d debug level. Valid levels are 0 through 4. Default: 0 -c config file path -v switch shows VoIPong version information: [murat@efe ~/voipong]$ ./voipong -v EnderUNIX VOIPONG Voice Over IP Sniffer Release 2.0-DEVEL Copyright (C) 2004 Murat Balaban murat || enderunix.org All rights reserved. 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. For more information on licensing, please see LICENSE file included in the voipong source distribution. [murat@efe ~/voipong]$ You can set the debug log level by -d switch. Valid levels are 0 through 4, latter being the most verbose. Default configuration file is /usr/local/etc/voipong/voipong.conf. You can use alternate configuration file by issuing -c switch and providing full path to the alternate configuration file. If you don't want VoIPong to daemonize, but instead you want it to stay at your terminal and dump log messages to the terminal, you will need to issue -f switch. So, If you want VoIPong to stay at the terminal, and you want to see as many log messages as possible, you should fire VoIPong as such: [root@devel ~]$ voipong -d4 -f EnderUNIX VOIPONG Voice Over IP Sniffer starting... Release 2.0-DEVEL, running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] (c) Murat Balaban http://www.enderunix.org/ 20/11/05 19:33:33: EnderUNIX VOIPONG Voice Over IP Sniffer starting... 20/11/05 19:33:33: Release 2.0-DEVEL running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 23627] 20/11/05 19:33:33: Default matching algorithm: lfp 20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc) 20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0) 20/11/05 19:33:33: loaded 2 module(s) 20/11/05 19:33:33: loadnet(10.0.0.145/255.255.255.255) method: fixed 49604 20/11/05 19:33:33: loadnet(172.16.0.10/255.255.0.0) method: lfp 20/11/05 19:33:33: fxp0 has been opened in promisc mode. (43.43.43.0/255.255.255.192) Management Console: voipctl VoIPong provides the user with the ability to administer the server at runtime. You can use voipctl command for this purpose. When fired, voipctl will connect VoIPong and will wait for user's commands: [root@efe ~/voipong]$ voipctl Connected to VoIPong Management Console System: efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] voipong> help is the same old "help": voipong> help Commands: help : this one quit : quit management console uptime : Server uptime setdebug [level] : set debug level to [level] logrotate : rotate server's logs shutdown : shutdown server rusage : CPU usage statistics for the server loadnets : Reload voipongnets file info : General server information shcall : Show currently monitored calls shrtcp : Show currently RTCP cache killcall [id] : end monitoring session with [id] voipong> uptime shows how long the server has been running: voipong> uptime Server uptime: 5 minutes 57 seconds voipong> !!: You can use !! command to issue the last command you typed. (same as in sh): voipong> !! Server uptime: 6 minutes 13 seconds voipong> logrotate command rotates server logs: voipong> logrotate Logrotate successfull voipong> shutdown command will shutdown the server and close management console connection voipong> shutdown rusage command will give information related to server's CPU utilization voipong> rusage Current CPU usage stats: ---------------------------------------- Total "user" time : 0 seconds Total used "system" time : 0 seconds Shared Memory Size : 384 KB Integral Memory Size : 1512 KB Integral stack Size : 1024 KB Page requests : 70 Page errors : 0 Block input operations : 0 Block output operations : 2 Messages sent : 1 Messages received : 1 Signals : 0 Voluntary "context switch"s : 78 Involuntary "context switch"s : 1 voipong> loadnets command will re-read voipongnets and re-load network/algorithms mapping table voipong> loadnets Networks file has been reloaded successfuly voipong> info command will give general server information voipong> info General Server Info: --------------------------: Server version : Release 2.0-DEVEL System : efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] Current work. direct. : /usr/home/murat/voipong Log level : 4 Process ID (PID) : 16240 User : root [Charlie &] Group : 0 voipong> setdebug command will change runtime log verbosity voipong> setdebug 4 # set new debug level to 4 voipong> shcall command will list calls currently monitored voipong> shcall ID NODE1 PORT1 NODE2 PORT2 STIME DURATION ----- ---------------- ----- ---------------- ----- ----------------- ------------ 01123 41.27.13.1 12000 31.12.11.8 24000 24/10/05 11:11:23 33 seconds Total listed: 1 voipong> shrtcp command will show current RTCP cache voipong> shrtcp ID NODE1 PORT1 NODE2 PORT2 STIME ----- ---------------- ----- ---------------- ----- ----------------- 01123 41.27.13.1 12001 31.12.11.8 24001 24/10/05 11:11:23 Total listed: 1 voipong> killcall will end monitoring the call by id voipong> killcall 2 transport_simplecmd: server returned error: No such session by ID: 2 cannot process killcall command voipong> q, quit, exit commands will end management session voipong> q Bye! [root@efe /home/murat/voipong]$ Running VoIPong with a non-privileged user It is strongly advised that you avoid running VoIPong with super-user, but use a non-privileged special user created only for it. This section describes the steps you should take to accomplish this. Note that these steps should be done after you compiled and installed VoIPong successfully. Create voipong user and group &prompt.root; pw group add voipong &prompt.root; pw user add voipong -g voipong -m -s /usr/local/bin/bash Change ownership of voipong, voipctl and /usr/local/etc/voipong directory to voipong user: &prompt.root; chown voipong /usr/local/bin/voipong &prompt.root; chown voipong /usr/local/bin/voipctl &prompt.root; chown -R voipong /usr/local/etc/voipong &prompt.root; chgrp -R voipong /usr/local/etc/voipong Change ownership of BPF device files (/dev/bpf*) to voipong user: &prompt.root; chown voipong /dev/bpf* Switch user to voipong: &prompt.root; su - voipong To see all of the directories on your FreeBSD system, type ls -R / | more -- Dru genesis@istar.ca &prompt.user; Create runtime directories: &prompt.user; mkdir logs &prompt.user; mkdir output &prompt.user; mkdir run Change log, pid and output directory paths to the new directories in voipong.conf logdir = /home/voipong/logs/ logfile = voipong.log outdir = /home/voipong/output/ cdrfile = /home/voipong/output/voipcdr.log pidfile = /home/voipong/run/voipong.pid mgmt_ipcpath = /home/voipong/run/voipongmgmt.sock You can now run voipong &prompt.user; id uid=1042(voipong) gid=1042(voipong) groups=1042(voipong) &prompt.user; voipong -d4 -f EnderUNIX VOIPONG Voice Over IP Sniffer starting... Release 2.0-DEVEL, running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] (c) Murat Balaban http://www.enderunix.org/ 20/11/05 22:34:03: EnderUNIX VOIPONG Voice Over IP Sniffer starting... 20/11/05 22:34:03: Release 2.0-DEVEL running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 41334] 20/11/05 22:34:03: Default matching algorithm: lfp 20/11/05 22:34:03: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc) 20/11/05 22:34:03: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0) 20/11/05 22:34:03: loaded 2 module(s) 20/11/05 22:34:03: loadnet(10.0.0.145/255.255.255.255) method: fixed 49604 20/11/05 22:34:03: loadnet(172.16.0.10/255.255.0.0) method: lfp 20/11/05 22:34:03: fxp0 has been opened in promisc mode. (43.43.43.0/255.255.255.128) You can check whether the daemon is running with the correct user with voipctl &prompt.user; id uid=1042(voipong) gid=1042(voipong) groups=1042(voipong) &prompt.user; voipctl Connected to VoIPong Management Console System: devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] voipong> info General Server Info: --------------------------: Server version : Release 2.0-DEVEL System : devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386] Current work. direct. : /usr/home/voipong Log level : 4 Mix Voice Flag : true Process ID (PID) : 41334 User : voipong [VoIPong Kullanicisi] Group : 1042 voipong> VoIPong Live CD Omer Faruk Sen has maintains VoIPong LiveCD! based on FreeSBIE project. LiveCD is an ISO image which can be burnt into a blank CD directly, and includes pre-installed VoIPong release along with several boot-time scripts for configuring the OS and VoIPong. Please find the gzip'ed ISO images here: Version 2.0 MD5: 2458d372b0113771eb642987ce0b2f43 voipong-2.0/docs/users-manual/0040755000175400000000000000000010346322276015416 5ustar muratwheelvoipong-2.0/docs/users-manual/CVS/0040755000175400000000000000000010346320213016036 5ustar muratwheelvoipong-2.0/docs/users-manual/CVS/Root0100644000175400000000000000001310346320213016673 0ustar muratwheel/cvsup/cvs voipong-2.0/docs/users-manual/CVS/Repository0100644000175400000000000000003210346320213020130 0ustar muratwheelvoipong/docs/users-manual voipong-2.0/docs/users-manual/CVS/Entries0100644000175400000000000000000210346320213017357 0ustar muratwheelD voipong-2.0/docs/users-manual/index.html0100444000175400000000000001024210346322276017405 0ustar muratwheel VoIPong User's Manual

VoIPong User's Manual

Murat Balaban


Table of Contents
1. Introduction
2. Features
3. Installation
3.1. Before you proceed: Prerequisites
3.2. Compilation & Installation
3.3. Installation via BSD ports system
4. Dynamic Shared Object Modules (DSOM)
5. Configuration
5.1. Configuration file: voipong.conf
5.1.1. GENERAL section
5.1.2. FILTERS section
5.2. Network - Algorithm mappings: voipongnets
5.2.1. Least False Positive (LFP) algorithm
5.2.2. Fixed (Fixed Port) algorithm
5.2.3. LRA-SIP Algorithm
6. Usage
6.1. Startup Parameters
6.2. Management Console: voipctl
6.3. Running VoIPong with a non-privileged user
6.4. VoIPong Live CD
7. Example Scenarios
7.1. Replaying a previous capture file
7.2. Capturing a Microsoft™ Netmeeting call
8. Frequently Asked Questions
9. Thanks
voipong-2.0/docs/users-manual/intro.html0100444000175400000000000000717310346322276017442 0ustar muratwheel Introduction

Chapter 1. Introduction

VoIPong is a sniffer utility which tries to detects Voice Over IP calls on a pipeline, and for those which have vocoder modules loaded, dumps actual conversation to seperate wave files. Currently it can catch calls made via a wide variety of protocols including SIP, H323, Cisco's Skinny Client Protocol. It can also catch calls made through dummy IP adapters which do not do any signalling but transport voice payload via RTP protocol.

It's been written in C language for performance reasons, proved to be running on Solaris, Linux and FreeBSD; though it's thought to compile and run on other platforms as well.

On a 45 Mbit/sec actual network traffic, it's been verified that VoIPong successfully detected all VoIP gateways and the VoIP calls. CPU utilization during the run has been found ranging between 66% - 80% on a 256MB RAM, Celeron 1700 Mhz Toshiba notebook.

With its powerful and extensible Dynamic Shared Object Modules (DSOM) subsystem, and its related API (will be documented later), new third party voice decoder modules can be coded and installed, resulting in a great flexibility. By default, VoIPong comes with two pre-written voice decoder modules for calls encoded with G711 (u-law) and G711 (a-law) . Audible output can be generated for calls encoded with any one of them.

voipong-2.0/docs/users-manual/features.html0100444000175400000000000000563010346322276020121 0ustar muratwheel Features

Chapter 2. Features

voipong-2.0/docs/users-manual/installation.html0100444000175400000000000000623310346322276021004 0ustar muratwheel Installation

Chapter 3. Installation

Table of Contents
3.1. Before you proceed: Prerequisites
3.2. Compilation & Installation
3.3. Installation via BSD ports system

3.1. Before you proceed: Prerequisites

You should have pcap library installed beforehand. Please download libpcap from tcpdump.org and install it if you don't have it in your system. Please note that most Operating Systems and Linux distributions provide this library in their default installations.

Also, for .WAV file creation, you should have sox and soxmix tools installed. If you don't have those, please download them from sox.sourceforge.net and install it in your system.

voipong-2.0/docs/users-manual/compilation.html0100444000175400000000000000747210346322276020627 0ustar muratwheel Compilation & Installation

3.2. Compilation & Installation

Download the latest VoIPong tarball from EnderUNIX and uncompress it:

# tar zxvf voipong-version.tar.gz
There are several pre-written Makefile files in the source directory. Examine each of them and choose the one which most suits your system. If you're running of the the BSD type Operating Systems (i.e. FreeBSD, OpenBSD, NetBSD, Mac OSX) copy Makefile.bsd as Makefile; if you're using a Linux distribution then, copy Makefile.linux as Makefile. You might need to change CFLAGS and LDFLAGS variables accordingly:
# cp Makefile.bsd Makefile
Type make to compile voipong, voipctl and voice decoder modules:
# make
Type make install to copy compiled binaries, shared modules, configuration files, manual pages and related documentation into the proper locations:
# make install 


voipong-2.0/docs/users-manual/installports.html0100444000175400000000000000666310346322276021050 0ustar muratwheel Installation via BSD ports system

3.3. Installation via BSD ports system

BSD Operating Systems (FreeBSD, NetBSD, OpenBSD, Darwin etc.) has a ports system for easy package administration. VoIPong is a FreeBSD port, so you can install it from FreeBSD ports tree. VoIPong is located in /usr/ports/audio/voipong directory:

Change your current working directory to /usr/ports/audio/voipong and type:

# cd /usr/ports/audio/voipong
# make install clean
FreeBSD will fetch the tarball, uncompress it, compile the sources and install VoIPong for you.

Alternatively, you can install VoIPong .tbz package with pkg_add (1) command:

# fetch \ 
        ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/audio/voipong-2.0.tbz
# pkg_add voipong-2.0.tbz


voipong-2.0/docs/users-manual/dsom.html0100444000175400000000000001004010346322276017234 0ustar muratwheel Dynamic Shared Object Modules (DSOM)

Chapter 4. Dynamic Shared Object Modules (DSOM)

Since release 2.0 upwards, VoIPong provides a powerful dynamic framework for loading of 3rd party voice decoders into the running voipong executable at runtime. This is called Dynamic Shared Object Modules (DSOM) Framework. Simply put, DSOM vocoder modules are shared libraries with the .so extension. VoIPong looks for those shared libraries in the preconfigured modpath directory, loads them one by one. DSOM engine resident at VoIPong core, spots the initialization method in the shared module and invokes it allowing the module to register itself inside VoIPong runtime environment:

07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2813e370)
07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x28140390)
07/12/05 13:29:25: loaded 2 module(s)


For security reasons, the DSOMs are expected to be owned by the same user and group who is running the core VoIPong executable. For instance, if the user running the program has uid 1000 and gid 10; the modules should also be owned by uid 1000 and gid 10.

The naming convention is that the modules should start with the modvocoder_ keyword, and should include the name of the decoder in the module, followed by the .so extension. For example, the correct name for the g711 (u-law) module can be modvocoder_pcmu.so.

There are two pre-written voice decoder modules with VoIPong release 2.0:



To code and install your own vocoder module (i.e. for g726), VoIPong DSOM Decoder Writer's Guide will be available soon.

voipong-2.0/docs/users-manual/config.html0100444000175400000000000001556110346322276017554 0ustar muratwheel Configuration

Chapter 5. Configuration

Table of Contents
5.1. Configuration file: voipong.conf
5.2. Network - Algorithm mappings: voipongnets

Configuration files are all installed into VoIPong directory: /usr/local/etc/voipong. Main configuration parameters are included in voipong.conf file. voipongnets file maps network addresses to their proper algorithms. DSOM modules for g711-ulaw and g711-alaw (modvocoder_pcmu.so, modvocoder_pcma.so) are installed to the path given with the modpath configuration file directive.

5.1. Configuration file: voipong.conf

Runtime configuration parameters vital to the smoothly operation of VoIPong server are defined in voipong.conf, formatted as a standart .ini file. There are two sections: GENERAL for general server settings, and FILTERS for setting up startup filters.

5.1.1. GENERAL section

  • logdir: specifies the log directory where voipong will save its logs e.g. /var/log

  • logfile: name of the main server log file e.g. voipong.log

  • outdir: path where output .WAV and/or .RAW files are to be written. e.g. /var/log/voipoutput

  • cdrfile: name of the CDR (Common Data Record) log file e.g. cdr.log

  • networksfile: path to the network/algorithm mappings file e.g. /usr/local/etc/voipong/voipongnets

  • pidfile: path to the pidfile e.g. /var/run/voipong.pid

  • soxpath: path to the sox executable e.g. /usr/local/bin/sox

  • modpath: path to the directory where vocoder DSOM modules are installed. e.g. /usr/local/etc/voipong/modules

  • soxmixpath: path to the soxmix executable e.g. /usr/local/bin/soxmix

  • mgmt_ipcpath: path to the UNIX domain socket for management console e.g. /tmp/voipongmgmt.sock

  • defalg: Default packet matching algorithm. This can currently only be lfp. Other algorithms are to be developed. e.g. lfp

  • rtp_idle_time: (in seconds) when this amount of time elapses and no RTP traffic is received for the call, the call is considered to be finished. e.g. 10

  • device: network device to sniff packets from e.g. eth0

  • promisc: set this to true 1 if you want VoIpong to set your sniffing device to promiscious mode. e.g. set this to 1 for true, 0 for false.

  • mixwaves: set this to true 1 if you want VoIPong to mix the seperate .WAV files into a single .WAV file. e.g. set this to 1 for true, 0 for false.

  • snaplen: maximum number of bytes to capture e.g. 1500

  • readtmt: specifies the read-from-device timeout in milliseconds. e.g. 500

5.1.2. FILTERS section

  • startup: Pcap filter string. This filter will be set during startup procedures. To see detailed usage of pcap filters, see pcap(3) manual page. e.g. "udp"

voipong-2.0/docs/users-manual/config-netfile.html0100444000175400000000000001240310346322276021170 0ustar muratwheel Network - Algorithm mappings: voipongnets

5.2. Network - Algorithm mappings: voipongnets

Sniffing out voice is a tough task. You cannot design an algorithm and expect to catch all the VoIP calls. VoIP is relatively new and it is not a highly standardized technology. So there have to be several call catching algorithms for various setups. VoIPong provides a framework where you can set the call catching algorithm which you think will best suit your VoIP infrastructure. This results in a much more specialized and successful call sniffing.

5.2.1. Least False Positive (LFP) algorithm

This algorithm tries to detect calls generated via VoIP devices conforming to RTP and RTCP RFCs. This algorithm should detect and record a broad range of calls. The most obvious advantage of this algorithm is that you'll have barely no false positives. This is why this method is named as LFP. The #1 disadvantage will be that this will not be able to catch calls if there are no RTCP packets or the devices do not conform to RFCs. To use this algorithm, you will need to specify a network to use with it in your voipongnets file.

172.16.1.0/255.255.255.0   lfp
10.30.0.0/255.255.252.0    lfp


5.2.2. Fixed (Fixed Port) algorithm

Some VoIP devices (e.g. Grandstream(TM) IP adapters) use a fixed port to send and receive RTP datagrams, and they do not conform to RFCs, and do not send any link control information (RTCP packets). If you have such devices in your network, you can specify their algorithm as fixed in the voipongnets file. This algorithm cannot be used with networks, it can only be used with hosts, so netmask address should always be 255.255.255.255. Please note that, after the fixed keyword, you are expected to set the fixed port number the device is using. For example, suppose that you have a device which uses port 40000 to send RTP packets, you should add this line to your voipongnets file:

172.16.1.101/255.255.255.255   fixed   40000


5.2.3. LRA-SIP Algorithm

LRA-SIP will follow SIP signalling packets, and will spot the RTP/RTCP session from the SDP packets. This algorithm is not implemented yet, however I will be working on it for the next release (probably 2.1.?)

voipong-2.0/docs/users-manual/usage.html0100444000175400000000000001450210346322276017405 0ustar muratwheel Usage

Chapter 6. Usage

Table of Contents
6.1. Startup Parameters
6.2. Management Console: voipctl
6.3. Running VoIPong with a non-privileged user
6.4. VoIPong Live CD

Similar to other sniffer tools at the market, VoIPong needs to get a copy of the voice traffic you're interested in. If you're sharing a hub with one of the endpoints of the voice conversation, you will not need to do anything, since hub devices inherently copy traffic to all its ports. If you are in a switched environment, some network administration will be needed. Most modern switch devices has a handy "monitor port" which you can use for copying traffic going through one or more switch ports. So you'll need to copy one of the endpoints' traffic to that monitor port, and connect the computer on which VoIPong is running. If you're running VoIPong on a gateway machine, where this machine has already access to all the voice traffic, you will not need to do anything.

6.1. Startup Parameters

You can use -h switch to see available startup parameters:

[murat@efe ~/voipong]$ ./voipong -h
usage: voipong [options]
options:
-h this screen
-v version info
-f run in foreground (don't become a daemon)
-d debug level. Valid levels are 0 through 4. Default: 0
-c config file path
-v switch shows VoIPong version information:
[murat@efe ~/voipong]$ ./voipong -v
EnderUNIX VOIPONG Voice Over IP Sniffer Release 2.0-DEVEL
Copyright (C) 2004 Murat Balaban murat || enderunix.org
All rights reserved.
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.
For more information on licensing, please see LICENSE
file included in the voipong source distribution.
[murat@efe ~/voipong]$ 
You can set the debug log level by -d switch. Valid levels are 0 through 4, latter being the most verbose. Default configuration file is /usr/local/etc/voipong/voipong.conf. You can use alternate configuration file by issuing -c switch and providing full path to the alternate configuration file. If you don't want VoIPong to daemonize, but instead you want it to stay at your terminal and dump log messages to the terminal, you will need to issue -f switch.

So, If you want VoIPong to stay at the terminal, and you want to see as many log messages as possible, you should fire VoIPong as such:

[root@devel ~]$ voipong -d4 -f
EnderUNIX VOIPONG Voice Over IP Sniffer starting...
Release 2.0-DEVEL, running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
(c) Murat Balaban http://www.enderunix.org/
20/11/05 19:33:33: EnderUNIX VOIPONG Voice Over IP Sniffer starting...
20/11/05 19:33:33: Release 2.0-DEVEL running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 23627]
20/11/05 19:33:33: Default matching algorithm: lfp
20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc)
20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0)
20/11/05 19:33:33: loaded 2 module(s)
20/11/05 19:33:33: loadnet(10.0.0.145/255.255.255.255) method: fixed 49604
20/11/05 19:33:33: loadnet(172.16.0.10/255.255.0.0) method: lfp 
20/11/05 19:33:33: fxp0 has been opened in  promisc mode. (43.43.43.0/255.255.255.192)


voipong-2.0/docs/users-manual/usage-voipctl.html0100444000175400000000000001474510346322276021074 0ustar muratwheel Management Console: voipctl

6.2. Management Console: voipctl

VoIPong provides the user with the ability to administer the server at runtime. You can use voipctl command for this purpose. When fired, voipctl will connect VoIPong and will wait for user's commands:

[root@efe ~/voipong]$ voipctl 
Connected to VoIPong Management Console
System:
efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
voipong> 
help is the same old "help":
voipong> help
Commands:
help : this one
quit : quit management console
uptime : Server uptime
setdebug [level] : set debug level to [level]
logrotate : rotate server's logs
shutdown : shutdown server
rusage : CPU usage statistics for the server
loadnets : Reload voipongnets file
info : General server information
shcall : Show currently monitored calls
shrtcp : Show currently RTCP cache
killcall [id] : end monitoring session with [id]
voipong> 
uptime shows how long the server has been running:
voipong> uptime
Server uptime: 5 minutes 57 seconds
voipong>
!!: You can use !! command to issue the last command you typed. (same as in sh):
voipong> !!
Server uptime: 6 minutes 13 seconds
voipong>
logrotate command rotates server logs:
voipong> logrotate
Logrotate successfull
voipong>
shutdown command will shutdown the server and close management console connection
voipong> shutdown
rusage command will give information related to server's CPU utilization
voipong> rusage
Current CPU usage stats:
----------------------------------------
Total "user" time : 0 seconds
Total used "system" time : 0 seconds
Shared Memory Size : 384 KB
Integral Memory Size : 1512 KB
Integral stack Size : 1024 KB
Page requests : 70
Page errors : 0
Block input operations : 0
Block output operations : 2
Messages sent : 1
Messages received : 1
Signals : 0
Voluntary "context switch"s : 78
Involuntary "context switch"s : 1
voipong> 
loadnets command will re-read voipongnets and re-load network/algorithms mapping table
voipong> loadnets
Networks file has been reloaded successfuly
voipong>
info command will give general server information
voipong> info
General Server Info:
--------------------------:
Server version : Release 2.0-DEVEL
System : efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
Current work. direct. : /usr/home/murat/voipong
Log level : 4
Process ID (PID) : 16240
User : root [Charlie &]
Group : 0
voipong> 
setdebug command will change runtime log verbosity
voipong> setdebug 4
# set new debug level to 4
voipong>
shcall command will list calls currently monitored
voipong> shcall
ID    NODE1            PORT1 NODE2            PORT2 STIME             DURATION 
----- ---------------- ----- ---------------- ----- ----------------- ------------
01123 41.27.13.1       12000 31.12.11.8       24000 24/10/05 11:11:23 33 seconds
Total listed: 1
voipong> 
shrtcp command will show current RTCP cache
voipong> shrtcp
ID    NODE1            PORT1 NODE2            PORT2 STIME            
----- ---------------- ----- ---------------- ----- -----------------
01123 41.27.13.1       12001 31.12.11.8       24001 24/10/05 11:11:23
Total listed: 1
voipong>
killcall will end monitoring the call by id
voipong> killcall 2
transport_simplecmd: server returned error: No such session by ID: 2
cannot process killcall command
voipong> 
q, quit, exit commands will end management session
voipong> q
Bye!
[root@efe /home/murat/voipong]$ 


voipong-2.0/docs/users-manual/usage-nonpriv.html0100444000175400000000000001566310346322276021107 0ustar muratwheel Running VoIPong with a non-privileged user

6.3. Running VoIPong with a non-privileged user

It is strongly advised that you avoid running VoIPong with super-user, but use a non-privileged special user created only for it. This section describes the steps you should take to accomplish this. Note that these steps should be done after you compiled and installed VoIPong successfully.

voipong-2.0/docs/users-manual/usage-livecd.html0100444000175400000000000000526710346322276020661 0ustar muratwheel VoIPong Live CD

6.4. VoIPong Live CD

Omer Faruk Sen has maintains VoIPong LiveCD! based on FreeSBIE project. LiveCD is an ISO image which can be burnt into a blank CD directly, and includes pre-installed VoIPong release along with several boot-time scripts for configuring the OS and VoIPong.

Please find the gzip'ed ISO images here:

voipong-2.0/docs/users-manual/examples.html0100444000175400000000000001374310346322276020125 0ustar muratwheel Example Scenarios

Chapter 7. Example Scenarios

Table of Contents
7.1. Replaying a previous capture file
7.2. Capturing a Microsoft™ Netmeeting call

You can try VoIPong with Microsoft Netmeeting. Set up netmeeting so that it uses G711 at both ends, and make a voice call. You'll see the calls captured and wave files created after your call finishes.

If you do not have a testbed, do not want so much pain to test VoIPong, you can replay a test capture file in your machine and see if it is catched.

7.1. Replaying a previous capture file

voipong-2.0/docs/users-manual/examples-msnetmeeting.html0100444000175400000000000000446710346322276022625 0ustar muratwheel Capturing a Microsoft Netmeeting call

7.2. Capturing a Microsoft™ Netmeeting call

Not written yet.

voipong-2.0/docs/users-manual/faq.html0100444000175400000000000000470710346322276017056 0ustar muratwheel Frequently Asked Questions

Chapter 8. Frequently Asked Questions

This is a a non-complete list of questions frequently asked at voipong mailing list. You can have a more recent and updated one within the FAQ at VoIPong web site.

voipong-2.0/docs/users-manual/thanks.html0100444000175400000000000000406210346322276017571 0ustar muratwheel Thanks

Chapter 9. Thanks

Please find a list of people and organizations who contributed or gave support to VoIPong here .

voipong-2.0/docs/users-manual/docbook.css0100444000175400000000000000563310346322276017552 0ustar muratwheel/* * Copyright (c) 2001, 2003 The FreeBSD Documentation Project * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, 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. * * $FreeBSD: doc/share/misc/docbook.css,v 1.7 2004/03/22 19:17:52 ceri Exp $ */ BODY ADDRESS { line-height: 1.3; margin: .6em 0; } BODY BLOCKQUOTE { margin-top: .75em; line-height: 1.5; margin-bottom: .75em; } HTML BODY { margin: 1em 8% 1em 10%; line-height: 1.2; } .LEGALNOTICE { font-size: small; font-variant: small-caps; } BODY DIV { margin: 0; } DL { margin: .8em 0; line-height: 1.2; } BODY FORM { margin: .6em 0; } H1, H2, H3, H4, H5, H6, DIV.EXAMPLE P B, .QUESTION, DIV.TABLE P B, DIV.PROCEDURE P B { color: #990000; } BODY H1 { margin: .8em 0 0 -4%; line-height: 1.3; } BODY H2 { margin: .8em 0 0 -4%; line-height: 1.3; } BODY H3 { margin: .8em 0 0 -3%; line-height: 1.3; } BODY H4 { margin: .8em 0 0 -3%; line-height: 1.3; } BODY H5 { margin: .8em 0 0 -2%; line-height: 1.3; } BODY H6 { margin: .8em 0 0 -1%; line-height: 1.3; } BODY HR { margin: .6em } BODY IMG.NAVHEADER { margin: 0 0 0 -4%; } OL { margin: 0 0 0 5%; line-height: 1.2; } BODY PRE { margin: .75em 0; line-height: 1.0; color: #461b7e; } BODY TD { line-height: 1.2 } BODY TH { line-height: 1.2; } UL, BODY DIR, BODY MENU { margin: 0 0 0 5%; line-height: 1.2; } HTML { margin: 0; padding: 0; } .FILENAME { color: #007a00; } BODY H1, BODY H2, BODY H3, BODY H4, BODY H5, BODY H6 { margin-left: 0 } .GUIMENU, .GUIMENUITEM, .GUISUBMENU, .GUILABEL, .INTERFACE, .GUIBUTTON, .SHORTCUT, .SHORTCUT .KEYCAP { background-color: #F0F0F0; } .ACCEL { background-color: #F0F0F0; text-decoration: underline; } .PROGRAMLISTING, .SCREEN { margin-left: 3ex; } voipong-2.0/docs/users-manual/book.html0100444000175400000000000011424510346322276017240 0ustar muratwheel VoIPong User's Manual

VoIPong User's Manual

Murat Balaban


Table of Contents
1. Introduction
2. Features
3. Installation
3.1. Before you proceed: Prerequisites
3.2. Compilation & Installation
3.3. Installation via BSD ports system
4. Dynamic Shared Object Modules (DSOM)
5. Configuration
5.1. Configuration file: voipong.conf
5.1.1. GENERAL section
5.1.2. FILTERS section
5.2. Network - Algorithm mappings: voipongnets
5.2.1. Least False Positive (LFP) algorithm
5.2.2. Fixed (Fixed Port) algorithm
5.2.3. LRA-SIP Algorithm
6. Usage
6.1. Startup Parameters
6.2. Management Console: voipctl
6.3. Running VoIPong with a non-privileged user
6.4. VoIPong Live CD
7. Example Scenarios
7.1. Replaying a previous capture file
7.2. Capturing a Microsoft™ Netmeeting call
8. Frequently Asked Questions
9. Thanks

Chapter 1. Introduction

VoIPong is a sniffer utility which tries to detects Voice Over IP calls on a pipeline, and for those which have vocoder modules loaded, dumps actual conversation to seperate wave files. Currently it can catch calls made via a wide variety of protocols including SIP, H323, Cisco's Skinny Client Protocol. It can also catch calls made through dummy IP adapters which do not do any signalling but transport voice payload via RTP protocol.

It's been written in C language for performance reasons, proved to be running on Solaris, Linux and FreeBSD; though it's thought to compile and run on other platforms as well.

On a 45 Mbit/sec actual network traffic, it's been verified that VoIPong successfully detected all VoIP gateways and the VoIP calls. CPU utilization during the run has been found ranging between 66% - 80% on a 256MB RAM, Celeron 1700 Mhz Toshiba notebook.

With its powerful and extensible Dynamic Shared Object Modules (DSOM) subsystem, and its related API (will be documented later), new third party voice decoder modules can be coded and installed, resulting in a great flexibility. By default, VoIPong comes with two pre-written voice decoder modules for calls encoded with G711 (u-law) and G711 (a-law) . Audible output can be generated for calls encoded with any one of them.


Chapter 2. Features


Chapter 3. Installation

3.1. Before you proceed: Prerequisites

You should have pcap library installed beforehand. Please download libpcap from tcpdump.org and install it if you don't have it in your system. Please note that most Operating Systems and Linux distributions provide this library in their default installations.

Also, for .WAV file creation, you should have sox and soxmix tools installed. If you don't have those, please download them from sox.sourceforge.net and install it in your system.


3.2. Compilation & Installation

Download the latest VoIPong tarball from EnderUNIX and uncompress it:

# tar zxvf voipong-version.tar.gz
There are several pre-written Makefile files in the source directory. Examine each of them and choose the one which most suits your system. If you're running of the the BSD type Operating Systems (i.e. FreeBSD, OpenBSD, NetBSD, Mac OSX) copy Makefile.bsd as Makefile; if you're using a Linux distribution then, copy Makefile.linux as Makefile. You might need to change CFLAGS and LDFLAGS variables accordingly:
# cp Makefile.bsd Makefile
Type make to compile voipong, voipctl and voice decoder modules:
# make
Type make install to copy compiled binaries, shared modules, configuration files, manual pages and related documentation into the proper locations:
# make install 



3.3. Installation via BSD ports system

BSD Operating Systems (FreeBSD, NetBSD, OpenBSD, Darwin etc.) has a ports system for easy package administration. VoIPong is a FreeBSD port, so you can install it from FreeBSD ports tree. VoIPong is located in /usr/ports/audio/voipong directory:

Change your current working directory to /usr/ports/audio/voipong and type:

# cd /usr/ports/audio/voipong
# make install clean
FreeBSD will fetch the tarball, uncompress it, compile the sources and install VoIPong for you.

Alternatively, you can install VoIPong .tbz package with pkg_add (1) command:

# fetch \ 
        ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.4-RELEASE/packages/audio/voipong-2.0.tbz
# pkg_add voipong-2.0.tbz



Chapter 4. Dynamic Shared Object Modules (DSOM)

Since release 2.0 upwards, VoIPong provides a powerful dynamic framework for loading of 3rd party voice decoders into the running voipong executable at runtime. This is called Dynamic Shared Object Modules (DSOM) Framework. Simply put, DSOM vocoder modules are shared libraries with the .so extension. VoIPong looks for those shared libraries in the preconfigured modpath directory, loads them one by one. DSOM engine resident at VoIPong core, spots the initialization method in the shared module and invokes it allowing the module to register itself inside VoIPong runtime environment:

07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2813e370)
07/12/05 13:29:25: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x28140390)
07/12/05 13:29:25: loaded 2 module(s)


For security reasons, the DSOMs are expected to be owned by the same user and group who is running the core VoIPong executable. For instance, if the user running the program has uid 1000 and gid 10; the modules should also be owned by uid 1000 and gid 10.

The naming convention is that the modules should start with the modvocoder_ keyword, and should include the name of the decoder in the module, followed by the .so extension. For example, the correct name for the g711 (u-law) module can be modvocoder_pcmu.so.

There are two pre-written voice decoder modules with VoIPong release 2.0:



To code and install your own vocoder module (i.e. for g726), VoIPong DSOM Decoder Writer's Guide will be available soon.


Chapter 5. Configuration

Configuration files are all installed into VoIPong directory: /usr/local/etc/voipong. Main configuration parameters are included in voipong.conf file. voipongnets file maps network addresses to their proper algorithms. DSOM modules for g711-ulaw and g711-alaw (modvocoder_pcmu.so, modvocoder_pcma.so) are installed to the path given with the modpath configuration file directive.


5.1. Configuration file: voipong.conf

Runtime configuration parameters vital to the smoothly operation of VoIPong server are defined in voipong.conf, formatted as a standart .ini file. There are two sections: GENERAL for general server settings, and FILTERS for setting up startup filters.


5.1.1. GENERAL section

  • logdir: specifies the log directory where voipong will save its logs e.g. /var/log

  • logfile: name of the main server log file e.g. voipong.log

  • outdir: path where output .WAV and/or .RAW files are to be written. e.g. /var/log/voipoutput

  • cdrfile: name of the CDR (Common Data Record) log file e.g. cdr.log

  • networksfile: path to the network/algorithm mappings file e.g. /usr/local/etc/voipong/voipongnets

  • pidfile: path to the pidfile e.g. /var/run/voipong.pid

  • soxpath: path to the sox executable e.g. /usr/local/bin/sox

  • modpath: path to the directory where vocoder DSOM modules are installed. e.g. /usr/local/etc/voipong/modules

  • soxmixpath: path to the soxmix executable e.g. /usr/local/bin/soxmix

  • mgmt_ipcpath: path to the UNIX domain socket for management console e.g. /tmp/voipongmgmt.sock

  • defalg: Default packet matching algorithm. This can currently only be lfp. Other algorithms are to be developed. e.g. lfp

  • rtp_idle_time: (in seconds) when this amount of time elapses and no RTP traffic is received for the call, the call is considered to be finished. e.g. 10

  • device: network device to sniff packets from e.g. eth0

  • promisc: set this to true 1 if you want VoIpong to set your sniffing device to promiscious mode. e.g. set this to 1 for true, 0 for false.

  • mixwaves: set this to true 1 if you want VoIPong to mix the seperate .WAV files into a single .WAV file. e.g. set this to 1 for true, 0 for false.

  • snaplen: maximum number of bytes to capture e.g. 1500

  • readtmt: specifies the read-from-device timeout in milliseconds. e.g. 500


5.1.2. FILTERS section

  • startup: Pcap filter string. This filter will be set during startup procedures. To see detailed usage of pcap filters, see pcap(3) manual page. e.g. "udp"


5.2. Network - Algorithm mappings: voipongnets

Sniffing out voice is a tough task. You cannot design an algorithm and expect to catch all the VoIP calls. VoIP is relatively new and it is not a highly standardized technology. So there have to be several call catching algorithms for various setups. VoIPong provides a framework where you can set the call catching algorithm which you think will best suit your VoIP infrastructure. This results in a much more specialized and successful call sniffing.


5.2.1. Least False Positive (LFP) algorithm

This algorithm tries to detect calls generated via VoIP devices conforming to RTP and RTCP RFCs. This algorithm should detect and record a broad range of calls. The most obvious advantage of this algorithm is that you'll have barely no false positives. This is why this method is named as LFP. The #1 disadvantage will be that this will not be able to catch calls if there are no RTCP packets or the devices do not conform to RFCs. To use this algorithm, you will need to specify a network to use with it in your voipongnets file.

172.16.1.0/255.255.255.0   lfp
10.30.0.0/255.255.252.0    lfp



5.2.2. Fixed (Fixed Port) algorithm

Some VoIP devices (e.g. Grandstream(TM) IP adapters) use a fixed port to send and receive RTP datagrams, and they do not conform to RFCs, and do not send any link control information (RTCP packets). If you have such devices in your network, you can specify their algorithm as fixed in the voipongnets file. This algorithm cannot be used with networks, it can only be used with hosts, so netmask address should always be 255.255.255.255. Please note that, after the fixed keyword, you are expected to set the fixed port number the device is using. For example, suppose that you have a device which uses port 40000 to send RTP packets, you should add this line to your voipongnets file:

172.16.1.101/255.255.255.255   fixed   40000



5.2.3. LRA-SIP Algorithm

LRA-SIP will follow SIP signalling packets, and will spot the RTP/RTCP session from the SDP packets. This algorithm is not implemented yet, however I will be working on it for the next release (probably 2.1.?)


Chapter 6. Usage

Similar to other sniffer tools at the market, VoIPong needs to get a copy of the voice traffic you're interested in. If you're sharing a hub with one of the endpoints of the voice conversation, you will not need to do anything, since hub devices inherently copy traffic to all its ports. If you are in a switched environment, some network administration will be needed. Most modern switch devices has a handy "monitor port" which you can use for copying traffic going through one or more switch ports. So you'll need to copy one of the endpoints' traffic to that monitor port, and connect the computer on which VoIPong is running. If you're running VoIPong on a gateway machine, where this machine has already access to all the voice traffic, you will not need to do anything.


6.1. Startup Parameters

You can use -h switch to see available startup parameters:

[murat@efe ~/voipong]$ ./voipong -h
usage: voipong [options]
options:
-h this screen
-v version info
-f run in foreground (don't become a daemon)
-d debug level. Valid levels are 0 through 4. Default: 0
-c config file path
-v switch shows VoIPong version information:
[murat@efe ~/voipong]$ ./voipong -v
EnderUNIX VOIPONG Voice Over IP Sniffer Release 2.0-DEVEL
Copyright (C) 2004 Murat Balaban murat || enderunix.org
All rights reserved.
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.
For more information on licensing, please see LICENSE
file included in the voipong source distribution.
[murat@efe ~/voipong]$ 
You can set the debug log level by -d switch. Valid levels are 0 through 4, latter being the most verbose. Default configuration file is /usr/local/etc/voipong/voipong.conf. You can use alternate configuration file by issuing -c switch and providing full path to the alternate configuration file. If you don't want VoIPong to daemonize, but instead you want it to stay at your terminal and dump log messages to the terminal, you will need to issue -f switch.

So, If you want VoIPong to stay at the terminal, and you want to see as many log messages as possible, you should fire VoIPong as such:

[root@devel ~]$ voipong -d4 -f
EnderUNIX VOIPONG Voice Over IP Sniffer starting...
Release 2.0-DEVEL, running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
(c) Murat Balaban http://www.enderunix.org/
20/11/05 19:33:33: EnderUNIX VOIPONG Voice Over IP Sniffer starting...
20/11/05 19:33:33: Release 2.0-DEVEL running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 23627]
20/11/05 19:33:33: Default matching algorithm: lfp
20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc)
20/11/05 19:33:33: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0)
20/11/05 19:33:33: loaded 2 module(s)
20/11/05 19:33:33: loadnet(10.0.0.145/255.255.255.255) method: fixed 49604
20/11/05 19:33:33: loadnet(172.16.0.10/255.255.0.0) method: lfp 
20/11/05 19:33:33: fxp0 has been opened in  promisc mode. (43.43.43.0/255.255.255.192)



6.2. Management Console: voipctl

VoIPong provides the user with the ability to administer the server at runtime. You can use voipctl command for this purpose. When fired, voipctl will connect VoIPong and will wait for user's commands:

[root@efe ~/voipong]$ voipctl 
Connected to VoIPong Management Console
System:
efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
voipong> 
help is the same old "help":
voipong> help
Commands:
help : this one
quit : quit management console
uptime : Server uptime
setdebug [level] : set debug level to [level]
logrotate : rotate server's logs
shutdown : shutdown server
rusage : CPU usage statistics for the server
loadnets : Reload voipongnets file
info : General server information
shcall : Show currently monitored calls
shrtcp : Show currently RTCP cache
killcall [id] : end monitoring session with [id]
voipong> 
uptime shows how long the server has been running:
voipong> uptime
Server uptime: 5 minutes 57 seconds
voipong>
!!: You can use !! command to issue the last command you typed. (same as in sh):
voipong> !!
Server uptime: 6 minutes 13 seconds
voipong>
logrotate command rotates server logs:
voipong> logrotate
Logrotate successfull
voipong>
shutdown command will shutdown the server and close management console connection
voipong> shutdown
rusage command will give information related to server's CPU utilization
voipong> rusage
Current CPU usage stats:
----------------------------------------
Total "user" time : 0 seconds
Total used "system" time : 0 seconds
Shared Memory Size : 384 KB
Integral Memory Size : 1512 KB
Integral stack Size : 1024 KB
Page requests : 70
Page errors : 0
Block input operations : 0
Block output operations : 2
Messages sent : 1
Messages received : 1
Signals : 0
Voluntary "context switch"s : 78
Involuntary "context switch"s : 1
voipong> 
loadnets command will re-read voipongnets and re-load network/algorithms mapping table
voipong> loadnets
Networks file has been reloaded successfuly
voipong>
info command will give general server information
voipong> info
General Server Info:
--------------------------:
Server version : Release 2.0-DEVEL
System : efe.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
Current work. direct. : /usr/home/murat/voipong
Log level : 4
Process ID (PID) : 16240
User : root [Charlie &]
Group : 0
voipong> 
setdebug command will change runtime log verbosity
voipong> setdebug 4
# set new debug level to 4
voipong>
shcall command will list calls currently monitored
voipong> shcall
ID    NODE1            PORT1 NODE2            PORT2 STIME             DURATION 
----- ---------------- ----- ---------------- ----- ----------------- ------------
01123 41.27.13.1       12000 31.12.11.8       24000 24/10/05 11:11:23 33 seconds
Total listed: 1
voipong> 
shrtcp command will show current RTCP cache
voipong> shrtcp
ID    NODE1            PORT1 NODE2            PORT2 STIME            
----- ---------------- ----- ---------------- ----- -----------------
01123 41.27.13.1       12001 31.12.11.8       24001 24/10/05 11:11:23
Total listed: 1
voipong>
killcall will end monitoring the call by id
voipong> killcall 2
transport_simplecmd: server returned error: No such session by ID: 2
cannot process killcall command
voipong> 
q, quit, exit commands will end management session
voipong> q
Bye!
[root@efe /home/murat/voipong]$ 



6.3. Running VoIPong with a non-privileged user

It is strongly advised that you avoid running VoIPong with super-user, but use a non-privileged special user created only for it. This section describes the steps you should take to accomplish this. Note that these steps should be done after you compiled and installed VoIPong successfully.

  • Create voipong user and group

    # pw group add voipong
    # pw user add voipong -g voipong -m -s /usr/local/bin/bash
    
  • Change ownership of voipong, voipctl and /usr/local/etc/voipong directory to voipong user:

    # chown voipong /usr/local/bin/voipong
    # chown voipong /usr/local/bin/voipctl
    # chown -R voipong /usr/local/etc/voipong
    # chgrp -R voipong /usr/local/etc/voipong
    
  • Change ownership of BPF device files (/dev/bpf*) to voipong user:

    # chown voipong /dev/bpf*
    
  • Switch user to voipong:

    # su - voipong
    To see all of the directories on your FreeBSD system, type
            ls -R / | more
                    -- Dru genesis@istar.ca
    %
    
  • Create runtime directories:

    % mkdir logs
    % mkdir output
    % mkdir run
    
  • Change log, pid and output directory paths to the new directories in voipong.conf

    logdir = /home/voipong/logs/
    logfile = voipong.log
    outdir = /home/voipong/output/
    cdrfile = /home/voipong/output/voipcdr.log
    pidfile = /home/voipong/run/voipong.pid
    mgmt_ipcpath = /home/voipong/run/voipongmgmt.sock
    
  • You can now run voipong

    % id
    uid=1042(voipong) gid=1042(voipong) groups=1042(voipong)
    % voipong -d4 -f
    EnderUNIX VOIPONG Voice Over IP Sniffer starting...
    Release 2.0-DEVEL, running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
    (c) Murat Balaban http://www.enderunix.org/
    20/11/05 22:34:03: EnderUNIX VOIPONG Voice Over IP Sniffer starting...
    20/11/05 22:34:03: Release 2.0-DEVEL running on devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 41334]
    20/11/05 22:34:03: Default matching algorithm: lfp
    20/11/05 22:34:03: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc)
    20/11/05 22:34:03: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0)
    20/11/05 22:34:03: loaded 2 module(s)
    20/11/05 22:34:03: loadnet(10.0.0.145/255.255.255.255) method: fixed 49604
    20/11/05 22:34:03: loadnet(172.16.0.10/255.255.0.0) method: lfp 
    20/11/05 22:34:03: fxp0 has been opened in  promisc mode. (43.43.43.0/255.255.255.128)
    
  • You can check whether the daemon is running with the correct user with voipctl

    % id
    uid=1042(voipong) gid=1042(voipong) groups=1042(voipong)
    % voipctl
    Connected to VoIPong Management Console
    System:
    devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
    voipong> info
    General Server Info:
    --------------------------:
    Server version            : Release 2.0-DEVEL
    System                    : devel.enderunix.org [FreeBSD 4.11-STABLE FreeBSD 4.11-STABLE #0: Tue Sep i386]
    Current work. direct.     : /usr/home/voipong
    Log level                 : 4
    Mix Voice Flag            : true
    Process ID (PID)          : 41334
    User                      : voipong [VoIPong Kullanicisi]
    Group                     : 1042
    voipong> 
    

6.4. VoIPong Live CD

Omer Faruk Sen has maintains VoIPong LiveCD! based on FreeSBIE project. LiveCD is an ISO image which can be burnt into a blank CD directly, and includes pre-installed VoIPong release along with several boot-time scripts for configuring the OS and VoIPong.

Please find the gzip'ed ISO images here:


Chapter 7. Example Scenarios

You can try VoIPong with Microsoft Netmeeting. Set up netmeeting so that it uses G711 at both ends, and make a voice call. You'll see the calls captured and wave files created after your call finishes.

If you do not have a testbed, do not want so much pain to test VoIPong, you can replay a test capture file in your machine and see if it is catched.


7.1. Replaying a previous capture file

  • Download this test call capture, where me and Baris are talking about EnderUNIX team.

  • Download and install tcpreplay tool. Tcpreplay tool reads pcap capture files, and re-injects the packets into a live network.

  • Start VoIPong

    04/12/05 16:27:20: EnderUNIX VOIPONG Voice Over IP Sniffer starting...
    04/12/05 16:27:20: Release 2.0-DEVEL running on efe.enderunix.org [FreeBSD 5.4-STABLE FreeBSD 5.4-STABLE #0: Sun Oct 23 16:39:41 EEST 2005     mb@efe.enderunix.org:/usr/src/sys/i386/compile/EFE i386]. (c) Murat Balaban http://www.enderunix.org/ [pid: 1075]
    04/12/05 16:27:20: Default matching algorithm: lfp
    04/12/05 16:27:20: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcmu.so (@0x2817f3bc)
    04/12/05 16:27:20: loadmodule: /usr/local/etc/voipong/modules/modvocoder_pcma.so (@0x281813e0)
    04/12/05 16:27:20: loaded 2 module(s)
    04/12/05 16:27:20: loadnet(10.30.0.11/255.255.255.255) method: fixed 40000
    04/12/05 16:27:20: em0 has been opened in  promisc mode. (192.168.1.0/255.255.255.0)
    
  • Start tcpreplay with the test capture you just downloaded at step 1.

    [root@efe ~/calls/ok]$ /usr/local/sbin/tcpreplay -i em0 endercall2.pcap
    sending on: em0
     4534 packets (1344595 bytes) sent in 141.44 seconds
     9506.2 bytes/sec 0.07 megabits/sec 32 packets/sec
    
  • You will see that VoIPong immediately starts monitoring your call. Following lines will appear in your voipong.log file:

    24/10/05 20:47:23: created a call recording instance!
    24/10/05 20:47:23: [68826] VoIP call has been detected.
    24/10/05 20:47:23: [68826] 10.0.0.145:49604 < -- > 10.0.0.200:49606
    24/10/05 20:47:23: [68826] Encoding 0-PCMU-8KHz, recording.......
    

    At the end of the call, you'll see that two .WAV files are created:

    24/10/05 20:52:52: [68826] maximum idle time [10 secs] has been elapsed for this call, the call might have been ended.
    24/10/05 20:52:52: [68826] .WAV file output/20051204/session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav has been created successfully
    24/10/05 20:52:52: [68826] .WAV file output/20051204/session-enc0-PCMU-8KHz-10.0.0.200,49606-10.0.0.145,49604.wav has been created successfully
    
    # ls /var/log/output/20051024/
    session-enc0-PCMU-8KHz-10.0.0.200,49606-10.0.0.145,49604.wav        session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav
    
  • You can play output files with several utilities including play, xmms etc.:

    # play /var/log/voipoutput/20051025/session-enc0-PCMU-8KHz-10.0.0.145,49604-10.0.0.200,49606.wav
    

Chapter 8. Frequently Asked Questions

This is a a non-complete list of questions frequently asked at voipong mailing list. You can have a more recent and updated one within the FAQ at VoIPong web site.


Chapter 9. Thanks

Please find a list of people and organizations who contributed or gave support to VoIPong here .


voipong-2.0/CVS/0040755000175400000000000000000010346323241012476 5ustar muratwheelvoipong-2.0/CVS/Root0100644000175400000000000000001310346320213013327 0ustar muratwheel/cvsup/cvs voipong-2.0/CVS/Repository0100644000175400000000000000001010346320213014560 0ustar muratwheelvoipong voipong-2.0/CVS/Entries0100644000175400000000000000264710346323241014040 0ustar muratwheel/ALGORITHMS/1.1/Thu Oct 20 08:26:33 2005// /AUTHORS/1.1.1.1/Tue Oct 18 17:28:10 2005// /COPYING/1.1.1.1/Tue Oct 18 17:28:15 2005// /ChangeLog/1.13/Sun Dec 4 14:29:14 2005// /conf.c/1.2/Wed Oct 19 11:18:34 2005// /configure.in/1.1/Sun Nov 20 17:14:47 2005// /miscutil.c/1.7/Fri Dec 9 14:59:26 2005// /modvocoder_pcma.c/1.6/Fri Dec 9 14:59:26 2005// /modvocoder_pcmu.c/1.6/Thu Nov 17 15:41:24 2005// /voipctl.c/1.10/Fri Dec 9 14:59:26 2005// /voipong.c/1.11/Fri Dec 9 14:59:26 2005// /voipongcdr.c/1.2/Fri Dec 9 14:59:26 2005// /voipongcodec.c/1.10/Tue Dec 6 09:07:56 2005// /voipongfixed.c/1.2/Mon Nov 14 18:58:20 2005// /voipongglobals.c/1.6/Sun Dec 4 14:27:35 2005// /voiponglfp.c/1.3/Mon Nov 14 18:58:20 2005// /voipongmgmt.c/1.7/Mon Nov 14 18:58:20 2005// /voipongnet.c/1.3/Sat Oct 22 11:46:28 2005// /voipongpcap.c/1.5/Fri Dec 9 14:59:26 2005// /voipongsign.c/1.2/Fri Dec 9 14:59:26 2005// /voipongsock.c/1.3/Wed Nov 23 18:59:15 2005// /voipongvoip.c/1.5/Tue Dec 6 09:19:47 2005// /voipongworker.c/1.12/Sat Nov 26 10:28:47 2005// D/docs//// D/etc//// D/include//// /Makefile.bsd/1.3/Fri Dec 9 15:20:53 2005// /Makefile.linux/1.3/Fri Dec 9 15:20:38 2005// /INSTALL/1.3/Fri Dec 9 15:38:38 2005// /KNOWN_BUGS/1.2/Fri Dec 9 15:45:33 2005// /LICENSE/1.2/Fri Dec 9 15:42:46 2005// /NEWS/1.2/Fri Dec 9 15:43:56 2005// /README/1.2/Fri Dec 9 15:42:11 2005// /THANKS/1.8/Fri Dec 9 15:43:18 2005// /TODO/1.4/Fri Dec 9 15:44:06 2005// voipong-2.0/etc/0040755000175400000000000000000010346320213012612 5ustar muratwheelvoipong-2.0/etc/CVS/0040755000175400000000000000000010346320213013245 5ustar muratwheelvoipong-2.0/etc/CVS/Root0100644000175400000000000000001310346320213014102 0ustar muratwheel/cvsup/cvs voipong-2.0/etc/CVS/Repository0100644000175400000000000000001410346320213015337 0ustar muratwheelvoipong/etc voipong-2.0/etc/CVS/Entries0100644000175400000000000000014010346320213014571 0ustar muratwheel/voipong.conf/1.10/Sun Dec 4 14:27:35 2005// /voipongnets/1.1.1.1/Tue Oct 18 17:28:26 2005// D voipong-2.0/etc/voipong.conf0100755000175400000000000000251110344576327015162 0ustar muratwheel# # 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 = /var/log logfile = voipong.log cdrfile = /var/log/voipcdr.log networksfile = /usr/local/etc/voipong/voipongnets pidfile = /var/run/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 = em0 promisc = 1 snaplen = 1500 readtmt = 500 outdir = output [FILTERS] startup = "udp" voipong-2.0/etc/voipongnets0100644000175400000000000000010510325230272015103 0ustar muratwheel#10.0.0.145/255.255.255.255 fixed 49604 #172.16.0.10/255.255.0.0 lfp voipong-2.0/include/0040755000175400000000000000000010346321170013465 5ustar muratwheelvoipong-2.0/include/CVS/0040755000175400000000000000000010346322430014120 5ustar muratwheelvoipong-2.0/include/CVS/Root0100644000175400000000000000001310346320213014752 0ustar muratwheel/cvsup/cvs voipong-2.0/include/CVS/Repository0100644000175400000000000000002010346320213016204 0ustar muratwheelvoipong/include voipong-2.0/include/CVS/Entries0100644000175400000000000000127110346322430015452 0ustar muratwheel/Makefile.am/1.1/Thu Dec 8 10:57:46 2005// /conf.h/1.1.1.1/Tue Oct 18 17:28:25 2005// /g711.h/1.2/Wed Oct 26 12:28:14 2005// /miscutil.h/1.5/Sun Oct 30 14:31:07 2005// /osspecific.h/1.1.1.1/Tue Oct 18 17:28:25 2005// /voipongcdr.h/1.1/Sat Oct 22 12:00:53 2005// /voipongcodec.h/1.2/Sun Oct 23 11:53:49 2005// /voipongmgmt.h/1.1.1.1/Tue Oct 18 17:28:26 2005// /voipongnet.h/1.2/Sat Oct 22 11:46:28 2005// /voipongpcap.h/1.1.1.1/Tue Oct 18 17:28:25 2005// /voipongsign.h/1.1.1.1/Tue Oct 18 17:28:25 2005// /voipongsock.h/1.1.1.1/Tue Oct 18 17:28:25 2005// /voipongvoip.h/1.1.1.1/Tue Oct 18 17:28:26 2005// /voipongworker.h/1.4/Mon Nov 14 18:58:21 2005// /voipong.h/1.2/Fri Dec 9 15:27:52 2005// D voipong-2.0/include/Makefile.am0100644000175400000000000000034710346010652015522 0ustar muratwheelnoinst_HEADERS = conf.h\ g711.h\ miscutil.h\ osspecific.h\ voipong.h\ voipongcdr.h\ voipongcodec.h\ voipongmgmt.h\ voipongnet.h\ voipongpcap.h\ voipongsign.h\ voipongsock.h\ voipongvoip.h\ voipongworker.h voipong-2.0/include/conf.h0100644000175400000000000000404610325230271014562 0ustar muratwheel#ifndef CONF_H__ #define CONF_H__ /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #define CONFERRBUFSIZ 1024 #define CONFFILESIZ 256 #define SECTSIZ 256 #define KEYWORDSIZ 256 #define VALSIZ 1024 typedef struct confsect confsect; typedef struct confnode confnode; typedef struct config config; struct confnode { char node[KEYWORDSIZ]; char val[VALSIZ]; struct confnode *next; }; struct confsect { char sect[SECTSIZ]; struct confnode *nodes; struct confsect *next; }; struct config { char file[CONFFILESIZ]; struct confsect *sects; }; int config_getsectionname(char *sect, int len, char *buf); int config_getkwvalpair(char *kw, int kwlen, char *val, int vallen, char *buf); config * config_parse(config *cfg, FILE *fp, char *errbuf); config * config_load(config *cfg, const char *path, char *errbuf); void config_dump(const config *cfg); void config_free(config *cfg); const char * config_getval(config *cfg, char *st, char *kw); int config_getstr(config *cfg, char *st, char *kw, char *out, int outlen); int config_getint(config *cfg, char *st, char *kw, int defval); long config_getlong(config *cfg, char *st, char *kw, long defval); double config_getdouble(config *cfg, char *st, char *kw, double defval); int config_save(const config *cfg, char *errbuf); #endif voipong-2.0/include/g711.h0100644000175400000000000000161610327673136014331 0ustar muratwheel#ifndef G711_H #define G711_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ int ulaw2linear(u_char u_val); int alaw2linear(u_char u_val); #endif voipong-2.0/include/miscutil.h0100644000175400000000000000544110331154453015472 0ustar muratwheel #ifndef MISCUTIL_H #define MISCUTIL_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #define MISC_LOGFG 1 #define MISC_LOGBG 0 #define O_LOGHEX 0x00000001 #define O_LOGCHAR 0x00000002 #define read_lock(fd) \ misc_lockreg(fd, F_SETLK, F_RDLCK, 0, SEEK_END, 0) #define readw_lock(fd) \ misc_lockreg(fd, F_SETLKW, F_RDLCK, 0, SEEK_END, 0) #define write_lock(fd) \ misc_lockreg(fd, F_SETLK, F_WRLCK, 0, SEEK_END, 0) #define writew_lock(fd) \ misc_lockreg(fd, F_SETLKW, F_WRLCK, 0, SEEK_END, 0) #define un_lock(fd) \ misc_lockreg(fd, F_SETLK, F_UNLCK, 0, SEEK_END, 0) void misc_setlogtype(int t); void misc_setlogdir(const char *); void misc_setlogfile(const char *); void misc_setloglevel(int); int misc_getlogleve(); int misc_openlog(); int misc_closelog(); void misc_debug(int, char *, ...); void misc_devmsglog(char *a, int flags, unsigned char *buf, int len); void misc_devlogx(char *a, int flags, unsigned char *buf, int len, char direction); void misc_devlog(char *a, char *fmt, ...); int misc_rotatelog(); char * misc_getunamestr(char *, int); char * misc_getuptimestr(char *, int, time_t); char *misc_inet_ntoa(int); int misc_inet_addr(char *); char *misc_trim(char *, int); char *misc_trimnewline(char *, int); int misc_hexstr2raw(char *str, char *out, int len); int misc_hexchar2int(char *str); int misc_substr(char *out, char *in, int offset, int len); int misc_strftime(char *out, int len, char *fmt); int misc_strftimegiven(char *out, int len, char *fmt, time_t tv); int misc_strstr(char *out, int outlen, char *in, int inlen, char sep, int sepix); double misc_getamount(char *stramount, int currencycode); double misc_timediff(struct timeval *t2, struct timeval *t1); int misc_trimnongraph(char *str, int len); int misc_getdayofmonth(time_t *tv); int misc_getmonth(time_t *tv); int misc_getyear(time_t *tv); char * misc_strbuf(char *hs, int hslen, char *ndl, int ndllen); int misc_lockreg(int fd, int cmd, int type, int offset, int whence, int len); void misc_strrev(char *str, int len); #endif voipong-2.0/include/osspecific.h0100644000175400000000000000006510325230271015761 0ustar muratwheel#ifndef __OSSPECIFIC__ #define __OSSPECIFIC__ #endif voipong-2.0/include/voipong.h0100644000175400000000000000251610346321170015320 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ #ifndef VOIPONG_H #define VOIPONG_H #define PROGRAM "EnderUNIX VOIPONG Voice Over IP Sniffer" #define VERSION "Release 2.0" #define COPYRIGHT "(c) Murat Balaban http://www.enderunix.org/" #include enum { ERRBUFSIZ = 1024, MAXSBUFSIZ = 128, MAXMBUFSIZ = 512, MAXBUFSIZ = 1024, MAXLBUFSIZ = 2048, MAXXBUFSIZ = 4096, MAXXXBUFSIZ = 8192 }; void graceful_shutdown(); void reload(); void usage(); void wexit(int); void waitforevents(void); void process_deadchild(void); void init_config(); void get_initcfgvals(); #endif voipong-2.0/include/voipongcdr.h0100644000175400000000000000013210326424765016015 0ustar muratwheel#ifndef CDR_H_ #define CDR_H_ #include int add2cdr(worker *); #endif voipong-2.0/include/voipongcodec.h0100644000175400000000000000043410326674715016331 0ustar muratwheel#ifndef VOIPONGCODEC_H_ #define VOIPONGCODEC_H_ #define MAXCODECS 128 typedef int vocoder_t(int, unsigned char *, int); typedef struct vocoder vocoder; struct vocoder { int rate; vocoder_t *f; }; void init_vocoders(void); int vocoder_default(int, unsigned char *, int); #endif voipong-2.0/include/voipongmgmt.h0100644000175400000000000000210310325230272016174 0ustar muratwheel#ifndef MGMTCONSOLE_H #define MGMTCONSOLE_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #define MGMTMAXPASSTRIES 3 #include #include #include int is_mgmt_active(); void accept_mgmt_client(int); void process_mgmt_request(); void close_mgmt_client(); int get_mgmt_fd(); #endif voipong-2.0/include/voipongnet.h0100644000175400000000000000243210326423224016025 0ustar muratwheel #ifndef VOIPONGNET_H #define VOIPONGNET_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include enum algos { ALGORITHM_LFP = 1, ALGORITHM_LRA = 2, ALGORITHM_FIXED }; typedef struct vnet vnet; struct vnet { int addr; int mask; int algo; int fixport; short inuse; void (*op) (struct vnet *, unsigned char *udata, const struct pcap_pkthdr *pkthdr, const unsigned char *packet); struct vnet *next; }; int loadnetfile(char *netfile); void init_vnet(); void free_vnet(); vnet *get_vnet(); #endif voipong-2.0/include/voipongpcap.h0100644000175400000000000000320210325230271016153 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #ifndef VOIPONGPCAP_H #define VOIPONGPCAP_H 1 #define isodd(x) (x & 1) #define iseven(x) !(x & 1) #include #include typedef struct voipstat voipstat; struct voipstat { double totalpack; double rtcppack; double rtcpsess; double rtpsess; }; voipstat * getstats(); void setstats(voipstat *s); int initpcap(int, char *, char *errbuf); int getdllen(); void peekpcap(int, pcap_handler); pcap_t *getpcapt(); void packet_handler(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); void packet_handler_lfp(vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); void packet_handler_lra(vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); void packet_handler_fixed(vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); #endif voipong-2.0/include/voipongsign.h0100644000175400000000000000200310325230271016166 0ustar muratwheel#ifndef SIGNALOPS_H #define SIGNALOPS_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ void sighandler(int); void sigint_handler(); void sigterm_handler(); void sigusr2_handler(); void sighup_handler(); void sigchld_handler(); void sigworkerhandler(int); #endif voipong-2.0/include/voipongsock.h0100644000175400000000000000224210325230271016172 0ustar muratwheel #ifndef VOIPONGSOCKET_H #define VOIPONGSOCKET_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ #include #define AUTHCLIRBUFSIZ 8192 int open_server_socket(); void add_to_select_set(int); void remove_from_select_set(int); void sockets_run(void); /* void init_socket(); void close_all_connections(); void setselecttimeout(int val); int getselecttimeout(void); int open_server_socket(int, int *); */ #endif voipong-2.0/include/voipongvoip.h0100644000175400000000000000443110325230272016213 0ustar muratwheel#ifndef RTP_H #define RTP_H /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #define PT_ULAW 0 #define PT_G723 4 #define PT_G729 18 #define SNAPLEN 1514 #define MAXNODE 10000 #include #include typedef struct rtp_session { u_int32_t ip1; u_int16_t port1; u_int32_t ip2; u_int16_t port2; char dev[256]; int rate; int size; int enc; int pid; time_t stime; struct rtp_session *next; } rtp_session; typedef struct rtcp_session rtcp_session; struct rtcp_session { u_int32_t ip1; u_int16_t port1; u_int32_t ip2; u_int16_t port2; time_t stime; struct rtcp_session *next; }; struct rtphdr { unsigned int cc:4; unsigned int ext:1; unsigned int pad:1; unsigned int ver:2; unsigned int pt:7; unsigned int mark:1; u_int16_t seq; u_int32_t timestamp; u_int32_t ssrc; u_int32_t csrc; }; typedef struct u_data { u_int32_t ip_arr[2]; int fd[2]; char ip1[24]; char ip2[24]; int dloffset; int last_req1; int last_req2; } u_data; #define IP_L sizeof(struct ip) #define UDP_L sizeof(struct udphdr) #define RTP_L sizeof(struct rtphdr) void removertcp(); void probertp(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); void probertcp(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); int child_loop(pcap_t *pd, int cnt, pcap_handler callback, u_char *user); unsigned int tuplehash(u_int32_t sip, u_int32_t dip, u_int16_t sp, u_int16_t dp); void init_voip(); int create_rtp_instance(rtcp_session **, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); #endif voipong-2.0/include/voipongworker.h0100644000175400000000000000154210336157115016555 0ustar muratwheel#ifndef ___WORKER_H #define ___WORKER_H #include #include #include typedef struct worker worker; struct worker { pid_t pid; rtcp_session *rtcp; rtp_session *rtp; int ip1fd; int ip2fd; char file1name[MAXLBUFSIZ]; char file2name[MAXLBUFSIZ]; time_t stime; time_t etime; struct worker *next; }; void init_workers(); void worker_main(worker *, int, unsigned char *); void kill_workers(); worker *getworkerbypid(pid_t ); void worker_remove(worker *); int worker_create(worker **, int, unsigned char *); int worker_isexist(u_int32_t, u_int32_t, u_int16_t, u_int16_t); int create_wave(); int exec_sox(char *, char *, char *, char *, char *); int exec_soxmix(char *, char *, char *); int create_outpath(); void worker_graceful_exit(int); void dumprtppayload(u_char *, const struct pcap_pkthdr *, const u_char *); #endif voipong-2.0/ALGORITHMS0100644000175400000000000000277010325652271013447 0ustar muratwheel VOIPONG ALGORITHMS Following release 2.0, voipong has started to provide a framework where the user will be able to select the algorithm that will be used for a network. This will hopefully enable the user to select the best algorithm to suit his VoIP infrastructure, so that many more calls can be detected. There are two currently active algorithms: 1. LFP (Least False Positive) Algorithm: ---------------------------------------- This algorithm tries to detect calls generated via VoIP devices conforming to RTP and RTCP RFCs. This algorithm should be able to detect and record a wide range of calls (about 70 % - 80 %). To use this algorithm, you'll need to specify a network to use with it in your voipongnets configuration file. E.g.: 172.16.1.0/255.255.255.0 lfp 2. FIXED (Fixed Port) Algorithm: -------------------------------- Some VoIP devices (e.g. Grand Stream IP phone adapters) use a fixed port to send and receive RTP packets, and they do not conform to RFCs. If you have such a device, you'll need to specify it in your voipongnets file: E.g.: 172.16.1.101/255.255.255.255 fixed 40000 The number next to "fixed" keyword specifies the fixed port number the device uses for RTP transportation. 3. LRA-SIP (Least Run Away - SIP) Algorithm: -------------------------------------------- This algo will follow SIP signalling packets, and will spot the RTP/RTCP session from the SDP packets. LRA-SIP is not implemented yet, however I'll be working on it for the next release (probably 2.1). voipong-2.0/INSTALL0100644000175400000000000000445110346322376013105 0ustar muratwheel EnderUNIX VoIPong 2.0 INSTALL The program is tested on - FreeBSD 5.4 - Solaris 8 - istanbulX GNU/Linux [1] Prerequisites a) You should have libpcap packet capturing library installed b) For .WAV file creation, you should install sox program and supply sox and soxmix path in voipong.conf configuration file. To compile VoIPong: There are several pre-written Makefiles in the source directory. Examine each of them and choose the one which most suits your system. If you're running of the the BSD type Operating Systems (i.e. FreeBSD, OpenBSD, NetBSD, Mac OSX) copy Makefile.bsd as Makefile; if you're using a Linux distribution then, copy Makefile.linux as Makefile. You might need to change CFLAGS and LDFLAGS variables accordingly. After you've chosen the Makefile and copied it, type make to compile VoIPong: # make To install the compiled binaries, type: # make install and binaries will be installed at /usr/local/bin/, the configuration file will be installed as /usr/local/etc/voipong.conf, and the algorithm specification file as /usr/local/etc/voipongnets. You're done. All you need to edit the configuration file, change soxpath and device parameters to suit your system and fire voipong $ voipong You can connect to mgmt interface and control your server from the interface. Use voipctl command for this purpose: mb@efe ~$ voipctl Connected to /var/run/voipongmgmt.sock. Escape character is '^]'. EnderUNIX VOIPONG Voice Over IP Sniffer Welcome to management console System: efe.enderunix.org [FreeBSD 5.4-RELEASE FreeBSD 5.4-RELEASE #0: Sun May 8 10:21:06 UTC 2005 root@harlow.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386] voipong> voipong> help Commands: help : this one quit : quit management console logrotate : rotate server's logs shutdown : shutdown server rusage : CPU usage statistics for the server info : General server information uptime : Server uptime shcall : Show currently monitored calls shrtcp : Show current RTCP cache killcall [id] : end monitoring session with [id] voipong> Please see ALGORITHMS file for a quick primer on using VoIPong's call catching algorithms. Wed Sep 28 16:42:02 EEST 2005 http://www.enderunix.org voipong-2.0/KNOWN_BUGS0100644000175400000000000000031010346323235013474 0ustar muratwheel - Some calls might not be detected, see Question 2: http://www.enderunix.org/voipong/index.php?sect=faq&lang=en - Only for G711 u-law and G711 a-law payload types will there be .WAV files. voipong-2.0/LICENSE0100644000175400000000000000344410346322766013065 0ustar muratwheel EnderUNIX VoIPong Voice Over IP Sniffer Copyright (C) 2004 - ... 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. Murat Balaban retains copyright to VoIPong as a whole (including, but not limited to, call catching algorithms), and therefore can grant, at his sole discretion, the ability for companies, individuals, or organizations to create proprietary or Open Source (but non-GPL'd) modules which may be dynamically linked at runtime or statically linked at compile time with the portions of VoIPong which fall under his copyright umbrella, or are distributed under more flexible licenses than GPL. If you want to use my code in your GPL'd programs, go for it -- there is no requirement that you provide the same exemption in your GPL'd products (although if you've written a module for VoIPong I would strongly encourage you to make the same exemption that I do). You can see GPL-License file for details about GNU General Public License http://www.enderunix.org http://www.enderunix.org/voipong/ http://www.enderunix.org/murat/ voipong-2.0/Makefile.bsd0100644000175400000000000000420010346320325014243 0ustar muratwheel# # VoIPong Voice Over IP Sniffer # Copyright (C) 2005 Murat Balaban # All rights reserved. # # 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. # CC=cc CFLAGS= -g -Wall -Iinclude SHLIBS=-lpcap CLEARX = rm -f *~ *core* *pid all: voipong voipctl modules modules: modvocoder_pcmu modvocoder_pcma modvocoder_pcmu: $(CLEARX) $(CC) -fPIC $(CFLAGS) -c modvocoder_pcmu.c $(CC) -shared -nostdlib -o modvocoder_pcmu.so modvocoder_pcmu.o modvocoder_pcma: $(CLEARX) $(CC) -fPIC $(CFLAGS) -c modvocoder_pcma.c $(CC) -shared -nostdlib -o modvocoder_pcma.so modvocoder_pcma.o OBJS= miscutil.o conf.o voipongglobals.o voipongsign.o voipong.o voipongsock.o \ voipongnet.o voipongpcap.o voipongvoip.o voipongmgmt.o voipongworker.o \ voipongcdr.o voipongcodec.o voiponglfp.o voipongfixed.o voipong: $(OBJS) $(CLEARX) $(CC) -g -o voipong $(CFLAGS) $(LDFLAGS) $(OBJS) $(STLIBS) $(SHLIBS) voipctl: voipctl.o voipongglobals.o $(CLEARX) $(CC) -g -o voipctl voipctl.o voipongglobals.o conf.o miscutil.o $(CFLAGS) install: mkdir -p /usr/local/etc/voipong mkdir -p /usr/local/etc/voipong/modules cp voipong /usr/local/bin/ cp voipctl /usr/local/bin/ cp etc/voipong.conf /usr/local/etc/voipong/ chmod 750 /usr/local/bin/voipong chmod 750 /usr/local/bin/voipctl chmod 600 /usr/local/etc/voipong/voipong.conf cp modvocoder_*.so /usr/local/etc/voipong/modules/ chmod 500 /usr/local/etc/voipong/modules/* cls: $(CLEARX) clean: $(CLEARX) rm -f voipong voipctl $(OBJS) *.o *.so *~ voipong-2.0/Makefile.linux0100644000175400000000000000420510346320306014636 0ustar muratwheel# # VoIPong Voice Over IP Sniffer # Copyright (C) 2005 Murat Balaban # All rights reserved. # # 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. # CC=cc CFLAGS= -g -Wall -Iinclude SHLIBS=-lpcap -ldl CLEARX = rm -f *~ *core* *pid OBJS= miscutil.o conf.o voipongglobals.o voipongsign.o voipong.o voipongsock.o \ voipongnet.o voipongpcap.o voipongvoip.o voipongmgmt.o voipongworker.o \ voipongcdr.o voipongcodec.o voiponglfp.o voipongfixed.o all: modules voipong voipctl voipong: $(OBJS) $(CLEARX) $(CC) -g -o voipong $(CFLAGS) $(LDFLAGS) $(OBJS) $(STLIBS) $(SHLIBS) voipctl: voipctl.o voipongglobals.o $(CLEARX) $(CC) -g -o voipctl voipctl.o voipongglobals.o conf.o miscutil.o $(CFLAGS) modules: modvocoder_pcmu modvocoder_pcma modvocoder_pcmu: $(CLEARX) $(CC) -fPIC $(CFLAGS) -c modvocoder_pcmu.c $(CC) -shared -nostdlib -o modvocoder_pcmu.so modvocoder_pcmu.o modvocoder_pcma: $(CLEARX) $(CC) -fPIC $(CFLAGS) -c modvocoder_pcma.c $(CC) -shared -nostdlib -o modvocoder_pcma.so modvocoder_pcma.o install: mkdir -p /usr/local/etc/voipong mkdir -p /usr/local/etc/voipong/modules cp voipong /usr/local/bin/ cp voipctl /usr/local/bin/ cp etc/voipong.conf /usr/local/etc/voipong/ chmod 750 /usr/local/bin/voipong chmod 750 /usr/local/bin/voipctl chmod 600 /usr/local/etc/voipong/voipong.conf cp modvocoder_*.so /usr/local/etc/voipong/modules/ chmod 500 /usr/local/etc/voipong/modules/* cls: $(CLEARX) clean: $(CLEARX) rm -f voipong voipctl $(OBJS) *.o *.so *~ voipong-2.0/NEWS0100644000175400000000000000041210346323074012540 0ustar muratwheel- VoIPong 2.0 has been released (2005/12/9) - VoIPong 2.0-DEVEL has been released for beta testers (2005/10/18) - VoIPong has been awarded the first standing in IBM Turkiye Linux competition. (2004/12/15) - VoIPong 1.1 has been released for public use. (2004/12/15) voipong-2.0/README0100755000175400000000000000237410346322723012735 0ustar muratwheel EnderUNIX VoIPong VoIP call detector and voice dumper VoIPong is a utility which detects all Voice Over IP calls on a pipeline, and for those which are G711 encoded, dumps actual conversation to seperate wave files. It supports SIP, H323, Cisco's Skinny Client Protocol, RTP and RTCP. It's been written in C language for performance reasons, proved to be running on Solaris, Linux and FreeBSD; though it's thought to compile and run on other platforms as well. It's multi-algoritm framework enables users with the ability to suit the best packet matching algorithm for their environment. On a 45 Mbit/sec actual network traffic, it's been verified that VoIPong successfully detected all VoIP gateways and the VoIP calls. CPU utilization during the run has been found ranging between 66% - 80% on a 256MB RAM, Celeron 1700 Mhz Toshiba notebook. With it's dynamic framework for coding 3rd party voice codecs, the current decoding capability can be easily extended. VoIPong has been awarded the first standing by IBM Turkiye in its Linux Awards 2004 competition. Please see INSTALL file in this tarball, and the online User's Manual available at: http://www.enderunix.org/voipong/manual/ to compile and install VoIPong into your system. voipong-2.0/THANKS0100644000175400000000000000377510346323026012770 0ustar muratwheel Special thanks to: * IBM Turk for electing VoIPong as the best project in Linux Awards 2004. * Baris Simsek for his work on VoIPong autoconf scripts, pointers for codecs and CDR file. * Omer Faruk Sen for his work on VoIPong Live-CD!. * Halil Demirezen for the Solaris Makefile. * EnderUNIX team for their invaluable support and friendships * Alex Barger for bug-reports, patches and sample voice sessions. * Andreas Jutzy for the hint about G711 PCMA support. * Eric [valgasu at club-internet dot fr] for the hint about fixed ip-port IP adapters * Pete Erickson fot the news about Gentoo-Linux compilation * "Vitalij Gura" for the codec pointers * Ignacio Bolivar for the codec pointers * Stijn Vande Casteele for the hint about startup filters * Mark Wiater for the idea of generating much more information out of RTP/RTCP. * Ami Chayun for the notice about daemon_init pidfile locking issue. * bobci for bug-reports * Aaron Schulman for letting me know that VoIPong runs on OS X 10.4.2 * Kevin Watkins for .wav file injection idea. * Rob Deker for bug-reports for sample voice sessions: * Rupa Schomaker * Ramamohan Yeggoni * Richard Hill * Jonathan Wilson * Clement Chen * Rodrigo Frez * Andrea wizard * Eric Alexander * Iqbal < iqbal at gigo dot co dot uk> Wed Sep 28 16:58:31 EEST 2005 voipong-2.0/TODO0100644000175400000000000000071410346323106012532 0ustar muratwheel VoIPong TODO * Implement "algorithm SIP" (a.k.a. algorithm lra) , where VoIPong will trace SIP signalling and catch calls out of SDP packets. * VoIPong Distributed: Redesign and code call recording so that it can be done in a distributed manner * Collect call statistics out of RTP/RTCP packets. * Better Cisco Skinny support (i.e. extract phone numbers) * G726 codec support Investigate further: Ignecio's mail * G723.1 codec support voipong-2.0/conf.c0100644000175400000000000001711410325425612013137 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 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. */ #include #include #include #include #include #include #include #include static const char emptystr[] = ""; int config_getsectionname(char *sect, int len, char *buf) { int i = 0; int j = 0; int buflen = strlen(buf); memset(sect, 0, len); for (buf++, buflen--; j < len - 1 && i < buflen && buf[i] != ']'; i++) sect[j++] = buf[i]; sect[j] = '\0'; return j; } int config_getkwvalpair(char *kw, int kwlen, char *val, int vallen, char *buf) { int j = 0; char *cp1 = NULL; int buflen = strlen(buf); memset(kw, 0, kwlen); memset(val, 0, vallen); cp1 = buf; for (; !isgraph(*cp1) && (cp1 - buf) < buflen; cp1++) ; for (; *cp1 != '=' && *cp1 != '#' && *cp1 != ' ' && (j < kwlen - 1) && (cp1 - buf) < buflen; cp1++, j++) kw[j] = *cp1; kw[j] = '\0'; if (strlen(kw) == 0) return 0; for (; (!isgraph(*cp1) || *cp1 == '=') && (cp1 - buf) < buflen; cp1++) ; j = 0; if (*cp1 == '"') for (cp1++; *cp1 != '"' && (j < vallen - 1) && (cp1 - buf) < buflen; cp1++, j++) val[j] = *cp1; else for (; *cp1 != '#' && (j < vallen - 1) && (cp1 - buf) < buflen; cp1++, j++) val[j] = *cp1; val[j] = '\0'; if (strlen(val) == 0) return 0; return 1; } config * config_parse(config *cfg, FILE *fp, char *errbuf) { char kw[KEYWORDSIZ]; char val[VALSIZ]; char buf[2048]; char sect[SECTSIZ]; int line; confsect *sptr = NULL; confnode *nptr = NULL; confsect *cursect = NULL; line = 0; while(fgets(buf, sizeof(buf) - 1, fp) != NULL) { /* misc_trimnongraph(buf, strlen(buf)); */ misc_trimnewline(buf, strlen(buf)); line++; if (buf[0] == '#' || strlen(buf) == 0) continue; if (buf[0] == '[') { config_getsectionname(sect, sizeof(sect), buf); if ((sptr = (confsect *)calloc(1, sizeof(confsect))) == NULL) { config_free(cfg); return NULL; } strncpy(sptr->sect, sect, SECTSIZ - 2); sptr->next = cfg->sects; cfg->sects = sptr; cursect = sptr; continue; } if (!config_getkwvalpair(kw, sizeof(kw), val, sizeof(val), buf)) continue; if (cursect == NULL) { if ((sptr = (confsect *)calloc(1, sizeof(confsect))) == NULL) { config_free(cfg); return NULL; } strncpy(sptr->sect, "DEFAULT", SECTSIZ - 2); sptr->next = cfg->sects; cfg->sects = sptr; cursect = sptr; } if ((nptr = (confnode *)calloc(1, sizeof(confnode))) == NULL) { config_free(cfg); return NULL; } strncpy(nptr->node, kw, KEYWORDSIZ - 2); strncpy(nptr->val, val, VALSIZ - 2); nptr->next = cursect->nodes; cursect->nodes = nptr; } fclose(fp); return cfg; } config * config_load(config *cfg, const char *path, char *errbuf) { FILE *fp = NULL; if ((fp = fopen(path, "r")) == NULL) { if (errbuf != NULL) snprintf(errbuf, CONFERRBUFSIZ - 2, "config_load: fopen(%s) failed: %s", path, strerror(errno)); return NULL; } strncpy(cfg->file, path, CONFFILESIZ - 2); cfg->sects = NULL; return config_parse(cfg, fp, errbuf); } void config_dump(const config *cfg) { confsect *sect = NULL; confnode *node = NULL; printf("config_dump for file %s\n\n", cfg->file); for (sect = cfg->sects; sect != NULL; sect = sect->next) { printf("[%s]\n", sect->sect); for (node = sect->nodes; node != NULL; node = node->next) printf("\t%s = %s\n", node->node, node->val); printf("\n"); } } void config_free(config *cfg) { confsect *sect = NULL; confnode *node = NULL; for (sect = cfg->sects; sect != NULL; sect = sect->next) { for (node = sect->nodes; node != NULL; node = node->next) free(node); free(sect); } cfg->sects = NULL; } const char * config_getval(config *cfg, char *st, char *kw) { confsect *sect = NULL; confnode *node = NULL; for (sect = cfg->sects; sect != NULL; sect = sect->next) { if (st != NULL) if (memcmp(sect->sect, st, strlen(sect->sect)) != 0) continue; for (node = sect->nodes; node != NULL; node = node->next) if (memcmp(node->node, kw, strlen(node->node)) == 0) return node->val; if (st != NULL) break; } return emptystr; } int config_getstr(config *cfg, char *st, char *kw, char *out, int outlen) { confsect *sect = NULL; confnode *node = NULL; int cplen = 0; for (sect = cfg->sects; sect != NULL; sect = sect->next) { if (st != NULL) if (memcmp(sect->sect, st, strlen(sect->sect)) != 0) continue; for (node = sect->nodes; node != NULL; node = node->next) if (memcmp(node->node, kw, strlen(node->node)) == 0) { cplen = strlen(node->val) < outlen ? strlen(node->val) : outlen - 1; memcpy(out, node->val, cplen); out[cplen] = '\0'; return strlen(out); } if (st != NULL) break; } return 0; } int config_getint(config *cfg, char *st, char *kw, int defval) { confsect *sect = NULL; confnode *node = NULL; for (sect = cfg->sects; sect != NULL; sect = sect->next) { if (st != NULL) if (memcmp(sect->sect, st, strlen(sect->sect)) != 0) continue; for (node = sect->nodes; node != NULL; node = node->next) if (memcmp(node->node, kw, strlen(node->node)) == 0) { return atoi(node->val); } if (st != NULL) break; } return defval; } long config_getlong(config *cfg, char *st, char *kw, long defval) { confsect *sect = NULL; confnode *node = NULL; for (sect = cfg->sects; sect != NULL; sect = sect->next) { if (st != NULL) if (memcmp(sect->sect, st, strlen(sect->sect)) != 0) continue; for (node = sect->nodes; node != NULL; node = node->next) if (memcmp(node->node, kw, strlen(node->node)) == 0) { return atol(node->val); } if (st != NULL) break; } return defval; } double config_getdouble(config *cfg, char *st, char *kw, double defval) { confsect *sect = NULL; confnode *node = NULL; for (sect = cfg->sects; sect != NULL; sect = sect->next) { if (st != NULL) if (memcmp(sect->sect, st, strlen(sect->sect)) != 0) continue; for (node = sect->nodes; node != NULL; node = node->next) if (memcmp(node->node, kw, strlen(node->node)) == 0) { return atof(node->val); } if (st != NULL) break; } return defval; } int config_save(const config *cfg, char *errbuf) { FILE *fp; char tstamp[64]; confsect *sect = NULL; confnode *node = NULL; if (strlen(cfg->file) == 0) { if (errbuf != NULL) snprintf(errbuf, CONFERRBUFSIZ - 2, "config_load: cfg->file is not specified!\n"); return -1; } if ((fp = fopen(cfg->file, "w")) == NULL) { if (errbuf != NULL) snprintf(errbuf, CONFERRBUFSIZ - 2, "config_load: fopen(%s) failed: %s", cfg->file, strerror(errno)); return -1; } misc_strftime(tstamp, sizeof(tstamp) - 2, "%Y.%m.%d-%H.%M.%S"); fprintf(fp, "#\n# %s, created by libconfig2 at %s\n#\n\n", cfg->file, tstamp); for (sect = cfg->sects; sect != NULL; sect = sect->next) { fprintf(fp, "[%s]\n", sect->sect); for (node = sect->nodes; node != NULL; node = node->next) fprintf(fp, "\t%s=%s\n", node->node, node->val); fprintf(fp, "\n"); } fflush(fp); fclose(fp); return 0; } voipong-2.0/configure.in0100644000175400000000000000467210340127407014362 0ustar muratwheel# # b$ # Thu Dec 23 11:04:01 EET 2004 # AC_INIT(voipong, 2.0, murat@enderunix.org) AM_INIT_AUTOMAKE(voipong, 2.0) AM_CONFIG_HEADER(config.h) AC_PREFIX_DEFAULT([/usr/local]) AC_CANONICAL_HOST CFLAGS="" LDFLAGS="${LDFLAGS} -L/usr/local/lib -L/usr/lib" LIBS=-lpcap AC_MSG_CHECKING([for operating system]) case "$host_os" in linux*) AC_DEFINE([LINUX], 1, [Define for the Linux operating system.]) ;; freebsd*) AC_DEFINE([FREEBSD], 1, [Define for the freebsd operating system.]) ;; openbsd*) AC_DEFINE([FREEBSD], 1, [Define for the openbsd operating system.]) ;; netbsd*) AC_DEFINE([FREEBSD], 1, [Define for the netbsd operating system.]) ;; solaris*) AC_DEFINE([SOLARIS], 1, [Define for the solaris operating system.]) LIBS="${LIBS} -lsocket -lresolv -lnsl" ;; hpux*) AC_DEFINE([HPUX], 1, [Define for the hp-ux operating system.]) ;; aix*) AC_DEFINE([AIX], 1, [Define for the aix operating system.]) ;; *) AC_MSG_ERROR([Non supprted operating system: $host_os. exiting.]) ;; esac AC_MSG_RESULT($host_os) AC_CONFIG_SRCDIR([voipong.c]) # Checks for programs. AC_PROG_CC # Checks for libraries. # FIXME: Replace `main' with a function in `-lpcap': AC_CHECK_LIB([pcap], [pcap_lookupnet], [], [ echo "Error! You need to have pcap library." echo "Visit http://www.tcpdump.org/ for pcap library." exit -1 ]) # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM AC_CHECK_TYPE(u_int32_t, [ echo "#ifndef __OSSPECIFIC__" > include/osspecific.h; echo "#define __OSSPECIFIC__" >> include/osspecific.h; ], [ echo "#ifndef __OSSPECIFIC__" > include/osspecific.h; echo "#define __OSSPECIFIC__" >> include/osspecific.h; echo "typedef unsigned int u_int32_t;" >> include/osspecific.h; ] ) AC_CHECK_TYPE(u_int16_t, [ echo "#endif" >> include/osspecific.h; ], [ echo "typedef unsigned short u_int16_t;" >> include/osspecific.h; echo "#endif" >> include/osspecific.h; ] ) # Checks for library functions. AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_MEMCMP AC_FUNC_STAT AC_FUNC_STRFTIME AC_FUNC_VPRINTF AC_CHECK_FUNCS([getcwd inet_ntoa localtime_r memmove memset mkdir select socket strerror uname]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT voipong-2.0/miscutil.c0100644000175400000000000002064710346315716014056 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int debuglevel = 0; static char logdir[1024]; static char logfile[1024]; static FILE *logp = NULL; static int foreground = 0; #ifdef __REENTRANT static pthread_mutex_t logmtx = PTHREAD_MUTEX_INITIALIZER; #endif void misc_setlogtype(int t) { #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif if (t == 1) foreground = 1; else foreground = 0; #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif } void misc_setlogdir(const char *l) { #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif strncpy(logdir, l, sizeof(logdir) - 2); #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif } void misc_setlogfile(const char *l) { #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif strncpy(logfile, l, sizeof(logfile) - 2); #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif } void misc_setloglevel(int l) { #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif debuglevel = l; #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif } int misc_getloglevel() { int ret = 0; #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif ret = debuglevel; #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return ret; } int misc_openlog() { char logpath[1024]; snprintf(logpath, sizeof(logpath) - 2, "%s/%s", logdir, logfile); #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif if ((logp = fopen(logpath, "a")) == NULL) { syslog(LOG_ERR, "cannot open %s for writing: %s", logpath, strerror(errno)); #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return -1; } #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return 0; } int misc_closelog() { if (logp == NULL) return 0; #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif if (fclose(logp) != 0) { syslog(LOG_ERR, "cannot close logfile: %s\n", strerror(errno)); #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return -errno; } logp = NULL; #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return 0; } int misc_rotatelog() { time_t tv; struct tm tm; char tbuf[64]; char movepath[1024]; char logpath[1024]; time(&tv); localtime_r(&tv, &tm); strftime(tbuf, sizeof(tbuf) - 2, "%Y.%m.%d-%H.%M.%S", &tm); snprintf(movepath, sizeof(movepath) - 2, "%s/%s-%s", logdir, logfile, tbuf); snprintf(logpath, sizeof(logpath) - 2, "%s/%s", logdir, logfile); misc_debug(0, "Switching main server log from %s to %s\n", logpath, movepath); if (misc_closelog() < 0) return -1; #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif if ((rename(logpath, movepath)) < 0) { syslog(LOG_ERR, "Cannot rename %s to %s: %s\n", logpath, movepath, strerror(errno)); #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif return -1; } #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif misc_openlog(); misc_debug(0, "Logrotate finished successfully\n"); return 0; } char * misc_trim(char *s, int len) { int i, j = 0; char *tmp = (char *)malloc(len + 1); len = strlen(s); for (i = 0, j = 0; (i < (len - 1)) && (j < (len - 1)); i++) { if (s[i] == ' ') continue; tmp[j++] = s[i]; } tmp[j] = '\0'; memset(s, 0x0, len); strncpy(s, tmp, len - 1); free(tmp); return s; } char * misc_trimnewline(char *s, int len) { int i, j = 0; char *tmp; tmp = (char *)malloc(len + 1); for (i = 0, j = 0; (i < (len - 1)) && (j < (len - 1)); i++) { if (s[i] == '\r' || s[i] == '\n') continue; tmp[j++] = s[i]; } tmp[j] = '\0'; memset(s, 0, len); strncpy(s, tmp, len - 1); free(tmp); return s; } void misc_debug(int l, char *fmt, ...) { va_list ap; FILE *lp; time_t tv; struct tm tm; char lfmt[4096]; char tbuf[64]; if (logp == NULL) return; if (l > debuglevel) return; #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif if (foreground == 1) lp = stdout; else lp = logp; time(&tv); localtime_r(&tv, &tm); strftime(tbuf, sizeof(tbuf) - 2, "%d/%m/%y %H:%M:%S", &tm); snprintf(lfmt, sizeof(lfmt) - 2, "%s: %s", tbuf, fmt); va_start(ap, fmt); if (vfprintf(lp, lfmt, ap) < 1) { #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif misc_closelog(); misc_openlog(); #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif } if (fflush(lp) != 0) { #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif misc_closelog(); misc_openlog(); #ifdef __REENTRANT pthread_mutex_lock(&logmtx); #endif } #ifdef __REENTRANT pthread_mutex_unlock(&logmtx); #endif va_end(ap); } char * misc_getunamestr(char *uname_str, int len) { struct utsname uts; if (uname(&uts) < 0) strcpy(uname_str, "Undefined host"); else snprintf(uname_str, len - 1, "%s [%s %s %s %s]", uts.nodename, uts.sysname, uts.release, uts.version, uts.machine); return uname_str; } char * misc_getuptimestr(char *uptime_str, int len, time_t firetime) { char fmt[32]; time_t now; time_t diff; time(&now); diff = now - firetime; memset(uptime_str, 0x0, len); if (diff > 86400) { snprintf(fmt, sizeof(fmt) - 2, "%d days ", diff / 86400); diff -= (diff / 86400) * 86400; strncpy(uptime_str, fmt, len - 1); } if (diff > 3600) { snprintf(fmt, sizeof(fmt) - 2, "%d hours ", diff / 3600); diff -= (diff / 3600) * 3600; strncat(uptime_str, fmt, len - 1); } if (diff > 60) { snprintf(fmt, sizeof(fmt) - 2, "%d minutes ", diff / 60); diff -= (diff / 60) * 60; strncat(uptime_str, fmt, len - 1); } if (diff > 0) { snprintf(fmt, sizeof(fmt) - 2, "%d seconds", diff); strncat(uptime_str, fmt, len - 1); } return uptime_str; } /* Returns formatted current time */ int misc_strftime(char *out, int len, char *fmt) { time_t tv; struct tm tm; time(&tv); localtime_r(&tv, &tm); return strftime(out, len, fmt, &tm); } /* Returns formatted given time */ int misc_strftimegiven(char *out, int len, char *fmt, time_t tv) { struct tm tm; localtime_r(&tv, &tm); return strftime(out, len, fmt, &tm); } int misc_lockreg(int fd, int cmd, int type, int offset, int whence, int len) { struct flock lock; lock.l_type = type; lock.l_start = offset; lock.l_whence = whence; lock.l_len = len; return fcntl(fd, cmd, &lock); } double misc_timediff(struct timeval *t2, struct timeval *t1) { double diff = 0.0; diff = t2->tv_sec - t1->tv_sec; diff += (t2->tv_usec - t1->tv_usec) / 1000000.0; return diff; } int misc_trimnongraph(char *str, int len) { register int i = 0; for (i = 0; i < len; ) { if (!isgraph(str[i])) memmove(&str[i], &str[i + 1], --len); else i++; } str[len] = '\0'; return len; } char * misc_inet_ntoa(int ip) { struct in_addr in; in.s_addr = ip; return inet_ntoa(in); } int misc_inet_addr(char *ip) { return inet_addr(ip); } char * misc_strbuf(char *hs, int hslen, char *ndl, int ndllen) { int i = 0, j = 0, match = 0; for (i = 0, j = 0; i < hslen; i++) { if (hs[i] == ndl[0]) { for (j = 1, match = 1, i++; j < ndllen && i < hslen; j++, i++) { if (hs[i] != ndl[j]) break; else match++; } if (match == ndllen) return &hs[i - match]; } } return NULL; } void misc_strrev(char *str, int len) { register int i = 0, j = 0; char tmp; for (i = 0, j = len - 1; (i <= j) && (i < len) && (j < len); i++, j--) { tmp = str[i]; str[i] = str[j]; str[j] = tmp; } } voipong-2.0/modvocoder_pcma.c0100644000175400000000000000702610346315716015362 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. G711 PCMA (a-law) Decoder Module 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. */ /* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #include #include #include /* modvocoder_pcma.c * * Module Definitions * */ #define MODNAME "VOIPONG vocoder G711 (a-law)" #define MODVERSION "1.0" #define MODPAYLOADTYPE 8 #define MODPAYLOADRATE 8000 /* * g711.c * * u-law, A-law and linear PCM conversions. */ #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ /* * alaw2linear() - Convert an A-law value to 16-bit linear PCM * */ static int alaw2linear( unsigned char a_val) { int t; int seg; a_val ^= 0x55; t = (a_val & QUANT_MASK) << 4; seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; switch (seg) { case 0: t += 8; break; case 1: t += 0x108; break; default: t += 0x108; t <<= seg - 1; } return ((a_val & SIGN_BIT) ? t : -t); } /* Decodes one byte PCMU data to two bytes unsigned linear data */ static int vocoder_alaw(int fd, u_char *pl, int len) { u_int16_t wbuf[2048]; int i = 0; int wlen = len * sizeof(u_int16_t); for (i = 0; i < len && (i < sizeof(wbuf) / sizeof(u_int16_t)); i++) wbuf[i] = alaw2linear(pl[i]); if (write(fd, wbuf, wlen) < wlen) return -1; return wlen; } /* Install module hook */ vocoder_t * modvocoder_pcma_init(vocoder vocoders[]) { vocoders[MODPAYLOADTYPE].rate = MODPAYLOADRATE; vocoders[MODPAYLOADTYPE].f = vocoder_alaw; return (vocoder_t *)vocoders[MODPAYLOADTYPE].f; } voipong-2.0/modvocoder_pcmu.c0100644000175400000000000000764110337122244015401 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. G711 PCMU (u-law) Decoder Module 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. */ /* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #include #include #include /* modvocoder_pcmu.c * * Module Definitions */ #define MODNAME "VOIPONG vocoder G711 (u-law)" #define MODVERSION "1.0" #define MODPAYLOADTYPE 0 #define MODPAYLOADRATE 8000 /* * g711.c * * u-law, A-law and linear PCM conversions. */ #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ #define BIAS (0x84) /* Bias for linear code. */ /* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */ static int ulaw2linear( unsigned char u_val) { int t; /* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } /* Decodes one byte PCMU data to two bytes unsigned linear data */ static int vocoder_ulaw(int fd, u_char *pl, int len) { u_int16_t wbuf[2048]; int i = 0; int wlen = len * sizeof(u_int16_t); for (i = 0; i < len && (i < sizeof(wbuf) / sizeof(u_int16_t)); i++) wbuf[i] = ulaw2linear(pl[i]); if (write(fd, wbuf, wlen) < wlen) return -1; return wlen; } /* Install module hook */ vocoder_t * modvocoder_pcmu_init(vocoder vocoders[]) { vocoders[MODPAYLOADTYPE].rate = MODPAYLOADRATE; vocoders[MODPAYLOADTYPE].f = vocoder_ulaw; return (vocoder_t *)vocoders[MODPAYLOADTYPE].f; } voipong-2.0/voipctl.c0100644000175400000000000003127710346315716013706 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2004,2005 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Externals */ extern config cfg; extern char gcfgfile[128]; extern int gthisday; extern int gthismon; extern time_t gstarttime; extern char gmgmt_path[128]; static int sd = -1; int process_greets(void); void process_req(void); int open_client_socket(); void freecmds(char **cmds, int csiz); int main(int argc, char **argv) { extern char *optarg; int error = 0; int c = 0; struct tm tm; /* Program baslarken bugunku tarihi alalim */ time(&gstarttime); localtime_r(&gstarttime, &tm); gthisday = tm.tm_mday; gthismon = tm.tm_mon; strcpy(gcfgfile, "/usr/local/etc/voipong/voipong.conf"); while (!error && (c = getopt(argc, argv, "c:hv")) != -1) { switch(c) { case 'v': printf("%s %s\n", "voipctl", VERSION); printf("Copyright (C) 2005 Murat Balaban \n" "All rights reserved.\n\n" "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version 2\n" "of the License, or (at your option) any later version.\n\n" "For more information on copying and license, please see LICENSE\n" "file included in the voipong source distribution.\n"); exit(0); break; case 'h': usage(); exit(0); break; case 'c': strncpy(gcfgfile, optarg, sizeof(gcfgfile) - 2); break; default: printf("invalid option: %c, try -h for help\n", c); exit(EX_USAGE); } } init_config(); if ((sd = open_client_socket()) == -1) exit(1); process_req(); return 0; } void init_config() { char errbuf[CONFERRBUFSIZ]; if ((config_load(&cfg, gcfgfile, errbuf)) == NULL) { fprintf(stderr, "init_config: %s\n", errbuf); exit(1); } get_initcfgvals(); } void get_initcfgvals() { if (config_getstr(&cfg, "GENERAL", "mgmt_ipcpath", gmgmt_path, sizeof(gmgmt_path) - 2) == 0) { printf("cannot get mgmtipcpath from configfile, shutting down......\n"); exit(1); } } void usage() { printf("usage: voipctl [options]\n"); printf("\toptions:\n"); printf("\t\t-h this screen\n"); printf("\t\t-v version info\n"); printf("\t\t-c config file path\n"); printf("\n"); } int open_client_socket() { struct sockaddr_un sun; memset(&sun, 0x0, sizeof(sun)); sun.sun_family = AF_LOCAL; strncpy(sun.sun_path, gmgmt_path, 100); if ((sd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "open_client_socket: socket: %s\n", strerror(errno)); return -1; } if (connect(sd, (const struct sockaddr *)&sun, sizeof(sun)) == -1) { fprintf(stderr, "open_client_socket: connect(%s): %s\n", sun.sun_path, strerror(errno)); return -1; } if (process_greets() != 0) { fprintf(stderr, "open_client_socket: greeting failed with the management server\n"); return -1; } return sd; } void prompt() { printf("voipong> "); fflush(stdout); } int process_greets(void) { char rbuf[1024]; int rlen = 0; memset(rbuf, 0x0, sizeof(rbuf)); if ((rlen = recv(sd, rbuf, sizeof(rbuf) - 2, 0)) == -1) { fprintf(stderr, "process_greets: recv: %s\n", strerror(errno)); return -1; } if (memcmp(rbuf, "+OK", 3) != 0) { fprintf(stderr, "process_greets: server did not welcome us:\n%s\n", rbuf); return -1; } printf("\n\n\nConnected to VoIPong Management Console\n\nSystem:\n%s\n\n", rbuf + 4); return 0; } int parsecmd(char *str, int siz, char **cmds, int csiz) { char tmp[1024]; int i = 0, j = 0, k = 0; while (i < siz && k < csiz) { memset(tmp, 0x0, sizeof(tmp)); for (; (i < siz) && (!isalnum(str[i])); i++) ; for (j = 0; (i < siz) && (isalnum(str[i])) && j < (sizeof(tmp) - 2); i++) tmp[j++] = str[i]; tmp[j] = '\0'; if (strlen(tmp) == 0) continue; cmds[k++] = strdup(tmp); } return k; } void freecmds(char **cmds, int csiz) { int i = 0; for (i = 0; i < csiz; i++) { if (cmds[i] != NULL) { free(cmds[i]); cmds[i] = NULL; } } } void help() { printf("Commands:\n"); printf("help : this one\n"); printf("quit : quit management console\n"); printf("uptime : Server uptime\n"); printf("logrotate : rotate server's logs\n"); printf("setdebug [level] : set debug level to [level]\n"); printf("setmixflag [flag] : set mix voice flag to true or false [e.g: 1 for true, 0 for false]\n"); printf("shutdown : shutdown server\n"); printf("rusage : CPU usage statistics for the server\n"); printf("loadnets : Reload voipongnets file\n"); printf("info : General server information\n"); printf("shcall : Show currently monitored calls\n"); printf("shrtcp : Show currently RTCP cache\n"); printf("killcall [id] : end monitoring session with [id]\n"); } int transport_simplecmd(char *sbuf, int slen, char *rbuf, int rlen) { int ret = 0; if ((ret = send(sd, sbuf, slen, 0)) < slen) { printf("transport_simplecmd: send (%d): %s\n", ret, strerror(errno)); return -1; } memset(rbuf, 0x0, rlen); if ((ret = recv(sd, rbuf, rlen, 0)) == -1) { printf("transport_simplecmd: recv: %s\n", strerror(errno)); return -1; } if (memcmp(rbuf, "+OK", 3) != 0) { printf("transport_simplecmd: server returned error: %.128s\n", rbuf + 5); return -1; } return 0; } int transport_advcmd(char *sbuf, int slen, char *rbuf, int rlen) { int ret = 0; char *tmp; int ntmp = 0; if ((ret = send(sd, sbuf, slen, 0)) < slen) { printf("transport_advcmd: send (%d): %s\n", ret, strerror(errno)); return -1; } memset(rbuf, 0x0, rlen); if ((ret = recv(sd, rbuf, rlen, 0)) == -1) { printf("transport_advcmd: recv: %s\n", strerror(errno)); return -1; } if (memcmp(rbuf, "+OK", 3) != 0) { printf("transport_advcmd: server returned error: %.128s\n", rbuf + 5); return -1; } if ((tmp = misc_strbuf(rbuf, ret, "+OK .", 5)) != NULL) ntmp = (tmp - rbuf - 5); else return -1; fwrite(rbuf + 5, sizeof(char), ntmp, stdout); fflush(stdout); while(misc_strbuf(rbuf, ret, "+OK .", 5) == NULL) { memset(rbuf, 0x0, rlen); if ((ret = recv(sd, rbuf, rlen, 0)) == -1) { printf("transport_advcmd: w recv: %s\n", strerror(errno)); return -1; } fwrite(rbuf, sizeof(char), ret, stdout); fflush(stdout); } return 0; } void uptime(char **cmds, int cnt) { char buf[1024]; if (transport_simplecmd("UPTIME\r\n", 8, buf, sizeof(buf) - 2) == -1) { printf("cannot retrieve uptime information\n"); return; } printf("Server uptime: %s\n", buf + 4); } void logrotate(char **cmds, int cnt) { char buf[1024]; if (transport_simplecmd("LOGROTATE\r\n", 11, buf, sizeof(buf) - 2) == -1) { printf("cannot rotate logs\n"); return; } printf("Logrotate successfull\n"); } void loadnets(char **cmds, int cnt) { char buf[1024]; if (transport_simplecmd("LOADNETS\r\n", 10, buf, sizeof(buf) - 2) == -1) { printf("cannot load voipongnets\n"); return; } printf("Networks file has been reloaded successfull\n"); } void sshutdown(char **cmds, int cnt) { char buf[1024]; if (transport_simplecmd("SHUTDOWN\r\n", 10, buf, sizeof(buf) - 2) == -1) { printf("cannot send shutdown command\n"); return; } exit(0); } void sendclose(char **cmds, int cnt) { char buf[1024]; if (transport_simplecmd("CLOSESESSION\r\n", 14, buf, sizeof(buf) - 2) == -1) { printf("cannot send closesession command\n"); return; } } void rusage(char **cmds, int cnt) { char buf[1024]; if (transport_advcmd("RUSAGE\r\n", 8, buf, sizeof(buf) - 2) == -1) { printf("cannot process rusage command\n"); return; } } void info(char **cmds, int cnt) { char buf[1024]; if (transport_advcmd("INFO\r\n", 6, buf, sizeof(buf) - 2) == -1) { printf("cannot process info command\n"); return; } } void shcall(char **cmds, int cnt) { char buf[1024]; if (transport_advcmd("SHCALL\r\n", 8, buf, sizeof(buf) - 2) == -1) { printf("cannot process shcall command\n"); return; } } void shrtcp(char **cmds, int cnt) { char buf[1024]; if (transport_advcmd("SHRTCP\r\n", 8, buf, sizeof(buf) - 2) == -1) { printf("cannot process shrtcp command\n"); return; } } void killcall(char **cmds, int cnt) { char sbuf[1024]; char buf[1024]; if (cmds[1] == NULL) return; if (strlen(cmds[1]) < 1) return; snprintf(sbuf, sizeof(sbuf) - 2, "KILLCALL %.20s\r\n", cmds[1]); if (transport_simplecmd(sbuf, strlen(sbuf), buf, sizeof(buf) - 2) == -1) { printf("cannot process killcall command\n"); return; } printf("# %s\n", buf + 4); } void setdebug(char **cmds, int cnt) { char sbuf[1024]; char buf[1024]; if (cmds[1] == NULL) return; if (strlen(cmds[1]) < 1) return; snprintf(sbuf, sizeof(sbuf) - 2, "SETDEBUG %.20s\r\n", cmds[1]); if (transport_simplecmd(sbuf, strlen(sbuf), buf, sizeof(buf) - 2) == -1) { printf("cannot process setdebug command\n"); return; } printf("# %s\n", buf + 4); } void setmixflag(char **cmds, int cnt) { char sbuf[1024]; char buf[1024]; if (cmds[1] == NULL) return; if (strlen(cmds[1]) < 1) return; snprintf(sbuf, sizeof(sbuf) - 2, "SETMIXFLAG %.20s\r\n", cmds[1]); if (transport_simplecmd(sbuf, strlen(sbuf), buf, sizeof(buf) - 2) == -1) { printf("cannot process setmixflag command\n"); return; } printf("# %s\n", buf + 4); } void process_req(void) { char line[1024]; char prevline[1024]; char *cmds[10]; int ccnt = 0; memset(line, 0x0, sizeof(line)); memset(prevline, 0x0, sizeof(prevline)); prompt(); while (fgets(line, sizeof(line) - 1, stdin) != NULL) { ccnt = 0; memset(cmds, 0x0, sizeof(cmds)); misc_trimnewline(line, strlen(line)); if (strlen(line) == 0) { prompt(); continue; } if (memcmp(line, "!!", 2) == 0) { if (strlen(prevline) == 0) { prompt(); continue; } strncpy(line, prevline, sizeof(line) - 2); } if ((ccnt = parsecmd(line, strlen(line), cmds, sizeof(cmds) / sizeof(char *))) < 1) { printf("cannot parse command: %s\n", line); freecmds(cmds, sizeof(cmds) / sizeof(char *)); prompt(); continue; } if (cmds[0] == NULL) continue; strncpy(prevline, line, sizeof(prevline) - 2); /* Here it is: */ if (memcmp(cmds[0], "q", 1) == 0 || memcmp(cmds[0], "quit", 4) == 0 || memcmp(cmds[0], "exit", 4) == 0 || memcmp(cmds[0], "bye", 3) == 0) { printf("Bye!\n"); sendclose(cmds, ccnt); close(sd); return; } else if (memcmp(cmds[0], "help", 4) == 0) help(); else if (memcmp(cmds[0], "uptime", 5) == 0) uptime(cmds, ccnt); else if (memcmp(cmds[0], "logrotate", 9) == 0) logrotate(cmds, ccnt); else if (memcmp(cmds[0], "shutdown", 8) == 0) sshutdown(cmds, ccnt); else if (memcmp(cmds[0], "rusage", 6) == 0) rusage(cmds, ccnt); else if (memcmp(cmds[0], "info", 4) == 0) info(cmds, ccnt); else if (memcmp(cmds[0], "shcall", 6) == 0) shcall(cmds, ccnt); else if (memcmp(cmds[0], "shrtcp", 6) == 0) shrtcp(cmds, ccnt); else if (memcmp(cmds[0], "killcall", 8) == 0) killcall(cmds, ccnt); else if (memcmp(cmds[0], "setdebug", 8) == 0) setdebug(cmds, ccnt); else if (memcmp(cmds[0], "setmixflag", 8) == 0) setmixflag(cmds, ccnt); else if (memcmp(cmds[0], "loadnets", 8) == 0) loadnets(cmds, ccnt); freecmds(cmds, sizeof(cmds) / sizeof(char *)); prompt(); } printf("Closing management console...\n"); close(sd); } voipong-2.0/voipong.c0100644000175400000000000002477510346315716013714 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Externals */ extern config cfg; extern int gfg; extern int gdbg; extern char gcfgfile[128]; extern int gthisday; extern int gthismon; extern time_t gstarttime; extern char gsoxpath[256]; extern char gsoxmixpath[256]; extern int gsoxmixflag; extern char gpidfile[128]; extern char goutdir[256]; extern char gmodpath[256]; extern char gnetfile[256]; extern char gcdrfile[256]; extern char gdefalg[256]; extern int pcapfd, mgmtfd; extern char gdevice[256]; extern char gfilter[1024]; extern char gmgmt_path[128]; extern int gpromisc; extern int gsnaplen; extern int greadtmt; extern int grtp_idle_time; extern rtp_session *rtps; extern void (*packet_handler_default) (vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); int daemon_init(void) { FILE *lckp = NULL; pid_t pid = 0; int i = 0; if (gfg == 0) { if ((pid = fork()) < 0) return -1; else if (pid != 0) exit(0); setsid(); /* fork again so that I cannot gain controlling terminal anymore */ if ((pid = fork()) < 0) return -1; else if (pid != 0) exit(0); for (i = getdtablesize(); i >= 0; i--) close(i); if ((i = open(_PATH_DEVNULL, O_RDWR, 0640)) == -1) /* stdin */ exit(1); dup2(i, STDOUT_FILENO); dup2(i, STDERR_FILENO); } setuid(getuid()); setgid(getgid()); umask(077); openlog("voipong", 0, LOG_DAEMON); if ((lckp = fopen(gpidfile, "w")) == NULL) { fprintf(stderr, "cannot open pidfile: %s\n", strerror(errno)); syslog(LOG_WARNING, "cannot open pidfile: %.128s\n", strerror(errno)); exit(1); } if (lockf(fileno(lckp), F_TLOCK, 0)) { fprintf(stderr, "cannot lock pidfile %s: %s, may be another copy running?\n", gpidfile, strerror(errno)); syslog(LOG_WARNING, "cannot lock pidfile %.128s: %.128s, may be another copy running?\n", gpidfile, strerror(errno)); exit(1); } /* write pid */ fprintf(lckp, "%d\n", getpid()); fflush(lckp); return 0; } void wexit(int c) { char tmp[1024]; misc_debug(0, "PID %d [parent: %d]: exited with code: %d. uptime: %s.\n", getpid(), getppid(), c, misc_getuptimestr(tmp, sizeof(tmp) - 2, gstarttime)); if (unlink(gpidfile) == -1) syslog(LOG_ERR, "can't remove pidfile[%.128s]: %.128s\n", gpidfile, strerror(errno)); if (unlink(gmgmt_path) == -1) syslog(LOG_ERR, "can't remove mgmt_ipcfile[%.128s]: %.128s\n", gmgmt_path, strerror(errno)); misc_closelog(); exit(c); } int main(int argc, char **argv) { extern char *optarg; int error = 0; int c = 0; char tmp[512]; struct tm tm; struct sigaction sa; struct sigaction sa_old; char errbuf[ERRBUFSIZ]; sa.sa_handler = sighandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sigaction(SIGHUP, &sa, &sa_old); sigaction(SIGUSR2, &sa, &sa_old); sigaction(SIGTERM, &sa, &sa_old); sigaction(SIGINT, &sa, &sa_old); sigaction(SIGCHLD, &sa, &sa_old); sigaction(SIGSTOP, &sa, &sa_old); sigaction(SIGQUIT, &sa, &sa_old); sigaction(SIGPIPE, &sa, &sa_old); sigaction(SIGALRM, &sa, &sa_old); /* Program baslarken bugunku tarihi alalim */ time(&gstarttime); localtime_r(&gstarttime, &tm); gthisday = tm.tm_mday; gthismon = tm.tm_mon; strcpy(gcfgfile, "/usr/local/etc/voipong/voipong.conf"); while (!error && (c = getopt(argc, argv, "c:d:hvf")) != -1) { switch(c) { case 'v': printf("%s %s\n", PROGRAM, VERSION); printf("Copyright (C) 2004 Murat Balaban \n" "All rights reserved.\n\n" "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version 2\n" "of the License, or (at your option) any later version.\n\n" "For more information on licensing, please see LICENSE\n" "file included in the voipong source distribution.\n"); exit(0); break; case 'h': usage(); exit(0); break; case 'f': gfg = 1; break; case 'd': gdbg = atoi(optarg); break; case 'c': strncpy(gcfgfile, optarg, sizeof(gcfgfile) - 2); break; default: printf("invalid option: %c, try -h for help\n", c); exit(EX_USAGE); } } init_config(); misc_setlogtype(gfg); misc_setlogdir(config_getval(&cfg, "GENERAL", "logdir")); misc_setlogfile(config_getval(&cfg, "GENERAL", "logfile")); misc_setloglevel(gdbg); printf("%s starting...\n", PROGRAM); printf("%s, running on %s\n\n", VERSION, misc_getunamestr(tmp, sizeof(tmp) - 2)); printf("%s\n", COPYRIGHT); daemon_init(); if (misc_openlog() < 0) { syslog(LOG_ERR, "misc_openlog: error!: %.128s", strerror(errno)); wexit(1); } misc_debug(0, "%s starting...\n", PROGRAM); misc_debug(0, "%s running on %s. %s [pid: %d]\n", VERSION, misc_getunamestr(tmp, 512), COPYRIGHT, getpid()); misc_debug(0, "Default matching algorithm: %s\n", gdefalg); init_voip(); init_workers(); init_vnet(); init_vocoders(); loadnetfile(gnetfile); if ((pcapfd = initpcap(1, gfilter, errbuf)) == -1) { misc_debug(0, "libpcap start failure: %s\n", errbuf); wexit(1); } add_to_select_set(pcapfd); if (open_server_socket() == -1) { misc_debug(0, "mgmt socket open failure!\n"); wexit(1); } sockets_run(); wexit(0); return 0; } void graceful_shutdown() { kill_workers(); wexit(0); } void reload() { } void init_config() { char errbuf[CONFERRBUFSIZ]; if ((config_load(&cfg, gcfgfile, errbuf)) == NULL) { fprintf(stderr, "init_config: %s\n", errbuf); wexit(1); } get_initcfgvals(); } void get_initcfgvals() { if (config_getstr(&cfg, "GENERAL", "mgmt_ipcpath", gmgmt_path, sizeof(gmgmt_path) -2) == 0) { printf("cannot get mgmtipcpath from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "pidfile", gpidfile, sizeof(gpidfile) - 2) == 0) { printf("cannot get pidfile from configfile, shutting down......\n"); exit(1); } if ((grtp_idle_time = config_getint(&cfg, "GENERAL", "rtp_idle_time", -1)) == -1) { printf("cannot get rtp_idle_time from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "outdir", goutdir, sizeof(goutdir) - 2) == 0) { printf("cannot get outdir from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "cdrfile", gcdrfile, sizeof(gcdrfile) - 2) == 0) { printf("cannot get cdrfile from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "soxpath", gsoxpath, sizeof(gsoxpath) - 2) == 0) { printf("cannot get soxpath from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "soxmixpath", gsoxmixpath, sizeof(gsoxmixpath) - 2) == 0) { printf("cannot get soxmixpath from configfile, shutting down......\n"); exit(1); } gsoxmixflag = config_getint(&cfg, "GENERAL", "mixwaves", 0); if (config_getstr(&cfg, "GENERAL", "defalg", gdefalg, sizeof(gdefalg) - 2) == 0) { printf("cannot get gdefalg from configfile, shutting down......\n"); exit(1); } if (config_getstr(&cfg, "GENERAL", "modpath", gmodpath, sizeof(gmodpath) - 2) == 0) { printf("cannot get modpath from configfile, shutting down......\n"); exit(1); } if (strcmp(gdefalg, "lfp") == 0) packet_handler_default = packet_handler_lfp; else if (strcmp(gdefalg, "lra") == 0) { printf("This matching algorithm is not implemented yet!\n"); /*packet_handler_default = packet_handler_lra; */ exit(1); } else { printf("Default packet matching algorithm should be selected: (lfp/lra) wrong input: %s\n", gdefalg); exit(1); } config_getstr(&cfg, "FILTERS", "startup_filter", gfilter, sizeof(gfilter) - 2); config_getstr(&cfg, "GENERAL", "device", gdevice, sizeof(gdevice) - 2); config_getstr(&cfg, "GENERAL", "networksfile", gnetfile, sizeof(gdevice) - 2); if ((gpromisc = config_getint(&cfg, "GENERAL", "promisc", -1)) == -1) { printf("cannot get promisc value from configfile, shutting down......\n"); exit(1); } if ((gsnaplen = config_getint(&cfg, "GENERAL", "snaplen", -1)) == -1) { printf("cannot get snaplen value from configfile, shutting down......\n"); exit(1); } if ((greadtmt = config_getint(&cfg, "GENERAL", "readtmt", -1)) == -1) { printf("cannot get readtmt value from configfile, shutting down......\n"); exit(1); } } void usage() { printf("usage: voipong [options]\n"); printf("\toptions:\n"); printf("\t\t-h this screen\n"); printf("\t\t-v version info\n"); printf("\t\t-f run in foreground (don't become a daemon)\n"); printf("\t\t-d debug level. Valid levels are 0 through 4. Default: 0\n"); printf("\t\t-c config file path\n"); printf("\n"); } void process_deadchild() { pid_t pid; int stat = 0; int termsig = 0, exitcode = 0; struct sigaction sa; worker *w; sigemptyset(&sa.sa_mask); sigaddset(&(sa.sa_mask), SIGCHLD); sigprocmask(SIG_BLOCK, &(sa.sa_mask), NULL); if ((pid = wait(&stat)) == -1) { misc_debug(0, "process_deadchild: wait error: %s\n", strerror(errno)); return; } if ((w = getworkerbypid(pid)) == NULL) { misc_debug(0, "I dont have a child with pid %d\n", pid); return; } if (WIFEXITED(stat)) misc_debug(0, "child [pid: %d] terminated normally [exit code: %d]\n", pid, (exitcode = WEXITSTATUS(stat))); else if (WIFSIGNALED(stat)) misc_debug(0, "child [pid: %d] terminated by signal %d\n", pid, (termsig = WTERMSIG(stat))); worker_remove(w); free(w); } voipong-2.0/voipongcdr.c0100644000175400000000000000314210346315716014366 0ustar muratwheel#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include #include extern char goutdir[256]; extern char gcdrfile[256]; void checkcdrfile() { struct stat st; FILE *fp; if (stat(gcdrfile, &st) == -1) if (errno == ENOENT) { if ((fp = fopen(gcdrfile, "a")) == NULL) { misc_debug(0, "checkcdrfile: fopen(%s): %s\n", gcdrfile, strerror(errno)); return; } writew_lock(fileno(fp)); fprintf(fp, "Start;End;Duration(seconds);Session Id;Party1 RTP Pair; Party 2 RTP Pair;Encoding;Rate\n"); fclose(fp); } } int add2cdr(worker *w) { FILE *fp; char stime[256]; char etime[256]; checkcdrfile(); if ((fp = fopen(gcdrfile, "a")) == NULL) { misc_debug(0, "add2cdr: fopen(%s): %s\n", gcdrfile, strerror(errno)); return -1; } writew_lock(fileno(fp)); misc_strftimegiven(stime, sizeof(stime) - 2, "%a %b %d %H:%M:%S %Y", w->stime); misc_strftimegiven(etime, sizeof(etime) - 2, "%a %b %d %H:%M:%S %Y", w->etime); fprintf(fp, "%s;%s;%d;%d;%s:%d;%s:%d;%d;%d\n", stime, etime, (w->etime - w->stime), getpid(), misc_inet_ntoa(w->rtp->ip1), w->rtp->port1, misc_inet_ntoa(w->rtp->ip2), w->rtp->port2, w->rtp->enc, w->rtp->rate); fclose(fp); return 0; } voipong-2.0/voipongcodec.c0100644000175400000000000001053010345252354014667 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. Decoder Modules Interfaces 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include #include #include #include extern char gmodpath[256]; vocoder vocoders[MAXCODECS]; int vocoder_default(int fd, u_char *pl, int len) { if (write(fd, pl, len) < len) { misc_debug(0, "dumppl_default: write: %s\n", strerror(errno)); return -1; } return len; } void getmodinitfunc(char *initstr, short initlen, char *mpath) { int i = 0, j = 0; char modname[128]; for (i = strlen(mpath) - 1, j = 0; i > 0 && j < sizeof(modname) - 6; i--) { if (mpath[i] == '/') break; modname[j++] = mpath[i]; } modname[j] = '\0'; misc_strrev(modname, strlen(modname)); strncpy(initstr, modname, initlen - 6); memcpy(initstr + (strlen(initstr) - 3), "_init", 5); } int loadmodule(char *path) { void * ld; const char *errstr = NULL; char initstr[128]; vocoder_t * (*f) (vocoder vocoders[]); void *addr = NULL; if ((ld = dlopen(path, RTLD_NOW)) == NULL) { misc_debug(0, "loadmodule: dlopen(%s): %s\n", path, dlerror()); return -1; } getmodinitfunc(initstr, sizeof(initstr) - 2, path); f = dlsym(ld, initstr); if ((errstr = dlerror()) != NULL) { misc_debug(0, "loadmodule (%s): dlsym: %s\n", path, errstr); dlclose(ld); return -1; } addr = (*f) (vocoders); misc_debug(0, "loadmodule: %s (@%p)\n", path, addr); return 0; } /* Try to avoid some "really nasty" actions... */ int securemod(struct stat *st, char *fname) { if (strlen(fname) < 7) { misc_debug(0, "error: securemod(%s): invalid module naming", fname); return 0; } if (st->st_uid != getuid()) { misc_debug(0, "error: securemod(%s): uid: got %d, expected %d\n", fname, st->st_uid, getuid()); return 0; } if (st->st_gid != getgid()) { misc_debug(0, "error: securemod(%s): gid: got %d, expected %d\n", fname, st->st_gid, getgid()); return 0; } if (st->st_mode & S_IWGRP) { misc_debug(0, "error: securemod(%s): module has group-writable bit set\n", fname); return 0; } if (st->st_mode & S_IWOTH) { misc_debug(0, "error: securemod(%s): module has world-writable bit set\n", fname); return 0; } if (S_ISLNK(st->st_mode)) { misc_debug(0, "error: securemod(%s): module cannot be a symbolic link\n", fname); return 0; } return 1; } void init_vocoders() { char fname[1024]; DIR *dirp; struct dirent *dp; int i = 0; struct stat st; int cnt = 0; for (i = 0; i < MAXCODECS; i++) { vocoders[i].f = vocoder_default; vocoders[i].rate = 0; } if ((dirp = opendir(gmodpath)) == NULL) { misc_debug(0, "init_vocoders: cannot open modules dir %s: %s\n", gmodpath, strerror(errno)); return; } while((dp = readdir(dirp)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0 || (memcmp(dp->d_name, "mod", 3) != 0)) continue; snprintf(fname, sizeof(fname) - 2, "%s/%s", gmodpath, dp->d_name); stat(fname, &st); if (S_ISREG(st.st_mode)) if (securemod(&st, fname)) if (loadmodule(fname) == 0) cnt++; } misc_debug(0, "loaded %d module(s)\n", cnt); } voipong-2.0/COPYING0100644000175400000000000003536010325230257013103 0ustar muratwheel GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. voipong-2.0/voipongfixed.c0100644000175400000000000000455410336157114014720 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. "Fixed Pcap-Capture-String" Algorithm This is useful for catching dummy IP adapters, which has neither signalling nor RTCP, RTSP, but always use fixed port numbers. In voipongnet.conf file, the user is expected to supply a pcap filter string: (e.g. "port 40000 and udp"). */ #include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include #include /* * #include */ #include #include #include extern char gdevice[256]; extern char gfilter[1024]; extern int gpromisc; extern int gsnaplen; extern int greadtmt; void packet_handler_fixed(vnet *v, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *ip; struct udphdr *udp; short iphlen; rtcp_session *rtcp = NULL; ip = (struct ip *)packet; iphlen = ip->ip_hl << 2; if (ip->ip_p != IPPROTO_UDP) return; udp = (struct udphdr *)(packet + iphlen); if (udp->uh_sport == v->fixport || udp->uh_dport == v->fixport) { if (worker_isexist(ip->ip_src.s_addr, ip->ip_dst.s_addr, ntohs(udp->uh_sport), ntohs(udp->uh_dport))) return; if (create_rtp_instance(&rtcp, udata, pkthdr, packet) == -1) misc_debug(0, "packet_handler_fixed: failed creating rtp instance\n"); } } voipong-2.0/voipongglobals.c0100644000175400000000000000303210344576327015244 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ #include #include #include #include /* GLOBALS */ config cfg; int gfg = 0; int gdbg = 0; char gcfgfile[128]; char gmgmt_path[128]; char gmodpath[256]; int grtp_idle_time = 0; int gthisday = 0; int gthismon = 0; time_t gstarttime = 0; int mgmt_client = 0; int gmgmtport = 0; char gsoxpath[256]; char gsoxmixpath[256]; int gsoxmixflag = 0; char gpidfile[128]; char goutdir[256]; char gnetfile[256]; char gcdrfile[256]; char gdefalg[256]; int pcapfd = -1, mgmtfd = -1; char gdevice[256]; char gfilter[1024]; int gpromisc = 1; int gsnaplen = 1; int greadtmt = 1; rtp_session *rtps = NULL; void (*packet_handler_default) (vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); voipong-2.0/voiponglfp.c0100644000175400000000000000421510336157114014374 0ustar muratwheel/* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. "Least False Positive" Algorithm This will try to catch calls that are compliant with the RTP and RTCP RFCs. Note that this algorithm was the default call-catching algorithm prior to version 1.2 and may not catch calls that are not RFC-compliant at all. */ #include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include #include #include #include extern char gdevice[256]; extern char gfilter[1024]; extern int gpromisc; extern int gsnaplen; extern int greadtmt; void packet_handler_lfp(vnet *v, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *ip; struct udphdr *udp; short iphlen = 0; ip = (struct ip *)packet; iphlen = ip->ip_hl << 2; if (ip->ip_p != IPPROTO_UDP) return; udp = (struct udphdr *)(packet + iphlen); if (isodd(ntohs(udp->uh_sport)) && isodd(ntohs(udp->uh_dport))) probertcp(udata, pkthdr, packet); else if (iseven(ntohs(udp->uh_sport)) && iseven(ntohs(udp->uh_dport))) probertp(udata, pkthdr, packet); } voipong-2.0/voipongmgmt.c0100644000175400000000000002337010336157114014562 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern config cfg; extern int gdbg; extern time_t gstarttime; extern int gsoxmixflag; extern char gcfgfile[]; extern char gnetfile[]; extern rtp_session *rtps; extern worker *workers[MAXNODE]; extern rtcp_session *rtcps[MAXNODE]; static int mgmtfd = -1; static int mgmtconnected = 0; static int authok = 0; static int passtries = 0; static FILE *fp; static void uptime() { char str[512]; fprintf(fp, "+OK %s\n", misc_getuptimestr(str, sizeof(str) - 1, gstarttime)); } static void loadnets() { free_vnet(); if (loadnetfile(gnetfile) != 0) { fprintf(fp, "-ERR cannot load voipongnets file!\n"); misc_debug(0, "mgmt: loadnets: cannot load voipongnets file!\n"); return; } fprintf(fp, "+OK networks file has been reloaded.\n"); } static void killcall(char *line) { char sid[128]; int nsid; if (strlen(line) < 9) return; strncpy(sid, line + 9, sizeof(sid) - 2); if ((nsid = atoi(sid)) < 2) { fprintf(fp, "+ERR Invalid session ID: %d\n", nsid); return; } if (getworkerbypid(nsid) == NULL) { fprintf(fp, "+ERR No such session by ID: %d\n", nsid); return; } kill(nsid, SIGTERM); fprintf(fp, "+OK Sent deadly signal to session %d\n", nsid); } static void setdebug(char *line) { char dl[128]; int ndl; if (strlen(line) < 9) return; strncpy(dl, line + 9, sizeof(dl) - 2); if ((ndl = atoi(dl)) < 0 || ndl > 4) { fprintf(fp, "+ERR Invalid debug level: %d, valid levels are 0 through 4\n", ndl); return; } gdbg = ndl; misc_setloglevel(ndl); fprintf(fp, "+OK set new debug level to %d\n", ndl); misc_debug(0, "mgmt_console: set new debug level to %d\n", ndl); } static void setmixflag(char *line) { char dl[128]; int ndl; if (strlen(line) < 10) return; strncpy(dl, line + 10, sizeof(dl) - 2); ndl = atoi(dl); gsoxmixflag = (ndl ? 1 : 0); fprintf(fp, "+OK set mixflag to %d\n", ndl); misc_debug(0, "mgmt_console: set mixflag to %d\n", gsoxmixflag); } static void shrtcp() { int i = 0; char tstr[64]; char ipstr1[32]; char ipstr2[32]; time_t now; rtcp_session *w; int j = 0; fprintf(fp, "+OK +\n"); fprintf(fp, "\n\n"); fprintf(fp, "%-5.5s %-16.16s %s %-16.16s %s %-17.17s\n", "ID", "NODE1", "PORT1", "NODE2", "PORT2", "STIME"); fprintf(fp, "----- ---------------- ----- ---------------- ----- -----------------\n"); time(&now); for (i = 0; i < MAXNODE; i++) { for (w = rtcps[i]; w != NULL; w = w->next, i++) { j++; misc_strftimegiven(tstr, sizeof(tstr) - 2, "%d/%m/%y %H:%M:%S", w->stime); snprintf(ipstr1, sizeof(ipstr1) - 2, "%s", misc_inet_ntoa(w->ip1)); snprintf(ipstr2, sizeof(ipstr2) - 2, "%s", misc_inet_ntoa(w->ip2)); fprintf(fp, "%05d %-16.16s %05d %-16.16s %05d %-17.17s\n", j, ipstr1, w->port1, ipstr2, w->port2, tstr); } } fprintf(fp, "\n"); fprintf(fp, "Total listed: %d\n", j); fprintf(fp, "+OK .\n"); fflush(fp); } static void shcall() { int i = 0; char tstr[64]; char ipstr1[32]; char ipstr2[32]; time_t now; worker *w; int j = 0; fprintf(fp, "+OK +\n"); fprintf(fp, "\n\n"); fprintf(fp, "%-5.5s %-16.16s %s %-16.16s %s %-17.17s %-12.12s\n", "ID", "NODE1", "PORT1", "NODE2", "PORT2", "STIME", "DURATION"); fprintf(fp, "----- ---------------- ----- ---------------- ----- ----------------- ------------\n"); time(&now); for (i = 0; i < MAXNODE; i++) { for (w = workers[i]; w != NULL; w = w->next, i++) { j++; misc_strftimegiven(tstr, sizeof(tstr) - 2, "%d/%m/%y %H:%M:%S", w->rtp->stime); snprintf(ipstr1, sizeof(ipstr1) - 2, "%s", misc_inet_ntoa(w->rtp->ip1)); snprintf(ipstr2, sizeof(ipstr2) - 2, "%s", misc_inet_ntoa(w->rtp->ip2)); fprintf(fp, "%05d %-16.16s %05d %-16.16s %05d %-17.17s %d seconds\n", w->pid, ipstr1, w->rtp->port1, ipstr2, w->rtp->port2, tstr, (now - (int)w->rtp->stime) ); } } fprintf(fp, "\n"); fprintf(fp, "Total listed: %d\n", j); fprintf(fp, "+OK .\n"); fflush(fp); } static void info() { struct passwd *pwd; char tmp[512]; fprintf(fp, "+OK +\n"); fprintf(fp, "General Server Info:\n"); fprintf(fp, "--------------------------:\n"); fprintf(fp, "Server version : %s\n", VERSION); fprintf(fp, "System : %s\n", misc_getunamestr(tmp, sizeof(tmp) - 2)); getcwd(tmp, sizeof(tmp) - 2); fprintf(fp, "Current work. direct. : %s\n", tmp); fprintf(fp, "Log level : %d\n", gdbg); fprintf(fp, "Mix Voice Flag : %s\n", (gsoxmixflag ? "true" : "false")); fprintf(fp, "Process ID (PID) : %d\n", getpid()); pwd = getpwuid(getuid()); fprintf(fp, "User : %s [%s]\n", pwd->pw_name, pwd->pw_gecos); fprintf(fp, "Group : %d\n", pwd->pw_gid); fprintf(fp, "+OK .\n"); fflush(fp); } int rusage() { struct rusage ru; if (getrusage(RUSAGE_SELF, &ru) < 0) { misc_debug(0, "mgmt_console: rusage error : %s\n", strerror(errno)); fprintf(fp, "+ERR mgmt_console: rusage error : %s\n", strerror(errno)); return -1; } fprintf(fp, "+OK +\n"); fprintf(fp, "Current CPU usage stats:\n"); fprintf(fp, "----------------------------------------\n"); fprintf(fp, "Total \"user\" time : %ld seconds\n", ru.ru_utime.tv_sec); fprintf(fp, "Total used \"system\" time : %ld seconds\n", ru.ru_stime.tv_sec); fprintf(fp, "Shared Memory Size : %ld KB\n", ru.ru_ixrss); fprintf(fp, "Integral Memory Size : %ld KB\n", ru.ru_idrss); fprintf(fp, "Integral stack Size : %ld KB\n", ru.ru_isrss); fprintf(fp, "Page requests : %ld\n", ru.ru_minflt); fprintf(fp, "Page errors : %ld\n", ru.ru_majflt); fprintf(fp, "Block input operations : %ld\n", ru.ru_inblock); fprintf(fp, "Block output operations : %ld\n", ru.ru_oublock); fprintf(fp, "Messages sent : %ld\n", ru.ru_msgsnd); fprintf(fp, "Messages received : %ld\n", ru.ru_msgrcv); fprintf(fp, "Signals : %ld\n", ru.ru_nsignals); fprintf(fp, "Voluntary \"context switch\"s : %ld\n", ru.ru_nvcsw); fprintf(fp, "Involuntary \"context switch\"s : %ld\n", ru.ru_nivcsw); fprintf(fp, "+OK .\n"); fflush(fp); return 0; } int is_mgmt_active() { return mgmtconnected; } int get_mgmt_fd() { return mgmtfd; } void accept_mgmt_client(int fd) { struct sockaddr_in cin; size_t len; int nsd; int flags; char tmp[512]; len = sizeof(cin); memset(&cin, 0, sizeof(cin)); if ((nsd = accept(fd, (void *)&cin, &len)) < 0) { misc_debug(0, "accept_mgmt_client: accept error: %s\n", strerror(errno)); return; } flags = fcntl(nsd, F_GETFL, 0); fcntl(nsd, F_SETFL, flags | O_NONBLOCK); if (is_mgmt_active() == 1) close_mgmt_client(); misc_debug(0, "New management console request has been accepted!\n"); if ((fp = fdopen(nsd, "r+")) == NULL) { misc_debug(0, "MGMT: fdopen: %s\n", strerror(errno)); return; } mgmtconnected = 1; mgmtfd = nsd; add_to_select_set(mgmtfd); misc_getunamestr(tmp, sizeof(tmp) - 2); fprintf(fp, "+OK %s\r\n", tmp); fflush(fp); } void process_mgmt_request() { char line[1024]; if ((fgets(line, sizeof(line) - 2, fp)) == NULL) { misc_debug(0, "process_mgmt_read: fgets error: %s\n", strerror(errno)); close_mgmt_client(); return; } misc_trimnewline(line, strlen(line)); if (memcmp(line, "UPTIME", 6) == 0) uptime(); else if (memcmp(line, "LOGROTATE", 9) == 0) { if (misc_rotatelog() < 0) fprintf(fp, "+ERR logrotate error!\n"); else fprintf(fp, "+OK logrorate successfull!\n"); } else if (memcmp(line, "SHUTDOWN", 8) == 0) { fprintf(fp, "+OK SHUTDOWN received!, shutting down the server!!!\n\n"); graceful_shutdown(); return; } else if (memcmp(line, "RUSAGE", 6) == 0) rusage(); else if (memcmp(line, "LOADNETS", 8) == 0) loadnets(); else if (memcmp(line, "INFO", 4) == 0) info(); else if (memcmp(line, "SHCALL", 6) == 0) shcall(); else if (memcmp(line, "SHRTCP", 6) == 0) shrtcp(); else if (memcmp(line, "KILLCALL", 8) == 0) killcall(line); else if (memcmp(line, "SETDEBUG", 8) == 0) setdebug(line); else if (memcmp(line, "SETMIXFLAG", 10) == 0) setmixflag(line); else if (memcmp(line, "CLOSESESSION", 12) == 0) { fprintf(fp, "+OK bye bye\n"); fflush(fp); close_mgmt_client(); } else fprintf(fp, "+ERR Invalid command in protocol\n"); fflush(fp); } void close_mgmt_client() { misc_debug(0, "Shutting down management console...\n"); close(mgmtfd); remove_from_select_set(mgmtfd); mgmtconnected = 0; mgmtfd = -1; authok = 0; passtries = 0; } voipong-2.0/voipongnet.c0100644000175400000000000001137710326423224014405 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vnet *allnets[256]; extern config conf; extern int pcapfd, mgmtfd; void init_vnet() { int i = 0; for ( ; i < 256; i++) allnets[i] = NULL; } void free_vnet() { int i = 0; vnet *v = NULL; for (i = 0; i < 256; i++) while ((v = allnets[i]) != NULL) { allnets[i] = v->next; free(v); } } void add_vnet(int ip, int mask, int algo, char *opts) { vnet *v = NULL; int h = ip & 0x000000ff; if ((v = malloc(sizeof(vnet))) == NULL) { misc_debug(0, "add_vnet: malloc: %s\n", strerror(errno)); return; } switch(algo) { case ALGORITHM_LRA: misc_debug(0, "add_vnet: lra algorithm is not implemented, defaulting to lfp\n"); case ALGORITHM_LFP: v->op = packet_handler_lfp; break; case ALGORITHM_FIXED: v->op = packet_handler_fixed; break; default: v->op = packet_handler_lfp; break; } v->addr = ip; v->mask = mask; v->fixport = htons(atoi(opts)); v->next = allnets[h]; allnets[h] = v; } vnet * get_vnet(int ip) { int h; vnet *v; h = ip & 0x000000ff; for (v = allnets[h]; v != NULL; v = v->next) if ((ip & v->mask) == v->addr) return v; return NULL; } int loadnetfile(char *netfile) { FILE *fp = NULL; char line[1024]; char strip[24], strmask[24], stralgo[24], stropts[128]; int i = 0, j = 0, k = 0, buflen = 0, nalgo = 0; if ((fp = fopen(netfile, "r")) == NULL) { misc_debug(0, "loadnetfile: fopen(%s): %s\n", netfile, strerror(errno)); return -1; } while(fgets(line, sizeof(line) - 1, fp) != NULL) { k++; i = 0, j = 0, buflen = 0; memset(strip, 0x0, sizeof(strip)); memset(strmask, 0x0, sizeof(strmask)); memset(stralgo, 0x0, sizeof(stralgo)); memset(stropts, 0x0, sizeof(stropts)); buflen = strlen(line); /* skip white space */ while(i < buflen && !isgraph(line[i])) i++; if (line[i] == '#') continue; while (i < buflen && isgraph(line[i]) && j < sizeof(strip) - 1 && line[i] != '/') strip[j++] = line[i++]; strip[j] = '\0'; if (strlen(strip) == 0) { misc_debug(0, "loadnetfile: parse error at line %d, cannot get ip\n", k); continue; } i++; j = 0; while (i < buflen && isgraph(line[i]) && j < sizeof(strmask) - 1) strmask[j++] = line[i++]; strmask[j] = '\0'; if (strlen(strmask) == 0) { misc_debug(0, "loadnetfile: parse error at line %d, cannot get mask\n", k); continue; } /* skip white space */ while(i < buflen && !isgraph(line[i])) i++; j = 0; while (i < buflen && isgraph(line[i]) && j < sizeof(stralgo) - 1) stralgo[j++] = line[i++]; stralgo[j] = '\0'; if (strlen(stralgo) == 0) { misc_debug(0, "loadnetfile: parse error at line %d, cannot get algorithm\n", k); continue; } if (strcmp(stralgo, "fixed") == 0) { if (strcmp(strmask, "255.255.255.255") != 0) { misc_debug(0, "loadnetfile: fixed algorithm can only by used with hosts, not networks\n"); continue; } while(i < buflen && !isgraph(line[i])) i++; j = 0; while (i < buflen && isgraph(line[i]) && j < sizeof(stropts) - 1) stropts[j++] = line[i++]; stropts[j] = '\0'; if (strlen(stropts) == 0) { misc_debug(0, "loadnetfile: parse error at line %d, cannot get port number for fixed algorithm\n", k); continue; } } if (strcmp(stralgo, "lfp") == 0) nalgo = ALGORITHM_LFP; else if (strcmp(stralgo, "lra") == 0) nalgo = ALGORITHM_LRA; else if (strcmp(stralgo, "fixed") == 0) nalgo = ALGORITHM_FIXED; misc_debug(0, "loadnet(%s/%s) method: %s %s\n", strip, strmask, stralgo, stropts); add_vnet(inet_addr(strip), inet_addr(strmask), nalgo, stropts); } fclose(fp); return 0; } voipong-2.0/voipongpcap.c0100644000175400000000000001106510346315716014544 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2005 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include /* * #include */ #include #include #include #define MINPACKETSIZ (getdllen() + sizeof(struct ip) + sizeof(struct udphdr) + 20) static pcap_t *pd = NULL; static int dllen = 14; static voipstat stats; extern char gdevice[256]; extern char gfilter[1024]; extern int gpromisc; extern int gsnaplen; extern int greadtmt; extern void (*packet_handler_default) (vnet *, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet); pcap_t * getpcapt() { return pd; } voipstat * getstats() { return &stats; } void setstats(voipstat *s) { memcpy(&stats, s, sizeof(voipstat)); } int initpcap(int verbose, char *filter, char *errbuf) { bpf_u_int32 netp; bpf_u_int32 maskp; char netstr[64], maskstr[64]; struct bpf_program fprog; struct in_addr in; char *dev; char perrbuf[PCAP_ERRBUF_SIZE]; if (strlen(gdevice) == 0) { if ((dev = pcap_lookupdev(perrbuf)) == NULL) { snprintf(errbuf, ERRBUFSIZ - 2, "cannot find any available device to sniff on: %s\n", perrbuf); return -1; } strncpy(gdevice, dev, sizeof(gdevice) - 2); } if ((pd = pcap_open_live(gdevice, gsnaplen, gpromisc, greadtmt, perrbuf)) == NULL) { snprintf(errbuf, ERRBUFSIZ - 2, "pcap_open_live: %s\n", perrbuf); return -1; } pcap_lookupnet(gdevice, &netp, &maskp, perrbuf); in.s_addr = netp; strncpy(netstr, inet_ntoa(in), sizeof(netstr) - 2); in.s_addr = maskp; strncpy(maskstr, inet_ntoa(in), sizeof(maskstr) - 2); switch(pcap_datalink(pd)) { case DLT_EN10MB: dllen = 14; break; case DLT_IEEE802: dllen = 22; break; case DLT_FDDI: dllen = 21; break; case DLT_PPP: dllen = 12; break; case DLT_NULL: dllen = 4; break; } if (verbose) misc_debug(0, "%s has been opened in %s mode. (%s/%s)\n", gdevice, (gpromisc ? "promisc" : "non-promisc"), netstr, maskstr); if (strlen(filter) > 0) { pcap_compile(pd, &fprog, filter, 0, netp); pcap_setfilter(pd, &fprog); pcap_freecode(&fprog); if (pcap_setnonblock(pd, 1, perrbuf) == -1) { misc_debug(0, "pcap_setnonblock: %s\n", perrbuf); wexit(1); } } return pcap_fileno(pd); } void peekpcap(int cnt, pcap_handler phandler) { while (pcap_dispatch(pd, cnt, phandler, (u_char *)dllen) != 0) ; } int getdllen() { return dllen; } void packet_handler(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { int offset = (int)udata; struct ip *ip; struct udphdr *udp; vnet *v; if (pkthdr->len < MINPACKETSIZ) return; ip = (struct ip *)(packet + offset); if (ip->ip_p == IPPROTO_UDP) { udp = (struct udphdr *)(packet + offset + sizeof(struct ip)); if (ntohs(udp->uh_sport) < 5000 || ntohs(udp->uh_dport) < 5000) return; } if ((v = get_vnet(ip->ip_src.s_addr)) == NULL) if ((v = get_vnet(ip->ip_dst.s_addr)) == NULL) { (packet_handler_default) (NULL, udata, pkthdr, (const u_char *)ip); return; } (v->op) (v, udata, pkthdr, (const u_char *)ip); } /* "Least Run-Away" Algorithm * * This *new* one has been designed to catch calls, impossible to catch with the default * algorithm, which tries to minimize false positives. * * So, if your network routes non RFC-compliant calls, and you cannot catch them with L.F.P, * you should give this a try. * */ void packet_handler_lra(vnet *v, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { misc_debug(0, "! lra not implemented yet !\n"); } voipong-2.0/voipongsign.c0100644000175400000000000000421710346315716014562 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include extern void wexit(int); extern int gmainprocess; void sigint_handler() { misc_debug(0, "INTERRUPT signal caught, starting shutdown procedures...\n"); wexit(0); } void sigusr2_handler() { } void sigalrm_handler() { } void sigterm_handler() { misc_debug(0, "SHUTDOWN signal caught, starting shutdown procedures...\n"); graceful_shutdown(); wexit(0); } void sigworkeralrm_handler() { } void sigworkerterm_handler() { misc_debug(0, "SHUTDOWN signal caught, starting shutdown procedures...\n"); worker_graceful_exit(0); } void sighandler(int signal) { switch(signal) { case SIGCHLD: process_deadchild(); break; case SIGINT: sigterm_handler(); break; case SIGTERM: sigterm_handler(); break; case SIGKILL: sigterm_handler(); break; case SIGPIPE: break; case SIGALRM: sigalrm_handler(); break; case SIGUSR2: sigusr2_handler(); break; default: break; } } void sigworkerhandler(int signal) { switch(signal) { case SIGINT: case SIGTERM: sigworkerterm_handler(); break; case SIGPIPE: break; case SIGALRM: sigworkeralrm_handler(); break; default: break; } } voipong-2.0/voipongsock.c0100644000175400000000000000712310341136003014541 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern char gmgmt_path[128]; extern int pcapfd; static fd_set allset; static int mgmtfd = -1; int getmaxfd() { int maxfd; int mfd = get_mgmt_fd(); if (mgmtfd > pcapfd) maxfd = mgmtfd; else maxfd = pcapfd; if (mfd > maxfd) return mfd; else return maxfd; } void initsock() { FD_ZERO(&allset); } void add_to_select_set(int sd) { FD_SET(sd, &allset); } void remove_from_select_set(int sd) { FD_CLR(sd, &allset); } int open_server_socket() { struct sockaddr_un sun; int flags; int optval = 1; memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_LOCAL; /* TODO */ strncpy(sun.sun_path, gmgmt_path, 96); if (unlink(gmgmt_path) == -1) { if (errno != ENOENT) { misc_debug(0, "cannot delete mmgt IPC mgmt_path %s: %s\n", gmgmt_path, strerror(errno)); return -1; } } if ((mgmtfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { misc_debug(0, "cannot create mgmt server socket: %s\n", strerror(errno)); return -1; } if (setsockopt(mgmtfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { misc_debug(0, "cannot set SO_REUSEADDR socket option: %s\n", strerror(errno)); return -1; } /* Set socket mode non-blocking */ flags = fcntl(mgmtfd, F_GETFL, 0); fcntl(mgmtfd, F_SETFL, flags | O_NONBLOCK); if (bind(mgmtfd, (void *)&sun, sizeof(sun)) < 0) { misc_debug(0, "cannot bind to mgmt server mgmt_path %s: %s\n", gmgmt_path, strerror(errno)); return -1; } if (listen(mgmtfd, 128) < 0) { misc_debug(0, "cannot listen server mgmt_path %s: %s\n", gmgmt_path, strerror(errno)); return -1; } /* TODO */ if (chmod(gmgmt_path, 0700) == -1) { misc_debug(0, "cannot chmod mgmt_ipcpath[%s]: %s\n", gmgmt_path, strerror(errno)); return -1; } add_to_select_set(mgmtfd); return 0; } void sockets_run(void) { fd_set rset; struct timeval tv; int nready; tv.tv_sec = 1; tv.tv_usec = 0; for ( ; ; ) { rset = allset; if ((nready = select(getmaxfd() + 1, &rset, NULL, NULL, &tv)) < 0) { if (errno == EINTR) continue; misc_debug(0, "select: %s\n", strerror(errno)); continue; } if (FD_ISSET(mgmtfd, &rset)) { accept_mgmt_client(mgmtfd); nready--; } if (nready > 0 && FD_ISSET(pcapfd, &rset)) { peekpcap(100, packet_handler); nready--; } if (nready > 0 && is_mgmt_active()) { if (FD_ISSET(get_mgmt_fd(), &rset)) { process_mgmt_request(); nready--; } } } } voipong-2.0/voipongvoip.c0100644000175400000000000001166010345253663014600 0ustar muratwheel#include #include #include #include #include #include #include #include #include #include #include #define __USE_BSD 1 #define __FAVOR_BSD 1 #include #include #include #include #include #include #include extern char goutdir[256]; struct rtcp_session *rtcps[MAXNODE]; /* !!! Port Numbers are in Host Byte Order !!! */ rtcp_session * getrtcppair(u_int32_t ip1, u_int16_t port1, u_int32_t ip2, u_int16_t port2) { rtcp_session *rtcp = NULL; int h = 0; h = tuplehash(ip1, ip2, port1, port2); for (rtcp = rtcps[h]; rtcp != NULL; rtcp = rtcp->next) { if ((rtcp->ip1 == ip1 || rtcp->ip2 == ip1) && (rtcp->ip2 == ip2 || rtcp->ip1 == ip2) && (rtcp->port1 == port1 || rtcp->port2 == port1) && (rtcp->port2 == port2 || rtcp->port1 == port2)) return rtcp; } return NULL; } void removertcp(rtcp_session *in) { rtcp_session *rtcp; rtcp_session *prev = NULL; int h = 0; if (in == NULL) return; h = tuplehash(in->ip1, in->ip2, in->port1, in->port2); for (rtcp = rtcps[h]; rtcp != NULL; rtcp = rtcp->next) { if (rtcp->ip1 == in->ip1 && rtcp->ip2 == in->ip2 && rtcp->port1 == in->port1 && rtcp->port2 == in->port2) { if (prev == NULL) { rtcps[h] = rtcp->next; free(rtcp); return; } else { prev->next = rtcp->next; free(rtcp); return; } } prev = rtcp; } } /* !!! Port Numbers are in Host Byte Order !!! */ void checkrtcps(u_int32_t ip1, u_int16_t port1, u_int32_t ip2, u_int16_t port2) { rtcp_session *rtcp = NULL; int h = 0; h = tuplehash(ip1, ip2, port1, port2); for (rtcp = rtcps[h]; rtcp != NULL; rtcp = rtcp->next) { if ((rtcp->ip1 == ip1 || rtcp->ip2 == ip1) && (rtcp->ip2 == ip2 || rtcp->ip1 == ip2) && (rtcp->port1 == port1 || rtcp->port2 == port1) && (rtcp->port2 == port2 || rtcp->port1 == port2)) return; } rtcp = (rtcp_session *)malloc(sizeof(rtcp_session)); memset(rtcp, 0x0, sizeof(rtcp_session)); rtcp->ip1 = ip1; rtcp->ip2 = ip2; rtcp->port1 = port1; rtcp->port2 = port2; time(&rtcp->stime); rtcp->next = rtcps[h]; rtcps[h] = rtcp; } unsigned int tuplehash(u_int32_t sip, u_int32_t dip, u_int16_t sp, u_int16_t dp) { unsigned int key; key = (unsigned int)(sip * dip * sp * dp); key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); return key % MAXNODE; } void probertcp(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *ip; struct udphdr *udp; u_char *rtcp; ip = (struct ip *)packet; udp = (struct udphdr *)(packet + sizeof(struct ip)); rtcp = (u_char *)(packet + sizeof(struct ip) + sizeof(struct udphdr)); if (rtcp[0] == 0x80 || rtcp[0] == 0x81) if (rtcp[1] == 0xc8 || rtcp[1] == 0xc9) checkrtcps(ip->ip_src.s_addr, ntohs(udp->uh_sport), ip->ip_dst.s_addr, ntohs(udp->uh_dport)); } void probertp(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *ip; struct udphdr *udp; rtcp_session *rtcp; ip = (struct ip *)packet; udp = (struct udphdr *)(packet + sizeof(struct ip)); if (worker_isexist(ip->ip_src.s_addr, ip->ip_dst.s_addr, ntohs(udp->uh_sport), ntohs(udp->uh_dport))) return; if ((rtcp = getrtcppair(ip->ip_src.s_addr, ntohs(udp->uh_sport) + 1, ip->ip_dst.s_addr, ntohs(udp->uh_dport) + 1)) == NULL) return; if (create_rtp_instance(&rtcp, udata, pkthdr, packet) == -1) misc_debug(0, "failed creating rtp instance\n"); } int create_rtp_instance(rtcp_session **rtcp, u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct ip *ip; struct udphdr *udp; struct rtphdr *rtp; worker *w; u_char *pl; int plen = 0; int iphlen = 0; ip = (struct ip *)packet; iphlen = ip->ip_hl << 2; udp = (struct udphdr *)(packet + iphlen); rtp = (struct rtphdr *)(packet + iphlen + UDP_L); pl = (u_char *)(packet + iphlen + UDP_L + RTP_L); plen = pkthdr->len - (getdllen() + iphlen + UDP_L + RTP_L); if ((w = (worker *)malloc(sizeof(worker))) == NULL) { misc_debug(0, "WARNING!!! cannot malloc worker instance: %s\n", strerror(errno)); return -1; } w->rtcp = *rtcp; if ((w->rtp = (rtp_session *)malloc(sizeof(rtp_session))) == NULL) { misc_debug(0, "WARNING!!! cannot malloc rtp_session storage for a worker instance: %s!\n", strerror(errno)); free(w); return -1; } w->rtp->ip1 = ip->ip_src.s_addr; w->rtp->ip2 = ip->ip_dst.s_addr; w->rtp->port1 = ntohs(udp->uh_sport); w->rtp->port2 = ntohs(udp->uh_dport); time(&w->stime); w->rtp->enc = rtp->pt; w->next = NULL; if (worker_create(&w, plen, pl) == -1) { misc_debug(0, "creating worker instance failed\n"); free(w); return -1; } misc_debug(4, "created a call recorder instance!\n"); return 0; } void init_voip() { int i = 0; for (i = 0; i < MAXNODE; i++) rtcps[i] = NULL; } voipong-2.0/voipongworker.c0100644000175400000000000003414010342034337015122 0ustar muratwheel /* VoIPong Voice Over IP Sniffer Copyright (C) 2004 Murat Balaban All rights reserved. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern char goutdir[256]; extern char gsoxpath[256]; extern char gsoxmixpath[256]; extern int grtp_idle_time; extern int gsoxmixflag; extern vocoder vocoders[MAXCODECS]; worker *workers[MAXNODE]; worker *curw = NULL; pid_t mypid = -1; static char *rtp_pt_desc[] = {"0-PCMU-8KHz", "1-1016-8KHz", "2-G726-32-8KHz", "3-GSM-8KHz", "4-G723.1-8KHz", "5-DVI4-8KHz", "6-DVI4-16KHz", "7-LPC-8KHz", "8-PCMA-8KHz", "9-G722-8KHz", "10-L16-44.1KHz", "11-L16-44.1KHz", "12-QCELP-8KHz", "13-CN-8KHz", "14-MPA-90KHz", "15-G728-8KHz", "16-DVI4-11KHz", "17-DVI4-22KHz", "18-G729-8KHz", "19-reserved", "20-unassigned", "21-unassigned", "22-unassigned", "23-unassigned", "24-unassigned", "25-CelB-90KHz", "26-JPEG-90KHz", "27-unassigned" }; int create_wave() { char outf1[1024]; char outf2[1024]; char mixout[1024]; char inrate[32]; char insize[4]; char indenc[4]; struct stat st; int outcnt = 0; if (vocoders[curw->rtp->enc].f == vocoder_default) { misc_debug(0, "[%d] create_wave: no modules have been loaded to decode payload type: %d\n", getpid(), curw->rtp->enc); misc_debug(0, "[%d] create_wave: leaving *.raw files untouched.\n", getpid()); return -1; } snprintf(inrate, sizeof(inrate) - 1, "%d", vocoders[curw->rtp->enc].rate); strcpy(insize, "-w"); strcpy(indenc, "-s"); strncpy(outf1, curw->file1name, sizeof(outf1) - 2); memcpy(outf1 + (strlen(outf1) - 4), ".wav", 4); if (stat(curw->file1name, &st) == 0) { if (exec_sox(inrate, insize, indenc, curw->file1name, outf1) == 0) { if (unlink(curw->file1name) == -1) misc_debug(0, "[%d] Cannot remove file [%s]: %s\n", mypid, curw->file1name, strerror(errno)); } else { misc_debug(0, "[%d] exec_sox failed!\n", mypid); return -1; } misc_debug(0, "[%d] .WAV file %s has been created successfully\n", mypid, outf1); outcnt++; } strncpy(outf2, curw->file2name, sizeof(outf2) - 2); memcpy(outf2 + (strlen(outf2) - 4), ".wav", 4); if (stat(curw->file2name, &st) == 0) { if (exec_sox(inrate, insize, indenc, curw->file2name, outf2) == 0) { if (unlink(curw->file2name) == -1) misc_debug(0, "[%d] Cannot remove file [%s]: %s\n", mypid, curw->file2name, strerror(errno)); } else { misc_debug(0, "[%d] exec_sox failed!\n", mypid); return -1; } misc_debug(0, "[%d] .WAV file %s has been created successfully\n", mypid, outf2); outcnt++; } if (gsoxmixflag && (outcnt > 1)) { strncpy(mixout, curw->file1name, sizeof(mixout) - 13); strcpy(mixout + (strlen(mixout) - 4), "-mixed.wav"); if (exec_soxmix(outf1, outf2, mixout) == 0) { misc_debug(0, "[%d] Mixed output files: %s\n", mypid, mixout); /* if(unlink(outf1) == -1) misc_debug(0, "[%d] Cannot remove file [%s]: %s\n", mypid, outf1, strerror(errno)); if(unlink(outf2) == -1) misc_debug(0, "[%d] Cannot remove file [%s]: %s\n", mypid, outf2, strerror(errno)); */ } else { misc_debug(0, "[%d] Could not mix output files: exec_soxmix failed!\n", mypid); } } return 0; } int exec_sox(char *rt, char *sz, char *dc, char *srcfile, char *dstfile) { pid_t pid, wpid; int stat = 0; int exitcode = 0; switch(pid = fork()) { case -1: misc_debug(0, "[%d] exec_sox: cannot fork new process to create .WAV file: %s\n", mypid, strerror(errno)); return -1; break; case 0: if (execl(gsoxpath, "sox", "-r", rt, sz, dc, srcfile, dstfile, NULL) == -1) { misc_debug(0, "[%d] execl(%s -r %s %s %s %s %s) error: %s\n", mypid, gsoxpath, rt, sz, dc, srcfile, dstfile, strerror(errno)); exit(100); } exit(1); break; default: if ((wpid = waitpid(pid, &stat, 0)) == -1) { misc_debug(0, "[%d] exec_sox: waitpid: %s\n", mypid, strerror(errno)); return -1; } if ((exitcode = WEXITSTATUS(stat)) != 0) { misc_debug(0, "[%d] exec_sox: sox helper process failed, return value: %d\n", mypid, exitcode); return -1; } else if (WIFSIGNALED(stat)) { misc_debug(0, "[%d] exec_sox: sox helper process recv'd siganal %d\n", mypid, pid, WTERMSIG(stat)); return -1; } break; } return 0; } int exec_soxmix(char *f1, char *f2, char *dstfile) { pid_t pid, wpid; int stat = 0; int exitcode = 0; switch(pid = fork()) { case -1: misc_debug(0, "[%d] exec_soxmix: cannot fork new process to create mixed .WAV file: %s\n", mypid, strerror(errno)); return -1; break; case 0: if (execl(gsoxmixpath, "soxmix", f1, f2, dstfile, NULL) == -1) { misc_debug(0, "[%d] execl(%s %s %s %s) error: %s\n", mypid, gsoxmixpath, f1, f2, dstfile, strerror(errno)); exit(100); } exit(1); break; default: if ((wpid = waitpid(pid, &stat, 0)) == -1) { misc_debug(0, "[%d] exec_soxmix: waitpid: %s\n", mypid, strerror(errno)); return -1; } if ((exitcode = WEXITSTATUS(stat)) != 0) { misc_debug(0, "[%d] exec_soxmix: soxmix helper process failed, return value: %d\n", mypid, exitcode); return -1; } else if (WIFSIGNALED(stat)) { misc_debug(0, "[%d] exec_soxmix: soxmix helper process recv'd siganal %d\n", mypid, pid, WTERMSIG(stat)); return -1; } break; } return 0; } void init_workers() { int i = 0; for (i = 0; i < MAXNODE; i++) workers[i] = NULL; } int worker_create(worker **w, int pllen, u_char *packet) { int h = 0; switch(((*w)->pid = fork())) { case -1: misc_debug(0, "worker_create: fork: %s\n", strerror(errno)); break; case 0: worker_main(*w, pllen, packet); exit(0); default: time(&(*w)->rtp->stime); h = tuplehash((*w)->rtp->ip1, (*w)->rtp->ip2, (*w)->rtp->port1, (*w)->rtp->port2); (*w)->next = workers[h]; workers[h] = (*w); break; } return (*w)->pid; } worker * getworkerbypid(pid_t pid) { worker *w; int i; for (i = 0; i < MAXNODE; i++) for (w = workers[i]; w != NULL; w = w->next) if (w->pid == pid) return w; return NULL; } int worker_isexist(u_int32_t ip1, u_int32_t ip2, u_int16_t port1, u_int16_t port2) { worker *w; int h; h = tuplehash(ip1, ip2, port1, port2); for (w = workers[h]; w != NULL; w = w->next) if ((ip1 == w->rtp->ip1 || ip1 == w->rtp->ip2) && (ip2 == w->rtp->ip1 || ip2 == w->rtp->ip2) && (port1 == w->rtp->port1 || port1 == w->rtp->port2) && (port2 == w->rtp->port1 || port2 == w->rtp->port2)) return 1; return 0; } void worker_remove(worker *in) { worker *w; worker *prev = NULL; int h = 0; /* Remove related RTCP session */ removertcp(in->rtcp); h = tuplehash(in->rtp->ip1, in->rtp->ip2, in->rtp->port1, in->rtp->port2); for (w = workers[h]; w != NULL; w = w->next) { if (in->pid == w->pid) { if (prev == NULL) workers[h] = w->next; else prev->next = w->next; } prev = w; } } void kill_workers() { worker *w = NULL; int i = 0; for (i = 0; i < MAXNODE; i++) for (w = workers[i]; w != NULL; w = w->next) if (w->pid > 1) { misc_debug(0, "Terminating session [%d]\n", w->pid); kill(w->pid, SIGTERM); } } void worker_main(worker *w, int pllen, u_char *payload) { char filterstr[512]; char errbuf[ERRBUFSIZ]; char strpt[32]; char tfmt[64]; char strip1[32]; char strip2[32]; int pd = -1; pcap_t *pcapptr; fd_set set; time_t tnow, tidle; struct timeval tv; struct sigaction sa, sa1; struct sigaction sa_old, sa_old1; sa.sa_handler = sigworkerhandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sigaction(SIGHUP, &sa, &sa_old); sigaction(SIGUSR2, &sa, &sa_old); sigaction(SIGTERM, &sa, &sa_old); sigaction(SIGINT, &sa, &sa_old); sigaction(SIGSTOP, &sa, &sa_old); sigaction(SIGQUIT, &sa, &sa_old); sigaction(SIGALRM, &sa, &sa_old); sa.sa_handler = SIG_IGN; sigemptyset(&sa1.sa_mask); sigaction(SIGCHLD, &sa1, &sa_old1); curw = w; mypid = getpid(); misc_strftime(tfmt, sizeof(tfmt) - 2, "%Y%m%d"); snprintf(strip1, sizeof(strip1) - 2, misc_inet_ntoa(w->rtp->ip1)); snprintf(strip2, sizeof(strip2) - 2, misc_inet_ntoa(w->rtp->ip2)); if (create_outpath() == -1) { misc_debug(0, "[%d] create_path failed!\n", mypid); exit(1); } if (w->rtp->enc > MAXCODECS) { misc_debug(0, "Encoding type %d is higher than MAXCODECS value [%d], giving up...\n", w->rtp->enc, MAXCODECS); exit(0); } if (w->rtp->enc > 27) snprintf(strpt, sizeof(strpt) - 2, "%d-unknown", w->rtp->enc); else snprintf(strpt, sizeof(strpt), "%s", rtp_pt_desc[w->rtp->enc]); snprintf(w->file1name, MAXLBUFSIZ - 2, "%s/%s/session-enc%s-%s,%d-%s,%d.raw", goutdir, tfmt, strpt, strip1, w->rtp->port1, strip2, w->rtp->port2); if ((w->ip1fd = creat(w->file1name, S_IRWXU)) == -1) { misc_debug(0, "[%d] Cannot create raw voice output file %s: %s\n", mypid, w->file1name, strerror(errno)); exit(1); } snprintf(w->file2name, MAXLBUFSIZ - 2, "%s/%s/session-enc%s-%s,%d-%s,%d.raw", goutdir, tfmt, strpt, strip2, w->rtp->port2, strip1, w->rtp->port1); if ((w->ip2fd = creat(w->file2name, S_IRWXU)) == -1) { misc_debug(0, "[%d] Cannot create raw voice output file %s: %s\n", mypid, w->file2name, strerror(errno)); exit(1); } switch(w->rtp->enc) { case PT_ULAW: w->rtp->rate = 8000; break; default: w->rtp->rate = 0; break; } misc_debug(0, "[%d] VoIP call has been detected.\n", mypid); misc_debug(0, "[%d] %s:%d <--> %s:%d\n", mypid, strip1, w->rtp->port1, strip2, w->rtp->port2); misc_debug(0, "[%d] Encoding %s, recording.......\n", mypid, strpt); /* Now, let's talk real bussiness ! */ /* First RTP packet, inherited from parent process */ vocoders[curw->rtp->enc].f (w->ip1fd, payload, pllen); /* Reopen pcap interface for a fixed port tuple ! */ snprintf(filterstr, sizeof(filterstr) - 2, "(host %s and port %d) and (host %s and port %d) and udp", strip1, w->rtp->port1, strip2, w->rtp->port2); if ((pd = initpcap(0, filterstr, errbuf)) == -1) { misc_debug(0, "[%d] initpcap: %s\n", mypid, errbuf); exit(1); } pcapptr = getpcapt(); tv.tv_sec = grtp_idle_time; tv.tv_usec = 0; time(&tnow); tidle = tnow; for ( ; ; ) { FD_ZERO(&set); FD_SET(pd, &set); switch(select(pd + 1, &set, NULL, NULL, &tv)) { case -1: misc_debug(0, "[%d] select: error: %s\n", mypid, strerror(errno)); exit(1); break; case 0: time(&tnow); if ((tnow - tidle) > grtp_idle_time) { misc_debug(0, "[%d] maximum idle time [%d secs] has been elapsed for this call, the call might have been ended.\n", mypid, grtp_idle_time); w->etime = time(&w->etime) - grtp_idle_time; if (create_wave() == 0) { unlink(curw->file1name); unlink(curw->file2name); } worker_graceful_exit(0); } break; default: time(&tidle); peekpcap(-1, dumprtppayload); break; } } exit(0); } void dumprtppayload(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { u_char *pl; int plen = 0; struct ip *ip; int fd = -1; int off = 0; int iphlen = 0; unsigned short padlen = 0; struct rtphdr *rtp; unsigned short cur_seq = 0; static unsigned short last_seq1 = 0, last_seq2 = 0; off = getdllen(); ip = (struct ip *)(packet + off); iphlen = ip->ip_hl << 2; rtp = (struct rtphdr *)(packet + off + iphlen + UDP_L); pl = (u_char *)(packet + off + iphlen + UDP_L + RTP_L); plen = pkthdr->len - (getdllen() + iphlen + UDP_L + RTP_L); if (rtp->pad) { /* If padding is enabled, calc real payload length */ padlen = (unsigned short)(pl[plen]); plen -= padlen; } /* printf("\n[-------- START RTP HEADER ----------]\n"); printf("Version : %d\n", rtp->ver); printf("Padding : %d\n", rtp->pad); printf("Extension : %d\n", rtp->ext); printf("CSRC count: %d\n", rtp->cc); printf("Mark : %d\n", rtp->mark); printf("Payload : %d\n", rtp->pt); printf("SeqNo : %d\n", rtp->seq); printf("Timestamp : %d\n", rtp->timestamp); printf("SSRC : %d\n", rtp->ssrc); printf("CSRC : %d\n", rtp->csrc); printf("[---------- END RTP HEADER ----------]\n"); */ /* Avoid duplicate packets */ cur_seq = ntohs(rtp->seq); if (cur_seq == last_seq1 || cur_seq == last_seq2) return; if (ip->ip_src.s_addr == curw->rtp->ip1) { fd = curw->ip1fd; last_seq1 = cur_seq; } else { fd = curw->ip2fd; last_seq2 = cur_seq; } vocoders[curw->rtp->enc].f (fd, pl, plen); } int create_outpath() { char tfmt[64]; char filefmt[512]; struct stat st; if (stat(goutdir, &st) == -1) if (errno == ENOENT) { if (mkdir(goutdir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) { misc_debug(0, "cannot create outputdir %s: %s\n", goutdir, strerror(errno)); return -1; } } misc_strftime(tfmt, sizeof(tfmt) - 1, "%Y%m%d"); snprintf(filefmt, sizeof(filefmt) - 2, "%s/%s", goutdir, tfmt); if (stat(filefmt, &st) == -1) if (errno == ENOENT) { if (mkdir(filefmt, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) { misc_debug(0, "cannot create daily outputdir %s: %s\n", filefmt, strerror(errno)); return -1; } } return 0; } void worker_graceful_exit(int code) { if (code == 0) add2cdr(curw); exit(code); } voipong-2.0/AUTHORS0100644000175400000000000000020310325230252013077 0ustar muratwheel EnderUNIX VoIPong is designed and developed by: * Murat Balaban [murat at enderunix dot org] EnderUNIX core team member voipong-2.0/ChangeLog0100644000175400000000000000572310344576472013637 0ustar muratwheel VOIPONG ChangeLog For a recent version of this file, please refer to: http://www.enderunix.org/voipong/voipong-devel/ChangeLog ------------------------------------------------------------------------------- 2.0 BETA [Last Update: Sun Nov 20 15:38:46 EET 2005 ------------------------------------------------------------------------------- - Introduced a framework, where specific algorithms can be specified based on CIDR addresses for perfect packet matching. This results in much more specialized call catching. Thus a configuration file will be used for the "netaddr - algorithm" specifications (voipongnets). - Introduced DSOM (Dynamic Shared Object Module) codec subsystem. Beginning with this release, voice codecs will no longer be linked statically into the voipong executable. Instead, Voice codecs (vocoders) will be compiled as seperate dynamic shared objects (.so). VoIPong will search those modules in its module directory and load them at runtime during server initialization. - Introduced "LFP" (Least False Positive) algorithm which was the only packet matcher in 1.1 as the default algorithm. - Introduced "FIXED" algorithm for situations where endpoints do not conform to RTP/RTCP RFCs and, do not send RTCP packets. If your endpoints do not do signalling but send RTP packets to a fixed UDP port, then you can use this algorithm. - A newly authored User's Manual available in .html and .sgml forms. - PCMU codec has been re-desgined and re-written. - Introduced voipctl command to connect to management console. - Security improvement: Management console is no longer bound to a TCP port, instead it's now bound to a UNIX domain socket. - Introduced a CDR log file (CSV style). All call summaries will be logged here. - G711 PCMA support has been added. - Output .Wav files can now be mixed for a single .Wav file. (via soxmix) - Startup filters can now be specified. - Improved packet demultiplexer - Improved output .WAV voice quality - Many bugfixes, performance improvements and clean-ups in RTP code - Improved job handling - Improved hash function - Management Console changes: - calllist command renamed to shcall - killsession command renamed to killcall - new command: shrtcp, which shows RTCP cache - new command: loadnets, to reload network-algorithm matching table - new command: setmixflag, to set mixflag This command will enable you to specify new network/algorithm matchings without restarting voipong. - voipong.conf, voipongnets will be copied to /usr/local/etc/voipong directory - fixed bug: avoid .WAV file creation for empty .RAW files - fixed bug: killsession bug - fixed bug: proper clean-ups are now done after sniffing worker process finishes up. ------------------------------------------------------------------------------- 1.1 [December 14, 2004] ------------------------------------------------------------------------------- - First public release