Constify.
[obnox/wireshark/wip.git] / wiretap / netxray.c
1 /* netxray.c
2  *
3  * $Id$
4  *
5  * Wiretap Library
6  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include "wtap-int.h"
31 #include "file_wrappers.h"
32 #include "netxray.h"
33 #include "buffer.h"
34 #include "atm.h"
35
36 /* Capture file header, *including* magic number, is padded to 128 bytes. */
37 #define CAPTUREFILE_HEADER_SIZE 128
38
39 /* Magic number in NetXRay 1.x files. */
40 static const char old_netxray_magic[] = {
41         'V', 'L', '\0', '\0'
42 };
43
44 /* Magic number in NetXRay 2.0 and later, and Windows Sniffer, files. */
45 static const char netxray_magic[] = {   /* magic header */
46         'X', 'C', 'P', '\0'
47 };
48
49 /* NetXRay file header (minus magic number).                    */
50 /*                                                              */
51 /* As field usages are identified, please revise as needed      */
52 /* Please do *not* use netxray_hdr xxx... names in the code     */
53 /* (Placeholder names for all 'unknown' fields are              */
54 /*   of form xxx_x<hex_hdr_offset>                              */
55 /*   where <hex_hdr_offset> *includes* the magic number)        */
56
57 struct netxray_hdr {
58         char    version[8];     /* version number                               */
59         guint32 start_time;     /* UNIX [UTC] time when capture started         */
60
61         guint32 nframes;        /* number of packets                            */
62         guint32 xxx_x14;        /* unknown [some kind of file offset]           */
63         guint32 start_offset;   /* offset of first packet in capture            */
64         guint32 end_offset;     /* offset after last packet in capture          */
65
66         guint32 xxx_x20;        /* unknown [some kind of file offset]           */
67         guint32 xxx_x24;        /* unknown [unused ?]                           */
68         guint32 xxx_x28;        /* unknown [some kind of file offset]           */
69         guint8  network;        /* datalink type                                */
70         guint8  network_plus;   /* [See code]                                   */
71         guint8  xxx_x2E[2];     /* unknown                                      */
72
73         guint8  timeunit;       /* encodes length of a tick                     */
74         guint8  xxx_x31[3];     /* XXX - upper 3 bytes of timeunit ?            */
75         guint32 timelo;         /* lower 32 bits of capture start time stamp    */
76         guint32 timehi;         /* upper 32 bits of capture start time stamp    */
77         guint32 linespeed;      /* speed of network, in bits/second             */
78
79         guint8  xxx_x40[12];    /* unknown [other stuff]                        */
80         guint8  realtick[4];    /* (ticks/sec for Ethernet/Ndis/Timeunit=2 ?)   */
81                                 /* (realtick[1], realtick[2] also currently     */
82                                 /*  used as flag for 'FCS presence')            */
83
84         guint8  xxx_x50[4];     /* unknown [other stuff]                        */
85         guint8  captype;        /* capture type                                 */
86         guint8  xxx_x55[3];     /* unknown [other stuff]                        */
87         guint8  xxx_x58[4];     /* unknown [other stuff]                        */
88         guint8  wan_hdlc_subsub_captype; /* WAN HDLC subsub_captype             */
89         guint8  xxx_x5D[3];     /* unknown [other stuff]                        */
90
91         guint8  xxx_x60[16];    /* unknown [other stuff]                        */
92
93         guint8  xxx_x70[14];    /* unknown [other stuff]                        */
94         gint16 timezone_hrs;    /* timezone hours [at least for version 2.2..]; */
95                                 /*  positive values = west of UTC:              */
96                                 /*  negative values = east of UTC:              */
97                                 /*  e.g. +5 is American Eastern                 */
98                                 /* [Does not appear to be adjusted for DST ]    */
99 };
100
101 /*
102  * Capture type, in hdr.captype.
103  *
104  * Values other than 0 are dependent on the network type.
105  * For Ethernet captures, it indicates the type of capture pod.
106  * For WAN captures (all of which are done with a pod), it indicates
107  * the link-layer type.
108  */
109 #define CAPTYPE_NDIS    0               /* Capture on network interface using NDIS                      */
110
111 /*
112  * Ethernet capture types.
113  */
114 #define ETH_CAPTYPE_GIGPOD      2       /* gigabit Ethernet captured with pod                           */
115 #define ETH_CAPTYPE_OTHERPOD    3       /* non-gigabit Ethernet captured with pod                       */
116 #define ETH_CAPTYPE_OTHERPOD2   5       /* gigabit Ethernet via pod ??                                  */
117                                         /*  Captype 5 seen in capture from Distributed Sniffer with:    */
118                                         /*    Version 4.50.211 software                                 */
119                                         /*    SysKonnect SK-9843 Gigabit Ethernet Server Adapter        */
120 #define ETH_CAPTYPE_GIGPOD2     6       /* gigabit Ethernet, captured with blade on S6040-model Sniffer */
121
122 /*
123  * WAN capture types.
124  */
125 #define WAN_CAPTYPE_BROUTER     1       /* Bridge/router captured with pod */
126 #define WAN_CAPTYPE_PPP         3       /* PPP captured with pod */
127 #define WAN_CAPTYPE_FRELAY      4       /* Frame Relay captured with pod */
128 #define WAN_CAPTYPE_BROUTER2    5       /* Bridge/router captured with pod */
129 #define WAN_CAPTYPE_HDLC        6       /* HDLC (X.25, ISDN) captured with pod */
130 #define WAN_CAPTYPE_SDLC        7       /* SDLC captured with pod */
131 #define WAN_CAPTYPE_HDLC2       8       /* HDLC captured with pod */
132 #define WAN_CAPTYPE_BROUTER3    9       /* Bridge/router captured with pod */
133 #define WAN_CAPTYPE_SMDS        10      /* SMDS DXI */
134 #define WAN_CAPTYPE_BROUTER4    11      /* Bridge/router captured with pod */
135 #define WAN_CAPTYPE_BROUTER5    12      /* Bridge/router captured with pod */
136 #define WAN_CAPTYPE_CHDLC       19      /* Cisco router (CHDLC) captured with pod */
137
138 #define CAPTYPE_ATM             15      /* ATM captured with pod */
139
140 /*
141  * # of ticks that equal 1 second, in version 002.xxx files other
142  * than Ethernet captures with a captype other than CAPTYPE_NDIS;
143  * the index into this array is hdr.timeunit.
144  *
145  * DO NOT SEND IN PATCHES THAT CHANGE ANY OF THE NON-ZERO VALUES IN
146  * ANY OF THE TpS TABLES.  THOSE VALUES ARE CORRECT FOR AT LEAST ONE
147  * CAPTURE, SO CHANGING THEM WILL BREAK AT LEAST SOME CAPTURES.  WE
148  * WILL NOT CHECK IN PATCHES THAT CHANGE THESE VALUES.
149  *
150  * Instead, if a value in a TpS table is wrong, check whether captype
151  * has a non-zero value; if so, perhaps we need a new TpS table for the
152  * corresponding network type and captype, or perhaps the 'realtick'
153  * field contains the correct ticks-per-second value.
154  *
155  * TpS...[] entries of 0.0 mean that no capture file for the
156  * corresponding captype/timeunit values has yet been seen, or that
157  * we're using the 'realtick' value.
158  *
159  * XXX - 05/29/07: For Ethernet captype = 0 (NDIS) and timeunit = 2:
160  *  Perusal of a number of Sniffer captures
161  *  (including those from Wireshark bug reports
162  *  and those from the Wireshark 'menagerie)
163  *  suggests that 'realtick' for this case
164  *  contains the correct ticks/second to be used.
165  *  So: we'll use realtick for Ethernet captype=0 and timeunit=2.
166  *  (It might be that realtick should be used for Ethernet captype = 0 
167  *  and timeunit = 1 but I've not yet enough captures to be sure).
168  *   Based upon the captures reviewed to date, realtick cannot be used for
169  *   any of the other Ethernet captype/timeunit combinations for which there
170  *   are non-zero values in the TpS tables.
171  *
172  *  In at least one capture where "realtick" doesn't correspond
173  *  to the value from the appropriate TpS table, the per-packet header's
174  *  "xxx" field is all zero, so it's not as if a 2.x header includes
175  *  a "compatibility" time stamp corresponding to the value from the
176  *  TpS table and a "real" time stamp corresponding to "realtick".
177  *
178  * XXX - the item corresponding to timeunit = 2 is 1193180.0, presumably
179  *  because somebody found it gave the right answer for some captures, but
180  *  3 times that, i.e. 3579540.0, appears to give the right answer for some
181  *  other captures.
182  *
183  *  Some captures have realtick of 1193182, some have 3579545, and some
184  *  have 1193000.  Most of those, in one set of captures somebody has,
185  *  are wrong.  (Did that mean "wrong for some capture files, but not
186  *  for the files in which they occurred", or "wrong for the files in
187  *  which they occurred?  If it's "wrong for some capture files, but
188  *  not for the files in which they occurred", perhaps those were Ethernet
189  *  captures with a captype of 0 and timeunit = 2, so that we now use
190  *  realtick, and perhaps that fixes the problems.)
191  *
192  * XXX - in at least one ATM capture, hdr.realtick is 1193180.0
193  *  and hdr.timeunit is 0.  Does that capture have a captype of
194  *  CAPTYPE_ATM?  If so, what should the table for ATM captures with
195  *  that captype be?
196  */
197 static const double TpS[] = { 1e6, 1193000.0, 1193182.0 };
198 #define NUM_NETXRAY_TIMEUNITS (sizeof TpS / sizeof TpS[0])
199
200 /*
201  * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD.
202  * 0.0 means "unknown".
203  *
204  * It appears that, at least for Ethernet captures, if captype is
205  * ETH_CAPTYPE_GIGPOD, that indicates that it's a gigabit Ethernet
206  * capture, possibly from a special whizzo gigabit pod, and also
207  * indicates that the time stamps have some higher resolution than
208  * in other captures, possibly thanks to a high-resolution timer
209  * on the pod.
210  *
211  * It also appears that the time units might differ for gigabit pod
212  * captures between version 002.001 and 002.002.  For 002.001,
213  * the values below are correct; for 002.002, it's claimed that
214  * the right value for TpS_gigpod[2] is 1250000.0, but at least one
215  * 002.002 gigabit pod capture has 31250000.0 as the right value.
216  * XXX: Note that the TpS_otherpod[2] value is 1250000.0; It seems
217  *  reasonable to suspect that the original claim might actually 
218  *  have been for a capture with a captype of 'otherpod'.
219  * (Based upon captures reviewed realtick does not contain the 
220  *   correct TpS values for the 'gigpod' captype).
221  */
222 static const double TpS_gigpod[] = { 1e9, 0.0, 31250000.0 };
223 #define NUM_NETXRAY_TIMEUNITS_GIGPOD (sizeof TpS_gigpod / sizeof TpS_gigpod[0])
224
225 /*
226  * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD.
227  *  (Based upon captures reviewed realtick does not contain the 
228  *   correct TpS values for the 'otherpod' captype).
229  */
230 static const double TpS_otherpod[] = { 1e6, 0.0, 1250000.0 }; 
231 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD (sizeof TpS_otherpod / sizeof TpS_otherpod[0])
232
233 /*
234  * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD2.
235  * (Based upon captures reviewed realtick does not contain the 
236  *   correct TpS values for the 'otherpod2' captype).
237  */
238 static const double TpS_otherpod2[] = { 1e6, 0.0, 0.0 }; 
239 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD2 (sizeof TpS_otherpod2 / sizeof TpS_otherpod2[0])
240
241 /*
242  * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD2. 
243  * (Based upon captures reviewed realtick does not contain the 
244  *   correct TpS values for the 'gigpod2' captype).
245  */
246 static const double TpS_gigpod2[] = { 1e9, 0.0, 20000000.0 };
247 #define NUM_NETXRAY_TIMEUNITS_GIGPOD2 (sizeof TpS_gigpod2 / sizeof TpS_gigpod2[0])
248
249 /* Version number strings. */
250 static const char vers_1_0[] = {
251         '0', '0', '1', '.', '0', '0', '0', '\0'
252 };
253
254 static const char vers_1_1[] = {
255         '0', '0', '1', '.', '1', '0', '0', '\0'
256 };
257
258 static const char vers_2_000[] = {
259         '0', '0', '2', '.', '0', '0', '0', '\0'
260 };
261
262 static const char vers_2_001[] = {
263         '0', '0', '2', '.', '0', '0', '1', '\0'
264 };
265
266 static const char vers_2_002[] = {
267         '0', '0', '2', '.', '0', '0', '2', '\0'
268 };
269
270 static const char vers_2_003[] = {
271         '0', '0', '2', '.', '0', '0', '3', '\0'
272 };
273
274 /* Old NetXRay data record format - followed by frame data. */
275 struct old_netxrayrec_hdr {
276         guint32 timelo;         /* lower 32 bits of time stamp */
277         guint32 timehi;         /* upper 32 bits of time stamp */
278         guint16 len;            /* packet length */
279         guint8  xxx[6];         /* unknown */
280 };
281
282 /* NetXRay format version 1.x data record format - followed by frame data. */
283 struct netxrayrec_1_x_hdr {
284         guint32 timelo;         /* lower 32 bits of time stamp */
285         guint32 timehi;         /* upper 32 bits of time stamp */
286         guint16 orig_len;       /* packet length */
287         guint16 incl_len;       /* capture length */
288         guint8  xxx[16];        /* unknown */
289 };
290
291 /* NetXRay format version 2.x data record format - followed by frame data. */
292 struct netxrayrec_2_x_hdr {
293         guint32 timelo;         /* lower 32 bits of time stamp */
294         guint32 timehi;         /* upper 32 bits of time stamp */
295         guint16 orig_len;       /* packet length */
296         guint16 incl_len;       /* capture length */
297         guint8  xxx[28];        /* various data */
298 };
299
300 /*
301  * Union of the data record headers.
302  */
303 union netxrayrec_hdr {
304         struct old_netxrayrec_hdr old_hdr;
305         struct netxrayrec_1_x_hdr hdr_1_x;
306         struct netxrayrec_2_x_hdr hdr_2_x;
307 };
308
309 typedef struct {
310         time_t          start_time;
311         double          ticks_per_sec;
312         double          start_timestamp;
313         gboolean        wrapped;
314         guint32         nframes;
315         gint64          start_offset;
316         gint64          end_offset;
317         int             version_major;
318         gboolean        fcs_valid;      /* if packets have valid FCS at the end */
319         guint           isdn_type;      /* 1 = E1 PRI, 2 = T1 PRI, 3 = BRI */
320 } netxray_t;
321
322 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
323     gint64 *data_offset);
324 static gboolean netxray_seek_read(wtap *wth, gint64 seek_off,
325     union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
326     int *err, gchar **err_info);
327 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
328     union netxrayrec_hdr *hdr, int *err);
329 static guint netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
330     union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr);
331 static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr,
332     guint32 packet_size, int *err);
333 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
334     const struct wtap_pkthdr *phdr,
335     const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
336 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
337 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
338     const struct wtap_pkthdr *phdr,
339     const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
340 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
341
342 int netxray_open(wtap *wth, int *err, gchar **err_info)
343 {
344         int bytes_read;
345         char magic[sizeof netxray_magic];
346         gboolean is_old;
347         struct netxray_hdr hdr;
348         guint network_type;
349         double ticks_per_sec;
350         int version_major, version_minor;
351         int file_type;
352         double start_timestamp;
353         static const int netxray_encap[] = {
354                 WTAP_ENCAP_UNKNOWN,
355                 WTAP_ENCAP_ETHERNET,
356                 WTAP_ENCAP_TOKEN_RING,
357                 WTAP_ENCAP_FDDI_BITSWAPPED,
358                 /*
359                  * XXX - some PPP captures may look like Ethernet,
360                  * perhaps because they're using NDIS to capture on the
361                  * same machine and it provides simulated-Ethernet
362                  * packets, but captures taken with various serial
363                  * pods use the same network type value but aren't
364                  * shaped like Ethernet.  We handle that below.
365                  */
366                 WTAP_ENCAP_ETHERNET,            /* WAN(PPP), but shaped like Ethernet */
367                 WTAP_ENCAP_UNKNOWN,             /* LocalTalk */
368                 WTAP_ENCAP_UNKNOWN,             /* "DIX" - should not occur */
369                 WTAP_ENCAP_UNKNOWN,             /* ARCNET raw */
370                 WTAP_ENCAP_UNKNOWN,             /* ARCNET 878.2 */
371                 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,/* ATM */
372                 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
373                                                 /* Wireless WAN with radio information */
374                 WTAP_ENCAP_UNKNOWN              /* IrDA */
375         };
376         #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
377         int file_encap;
378         guint isdn_type = 0;
379         netxray_t *netxray;
380
381         /* Read in the string that should be at the start of a NetXRay
382          * file */
383         errno = WTAP_ERR_CANT_READ;
384         bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
385         if (bytes_read != sizeof magic) {
386                 *err = file_error(wth->fh);
387                 if (*err != 0)
388                         return -1;
389                 return 0;
390         }
391         wth->data_offset += sizeof magic;
392
393         if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
394                 is_old = FALSE;
395         } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
396                 is_old = TRUE;
397         } else {
398                 return 0;
399         }
400
401         /* Read the rest of the header. */
402         errno = WTAP_ERR_CANT_READ;
403         bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
404         if (bytes_read != sizeof hdr) {
405                 *err = file_error(wth->fh);
406                 if (*err != 0)
407                         return -1;
408                 return 0;
409         }
410         wth->data_offset += sizeof hdr;
411
412         if (is_old) {
413                 version_major = 0;
414                 version_minor = 0;
415                 file_type = WTAP_FILE_NETXRAY_OLD;
416         } else {
417                 /* It appears that version 1.1 files (as produced by Windows
418                  * Sniffer Pro 2.0.01) have the time stamp in microseconds,
419                  * rather than the milliseconds version 1.0 files appear to
420                  * have.
421                  *
422                  * It also appears that version 2.00x files have per-packet
423                  * headers with some extra fields. */
424                 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
425                         version_major = 1;
426                         version_minor = 0;
427                         file_type = WTAP_FILE_NETXRAY_1_0;
428                 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
429                         version_major = 1;
430                         version_minor = 1;
431                         file_type = WTAP_FILE_NETXRAY_1_1;
432                 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
433                         version_major = 2;
434                         version_minor = 0;
435                         file_type = WTAP_FILE_NETXRAY_2_00x;
436                 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
437                         version_major = 2;
438                         version_minor = 1;
439                         file_type = WTAP_FILE_NETXRAY_2_00x;
440                 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
441                         version_major = 2;
442                         version_minor = 2;
443                         file_type = WTAP_FILE_NETXRAY_2_00x;
444                 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
445                         version_major = 2;
446                         version_minor = 3;
447                         file_type = WTAP_FILE_NETXRAY_2_00x;
448                 } else {
449                         *err = WTAP_ERR_UNSUPPORTED;
450                         *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
451                         return -1;
452                 }
453         }
454
455         switch (hdr.network_plus) {
456
457         case 0:
458                 /*
459                  * The byte after hdr.network is usually 0, in which case
460                  * the hdr.network byte is an NDIS network type value - 1.
461                  */
462                 network_type = hdr.network + 1;
463                 break;
464
465         case 2:
466                 /*
467                  * However, in some Ethernet captures, it's 2, and the
468                  * hdr.network byte is 1 rather than 0.  We assume
469                  * that if there's a byte after hdr.network with the value
470                  * 2, the hdr.network byte is an NDIS network type, rather
471                  * than an NDIS network type - 1.
472                  */
473                 network_type = hdr.network;
474                 break;
475
476         default:
477                 *err = WTAP_ERR_UNSUPPORTED;
478                 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
479                     hdr.network_plus);
480                 return -1;
481         }
482
483         if (network_type >= NUM_NETXRAY_ENCAPS
484             || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
485                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
486                 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
487                     network_type, hdr.network_plus);
488                 return -1;
489         }
490
491         /*
492          * Figure out the time stamp units and start time stamp.
493          */
494         start_timestamp = (double)pletohl(&hdr.timelo)
495             + (double)pletohl(&hdr.timehi)*4294967296.0;
496         switch (file_type) {
497
498         case WTAP_FILE_NETXRAY_OLD:
499                 ticks_per_sec = 1000.0;
500                 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
501                 break;
502
503         case WTAP_FILE_NETXRAY_1_0:
504                 ticks_per_sec = 1000.0;
505                 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
506                 break;
507
508         case WTAP_FILE_NETXRAY_1_1:
509                 /*
510                  * In version 1.1 files (as produced by Windows Sniffer
511                  * Pro 2.0.01), the time stamp is in microseconds,
512                  * rather than the milliseconds time stamps in NetXRay
513                  * and older versions of Windows Sniffer.
514                  */
515                 ticks_per_sec = 1000000.0;
516                 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
517                 break;
518
519         case WTAP_FILE_NETXRAY_2_00x:
520                 /*
521                  * Get the time stamp units from the appropriate TpS
522                  * table or from the file header.
523                  */
524                 switch (network_type) {
525
526                 case 1:
527                         /*
528                          * Ethernet - the table to use depends on whether
529                          * this is an NDIS or pod capture.
530                          */
531                         switch (hdr.captype) {
532
533                         case CAPTYPE_NDIS:
534                                 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
535                                         *err = WTAP_ERR_UNSUPPORTED;
536                                         *err_info = g_strdup_printf(
537                                             "netxray: Unknown timeunit %u for Ethernet/CAPTYPE_NDIS version %.8s capture",
538                                             hdr.timeunit, hdr.version);
539                                         return -1;
540                                 }
541                                 /* 
542                                 XXX: 05/29/07: Use 'realtick' instead of TpS table if timeunit=2;
543                                         Using 'realtick' in this case results
544                                         in the correct 'ticks per second' for all the captures that 
545                                         I have of this type (including captures from a number of Wirshark
546                                         bug reports).
547                                 */
548                                 if (hdr.timeunit == 2) {
549                                         ticks_per_sec = pletohl(hdr.realtick);
550                                 }
551                                 else {
552                                         ticks_per_sec = TpS[hdr.timeunit];
553                                 }
554                                 break;
555
556                         case ETH_CAPTYPE_GIGPOD:
557                                 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD
558                                     || TpS_gigpod[hdr.timeunit] == 0.0) {
559                                         *err = WTAP_ERR_UNSUPPORTED;
560                                         *err_info = g_strdup_printf(
561                                             "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD version %.8s capture",
562                                             hdr.timeunit, hdr.version);
563                                         return -1;
564                                 }
565                                 ticks_per_sec = TpS_gigpod[hdr.timeunit];
566
567                                 /*
568                                  * At least for 002.002 and 002.003
569                                  * captures, the start time stamp is 0,
570                                  * not the value in the file.
571                                  */
572                                 if (version_minor == 2 || version_minor == 3)
573                                         start_timestamp = 0.0;
574                                 break;
575
576                         case ETH_CAPTYPE_OTHERPOD:
577                                 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD
578                                     || TpS_otherpod[hdr.timeunit] == 0.0) {
579                                         *err = WTAP_ERR_UNSUPPORTED;
580                                         *err_info = g_strdup_printf(
581                                             "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD version %.8s capture",
582                                             hdr.timeunit, hdr.version);
583                                         return -1;
584                                 }
585                                 ticks_per_sec = TpS_otherpod[hdr.timeunit];
586
587                                 /*
588                                  * At least for 002.002 and 002.003
589                                  * captures, the start time stamp is 0,
590                                  * not the value in the file.
591                                  */
592                                 if (version_minor == 2 || version_minor == 3)
593                                         start_timestamp = 0.0;
594                                 break;
595
596                         case ETH_CAPTYPE_OTHERPOD2:
597                                 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD2
598                                     || TpS_otherpod2[hdr.timeunit] == 0.0) {
599                                         *err = WTAP_ERR_UNSUPPORTED;
600                                         *err_info = g_strdup_printf(
601                                             "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD2 version %.8s capture",
602                                             hdr.timeunit, hdr.version);
603                                         return -1;
604                                 }
605                                 ticks_per_sec = TpS_otherpod2[hdr.timeunit];
606                                 /*
607                                  * XXX: start time stamp in the one capture file examined of this type was 0;
608                                  *      We'll assume the start time handling is the same as for other pods.
609                                  *
610                                  * At least for 002.002 and 002.003
611                                  * captures, the start time stamp is 0,
612                                  * not the value in the file.
613                                  */
614                                 if (version_minor == 2 || version_minor == 3)
615                                         start_timestamp = 0.0;
616                                 break;
617
618                         case ETH_CAPTYPE_GIGPOD2:
619                                 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD2
620                                     || TpS_gigpod2[hdr.timeunit] == 0.0) {
621                                         *err = WTAP_ERR_UNSUPPORTED;
622                                         *err_info = g_strdup_printf(
623                                             "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD2 version %.8s capture",
624                                             hdr.timeunit, hdr.version);
625                                         return -1;
626                                 }
627                                 ticks_per_sec = TpS_gigpod2[hdr.timeunit];
628                                 /*
629                                  * XXX: start time stamp in the one capture file examined of this type was 0;
630                                  *      We'll assume the start time handling is the same as for other pods.
631                                  *
632                                  * At least for 002.002 and 002.003
633                                  * captures, the start time stamp is 0,
634                                  * not the value in the file.
635                                  */
636                                 if (version_minor == 2 || version_minor == 3)
637                                         start_timestamp = 0.0;
638                                 break;
639
640                         default:
641                                 *err = WTAP_ERR_UNSUPPORTED;
642                                 *err_info = g_strdup_printf(
643                                     "netxray: Unknown capture type %u for Ethernet version %.8s capture",
644                                     hdr.captype, hdr.version);
645                                 return -1;
646                         }
647                         break;
648
649                 default:
650                         if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
651                                 *err = WTAP_ERR_UNSUPPORTED;
652                                 *err_info = g_strdup_printf(
653                                     "netxray: Unknown timeunit %u for %u/%u version %.8s capture",
654                                     hdr.timeunit, network_type, hdr.captype,
655                                     hdr.version);
656                                 return -1;
657                         }
658                         ticks_per_sec = TpS[hdr.timeunit];
659                         break;
660                 }
661
662                 /*
663                  * If the number of ticks per second is greater than
664                  * 1 million, make the precision be nanoseconds rather
665                  * than microseconds.
666                  *
667                  * XXX - do values only slightly greater than one million
668                  * correspond to a resolution sufficiently better than
669                  * 1 microsecond to display more digits of precision?
670                  * XXX - Seems reasonable to use nanosecs only if TPS >= 10M
671                  */
672                 if (ticks_per_sec >= 1e7)
673                         wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
674                 else
675                         wth->tsprecision = WTAP_FILE_TSPREC_USEC;
676                 break;
677
678         default:
679                 g_assert_not_reached();
680                 ticks_per_sec = 0.0;
681         }
682         start_timestamp = start_timestamp/ticks_per_sec;
683
684         if (network_type == 4) {
685                 /*
686                  * In version 0 and 1, we assume, for now, that all
687                  * WAN captures have frames that look like Ethernet
688                  * frames (as a result, presumably, of having passed
689                  * through NDISWAN).
690                  *
691                  * In version 2, it looks as if there's stuff in the 
692                  * file header to specify what particular type of WAN
693                  * capture we have.
694                  */
695                 if (version_major == 2) {
696                         switch (hdr.captype) {
697
698                         case WAN_CAPTYPE_PPP:
699                                 /*
700                                  * PPP.
701                                  */
702                                 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
703                                 break;
704
705                         case WAN_CAPTYPE_FRELAY:
706                                 /*
707                                  * Frame Relay.
708                                  *
709                                  * XXX - in at least one capture, this
710                                  * is Cisco HDLC, not Frame Relay, but
711                                  * in another capture, it's Frame Relay.
712                                  *
713                                  * [Bytes in each capture:
714                                  * Cisco HDLC:  hdr.xxx_x60[06:10]: 0x02 0x00 0x01 0x00 0x06
715                                  * Frame Relay: hdr.xxx_x60[06:10]  0x00 0x00 0x00 0x00 0x00
716
717                                  * Cisco HDLC:  hdr.xxx_x60[14:15]: 0xff 0xff
718                                  * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
719                                  * ]
720                                  */
721                                 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
722                                 break;
723
724                         case WAN_CAPTYPE_HDLC:
725                         case WAN_CAPTYPE_HDLC2:
726                                 /*
727                                  * Various HDLC flavors?
728                                  */
729                                 switch (hdr.wan_hdlc_subsub_captype) {
730
731                                 case 0: /* LAPB/X.25 */
732                                         file_encap = WTAP_ENCAP_LAPB;
733                                         break;
734
735                                 case 1: /* E1 PRI */
736                                 case 2: /* T1 PRI */
737                                 case 3: /* BRI */
738                                         file_encap = WTAP_ENCAP_ISDN;
739                                         isdn_type = hdr.wan_hdlc_subsub_captype;
740                                         break;
741
742                                 default:
743                                         *err = WTAP_ERR_UNSUPPORTED_ENCAP;
744                                         *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
745                                            hdr.wan_hdlc_subsub_captype);
746                                         return -1;
747                                 }
748                                 break;
749
750                         case WAN_CAPTYPE_SDLC:
751                                 /*
752                                  * SDLC.
753                                  */
754                                 file_encap = WTAP_ENCAP_SDLC;
755                                 break;
756
757                         case WAN_CAPTYPE_CHDLC:
758                                 /*
759                                  *  Cisco router (CHDLC) captured with pod
760                                  */
761                                 file_encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
762                                 break;
763
764                         default:
765                                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
766                                 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
767                                    hdr.captype);
768                                 return -1;
769                         }
770                 } else
771                         file_encap = WTAP_ENCAP_ETHERNET;
772         } else
773                 file_encap = netxray_encap[network_type];
774
775         /* This is a netxray file */
776         wth->file_type = file_type;
777         netxray = (netxray_t *)g_malloc(sizeof(netxray_t));
778         wth->priv = (void *)netxray;
779         wth->subtype_read = netxray_read;
780         wth->subtype_seek_read = netxray_seek_read;
781         wth->file_encap = file_encap;
782         wth->snapshot_length = 0;       /* not available in header */
783         netxray->start_time = pletohl(&hdr.start_time);
784         netxray->ticks_per_sec = ticks_per_sec;
785         netxray->start_timestamp = start_timestamp;
786         netxray->version_major = version_major;
787
788         /*
789          * If frames have an extra 4 bytes of stuff at the end, is
790          * it an FCS, or just junk?
791          */
792         netxray->fcs_valid = FALSE;
793         switch (file_encap) {
794
795         case WTAP_ENCAP_ETHERNET:
796         case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
797         case WTAP_ENCAP_ISDN:
798         case WTAP_ENCAP_LAPB:
799                 /*
800                  * It appears that, in at least some version 2 Ethernet
801                  * captures, for frames that have 0xff in hdr_2_x.xxx[2]
802                  * and hdr_2_x.xxx[3] in the per-packet header:
803                  *
804                  *      if, in the file header, hdr.realtick[1] is 0x34
805                  *      and hdr.realtick[2] is 0x12, the frames have an
806                  *      FCS at the end;
807                  *
808                  *      otherwise, they have 4 bytes of junk at the end.
809                  *
810                  * Yes, it's strange that you have to check the *middle*
811                  * of the time stamp field; you can't check for any
812                  * particular value of the time stamp field.
813                  *
814                  * For now, we assume that to be true for 802.11 captures
815                  * as well; it appears to be the case for at least one
816                  * such capture - the file doesn't have 0x34 and 0x12,
817                  * and the 4 bytes at the end of the frames with 0xff
818                  * are junk, not an FCS.
819                  *
820                  * For ISDN captures, it appears, at least in some
821                  * captures, to be similar, although I haven't yet
822                  * checked whether it's a valid FCS.
823                  *
824                  * XXX - should we do this for all encapsulation types?
825                  *
826                  * XXX - is there some other field that *really* indicates
827                  * whether we have an FCS or not?  The check of the time
828                  * stamp is bizarre, as we're checking the middle.
829                  * Perhaps hdr.realtick[0] is 0x00, in which case time
830                  * stamp units in the range 1192960 through 1193215
831                  * correspond to captures with an FCS, but that's still
832                  * a bit bizarre.
833                  *
834                  * Note that there are captures with a network type of 0
835                  * (Ethernet) and capture type of 0 (NDIS) that do, and
836                  * that don't, have 0x34 0x12 in them, and at least one
837                  * of the NDIS captures with 0x34 0x12 in it has FCSes,
838                  * so it's not as if no NDIS captures have an FCS.
839                  *
840                  * There are also captures with a network type of 4 (WAN),
841                  * capture type of 6 (HDLC), and subtype of 2 (T1 PRI) that
842                  * do, and that don't, have 0x34 0x12, so there are at least
843                  * some captures taken with a WAN pod that might lack an FCS.
844                  * (We haven't yet tried dissecting the 4 bytes at the
845                  * end of packets with hdr_2_x.xxx[2] and hdr_2_x.xxx[3]
846                  * equal to 0xff as an FCS.)
847                  *
848                  * All captures I've seen that have 0x34 and 0x12 *and*
849                  * have at least one frame with an FCS have a value of
850                  * 0x01 in xxx_x40[4].  No captures I've seen with a network
851                  * type of 0 (Ethernet) missing 0x34 0x12 have 0x01 there,
852                  * however.  However, there's at least one capture
853                  * without 0x34 and 0x12, with a network type of 0,
854                  * and with 0x01 in xxx_x40[4], *without* FCSes in the
855                  * frames - the 4 bytes at the end are all zero - so it's
856                  * not as simple as "xxx_x40[4] = 0x01 means the 4 bytes at
857                  * the end are FCSes".  Also, there's also at least one
858                  * 802.11 capture with an xxx_x40[4] value of 0x01 with junk
859                  * rather than an FCS at the end of the frame, so xxx_x40[4]
860                  * isn't an obvious flag to determine whether the
861                  * capture has FCSes.
862                  *
863                  * There don't seem to be any other values in any of the
864                  * xxx_x5..., xxx_x6...., xxx_x7.... fields
865                  * that obviously correspond to frames having an FCS.
866                  *
867                  * 05/29/07: Examination of numerous sniffer captures suggests
868                  *            that the apparent correlation of certain realtick 
869                  *            bytes to 'FCS presence' may actually be 
870                  *            a 'false positive'.
871                  *           ToDo: Review analysis and update code.
872                  *           It might be that the ticks-per-second value
873                  *           is hardware-dependent, and that hardware with
874                  *           a particular realtick value puts an FCS there
875                  *           and other hardware doesn't.
876                  */
877                 if (version_major == 2) {
878                         if (hdr.realtick[1] == 0x34 && hdr.realtick[2] == 0x12)
879                                 netxray->fcs_valid = TRUE;
880                 }
881                 break;
882         }
883
884         /*
885          * Remember the ISDN type, as we need it to interpret the
886          * channel number in ISDN captures.
887          */
888         netxray->isdn_type = isdn_type;
889
890         /* Remember the offset after the last packet in the capture (which
891          * isn't necessarily the last packet in the file), as it appears
892          * there's sometimes crud after it.
893          * XXX: Remember 'start_offset' to help testing for 'short file' at EOF
894          */
895         netxray->wrapped      = FALSE;
896         netxray->nframes      = pletohl(&hdr.nframes);
897         netxray->start_offset = pletohl(&hdr.start_offset);
898         netxray->end_offset   = pletohl(&hdr.end_offset);
899
900         /* Seek to the beginning of the data records. */
901         if (file_seek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET, err) == -1) {
902                 g_free(netxray);
903                 return -1;
904         }
905         wth->data_offset = pletohl(&hdr.start_offset);
906
907         return 1;
908 }
909
910 /* Read the next packet */
911 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info _U_,
912     gint64 *data_offset)
913 {
914         netxray_t *netxray = (netxray_t *)wth->priv;
915         guint32 packet_size;
916         union netxrayrec_hdr hdr;
917         int     hdr_size;
918         double  t;
919         guint8  *pd;
920         guint   padding;
921
922 reread:
923         /* Have we reached the end of the packet data? */
924         if (wth->data_offset == netxray->end_offset) {
925                 /* Yes. */
926                 *err = 0;       /* it's just an EOF, not an error */
927                 return FALSE;
928         }
929         /* Read record header. */
930         hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err);
931         if (hdr_size == 0) {
932                 /*
933                  * Error or EOF.
934                  */
935                 if (*err != 0) {
936                         /*
937                          * Error of some sort; give up.
938                          */
939                         return FALSE;
940                 }
941
942                 /* We're at EOF.  Wrap?
943                  * XXX: Need to handle 'short file' cases
944                  *      (Distributed Sniffer seems to have a 
945                  *       certain small propensity to generate 'short' files
946                  *       i.e. [many] bytes are missing from the end of the file)
947                  *   case 1: start_offset < end_offset 
948                  *           wrap will read already read packets again;
949                  *           so: error with "short file"
950                  *   case 2: start_offset > end_offset ("circular" file)
951                  *           wrap will mean there's a gap (missing packets).
952                  *           However, I don't see a good way to identify this
953                  *           case so we'll just have to allow the wrap.
954                  *           (Maybe there can be an error message after all
955                  *            packets are read since there'll be less packets than
956                  *            specified in the file header).
957                  * Note that these cases occur *only* if a 'short' eof occurs exactly 
958                  * at the expected beginning of a frame header record; If there is a
959                  * partial frame header (or partial frame data) record, then the
960                  * netxray_read... functions will detect the short record.
961                  */
962                 if (netxray->start_offset < netxray->end_offset) {
963                         *err = WTAP_ERR_SHORT_READ;
964                         return FALSE;
965                 }
966                 
967                 if (!netxray->wrapped) {
968                         /* Yes.  Remember that we did. */
969                         netxray->wrapped = TRUE;
970                         if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
971                             SEEK_SET, err) == -1)
972                                 return FALSE;
973                         wth->data_offset = CAPTUREFILE_HEADER_SIZE;
974                         goto reread;
975                 }
976
977                 /* We've already wrapped - don't wrap again. */
978                 return FALSE;
979         }
980
981         /*
982          * Return the offset of the record header, so we can reread it
983          * if we go back to this frame.
984          */
985         *data_offset = wth->data_offset;
986         wth->data_offset += hdr_size;
987
988         /*
989          * Read the packet data.
990          */
991         if (netxray->version_major == 0)
992                 packet_size = pletohs(&hdr.old_hdr.len);
993         else
994                 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
995         buffer_assure_space(wth->frame_buffer, packet_size);
996         pd = buffer_start_ptr(wth->frame_buffer);
997         if (!netxray_read_rec_data(wth->fh, pd, packet_size, err))
998                 return FALSE;
999         wth->data_offset += packet_size;
1000
1001         /*
1002          * Set the pseudo-header.
1003          */
1004         padding = netxray_set_pseudo_header(wth, pd, packet_size,
1005             &wth->pseudo_header, &hdr);
1006
1007         if (netxray->version_major == 0) {
1008                 t = (double)pletohl(&hdr.old_hdr.timelo)
1009                     + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
1010                 t /= netxray->ticks_per_sec;
1011                 t -= netxray->start_timestamp;
1012                 wth->phdr.ts.secs = netxray->start_time + (long)t;
1013                 wth->phdr.ts.nsecs = (int)((t-(double)(unsigned long)(t))
1014                         *1.0e9);
1015                 /*
1016                  * We subtract the padding from the packet size, so our caller
1017                  * doesn't see it.
1018                  */
1019                 wth->phdr.caplen = packet_size - padding;
1020                 wth->phdr.len = wth->phdr.caplen;
1021         } else {
1022                 t = (double)pletohl(&hdr.hdr_1_x.timelo)
1023                     + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
1024                 t /= netxray->ticks_per_sec;
1025                 t -= netxray->start_timestamp;
1026                 wth->phdr.ts.secs = netxray->start_time + (time_t)t;
1027                 wth->phdr.ts.nsecs = (int)((t-(double)(unsigned long)(t))
1028                         *1.0e9);
1029                 /*
1030                  * We subtract the padding from the packet size, so our caller
1031                  * doesn't see it.
1032                  */
1033                 wth->phdr.caplen = packet_size - padding;
1034                 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
1035         }
1036
1037         return TRUE;
1038 }
1039
1040 static gboolean
1041 netxray_seek_read(wtap *wth, gint64 seek_off,
1042     union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
1043     int *err, gchar **err_info _U_)
1044 {
1045         union netxrayrec_hdr hdr;
1046         gboolean ret;
1047
1048         if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1049                 return FALSE;
1050
1051         if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) {
1052                 if (*err == 0) {
1053                         /*
1054                          * EOF - we report that as a short read, as
1055                          * we've read this once and know that it
1056                          * should be there.
1057                          */
1058                         *err = WTAP_ERR_SHORT_READ;
1059                 }
1060                 return FALSE;
1061         }
1062
1063         /*
1064          * Read the packet data.
1065          */
1066         ret = netxray_read_rec_data(wth->random_fh, pd, length, err);
1067         if (!ret)
1068                 return FALSE;
1069
1070         /*
1071          * Set the pseudo-header.
1072          */
1073         netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1074         return TRUE;
1075 }
1076
1077 static int
1078 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1079     int *err)
1080 {
1081         netxray_t *netxray = (netxray_t *)wth->priv;
1082         int     bytes_read;
1083         int     hdr_size = 0;
1084
1085         /* Read record header. */
1086         switch (netxray->version_major) {
1087
1088         case 0:
1089                 hdr_size = sizeof (struct old_netxrayrec_hdr);
1090                 break;
1091
1092         case 1:
1093                 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1094                 break;
1095
1096         case 2:
1097                 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1098                 break;
1099         }
1100         errno = WTAP_ERR_CANT_READ;
1101         bytes_read = file_read(hdr, 1, hdr_size, fh);
1102         if (bytes_read != hdr_size) {
1103                 *err = file_error(wth->fh);
1104                 if (*err != 0)
1105                         return 0;
1106                 if (bytes_read != 0) {
1107                         *err = WTAP_ERR_SHORT_READ;
1108                         return 0;
1109                 }
1110
1111                 /*
1112                  * We're at EOF.  "*err" is 0; we return FALSE - that
1113                  * combination tells our caller we're at EOF.
1114                  */
1115                 return 0;
1116         }
1117         return hdr_size;
1118 }
1119
1120 static guint
1121 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1122     union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1123 {
1124         netxray_t *netxray = (netxray_t *)wth->priv;
1125         guint padding = 0;
1126
1127         /*
1128          * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1129          * pseudo-header.
1130          */
1131         switch (netxray->version_major) {
1132
1133         case 1:
1134                 switch (wth->file_encap) {
1135
1136                 case WTAP_ENCAP_ETHERNET:
1137                         /*
1138                          * XXX - if hdr->hdr_1_x.xxx[15] is 1
1139                          * the frame appears not to have any extra
1140                          * stuff at the end, but if it's 0,
1141                          * there appears to be 4 bytes of stuff
1142                          * at the end, but it's not an FCS.
1143                          *
1144                          * Or is that just the low-order bit?
1145                          *
1146                          * For now, we just say "no FCS".
1147                          */
1148                         pseudo_header->eth.fcs_len = 0;
1149                         break;
1150                 }
1151                 break;
1152
1153         case 2:
1154                 switch (wth->file_encap) {
1155
1156                 case WTAP_ENCAP_ETHERNET:
1157                         /*
1158                          * It appears, at least with version 2 captures,
1159                          * that we have 4 bytes of stuff (which might be
1160                          * a valid FCS or might be junk) at the end of
1161                          * the packet if hdr->hdr_2_x.xxx[2] and
1162                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1163                          * they don't.
1164                          *
1165                          * It also appears that if the low-order bit of
1166                          * hdr->hdr_2_x.xxx[8] is set, the packet has a
1167                          * bad FCS.
1168                          */
1169                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1170                             hdr->hdr_2_x.xxx[3] == 0xff) {
1171                                 /*
1172                                  * We have 4 bytes of stuff at the
1173                                  * end of the frame - FCS, or junk?
1174                                  */
1175                                 if (netxray->fcs_valid) {
1176                                         /*
1177                                          * FCS.
1178                                          */
1179                                         pseudo_header->eth.fcs_len = 4;
1180                                 } else {
1181                                         /*
1182                                          * Junk.
1183                                          */
1184                                         padding = 4;
1185                                 }
1186                         } else
1187                                 pseudo_header->eth.fcs_len = 0;
1188                         break;
1189
1190                 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1191                         /*
1192                          * It appears, in one 802.11 capture, that
1193                          * we have 4 bytes of junk at the ends of
1194                          * frames in which hdr->hdr_2_x.xxx[2] and
1195                          * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1196                          * seen any frames where it's an FCS, but,
1197                          * for now, we still check the fcs_valid
1198                          * flag - I also haven't seen any capture
1199                          * where we'd set it based on the realtick
1200                          * value.
1201                          *
1202                          * It also appears that if the low-order bit of
1203                          * hdr->hdr_2_x.xxx[8] is set, the packet has a
1204                          * bad FCS.  According to Ken Mann, the 0x4 bit
1205                          * is sometimes also set for errors.
1206                          *
1207                          * Ken also says that xxx[11] is 0x5 when the
1208                          * packet is WEP-encrypted.
1209                          */
1210                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1211                             hdr->hdr_2_x.xxx[3] == 0xff) {
1212                                 /*
1213                                  * We have 4 bytes of stuff at the
1214                                  * end of the frame - FCS, or junk?
1215                                  */
1216                                 if (netxray->fcs_valid) {
1217                                         /*
1218                                          * FCS.
1219                                          */
1220                                         pseudo_header->ieee_802_11.fcs_len = 4;
1221                                 } else {
1222                                         /*
1223                                          * Junk.
1224                                          */
1225                                         padding = 4;
1226                                 }
1227                         } else
1228                                 pseudo_header->ieee_802_11.fcs_len = 0;
1229
1230                         pseudo_header->ieee_802_11.channel =
1231                             hdr->hdr_2_x.xxx[12];
1232                         pseudo_header->ieee_802_11.data_rate =
1233                             hdr->hdr_2_x.xxx[13];
1234                         pseudo_header->ieee_802_11.signal_level =
1235                             hdr->hdr_2_x.xxx[14];
1236                         /*
1237                          * According to Ken Mann, at least in the captures
1238                          * he's seen, xxx[15] is the noise level, which
1239                          * is either 0xFF meaning "none reported" or a value
1240                          * from 0x00 to 0x7F for 0 to 100%.
1241                          */
1242                         break;
1243
1244                 case WTAP_ENCAP_ISDN:
1245                         /*
1246                          * ISDN.
1247                          *
1248                          * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1249                          * is the direction flag.
1250                          *
1251                          * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
1252                          * are the channel number, but some mapping is
1253                          * required for PRI.  (Is it really just the time
1254                          * slot?)
1255                          */
1256                         pseudo_header->isdn.uton =
1257                             (hdr->hdr_2_x.xxx[12] & 0x01);
1258                         pseudo_header->isdn.channel =
1259                             hdr->hdr_2_x.xxx[13] & 0x1F;
1260                         switch (netxray->isdn_type) {
1261
1262                         case 1:
1263                                 /*
1264                                  * E1 PRI.  Channel numbers 0 and 16
1265                                  * are the D channel; channel numbers 1
1266                                  * through 15 are B1 through B15; channel
1267                                  * numbers 17 through 31 are B16 through
1268                                  * B31.
1269                                  */
1270                                 if (pseudo_header->isdn.channel == 16)
1271                                         pseudo_header->isdn.channel = 0;
1272                                 else if (pseudo_header->isdn.channel > 16)
1273                                         pseudo_header->isdn.channel -= 1;
1274                                 break;
1275
1276                         case 2:
1277                                 /*
1278                                  * T1 PRI.  Channel numbers 0 and 24
1279                                  * are the D channel; channel numbers 1
1280                                  * through 23 are B1 through B23.
1281                                  */
1282                                 if (pseudo_header->isdn.channel == 24)
1283                                         pseudo_header->isdn.channel = 0;
1284                                 else if (pseudo_header->isdn.channel > 24)
1285                                         pseudo_header->isdn.channel -= 1;
1286                                 break;
1287                         }
1288
1289                         /*
1290                          * It appears, at least with version 2 captures,
1291                          * that we have 4 bytes of stuff (which might be
1292                          * a valid FCS or might be junk) at the end of
1293                          * the packet if hdr->hdr_2_x.xxx[2] and
1294                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1295                          * they don't.
1296                          *
1297                          * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1298                          * indicate a bad FCS, as is the case with
1299                          * Ethernet?
1300                          */
1301                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1302                             hdr->hdr_2_x.xxx[3] == 0xff) {
1303                                 /*
1304                                  * FCS, or junk, at the end.
1305                                  * XXX - is it an FCS if "fcs_valid" is
1306                                  * true?
1307                                  */
1308                                 padding = 4;
1309                         }
1310                         break;
1311
1312                 case WTAP_ENCAP_LAPB:
1313                 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1314                         /*
1315                          * LAPB/X.25 and Frame Relay.
1316                          *
1317                          * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1318                          * is the direction flag.  (Probably true for other
1319                          * HDLC encapsulations as well.)
1320                          */
1321                         pseudo_header->x25.flags =
1322                             (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1323
1324                         /*
1325                          * It appears, at least with version 2 captures,
1326                          * that we have 4 bytes of stuff (which might be
1327                          * a valid FCS or might be junk) at the end of
1328                          * the packet if hdr->hdr_2_x.xxx[2] and
1329                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1330                          * they don't.
1331                          *
1332                          * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1333                          * indicate a bad FCS, as is the case with
1334                          * Ethernet?
1335                          */
1336                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1337                             hdr->hdr_2_x.xxx[3] == 0xff) {
1338                                 /*
1339                                  * FCS, or junk, at the end.
1340                                  * XXX - is it an FCS if "fcs_valid" is
1341                                  * true?
1342                                  */
1343                                 padding = 4;
1344                         }
1345                         break;
1346
1347                 case WTAP_ENCAP_PPP_WITH_PHDR:
1348                 case WTAP_ENCAP_SDLC:
1349                 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1350                         pseudo_header->p2p.sent =
1351                             (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1352                         break;
1353
1354                 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1355                         pseudo_header->atm.flags = 0;
1356                         /*
1357                          * XXX - is 0x08 an "OAM cell" flag?
1358                          */
1359                         if (hdr->hdr_2_x.xxx[9] & 0x04)
1360                                 pseudo_header->atm.flags |= ATM_RAW_CELL;
1361                         pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
1362                         pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1363                         pseudo_header->atm.channel =
1364                             (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1365                         pseudo_header->atm.cells = 0;
1366
1367                         switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1368
1369                         case 0x00:      /* Unknown */
1370                                 /*
1371                                  * Infer the AAL, traffic type, and subtype.
1372                                  */
1373                                 atm_guess_traffic_type(pd, len,
1374                                     pseudo_header);
1375                                 break;
1376
1377                         case 0x50:      /* AAL5 (including signalling) */
1378                                 pseudo_header->atm.aal = AAL_5;
1379                                 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1380
1381                                 case 0x09:
1382                                 case 0x0a:      /* Signalling traffic */
1383                                         pseudo_header->atm.aal = AAL_SIGNALLING;
1384                                         pseudo_header->atm.type = TRAF_UNKNOWN;
1385                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1386                                         break;
1387
1388                                 case 0x0b:      /* ILMI */
1389                                         pseudo_header->atm.type = TRAF_ILMI;
1390                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1391                                         break;
1392
1393                                 case 0x0c:      /* LANE LE Control */
1394                                         pseudo_header->atm.type = TRAF_LANE;
1395                                         pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1396                                         break;
1397
1398                                 case 0x0d:
1399                                         /*
1400                                          * 0x0d is *mostly* LANE 802.3,
1401                                          * but I've seen an LE Control frame
1402                                          * with 0x0d.
1403                                          */
1404                                         pseudo_header->atm.type = TRAF_LANE;
1405                                         atm_guess_lane_type(pd, len,
1406                                             pseudo_header);
1407                                         break;
1408
1409                                 case 0x0f:      /* LLC multiplexed */
1410                                         pseudo_header->atm.type = TRAF_LLCMX;   /* XXX */
1411                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;   /* XXX */
1412                                         break;
1413
1414                                 default:
1415                                         /*
1416                                          * XXX - discover the other types.
1417                                          */
1418                                         pseudo_header->atm.type = TRAF_UNKNOWN;
1419                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1420                                         break;
1421                                 }
1422                                 break;
1423
1424                         default:
1425                                 /*
1426                                  * 0x60 seen, and dissected by Sniffer
1427                                  * Pro as a raw cell.
1428                                  *
1429                                  * XXX - discover what those types are.
1430                                  */
1431                                 pseudo_header->atm.aal = AAL_UNKNOWN;
1432                                 pseudo_header->atm.type = TRAF_UNKNOWN;
1433                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1434                                 break;
1435                         }
1436                         break;
1437                 }
1438                 break;
1439         }
1440         return padding;
1441 }
1442
1443 static gboolean
1444 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1445     int *err)
1446 {
1447         int     bytes_read;
1448
1449         errno = WTAP_ERR_CANT_READ;
1450         bytes_read = file_read(data_ptr, 1, packet_size, fh);
1451
1452         if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1453                 *err = file_error(fh);
1454                 if (*err == 0)
1455                         *err = WTAP_ERR_SHORT_READ;
1456                 return FALSE;
1457         }
1458         return TRUE;
1459 }
1460
1461 typedef struct {
1462         gboolean first_frame;
1463         struct wtap_nstime start;
1464         guint32 nframes;
1465 } netxray_dump_t;
1466
1467 static const struct {
1468         int     wtap_encap_value;
1469         int     ndis_value;
1470 } wtap_encap_1_1[] = {
1471     { WTAP_ENCAP_ETHERNET, 0 },         /* -> NDIS Ethernet */
1472     { WTAP_ENCAP_TOKEN_RING, 1 },       /* -> NDIS Token Ring */
1473     { WTAP_ENCAP_FDDI, 2 },             /* -> NDIS FDDI */
1474     { WTAP_ENCAP_FDDI_BITSWAPPED, 2 },  /* -> NDIS FDDI */
1475 };
1476 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1477
1478 static int
1479 wtap_encap_to_netxray_1_1_encap(int encap)
1480 {
1481     unsigned int i;
1482
1483     for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1484         if (encap == wtap_encap_1_1[i].wtap_encap_value)
1485             return wtap_encap_1_1[i].ndis_value;
1486     }
1487
1488     return -1;
1489 }
1490
1491 /* Returns 0 if we could write the specified encapsulation type,
1492    an error indication otherwise. */
1493 int netxray_dump_can_write_encap_1_1(int encap)
1494 {
1495     /* Per-packet encapsulations aren't supported. */
1496     if (encap == WTAP_ENCAP_PER_PACKET)
1497         return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1498
1499     if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1500         return WTAP_ERR_UNSUPPORTED_ENCAP;
1501
1502     return 0;
1503 }
1504
1505 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1506    failure */
1507 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
1508 {
1509     netxray_dump_t *netxray;
1510
1511     /* This is a NetXRay file.  We can't fill in some fields in the header
1512        until all the packets have been written, so we can't write to a
1513        pipe. */
1514     if (cant_seek) {
1515         *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1516         return FALSE;
1517     }
1518
1519     wdh->subtype_write = netxray_dump_1_1;
1520     wdh->subtype_close = netxray_dump_close_1_1;
1521
1522     /* We can't fill in all the fields in the file header, as we
1523        haven't yet written any packets.  As we'll have to rewrite
1524        the header when we've written out all the packets, we just
1525        skip over the header for now. */
1526     if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1527         *err = errno;
1528         return FALSE;
1529     }
1530
1531     netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1532     wdh->priv = (void *)netxray;
1533     netxray->first_frame = TRUE;
1534     netxray->start.secs = 0;
1535     netxray->start.nsecs = 0;
1536     netxray->nframes = 0;
1537
1538     return TRUE;
1539 }
1540
1541 /* Write a record for a packet to a dump file.
1542    Returns TRUE on success, FALSE on failure. */
1543 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1544         const struct wtap_pkthdr *phdr,
1545         const union wtap_pseudo_header *pseudo_header _U_,
1546         const guchar *pd, int *err)
1547 {
1548     netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1549     guint64 timestamp;
1550     guint32 t32;
1551     struct netxrayrec_1_x_hdr rec_hdr;
1552     size_t nwritten;
1553
1554     /* NetXRay/Windows Sniffer files have a capture start date/time
1555        in the header, in a UNIX-style format, with one-second resolution,
1556        and a start time stamp with microsecond resolution that's just
1557        an arbitrary time stamp relative to some unknown time (boot
1558        time?), and have times relative to the start time stamp in
1559        the packet headers; pick the seconds value of the time stamp
1560        of the first packet as the UNIX-style start date/time, and make
1561        the high-resolution start time stamp 0, with the time stamp of
1562        packets being the delta between the stamp of the packet and
1563        the stamp of the first packet with the microseconds part 0. */
1564     if (netxray->first_frame) {
1565         netxray->first_frame = FALSE;
1566         netxray->start = phdr->ts;
1567     }
1568
1569     /* build the header for each packet */
1570     memset(&rec_hdr, '\0', sizeof(rec_hdr));
1571     timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000 
1572                 + ((guint64)phdr->ts.nsecs)/1000;
1573     t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1574     rec_hdr.timelo = htolel(t32);
1575     t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1576     rec_hdr.timehi = htolel(t32);
1577     rec_hdr.orig_len = htoles(phdr->len);
1578     rec_hdr.incl_len = htoles(phdr->caplen);
1579
1580     nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1581     if (nwritten != sizeof(rec_hdr)) {
1582         if (nwritten == 0 && ferror(wdh->fh))
1583             *err = errno;
1584         else
1585             *err = WTAP_ERR_SHORT_WRITE;
1586         return FALSE;
1587     }
1588
1589     /* write the packet data */
1590     nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1591     if (nwritten != phdr->caplen) {
1592         if (nwritten == 0 && ferror(wdh->fh))
1593             *err = errno;
1594         else
1595             *err = WTAP_ERR_SHORT_WRITE;
1596         return FALSE;
1597     }
1598
1599     netxray->nframes++;
1600
1601     return TRUE;
1602 }
1603
1604 /* Finish writing to a dump file.
1605    Returns TRUE on success, FALSE on failure. */
1606 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1607 {
1608     char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1609     netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1610     guint32 filelen;
1611     struct netxray_hdr file_hdr;
1612     size_t nwritten;
1613
1614     filelen = (guint32)ftell(wdh->fh);  /* XXX - large files? */
1615
1616     /* Go back to beginning */
1617     fseek(wdh->fh, 0, SEEK_SET);
1618
1619     /* Rewrite the file header. */
1620     nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1621     if (nwritten != sizeof netxray_magic) {
1622         if (err != NULL) {
1623             if (nwritten == 0 && ferror(wdh->fh))
1624                 *err = errno;
1625             else
1626                 *err = WTAP_ERR_SHORT_WRITE;
1627         }
1628         return FALSE;
1629     }
1630
1631     /* "sniffer" version ? */
1632     memset(&file_hdr, '\0', sizeof file_hdr);
1633     memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1634     file_hdr.start_time = htolel(netxray->start.secs);
1635     file_hdr.nframes = htolel(netxray->nframes);
1636     file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1637     file_hdr.end_offset = htolel(filelen);
1638     file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1639     file_hdr.timelo = htolel(0);
1640     file_hdr.timehi = htolel(0);
1641
1642     memset(hdr_buf, '\0', sizeof hdr_buf);
1643     memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1644     nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1645     if (nwritten != sizeof hdr_buf) {
1646         if (err != NULL) {
1647             if (nwritten == 0 && ferror(wdh->fh))
1648                 *err = errno;
1649             else
1650                 *err = WTAP_ERR_SHORT_WRITE;
1651         }
1652         return FALSE;
1653     }
1654
1655     return TRUE;
1656 }
1657
1658 static const struct {
1659         int     wtap_encap_value;
1660         int     ndis_value;
1661 } wtap_encap_2_0[] = {
1662     { WTAP_ENCAP_ETHERNET, 0 },                 /* -> NDIS Ethernet */
1663     { WTAP_ENCAP_TOKEN_RING, 1 },               /* -> NDIS Token Ring */
1664     { WTAP_ENCAP_FDDI, 2 },                     /* -> NDIS FDDI */
1665     { WTAP_ENCAP_FDDI_BITSWAPPED, 2 },          /* -> NDIS FDDI */
1666     { WTAP_ENCAP_PPP_WITH_PHDR, 3 },            /* -> NDIS WAN */
1667     { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 },         /* -> NDIS WAN */
1668     { WTAP_ENCAP_LAPB, 3 },                     /* -> NDIS WAN */
1669     { WTAP_ENCAP_SDLC, 3 },                     /* -> NDIS WAN */
1670 };
1671 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1672
1673 static int
1674 wtap_encap_to_netxray_2_0_encap(int encap)
1675 {
1676     unsigned int i;
1677
1678     for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1679         if (encap == wtap_encap_2_0[i].wtap_encap_value)
1680             return wtap_encap_2_0[i].ndis_value;
1681     }
1682
1683     return -1;
1684 }
1685
1686 /* Returns 0 if we could write the specified encapsulation type,
1687    an error indication otherwise. */
1688 int netxray_dump_can_write_encap_2_0(int encap)
1689 {
1690     /* Per-packet encapsulations aren't supported. */
1691     if (encap == WTAP_ENCAP_PER_PACKET)
1692         return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1693
1694     if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1695         return WTAP_ERR_UNSUPPORTED_ENCAP;
1696
1697     return 0;
1698 }
1699
1700 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1701    failure */
1702 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
1703 {
1704     netxray_dump_t *netxray;
1705
1706     /* This is a NetXRay file.  We can't fill in some fields in the header
1707        until all the packets have been written, so we can't write to a
1708        pipe. */
1709     if (cant_seek) {
1710         *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1711         return FALSE;
1712     }
1713
1714     wdh->subtype_write = netxray_dump_2_0;
1715     wdh->subtype_close = netxray_dump_close_2_0;
1716
1717     /* We can't fill in all the fields in the file header, as we
1718        haven't yet written any packets.  As we'll have to rewrite
1719        the header when we've written out all the packets, we just
1720        skip over the header for now. */
1721     if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1722         *err = errno;
1723         return FALSE;
1724     }
1725
1726     netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1727     wdh->priv = (void *)netxray;
1728     netxray->first_frame = TRUE;
1729     netxray->start.secs = 0;
1730     netxray->start.nsecs = 0;
1731     netxray->nframes = 0;
1732
1733     return TRUE;
1734 }
1735
1736 /* Write a record for a packet to a dump file.
1737    Returns TRUE on success, FALSE on failure. */
1738 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1739         const struct wtap_pkthdr *phdr,
1740         const union wtap_pseudo_header *pseudo_header _U_,
1741         const guchar *pd, int *err)
1742 {
1743     netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1744     guint64 timestamp;
1745     guint32 t32;
1746     struct netxrayrec_2_x_hdr rec_hdr;
1747     size_t nwritten;
1748
1749     /* NetXRay/Windows Sniffer files have a capture start date/time
1750        in the header, in a UNIX-style format, with one-second resolution,
1751        and a start time stamp with microsecond resolution that's just
1752        an arbitrary time stamp relative to some unknown time (boot
1753        time?), and have times relative to the start time stamp in
1754        the packet headers; pick the seconds value of the time stamp
1755        of the first packet as the UNIX-style start date/time, and make
1756        the high-resolution start time stamp 0, with the time stamp of
1757        packets being the delta between the stamp of the packet and
1758        the stamp of the first packet with the microseconds part 0. */
1759     if (netxray->first_frame) {
1760         netxray->first_frame = FALSE;
1761         netxray->start = phdr->ts;
1762     }
1763
1764     /* build the header for each packet */
1765     memset(&rec_hdr, '\0', sizeof(rec_hdr));
1766     timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000 
1767                 + ((guint64)phdr->ts.nsecs)/1000;
1768     t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1769     rec_hdr.timelo = htolel(t32);
1770     t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1771     rec_hdr.timehi = htolel(t32);
1772     rec_hdr.orig_len = htoles(phdr->len);
1773     rec_hdr.incl_len = htoles(phdr->caplen);
1774
1775     switch (phdr->pkt_encap) {
1776
1777     case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1778         rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1779         rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1780         rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1781         break;
1782
1783     case WTAP_ENCAP_PPP_WITH_PHDR:
1784     case WTAP_ENCAP_SDLC:
1785         rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1786         break;
1787
1788     case WTAP_ENCAP_FRELAY_WITH_PHDR:
1789         rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1790         break;
1791     }
1792
1793     nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1794     if (nwritten != sizeof(rec_hdr)) {
1795         if (nwritten == 0 && ferror(wdh->fh))
1796             *err = errno;
1797         else
1798             *err = WTAP_ERR_SHORT_WRITE;
1799         return FALSE;
1800     }
1801
1802     /* write the packet data */
1803     nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1804     if (nwritten != phdr->caplen) {
1805         if (nwritten == 0 && ferror(wdh->fh))
1806             *err = errno;
1807         else
1808             *err = WTAP_ERR_SHORT_WRITE;
1809         return FALSE;
1810     }
1811
1812     netxray->nframes++;
1813
1814     return TRUE;
1815 }
1816
1817 /* Finish writing to a dump file.
1818    Returns TRUE on success, FALSE on failure. */
1819 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1820 {
1821     char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1822     netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1823     guint32 filelen;
1824     struct netxray_hdr file_hdr;
1825     size_t nwritten;
1826
1827     filelen = (guint32)ftell(wdh->fh);  /* XXX - large files? */
1828
1829     /* Go back to beginning */
1830     fseek(wdh->fh, 0, SEEK_SET);
1831
1832     /* Rewrite the file header. */
1833     nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1834     if (nwritten != sizeof netxray_magic) {
1835         if (err != NULL) {
1836             if (nwritten == 0 && ferror(wdh->fh))
1837                 *err = errno;
1838             else
1839                 *err = WTAP_ERR_SHORT_WRITE;
1840         }
1841         return FALSE;
1842     }
1843
1844     /* "sniffer" version ? */
1845     memset(&file_hdr, '\0', sizeof file_hdr);
1846     memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1847     file_hdr.start_time = htolel(netxray->start.secs);
1848     file_hdr.nframes = htolel(netxray->nframes);
1849     file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1850     file_hdr.end_offset = htolel(filelen);
1851     file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1852     file_hdr.timelo = htolel(0);
1853     file_hdr.timehi = htolel(0);
1854     switch (wdh->encap) {
1855
1856     case WTAP_ENCAP_PPP_WITH_PHDR:
1857         file_hdr.captype = WAN_CAPTYPE_PPP;
1858         break;
1859
1860     case WTAP_ENCAP_FRELAY_WITH_PHDR:
1861         file_hdr.captype = WAN_CAPTYPE_FRELAY;
1862         break;
1863
1864     case WTAP_ENCAP_LAPB:
1865         file_hdr.captype = WAN_CAPTYPE_HDLC;
1866         file_hdr.wan_hdlc_subsub_captype = 0;
1867         break;
1868
1869     case WTAP_ENCAP_SDLC:
1870         file_hdr.captype = WAN_CAPTYPE_SDLC;
1871         break;
1872
1873     default:
1874         file_hdr.captype = CAPTYPE_NDIS;
1875         break;
1876     }
1877
1878     memset(hdr_buf, '\0', sizeof hdr_buf);
1879     memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1880     nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1881     if (nwritten != sizeof hdr_buf) {
1882         if (err != NULL) {
1883             if (nwritten == 0 && ferror(wdh->fh))
1884                 *err = errno;
1885             else
1886                 *err = WTAP_ERR_SHORT_WRITE;
1887         }
1888         return FALSE;
1889     }
1890
1891     return TRUE;
1892 }