我正在编写一个Wireshark插件来剖析一个协议,该协议将多个应用程序级别的数据包放在一个UDP帧中。没有封装协议来指示帧中有多少个数据包。因此,从本质上讲,传来的有效负载将如下所示:
uint64 sequence1
uint64 data1
uint8 flags1
uint64 sequence2
uint64 data2
uint8 flags2
: : :
uint64 sequence_n
uint64 data_n
uint8 flags_n在实际处理此信息的服务器代码中,我只需循环遍历框架,直到到达末尾。在浏览wireshark源代码中包含的插件时,我没有看到任何协议执行这样的循环。
我知道其他协议每帧都会打包多个有效载荷。在Wireshark解析器中处理此类协议的通用或标准方法是什么?
发布于 2010-06-03 06:01:02
我找到了一个对我有效的答案。我只是在解析器中循环,在我处理的每个字段中递增一个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);
}https://stackoverflow.com/questions/2930455
复制相似问题