Remove Makefile.common files
[metze/wireshark/wip.git] / wiretap / wtap.c
index 6ce8f38dda574b8fb8e1a464608a16d5ea7b88f8..0d1acc3657ea117926979fec374b8f96e224337a 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
 #endif
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
 #include "wtap-int.h"
+#include "wtap_opttypes.h"
+#include "pcapng.h"
 
 #include "file_wrappers.h"
 #include <wsutil/file_util.h>
@@ -61,7 +55,6 @@ static gboolean
 check_for_wtap_plugin(GModule *handle)
 {
        gpointer gp;
-       void (*register_wtap_module)(void);
        wtap_plugin *plugin;
 
        /*
@@ -74,14 +67,12 @@ check_for_wtap_plugin(GModule *handle)
 
        /*
         * Yes - this plugin includes one or more wiretap modules.
-        */
-       register_wtap_module = (void (*)(void))gp;
-
-       /*
         * Add this one to the list of wiretap module plugins.
         */
        plugin = (wtap_plugin *)g_malloc(sizeof (wtap_plugin));
-       plugin->register_wtap_module = register_wtap_module;
+DIAG_OFF(pedantic)
+       plugin->register_wtap_module = (void (*)(void))gp;
+DIAG_ON(pedantic)
        wtap_plugins = g_slist_append(wtap_plugins, plugin);
        return TRUE;
 }
@@ -89,6 +80,9 @@ check_for_wtap_plugin(GModule *handle)
 void
 wtap_register_plugin_types(void)
 {
+       /* Piggyback the initialization here for now */
+       wtap_opttypes_initialize();
+
        add_plugin_type("libwiretap", check_for_wtap_plugin);
 }
 
@@ -167,31 +161,85 @@ wtap_file_tsprec(wtap *wth)
        return wth->file_tsprec;
 }
 
-wtapng_section_t *
-wtap_file_get_shb_info(wtap *wth)
+const gchar *
+wtap_file_get_shb_comment(wtap *wth)
+{
+       char* opt_comment;
+       if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0))
+               return NULL;
+
+       wtap_optionblock_get_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, &opt_comment);
+       return opt_comment;
+}
+
+wtap_optionblock_t
+wtap_file_get_shb(wtap *wth)
+{
+       if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0))
+               return NULL;
+
+       return g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0);
+}
+
+GArray*
+wtap_file_get_shb_for_new_file(wtap *wth)
 {
-       wtapng_section_t                *shb_hdr;
+       guint shb_count;
+       wtap_optionblock_t shb_hdr_src, shb_hdr_dest;
+       GArray* shb_hdrs;
 
-       if(wth == NULL)
+       if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0))
                return NULL;
-       shb_hdr = g_new(wtapng_section_t,1);
-       shb_hdr->section_length = wth->shb_hdr.section_length;
-       /* options */
-       shb_hdr->opt_comment   =        wth->shb_hdr.opt_comment;       /* NULL if not available */
-       shb_hdr->shb_hardware  =        wth->shb_hdr.shb_hardware;      /* NULL if not available, UTF-8 string containing the description of the hardware used to create this section. */
-       shb_hdr->shb_os        =        wth->shb_hdr.shb_os;            /* NULL if not available, UTF-8 string containing the name of the operating system used to create this section. */
-       shb_hdr->shb_user_appl =        wth->shb_hdr.shb_user_appl;     /* NULL if not available, UTF-8 string containing the name of the application used to create this section. */
 
+       shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
-       return shb_hdr;
+       for (shb_count = 0; shb_count < wth->shb_hdrs->len; shb_count++) {
+               shb_hdr_src = g_array_index(wth->shb_hdrs, wtap_optionblock_t, shb_count);
+               shb_hdr_dest = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
+               wtap_optionblock_copy_options(shb_hdr_dest, shb_hdr_src);
+               g_array_append_val(shb_hdrs, shb_hdr_dest);
+       }
+
+       return shb_hdrs;
+}
+
+const gchar*
+wtap_get_nrb_comment(wtap *wth)
+{
+       char* opt_comment;
+       g_assert(wth);
+
+       if ((wth == NULL) || (wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0))
+               return NULL;
+
+       wtap_optionblock_get_option_string(g_array_index(wth->nrb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, &opt_comment);
+       return opt_comment;
 }
 
 void
-wtap_write_shb_comment(wtap *wth, gchar *comment)
+wtap_write_nrb_comment(wtap *wth, gchar *comment)
 {
-       g_free(wth->shb_hdr.opt_comment);
-       wth->shb_hdr.opt_comment = comment;
+       wtap_optionblock_t nrb;
+       g_assert(wth);
+
+       if (wth == NULL)
+               return;
+
+       if (wth->nrb_hdrs == NULL) {
+               wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
+               nrb = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
+               g_array_append_val(wth->nrb_hdrs, nrb);
+       }
 
+       wtap_optionblock_set_option_string(g_array_index(wth->nrb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, (gsize)(comment ? strlen(comment) : 0));
+}
+
+void
+wtap_write_shb_comment(wtap *wth, gchar *comment)
+{
+       if ((wth != NULL) && (wth->shb_hdrs != NULL) && (wth->shb_hdrs->len > 0)) {
+               wtap_optionblock_set_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, (gsize)(comment ? strlen(comment) : 0));
+       }
 }
 
 wtapng_iface_descriptions_t *
@@ -206,6 +254,140 @@ wtap_file_get_idb_info(wtap *wth)
        return idb_info;
 }
 
+
+void
+wtap_free_idb_info(wtapng_iface_descriptions_t *idb_info)
+{
+       if (idb_info == NULL)
+               return;
+
+       wtap_optionblock_array_free(idb_info->interface_data);
+       g_free(idb_info);
+}
+
+gchar *
+wtap_get_debug_if_descr(const wtap_optionblock_t if_descr,
+                        const int indent,
+                        const char* line_end)
+{
+       char* tmp_content;
+       wtapng_if_descr_mandatory_t* if_descr_mand;
+       GString *info = g_string_new("");
+       guint64 tmp64;
+       gint8 itmp8;
+       guint8 tmp8;
+       wtapng_if_descr_filter_t* if_filter;
+
+       g_assert(if_descr);
+
+       if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(if_descr);
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_NAME, &tmp_content);
+       g_string_printf(info,
+                       "%*cName = %s%s", indent, ' ',
+                       tmp_content ? tmp_content : "UNKNOWN",
+                       line_end);
+
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_DESCR, &tmp_content);
+       g_string_append_printf(info,
+                       "%*cDescription = %s%s", indent, ' ',
+                       tmp_content ? tmp_content : "NONE",
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cEncapsulation = %s (%d/%u - %s)%s", indent, ' ',
+                       wtap_encap_string(if_descr_mand->wtap_encap),
+                       if_descr_mand->wtap_encap,
+                       if_descr_mand->link_type,
+                       wtap_encap_short_string(if_descr_mand->wtap_encap),
+                       line_end);
+
+       wtap_optionblock_get_option_uint64(if_descr, OPT_IDB_SPEED, &tmp64);
+       g_string_append_printf(info,
+                       "%*cSpeed = %" G_GINT64_MODIFIER "u%s", indent, ' ',
+                       tmp64,
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cCapture length = %u%s", indent, ' ',
+                       if_descr_mand->snap_len,
+                       line_end);
+
+       wtap_optionblock_get_option_uint8(if_descr, OPT_IDB_FCSLEN, &itmp8);
+       g_string_append_printf(info,
+                       "%*cFCS length = %d%s", indent, ' ',
+                       itmp8,
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cTime precision = %s (%d)%s", indent, ' ',
+                       wtap_tsprec_string(if_descr_mand->tsprecision),
+                       if_descr_mand->tsprecision,
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cTime ticks per second = %" G_GINT64_MODIFIER "u%s", indent, ' ',
+                       if_descr_mand->time_units_per_second,
+                       line_end);
+
+       wtap_optionblock_get_option_uint8(if_descr, OPT_IDB_TSRESOL, &tmp8);
+       g_string_append_printf(info,
+                       "%*cTime resolution = 0x%.2x%s", indent, ' ',
+                       tmp8,
+                       line_end);
+
+       wtap_optionblock_get_option_custom(if_descr, OPT_IDB_FILTER, (void**)&if_filter);
+       g_string_append_printf(info,
+                       "%*cFilter string = %s%s", indent, ' ',
+                       if_filter->if_filter_str ? if_filter->if_filter_str : "NONE",
+                       line_end);
+
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_OS, &tmp_content);
+       g_string_append_printf(info,
+                       "%*cOperating system = %s%s", indent, ' ',
+                       tmp_content ? tmp_content : "UNKNOWN",
+                       line_end);
+
+       wtap_optionblock_get_option_string(if_descr, OPT_COMMENT, &tmp_content);
+       g_string_append_printf(info,
+                       "%*cComment = %s%s", indent, ' ',
+                       tmp_content ? tmp_content : "NONE",
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cBPF filter length = %u%s", indent, ' ',
+                       if_filter->bpf_filter_len,
+                       line_end);
+
+       g_string_append_printf(info,
+                       "%*cNumber of stat entries = %u%s", indent, ' ',
+                       if_descr_mand->num_stat_entries,
+                       line_end);
+
+       return g_string_free(info, FALSE);
+}
+
+GArray*
+wtap_file_get_nrb_for_new_file(wtap *wth)
+{
+       guint nrb_count;
+       wtap_optionblock_t nrb_hdr_src, nrb_hdr_dest;
+       GArray* nrb_hdrs;
+
+       if ((wth == NULL || wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0))
+               return NULL;
+
+       nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
+
+       for (nrb_count = 0; nrb_count < wth->nrb_hdrs->len; nrb_count++) {
+               nrb_hdr_src = g_array_index(wth->nrb_hdrs, wtap_optionblock_t, nrb_count);
+               nrb_hdr_dest = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
+               wtap_optionblock_copy_options(nrb_hdr_dest, nrb_hdr_src);
+               g_array_append_val(nrb_hdrs, nrb_hdr_dest);
+       }
+
+       return nrb_hdrs;
+}
+
 /* Table of the encapsulation types we know about. */
 struct encap_type_info {
        const char *name;
@@ -259,7 +441,7 @@ static struct encap_type_info encap_table_base[] = {
        { "ATM PDUs - untruncated", "atm-pdus-untruncated" },
 
        /* WTAP_ENCAP_NULL */
-       { "NULL", "null" },
+       { "NULL/Loopback", "null" },
 
        /* WTAP_ENCAP_ASCEND */
        { "Lucent/Ascend access equipment", "ascend" },
@@ -648,9 +830,6 @@ static struct encap_type_info encap_table_base[] = {
        /* WTAP_ENCAP_IXVERIWAVE */
        { "IxVeriWave header and stats block", "ixveriwave" },
 
-       /* WTAP_ENCAP_IEEE_802_11_AIROPEEK */
-       { "IEEE 802.11 plus AiroPeek radio header", "ieee-802-11-airopeek" },
-
        /* WTAP_ENCAP_SDH */
        { "SDH", "sdh" },
 
@@ -737,6 +916,30 @@ static struct encap_type_info encap_table_base[] = {
 
        /* WTAP_ENCAP_IPMI_TRACE */
        { "IPMI Trace Data Collection", "ipmi-trace" },
+
+       /* WTAP_ENCAP_LOOP */
+       { "OpenBSD loopback", "loop" },
+
+       /* WTAP_ENCAP_JSON */
+       { "JavaScript Object Notation", "json" },
+
+       /* WTAP_ENCAP_NSTRACE_3_5 */
+       { "NetScaler Encapsulation 3.5 of Ethernet", "nstrace35" },
+
+       /* WTAP_ENCAP_ISO14443 */
+       { "ISO 14443 contactless smartcard standards", "iso14443" },
+
+       /* WTAP_ENCAP_GFP_T */
+       { "ITU-T G.7041/Y.1303 Generic Framing Procedure Transparent mode", "gfp-t" },
+
+       /* WTAP_ENCAP_GFP_F */
+       { "ITU-T G.7041/Y.1303 Generic Framing Procedure Frame-mapped mode", "gfp-f" },
+
+       /* WTAP_ENCAP_IP_OVER_IB_PCAP */
+       { "IP over IB", "ip-ib" },
+
+       /* WTAP_ENCAP_JUNIPER_VN */
+       { "Juniper VN", "juniper-vn" },
 };
 
 WS_DLL_LOCAL
@@ -812,6 +1015,40 @@ wtap_short_string_to_encap(const char *short_name)
        return -1;      /* no such encapsulation type */
 }
 
+const char*
+wtap_tsprec_string(int tsprec)
+{
+       const char* s;
+       switch (tsprec) {
+               case WTAP_TSPREC_PER_PACKET:
+                       s = "per-packet";
+                       break;
+               case WTAP_TSPREC_SEC:
+                       s = "seconds";
+                       break;
+               case WTAP_TSPREC_DSEC:
+                       s = "deciseconds";
+                       break;
+               case WTAP_TSPREC_CSEC:
+                       s = "centiseconds";
+                       break;
+               case WTAP_TSPREC_MSEC:
+                       s = "milliseconds";
+                       break;
+               case WTAP_TSPREC_USEC:
+                       s = "microseconds";
+                       break;
+               case WTAP_TSPREC_NSEC:
+                       s = "nanoseconds";
+                       break;
+               case WTAP_TSPREC_UNKNOWN:
+               default:
+                       s = "UNKNOWN";
+                       break;
+       }
+       return s;
+}
+
 static const char *wtap_errlist[] = {
        /* WTAP_ERR_NOT_REGULAR_FILE */
        "The file isn't a plain file or pipe",
@@ -831,11 +1068,11 @@ static const char *wtap_errlist[] = {
        /* WTAP_ERR_CANT_OPEN */
        NULL,
 
-       /* WTAP_ERR_UNSUPPORTED_FILE_TYPE */
+       /* WTAP_ERR_UNWRITABLE_FILE_TYPE */
        "Files can't be saved in that format",
 
        /* WTAP_ERR_UNWRITABLE_ENCAP */
-       "Files from that network type can't be saved in that format",
+       "Packets with that network type can't be saved in that format",
 
        /* WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED */
        "That file format doesn't support per-packet encapsulations",
@@ -882,8 +1119,11 @@ static const char *wtap_errlist[] = {
        /* WTAP_ERR_CHECK_WSLUA */
        NULL,
 
-       /* WTAP_ERR_REC_TYPE_UNSUPPORTED */
-       "That record type cannot be written in that format"
+       /* WTAP_ERR_UNWRITABLE_REC_TYPE */
+       "That record type cannot be written in that format",
+
+       /* WTAP_ERR_UNWRITABLE_REC_DATA */
+       "That record can't be written in that format"
 };
 #define        WTAP_ERRLIST_SIZE       (sizeof wtap_errlist / sizeof wtap_errlist[0])
 
@@ -956,10 +1196,6 @@ wtap_fdclose(wtap *wth)
 void
 wtap_close(wtap *wth)
 {
-       guint i, j;
-       wtapng_if_descr_t *wtapng_if_descr;
-       wtapng_if_stats_t *if_stats;
-
        wtap_sequential_close(wth);
 
        if (wth->subtype_close != NULL)
@@ -976,42 +1212,10 @@ wtap_close(wtap *wth)
                g_ptr_array_free(wth->fast_seek, TRUE);
        }
 
-       g_free(wth->shb_hdr.opt_comment);
-       g_free(wth->shb_hdr.shb_hardware);
-       g_free(wth->shb_hdr.shb_os);
-       g_free(wth->shb_hdr.shb_user_appl);
+       wtap_optionblock_array_free(wth->shb_hdrs);
+       wtap_optionblock_array_free(wth->nrb_hdrs);
+       wtap_optionblock_array_free(wth->interface_data);
 
-       for(i = 0; i < wth->interface_data->len; i++) {
-               wtapng_if_descr = &g_array_index(wth->interface_data, wtapng_if_descr_t, i);
-               if(wtapng_if_descr->opt_comment != NULL){
-                       g_free(wtapng_if_descr->opt_comment);
-               }
-               if(wtapng_if_descr->if_name != NULL){
-                       g_free(wtapng_if_descr->if_name);
-               }
-               if(wtapng_if_descr->if_description != NULL){
-                       g_free(wtapng_if_descr->if_description);
-               }
-               if(wtapng_if_descr->if_filter_str != NULL){
-                       g_free(wtapng_if_descr->if_filter_str);
-               }
-               if(wtapng_if_descr->if_filter_bpf_bytes != NULL){
-                       g_free(wtapng_if_descr->if_filter_bpf_bytes);
-               }
-               if(wtapng_if_descr->if_os != NULL){
-                       g_free(wtapng_if_descr->if_os);
-               }
-               for(j = 0; j < wtapng_if_descr->num_stat_entries; j++) {
-                       if_stats = &g_array_index(wtapng_if_descr->interface_statistics, wtapng_if_stats_t, j);
-                       if(if_stats->opt_comment != NULL){
-                               g_free(if_stats->opt_comment);
-                       }
-               }
-               if(wtapng_if_descr->num_stat_entries != 0){
-                       g_array_free(wtapng_if_descr->interface_statistics, TRUE);
-               }
-       }
-       g_array_free(wth->interface_data, TRUE);
        g_free(wth);
 }
 
@@ -1047,6 +1251,8 @@ wtap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
        wth->phdr.pkt_encap = wth->file_encap;
        wth->phdr.pkt_tsprec = wth->file_tsprec;
 
+       *err = 0;
+       *err_info = NULL;
        if (!wth->subtype_read(wth, err, err_info, data_offset)) {
                /*
                 * If we didn't get an error indication, we read
@@ -1196,6 +1402,19 @@ gboolean
 wtap_seek_read(wtap *wth, gint64 seek_off,
        struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
 {
+       /*
+        * Set the packet encapsulation to the file's encapsulation
+        * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
+        * right answer (and means that the read routine for this
+        * capture file type doesn't have to set it), and if it
+        * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
+        * anyway.
+        *
+        * Do the same for the packet time stamp resolution.
+        */
+       phdr->pkt_encap = wth->file_encap;
+       phdr->pkt_tsprec = wth->file_tsprec;
+
        if (!wth->subtype_seek_read(wth, seek_off, phdr, buf, err, err_info))
                return FALSE;
 
@@ -1216,3 +1435,16 @@ wtap_seek_read(wtap *wth, gint64 seek_off,
 
        return TRUE;
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */