static void dissect_dvb_tdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; proto_item *ti; proto_tree *dvb_tdt_tree; nstime_t utc_time; col_set_str(pinfo->cinfo, COL_INFO, "Time and Date Table (TDT)"); ti = proto_tree_add_item(tree, proto_dvb_tdt, tvb, offset, -1, ENC_NA); dvb_tdt_tree = proto_item_add_subtree(ti, ett_dvb_tdt); offset += packet_mpeg_sect_header(tvb, offset, dvb_tdt_tree, NULL, NULL); if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) { proto_tree_add_text(dvb_tdt_tree, tvb, offset, 5, "Unparseable time"); } else { proto_tree_add_time(dvb_tdt_tree, hf_dvb_tdt_utc_time, tvb, offset, 5, &utc_time); } offset += 5; proto_item_set_len(ti, offset); }
static int dissect_e100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int ret_val = 0; tvbuff_t *next_tvb = NULL; /* heuristic testing: * (1) tvb packet is larger than e100 packet * (2) e100 header is 1 * (3) e100 capture size matches tvb packet size */ if (tvb_length(tvb) >= e100_encap_len && tvb_get_guint8(tvb, e100_header_ver.offset) == 1 && tvb_get_ntohl(tvb, e100_bytes_cap.offset) == tvb_length(tvb)-e100_encap_len) { guint32 bytes_captured=0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "e100"); col_set_str(pinfo->cinfo, COL_INFO, "E100 Encapsulated Packet"); if (tree) { /* pick apart protocol for display */ proto_item *ti = NULL; proto_tree *e100_tree = NULL; ti = proto_tree_add_item(tree, proto_e100, tvb, 0, e100_encap_len, FALSE); e100_tree = proto_item_add_subtree(ti, ett_e100); proto_tree_add_item(e100_tree, hf_e100_header, tvb, e100_header_ver.offset, e100_header_ver.len, FALSE); proto_tree_add_item(e100_tree, hf_e100_port, tvb, e100_port_recv.offset, e100_port_recv.len, FALSE); proto_tree_add_item(e100_tree, hf_e100_seq, tvb, e100_seq.offset, e100_seq.len, FALSE); proto_tree_add_item(e100_tree, hf_e100_ip, tvb, e100_ip.offset, e100_ip.len, FALSE); proto_tree_add_item(e100_tree, hf_e100_mon_pkt_id, tvb, e100_mon_pkt_id.offset, e100_mon_pkt_id.len, FALSE); { nstime_t ts; ts.secs = tvb_get_ntohl(tvb, e100_ts.offset); ts.nsecs = tvb_get_ntohl(tvb, e100_ts.offset+4)*1000; proto_tree_add_time(e100_tree, hf_e100_pkt_ts, tvb, e100_ts.offset, e100_ts.len, &ts); } proto_tree_add_item(e100_tree, hf_e100_bytes_cap, tvb, e100_bytes_cap.offset, e100_bytes_cap.len, FALSE); proto_tree_add_item(e100_tree, hf_e100_bytes_orig, tvb, e100_bytes_orig.offset, e100_bytes_orig.len, FALSE); } /* if(tree) */ bytes_captured = tvb_get_ntohl(tvb, e100_bytes_cap.offset); next_tvb = tvb_new_subset(tvb, e100_encap_len, -1, bytes_captured); call_dissector(eth_handle, next_tvb, pinfo, tree); ret_val = tvb_length(tvb); } /* heuristic testing */ return ret_val; }
static int dissect_rx_response_encrypted(tvbuff_t *tvb, proto_tree *parent_tree, int offset) { proto_tree *tree; proto_item *item; int old_offset=offset; int i; guint32 callnumber; item = proto_tree_add_item(parent_tree, hf_rx_encrypted, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_rx_encrypted); /* epoch : 4 bytes */ { nstime_t ts; ts.secs = tvb_get_ntohl(tvb, offset); ts.nsecs = 0; proto_tree_add_time(tree, hf_rx_epoch, tvb, offset, 4, &ts); offset += 4; } /* cid : 4 bytes */ proto_tree_add_item(tree, hf_rx_cid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /*FIXME don't know how to handle this checksum, skipping it */ offset += 4; /* sequrityindex : 1 byte */ proto_tree_add_item(tree, hf_rx_securityindex, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 4; for (i=0; i<RX_MAXCALLS; i++) { /* callnumber : 4 bytes */ callnumber = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(tree, hf_rx_callnumber, tvb, offset, 4, callnumber); offset += 4; } /* inc nonce : 4 bytes */ proto_tree_add_item(tree, hf_rx_inc_nonce, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* level : 4 bytes */ proto_tree_add_item(tree, hf_rx_level, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_item_set_len(item, offset-old_offset); return offset; }
static void decode_time_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, int* hfValue, int offset, int length) { nstime_t ns; if (length < 8) { expert_add_info(pinfo, item, &ei_opsi_short_attribute); return; } ns.secs = tvb_get_ntohl(tvb, offset+4); ns.nsecs = 0; proto_tree_add_time(tree, *hfValue, tvb, offset+4, 4, &ns); }
static void nlm_print_msgres_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb) { nlm_msg_res_matched_data *md; md=(nlm_msg_res_matched_data *)g_hash_table_lookup(nlm_msg_res_matched, GINT_TO_POINTER(pinfo->fd->num)); if(md){ nstime_t ns; proto_tree_add_uint(tree, hf_nlm_request_in, tvb, 0, 0, md->req_frame); nstime_delta(&ns, &pinfo->fd->abs_ts, &md->ns); proto_tree_add_time(tree, hf_nlm_time, tvb, 0, 0, &ns); } }
static void dissect_ayiya(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ayiya_tree; int offset = 0; int idlen, siglen, ayiya_len; guint8 next_header, opcode; tvbuff_t *payload; idlen = 1 << tvb_get_bits8(tvb, 0, 4); siglen = tvb_get_bits8(tvb, 8, 4) * 4; opcode = tvb_get_bits8(tvb, 20, 4); next_header = tvb_get_guint8(tvb, 3); ayiya_len = 8+idlen+siglen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AYIYA"); if (tree) { proto_item *ti; nstime_t tv; ti = proto_tree_add_protocol_format( tree, proto_ayiya, tvb, offset, ayiya_len, "AYIYA" ); ayiya_tree = proto_item_add_subtree(ti, ett_ayiya); proto_tree_add_bits_item(ayiya_tree, hf_id_len, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_id_type, tvb, 4, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_sig_len, tvb, 8, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_hash_method, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_auth_method, tvb, 16, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_opcode, tvb, 20, 4, ENC_BIG_ENDIAN); proto_tree_add_uint_format(ayiya_tree, hf_next_header, tvb, 3, 1, next_header, "Next header: %s (0x%02x)", ipprotostr(next_header), next_header); tv.secs = tvb_get_ntohl(tvb, 4); tv.nsecs = 0; proto_tree_add_time(ayiya_tree, hf_epoch, tvb, 4, 4, &tv); proto_tree_add_item(ayiya_tree, hf_identity, tvb, 8, idlen, ENC_NA); proto_tree_add_item(ayiya_tree, hf_signature, tvb, 8+idlen, siglen, ENC_NA); } offset = ayiya_len; switch (opcode) { case OPCODE_FORWARD: payload = tvb_new_subset_remaining(tvb, offset); dissector_try_uint(ip_dissector_table, next_header, payload, pinfo, tree); break; } }
static int dissect_kt_replication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { gint new_offset; guint32 next32, size; guint64 ts; nstime_t ns_ts; proto_item *pi; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; if (tvb_reported_length_remaining(tvb, new_offset) > 0) { next32 = tvb_get_ntohl(tvb, new_offset); if (next32 <= 1) { /* This means request. the 32 bits are flags */ proto_tree_add_item(tree, hf_kt_flags, tvb, new_offset, 4, ENC_BIG_ENDIAN); new_offset += 4; proto_tree_add_item(tree, hf_kt_ts, tvb, new_offset, 8, ENC_BIG_ENDIAN); new_offset += 8; proto_tree_add_item(tree, hf_kt_sid, tvb, new_offset, 2, ENC_BIG_ENDIAN); new_offset += 2; } else { /* This is a response. The 32 bits are the first half of the ts */ ts = tvb_get_ntoh64(tvb, new_offset); ns_ts.secs = (time_t)(ts/1000000000); ns_ts.nsecs = (int)(ts%1000000000); proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts); new_offset += 8; size = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_size, tvb, new_offset, 4, size); new_offset += 4; proto_tree_add_item(tree, hf_kt_log, tvb, new_offset, size, ENC_NA); new_offset += size; } } else { /* This is an empty ack to the message with magic 0xB0. */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); } return new_offset; }
static void add_integer_value(const gchar *tag_desc, proto_tree *tree, tvbuff_t *tvb, int offset, int name_length, int value_length, guint8 tag) { char *name_val = NULL; offset = add_value_head(tag_desc, tree, tvb, offset, name_length, value_length, &name_val); switch (tag) { case TAG_BOOLEAN: if (value_length == 1) { proto_tree_add_item(tree, hf_ipp_bool_value, tvb, offset, value_length, ENC_NA); } break; case TAG_INTEGER: case TAG_ENUM: /* Some fields in IPP are really unix timestamps but IPP * transports these as 4 byte integers. * A simple heuristic to make the display of these fields * more human readable is to assume that if the field name * ends in '-time' then assume they are timestamps instead * of integers. */ if (value_length == 4) { if ((name_length > 5) && name_val && !strcmp(name_val+name_length-5, "-time")) { nstime_t ns; ns.secs=tvb_get_ntohl(tvb, offset); ns.nsecs=0; proto_tree_add_time(tree, hf_ipp_timestamp, tvb, offset, 4, &ns); } else if ((name_length > 5) && name_val && !strcmp(name_val, "printer-state")) { proto_tree_add_item(tree, hf_ipp_printer_state, tvb, offset, value_length, ENC_BIG_ENDIAN); } else if ((name_length > 5) && name_val && !strcmp(name_val, "job-state")) { proto_tree_add_item(tree, hf_ipp_job_state, tvb, offset, value_length, ENC_BIG_ENDIAN); } else{ proto_tree_add_item(tree, hf_ipp_uint32_value, tvb, offset, value_length, ENC_BIG_ENDIAN); } } break; } }
/** *Helper function to dissect a Thermostat schedule, which has * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset payload offset of the ZoneStatus value. *@return length of parsed data. */ static int dissect_zcl_thermostat_schedule(proto_tree *tree, tvbuff_t *tvb, guint offset) { guint start = offset; guint8 num_transitions; guint8 mode_sequence; int i; num_transitions = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zbee_zcl_thermostat_schedule_num_trans, tvb, offset, 1, num_transitions); offset++; dissect_zcl_thermostat_schedule_days(tree, tvb, offset); offset++; mode_sequence = tvb_get_guint8(tvb, offset); dissect_zcl_thermostat_schedule_mode(tree, tvb, offset); offset++; /* Parse the list of setpoint transitions. */ for (i = 0; i < num_transitions; i++) { nstime_t tv; tv.secs = tvb_get_letohs(tvb, offset) * 60; tv.nsecs = 0; proto_tree_add_time(tree, hf_zbee_zcl_thermostat_schedule_time, tvb, offset, 2, &tv); offset += 2; if (mode_sequence & ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_HEAT) { float setpoint = (gint16)tvb_get_letohs(tvb, offset); proto_tree_add_float(tree, hf_zbee_zcl_thermostat_schedule_heat, tvb, offset, 2, (setpoint / 100.0f)); offset += 2; } if (mode_sequence & ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_COOL) { float setpoint = (gint16)tvb_get_letohs(tvb, offset); proto_tree_add_float(tree, hf_zbee_zcl_thermostat_schedule_cool, tvb, offset, 2, (setpoint / 100.0f)); offset += 2; } } /* for */ /* Return the number of bytes parsed. */ return (offset - start); } /* dissect_zcl_thermostat_cmd_schedule */
static void dissect_whoent(tvbuff_t *tvb, int offset, proto_tree *tree) { proto_tree *whoent_tree = NULL; proto_item *whoent_ti = NULL; int line_offset = offset; guint8 *out_line; guint8 *out_name; nstime_t ts; int whoent_num = 0; guint32 idle_secs; /* say that out loud... */ ts.nsecs = 0; while (tvb_reported_length_remaining(tvb, line_offset) > 0 && whoent_num < MAX_NUM_WHOENTS) { whoent_ti = proto_tree_add_item(tree, hf_who_whoent, tvb, line_offset, SIZE_OF_WHOENT, ENC_NA); whoent_tree = proto_item_add_subtree(whoent_ti, ett_whoent); out_line = tvb_get_stringzpad(wmem_packet_scope(), tvb, line_offset, 8, ENC_ASCII|ENC_NA); proto_tree_add_string(whoent_tree, hf_who_tty, tvb, line_offset, 8, out_line); line_offset += 8; out_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, line_offset, 8, ENC_ASCII|ENC_NA); proto_tree_add_string(whoent_tree, hf_who_uid, tvb, line_offset, 8, out_name); line_offset += 8; ts.secs = tvb_get_ntohl(tvb, line_offset); proto_tree_add_time(whoent_tree, hf_who_timeon, tvb, line_offset, 4, &ts); line_offset += 4; idle_secs = tvb_get_ntohl(tvb, line_offset); proto_tree_add_uint_format(whoent_tree, hf_who_idle, tvb, line_offset, 4, idle_secs, "Idle: %s", time_secs_to_str(wmem_packet_scope(), idle_secs)); line_offset += 4; whoent_num++; } }
static void dissect_whoent(tvbuff_t *tvb, int offset, proto_tree *tree) { proto_tree *whoent_tree = NULL; proto_item *whoent_ti = NULL; int line_offset = offset; gchar out_line[9]; gchar out_name[9]; nstime_t ts; int whoent_num = 0; guint32 idle_secs; /* say that out loud... */ ts.nsecs = 0; while (tvb_reported_length_remaining(tvb, line_offset) > 0 && whoent_num < MAX_NUM_WHOENTS) { whoent_ti = proto_tree_add_item(tree, hf_who_whoent, tvb, line_offset, SIZE_OF_WHOENT, FALSE); whoent_tree = proto_item_add_subtree(whoent_ti, ett_whoent); tvb_get_nstringz0(tvb, line_offset, sizeof(out_line), (guint8*)out_line); proto_tree_add_string(whoent_tree, hf_who_tty, tvb, line_offset, 8, out_line); line_offset += 8; tvb_get_nstringz0(tvb, line_offset, sizeof(out_name), (guint8*)out_name); proto_tree_add_string(whoent_tree, hf_who_uid, tvb, line_offset, 8, out_name); line_offset += 8; ts.secs = tvb_get_ntohl(tvb, line_offset); proto_tree_add_time(whoent_tree, hf_who_timeon, tvb, line_offset, 4, &ts); line_offset += 4; idle_secs = tvb_get_ntohl(tvb, line_offset); proto_tree_add_uint_format(whoent_tree, hf_who_idle, tvb, line_offset, 4, idle_secs, "Idle: %s", time_secs_to_str(idle_secs)); line_offset += 4; whoent_num++; } }
/* Dissection routines */ static int dissect_kt_replication_wait(tvbuff_t *tvb, proto_tree *tree, gint offset) { gint new_offset; guint64 ts; nstime_t ns_ts; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; ts = tvb_get_ntoh64(tvb, new_offset); ns_ts.secs = (time_t)(ts/1000000000); ns_ts.nsecs = (int)(ts%1000000000); proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts); new_offset += 8; return new_offset; }
static rtpproxy_info_t * rtpproxy_add_tid(gboolean is_request, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_tree, rtpproxy_conv_info_t *rtpproxy_conv, gchar* cookie) { rtpproxy_info_t *rtpproxy_info; proto_item *pi; if (!PINFO_FD_VISITED(pinfo)) { if (is_request) { rtpproxy_info = wmem_new(wmem_file_scope(), rtpproxy_info_t); rtpproxy_info->req_frame = PINFO_FD_NUM(pinfo); rtpproxy_info->resp_frame = 0; rtpproxy_info->req_time = pinfo->fd->abs_ts; rtpproxy_info->callid = NULL; wmem_tree_insert_string(rtpproxy_conv->trans, cookie, rtpproxy_info, 0); } else { rtpproxy_info = (rtpproxy_info_t *)wmem_tree_lookup_string(rtpproxy_conv->trans, cookie, 0); if (rtpproxy_info) { rtpproxy_info->resp_frame = PINFO_FD_NUM(pinfo); } } } else { rtpproxy_info = (rtpproxy_info_t *)wmem_tree_lookup_string(rtpproxy_conv->trans, cookie, 0); if (rtpproxy_info && (is_request ? rtpproxy_info->resp_frame : rtpproxy_info->req_frame)) { nstime_t ns; pi = proto_tree_add_uint(rtpproxy_tree, is_request ? hf_rtpproxy_response_in : hf_rtpproxy_request_in, tvb, 0, 0, is_request ? rtpproxy_info->resp_frame : rtpproxy_info->req_frame); PROTO_ITEM_SET_GENERATED(pi); /* If reply then calculate response time */ if (!is_request) { nstime_delta(&ns, &pinfo->fd->abs_ts, &rtpproxy_info->req_time); pi = proto_tree_add_time(rtpproxy_tree, hf_rtpproxy_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(pi); if (nstime_cmp(&rtpproxy_timeout_ns, &ns) < 0) expert_add_info_format(pinfo, rtpproxy_tree, &ei_rtpproxy_timeout, "Response timeout %.3f seconds", nstime_to_sec(&ns)); } } } /* Could be NULL so we should check it before dereferencing */ return rtpproxy_info; }
/* Dissection routines */ static int dissect_kt_replication_wait(tvbuff_t *tvb, proto_tree *tree) { int offset; guint64 ts; nstime_t ns_ts; proto_item *pi; pi = proto_tree_add_uint(tree, hf_kt_type, tvb, 0, 1, KT_OPER_REQUEST); PROTO_ITEM_SET_GENERATED(pi); offset = 1; ts = tvb_get_ntoh64(tvb, offset); ns_ts.secs = (time_t)(ts/1000000000); ns_ts.nsecs = (int)(ts%1000000000); proto_tree_add_time(tree, hf_kt_ts, tvb, offset, 8, &ns_ts); offset += 8; return offset; }
static gint dissect_om2k_time(tvbuff_t *tvb, gint offset, proto_tree *tree) { nstime_t tmptime; time_t tval; struct tm _time; _time.tm_year = 100 + tvb_get_guint8(tvb, offset++); _time.tm_mon = tvb_get_guint8(tvb, offset++) - 1; _time.tm_mday = tvb_get_guint8(tvb, offset++); _time.tm_hour = tvb_get_guint8(tvb, offset++); _time.tm_min = tvb_get_guint8(tvb, offset++); _time.tm_sec = tvb_get_guint8(tvb, offset++); _time.tm_isdst = -1; tval = mktime(&_time); tmptime.secs = tval; tmptime.nsecs = 0; proto_tree_add_time(tree, hf_om2k_cal_time, tvb, offset, 6, &tmptime); return 6; }
static void dissect_dvb_tot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint descriptor_len; proto_item *ti; proto_tree *dvb_tot_tree; nstime_t utc_time; col_set_str(pinfo->cinfo, COL_INFO, "Time Offset Table (TOT)"); ti = proto_tree_add_item(tree, proto_dvb_tot, tvb, offset, -1, ENC_NA); dvb_tot_tree = proto_item_add_subtree(ti, ett_dvb_tot); offset += packet_mpeg_sect_header(tvb, offset, dvb_tot_tree, NULL, NULL); if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) { proto_tree_add_time_format_value(dvb_tot_tree, hf_dvb_tot_utc_time, tvb, offset, 5, &utc_time, "Unparseable time"); } else { proto_tree_add_time(dvb_tot_tree, hf_dvb_tot_utc_time, tvb, offset, 5, &utc_time); } offset += 5; descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_TOT_DESCRIPTORS_LOOP_LENGTH_MASK; proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += proto_mpeg_descriptor_loop_dissect(tvb, offset, descriptor_len, dvb_tot_tree); offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_tot_tree, 0, offset); proto_item_set_len(ti, offset); }
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 dissect_cmp_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { tvbuff_t *next_tvb; guint32 pdu_len; guint8 pdu_type; nstime_t ts; proto_item *item=NULL; proto_item *ti=NULL; proto_tree *tree=NULL; proto_tree *tcptrans_tree=NULL; asn1_ctx_t asn1_ctx; int offset=0; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); col_set_str(pinfo->cinfo, COL_PROTOCOL, "CMP"); col_set_str(pinfo->cinfo, COL_INFO, "PKIXCMP"); if(parent_tree){ item=proto_tree_add_item(parent_tree, proto_cmp, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_cmp); } pdu_len=tvb_get_ntohl(tvb, 0); pdu_type=tvb_get_guint8(tvb, 4); if (pdu_type < 10) { /* RFC2510 TCP transport */ ti = proto_tree_add_item(tree, proto_cmp, tvb, offset, 5, ENC_NA); tcptrans_tree = proto_item_add_subtree(ti, ett_cmp); proto_tree_add_item(tree, hf_cmp_tcptrans_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_cmp_tcptrans_type, tvb, offset++, 1, ENC_BIG_ENDIAN); } else { /* post RFC2510 TCP transport - the former "type" field is now "version" */ ti = proto_tree_add_text(tree, tvb, offset, 7, "TCP transport"); tcptrans_tree = proto_item_add_subtree(ti, ett_cmp); pdu_type=tvb_get_guint8(tvb, 6); proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans10_version, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans10_flags, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_type, tvb, offset++, 1, ENC_BIG_ENDIAN); } col_add_str (pinfo->cinfo, COL_INFO, val_to_str (pdu_type, cmp_pdu_types, "0x%x")); switch(pdu_type){ case CMP_TYPE_PKIMSG: next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len); dissect_cmp_pdu(next_tvb, tree, &asn1_ctx); offset += tvb_length_remaining(tvb, offset); break; case CMP_TYPE_POLLREP: proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; ts.secs = tvb_get_ntohl(tvb, 4); ts.nsecs = 0; proto_tree_add_time(tcptrans_tree, hf_cmp_tcptrans_ttcb, tvb, offset, 4, &ts); offset += 4; break; case CMP_TYPE_POLLREQ: proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case CMP_TYPE_NEGPOLLREP: break; case CMP_TYPE_PARTIALMSGREP: proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_next_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; ts.secs = tvb_get_ntohl(tvb, 4); ts.nsecs = 0; proto_tree_add_time(tcptrans_tree, hf_cmp_tcptrans_ttcb, tvb, offset, 4, &ts); offset += 4; next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len); dissect_cmp_pdu(next_tvb, tree, &asn1_ctx); offset += tvb_length_remaining(tvb, offset); break; case CMP_TYPE_FINALMSGREP: next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len); dissect_cmp_pdu(next_tvb, tree, &asn1_ctx); offset += tvb_length_remaining(tvb, offset); break; case CMP_TYPE_ERRORMSGREP: /*XXX to be added*/ break; } return offset; }
static void dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_item *volatile ti = NULL; nstime_t ts; int cap_len = 0, frame_len = 0; proto_tree *volatile tree; proto_item *item; guint32 frame_number; frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps will show the packetnumber where the crash occurred. */ tree=parent_tree; pinfo->current_proto = "Frame"; if (pinfo->pseudo_header != NULL) { switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_WFLEET_HDLC: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: case WTAP_ENCAP_SDLC: case WTAP_ENCAP_BLUETOOTH_H4: case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_BLUETOOTH_HCI: pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: case WTAP_ENCAP_FRELAY_WITH_PHDR: pinfo->p2p_dir = (pinfo->pseudo_header->x25.flags & FROM_DCE) ? P2P_DIR_RECV : P2P_DIR_SENT; break; case WTAP_ENCAP_ISDN: pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_LINUX_LAPD: pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 || pinfo->pseudo_header->lapd.pkttype == 4) ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_MTP2_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ? P2P_DIR_SENT : P2P_DIR_RECV; pinfo->link_number = pinfo->pseudo_header->mtp2.link_number; pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used; break; case WTAP_ENCAP_GSM_UM: pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ? P2P_DIR_SENT : P2P_DIR_RECV; break; } } /* if FRAME is not referenced from any filters we dont need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_frame)) { tree=NULL; if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } else { proto_tree *fh_tree; /* Put in frame header information. */ cap_len = tvb_length(tvb); frame_len = tvb_reported_length(tvb); ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1, "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, frame_len, cap_len); fh_tree = proto_item_add_subtree(ti, ett_frame); ts = pinfo->fd->abs_ts; proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb, 0, 0, &ts); if(ts.nsecs < 0 || ts.nsecs >= 1000000000) { item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb, 0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs); PROTO_ITEM_SET_GENERATED(item); expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)"); } ts = pinfo->fd->del_cap_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); ts = pinfo->fd->del_dis_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); ts = pinfo->fd->rel_ts; item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb, 0, 0, &ts); PROTO_ITEM_SET_GENERATED(item); if(pinfo->fd->flags.ref_time){ ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, FALSE); PROTO_ITEM_SET_GENERATED(ti); } proto_tree_add_uint(fh_tree, hf_frame_number, tvb, 0, 0, pinfo->fd->num); proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb, 0, 0, frame_len, "Frame Length: %d byte%s", frame_len, plurality(frame_len, "", "s")); proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb, 0, 0, cap_len, "Capture Length: %d byte%s", cap_len, plurality(cap_len, "", "s")); if (generate_md5_hash) { const guint8 *cp; md5_state_t md_ctx; md5_byte_t digest[16]; gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); md5_init(&md_ctx); md5_append(&md_ctx, cp, cap_len); md5_finish(&md_ctx, digest); digest_string = bytestring_to_str(digest, 16, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); pinfo->layer_names = g_string_new(""); /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } /* Check for existences of MTP2 link number */ if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) { proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } if (show_file_off) { proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } if(pinfo->fd->color_filter != NULL) { color_filter_t *color_filter = pinfo->fd->color_filter; item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ __try { #endif if ((force_docsis_encap) && (docsis_handle)) { call_dissector(docsis_handle, tvb, pinfo, parent_tree); } else { if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u", pinfo->fd->lnk_t); call_dissector(data_handle,tvb, pinfo, parent_tree); } } #ifdef _MSC_VER } __except(TRUE /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if (tree && pinfo->layer_names) { proto_item_append_string(ti, pinfo->layer_names->str); g_string_free(pinfo->layer_names, TRUE); pinfo->layer_names = NULL; } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(TRUE /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } tap_queue_packet(frame_tap, pinfo, NULL); if (frame_end_routines) { g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL); g_slist_free(frame_end_routines); frame_end_routines = NULL; } }
static int dissect_kt_get_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { guint32 next32, rnum, ksiz, vsiz; guint64 xt; nstime_t ts; gint new_offset, rec_start_offset; proto_item *ti; proto_item *pi; proto_tree *rec_tree; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; next32 = tvb_get_ntohl(tvb, new_offset); if (next32 == 0) { if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* request */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST); PROTO_ITEM_SET_GENERATED(pi); proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32); new_offset += 4; rnum = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum); new_offset += 4; while (rnum > 0) { /* Create a sub-tree for each record */ ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA); rec_tree = proto_item_add_subtree(ti, ett_kt_rec); rec_start_offset = new_offset; proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN); new_offset += 2; ksiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz); new_offset += 4; proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += ksiz; proto_item_set_len(ti, new_offset - rec_start_offset); rnum--; } } else { /* response - no records */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, next32); new_offset += 4; } } else { /* response - one or more records */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); rnum = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, rnum); new_offset += 4; while (rnum > 0) { /* Create a sub-tree for each record */ ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA); rec_tree = proto_item_add_subtree(ti, ett_kt_rec); rec_start_offset = new_offset; proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN); new_offset += 2; ksiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz); new_offset += 4; vsiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz); new_offset += 4; xt = tvb_get_ntoh64(tvb, new_offset); ts.secs = (time_t)(xt&0xFFFFFFFF); ts.nsecs = 0; proto_tree_add_time(rec_tree, hf_kt_xt_resp, tvb, new_offset, 8, &ts); new_offset += 8; proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += ksiz; proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += vsiz; proto_item_set_len(ti, new_offset - rec_start_offset); rnum--; } } return new_offset; }
/*FUNCTION:------------------------------------------------------ * NAME * dissect_zep * DESCRIPTION * IEEE 802.15.4 packet dissection routine for Wireshark. * PARAMETERS * tvbuff_t *tvb - pointer to buffer containing raw packet. * packet_info *pinfo - pointer to packet information fields * proto_tree *tree - pointer to data tree Wireshark uses to display packet. * RETURNS * void *--------------------------------------------------------------- */ static void dissect_zep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *proto_root, *pi; proto_tree *zep_tree; guint8 ieee_packet_len; guint8 zep_header_len; zep_info zep_data; dissector_handle_t next_dissector; /* Determine whether this is a Q51/IEEE 802.15.4 sniffer packet or not */ if(strcmp(tvb_get_ephemeral_string(tvb, 0, 2), ZEP_PREAMBLE)){ /* This is not a Q51/ZigBee sniffer packet */ call_dissector(data_handle, tvb, pinfo, tree); return; } memset(&zep_data, 0, sizeof(zep_data)); /* Zero all zep_data fields. */ /* Extract the protocol version from the ZEP header. */ zep_data.version = tvb_get_guint8(tvb, 2); if (zep_data.version == 1) { /* Type indicates a ZEP_v1 packet. */ zep_header_len = ZEP_V1_HEADER_LEN; zep_data.type = 0; zep_data.channel_id = tvb_get_guint8(tvb, 3); zep_data.device_id = tvb_get_ntohs(tvb, 4); zep_data.lqi_mode = tvb_get_guint8(tvb, 6)?1:0; zep_data.lqi = tvb_get_guint8(tvb, 7); ieee_packet_len = (tvb_get_guint8(tvb, ZEP_V1_HEADER_LEN - 1) & ZEP_LENGTH_MASK); } else { /* At the time of writing, v2 is the latest version of ZEP, assuming * anything higher than v2 has identical format. */ zep_data.type = tvb_get_guint8(tvb, 3); if (zep_data.type == ZEP_V2_TYPE_ACK) { /* ZEP Ack has only the seqno. */ zep_header_len = ZEP_V2_ACK_LEN; zep_data.seqno = tvb_get_ntohl(tvb, 4); ieee_packet_len = 0; } else { /* Although, only type 1 corresponds to data, if another value is present, assume it is dissected the same. */ zep_header_len = ZEP_V2_HEADER_LEN; zep_data.channel_id = tvb_get_guint8(tvb, 4); zep_data.device_id = tvb_get_ntohs(tvb, 5); zep_data.lqi_mode = tvb_get_guint8(tvb, 7)?1:0; zep_data.lqi = tvb_get_guint8(tvb, 8); ntp_to_nstime(tvb, 9, &(zep_data.ntp_time)); zep_data.seqno = tvb_get_ntohl(tvb, 17); ieee_packet_len = (tvb_get_guint8(tvb, ZEP_V2_HEADER_LEN - 1) & ZEP_LENGTH_MASK); } } #if 0 /*??dat*/ if (zep_data.ntp_time.secs && zep_data.ntp_time.nsecs) { pinfo->fd->abs_ts = zep_data.ntp_time; } #endif if(ieee_packet_len < tvb_length(tvb)-zep_header_len){ /* Packet's length is mis-reported, abort dissection */ call_dissector(data_handle, tvb, pinfo, tree); return; } /* Enter name info protocol field */ col_set_str(pinfo->cinfo, COL_PROTOCOL, (zep_data.version==1)?"ZEP":"ZEPv2"); /* Enter name info protocol field */ col_clear(pinfo->cinfo, COL_INFO); if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) col_add_fstr(pinfo->cinfo, COL_INFO, "Encapsulated ZigBee Packet [Channel]=%i [Length]=%i", zep_data.channel_id, ieee_packet_len); else col_add_fstr(pinfo->cinfo, COL_INFO, "Ack, Sequence Number: %i", zep_data.seqno); if(tree){ /* Create subtree for the ZEP Header */ if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) { proto_root = proto_tree_add_protocol_format(tree, proto_zep, tvb, 0, zep_header_len, "ZigBee Encapsulation Protocol, Channel: %i, Length: %i", zep_data.channel_id, ieee_packet_len); } else { proto_root = proto_tree_add_protocol_format(tree, proto_zep, tvb, 0, zep_header_len, "ZigBee Encapsulation Protocol, Ack"); } zep_tree = proto_item_add_subtree(proto_root, ett_zep); /* Display the information in the subtree */ proto_tree_add_text(zep_tree, tvb, 0, 2, "Protocol ID String: EX"); if (zep_data.version==1) { proto_tree_add_uint(zep_tree, hf_zep_version, tvb, 2, 1, zep_data.version); proto_tree_add_uint(zep_tree, hf_zep_channel_id, tvb, 3, 1, zep_data.channel_id); proto_tree_add_uint(zep_tree, hf_zep_device_id, tvb, 4, 2, zep_data.device_id); proto_tree_add_boolean_format(zep_tree, hf_zep_lqi_mode, tvb, 6, 1, zep_data.lqi_mode, "LQI/CRC Mode: %s", zep_data.lqi_mode?"CRC":"LQI"); if(!(zep_data.lqi_mode)){ proto_tree_add_uint(zep_tree, hf_zep_lqi, tvb, 7, 1, zep_data.lqi); } proto_tree_add_text(zep_tree, tvb, 7+((zep_data.lqi_mode)?0:1), 7+((zep_data.lqi_mode)?1:0), "Reserved Fields"); } else { proto_tree_add_uint(zep_tree, hf_zep_version, tvb, 2, 1, zep_data.version); if (zep_data.type == ZEP_V2_TYPE_ACK) { proto_tree_add_uint_format(zep_tree, hf_zep_version, tvb, 3, 1, zep_data.type, "Type: %i (Ack)", ZEP_V2_TYPE_ACK); proto_tree_add_uint(zep_tree, hf_zep_seqno, tvb, 4, 4, zep_data.seqno); } else { proto_tree_add_uint_format(zep_tree, hf_zep_version, tvb, 3, 1, zep_data.type, "Type: %i (%s)", zep_data.type, (zep_data.type==ZEP_V2_TYPE_DATA)?"Data":"Reserved"); proto_tree_add_uint(zep_tree, hf_zep_channel_id, tvb, 4, 1, zep_data.channel_id); proto_tree_add_uint(zep_tree, hf_zep_device_id, tvb, 5, 2, zep_data.device_id); proto_tree_add_boolean_format(zep_tree, hf_zep_lqi_mode, tvb, 7, 1, zep_data.lqi_mode, "LQI/CRC Mode: %s", zep_data.lqi_mode?"CRC":"LQI"); if(!(zep_data.lqi_mode)){ proto_tree_add_uint(zep_tree, hf_zep_lqi, tvb, 8, 1, zep_data.lqi); } pi = proto_tree_add_time(zep_tree, hf_zep_timestamp, tvb, 9, 8, &(zep_data.ntp_time)); proto_item_append_text(pi, " (%ld.%09ds)", (long)zep_data.ntp_time.secs, zep_data.ntp_time.nsecs); proto_tree_add_uint(zep_tree, hf_zep_seqno, tvb, 17, 4, zep_data.seqno); } } if (!((zep_data.version==2) && (zep_data.type==ZEP_V2_TYPE_ACK))) proto_tree_add_uint_format(zep_tree, hf_zep_ieee_length, tvb, zep_header_len - 1, 1, ieee_packet_len, "Length: %i %s", ieee_packet_len, (ieee_packet_len==1)?"Byte":"Bytes"); } /* Determine which dissector to call next. */ if (zep_data.lqi_mode) { /* CRC present, use standard IEEE dissector. */ next_dissector = ieee802154_handle; } else { /* ChipCon compliant FCS present. */ next_dissector = ieee802154_ccfcs_handle; } if (!next_dissector) { /* IEEE 802.15.4 dissectors couldn't be found. */ next_dissector = data_handle; } /* Call the IEEE 802.15.4 dissector */ if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) { next_tvb = tvb_new_subset(tvb, zep_header_len, ieee_packet_len, ieee_packet_len); call_dissector(next_dissector, next_tvb, pinfo, tree); } } /* dissect_ieee802_15_4 */
static void dissect_ata_pdu(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean response, guint32 tag) { proto_item *tmp_item; guint8 aflags; guint64 lba; ata_info_t *ata_info=NULL; conversation_t *conversation; /* only create a conversation for ATA commands */ conversation = find_or_create_conversation(pinfo); if( !(pinfo->fd->flags.visited) ){ if(!response){ ata_info_t *tmp_ata_info; /* first time we see this request so add a struct for request/response matching */ ata_info=se_new(ata_info_t); ata_info->tag=tag; ata_info->conversation=conversation; ata_info->request_frame=pinfo->fd->num; ata_info->response_frame=0; ata_info->cmd=tvb_get_guint8(tvb, offset+3); ata_info->req_time=pinfo->fd->abs_ts; tmp_ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_unmatched, ata_info); if(tmp_ata_info){ g_hash_table_remove(ata_cmd_unmatched, tmp_ata_info); } g_hash_table_insert(ata_cmd_unmatched, ata_info, ata_info); } else { ata_info_t tmp_ata_info; /* first time we see this response so see if we can match it with a request */ tmp_ata_info.tag=tag; tmp_ata_info.conversation=conversation; ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_unmatched, &tmp_ata_info); /* woo hoo we could, so no need to store this in unmatched any more, move both request and response to the matched table */ if(ata_info){ ata_info->response_frame=pinfo->fd->num; g_hash_table_remove(ata_cmd_unmatched, ata_info); g_hash_table_insert(ata_cmd_matched, GUINT_TO_POINTER(ata_info->request_frame), ata_info); g_hash_table_insert(ata_cmd_matched, GUINT_TO_POINTER(ata_info->response_frame), ata_info); } } } else { ata_info=(ata_info_t *)g_hash_table_lookup(ata_cmd_matched, GUINT_TO_POINTER(pinfo->fd->num)); } if(ata_info){ if(response){ if(ata_info->request_frame){ nstime_t delta_ts; tmp_item=proto_tree_add_uint(tree, hf_aoe_response_to, tvb, 0, 0, ata_info->request_frame); PROTO_ITEM_SET_GENERATED(tmp_item); nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &ata_info->req_time); tmp_item=proto_tree_add_time(tree, hf_aoe_time, tvb, offset, 0, &delta_ts); PROTO_ITEM_SET_GENERATED(tmp_item); } } else { if(ata_info->response_frame){ tmp_item=proto_tree_add_uint(tree, hf_aoe_response_in, tvb, 0, 0, ata_info->response_frame); PROTO_ITEM_SET_GENERATED(tmp_item); } } } /* aflags */ aflags=tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_aoe_aflags_e, tvb, offset, 1, ENC_BIG_ENDIAN); if(aflags&AOE_AFLAGS_E){ proto_tree_add_item(tree, hf_aoe_aflags_d, tvb, offset, 1, ENC_BIG_ENDIAN); } if(aflags&AOE_AFLAGS_W){ proto_tree_add_item(tree, hf_aoe_aflags_a, tvb, offset, 1, ENC_BIG_ENDIAN); } proto_tree_add_item(tree, hf_aoe_aflags_w, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* err/feature */ proto_tree_add_item(tree, hf_aoe_err_feature, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* sector count */ proto_tree_add_item(tree, hf_aoe_sector_count, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* ata command/status */ if(!response){ proto_tree_add_item(tree, hf_aoe_acmd, tvb, offset, 1, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " ATA:%s", val_to_str(tvb_get_guint8(tvb, offset), ata_cmd_vals, " Unknown ATA<0x%02x>")); } else { proto_tree_add_item(tree, hf_aoe_astatus, tvb, offset, 1, ENC_BIG_ENDIAN); if(ata_info != NULL && ata_info->request_frame){ /* we dont know what command it was unless we saw the request_frame */ tmp_item=proto_tree_add_uint(tree, hf_aoe_acmd, tvb, 0, 0, ata_info->cmd); PROTO_ITEM_SET_GENERATED(tmp_item); col_append_fstr(pinfo->cinfo, COL_INFO, " ATA:%s", val_to_str(ata_info->cmd, ata_cmd_vals, " Unknown ATA<0x%02x>")); } } offset++; /*lba probably complete wrong */ lba=tvb_get_letohs(tvb, offset+4); lba=(lba<<32)|tvb_get_letohl(tvb, offset); offset+=8; proto_tree_add_uint64(tree, hf_aoe_lba, tvb, offset-8, 6, lba); }
static void dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* These are locals used for processing the current tvb */ guint length; gint length_remaining; int offset = 0; proto_tree *ppi_gps_tree = NULL; proto_tree *pt, *present_tree = NULL; proto_tree *my_pt, *gpsflags_flags_tree = NULL; /* used for DeviceType bitmask stuff */ proto_item *ti = NULL; proto_item *gps_line = NULL; /* bits */ int bit; guint32 present, next_present; /* values actually read out, for displaying */ guint32 version, gpsflags_flags; gdouble lat, lon, alt, alt_gnd; nstime_t gps_timestamp; int gps_time_size, already_processed_fractime; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */ gdouble eph, epv, ept; gchar *curr_str; /* these are temporary intermediate values, used in the individual cases below */ guint32 t_lat, t_lon, t_alt, t_alt_gnd; guint32 t_herr, t_verr, t_terr; guint32 t_appspecific_num; /* initialize the timestamp value(s) */ gps_timestamp.secs = gps_timestamp.nsecs = already_processed_fractime = 0; /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); /* pull out the first three fields of the BASE-GEOTAG-HEADER */ version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); /* Setup basic column info */ col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length); /* Create the basic dissection tree*/ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ppi_gps, tvb, 0, length, "GPS:"); gps_line = ti; /*we will make this more useful if we hit lon/lat later */ ppi_gps_tree= proto_item_add_subtree(ti, ett_ppi_gps); proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version); proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, ENC_NA); ti = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length); } /* We support v1 and v2 of GPS tags (identical) */ if (! (version == 1 || version == 2) ) { if (tree) proto_item_append_text(ti, "invalid version (got %d, expected 1 or 2)", version); return; } /* initialize the length of the actual tag contents */ length_remaining = length; /* minimum length check, should atleast be a fixed-size geotagging-base header*/ if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { /* * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion * plus one "present" bitset. */ if (tree) proto_item_append_text(ti, " (invalid - minimum length is 8)"); return; } /* perform tag-specific max length sanity checking */ if (length > PPI_GPS_MAXTAGLEN ) { if (tree) proto_item_append_text(ti, "Invalid PPI-GPS length (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN); return; } /* Subtree for the "present flags" bitfield. */ if (tree) { pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_present, tvb, offset + 4, 4, present); present_tree = proto_item_add_subtree(pt, ett_ppi_gps_present); proto_tree_add_item(present_tree, hf_ppi_gps_present_gpsflags_flags, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_lat, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_lon, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_alt, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_alt_gnd, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_gpstime, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_fractime, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_eph, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_epv, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_ept, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_descr, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_num, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_data, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_ext, tvb, 4, 4, ENC_LITTLE_ENDIAN); } offset += PPI_GEOBASE_MIN_HEADER_LEN; length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */ 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 PPI_GEOTAG_GPSFLAGS: if (length_remaining < 4) break; gpsflags_flags = tvb_get_letohl(tvb, offset); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */ if (tree) { /* first we add the hex flags line */ my_pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_gpsflags_flags, tvb, offset , 4, gpsflags_flags); /* then we add a subtree */ gpsflags_flags_tree = proto_item_add_subtree(my_pt, ett_ppi_gps_gpsflags_flags); /* to pin the individual bits on */ proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag0_nofix, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag1_gpsfix, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag2_diffgps, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag3_PPS, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag4_RTK, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag5_floatRTK, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag6_dead_reck, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag7_manual, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag8_sim, tvb, offset, 4, ENC_LITTLE_ENDIAN); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_LAT: if (length_remaining < 4) break; t_lat = tvb_get_letohl(tvb, offset); lat = ppi_fixed3_7_to_gdouble(t_lat); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lat, tvb, offset, 4, lat); proto_item_append_text(gps_line, " Lat:%f ", lat); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_LON: if (length_remaining < 4) break; t_lon = tvb_get_letohl(tvb, offset); lon = ppi_fixed3_7_to_gdouble(t_lon); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lon, tvb, offset, 4, lon); proto_item_append_text(gps_line, " Lon:%f ", lon); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_ALT: if (length_remaining < 4) break; t_alt = tvb_get_letohl(tvb, offset); alt = ppi_fixed6_4_to_gdouble(t_alt); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt, tvb, offset, 4, alt); proto_item_append_text(gps_line, " Alt:%f ", alt); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_ALT_G: if (length_remaining < 4) break; t_alt_gnd = tvb_get_letohl(tvb, offset); alt_gnd = ppi_fixed6_4_to_gdouble(t_alt_gnd); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt_gnd, tvb, offset, 4, alt_gnd); proto_item_append_text(gps_line, " Alt_g:%f ", alt_gnd); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_GPSTIME: if (length_remaining < 4) break; gps_timestamp.secs = tvb_get_letohl(tvb, offset); gps_timestamp.nsecs = 0; gps_time_size = 4; /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */ /* is present. If so, we pull it out, and combine it with GPSTime. */ /* If we do this, we set already_processed_fractime to avoid hitting it below */ if (length_remaining < 4 && (present & PPI_GPS_MASK_FRACTIME)) break; else if (present & PPI_GPS_MASK_FRACTIME) { gps_timestamp.nsecs = tvb_get_letohl(tvb, offset + 4); /* manually offset seconds */ already_processed_fractime = 1; gps_time_size = 8; } if (tree) { proto_tree_add_time(ppi_gps_tree, hf_ppi_gps_gpstime, tvb, offset, gps_time_size, &gps_timestamp); } offset += gps_time_size; length_remaining -= gps_time_size; break; case PPI_GEOTAG_FRACTIONALTIME: if (length_remaining < 4) break; if (already_processed_fractime) break; break; case PPI_GEOTAG_EPH: if (length_remaining < 4) break; t_herr = tvb_get_letohl(tvb, offset); eph = ppi_fixed3_6_to_gdouble(t_herr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_EPV: if (length_remaining < 4) break; t_verr = tvb_get_letohl(tvb, offset); epv = ppi_fixed3_6_to_gdouble(t_verr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_EPT: if (length_remaining < 4) break; t_terr = tvb_get_letohl(tvb, offset); ept = ppi_ns_counter_to_gdouble(t_terr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_DESCRIPTIONSTR: if (length_remaining < 32) break; if (tree) { /* proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, ENC_ASCII|ENC_NA); */ curr_str = tvb_format_stringzpad(tvb, offset, 32); /* need to append_text this */ proto_tree_add_string(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, curr_str); proto_item_append_text(gps_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_GEOTAG_APPID: if (length_remaining < 4) break; t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ if (tree) { proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_APPDATA: if (length_remaining < 60) break; if (tree) { proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60, ENC_NA); } offset+=60; length_remaining-=60; break; /* * This indicates a field whose size we do not know, so we cannot proceed. */ default: next_present = 0; /* this will terminate the loop */ proto_tree_add_text(ppi_gps_tree, tvb, offset, 0, "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.\n", bit); continue; } /* switch (bit) */ } /* (for present..)*/ /* If there was any post processing of the elements, it could happen here. */ return; }
/* entry point */ static gboolean dissect_pktgen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti = NULL; proto_item *tmp = NULL; proto_tree *pktgen_tree = NULL; guint32 offset = 0; nstime_t tstamp; /* check for min size */ if(tvb_length(tvb) < 16) { /* Not a PKTGEN packet. */ return FALSE; } /* check for magic number */ if(tvb_memeql(tvb, 0, pktgen_magic, 4) == -1) { /* Not a PKTGEN packet. */ return FALSE; } /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PKTGEN"); if(check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "Seq: %u", tvb_get_ntohl(tvb, 4)); } if(tree) { /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_pktgen, tvb, 0, -1, FALSE); pktgen_tree = proto_item_add_subtree(ti, ett_pktgen); /* add items to the subtree */ proto_tree_add_item(pktgen_tree, hf_pktgen_magic, tvb, offset, 4, FALSE); offset+=4; proto_tree_add_item(pktgen_tree, hf_pktgen_seqnum, tvb, offset, 4, FALSE); offset+=4; tstamp.secs = tvb_get_ntohl(tvb, offset); tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvsec, tvb, offset, 4, FALSE); PROTO_ITEM_SET_GENERATED(tmp); offset+=4; tstamp.nsecs = tvb_get_ntohl(tvb, offset) /* microsecond on the wire so... */ * 1000; tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvusec, tvb, offset, 4, FALSE); PROTO_ITEM_SET_GENERATED(tmp); offset+=4; proto_tree_add_time(pktgen_tree, hf_pktgen_timestamp, tvb, offset - 8, 8, &tstamp); #if 0 if(tvb_length_remaining(tvb, offset)) /* random data */ proto_tree_add_text(pktgen_tree, tvb, offset, -1, "Data (%u bytes)", tvb_length_remaining(tvb, offset)); #else if(tvb_length_remaining(tvb, offset)) /* random data */ call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, pktgen_tree); #endif } return TRUE; }
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; } }
/* Dissect 9P messages*/ static void dissect_9P(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { guint32 ninesz,tmp,i; guint16 tmp16; guint8 ninemsg; guint offset = 0; const char *mname; gint len,reportedlen; tvbuff_t *next_tvb; proto_item *ti; proto_tree *ninep_tree,*tmp_tree; nstime_t tv; col_set_str(pinfo->cinfo, COL_PROTOCOL, "9P"); col_clear(pinfo->cinfo, COL_INFO); ninesz = tvb_get_letohl(tvb, offset); ninemsg = tvb_get_guint8(tvb, offset + 4); mname = val_to_str(ninemsg, ninep_msg_type,"Unknown"); if(strcmp(mname,"Unknown") == 0) { col_add_fstr(pinfo->cinfo, COL_INFO, "9P Data Continuation(?) (Tag %u)",(guint)ninemsg); return; } col_append_fstr(pinfo->cinfo, COL_INFO, "%s Tag=%u",mname,(guint)tvb_get_letohs(tvb,offset+5)); if (!tree) /*not much more of one line summary interrest yet.. */ return; ti = proto_tree_add_item(tree, proto_9P, tvb, 0, -1, FALSE); ninep_tree = proto_item_add_subtree(ti, ett_9P); proto_tree_add_item(ninep_tree, hf_9P_msgsz, tvb, offset, 4, TRUE); offset+=4; proto_tree_add_item(ninep_tree, hf_9P_msgtype, tvb, offset, 1, TRUE); ++offset; proto_tree_add_item(ninep_tree, hf_9P_tag, tvb, offset, 2, TRUE); offset += 2; switch(ninemsg) { case RVERSION: case TVERSION: proto_tree_add_item(ninep_tree, hf_9P_maxsize, tvb, offset, 4, TRUE); offset +=4; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_version, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_version); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += 2; break; case TAUTH: proto_tree_add_item(ninep_tree, hf_9P_afid, tvb, offset, 4, TRUE); offset +=4; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_uname, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_uname); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_aname, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_aname); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset +=2; break; case RAUTH: dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; break; case RERROR: tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_ename, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_ename); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset +=2; break; case TFLUSH: proto_tree_add_item(ninep_tree, hf_9P_oldtag, tvb, offset, 2, TRUE); break; case RFLUSH: break; case TATTACH: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_afid, tvb, offset, 4, TRUE); offset +=4; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_uname, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_uname); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16 + 2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_aname, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_aname); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; break; case RATTACH: dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; break; case TWALK: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_newfid, tvb, offset, 4, TRUE); offset +=4; tmp16 = tvb_get_letohs(tvb,offset); proto_tree_add_item(ninep_tree, hf_9P_nwalk, tvb, offset, 2, TRUE); offset +=2; /* I can't imagine anyone having a directory depth more than 25, Limit to 10 times that to be sure, 2^16 is too much */ if(tmp16 > 250) { tmp16 = 250; tmp_tree = proto_tree_add_text(ninep_tree, tvb, 0, 0, "Only first 250 items shown"); PROTO_ITEM_SET_GENERATED(tmp_tree); } for(i = 0 ; i < tmp16; i++) { guint16 tmplen; proto_item *wname; proto_tree *wname_tree; tmplen = tvb_get_letohs(tvb,offset); wname = proto_tree_add_item(ninep_tree, hf_9P_wname, tvb, offset+2, tmplen, TRUE); wname_tree = proto_item_add_subtree(wname,ett_9P_wname); proto_tree_add_item(wname_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmplen + 2; } break; case RWALK: tmp16 = tvb_get_letohs(tvb,offset); proto_tree_add_item(ninep_tree, hf_9P_nqid, tvb, offset, 2, TRUE); offset +=2; /* I can't imagine anyone having a directory depth more than 25, Limit to 10 times that to be sure, 2^16 is too much */ if(tmp16 > 250) { tmp16 = 250; tmp_tree = proto_tree_add_text(ninep_tree, tvb, 0, 0, "Only first 250 items shown"); PROTO_ITEM_SET_GENERATED(tmp_tree); } for(i = 0; i < tmp16; i++) { dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; } break; case TOPEN: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; ti = proto_tree_add_item(ninep_tree, hf_9P_mode, tvb, offset, 1, TRUE); dissect_9P_mode(tvb,ti,offset); break; case ROPEN: dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; proto_tree_add_item(ninep_tree, hf_9P_iounit, tvb, offset, 4, TRUE); break; case TCREATE: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_name, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_filename); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16 + 2; ti = proto_tree_add_item(ninep_tree, hf_9P_perm, tvb, offset, 4, TRUE); dissect_9P_dm(tvb,ti,offset,1); offset +=4; ti = proto_tree_add_item(ninep_tree, hf_9P_mode, tvb, offset, 1, TRUE); dissect_9P_mode(tvb,ti,offset); break; case RCREATE: dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; proto_tree_add_item(ninep_tree, hf_9P_iounit, tvb, offset, 4, TRUE); break; case TREAD: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_offset, tvb, offset, 8, TRUE); offset +=8; proto_tree_add_item(ninep_tree, hf_9P_count, tvb, offset, 4, TRUE); break; case RREAD: tmp = tvb_get_letohl(tvb,offset); proto_tree_add_item(ninep_tree, hf_9P_count, tvb, offset, 4, TRUE); offset += 4; len = tvb_reported_length_remaining(tvb, offset); reportedlen = ((gint)tmp&0xffff) > len ? len : (gint)tmp&0xffff; next_tvb = tvb_new_subset(tvb, offset, len, reportedlen); call_dissector(data_handle,next_tvb, pinfo, tree); break; case TWRITE: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_offset, tvb, offset, 8, TRUE); offset +=8; tmp = tvb_get_letohl(tvb,offset); proto_tree_add_item(ninep_tree, hf_9P_count, tvb, offset, 4, TRUE); offset += 4; len = tvb_reported_length_remaining(tvb, offset); reportedlen = ((gint)tmp&0xffff) > len ? len : (gint)tmp&0xffff; next_tvb = tvb_new_subset(tvb, offset, len, reportedlen); call_dissector(data_handle,next_tvb, pinfo, tree); break; case RWRITE: proto_tree_add_item(ninep_tree, hf_9P_count, tvb, offset, 4, TRUE); break; case TCLUNK: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); break; case RCLUNK: break; case TREMOVE: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); break; case RREMOVE: break; case TSTAT: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); break; case RSTAT: proto_tree_add_item(ninep_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_sdlen, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_stattype, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_dev, tvb, offset, 4, TRUE); offset +=4; dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; ti = proto_tree_add_item(ninep_tree, hf_9P_statmode, tvb, offset, 4, TRUE); dissect_9P_dm(tvb,ti,offset,0); offset +=4; tv.secs = tvb_get_letohl(tvb,offset); tv.nsecs = 0; proto_tree_add_time(ninep_tree, hf_9P_atime, tvb, offset, 4, &tv); offset +=4; tv.secs = tvb_get_letohl(tvb,offset); tv.nsecs = 0; proto_tree_add_time(ninep_tree, hf_9P_mtime, tvb, offset, 4, &tv); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_length, tvb, offset, 8, TRUE); offset +=8; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_filename, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_filename); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_uid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_uid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_gid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_gid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_muid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_muid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; break; case TWSTAT: proto_tree_add_item(ninep_tree, hf_9P_fid, tvb, offset, 4, TRUE); offset += 4; proto_tree_add_item(ninep_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_sdlen, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_stattype, tvb, offset, 2, TRUE); offset +=2; proto_tree_add_item(ninep_tree, hf_9P_dev, tvb, offset, 4, TRUE); offset +=4; dissect_9P_qid(tvb,ninep_tree,offset); offset += 13; ti = proto_tree_add_item(ninep_tree, hf_9P_statmode, tvb, offset, 4, TRUE); dissect_9P_dm(tvb,ti,offset,0); offset +=4; tv.secs = tvb_get_letohl(tvb,offset); tv.nsecs = 0; proto_tree_add_time(ninep_tree, hf_9P_atime, tvb, offset, 4, &tv); offset +=4; tv.secs = tvb_get_letohl(tvb,offset); tv.nsecs = 0; proto_tree_add_time(ninep_tree, hf_9P_mtime, tvb, offset, 4, &tv); offset +=4; proto_tree_add_item(ninep_tree, hf_9P_length, tvb, offset, 8, TRUE); offset +=8; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_filename, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_filename); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_uid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_uid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_gid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_gid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; tmp16 = tvb_get_letohs(tvb,offset); ti = proto_tree_add_item(ninep_tree, hf_9P_muid, tvb, offset+2, tmp16, TRUE); tmp_tree = proto_item_add_subtree(ti,ett_9P_muid); proto_tree_add_item(tmp_tree, hf_9P_parmsz, tvb, offset, 2, TRUE); offset += tmp16+2; break; } }
static void dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { const int start_tlv_offset = 4; proto_tree *nflog_tree = NULL; proto_item *ti; int offset = 0; tvbuff_t *next_tvb = NULL; int aftype; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NFLOG"); col_clear(pinfo->cinfo, COL_INFO); aftype = tvb_get_guint8(tvb, 0); /* Header */ if (proto_field_is_referenced(tree, hfi_nflog->id)) { ti = proto_tree_add_item(tree, hfi_nflog, tvb, 0, -1, ENC_NA); nflog_tree = proto_item_add_subtree(ti, ett_nflog); proto_tree_add_item(nflog_tree, &hfi_nflog_family, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(nflog_tree, &hfi_nflog_version, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(nflog_tree, &hfi_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN); /*offset += 2;*/ } offset = start_tlv_offset; /* TLVs */ while (tvb_reported_length_remaining(tvb, offset) >= 4) { guint16 tlv_len = tvb_get_h_guint16(tvb, offset + 0); guint16 tlv_type; guint16 value_len; proto_tree *tlv_tree; /* malformed */ if (tlv_len < 4) return; value_len = tlv_len - 4; tlv_type = (tvb_get_h_guint16(tvb, offset + 2) & 0x7fff); if (nflog_tree) { gboolean handled = FALSE; ti = proto_tree_add_bytes_format(nflog_tree, hfi_nflog_tlv.id, tvb, offset, tlv_len, NULL, "TLV Type: %s (%u), Length: %u", val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"), tlv_type, tlv_len); tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv); proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_length, tvb, offset + 0, 2, ENC_HOST_ENDIAN); proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_type, tvb, offset + 2, 2, ENC_HOST_ENDIAN); switch (tlv_type) { case WS_NFULA_PAYLOAD: handled = TRUE; break; case WS_NFULA_PREFIX: if (value_len >= 1) { proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_prefix, tvb, offset + 4, value_len, ENC_NA); handled = TRUE; } break; case WS_NFULA_UID: if (value_len == 4) { proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_uid, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); handled = TRUE; } break; case WS_NFULA_GID: if (value_len == 4) { proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_gid, tvb, offset + 4, value_len, ENC_BIG_ENDIAN); handled = TRUE; } break; case WS_NFULA_TIMESTAMP: if (value_len == 16) { nstime_t ts; ts.secs = (time_t)tvb_get_ntoh64(tvb, offset + 4); /* XXX - add an "expert info" warning if this is >= 10^9? */ ts.nsecs = (int)tvb_get_ntoh64(tvb, offset + 12); proto_tree_add_time(tlv_tree, &hfi_nflog_tlv_timestamp, tvb, offset + 4, value_len, &ts); handled = TRUE; } break; } if (!handled) proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_unknown, tvb, offset + 4, value_len, ENC_NA); } if (tlv_type == WS_NFULA_PAYLOAD) next_tvb = tvb_new_subset_length(tvb, offset + 4, value_len); offset += ((tlv_len + 3) & ~3); /* next TLV aligned to 4B */ } if (next_tvb) { switch (aftype) { case LINUX_AF_INET: call_dissector(ip_handle, next_tvb, pinfo, tree); break; case LINUX_AF_INET6: call_dissector(ip6_handle, next_tvb, pinfo, tree); break; default: call_dissector(data_handle, next_tvb, pinfo, tree); break; } } }
/* Transfers happen in response to broadcasts, they are always TCP and are * used to send the file to the port mentioned in the broadcast. There are * 2 types of transfers: Pushes, which are direct responses to searches, * in which the peer that has the file connects to the peer that doesn't and * sends it, then disconnects. The other type of transfer is a pull, where * the peer that doesn't have the file connects to the peer that does and * requests it be sent. * * Pulls have a file request which identifies the desired file, * while pushes simply send the file. In practice this works because every * file the implementation sends searches for is on a different TCP port * on the searcher's machine. */ static int dissect_ldss_transfer (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { conversation_t *transfer_conv; ldss_transfer_info_t *transfer_info; struct tcpinfo *transfer_tcpinfo; proto_tree *ti, *line_tree = NULL, *ldss_tree = NULL; nstime_t broadcast_response_time; /* Reject the packet if data is NULL */ if (data == NULL) return 0; transfer_tcpinfo = (struct tcpinfo *)data; col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDSS"); /* Look for the transfer conversation; this was created during * earlier broadcast dissection (see prepare_ldss_transfer_conv) */ transfer_conv = find_conversation (pinfo->num, &pinfo->src, &pinfo->dst, PT_TCP, pinfo->srcport, pinfo->destport, 0); transfer_info = (ldss_transfer_info_t *)conversation_get_proto_data(transfer_conv, proto_ldss); /* For a pull, the first packet in the TCP connection is the file request. * First packet is identified by relative seq/ack numbers of 1. * File request only appears on a pull (triggered by an offer - see above * about broadcasts) */ if (transfer_tcpinfo->seq == 1 && transfer_tcpinfo->lastackseq == 1 && transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND) { /* LDSS pull transfers look a lot like HTTP. * Sample request: * md5:01234567890123... * Size: 2550 * Start: 0 * Compression: 0 * (remote end sends the file identified by the digest) */ guint offset = 0; gboolean already_dissected = TRUE; col_set_str(pinfo->cinfo, COL_INFO, "LDSS File Transfer (Requesting file - pull)"); if (highest_num_seen == 0 || highest_num_seen < pinfo->num) { already_dissected = FALSE; transfer_info->req = wmem_new0(wmem_file_scope(), ldss_file_request_t); transfer_info->req->file = wmem_new0(wmem_file_scope(), ldss_file_t); highest_num_seen = pinfo->num; } if (tree) { ti = proto_tree_add_item(tree, proto_ldss, tvb, 0, tvb_reported_length(tvb), ENC_NA); ldss_tree = proto_item_add_subtree(ti, ett_ldss_transfer); } /* Populate digest data into the file struct in the request */ transfer_info->file = transfer_info->req->file; /* Grab each line from the packet, there should be 4 but lets * not walk off the end looking for more. */ while (tvb_offset_exists(tvb, offset)) { gint next_offset; const guint8 *line; int linelen; gboolean is_digest_line; guint digest_type_len; linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); /* Include new-line in line */ line = (guint8 *)tvb_memdup(NULL, tvb, offset, linelen+1); /* XXX - memory leak? */ line_tree = proto_tree_add_subtree(ldss_tree, tvb, offset, linelen, ett_ldss_transfer_req, NULL, tvb_format_text(tvb, offset, next_offset-offset)); /* Reduce code duplication processing digest lines. * There are too many locals to pass to a function - the signature * looked pretty ugly when I tried! */ is_digest_line = FALSE; if (strncmp(line,"md5:",4)==0) { is_digest_line = TRUE; digest_type_len = 4; transfer_info->file->digest_type = DIGEST_TYPE_MD5; } else if (strncmp(line, "sha1:", 5)==0) { is_digest_line = TRUE; digest_type_len = 5; transfer_info->file->digest_type = DIGEST_TYPE_SHA1; } else if (strncmp(line, "sha256:", 7)==0) { is_digest_line = TRUE; digest_type_len = 7; transfer_info->file->digest_type = DIGEST_TYPE_SHA256; } else if (strncmp(line, "unknown:", 8)==0) { is_digest_line = TRUE; digest_type_len = 8; transfer_info->file->digest_type = DIGEST_TYPE_UNKNOWN; } else if (strncmp(line, "Size: ", 6)==0) { /* Sample size line: * Size: 2550\n */ transfer_info->req->size = g_ascii_strtoull(line+6, NULL, 10); if (tree) { ti = proto_tree_add_uint64(line_tree, hf_ldss_size, tvb, offset+6, linelen-6, transfer_info->req->size); PROTO_ITEM_SET_GENERATED(ti); } } else if (strncmp(line, "Start: ", 7)==0) { /* Sample offset line: * Start: 0\n */ transfer_info->req->offset = g_ascii_strtoull(line+7, NULL, 10); if (tree) { ti = proto_tree_add_uint64(line_tree, hf_ldss_offset, tvb, offset+7, linelen-7, transfer_info->req->offset); PROTO_ITEM_SET_GENERATED(ti); } } else if (strncmp(line, "Compression: ", 13)==0) { /* Sample compression line: * Compression: 0\n */ transfer_info->req->compression = (gint8)strtol(line+13, NULL, 10); /* XXX - bad cast */ if (tree) { ti = proto_tree_add_uint(line_tree, hf_ldss_compression, tvb, offset+13, linelen-13, transfer_info->req->compression); PROTO_ITEM_SET_GENERATED(ti); } } else { proto_tree_add_expert(line_tree, pinfo, &ei_ldss_unrecognized_line, tvb, offset, linelen); } if (is_digest_line) { /* Sample digest-type/digest line: * md5:0123456789ABCDEF\n */ if (!already_dissected) { GByteArray *digest_bytes; digest_bytes = g_byte_array_new(); hex_str_to_bytes( tvb_get_ptr(tvb, offset+digest_type_len, linelen-digest_type_len), digest_bytes, FALSE); if(digest_bytes->len >= DIGEST_LEN) digest_bytes->len = (DIGEST_LEN-1); /* Ensure the digest is zero-padded */ transfer_info->file->digest = (guint8 *)wmem_alloc0(wmem_file_scope(), DIGEST_LEN); memcpy(transfer_info->file->digest, digest_bytes->data, digest_bytes->len); g_byte_array_free(digest_bytes, TRUE); } if (tree) { proto_item *tii = NULL; tii = proto_tree_add_uint(line_tree, hf_ldss_digest_type, tvb, offset, digest_type_len, transfer_info->file->digest_type); PROTO_ITEM_SET_GENERATED(tii); tii = proto_tree_add_bytes(line_tree, hf_ldss_digest, tvb, offset+digest_type_len, MIN(linelen-digest_type_len, DIGEST_LEN), transfer_info->file->digest); PROTO_ITEM_SET_GENERATED(tii); } } offset = next_offset; } /* Link forwards to the response for this pull. */ if (tree && transfer_info->resp_num != 0) { ti = proto_tree_add_uint(ldss_tree, hf_ldss_response_in, tvb, 0, 0, transfer_info->resp_num); PROTO_ITEM_SET_GENERATED(ti); } transfer_info->req->num = pinfo->num; transfer_info->req->ts = pinfo->abs_ts; } /* Remaining packets are the file response */ else { guint64 size; guint64 offset; guint8 compression; /* size, digest, compression come from the file request for a pull but * they come from the broadcast for a push. Pushes don't bother * with a file request - they just send the data. We have to get file * info from the offer broadcast which triggered this transfer. * If we cannot find the file request, default to the broadcast. */ if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND && transfer_info->req != NULL) { transfer_info->file = transfer_info->req->file; size = transfer_info->req->size; offset = transfer_info->req->offset; compression = transfer_info->req->compression; } else { transfer_info->file = transfer_info->broadcast->file; size = transfer_info->broadcast->size; offset = transfer_info->broadcast->offset; compression = transfer_info->broadcast->compression; } /* Remaining data in this TCP connection is all file data. * Always desegment if the size is 0 (ie. unknown) */ if (pinfo->can_desegment) { if (size == 0 || tvb_captured_length(tvb) < size) { pinfo->desegment_offset = 0; pinfo->desegment_len = DESEGMENT_UNTIL_FIN; return 0; } } /* OK. Now we have the whole file that was transferred. */ transfer_info->resp_num = pinfo->num; transfer_info->resp_ts = pinfo->abs_ts; col_add_fstr(pinfo->cinfo, COL_INFO, "LDSS File Transfer (Sending file - %s)", transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND ? "pull" : "push"); if (tree) { ti = proto_tree_add_item(tree, proto_ldss, tvb, 0, tvb_reported_length(tvb), ENC_NA); ldss_tree = proto_item_add_subtree(ti, ett_ldss_transfer); proto_tree_add_bytes_format(ldss_tree, hf_ldss_file_data, tvb, 0, tvb_captured_length(tvb), NULL, compression == COMPRESSION_GZIP ? "Gzip compressed data: %d bytes" : "File data: %d bytes", tvb_captured_length(tvb)); #ifdef HAVE_ZLIB /* Be nice and uncompress the file data. */ if (compression == COMPRESSION_GZIP) { tvbuff_t *uncomp_tvb; uncomp_tvb = tvb_child_uncompress(tvb, tvb, 0, tvb_captured_length(tvb)); if (uncomp_tvb != NULL) { /* XXX: Maybe not a good idea to add a data_source for what may very well be a large buffer since then the full uncompressed buffer will be shown in a tab in the hex bytes pane ? However, if we don't, bytes in an unrelated tab will be highlighted. */ add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Data"); proto_tree_add_bytes_format_value(ldss_tree, hf_ldss_file_data, uncomp_tvb, 0, tvb_captured_length(uncomp_tvb), NULL, "Uncompressed data: %d bytes", tvb_captured_length(uncomp_tvb)); } } #endif ti = proto_tree_add_uint(ldss_tree, hf_ldss_digest_type, tvb, 0, 0, transfer_info->file->digest_type); PROTO_ITEM_SET_GENERATED(ti); if (transfer_info->file->digest != NULL) { /* This is ugly. You can't add bytes of nonzero length and have * filtering work correctly unless you give a valid location in * the packet. This hack pretends the first 32 bytes of the packet * are the digest, which they aren't: they're actually the first 32 * bytes of the file that was sent. */ ti = proto_tree_add_bytes(ldss_tree, hf_ldss_digest, tvb, 0, DIGEST_LEN, transfer_info->file->digest); } PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint64(ldss_tree, hf_ldss_size, tvb, 0, 0, size); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint64(ldss_tree, hf_ldss_offset, tvb, 0, 0, offset); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(ldss_tree, hf_ldss_compression, tvb, 0, 0, compression); PROTO_ITEM_SET_GENERATED(ti); /* Link to the request for a pull. */ if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND && transfer_info->req != NULL && transfer_info->req->num != 0) { ti = proto_tree_add_uint(ldss_tree, hf_ldss_response_to, tvb, 0, 0, transfer_info->req->num); PROTO_ITEM_SET_GENERATED(ti); } } } /* Print the pull response time */ if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND && transfer_info->req != NULL && transfer_info->resp_num != 0) { nstime_t pull_response_time; nstime_delta(&pull_response_time, &transfer_info->resp_ts, &transfer_info->req->ts); ti = proto_tree_add_time(ldss_tree, hf_ldss_transfer_response_time, tvb, 0, 0, &pull_response_time); PROTO_ITEM_SET_GENERATED(ti); } /* Link the transfer back to the initiating broadcast. Response time is * calculated as the time from broadcast to completed transfer. */ ti = proto_tree_add_uint(ldss_tree, hf_ldss_initiated_by, tvb, 0, 0, transfer_info->broadcast->num); PROTO_ITEM_SET_GENERATED(ti); if (transfer_info->resp_num != 0) { nstime_delta(&broadcast_response_time, &transfer_info->resp_ts, &transfer_info->broadcast->ts); ti = proto_tree_add_time(ldss_tree, hf_ldss_transfer_completed_in, tvb, 0, 0, &broadcast_response_time); PROTO_ITEM_SET_GENERATED(ti); } /* This conv got its addr2/port2 set by the TCP dissector because a TCP * connection was established. Make a new one to handle future connections * to the addr/port mentioned in the broadcast, because that socket is * still open. */ if (transfer_tcpinfo->seq == 1 && transfer_tcpinfo->lastackseq == 1) { prepare_ldss_transfer_conv(transfer_info->broadcast); } return tvb_captured_length(tvb); }
static ros_call_response_t * ros_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint invokeId, gboolean isInvoke) { ros_call_response_t rcr, *rcrp=NULL; ros_conv_info_t *ros_info = ros_info_items; /* first see if we have already matched this */ rcr.invokeId=invokeId; rcr.is_request = isInvoke; if(isInvoke) { rcr.req_frame=pinfo->fd->num; rcr.rep_frame=0; } else { rcr.req_frame=0; rcr.rep_frame=pinfo->fd->num; } rcrp=(ros_call_response_t *)g_hash_table_lookup(ros_info->matched, &rcr); if(rcrp) { /* we have found a match */ rcrp->is_request=rcr.is_request; } else { /* we haven't found a match - try and match it up */ if(isInvoke) { /* this a a request - add it to the unmatched list */ /* check that we dont already have one of those in the unmatched list and if so remove it */ rcr.invokeId=invokeId; rcrp=(ros_call_response_t *)g_hash_table_lookup(ros_info->unmatched, &rcr); if(rcrp){ g_hash_table_remove(ros_info->unmatched, rcrp); } /* if we cant reuse the old one, grab a new chunk */ if(!rcrp){ rcrp=wmem_new(wmem_file_scope(), ros_call_response_t); } rcrp->invokeId=invokeId; rcrp->req_frame=pinfo->fd->num; rcrp->req_time=pinfo->fd->abs_ts; rcrp->rep_frame=0; rcrp->is_request=TRUE; g_hash_table_insert(ros_info->unmatched, rcrp, rcrp); return NULL; } else { /* this is a result - it should be in our unmatched list */ rcr.invokeId=invokeId; rcrp=(ros_call_response_t *)g_hash_table_lookup(ros_info->unmatched, &rcr); if(rcrp){ if(!rcrp->rep_frame){ g_hash_table_remove(ros_info->unmatched, rcrp); rcrp->rep_frame=pinfo->fd->num; rcrp->is_request=FALSE; g_hash_table_insert(ros_info->matched, rcrp, rcrp); } } } } if(rcrp){ /* we have found a match */ proto_item *item = NULL; if(rcrp->is_request){ item=proto_tree_add_uint(tree, hf_ros_response_in, tvb, 0, 0, rcrp->rep_frame); PROTO_ITEM_SET_GENERATED (item); } else { nstime_t ns; item=proto_tree_add_uint(tree, hf_ros_response_to, tvb, 0, 0, rcrp->req_frame); PROTO_ITEM_SET_GENERATED (item); nstime_delta(&ns, &pinfo->fd->abs_ts, &rcrp->req_time); item=proto_tree_add_time(tree, hf_ros_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED (item); } } return rcrp; }
/* * Function for the PANA PDU dissector. */ static void dissect_pana_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *pana_tree = NULL; guint16 flags; guint16 msg_type; guint32 msg_length; guint32 avp_length; guint32 seq_num; conversation_t *conversation; pana_conv_info_t *pana_info; pana_transaction_t *pana_trans; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PANA"); col_clear(pinfo->cinfo, COL_INFO); /* Get message length, type and flags */ msg_length = tvb_get_ntohs(tvb, 2); flags = tvb_get_ntohs(tvb, 4); msg_type = tvb_get_ntohs(tvb, 6); seq_num = tvb_get_ntohl(tvb, 12); avp_length = msg_length - 16; col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s-%s", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)")); /* Make the protocol tree */ if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_pana, tvb, 0, -1, ENC_NA); pana_tree = proto_item_add_subtree(ti, ett_pana); } /* * We need to track some state for this protocol on a per conversation * basis so we can do neat things like request/response tracking */ conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ pana_info = (pana_conv_info_t *)conversation_get_proto_data(conversation, proto_pana); if (!pana_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ pana_info = wmem_new(wmem_file_scope(), pana_conv_info_t); pana_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_pana, pana_info); } if(!pinfo->fd->flags.visited){ if(flags&PANA_FLAG_R){ /* This is a request */ pana_trans=wmem_new(wmem_file_scope(), pana_transaction_t); pana_trans->req_frame=pinfo->num; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->abs_ts; wmem_map_insert(pana_info->pdus, GUINT_TO_POINTER(seq_num), (void *)pana_trans); } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); if(pana_trans){ pana_trans->rep_frame=pinfo->num; } } } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); } if(!pana_trans){ /* create a "fake" pana_trans structure */ pana_trans=wmem_new(wmem_packet_scope(), pana_transaction_t); pana_trans->req_frame=0; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->abs_ts; } /* print state tracking in the tree */ if(flags&PANA_FLAG_R){ /* This is a request */ if(pana_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(pana_tree, hf_pana_response_in, tvb, 0, 0, pana_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else { /* This is a reply */ if(pana_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(pana_tree, hf_pana_response_to, tvb, 0, 0, pana_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->abs_ts, &pana_trans->req_time); it=proto_tree_add_time(pana_tree, hf_pana_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } /* Reserved field */ proto_tree_add_item(pana_tree, hf_pana_reserved_type, tvb, offset, 2, ENC_NA); offset += 2; /* Length */ proto_tree_add_item(pana_tree, hf_pana_length_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Flags */ dissect_pana_flags(pana_tree, tvb, offset, flags); offset += 2; /* Message Type */ proto_tree_add_uint_format_value(pana_tree, hf_pana_msg_type, tvb, offset, 2, msg_type, "%s-%s (%d)", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"), msg_type); offset += 2; /* Session ID */ proto_tree_add_item(pana_tree, hf_pana_session_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* Sequence Number */ proto_tree_add_item(pana_tree, hf_pana_seqnumber, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* AVPs */ if(avp_length != 0){ tvbuff_t *avp_tvb; proto_tree *avp_tree; avp_tvb = tvb_new_subset_length(tvb, offset, avp_length); avp_tree = proto_tree_add_subtree(pana_tree, tvb, offset, avp_length, ett_pana_avp, NULL, "Attribute Value Pairs"); dissect_avps(avp_tvb, pinfo, avp_tree); } }