Give it an RCS ID.
[obnox/wireshark/wip.git] / wiretap / radcom.c
index 4db683a1f665fdd24e7c15bc5033d916efb317e5..a2696be2e675697be324205410bd61d115eae3dc 100644 (file)
@@ -1,4 +1,6 @@
 /* radcom.c
+ *
+ * $Id: radcom.c,v 1.11 1999/09/23 05:03:32 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -25,6 +27,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <time.h>
+#include "file.h"
 #include "wtap.h"
 #include "buffer.h"
 #include "radcom.h"
@@ -37,10 +40,33 @@ struct frame_date {
        guint32 usec;
 };
 
+struct unaligned_frame_date {
+       char    year[2];
+       char    month;
+       char    day;
+       char    sec[4];         /* seconds since midnight */
+       char    usec[4];
+};
+
 static char radcom_magic[8] = {
        0x42, 0xD2, 0x00, 0x34, 0x12, 0x66, 0x22, 0x88
 };
 
+/* RADCOM record header - followed by frame data (perhaps including FCS).
+   The first two bytes of "xxz" appear to equal "length", as do the
+   second two bytes; if a RADCOM box can be told not to save all of
+   the captured packet, might one or the other of those be the
+   captured length of the packet? */
+struct radcomrec_hdr {
+       char    xxx[4];         /* unknown */
+       char    length[2];      /* packet length */
+       char    xxy[5];         /* unknown */
+       struct unaligned_frame_date date; /* date/time stamp of packet */
+       char    xxz[6];         /* unknown */
+       char    dce;            /* DCE/DTE flag (and other flags?) */
+       char    xxw[9];         /* unknown */
+};
+
 static int radcom_read(wtap *wth, int *err);
 
 int radcom_open(wtap *wth, int *err)
@@ -48,17 +74,18 @@ int radcom_open(wtap *wth, int *err)
        int bytes_read;
        char magic[8];
        struct frame_date start_date;
+       guint32 sec;
        struct tm tm;
        char byte;
        char encap_magic[7] = {0x54, 0x43, 0x50, 0x00, 0x42, 0x43, 0x09};
        char search_encap[7];
 
        /* Read in the string that should be at the start of a RADCOM file */
-       fseek(wth->fh, 0, SEEK_SET);
+       file_seek(wth->fh, 0, SEEK_SET);
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(magic, 1, 8, wth->fh);
+       bytes_read = file_read(magic, 1, 8, wth->fh);
        if (bytes_read != 8) {
-               if (ferror(wth->fh)) {
+               if (file_error(wth->fh)) {
                        *err = errno;
                        return -1;
                }
@@ -69,39 +96,44 @@ int radcom_open(wtap *wth, int *err)
                return 0;
        }
 
-       fseek(wth->fh, 0x8B, SEEK_SET);
+       file_seek(wth->fh, 0x8B, SEEK_SET);
+       wth->data_offset = 0x8B;
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(&byte, 1, 1, wth->fh);
+       bytes_read = file_read(&byte, 1, 1, wth->fh);
        if (bytes_read != 1) {
-               if (ferror(wth->fh)) {
+               if (file_error(wth->fh)) {
                        *err = errno;
                        return -1;
                }
                return 0;
        }
+       wth->data_offset += 1;
        while (byte) {
                errno = WTAP_ERR_CANT_READ;
-               bytes_read = fread(&byte, 1, 1, wth->fh);
+               bytes_read = file_read(&byte, 1, 1, wth->fh);
                if (bytes_read != 1) {
-                       if (ferror(wth->fh)) {
+                       if (file_error(wth->fh)) {
                                *err = errno;
                                return -1;
                        }
                        return 0;
                }
+               wth->data_offset += 1;
        }
-       fseek(wth->fh, 1, SEEK_CUR);
+       file_seek(wth->fh, 1, SEEK_CUR);
+       wth->data_offset += 1;
 
        /* Get capture start time */
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(&start_date, 1, sizeof(struct frame_date), wth->fh);
+       bytes_read = file_read(&start_date, 1, sizeof(struct frame_date), wth->fh);
        if (bytes_read != sizeof(struct frame_date)) {
-               if (ferror(wth->fh)) {
+               if (file_error(wth->fh)) {
                        *err = errno;
                        return -1;
                }
                return 0;
        }
+       wth->data_offset += sizeof(struct frame_date);
 
        /* This is a radcom file */
        wth->file_type = WTAP_FILE_RADCOM;
@@ -109,36 +141,43 @@ int radcom_open(wtap *wth, int *err)
        wth->subtype_read = radcom_read;
        wth->snapshot_length = 16384;   /* not available in header, only in frame */
 
-       tm.tm_year = start_date.year-1900;
+       tm.tm_year = pletohs(&start_date.year)-1900;
        tm.tm_mon = start_date.month-1;
        tm.tm_mday = start_date.day;
-       tm.tm_hour = start_date.sec/3600;
-       tm.tm_min = (start_date.sec%3600)/60;
-       tm.tm_sec = start_date.sec%60;
+       sec = pletohl(&start_date.sec);
+       tm.tm_hour = sec/3600;
+       tm.tm_min = (sec%3600)/60;
+       tm.tm_sec = sec%60;
        tm.tm_isdst = -1;
        wth->capture.radcom->start = mktime(&tm);
 
-       fseek(wth->fh, sizeof(struct frame_date), SEEK_CUR);
+       file_seek(wth->fh, sizeof(struct frame_date), SEEK_CUR);
+       wth->data_offset += sizeof(struct frame_date);
 
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(search_encap, 1, 7, wth->fh);
+       bytes_read = file_read(search_encap, 1, 7, wth->fh);
        if (bytes_read != 7) {
                goto read_error;
        }
+       wth->data_offset += 7;
        while (memcmp(encap_magic, search_encap, 7)) {
-               fseek(wth->fh, -6, SEEK_CUR);
+               file_seek(wth->fh, -6, SEEK_CUR);
+               wth->data_offset -= 6;
                errno = WTAP_ERR_CANT_READ;
-               bytes_read = fread(search_encap, 1, 7, wth->fh);
+               bytes_read = file_read(search_encap, 1, 7, wth->fh);
                if (bytes_read != 7) {
                        goto read_error;
                }
+               wth->data_offset += 7;
        }
-       fseek(wth->fh, 12, SEEK_CUR);
+       file_seek(wth->fh, 12, SEEK_CUR);
+       wth->data_offset += 12;
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(search_encap, 1, 4, wth->fh);
+       bytes_read = file_read(search_encap, 1, 4, wth->fh);
        if (bytes_read != 4) {
                goto read_error;
        }
+       wth->data_offset += 4;
        if (!memcmp(search_encap, "LAPB", 4))
                wth->file_encap = WTAP_ENCAP_LAPB;
        else if (!memcmp(search_encap, "Ethe", 4))
@@ -149,16 +188,16 @@ int radcom_open(wtap *wth, int *err)
                return -1;
        }
 
-       /*bytes_read = fread(&next_date, 1, sizeof(struct frame_date), wth->fh);
+       /*bytes_read = file_read(&next_date, 1, sizeof(struct frame_date), wth->fh);
        errno = WTAP_ERR_CANT_READ;
        if (bytes_read != sizeof(struct frame_date)) {
                goto read_error;
        }
 
        while (memcmp(&start_date, &next_date, 4)) {
-               fseek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR);
+               file_seek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR);
                errno = WTAP_ERR_CANT_READ;
-               bytes_read = fread(&next_date, 1, sizeof(struct frame_date),
+               bytes_read = file_read(&next_date, 1, sizeof(struct frame_date),
                                   wth->fh);
                if (bytes_read != sizeof(struct frame_date)) {
                        goto read_error;
@@ -166,17 +205,17 @@ int radcom_open(wtap *wth, int *err)
        }*/
 
        if (wth->file_encap == WTAP_ENCAP_ETHERNET) {
-               fseek(wth->fh, 294, SEEK_CUR);
-               wth->data_offset = 294;
+               file_seek(wth->fh, 294, SEEK_CUR);
+               wth->data_offset += 294;
        } else if (wth->file_encap == WTAP_ENCAP_LAPB) {
-               fseek(wth->fh, 297, SEEK_CUR);
-               wth->data_offset = 297;
+               file_seek(wth->fh, 297, SEEK_CUR);
+               wth->data_offset += 297;
        }
 
        return 1;
 
 read_error:
-       if (ferror(wth->fh)) {
+       if (file_error(wth->fh)) {
                *err = errno;
                free(wth->capture.radcom);
                return -1;
@@ -189,22 +228,18 @@ read_error:
 static int radcom_read(wtap *wth, int *err)
 {
        int     bytes_read;
+       struct radcomrec_hdr hdr;
        guint16 length;
-       struct frame_date date;
-       int     data_offset;
+       guint32 sec;
        struct tm tm;
-       char dce;
-
-       fseek(wth->fh, 4, SEEK_CUR);
-       wth->data_offset += 4;
+       int     data_offset;
+       char    fcs[2];
 
-       /*
-        * Read the frame size
-        */
+       /* Read record header. */
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(&length, 1, 2, wth->fh);
-       if (bytes_read != 2) {
-               if (ferror(wth->fh)) {
+       bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
+       if (bytes_read != sizeof hdr) {
+               if (file_error(wth->fh)) {
                        *err = errno;
                        return -1;
                }
@@ -214,7 +249,9 @@ static int radcom_read(wtap *wth, int *err)
                }
                return 0;
        }
-       wth->data_offset += 2;
+       wth->data_offset += sizeof hdr;
+       length = pletohs(&hdr.length);
+       if (length == 0) return 0;
 
        if (wth->file_encap == WTAP_ENCAP_LAPB)
                length -= 2; /* FCS */
@@ -222,44 +259,17 @@ static int radcom_read(wtap *wth, int *err)
        wth->phdr.len = length;
        wth->phdr.caplen = length;
 
-       fseek(wth->fh, 5, SEEK_CUR);
-       wth->data_offset += 5;
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(&date, 1, sizeof(struct frame_date), wth->fh);
-       if (bytes_read != sizeof(struct frame_date)) {
-               if (ferror(wth->fh))
-                       *err = errno;
-               else
-                       *err = WTAP_ERR_SHORT_READ;
-               return -1;
-       }
-       wth->data_offset += sizeof(struct frame_date);
-
-       tm.tm_year = date.year-1900;
-       tm.tm_mon = date.month-1;
-       tm.tm_mday = date.day;
-       tm.tm_hour = date.sec/3600;
-       tm.tm_min = (date.sec%3600)/60;
-       tm.tm_sec = date.sec%60;
+       tm.tm_year = pletohs(&hdr.date.year)-1900;
+       tm.tm_mon = hdr.date.month-1;
+       tm.tm_mday = hdr.date.day;
+       sec = pletohl(&hdr.date.sec);
+       tm.tm_hour = sec/3600;
+       tm.tm_min = (sec%3600)/60;
+       tm.tm_sec = sec%60;
        tm.tm_isdst = -1;
        wth->phdr.ts.tv_sec = mktime(&tm);
-       wth->phdr.ts.tv_usec = date.usec;
-
-       fseek(wth->fh, 6, SEEK_CUR);
-       wth->data_offset += 6;
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(&dce, 1, 1, wth->fh);
-       if (bytes_read != 1) {
-               if (ferror(wth->fh))
-                       *err = errno;
-               else
-                       *err = WTAP_ERR_SHORT_READ;
-               return -1;
-       }
-       wth->data_offset += 1;
-       wth->phdr.pseudo_header.x25.flags = (dce & 0x1) ? 0x00 : 0x80;
-
-       fseek(wth->fh, 9, SEEK_CUR);
+       wth->phdr.ts.tv_usec = pletohl(&hdr.date.usec);
+       wth->phdr.pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : 0x80;
 
        /*
         * Read the packet data.
@@ -267,11 +277,11 @@ static int radcom_read(wtap *wth, int *err)
        buffer_assure_space(wth->frame_buffer, length);
        data_offset = wth->data_offset;
        errno = WTAP_ERR_CANT_READ;
-       bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
+       bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
                        length, wth->fh);
 
        if (bytes_read != length) {
-               if (ferror(wth->fh))
+               if (file_error(wth->fh))
                        *err = errno;
                else
                        *err = WTAP_ERR_SHORT_READ;
@@ -282,8 +292,18 @@ static int radcom_read(wtap *wth, int *err)
        wth->phdr.pkt_encap = wth->file_encap;
 
        if (wth->file_encap == WTAP_ENCAP_LAPB) {
-               fseek(wth->fh, 2, SEEK_CUR); /* FCS */
-               wth->data_offset += 2;
+               /* Read the FCS.
+                  XXX - should we put it in the pseudo-header? */
+               errno = WTAP_ERR_CANT_READ;
+               bytes_read = file_read(&fcs, 1, sizeof fcs, wth->fh);
+               if (bytes_read != sizeof fcs) {
+                       if (file_error(wth->fh))
+                               *err = errno;
+                       else
+                               *err = WTAP_ERR_SHORT_READ;
+                       return -1;
+               }
+               wth->data_offset += sizeof fcs;
        }
 
        return data_offset;