some more path fixes for g_ascii_strcasecmp.h
[obnox/wireshark/wip.git] / gtk / rtp_analysis.c
index f6ad1016b23c3b47f126f88b92bc30fd228699b9..a4bdf39a273429bd44754285ed995677a812d501 100644 (file)
@@ -1,5 +1,5 @@
 /* rtp_analysis.c
- * RTP analysis addition for ethereal
+ * RTP analysis addition for Wireshark
  *
  * $Id$
  *
  *
  * Graph. Copyright 2004, Verso Technology
  * By Alejandro Vaquero <alejandro.vaquero@verso.com>
- * Based on io_stat.c by Ronnie Sahlberg 
+ * Based on io_stat.c by Ronnie Sahlberg
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 /*do not define this symbol. will be added soon*/
 /*#define USE_CONVERSATION_GRAPH 1*/
 
-#include "rtp_analysis.h"
-#include "rtp_stream.h"
-#include "rtp_stream_dlg.h"
-
 #ifdef USE_CONVERSATION_GRAPH
 #include "../graph/graph.h"
 #endif
 #include "register.h"
 #include <epan/dissectors/packet-rtp.h>
 #include "g711.h"
-#include "rtp_pt.h"
+#include <epan/rtp_pt.h>
+#include <epan/addr_resolv.h>
 
 /* in /gtk ... */
 #include <gtk/gtk.h>
 #include "gtkglobals.h"
 
+#include <epan/stat_cmd_args.h>
 #include "dlg_utils.h"
-#include "ui_util.h"
+#include "file_dlg.h"
+#include "gui_utils.h"
 #include "alert_box.h"
 #include "simple_dialog.h"
-#include "tap_menu.h"
+#include "../stat_menu.h"
+#include "gui_stat_menu.h"
 #include "main.h"
 #include "progress_dlg.h"
 #include "compat_macros.h"
@@ -76,8 +76,8 @@
 #include "image/clist_descend.xpm"
 
 #include <math.h>
-#include <fcntl.h>
 #include <string.h>
+#include <locale.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #include <fcntl.h>
 #endif
 
-#ifdef HAVE_IO_H
-#include <io.h> /* open/close on win32 */
-#endif
+#include "file_util.h"
+#include "tempfile.h"
 
-/* Win32 needs the O_BINARY flag for open() */
-#ifndef O_BINARY
-#define O_BINARY 0
+#include "rtp_analysis.h"
+#include "rtp_stream.h"
+#include "rtp_stream_dlg.h"
+
+#ifdef NEED_G_ASCII_STRCASECMP_H
+#include "../epan/g_ascii_strcasecmp.h"
 #endif
 
+
 /****************************************************************************/
 
 typedef struct column_arrows {
@@ -118,7 +121,7 @@ static guint32 yscale_max[MAX_YSCALE] = {AUTO_MAX_YSCALE, 1000, 2000, 5000, 1000
 #define MAX_PIXELS_PER_TICK 4
 #define DEFAULT_PIXELS_PER_TICK 1
 static guint32 pixels_per_tick[MAX_PIXELS_PER_TICK] = {1, 2, 5, 10};
-static char *graph_descr[4] = {"Fwd Jitter", "Fwd Difference", "Rvr Jitter", "Rvr Difference"};
+static const char *graph_descr[4] = {"Fwd Jitter", "Fwd Difference", "Rvr Jitter", "Rvr Difference"};
 /* unit is in ms */
 #define MAX_TICK_VALUES 5
 #define DEFAULT_TICK_VALUE 1
@@ -129,7 +132,7 @@ typedef struct _dialog_graph_graph_item_t {
 } dialog_graph_graph_item_t;
 
 typedef struct _dialog_graph_graph_t {
-       struct _user_data_t *ud;        
+       struct _user_data_t *ud;
         dialog_graph_graph_item_t items[NUM_GRAPH_ITEMS];
         int plot_style;
         gboolean display;
@@ -158,7 +161,7 @@ typedef struct _dialog_graph_t {
         int pixels_per_tick;
         int max_y_units;
        double start_time;
-} dialog_graph_t;      
+} dialog_graph_t;
 
 typedef struct _dialog_data_t {
        GtkWidget *window;
@@ -235,6 +238,63 @@ get_clock_rate(guint32 key)
        return 1;
 }
 
+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.
+*/
+static const mimetype_and_clock mimetype_and_clock_map[] = {
+       {"AMR",         8000},                  /* [RFC3267] */
+       {"AMR-WB",      16000},                 /* [RFC3267] */
+       {"EVRC",        8000},                  /* [RFC3558] */
+       {"EVRC0",       8000},                  /* [RFC3558] */
+       {"G7221",       16000},                 /* [RFC3047] */
+       {"G726-16",     8000},                  /* [RFC3551] */
+       {"G726-24",     8000},                  /* [RFC3551] */
+       {"G726-32",     8000},                  /* [RFC3551] */
+       {"G726-40",     8000},                  /* [RFC3551] */
+       {"G729D",       8000},                  /* [RFC3551] */
+       {"G729E",       8000},                  /* [RFC3551] */
+       {"GSM-EFR",     8000},                  /* [RFC3551] */
+       {"mpa-robust",  90000},         /* [RFC3119] */
+       {"SMV",         8000},                  /* [RFC3558] */
+       {"SMV0",        8000},                  /* [RFC3558] */
+       {"red",         1000},                  /* [RFC4102] */
+       {"t140",        1000},                  /* [RFC4103] */
+       {"BMPEG",       90000},                 /* [RFC2343],[RFC3555] */
+       {"BT656",       90000},                 /* [RFC2431],[RFC3555] */
+       {"DV",          90000},                 /* [RFC3189] */
+       {"H263-1998",   90000},         /* [RFC2429],[RFC3555] */
+       {"H263-2000",   90000},         /* [RFC2429],[RFC3555] */
+       {"MP1S",        90000},                 /* [RFC2250],[RFC3555] */
+       {"MP2P",        90000},                 /* [RFC2250],[RFC3555] */
+       {"MP4V-ES",     90000},                 /* [RFC3016] */
+       {"pointer",     90000},                 /* [RFC2862] */
+       {"raw",         90000},                 /* [RFC4175] */
+       {"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(gchar *payload_type_str)
+{
+       size_t i;
+
+       for (i = 0; i < NUM_DYN_CLOCK_VALUES; 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 1;
+}
 
 /* type of error when saving voice in a file didn't succeed */
 typedef enum {
@@ -244,7 +304,7 @@ typedef enum {
        TAP_RTP_SHORT_FRAME,
        TAP_RTP_FILE_OPEN_ERROR,
        TAP_RTP_NO_DATA
-} error_type_t; 
+} error_type_t;
 
 #if GTK_MAJOR_VERSION < 2
 GtkRcStyle *rc_style;
@@ -267,7 +327,10 @@ struct _info_direction {
 
 #define TMPNAMSIZE 100
 
-/* structure that holds general information about the connection 
+#define SILENCE_PCMU   (guint8)0xFF
+#define SILENCE_PCMA   (guint8)0x55
+
+/* structure that holds general information about the connection
 * and structures for both directions */
 typedef struct _user_data_t {
        /* tap associated data*/
@@ -299,7 +362,7 @@ typedef struct _user_data_t {
 
 
 /* Column titles. */
-static gchar *titles[9] =  {
+static const gchar *titles[9] =  {
        "Packet",
        "Sequence",
        "Delta (ms)",
@@ -311,12 +374,22 @@ static gchar *titles[9] =  {
        "Length"
 };
 
+#define SAVE_FORWARD_DIRECTION_MASK 0x01
+#define SAVE_REVERSE_DIRECTION_MASK 0x02
+#define SAVE_BOTH_DIRECTION_MASK       (SAVE_FORWARD_DIRECTION_MASK|SAVE_REVERSE_DIRECTION_MASK)
+
+#define SAVE_NONE_FORMAT 0
+#define SAVE_WAV_FORMAT        1
+#define SAVE_AU_FORMAT 2
+#define SAVE_SW_FORMAT 3
+#define SAVE_RAW_FORMAT        4
+
 
 static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_);
 /****************************************************************************/
 static void enable_graph(dialog_graph_graph_t *dgg)
 {
-        
+
         dgg->display=TRUE;
 
 }
@@ -344,8 +417,8 @@ rtp_reset(void *user_data_arg)
        user_data->reversed.statinfo.mean_jitter = 0;
        user_data->forward.statinfo.delta = 0;
        user_data->reversed.statinfo.delta = 0;
-        user_data->forward.statinfo.diff = 0;
-        user_data->reversed.statinfo.diff = 0;
+       user_data->forward.statinfo.diff = 0;
+       user_data->reversed.statinfo.diff = 0;
        user_data->forward.statinfo.jitter = 0;
        user_data->reversed.statinfo.jitter = 0;
        user_data->forward.statinfo.bandwidth = 0;
@@ -394,7 +467,7 @@ rtp_reset(void *user_data_arg)
 #ifdef USE_CONVERSATION_GRAPH
        if (user_data->dlg.graph_window != NULL)
                window_destroy(user_data->dlg.graph_window);
-       
+
        g_array_free(user_data->series_fwd.value_pairs, TRUE);
        user_data->series_fwd.value_pairs = g_array_new(FALSE, FALSE, sizeof(value_pair_t));
 
@@ -404,13 +477,13 @@ rtp_reset(void *user_data_arg)
 
        /* XXX check for error at fclose? */
        if (user_data->forward.saveinfo.fp != NULL)
-               fclose(user_data->forward.saveinfo.fp); 
+               fclose(user_data->forward.saveinfo.fp);
        if (user_data->reversed.saveinfo.fp != NULL)
-               fclose(user_data->reversed.saveinfo.fp); 
-       user_data->forward.saveinfo.fp = fopen(user_data->f_tempname, "wb"); 
+               fclose(user_data->reversed.saveinfo.fp);
+       user_data->forward.saveinfo.fp = eth_fopen(user_data->f_tempname, "wb");
        if (user_data->forward.saveinfo.fp == NULL)
                user_data->forward.saveinfo.error_type = TAP_RTP_FILE_OPEN_ERROR;
-       user_data->reversed.saveinfo.fp = fopen(user_data->r_tempname, "wb");
+       user_data->reversed.saveinfo.fp = eth_fopen(user_data->r_tempname, "wb");
        if (user_data->reversed.saveinfo.fp == NULL)
                user_data->reversed.saveinfo.error_type = TAP_RTP_FILE_OPEN_ERROR;
        return;
@@ -419,56 +492,56 @@ rtp_reset(void *user_data_arg)
 /****************************************************************************/
 static int rtp_packet_add_graph(dialog_graph_graph_t *dgg, tap_rtp_stat_t *statinfo, packet_info *pinfo, guint32 value)
 {
-        dialog_graph_graph_item_t *it;
-        int idx;
+       dialog_graph_graph_item_t *it;
+       int idx;
        double rtp_time;
 
-        /* we sometimes get called when dgg is disabled.
-           this is a bug since the tap listener should be removed first */
-        if(!dgg->display){
-                return 0;
-        }
+       /* we sometimes get called when dgg is disabled.
+       this is a bug since the tap listener should be removed first */
+       if(!dgg->display){
+               return 0;
+       }
 
-        dgg->ud->dlg.dialog_graph.needs_redraw=TRUE;
+       dgg->ud->dlg.dialog_graph.needs_redraw=TRUE;
 
-        /*
-         * Find which interval this is supposed to to in and store the
-         * interval index as idx
-         */
+       /*
+       * Find which interval this is supposed to to in and store the
+       * interval index as idx
+       */
        if (dgg->ud->dlg.dialog_graph.start_time == -1){ /* it is the first */
                dgg->ud->dlg.dialog_graph.start_time = statinfo->start_time;
-       }       
-       rtp_time = ((double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000) - dgg->ud->dlg.dialog_graph.start_time;
+       }
+       rtp_time = nstime_to_sec(&pinfo->fd->rel_ts) - dgg->ud->dlg.dialog_graph.start_time;
        if(rtp_time<0){
                return FALSE;
-       }       
+       }
        idx = (guint32)(rtp_time*1000)/dgg->ud->dlg.dialog_graph.interval;
 
-        /* some sanity checks */
-        if((idx<0)||(idx>=NUM_GRAPH_ITEMS)){
-                return FALSE;
-        }
+       /* some sanity checks */
+       if((idx<0)||(idx>=NUM_GRAPH_ITEMS)){
+               return FALSE;
+       }
 
-        /* update num_items */
-        if((guint32)idx > dgg->ud->dlg.dialog_graph.num_items){
-                dgg->ud->dlg.dialog_graph.num_items=idx;
-                dgg->ud->dlg.dialog_graph.max_interval=idx*dgg->ud->dlg.dialog_graph.interval;
-        }
+       /* update num_items */
+       if((guint32)idx > dgg->ud->dlg.dialog_graph.num_items){
+               dgg->ud->dlg.dialog_graph.num_items=idx;
+               dgg->ud->dlg.dialog_graph.max_interval=idx*dgg->ud->dlg.dialog_graph.interval;
+       }
 
-        /*
-         * Find the appropriate dialog_graph_graph_item_t structure
-         */
-        it=&dgg->items[idx];
+       /*
+       * Find the appropriate dialog_graph_graph_item_t structure
+       */
+       it=&dgg->items[idx];
 
        /*
-        * Use the max value to highlight RTP problems
-        */
+       * Use the max value to highlight RTP problems
+       */
        if (value > it->value) {
                it->value=value;
        }
        it->flags = it->flags | statinfo->flags;
 
-        return TRUE;
+       return TRUE;
 }
 
 /****************************************************************************/
@@ -488,7 +561,7 @@ static int rtp_packet_add_info(GtkCList *clist,
        tap_rtp_stat_t *statinfo, packet_info *pinfo,
        const struct _rtp_info *rtpinfo);
 
-static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo, 
+static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                                    tap_rtp_stat_t *statinfo,
                                    packet_info *pinfo,
                                    const struct _rtp_info *rtpinfo);
@@ -510,7 +583,11 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
        else if (rtpinfo->info_version !=2)
                return 0;
        /* is it the forward direction?  */
-       else if (user_data->ssrc_fwd == rtpinfo->info_sync_src)  {
+       else if (user_data->ssrc_fwd == rtpinfo->info_sync_src
+               && CMP_ADDRESS(&(user_data->ip_src_fwd), &(pinfo->net_src)) == 0
+               && user_data->port_src_fwd == pinfo->srcport
+               && CMP_ADDRESS(&(user_data->ip_dst_fwd), &(pinfo->net_dst)) == 0
+               && user_data->port_dst_fwd == pinfo->destport)  {
 #ifdef USE_CONVERSATION_GRAPH
                vp.time = ((double)pinfo->fd->rel_secs + (double)pinfo->fd->rel_usecs/1000000);
                vp.fnumber = pinfo->fd->num;
@@ -525,7 +602,11 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
                        &(user_data->forward.statinfo), pinfo, rtpinfo);
        }
        /* is it the reversed direction? */
-       else if (user_data->ssrc_rev == rtpinfo->info_sync_src) {
+       else if (user_data->ssrc_rev == rtpinfo->info_sync_src
+               && CMP_ADDRESS(&(user_data->ip_src_rev), &(pinfo->net_src)) == 0
+               && user_data->port_src_rev == pinfo->srcport
+               && CMP_ADDRESS(&(user_data->ip_dst_rev), &(pinfo->net_dst)) == 0
+               && user_data->port_dst_rev == pinfo->destport)  {
 #ifdef USE_CONVERSATION_GRAPH
                vp.time = ((double)pinfo->fd->rel_secs + (double)pinfo->fd->rel_usecs/1000000);
                vp.fnumber = pinfo->fd->num;
@@ -570,10 +651,17 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
         * payload types, presumably meaning that we should
         * just ignore this packet?
         */
-       clock_rate = get_clock_rate(statinfo->pt);
+       if (statinfo->pt < 96 ){
+               clock_rate = get_clock_rate(statinfo->pt);
+       }else{ /* dynamic PT */
+               if ( rtpinfo->info_payload_type_str != NULL )
+                       clock_rate = get_dyn_pt_clock_rate(rtpinfo-> info_payload_type_str);
+               else
+                       clock_rate = 1;
+       }
 
        /* store the current time and calculate the current jitter */
-       current_time = (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
+       current_time = nstime_to_sec(&pinfo->fd->rel_ts);
        current_diff = fabs (current_time - (statinfo->time) - ((double)(rtpinfo->info_timestamp)-(double)(statinfo->timestamp))/clock_rate);
        current_jitter = statinfo->jitter + ( current_diff - statinfo->jitter)/16;
        statinfo->delta = current_time-(statinfo->time);
@@ -585,14 +673,14 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
        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+1)<current_time){
-               statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;  
+               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;
        };
        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;      
+       if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
 
 
        /*  is this the first packet we got in this direction? */
@@ -607,8 +695,8 @@ int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
        }
        /* is it a packet with the mark bit set? */
        if (rtpinfo->info_marker_set) {
+               statinfo->delta_timestamp = rtpinfo->info_timestamp - statinfo->timestamp;
                if (rtpinfo->info_timestamp > statinfo->timestamp){
-                       statinfo->delta_timestamp = rtpinfo->info_timestamp - statinfo->timestamp;
                        statinfo->flags |= STAT_FLAG_MARKER;
                }
                else{
@@ -727,8 +815,8 @@ static int rtp_packet_add_info(GtkCList *clist,
        time_t then;
        gchar status[40];
        GdkColor color = COLOR_DEFAULT;
-       then = pinfo->fd->abs_secs;
-       msecs = (guint16)(pinfo->fd->abs_usecs/1000);
+       then = pinfo->fd->abs_ts.secs;
+       msecs = (guint16)(pinfo->fd->abs_ts.nsecs/1000000);
        tm_tmp = localtime(&then);
        g_snprintf(timeStr,sizeof(timeStr),"%02d/%02d/%04d %02d:%02d:%02d.%03d",
                tm_tmp->tm_mon + 1,
@@ -799,16 +887,17 @@ static int rtp_packet_add_info(GtkCList *clist,
        return 0;
 }
 
-
+#define MAX_SILENCE_TICKS 1000000
 /****************************************************************************/
-static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo, 
+static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                                    tap_rtp_stat_t *statinfo,
                                    packet_info *pinfo,
                                    const struct _rtp_info *rtpinfo)
 {
        guint i;
        const guint8 *data;
-       gint16 tmp;
+       guint8 tmp;
+       size_t nchars;
 
        /*  is this the first packet we got in this direction? */
        if (statinfo->flags & STAT_FLAG_FIRST) {
@@ -826,8 +915,9 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                return 0;
 
        /* if the captured length and packet length aren't equal, we quit
-       * because there is some information missing */
-       if (pinfo->fd->pkt_len != pinfo->fd->cap_len) {
+       * if also the RTP dissector thinks there is some information missing */
+       if ((pinfo->fd->pkt_len != pinfo->fd->cap_len) &&
+           (!rtpinfo->info_all_data_present)) {
                saveinfo->saved = FALSE;
                saveinfo->error_type = TAP_RTP_WRONG_LENGTH;
                return 0;
@@ -845,46 +935,37 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
        /* do we need to insert some silence? */
        if ((rtpinfo->info_marker_set) &&
                !(statinfo->flags & STAT_FLAG_FIRST) &&
+               !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP) &&
                (statinfo->delta_timestamp > (rtpinfo->info_payload_len - rtpinfo->info_padding_count)) )  {
                /* the amount of silence should be the difference between
                * the last timestamp and the current one minus x
                * x should equal the amount of information in the last frame
                * XXX not done yet */
                for(i=0; i < (statinfo->delta_timestamp - rtpinfo->info_payload_len -
-                       rtpinfo->info_padding_count); i++) {
-                       tmp = (gint16 )ulaw2linear((unsigned char)(0x55));
-                       fwrite(&tmp, 2, 1, saveinfo->fp);
+                       rtpinfo->info_padding_count) && i < MAX_SILENCE_TICKS; i++) {
+                       switch (statinfo->reg_pt) {
+                       case PT_PCMU:
+                               tmp = SILENCE_PCMU;
+                               break;
+                       case PT_PCMA:
+                               tmp = SILENCE_PCMA;
+                               break;
+                       default:
+                               tmp = 0;
+                               break;
+                       }
+                       nchars=fwrite(&tmp, 1, 1, saveinfo->fp);
                        saveinfo->count++;
                }
                fflush(saveinfo->fp);
        }
 
-       /* ulaw? */
-       if (rtpinfo->info_payload_type == PT_PCMU) {
-               if (!rtpinfo->info_all_data_present) {
-                       /* Not all the data was captured. */
-                       saveinfo->saved = FALSE;
-                       saveinfo->error_type = TAP_RTP_SHORT_FRAME;
-                       return 0;
-               }
 
-               /* we put the pointer at the beginning of the RTP
-               * payload, that is, at the beginning of the RTP data
-               * plus the offset of the payload from the beginning
-               * of the RTP data */
-               data = rtpinfo->info_data + rtpinfo->info_payload_offset;
-               for(i=0; i < (rtpinfo->info_payload_len - rtpinfo->info_padding_count); i++, data++) {
-                       tmp = (gint16 )ulaw2linear((unsigned char)*data);
-                       fwrite(&tmp, 2, 1, saveinfo->fp);
-                       saveinfo->count++;
-               }
-               fflush(saveinfo->fp);
-               saveinfo->saved = TRUE;
-               return 0;
+       if (rtpinfo->info_payload_type == PT_CN
+               || rtpinfo->info_payload_type == PT_CN_OLD) {
        }
-
-       /* alaw? */
-       else if (rtpinfo->info_payload_type == PT_PCMA) {
+       /*all other payloads*/
+       else {
                if (!rtpinfo->info_all_data_present) {
                        /* Not all the data was captured. */
                        saveinfo->saved = FALSE;
@@ -897,25 +978,13 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                * plus the offset of the payload from the beginning
                * of the RTP data */
                data = rtpinfo->info_data + rtpinfo->info_payload_offset;
-               for(i=0; i < (rtpinfo->info_payload_len - rtpinfo->info_padding_count); i++, data++) {
-                       tmp = (gint16 )alaw2linear((unsigned char)*data);
-                       fwrite(&tmp, 2, 1, saveinfo->fp);
-                       saveinfo->count++;
-               }
+               nchars=fwrite(data, sizeof(unsigned char), (rtpinfo->info_payload_len - rtpinfo->info_padding_count), saveinfo->fp);
+               saveinfo->count+=(rtpinfo->info_payload_len - rtpinfo->info_padding_count);
+
                fflush(saveinfo->fp);
                saveinfo->saved = TRUE;
                return 0;
        }
-       /* comfort noise? - do nothing */
-       else if (rtpinfo->info_payload_type == PT_CN
-               || rtpinfo->info_payload_type == PT_CN_OLD) {
-       }
-       /* unsupported codec or XXX other error */
-       else {
-               saveinfo->saved = FALSE;
-               saveinfo->error_type = TAP_RTP_WRONG_CODEC;
-               return 0;
-       }
 
        return 0;
 }
@@ -945,8 +1014,8 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_)
        if (user_data->reversed.saveinfo.fp != NULL)
                fclose(user_data->reversed.saveinfo.fp);
        /*XXX: test for error **/
-       remove(user_data->f_tempname);
-       remove(user_data->r_tempname);
+       eth_remove(user_data->f_tempname);
+       eth_remove(user_data->r_tempname);
 
        /* destroy save_voice_as window if open */
        if (user_data->dlg.save_voice_as_w != NULL)
@@ -962,7 +1031,7 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_)
                window_destroy(user_data->dlg.graph_window);
 #endif
 
-       /* disable the "switch_page" signal in the dlg, otherwise will be called when the windows is destroy and cause an exeption using GTK1*/
+       /* disable the "switch_page" signal in the dlg, otherwise will be called when the windows is destroy and cause an exception using GTK1*/
        gtk_signal_disconnect(GTK_OBJECT(user_data->dlg.notebook), user_data->dlg.notebook_signal_id);
 
        g_free(user_data->dlg.col_arrows_fwd);
@@ -1033,7 +1102,7 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        gchar title1[80];
        gchar title2[80];
        GList *list = NULL;
-       
+
        if (user_data->dlg.graph_window != NULL) {
                /* There's already a graph window; reactivate it. */
                reactivate_window(user_data->dlg.graph_window);
@@ -1054,24 +1123,24 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        user_data->series_rev.color.blue = 0xffff;
        user_data->series_rev.yvalue = -0.5;
 
-       g_snprintf(title1, 80, "Forward: %s:%u to %s:%u (SSRC=%u)",
-               address_to_str_w_none(&(user_data->ip_src_fwd)), 
+       g_snprintf(title1, 80, "Forward: %s:%u to %s:%u (SSRC=0x%X)",
+               get_addr_name(&(user_data->ip_src_fwd)),
                user_data->port_src_fwd,
-               address_to_str_w_none(&(user_data->ip_dst_fwd)),
+               get_addr_name(&(user_data->ip_dst_fwd)),
                user_data->port_dst_fwd,
                user_data->ssrc_fwd);
 
-       g_snprintf(title2, 80, "Reverse: %s:%u to %s:%u (SSRC=%u)",
-               address_to_str_w_none(&(user_data->ip_src_rev)),
+       g_snprintf(title2, 80, "Reverse: %s:%u to %s:%u (SSRC=0x%X)",
+               get_addr_name(&(user_data->ip_src_rev)),
                user_data->port_src_rev,
-               address_to_str_w_none(&(user_data->ip_dst_rev)),
+               get_addr_name(&(user_data->ip_dst_rev)),
                user_data->port_dst_rev,
                user_data->ssrc_rev);
 
        user_data->dlg.graph_window = show_conversation_graph(list, title1, title2,
                &graph_selection_callback, user_data);
        SIGNAL_CONNECT(user_data->dlg.graph_window, "destroy",
-                       on_destroy_graph, user_data);
+                       on_destroy_graph, user_data);
 }
 #endif /*USE_CONVERSATION_GRAPH*/
 
@@ -1083,17 +1152,17 @@ static void dialog_graph_set_title(user_data_t* user_data)
                return;
        }
        title = g_strdup_printf("RTP Graph Analysis Forward: %s:%u to %s:%u   Reverse: %s:%u to %s:%u",
-                       address_to_str_w_none(&(user_data->ip_src_fwd)),
+                       get_addr_name(&(user_data->ip_src_fwd)),
                        user_data->port_src_fwd,
-                       address_to_str_w_none(&(user_data->ip_dst_fwd)),
+                       get_addr_name(&(user_data->ip_dst_fwd)),
                        user_data->port_dst_fwd,
-                       address_to_str_w_none(&(user_data->ip_src_rev)),
+                       get_addr_name(&(user_data->ip_src_rev)),
                        user_data->port_src_rev,
-                       address_to_str_w_none(&(user_data->ip_dst_rev)),
+                       get_addr_name(&(user_data->ip_dst_rev)),
                        user_data->port_dst_rev);
 
        gtk_window_set_title(GTK_WINDOW(user_data->dlg.dialog_graph.window), title);
-       g_free(title);  
+       g_free(title);
 
 }
 
@@ -1118,28 +1187,28 @@ static void dialog_graph_reset(user_data_t* user_data)
 
        /* create the color titles near the filter buttons */
        for(i=0;i<MAX_GRAPHS;i++){
-               /* it is forward */ 
+               /* it is forward */
                if (i<2){
-                               g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=%u)",
+                               g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=0x%X)",
                        graph_descr[i],
-                       address_to_str_w_none(&(user_data->ip_src_fwd)),
+                       get_addr_name(&(user_data->ip_src_fwd)),
                        user_data->port_src_fwd,
-                       address_to_str_w_none(&(user_data->ip_dst_fwd)),
+                       get_addr_name(&(user_data->ip_dst_fwd)),
                        user_data->port_dst_fwd,
                        user_data->ssrc_fwd);
                /* it is reverse */
                } else {
-                       g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=%u)",
+                       g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=0x%X)",
                        graph_descr[i],
-                       address_to_str_w_none(&(user_data->ip_src_rev)),
+                       get_addr_name(&(user_data->ip_src_rev)),
                        user_data->port_src_rev,
-                       address_to_str_w_none(&(user_data->ip_dst_rev)),
+                       get_addr_name(&(user_data->ip_dst_rev)),
                        user_data->port_dst_rev,
                        user_data->ssrc_rev);
                }
        }
 
-       dialog_graph_set_title(user_data);      
+       dialog_graph_set_title(user_data);
 }
 
 /****************************************************************************/
@@ -1183,7 +1252,7 @@ static void dialog_graph_draw(user_data_t* user_data)
 #else
         PangoLayout  *layout;
 #endif
-        guint32 label_width, label_height;
+        int label_width, label_height;
         guint32 draw_width, draw_height;
         char label_string[15];
 
@@ -1237,7 +1306,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                         }
                 }
         }
-       
+
         /*
          * Clear out old plot
          */
@@ -1516,7 +1585,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                 layout);
 #endif
 
-       /* Draw the marks */    
+       /* Draw the marks */
        for(i=MAX_GRAPHS-1;i>=0;i--){
                guint32 interval;
                guint32 x_pos, prev_x_pos;
@@ -1538,7 +1607,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                                } else {
                                        strcpy(label_string,"m");
                                }
-                                       
+
 #if GTK_MAJOR_VERSION < 2
                                 lwidth=gdk_string_width(font, label_string);
                                 gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
@@ -1547,7 +1616,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         x_pos-1-lwidth/2,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+7*(i/2)+label_height,
                                         label_string);
-#else                          
+#else
                                pango_layout_set_text(layout, label_string, -1);
                                 pango_layout_get_pixel_size(layout, &lwidth, NULL);
                                 gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1575,11 +1644,11 @@ static void dialog_graph_draw(user_data_t* user_data)
                guint32 x_pos, y_pos, prev_x_pos, prev_y_pos;
                if (!user_data->dlg.dialog_graph.graph[i].display){
                         continue;
-                }      
+                }
                /* initialize prev x/y to the low left corner of the graph */
                prev_x_pos=draw_width-1-user_data->dlg.dialog_graph.pixels_per_tick*((last_interval-first_interval)/user_data->dlg.dialog_graph.interval+1)+left_x_border;
                prev_y_pos=draw_height-1+top_y_border;
-               
+
                for(interval=first_interval+user_data->dlg.dialog_graph.interval;interval<=last_interval;interval+=user_data->dlg.dialog_graph.interval){
                        guint32 val;
                        x_pos=draw_width-1-user_data->dlg.dialog_graph.pixels_per_tick*((last_interval-interval)/user_data->dlg.dialog_graph.interval+1)+left_x_border;
@@ -1598,7 +1667,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                                 prev_x_pos=x_pos;
                                 continue;
                         }
-               
+
                         if(val){
                                gdk_draw_line(user_data->dlg.dialog_graph.pixmap, user_data->dlg.dialog_graph.graph[i].gc,
                                 x_pos, draw_height-1+top_y_border,
@@ -1638,7 +1707,7 @@ static void dialog_graph_draw(user_data_t* user_data)
 static void dialog_graph_redraw(user_data_t* user_data)
 {
         user_data->dlg.dialog_graph.needs_redraw=TRUE;
-        dialog_graph_draw(user_data); 
+        dialog_graph_draw(user_data);
 }
 
 /****************************************************************************/
@@ -1783,13 +1852,13 @@ static gint filter_callback(GtkWidget *widget _U_, dialog_graph_graph_t *dgg)
 {
         /* this graph is not active, just update display and redraw */
         if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dgg->display_button))){
-                disable_graph(dgg); 
+                disable_graph(dgg);
                 dialog_graph_redraw(dgg->ud);
                return 0;
         }
 
        enable_graph(dgg);
-        cf_retap_packets(&cfile);
+        cf_retap_packets(&cfile, FALSE);
         dialog_graph_redraw(dgg->ud);
 
         return 0;
@@ -1878,9 +1947,9 @@ static void yscale_select(GtkWidget *item, gpointer key)
 {
         int val;
        user_data_t *user_data;
-        
+
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "yscale_max");
+        val=(long)OBJECT_GET_DATA(item, "yscale_max");
 
         user_data->dlg.dialog_graph.max_y_units=val;
         dialog_graph_redraw(user_data);
@@ -1893,7 +1962,7 @@ static void pixels_per_tick_select(GtkWidget *item, gpointer key)
         user_data_t *user_data;
 
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "pixels_per_tick");
+        val=(long)OBJECT_GET_DATA(item, "pixels_per_tick");
         user_data->dlg.dialog_graph.pixels_per_tick=val;
         dialog_graph_redraw(user_data);
 }
@@ -1905,10 +1974,10 @@ static void tick_interval_select(GtkWidget *item, gpointer key)
         user_data_t *user_data;
 
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "tick_interval");
+        val=(long)OBJECT_GET_DATA(item, "tick_interval");
 
         user_data->dlg.dialog_graph.interval=val;
-        cf_retap_packets(&cfile);
+        cf_retap_packets(&cfile, FALSE);
         dialog_graph_redraw(user_data);
 }
 
@@ -1987,7 +2056,7 @@ static void create_tick_interval_menu_items(user_data_t* user_data, GtkWidget *m
 }
 
 /****************************************************************************/
-static void create_ctrl_menu(user_data_t* user_data, GtkWidget *box, char *name, void (*func)(user_data_t* user_data, GtkWidget *menu))
+static void create_ctrl_menu(user_data_t* user_data, GtkWidget *box, const char *name, void (*func)(user_data_t* user_data, GtkWidget *menu))
 {
         GtkWidget *hbox;
         GtkWidget *label;
@@ -2101,7 +2170,7 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
                 return;
         }
 
-       dialog_graph_init_window(user_data);    
+       dialog_graph_init_window(user_data);
 
 }
 
@@ -2124,75 +2193,15 @@ static void draw_stat(user_data_t *user_data);
 /* re-dissects all packets */
 static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
 {
-       gchar filter_text[256];
-       dfilter_t *sfcode;
        GString *error_string;
-       gchar ip_version[3];
-
-       /* try to compile the filter. */
-       strcpy(filter_text,"rtp && ip");
-       if (!dfilter_compile(filter_text, &sfcode)) {
-               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg);
-               return;
-       }
 
-       if (user_data->ip_src_fwd.type==AT_IPv6){
-               strcpy(ip_version,"v6");
-       }
-       else{
-               strcpy(ip_version,"");
-       }
-
-
-       if (user_data->ip_src_fwd.type!=AT_NONE){
-               if (user_data->ip_src_rev.type!=AT_NONE){
-                       g_snprintf(filter_text,sizeof(filter_text),
-                               "rtp && (( ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u ) || ( ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u ))",
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_src_fwd)),
-                               user_data->port_src_fwd,
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_dst_fwd)),
-                               user_data->port_dst_fwd,
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_src_rev)),
-                               user_data->port_src_rev,
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_dst_rev)),
-                               user_data->port_dst_rev
-                               );
-               }
-               else{
-                       g_snprintf(filter_text,sizeof(filter_text),
-                               "rtp && (ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u )",
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_src_fwd)),
-                               user_data->port_src_fwd,
-                               ip_version,
-                               address_to_str_w_none(&(user_data->ip_dst_fwd)),
-                               user_data->port_dst_fwd
-                               );
-                       }
-       }
-       else{
-               g_snprintf(filter_text,sizeof(filter_text),
-                       "rtp && ( ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u )",
-                       ip_version,
-                       address_to_str_w_none(&(user_data->ip_src_rev)),
-                       user_data->port_src_rev,
-                       ip_version,
-                       address_to_str_w_none(&(user_data->ip_dst_rev)),
-                       user_data->port_dst_rev
-                       );
-       }               
-       
        /* remove tap listener */
        protect_thread_critical_region();
        remove_tap_listener(user_data);
        unprotect_thread_critical_region();
 
        /* register tap listener */
-       error_string = register_tap_listener("rtp", user_data, filter_text,
+       error_string = register_tap_listener("rtp", user_data, NULL,
                rtp_reset, rtp_packet, rtp_draw);
        if (error_string != NULL) {
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
@@ -2201,7 +2210,7 @@ static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        }
 
        /* retap all packets */
-       cf_retap_packets(&cfile);
+       cf_retap_packets(&cfile, FALSE);
 
        /* draw statistics info */
        draw_stat(user_data);
@@ -2250,13 +2259,13 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
        gchar *g_dest;
        GtkWidget *rev, *forw, *both;
        user_data_t *user_data;
-       
+
        FILE *fp;
        char *columnText;
        int i,j;
-       
+
        g_dest = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
-       
+
        /* Perhaps the user specified a directory instead of a file.
        Check whether they did. */
        if (test_for_directory(g_dest) == EISDIR) {
@@ -2266,19 +2275,19 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                file_selection_set_current_folder(fs, get_last_open_dir());
                return;
        }
-       
+
        rev = (GtkWidget*)OBJECT_GET_DATA(bt, "reversed_rb");
        forw = (GtkWidget*)OBJECT_GET_DATA(bt, "forward_rb");
        both = (GtkWidget*)OBJECT_GET_DATA(bt, "both_rb");
        user_data = (user_data_t*)OBJECT_GET_DATA(bt, "user_data");
-       
+
        if (GTK_TOGGLE_BUTTON(forw)->active || GTK_TOGGLE_BUTTON(both)->active) {
-               fp = fopen(g_dest, "w");
+               fp = eth_fopen(g_dest, "w");
                if (fp == NULL) {
                        open_failure_alert_box(g_dest, errno, TRUE);
                        return;
                }
-               
+
                if (GTK_TOGGLE_BUTTON(both)->active) {
                        fprintf(fp, "Forward\n");
                        if (ferror(fp)) {
@@ -2287,7 +2296,7 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                                return;
                        }
                }
-               
+
                for(j = 0; j < NUM_COLS; j++) {
                        if (j == 0) {
                                fprintf(fp,"%s",titles[j]);
@@ -2317,17 +2326,17 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                                return;
                        }
                }
-               
+
                if (fclose(fp) == EOF) {
                        write_failure_alert_box(g_dest, errno);
                        return;
                }
        }
-       
+
        if (GTK_TOGGLE_BUTTON(rev)->active || GTK_TOGGLE_BUTTON(both)->active) {
-               
+
                if (GTK_TOGGLE_BUTTON(both)->active) {
-                       fp = fopen(g_dest, "a");
+                       fp = eth_fopen(g_dest, "a");
                        if (fp == NULL) {
                                open_failure_alert_box(g_dest, errno, TRUE);
                                return;
@@ -2339,7 +2348,7 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                                return;
                        }
                } else {
-                       fp = fopen(g_dest, "w");
+                       fp = eth_fopen(g_dest, "w");
                        if (fp == NULL) {
                                open_failure_alert_box(g_dest, errno, TRUE);
                                return;
@@ -2400,82 +2409,82 @@ static void save_csv_as_cb(GtkWidget *bt _U_, user_data_t *user_data _U_)
        GtkWidget *reversed_rb;
        GtkWidget *both_rb;
        GtkWidget *ok_bt;
-       
+
        if (user_data->dlg.save_csv_as_w != NULL) {
                /* There's already a Save CSV info dialog box; reactivate it. */
                reactivate_window(user_data->dlg.save_csv_as_w);
                return;
        }
-       
-       user_data->dlg.save_csv_as_w = gtk_file_selection_new("Ethereal: Save Data As CSV");
-       
+
+       user_data->dlg.save_csv_as_w = gtk_file_selection_new("Wireshark: Save Data As CSV");
+
        /* Container for each row of widgets */
        vertb = gtk_vbox_new(FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(vertb), 5);
        gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->action_area),
                vertb, FALSE, FALSE, 0);
        gtk_widget_show (vertb);
-       
+
        table1 = gtk_table_new (2, 4, FALSE);
        gtk_widget_show (table1);
        gtk_box_pack_start (GTK_BOX (vertb), table1, FALSE, FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (table1), 10);
        gtk_table_set_row_spacings (GTK_TABLE (table1), 20);
-       
+
        label_format = gtk_label_new ("Format: Comma Separated Values");
        gtk_widget_show (label_format);
        gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       
+
+
        channels_label = gtk_label_new ("Channels:");
        gtk_widget_show (channels_label);
        gtk_table_attach (GTK_TABLE (table1), channels_label, 0, 1, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
        gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5);
-       
+
        forward_rb = gtk_radio_button_new_with_label (channels_group, "forward  ");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (forward_rb));
        gtk_widget_show (forward_rb);
        gtk_table_attach (GTK_TABLE (table1), forward_rb, 1, 2, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (reversed_rb));
        gtk_widget_show (reversed_rb);
        gtk_table_attach (GTK_TABLE (table1), reversed_rb, 2, 3, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        both_rb = gtk_radio_button_new_with_label (channels_group, "both");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (both_rb));
        gtk_widget_show (both_rb);
        gtk_table_attach (GTK_TABLE (table1), both_rb, 3, 4, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_rb), TRUE);
-       
+
        ok_bt = GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->ok_button;
        OBJECT_SET_DATA(ok_bt, "forward_rb", forward_rb);
        OBJECT_SET_DATA(ok_bt, "reversed_rb", reversed_rb);
        OBJECT_SET_DATA(ok_bt, "both_rb", both_rb);
        OBJECT_SET_DATA(ok_bt, "user_data", user_data);
        SIGNAL_CONNECT(ok_bt, "clicked", save_csv_as_ok_cb,
-                       user_data->dlg.save_csv_as_w);
+               user_data->dlg.save_csv_as_w);
+
+       window_set_cancel_button(user_data->dlg.save_csv_as_w,
+               GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->cancel_button, window_cancel_button_cb);
 
-    window_set_cancel_button(user_data->dlg.save_csv_as_w, 
-        GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->cancel_button, NULL);
-       
-    SIGNAL_CONNECT(user_data->dlg.save_csv_as_w, "delete_event", window_delete_event_cb, NULL);
+       SIGNAL_CONNECT(user_data->dlg.save_csv_as_w, "delete_event", window_delete_event_cb, NULL);
        SIGNAL_CONNECT(user_data->dlg.save_csv_as_w, "destroy",
-                       save_csv_as_destroy_cb, user_data);
-    
+               save_csv_as_destroy_cb, user_data);
+
        gtk_widget_show(user_data->dlg.save_csv_as_w);
-    window_present(user_data->dlg.save_csv_as_w);
+       window_present(user_data->dlg.save_csv_as_w);
 }
 
 
@@ -2489,179 +2498,301 @@ static void save_voice_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data
 /****************************************************************************/
 /* here we save it into a file that user specified */
 /* XXX what about endians here? could go something wrong? */
-static gboolean copy_file(gchar *dest, gint channels, /*gint format,*/ user_data_t *user_data)
+static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *user_data)
 {
        int to_fd, forw_fd, rev_fd, fread = 0, rread = 0, fwritten, rwritten;
-       gint16 f_pd;
-       gint16 r_pd;
+       gchar f_pd[1] = {0};
+       gchar r_pd[1] = {0};
+       gint16 tmp;
        gchar pd[1];
        guint32 f_write_silence = 0;
        guint32 r_write_silence = 0;
        progdlg_t *progbar;
        guint32 progbar_count, progbar_quantum, progbar_nextstep = 0, count = 0;
        gboolean stop_flag = FALSE;
+       size_t nchars;
 
-       forw_fd = open(user_data->f_tempname, O_RDONLY | O_BINARY);
-       if (forw_fd < 0) 
+       forw_fd = eth_open(user_data->f_tempname, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
+       if (forw_fd < 0)
                return FALSE;
-       rev_fd = open(user_data->r_tempname, O_RDONLY | O_BINARY);
+       rev_fd = eth_open(user_data->r_tempname, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
        if (rev_fd < 0) {
-               close(forw_fd); 
+               eth_close(forw_fd);
                return FALSE;
        }
 
        /* open file for saving */
-       to_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+       to_fd = eth_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
        if (to_fd < 0) {
-               close(forw_fd);
-               close(rev_fd);
+               eth_close(forw_fd);
+               eth_close(rev_fd);
                return FALSE;
        }
 
-       progbar = create_progress_dlg("Saving voice in a file", dest, &stop_flag);
-
-       /* First we write the .au header. XXX Hope this is endian independant */
-       /* the magic word 0x2e736e64 == .snd */
-       *pd = (unsigned char)0x2e; write(to_fd, pd, 1);
-       *pd = (unsigned char)0x73; write(to_fd, pd, 1);
-       *pd = (unsigned char)0x6e; write(to_fd, pd, 1);
-       *pd = (unsigned char)0x64; write(to_fd, pd, 1);
-       /* header offset == 24 bytes */
-       *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       *pd = (unsigned char)0x18; write(to_fd, pd, 1);
-       /* total length, it is permited to set this to 0xffffffff */
-       *pd = (unsigned char)0xff; write(to_fd, pd, 1); 
-       write(to_fd, pd, 1); 
-       write(to_fd, pd, 1); 
-       write(to_fd, pd, 1);
-       /* encoding format == 8 bit ulaw */
-       *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       *pd = (unsigned char)0x01; write(to_fd, pd, 1);
-       /* sample rate == 8000 Hz */
-       *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       *pd = (unsigned char)0x1f; write(to_fd, pd, 1);
-       *pd = (unsigned char)0x40; write(to_fd, pd, 1);
-       /* channels == 1 */
-       *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       write(to_fd, pd, 1);
-       *pd = (unsigned char)0x01; write(to_fd, pd, 1);
-       
-       switch (channels) {
-               /* only forward direction */
-               case 1: {
-                       progbar_count = user_data->forward.saveinfo.count;
-                       progbar_quantum = user_data->forward.saveinfo.count/100;
-                       while ((fread = read(forw_fd, &f_pd, 2)) > 0) {
-                               if(stop_flag) 
-                                       break;
-                               if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                       update_progress_dlg(progbar, 
-                                               (gfloat) count/progbar_count, "Saving");
-                                       progbar_nextstep = progbar_nextstep + progbar_quantum;
+       progbar = create_progress_dlg("Saving voice in a file", dest, TRUE,
+           &stop_flag);
+
+       if      (format == SAVE_AU_FORMAT) /* au format */
+       {
+               /* First we write the .au header. XXX Hope this is endian independant */
+               /* the magic word 0x2e736e64 == .snd */
+               *pd = (unsigned char)0x2e; nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x73; nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x6e; nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x64; nchars=eth_write(to_fd, pd, 1);
+               /* header offset == 24 bytes */
+               *pd = (unsigned char)0x00; nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x18; nchars=eth_write(to_fd, pd, 1);
+               /* total length, it is permited to set this to 0xffffffff */
+               *pd = (unsigned char)0xff; nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               /* encoding format == 8 bit ulaw */
+               *pd = (unsigned char)0x00; nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x01; nchars=eth_write(to_fd, pd, 1);
+               /* sample rate == 8000 Hz */
+               *pd = (unsigned char)0x00; nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x1f; nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x40; nchars=eth_write(to_fd, pd, 1);
+               /* channels == 1 */
+               *pd = (unsigned char)0x00; nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               nchars=eth_write(to_fd, pd, 1);
+               *pd = (unsigned char)0x01; nchars=eth_write(to_fd, pd, 1);
+
+
+               switch (channels) {
+                       /* only forward direction */
+                       case SAVE_FORWARD_DIRECTION_MASK: {
+                               progbar_count = user_data->forward.saveinfo.count;
+                               progbar_quantum = user_data->forward.saveinfo.count/100;
+                               while ((fread = read(forw_fd, f_pd, 1)) > 0) {
+                                       if(stop_flag)
+                                               break;
+                                       if((count > progbar_nextstep) && (count <= progbar_count)) {
+                                               update_progress_dlg(progbar,
+                                                       (gfloat) count/progbar_count, "Saving");
+                                               progbar_nextstep = progbar_nextstep + progbar_quantum;
+                                       }
+                                       count++;
+
+                                       if (user_data->forward.statinfo.pt == PT_PCMU){
+                                               *pd = *f_pd;
+                                       }
+                                       else if(user_data->forward.statinfo.pt == PT_PCMA){
+                                               tmp = (gint16 )alaw2linear(*f_pd);
+                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                       }
+                                       else{
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
+
+                                       fwritten = eth_write(to_fd, pd, 1);
+                                       if ((fwritten < fread) || (fwritten < 0) || (fread < 0)) {
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
                                }
-                               count++;
-                               *pd = (unsigned char)linear2ulaw(f_pd);
-                               fwritten = write(to_fd, pd, 1);
-                               if ((fwritten*2 < fread) || (fwritten < 0) || (fread < 0)) {
-                                       close(forw_fd);
-                                       close(rev_fd);
-                                       close(to_fd);
-                                       destroy_progress_dlg(progbar);
-                                       return FALSE;
+                               break;
+                       }
+                       /* only reversed direction */
+                       case SAVE_REVERSE_DIRECTION_MASK: {
+                               progbar_count = user_data->reversed.saveinfo.count;
+                               progbar_quantum = user_data->reversed.saveinfo.count/100;
+                               while ((rread = read(rev_fd, r_pd, 1)) > 0) {
+                                       if(stop_flag)
+                                               break;
+                                       if((count > progbar_nextstep) && (count <= progbar_count)) {
+                                               update_progress_dlg(progbar,
+                                                       (gfloat) count/progbar_count, "Saving");
+                                               progbar_nextstep = progbar_nextstep + progbar_quantum;
+                                       }
+                                       count++;
+
+                                       if (user_data->forward.statinfo.pt == PT_PCMU){
+                                               *pd = *r_pd;
+                                       }
+                                       else if(user_data->forward.statinfo.pt == PT_PCMA){
+                                               tmp = (gint16 )alaw2linear(*r_pd);
+                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                       }
+                                       else{
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
+
+                                       rwritten = eth_write(to_fd, pd, 1);
+                                       if ((rwritten < rread) || (rwritten < 0) || (rread < 0)) {
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
                                }
+                               break;
                        }
-                       break;
-               }
-               /* only reversed direction */
-               case 2: {
-                       progbar_count = user_data->reversed.saveinfo.count;
-                       progbar_quantum = user_data->reversed.saveinfo.count/100;
-                       while ((rread = read(rev_fd, &r_pd, 2)) > 0) {
-                               if(stop_flag) 
-                                       break;
-                               if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                       update_progress_dlg(progbar, 
-                                               (gfloat) count/progbar_count, "Saving");
-                                       progbar_nextstep = progbar_nextstep + progbar_quantum;
+                       /* both directions */
+                       case SAVE_BOTH_DIRECTION_MASK: {
+                               (user_data->forward.saveinfo.count > user_data->reversed.saveinfo.count) ?
+                                               (progbar_count = user_data->forward.saveinfo.count) :
+                                                       (progbar_count = user_data->reversed.saveinfo.count);
+                               progbar_quantum = progbar_count/100;
+                               /* since conversation in one way can start later than in the other one,
+                                * we have to write some silence information for one channel */
+                               if (user_data->forward.statinfo.start_time > user_data->reversed.statinfo.start_time) {
+                                       f_write_silence = (guint32)
+                                               ((user_data->forward.statinfo.start_time-user_data->reversed.statinfo.start_time)*8000);
                                }
-                               count++;
-                               *pd = (unsigned char)linear2ulaw(r_pd);
-                               rwritten = write(to_fd, pd, 1);
-                               if ((rwritten*2 < rread) || (rwritten < 0) || (rread < 0)) {
-                                       close(forw_fd);
-                                       close(rev_fd);
-                                       close(to_fd);
-                                       destroy_progress_dlg(progbar);
-                                       return FALSE;
+                               else if (user_data->forward.statinfo.start_time < user_data->reversed.statinfo.start_time) {
+                                       r_write_silence = (guint32)
+                                               ((user_data->reversed.statinfo.start_time-user_data->forward.statinfo.start_time)*8000);
+                               }
+                               for(;;) {
+                                       if(stop_flag)
+                                               break;
+                                       if((count > progbar_nextstep) && (count <= progbar_count)) {
+                                               update_progress_dlg(progbar,
+                                                       (gfloat) count/progbar_count, "Saving");
+                                               progbar_nextstep = progbar_nextstep + progbar_quantum;
+                                       }
+                                       count++;
+                                       if(f_write_silence > 0) {
+                                               rread = read(rev_fd, r_pd, 1);
+                                               switch (user_data->forward.statinfo.reg_pt) {
+                                               case PT_PCMU:
+                                                       *f_pd = SILENCE_PCMU;
+                                                       break;
+                                               case PT_PCMA:
+                                                       *f_pd = SILENCE_PCMA;
+                                                       break;
+                                               }
+                                               fread = 1;
+                                               f_write_silence--;
+                                       }
+                                       else if(r_write_silence > 0) {
+                                               fread = read(forw_fd, f_pd, 1);
+                                               switch (user_data->forward.statinfo.reg_pt) {
+                                               case PT_PCMU:
+                                                       *r_pd = SILENCE_PCMU;
+                                                       break;
+                                               case PT_PCMA:
+                                                       *r_pd = SILENCE_PCMA;
+                                                       break;
+                                               }
+                                               rread = 1;
+                                               r_write_silence--;
+                                       }
+                                       else {
+                                               fread = read(forw_fd, f_pd, 1);
+                                               rread = read(rev_fd, r_pd, 1);
+                                       }
+                                       if ((rread == 0) && (fread == 0))
+                                               break;
+                                       if ((user_data->forward.statinfo.pt == PT_PCMU) && (user_data->reversed.statinfo.pt == PT_PCMU)){
+                                               tmp = ulaw2linear(*r_pd);
+                                               tmp += ulaw2linear(*f_pd);
+                                               *pd = (unsigned char)linear2ulaw(tmp/2);
+                                       }
+                                       else if((user_data->forward.statinfo.pt == PT_PCMA) && (user_data->reversed.statinfo.pt == PT_PCMA)){
+                                               tmp = alaw2linear(*r_pd);
+                                               tmp += alaw2linear(*f_pd);
+                                               *pd = (unsigned char)linear2ulaw(tmp/2);
+                                       }
+                                       else
+                                       {
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
+
+
+                                       rwritten = eth_write(to_fd, pd, 1);
+                                       if ((rwritten < 0) || (rread < 0) || (fread < 0)) {
+                                               eth_close(forw_fd);
+                                               eth_close(rev_fd);
+                                               eth_close(to_fd);
+                                               destroy_progress_dlg(progbar);
+                                               return FALSE;
+                                       }
                                }
                        }
-                       break;
                }
-               /* both directions */
-               default: {
-                       (user_data->forward.saveinfo.count > user_data->reversed.saveinfo.count) ? 
-                                       (progbar_count = user_data->forward.saveinfo.count) : 
-                                               (progbar_count = user_data->reversed.saveinfo.count);
-                       progbar_quantum = progbar_count/100;
-                       /* since conversation in one way can start later than in the other one, 
-                        * we have to write some silence information for one channel */
-                       if (user_data->forward.statinfo.start_time > user_data->reversed.statinfo.start_time) {
-                               f_write_silence = (guint32)
-                                       ((user_data->forward.statinfo.start_time-user_data->reversed.statinfo.start_time)*8000);
+       }
+       else if (format == SAVE_RAW_FORMAT)     /* raw format */
+       {
+               int fd;
+               switch (channels) {
+                       /* only forward direction */
+                       case SAVE_FORWARD_DIRECTION_MASK: {
+                               progbar_count = user_data->forward.saveinfo.count;
+                               progbar_quantum = user_data->forward.saveinfo.count/100;
+                               fd = forw_fd;
+                               break;
                        }
-                       else if (user_data->forward.statinfo.start_time < user_data->reversed.statinfo.start_time) {
-                               r_write_silence = (guint32)
-                                       ((user_data->reversed.statinfo.start_time-user_data->forward.statinfo.start_time)*8000);
+                       /* only reversed direction */
+                       case SAVE_REVERSE_DIRECTION_MASK: {
+                               progbar_count = user_data->reversed.saveinfo.count;
+                               progbar_quantum = user_data->reversed.saveinfo.count/100;
+                               fd = rev_fd;
+                               break;
                        }
-                       for(;;) {
-                               if(stop_flag) 
-                                       break;
-                               if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                       update_progress_dlg(progbar, 
-                                               (gfloat) count/progbar_count, "Saving");
-                                       progbar_nextstep = progbar_nextstep + progbar_quantum;
-                               }
-                               count++;
-                               if(f_write_silence > 0) {
-                                       rread = read(rev_fd, &r_pd, 2);
-                                       f_pd = 0;
-                                       fread = 1;
-                                       f_write_silence--;
-                               }
-                               else if(r_write_silence > 0) {
-                                       fread = read(forw_fd, &f_pd, 2);
-                                       r_pd = 0;
-                                       rread = 1;
-                                       r_write_silence--;
-                               }
-                               else {
-                                       fread = read(forw_fd, &f_pd, 2); 
-                                       rread = read(rev_fd, &r_pd, 2);
-                               }
-                               if ((rread == 0) && (fread == 0)) 
-                                       break;
-                               *pd = (unsigned char)linear2ulaw( (f_pd + r_pd)/2 );
-                               rwritten = write(to_fd, pd, 1);
-                               if ((rwritten < 0) || (rread < 0) || (fread < 0)) {
-                                       close(forw_fd);
-                                       close(rev_fd);
-                                       close(to_fd);
-                                       destroy_progress_dlg(progbar);
-                                       return FALSE;
-                               }
+                       default: {
+                               eth_close(forw_fd);
+                               eth_close(rev_fd);
+                               eth_close(to_fd);
+                               destroy_progress_dlg(progbar);
+                               return FALSE;
+                       }
+               }
+
+
+
+               /* XXX how do you just copy the file? */
+               while ((rread = read(fd, pd, 1)) > 0) {
+                       if(stop_flag)
+                               break;
+                       if((count > progbar_nextstep) && (count <= progbar_count)) {
+                               update_progress_dlg(progbar,
+                                       (gfloat) count/progbar_count, "Saving");
+                               progbar_nextstep = progbar_nextstep + progbar_quantum;
+                       }
+                       count++;
+
+                       rwritten = eth_write(to_fd, pd, 1);
+
+                       if ((rwritten < rread) || (rwritten < 0) || (rread < 0)) {
+                               eth_close(forw_fd);
+                               eth_close(rev_fd);
+                               eth_close(to_fd);
+                               destroy_progress_dlg(progbar);
+                               return FALSE;
                        }
                }
        }
+
        destroy_progress_dlg(progbar);
-       close(forw_fd);
-       close(rev_fd);
-       close(to_fd);
+       eth_close(forw_fd);
+       eth_close(rev_fd);
+       eth_close(to_fd);
        return TRUE;
 }
 
@@ -2672,13 +2803,14 @@ static gboolean copy_file(gchar *dest, gint channels, /*gint format,*/ user_data
 static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
 {
        gchar *g_dest;
-       /*GtkWidget *wav, *au, *sw;*/
+       /*GtkWidget *wav, *sw;*/
+       GtkWidget *au, *raw;
        GtkWidget *rev, *forw, *both;
        user_data_t *user_data;
-       gint channels /*, format*/;
-       
+       gint channels , format;
+
        g_dest = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
-       
+
        /* Perhaps the user specified a directory instead of a file.
        Check whether they did. */
        if (test_for_directory(g_dest) == EISDIR) {
@@ -2688,50 +2820,51 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                file_selection_set_current_folder(fs, get_last_open_dir());
                return;
        }
-       
+
        /*wav = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "wav_rb");
-       au = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "au_rb");
        sw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "sw_rb");*/
+       au = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "au_rb");
+       raw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "raw_rb");
        rev = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "reversed_rb");
        forw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "forward_rb");
        both = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "both_rb");
        user_data = (user_data_t *)OBJECT_GET_DATA(ok_bt, "user_data");
-       
+
        /* XXX user clicks the ok button, but we know we can't save the voice info because f.e.
        * we don't support that codec. So we pop up a warning. Maybe it would be better to
        * disable the ok button or disable the buttons for direction if only one is not ok. The
-       * problem is if we open the save voice dialog and then click the refresh button and maybe 
+       * problem is if we open the save voice dialog and then click the refresh button and maybe
        * the state changes, so we can't save anymore. In this case we should be able to update
        * the buttons. For now it is easier if we put the warning when the ok button is pressed.
        */
-       
-       /* we can not save in both dirctions */
+
+       /* we can not save in both directions */
        if ((user_data->forward.saveinfo.saved == FALSE) && (user_data->reversed.saveinfo.saved == FALSE) && (GTK_TOGGLE_BUTTON (both)->active)) {
                /* there are many combinations here, we just exit when first matches */
-               if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC) || 
+               if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_CODEC))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Unsupported codec!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_LENGTH) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_LENGTH) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_LENGTH))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Wrong length of captured packets!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_PADDING_ERROR) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_PADDING_ERROR) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_PADDING_ERROR))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: RTP data with padding!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_SHORT_FRAME) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_SHORT_FRAME) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_SHORT_FRAME))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Not all data in all packets was captured!");
-               else  
+               else
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: File I/O problem!");
                return;
        }
        /* we can not save forward direction */
        else if ((user_data->forward.saveinfo.saved == FALSE) && ((GTK_TOGGLE_BUTTON (forw)->active) ||
-               (GTK_TOGGLE_BUTTON (both)->active))) {  
+               (GTK_TOGGLE_BUTTON (both)->active))) {
                if (user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save forward direction in a file: Unsupported codec!");
@@ -2751,7 +2884,7 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
        }
        /* we can not save reversed direction */
        else if ((user_data->reversed.saveinfo.saved == FALSE) && ((GTK_TOGGLE_BUTTON (rev)->active) ||
-               (GTK_TOGGLE_BUTTON (both)->active))) {  
+               (GTK_TOGGLE_BUTTON (both)->active))) {
                if (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_CODEC)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save reversed direction in a file: Unsupported codec!");
@@ -2772,28 +2905,69 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                        "Can't save reversed direction in a file: File I/O problem!");
                return;
        }
-       
+
        /*if (GTK_TOGGLE_BUTTON (wav)->active)
-       format = 1;
-       else if (GTK_TOGGLE_BUTTON (au)->active)
-       format = 2;
-       else if (GTK_TOGGLE_BUTTON (sw)->active)
-       format = 3;*/
-       
+       format = SAVE_WAV_FORMAT;
+       else */if (GTK_TOGGLE_BUTTON (au)->active)
+       format = SAVE_AU_FORMAT;
+       /*else if (GTK_TOGGLE_BUTTON (sw)->active)
+       format = SAVE_SW_FORMAT;*/
+       else if (GTK_TOGGLE_BUTTON (raw)->active)
+       format = SAVE_RAW_FORMAT;
+       else
+       format = SAVE_NONE_FORMAT;
+
        if (GTK_TOGGLE_BUTTON (rev)->active)
-               channels = 2;
+               channels = SAVE_REVERSE_DIRECTION_MASK;
        else if (GTK_TOGGLE_BUTTON (both)->active)
-               channels = 3;
-       else 
-               channels = 1;
-       
-       if(!copy_file(g_dest, channels/*, format*/, user_data)) {
+               channels = SAVE_BOTH_DIRECTION_MASK;
+       else
+               channels = SAVE_FORWARD_DIRECTION_MASK;
+
+       /* direction/format validity*/
+       if (format == SAVE_AU_FORMAT)
+       {
+               /* make sure streams are alaw/ulaw */
+               if ((channels & SAVE_FORWARD_DIRECTION_MASK) && (user_data->forward.statinfo.pt != PT_PCMA) && (user_data->forward.statinfo.pt != PT_PCMU)){
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                               "Can't save in a file: saving in au format supported only for alaw/ulaw streams");
+                       return;
+               }
+               if ((channels & SAVE_REVERSE_DIRECTION_MASK) && (user_data->reversed.statinfo.pt != PT_PCMA) && (user_data->reversed.statinfo.pt != PT_PCMU)){
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                               "Can't save in a file: saving in au format supported only for alaw/ulaw streams");
+                       return;
+               }
+               /* make sure pt's don't differ */
+               if ((channels == SAVE_BOTH_DIRECTION_MASK) && (user_data->forward.statinfo.pt != user_data->reversed.statinfo.pt)){
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                               "Can't save in a file: Forward and reverse direction differ in type");
+                       return;
+               }
+       }
+       else if (format == SAVE_RAW_FORMAT)
+       {
+               /* can't save raw in both directions */
+               if (channels == SAVE_BOTH_DIRECTION_MASK){
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                               "Can't save in a file: Unable to save raw data in both directions");
+                       return;
+               }
+       }
+       else
+       {
+               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                       "Can't save in a file: Invalid save format");
+               return;
+       }
+
+       if(!copy_file(g_dest, channels, format, user_data)) {
                /* XXX - report the error type! */
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                       "An error occured while saving voice in a file!");
+                       "An error occurred while saving voice in a file!");
                return;
        }
-       
+
        window_destroy(GTK_WIDGET(user_data->dlg.save_voice_as_w));
 }
 
@@ -2806,54 +2980,79 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        GtkWidget *table1;
        GtkWidget *label_format;
        GtkWidget *channels_label;
-       /*GSList *format_group = NULL;*/
+       GSList *format_group = NULL;
        GSList *channels_group = NULL;
        GtkWidget *forward_rb;
        GtkWidget *reversed_rb;
        GtkWidget *both_rb;
-       /*GtkWidget *wav_rb; GtkWidget *au_rb; GtkWidget *sw_rb;*/
+       /*GtkWidget *wav_rb;  GtkWidget *sw_rb;*/
+       GtkWidget *au_rb;
+       GtkWidget *raw_rb;
        GtkWidget *ok_bt;
-       
+
        /* if we can't save in a file: wrong codec, cut packets or other errors */
-       /* shold the error arise here or later when you click ok button ? 
+       /* shold the error arise here or later when you click ok button ?
        * if we do it here, then we must disable the refresh button, so we don't do it here */
-       
+
        if (user_data->dlg.save_voice_as_w != NULL) {
                /* There's already a Save voice info dialog box; reactivate it. */
                reactivate_window(user_data->dlg.save_voice_as_w);
                return;
        }
-       
+
     /* XXX - use file_selection from dlg_utils instead! */
-       user_data->dlg.save_voice_as_w = gtk_file_selection_new("Ethereal: Save Payload As ...");
-       
+       user_data->dlg.save_voice_as_w = gtk_file_selection_new("Wireshark: Save Payload As ...");
+
        /* Container for each row of widgets */
        vertb = gtk_vbox_new(FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(vertb), 5);
        gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->action_area),
                vertb, FALSE, FALSE, 0);
        gtk_widget_show (vertb);
-       
+
        table1 = gtk_table_new (2, 4, FALSE);
        gtk_widget_show (table1);
        gtk_box_pack_start (GTK_BOX (vertb), table1, FALSE, FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (table1), 10);
        gtk_table_set_row_spacings (GTK_TABLE (table1), 20);
-       
-       label_format = gtk_label_new ("Format: .au (ulaw, 8 bit, 8000 Hz, mono) ");
+
+       /*label_format = gtk_label_new ("Format: .au (ulaw, 8 bit, 8000 Hz, mono) ");
+       gtk_widget_show (label_format);
+       gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
+               (GtkAttachOptions) (GTK_FILL),
+               (GtkAttachOptions) (0), 0, 0);*/
+
+       label_format = gtk_label_new ("Format: ");
        gtk_widget_show (label_format);
        gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       /* we support .au - ulaw*/ 
+
+       gtk_misc_set_alignment (GTK_MISC (label_format), 0, 0.5);
+
+       raw_rb = gtk_radio_button_new_with_label (format_group, ".raw");
+       format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (raw_rb));
+       gtk_widget_show (raw_rb);
+       gtk_table_attach (GTK_TABLE (table1), raw_rb, 1, 2, 0, 1,
+       (GtkAttachOptions) (GTK_FILL),
+       (GtkAttachOptions) (0), 0, 0);
+
+
+       au_rb = gtk_radio_button_new_with_label (format_group, ".au");
+       format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (au_rb));
+       gtk_widget_show (au_rb);
+       gtk_table_attach (GTK_TABLE (table1), au_rb, 3, 4, 0, 1,
+       (GtkAttachOptions) (GTK_FILL),
+       (GtkAttachOptions) (0), 0, 0);
+
+       /* we support .au - ulaw*/
        /*      wav_rb = gtk_radio_button_new_with_label (format_group, ".wav");
        format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (wav_rb));
        gtk_widget_show (wav_rb);
        gtk_table_attach (GTK_TABLE (table1), wav_rb, 1, 2, 0, 1,
        (GtkAttachOptions) (GTK_FILL),
        (GtkAttachOptions) (0), 0, 0);
-       
+
          sw_rb = gtk_radio_button_new_with_label (format_group, "8 kHz, 16 bit  ");
          format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (sw_rb));
          gtk_widget_show (sw_rb);
@@ -2866,39 +3065,40 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
          gtk_table_attach (GTK_TABLE (table1), au_rb, 3, 4, 0, 1,
          (GtkAttachOptions) (GTK_FILL),
          (GtkAttachOptions) (0), 0, 0);
-       */ 
-       
+       */
+
+
        channels_label = gtk_label_new ("Channels:");
        gtk_widget_show (channels_label);
        gtk_table_attach (GTK_TABLE (table1), channels_label, 0, 1, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
        gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5);
-       
+
        forward_rb = gtk_radio_button_new_with_label (channels_group, "forward  ");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (forward_rb));
        gtk_widget_show (forward_rb);
        gtk_table_attach (GTK_TABLE (table1), forward_rb, 1, 2, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (reversed_rb));
        gtk_widget_show (reversed_rb);
        gtk_table_attach (GTK_TABLE (table1), reversed_rb, 2, 3, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        both_rb = gtk_radio_button_new_with_label (channels_group, "both");
        channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (both_rb));
        gtk_widget_show (both_rb);
        gtk_table_attach (GTK_TABLE (table1), both_rb, 3, 4, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_rb), TRUE);
-       
-       /* if one direction is nok we don't allow saving 
+
+       /* if one direction is nok we don't allow saving
        XXX this is not ok since the user can click the refresh button and cause changes
        but we can not update this window. So we move all the decision on the time the ok
        button is clicked
@@ -2912,11 +3112,12 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        gtk_widget_set_sensitive(both_rb, FALSE);
        }
        */
-       
+
        ok_bt = GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->ok_button;
-       /*OBJECT_SET_DATA(ok_bt, "wav_rb", wav_rb);
+       /*OBJECT_SET_DATA(ok_bt, "wav_rb", wav_rb);*/
        OBJECT_SET_DATA(ok_bt, "au_rb", au_rb);
-       OBJECT_SET_DATA(ok_bt, "sw_rb", sw_rb);*/
+       /*OBJECT_SET_DATA(ok_bt, "sw_rb", sw_rb);*/
+       OBJECT_SET_DATA(ok_bt, "raw_rb", raw_rb);
        OBJECT_SET_DATA(ok_bt, "forward_rb", forward_rb);
        OBJECT_SET_DATA(ok_bt, "reversed_rb", reversed_rb);
        OBJECT_SET_DATA(ok_bt, "both_rb", both_rb);
@@ -2924,10 +3125,10 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        SIGNAL_CONNECT(ok_bt, "clicked", save_voice_as_ok_cb,
                        user_data->dlg.save_voice_as_w);
 
-    window_set_cancel_button(user_data->dlg.save_voice_as_w, 
+    window_set_cancel_button(user_data->dlg.save_voice_as_w,
       GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->cancel_button, window_cancel_button_cb);
 
-    SIGNAL_CONNECT(user_data->dlg.save_voice_as_w, "delete_event", 
+    SIGNAL_CONNECT(user_data->dlg.save_voice_as_w, "delete_event",
                         window_delete_event_cb, NULL);
        SIGNAL_CONNECT(user_data->dlg.save_voice_as_w, "destroy",
                         save_voice_as_destroy_cb, user_data);
@@ -2958,8 +3159,8 @@ static void draw_stat(user_data_t *user_data)
                 r_perc = (double)(r_lost*100)/(double)r_expected;
         } else {
                 r_perc = 0;
-        } 
-               
+        }
+
        g_snprintf(label_max, 199, "Max delta = %f sec at packet no. %u \n"
                "Total RTP packets = %u   (expected %u)   Lost RTP packets = %d (%.2f%%)"
                "   Sequence errors = %u",
@@ -2992,6 +3193,7 @@ static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
        guint added_row;
        gchar *data[9];
        gchar field[9][32];
+       char *savelocale;
 
        data[0]=&field[0][0];
        data[1]=&field[1][0];
@@ -3003,6 +3205,11 @@ static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
        data[7]=&field[7][0];
        data[8]=&field[8][0];
 
+       /* save the current locale */
+       savelocale = setlocale(LC_NUMERIC, NULL);
+       /* switch to "C" locale to avoid problems with localized decimal separators
+               in g_snprintf("%f") functions */
+       setlocale(LC_NUMERIC, "C");
        g_snprintf(field[0], 20, "%u", number);
        g_snprintf(field[1], 20, "%u", seq_num);
        g_snprintf(field[2], 20, "%.2f", delta);
@@ -3012,6 +3219,9 @@ static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
        g_snprintf(field[6], 40, "%s", status);
        g_snprintf(field[7], 32, "%s", timeStr);
        g_snprintf(field[8], 20, "%u", pkt_len);
+       /* restore previous locale setting */
+       setlocale(LC_NUMERIC, savelocale);
+
        added_row = gtk_clist_append(GTK_CLIST(clist), data);
        gtk_clist_set_row_data(GTK_CLIST(clist), added_row, GUINT_TO_POINTER(number));
        gtk_clist_set_background(GTK_CLIST(clist), added_row, color);
@@ -3185,7 +3395,7 @@ column_arrows* add_sort_by_column(GtkWidget* window, GtkWidget* clist,
 
 /****************************************************************************/
 /* Create the dialog box with all widgets */
-void create_rtp_dialog(user_data_t* user_data)
+static void create_rtp_dialog(user_data_t* user_data)
 {
        GtkWidget *window = NULL;
        GtkWidget *clist_fwd;
@@ -3209,8 +3419,8 @@ void create_rtp_dialog(user_data_t* user_data)
        gchar str_ip_dst[16];
        column_arrows *col_arrows_fwd;
        column_arrows *col_arrows_rev;
-       
-       window = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: RTP Stream Analysis");
+
+       window = window_new(GTK_WINDOW_TOPLEVEL, "Wireshark: RTP Stream Analysis");
        gtk_window_set_default_size(GTK_WINDOW(window), 700, 400);
 
        /* Container for each row of widgets */
@@ -3220,19 +3430,19 @@ void create_rtp_dialog(user_data_t* user_data)
        gtk_widget_show(main_vb);
 
        /* Notebooks... */
-       strcpy(str_ip_src, address_to_str_w_none(&(user_data->ip_src_fwd)));
-       strcpy(str_ip_dst, address_to_str_w_none(&(user_data->ip_dst_fwd)));
+       strcpy(str_ip_src, get_addr_name(&(user_data->ip_src_fwd)));
+       strcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_fwd)));
 
-       g_snprintf(label_forward, 149, 
-               "Analysing stream from  %s port %u  to  %s port %u   SSRC = %u", 
+       g_snprintf(label_forward, 149,
+               "Analysing stream from  %s port %u  to  %s port %u   SSRC = 0x%X",
                str_ip_src, user_data->port_src_fwd, str_ip_dst, user_data->port_dst_fwd, user_data->ssrc_fwd);
 
 
-       strcpy(str_ip_src, address_to_str_w_none(&(user_data->ip_src_rev)));
-       strcpy(str_ip_dst, address_to_str_w_none(&(user_data->ip_dst_rev)));
+       strcpy(str_ip_src, get_addr_name(&(user_data->ip_src_rev)));
+       strcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_rev)));
 
        g_snprintf(label_reverse, 149,
-               "Analysing stream from  %s port %u  to  %s port %u   SSRC = %u", 
+               "Analysing stream from  %s port %u  to  %s port %u   SSRC = 0x%X",
                str_ip_src, user_data->port_src_rev, str_ip_dst, user_data->port_dst_rev, user_data->ssrc_rev);
 
        /* Start a notebook for flipping between sets of changes */
@@ -3335,7 +3545,7 @@ void create_rtp_dialog(user_data_t* user_data)
         graph_bt = gtk_button_new_with_label("Graph");
        gtk_container_add(GTK_CONTAINER(box4), graph_bt);
        gtk_widget_show(graph_bt);
-       SIGNAL_CONNECT(graph_bt, "clicked", on_graph_bt_clicked, user_data);    
+       SIGNAL_CONNECT(graph_bt, "clicked", on_graph_bt_clicked, user_data);
 
 
 #ifdef USE_CONVERSATION_GRAPH
@@ -3382,7 +3592,7 @@ void create_rtp_dialog(user_data_t* user_data)
 
 /****************************************************************************/
 static gboolean process_node(proto_node *ptree_node, header_field_info *hfinformation,
-                                                       gchar* proto_field, guint32* p_result)
+                                                       const gchar* proto_field, guint32* p_result)
 {
        field_info            *finfo;
        proto_node            *proto_sibling_node;
@@ -3395,7 +3605,7 @@ static gboolean process_node(proto_node *ptree_node, header_field_info *hfinform
                hfssrc = proto_registrar_get_byname(proto_field);
                if (hfssrc == NULL)
                        return FALSE;
-               for(ptree_node=ptree_node->first_child; ptree_node!=NULL; 
+               for(ptree_node=ptree_node->first_child; ptree_node!=NULL;
                                        ptree_node=ptree_node->next) {
                        finfo=PITEM_FINFO(ptree_node);
                        if (hfssrc==finfo->hfinfo) {
@@ -3404,11 +3614,13 @@ static gboolean process_node(proto_node *ptree_node, header_field_info *hfinform
                                        *p_result = ipv4_get_net_order_addr(ipv4);
                                }
                                else {
-                                       *p_result = fvalue_get_integer(&finfo->value);
+                                       *p_result = fvalue_get_uinteger(&finfo->value);
                                }
                                return TRUE;
                        }
                }
+               if(!ptree_node)
+                       return FALSE;
        }
 
        proto_sibling_node = ptree_node->next;
@@ -3422,9 +3634,9 @@ static gboolean process_node(proto_node *ptree_node, header_field_info *hfinform
 
 /****************************************************************************/
 static gboolean get_int_value_from_proto_tree(proto_tree *protocol_tree,
-                                                                                        gchar* proto_name,
-                                                                                        gchar* proto_field,
-                                                                                        guint32* p_result)
+                                                const gchar* proto_name,
+                                                const gchar* proto_field,
+                                                guint32* p_result)
 {
        proto_node      *ptree_node;
        header_field_info     *hfinformation;
@@ -3446,7 +3658,6 @@ void protect_thread_critical_region(void);
 void unprotect_thread_critical_region(void);
 
 /****************************************************************************/
-/* XXX only handles RTP over IPv4, should add IPv6 support */
 void rtp_analysis(
                address *ip_src_fwd,
                guint16 port_src_fwd,
@@ -3489,10 +3700,10 @@ void rtp_analysis(
        /*XXX: check for errors*/
        fd = create_tempfile(user_data->f_tempname, sizeof(user_data->f_tempname),
                "ether_rtp_f");
-       close(fd);
+       eth_close(fd);
        fd = create_tempfile(user_data->r_tempname, sizeof(user_data->r_tempname),
                "ether_rtp_r");
-       close(fd);
+       eth_close(fd);
        user_data->forward.saveinfo.fp = NULL;
        user_data->reversed.saveinfo.fp = NULL;
        user_data->dlg.save_voice_as_w = NULL;
@@ -3541,7 +3752,7 @@ void rtp_analysis(
 
 /****************************************************************************/
 /* entry point from main menu */
-void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_) 
+static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
 {
        address ip_src_fwd;
        guint16 port_src_fwd;
@@ -3569,7 +3780,7 @@ void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
        guint nfound;
 
        /* Try to compile the filter. */
-       strcpy(filter_text,"rtp && (ip || ipv6)");
+       strcpy(filter_text,"rtp && rtp.version && rtp.ssrc && (ip || ipv6)");
        if (!dfilter_compile(filter_text, &sfcode)) {
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg);
                return;
@@ -3577,7 +3788,7 @@ void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
        /* we load the current file into cf variable */
        cf = &cfile;
        fdata = cf->current_frame;
-       
+
        /* we are on the selected frame now */
        if (fdata == NULL)
                return; /* if we exit here it's an error */
@@ -3591,9 +3802,9 @@ void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
        }
        edt = epan_dissect_new(TRUE, FALSE);
        epan_dissect_prime_dfilter(edt, sfcode);
-       epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
+       epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
        frame_matched = dfilter_apply_edt(sfcode, edt);
-       
+
        /* if it is not an rtp frame, show the rtpstream dialog */
        frame_matched = dfilter_apply_edt(sfcode, edt);
        if (frame_matched != 1) {
@@ -3621,7 +3832,7 @@ void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
                     "RTP Version != 2 isn't supported!");
                 return;
         }
-       
+
        /* now we need the SSRC value of the current frame */
        if (!get_int_value_from_proto_tree(edt->tree, "rtp", "rtp.ssrc", &ssrc_fwd)) {
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -3682,7 +3893,7 @@ void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
 
 /****************************************************************************/
 static void
-rtp_analysis_init(char *dummy _U_)
+rtp_analysis_init(const char *dummy _U_,void* userdata _U_)
 {
        rtp_analysis_cb(NULL, NULL);
 }
@@ -3691,8 +3902,8 @@ rtp_analysis_init(char *dummy _U_)
 void
 register_tap_listener_rtp_analysis(void)
 {
-       register_ethereal_tap("rtp", rtp_analysis_init);
+       register_stat_cmd_arg("rtp", rtp_analysis_init,NULL);
 
-       register_tap_menu_item("RTP/Stream Analysis...", REGISTER_TAP_GROUP_NONE,
+       register_stat_menu_item("RTP/Stream Analysis...", REGISTER_STAT_GROUP_TELEPHONY,
            rtp_analysis_cb, NULL, NULL, NULL);
 }