#define RX_STATUS_TRIGGERED 0x0001 /* frame did trigger */
static gboolean snoop_read(wtap *wth, int *err, gchar **err_info,
- long *data_offset);
-static gboolean snoop_seek_read(wtap *wth, long seek_off,
+ gint64 *data_offset);
+static gboolean snoop_seek_read(wtap *wth, gint64 seek_off,
union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
int *err, gchar **err_info);
static gboolean snoop_read_atm_pseudoheader(FILE_T fh,
- union wtap_pseudo_header *pseudo_header, int *err);
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+static gboolean snoop_read_shomiti_wireless_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info,
+ int *header_size);
static gboolean snoop_read_rec_data(FILE_T fh, guchar *pd, int length,
- int *err);
+ int *err, gchar **err_info);
static gboolean snoop_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
WTAP_ENCAP_UNKNOWN, /* 100BaseT (but that's just Ethernet) */
};
#define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0])
+ #define SNOOP_PRIVATE_BIT 0x80000000
+ static const int snoop_private_encap[] = {
+ WTAP_ENCAP_UNKNOWN, /* Not Used */
+ WTAP_ENCAP_UNKNOWN, /* IPv4 Tunnel Link */
+ WTAP_ENCAP_UNKNOWN, /* IPv6 Tunnel Link */
+ WTAP_ENCAP_UNKNOWN, /* Virtual network interface */
+ WTAP_ENCAP_UNKNOWN, /* IEEE 802.11 */
+ WTAP_ENCAP_IPNET, /* ipnet(7D) link */
+ WTAP_ENCAP_UNKNOWN, /* IPMP stub interface */
+ WTAP_ENCAP_UNKNOWN, /* 6to4 Tunnel Link */
+ };
+ #define NUM_SNOOP_PRIVATE_ENCAPS (sizeof snoop_private_encap / sizeof snoop_private_encap[0])
static const int shomiti_encap[] = {
WTAP_ENCAP_ETHERNET, /* IEEE 802.3 */
WTAP_ENCAP_UNKNOWN, /* IEEE 802.4 Token Bus */
WTAP_ENCAP_ETHERNET, /* Gigabit Ethernet */
WTAP_ENCAP_TOKEN_RING, /* "IEEE 802.5 Shomiti" */
WTAP_ENCAP_TOKEN_RING, /* "4MB IEEE 802.5 Shomiti" */
+ WTAP_ENCAP_UNKNOWN, /* Other */
+ WTAP_ENCAP_UNKNOWN, /* Other */
+ WTAP_ENCAP_UNKNOWN, /* Other */
+ WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
};
#define NUM_SHOMITI_ENCAPS (sizeof shomiti_encap / sizeof shomiti_encap[0])
int file_encap;
/* Read in the string that should be at the start of a "snoop" file */
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
+ bytes_read = file_read(magic, sizeof magic, wth->fh);
if (bytes_read != sizeof magic) {
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
if (*err != 0)
return -1;
return 0;
/* Read the rest of the header. */
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
+ bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
if (*err != 0)
return -1;
return 0;
/* Read first record header. */
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&rec_hdr, 1, sizeof rec_hdr, wth->fh);
+ bytes_read = file_read(&rec_hdr, sizeof rec_hdr, wth->fh);
if (bytes_read != sizeof rec_hdr) {
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
if (*err == 0 && bytes_read != 0)
*err = WTAP_ERR_SHORT_READ;
if (*err != 0) {
* Well, we have padding; how much?
*/
padbytes = g_ntohl(rec_hdr.rec_len) -
- (sizeof rec_hdr + g_ntohl(rec_hdr.incl_len));
+ ((guint)sizeof rec_hdr + g_ntohl(rec_hdr.incl_len));
/*
* Is it at least the size of a Shomiti trailer?
/* This is a Shomiti file */
wth->file_type = WTAP_FILE_SHOMITI;
+ } else if (hdr.network & SNOOP_PRIVATE_BIT) {
+ if ((hdr.network^SNOOP_PRIVATE_BIT) >= NUM_SNOOP_PRIVATE_ENCAPS
+ || snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT] == WTAP_ENCAP_UNKNOWN) {
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("snoop: private network type %u unknown or unsupported",
+ hdr.network);
+ return -1;
+ }
+ file_encap = snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT];
+
+ /* This is a snoop file */
+ wth->file_type = WTAP_FILE_SNOOP;
} else {
if (hdr.network >= NUM_SNOOP_ENCAPS
|| snoop_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
return 1;
}
+typedef struct {
+ guint8 pad[4];
+ guint8 undecrypt[2];
+ guint8 rate;
+ guint8 preamble;
+ guint8 code;
+ guint8 signal;
+ guint8 qual;
+ guint8 channel;
+} shomiti_wireless_header;
+
+
/* Read the next packet */
static gboolean snoop_read(wtap *wth, int *err, gchar **err_info,
- long *data_offset)
+ gint64 *data_offset)
{
guint32 rec_size;
guint32 packet_size;
char padbuf[4];
guint padbytes;
int bytes_to_read;
+ int header_size;
/* Read record header. */
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
+ bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
if (bytes_read != sizeof hdr) {
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
if (*err == 0 && bytes_read != 0)
*err = WTAP_ERR_SHORT_READ;
return FALSE;
* have a pseudo-header.
*/
*err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
+ *err_info = g_strdup_printf("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header",
packet_size);
return FALSE;
}
if (!snoop_read_atm_pseudoheader(wth->fh, &wth->pseudo_header,
- err))
+ err, err_info))
return FALSE; /* Read error */
/*
* Don't count the pseudo-header as part of the packet.
*/
- rec_size -= sizeof (struct snoop_atm_hdr);
- orig_size -= sizeof (struct snoop_atm_hdr);
- packet_size -= sizeof (struct snoop_atm_hdr);
+ rec_size -= (guint32)sizeof (struct snoop_atm_hdr);
+ orig_size -= (guint32)sizeof (struct snoop_atm_hdr);
+ packet_size -= (guint32)sizeof (struct snoop_atm_hdr);
wth->data_offset += sizeof (struct snoop_atm_hdr);
break;
else
wth->pseudo_header.eth.fcs_len = 0;
break;
+
+ case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
+ if (packet_size < sizeof (shomiti_wireless_header)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header",
+ packet_size);
+ return FALSE;
+ }
+ if (!snoop_read_shomiti_wireless_pseudoheader(wth->fh,
+ &wth->pseudo_header, err, err_info, &header_size))
+ return FALSE; /* Read error */
+
+ /*
+ * Don't count the pseudo-header as part of the packet.
+ */
+ rec_size -= header_size;
+ orig_size -= header_size;
+ packet_size -= header_size;
+ wth->data_offset += header_size;
+ break;
}
buffer_assure_space(wth->frame_buffer, packet_size);
if (!snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
- packet_size, err))
+ packet_size, err, err_info))
return FALSE; /* Read error */
wth->data_offset += packet_size;
rec_size, packet_size);
return FALSE;
}
- padbytes = rec_size - (sizeof hdr + packet_size);
+ padbytes = rec_size - ((guint)sizeof hdr + packet_size);
while (padbytes != 0) {
bytes_to_read = padbytes;
if ((unsigned)bytes_to_read > sizeof padbuf)
bytes_to_read = sizeof padbuf;
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(padbuf, 1, bytes_to_read, wth->fh);
+ bytes_read = file_read(padbuf, bytes_to_read, wth->fh);
if (bytes_read != bytes_to_read) {
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
if (*err == 0)
*err = WTAP_ERR_SHORT_READ;
return FALSE;
}
static gboolean
-snoop_seek_read(wtap *wth, long seek_off,
+snoop_seek_read(wtap *wth, gint64 seek_off,
union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
- int *err, gchar **err_info _U_)
+ int *err, gchar **err_info)
{
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return FALSE;
case WTAP_ENCAP_ATM_PDUS:
if (!snoop_read_atm_pseudoheader(wth->random_fh, pseudo_header,
- err)) {
+ err, err_info)) {
/* Read error */
return FALSE;
}
else
pseudo_header->eth.fcs_len = 0;
break;
+
+ case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
+ if (!snoop_read_shomiti_wireless_pseudoheader(wth->random_fh,
+ pseudo_header, err, err_info, NULL)) {
+ /* Read error */
+ return FALSE;
+ }
+ break;
}
/*
* Read the packet data.
*/
- if (!snoop_read_rec_data(wth->random_fh, pd, length, err))
+ if (!snoop_read_rec_data(wth->random_fh, pd, length, err, err_info))
return FALSE; /* failed */
/*
static gboolean
snoop_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
- int *err)
+ int *err, gchar **err_info)
{
struct snoop_atm_hdr atm_phdr;
int bytes_read;
guint16 vci;
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&atm_phdr, 1, sizeof (struct snoop_atm_hdr), fh);
+ bytes_read = file_read(&atm_phdr, sizeof (struct snoop_atm_hdr), fh);
if (bytes_read != sizeof (struct snoop_atm_hdr)) {
- *err = file_error(fh);
+ *err = file_error(fh, err_info);
if (*err == 0)
*err = WTAP_ERR_SHORT_READ;
return FALSE;
}
static gboolean
-snoop_read_rec_data(FILE_T fh, guchar *pd, int length, int *err)
+snoop_read_shomiti_wireless_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info,
+ int *header_size)
{
+ shomiti_wireless_header whdr;
int bytes_read;
+ int rsize;
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(pd, 1, length, fh);
+ bytes_read = file_read(&whdr, sizeof (shomiti_wireless_header), fh);
+ if (bytes_read != sizeof (shomiti_wireless_header)) {
+ *err = file_error(fh, err_info);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ /* the 4th byte of the pad is actually a header length,
+ * we've already read 8 bytes of it, and it must never
+ * be less than 8.
+ *
+ * XXX - presumably that means that the header length
+ * doesn't include the length field, as we've read
+ * 12 bytes total.
+ *
+ * XXX - what's in the other 3 bytes of the padding? Is it a
+ * 4-byte length field?
+ * XXX - is there anything in the rest of the header of interest?
+ * XXX - are there any files where the header is shorter than
+ * 4 bytes of length plus 8 bytes of information?
+ */
+ if (whdr.pad[3] < 8) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("snoop: Header length in Surveyor record is %u, less than minimum of 8",
+ whdr.pad[3]);
+ return FALSE;
+ }
+ /* Skip the header. */
+ rsize = ((int) whdr.pad[3]) - 8;
+ if (file_seek(fh, rsize, SEEK_CUR, err) == -1)
+ return FALSE;
+
+ pseudo_header->ieee_802_11.fcs_len = 4;
+ pseudo_header->ieee_802_11.channel = whdr.channel;
+ pseudo_header->ieee_802_11.data_rate = whdr.rate;
+ pseudo_header->ieee_802_11.signal_level = whdr.signal;
+
+ /* add back the header and don't forget the pad as well */
+ if(header_size != NULL)
+ *header_size = rsize + 8 + 4;
+
+ return TRUE;
+}
+
+static gboolean
+snoop_read_rec_data(FILE_T fh, guchar *pd, int length, int *err,
+ gchar **err_info)
+{
+ int bytes_read;
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(pd, length, fh);
if (bytes_read != length) {
- *err = file_error(fh);
+ *err = file_error(fh, err_info);
if (*err == 0)
*err = WTAP_ERR_SHORT_READ;
return FALSE;
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean snoop_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
+gboolean snoop_dump_open(wtap_dumper *wdh, int *err)
{
struct snoop_hdr file_hdr;
- size_t nwritten;
/* This is a snoop file */
wdh->subtype_write = snoop_dump;
wdh->subtype_close = NULL;
/* Write the file header. */
- nwritten = fwrite(&snoop_magic, 1, sizeof snoop_magic, wdh->fh);
- if (nwritten != sizeof snoop_magic) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, &snoop_magic, sizeof snoop_magic, err))
return FALSE;
- }
/* current "snoop" format is 2 */
file_hdr.version = g_htonl(2);
file_hdr.network = g_htonl(wtap_encap[wdh->encap]);
- nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
- if (nwritten != sizeof file_hdr) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr, err))
return FALSE;
- }
return TRUE;
}
const guchar *pd, int *err)
{
struct snooprec_hdr rec_hdr;
- size_t nwritten;
int reclen;
guint padlen;
static char zeroes[4];
atm_hdrsize = 0;
/* Record length = header length plus data length... */
- reclen = sizeof rec_hdr + phdr->caplen + atm_hdrsize;
+ reclen = (int)sizeof rec_hdr + phdr->caplen + atm_hdrsize;
/* ... plus enough bytes to pad it to a 4-byte boundary. */
padlen = ((reclen + 3) & ~3) - reclen;
rec_hdr.cum_drops = 0;
rec_hdr.ts_sec = g_htonl(phdr->ts.secs);
rec_hdr.ts_usec = g_htonl(phdr->ts.nsecs / 1000);
- nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, wdh->fh);
- if (nwritten != sizeof rec_hdr) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof rec_hdr, err))
return FALSE;
- }
if (wdh->encap == WTAP_ENCAP_ATM_PDUS) {
/*
}
atm_hdr.vpi = (guint8) pseudo_header->atm.vpi;
atm_hdr.vci = g_htons(pseudo_header->atm.vci);
- nwritten = fwrite(&atm_hdr, 1, sizeof atm_hdr, wdh->fh);
- if (nwritten != sizeof atm_hdr) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr, err))
return FALSE;
- }
}
- nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
- if (nwritten != phdr->caplen) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
return FALSE;
- }
/* Now write the padding. */
- nwritten = fwrite(zeroes, 1, padlen, wdh->fh);
- if (nwritten != padlen) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
+ if (!wtap_dump_file_write(wdh, zeroes, padlen, err))
return FALSE;
- }
return TRUE;
}