- 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/
我在下面的函数中发现了一个错误。当 temp = 10 时。它会将 temp 转换为字符串 '01'。而不是字符串'10'。我不知道为什么?将Num转换为Str有更好的方法吗?谢谢。 这样完成了 Nu
我正在编写一个 Wireshark 插件来剖析将多个应用程序级数据包放置在单个 UDP 帧中的协议(protocol)。没有封闭协议(protocol)指示帧中有多少数据包。因此,从本质上讲,传输下来
我是一名优秀的程序员,十分优秀!