static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree) { guint saved_offset; gint8 appclass; gboolean pc; gboolean ind = FALSE; guint32 component_len = 0; guint32 header_end_offset; guint32 header_len; asn1_ctx_t asn1_ctx; tvbuff_t *ss_tvb = NULL; static gint comp_type_tag; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); saved_offset = offset; col_append_str(pinfo->cinfo, COL_PROTOCOL, "/"); col_set_fence(pinfo->cinfo, COL_PROTOCOL); while (len > (offset - saved_offset)) { /* get the length of the component. there can be multiple components in one message */ header_end_offset = get_ber_identifier(tvb, offset, &appclass, &pc, &comp_type_tag); header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind); header_len = header_end_offset -offset; component_len += header_len; ss_tvb = tvb_new_subset_length(tvb, offset, component_len); col_append_str(pinfo->cinfo, COL_INFO, "(GSM MAP) "); col_set_fence(pinfo->cinfo, COL_INFO); call_dissector(gsm_map_handle, ss_tvb, pinfo, tree); offset += component_len; } }
WSLUA_METHOD Column_fence(lua_State *L) { /* Sets Column text fence, to prevent overwriting */ Column c = checkColumn(L,1); if (c && c->cinfo) col_set_fence(c->cinfo, c->col); return 0; }
/* ---------------------------- */ static void dissect_nasdaq_soup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *nasdaq_soup_tree = NULL; guint8 nasdaq_soup_type; int linelen; gint next_offset; int offset = 0; gint col_info; gint counter = 0; col_info = check_col(pinfo->cinfo, COL_INFO); while (tvb_offset_exists(tvb, offset)) { /* there's only a \n no \r */ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, nasdaq_soup_desegment && pinfo->can_desegment); if (linelen == -1) { /* * We didn't find a line ending, and we're doing desegmentation; * tell the TCP dissector where the data for this message starts * in the data it handed us, and tell it we need one more byte * (we may need more, but we'll try again if what we get next * isn't enough), and return. */ pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return; } nasdaq_soup_type = tvb_get_guint8(tvb, offset); if (counter == 0) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "Nasdaq-SOUP"); if (col_info) col_clear(pinfo->cinfo, COL_INFO); } if (col_info ) { if (counter) { col_append_str(pinfo->cinfo, COL_INFO, "; "); col_set_fence(pinfo->cinfo, COL_INFO); } col_append_str(pinfo->cinfo, COL_INFO, val_to_str(nasdaq_soup_type, message_types_val, "Unknown packet type (0x%02x)")); } counter++; if (tree) { ti = proto_tree_add_item(tree, proto_nasdaq_soup, tvb, offset, linelen +1, ENC_NA); nasdaq_soup_tree = proto_item_add_subtree(ti, ett_nasdaq_soup); } dissect_nasdaq_soup_packet(tvb, pinfo, tree, nasdaq_soup_tree, offset, linelen); offset = next_offset; } }
static int dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *it; proto_tree *tr; int offset = 0; pi_current++; if(pi_current==5){ pi_current=0; } h225_pi=&pi_arr[pi_current]; /* Init struct for collecting h225_packet_info */ reset_h225_packet_info(h225_pi); h225_pi->msg_type = H225_CS; next_tvb_init(&h245_list); next_tvb_init(&tp_list); col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME); col_clear(pinfo->cinfo, COL_INFO); it=proto_tree_add_protocol_format(tree, proto_h225, tvb, 0, tvb_length(tvb), PSNAME" CS"); tr=proto_item_add_subtree(it, ett_h225); offset = dissect_H323_UserInformation_PDU(tvb, pinfo, tr); if (h245_list.count){ col_append_str(pinfo->cinfo, COL_PROTOCOL, "/"); col_set_fence(pinfo->cinfo, COL_PROTOCOL); } next_tvb_call(&h245_list, pinfo, tree, h245dg_handle, data_handle); next_tvb_call(&tp_list, pinfo, tree, NULL, data_handle); tap_queue_packet(h225_tap, pinfo, h225_pi); return offset; }
/* Code to actually dissect the packets */ static int dissect_tte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t* tvb_next; int is_frame_pcf; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *tte_root_item, *tte_macdest_item, *tte_macsrc_item; proto_tree *tte_tree, *tte_macdest_tree/*, *tte_macsrc_tree*/; /* Check that there's enough data */ if (tvb_length(tvb) < TTE_HEADER_LENGTH) return 0; /* check if data of pcf frame */ is_frame_pcf = (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2) == ETHERTYPE_TTE_PCF); /* return if no valid cosntant field is found */ if (!is_frame_pcf) { if ( (tvb_get_ntohl(tvb, 0) & tte_pref_ct_mask) != tte_pref_ct_marker) return 0; } /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "TTE "); col_set_str(pinfo->cinfo, COL_INFO, "Bogus TTEthernet Frame"); if (tree) { /* create display subtree for the protocol */ tte_root_item = proto_tree_add_item(tree, proto_tte, tvb, 0, TTE_HEADER_LENGTH, FALSE); tte_tree = proto_item_add_subtree(tte_root_item, ett_tte); tte_macdest_item = proto_tree_add_item(tte_tree, hf_eth_dst, tvb, 0, TTE_MAC_LENGTH, FALSE); tte_macsrc_item = proto_tree_add_item(tte_tree, hf_eth_src, tvb, TTE_MAC_LENGTH, TTE_MAC_LENGTH, FALSE); proto_tree_add_item(tte_tree, hf_eth_type, tvb, TTE_MAC_LENGTH*2, TTE_ETHERTYPE_LENGTH, FALSE); tte_macdest_tree = proto_item_add_subtree(tte_macdest_item, ett_tte_macdest); proto_tree_add_item(tte_macdest_tree, hf_tte_dst_cf, tvb, 0, TTE_MACDEST_CF_LENGTH, FALSE); proto_tree_add_item(tte_macdest_tree, hf_tte_ctid, tvb, TTE_MACDEST_CF_LENGTH, TTE_MACDEST_CTID_LENGTH, FALSE); } tvb_next = tvb_new_subset_remaining(tvb, TTE_HEADER_LENGTH); /* prevent the Columns to be cleared...appending cannot be prevented */ col_set_fence(pinfo->cinfo, COL_PROTOCOL); /* call std Ethernet dissector */ ethertype (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2), tvb , 14, pinfo, tree, NULL, hf_eth_type, 0, 0 ); return tvb_length(tvb); }
static void dissect_fcgi_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint8 type; type = tvb_get_guint8(tvb, 1); /* When there are multiple FCGI records in a TCP frame the following code */ /* will append the type for each record to COL_INFO. */ /* XXX: Unfortunately, something in the tcp_dissect_pdus() code is broken */ /* such that only the type for the first FCGI record appears in the */ /* INFO column. (All write attempts to COL_INFO after the first fail */ /* because pinfo->cinfo->writable is FALSE). */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCGI"); col_clear(pinfo->cinfo, COL_INFO); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(type, record_types, "Unknown (%u)")); col_set_fence(pinfo->cinfo, COL_INFO); if (tree) { /* we are being asked for details */ proto_item *ti; proto_tree *fcgi_tree; guint16 clen; guint8 plen; ti = proto_tree_add_item(tree, proto_fcgi, tvb, 0, -1, ENC_NA); proto_item_append_text(ti, " (%s)", val_to_str(type, record_types, "Unknown (%u)")); fcgi_tree = proto_item_add_subtree(ti, ett_fcgi); proto_tree_add_item(fcgi_tree, hf_fcgi_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(fcgi_tree, hf_fcgi_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(fcgi_tree, hf_fcgi_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; clen = tvb_get_ntohs(tvb, offset); proto_tree_add_item(fcgi_tree, hf_fcgi_content_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; plen = tvb_get_guint8(tvb, offset); proto_tree_add_item(fcgi_tree, hf_fcgi_padding_length, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; offset += 1; switch (type) { case FCGI_BEGIN_REQUEST: dissect_begin_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_ABORT_REQUEST: dissect_abort_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_END_REQUEST: dissect_end_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_PARAMS: dissect_params(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_GET_VALUES: dissect_get_values(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_GET_VALUES_RESULT: dissect_get_values_result(tvb, fcgi_tree, offset, clen); offset += clen; break; default: if (clen > 0) { proto_tree_add_item(fcgi_tree, hf_fcgi_content_data, tvb, offset, clen, ENC_NA); offset += clen; } break; } if (plen > 0) { proto_tree_add_item(fcgi_tree, hf_fcgi_padding_data, tvb, offset, plen, ENC_NA); /*offset += plen;*/ } } }
static void dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *wlan_tvb; proto_tree *ti, *cwids_tree; volatile int offset = 0; guint16 capturelen; void *pd_save; col_set_str(pinfo->cinfo, COL_PROTOCOL, "CWIDS"); col_set_str(pinfo->cinfo, COL_INFO, "Cwids: "); /* FIXME: col_set_fence(pinfo->cinfo, all-cols, only addr-cols?); */ cwids_tree = NULL; while(tvb_length_remaining(tvb, offset) > 0) { ti = proto_tree_add_item(tree, proto_cwids, tvb, offset, 28, ENC_NA); cwids_tree = proto_item_add_subtree(ti, ett_cwids); proto_tree_add_item(cwids_tree, hf_cwids_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(cwids_tree, hf_cwids_unknown1, tvb, offset, 7, ENC_NA); offset += 7; proto_tree_add_item(cwids_tree, hf_cwids_channel, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(cwids_tree, hf_cwids_unknown2, tvb, offset, 6, ENC_NA); offset += 6; proto_tree_add_item(cwids_tree, hf_cwids_reallength, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; capturelen = tvb_get_ntohs(tvb, offset); proto_tree_add_item(cwids_tree, hf_cwids_capturelen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(cwids_tree, hf_cwids_unknown3, tvb, offset, 8, ENC_NA); offset += 8; wlan_tvb = tvb_new_subset(tvb, offset, capturelen, capturelen); /* Continue after ieee80211 dissection errors */ pd_save = pinfo->private_data; TRY { call_dissector(ieee80211_handle, wlan_tvb, pinfo, tree); } CATCH2(BoundsError, ReportedBoundsError) { expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_ERROR, "Malformed or short IEEE80211 subpacket"); /* Restore the private_data structure in case one of the * called dissectors modified it (and, due to the exception, * was unable to restore it). */ pinfo->private_data = pd_save; col_append_str(pinfo->cinfo, COL_INFO, " [Malformed or short IEEE80211 subpacket] " ); col_set_fence(pinfo->cinfo, COL_INFO); #if 0 wlan_tvb = tvb_new_subset(tvb, offset, capturelen, capturelen); /* FIXME: Why does this throw an exception? */ proto_tree_add_text(cwids_tree, wlan_tvb, offset, capturelen, "[Malformed or short IEEE80211 subpacket]"); #else tvb_new_subset(tvb, offset, capturelen, capturelen); #endif ; } ENDTRY; offset += capturelen; }
static void dissect_rtmpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *rtmpt_tree = NULL; proto_tree *rtmptroot_tree = NULL; proto_item *ti = NULL; gint offset = 0; struct tcpinfo* tcpinfo = pinfo->private_data; guint8 iCommand = -1; guint32 iLength = 1; guint16 iHeaderType = 4; guint16 iHeaderLength; guint8 iID; guint rtmp_index; conversation_t * current_conversation; rtmpt_conversation_data_t * conversation_data; rtmpt_packet_data_t * packet_data; rtmpt_chunk_data_t *current_chunk_data = NULL; rtmpt_chunk_data_t *initial_chunk_data = NULL; tvbuff_t* amf_tvb; current_conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (NULL != current_conversation) { conversation_data = (rtmpt_conversation_data_t*)conversation_get_proto_data(current_conversation, proto_rtmpt); if (NULL == conversation_data) { conversation_data = se_alloc(sizeof(rtmpt_conversation_data_t)); memset((void*)conversation_data, 0, sizeof(rtmpt_conversation_data_t)); conversation_add_proto_data(current_conversation, proto_rtmpt, conversation_data); conversation_data->current_chunks = g_hash_table_new(g_direct_hash, g_direct_equal); conversation_data->previous_frame_number = -1; conversation_data->current_chunk_size = RTMPT_DEFAULT_CHUNK_SIZE; conversation_data->is_rtmpe = 0; } packet_data = p_get_proto_data(pinfo->fd, proto_rtmpt); if (NULL == packet_data) { packet_data = se_alloc(sizeof(rtmpt_packet_data_t)); memset((void*)packet_data, 0, sizeof(rtmpt_packet_data_t)); p_add_proto_data(pinfo->fd, proto_rtmpt, packet_data); packet_data->initial_chunks = g_hash_table_new(g_direct_hash, g_direct_equal); packet_data->initial_chunk_size = conversation_data->current_chunk_size; } if (conversation_data->is_rtmpe == 1) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMPE"); return; } else { col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP"); } if (conversation_data->previous_frame_number != (guint) pinfo->fd->num) { conversation_data->current_chunk_size = packet_data->initial_chunk_size; } col_set_writable(pinfo->cinfo, TRUE); col_clear(pinfo->cinfo, COL_INFO); conversation_data->previous_frame_number = pinfo->fd->num; if (tvb_length_remaining(tvb, offset) >= 1) { if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_1 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1) { iCommand = RTMPT_TYPE_HANDSHAKE_1; } else if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_2 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1) iCommand = RTMPT_TYPE_HANDSHAKE_2; else if (tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_2 && tvb_length(tvb) == RTMPT_HANDSHAKE_LENGTH_3) iCommand = RTMPT_TYPE_HANDSHAKE_3; else { iID = tvb_get_guint8(tvb, offset + 0); iHeaderType = iID >> 6; rtmp_index = iID & 0x3F; current_chunk_data = g_hash_table_lookup(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index)); initial_chunk_data = g_hash_table_lookup(packet_data->initial_chunks, GUINT_TO_POINTER(rtmp_index)); if (iHeaderType <= 2) iLength = tvb_get_ntoh24(tvb, offset + 4); if (iHeaderType <= 1) { iCommand = tvb_get_guint8(tvb, offset + 7); if (NULL == current_chunk_data) { current_chunk_data = se_alloc(sizeof(rtmpt_chunk_data_t)); memset((void*)current_chunk_data, 0, sizeof(rtmpt_chunk_data_t)); g_hash_table_insert(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index), current_chunk_data); } current_chunk_data->data_type = iCommand; current_chunk_data->last_length = iLength; current_chunk_data->frame_modified = pinfo->fd->num; } else { /* must get the command type from the previous entries in the hash table */ /* try to use the current_chunk_data unless it is from a different frame */ if (NULL != current_chunk_data && NULL != initial_chunk_data) { /* we have precedent data (we should)*/ if (current_chunk_data->frame_modified != pinfo->fd->num) { iCommand = initial_chunk_data->data_type; iLength = initial_chunk_data->length_remaining; current_chunk_data->frame_modified = pinfo->fd->num; current_chunk_data->data_type = iCommand; current_chunk_data->last_length = iLength; current_chunk_data->dechunk_buffer = initial_chunk_data->dechunk_buffer; } else { iCommand = current_chunk_data->data_type; iLength = current_chunk_data->length_remaining; } if (iLength > conversation_data->current_chunk_size) { iLength = conversation_data->current_chunk_size; } } } } iHeaderLength = rtmpt_header_length_from_type(iHeaderType); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_fstr(pinfo->cinfo, COL_INFO, " | ", "%s", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)")); col_set_fence(pinfo->cinfo, COL_INFO); } if (tree) { ti = proto_tree_add_item(tree, proto_rtmpt, tvb, offset, -1, FALSE); proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)")); rtmptroot_tree = proto_item_add_subtree(ti, ett_rtmpt); ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, iHeaderLength, RTMPT_TEXT_RTMP_HEADER); proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)")); rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_header); if (iHeaderType <= 3) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_objid, tvb, offset + 0, 1, FALSE); if (iHeaderType <= 2) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_timestamp, tvb, offset + 1, 3, FALSE); if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_body_size, tvb, offset + 4, 3, FALSE); if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_function, tvb, offset + 7, 1, FALSE); if (iHeaderType <= 0) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_source, tvb, offset + 8, 4, TRUE); if (iCommand == RTMPT_TYPE_HANDSHAKE_1) { proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE); } else if (iCommand == RTMPT_TYPE_HANDSHAKE_2) { proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE); proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1537, 1536, FALSE); } else if (iCommand == RTMPT_TYPE_HANDSHAKE_3) { proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 0, -1, FALSE); } else if (iCommand == RTMPT_TYPE_CHUNK_SIZE) { conversation_data->current_chunk_size = tvb_get_ntohl (tvb, offset + iHeaderLength); } offset = iHeaderLength; if (tvb_length_remaining(tvb, offset)) { ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, -1, RTMPT_TEXT_RTMP_BODY); } if (iCommand == RTMPT_TYPE_INVOKE || iCommand == RTMPT_TYPE_NOTIFY) { guint iChunkSize = tvb_length_remaining(tvb, iHeaderLength); /* we have data which will be AMF */ /* we should add it to a new tvb */ if (NULL != current_chunk_data) { if (NULL == current_chunk_data->dechunk_buffer) { /* we have to create a new tvbuffer */ current_chunk_data->dechunk_buffer = tvb_new_composite(); } if (!(current_chunk_data->dechunk_buffer->initialized)) { /* add the existing data to the new buffer */ tvb_composite_append(current_chunk_data->dechunk_buffer, tvb_new_real_data(tvb_memdup(tvb, iHeaderLength, iChunkSize), iChunkSize, iChunkSize)); if (current_chunk_data->length_remaining <= 0) { guint amf_length; guint8* amf_data; tvb_composite_finalize(current_chunk_data->dechunk_buffer); amf_length = tvb_length(current_chunk_data->dechunk_buffer); if (amf_length == 0) { return; } amf_data = tvb_memdup(current_chunk_data->dechunk_buffer, 0, amf_length); amf_tvb = tvb_new_real_data(amf_data, tvb_length_remaining(current_chunk_data->dechunk_buffer, 0), tvb_length_remaining(current_chunk_data->dechunk_buffer, 0)); add_new_data_source(pinfo, amf_tvb, "Dechunked AMF data"); ti = proto_tree_add_item(tree, proto_rtmpt, amf_tvb, 0, -1, FALSE); rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_body); proto_tree_set_appendix(rtmpt_tree, amf_tvb, 0, tvb_length_remaining(amf_tvb, 0)); proto_item_append_text(rtmpt_tree, " (%s)", "AMF Data"); dissect_rtmpt_amf(amf_tvb, rtmpt_tree); current_chunk_data->dechunk_buffer = NULL; } } } } } } }
/* * Call this method to actually dissect the multipart body. * NOTE - Only do so if a boundary string has been found! */ static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { proto_tree *subtree; proto_item *ti; proto_item *type_ti; multipart_info_t *m_info = get_multipart_info(pinfo, (const char*)data); gint header_start = 0; gint body_index = 0; gboolean last_boundary = FALSE; if (m_info == NULL) { /* * We can't get the required multipart information */ proto_tree_add_expert(tree, pinfo, &ei_multipart_no_required_parameter, tvb, 0, -1); call_dissector(data_handle, tvb, pinfo, tree); return tvb_reported_length(tvb); } /* Clean up the memory if an exception is thrown */ /* CLEANUP_PUSH(cleanup_multipart_info, m_info); */ /* Add stuff to the protocol tree */ ti = proto_tree_add_item(tree, proto_multipart, tvb, 0, -1, ENC_NA); subtree = proto_item_add_subtree(ti, ett_multipart); proto_item_append_text(ti, ", Type: %s, Boundary: \"%s\"", m_info->type, m_info->boundary); /* Show multi-part type as a generated field */ type_ti = proto_tree_add_string(subtree, hf_multipart_type, tvb, 0, 0, pinfo->match_string); PROTO_ITEM_SET_GENERATED(type_ti); /* * Make no entries in Protocol column and Info column on summary display, * but stop sub-dissectors from clearing entered text in summary display. */ col_set_fence(pinfo->cinfo, COL_INFO); /* * Process the multipart preamble */ header_start = process_preamble(subtree, tvb, m_info, &last_boundary); if (header_start == -1) { call_dissector(data_handle, tvb, pinfo, subtree); /* Clean up the dynamically allocated memory */ cleanup_multipart_info(m_info); return tvb_reported_length(tvb); } /* * Process the encapsulated bodies */ while (last_boundary == FALSE) { header_start = process_body_part(subtree, tvb, m_info, pinfo, header_start, body_index++, &last_boundary); if (header_start == -1) { /* Clean up the dynamically allocated memory */ cleanup_multipart_info(m_info); return tvb_reported_length(tvb); } } /* * Process the multipart trailer */ if (tvb_reported_length_remaining(tvb, header_start) > 0) { proto_tree_add_item(subtree, hf_multipart_trailer, tvb, header_start, -1, ENC_NA); } /* Clean up the dynamically allocated memory */ cleanup_multipart_info(m_info); return tvb_reported_length(tvb); }