Make sure the packet length isn't > WTAP_MAX_PACKET_SIZE.
[metze/wireshark/wip.git] / wiretap / libpcap.c
index 75e52015fdac9226faa35cd8d45c9550504eec12..66572425e195d2ba91d1a733acf004ebbd89faa3 100644 (file)
@@ -25,7 +25,6 @@
 #include <errno.h>
 #include "wtap-int.h"
 #include "file_wrappers.h"
-#include <wsutil/buffer.h>
 #include "pcap-common.h"
 #include "pcap-encap.h"
 #include "libpcap.h"
@@ -67,13 +66,12 @@ static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off,
 static gboolean libpcap_read_packet(wtap *wth, FILE_T fh,
     struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
 static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
-    const guint8 *pd, int *err);
+    const guint8 *pd, int *err, gchar **err_info);
 static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
     struct pcaprec_ss990915_hdr *hdr);
 
-int libpcap_open(wtap *wth, int *err, gchar **err_info)
+wtap_open_return_val libpcap_open(wtap *wth, int *err, gchar **err_info)
 {
-       int bytes_read;
        guint32 magic;
        struct pcap_hdr hdr;
        gboolean byte_swapped;
@@ -106,13 +104,10 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
        int i;
 
        /* Read in the number that should be at the start of a "libpcap" file */
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(&magic, sizeof magic, wth->fh);
-       if (bytes_read != sizeof magic) {
-               *err = file_error(wth->fh, err_info);
-               if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
-                       return -1;
-               return 0;
+       if (!wtap_read_bytes(wth->fh, &magic, sizeof magic, err, err_info)) {
+               if (*err != WTAP_ERR_SHORT_READ)
+                       return WTAP_OPEN_ERROR;
+               return WTAP_OPEN_NOT_MINE;
        }
 
        switch (magic) {
@@ -122,7 +117,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   a program using either standard or ss990417 libpcap. */
                byte_swapped = FALSE;
                modified = FALSE;
-               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wth->file_tsprec = WTAP_TSPREC_USEC;
                break;
 
        case PCAP_MODIFIED_MAGIC:
@@ -130,7 +125,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   a program using either ss990915 or ss991029 libpcap. */
                byte_swapped = FALSE;
                modified = TRUE;
-               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wth->file_tsprec = WTAP_TSPREC_USEC;
                break;
 
        case PCAP_SWAPPED_MAGIC:
@@ -139,7 +134,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   ss990417 libpcap. */
                byte_swapped = TRUE;
                modified = FALSE;
-               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wth->file_tsprec = WTAP_TSPREC_USEC;
                break;
 
        case PCAP_SWAPPED_MODIFIED_MAGIC:
@@ -148,7 +143,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   or ss991029 libpcap. */
                byte_swapped = TRUE;
                modified = TRUE;
-               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wth->file_tsprec = WTAP_TSPREC_USEC;
                break;
 
        case PCAP_NSEC_MAGIC:
@@ -157,7 +152,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   except that the time stamps have nanosecond resolution. */
                byte_swapped = FALSE;
                modified = FALSE;
-               wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
+               wth->file_tsprec = WTAP_TSPREC_NSEC;
                break;
 
        case PCAP_SWAPPED_NSEC_MAGIC:
@@ -167,23 +162,17 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   nanosecond resolution. */
                byte_swapped = TRUE;
                modified = FALSE;
-               wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
+               wth->file_tsprec = WTAP_TSPREC_NSEC;
                break;
 
        default:
                /* Not a "libpcap" type we know about. */
-               return 0;
+               return WTAP_OPEN_NOT_MINE;
        }
 
        /* Read the rest of the header. */
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
-       if (bytes_read != sizeof hdr) {
-               *err = file_error(wth->fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
-               return -1;
-       }
+       if (!wtap_read_bytes(wth->fh, &hdr, sizeof hdr, err, err_info))
+               return WTAP_OPEN_ERROR;
 
        if (byte_swapped) {
                /* Byte-swap the header fields about which we care. */
@@ -197,7 +186,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                *err = WTAP_ERR_UNSUPPORTED;
                *err_info = g_strdup_printf("pcap: major version %u unsupported",
                    hdr.version_major);
-               return -1;
+               return WTAP_OPEN_ERROR;
        }
 
        /*
@@ -263,10 +252,10 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
 
        file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
        if (file_encap == WTAP_ENCAP_UNKNOWN) {
-               *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+               *err = WTAP_ERR_UNSUPPORTED;
                *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
                    hdr.network);
-               return -1;
+               return WTAP_OPEN_ERROR;
        }
 
        /* This is a libpcap file */
@@ -326,8 +315,8 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                 * precision to nanosecond precision.
                 */
                wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX;
-               wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
-               return 1;
+               wth->file_tsprec = WTAP_TSPREC_NSEC;
+               return WTAP_OPEN_MINE;
        }
 
        /*
@@ -371,7 +360,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                subtypes = subtypes_modified;
                n_subtypes = N_SUBTYPES_MODIFIED;
        } else {
-               if (wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+               if (wth->file_tsprec == WTAP_TSPREC_NSEC) {
                        /*
                         * We have nanosecond-format libpcap's magic
                         * number.  Try the subtypes for that.
@@ -400,7 +389,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                         * Well, we couldn't even read it.
                         * Give up.
                         */
-                       return -1;
+                       return WTAP_OPEN_ERROR;
                }
                if (figures_of_merit[i] == 0) {
                        /*
@@ -408,7 +397,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                         * Put the seek pointer back, and finish.
                         */
                        if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
-                               return -1;
+                               return WTAP_OPEN_ERROR;
                        }
                        goto done;
                }
@@ -418,7 +407,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                 * go back to the first packet and try the next one.
                 */
                if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
-                       return -1;
+                       return WTAP_OPEN_ERROR;
                }
        }
 
@@ -460,7 +449,7 @@ done:
                 */
                erf_populate_interfaces(wth);
        }
-       return 1;
+       return WTAP_OPEN_MINE;
 }
 
 /* Try to read the first two records of the capture file. */
@@ -576,21 +565,21 @@ static int libpcap_try_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
                ret++;
        }
 
-        if (hdr->hdr.orig_len > 64*1024*1024) {
-                /*
-                 * In theory I guess the on-the-wire packet size can be
-                 * arbitrarily large, and it can certainly be larger than the
-                 * maximum snapshot length which bounds the snapshot size,
-                 * but any file claiming 64MB in a single packet is *probably*
-                 * corrupt, and treating them as such makes the heuristics
-                 * much more reliable. See, for example,
-                 *
-                 *    https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9634
-                 *
-                 * (64MB is an arbitrary size at this point).
-                 */
-                ret++;
-        }
+       if (hdr->hdr.orig_len > 64*1024*1024) {
+               /*
+                * In theory I guess the on-the-wire packet size can be
+                * arbitrarily large, and it can certainly be larger than the
+                * maximum snapshot length which bounds the snapshot size,
+                * but any file claiming 64MB in a single packet is *probably*
+                * corrupt, and treating them as such makes the heuristics
+                * much more reliable. See, for example,
+                *
+                *    https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9634
+                *
+                * (64MB is an arbitrary size at this point).
+                */
+               ret++;
+       }
 
        if (hdr->hdr.incl_len > wth->snapshot_length) {
                /*
@@ -715,7 +704,7 @@ libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
        /* Update the timestamp, if not already done */
        if (wth->file_encap != WTAP_ENCAP_ERF) {
                phdr->ts.secs = hdr.hdr.ts_sec;
-               if (wth->tsprecision == WTAP_FILE_TSPREC_NSEC)
+               if (wth->file_tsprec == WTAP_TSPREC_NSEC)
                        phdr->ts.nsecs = hdr.hdr.ts_usec;
                else
                        phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
@@ -745,11 +734,10 @@ libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
 static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
     struct pcaprec_ss990915_hdr *hdr)
 {
-       int bytes_to_read, bytes_read;
+       int bytes_to_read;
        guint32 temp;
        libpcap_t *libpcap;
 
-       errno = WTAP_ERR_CANT_READ;
        switch (wth->file_type_subtype) {
 
        case WTAP_FILE_TYPE_SUBTYPE_PCAP:
@@ -775,14 +763,8 @@ static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info,
                g_assert_not_reached();
                bytes_to_read = 0;
        }
-       bytes_read = file_read(hdr, bytes_to_read, fh);
-       if (bytes_read != bytes_to_read) {
-               *err = file_error(fh, err_info);
-               if (*err == 0 && bytes_read != 0) {
-                       *err = WTAP_ERR_SHORT_READ;
-               }
+       if (!wtap_read_bytes_or_eof(fh, hdr, bytes_to_read, err, err_info))
                return FALSE;
-       }
 
        libpcap = (libpcap_t *)wth->priv;
        if (libpcap->byte_swapped) {
@@ -828,7 +810,7 @@ int libpcap_dump_can_write_encap(int encap)
                return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
 
        if (wtap_wtap_encap_to_pcap_encap(encap) == -1)
-               return WTAP_ERR_UNSUPPORTED_ENCAP;
+               return WTAP_ERR_UNWRITABLE_ENCAP;
 
        return 0;
 }
@@ -842,7 +824,6 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
 
        /* This is a libpcap file */
        wdh->subtype_write = libpcap_dump;
-       wdh->subtype_close = NULL;
 
        /* Write the file header. */
        switch (wdh->file_type_subtype) {
@@ -851,24 +832,24 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
        case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417:      /* modified, but with the old magic, sigh */
        case WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA: /* Nokia libpcap of some sort */
                magic = PCAP_MAGIC;
-               wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wdh->tsprecision = WTAP_TSPREC_USEC;
                break;
 
        case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915:      /* new magic, extra crap */
        case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029:
                magic = PCAP_MODIFIED_MAGIC;
-               wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
+               wdh->tsprecision = WTAP_TSPREC_USEC;
                break;
 
        case WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC:          /* same as WTAP_FILE_TYPE_SUBTYPE_PCAP, but nsec precision */
                magic = PCAP_NSEC_MAGIC;
-               wdh->tsprecision = WTAP_FILE_TSPREC_NSEC;
+               wdh->tsprecision = WTAP_TSPREC_NSEC;
                break;
 
        default:
                /* We should never get here - our open routine
                   should only get called for the types above. */
-               *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
+               *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
                return FALSE;
        }
 
@@ -906,7 +887,7 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
    Returns TRUE on success, FALSE on failure. */
 static gboolean libpcap_dump(wtap_dumper *wdh,
        const struct wtap_pkthdr *phdr,
-       const guint8 *pd, int *err)
+       const guint8 *pd, int *err, gchar **err_info _U_)
 {
        const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
        struct pcaprec_ss990915_hdr rec_hdr;
@@ -917,7 +898,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
 
        /* We can only write packet records. */
        if (phdr->rec_type != REC_TYPE_PACKET) {
-               *err = WTAP_ERR_REC_TYPE_UNSUPPORTED;
+               *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
                return FALSE;
        }
 
@@ -928,7 +909,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
        }
 
        rec_hdr.hdr.ts_sec = (guint32) phdr->ts.secs;
-       if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+       if(wdh->tsprecision == WTAP_TSPREC_NSEC) {
                rec_hdr.hdr.ts_usec = phdr->ts.nsecs;
        } else {
                rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000;
@@ -999,7 +980,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                /* We should never get here - our open routine
                   should only get called for the types above. */
                g_assert_not_reached();
-               *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
+               *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
                return FALSE;
        }
 
@@ -1012,6 +993,19 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
 
        if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
                return FALSE;
-        wdh->bytes_dumped += phdr->caplen;
+       wdh->bytes_dumped += phdr->caplen;
        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:
+ */