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