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 char version[8]; /* version number */
52 guint32 start_time; /* UNIX time when capture started */
53 guint32 nframes; /* number of packets */
54 guint32 xxx; /* unknown */
55 guint32 start_offset; /* offset of first packet in capture */
56 guint32 end_offset; /* offset after last packet in capture */
57 guint32 xxy[3]; /* unknown */
58 guint8 network; /* datalink type */
59 guint8 xxz[3]; /* XXX - is this the upper 3 bytes of the datalink type? */
60 guint8 timeunit; /* encodes length of a tick */
61 guint8 xxa[3]; /* XXX - is this the upper 3 bytes of the time units? */
62 guint32 timelo; /* lower 32 bits of time stamp of capture start */
63 guint32 timehi; /* upper 32 bits of time stamp of capture start */
64 guint32 linespeed; /* speed of network, in bits/second */
65 guint8 xxb[64]; /* other stuff */
69 * Capture type, in xxb[20].
71 #define CAPTYPE_NDIS 0 /* Capture on network interface using NDIS */
72 #define CAPTYPE_BROUTER 1 /* Bridge/router captured with pod */
73 #define CAPTYPE_GIGPOD 2 /* gigabit Ethernet captured with pod */
74 #define CAPTYPE_PPP 3 /* PPP captured with pod */
75 #define CAPTYPE_FRELAY 4 /* Frame Relay captured with pod */
76 #define CAPTYPE_BROUTER2 5 /* Bridge/router captured with pod */
77 #define CAPTYPE_HDLC 6 /* HDLC (X.25, ISDN) captured with pod */
78 #define CAPTYPE_SDLC 7 /* SDLC captured with pod */
79 #define CAPTYPE_HDLC2 8 /* HDLC captured with pod */
80 #define CAPTYPE_BROUTER3 9 /* Bridge/router captured with pod */
81 #define CAPTYPE_SMDS 10 /* SMDS DXI */
82 #define CAPTYPE_BROUTER4 11 /* Bridge/router captured with pod */
83 #define CAPTYPE_BROUTER5 12 /* Bridge/router captured with pod */
86 * # of ticks that equal 1 second
88 * XXX - the third item was 1193180.0, presumably because somebody found
89 * it gave the right answer for some captures, but 3 times that, i.e.
90 * 3579540.0, appears to give the right answer for some other captures.
92 * Is there something else in the file header to indicate which of those
95 static double TpS[] = { 1e6, 1193000.0, 3579540.0 };
96 #define NUM_NETXRAY_TIMEUNITS (sizeof TpS / sizeof TpS[0])
98 /* Version number strings. */
99 static const char vers_1_0[] = {
100 '0', '0', '1', '.', '0', '0', '0', '\0'
103 static const char vers_1_1[] = {
104 '0', '0', '1', '.', '1', '0', '0', '\0'
107 static const char vers_2_000[] = {
108 '0', '0', '2', '.', '0', '0', '0', '\0'
111 static const char vers_2_001[] = {
112 '0', '0', '2', '.', '0', '0', '1', '\0'
115 static const char vers_2_002[] = {
116 '0', '0', '2', '.', '0', '0', '2', '\0'
119 /* Old NetXRay data record format - followed by frame data. */
120 struct old_netxrayrec_hdr {
121 guint32 timelo; /* lower 32 bits of time stamp */
122 guint32 timehi; /* upper 32 bits of time stamp */
123 guint16 len; /* packet length */
124 guint8 xxx[6]; /* unknown */
127 /* NetXRay format version 1.x data record format - followed by frame data. */
128 struct netxrayrec_1_x_hdr {
129 guint32 timelo; /* lower 32 bits of time stamp */
130 guint32 timehi; /* upper 32 bits of time stamp */
131 guint16 orig_len; /* packet length */
132 guint16 incl_len; /* capture length */
133 guint8 xxx[16]; /* unknown */
136 /* NetXRay format version 2.x data record format - followed by frame data. */
137 struct netxrayrec_2_x_hdr {
138 guint32 timelo; /* lower 32 bits of time stamp */
139 guint32 timehi; /* upper 32 bits of time stamp */
140 guint16 orig_len; /* packet length */
141 guint16 incl_len; /* capture length */
142 guint8 xxx[28]; /* various data */
146 * Union of the data record headers.
148 union netxrayrec_hdr {
149 struct old_netxrayrec_hdr old_hdr;
150 struct netxrayrec_1_x_hdr hdr_1_x;
151 struct netxrayrec_2_x_hdr hdr_2_x;
154 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info,
156 static gboolean netxray_seek_read(wtap *wth, long seek_off,
157 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
158 int *err, gchar **err_info);
159 static int netxray_read_rec_header(wtap *wth, FILE_T fh,
160 union netxrayrec_hdr *hdr, int *err);
161 static guint netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
162 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr);
163 static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr,
164 guint32 packet_size, int *err);
165 static void netxray_close(wtap *wth);
166 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
167 const struct wtap_pkthdr *phdr,
168 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
169 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
170 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
171 const struct wtap_pkthdr *phdr,
172 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
173 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err);
175 int netxray_open(wtap *wth, int *err, gchar **err_info)
178 char magic[sizeof netxray_magic];
180 struct netxray_hdr hdr;
183 int version_major, version_minor;
185 double start_timestamp;
186 static const int netxray_encap[] = {
189 WTAP_ENCAP_TOKEN_RING,
190 WTAP_ENCAP_FDDI_BITSWAPPED,
192 * XXX - PPP captures may look like Ethernet, perhaps
193 * because they're using NDIS to capture on the
194 * same machine and it provides simulated-Ethernet
195 * packets, but at least one ISDN capture uses the
196 * same network type value but isn't shaped like
199 WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */
200 WTAP_ENCAP_UNKNOWN, /* LocalTalk */
201 WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */
202 WTAP_ENCAP_UNKNOWN, /* ARCNET raw */
203 WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */
204 WTAP_ENCAP_ATM_PDUS_UNTRUNCATED, /* ATM */
205 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
206 /* Wireless WAN with radio information */
207 WTAP_ENCAP_UNKNOWN /* IrDA */
209 #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0])
213 /* Read in the string that should be at the start of a NetXRay
215 errno = WTAP_ERR_CANT_READ;
216 bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
217 if (bytes_read != sizeof magic) {
218 *err = file_error(wth->fh);
223 wth->data_offset += sizeof magic;
225 if (memcmp(magic, netxray_magic, sizeof magic) == 0) {
227 } else if (memcmp(magic, old_netxray_magic, sizeof magic) == 0) {
233 /* Read the rest of the header. */
234 errno = WTAP_ERR_CANT_READ;
235 bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
236 if (bytes_read != sizeof hdr) {
237 *err = file_error(wth->fh);
242 wth->data_offset += sizeof hdr;
247 file_type = WTAP_FILE_NETXRAY_OLD;
249 /* It appears that version 1.1 files (as produced by Windows
250 * Sniffer Pro 2.0.01) have the time stamp in microseconds,
251 * rather than the milliseconds version 1.0 files appear to
254 * It also appears that version 2.00x files have per-packet
255 * headers with some extra fields. */
256 if (memcmp(hdr.version, vers_1_0, sizeof vers_1_0) == 0) {
260 file_type = WTAP_FILE_NETXRAY_1_0;
261 } else if (memcmp(hdr.version, vers_1_1, sizeof vers_1_1) == 0) {
262 timeunit = 1000000.0;
265 file_type = WTAP_FILE_NETXRAY_1_1;
266 } else if (memcmp(hdr.version, vers_2_000, sizeof vers_2_000) == 0) {
269 file_type = WTAP_FILE_NETXRAY_2_00x;
270 } else if (memcmp(hdr.version, vers_2_001, sizeof vers_2_001) == 0) {
273 file_type = WTAP_FILE_NETXRAY_2_00x;
274 } else if (memcmp(hdr.version, vers_2_002, sizeof vers_2_002) == 0) {
277 file_type = WTAP_FILE_NETXRAY_2_00x;
279 *err = WTAP_ERR_UNSUPPORTED;
280 *err_info = g_strdup_printf("netxray: version \"%.8s\" unsupported", hdr.version);
285 switch (hdr.xxz[0]) {
289 * The byte after hdr.network is usually 0, in which case
290 * the hdr.network byte is an NDIS network type value - 1.
292 network_type = hdr.network + 1;
297 * However, in some Ethernet captures, it's 2, and the
298 * hdr.network byte is 1 rather than 0. We assume
299 * that if there's a byte after hdr.network with the value
300 * 2, the hdr.network byte is an NDIS network type, rather
301 * than an NDIS network type - 1.
303 network_type = hdr.network;
307 *err = WTAP_ERR_UNSUPPORTED;
308 *err_info = g_strdup_printf("netxray: the byte after the network type has the value %u, which I don't understand",
313 if (network_type >= NUM_NETXRAY_ENCAPS
314 || netxray_encap[network_type] == WTAP_ENCAP_UNKNOWN) {
315 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
316 *err_info = g_strdup_printf("netxray: network type %u (%u) unknown or unsupported",
317 network_type, hdr.xxz[0]);
322 * Figure out the time stamp units and start time stamp.
324 start_timestamp = (double)pletohl(&hdr.timelo)
325 + (double)pletohl(&hdr.timehi)*4294967296.0;
328 case WTAP_FILE_NETXRAY_OLD:
332 case WTAP_FILE_NETXRAY_1_0:
336 case WTAP_FILE_NETXRAY_1_1:
337 timeunit = 1000000.0;
340 case WTAP_FILE_NETXRAY_2_00x:
342 * It appears that, at least for Ethernet
343 * captures, if hdr.xxb[20] is 2, that indicates
344 * that it's a gigabit Ethernet capture, possibly
345 * from a special whizzo gigabit pod, and also
346 * indicates that the time stamps have some
347 * higher resolution than in other captures,
348 * possibly thanks to a high-resolution
351 * It also appears that the time units might differ
352 * for gigabit pod captures between version 002.001
355 if (network_type == 1 && hdr.xxb[20] == CAPTYPE_GIGPOD) {
356 if (version_minor == 1) {
358 * It appears that the time units for
359 * these captures are nanoseconds, unless
360 * hdr.timeunit is 2, in which case it's
361 * 1/31250000.0 of a second.
363 if (hdr.timeunit == 2)
364 timeunit = 31250000.0;
369 * These just seem to be 1000 times
370 * the regular time stamp units, unless
371 * hdr.timeunit is 2, in which case it's
372 * 1/1125000 of a second.
374 * In addition, the start timestamp
377 if (hdr.timeunit == 2)
378 timeunit = 1250000.0;
380 timeunit = TpS[hdr.timeunit]*1000.0;
381 start_timestamp = 0.0;
384 if (hdr.timeunit > NUM_NETXRAY_TIMEUNITS) {
385 *err = WTAP_ERR_UNSUPPORTED;
386 *err_info = g_strdup_printf("netxray: Unknown timeunit %u",
390 timeunit = TpS[hdr.timeunit];
395 g_assert_not_reached();
398 start_timestamp = start_timestamp/timeunit;
400 if (network_type == 4) {
402 * In version 0 and 1, we assume, for now, that all
403 * WAN captures have frames that look like Ethernet
404 * frames (as a result, presumably, of having passed
407 * In version 2, it looks as if there's stuff in the "xxb"
408 * words of the file header to specify what particular
409 * type of WAN capture we have.
411 if (version_major == 2) {
412 switch (hdr.xxb[20]) {
418 file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
425 file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
431 * Various HDLC flavors?
433 switch (hdr.xxb[28]) {
435 case 0: /* LAPB/X.25 */
436 file_encap = WTAP_ENCAP_LAPB;
442 file_encap = WTAP_ENCAP_ISDN;
443 isdn_type = hdr.xxb[28];
447 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
448 *err_info = g_strdup_printf("netxray: WAN HDLC capture subsubtype 0x%02x unknown or unsupported",
458 file_encap = WTAP_ENCAP_SDLC;
462 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
463 *err_info = g_strdup_printf("netxray: WAN capture subtype 0x%02x unknown or unsupported",
468 file_encap = WTAP_ENCAP_ETHERNET;
470 file_encap = netxray_encap[network_type];
472 /* This is a netxray file */
473 wth->file_type = file_type;
474 wth->capture.netxray = g_malloc(sizeof(netxray_t));
475 wth->subtype_read = netxray_read;
476 wth->subtype_seek_read = netxray_seek_read;
477 wth->subtype_close = netxray_close;
478 wth->file_encap = file_encap;
479 wth->snapshot_length = 0; /* not available in header */
480 wth->capture.netxray->start_time = pletohl(&hdr.start_time);
481 wth->capture.netxray->timeunit = timeunit;
482 wth->capture.netxray->start_timestamp = start_timestamp;
483 wth->capture.netxray->version_major = version_major;
486 * If frames have an extra 4 bytes of stuff at the end, is
487 * it an FCS, or just junk?
489 wth->capture.netxray->fcs_valid = FALSE;
490 switch (file_encap) {
492 case WTAP_ENCAP_ETHERNET:
493 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
494 case WTAP_ENCAP_ISDN:
496 * It appears that, in at least some version 2 Ethernet
497 * captures, for frames that have 0xff in hdr_2_x.xxx[2]
498 * and hdr_2_x.xxx[3] in the per-packet header:
500 * if, in the file header, hdr.xxb[13] is 0x34 and
501 * hdr.xxb[14] is 0x12, the frames have an FCS at
504 * otherwise, they have 4 bytes of junk at the end.
506 * For now, we assume that to be true for 802.11 captures
507 * as well; it appears to be the case for at least one
510 * For ISDN captures, it appears, at least in some
511 * captures, to be similar, although I haven't yet
512 * checked whether it's a valid FCS.
514 * XXX - should we do this for all encapsulation types?
516 * XXX - is that actually a 2-byte little-endian 0x1234?
517 * What does that field signify?
519 if (version_major == 2) {
520 if (hdr.xxb[13] == 0x34 && hdr.xxb[14] == 0x12)
521 wth->capture.netxray->fcs_valid = TRUE;
527 * Remember the ISDN type, as we need it to interpret the
528 * channel number in ISDN captures.
530 wth->capture.netxray->isdn_type = isdn_type;
532 /* Remember the offset after the last packet in the capture (which
533 * isn't necessarily the last packet in the file), as it appears
534 * there's sometimes crud after it. */
535 wth->capture.netxray->wrapped = FALSE;
536 wth->capture.netxray->end_offset = pletohl(&hdr.end_offset);
538 /* Seek to the beginning of the data records. */
539 if (file_seek(wth->fh, pletohl(&hdr.start_offset), SEEK_SET, err) == -1) {
540 g_free(wth->capture.netxray);
543 wth->data_offset = pletohl(&hdr.start_offset);
548 /* Read the next packet */
549 static gboolean netxray_read(wtap *wth, int *err, gchar **err_info _U_,
553 union netxrayrec_hdr hdr;
560 /* Have we reached the end of the packet data? */
561 if (wth->data_offset == wth->capture.netxray->end_offset) {
563 *err = 0; /* it's just an EOF, not an error */
566 /* Read record header. */
567 hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err);
574 * Error of some sort; give up.
579 /* We're at EOF. Wrap? */
580 if (!wth->capture.netxray->wrapped) {
581 /* Yes. Remember that we did. */
582 wth->capture.netxray->wrapped = TRUE;
583 if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE,
584 SEEK_SET, err) == -1)
586 wth->data_offset = CAPTUREFILE_HEADER_SIZE;
590 /* We've already wrapped - don't wrap again. */
595 * Return the offset of the record header, so we can reread it
596 * if we go back to this frame.
598 *data_offset = wth->data_offset;
599 wth->data_offset += hdr_size;
602 * Read the packet data.
604 if (wth->capture.netxray->version_major == 0)
605 packet_size = pletohs(&hdr.old_hdr.len);
607 packet_size = pletohs(&hdr.hdr_1_x.incl_len);
608 buffer_assure_space(wth->frame_buffer, packet_size);
609 pd = buffer_start_ptr(wth->frame_buffer);
610 if (!netxray_read_rec_data(wth->fh, pd, packet_size, err))
612 wth->data_offset += packet_size;
615 * Set the pseudo-header.
617 padding = netxray_set_pseudo_header(wth, pd, packet_size,
618 &wth->pseudo_header, &hdr);
620 if (wth->capture.netxray->version_major == 0) {
621 t = (double)pletohl(&hdr.old_hdr.timelo)
622 + (double)pletohl(&hdr.old_hdr.timehi)*4294967296.0;
623 t /= wth->capture.netxray->timeunit;
624 t -= wth->capture.netxray->start_timestamp;
625 wth->phdr.ts.tv_sec = wth->capture.netxray->start_time + (long)t;
626 wth->phdr.ts.tv_usec = (unsigned long)((t-(double)(unsigned long)(t))
629 * We subtract the padding from the packet size, so our caller
632 wth->phdr.caplen = packet_size - padding;
633 wth->phdr.len = wth->phdr.caplen;
635 t = (double)pletohl(&hdr.hdr_1_x.timelo)
636 + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0;
637 t /= wth->capture.netxray->timeunit;
638 t -= wth->capture.netxray->start_timestamp;
639 wth->phdr.ts.tv_sec = wth->capture.netxray->start_time + (long)t;
640 wth->phdr.ts.tv_usec = (unsigned long)((t-(double)(unsigned long)(t))
643 * We subtract the padding from the packet size, so our caller
646 wth->phdr.caplen = packet_size - padding;
647 wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len) - padding;
654 netxray_seek_read(wtap *wth, long seek_off,
655 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
656 int *err, gchar **err_info _U_)
658 union netxrayrec_hdr hdr;
661 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
664 if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) {
667 * EOF - we report that as a short read, as
668 * we've read this once and know that it
671 *err = WTAP_ERR_SHORT_READ;
677 * Read the packet data.
679 ret = netxray_read_rec_data(wth->random_fh, pd, length, err);
684 * Set the pseudo-header.
686 netxray_set_pseudo_header(wth, pd, length, pseudo_header, &hdr);
691 netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr,
697 /* Read record header. */
698 switch (wth->capture.netxray->version_major) {
701 hdr_size = sizeof (struct old_netxrayrec_hdr);
705 hdr_size = sizeof (struct netxrayrec_1_x_hdr);
709 hdr_size = sizeof (struct netxrayrec_2_x_hdr);
712 errno = WTAP_ERR_CANT_READ;
713 bytes_read = file_read(hdr, 1, hdr_size, fh);
714 if (bytes_read != hdr_size) {
715 *err = file_error(wth->fh);
718 if (bytes_read != 0) {
719 *err = WTAP_ERR_SHORT_READ;
724 * We're at EOF. "*err" is 0; we return FALSE - that
725 * combination tells our caller we're at EOF.
733 netxray_set_pseudo_header(wtap *wth, const guint8 *pd, int len,
734 union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr)
739 * If this is Ethernet, 802.11, ISDN, X.25, or ATM, set the
742 switch (wth->capture.netxray->version_major) {
745 switch (wth->file_encap) {
747 case WTAP_ENCAP_ETHERNET:
749 * XXX - if hdr->hdr_1_x.xxx[15] is 1
750 * the frame appears not to have any extra
751 * stuff at the end, but if it's 0,
752 * there appears to be 4 bytes of stuff
753 * at the end, but it's not an FCS.
755 * Or is that just the low-order bit?
757 * For now, we just say "no FCS".
759 pseudo_header->eth.fcs_len = 0;
765 switch (wth->file_encap) {
767 case WTAP_ENCAP_ETHERNET:
769 * It appears, at least with version 2 captures,
770 * that we have 4 bytes of stuff (which might be
771 * a valid FCS or might be junk) at the end of
772 * the packet if hdr->hdr_2_x.xxx[2] and
773 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
776 * It also appears that if the low-order bit of
777 * hdr->hdr_2_x.xxx[8] is set, the packet has a
780 if (hdr->hdr_2_x.xxx[2] == 0xff &&
781 hdr->hdr_2_x.xxx[3] == 0xff) {
783 * We have 4 bytes of stuff at the
784 * end of the frame - FCS, or junk?
786 if (wth->capture.netxray->fcs_valid) {
790 pseudo_header->eth.fcs_len = 4;
798 pseudo_header->eth.fcs_len = 0;
801 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
803 * It appears, in one 802.11 capture, that
804 * we have 4 bytes of junk at the ends of
805 * frames in which hdr->hdr_2_x.xxx[2] and
806 * hdr->hdr_2_x.xxx[3] are 0xff; we assume
807 * for now that it works like Ethernet.
809 if (hdr->hdr_2_x.xxx[2] == 0xff &&
810 hdr->hdr_2_x.xxx[3] == 0xff) {
812 * We have 4 bytes of stuff at the
813 * end of the frame - FCS, or junk?
815 if (wth->capture.netxray->fcs_valid) {
819 pseudo_header->ieee_802_11.fcs_len = 4;
827 pseudo_header->ieee_802_11.fcs_len = 0;
829 pseudo_header->ieee_802_11.channel =
830 hdr->hdr_2_x.xxx[12];
831 pseudo_header->ieee_802_11.data_rate =
832 hdr->hdr_2_x.xxx[13];
833 pseudo_header->ieee_802_11.signal_level =
834 hdr->hdr_2_x.xxx[14];
837 case WTAP_ENCAP_ISDN:
841 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
842 * is the direction flag.
844 * The bottom 5 bits of byte 13 of "hdr.hdr_2_x.xxx"
845 * are the channel number, but some mapping is
846 * required for PRI. (Is it really just the time
849 pseudo_header->isdn.uton =
850 (hdr->hdr_2_x.xxx[12] & 0x01);
851 pseudo_header->isdn.channel =
852 hdr->hdr_2_x.xxx[13] & 0x1F;
853 switch (wth->capture.netxray->isdn_type) {
857 * E1 PRI. Channel numbers 0 and 16
858 * are the D channel; channel numbers 1
859 * through 15 are B1 through B15; channel
860 * numbers 17 through 31 are B16 through
863 if (pseudo_header->isdn.channel == 16)
864 pseudo_header->isdn.channel = 0;
865 else if (pseudo_header->isdn.channel > 16)
866 pseudo_header->isdn.channel -= 1;
871 * T1 PRI. Channel numbers 0 and 24
872 * are the D channel; channel numbers 1
873 * through 23 are B1 through B23.
875 if (pseudo_header->isdn.channel == 24)
876 pseudo_header->isdn.channel = 0;
877 else if (pseudo_header->isdn.channel > 24)
878 pseudo_header->isdn.channel -= 1;
883 * It appears, at least with version 2 captures,
884 * that we have 4 bytes of stuff (which might be
885 * a valid FCS or might be junk) at the end of
886 * the packet if hdr->hdr_2_x.xxx[2] and
887 * hdr->hdr_2_x.xxx[3] are 0xff, and we don't if
890 * XXX - does the low-order bit of hdr->hdr_2_x.xxx[8]
891 * indicate a bad FCS, as is the case with
894 if (hdr->hdr_2_x.xxx[2] == 0xff &&
895 hdr->hdr_2_x.xxx[3] == 0xff) {
897 * FCS, or junk, at the end.
898 * XXX - is it an FCS if "fcs_valid" is
905 case WTAP_ENCAP_LAPB:
906 case WTAP_ENCAP_FRELAY_WITH_PHDR:
908 * LAPB/X.25 and Frame Relay.
910 * The bottommost bit of byte 12 of "hdr.hdr_2_x.xxx"
911 * is the direction flag. (Probably true for other
912 * HDLC encapsulations as well.)
914 pseudo_header->x25.flags =
915 (hdr->hdr_2_x.xxx[12] & 0x01) ? 0x00 : FROM_DCE;
918 case WTAP_ENCAP_PPP_WITH_PHDR:
919 case WTAP_ENCAP_SDLC:
920 pseudo_header->p2p.sent =
921 (hdr->hdr_2_x.xxx[12] & 0x01) ? TRUE : FALSE;
924 case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
925 pseudo_header->atm.flags = 0;
927 * XXX - is 0x08 an "OAM cell" flag?
929 if (hdr->hdr_2_x.xxx[9] & 0x04)
930 pseudo_header->atm.flags |= ATM_RAW_CELL;
931 pseudo_header->atm.vpi = hdr->hdr_2_x.xxx[11];
932 pseudo_header->atm.vci = pletohs(&hdr->hdr_2_x.xxx[12]);
933 pseudo_header->atm.channel =
934 (hdr->hdr_2_x.xxx[15] & 0x10)? 1 : 0;
935 pseudo_header->atm.cells = 0;
937 switch (hdr->hdr_2_x.xxx[0] & 0xF0) {
939 case 0x00: /* Unknown */
941 * Infer the AAL, traffic type, and subtype.
943 atm_guess_traffic_type(pd, len,
947 case 0x50: /* AAL5 (including signalling) */
948 pseudo_header->atm.aal = AAL_5;
949 switch (hdr->hdr_2_x.xxx[0] & 0x0F) {
952 case 0x0a: /* Signalling traffic */
953 pseudo_header->atm.aal = AAL_SIGNALLING;
954 pseudo_header->atm.type = TRAF_UNKNOWN;
955 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
958 case 0x0b: /* ILMI */
959 pseudo_header->atm.type = TRAF_ILMI;
960 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
963 case 0x0c: /* LANE LE Control */
964 pseudo_header->atm.type = TRAF_LANE;
965 pseudo_header->atm.subtype = TRAF_ST_LANE_LE_CTRL;
970 * 0x0d is *mostly* LANE 802.3,
971 * but I've seen an LE Control frame
974 pseudo_header->atm.type = TRAF_LANE;
975 atm_guess_lane_type(pd, len,
979 case 0x0f: /* LLC multiplexed */
980 pseudo_header->atm.type = TRAF_LLCMX; /* XXX */
981 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; /* XXX */
986 * XXX - discover the other types.
988 pseudo_header->atm.type = TRAF_UNKNOWN;
989 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
996 * 0x60 seen, and dissected by Sniffer
999 * XXX - discover what those types are.
1001 pseudo_header->atm.aal = AAL_UNKNOWN;
1002 pseudo_header->atm.type = TRAF_UNKNOWN;
1003 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1014 netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size,
1019 errno = WTAP_ERR_CANT_READ;
1020 bytes_read = file_read(data_ptr, 1, packet_size, fh);
1022 if (bytes_read <= 0 || (guint32)bytes_read != packet_size) {
1023 *err = file_error(fh);
1025 *err = WTAP_ERR_SHORT_READ;
1032 netxray_close(wtap *wth)
1034 g_free(wth->capture.netxray);
1037 static const struct {
1038 int wtap_encap_value;
1040 } wtap_encap_1_1[] = {
1041 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1042 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1043 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1044 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1046 #define NUM_WTAP_ENCAPS_1_1 (sizeof wtap_encap_1_1 / sizeof wtap_encap_1_1[0])
1049 wtap_encap_to_netxray_1_1_encap(int encap)
1053 for (i = 0; i < NUM_WTAP_ENCAPS_1_1; i++) {
1054 if (encap == wtap_encap_1_1[i].wtap_encap_value)
1055 return wtap_encap_1_1[i].ndis_value;
1061 /* Returns 0 if we could write the specified encapsulation type,
1062 an error indication otherwise. */
1063 int netxray_dump_can_write_encap_1_1(int encap)
1065 /* Per-packet encapsulations aren't supported. */
1066 if (encap == WTAP_ENCAP_PER_PACKET)
1067 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1069 if (wtap_encap_to_netxray_1_1_encap(encap) == -1)
1070 return WTAP_ERR_UNSUPPORTED_ENCAP;
1075 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1077 gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
1079 /* This is a NetXRay file. We can't fill in some fields in the header
1080 until all the packets have been written, so we can't write to a
1083 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1087 wdh->subtype_write = netxray_dump_1_1;
1088 wdh->subtype_close = netxray_dump_close_1_1;
1090 /* We can't fill in all the fields in the file header, as we
1091 haven't yet written any packets. As we'll have to rewrite
1092 the header when we've written out all the packets, we just
1093 skip over the header for now. */
1094 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1099 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1100 wdh->dump.netxray->first_frame = TRUE;
1101 wdh->dump.netxray->start.tv_sec = 0;
1102 wdh->dump.netxray->start.tv_usec = 0;
1103 wdh->dump.netxray->nframes = 0;
1108 /* Write a record for a packet to a dump file.
1109 Returns TRUE on success, FALSE on failure. */
1110 static gboolean netxray_dump_1_1(wtap_dumper *wdh,
1111 const struct wtap_pkthdr *phdr,
1112 const union wtap_pseudo_header *pseudo_header _U_,
1113 const guchar *pd, int *err)
1115 netxray_dump_t *netxray = wdh->dump.netxray;
1117 struct netxrayrec_1_x_hdr rec_hdr;
1120 /* NetXRay/Windows Sniffer files have a capture start date/time
1121 in the header, in a UNIX-style format, with one-second resolution,
1122 and a start time stamp with microsecond resolution that's just
1123 an arbitrary time stamp relative to some unknown time (boot
1124 time?), and have times relative to the start time stamp in
1125 the packet headers; pick the seconds value of the time stamp
1126 of the first packet as the UNIX-style start date/time, and make
1127 the high-resolution start time stamp 0, with the time stamp of
1128 packets being the delta between the stamp of the packet and
1129 the stamp of the first packet with the microseconds part 0. */
1130 if (netxray->first_frame) {
1131 netxray->first_frame = FALSE;
1132 netxray->start = phdr->ts;
1135 /* build the header for each packet */
1136 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1137 timestamp = (phdr->ts.tv_sec - netxray->start.tv_sec)*1000000 +
1139 rec_hdr.timelo = htolel(timestamp);
1140 rec_hdr.timehi = htolel(0);
1141 rec_hdr.orig_len = htoles(phdr->len);
1142 rec_hdr.incl_len = htoles(phdr->caplen);
1144 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1145 if (nwritten != sizeof(rec_hdr)) {
1146 if (nwritten == 0 && ferror(wdh->fh))
1149 *err = WTAP_ERR_SHORT_WRITE;
1153 /* write the packet data */
1154 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1155 if (nwritten != phdr->caplen) {
1156 if (nwritten == 0 && ferror(wdh->fh))
1159 *err = WTAP_ERR_SHORT_WRITE;
1168 /* Finish writing to a dump file.
1169 Returns TRUE on success, FALSE on failure. */
1170 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
1172 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1173 netxray_dump_t *netxray = wdh->dump.netxray;
1175 struct netxray_hdr file_hdr;
1178 filelen = ftell(wdh->fh);
1180 /* Go back to beginning */
1181 fseek(wdh->fh, 0, SEEK_SET);
1183 /* Rewrite the file header. */
1184 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1185 if (nwritten != sizeof netxray_magic) {
1187 if (nwritten == 0 && ferror(wdh->fh))
1190 *err = WTAP_ERR_SHORT_WRITE;
1195 /* "sniffer" version ? */
1196 memset(&file_hdr, '\0', sizeof file_hdr);
1197 memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
1198 file_hdr.start_time = htolel(netxray->start.tv_sec);
1199 file_hdr.nframes = htolel(netxray->nframes);
1200 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1201 file_hdr.end_offset = htolel(filelen);
1202 file_hdr.network = (guint8) htoles(wtap_encap_to_netxray_1_1_encap(wdh->encap));
1203 file_hdr.timelo = htolel(0);
1204 file_hdr.timehi = htolel(0);
1206 memset(hdr_buf, '\0', sizeof hdr_buf);
1207 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1208 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1209 if (nwritten != sizeof hdr_buf) {
1211 if (nwritten == 0 && ferror(wdh->fh))
1214 *err = WTAP_ERR_SHORT_WRITE;
1222 static const struct {
1223 int wtap_encap_value;
1225 } wtap_encap_2_0[] = {
1226 { WTAP_ENCAP_ETHERNET, 0 }, /* -> NDIS Ethernet */
1227 { WTAP_ENCAP_TOKEN_RING, 1 }, /* -> NDIS Token Ring */
1228 { WTAP_ENCAP_FDDI, 2 }, /* -> NDIS FDDI */
1229 { WTAP_ENCAP_FDDI_BITSWAPPED, 2 }, /* -> NDIS FDDI */
1230 { WTAP_ENCAP_PPP_WITH_PHDR, 3 }, /* -> NDIS WAN */
1231 { WTAP_ENCAP_FRELAY_WITH_PHDR, 3 }, /* -> NDIS WAN */
1232 { WTAP_ENCAP_LAPB, 3 }, /* -> NDIS WAN */
1233 { WTAP_ENCAP_SDLC, 3 }, /* -> NDIS WAN */
1235 #define NUM_WTAP_ENCAPS_2_0 (sizeof wtap_encap_2_0 / sizeof wtap_encap_2_0[0])
1238 wtap_encap_to_netxray_2_0_encap(int encap)
1242 for (i = 0; i < NUM_WTAP_ENCAPS_2_0; i++) {
1243 if (encap == wtap_encap_2_0[i].wtap_encap_value)
1244 return wtap_encap_2_0[i].ndis_value;
1250 /* Returns 0 if we could write the specified encapsulation type,
1251 an error indication otherwise. */
1252 int netxray_dump_can_write_encap_2_0(int encap)
1254 /* Per-packet encapsulations aren't supported. */
1255 if (encap == WTAP_ENCAP_PER_PACKET)
1256 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1258 if (wtap_encap_to_netxray_2_0_encap(encap) == -1)
1259 return WTAP_ERR_UNSUPPORTED_ENCAP;
1264 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1266 gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
1268 /* This is a NetXRay file. We can't fill in some fields in the header
1269 until all the packets have been written, so we can't write to a
1272 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1276 wdh->subtype_write = netxray_dump_2_0;
1277 wdh->subtype_close = netxray_dump_close_2_0;
1279 /* We can't fill in all the fields in the file header, as we
1280 haven't yet written any packets. As we'll have to rewrite
1281 the header when we've written out all the packets, we just
1282 skip over the header for now. */
1283 if (fseek(wdh->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) {
1288 wdh->dump.netxray = g_malloc(sizeof(netxray_dump_t));
1289 wdh->dump.netxray->first_frame = TRUE;
1290 wdh->dump.netxray->start.tv_sec = 0;
1291 wdh->dump.netxray->start.tv_usec = 0;
1292 wdh->dump.netxray->nframes = 0;
1297 /* Write a record for a packet to a dump file.
1298 Returns TRUE on success, FALSE on failure. */
1299 static gboolean netxray_dump_2_0(wtap_dumper *wdh,
1300 const struct wtap_pkthdr *phdr,
1301 const union wtap_pseudo_header *pseudo_header _U_,
1302 const guchar *pd, int *err)
1304 netxray_dump_t *netxray = wdh->dump.netxray;
1306 struct netxrayrec_2_x_hdr rec_hdr;
1309 /* NetXRay/Windows Sniffer files have a capture start date/time
1310 in the header, in a UNIX-style format, with one-second resolution,
1311 and a start time stamp with microsecond resolution that's just
1312 an arbitrary time stamp relative to some unknown time (boot
1313 time?), and have times relative to the start time stamp in
1314 the packet headers; pick the seconds value of the time stamp
1315 of the first packet as the UNIX-style start date/time, and make
1316 the high-resolution start time stamp 0, with the time stamp of
1317 packets being the delta between the stamp of the packet and
1318 the stamp of the first packet with the microseconds part 0. */
1319 if (netxray->first_frame) {
1320 netxray->first_frame = FALSE;
1321 netxray->start = phdr->ts;
1324 /* build the header for each packet */
1325 memset(&rec_hdr, '\0', sizeof(rec_hdr));
1326 timestamp = (phdr->ts.tv_sec - netxray->start.tv_sec)*1000000 +
1328 rec_hdr.timelo = htolel(timestamp);
1329 rec_hdr.timehi = htolel(0);
1330 rec_hdr.orig_len = htoles(phdr->len);
1331 rec_hdr.incl_len = htoles(phdr->caplen);
1333 switch (phdr->pkt_encap) {
1335 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
1336 rec_hdr.xxx[12] = pseudo_header->ieee_802_11.channel;
1337 rec_hdr.xxx[13] = pseudo_header->ieee_802_11.data_rate;
1338 rec_hdr.xxx[14] = pseudo_header->ieee_802_11.signal_level;
1341 case WTAP_ENCAP_PPP_WITH_PHDR:
1342 case WTAP_ENCAP_SDLC:
1343 rec_hdr.xxx[12] |= pseudo_header->p2p.sent ? 0x01 : 0x00;
1346 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1347 rec_hdr.xxx[12] |= (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : 0x01;
1351 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
1352 if (nwritten != sizeof(rec_hdr)) {
1353 if (nwritten == 0 && ferror(wdh->fh))
1356 *err = WTAP_ERR_SHORT_WRITE;
1360 /* write the packet data */
1361 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1362 if (nwritten != phdr->caplen) {
1363 if (nwritten == 0 && ferror(wdh->fh))
1366 *err = WTAP_ERR_SHORT_WRITE;
1375 /* Finish writing to a dump file.
1376 Returns TRUE on success, FALSE on failure. */
1377 static gboolean netxray_dump_close_2_0(wtap_dumper *wdh, int *err)
1379 char hdr_buf[CAPTUREFILE_HEADER_SIZE - sizeof(netxray_magic)];
1380 netxray_dump_t *netxray = wdh->dump.netxray;
1382 struct netxray_hdr file_hdr;
1385 filelen = ftell(wdh->fh);
1387 /* Go back to beginning */
1388 fseek(wdh->fh, 0, SEEK_SET);
1390 /* Rewrite the file header. */
1391 nwritten = fwrite(netxray_magic, 1, sizeof netxray_magic, wdh->fh);
1392 if (nwritten != sizeof netxray_magic) {
1394 if (nwritten == 0 && ferror(wdh->fh))
1397 *err = WTAP_ERR_SHORT_WRITE;
1402 /* "sniffer" version ? */
1403 memset(&file_hdr, '\0', sizeof file_hdr);
1404 memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
1405 file_hdr.start_time = htolel(netxray->start.tv_sec);
1406 file_hdr.nframes = htolel(netxray->nframes);
1407 file_hdr.start_offset = htolel(CAPTUREFILE_HEADER_SIZE);
1408 file_hdr.end_offset = htolel(filelen);
1409 file_hdr.network = (guint8) htoles(wtap_encap_to_netxray_2_0_encap(wdh->encap));
1410 file_hdr.timelo = htolel(0);
1411 file_hdr.timehi = htolel(0);
1412 switch (wdh->encap) {
1414 case WTAP_ENCAP_PPP_WITH_PHDR:
1415 file_hdr.xxb[20] = CAPTYPE_PPP;
1418 case WTAP_ENCAP_FRELAY_WITH_PHDR:
1419 file_hdr.xxb[20] = CAPTYPE_FRELAY;
1422 case WTAP_ENCAP_LAPB:
1423 file_hdr.xxb[20] = CAPTYPE_HDLC;
1424 file_hdr.xxb[28] = 0;
1427 case WTAP_ENCAP_SDLC:
1428 file_hdr.xxb[20] = CAPTYPE_SDLC;
1432 file_hdr.xxb[20] = CAPTYPE_NDIS;
1436 memset(hdr_buf, '\0', sizeof hdr_buf);
1437 memcpy(hdr_buf, &file_hdr, sizeof(file_hdr));
1438 nwritten = fwrite(hdr_buf, 1, sizeof hdr_buf, wdh->fh);
1439 if (nwritten != sizeof hdr_buf) {
1441 if (nwritten == 0 && ferror(wdh->fh))
1444 *err = WTAP_ERR_SHORT_WRITE;