static void dissect_rssi(tvbuff_t *tvb, proto_tree *tree) { gint32 rssi; rssi = (-1)*((gint32)tvb_get_guint8(tvb, get_rssi_index())); proto_tree_add_int(tree, hf_nordic_ble_rssi, tvb, get_rssi_index(), 1, rssi); }
bool dissect_protobuf_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf) { int len = WireFormat::FieldByteSize( field, *message ); map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT32: proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetFloat( *message, field ) ); break; case FieldDescriptor::CPPTYPE_UINT64: proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT64: proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetDouble( *message, field ) ); break; case FieldDescriptor::CPPTYPE_BOOL: proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetBool( *message, field ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetEnum( *message, field ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetString( *message, field ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }
/* Dissect an individual actrace ISDN message */ static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *actrace_tree) { /* Declare variables */ gint len; gint32 value, trunk; tvbuff_t *next_tvb; int offset = 0; len = tvb_get_ntohs(tvb, 44); value = tvb_get_ntohl(tvb, offset+4); proto_tree_add_int(actrace_tree, hf_actrace_isdn_direction, tvb, offset+4, 4, value); offset += 8; trunk = tvb_get_ntohs(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_isdn_trunk, tvb, offset, 2, trunk); offset = 44; proto_tree_add_int(actrace_tree, hf_actrace_isdn_length, tvb, offset, 2, len); /* if it is a q931 packet (we don't want LAPD packets for Voip Graph) add tap info */ if (len > 4) { /* Initialise packet info for passing to tap */ actrace_pi = ep_new(actrace_info_t); actrace_pi->type = ACTRACE_ISDN; actrace_pi->direction = (value==PSTN_TO_BLADE?1:0); actrace_pi->trunk = trunk; /* Report this packet to the tap */ tap_queue_packet(actrace_tap, pinfo, actrace_pi); } /* Dissect lapd payload */ offset += 2 ; next_tvb = tvb_new_subset(tvb, offset, len, len); call_dissector(lapd_handle, next_tvb, pinfo, tree); col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_ISDN"); col_prepend_fstr(pinfo->cinfo, COL_INFO, "Trunk:%d Blade %s PSTN " , trunk, value==PSTN_TO_BLADE?"<--":"-->"); }
static void dissect_pw_padding(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { /* do not touch columns */ if (tree) { gint size; proto_item* item; size = tvb_reported_length_remaining(tvb, 0); item = proto_tree_add_item(tree, proto_pw_padding, tvb, 0, -1, FALSE); pwc_item_append_text_n_items(item,size,"byte"); { proto_tree* tree_p; tree_p = proto_item_add_subtree(item, ett); call_dissector(dh_data, tvb, pinfo, tree_p); item = proto_tree_add_int(tree_p, hf_padding_len, tvb, 0, 0, size); PROTO_ITEM_SET_HIDDEN(item); /*allow filtering*/ } } return; }
static void dissect_wlancap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *wlan_tree = NULL; proto_item *ti; tvbuff_t *next_tvb; int offset; guint32 version; guint32 length; guint32 channel; guint32 datarate; guint32 ssi_type; guint32 antnoise; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_ntohl(tvb, offset) - WLANCAP_MAGIC_COOKIE_BASE; length = tvb_get_ntohl(tvb, offset+4); col_add_fstr(pinfo->cinfo, COL_INFO, "AVS WLAN Capture v%x, Length %d",version, length); if (version > 2) { goto skip; } /* Dissect the AVS header */ if (tree) { ti = proto_tree_add_item(tree, proto_wlancap, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_radio); proto_tree_add_item(wlan_tree, hf_wlan_magic, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(wlan_tree, hf_wlan_version, tvb, offset, 4, ENC_BIG_ENDIAN); } offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_length, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_mactime, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; if (tree) proto_tree_add_item(wlan_tree, hf_hosttime, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_phytype, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; /* XXX cook channel (fh uses different numbers) */ channel = tvb_get_ntohl(tvb, offset); if (channel < 256) { col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", channel); if (tree) proto_tree_add_uint(wlan_tree, hf_channel, tvb, offset, 4, channel); } else if (channel < 10000) { col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", channel); if (tree) proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset, 4, channel, "Frequency: %u MHz", channel); } else { col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u KHz", channel); if (tree) proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset, 4, channel, "Frequency: %u KHz", channel); } offset+=4; datarate = tvb_get_ntohl(tvb, offset); if (datarate < 100000) { /* In units of 100 Kb/s; convert to b/s */ datarate *= 100000; } col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u", datarate / 1000000, ((datarate % 1000000) > 500000) ? 5 : 0); if (tree) { proto_tree_add_uint64_format(wlan_tree, hf_data_rate, tvb, offset, 4, datarate, "Data Rate: %u.%u Mb/s", datarate/1000000, ((datarate % 1000000) > 500000) ? 5 : 0); } offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_antenna, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_priority, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; ssi_type = tvb_get_ntohl(tvb, offset); if (tree) proto_tree_add_uint(wlan_tree, hf_wlan_ssi_type, tvb, offset, 4, ssi_type); offset+=4; switch (ssi_type) { case SSI_NONE: default: /* either there is no SSI information, or we don't know what type it is */ break; case SSI_NORM_RSSI: /* Normalized RSSI */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (norm)", tvb_get_ntohl(tvb, offset)); if (tree) proto_tree_add_item(wlan_tree, hf_normrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN); break; case SSI_DBM: /* dBm */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", tvb_get_ntohl(tvb, offset)); if (tree) proto_tree_add_item(wlan_tree, hf_dbm_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN); break; case SSI_RAW_RSSI: /* Raw RSSI */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (raw)", tvb_get_ntohl(tvb, offset)); if (tree) proto_tree_add_item(wlan_tree, hf_rawrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN); break; } offset+=4; antnoise = tvb_get_ntohl(tvb, offset); /* 0xffffffff means "hardware does not provide noise data" */ if (antnoise != 0xffffffff) { switch (ssi_type) { case SSI_NONE: default: /* either there is no SSI information, or we don't know what type it is */ break; case SSI_NORM_RSSI: /* Normalized RSSI */ if (tree) proto_tree_add_uint(wlan_tree, hf_normrssi_antnoise, tvb, offset, 4, antnoise); break; case SSI_DBM: /* dBm */ if (tree) proto_tree_add_int(wlan_tree, hf_dbm_antnoise, tvb, offset, 4, antnoise); break; case SSI_RAW_RSSI: /* Raw RSSI */ if (tree) proto_tree_add_uint(wlan_tree, hf_rawrssi_antnoise, tvb, offset, 4, antnoise); break; } } offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_preamble, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_encoding, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (version > 1) { if (tree) proto_tree_add_item(wlan_tree, hf_wlan_sequence, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_drops, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_receiver_addr, tvb, offset, 6, ENC_NA); offset+=6; if (tree) proto_tree_add_item(wlan_tree, hf_wlan_padding, tvb, offset, 2, ENC_NA); offset+=2; } skip: offset = length; /* dissect the 802.11 header next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(ieee80211_handle, next_tvb, pinfo, tree); }
static void dissect_pw_satop(tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; enum { PAY_NO_IDEA = 0 ,PAY_LIKE_E1 ,PAY_LIKE_T1 ,PAY_LIKE_E3_T3 ,PAY_LIKE_OCTET_ALIGNED_T1 } payload_properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_cw_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = 0; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 0) & 0x03 /*rsv*/)) { properties |= PWC_CW_BAD_RSV; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC4553: * [...MAY be used to carry the length of the SAToP * packet (defined as the size of the SAToP header + the payload * size) if it is less than 64 bytes, and MUST be set to zero * otherwise... ] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC4553's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } if (payload_size == 0) { /* * As CW.L it indicates that PW payload is invalid, dissector should * not blame packets with bad payload (including "bad" or "strange" SIZE of * payload) when L bit is set. */ if (0 == (tvb_get_guint8(tvb_original, 0) & 0x08 /*L bit*/)) { properties |= PWC_PAY_SIZE_BAD; } } /* guess about payload type */ if (payload_size == 256) { payload_properties = PAY_LIKE_E1; } else if (payload_size == 192) { payload_properties = PAY_LIKE_T1; } else if (payload_size == 1024) { payload_properties = PAY_LIKE_E3_T3; } else if ((payload_size != 0) && (payload_size % 25 == 0)) { payload_properties = PAY_LIKE_OCTET_ALIGNED_T1; } else { payload_properties = PAY_NO_IDEA; /*we do not have any ideas about payload type*/ } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:0 (Bad)"); } else { col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); } if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2, tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item2, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } proto_tree_add_item(tree3, hf_cw_l , tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree3, hf_cw_r , tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_rsv, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_RSV) { expert_add_info(pinfo, item3, &ei_cw_rsv); } item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_payload_size_invalid, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_payload_size_invalid, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_payload_size_invalid, "Bad Length: must be 0 if SAToP packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid, "SAToP payload: none found. Size of payload must be <> 0"); } else if (payload_size == 0) { expert_add_info(pinfo, item, &ei_payload_size_invalid_undecoded); } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); { proto_tree* tree3; const char* s; switch(payload_properties) { case PAY_LIKE_E1: s = " (looks like E1)"; break; case PAY_LIKE_T1: s = " (looks like T1)"; break; case PAY_LIKE_E3_T3: s = " (looks like E3/T3)"; break; case PAY_LIKE_OCTET_ALIGNED_T1: s = " (looks like octet-aligned T1)"; break; case PAY_NO_IDEA: default: s = ""; break; } proto_item_append_text(item2, "%s", s); tree3 = proto_item_add_subtree(item2, ett); call_data_dissector(tvb, pinfo, tree3); item2 = proto_tree_add_int(tree3, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
static void dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int direction) { proto_tree *cl_tree = NULL; proto_tree *text_tree = NULL; guint8 text[MAX_TEXT_SIZE+1]; int len; int offset; guint32 marker; int command_len; const char *command = ""; gboolean command_finished = FALSE; marker = tvb_get_ntohl(tvb, 0); if (tree) { proto_item *cl_item; cl_item = proto_tree_add_text(tree, tvb, 0, -1, "Connectionless"); cl_tree = proto_item_add_subtree(cl_item, ett_quakeworld_connectionless); proto_tree_add_uint(cl_tree, hf_quakeworld_connectionless_marker, tvb, 0, 4, marker); } /* all the rest of the packet is just text */ offset = 4; len = tvb_get_nstringz0(tvb, offset, sizeof(text), text); /* actually, we should look for a eol char and stop already there */ if (cl_tree) { proto_item *text_item; text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text, tvb, offset, len + 1, text); text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text); } if (direction == DIR_C2S) { /* client to server commands */ const char *c; Cmd_TokenizeString(text); c = Cmd_Argv(0); /* client to sever commands */ if (strcmp(c,"ping") == 0) { command = "Ping"; command_len = 4; } else if (strcmp(c,"status") == 0) { command = "Status"; command_len = 6; } else if (strcmp(c,"log") == 0) { command = "Log"; command_len = 3; } else if (strcmp(c,"connect") == 0) { int version; int qport; int challenge; const char *infostring; proto_tree *argument_tree = NULL; command = "Connect"; command_len = Cmd_Argv_length(0); if (text_tree) { proto_item *argument_item; proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); argument_item = proto_tree_add_string(text_tree, hf_quakeworld_connectionless_arguments, tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1), text + Cmd_Argv_start(1)); argument_tree = proto_item_add_subtree(argument_item, ett_quakeworld_connectionless_arguments); command_finished=TRUE; } version = atoi(Cmd_Argv(1)); qport = atoi(Cmd_Argv(2)); challenge = atoi(Cmd_Argv(3)); infostring = Cmd_Argv(4); if (argument_tree) { proto_item *info_item; proto_tree *info_tree; proto_tree_add_uint(argument_tree, hf_quakeworld_connectionless_connect_version, tvb, offset + Cmd_Argv_start(1), Cmd_Argv_length(1), version); proto_tree_add_uint(argument_tree, hf_quakeworld_connectionless_connect_qport, tvb, offset + Cmd_Argv_start(2), Cmd_Argv_length(2), qport); proto_tree_add_int(argument_tree, hf_quakeworld_connectionless_connect_challenge, tvb, offset + Cmd_Argv_start(3), Cmd_Argv_length(3), challenge); info_item = proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_connect_infostring, tvb, offset + Cmd_Argv_start(4), Cmd_Argv_length(4), infostring); info_tree = proto_item_add_subtree( info_item, ett_quakeworld_connectionless_connect_infostring); dissect_id_infostring(tvb, info_tree, offset + Cmd_Argv_start(4), ep_strdup(infostring), ett_quakeworld_connectionless_connect_infostring_key_value, hf_quakeworld_connectionless_connect_infostring_key_value, hf_quakeworld_connectionless_connect_infostring_key, hf_quakeworld_connectionless_connect_infostring_value); } } else if (strcmp(c,"getchallenge") == 0) { command = "Get Challenge"; command_len = Cmd_Argv_length(0); } else if (strcmp(c,"rcon") == 0) { const char* password; int i; char remaining[MAX_TEXT_SIZE+1]; proto_tree *argument_tree = NULL; command = "Remote Command"; command_len = Cmd_Argv_length(0); if (text_tree) { proto_item *argument_item; proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); argument_item = proto_tree_add_string(text_tree, hf_quakeworld_connectionless_arguments, tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1), text + Cmd_Argv_start(1)); argument_tree = proto_item_add_subtree(argument_item, ett_quakeworld_connectionless_arguments); command_finished=TRUE; } password = Cmd_Argv(1); if (argument_tree) { proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_rcon_password, tvb, offset + Cmd_Argv_start(1), Cmd_Argv_length(1), password); } remaining[0] = '\0'; for (i=2; i<Cmd_Argc() ; i++) { g_strlcat (remaining, Cmd_Argv(i), MAX_TEXT_SIZE+1); g_strlcat (remaining, " ", MAX_TEXT_SIZE+1); } if (text_tree) { proto_tree_add_string(argument_tree, hf_quakeworld_connectionless_rcon_command, tvb, offset + Cmd_Argv_start(2), Cmd_Argv_start(Cmd_Argc()-1) + Cmd_Argv_length(Cmd_Argc()-1) - Cmd_Argv_start(2), remaining); } } else if (c[0]==A2A_PING && ( c[1]=='\0' || c[1]=='\n')) { command = "Ping"; command_len = 1; } else if (c[0]==A2A_ACK && ( c[1]=='\0' || c[1]=='\n')) { command = "Ack"; command_len = 1; } else { command = "Unknown"; command_len = len; } } else { /* server to client commands */ if (text[0] == S2C_CONNECTION) { command = "Connected"; command_len = 1; } else if (text[0] == A2C_CLIENT_COMMAND) { command = "Client Command"; command_len = 1; /* stringz (command), stringz (localid) */ } else if (text[0] == A2C_PRINT) { command = "Print"; command_len = 1; /* string */ } else if (text[0] == A2A_PING) { command = "Ping"; command_len = 1; } else if (text[0] == S2C_CHALLENGE) { command = "Challenge"; command_len = 1; /* string, atoi */ } else { command = "Unknown"; command_len = len; } } if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command); } if (text_tree && !command_finished) { proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command, tvb, offset, command_len, command); } offset += len + 1; }
/* 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; }
static int dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *signature_tree; proto_tree *name_tree; proto_tree *signedinfo_tree; proto_tree *content_tree; proto_item *titem; struct ccn_parsed_ContentObject co; struct ccn_parsed_ContentObject *pco = &co; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t blob_size; const unsigned char *blob; int l; unsigned int i; double dt; nstime_t timestamp; int res; comps = ccn_indexbuf_create(); res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps); if (res < 0) return (-1); /* Signature */ l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]; titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE); signature_tree = proto_item_add_subtree(titem, ett_signature); /* DigestAlgorithm */ l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb, pco->offset[CCN_PCO_B_DigestAlgorithm], pco->offset[CCN_PCO_E_DigestAlgorithm], &blob, &blob_size); titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb, blob - ccnb, blob_size, FALSE); } /* Witness */ l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness]; if (l > 0) { /* add the witness item to the signature tree */ } /* Signature bits */ l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb, pco->offset[CCN_PCO_B_SignatureBits], pco->offset[CCN_PCO_E_SignatureBits], &blob, &blob_size); titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb, blob - ccnb, blob_size, blob); } /* /Signature */ /* Name */ l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pco->offset[CCN_PCO_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); /* Name Components */ for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* /Name */ /* SignedInfo */ l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]; titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_SignedInfo], l, "SignedInfo"); signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo); /* PublisherPublicKeyDigest */ l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb, pco->offset[CCN_PCO_B_PublisherPublicKeyDigest], pco->offset[CCN_PCO_E_PublisherPublicKeyDigest], &blob, &blob_size); titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob); } /* Timestamp */ l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb, pco->offset[CCN_PCO_B_Timestamp], pco->offset[CCN_PCO_E_Timestamp], &blob, &blob_size); dt = 0.0; for (i = 0; i < blob_size; i++) dt = dt * 256.0 + (double)blob[i]; dt /= 4096.0; timestamp.secs = dt; /* truncates */ timestamp.nsecs = (dt - (double) timestamp.secs) * 1000000000.0; titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, ×tamp); } /* Type */ l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb, pco->offset[CCN_PCO_B_Type], pco->offset[CCN_PCO_E_Type], &blob, &blob_size); titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type); } else { titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type); } /* FreshnessSeconds */ l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds], &blob, &blob_size); i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds]); titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i); } /* FinalBlockID */ l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb, pco->offset[CCN_PCO_B_FinalBlockID], pco->offset[CCN_PCO_E_FinalBlockID], &blob, &blob_size); titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE); } /* TODO: KeyLocator */ /* /SignedInfo */ /* Content */ l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content]; res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb, pco->offset[CCN_PCO_B_Content], pco->offset[CCN_PCO_E_Content], &blob, &blob_size); titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_Content], l, "Content: %d bytes", blob_size); if (blob_size > 0) { content_tree = proto_item_add_subtree(titem, ett_content); titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE); } return (ccnb_size); }
static int add_option_info(tvbuff_t *tvb, int pos, proto_tree *tree, proto_item *ti) { guint8 tag, length, fcs_err = 0, encr = 0, seen_fcs_err = 0; /* * Read all option tags in an endless loop. If the packet is malformed this * loop might be a problem. */ while (TRUE) { tag = tvb_get_guint8(tvb, pos++); switch (tag) { case TZSP_HDR_PAD: length = 0; break; case TZSP_HDR_END: /* Fill in header with information from other tags. */ if (seen_fcs_err) { if (tree) proto_item_append_text(ti,"%s", fcs_err?"FCS Error":(encr?"Encrypted":"Good")); } return pos; case TZSP_HDR_ORIGINAL_LENGTH: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_original_length, tvb, pos-2, 4, tvb_get_ntohs(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_SIGNAL: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_signal, tvb, pos-2, 3, (char)tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_NOISE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_silence, tvb, pos-2, 3, (char)tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_RATE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_rate, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_TIMESTAMP: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_time, tvb, pos-2, 6, tvb_get_ntohl(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_MSG_TYPE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_status_msg_type, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_CF: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_pcf, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_UN_DECR: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_undecrypted, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); encr = tvb_get_guint8(tvb, pos); pos += length; break; case WLAN_RADIO_HDR_FCS_ERR: seen_fcs_err = 1; length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_fcs_error, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); fcs_err = tvb_get_guint8(tvb, pos); pos += length; break; case WLAN_RADIO_HDR_CHANNEL: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_channel, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case TZSP_HDR_SENSOR: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_ether(tree, hf_sensormac, tvb, pos-2, 6, tvb_get_ptr (tvb, pos, 6)); pos += length; break; default: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_bytes(tree, hf_unknown, tvb, pos-2, length+2, tvb_get_ptr(tvb, pos, length)); pos += length; break; } } }
/* Dissect an individual actrace CAS message */ static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree) { /* Declare variables */ gint32 value, function, trunk, bchannel, source, event, curr_state, next_state; gint32 par0, par1, par2; gchar *frame_label = NULL; int direction = 0; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS"); value = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value); offset += 4; source = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source); offset += 4; curr_state = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state); offset += 4; event = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event); offset += 4; next_state = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state); offset += 4; function = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function); offset += 4; col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|", val_to_str_const(source, actrace_cas_source_vals_short, "ukn"), curr_state, val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"), next_state, val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d")); par0 = tvb_get_ntohl(tvb, offset); switch (function) { case SEND_EVENT: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d")); break; case CHANGE_COLLECT_TYPE: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str(par0, actrace_cas_collect_type_vals, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str(par0, actrace_cas_collect_type_vals, "%d")); break; case SEND_MF: case SEND_DEST_NUM: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str(par0, actrace_cas_send_type_vals, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str(par0, actrace_cas_send_type_vals, "%d")); break; default: proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0); } offset += 4; par1 = tvb_get_ntohl(tvb, offset); if (function == SEND_EVENT) { proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 1: %s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d")); } else { proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1); } offset += 4; par2 = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2); offset += 4; trunk = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk); offset += 4; bchannel = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel); offset += 4; col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel); value = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value); /* Add tap info for the Voip Graph */ if (source == ACTRACE_CAS_SOURCE_DSP) { direction = 1; if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) { frame_label = ep_strdup_printf("AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") ); } else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */ frame_label = ep_strdup_printf("MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") ); } else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */ frame_label = ep_strdup_printf("DTMF: %u", par0 ); } } else if (source == ACTRACE_CAS_SOURCE_TABLE) { direction = 0; if (function == SEND_MF) { if (par0 == SEND_TYPE_SPECIFIC ) { frame_label = ep_strdup_printf("MF: %u", par1); } else if (par0 == SEND_TYPE_ADDRESS ) { frame_label = ep_strdup("MF: DNIS digit"); } else if (par0 == SEND_TYPE_ANI ) { frame_label = ep_strdup("MF: ANI digit"); } else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) { frame_label = ep_strdup("MF: src_category"); } else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) { frame_label = ep_strdup("MF: trf_capability"); } else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) { frame_label = ep_strdup("MF: inter_exch_sw"); } } else if (function == SEND_CAS) { frame_label = ep_strdup_printf("AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR")); } else if (function == SEND_DEST_NUM) { if (par0 == SEND_TYPE_ADDRESS ) { frame_label = ep_strdup("DTMF/MF: sending DNIS"); } else if (par0 == SEND_TYPE_ANI ) { frame_label = ep_strdup("DTMF/MF: sending ANI"); } } } if (frame_label != NULL) { /* Initialise packet info for passing to tap */ actrace_pi = ep_new(actrace_info_t); actrace_pi->type = ACTRACE_CAS; actrace_pi->direction = direction; actrace_pi->trunk = trunk; actrace_pi->cas_bchannel = bchannel; actrace_pi->cas_frame_label = frame_label; /* Report this packet to the tap */ tap_queue_packet(actrace_tap, pinfo, actrace_pi); } }
bool dissect_protobuf_repeated_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf, int iRepeatedIndex) { int len = 0; string scratch; if( !field->options().packed() ) { len += WireFormat::TagSize( field->number(), field->type() ); } map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: if( field->type() == FieldDescriptor::TYPE_FIXED32 ) { len += WireFormatLite::kFixed32Size; } else { len += WireFormatLite::UInt32Size( reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT32: if( field->type() == FieldDescriptor::TYPE_SFIXED32 ) { len += WireFormatLite::kSFixed32Size; } else if( field->type() == FieldDescriptor::TYPE_SINT32 ) { len += WireFormatLite::SInt32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: len += WireFormatLite::kFloatSize; proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedFloat( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_UINT64: if( field->type() == FieldDescriptor::TYPE_FIXED64 ) { len += WireFormatLite::kFixed64Size; } else { len += WireFormatLite::UInt64Size( reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT64: if( field->type() == FieldDescriptor::TYPE_SFIXED64 ) { len += WireFormatLite::kSFixed64Size; } else if( field->type() == FieldDescriptor::TYPE_SINT64 ) { len += WireFormatLite::SInt64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: len += WireFormatLite::kDoubleSize; proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedDouble( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_BOOL: len += WireFormatLite::kBoolSize; proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedBool( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetRepeatedEnum( *message, field, iRepeatedIndex ); len += WireFormatLite::EnumSize( enumDesc->number() ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: len += WireFormatLite::StringSize( reflection->GetRepeatedStringReference( *message, field, iRepeatedIndex, &scratch ) ); proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedString( *message, field, iRepeatedIndex ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s, *t; gint32 num_nonsupported_options; proto_item *ti; proto_tree *shrub; guint32 auth_type; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item_ret_uint(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN, &auth_type); switch (auth_type) { case PGSQL_AUTH_TYPE_CRYPT: case PGSQL_AUTH_TYPE_MD5: n += 4; siz = (auth_type == PGSQL_AUTH_TYPE_CRYPT ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); break; case PGSQL_AUTH_TYPE_GSSAPI_SSPI_CONTINUE: conv_data->auth_state = PGSQL_AUTH_GSSAPI_SSPI_DATA; proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-8, ENC_NA); break; case PGSQL_AUTH_TYPE_SASL: conv_data->auth_state = PGSQL_AUTH_SASL_REQUESTED; n += 4; while ((guint)n < length) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; } break; case PGSQL_AUTH_TYPE_SASL_CONTINUE: case PGSQL_AUTH_TYPE_SASL_COMPLETE: conv_data->auth_state = PGSQL_AUTH_SASL_CONTINUE; n += 4; if ((guint)n < length) { proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA); } break; } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; /* Negotiate Protocol Version */ case 'v': proto_tree_add_item(tree, hf_supported_minor_version, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item_ret_int(tree, hf_number_nonsupported_options, tvb, n, 4, ENC_BIG_ENDIAN, &num_nonsupported_options); n += 4; while (num_nonsupported_options > 0) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_nonsupported_option, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; num_nonsupported_options--; } break; } }
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s; proto_tree *shrub; gint32 data_length; switch (type) { /* Password, SASL or GSSAPI Response, depending on context */ case 'p': switch(conv_data->auth_state) { case PGSQL_AUTH_SASL_REQUESTED: /* SASLInitResponse */ siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; proto_tree_add_item_ret_int(tree, hf_sasl_auth_data_length, tvb, n, 4, ENC_BIG_ENDIAN, &data_length); n += 4; if (data_length) { proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, data_length, ENC_NA); n += data_length; } break; case PGSQL_AUTH_SASL_CONTINUE: proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-4, ENC_NA); break; case PGSQL_AUTH_GSSAPI_SSPI_DATA: proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-4, ENC_NA); break; default: siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA); break; } break; /* Simple query */ case 'Q': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Parse */ case 'P': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Bind */ case 'B': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Execute */ case 'E': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohl(tvb, n); if (i == 0) proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows"); else proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i); break; /* Describe, Close */ case 'D': case 'C': c = tvb_get_guint8(tvb, n); if (c == 'P') i = hf_portal; else i = hf_statement; n += 1; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, i, tvb, n, siz, s); break; /* Messages without a type identifier */ case '\0': i = tvb_get_ntohl(tvb, n); n += 4; length -= n; switch (i) { /* Startup message */ case 196608: proto_tree_add_item(tree, hf_version_major, tvb, n-4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_version_minor, tvb, n-2, 2, ENC_BIG_ENDIAN); while ((signed)length > 0) { siz = tvb_strsize(tvb, n); length -= siz; if ((signed)length <= 0) { break; } proto_tree_add_item(tree, hf_parameter_name, tvb, n, siz, ENC_ASCII|ENC_NA); i = tvb_strsize(tvb, n+siz); proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i, ENC_ASCII|ENC_NA); length -= i; n += siz+i; if (length == 1 && tvb_get_guint8(tvb, n) == 0) break; } break; /* SSL request */ case 80877103: /* Next reply will be a single byte. */ conv_data->ssl_requested = TRUE; break; /* Cancellation request */ case 80877102: proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Copy failure */ case 'f': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Function call */ case 'F': proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); break; } }
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree) { guchar c; gint i, siz; char *s; proto_tree *shrub; switch (type) { /* Password */ case 'p': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Simple query */ case 'Q': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Parse */ case 'P': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Bind */ case 'B': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Execute */ case 'E': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohl(tvb, n); if (i == 0) proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows"); else proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i); break; /* Describe, Close */ case 'D': case 'C': c = tvb_get_guint8(tvb, n); if (c == 'P') i = hf_portal; else i = hf_statement; n += 1; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, i, tvb, n, siz, s); break; /* Messages without a type identifier */ case '\0': i = tvb_get_ntohl(tvb, n); n += 4; length -= n; switch (i) { /* Startup message */ case 196608: while ((signed)length > 0) { siz = tvb_strsize(tvb, n); length -= siz; if ((signed)length <= 0) { break; } proto_tree_add_item(tree, hf_parameter_name, tvb, n, siz, ENC_ASCII|ENC_NA); i = tvb_strsize(tvb, n+siz); proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i, ENC_ASCII|ENC_NA); length -= i; n += siz+i; if (length == 1 && tvb_get_guint8(tvb, n) == 0) break; } break; /* SSL request */ case 80877103: /* There's nothing to parse here, but what do we do if the SSL negotiation succeeds? */ break; /* Cancellation request */ case 80877102: proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Copy failure */ case 'f': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Function call */ case 'F': proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); break; } }
static void dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 type; tvbuff_t *next_tvb; proto_item *ti=NULL; proto_tree *hci_h1_tree = NULL; void *pd_save; hci_data_t *hci_data; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCI"); col_clear(pinfo->cinfo, COL_INFO); type = pinfo->pseudo_header->bthci.channel; if(tree){ ti = proto_tree_add_item(tree, proto_hci_h1, tvb, 0, 0, ENC_NA); hci_h1_tree = proto_item_add_subtree(ti, ett_hci_h1); if(pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) proto_item_append_text(hci_h1_tree, " %s %s", val_to_str(pinfo->p2p_dir, hci_h1_direction_vals, "Unknown: %d"), val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); else proto_item_append_text(hci_h1_tree, " %s", val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); } if(check_col(pinfo->cinfo, COL_INFO)){ if(pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", val_to_str(pinfo->p2p_dir, hci_h1_direction_vals, "Unknown: %d"), val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); else col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); } pd_save = pinfo->private_data; hci_data = ep_alloc(sizeof(hci_data_t)); hci_data->interface_id = HCI_INTERFACE_H4; hci_data->adapter_id = HCI_ADAPTER_DEFAULT; hci_data->chandle_to_bdaddr_table = chandle_to_bdaddr_table; hci_data->bdaddr_to_name_table = bdaddr_to_name_table; hci_data->localhost_bdaddr = localhost_bdaddr; hci_data->localhost_name = localhost_name; pinfo->private_data = hci_data; ti=proto_tree_add_int(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir); PROTO_ITEM_SET_GENERATED(ti); next_tvb = tvb_new_subset_remaining(tvb, 0); if(!dissector_try_uint(hci_h1_table, type, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); } pinfo->private_data = pd_save; }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree) { guchar c; gint i, siz; char *s, *t; proto_item *ti; proto_tree *shrub; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN); i = tvb_get_ntohl(tvb, n); if (i == 4 || i == 5) { /* i -= (6-i); :-) */ n += 4; siz = (i == 4 ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_NA); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; } }
static void dissect_nettl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *nettl_tree; proto_item *nettl_item; pinfo->current_proto = "nettl"; if (tree) { nettl_item = proto_tree_add_protocol_format(tree, proto_nettl, tvb, 0, -1, "HP-UX Network Tracing and Logging (nettl) header"); nettl_tree = proto_item_add_subtree(nettl_item, ett_nettl); proto_tree_add_uint_format(nettl_tree, hf_nettl_subsys, tvb, 0, 0, pinfo->pseudo_header->nettl.subsys, "Subsystem: %d (%s)", pinfo->pseudo_header->nettl.subsys, val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown")); proto_tree_add_int(nettl_tree, hf_nettl_devid, tvb, 0, 0, pinfo->pseudo_header->nettl.devid); proto_tree_add_uint_format(nettl_tree, hf_nettl_kind, tvb, 0, 0, pinfo->pseudo_header->nettl.kind, "Trace Kind: 0x%08x (%s)", pinfo->pseudo_header->nettl.kind, val_to_str_const(pinfo->pseudo_header->nettl.kind & ~NETTL_HDR_SUBSYSTEM_BITS_MASK, trace_kind, "Unknown")); proto_tree_add_int(nettl_tree, hf_nettl_pid, tvb, 0, 0, pinfo->pseudo_header->nettl.pid); proto_tree_add_uint(nettl_tree, hf_nettl_uid, tvb, 0, 0, pinfo->pseudo_header->nettl.uid); } switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_NETTL_ETHERNET: call_dissector(eth_withoutfcs_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_TOKEN_RING: call_dissector(tr_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_FDDI: if (!dissector_try_uint(wtap_dissector_table, WTAP_ENCAP_FDDI_BITSWAPPED, tvb, pinfo, tree)) call_dissector(data_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_RAW_IP: if ( (pinfo->pseudo_header->nettl.kind & NETTL_HDR_PDU_MASK) == 0 ) /* not actually a data packet (PDU) trace record */ call_dissector(data_handle, tvb, pinfo, tree); else if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_NS_LS_SCTP ) call_dissector(sctp_handle, tvb, pinfo, tree); else if (!dissector_try_uint(wtap_dissector_table, WTAP_ENCAP_RAW_IP, tvb, pinfo, tree)) call_dissector(data_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_RAW_ICMP: if (!dissector_try_uint(ip_proto_dissector_table, IP_PROTO_ICMP, tvb, pinfo, tree)) call_dissector(data_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_RAW_ICMPV6: if (!dissector_try_uint(ip_proto_dissector_table, IP_PROTO_ICMPV6, tvb, pinfo, tree)) call_dissector(data_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_X25: if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUIN) pinfo->p2p_dir = P2P_DIR_RECV; else if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUOUT) pinfo->p2p_dir = P2P_DIR_SENT; if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_SX25L2) call_dissector(lapb_handle, tvb, pinfo, tree); else call_dissector(x25_handle, tvb, pinfo, tree); break; case WTAP_ENCAP_NETTL_RAW_TELNET: if (!dissector_try_uint(tcp_subdissector_table, TCP_PORT_TELNET, tvb, pinfo, tree)) call_dissector(data_handle, tvb, pinfo, tree); break; default: col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported nettl subsytem: %d (%s)", pinfo->pseudo_header->nettl.subsys, val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown")); call_dissector(data_handle, tvb, pinfo, tree); } }
static void dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *radiotap_tree = NULL; proto_tree *pt, *present_tree = NULL; proto_tree *ft; proto_item *ti = NULL, *hidden_item; int align_offset, offset; tvbuff_t *next_tvb; guint32 version; guint length, length_remaining; guint32 rate, freq, flags; gint8 dbm; guint8 db, rflags; guint32 present, next_present; int bit; /* backward compat with bit 14 == fcs in header */ proto_item *hdr_fcs_ti = NULL; int hdr_fcs_offset = 0; guint32 sent_fcs = 0; guint32 calc_fcs; struct _radiotap_info *radiotap_info; static struct _radiotap_info rtp_info_arr[1]; radiotap_info = &rtp_info_arr[0]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); radiotap_info->radiotap_length = length; col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u", version, length); /* Dissect the packet */ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_radiotap, tvb, 0, length, "Radiotap Header v%u, Length %u", version, length); radiotap_tree = proto_item_add_subtree(ti, ett_radiotap); proto_tree_add_uint(radiotap_tree, hf_radiotap_version, tvb, offset, 1, version); proto_tree_add_item(radiotap_tree, hf_radiotap_pad, tvb, offset + 1, 1, FALSE); ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_length, tvb, offset + 2, 2, length); } length_remaining = length; /* * FIXME: This only works if there is exactly 1 it_present * field in the header */ if (length_remaining < RADIOTAP_MIN_HEADER_LEN) { /* * Radiotap header is shorter than the fixed-length portion * plus one "present" bitset. */ if (tree) proto_item_append_text(ti, " (bogus - minimum length is 8)"); return; } /* Subtree for the "present flags" bitfield. */ if (tree) { pt = proto_tree_add_uint(radiotap_tree, hf_radiotap_present, tvb, offset + 4, 4, present); present_tree = proto_item_add_subtree(pt, ett_radiotap_present); proto_tree_add_item(present_tree, hf_radiotap_present_tsft, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_flags, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_rate, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_channel, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_fhss, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_antenna, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise, tvb, offset + 4, 4, TRUE); if (radiotap_bit14_fcs) { proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs, tvb, offset + 4, 4, TRUE); } else { proto_tree_add_item(present_tree, hf_radiotap_present_rxflags, tvb, offset + 4, 4, TRUE); } proto_tree_add_item(present_tree, hf_radiotap_present_xchannel, tvb, offset + 4, 4, TRUE); proto_tree_add_item(present_tree, hf_radiotap_present_ext, tvb, offset + 4, 4, TRUE); } offset += RADIOTAP_MIN_HEADER_LEN; length_remaining -= RADIOTAP_MIN_HEADER_LEN; rflags = 0; for (; present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = BITNO_32(present ^ next_present); switch (bit) { case IEEE80211_RADIOTAP_TSFT: align_offset = ALIGN_OFFSET(offset, 8); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 8) break; radiotap_info->tsft=tvb_get_letoh64(tvb, offset); if (tree) { proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime, tvb, offset, 8,radiotap_info->tsft ); } offset+=8; length_remaining-=8; break; case IEEE80211_RADIOTAP_FLAGS: { proto_tree *flags_tree; if (length_remaining < 1) break; rflags = tvb_get_guint8(tvb, offset); if (tree) { ft = proto_tree_add_item(radiotap_tree, hf_radiotap_flags, tvb, offset, 1, FALSE); flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags); proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_wep, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_frag, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi, tvb, offset, 1, FALSE); } offset++; length_remaining--; break; } case IEEE80211_RADIOTAP_RATE: if (length_remaining < 1) break; rate = tvb_get_guint8(tvb, offset); if (rate & 0x80) { /* XXX adjust by CW and short GI like other sniffers? */ rate = ieee80211_htrates[rate & 0xf]; } col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d", rate / 2, rate & 1 ? 5 : 0); if (tree) { proto_tree_add_float_format(radiotap_tree, hf_radiotap_datarate, tvb, offset, 1, (float)rate / 2, "Data Rate: %.1f Mb/s", (float)rate / 2); } offset++; length_remaining--; radiotap_info->rate = rate; break; case IEEE80211_RADIOTAP_CHANNEL: { proto_item *it; proto_tree *flags_tree; gchar *chan_str; align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; if (tree) { freq = tvb_get_letohs(tvb, offset); flags = tvb_get_letohs(tvb, offset+2); chan_str = ieee80211_mhz_to_str(freq); col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str); proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency, tvb, offset, 2, freq, "Channel frequency: %s", chan_str); g_free(chan_str); /* We're already 2-byte aligned. */ it = proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags, tvb, offset+2, 2, flags); flags_tree = proto_item_add_subtree(it, ett_radiotap_channel_flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_turbo, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_cck, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_ofdm, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_2ghz, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_5ghz, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_passive, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_dynamic, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gfsk, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gsm, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_sturbo, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_half, tvb, offset+3, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_quarter, tvb, offset+3, 1, flags); radiotap_info->freq=freq; radiotap_info->flags=flags; } offset+=4 /* Channel + flags */; length_remaining-=4; break; } case IEEE80211_RADIOTAP_FHSS: align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_hopset, tvb, offset, 1, FALSE); proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_pattern, tvb, offset, 1, FALSE); offset+=2; length_remaining-=2; break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: if (length_remaining < 1) break; dbm = (gint8) tvb_get_guint8(tvb, offset); col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm); if (tree) { proto_tree_add_int_format(radiotap_tree, hf_radiotap_dbm_antsignal, tvb, offset, 1, dbm, "SSI Signal: %d dBm", dbm); } offset++; length_remaining--; radiotap_info->dbm_antsignal=dbm; break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: if (length_remaining < 1) break; dbm = (gint8) tvb_get_guint8(tvb, offset); if (tree) { proto_tree_add_int_format(radiotap_tree, hf_radiotap_dbm_antnoise, tvb, offset, 1, dbm, "SSI Noise: %d dBm", dbm); } offset++; length_remaining--; radiotap_info->dbm_antnoise=dbm; break; case IEEE80211_RADIOTAP_LOCK_QUALITY: align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; if (tree) { proto_tree_add_uint(radiotap_tree, hf_radiotap_quality, tvb, offset, 2, tvb_get_letohs(tvb, offset)); } offset+=2; length_remaining-=2; break; case IEEE80211_RADIOTAP_TX_ATTENUATION: align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation, tvb, offset, 2, FALSE); offset+=2; length_remaining-=2; break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation, tvb, offset, 2, FALSE); offset+=2; length_remaining-=2; break; case IEEE80211_RADIOTAP_DBM_TX_POWER: if (length_remaining < 1) break; if (tree) { proto_tree_add_int(radiotap_tree, hf_radiotap_txpower, tvb, offset, 1, tvb_get_guint8(tvb, offset)); } offset++; length_remaining--; break; case IEEE80211_RADIOTAP_ANTENNA: if (length_remaining < 1) break; if (tree) { proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna, tvb, offset, 1, tvb_get_guint8(tvb, offset)); } offset++; length_remaining--; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: if (length_remaining < 1) break; db = tvb_get_guint8(tvb, offset); col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db); if (tree) { proto_tree_add_uint_format(radiotap_tree, hf_radiotap_db_antsignal, tvb, offset, 1, db, "SSI Signal: %u dB", db); } offset++; length_remaining--; break; case IEEE80211_RADIOTAP_DB_ANTNOISE: if (length_remaining < 1) break; db = tvb_get_guint8(tvb, offset); if (tree) { proto_tree_add_uint_format(radiotap_tree, hf_radiotap_db_antnoise, tvb, offset, 1, db, "SSI Noise: %u dB", db); } offset++; length_remaining--; break; case IEEE80211_RADIOTAP_RX_FLAGS: { proto_tree *flags_tree; if (radiotap_bit14_fcs) { align_offset = ALIGN_OFFSET(offset, 4); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 4) break; if (tree) { sent_fcs = tvb_get_ntohl(tvb, offset); hdr_fcs_ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs, tvb, offset, 4, sent_fcs); hdr_fcs_offset = offset; } offset+=4; length_remaining-=4; } else { proto_item *it; align_offset = ALIGN_OFFSET(offset, 2); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 2) break; if (tree) { flags = tvb_get_letohs(tvb, offset); it = proto_tree_add_uint(radiotap_tree, hf_radiotap_rxflags, tvb, offset, 2, flags); flags_tree = proto_item_add_subtree(it, ett_radiotap_rxflags); proto_tree_add_boolean(flags_tree, hf_radiotap_rxflags_badplcp, tvb, offset, 1, flags); } offset+=2; length_remaining-=2; } break; } case IEEE80211_RADIOTAP_XCHANNEL: { proto_item *it; proto_tree *flags_tree; align_offset = ALIGN_OFFSET(offset, 4); offset += align_offset; length_remaining -= align_offset; if (length_remaining < 8) break; if (tree) { int channel; guint8 maxpower; flags = tvb_get_letohl(tvb, offset); freq = tvb_get_letohs(tvb, offset+4); channel = tvb_get_guint8(tvb, offset+6); maxpower = tvb_get_guint8(tvb, offset+7); proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel, tvb, offset+6, 1, (guint32) channel); proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_frequency, tvb, offset+4, 2, freq); it = proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_flags, tvb, offset+0, 4, flags); flags_tree = proto_item_add_subtree(it, ett_radiotap_xchannel_flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_turbo, tvb, offset+0, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_cck, tvb, offset+0, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ofdm, tvb, offset+0, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_2ghz, tvb, offset+0, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_5ghz, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_passive, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_dynamic, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gfsk, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gsm, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_sturbo, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_half, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_quarter, tvb, offset+1, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht20, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40u, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40d, tvb, offset+2, 1, flags); #if 0 proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_maxpower, tvb, offset+7, 1, maxpower); #endif } offset+=8 /* flags + freq + ieee + maxregpower */; length_remaining-=8; break; } default: /* * This indicates a field whose size we do not * know, so we cannot proceed. */ next_present = 0; continue; } } /* This handles the case of an FCS exiting at the end of the frame. */ if (rflags & IEEE80211_RADIOTAP_F_FCS) pinfo->pseudo_header->ieee_802_11.fcs_len = 4; else pinfo->pseudo_header->ieee_802_11.fcs_len = 0; /* Grab the rest of the frame. */ next_tvb = tvb_new_subset_remaining(tvb, length); /* If we had an in-header FCS, check it. * This can only happen if the backward-compat configuration option * is chosen by the user. */ if (hdr_fcs_ti) { /* It would be very strange for the header to have an FCS for the * frame *and* the frame to have the FCS at the end, but it's possible, so * take that into account by using the FCS length recorded in pinfo. */ /* Watch out for [erroneously] short frames */ if (tvb_length(next_tvb) > (unsigned int) pinfo->pseudo_header->ieee_802_11.fcs_len) { calc_fcs = crc32_802_tvb(next_tvb, tvb_length(next_tvb) - pinfo->pseudo_header->ieee_802_11.fcs_len); /* By virtue of hdr_fcs_ti being set, we know that 'tree' is set, * so there's no need to check it here. */ if (calc_fcs == sent_fcs) { proto_item_append_text(hdr_fcs_ti, " [correct]"); } else { proto_item_append_text(hdr_fcs_ti, " [incorrect, should be 0x%08x]", calc_fcs); hidden_item = proto_tree_add_boolean(radiotap_tree, hf_radiotap_fcs_bad, tvb, hdr_fcs_offset, 4, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } } else { proto_item_append_text(hdr_fcs_ti, " [cannot verify - not enough data]"); } } /* dissect the 802.11 header next */ call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ? ieee80211_datapad_handle : ieee80211_handle, next_tvb, pinfo, tree); tap_queue_packet(radiotap_tap, pinfo, radiotap_info); }
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; switch (pinfo->phdr->rec_type) { case REC_TYPE_PACKET: 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; } } break; case REC_TYPE_FT_SPECIFIC_EVENT: pinfo->current_proto = "Event"; break; case REC_TYPE_FT_SPECIFIC_REPORT: pinfo->current_proto = "Report"; break; default: g_assert_not_reached(); break; } if(pinfo->pkt_comment){ item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, 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, 0, pinfo->pkt_comment, "%s", pinfo->pkt_comment); expert_add_info_format(pinfo, comment_item, &ei_comments_text, "%s", pinfo->pkt_comment); } /* if FRAME is not referenced from any filters we don't 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(pinfo, NULL, &ei_arrive_time_out_of_range); } } 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, tvb_captured_length(tvb), "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->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) { proto_item_append_text(ti, " on interface %u", pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) { if (pinfo->phdr->pack_flags & 0x00000001) { proto_item_append_text(ti, " (inbound)"); pinfo->p2p_dir = P2P_DIR_RECV; } if (pinfo->phdr->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->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) { const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id); if (interface_name) proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name); else proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_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->phdr->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->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags); } if (pinfo->phdr->rec_type == REC_TYPE_PACKET) 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) { expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range, "Arrival Time: Fractional second %09ld is invalid," " the valid range is 0-1000000000", (long) pinfo->fd->abs_ts.nsecs); } 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->epan, pinfo->fd, pinfo->fd->num - 1, &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->epan, pinfo->fd, pinfo->fd->prev_dis_num, &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->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(wmem_packet_scope(), 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); } /* 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_value(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "%" 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 = (const color_filter_t *)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, 0, "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 switch (pinfo->phdr->rec_type) { case REC_TYPE_PACKET: 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); } } break; case REC_TYPE_FT_SPECIFIC_EVENT: case REC_TYPE_FT_SPECIFIC_REPORT: if (!dissector_try_uint(wtap_fts_rec_dissector_table, pinfo->file_type_subtype, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", pinfo->file_type_subtype); call_dissector(data_handle,tvb, pinfo, parent_tree); } break; } #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_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if(proto_field_is_referenced(tree, hf_frame_protocols)) { wmem_strbuf_t *val = wmem_strbuf_sized_new(wmem_packet_scope(), 128, 0); wmem_list_frame_t *frame; /* skip the first entry, it's always the "frame" protocol */ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers)); if (frame) { wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } while (frame) { wmem_strbuf_append_c(val, ':'); wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } proto_item_append_string(ti, wmem_strbuf_get_str(val)); } /* 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_BOUNDS_AND_DISSECTOR_ERRORS { 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 int dissect_banana_element(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { proto_item *ti; proto_tree *list_tree; guint8 byte = 0; gint64 val = 0; gint val_len = 0; int start_offset = offset; int old_offset; int i; /* Accumulate our value/length 'til we hit a valid type */ while (tvb_length_remaining(tvb, offset) > 0) { byte = tvb_get_guint8(tvb, offset); offset++; if (byte & 0x80) { if (is_element(byte)) { break; } else { expert_add_info_format(pinfo, NULL, &ei_banana_unknown_type, "Unknown type %u", byte); } } else { val_len++; if (val_len > MAX_ELEMENT_VAL_LEN) { expert_add_info(pinfo, NULL, &ei_banana_too_many_value_bytes); } val += byte + (val << 7); } } /* Type */ switch (byte) { case BE_LIST: if (val > MAX_ELEMENT_VAL) { expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "List length %" G_GINT64_MODIFIER "d longer than we can handle", val); } ti = proto_tree_add_uint_format_value(tree, hf_banana_list, tvb, start_offset, offset - start_offset - 1, (guint32) val, "(%d items)", (gint) val); list_tree = proto_item_add_subtree(ti, ett_list); for (i = 0; i < val; i++) { old_offset = offset; offset += dissect_banana_element(tvb, pinfo, list_tree, offset); if (offset <= old_offset) { return offset - start_offset; } } break; case BE_INT: if (val > MAX_ELEMENT_VAL) { expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value %" G_GINT64_MODIFIER "d too large", val); } proto_tree_add_uint(tree, hf_banana_int, tvb, start_offset, offset - start_offset, (guint32) val); break; case BE_STRING: if (val > MAX_ELEMENT_VAL) { expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "String length %" G_GINT64_MODIFIER "d longer than we can handle", val); } proto_tree_add_item(tree, hf_banana_string, tvb, offset, (guint32) val, ENC_ASCII|ENC_NA); offset += (gint) val; break; case BE_NEG_INT: if (val > MAX_ELEMENT_VAL) { expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value -%" G_GINT64_MODIFIER "d too large", val); } proto_tree_add_int(tree, hf_banana_neg_int, tvb, start_offset, offset - start_offset, (gint32) val * -1); break; case BE_FLOAT: proto_tree_add_item(tree, hf_banana_float, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case BE_LG_INT: proto_tree_add_item(tree, hf_banana_lg_int, tvb, start_offset, offset - start_offset, ENC_NA); break; case BE_LG_NEG_INT: proto_tree_add_item(tree, hf_banana_lg_neg_int, tvb, start_offset, offset - start_offset, ENC_NA); break; case BE_PB: if (val_len > 1) { expert_add_info(pinfo, NULL, &ei_banana_pb_error); } /* * The spec says the pb dictionary value comes after the tag. * In real-world captures it comes before. */ proto_tree_add_item(tree, hf_banana_pb, tvb, offset - 2, 1, ENC_BIG_ENDIAN); break; default: return 0; break; } return offset - start_offset; }
static void dissect_dsi_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *dsi_tree; proto_item *ti; guint8 dsi_flags,dsi_command; guint16 dsi_requestid; gint32 dsi_code; guint32 dsi_length; guint32 dsi_reserved; struct aspinfo aspinfo; col_set_str(pinfo->cinfo, COL_PROTOCOL, "DSI"); col_clear(pinfo->cinfo, COL_INFO); dsi_flags = tvb_get_guint8(tvb, 0); dsi_command = tvb_get_guint8(tvb, 1); dsi_requestid = tvb_get_ntohs(tvb, 2); dsi_code = tvb_get_ntohl(tvb, 4); dsi_length = tvb_get_ntohl(tvb, 8); dsi_reserved = tvb_get_ntohl(tvb, 12); col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s (%u)", val_to_str(dsi_flags, flag_vals, "Unknown flag (0x%02x)"), val_to_str_ext(dsi_command, &func_vals_ext, "Unknown function (0x%02x)"), dsi_requestid); if (tree) { ti = proto_tree_add_item(tree, proto_dsi, tvb, 0, -1, ENC_NA); dsi_tree = proto_item_add_subtree(ti, ett_dsi); proto_tree_add_uint(dsi_tree, hf_dsi_flags, tvb, 0, 1, dsi_flags); proto_tree_add_uint(dsi_tree, hf_dsi_command, tvb, 1, 1, dsi_command); proto_tree_add_uint(dsi_tree, hf_dsi_requestid, tvb, 2, 2, dsi_requestid); switch (dsi_flags) { case DSIFL_REQUEST: proto_tree_add_int(dsi_tree, hf_dsi_offset, tvb, 4, 4, dsi_code); break; case DSIFL_REPLY: proto_tree_add_int(dsi_tree, hf_dsi_error, tvb, 4, 4, dsi_code); break; } proto_tree_add_uint_format_value(dsi_tree, hf_dsi_length, tvb, 8, 4, dsi_length, "%u bytes", dsi_length); proto_tree_add_uint(dsi_tree, hf_dsi_reserved, tvb, 12, 4, dsi_reserved); } else dsi_tree = tree; switch (dsi_command) { case DSIFUNC_OPEN: if (tree) { dissect_dsi_open_session(tvb, dsi_tree, DSI_BLOCKSIZ, dsi_length); } break; case DSIFUNC_ATTN: if (tree) { dissect_dsi_attention(tvb, dsi_tree, DSI_BLOCKSIZ); } break; case DSIFUNC_STAT: if (tree && (dsi_flags == DSIFL_REPLY)) { dissect_dsi_reply_get_status(tvb, dsi_tree, DSI_BLOCKSIZ); } break; case DSIFUNC_CMD: case DSIFUNC_WRITE: { tvbuff_t *new_tvb; void* pd_save; int len = tvb_reported_length_remaining(tvb,DSI_BLOCKSIZ); aspinfo.reply = (dsi_flags == DSIFL_REPLY); aspinfo.command = dsi_command; aspinfo.seq = dsi_requestid; aspinfo.code = dsi_code; pd_save = pinfo->private_data; pinfo->private_data = &aspinfo; proto_item_set_len(dsi_tree, DSI_BLOCKSIZ); new_tvb = tvb_new_subset(tvb, DSI_BLOCKSIZ,-1,len); call_dissector(afp_handle, new_tvb, pinfo, tree); pinfo->private_data = pd_save; } break; default: if (tree) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, DSI_BLOCKSIZ), pinfo, dsi_tree); } break; } }
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; } }
/* Code to actually dissect the packets */ static void dissect_rngrsp (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { proto_item *it; proto_tree *rngrsp_tree; guint8 tlvtype, tlvlen; int pos; gint length; guint8 upchid; guint16 sid; gint8 pwr; gint32 tim; sid = tvb_get_ntohs (tvb, 0); upchid = tvb_get_guint8 (tvb, 2); if (upchid > 0) col_add_fstr (pinfo->cinfo, COL_INFO, "Ranging Response: SID = %u, Upstream Channel = %u (U%u)", sid, upchid, upchid - 1); else col_add_fstr (pinfo->cinfo, COL_INFO, "Ranging Response: SID = %u, Telephony Return", sid); if (tree) { it = proto_tree_add_protocol_format (tree, proto_docsis_rngrsp, tvb, 0, -1, "Ranging Response"); rngrsp_tree = proto_item_add_subtree (it, ett_docsis_rngrsp); proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_sid, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_upstream_chid, tvb, 2, 1, ENC_BIG_ENDIAN); length = tvb_reported_length_remaining (tvb, 0); pos = 3; while (pos < length) { tlvtype = tvb_get_guint8 (tvb, pos++); tlvlen = tvb_get_guint8 (tvb, pos++); switch (tlvtype) { case RNGRSP_TIMING: if (tlvlen == 4) { tim = tvb_get_ntohl (tvb, pos); proto_tree_add_int (rngrsp_tree, hf_docsis_rngrsp_timing_adj, tvb, pos, tlvlen, tim); } else { THROW (ReportedBoundsError); } break; case RNGRSP_PWR_LEVEL_ADJ: if (tlvlen == 1) { pwr = tvb_get_guint8 (tvb, pos); proto_tree_add_int (rngrsp_tree, hf_docsis_rngrsp_power_adj, tvb, pos, tlvlen, pwr); } else { THROW (ReportedBoundsError); } break; case RNGRSP_OFFSET_FREQ_ADJ: if (tlvlen == 2) { proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_freq_adj, tvb, pos, tlvlen, ENC_BIG_ENDIAN); } else { THROW (ReportedBoundsError); } break; case RNGRSP_TRANSMIT_EQ_ADJ: proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_xmit_eq_adj, tvb, pos, tlvlen, ENC_NA); break; case RNGRSP_RANGING_STATUS: if (tlvlen == 1) proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_ranging_status, tvb, pos, tlvlen, ENC_BIG_ENDIAN); else { THROW (ReportedBoundsError); } break; case RNGRSP_DOWN_FREQ_OVER: if (tlvlen == 4) proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_down_freq_over, tvb, pos, tlvlen, ENC_BIG_ENDIAN); else { THROW (ReportedBoundsError); } break; case RNGRSP_UP_CHID_OVER: if (tlvlen == 1) proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_upstream_ch_over, tvb, pos, tlvlen, ENC_BIG_ENDIAN); else { THROW (ReportedBoundsError); } break; } /* switch(tlvtype) */ pos = pos + tlvlen; } /* while (pos < length) */ } /* if (tree) */ }
static void dissect_pw_cesopsn( tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = PWC_PACKET_PROPERTIES_T_INITIALIZER; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC5086: * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN * packet (defined as the size of the CESoPSN header + the payload size) * if it is less than 64 bytes, and MUST be set to zero otherwise. * Note: If fixed RTP header is used in the encapsulation, it is * considered part of the CESoPSN header.] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC5086's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } { guint8 cw_lm; cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/; if (NULL == try_val_to_str(cw_lm, vals_cw_lm)) { properties |= PWC_CW_SUSPECT_LM; } { guint8 l_bit, m_bits; l_bit = (cw_lm & 0x08) >> 3; m_bits = (cw_lm & 0x03) >> 0; if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/ ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ ) { if ((payload_size == 0) || ((payload_size % 8) != 0)) { properties |= PWC_PAY_SIZE_BAD; } } else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/ { /*allow any size of payload*/ } else /*reserved combinations*/ { /*allow any size of payload*/ } } } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } else if (properties & PWC_ANYOF_CW_SUSPECT) { col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, "); } col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset(tvb_original, 0, PWC_SIZEOF_CW, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } item3 = proto_tree_add_item(tree3, hf_cw_lm, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_SUSPECT_LM) { expert_add_info(pinfo, item3, &ei_cw_lm); } proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be 0 if CESoPSN packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (payload_size == 0) { if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error, "CESoPSN payload: none found. Size of payload must be <> 0"); } else { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded, "CESoPSN payload: omitted to conserve bandwidth"); } } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW, payload_size, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error, "CESoPSN packet payload size must be multiple of 8"); } tree2 = proto_item_add_subtree(item2, ett); call_dissector(data_handle, tvb, pinfo, tree2); item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
/* Code to actually dissect the packets */ static void dissect_lsc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *lsc_tree; guint8 op_code; guint32 stream; guint expected_len; /* Protocol is LSC, packet summary is not yet known */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LSC"); col_clear(pinfo->cinfo, COL_INFO); /* Too little data? */ if (tvb->length < LSC_MIN_LEN) { col_set_str(pinfo->cinfo, COL_INFO, "[Too short]"); return; } /* Get the op code */ op_code = tvb_get_guint8(tvb, 2); /* And the stream handle */ stream = tvb_get_ntohl(tvb, 4); /* Check the data length against what we actually received */ switch (op_code) { case LSC_PAUSE: expected_len = LSC_PAUSE_LEN; break; case LSC_RESUME: expected_len = LSC_RESUME_LEN; break; case LSC_STATUS: expected_len = LSC_STATUS_LEN; break; case LSC_RESET: expected_len = LSC_RESET_LEN; break; case LSC_JUMP: expected_len = LSC_JUMP_LEN; break; case LSC_PLAY: expected_len = LSC_PLAY_LEN; break; case LSC_DONE: case LSC_PAUSE_REPLY: case LSC_RESUME_REPLY: case LSC_STATUS_REPLY: case LSC_RESET_REPLY: case LSC_JUMP_REPLY: case LSC_PLAY_REPLY: expected_len = LSC_REPLY_LEN; break; default: /* Unrecognized op code */ expected_len = LSC_MIN_LEN; break; } /* Display the op code in the summary */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s, session %.8u", val_to_str(op_code, op_code_vals, "Unknown op code (0x%x)"), stream); if (tvb->length < expected_len) col_append_str(pinfo->cinfo, COL_INFO, " [Too short]"); else if (tvb->length > expected_len) col_append_str(pinfo->cinfo, COL_INFO, " [Too long]"); } if (tree) { /* Create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_lsc, tvb, 0, -1, FALSE); lsc_tree = proto_item_add_subtree(ti, ett_lsc); /* Add already fetched items to the tree */ proto_tree_add_uint(lsc_tree, hf_lsc_op_code, tvb, 2, 1, op_code); proto_tree_add_uint_format_value(lsc_tree, hf_lsc_stream_handle, tvb, 4, 4, stream, "%.8u", stream); /* Add rest of LSC header */ proto_tree_add_uint(lsc_tree, hf_lsc_version, tvb, 0, 1, tvb_get_guint8(tvb, 0)); proto_tree_add_uint(lsc_tree, hf_lsc_trans_id, tvb, 1, 1, tvb_get_guint8(tvb, 1)); /* Only replies contain a status code */ if (isReply(op_code)) proto_tree_add_uint(lsc_tree, hf_lsc_status_code, tvb, 3, 1, tvb_get_guint8(tvb, 3)); /* Add op code specific parts */ switch (op_code) { case LSC_PAUSE: proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); break; case LSC_RESUME: proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2, tvb_get_ntohs(tvb, 12)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2, tvb_get_ntohs(tvb, 14)); break; case LSC_JUMP: case LSC_PLAY: proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 12, 4, tvb_get_ntohl(tvb, 12)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 16, 2, tvb_get_ntohs(tvb, 16)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 18, 2, tvb_get_ntohs(tvb, 18)); break; case LSC_DONE: case LSC_PAUSE_REPLY: case LSC_RESUME_REPLY: case LSC_STATUS_REPLY: case LSC_RESET_REPLY: case LSC_JUMP_REPLY: case LSC_PLAY_REPLY: proto_tree_add_int(lsc_tree, hf_lsc_current_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2, tvb_get_ntohs(tvb, 12)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2, tvb_get_ntohs(tvb, 14)); proto_tree_add_uint(lsc_tree, hf_lsc_mode, tvb, 16, 1, tvb_get_guint8(tvb, 16)); break; default: break; } } }
/* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */ static int dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { proto_item *volatile ti = NULL; guint cap_len = 0, frame_len = 0; proto_tree *volatile fh_tree = NULL; proto_tree *volatile tree; proto_item *item; const gchar *cap_plurality, *frame_plurality; const color_filter_t *color_filter; file_data_t *file_data = (file_data_t*)data; tree=parent_tree; pinfo->current_proto = "File"; /* if FILE is not referenced from any filters we don't need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_file)) { tree=NULL; } else { /* Put in frame header information. */ cap_len = tvb_captured_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_file, tvb, 0, -1, "File record %u: %u byte%s", pinfo->num, frame_len, frame_plurality); proto_item_append_text(ti, ", %u byte%s", cap_len, cap_plurality); fh_tree = proto_item_add_subtree(ti, ett_file); proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->pkt_encap); proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->num); proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb, 0, 0, frame_len, "Record Length: %u byte%s (%u bits)", frame_len, frame_plurality, frame_len * 8); ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->flags.ignored); PROTO_ITEM_SET_GENERATED(ti); if(pinfo->fd->pfd != 0){ proto_item *ppd_item; guint num_entries = g_slist_length(pinfo->fd->pfd); guint i; ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries); PROTO_ITEM_SET_GENERATED(ppd_item); for(i=0; i<num_entries; i++){ gchar* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i); proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str); } } #if 0 if (show_file_off) { proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } #endif } if (pinfo->fd->flags.ignored) { /* Ignored package, stop handling here */ col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>"); proto_tree_add_boolean_format(tree, hf_file_ignored, tvb, 0, -1, TRUE, "This record is marked as ignored"); return tvb_captured_length(tvb); } /* 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 (!dissector_try_uint(file_encap_dissector_table, pinfo->pkt_encap, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d", pinfo->pkt_encap); call_data_dissector(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_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if(proto_field_is_referenced(tree, hf_file_protocols)) { wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), ""); wmem_list_frame_t *frame; /* skip the first entry, it's always the "frame" protocol */ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers)); if (frame) { wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } while (frame) { wmem_strbuf_append_c(val, ':'); wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val)); PROTO_ITEM_SET_GENERATED(ti); } /* 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_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } /* Attempt to (re-)calculate color filters (if any). */ if (pinfo->fd->flags.need_colorize) { color_filter = color_filters_colorize_packet(file_data->color_edt); pinfo->fd->color_filter = color_filter; pinfo->fd->flags.need_colorize = 0; } else { color_filter = pinfo->fd->color_filter; } if (color_filter) { pinfo->fd->color_filter = color_filter; item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } tap_queue_packet(file_tap, pinfo, NULL); if (pinfo->frame_end_routines) { g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL); g_slist_free(pinfo->frame_end_routines); pinfo->frame_end_routines = NULL; } return tvb_captured_length(tvb); }
static gint ett = -1; static int hf_padding_len = -1; static int dissect_pw_padding(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_) { gint size; proto_item* item; proto_tree* tree_p; size = tvb_reported_length_remaining(tvb, 0); item = proto_tree_add_item(tree, proto_pw_padding, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item,size,"byte"); tree_p = proto_item_add_subtree(item, ett); call_data_dissector(tvb, pinfo, tree_p); item = proto_tree_add_int(tree_p, hf_padding_len, tvb, 0, 0, size); PROTO_ITEM_SET_HIDDEN(item); /*allow filtering*/ return tvb_captured_length(tvb); } void proto_register_pw_padding(void) { static hf_register_info hfpadding[] = { {&hf_padding_len ,{"Length" ,"pw.padding.len" ,FT_INT32 ,BASE_DEC ,NULL ,0 ,NULL ,HFILL }} }; static gint *ett_array[] = { &ett };
static gboolean dissect_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_tree *h1_tree = NULL; proto_item *ti; proto_tree *opcode_tree = NULL; proto_tree *org_tree = NULL; proto_tree *response_tree = NULL; proto_tree *empty_tree = NULL; unsigned int position = 3; unsigned int offset=0; if (tvb_length(tvb) < 2) { /* Not enough data captured to hold the "S5" header; don't try to interpret it as H1. */ return FALSE; } if (!(tvb_get_guint8(tvb,offset) == 'S' && tvb_get_guint8(tvb,offset+1) == '5')) { return FALSE; } col_set_str (pinfo->cinfo, COL_PROTOCOL, "H1"); col_set_str(pinfo->cinfo, COL_INFO, "S5: "); if (tree) { ti = proto_tree_add_item (tree, proto_h1, tvb, offset, 16, ENC_NA); h1_tree = proto_item_add_subtree (ti, ett_h1); proto_tree_add_uint (h1_tree, hf_h1_header, tvb, offset, 2, tvb_get_ntohs(tvb,offset)); proto_tree_add_uint (h1_tree, hf_h1_len, tvb, offset + 2, 1, tvb_get_guint8(tvb,offset+2)); } while (position < tvb_get_guint8(tvb,offset+2)) { switch (tvb_get_guint8(tvb,offset + position)) { case OPCODE_BLOCK: if (h1_tree) { ti = proto_tree_add_uint (h1_tree, hf_h1_opfield, tvb, offset + position, tvb_get_guint8(tvb,offset+position+1), tvb_get_guint8(tvb,offset+position)); opcode_tree = proto_item_add_subtree (ti, ett_opcode); proto_tree_add_uint (opcode_tree, hf_h1_oplen, tvb, offset + position + 1, 1, tvb_get_guint8(tvb,offset + position + 1)); proto_tree_add_uint (opcode_tree, hf_h1_opcode, tvb, offset + position + 2, 1, tvb_get_guint8(tvb,offset + position + 2)); } if (check_col (pinfo->cinfo, COL_INFO)) { col_append_str (pinfo->cinfo, COL_INFO, val_to_str (tvb_get_guint8(tvb,offset + position + 2), opcode_vals,"Unknown Opcode (0x%2.2x)")); } break; case REQUEST_BLOCK: if (h1_tree) { ti = proto_tree_add_uint (h1_tree, hf_h1_requestblock, tvb, offset + position, tvb_get_guint8(tvb,offset + position + 1), tvb_get_guint8(tvb,offset + position)); org_tree = proto_item_add_subtree (ti, ett_org); proto_tree_add_uint (org_tree, hf_h1_requestlen, tvb, offset + position + 1, 1, tvb_get_guint8(tvb,offset + position+1)); proto_tree_add_uint (org_tree, hf_h1_org, tvb, offset + position + 2, 1, tvb_get_guint8(tvb,offset + position+2)); proto_tree_add_uint (org_tree, hf_h1_dbnr, tvb, offset + position + 3, 1, tvb_get_guint8(tvb,offset + position+3)); proto_tree_add_uint (org_tree, hf_h1_dwnr, tvb, offset + position + 4, 2, tvb_get_ntohs(tvb,offset+position+4)); proto_tree_add_int (org_tree, hf_h1_dlen, tvb, offset + position + 6, 2, tvb_get_ntohs(tvb,offset+position+6)); } if (check_col (pinfo->cinfo, COL_INFO)) { col_append_fstr (pinfo->cinfo, COL_INFO, " %s %d", val_to_str (tvb_get_guint8(tvb,offset + position + 2), org_vals,"Unknown Type (0x%2.2x)"), tvb_get_guint8(tvb,offset + position + 3)); col_append_fstr (pinfo->cinfo, COL_INFO, " DW %d", tvb_get_ntohs(tvb,offset+position+4)); col_append_fstr (pinfo->cinfo, COL_INFO, " Count %d", tvb_get_ntohs(tvb,offset+position+6)); } break; case RESPONSE_BLOCK: if (h1_tree) { ti = proto_tree_add_uint (h1_tree, hf_h1_response, tvb, offset + position, tvb_get_guint8(tvb,offset + position + 1), tvb_get_guint8(tvb,offset + position)); response_tree = proto_item_add_subtree (ti, ett_response); proto_tree_add_uint (response_tree, hf_h1_response_len, tvb, offset + position + 1, 1, tvb_get_guint8(tvb,offset + position+1)); proto_tree_add_uint (response_tree, hf_h1_response_value, tvb, offset + position + 2, 1, tvb_get_guint8(tvb,offset + position+2)); } if (check_col (pinfo->cinfo, COL_INFO)) { col_append_fstr (pinfo->cinfo, COL_INFO, " %s", val_to_str (tvb_get_guint8(tvb,offset + position + 2), returncode_vals,"Unknown Returncode (0x%2.2x")); } break; case EMPTY_BLOCK: if (h1_tree) { ti = proto_tree_add_uint (h1_tree, hf_h1_empty, tvb, offset + position, tvb_get_guint8(tvb,offset + position + 1), tvb_get_guint8(tvb,offset + position)); empty_tree = proto_item_add_subtree (ti, ett_empty); proto_tree_add_uint (empty_tree, hf_h1_empty_len, tvb, offset + position + 1, 1, tvb_get_guint8(tvb,offset + position+1)); } break; default: /* This is not a valid telegram. So cancel dissection and try the next dissector */ return FALSE; } if (tvb_get_guint8(tvb,offset + position + 1) < 1) THROW(ReportedBoundsError); position += tvb_get_guint8(tvb,offset + position + 1); /* Goto next section */ } /* ..while */ next_tvb = tvb_new_subset(tvb, offset+tvb_get_guint8(tvb,offset+2), -1, -1); call_dissector(data_handle,next_tvb, pinfo, tree); return TRUE; }
static void dissect_asterix_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree* asterix_tree[5]; int tree_depth = 0; proto_item* t_head_item; proto_item* t_item = NULL; static fulliautomatix_data* pDataList = NULL; fulliautomatix_data* pData = NULL; guint32 offset = 0; guint8 category; guint32 payload_len; char tmpstr[256]; char tmp2[64]; int error=0; tmpstr[0] = 0; while(offset < tvb_length(tvb) && strlen(tmpstr)<200) { category = tvb_get_guint8(tvb,offset); offset+=1; payload_len = tvb_get_ntohs(tvb,offset); offset+=2; offset += payload_len-3; sprintf(tmp2,"CAT%03d (%-3d bytes),", category, payload_len); strcat(tmpstr, tmp2); } if (offset != tvb_length(tvb)) { sprintf(tmp2, "Total= %d bytes - Wrong length !!!! ", offset); } else { sprintf(tmp2, "Total = %d bytes", offset); } strcat(tmpstr, tmp2); if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "Asterix"); if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, tmpstr); if(!tree) return; t_head_item = proto_tree_add_protocol_format(tree, proto_asterix, tvb, 0, -1, "All Purpose Structured Eurocontrol Surveillance Information Exhange (Asterix) Protocol"); asterix_tree[tree_depth] = proto_item_add_subtree(t_head_item, ett_asterix[tree_depth]); pDataList = fulliautomatix_parse(tvb_get_ptr(tvb,0,tvb_length(tvb)), tvb_length(tvb)); pData = pDataList; while(pData) { if (pData->tree == 1) { t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->description); if (tree_depth < MAX_TREE_DEPTH-1) { tree_depth++; } asterix_tree[tree_depth] = proto_item_add_subtree(t_item, ett_asterix[tree_depth]); } else if (pData->tree == -1) { if (tree_depth > 0) { tree_depth--; } } else { if (pData->pid < 0 || pData->pid > maxpid) { logTraceFunc("Wrong PID.\n"); } else if (pData->type == FT_STRINGZ) { t_item = proto_tree_add_string(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str); } else if (pData->type == FT_UINT32) { t_item = proto_tree_add_uint(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.ul); } else if (pData->type == FT_INT32) { t_item = proto_tree_add_int(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.sl); } else if (pData->type == FT_BYTES) { t_item = proto_tree_add_bytes(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str); } else if (pData->type == FT_NONE) { t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->val.str); } //TODO add other types } if (pData->value_description) { proto_item_append_text(t_item, pData->value_description); } if (pData->err == 1) { proto_item_set_expert_flags(t_item, PI_GROUP_MASK, PI_WARN); expert_add_info_format(pinfo, t_item, PI_UNDECODED, PI_WARN, "Warning in Asterix message"); if (error==0) error=1; } else if (pData->err == 2) { proto_item_set_expert_flags(t_item, PI_REASSEMBLE, PI_ERROR); expert_add_info_format(pinfo, t_item, PI_MALFORMED, PI_ERROR, "Error in Asterix message"); if (error<2) error=2; } pData = pData->next; } if (error == 1) { proto_item_set_expert_flags(t_head_item, PI_GROUP_MASK, PI_WARN); } else if (error == 2) { proto_item_set_expert_flags(t_head_item, PI_REASSEMBLE, PI_ERROR); } fulliautomatix_data_destroy(pDataList); }