示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
}
示例#5
0
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;
	}
}
示例#7
0
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;
}
示例#8
0
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;
    }
}
示例#9
0
/**
 *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 */
示例#10
0
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++;
	}
}
示例#11
0
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++;
	}
}
示例#12
0
/* 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;
}
示例#13
0
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;
}
示例#14
0
/* 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;
}
示例#15
0
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;
}
示例#16
0
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);
}
示例#17
0
文件: packet-ccn.c 项目: futtre/ccnx
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, &timestamp);
    }

    /* 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;
}
示例#19
0
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;
	}
}
示例#20
0
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;
}
示例#21
0
/*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 */
示例#22
0
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);

}
示例#23
0
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;
}
示例#24
0
/* 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;
	}
}
示例#26
0
文件: packet-9p.c 项目: flaub/HotFuzz
/* 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;
	}
}
示例#27
0
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;
        }
    }
}
示例#28
0
/* 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);
}
示例#29
0
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;
}
示例#30
0
/*
 * 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);
        }

}