#include <ui/voip_calls.h>
#include <ui/rtp_stream.h>
#include <ui/tap-rtp-common.h>
+#include <ui/tap-rtp-analysis.h>
#include <epan/to_str.h>
#include <epan/addr_resolv.h>
tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
struct sharkd_analyse_rtp_items *item;
- rtp_packet_analyse(statinfo, pinfo, rtpinfo);
+ rtppacket_analyse(statinfo, pinfo, rtpinfo);
item = (struct sharkd_analyse_rtp_items *) g_malloc(sizeof(struct sharkd_analyse_rtp_items));
printf(",\"streams\":[");
for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
{
- rtp_stream_info_t *streaminfo = (rtp_stream_info_t *) listx->data;
+ rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
char *src_addr, *dst_addr;
char *payload;
}
else if (!strcmp(tok_tap, "rtp-streams"))
{
- tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet, sharkd_session_process_tap_rtp_cb);
+ tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb);
tap_data = &rtp_tapinfo;
tap_free = rtpstream_reset_cb;
summary.c
tap_export_pdu.c
tap-iax2-analysis.c
+ tap-rtp-analysis.c
tap-rtp-common.c
tap-sctp-analysis.c
tap-rlc-graph.c
rtp_streams_stat_draw(void *arg _U_)
{
GList *list;
- rtp_stream_info_t *strinfo;
+ rtpstream_info_t *strinfo;
gchar *payload_type;
guint32 expected;
gint32 lost;
list = g_list_first(list);
while (list)
{
- strinfo = (rtp_stream_info_t*)(list->data);
+ strinfo = (rtpstream_info_t*)(list->data);
/* payload type */
if (strinfo->payload_type > 95) {
err_p =
register_tap_listener("rtp", &the_tapinfo_struct, NULL, 0,
rtpstream_reset_cb,
- rtpstream_packet,
+ rtpstream_packet_cb,
rtp_streams_stat_draw);
if (err_p != NULL)
tapinfo.tap_data = this;
tapinfo.mode = TAP_ANALYSE;
-// register_tap_listener_rtp_stream(&tapinfo, NULL);
+// register_tap_listener_rtpstream(&tapinfo, NULL);
/* Scan for RTP streams (redissect all packets) */
rtpstream_scan(&tapinfo, cap_file_.capFile(), NULL);
Iax2AnalysisDialog::~Iax2AnalysisDialog()
{
delete ui;
-// remove_tap_listener_rtp_stream(&tapinfo);
+// remove_tap_listener_rtpstream(&tapinfo);
delete fwd_tempfile_;
delete rev_tempfile_;
}
num_graphs_
};
-RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd, struct _rtp_stream_info *stream_rev) :
+RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream_info_t *stream_fwd, rtpstream_info_t *stream_rev) :
WiresharkDialog(parent, cf),
ui(new Ui::RtpAnalysisDialog),
port_src_fwd_(0),
RtpAnalysisDialog::~RtpAnalysisDialog()
{
delete ui;
-// remove_tap_listener_rtp_stream(&tapinfo_);
+// remove_tap_listener_rtpstream(&tapinfo_);
delete fwd_tempfile_;
delete rev_tempfile_;
}
// add_rtp_packet(rtpinfo, pinfo);
if (forward) {
- rtp_packet_analyse(&fwd_statinfo_, pinfo, rtpinfo);
+ rtppacket_analyse(&fwd_statinfo_, pinfo, rtpinfo);
new RtpAnalysisTreeWidgetItem(ui->forwardTreeWidget, &fwd_statinfo_, pinfo, rtpinfo);
fwd_time_vals_.append(fwd_statinfo_.time / 1000);
savePayload(fwd_tempfile_, &fwd_statinfo_, pinfo, rtpinfo);
} else {
- rtp_packet_analyse(&rev_statinfo_, pinfo, rtpinfo);
+ rtppacket_analyse(&rev_statinfo_, pinfo, rtpinfo);
new RtpAnalysisTreeWidgetItem(ui->reverseTreeWidget, &rev_statinfo_, pinfo, rtpinfo);
rev_time_vals_.append(rev_statinfo_.time / 1000);
if (nchars != sizeof(save_data)) {
/* Write error or short write */
err_str_ = tr("Can't save in a file: File I/O problem.");
- save_payload_error_ = TAP_RTP_FILE_IO_ERROR;
+ save_payload_error_ = TAP_RTP_FILE_WRITE_ERROR;
tmpfile->close();
return;
}
if (nchars != save_data.payload_len) {
/* Write error or short write */
err_str_ = tr("Can't save in a file: File I/O problem.");
- save_payload_error_ = TAP_RTP_FILE_IO_ERROR;
+ save_payload_error_ = TAP_RTP_FILE_WRITE_ERROR;
tmpfile->close();
return;
}
if (num_streams_ < 1) return;
RtpPlayerDialog rtp_player_dialog(*this, cap_file_);
- rtp_stream_info_t stream_info;
+ rtpstream_info_t stream_info;
// XXX We might want to create an "rtp_stream_id_t" struct with only
// addresses, ports & SSRC.
tapinfo_.tap_data = this;
tapinfo_.mode = TAP_ANALYSE;
-// register_tap_listener_rtp_stream(&tapinfo_, NULL);
+// register_tap_listener_rtpstream(&tapinfo_, NULL);
/* Scan for RTP streams (redissect all packets) */
rtpstream_scan(&tapinfo_, cap_file_.capFile(), 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);
+ rtpstream_info_t * strinfo = (rtpstream_info_t*)(strinfo_list->data);
if (addresses_equal(&(strinfo->src_addr), &(src_fwd_))
&& (strinfo->src_port == port_src_fwd_)
&& (addresses_equal(&(strinfo->dest_addr), &(dst_fwd_)))
#include "epan/address.h"
#include "ui/rtp_stream.h"
+#include "ui/tap-rtp-common.h"
#include "ui/tap-rtp-analysis.h"
#include <QAbstractButton>
class QCPGraph;
class QTemporaryFile;
-typedef enum {
- TAP_RTP_NO_ERROR,
- TAP_RTP_WRONG_LENGTH,
- TAP_RTP_PADDING_ERROR,
- TAP_RTP_FILE_IO_ERROR
-} rtp_error_type_t;
-
class RtpAnalysisDialog : public WiresharkDialog
{
Q_OBJECT
public:
- explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd = 0, struct _rtp_stream_info *stream_rev = 0);
+ explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream_info_t *stream_fwd = 0, rtpstream_info_t *stream_rev = 0);
~RtpAnalysisDialog();
signals:
rtpstream_tapinfo_t tapinfo_;
QString err_str_;
- rtp_error_type_t save_payload_error_;
+ tap_rtp_error_type_t save_payload_error_;
QMenu stream_ctx_menu_;
QMenu graph_ctx_menu_;
static spx_int16_t default_audio_sample_rate_ = 8000;
static const spx_int16_t visual_sample_rate_ = 1000;
-RtpAudioStream::RtpAudioStream(QObject *parent, _rtp_stream_info *rtp_stream) :
+RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtp_stream) :
QObject(parent),
decoders_hash_(rtp_decoder_hash_table_new()),
global_start_rel_time_(0.0),
speex_resampler_destroy (visual_resampler_);
}
-bool RtpAudioStream::isMatch(const _rtp_stream_info *rtp_stream) const
+bool RtpAudioStream::isMatch(const rtpstream_info_t *rtp_stream) const
{
if (rtp_stream
&& addresses_equal(&rtp_stream->src_addr, &src_addr_)
// XXX We add multiple RTP streams here because that's what the GTK+ UI does.
// Should we make these distinct, with their own waveforms? It seems like
// that would simplify a lot of things.
-void RtpAudioStream::addRtpStream(const _rtp_stream_info *rtp_stream)
+void RtpAudioStream::addRtpStream(const rtpstream_info_t *rtp_stream)
{
if (!rtp_stream) return;
silence_timestamps_.append(stop_rel_time_);
decoded_bytes_prev = 0;
-/* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
+/* defined start_timestamp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
/* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */
start_timestamp = rtp_packet->info->info_timestamp;
start_rtp_time = 0;
#include <glib.h>
#include <epan/address.h>
+#include <ui/rtp_stream.h>
#include <QAudio>
#include <QColor>
class QTemporaryFile;
struct _rtp_info;
-struct _rtp_stream_info;
struct _rtp_sample;
class RtpAudioStream : public QObject
public:
enum TimingMode { JitterBuffer, RtpTimestamp, Uninterrupted };
- explicit RtpAudioStream(QObject *parent, struct _rtp_stream_info *rtp_stream);
+ explicit RtpAudioStream(QObject *parent, rtpstream_info_t *rtp_stream);
~RtpAudioStream();
- bool isMatch(const struct _rtp_stream_info *rtp_stream) const;
+ bool isMatch(const rtpstream_info_t *rtp_stream) const;
bool isMatch(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info) const;
- void addRtpStream(const struct _rtp_stream_info *rtp_stream);
+ void addRtpStream(const rtpstream_info_t *rtp_stream);
void addRtpPacket(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info);
void reset(double start_rel_time);
void decode();
QVector<struct _rtp_packet *>rtp_packets_;
QTemporaryFile *tempfile_;
struct _GHashTable *decoders_hash_;
- QList<const struct _rtp_stream_info *>rtp_streams_;
+ QList<const rtpstream_info_t *>rtp_streams_;
double global_start_rel_time_;
double start_abs_offset_;
double start_rel_time_;
updateWidgets();
}
-void RtpPlayerDialog::addRtpStream(struct _rtp_stream_info *rtp_stream)
+void RtpPlayerDialog::addRtpStream(rtpstream_info_t *rtp_stream)
{
if (!rtp_stream) return;
#if 0
// This also serves as a title in RtpAudioFrame.
static const QString stream_key_tmpl_ = "%1:%2 " UTF8_RIGHTWARDS_ARROW " %3:%4 0x%5";
-const QString RtpPlayerDialog::streamKey(const struct _rtp_stream_info *rtp_stream)
+const QString RtpPlayerDialog::streamKey(const rtpstream_info_t *rtp_stream)
{
const QString stream_key = QString(stream_key_tmpl_)
.arg(address_to_display_qstring(&rtp_stream->src_addr))
class RtpPlayerDialog;
}
-struct _rtp_stream_info;
-
class QCPItemStraightLine;
class QDialogButtonBox;
class QMenu;
*
* @param rtp_stream struct with rtp_stream info
*/
- void addRtpStream(struct _rtp_stream_info *rtp_stream);
+ void addRtpStream(rtpstream_info_t *rtp_stream);
public slots:
QCPItemStraightLine *cur_play_pos_;
QString playback_error_;
-// const QString streamKey(const struct _rtp_stream_info *rtp_stream);
+// const QString streamKey(const rtp_stream_info_t *rtp_stream);
// const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo);
// Tap callbacks
class RtpStreamTreeWidgetItem : public QTreeWidgetItem
{
public:
- RtpStreamTreeWidgetItem(QTreeWidget *tree, rtp_stream_info_t *stream_info) :
+ RtpStreamTreeWidgetItem(QTreeWidget *tree, rtpstream_info_t *stream_info) :
QTreeWidgetItem(tree, rtp_stream_type_),
stream_info_(stream_info)
{
drawData();
}
- rtp_stream_info_t *streamInfo() const { return stream_info_; }
+ rtpstream_info_t *streamInfo() const { return stream_info_; }
void drawData() {
if (!stream_info_) {
}
private:
- rtp_stream_info_t *stream_info_;
+ rtpstream_info_t *stream_info_;
guint32 lost_;
};
tapinfo_.tap_data = this;
tapinfo_.mode = TAP_ANALYSE;
- register_tap_listener_rtp_stream(&tapinfo_, NULL);
+ register_tap_listener_rtpstream(&tapinfo_, NULL);
/* Scan for RTP streams (redissect all packets) */
rtpstream_scan(&tapinfo_, cf.capFile(), NULL);
RtpStreamDialog::~RtpStreamDialog()
{
delete ui;
- remove_tap_listener_rtp_stream(&tapinfo_);
+ remove_tap_listener_rtpstream(&tapinfo_);
}
bool RtpStreamDialog::eventFilter(QObject *, QEvent *event)
// Add any missing items
while (cur_stream && cur_stream->data) {
- rtp_stream_info_t *stream_info = (rtp_stream_info_t*) cur_stream->data;
+ rtpstream_info_t *stream_info = (rtpstream_info_t*) cur_stream->data;
new RtpStreamTreeWidgetItem(ui->streamTreeWidget, stream_info);
cur_stream = g_list_next(cur_stream);
}
void RtpStreamDialog::captureFileClosing()
{
- remove_tap_listener_rtp_stream(&tapinfo_);
+ remove_tap_listener_rtpstream(&tapinfo_);
WiresharkDialog::captureFileClosing();
}
void RtpStreamDialog::on_actionAnalyze_triggered()
{
- rtp_stream_info_t *stream_a, *stream_b = NULL;
+ rtpstream_info_t *stream_a, *stream_b = NULL;
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
// XXX If the user selected multiple frames is this the one we actually want?
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
- rtp_stream_info_t *stream_info = rsti->streamInfo();
+ rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
QString file_name;
QDir path(wsApp->lastOpenDir());
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
// Gather up our selected streams...
- QList<rtp_stream_info_t *> selected_streams;
+ QList<rtpstream_info_t *> selected_streams;
foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) {
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
- rtp_stream_info_t *stream_info = rsti->streamInfo();
+ rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
selected_streams << stream_info;
}
QTreeWidgetItemIterator iter(ui->streamTreeWidget, QTreeWidgetItemIterator::Unselected);
while (*iter) {
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(*iter);
- rtp_stream_info_t *stream_info = rsti->streamInfo();
+ rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
- foreach (rtp_stream_info_t *fwd_stream, selected_streams) {
- if (rtp_stream_info_is_reverse(fwd_stream, stream_info)) {
+ foreach (rtpstream_info_t *fwd_stream, selected_streams) {
+ if (rtpstream_info_is_reverse(fwd_stream, stream_info)) {
(*iter)->setSelected(true);
}
}
// XXX If the user selected multiple frames is this the one we actually want?
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
- rtp_stream_info_t *stream_info = rsti->streamInfo();
+ rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
emit goToPacket(stream_info->setup_frame_number);
}
void RtpStreamDialog::on_actionMarkPackets_triggered()
{
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
- rtp_stream_info_t *stream_a, *stream_b = NULL;
+ rtpstream_info_t *stream_a, *stream_b = NULL;
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
QStringList stream_filters;
foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) {
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
- rtp_stream_info_t *stream_info = rsti->streamInfo();
+ rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
QString ip_proto = stream_info->src_addr.type == AT_IPv6 ? "ipv6" : "ip";
stream_filters << QString("(%1.src==%2 && udp.srcport==%3 && %1.dst==%4 && udp.dstport==%5 && rtp.ssrc==0x%6)")
}
if (stream_filters.length() > 0) {
QString filter = stream_filters.join(" || ");
- remove_tap_listener_rtp_stream(&tapinfo_);
+ remove_tap_listener_rtpstream(&tapinfo_);
emit updateFilter(filter);
}
}
for (; graph_item; graph_item = g_list_next(graph_item)) {
for (GList *rsi_entry = g_list_first(tapinfo->rtp_stream_list); rsi_entry; rsi_entry = g_list_next(rsi_entry)) {
seq_analysis_item_t * sai = (seq_analysis_item_t *)graph_item->data;
- rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_entry->data;
+ rtpstream_info_t *rsi = (rtpstream_info_t *)rsi_entry->data;
if (rsi->start_fd->num == sai->frame_number) {
rsi->call_num = sai->conv_num;
if (!vci) continue;
for (GList *rsi_entry = g_list_first(tapinfo_.rtp_stream_list); rsi_entry; rsi_entry = g_list_next(rsi_entry)) {
- rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_entry->data;
+ rtpstream_info_t *rsi = (rtpstream_info_t *)rsi_entry->data;
if (!rsi) continue;
//VOIP_CALLS_DEBUG("checking call %u, start frame %u == stream call %u, start frame %u, setup frame %u",
g_hash_table_insert(decoders_hash, GUINT_TO_POINTER(payload_type), decoder);
}
if (decoder->handle) { /* Decode with registered codec */
+ /* if output == NULL and outputSizeBytes == NULL => ask for expected size of the buffer */
tmp_buff_len = codec_decode(decoder->handle, decoder->context, rp->payload_data, rp->info->info_payload_len, NULL, NULL);
tmp_buff = (SAMPLE *)g_malloc(tmp_buff_len);
decoded_bytes = codec_decode(decoder->handle, decoder->context, rp->payload_data, rp->info->info_payload_len, tmp_buff, &tmp_buff_len);
/****************************************************************************/
/* redraw the output */
-static void rtpstream_draw(void *ti_ptr)
+static void rtpstream_draw_cb(void *ti_ptr)
{
rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)ti_ptr;
/* XXX: see rtpstream_on_update in rtp_streams_dlg.c for comments
was_registered = tapinfo->is_registered;
if (!tapinfo->is_registered)
- register_tap_listener_rtp_stream(tapinfo, fstring);
+ register_tap_listener_rtpstream(tapinfo, fstring);
/* RTP_STREAM_DEBUG("scanning %s, filter: %s", cap_file->filename, fstring); */
tapinfo->mode = TAP_ANALYSE;
cf_retap_packets(cap_file);
if (!was_registered)
- remove_tap_listener_rtp_stream(tapinfo);
+ remove_tap_listener_rtpstream(tapinfo);
}
/****************************************************************************/
/* save rtp dump of stream_fwd */
-gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream, const gchar *filename)
+gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream, const gchar *filename)
{
gboolean was_registered;
}
if (!tapinfo->is_registered)
- register_tap_listener_rtp_stream(tapinfo, NULL);
+ register_tap_listener_rtpstream(tapinfo, NULL);
tapinfo->mode = TAP_SAVE;
tapinfo->filter_stream_fwd = stream;
tapinfo->mode = TAP_ANALYSE;
if (!was_registered)
- remove_tap_listener_rtp_stream(tapinfo);
+ remove_tap_listener_rtpstream(tapinfo);
if (ferror(tapinfo->save_file)) {
write_failure_alert_box(filename, errno);
/****************************************************************************/
/* compare the endpoints of two RTP streams */
-gboolean rtp_stream_info_is_reverse(const rtp_stream_info_t *stream_a, rtp_stream_info_t *stream_b)
+gboolean rtpstream_info_is_reverse(const rtpstream_info_t *stream_a, rtpstream_info_t *stream_b)
{
if (stream_a == NULL || stream_b == NULL)
return FALSE;
/****************************************************************************/
/* mark packets in stream_fwd or stream_rev */
-void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream_fwd, rtp_stream_info_t* stream_rev)
+void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev)
{
gboolean was_registered;
was_registered = tapinfo->is_registered;
if (!tapinfo->is_registered)
- register_tap_listener_rtp_stream(tapinfo, NULL);
+ register_tap_listener_rtpstream(tapinfo, NULL);
tapinfo->mode = TAP_MARK;
tapinfo->filter_stream_fwd = stream_fwd;
tapinfo->mode = TAP_ANALYSE;
if (!was_registered)
- remove_tap_listener_rtp_stream(tapinfo);
+ remove_tap_listener_rtpstream(tapinfo);
}
/****************************************************************************/
void
-remove_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo)
+remove_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo)
{
if (tapinfo && tapinfo->is_registered) {
remove_tap_listener(tapinfo);
/****************************************************************************/
void
-register_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo, const char *fstring)
+register_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo, const char *fstring)
{
GString *error_string;
if (!tapinfo->is_registered) {
error_string = register_tap_listener("rtp", tapinfo,
- fstring, 0, rtpstream_reset_cb, rtpstream_packet,
- rtpstream_draw);
+ fstring, 0, rtpstream_reset_cb, rtpstream_packet_cb,
+ rtpstream_draw_cb);
if (error_string != NULL) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
#include <epan/tap.h>
/** Defines an rtp stream */
-typedef struct _rtp_stream_info {
+typedef struct _rtpstream_info {
address src_addr;
guint32 src_port;
address dest_addr;
tap_rtp_stat_t rtp_stats; /**< here goes the RTP statistics info */
gboolean problem; /**< if the streams had wrong sequence numbers or wrong timestamps */
gchar *ed137_info;
-} rtp_stream_info_t;
+} rtpstream_info_t;
/** tapping modes */
typedef enum
int npackets; /**< total number of rtp packets of all streams */
/* used while tapping. user shouldn't modify these */
tap_mode_t mode;
- rtp_stream_info_t *filter_stream_fwd; /**< used as filter in some tap modes */
- rtp_stream_info_t *filter_stream_rev; /**< used as filter in some tap modes */
+ rtpstream_info_t *filter_stream_fwd; /**< used as filter in some tap modes */
+ rtpstream_info_t *filter_stream_rev; /**< used as filter in some tap modes */
FILE *save_file;
gboolean is_registered; /**< if the tap listener is currently registered or not */
};
* So whenever rtp_stream.c is added to the list of WIRESHARK_TAP_SRCs, the tap will be registered on startup.
* If not, it will be registered on demand by the rtp_streams and rtp_analysis functions that need it.
*/
-void register_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo, const char *fstring);
+void register_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo, const char *fstring);
/**
* Removes the rtp_streams tap listener (if not already done)
* From that point on, the RTP streams list won't be updated any more.
*/
-void remove_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo);
+void remove_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo);
/**
* Cleans up memory of rtp streams tap.
* Saves an RTP stream as raw data stream with timestamp information for later RTP playback.
* (redissects all packets)
*/
-gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream, const gchar *filename);
+gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream, const gchar *filename);
/**
* Compares the endpoints of two RTP streams.
*
* @return TRUE if the
*/
-gboolean rtp_stream_info_is_reverse(const rtp_stream_info_t *stream_a, rtp_stream_info_t *stream_b);
+gboolean rtpstream_info_is_reverse(const rtpstream_info_t *stream_a, rtpstream_info_t *stream_b);
/**
* Marks all packets belonging to either of stream_fwd or stream_rev.
* (both can be NULL)
* (redissects all packets)
*/
-void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream_fwd, rtp_stream_info_t* stream_rev);
+void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev);
#define MAX_SILENCE_FRAMES 14400000
#define BUFF_BW 300
typedef struct _tap_iax2_stat_t {
- gboolean first_packet; /* do not use in code that is called after rtp_packet_analyse */
+ gboolean first_packet; /* do not use in code that is called after iax2_packet_analyse */
/* use (flags & STAT_FLAG_FIRST) instead */
/* all of the following fields will be initialized after
- rtp_packet_analyse has been called */
+ iax2_packet_analyse has been called */
guint32 flags; /* see STAT_FLAG-defines below */
guint16 seq_num;
guint32 timestamp;
--- /dev/null
+/* tap-rtp-analysis.c
+ * RTP stream handler functions used by tshark and wireshark
+ *
+ * Copyright 2008, Ericsson AB
+ * By Balint Reczey <balint.reczey@ericsson.com>
+ *
+ * most functions are copied from ui/gtk/rtp_stream.c and ui/gtk/rtp_analysis.c
+ * Copyright 2003, Alcatel Business Systems
+ * By Lars Ruoff <lars.ruoff@gmx.net>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <math.h>
+#include "globals.h"
+
+#include <string.h>
+#include <epan/rtp_pt.h>
+#include <epan/addr_resolv.h>
+#include <epan/proto_data.h>
+#include <epan/dissectors/packet-rtp.h>
+#include <wsutil/pint.h>
+#include "rtp_stream.h"
+#include "tap-rtp-common.h"
+#include "tap-rtp-analysis.h"
+
+typedef struct _key_value {
+ guint32 key;
+ guint32 value;
+} key_value;
+
+
+/* RTP sampling clock rates for fixed payload types as defined in
+ http://www.iana.org/assignments/rtp-parameters */
+static const key_value clock_map[] = {
+ {PT_PCMU, 8000},
+ {PT_1016, 8000},
+ {PT_G721, 8000},
+ {PT_GSM, 8000},
+ {PT_G723, 8000},
+ {PT_DVI4_8000, 8000},
+ {PT_DVI4_16000, 16000},
+ {PT_LPC, 8000},
+ {PT_PCMA, 8000},
+ {PT_G722, 8000},
+ {PT_L16_STEREO, 44100},
+ {PT_L16_MONO, 44100},
+ {PT_QCELP, 8000},
+ {PT_CN, 8000},
+ {PT_MPA, 90000},
+ {PT_G728, 8000},
+ {PT_G728, 8000},
+ {PT_DVI4_11025, 11025},
+ {PT_DVI4_22050, 22050},
+ {PT_G729, 8000},
+ {PT_CN_OLD, 8000},
+ {PT_CELB, 90000},
+ {PT_JPEG, 90000},
+ {PT_NV, 90000},
+ {PT_H261, 90000},
+ {PT_MPV, 90000},
+ {PT_MP2T, 90000},
+ {PT_H263, 90000},
+};
+
+#define NUM_CLOCK_VALUES (sizeof clock_map / sizeof clock_map[0])
+
+static guint32
+get_clock_rate(guint32 key)
+{
+ size_t i;
+
+ for (i = 0; i < NUM_CLOCK_VALUES; i++) {
+ if (clock_map[i].key == key)
+ return clock_map[i].value;
+ }
+ return 0;
+}
+
+typedef struct _mimetype_and_clock {
+ const gchar *pt_mime_name_str;
+ guint32 value;
+} mimetype_and_clock;
+/* RTP sampling clock rates for
+ "In addition to the RTP payload formats (encodings) listed in the RTP
+ Payload Types table, there are additional payload formats that do not
+ have static RTP payload types assigned but instead use dynamic payload
+ type number assignment. Each payload format is named by a registered
+ MIME subtype"
+ http://www.iana.org/assignments/rtp-parameters.
+
+ NOTE: Please keep the mimetypes in case insensitive alphabetical order.
+*/
+static const mimetype_and_clock mimetype_and_clock_map[] = {
+ {"AMR", 8000}, /* [RFC4867][RFC3267] */
+ {"AMR-WB", 16000}, /* [RFC4867][RFC3267] */
+ {"BMPEG", 90000}, /* [RFC2343],[RFC3555] */
+ {"BT656", 90000}, /* [RFC2431],[RFC3555] */
+ {"DV", 90000}, /* [RFC3189] */
+ {"EVRC", 8000}, /* [RFC3558] */
+ {"EVRC0", 8000}, /* [RFC4788] */
+ {"EVRC1", 8000}, /* [RFC4788] */
+ {"EVRCB", 8000}, /* [RFC4788] */
+ {"EVRCB0", 8000}, /* [RFC4788] */
+ {"EVRCB1", 8000}, /* [RFC4788] */
+ {"EVRCWB", 16000}, /* [RFC5188] */
+ {"EVRCWB0", 16000}, /* [RFC5188] */
+ {"EVRCWB1", 16000}, /* [RFC5188] */
+ {"EVS", 16000}, /* [3GPP TS 26.445] */
+ {"G7221", 16000}, /* [RFC3047] */
+ {"G726-16", 8000}, /* [RFC3551][RFC4856] */
+ {"G726-24", 8000}, /* [RFC3551][RFC4856] */
+ {"G726-32", 8000}, /* [RFC3551][RFC4856] */
+ {"G726-40", 8000}, /* [RFC3551][RFC4856] */
+ {"G729D", 8000}, /* [RFC3551][RFC4856] */
+ {"G729E", 8000}, /* [RFC3551][RFC4856] */
+ {"GSM-EFR", 8000}, /* [RFC3551] */
+ {"H263-1998", 90000}, /* [RFC2429],[RFC3555] */
+ {"H263-2000", 90000}, /* [RFC2429],[RFC3555] */
+ {"H264", 90000}, /* [RFC3984] */
+ {"MP1S", 90000}, /* [RFC2250],[RFC3555] */
+ {"MP2P", 90000}, /* [RFC2250],[RFC3555] */
+ {"MP4V-ES", 90000}, /* [RFC3016] */
+ {"mpa-robust", 90000}, /* [RFC3119] */
+ {"pointer", 90000}, /* [RFC2862] */
+ {"raw", 90000}, /* [RFC4175] */
+ {"red", 1000}, /* [RFC4102] */
+ {"SMV", 8000}, /* [RFC3558] */
+ {"SMV0", 8000}, /* [RFC3558] */
+ {"t140", 1000}, /* [RFC4103] */
+ {"telephone-event", 8000}, /* [RFC4733] */
+};
+
+#define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
+
+static guint32
+get_dyn_pt_clock_rate(const gchar *payload_type_str)
+{
+ int i;
+
+ /* Search for matching mimetype in reverse order to avoid false matches
+ * when pt_mime_name_str is the prefix of payload_type_str */
+ for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
+ if (g_ascii_strncasecmp(mimetype_and_clock_map[i].pt_mime_name_str,payload_type_str,(strlen(mimetype_and_clock_map[i].pt_mime_name_str))) == 0)
+ return mimetype_and_clock_map[i].value;
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+void
+rtppacket_analyse(tap_rtp_stat_t *statinfo,
+ packet_info *pinfo,
+ const struct _rtp_info *rtpinfo)
+{
+ double current_time;
+ double current_jitter;
+ double current_diff = 0;
+ double nominaltime;
+ double arrivaltime; /* Time relative to start_time */
+ double expected_time;
+ double absskew;
+ guint32 clock_rate;
+
+ /* Store the current time */
+ current_time = nstime_to_msec(&pinfo->rel_ts);
+
+ /* Is this the first packet we got in this direction? */
+ if (statinfo->first_packet) {
+ /* Save the MAC address of the first RTP frame */
+ if( pinfo->dl_src.type == AT_ETHER){
+ copy_address(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
+ }
+ statinfo->start_seq_nr = rtpinfo->info_seq_num;
+ statinfo->stop_seq_nr = rtpinfo->info_seq_num;
+ statinfo->seq_num = rtpinfo->info_seq_num;
+ statinfo->start_time = current_time;
+ statinfo->timestamp = rtpinfo->info_timestamp;
+ statinfo->first_timestamp = rtpinfo->info_timestamp;
+ statinfo->time = current_time;
+ statinfo->lastnominaltime = 0;
+ statinfo->pt = rtpinfo->info_payload_type;
+ statinfo->reg_pt = rtpinfo->info_payload_type;
+ if (pinfo->net_src.type == AT_IPv6) {
+ statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
+ } else {
+ statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
+ }
+ statinfo->bw_history[statinfo->bw_index].time = current_time;
+ statinfo->bw_index++;
+ if (pinfo->net_src.type == AT_IPv6) {
+ statinfo->total_bytes += rtpinfo->info_data_len + 48;
+ } else {
+ statinfo->total_bytes += rtpinfo->info_data_len + 28;
+ }
+ statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
+ /* Not needed ? initialised to zero? */
+ statinfo->delta = 0;
+ statinfo->jitter = 0;
+ statinfo->diff = 0;
+
+ statinfo->total_nr++;
+ statinfo->flags |= STAT_FLAG_FIRST;
+ if (rtpinfo->info_marker_set) {
+ statinfo->flags |= STAT_FLAG_MARKER;
+ }
+ statinfo->first_packet_num = pinfo->num;
+ statinfo->first_packet = FALSE;
+ return;
+ }
+
+ /* Reset flags */
+ statinfo->flags = 0;
+#if 0
+ /*According to bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11478
+ * this code causes problems. A better solution is needed if there is need for the functionality */
+ /* Try to detect duplicated packets due to mirroring/span ports by comparing src MAC addresses.
+ * Check for duplicates (src mac differs from first_packet_mac_addr) */
+ */
+ if( pinfo->dl_src.type == AT_ETHER){
+ if(!addresses_equal(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
+ statinfo->flags |= STAT_FLAG_DUP_PKT;
+ statinfo->delta = current_time-(statinfo->time);
+ return;
+ }
+ }
+#endif
+ /* When calculating expected rtp packets the seq number can wrap around
+ * so we have to count the number of cycles
+ * Variable cycles counts the wraps around in forwarding connection and
+ * under is flag that indicates where we are
+ *
+ * XXX How to determine number of cycles with all possible lost, late
+ * and duplicated packets without any doubt? It seems to me, that
+ * because of all possible combination of late, duplicated or lost
+ * packets, this can only be more or less good approximation
+ *
+ * There are some combinations (rare but theoretically possible),
+ * where below code won't work correctly - statistic may be wrong then.
+ */
+
+ /* So if the current sequence number is less than the start one
+ * we assume, that there is another cycle running
+ */
+ if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
+ statinfo->cycles++;
+ statinfo->under = TRUE;
+ }
+ /* what if the start seq nr was 0? Then the above condition will never
+ * be true, so we add another condition. XXX The problem would arise
+ * if one of the packets with seq nr 0 or 65535 would be lost or late
+ */
+ else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
+ (statinfo->under == FALSE)) {
+ statinfo->cycles++;
+ statinfo->under = TRUE;
+ }
+ /* the whole round is over, so reset the flag */
+ else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
+ statinfo->under = FALSE;
+ }
+
+ /* Since it is difficult to count lost, duplicate or late packets separately,
+ * we would like to know at least how many times the sequence number was not ok
+ */
+
+ /* If the current seq number equals the last one or if we are here for
+ * the first time, then it is ok, we just store the current one as the last one
+ */
+ if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
+ statinfo->seq_num = rtpinfo->info_seq_num;
+ /* If the first one is 65535 we wrap */
+ else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
+ statinfo->seq_num = rtpinfo->info_seq_num;
+ /* Lost packets. If the prev seq is enormously larger than the cur seq
+ * we assume that instead of being massively late we lost the packet(s)
+ * that would have indicated the sequence number wrapping. An imprecise
+ * heuristic at best, but it seems to work well enough.
+ * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
+ else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
+ statinfo->seq_num = rtpinfo->info_seq_num;
+ statinfo->sequence++;
+ statinfo->flags |= STAT_FLAG_WRONG_SEQ;
+ }
+ /* Late or duplicated */
+ else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
+ statinfo->sequence++;
+ statinfo->flags |= STAT_FLAG_WRONG_SEQ;
+ }
+
+ /* Check payload type */
+ if (rtpinfo->info_payload_type == PT_CN
+ || rtpinfo->info_payload_type == PT_CN_OLD)
+ statinfo->flags |= STAT_FLAG_PT_CN;
+ if (statinfo->pt == PT_CN
+ || statinfo->pt == PT_CN_OLD)
+ statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
+ if (rtpinfo->info_payload_type != statinfo->pt)
+ statinfo->flags |= STAT_FLAG_PT_CHANGE;
+ statinfo->pt = rtpinfo->info_payload_type;
+
+ /*
+ * Return for unknown payload types
+ * Ignore jitter calculation for clockrate = 0
+ */
+ if (statinfo->pt < 96 ){
+ clock_rate = get_clock_rate(statinfo->pt);
+ } else { /* Dynamic PT */
+ if ( rtpinfo->info_payload_type_str != NULL ) {
+ /* Is it a "telephone-event" ?
+ * Timestamp is not increased for telepone-event packets impacting
+ * calculation of Jitter Skew and clock drift.
+ * see 2.2.1 of RFC 4733
+ */
+ if (g_ascii_strncasecmp("telephone-event",rtpinfo->info_payload_type_str,(strlen("telephone-event")))==0) {
+ clock_rate = 0;
+ statinfo->flags |= STAT_FLAG_PT_T_EVENT;
+ } else {
+ if(rtpinfo->info_payload_rate !=0) {
+ clock_rate = rtpinfo->info_payload_rate;
+ } else {
+ clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str);
+ }
+ }
+ } else {
+ clock_rate = 0;
+ }
+ }
+
+ /* Handle wraparound ? */
+ arrivaltime = current_time - statinfo->start_time;
+
+ nominaltime = (double)(guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->first_timestamp));
+
+ /* Can only analyze defined sampling rates */
+ if (clock_rate != 0) {
+ statinfo->clock_rate = clock_rate;
+ /* Convert from sampling clock to ms */
+ nominaltime = nominaltime /(clock_rate/1000);
+
+ /* Calculate the current jitter(in ms) */
+ if (!statinfo->first_packet) {
+ expected_time = statinfo->time + (nominaltime - statinfo->lastnominaltime);
+ current_diff = fabs(current_time - expected_time);
+ current_jitter = (15 * statinfo->jitter + current_diff) / 16;
+
+ statinfo->delta = current_time-(statinfo->time);
+ statinfo->jitter = current_jitter;
+ statinfo->diff = current_diff;
+ }
+ statinfo->lastnominaltime = nominaltime;
+ /* Calculate skew, i.e. absolute jitter that also catches clock drift
+ * Skew is positive if TS (nominal) is too fast
+ */
+ statinfo->skew = nominaltime - arrivaltime;
+ absskew = fabs(statinfo->skew);
+ if(absskew > fabs(statinfo->max_skew)) {
+ statinfo->max_skew = statinfo->skew;
+ }
+ /* Gather data for calculation of average, minimum and maximum framerate based on timestamp */
+#if 0
+ if (numPackets > 0 && (!hardPayloadType || !alternatePayloadType)) {
+ /* Skip first packet and possibly alternate payload type packets */
+ double dt;
+ dt = nominaltime - statinfo->lastnominaltime;
+ sumdt += 1.0 * dt;
+ numdt += (dt != 0 ? 1 : 0);
+ mindt = (dt < mindt ? dt : mindt);
+ maxdt = (dt > maxdt ? dt : maxdt);
+ }
+#endif
+ /* Gather data for calculation of skew least square */
+ statinfo->sumt += 1.0 * current_time;
+ statinfo->sumTS += 1.0 * nominaltime;
+ statinfo->sumt2 += 1.0 * current_time * current_time;
+ statinfo->sumtTS += 1.0 * current_time * nominaltime;
+ }
+
+ /* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP) + 8bytes(UDP) */
+ if (pinfo->net_src.type == AT_IPv6) {
+ statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
+ } else {
+ statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
+ }
+ statinfo->bw_history[statinfo->bw_index].time = current_time;
+
+ /* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
+ while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
+ statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
+ statinfo->bw_start_index++;
+ if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
+ };
+ /* IP hdr + UDP + RTP */
+ if (pinfo->net_src.type == AT_IPv6){
+ statinfo->total_bytes += rtpinfo->info_data_len + 48;
+ }else{
+ statinfo->total_bytes += rtpinfo->info_data_len + 28;
+ }
+ statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
+ statinfo->bw_index++;
+ if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
+
+
+ /* Used by GTK code only */
+ statinfo->delta_timestamp = guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->timestamp);
+
+ /* Is it a packet with the mark bit set? */
+ if (rtpinfo->info_marker_set) {
+ statinfo->flags |= STAT_FLAG_MARKER;
+ }
+
+ /* Difference can be negative. We don't expect difference bigger than 31 bits. Difference don't care about wrap around. */
+ gint32 tsdelta=rtpinfo->info_timestamp - statinfo->timestamp;
+ if (tsdelta < 0) {
+ statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
+ }
+ /* Is it a regular packet? */
+ if (!(statinfo->flags & STAT_FLAG_FIRST)
+ && !(statinfo->flags & STAT_FLAG_MARKER)
+ && !(statinfo->flags & STAT_FLAG_PT_CN)
+ && !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
+ && !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
+ /* Include it in maximum delta calculation */
+ if (statinfo->delta > statinfo->max_delta) {
+ statinfo->max_delta = statinfo->delta;
+ statinfo->max_nr = pinfo->num;
+ }
+ if (clock_rate != 0) {
+ /* Maximum and mean jitter calculation */
+ if (statinfo->jitter > statinfo->max_jitter) {
+ statinfo->max_jitter = statinfo->jitter;
+ }
+ statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
+ }
+ }
+ /* Regular payload change? (CN ignored) */
+ if (!(statinfo->flags & STAT_FLAG_FIRST)
+ && !(statinfo->flags & STAT_FLAG_PT_CN)) {
+ if ((statinfo->pt != statinfo->reg_pt)
+ && (statinfo->reg_pt != PT_UNDEFINED)) {
+ statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
+ }
+ }
+
+ /* Set regular payload*/
+ if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
+ statinfo->reg_pt = statinfo->pt;
+ }
+
+ statinfo->time = current_time;
+ statinfo->timestamp = rtpinfo->info_timestamp;
+ statinfo->stop_seq_nr = rtpinfo->info_seq_num;
+ statinfo->total_nr++;
+ statinfo->last_payload_len = rtpinfo->info_payload_len - rtpinfo->info_padding_count;
+
+ return;
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
#define BUFF_BW 300
typedef struct _tap_rtp_stat_t {
- gboolean first_packet; /**< do not use in code that is called after rtp_packet_analyse */
+ gboolean first_packet; /**< do not use in code that is called after rtppacket_analyse */
/* use (flags & STAT_FLAG_FIRST) instead */
/* all of the following fields will be initialized after
- * rtp_packet_analyse has been called
+ * rtppacket_analyse has been called
*/
address first_packet_mac_addr; /**< MAC address of first packet, used to determine duplicates due to mirroring */
guint32 flags; /* see STAT_FLAG-defines below */
struct _rtp_info;
/* function for analysing an RTP packet. Called from rtp_analysis and rtp_streams */
-extern void rtp_packet_analyse(tap_rtp_stat_t *statinfo,
+extern void rtppacket_analyse(tap_rtp_stat_t *statinfo,
packet_info *pinfo,
const struct _rtp_info *rtpinfo);
} rtpdump_info_t;
/****************************************************************************/
-/* GCompareFunc style comparison function for _rtp_stream_info */
-static gint rtp_stream_info_cmp(gconstpointer aa, gconstpointer bb)
+/* GCompareFunc style comparison function for rtp_stream_info_t */
+static gint rtpstream_info_cmp(gconstpointer aa, gconstpointer bb)
{
- const struct _rtp_stream_info* a = (const struct _rtp_stream_info*)aa;
- const struct _rtp_stream_info* b = (const struct _rtp_stream_info*)bb;
+ const rtpstream_info_t* a = (const rtpstream_info_t*)aa;
+ const rtpstream_info_t* b = (const rtpstream_info_t*)bb;
if (a==b)
return 0;
* The header consists of an identifying string, followed
* by a binary structure.
*/
-void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file)
+void rtp_write_header(rtpstream_info_t *strinfo, FILE *file)
{
guint32 start_sec; /* start of recording (GMT) (seconds) */
guint32 start_usec; /* start of recording (GMT) (microseconds)*/
/****************************************************************************/
/* whenever a RTP packet is seen by the tap listener */
-int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
+int rtpstream_packet_cb(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
{
rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)arg;
const struct _rtp_info *rtpinfo = (const struct _rtp_info *)arg2;
- rtp_stream_info_t new_stream_info;
- rtp_stream_info_t *stream_info = NULL;
+ rtpstream_info_t new_stream_info;
+ rtpstream_info_t *stream_info = NULL;
GList* list;
rtpdump_info_t rtpdump_info;
/* gather infos on the stream this packet is part of.
* Addresses and strings are read-only and must be duplicated if copied. */
- memset(&new_stream_info, 0, sizeof(rtp_stream_info_t));
+ memset(&new_stream_info, 0, sizeof(rtpstream_info_t));
copy_address_shallow(&(new_stream_info.src_addr), &(pinfo->src));
new_stream_info.src_port = pinfo->srcport;
copy_address_shallow(&(new_stream_info.dest_addr), &(pinfo->dst));
list = g_list_first(tapinfo->strinfo_list);
while (list)
{
- if (rtp_stream_info_cmp(&new_stream_info, (rtp_stream_info_t*)(list->data))==0)
+ if (rtpstream_info_cmp(&new_stream_info, (rtpstream_info_t*)(list->data))==0)
{
- stream_info = (rtp_stream_info_t*)(list->data); /*found!*/
+ stream_info = (rtpstream_info_t*)(list->data); /*found!*/
break;
}
list = g_list_next(list);
else
new_stream_info.setup_frame_number = 0xFFFFFFFF;
- stream_info = g_new(rtp_stream_info_t,1);
+ stream_info = g_new(rtpstream_info_t,1);
/* Deep clone of contents. */
copy_address(&(new_stream_info.src_addr), &(new_stream_info.src_addr));
copy_address(&(new_stream_info.dest_addr), &(new_stream_info.dest_addr));
}
/* get RTP stats for the packet */
- rtp_packet_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo);
+ rtppacket_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo);
if (stream_info->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
|| stream_info->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
stream_info->problem = TRUE;
return 1; /* refresh output */
}
else if (tapinfo->mode == TAP_SAVE) {
- if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) {
+ if (rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) {
/* XXX - what if rtpinfo->info_all_data_present is
FALSE, so that we don't *have* all the data? */
rtpdump_info.rec_time = nstime_to_msec(&pinfo->abs_ts) -
}
}
else if (tapinfo->mode == TAP_MARK && tapinfo->tap_mark_packet) {
- if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0
- || rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_rev)==0)
+ if (rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0
+ || rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_rev)==0)
{
tapinfo->tap_mark_packet(tapinfo, pinfo->fd);
}
return 0;
}
-
-typedef struct _key_value {
- guint32 key;
- guint32 value;
-} key_value;
-
-
-/* RTP sampling clock rates for fixed payload types as defined in
- http://www.iana.org/assignments/rtp-parameters */
-static const key_value clock_map[] = {
- {PT_PCMU, 8000},
- {PT_1016, 8000},
- {PT_G721, 8000},
- {PT_GSM, 8000},
- {PT_G723, 8000},
- {PT_DVI4_8000, 8000},
- {PT_DVI4_16000, 16000},
- {PT_LPC, 8000},
- {PT_PCMA, 8000},
- {PT_G722, 8000},
- {PT_L16_STEREO, 44100},
- {PT_L16_MONO, 44100},
- {PT_QCELP, 8000},
- {PT_CN, 8000},
- {PT_MPA, 90000},
- {PT_G728, 8000},
- {PT_G728, 8000},
- {PT_DVI4_11025, 11025},
- {PT_DVI4_22050, 22050},
- {PT_G729, 8000},
- {PT_CN_OLD, 8000},
- {PT_CELB, 90000},
- {PT_JPEG, 90000},
- {PT_NV, 90000},
- {PT_H261, 90000},
- {PT_MPV, 90000},
- {PT_MP2T, 90000},
- {PT_H263, 90000},
-};
-
-#define NUM_CLOCK_VALUES (sizeof clock_map / sizeof clock_map[0])
-
-static guint32
-get_clock_rate(guint32 key)
-{
- size_t i;
-
- for (i = 0; i < NUM_CLOCK_VALUES; i++) {
- if (clock_map[i].key == key)
- return clock_map[i].value;
- }
- return 0;
-}
-
-typedef struct _mimetype_and_clock {
- const gchar *pt_mime_name_str;
- guint32 value;
-} mimetype_and_clock;
-/* RTP sampling clock rates for
- "In addition to the RTP payload formats (encodings) listed in the RTP
- Payload Types table, there are additional payload formats that do not
- have static RTP payload types assigned but instead use dynamic payload
- type number assignment. Each payload format is named by a registered
- MIME subtype"
- http://www.iana.org/assignments/rtp-parameters.
-
- NOTE: Please keep the mimetypes in case insensitive alphabetical order.
-*/
-static const mimetype_and_clock mimetype_and_clock_map[] = {
- {"AMR", 8000}, /* [RFC4867][RFC3267] */
- {"AMR-WB", 16000}, /* [RFC4867][RFC3267] */
- {"BMPEG", 90000}, /* [RFC2343],[RFC3555] */
- {"BT656", 90000}, /* [RFC2431],[RFC3555] */
- {"DV", 90000}, /* [RFC3189] */
- {"EVRC", 8000}, /* [RFC3558] */
- {"EVRC0", 8000}, /* [RFC4788] */
- {"EVRC1", 8000}, /* [RFC4788] */
- {"EVRCB", 8000}, /* [RFC4788] */
- {"EVRCB0", 8000}, /* [RFC4788] */
- {"EVRCB1", 8000}, /* [RFC4788] */
- {"EVRCWB", 16000}, /* [RFC5188] */
- {"EVRCWB0", 16000}, /* [RFC5188] */
- {"EVRCWB1", 16000}, /* [RFC5188] */
- {"EVS", 16000}, /* [3GPP TS 26.445] */
- {"G7221", 16000}, /* [RFC3047] */
- {"G726-16", 8000}, /* [RFC3551][RFC4856] */
- {"G726-24", 8000}, /* [RFC3551][RFC4856] */
- {"G726-32", 8000}, /* [RFC3551][RFC4856] */
- {"G726-40", 8000}, /* [RFC3551][RFC4856] */
- {"G729D", 8000}, /* [RFC3551][RFC4856] */
- {"G729E", 8000}, /* [RFC3551][RFC4856] */
- {"GSM-EFR", 8000}, /* [RFC3551] */
- {"H263-1998", 90000}, /* [RFC2429],[RFC3555] */
- {"H263-2000", 90000}, /* [RFC2429],[RFC3555] */
- {"H264", 90000}, /* [RFC3984] */
- {"MP1S", 90000}, /* [RFC2250],[RFC3555] */
- {"MP2P", 90000}, /* [RFC2250],[RFC3555] */
- {"MP4V-ES", 90000}, /* [RFC3016] */
- {"mpa-robust", 90000}, /* [RFC3119] */
- {"pointer", 90000}, /* [RFC2862] */
- {"raw", 90000}, /* [RFC4175] */
- {"red", 1000}, /* [RFC4102] */
- {"SMV", 8000}, /* [RFC3558] */
- {"SMV0", 8000}, /* [RFC3558] */
- {"t140", 1000}, /* [RFC4103] */
- {"telephone-event", 8000}, /* [RFC4733] */
-};
-
-#define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
-
-static guint32
-get_dyn_pt_clock_rate(const gchar *payload_type_str)
-{
- int i;
-
- /* Search for matching mimetype in reverse order to avoid false matches
- * when pt_mime_name_str is the prefix of payload_type_str */
- for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
- if (g_ascii_strncasecmp(mimetype_and_clock_map[i].pt_mime_name_str,payload_type_str,(strlen(mimetype_and_clock_map[i].pt_mime_name_str))) == 0)
- return mimetype_and_clock_map[i].value;
- }
-
- return 0;
-}
-
-/****************************************************************************/
-void
-rtp_packet_analyse(tap_rtp_stat_t *statinfo,
- packet_info *pinfo,
- const struct _rtp_info *rtpinfo)
-{
- double current_time;
- double current_jitter;
- double current_diff = 0;
- double nominaltime;
- double arrivaltime; /* Time relative to start_time */
- double expected_time;
- double absskew;
- guint32 clock_rate;
-
- /* Store the current time */
- current_time = nstime_to_msec(&pinfo->rel_ts);
-
- /* Is this the first packet we got in this direction? */
- if (statinfo->first_packet) {
- /* Save the MAC address of the first RTP frame */
- if( pinfo->dl_src.type == AT_ETHER){
- copy_address(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
- }
- statinfo->start_seq_nr = rtpinfo->info_seq_num;
- statinfo->stop_seq_nr = rtpinfo->info_seq_num;
- statinfo->seq_num = rtpinfo->info_seq_num;
- statinfo->start_time = current_time;
- statinfo->timestamp = rtpinfo->info_timestamp;
- statinfo->first_timestamp = rtpinfo->info_timestamp;
- statinfo->time = current_time;
- statinfo->lastnominaltime = 0;
- statinfo->pt = rtpinfo->info_payload_type;
- statinfo->reg_pt = rtpinfo->info_payload_type;
- if (pinfo->net_src.type == AT_IPv6) {
- statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
- } else {
- statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
- }
- statinfo->bw_history[statinfo->bw_index].time = current_time;
- statinfo->bw_index++;
- if (pinfo->net_src.type == AT_IPv6) {
- statinfo->total_bytes += rtpinfo->info_data_len + 48;
- } else {
- statinfo->total_bytes += rtpinfo->info_data_len + 28;
- }
- statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
- /* Not needed ? initialised to zero? */
- statinfo->delta = 0;
- statinfo->jitter = 0;
- statinfo->diff = 0;
-
- statinfo->total_nr++;
- statinfo->flags |= STAT_FLAG_FIRST;
- if (rtpinfo->info_marker_set) {
- statinfo->flags |= STAT_FLAG_MARKER;
- }
- statinfo->first_packet_num = pinfo->num;
- statinfo->first_packet = FALSE;
- return;
- }
-
- /* Reset flags */
- statinfo->flags = 0;
-#if 0
- /*According to bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11478
- * this code causes problems. A better solution is needed if there is need for the functionality */
- /* Try to detect duplicated packets due to mirroring/span ports by comparing src MAC addresses.
- * Chek for duplicates (src mac differs from first_packet_mac_addr) */
- */
- if( pinfo->dl_src.type == AT_ETHER){
- if(!addresses_equal(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
- statinfo->flags |= STAT_FLAG_DUP_PKT;
- statinfo->delta = current_time-(statinfo->time);
- return;
- }
- }
-#endif
- /* When calculating expected rtp packets the seq number can wrap around
- * so we have to count the number of cycles
- * Variable cycles counts the wraps around in forwarding connection and
- * under is flag that indicates where we are
- *
- * XXX How to determine number of cycles with all possible lost, late
- * and duplicated packets without any doubt? It seems to me, that
- * because of all possible combination of late, duplicated or lost
- * packets, this can only be more or less good approximation
- *
- * There are some combinations (rare but theoretically possible),
- * where below code won't work correctly - statistic may be wrong then.
- */
-
- /* So if the current sequence number is less than the start one
- * we assume, that there is another cycle running
- */
- if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
- statinfo->cycles++;
- statinfo->under = TRUE;
- }
- /* what if the start seq nr was 0? Then the above condition will never
- * be true, so we add another condition. XXX The problem would arise
- * if one of the packets with seq nr 0 or 65535 would be lost or late
- */
- else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
- (statinfo->under == FALSE)) {
- statinfo->cycles++;
- statinfo->under = TRUE;
- }
- /* the whole round is over, so reset the flag */
- else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
- statinfo->under = FALSE;
- }
-
- /* Since it is difficult to count lost, duplicate or late packets separately,
- * we would like to know at least how many times the sequence number was not ok
- */
-
- /* If the current seq number equals the last one or if we are here for
- * the first time, then it is ok, we just store the current one as the last one
- */
- if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
- statinfo->seq_num = rtpinfo->info_seq_num;
- /* If the first one is 65535 we wrap */
- else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
- statinfo->seq_num = rtpinfo->info_seq_num;
- /* Lost packets. If the prev seq is enormously larger than the cur seq
- * we assume that instead of being massively late we lost the packet(s)
- * that would have indicated the sequence number wrapping. An imprecise
- * heuristic at best, but it seems to work well enough.
- * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
- else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
- statinfo->seq_num = rtpinfo->info_seq_num;
- statinfo->sequence++;
- statinfo->flags |= STAT_FLAG_WRONG_SEQ;
- }
- /* Late or duplicated */
- else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
- statinfo->sequence++;
- statinfo->flags |= STAT_FLAG_WRONG_SEQ;
- }
-
- /* Check payload type */
- if (rtpinfo->info_payload_type == PT_CN
- || rtpinfo->info_payload_type == PT_CN_OLD)
- statinfo->flags |= STAT_FLAG_PT_CN;
- if (statinfo->pt == PT_CN
- || statinfo->pt == PT_CN_OLD)
- statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
- if (rtpinfo->info_payload_type != statinfo->pt)
- statinfo->flags |= STAT_FLAG_PT_CHANGE;
- statinfo->pt = rtpinfo->info_payload_type;
-
- /*
- * Return for unknown payload types
- * Ignore jitter calculation for clockrate = 0
- */
- if (statinfo->pt < 96 ){
- clock_rate = get_clock_rate(statinfo->pt);
- } else { /* Dynamic PT */
- if ( rtpinfo->info_payload_type_str != NULL ) {
- /* Is it a "telephone-event" ?
- * Timestamp is not increased for telepone-event packets impacting
- * calculation of Jitter Skew and clock drift.
- * see 2.2.1 of RFC 4733
- */
- if (g_ascii_strncasecmp("telephone-event",rtpinfo->info_payload_type_str,(strlen("telephone-event")))==0) {
- clock_rate = 0;
- statinfo->flags |= STAT_FLAG_PT_T_EVENT;
- } else {
- if(rtpinfo->info_payload_rate !=0) {
- clock_rate = rtpinfo->info_payload_rate;
- } else {
- clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str);
- }
- }
- } else {
- clock_rate = 0;
- }
- }
-
- /* Handle wraparound ? */
- arrivaltime = current_time - statinfo->start_time;
-
- nominaltime = (double)(guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->first_timestamp));
-
- /* Can only analyze defined sampling rates */
- if (clock_rate != 0) {
- statinfo->clock_rate = clock_rate;
- /* Convert from sampling clock to ms */
- nominaltime = nominaltime /(clock_rate/1000);
-
- /* Calculate the current jitter(in ms) */
- if (!statinfo->first_packet) {
- expected_time = statinfo->time + (nominaltime - statinfo->lastnominaltime);
- current_diff = fabs(current_time - expected_time);
- current_jitter = (15 * statinfo->jitter + current_diff) / 16;
-
- statinfo->delta = current_time-(statinfo->time);
- statinfo->jitter = current_jitter;
- statinfo->diff = current_diff;
- }
- statinfo->lastnominaltime = nominaltime;
- /* Calculate skew, i.e. absolute jitter that also catches clock drift
- * Skew is positive if TS (nominal) is too fast
- */
- statinfo->skew = nominaltime - arrivaltime;
- absskew = fabs(statinfo->skew);
- if(absskew > fabs(statinfo->max_skew)) {
- statinfo->max_skew = statinfo->skew;
- }
- /* Gather data for calculation of average, minimum and maximum framerate based on timestamp */
-#if 0
- if (numPackets > 0 && (!hardPayloadType || !alternatePayloadType)) {
- /* Skip first packet and possibly alternate payload type packets */
- double dt;
- dt = nominaltime - statinfo->lastnominaltime;
- sumdt += 1.0 * dt;
- numdt += (dt != 0 ? 1 : 0);
- mindt = (dt < mindt ? dt : mindt);
- maxdt = (dt > maxdt ? dt : maxdt);
- }
-#endif
- /* Gather data for calculation of skew least square */
- statinfo->sumt += 1.0 * current_time;
- statinfo->sumTS += 1.0 * nominaltime;
- statinfo->sumt2 += 1.0 * current_time * current_time;
- statinfo->sumtTS += 1.0 * current_time * nominaltime;
- }
-
- /* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP) + 8bytes(UDP) */
- if (pinfo->net_src.type == AT_IPv6) {
- statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
- } else {
- statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
- }
- statinfo->bw_history[statinfo->bw_index].time = current_time;
-
- /* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
- while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
- statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
- statinfo->bw_start_index++;
- if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
- };
- /* IP hdr + UDP + RTP */
- if (pinfo->net_src.type == AT_IPv6){
- statinfo->total_bytes += rtpinfo->info_data_len + 48;
- }else{
- statinfo->total_bytes += rtpinfo->info_data_len + 28;
- }
- statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
- statinfo->bw_index++;
- if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
-
-
- /* Used by GTK code only */
- statinfo->delta_timestamp = guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->timestamp);
-
- /* Is it a packet with the mark bit set? */
- if (rtpinfo->info_marker_set) {
- statinfo->flags |= STAT_FLAG_MARKER;
- }
-
- /* Difference can be negative. We don't expect difference bigger than 31 bits. Difference don't care about wrap around. */
- gint32 tsdelta=rtpinfo->info_timestamp - statinfo->timestamp;
- if (tsdelta < 0) {
- statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
- }
- /* Is it a regular packet? */
- if (!(statinfo->flags & STAT_FLAG_FIRST)
- && !(statinfo->flags & STAT_FLAG_MARKER)
- && !(statinfo->flags & STAT_FLAG_PT_CN)
- && !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
- && !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
- /* Include it in maximum delta calculation */
- if (statinfo->delta > statinfo->max_delta) {
- statinfo->max_delta = statinfo->delta;
- statinfo->max_nr = pinfo->num;
- }
- if (clock_rate != 0) {
- /* Maximum and mean jitter calculation */
- if (statinfo->jitter > statinfo->max_jitter) {
- statinfo->max_jitter = statinfo->jitter;
- }
- statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
- }
- }
- /* Regular payload change? (CN ignored) */
- if (!(statinfo->flags & STAT_FLAG_FIRST)
- && !(statinfo->flags & STAT_FLAG_PT_CN)) {
- if ((statinfo->pt != statinfo->reg_pt)
- && (statinfo->reg_pt != PT_UNDEFINED)) {
- statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
- }
- }
-
- /* Set regular payload*/
- if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
- statinfo->reg_pt = statinfo->pt;
- }
-
- statinfo->time = current_time;
- statinfo->timestamp = rtpinfo->info_timestamp;
- statinfo->stop_seq_nr = rtpinfo->info_seq_num;
- statinfo->total_nr++;
- statinfo->last_payload_len = rtpinfo->info_payload_len - rtpinfo->info_padding_count;
-
- return;
-}
-
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
extern "C" {
#endif /* __cplusplus */
+#include "ui/rtp_stream.h"
+
/* type of error when saving voice in a file didn't succeed */
typedef enum {
+ TAP_RTP_NO_ERROR,
TAP_RTP_WRONG_CODEC,
TAP_RTP_WRONG_LENGTH,
TAP_RTP_PADDING_ERROR,
TAP_RTP_SHORT_FRAME,
TAP_RTP_FILE_OPEN_ERROR,
TAP_RTP_FILE_WRITE_ERROR,
- TAP_RTP_NO_DATA
-} error_type_t;
+ TAP_RTP_NO_DATA,
+} tap_rtp_error_type_t;
typedef struct _tap_rtp_save_info_t {
FILE *fp;
guint32 count;
- error_type_t error_type;
+ tap_rtp_error_type_t error_type;
gboolean saved;
} tap_rtp_save_info_t;
-struct _rtp_stream_info;
-
void rtpstream_reset_cb(void*);
-void rtp_write_header(struct _rtp_stream_info*, FILE*);
-int rtpstream_packet(void*, packet_info*, epan_dissect_t *, const void *);
+void rtp_write_header(rtpstream_info_t*, FILE*);
+int rtpstream_packet_cb(void*, packet_info*, epan_dissect_t *, const void *);
#ifdef __cplusplus
}
voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
{
voip_calls_info_t *callsinfo;
- rtp_stream_info_t *strinfo;
+ rtpstream_info_t *strinfo;
GList *list = NULL;
/* VOIP_CALLS_DEBUG("reset packets: %d streams: %d", tapinfo->npackets, tapinfo->nrtp_streams); */
list = g_list_first(tapinfo->rtp_stream_list);
while(list)
{
- strinfo = (rtp_stream_info_t *)list->data;
+ strinfo = (rtpstream_info_t *)list->data;
wmem_free(NULL, strinfo->payload_type_name);
wmem_free(NULL, strinfo->ed137_info);
list = g_list_next(list);
rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
- rtp_stream_info_t *tmp_listinfo;
- rtp_stream_info_t *strinfo = NULL;
+ rtpstream_info_t *tmp_listinfo;
+ rtpstream_info_t *strinfo = NULL;
GList *list;
struct _rtp_conversation_info *p_conv_data = NULL;
list = g_list_first(tapinfo->rtp_stream_list);
while (list)
{
- tmp_listinfo=(rtp_stream_info_t *)list->data;
+ tmp_listinfo=(rtpstream_info_t *)list->data;
if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
&& (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
/* if the payload type has changed, we mark the stream as finished to create a new one
/* if ed137_info has changed, create new stream */
tmp_listinfo->end_stream = TRUE;
} else {
- strinfo = (rtp_stream_info_t*)(list->data);
+ strinfo = (rtpstream_info_t*)(list->data);
break;
}
}
/* not in the list? then create a new entry */
if (strinfo==NULL) {
- strinfo = (rtp_stream_info_t *)g_malloc0(sizeof(rtp_stream_info_t));
+ strinfo = (rtpstream_info_t *)g_malloc0(sizeof(rtpstream_info_t));
copy_address(&(strinfo->src_addr), &(pinfo->src));
strinfo->src_port = pinfo->srcport;
copy_address(&(strinfo->dest_addr), &(pinfo->dst));
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
GList *rtp_streams_list;
- rtp_stream_info_t *rtp_listinfo;
+ rtpstream_info_t *rtp_listinfo;
/* GList *voip_calls_graph_list; */
seq_analysis_item_t *gai = NULL;
seq_analysis_item_t *new_gai;
rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
while (rtp_streams_list)
{
- rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
+ rtp_listinfo = (rtpstream_info_t *)rtp_streams_list->data;
/* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
/* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
{
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
GList *rtp_streams_list;
- rtp_stream_info_t *rtp_listinfo;
+ rtpstream_info_t *rtp_listinfo;
GList *voip_calls_graph_list;
guint item;
seq_analysis_item_t *gai;