Exemple #1
0
QString &PacketList::getFilterFromRowAndColumn()
{
    frame_data *fdata;
    QString &filter = *new QString();
    int row = currentIndex().row();

    if (!cap_file_ || !packet_list_model_ || ctx_column_ < 0 || ctx_column_ >= cap_file_->cinfo.num_cols) return filter;

    fdata = packet_list_model_->getRowFdata(row);

    if (fdata != NULL) {
        epan_dissect_t edt;

        if (!cf_read_record(cap_file_, fdata))
            return filter; /* error reading the record */
        /* proto tree, visible. We need a proto tree if there's custom columns */
        epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), FALSE);
        col_custom_prime_edt(&edt, &cap_file_->cinfo);

        epan_dissect_run(&edt, cap_file_->cd_t, &cap_file_->phdr, frame_tvbuff_new_buffer(fdata, &cap_file_->buf), fdata, &cap_file_->cinfo);
        epan_dissect_fill_in_columns(&edt, TRUE, TRUE);

        if ((cap_file_->cinfo.col_custom_occurrence[ctx_column_]) ||
            (strchr (cap_file_->cinfo.col_expr.col_expr_val[ctx_column_], ',') == NULL))
        {
            /* Only construct the filter when a single occurrence is displayed
             * otherwise we might end up with a filter like "ip.proto==1,6".
             *
             * Or do we want to be able to filter on multiple occurrences so that
             * the filter might be calculated as "ip.proto==1 && ip.proto==6"
             * instead?
             */
            if (strlen(cap_file_->cinfo.col_expr.col_expr[ctx_column_]) != 0 &&
                strlen(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]) != 0) {
                /* leak a little but safer than ep_ here */
                if (cap_file_->cinfo.col_fmt[ctx_column_] == COL_CUSTOM) {
                    header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_custom_field[ctx_column_]);
                    if (hfi->parent == -1) {
                        /* Protocol only */
                        filter.append(cap_file_->cinfo.col_expr.col_expr[ctx_column_]);
                    } else if (hfi->type == FT_STRING) {
                        /* Custom string, add quotes */
                        filter.append(QString("%1 == \"%2\"")
                                      .arg(cap_file_->cinfo.col_expr.col_expr[ctx_column_])
                                      .arg(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]));
                    }
                }
                if (filter.isEmpty()) {
                    filter.append(QString("%1 == %2")
                                  .arg(cap_file_->cinfo.col_expr.col_expr[ctx_column_])
                                  .arg(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]));
                }
            }
        }

        epan_dissect_cleanup(&edt);
    }

    return filter;
}
QVariant PacketListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer());
    if (!record)
        return QVariant();
    frame_data *fdata = record->getFdata();
    if (!fdata)
        return QVariant();

    switch (role) {
    case Qt::FontRole:
        return wsApp->monospaceFont();
    case Qt::TextAlignmentRole:
        switch(recent_get_column_xalign(index.column())) {
        case COLUMN_XALIGN_RIGHT:
            return Qt::AlignRight;
            break;
        case COLUMN_XALIGN_CENTER:
            return Qt::AlignCenter;
            break;
        case COLUMN_XALIGN_LEFT:
            return Qt::AlignLeft;
            break;
        case COLUMN_XALIGN_DEFAULT:
        default:
            if (right_justify_column(index.column(), cap_file_)) {
                return Qt::AlignRight;
            }
            break;
        }
        return Qt::AlignLeft;

    case Qt::BackgroundRole:
        const color_t *color;
        if (fdata->flags.ignored) {
            color = &prefs.gui_ignored_bg;
        } else if (fdata->flags.marked) {
            color = &prefs.gui_marked_bg;
        } else if (fdata->color_filter) {
            const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter;
            color = &color_filter->bg_color;
        } else {
            return QVariant();
        }
//        g_log(NULL, G_LOG_LEVEL_DEBUG, "i: %d m: %d cf: %p bg: %d %d %d", fdata->flags.ignored, fdata->flags.marked, fdata->color_filter, color->red, color->green, color->blue);
        return QColor(color->red >> 8, color->green >> 8, color->blue >> 8);
    case Qt::ForegroundRole:
        if (fdata->flags.ignored) {
            color = &prefs.gui_ignored_fg;
        } else if (fdata->flags.marked) {
            color = &prefs.gui_marked_fg;
        } else if (fdata->color_filter) {
            const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter;
            color = &color_filter->fg_color;
        } else {
            return QVariant();
        }
        return QColor(color->red >> 8, color->green >> 8, color->blue >> 8);
    case Qt::DisplayRole:
        // Need packet data -- fall through
        break;
    default:
        return QVariant();
    }

    int col_num = index.column();
//    g_log(NULL, G_LOG_LEVEL_DEBUG, "showing col %d", col_num);

    if (!cap_file_ || col_num > cap_file_->cinfo.num_cols)
        return QVariant();

    epan_dissect_t edt;
    column_info *cinfo;
    gboolean create_proto_tree;
    struct wtap_pkthdr phdr; /* Packet header */
    Buffer buf;  /* Packet data */
    gboolean dissect_columns = TRUE; // XXX - Currently only a placeholder

    if (dissect_columns && cap_file_)
        cinfo = &cap_file_->cinfo;
    else
        cinfo = NULL;

    buffer_init(&buf, 1500);
    if (!cap_file_ || !cf_read_frame_r(cap_file_, fdata, &phdr, &buf)) {
        /*
         * Error reading the frame.
         *
         * Don't set the color filter for now (we might want
         * to colorize it in some fashion to warn that the
         * row couldn't be filled in or colorized), and
         * set the columns to placeholder values, except
         * for the Info column, where we'll put in an
         * error message.
         */
        if (dissect_columns) {
            col_fill_in_error(cinfo, fdata, FALSE, FALSE /* fill_fd_columns */);

            //            for(gint col = 0; col < cinfo->num_cols; ++col) {
            //                /* Skip columns based on frame_data because we already store those. */
            //                if (!col_based_on_frame_data(cinfo, col))
            //                    packet_list_change_record(packet_list, record->physical_pos, col, cinfo);
            //            }
            //            record->columnized = TRUE;
        }
        if (enable_color_) {
            fdata->color_filter = NULL;
            //            record->colorized = TRUE;
        }
        buffer_free(&buf);
        return QVariant();	/* error reading the frame */
    }

    create_proto_tree = (color_filters_used() && enable_color_) ||
                        (have_custom_cols(cinfo) && dissect_columns);

    epan_dissect_init(&edt, cap_file_->epan,
                      create_proto_tree,
                      FALSE /* proto_tree_visible */);

    if (enable_color_)
        color_filters_prime_edt(&edt);
    if (dissect_columns)
        col_custom_prime_edt(&edt, cinfo);

    epan_dissect_run(&edt, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, cinfo);

    if (enable_color_)
        fdata->color_filter = color_filters_colorize_packet(&edt);

    if (dissect_columns) {
        /* "Stringify" non frame_data vals */
        epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */);

        //            for(col = 0; col < cinfo->num_cols; ++col) {
        //                    /* Skip columns based on frame_data because we already store those. */
        //                    if (!col_based_on_frame_data(cinfo, col))
        //                            packet_list_change_record(packet_list, record->physical_pos, col, cinfo);
        //            }
//        g_log(NULL, G_LOG_LEVEL_DEBUG, "d_c %d: %s", col_num, cinfo->col_data[col_num]);
    }

    //    if (dissect_columns)
    //            record->columnized = TRUE;
    //    if (enable_color_)
    //            record->colorized = TRUE;

    epan_dissect_cleanup(&edt);
    buffer_free(&buf);

    switch (role) {
    case Qt::DisplayRole:
        return record->data(col_num, cinfo);
        break;
    default:
        break;
    }
    return QVariant();
}
void PacketListRecord::dissect(capture_file *cap_file, bool dissect_color)
{
    // packet_list_store.c:packet_list_dissect_and_cache_record
    epan_dissect_t edt;
    column_info *cinfo = NULL;
    gboolean create_proto_tree;
    struct wtap_pkthdr phdr; /* Packet header */
    Buffer buf; /* Packet data */
    gboolean dissect_columns = col_text_.isEmpty() || data_ver_ != col_data_ver_;

    if (!cap_file) {
        return;
    }

    memset(&phdr, 0, sizeof(struct wtap_pkthdr));

    if (dissect_columns) {
        cinfo = &cap_file->cinfo;
    }

    ws_buffer_init(&buf, 1500);
    if (!cf_read_record_r(cap_file, fdata_, &phdr, &buf)) {
        /*
         * Error reading the record.
         *
         * Don't set the color filter for now (we might want
         * to colorize it in some fashion to warn that the
         * row couldn't be filled in or colorized), and
         * set the columns to placeholder values, except
         * for the Info column, where we'll put in an
         * error message.
         */
        if (dissect_columns) {
            col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */);

            cacheColumnStrings(cinfo);
        }
        if (dissect_color) {
            fdata_->color_filter = NULL;
            colorized_ = true;
        }
        ws_buffer_free(&buf);
        return;    /* error reading the record */
    }

    create_proto_tree = (dissect_color && color_filters_used()) ||
                        (dissect_columns && have_custom_cols(cinfo));

    epan_dissect_init(&edt, cap_file->epan,
                      create_proto_tree,
                      FALSE /* proto_tree_visible */);

    /* Re-color when the coloring rules are changed via the UI. */
    if (dissect_color) {
        color_filters_prime_edt(&edt);
        fdata_->flags.need_colorize = 1;
    }
    if (dissect_columns)
        col_custom_prime_edt(&edt, cinfo);

    /*
     * XXX - need to catch an OutOfMemoryError exception and
     * attempt to recover from it.
     */
    epan_dissect_run(&edt, cap_file->cd_t, &phdr, frame_tvbuff_new_buffer(fdata_, &buf), fdata_, cinfo);

    if (dissect_columns) {
        /* "Stringify" non frame_data vals */
        epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */);
        cacheColumnStrings(cinfo);
    }

    if (dissect_color) {
        colorized_ = true;
    }
    data_ver_ = col_data_ver_;

    packet_info *pi = &edt.pi;
    conv_ = find_conversation(pi->num, &pi->src, &pi->dst, pi->ptype,
                              pi->srcport, pi->destport, 0);

    epan_dissect_cleanup(&edt);
    ws_buffer_free(&buf);
}
void PacketListRecord::dissect(capture_file *cap_file, bool dissect_color)
{
    // packet_list_store.c:packet_list_dissect_and_cache_record
    epan_dissect_t edt;
    column_info *cinfo = NULL;
    gboolean create_proto_tree;
    wtap_rec rec; /* Record metadata */
    Buffer buf;   /* Record data */

    if (!col_text_) col_text_ = new ColumnTextList;
    gboolean dissect_columns = col_text_->isEmpty() || data_ver_ != col_data_ver_;

    if (!cap_file) {
        return;
    }

    memset(&rec, 0, sizeof rec);

    if (dissect_columns) {
        cinfo = &cap_file->cinfo;
    }

    ws_buffer_init(&buf, 1500);
    if (!cf_read_record_r(cap_file, fdata_, &rec, &buf)) {
        /*
         * Error reading the record.
         *
         * Don't set the color filter for now (we might want
         * to colorize it in some fashion to warn that the
         * row couldn't be filled in or colorized), and
         * set the columns to placeholder values, except
         * for the Info column, where we'll put in an
         * error message.
         */
        if (dissect_columns) {
            col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */);

            cacheColumnStrings(cinfo);
        }
        if (dissect_color) {
            fdata_->color_filter = NULL;
            colorized_ = true;
        }
        ws_buffer_free(&buf);
        return;    /* error reading the record */
    }

    /*
     * Determine whether we need to create a protocol tree.
     * We do if:
     *
     *    we're going to apply a color filter to this packet;
     *
     *    we're need to fill in the columns and we have custom columns
     *    (which require field values, which currently requires that
     *    we build a protocol tree).
     *
     *    XXX - field extractors?  (Not done for GTK+....)
     */
    create_proto_tree = ((dissect_color && color_filters_used()) ||
                         (dissect_columns && (have_custom_cols(cinfo) ||
                                              have_field_extractors())));

    epan_dissect_init(&edt, cap_file->epan,
                      create_proto_tree,
                      FALSE /* proto_tree_visible */);

    /* Re-color when the coloring rules are changed via the UI. */
    if (dissect_color) {
        color_filters_prime_edt(&edt);
        fdata_->flags.need_colorize = 1;
    }
    if (dissect_columns)
        col_custom_prime_edt(&edt, cinfo);

    /*
     * XXX - need to catch an OutOfMemoryError exception and
     * attempt to recover from it.
     */
    epan_dissect_run(&edt, cap_file->cd_t, &rec,
                     frame_tvbuff_new_buffer(&cap_file->provider, fdata_, &buf),
                     fdata_, cinfo);

    if (dissect_columns) {
        /* "Stringify" non frame_data vals */
        epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */);
        cacheColumnStrings(cinfo);
    }

    if (dissect_color) {
        colorized_ = true;
    }
    data_ver_ = col_data_ver_;

    packet_info *pi = &edt.pi;
    conv_ = find_conversation_pinfo(pi, 0);

    epan_dissect_cleanup(&edt);
    ws_buffer_free(&buf);
}