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