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