static int
dissect_turnchannel_message(tvbuff_t *tvb, packet_info *pinfo,
			    proto_tree *tree)
{
  	guint   len;
	guint16 channel_id;
	guint16 data_len;
	proto_item *ti;
	proto_tree *turnchannel_tree;

	len = tvb_length(tvb);
	/* First, make sure we have enough data to do the check. */
	if (len < TURNCHANNEL_HDR_LEN) {
		  return 0;
	}

	channel_id = tvb_get_ntohs(tvb, 0);
	data_len = tvb_get_ntohs(tvb, 2);

	if ((channel_id < 0x4000) || (channel_id > 0xFFFE)) {
	  return 0;
	}

	if (len != TURNCHANNEL_HDR_LEN + data_len) {
	  return 0;
	}

	/* Seems to be a decent TURN channel message */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "TURN CHANNEL");

	if (check_col(pinfo->cinfo, COL_INFO))
	  col_add_fstr(pinfo->cinfo, COL_INFO, "Channel Id 0x%x", channel_id);

	ti = proto_tree_add_item(tree, proto_turnchannel, tvb, 0, -1, ENC_NA);

	turnchannel_tree = proto_item_add_subtree(ti, ett_turnchannel);

	proto_tree_add_uint(turnchannel_tree, hf_turnchannel_id, tvb, 0, 2, channel_id);
	proto_tree_add_uint(turnchannel_tree, hf_turnchannel_len, tvb, 2, 2, data_len);


	if (len > TURNCHANNEL_HDR_LEN) {
	  tvbuff_t *next_tvb;
	  guint reported_len, new_len;

	  new_len = tvb_length_remaining(tvb, TURNCHANNEL_HDR_LEN);
	  reported_len = tvb_reported_length_remaining(tvb,
						       TURNCHANNEL_HDR_LEN);
	  if (data_len < reported_len) {
	    reported_len = data_len;
	  }
	  next_tvb = tvb_new_subset(tvb, TURNCHANNEL_HDR_LEN, new_len,
				    reported_len);


	  if (!dissector_try_heuristic(heur_subdissector_list,
				       next_tvb, pinfo, tree)) {
	    call_dissector(data_handle,next_tvb, pinfo, tree);
	  }
	}

	return tvb_length(tvb);
}
/* XXX: Are all the tests against tvb_length() really the right way to handle invalid fields ?
 *      It seems to me that invalid fields should just add an expert item
 *        or cause a "Malformed" exception.
 */
static void
dissect_elcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
        gboolean    is_request, length_ok;
        proto_tree *elcom_tree;
        proto_item *ti, *hidden_item;
        gint        offset = 0;
        guint       elcom_len;
        guint8      elcom_msg_type;
        guint8     *suffix;

        /* Check that there's enough data */
        if (tvb_length(tvb) < 3)
                return;

        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ELCOM");
        col_clear(pinfo->cinfo, COL_INFO);

        is_request = (pinfo->match_port == pinfo->destport);
        elcom_len  = tvb_get_ntohs(tvb, 0);
        length_ok  = (tvb_reported_length(tvb) == (elcom_len+2));

        col_add_fstr(pinfo->cinfo, COL_INFO, "%s Len=%d%s",
                             is_request ? "Request" : "Response",
                             elcom_len,
                             length_ok ? "" : " (incorrect)");

        elcom_msg_type = tvb_get_guint8(tvb, 2);
        switch (elcom_msg_type) {
                case P_CONRQ:
                case P_CONRS:

                        /* starting after elcom_len and elcom_msg_type,
                           initiator + responder + userdata fields must be there */
                        if (tvb_length_remaining(tvb, 3+TOTAL_LEN+TOTAL_LEN+3) < 0) return;
                        /* check also that those field lengths are valid */
                        if (tvb_get_guint8(tvb, 3)  != LOWADR_LEN) return;
                        if (tvb_get_guint8(tvb, 3+1+LOWADR_LEN) != SUFFIX_LEN) return;
                        if (tvb_get_guint8(tvb, 3+TOTAL_LEN) != LOWADR_LEN) return;
                        if (tvb_get_guint8(tvb, 3+1+TOTAL_LEN+LOWADR_LEN) != SUFFIX_LEN) return;

                        /* finally believe that there is valid suffix */
                        suffix = tvb_get_string(wmem_packet_scope(), tvb, 3+2+LOWADR_LEN, 2);
                        col_append_fstr(pinfo->cinfo, COL_INFO, " %s Connect", suffix);
                        break;

                case P_RELRQ:
                case P_RELRS:
                        col_append_str(pinfo->cinfo, COL_INFO, " Release");
                        break;

                case P_DATRQ:
                        col_append_str(pinfo->cinfo, COL_INFO, " Data");
                        break;
                }

                switch (elcom_msg_type) {
                case P_CONRQ:
                case P_RELRQ:
                        col_append_str(pinfo->cinfo, COL_INFO, " Request");
                        break;

                case P_CONRS:
                case P_RELRS:
                        col_append_str(pinfo->cinfo, COL_INFO, " Response");
                        break;
        }

        if (!tree)
                return;

        ti = proto_tree_add_item(tree, proto_elcom, tvb, offset, -1, ENC_NA);
        elcom_tree = proto_item_add_subtree(ti, ett_elcom);

        hidden_item = proto_tree_add_boolean(elcom_tree,
                                             is_request ? hf_elcom_request : hf_elcom_response,
                                             tvb, 0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);

        /* 2 first bytes are the frame length */
        offset = 0;
        ti = proto_tree_add_item(elcom_tree, hf_elcom_length, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset = +2;
        if (! length_ok) {
                proto_item_append_text(ti, " (incorrect)");
        }

        elcom_msg_type = tvb_get_guint8(tvb, offset);
        ti = proto_tree_add_item(elcom_tree, hf_elcom_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_item_append_text(elcom_tree, " ( %s)", val_to_str(elcom_msg_type, type_vals, "Unknown %d"));

        offset++;
        if (tvb_length_remaining(tvb, offset) <= 0)
                return;

        switch (elcom_msg_type) {
        case P_CONRQ:
        case P_CONRS:
                /*
                 * Connection request/release assiciated PDU's,
                 * /ELCOM-90 P Protocol spec/ p. 85...
                 */

                /* We need the length here, hardcode the LOWADR_LEN = 21 */
                ti = proto_tree_add_item(elcom_tree, hf_elcom_initiator, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN);
                offset = dissect_lower_address(ti, ett_elcom_initiator, tvb, offset,
                                               hf_elcom_initiator_endian,
                                               hf_elcom_initiator_ip,
                                               hf_elcom_initiator_port,
                                               hf_elcom_initiator_suff);
                if (tvb_length_remaining(tvb, offset) <= 0)
                        return;

                ti = proto_tree_add_item(elcom_tree, hf_elcom_responder, tvb, offset, TOTAL_LEN, ENC_BIG_ENDIAN);
                offset = dissect_lower_address(ti, ett_elcom_responder, tvb, offset,
                                               hf_elcom_responder_endian,
                                               hf_elcom_responder_ip,
                                               hf_elcom_responder_port,
                                               hf_elcom_responder_suff);
                if (tvb_length_remaining(tvb, offset) <= 0)
                        return;

                /* Rest of the payload is USER-DATA, 0..82 bytes */
                ti = proto_tree_add_item(elcom_tree, hf_elcom_userdata, tvb, offset, -1, ENC_NA);
                offset = dissect_userdata(ti, ett_elcom_userdata, tvb, offset);

                break;

        case P_RELRQ:

                proto_tree_add_item(elcom_tree, hf_elcom_release_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                break;
        case P_RELRS:

                proto_tree_add_item(elcom_tree, hf_elcom_release_result, tvb, offset, 1, ENC_BIG_ENDIAN);

                offset += 1;

                break;

        case P_DATRQ:
                ti = proto_tree_add_item(elcom_tree, hf_elcom_datarequest, tvb, offset, -1, ENC_NA);
                offset = dissect_datarequest(ti, ett_elcom_datarequest, tvb, offset);
                break;

        default:
                proto_item_append_text(ti, " <<--- meaning WHAT??");
                break;
        }


        if (tvb_length_remaining(tvb, offset) <= 0)
                return;

        /* We should not get here, but if we do, show what is left over: */
        ti = proto_tree_add_item(elcom_tree, hf_elcom_strangeleftover, tvb, offset, -1, ENC_NA);
        while (tvb_length_remaining(tvb, offset) > 0) {
                proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o",
                                       tvb_get_guint8(tvb, offset));
                offset++;
        }
}
Exemple #3
0
static gboolean
dissect_fcip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
              gboolean check_port)
{
    gint offset = 0,
         start  = 0,
         frame_len = 0;
    gint bytes_remaining = tvb_length (tvb);
    guint8 pflags, sof = 0, eof = 0;
   /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti;
    proto_tree *fcip_tree = NULL;
    tvbuff_t *next_tvb;

    if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
        return FALSE;
    }

    if (check_port &&
        ((pinfo->srcport != fcip_port) && (pinfo->destport != fcip_port))) {
        return FALSE;
    }

    while (bytes_remaining > FCIP_ENCAP_HEADER_LEN) {
        if ((offset = get_next_fcip_header_offset (tvb, pinfo, offset)) == -1) {
            return FALSE;
        }
        else if (offset == -2) {
            /* We need more data to desegment */
            return (TRUE);
        }

        start = offset;
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCIP");

        frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;

        if (bytes_remaining < frame_len) {
            if(fcip_desegment && pinfo->can_desegment) {
                /*
                 * This frame doesn't have all of the data for
                 * this message, but we can do reassembly on it.
                 *
                 * Tell the TCP dissector where the data for this
                 * message starts in the data it handed us, and
                 * how many more bytes we need, and return.
                 */
                pinfo->desegment_offset = offset;
                pinfo->desegment_len = frame_len - bytes_remaining;
                return (TRUE);
            }
        }

        pflags = tvb_get_guint8 (tvb, start+8);

        if (tree) {
            if (FCIP_IS_SF (pflags)) {
                ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
                                                     FCIP_ENCAP_HEADER_LEN,
                                                     "FCIP");
            }
            else if (tvb_bytes_exist (tvb, offset, offset+frame_len-4)) {
                sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);
                eof = tvb_get_guint8 (tvb, offset+frame_len - 4);

                ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
                                                     FCIP_ENCAP_HEADER_LEN,
                                                     "FCIP (%s/%s)",
                                                     val_to_str (sof, fcip_sof_vals,
                                                                 "0x%x"),
                                                     val_to_str (eof, fcip_eof_vals,
                                                                 "0x%x"));
            }
            else {
                sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN);

                ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0,
                                                     FCIP_ENCAP_HEADER_LEN,
                                                     "FCIP (%s/%s)",
                                                     val_to_str (sof, fcip_sof_vals,
                                                                 "0x%x"),
                                                     "NA");
            }
            fcip_tree = proto_item_add_subtree (ti, ett_fcip);
            /* Dissect the Common FC Encap header */
            dissect_fcencap_header (tvb, fcip_tree, offset);

            offset += FCIP_ENCAP_HEADER_LEN;

            if (!FCIP_IS_SF (pflags)) {
                /* print SOF */
                proto_tree_add_item (fcip_tree, hf_fcip_sof, tvb, offset, 1, 0);
                proto_tree_add_item (fcip_tree, hf_fcip_sof_c, tvb, offset+2, 1, 0);
                /* print EOF */

                offset += (frame_len-FCIP_ENCAP_HEADER_LEN-4);
                if (tvb_bytes_exist (tvb, offset, 4)) {
                    proto_tree_add_item (fcip_tree, hf_fcip_eof, tvb, offset, 1, 0);
                    proto_tree_add_item (fcip_tree, hf_fcip_eof_c, tvb, offset+2, 1, 0);
                }
            }
        }

        /* Call the FC Dissector if this is carrying an FC frame */
        if (!FCIP_IS_SF(pflags)) {
            /* Set the SOF/EOF flags in the packet_info header */
            pinfo->sof_eof = 0;

            if (sof) {
                if ((sof == FCIP_SOFi3) || (sof == FCIP_SOFi2) || (sof == FCIP_SOFi4)) {
                    pinfo->sof_eof = PINFO_SOF_FIRST_FRAME;
                }
                else if (sof == FCIP_SOFf) {
                    pinfo->sof_eof = PINFO_SOF_SOFF;
                }

                if (eof != FCIP_EOFn) {
                    pinfo->sof_eof |= PINFO_EOF_LAST_FRAME;
                }
                else if (eof != FCIP_EOFt) {
                    pinfo->sof_eof |= PINFO_EOF_INVALID;
                }
            }

            /* Special frame bit is not set */
            next_tvb = tvb_new_subset_remaining (tvb, FCIP_ENCAP_HEADER_LEN+4);
            if (fc_handle) {
                call_dissector (fc_handle, next_tvb, pinfo, tree);
            }
            else if (data_handle) {
                call_dissector (data_handle, next_tvb, pinfo, tree);
            }
        }
        else {
            col_set_str(pinfo->cinfo, COL_INFO, "Special Frame");
            if (FCIP_IS_CH (pflags)) {
                col_append_str(pinfo->cinfo, COL_INFO, "(Changed)");
            }

            dissect_fcip_sf (tvb, fcip_tree, offset+4);
        }

        bytes_remaining -= frame_len;
    }

    return (TRUE);
}
Exemple #4
0
static void
dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count)
{
	char pdu_msg_type;
	nstime_t timeValue;
	int client_size = 0;
	guint value = 0;
	int size = 0;
	guint public_key = 0;
	char valStr[1024];
	const char *valBulk = NULL;
	const char *valMac = NULL;

	proto_item *ti;
	proto_item *cli_key_item;
	proto_tree *wtls_msg_type_tree;
	proto_tree *wtls_msg_type_item_tree;
	proto_tree *wtls_msg_type_item_sub_tree;
	proto_tree *wtls_msg_type_item_sub_sub_tree;

	pdu_msg_type = tvb_get_guint8 (tvb, offset);
	ti = proto_tree_add_uint(tree, hf_wtls_hands, tvb, offset,count, pdu_msg_type);
	wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type);

	proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type,
			tvb,offset,1,ENC_BIG_ENDIAN);
	offset+=1;
	count = tvb_get_ntohs (tvb, offset);
	proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length,
			tvb,offset,2,ENC_BIG_ENDIAN);
	offset+=2;
	switch(pdu_msg_type) {
		case WTLS_HANDSHAKE_CLIENT_HELLO :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset,
					 count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			timeValue.secs = tvb_get_ntohl (tvb, offset);
			timeValue.nsecs = 0;
			proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb,
					offset, 4, &timeValue);
			offset+=4;
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random,
					tvb,offset,12,ENC_NA);
			offset+=12;
			offset = add_session_id (wtls_msg_type_item_tree,
			    hf_wtls_hands_cli_hello_session,
			    hf_wtls_hands_cli_hello_session_str,
			    tvb, offset);

			/* process client_key_ids structure */
			count = tvb_get_ntohs (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_cli_key_id, tvb, offset,
					 count+2, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);

			/* display length of client_key_ids structure */
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_cli_hello_cli_key_len,
					tvb,offset,2,ENC_BIG_ENDIAN);
			offset+=2;

			/* cycle through client_key_ids entries */
			for (;count > 0;count-=client_size) {
				/* get encryption suite id (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1,
						value);
				client_size=1;
				wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub_sub);
				proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange_suite,
						tvb,offset,1,value);
				offset++;
#ifdef DEBUG
				fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* get parameter index (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
					hf_wtls_hands_cli_hello_key_parameter_index,
					tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* explicit parameters present in next field */
				if (value == 0xff) {
					size = tvb_get_ntohs (tvb, offset);
					proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_parameter_set,
						tvb,offset,size+2,ENC_ASCII|ENC_NA);
					offset+=size+2;
					client_size+=size+2;
				}

				/* get identifier type */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_identifier_type,
						tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* identifier present in next field */
				/* note: value 0x0 means no identifier */
				switch(value) {
					case IDENTIFIER_TEXT :
						/* text identifier */
						/* not tested */
						size = add_text_identifier(
							tvb, offset,
							hf_wtls_hands_cli_hello_key_identifier_charset,
							hf_wtls_hands_cli_hello_key_identifier_size,
							hf_wtls_hands_cli_hello_key_identifier_str,
							wtls_msg_type_item_sub_sub_tree);
						offset += size;
						client_size += size;
						break;
					case IDENTIFIER_BIN :
						/* binary identifier */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "binary id size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_SHA_1 :
						/* SHA-1 hash of the public key */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,20,ENC_NA);
						offset+=20;
						client_size+=20;
#ifdef DEBUG
						fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n",
							client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_X509 :
						/* X.509 distinguished name */
						/* not tested */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "X.509 name size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
				}

				proto_item_set_len(cli_key_item, client_size);
			}

			/* process trusted_keys structure */
			count = tvb_get_ntohs (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_trust_key_id, tvb, offset,
					 count+2, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);

			/* display length of trusted_keys structure */
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_cli_hello_cli_key_len,
					tvb,offset,2,ENC_BIG_ENDIAN);

			offset+=2;
			for (;count > 0;count-=client_size) {
				/* get encryption suite id (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1,
						value);
				client_size=1;
				wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub_sub);
				proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange_suite,
						tvb,offset,1,value);
				offset++;
#ifdef DEBUG
				fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* get parameter index (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
					hf_wtls_hands_cli_hello_key_parameter_index,
					tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* explicit parameters present in next field */
				if (value == 0xff) {
					size = tvb_get_ntohs (tvb, offset);
					proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_parameter_set,
						tvb,offset,size+2,ENC_ASCII|ENC_NA);
					offset+=size+2;
					client_size+=size+2;
				}

				/* get identifier type */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_identifier_type,
						tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* identifier present in next field */
				/* note: value 0x0 means no identifier */
				switch (value) {
					case IDENTIFIER_TEXT :
						/* text identifier */
						/* not tested */
						size = add_text_identifier(
							tvb, offset,
							hf_wtls_hands_cli_hello_key_identifier_charset,
							hf_wtls_hands_cli_hello_key_identifier_size,
							hf_wtls_hands_cli_hello_key_identifier_str,
							wtls_msg_type_item_sub_sub_tree);
						offset += size;
						client_size += size;
						break;
					case IDENTIFIER_BIN :
						/* binary identifier */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "binary id size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_SHA_1 :
						/* SHA-1 hash of the public key */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,20,ENC_NA);
						offset+=20;
						client_size+=20;
#ifdef DEBUG
						fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n",
							client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_X509 :
					 	/* X.509 distinguished name */
						/* not tested */
						size = tvb_get_guint8 (tvb, offset);
						/* need to fetch identifier and display it */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "X.509 name size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
				}
				proto_item_set_len(cli_key_item, client_size);
			}

			/* process cipher_suites structure */
			count = tvb_get_guint8 (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_cipher_suite, tvb, offset,
					 count+1, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);
			offset+=1;
			for (;count > 0;count-=client_size) {
			       value = tvb_get_guint8 (tvb, offset);
			       valBulk = match_strval_ext(value, &wtls_vals_cipher_bulk_ext);
			       offset++;
			       client_size=1;
			       valMac = match_strval_ext(tvb_get_guint8 (tvb, offset), &wtls_vals_cipher_mac_ext);
			       if (valBulk != NULL)
			       {
				       if (valMac != NULL)
				       {
					       g_snprintf(valStr,1024,"%s, %s",valBulk,valMac);
				       }
				       else
				       {
					       g_snprintf(valStr,1024,"%s, Unknown MAC (0x%02x)",valBulk,tvb_get_guint8 (tvb, offset));
				       }
			       }
			       else
			       {
				       if (valMac != NULL)
				       {
					       g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), %s",value,valMac);
				       }
				       else
				       {
					       g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), Unknown MAC (0x%02x)",value,
							       tvb_get_guint8 (tvb, offset));
				       }
				}
				offset++;
				client_size++;
				proto_tree_add_string(wtls_msg_type_item_sub_tree,
						      hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset-2,2,
						      valStr);
			}
			count = tvb_get_guint8 (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_compression_methods, tvb, offset,
					 count+1, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);
			offset+=1;
			for (;count > 0;count-=client_size) {
				client_size=0;
				proto_tree_add_item(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_compression, tvb, offset,1,
						ENC_LITTLE_ENDIAN);
				offset++;
				client_size++;
			}
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_sequence_mode, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_key_refresh, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			break;
		case WTLS_HANDSHAKE_SERVER_HELLO :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset,
					 count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			timeValue.secs = tvb_get_ntohl (tvb, offset);
			timeValue.nsecs = 0;
			proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb,
					offset, 4, &timeValue);
			offset+=4;
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random,
					tvb,offset,12,ENC_NA);
			offset+=12;
			offset = add_session_id (wtls_msg_type_item_tree,
			    hf_wtls_hands_serv_hello_session,
			    hf_wtls_hands_serv_hello_session_str,
			    tvb, offset);
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_cli_key_id,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2,
					ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item,
							  ett_wtls_msg_type_item_sub);
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_serv_hello_cipher_bulk,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			value = tvb_get_guint8 (tvb, offset);
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
				hf_wtls_hands_serv_hello_cipher_mac,
				tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_compression, tvb, offset,1,
					ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_sequence_mode, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_key_refresh, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			break;
		case WTLS_HANDSHAKE_CERTIFICATE :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates,
					tvb, offset,count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			count = tvb_get_ntohs (tvb, offset);
			offset+=2;
			for (;count > 0;count-=client_size) {
				cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree,
						hf_wtls_hands_certificate, tvb, offset,1,
						ENC_NA);
				client_size=0;
				wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub);
				proto_item_set_len(cli_key_item, client_size);
				value =  tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_certificate_type, tvb, offset,1,
						ENC_LITTLE_ENDIAN);
				offset++;
				client_size++;
				switch(value) {
					case CERTIFICATE_WTLS:
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_version,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_signature_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						value =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_issuer_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						switch (value) {
							case IDENTIFIER_NULL :
								break;
							case IDENTIFIER_TEXT :
								value = add_text_identifier(tvb, offset,
									hf_wtls_hands_certificate_wtls_issuer_charset,
									hf_wtls_hands_certificate_wtls_issuer_size,
									hf_wtls_hands_certificate_wtls_issuer_name,
									wtls_msg_type_item_sub_tree);
								offset += value;
								client_size += value;
								break;
							case IDENTIFIER_BIN :
								break;
							case IDENTIFIER_SHA_1 :
								break;
							case IDENTIFIER_X509 :
								break;
						}
						timeValue.secs = tvb_get_ntohl (tvb, offset);
						timeValue.nsecs = 0;
						proto_tree_add_time (wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_valid_not_before,
								tvb, offset, 4, &timeValue);
						offset+=4;
						client_size+=4;
						timeValue.secs = tvb_get_ntohl (tvb, offset);
						timeValue.nsecs = 0;
						proto_tree_add_time (wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_valid_not_after,
								tvb, offset, 4, &timeValue);
						offset+=4;
						client_size+=4;
						value =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_subject_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						switch (value) {
							case IDENTIFIER_NULL :
								break;
							case IDENTIFIER_TEXT :
								value = add_text_identifier(tvb, offset,
									hf_wtls_hands_certificate_wtls_subject_charset,
									hf_wtls_hands_certificate_wtls_subject_size,
									hf_wtls_hands_certificate_wtls_subject_name,
									wtls_msg_type_item_sub_tree);
								offset += value;
								client_size += value;
								break;
							case IDENTIFIER_BIN :
								break;
							case IDENTIFIER_SHA_1 :
								break;
							case IDENTIFIER_X509 :
								break;
						}
						public_key =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_public_key_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						value = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_key_parameter_index,
							tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						client_size++;
						if (value == 0xff) {
							size = tvb_get_ntohs (tvb, offset);
							proto_tree_add_item(wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_key_parameter_set,
								tvb,offset,size+2,ENC_ASCII|ENC_NA);
							offset+=size+2;
							client_size+=size+2;
						}
						switch (public_key) {
							case PUBLIC_KEY_RSA :
								value = tvb_get_ntohs (tvb, offset);
								proto_tree_add_uint(wtls_msg_type_item_sub_tree,
									hf_wtls_hands_certificate_wtls_rsa_exponent,
									tvb,offset,value+2,value*8);
								offset+=2+value;
								client_size+=2+value;
								value = tvb_get_ntohs (tvb, offset);
								proto_tree_add_uint(wtls_msg_type_item_sub_tree,
									hf_wtls_hands_certificate_wtls_rsa_modules,
									tvb,offset,value+2,value*8);
								offset+=2+value;
								client_size+=2+value;
								break;
							case PUBLIC_KEY_ECDH :
								break;
							case PUBLIC_KEY_ECDSA :
								break;
						}
						value = tvb_get_ntohs (tvb, offset);
						proto_tree_add_uint(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_signature,
							tvb,offset,2+value,value*8);
						offset+=2+value;
						client_size+=2+value;
						break;
					case CERTIFICATE_X509:
					case CERTIFICATE_X968:
						value =  tvb_get_ntohs (tvb, offset);
						offset+=2;
						client_size+=2;
						client_size += value;
						offset += value;
						break;
					case CERTIFICATE_URL:
						value =  tvb_get_guint8 (tvb, offset);
						offset++;
						client_size++;
						client_size += value;
						offset += value;
						break;
				}
				proto_item_set_len(cli_key_item, client_size);
			}
			break;
		default:
			offset+=count;
			break;
	}
}
Exemple #5
0
static void
dissect_eapol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  int         offset = 0;
  guint8      eapol_type;
  guint8      keydesc_type;
  guint16     eapol_len;
  guint       len;
  guint16     eapol_key_len, eapol_data_len;
  guint8      key_index;
  guint16     keyinfo;
  proto_tree *ti = NULL;
  proto_tree *eapol_tree = NULL;
  proto_tree *keyinfo_item = NULL;
  proto_tree *keyinfo_tree = NULL;
  proto_tree *key_index_tree, *keydes_tree;
  tvbuff_t   *next_tvb;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPOL");
  col_clear(pinfo->cinfo, COL_INFO);

  if (tree) {
    ti = proto_tree_add_item(tree, proto_eapol, tvb, 0, -1, ENC_NA);
    eapol_tree = proto_item_add_subtree(ti, ett_eapol);

    proto_tree_add_item(eapol_tree, hf_eapol_version, tvb, offset, 1, ENC_BIG_ENDIAN);
  }
  offset++;

  eapol_type = tvb_get_guint8(tvb, offset);
  if (tree)
    proto_tree_add_uint(eapol_tree, hf_eapol_type, tvb, offset, 1, eapol_type);
  if (check_col(pinfo->cinfo, COL_INFO))
    col_add_str(pinfo->cinfo, COL_INFO,
		val_to_str(eapol_type, eapol_type_vals, "Unknown type (0x%02X)"));
  offset++;

  eapol_len = tvb_get_ntohs(tvb, offset);
  len = EAPOL_HDR_LEN + eapol_len;
  set_actual_length(tvb, len);
  if (tree) {
    proto_item_set_len(ti, len);
    proto_tree_add_uint(eapol_tree, hf_eapol_len, tvb, offset, 2, eapol_len);
  }
  offset += 2;

  switch (eapol_type) {

  case EAP_PACKET:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(eap_handle, next_tvb, pinfo, eapol_tree);
    break;

  case EAPOL_KEY:
    if (tree) {
      keydesc_type = tvb_get_guint8(tvb, offset);
      proto_tree_add_item(eapol_tree, hf_eapol_keydes_type, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;
      if (keydesc_type == EAPOL_WPA_KEY || keydesc_type == EAPOL_RSN_KEY) {
	keyinfo = tvb_get_ntohs(tvb, offset);
	if (check_col(pinfo->cinfo, COL_INFO)) {
          if (keyinfo & KEY_INFO_REQUEST_MASK) {
            col_set_str(pinfo->cinfo, COL_INFO, "Key (Request)");
            if (keyinfo & KEY_INFO_ERROR_MASK)
              col_set_str(pinfo->cinfo, COL_INFO, "Key (Request, Error)");
          } else if (keyinfo & KEY_INFO_KEY_TYPE_MASK) {
            guint16 masked;
            masked = keyinfo &
              (KEY_INFO_INSTALL_MASK | KEY_INFO_KEY_ACK_MASK |
               KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK);
            switch (masked) {
            case KEY_INFO_KEY_ACK_MASK:
              col_set_str(pinfo->cinfo, COL_INFO, "Key (msg 1/4)");
              break;
            case KEY_INFO_KEY_MIC_MASK:
              col_set_str(pinfo->cinfo, COL_INFO, "Key (msg 2/4)");
              break;
            case (KEY_INFO_INSTALL_MASK | KEY_INFO_KEY_ACK_MASK |
                  KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK):
              col_set_str(pinfo->cinfo, COL_INFO, "Key (msg 3/4)");
              break;
            case (KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK):
              col_set_str(pinfo->cinfo, COL_INFO, "Key (msg 4/4)");
              break;
            }
          } else {
            if (keyinfo & KEY_INFO_KEY_ACK_MASK)
              col_set_str(pinfo->cinfo, COL_INFO, "Key (Group msg 1/2)");
            else
              col_set_str(pinfo->cinfo, COL_INFO, "Key (Group msg 2/2)");
          }
        }
	keyinfo_item =
	  proto_tree_add_uint(eapol_tree, hf_eapol_wpa_keydes_keyinfo, tvb,
			      offset, 2, keyinfo);

	keyinfo_tree = proto_item_add_subtree(keyinfo_item, ett_keyinfo);
	proto_tree_add_uint(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_keydes_ver, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_type, tvb, offset, 2, keyinfo);
	proto_tree_add_uint(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_index, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_install, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_ack, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_mic, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_secure, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_error, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_request, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_encr_key_data, tvb, offset, 2, keyinfo);

        offset += 2;
        proto_tree_add_uint(eapol_tree, hf_eapol_keydes_keylen, tvb, offset,
        		    2, tvb_get_ntohs(tvb, offset));
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
        		    offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_nonce, tvb, offset,
        		    32, ENC_NA);
        offset += 32;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
        		    offset, 16, ENC_NA);
        offset += 16;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_rsc, tvb, offset,
        		    8, ENC_NA);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_id, tvb, offset, 8,
        		    ENC_NA);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_mic, tvb, offset,
        		    16, ENC_NA);
        offset += 16;
        eapol_data_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(eapol_tree, hf_eapol_wpa_keydes_datalen, tvb,
        		    offset, 2, eapol_data_len);
        offset += 2;
        if (eapol_data_len != 0) {
          ti = proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_data,
          	tvb, offset, eapol_data_len, ENC_NA);
	  if ((keyinfo & KEY_INFO_ENCR_KEY_DATA_MASK) ||
	      !(keyinfo & KEY_INFO_KEY_TYPE_MASK)) {
	    /* RSN: EAPOL-Key Key Data is encrypted.
	     * WPA: Group Keys use encrypted Key Data.
	     * Cannot parse this without knowing the key.
	     * IEEE 802.11i-2004 8.5.2.
	     */
	  } else {
	    keydes_tree = proto_item_add_subtree(ti, ett_eapol_keydes_data);
	    ieee_80211_add_tagged_parameters(tvb, offset, pinfo, keydes_tree,
					     eapol_data_len, -1);
	  }
        }
      } else {
        eapol_key_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(eapol_tree, hf_eapol_keydes_keylen, tvb, offset, 2, eapol_key_len);
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
  			  offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
  			  offset, 16, ENC_NA);
        offset += 16;
        key_index = tvb_get_guint8(tvb, offset);
        ti = proto_tree_add_text(eapol_tree, tvb, offset, 1,
  			       "Key Index: %s, index %u",
  			       (key_index & 0x80) ? "unicast" : "broadcast",
  			       key_index & 0x7F);
        key_index_tree = proto_item_add_subtree(ti, ett_eapol_key_index);
        proto_tree_add_boolean(key_index_tree, hf_eapol_keydes_key_index_keytype,
  			     tvb, offset, 1, key_index);
        proto_tree_add_uint(key_index_tree, hf_eapol_keydes_key_index_indexnum,
  			     tvb, offset, 1, key_index);
        offset += 1;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_signature, tvb,
  			  offset, 16, ENC_NA);
        offset += 16;
        if (eapol_key_len != 0) {
          if (eapol_len > 44) { /* Size of rc4 key with no key content */
            proto_tree_add_item(eapol_tree, hf_eapol_keydes_key, tvb, offset,
  			    eapol_key_len, ENC_NA);
          } else {
		/* IEEE 802.1X-2004 7.6.3.6: If no bytes remain, then  */
		proto_tree_add_text(eapol_tree, tvb, offset, 0, "Key: Use key locally generated by peer");
          }
        }
      }
    }
    break;

  case EAPOL_ENCAP_ASF_ALERT:	/* XXX - is this an SNMP trap? */
  default:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(data_handle, next_tvb, pinfo, eapol_tree);
    break;
  }
}
/* dissector of each payload */
static int
dissect_xtp_aseg(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
	guint32 len = tvb_length_remaining(tvb, offset);
	guint32 start = offset;
	proto_item *ti, *ti2, *top_ti;
	proto_tree *xtp_subtree;
	struct xtp_ip_addr_seg aseg[1];
	int error = 0;

	top_ti = proto_tree_add_text(tree, tvb, offset, len, "Address Segment");
	xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_aseg);

	if (len < XTP_NULL_ADDR_SEG_LEN) {
		proto_item_append_text(top_ti, ", bogus length(%u, must be at least %u)",
			len, XTP_NULL_ADDR_SEG_LEN);
		return 0;
	}

	/** parse common fields **/
	/* alen(2) */
	aseg->alen = tvb_get_ntohs(tvb, offset);
	offset += 2;
	/* adomain(1) */
	aseg->adomain = tvb_get_guint8(tvb, offset);
	offset++;
	/* aformat(1) */
	aseg->aformat = tvb_get_guint8(tvb, offset);

	/** display common fields **/
	offset = start;
	/* alen(2) */
	ti = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_alen,
				tvb, offset, 2, aseg->alen);
	offset += 2;
	if (aseg->alen > len) {
		proto_item_append_text(ti, ", bogus length(%u, must be at most %u)",
			aseg->alen, len);
		error = 1;
	}
	/* adomain(1) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_adomain,
			tvb, offset, 1, aseg->adomain);
	offset++;
	/* aformat(1) */
	ti2 = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_aformat,
			tvb, offset, 1, aseg->aformat);
	offset++;
	switch (aseg->aformat) {
	case 0:
		if (aseg->alen != XTP_NULL_ADDR_SEG_LEN) {
			proto_item_append_text(ti, ", bogus length(%u, must be %u)",
				aseg->alen, XTP_NULL_ADDR_SEG_LEN);
			error = 1;
		}
		break;
	case 1:
		if (aseg->alen != XTP_IP_ADDR_SEG_LEN) {
			proto_item_append_text(ti, ", bogus length(%u, must be %u)",
				aseg->alen, XTP_IP_ADDR_SEG_LEN);
			error = 1;
		}
		break;
	default:
		if (aseg->aformat < 128) {
			proto_item_append_text(ti2,
				", Unsupported aformat(%u)", aseg->aformat);
			error = 1;
		}
		break;
	}

	if (error)
		return (offset - start);

	/** parse and display each address fileds */
	switch (aseg->aformat) {
	case 0:
		/* address(4) */
		aseg->dsthost = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_address,
				tvb, offset, 4, aseg->dsthost);
		offset += 4;
		break;
	case 1:
		/* dsthost(4) */
		aseg->dsthost = tvb_get_ipv4(tvb, offset);
		proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_dsthost,
				tvb, offset, 4, aseg->dsthost);
		offset += 4;
		/* srchost(4) */
		aseg->srchost = tvb_get_ipv4(tvb, offset);
		proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_srchost,
				tvb, offset, 4, aseg->srchost);
		offset += 4;
		/* dstport(2) */
		aseg->dstport = tvb_get_ntohs(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_dstport,
				tvb, offset, 2, aseg->dstport);
		offset += 2;
		/* srcport(2) */
		aseg->srcport = tvb_get_ntohs(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_srcport,
				tvb, offset, 2, aseg->srcport);
		offset += 2;

		/** add summary **/
		proto_item_append_text(top_ti, ", Dst Port: %u", aseg->dstport);
		proto_item_append_text(top_ti, ", Src Port: %u", aseg->srcport);
		break;
	default:
		break;
	}

	return (offset - start);
}
static void
dissect_drda(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gint offset = 0;

    guint16 iCommand;
    guint16 iLength;
    guint16 iCommandEnd = 0;

    guint8 iFormatFlags;
    guint8 iDSSType;
    guint8 iDSSFlags;

    guint16 iParameterCP;
    gint iLengthParam;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDA");
    /* This is a trick to know whether this is the first PDU in this packet or not */
    if (iPreviousFrameNumber != pinfo->fd->num)
        col_clear(pinfo->cinfo, COL_INFO);
    else
        col_append_str(pinfo->cinfo, COL_INFO, " | ");

    iPreviousFrameNumber = pinfo->fd->num;
    /* There may be multiple DRDA commands in one frame */
    while ((guint) (offset + 10) <= tvb_length(tvb))
    {
        iCommand = tvb_get_ntohs(tvb, offset + 8);
        iLength = tvb_get_ntohs(tvb, offset + 0);
        if (iLength < 10) {
            expert_add_info_format_text(pinfo, NULL, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be at least 10 bytes long", iLength);
            break;
        }
        /* iCommandEnd is the length of the packet up to the end of the current command */
        iCommandEnd += iLength;

        if (offset > 0)
            col_append_str(pinfo->cinfo, COL_INFO, " | ");
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext(iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));

        if (tree)
        {
            proto_tree  *drda_tree;
            proto_tree  *drdaroot_tree;
            proto_tree  *drda_tree_sub;
            proto_item  *ti;

            ti = proto_tree_add_item(tree, proto_drda, tvb, offset, -1, ENC_NA);
            proto_item_append_text(ti, " (%s)", val_to_str_ext(iCommand, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
            drdaroot_tree = proto_item_add_subtree(ti, ett_drda);

            ti = proto_tree_add_text(drdaroot_tree, tvb, offset, 10, DRDA_TEXT_DDM);
            proto_item_append_text(ti, " (%s)", val_to_str_ext(iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));
            drda_tree = proto_item_add_subtree(ti, ett_drda_ddm);

            proto_tree_add_item(drda_tree, hf_drda_ddm_length, tvb, offset + 0, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(drda_tree, hf_drda_ddm_magic, tvb, offset + 2, 1, ENC_BIG_ENDIAN);

            iFormatFlags = tvb_get_guint8(tvb, offset + 3);
            iDSSType = iFormatFlags & 0x0F;
            iDSSFlags = iFormatFlags >> 4;

            ti = proto_tree_add_item(drda_tree, hf_drda_ddm_format, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
            drda_tree_sub = proto_item_add_subtree(ti, ett_drda_ddm_format);

            proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_reserved, tvb, offset + 3, 1, iDSSFlags);
            proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_chained, tvb, offset + 3, 1, iDSSFlags);
            proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_errcont, tvb, offset + 3, 1, iDSSFlags);
            proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_samecorr, tvb, offset + 3, 1, iDSSFlags);
            proto_tree_add_uint(drda_tree_sub, hf_drda_ddm_fmt_dsstyp, tvb, offset + 3, 1, iDSSType);

            proto_tree_add_item(drda_tree, hf_drda_ddm_rc, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(drda_tree, hf_drda_ddm_length2, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(drda_tree, hf_drda_ddm_codepoint, tvb, offset + 8, 2, ENC_BIG_ENDIAN);

            /* The number of attributes is variable */
            for (offset += 10; offset < iCommandEnd; )
            {
                if (tvb_length_remaining(tvb, offset) >= 2)
                {
                    iLengthParam = tvb_get_ntohs(tvb, offset + 0);
                    if (iLengthParam == 0 || iLengthParam == 1) iLengthParam = iLength - 10;
                    if (tvb_length_remaining(tvb, offset) >= iLengthParam)
                    {
                        iParameterCP = tvb_get_ntohs(tvb, offset + 2);
                        ti = proto_tree_add_text(drdaroot_tree, tvb, offset, iLengthParam,
                                     DRDA_TEXT_PARAM);
                        proto_item_append_text(ti, " (%s)", val_to_str_ext(iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
                        drda_tree_sub = proto_item_add_subtree(ti, ett_drda_param);
                        proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                        proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
                        proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, ENC_UTF_8|ENC_NA);
                        proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, ENC_EBCDIC|ENC_NA);
                        if (iCommand == DRDA_CP_SQLSTT)
                        {
                            /* Extract SQL statement from packet */
                            tvbuff_t* next_tvb = NULL;
                            next_tvb = tvb_new_subset(tvb, offset + 4, iLengthParam - 4, iLengthParam - 4);
                            add_new_data_source(pinfo, next_tvb, "SQL statement");
                            proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement, next_tvb, 0, iLengthParam - 5, ENC_UTF_8|ENC_NA);
                            proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement_ebcdic, next_tvb, 0, iLengthParam - 4, ENC_EBCDIC|ENC_NA);
                        }
                    }
                    offset += iLengthParam;
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            /* No tree, advance directly to next command */
            offset += iLength;
        }
    }
/* Code to actually dissect the packets */
static void
dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_udp)
{
	gint remaining;
	gint header_length = 3;
	int offset = 0;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPA");
	col_clear(pinfo->cinfo, COL_INFO);

	while ((remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
		proto_item *ti;
		proto_tree *ipa_tree = NULL;
		guint16 len, msg_type;
		tvbuff_t *next_tvb;

		len = tvb_get_ntohs(tvb, offset);
		msg_type = tvb_get_guint8(tvb, offset+2);

		col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
		                val_to_str(msg_type, ipa_protocol_vals,
		                           "unknown 0x%02x"));

		/*
		 * The IPA header is different depending on the transport protocol.
		 * With UDP there seems to be a fourth byte for the IPA header.
		 * We attempt to detect this by checking if the length from the
		 * header + four bytes of the IPA header equals the remaining size.
		 */
		if (is_udp && (len + 4 == remaining)) {
			header_length++;
		}

		if (tree) {
			ti = proto_tree_add_protocol_format(tree, proto_ipa,
					tvb, offset, len+header_length,
					"IPA protocol ip.access, type: %s",
					val_to_str(msg_type, ipa_protocol_vals,
						   "unknown 0x%02x"));
			ipa_tree = proto_item_add_subtree(ti, ett_ipa);
			proto_tree_add_item(ipa_tree, hf_ipa_data_len,
					    tvb, offset, 2, ENC_BIG_ENDIAN);
			proto_tree_add_item(ipa_tree, hf_ipa_protocol,
					    tvb, offset+2, 1, ENC_BIG_ENDIAN);
		}

		next_tvb = tvb_new_subset_length(tvb, offset+header_length, len);

		switch (msg_type) {
		case ABISIP_OML:
			/* hand this off to the standard A-bis OML dissector */
			if (sub_handles[SUB_OML])
				call_dissector(sub_handles[SUB_OML], next_tvb,
						 pinfo, tree);
			break;
		case ABISIP_IPACCESS:
			dissect_ipaccess(next_tvb, pinfo, tree);
			break;
		case AIP_SCCP:
			/* hand this off to the standard SCCP dissector */
			call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree);
			break;
		case IPA_MGCP:
			/* hand this off to the standard MGCP dissector */
			call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree);
			break;
		case OSMO_EXT:
			dissect_osmo(next_tvb, pinfo, ipa_tree, tree);
			break;
		case HSL_DEBUG:
			if (tree) {
				proto_tree_add_item(ipa_tree, hf_ipa_hsl_debug,
						    next_tvb, 0, len, ENC_ASCII|ENC_NA);
				if (global_ipa_in_root == TRUE)
					proto_tree_add_item(tree, hf_ipa_hsl_debug,
							    next_tvb, 0, len, ENC_ASCII|ENC_NA);
			}
			if (global_ipa_in_info == TRUE)
				col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
						tvb_get_stringz_enc(wmem_packet_scope(), next_tvb, 0, NULL, ENC_ASCII));
			break;
		default:
			if (msg_type < ABISIP_RSL_MAX) {
				/* hand this off to the standard A-bis RSL dissector */
				call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree);
			}
			break;
		}
		offset += len + header_length;
	}
}
Exemple #9
0
    proto_item *ti_main;
    proto_item *hidden_item;
    proto_tree *mdshdr_tree_main, *mdshdr_tree_hdr, *mdshdr_tree_trlr;
    int         offset        = 0;
    guint       pktlen;
    tvbuff_t   *next_tvb;
    guint8      sof, eof;
    int         trailer_start = 0; /*0 means "no trailer found"*/
    fc_data_t fc_data;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MDS Header");

    col_clear(pinfo->cinfo, COL_INFO);

    sof     = tvb_get_guint8(tvb, offset+MDSHDR_SOF_OFFSET) & 0x0F;
    pktlen  = tvb_get_ntohs(tvb, offset+MDSHDR_PKTLEN_OFFSET) & 0x1FFF;

    /* The Mdshdr trailer is at the end of the frame */
    if ((tvb_captured_length(tvb) >= (MDSHDR_HEADER_SIZE + pktlen))
        /* Avoid header/trailer overlap if something wrong */
        && (pktlen >= MDSHDR_TRAILER_SIZE))  {
        trailer_start = MDSHDR_HEADER_SIZE + pktlen - MDSHDR_TRAILER_SIZE;

        eof = tvb_get_guint8(tvb, trailer_start);
        tvb_set_reported_length(tvb, MDSHDR_HEADER_SIZE+pktlen);
    }
    else {
        eof = MDSHDR_EOF_UNKNOWN;
    }

    fc_data.sof_eof = 0;
Exemple #10
0
/* main dissector function. wireshark calls it for segments in both
 * directions.
 */
static void
dissect_ajp13_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  guint16 mag;
  /* guint16 len; */
  conversation_t *conv = NULL;
  ajp13_conv_data *cd = NULL;
  proto_tree *ajp13_tree = NULL;
  ajp13_frame_data* fd = NULL;

  /* conversational state really only does us good during the first
   * in-order traversal
   */
  conv = find_or_create_conversation(pinfo);

  cd = (ajp13_conv_data*)conversation_get_proto_data(conv, proto_ajp13);
  if (!cd) {
    cd = se_new(ajp13_conv_data);
    cd->content_length = 0;
    cd->was_get_body_chunk = FALSE;
    conversation_add_proto_data(conv, proto_ajp13, cd);
  }

  /* we use the per segment user data to record the conversational
   * state for use later on when we're called out of order (see
   * comments at top of this file)
   */
  fd = (ajp13_frame_data*)p_get_proto_data(pinfo->fd, proto_ajp13);
  if (!fd) {
    /*printf("ajp13:dissect_ajp13_common():no frame data, adding");*/
    /* since there's no per-packet user data, this must be the first
     * time we've see the packet, and it must be the first "in order"
     * pass through the data.
     */
    fd = se_new(ajp13_frame_data);
    p_add_proto_data(pinfo->fd, proto_ajp13, fd);
    fd->is_request_body = FALSE;
    if (cd->content_length) {
      /* this is screwy, see AJPv13.html. the idea is that if the
       * request has a body (as determined by the content-length
       * header), then there's always an immediate follow-up PDU with
       * no GET_BODY_CHUNK from the container.
       */
      fd->is_request_body = TRUE;
    }
  }

  col_clear(pinfo->cinfo, COL_INFO);

  mag = tvb_get_ntohs(tvb, 0);
  /*  len = tvb_get_ntohs(tvb, 2); */

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "AJP13");

  if (mag == 0x1234 && !fd->is_request_body)
    col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:", conv->index);
  else if (mag == 0x1234 && fd->is_request_body)
    col_append_fstr(pinfo->cinfo, COL_INFO, "%d:REQ:Body", conv->index);
  else if (mag == 0x4142)
    col_append_fstr(pinfo->cinfo, COL_INFO, "%d:RSP:", conv->index);
  else
    col_set_str(pinfo->cinfo, COL_INFO, "AJP13 Error?");

  if (tree) {
    proto_item *ti;
    ti = proto_tree_add_item(tree, proto_ajp13, tvb, 0, -1, ENC_NA);
    ajp13_tree = proto_item_add_subtree(ti, ett_ajp13);
  }

  if (mag == 0x1234) {

    if (fd->is_request_body)
      display_req_body(tvb, ajp13_tree, cd);
    else
      display_req_forward(tvb, pinfo, ajp13_tree, cd);

  } else if (mag == 0x4142) {

    display_rsp(tvb, pinfo, ajp13_tree, cd);

  }
}
Exemple #11
0
static int
dissect_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mndp_tree,
	guint32 offset, guint32 length _U_, const ext_value_string *value_array)
{
	guint32     tlv_type;
	guint32     tlv_length;
	proto_item *tlv_tree;
	proto_item *type_item;
	int         type_index;
	guint32     tlv_end;
	guint       encoding_info;

	tlv_type = tvb_get_ntohs(tvb, offset);
	tlv_length = tvb_get_ntohs(tvb, offset + 2);
	/* DISSECTOR_ASSERT(tlv_length >= 4); */
	tlv_tree = proto_tree_add_subtree_format(mndp_tree, tvb,
		offset, tlv_length+4, ett_mndp_tlv_header, NULL,
		"T %d, L %d: %s",
		tlv_type,
		tlv_length,
		extval_to_str_idx(tlv_type, value_array, NULL, "Unknown"));

	type_item = proto_tree_add_item(tlv_tree, hf_mndp_tlv_type,
		tvb, offset, 2, ENC_BIG_ENDIAN);
	proto_item_append_text(type_item, " = %s",
		extval_to_str_idx(tlv_type, value_array,
			&type_index, "Unknown"));
	offset += 2;
	proto_tree_add_item(tlv_tree, hf_mndp_tlv_length,
		tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	/* tlv_length -= 4; */

	if (tlv_length == 0)
		return offset;

	tlv_end = offset + tlv_length;

	/* Make hf_ handling independent of specialfuncion */
	/* FIXME: Properly handle encoding info */
	if ( type_index != -1
		 && !value_array[type_index].specialfunction
		 && value_array[type_index].evs != NULL
	) {
		encoding_info = value_array[type_index].evs ? TRUE : FALSE;
	} else {
		encoding_info = FALSE;
	}
	if ( type_index != -1 && value_array[type_index].hf_element) {
		proto_tree_add_item(tlv_tree,
			*(value_array[type_index].hf_element),
			tvb, offset, tlv_length, encoding_info);
	} else {
		proto_tree_add_item(tlv_tree, hf_mndp_tlv_data,
			tvb, offset, tlv_length, ENC_NA);
	}
	if ( type_index != -1 && value_array[type_index].specialfunction ) {
		guint32 newoffset;

		while (offset < tlv_end) {
			newoffset = value_array[type_index].specialfunction (
				tvb, pinfo, tlv_tree, offset, tlv_length,
				value_array[type_index].evs);
			DISSECTOR_ASSERT(newoffset > offset);
			offset = newoffset;
		}
	}
	return tlv_end;
}
Exemple #12
0
/* note that even if ajp13_tree is null on the first pass, we still
 * need to dissect the packet in order to determine if there is a
 * content-length, and thus if there is a subsequent automatic
 * request-body transmitted in the next request packet. if there is a
 * content-length, we record the fact in the conversation context.
 * ref the top of this file for comments explaining the multi-pass
 * thing.
*/
static void
display_req_forward(tvbuff_t *tvb, packet_info *pinfo,
                    proto_tree *ajp13_tree,
                    ajp13_conv_data* cd)
{
  int pos = 0;
  guint8 meth;
  guint8 cod;
  const gchar *ver;
  guint16 ver_len;
  const gchar *uri;
  guint16 uri_len;
  const gchar *raddr;
  guint16 raddr_len;
  const gchar *rhost;
  guint16 rhost_len;
  const gchar *srv;
  guint16 srv_len;
  guint nhdr;
  guint i;

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA);
  pos+=2;

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* PACKET CODE
   */
  cod = tvb_get_guint8(tvb, 4);
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;
  if ( cod == MTYPE_CPING ) {
    col_append_str(pinfo->cinfo, COL_INFO, "CPING" );
    return;
  }

  /* HTTP METHOD (ENCODED AS INTEGER)
   */
  meth = tvb_get_guint8(tvb, pos);
  col_append_str(pinfo->cinfo, COL_INFO, val_to_str(meth, http_method_codes, "Unknown method %u"));
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_method, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;

  /* HTTP VERSION STRING
   */
  ver = ajp13_get_nstring(tvb, pos, &ver_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_ver, tvb, pos, ver_len+2, ver);
  pos=pos+ver_len+2;  /* skip over size + chars + trailing null */

  /* URI
   */
  uri = ajp13_get_nstring(tvb, pos, &uri_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_uri, tvb, pos, uri_len+2, uri);
  pos=pos+uri_len+2;  /* skip over size + chars + trailing null */


  col_append_fstr(pinfo->cinfo, COL_INFO, " %s %s", uri, ver);


  /* REMOTE ADDRESS
   */
  raddr = ajp13_get_nstring(tvb, pos, &raddr_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_raddr, tvb, pos, raddr_len+2, raddr);
  pos=pos+raddr_len+2;  /* skip over size + chars + trailing null */

  /* REMOTE HOST
   */
  rhost = ajp13_get_nstring(tvb, pos, &rhost_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_rhost, tvb, pos, rhost_len+2, rhost);
  pos=pos+rhost_len+2;  /* skip over size + chars + trailing null */

  /* SERVER NAME
   */
  srv = ajp13_get_nstring(tvb, pos, &srv_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_srv, tvb, pos, srv_len+2, srv);
  pos=pos+srv_len+2;  /* skip over size + chars + trailing null */

  /* SERVER PORT
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_port, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* IS SSL?
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_sslp, tvb, pos, 1, ENC_NA);
  pos+=1;

  /* NUM HEADERS
   */
  nhdr = tvb_get_ntohs(tvb, pos);

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;
  cd->content_length = 0;

  /* HEADERS
   */
  for(i=0; i<nhdr; i++) {

    guint8 hcd;
    guint8 hid;
    const gchar* hname = NULL;
    header_field_info *hfinfo;
    int hpos = pos;
    int cl = 0;
    const gchar *hval;
    guint16 hval_len, hname_len;

    /* HEADER CODE/NAME
     */
    hcd = tvb_get_guint8(tvb, pos);

    if (hcd == 0xA0) {
      pos+=1;
      hid = tvb_get_guint8(tvb, pos);
      pos+=1;

      if (hid >= array_length(req_headers))
        hid = 0;

      hval = ajp13_get_nstring(tvb, pos, &hval_len);

      if (ajp13_tree) {
        hfinfo = proto_registrar_get_nth(*req_headers[hid]);
        proto_tree_add_string_format(ajp13_tree, *req_headers[hid],
                                     tvb, hpos, 2+hval_len+2, hval,
                                     "%s: %s", hfinfo->name, hval);
      }
      pos+=hval_len+2;

      if (hid == 0x08)
        cl = 1;
    } else {
      hname = ajp13_get_nstring(tvb, pos, &hname_len);
      pos+=hname_len+2;

      hval = ajp13_get_nstring(tvb, pos, &hval_len);

      if (ajp13_tree) {
        proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header,
                                     tvb, hpos, hname_len+2+hval_len+2,
                                     ep_strdup_printf("%s: %s", hname, hval),
                                     "%s: %s", hname, hval);
      }
      pos+=hval_len+2;
    }

    if (cl) {
      cl = atoi(hval);
      cd->content_length = cl;
    }
  }

  /* ATTRIBUTES
   */
  while(tvb_reported_length_remaining(tvb, pos) > 0) {
    guint8 aid;
    const gchar* aname = NULL;
    const gchar* aval;
    guint16 aval_len, aname_len;

    header_field_info *hfinfo;
    int apos = pos;

    /* ATTRIBUTE CODE/NAME
     */
    aid = tvb_get_guint8(tvb, pos);
    pos+=1;

    if (aid == 0xFF) {
      /* request terminator */
      break;
    }
    if (aid == 0x0A) {
      /* req_attribute - name and value follow */

      aname = ajp13_get_nstring(tvb, pos, &aname_len);
      pos+=aname_len+2;

      aval = ajp13_get_nstring(tvb, pos, &aval_len);
      pos+=aval_len+2;

      if (ajp13_tree) {
        proto_tree_add_string_format(ajp13_tree, hf_ajp13_req_attribute,
                                     tvb, apos, 1+aname_len+2+aval_len+2,
                                     g_strdup_printf("%s: %s", aname, aval),
                                     "%s: %s", aname, aval);
      }
    } else if (aid == 0x0B ) {
      /* ssl_key_length */
      if (ajp13_tree) {
        proto_tree_add_uint(ajp13_tree, hf_ajp13_ssl_key_size,
                            tvb, apos, 1+2, tvb_get_ntohs(tvb, pos));
      }
      pos+=2;
    } else {

      if (aid >= array_length(req_attributes))
        aid = 0;

      hfinfo = proto_registrar_get_nth(*req_attributes[aid]);
      aval = ajp13_get_nstring(tvb, pos, &aval_len);
      pos+=aval_len+2;

      if (ajp13_tree) {
        proto_tree_add_string_format(ajp13_tree, *req_attributes[aid],
                                     tvb, apos, 1+aval_len+2, aval,
                                     "%s: %s", hfinfo->name, aval);
      }
    }
  }
}
Exemple #13
0
/* dissect a response. more work to do here.
 */
static void
display_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd)
{
  int pos = 0;
  guint8 mcode = 0;
  int i;

  /* MAGIC
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA);
  pos+=2;

  /* PDU LENGTH
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_len,   tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* MESSAGE TYPE CODE
   */
  mcode = tvb_get_guint8(tvb, pos);
  col_append_str(pinfo->cinfo, COL_INFO, val_to_str(mcode, mtype_codes, "Unknown message code %u"));
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;

  switch (mcode) {

  case MTYPE_END_RESPONSE:
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_reusep, tvb, pos, 1, ENC_BIG_ENDIAN);
    /*pos+=1;*/
    break;

  case MTYPE_SEND_HEADERS:
  {
    const gchar *rsmsg;
    guint16 rsmsg_len;
    guint16 nhdr;
    guint16 rcode_num;

    /* HTTP RESPONSE STATUS CODE
     */
    rcode_num = tvb_get_ntohs(tvb, pos);
    col_append_fstr(pinfo->cinfo, COL_INFO, ":%d", rcode_num);
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_rstatus, tvb, pos, 2, ENC_BIG_ENDIAN);
    pos+=2;

    /* HTTP RESPONSE STATUS MESSAGE
     */
    rsmsg = ajp13_get_nstring(tvb, pos, &rsmsg_len);
    col_append_fstr(pinfo->cinfo, COL_INFO, " %s", rsmsg);
    if (ajp13_tree)
      proto_tree_add_string(ajp13_tree, hf_ajp13_rsmsg, tvb, pos, rsmsg_len+2, rsmsg);
    pos+=rsmsg_len+2;

    /* NUMBER OF HEADERS
     */
    nhdr = tvb_get_ntohs(tvb, pos);
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN);
    pos+=2;

    /* HEADERS
     */
    for(i=0; i<nhdr; i++) {

      guint8 hcd;
      guint8 hid;
      const gchar *hval;
      guint16 hval_len, hname_len;
      const gchar* hname = NULL;
      header_field_info *hfinfo;
      int hpos = pos;
      /* int cl = 0; TODO: Content-Length header (encoded by 0x08) is special */

      /* HEADER CODE/NAME
       */
      hcd = tvb_get_guint8(tvb, pos);

      if (hcd == 0xA0) {
        pos+=1;
        hid = tvb_get_guint8(tvb, pos);
        pos+=1;

        if (hid >= array_length(rsp_headers))
          hid = 0;

        hval = ajp13_get_nstring(tvb, pos, &hval_len);

        if (ajp13_tree) {
          hfinfo = proto_registrar_get_nth(*rsp_headers[hid]);
          proto_tree_add_string_format(ajp13_tree, *rsp_headers[hid],
                                       tvb, hpos, 2+hval_len+2, hval,
                                       "%s: %s", hfinfo->name, hval);
        }
        pos+=hval_len+2;
#if 0
        /* TODO: Content-Length header (encoded by 0x08) is special */
        if (hid == 0x08)
          cl = 1;
#endif
      } else {
        hname = ajp13_get_nstring(tvb, pos, &hname_len);
        pos+=hname_len+2;

        hval = ajp13_get_nstring(tvb, pos, &hval_len);

        if (ajp13_tree) {
          proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header,
                                tvb, hpos, hname_len+2+hval_len+2,
                                ep_strdup_printf("%s: %s", hname, hval),
                                "%s: %s", hname, hval);
        }
        pos+=hval_len+2;
      }
    }
    break;
  }

  case MTYPE_GET_BODY_CHUNK:
  {
    guint16 rlen;
    rlen = tvb_get_ntohs(tvb, pos);
    cd->content_length = rlen;
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_rlen, tvb, pos, 2, ENC_BIG_ENDIAN);
    /*pos+=2;*/
    break;
  }

  case MTYPE_CPONG:
    break;

  default:
    /* MESSAGE DATA (COPOUT)
     */
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_data,  tvb, pos+2, -1, ENC_UTF_8|ENC_NA);
    break;
  }
}
Exemple #14
0
  }
}



/* given the first chunk of the AJP13 pdu, extract out and return the
 * packet length. see comments in packet-tcp.c:tcp_dissect_pdus().
 */
static guint
get_ajp13_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
  /*guint16 magic;*/
  guint16 plen;
  /*magic = tvb_get_ntohs(tvb, offset); */
  plen = tvb_get_ntohs(tvb, offset+2);
  plen += 4;
  return plen;
}



/* Code to actually dissect the packets.
 */
static void
dissect_ajp13(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  /* Set up structures needed to add the protocol subtree and manage it
   */
  tcp_dissect_pdus(tvb, pinfo, tree,
                   TRUE,                   /* desegment or not   */
Exemple #15
0
    /* Actor Key */

    proto_tree_add_item(lacpdu_tree, hf_lacp_actor_key, tvb,
                        offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    /* Actor Port Priority */

    proto_tree_add_item(lacpdu_tree, hf_lacp_actor_port_priority, tvb,
                        offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    /* Actor Port */

    raw_word = tvb_get_ntohs(tvb, offset);
    col_append_fstr(pinfo->cinfo, COL_INFO, "Actor Port = %d ", raw_word);
    proto_tree_add_uint(lacpdu_tree, hf_lacp_actor_port, tvb,
                        offset, 2, raw_word);
    offset += 2;

    /* Actor State */
    proto_tree_add_bitmask_with_flags(lacpdu_tree, tvb, offset, hf_lacp_actor_state,
                           ett_lacp_a_flags, actor_flags, ENC_NA, BMT_NO_INT|BMT_NO_TFS|BMT_NO_FALSE);
    offset += 1;

    /* Actor Reserved */

    proto_tree_add_item(lacpdu_tree, hf_lacp_actor_reserved, tvb,
                        offset, 3, ENC_NA);
    offset += 3;
Exemple #16
0
	guint16		checksum, checksum_calculated;
	guint		checksum_offset;
#endif
	guint16		addr, cr, eah, eal, v5addr;
	gboolean	is_response = 0;
#if 0
	guint		length, reported_length;
#endif
	tvbuff_t	*next_tvb;
	const char	*srcname = "?";
	const char	*dstname = "?";

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5DL");
	col_clear(pinfo->cinfo, COL_INFO);

	addr = tvb_get_ntohs(tvb, 0);
	cr = addr & V5DL_CR;
	eal = (addr & V5DL_EAL) >> V5DL_EAL_SHIFT;
	eah = (addr & V5DL_EAH) >> V5DL_EAH_SHIFT;
	v5addr = (eah << 7) + eal;
	v5dl_header_len = 2;	/* addr */

	direction = pinfo->p2p_dir;
	if (pinfo->p2p_dir == P2P_DIR_RECV) {
	    is_response = cr ? FALSE : TRUE;
	    srcname = "Network";
	    dstname = "User";
	}
	else if (pinfo->p2p_dir == P2P_DIR_SENT) {
	    is_response = cr ? TRUE : FALSE;
	    srcname = "User";
Exemple #17
0
static void
dissect_http2_frame_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
        proto_item *ti;
        proto_tree *http2_tree;
        guint32 offset = 0;
    
        http2_frame_header frame;

        /* tvb_memeql makes certain there are enough bytes in the buffer.
         * returns -1 if there are not enough bytes or if there is not a
         * match.  Returns 0 on a match */
        if ( tvb_memeql( tvb, offset, kMagicHello, MAGIC_FRAME_LENGTH ) == 0 )
        {
                col_append_sep_str( pinfo->cinfo, COL_INFO, ", ", "Magic" );
                
                ti = proto_tree_add_item(tree, proto_http2, tvb, offset, MAGIC_FRAME_LENGTH, ENC_NA);
                proto_item_append_text( ti, ", Magic" );
                
                http2_tree = proto_item_add_subtree(ti, ett_http2);
                
                proto_tree_add_item(http2_tree, hf_http2_magic, tvb,
                                    offset, MAGIC_FRAME_LENGTH, ENC_BIG_ENDIAN);
                return;
        }


        frame.length   = tvb_get_ntohs( tvb, offset + 0 );
        frame.type     = tvb_get_guint8( tvb, offset + 2 );
        frame.flags    = tvb_get_guint8( tvb, offset + 3 );
        frame.streamid = tvb_get_ntohl( tvb, offset + 4 );

        col_append_sep_fstr( pinfo->cinfo, COL_INFO, ", ", "%s",
                             val_to_str( frame.type, frametypenames, "Unknown (0x%02X)" ) );

    
        /* create display subtree for the protocol */
        ti = proto_tree_add_item(tree, proto_http2, tvb, offset, FRAME_HEADER_LENGTH + frame.length, ENC_NA);

        proto_item_append_text( ti, ", %s", val_to_str( frame.type, frametypenames, "Unknown (0x%02X)" ) );
        proto_item_append_text( ti, ", Length: %d, Flags: %d, streamid: %d",
                                frame.length, frame.flags, frame.streamid );
    
        http2_tree = proto_item_add_subtree(ti, ett_http2);

        /* Add an item to the subtree, see section 1.6 of README.developer for more
         * information. */
        proto_tree_add_item(http2_tree, hf_http2_length, tvb,
                            offset + 0, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_type, tvb,
                            offset + 2, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_flags, tvb,
                            offset + 3, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_streamid, tvb,
                            offset + 4, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_payload, tvb,
                            offset + 8, frame.length, ENC_BIG_ENDIAN);

        offset += frame.length + FRAME_HEADER_LENGTH;

        return;
}
Exemple #18
0
static void dissect_turbocell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    proto_item *ti, *name_item;
    proto_tree *turbocell_tree = NULL, *network_tree;
    tvbuff_t   *next_tvb;
    int i=0;
    guint8 packet_type;
    guint8 * str_name;
    guint str_len;
    gint remaining_length;

    packet_type = tvb_get_guint8(tvb, 0);

    if (!(packet_type & 0x0F)){
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Beacon)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }  else if ( packet_type == TURBOCELL_TYPE_MANAGEMENT ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Management)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else if ( packet_type == TURBOCELL_TYPE_DATA ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Data)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Unknown)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }

    if (tree) {
        ti = proto_tree_add_item(tree, proto_turbocell, tvb, 0, 20, ENC_NA);

        turbocell_tree = proto_item_add_subtree(ti, ett_turbocell);

        proto_tree_add_item(turbocell_tree, hf_turbocell_type, tvb, 0, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_satmode, tvb, 1, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_nwid, tvb, 1, 1, ENC_BIG_ENDIAN);

        /* it seem when we have this magic number,that means an alternate header version */

        if (tvb_get_bits64(tvb, 64,48,ENC_BIG_ENDIAN) != G_GINT64_CONSTANT(0x000001fe23dc45ba)){
        proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x02, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x04, 6, ENC_NA);
        proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x0A, 3, ENC_BIG_ENDIAN);

        } else {
        proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x02, 3, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x05, 3, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x08, 6, ENC_NA);
        }

        proto_tree_add_item(turbocell_tree, hf_turbocell_unknown, tvb, 0x0E, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_ip, tvb, 0x10, 4, ENC_BIG_ENDIAN);

    }

        remaining_length=tvb_captured_length_remaining(tvb, 0x14);

        if (remaining_length > 6) {

            /* If the first character is a printable character that means we have a payload with network info */
            /* I couldn't find anything in the header that would definitvely indicate if payload is either data or network info */
            /* Since the frame size is limited this should work ok */

            if (tvb_get_guint8(tvb, 0x14)>=0x20){
                name_item = proto_tree_add_item(turbocell_tree, hf_turbocell_name, tvb, 0x14, 30, ENC_ASCII|ENC_NA);
                network_tree = proto_item_add_subtree(name_item, ett_network);

                str_name=tvb_get_stringz_enc(wmem_packet_scope(), tvb, 0x14, &str_len, ENC_ASCII);
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Network=\"%s\"",format_text(str_name, str_len-1));

                while(tvb_get_guint8(tvb, 0x34 + 8*i)==0x00 && (tvb_captured_length_remaining(tvb,0x34 + 8*i) > 6) && (i<32)) {
                    proto_tree_add_item(network_tree, hf_turbocell_station[i], tvb, 0x34+8*i, 6, ENC_NA);
                    i++;
                }

                /*Couldn't make sense of the apparently random data in the end*/

                next_tvb = tvb_new_subset_remaining(tvb, 0x34 + 8*i);
                call_dissector(data_handle, next_tvb, pinfo, tree);

            } else {

                tvbuff_t *volatile msdu_tvb = NULL;
                guint32 msdu_offset = 0x04;
                guint16 j = 1;
                guint16 msdu_length;

                proto_item *parent_item;
                proto_tree *mpdu_tree;
                proto_tree *subframe_tree;

                next_tvb = tvb_new_subset(tvb, 0x14, -1, tvb_get_ntohs(tvb, 0x14));
                parent_item = proto_tree_add_protocol_format(tree, proto_aggregate, next_tvb, 0,
                              tvb_reported_length_remaining(next_tvb, 0), "Turbocell Aggregate Frames");
                mpdu_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_parent_tree);
                proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_len, next_tvb, 0x00, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_unknown1, next_tvb, 0x02, 2, ENC_BIG_ENDIAN);

                remaining_length=tvb_captured_length_remaining(next_tvb, msdu_offset);

                do {
                    msdu_length = (tvb_get_letohs(next_tvb, msdu_offset) & 0x0FFF);
                    if (msdu_length==0) break;
                    parent_item = proto_tree_add_uint_format(mpdu_tree, hf_turbocell_aggregate_msdu_header_text,
                    next_tvb,msdu_offset, msdu_length + 0x02,j, "A-MSDU Subframe #%u", j);

                    subframe_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_subframe_tree);
                    j++;

                    proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_msdu_len, next_tvb, msdu_offset, 2, ENC_LITTLE_ENDIAN);
                    proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_unknown2, next_tvb, msdu_offset+1, 1, ENC_BIG_ENDIAN);

                    msdu_offset += 0x02;
                    remaining_length -= 0x02;
                    msdu_tvb = tvb_new_subset(next_tvb, msdu_offset, (msdu_length>remaining_length)?remaining_length:msdu_length, msdu_length);
                    call_dissector(eth_handle, msdu_tvb, pinfo, subframe_tree);
                    msdu_offset += msdu_length;
                    remaining_length -= msdu_length;
                } while (remaining_length > 6);

                if (remaining_length > 2) {
                    next_tvb = tvb_new_subset_remaining(next_tvb, msdu_offset);
                    call_dissector(data_handle, next_tvb, pinfo, tree);
                }
            }
        }
}
Exemple #19
0
static int
dissect_xtp_tspec(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
	guint32 len = tvb_length_remaining(tvb, offset);
	guint32 start = offset;
	proto_item *ti, *ti2;
	proto_tree *xtp_subtree;
	struct xtp_traffic_spec1 tspec[1];
	int error = 0;

	ti = proto_tree_add_text(tree, tvb, offset, len, "Traffic Specifier");
	xtp_subtree = proto_item_add_subtree(ti, ett_xtp_tspec);

	if (len < XTP_TRAFFIC_SPEC0_LEN) {
		proto_item_append_text(ti,
			", bogus length(%u, must be at least %u)",
			len, XTP_TRAFFIC_SPEC0_LEN);
		return 0;
	}

	/** parse common fields **/
	/* tlen(2) */
	tspec->tlen = tvb_get_ntohs(tvb, offset);
	offset += 2;
	/* service(1) */
	tspec->service = tvb_get_guint8(tvb, offset);
	offset++;
	/* tformat(1) */
	tspec->tformat = tvb_get_guint8(tvb, offset);

	/** display common fields */
	offset = start;
	/* tlen(2) */
	ti = proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_tlen,
			tvb, offset, 2, tspec->tlen);
	offset += 2;
	if (tspec->tlen > len) {
		proto_item_append_text(ti, ", bogus length(%u, must be at most %u)",
			tspec->tlen, len);
		error = 1;
	}
	/* service(1) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_service,
			tvb, offset, 1, tspec->service);
	offset++;
	/* tformat(1) */
	ti2 = proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_tformat,
			tvb, offset, 1, tspec->tformat);
	offset++;
	switch (tspec->tformat) {
	case 0:
		if (tspec->tlen != XTP_TRAFFIC_SPEC0_LEN) {
			proto_item_append_text(ti, ", bogus length(%u, must be %u)",
				tspec->tlen, XTP_TRAFFIC_SPEC0_LEN);
			error = 1;
		}
		break;
	case 1:
		if (tspec->tlen != XTP_TRAFFIC_SPEC1_LEN) {
			proto_item_append_text(ti, ", bogus length(%u, must be %u)",
				tspec->tlen, XTP_TRAFFIC_SPEC1_LEN);
			error = 1;
		}
		break;
	default:
		proto_item_append_text(ti2, ", Unsupported tformat(%u)",
				tspec->tformat);
		error = 1;
		break;
	}

	if (error)
		return (offset - start);

	/** parse and display each traffic fields **/
	switch (tspec->tformat) {
	case 0:
		/* traffic(4) */
		tspec->maxdata = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_traffic,
				tvb, offset, 4, tspec->maxdata);
		offset += 4;
		break;
	case 1:
		/* maxdata(4) */
		tspec->maxdata = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_maxdata,
				tvb, offset, 4, tspec->maxdata);
		offset += 4;
		/* inrate(4) */
		tspec->inrate = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_inrate,
				tvb, offset, 4, tspec->inrate);
		offset += 4;
		/* inburst(4) */
		tspec->inburst = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_inburst,
				tvb, offset, 4, tspec->inburst);
		offset += 4;
		/* outrate(4) */
		tspec->outrate = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_outrate,
				tvb, offset, 4, tspec->outrate);
		offset += 4;
		/* outburst(4) */
		tspec->outburst = tvb_get_ntohl(tvb, offset);
		proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_outburst,
				tvb, offset, 4, tspec->outburst);
		offset += 4;
		break;
	default:
		break;
	}

	return (offset - start);
}
Exemple #20
0
proto_tree *add_protocol_subtree(tlv_info_t *self, gint idx, proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length _U_, const char *label)
{
    /* Declare local variables */
    proto_tree *tlv_tree;
    proto_item *tlv_item;
    gint tlv_value_length, tlv_val_offset;
    guint8 size_of_tlv_length_field;
    guint8 tlv_type;
    guint32 tlv_value;
    const gchar *hex_fmt;

    /* Make sure we're dealing with a valid TLV here */
    if (get_tlv_type(self) < 0)
        return tree;

    /* Retrieve the necessary TLV information */
    tlv_val_offset = get_tlv_value_offset(self);
    tlv_value_length = get_tlv_length(self);
    size_of_tlv_length_field = get_tlv_size_of_length(self);
    tlv_type = get_tlv_type(self);

    /* display the TLV name and display the value in hex. Highlight type, length, and value. */
    tlv_item = proto_tree_add_protocol_format(tree, hfindex, tvb, start, tlv_value_length+tlv_val_offset, "%s (%u byte(s))", label, tlv_value_length);
    tlv_tree = proto_item_add_subtree(tlv_item, ett_tlv[tlv_type]);

    proto_tree_add_uint(tlv_tree, hf_tlv_type, tvb, start, 1, tlv_type);
    if (size_of_tlv_length_field > 0) /* It is */
    {
        /* display the length of the length field TLV */
        proto_tree_add_uint(tlv_tree, hf_tlv_length_size, tvb, start+1, 1, size_of_tlv_length_field);
        /* display the TLV length */
        proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+2, size_of_tlv_length_field, tlv_value_length);
    } else { /* It is not */
        /* display the TLV length */
        proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+1, 1, tlv_value_length);
    }

    /* display the TLV value and make it a subtree */
    switch (tlv_value_length)
    {
    case 1:
        tlv_value = tvb_get_guint8(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_1byte;
        break;
    case 2:
        tlv_value = tvb_get_ntohs(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_2byte;
        break;
    case 3:
        tlv_value = tvb_get_ntoh24(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_3byte;
        break;
    case 4:
        tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_4byte;
        break;
    default:
        tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_5byte;
        break;
    }
    /* Show "TLV value: " */
    tlv_item = proto_tree_add_text(tlv_tree, tvb, start+tlv_val_offset, tlv_value_length, hex_fmt, label, tlv_value);
    tlv_tree = proto_item_add_subtree(tlv_item, idx);

    /* Return a pointer to the value level */
    return tlv_tree;
}
Exemple #21
0
/* Code to actually dissect the packets */
static void
dissect_wtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int offset = 0;

	char pdut;
	guint count = 0;
	guint offset_wtls = 0;

/* Set up structures we will need to add the protocol subtree and manage it */
	proto_item *ti;
	proto_tree *wtls_tree;
	proto_tree *wtls_rec_tree;
	proto_tree *wtls_msg_type_tree;

	if (check_col(pinfo->cinfo, COL_PROTOCOL))
	{
		switch ( pinfo->match_uint )
		{
			case UDP_PORT_WTLS_WSP:
				col_set_str(pinfo->cinfo, COL_PROTOCOL, "WTLS+WSP" );
				break;
			case UDP_PORT_WTLS_WTP_WSP:
				col_set_str(pinfo->cinfo, COL_PROTOCOL, "WTLS+WTP+WSP" );
				break;
		}
	}

	/* Develop the string to put in the Info column */
	col_set_str(pinfo->cinfo, COL_INFO, "WTLS");

	/* In the interest of speed, if "tree" is NULL, don't do any work not
	necessary to generate protocol tree items. */

	if (tree) {
		ti = proto_tree_add_item(tree, proto_wtls, tvb, offset_wtls,
				 -1, ENC_NA);
		wtls_tree = proto_item_add_subtree(ti, ett_wtls);

		for (offset_wtls=0; offset_wtls < (tvb_reported_length(tvb)-1);) {
			pdut = tvb_get_guint8 (tvb, offset_wtls);

			offset = offset_wtls+1;

			if (pdut & WTLS_RECORD_TYPE_SEQUENCE) {
				offset+=2;
			}
			if (pdut & WTLS_RECORD_TYPE_LENGTH) {
				count = tvb_get_ntohs(tvb, offset);
				offset+=2;
				count += offset-offset_wtls;
			}
			else {
				count = tvb_length_remaining (tvb, offset_wtls);
			}
			ti = proto_tree_add_uint(wtls_tree, hf_wtls_record, tvb, offset_wtls,
				 count, pdut);
			wtls_rec_tree = proto_item_add_subtree(ti, ett_wtls_rec);

			offset = offset_wtls;

			proto_tree_add_item (wtls_rec_tree, hf_wtls_record_type,
					tvb,offset,1,ENC_BIG_ENDIAN);

			offset++;

			offset_wtls += count;

			if (pdut & WTLS_RECORD_TYPE_SEQUENCE) {
				proto_tree_add_item (wtls_rec_tree, hf_wtls_record_sequence,
						tvb,offset,2,ENC_BIG_ENDIAN);
				offset+=2;
			}
			if (pdut & WTLS_RECORD_TYPE_LENGTH) {
				count = tvb_get_ntohs(tvb, offset);
				proto_tree_add_item (wtls_rec_tree, hf_wtls_record_length,
						tvb,offset,2,ENC_BIG_ENDIAN);
				offset+=2;
			}
			else {
				count = tvb_length_remaining (tvb, offset);
			}

			if (pdut & WTLS_RECORD_TYPE_CIPHER_CUR) {
				proto_tree_add_item (wtls_rec_tree, hf_wtls_record_ciphered,
						tvb,offset,count,ENC_NA);
				continue;
			}

			switch (pdut & WTLS_RECORD_CONTENT_TYPE) {
				case WTLS_PLAIN_HANDSHAKE :
					dissect_wtls_handshake(wtls_rec_tree,tvb,offset,count);
					break;
				case WTLS_ALERT :
					ti = proto_tree_add_item(wtls_rec_tree, hf_wtls_alert, tvb, offset,
							 count, ENC_NA);
					wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type);
					proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_level,
							tvb,offset,1,ENC_BIG_ENDIAN);
					offset+=1;
					count = tvb_get_ntohs (tvb, offset);
					proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_description,
							tvb,offset,1,ENC_BIG_ENDIAN);
					offset+=1;
				default:
					offset+=count;
					break;
			}
		}
	}
}
Exemple #22
0
/* Code to actually dissect the packets */
static int
dissect_mbtcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Set up structures needed to add the protocol subtree and manage it */
	mbtcp_hdr	mh;
	proto_item	*mi, *mf;
	proto_tree	*mbtcp_tree, *modbus_tree, *group_tree;
	int		offset, group_offset, packet_type;
	guint		i;
	gint		packet_len, payload_start, payload_len;
	const char	*func_string = "";
	const char	*pkt_type_str = "";
	const char	*err_str = "";
	guint32		byte_cnt, group_byte_cnt, group_word_cnt;
	guint32		packet_num;	/* num to uniquely identify different mbtcp
					 * packets in one packet */
	guint8		exception_code;
	gboolean	exception_returned;
	guint8		fc;

	mh.transaction_id = tvb_get_ntohs(tvb, 0);
	mh.protocol_id = tvb_get_ntohs(tvb, 2);
	mh.len = tvb_get_ntohs(tvb, 4);
	mh.mdbs_hdr.unit_id = tvb_get_guint8(tvb, 6);
	mh.mdbs_hdr.function_code = tvb_get_guint8(tvb, 7);


	/* check that it actually looks like Modbus/TCP */
	/* protocol id == 0 */
	if( mh.protocol_id != 0 ){
		return 0;
	}
	/* length is at least 2 (unit_id + function_code) */
	if( mh.len < 2 ){
		return 0;
	}
	/* function code is in the set 1-24, 40, 125-127.
	 * Note that function code is only 7 bits.
	 */
	fc=mh.mdbs_hdr.function_code&0x7f;
	if(!match_strval(fc, function_code_vals))
		return 0;


	/* Make entries in Protocol column on summary display */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP");

	col_clear(pinfo->cinfo, COL_INFO);


	/* Make entries in Info column on summary display */
	offset = 0;

	if ( mh.mdbs_hdr.function_code & 0x80 ) {
		exception_code = tvb_get_guint8(tvb, offset + sizeof(mbtcp_hdr));
		mh.mdbs_hdr.function_code ^= 0x80;
		exception_returned = TRUE;
	}
	else {
		exception_code = 0;
		exception_returned = FALSE;
	}
	func_string = val_to_str(mh.mdbs_hdr.function_code, function_code_vals,
	    "Unknown function (%u)");
	if (check_col(pinfo->cinfo, COL_INFO))
	{
		packet_type = classify_packet(pinfo);
		switch ( packet_type ) {
			case QUERY_PACKET : 		pkt_type_str="query";
												break;
			case RESPONSE_PACKET : 	pkt_type_str="response";
												break;
			case CANNOT_CLASSIFY :		err_str="Unable to classify as query or response.";
										pkt_type_str="unknown";
												break;
			default :
												break;
		}
		if ( exception_returned )
			err_str="Exception returned ";
		col_add_fstr(pinfo->cinfo, COL_INFO,
				"%8s [%2u pkt(s)]: trans: %5u; unit: %3u, func: %3u: %s. %s",
				pkt_type_str, 1, mh.transaction_id, (unsigned char) mh.mdbs_hdr.unit_id,
				(unsigned char) mh.mdbs_hdr.function_code, func_string, err_str);
	}

	/* build up protocol tree and iterate over multiple packets */
	packet_num = 0;
	while (1) {
		packet_type = classify_packet(pinfo);
		packet_len = sizeof(mbtcp_hdr) - sizeof(modbus_hdr) + mh.len;

		/* if a tree exists, perform operations to add fields to it */
		if (tree) {
			mi = proto_tree_add_protocol_format(tree, proto_mbtcp, tvb, offset,
					packet_len, "Modbus/TCP");
			mbtcp_tree = proto_item_add_subtree(mi, ett_mbtcp);

			/* Add items to protocol tree specific to Modbus/TCP */
			proto_tree_add_uint(mbtcp_tree, hf_mbtcp_transid, tvb, offset, 2,
					mh.transaction_id);
			proto_tree_add_uint(mbtcp_tree, hf_mbtcp_protid, tvb, offset + 2, 2,
					mh.protocol_id);
			proto_tree_add_uint(mbtcp_tree, hf_mbtcp_len, tvb, offset + 4, 2,
					mh.len);
					
			proto_tree_add_uint(mbtcp_tree, hf_mbtcp_unitid, tvb, offset + 6, 1,
					mh.mdbs_hdr.unit_id);


			/* Add items to protocol tree specific to Modbus generic */
			mf = proto_tree_add_text(mbtcp_tree, tvb, offset + 7, mh.len - 1,
					"Modbus");
	  		modbus_tree = proto_item_add_subtree(mf, ett_modbus_hdr);
			mi = proto_tree_add_uint(modbus_tree, hf_mbtcp_functioncode, tvb, offset + 7, 1,
					mh.mdbs_hdr.function_code);
					
			/** detail payload as a function of exception/function code */
			func_string = val_to_str(mh.mdbs_hdr.function_code,
			    function_code_vals, "Unknown function");
			payload_start = offset + 8;
			payload_len = mh.len - sizeof(modbus_hdr);
			if (exception_returned) {
				proto_item_set_text(mi, "function %u:  %s.  Exception: %s",
						mh.mdbs_hdr.function_code,
						func_string,
						val_to_str(exception_code,
						    exception_code_vals,
						    "Unknown exception code (%u)"));
				proto_tree_add_uint(modbus_tree, hf_modbus_exceptioncode, tvb, payload_start, 1,
						exception_code);
			}
			else {
				proto_item_set_text(mi, "function %u:  %s", mh.mdbs_hdr.function_code,
						func_string);
				switch (mh.mdbs_hdr.function_code) {
					
					case READ_COILS:			
					case READ_INPUT_DISCRETES:	
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE);
						}
						else if (packet_type == RESPONSE_PACKET) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data");
						}
						break;
						
					case READ_MULT_REGS:		
					case READ_INPUT_REGS:		
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE);
						}
						else if (packet_type == RESPONSE_PACKET) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data");
						}
						break;
						
					case WRITE_COIL:			
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 1, "Data");
							proto_tree_add_text(modbus_tree, tvb, payload_start + 3, 1, "Padding");
						}
						else if (packet_type == RESPONSE_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 1, "Data");
							proto_tree_add_text(modbus_tree, tvb, payload_start + 3, 1, "Padding");
						}
						break;
						
					case WRITE_SINGLE_REG:		
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 2, "Data");
						}
						else if (packet_type == RESPONSE_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 2, "Data");
						}
						break;
						
					case READ_EXCEPT_STAT:		
						if (packet_type == RESPONSE_PACKET)
							proto_tree_add_text(modbus_tree, tvb, payload_start, 1, "Data");
						break;
						
					case FORCE_MULT_COILS:		
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE);
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 4);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 4, 1,
									byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 5, byte_cnt, "Data");
						}
						else if (packet_type == RESPONSE_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE);
						}
						break;
						
					case WRITE_MULT_REGS:		
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE);
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 4);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 4, 1,
									byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 5, byte_cnt, "Data");
						}
						else if (packet_type == RESPONSE_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE);
						}
						break;
						
					case READ_GENL_REF:			
						if (packet_type == QUERY_PACKET) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1,
									byte_cnt);
									
							/* add subtrees to describe each group of packet */
							group_offset = payload_start + 1;
							for (i = 0; i < byte_cnt / 7; i++) {
								mi = proto_tree_add_text( modbus_tree, tvb, group_offset, 7,
										"Group %u", i);
						  		group_tree = proto_item_add_subtree(mi, ett_group_hdr);
								proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset, 1, FALSE);
								proto_tree_add_item(group_tree, hf_modbus_lreference, tvb, group_offset + 1, 4, FALSE);
								proto_tree_add_item(group_tree, hf_modbus_wordcnt, tvb, group_offset + 5, 2, FALSE);
								group_offset += 7;
							}
						}
						else if (packet_type == RESPONSE_PACKET) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1,
									byte_cnt);
									
							/* add subtrees to describe each group of packet */
							group_offset = payload_start + 1;
							i = 0;
							while (byte_cnt > 0) {
								group_byte_cnt = (guint32)tvb_get_guint8(tvb, group_offset);
								mi = proto_tree_add_text( modbus_tree, tvb, group_offset, group_byte_cnt + 1,
										"Group %u", i);
						  		group_tree = proto_item_add_subtree(mi, ett_group_hdr);
								proto_tree_add_uint(group_tree, hf_modbus_bytecnt, tvb, group_offset, 1,
										group_byte_cnt);
								proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset + 1, 1, FALSE);
								proto_tree_add_text(group_tree, tvb, group_offset + 2, group_byte_cnt - 1, "Data");
								group_offset += (group_byte_cnt + 1);
								byte_cnt -= (group_byte_cnt + 1);
								i++;
							}
						}
						break;
						
					case WRITE_GENL_REF:		
						if ((packet_type == QUERY_PACKET) || (packet_type == RESPONSE_PACKET)) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1,
									byte_cnt);
									
							/* add subtrees to describe each group of packet */
							group_offset = payload_start + 1;
							i = 0;
							while (byte_cnt > 0) {
								group_word_cnt = tvb_get_ntohs(tvb, group_offset + 5);
								group_byte_cnt = (2 * group_word_cnt) + 7;
								mi = proto_tree_add_text( modbus_tree, tvb, group_offset, 
										group_byte_cnt, "Group %u", i);
						  		group_tree = proto_item_add_subtree(mi, ett_group_hdr);
								proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset, 1, FALSE);
								proto_tree_add_item(group_tree, hf_modbus_lreference, tvb, group_offset + 1, 4, FALSE);
								proto_tree_add_uint(group_tree, hf_modbus_wordcnt, tvb, group_offset + 5, 2, 
										group_word_cnt);
								proto_tree_add_text(group_tree, tvb, group_offset + 7, group_byte_cnt - 7, "Data");
								group_offset += group_byte_cnt;
								byte_cnt -= group_byte_cnt;
								i++;
							}
						}
						break;
						
					case MASK_WRITE_REG:		
						if ((packet_type == QUERY_PACKET) || (packet_type == RESPONSE_PACKET)) {
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_andmask, tvb, payload_start + 2, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_ormask, tvb, payload_start + 4, 2, FALSE);
						}
						break;
						
					case READ_WRITE_REG:		
						if (packet_type == QUERY_PACKET) {
							proto_tree_add_item(modbus_tree, hf_modbus_readref, tvb, payload_start, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_readwordcnt, tvb, payload_start + 2, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_writeref, tvb, payload_start + 4, 2, FALSE);
							proto_tree_add_item(modbus_tree, hf_modbus_writewordcnt, tvb, payload_start + 6, 2, FALSE);
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 8);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 8, 1,
									byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 9, byte_cnt, "Data");
						}
						else if (packet_type == RESPONSE_PACKET) {
							byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1,
									byte_cnt);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data");
						}
						break;
						
					case READ_FIFO_QUEUE:		
						if (packet_type == QUERY_PACKET)
							proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE);
						else if (packet_type == RESPONSE_PACKET) {
							byte_cnt = (guint32)tvb_get_ntohs(tvb, payload_start);
							proto_tree_add_uint(modbus_tree, hf_modbus_lbytecnt, tvb, payload_start, 2,
									byte_cnt);
							proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE);
							proto_tree_add_text(modbus_tree, tvb, payload_start + 4, byte_cnt - 2, "Data");
						}
						break;
						
					case DIAGNOSTICS:			
					case PROGRAM_484:			
					case POLL_484:				
					case GET_COMM_EVENT_CTRS:	
					case GET_COMM_EVENT_LOG:	
					case PROGRAM_584_984:		
					case POLL_584_984:			
					case REPORT_SLAVE_ID:		
					case PROGRAM_884_U84:		
					case RESET_COMM_LINK:		
					case PROGRAM_CONCEPT:		
					case FIRMWARE_REPLACE:		
					case PROGRAM_584_984_2:		
					case REPORT_LOCAL_ADDR_MB:	
						/* these function codes are not part of the Modbus/TCP specification */
					default:					
						if (payload_len > 0)
							proto_tree_add_text(modbus_tree, tvb, payload_start, payload_len, "Data");
						break;
				}
			}
		}
		
		/* move onto next packet (if there) */
		offset += packet_len;
		packet_num++;
		if (tvb_reported_length_remaining(tvb, offset) > 0) {
			
			/* load header structure for next packet */
			mh.transaction_id = tvb_get_ntohs(tvb, offset+0);
			mh.protocol_id = tvb_get_ntohs(tvb, offset+2);
			mh.len = tvb_get_ntohs(tvb, offset+4);
			mh.mdbs_hdr.unit_id = tvb_get_guint8(tvb, offset+6);
			mh.mdbs_hdr.function_code = tvb_get_guint8(tvb, offset+7);

	
			if ( mh.mdbs_hdr.function_code & 0x80 ) {
				exception_code = tvb_get_guint8(tvb, offset + sizeof(mbtcp_hdr));
				mh.mdbs_hdr.function_code ^= 0x80;
				exception_returned = TRUE;
			} else
				exception_returned = FALSE;
		}
		else
			break;
	}

	return tvb_length(tvb);
}
Exemple #23
0
	{ CONFIRM_STATUS_SERVER_ERROR, "Server couldn't start confirmation process" },
	{ 0, NULL }
};

/* Initialize the protocol and registered fields */
static int proto_aim_admin = -1;
static int hf_admin_acctinfo_code = -1;
static int hf_admin_acctinfo_permissions = -1;
static int hf_admin_confirm_status = -1;

/* Initialize the subtree pointers */
static gint ett_aim_admin          = -1;

static int dissect_aim_admin_accnt_info_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *admin_tree) 
{
	proto_tree_add_item(admin_tree, hf_admin_acctinfo_code, tvb, 0, 2, tvb_get_ntohs(tvb, 0)); 
	proto_tree_add_text(admin_tree, tvb, 2, 2, "Unknown");
	return 4;
}

static int dissect_aim_admin_accnt_info_repl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *admin_tree) 
{
	int offset = 0;
	proto_tree_add_uint(admin_tree, hf_admin_acctinfo_permissions, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); offset+=2;
	return dissect_aim_tlv_list(tvb, pinfo, offset, admin_tree, client_tlvs);
}

static int dissect_aim_admin_info_change_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *admin_tree) 
{
	return dissect_aim_tlv_sequence(tvb, pinfo, 0, admin_tree, client_tlvs);
}
Exemple #24
0
    ti = proto_tree_add_item(tree, proto_hsr, tvb, 0, HSR_TOTAL_LENGTH, ENC_NA);

    hsr_tree = proto_item_add_subtree(ti, ett_hsr_frame);

    proto_tree_add_item(hsr_tree, hf_hsr_path,
                        tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN);

    proto_tree_add_item(hsr_tree, hf_hsr_netid,
                        tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN);

    proto_tree_add_item(hsr_tree, hf_hsr_laneid,
                        tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN);


    lsdu_size = tvb_get_ntohs(tvb, HSR_PATH_OFFSET) & 0x0fff;
    lsdu_size_correct = tvb_reported_length_remaining(tvb, 0);
    if (lsdu_size == lsdu_size_correct) {
        proto_tree_add_uint_format_value(hsr_tree, hf_hsr_lsdu_size,
                                   tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH, lsdu_size,
                                   "%d [correct]", lsdu_size);
    } else {
        proto_tree_add_uint_format_value(hsr_tree, hf_hsr_lsdu_size,
                                   tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH, lsdu_size,
                                   "%d [WRONG, should be %d]", lsdu_size, lsdu_size_correct);
    }

    proto_tree_add_item(hsr_tree, hf_hsr_sequence_nr,
                        tvb, HSR_SEQUENZNR_OFFSET,HSR_SEQUENZNR_LENGTH, ENC_BIG_ENDIAN);

    proto_tree_add_item(hsr_tree, hf_type,
static gint
dissect_userdata(proto_item *ti_arg, gint ett_arg, tvbuff_t *tvb, gint arg_offset)
{
        gint        offset = arg_offset;
        guint8      flen, lenbytes;
        guint8      year, month, day, hour, min, sec;
        guint16     msec;
        proto_tree *tree;
        proto_item *ti;

        tree = proto_item_add_subtree(ti_arg, ett_arg);

        /* length of User Data, should be 1 byte field ... */
        flen     = tvb_get_guint8(tvb, offset);
        lenbytes = 1;

        /* ... but sometimes it seems to be 2 bytes; try to be clever */
        if (flen == 0) {
                flen = tvb_get_guint8(tvb, offset+1);
                lenbytes = 2;
        }
        if (flen == 0 || flen > 79) /* invalid */
                return offset;

        ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN);
        offset += lenbytes;
        if (lenbytes == 2) {
                proto_item_append_text(ti, " (2 bytes, should be 1 byte)");
        }

        if (tvb_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        if (tvb_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;


        if (tvb_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        /* show the rest */
        /*        tree2 = proto_tree_add_text(tree, tvb, offset, -1, "User Data"); */

        if (tvb_length_remaining(tvb, offset) <= 0)
                return offset;
        ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_item_append_text(ti, " <-- '0' = no restart etc.");
        offset +=1;

        if (tvb_length_remaining(tvb, offset+8) <= 0)
                return offset;
        year  = tvb_get_guint8(tvb, offset);
        month = tvb_get_guint8(tvb, offset+1);
        day   = tvb_get_guint8(tvb, offset+2);
        hour  = tvb_get_guint8(tvb, offset+3);
        min   = tvb_get_guint8(tvb, offset+4);
        sec   = tvb_get_guint8(tvb, offset+5);
        msec  = tvb_get_ntohs(tvb, offset+6);

        proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8,
                                   "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d",
                                   year+1900, month, day, hour, min, sec, msec);

        offset += 12;
        if (tvb_length_remaining(tvb, offset+12) > 0) {
                proto_item_append_text(ti, " Security info: ");
        }
        /* security info field, if present */
        while (tvb_length_remaining(tvb, offset) > 0) {
                proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o",
                                       tvb_get_guint8(tvb, offset));
                offset++;
        }

        return offset;
}
Exemple #26
0
static int
dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo)
{
    proto_tree *hdrs_tree   = NULL;
    proto_tree *hdr_tree    = NULL;
    proto_item *hdr         = NULL;
    proto_item *handle_item;
    gint        item_length = -1;
    guint8      hdr_id, i;

    if (tvb_length_remaining(tvb, offset) > 0) {
        proto_item *hdrs;
        hdrs      = proto_tree_add_text(tree, tvb, offset, item_length, "Headers");
        hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs);
    }
    else {
        return offset;
    }

    while (tvb_length_remaining(tvb, offset) > 0) {
        hdr_id = tvb_get_guint8(tvb, offset);

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x40:  /* byte sequence */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x80:  /* 1 byte */
                item_length = 2;
                break;
            case 0xc0:  /* 4 bytes */
                item_length = 5;
                break;
        }

        hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s",
                                  val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown"));
        hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr);

        proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN);

        offset++;

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                {
                    proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    if ((item_length - 3) > 0) {
                        char *str;

                        display_unicode_string(tvb, hdr_tree, offset, &str);
                        proto_item_append_text(hdr_tree, " (\"%s\")", str);
                        col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str);
                    }
                    else {
                        col_append_str(pinfo->cinfo, COL_INFO, " \"\"");
                    }

                    offset += item_length - 3;
                }
                break;
            case 0x40:  /* byte sequence */
                proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA);

                if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */
                    for(i=0; target_vals[i].strptr != NULL; i++) {
                        if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) {
                            proto_item_append_text(handle_item, ": %s", target_vals[i].strptr);
                            proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr);
                            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr);
                        }
                    }
                }

                if (!tvb_strneql(tvb, offset, "<?xml", 5))
                {
                    tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset);

                    call_dissector(xml_handle, next_tvb, pinfo, tree);
                }
                else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3))
                {
                    proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                    col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                }

                offset += item_length - 3;
                break;
            case 0x80:  /* 1 byte */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                break;
            case 0xc0:  /* 4 bytes */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            default:
                break;
        }
    }

    return offset;
}
Exemple #27
0
/* This routine attempts to locate the position of the next header in the
 * provided segment
 */
static guint
get_next_fcip_header_offset (tvbuff_t *tvb, packet_info *pinfo, gint offset)
{
    gint bytes_remaining = tvb_length_remaining (tvb, offset);
    gint frame_len;
    guint16 flen, flen1;
    fcip_eof_t eof, eofc;

    /*
     * As per the FCIP standard, the following tests must PASS:
     * 1)  Frame Length field validation -- 15 < Frame Length < 545;
     * 2)  Comparison of Frame Length field to its ones complement; and
     * 3)  A valid EOF is found in the word preceding the start of the next
     *     FCIP header as indicated by the Frame Length field, to be tested
     *     as follows:
     *     1)  Bits 24-31 and 16-23 contain identical legal EOF values (the
     *         list of legal EOF values is in the FC Frame Encapsulation
     *         [21]); and
     *     2)  Bits 8-15 and 0-7 contain the ones complement of the EOF
     *         value found in bits 24-31.
     *
     * As per the FCIP standard, in addition, at least 3 of the following set
     * of tests must be performed to identify that we've located the start of
     * an FCIP frame.
     * a)  Protocol# ones complement field (1 test);
     * b)  Version ones complement field (1 test);
     * c)  Replication of encapsulation word 0 in word 1 (1 test);
     * d)  Reserved field and its ones complement (2 tests);
     * e)  Flags field and its ones complement (2 tests);
     *    f)  CRC field is equal to zero (1 test); (DONT DO THIS TEST!)
     * g)  SOF fields and ones complement fields (4 tests);
     * h)  Format and values of FC header (1 test);
     * i)  CRC of FC Frame (2 tests);
     * j)  FC Frame Encapsulation header information in the next FCIP Frame
     *     (1 test).
     *
     * At least 3 of the 16 tests listed above SHALL be performed. Failure
     * of any of the above tests actually performed SHALL indicate an
     * encapsulation error and the FC Frame SHALL NOT be forwarded on to
     * the FC Entity.
     */

NXT_BYTE: while (bytes_remaining) {
        if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
            if(fcip_desegment && pinfo->can_desegment) {
                /*
                 * This frame doesn't have all of the data for
                 * the message header, but we can do reassembly on it.
                 *
                 * Tell the TCP dissector where the data for this
                 * message starts in the data it handed us, and that we need
                 * "some more data."  Don't tell it exactly how many bytes
		 * we need because if/when we ask for even more (after the
		 * header) that will break reassembly.
                 */
                pinfo->desegment_offset = offset;
                pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
                return -2;
            }
        }

        /* I check that we have a valid header before checking for the frame
         * length and the other initial tests.
         */

        /*
         * Tests a, b and c
         */
        if (tvb_memeql(tvb, offset, fcip_header_8_bytes, 8) != 0) {
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        flen = (tvb_get_ntohs (tvb, offset+12)) & 0x03FF;
        frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;

        if ((flen < 15) || (flen > 545)) {
            /* Frame length check failed. Skip byte and try again */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        flen1 = (tvb_get_ntohs (tvb, offset+14)) & 0x03FF;

        if ((flen & 0x03FF) != ((~flen1)&0x03FF)) {
            /* frame_len and its one's complement are not the same */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        /* Valid EOF check */
        if (tvb_bytes_exist (tvb, offset+(frame_len-1)*4, 4)) {
            eof = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4);
            eofc = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4+2);

            if ((eof != FCIP_EOFn) && (eof != FCIP_EOFt) && (eof != FCIP_EOFrt)
                && (eof != FCIP_EOFdt) && (eof != FCIP_EOFni) &&
                (eof != FCIP_EOFdti) && (eof != FCIP_EOFrti) &&
                (eof != FCIP_EOFa)) {
                offset++;
                bytes_remaining--;
                goto NXT_BYTE;
            }

            if ((eof != ~eofc) ||
                (eof != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+1)) ||
                (eofc != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+3))) {
                offset++;
                bytes_remaining--;
                goto NXT_BYTE;
            }
        }

        /* Test d */
        if ((tvb_get_guint8 (tvb, offset+9) != 0) ||
            (tvb_get_guint8 (tvb, offset+11) != 0xFF)) {
            /* Failed */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        /* Test e */


        /* Test f
	 * We dont test this since some implementations actually provide
	 * a CRC here.
	 */

        if (bytes_remaining >= (frame_len)) {
            if (tvb_bytes_exist (tvb, offset+frame_len, 8)) {
                /* The start of the next header matches what we wish to see */
                if (tvb_memeql (tvb, offset+frame_len, fcip_header_8_bytes,
                                8) == 0) {
                    return (offset);
                }
                else {
                    offset++;
                    bytes_remaining--;
                    goto NXT_BYTE;
                }
            }
            else {
                return (offset);
            }
        }
        else {
            if(fcip_desegment && pinfo->can_desegment) {
                /*
                 * This frame doesn't have all of the data for
                 * this message, but we can do reassembly on it.
                 *
                 * Tell the TCP dissector where the data for this
                 * message starts in the data it handed us, and
                 * how many more bytes we need, and return.
                 */
                pinfo->desegment_offset = offset;
                pinfo->desegment_len = frame_len - bytes_remaining;
                return -2;
            }
            else {
                return (offset);
            }
        }
    }

    return (-1);                /* Unable to find FCIP header */
}
Exemple #28
0
static void
dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item    *ti;
    proto_tree    *st;
    fragment_data *frag_msg       = NULL;
    gboolean       save_fragmented, complete;
    tvbuff_t*      new_tvb        = NULL;
    tvbuff_t*      next_tvb       = NULL;
    guint32        no_of_segments = 0;
    int            offset         = 0;

    save_fragmented = pinfo->fragmented;

    frag_msg = NULL;
    complete = FALSE;

    if (fragment_get(pinfo, pinfo->p2p_dir, fragment_table)) {
        /* not the first fragment */
        frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

        new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

        pinfo->fragmented = TRUE;
    }
    else    {
        if (tvb_length(tvb) < tvb_get_ntohs(tvb, offset+1)) {
            /* first fragment in a sequence */
            no_of_segments = tvb_get_ntohs(tvb, offset+1)/tvb_length(tvb);
            if (tvb_get_ntohs(tvb, offset+1) > (no_of_segments * tvb_length(tvb)))
                no_of_segments++;

            frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

            fragment_set_tot_len(pinfo, pinfo->p2p_dir, fragment_table, no_of_segments-1);

            new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

            pinfo->fragmented = TRUE;
            }
        else if (tvb_length(tvb) == tvb_get_ntohs(tvb, offset+1)) {
            /* non-fragmented */
            complete = TRUE;
            pinfo->fragmented = FALSE;
        }
    }

    if (new_tvb) { /* take it all */
        next_tvb = new_tvb;
        complete = TRUE;
    }
    else { /* make a new subset */
        next_tvb = tvb_new_subset_remaining(tvb, offset);
    }

    if (complete) {
        guint8 code, final_flag;

        /* fully dissectable packet ready */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBEX");

        ti = proto_tree_add_item(tree, proto_btobex, next_tvb, 0, -1, ENC_NA);
        st = proto_item_add_subtree(ti, ett_btobex);

        /* op/response code */
        code = tvb_get_guint8(next_tvb, offset) & BTOBEX_CODE_VALS_MASK;
        final_flag = tvb_get_guint8(next_tvb, offset) & 0x80;

        switch (pinfo->p2p_dir)
        {
        case P2P_DIR_SENT:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Sent ");
            break;

        case P2P_DIR_RECV:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;

        case P2P_DIR_UNKNOWN:
            break;

        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
        }

        col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
                        val_to_str_ext_const(code, &code_vals_ext, "Unknown"));

        if ((code < BTOBEX_CODE_VALS_CONTINUE) || (code == BTOBEX_CODE_VALS_ABORT)) {
            proto_tree_add_item(st, hf_opcode, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            if (pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) {
                last_opcode[pinfo->p2p_dir] = code;
            }
            }
        else    {
            proto_tree_add_item(st, hf_response_code, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            }
        proto_tree_add_item(st, hf_final_flag, next_tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        /* length */
        proto_tree_add_item(st, hf_length, next_tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        switch(code)
        {
        case BTOBEX_CODE_VALS_CONNECT:
            proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            break;

        case BTOBEX_CODE_VALS_PUT:
        case BTOBEX_CODE_VALS_GET:
            col_append_fstr(pinfo->cinfo, COL_INFO, " %s",  (final_flag == 0x80) ? "final" : "continue");
            break;

        case BTOBEX_CODE_VALS_SET_PATH:
            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_0, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_1, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_constants, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;
            break;

        case BTOBEX_CODE_VALS_DISCONNECT:
        case BTOBEX_CODE_VALS_ABORT:
            break;

        default:
            {
                guint8 response_opcode = last_opcode[(pinfo->p2p_dir + 1) & 0x01];

                if (response_opcode == BTOBEX_CODE_VALS_CONNECT) {
                    proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;
                }
            }
            break;
        }

        dissect_headers(st, next_tvb, offset, pinfo);
    }
    else
    {
        /* packet fragment */
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s Obex fragment",
                     (pinfo->p2p_dir==P2P_DIR_SENT) ? "Sent" : "Rcvd");

        call_dissector(data_handle, next_tvb, pinfo, tree);
    }

    pinfo->fragmented = save_fragmented;
}
Exemple #29
0
	{ 0x01,	"CDCP" },
	{ 0x02,	"VDP" },
	{ 0, NULL }
};

/* Dissect Unknown TLV */
static gint32
dissect_ecp_unknown_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset)
{
	guint16 tempLen;
	guint16 tempShort;

	proto_tree *ecp_unknown_tlv_tree;

	/* Get tlv type and length */
	tempShort = tvb_get_ntohs(tvb, offset);

	/* Get tlv length */
	tempLen = TLV_INFO_LEN(tempShort);

	ecp_unknown_tlv_tree = proto_tree_add_subtree(tree, tvb, offset, (tempLen + 2), ett_ecp, NULL, "Unknown TLV");

	proto_tree_add_item(ecp_unknown_tlv_tree, hf_ecp_subtype, tvb, offset, 2, ENC_BIG_ENDIAN);

	return -1;
}

/* Dissect mac/vid pairs in VDP TLVs */
static gint32
dissect_vdp_fi_macvid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset)
{
Exemple #30
0
static gboolean
dissect_parameter(tvbuff_t *tvb, int offset, proto_tree *tree,
    proto_tree *param_tree, packet_info *pinfo, guint8 param_type,
    guint16 param_len, struct SESSION_DATA_STRUCTURE *session)
{
	gboolean has_user_information = TRUE;
	guint16       flags;
	proto_item   *tf;
	proto_tree   *flags_tree;
	asn1_ctx_t asn1_ctx;
	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

	switch (param_type)
	{
	case Called_SS_user_Reference:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_called_ss_user_reference,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Calling_SS_user_Reference:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_calling_ss_user_reference,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Common_Reference:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_common_reference,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Additional_Reference_Information:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_additional_reference_information,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Token_Item:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		if (tree)
		{
			flags = tvb_get_guint8(tvb, offset);
			tf = proto_tree_add_uint(param_tree,
			    hf_token_item_options_flags, tvb, offset, 1,
			    flags);
			flags_tree = proto_item_add_subtree(tf,
			    ett_token_item_flags);
			proto_tree_add_boolean(flags_tree, hf_release_token,
			    tvb, offset, 1, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_major_activity_token, tvb, offset, 1, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_synchronize_minor_token, tvb, offset, 1, flags);
			proto_tree_add_boolean(flags_tree, hf_data_token, tvb,
			    offset, 1, flags);
		}
		break;

	case Transport_Disconnect:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		if (tree)
		{
			guint8       flags8;

			flags8 = tvb_get_guint8(tvb, offset);
			if(flags8 & transport_connection_is_released )
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "transport connection is released");
			}
			else
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "transport connection is kept");
			}

			if(flags8 & user_abort )
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "user abort");
				session->abort_type = SESSION_USER_ABORT;
			}
			else
			{
				session->abort_type = SESSION_PROVIDER_ABORT;
			}

			if(flags8 & protocol_error )
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "protocol error");
			}

			if(flags8 & no_reason )
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "no reason");
			}

			if(flags8 & implementation_restriction )
			{
				proto_tree_add_text(param_tree, tvb, offset, 1,
				    "implementation restriction");
			}
		}
		break;

	case Protocol_Options:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		if (tree)
		{
			flags = tvb_get_guint8(tvb, offset);
			tf = proto_tree_add_uint(param_tree,
			    hf_connect_protocol_options_flags, tvb, offset, 1,
			    flags);
			flags_tree = proto_item_add_subtree(tf, 
			    ett_connect_protocol_options_flags);
			proto_tree_add_boolean(flags_tree, 
			    hf_able_to_receive_extended_concatenated_SPDU,
			    tvb, offset, 1, flags);
		}
		break;

	case Session_Requirement:
		if (param_len != 2)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 2",
			    param_len);
			break;
		}
		if (tree)
		{
			flags = tvb_get_ntohs(tvb, offset);
			tf = proto_tree_add_uint(param_tree,
			    hf_session_user_req_flags, tvb, offset, 2,
			    flags);
			flags_tree = proto_item_add_subtree(tf,
			    ett_ses_req_options_flags);
			proto_tree_add_boolean(flags_tree,
			    hf_session_exception_report, tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_data_separation_function_unit, tvb, offset, 2,
			    flags);
			proto_tree_add_boolean(flags_tree,
			    hf_symmetric_synchronize_function_unit, 
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_typed_data_function_unit, tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_exception_function_unit, tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_capability_function_unit, tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_negotiated_release_function_unit, 
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_activity_management_function_unit, 
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_resynchronize_function_unit, tvb, offset, 2,
			    flags);
			proto_tree_add_boolean(flags_tree,
			    hf_major_resynchronize_function_unit, 
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_minor_resynchronize_function_unit, 
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree, 
			    hf_expedited_data_resynchronize_function_unit,
			    tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_duplex_function_unit, tvb, offset, 2, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_half_duplex_function_unit,
			    tvb, offset, 2, flags);
		}
		break;

	case TSDU_Maximum_Size:
		if (param_len != 4)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 4",
			    param_len);
			break;
		}
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_proposed_tsdu_maximum_size_i2r,
			    tvb, offset, 2, FALSE);
			proto_tree_add_item(param_tree,
			    hf_proposed_tsdu_maximum_size_r2i,
			    tvb, offset+2, 2, FALSE);
		}
		break;

	case Version_Number:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		if (tree)
		{
			flags = tvb_get_guint8(tvb, offset);
			tf = proto_tree_add_uint(param_tree,
			    hf_version_number_options_flags, tvb, offset, 1,
			    flags);
			flags_tree = proto_item_add_subtree(tf,
			    ett_protocol_version_flags);
			proto_tree_add_boolean(flags_tree,
			    hf_protocol_version_2, tvb, offset, 1, flags);
			proto_tree_add_boolean(flags_tree,
			    hf_protocol_version_1, tvb, offset, 1, flags);
		}
		break;

	case Initial_Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_initial_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case EnclosureItem:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		flags = tvb_get_guint8(tvb, offset);
		if (tree)
		{
			tf = proto_tree_add_uint(param_tree,
			    hf_enclosure_item_options_flags, tvb, offset, 1,
			    flags);
			flags_tree = proto_item_add_subtree(tf,
			    ett_enclosure_item_flags);
			proto_tree_add_boolean(flags_tree, hf_end_of_SSDU,
			    tvb, offset, 1, flags);
			proto_tree_add_boolean(flags_tree, hf_beginning_of_SSDU,
			    tvb, offset, 1, flags);
		}
		if (flags & END_SPDU) {
			/*
			 * In Data Transfer and Typed Data SPDUs, (X.225: 8.3.{11,13}.4)
			 * "The User Information Field shall be present
			 * if the Enclosure Item is not present, or has
			 * bit 2 = 0", which presumably means it shall
			 * *not* be present if the Enclosure item *is*
			 * present and has bit 2 = 1.
			 */

		  if(!(flags & BEGINNING_SPDU)) {
		    /* X.225 7.11.2 also states:
		     * "All DATA TRANSFER SPDUs, except the last DATA TRANSFER SPDU in a sequence greater than one, must have user information"
		     * So if BEGINNING_SPDU and END_SPDU are set in the enclosure item, then this is presumably a sequence of one and 
		     * consequently there must be user information.
		     *
		     * So, there is only no user information if *only* END_SPDU is set.
		     */

		     has_user_information = FALSE;
		  }
		}
		break;

	case Token_Setting_Item:
		if (param_len != 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be 1",
			    param_len);
			break;
		}
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_release_token_setting,
			    tvb, offset, 1, FALSE);
			proto_tree_add_item(param_tree,
			    hf_major_activity_token_setting,
			    tvb, offset, 1, FALSE);
			proto_tree_add_item(param_tree,
			    hf_synchronize_minor_token_setting,
			    tvb, offset, 1, FALSE);
			proto_tree_add_item(param_tree,
			    hf_data_token_setting,
			    tvb, offset, 1, FALSE);
		}
		break;

	case Activity_Identifier:
		if (param_len == 0)
			break;
		if (tree)
		{
			dissect_ber_integer(FALSE, &asn1_ctx, param_tree, tvb, offset,
			    hf_activity_identifier, NULL);
		}
		break;

	case Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Reason_Code:
/*
	0:	Rejection by called SS-user; reason not specified.
	1:	Rejection by called SS-user due to temporary congestion.
	2:	Rejection by called SS-user. Subsequent octets may be used for user data 
up to a length of 512 octets if Protocol Version 1 has been selected, and up 
to a length such that the total length (including SI and LI)  of the SPDU 
does not exceed 65 539 octets if Protocol Version 2 has been selected.
	128 + 1:	Session Selector unknown.
	128 + 2:	SS-user not attached to SSAP.
	128 + 3:	SPM congestion at connect time.
	128 + 4:	Proposed protocol versions not supported.
	128 + 5:	Rejection by the SPM; reason not specified.
	128 + 6:	Rejection by the SPM; implementation restriction stated in the 
PICS.    */
		if (param_len < 1)
		{
			proto_tree_add_text(param_tree, tvb, offset,
			    param_len, "Length is %u, should be >= 1",
			    param_len);
			break;
		}
		if (tree)
		{
			guint8      reason_code;

			reason_code = tvb_get_guint8(tvb, offset);
			proto_tree_add_text(param_tree, tvb, offset, 1,
			    "Reason Code: %s",
			    val_to_str(reason_code, reason_vals, "Unknown (%u)"));
		}
		offset++;
		param_len--;
		if (param_len != 0)
		{
			call_pres_dissector(tvb, offset, param_len,
			    pinfo, tree, param_tree, session);
		}
		break;

	case Calling_Session_Selector:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_calling_session_selector,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Called_Session_Selector:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_called_session_selector,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Second_Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_second_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Second_Initial_Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_second_initial_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Large_Initial_Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_large_initial_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	case Large_Second_Initial_Serial_Number:
		if (param_len == 0)
			break;
		if (tree)
		{
			proto_tree_add_item(param_tree,
			    hf_large_second_initial_serial_number,
			    tvb, offset, param_len, FALSE);
		}
		break;

	default:
		break;
	}
	return has_user_information;
}