added compression support for capture file output. The Save/As dialog now has a check...
[obnox/wireshark/wip.git] / wiretap / libpcap.c
index 2fc7b78a02f0b8b579403247143e13db40b7e684..7226f78585b2d3be249b4fa397e00c3b623a6d0b 100644 (file)
@@ -307,9 +307,10 @@ static const struct {
        { 127,          WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP },  /* 802.11 plus radiotap WLAN header */
        { 128,          WTAP_ENCAP_TZSP },      /* Tazmen Sniffer Protocol */
        { 129,          WTAP_ENCAP_ARCNET_LINUX },
-
+        { 130,          WTAP_ENCAP_JUNIPER_MLPPP }, /* Juniper MLPPP on ML-, LS-, AS- PICs */
+        { 131,          WTAP_ENCAP_JUNIPER_MLFR }, /* Juniper MLFR (FRF.15) on ML-, LS-, AS- PICs */
        /*
-        * Values 130 through 137 not listed here are reserved for use
+        * Values 132-134, 136 not listed here are reserved for use
         * in Juniper hardware.
         */
        { 135,          WTAP_ENCAP_JUNIPER_ATM2 }, /* various encapsulations captured on the ATM2 PIC */
@@ -373,6 +374,10 @@ static const struct {
         * Framing Procedure.
         */
 
+       /* Registered by Gcom, Inc. */
+       { 172,          WTAP_GCOM_TIE1 },
+       { 173,          WTAP_GCOM_SERIAL },
+
        /*
         * To repeat:
         *
@@ -596,6 +601,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
        gboolean aix;
        int file_encap;
 
+       
        /* Read in the number that should be at the start of a "libpcap" file */
        errno = WTAP_ERR_CANT_READ;
        bytes_read = file_read(&magic, 1, sizeof magic, wth->fh);
@@ -614,6 +620,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;
                break;
 
        case PCAP_MODIFIED_MAGIC:
@@ -621,6 +628,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;
                break;
 
        case PCAP_SWAPPED_MAGIC:
@@ -629,6 +637,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   ss990417 libpcap. */
                byte_swapped = TRUE;
                modified = FALSE;
+               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
                break;
 
        case PCAP_SWAPPED_MODIFIED_MAGIC:
@@ -637,6 +646,24 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                   or ss991029 libpcap. */
                byte_swapped = TRUE;
                modified = TRUE;
+               wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+               break;
+
+       case PCAP_NSEC_MAGIC:
+               /* Host that wrote it has our byte order, and was running
+                  a program using either standard or ss990417 libpcap. */
+               byte_swapped = FALSE;
+               modified = FALSE;
+               wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
+               break;
+
+       case PCAP_SWAPPED_NSEC_MAGIC:
+               /* Host that wrote it out has a byte order opposite to
+                  ours, and was running a program using either ss990915 
+                  or ss991029 libpcap. */
+               byte_swapped = TRUE;
+               modified = FALSE;
+               wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
                break;
 
        default:
@@ -894,7 +921,11 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                 *
                 * Try the standard format first.
                 */
-               wth->file_type = WTAP_FILE_PCAP;
+               if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+                       wth->file_type = WTAP_FILE_PCAP_NSEC;
+               } else {
+                       wth->file_type = WTAP_FILE_PCAP;
+               }
                switch (libpcap_try(wth, err)) {
 
                case BAD_READ:
@@ -988,6 +1019,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
                        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
                        *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
                            hdr.network);
+                       g_free(wth->capture.pcap);
                        return -1;
                }
        }
@@ -1261,8 +1293,12 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
                return FALSE;   /* Read error */
        wth->data_offset += packet_size;
 
-       wth->phdr.ts.tv_sec = hdr.hdr.ts_sec;
-       wth->phdr.ts.tv_usec = hdr.hdr.ts_usec;
+       wth->phdr.ts.secs = hdr.hdr.ts_sec;
+       if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+               wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
+       } else {
+               wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
+       }
        wth->phdr.caplen = packet_size;
        wth->phdr.len = orig_size;
 
@@ -1405,6 +1441,7 @@ static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
 
        case WTAP_FILE_PCAP:
        case WTAP_FILE_PCAP_AIX:
+       case WTAP_FILE_PCAP_NSEC:
                bytes_to_read = sizeof (struct pcaprec_hdr);
                break;
 
@@ -1813,8 +1850,8 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr,
           be a "struct bpf_timeval", with member sizes wired to 32
           bits - and we may go that way ourselves in the future, so
           copy the members individually. */
-       whdr->ts.tv_sec = phdr->ts.tv_sec;
-       whdr->ts.tv_usec = phdr->ts.tv_usec;
+       whdr->ts.secs = phdr->ts.tv_sec;
+       whdr->ts.nsecs = phdr->ts.tv_usec * 1000;
        whdr->caplen = phdr->caplen;
        whdr->len = phdr->len;
        whdr->pkt_encap = linktype;
@@ -1933,11 +1970,18 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
        case WTAP_FILE_PCAP_SS990417:   /* modified, but with the old magic, sigh */
        case WTAP_FILE_PCAP_NOKIA:      /* Nokia libpcap of some sort */
                magic = PCAP_MAGIC;
+               wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
                break;
 
        case WTAP_FILE_PCAP_SS990915:   /* new magic, extra crap */
        case WTAP_FILE_PCAP_SS991029:
                magic = PCAP_MODIFIED_MAGIC;
+               wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
+               break;
+
+       case WTAP_FILE_PCAP_NSEC:               /* same as WTAP_FILE_PCAP, but nsec precision */
+               magic = PCAP_NSEC_MAGIC;
+               wdh->tsprecision = WTAP_FILE_TSPREC_NSEC;
                break;
 
        default:
@@ -1947,10 +1991,10 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
                return FALSE;
        }
 
-       nwritten = fwrite(&magic, 1, sizeof magic, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &magic, sizeof magic);
        if (nwritten != sizeof magic) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -1976,10 +2020,10 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
        file_hdr.snaplen = (wdh->snaplen != 0) ? wdh->snaplen :
                                                 WTAP_MAX_PACKET_SIZE;
        file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->encap);
-       nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr);
        if (nwritten != sizeof file_hdr) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -2011,13 +2055,18 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
        else
                hdrsize = 0;
 
-       rec_hdr.hdr.ts_sec = phdr->ts.tv_sec;
-       rec_hdr.hdr.ts_usec = phdr->ts.tv_usec;
+       rec_hdr.hdr.ts_sec = phdr->ts.secs;
+       if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
+               rec_hdr.hdr.ts_usec = phdr->ts.nsecs;
+       } else {
+               rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000;
+       }
        rec_hdr.hdr.incl_len = phdr->caplen + hdrsize;
        rec_hdr.hdr.orig_len = phdr->len + hdrsize;
        switch (wdh->file_type) {
 
        case WTAP_FILE_PCAP:
+       case WTAP_FILE_PCAP_NSEC:
                hdr_size = sizeof (struct pcaprec_hdr);
                break;
 
@@ -2074,10 +2123,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                return FALSE;
        }
 
-       nwritten = fwrite(&rec_hdr, 1, hdr_size, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &rec_hdr, hdr_size);
        if (nwritten != hdr_size) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -2119,10 +2168,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                }
                atm_hdr.vpi = (guint8) pseudo_header->atm.vpi;
                atm_hdr.vci = phtons(&pseudo_header->atm.vci);
-               nwritten = fwrite(&atm_hdr, 1, sizeof atm_hdr, wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr);
                if (nwritten != sizeof atm_hdr) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2136,10 +2185,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                memset(&irda_hdr, 0, sizeof(irda_hdr));
                irda_hdr.sll_pkttype  = phtons(&pseudo_header->irda.pkttype);
                irda_hdr.sll_protocol = g_htons(0x0017);
-               nwritten = fwrite(&irda_hdr, 1, sizeof(irda_hdr), wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &irda_hdr, sizeof(irda_hdr));
                if (nwritten != sizeof(irda_hdr)) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2154,10 +2203,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                mtp2_hdr.sent         = pseudo_header->mtp2.sent;
                mtp2_hdr.annex_a_used = pseudo_header->mtp2.annex_a_used;
                mtp2_hdr.link_number  = phtons(&pseudo_header->mtp2.link_number);
-               nwritten = fwrite(&mtp2_hdr, 1, sizeof(mtp2_hdr), wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &mtp2_hdr, sizeof(mtp2_hdr));
                if (nwritten != sizeof(mtp2_hdr)) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2165,10 +2214,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                wdh->bytes_dumped += sizeof(mtp2_hdr);
        }
 
-       nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, pd, phdr->caplen);
        if (nwritten != phdr->caplen) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;