Skip to content

Commit

Permalink
Implement RTCP saving to pcap file. No analyze is done on RTCP just o…
Browse files Browse the repository at this point in the history
…nly save it to pcap.

It is possible to enable SIP + RTCP only. If RTP saving is enabled RTCP is automatically
saving too. RTCP port is inherited from RTP base port + 1.
  • Loading branch information
Martin Vit committed Oct 6, 2011
1 parent 4c5d71b commit 88d99e0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 11 deletions.
11 changes: 9 additions & 2 deletions calltable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
using namespace std;

extern int verbosity;
extern int opt_rtcp;
extern int opt_saveRAW; // save RTP payload RAW data?
extern int opt_saveWAV; // save RTP payload RAW data?
extern int opt_saveGRAPH; // save GRAPH data to graph file?
Expand Down Expand Up @@ -98,6 +99,10 @@ Call::~Call(){

for(i = 0; i < ipport_n; i++) {
ct->hashRemove(this->addr[i], this->port[i]);
if(opt_rtcp) {
ct->hashRemove(this->addr[i], this->port[i] + 1);
}

}

for(int i = 0; i < MAX_SSRC_PER_CALL; i++) {
Expand Down Expand Up @@ -819,7 +824,7 @@ Calltable::Calltable() {

/* add node to hash. collisions are linked list of nodes*/
void
Calltable::hashAdd(in_addr_t addr, unsigned short port, Call* call, int iscaller) {
Calltable::hashAdd(in_addr_t addr, unsigned short port, Call* call, int iscaller, int is_rtcp) {
u_int32_t h;
hash_node *node = NULL;

Expand All @@ -841,6 +846,7 @@ Calltable::hashAdd(in_addr_t addr, unsigned short port, Call* call, int iscaller
node->port = port;
node->call = call;
node->iscaller = iscaller;
node->is_rtcp = is_rtcp;
node->next = (hash_node *)calls_hash[h];
calls_hash[h] = node;
}
Expand Down Expand Up @@ -870,14 +876,15 @@ Calltable::hashRemove(in_addr_t addr, unsigned short port) {

/* find call in hash */
Call*
Calltable::hashfind_by_ip_port(in_addr_t addr, unsigned short port, int *iscaller) {
Calltable::hashfind_by_ip_port(in_addr_t addr, unsigned short port, int *iscaller, int *is_rtcp) {
hash_node *node = NULL;
u_int32_t h;

h = tuplehash(addr, port);
for (node = (hash_node *)calls_hash[h]; node != NULL; node = node->next) {
if ((node->addr == addr) && (node->port == port)) {
*iscaller = node->iscaller;
*is_rtcp = node->is_rtcp;
return node->call;
}
}
Expand Down
5 changes: 3 additions & 2 deletions calltable.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,13 @@ class Calltable {
* @brief add call to hash table
*
*/
void hashAdd(in_addr_t addr, unsigned short port, Call* call, int iscaller);
void hashAdd(in_addr_t addr, unsigned short port, Call* call, int iscaller, int isrtcp);

/**
* @brief add call to hash table
*
*/
Call *hashfind_by_ip_port(in_addr_t addr, unsigned short port, int *iscaller);
Call *hashfind_by_ip_port(in_addr_t addr, unsigned short port, int *iscaller, int *isrtcp);

/**
* @brief remove call from hash
Expand All @@ -364,6 +364,7 @@ class Calltable {
int iscaller;
u_int32_t addr;
u_int16_t port;
u_int16_t is_rtcp;
};

void *calls_hash[MAXNODE];
Expand Down
5 changes: 4 additions & 1 deletion config/voipmonitor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@
#save SIP packets to pcap file
;savesip = no

# save RTP packets to pcap file
# save RTP packets to pcap file. savertp = yes automatically saves RTCP packets
;savertp = no

# save RTCP packets to pcap file
;savertcp = no

# save RTP payload to audio file. Choose 'wav' for WAV PCM or 'ogg' for OGG 25kbps format.
;saveaudio = ogg

Expand Down
27 changes: 22 additions & 5 deletions sniff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ Calltable *calltable;
extern int calls;
extern int opt_saveSIP; // save SIP packets to pcap file?
extern int opt_saveRTP; // save RTP packets to pcap file?
extern int opt_saveRTCP; // save RTCP packets to pcap file?
extern int opt_saveRAW;
extern int opt_saveWAV;
extern int opt_packetbuffered; // Make .pcap files writing ‘‘packet-buffered’’
extern int opt_rtcp; // Make .pcap files writing ‘‘packet-buffered’’
extern int verbosity;
extern int terminating;
extern int opt_rtp_firstleg;
Expand Down Expand Up @@ -246,7 +248,7 @@ void readdump(pcap_t *handle) {
struct tcphdr *header_tcp;
char *data;
int datalen;
char *s, *tmp;
char *s;
unsigned long l;
char str1[1024],str2[1024];
int sip_method = 0;
Expand All @@ -263,6 +265,7 @@ void readdump(pcap_t *handle) {
int lastSIPresponseNum;
int pcapstatresCount = 0;
int pcap_dlink = pcap_datalink(handle);
int is_rtcp = 0;

while (!terminating) {
res = pcap_next_ex(handle, &header, &packet);
Expand Down Expand Up @@ -382,17 +385,25 @@ void readdump(pcap_t *handle) {
}
// TODO: remove if hash will be stable
//if ((call = calltable->find_by_ip_port(header_ip->daddr, htons(header_udp->dest), &iscaller))){
if ((call = calltable->hashfind_by_ip_port(header_ip->daddr, htons(header_udp->dest), &iscaller))){
if ((call = calltable->hashfind_by_ip_port(header_ip->daddr, htons(header_udp->dest), &iscaller, &is_rtcp))){
// packet (RTP) by destination:port is already part of some stored call
if(is_rtcp && (opt_saveRTP || opt_saveRTCP)) {
save_packet(call, header, packet);
continue;
}
call->read_rtp((unsigned char*) data, datalen, header, header_ip->saddr, htons(header_udp->source), iscaller);
call->set_last_packet_time(header->ts.tv_sec);
if(opt_saveRTP) {
save_packet(call, header, packet);
}
// TODO: remove if hash will be stable
//} else if ((call = calltable->find_by_ip_port(header_ip->saddr, htons(header_udp->source), &iscaller))){
} else if ((call = calltable->hashfind_by_ip_port(header_ip->saddr, htons(header_udp->source), &iscaller))){
} else if ((call = calltable->hashfind_by_ip_port(header_ip->saddr, htons(header_udp->source), &iscaller, &is_rtcp))){
// packet (RTP) by source:port is already part of some stored call
if(is_rtcp && (opt_saveRTP || opt_saveRTCP)) {
save_packet(call, header, packet);
continue;
}
// as we are searching by source address and find some call, revert iscaller
call->read_rtp((unsigned char*) data, datalen, header, header_ip->saddr, htons(header_udp->source), !iscaller);
call->set_last_packet_time(header->ts.tv_sec);
Expand Down Expand Up @@ -682,10 +693,16 @@ void readdump(pcap_t *handle) {
// store RTP stream
get_rtpmap_from_sdp(tmp + 1, datalen - (tmp + 1 - data), rtpmap);
call->add_ip_port(tmp_addr, tmp_port, s, l, call->sipcallerip != header_ip->saddr, rtpmap);
calltable->hashAdd(tmp_addr, tmp_port, call, call->sipcallerip != header_ip->saddr);
calltable->hashAdd(tmp_addr, tmp_port, call, call->sipcallerip != header_ip->saddr, 0);
if(opt_rtcp) {
calltable->hashAdd(tmp_addr, tmp_port + 1, call, call->sipcallerip != header_ip->saddr, 1); //add rtcp
}
#ifdef NAT
call->add_ip_port(header_ip->saddr, tmp_port, s, l, call->sipcallerip != header_ip->saddr, rtpmap);
calltable->hashAdd(header_ip->saddr, tmp_port, call, call->sipcallerip != header_ip->saddr);
calltable->hashAdd(header_ip->saddr, tmp_port, call, call->sipcallerip != header_ip->saddr, 0);
if(opt_rtcp) {
calltable->hashAdd(header_ip->saddr, tmp_port, call, call->sipcallerip != header_ip->saddr, 1);
}
#endif

} else {
Expand Down
14 changes: 13 additions & 1 deletion voipmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ int opt_packetbuffered = 0; // Make .pcap files writing ‘‘packet-buffered’
int opt_fork = 1; // fork or run foreground
int opt_saveSIP = 0; // save SIP packets to pcap file?
int opt_saveRTP = 0; // save RTP packets to pcap file?
int opt_saveRTCP = 0; // save RTCP packets to pcap file?
int opt_saveRAW = 0; // save RTP packets to pcap file?
int opt_saveWAV = 0; // save RTP packets to pcap file?
int opt_saveGRAPH = 0; // save GRAPH data to *.graph file?
int opt_gzipGRAPH = 0; // compress GRAPH data ?
int opt_rtcp = 1; // pair RTP+1 port to RTCP and save it.
int opt_nocdr = 0; // do not save cdr?
int opt_gzipPCAP = 0; // compress PCAP data ?
int verbosity = 0; // cebug level
Expand Down Expand Up @@ -260,6 +262,9 @@ int load_config(char *fname) {
if((value = ini.GetValue("general", "savertp", NULL))) {
opt_saveRTP = yesno(value);
}
if((value = ini.GetValue("general", "savertcp", NULL))) {
opt_saveRTCP = yesno(value);
}
if((value = ini.GetValue("general", "saveaudio", NULL))) {
switch(value[0]) {
case 'y':
Expand Down Expand Up @@ -329,6 +334,7 @@ int main(int argc, char *argv[]) {
{"gzip-pcap", 0, 0, '2'},
{"save-sip", 0, 0, 'S'},
{"save-rtp", 0, 0, 'R'},
{"save-rtcp", 0, 0, '8'},
{"save-raw", 0, 0, 'A'},
{"save-audio", 0, 0, 'W'},
{"no-cdr", 0, 0, 'c'},
Expand Down Expand Up @@ -393,6 +399,9 @@ int main(int argc, char *argv[]) {
strncpy(configfile, optarg, sizeof(configfile));
load_config(configfile);
break;
case '8':
opt_saveRTCP = 1;
break;
case 'i':
strncpy(ifname, optarg, sizeof(ifname));
break;
Expand Down Expand Up @@ -469,7 +478,10 @@ int main(int argc, char *argv[]) {
" save SIP packets to pcap file. Default is disabled.\n"
"\n"
" -R, --save-rtp\n"
" save RTP packets to pcap file. Default is disabled.\n"
" save RTP packets to pcap file. Default is disabled. Whan enabled RTCP packets will be saved too.\n"
"\n"
" --save-rtcp\n"
" save RTCP packets to pcap file. You can enable SIP signalization + only RTCP packets and not RTP packets.\n"
"\n"
" --sip-register\n"
" save SIP register requests to cdr.register table and to pcap file.\n"
Expand Down

0 comments on commit 88d99e0

Please sign in to comment.