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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include "file_wrappers.h"
36 /* Capture file header, *including* magic number, is padded to 128 bytes. */
37 #define CAPTUREFILE_HEADER_SIZE 128
39 /* Magic number in NetXRay 1.x files. */
40 static const char old_netxray_magic[] = {
44 /* Magic number in NetXRay 2.0 and later, and Windows Sniffer, files. */
45 static const char netxray_magic[] = { /* magic header */
49 /* NetXRay file header (minus magic number). */
51 /* As field usages are identified, please revise as needed */
52 /* Please do *not* use netxray_hdr xxx... names in the code */
53 /* (Placeholder names for all 'unknown' fields are */
54 /* of form xxx_x<hex_hdr_offset> */
55 /* where <hex_hdr_offset> *includes* the magic number) */
58 char version[8]; /* version number */
59 guint32 start_time; /* UNIX [UTC] time when capture started */
61 guint32 nframes; /* number of packets */
62 guint32 xxx_x14; /* unknown [some kind of file offset] */
63 guint32 start_offset; /* offset of first packet in capture */
64 guint32 end_offset; /* offset after last packet in capture */
66 guint32 xxx_x20; /* unknown [some kind of file offset] */
67 guint32 xxx_x24; /* unknown [unused ?] */
68 guint32 xxx_x28; /* unknown [some kind of file offset] */
69 guint8 network; /* datalink type */
70 guint8 network_plus; /* [See code] */
71 guint8 xxx_x2E[2]; /* unknown */
73 guint8 timeunit; /* encodes length of a tick */
74 guint8 xxx_x31[3]; /* XXX - upper 3 bytes of timeunit ? */
75 guint32 timelo; /* lower 32 bits of capture start time stamp */
76 guint32 timehi; /* upper 32 bits of capture start time stamp */
77 guint32 linespeed; /* speed of network, in bits/second */
79 guint8 xxx_x40[12]; /* unknown [other stuff] */
80 guint8 realtick[4]; /* (ticks/sec for Ethernet/Ndis/Timeunit=2 ?) */
81 /* (realtick[1], realtick[2] also curently */
82 /* used as flag for 'FCS presence') */
84 guint8 xxx_x50[4]; /* unknown [other stuff] */
85 guint8 captype; /* capture type */
86 guint8 xxx_x55[3]; /* unknown [other stuff] */
87 guint8 xxx_x58[4]; /* unknown [other stuff] */
88 guint8 wan_hdlc_subsub_captype; /* WAN HDLC subsub_captype */
89 guint8 xxx_x5D[3]; /* unknown [other stuff] */
91 guint8 xxx_x60[16]; /* unknown [other stuff] */
93 guint8 xxx_x70[14]; /* unknown [other stuff] */
94 gint16 timezone_hrs; /* timezone hours [at least for version 2.2..]; */
95 /* positive values = west of UTC: */
96 /* negative values = east of UTC: */
97 /* e.g. +5 is American Eastern */
98 /* [Does not appear to be adjusted for DST ] */
102 * Capture type, in hdr.captype.
104 * Values other than 0 are dependent on the network type.
105 * For Ethernet captures, it indicates the type of capture pod.
106 * For WAN captures (all of which are done with a pod), it indicates
107 * the link-layer type.
109 #define CAPTYPE_NDIS 0 /* Capture on network interface using NDIS */
112 * Ethernet capture types.
114 #define ETH_CAPTYPE_GIGPOD 2 /* gigabit Ethernet captured with pod */
115 #define ETH_CAPTYPE_OTHERPOD 3 /* non-gigabit Ethernet captured with pod */
116 #define ETH_CAPTYPE_OTHERPOD2 5 /* gigabit Ethernet via pod ?? */
117 /* Captype 5 seen in capture from Distributed Sniffer with: */
118 /* Version 4.50.211 software */
119 /* SysKonnect SK-9843 Gigabit Ethernet Server Adapter */
120 #define ETH_CAPTYPE_GIGPOD2 6 /* gigabit Ethernet, captured with blade on S6040-model Sniffer */
125 #define WAN_CAPTYPE_BROUTER 1 /* Bridge/router captured with pod */
126 #define WAN_CAPTYPE_PPP 3 /* PPP captured with pod */
127 #define WAN_CAPTYPE_FRELAY 4 /* Frame Relay captured with pod */
128 #define WAN_CAPTYPE_BROUTER2 5 /* Bridge/router captured with pod */
129 #define WAN_CAPTYPE_HDLC 6 /* HDLC (X.25, ISDN) captured with pod */
130 #define WAN_CAPTYPE_SDLC 7 /* SDLC captured with pod */
131 #define WAN_CAPTYPE_HDLC2 8 /* HDLC captured with pod */
132 #define WAN_CAPTYPE_BROUTER3 9 /* Bridge/router captured with pod */
133 #define WAN_CAPTYPE_SMDS 10 /* SMDS DXI */
134 #define WAN_CAPTYPE_BROUTER4 11 /* Bridge/router captured with pod */
135 #define WAN_CAPTYPE_BROUTER5 12 /* Bridge/router captured with pod */
136 #define WAN_CAPTYPE_CHDLC 19 /* Cisco router (CHDLC) captured with pod */
138 #define CAPTYPE_ATM 15 /* ATM captured with pod */
141 * # of ticks that equal 1 second, in version 002.xxx files other
142 * than Ethernet captures with a captype other than CAPTYPE_NDIS;
143 * the index into this array is hdr.timeunit.
145 * DO NOT SEND IN PATCHES THAT CHANGE ANY OF THE NON-ZERO VALUES IN
146 * ANY OF THE TpS TABLES. THOSE VALUES ARE CORRECT FOR AT LEAST ONE
147 * CAPTURE, SO CHANGING THEM WILL BREAK AT LEAST SOME CAPTURES. WE
148 * WILL NOT CHECK IN PATCHES THAT CHANGE THESE VALUES.
150 * Instead, if a value in a TpS table is wrong, check whether captype
151 * has a non-zero value; if so, perhaps we need a new TpS table for the
152 * corresponding network type and captype, or perhaps the 'realtick'
153 * field contains the correct ticks-per-second value.
155 * TpS...[] entries of 0.0 mean that no capture file for the
156 * corresponding captype/timeunit values has yet been seen, or that
157 * we're using the 'realtick' value.
159 * XXX - 05/29/07: For Ethernet captype = 0 (NDIS) and timeunit = 2:
160 * Perusal of a number of Sniffer captures
161 * (including those from Wireshark bug reports
162 * and those from the Wireshark 'menagerie)
163 * suggests that 'realtick' for this case
164 * contains the correct ticks/second to be used.
165 * So: we'll use realtick for Ethernet captype=0 and timeunit=2.
166 * (It might be that realtick should be used for Ethernet captype = 0
167 * and timeunit = 1 but I've not yet enough captures to be sure).
168 * Based upon the captures reviewed to date, realtick cannot be used for
169 * any of the other Ethernet captype/timeunit combinations for which there
170 * are non-zero values in the TpS tables.
172 * In at least one capture where "realtick" doesn't correspond
173 * to the value from the appropriate TpS table, the per-packet header's
174 * "xxx" field is all zero, so it's not as if a 2.x header includes
175 * a "compatibility" time stamp corresponding to the value from the
176 * TpS table and a "real" time stamp corresponding to "realtick".
178 * XXX - the item corresponding to timeunit = 2 is 1193180.0, presumably
179 * because somebody found it gave the right answer for some captures, but
180 * 3 times that, i.e. 3579540.0, appears to give the right answer for some
183 * Some captures have realtick of 1193182, some have 3579545, and some
184 * have 1193000. Most of those, in one set of captures somebody has,
185 * are wrong. (Did that mean "wrong for some capture files, but not
186 * for the files in which they occurred", or "wrong for the files in
187 * which they occurred? If it's "wrong for some capture files, but
188 * not for the files in which they occurred", perhaps those were Ethernet
189 * captures with a captype of 0 and timeunit = 2, so that we now use
190 * realtick, and perhaps that fixes the problems.)
192 * XXX - in at least one ATM capture, hdr.realtick is 1193180.0
193 * and hdr.timeunit is 0. Does that capture have a captype of
194 * CAPTYPE_ATM? If so, what should the table for ATM captures with
197 static double TpS[] = { 1e6, 1193000.0, 1193182.0 };
198 #define NUM_NETXRAY_TIMEUNITS (sizeof TpS / sizeof TpS[0])
201 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD.
202 * 0.0 means "unknown".
204 * It appears that, at least for Ethernet captures, if captype is
205 * ETH_CAPTYPE_GIGPOD, that indicates that it's a gigabit Ethernet
206 * capture, possibly from a special whizzo gigabit pod, and also
207 * indicates that the time stamps have some higher resolution than
208 * in other captures, possibly thanks to a high-resolution timer
211 * It also appears that the time units might differ for gigabit pod
212 * captures between version 002.001 and 002.002. For 002.001,
213 * the values below are correct; for 002.002, it's claimed that
214 * the right value for TpS_gigpod[2] is 1250000.0, but at least one
215 * 002.002 gigabit pod capture has 31250000.0 as the right value.
216 * XXX: Note that the TpS_otherpod[2] value is 1250000.0; It seems
217 * reasonable to suspect that the original claim might actually
218 * have been for a capture with a captype of 'otherpod'.
219 * (Based upon captures reviewed realtick does not contain the
220 * correct TpS values for the 'gigpod' captype).
222 static double TpS_gigpod[] = { 1e9, 0.0, 31250000.0 };
223 #define NUM_NETXRAY_TIMEUNITS_GIGPOD (sizeof TpS_gigpod / sizeof TpS_gigpod[0])
226 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD.
227 * (Based upon captures reviewed realtick does not contain the
228 * correct TpS values for the 'otherpod' captype).
230 static double TpS_otherpod[] = { 1e6, 0.0, 1250000.0 };
231 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD (sizeof TpS_otherpod / sizeof TpS_otherpod[0])
234 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD2.
235 * (Based upon captures reviewed realtick does not contain the
236 * correct TpS values for the 'otherpod2' captype).
238 static double TpS_otherpod2[] = { 1e6, 0.0, 0.0 };
239 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD2 (sizeof TpS_otherpod2 / sizeof TpS_otherpod2[0])
242 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD2.
243 * (Based upon captures reviewed realtick does not contain the
244 * correct TpS values for the 'gigpod2' captype).
246 static double TpS_gigpod2[] = { 1e9, 0.0, 20000000.0 };
247 #define NUM_NETXRAY_TIMEUNITS_GIGPOD2 (sizeof TpS_gigpod2 / sizeof TpS_gigpod2[0])
249 /* Version number strings. */
250 static const char vers_1_0[] = {
251 '0', '0', '1', '.', '0', '0', '0', '\0'
254 static const char vers_1_1[] = {
255 '0', '0', '1', '.', '1', '0', '0', '\0'
258 static const char vers_2_000[] = {
259 '0', '0', '2', '.', '0', '0', '0', '\0'
262 static const char vers_2_001[] = {
263 '0', '0', '2', '.', '0', '0', '1', '\0'
266 static const char vers_2_002[] = {
267 '0', '0', '2', '.', '0', '0', '2', '\0'
270 static const char vers_2_003[] = {
271 '0', '0', '2', '.', '0', '0', '3', '\0'
274 /* Old NetXRay data record format - followed by frame data. */
275 struct old_netxrayrec_hdr {
276 guint32 timelo; /* lower 32 bits of time stamp */
277 guint32 timehi; /* upper 32 bits of time stamp */
278 guint16 len; /* packet length */
279 guint8 xxx[6]; /* unknown */
282 /* NetXRay format version 1.x data record format - followed by frame data. */
283 struct netxrayrec_1_x_hdr {
284 guint32 timelo; /* lower 32 bits of time stamp */
285 guint32 timehi; /* upper 32 bits of time stamp */
286 guint16 orig_len; /* packet length */
287 guint16 incl_len; /* capture length */
288 guint8 xxx[16]; /* unknown */
291 /* NetXRay format version 2.x data record format - followed by frame data. */
292 struct netxrayrec_2_x_hdr {
293 guint32 timelo; /* lower 32 bits of time stamp */
294 guint32 timehi; /* upper 32 bits of time stamp */
295 guint16 orig_len; /* packet length */
296 guint16 incl_len; /* capture length */
297 guint8 xxx[28]; /* various data */
301 * Union of the data record headers.
303 union netxrayrec_hdr {
304 struct old_netxrayrec_hdr old_hdr;
305 struct netxrayrec_1_x_hdr hdr_1_x;
306 struct netxrayrec_2_x_hdr hdr_2_x;
309 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
310 gint64 *data_offset);
311 static gboolean netxray_seek_read(wtap *wth, gint64 seek_off,
312 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
313 int *err, gchar **err_info);
314 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
315 union netxrayrec_hdr *hdr, int *err);
316 static guint netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
317 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr);
318 static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr,
319 guint32 packet_size, int *err);
320 static void netxray_close(wtap *wth);
321 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
322 const struct wtap_pkthdr *phdr,
323 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
324 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
325 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
326 const struct wtap_pkthdr *phdr,
327 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
328 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
330 int netxray_open(wtap *wth, int *err, gchar **err_info)
333 char magic[sizeof netxray_magic];
335 struct netxray_hdr hdr;
337 double ticks_per_sec;
338 int version_major, version_minor;
340 double start_timestamp;
341 static const int netxray_encap[] = {
344 WTAP_ENCAP_TOKEN_RING,
345 WTAP_ENCAP_FDDI_BITSWAPPED,
347 * XXX - some PPP captures may look like Ethernet,
348 * perhaps because they're using NDIS to capture on the
349 * same machine and it provides simulated-Ethernet
350 * packets, but captures taken with various serial
351 * pods use the same network type value but aren't
352 * shaped like Ethernet. We handle that below.
354 WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */
355 WTAP_ENCAP_UNKNOWN, /* LocalTalk */
356 WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */
357 WTAP_ENCAP_UNKNOWN, /* ARCNET raw */
358 WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */
359 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,/* ATM */
360 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
361 /* Wireless WAN with radio information */
362 WTAP_ENCAP_UNKNOWN /* IrDA */
364 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
368 /* Read in the string that should be at the start of a NetXRay
370 errno = WTAP_ERR_CANT_READ;
371 bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
372 if (bytes_read != sizeof magic) {
373 *err = file_error(wth->fh);
378 wth->data_offset += sizeof magic;
380 if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
382 } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
388 /* Read the rest of the header. */
389 errno = WTAP_ERR_CANT_READ;
390 bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
391 if (bytes_read != sizeof hdr) {
392 *err = file_error(wth->fh);
397 wth->data_offset += sizeof hdr;
402 file_type = WTAP_FILE_NETXRAY_OLD;
404 /* It appears that version 1.1 files (as produced by Windows
405 * Sniffer Pro 2.0.01) have the time stamp in microseconds,
406 * rather than the milliseconds version 1.0 files appear to
409 * It also appears that version 2.00x files have per-packet
410 * headers with some extra fields. */
411 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
414 file_type = WTAP_FILE_NETXRAY_1_0;
415 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
418 file_type = WTAP_FILE_NETXRAY_1_1;
419 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
422 file_type = WTAP_FILE_NETXRAY_2_00x;
423 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
426 file_type = WTAP_FILE_NETXRAY_2_00x;
427 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
430 file_type = WTAP_FILE_NETXRAY_2_00x;
431 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
434 file_type = WTAP_FILE_NETXRAY_2_00x;
436 *err = WTAP_ERR_UNSUPPORTED;
437 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
442 switch (hdr.network_plus) {
446 * The byte after hdr.network is usually 0, in which case
447 * the hdr.network byte is an NDIS network type value - 1.
449 network_type = hdr.network + 1;
454 * However, in some Ethernet captures, it's 2, and the
455 * hdr.network byte is 1 rather than 0. We assume
456 * that if there's a byte after hdr.network with the value
457 * 2, the hdr.network byte is an NDIS network type, rather
458 * than an NDIS network type - 1.
460 network_type = hdr.network;
464 *err = WTAP_ERR_UNSUPPORTED;
465 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
470 if (network_type >= NUM_NETXRAY_ENCAPS
471 || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
472 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
473 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
474 network_type, hdr.network_plus);
479 * Figure out the time stamp units and start time stamp.
481 start_timestamp = (double)pletohl(&hdr.timelo)
482 + (double)pletohl(&hdr.timehi)*4294967296.0;
485 case WTAP_FILE_NETXRAY_OLD:
486 ticks_per_sec = 1000.0;
487 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
490 case WTAP_FILE_NETXRAY_1_0:
491 ticks_per_sec = 1000.0;
492 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
495 case WTAP_FILE_NETXRAY_1_1:
497 * In version 1.1 files (as produced by Windows Sniffer
498 * Pro 2.0.01), the time stamp is in microseconds,
499 * rather than the milliseconds time stamps in NetXRay
500 * and older versions of Windows Sniffer.
502 ticks_per_sec = 1000000.0;
503 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
506 case WTAP_FILE_NETXRAY_2_00x:
508 * Get the time stamp units from the appropriate TpS
509 * table or from the file header.
511 switch (network_type) {
515 * Ethernet - the table to use depends on whether
516 * this is an NDIS or pod capture.
518 switch (hdr.captype) {
521 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
522 *err = WTAP_ERR_UNSUPPORTED;
523 *err_info = g_strdup_printf(
524 "netxray: Unknown timeunit %u for Ethernet/CAPTYPE_NDIS version %.8s capture",
525 hdr.timeunit, hdr.version);
529 XXX: 05/29/07: Use 'realtick' instead of TpS table if timeunit=2;
530 Using 'realtick' in this case results
531 in the correct 'ticks per second' for all the captures that
532 I have of this type (including captures from a number of Wirshark
535 if (hdr.timeunit == 2) {
536 ticks_per_sec = pletohl(hdr.realtick);
539 ticks_per_sec = TpS[hdr.timeunit];
543 case ETH_CAPTYPE_GIGPOD:
544 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD
545 || TpS_gigpod[hdr.timeunit] == 0.0) {
546 *err = WTAP_ERR_UNSUPPORTED;
547 *err_info = g_strdup_printf(
548 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD version %.8s capture",
549 hdr.timeunit, hdr.version);
552 ticks_per_sec = TpS_gigpod[hdr.timeunit];
555 * At least for 002.002 and 002.003
556 * captures, the start time stamp is 0,
557 * not the value in the file.
559 if (version_minor == 2 || version_minor == 3)
560 start_timestamp = 0.0;
563 case ETH_CAPTYPE_OTHERPOD:
564 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD
565 || TpS_otherpod[hdr.timeunit] == 0.0) {
566 *err = WTAP_ERR_UNSUPPORTED;
567 *err_info = g_strdup_printf(
568 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD version %.8s capture",
569 hdr.timeunit, hdr.version);
572 ticks_per_sec = TpS_otherpod[hdr.timeunit];
575 * At least for 002.002 and 002.003
576 * captures, the start time stamp is 0,
577 * not the value in the file.
579 if (version_minor == 2 || version_minor == 3)
580 start_timestamp = 0.0;
583 case ETH_CAPTYPE_OTHERPOD2:
584 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD2
585 || TpS_otherpod2[hdr.timeunit] == 0.0) {
586 *err = WTAP_ERR_UNSUPPORTED;
587 *err_info = g_strdup_printf(
588 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD2 version %.8s capture",
589 hdr.timeunit, hdr.version);
592 ticks_per_sec = TpS_otherpod2[hdr.timeunit];
594 * XXX: start time stamp in the one capture file examined of this type was 0;
595 * We'll assume the start time handling is the same as for other pods.
597 * At least for 002.002 and 002.003
598 * captures, the start time stamp is 0,
599 * not the value in the file.
601 if (version_minor == 2 || version_minor == 3)
602 start_timestamp = 0.0;
605 case ETH_CAPTYPE_GIGPOD2:
606 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD2
607 || TpS_gigpod2[hdr.timeunit] == 0.0) {
608 *err = WTAP_ERR_UNSUPPORTED;
609 *err_info = g_strdup_printf(
610 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD2 version %.8s capture",
611 hdr.timeunit, hdr.version);
614 ticks_per_sec = TpS_gigpod2[hdr.timeunit];
616 * XXX: start time stamp in the one capture file examined of this type was 0;
617 * We'll assume the start time handling is the same as for other pods.
619 * At least for 002.002 and 002.003
620 * captures, the start time stamp is 0,
621 * not the value in the file.
623 if (version_minor == 2 || version_minor == 3)
624 start_timestamp = 0.0;
628 *err = WTAP_ERR_UNSUPPORTED;
629 *err_info = g_strdup_printf(
630 "netxray: Unknown capture type %u for Ethernet version %.8s capture",
631 hdr.captype, hdr.version);
637 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
638 *err = WTAP_ERR_UNSUPPORTED;
639 *err_info = g_strdup_printf(
640 "netxray: Unknown timeunit %u for %u/%u version %.8s capture",
641 hdr.timeunit, network_type, hdr.captype,
645 ticks_per_sec = TpS[hdr.timeunit];
650 * If the number of ticks per second is greater than
651 * 1 million, make the precision be nanoseconds rather
654 * XXX - do values only slightly greater than one million
655 * correspond to a resolution sufficiently better than
656 * 1 microsecond to display more digits of precision?
657 * XXX - Seems reasonable to use nanosecs only if TPS >= 10M
659 if (ticks_per_sec >= 1e7)
660 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
662 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
666 g_assert_not_reached();
669 start_timestamp = start_timestamp/ticks_per_sec;
671 if (network_type == 4) {
673 * In version 0 and 1, we assume, for now, that all
674 * WAN captures have frames that look like Ethernet
675 * frames (as a result, presumably, of having passed
678 * In version 2, it looks as if there's stuff in the
679 * file header to specify what particular type of WAN
682 if (version_major == 2) {
683 switch (hdr.captype) {
685 case WAN_CAPTYPE_PPP:
689 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
692 case WAN_CAPTYPE_FRELAY:
696 * XXX - in at least one capture, this
697 * is Cisco HDLC, not Frame Relay, but
698 * in another capture, it's Frame Relay.
700 * [Bytes in each capture:
701 * Cisco HDLC: hdr.xxx_x60[06:10]: 0x02 0x00 0x01 0x00 0x06
702 * Frame Relay: hdr.xxx_x60[06:10] 0x00 0x00 0x00 0x00 0x00
704 * Cisco HDLC: hdr.xxx_x60[14:15]: 0xff 0xff
705 * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
708 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
711 case WAN_CAPTYPE_HDLC:
712 case WAN_CAPTYPE_HDLC2:
714 * Various HDLC flavors?
716 switch (hdr.wan_hdlc_subsub_captype) {
718 case 0: /* LAPB/X.25 */
719 file_encap = WTAP_ENCAP_LAPB;
725 file_encap = WTAP_ENCAP_ISDN;
726 isdn_type = hdr.wan_hdlc_subsub_captype;
730 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
731 *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
732 hdr.wan_hdlc_subsub_captype);
737 case WAN_CAPTYPE_SDLC:
741 file_encap = WTAP_ENCAP_SDLC;
744 case WAN_CAPTYPE_CHDLC:
746 * Cisco router (CHDLC) captured with pod
748 file_encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
752 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
753 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
758 file_encap = WTAP_ENCAP_ETHERNET;
760 file_encap = netxray_encap[network_type];
762 /* This is a netxray file */
763 wth->file_type = file_type;
764 wth->capture.netxray = g_malloc(sizeof(netxray_t));
765 wth->subtype_read = netxray_read;
766 wth->subtype_seek_read = netxray_seek_read;
767 wth->subtype_close = netxray_close;
768 wth->file_encap = file_encap;
769 wth->snapshot_length = 0; /* not available in header */
770 wth->capture.netxray->start_time = pletohl(&hdr.start_time);
771 wth->capture.netxray->ticks_per_sec = ticks_per_sec;
772 wth->capture.netxray->start_timestamp = start_timestamp;
773 wth->capture.netxray->version_major = version_major;
776 * If frames have an extra 4 bytes of stuff at the end, is
777 * it an FCS, or just junk?
779 wth->capture.netxray->fcs_valid = FALSE;
780 switch (file_encap) {
782 case WTAP_ENCAP_ETHERNET:
783 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
784 case WTAP_ENCAP_ISDN:
785 case WTAP_ENCAP_LAPB:
787 * It appears that, in at least some version 2 Ethernet
788 * captures, for frames that have 0xff in hdr_2_x.xxx[2]
789 * and hdr_2_x.xxx[3] in the per-packet header:
791 * if, in the file header, hdr.realtick[1] is 0x34
792 * and hdr.realtick[2] is 0x12, the frames have an
795 * otherwise, they have 4 bytes of junk at the end.
797 * Yes, it's strange that you have to check the *middle*
798 * of the time stamp field; you can't check for any
799 * particular value of the time stamp field.
801 * For now, we assume that to be true for 802.11 captures
802 * as well; it appears to be the case for at least one
803 * such capture - the file doesn't have 0x34 and 0x12,
804 * and the 4 bytes at the end of the frames with 0xff
805 * are junk, not an FCS.
807 * For ISDN captures, it appears, at least in some
808 * captures, to be similar, although I haven't yet
809 * checked whether it's a valid FCS.
811 * XXX - should we do this for all encapsulation types?
813 * XXX - is there some other field that *really* indicates
814 * whether we have an FCS or not? The check of the time
815 * stamp is bizarre, as we're checking the middle.
816 * Perhaps hdr.realtick[0] is 0x00, in which case time
817 * stamp units in the range 1192960 through 1193215
818 * correspond to captures with an FCS, but that's still
821 * Note that there are captures with a network type of 0
822 * (Ethernet) and capture type of 0 (NDIS) that do, and
823 * that don't, have 0x34 0x12 in them, and at least one
824 * of the NDIS captures with 0x34 0x12 in it has FCSes,
825 * so it's not as if no NDIS captures have an FCS.
827 * There are also captures with a network type of 4 (WAN),
828 * capture type of 6 (HDLC), and subtype of 2 (T1 PRI) that
829 * do, and that don't, have 0x34 0x12, so there are at least
830 * some captures taken with a WAN pod that might lack an FCS.
831 * (We haven't yet tried dissecting the 4 bytes at the
832 * end of packets with hdr_2_x.xxx[2] and hdr_2_x.xxx[3]
833 * equal to 0xff as an FCS.)
835 * All captures I've seen that have 0x34 and 0x12 *and*
836 * have at least one frame with an FCS have a value of
837 * 0x01 in xxx_x40[4]. No captures I've seen with a network
838 * type of 0 (Ethernet) missing 0x34 0x12 have 0x01 there,
839 * however. However, there's at least one capture
840 * without 0x34 and 0x12, with a network type of 0,
841 * and with 0x01 in xxx_x40[4], *without* FCSes in the
842 * frames - the 4 bytes at the end are all zero - so it's
843 * not as simple as "xxx_x40[4] = 0x01 means the 4 bytes at
844 * the end are FCSes". Also, there's also at least one
845 * 802.11 capture with an xxx_x40[4] value of 0x01 with junk
846 * rather than an FCS at the end of the frame, so xxx_x40[4]
847 * isn't an obvious flag to determine whether the
850 * There don't seem to be any other values in any of the
851 * xxx_x5..., xxx_x6...., xxx_x7.... fields
852 * that obviously correspond to frames having an FCS.
854 * 05/29/07: Examination of numerous sniffer captures suggests
855 * that the apparent correlation of certain realtick
856 * bytes to 'FCS presence' may actually be
857 * a 'false positive'.
858 * ToDo: Review analysis and update code.
859 * It might be that the ticks-per-second value
860 * is hardware-dependent, and that hardware with
861 * a particular realtick value puts an FCS there
862 * and other hardware doesn't.
864 if (version_major == 2) {
865 if (hdr.realtick[1] == 0x34 && hdr.realtick[2] == 0x12)
866 wth->capture.netxray->fcs_valid = TRUE;
872 * Remember the ISDN type, as we need it to interpret the
873 * channel number in ISDN captures.
875 wth->capture.netxray->isdn_type = isdn_type;
877 /* Remember the offset after the last packet in the capture (which
878 * isn't necessarily the last packet in the file), as it appears
879 * there's sometimes crud after it.
880 * XXX: Remember 'start_offset' to help testing for 'short file' at EOF
882 wth->capture.netxray->wrapped = FALSE;
883 wth->capture.netxray->nframes = pletohl(&hdr.nframes);
884 wth->capture.netxray->start_offset = pletohl(&hdr.start_offset);
885 wth->capture.netxray->end_offset = pletohl(&hdr.end_offset);
887 /* Seek to the beginning of the data records. */
888 if (file_seek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET, err) == -1) {
889 g_free(wth->capture.netxray);
892 wth->data_offset = pletohl(&hdr.start_offset);
897 /* Read the next packet */
898 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info _U_,
902 union netxrayrec_hdr hdr;
909 /* Have we reached the end of the packet data? */
910 if (wth->data_offset == wth->capture.netxray->end_offset) {
912 *err = 0; /* it's just an EOF, not an error */
915 /* Read record header. */
916 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err);
923 * Error of some sort; give up.
928 /* We're at EOF. Wrap?
929 * XXX: Need to handle 'short file' cases
930 * (Distributed Sniffer seems to have a
931 * certain small propensity to generate 'short' files
932 * i.e. [many] bytes are missing from the end of the file)
933 * case 1: start_offset < end_offset
934 * wrap will read already read packets again;
935 * so: error with "short file"
936 * case 2: start_offset > end_offset ("circular" file)
937 * wrap will mean there's a gap (missing packets).
938 * However, I don't see a good way to identify this
939 * case so we'll just have to allow the wrap.
940 * (Maybe there can be an error message after all
941 * packets are read since there'll be less packets than
942 * specified in the file header).
943 * Note that these cases occur *only* if a 'short' eof occurs exactly
944 * at the expected beginning of a frame header record; If there is a
945 * partial frame header (or partial frame data) record, then the
946 * netxray_read... functions will detect the short record.
948 if (wth->capture.netxray->start_offset < wth->capture.netxray->end_offset) {
949 *err = WTAP_ERR_SHORT_READ;
953 if (!wth->capture.netxray->wrapped) {
954 /* Yes. Remember that we did. */
955 wth->capture.netxray->wrapped = TRUE;
956 if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
957 SEEK_SET, err) == -1)
959 wth->data_offset = CAPTUREFILE_HEADER_SIZE;
963 /* We've already wrapped - don't wrap again. */
968 * Return the offset of the record header, so we can reread it
969 * if we go back to this frame.
971 *data_offset = wth->data_offset;
972 wth->data_offset += hdr_size;
975 * Read the packet data.
977 if (wth->capture.netxray->version_major == 0)
978 packet_size = pletohs(&hdr.old_hdr.len);
980 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
981 buffer_assure_space(wth->frame_buffer, packet_size);
982 pd = buffer_start_ptr(wth->frame_buffer);
983 if (!netxray_read_rec_data(wth->fh, pd, packet_size, err))
985 wth->data_offset += packet_size;
988 * Set the pseudo-header.
990 padding = netxray_set_pseudo_header(wth, pd, packet_size,
991 &wth->pseudo_header, &hdr);
993 if (wth->capture.netxray->version_major == 0) {
994 t = (double)pletohl(&hdr.old_hdr.timelo)
995 + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
996 t /= wth->capture.netxray->ticks_per_sec;
997 t -= wth->capture.netxray->start_timestamp;
998 wth->phdr.ts.secs = wth->capture.netxray->start_time + (long)t;
999 wth->phdr.ts.nsecs = (unsigned long)((t-(double)(unsigned long)(t))
1002 * We subtract the padding from the packet size, so our caller
1005 wth->phdr.caplen = packet_size - padding;
1006 wth->phdr.len = wth->phdr.caplen;
1008 t = (double)pletohl(&hdr.hdr_1_x.timelo)
1009 + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
1010 t /= wth->capture.netxray->ticks_per_sec;
1011 t -= wth->capture.netxray->start_timestamp;
1012 wth->phdr.ts.secs = wth->capture.netxray->start_time + (long)t;
1013 wth->phdr.ts.nsecs = (unsigned long)((t-(double)(unsigned long)(t))
1016 * We subtract the padding from the packet size, so our caller
1019 wth->phdr.caplen = packet_size - padding;
1020 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
1027 netxray_seek_read(wtap *wth, gint64 seek_off,
1028 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
1029 int *err, gchar **err_info _U_)
1031 union netxrayrec_hdr hdr;
1034 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1037 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) {
1040 * EOF - we report that as a short read, as
1041 * we've read this once and know that it
1044 *err = WTAP_ERR_SHORT_READ;
1050 * Read the packet data.
1052 ret = netxray_read_rec_data(wth->random_fh, pd, length, err);
1057 * Set the pseudo-header.
1059 netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1064 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1070 /* Read record header. */
1071 switch (wth->capture.netxray->version_major) {
1074 hdr_size = sizeof (struct old_netxrayrec_hdr);
1078 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1082 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1085 errno = WTAP_ERR_CANT_READ;
1086 bytes_read = file_read(hdr, 1, hdr_size, fh);
1087 if (bytes_read != hdr_size) {
1088 *err = file_error(wth->fh);
1091 if (bytes_read != 0) {
1092 *err = WTAP_ERR_SHORT_READ;
1097 * We're at EOF. "*err" is 0; we return FALSE - that
1098 * combination tells our caller we're at EOF.
1106 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1107 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1112 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1115 switch (wth->capture.netxray->version_major) {
1118 switch (wth->file_encap) {
1120 case WTAP_ENCAP_ETHERNET:
1122 * XXX - if hdr->hdr_1_x.xxx[15] is 1
1123 * the frame appears not to have any extra
1124 * stuff at the end, but if it's 0,
1125 * there appears to be 4 bytes of stuff
1126 * at the end, but it's not an FCS.
1128 * Or is that just the low-order bit?
1130 * For now, we just say "no FCS".
1132 pseudo_header->eth.fcs_len = 0;
1138 switch (wth->file_encap) {
1140 case WTAP_ENCAP_ETHERNET:
1142 * It appears, at least with version 2 captures,
1143 * that we have 4 bytes of stuff (which might be
1144 * a valid FCS or might be junk) at the end of
1145 * the packet if hdr->hdr_2_x.xxx[2] and
1146 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1149 * It also appears that if the low-order bit of
1150 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1153 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1154 hdr->hdr_2_x.xxx[3] == 0xff) {
1156 * We have 4 bytes of stuff at the
1157 * end of the frame - FCS, or junk?
1159 if (wth->capture.netxray->fcs_valid) {
1163 pseudo_header->eth.fcs_len = 4;
1171 pseudo_header->eth.fcs_len = 0;
1174 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1176 * It appears, in one 802.11 capture, that
1177 * we have 4 bytes of junk at the ends of
1178 * frames in which hdr->hdr_2_x.xxx[2] and
1179 * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1180 * seen any frames where it's an FCS, but,
1181 * for now, we still check the fcs_valid
1182 * flag - I also haven't seen any capture
1183 * where we'd set it based on the realtick
1186 * It also appears that if the low-order bit of
1187 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1188 * bad FCS. According to Ken Mann, the 0x4 bit
1189 * is sometimes also set for errors.
1191 * Ken also says that xxx[11] is 0x5 when the
1192 * packet is WEP-encrypted.
1194 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1195 hdr->hdr_2_x.xxx[3] == 0xff) {
1197 * We have 4 bytes of stuff at the
1198 * end of the frame - FCS, or junk?
1200 if (wth->capture.netxray->fcs_valid) {
1204 pseudo_header->ieee_802_11.fcs_len = 4;
1212 pseudo_header->ieee_802_11.fcs_len = 0;
1214 pseudo_header->ieee_802_11.channel =
1215 hdr->hdr_2_x.xxx[12];
1216 pseudo_header->ieee_802_11.data_rate =
1217 hdr->hdr_2_x.xxx[13];
1218 pseudo_header->ieee_802_11.signal_level =
1219 hdr->hdr_2_x.xxx[14];
1221 * According to Ken Mann, at least in the captures
1222 * he's seen, xxx[15] is the noise level, which
1223 * is either 0xFF meaning "none reported" or a value
1224 * from 0x00 to 0x7F for 0 to 100%.
1228 case WTAP_ENCAP_ISDN:
1232 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1233 * is the direction flag.
1235 * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
1236 * are the channel number, but some mapping is
1237 * required for PRI. (Is it really just the time
1240 pseudo_header->isdn.uton =
1241 (hdr->hdr_2_x.xxx[12] & 0x01);
1242 pseudo_header->isdn.channel =
1243 hdr->hdr_2_x.xxx[13] & 0x1F;
1244 switch (wth->capture.netxray->isdn_type) {
1248 * E1 PRI. Channel numbers 0 and 16
1249 * are the D channel; channel numbers 1
1250 * through 15 are B1 through B15; channel
1251 * numbers 17 through 31 are B16 through
1254 if (pseudo_header->isdn.channel == 16)
1255 pseudo_header->isdn.channel = 0;
1256 else if (pseudo_header->isdn.channel > 16)
1257 pseudo_header->isdn.channel -= 1;
1262 * T1 PRI. Channel numbers 0 and 24
1263 * are the D channel; channel numbers 1
1264 * through 23 are B1 through B23.
1266 if (pseudo_header->isdn.channel == 24)
1267 pseudo_header->isdn.channel = 0;
1268 else if (pseudo_header->isdn.channel > 24)
1269 pseudo_header->isdn.channel -= 1;
1274 * It appears, at least with version 2 captures,
1275 * that we have 4 bytes of stuff (which might be
1276 * a valid FCS or might be junk) at the end of
1277 * the packet if hdr->hdr_2_x.xxx[2] and
1278 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1281 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1282 * indicate a bad FCS, as is the case with
1285 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1286 hdr->hdr_2_x.xxx[3] == 0xff) {
1288 * FCS, or junk, at the end.
1289 * XXX - is it an FCS if "fcs_valid" is
1296 case WTAP_ENCAP_LAPB:
1297 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1299 * LAPB/X.25 and Frame Relay.
1301 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1302 * is the direction flag. (Probably true for other
1303 * HDLC encapsulations as well.)
1305 pseudo_header->x25.flags =
1306 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1309 * It appears, at least with version 2 captures,
1310 * that we have 4 bytes of stuff (which might be
1311 * a valid FCS or might be junk) at the end of
1312 * the packet if hdr->hdr_2_x.xxx[2] and
1313 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1316 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1317 * indicate a bad FCS, as is the case with
1320 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1321 hdr->hdr_2_x.xxx[3] == 0xff) {
1323 * FCS, or junk, at the end.
1324 * XXX - is it an FCS if "fcs_valid" is
1331 case WTAP_ENCAP_PPP_WITH_PHDR:
1332 case WTAP_ENCAP_SDLC:
1333 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1334 pseudo_header->p2p.sent =
1335 (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1338 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1339 pseudo_header->atm.flags = 0;
1341 * XXX - is 0x08 an "OAM cell" flag?
1343 if (hdr->hdr_2_x.xxx[9] & 0x04)
1344 pseudo_header->atm.flags |= ATM_RAW_CELL;
1345 pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
1346 pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1347 pseudo_header->atm.channel =
1348 (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1349 pseudo_header->atm.cells = 0;
1351 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1353 case 0x00: /* Unknown */
1355 * Infer the AAL, traffic type, and subtype.
1357 atm_guess_traffic_type(pd, len,
1361 case 0x50: /* AAL5 (including signalling) */
1362 pseudo_header->atm.aal = AAL_5;
1363 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1366 case 0x0a: /* Signalling traffic */
1367 pseudo_header->atm.aal = AAL_SIGNALLING;
1368 pseudo_header->atm.type = TRAF_UNKNOWN;
1369 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1372 case 0x0b: /* ILMI */
1373 pseudo_header->atm.type = TRAF_ILMI;
1374 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1377 case 0x0c: /* LANE LE Control */
1378 pseudo_header->atm.type = TRAF_LANE;
1379 pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1384 * 0x0d is *mostly* LANE 802.3,
1385 * but I've seen an LE Control frame
1388 pseudo_header->atm.type = TRAF_LANE;
1389 atm_guess_lane_type(pd, len,
1393 case 0x0f: /* LLC multiplexed */
1394 pseudo_header->atm.type = TRAF_LLCMX; /* XXX */
1395 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
1400 * XXX - discover the other types.
1402 pseudo_header->atm.type = TRAF_UNKNOWN;
1403 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1410 * 0x60 seen, and dissected by Sniffer
1411 * Pro as a raw cell.
1413 * XXX - discover what those types are.
1415 pseudo_header->atm.aal = AAL_UNKNOWN;
1416 pseudo_header->atm.type = TRAF_UNKNOWN;
1417 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1428 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1433 errno = WTAP_ERR_CANT_READ;
1434 bytes_read = file_read(data_ptr, 1, packet_size, fh);
1436 if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1437 *err = file_error(fh);
1439 *err = WTAP_ERR_SHORT_READ;
1446 netxray_close(wtap *wth)
1448 g_free(wth->capture.netxray);
1451 static const struct {
1452 int wtap_encap_value;
1454 } wtap_encap_1_1[] = {
1455 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1456 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1457 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1458 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1460 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1463 wtap_encap_to_netxray_1_1_encap(int encap)
1467 for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1468 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1469 return wtap_encap_1_1[i].ndis_value;
1475 /* Returns 0 if we could write the specified encapsulation type,
1476 an error indication otherwise. */
1477 int netxray_dump_can_write_encap_1_1(int encap)
1479 /* Per-packet encapsulations aren't supported. */
1480 if (encap == WTAP_ENCAP_PER_PACKET)
1481 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1483 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1484 return WTAP_ERR_UNSUPPORTED_ENCAP;
1489 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1491 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
1493 /* This is a NetXRay file. We can't fill in some fields in the header
1494 until all the packets have been written, so we can't write to a
1497 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1501 wdh->subtype_write = netxray_dump_1_1;
1502 wdh->subtype_close = netxray_dump_close_1_1;
1504 /* We can't fill in all the fields in the file header, as we
1505 haven't yet written any packets. As we'll have to rewrite
1506 the header when we've written out all the packets, we just
1507 skip over the header for now. */
1508 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1513 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1514 wdh->dump.netxray->first_frame = TRUE;
1515 wdh->dump.netxray->start.secs = 0;
1516 wdh->dump.netxray->start.nsecs = 0;
1517 wdh->dump.netxray->nframes = 0;
1522 /* Write a record for a packet to a dump file.
1523 Returns TRUE on success, FALSE on failure. */
1524 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1525 const struct wtap_pkthdr *phdr,
1526 const union wtap_pseudo_header *pseudo_header _U_,
1527 const guchar *pd, int *err)
1529 netxray_dump_t *netxray = wdh->dump.netxray;
1532 struct netxrayrec_1_x_hdr rec_hdr;
1535 /* NetXRay/Windows Sniffer files have a capture start date/time
1536 in the header, in a UNIX-style format, with one-second resolution,
1537 and a start time stamp with microsecond resolution that's just
1538 an arbitrary time stamp relative to some unknown time (boot
1539 time?), and have times relative to the start time stamp in
1540 the packet headers; pick the seconds value of the time stamp
1541 of the first packet as the UNIX-style start date/time, and make
1542 the high-resolution start time stamp 0, with the time stamp of
1543 packets being the delta between the stamp of the packet and
1544 the stamp of the first packet with the microseconds part 0. */
1545 if (netxray->first_frame) {
1546 netxray->first_frame = FALSE;
1547 netxray->start = phdr->ts;
1550 /* build the header for each packet */
1551 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1552 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1553 + ((guint64)phdr->ts.nsecs)/1000;
1554 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1555 rec_hdr.timelo = htolel(t32);
1556 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1557 rec_hdr.timehi = htolel(t32);
1558 rec_hdr.orig_len = htoles(phdr->len);
1559 rec_hdr.incl_len = htoles(phdr->caplen);
1561 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1562 if (nwritten != sizeof(rec_hdr)) {
1563 if (nwritten == 0 && ferror(wdh->fh))
1566 *err = WTAP_ERR_SHORT_WRITE;
1570 /* write the packet data */
1571 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1572 if (nwritten != phdr->caplen) {
1573 if (nwritten == 0 && ferror(wdh->fh))
1576 *err = WTAP_ERR_SHORT_WRITE;
1585 /* Finish writing to a dump file.
1586 Returns TRUE on success, FALSE on failure. */
1587 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1589 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1590 netxray_dump_t *netxray = wdh->dump.netxray;
1592 struct netxray_hdr file_hdr;
1595 filelen = ftell(wdh->fh);
1597 /* Go back to beginning */
1598 fseek(wdh->fh, 0, SEEK_SET);
1600 /* Rewrite the file header. */
1601 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1602 if (nwritten != sizeof netxray_magic) {
1604 if (nwritten == 0 && ferror(wdh->fh))
1607 *err = WTAP_ERR_SHORT_WRITE;
1612 /* "sniffer" version ? */
1613 memset(&file_hdr, '\0', sizeof file_hdr);
1614 memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1615 file_hdr.start_time = htolel(netxray->start.secs);
1616 file_hdr.nframes = htolel(netxray->nframes);
1617 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1618 file_hdr.end_offset = htolel(filelen);
1619 file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1620 file_hdr.timelo = htolel(0);
1621 file_hdr.timehi = htolel(0);
1623 memset(hdr_buf, '\0', sizeof hdr_buf);
1624 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1625 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1626 if (nwritten != sizeof hdr_buf) {
1628 if (nwritten == 0 && ferror(wdh->fh))
1631 *err = WTAP_ERR_SHORT_WRITE;
1639 static const struct {
1640 int wtap_encap_value;
1642 } wtap_encap_2_0[] = {
1643 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1644 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1645 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1646 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1647 { WTAP_ENCAP_PPP_WITH_PHDR, 3 }, /* -> NDIS WAN */
1648 { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 }, /* -> NDIS WAN */
1649 { WTAP_ENCAP_LAPB, 3 }, /* -> NDIS WAN */
1650 { WTAP_ENCAP_SDLC, 3 }, /* -> NDIS WAN */
1652 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1655 wtap_encap_to_netxray_2_0_encap(int encap)
1659 for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1660 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1661 return wtap_encap_2_0[i].ndis_value;
1667 /* Returns 0 if we could write the specified encapsulation type,
1668 an error indication otherwise. */
1669 int netxray_dump_can_write_encap_2_0(int encap)
1671 /* Per-packet encapsulations aren't supported. */
1672 if (encap == WTAP_ENCAP_PER_PACKET)
1673 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1675 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1676 return WTAP_ERR_UNSUPPORTED_ENCAP;
1681 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1683 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
1685 /* This is a NetXRay file. We can't fill in some fields in the header
1686 until all the packets have been written, so we can't write to a
1689 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1693 wdh->subtype_write = netxray_dump_2_0;
1694 wdh->subtype_close = netxray_dump_close_2_0;
1696 /* We can't fill in all the fields in the file header, as we
1697 haven't yet written any packets. As we'll have to rewrite
1698 the header when we've written out all the packets, we just
1699 skip over the header for now. */
1700 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1705 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1706 wdh->dump.netxray->first_frame = TRUE;
1707 wdh->dump.netxray->start.secs = 0;
1708 wdh->dump.netxray->start.nsecs = 0;
1709 wdh->dump.netxray->nframes = 0;
1714 /* Write a record for a packet to a dump file.
1715 Returns TRUE on success, FALSE on failure. */
1716 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1717 const struct wtap_pkthdr *phdr,
1718 const union wtap_pseudo_header *pseudo_header _U_,
1719 const guchar *pd, int *err)
1721 netxray_dump_t *netxray = wdh->dump.netxray;
1724 struct netxrayrec_2_x_hdr rec_hdr;
1727 /* NetXRay/Windows Sniffer files have a capture start date/time
1728 in the header, in a UNIX-style format, with one-second resolution,
1729 and a start time stamp with microsecond resolution that's just
1730 an arbitrary time stamp relative to some unknown time (boot
1731 time?), and have times relative to the start time stamp in
1732 the packet headers; pick the seconds value of the time stamp
1733 of the first packet as the UNIX-style start date/time, and make
1734 the high-resolution start time stamp 0, with the time stamp of
1735 packets being the delta between the stamp of the packet and
1736 the stamp of the first packet with the microseconds part 0. */
1737 if (netxray->first_frame) {
1738 netxray->first_frame = FALSE;
1739 netxray->start = phdr->ts;
1742 /* build the header for each packet */
1743 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1744 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1745 + ((guint64)phdr->ts.nsecs)/1000;
1746 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1747 rec_hdr.timelo = htolel(t32);
1748 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1749 rec_hdr.timehi = htolel(t32);
1750 rec_hdr.orig_len = htoles(phdr->len);
1751 rec_hdr.incl_len = htoles(phdr->caplen);
1753 switch (phdr->pkt_encap) {
1755 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1756 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1757 rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1758 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1761 case WTAP_ENCAP_PPP_WITH_PHDR:
1762 case WTAP_ENCAP_SDLC:
1763 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1766 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1767 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1771 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1772 if (nwritten != sizeof(rec_hdr)) {
1773 if (nwritten == 0 && ferror(wdh->fh))
1776 *err = WTAP_ERR_SHORT_WRITE;
1780 /* write the packet data */
1781 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1782 if (nwritten != phdr->caplen) {
1783 if (nwritten == 0 && ferror(wdh->fh))
1786 *err = WTAP_ERR_SHORT_WRITE;
1795 /* Finish writing to a dump file.
1796 Returns TRUE on success, FALSE on failure. */
1797 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1799 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1800 netxray_dump_t *netxray = wdh->dump.netxray;
1802 struct netxray_hdr file_hdr;
1805 filelen = ftell(wdh->fh);
1807 /* Go back to beginning */
1808 fseek(wdh->fh, 0, SEEK_SET);
1810 /* Rewrite the file header. */
1811 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1812 if (nwritten != sizeof netxray_magic) {
1814 if (nwritten == 0 && ferror(wdh->fh))
1817 *err = WTAP_ERR_SHORT_WRITE;
1822 /* "sniffer" version ? */
1823 memset(&file_hdr, '\0', sizeof file_hdr);
1824 memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1825 file_hdr.start_time = htolel(netxray->start.secs);
1826 file_hdr.nframes = htolel(netxray->nframes);
1827 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1828 file_hdr.end_offset = htolel(filelen);
1829 file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1830 file_hdr.timelo = htolel(0);
1831 file_hdr.timehi = htolel(0);
1832 switch (wdh->encap) {
1834 case WTAP_ENCAP_PPP_WITH_PHDR:
1835 file_hdr.captype = WAN_CAPTYPE_PPP;
1838 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1839 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1842 case WTAP_ENCAP_LAPB:
1843 file_hdr.captype = WAN_CAPTYPE_HDLC;
1844 file_hdr.wan_hdlc_subsub_captype = 0;
1847 case WTAP_ENCAP_SDLC:
1848 file_hdr.captype = WAN_CAPTYPE_SDLC;
1852 file_hdr.captype = CAPTYPE_NDIS;
1856 memset(hdr_buf, '\0', sizeof hdr_buf);
1857 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1858 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1859 if (nwritten != sizeof hdr_buf) {
1861 if (nwritten == 0 && ferror(wdh->fh))
1864 *err = WTAP_ERR_SHORT_WRITE;