2010-05-28 23 views
2

我正在寫一個Wireshark插件來剖析一個協議,該協議將多個應用程序級數據包放置在單個UDP幀中。沒有封閉協議指示幀中有多少數據包。所以基本上,灌進了線的有效載荷將是這樣的: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解析器中處理這種協議的方式是什麼?

回答

3

我找到了適合我的答案。我簡單地在解剖器內循環,對每個我處理的字段值遞增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); 
} 
相關問題