6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
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.
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.
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.
28 #include "file_wrappers.h"
33 /* Capture file header, *including* magic number, is padded to 128 bytes. */
34 #define CAPTUREFILE_HEADER_SIZE 128
36 /* Magic number in NetXRay 1.x files. */
37 static const char old_netxray_magic[] = {
41 /* Magic number in NetXRay 2.0 and later, and Windows Sniffer, files. */
42 static const char netxray_magic[] = { /* magic header */
46 /* NetXRay file header (minus magic number). */
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) */
55 char version[8]; /* version number */
56 guint32 start_time; /* UNIX [UTC] time when capture started */
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 */
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 */
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 */
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') */
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] */
88 guint8 xxx_x60[16]; /* unknown [other stuff] */
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 ] */
99 * Capture type, in hdr.captype.
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.
106 #define CAPTYPE_NDIS 0 /* Capture on network interface using NDIS */
109 * Ethernet capture types.
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 */
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 */
135 #define CAPTYPE_ATM 15 /* ATM captured with pod */
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.
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.
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.
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.
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.
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".
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
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.)
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
194 static const double TpS[] = { 1e6, 1193000.0, 1193182.0 };
195 #define NUM_NETXRAY_TIMEUNITS (sizeof TpS / sizeof TpS[0])
198 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD.
199 * 0.0 means "unknown".
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
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).
219 static const double TpS_gigpod[] = { 1e9, 0.0, 31250000.0 };
220 #define NUM_NETXRAY_TIMEUNITS_GIGPOD (sizeof TpS_gigpod / sizeof TpS_gigpod[0])
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).
227 static const double TpS_otherpod[] = { 1e6, 0.0, 1250000.0 };
228 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD (sizeof TpS_otherpod / sizeof TpS_otherpod[0])
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).
235 static const double TpS_otherpod2[] = { 1e6, 0.0, 0.0 };
236 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD2 (sizeof TpS_otherpod2 / sizeof TpS_otherpod2[0])
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).
243 static const double TpS_gigpod2[] = { 1e9, 0.0, 20000000.0 };
244 #define NUM_NETXRAY_TIMEUNITS_GIGPOD2 (sizeof TpS_gigpod2 / sizeof TpS_gigpod2[0])
246 /* Version number strings. */
247 static const char vers_1_0[] = {
248 '0', '0', '1', '.', '0', '0', '0', '\0'
251 static const char vers_1_1[] = {
252 '0', '0', '1', '.', '1', '0', '0', '\0'
255 static const char vers_2_000[] = {
256 '0', '0', '2', '.', '0', '0', '0', '\0'
259 static const char vers_2_001[] = {
260 '0', '0', '2', '.', '0', '0', '1', '\0'
263 static const char vers_2_002[] = {
264 '0', '0', '2', '.', '0', '0', '2', '\0'
267 static const char vers_2_003[] = {
268 '0', '0', '2', '.', '0', '0', '3', '\0'
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 */
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 */
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 */
298 * Union of the data record headers.
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;
308 double ticks_per_sec;
309 double start_timestamp;
315 gboolean fcs_valid; /* if packets have valid FCS at the end */
316 guint isdn_type; /* 1 = E1 PRI, 2 = T1 PRI, 3 = BRI */
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);
339 int netxray_open(wtap *wth, int *err, gchar **err_info)
342 char magic[sizeof netxray_magic];
344 struct netxray_hdr hdr;
346 double ticks_per_sec;
347 int version_major, version_minor;
349 double start_timestamp;
350 static const int netxray_encap[] = {
353 WTAP_ENCAP_TOKEN_RING,
354 WTAP_ENCAP_FDDI_BITSWAPPED,
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.
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 */
373 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
378 /* Read in the string that should be at the start of a NetXRay
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);
389 if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
391 } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
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);
410 file_type = WTAP_FILE_NETXRAY_OLD;
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
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) {
422 file_type = WTAP_FILE_NETXRAY_1_0;
423 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
426 file_type = WTAP_FILE_NETXRAY_1_1;
427 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
430 file_type = WTAP_FILE_NETXRAY_2_00x;
431 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
434 file_type = WTAP_FILE_NETXRAY_2_00x;
435 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
438 file_type = WTAP_FILE_NETXRAY_2_00x;
439 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
442 file_type = WTAP_FILE_NETXRAY_2_00x;
444 *err = WTAP_ERR_UNSUPPORTED;
445 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
450 switch (hdr.network_plus) {
454 * The byte after hdr.network is usually 0, in which case
455 * the hdr.network byte is an NDIS network type value - 1.
457 network_type = hdr.network + 1;
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.
468 network_type = hdr.network;
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",
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);
487 * Figure out the time stamp units and start time stamp.
489 start_timestamp = (double)pletohl(&hdr.timelo)
490 + (double)pletohl(&hdr.timehi)*4294967296.0;
493 case WTAP_FILE_NETXRAY_OLD:
494 ticks_per_sec = 1000.0;
495 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
498 case WTAP_FILE_NETXRAY_1_0:
499 ticks_per_sec = 1000.0;
500 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
503 case WTAP_FILE_NETXRAY_1_1:
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.
510 ticks_per_sec = 1000000.0;
511 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
514 case WTAP_FILE_NETXRAY_2_00x:
516 * Get the time stamp units from the appropriate TpS
517 * table or from the file header.
519 switch (network_type) {
523 * Ethernet - the table to use depends on whether
524 * this is an NDIS or pod capture.
526 switch (hdr.captype) {
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);
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
543 if (hdr.timeunit == 2) {
544 ticks_per_sec = pletohl(hdr.realtick);
547 ticks_per_sec = TpS[hdr.timeunit];
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);
560 ticks_per_sec = TpS_gigpod[hdr.timeunit];
563 * At least for 002.002 and 002.003
564 * captures, the start time stamp is 0,
565 * not the value in the file.
567 if (version_minor == 2 || version_minor == 3)
568 start_timestamp = 0.0;
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);
580 ticks_per_sec = TpS_otherpod[hdr.timeunit];
583 * At least for 002.002 and 002.003
584 * captures, the start time stamp is 0,
585 * not the value in the file.
587 if (version_minor == 2 || version_minor == 3)
588 start_timestamp = 0.0;
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);
600 ticks_per_sec = TpS_otherpod2[hdr.timeunit];
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.
605 * At least for 002.002 and 002.003
606 * captures, the start time stamp is 0,
607 * not the value in the file.
609 if (version_minor == 2 || version_minor == 3)
610 start_timestamp = 0.0;
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);
622 ticks_per_sec = TpS_gigpod2[hdr.timeunit];
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.
627 * At least for 002.002 and 002.003
628 * captures, the start time stamp is 0,
629 * not the value in the file.
631 if (version_minor == 2 || version_minor == 3)
632 start_timestamp = 0.0;
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);
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,
653 ticks_per_sec = TpS[hdr.timeunit];
658 * If the number of ticks per second is greater than
659 * 1 million, make the precision be nanoseconds rather
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
667 if (ticks_per_sec >= 1e7)
668 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
670 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
674 g_assert_not_reached();
677 start_timestamp = start_timestamp/ticks_per_sec;
679 if (network_type == 4) {
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
686 * In version 2, it looks as if there's stuff in the
687 * file header to specify what particular type of WAN
690 if (version_major == 2) {
691 switch (hdr.captype) {
693 case WAN_CAPTYPE_PPP:
697 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
700 case WAN_CAPTYPE_FRELAY:
704 * XXX - in at least one capture, this
705 * is Cisco HDLC, not Frame Relay, but
706 * in another capture, it's Frame Relay.
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
712 * Cisco HDLC: hdr.xxx_x60[14:15]: 0xff 0xff
713 * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
716 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
719 case WAN_CAPTYPE_HDLC:
720 case WAN_CAPTYPE_HDLC2:
722 * Various HDLC flavors?
724 switch (hdr.wan_hdlc_subsub_captype) {
726 case 0: /* LAPB/X.25 */
728 * XXX - at least one capture of
729 * this type appears to be PPP.
731 file_encap = WTAP_ENCAP_LAPB;
737 file_encap = WTAP_ENCAP_ISDN;
738 isdn_type = hdr.wan_hdlc_subsub_captype;
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);
749 case WAN_CAPTYPE_SDLC:
753 file_encap = WTAP_ENCAP_SDLC;
756 case WAN_CAPTYPE_CHDLC:
758 * Cisco router (CHDLC) captured with pod
760 file_encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
764 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
765 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
770 file_encap = WTAP_ENCAP_ETHERNET;
772 file_encap = netxray_encap[network_type];
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;
788 * If frames have an extra 4 bytes of stuff at the end, is
789 * it an FCS, or just junk?
791 netxray->fcs_valid = FALSE;
792 switch (file_encap) {
794 case WTAP_ENCAP_ETHERNET:
795 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
796 case WTAP_ENCAP_ISDN:
797 case WTAP_ENCAP_LAPB:
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:
803 * if, in the file header, hdr.realtick[1] is 0x34
804 * and hdr.realtick[2] is 0x12, the frames have an
807 * otherwise, they have 4 bytes of junk at the end.
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.
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.
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.
823 * XXX - should we do this for all encapsulation types?
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
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.
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.)
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
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.
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.
876 if (version_major == 2) {
877 if (hdr.realtick[1] == 0x34 && hdr.realtick[2] == 0x12)
878 netxray->fcs_valid = TRUE;
884 * Remember the ISDN type, as we need it to interpret the
885 * channel number in ISDN captures.
887 netxray->isdn_type = isdn_type;
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
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);
899 /* Seek to the beginning of the data records. */
900 if (file_seek(wth->fh, netxray->start_offset, SEEK_SET, err) == -1) {
908 /* Read the next packet */
909 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
912 netxray_t *netxray = (netxray_t *)wth->priv;
914 union netxrayrec_hdr hdr;
922 * Return the offset of the record header, so we can reread it
923 * if we go back to this frame.
925 *data_offset = file_tell(wth->fh);
927 /* Have we reached the end of the packet data? */
928 if (*data_offset == netxray->end_offset) {
930 *err = 0; /* it's just an EOF, not an error */
934 /* Read record header. */
935 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err, err_info);
942 * Error of some sort; give up.
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.
967 if (netxray->start_offset < netxray->end_offset) {
968 *err = WTAP_ERR_SHORT_READ;
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)
981 /* We've already wrapped - don't wrap again. */
986 * Read the packet data.
988 if (netxray->version_major == 0)
989 packet_size = pletohs(&hdr.old_hdr.len);
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))
998 * Set the pseudo-header.
1000 padding = netxray_set_pseudo_header(wth, pd, packet_size,
1001 &wth->pseudo_header, &hdr);
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))
1013 * We subtract the padding from the packet size, so our caller
1016 wth->phdr.caplen = packet_size - padding;
1017 wth->phdr.len = wth->phdr.caplen;
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))
1028 * We subtract the padding from the packet size, so our caller
1031 wth->phdr.caplen = packet_size - padding;
1032 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
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)
1043 union netxrayrec_hdr hdr;
1046 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1049 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err,
1053 * EOF - we report that as a short read, as
1054 * we've read this once and know that it
1057 *err = WTAP_ERR_SHORT_READ;
1063 * Read the packet data.
1065 ret = netxray_read_rec_data(wth->random_fh, pd, length, err, err_info);
1070 * Set the pseudo-header.
1072 netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1077 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1078 int *err, gchar **err_info)
1080 netxray_t *netxray = (netxray_t *)wth->priv;
1084 /* Read record header. */
1085 switch (netxray->version_major) {
1088 hdr_size = sizeof (struct old_netxrayrec_hdr);
1092 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1096 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
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);
1105 if (bytes_read != 0) {
1106 *err = WTAP_ERR_SHORT_READ;
1111 * We're at EOF. "*err" is 0; we return FALSE - that
1112 * combination tells our caller we're at EOF.
1120 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1121 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1123 netxray_t *netxray = (netxray_t *)wth->priv;
1127 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1130 switch (netxray->version_major) {
1133 switch (wth->file_encap) {
1135 case WTAP_ENCAP_ETHERNET:
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.
1143 * Or is that just the low-order bit?
1145 * For now, we just say "no FCS".
1147 pseudo_header->eth.fcs_len = 0;
1153 switch (wth->file_encap) {
1155 case WTAP_ENCAP_ETHERNET:
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
1164 * It also appears that if the low-order bit of
1165 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1168 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1169 hdr->hdr_2_x.xxx[3] == 0xff) {
1171 * We have 4 bytes of stuff at the
1172 * end of the frame - FCS, or junk?
1174 if (netxray->fcs_valid) {
1178 pseudo_header->eth.fcs_len = 4;
1186 pseudo_header->eth.fcs_len = 0;
1189 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
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
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.
1206 * Ken also says that xxx[11] is 0x5 when the
1207 * packet is WEP-encrypted.
1209 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1210 hdr->hdr_2_x.xxx[3] == 0xff) {
1212 * We have 4 bytes of stuff at the
1213 * end of the frame - FCS, or junk?
1215 if (netxray->fcs_valid) {
1219 pseudo_header->ieee_802_11.fcs_len = 4;
1227 pseudo_header->ieee_802_11.fcs_len = 0;
1229 pseudo_header->ieee_802_11.decrypted = FALSE;
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];
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%.
1245 case WTAP_ENCAP_ISDN:
1249 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1250 * is the direction flag.
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
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) {
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
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;
1279 * T1 PRI. Channel numbers 0 and 24
1280 * are the D channel; channel numbers 1
1281 * through 23 are B1 through B23.
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;
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
1298 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1299 * indicate a bad FCS, as is the case with
1302 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1303 hdr->hdr_2_x.xxx[3] == 0xff) {
1305 * FCS, or junk, at the end.
1306 * XXX - is it an FCS if "fcs_valid" is
1313 case WTAP_ENCAP_LAPB:
1314 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1316 * LAPB/X.25 and Frame Relay.
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.)
1322 pseudo_header->x25.flags =
1323 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
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
1333 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1334 * indicate a bad FCS, as is the case with
1337 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1338 hdr->hdr_2_x.xxx[3] == 0xff) {
1340 * FCS, or junk, at the end.
1341 * XXX - is it an FCS if "fcs_valid" is
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;
1355 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1356 pseudo_header->atm.flags = 0;
1358 * XXX - is 0x08 an "OAM cell" flag?
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;
1368 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1370 case 0x00: /* Unknown */
1372 * Infer the AAL, traffic type, and subtype.
1374 atm_guess_traffic_type(pd, len,
1378 case 0x50: /* AAL5 (including signalling) */
1379 pseudo_header->atm.aal = AAL_5;
1380 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
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;
1389 case 0x0b: /* ILMI */
1390 pseudo_header->atm.type = TRAF_ILMI;
1391 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1394 case 0x0c: /* LANE LE Control */
1395 pseudo_header->atm.type = TRAF_LANE;
1396 pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1401 * 0x0d is *mostly* LANE 802.3,
1402 * but I've seen an LE Control frame
1405 pseudo_header->atm.type = TRAF_LANE;
1406 atm_guess_lane_type(pd, len,
1410 case 0x0f: /* LLC multiplexed */
1411 pseudo_header->atm.type = TRAF_LLCMX; /* XXX */
1412 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
1417 * XXX - discover the other types.
1419 pseudo_header->atm.type = TRAF_UNKNOWN;
1420 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1427 * 0x60 seen, and dissected by Sniffer
1428 * Pro as a raw cell.
1430 * XXX - discover what those types are.
1432 pseudo_header->atm.aal = AAL_UNKNOWN;
1433 pseudo_header->atm.type = TRAF_UNKNOWN;
1434 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1445 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1446 int *err, gchar **err_info)
1450 errno = WTAP_ERR_CANT_READ;
1451 bytes_read = file_read(data_ptr, packet_size, fh);
1453 if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1454 *err = file_error(fh, err_info);
1456 *err = WTAP_ERR_SHORT_READ;
1463 gboolean first_frame;
1464 struct wtap_nstime start;
1468 static const struct {
1469 int wtap_encap_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 */
1477 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1480 wtap_encap_to_netxray_1_1_encap(int encap)
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;
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)
1496 /* Per-packet encapsulations aren't supported. */
1497 if (encap == WTAP_ENCAP_PER_PACKET)
1498 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1500 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1501 return WTAP_ERR_UNSUPPORTED_ENCAP;
1506 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1508 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err)
1510 netxray_dump_t *netxray;
1512 wdh->subtype_write = netxray_dump_1_1;
1513 wdh->subtype_close = netxray_dump_close_1_1;
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) {
1523 wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
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;
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)
1542 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1545 struct netxrayrec_1_x_hdr rec_hdr;
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;
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);
1573 if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1575 wdh->bytes_dumped += sizeof(rec_hdr);
1577 /* write the packet data */
1578 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1580 wdh->bytes_dumped += phdr->caplen;
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)
1591 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1592 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1594 struct netxray_hdr file_hdr;
1596 filelen = (guint32)ftell(wdh->fh); /* XXX - large files? */
1598 /* Go back to beginning */
1599 fseek(wdh->fh, 0, SEEK_SET);
1601 /* Rewrite the file header. */
1602 if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
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);
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))
1624 static const struct {
1625 int wtap_encap_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 */
1637 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1640 wtap_encap_to_netxray_2_0_encap(int encap)
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;
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)
1656 /* Per-packet encapsulations aren't supported. */
1657 if (encap == WTAP_ENCAP_PER_PACKET)
1658 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1660 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1661 return WTAP_ERR_UNSUPPORTED_ENCAP;
1666 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1668 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, int *err)
1670 netxray_dump_t *netxray;
1672 wdh->subtype_write = netxray_dump_2_0;
1673 wdh->subtype_close = netxray_dump_close_2_0;
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) {
1683 wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
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;
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)
1702 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1705 struct netxrayrec_2_x_hdr rec_hdr;
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;
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);
1733 switch (phdr->pkt_encap) {
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;
1741 case WTAP_ENCAP_PPP_WITH_PHDR:
1742 case WTAP_ENCAP_SDLC:
1743 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1746 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1747 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1751 if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1753 wdh->bytes_dumped += sizeof(rec_hdr);
1755 /* write the packet data */
1756 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1758 wdh->bytes_dumped += phdr->caplen;
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)
1769 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1770 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1772 struct netxray_hdr file_hdr;
1774 filelen = (guint32)ftell(wdh->fh); /* XXX - large files? */
1776 /* Go back to beginning */
1777 fseek(wdh->fh, 0, SEEK_SET);
1779 /* Rewrite the file header. */
1780 if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
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) {
1795 case WTAP_ENCAP_PPP_WITH_PHDR:
1796 file_hdr.captype = WAN_CAPTYPE_PPP;
1799 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1800 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1803 case WTAP_ENCAP_LAPB:
1804 file_hdr.captype = WAN_CAPTYPE_HDLC;
1805 file_hdr.wan_hdlc_subsub_captype = 0;
1808 case WTAP_ENCAP_SDLC:
1809 file_hdr.captype = WAN_CAPTYPE_SDLC;
1813 file_hdr.captype = CAPTYPE_NDIS;
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))