2015-02-21 6 views
0

Я пытаюсь написать простой SIP-сниффер, используя libtins, который работает хорошо. Затем я пытаюсь разобрать полученный пакет на libosip. Хотя он правильно разбирает сообщение, он умирает молча.с использованием libtins и libosip

Я понятия не имею, что может быть неправильным здесь, некоторая помощь будет принята с благодарностью!

это мой источник:

#include <iostream> 
#include "tins/tins.h" 
#include <osip2/osip.h> 
#include <osipparser2/osip_message.h> 
#include <vector> 

using namespace Tins; 

bool invalidChar (char c); 
void stripUnicode(std::string & str); 

bool callback(const PDU &pdu) 
{ 

    const IP &ip = pdu.rfind_pdu<IP>(); // Find the IP layer 
    const UDP &udp = pdu.rfind_pdu<UDP>(); // Find the TCP layer 

    osip_message *sip; 
    osip_message_init(&sip); 

    // First here we print Source and Destination Information 
    std::cout << ip.src_addr() << ':' << udp.sport() << " -> " 
      << ip.dst_addr() << ':' << udp.dport() << std::endl; 

    // Extract the RawPDU object. 
    const RawPDU& raw = udp.rfind_pdu<RawPDU>(); 

    // Finally, take the payload (this is a vector<uint8_t>) 
    const RawPDU::payload_type& payload = raw.payload(); 

    // We create a string message 
    std::string message(payload.begin(), payload.end()); 
    std::string sip_message; 

    // Try to parse the message 
    std::cout << "copying message with len " << message.size() << std::endl; 
    const char *msg = message.c_str(); 

    std::cout << "parsing message with size " << strlen(msg) << std::endl; 
    osip_message_parse(sip, msg, strlen(msg)); 

    std::cout << "freeing message" << std::endl; 
    osip_message_free(sip); 
    return true; 
} 

int main(int argc, char *argv[]) 
{ 
    if(argc != 2) { 
     std::cout << "Usage: " << *argv << " <interface>" << std::endl; 
     return 1; 
    } 
    // Sniff on the provided interface in promiscuos mode 
    Sniffer sniffer(argv[1], Sniffer::PROMISC); 

    // Only capture udp packets sent to port 53 
    sniffer.set_filter("port 5060"); 

    // Start the capture 
    sniffer.sniff_loop(callback); 
} 

Выход заключается в следующем:

1.2.3.4:5060 -> 4.3.2.1:5060 
copying message with len 333 
parsing message with size 333 

И он умирает молча.

Если удалить строку:

osip_message_parse(sip, msg, strlen(msg)); 

Он продолжает идти отлично ...

Спасибо большое за помощь!

+0

(ОТ) (не мог устоять) «Я просто не знаю, что пошло не так!» (c) –

+0

В серьезной заметке, возможно, запустите это в отладчике и запустите 'exit' /' _exit'? –

+0

Я не могу, мой отладчик не работает в моей удаленной системе ... :( –

ответ

0

я, наконец, нашел проблему. необходимо инициализировать анализатор с

parser_init(); 

Это нигде не документированы :(

Теперь он не умирает от меня больше, но синтаксический не работает должным образом. Мне нужно исследовать больше.

Спасибо всем!

David

0

Во-первых, если раньше произошло повреждение памяти, авария может произойти в osip_message_parse, но это может быть не происхождение первоначального повреждения.

Для того, чтобы проверить сообщение глотнуть с libosip, вы можете перейти в каталог сборки Осипа и создать файл, содержащий ваш глотнуть сообщение: mymessage.txt

$> ./src/test/torture_test mymessage.txt 0 -v 

и даже для более глубокого сверяться с Valgrind :

$> valgrind ./src/test/.libs/torture_test mymessage.txt 0 -v 

Если код не удается на все сообщения глотки, я думаю, этот вопрос является повреждением памяти за пределами libosip.

У вас есть еще ошибка с размером сообщения SIP:

osip_message_parse(sip, msg, strlen(msg)); 

сообщение SIP может содержать двоичные данные с \ 0 полукокса внутри, так что ваш код должен использовать точную длину двоичной полезной нагрузки не STRLEN(). Такое изменение не требуется (но не зафиксирует ваш главный вопрос):

osip_message_parse(sip, msg, payload.end() - payload.begin()); 

Я также советую вам попробовать последнюю Осип мерзавца и завершить вопрос с копией сообщения SIP неисправного.

EDIT: Как признал Дэвид, init не был выполнен, и это было причиной проблемы. Тем не менее, правильный способ инициализации является, как указан первой строкой документации:

How-To initialize libosip2

When using osip, your first task is to initialize the parser and the state machine. This must be done prior to any use of libosip2. 

#include <sys/time.h> 
#include <osip2/osip.h> 
int i; 
osip_t *osip; 
i=osip_init(&osip); 
if (i!=0) 
    return -1;