static void dissect_icp_payload(tvbuff_t *tvb, int offset,
        proto_tree *pload_tree, guint8 opcode)
{
  gint stringlength;
  guint16 objectlength;

  switch(opcode)
  {
	case CODE_ICP_OP_QUERY:
	 	/* 4 byte requester host address */
		proto_tree_add_text(pload_tree, tvb,offset,4,
			"Requester Host Address %s",
			tvb_ip_to_str(tvb, offset));
		offset += 4;

		/* null terminated URL */
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_text(pload_tree, tvb, offset, stringlength,
			"URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength));
		break;

	case CODE_ICP_OP_SECHO:
	case CODE_ICP_OP_DECHO:
	case CODE_ICP_OP_HIT:
	case CODE_ICP_OP_MISS:
	case CODE_ICP_OP_ERR:
	case CODE_ICP_OP_MISS_NOFETCH:
	case CODE_ICP_OP_DENIED:
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_text(pload_tree, tvb, offset, stringlength,
			"URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength));
		break;

	case CODE_ICP_OP_HIT_OBJ:
		/* null terminated URL */
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_text(pload_tree, tvb, offset, stringlength,
			"URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength));
		offset += stringlength;

		/* 2 byte object size */
		/* object data not recommended by standard*/
		objectlength=tvb_get_ntohs(tvb, offset);
		proto_tree_add_text(pload_tree, tvb,offset,2,"Object length: %u", objectlength);
		offset += 2;

		/* object data not recommended by standard*/
		proto_tree_add_text(pload_tree, tvb,offset,objectlength,"Object data");
		if (objectlength > tvb_reported_length_remaining(tvb, offset))
		{
			proto_tree_add_text(pload_tree, tvb,offset,0,
				"Packet is fragmented, rest of object is in next udp packet");
		}
		break;
	default:
		break;
  }
}
Exemple #2
0
static void dissect_icp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset,
				proto_tree *pload_tree, guint8 opcode)
{
	gint stringlength;
	guint16 objectlength;
	proto_item* object_item;

	switch(opcode)
	{
	case CODE_ICP_OP_QUERY:
	 	/* 4 byte requester host address */
		proto_tree_add_item(pload_tree, hf_icp_requester_host_address, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		/* null terminated URL */
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA);
		break;

	case CODE_ICP_OP_SECHO:
	case CODE_ICP_OP_DECHO:
	case CODE_ICP_OP_HIT:
	case CODE_ICP_OP_MISS:
	case CODE_ICP_OP_ERR:
	case CODE_ICP_OP_MISS_NOFETCH:
	case CODE_ICP_OP_DENIED:
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA);
		break;

	case CODE_ICP_OP_HIT_OBJ:
		/* null terminated URL */
		stringlength = tvb_strsize(tvb, offset);
		proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA);
		offset += stringlength;

		/* 2 byte object size */
		/* object data not recommended by standard*/
		objectlength=tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(pload_tree, hf_icp_object_length, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* object data not recommended by standard*/
		object_item = proto_tree_add_item(pload_tree, hf_icp_object_data, tvb, offset, objectlength, ENC_NA);
		if (objectlength > tvb_reported_length_remaining(tvb, offset))
		{
			expert_add_info(pinfo, object_item, &ei_icp_fragmented_packet);
		}
		break;
	default:
		break;
	}
}
static int
dissect_mongo_msg(tvbuff_t *tvb, guint offset, proto_tree *tree)
{
  proto_tree_add_item(tree, hf_mongo_message, tvb, offset, -1, ENC_ASCII|ENC_NA);
  offset += tvb_strsize(tvb, offset);

  return offset;
}
Exemple #4
0
static void
tftp_dissect_options(tvbuff_t *tvb, packet_info *pinfo, int offset,
                     proto_tree *tree, guint16 opcode, tftp_conv_info_t *tftp_info)
{
  int         option_len, value_len;
  int         value_offset;
  const char *optionname;
  const char *optionvalue;
  proto_tree *opt_tree;

  while (tvb_offset_exists(tvb, offset)) {
    /* option_len and value_len include the trailing 0 byte */
    option_len = tvb_strsize(tvb, offset);
    value_offset = offset + option_len;
    value_len = tvb_strsize(tvb, value_offset);
    /* use xxx_len-1 to exclude the trailing 0 byte, it would be
       displayed as nonprinting character
       tvb_format_text() creates a temporary 0-terminated buffer */
    optionname = tvb_format_text(tvb, offset, option_len-1);
    optionvalue = tvb_format_text(tvb, value_offset, value_len-1);
    opt_tree = proto_tree_add_subtree_format(tree, tvb, offset, option_len+value_len,
                                   ett_tftp_option, NULL, "Option: %s = %s", optionname, optionvalue);

    proto_tree_add_item(opt_tree, hf_tftp_option_name, tvb, offset,
                        option_len, ENC_ASCII|ENC_NA);
    proto_tree_add_item(opt_tree, hf_tftp_option_value, tvb, value_offset,
                        value_len, ENC_ASCII|ENC_NA);

    offset += option_len + value_len;

    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s=%s",
                    optionname, optionvalue);

    /* Special code to handle individual options */
    if (!g_ascii_strcasecmp((const char *)optionname, "blksize") &&
        opcode == TFTP_OACK) {
      gint blocksize = (gint)strtol((const char *)optionvalue, NULL, 10);
      if (blocksize < 8 || blocksize > 65464) {
        expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range);
      } else {
        tftp_info->blocksize = blocksize;
      }
    }
  }
}
Exemple #5
0
static int
dissect_mongo_op_command(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree)
{
  gint32 db_length, cmd_length;

  db_length = tvb_strsize(tvb, offset);
  proto_tree_add_item(tree, hf_mongo_database, tvb, offset, db_length, ENC_ASCII|ENC_NA);
  offset += db_length;

  cmd_length = tvb_strsize(tvb, offset);
  proto_tree_add_item(tree, hf_mongo_commandname, tvb, offset, cmd_length, ENC_ASCII|ENC_NA);
  offset += cmd_length;

  offset += dissect_bson_document(tvb, pinfo, offset, tree, hf_mongo_metadata, 1);

  offset += dissect_bson_document(tvb, pinfo, offset, tree, hf_mongo_commandargs, 1);

  return offset;
}
Exemple #6
0
static void
tftp_dissect_options(tvbuff_t *tvb, packet_info *pinfo, int offset,
	proto_tree *tree, guint16 opcode, tftp_conv_info_t *tftp_info)
{
	int option_len, value_len;
	int value_offset;
	const char *optionname;
	const char *optionvalue;
	proto_item *opt_item;
	proto_tree *opt_tree;

	while (tvb_offset_exists(tvb, offset)) {
	  option_len = tvb_strsize(tvb, offset);	/* length of option */
	  value_offset = offset + option_len;
	  value_len = tvb_strsize(tvb, value_offset);	/* length of value */
	  optionname = tvb_format_text(tvb, offset, option_len);
	  optionvalue = tvb_format_text(tvb, value_offset, value_len);
	  opt_item = proto_tree_add_text(tree, tvb, offset, option_len+value_len,
	          "Option: %s = %s", optionname, optionvalue);

	  opt_tree = proto_item_add_subtree(opt_item, ett_tftp_option);
	  proto_tree_add_item(opt_tree, hf_tftp_option_name, tvb, offset,
		option_len, ENC_ASCII|ENC_NA);
	  proto_tree_add_item(opt_tree, hf_tftp_option_value, tvb, value_offset,
		value_len, ENC_ASCII|ENC_NA);

	  offset += option_len + value_len;

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", %s=%s",
			  optionname, optionvalue);

	  /* Special code to handle individual options */
	  if (!g_ascii_strcasecmp((const char *)optionname, "blksize") &&
	      opcode == TFTP_OACK) {
		gint blocksize = (gint)strtol((const char *)optionvalue, NULL, 10);
		if (blocksize < 8 || blocksize > 65464) {
			expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range);
		} else {
			tftp_info->blocksize = blocksize;
		}
	  }
	}
}
static void
dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
{
    int offset = 16; /* past the fcct header */
    int len, tot_len, prevlen;

    if (tree) {
        if (isreq) {
            proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
                                   tvb_fcwwn_to_str (tvb, offset));
        }
        else {
            tot_len = tvb_get_guint8 (tvb, offset+3);
            proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d",
                                 tot_len);

            prevlen = 0;
            len = tvb_strsize(tvb, offset+4);
            proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4,
                                 len, ENC_ASCII|ENC_NA);
            prevlen += len;

            len = tvb_strsize(tvb, offset+4+prevlen);
            proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen,
                                 len, ENC_ASCII|ENC_NA);
            prevlen += len;

            len = tvb_strsize(tvb, offset+4+prevlen);
            proto_tree_add_item (tree, hf_fcs_releasecode, tvb,
                                 offset+4+prevlen, len, ENC_ASCII|ENC_NA);
            prevlen += len;
            offset += (4+prevlen);
            while (tot_len > prevlen) {
                len = tvb_strsize(tvb, offset);
                proto_tree_add_text (tree, tvb, offset, len,
                                     "Vendor-specific Information: %s",
                                     tvb_format_text(tvb, offset, len-1));
                prevlen += len;
                offset += len;
            }
        }
    }
}
Exemple #8
0
WSLUA_METHOD TvbRange_strsize(lua_State* L) {
        /* Find the size of a zero terminated string from a TvbRange.  The size of the string includes the terminating zero. */
    TvbRange tvbr = checkTvbRange(L,1);

    if ( !(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset));

    WSLUA_RETURN(1); /* Length of the zero terminated string */
}
Exemple #9
0
/*!
 * Decodes a Text-string from the protocol data
 * 	Text-string = [Quote] *TEXT End-of-string
 * 	Quote	    = <Octet 127>
 * 	End-of-string = <Octet 0>
 *
 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
 *
 * \param	tvb	The buffer with PDU-data
 * \param	offset	Offset within that buffer
 * \param	strval	Pointer to variable into which to put pointer to
 *			buffer allocated to hold the text; must be freed
 *			when no longer used
 *
 * \return		The length in bytes of the entire field
 */
static guint
get_text_string(tvbuff_t *tvb, guint offset, const char **strval)
{
    guint	 len;

    DebugLog(("get_text_string(tvb = %p, offset = %u, **strval) - start\n",
		tvb, offset));
    len = tvb_strsize(tvb, offset);
    DebugLog((" [1] tvb_strsize(tvb, offset) == %u\n", len));
    if (tvb_get_guint8(tvb, offset) == MM_QUOTE)
	*strval = (const char *)tvb_memdup(wmem_packet_scope(), tvb, offset+1, len-1);
    else
	*strval = (const char *)tvb_memdup(wmem_packet_scope(), tvb, offset, len);
    DebugLog((" [3] Return(len) == %u\n", len));
    return len;
}
Exemple #10
0
WSLUA_METHOD TvbRange_strsize(lua_State* L) {
        /* Find the size of a zero terminated string from a `TvbRange`.
           The size of the string includes the terminating zero.

           @since 1.11.3
         */
#define WSLUA_OPTARG_TvbRange_strsize_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
    TvbRange tvbr = checkTvbRange(L,1);
    guint encoding = (guint)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_strsize_ENCODING, ENC_ASCII|ENC_NA);
    gint offset;
    gunichar2 uchar;

    if ( !(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    switch (encoding & ENC_CHARENCODING_MASK) {

    case ENC_UTF_16:
    case ENC_UCS_2:
        offset = tvbr->offset;
        do {
            if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
                luaL_error(L,"out of bounds");
                return 0;
            }
            /* Endianness doesn't matter when looking for null */
            uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
            offset += 2;
        } while (uchar != 0);
        lua_pushinteger(L, tvb_unicode_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
        break;

    default:
        if (tvb_find_guint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
            luaL_error(L,"out of bounds");
            return 0;
        }
        lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
        break;
    }

    WSLUA_RETURN(1); /* Length of the zero terminated string. */
}
static int
dissect_fullcollectionname(tvbuff_t *tvb, guint offset, proto_tree *tree)
{
  gint32 fcn_length, dbn_length;
  proto_item *ti;
  proto_tree *fcn_tree;

  fcn_length = tvb_strsize(tvb, offset);
  ti = proto_tree_add_item(tree, hf_mongo_fullcollectionname, tvb, offset, fcn_length, ENC_ASCII|ENC_NA);

  /* If this doesn't find anything, we'll just throw an exception below */
  dbn_length = tvb_find_guint8(tvb, offset, fcn_length, '.') - offset;

  fcn_tree = proto_item_add_subtree(ti, ett_mongo_fcn);

  proto_tree_add_item(fcn_tree, hf_mongo_database_name, tvb, offset, dbn_length, ENC_ASCII|ENC_NA);

  proto_tree_add_item(fcn_tree, hf_mongo_collection_name, tvb, offset + 1 + dbn_length, fcn_length - dbn_length - 2, ENC_ASCII|ENC_NA);

  return fcn_length;
}
Exemple #12
0
/* Dissect details of packet */
static void rlogin_display(rlogin_hash_entry_t *hash_info,
			   tvbuff_t *tvb,
			   packet_info *pinfo,
			   proto_tree *tree,
			   struct tcpinfo *tcpinfo)
{
	/* Display the proto tree */
	int             offset = 0;
	proto_tree      *rlogin_tree, *user_info_tree, *window_tree;
	proto_item      *ti;
	guint           length;
	int             str_len;
	gint            ti_offset;
	proto_item      *user_info_item, *window_info_item;

	/* Create rlogin subtree */
	ti = proto_tree_add_item(tree, proto_rlogin, tvb, 0, -1, ENC_NA);
	rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);

	/* Return if data empty */
	length = tvb_captured_length(tvb);
	if (length == 0)
	{
		return;
	}

	/*
	 * XXX - this works only if the urgent pointer points to something
	 * in this segment; to make it work if the urgent pointer points
	 * to something past this segment, we'd have to remember the urgent
	 * pointer setting for this conversation.
	 */
	if (tcpinfo && IS_TH_URG(tcpinfo->flags) &&      /* if urgent pointer set */
	    length >= tcpinfo->urgent_pointer) /* and it's in this frame */
	{
		/* Get urgent byte into Temp */
		int urgent_offset = tcpinfo->urgent_pointer - 1;
		guint8 control_byte;

		/* Check for text data in front */
		if (urgent_offset > offset)
		{
			proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, urgent_offset, ENC_ASCII|ENC_NA);
		}

		/* Show control byte */
		proto_tree_add_item(rlogin_tree, hf_control_message, tvb,
		                    urgent_offset, 1, ENC_BIG_ENDIAN);
		control_byte = tvb_get_guint8(tvb, urgent_offset);
		col_append_fstr(pinfo->cinfo, COL_INFO,
			               " (%s)", val_to_str_const(control_byte, control_message_vals, "Unknown"));

		offset = urgent_offset + 1; /* adjust offset */
	}
	else
	if (tvb_get_guint8(tvb, offset) == '\0')
	{
		/* Startup */
		if (pinfo->srcport == RLOGIN_PORT)   /* from server */
		{
			proto_tree_add_item(rlogin_tree, hf_startup_info_received_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		else
		{
			proto_tree_add_item(rlogin_tree, hf_client_startup_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		++offset;
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	if (hash_info->info_framenum == pinfo->num)
	{
		gint info_len;
		gint slash_offset;

		/* First frame of conversation, assume user info... */

		info_len = tvb_captured_length_remaining(tvb, offset);
		if (info_len <= 0)
			return;

		/* User info tree */
		user_info_item = proto_tree_add_string_format(rlogin_tree, hf_user_info, tvb,
		                                              offset, info_len, FALSE,
		                                              "User info (%s)",
		                                              tvb_format_text(tvb, offset, info_len));
		user_info_tree = proto_item_add_subtree(user_info_item,
		                                        ett_rlogin_user_info);

		/* Client user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_client_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Server user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_server_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Terminal type/speed. */
		slash_offset = tvb_find_guint8(tvb, offset, -1, '/');
		if (slash_offset != -1)
		{
			guint8* str = NULL;
			guint32 term_len = 0;
			gboolean term_len_valid;
			proto_item* pi = NULL;

			/* Terminal type */
			proto_tree_add_item(user_info_tree, hf_user_info_terminal_type,
			                    tvb, offset, slash_offset-offset, ENC_ASCII|ENC_NA);
			offset = slash_offset + 1;

			/* Terminal speed */
			str_len = tvb_strsize(tvb, offset);
			str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, str_len,
				ENC_NA|ENC_ASCII);
			term_len_valid = ws_strtou32(str, NULL, &term_len);
			pi = proto_tree_add_uint(user_info_tree,
				hf_user_info_terminal_speed,
				tvb, offset, str_len, term_len);
			if (!term_len_valid)
				expert_add_info(pinfo, pi, &ei_rlogin_termlen_invalid);

			offset += str_len;
		}
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	/* Test for terminal information, the data will have 2 0xff bytes */
	/* look for first 0xff byte */
	ti_offset = tvb_find_guint8(tvb, offset, -1, 0xff);

	/* Next byte must also be 0xff */
	if (ti_offset != -1 &&
	    tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
	    tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
	{
		guint16 rows, columns;

		/* Have found terminal info. */
		if (ti_offset > offset)
		{
			/* There's data before the terminal info. */
			proto_tree_add_item(rlogin_tree, hf_data, tvb,
			                    offset, ti_offset - offset, ENC_ASCII|ENC_NA);
		}

		/* Create window info tree */
		window_info_item =
			proto_tree_add_item(rlogin_tree, hf_window_info, tvb, offset, 12, ENC_NA);
		window_tree = proto_item_add_subtree(window_info_item, ett_rlogin_window);

		/* Cookie */
		proto_tree_add_item(window_tree, hf_magic_cookie, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* These bytes should be "ss" */
		proto_tree_add_item(window_tree, hf_window_info_ss, tvb, offset, 2, ENC_ASCII|ENC_NA);
		offset += 2;

		/* Character rows */
		rows = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_rows, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Characters per row */
		columns = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_cols, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* x pixels */
		proto_tree_add_item(window_tree, hf_window_info_x_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* y pixels */
		proto_tree_add_item(window_tree, hf_window_info_y_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Show setting highlights in info column */
		col_append_fstr(pinfo->cinfo, COL_INFO, " (rows=%u, cols=%u)",
			                rows, columns);
	}

	if (tvb_offset_exists(tvb, offset))
	{
		/* There's more data in the frame. */
		proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, -1, ENC_ASCII|ENC_NA);
	}
}
Exemple #13
0
/* Dissect OSC message */
static int
dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len)
{
    proto_tree  *message_tree;
    proto_tree  *header_tree;
    gint         slen;
    gint         rem;
    gint         end = offset + len;
    const gchar *path;
    gint         path_len;
    gint         path_offset;
    const gchar *format;
    gint         format_offset;
    gint         format_len;
    const gchar *ptr;

    /* peek/read path */
    path_offset = offset;
    path = tvb_get_const_stringz(tvb, path_offset, &path_len);
    if( (rem = path_len%4) ) path_len += 4-rem;

    if(!is_valid_path(path))
        return -1;

    /* peek/read fmt */
    format_offset = path_offset + path_len;
    format = tvb_get_const_stringz(tvb, format_offset, &format_len);
    if( (rem = format_len%4) ) format_len += 4-rem;

    if(!is_valid_format(format))
        return -1;

    /* create message */
    ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format);
    message_tree = proto_item_add_subtree(ti, ett_osc_message);

    /* append header */
    ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA);
    header_tree = proto_item_add_subtree(ti, ett_osc_message_header);

    /* append path */
    proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA);

    /* append format */
    proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA);

    offset += path_len + format_len;

    /* ::parse argument:: */
    ptr = format + 1; /* skip ',' */
    while( (*ptr != '\0') && (offset < end) )
    {
        switch(*ptr)
        {
            case OSC_INT32:
                proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_FLOAT:
                proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_STRING:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_BLOB:
            {
                proto_item *bi;
                proto_tree *blob_tree;

                gint32 blen = tvb_get_ntohl(tvb, offset);
                slen = blen;
                if( (rem = slen%4) ) slen += 4-rem;

                bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen);
                blob_tree = proto_item_add_subtree(bi, ett_osc_blob);

                proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen);
                offset += 4;

                /* check for zero length blob */
                if(blen == 0)
                    break;

                proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA);
                offset += slen;
                break;
            }

            case OSC_TRUE:
                proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_FALSE:
                proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_NIL:
                proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_BANG:
                proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA);
                break;

            case OSC_INT64:
                proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_DOUBLE:
                proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_TIMETAG:
            {
                guint32  sec  = tvb_get_ntohl(tvb, offset);
                guint32  frac = tvb_get_ntohl(tvb, offset+4);
                nstime_t ns;
                if( (sec == 0) && (frac == 1) )
                    proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str);
                else
                    proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN);
                offset += 8;
            }
                break;

            case OSC_SYMBOL:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_CHAR:
                offset += 3;
                proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA);
                offset += 1;
                break;
            case OSC_RGBA:
            {
                proto_item *ri;
                proto_tree *rgba_tree;

                ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba);

                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                break;
            }
            case OSC_MIDI:
            {
                const gchar *status_str;
                proto_item  *mi = NULL;
                proto_tree  *midi_tree;
                guint8       port;
                guint8       command;
                guint8       data1;
                guint8       data2;
                guint8       status;
                guint8       channel;
                gboolean     system_msg;
                guint8       status_shifted;

                port = tvb_get_guint8(tvb, offset);
                command  = tvb_get_guint8(tvb, offset+1);
                data1   = tvb_get_guint8(tvb, offset+2);
                data2   = tvb_get_guint8(tvb, offset+3);

                status  = command & 0xF0;
                channel = command & 0x0F;

                system_msg = status == 0xF0; /* is system message */
                status_shifted = status >> 4;

                if(system_msg)
                    status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown");
                else
                    status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown");

                if(system_msg)
                {
                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Port %i, %s, %i, %i",
                            port, status_str, data1, data2);
                }
                else
                {
                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            const gchar *note_str;
                            note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, note_str, data2);
                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            const gchar *control_str;
                            control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, control_str, data2);
                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i",
                                    port, channel, status_str, bender);
                            break;
                        }
                        default:
                        {
                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i, %i",
                                    port, channel, status_str, data1, data2);
                            break;
                        }
                    }
                }
                midi_tree = proto_item_add_subtree(mi, ett_osc_midi);

                proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                if(system_msg)
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                else
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CHANNEL_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender);
                            offset += 2;

                            break;
                        }
                        default:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                    }
                }

                break;
            }

            default:
                /* if we get here, there must be a bug in the dissector  */
                DISSECTOR_ASSERT_NOT_REACHED();
                break;
        }
        ptr++;
    }

    if(offset != end)
        return -1;
    else
        return 0;
}
Exemple #14
0
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree)
{
    guchar c;
    gint i, siz;
    char *s, *t;
    proto_item *ti;
    proto_tree *shrub;

    switch (type) {
    /* Authentication request */
    case 'R':
        proto_tree_add_item(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN);
        i = tvb_get_ntohl(tvb, n);
        if (i == 4 || i == 5) {
            /* i -= (6-i); :-) */
            n += 4;
            siz = (i == 4 ? 2 : 4);
            proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA);
        }
        break;

    /* Key data */
    case 'K':
        proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
        break;

    /* Parameter status */
    case 'S':
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s);
        n += siz;
        t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t);
        break;

    /* Parameter description */
    case 't':
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Row description */
    case 'T':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            proto_tree *twig;
            siz = tvb_strsize(tvb, n);
            ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA);
            twig = proto_item_add_subtree(ti, ett_values);
            n += siz;
            proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Data row */
    case 'D':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }
        break;

    /* Command completion */
    case 'C':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Ready */
    case 'Z':
        proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_NA);
        break;

    /* Error, Notice */
    case 'E':
    case 'N':
        length -= 4;
        while ((signed)length > 0) {
            c = tvb_get_guint8(tvb, n);
            if (c == '\0')
                break;
            s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII);
            i = hf_text;
            switch (c) {
            case 'S': i = hf_severity;          break;
            case 'C': i = hf_code;              break;
            case 'M': i = hf_message;           break;
            case 'D': i = hf_detail;            break;
            case 'H': i = hf_hint;              break;
            case 'P': i = hf_position;          break;
            case 'p': i = hf_internal_position; break;
            case 'q': i = hf_internal_query;    break;
            case 'W': i = hf_where;             break;
            case 's': i = hf_schema_name;       break;
            case 't': i = hf_table_name;        break;
            case 'c': i = hf_column_name;       break;
            case 'd': i = hf_type_name;         break;
            case 'n': i = hf_constraint_name;   break;
            case 'F': i = hf_file;              break;
            case 'L': i = hf_line;              break;
            case 'R': i = hf_routine;           break;
            }
            proto_tree_add_string(tree, i, tvb, n, siz+1, s);
            length -= siz+1;
            n += siz+1;
        }
        break;

    /* NOTICE response */
    case 'A':
        proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;
        siz = tvb_strsize(tvb, n);
        if (siz > 1)
            proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Copy in/out */
    case 'G':
    case 'H':
        proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN);
        n += 1;
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i);
        n += 2;
        while (i-- > 2) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Function call response */
    case 'V':
        siz = tvb_get_ntohl(tvb, n);
        proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz);
        if (siz > 0)
            proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA);
        break;
    }
}
Exemple #15
0
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree)
{
    guchar c;
    gint i, siz;
    char *s;
    proto_tree *shrub;

    switch (type) {
    /* Password */
    case 'p':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Simple query */
    case 'Q':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Parse */
    case 'P':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Bind */
    case 'B':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Execute */
    case 'E':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohl(tvb, n);
        if (i == 0)
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows");
        else
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i);
        break;

    /* Describe, Close */
    case 'D':
    case 'C':
        c = tvb_get_guint8(tvb, n);
        if (c == 'P')
            i = hf_portal;
        else
            i = hf_statement;

        n += 1;
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, i, tvb, n, siz, s);
        break;

    /* Messages without a type identifier */
    case '\0':
        i = tvb_get_ntohl(tvb, n);
        n += 4;
        length -= n;
        switch (i) {
        /* Startup message */
        case 196608:
            while ((signed)length > 0) {
                siz = tvb_strsize(tvb, n);
                length -= siz;
                if ((signed)length <= 0) {
                    break;
                }
                proto_tree_add_item(tree, hf_parameter_name,  tvb, n,       siz, ENC_ASCII|ENC_NA);
                i = tvb_strsize(tvb, n+siz);
                proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i,   ENC_ASCII|ENC_NA);
                length -= i;

                n += siz+i;
                if (length == 1 && tvb_get_guint8(tvb, n) == 0)
                    break;
            }
            break;

        /* SSL request */
        case 80877103:
            /* There's nothing to parse here, but what do we do if the
               SSL negotiation succeeds? */
            break;

        /* Cancellation request */
        case 80877102:
            proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
            break;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Copy failure */
    case 'f':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Function call */
    case 'F':
        proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
        break;
    }
}
Exemple #16
0
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree,
                                 pgsql_conn_data_t *conv_data)
{
    guchar c;
    gint i, siz;
    char *s, *t;
    gint32 num_nonsupported_options;
    proto_item *ti;
    proto_tree *shrub;
    guint32 auth_type;

    switch (type) {
    /* Authentication request */
    case 'R':
        proto_tree_add_item_ret_uint(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN, &auth_type);
        switch (auth_type) {
        case PGSQL_AUTH_TYPE_CRYPT:
        case PGSQL_AUTH_TYPE_MD5:
            n += 4;
            siz = (auth_type == PGSQL_AUTH_TYPE_CRYPT ? 2 : 4);
            proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA);
            break;
        case PGSQL_AUTH_TYPE_GSSAPI_SSPI_CONTINUE:
            conv_data->auth_state = PGSQL_AUTH_GSSAPI_SSPI_DATA;
            proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-8, ENC_NA);
            break;
        case PGSQL_AUTH_TYPE_SASL:
            conv_data->auth_state = PGSQL_AUTH_SASL_REQUESTED;
            n += 4;
            while ((guint)n < length) {
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA);
                n += siz;
            }
            break;
        case PGSQL_AUTH_TYPE_SASL_CONTINUE:
        case PGSQL_AUTH_TYPE_SASL_COMPLETE:
            conv_data->auth_state = PGSQL_AUTH_SASL_CONTINUE;
            n += 4;
            if ((guint)n < length) {
                proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA);
            }
            break;
        }
        break;

    /* Key data */
    case 'K':
        proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
        break;

    /* Parameter status */
    case 'S':
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s);
        n += siz;
        t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t);
        break;

    /* Parameter description */
    case 't':
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Row description */
    case 'T':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            proto_tree *twig;
            siz = tvb_strsize(tvb, n);
            ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA);
            twig = proto_item_add_subtree(ti, ett_values);
            n += siz;
            proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Data row */
    case 'D':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }
        break;

    /* Command completion */
    case 'C':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Ready */
    case 'Z':
        proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN);
        break;

    /* Error, Notice */
    case 'E':
    case 'N':
        length -= 4;
        while ((signed)length > 0) {
            c = tvb_get_guint8(tvb, n);
            if (c == '\0')
                break;
            s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII);
            i = hf_text;
            switch (c) {
            case 'S': i = hf_severity;          break;
            case 'C': i = hf_code;              break;
            case 'M': i = hf_message;           break;
            case 'D': i = hf_detail;            break;
            case 'H': i = hf_hint;              break;
            case 'P': i = hf_position;          break;
            case 'p': i = hf_internal_position; break;
            case 'q': i = hf_internal_query;    break;
            case 'W': i = hf_where;             break;
            case 's': i = hf_schema_name;       break;
            case 't': i = hf_table_name;        break;
            case 'c': i = hf_column_name;       break;
            case 'd': i = hf_type_name;         break;
            case 'n': i = hf_constraint_name;   break;
            case 'F': i = hf_file;              break;
            case 'L': i = hf_line;              break;
            case 'R': i = hf_routine;           break;
            }
            proto_tree_add_string(tree, i, tvb, n, siz+1, s);
            length -= siz+1;
            n += siz+1;
        }
        break;

    /* NOTICE response */
    case 'A':
        proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;
        siz = tvb_strsize(tvb, n);
        if (siz > 1)
            proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Copy in/out */
    case 'G':
    case 'H':
        proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN);
        n += 1;
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i);
        n += 2;
        while (i-- > 2) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Function call response */
    case 'V':
        siz = tvb_get_ntohl(tvb, n);
        proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz);
        if (siz > 0)
            proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA);
        break;

    /* Negotiate Protocol Version */
    case 'v':
        proto_tree_add_item(tree, hf_supported_minor_version, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        proto_tree_add_item_ret_int(tree, hf_number_nonsupported_options, tvb, n, 4, ENC_BIG_ENDIAN, &num_nonsupported_options);
        n += 4;
        while (num_nonsupported_options > 0) {
            siz = tvb_strsize(tvb, n);
            proto_tree_add_item(tree, hf_nonsupported_option, tvb, n, siz, ENC_ASCII|ENC_NA);
            n += siz;
            num_nonsupported_options--;
        }
        break;
    }
}
Exemple #17
0
/* Dissect OSC message */
static int
dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len)
{
    proto_tree *message_tree = NULL;
    proto_tree *header_tree = NULL;
    gint slen;
    gint rem;
    gint end = offset + len;
    const gchar *path = NULL;
    gint path_len;
    gint path_offset;
    const gchar *format = NULL;
    gint format_offset;
    gint format_len;
    const gchar *ptr = NULL;

    /* peek/read path */
    path_offset = offset;
    path = tvb_get_const_stringz(tvb, path_offset, &path_len);
    if( (rem = path_len%4) ) path_len += 4-rem;

    if(!is_valid_path(path))
        return -1;

    /* peek/read fmt */
    format_offset = path_offset + path_len;
    format = tvb_get_const_stringz(tvb, format_offset, &format_len);
    if( (rem = format_len%4) ) format_len += 4-rem;

    if(!is_valid_format(format))
        return -1;

    /* create message */
    ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format);
    message_tree = proto_item_add_subtree(ti, ett_osc_message);

    /* append header */
    ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA);
    header_tree = proto_item_add_subtree(ti, ett_osc_message_header);

    /* append path */
    proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA);

    /* append format */
    proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA);

    offset += path_len + format_len;

    /* ::parse argument:: */
    ptr = format + 1; /* skip ',' */
    while( (*ptr != '\0') && (offset < end) )
    {
        switch(*ptr)
        {
            case OSC_INT32:
                proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_FLOAT:
                proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_STRING:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_BLOB:
            {
                proto_item *bi = NULL;
                proto_tree *blob_tree = NULL;

                gint32 blen = tvb_get_ntohl(tvb, offset);
                slen = blen;
                if( (rem = slen%4) ) slen += 4-rem;

                bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen);
                blob_tree = proto_item_add_subtree(bi, ett_osc_blob);

                proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen);
                offset += 4;

                /* check for zero length blob */
                if(blen == 0)
                    break;

                proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA);
                offset += slen;
                break;
            }

            case OSC_TRUE:
                proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_FALSE:
                proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_NIL:
                proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_BANG:
                proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA);
                break;

            case OSC_INT64:
                proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_DOUBLE:
                proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_TIMETAG:
            {
                guint32 sec = tvb_get_ntohl(tvb, offset);
                guint32 frac = tvb_get_ntohl(tvb, offset+4);
                nstime_t ns;
                if( (sec == 0UL) && (frac == 1UL) )
                    proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str);
                else
                    proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN);
                offset += 8;
            }
                break;

            case OSC_SYMBOL:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_CHAR:
                offset += 3;
                proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA);
                offset += 1;
                break;
            case OSC_RGBA:
            {
                proto_item *ri = NULL;
                proto_tree *rgba_tree = NULL;

                ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba);

                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                break;
            }
            case OSC_MIDI:
            {
                const gchar *status_str = NULL;
                const gchar *control_str = NULL;
                proto_item *mi = NULL;
                proto_tree *midi_tree = NULL;
                guint8 channel;
                guint8 status;
                guint8 data1;
                guint8 data2;

                channel = tvb_get_guint8(tvb, offset);
                status = tvb_get_guint8(tvb, offset+1);
                data1 = tvb_get_guint8(tvb, offset+2);
                data2 = tvb_get_guint8(tvb, offset+3);

                status_str = val_to_str_const(status, MIDI_status, "Unknown");

                if(status == MIDI_STATUS_CONTROLLER) /* MIDI Controller */
                {
                    control_str = val_to_str_const(data1, MIDI_control, "Unknown");

                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Channel %2i, %s (0x%02x), %s (0x%02x), 0x%02x",
                            channel,
                            status_str, status,
                            control_str, data1,
                            data2);
                }
                else
                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Channel %2i, %s (0x%02x), 0x%02x, 0x%02x",
                            channel,
                            status_str, status,
                            data1, data2);
                midi_tree = proto_item_add_subtree(mi, ett_osc_midi);

                proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                if(status == MIDI_STATUS_CONTROLLER)
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_value_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                else
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }

                break;
            }

            default:
                /* if we get here, there must be a bug in the dissector  */
                DISSECTOR_ASSERT_NOT_REACHED();
                break;
        }
        ptr++;
    }

    if(offset != end)
        return -1;
    else
        return 0;
}
/*
 * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't
 * the same as browser announcements sent to \MAILSLOT\BROWSE.
 * Was that an older version of the protocol?
 *
 * The document at
 *
 *	http://www.samba.org/samba/ftp/specs/brow_rev.txt
 *
 * gives both formats of host announcement packets, saying that
 * "[The first] format seems wrong", that one being what appears to
 * show up in \MAILSLOT\LANMAN packets, and that "[The second one]
 * may be better", that one being what appears to show up in
 * \MAILSLOT\BROWSE packets.
 *
 * XXX - what other browser packets go out to that mailslot?
 */
static void
dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	guint8 cmd;
	proto_tree *tree = NULL;
	proto_item *item = NULL;
	guint32 periodicity;
	const guint8 *host_name;
	guint namelen;

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

	cmd = tvb_get_guint8(tvb, offset);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		/* Put in something, and replace it later */
		col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
	}


	if (parent_tree) {
		item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, TRUE);

		tree = proto_item_add_subtree(item, ett_browse);
	}

	/* command */
	proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
	offset += 1;

	switch (cmd) {
	case BROWSE_DOMAIN_ANNOUNCEMENT:
	case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
	case BROWSE_HOST_ANNOUNCE:

		/* update count */
		proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, TRUE);
		offset += 1;

		/* server type flags */
		offset = dissect_smb_server_type_flags(
			tvb, offset, pinfo, tree, NULL, TRUE);

		/* OS major version */
		proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, TRUE);
		offset += 1;

		/* OS minor version */
		proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, TRUE);
		offset += 1;

		/* periodicity (in seconds; convert to milliseconds) */
		periodicity = tvb_get_letohs(tvb, offset)*1000;
		proto_tree_add_uint_format(tree, hf_periodicity, tvb, offset, 2,
		    periodicity,
		    "Update Periodicity: %s",
		    time_msecs_to_str(periodicity));
		offset += 2;

		/* server name */
		namelen = tvb_strsize(tvb, offset);
		host_name = tvb_get_ptr(tvb, offset, namelen);
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
		}
		proto_tree_add_item(tree, hf_server_name,
			tvb, offset, namelen, TRUE);
		offset += namelen;

		/* master browser server name or server comment */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
			    hf_mb_server_name : hf_server_comment,
			tvb, offset, namelen, TRUE);
		offset += namelen;
		break;
	}
}
Exemple #19
0
static void
dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	guint8 cmd;
	proto_tree *tree = NULL;
	proto_item *item = NULL;
	guint32 periodicity;
	gchar host_name[17];
	gchar *utf8_host_name;
	gint namelen;
	guint8 server_count, reset_cmd;
	guint8 os_major_ver, os_minor_ver;
	gchar *windows_version = NULL;
	int i;
	guint32 uptime;

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

	cmd = tvb_get_guint8(tvb, offset);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		/* Put in something, and replace it later */
		col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
	}


	if (parent_tree) {
		item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, TRUE);

		tree = proto_item_add_subtree(item, ett_browse);
	}

	/* command */
	proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
	offset += 1;

	switch (cmd) {
	case BROWSE_DOMAIN_ANNOUNCEMENT:
	case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
	case BROWSE_HOST_ANNOUNCE: {
		/* update count */
		proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, TRUE);
		offset += 1;

		/* periodicity (in milliseconds) */
		periodicity = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format(tree, hf_periodicity, tvb, offset, 4,
		    periodicity,
		    "Update Periodicity: %s",
		    time_msecs_to_str(periodicity));
		offset += 4;

		/* server name */
		tvb_get_nstringz0(tvb, offset, sizeof(host_name), host_name);
		utf8_host_name = g_convert(host_name, strlen(host_name),
			"UTF-8", "CP437", NULL, NULL, NULL);
		if (utf8_host_name == NULL)
			utf8_host_name = host_name;
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_append_fstr(pinfo->cinfo, COL_INFO, " %s", utf8_host_name);
		}
		proto_tree_add_string_format(tree, hf_server_name,
			tvb, offset, 16,
			utf8_host_name,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
				"Domain/Workgroup: %s":
				"Host Name: %s",
			utf8_host_name);
		if (utf8_host_name != host_name)
			g_free(utf8_host_name);
		offset += 16;

		/* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
		os_major_ver = tvb_get_guint8(tvb, offset);
		os_minor_ver = tvb_get_guint8(tvb, offset+1);

		SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);

		if(windows_version)
		  proto_tree_add_text(tree, tvb, offset, 2, "Windows version: %s", windows_version);

		/* OS major version */
		proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, TRUE);
		offset += 1;

		/* OS minor version */
		proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, TRUE);
		offset += 1;

		/* server type flags */
		offset = dissect_smb_server_type_flags(
			tvb, offset, pinfo, tree, NULL, TRUE);

		if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) {
			/*
			 * Network Monitor claims this is a "Comment
			 * Pointer".  I don't believe it.
			 *
			 * It's not a browser protocol major/minor
			 * version number, and signature constant,
			 * however.
			 */
			proto_tree_add_text(tree, tvb, offset, 4,
			    "Mysterious Field: 0x%08x",
			    tvb_get_letohl(tvb, offset));
			offset += 4;
		} else {
			/* browser protocol major version */
			proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, TRUE);
			offset += 1;

			/* browser protocol minor version */
			proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, TRUE);
			offset += 1;

			/* signature constant */
			proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, TRUE);
			offset += 2;
		}

		/* master browser server name or server comment */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
			    hf_mb_server_name : hf_server_comment,
			tvb, offset, namelen, TRUE);
		offset += namelen;
		break;
	}
	case BROWSE_REQUEST_ANNOUNCE: {
		guint8 *computer_name;

		/* unused/unknown flags */
		proto_tree_add_item(tree, hf_unused_flags,
			tvb, offset, 1, TRUE);
		offset += 1;

		/* name of computer to which to send reply */
		computer_name = tvb_get_ephemeral_stringz(tvb, offset, &namelen);
		proto_tree_add_string(tree, hf_response_computer_name,
			tvb, offset, namelen, computer_name);
		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(
				pinfo->cinfo, COL_INFO, " %s", computer_name);
		offset += namelen;
		break;
	}

	case BROWSE_ELECTION_REQUEST:
		/* election version */
		proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, TRUE);
		offset += 1;

		/* criterion */
		dissect_election_criterion(tvb, tree, offset);
		offset += 4;

		/* server uptime */
		uptime = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format(tree, hf_server_uptime,
		    tvb, offset, 4, uptime,
		    "Uptime: %s",
		    time_msecs_to_str(uptime));
		offset += 4;

		/* next 4 bytes must be zero */
		offset += 4;

		/* server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_server_name,
			tvb, offset, namelen, TRUE);
		offset += namelen;
		break;

	case BROWSE_BACKUP_LIST_REQUEST:
		/* backup list requested count */
		proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, TRUE);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, TRUE);
		offset += 4;
		break;

	case BROWSE_BACKUP_LIST_RESPONSE:
		/* backup list requested count */
		server_count = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1,
		    server_count);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, TRUE);
		offset += 4;

		/* backup server names */
		for (i = 0; i < server_count; i++) {
			namelen = tvb_strsize(tvb, offset);
			proto_tree_add_item(tree, hf_backup_server,
				tvb, offset, namelen, TRUE);
			offset += namelen;
		}
		break;

	case BROWSE_MASTER_ANNOUNCEMENT:
		/* master browser server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_mb_server_name,
			tvb, offset, namelen, TRUE);
		offset += namelen;
		break;

	case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: {
	        proto_tree *sub_tree;
	        proto_item *reset_item;

		/* the subcommand follows ... one of three values */

	        reset_cmd = tvb_get_guint8(tvb, offset);
		reset_item = proto_tree_add_uint(tree, hf_mb_reset_command, tvb,
						 offset, 1, reset_cmd);
		sub_tree = proto_item_add_subtree(item, ett_browse_reset_cmd_flags);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_demote, tvb,
				       offset, 1, reset_cmd);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_flush, tvb,
				       offset, 1, reset_cmd);
		proto_tree_add_boolean(sub_tree, hf_mb_reset_stop, tvb,
				       offset, 1, reset_cmd);
		offset += 1;
		break;
	}

	case BROWSE_BECOME_BACKUP:
		/* name of browser to promote */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_browser_to_promote,
			tvb, offset, namelen, TRUE);
		offset += namelen;
		break;
	}
}
Exemple #20
0
gboolean
dissect_mailslot_smb(tvbuff_t *mshdr_tvb, tvbuff_t *setup_tvb,
		     tvbuff_t *tvb, const char *mailslot, packet_info *pinfo,
		     proto_tree *parent_tree)
{
	smb_info_t *smb_info;
	smb_transact_info_t *tri;
	int             trans_subcmd;
	proto_tree      *tree = NULL;
	proto_item      *item = NULL;
	guint16         opcode;
	int             offset = 0;
	int             len;

	if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_msp))) {
		return FALSE;
	}
	pinfo->current_proto = "SMB Mailslot";

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Mailslot");

	if ((tvb==NULL) || (tvb_reported_length(tvb)==0)) {
		/* Interim reply */
		col_set_str(pinfo->cinfo, COL_INFO, "Interim reply");
		return TRUE;
	}

	col_clear(pinfo->cinfo, COL_INFO);

	smb_info = pinfo->private_data;
	if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI)
		tri = smb_info->sip->extra_info;
	else
		tri = NULL;

	/* check which mailslot this is about */
	trans_subcmd=MAILSLOT_UNKNOWN;
	if(smb_info->request){
		if(strncmp(mailslot,"BROWSE",6) == 0){
	  		trans_subcmd=MAILSLOT_BROWSE;
		} else if(strncmp(mailslot,"LANMAN",6) == 0){
	  		trans_subcmd=MAILSLOT_LANMAN;
		} else if(strncmp(mailslot,"NET",3) == 0){
	  		trans_subcmd=MAILSLOT_NET;
		} else if(strncmp(mailslot,"TEMP\\NETLOGON",13) == 0){
	  		trans_subcmd=MAILSLOT_TEMP_NETLOGON;
		} else if(strncmp(mailslot,"MSSP",4) == 0){
			trans_subcmd=MAILSLOT_MSSP;
		}
		if (!pinfo->fd->flags.visited) {
			if (tri != NULL)
				tri->trans_subcmd = trans_subcmd;
		}
	} else {
		if(!tri){
			return FALSE;
		} else {
			trans_subcmd = tri->trans_subcmd;
		}
	}

	/* Only do these ones if we have them. For fragmented SMB Transactions
	   we may only have the setup area for the first fragment
	*/
	if(mshdr_tvb && setup_tvb){
		if (parent_tree) {
			item = proto_tree_add_item(parent_tree, proto_smb_msp,
						   mshdr_tvb, 0, -1, FALSE);
			tree = proto_item_add_subtree(item, ett_smb_msp);
		}

		/* do the opcode field */
		opcode = tvb_get_letohs(setup_tvb, offset);

		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_str(pinfo->cinfo, COL_INFO,
				    val_to_str(opcode, opcode_vals, "Unknown opcode: 0x%04x"));
		}


		/* These are in the setup words; use "setup_tvb". */

		/* opcode */
		proto_tree_add_uint(tree, hf_opcode, setup_tvb, offset, 2,
		    opcode);
		offset += 2;

		/* priority */
		proto_tree_add_item(tree, hf_priority, setup_tvb, offset, 2,
		    TRUE);
		offset += 2;

		/* class */
		proto_tree_add_item(tree, hf_class, setup_tvb, offset, 2, TRUE);
		offset += 2;

		/* These are in the rest of the data; use "mshdr_tvb", which
		   starts at the same place "setup_tvb" does. */

		/* size */
		/* this is actually bytecount in the SMB Transaction command */
		proto_tree_add_item(tree, hf_size, mshdr_tvb, offset, 2, TRUE);
		offset += 2;

		/* mailslot name */
		len = tvb_strsize(mshdr_tvb, offset);
		proto_tree_add_item(tree, hf_name, mshdr_tvb, offset, len, TRUE);
		offset += len;
		proto_item_set_len(item, offset);
	}

	switch(trans_subcmd){
	case MAILSLOT_BROWSE:
		call_dissector(mailslot_browse_handle, tvb, pinfo,
		    parent_tree);
		break;

	case MAILSLOT_LANMAN:
		call_dissector(mailslot_lanman_handle, tvb, pinfo,
		    parent_tree);
		break;

	case MAILSLOT_NET:
	case MAILSLOT_TEMP_NETLOGON:
	case MAILSLOT_MSSP:
		call_dissector(netlogon_handle, tvb, pinfo,
		    parent_tree);
		break;

	default:
		/*
		 * We dissected the mailslot header, but we don't know
		 * how to dissect the message; dissect the latter as data,
		 * but indicate that we successfully dissected the mailslot
		 * stuff.
		 */
		call_dissector(data_handle ,tvb, pinfo, parent_tree);
		break;
	}
	return TRUE;
}
static guint
state_machine_v4( socks_hash_entry_t *hash_info, tvbuff_t *tvb,
	int offset, packet_info *pinfo) {

/* Decode V4 protocol.  This is done on the first pass through the 	*/
/* list.  Based upon the current state, decode the packet and determine	*/
/* what the next state should be.  If we had per packet information, 	*/
/* this would be the place to load them up.				*/

	if ( hash_info->state == None) {		/* new connection */

		col_append_str(pinfo->cinfo, COL_INFO, " Connect to server request");

		hash_info->state = Connecting;	/* change state		*/

		hash_info->command = tvb_get_guint8(tvb, offset + 1);
						/* get remote port	*/
		if ( hash_info->command == CONNECT_COMMAND)
			hash_info->port =  tvb_get_ntohs(tvb, offset + 2);
						/* get remote address	*/

		hash_info->dst_addr = tvb_get_ipv4(tvb, offset + 4);

						/* save the packet pointer */
		hash_info->connect_row = get_packet_ptr;

						/* skip past this stuff	*/
		hash_info->connect_offset = offset + 8;

		offset += 8;

		if ( !tvb_offset_exists(tvb, offset)) {	/* if no user name */
							/* change state */
			hash_info->state = V4UserNameWait;
			/*
			 * XXX - add 1, or leave it alone?
			 * We were adding "strlen(...) + 1".
			 */
			hash_info->connect_offset += 1;
		} else {
			/*
			 * Add in the length of the user name.
			 * XXX - what if the user name is split between
			 * TCP segments?
			 */
			hash_info->connect_offset += tvb_strsize(tvb, offset);
		}

		if ( !hash_info->dst_addr){ 		/* if no dest address */
							/* if more data */
			if ( tvb_offset_exists(tvb, hash_info->connect_offset)) {
/*XXX copy remote name here ??? */
				hash_info->state = Connecting;
			}
			else
				hash_info->state = V4NameWait;
						}
						/* waiting for V4 user name */
	}else if ( hash_info->state == V4UserNameWait){

		col_append_str(pinfo->cinfo, COL_INFO, " Connect Request (User name)");

		hash_info->v4_user_name_row = get_packet_ptr;
/*XXX may need to check for domain name here */
		hash_info->state = Connecting;
	}
					/* waiting for V4 domain name	*/
	else if ( hash_info->state == V4NameWait){

		hash_info->v4_name_row = get_packet_ptr;
		hash_info->state = Connecting;

	}
	else if ( hash_info->state == Connecting){

		col_append_str(pinfo->cinfo, COL_INFO, " Connect Response");

						/* save packet pointer 	*/
		hash_info->cmd_reply_row = get_packet_ptr;
		hash_info->state = Done;		/* change state		*/
		offset = offset + 8;
	}

	return offset;
}
static void
display_socks_v4(tvbuff_t *tvb, int offset, packet_info *pinfo,
	proto_tree *tree, socks_hash_entry_t *hash_info) {


/* Display the protocol tree for the V4 version. This routine uses the	*/
/* stored conversation information to decide what to do with the row.	*/
/* Per packet information would have been better to do this, but we	*/
/* didn't have that when I wrote this. And I didn't expect this to get	*/
/* so messy.								*/


	proto_item *hidden_item;
	guint command;
	unsigned char ipaddr[4];
	guint username_len, domainname_len;

					/* Display command from client */
	if (compare_packet( hash_info->connect_row)){

		proto_tree_add_text( tree, tvb, offset, 1,
				"Version: %u", hash_info->version);
		++offset;
		command = tvb_get_guint8(tvb, offset);

		proto_tree_add_text( tree, tvb, offset, 1,
			"Command: %u (%s)", command,
				get_command_name( command));
		++offset;

						/* Do remote port	*/
		proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2,
				FALSE);
		offset += 2;

						/* Do destination address */
		tvb_memcpy(tvb, ipaddr, offset, 4);
		proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset,
				4, FALSE);

		offset += 4;

/*XXX check this, needs to do length checking	 */
/* Should perhaps do TCP reassembly as well */
		if ( tvb_offset_exists(tvb, offset)) {
						/* display user name 	*/
			username_len = tvb_strsize(tvb, offset);
			proto_tree_add_item( tree, hf_user_name, tvb, offset,
				username_len, FALSE);
			offset += username_len;
			if ( ipaddr[0] == 0 && ipaddr[1] == 0 &&
			     ipaddr[2] == 0 && ipaddr[3] != 0) {
			     	/* 0.0.0.x , where x!=0 means v4a support */
			     	domainname_len = tvb_strsize(tvb, offset);
				proto_tree_add_item( tree, hf_v4a_dns_name,
					tvb, offset, domainname_len,
					FALSE);
			}
		}

	}
				/*Display command response from server*/

	else if ( compare_packet( hash_info->cmd_reply_row)){

		proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1,
				FALSE);
		++offset;
						/* Do results code	*/
		proto_tree_add_item( tree, hf_socks_results_4, tvb, offset, 1, FALSE);
		hidden_item = proto_tree_add_item(tree, hf_socks_results, tvb, offset, 1, FALSE);
		PROTO_ITEM_SET_HIDDEN(hidden_item);

		++offset;

						/* Do remote port	*/
		proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2,
				FALSE);
		offset += 2;
						/* Do remote address	*/
		proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4,
			FALSE);
	}

	else if ( compare_packet( hash_info->v4_user_name_row)){

/*XXX check this, needs to do length checking	 */
/* Should perhaps do TCP reassembly as well */
		if ( tvb_offset_exists(tvb, offset)) {
			proto_tree_add_text( tree, tvb, offset,
				tvb_strsize(tvb, offset),
				"User Name: %s", tvb_get_ptr(tvb, offset, -1));
		}
	}
}
Exemple #23
0
static void
display_socks_v4(tvbuff_t *tvb, int offset, packet_info *pinfo,
    proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) {


/* Display the protocol tree for the V4 version. This routine uses the  */
/* stored frame information to decide what to do with the row.  */

    unsigned char ipaddr[4];
    guint         str_len;

    /* Either there is an error, or we're done with the state machine
      (so there's nothing to display) */
    if (state_info == NULL)
        return;

    if (hash_info->server_port == pinfo->destport) {
        /* Client side */
        switch (state_info->client)
        {
        case clientStart:
            proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;

            proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA);
            offset += 1;

            /* Do remote port */
            proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;

            /* Do destination address */
            tvb_memcpy(tvb, ipaddr, offset, 4);
            proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            /* display user name */
            str_len = tvb_strsize(tvb, offset);
            proto_tree_add_item( tree, hf_socks_username, tvb, offset, str_len, ENC_ASCII|ENC_NA);
            offset += str_len;

            if ( ipaddr[0] == 0 && ipaddr[1] == 0 &&
                 ipaddr[2] == 0 && ipaddr[3] != 0) {
                /* 0.0.0.x , where x!=0 means v4a support */
                str_len = tvb_strsize(tvb, offset);
                proto_tree_add_item( tree, hf_v4a_dns_name, tvb, offset, str_len, ENC_ASCII|ENC_NA);
            }
            break;
        default:
            break;
        }
    } else {
        /* Server side */
        switch (state_info->server)
        {
        case serverStart:
            proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
                            /* Do results code */
            proto_tree_add_item( tree, hf_socks_results_4, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;

                            /* Do remote port */
            proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
                            /* Do remote address */
            proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
            break;
        default:
            break;
        }
    }
}
static void
dissect_sapenqueue_conn_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint8 opcode){
	proto_item *conn_admin = NULL;
	proto_tree *conn_admin_tree = NULL;

	conn_admin = proto_tree_add_item(tree, hf_sapenqueue_conn_admin, tvb, offset, -1, FALSE);
	conn_admin_tree = proto_item_add_subtree(conn_admin, ett_sapenqueue);

	switch (opcode){
		case 0x01:		/* Parameter Request */
		case 0x02:{		/* Parameter Response */
			gint name_length_remaining = 0;
			guint8 length = 0, total_length = 0;
			guint32 count = 0, id = 0, name_length = 0;
			proto_item *params = NULL, *param = NULL;
			proto_tree *params_tree = NULL, *param_tree = NULL;

			count = tvb_get_ntohl(tvb, offset);
	        proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params_count, tvb, offset, 4, FALSE); offset += 4;

	        params = proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params, tvb, offset, 1, FALSE);
	        params_tree = proto_item_add_subtree(params, ett_sapenqueue);

	        while (count > 0 && tvb_offset_exists(tvb, offset)){
	        	/* As we don't have the right size yet, start with 1 byte */
	        	param = proto_tree_add_item(params_tree, hf_sapenqueue_conn_admin_param, tvb, offset, 1, FALSE);
	        	param_tree = proto_item_add_subtree(param, ett_sapenqueue);

	        	id = tvb_get_ntohl(tvb, offset);
	        	proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_id, tvb, offset, 4, FALSE); offset += 4;
	        	length = 4;

	        	if (id == 0x03){	/* Set Name parameter */
	        		name_length = tvb_strsize(tvb, offset);
	        		if (name_length > 0) {
	        			proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_name, tvb, offset, name_length, FALSE); offset += name_length;
	        			length += name_length;
	        		}

				} else if (id == 0x04) {  /* No support parameter */
					/* This parameter appears to have more fields only for responses */
					if (opcode == 0x02) {
						proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4;
						length += 4;
					}

	        	} else if (id == 0x06){  /* Set Unicode Support Parameter */
	        		name_length = tvb_get_ntohl(tvb, offset);
	        		proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_len, tvb, offset, 4, FALSE); offset += 4;

	        		/* If the reported length is not correct, use the remaining of the packet as length */
	        		name_length_remaining = tvb_captured_length_remaining(tvb, offset);
	        		if (name_length_remaining < 0){
	        			expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_offset);
	        			break;
	        		}
	        		if ((guint32)name_length_remaining < name_length) {
	        			name_length = (guint32)name_length_remaining;
        				expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_length);
	        		}

	        		proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, name_length, FALSE); offset += name_length;
					length += 4 + name_length;
				} else {
					/* The rest of the parameters have an integer value field */
					proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4;
					length += 4;
	        	}

	        	/* Set the right size for the parameter tree */
	        	proto_item_set_len(param, length);

	        	count -= 1;
	        	total_length += length;
	        }

	        proto_item_set_len(params, total_length);

			break;
		}
	}

}
Exemple #25
0
static void dissect_tftp_message(tftp_conv_info_t *tftp_info,
                                 tvbuff_t *tvb, packet_info *pinfo,
                                 proto_tree *tree)
{
  proto_tree *tftp_tree;
  proto_item *ti;
  gint        offset    = 0;
  guint16     opcode;
  guint16     bytes;
  guint16     blocknum;
  guint       i1;
  guint16     error;
  tvbuff_t    *data_tvb = NULL;

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

  /* Protocol root */
  ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA);
  tftp_tree = proto_item_add_subtree(ti, ett_tftp);

  /* Opcode */
  opcode = tvb_get_ntohs(tvb, offset);
  proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb, offset, 2, opcode);
  col_add_str(pinfo->cinfo, COL_INFO,
              val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)"));
  offset += 2;

  /* read and write requests contain file names
     for other messages, we add the filenames from the conversation */
  if (opcode!=TFTP_RRQ && opcode!=TFTP_WRQ) {
    if (tftp_info->source_file) {
      ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb,
          0, 0, tftp_info->source_file);
      PROTO_ITEM_SET_GENERATED(ti);
    }

    if (tftp_info->destination_file) {
      ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb,
          0, 0, tftp_info->destination_file);
      PROTO_ITEM_SET_GENERATED(ti);
    }
  }

  switch (opcode) {

  case TFTP_RRQ:
    i1 = tvb_strsize(tvb, offset);
    proto_tree_add_item(tftp_tree, hf_tftp_source_file,
                        tvb, offset, i1, ENC_ASCII|ENC_NA);

    tftp_info->source_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII);
    /* we either have a source file name (for read requests) or a
       destination file name (for write requests) 
       when we set one of the names, we clear the other */
    tftp_info->destination_file = NULL;

    col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
                    tvb_format_stringzpad(tvb, offset, i1));

    offset += i1;

    i1 = tvb_strsize(tvb, offset);
    proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
                        tvb, offset, i1, ENC_ASCII|ENC_NA);

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
                    tvb_format_stringzpad(tvb, offset, i1));

    offset += i1;

    tftp_dissect_options(tvb, pinfo,  offset, tftp_tree,
                         opcode, tftp_info);
    break;

  case TFTP_WRQ:
    i1 = tvb_strsize(tvb, offset);
    proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
                        tvb, offset, i1, ENC_ASCII|ENC_NA);

    tftp_info->destination_file =
      tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII);
    tftp_info->source_file = NULL; /* see above */

    col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
                    tvb_format_stringzpad(tvb, offset, i1));

    offset += i1;

    i1 = tvb_strsize(tvb, offset);
    proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
                        tvb, offset, i1, ENC_ASCII|ENC_NA);

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
                    tvb_format_stringzpad(tvb, offset, i1));

    offset += i1;

    tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                         opcode,  tftp_info);
    break;

  case TFTP_INFO:
    tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                         opcode,  tftp_info);
    break;

  case TFTP_DATA:
    blocknum = tvb_get_ntohs(tvb, offset);
    proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
                        blocknum);

    /* Sequence analysis on blocknums (first pass only) */
    if (!pinfo->fd->flags.visited) {
      if (blocknum > tftp_info->next_block_num) {
        /* There is a gap.  Don't try to recover from this. */
        tftp_info->next_block_num = blocknum + 1;
        tftp_info->blocks_missing = TRUE;
        /* TODO: add info to a result table for showing expert info in later passes */
      }
      else if (blocknum == tftp_info->next_block_num) {
        /* OK, inc what we expect next */
        tftp_info->next_block_num++;
      }
    }
    offset += 2;

    /* Show number of bytes in this block, and whether it is the end of the file */
    bytes = tvb_reported_length_remaining(tvb, offset);
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s",
                    blocknum,
                    (bytes < tftp_info->blocksize)?" (last)":"" );

    /* Show data in tree */
    if (bytes > 0) {
      data_tvb = tvb_new_subset(tvb, offset, -1, bytes);
      call_dissector(data_handle, data_tvb, pinfo, tree);
    }

    /* If Export Object tap is listening, need to accumulate blocks info list
       to send to tap. But if already know there are blocks missing, there is no
       point in trying. */
    if (have_tap_listener(tftp_eo_tap) && !tftp_info->blocks_missing) {
      file_block_t *block;

      if (blocknum == 1) {
        /* Reset data for this conversation, freeing any accumulated blocks! */
        cleanup_tftp_blocks(tftp_info);
        tftp_info->next_tap_block_num = 1;
      }

      if (blocknum != tftp_info->next_tap_block_num) {
        /* Ignore.  Could be missing frames, or just clicking previous frame */
        return;
      }

      if (bytes > 0) {
        /* Create a block for this block */
        block = (file_block_t*)g_malloc(sizeof(file_block_t));
        block->length = bytes;
        block->data = tvb_memdup(NULL, data_tvb, 0, bytes);

        /* Add to the end of the list (does involve traversing whole list..) */
        tftp_info->block_list = g_slist_append(tftp_info->block_list, block);
        tftp_info->file_length += bytes;

        /* Look for next blocknum next time */
        tftp_info->next_tap_block_num++;
      }

      /* Tap export object only when reach end of file */
      if (bytes < tftp_info->blocksize) {
        tftp_eo_t        *eo_info;

        /* If don't have a filename, won't tap file info */
        if ((tftp_info->source_file == NULL) && (tftp_info->destination_file == NULL)) {
            cleanup_tftp_blocks(tftp_info);
            return;
        }

        /* Create the eo_info to pass to the listener */
        eo_info = wmem_new(wmem_packet_scope(), tftp_eo_t);

        /* Set filename */
        if (tftp_info->source_file) {
          eo_info->filename = g_strdup(tftp_info->source_file);
        }
        else if (tftp_info->destination_file) {
          eo_info->filename = g_strdup(tftp_info->destination_file);
        }

        /* Send block list, which will be combined and freed at tap. */
        eo_info->payload_len = tftp_info->file_length;
        eo_info->pkt_num = blocknum;
        eo_info->block_list = tftp_info->block_list;

        /* Send to tap */
        tap_queue_packet(tftp_eo_tap, pinfo, eo_info);

        /* Have sent, so forget list of blocks, and only pay attention if we
           get back to the first block again. */
        tftp_info->block_list = NULL;
        tftp_info->next_tap_block_num = 1;
      }
    }
    break;

  case TFTP_ACK:
    blocknum = tvb_get_ntohs(tvb, offset);
    proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
                        blocknum);

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i",
                    blocknum);
    break;

  case TFTP_ERROR:
    error = tvb_get_ntohs(tvb, offset);
    proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2,
                        error);

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s",
                    val_to_str(error, tftp_error_code_vals, "Unknown (%u)"));

    offset += 2;

    i1 = tvb_strsize(tvb, offset);
    proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
                        i1, ENC_ASCII|ENC_NA);

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s",
                    tvb_format_stringzpad(tvb, offset, i1));

    expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range);
    break;

  case TFTP_OACK:
    tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                         opcode, tftp_info);
    break;

  default:
    proto_tree_add_item(tftp_tree, hf_tftp_data, tvb, offset, -1, ENC_NA);
    break;

  }
}
static void
dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	guint8 cmd;
	proto_tree *tree = NULL;
	proto_item *item = NULL;
	guint32 periodicity;
	guint8 *host_name;
	gint namelen;
	guint8 server_count;
	guint8 os_major_ver, os_minor_ver;
	const gchar *windows_version;
	int i;
	guint32 uptime;

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

	cmd = tvb_get_guint8(tvb, offset);

	/* Put in something, and replace it later */
	col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));


	item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_browse);

	/* command */
	proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
	offset += 1;

	switch (cmd) {
	case BROWSE_DOMAIN_ANNOUNCEMENT:
	case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
	case BROWSE_HOST_ANNOUNCE: {
		/* update count */
		proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* periodicity (in milliseconds) */
		periodicity = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 4,
		    periodicity,
		    "%s",
		    time_msecs_to_str(wmem_packet_scope(), periodicity));
		offset += 4;

		/* server name */
		host_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, HOST_NAME_LEN, ENC_CP437|ENC_NA);
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
		proto_tree_add_string_format(tree, hf_server_name,
			tvb, offset, HOST_NAME_LEN,
			host_name,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
				"Domain/Workgroup: %s":
				"Host Name: %s",
			host_name);
		offset += HOST_NAME_LEN;

		/* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
		os_major_ver = tvb_get_guint8(tvb, offset);
		os_minor_ver = tvb_get_guint8(tvb, offset+1);

		SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
		proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version);

		/* OS major version */
		proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* OS minor version */
		proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* server type flags */
		offset = dissect_smb_server_type_flags(
			tvb, offset, pinfo, tree, NULL, TRUE);

		if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) {
			/*
			 * Network Monitor claims this is a "Comment
			 * Pointer".  I don't believe it.
			 *
			 * It's not a browser protocol major/minor
			 * version number, and signature constant,
			 * however.
			 */
			proto_tree_add_item(tree, hf_mysterious_field, tvb, offset, 4, ENC_LITTLE_ENDIAN);
			offset += 4;
		} else {
			/* browser protocol major version */
			proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			offset += 1;

			/* browser protocol minor version */
			proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			offset += 1;

			/* signature constant */
			proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, ENC_LITTLE_ENDIAN);
			offset += 2;
		}

		/* master browser server name or server comment */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
			    hf_mb_server_name : hf_server_comment,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;
	}
	case BROWSE_REQUEST_ANNOUNCE: {
		guint8 *computer_name;

		/* unused/unknown flags */
		proto_tree_add_item(tree, hf_unused_flags,
			tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* name of computer to which to send reply */
		computer_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &namelen, ENC_ASCII);
		proto_tree_add_string(tree, hf_response_computer_name,
			tvb, offset, namelen, computer_name);
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", computer_name);
		break;
	}

	case BROWSE_ELECTION_REQUEST:
		/* election version */
		proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* criterion */
		dissect_election_criterion(tvb, tree, offset);
		offset += 4;

		/* server uptime */
		uptime = tvb_get_letohl(tvb, offset);
		proto_tree_add_uint_format_value(tree, hf_server_uptime,
		    tvb, offset, 4, uptime,
		    "%s",
		    time_msecs_to_str(wmem_packet_scope(), uptime));
		offset += 4;

		/* next 4 bytes must be zero */
		offset += 4;

		/* server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_server_name,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;

	case BROWSE_BACKUP_LIST_REQUEST:
		/* backup list requested count */
		proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		break;

	case BROWSE_BACKUP_LIST_RESPONSE:
		/* backup list requested count */
		server_count = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1,
		    server_count);
		offset += 1;

		/* backup requested token */
		proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		/* backup server names */
		for (i = 0; i < server_count; i++) {
			namelen = tvb_strsize(tvb, offset);
			proto_tree_add_item(tree, hf_backup_server,
				tvb, offset, namelen, ENC_ASCII|ENC_NA);
			offset += namelen;
		}
		break;

	case BROWSE_MASTER_ANNOUNCEMENT:
		/* master browser server name */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_mb_server_name,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;

	case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: {
		static const int * flags[] = {
			&hf_mb_reset_demote,
			&hf_mb_reset_flush,
			&hf_mb_reset_stop,
			NULL
		};

		proto_tree_add_bitmask(tree, tvb, offset, hf_mb_reset_command, ett_browse_reset_cmd_flags, flags, ENC_NA);
		break;
	}

	case BROWSE_BECOME_BACKUP:
		/* name of browser to promote */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree, hf_browser_to_promote,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		break;
	}
}
/*
 * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't
 * the same as browser announcements sent to \MAILSLOT\BROWSE.
 * Was that an older version of the protocol?
 *
 * The document at
 *
 *	http://www.samba.org/samba/ftp/specs/brow_rev.txt
 *
 * gives both formats of host announcement packets, saying that
 * "[The first] format seems wrong", that one being what appears to
 * show up in \MAILSLOT\LANMAN packets, and that "[The second one]
 * may be better", that one being what appears to show up in
 * \MAILSLOT\BROWSE packets.
 *
 * XXX - what other browser packets go out to that mailslot?
 */
static void
dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	guint8 cmd;
	proto_tree *tree = NULL;
	proto_item *item = NULL;
	guint32 periodicity;
	const guint8 *host_name;
	guint8 os_major_ver, os_minor_ver;
	const gchar *windows_version;
	guint namelen;

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

	cmd = tvb_get_guint8(tvb, offset);

	/* Put in something, and replace it later */
	col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));

	if (parent_tree) {
		item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);

		tree = proto_item_add_subtree(item, ett_browse);
	}

	/* command */
	proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
	offset += 1;

	switch (cmd) {
	case BROWSE_DOMAIN_ANNOUNCEMENT:
	case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
	case BROWSE_HOST_ANNOUNCE:
		/* update count */
		proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* server type flags */
		offset = dissect_smb_server_type_flags(
			tvb, offset, pinfo, tree, NULL, TRUE);

		/* OS version string (See "OSVERSIONINFO Structure" on MSDN) */
		os_major_ver = tvb_get_guint8(tvb, offset);
		os_minor_ver = tvb_get_guint8(tvb, offset+1);

		SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
		proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version);

		/* OS major version */
		proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* OS minor version */
		proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		offset += 1;

		/* periodicity (in seconds; convert to milliseconds) */
		periodicity = tvb_get_letohs(tvb, offset)*1000;
		proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 2,
		    periodicity,
		    "%s",
		    time_msecs_to_str(wmem_packet_scope(), periodicity));
		offset += 2;

		/* server name */
		host_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &namelen, ENC_CP437|ENC_NA);
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);

		proto_tree_add_item(tree, hf_server_name,
			tvb, offset, namelen, ENC_ASCII|ENC_NA);
		offset += namelen;

		/* master browser server name or server comment */
		namelen = tvb_strsize(tvb, offset);
		proto_tree_add_item(tree,
			(cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
			    hf_mb_server_name : hf_server_comment,
			tvb, offset, namelen, ENC_CP437|ENC_NA);
		break;
	}
}
Exemple #28
0
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree,
                                 pgsql_conn_data_t *conv_data)
{
    guchar c;
    gint i, siz;
    char *s;
    proto_tree *shrub;
    gint32 data_length;

    switch (type) {
    /* Password, SASL or GSSAPI Response, depending on context */
    case 'p':
        switch(conv_data->auth_state) {

            case PGSQL_AUTH_SASL_REQUESTED:
                /* SASLInitResponse */
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA);
                n += siz;
                proto_tree_add_item_ret_int(tree, hf_sasl_auth_data_length, tvb, n, 4, ENC_BIG_ENDIAN, &data_length);
                n += 4;
                if (data_length) {
                    proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, data_length, ENC_NA);
                    n += data_length;
                }
                break;

            case PGSQL_AUTH_SASL_CONTINUE:
                proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-4, ENC_NA);
                break;

            case PGSQL_AUTH_GSSAPI_SSPI_DATA:
                proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-4, ENC_NA);
                break;

            default:
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA);
                break;
        }
        break;

    /* Simple query */
    case 'Q':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Parse */
    case 'P':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Bind */
    case 'B':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Execute */
    case 'E':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohl(tvb, n);
        if (i == 0)
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows");
        else
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i);
        break;

    /* Describe, Close */
    case 'D':
    case 'C':
        c = tvb_get_guint8(tvb, n);
        if (c == 'P')
            i = hf_portal;
        else
            i = hf_statement;

        n += 1;
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, i, tvb, n, siz, s);
        break;

    /* Messages without a type identifier */
    case '\0':
        i = tvb_get_ntohl(tvb, n);
        n += 4;
        length -= n;
        switch (i) {
        /* Startup message */
        case 196608:
            proto_tree_add_item(tree, hf_version_major, tvb, n-4, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_version_minor, tvb, n-2, 2, ENC_BIG_ENDIAN);
            while ((signed)length > 0) {
                siz = tvb_strsize(tvb, n);
                length -= siz;
                if ((signed)length <= 0) {
                    break;
                }
                proto_tree_add_item(tree, hf_parameter_name,  tvb, n,       siz, ENC_ASCII|ENC_NA);
                i = tvb_strsize(tvb, n+siz);
                proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i,   ENC_ASCII|ENC_NA);
                length -= i;

                n += siz+i;
                if (length == 1 && tvb_get_guint8(tvb, n) == 0)
                    break;
            }
            break;

        /* SSL request */
        case 80877103:
            /* Next reply will be a single byte. */
            conv_data->ssl_requested = TRUE;
            break;

        /* Cancellation request */
        case 80877102:
            proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
            break;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Copy failure */
    case 'f':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Function call */
    case 'F':
        proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
        break;
    }
}
Exemple #29
0
static void dissect_tftp_message(tftp_conv_info_t *tftp_info,
				 tvbuff_t *tvb, packet_info *pinfo,
				 proto_tree *tree)
{
	proto_tree	 *tftp_tree = NULL;
	proto_item	 *ti;
	gint		 offset = 0;
	guint16		 opcode;
	guint16		 bytes;
	guint16		 blocknum;
	guint		 i1;
	guint16	         error;

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

	opcode = tvb_get_ntohs(tvb, offset);

	col_add_str(pinfo->cinfo, COL_INFO,
		    val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)"));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA);
	  tftp_tree = proto_item_add_subtree(ti, ett_tftp);

	  if (tftp_info->source_file) {
	    ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb,
				       0, 0, tftp_info->source_file);
	    PROTO_ITEM_SET_GENERATED(ti);
	  }

	  if (tftp_info->destination_file) {
	    ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb,
				       0, 0, tftp_info->destination_file);
	    PROTO_ITEM_SET_GENERATED(ti);
	  }

	  proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb,
			      offset, 2, opcode);
	}
	offset += 2;

	switch (opcode) {

	case TFTP_RRQ:
	  i1 = tvb_strsize(tvb, offset);
	  proto_tree_add_item(tftp_tree, hf_tftp_source_file,
			      tvb, offset, i1, ENC_ASCII|ENC_NA);

	  tftp_info->source_file = tvb_get_string(wmem_file_scope(), tvb, offset, i1);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
			  tvb_format_stringzpad(tvb, offset, i1));

	  offset += i1;

	  i1 = tvb_strsize(tvb, offset);
	  proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
			      tvb, offset, i1, ENC_ASCII|ENC_NA);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
			  tvb_format_stringzpad(tvb, offset, i1));

	  offset += i1;

	  tftp_dissect_options(tvb, pinfo,  offset, tftp_tree,
			       opcode, tftp_info);
	  break;

	case TFTP_WRQ:
	  i1 = tvb_strsize(tvb, offset);
	  proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
			      tvb, offset, i1, ENC_ASCII|ENC_NA);

	  tftp_info->destination_file =
	    tvb_get_string(wmem_file_scope(), tvb, offset, i1);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
			  tvb_format_stringzpad(tvb, offset, i1));

	  offset += i1;

	  i1 = tvb_strsize(tvb, offset);
	  proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
			           tvb, offset, i1, ENC_ASCII|ENC_NA);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
			  tvb_format_stringzpad(tvb, offset, i1));

	  offset += i1;

	  tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
			       opcode,  tftp_info);
	  break;

	case TFTP_INFO:
	  tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
			       opcode,  tftp_info);
	  break;

	case TFTP_DATA:
	  blocknum = tvb_get_ntohs(tvb, offset);
	  proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
			      blocknum);

	  offset += 2;

	  bytes = tvb_reported_length_remaining(tvb, offset);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s",
			  blocknum,
			  (bytes < tftp_info->blocksize)?" (last)":"" );

	  if (bytes != 0) {
	    tvbuff_t *data_tvb = tvb_new_subset(tvb, offset, -1, bytes);
	    call_dissector(data_handle, data_tvb, pinfo, tree);
	  }
	  break;

	case TFTP_ACK:
	  blocknum = tvb_get_ntohs(tvb, offset);
	  proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
			      blocknum);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i",
			  blocknum);
	  break;

	case TFTP_ERROR:
	  error = tvb_get_ntohs(tvb, offset);
	  proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2,
			      error);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s",
			  val_to_str(error, tftp_error_code_vals, "Unknown (%u)"));

	  offset += 2;

	  i1 = tvb_strsize(tvb, offset);
	  proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
			      i1, ENC_ASCII|ENC_NA);

	  col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s",
			  tvb_format_stringzpad(tvb, offset, i1));

	  expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range);
	  break;

	case TFTP_OACK:
	  tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
			       opcode, tftp_info);
	  break;

	default:
	  proto_tree_add_text(tftp_tree, tvb, offset, -1,
			      "Data (%d bytes)", tvb_reported_length_remaining(tvb, offset));
	  break;

	}

  return;
}
Exemple #30
0
/* nopad == TRUE : Do not add any padding before this string
 * exactlen == TRUE : len contains the exact len of the string in bytes.
 * bc: pointer to variable with amount of data left in the byte parameters
 *   region
 */
const gchar *
get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
    gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
    guint16 *bcp)
{
  gchar *cur;
  const gchar *string;
  int string_len = 0;
  int copylen;
  gboolean overflow = FALSE;

  if (*bcp == 0) {
    /* Not enough data in buffer */
    return NULL;
  }
  if (useunicode) {
    if ((!nopad) && (*offsetp % 2)) {
      (*offsetp)++;   /* Looks like a pad byte there sometimes */
      (*bcp)--;
      if (*bcp == 0) {
        /* Not enough data in buffer */
        return NULL;
      }
    }
    if(exactlen){
      string_len = *len;
      if (string_len < 0) {
        /* This probably means it's a very large unsigned number; just set
           it to the largest signed number, so that we throw the appropriate
           exception. */
        string_len = INT_MAX;
      }
    }
    string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
  } else {
    if(exactlen){
      /*
       * The string we return must be null-terminated.
       */
      cur=ep_alloc(MAX_UNICODE_STR_LEN+3+1);
      copylen = *len;
      if (copylen < 0) {
        /* This probably means it's a very large unsigned number; just set
           it to the largest signed number, so that we throw the appropriate
           exception. */
        copylen = INT_MAX;
      }
      tvb_ensure_bytes_exist(tvb, *offsetp, copylen);
      if (copylen > MAX_UNICODE_STR_LEN) {
        copylen = MAX_UNICODE_STR_LEN;
        overflow = TRUE;
      }
      tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
      cur[copylen] = '\0';
      if (overflow)
        g_strlcat(cur, "...",MAX_UNICODE_STR_LEN+3+1);
      string_len = *len;
      string = cur;
    } else {
      string_len = tvb_strsize(tvb, *offsetp);
      string = tvb_get_ptr(tvb, *offsetp, string_len);
    }
  }
  *len = string_len;
  return string;
}