David Villasmil
David Villasmil

Reputation: 415

using libtins and libosip

I'm trying to write a simple SIP sniffer using libtins which works nice. I then try to parse the packet received to libosip. Although it does parses the message properly, it dies silently.

I've no idea what could be wrong here, some help would be greatly appreciated!

this is my source:

#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);
}

The output is this:

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

And it dies silently.

If I remove the line:

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

It keeps going perfectly...

Thanks a lot for your help!

Upvotes: 0

Views: 1505

Answers (2)

AymericM
AymericM

Reputation: 1745

First, if a memory corruption happens before, the crash may happen in osip_message_parse but this might not be the origin of the initial corruption.

In order to test a sip message with libosip, you can go into the build directory of osip and create a file containing your sip message: mymessage.txt

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

and even for a deeper check with valgrind:

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

If your code is failing for all sip message, I guess the issue is a memory corruption outside libosip.

You do have another bug with the size of the SIP message:

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

A SIP message can contain binary data with \0 char inside, so your code should use the exact length of binary payload not strlen(). Such a change is required (but won't fix your main issue):

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

I also advise you to try the latest osip git and complete your question with a copy of a SIP message failing.

EDIT: As David found, the init wasn't done and that was the origin of the issue. However, the correct way to init is as specified by first line of documentation:

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;

Upvotes: 1

David Villasmil
David Villasmil

Reputation: 415

I finally found the problem. it is necessary to initialise the parser with

parser_init();

It's not documented anywhere :(

Now it's not dying on me anymore, but the parsing is not working properly. I need to investigate more.

Thanks everyone!

David

Upvotes: 1

Related Questions