static void dissect_auto_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
        guint8 ver_type, rp_count;

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

        ver_type = tvb_get_guint8(tvb, 0);
        rp_count = tvb_get_guint8(tvb, 1);
        if (check_col(pinfo->cinfo, COL_INFO))
                col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%s) for %u RP%s",
                             val_to_str(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"),
                             val_to_str(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"),
                             rp_count, plurality(rp_count, "", "s"));

        if (tree) {
                proto_item *ti, *tv;
                proto_tree *auto_rp_tree, *ver_type_tree;
                int i, offset;
                guint16 holdtime;

                offset = 0;
                ti = proto_tree_add_item(tree, proto_auto_rp, tvb, offset, -1, FALSE);
                auto_rp_tree = proto_item_add_subtree(ti, ett_auto_rp);

                tv = proto_tree_add_text(auto_rp_tree, tvb, offset, 1, "Version: %s, Packet type: %s",
                                         val_to_str(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"),
                                         val_to_str(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"));
                ver_type_tree = proto_item_add_subtree(tv, ett_auto_rp_ver_type);
                proto_tree_add_uint(ver_type_tree, hf_auto_rp_version, tvb, offset, 1, ver_type);
                proto_tree_add_uint(ver_type_tree, hf_auto_rp_type, tvb, offset, 1, ver_type);
                offset++;

                proto_tree_add_uint(auto_rp_tree, hf_auto_rp_count, tvb, offset, 1, rp_count);
                offset++;

                holdtime = tvb_get_ntohs(tvb, offset);
                proto_tree_add_uint_format_value(auto_rp_tree, hf_auto_rp_holdtime, tvb, offset, 2, holdtime,
                                           "%u second%s", holdtime, plurality(holdtime, "", "s"));
                offset+=2;

                proto_tree_add_text(auto_rp_tree, tvb, offset, 4, "Reserved: 0x%x", tvb_get_ntohs(tvb, offset));
                offset+=4;

                for (i = 0; i < rp_count; i++)
                        offset = do_auto_rp_map(tvb, offset, auto_rp_tree);

                if (tvb_offset_exists(tvb, offset))
                        proto_tree_add_text(tree, tvb, offset, -1, "Trailing junk");
        }

        return;
}
Esempio n. 2
0
static void dissect_auto_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint8 ver_type, rp_count;

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

    ver_type = tvb_get_guint8(tvb, 0);
    rp_count = tvb_get_guint8(tvb, 1);
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%s) for %u RP%s",
                 val_to_str_const(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"),
                 val_to_str_const(hi_nibble(ver_type), auto_rp_ver_vals,  "Unknown"),
                 rp_count, plurality(rp_count, "", "s"));

    if (tree) {
        proto_item *ti;
        proto_tree *auto_rp_tree, *ver_type_tree;
        int         i, offset;
        guint16     holdtime;

        offset = 0;
        ti = proto_tree_add_item(tree, proto_auto_rp, tvb, offset, -1, ENC_NA);
        auto_rp_tree = proto_item_add_subtree(ti, ett_auto_rp);

        ver_type_tree = proto_tree_add_subtree_format(auto_rp_tree, tvb, offset, 1,
                        ett_auto_rp_ver_type, NULL, "Version: %s, Packet type: %s",
                        val_to_str_const(hi_nibble(ver_type), auto_rp_ver_vals,  "Unknown"),
                        val_to_str_const(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"));
        proto_tree_add_uint(ver_type_tree, hf_auto_rp_version, tvb, offset, 1, ver_type);
        proto_tree_add_uint(ver_type_tree, hf_auto_rp_type, tvb, offset, 1, ver_type);
        offset++;

        proto_tree_add_uint(auto_rp_tree, hf_auto_rp_count, tvb, offset, 1, rp_count);
        offset++;

        holdtime = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint_format_value(auto_rp_tree, hf_auto_rp_holdtime, tvb, offset, 2, holdtime,
                                         "%u second%s", holdtime, plurality(holdtime, "", "s"));
        offset+=2;

        proto_tree_add_item(auto_rp_tree, hf_auto_rp_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset+=4;

        for (i = 0; i < rp_count; i++)
            offset = do_auto_rp_map(tvb, offset, auto_rp_tree);

        if (tvb_reported_length_remaining(tvb, offset) > 0)
            proto_tree_add_item(tree, hf_auto_rp_trailing_junk, tvb, offset, -1, ENC_NA);
    }

    return;
}
void FileSetDialog::addFile(fileset_entry *entry) {
    QString created;
    QString modified;
    QString dir_name;
    QString elided_dir_name;
    QTreeWidgetItem *entry_item;
    gchar *size_str;

    if (!entry) {
        setWindowTitle(wsApp->windowTitleString(tr("No files in Set")));
        fs_ui_->directoryLabel->setText(tr("No capture loaded"));
        fs_ui_->directoryLabel->setEnabled(false);
        return;
    }

    created = nameToDate(entry->name);
    if(created.length() < 1) {
        /* if this file doesn't follow the file set pattern, */
        /* use the creation time of that file */
        /* http://en.wikipedia.org/wiki/ISO_8601 */
        created = QDateTime::fromTime_t(entry->ctime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss");
    }

    modified = QDateTime::fromTime_t(entry->mtime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss");

    size_str = format_size(entry->size, format_size_unit_bytes|format_size_prefix_si);

    entry_item = new QTreeWidgetItem(fs_ui_->fileSetTree);
    entry_item->setToolTip(0, QString(tr("Open this capture file")));
    entry_item->setData(0, Qt::UserRole, qVariantFromValue(entry));

    entry_item->setText(0, entry->name);
    entry_item->setText(1, created);
    entry_item->setText(2, modified);
    entry_item->setText(3, size_str);
    g_free(size_str);
    // Not perfect but better than nothing.
    entry_item->setTextAlignment(3, Qt::AlignRight);

    setWindowTitle(wsApp->windowTitleString(tr("%1 File%2 in Set")
                                            .arg(fs_ui_->fileSetTree->topLevelItemCount())
                                            .arg(plurality(fs_ui_->fileSetTree->topLevelItemCount(), "", "s"))));

    dir_name = fileset_get_dirname();
    fs_ui_->directoryLabel->setText(dir_name);
    fs_ui_->directoryLabel->setUrl(QUrl::fromLocalFile(dir_name).toString());
    fs_ui_->directoryLabel->setEnabled(true);

    if(entry->current) {
        fs_ui_->fileSetTree->setCurrentItem(entry_item);
    }

    if (close_button_)
        close_button_->setEnabled(true);

    fs_ui_->fileSetTree->addTopLevelItem(entry_item);
    for (int i = 0; i < fs_ui_->fileSetTree->columnCount(); i++)
        fs_ui_->fileSetTree->resizeColumnToContents(i);
    fs_ui_->fileSetTree->setFocus();
}
Esempio n. 4
0
static void
dissect_xtp_data(tvbuff_t *tvb, proto_tree *tree, guint32 offset, gboolean have_btag) {
	guint32 len = tvb_length_remaining(tvb, offset);
	proto_item *ti;
	proto_tree *xtp_subtree;
	guint64 btag;

	ti = proto_tree_add_text(tree, tvb, offset, len, "Data Segment");
	xtp_subtree = proto_item_add_subtree(ti, ett_xtp_data);

	if (have_btag) {
		btag = tvb_get_ntohl(tvb, offset);
		btag <<= 32;
		btag += tvb_get_ntohl(tvb, offset+4);
		proto_tree_add_uint64(xtp_subtree, hf_xtp_btag, tvb, offset, 8, btag);
		offset += 8;
		len -= 8;
	}

	proto_tree_add_text(xtp_subtree, tvb, offset, len,
		"Data (%u byte%s)", len,
		plurality(len, "", "s"));

	return;
}
static void
dissect_diagnostic_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  guint16 diag_info_length;

  diag_info_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
  proto_tree_add_item(parameter_tree, hf_diag_info, parameter_tvb, PARAMETER_VALUE_OFFSET, diag_info_length, ENC_NA);
  proto_item_append_text(parameter_item, " (%u byte%s)", diag_info_length, plurality(diag_info_length, "", "s"));
}
static gint xdmcp_add_bytes(proto_tree *tree, const char *text,
		     tvbuff_t *tvb, gint offset)
{
  guint len;
  len = tvb_get_ntohs(tvb, offset);
  proto_tree_add_text(tree, tvb, offset, len+2,
		      "%s (%u byte%s)", text, len, plurality(len, "", "s"));
  return len+2;
}
Esempio n. 7
0
static void
dissect_heartbeat_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  guint16 heartbeat_data_length;

  heartbeat_data_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
  proto_tree_add_item(parameter_tree, hf_heartbeat_data, parameter_tvb, HEARTBEAT_DATA_OFFSET, heartbeat_data_length, NETWORK_BYTE_ORDER);
  proto_item_append_text(parameter_item, " (%u byte%s)", heartbeat_data_length, plurality(heartbeat_data_length, "", "s"));
}
Esempio n. 8
0
static void
dissect_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  guint16 cookie_length;

  cookie_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
  if (cookie_length > 0)
    proto_tree_add_item(parameter_tree, hf_cookie, parameter_tvb, COOKIE_OFFSET, cookie_length, ENC_NA);
  proto_item_append_text(parameter_item, " (%u byte%s)", cookie_length, plurality(cookie_length, "", "s"));
}
Esempio n. 9
0
/* Capture child told us how many dropped packets it counted.
 */
void
capture_input_drops(capture_session *cap_session, guint32 dropped)
{
  g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "%u packet%s dropped", dropped, plurality(dropped, "", "s"));

  g_assert(cap_session->state == CAPTURE_RUNNING);

  cf_set_drops_known((capture_file *)cap_session->cf, TRUE);
  cf_set_drops((capture_file *)cap_session->cf, dropped);
}
Esempio n. 10
0
void
decode_content(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
    gint payload_len;
    proto_tree_add_item(tree, hf_scribe_content_type, tvb, offset, 2, FALSE);
    offset += 2;
    payload_len = tvb_reported_length_remaining(tvb, offset);
    proto_tree_add_text(tree, tvb, offset, payload_len,
				    "Payload (%u byte%s)", payload_len,
				    plurality(payload_len, "", "s"));
}
Esempio n. 11
0
void pwc_item_append_text_n_items(proto_item* item, const int n, const char * const item_text)
{
	if (item != NULL)
	{
		if (n >=0)
		{
			proto_item_append_text(item, ", %d %s%s", n, item_text, plurality(n,"","s"));
		}
	}
	return;
}
static void
dissect_sccpmg_unknown_message(tvbuff_t *message_tvb, proto_tree *sccpmg_tree)
{
	guint32 message_length;

	message_length = tvb_length(message_tvb);

	proto_tree_add_text(sccpmg_tree, message_tvb, 0, message_length,
			    "Unknown message (%u byte%s)", message_length,
			    plurality(message_length, "", "s"));
}
Esempio n. 13
0
static int
dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, void* data)
{
    int bytes;
    proto_item *ti;
    proto_tree *media_tree = 0;
    heur_dtbl_entry_t *hdtbl_entry;

    if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, data)) {
        return tvb_reported_length(tvb);
    }

    /* Add media type to the INFO column if it is visible */
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", (pinfo->match_string) ? pinfo->match_string : "");

    if (tree) {
        if ( (bytes = tvb_reported_length(tvb)) > 0 )
        {
            ti = proto_tree_add_item(tree, proto_media, tvb, 0, -1, ENC_NA);
            media_tree = proto_item_add_subtree(ti, ett_media);

            if (data) {
                /* The media type has parameters */
                proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes,
                    NULL, "%s; %s (%d byte%s)",
                    pinfo->match_string, (char *)data,
                    bytes, plurality(bytes, "", "s"));
            } else {
                /* The media type has no parameters */
                proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes,
                    NULL, "%s (%d byte%s)",
                    pinfo->match_string ? pinfo->match_string : "",
                    bytes, plurality(bytes, "", "s"));
            }
        }
    }

    return tvb_reported_length(tvb);
}
Esempio n. 14
0
static void
dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree)
{
    int bytes;
    proto_item *ti;
    proto_tree *media_tree = 0;

    if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) {
        return;
    }

    /* Add media type to the INFO column if it is visible */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", (pinfo->match_string) ? pinfo->match_string : "");
    }

    if (tree) {
        if ( (bytes = tvb_length(tvb)) > 0 )
        {
            ti = proto_tree_add_item(tree, proto_media, tvb, 0, -1, ENC_NA);
            media_tree = proto_item_add_subtree(ti, ett_media);

            if (pinfo->private_data) {
                /* The media type has parameters */
                proto_tree_add_text(media_tree, tvb, 0, bytes,
                    "Media Type: %s; %s (%d byte%s)",
                    pinfo->match_string, (char *)pinfo->private_data,
                    bytes, plurality(bytes, "", "s"));
            } else {
                /* The media type has no parameters */
                proto_tree_add_text(media_tree, tvb, 0, bytes,
                    "Media Type: %s (%d byte%s)",
                    pinfo->match_string ? pinfo->match_string : "",
                    bytes, plurality(bytes, "", "s"));
            }
        }
    }
}
/*
 * Handles one Auto-RP map entry. Returns the new offset.
 */
static int do_auto_rp_map(tvbuff_t *tvb, int offset, proto_tree *auto_rp_tree)
{
        proto_item *ti;
        proto_tree *map_tree;
        guint8 group_count;
        guint32 rp_addr;      /* In network byte order */
        int i;

        rp_addr = tvb_get_ipv4(tvb, offset);
        group_count = tvb_get_guint8(tvb, offset + 5);

                               /* sizeof map header + n * sizeof encoded group addresses */
        ti = proto_tree_add_text(auto_rp_tree, tvb, offset, 6 + group_count * 6,
                                 "RP %s: %u group%s", ip_to_str((void *)&rp_addr),
                                 group_count, plurality(group_count, "", "s"));
        map_tree = proto_item_add_subtree(ti, ett_auto_rp_map);

        proto_tree_add_ipv4(map_tree, hf_auto_rp_rp_addr, tvb, offset, 4, rp_addr);
        offset += 4;
        proto_tree_add_uint(map_tree, hf_auto_rp_pim_ver, tvb, offset, 1, tvb_get_guint8(tvb, offset));
        offset++;
        proto_tree_add_text(map_tree, tvb, offset, 1, "Number of groups this RP maps to: %u", group_count);
        offset++;

        for (i = 0; i < group_count; i++) {
                proto_item *gi;
                proto_tree *grp_tree;
                guint8 sign, mask_len;
                guint32 group_addr;     /* In network byte order */

                sign = tvb_get_guint8(tvb, offset);
                mask_len = tvb_get_guint8(tvb, offset + 1);
                group_addr = tvb_get_ipv4(tvb, offset + 2);
                gi = proto_tree_add_text(map_tree, tvb, offset, 6, "Group %s/%u (%s)",
                                         ip_to_str((void *)&group_addr), mask_len,
                                         val_to_str(sign&AUTO_RP_SIGN_MASK, auto_rp_mask_sign_vals, ""));
                grp_tree = proto_item_add_subtree(gi, ett_auto_rp_group);

                proto_tree_add_uint(grp_tree, hf_auto_rp_prefix_sgn, tvb, offset, 1, sign);
                offset++;
                proto_tree_add_uint(grp_tree, hf_auto_rp_mask_len, tvb, offset, 1, mask_len);
                offset++;
                proto_tree_add_ipv4(grp_tree, hf_auto_rp_group_prefix, tvb, offset, 4, group_addr);
                offset += 4;

        }

        return offset;
}
Esempio n. 16
0
static void
dissect_integer_range_interface_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  guint16 number_of_ranges, range_number;
  gint offset;

  number_of_ranges = (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / INTERVAL_LENGTH;
  offset = PARAMETER_VALUE_OFFSET;
  for(range_number = 1; range_number <= number_of_ranges; range_number++) {
    proto_tree_add_item(parameter_tree, hf_interface_range_start, parameter_tvb, offset + START_OFFSET, START_LENGTH, NETWORK_BYTE_ORDER);
    proto_tree_add_item(parameter_tree, hf_interface_range_end,   parameter_tvb, offset + END_OFFSET,   END_LENGTH,   NETWORK_BYTE_ORDER);
    offset += INTERVAL_LENGTH;
  };

  proto_item_append_text(parameter_item, " (%u range%s)", number_of_ranges, plurality(number_of_ranges, "", "s"));
}
static void
dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, proto_item *parameter_item, packet_info *pinfo, proto_tree *tree)
{
  guint16 protocol_data_length;
  tvbuff_t *protocol_data_tvb;

  protocol_data_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
  protocol_data_tvb    = tvb_new_subset_length(parameter_tvb, PROTOCOL_DATA_OFFSET, protocol_data_length);
  if(dpnss_handle){
    call_dissector(dpnss_handle, protocol_data_tvb, pinfo, tree);
    return;
  }

  call_dissector(data_handle, protocol_data_tvb, pinfo, tree);

  proto_item_append_text(parameter_item, " (%u byte%s)", protocol_data_length, plurality(protocol_data_length, "", "s"));
}
Esempio n. 18
0
/*
 * Handles one Auto-RP map entry. Returns the new offset.
 */
static int do_auto_rp_map(tvbuff_t *tvb, int offset, proto_tree *auto_rp_tree)
{
    proto_tree *map_tree;
    guint8      group_count;
    int         i;

    group_count = tvb_get_guint8(tvb, offset + 5);

    /* sizeof map header + n * sizeof encoded group addresses */
    map_tree = proto_tree_add_subtree_format(auto_rp_tree, tvb, offset, 6 + group_count * 6,
               ett_auto_rp_map, NULL,
               "RP %s: %u group%s", tvb_ip_to_str(tvb, offset),
               group_count, plurality(group_count, "", "s"));

    proto_tree_add_item(map_tree, hf_auto_rp_rp_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;
    proto_tree_add_item(map_tree, hf_auto_rp_pim_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset++;
    proto_tree_add_uint(map_tree, hf_auto_rp_group_num, tvb, offset, 1, group_count);
    offset++;

    for (i = 0; i < group_count; i++) {
        proto_tree *grp_tree;
        guint8      sign, mask_len;

        sign = tvb_get_guint8(tvb, offset);
        mask_len = tvb_get_guint8(tvb, offset + 1);
        grp_tree = proto_tree_add_subtree_format(map_tree, tvb, offset, 6,
                   ett_auto_rp_group, NULL, "Group %s/%u (%s)",
                   tvb_ip_to_str(tvb, offset + 2), mask_len,
                   val_to_str_const(sign&AUTO_RP_SIGN_MASK, auto_rp_mask_sign_vals, ""));

        proto_tree_add_uint(grp_tree, hf_auto_rp_prefix_sgn, tvb, offset, 1, sign);
        offset++;
        proto_tree_add_uint(grp_tree, hf_auto_rp_mask_len, tvb, offset, 1, mask_len);
        offset++;
        proto_tree_add_item(grp_tree, hf_auto_rp_group_prefix, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

    }

    return offset;
}
Esempio n. 19
0
gint
decode_past_error(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
  guint32 error_len;
  guint32 remaining = (guint32) tvb_reported_length_remaining(tvb, offset);

  if (remaining < 4){
    proto_tree_add_text(tree, tvb, offset, remaining, "Too short attributes!");
    return -1;
  }
  error_len = tvb_get_ntohl(tvb, offset);
  proto_tree_add_uint(tree, hf_past_error_len, tvb, offset, 4, error_len);

  if (error_len > 0){
    if (remaining < (4 + error_len)){
      proto_tree_add_text(tree, tvb, offset + 4, remaining, "Too short attributes!");
      return -1;
    }
    proto_tree_add_text(tree, tvb, offset + 4, error_len,
				    "Error (%u byte%s)", error_len,
				    plurality(error_len, "", "s"));
  }
  return (offset + error_len + 4);
}
Esempio n. 20
0
gint
decode_past_content_handle(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
  guint16 content_handle_type;
  guint remaining = tvb_reported_length_remaining(tvb, offset);

  if (remaining < 2){
    proto_tree_add_text(tree, tvb, offset, remaining, "Too short attributes!");
    return -1;
  }

  content_handle_type = tvb_get_ntohs(tvb, offset);
  proto_tree_add_uint(tree, hf_past_content_handle_type, tvb, offset, 2, content_handle_type);

    if (content_handle_type == 0) {
      guint32 content_handle_len;
      if (remaining < 6){/*3 = type + len*/
        proto_tree_add_text(tree, tvb, offset + 2, remaining, "Too short attributes!");
      return -1;
      }
      content_handle_len = (guint32) tvb_get_ntohl(tvb, offset +2);
      proto_tree_add_uint(tree, hf_past_content_handle_len, tvb, offset + 2, 4, content_handle_len);
      if (remaining < (6 + content_handle_len)){
        proto_tree_add_text(tree, tvb, offset + 6, remaining, "Too short attributes!");
        return -1;
      }
      proto_tree_add_text(tree, tvb, offset + 6, content_handle_len,
				    "Past handle content (%u byte%s)", content_handle_len,
				    plurality(content_handle_len, "", "s"));
      return (offset + content_handle_len + 6);
    } else {
      /*unknown type, cannot dissect more data*/
      proto_tree_add_text(tree, tvb, offset + 6, -1, "Not supported by dissector.");
      return -1;
    }
}
static void dissect_xdmcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gint version = -1, opcode = -1;
  gint offset = 0;
  proto_item *ti;
  proto_tree *xdmcp_tree = 0;

  version = tvb_get_ntohs(tvb, offset);
  if (version != XDMCP_PROTOCOL_VERSION) {
    /* Only version 1 exists, so this probably is not XDMCP at all... */
    return;
  }

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

  if (tree) {
    ti = proto_tree_add_item(tree, proto_xdmcp, tvb, offset, -1, FALSE);
    xdmcp_tree = proto_item_add_subtree(ti, ett_xdmcp);

    proto_tree_add_uint(xdmcp_tree, hf_xdmcp_version, tvb,
			offset, 2, version);
  }
  offset += 2;

  opcode = tvb_get_ntohs(tvb, offset);
  if (tree) {
    proto_tree_add_uint(xdmcp_tree, hf_xdmcp_opcode, tvb,
			offset, 2, opcode);
  }
  offset += 2;
  if (check_col(pinfo->cinfo, COL_INFO)) {
    col_add_str(pinfo->cinfo, COL_INFO, 
                 val_to_str(opcode, opcode_vals, "Unknown (0x%04x)"));

  }

  if (tree) {
    proto_tree_add_item(xdmcp_tree, hf_xdmcp_length, tvb,
			offset, 2, FALSE);
    offset += 2;

    switch (opcode) {
      case XDMCP_FORWARD_QUERY:
      {
	gint alen, plen;
	alen = tvb_get_ntohs(tvb, offset);
	/* I have never seen anything except IPv4 addresses here,
	 * but in theory the protocol should support other address
	 * families. */
	if (alen == 4) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, alen+2,
			      "Client address: %s",
			      ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
	  offset += 6;
	} else if (alen == 16) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, alen+2,
			      "Client address: %s",
			      ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+2, 16)));
	  offset += 18;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, "Client address", tvb, offset);
	}

	plen = tvb_get_ntohs(tvb, offset);
	if (plen == 2) {
	  proto_tree_add_text(xdmcp_tree, tvb, offset, plen+2,
			      "Client port: %u",
			      tvb_get_ntohs(tvb, offset+2));
	  offset += 4;
	} else {
	  offset += xdmcp_add_bytes(xdmcp_tree, "Client port", tvb, offset);
	}
      }
      /* fall-through */

      case XDMCP_BROADCAST_QUERY:
      case XDMCP_QUERY:
      case XDMCP_INDIRECT_QUERY:
	offset += xdmcp_add_authentication_names(xdmcp_tree, tvb, offset);
	break;

      case XDMCP_WILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_UNWILLING:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_hostname,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_REQUEST:
      {
	proto_tree *clist_tree;
	proto_item *clist_ti;
	gint ctypes_len, caddrs_len, n;
	gint ctypes_start_offset, caddrs_offset;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	ctypes_len = tvb_get_guint8(tvb, offset);
	ctypes_start_offset = offset;
	caddrs_offset = offset + 1 + 2*ctypes_len;
	caddrs_len = tvb_get_guint8(tvb, caddrs_offset);
	if (ctypes_len != caddrs_len) {
	  proto_tree_add_text(xdmcp_tree, NULL, 0, 0,
			      "Error: Connection type/address arrays don't match");
	  return;
	}

	clist_ti = proto_tree_add_text(xdmcp_tree,
				       tvb, ctypes_start_offset, -1,
				       "Connections (%d)",
				       ctypes_len);
	clist_tree = proto_item_add_subtree(clist_ti, ett_xdmcp_connections);

	offset++;
	caddrs_offset++;

	n = 1;
	while (ctypes_len > 0) {
	  proto_item *connection_ti;
	  proto_tree *connection_tree;
	  const char *ip_string;

	  gint alen;
	  gint ctype = tvb_get_ntohs(tvb, offset);
	  offset += 2;
	  alen = tvb_get_ntohs(tvb, caddrs_offset);
	  caddrs_offset += 2;

	  if ((ctype == 0) && (alen == 4)) {
	    ip_string = ip_to_str(tvb_get_ptr(tvb, caddrs_offset, 4));
	  } else if ((ctype == 6) && (alen == 16)) {
	    ip_string = ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, caddrs_offset, 16));
	  } else {
	    ip_string = NULL;
	  }

	  connection_ti = proto_tree_add_text(clist_tree, NULL, 0, 0,
					      "Connection %d%s%s", n,
					      (ip_string ? ": " : ""),
					      (ip_string ? ip_string : ""));
	  connection_tree = proto_item_add_subtree(connection_ti,
						   ett_xdmcp_connection);

	  proto_tree_add_text(connection_tree, tvb, offset-2, 2,
			      "Type: %s",
			      val_to_str(ctype, family_vals,
					 "Unknown (0x%04x)"));
	  if (ip_string) {
	    proto_tree_add_text(connection_tree, tvb, caddrs_offset-2, alen+2,
				"Address: %s", ip_string);
	  } else {
	    proto_tree_add_text(connection_tree, tvb, caddrs_offset-2, alen+2,
				"Address: (%u byte%s)", alen,
				plurality(alen, "", "s"));
	  }
	  caddrs_offset += alen;
	  ctypes_len--;
	  n++;
	}
	offset = caddrs_offset;
	proto_item_set_len(clist_ti, offset - ctypes_start_offset);

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);

	offset += xdmcp_add_authorization_names(xdmcp_tree, tvb, offset);

	offset += xdmcp_add_text(xdmcp_tree, "Manufacturer display ID",
				 tvb, offset);
	break;
      }

      case XDMCP_ACCEPT:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authorization_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authorization data",
				  tvb, offset);
	break;

      case XDMCP_DECLINE:
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_authentication_name,
				   tvb, offset);
	offset += xdmcp_add_bytes(xdmcp_tree, "Authentication data",
				  tvb, offset);
	break;

      case XDMCP_MANAGE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	offset += xdmcp_add_text(xdmcp_tree, "Display class",
				 tvb, offset);
	break;

      case XDMCP_REFUSE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;

      case XDMCP_FAILED:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;

	offset += xdmcp_add_string(xdmcp_tree, hf_xdmcp_status,
				   tvb, offset);
	break;

      case XDMCP_KEEPALIVE:
	proto_tree_add_item(xdmcp_tree, hf_xdmcp_display_number, tvb,
			    offset, 2, FALSE);
	offset += 2;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;

      case XDMCP_ALIVE:
	proto_tree_add_text(xdmcp_tree, tvb, offset, 1,
			    "Session running: %s",
			    (tvb_get_guint8(tvb, offset) ? "Yes" : "No"));
	offset++;

	proto_tree_add_item(xdmcp_tree, hf_xdmcp_session_id, tvb,
			    offset, 4, FALSE);
	offset += 4;
	break;
    }
  }
}
Esempio n. 22
0
static void
dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
{
  guint16 code, length, cause_info_length;

  code              = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
  length            = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
  cause_info_length = length - CAUSE_HEADER_LENGTH;
  if (cause_info_length > 0)
    proto_tree_add_item(cause_tree, hf_cause_info, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, ENC_NA);
  proto_item_append_text(cause_item, " (code %u and %u byte%s information)", code, cause_info_length, plurality(cause_info_length, "", "s"));
}
Esempio n. 23
0
static void
dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  struct smtp_proto_data    *spd_frame_data;
  proto_tree                *smtp_tree = NULL;
  proto_tree                *cmdresp_tree;
  proto_item                *ti, *hidden_item;
  int                       offset = 0;
  int                       request = 0;
  conversation_t            *conversation;
  struct smtp_session_state *session_state;
  const guchar              *line, *linep, *lineend;
  guint32                   code;
  int                       linelen = 0;
  gint                      length_remaining;
  gboolean                  eom_seen = FALSE;
  gint                      next_offset;
  gint                      loffset = 0;
  int                       cmdlen;
  fragment_data             *frag_msg = NULL;
  tvbuff_t                  *next_tvb;

  /* As there is no guarantee that we will only see frames in the
   * the SMTP conversation once, and that we will see them in
   * order - in Wireshark, the user could randomly click on frames
   * in the conversation in any order in which they choose - we
   * have to store information with each frame indicating whether
   * it contains commands or data or an EOM indication.
   *
   * XXX - what about frames that contain *both*?  TCP is a
   * byte-stream protocol, and there are no guarantees that
   * TCP segment boundaries will correspond to SMTP commands
   * or EOM indications.
   *
   * We only need that for the client->server stream; responses
   * are easy to manage.
   *
   * If we have per frame data, use that, else, we must be on the first
   * pass, so we figure it out on the first pass.
   */

  /*
   * Find or create the conversation for this.
   */
  conversation = find_or_create_conversation(pinfo);

  /*
   * Is there a request structure attached to this conversation?
   */
  session_state = conversation_get_proto_data(conversation, proto_smtp);
  if (!session_state) {
    /*
     * No - create one and attach it.
     */
    session_state = se_alloc(sizeof(struct smtp_session_state));
    session_state->smtp_state = SMTP_STATE_READING_CMDS;
    session_state->crlf_seen = FALSE;
    session_state->data_seen = FALSE;
    session_state->msg_read_len = 0;
    session_state->msg_tot_len = 0;
    session_state->msg_last = TRUE;
    session_state->last_nontls_frame = 0;

    conversation_add_proto_data(conversation, proto_smtp, session_state);
  }

  /* Are we doing TLS?
   * FIXME In my understanding of RFC 2487 client and server can send SMTP cmds
   * after a rejected TLS negotiation
   */
  if (session_state->last_nontls_frame != 0 && pinfo->fd->num > session_state->last_nontls_frame) {
    guint16 save_can_desegment;
    guint32 save_last_nontls_frame;

    /* This is TLS, not raw SMTP. TLS can desegment */
    save_can_desegment = pinfo->can_desegment;
    pinfo->can_desegment = pinfo->saved_can_desegment;

    /* Make sure the SSL dissector will not be called again after decryption */
    save_last_nontls_frame = session_state->last_nontls_frame;
    session_state->last_nontls_frame = 0;

    call_dissector(ssl_handle, tvb, pinfo, tree);

    pinfo->can_desegment = save_can_desegment;
    session_state->last_nontls_frame = save_last_nontls_frame;
    return;
  }

  /* Is this a request or a response? */
  request = pinfo->destport == pinfo->match_uint;

  /*
   * Is there any data attached to this frame?
   */
  spd_frame_data = p_get_proto_data(pinfo->fd, proto_smtp);

  if (!spd_frame_data) {

    /*
     * No frame data.
     */
    if(request) {

      /*
       * Create a frame data structure and attach it to the packet.
       */
      spd_frame_data = se_alloc0(sizeof(struct smtp_proto_data));

      spd_frame_data->conversation_id = conversation->index;
      spd_frame_data->more_frags = TRUE;

      p_add_proto_data(pinfo->fd, proto_smtp, spd_frame_data);

    }

    /*
     * Get the first line from the buffer.
     *
     * Note that "tvb_find_line_end()" will, if it doesn't return
     * -1, return a value that is not longer than what's in the buffer,
     * and "tvb_find_line_end()" will always return a value that is not
     * longer than what's in the buffer, so the "tvb_get_ptr()" call
     * won't throw an exception.
     */
    loffset = offset;
    while (tvb_offset_exists(tvb, loffset)) {
      linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset,
                                  smtp_desegment && pinfo->can_desegment);
      if (linelen == -1) {
        if (offset == loffset) {
          /*
           * We didn't find a line ending, and we're doing desegmentation;
           * tell the TCP dissector where the data for this message starts
           * in the data it handed us, and tell it we need more bytes
           */
          pinfo->desegment_offset = loffset;
          pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
          return;
        } else {
          linelen = tvb_length_remaining(tvb, loffset);
          next_offset = loffset + linelen;
        }
      }
      line = tvb_get_ptr(tvb, loffset, linelen);

      /*
       * Check whether or not this packet is an end of message packet
       * We should look for CRLF.CRLF and they may be split.
       * We have to keep in mind that we may see what we want on
       * two passes through here ...
       */
      if (session_state->smtp_state == SMTP_STATE_READING_DATA) {
        /*
         * The order of these is important ... We want to avoid
         * cases where there is a CRLF at the end of a packet and a
         * .CRLF at the begining of the same packet.
         */
        if ((session_state->crlf_seen && tvb_strneql(tvb, loffset, ".\r\n", 3) == 0) ||
            tvb_strneql(tvb, loffset, "\r\n.\r\n", 5) == 0)
          eom_seen = TRUE;

        length_remaining = tvb_length_remaining(tvb, loffset);
        if (length_remaining == tvb_reported_length_remaining(tvb, loffset) &&
            tvb_strneql(tvb, loffset + length_remaining - 2, "\r\n", 2) == 0)
          session_state->crlf_seen = TRUE;
        else
          session_state->crlf_seen = FALSE;
      }

      /*
       * OK, Check if we have seen a DATA request. We do it here for
       * simplicity, but we have to be careful below.
       */
      if (request) {
        if (session_state->smtp_state == SMTP_STATE_READING_DATA) {
          /*
           * This is message data.
           */
          if (eom_seen) { /* Seen the EOM */
            /*
             * EOM.
             * Everything that comes after it is commands.
             */
            spd_frame_data->pdu_type = SMTP_PDU_EOM;
            session_state->smtp_state = SMTP_STATE_READING_CMDS;
            break;
          } else {
            /*
             * Message data with no EOM.
             */
            spd_frame_data->pdu_type = SMTP_PDU_MESSAGE;

            if (session_state->msg_tot_len > 0) {
              /*
               * We are handling a BDAT message.
               * Check if we have reached end of the data chunk.
               */
              session_state->msg_read_len += tvb_length_remaining(tvb, loffset);

              if (session_state->msg_read_len == session_state->msg_tot_len) {
                /*
                 * We have reached end of BDAT data chunk.
                 * Everything that comes after this is commands.
                 */
                session_state->smtp_state = SMTP_STATE_READING_CMDS;

                if (session_state->msg_last) {
                  /*
                   * We have found the LAST data chunk.
                   * The message can now be reassembled.
                   */
                  spd_frame_data->more_frags = FALSE;
                }

                break; /* no need to go through the remaining lines */
              }
            }
          }
        } else {
          /*
           * This is commands - unless the capture started in the
           * middle of a session, and we're in the middle of data.
           *
           * Commands are not necessarily 4 characters; look
           * for a space or the end of the line to see where
           * the putative command ends.
           */
          linep = line;
          lineend = line + linelen;
          while (linep < lineend && *linep != ' ')
            linep++;
          cmdlen = (int)(linep - line);
          if (line_is_smtp_command(line, cmdlen)) {
            if (g_ascii_strncasecmp(line, "DATA", 4) == 0) {
              /*
               * DATA command.
               * This is a command, but everything that comes after it,
               * until an EOM, is data.
               */
              spd_frame_data->pdu_type = SMTP_PDU_CMD;
              session_state->smtp_state = SMTP_STATE_READING_DATA;
              session_state->data_seen = TRUE;
            } else if (g_ascii_strncasecmp(line, "BDAT", 4) == 0) {
              /*
               * BDAT command.
               * This is a command, but everything that comes after it,
               * until given length is received, is data.
               */
              guint32 msg_len;

              msg_len = strtoul (line+5, NULL, 10);

              spd_frame_data->pdu_type = SMTP_PDU_CMD;
              session_state->data_seen = TRUE;
              session_state->msg_tot_len += msg_len;

              if (msg_len == 0) {
                /* No data to read, next will be a command */
                session_state->smtp_state = SMTP_STATE_READING_CMDS;
              } else {
                session_state->smtp_state = SMTP_STATE_READING_DATA;
              }

              if (g_ascii_strncasecmp(line+linelen-4, "LAST", 4) == 0) {
                /*
                 * This is the last data chunk.
                 */
                session_state->msg_last = TRUE;

                if (msg_len == 0) {
                  /*
                   * No more data to expect.
                   * The message can now be reassembled.
                   */
                  spd_frame_data->more_frags = FALSE;
                }
              } else {
                session_state->msg_last = FALSE;
              }
            } else if (g_ascii_strncasecmp(line, "STARTTLS", 8) == 0) {
              /*
               * STARTTLS command.
               * This is a command, but if the response is 220,
               * everything after the response is TLS.
               */
              session_state->smtp_state = SMTP_STATE_AWAITING_STARTTLS_RESPONSE;
              spd_frame_data->pdu_type = SMTP_PDU_CMD;
            } else {
              /*
               * Regular command.
               */
              spd_frame_data->pdu_type = SMTP_PDU_CMD;
            }
          } else {
            /*
             * Assume it's message data.
             */
            spd_frame_data->pdu_type = session_state->data_seen ? SMTP_PDU_MESSAGE : SMTP_PDU_CMD;
          }
        }
      }

      /*
       * Step past this line.
       */
      loffset = next_offset;
    }
  }


  /*
   * From here, we simply add items to the tree and info to the info
   * fields ...
   */

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

  if (check_col(pinfo->cinfo, COL_INFO)) {  /* Add the appropriate type here */
    col_clear(pinfo->cinfo, COL_INFO);

    /*
     * If it is a request, we have to look things up, otherwise, just
     * display the right things
     */

    if (request) {
      /* We must have frame_data here ... */
      switch (spd_frame_data->pdu_type) {
      case SMTP_PDU_MESSAGE:

        length_remaining = tvb_length_remaining(tvb, offset);
        col_set_str(pinfo->cinfo, COL_INFO, smtp_data_desegment ? "C: DATA fragment" : "C: Message Body");
        col_append_fstr(pinfo->cinfo, COL_INFO, ", %d byte%s", length_remaining,
                        plurality (length_remaining, "", "s"));
        break;

      case SMTP_PDU_EOM:
        col_set_str(pinfo->cinfo, COL_INFO, "C: .");
        break;

      case SMTP_PDU_CMD:
        loffset = offset;
        while (tvb_offset_exists(tvb, loffset)) {
          /*
           * Find the end of the line.
           */
          linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);
          line = tvb_get_ptr(tvb, loffset, linelen);

          if(loffset == offset)
            col_append_fstr(pinfo->cinfo, COL_INFO, "C: %s",
                            format_text(line, linelen));
          else {
            col_append_fstr(pinfo->cinfo, COL_INFO, " | %s",
                            format_text(line, linelen));
          }

          loffset = next_offset;
        }
        break;
      }
    } else {
      loffset = offset;
      while (tvb_offset_exists(tvb, loffset)) {
        /*
         * Find the end of the line.
         */
        linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);
        line = tvb_get_ptr(tvb, loffset, linelen);

        if (loffset == offset)
          col_append_fstr(pinfo->cinfo, COL_INFO, "S: %s",
                          format_text(line, linelen));
        else {
          col_append_fstr(pinfo->cinfo, COL_INFO, " | %s",
                          format_text(line, linelen));
        }

        loffset = next_offset;
      }
    }
  }

  if (tree) { /* Build the tree info ... */
    ti = proto_tree_add_item(tree, proto_smtp, tvb, offset, -1, ENC_NA);
    smtp_tree = proto_item_add_subtree(ti, ett_smtp);
  }

  if (request) {
    /*
     * Check out whether or not we can see a command in there ...
     * What we are looking for is not data_seen and the word DATA
     * and not eom_seen.
     *
     * We will see DATA and session_state->data_seen when we process the
     * tree view after we have seen a DATA packet when processing
     * the packet list pane.
     *
     * On the first pass, we will not have any info on the packets
     * On second and subsequent passes, we will.
     */
    switch (spd_frame_data->pdu_type) {

    case SMTP_PDU_MESSAGE:
      if (smtp_data_desegment) {
        frag_msg = fragment_add_seq_next(tvb, 0, pinfo, spd_frame_data->conversation_id,
                                         smtp_data_segment_table, smtp_data_reassembled_table,
                                         tvb_length(tvb), spd_frame_data->more_frags);
      } else {
        /*
         * Message body.
         * Put its lines into the protocol tree, a line at a time.
         */
        dissect_smtp_data(tvb, offset, smtp_tree);
      }
      break;

    case SMTP_PDU_EOM:
      /*
       * End-of-message-body indicator.
       *
       * XXX - what about stuff after the first line?
       * Unlikely, as the client should wait for a response to the
       * DATA command this terminates before sending another
       * request, but we should probably handle it.
       */
      proto_tree_add_text(smtp_tree, tvb, offset, linelen, "C: .");

      if (smtp_data_desegment) {
        /* add final data segment */
        if (loffset)
          fragment_add_seq_next(tvb, 0, pinfo, spd_frame_data->conversation_id,
                                smtp_data_segment_table, smtp_data_reassembled_table,
                                loffset, spd_frame_data->more_frags);

        /* terminate the desegmentation */
        frag_msg = fragment_end_seq_next (pinfo, spd_frame_data->conversation_id, smtp_data_segment_table,
                                          smtp_data_reassembled_table);
      }
      break;

    case SMTP_PDU_CMD:
      /*
       * Command.
       *
       * XXX - what about stuff after the first line?
       * Unlikely, as the client should wait for a response to the
       * previous command before sending another request, but we
       * should probably handle it.
       */

      loffset = offset;
      while (tvb_offset_exists(tvb, loffset)) {
        /*
         * Find the end of the line.
         */
        linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);

        if (linelen >= 4)
          cmdlen = 4;
        else
          cmdlen = linelen;
        hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_req, tvb,
                                             0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);

        /*
         * Put the command line into the protocol tree.
         */
        ti =  proto_tree_add_item(smtp_tree, hf_smtp_command_line, tvb,
                          loffset, next_offset - loffset, ENC_ASCII|ENC_NA);
        cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp);

        proto_tree_add_item(cmdresp_tree, hf_smtp_req_command, tvb,
                            loffset, cmdlen, ENC_ASCII|ENC_NA);
        if (linelen > 5) {
          proto_tree_add_item(cmdresp_tree, hf_smtp_req_parameter, tvb,
                              loffset + 5, linelen - 5, ENC_ASCII|ENC_NA);
        }

        if (smtp_data_desegment && !spd_frame_data->more_frags) {
          /* terminate the desegmentation */
          frag_msg = fragment_end_seq_next (pinfo, spd_frame_data->conversation_id, smtp_data_segment_table,
                                            smtp_data_reassembled_table);
        }

        /*
         * Step past this line.
         */
        loffset = next_offset;
      }
    }

    if (smtp_data_desegment) {
      next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled SMTP",
                                          frag_msg, &smtp_data_frag_items, NULL, smtp_tree);
      if (next_tvb) {
        /* XXX: this is presumptious - we may have negotiated something else */
        if (imf_handle) {
          call_dissector(imf_handle, next_tvb, pinfo, tree);
        } else {
          /*
           * Message body.
           * Put its lines into the protocol tree, a line at a time.
           */
          dissect_smtp_data(tvb, offset, smtp_tree);
        }

        pinfo->fragmented = FALSE;
      } else {
        pinfo->fragmented = TRUE;
      }
    }
  } else {
    /*
     * Process the response, a line at a time, until we hit a line
     * that doesn't have a continuation indication on it.
     */
    if (tree) {
      hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_rsp, tvb,
                                           0, 0, TRUE);
      PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    while (tvb_offset_exists(tvb, offset)) {
      /*
       * Find the end of the line.
       */
      linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);

      if (tree) {
        /*
         * Put it into the protocol tree.
         */
        ti =  proto_tree_add_item(smtp_tree, hf_smtp_response, tvb,
                          offset, next_offset - offset, ENC_ASCII|ENC_NA);
        cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp);
      } else
        cmdresp_tree = NULL;

      line = tvb_get_ptr(tvb, offset, linelen);
      if (linelen >= 3 && isdigit(line[0]) && isdigit(line[1])
          && isdigit(line[2])) {
        /*
         * We have a 3-digit response code.
         */
        code = (line[0] - '0')*100 + (line[1] - '0')*10 + (line[2] - '0');

        /*
         * If we're awaiting the response to a STARTTLS code, this
         * is it - if it's 220, all subsequent traffic will
         * be TLS, otherwise we're back to boring old SMTP.
         */
        if (session_state->smtp_state == SMTP_STATE_AWAITING_STARTTLS_RESPONSE) {
          if (code == 220) {
            /* This is the last non-TLS frame. */
            session_state->last_nontls_frame = pinfo->fd->num;
          }
          session_state->smtp_state =  SMTP_STATE_READING_CMDS;
        }

        if (tree) {
          /*
           * Put the response code and parameters into the protocol tree.
           */
          proto_tree_add_uint(cmdresp_tree, hf_smtp_rsp_code, tvb, offset, 3,
                              code);

          if (linelen >= 4) {
            proto_tree_add_item(cmdresp_tree, hf_smtp_rsp_parameter, tvb,
                                offset + 4, linelen - 4, ENC_ASCII|ENC_NA);
          }
        }
      }

      /*
       * Step past this line.
       */
      offset = next_offset;

    }
  }
}
Esempio n. 24
0
/*
* Dissect RTSE PDUs inside a PPDU.
*/
static void
dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	int old_offset;
	proto_item *item=NULL;
	proto_tree *tree=NULL;
	proto_tree *next_tree=NULL;
	tvbuff_t *next_tvb = NULL;
	tvbuff_t *data_tvb = NULL;
	fragment_data *frag_msg = NULL;
	guint32 fragment_length;
	guint32 rtse_id = 0;
	gboolean data_handled = FALSE;
	conversation_t *conversation = NULL;
	asn1_ctx_t asn1_ctx;
	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

	/* save parent_tree so subdissectors can create new top nodes */
	top_tree=parent_tree;

	/* do we have application context from the acse dissector?  */
	if( !pinfo->private_data ){
		if(parent_tree){
			proto_tree_add_text(parent_tree, tvb, offset, -1,
				"Internal error:can't get application context from ACSE dissector.");
		} 
		return  ;
	} else {
		session  = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );

	}

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

	if (rtse_reassemble && 
	    ((session->spdu_type == SES_DATA_TRANSFER) ||
	     (session->spdu_type == SES_MAJOR_SYNC_POINT))) {
		/* Use conversation index as fragment id */
		conversation  = find_conversation (pinfo->fd->num, 
						   &pinfo->src, &pinfo->dst, pinfo->ptype, 
						   pinfo->srcport, pinfo->destport, 0);
		if (conversation != NULL) { 
			rtse_id = conversation->index;
		} 
		session->rtse_reassemble = TRUE;
	}
	if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
		frag_msg = fragment_end_seq_next (pinfo, rtse_id, rtse_segment_table,
						  rtse_reassembled_table);
		next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE", 
						     frag_msg, &rtse_frag_items, NULL, parent_tree);
	}
	if(parent_tree){
		item = proto_tree_add_item(parent_tree, proto_rtse, next_tvb ? next_tvb : tvb, 0, -1, FALSE);
		tree = proto_item_add_subtree(item, ett_rtse);
	}
	if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) {
		/* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
		dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hf_rtse_segment_data, &data_tvb);

		if (data_tvb) {
			fragment_length = tvb_length_remaining (data_tvb, 0);
			proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length,
      	                              plurality(fragment_length, "", "s"));
			frag_msg = fragment_add_seq_next (data_tvb, 0, pinfo, 
							  rtse_id, rtse_segment_table,
							  rtse_reassembled_table, fragment_length, TRUE);
			if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) {
				/* Add a "Reassembled in" link if not reassembled in this frame */
				proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
						     data_tvb, 0, 0, frag_msg->reassembled_in);
			}
			pinfo->fragmented = TRUE;
			data_handled = TRUE;
		} else {
			fragment_length = tvb_length_remaining (tvb, offset);
		}

		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE fragment, %u byte%s]",
					fragment_length, plurality(fragment_length, "", "s"));
	} else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
		if (next_tvb) {
			/* ROS won't do this for us */
			session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
			offset=dissect_ber_external_type(FALSE, tree, next_tvb, 0, &asn1_ctx, -1, call_rtse_external_type_callback);
		} else {
			offset = tvb_length (tvb);
		}
		pinfo->fragmented = FALSE;
		data_handled = TRUE;
	} 

	if (!data_handled) {
		while (tvb_reported_length_remaining(tvb, offset) > 0){
			old_offset=offset;
			offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
			if(offset == old_offset){
				item = proto_tree_add_text(tree, tvb, offset, -1, "Unknown RTSE PDU");

				if(item){
					expert_add_info_format (pinfo, item, PI_UNDECODED, PI_WARN, "Unknown RTSE PDU");
					next_tree=proto_item_add_subtree(item, ett_rtse_unknown);
					dissect_unknown_ber(pinfo, tvb, offset, next_tree);
				}

				offset = tvb_length(tvb);
				break;
			}
		}
	}

	top_tree = NULL;
}
Esempio n. 25
0
static void
dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
{
  guint16 type, parameter_value_length;

  type                   = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
  parameter_value_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;

  if (parameter_value_length > 0)
    proto_tree_add_item(parameter_tree, hf_parameter_value, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, ENC_NA);

  proto_item_append_text(parameter_item, " (type %u and %u byte%s value)", type, parameter_value_length, plurality(parameter_value_length, "", "s"));
}
Esempio n. 26
0
/* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */
static int
dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	proto_item  *volatile ti = NULL;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile fh_tree = NULL;
	proto_tree  *volatile tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;
	const color_filter_t *color_filter;
	file_data_t *file_data = (file_data_t*)data;

	tree=parent_tree;

	pinfo->current_proto = "File";

	/* if FILE is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_file)) {
		tree=NULL;
	} else {
		/* Put in frame header information. */
		cap_len = tvb_captured_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_file, tvb, 0, -1,
		    "File record %u: %u byte%s",
		    pinfo->num, frame_len, frame_plurality);
		proto_item_append_text(ti, ", %u byte%s",
		    cap_len, cap_plurality);

		fh_tree = proto_item_add_subtree(ti, ett_file);

		proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->pkt_encap);

		proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->num);

		proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb,
					   0, 0, frame_len, "Record Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(pinfo->fd->pfd != 0){
			proto_item *ppd_item;
			guint num_entries = g_slist_length(pinfo->fd->pfd);
			guint i;
			ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries);
			PROTO_ITEM_SET_GENERATED(ppd_item);
			for(i=0; i<num_entries; i++){
				gchar* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i);
				proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str);
			}
		}

#if 0
		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}
#endif
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_boolean_format(tree, hf_file_ignored, tvb, 0, -1, TRUE, "This record is marked as ignored");
		return tvb_captured_length(tvb);
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
		/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
		   stack in an inconsistent state thus causing a crash at some point in the
		   handling of the exception.
		   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
		*/
		__try {
#endif
			if (!dissector_try_uint(file_encap_dissector_table, pinfo->pkt_encap,
						tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d",
					     pinfo->pkt_encap);
				call_data_dissector(tvb, pinfo, parent_tree);
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if(proto_field_is_referenced(tree, hf_file_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
		PROTO_ITEM_SET_GENERATED(ti);
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
			/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
			   stack in an inconsistent state thus causing a crash at some point in the
			   handling of the exception.
			   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
			*/
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	/* Attempt to (re-)calculate color filters (if any). */
	if (pinfo->fd->flags.need_colorize) {
		color_filter = color_filters_colorize_packet(file_data->color_edt);
		pinfo->fd->color_filter = color_filter;
		pinfo->fd->flags.need_colorize = 0;
	} else {
		color_filter = pinfo->fd->color_filter;
	}
	if (color_filter) {
		pinfo->fd->color_filter = color_filter;
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb,
					     0, 0, color_filter->filter_name);
		PROTO_ITEM_SET_GENERATED(item);
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb,
					     0, 0, color_filter->filter_text);
		PROTO_ITEM_SET_GENERATED(item);
	}

	tap_queue_packet(file_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}

	return tvb_captured_length(tvb);
}
Esempio n. 27
0
/*
 * Dissect an SPDU.
 */
static int
dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
	     gboolean tokens, gboolean connectionless)
{
	gboolean has_user_information = FALSE;
	guint8 type;
	proto_item *ti = NULL;
	proto_tree *ses_tree = NULL;
	int len_len;
	guint16 parameters_len;
	tvbuff_t *next_tvb = NULL;
	guint32 *pres_ctx_id = NULL;
	guint8 enclosure_item_flags = BEGINNING_SPDU|END_SPDU;
	struct SESSION_DATA_STRUCTURE session;

	/*
	 * Get SPDU type.
	 */
	type = tvb_get_guint8(tvb, offset);
	session.spdu_type = type;
	session.abort_type = SESSION_NO_ABORT;
	session.pres_ctx_id = 0;
	session.ros_op = 0;
	session.rtse_reassemble = FALSE;

	if(connectionless) {
		col_add_str(pinfo->cinfo, COL_INFO,
			    val_to_str(type, ses_vals, "Unknown SPDU type (0x%02x)"));
		if (tree) {
			ti = proto_tree_add_item(tree, proto_clses, tvb, offset,
				-1, ENC_NA);
			ses_tree = proto_item_add_subtree(ti, ett_ses);
			proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
				offset, 1, type);
		}
		has_user_information = TRUE;
	}
	else if (tokens) {
		col_add_str(pinfo->cinfo, COL_INFO,
			    val_to_str(type, ses_category0_vals, "Unknown SPDU type (0x%02x)"));
		if (tree) {
			ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
			    -1, ENC_NA);
			ses_tree = proto_item_add_subtree(ti, ett_ses);
			proto_tree_add_uint(ses_tree, hf_ses_type_0, tvb,
			    offset, 1, type);
		}
	} else {
		col_add_str(pinfo->cinfo, COL_INFO,
			    val_to_str(type, ses_vals, "Unknown SPDU type (0x%02x)"));
		if (tree) {
			ti = proto_tree_add_item(tree, proto_ses, tvb, offset,
				-1, ENC_NA);
			ses_tree = proto_item_add_subtree(ti, ett_ses);
			proto_tree_add_uint(ses_tree, hf_ses_type, tvb,
				offset, 1, type);
		}

		/*
		 * Might this SPDU have a User Information field?
		 */
		switch (type) {
		case SES_DATA_TRANSFER:
		case SES_EXPEDITED:
		case SES_TYPED_DATA:
			has_user_information = TRUE;
			break;
		case SES_MAJOR_SYNC_POINT:
			pres_ctx_id = (guint32 *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ses, 0);
			if (ses_rtse_reassemble != 0 && !pres_ctx_id) {
				/* First time visited - save pres_ctx_id */
				pres_ctx_id = wmem_new(wmem_file_scope(), guint32);
				*pres_ctx_id = ses_pres_ctx_id;
				p_add_proto_data(wmem_file_scope(), pinfo, proto_ses, 0, pres_ctx_id);
			}
			if (pres_ctx_id) {
				session.pres_ctx_id = *pres_ctx_id;
				session.rtse_reassemble = TRUE;
				has_user_information = TRUE;
			}
			ses_rtse_reassemble = FALSE;
			break;
		}
	}
	offset++;

	/* get length of SPDU parameter field */
	parameters_len = get_item_len(tvb, offset, &len_len);
	if (tree)
		proto_tree_add_uint(ses_tree, hf_ses_length, tvb, offset,
		    len_len, parameters_len);
	offset += len_len;

	/* Dissect parameters. */
	if (!dissect_parameters(tvb, offset, parameters_len, tree, ses_tree,
				pinfo, &enclosure_item_flags, &session))
		has_user_information = FALSE;
	offset += parameters_len;

	proto_item_set_end(ti, tvb, offset);

	/* Dissect user information, if present */
	if (!ses_desegment || enclosure_item_flags == (BEGINNING_SPDU|END_SPDU)) {
		if (has_user_information) {
			/* Not desegment or only one segment */
			if (tvb_reported_length_remaining(tvb, offset) > 0 || type == SES_MAJOR_SYNC_POINT) {
				next_tvb = tvb_new_subset_remaining(tvb, offset);
			}
		}
	} else {
		conversation_t *conversation = NULL;
		fragment_head *frag_msg = NULL;
		gint fragment_len;
		guint32 ses_id = 0;

		/* Use conversation index as segment id */
		conversation  = find_conversation (pinfo->fd->num,
						   &pinfo->src, &pinfo->dst, pinfo->ptype,
						   pinfo->srcport, pinfo->destport, 0);
		if (conversation != NULL) {
			ses_id = conversation->index;
		}
		fragment_len = tvb_reported_length_remaining (tvb, offset);
		ti = proto_tree_add_item (ses_tree, hf_ses_segment_data, tvb, offset,
					  fragment_len, ENC_NA);
		proto_item_append_text (ti, " (%d byte%s)", fragment_len, plurality (fragment_len, "", "s"));
		frag_msg = fragment_add_seq_next (&ses_reassembly_table,
						  tvb, offset,
						  pinfo, ses_id, NULL,
						  fragment_len,
						  (enclosure_item_flags & END_SPDU) ? FALSE : TRUE);
		next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled SES",
						     frag_msg, &ses_frag_items, NULL,
						     (enclosure_item_flags & END_SPDU) ? tree : ses_tree);

		has_user_information = TRUE;
		offset += fragment_len;
	}

	if (has_user_information && next_tvb) {
		if (!pres_handle) {
			call_dissector(data_handle, next_tvb, pinfo, tree);
		} else {
			/* Pass the session pdu to the presentation dissector */
			call_dissector_with_data(pres_handle, next_tvb, pinfo, tree, &session);
		}

		/*
		 * No more SPDUs to dissect.  Set the offset to the
		 * end of the tvbuff.
		 */
		offset = tvb_captured_length(tvb);
		if (session.rtse_reassemble && type == SES_DATA_TRANSFER) {
			ses_pres_ctx_id = session.pres_ctx_id;
			ses_rtse_reassemble = TRUE;
		}
	}
	return offset;
}
Esempio n. 28
0
static void
dissect_sap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int offset = 0;
    int sap_version, is_ipv6, is_del, is_enc, is_comp, addr_len;
    guint8 vers_flags;
    guint8 auth_len;
    guint16 tmp1;
    guint8 auth_flags;
    tvbuff_t *next_tvb;

    proto_item *si, *sif;
    proto_tree *sap_tree, *sap_flags_tree;

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

    vers_flags = tvb_get_guint8(tvb, offset);
    is_ipv6 = vers_flags&MCAST_SAP_BIT_A;
    is_del = vers_flags&MCAST_SAP_BIT_T;
    is_enc = vers_flags&MCAST_SAP_BIT_E;
    is_comp = vers_flags&MCAST_SAP_BIT_C;

    sap_version = (vers_flags&MCAST_SAP_VERSION_MASK)>>MCAST_SAP_VERSION_SHIFT;
    addr_len = (is_ipv6) ? sizeof(struct e_in6_addr) : 4;

    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%u)",
                     (is_del) ? "Deletion" : "Announcement", sap_version);
    }

    if (tree) {
        si = proto_tree_add_item(tree, proto_sap, tvb, offset, -1, ENC_NA);
        sap_tree = proto_item_add_subtree(si, ett_sap);

        sif = proto_tree_add_uint(sap_tree, hf_sap_flags, tvb, offset, 1, vers_flags);
        sap_flags_tree = proto_item_add_subtree(sif, ett_sap_flags);
        proto_tree_add_uint(sap_flags_tree, hf_sap_flags_v, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_a, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_r, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_t, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_e, tvb, offset, 1, vers_flags);
        proto_tree_add_boolean(sap_flags_tree, hf_sap_flags_c, tvb, offset, 1, vers_flags);
        offset++;

        auth_len = tvb_get_guint8(tvb, offset);
        proto_tree_add_text(sap_tree, tvb, offset, 1, "Authentication Length: %u", auth_len);
        offset++;

        tmp1 = tvb_get_ntohs(tvb, offset);
        proto_tree_add_text(sap_tree, tvb, offset, 2, "Message Identifier Hash: 0x%x", tmp1);
        offset +=2;

        proto_tree_add_text(sap_tree, tvb, offset, addr_len, "Originating Source: %s",
                            (is_ipv6) ? tvb_ip6_to_str(tvb, offset) : tvb_ip_to_str(tvb, offset));
        offset += addr_len;

        /* Authentication data lives in its own subtree */
        if (auth_len > 0) {
            guint32 auth_data_len;
            proto_item *sdi, *sai;
            proto_tree *sa_tree, *saf_tree;
            int has_pad;
            guint8 pad_len = 0;

            auth_data_len = auth_len * sizeof(guint32);

            sdi = proto_tree_add_item(sap_tree, hf_auth_data, tvb, offset, auth_data_len, ENC_NA);
            sa_tree = proto_item_add_subtree(sdi, ett_sap_auth);

            auth_flags = tvb_get_guint8(tvb, offset);
            sai = proto_tree_add_uint(sa_tree, hf_auth_flags, tvb, offset, 1, auth_flags);
            saf_tree = proto_item_add_subtree(sai, ett_sap_authf);
            proto_tree_add_uint(saf_tree, hf_auth_flags_v, tvb, offset, 1, auth_flags);
            proto_tree_add_boolean(saf_tree, hf_auth_flags_p, tvb, offset, 1, auth_flags);
            proto_tree_add_uint(saf_tree, hf_auth_flags_t, tvb, offset, 1, auth_flags);

            has_pad = auth_flags&MCAST_SAP_AUTH_BIT_P;
            if (has_pad)
                pad_len = tvb_get_guint8(tvb, offset+auth_data_len-1);

            if ((int) auth_data_len - pad_len - 1 < 0) {
                proto_tree_add_text(sa_tree, tvb, 0, 0,
                                    "Bogus authentication length (%d) or pad length (%d)",
                                    auth_len, pad_len);
                return;
            }


            proto_tree_add_text(sa_tree, tvb, offset+1, auth_data_len-pad_len-1,
                                "Authentication subheader: (%u byte%s)",
                                auth_data_len-1, plurality(auth_data_len-1, "", "s"));
            if (has_pad) {
                proto_tree_add_text(sa_tree, tvb, offset+auth_data_len-pad_len, pad_len,
                                    "Authentication data padding: (%u byte%s)",
                                    pad_len, plurality(pad_len, "", "s"));
                proto_tree_add_text(sa_tree, tvb, offset+auth_data_len-1, 1,
                                    "Authentication data pad count: %u byte%s",
                                    pad_len, plurality(pad_len, "", "s"));
            }

            offset += auth_data_len;
        }
        if (is_enc || is_comp) {
            const char *mangle;
            if (is_enc && is_comp) mangle = "compressed and encrypted";
            else if (is_enc) mangle = "encrypted";
            else mangle = "compressed";
            proto_tree_add_text(sap_tree, tvb, offset, -1,
                                "The rest of the packet is %s", mangle);
            return;
        }

        /* Do we have the optional payload type aka. MIME content specifier */
        if (tvb_strneql(tvb, offset, "v=", strlen("v="))) {
            gint remaining_len;
            guint32 pt_len;
            int pt_string_len;

            remaining_len = tvb_length_remaining(tvb, offset);
            if (remaining_len == 0) {
                /*
                 * "tvb_strneql()" failed because there was no
                * data left in the packet.
                *
                * Set the remaining length to 1, so that
                * we throw the appropriate exception in
                * "tvb_get_ptr()", rather than displaying
                * the payload type.
                */
                remaining_len = 1;
            }
            pt_string_len = tvb_strnlen(tvb, offset, remaining_len);
            if (pt_string_len == -1) {
                /*
                 * We didn't find a terminating '\0'; run to the
                 * end of the buffer.
                 */
                pt_string_len = remaining_len;
                pt_len = pt_string_len;
            } else {
                /*
                 * Include the '\0' in the total item length.
                 */
                pt_len = pt_string_len + 1;
            }
            proto_tree_add_text(sap_tree, tvb, offset, pt_len,
                                "Payload type: %.*s", pt_string_len,
                                tvb_get_ephemeral_string(tvb, offset, pt_string_len));
            offset += pt_len;
        }
    }

    /* Done with SAP */
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(sdp_handle, next_tvb, pinfo, tree);

    return;
}
Esempio n. 29
0
static void
dissect_pop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  struct pop_proto_data  *frame_data_p;
  gboolean               is_request;
  gboolean               is_continuation;
  proto_tree             *pop_tree, *reqresp_tree;
  proto_item             *ti;
  gint                   offset = 0;
  const guchar           *line;
  gint                   next_offset;
  int                    linelen;
  int                    tokenlen;
  const guchar           *next_token;
  fragment_data          *frag_msg = NULL;
  tvbuff_t               *next_tvb = NULL;
  conversation_t         *conversation = NULL;
  struct pop_data_val    *data_val = NULL;
  gint                   length_remaining;

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

  /*
   * Find the end of the first line.
   *
   * Note that "tvb_find_line_end()" will return a value that is
   * not longer than what's in the buffer, so the "tvb_get_ptr()"
   * call won't throw an exception.
   */
  linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
  line = tvb_get_ptr(tvb, offset, linelen);

  if (pinfo->match_port == pinfo->destport) {
    is_request = TRUE;
    is_continuation = FALSE;
  } else {
    is_request = FALSE;
    is_continuation = response_is_continuation(line);
  }

  frame_data_p = p_get_proto_data(pinfo->fd, proto_pop);

  if (!frame_data_p) {

    conversation = find_conversation(pinfo->fd->num, 
             &pinfo->src, &pinfo->dst, 
             pinfo->ptype,
             pinfo->srcport, pinfo->destport, 0);

    if (conversation == NULL) { /* No conversation, create one */
      conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
                                      pinfo->ptype, pinfo->srcport,
                                      pinfo->destport, 0);
    }

    data_val = conversation_get_proto_data(conversation, proto_pop);

    if (!data_val) {

      /*
       * No - create one and attach it.
       */
      data_val = se_alloc0(sizeof(struct pop_data_val));
      
      conversation_add_proto_data(conversation, proto_pop, data_val);
    }
  }

  if (check_col(pinfo->cinfo, COL_INFO)) {
    /*
     * Put the first line from the buffer into the summary
     * if it's a POP request or reply (but leave out the
     * line terminator).
     * Otherwise, just call it a continuation.
     */
    if (is_continuation) {
      length_remaining = tvb_length_remaining(tvb, offset);
      col_add_fstr(pinfo->cinfo, COL_INFO, "S: DATA fragment, %d byte%s", 
                   length_remaining, plurality (length_remaining, "", "s"));
    }
    else
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", is_request ? "C" : "S",
                   format_text(line, linelen));
  }

  ti = proto_tree_add_item(tree, proto_pop, tvb, offset, -1, FALSE);
  pop_tree = proto_item_add_subtree(ti, ett_pop);

  if (is_continuation) {

    if (pop_data_desegment) {

      if (!frame_data_p) {

        data_val->msg_read_len += tvb_length(tvb);

        frame_data_p = se_alloc(sizeof(struct pop_proto_data));

        frame_data_p->conversation_id = conversation->index;
        frame_data_p->more_frags = data_val->msg_read_len < data_val->msg_tot_len;

        p_add_proto_data(pinfo->fd, proto_pop, frame_data_p);  
      }

      frag_msg = fragment_add_seq_next(tvb, 0, pinfo, 
                                       frame_data_p->conversation_id, 
                                       pop_data_segment_table, 
                                       pop_data_reassembled_table, 
                                       tvb_length(tvb), 
                                       frame_data_p->more_frags);

      next_tvb = process_reassembled_data(tvb, offset, pinfo, 
                                          "Reassembled DATA",
                                          frag_msg, &pop_data_frag_items, 
                                          NULL, pop_tree);

      if (next_tvb) {

        if (imf_handle)
          call_dissector(imf_handle, next_tvb, pinfo, tree);

        if (data_val) {
          /* we have read everything - reset */
          
          data_val->msg_read_len = 0;
          data_val->msg_tot_len = 0; 
        }
        pinfo->fragmented = FALSE;
      } else {
        pinfo->fragmented = TRUE;
      }

    } else {

      /*
       * Put the whole packet into the tree as data.
       */
      call_dissector(data_handle,tvb, pinfo, pop_tree);
    
    }
    return;
  }

  /*
   * Put the line into the protocol tree.
   */
  ti = proto_tree_add_string_format(pop_tree,
                                    (is_request) ?
                                        hf_pop_request :
                                        hf_pop_response,
                                    tvb, offset,
                                    next_offset - offset,
                                    "", "%s",
                                    tvb_format_text(tvb, offset, next_offset - offset));
  reqresp_tree = proto_item_add_subtree(ti, ett_pop_reqresp);

  /*
   * Extract the first token, and, if there is a first
   * token, add it as the request or reply code.
   */
  tokenlen = get_token_len(line, line + linelen, &next_token);
  if (tokenlen != 0) {
    proto_tree_add_item(reqresp_tree,
                        (is_request) ?
                            hf_pop_request_command :
                            hf_pop_response_indicator,
                        tvb, offset, tokenlen, FALSE);

    if (data_val) {
      if (is_request) {
        /* see if this is RETR or TOP command */
        if (g_ascii_strncasecmp(line, "RETR", 4) == 0 ||
           g_ascii_strncasecmp(line, "TOP", 3) == 0)
          /* the next response will tell us how many bytes */
          data_val->msg_request = TRUE;
      } else {
        if (data_val->msg_request) {
          /* this is a response to a RETR or TOP command */

          if (g_ascii_strncasecmp(line, "+OK ", 4) == 0) {
            /* the message will be sent - work out how many bytes */
            data_val->msg_read_len = 0;
            data_val->msg_tot_len = atoi(line + 4);
          }
          data_val->msg_request = FALSE;
        }
      }
    }

    offset += (gint) (next_token - line);
    linelen -= (int) (next_token - line);
  }


  if (tree) { 
    /*
     * Add the rest of the first line as request or
     * reply param/description.
     */
    if (linelen != 0) {
      proto_tree_add_item(reqresp_tree,
                          (is_request) ?
                              hf_pop_request_parameter :
                              hf_pop_response_description,
                          tvb, offset, linelen, FALSE);
    }
    offset = next_offset;

    /*
     * Show the rest of the request or response as text,
     * a line at a time.
     */
    while (tvb_offset_exists(tvb, offset)) {
      /*
       * Find the end of the line.
       */
      tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);

      /*
       * Put this line.
       */
      proto_tree_add_string_format(pop_tree,
                                   (is_request) ?
                                       hf_pop_request_data :
                                       hf_pop_response_data,
                                   tvb, offset,
                                   next_offset - offset,
                                   "", "%s",
                                   tvb_format_text(tvb, offset, next_offset - offset));
      offset = next_offset;
    }
  } 
}
Esempio n. 30
0
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item	*volatile ti = NULL;
	nstime_t	ts;
	int		cap_len = 0, frame_len = 0;
	proto_tree	*volatile tree;
        proto_item  *item;
	guint32 frame_number;

	frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps
					will show the packetnumber where the
					crash occurred.
				     */
	tree=parent_tree;

	pinfo->current_proto = "Frame";

	if (pinfo->pseudo_header != NULL) {
		switch (pinfo->fd->lnk_t) {

		case WTAP_ENCAP_WFLEET_HDLC:
		case WTAP_ENCAP_CHDLC_WITH_PHDR:
		case WTAP_ENCAP_PPP_WITH_PHDR:
		case WTAP_ENCAP_SDLC:
		case WTAP_ENCAP_BLUETOOTH_H4:
		case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_BLUETOOTH_HCI:
			pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
			break;

		case WTAP_ENCAP_LAPB:
		case WTAP_ENCAP_FRELAY_WITH_PHDR:
			pinfo->p2p_dir =
			    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
			    P2P_DIR_RECV : P2P_DIR_SENT;
			break;

		case WTAP_ENCAP_ISDN:
			pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_LINUX_LAPD:
			pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
				pinfo->pseudo_header->lapd.pkttype == 4) ?
				P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_MTP2_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
			pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
			break;

		case WTAP_ENCAP_GSM_UM:
			pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		}
	}

	/* if FRAME is not referenced from any filters we dont need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
        tree=NULL;
        if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
            expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN,
                "Arrival Time: Fractional second out of range (0-1000000000)");
    } else {
	    proto_tree	*fh_tree;

	  /* Put in frame header information. */
	  cap_len = tvb_length(tvb);
	  frame_len = tvb_reported_length(tvb);

	  ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
	    "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, frame_len, cap_len);

	  fh_tree = proto_item_add_subtree(ti, ett_frame);

	  ts = pinfo->fd->abs_ts;

	  proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
		0, 0, &ts);
	  if(ts.nsecs < 0 || ts.nsecs >= 1000000000) {
	    item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb,
	  	  0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs);
	    PROTO_ITEM_SET_GENERATED(item);
	    expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)");
	  }

	  ts = pinfo->fd->del_cap_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->del_dis_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->rel_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  if(pinfo->fd->flags.ref_time){
		ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, FALSE);
		PROTO_ITEM_SET_GENERATED(ti);
	  }

	  proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
		0, 0, pinfo->fd->num);

	  proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
		0, 0, frame_len, "Frame Length: %d byte%s", frame_len,
		plurality(frame_len, "", "s"));

	  proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
		0, 0, cap_len, "Capture Length: %d byte%s", cap_len,
		plurality(cap_len, "", "s"));

	  if (generate_md5_hash) {
		  const guint8 *cp;
		  md5_state_t md_ctx;
		  md5_byte_t digest[16];
		  gchar *digest_string;

		  cp = tvb_get_ptr(tvb, 0, cap_len);

		  md5_init(&md_ctx);
		  md5_append(&md_ctx, cp, cap_len);
		  md5_finish(&md_ctx, digest);

		  digest_string = bytestring_to_str(digest, 16, '\0');
		  ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
		  PROTO_ITEM_SET_GENERATED(ti);
	  }

	  ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
	  PROTO_ITEM_SET_GENERATED(ti);

	  /* we are going to be using proto_item_append_string() on
	   * hf_frame_protocols, and we must therefore disable the
	   * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
	   * setting it as visible.
	   *
	   * See proto.h for details.
	   */
	  proto_tree_set_visible(fh_tree, TRUE);

	  ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb,
	  	0, 0, "");
	  PROTO_ITEM_SET_GENERATED(ti);
	  pinfo->layer_names = g_string_new("");

	  /* Check for existences of P2P pseudo header */
	  if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
		  proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
				  0, 0, pinfo->p2p_dir);
	  }

	  /* Check for existences of MTP2 link number */
	  if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
		  proto_tree_add_uint(fh_tree, hf_link_number, tvb,
				  0, 0, pinfo->link_number);
	  }

	  if (show_file_off) {
		  proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb,
				  0, 0, pinfo->fd->file_off,
				  "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
				  pinfo->fd->file_off, pinfo->fd->file_off);
	  }

	  if(pinfo->fd->color_filter != NULL) {
	      color_filter_t *color_filter = pinfo->fd->color_filter;
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
		    0, 0, color_filter->filter_name);
	      PROTO_ITEM_SET_GENERATED(item);
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
		    0, 0, color_filter->filter_text);
	      PROTO_ITEM_SET_GENERATED(item);
	  }
    }

    /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
    /* (a running debugger will be called before the except part below) */
    __try {
#endif
	if ((force_docsis_encap) && (docsis_handle)) {
	    call_dissector(docsis_handle, tvb, pinfo, parent_tree);
	} else {
            if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t,
                tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u",
				    pinfo->fd->lnk_t);
			call_dissector(data_handle,tvb, pinfo, parent_tree);
		}
	}
#ifdef _MSC_VER
    } __except(TRUE /* handle all exceptions */) {
        switch(GetExceptionCode()) {
        case(STATUS_ACCESS_VIOLATION):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
            break;
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
            break;
        case(STATUS_STACK_OVERFLOW):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
            /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
            break;
        /* XXX - add other hardware exception codes as required */
        default:
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
        }
    }
#endif
	}
	CATCH(OutOfMemoryError) {
		RETHROW;
	}
	CATCH_ALL {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if (tree && pinfo->layer_names) {
		proto_item_append_string(ti, pinfo->layer_names->str);
		g_string_free(pinfo->layer_names, TRUE);
		pinfo->layer_names = NULL;
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
	    TRY {
#ifdef _MSC_VER
	    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
	    /* (a running debugger will be called before the except part below) */
	    __try {
#endif
		call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
	    } __except(TRUE /* handle all exceptions */) {
		switch(GetExceptionCode()) {
		case(STATUS_ACCESS_VIOLATION):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
		    break;
		case(STATUS_INTEGER_DIVIDE_BY_ZERO):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
		    break;
		case(STATUS_STACK_OVERFLOW):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
		    /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
		    break;
		/* XXX - add other hardware exception codes as required */
		default:
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
		}
	    }
#endif
	    }
	    CATCH(OutOfMemoryError) {
		    RETHROW;
	    }
	    CATCH_ALL {
		    show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	    }
	    ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (frame_end_routines) {
		g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(frame_end_routines);
		frame_end_routines = NULL;
	}
}