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