HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / wiretap / netxray.c
blob2d4481260ee04927eceff1f7138856d23287e0a7
1 /* netxray.c
3 * $Id$
5 * Wiretap Library
6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "config.h"
25 #include <errno.h>
26 #include <string.h>
27 #include "wtap-int.h"
28 #include "file_wrappers.h"
29 #include "netxray.h"
30 #include "buffer.h"
31 #include "atm.h"
33 /* Capture file header, *including* magic number, is padded to 128 bytes. */
34 #define CAPTUREFILE_HEADER_SIZE 128
36 /* Magic number size, in both 1.x and later files. */
37 #define MAGIC_SIZE 4
39 /* Magic number in NetXRay 1.x files. */
40 static const char old_netxray_magic[MAGIC_SIZE] = {
41 'V', 'L', '\0', '\0'
44 /* Magic number in NetXRay 2.0 and later, and Windows Sniffer, files. */
45 static const char netxray_magic[MAGIC_SIZE] = {
46 'X', 'C', 'P', '\0'
49 /* NetXRay file header (minus magic number). */
50 /* */
51 /* As field usages are identified, please revise as needed */
52 /* Please do *not* use netxray_hdr xxx... names in the code */
53 /* (Placeholder names for all 'unknown' fields are */
54 /* of form xxx_x<hex_hdr_offset> */
55 /* where <hex_hdr_offset> *includes* the magic number) */
57 struct netxray_hdr {
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 */
123 * WAN capture types.
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
181 * other captures.
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
195 * that captype be?
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
209 * on the pod.
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;
309 typedef struct {
310 time_t start_time;
311 double ticks_per_sec;
312 double start_timestamp;
313 gboolean wrapped;
314 guint32 nframes;
315 gint64 start_offset;
316 gint64 end_offset;
317 int version_major;
318 gboolean fcs_valid; /* if packets have valid FCS at the end */
319 guint isdn_type; /* 1 = E1 PRI, 2 = T1 PRI, 3 = BRI */
320 } netxray_t;
322 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
323 gint64 *data_offset);
324 static gboolean netxray_seek_read(wtap *wth, gint64 seek_off,
325 struct wtap_pkthdr *phdr, Buffer *buf, int length,
326 int *err, gchar **err_info);
327 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
328 union netxrayrec_hdr *hdr, int *err, gchar **err_info);
329 static void netxray_set_phdr(wtap *wth, Buffer *buf, int len,
330 struct wtap_pkthdr *phdr, union netxrayrec_hdr *hdr);
331 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
332 const struct wtap_pkthdr *phdr,
333 const guint8 *pd, int *err);
334 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
335 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
336 const struct wtap_pkthdr *phdr,
337 const guint8 *pd, int *err);
338 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
340 int netxray_open(wtap *wth, int *err, gchar **err_info)
342 int bytes_read;
343 char magic[MAGIC_SIZE];
344 gboolean is_old;
345 struct netxray_hdr hdr;
346 guint network_type;
347 double ticks_per_sec;
348 int version_major, version_minor;
349 int file_type;
350 double start_timestamp;
351 static const int netxray_encap[] = {
352 WTAP_ENCAP_UNKNOWN,
353 WTAP_ENCAP_ETHERNET,
354 WTAP_ENCAP_TOKEN_RING,
355 WTAP_ENCAP_FDDI_BITSWAPPED,
357 * XXX - some PPP captures may look like Ethernet,
358 * perhaps because they're using NDIS to capture on the
359 * same machine and it provides simulated-Ethernet
360 * packets, but captures taken with various serial
361 * pods use the same network type value but aren't
362 * shaped like Ethernet. We handle that below.
364 WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */
365 WTAP_ENCAP_UNKNOWN, /* LocalTalk */
366 WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */
367 WTAP_ENCAP_UNKNOWN, /* ARCNET raw */
368 WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */
369 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,/* ATM */
370 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
371 /* Wireless WAN with radio information */
372 WTAP_ENCAP_UNKNOWN /* IrDA */
374 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
375 int file_encap;
376 guint isdn_type = 0;
377 netxray_t *netxray;
379 /* Read in the string that should be at the start of a NetXRay
380 * file */
381 errno = WTAP_ERR_CANT_READ;
382 bytes_read = file_read(magic, MAGIC_SIZE, wth->fh);
383 if (bytes_read != MAGIC_SIZE) {
384 *err = file_error(wth->fh, err_info);
385 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
386 return -1;
387 return 0;
390 if (memcmp(magic, netxray_magic, MAGIC_SIZE) == 0) {
391 is_old = FALSE;
392 } else if (memcmp(magic, old_netxray_magic, MAGIC_SIZE) == 0) {
393 is_old = TRUE;
394 } else {
395 return 0;
398 /* Read the rest of the header. */
399 errno = WTAP_ERR_CANT_READ;
400 bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
401 if (bytes_read != sizeof hdr) {
402 *err = file_error(wth->fh, err_info);
403 if (*err == 0)
404 *err = WTAP_ERR_SHORT_READ;
405 return -1;
408 if (is_old) {
409 version_major = 0;
410 version_minor = 0;
411 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD;
412 } else {
413 /* It appears that version 1.1 files (as produced by Windows
414 * Sniffer Pro 2.0.01) have the time stamp in microseconds,
415 * rather than the milliseconds version 1.0 files appear to
416 * have.
418 * It also appears that version 2.00x files have per-packet
419 * headers with some extra fields. */
420 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
421 version_major = 1;
422 version_minor = 0;
423 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0;
424 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
425 version_major = 1;
426 version_minor = 1;
427 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1;
428 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
429 version_major = 2;
430 version_minor = 0;
431 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x;
432 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
433 version_major = 2;
434 version_minor = 1;
435 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x;
436 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
437 version_major = 2;
438 version_minor = 2;
439 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x;
440 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
441 version_major = 2;
442 version_minor = 3;
443 file_type = WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x;
444 } else {
445 *err = WTAP_ERR_UNSUPPORTED;
446 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
447 return -1;
451 switch (hdr.network_plus) {
453 case 0:
455 * The byte after hdr.network is usually 0, in which case
456 * the hdr.network byte is an NDIS network type value - 1.
458 network_type = hdr.network + 1;
459 break;
461 case 2:
463 * However, in some Ethernet captures, it's 2, and the
464 * hdr.network byte is 1 rather than 0. We assume
465 * that if there's a byte after hdr.network with the value
466 * 2, the hdr.network byte is an NDIS network type, rather
467 * than an NDIS network type - 1.
469 network_type = hdr.network;
470 break;
472 default:
473 *err = WTAP_ERR_UNSUPPORTED;
474 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
475 hdr.network_plus);
476 return -1;
479 if (network_type >= NUM_NETXRAY_ENCAPS
480 || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
481 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
482 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
483 network_type, hdr.network_plus);
484 return -1;
488 * Figure out the time stamp units and start time stamp.
490 start_timestamp = (double)pletohl(&hdr.timelo)
491 + (double)pletohl(&hdr.timehi)*4294967296.0;
492 switch (file_type) {
494 case WTAP_FILE_TYPE_SUBTYPE_NETXRAY_OLD:
495 ticks_per_sec = 1000.0;
496 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
497 break;
499 case WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_0:
500 ticks_per_sec = 1000.0;
501 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
502 break;
504 case WTAP_FILE_TYPE_SUBTYPE_NETXRAY_1_1:
506 * In version 1.1 files (as produced by Windows Sniffer
507 * Pro 2.0.01), the time stamp is in microseconds,
508 * rather than the milliseconds time stamps in NetXRay
509 * and older versions of Windows Sniffer.
511 ticks_per_sec = 1000000.0;
512 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
513 break;
515 case WTAP_FILE_TYPE_SUBTYPE_NETXRAY_2_00x:
517 * Get the time stamp units from the appropriate TpS
518 * table or from the file header.
520 switch (network_type) {
522 case 1:
524 * Ethernet - the table to use depends on whether
525 * this is an NDIS or pod capture.
527 switch (hdr.captype) {
529 case CAPTYPE_NDIS:
530 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
531 *err = WTAP_ERR_UNSUPPORTED;
532 *err_info = g_strdup_printf(
533 "netxray: Unknown timeunit %u for Ethernet/CAPTYPE_NDIS version %.8s capture",
534 hdr.timeunit, hdr.version);
535 return -1;
538 XXX: 05/29/07: Use 'realtick' instead of TpS table if timeunit=2;
539 Using 'realtick' in this case results
540 in the correct 'ticks per second' for all the captures that
541 I have of this type (including captures from a number of Wirshark
542 bug reports).
544 if (hdr.timeunit == 2) {
545 ticks_per_sec = pletohl(hdr.realtick);
547 else {
548 ticks_per_sec = TpS[hdr.timeunit];
550 break;
552 case ETH_CAPTYPE_GIGPOD:
553 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD
554 || TpS_gigpod[hdr.timeunit] == 0.0) {
555 *err = WTAP_ERR_UNSUPPORTED;
556 *err_info = g_strdup_printf(
557 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD version %.8s capture",
558 hdr.timeunit, hdr.version);
559 return -1;
561 ticks_per_sec = TpS_gigpod[hdr.timeunit];
564 * At least for 002.002 and 002.003
565 * captures, the start time stamp is 0,
566 * not the value in the file.
568 if (version_minor == 2 || version_minor == 3)
569 start_timestamp = 0.0;
570 break;
572 case ETH_CAPTYPE_OTHERPOD:
573 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD
574 || TpS_otherpod[hdr.timeunit] == 0.0) {
575 *err = WTAP_ERR_UNSUPPORTED;
576 *err_info = g_strdup_printf(
577 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD version %.8s capture",
578 hdr.timeunit, hdr.version);
579 return -1;
581 ticks_per_sec = TpS_otherpod[hdr.timeunit];
584 * At least for 002.002 and 002.003
585 * captures, the start time stamp is 0,
586 * not the value in the file.
588 if (version_minor == 2 || version_minor == 3)
589 start_timestamp = 0.0;
590 break;
592 case ETH_CAPTYPE_OTHERPOD2:
593 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD2
594 || TpS_otherpod2[hdr.timeunit] == 0.0) {
595 *err = WTAP_ERR_UNSUPPORTED;
596 *err_info = g_strdup_printf(
597 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD2 version %.8s capture",
598 hdr.timeunit, hdr.version);
599 return -1;
601 ticks_per_sec = TpS_otherpod2[hdr.timeunit];
603 * XXX: start time stamp in the one capture file examined of this type was 0;
604 * We'll assume the start time handling is the same as for other pods.
606 * At least for 002.002 and 002.003
607 * captures, the start time stamp is 0,
608 * not the value in the file.
610 if (version_minor == 2 || version_minor == 3)
611 start_timestamp = 0.0;
612 break;
614 case ETH_CAPTYPE_GIGPOD2:
615 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD2
616 || TpS_gigpod2[hdr.timeunit] == 0.0) {
617 *err = WTAP_ERR_UNSUPPORTED;
618 *err_info = g_strdup_printf(
619 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD2 version %.8s capture",
620 hdr.timeunit, hdr.version);
621 return -1;
623 ticks_per_sec = TpS_gigpod2[hdr.timeunit];
625 * XXX: start time stamp in the one capture file examined of this type was 0;
626 * We'll assume the start time handling is the same as for other pods.
628 * At least for 002.002 and 002.003
629 * captures, the start time stamp is 0,
630 * not the value in the file.
632 if (version_minor == 2 || version_minor == 3)
633 start_timestamp = 0.0;
634 break;
636 default:
637 *err = WTAP_ERR_UNSUPPORTED;
638 *err_info = g_strdup_printf(
639 "netxray: Unknown capture type %u for Ethernet version %.8s capture",
640 hdr.captype, hdr.version);
641 return -1;
643 break;
645 default:
646 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
647 *err = WTAP_ERR_UNSUPPORTED;
648 *err_info = g_strdup_printf(
649 "netxray: Unknown timeunit %u for %u/%u version %.8s capture",
650 hdr.timeunit, network_type, hdr.captype,
651 hdr.version);
652 return -1;
654 ticks_per_sec = TpS[hdr.timeunit];
655 break;
659 * If the number of ticks per second is greater than
660 * 1 million, make the precision be nanoseconds rather
661 * than microseconds.
663 * XXX - do values only slightly greater than one million
664 * correspond to a resolution sufficiently better than
665 * 1 microsecond to display more digits of precision?
666 * XXX - Seems reasonable to use nanosecs only if TPS >= 10M
668 if (ticks_per_sec >= 1e7)
669 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
670 else
671 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
672 break;
674 default:
675 g_assert_not_reached();
676 ticks_per_sec = 0.0;
678 start_timestamp = start_timestamp/ticks_per_sec;
680 if (network_type == 4) {
682 * In version 0 and 1, we assume, for now, that all
683 * WAN captures have frames that look like Ethernet
684 * frames (as a result, presumably, of having passed
685 * through NDISWAN).
687 * In version 2, it looks as if there's stuff in the
688 * file header to specify what particular type of WAN
689 * capture we have.
691 if (version_major == 2) {
692 switch (hdr.captype) {
694 case WAN_CAPTYPE_PPP:
696 * PPP.
698 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
699 break;
701 case WAN_CAPTYPE_FRELAY:
703 * Frame Relay.
705 * XXX - in at least one capture, this
706 * is Cisco HDLC, not Frame Relay, but
707 * in another capture, it's Frame Relay.
709 * [Bytes in each capture:
710 * Cisco HDLC: hdr.xxx_x60[06:10]: 0x02 0x00 0x01 0x00 0x06
711 * Frame Relay: hdr.xxx_x60[06:10] 0x00 0x00 0x00 0x00 0x00
713 * Cisco HDLC: hdr.xxx_x60[14:15]: 0xff 0xff
714 * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
717 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
718 break;
720 case WAN_CAPTYPE_HDLC:
721 case WAN_CAPTYPE_HDLC2:
723 * Various HDLC flavors?
725 switch (hdr.wan_hdlc_subsub_captype) {
727 case 0: /* LAPB/X.25 */
729 * XXX - at least one capture of
730 * this type appears to be PPP.
732 file_encap = WTAP_ENCAP_LAPB;
733 break;
735 case 1: /* E1 PRI */
736 case 2: /* T1 PRI */
737 case 3: /* BRI */
738 file_encap = WTAP_ENCAP_ISDN;
739 isdn_type = hdr.wan_hdlc_subsub_captype;
740 break;
742 default:
743 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
744 *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
745 hdr.wan_hdlc_subsub_captype);
746 return -1;
748 break;
750 case WAN_CAPTYPE_SDLC:
752 * SDLC.
754 file_encap = WTAP_ENCAP_SDLC;
755 break;
757 case WAN_CAPTYPE_CHDLC:
759 * Cisco router (CHDLC) captured with pod
761 file_encap = WTAP_ENCAP_CHDLC_WITH_PHDR;
762 break;
764 default:
765 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
766 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
767 hdr.captype);
768 return -1;
770 } else
771 file_encap = WTAP_ENCAP_ETHERNET;
772 } else
773 file_encap = netxray_encap[network_type];
775 /* This is a netxray file */
776 wth->file_type_subtype = 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
806 * FCS at the end;
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
832 * a bit bizarre.
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
861 * capture has FCSes.
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;
881 break;
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, netxray->start_offset, SEEK_SET, err) == -1) {
902 return -1;
905 return 1;
908 /* Read the next packet */
909 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
910 gint64 *data_offset)
912 netxray_t *netxray = (netxray_t *)wth->priv;
913 guint32 packet_size;
914 union netxrayrec_hdr hdr;
915 int hdr_size;
917 reread:
919 * Return the offset of the record header, so we can reread it
920 * if we go back to this frame.
922 *data_offset = file_tell(wth->fh);
924 /* Have we reached the end of the packet data? */
925 if (*data_offset == netxray->end_offset) {
926 /* Yes. */
927 *err = 0; /* it's just an EOF, not an error */
928 return FALSE;
931 /* Read record header. */
932 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err, err_info);
933 if (hdr_size == 0) {
935 * Error or EOF.
937 if (*err != 0) {
939 * Error of some sort; give up.
941 return FALSE;
944 /* We're at EOF. Wrap?
945 * XXX: Need to handle 'short file' cases
946 * (Distributed Sniffer seems to have a
947 * certain small propensity to generate 'short' files
948 * i.e. [many] bytes are missing from the end of the file)
949 * case 1: start_offset < end_offset
950 * wrap will read already read packets again;
951 * so: error with "short file"
952 * case 2: start_offset > end_offset ("circular" file)
953 * wrap will mean there's a gap (missing packets).
954 * However, I don't see a good way to identify this
955 * case so we'll just have to allow the wrap.
956 * (Maybe there can be an error message after all
957 * packets are read since there'll be less packets than
958 * specified in the file header).
959 * Note that these cases occur *only* if a 'short' eof occurs exactly
960 * at the expected beginning of a frame header record; If there is a
961 * partial frame header (or partial frame data) record, then the
962 * netxray_read... functions will detect the short record.
964 if (netxray->start_offset < netxray->end_offset) {
965 *err = WTAP_ERR_SHORT_READ;
966 return FALSE;
969 if (!netxray->wrapped) {
970 /* Yes. Remember that we did. */
971 netxray->wrapped = TRUE;
972 if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
973 SEEK_SET, err) == -1)
974 return FALSE;
975 goto reread;
978 /* We've already wrapped - don't wrap again. */
979 return FALSE;
983 * Read the packet data.
985 if (netxray->version_major == 0)
986 packet_size = pletohs(&hdr.old_hdr.len);
987 else
988 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
989 if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer, packet_size,
990 err, err_info))
991 return FALSE;
994 * Fill in the struct wtap_pkthdr.
996 netxray_set_phdr(wth, wth->frame_buffer, packet_size, &wth->phdr, &hdr);
997 return TRUE;
1000 static gboolean
1001 netxray_seek_read(wtap *wth, gint64 seek_off,
1002 struct wtap_pkthdr *phdr, Buffer *buf, int length,
1003 int *err, gchar **err_info)
1005 union netxrayrec_hdr hdr;
1007 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1008 return FALSE;
1010 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err,
1011 err_info)) {
1012 if (*err == 0) {
1014 * EOF - we report that as a short read, as
1015 * we've read this once and know that it
1016 * should be there.
1018 *err = WTAP_ERR_SHORT_READ;
1020 return FALSE;
1024 * Read the packet data.
1026 if (!wtap_read_packet_bytes(wth->random_fh, buf, length, err, err_info))
1027 return FALSE;
1030 * Fill in the struct wtap_pkthdr.
1032 netxray_set_phdr(wth, buf, length, phdr, &hdr);
1033 return TRUE;
1036 static int
1037 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1038 int *err, gchar **err_info)
1040 netxray_t *netxray = (netxray_t *)wth->priv;
1041 int bytes_read;
1042 int hdr_size = 0;
1044 /* Read record header. */
1045 switch (netxray->version_major) {
1047 case 0:
1048 hdr_size = sizeof (struct old_netxrayrec_hdr);
1049 break;
1051 case 1:
1052 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1053 break;
1055 case 2:
1056 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1057 break;
1059 errno = WTAP_ERR_CANT_READ;
1060 bytes_read = file_read(hdr, hdr_size, fh);
1061 if (bytes_read != hdr_size) {
1062 *err = file_error(wth->fh, err_info);
1063 if (*err != 0)
1064 return 0;
1065 if (bytes_read != 0) {
1066 *err = WTAP_ERR_SHORT_READ;
1067 return 0;
1071 * We're at EOF. "*err" is 0; we return FALSE - that
1072 * combination tells our caller we're at EOF.
1074 return 0;
1076 return hdr_size;
1079 static void
1080 netxray_set_phdr(wtap *wth, Buffer *buf, int len,
1081 struct wtap_pkthdr *phdr, union netxrayrec_hdr *hdr)
1083 netxray_t *netxray = (netxray_t *)wth->priv;
1084 double t;
1085 guint32 packet_size;
1086 guint padding = 0;
1087 const guint8 *pd;
1090 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1091 * pseudo-header.
1093 switch (netxray->version_major) {
1095 case 1:
1096 switch (wth->file_encap) {
1098 case WTAP_ENCAP_ETHERNET:
1100 * XXX - if hdr->hdr_1_x.xxx[15] is 1
1101 * the frame appears not to have any extra
1102 * stuff at the end, but if it's 0,
1103 * there appears to be 4 bytes of stuff
1104 * at the end, but it's not an FCS.
1106 * Or is that just the low-order bit?
1108 * For now, we just say "no FCS".
1110 phdr->pseudo_header.eth.fcs_len = 0;
1111 break;
1113 break;
1115 case 2:
1116 switch (wth->file_encap) {
1118 case WTAP_ENCAP_ETHERNET:
1120 * It appears, at least with version 2 captures,
1121 * that we have 4 bytes of stuff (which might be
1122 * a valid FCS or might be junk) at the end of
1123 * the packet if hdr->hdr_2_x.xxx[2] and
1124 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1125 * they don't.
1127 * It also appears that if the low-order bit of
1128 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1129 * bad FCS.
1131 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1132 hdr->hdr_2_x.xxx[3] == 0xff) {
1134 * We have 4 bytes of stuff at the
1135 * end of the frame - FCS, or junk?
1137 if (netxray->fcs_valid) {
1139 * FCS.
1141 phdr->pseudo_header.eth.fcs_len = 4;
1142 } else {
1144 * Junk.
1146 padding = 4;
1148 } else
1149 phdr->pseudo_header.eth.fcs_len = 0;
1150 break;
1152 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1154 * It appears, in one 802.11 capture, that
1155 * we have 4 bytes of junk at the ends of
1156 * frames in which hdr->hdr_2_x.xxx[2] and
1157 * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1158 * seen any frames where it's an FCS, but,
1159 * for now, we still check the fcs_valid
1160 * flag - I also haven't seen any capture
1161 * where we'd set it based on the realtick
1162 * value.
1164 * It also appears that if the low-order bit of
1165 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1166 * bad FCS. According to Ken Mann, the 0x4 bit
1167 * is sometimes also set for errors.
1169 * Ken also says that xxx[11] is 0x5 when the
1170 * packet is WEP-encrypted.
1172 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1173 hdr->hdr_2_x.xxx[3] == 0xff) {
1175 * We have 4 bytes of stuff at the
1176 * end of the frame - FCS, or junk?
1178 if (netxray->fcs_valid) {
1180 * FCS.
1182 phdr->pseudo_header.ieee_802_11.fcs_len = 4;
1183 } else {
1185 * Junk.
1187 padding = 4;
1189 } else
1190 phdr->pseudo_header.ieee_802_11.fcs_len = 0;
1192 phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
1194 phdr->pseudo_header.ieee_802_11.channel =
1195 hdr->hdr_2_x.xxx[12];
1196 phdr->pseudo_header.ieee_802_11.data_rate =
1197 hdr->hdr_2_x.xxx[13];
1198 phdr->pseudo_header.ieee_802_11.signal_level =
1199 hdr->hdr_2_x.xxx[14];
1201 * According to Ken Mann, at least in the captures
1202 * he's seen, xxx[15] is the noise level, which
1203 * is either 0xFF meaning "none reported" or a value
1204 * from 0x00 to 0x7F for 0 to 100%.
1206 break;
1208 case WTAP_ENCAP_ISDN:
1210 * ISDN.
1212 * The bottommost bit of byte 12 of "hdr->hdr_2_x.xxx"
1213 * is the direction flag.
1215 * The bottom 5 bits of byte 13 of "hdr->hdr_2_x.xxx"
1216 * are the channel number, but some mapping is
1217 * required for PRI. (Is it really just the time
1218 * slot?)
1220 phdr->pseudo_header.isdn.uton =
1221 (hdr->hdr_2_x.xxx[12] & 0x01);
1222 phdr->pseudo_header.isdn.channel =
1223 hdr->hdr_2_x.xxx[13] & 0x1F;
1224 switch (netxray->isdn_type) {
1226 case 1:
1228 * E1 PRI. Channel numbers 0 and 16
1229 * are the D channel; channel numbers 1
1230 * through 15 are B1 through B15; channel
1231 * numbers 17 through 31 are B16 through
1232 * B31.
1234 if (phdr->pseudo_header.isdn.channel == 16)
1235 phdr->pseudo_header.isdn.channel = 0;
1236 else if (phdr->pseudo_header.isdn.channel > 16)
1237 phdr->pseudo_header.isdn.channel -= 1;
1238 break;
1240 case 2:
1242 * T1 PRI. Channel numbers 0 and 24
1243 * are the D channel; channel numbers 1
1244 * through 23 are B1 through B23.
1246 if (phdr->pseudo_header.isdn.channel == 24)
1247 phdr->pseudo_header.isdn.channel = 0;
1248 else if (phdr->pseudo_header.isdn.channel > 24)
1249 phdr->pseudo_header.isdn.channel -= 1;
1250 break;
1254 * It appears, at least with version 2 captures,
1255 * that we have 4 bytes of stuff (which might be
1256 * a valid FCS or might be junk) at the end of
1257 * the packet if hdr->hdr_2_x.xxx[2] and
1258 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1259 * they don't.
1261 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1262 * indicate a bad FCS, as is the case with
1263 * Ethernet?
1265 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1266 hdr->hdr_2_x.xxx[3] == 0xff) {
1268 * FCS, or junk, at the end.
1269 * XXX - is it an FCS if "fcs_valid" is
1270 * true?
1272 padding = 4;
1274 break;
1276 case WTAP_ENCAP_LAPB:
1277 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1279 * LAPB/X.25 and Frame Relay.
1281 * The bottommost bit of byte 12 of "hdr->hdr_2_x.xxx"
1282 * is the direction flag. (Probably true for other
1283 * HDLC encapsulations as well.)
1285 phdr->pseudo_header.x25.flags =
1286 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1289 * It appears, at least with version 2 captures,
1290 * that we have 4 bytes of stuff (which might be
1291 * a valid FCS or might be junk) at the end of
1292 * the packet if hdr->hdr_2_x.xxx[2] and
1293 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1294 * they don't.
1296 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1297 * indicate a bad FCS, as is the case with
1298 * Ethernet?
1300 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1301 hdr->hdr_2_x.xxx[3] == 0xff) {
1303 * FCS, or junk, at the end.
1304 * XXX - is it an FCS if "fcs_valid" is
1305 * true?
1307 padding = 4;
1309 break;
1311 case WTAP_ENCAP_PPP_WITH_PHDR:
1312 case WTAP_ENCAP_SDLC:
1313 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1314 phdr->pseudo_header.p2p.sent =
1315 (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1316 break;
1318 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1319 pd = buffer_start_ptr(buf);
1320 phdr->pseudo_header.atm.flags = 0;
1322 * XXX - is 0x08 an "OAM cell" flag?
1324 if (hdr->hdr_2_x.xxx[9] & 0x04)
1325 phdr->pseudo_header.atm.flags |= ATM_RAW_CELL;
1326 phdr->pseudo_header.atm.vpi = hdr->hdr_2_x.xxx[11];
1327 phdr->pseudo_header.atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1328 phdr->pseudo_header.atm.channel =
1329 (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1330 phdr->pseudo_header.atm.cells = 0;
1332 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1334 case 0x00: /* Unknown */
1336 * Infer the AAL, traffic type, and subtype.
1338 atm_guess_traffic_type(pd, len,
1339 &phdr->pseudo_header);
1340 break;
1342 case 0x50: /* AAL5 (including signalling) */
1343 phdr->pseudo_header.atm.aal = AAL_5;
1344 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1346 case 0x09:
1347 case 0x0a: /* Signalling traffic */
1348 phdr->pseudo_header.atm.aal = AAL_SIGNALLING;
1349 phdr->pseudo_header.atm.type = TRAF_UNKNOWN;
1350 phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
1351 break;
1353 case 0x0b: /* ILMI */
1354 phdr->pseudo_header.atm.type = TRAF_ILMI;
1355 phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
1356 break;
1358 case 0x0c: /* LANE LE Control */
1359 phdr->pseudo_header.atm.type = TRAF_LANE;
1360 phdr->pseudo_header.atm.subtype = TRAF_ST_LANE_LE_CTRL;
1361 break;
1363 case 0x0d:
1365 * 0x0d is *mostly* LANE 802.3,
1366 * but I've seen an LE Control frame
1367 * with 0x0d.
1369 phdr->pseudo_header.atm.type = TRAF_LANE;
1370 atm_guess_lane_type(pd, len,
1371 &phdr->pseudo_header);
1372 break;
1374 case 0x0f: /* LLC multiplexed */
1375 phdr->pseudo_header.atm.type = TRAF_LLCMX; /* XXX */
1376 phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
1377 break;
1379 default:
1381 * XXX - discover the other types.
1383 phdr->pseudo_header.atm.type = TRAF_UNKNOWN;
1384 phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
1385 break;
1387 break;
1389 default:
1391 * 0x60 seen, and dissected by Sniffer
1392 * Pro as a raw cell.
1394 * XXX - discover what those types are.
1396 phdr->pseudo_header.atm.aal = AAL_UNKNOWN;
1397 phdr->pseudo_header.atm.type = TRAF_UNKNOWN;
1398 phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
1399 break;
1401 break;
1403 break;
1406 if (netxray->version_major == 0) {
1407 phdr->presence_flags = WTAP_HAS_TS;
1408 t = (double)pletohl(&hdr->old_hdr.timelo)
1409 + (double)pletohl(&hdr->old_hdr.timehi)*4294967296.0;
1410 t /= netxray->ticks_per_sec;
1411 t -= netxray->start_timestamp;
1412 phdr->ts.secs = netxray->start_time + (long)t;
1413 phdr->ts.nsecs = (int)((t-(double)(unsigned long)(t))
1414 *1.0e9);
1416 * We subtract the padding from the packet size, so our caller
1417 * doesn't see it.
1419 packet_size = pletohs(&hdr->old_hdr.len);
1420 phdr->caplen = packet_size - padding;
1421 phdr->len = phdr->caplen;
1422 } else {
1423 phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
1424 t = (double)pletohl(&hdr->hdr_1_x.timelo)
1425 + (double)pletohl(&hdr->hdr_1_x.timehi)*4294967296.0;
1426 t /= netxray->ticks_per_sec;
1427 t -= netxray->start_timestamp;
1428 phdr->ts.secs = netxray->start_time + (time_t)t;
1429 phdr->ts.nsecs = (int)((t-(double)(unsigned long)(t))
1430 *1.0e9);
1432 * We subtract the padding from the packet size, so our caller
1433 * doesn't see it.
1435 packet_size = pletohs(&hdr->hdr_1_x.incl_len);
1436 phdr->caplen = packet_size - padding;
1437 phdr->len = pletohs(&hdr->hdr_1_x.orig_len) - padding;
1441 typedef struct {
1442 gboolean first_frame;
1443 nstime_t start;
1444 guint32 nframes;
1445 } netxray_dump_t;
1447 static const struct {
1448 int wtap_encap_value;
1449 int ndis_value;
1450 } wtap_encap_1_1[] = {
1451 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1452 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1453 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1454 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1456 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1458 static int
1459 wtap_encap_to_netxray_1_1_encap(int encap)
1461 unsigned int i;
1463 for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1464 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1465 return wtap_encap_1_1[i].ndis_value;
1468 return -1;
1471 /* Returns 0 if we could write the specified encapsulation type,
1472 an error indication otherwise. */
1473 int netxray_dump_can_write_encap_1_1(int encap)
1475 /* Per-packet encapsulations aren't supported. */
1476 if (encap == WTAP_ENCAP_PER_PACKET)
1477 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1479 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1480 return WTAP_ERR_UNSUPPORTED_ENCAP;
1482 return 0;
1485 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1486 failure */
1487 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err)
1489 netxray_dump_t *netxray;
1491 wdh->subtype_write = netxray_dump_1_1;
1492 wdh->subtype_close = netxray_dump_close_1_1;
1494 /* We can't fill in all the fields in the file header, as we
1495 haven't yet written any packets. As we'll have to rewrite
1496 the header when we've written out all the packets, we just
1497 skip over the header for now. */
1498 if (wtap_dump_file_seek(wdh, CAPTUREFILE_HEADER_SIZE, SEEK_SET, err) == -1)
1499 return FALSE;
1500 wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
1502 netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1503 wdh->priv = (void *)netxray;
1504 netxray->first_frame = TRUE;
1505 netxray->start.secs = 0;
1506 netxray->start.nsecs = 0;
1507 netxray->nframes = 0;
1509 return TRUE;
1512 /* Write a record for a packet to a dump file.
1513 Returns TRUE on success, FALSE on failure. */
1514 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1515 const struct wtap_pkthdr *phdr,
1516 const guint8 *pd, int *err)
1518 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1519 guint64 timestamp;
1520 guint32 t32;
1521 struct netxrayrec_1_x_hdr rec_hdr;
1523 /* NetXRay/Windows Sniffer files have a capture start date/time
1524 in the header, in a UNIX-style format, with one-second resolution,
1525 and a start time stamp with microsecond resolution that's just
1526 an arbitrary time stamp relative to some unknown time (boot
1527 time?), and have times relative to the start time stamp in
1528 the packet headers; pick the seconds value of the time stamp
1529 of the first packet as the UNIX-style start date/time, and make
1530 the high-resolution start time stamp 0, with the time stamp of
1531 packets being the delta between the stamp of the packet and
1532 the stamp of the first packet with the microseconds part 0. */
1533 if (netxray->first_frame) {
1534 netxray->first_frame = FALSE;
1535 netxray->start = phdr->ts;
1538 /* build the header for each packet */
1539 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1540 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1541 + ((guint64)phdr->ts.nsecs)/1000;
1542 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1543 rec_hdr.timelo = htolel(t32);
1544 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1545 rec_hdr.timehi = htolel(t32);
1546 rec_hdr.orig_len = htoles(phdr->len);
1547 rec_hdr.incl_len = htoles(phdr->caplen);
1549 if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1550 return FALSE;
1551 wdh->bytes_dumped += sizeof(rec_hdr);
1553 /* write the packet data */
1554 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1555 return FALSE;
1556 wdh->bytes_dumped += phdr->caplen;
1558 netxray->nframes++;
1560 return TRUE;
1563 /* Finish writing to a dump file.
1564 Returns TRUE on success, FALSE on failure. */
1565 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1567 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1568 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1569 gint64 filelen;
1570 struct netxray_hdr file_hdr;
1572 if (-1 == (filelen = wtap_dump_file_tell(wdh, err)))
1573 return FALSE;
1575 /* Go back to beginning */
1576 if (wtap_dump_file_seek(wdh, 0, SEEK_SET, err) == -1)
1577 return FALSE;
1579 /* Rewrite the file header. */
1580 if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
1581 return FALSE;
1583 /* "sniffer" version ? */
1584 memset(&file_hdr, '\0', sizeof file_hdr);
1585 memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1586 file_hdr.start_time = htolel(netxray->start.secs);
1587 file_hdr.nframes = htolel(netxray->nframes);
1588 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1589 /* XXX - large files? */
1590 file_hdr.end_offset = htolel((guint32)filelen);
1591 file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1592 file_hdr.timelo = htolel(0);
1593 file_hdr.timehi = htolel(0);
1595 memset(hdr_buf, '\0', sizeof hdr_buf);
1596 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1597 if (!wtap_dump_file_write(wdh, hdr_buf, sizeof hdr_buf, err))
1598 return FALSE;
1600 return TRUE;
1603 static const struct {
1604 int wtap_encap_value;
1605 int ndis_value;
1606 } wtap_encap_2_0[] = {
1607 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1608 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1609 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1610 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1611 { WTAP_ENCAP_PPP_WITH_PHDR, 3 }, /* -> NDIS WAN */
1612 { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 }, /* -> NDIS WAN */
1613 { WTAP_ENCAP_LAPB, 3 }, /* -> NDIS WAN */
1614 { WTAP_ENCAP_SDLC, 3 }, /* -> NDIS WAN */
1616 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1618 static int
1619 wtap_encap_to_netxray_2_0_encap(int encap)
1621 unsigned int i;
1623 for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1624 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1625 return wtap_encap_2_0[i].ndis_value;
1628 return -1;
1631 /* Returns 0 if we could write the specified encapsulation type,
1632 an error indication otherwise. */
1633 int netxray_dump_can_write_encap_2_0(int encap)
1635 /* Per-packet encapsulations aren't supported. */
1636 if (encap == WTAP_ENCAP_PER_PACKET)
1637 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1639 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1640 return WTAP_ERR_UNSUPPORTED_ENCAP;
1642 return 0;
1645 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1646 failure */
1647 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, int *err)
1649 netxray_dump_t *netxray;
1651 wdh->subtype_write = netxray_dump_2_0;
1652 wdh->subtype_close = netxray_dump_close_2_0;
1654 /* We can't fill in all the fields in the file header, as we
1655 haven't yet written any packets. As we'll have to rewrite
1656 the header when we've written out all the packets, we just
1657 skip over the header for now. */
1658 if (wtap_dump_file_seek(wdh, CAPTUREFILE_HEADER_SIZE, SEEK_SET, err) == -1)
1659 return FALSE;
1661 wdh->bytes_dumped += CAPTUREFILE_HEADER_SIZE;
1663 netxray = (netxray_dump_t *)g_malloc(sizeof(netxray_dump_t));
1664 wdh->priv = (void *)netxray;
1665 netxray->first_frame = TRUE;
1666 netxray->start.secs = 0;
1667 netxray->start.nsecs = 0;
1668 netxray->nframes = 0;
1670 return TRUE;
1673 /* Write a record for a packet to a dump file.
1674 Returns TRUE on success, FALSE on failure. */
1675 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1676 const struct wtap_pkthdr *phdr,
1677 const guint8 *pd, int *err)
1679 const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
1680 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1681 guint64 timestamp;
1682 guint32 t32;
1683 struct netxrayrec_2_x_hdr rec_hdr;
1685 /* NetXRay/Windows Sniffer files have a capture start date/time
1686 in the header, in a UNIX-style format, with one-second resolution,
1687 and a start time stamp with microsecond resolution that's just
1688 an arbitrary time stamp relative to some unknown time (boot
1689 time?), and have times relative to the start time stamp in
1690 the packet headers; pick the seconds value of the time stamp
1691 of the first packet as the UNIX-style start date/time, and make
1692 the high-resolution start time stamp 0, with the time stamp of
1693 packets being the delta between the stamp of the packet and
1694 the stamp of the first packet with the microseconds part 0. */
1695 if (netxray->first_frame) {
1696 netxray->first_frame = FALSE;
1697 netxray->start = phdr->ts;
1700 /* build the header for each packet */
1701 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1702 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1703 + ((guint64)phdr->ts.nsecs)/1000;
1704 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1705 rec_hdr.timelo = htolel(t32);
1706 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1707 rec_hdr.timehi = htolel(t32);
1708 rec_hdr.orig_len = htoles(phdr->len);
1709 rec_hdr.incl_len = htoles(phdr->caplen);
1711 switch (phdr->pkt_encap) {
1713 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1714 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1715 rec_hdr.xxx[13] = (guint8)pseudo_header->ieee_802_11.data_rate;
1716 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1717 break;
1719 case WTAP_ENCAP_PPP_WITH_PHDR:
1720 case WTAP_ENCAP_SDLC:
1721 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1722 break;
1724 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1725 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1726 break;
1729 if (!wtap_dump_file_write(wdh, &rec_hdr, sizeof(rec_hdr), err))
1730 return FALSE;
1731 wdh->bytes_dumped += sizeof(rec_hdr);
1733 /* write the packet data */
1734 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1735 return FALSE;
1736 wdh->bytes_dumped += phdr->caplen;
1738 netxray->nframes++;
1740 return TRUE;
1743 /* Finish writing to a dump file.
1744 Returns TRUE on success, FALSE on failure. */
1745 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1747 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1748 netxray_dump_t *netxray = (netxray_dump_t *)wdh->priv;
1749 gint64 filelen;
1750 struct netxray_hdr file_hdr;
1752 if (-1 == (filelen = wtap_dump_file_tell(wdh, err)))
1753 return FALSE;
1755 /* Go back to beginning */
1756 if (wtap_dump_file_seek(wdh, 0, SEEK_SET, err) == -1)
1757 return FALSE;
1759 /* Rewrite the file header. */
1760 if (!wtap_dump_file_write(wdh, netxray_magic, sizeof netxray_magic, err))
1761 return FALSE;
1763 /* "sniffer" version ? */
1764 memset(&file_hdr, '\0', sizeof file_hdr);
1765 memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1766 file_hdr.start_time = htolel(netxray->start.secs);
1767 file_hdr.nframes = htolel(netxray->nframes);
1768 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1769 /* XXX - large files? */
1770 file_hdr.end_offset = htolel((guint32)filelen);
1771 file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1772 file_hdr.timelo = htolel(0);
1773 file_hdr.timehi = htolel(0);
1774 switch (wdh->encap) {
1776 case WTAP_ENCAP_PPP_WITH_PHDR:
1777 file_hdr.captype = WAN_CAPTYPE_PPP;
1778 break;
1780 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1781 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1782 break;
1784 case WTAP_ENCAP_LAPB:
1785 file_hdr.captype = WAN_CAPTYPE_HDLC;
1786 file_hdr.wan_hdlc_subsub_captype = 0;
1787 break;
1789 case WTAP_ENCAP_SDLC:
1790 file_hdr.captype = WAN_CAPTYPE_SDLC;
1791 break;
1793 default:
1794 file_hdr.captype = CAPTYPE_NDIS;
1795 break;
1798 memset(hdr_buf, '\0', sizeof hdr_buf);
1799 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1800 if (!wtap_dump_file_write(wdh, hdr_buf, sizeof hdr_buf, err))
1801 return FALSE;
1803 return TRUE;