Move the new files to the same places as in automake.
[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 <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, guint8 *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 guint8 *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 guint8 *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                 wth->phdr.presence_flags = WTAP_HAS_TS;
1012                 t = (double)pletohl(&hdr.old_hdr.timelo)
1013                     + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
1014                 t /= netxray->ticks_per_sec;
1015                 t -= netxray->start_timestamp;
1016                 wth->phdr.ts.secs = netxray->start_time + (long)t;
1017                 wth->phdr.ts.nsecs = (int)((t-(double)(unsigned long)(t))
1018                         *1.0e9);
1019                 /*
1020                  * We subtract the padding from the packet size, so our caller
1021                  * doesn't see it.
1022                  */
1023                 wth->phdr.caplen = packet_size - padding;
1024                 wth->phdr.len = wth->phdr.caplen;
1025         } else {
1026                 wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
1027                 t = (double)pletohl(&hdr.hdr_1_x.timelo)
1028                     + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
1029                 t /= netxray->ticks_per_sec;
1030                 t -= netxray->start_timestamp;
1031                 wth->phdr.ts.secs = netxray->start_time + (time_t)t;
1032                 wth->phdr.ts.nsecs = (int)((t-(double)(unsigned long)(t))
1033                         *1.0e9);
1034                 /*
1035                  * We subtract the padding from the packet size, so our caller
1036                  * doesn't see it.
1037                  */
1038                 wth->phdr.caplen = packet_size - padding;
1039                 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
1040         }
1041
1042         return TRUE;
1043 }
1044
1045 static gboolean
1046 netxray_seek_read(wtap *wth, gint64 seek_off,
1047     union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
1048     int *err, gchar **err_info)
1049 {
1050         union netxrayrec_hdr hdr;
1051         gboolean ret;
1052
1053         if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1054                 return FALSE;
1055
1056         if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err,
1057             err_info)) {
1058                 if (*err == 0) {
1059                         /*
1060                          * EOF - we report that as a short read, as
1061                          * we've read this once and know that it
1062                          * should be there.
1063                          */
1064                         *err = WTAP_ERR_SHORT_READ;
1065                 }
1066                 return FALSE;
1067         }
1068
1069         /*
1070          * Read the packet data.
1071          */
1072         ret = netxray_read_rec_data(wth->random_fh, pd, length, err, err_info);
1073         if (!ret)
1074                 return FALSE;
1075
1076         /*
1077          * Set the pseudo-header.
1078          */
1079         netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1080         return TRUE;
1081 }
1082
1083 static int
1084 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1085     int *err, gchar **err_info)
1086 {
1087         netxray_t *netxray = (netxray_t *)wth->priv;
1088         int     bytes_read;
1089         int     hdr_size = 0;
1090
1091         /* Read record header. */
1092         switch (netxray->version_major) {
1093
1094         case 0:
1095                 hdr_size = sizeof (struct old_netxrayrec_hdr);
1096                 break;
1097
1098         case 1:
1099                 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1100                 break;
1101
1102         case 2:
1103                 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1104                 break;
1105         }
1106         errno = WTAP_ERR_CANT_READ;
1107         bytes_read = file_read(hdr, hdr_size, fh);
1108         if (bytes_read != hdr_size) {
1109                 *err = file_error(wth->fh, err_info);
1110                 if (*err != 0)
1111                         return 0;
1112                 if (bytes_read != 0) {
1113                         *err = WTAP_ERR_SHORT_READ;
1114                         return 0;
1115                 }
1116
1117                 /*
1118                  * We're at EOF.  "*err" is 0; we return FALSE - that
1119                  * combination tells our caller we're at EOF.
1120                  */
1121                 return 0;
1122         }
1123         return hdr_size;
1124 }
1125
1126 static guint
1127 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1128     union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1129 {
1130         netxray_t *netxray = (netxray_t *)wth->priv;
1131         guint padding = 0;
1132
1133         /*
1134          * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1135          * pseudo-header.
1136          */
1137         switch (netxray->version_major) {
1138
1139         case 1:
1140                 switch (wth->file_encap) {
1141
1142                 case WTAP_ENCAP_ETHERNET:
1143                         /*
1144                          * XXX - if hdr->hdr_1_x.xxx[15] is 1
1145                          * the frame appears not to have any extra
1146                          * stuff at the end, but if it's 0,
1147                          * there appears to be 4 bytes of stuff
1148                          * at the end, but it's not an FCS.
1149                          *
1150                          * Or is that just the low-order bit?
1151                          *
1152                          * For now, we just say "no FCS".
1153                          */
1154                         pseudo_header->eth.fcs_len = 0;
1155                         break;
1156                 }
1157                 break;
1158
1159         case 2:
1160                 switch (wth->file_encap) {
1161
1162                 case WTAP_ENCAP_ETHERNET:
1163                         /*
1164                          * It appears, at least with version 2 captures,
1165                          * that we have 4 bytes of stuff (which might be
1166                          * a valid FCS or might be junk) at the end of
1167                          * the packet if hdr->hdr_2_x.xxx[2] and
1168                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1169                          * they don't.
1170                          *
1171                          * It also appears that if the low-order bit of
1172                          * hdr->hdr_2_x.xxx[8] is set, the packet has a
1173                          * bad FCS.
1174                          */
1175                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1176                             hdr->hdr_2_x.xxx[3] == 0xff) {
1177                                 /*
1178                                  * We have 4 bytes of stuff at the
1179                                  * end of the frame - FCS, or junk?
1180                                  */
1181                                 if (netxray->fcs_valid) {
1182                                         /*
1183                                          * FCS.
1184                                          */
1185                                         pseudo_header->eth.fcs_len = 4;
1186                                 } else {
1187                                         /*
1188                                          * Junk.
1189                                          */
1190                                         padding = 4;
1191                                 }
1192                         } else
1193                                 pseudo_header->eth.fcs_len = 0;
1194                         break;
1195
1196                 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1197                         /*
1198                          * It appears, in one 802.11 capture, that
1199                          * we have 4 bytes of junk at the ends of
1200                          * frames in which hdr->hdr_2_x.xxx[2] and
1201                          * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1202                          * seen any frames where it's an FCS, but,
1203                          * for now, we still check the fcs_valid
1204                          * flag - I also haven't seen any capture
1205                          * where we'd set it based on the realtick
1206                          * value.
1207                          *
1208                          * It also appears that if the low-order bit of
1209                          * hdr->hdr_2_x.xxx[8] is set, the packet has a
1210                          * bad FCS.  According to Ken Mann, the 0x4 bit
1211                          * is sometimes also set for errors.
1212                          *
1213                          * Ken also says that xxx[11] is 0x5 when the
1214                          * packet is WEP-encrypted.
1215                          */
1216                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1217                             hdr->hdr_2_x.xxx[3] == 0xff) {
1218                                 /*
1219                                  * We have 4 bytes of stuff at the
1220                                  * end of the frame - FCS, or junk?
1221                                  */
1222                                 if (netxray->fcs_valid) {
1223                                         /*
1224                                          * FCS.
1225                                          */
1226                                         pseudo_header->ieee_802_11.fcs_len = 4;
1227                                 } else {
1228                                         /*
1229                                          * Junk.
1230                                          */
1231                                         padding = 4;
1232                                 }
1233                         } else
1234                                 pseudo_header->ieee_802_11.fcs_len = 0;
1235
1236                         pseudo_header->ieee_802_11.channel =
1237                             hdr->hdr_2_x.xxx[12];
1238                         pseudo_header->ieee_802_11.data_rate =
1239                             hdr->hdr_2_x.xxx[13];
1240                         pseudo_header->ieee_802_11.signal_level =
1241                             hdr->hdr_2_x.xxx[14];
1242                         /*
1243                          * According to Ken Mann, at least in the captures
1244                          * he's seen, xxx[15] is the noise level, which
1245                          * is either 0xFF meaning "none reported" or a value
1246                          * from 0x00 to 0x7F for 0 to 100%.
1247                          */
1248                         break;
1249
1250                 case WTAP_ENCAP_ISDN:
1251                         /*
1252                          * ISDN.
1253                          *
1254                          * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1255                          * is the direction flag.
1256                          *
1257                          * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
1258                          * are the channel number, but some mapping is
1259                          * required for PRI.  (Is it really just the time
1260                          * slot?)
1261                          */
1262                         pseudo_header->isdn.uton =
1263                             (hdr->hdr_2_x.xxx[12] & 0x01);
1264                         pseudo_header->isdn.channel =
1265                             hdr->hdr_2_x.xxx[13] & 0x1F;
1266                         switch (netxray->isdn_type) {
1267
1268                         case 1:
1269                                 /*
1270                                  * E1 PRI.  Channel numbers 0 and 16
1271                                  * are the D channel; channel numbers 1
1272                                  * through 15 are B1 through B15; channel
1273                                  * numbers 17 through 31 are B16 through
1274                                  * B31.
1275                                  */
1276                                 if (pseudo_header->isdn.channel == 16)
1277                                         pseudo_header->isdn.channel = 0;
1278                                 else if (pseudo_header->isdn.channel > 16)
1279                                         pseudo_header->isdn.channel -= 1;
1280                                 break;
1281
1282                         case 2:
1283                                 /*
1284                                  * T1 PRI.  Channel numbers 0 and 24
1285                                  * are the D channel; channel numbers 1
1286                                  * through 23 are B1 through B23.
1287                                  */
1288                                 if (pseudo_header->isdn.channel == 24)
1289                                         pseudo_header->isdn.channel = 0;
1290                                 else if (pseudo_header->isdn.channel > 24)
1291                                         pseudo_header->isdn.channel -= 1;
1292                                 break;
1293                         }
1294
1295                         /*
1296                          * It appears, at least with version 2 captures,
1297                          * that we have 4 bytes of stuff (which might be
1298                          * a valid FCS or might be junk) at the end of
1299                          * the packet if hdr->hdr_2_x.xxx[2] and
1300                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1301                          * they don't.
1302                          *
1303                          * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1304                          * indicate a bad FCS, as is the case with
1305                          * Ethernet?
1306                          */
1307                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1308                             hdr->hdr_2_x.xxx[3] == 0xff) {
1309                                 /*
1310                                  * FCS, or junk, at the end.
1311                                  * XXX - is it an FCS if "fcs_valid" is
1312                                  * true?
1313                                  */
1314                                 padding = 4;
1315                         }
1316                         break;
1317
1318                 case WTAP_ENCAP_LAPB:
1319                 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1320                         /*
1321                          * LAPB/X.25 and Frame Relay.
1322                          *
1323                          * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1324                          * is the direction flag.  (Probably true for other
1325                          * HDLC encapsulations as well.)
1326                          */
1327                         pseudo_header->x25.flags =
1328                             (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1329
1330                         /*
1331                          * It appears, at least with version 2 captures,
1332                          * that we have 4 bytes of stuff (which might be
1333                          * a valid FCS or might be junk) at the end of
1334                          * the packet if hdr->hdr_2_x.xxx[2] and
1335                          * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1336                          * they don't.
1337                          *
1338                          * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1339                          * indicate a bad FCS, as is the case with
1340                          * Ethernet?
1341                          */
1342                         if (hdr->hdr_2_x.xxx[2] == 0xff &&
1343                             hdr->hdr_2_x.xxx[3] == 0xff) {
1344                                 /*
1345                                  * FCS, or junk, at the end.
1346                                  * XXX - is it an FCS if "fcs_valid" is
1347                                  * true?
1348                                  */
1349                                 padding = 4;
1350                         }
1351                         break;
1352
1353                 case WTAP_ENCAP_PPP_WITH_PHDR:
1354                 case WTAP_ENCAP_SDLC:
1355                 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1356                         pseudo_header->p2p.sent =
1357                             (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1358                         break;
1359
1360                 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1361                         pseudo_header->atm.flags = 0;
1362                         /*
1363                          * XXX - is 0x08 an "OAM cell" flag?
1364                          */
1365                         if (hdr->hdr_2_x.xxx[9] & 0x04)
1366                                 pseudo_header->atm.flags |= ATM_RAW_CELL;
1367                         pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
1368                         pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1369                         pseudo_header->atm.channel =
1370                             (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1371                         pseudo_header->atm.cells = 0;
1372
1373                         switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1374
1375                         case 0x00:      /* Unknown */
1376                                 /*
1377                                  * Infer the AAL, traffic type, and subtype.
1378                                  */
1379                                 atm_guess_traffic_type(pd, len,
1380                                     pseudo_header);
1381                                 break;
1382
1383                         case 0x50:      /* AAL5 (including signalling) */
1384                                 pseudo_header->atm.aal = AAL_5;
1385                                 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1386
1387                                 case 0x09:
1388                                 case 0x0a:      /* Signalling traffic */
1389                                         pseudo_header->atm.aal = AAL_SIGNALLING;
1390                                         pseudo_header->atm.type = TRAF_UNKNOWN;
1391                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1392                                         break;
1393
1394                                 case 0x0b:      /* ILMI */
1395                                         pseudo_header->atm.type = TRAF_ILMI;
1396                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1397                                         break;
1398
1399                                 case 0x0c:      /* LANE LE Control */
1400                                         pseudo_header->atm.type = TRAF_LANE;
1401                                         pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1402                                         break;
1403
1404                                 case 0x0d:
1405                                         /*
1406                                          * 0x0d is *mostly* LANE 802.3,
1407                                          * but I've seen an LE Control frame
1408                                          * with 0x0d.
1409                                          */
1410                                         pseudo_header->atm.type = TRAF_LANE;
1411                                         atm_guess_lane_type(pd, len,
1412                                             pseudo_header);
1413                                         break;
1414
1415                                 case 0x0f:      /* LLC multiplexed */
1416                                         pseudo_header->atm.type = TRAF_LLCMX;   /* XXX */
1417                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;   /* XXX */
1418                                         break;
1419
1420                                 default:
1421                                         /*
1422                                          * XXX - discover the other types.
1423                                          */
1424                                         pseudo_header->atm.type = TRAF_UNKNOWN;
1425                                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1426                                         break;
1427                                 }
1428                                 break;
1429
1430                         default:
1431                                 /*
1432                                  * 0x60 seen, and dissected by Sniffer
1433                                  * Pro as a raw cell.
1434                                  *
1435                                  * XXX - discover what those types are.
1436                                  */
1437                                 pseudo_header->atm.aal = AAL_UNKNOWN;
1438                                 pseudo_header->atm.type = TRAF_UNKNOWN;
1439                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1440                                 break;
1441                         }
1442                         break;
1443                 }
1444                 break;
1445         }
1446         return padding;
1447 }
1448
1449 static gboolean
1450 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1451     int *err, gchar **err_info)
1452 {
1453         int     bytes_read;
1454
1455         errno = WTAP_ERR_CANT_READ;
1456         bytes_read = file_read(data_ptr, packet_size, fh);
1457
1458         if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1459                 *err = file_error(fh, err_info);
1460                 if (*err == 0)
1461                         *err = WTAP_ERR_SHORT_READ;
1462                 return FALSE;
1463         }
1464         return TRUE;
1465 }
1466
1467 typedef struct {
1468         gboolean first_frame;
1469         struct wtap_nstime start;
1470         guint32 nframes;
1471 } netxray_dump_t;
1472
1473 static const struct {
1474         int     wtap_encap_value;
1475         int     ndis_value;
1476 } wtap_encap_1_1[] = {
1477         { WTAP_ENCAP_ETHERNET, 0 },             /* -> NDIS Ethernet */
1478         { WTAP_ENCAP_TOKEN_RING, 1 },           /* -> NDIS Token Ring */
1479         { WTAP_ENCAP_FDDI, 2 },                 /* -> NDIS FDDI */
1480         { WTAP_ENCAP_FDDI_BITSWAPPED, 2 },      /* -> NDIS FDDI */
1481 };
1482 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1483
1484 static int
1485 wtap_encap_to_netxray_1_1_encap(int encap)
1486 {
1487         unsigned int i;
1488
1489         for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1490                 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1491                         return wtap_encap_1_1[i].ndis_value;
1492         }
1493
1494         return -1;
1495 }
1496
1497 /* Returns 0 if we could write the specified encapsulation type,
1498    an error indication otherwise. */
1499 int netxray_dump_can_write_encap_1_1(int encap)
1500 {
1501         /* Per-packet encapsulations aren't supported. */
1502         if (encap == WTAP_ENCAP_PER_PACKET)
1503                 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1504
1505         if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1506                 return WTAP_ERR_UNSUPPORTED_ENCAP;
1507
1508         return 0;
1509 }
1510
1511 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1512    failure */
1513 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err)
1514 {
1515         netxray_dump_t *netxray;
1516
1517         wdh->subtype_write = netxray_dump_1_1;
1518         wdh->subtype_close = netxray_dump_close_1_1;
1519
1520         /* We can't fill in all the fields in the file header, as we
1521            haven't yet written any packets.  As we'll have to rewrite
1522            the header when we've written out all the packets, we just
1523            skip over the header for now. */
1524         if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1525                 *err = errno;
1526                 return FALSE;
1527         }
1528         wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
1529
1530         netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1531         wdh->priv = (void *)netxray;
1532         netxray->first_frame = TRUE;
1533         netxray->start.secs = 0;
1534         netxray->start.nsecs = 0;
1535         netxray->nframes = 0;
1536
1537         return TRUE;
1538 }
1539
1540 /* Write a record for a packet to a dump file.
1541    Returns TRUE on success, FALSE on failure. */
1542 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1543                                  const struct wtap_pkthdr *phdr,
1544                                  const union wtap_pseudo_header *pseudo_header _U_,
1545                                  const guint8 *pd, int *err)
1546 {
1547         netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1548         guint64 timestamp;
1549         guint32 t32;
1550         struct netxrayrec_1_x_hdr rec_hdr;
1551
1552         /* NetXRay/Windows Sniffer files have a capture start date/time
1553            in the header, in a UNIX-style format, with one-second resolution,
1554            and a start time stamp with microsecond resolution that's just
1555            an arbitrary time stamp relative to some unknown time (boot
1556            time?), and have times relative to the start time stamp in
1557            the packet headers; pick the seconds value of the time stamp
1558            of the first packet as the UNIX-style start date/time, and make
1559            the high-resolution start time stamp 0, with the time stamp of
1560            packets being the delta between the stamp of the packet and
1561            the stamp of the first packet with the microseconds part 0. */
1562         if (netxray->first_frame) {
1563                 netxray->first_frame = FALSE;
1564                 netxray->start = phdr->ts;
1565         }
1566
1567         /* build the header for each packet */
1568         memset(&rec_hdr, '\0', sizeof(rec_hdr));
1569         timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1570                 + ((guint64)phdr->ts.nsecs)/1000;
1571         t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1572         rec_hdr.timelo = htolel(t32);
1573         t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1574         rec_hdr.timehi = htolel(t32);
1575         rec_hdr.orig_len = htoles(phdr->len);
1576         rec_hdr.incl_len = htoles(phdr->caplen);
1577
1578         if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1579                 return FALSE;
1580         wdh->bytes_dumped += sizeof(rec_hdr);
1581
1582         /* write the packet data */
1583         if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1584                 return FALSE;
1585         wdh->bytes_dumped += phdr->caplen;
1586
1587         netxray->nframes++;
1588
1589         return TRUE;
1590 }
1591
1592 /* Finish writing to a dump file.
1593    Returns TRUE on success, FALSE on failure. */
1594 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1595 {
1596         char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1597         netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1598         guint32 filelen;
1599         struct netxray_hdr file_hdr;
1600
1601         filelen = (guint32)ftell(wdh->fh);      /* XXX - large files? */
1602
1603         /* Go back to beginning */
1604         fseek(wdh->fh, 0, SEEK_SET);
1605
1606         /* Rewrite the file header. */
1607         if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
1608                 return FALSE;
1609
1610         /* "sniffer" version ? */
1611         memset(&file_hdr, '\0', sizeof file_hdr);
1612         memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1613         file_hdr.start_time = htolel(netxray->start.secs);
1614         file_hdr.nframes = htolel(netxray->nframes);
1615         file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1616         file_hdr.end_offset = htolel(filelen);
1617         file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1618         file_hdr.timelo = htolel(0);
1619         file_hdr.timehi = htolel(0);
1620
1621         memset(hdr_buf, '\0', sizeof hdr_buf);
1622         memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1623         if (!wtap_dump_file_write(wdh, hdr_buf, sizeof hdr_buf, err))
1624                 return FALSE;
1625
1626         return TRUE;
1627 }
1628
1629 static const struct {
1630         int     wtap_encap_value;
1631         int     ndis_value;
1632 } wtap_encap_2_0[] = {
1633         { WTAP_ENCAP_ETHERNET, 0 },                     /* -> NDIS Ethernet */
1634         { WTAP_ENCAP_TOKEN_RING, 1 },           /* -> NDIS Token Ring */
1635         { WTAP_ENCAP_FDDI, 2 },                 /* -> NDIS FDDI */
1636         { WTAP_ENCAP_FDDI_BITSWAPPED, 2 },              /* -> NDIS FDDI */
1637         { WTAP_ENCAP_PPP_WITH_PHDR, 3 },                /* -> NDIS WAN */
1638         { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 },             /* -> NDIS WAN */
1639         { WTAP_ENCAP_LAPB, 3 },                 /* -> NDIS WAN */
1640         { WTAP_ENCAP_SDLC, 3 },                 /* -> NDIS WAN */
1641 };
1642 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1643
1644 static int
1645 wtap_encap_to_netxray_2_0_encap(int encap)
1646 {
1647         unsigned int i;
1648
1649         for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1650                 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1651                         return wtap_encap_2_0[i].ndis_value;
1652         }
1653
1654         return -1;
1655 }
1656
1657 /* Returns 0 if we could write the specified encapsulation type,
1658    an error indication otherwise. */
1659 int netxray_dump_can_write_encap_2_0(int encap)
1660 {
1661         /* Per-packet encapsulations aren't supported. */
1662         if (encap == WTAP_ENCAP_PER_PACKET)
1663                 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1664
1665         if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1666                 return WTAP_ERR_UNSUPPORTED_ENCAP;
1667
1668         return 0;
1669 }
1670
1671 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1672    failure */
1673 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, int *err)
1674 {
1675         netxray_dump_t *netxray;
1676
1677         wdh->subtype_write = netxray_dump_2_0;
1678         wdh->subtype_close = netxray_dump_close_2_0;
1679
1680         /* We can't fill in all the fields in the file header, as we
1681            haven't yet written any packets.  As we'll have to rewrite
1682            the header when we've written out all the packets, we just
1683            skip over the header for now. */
1684         if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1685                 *err = errno;
1686                 return FALSE;
1687         }
1688         wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
1689
1690         netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1691         wdh->priv = (void *)netxray;
1692         netxray->first_frame = TRUE;
1693         netxray->start.secs = 0;
1694         netxray->start.nsecs = 0;
1695         netxray->nframes = 0;
1696
1697         return TRUE;
1698 }
1699
1700 /* Write a record for a packet to a dump file.
1701    Returns TRUE on success, FALSE on failure. */
1702 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1703                                  const struct wtap_pkthdr *phdr,
1704                                  const union wtap_pseudo_header *pseudo_header _U_,
1705                                  const guint8 *pd, int *err)
1706 {
1707         netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1708         guint64 timestamp;
1709         guint32 t32;
1710         struct netxrayrec_2_x_hdr rec_hdr;
1711
1712         /* NetXRay/Windows Sniffer files have a capture start date/time
1713            in the header, in a UNIX-style format, with one-second resolution,
1714            and a start time stamp with microsecond resolution that's just
1715            an arbitrary time stamp relative to some unknown time (boot
1716            time?), and have times relative to the start time stamp in
1717            the packet headers; pick the seconds value of the time stamp
1718            of the first packet as the UNIX-style start date/time, and make
1719            the high-resolution start time stamp 0, with the time stamp of
1720            packets being the delta between the stamp of the packet and
1721            the stamp of the first packet with the microseconds part 0. */
1722         if (netxray->first_frame) {
1723                 netxray->first_frame = FALSE;
1724                 netxray->start = phdr->ts;
1725         }
1726
1727         /* build the header for each packet */
1728         memset(&rec_hdr, '\0', sizeof(rec_hdr));
1729         timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1730                 + ((guint64)phdr->ts.nsecs)/1000;
1731         t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1732         rec_hdr.timelo = htolel(t32);
1733         t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1734         rec_hdr.timehi = htolel(t32);
1735         rec_hdr.orig_len = htoles(phdr->len);
1736         rec_hdr.incl_len = htoles(phdr->caplen);
1737
1738         switch (phdr->pkt_encap) {
1739
1740         case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1741                 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1742                 rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1743                 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1744                 break;
1745
1746         case WTAP_ENCAP_PPP_WITH_PHDR:
1747         case WTAP_ENCAP_SDLC:
1748                 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1749                 break;
1750
1751         case WTAP_ENCAP_FRELAY_WITH_PHDR:
1752                 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1753                 break;
1754         }
1755
1756         if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1757                 return FALSE;
1758         wdh->bytes_dumped += sizeof(rec_hdr);
1759
1760         /* write the packet data */
1761         if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1762                 return FALSE;
1763         wdh->bytes_dumped += phdr->caplen;
1764
1765         netxray->nframes++;
1766
1767         return TRUE;
1768 }
1769
1770 /* Finish writing to a dump file.
1771    Returns TRUE on success, FALSE on failure. */
1772 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1773 {
1774         char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1775         netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1776         guint32 filelen;
1777         struct netxray_hdr file_hdr;
1778
1779         filelen = (guint32)ftell(wdh->fh);      /* XXX - large files? */
1780
1781         /* Go back to beginning */
1782         fseek(wdh->fh, 0, SEEK_SET);
1783
1784         /* Rewrite the file header. */
1785         if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
1786                 return FALSE;
1787
1788         /* "sniffer" version ? */
1789         memset(&file_hdr, '\0', sizeof file_hdr);
1790         memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1791         file_hdr.start_time = htolel(netxray->start.secs);
1792         file_hdr.nframes = htolel(netxray->nframes);
1793         file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1794         file_hdr.end_offset = htolel(filelen);
1795         file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1796         file_hdr.timelo = htolel(0);
1797         file_hdr.timehi = htolel(0);
1798         switch (wdh->encap) {
1799
1800         case WTAP_ENCAP_PPP_WITH_PHDR:
1801                 file_hdr.captype = WAN_CAPTYPE_PPP;
1802                 break;
1803
1804         case WTAP_ENCAP_FRELAY_WITH_PHDR:
1805                 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1806                 break;
1807
1808         case WTAP_ENCAP_LAPB:
1809                 file_hdr.captype = WAN_CAPTYPE_HDLC;
1810                 file_hdr.wan_hdlc_subsub_captype = 0;
1811                 break;
1812
1813         case WTAP_ENCAP_SDLC:
1814                 file_hdr.captype = WAN_CAPTYPE_SDLC;
1815                 break;
1816
1817         default:
1818                 file_hdr.captype = CAPTYPE_NDIS;
1819                 break;
1820         }
1821
1822         memset(hdr_buf, '\0', sizeof hdr_buf);
1823         memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1824         if (!wtap_dump_file_write(wdh, hdr_buf, sizeof hdr_buf, err))
1825                 return FALSE;
1826
1827         return TRUE;
1828 }