/* Colorize a single packet of the packet list (old packet list) * (row is only _U_ for the NEW_PACKET_LIST case * Return the color_t for later use (new packet list) */ color_filter_t * color_filters_colorize_packet(gint row _U_, epan_dissect_t *edt) { GSList *curr; color_filter_t *colorf; /* If we have color filters, "search" for the matching one. */ if (color_filters_used()) { curr = color_filter_list; while(curr != NULL) { colorf = curr->data; if ( (!colorf->disabled) && (colorf->c_colorfilter != NULL) && dfilter_apply_edt(colorf->c_colorfilter, edt)) { /* this is the filter to use, apply it to the packet list */ #ifndef NEW_PACKET_LIST /* We'll do this in the column cell function instead. */ packet_list_set_colors(row, &(colorf->fg_color), &(colorf->bg_color)); #endif return colorf; } curr = g_slist_next(curr); } } return NULL; }
/* this function is called after a packet has been fully dissected to push the tapped data to all extensions that has callbacks registered. */ void tap_push_tapped_queue(epan_dissect_t *edt) { tap_packet_t *tp; volatile tap_listener_t *tl; guint i; /* nothing to do, just return */ if(!tapping_is_active){ return; } tapping_is_active=FALSE; /* nothing to do, just return */ if(!tap_packet_index){ return; } /* loop over all tap listeners and call the listener callback for all packets that match the filter. */ for(i=0;i<tap_packet_index;i++){ for(tl=tap_listener_queue;tl;tl=tl->next){ tp=&tap_packet_array[i]; /* Don't tap the packet if it's an "error" unless the listener tells us to */ if (!(tp->flags & TAP_PACKET_IS_ERROR_PACKET) || (tl->flags & TL_REQUIRES_ERROR_PACKETS)) { if(tp->tap_id==tl->tap_id){ gboolean passed=TRUE; if(tl->code){ passed=dfilter_apply_edt(tl->code, edt); } if(passed && tl->packet){ tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data); } } } } } }
/* * Return the color_t for later use */ const color_filter_t * color_filters_colorize_packet(epan_dissect_t *edt) { GSList *curr; color_filter_t *colorf; /* If we have color filters, "search" for the matching one. */ if (color_filters_used()) { curr = color_filter_list; while(curr != NULL) { colorf = (color_filter_t *)curr->data; if ( (!colorf->disabled) && (colorf->c_colorfilter != NULL) && dfilter_apply_edt(colorf->c_colorfilter, edt)) { return colorf; } curr = g_slist_next(curr); } } return NULL; }
/* this function is called after a packet has been fully dissected to push the tapped data to all extensions that has callbacks registered. */ void tap_push_tapped_queue(epan_dissect_t *edt) { tap_packet_t *tp; tap_listener_t *tl; guint i; /* nothing to do, just return */ if(!tapping_is_active){ return; } tapping_is_active=FALSE; /* nothing to do, just return */ if(!tap_packet_index){ return; } /* loop over all tap listeners and call the listener callback for all packets that match the filter. */ for(i=0;i<tap_packet_index;i++){ for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){ tp=&tap_packet_array[i]; if(tp->tap_id==tl->tap_id){ gboolean passed=TRUE; if(tl->code){ passed=dfilter_apply_edt(tl->code, edt); } if(passed && tl->packet){ tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data); } } } } }
/** * Given a handle on a capture file, and an offset within that file, * this function will read a packet and decide if it matches the display * filter. If it does, it calls proto_tree_get_fields() to read specific fields * into stdata. * * @return passed a boolean describing whether the packet matched the filter. */ gboolean process_packet(capture_file *cf, gint64 offset, st_data_t *stdata) { frame_data fdata; epan_dissect_t edt; gboolean passed; const struct wtap_pkthdr *whdr = wtap_phdr(cf->wth); union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth); const guchar *pd = wtap_buf_ptr(cf->wth); /* Count this packet. NB: the frame dissector uses this to determine frame.number */ cf->count++; /** * Initialize dissector tree */ epan_dissect_init(&edt, TRUE, TRUE); frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes); frame_data_set_before_dissect(&fdata, &cf->elapsed_time, &first_ts, &prev_dis_ts, &prev_cap_ts); passed = TRUE; // AB: prime the epan_dissect_t with the dfilter. if(cf->rfcode) { epan_dissect_prime_dfilter(&edt, cf->rfcode); } tap_queue_init(&edt); /** * Run the dissector on this packet */ epan_dissect_run(&edt, pseudo_header, pd, &fdata, NULL); tap_push_tapped_queue(&edt); // AB: Run the read filter if(cf->rfcode) { passed = dfilter_apply_edt(cf->rfcode, &edt); } else { passed = TRUE; } if(passed) { frame_data_set_after_dissect(&fdata, &cum_bytes, &prev_dis_ts); // stdata could be NULL if we are just counting packets if(stdata != NULL) proto_tree_get_fields(stdata, &edt); } epan_dissect_cleanup(&edt); frame_data_cleanup(&fdata); return passed; }
Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) : WiresharkDialog(parent, cf), ui(new Ui::Iax2AnalysisDialog), port_src_fwd_(0), port_dst_fwd_(0), port_src_rev_(0), port_dst_rev_(0) { ui->setupUi(this); setWindowSubtitle(tr("IAX2 Stream Analysis")); // XXX Use recent settings instead resize(parent.width() * 4 / 5, parent.height() * 4 / 5); ui->progressFrame->hide(); stream_ctx_menu_.addAction(ui->actionGoToPacket); stream_ctx_menu_.addAction(ui->actionNextProblem); stream_ctx_menu_.addSeparator(); stream_ctx_menu_.addAction(ui->actionSaveAudio); stream_ctx_menu_.addAction(ui->actionSaveForwardAudio); stream_ctx_menu_.addAction(ui->actionSaveReverseAudio); stream_ctx_menu_.addSeparator(); stream_ctx_menu_.addAction(ui->actionSaveCsv); stream_ctx_menu_.addAction(ui->actionSaveForwardCsv); stream_ctx_menu_.addAction(ui->actionSaveReverseCsv); stream_ctx_menu_.addSeparator(); stream_ctx_menu_.addAction(ui->actionSaveGraph); ui->forwardTreeWidget->installEventFilter(this); ui->forwardTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->forwardTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showStreamMenu(QPoint))); ui->reverseTreeWidget->installEventFilter(this); ui->reverseTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->reverseTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showStreamMenu(QPoint))); connect(ui->streamGraph, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(graphClicked(QMouseEvent*))); graph_ctx_menu_.addAction(ui->actionSaveGraph); QStringList header_labels; for (int i = 0; i < ui->forwardTreeWidget->columnCount(); i++) { header_labels << ui->forwardTreeWidget->headerItem()->text(i); } ui->reverseTreeWidget->setHeaderLabels(header_labels); memset(&src_fwd_, 0, sizeof(address)); memset(&dst_fwd_, 0, sizeof(address)); memset(&src_rev_, 0, sizeof(address)); memset(&dst_rev_, 0, sizeof(address)); QList<QCheckBox *> graph_cbs = QList<QCheckBox *>() << ui->fJitterCheckBox << ui->fDiffCheckBox << ui->rJitterCheckBox << ui->rDiffCheckBox; for (int i = 0; i < num_graphs_; i++) { QCPGraph *graph = ui->streamGraph->addGraph(); graph->setPen(QPen(ColorUtils::graph_colors_[i])); graph->setName(graph_cbs[i]->text()); graphs_ << graph; graph_cbs[i]->setChecked(true); graph_cbs[i]->setIcon(StockIcon::colorIcon(ColorUtils::graph_colors_[i], QPalette::Text)); } ui->streamGraph->xAxis->setLabel("Arrival Time"); ui->streamGraph->yAxis->setLabel("Value (ms)"); // We keep our temp files open for the lifetime of the dialog. The GTK+ // UI opens and closes at various points. QString tempname = QString("%1/wireshark_iax2_f").arg(QDir::tempPath()); fwd_tempfile_ = new QTemporaryFile(tempname, this); fwd_tempfile_->open(); tempname = QString("%1/wireshark_iax2_r").arg(QDir::tempPath()); rev_tempfile_ = new QTemporaryFile(tempname, this); rev_tempfile_->open(); if (fwd_tempfile_->error() != QFile::NoError || rev_tempfile_->error() != QFile::NoError) { err_str_ = tr("Unable to save RTP data."); ui->actionSaveAudio->setEnabled(false); ui->actionSaveForwardAudio->setEnabled(false); ui->actionSaveReverseAudio->setEnabled(false); } QMenu *save_menu = new QMenu(); save_menu->addAction(ui->actionSaveAudio); save_menu->addAction(ui->actionSaveForwardAudio); save_menu->addAction(ui->actionSaveReverseAudio); save_menu->addSeparator(); save_menu->addAction(ui->actionSaveCsv); save_menu->addAction(ui->actionSaveForwardCsv); save_menu->addAction(ui->actionSaveReverseCsv); save_menu->addSeparator(); save_menu->addAction(ui->actionSaveGraph); ui->buttonBox->button(QDialogButtonBox::Save)->setMenu(save_menu); const gchar *filter_text = "iax2 && (ip || ipv6)"; dfilter_t *sfcode; gchar *err_msg; if (!dfilter_compile(filter_text, &sfcode, &err_msg)) { QMessageBox::warning(this, tr("No IAX2 packets found"), QString("%1").arg(err_msg)); g_free(err_msg); close(); } if (!cap_file_.capFile() || !cap_file_.capFile()->current_frame) close(); frame_data *fdata = cap_file_.capFile()->current_frame; if (!cf_read_record(cap_file_.capFile(), fdata)) close(); epan_dissect_t edt; epan_dissect_init(&edt, cap_file_.capFile()->epan, TRUE, FALSE); epan_dissect_prime_dfilter(&edt, sfcode); epan_dissect_run(&edt, cap_file_.capFile()->cd_t, &cap_file_.capFile()->phdr, frame_tvbuff_new_buffer(fdata, &cap_file_.capFile()->buf), fdata, NULL); // This shouldn't happen (the menu item should be disabled) but check anyway if (!dfilter_apply_edt(sfcode, &edt)) { epan_dissect_cleanup(&edt); dfilter_free(sfcode); err_str_ = tr("Please select an IAX2 packet"); updateWidgets(); return; } dfilter_free(sfcode); /* ok, it is a IAX2 frame, so let's get the ip and port values */ COPY_ADDRESS(&(src_fwd_), &(edt.pi.src)); COPY_ADDRESS(&(dst_fwd_), &(edt.pi.dst)); port_src_fwd_ = edt.pi.srcport; port_dst_fwd_ = edt.pi.destport; /* assume the inverse ip/port combination for the reverse direction */ COPY_ADDRESS(&(src_rev_), &(edt.pi.dst)); COPY_ADDRESS(&(dst_rev_), &(edt.pi.src)); port_src_rev_ = edt.pi.destport; port_dst_rev_ = edt.pi.srcport; #if 0 /* check if it is Voice or MiniPacket */ bool ok; getIntFromProtoTree(edt.tree, "iax2", "iax2.call", &ok); if (!ok) { err_str_ = tr("Please select an IAX2 packet."); updateWidgets(); return; } #endif #ifdef IAX2_RTP_STREAM_CHECK rtpstream_tapinfot tapinfo; /* Register the tap listener */ memset(&tapinfo, 0, sizeof(rtpstream_tapinfot)); tapinfo.tap_data = this; tapinfo.mode = TAP_ANALYSE; // register_tap_listener_rtp_stream(&tapinfo, NULL); /* Scan for RTP streams (redissect all packets) */ rtpstream_scan(&tapinfo, cap_file_.capFile(), NULL); int num_streams = 0; GList *filtered_list = NULL; for (GList *strinfo_list = g_list_first(tapinfo.strinfo_list); strinfo_list; strinfo_list = g_list_next(strinfo_list)) { rtp_stream_info_t * strinfo = (rtp_stream_info_t*)(strinfo_list->data); << address_to_qstring(&strinfo->dest_addr) << address_to_qstring(&src_rev_) << address_to_qstring(&dst_rev_); if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_fwd_)) && (strinfo->src_port == port_src_fwd_) && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_fwd_))) && (strinfo->dest_port == port_dst_fwd_)) { ++num_streams; filtered_list = g_list_prepend(filtered_list, strinfo); } if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_rev_)) && (strinfo->src_port == port_src_rev_) && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_rev_))) && (strinfo->dest_port == port_dst_rev_)) { ++num_streams; filtered_list = g_list_append(filtered_list, strinfo); } }
static gboolean process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr, const guchar *pd) { frame_data fdata; gboolean create_proto_tree; epan_dissect_t edt; gboolean passed; union wtap_pseudo_header pseudo_header; int i; if(whdr->len == 0) { /* The user sends an empty packet when he wants to get output from us even if we don't currently have packets to process. We spit out a line with the timestamp and the text "void" */ printf("%lu %lu %lu void -\n", (unsigned long int)cf->count, (unsigned long int)whdr->ts.secs, (unsigned long int)whdr->ts.nsecs); fflush(stdout); return FALSE; } memset(&pseudo_header, 0, sizeof(pseudo_header)); /* Count this packet. */ cf->count++; /* If we're going to print packet information, or we're going to run a read filter, or we're going to process taps, set up to do a dissection and do so. */ fill_in_fdata(&fdata, cf, whdr, offset); passed = TRUE; create_proto_tree = TRUE; /* The protocol tree will be "visible", i.e., printed, only if we're printing packet details, which is true if we're in verbose mode ("verbose" is true). */ epan_dissect_init(&edt, create_proto_tree, FALSE); /* If we're running a read filter, prime the epan_dissect_t with that filter. */ if (n_rfilters > 0) { for(i = 0; i < n_rfcodes; i++) { epan_dissect_prime_dfilter(&edt, rfcodes[i]); } } tap_queue_init(&edt); printf("%lu", (unsigned long int)cf->count); /* We only need the columns if we're printing packet info but we're *not* verbose; in verbose mode, we print the protocol tree, not the protocol summary. */ epan_dissect_run(&edt, &pseudo_header, pd, &fdata, &cf->cinfo); tap_push_tapped_queue(&edt); for(i = 0; i < n_rfilters; i++) { /* Run the read filter if we have one. */ if (rfcodes[i]) passed = dfilter_apply_edt(rfcodes[i], &edt); else passed = TRUE; /* Print a one-line summary */ printf(" %u", passed ? 1 : 0); } printf(" -\n"); /* The ANSI C standard does not appear to *require* that a line-buffered stream be flushed to the host environment whenever a newline is written, it just says that, on such a stream, characters "are intended to be transmitted to or from the host environment as a block when a new-line character is encountered". The Visual C++ 6.0 C implementation doesn't do what is intended; even if you set a stream to be line-buffered, it still doesn't flush the buffer at the end of every line. So, if the "-l" flag was specified, we flush the standard output at the end of a packet. This will do the right thing if we're printing packet summary lines, and, as we print the entire protocol tree for a single packet without waiting for anything to happen, it should be as good as line-buffered mode if we're printing protocol trees. (The whole reason for the "-l" flag in either tcpdump or Rawshark is to allow the output of a live capture to be piped to a program or script and to have that script see the information for the packet as soon as it's printed, rather than having to wait until a standard I/O buffer fills up. */ if (line_buffered) fflush(stdout); if (ferror(stdout)) { show_print_file_io_error(errno); exit(2); } epan_dissect_cleanup(&edt); clear_fdata(&fdata); return passed; }