使用 libtins 和 libosip
using libtins and libosip
我正在尝试使用 libtins 编写一个简单的 SIP 嗅探器,效果很好。
然后我尝试解析接收到的数据包到 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 ) );
一切顺利...
非常感谢您的帮助!
首先,如果之前发生过内存损坏,崩溃可能会在 osip_message_parse 中发生,但这可能不是初始损坏的根源。
为了使用 libosip 测试 sip 消息,您可以进入 osip 的构建目录并创建一个包含您的 sip 消息的文件:mymessage.txt
$> ./src/test/torture_test mymessage.txt 0 -v
甚至使用 valgrind 进行更深入的检查:
$> valgrind ./src/test/.libs/torture_test mymessage.txt 0 -v
如果您的代码对所有 sip 消息都失败,我猜问题是 libosip 之外的内存损坏。
SIP 消息的大小确实存在另一个错误:
osip_message_parse( sip, msg, strlen( msg ) );
SIP 消息可以包含内部带有 \0 字符的二进制数据,因此您的代码应该使用二进制有效负载的确切长度,而不是 strlen()。需要进行此类更改(但不会解决您的主要问题):
osip_message_parse( sip, msg, payload.end() - payload.begin() );
我还建议您尝试最新的 osip git 并使用失败的 SIP 消息副本来完成您的问题。
编辑:正如大卫发现的那样,初始化没有完成,这就是问题的根源。然而,正确的初始化方法是由文档的第一行指定的:
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;
终于找到问题了。
有必要用
初始化解析器
parser_init();
在任何地方都没有记录:(
现在它不再对我死了,但解析工作不正常。我需要调查更多。
谢谢大家!
大卫
我正在尝试使用 libtins 编写一个简单的 SIP 嗅探器,效果很好。 然后我尝试解析接收到的数据包到 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 ) );
一切顺利...
非常感谢您的帮助!
首先,如果之前发生过内存损坏,崩溃可能会在 osip_message_parse 中发生,但这可能不是初始损坏的根源。
为了使用 libosip 测试 sip 消息,您可以进入 osip 的构建目录并创建一个包含您的 sip 消息的文件:mymessage.txt
$> ./src/test/torture_test mymessage.txt 0 -v
甚至使用 valgrind 进行更深入的检查:
$> valgrind ./src/test/.libs/torture_test mymessage.txt 0 -v
如果您的代码对所有 sip 消息都失败,我猜问题是 libosip 之外的内存损坏。
SIP 消息的大小确实存在另一个错误:
osip_message_parse( sip, msg, strlen( msg ) );
SIP 消息可以包含内部带有 \0 字符的二进制数据,因此您的代码应该使用二进制有效负载的确切长度,而不是 strlen()。需要进行此类更改(但不会解决您的主要问题):
osip_message_parse( sip, msg, payload.end() - payload.begin() );
我还建议您尝试最新的 osip git 并使用失败的 SIP 消息副本来完成您的问题。
编辑:正如大卫发现的那样,初始化没有完成,这就是问题的根源。然而,正确的初始化方法是由文档的第一行指定的:
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;
终于找到问题了。 有必要用
初始化解析器parser_init();
在任何地方都没有记录:(
现在它不再对我死了,但解析工作不正常。我需要调查更多。
谢谢大家!
大卫