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