Skip to content

Commit

Permalink
add filter by sip type into live sniffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Radek Bucek committed Jun 6, 2013
1 parent f2e24ea commit c334604
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 21 deletions.
121 changes: 117 additions & 4 deletions manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ struct listening_worker_arg {
Call *call;
};

static void updateLivesnifferfilters();

livesnifferfilter_use_siptypes_s livesnifferfilterUseSipTypes;

/*
* this function runs as thread. It reads RTP audio data from call
* and write it to output buffer
Expand Down Expand Up @@ -396,10 +400,13 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
sscanf(buf, "stoplivesniffer %u", &uid);
map<unsigned int, livesnifferfilter_t*>::iterator usersnifferIT = usersniffer.find(uid);
if(usersnifferIT != usersniffer.end()) {
global_livesniffer = 0;
// global_livesniffer_all = 0;
free(usersnifferIT->second);
usersniffer.erase(usersnifferIT);
if(!usersniffer.size()) {
global_livesniffer = 0;
//global_livesniffer_all = 0;
}
updateLivesnifferfilters();
}
return 0;
} else if(strstr(buf, "getlivesniffer") != NULL) {
Expand Down Expand Up @@ -431,7 +438,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
filter = (livesnifferfilter_t*)calloc(1, sizeof(livesnifferfilter_t));
usersniffer[uid] = filter;
}
filter->all = 1;
updateLivesnifferfilters();
return 0;
}

Expand All @@ -445,7 +452,6 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
}

if(strstr(search, "srcaddr")) {

int i = 0;
//reset filters
for(i = 0; i < MAXLIVEFILTERS; i++) {
Expand All @@ -461,6 +467,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
filter->lv_bothaddr[i] = ntohl((unsigned int)inet_addr(val.c_str()));
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "dstaddr")) {
int i = 0;
//reset filters
Expand All @@ -477,6 +484,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
filter->lv_bothaddr[i] = ntohl((unsigned int)inet_addr(val.c_str()));
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "bothaddr")) {
int i = 0;
//reset filters
Expand All @@ -493,6 +501,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
filter->lv_bothaddr[i] = ntohl((unsigned int)inet_addr(val.c_str()));
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "srcnum")) {
int i = 0;
//reset filters
Expand All @@ -511,6 +520,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
//cout << filter->lv_srcnum[i] << "\n";
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "dstnum")) {
int i = 0;
//reset filters
Expand All @@ -529,6 +539,7 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
//cout << filter->lv_dstnum[i] << "\n";
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "bothnum")) {
int i = 0;
//reset filters
Expand All @@ -547,6 +558,18 @@ int parse_command(char *buf, int size, int client, int eof, const char *buf_long
//cout << filter->lv_bothnum[i] << "\n";
i++;
}
updateLivesnifferfilters();
} else if(strstr(search, "siptypes")) {
//cout << "siptypes: " << value << "\n";
for(size_t i = 0; i < strlen(value) && i < MAXLIVEFILTERS; i++) {
filter->lv_siptypes[i] = value[i] == 'I' ? INVITE :
value[i] == 'R' ? REGISTER :
value[i] == 'O' ? OPTIONS :
value[i] == 'S' ? SUBSCRIBE :
value[i] == 'M' ? MESSAGE :
0;
}
updateLivesnifferfilters();
}
} else if(strstr(buf, "listen") != NULL) {
long long callreference;
Expand Down Expand Up @@ -1058,3 +1081,93 @@ void *manager_server(void *dummy) {
close(manager_socket_server);
return 0;
}

void livesnifferfilter_s::updateState() {
state_s new_state;
new_state.all_saddr = true;
new_state.all_daddr = true;
new_state.all_bothaddr = true;
new_state.all_srcnum = true;
new_state.all_dstnum = true;
new_state.all_bothnum = true;
new_state.all_siptypes = true;
for(int i = 0; i < MAXLIVEFILTERS; i++) {
if(this->lv_saddr[i]) {
new_state.all_saddr = false;
}
if(this->lv_daddr[i]) {
new_state.all_daddr = false;
}
if(this->lv_bothaddr[i]) {
new_state.all_bothaddr = false;
}
if(this->lv_srcnum[i][0]) {
new_state.all_srcnum = false;
}
if(this->lv_dstnum[i][0]) {
new_state.all_dstnum = false;
}
if(this->lv_bothnum[i][0]) {
new_state.all_bothnum = false;
}
if(this->lv_siptypes[i]) {
new_state.all_siptypes = false;
}
}
new_state.all_addr = new_state.all_saddr && new_state.all_daddr && new_state.all_bothaddr;
new_state.all_num = new_state.all_srcnum && new_state.all_dstnum && new_state.all_bothnum;
new_state.all_all = new_state.all_addr && new_state.all_num && new_state.all_siptypes;
this->state = new_state;
}

void updateLivesnifferfilters() {
livesnifferfilter_use_siptypes_s new_livesnifferfilterUseSipTypes;
memset(&new_livesnifferfilterUseSipTypes, 0, sizeof(new_livesnifferfilterUseSipTypes));
if(usersniffer.size()) {
global_livesniffer = 1;
map<unsigned int, livesnifferfilter_t*>::iterator usersnifferIT;
for(usersnifferIT = usersniffer.begin(); usersnifferIT != usersniffer.end(); ++usersnifferIT) {
usersnifferIT->second->updateState();
if(usersnifferIT->second->state.all_siptypes) {
new_livesnifferfilterUseSipTypes.u_invite = true;
new_livesnifferfilterUseSipTypes.u_register = true;
new_livesnifferfilterUseSipTypes.u_options = true;
new_livesnifferfilterUseSipTypes.u_subscribe = true;
new_livesnifferfilterUseSipTypes.u_message = true;
} else {
for(int i = 0; i < MAXLIVEFILTERS; i++) {
if(usersnifferIT->second->lv_siptypes[i]) {
switch(usersnifferIT->second->lv_siptypes[i]) {
case INVITE:
new_livesnifferfilterUseSipTypes.u_invite = true;
break;
case REGISTER:
new_livesnifferfilterUseSipTypes.u_register = true;
break;
case OPTIONS:
new_livesnifferfilterUseSipTypes.u_options = true;
break;
case SUBSCRIBE:
new_livesnifferfilterUseSipTypes.u_subscribe = true;
break;
case MESSAGE:
new_livesnifferfilterUseSipTypes.u_message = true;
break;
}
}
}
}
}
} else {
global_livesniffer = 0;
}
livesnifferfilterUseSipTypes = new_livesnifferfilterUseSipTypes;
/*
cout << "livesnifferfilterUseSipTypes" << endl;
if(livesnifferfilterUseSipTypes.u_invite) cout << "INVITE" << endl;
if(livesnifferfilterUseSipTypes.u_register) cout << "REGISTER" << endl;
if(livesnifferfilterUseSipTypes.u_options) cout << "OPTIONS" << endl;
if(livesnifferfilterUseSipTypes.u_subscribe) cout << "SUBSCRIBE" << endl;
if(livesnifferfilterUseSipTypes.u_message) cout << "MESSAGE" << endl;
*/
}
83 changes: 69 additions & 14 deletions sniff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ extern char opt_silencedmtfseq[16];
extern int opt_skinny;
extern int opt_saverfc2833;
extern vector<dstring> opt_custom_headers;
extern livesnifferfilter_use_siptypes_s livesnifferfilterUseSipTypes;

#ifdef QUEUE_MUTEX
extern sem_t readpacket_thread_semaphore;
Expand Down Expand Up @@ -274,7 +275,18 @@ inline void save_packet_sql(Call *call, struct pcap_pkthdr *header, const u_char

// construct query and push it to mysqlquery queue
int id_sensor = opt_id_sensor > 0 ? opt_id_sensor : 0;
query << "INSERT INTO livepacket_" << uid << " SET sipcallerip = '" << saddr << "', sipcalledip = '" << daddr << "', id_sensor = " << id_sensor << ", sport = " << source << ", dport = " << dest << ", istcp = " << istcp << ", created_at = " << sqlEscapeStringBorder(sqlDateTimeString(header->ts.tv_sec).c_str()) << ", microseconds = " << header->ts.tv_usec << ", callid = " << sqlEscapeStringBorder(call->call_id) << ", description = " << sqlEscapeStringBorder(description) << ", data = '#" << sqlDb->escape(mpacket, len) << "#'";
query << "INSERT INTO livepacket_" << uid <<
" SET sipcallerip = '" << saddr <<
"', sipcalledip = '" << daddr <<
"', id_sensor = " << id_sensor <<
", sport = " << source <<
", dport = " << dest <<
", istcp = " << istcp <<
", created_at = " << sqlEscapeStringBorder(sqlDateTimeString(header->ts.tv_sec).c_str()) <<
", microseconds = " << header->ts.tv_usec <<
", callid = " << (call ? sqlEscapeStringBorder(call->call_id) : "NULL") <<
", description = " << sqlEscapeStringBorder(description) <<
", data = '#" << sqlDb->escape(mpacket, len) << "#'";
pthread_mutex_lock(&mysqlquery_lock);
mysqlquery.push(query.str());
pthread_mutex_unlock(&mysqlquery_lock);
Expand All @@ -285,7 +297,11 @@ inline void save_packet_sql(Call *call, struct pcap_pkthdr *header, const u_char
/*
stores SIP messags to sql.livepacket based on user filters
*/
inline void save_live_packet(Call *call, struct pcap_pkthdr *header, const u_char *packet, unsigned int saddr, int source, unsigned int daddr, int dest, int istcp, char *data, int datalen, char type) {
inline void save_live_packet(Call *call, struct pcap_pkthdr *header, const u_char *packet, unsigned int saddr, int source, unsigned int daddr, int dest, int istcp, char *data, int datalen, unsigned char sip_type) {
if(!global_livesniffer && !global_livesniffer_all) {
return;
}

// check saddr and daddr filters
daddr = htonl(daddr);
saddr = htonl(saddr);
Expand All @@ -295,6 +311,7 @@ inline void save_live_packet(Call *call, struct pcap_pkthdr *header, const u_cha
return;
}

/*
map<unsigned int, livesnifferfilter_t*>::iterator usersnifferIT;
for(usersnifferIT = usersniffer.begin(); usersnifferIT != usersniffer.end(); usersnifferIT++) {
livesnifferfilter_t *filter = usersnifferIT->second;
Expand All @@ -305,9 +322,9 @@ inline void save_live_packet(Call *call, struct pcap_pkthdr *header, const u_cha
if(filter->lv_saddr[i] == saddr) goto save;
if(filter->lv_daddr[i] == daddr) goto save;
if(filter->lv_bothaddr[i] == daddr or filter->lv_bothaddr[i] == saddr) goto save;
if(filter->lv_srcnum[i][0] != '\0' and memmem(call->caller, strlen(call->caller), filter->lv_srcnum[i], strlen(filter->lv_srcnum[i]))) goto save;
if(filter->lv_dstnum[i][0] != '\0' and memmem(call->caller, strlen(call->caller), filter->lv_dstnum[i], strlen(filter->lv_dstnum[i]))) goto save;
if(filter->lv_bothnum[i][0] != '\0' and (
if(call and filter->lv_srcnum[i][0] != '\0' and memmem(call->caller, strlen(call->caller), filter->lv_srcnum[i], strlen(filter->lv_srcnum[i]))) goto save;
if(call and filter->lv_dstnum[i][0] != '\0' and memmem(call->caller, strlen(call->caller), filter->lv_dstnum[i], strlen(filter->lv_dstnum[i]))) goto save;
if(call and filter->lv_bothnum[i][0] != '\0' and (
memmem(call->caller, strlen(call->caller), filter->lv_bothnum[i], strlen(filter->lv_bothnum[i])) or
memmem(call->called, strlen(call->called), filter->lv_bothnum[i], strlen(filter->lv_bothnum[i])))
) goto save;
Expand All @@ -319,6 +336,43 @@ inline void save_live_packet(Call *call, struct pcap_pkthdr *header, const u_cha
// nothing matches
return;
*/

map<unsigned int, livesnifferfilter_t*>::iterator usersnifferIT;
for(usersnifferIT = usersniffer.begin(); usersnifferIT != usersniffer.end(); usersnifferIT++) {
livesnifferfilter_t *filter = usersnifferIT->second;
bool save = filter->state.all_all;
for(int i = 0; i < MAXLIVEFILTERS && !save; i++) {
bool okAddr =
filter->state.all_addr ||
((filter->state.all_saddr || (filter->lv_saddr[i] &&
saddr == filter->lv_saddr[i])) &&
(filter->state.all_daddr || (filter->lv_daddr[i] &&
daddr == filter->lv_daddr[i])) &&
(filter->state.all_bothaddr || (filter->lv_bothaddr[i] &&
(saddr == filter->lv_bothaddr[i] ||
daddr == filter->lv_bothaddr[i]))));
bool okNum =
!call ||
filter->state.all_num ||
((filter->state.all_srcnum || (filter->lv_srcnum[i][0] &&
memmem(call->caller, strlen(call->caller), filter->lv_srcnum[i], strlen(filter->lv_srcnum[i])))) &&
(filter->state.all_dstnum || (filter->lv_dstnum[i][0] &&
memmem(call->caller, strlen(call->caller), filter->lv_dstnum[i], strlen(filter->lv_dstnum[i])))) &&
(filter->state.all_bothnum || (filter->lv_bothnum[i][0] &&
(memmem(call->caller, strlen(call->caller), filter->lv_bothnum[i], strlen(filter->lv_bothnum[i])) ||
memmem(call->called, strlen(call->called), filter->lv_bothnum[i], strlen(filter->lv_bothnum[i]))))));
bool okSipType =
filter->state.all_siptypes ||
filter->lv_siptypes[i] == sip_type;
if(okAddr && okNum && okSipType) {
save = true;
}
}
if(save) {
save_packet_sql(call, header, packet, saddr, source, daddr, dest, istcp, data, datalen, usersnifferIT->first);
}
}
}

/*
Expand Down Expand Up @@ -1659,14 +1713,16 @@ Call *process_packet(unsigned int saddr, int source, unsigned int daddr, int des
if(verbosity > 2)
syslog(LOG_NOTICE,"SIP msg: OPTIONS\n");
sip_method = OPTIONS;
Call tmpcall;
save_live_packet(&tmpcall, header, packet, saddr, source, daddr, dest, istcp, data, datalen, OPTIONS);
if(livesnifferfilterUseSipTypes.u_options) {
save_live_packet(NULL, header, packet, saddr, source, daddr, dest, istcp, data, datalen, OPTIONS);
}
} else if ((datalen > 8) && !(memmem(data, 9, "SUBSCRIBE", 9) == 0)) {
if(verbosity > 2)
syslog(LOG_NOTICE,"SIP msg: SUBSCRIBE\n");
sip_method = SUBSCRIBE;
Call tmpcall;
save_live_packet(&tmpcall, header, packet, saddr, source, daddr, dest, istcp, data, datalen, SUBSCRIBE);
if(livesnifferfilterUseSipTypes.u_subscribe) {
save_live_packet(NULL, header, packet, saddr, source, daddr, dest, istcp, data, datalen, SUBSCRIBE);
}
} else {
if(verbosity > 2) {
syslog(LOG_NOTICE,"SIP msg: 1XX or Unknown msg \n");
Expand Down Expand Up @@ -1716,12 +1772,11 @@ Call *process_packet(unsigned int saddr, int source, unsigned int daddr, int des
// TODO: check if we have enabled live sniffer for SUBSCRIBE or OPTIONS
// if yes check for cseq OPTIONS or SUBSCRIBE
s = gettag(data, datalen, "\nCSeq:", &l);
Call tmpcall;
if(l && l < 32) {
if(memmem(s, l, "SUBSCRIBE", 9)) {
save_live_packet(&tmpcall, header, packet, saddr, source, daddr, dest, istcp, data, datalen, SUBSCRIBE);
} else if(memmem(s, l, "OPTIONS", 7)) {
save_live_packet(&tmpcall, header, packet, saddr, source, daddr, dest, istcp, data, datalen, OPTIONS);
if(livesnifferfilterUseSipTypes.u_subscribe && memmem(s, l, "SUBSCRIBE", 9)) {
save_live_packet(NULL, header, packet, saddr, source, daddr, dest, istcp, data, datalen, SUBSCRIBE);
} else if(livesnifferfilterUseSipTypes.u_options && memmem(s, l, "OPTIONS", 7)) {
save_live_packet(NULL, header, packet, saddr, source, daddr, dest, istcp, data, datalen, OPTIONS);
}
}
return NULL;
Expand Down
28 changes: 25 additions & 3 deletions sniff.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,37 @@ typedef struct {
#define MAXLIVEFILTERSCHARS 32

typedef struct livesnifferfilter_s {
struct state_s {
bool all_saddr;
bool all_daddr;
bool all_bothaddr;
bool all_addr;
bool all_srcnum;
bool all_dstnum;
bool all_bothnum;
bool all_num;
bool all_siptypes;
bool all_all;
};
unsigned int lv_saddr[MAXLIVEFILTERS];
unsigned int lv_daddr[MAXLIVEFILTERS];
unsigned int lv_bothaddr[MAXLIVEFILTERS];
unsigned int lv_bothaddr[MAXLIVEFILTERS];
char lv_srcnum[MAXLIVEFILTERS][MAXLIVEFILTERSCHARS];
char lv_dstnum[MAXLIVEFILTERS][MAXLIVEFILTERSCHARS];
char lv_bothnum[MAXLIVEFILTERS][MAXLIVEFILTERSCHARS];
char lv_bothnum[MAXLIVEFILTERS][MAXLIVEFILTERSCHARS];
unsigned char lv_siptypes[MAXLIVEFILTERS];
int uid;
time_t created_at;
int all;
state_s state;
void updateState();
} livesnifferfilter_t;

struct livesnifferfilter_use_siptypes_s {
bool u_invite;
bool u_register;
bool u_options;
bool u_subscribe;
bool u_message;
};

#endif

0 comments on commit c334604

Please sign in to comment.