ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &cf, register_rtd *rtd, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    rtd_(rtd)
{
    QString subtitle = tr("%1 Response Time Delay Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
    setWindowSubtitle(subtitle);
    loadGeometry(0, 0, "ResponseTimeDelayDialog");

    QStringList header_names = QStringList()
            << tr("Type") << tr("Messages")
            << tr("Min SRT") << tr("Max SRT") << tr("Avg SRT")
            << tr("Min in Frame") << tr("Max in Frame")
            << tr("Open Requests") << tr("Discarded Responses")
            << tr("Repeated Requests") << tr("Repeated Responses");

    statsTreeWidget()->setHeaderLabels(header_names);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == col_type_) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }
}
ServiceResponseTimeDialog::ServiceResponseTimeDialog(QWidget &parent, CaptureFile &cf, register_srt *srt, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    srt_(srt)
{
    QString subtitle = QString("%1 Service Response Time Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt))));
    setWindowSubtitle(subtitle);

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int col = 0; col < NUM_SRT_COLUMNS; col++) {
        header_labels.push_back(service_response_time_get_column_name(col));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == SRT_COLUMN_PROCEDURE) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    QMenu *submenu;
    QAction *insert_action = ctx_menu_.actions().first();

    FilterAction::Action cur_action = FilterAction::ActionApply;
    submenu = ctx_menu_.addMenu(FilterAction::actionName(cur_action));
    foreach (FilterAction::ActionType at, FilterAction::actionTypes()) {
        FilterAction *fa = new FilterAction(submenu, cur_action, at);
        submenu->addAction(fa);
        connect(fa, SIGNAL(triggered()), this, SLOT(filterActionTriggered()));
        filter_actions_ << fa;
    }
ServiceResponseTimeDialog::ServiceResponseTimeDialog(QWidget &parent, CaptureFile &cf, register_srt *srt, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    srt_(srt)
{
    QString subtitle = QString("%1 Service Response Time Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt))));
    setWindowSubtitle(subtitle);

    // Add number of columns for this stats_tree
    QStringList header_labels;
    for (int col = 0; col < NUM_SRT_COLUMNS; col++) {
        header_labels.push_back(service_response_time_get_column_name(col));
    }
    statsTreeWidget()->setColumnCount(header_labels.count());
    statsTreeWidget()->setHeaderLabels(header_labels);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == SRT_COLUMN_PROCEDURE) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    addFilterActions();

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }

    connect(statsTreeWidget(), SIGNAL(itemChanged(QTreeWidgetItem*,int)),
            this, SLOT(statsTreeWidgetItemChanged()));
}
Exemple #4
0
void register_follow_stream(const int proto_id, const char* tap_listener,
                            follow_conv_filter_func conv_filter, follow_index_filter_func index_filter, follow_address_filter_func address_filter,
                            follow_port_to_display_func port_to_display, tap_packet_cb tap_handler)
{
  register_follow_t *follower;
  DISSECTOR_ASSERT(tap_listener);
  DISSECTOR_ASSERT(conv_filter);
  DISSECTOR_ASSERT(index_filter);
  DISSECTOR_ASSERT(address_filter);
  DISSECTOR_ASSERT(port_to_display);
  DISSECTOR_ASSERT(tap_handler);

  follower = wmem_new(wmem_epan_scope(), register_follow_t);

  follower->proto_id       = proto_id;
  follower->tap_listen_str = tap_listener;
  follower->conv_filter    = conv_filter;
  follower->index_filter   = index_filter;
  follower->address_filter = address_filter;
  follower->port_to_display = port_to_display;
  follower->tap_handler    = tap_handler;

  if (registered_followers == NULL)
    registered_followers = wmem_tree_new(wmem_epan_scope());

  wmem_tree_insert_string(registered_followers, proto_get_protocol_short_name(find_protocol_by_id(proto_id)), follower, 0);
}
void register_service_response_tables(gpointer data, gpointer)
{
    register_srt_t *srt = (register_srt_t*)data;
    const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
    const char *cfg_abbr = srt_table_get_tap_string(srt);
    tpdCreator tpd_creator = ServiceResponseTimeDialog::createSrtDialog;

    /* XXX - These dissectors haven't been converted over to due to an "interactive input dialog" for their
       tap data.  Let those specific dialogs register for themselves */
    if (strcmp(short_name, "DCERPC") == 0) {
        short_name = "DCE-RPC";
        tpd_creator = RpcServiceResponseTimeDialog::createDceRpcSrtDialog;
    } else if (strcmp(short_name, "RPC") == 0) {
        short_name = "ONC-RPC";
        tpd_creator = RpcServiceResponseTimeDialog::createOncRpcSrtDialog;
    }

    cfg_str_to_srt_[cfg_abbr] = srt;
    TapParameterDialog::registerDialog(
                short_name,
                cfg_abbr,
                REGISTER_STAT_GROUP_RESPONSE_TIME,
                srt_init,
                tpd_creator);
}
static gint
insert_sorted_by_table_name(gconstpointer aparam, gconstpointer bparam)
{
    const register_ct_t *a = (register_ct_t *)aparam;
    const register_ct_t *b = (register_ct_t *)bparam;

    return g_ascii_strcasecmp(proto_get_protocol_short_name(find_protocol_by_id(a->proto_id)), proto_get_protocol_short_name(find_protocol_by_id(b->proto_id)));
}
static void
rtd_set_title(rtd_t *rr)
{
	gchar *str;

	str = g_strdup_printf("%s Service Response Time statistics", proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rr->rtd))));
	set_window_title(rr->gtk_data.win, str);
	g_free(str);
}
Exemple #8
0
expert_module_t *expert_register_protocol(int id)
{
	expert_module_t *module;
	protocol_t      *protocol;

	protocol = find_protocol_by_id(id);

	module = wmem_new(wmem_epan_scope(), expert_module_t);
	module->proto_id = id;
	module->proto_name = proto_get_protocol_short_name(protocol);

	return module;
}
static char *
hfinfo_to_name(const header_field_info *hfinfo)
{
	if (hfinfo->parent == -1) {
		protocol_t *protocol = find_protocol_by_id(hfinfo->id);

		return g_strdup_printf("%s - %s", proto_get_protocol_short_name(protocol), proto_get_protocol_long_name(protocol));
	}
	if (hfinfo->blurb != NULL && hfinfo->blurb[0] != '\0')
		return g_strdup_printf("%s - %s (%s)", hfinfo->abbrev, hfinfo->name, hfinfo->blurb);
	else
		return g_strdup_printf("%s - %s", hfinfo->abbrev, hfinfo->name);
}
void register_response_time_delay_tables(gpointer data, gpointer)
{
    register_rtd_t *rtd = (register_rtd_t*)data;
    const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
    const char *cfg_abbr = rtd_table_get_tap_string(rtd);

    cfg_str_to_rtd_[cfg_abbr] = rtd;
    TapParameterDialog::registerDialog(
                short_name,
                cfg_abbr,
                REGISTER_STAT_GROUP_RESPONSE_TIME,
                rtd_init,
                ResponseTimeDelayDialog::createRtdDialog);
}
void ProtocolPreferencesMenu::setModule(const char *module_name)
{
    QAction *action;
    int proto_id = -1;

    if (module_name) {
        proto_id = proto_get_id_by_filter_name(module_name);
    }

    clear();
    module_name_.clear();
    module_ = NULL;

    protocol_ = find_protocol_by_id(proto_id);
    const QString long_name = proto_get_protocol_long_name(protocol_);
    const QString short_name = proto_get_protocol_short_name(protocol_);
    if (!module_name || proto_id < 0 || !protocol_) {
        action = addAction(tr("No protocol preferences available"));
        action->setDisabled(true);
        return;
    }

    QAction *disable_action = new QAction(tr("Disable %1" UTF8_HORIZONTAL_ELLIPSIS).arg(short_name), this);
    connect(disable_action, SIGNAL(triggered(bool)), this, SLOT(disableProtocolTriggered()));

    module_ = prefs_find_module(module_name);
    if (!module_ || !prefs_is_registered_protocol(module_name)) {
        action = addAction(tr("%1 has no preferences").arg(long_name));
        action->setDisabled(true);
        addSeparator();
        addAction(disable_action);
        return;
    }

    module_name_ = module_name;

    action = addAction(tr("Open %1 preferences" UTF8_HORIZONTAL_ELLIPSIS).arg(long_name));
    action->setData(QString(module_name));
    connect(action, SIGNAL(triggered(bool)), this, SLOT(modulePreferencesTriggered()));
    addSeparator();

    prefs_pref_foreach(module_, add_prefs_menu_item, this);

    if (!actions().last()->isSeparator()) {
        addSeparator();
    }
    addAction(disable_action);
}
// Nearly identical to SupportedProtocolsDialog::fillTree.
void DisplayFilterExpressionDialog::fillTree()
{
    void *proto_cookie;
    QList <QTreeWidgetItem *> proto_list;

    for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1;
         proto_id = proto_get_next_protocol(&proto_cookie)) {
        protocol_t *protocol = find_protocol_by_id(proto_id);
        if (!proto_is_protocol_enabled(protocol)) continue;

        QTreeWidgetItem *proto_ti = new QTreeWidgetItem(proto_type_);
        QString label = QString("%1 " UTF8_MIDDLE_DOT " %3")
                .arg(proto_get_protocol_short_name(protocol))
                .arg(proto_get_protocol_long_name(protocol));
        proto_ti->setText(0, label);
        proto_ti->setData(0, Qt::UserRole, QVariant::fromValue(proto_id));
        proto_list << proto_ti;
    }

    wsApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers, 1);

    ui->fieldTreeWidget->invisibleRootItem()->addChildren(proto_list);
    ui->fieldTreeWidget->sortByColumn(0, Qt::AscendingOrder);

    int field_count = 0;
    foreach (QTreeWidgetItem *proto_ti, proto_list) {
        void *field_cookie;
        int proto_id = proto_ti->data(0, Qt::UserRole).toInt();

        QList <QTreeWidgetItem *> field_list;
        for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL;
             hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
            if (hfinfo->same_name_prev_id != -1) continue; // Ignore duplicate names.

            QTreeWidgetItem *field_ti = new QTreeWidgetItem(field_type_);
            QString label = QString("%1 " UTF8_MIDDLE_DOT " %3").arg(hfinfo->abbrev).arg(hfinfo->name);
            field_ti->setText(0, label);
            field_ti->setData(0, Qt::UserRole, VariantPointer<header_field_info>::asQVariant(hfinfo));
            field_list << field_ti;

            field_count++;
            if (field_count % 10000 == 0) {
                wsApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers, 1);
            }
        }
        std::sort(field_list.begin(), field_list.end());
        proto_ti->addChildren(field_list);
    }
gboolean register_response_time_delay_tables(const void *, void *value, void*)
{
    register_rtd_t *rtd = (register_rtd_t*)value;
    const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
    char *cfg_abbr = rtd_table_get_tap_string(rtd);

    cfg_str_to_rtd_[cfg_abbr] = rtd;
    TapParameterDialog::registerDialog(
                short_name,
                cfg_abbr,
                REGISTER_STAT_GROUP_RESPONSE_TIME,
                rtd_init,
                ResponseTimeDelayDialog::createRtdDialog);
    g_free(cfg_abbr);
    return FALSE;
}
void SupportedProtocolsDialog::fillTree()
{
    void *proto_cookie;
    QList <QTreeWidgetItem *> proto_list;

    for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1;
         proto_id = proto_get_next_protocol(&proto_cookie)) {
        protocol_t *protocol = find_protocol_by_id(proto_id);
        QTreeWidgetItem *proto_ti = new QTreeWidgetItem();
        proto_ti->setText(name_col_, proto_get_protocol_short_name(protocol));
        proto_ti->setText(filter_col_, proto_get_protocol_filter_name(proto_id));
        // type_col_ empty
        proto_ti->setText(descr_col_, proto_get_protocol_long_name(protocol));
        proto_ti->setData(name_col_, Qt::UserRole, proto_id);
        proto_list << proto_ti;
    }

    updateStatistics();
    ui->protoTreeWidget->invisibleRootItem()->addChildren(proto_list);
    ui->protoTreeWidget->sortByColumn(name_col_, Qt::AscendingOrder);

    foreach (QTreeWidgetItem *proto_ti, proto_list) {
        void *field_cookie;
        int proto_id = proto_ti->data(name_col_, Qt::UserRole).toInt();
        QList <QTreeWidgetItem *> field_list;
        for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL;
             hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
            if (hfinfo->same_name_prev_id != -1) continue;

            QTreeWidgetItem *field_ti = new QTreeWidgetItem();
            field_ti->setText(name_col_, hfinfo->name);
            field_ti->setText(filter_col_, hfinfo->abbrev);
            field_ti->setText(type_col_, ftype_pretty_name(hfinfo->type));
            field_ti->setText(descr_col_, hfinfo->blurb);
            field_list << field_ti;

            field_count_++;
            if (field_count_ % 1000 == 0) updateStatistics();
        }
        std::sort(field_list.begin(), field_list.end());
        proto_ti->addChildren(field_list);
    }
Exemple #15
0
void init_iousers(struct register_ct *ct, const char *filter)
{
	io_users_t *iu;
	GString *error_string;

	iu = g_new0(io_users_t, 1);
	iu->type = proto_get_protocol_short_name(find_protocol_by_id(get_conversation_proto_id(ct)));
	iu->filter = g_strdup(filter);
	iu->hash.user_data = iu;

	error_string = register_tap_listener(proto_get_protocol_filter_name(get_conversation_proto_id(ct)), &iu->hash, filter, 0, NULL, get_conversation_packet_func(ct), iousers_draw);
	if (error_string) {
		g_free(iu);
		fprintf(stderr, "tshark: Couldn't register conversations tap: %s\n",
		    error_string->str);
		g_string_free(error_string, TRUE);
		exit(1);
	}

}
ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &cf, register_rtd *rtd, const QString filter, int help_topic) :
    TapParameterDialog(parent, cf, help_topic),
    rtd_(rtd)
{
    QString subtitle = QString("%1 Response Time Delay Statistics")
            .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
    setWindowSubtitle(subtitle);

    statsTreeWidget()->setHeaderLabels(header_names_);

    for (int col = 0; col < statsTreeWidget()->columnCount(); col++) {
        if (col == col_type_) continue;
        statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight);
    }

    setDisplayFilter(filter);

    if (!filter.isEmpty()) {
        setDisplayFilter(filter);
    }
}
Exemple #17
0
static void
init_srt_tables(register_srt_t* srt, const char *filter)
{
	srt_t *ui;
	GString *error_string;

	ui = g_new0(srt_t, 1);
	ui->type = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
	ui->filter = g_strdup(filter);
	ui->data.srt_array = global_srt_array;
	ui->data.user_data = ui;

	error_string = register_tap_listener(get_srt_tap_listener_name(srt), &ui->data, filter, 0, NULL, get_srt_packet_func(srt), srt_draw, NULL);
	if (error_string) {
		free_srt_table(srt, global_srt_array);
		g_free(ui);
		cmdarg_err("Couldn't register srt tap: %s", error_string->str);
		g_string_free(error_string, TRUE);
		exit(1);
	}
}
Exemple #18
0
static void
init_rtd_tables(register_rtd_t* rtd, const char *filter)
{
	GString *error_string;
	rtd_t* ui;

	ui = g_new0(rtd_t, 1);
	ui->type = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
	ui->filter = g_strdup(filter);
	ui->vs_type = get_rtd_value_string(rtd);
	ui->rtd.user_data = ui;

	rtd_table_dissector_init(rtd, &ui->rtd.stat_table, NULL, NULL);

	error_string = register_tap_listener(get_rtd_tap_listener_name(rtd), &ui->rtd, filter, 0, NULL, get_rtd_packet_func(rtd), rtd_draw);
	if (error_string) {
		free_rtd_table(&ui->rtd.stat_table, NULL, NULL);
		fprintf(stderr, "tshark: Couldn't register srt tap: %s\n", error_string->str);
		g_string_free(error_string, TRUE);
		exit(1);
	}
}
Exemple #19
0
		exit(1);
	}

	/* Need to create the SRT array now */
	global_srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table*));

	srt_table_dissector_init(srt, global_srt_array);
	init_srt_tables(srt, filter);
}

/* Set GUI fields for register_srt list */
gboolean
register_srt_tables(const void *key _U_, void *value, void *userdata _U_)
{
	register_srt_t *srt = (register_srt_t*)value;
	const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
	stat_tap_ui ui_info;
	gchar *cli_string;

	/* XXX - CAMEL dissector hasn't been converted over due seemingly different tap packet
	   handling functions.  So let the existing TShark CAMEL tap keep its registration */
	if (strcmp(short_name, "CAMEL") == 0)
		return FALSE;

	cli_string = srt_table_get_tap_string(srt);
	ui_info.group = REGISTER_STAT_GROUP_RESPONSE_TIME;
	ui_info.title = NULL;   /* construct this from the protocol info? */
	ui_info.cli_string = cli_string;
	ui_info.tap_init_cb = dissector_srt_init;
	ui_info.nparams = 0;
	ui_info.params = NULL;
ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo) :
    WiresharkDialog(parent, cf),
    eo_ui_(new Ui::ExportObjectDialog),
    save_bt_(NULL),
    save_all_bt_(NULL),
    model_(eo, this),
    proxyModel_(this)
{
    QPushButton *close_bt;

    eo_ui_->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose, true);

    proxyModel_.setSourceModel(&model_);
    eo_ui_->objectTree->setModel(&proxyModel_);

    proxyModel_.setFilterFixedString("");
    proxyModel_.setFilterCaseSensitivity(Qt::CaseInsensitive);
    proxyModel_.setFilterKeyColumn(-1);

#if defined(Q_OS_MAC)
    eo_ui_->progressLabel->setAttribute(Qt::WA_MacSmallSize, true);
    eo_ui_->progressBar->setAttribute(Qt::WA_MacSmallSize, true);
#endif

    connect(&model_, SIGNAL(rowsInserted(QModelIndex,int,int)),
            this, SLOT(modelDataChanged(QModelIndex)));
    connect(&model_, SIGNAL(modelReset()), this, SLOT(modelRowsReset()));
    connect(eo_ui_->filterLine, &QLineEdit::textChanged,
            &proxyModel_, &QSortFilterProxyModel::setFilterFixedString);


    save_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::Save);
    save_all_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::SaveAll);
    close_bt = eo_ui_->buttonBox->button(QDialogButtonBox::Close);

    setWindowTitle(wsApp->windowTitleString(QStringList() << tr("Export") << tr("%1 object list").arg(proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))))));

    if (save_bt_) save_bt_->setEnabled(false);
    if (save_all_bt_) save_all_bt_->setEnabled(false);
    if (close_bt) close_bt->setDefault(true);

    connect(&cap_file_, SIGNAL(captureEvent(CaptureEvent)),
            this, SLOT(captureEvent(CaptureEvent)));

    show();
    raise();
    activateWindow();
}
 ProtocolTreeWidgetItem(QTreeWidgetItem *parent, const protocol_t *protocol) :
     EnableProtocolTreeWidgetItem (parent, proto_get_protocol_long_name(protocol), proto_get_protocol_short_name(protocol), proto_is_protocol_enabled(protocol), protocol_type_),
     protocol_(protocol)
 {
 }
bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index, int stream_num)
{
    QString             follow_filter;
    const char          *hostname0 = NULL, *hostname1 = NULL;
    char                *port0 = NULL, *port1 = NULL;
    QString             server_to_client_string;
    QString             client_to_server_string;
    QString             both_directions_string;
    gboolean            is_follower = FALSE;

    resetStream();

    if (file_closed_)
    {
        QMessageBox::warning(this, tr("No capture file."), tr("Please make sure you have a capture file opened."));
        return false;
    }

    if (cap_file_.capFile()->edt == NULL)
    {
        QMessageBox::warning(this, tr("Error following stream."), tr("Capture file invalid."));
        return false;
    }

    is_follower = proto_is_frame_protocol(cap_file_.capFile()->edt->pi.layers, proto_get_protocol_filter_name(get_follow_proto_id(follower_)));
    if (!is_follower) {
        QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a %1 packet selected.").arg
                                (proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_)))));
        return false;
    }

    if (follow_type_ == FOLLOW_SSL)
    {
        /* we got ssl so we can follow */
        removeStreamControls();
    }

    follow_reset_stream(&follow_info_);

    /* Create a new filter that matches all packets in the TCP stream,
        and set the display filter entry accordingly */
    if (use_stream_index) {
        follow_filter = gchar_free_to_qstring(get_follow_index_func(follower_)(stream_num));
    } else {
        follow_filter = gchar_free_to_qstring(get_follow_conv_func(follower_)(&cap_file_.capFile()->edt->pi, &stream_num));
    }
    if (follow_filter.isEmpty()) {
        QMessageBox::warning(this,
                             tr("Error creating filter for this stream."),
                             tr("A transport or network layer header is needed."));
        return false;
    }

    /* append the negation */
    if(!previous_filter.isEmpty()) {
        filter_out_filter_ = QString("%1 and !(%2)")
                .arg(previous_filter).arg(follow_filter);
    }
    else
    {
        filter_out_filter_ = QString("!(%1)").arg(follow_filter);
    }

    /* data will be passed via tap callback*/
    if (!registerTapListener(get_follow_tap_string(follower_), &follow_info_,
                                follow_filter.toUtf8().constData(),
                                0, NULL, get_follow_tap_handler(follower_), NULL)) {
        return false;
    }

    switch (follow_type_)
    {
    case FOLLOW_TCP:
    {
        int stream_count = get_tcp_stream_count();
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count-1);
        ui->streamNumberSpinBox->setValue(stream_num);
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_UDP:
    {
        int stream_count = get_udp_stream_count();
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count-1);
        ui->streamNumberSpinBox->setValue(stream_num);
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_SSL:
    case FOLLOW_HTTP:
        /* No extra handling */
        break;
    }

    beginRetapPackets();
    updateWidgets(true);

    /* Run the display filter so it goes in effect - even if it's the
       same as the previous display filter. */
    emit updateFilter(follow_filter, TRUE);

    removeTapListeners();

    hostname0 = address_to_name(&follow_info_.client_ip);
    hostname1 = address_to_name(&follow_info_.server_ip);

    port0 = get_follow_port_to_display(follower_)(NULL, follow_info_.client_port);
    port1 = get_follow_port_to_display(follower_)(NULL, follow_info_.server_port);

    server_to_client_string =
            QString("%1:%2 %3 %4:%5 (%6)")
            .arg(hostname0).arg(port0)
            .arg(UTF8_RIGHTWARDS_ARROW)
            .arg(hostname1).arg(port1)
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[0],
                                        format_size_unit_bytes|format_size_prefix_si)));

    client_to_server_string =
            QString("%1:%2 %3 %4:%5 (%6)")
            .arg(hostname1).arg(port1)
            .arg(UTF8_RIGHTWARDS_ARROW)
            .arg(hostname0).arg(port0)
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[1],
                                        format_size_unit_bytes|format_size_prefix_si)));

    wmem_free(NULL, port0);
    wmem_free(NULL, port1);

    both_directions_string = QString("Entire conversation (%1)")
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
                    format_size_unit_bytes|format_size_prefix_si)));
    setWindowSubtitle(tr("Follow %1 Stream (%2)").arg(proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_))))
                                                 .arg(follow_filter));

    ui->cbDirections->clear();
    ui->cbDirections->addItem(both_directions_string);
    ui->cbDirections->addItem(client_to_server_string);
    ui->cbDirections->addItem(server_to_client_string);

    followStream();
    fillHintLabel(-1);

    updateWidgets(false);
    endRetapPackets();
    return true;
}