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]; /* in v2, means ??? */
82 guint8 xxx_x50[4]; /* unknown [other stuff] */
83 guint8 captype; /* capture type */
84 guint8 xxx_x55[3]; /* unknown [other stuff] */
85 guint8 xxx_x58[4]; /* unknown [other stuff] */
86 guint8 wan_hdlc_subsub_captype; /* WAN HDLC subsub_captype */
87 guint8 xxx_x5D[3]; /* unknown [other stuff] */
89 guint8 xxx_x60[16]; /* unknown [other stuff] */
91 guint8 xxx_x70[14]; /* unknown [other stuff] */
92 gint16 timezone_hrs; /* timezone hours [at least for version 2.2..]; */
93 /* positive values = west of UTC: */
94 /* negative values = east of UTC: */
95 /* e.g. +5 is American Eastern */
96 /* [Does not appear to be adjusted for DST ] */
100 * Capture type, in hdr.captype.
102 * XXX - S6040-model Sniffers with gigabit blades store 6 here for
103 * Ethernet captures, and some other Ethernet captures had a capture
104 * type of 3, so presumably the interpretation of the capture type
105 * depends on the network type. We prefix all the capture types
106 * for WAN captures with WAN_.
108 #define CAPTYPE_NDIS 0 /* Capture on network interface using NDIS */
111 * Ethernet capture types.
113 #define ETH_CAPTYPE_GIGPOD 2 /* gigabit Ethernet captured with pod */
114 #define ETH_CAPTYPE_OTHERPOD 3 /* non-gigabit Ethernet captured with pod */
115 #define ETH_CAPTYPE_OTHERPOD2 5 /* gigabit Ethernet via pod ?? */
116 /* Captype 5 seen in capture from Distributed Sniffer with: */
117 /* Version 4.50.211 software */
118 /* SysKonnect SK-9843 Gigabit Ethernet Server Adapter */
119 #define ETH_CAPTYPE_GIGPOD2 6 /* gigabit Ethernet captured with pod */
124 #define WAN_CAPTYPE_BROUTER 1 /* Bridge/router captured with pod */
125 #define WAN_CAPTYPE_PPP 3 /* PPP captured with pod */
126 #define WAN_CAPTYPE_FRELAY 4 /* Frame Relay captured with pod */
127 #define WAN_CAPTYPE_BROUTER2 5 /* Bridge/router captured with pod */
128 #define WAN_CAPTYPE_HDLC 6 /* HDLC (X.25, ISDN) captured with pod */
129 #define WAN_CAPTYPE_SDLC 7 /* SDLC captured with pod */
130 #define WAN_CAPTYPE_HDLC2 8 /* HDLC captured with pod */
131 #define WAN_CAPTYPE_BROUTER3 9 /* Bridge/router captured with pod */
132 #define WAN_CAPTYPE_SMDS 10 /* SMDS DXI */
133 #define WAN_CAPTYPE_BROUTER4 11 /* Bridge/router captured with pod */
134 #define WAN_CAPTYPE_BROUTER5 12 /* Bridge/router captured with pod */
136 #define CAPTYPE_ATM 15 /* ATM captured with pod */
139 * # of ticks that equal 1 second, in version 002.xxx files other
140 * than Ethernet captures with a captype other than CAPTYPE_NDIS;
141 * the index into this array is hdr.timeunit.
143 * DO NOT SEND IN PATCHES THAT CHANGE ANY OF THE NON-ZERO VALUES IN
144 * ANY OF THE TpS TABLES. THOSE VALUES ARE CORRECT FOR AT LEAST ONE
145 * CAPTURE, SO CHANGING THEM WILL BREAK AT LEAST SOME CAPTURES. WE
146 * WILL NOT CHECK IN PATCHES THAT CHANGE THESE VALUES.
148 * Instead, if a value in a TpS table is wrong, check whether captype
149 * has a non-zero value; if so, perhaps we need a new TpS table for the
150 * corresponding network type and captype.
152 * TpS...[] entries of 0.0 mean that no capture file for the
153 * corresponding captype/timeunit values has yet been seen
155 * Note that the "realtick" value is wrong in many captures, so
156 * we no longer use it. We don't know what significance it has.
157 * In at least one capture where "realtick" doesn't correspond
158 * to the value from the appropriate TpS table, the per-packet header's
159 * "xxx" field is all zero, so it's not as if a 2.x header includes
160 * a "compatibility" time stamp corresponding to the value from the
161 * TpS table and a "real" time stamp corresponding to "realtick".
163 * XXX - the third item is 1193180.0, presumably because somebody found
164 * it gave the right answer for some captures, but 3 times that, i.e.
165 * 3579540.0, appears to give the right answer for some other captures.
166 * Some captures have realtick of 1193182, some have 3579545, and some
167 * have 1193000. Most of those, in one set of captures somebody has,
170 * XXX - in at least one ATM capture, hdr.realtick is 1193180.0
171 * and hdr.timeunit is 0. Does that capture have a captype of
172 * CAPTYPE_ATM? If so, what should the table for ATM captures with
175 static double TpS[] = { 1e6, 1193000.0, 1193182.0 };
176 #define NUM_NETXRAY_TIMEUNITS (sizeof TpS / sizeof TpS[0])
179 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD.
180 * 0.0 means "unknown.
182 * It appears that, at least for Ethernet captures, if captype is
183 * ETH_CAPTYPE_GIGPOD, that indicates that it's a gigabit Ethernet
184 * capture, possibly from a special whizzo gigabit pod, and also
185 * indicates that the time stamps have some higher resolution than
186 * in other captures, possibly thanks to a high-resolution timer
189 * It also appears that the time units might differ for gigabit pod
190 * captures between version 002.001 and 002.002. For 002.001,
191 * the values below are correct; for 002.002, it's claimed that
192 * the right value for TpS_gigpod[2] is 1250000.0, but at least one
193 * 002.002 gigabit pod capture has 31250000.0 as the right value.
195 static double TpS_gigpod[] = { 1e9, 0.0, 31250000.0 };
196 #define NUM_NETXRAY_TIMEUNITS_GIGPOD (sizeof TpS_gigpod / sizeof TpS_gigpod[0])
199 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD.
201 static double TpS_otherpod[] = { 1e6, 0.0, 1250000.0 };
202 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD (sizeof TpS_otherpod / sizeof TpS_otherpod[0])
205 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_OTHERPOD2.
207 static double TpS_otherpod2[] = { 1e6, 0.0, 0.0 };
208 #define NUM_NETXRAY_TIMEUNITS_OTHERPOD2 (sizeof TpS_otherpod2 / sizeof TpS_otherpod2[0])
211 * Table of time units for Ethernet captures with captype ETH_CAPTYPE_GIGPOD2.
213 static double TpS_gigpod2[] = { 1e9, 0.0, 20000000.0 };
214 #define NUM_NETXRAY_TIMEUNITS_GIGPOD2 (sizeof TpS_gigpod2 / sizeof TpS_gigpod2[0])
216 /* Version number strings. */
217 static const char vers_1_0[] = {
218 '0', '0', '1', '.', '0', '0', '0', '\0'
221 static const char vers_1_1[] = {
222 '0', '0', '1', '.', '1', '0', '0', '\0'
225 static const char vers_2_000[] = {
226 '0', '0', '2', '.', '0', '0', '0', '\0'
229 static const char vers_2_001[] = {
230 '0', '0', '2', '.', '0', '0', '1', '\0'
233 static const char vers_2_002[] = {
234 '0', '0', '2', '.', '0', '0', '2', '\0'
237 static const char vers_2_003[] = {
238 '0', '0', '2', '.', '0', '0', '3', '\0'
241 /* Old NetXRay data record format - followed by frame data. */
242 struct old_netxrayrec_hdr {
243 guint32 timelo; /* lower 32 bits of time stamp */
244 guint32 timehi; /* upper 32 bits of time stamp */
245 guint16 len; /* packet length */
246 guint8 xxx[6]; /* unknown */
249 /* NetXRay format version 1.x data record format - followed by frame data. */
250 struct netxrayrec_1_x_hdr {
251 guint32 timelo; /* lower 32 bits of time stamp */
252 guint32 timehi; /* upper 32 bits of time stamp */
253 guint16 orig_len; /* packet length */
254 guint16 incl_len; /* capture length */
255 guint8 xxx[16]; /* unknown */
258 /* NetXRay format version 2.x data record format - followed by frame data. */
259 struct netxrayrec_2_x_hdr {
260 guint32 timelo; /* lower 32 bits of time stamp */
261 guint32 timehi; /* upper 32 bits of time stamp */
262 guint16 orig_len; /* packet length */
263 guint16 incl_len; /* capture length */
264 guint8 xxx[28]; /* various data */
268 * Union of the data record headers.
270 union netxrayrec_hdr {
271 struct old_netxrayrec_hdr old_hdr;
272 struct netxrayrec_1_x_hdr hdr_1_x;
273 struct netxrayrec_2_x_hdr hdr_2_x;
276 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
277 gint64 *data_offset);
278 static gboolean netxray_seek_read(wtap *wth, gint64 seek_off,
279 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
280 int *err, gchar **err_info);
281 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
282 union netxrayrec_hdr *hdr, int *err);
283 static guint netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
284 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr);
285 static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr,
286 guint32 packet_size, int *err);
287 static void netxray_close(wtap *wth);
288 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
289 const struct wtap_pkthdr *phdr,
290 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
291 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
292 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
293 const struct wtap_pkthdr *phdr,
294 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
295 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
297 int netxray_open(wtap *wth, int *err, gchar **err_info)
300 char magic[sizeof netxray_magic];
302 struct netxray_hdr hdr;
305 int version_major, version_minor;
307 double start_timestamp;
308 static const int netxray_encap[] = {
311 WTAP_ENCAP_TOKEN_RING,
312 WTAP_ENCAP_FDDI_BITSWAPPED,
314 * XXX - some PPP captures may look like Ethernet,
315 * perhaps because they're using NDIS to capture on the
316 * same machine and it provides simulated-Ethernet
317 * packets, but captures taken with various serial
318 * pods use the same network type value but aren't
319 * shaped like Ethernet. We handle that below.
321 WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */
322 WTAP_ENCAP_UNKNOWN, /* LocalTalk */
323 WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */
324 WTAP_ENCAP_UNKNOWN, /* ARCNET raw */
325 WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */
326 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,/* ATM */
327 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
328 /* Wireless WAN with radio information */
329 WTAP_ENCAP_UNKNOWN /* IrDA */
331 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
335 /* Read in the string that should be at the start of a NetXRay
337 errno = WTAP_ERR_CANT_READ;
338 bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
339 if (bytes_read != sizeof magic) {
340 *err = file_error(wth->fh);
345 wth->data_offset += sizeof magic;
347 if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
349 } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
355 /* Read the rest of the header. */
356 errno = WTAP_ERR_CANT_READ;
357 bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
358 if (bytes_read != sizeof hdr) {
359 *err = file_error(wth->fh);
364 wth->data_offset += sizeof hdr;
369 file_type = WTAP_FILE_NETXRAY_OLD;
371 /* It appears that version 1.1 files (as produced by Windows
372 * Sniffer Pro 2.0.01) have the time stamp in microseconds,
373 * rather than the milliseconds version 1.0 files appear to
376 * It also appears that version 2.00x files have per-packet
377 * headers with some extra fields. */
378 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
381 file_type = WTAP_FILE_NETXRAY_1_0;
382 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
385 file_type = WTAP_FILE_NETXRAY_1_1;
386 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
389 file_type = WTAP_FILE_NETXRAY_2_00x;
390 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
393 file_type = WTAP_FILE_NETXRAY_2_00x;
394 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
397 file_type = WTAP_FILE_NETXRAY_2_00x;
398 } else if (memcmp(hdr.version, vers_2_003, sizeof vers_2_003) == 0) {
401 file_type = WTAP_FILE_NETXRAY_2_00x;
403 *err = WTAP_ERR_UNSUPPORTED;
404 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
409 switch (hdr.network_plus) {
413 * The byte after hdr.network is usually 0, in which case
414 * the hdr.network byte is an NDIS network type value - 1.
416 network_type = hdr.network + 1;
421 * However, in some Ethernet captures, it's 2, and the
422 * hdr.network byte is 1 rather than 0. We assume
423 * that if there's a byte after hdr.network with the value
424 * 2, the hdr.network byte is an NDIS network type, rather
425 * than an NDIS network type - 1.
427 network_type = hdr.network;
431 *err = WTAP_ERR_UNSUPPORTED;
432 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
437 if (network_type >= NUM_NETXRAY_ENCAPS
438 || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
439 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
440 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
441 network_type, hdr.network_plus);
446 * Figure out the time stamp units and start time stamp.
448 start_timestamp = (double)pletohl(&hdr.timelo)
449 + (double)pletohl(&hdr.timehi)*4294967296.0;
452 case WTAP_FILE_NETXRAY_OLD:
454 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
457 case WTAP_FILE_NETXRAY_1_0:
459 wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
462 case WTAP_FILE_NETXRAY_1_1:
464 * In version 1.1 files (as produced by Windows Sniffer
465 * Pro 2.0.01), the time stamp is in microseconds,
466 * rather than the milliseconds time stamps in NetXRay
467 * and older versions of Windows Sniffer.
469 timeunit = 1000000.0;
470 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
473 case WTAP_FILE_NETXRAY_2_00x:
475 * Get the time stamp value from the appropriate TpS
478 switch (network_type) {
482 * Ethernet - the table to use depends on whether
483 * this is an NDIS or pod capture.
485 switch (hdr.captype) {
488 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
489 *err = WTAP_ERR_UNSUPPORTED;
490 *err_info = g_strdup_printf(
491 "netxray: Unknown timeunit %u for Ethernet/CAPTYPE_NDIS version %.8s capture",
492 hdr.timeunit, hdr.version);
495 timeunit = TpS[hdr.timeunit];
498 case ETH_CAPTYPE_GIGPOD:
499 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD
500 || TpS_gigpod[hdr.timeunit] == 0.0) {
501 *err = WTAP_ERR_UNSUPPORTED;
502 *err_info = g_strdup_printf(
503 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD version %.8s capture",
504 hdr.timeunit, hdr.version);
507 timeunit = TpS_gigpod[hdr.timeunit];
510 * At least for 002.002 and 002.003
511 * captures, the start time stamp is 0,
512 * not the value in the file.
514 if (version_minor == 2 || version_minor == 3)
515 start_timestamp = 0.0;
518 case ETH_CAPTYPE_OTHERPOD:
519 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD
520 || TpS_otherpod[hdr.timeunit] == 0.0) {
521 *err = WTAP_ERR_UNSUPPORTED;
522 *err_info = g_strdup_printf(
523 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD version %.8s capture",
524 hdr.timeunit, hdr.version);
527 timeunit = TpS_otherpod[hdr.timeunit];
530 * At least for 002.002 and 002.003
531 * captures, the start time stamp is 0,
532 * not the value in the file.
534 if (version_minor == 2 || version_minor == 3)
535 start_timestamp = 0.0;
538 case ETH_CAPTYPE_OTHERPOD2:
539 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_OTHERPOD2
540 || TpS_otherpod2[hdr.timeunit] == 0.0) {
541 *err = WTAP_ERR_UNSUPPORTED;
542 *err_info = g_strdup_printf(
543 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_OTHERPOD2 version %.8s capture",
544 hdr.timeunit, hdr.version);
547 timeunit = TpS_otherpod2[hdr.timeunit];
549 * XXX: start time stamp in the one capture file examined of this type was 0;
550 * We'll assume the start time handling is the same as for other pods.
552 * At least for 002.002 and 002.003
553 * captures, the start time stamp is 0,
554 * not the value in the file.
556 if (version_minor == 2 || version_minor == 3)
557 start_timestamp = 0.0;
560 case ETH_CAPTYPE_GIGPOD2:
561 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS_GIGPOD2
562 || TpS_gigpod2[hdr.timeunit] == 0.0) {
563 *err = WTAP_ERR_UNSUPPORTED;
564 *err_info = g_strdup_printf(
565 "netxray: Unknown timeunit %u for Ethernet/ETH_CAPTYPE_GIGPOD2 version %.8s capture",
566 hdr.timeunit, hdr.version);
569 timeunit = TpS_gigpod2[hdr.timeunit];
571 * XXX: start time stamp in the one capture file examined of this type was 0;
572 * We'll assume the start time handling is the same as for other pods.
574 * At least for 002.002 and 002.003
575 * captures, the start time stamp is 0,
576 * not the value in the file.
578 if (version_minor == 2 || version_minor == 3)
579 start_timestamp = 0.0;
583 *err = WTAP_ERR_UNSUPPORTED;
584 *err_info = g_strdup_printf(
585 "netxray: Unknown capture type %u for Ethernet version %.8s capture",
586 hdr.captype, hdr.version);
592 if (hdr.timeunit >= NUM_NETXRAY_TIMEUNITS) {
593 *err = WTAP_ERR_UNSUPPORTED;
594 *err_info = g_strdup_printf(
595 "netxray: Unknown timeunit %u for %u/%u version %.8s capture",
596 hdr.timeunit, network_type, hdr.captype,
600 timeunit = TpS[hdr.timeunit];
605 * If the number of ticks per second is greater than
606 * 1 million, make the precision be nanoseconds rather
609 * XXX - do values only slightly greater than one million
610 * correspond to a resolution sufficiently better than
611 * 1 microsecond to display more digits of precision?
612 * XXX - Seems reasonable to use nanosecs only if TPS >= 10M
615 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
617 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
621 g_assert_not_reached();
624 start_timestamp = start_timestamp/timeunit;
626 if (network_type == 4) {
628 * In version 0 and 1, we assume, for now, that all
629 * WAN captures have frames that look like Ethernet
630 * frames (as a result, presumably, of having passed
633 * In version 2, it looks as if there's stuff in the
634 * file header to specify what particular type of WAN
637 if (version_major == 2) {
638 switch (hdr.captype) {
640 case WAN_CAPTYPE_PPP:
644 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
647 case WAN_CAPTYPE_FRELAY:
651 * XXX - in at least one capture, this
652 * is Cisco HDLC, not Frame Relay, but
653 * in another capture, it's Frame Relay.
655 * [Bytes in each capture:
656 * Cisco HDLC: hdr.xxx_x60[06:10]: 0x02 0x00 0x01 0x00 0x06
657 * Frame Relay: hdr.xxx_x60[06:10] 0x00 0x00 0x00 0x00 0x00
659 * Cisco HDLC: hdr.xxx_x60[14:15]: 0xff 0xff
660 * Frame Relay: hdr.xxx_x60[14:15]: 0x00 0x00
663 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
666 case WAN_CAPTYPE_HDLC:
667 case WAN_CAPTYPE_HDLC2:
669 * Various HDLC flavors?
671 switch (hdr.wan_hdlc_subsub_captype) {
673 case 0: /* LAPB/X.25 */
674 file_encap = WTAP_ENCAP_LAPB;
680 file_encap = WTAP_ENCAP_ISDN;
681 isdn_type = hdr.wan_hdlc_subsub_captype;
685 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
686 *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
687 hdr.wan_hdlc_subsub_captype);
692 case WAN_CAPTYPE_SDLC:
696 file_encap = WTAP_ENCAP_SDLC;
700 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
701 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
706 file_encap = WTAP_ENCAP_ETHERNET;
708 file_encap = netxray_encap[network_type];
710 /* This is a netxray file */
711 wth->file_type = file_type;
712 wth->capture.netxray = g_malloc(sizeof(netxray_t));
713 wth->subtype_read = netxray_read;
714 wth->subtype_seek_read = netxray_seek_read;
715 wth->subtype_close = netxray_close;
716 wth->file_encap = file_encap;
717 wth->snapshot_length = 0; /* not available in header */
718 wth->capture.netxray->start_time = pletohl(&hdr.start_time);
719 wth->capture.netxray->timeunit = timeunit;
720 wth->capture.netxray->start_timestamp = start_timestamp;
721 wth->capture.netxray->version_major = version_major;
724 * If frames have an extra 4 bytes of stuff at the end, is
725 * it an FCS, or just junk?
727 wth->capture.netxray->fcs_valid = FALSE;
728 switch (file_encap) {
730 case WTAP_ENCAP_ETHERNET:
731 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
732 case WTAP_ENCAP_ISDN:
734 * It appears that, in at least some version 2 Ethernet
735 * captures, for frames that have 0xff in hdr_2_x.xxx[2]
736 * and hdr_2_x.xxx[3] in the per-packet header:
738 * if, in the file header, hdr.realtick[1] is 0x34
739 * and hdr.realtick[2] is 0x12, the frames have an
742 * otherwise, they have 4 bytes of junk at the end.
744 * Yes, it's strange that you have to check the *middle*
745 * of the time stamp field; you can't check for any
746 * particular value of the time stamp field.
748 * For now, we assume that to be true for 802.11 captures
749 * as well; it appears to be the case for at least one
750 * such capture - the file doesn't have 0x34 and 0x12,
751 * and the 4 bytes at the end of the frames with 0xff
752 * are junk, not an FCS.
754 * For ISDN captures, it appears, at least in some
755 * captures, to be similar, although I haven't yet
756 * checked whether it's a valid FCS.
758 * XXX - should we do this for all encapsulation types?
760 * XXX - is there some other field that *really* indicates
761 * whether we have an FCS or not? The check of the time
762 * stamp is bizarre, as we're checking the middle.
763 * Perhaps hdr.realtick[0] is 0x00, in which case time
764 * stamp units in the range 1192960 through 1193215
765 * correspond to captures with an FCS, but that's still
768 * Note that there are captures with a network type of 0
769 * (Ethernet) and capture type of 0 (NDIS) that do, and
770 * that don't, have 0x34 0x12 in them, and at least one
771 * of the NDIS captures with 0x34 0x12 in it has FCSes,
772 * so it's not as if no NDIS captures have an FCS.
774 * There are also captures with a network type of 4 (WAN),
775 * capture type of 6 (HDLC), and subtype of 2 (T1 PRI) that
776 * do, and that don't, have 0x34 0x12, so there are at least
777 * some captures taken with a WAN pod that might lack an FCS.
778 * (We haven't yet tried dissecting the 4 bytes at the
779 * end of packets with hdr_2_x.xxx[2] and hdr_2_x.xxx[3]
780 * equal to 0xff as an FCS.)
782 * All captures I've seen that have 0x34 and 0x12 *and*
783 * have at least one frame with an FCS have a value of
784 * 0x01 in xxx_x40[4]. No captures I've seen with a network
785 * type of 0 (Ethernet) missing 0x34 0x12 have 0x01 there,
786 * however. However, there's at least one capture
787 * without 0x34 and 0x12, with a network type of 0,
788 * and with 0x01 in xxx_x40[4], *without* FCSes in the
789 * frames - the 4 bytes at the end are all zero - so it's
790 * not as simple as "xxx_x40[4] = 0x01 means the 4 bytes at
791 * the end are FCSes". Also, there's also at least one
792 * 802.11 capture with an xxx_x40[4] value of 0x01 with junk
793 * rather than an FCS at the end of the frame, so xxx_x40[4]
794 * isn't an obvious flag to determine whether the
797 * There don't seem to be any other values in any of the
798 * xxx_x5..., xxx_x6...., xxx_x7.... fields
799 * that obviously correspond to frames having an FCS.
801 if (version_major == 2) {
802 if (hdr.realtick[1] == 0x34 && hdr.realtick[2] == 0x12)
803 wth->capture.netxray->fcs_valid = TRUE;
809 * Remember the ISDN type, as we need it to interpret the
810 * channel number in ISDN captures.
812 wth->capture.netxray->isdn_type = isdn_type;
814 /* Remember the offset after the last packet in the capture (which
815 * isn't necessarily the last packet in the file), as it appears
816 * there's sometimes crud after it.
817 * XXX: Remember 'start_offset' to help testing for 'short file' at EOF
819 wth->capture.netxray->wrapped = FALSE;
820 wth->capture.netxray->nframes = pletohl(&hdr.nframes);
821 wth->capture.netxray->start_offset = pletohl(&hdr.start_offset);
822 wth->capture.netxray->end_offset = pletohl(&hdr.end_offset);
824 /* Seek to the beginning of the data records. */
825 if (file_seek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET, err) == -1) {
826 g_free(wth->capture.netxray);
829 wth->data_offset = pletohl(&hdr.start_offset);
834 /* Read the next packet */
835 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info _U_,
839 union netxrayrec_hdr hdr;
846 /* Have we reached the end of the packet data? */
847 if (wth->data_offset == wth->capture.netxray->end_offset) {
849 *err = 0; /* it's just an EOF, not an error */
852 /* Read record header. */
853 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err);
860 * Error of some sort; give up.
865 /* We're at EOF. Wrap?
866 * XXX: Need to handle 'short file' cases
867 * (Distributed Sniffer seems to have a
868 * certain small propensity to generate 'short' files
869 * i.e. [many] bytes are missing from the end of the file)
870 * case 1: start_offset < end_offset
871 * wrap will read already read packets again;
872 * so: error with "short file"
873 * case 2: start_offset > end_offset ("circular" file)
874 * wrap will mean there's a gap (missing packets).
875 * However, I don't see a good way to identify this
876 * case so we'll just have to allow the wrap.
877 * (Maybe there can be an error message after all
878 * packets are read since there'll be less packets than
879 * specified in the file header).
880 * Note that these cases occur *only* if a 'short' eof occurs exactly
881 * at the expected beginning of a frame header record; If there is a
882 * partial frame header (or partial frame data) record, then the
883 * netxray_read... functions will detect the short record.
885 if (wth->capture.netxray->start_offset < wth->capture.netxray->end_offset) {
886 *err = WTAP_ERR_SHORT_READ;
890 if (!wth->capture.netxray->wrapped) {
891 /* Yes. Remember that we did. */
892 wth->capture.netxray->wrapped = TRUE;
893 if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
894 SEEK_SET, err) == -1)
896 wth->data_offset = CAPTUREFILE_HEADER_SIZE;
900 /* We've already wrapped - don't wrap again. */
905 * Return the offset of the record header, so we can reread it
906 * if we go back to this frame.
908 *data_offset = wth->data_offset;
909 wth->data_offset += hdr_size;
912 * Read the packet data.
914 if (wth->capture.netxray->version_major == 0)
915 packet_size = pletohs(&hdr.old_hdr.len);
917 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
918 buffer_assure_space(wth->frame_buffer, packet_size);
919 pd = buffer_start_ptr(wth->frame_buffer);
920 if (!netxray_read_rec_data(wth->fh, pd, packet_size, err))
922 wth->data_offset += packet_size;
925 * Set the pseudo-header.
927 padding = netxray_set_pseudo_header(wth, pd, packet_size,
928 &wth->pseudo_header, &hdr);
930 if (wth->capture.netxray->version_major == 0) {
931 t = (double)pletohl(&hdr.old_hdr.timelo)
932 + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
933 t /= wth->capture.netxray->timeunit;
934 t -= wth->capture.netxray->start_timestamp;
935 wth->phdr.ts.secs = wth->capture.netxray->start_time + (long)t;
936 wth->phdr.ts.nsecs = (unsigned long)((t-(double)(unsigned long)(t))
939 * We subtract the padding from the packet size, so our caller
942 wth->phdr.caplen = packet_size - padding;
943 wth->phdr.len = wth->phdr.caplen;
945 t = (double)pletohl(&hdr.hdr_1_x.timelo)
946 + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
947 t /= wth->capture.netxray->timeunit;
948 t -= wth->capture.netxray->start_timestamp;
949 wth->phdr.ts.secs = wth->capture.netxray->start_time + (long)t;
950 wth->phdr.ts.nsecs = (unsigned long)((t-(double)(unsigned long)(t))
953 * We subtract the padding from the packet size, so our caller
956 wth->phdr.caplen = packet_size - padding;
957 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
964 netxray_seek_read(wtap *wth, gint64 seek_off,
965 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
966 int *err, gchar **err_info _U_)
968 union netxrayrec_hdr hdr;
971 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
974 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) {
977 * EOF - we report that as a short read, as
978 * we've read this once and know that it
981 *err = WTAP_ERR_SHORT_READ;
987 * Read the packet data.
989 ret = netxray_read_rec_data(wth->random_fh, pd, length, err);
994 * Set the pseudo-header.
996 netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
1001 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
1007 /* Read record header. */
1008 switch (wth->capture.netxray->version_major) {
1011 hdr_size = sizeof (struct old_netxrayrec_hdr);
1015 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
1019 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
1022 errno = WTAP_ERR_CANT_READ;
1023 bytes_read = file_read(hdr, 1, hdr_size, fh);
1024 if (bytes_read != hdr_size) {
1025 *err = file_error(wth->fh);
1028 if (bytes_read != 0) {
1029 *err = WTAP_ERR_SHORT_READ;
1034 * We're at EOF. "*err" is 0; we return FALSE - that
1035 * combination tells our caller we're at EOF.
1043 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
1044 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
1049 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
1052 switch (wth->capture.netxray->version_major) {
1055 switch (wth->file_encap) {
1057 case WTAP_ENCAP_ETHERNET:
1059 * XXX - if hdr->hdr_1_x.xxx[15] is 1
1060 * the frame appears not to have any extra
1061 * stuff at the end, but if it's 0,
1062 * there appears to be 4 bytes of stuff
1063 * at the end, but it's not an FCS.
1065 * Or is that just the low-order bit?
1067 * For now, we just say "no FCS".
1069 pseudo_header->eth.fcs_len = 0;
1075 switch (wth->file_encap) {
1077 case WTAP_ENCAP_ETHERNET:
1079 * It appears, at least with version 2 captures,
1080 * that we have 4 bytes of stuff (which might be
1081 * a valid FCS or might be junk) at the end of
1082 * the packet if hdr->hdr_2_x.xxx[2] and
1083 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1086 * It also appears that if the low-order bit of
1087 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1090 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1091 hdr->hdr_2_x.xxx[3] == 0xff) {
1093 * We have 4 bytes of stuff at the
1094 * end of the frame - FCS, or junk?
1096 if (wth->capture.netxray->fcs_valid) {
1100 pseudo_header->eth.fcs_len = 4;
1108 pseudo_header->eth.fcs_len = 0;
1111 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1113 * It appears, in one 802.11 capture, that
1114 * we have 4 bytes of junk at the ends of
1115 * frames in which hdr->hdr_2_x.xxx[2] and
1116 * hdr->hdr_2_x.xxx[3] are 0xff; I haven't
1117 * seen any frames where it's an FCS, but,
1118 * for now, we still check the fcs_valid
1119 * flag - I also haven't seen any capture
1120 * where we'd set it based on the realtick
1123 * It also appears that if the low-order bit of
1124 * hdr->hdr_2_x.xxx[8] is set, the packet has a
1125 * bad FCS. According to Ken Mann, the 0x4 bit
1126 * is sometimes also set for errors.
1128 * Ken also says that xxx[11] is 0x5 when the
1129 * packet is WEP-encrypted.
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 (wth->capture.netxray->fcs_valid) {
1141 pseudo_header->ieee_802_11.fcs_len = 4;
1149 pseudo_header->ieee_802_11.fcs_len = 0;
1151 pseudo_header->ieee_802_11.channel =
1152 hdr->hdr_2_x.xxx[12];
1153 pseudo_header->ieee_802_11.data_rate =
1154 hdr->hdr_2_x.xxx[13];
1155 pseudo_header->ieee_802_11.signal_level =
1156 hdr->hdr_2_x.xxx[14];
1158 * According to Ken Mann, at least in the captures
1159 * he's seen, xxx[15] is the noise level, which
1160 * is either 0xFF meaning "none reported" or a value
1161 * from 0x00 to 0x7F for 0 to 100%.
1165 case WTAP_ENCAP_ISDN:
1169 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1170 * is the direction flag.
1172 * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
1173 * are the channel number, but some mapping is
1174 * required for PRI. (Is it really just the time
1177 pseudo_header->isdn.uton =
1178 (hdr->hdr_2_x.xxx[12] & 0x01);
1179 pseudo_header->isdn.channel =
1180 hdr->hdr_2_x.xxx[13] & 0x1F;
1181 switch (wth->capture.netxray->isdn_type) {
1185 * E1 PRI. Channel numbers 0 and 16
1186 * are the D channel; channel numbers 1
1187 * through 15 are B1 through B15; channel
1188 * numbers 17 through 31 are B16 through
1191 if (pseudo_header->isdn.channel == 16)
1192 pseudo_header->isdn.channel = 0;
1193 else if (pseudo_header->isdn.channel > 16)
1194 pseudo_header->isdn.channel -= 1;
1199 * T1 PRI. Channel numbers 0 and 24
1200 * are the D channel; channel numbers 1
1201 * through 23 are B1 through B23.
1203 if (pseudo_header->isdn.channel == 24)
1204 pseudo_header->isdn.channel = 0;
1205 else if (pseudo_header->isdn.channel > 24)
1206 pseudo_header->isdn.channel -= 1;
1211 * It appears, at least with version 2 captures,
1212 * that we have 4 bytes of stuff (which might be
1213 * a valid FCS or might be junk) at the end of
1214 * the packet if hdr->hdr_2_x.xxx[2] and
1215 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
1218 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
1219 * indicate a bad FCS, as is the case with
1222 if (hdr->hdr_2_x.xxx[2] == 0xff &&
1223 hdr->hdr_2_x.xxx[3] == 0xff) {
1225 * FCS, or junk, at the end.
1226 * XXX - is it an FCS if "fcs_valid" is
1233 case WTAP_ENCAP_LAPB:
1234 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1236 * LAPB/X.25 and Frame Relay.
1238 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
1239 * is the direction flag. (Probably true for other
1240 * HDLC encapsulations as well.)
1242 pseudo_header->x25.flags =
1243 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
1246 case WTAP_ENCAP_PPP_WITH_PHDR:
1247 case WTAP_ENCAP_SDLC:
1248 pseudo_header->p2p.sent =
1249 (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
1252 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
1253 pseudo_header->atm.flags = 0;
1255 * XXX - is 0x08 an "OAM cell" flag?
1257 if (hdr->hdr_2_x.xxx[9] & 0x04)
1258 pseudo_header->atm.flags |= ATM_RAW_CELL;
1259 pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
1260 pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
1261 pseudo_header->atm.channel =
1262 (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
1263 pseudo_header->atm.cells = 0;
1265 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
1267 case 0x00: /* Unknown */
1269 * Infer the AAL, traffic type, and subtype.
1271 atm_guess_traffic_type(pd, len,
1275 case 0x50: /* AAL5 (including signalling) */
1276 pseudo_header->atm.aal = AAL_5;
1277 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
1280 case 0x0a: /* Signalling traffic */
1281 pseudo_header->atm.aal = AAL_SIGNALLING;
1282 pseudo_header->atm.type = TRAF_UNKNOWN;
1283 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1286 case 0x0b: /* ILMI */
1287 pseudo_header->atm.type = TRAF_ILMI;
1288 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1291 case 0x0c: /* LANE LE Control */
1292 pseudo_header->atm.type = TRAF_LANE;
1293 pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
1298 * 0x0d is *mostly* LANE 802.3,
1299 * but I've seen an LE Control frame
1302 pseudo_header->atm.type = TRAF_LANE;
1303 atm_guess_lane_type(pd, len,
1307 case 0x0f: /* LLC multiplexed */
1308 pseudo_header->atm.type = TRAF_LLCMX; /* XXX */
1309 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
1314 * XXX - discover the other types.
1316 pseudo_header->atm.type = TRAF_UNKNOWN;
1317 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1324 * 0x60 seen, and dissected by Sniffer
1325 * Pro as a raw cell.
1327 * XXX - discover what those types are.
1329 pseudo_header->atm.aal = AAL_UNKNOWN;
1330 pseudo_header->atm.type = TRAF_UNKNOWN;
1331 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1342 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1347 errno = WTAP_ERR_CANT_READ;
1348 bytes_read = file_read(data_ptr, 1, packet_size, fh);
1350 if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1351 *err = file_error(fh);
1353 *err = WTAP_ERR_SHORT_READ;
1360 netxray_close(wtap *wth)
1362 g_free(wth->capture.netxray);
1365 static const struct {
1366 int wtap_encap_value;
1368 } wtap_encap_1_1[] = {
1369 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1370 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1371 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1372 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1374 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1377 wtap_encap_to_netxray_1_1_encap(int encap)
1381 for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1382 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1383 return wtap_encap_1_1[i].ndis_value;
1389 /* Returns 0 if we could write the specified encapsulation type,
1390 an error indication otherwise. */
1391 int netxray_dump_can_write_encap_1_1(int encap)
1393 /* Per-packet encapsulations aren't supported. */
1394 if (encap == WTAP_ENCAP_PER_PACKET)
1395 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1397 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1398 return WTAP_ERR_UNSUPPORTED_ENCAP;
1403 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1405 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
1407 /* This is a NetXRay file. We can't fill in some fields in the header
1408 until all the packets have been written, so we can't write to a
1411 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1415 wdh->subtype_write = netxray_dump_1_1;
1416 wdh->subtype_close = netxray_dump_close_1_1;
1418 /* We can't fill in all the fields in the file header, as we
1419 haven't yet written any packets. As we'll have to rewrite
1420 the header when we've written out all the packets, we just
1421 skip over the header for now. */
1422 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1427 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1428 wdh->dump.netxray->first_frame = TRUE;
1429 wdh->dump.netxray->start.secs = 0;
1430 wdh->dump.netxray->start.nsecs = 0;
1431 wdh->dump.netxray->nframes = 0;
1436 /* Write a record for a packet to a dump file.
1437 Returns TRUE on success, FALSE on failure. */
1438 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1439 const struct wtap_pkthdr *phdr,
1440 const union wtap_pseudo_header *pseudo_header _U_,
1441 const guchar *pd, int *err)
1443 netxray_dump_t *netxray = wdh->dump.netxray;
1446 struct netxrayrec_1_x_hdr rec_hdr;
1449 /* NetXRay/Windows Sniffer files have a capture start date/time
1450 in the header, in a UNIX-style format, with one-second resolution,
1451 and a start time stamp with microsecond resolution that's just
1452 an arbitrary time stamp relative to some unknown time (boot
1453 time?), and have times relative to the start time stamp in
1454 the packet headers; pick the seconds value of the time stamp
1455 of the first packet as the UNIX-style start date/time, and make
1456 the high-resolution start time stamp 0, with the time stamp of
1457 packets being the delta between the stamp of the packet and
1458 the stamp of the first packet with the microseconds part 0. */
1459 if (netxray->first_frame) {
1460 netxray->first_frame = FALSE;
1461 netxray->start = phdr->ts;
1464 /* build the header for each packet */
1465 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1466 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1467 + ((guint64)phdr->ts.nsecs)/1000;
1468 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1469 rec_hdr.timelo = htolel(t32);
1470 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1471 rec_hdr.timehi = htolel(t32);
1472 rec_hdr.orig_len = htoles(phdr->len);
1473 rec_hdr.incl_len = htoles(phdr->caplen);
1475 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1476 if (nwritten != sizeof(rec_hdr)) {
1477 if (nwritten == 0 && ferror(wdh->fh))
1480 *err = WTAP_ERR_SHORT_WRITE;
1484 /* write the packet data */
1485 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1486 if (nwritten != phdr->caplen) {
1487 if (nwritten == 0 && ferror(wdh->fh))
1490 *err = WTAP_ERR_SHORT_WRITE;
1499 /* Finish writing to a dump file.
1500 Returns TRUE on success, FALSE on failure. */
1501 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1503 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1504 netxray_dump_t *netxray = wdh->dump.netxray;
1506 struct netxray_hdr file_hdr;
1509 filelen = ftell(wdh->fh);
1511 /* Go back to beginning */
1512 fseek(wdh->fh, 0, SEEK_SET);
1514 /* Rewrite the file header. */
1515 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1516 if (nwritten != sizeof netxray_magic) {
1518 if (nwritten == 0 && ferror(wdh->fh))
1521 *err = WTAP_ERR_SHORT_WRITE;
1526 /* "sniffer" version ? */
1527 memset(&file_hdr, '\0', sizeof file_hdr);
1528 memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1529 file_hdr.start_time = htolel(netxray->start.secs);
1530 file_hdr.nframes = htolel(netxray->nframes);
1531 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1532 file_hdr.end_offset = htolel(filelen);
1533 file_hdr.network = wtap_encap_to_netxray_1_1_encap(wdh->encap);
1534 file_hdr.timelo = htolel(0);
1535 file_hdr.timehi = htolel(0);
1537 memset(hdr_buf, '\0', sizeof hdr_buf);
1538 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1539 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1540 if (nwritten != sizeof hdr_buf) {
1542 if (nwritten == 0 && ferror(wdh->fh))
1545 *err = WTAP_ERR_SHORT_WRITE;
1553 static const struct {
1554 int wtap_encap_value;
1556 } wtap_encap_2_0[] = {
1557 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1558 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1559 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1560 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1561 { WTAP_ENCAP_PPP_WITH_PHDR, 3 }, /* -> NDIS WAN */
1562 { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 }, /* -> NDIS WAN */
1563 { WTAP_ENCAP_LAPB, 3 }, /* -> NDIS WAN */
1564 { WTAP_ENCAP_SDLC, 3 }, /* -> NDIS WAN */
1566 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1569 wtap_encap_to_netxray_2_0_encap(int encap)
1573 for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1574 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1575 return wtap_encap_2_0[i].ndis_value;
1581 /* Returns 0 if we could write the specified encapsulation type,
1582 an error indication otherwise. */
1583 int netxray_dump_can_write_encap_2_0(int encap)
1585 /* Per-packet encapsulations aren't supported. */
1586 if (encap == WTAP_ENCAP_PER_PACKET)
1587 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1589 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1590 return WTAP_ERR_UNSUPPORTED_ENCAP;
1595 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1597 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
1599 /* This is a NetXRay file. We can't fill in some fields in the header
1600 until all the packets have been written, so we can't write to a
1603 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1607 wdh->subtype_write = netxray_dump_2_0;
1608 wdh->subtype_close = netxray_dump_close_2_0;
1610 /* We can't fill in all the fields in the file header, as we
1611 haven't yet written any packets. As we'll have to rewrite
1612 the header when we've written out all the packets, we just
1613 skip over the header for now. */
1614 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1619 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1620 wdh->dump.netxray->first_frame = TRUE;
1621 wdh->dump.netxray->start.secs = 0;
1622 wdh->dump.netxray->start.nsecs = 0;
1623 wdh->dump.netxray->nframes = 0;
1628 /* Write a record for a packet to a dump file.
1629 Returns TRUE on success, FALSE on failure. */
1630 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1631 const struct wtap_pkthdr *phdr,
1632 const union wtap_pseudo_header *pseudo_header _U_,
1633 const guchar *pd, int *err)
1635 netxray_dump_t *netxray = wdh->dump.netxray;
1638 struct netxrayrec_2_x_hdr rec_hdr;
1641 /* NetXRay/Windows Sniffer files have a capture start date/time
1642 in the header, in a UNIX-style format, with one-second resolution,
1643 and a start time stamp with microsecond resolution that's just
1644 an arbitrary time stamp relative to some unknown time (boot
1645 time?), and have times relative to the start time stamp in
1646 the packet headers; pick the seconds value of the time stamp
1647 of the first packet as the UNIX-style start date/time, and make
1648 the high-resolution start time stamp 0, with the time stamp of
1649 packets being the delta between the stamp of the packet and
1650 the stamp of the first packet with the microseconds part 0. */
1651 if (netxray->first_frame) {
1652 netxray->first_frame = FALSE;
1653 netxray->start = phdr->ts;
1656 /* build the header for each packet */
1657 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1658 timestamp = ((guint64)phdr->ts.secs - (guint64)netxray->start.secs)*1000000
1659 + ((guint64)phdr->ts.nsecs)/1000;
1660 t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
1661 rec_hdr.timelo = htolel(t32);
1662 t32 = (guint32)(timestamp/G_GINT64_CONSTANT(4294967296));
1663 rec_hdr.timehi = htolel(t32);
1664 rec_hdr.orig_len = htoles(phdr->len);
1665 rec_hdr.incl_len = htoles(phdr->caplen);
1667 switch (phdr->pkt_encap) {
1669 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1670 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1671 rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1672 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1675 case WTAP_ENCAP_PPP_WITH_PHDR:
1676 case WTAP_ENCAP_SDLC:
1677 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1680 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1681 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1685 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1686 if (nwritten != sizeof(rec_hdr)) {
1687 if (nwritten == 0 && ferror(wdh->fh))
1690 *err = WTAP_ERR_SHORT_WRITE;
1694 /* write the packet data */
1695 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1696 if (nwritten != phdr->caplen) {
1697 if (nwritten == 0 && ferror(wdh->fh))
1700 *err = WTAP_ERR_SHORT_WRITE;
1709 /* Finish writing to a dump file.
1710 Returns TRUE on success, FALSE on failure. */
1711 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1713 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1714 netxray_dump_t *netxray = wdh->dump.netxray;
1716 struct netxray_hdr file_hdr;
1719 filelen = ftell(wdh->fh);
1721 /* Go back to beginning */
1722 fseek(wdh->fh, 0, SEEK_SET);
1724 /* Rewrite the file header. */
1725 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1726 if (nwritten != sizeof netxray_magic) {
1728 if (nwritten == 0 && ferror(wdh->fh))
1731 *err = WTAP_ERR_SHORT_WRITE;
1736 /* "sniffer" version ? */
1737 memset(&file_hdr, '\0', sizeof file_hdr);
1738 memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1739 file_hdr.start_time = htolel(netxray->start.secs);
1740 file_hdr.nframes = htolel(netxray->nframes);
1741 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1742 file_hdr.end_offset = htolel(filelen);
1743 file_hdr.network = wtap_encap_to_netxray_2_0_encap(wdh->encap);
1744 file_hdr.timelo = htolel(0);
1745 file_hdr.timehi = htolel(0);
1746 switch (wdh->encap) {
1748 case WTAP_ENCAP_PPP_WITH_PHDR:
1749 file_hdr.captype = WAN_CAPTYPE_PPP;
1752 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1753 file_hdr.captype = WAN_CAPTYPE_FRELAY;
1756 case WTAP_ENCAP_LAPB:
1757 file_hdr.captype = WAN_CAPTYPE_HDLC;
1758 file_hdr.wan_hdlc_subsub_captype = 0;
1761 case WTAP_ENCAP_SDLC:
1762 file_hdr.captype = WAN_CAPTYPE_SDLC;
1766 file_hdr.captype = CAPTYPE_NDIS;
1770 memset(hdr_buf, '\0', sizeof hdr_buf);
1771 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1772 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1773 if (nwritten != sizeof hdr_buf) {
1775 if (nwritten == 0 && ferror(wdh->fh))
1778 *err = WTAP_ERR_SHORT_WRITE;