It appears that the first two bytes of "xxz" are, in fact, the actual
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Jan 2003 08:41:23 +0000 (08:41 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Jan 2003 08:41:23 +0000 (08:41 +0000)
length of the packet, and the second two bytes are the captured length
of the packet.  The old "length" value appears to be the captured length
of the packet as well; perhaps it's to be interpreted as the number of
bytes of data following the packet header (just in case there's padding,
for example).

Treat "ATM/", as an encapsulation string, as RFC 1483 ATM.  (It may
actually be raw ATM, but the only capture I've seen had, in the parts I
saw, only RFC 1483 traffic LLC/SNAP traffic.)

There are 8 bytes in front of the LLC/SNAP header in ATM captures; skip
them, for now.  (Perhaps they're a pseudo-header, giving VPI/VCI
information and stuff such as that?  Or perhaps that's in the record
header?)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@6871 f5534014-38df-0310-8fa8-9805f1628bb7

wiretap/radcom.c

index d2e2c30588a2722dbae9e0acb7b71be1c38f6b9a..a2ac904c66d5c58603c1e6aa85cfbf1543ce4155 100644 (file)
@@ -1,6 +1,6 @@
 /* radcom.c
  *
- * $Id: radcom.c,v 1.40 2002/12/17 21:53:57 oabad Exp $
+ * $Id: radcom.c,v 1.41 2003/01/07 08:41:23 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -63,16 +63,28 @@ static guint8 active_time_magic[11] = {
 };
 
 /* 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? */
+
+   "data_length" appears to be the length of packet data following
+   the record header.  It's 0 in the last record.
+
+   "length" appears to be the amount of captured packet data, and
+   "real_length" might be the actual length of the frame on the wire -
+   in some captures, it's the same as "length", and, in others,
+   it's greater than "length".  In the last record, however, those
+   may have bogus values (or is that some kind of trailer record?).
+
+   "xxx" appears to be all-zero in all but the last record in one
+   capture; if so, perhaps this indicates that the last record is,
+   in fact, a trailer of some sort, and some field in the header
+   is a record type. */
 struct radcomrec_hdr {
        char    xxx[4];         /* unknown */
-       char    length[2];      /* packet length */
+       char    data_length[2]; /* packet length? */
        char    xxy[5];         /* unknown */
        struct unaligned_frame_date date; /* date/time stamp of packet */
-       char    xxz[6];         /* unknown */
+       char    real_length[2]; /* actual length of packet */
+       char    length[2];      /* captured length of packet */
+       char    xxz[2];         /* unknown */
        char    dce;            /* DCE/DTE flag (and other flags?) */
        char    xxw[9];         /* unknown */
 };
@@ -199,10 +211,12 @@ int radcom_open(wtap *wth, int *err)
                goto read_error;
        }
        wth->data_offset += 4;
-       if (!memcmp(search_encap, "LAPB", 4))
+       if (memcmp(search_encap, "LAPB", 4) == 0)
                wth->file_encap = WTAP_ENCAP_LAPB;
-       else if (!memcmp(search_encap, "Ethe", 4))
+       else if (memcmp(search_encap, "Ethe", 4) == 0)
                wth->file_encap = WTAP_ENCAP_ETHERNET;
+       else if (memcmp(search_encap, "ATM/", 4) == 0)
+               wth->file_encap = WTAP_ENCAP_ATM_RFC1483;
        else {
                g_message("pcap: network type \"%.4s\" unknown", search_encap);
                *err = WTAP_ERR_UNSUPPORTED_ENCAP;
@@ -234,6 +248,10 @@ int radcom_open(wtap *wth, int *err)
                if (file_seek(wth->fh, 297, SEEK_CUR, err) == -1)
                        return -1;
                wth->data_offset += 297;
+       } else if (wth->file_encap == WTAP_ENCAP_ATM_RFC1483) {
+               if (file_seek(wth->fh, 504, SEEK_CUR, err) == -1)
+                       return -1;
+               wth->data_offset += 504;
        }
 
        return 1;
@@ -250,10 +268,11 @@ static gboolean radcom_read(wtap *wth, int *err, long *data_offset)
 {
        int     ret;
        struct radcomrec_hdr hdr;
-       guint16 length;
+       guint16 data_length, real_length, length;
        guint32 sec;
        int     bytes_read;
        struct tm tm;
+       char    phdr[8];
        char    fcs[2];
 
        /* Read record header. */
@@ -264,17 +283,28 @@ static gboolean radcom_read(wtap *wth, int *err, long *data_offset)
                return FALSE;
        }
        wth->data_offset += sizeof hdr;
+       data_length = pletohs(&hdr.data_length);
+       if (data_length == 0) {
+               /*
+                * The last record appears to have 0 in its "data_length"
+                * field, but non-zero values in other fields, so we
+                * check for that and treat it as an EOF indication.
+                */
+               return FALSE;
+       }
        length = pletohs(&hdr.length);
-       if (length == 0) return FALSE;
+       real_length = pletohs(&hdr.real_length);
 
-       if (wth->file_encap == WTAP_ENCAP_LAPB)
+       if (wth->file_encap == WTAP_ENCAP_LAPB) {
                length -= 2; /* FCS */
+               real_length -= 2;
+       }
 
-       wth->phdr.len = length;
+       wth->phdr.len = real_length;
        wth->phdr.caplen = length;
 
        tm.tm_year = pletohs(&hdr.date.year)-1900;
-       tm.tm_mon = hdr.date.month-1;
+       tm.tm_mon = (hdr.date.month&0x0f)-1;
        tm.tm_mday = hdr.date.day;
        sec = pletohl(&hdr.date.sec);
        tm.tm_hour = sec/3600;
@@ -283,7 +313,27 @@ static gboolean radcom_read(wtap *wth, int *err, long *data_offset)
        tm.tm_isdst = -1;
        wth->phdr.ts.tv_sec = mktime(&tm);
        wth->phdr.ts.tv_usec = pletohl(&hdr.date.usec);
-       wth->pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE;
+
+       switch (wth->file_encap) {
+
+       case WTAP_ENCAP_LAPB:
+               wth->pseudo_header.x25.flags = (hdr.dce & 0x1) ?
+                   0x00 : FROM_DCE;
+               break;
+
+       case WTAP_ENCAP_ATM_RFC1483:
+               /*
+                * XXX - is this stuff a pseudo-header?
+                * The direction appears to be in the "hdr.dce" field.
+                */
+               if (!radcom_read_rec_data(wth->fh, phdr, sizeof phdr, err))
+                       return FALSE;   /* Read error */
+               wth->data_offset += 8;
+               length -= 8;
+               wth->phdr.len -= 8;
+               wth->phdr.caplen -= 8;
+               break;
+       }
 
        /*
         * Read the packet data.
@@ -298,7 +348,9 @@ static gboolean radcom_read(wtap *wth, int *err, long *data_offset)
 
        if (wth->file_encap == WTAP_ENCAP_LAPB) {
                /* Read the FCS.
-                  XXX - should we put it in the pseudo-header? */
+                  XXX - should we have some way of indicating the
+                  presence and size of an FCS to our caller?
+                  That'd let us handle other file types as well. */
                errno = WTAP_ERR_CANT_READ;
                bytes_read = file_read(&fcs, 1, sizeof fcs, wth->fh);
                if (bytes_read != sizeof fcs) {
@@ -319,6 +371,7 @@ radcom_seek_read(wtap *wth, long seek_off,
 {
        int     ret;
        struct radcomrec_hdr hdr;
+       char    phdr[8];
 
        if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
                return FALSE;
@@ -334,7 +387,22 @@ radcom_seek_read(wtap *wth, long seek_off,
                return FALSE;
        }
 
-       pseudo_header->x25.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE;
+       switch (wth->file_encap) {
+
+       case WTAP_ENCAP_LAPB:
+               pseudo_header->x25.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE;
+               break;
+
+       case WTAP_ENCAP_ATM_RFC1483:
+               /*
+                * XXX - is this stuff a pseudo-header?
+                * The direction appears to be in the "hdr.dce" field.
+                */
+               if (!radcom_read_rec_data(wth->random_fh, phdr, sizeof phdr,
+                   err))
+                       return FALSE;   /* Read error */
+               break;
+       }
 
        /*
         * Read the packet data.