static gint add_message(tvbuff_t * tvb, gint offset, proto_tree * tree, wmem_strbuf_t * info) { guint16 descriptor_id, message_id; gint data_len; proto_item *msg; proto_tree *msg_tree; const gchar *descriptor; descriptor_id = tvb_get_ntohs(tvb, offset); message_id = tvb_get_ntohs(tvb, offset + 2); data_len = tvb_get_ntohs(tvb, offset + 4) * 2; /* Message subtree */ descriptor = val_to_str(descriptor_id, descriptors, "Unknown (%u)"); if (descriptor_id == ACK) msg = proto_tree_add_none_format(tree, hf_armagetronad_msg_subtree, tvb, offset, data_len + 6, "ACK %d messages", data_len / 2); else msg = proto_tree_add_none_format(tree, hf_armagetronad_msg_subtree, tvb, offset, data_len + 6, "Message 0x%04x [%s]", message_id, descriptor); msg_tree = proto_item_add_subtree(msg, ett_message); /* DescriptorID field */ proto_tree_add_item(msg_tree, hf_armagetronad_descriptor_id, tvb, offset, 2, ENC_BIG_ENDIAN); if (info) wmem_strbuf_append_printf(info, "%s, ", descriptor); /* MessageID field */ proto_tree_add_item(msg_tree, hf_armagetronad_message_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN); /* DataLen field */ proto_tree_add_item(msg_tree, hf_armagetronad_data_len, tvb, offset + 4, 2, ENC_BIG_ENDIAN); /* Data field */ add_message_data(tvb, offset + 6, data_len, msg_tree); return data_len + 6; }
static void dissect_dmx_chan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX Channels"); col_clear(pinfo->cinfo, COL_INFO); if (tree != NULL) { static const char *chan_format[] = { "%2u%% ", "0x%02x ", "%3u " }; static const char *string_format[] = { "0x%03x: %s", "%3u: %s" }; wmem_strbuf_t *chan_str = wmem_strbuf_new_label(wmem_packet_scope()); proto_item *item; guint16 length,r,c,row_count; guint8 v; guint offset = 0; proto_tree *ti = proto_tree_add_item(tree, proto_dmx_chan, tvb, offset, -1, ENC_NA); proto_tree *dmx_chan_tree = proto_item_add_subtree(ti, ett_dmx_chan); length = tvb_reported_length_remaining(tvb, offset); row_count = (length / global_disp_col_count) + ((length % global_disp_col_count) == 0 ? 0 : 1); for (r = 0; r < row_count;r++) { wmem_strbuf_truncate(chan_str, 0); for (c = 0;(c < global_disp_col_count) && (((r * global_disp_col_count) + c) < length);c++) { if ((global_disp_col_count >= 2) && ((c % (global_disp_col_count / 2)) == 0)) { wmem_strbuf_append(chan_str, " "); } v = tvb_get_guint8(tvb, (offset + (r * global_disp_col_count) + c)); if (global_disp_chan_val_type == 0) { v = (v * 100) / 255; if (v == 100) { wmem_strbuf_append(chan_str, "FL "); } else { wmem_strbuf_append_printf(chan_str, chan_format[global_disp_chan_val_type], v); } } else { wmem_strbuf_append_printf(chan_str, chan_format[global_disp_chan_val_type], v); } } proto_tree_add_none_format(dmx_chan_tree, hf_dmx_chan_output_dmx_data, tvb, offset+(r * global_disp_col_count), c, string_format[global_disp_chan_nr_type], (r * global_disp_col_count) + 1, wmem_strbuf_get_str(chan_str)); } /* Add the real type hidden */ item = proto_tree_add_item(dmx_chan_tree, hf_dmx_chan_output_data_filter, tvb, offset, length, ENC_NA ); PROTO_ITEM_SET_HIDDEN(item); } }
/* dict = d...e */ static int dissect_bencoded_dict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const char *label ) { proto_item *ti; proto_tree *sub_tree; guint orig_offset = offset; if(offset == 0) { ti = proto_tree_add_item(tree, proto_bt_dht, tvb, 0, -1, ENC_NA); sub_tree = proto_item_add_subtree(ti, ett_bt_dht); } else { ti = proto_tree_add_none_format( tree, hf_bencoded_dict, tvb, offset, -1, "%s: Dictionary...", label ); sub_tree = proto_item_add_subtree( ti, ett_bencoded_dict); } /* skip the first char('d') */ offset += 1; while( tvb_get_guint8(tvb,offset)!='e' ) offset = dissect_bencoded_dict_entry( tvb, pinfo, sub_tree, offset ); offset += 1; proto_item_set_len( ti, offset-orig_offset ); return offset; }
/* Has storm request rate been exceeded with this request? */ static void check_for_storm_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gboolean report_storm = FALSE; if (p_get_proto_data(pinfo->fd, proto_arp) != 0) { /* Read any previous stored packet setting */ report_storm = (p_get_proto_data(pinfo->fd, proto_arp) == (void*)STORM); } else { /* Seeing packet for first time - check against preference settings */ gint seconds_delta = (gint) (pinfo->fd->abs_ts.secs - time_at_start_of_count.secs); gint nseconds_delta = pinfo->fd->abs_ts.nsecs - time_at_start_of_count.nsecs; gint gap = (seconds_delta*1000) + (nseconds_delta / 1000000); /* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */ if ((gap > (gint)global_arp_detect_request_storm_period) || (gap < 0)) { /* Time period elapsed without threshold being exceeded */ arp_request_count = 1; time_at_start_of_count = pinfo->fd->abs_ts; p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM); return; } else if (arp_request_count > global_arp_detect_request_storm_packets) { /* Storm detected, record and reset start time. */ report_storm = TRUE; p_add_proto_data(pinfo->fd, proto_arp, (void*)STORM); time_at_start_of_count = pinfo->fd->abs_ts; } else { /* Threshold not exceeded yet - no storm */ p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM); } } if (report_storm) { /* Report storm and reset counter */ proto_item *ti = proto_tree_add_none_format(tree, hf_arp_packet_storm, tvb, 0, 0, "Packet storm detected (%u packets in < %u ms)", global_arp_detect_request_storm_packets, global_arp_detect_request_storm_period); PROTO_ITEM_SET_GENERATED(ti); expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_NOTE, "ARP packet storm detected (%u packets in < %u ms)", global_arp_detect_request_storm_packets, global_arp_detect_request_storm_period); arp_request_count = 0; } }
/* dissect a bt dht values list from tvb, start at offset. it's like "l6:....6:....e" */ static int dissect_bt_dht_values(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label ) { proto_item *ti; proto_tree *sub_tree; proto_item *value_ti; proto_tree *value_tree; address addr; guint peer_index; guint string_len_start; guint string_len; guint16 port; ti = proto_tree_add_item( tree, hf_bt_dht_peers, tvb, offset, 0, ENC_NA ); sub_tree = proto_item_add_subtree( ti, ett_bt_dht_peers); peer_index = 0; /* we has confirmed that the first byte is 'l' */ offset += 1; /* dissect bt-dht values */ while( tvb_get_guint8(tvb,offset)!='e' ) { string_len_start = offset; while( tvb_get_guint8(tvb,offset) != ':' ) offset += 1; string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) ); /* skip the ':' */ offset += 1; /* 4 bytes ip, 2 bytes port */ for( ; string_len>=6; string_len-=6, offset+=6 ) { peer_index += 1; SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) ); port = tvb_get_letohl( tvb, offset+4 ); value_ti = proto_tree_add_none_format( sub_tree, hf_bt_dht_peer, tvb, offset, 6, "%d\t%s:%u", peer_index, ep_address_to_str( &addr ), port ); value_tree = proto_item_add_subtree( value_ti, ett_bt_dht_peers); proto_tree_add_item( value_tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item( value_tree, hf_port, tvb, offset+4, 2, ENC_BIG_ENDIAN); } /* truncated data */ if( string_len>0 ) { proto_tree_add_item( tree, hf_truncated_data, tvb, offset, string_len, ENC_NA ); offset += string_len; } } proto_item_set_text( ti, "%s: %d peers", label, peer_index ); col_append_fstr( pinfo->cinfo, COL_INFO, "reply=%d peers ", peer_index ); *result = ep_strdup_printf("%d peers", peer_index); return offset; }
static void add_double_coordinates( proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset, guint32 xoffset, guint32 yoffset, guint32 zoffset) { proto_item *ti; proto_tree * coord_tree; ti = proto_tree_add_none_format(tree, hf_mc_double_coords, tvb, offset, -1, "Coordinates: %f, %f, %f", tvb_get_ntohieee_double(tvb, offset+xoffset), tvb_get_ntohieee_double(tvb, offset+yoffset), tvb_get_ntohieee_double(tvb, offset+zoffset)); coord_tree = proto_item_add_subtree(ti, ett_mc_double_coords); proto_tree_add_item(coord_tree, hf_mc_x, tvb, offset + xoffset, 8, FALSE); proto_tree_add_item(coord_tree, hf_mc_y, tvb, offset + yoffset, 8, FALSE); proto_tree_add_item(coord_tree, hf_mc_z, tvb, offset + zoffset, 8, FALSE); }
void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset,guint uPrm,guint uVal,int hfindex) { header_field_info *hfinfo; guint8 *pVal; pVal=dissect_mqpcf_parm_getintval(uPrm,uVal); hfinfo=proto_registrar_get_nth(hfindex); if (pVal) { proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%d-%s", hfinfo->name, uVal, pVal); } else { proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%8x-%d", hfinfo->name, uVal, uVal); } }
int DDS_Dissector::dissect () { gint offset = 0; col_set_str(pinfo_->cinfo, COL_PROTOCOL, "OpenDDS"); col_clear(pinfo_->cinfo, COL_INFO); TransportHeader trans = demarshal_data<TransportHeader>(tvb_, offset); std::string trans_str(format(trans)); col_add_fstr(pinfo_->cinfo, COL_INFO, "DCPS %s", trans_str.c_str()); if (tree_ != NULL) { proto_item* item = proto_tree_add_protocol_format(tree_, proto_opendds, tvb_, 0, -1, "OpenDDS DCPS Protocol, %s", trans_str.c_str()); proto_tree* trans_tree = proto_item_add_subtree(item, ett_trans_header); this->dissect_transport_header (trans_tree, trans, offset); while (offset < gint(tvb_length(tvb_))) { DataSampleHeader sample = demarshal_data<DataSampleHeader>(tvb_, offset); std::string sample_str(format(sample)); proto_item* item = proto_tree_add_none_format (trans_tree, hf_sample, tvb_, offset, static_cast<gint>(sample.marshaled_size()) + sample.message_length_, "%s", sample_str.c_str() ); proto_tree* sample_tree = proto_item_add_subtree(item, ett_sample_header); this->dissect_sample_header (sample_tree, sample, offset); sample_tree = proto_item_add_subtree (item, ett_sample_header); this->dissect_sample_payload (sample_tree, sample, offset); } } return offset; }
static int dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label ) { proto_item *ti; proto_tree *sub_tree; proto_item *node_ti; proto_tree *node_tree; guint node_index; guint string_len_start; guint string_len; address addr; guint16 port; guint8 *id; ti = proto_tree_add_item( tree, hf_bt_dht_nodes, tvb, offset, 0, ENC_NA ); sub_tree = proto_item_add_subtree( ti, ett_bt_dht_nodes); node_index = 0; string_len_start = offset; while( tvb_get_guint8(tvb,offset) != ':' ) offset += 1; string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) ); /* skip the ':' */ offset += 1; /* 20 bytes id, 4 bytes ip, 2 bytes port */ for( ; string_len>=26; string_len-=26, offset+=26 ) { node_index += 1; id = tvb_bytes_to_str(tvb, offset, 20 ); SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) ); port = tvb_get_letohl( tvb, offset+24 ); node_ti = proto_tree_add_none_format( sub_tree, hf_bt_dht_node, tvb, offset, 26, "%d\t%s %s:%u", node_index, id, ep_address_to_str( &addr ), port ); node_tree = proto_item_add_subtree( node_ti, ett_bt_dht_peers); proto_tree_add_item( node_tree, hf_bt_dht_id, tvb, offset, 20, ENC_NA); proto_tree_add_item( node_tree, hf_ip, tvb, offset+20, 4, ENC_BIG_ENDIAN); proto_tree_add_item( node_tree, hf_port, tvb, offset+24, 2, ENC_BIG_ENDIAN); } if( string_len>0 ) { proto_tree_add_item( tree, hf_truncated_data, tvb, offset, string_len, ENC_NA ); offset += string_len; } proto_item_set_text( ti, "%s: %d nodes", label, node_index ); col_append_fstr( pinfo->cinfo, COL_INFO, "reply=%d nodes ", node_index ); *result = ep_strdup_printf("%d", node_index); return offset; }
/* Neighbor list is of the form: * HID_1 NUM_1 HA_11 HA_12 ... HA_1NUM_1 * HID_2 NUM_2 HA_21 HA_22 ... HA_2NUM_2 * ... * HID_count NUM_count HA_count1 HA_count2 ... HA_countNUM_count * * count == hid_count. */ static void dissect_nwp_nl(tvbuff_t *tvb, proto_tree *nwp_tree, guint8 hid_count, guint8 ha_len) { proto_tree *neigh_list_tree = NULL; proto_tree *neigh_tree = NULL; proto_item *pi = NULL; guint i; guint8 offset = NWPH_NLST; wmem_strbuf_t *hid_buf = wmem_strbuf_sized_new(wmem_packet_scope(), NWP_HID_STR_LEN, NWP_HID_STR_LEN); /* Set up tree for neighbor list. */ pi = proto_tree_add_item(nwp_tree, hf_nwp_neigh_list, tvb, NWPH_NLST, -1, ENC_NA); neigh_list_tree = proto_item_add_subtree(pi, ett_nwp_neigh_list_tree); for (i = 0; i < hid_count; i++) { const gchar *hid_str; guint j; guint8 ha_count = tvb_get_guint8(tvb, offset + NWP_XID_LEN); /* Set up tree for this individual neighbor. */ pi = proto_tree_add_none_format(neigh_list_tree, hf_nwp_neigh, tvb, offset, NWP_XID_LEN + 1 + ha_len * ha_count, "Neighbor %d", i + 1); neigh_tree = proto_item_add_subtree(pi, ett_nwp_neigh_tree); /* Add HID for this neighbor. */ wmem_strbuf_append(hid_buf, "hid-"); add_hid_to_strbuf(tvb, hid_buf, offset); hid_str = wmem_strbuf_get_str(hid_buf); proto_tree_add_string(neigh_tree, hf_nwp_neigh_hid, tvb, offset, NWP_XID_LEN, hid_str); wmem_strbuf_truncate(hid_buf, 0); offset += NWP_XID_LEN; /* Add number of devices this neighbor has. */ proto_tree_add_item(neigh_tree, hf_nwp_neigh_num, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* Add hardware addresses for the neighbor's devices. */ for (j = 0; j < ha_count; j++) proto_tree_add_item(neigh_tree, hf_nwp_neigh_haddr, tvb, offset + (j * ha_len), ha_len, ENC_NA); offset += ha_len * ha_count; } }
/* dissect one DCP block */ static int dissect_PNDCP_Block(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_item *dcp_item, guint8 service_id, gboolean is_response) { guint8 option; proto_item *block_item; proto_tree *block_tree; int ori_offset = offset; /* subtree for block */ block_item = proto_tree_add_none_format(tree, hf_pn_dcp_block, tvb, offset, 0, "Block: "); block_tree = proto_item_add_subtree(block_item, ett_pn_dcp_block); offset = dissect_pn_uint8(tvb, offset, pinfo, block_tree, hf_pn_dcp_option, &option); switch (option) { case PNDCP_OPTION_IP: offset = dissect_PNDCP_Suboption_IP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_DEVICE: offset = dissect_PNDCP_Suboption_Device(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_DHCP: offset = dissect_PNDCP_Suboption_DHCP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_CONTROL: offset = dissect_PNDCP_Suboption_Control(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_DEVICEINITIATIVE: offset = dissect_PNDCP_Suboption_DeviceInitiative(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_ALLSELECTOR: offset = dissect_PNDCP_Suboption_All(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); break; case PNDCP_OPTION_MANUF_X80: case PNDCP_OPTION_MANUF_X81: default: offset = dissect_PNDCP_Suboption_Manuf(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response); } proto_item_set_len(block_item, offset-ori_offset); if ((offset-ori_offset) & 1) { /* we have an odd number of bytes in this block, add a padding byte */ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1); } return offset; }
static void dissect_asf_payload_integrity(tvbuff_t *tvb, proto_tree *tree, gint offset, gint len) { guint8 alg; proto_item *ti; proto_tree *atree; alg = tvb_get_guint8(tvb, offset); ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset, len, "Integrity Algorithm: %s", val_to_str(alg, asf_integrity_type_vals, "Unknown (%u)")); atree = proto_item_add_subtree(ti, ett_asf_alg_payload); proto_tree_add_item(atree, hf_asf_integrity_alg, tvb, offset, 1,ENC_BIG_ENDIAN); proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA); }
static void add_int_coordinates( proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset, guint32 xoffset, guint x_size, guint32 yoffset, guint y_size, guint32 zoffset, guint z_size) { proto_item *ti; proto_tree * coord_tree; gint32 x,y,z; x = tvb_get_ntohint(tvb, offset+xoffset, x_size); y = tvb_get_ntohint(tvb, offset+yoffset, y_size); z = tvb_get_ntohint(tvb, offset+zoffset, z_size); ti = proto_tree_add_none_format(tree, hf_mc_int_coords, tvb, offset + xoffset, x_size + y_size + z_size, "Coordinates: %d, %d, %d", (gint32)tvb_get_ntohl(tvb, offset+xoffset), y, (gint32)tvb_get_ntohl(tvb, offset+zoffset)); coord_tree = proto_item_add_subtree(ti, ett_mc_int_coords); proto_tree_add_item_varint(coord_tree, hf_mc_xbyte, hf_mc_xint, tvb, offset+xoffset, 4); proto_tree_add_item_varint(coord_tree, hf_mc_ybyte, hf_mc_yint, tvb, offset+yoffset, 4); proto_tree_add_item_varint(coord_tree, hf_mc_zbyte, hf_mc_zint, tvb, offset+zoffset, 4); }
static void dissect_asf_payloads(tvbuff_t *tvb, proto_tree *tree, gint offset, gint len) { guint8 ptype; guint16 plen; proto_item *ti; proto_tree *ptree; while ( len >= 4 ) { ptype = tvb_get_guint8(tvb, offset); plen = tvb_get_ntohs(tvb, offset + 2); ti = proto_tree_add_none_format(tree, hf_asf_payload, tvb, offset, plen, "%s: %u bytes", val_to_str(ptype, asf_payload_type_vals, "Unknown (%u)"), plen); ptree = proto_item_add_subtree(ti, ett_asf_payload); proto_tree_add_item(ptree, hf_asf_payload_type, tvb, offset, 1,ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_asf_payload_len, tvb, offset + 2, 2,ENC_BIG_ENDIAN); if ( ptype && (plen > 4) ) { switch ( ptype ) { case ASF_PAYLOAD_TYPE_AUTHENTICATION: dissect_asf_payload_authentication(tvb, ptree, offset + 4, plen - 4); break; case ASF_PAYLOAD_TYPE_INTEGRITY: dissect_asf_payload_integrity(tvb, ptree, offset + 4, plen - 4); break; default: proto_tree_add_item(ptree, hf_asf_payload_data, tvb, offset + 4, plen - 4,ENC_NA); break; } } offset += plen; len -= plen; } }
/* dissect a bencoded list from tvb, start at offset. it's like "lXXXe", "X" is any bencoded thing */ static int dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label ) { proto_item *ti; proto_tree *sub_tree; guint one_byte; char *result; ti = proto_tree_add_none_format( tree, hf_bencoded_list, tvb, offset, 0, "%s: list...", label ); sub_tree = proto_item_add_subtree( ti, ett_bencoded_list); /* skip the 'l' */ offset += 1; while( (one_byte=tvb_get_guint8(tvb,offset)) != 'e' ) { switch( one_byte ) { /* a integer */ case 'i': offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &result, "Integer" ); break; /* a sub-list */ case 'l': offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Sub-list" ); break; /* a dictionary */ case 'd': offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Sub-dict" ); break; /* a string */ default: offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &result, FALSE, "String" ); break; } } offset += 1; return offset; }
/* Set System Boot Options */ static void rq08(tvbuff_t *tvb, proto_tree *tree) { proto_item *ti; proto_tree *s_tree; tvbuff_t *sub; guint8 pno; const char *desc; pno = tvb_get_guint8(tvb, 0) & 0x7f; if (pno < array_length(boot_options)) { desc = boot_options[pno].name; } else if (pno >= 96 && pno <= 127) { desc = "OEM"; } else { desc = "Reserved"; } ti = proto_tree_add_text(tree, tvb, 0, 1, "Boot option parameter selector: %s (0x%02x)", desc, pno); s_tree = proto_item_add_subtree(ti, ett_ipmi_chs_08_byte1); proto_tree_add_item(s_tree, hf_ipmi_chs_08_valid, tvb, 0, 1, TRUE); proto_tree_add_uint_format(s_tree, hf_ipmi_chs_08_selector, tvb, 0, 1, pno, "%sBoot option parameter selector: %s (0x%02x)", ipmi_dcd8(pno, 0x7f), desc, pno); /* Data is optional; no data means 'just set validity' */ if (tvb_length(tvb) > 1) { if (pno < array_length(boot_options)) { sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1); boot_options[pno].intrp(sub, tree); } else { proto_tree_add_none_format(tree, hf_ipmi_chs_08_data, tvb, 1, tvb_length(tvb) - 1, "Parameter data: %s", desc); } } }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree = NULL; proto_tree *header_tree = NULL; gint slen; gint rem; gint end = offset + len; const gchar *path = NULL; gint path_len; gint path_offset; const gchar *format = NULL; gint format_offset; gint format_len; const gchar *ptr = NULL; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi = NULL; proto_tree *blob_tree = NULL; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0UL) && (frac == 1UL) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri = NULL; proto_tree *rgba_tree = NULL; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str = NULL; const gchar *control_str = NULL; proto_item *mi = NULL; proto_tree *midi_tree = NULL; guint8 channel; guint8 status; guint8 data1; guint8 data2; channel = tvb_get_guint8(tvb, offset); status = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status_str = val_to_str_const(status, MIDI_status, "Unknown"); if(status == MIDI_STATUS_CONTROLLER) /* MIDI Controller */ { control_str = val_to_str_const(data1, MIDI_control, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), %s (0x%02x), 0x%02x", channel, status_str, status, control_str, data1, data2); } else mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), 0x%02x, 0x%02x", channel, status_str, status, data1, data2); midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(status == MIDI_STATUS_CONTROLLER) { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_value_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
static void dissect_llrp_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset) { guint8 has_length; guint16 len, type; guint real_len; proto_item *ti; proto_tree *param_tree; while (tvb_reported_length_remaining(tvb, offset) > 0) { has_length = !(tvb_get_guint8(tvb, offset) & 0x80); if (has_length) { len = tvb_get_ntohs(tvb, offset + 2); if (len < LLRP_TLV_LEN_MIN) real_len = LLRP_TLV_LEN_MIN; else if (len > tvb_reported_length_remaining(tvb, offset)) real_len = tvb_reported_length_remaining(tvb, offset); else real_len = len; ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb, offset, real_len, "TLV Parameter"); param_tree = proto_item_add_subtree(ti, ett_llrp_param); proto_tree_add_item(param_tree, hf_llrp_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ti = proto_tree_add_item(param_tree, hf_llrp_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN); if (len != real_len) expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Invalid length field: claimed %u, should be %u.", len, real_len); offset += 2; /* TODO: Decode actual TLV parameter fields */ /* The len field includes the 4-byte parameter header that we've * already accounted for in offset */ offset += real_len - 4; } else { type = tvb_get_guint8(tvb, offset) & 0x7F; /* TODO: Decode actual TV fields rather than just jumping * ahead the correct length */ switch (type) { case LLRP_TV_ANTENNA_ID: real_len = LLRP_TV_LEN_ANTENNA_ID; break; case LLRP_TV_FIRST_SEEN_TIME_UTC: real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UTC; break; case LLRP_TV_FIRST_SEEN_TIME_UPTIME: real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UPTIME; break; case LLRP_TV_LAST_SEEN_TIME_UTC: real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UTC; break; case LLRP_TV_LAST_SEEN_TIME_UPTIME: real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UPTIME; break; case LLRP_TV_PEAK_RSSI: real_len = LLRP_TV_LEN_PEAK_RSSI; break; case LLRP_TV_CHANNEL_INDEX: real_len = LLRP_TV_LEN_CHANNEL_INDEX; break; case LLRP_TV_TAG_SEEN_COUNT: real_len = LLRP_TV_LEN_TAG_SEEN_COUNT; break; case LLRP_TV_RO_SPEC_ID: real_len = LLRP_TV_LEN_RO_SPEC_ID; break; case LLRP_TV_INVENTORY_PARAM_SPEC_ID: real_len = LLRP_TV_LEN_INVENTORY_PARAM_SPEC_ID; break; case LLRP_TV_C1G2_CRC: real_len = LLRP_TV_LEN_C1G2_CRC; break; case LLRP_TV_C1G2_PC: real_len = LLRP_TV_LEN_C1G2_PC; break; case LLRP_TV_EPC96: real_len = LLRP_TV_LEN_EPC96; break; case LLRP_TV_SPEC_INDEX: real_len = LLRP_TV_LEN_SPEC_INDEX; break; case LLRP_TV_CLIENT_REQ_OP_SPEC_RES: real_len = LLRP_TV_LEN_CLIENT_REQ_OP_SPEC_RES; break; case LLRP_TV_ACCESS_SPEC_ID: real_len = LLRP_TV_LEN_ACCESS_SPEC_ID; break; case LLRP_TV_OP_SPEC_ID: real_len = LLRP_TV_LEN_OP_SPEC_ID; break; case LLRP_TV_C1G2_SINGULATION_DET: real_len = LLRP_TV_LEN_C1G2_SINGULATION_DET; break; case LLRP_TV_C1G2_XPC_W1: real_len = LLRP_TV_LEN_C1G2_XPC_W1; break; case LLRP_TV_C1G2_XPC_W2: real_len = LLRP_TV_LEN_C1G2_XPC_W2; break; default: /* ??? * No need to mark it, since the hf_llrp_tv_type field * will already show up as 'unknown'. */ real_len = 0; break; }; ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb, offset, real_len + 1, "TV Parameter"); param_tree = proto_item_add_subtree(ti, ett_llrp_param); proto_tree_add_item(param_tree, hf_llrp_tv_type, tvb, offset, 1, ENC_NA); offset++; /* Unlike for TLV's, real_len for TV's doesn't include the standard * header length, so just add it straight to the offset. */ offset += real_len; } } }
/* Process an APP0 block. * * XXX - This code only works on US-ASCII systems!!! */ static int process_app0_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len, guint16 marker, const char *marker_name) { proto_item *ti; proto_tree *subtree; proto_tree *subtree_details = NULL; guint32 offset; char *str; gint str_size; guint16 x, y; if (!tree) return 0; ti = proto_tree_add_item(tree, hf_marker_segment, tvb, 0, -1, ENC_NA); subtree = proto_item_add_subtree(ti, ett_marker_segment); proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker); proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN); str = tvb_get_stringz_enc(wmem_packet_scope(), tvb, 4, &str_size, ENC_ASCII); ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA); if (strcmp(str, "JFIF") == 0) { /* Version */ ti = proto_tree_add_none_format(subtree, hf_version, tvb, 9, 2, "Version: %u.%u", tvb_get_guint8(tvb, 9), tvb_get_guint8(tvb, 10)); subtree_details = proto_item_add_subtree(ti, ett_details); proto_tree_add_item(subtree_details, hf_version_major, tvb, 9, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree_details, hf_version_minor, tvb, 10, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_units, tvb, 11, 1, ENC_BIG_ENDIAN); /* Aspect ratio */ proto_tree_add_item(subtree, hf_xdensity, tvb, 12, 2, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_ydensity, tvb, 14, 2, ENC_BIG_ENDIAN); /* Thumbnail */ proto_tree_add_item(subtree, hf_xthumbnail, tvb, 16, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_ythumbnail, tvb, 17, 1, ENC_BIG_ENDIAN); x = tvb_get_guint8(tvb, 16); y = tvb_get_guint8(tvb, 17); if (x || y) { proto_tree_add_item(subtree, hf_rgb, tvb, 18, 3 * (x * y), ENC_NA); offset = 18 + (3 * (x * y)); } else { offset = 18; } } else if (strcmp(str, "JFXX") == 0) { proto_tree_add_item(subtree, hf_extension_code, tvb, 9, 1, ENC_BIG_ENDIAN); /* XXX - dissect the extension based on its extension code */ offset = 10; } else { /* Unknown */ proto_item_append_text(ti, " (unknown identifier)"); offset = 4 + str_size; proto_tree_add_bytes_format_value(subtree, hf_remain_seg_data, tvb, offset, -1, NULL, "%u bytes", len - 2 - str_size); } return offset; }
/* Check to see if this mac & ip pair represent 2 devices trying to share the same IP address - report if found (+ return TRUE and set out param) */ static gboolean check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, const guint8 *mac, guint32 ip, guint32 *duplicate_ip) { struct address_hash_value *value; gboolean return_value = FALSE; /* Look up any existing entries */ value = g_hash_table_lookup(address_hash_table, GUINT_TO_POINTER(ip)); /* If MAC matches table, just update details */ if (value != NULL) { if (pinfo->fd->num > value->frame_num) { if ((memcmp(value->mac, mac, 6) == 0)) { /* Same MAC as before - update existing entry */ value->frame_num = pinfo->fd->num; value->time_of_entry = pinfo->fd->abs_ts.secs; } else { /* Doesn't match earlier MAC - report! */ proto_tree *duplicate_tree; /* Create subtree */ proto_item *ti = proto_tree_add_none_format(tree, hf_arp_duplicate_ip_address, tvb, 0, 0, "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)", arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP), ether_to_str(mac), ether_to_str(value->mac), value->frame_num); PROTO_ITEM_SET_GENERATED(ti); duplicate_tree = proto_item_add_subtree(ti, ett_arp_duplicate_address); /* Add item for navigating to earlier frame */ ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame, tvb, 0, 0, value->frame_num); PROTO_ITEM_SET_GENERATED(ti); expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, "Duplicate IP address configured (%s)", arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP)); /* Time since that frame was seen */ ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_seconds_since_earlier_frame, tvb, 0, 0, (guint32)(pinfo->fd->abs_ts.secs - value->time_of_entry)); PROTO_ITEM_SET_GENERATED(ti); *duplicate_ip = ip; return_value = TRUE; } } } else { /* No existing entry. Prepare one */ value = se_alloc(sizeof(struct address_hash_value)); memcpy(value->mac, mac, 6); value->frame_num = pinfo->fd->num; value->time_of_entry = pinfo->fd->abs_ts.secs; /* Add it */ g_hash_table_insert(address_hash_table, GUINT_TO_POINTER(ip), value); } return return_value; }
/* Process an APP0 block. * * XXX - This code only works on US-ASCII systems!!! */ static int process_app0_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len, guint16 marker, const char *marker_name) { proto_item *ti = NULL; proto_tree *subtree = NULL; proto_tree *subtree_details = NULL; guint32 offset; char *str; gint str_size; if (!tree) return 0 ; ti = proto_tree_add_item(tree, hf_marker_segment, tvb, 0, -1, ENC_NA); subtree = proto_item_add_subtree(ti, ett_marker_segment); proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker); proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN); str = tvb_get_ephemeral_stringz(tvb, 4, &str_size); ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA); if (strcmp(str, "JFIF") == 0) { /* Version */ ti = proto_tree_add_none_format(subtree, hf_version, tvb, 9, 2, "Version: %u.%u", tvb_get_guint8(tvb, 9), tvb_get_guint8(tvb, 10)); subtree_details = proto_item_add_subtree(ti, ett_details); proto_tree_add_item(subtree_details, hf_version_major, tvb, 9, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree_details, hf_version_minor, tvb, 10, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_units, tvb, 11, 1, ENC_BIG_ENDIAN); /* Aspect ratio */ proto_tree_add_item(subtree, hf_xdensity, tvb, 12, 2, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_ydensity, tvb, 14, 2, ENC_BIG_ENDIAN); /* Thumbnail */ proto_tree_add_item(subtree, hf_xthumbnail, tvb, 16, 1, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_ythumbnail, tvb, 17, 1, ENC_BIG_ENDIAN); { guint16 x = tvb_get_guint8(tvb, 16); guint16 y = tvb_get_guint8(tvb, 17); if (x || y) { proto_tree_add_item(subtree, hf_rgb, tvb, 18, 3 * (x * y), ENC_NA); offset = 18 + (3 * (x * y)); } else { offset = 18; } } } else if (strcmp(str, "JFXX") == 0) { proto_tree_add_item(subtree, hf_extension_code, tvb, 9, 1, ENC_BIG_ENDIAN); { guint8 code = tvb_get_guint8(tvb, 9); switch (code) { case 0x10: /* Thumbnail coded using JPEG */ break; case 0x11: /* thumbnail stored using 1 byte per pixel */ break; case 0x13: /* thumbnail stored using 3 bytes per pixel */ break; default: /* Error */ break; } } offset = 10; } else { /* Unknown */ proto_item_append_text(ti, " (unknown identifier)"); offset = 4 + str_size; proto_tree_add_text(subtree, tvb, offset, -1, "Remaining segment data (%u bytes)", len - 2 - str_size); } return offset; }
static void expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int severity, int hf_index, gboolean use_vaformat, const char *format, va_list ap) { char formatted[ITEM_LABEL_LENGTH]; int tap; expert_info_t *ei; proto_tree *tree; proto_item *ti; if (pinfo == NULL && pi && pi->tree_data) { pinfo = PTREE_DATA(pi)->pinfo; } /* if this packet isn't loaded because of a read filter, don't output anything */ if (pinfo == NULL || pinfo->num == 0) { return; } if (severity > highest_severity) { highest_severity = severity; } /* XXX: can we get rid of these checks and make them programming errors instead now? */ if (pi != NULL && PITEM_FINFO(pi) != NULL) { expert_set_item_flags(pi, group, severity); } if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) || ((guint)severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK))) { col_add_str(pinfo->cinfo, COL_EXPERT, val_to_str(severity, expert_severity_vals, "Unknown (%u)")); } if (use_vaformat) { g_vsnprintf(formatted, ITEM_LABEL_LENGTH, format, ap); } else { g_strlcpy(formatted, format, ITEM_LABEL_LENGTH); } tree = expert_create_tree(pi, group, severity, formatted); if (hf_index == -1) { /* If no filterable expert info, just add the message */ ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted); PROTO_ITEM_SET_GENERATED(ti); } else { /* If filterable expert info, hide the "generic" form of the message, and generate the formatted filterable expert info */ ti = proto_tree_add_none_format(tree, hf_index, NULL, 0, 0, "%s", formatted); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted); PROTO_ITEM_SET_HIDDEN(ti); } ti = proto_tree_add_uint_format_value(tree, hf_expert_severity, NULL, 0, 0, severity, "%s", val_to_str_const(severity, expert_severity_vals, "Unknown")); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint_format_value(tree, hf_expert_group, NULL, 0, 0, group, "%s", val_to_str_const(group, expert_group_vals, "Unknown")); PROTO_ITEM_SET_GENERATED(ti); tap = have_tap_listener(expert_tap); if (!tap) return; ei = wmem_new(wmem_packet_scope(), expert_info_t); ei->packet_num = pinfo->num; ei->group = group; ei->severity = severity; ei->hf_index = hf_index; ei->protocol = pinfo->current_proto; ei->summary = wmem_strdup(wmem_packet_scope(), formatted); /* if we have a proto_item (not a faked item), set expert attributes to it */ if (pi != NULL && PITEM_FINFO(pi) != NULL) { ei->pitem = pi; } /* XXX: remove this because we don't have an internal-only function now? */ else { ei->pitem = NULL; } tap_queue_packet(expert_tap, pinfo, ei); }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree; proto_tree *header_tree; gint slen; gint rem; gint end = offset + len; const gchar *path; gint path_len; gint path_offset; const gchar *format; gint format_offset; gint format_len; const gchar *ptr; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi; proto_tree *blob_tree; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri; proto_tree *rgba_tree; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str; proto_item *mi = NULL; proto_tree *midi_tree; guint8 port; guint8 command; guint8 data1; guint8 data2; guint8 status; guint8 channel; gboolean system_msg; guint8 status_shifted; port = tvb_get_guint8(tvb, offset); command = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status = command & 0xF0; channel = command & 0x0F; system_msg = status == 0xF0; /* is system message */ status_shifted = status >> 4; if(system_msg) status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown"); else status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown"); if(system_msg) { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, %s, %i, %i", port, status_str, data1, data2); } else { switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: case MIDI_STATUS_NOTE_PRESSURE: { const gchar *note_str; note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, note_str, data2); break; } case MIDI_STATUS_CONTROLLER: { const gchar *control_str; control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, control_str, data2); break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i", port, channel, status_str, bender); break; } default: { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i, %i", port, channel, status_str, data1, data2); break; } } } midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(system_msg) { proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_NOTE_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CONTROLLER: { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CHANNEL_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender); offset += 2; break; } default: { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } } } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
bool dissect_protobuf_message(const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *tree, string& displayText, bool bRoot) { map<string, Handles*>::iterator it = g_mapHandles.find( message->GetDescriptor()->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } int iMsgLen = message->ByteSize(); // if not root field then submessage needs to be computed if( !bRoot ) { *offset += WireFormat::TagSize( message->GetDescriptor()->index(), FieldDescriptor::TYPE_MESSAGE ); *offset += io::CodedOutputStream::VarintSize32( iMsgLen ); } Handles* handles = it->second; proto_item* item = proto_tree_add_none_format( tree, handles->p_id, tvb, *offset, iMsgLen, "%s",displayText.c_str() ); proto_tree* subTree = proto_item_add_subtree( item, *(handles->indices) ); const Reflection *reflection = message->GetReflection(); // dissect field vector<const FieldDescriptor*> fieldList; reflection->ListFields(*message, &fieldList); for( vector<const FieldDescriptor*>::iterator itField = fieldList.begin(); itField!=fieldList.end(); itField++ ) { const FieldDescriptor* field = *itField; bool bMessage = ( FieldDescriptor::CPPTYPE_MESSAGE == field->cpp_type() ); if (field->is_repeated()) { int iRepeatedSize = reflection->FieldSize( *message, field ); for( int iRepeatedIndex = 0; iRepeatedIndex < iRepeatedSize; iRepeatedIndex++ ) { if (bMessage) { const Message& subMessage = reflection->GetRepeatedMessage( *message, field, iRepeatedIndex ); dissect_protobuf_message(&subMessage, tvb, offset, subTree, string(field->name()), false); } else { dissect_protobuf_repeated_field(field, message, tvb, offset, subTree, iRepeatedIndex); } } } else { if (bMessage) { const Message& subMessage = reflection->GetMessage( *message, field ); dissect_protobuf_message(&subMessage, tvb, offset, subTree, string(field->name()), false); } else { dissect_protobuf_field(field, message, tvb, offset, subTree); } } } // end for (int iFieldIndex = 0; iFieldIndex < message->field_count(); iFieldIndex++) return true; }
static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Logical packet representation */ struct _alc alc; /* Offset for subpacket dissection */ guint offset; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *alc_tree; /* Flute or not */ tvbuff_t *new_tvb; gboolean is_flute = FALSE; /* Structures and variables initialization */ offset = 0; memset(&alc, 0, sizeof(struct _alc)); /* Update packet info */ pinfo->current_proto = "ALC"; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC"); col_clear(pinfo->cinfo, COL_INFO); /* ALC header dissection */ /* --------------------- */ alc.version = hi_nibble(tvb_get_guint8(tvb, offset)); if (tree) { /* Create subtree for the ALC protocol */ ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA); alc_tree = proto_item_add_subtree(ti, ett.main); /* Fill the ALC subtree */ proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version); } else alc_tree = NULL; /* This dissector supports only ALCv1 packets. * If alc.version > 1 print only version field and quit. */ if (alc.version == 1) { struct _lct_ptr l; struct _fec_ptr f; l.lct = &alc.lct; l.hf = &hf.lct; l.ett = &ett.lct; l.prefs = &preferences.lct; f.fec = &alc.fec; f.hf = &hf.fec; f.ett = &ett.fec; f.prefs = &preferences.fec; /* LCT header dissection */ /* --------------------- */ is_flute = lct_dissector(l, f, tvb, alc_tree, &offset); /* FEC header dissection */ /* --------------------- */ /* Only if it's present and if LCT dissector has determined FEC Encoding ID * FEC dissector should be called with fec->encoding_id* and fec->instance_id* filled */ if (alc.fec.encoding_id_present && tvb_length(tvb) > offset) fec_dissector(f, tvb, alc_tree, &offset); /* Add the Payload item */ if (tvb_length(tvb) > offset){ if(is_flute){ new_tvb = tvb_new_subset_remaining(tvb,offset); call_dissector(xml_handle, new_tvb, pinfo, alc_tree); }else{ proto_tree_add_none_format(alc_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset); } } /* Complete entry in Info column on summary display */ /* ------------------------------------------------ */ if (check_col(pinfo->cinfo, COL_INFO)) { lct_info_column(&alc.lct, pinfo); fec_info_column(&alc.fec, pinfo); } /* Free g_allocated memory */ lct_dissector_free(&alc.lct); fec_dissector_free(&alc.fec); } else { if (tree) proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only"); /* Complete entry in Info column on summary display */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", alc.version); } }
static void dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_item *volatile ti = NULL, *comment_item; guint cap_len = 0, frame_len = 0; proto_tree *volatile tree; proto_tree *comments_tree; proto_item *item; const gchar *cap_plurality, *frame_plurality; tree=parent_tree; pinfo->current_proto = "Frame"; if (pinfo->pseudo_header != NULL) { switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_WFLEET_HDLC: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: case WTAP_ENCAP_SDLC: case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_BLUETOOTH_HCI: pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: case WTAP_ENCAP_FRELAY_WITH_PHDR: pinfo->p2p_dir = (pinfo->pseudo_header->x25.flags & FROM_DCE) ? P2P_DIR_RECV : P2P_DIR_SENT; break; case WTAP_ENCAP_ISDN: case WTAP_ENCAP_V5_EF: case WTAP_ENCAP_DPNSS: case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_LINUX_LAPD: pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 || pinfo->pseudo_header->lapd.pkttype == 4) ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_MTP2_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ? P2P_DIR_SENT : P2P_DIR_RECV; pinfo->link_number = pinfo->pseudo_header->mtp2.link_number; pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used; break; case WTAP_ENCAP_GSM_UM: pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ? P2P_DIR_SENT : P2P_DIR_RECV; break; } } if(pinfo->fd->opt_comment){ item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, -1, ENC_NA); comments_tree = proto_item_add_subtree(item, ett_comments); comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, -1, pinfo->fd->opt_comment, "%s", pinfo->fd->opt_comment); expert_add_info_format(pinfo, comment_item, PI_COMMENTS_GROUP, PI_COMMENT, "%s", pinfo->fd->opt_comment); } /* if FRAME is not referenced from any filters we dont need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_frame)) { tree=NULL; if(pinfo->fd->flags.has_ts) { if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } } else { proto_tree *fh_tree; gboolean old_visible; /* Put in frame header information. */ cap_len = tvb_length(tvb); frame_len = tvb_reported_length(tvb); cap_plurality = plurality(cap_len, "", "s"); frame_plurality = plurality(frame_len, "", "s"); ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1, "Frame %u: %u byte%s on wire", pinfo->fd->num, frame_len, frame_plurality); if (generate_bits_field) proto_item_append_text(ti, " (%u bits)", frame_len * 8); proto_item_append_text(ti, ", %u byte%s captured", cap_len, cap_plurality); if (generate_bits_field) { proto_item_append_text(ti, " (%u bits)", cap_len * 8); } if (pinfo->fd->flags.has_if_id) { proto_item_append_text(ti, " on interface %u", pinfo->fd->interface_id); } if (pinfo->fd->flags.has_pack_flags) { if (pinfo->fd->pack_flags & 0x00000001) { proto_item_append_text(ti, " (inbound)"); pinfo->p2p_dir = P2P_DIR_RECV; } if (pinfo->fd->pack_flags & 0x00000002) { proto_item_append_text(ti, " (outbound)"); pinfo->p2p_dir = P2P_DIR_SENT; } } fh_tree = proto_item_add_subtree(ti, ett_frame); if (pinfo->fd->flags.has_if_id) proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->fd->interface_id); if (pinfo->fd->flags.has_pack_flags) { proto_tree *flags_tree; proto_item *flags_item; flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->fd->pack_flags); flags_tree = proto_item_add_subtree(flags_item, ett_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->fd->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->fd->pack_flags); } proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t); if (pinfo->fd->flags.has_ts) { proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb, 0, 0, &(pinfo->fd->abs_ts)); if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) { item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb, 0, 0, "Arrival Time: Fractional second %09ld is invalid," " the valid range is 0-1000000000", (long) pinfo->fd->abs_ts.nsecs); PROTO_ITEM_SET_GENERATED(item); expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb, 0, 0, &(pinfo->fd->shift_offset)); PROTO_ITEM_SET_GENERATED(item); if(generate_epoch_time) { proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb, 0, 0, &(pinfo->fd->abs_ts)); } if (proto_field_is_referenced(tree, hf_frame_time_delta)) { nstime_t del_cap_ts; frame_delta_abs_time(pinfo->fd, pinfo->fd->prev_cap, &del_cap_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb, 0, 0, &(del_cap_ts)); PROTO_ITEM_SET_GENERATED(item); } if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) { nstime_t del_dis_ts; frame_delta_abs_time(pinfo->fd, pinfo->fd->prev_dis, &del_dis_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb, 0, 0, &(del_dis_ts)); PROTO_ITEM_SET_GENERATED(item); } item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb, 0, 0, &(pinfo->fd->rel_ts)); PROTO_ITEM_SET_GENERATED(item); if(pinfo->fd->flags.ref_time){ ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA); PROTO_ITEM_SET_GENERATED(ti); } } proto_tree_add_uint(fh_tree, hf_frame_number, tvb, 0, 0, pinfo->fd->num); proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb, 0, 0, frame_len, "Frame Length: %u byte%s (%u bits)", frame_len, frame_plurality, frame_len * 8); proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb, 0, 0, cap_len, "Capture Length: %u byte%s (%u bits)", cap_len, cap_plurality, cap_len * 8); if (generate_md5_hash) { const guint8 *cp; md5_state_t md_ctx; md5_byte_t digest[16]; const gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); md5_init(&md_ctx); md5_append(&md_ctx, cp, cap_len); md5_finish(&md_ctx, digest); digest_string = bytestring_to_str(digest, 16, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored); PROTO_ITEM_SET_GENERATED(ti); if(proto_field_is_referenced(tree, hf_frame_protocols)) { /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ old_visible = proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); proto_tree_set_visible(fh_tree, old_visible); pinfo->layer_names = g_string_new(""); } else pinfo->layer_names = NULL; /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } /* Check for existences of MTP2 link number */ if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) { proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } if (show_file_off) { proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } if(pinfo->fd->color_filter != NULL) { const color_filter_t *color_filter = pinfo->fd->color_filter; item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } } if (pinfo->fd->flags.ignored) { /* Ignored package, stop handling here */ col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>"); proto_tree_add_text (tree, tvb, 0, -1, "This frame is marked as ignored"); return; } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations. (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif if ((force_docsis_encap) && (docsis_handle)) { call_dissector(docsis_handle, tvb, pinfo, parent_tree); } else { if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", pinfo->fd->lnk_t); call_dissector(data_handle,tvb, pinfo, parent_tree); } } #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if (tree && pinfo->layer_names) { proto_item_append_string(ti, pinfo->layer_names->str); g_string_free(pinfo->layer_names, TRUE); pinfo->layer_names = NULL; } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } tap_queue_packet(frame_tap, pinfo, NULL); if (pinfo->frame_end_routines) { g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL); g_slist_free(pinfo->frame_end_routines); pinfo->frame_end_routines = NULL; } }
static gint dissect_userdata(proto_item *ti_arg, gint ett_arg, tvbuff_t *tvb, gint arg_offset) { gint offset = arg_offset; guint8 flen, lenbytes; guint8 year, month, day, hour, min, sec; guint16 msec; proto_tree *tree; proto_item *ti; tree = proto_item_add_subtree(ti_arg, ett_arg); /* length of User Data, should be 1 byte field ... */ flen = tvb_get_guint8(tvb, offset); lenbytes = 1; /* ... but sometimes it seems to be 2 bytes; try to be clever */ if (flen == 0) { flen = tvb_get_guint8(tvb, offset+1); lenbytes = 2; } if (flen == 0 || flen > 79) /* invalid */ return offset; ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN); offset += lenbytes; if (lenbytes == 2) { proto_item_append_text(ti, " (2 bytes, should be 1 byte)"); } if (tvb_reported_length_remaining(tvb, offset) <= 0) return offset; proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if (tvb_reported_length_remaining(tvb, offset) <= 0) return offset; proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if (tvb_reported_length_remaining(tvb, offset) <= 0) return offset; proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* show the rest */ /* tree2 = proto_tree_add_subtree(tree, tvb, offset, -1, "User Data"); */ if (tvb_reported_length_remaining(tvb, offset) <= 0) return offset; ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN); proto_item_append_text(ti, " <-- '0' = no restart etc."); offset +=1; if (tvb_reported_length_remaining(tvb, offset+8) <= 0) return offset; year = tvb_get_guint8(tvb, offset); month = tvb_get_guint8(tvb, offset+1); day = tvb_get_guint8(tvb, offset+2); hour = tvb_get_guint8(tvb, offset+3); min = tvb_get_guint8(tvb, offset+4); sec = tvb_get_guint8(tvb, offset+5); msec = tvb_get_ntohs(tvb, offset+6); proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8, "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d", year+1900, month, day, hour, min, sec, msec); offset += 12; if (tvb_reported_length_remaining(tvb, offset+12) > 0) { proto_item_append_text(ti, " Security info: "); } /* security info field, if present */ while (tvb_reported_length_remaining(tvb, offset) > 0) { proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o", tvb_get_guint8(tvb, offset)); offset++; } return offset; }
static void dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_item *volatile ti = NULL; nstime_t ts; int cap_len = 0, frame_len = 0; proto_tree *volatile tree; proto_item *item; guint32 frame_number; frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps will show the packetnumber where the crash occurred. */ tree=parent_tree; pinfo->current_proto = "Frame"; if (pinfo->pseudo_header != NULL) { switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_WFLEET_HDLC: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: case WTAP_ENCAP_SDLC: case WTAP_ENCAP_BLUETOOTH_H4: case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_BLUETOOTH_HCI: pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: case WTAP_ENCAP_FRELAY_WITH_PHDR: pinfo->p2p_dir = (pinfo->pseudo_header->x25.flags & FROM_DCE) ? P2P_DIR_RECV : P2P_DIR_SENT; break; case WTAP_ENCAP_ISDN: pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_LINUX_LAPD: pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 || pinfo->pseudo_header->lapd.pkttype == 4) ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_MTP2_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ? P2P_DIR_SENT : P2P_DIR_RECV; pinfo->link_number = pinfo->pseudo_header->mtp2.link_number; pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used; break; case WTAP_ENCAP_GSM_UM: pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ? P2P_DIR_SENT : P2P_DIR_RECV; break; } } /* if FRAME is not referenced from any filters we dont need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_frame)) { tree=NULL; if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } else { proto_tree *fh_tree; /* Put in frame header information. */ cap_len = tvb_length(tvb); frame_len = tvb_reported_length(tvb); ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1, "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, frame_len, cap_len); fh_tree = proto_item_add_subtree(ti, ett_frame); ts = pinfo->fd->abs_ts; proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb, 0, 0, &ts); if(ts.nsecs < 0 || ts.nsecs >= 1000000000) { item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb, 0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs); PROTO_ITEM_SET_GENERATED(item); expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } ts = pinfo->fd->del_cap_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); ts = pinfo->fd->del_dis_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); ts = pinfo->fd->rel_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); if(pinfo->fd->flags.ref_time){ ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, FALSE); PROTO_ITEM_SET_GENERATED(ti); } proto_tree_add_uint(fh_tree, hf_frame_number, tvb, 0, 0, pinfo->fd->num); proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb, 0, 0, frame_len, "Frame Length: %d byte%s", frame_len, plurality(frame_len, "", "s")); proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb, 0, 0, cap_len, "Capture Length: %d byte%s", cap_len, plurality(cap_len, "", "s")); if (generate_md5_hash) { const guint8 *cp; md5_state_t md_ctx; md5_byte_t digest[16]; gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); md5_init(&md_ctx); md5_append(&md_ctx, cp, cap_len); md5_finish(&md_ctx, digest); digest_string = bytestring_to_str(digest, 16, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); pinfo->layer_names = g_string_new(""); /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } /* Check for existences of MTP2 link number */ if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) { proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } if (show_file_off) { proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } if(pinfo->fd->color_filter != NULL) { color_filter_t *color_filter = pinfo->fd->color_filter; item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ __try { #endif if ((force_docsis_encap) && (docsis_handle)) { call_dissector(docsis_handle, tvb, pinfo, parent_tree); } else { if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u", pinfo->fd->lnk_t); call_dissector(data_handle,tvb, pinfo, parent_tree); } } #ifdef _MSC_VER } __except(TRUE /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if (tree && pinfo->layer_names) { proto_item_append_string(ti, pinfo->layer_names->str); g_string_free(pinfo->layer_names, TRUE); pinfo->layer_names = NULL; } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(TRUE /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } tap_queue_packet(frame_tap, pinfo, NULL); if (frame_end_routines) { g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL); g_slist_free(frame_end_routines); frame_end_routines = NULL; } }
/* Decode an EXT_FTI extension and fill FEC array */ void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f) { proto_item* ti = NULL; proto_tree *ext_tree; if (tree) ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length, "EXT_FTI, FEC Object Transmission Information (%u)", e->het); if (f.fec->encoding_id_present) { ext_tree = proto_item_add_subtree(ti, ett); rmt_ext_decode_default_header(e, tvb, ext_tree); /* Decode 48-bit length field */ f.fec->transfer_length = tvb_get_ntoh64(tvb, e->offset) & G_GINT64_CONSTANT(0xFFFFFFFFFFFFU); if (f.fec->encoding_id >= 128) { /* Decode FEC Instance ID */ f.fec->instance_id_present = TRUE; f.fec->instance_id = (guint8) tvb_get_ntohs(tvb, e->offset+8); } if (tree) proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length); switch (f.fec->encoding_id) { case 0: case 2: case 128: case 130: f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10); f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12); if (tree) { proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length); proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length); } break; case 129: f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10); f.fec->max_source_block_length = tvb_get_ntohs(tvb, e->offset+12); f.fec->max_number_encoding_symbols = tvb_get_ntohs(tvb, e->offset+14); if (tree) { proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length); proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 2, f.fec->max_source_block_length); proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+14, 2, f.fec->max_number_encoding_symbols); } break; case 132: f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10); f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12); f.fec->max_number_encoding_symbols = tvb_get_ntohl(tvb, e->offset+16); if (tree) { proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length); proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length); proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+16, 4, f.fec->max_number_encoding_symbols); } break; } } else if (tree) rmt_ext_decode_default_subtree(e, tvb, ti, ett); }
static gint dissect_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, proto_tree *tree, gint offset, guint8 *parameter, gint *parameter_offset) { proto_item *parameter_item; proto_item *pitem; proto_tree *ptree; tvbuff_t *next_tvb; guint parameter_id; guint parameter_length; guint parameter_padding_length; guint padding_length; guint length; guint16 max_msg_size; guint8 connection_status; guint8 result_code; guint8 disconnection_type; guint8 status_change; guint8 transport_protocol; parameter_id = tvb_get_guint8(tvb, offset); parameter_length = tvb_get_ntohs(tvb, offset + 2); parameter_padding_length = parameter_length % 4; if (parameter_padding_length > 0) parameter_padding_length = 4 - parameter_padding_length; parameter_item = proto_tree_add_none_format(tree, hf_btsap_parameter, tvb, offset, 2 + 2 + parameter_length + parameter_padding_length, "Parameter: %s: ", val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID")); ptree = proto_item_add_subtree(parameter_item, ett_btsap_parameter); proto_tree_add_item(ptree, hf_btsap_parameter_id, tvb, offset, 1, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID")); offset += 1; proto_tree_add_item(ptree, hf_btsap_parameter_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; pitem = proto_tree_add_item(ptree, hf_btsap_parameter_length, tvb, offset, 2, ENC_BIG_ENDIAN); proto_item_append_text(pitem, " (in 4 bytes sections, padding length: %u)", parameter_padding_length); offset += 2; switch(parameter_id) { case 0x00: /* MaxMsgSize */ proto_tree_add_item(ptree, hf_btsap_parameter_max_msg_size, tvb, offset, 2, ENC_BIG_ENDIAN); max_msg_size = tvb_get_ntohs(tvb, offset); proto_item_append_text(parameter_item, "%u", max_msg_size); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", max_msg_size); length = 2; padding_length = 2; break; case 0x01: /* ConnectionStatus */ proto_tree_add_item(ptree, hf_btsap_parameter_connection_status, tvb, offset, 1, ENC_BIG_ENDIAN); connection_status = tvb_get_guint8(tvb, offset); proto_item_append_text(parameter_item, "%s", val_to_str_const(connection_status, connection_status_vals, "Unknown")); col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(connection_status, connection_status_vals, "Unknown")); length = 1; padding_length = 3; break; case 0x02: /* ResultCode */ proto_tree_add_item(ptree, hf_btsap_parameter_result_code, tvb, offset, 1, ENC_BIG_ENDIAN); result_code = tvb_get_guint8(tvb, offset); proto_item_append_text(parameter_item, "%s", val_to_str_const(result_code, result_code_vals, "Unknown")); col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(result_code, result_code_vals, "Unknown")); length = 1; padding_length = 3; break; case 0x03: /* DisconnectionType */ proto_tree_add_item(ptree, hf_btsap_parameter_disconnection_type, tvb, offset, 1, ENC_BIG_ENDIAN); disconnection_type = tvb_get_guint8(tvb, offset); proto_item_append_text(parameter_item, "%s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown")); col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown")); length = 1; padding_length = 3; break; case 0x04: /* CommandAPDU */ /* GSM 11.11 */ if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) { next_tvb = tvb_new_subset_length(tvb, offset, parameter_length); col_append_str(pinfo->cinfo, COL_INFO, ": "); if (top_dissect == TOP_DISSECT_INTERNAL) { call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree); } else { col_clear(pinfo->cinfo, COL_INFO); call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree); } } else { proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA); } length = parameter_length; padding_length = parameter_padding_length; break; case 0x05: /* ResponseAPDU */ /* GSM 11.11 or ISO/IEC 7816-4; depend of TRANSFER_APDU_REQ */ if (gsm_sim_resp_handle && top_dissect != TOP_DISSECT_OFF) { next_tvb = tvb_new_subset_length(tvb, offset, parameter_length); col_append_str(pinfo->cinfo, COL_INFO, ": "); if (top_dissect == TOP_DISSECT_INTERNAL) { call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, ptree); } else { col_clear(pinfo->cinfo, COL_INFO); call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, top_tree); } } else { proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA); } length = parameter_length; padding_length = parameter_padding_length; break; case 0x06: /* ATR */ /* ISO/IEC 7816-3 */ if (iso7816_atr_handle && top_dissect != TOP_DISSECT_OFF) { next_tvb = tvb_new_subset_length(tvb, offset, parameter_length); col_append_str(pinfo->cinfo, COL_INFO, ": "); if (top_dissect == TOP_DISSECT_INTERNAL) { call_dissector(iso7816_atr_handle, next_tvb, pinfo, ptree); } else { col_clear(pinfo->cinfo, COL_INFO); call_dissector(iso7816_atr_handle, next_tvb, pinfo, top_tree); } } else { proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA); } length = parameter_length; padding_length = parameter_padding_length; break; case 0x07: /* CardReaderStatus */ /* 3GPP TS 11.14 */ proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_powered, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_present, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present_lower, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_removable, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_identity, tvb, offset, 1, ENC_BIG_ENDIAN); length = 1; padding_length = 3; break; case 0x08: /* StatusChange */ proto_tree_add_item(ptree, hf_btsap_parameter_status_change, tvb, offset, 1, ENC_BIG_ENDIAN); status_change = tvb_get_guint8(tvb, offset); proto_item_append_text(parameter_item, "%s", val_to_str_const(status_change, status_change_vals, "Unknown")); col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(status_change, status_change_vals, "Unknown")); length = 1; padding_length = 3; break; case 0x09: /* TransportProtocol */ proto_tree_add_item(ptree, hf_btsap_parameter_transport_protocol, tvb, offset, 1, ENC_BIG_ENDIAN); transport_protocol = tvb_get_guint8(tvb, offset); proto_item_append_text(parameter_item, "%u", transport_protocol); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", transport_protocol); length = 1; padding_length = 3; break; case 0x10: /* CommandAPDU7816 */ /* ISO/IEC 7816-4 */ if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) { next_tvb = tvb_new_subset_length(tvb, offset, parameter_length); col_append_str(pinfo->cinfo, COL_INFO, ": "); if (top_dissect == TOP_DISSECT_INTERNAL) { call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree); } else { col_clear(pinfo->cinfo, COL_INFO); call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree); } } else { proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA); } length = parameter_length; padding_length = parameter_padding_length; break; default: proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA); length = parameter_length; padding_length = parameter_padding_length; } *parameter = parameter_id; *parameter_offset = offset; if (length != parameter_length || padding_length != parameter_padding_length) { /* Malformed frame */ expert_add_info_format(pinfo, pitem, &ei_btsap_parameter_error, "Parameter Length does not meet content length"); } offset += parameter_length; if (parameter_padding_length > 0) { pitem = proto_tree_add_item(ptree, hf_btsap_parameter_padding, tvb, offset, parameter_padding_length, ENC_NA); proto_item_append_text(pitem, " (length %d)", parameter_padding_length); offset += parameter_padding_length; } return offset; }