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 currently */
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 const 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 const 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 const 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 const 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 const 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;
311 double ticks_per_sec;
312 double start_timestamp;
318 gboolean fcs_valid; /* if packets have valid FCS at the end */
319 guint isdn_type; /* 1 = E1 PRI, 2 = T1 PRI, 3 = BRI */
322 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
323 gint64 *data_offset);
324 static gboolean netxray_seek_read(wtap *wth, gint64 seek_off,
325 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
326 int *err, gchar **err_info);
327 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
328 union netxrayrec_hdr *hdr, int *err);
329 static guint netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
330 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr);
331 static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr,
332 guint32 packet_size, int *err);
333 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
334 const struct wtap_pkthdr *phdr,
335 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
336 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
337 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
338 const struct wtap_pkthdr *phdr,
339 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
340 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
342 int netxray_open(wtap *wth, int *err, gchar **err_info)
345 char magic[sizeof netxray_magic];
347 struct netxray_hdr hdr;
349 double ticks_per_sec;
350 int version_major, version_minor;
352 double start_timestamp;
353 static const int netxray_encap[] = {
356 WTAP_ENCAP_TOKEN_RING,
357 WTAP_ENCAP_FDDI_BITSWAPPED,
359 * XXX - some PPP captures may look like Ethernet,
360 * perhaps because they're using NDIS to capture on the
361 * same machine and it provides simulated-Ethernet
362 * packets, but captures taken with various serial
363 * pods use the same network type value but aren't
364 * shaped like Ethernet. We handle that below.
366 WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */
367 WTAP_ENCAP_UNKNOWN, /* LocalTalk */
368 WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */
369 WTAP_ENCAP_UNKNOWN, /* ARCNET raw */
370 WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */
371 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,/* ATM */
372 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
373 /* Wireless WAN with radio information */
374 WTAP_ENCAP_UNKNOWN /* IrDA */
376 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
381 /* Read in the string that should be at the start of a NetXRay
383 errno = WTAP_ERR_CANT_READ;
384 bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
385 if (bytes_read != sizeof magic) {
386 *err = file_error(wth->fh);
391 wth->data_offset += sizeof magic;
393 if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
395 } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
401 /* Read the rest of the header. */
402 errno = WTAP_ERR_CANT_READ;
403 bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
404 if (bytes_read != sizeof hdr) {
405 *err = file_error(wth->fh);
410 wth->data_offset += sizeof hdr;
415 file_type = WTAP_FILE_NETXRAY_OLD;
417 /* It appears that version 1.1 files (as produced by Windows
418 * Sniffer Pro 2.0.01) have the time stamp in microseconds,
419 * rather than the milliseconds version 1.0 files appear to
422 * It also appears that version 2.00x files have per-packet
423 * headers with some extra fields. */
424 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
427 file_type = WTAP_FILE_NETXRAY_1_0;
428 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
431 file_type = WTAP_FILE_NETXRAY_1_1;
432 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
435 file_type = WTAP_FILE_NETXRAY_2_00x;
436 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
439 file_type = WTAP_FILE_NETXRAY_2_00x;
440 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
443 file_type = WTAP_FILE_NETXRAY_2_00x;
444 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
447 file_type = WTAP_FILE_NETXRAY_2_00x;
449 *err = WTAP_ERR_UNSUPPORTED;
450 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
455 switch (hdr.network_plus) {
459 * The byte after hdr.network is usually 0, in which case
460 * the hdr.network byte is an NDIS network type value - 1.
462 network_type = hdr.network + 1;
467 * However, in some Ethernet captures, it's 2, and the
468 * hdr.network byte is 1 rather than 0. We assume
469 * that if there's a byte after hdr.network with the value
470 * 2, the hdr.network byte is an NDIS network type, rather
471 * than an NDIS network type - 1.
473 network_type = hdr.network;
477 *err = WTAP_ERR_UNSUPPORTED;
478 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
483 if (network_type >= NUM_NETXRAY_ENCAPS
484 || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
485 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
486 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
487 network_type, hdr.network_plus);
492 * Figure out the time stamp units and start time stamp.
494 start_timestamp = (double)pletohl(&hdr.timelo)
495 + (double)pletohl(&hdr.timehi)*4294967296.0;
498 case WTAP_FILE_NETXRAY_OLD:
499 ticks_per_sec = 1000.0;
500 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
503 case WTAP_FILE_NETXRAY_1_0:
504 ticks_per_sec = 1000.0;
505 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
508 case WTAP_FILE_NETXRAY_1_1:
510 * In version 1.1 files (as produced by Windows Sniffer
511 * Pro 2.0.01), the time stamp is in microseconds,
512 * rather than the milliseconds time stamps in NetXRay
513 * and older versions of Windows Sniffer.
515 ticks_per_sec = 1000000.0;
516 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
519 case WTAP_FILE_NETXRAY_2_00x:
521 * Get the time stamp units from the appropriate TpS
522 * table or from the file header.
524 switch (network_type) {
528 * Ethernet - the table to use depends on whether
529 * this is an NDIS or pod capture.
531 switch (hdr.captype) {
534 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
535 *err = WTAP_ERR_UNSUPPORTED;
536 *err_info = g_strdup_printf(
537 "netxray: Unknown timeunit %u for Ethernet/CAPTYPE_NDIS version %.8s capture",
538 hdr.timeunit, hdr.version);
542 XXX: 05/29/07: Use 'realtick' instead of TpS table if timeunit=2;
543 Using 'realtick' in this case results
544 in the correct 'ticks per second' for all the captures that
545 I have of this type (including captures from a number of Wirshark
548 if (hdr.timeunit == 2) {
549 ticks_per_sec = pletohl(hdr.realtick);
552 ticks_per_sec = TpS[hdr.timeunit];
556 case ETH_CAPTYPE_GIGPOD:
557 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD
558 || TpS_gigpod[hdr.timeunit] == 0.0) {
559 *err = WTAP_ERR_UNSUPPORTED;
560 *err_info = g_strdup_printf(
561 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD version %.8s capture",
562 hdr.timeunit, hdr.version);
565 ticks_per_sec = TpS_gigpod[hdr.timeunit];
568 * At least for 002.002 and 002.003
569 * captures, the start time stamp is 0,
570 * not the value in the file.
572 if (version_minor == 2 || version_minor == 3)
573 start_timestamp = 0.0;
576 case ETH_CAPTYPE_OTHERPOD:
577 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD
578 || TpS_otherpod[hdr.timeunit] == 0.0) {
579 *err = WTAP_ERR_UNSUPPORTED;
580 *err_info = g_strdup_printf(
581 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD version %.8s capture",
582 hdr.timeunit, hdr.version);
585 ticks_per_sec = TpS_otherpod[hdr.timeunit];
588 * At least for 002.002 and 002.003
589 * captures, the start time stamp is 0,
590 * not the value in the file.
592 if (version_minor == 2 || version_minor == 3)
593 start_timestamp = 0.0;
596 case ETH_CAPTYPE_OTHERPOD2:
597 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD2
598 || TpS_otherpod2[hdr.timeunit] == 0.0) {
599 *err = WTAP_ERR_UNSUPPORTED;
600 *err_info = g_strdup_printf(
601 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD2 version %.8s capture",
602 hdr.timeunit, hdr.version);
605 ticks_per_sec = TpS_otherpod2[hdr.timeunit];
607 * XXX: start time stamp in the one capture file examined of this type was 0;
608 * We'll assume the start time handling is the same as for other pods.
610 * At least for 002.002 and 002.003
611 * captures, the start time stamp is 0,
612 * not the value in the file.
614 if (version_minor == 2 || version_minor == 3)
615 start_timestamp = 0.0;
618 case ETH_CAPTYPE_GIGPOD2:
619 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD2
620 || TpS_gigpod2[hdr.timeunit] == 0.0) {
621 *err = WTAP_ERR_UNSUPPORTED;
622 *err_info = g_strdup_printf(
623 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD2 version %.8s capture",
624 hdr.timeunit, hdr.version);
627 ticks_per_sec = TpS_gigpod2[hdr.timeunit];
629 * XXX: start time stamp in the one capture file examined of this type was 0;
630 * We'll assume the start time handling is the same as for other pods.
632 * At least for 002.002 and 002.003
633 * captures, the start time stamp is 0,
634 * not the value in the file.
636 if (version_minor == 2 || version_minor == 3)
637 start_timestamp = 0.0;
641 *err = WTAP_ERR_UNSUPPORTED;
642 *err_info = g_strdup_printf(
643 "netxray: Unknown capture type %u for Ethernet version %.8s capture",
644 hdr.captype, hdr.version);
650 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
651 *err = WTAP_ERR_UNSUPPORTED;
652 *err_info = g_strdup_printf(
653 "netxray: Unknown timeunit %u for %u/%u version %.8s capture",
654 hdr.timeunit, network_type, hdr.captype,
658 ticks_per_sec = TpS[hdr.timeunit];
663 * If the number of ticks per second is greater than
664 * 1 million, make the precision be nanoseconds rather
667 * XXX - do values only slightly greater than one million
668 * correspond to a resolution sufficiently better than
669 * 1 microsecond to display more digits of precision?
670 * XXX - Seems reasonable to use nanosecs only if TPS >= 10M
672 if (ticks_per_sec >= 1e7)
673 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
675 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
679 g_assert_not_reached();
682 start_timestamp = start_timestamp/ticks_per_sec;
684 if (network_type == 4) {
686 * In version 0 and 1, we assume, for now, that all
687 * WAN captures have frames that look like Ethernet
688 * frames (as a result, presumably, of having passed
691 * In version 2, it looks as if there's stuff in the
692 * file header to specify what particular type of WAN
695 if (version_major == 2) {
696 switch (hdr.captype) {
698 case WAN_CAPTYPE_PPP:
702 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
705 case WAN_CAPTYPE_FRELAY:
709 * XXX - in at least one capture, this
710 * is Cisco HDLC, not Frame Relay, but
711 * in another capture, it's Frame Relay.
713 * [Bytes in each capture:
714 * Cisco HDLC: hdr.xxx_x60[06:10]: 0x02 0x00 0x01 0x00 0x06
715 * Frame Relay: hdr.xxx_x60[06:10] 0x00 0x00 0x00 0x00 0x00
717 * Cisco HDLC: hdr.xxx_x60[14:15]: 0xff 0xff
718 * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
721 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
724 case WAN_CAPTYPE_HDLC:
725 case WAN_CAPTYPE_HDLC2:
727 * Various HDLC flavors?
729 switch (hdr.wan_hdlc_subsub_captype) {
731 case 0: /* LAPB/X.25 */
732 file_encap = WTAP_ENCAP_LAPB;
738 file_encap = WTAP_ENCAP_ISDN;
739 isdn_type = hdr.wan_hdlc_subsub_captype;
743 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
744 *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
745 hdr.wan_hdlc_subsub_captype);
750 case WAN_CAPTYPE_SDLC:
754 file_encap = WTAP_ENCAP_SDLC;
757 case WAN_CAPTYPE_CHDLC:
759 * Cisco router (CHDLC) captured with pod
761 file_encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
765 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
766 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
771 file_encap = WTAP_ENCAP_ETHERNET;
773 file_encap = netxray_encap[network_type];
775 /* This is a netxray file */
776 wth->file_type = file_type;
777 netxray = (netxray_t *)g_malloc(sizeof(netxray_t));
778 wth->priv = (void *)netxray;
779 wth->subtype_read = netxray_read;
780 wth->subtype_seek_read = netxray_seek_read;
781 wth->file_encap = file_encap;
782 wth->snapshot_length = 0; /* not available in header */
783 netxray->start_time = pletohl(&hdr.start_time);
784 netxray->ticks_per_sec = ticks_per_sec;
785 netxray->start_timestamp = start_timestamp;
786 netxray->version_major = version_major;
789 * If frames have an extra 4 bytes of stuff at the end, is
790 * it an FCS, or just junk?
792 netxray->fcs_valid = FALSE;
793 switch (file_encap) {
795 case WTAP_ENCAP_ETHERNET:
796 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
797 case WTAP_ENCAP_ISDN:
798 case WTAP_ENCAP_LAPB:
800 * It appears that, in at least some version 2 Ethernet
801 * captures, for frames that have 0xff in hdr_2_x.xxx[2]
802 * and hdr_2_x.xxx[3] in the per-packet header:
804 * if, in the file header, hdr.realtick[1] is 0x34
805 * and hdr.realtick[2] is 0x12, the frames have an
808 * otherwise, they have 4 bytes of junk at the end.
810 * Yes, it's strange that you have to check the *middle*
811 * of the time stamp field; you can't check for any
812 * particular value of the time stamp field.
814 * For now, we assume that to be true for 802.11 captures
815 * as well; it appears to be the case for at least one
816 * such capture - the file doesn't have 0x34 and 0x12,
817 * and the 4 bytes at the end of the frames with 0xff
818 * are junk, not an FCS.
820 * For ISDN captures, it appears, at least in some
821 * captures, to be similar, although I haven't yet
822 * checked whether it's a valid FCS.
824 * XXX - should we do this for all encapsulation types?
826 * XXX - is there some other field that *really* indicates
827 * whether we have an FCS or not? The check of the time
828 * stamp is bizarre, as we're checking the middle.
829 * Perhaps hdr.realtick[0] is 0x00, in which case time
830 * stamp units in the range 1192960 through 1193215
831 * correspond to captures with an FCS, but that's still
834 * Note that there are captures with a network type of 0
835 * (Ethernet) and capture type of 0 (NDIS) that do, and
836 * that don't, have 0x34 0x12 in them, and at least one
837 * of the NDIS captures with 0x34 0x12 in it has FCSes,
838 * so it's not as if no NDIS captures have an FCS.
840 * There are also captures with a network type of 4 (WAN),
841 * capture type of 6 (HDLC), and subtype of 2 (T1 PRI) that
842 * do, and that don't, have 0x34 0x12, so there are at least
843 * some captures taken with a WAN pod that might lack an FCS.
844 * (We haven't yet tried dissecting the 4 bytes at the
845 * end of packets with hdr_2_x.xxx[2] and hdr_2_x.xxx[3]
846 * equal to 0xff as an FCS.)
848 * All captures I've seen that have 0x34 and 0x12 *and*
849 * have at least one frame with an FCS have a value of
850 * 0x01 in xxx_x40[4]. No captures I've seen with a network
851 * type of 0 (Ethernet) missing 0x34 0x12 have 0x01 there,
852 * however. However, there's at least one capture
853 * without 0x34 and 0x12, with a network type of 0,
854 * and with 0x01 in xxx_x40[4], *without* FCSes in the
855 * frames - the 4 bytes at the end are all zero - so it's
856 * not as simple as "xxx_x40[4] = 0x01 means the 4 bytes at
857 * the end are FCSes". Also, there's also at least one
858 * 802.11 capture with an xxx_x40[4] value of 0x01 with junk
859 * rather than an FCS at the end of the frame, so xxx_x40[4]
860 * isn't an obvious flag to determine whether the
863 * There don't seem to be any other values in any of the
864 * xxx_x5..., xxx_x6...., xxx_x7.... fields
865 * that obviously correspond to frames having an FCS.
867 * 05/29/07: Examination of numerous sniffer captures suggests
868 * that the apparent correlation of certain realtick
869 * bytes to 'FCS presence' may actually be
870 * a 'false positive'.
871 * ToDo: Review analysis and update code.
872 * It might be that the ticks-per-second value
873 * is hardware-dependent, and that hardware with
874 * a particular realtick value puts an FCS there
875 * and other hardware doesn't.
877 if (version_major == 2) {
878 if (hdr.realtick[1] == 0x34 && hdr.realtick[2] == 0x12)
879 netxray->fcs_valid = TRUE;
885 * Remember the ISDN type, as we need it to interpret the
886 * channel number in ISDN captures.
888 netxray->isdn_type = isdn_type;
890 /* Remember the offset after the last packet in the capture (which
891 * isn't necessarily the last packet in the file), as it appears
892 * there's sometimes crud after it.
893 * XXX: Remember 'start_offset' to help testing for 'short file' at EOF
895 netxray->wrapped = FALSE;
896 netxray->nframes = pletohl(&hdr.nframes);
897 netxray->start_offset = pletohl(&hdr.start_offset);
898 netxray->end_offset = pletohl(&hdr.end_offset);
900 /* Seek to the beginning of the data records. */
901 if (file_seek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET, err) == -1) {
905 wth->data_offset = pletohl(&hdr.start_offset);
910 /* Read the next packet */
911 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info _U_,
914 netxray_t *netxray = (netxray_t *)wth->priv;
916 union netxrayrec_hdr hdr;
923 /* Have we reached the end of the packet data? */
924 if (wth->data_offset == netxray->end_offset) {
926 *err = 0; /* it's just an EOF, not an error */
929 /* Read record header. */
930 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err);
937 * Error of some sort; give up.
942 /* We're at EOF. Wrap?
943 * XXX: Need to handle 'short file' cases
944 * (Distributed Sniffer seems to have a
945 * certain small propensity to generate 'short' files
946 * i.e. [many] bytes are missing from the end of the file)
947 * case 1: start_offset < end_offset
948 * wrap will read already read packets again;
949 * so: error with "short file"
950 * case 2: start_offset > end_offset ("circular" file)
951 * wrap will mean there's a gap (missing packets).
952 * However, I don't see a good way to identify this
953 * case so we'll just have to allow the wrap.
954 * (Maybe there can be an error message after all
955 * packets are read since there'll be less packets than
956 * specified in the file header).
957 * Note that these cases occur *only* if a 'short' eof occurs exactly
958 * at the expected beginning of a frame header record; If there is a
959 * partial frame header (or partial frame data) record, then the
960 * netxray_read... functions will detect the short record.
962 if (netxray->start_offset < netxray->end_offset) {
963 *err = WTAP_ERR_SHORT_READ;
967 if (!netxray->wrapped) {
968 /* Yes. Remember that we did. */
969 netxray->wrapped = TRUE;
970 if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
971 SEEK_SET, err) == -1)
973 wth->data_offset = CAPTUREFILE_HEADER_SIZE;
977 /* We've already wrapped - don't wrap again. */
982 * Return the offset of the record header, so we can reread it
983 * if we go back to this frame.
985 *data_offset = wth->data_offset;
986 wth->data_offset += hdr_size;
989 * Read the packet data.
991 if (netxray->version_major == 0)
992 packet_size = pletohs(&hdr.old_hdr.len);
994 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
995 buffer_assure_space(wth->frame_buffer, packet_size);
996 pd = buffer_start_ptr(wth->frame_buffer);
997 if (!netxray_read_rec_data(wth->fh, pd, packet_size, err))
999 wth->data_offset += packet_size;
1002 * Set the pseudo-header.
1004 padding = netxray_set_pseudo_header(wth, pd, packet_size,
1005 &wth->pseudo_header, &hdr);
1007 if (netxray->version_major == 0) {
1008 t = (double)pletohl(&hdr.old_hdr.timelo)
1009 + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
1010 t /= netxray->ticks_per_sec;
1011 t -= netxray->start_timestamp;
1012 wth->phdr.ts.secs = netxray->start_time + (long)t;
1013 wth->phdr.ts.nsecs = (int)((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 = wth->phdr.caplen;
1022 t = (double)pletohl(&hdr.hdr_1_x.timelo)
1023 + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
1024 t /= netxray->ticks_per_sec;
1025 t -= netxray->start_timestamp;
1026 wth->phdr.ts.secs = netxray->start_time + (time_t)t;
1027 wth->phdr.ts.nsecs = (int)((t-(double)(unsigned long)(t))
1030 * We subtract the padding from the packet size, so our caller
1033 wth->phdr.caplen = packet_size - padding;
1034 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
1041 netxray_seek_read(wtap *wth, gint64 seek_off,
1042 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
1043 int *err, gchar **err_info _U_)
1045 union netxrayrec_hdr hdr;
1048 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1051 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) {
1054 * EOF - we report that as a short read, as
1055 * we've read this once and know that it
1058 *err = WTAP_ERR_SHORT_READ;
1064 * Read the packet data.
1066 ret = netxray_read_rec_data(wth->random_fh, pd, length, err);
1071 * Set the pseudo-header.
1073 netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1078 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1081 netxray_t *netxray = (netxray_t *)wth->priv;
1085 /* Read record header. */
1086 switch (netxray->version_major) {
1089 hdr_size = sizeof (struct old_netxrayrec_hdr);
1093 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1097 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1100 errno = WTAP_ERR_CANT_READ;
1101 bytes_read = file_read(hdr, 1, hdr_size, fh);
1102 if (bytes_read != hdr_size) {
1103 *err = file_error(wth->fh);
1106 if (bytes_read != 0) {
1107 *err = WTAP_ERR_SHORT_READ;
1112 * We're at EOF. "*err" is 0; we return FALSE - that
1113 * combination tells our caller we're at EOF.
1121 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1122 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1124 netxray_t *netxray = (netxray_t *)wth->priv;
1128 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1131 switch (netxray->version_major) {
1134 switch (wth->file_encap) {
1136 case WTAP_ENCAP_ETHERNET:
1138 * XXX - if hdr->hdr_1_x.xxx[15] is 1
1139 * the frame appears not to have any extra
1140 * stuff at the end, but if it's 0,
1141 * there appears to be 4 bytes of stuff
1142 * at the end, but it's not an FCS.
1144 * Or is that just the low-order bit?
1146 * For now, we just say "no FCS".
1148 pseudo_header->eth.fcs_len = 0;
1154 switch (wth->file_encap) {
1156 case WTAP_ENCAP_ETHERNET:
1158 * It appears, at least with version 2 captures,
1159 * that we have 4 bytes of stuff (which might be
1160 * a valid FCS or might be junk) at the end of
1161 * the packet if hdr->hdr_2_x.xxx[2] and
1162 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1165 * It also appears that if the low-order bit of
1166 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1169 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1170 hdr->hdr_2_x.xxx[3] == 0xff) {
1172 * We have 4 bytes of stuff at the
1173 * end of the frame - FCS, or junk?
1175 if (netxray->fcs_valid) {
1179 pseudo_header->eth.fcs_len = 4;
1187 pseudo_header->eth.fcs_len = 0;
1190 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1192 * It appears, in one 802.11 capture, that
1193 * we have 4 bytes of junk at the ends of
1194 * frames in which hdr->hdr_2_x.xxx[2] and
1195 * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1196 * seen any frames where it's an FCS, but,
1197 * for now, we still check the fcs_valid
1198 * flag - I also haven't seen any capture
1199 * where we'd set it based on the realtick
1202 * It also appears that if the low-order bit of
1203 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1204 * bad FCS. According to Ken Mann, the 0x4 bit
1205 * is sometimes also set for errors.
1207 * Ken also says that xxx[11] is 0x5 when the
1208 * packet is WEP-encrypted.
1210 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1211 hdr->hdr_2_x.xxx[3] == 0xff) {
1213 * We have 4 bytes of stuff at the
1214 * end of the frame - FCS, or junk?
1216 if (netxray->fcs_valid) {
1220 pseudo_header->ieee_802_11.fcs_len = 4;
1228 pseudo_header->ieee_802_11.fcs_len = 0;
1230 pseudo_header->ieee_802_11.channel =
1231 hdr->hdr_2_x.xxx[12];
1232 pseudo_header->ieee_802_11.data_rate =
1233 hdr->hdr_2_x.xxx[13];
1234 pseudo_header->ieee_802_11.signal_level =
1235 hdr->hdr_2_x.xxx[14];
1237 * According to Ken Mann, at least in the captures
1238 * he's seen, xxx[15] is the noise level, which
1239 * is either 0xFF meaning "none reported" or a value
1240 * from 0x00 to 0x7F for 0 to 100%.
1244 case WTAP_ENCAP_ISDN:
1248 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1249 * is the direction flag.
1251 * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
1252 * are the channel number, but some mapping is
1253 * required for PRI. (Is it really just the time
1256 pseudo_header->isdn.uton =
1257 (hdr->hdr_2_x.xxx[12] & 0x01);
1258 pseudo_header->isdn.channel =
1259 hdr->hdr_2_x.xxx[13] & 0x1F;
1260 switch (netxray->isdn_type) {
1264 * E1 PRI. Channel numbers 0 and 16
1265 * are the D channel; channel numbers 1
1266 * through 15 are B1 through B15; channel
1267 * numbers 17 through 31 are B16 through
1270 if (pseudo_header->isdn.channel == 16)
1271 pseudo_header->isdn.channel = 0;
1272 else if (pseudo_header->isdn.channel > 16)
1273 pseudo_header->isdn.channel -= 1;
1278 * T1 PRI. Channel numbers 0 and 24
1279 * are the D channel; channel numbers 1
1280 * through 23 are B1 through B23.
1282 if (pseudo_header->isdn.channel == 24)
1283 pseudo_header->isdn.channel = 0;
1284 else if (pseudo_header->isdn.channel > 24)
1285 pseudo_header->isdn.channel -= 1;
1290 * It appears, at least with version 2 captures,
1291 * that we have 4 bytes of stuff (which might be
1292 * a valid FCS or might be junk) at the end of
1293 * the packet if hdr->hdr_2_x.xxx[2] and
1294 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1297 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1298 * indicate a bad FCS, as is the case with
1301 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1302 hdr->hdr_2_x.xxx[3] == 0xff) {
1304 * FCS, or junk, at the end.
1305 * XXX - is it an FCS if "fcs_valid" is
1312 case WTAP_ENCAP_LAPB:
1313 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1315 * LAPB/X.25 and Frame Relay.
1317 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1318 * is the direction flag. (Probably true for other
1319 * HDLC encapsulations as well.)
1321 pseudo_header->x25.flags =
1322 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1325 * It appears, at least with version 2 captures,
1326 * that we have 4 bytes of stuff (which might be
1327 * a valid FCS or might be junk) at the end of
1328 * the packet if hdr->hdr_2_x.xxx[2] and
1329 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1332 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1333 * indicate a bad FCS, as is the case with
1336 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1337 hdr->hdr_2_x.xxx[3] == 0xff) {
1339 * FCS, or junk, at the end.
1340 * XXX - is it an FCS if "fcs_valid" is
1347 case WTAP_ENCAP_PPP_WITH_PHDR:
1348 case WTAP_ENCAP_SDLC:
1349 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1350 pseudo_header->p2p.sent =
1351 (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1354 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1355 pseudo_header->atm.flags = 0;
1357 * XXX - is 0x08 an "OAM cell" flag?
1359 if (hdr->hdr_2_x.xxx[9] & 0x04)
1360 pseudo_header->atm.flags |= ATM_RAW_CELL;
1361 pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
1362 pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1363 pseudo_header->atm.channel =
1364 (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1365 pseudo_header->atm.cells = 0;
1367 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1369 case 0x00: /* Unknown */
1371 * Infer the AAL, traffic type, and subtype.
1373 atm_guess_traffic_type(pd, len,
1377 case 0x50: /* AAL5 (including signalling) */
1378 pseudo_header->atm.aal = AAL_5;
1379 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1382 case 0x0a: /* Signalling traffic */
1383 pseudo_header->atm.aal = AAL_SIGNALLING;
1384 pseudo_header->atm.type = TRAF_UNKNOWN;
1385 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1388 case 0x0b: /* ILMI */
1389 pseudo_header->atm.type = TRAF_ILMI;
1390 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1393 case 0x0c: /* LANE LE Control */
1394 pseudo_header->atm.type = TRAF_LANE;
1395 pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1400 * 0x0d is *mostly* LANE 802.3,
1401 * but I've seen an LE Control frame
1404 pseudo_header->atm.type = TRAF_LANE;
1405 atm_guess_lane_type(pd, len,
1409 case 0x0f: /* LLC multiplexed */
1410 pseudo_header->atm.type = TRAF_LLCMX; /* XXX */
1411 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
1416 * XXX - discover the other types.
1418 pseudo_header->atm.type = TRAF_UNKNOWN;
1419 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1426 * 0x60 seen, and dissected by Sniffer
1427 * Pro as a raw cell.
1429 * XXX - discover what those types are.
1431 pseudo_header->atm.aal = AAL_UNKNOWN;
1432 pseudo_header->atm.type = TRAF_UNKNOWN;
1433 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1444 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1449 errno = WTAP_ERR_CANT_READ;
1450 bytes_read = file_read(data_ptr, 1, packet_size, fh);
1452 if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1453 *err = file_error(fh);
1455 *err = WTAP_ERR_SHORT_READ;
1462 gboolean first_frame;
1463 struct wtap_nstime start;
1467 static const struct {
1468 int wtap_encap_value;
1470 } wtap_encap_1_1[] = {
1471 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1472 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1473 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1474 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1476 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1479 wtap_encap_to_netxray_1_1_encap(int encap)
1483 for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1484 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1485 return wtap_encap_1_1[i].ndis_value;
1491 /* Returns 0 if we could write the specified encapsulation type,
1492 an error indication otherwise. */
1493 int netxray_dump_can_write_encap_1_1(int encap)
1495 /* Per-packet encapsulations aren't supported. */
1496 if (encap == WTAP_ENCAP_PER_PACKET)
1497 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1499 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1500 return WTAP_ERR_UNSUPPORTED_ENCAP;
1505 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1507 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
1509 netxray_dump_t *netxray;
1511 /* This is a NetXRay file. We can't fill in some fields in the header
1512 until all the packets have been written, so we can't write to a
1515 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1519 wdh->subtype_write = netxray_dump_1_1;
1520 wdh->subtype_close = netxray_dump_close_1_1;
1522 /* We can't fill in all the fields in the file header, as we
1523 haven't yet written any packets. As we'll have to rewrite
1524 the header when we've written out all the packets, we just
1525 skip over the header for now. */
1526 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1531 netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1532 wdh->priv = (void *)netxray;
1533 netxray->first_frame = TRUE;
1534 netxray->start.secs = 0;
1535 netxray->start.nsecs = 0;
1536 netxray->nframes = 0;
1541 /* Write a record for a packet to a dump file.
1542 Returns TRUE on success, FALSE on failure. */
1543 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1544 const struct wtap_pkthdr *phdr,
1545 const union wtap_pseudo_header *pseudo_header _U_,
1546 const guchar *pd, int *err)
1548 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1551 struct netxrayrec_1_x_hdr rec_hdr;
1554 /* NetXRay/Windows Sniffer files have a capture start date/time
1555 in the header, in a UNIX-style format, with one-second resolution,
1556 and a start time stamp with microsecond resolution that's just
1557 an arbitrary time stamp relative to some unknown time (boot
1558 time?), and have times relative to the start time stamp in
1559 the packet headers; pick the seconds value of the time stamp
1560 of the first packet as the UNIX-style start date/time, and make
1561 the high-resolution start time stamp 0, with the time stamp of
1562 packets being the delta between the stamp of the packet and
1563 the stamp of the first packet with the microseconds part 0. */
1564 if (netxray->first_frame) {
1565 netxray->first_frame = FALSE;
1566 netxray->start = phdr->ts;
1569 /* build the header for each packet */
1570 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1571 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1572 + ((guint64)phdr->ts.nsecs)/1000;
1573 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1574 rec_hdr.timelo = htolel(t32);
1575 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1576 rec_hdr.timehi = htolel(t32);
1577 rec_hdr.orig_len = htoles(phdr->len);
1578 rec_hdr.incl_len = htoles(phdr->caplen);
1580 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1581 if (nwritten != sizeof(rec_hdr)) {
1582 if (nwritten == 0 && ferror(wdh->fh))
1585 *err = WTAP_ERR_SHORT_WRITE;
1589 /* write the packet data */
1590 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1591 if (nwritten != phdr->caplen) {
1592 if (nwritten == 0 && ferror(wdh->fh))
1595 *err = WTAP_ERR_SHORT_WRITE;
1604 /* Finish writing to a dump file.
1605 Returns TRUE on success, FALSE on failure. */
1606 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1608 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1609 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1611 struct netxray_hdr file_hdr;
1614 filelen = (guint32)ftell(wdh->fh); /* XXX - large files? */
1616 /* Go back to beginning */
1617 fseek(wdh->fh, 0, SEEK_SET);
1619 /* Rewrite the file header. */
1620 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1621 if (nwritten != sizeof netxray_magic) {
1623 if (nwritten == 0 && ferror(wdh->fh))
1626 *err = WTAP_ERR_SHORT_WRITE;
1631 /* "sniffer" version ? */
1632 memset(&file_hdr, '\0', sizeof file_hdr);
1633 memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1634 file_hdr.start_time = htolel(netxray->start.secs);
1635 file_hdr.nframes = htolel(netxray->nframes);
1636 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1637 file_hdr.end_offset = htolel(filelen);
1638 file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1639 file_hdr.timelo = htolel(0);
1640 file_hdr.timehi = htolel(0);
1642 memset(hdr_buf, '\0', sizeof hdr_buf);
1643 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1644 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1645 if (nwritten != sizeof hdr_buf) {
1647 if (nwritten == 0 && ferror(wdh->fh))
1650 *err = WTAP_ERR_SHORT_WRITE;
1658 static const struct {
1659 int wtap_encap_value;
1661 } wtap_encap_2_0[] = {
1662 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1663 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1664 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1665 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1666 { WTAP_ENCAP_PPP_WITH_PHDR, 3 }, /* -> NDIS WAN */
1667 { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 }, /* -> NDIS WAN */
1668 { WTAP_ENCAP_LAPB, 3 }, /* -> NDIS WAN */
1669 { WTAP_ENCAP_SDLC, 3 }, /* -> NDIS WAN */
1671 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1674 wtap_encap_to_netxray_2_0_encap(int encap)
1678 for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1679 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1680 return wtap_encap_2_0[i].ndis_value;
1686 /* Returns 0 if we could write the specified encapsulation type,
1687 an error indication otherwise. */
1688 int netxray_dump_can_write_encap_2_0(int encap)
1690 /* Per-packet encapsulations aren't supported. */
1691 if (encap == WTAP_ENCAP_PER_PACKET)
1692 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1694 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1695 return WTAP_ERR_UNSUPPORTED_ENCAP;
1700 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1702 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
1704 netxray_dump_t *netxray;
1706 /* This is a NetXRay file. We can't fill in some fields in the header
1707 until all the packets have been written, so we can't write to a
1710 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1714 wdh->subtype_write = netxray_dump_2_0;
1715 wdh->subtype_close = netxray_dump_close_2_0;
1717 /* We can't fill in all the fields in the file header, as we
1718 haven't yet written any packets. As we'll have to rewrite
1719 the header when we've written out all the packets, we just
1720 skip over the header for now. */
1721 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1726 netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1727 wdh->priv = (void *)netxray;
1728 netxray->first_frame = TRUE;
1729 netxray->start.secs = 0;
1730 netxray->start.nsecs = 0;
1731 netxray->nframes = 0;
1736 /* Write a record for a packet to a dump file.
1737 Returns TRUE on success, FALSE on failure. */
1738 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1739 const struct wtap_pkthdr *phdr,
1740 const union wtap_pseudo_header *pseudo_header _U_,
1741 const guchar *pd, int *err)
1743 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1746 struct netxrayrec_2_x_hdr rec_hdr;
1749 /* NetXRay/Windows Sniffer files have a capture start date/time
1750 in the header, in a UNIX-style format, with one-second resolution,
1751 and a start time stamp with microsecond resolution that's just
1752 an arbitrary time stamp relative to some unknown time (boot
1753 time?), and have times relative to the start time stamp in
1754 the packet headers; pick the seconds value of the time stamp
1755 of the first packet as the UNIX-style start date/time, and make
1756 the high-resolution start time stamp 0, with the time stamp of
1757 packets being the delta between the stamp of the packet and
1758 the stamp of the first packet with the microseconds part 0. */
1759 if (netxray->first_frame) {
1760 netxray->first_frame = FALSE;
1761 netxray->start = phdr->ts;
1764 /* build the header for each packet */
1765 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1766 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1767 + ((guint64)phdr->ts.nsecs)/1000;
1768 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1769 rec_hdr.timelo = htolel(t32);
1770 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1771 rec_hdr.timehi = htolel(t32);
1772 rec_hdr.orig_len = htoles(phdr->len);
1773 rec_hdr.incl_len = htoles(phdr->caplen);
1775 switch (phdr->pkt_encap) {
1777 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1778 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1779 rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1780 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1783 case WTAP_ENCAP_PPP_WITH_PHDR:
1784 case WTAP_ENCAP_SDLC:
1785 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1788 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1789 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1793 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1794 if (nwritten != sizeof(rec_hdr)) {
1795 if (nwritten == 0 && ferror(wdh->fh))
1798 *err = WTAP_ERR_SHORT_WRITE;
1802 /* write the packet data */
1803 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1804 if (nwritten != phdr->caplen) {
1805 if (nwritten == 0 && ferror(wdh->fh))
1808 *err = WTAP_ERR_SHORT_WRITE;
1817 /* Finish writing to a dump file.
1818 Returns TRUE on success, FALSE on failure. */
1819 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1821 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1822 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1824 struct netxray_hdr file_hdr;
1827 filelen = (guint32)ftell(wdh->fh); /* XXX - large files? */
1829 /* Go back to beginning */
1830 fseek(wdh->fh, 0, SEEK_SET);
1832 /* Rewrite the file header. */
1833 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1834 if (nwritten != sizeof netxray_magic) {
1836 if (nwritten == 0 && ferror(wdh->fh))
1839 *err = WTAP_ERR_SHORT_WRITE;
1844 /* "sniffer" version ? */
1845 memset(&file_hdr, '\0', sizeof file_hdr);
1846 memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1847 file_hdr.start_time = htolel(netxray->start.secs);
1848 file_hdr.nframes = htolel(netxray->nframes);
1849 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1850 file_hdr.end_offset = htolel(filelen);
1851 file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1852 file_hdr.timelo = htolel(0);
1853 file_hdr.timehi = htolel(0);
1854 switch (wdh->encap) {
1856 case WTAP_ENCAP_PPP_WITH_PHDR:
1857 file_hdr.captype = WAN_CAPTYPE_PPP;
1860 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1861 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1864 case WTAP_ENCAP_LAPB:
1865 file_hdr.captype = WAN_CAPTYPE_HDLC;
1866 file_hdr.wan_hdlc_subsub_captype = 0;
1869 case WTAP_ENCAP_SDLC:
1870 file_hdr.captype = WAN_CAPTYPE_SDLC;
1874 file_hdr.captype = CAPTYPE_NDIS;
1878 memset(hdr_buf, '\0', sizeof hdr_buf);
1879 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1880 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1881 if (nwritten != sizeof hdr_buf) {
1883 if (nwritten == 0 && ferror(wdh->fh))
1886 *err = WTAP_ERR_SHORT_WRITE;