- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在编写一个 Wireshark 插件来剖析将多个应用程序级数据包放置在单个 UDP 帧中的协议(protocol)。没有封闭协议(protocol)指示帧中有多少数据包。因此,从本质上讲,传输下来的有效载荷将如下所示:
uint64 sequence1
uint64 data1
uint8 flags1
uint64 sequence2
uint64 data2
uint8 flags2
: : :
uint64 sequence_n
uint64 data_n
uint8 flags_n
在我实际处理这些信息的服务器代码中,我简单地遍历帧直到到达结尾。在查看 wireshark 源代码中包含的插件时,我没有看到任何协议(protocol)会像这样进行任何循环。
我知道其他协议(protocol)每帧包含多个有效载荷。在 Wireshark 解析器中处理此类协议(protocol)的规范或标准方法是什么?
最佳答案
我找到了适合我的答案。我只是在解析器中循环,为我处理的每个字段增加一个 offset
值,直到 offset > tvb_reported_length(tvb)
。在每个循环中,我向父树项目添加一个新的子树,以便框架中的每个单独的消息都在它自己的树中。
编辑:为了您的娱乐,这里是完整的 disscection code for CQS ,包括处理每个 UDP 帧的多个数据包的代码:
static int dissect_cqs(tvbuff_t* tvb,
packet_info* pinfo,
proto_tree* tree)
{
guint offset = 0;
proto_item* ti = 0;
char msgcat = '\0';
gint field_sz;
static const char soh = 0x01, us = 0x1F, etx = 0x03;
proto_tree* cqs_tree, *frame_tree, *packet_tree;
guint8 ts_hour, ts_minute,ts_second;
char ts_msec_str[3];
char cattype [2];
int found = 0;
guint i;
char seq_str[9+1];
guint32 seq;
guint32 firstseq = 0, msgcount = 0;
guint framegaps = 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CQS");
col_clear(pinfo->cinfo, COL_INFO);
ti = proto_tree_add_item(tree, proto_cqs, tvb, offset, -1, FALSE);
cqs_tree = proto_item_add_subtree(ti, ett_cqs);
ti = proto_tree_add_item(cqs_tree, hf_cqs_frame_subtree, tvb, offset, -1, FALSE);
frame_tree = proto_item_add_subtree(ti, ett_frame);
/** APPEND THE LEADING CONTROL CHARACTER **/
field_sz = 1; ti = proto_tree_add_item(frame_tree, hf_cqs_ctrl, tvb, offset, field_sz, FALSE) ; offset += field_sz;
while( offset < tvb_reported_length(tvb) )
{
/** get the message type, category & sequence number **/
tvb_memcpy(tvb, cattype, offset, 2);
tvb_memcpy(tvb, seq_str, offset+8, 9);
seq_str[9] = 0;
seq = atol(seq_str);
++msgcount;
if( !firstseq )
firstseq = seq;
else
framegaps += (seq - firstseq) - (msgcount - 1);
ti = proto_tree_add_none_format(frame_tree, hf_cqs_packet_subtree, tvb, offset, 24, "CQS Packet [%ld]", seq);
if( ti ) packet_tree = proto_item_add_subtree(ti, ett_packet);
else packet_tree = 0;
/** dissect the packet header **/
cattype[0] = tvb_get_guint8(tvb, offset);
field_sz = 1; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_msgcat, tvb, offset, field_sz, FALSE) ; offset += field_sz;
cattype[1] = tvb_get_guint8(tvb, offset);
field_sz = 1; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_msgtype, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 1; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_msgnet, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 2; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_retran, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 1; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_hdrid, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 2; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_rsv, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 9; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_seq, tvb, offset, field_sz, FALSE) ; offset += field_sz;
field_sz = 1; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_partid, tvb, offset, field_sz, FALSE) ; offset += field_sz;
ts_hour = tvb_get_guint8(tvb, offset) - '0';
ts_minute = tvb_get_guint8(tvb, offset+1) - '0';
ts_second = tvb_get_guint8(tvb, offset+2) - '0';
ts_msec_str[0] = tvb_get_guint8(tvb, offset+3);
ts_msec_str[1] = tvb_get_guint8(tvb, offset+4);
ts_msec_str[2] = tvb_get_guint8(tvb, offset+5);
field_sz = 6; ti = proto_tree_add_item(packet_tree, hf_cqs_hdr_time, tvb, offset, field_sz, FALSE) ; offset += field_sz;
if( tree )
{
proto_item_set_text(ti, "CQS Timestamp: %02d:%02d:%02d.%c%c%c %cM", (ts_hour > 11) ? (ts_hour-12) : ts_hour, ts_minute, ts_second, ts_msec_str[0], ts_msec_str[1], ts_msec_str[2], (ts_hour > 11) ? 'P' : 'A');
}
/** COUNT UP BYTES UNTIL WE FIND A CONTROL CHARACTER **/
field_sz = 0;
found = 0;
for( i = 0; !found && offset+i < tvb_reported_length(tvb); ++i )
{
char c = tvb_get_guint8(tvb, offset+i);
switch( c )
{
case 0x01 : /** SOH **/
case 0x1F : /** US **/
case 0x03 : /* ETX **/
found = 1;
break;
default :
++field_sz;
break;
}
}
/** APPEND THE DATA PAYLOAD **/
ti = proto_tree_add_item(packet_tree, hf_cqs_payload, tvb, offset, field_sz, FALSE) ; offset += field_sz;
/** APPEND THE TRAILING CONTROL CHARACTER **/
field_sz = 1; ti = proto_tree_add_item(frame_tree, hf_cqs_ctrl, tvb, offset, field_sz, FALSE) ; offset += field_sz;
}
ti = proto_tree_add_uint(cqs_tree, hf_cqs_frame_first_seq, tvb, 0, 0, firstseq);
ti = proto_tree_add_uint(cqs_tree, hf_cqs_frame_expected_seq, tvb, 0, 0, firstseq+msgcount);
ti = proto_tree_add_uint(cqs_tree, hf_cqs_frame_msgcount, tvb, 0, 0, msgcount);
ti = proto_tree_add_uint(cqs_tree, hf_cqs_frame_gaps, tvb, 0, 0, framegaps);
return tvb_length(tvb);
}
关于c++ - Wireshark 插件 : Dissecting Payloads With Multiple Packets Per UDP Frame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2930455/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!