[Trivial] Constify a few things
[metze/wireshark/wip.git] / wiretap / ngsniffer.c
1 /* ngsniffer.c
2  *
3  * $Id$
4  *
5  * Wiretap Library
6  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
7  *
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.
12  *
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.
17  *
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.
21  */
22
23 /* The code in ngsniffer.c that decodes the time fields for each packet in the
24  * Sniffer trace originally came from code from TCPVIEW:
25  *
26  * TCPVIEW
27  *
28  * Author:      Martin Hunt
29  *              Networks and Distributed Computing
30  *              Computing & Communications
31  *              University of Washington
32  *              Administration Building, AG-44
33  *              Seattle, WA  98195
34  *              Internet: martinh@cac.washington.edu
35  *
36  *
37  * Copyright 1992 by the University of Washington
38  *
39  * Permission to use, copy, modify, and distribute this software and its
40  * documentation for any purpose and without fee is hereby granted, provided
41  * that the above copyright notice appears in all copies and that both the
42  * above copyright notice and this permission notice appear in supporting
43  * documentation, and that the name of the University of Washington not be
44  * used in advertising or publicity pertaining to distribution of the software
45  * without specific, written prior permission.  This software is made
46  * available "as is", and
47  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
48  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
49  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
50  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
51  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
52  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
53  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
54  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55  *
56  */
57 #ifdef HAVE_CONFIG_H
58 #include "config.h"
59 #endif
60
61 #include <stdlib.h>
62 #include <errno.h>
63 #include <string.h>
64 #include "wtap-int.h"
65 #include "file_wrappers.h"
66 #include "buffer.h"
67 #include "atm.h"
68 #include "ngsniffer.h"
69
70 /* Magic number in Sniffer files. */
71 static const char ngsniffer_magic[] = {
72         'T', 'R', 'S', 'N', 'I', 'F', 'F', ' ', 'd', 'a', 't', 'a',
73         ' ', ' ', ' ', ' ', 0x1a
74 };
75
76 /*
77  * Sniffer record types.
78  */
79 #define REC_VERS        1       /* Version record (f_vers) */
80 #define REC_FRAME2      4       /* Frame data (f_frame2) */
81 #define REC_FRAME4      8       /* Frame data (f_frame4) */
82 #define REC_FRAME6      12      /* Frame data (f_frame6) (see below) */
83 #define REC_EOF         3       /* End-of-file record (no data follows) */
84 /*
85  * and now for some unknown header types
86  */
87 #define REC_HEADER1     6       /* Header containing serial numbers? */
88 #define REC_HEADER2     7       /* Header containing ??? */
89 #define REC_V2DESC      8       /* In version 2 sniffer traces contains
90                                  * infos about this capturing session.
91                                  * Collides with REC_FRAME4 */
92 #define REC_HEADER3     13      /* Retransmission counts? */
93 #define REC_HEADER4     14      /* ? */
94 #define REC_HEADER5     15      /* ? */
95 #define REC_HEADER6     16      /* More broadcast/retransmission counts? */
96 #define REC_HEADER7     17      /* ? */
97
98
99 /*
100  * Sniffer version record format.
101  */
102 struct vers_rec {
103         gint16  maj_vers;       /* major version number */
104         gint16  min_vers;       /* minor version number */
105         gint16  time;           /* DOS-format time */
106         gint16  date;           /* DOS-format date */
107         gint8   type;           /* what type of records follow */
108         guint8  network;        /* network type */
109         gint8   format;         /* format version */
110         guint8  timeunit;       /* timestamp units */
111         gint8   cmprs_vers;     /* compression version */
112         gint8   cmprs_level;    /* compression level */
113         gint16  rsvd[2];        /* reserved */
114 };
115
116 /*
117  * Network types.
118  */
119 #define NETWORK_TRING           0       /* Token ring */
120 #define NETWORK_ENET            1       /* Ethernet */
121 #define NETWORK_ARCNET          2       /* ARCNET */
122 #define NETWORK_STARLAN         3       /* StarLAN */
123 #define NETWORK_PCNW            4       /* PC Network broadband (Sytek?) */
124 #define NETWORK_LOCALTALK       5       /* LocalTalk */
125 #define NETWORK_SYNCHRO         7       /* Internetwork analyzer (synchronous) */
126 #define NETWORK_ASYNC           8       /* Internetwork analyzer (asynchronous) */
127 #define NETWORK_FDDI            9       /* FDDI */
128 #define NETWORK_ATM             10      /* ATM */
129
130 /*
131  * Sniffer type 2 data record format - followed by frame data.
132  *
133  * The Expert Sniffer Network Analyzer Operations manual, Release 5.50,
134  * documents some of the values used in "fs" and "flags".  "flags" don't
135  * look as if they'd be of much interest to us, as those are internal
136  * flags for state used by the Sniffer, but "fs" gives various status
137  * bits including error indications *and*:
138  *
139  *      ISDN channel information for ISDN;
140  *
141  *      PPP vs. SLIP information for Async.
142  *
143  * In that section it also refers to "FDDI analyzers using the NPI PCI
144  * FDDI adapter" and "FDDI analyzers using the NPI ISA FDDI adapter",
145  * referring to the first as "F1SNIFF" and the second as "FDSNIFF";
146  * those sound as if they *could* be replacements for "TRSNIFF" in
147  * the file header, but that manual says, earlier, that the header
148  * starts with "TRSNIFF data, no matter where the frames were
149  * collected".
150  *
151  * It also says that a type 2 record has an 8-bit "time_high"
152  * and an 8-bit "time_day" field; the code here used to have a
153  * 16-bit "time_high" value, but that gave wrong time stamps on at
154  * least some captures.  Did some older manual have it as a 16-bit
155  * "tstamp_high", so that perhaps it depends on the version number
156  * in the file, or is it "tstamp_high" plus "tstamp_day" in all
157  * versions?  (I forget whether this came purely from tcpview, or if
158  * I saw any of it in an NAI document.)
159  *
160  * We interpret them as unsigned, as interpreting them as signed
161  * would appear to allow time stamps that precede the start of the
162  * capture.  The description of the record format shows them as
163  * "char", but the section "How the Analyzer Stores Time" shows a
164  * time stamp structure with those fields being "unsigned char".
165  *
166  * In addition, the description of the record format has the comment
167  * for the "time_day" field saying it's the time in days since the
168  * start of the capture, but the "How the Analyzer Stores Time"
169  * section says it's increased by 1 if the capture continues past
170  * midnight - and also says that the time stamp structure has a time
171  * relative to midnight when the capture started, not since the
172  * actual capture start, so that might be a difference between
173  * the internal time stamp in the Sniffer software and the time
174  * stamp in capture files (i.e., the latter might be relative to
175  * the time when the capture starts).
176  */
177 struct frame2_rec {
178         guint16 time_low;       /* low part of time stamp */
179         guint16 time_med;       /* middle part of time stamp */
180         guint8  time_high;      /* high part of the time stamp */
181         guint8  time_day;       /* time in days since start of capture */
182         gint16  size;           /* number of bytes of data */
183         guint8  fs;             /* frame error status bits */
184         guint8  flags;          /* buffer flags */
185         gint16  true_size;      /* size of original frame, in bytes */
186         gint16  rsvd;           /* reserved */
187 };
188
189 /*
190  * Bits in "fs".
191  *
192  * The bits differ for different link-layer types.
193  */
194
195 /*
196  * Ethernet.
197  */
198 #define FS_ETH_CRC              0x80    /* CRC error */
199 #define FS_ETH_ALIGN            0x40    /* bad alignment */
200 #define FS_ETH_RU               0x20    /* "RU out of resources" */
201 #define FS_ETH_OVERRUN          0x10    /* DMA overrun */
202 #define FS_ETH_RUNT             0x08    /* frame too small */
203 #define FS_ETH_COLLISION        0x02    /* collision fragment */
204
205 /*
206  * FDDI.
207  */
208 #define FS_FDDI_INVALID         0x10    /* frame indicators are invalid */
209 #define FS_FDDI_ERROR           0x20    /* "frame error bit 1" */
210 #define FS_FDDI_PCI_VDL         0x01    /* VDL error on frame on PCI adapter */
211 #define FS_FDDI_PCI_CRC         0x02    /* CRC error on frame on PCI adapter */
212 #define FS_FDDI_ISA_CRC         0x20    /* CRC error on frame on ISA adapter */
213
214 /*
215  * Internetwork analyzer (synchronous and asynchronous).
216  */
217 #define FS_WAN_DTE              0x80    /* DTE->DCE frame */
218
219 /*
220  * Internetwork analyzer (synchronous).
221  */
222 #define FS_SYNC_LOST            0x01    /* some frames were lost */
223 #define FS_SYNC_CRC             0x02    /* CRC error */
224 #define FS_SYNC_ABORT           0x04    /* aborted frame */
225 #define FS_ISDN_CHAN_MASK       0x18    /* ISDN channel */
226 #define FS_ISDN_CHAN_D          0x18    /* ISDN channel D */
227 #define FS_ISDN_CHAN_B1         0x08    /* ISDN channel B1 */
228 #define FS_ISDN_CHAN_B2         0x10    /* ISDN channel B2 */
229
230 /*
231  * Internetwork analyzer (asynchronous).
232  * XXX - are some of these synchronous flags?  They're listed with the
233  * asynchronous flags in the Sniffer 5.50 Network Analyzer Operations
234  * manual.  Is one of the "overrun" errors a synchronous overrun error?
235  */
236 #define FS_ASYNC_LOST           0x01    /* some frames were lost */
237 #define FS_ASYNC_OVERRUN        0x02    /* UART overrun, lost bytes */
238 #define FS_ASYNC_FRAMING        0x04    /* bad character (framing error?) */
239 #define FS_ASYNC_PPP            0x08    /* PPP frame */
240 #define FS_ASYNC_SLIP           0x10    /* SLIP frame */
241 #define FS_ASYNC_ALIGN          0x20    /* alignment or DLPP(?) error */
242 #define FS_ASYNC_OVERRUN2       0x40    /* overrun or bad frame length */
243
244 /*
245  * Sniffer type 4 data record format - followed by frame data.
246  *
247  * The ATM Sniffer manual says that the "flags" field holds "buffer flags;
248  * BF_xxxx", but doesn't say what the BF_xxxx flags are.  They may
249  * be the same as they are in a type 2 record, in which case they're
250  * probably not of much interest to us.
251  *
252  * XXX - the manual also says there's an 8-byte "ATMTimeStamp" driver
253  * time stamp at the end of "ATMSaveInfo", but, from an ATM Sniffer capture
254  * file I've looked at, that appears not to be the case.
255  */
256
257 /*
258  * Fields from the AAL5 trailer for the frame, if it's an AAL5 frame
259  * rather than a cell.
260  */
261 typedef struct _ATM_AAL5Trailer {
262         guint16 aal5t_u2u;      /* user-to-user indicator */
263         guint16 aal5t_len;      /* length of the packet */
264         guint32 aal5t_chksum;   /* checksum for AAL5 packet */
265 } ATM_AAL5Trailer;
266
267 typedef struct _ATMTimeStamp {
268         guint32 msw;    /* most significant word */
269         guint32 lsw;    /* least significant word */
270 } ATMTimeStamp;
271
272 typedef struct _ATMSaveInfo {
273         guint32 StatusWord;     /* status word from driver */
274         ATM_AAL5Trailer Trailer; /* AAL5 trailer */
275         guint8  AppTrafType;    /* traffic type */
276         guint8  AppHLType;      /* protocol type */
277         guint16 AppReserved;    /* reserved */
278         guint16 Vpi;            /* virtual path identifier */
279         guint16 Vci;            /* virtual circuit identifier */
280         guint16 channel;        /* link: 0 for DCE, 1 for DTE */
281         guint16 cells;          /* number of cells */
282         guint32 AppVal1;        /* type-dependent */
283         guint32 AppVal2;        /* type-dependent */
284 } ATMSaveInfo;
285
286 /*
287  * Bits in StatusWord.
288  */
289 #define SW_ERRMASK              0x0F    /* Error mask: */
290 #define SW_RX_FIFO_UNDERRUN     0x01    /* Receive FIFO underrun */
291 #define SW_RX_FIFO_OVERRUN      0x02    /* Receive FIFO overrun */
292 #define SW_RX_PKT_TOO_LONG      0x03    /* Received packet > max size */
293 #define SW_CRC_ERROR            0x04    /* CRC error */
294 #define SW_USER_ABORTED_RX      0x05    /* User aborted receive */
295 #define SW_BUF_LEN_TOO_LONG     0x06    /* buffer len > max buf */
296 #define SW_INTERNAL_T1_ERROR    0x07    /* Internal T1 error */
297 #define SW_RX_CHANNEL_DEACTIV8  0x08    /* Rx channel deactivate */
298
299 #define SW_ERROR                0x80    /* Error indicator */
300 #define SW_CONGESTION           0x40    /* Congestion indicator */
301 #define SW_CLP                  0x20    /* Cell loss priority indicator */
302 #define SW_RAW_CELL             0x100   /* RAW cell indicator */
303 #define SW_OAM_CELL             0x200   /* OAM cell indicator */
304
305 /*
306  * Bits in AppTrafType.
307  *
308  * For AAL types other than AAL5, the packet data is presumably for a
309  * single cell, not a reassembled frame, as the ATM Sniffer manual says
310  * it dosn't reassemble cells other than AAL5 cells.
311  */
312 #define ATT_AALTYPE             0x0F    /* AAL type: */
313 #define ATT_AAL_UNKNOWN         0x00    /* Unknown AAL */
314 #define ATT_AAL1                0x01    /* AAL1 */
315 #define ATT_AAL3_4              0x02    /* AAL3/4 */
316 #define ATT_AAL5                0x03    /* AAL5 */
317 #define ATT_AAL_USER            0x04    /* User AAL */
318 #define ATT_AAL_SIGNALLING      0x05    /* Signaling AAL */
319 #define ATT_OAMCELL             0x06    /* OAM cell */
320
321 #define ATT_HLTYPE              0xF0    /* Higher-layer type: */
322 #define ATT_HL_UNKNOWN          0x00    /* unknown */
323 #define ATT_HL_LLCMX            0x10    /* LLC multiplexed (probably RFC 1483) */
324 #define ATT_HL_VCMX             0x20    /* VC multiplexed (probably RFC 1483) */
325 #define ATT_HL_LANE             0x30    /* LAN Emulation */
326 #define ATT_HL_ILMI             0x40    /* ILMI */
327 #define ATT_HL_FRMR             0x50    /* Frame Relay */
328 #define ATT_HL_SPANS            0x60    /* FORE SPANS */
329 #define ATT_HL_IPSILON          0x70    /* Ipsilon */
330
331 /*
332  * Values for AppHLType; the interpretation depends on the ATT_HLTYPE
333  * bits in AppTrafType.
334  */
335 #define AHLT_UNKNOWN            0x0
336 #define AHLT_VCMX_802_3_FCS     0x1     /* VCMX: 802.3 FCS */
337 #define AHLT_LANE_LE_CTRL       0x1     /* LANE: LE Ctrl */
338 #define AHLT_IPSILON_FT0        0x1     /* Ipsilon: Flow Type 0 */
339 #define AHLT_VCMX_802_4_FCS     0x2     /* VCMX: 802.4 FCS */
340 #define AHLT_LANE_802_3         0x2     /* LANE: 802.3 */
341 #define AHLT_IPSILON_FT1        0x2     /* Ipsilon: Flow Type 1 */
342 #define AHLT_VCMX_802_5_FCS     0x3     /* VCMX: 802.5 FCS */
343 #define AHLT_LANE_802_5         0x3     /* LANE: 802.5 */
344 #define AHLT_IPSILON_FT2        0x3     /* Ipsilon: Flow Type 2 */
345 #define AHLT_VCMX_FDDI_FCS      0x4     /* VCMX: FDDI FCS */
346 #define AHLT_LANE_802_3_MC      0x4     /* LANE: 802.3 multicast */
347 #define AHLT_VCMX_802_6_FCS     0x5     /* VCMX: 802.6 FCS */
348 #define AHLT_LANE_802_5_MC      0x5     /* LANE: 802.5 multicast */
349 #define AHLT_VCMX_802_3         0x7     /* VCMX: 802.3 */
350 #define AHLT_VCMX_802_4         0x8     /* VCMX: 802.4 */
351 #define AHLT_VCMX_802_5         0x9     /* VCMX: 802.5 */
352 #define AHLT_VCMX_FDDI          0xa     /* VCMX: FDDI */
353 #define AHLT_VCMX_802_6         0xb     /* VCMX: 802.6 */
354 #define AHLT_VCMX_FRAGMENTS     0xc     /* VCMX: Fragments */
355 #define AHLT_VCMX_BPDU          0xe     /* VCMX: BPDU */
356
357 struct frame4_rec {
358         guint16 time_low;       /* low part of time stamp */
359         guint16 time_med;       /* middle part of time stamp */
360         guint8  time_high;      /* high part of time stamp */
361         guint8  time_day;       /* time in days since start of capture */
362         gint16  size;           /* number of bytes of data */
363         gint8   fs;             /* frame error status bits */
364         gint8   flags;          /* buffer flags */
365         gint16  true_size;      /* size of original frame, in bytes */
366         gint16  rsvd3;          /* reserved */
367         gint16  atm_pad;        /* pad to 4-byte boundary */
368         ATMSaveInfo atm_info;   /* ATM-specific stuff */
369 };
370
371 /*
372  * XXX - I have a version 5.50 file with a bunch of token ring
373  * records listed as type "12".  The record format below was
374  * derived from frame4_rec and a bit of experimentation.
375  * - Gerald
376  */
377 struct frame6_rec {
378         guint16 time_low;       /* low part of time stamp */
379         guint16 time_med;       /* middle part of time stamp */
380         guint8  time_high;      /* high part of time stamp */
381         guint8  time_day;       /* time in days since start of capture */
382         gint16  size;           /* number of bytes of data */
383         guint8  fs;             /* frame error status bits */
384         guint8  flags;          /* buffer flags */
385         gint16  true_size;      /* size of original frame, in bytes */
386         guint8  chemical_x[22]; /* ? */
387 };
388
389 /*
390  * Network type values in some type 7 records.
391  *
392  * Captures with a major version number of 2 appear to have type 7
393  * records with text in them (at least one I have does).
394  *
395  * Captures with a major version of 4, and at least some captures with
396  * a major version of 5, have type 7 records with those values in the
397  * 5th byte.
398  *
399  * However, some captures with a major version number of 5 appear not to
400  * have type 7 records at all (at least one I have doesn't), but do appear
401  * to put non-zero values in the "rsvd" field of the version header (at
402  * least one I have does) - at least some other captures with smaller version
403  * numbers appear to put 0 there, so *maybe* that's where the network
404  * (sub)type is hidden in those captures.  The version 5 captures I've seen
405  * that *do* have type 7 records put 0 there, so it's not as if *all* V5
406  * captures have something in the "rsvd" field, however.
407  *
408  * The semantics of these network types is inferred from the Sniffer
409  * documentation, as they correspond to types described in the UI;
410  * in particular, see
411  *
412  *      http://www.mcafee.com/common/media/sniffer/support/sdos/operation.pdf
413  *
414  * starting at page 3-10 (56 of 496).
415  *
416  * XXX - I've seen X.25 captures with NET_ROUTER, and I've seen bridge/
417  * router captures with NET_HDLC.  Sigh....  Are those just captures for
418  * which the user set the wrong network type when capturing?
419  */
420 #define NET_SDLC        0       /* Probably "SDLC then SNA" */
421 #define NET_HDLC        1       /* Used for X.25; is it used for other
422                                    things as well, or is it "HDLC then
423                                    X.25", as referred to by the document
424                                    cited above, and only used for X.25? */
425 #define NET_FRAME_RELAY 2
426 #define NET_ROUTER      3       /* Probably "Router/Bridge", for various
427                                    point-to-point protocols for use between
428                                    bridges and routers, including PPP as well
429                                    as various proprietary protocols; also
430                                    used for ISDN, for reasons not obvious
431                                    to me, given that a Sniffer knows
432                                    whether it's using a WAN or an ISDN pod */
433 #define NET_PPP         4       /* "Asynchronous", which includes SLIP too */
434 #define NET_SMDS        5       /* Not mentioned in the document, but
435                                    that's a document for version 5.50 of
436                                    the Sniffer, and that version might use
437                                    version 5 in the file format and thus
438                                    might not be using type 7 records */
439
440 /*
441  * Values for V.timeunit, in picoseconds, so that they can be represented
442  * as integers.  These values must be < 2^(64-40); see below.
443  *
444  * XXX - at least some captures with a V.timeunit value of 2 show
445  * packets with time stamps in 2011 if the time stamp is interpreted
446  * to be in units of 15 microseconds.  The capture predates 2008,
447  * so that interpretation is probably wrong.  Perhaps the interpretation
448  * of V.timeunit depends on the version number of the file?
449  */
450 static const guint32 Psec[] = {
451         15000000,               /* 15.0 usecs = 15000000 psecs */
452           838096,               /* .838096 usecs = 838096 psecs */
453         15000000,               /* 15.0 usecs = 15000000 psecs */
454           500000,               /* 0.5 usecs = 500000 psecs */
455          2000000,               /* 2.0 usecs = 2000000 psecs */
456          1000000,               /* 1.0 usecs = 1000000 psecs */
457                                 /* XXX - Sniffer doc says 0.08 usecs = 80000 psecs */
458           100000                /* 0.1 usecs = 100000 psecs */
459 };
460 #define NUM_NGSNIFF_TIMEUNITS (sizeof Psec / sizeof Psec[0])
461
462 static int process_header_records(wtap *wth, int *err, gchar **err_info,
463     gint16 maj_vers, guint8 network);
464 static int process_rec_header2_v2(wtap *wth, unsigned char *buffer,
465     guint16 length, int *err, gchar **err_info);
466 static int process_rec_header2_v145(wtap *wth, unsigned char *buffer,
467     guint16 length, gint16 maj_vers, int *err, gchar **err_info);
468 static gboolean ngsniffer_read(wtap *wth, int *err, gchar **err_info,
469     gint64 *data_offset);
470 static gboolean ngsniffer_seek_read(wtap *wth, gint64 seek_off,
471     union wtap_pseudo_header *pseudo_header, guchar *pd, int packet_size,
472     int *err, gchar **err_info);
473 static int ngsniffer_read_rec_header(wtap *wth, gboolean is_random,
474     guint16 *typep, guint16 *lengthp, int *err);
475 static gboolean ngsniffer_read_frame2(wtap *wth, gboolean is_random,
476     struct frame2_rec *frame2, int *err);
477 static void set_pseudo_header_frame2(wtap *wth,
478     union wtap_pseudo_header *pseudo_header, struct frame2_rec *frame2);
479 static gboolean ngsniffer_read_frame4(wtap *wth, gboolean is_random,
480     struct frame4_rec *frame4, int *err);
481 static void set_pseudo_header_frame4(union wtap_pseudo_header *pseudo_header,
482     struct frame4_rec *frame4);
483 static gboolean ngsniffer_read_frame6(wtap *wth, gboolean is_random,
484     struct frame6_rec *frame6, int *err);
485 static void set_pseudo_header_frame6(wtap *wth,
486     union wtap_pseudo_header *pseudo_header, struct frame6_rec *frame6);
487 static gboolean ngsniffer_read_rec_data(wtap *wth, gboolean is_random,
488     guchar *pd, size_t length, int *err);
489 static int infer_pkt_encap(const guint8 *pd, int len);
490 static int fix_pseudo_header(int encap, const guint8 *pd, int len,
491     union wtap_pseudo_header *pseudo_header);
492 static void ngsniffer_sequential_close(wtap *wth);
493 static void ngsniffer_close(wtap *wth);
494 static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
495         const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
496 static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err);
497 static int SnifferDecompress( unsigned char * inbuf, size_t inlen,
498         unsigned char * outbuf, size_t outlen, int *err );
499 static gint64 ng_file_read(void *buffer, size_t elementsize, size_t numelements,
500     wtap *wth, gboolean is_random, int *err);
501 static int read_blob(FILE_T infile, ngsniffer_comp_stream_t *comp_stream,
502     int *err);
503 static gint64 ng_file_seek_seq(wtap *wth, gint64 offset, int whence, int *err);
504 static gint64 ng_file_seek_rand(wtap *wth, gint64 offset, int whence, int *err);
505
506 int ngsniffer_open(wtap *wth, int *err, gchar **err_info)
507 {
508         int bytes_read;
509         char magic[sizeof ngsniffer_magic];
510         char record_type[2];
511         char record_length[4]; /* only the first 2 bytes are length,
512                                   the last 2 are "reserved" and are thrown away */
513         guint16 type, length;
514         struct vers_rec version;
515         guint16 maj_vers;
516         guint16 start_date;
517         guint16 start_time;
518         static const int sniffer_encap[] = {
519                 WTAP_ENCAP_TOKEN_RING,
520                 WTAP_ENCAP_ETHERNET,
521                 WTAP_ENCAP_ARCNET,
522                 WTAP_ENCAP_UNKNOWN,     /* StarLAN */
523                 WTAP_ENCAP_UNKNOWN,     /* PC Network broadband */
524                 WTAP_ENCAP_UNKNOWN,     /* LocalTalk */
525                 WTAP_ENCAP_UNKNOWN,     /* Znet */
526                 WTAP_ENCAP_PER_PACKET,  /* Internetwork analyzer (synchronous) */
527                 WTAP_ENCAP_PER_PACKET,  /* Internetwork analyzer (asynchronous) */
528                 WTAP_ENCAP_FDDI_BITSWAPPED,
529                 WTAP_ENCAP_ATM_PDUS
530         };
531         #define NUM_NGSNIFF_ENCAPS (sizeof sniffer_encap / sizeof sniffer_encap[0])
532         struct tm tm;
533
534         /* Read in the string that should be at the start of a Sniffer file */
535         errno = WTAP_ERR_CANT_READ;
536         bytes_read = file_read(magic, 1, sizeof magic, wth->fh);
537         if (bytes_read != sizeof magic) {
538                 *err = file_error(wth->fh);
539                 if (*err != 0)
540                         return -1;
541                 return 0;
542         }
543         wth->data_offset += sizeof magic;
544
545         if (memcmp(magic, ngsniffer_magic, sizeof ngsniffer_magic)) {
546                 return 0;
547         }
548
549         /*
550          * Read the first record, which the manual says is a version
551          * record.
552          */
553         errno = WTAP_ERR_CANT_READ;
554         bytes_read = file_read(record_type, 1, 2, wth->fh);
555         bytes_read += file_read(record_length, 1, 4, wth->fh);
556         if (bytes_read != 6) {
557                 *err = file_error(wth->fh);
558                 if (*err != 0)
559                         return -1;
560                 return 0;
561         }
562         wth->data_offset += 6;
563
564         type = pletohs(record_type);
565         length = pletohs(record_length);
566
567         if (type != REC_VERS) {
568                 *err = WTAP_ERR_BAD_RECORD;
569                 *err_info = g_strdup_printf("ngsniffer: Sniffer file doesn't start with a version record");
570                 return -1;
571         }
572
573         errno = WTAP_ERR_CANT_READ;
574         bytes_read = file_read(&version, 1, sizeof version, wth->fh);
575         if (bytes_read != sizeof version) {
576                 *err = file_error(wth->fh);
577                 if (*err != 0)
578                         return -1;
579                 return 0;
580         }
581         wth->data_offset += sizeof version;
582
583         /* Check the data link type. */
584         if (version.network >= NUM_NGSNIFF_ENCAPS
585             || sniffer_encap[version.network] == WTAP_ENCAP_UNKNOWN) {
586                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
587                 *err_info = g_strdup_printf("ngsniffer: network type %u unknown or unsupported",
588                     version.network);
589                 return -1;
590         }
591
592         /* Check the time unit */
593         if (version.timeunit >= NUM_NGSNIFF_TIMEUNITS) {
594                 *err = WTAP_ERR_UNSUPPORTED;
595                 *err_info = g_strdup_printf("ngsniffer: Unknown timeunit %u", version.timeunit);
596                 return -1;
597         }
598
599         /* compressed or uncompressed Sniffer file? */
600         if (version.format != 1) {
601                 wth->file_type = WTAP_FILE_NGSNIFFER_COMPRESSED;
602
603         } else {
604                 wth->file_type = WTAP_FILE_NGSNIFFER_UNCOMPRESSED;
605         }
606
607         /* Set encap type before reading header records because the
608          * header record may change encap type.
609          */
610         wth->file_encap = sniffer_encap[version.network];
611
612         /*
613          * We don't know how to handle the remaining header record types,
614          * so we just skip them - except for REC_HEADER2 records, which
615          * we look at, for "Internetwork analyzer" captures, to attempt to
616          * determine what the link-layer encapsulation is.
617          *
618          * XXX - in some version 1.16 internetwork analyzer files
619          * generated by the Windows Sniffer when saving Windows
620          * Sniffer files as DOS Sniffer files, there's no REC_HEADER2
621          * record, but the first "rsvd" word is 1 for PRI ISDN files, 2
622          * for BRI ISDN files, and 0 for non-ISDN files; is that something
623          * the DOS Sniffer understands?
624          */
625         maj_vers = pletohs(&version.maj_vers);
626         if (process_header_records(wth, err, err_info, maj_vers,
627             version.network) < 0)
628                 return -1;
629         if ((version.network == NETWORK_SYNCHRO ||
630             version.network == NETWORK_ASYNC) &&
631             wth->file_encap == WTAP_ENCAP_PER_PACKET) {
632                 /*
633                  * Well, we haven't determined the internetwork analyzer
634                  * subtype yet...
635                  */
636                 switch (maj_vers) {
637
638                 case 1:
639                         /*
640                          * ... and this is a version 1 capture; look
641                          * at the first "rsvd" word.
642                          */
643                         switch (pletohs(&version.rsvd[0])) {
644
645                         case 1:
646                         case 2:
647                                 wth->file_encap = WTAP_ENCAP_ISDN;
648                                 break;
649                         }
650                         break;
651
652                 case 3:
653                         /*
654                          * ...and this is a version 3 capture; we've
655                          * seen nothing in those that obviously
656                          * indicates the capture type, but the only
657                          * one we've seen is a Frame Relay capture,
658                          * so mark it as Frame Relay for now.
659                          */
660                         wth->file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
661                         break;
662                 }
663         }
664
665         /*
666          * Now, if we have a random stream open, position it to the same
667          * location, which should be the beginning of the real data, and
668          * should be the beginning of the compressed data.
669          *
670          * XXX - will we see any records other than REC_FRAME2, REC_FRAME4,
671          * or REC_EOF after this?  If not, we can get rid of the loop in
672          * "ngsniffer_read()".
673          */
674         if (wth->random_fh != NULL) {
675                 if (file_seek(wth->random_fh, wth->data_offset, SEEK_SET, err) == -1)
676                         return -1;
677         }
678
679         /* This is a ngsniffer file */
680         wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t));
681         wth->capture.ngsniffer->maj_vers = maj_vers;
682         wth->capture.ngsniffer->min_vers = pletohs(&version.min_vers);
683
684         /* We haven't allocated any uncompression buffers yet. */
685         wth->capture.ngsniffer->seq.buf = NULL;
686         wth->capture.ngsniffer->rand.buf = NULL;
687
688         /* Set the current file offset; the offset in the compressed file
689            and in the uncompressed data stream currently the same. */
690         wth->capture.ngsniffer->seq.uncomp_offset = wth->data_offset;
691         wth->capture.ngsniffer->seq.comp_offset = wth->data_offset;
692         wth->capture.ngsniffer->rand.uncomp_offset = wth->data_offset;
693         wth->capture.ngsniffer->rand.comp_offset = wth->data_offset;
694
695         /* We don't yet have any list of compressed blobs. */
696         wth->capture.ngsniffer->first_blob = NULL;
697         wth->capture.ngsniffer->last_blob = NULL;
698         wth->capture.ngsniffer->current_blob = NULL;
699
700         wth->subtype_read = ngsniffer_read;
701         wth->subtype_seek_read = ngsniffer_seek_read;
702         wth->subtype_sequential_close = ngsniffer_sequential_close;
703         wth->subtype_close = ngsniffer_close;
704         wth->snapshot_length = 0;       /* not available in header, only in frame */
705         wth->capture.ngsniffer->timeunit = Psec[version.timeunit];
706         wth->capture.ngsniffer->network = version.network;
707
708         /* Get capture start time */
709         start_time = pletohs(&version.time);
710         start_date = pletohs(&version.date);
711         tm.tm_year = ((start_date&0xfe00)>>9) + 1980 - 1900;
712         tm.tm_mon = ((start_date&0x1e0)>>5) - 1;
713         tm.tm_mday = (start_date&0x1f);
714         /* The time does not appear to act as an offset; only the date
715         tm.tm_hour = (start_time&0xf800)>>11;
716         tm.tm_min = (start_time&0x7e0)>>5;
717         tm.tm_sec = (start_time&0x1f)<<1;*/
718         tm.tm_hour = 0;
719         tm.tm_min = 0;
720         tm.tm_sec = 0;
721         tm.tm_isdst = -1;
722         wth->capture.ngsniffer->start = mktime(&tm);
723         /*
724          * XXX - what if "secs" is -1?  Unlikely,
725          * but if the capture was done in a time
726          * zone that switches between standard and
727          * summer time sometime other than when we
728          * do, and thus the time was one that doesn't
729          * exist here because a switch from standard
730          * to summer time zips over it, it could
731          * happen.
732          *
733          * On the other hand, if the capture was done
734          * in a different time zone, this won't work
735          * right anyway; unfortunately, the time zone
736          * isn't stored in the capture file.
737          */
738
739         wth->tsprecision = WTAP_FILE_TSPREC_NSEC;       /* XXX */
740
741         return 1;
742 }
743
744 static int
745 process_header_records(wtap *wth, int *err, gchar **err_info, gint16 maj_vers,
746     guint8 network)
747 {
748         int bytes_read;
749         char record_type[2];
750         char record_length[4]; /* only the first 2 bytes are length,
751                                   the last 2 are "reserved" and are thrown away */
752         guint16 type, length;
753         int bytes_to_read;
754         unsigned char buffer[256];
755
756         for (;;) {
757                 errno = WTAP_ERR_CANT_READ;
758                 bytes_read = file_read(record_type, 1, 2, wth->fh);
759                 if (bytes_read != 2) {
760                         *err = file_error(wth->fh);
761                         if (*err != 0)
762                                 return -1;
763                         if (bytes_read != 0) {
764                                 *err = WTAP_ERR_SHORT_READ;
765                                 return -1;
766                         }
767                         return 0;       /* EOF */
768                 }
769
770                 type = pletohs(record_type);
771                 if ((type != REC_HEADER1) && (type != REC_HEADER2)
772                         && (type != REC_HEADER3) && (type != REC_HEADER4)
773                         && (type != REC_HEADER5) && (type != REC_HEADER6)
774                         && (type != REC_HEADER7)
775                         && ((type != REC_V2DESC) || (maj_vers > 2)) ) {
776                         /*
777                          * Well, this is either some unknown header type
778                          * (we ignore this case), an uncompressed data
779                          * frame or the length of a compressed blob
780                          * which implies data. Seek backwards over the
781                          * two bytes we read, and return.
782                          */
783                         if (file_seek(wth->fh, -2, SEEK_CUR, err) == -1)
784                                 return -1;
785                         return 0;
786                 }
787
788                 errno = WTAP_ERR_CANT_READ;
789                 bytes_read = file_read(record_length, 1, 4, wth->fh);
790                 if (bytes_read != 4) {
791                         *err = file_error(wth->fh);
792                         if (*err == 0)
793                                 *err = WTAP_ERR_SHORT_READ;
794                         return -1;
795                 }
796                 wth->data_offset += 6;
797
798                 length = pletohs(record_length);
799
800                 /*
801                  * Is this is an "Internetwork analyzer" capture, and
802                  * is this a REC_HEADER2 record?
803                  *
804                  * If so, it appears to specify the particular type
805                  * of network we're on.
806                  *
807                  * XXX - handle sync and async differently?  (E.g.,
808                  * does this apply only to sync?)
809                  */
810                 if ((network == NETWORK_SYNCHRO || network == NETWORK_ASYNC) &&
811                     type == REC_HEADER2) {
812                         /*
813                          * Yes, get the first up-to-256 bytes of the
814                          * record data.
815                          */
816                         bytes_to_read = MIN(length, (int)sizeof buffer);
817                         bytes_read = file_read(buffer, 1, bytes_to_read,
818                                 wth->fh);
819                         if (bytes_read != bytes_to_read) {
820                                 *err = file_error(wth->fh);
821                                 if (*err == 0) {
822                                         *err = WTAP_ERR_SHORT_READ;
823                                         return -1;
824                                 }
825                         }
826
827                         switch (maj_vers) {
828
829                         case 2:
830                                 if (process_rec_header2_v2(wth, buffer,
831                                     length, err, err_info) < 0)
832                                         return -1;
833                                 break;
834
835                         case 1:
836                         case 4:
837                         case 5:
838                                 if (process_rec_header2_v145(wth, buffer,
839                                     length, maj_vers, err, err_info) < 0)
840                                         return -1;
841                                 break;
842                         }
843
844                         /*
845                          * Skip the rest of the record.
846                          */
847                         if (length > sizeof buffer) {
848                                 if (file_seek(wth->fh, length - sizeof buffer,
849                                     SEEK_CUR, err) == -1)
850                                         return -1;
851                         }
852                 } else {
853                         /* Nope, just skip over the data. */
854                         if (file_seek(wth->fh, length, SEEK_CUR, err) == -1)
855                                 return -1;
856                 }
857                 wth->data_offset += length;
858         }
859 }
860
861 static int
862 process_rec_header2_v2(wtap *wth, unsigned char *buffer, guint16 length,
863     int *err, gchar **err_info)
864 {
865         static const char x_25_str[] = "HDLC\nX.25\n";
866
867         /*
868          * There appears to be a string in a REC_HEADER2 record, with
869          * a list of protocols.  In one X.25 capture I've seen, the
870          * string was "HDLC\nX.25\nCLNP\nISO_TP\nSESS\nPRES\nVTP\nACSE".
871          * Presumably CLNP and everything else is per-packet, but
872          * we assume "HDLC\nX.25\n" indicates that it's an X.25 capture.
873          */
874         if (length < sizeof x_25_str - 1) {
875                 /*
876                  * There's not enough data to compare.
877                  */
878                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
879                 *err_info = g_strdup_printf("ngsniffer: WAN capture has too-short protocol list");
880                 return -1;
881         }
882
883         if (strncmp((char *)buffer, x_25_str, sizeof x_25_str - 1) == 0) {
884                 /*
885                  * X.25.
886                  */
887                 wth->file_encap = WTAP_ENCAP_LAPB;
888         } else {
889                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
890                 *err_info = g_strdup_printf("ngsniffer: WAN capture protocol string %.*s unknown",
891                     length, buffer);
892                 return -1;
893         }
894         return 0;
895 }
896
897 static int
898 process_rec_header2_v145(wtap *wth, unsigned char *buffer, guint16 length,
899     gint16 maj_vers, int *err, gchar **err_info)
900 {
901         /*
902          * The 5th byte of the REC_HEADER2 record appears to be a
903          * network type.
904          */
905         if (length < 5) {
906                 /*
907                  * There is no 5th byte; give up.
908                  */
909                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
910                 *err_info = g_strdup("ngsniffer: WAN capture has no network subtype");
911                 return -1;
912         }
913
914         /*
915          * The X.25 captures I've seen have a type of NET_HDLC, and the
916          * Sniffer documentation seems to imply that it's used for
917          * X.25, although it could be used for other purposes as well.
918          *
919          * NET_ROUTER is used for all sorts of point-to-point protocols,
920          * including ISDN.  It appears, from the documentation, that the
921          * Sniffer attempts to infer the particular protocol by looking
922          * at the traffic; it's not clear whether it stores in the file
923          * an indication of the protocol it inferred was being used.
924          *
925          * Unfortunately, it also appears that NET_HDLC is used for
926          * stuff other than X.25 as well, so we can't just interpret
927          * it unconditionally as X.25.
928          *
929          * For now, we interpret both NET_HDLC and NET_ROUTER as "per-packet
930          * encapsulation".  We remember that we saw NET_ROUTER, though,
931          * as it appears that we can infer whether a packet is PPP or
932          * ISDN based on the channel number subfield of the frame error
933          * status bits - if it's 0, it's PPP, otherwise it's ISDN and
934          * the channel number indicates which channel it is.  We assume
935          * NET_HDLC isn't used for ISDN.
936          */
937         switch (buffer[4]) {
938
939         case NET_SDLC:
940                 wth->file_encap = WTAP_ENCAP_SDLC;
941                 break;
942
943         case NET_HDLC:
944                 wth->file_encap = WTAP_ENCAP_PER_PACKET;
945                 break;
946
947         case NET_FRAME_RELAY:
948                 wth->file_encap = WTAP_ENCAP_FRELAY_WITH_PHDR;
949                 break;
950
951         case NET_ROUTER:
952                 /*
953                  * For most of the version 4 capture files I've seen,
954                  * 0xfa in buffer[1] means the file is an ISDN capture,
955                  * but there's one PPP file with 0xfa there; does that
956                  * mean that the 0xfa has nothing to do with ISDN,
957                  * or is that just an ISDN file with no D channel
958                  * packets?  (The channel number is not 0 in any
959                  * of the packets, so perhaps it is.)
960                  *
961                  * For one version 5 ISDN capture I've seen, there's
962                  * a 0x01 in buffer[6]; none of the non-ISDN version
963                  * 5 captures have it.
964                  */
965                 wth->file_encap = WTAP_ENCAP_PER_PACKET;
966                 switch (maj_vers) {
967
968                 case 4:
969                         if (buffer[1] == 0xfa)
970                                 wth->file_encap = WTAP_ENCAP_ISDN;
971                         break;
972
973                 case 5:
974                         if (length < 7) {
975                                 /*
976                                  * There is no 5th byte; give up.
977                                  */
978                                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
979                                 *err_info = g_strdup("ngsniffer: WAN bridge/router capture has no ISDN flag");
980                                 return -1;
981                         }
982                         if (buffer[6] == 0x01)
983                                 wth->file_encap = WTAP_ENCAP_ISDN;
984                         break;
985                 }
986                 break;
987
988         case NET_PPP:
989                 wth->file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
990                 break;
991
992         default:
993                 /*
994                  * Reject these until we can figure them out.
995                  */
996                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
997                 *err_info = g_strdup_printf("ngsniffer: WAN network subtype %u unknown or unsupported",
998                     buffer[4]);
999                 return -1;
1000         }
1001         return 0;
1002 }
1003
1004 /* Read the next packet */
1005 static gboolean ngsniffer_read(wtap *wth, int *err, gchar **err_info,
1006     gint64 *data_offset)
1007 {
1008         int     ret;
1009         guint16 type, length;
1010         struct frame2_rec frame2;
1011         struct frame4_rec frame4;
1012         struct frame6_rec frame6;
1013         guint16 time_low, time_med, true_size, size;
1014         guint8  time_high, time_day;
1015         guint64 t, tsecs, tpsecs;
1016         guchar  *pd;
1017
1018         for (;;) {
1019                 /*
1020                  * Read the record header.
1021                  */
1022                 *data_offset = wth->data_offset;
1023                 ret = ngsniffer_read_rec_header(wth, FALSE, &type, &length,
1024                     err);
1025                 if (ret <= 0) {
1026                         /* Read error or EOF */
1027                         return FALSE;
1028                 }
1029                 wth->data_offset += 6;
1030
1031                 switch (type) {
1032
1033                 case REC_FRAME2:
1034                         if (wth->capture.ngsniffer->network == NETWORK_ATM) {
1035                                 /*
1036                                  * We shouldn't get a frame2 record in
1037                                  * an ATM capture.
1038                                  */
1039                                 *err = WTAP_ERR_BAD_RECORD;
1040                                 *err_info = g_strdup("ngsniffer: REC_FRAME2 record in an ATM Sniffer file");
1041                                 return FALSE;
1042                         }
1043
1044                         /* Read the f_frame2_struct */
1045                         if (!ngsniffer_read_frame2(wth, FALSE, &frame2, err)) {
1046                                 /* Read error */
1047                                 return FALSE;
1048                         }
1049                         wth->data_offset += sizeof frame2;
1050                         time_low = pletohs(&frame2.time_low);
1051                         time_med = pletohs(&frame2.time_med);
1052                         time_high = frame2.time_high;
1053                         time_day = frame2.time_day;
1054                         size = pletohs(&frame2.size);
1055                         true_size = pletohs(&frame2.true_size);
1056
1057                         length -= sizeof frame2;        /* we already read that much */
1058
1059                         set_pseudo_header_frame2(wth, &wth->pseudo_header,
1060                             &frame2);
1061                         goto found;
1062
1063                 case REC_FRAME4:
1064                         if (wth->capture.ngsniffer->network != NETWORK_ATM) {
1065                                 /*
1066                                  * We shouldn't get a frame2 record in
1067                                  * a non-ATM capture.
1068                                  */
1069                                 *err = WTAP_ERR_BAD_RECORD;
1070                                 *err_info = g_strdup("ngsniffer: REC_FRAME4 record in a non-ATM Sniffer file");
1071                                 return FALSE;
1072                         }
1073
1074                         /* Read the f_frame4_struct */
1075                         if (!ngsniffer_read_frame4(wth, FALSE, &frame4, err)) {
1076                                 /* Read error */
1077                                 return FALSE;
1078                         }
1079                         wth->data_offset += sizeof frame4;
1080                         time_low = pletohs(&frame4.time_low);
1081                         time_med = pletohs(&frame4.time_med);
1082                         time_high = frame4.time_high;
1083                         time_day = frame4.time_day;
1084                         size = pletohs(&frame4.size);
1085                         true_size = pletohs(&frame4.true_size);
1086
1087                         /*
1088                          * XXX - it looks as if some version 4 captures have
1089                          * a bogus record length, based on the assumption
1090                          * that the record is a frame2 record.
1091                          */
1092                         if (wth->capture.ngsniffer->maj_vers >= 5)
1093                                 length -= sizeof frame4;        /* we already read that much */
1094                         else {
1095                                 if (wth->capture.ngsniffer->min_vers >= 95)
1096                                         length -= sizeof frame2;
1097                                 else
1098                                         length -= sizeof frame4;
1099                         }
1100
1101                         set_pseudo_header_frame4(&wth->pseudo_header, &frame4);
1102                         goto found;
1103
1104                 case REC_FRAME6:
1105                         /* Read the f_frame6_struct */
1106                         if (!ngsniffer_read_frame6(wth, FALSE, &frame6, err)) {
1107                                 /* Read error */
1108                                 return FALSE;
1109                         }
1110                         wth->data_offset += sizeof frame6;
1111                         time_low = pletohs(&frame6.time_low);
1112                         time_med = pletohs(&frame6.time_med);
1113                         time_high = frame6.time_high;
1114                         time_day = frame6.time_day;
1115                         size = pletohs(&frame6.size);
1116                         true_size = pletohs(&frame6.true_size);
1117
1118                         length -= sizeof frame6;        /* we already read that much */
1119
1120                         set_pseudo_header_frame6(wth, &wth->pseudo_header,
1121                             &frame6);
1122                         goto found;
1123
1124                 case REC_EOF:
1125                         /*
1126                          * End of file.  Return an EOF indication.
1127                          */
1128                         *err = 0;       /* EOF, not error */
1129                         return FALSE;
1130
1131                 default:
1132                         break;  /* unknown type, skip it */
1133                 }
1134
1135                 /*
1136                  * Well, we don't know what it is, or we know what
1137                  * it is but can't handle it.  Skip past the data
1138                  * portion, and keep looping.
1139                  */
1140                 if (ng_file_seek_seq(wth, length, SEEK_CUR, err) == -1)
1141                         return FALSE;
1142                 wth->data_offset += length;
1143         }
1144
1145 found:
1146         /*
1147          * OK, is the frame data size greater than than what's left of the
1148          * record?
1149          */
1150         if (size > length) {
1151                 /*
1152                  * Yes - treat this as an error.
1153                  */
1154                 *err = WTAP_ERR_BAD_RECORD;
1155                 *err_info = g_strdup("ngsniffer: Record length is less than packet size");
1156                 return FALSE;
1157         }
1158
1159         wth->phdr.len = true_size ? true_size : size;
1160         wth->phdr.caplen = size;
1161
1162         /*
1163          * Read the packet data.
1164          */
1165         buffer_assure_space(wth->frame_buffer, length);
1166         pd = buffer_start_ptr(wth->frame_buffer);
1167         if (!ngsniffer_read_rec_data(wth, FALSE, pd, length, err))
1168                 return FALSE;   /* Read error */
1169         wth->data_offset += length;
1170
1171         wth->phdr.pkt_encap = fix_pseudo_header(wth->file_encap, pd, length,
1172             &wth->pseudo_header);
1173
1174         /*
1175          * 40-bit time stamp, in units of timeunit picoseconds.
1176          */
1177         t = (((guint64)time_high)<<32) | (((guint32)time_med) << 16) | time_low;
1178
1179         /*
1180          * timeunit is always < 2^(64-40), so t * timeunit fits in 64
1181          * bits.  That gives a 64-bit time stamp, in units of
1182          * picoseconds.
1183          */
1184         t *= wth->capture.ngsniffer->timeunit;
1185
1186         /*
1187          * Convert to seconds and picoseconds.
1188          */
1189         tsecs = t/G_GINT64_CONSTANT(1000000000000U);
1190         tpsecs = t - tsecs*G_GINT64_CONSTANT(1000000000000U);
1191
1192         /*
1193          * Add in the time_day value (86400 seconds/day).
1194          */
1195         tsecs += time_day*86400;
1196
1197         /*
1198          * Add in the capture start time.
1199          */
1200         tsecs += wth->capture.ngsniffer->start;
1201
1202         wth->phdr.ts.secs = (time_t)tsecs;
1203         wth->phdr.ts.nsecs = (int)(tpsecs/1000);        /* psecs to nsecs */
1204         return TRUE;
1205 }
1206
1207 static gboolean ngsniffer_seek_read(wtap *wth, gint64 seek_off,
1208     union wtap_pseudo_header *pseudo_header, guchar *pd, int packet_size,
1209     int *err, gchar **err_info _U_)
1210 {
1211         int     ret;
1212         guint16 type, length;
1213         struct frame2_rec frame2;
1214         struct frame4_rec frame4;
1215         struct frame6_rec frame6;
1216
1217         if (ng_file_seek_rand(wth, seek_off, SEEK_SET, err) == -1)
1218                 return FALSE;
1219
1220         ret = ngsniffer_read_rec_header(wth, TRUE, &type, &length, err);
1221         if (ret <= 0) {
1222                 /* Read error or EOF */
1223                 if (ret == 0) {
1224                         /* EOF means "short read" in random-access mode */
1225                         *err = WTAP_ERR_SHORT_READ;
1226                 }
1227                 return FALSE;
1228         }
1229
1230         switch (type) {
1231
1232         case REC_FRAME2:
1233                 /* Read the f_frame2_struct */
1234                 if (!ngsniffer_read_frame2(wth, TRUE, &frame2, err)) {
1235                         /* Read error */
1236                         return FALSE;
1237                 }
1238
1239                 length -= sizeof frame2;        /* we already read that much */
1240
1241                 set_pseudo_header_frame2(wth, pseudo_header, &frame2);
1242                 break;
1243
1244         case REC_FRAME4:
1245                 /* Read the f_frame4_struct */
1246                 if (!ngsniffer_read_frame4(wth, TRUE, &frame4, err)) {
1247                         /* Read error */
1248                         return FALSE;
1249                 }
1250
1251                 length -= sizeof frame4;        /* we already read that much */
1252
1253                 set_pseudo_header_frame4(pseudo_header, &frame4);
1254                 break;
1255
1256         case REC_FRAME6:
1257                 /* Read the f_frame6_struct */
1258                 if (!ngsniffer_read_frame6(wth, TRUE, &frame6, err)) {
1259                         /* Read error */
1260                         return FALSE;
1261                 }
1262
1263                 length -= sizeof frame6;        /* we already read that much */
1264
1265                 set_pseudo_header_frame6(wth, pseudo_header, &frame6);
1266                 break;
1267
1268         default:
1269                 /*
1270                  * "Can't happen".
1271                  */
1272                 g_assert_not_reached();
1273                 return FALSE;
1274         }
1275
1276         /*
1277          * Got the pseudo-header (if any), now get the data.
1278          */
1279         if (!ngsniffer_read_rec_data(wth, TRUE, pd, packet_size, err))
1280                 return FALSE;
1281
1282         fix_pseudo_header(wth->file_encap, pd, packet_size, pseudo_header);
1283
1284         return TRUE;
1285 }
1286
1287 static int ngsniffer_read_rec_header(wtap *wth, gboolean is_random,
1288     guint16 *typep, guint16 *lengthp, int *err)
1289 {
1290         gint64  bytes_read;
1291         char    record_type[2];
1292         char    record_length[4]; /* only 1st 2 bytes are length */
1293
1294         /*
1295          * Read the record header.
1296          */
1297         bytes_read = ng_file_read(record_type, 1, 2, wth, is_random, err);
1298         if (bytes_read != 2) {
1299                 if (*err != 0)
1300                         return -1;
1301                 if (bytes_read != 0) {
1302                         *err = WTAP_ERR_SHORT_READ;
1303                         return -1;
1304                 }
1305                 return 0;
1306         }
1307         bytes_read = ng_file_read(record_length, 1, 4, wth, is_random, err);
1308         if (bytes_read != 4) {
1309                 if (*err == 0)
1310                         *err = WTAP_ERR_SHORT_READ;
1311                 return -1;
1312         }
1313
1314         *typep = pletohs(record_type);
1315         *lengthp = pletohs(record_length);
1316         return 1;       /* success */
1317 }
1318
1319 static gboolean ngsniffer_read_frame2(wtap *wth, gboolean is_random,
1320     struct frame2_rec *frame2, int *err)
1321 {
1322         gint64 bytes_read;
1323
1324         /* Read the f_frame2_struct */
1325         bytes_read = ng_file_read(frame2, 1, sizeof *frame2, wth, is_random,
1326             err);
1327         if (bytes_read != sizeof *frame2) {
1328                 if (*err == 0)
1329                         *err = WTAP_ERR_SHORT_READ;
1330                 return FALSE;
1331         }
1332         return TRUE;
1333 }
1334
1335 static void set_pseudo_header_frame2(wtap *wth,
1336     union wtap_pseudo_header *pseudo_header, struct frame2_rec *frame2)
1337 {
1338         /*
1339          * In one PPP "Internetwork analyzer" capture:
1340          *
1341          *      The only bit seen in "frame2.fs" is the 0x80 bit, which
1342          *      probably indicates the packet's direction; all other
1343          *      bits were zero.  The Expert Sniffer Network Analyzer
1344          *      5.50 Operations manual says that bit is the FS_DTE bit
1345          *      for async/PPP data.  The other bits are error bits
1346          *      plus bits indicating whether the frame is PPP or SLIP,
1347          *      but the PPP bit isn't set.
1348          *
1349          *      All bits in "frame2.flags" were zero.
1350          *
1351          * In one X.25 "Internetwork analyzer" capture:
1352          *
1353          *      The only bit seen in "frame2.fs" is the 0x80 bit, which
1354          *      probably indicates the packet's direction; all other
1355          *      bits were zero.
1356          *
1357          *      "frame2.flags" was always 0x18; however, the Sniffer
1358          *      manual says that just means that a display filter was
1359          *      calculated for the frame, and it should be displayed,
1360          *      so perhaps that's just a quirk of that particular capture.
1361          *
1362          * In one Ethernet capture:
1363          *
1364          *      "frame2.fs" was always 0; the Sniffer manual says they're
1365          *      error bits of various sorts.
1366          *
1367          *      "frame2.flags" was either 0 or 0x18, with no obvious
1368          *      correlation with anything.  See previous comment
1369          *      about display filters.
1370          *
1371          * In one Token Ring capture:
1372          *
1373          *      "frame2.fs" was either 0 or 0xcc; the Sniffer manual says
1374          *      nothing about those bits for Token Ring captures.
1375          *
1376          *      "frame2.flags" was either 0 or 0x18, with no obvious
1377          *      correlation with anything.  See previous comment
1378          *      about display filters.
1379          */
1380         switch (wth->file_encap) {
1381
1382         case WTAP_ENCAP_ETHERNET:
1383                 /*
1384                  * XXX - do we ever have an FCS?  If not, why do we often
1385                  * have 4 extra bytes of stuff at the end?  Do some
1386                  * PC Ethernet interfaces report the length including the
1387                  * FCS but not store the FCS in the packet, or do some
1388                  * Ethernet drivers work that way?
1389                  */
1390                 pseudo_header->eth.fcs_len = 0;
1391                 break;
1392
1393         case WTAP_ENCAP_PPP_WITH_PHDR:
1394         case WTAP_ENCAP_SDLC:
1395                 pseudo_header->p2p.sent = (frame2->fs & FS_WAN_DTE) ? TRUE : FALSE;
1396                 break;
1397
1398         case WTAP_ENCAP_LAPB:
1399         case WTAP_ENCAP_FRELAY_WITH_PHDR:
1400         case WTAP_ENCAP_PER_PACKET:
1401                 pseudo_header->x25.flags = (frame2->fs & FS_WAN_DTE) ? 0x00 : FROM_DCE;
1402                 break;
1403
1404         case WTAP_ENCAP_ISDN:
1405                 pseudo_header->isdn.uton = (frame2->fs & FS_WAN_DTE) ? FALSE : TRUE;
1406                 switch (frame2->fs & FS_ISDN_CHAN_MASK) {
1407
1408                 case FS_ISDN_CHAN_D:
1409                         pseudo_header->isdn.channel = 0;        /* D-channel */
1410                         break;
1411
1412                 case FS_ISDN_CHAN_B1:
1413                         pseudo_header->isdn.channel = 1;        /* B1-channel */
1414                         break;
1415
1416                 case FS_ISDN_CHAN_B2:
1417                         pseudo_header->isdn.channel = 2;        /* B2-channel */
1418                         break;
1419
1420                 default:
1421                         pseudo_header->isdn.channel = 30;       /* XXX */
1422                         break;
1423                 }
1424         }
1425 }
1426
1427 static gboolean ngsniffer_read_frame4(wtap *wth, gboolean is_random,
1428     struct frame4_rec *frame4, int *err)
1429 {
1430         gint64 bytes_read;
1431
1432         /* Read the f_frame4_struct */
1433         bytes_read = ng_file_read(frame4, 1, sizeof *frame4, wth, is_random,
1434             err);
1435         if (bytes_read != sizeof *frame4) {
1436                 if (*err == 0)
1437                         *err = WTAP_ERR_SHORT_READ;
1438                 return FALSE;
1439         }
1440         return TRUE;
1441 }
1442
1443 static void set_pseudo_header_frame4(union wtap_pseudo_header *pseudo_header,
1444     struct frame4_rec *frame4)
1445 {
1446         guint32 StatusWord;
1447         guint8 aal_type, hl_type;
1448         guint16 vpi, vci;
1449
1450         /*
1451          * Map flags from frame4.atm_info.StatusWord.
1452          */
1453         pseudo_header->atm.flags = 0;
1454         StatusWord = pletohl(&frame4->atm_info.StatusWord);
1455         if (StatusWord & SW_RAW_CELL)
1456                 pseudo_header->atm.flags |= ATM_RAW_CELL;
1457
1458         aal_type = frame4->atm_info.AppTrafType & ATT_AALTYPE;
1459         hl_type = frame4->atm_info.AppTrafType & ATT_HLTYPE;
1460         vpi = pletohs(&frame4->atm_info.Vpi);
1461         vci = pletohs(&frame4->atm_info.Vci);
1462
1463         switch (aal_type) {
1464
1465         case ATT_AAL_UNKNOWN:
1466                 /*
1467                  * Map ATT_AAL_UNKNOWN on VPI 0, VCI 5 to ATT_AAL_SIGNALLING,
1468                  * as that's the VPCI used for signalling.
1469                  *
1470                  * XXX - is this necessary, or will frames to 0/5 always
1471                  * have ATT_AAL_SIGNALLING?
1472                  */
1473                 if (vpi == 0 && vci == 5)
1474                         pseudo_header->atm.aal = AAL_SIGNALLING;
1475                 else
1476                         pseudo_header->atm.aal = AAL_UNKNOWN;
1477                 pseudo_header->atm.type = TRAF_UNKNOWN;
1478                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1479                 break;
1480
1481         case ATT_AAL1:
1482                 pseudo_header->atm.aal = AAL_1;
1483                 pseudo_header->atm.type = TRAF_UNKNOWN;
1484                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1485                 break;
1486
1487         case ATT_AAL3_4:
1488                 pseudo_header->atm.aal = AAL_3_4;
1489                 pseudo_header->atm.type = TRAF_UNKNOWN;
1490                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1491                 break;
1492
1493         case ATT_AAL5:
1494                 pseudo_header->atm.aal = AAL_5;
1495                 switch (hl_type) {
1496
1497                 case ATT_HL_UNKNOWN:
1498                         pseudo_header->atm.type = TRAF_UNKNOWN;
1499                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1500                         break;
1501
1502                 case ATT_HL_LLCMX:
1503                         pseudo_header->atm.type = TRAF_LLCMX;
1504                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1505                         break;
1506
1507                 case ATT_HL_VCMX:
1508                         pseudo_header->atm.type = TRAF_VCMX;
1509                         switch (frame4->atm_info.AppHLType) {
1510
1511                         case AHLT_UNKNOWN:
1512                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1513                                 break;
1514
1515                         case AHLT_VCMX_802_3_FCS:
1516                                 pseudo_header->atm.subtype =
1517                                     TRAF_ST_VCMX_802_3_FCS;
1518                                 break;
1519
1520                         case AHLT_VCMX_802_4_FCS:
1521                                 pseudo_header->atm.subtype =
1522                                     TRAF_ST_VCMX_802_4_FCS;
1523                                 break;
1524
1525                         case AHLT_VCMX_802_5_FCS:
1526                                 pseudo_header->atm.subtype =
1527                                     TRAF_ST_VCMX_802_5_FCS;
1528                                 break;
1529
1530                         case AHLT_VCMX_FDDI_FCS:
1531                                 pseudo_header->atm.subtype =
1532                                     TRAF_ST_VCMX_FDDI_FCS;
1533                                 break;
1534
1535                         case AHLT_VCMX_802_6_FCS:
1536                                 pseudo_header->atm.subtype =
1537                                     TRAF_ST_VCMX_802_6_FCS;
1538                                 break;
1539
1540                         case AHLT_VCMX_802_3:
1541                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_802_3;
1542                                 break;
1543
1544                         case AHLT_VCMX_802_4:
1545                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_802_4;
1546                                 break;
1547
1548                         case AHLT_VCMX_802_5:
1549                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_802_5;
1550                                 break;
1551
1552                         case AHLT_VCMX_FDDI:
1553                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_FDDI;
1554                                 break;
1555
1556                         case AHLT_VCMX_802_6:
1557                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_802_6;
1558                                 break;
1559
1560                         case AHLT_VCMX_FRAGMENTS:
1561                                 pseudo_header->atm.subtype =
1562                                     TRAF_ST_VCMX_FRAGMENTS;
1563                                 break;
1564
1565                         case AHLT_VCMX_BPDU:
1566                                 pseudo_header->atm.subtype = TRAF_ST_VCMX_BPDU;
1567                                 break;
1568
1569                         default:
1570                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1571                                 break;
1572                         }
1573                         break;
1574
1575                 case ATT_HL_LANE:
1576                         pseudo_header->atm.type = TRAF_LANE;
1577                         switch (frame4->atm_info.AppHLType) {
1578
1579                         case AHLT_UNKNOWN:
1580                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1581                                 break;
1582
1583                         case AHLT_LANE_LE_CTRL:
1584                                 pseudo_header->atm.subtype =
1585                                     TRAF_ST_LANE_LE_CTRL;
1586                                 break;
1587
1588                         case AHLT_LANE_802_3:
1589                                 pseudo_header->atm.subtype = TRAF_ST_LANE_802_3;
1590                                 break;
1591
1592                         case AHLT_LANE_802_5:
1593                                 pseudo_header->atm.subtype = TRAF_ST_LANE_802_5;
1594                                 break;
1595
1596                         case AHLT_LANE_802_3_MC:
1597                                 pseudo_header->atm.subtype =
1598                                     TRAF_ST_LANE_802_3_MC;
1599                                 break;
1600
1601                         case AHLT_LANE_802_5_MC:
1602                                 pseudo_header->atm.subtype =
1603                                     TRAF_ST_LANE_802_5_MC;
1604                                 break;
1605
1606                         default:
1607                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1608                                 break;
1609                         }
1610                         break;
1611
1612                 case ATT_HL_ILMI:
1613                         pseudo_header->atm.type = TRAF_ILMI;
1614                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1615                         break;
1616
1617                 case ATT_HL_FRMR:
1618                         pseudo_header->atm.type = TRAF_FR;
1619                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1620                         break;
1621
1622                 case ATT_HL_SPANS:
1623                         pseudo_header->atm.type = TRAF_SPANS;
1624                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1625                         break;
1626
1627                 case ATT_HL_IPSILON:
1628                         pseudo_header->atm.type = TRAF_IPSILON;
1629                         switch (frame4->atm_info.AppHLType) {
1630
1631                         case AHLT_UNKNOWN:
1632                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1633                                 break;
1634
1635                         case AHLT_IPSILON_FT0:
1636                                 pseudo_header->atm.subtype =
1637                                     TRAF_ST_IPSILON_FT0;
1638                                 break;
1639
1640                         case AHLT_IPSILON_FT1:
1641                                 pseudo_header->atm.subtype =
1642                                     TRAF_ST_IPSILON_FT1;
1643                                 break;
1644
1645                         case AHLT_IPSILON_FT2:
1646                                 pseudo_header->atm.subtype =
1647                                     TRAF_ST_IPSILON_FT2;
1648                                 break;
1649
1650                         default:
1651                                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1652                                 break;
1653                         }
1654                         break;
1655
1656                 default:
1657                         pseudo_header->atm.type = TRAF_UNKNOWN;
1658                         pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1659                         break;
1660                 }
1661                 break;
1662
1663         case ATT_AAL_USER:
1664                 pseudo_header->atm.aal = AAL_USER;
1665                 pseudo_header->atm.type = TRAF_UNKNOWN;
1666                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1667                 break;
1668
1669         case ATT_AAL_SIGNALLING:
1670                 pseudo_header->atm.aal = AAL_SIGNALLING;
1671                 pseudo_header->atm.type = TRAF_UNKNOWN;
1672                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1673                 break;
1674
1675         case ATT_OAMCELL:
1676                 pseudo_header->atm.aal = AAL_OAMCELL;
1677                 pseudo_header->atm.type = TRAF_UNKNOWN;
1678                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1679                 break;
1680
1681         default:
1682                 pseudo_header->atm.aal = AAL_UNKNOWN;
1683                 pseudo_header->atm.type = TRAF_UNKNOWN;
1684                 pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
1685                 break;
1686         }
1687         pseudo_header->atm.vpi = vpi;
1688         pseudo_header->atm.vci = vci;
1689         pseudo_header->atm.channel = pletohs(&frame4->atm_info.channel);
1690         pseudo_header->atm.cells = pletohs(&frame4->atm_info.cells);
1691         pseudo_header->atm.aal5t_u2u = pletohs(&frame4->atm_info.Trailer.aal5t_u2u);
1692         pseudo_header->atm.aal5t_len = pletohs(&frame4->atm_info.Trailer.aal5t_len);
1693         pseudo_header->atm.aal5t_chksum = pntohl(&frame4->atm_info.Trailer.aal5t_chksum);
1694 }
1695
1696 static gboolean ngsniffer_read_frame6(wtap *wth, gboolean is_random,
1697     struct frame6_rec *frame6, int *err)
1698 {
1699         gint64 bytes_read;
1700
1701         /* Read the f_frame6_struct */
1702         bytes_read = ng_file_read(frame6, 1, sizeof *frame6, wth, is_random,
1703             err);
1704         if (bytes_read != sizeof *frame6) {
1705                 if (*err == 0)
1706                         *err = WTAP_ERR_SHORT_READ;
1707                 return FALSE;
1708         }
1709         return TRUE;
1710 }
1711
1712 static void set_pseudo_header_frame6(wtap *wth,
1713         union wtap_pseudo_header *pseudo_header,
1714         struct frame6_rec *frame6 _U_)
1715 {
1716         /* XXX - Once the frame format is divined, something will most likely go here */
1717
1718         switch (wth->file_encap) {
1719
1720         case WTAP_ENCAP_ETHERNET:
1721                 /* XXX - is there an FCS? */
1722                 pseudo_header->eth.fcs_len = -1;
1723                 break;
1724         }
1725 }
1726
1727 static gboolean ngsniffer_read_rec_data(wtap *wth, gboolean is_random,
1728     guchar *pd, size_t length, int *err)
1729 {
1730         gint64  bytes_read;
1731
1732         bytes_read = ng_file_read(pd, 1, length, wth, is_random, err);
1733
1734         if (bytes_read != (gint64) length) {
1735                 if (*err == 0)
1736                         *err = WTAP_ERR_SHORT_READ;
1737                 return FALSE;
1738         }
1739         return TRUE;
1740 }
1741
1742 /*
1743  * OK, this capture is from an "Internetwork analyzer", and we either
1744  * didn't see a type 7 record or it had a network type such as NET_HDLC
1745  * that doesn't tell us which *particular* HDLC derivative this is;
1746  * let's look at the first few bytes of the packet, a pointer to which
1747  * was passed to us as an argument, and see whether it looks like PPP,
1748  * Frame Relay, Wellfleet HDLC, Cisco HDLC, or LAPB - or, if it's none
1749  * of those, assume it's LAPD.
1750  *
1751  * (XXX - are there any "Internetwork analyzer" captures that don't
1752  * have type 7 records?  If so, is there some other field that will
1753  * tell us what type of capture it is?)
1754  */
1755 static int infer_pkt_encap(const guint8 *pd, int len)
1756 {
1757         int i;
1758
1759         if (len <= 0) {
1760                 /*
1761                  * Nothing to infer, but it doesn't matter how you
1762                  * dissect an empty packet.  Let's just say PPP.
1763                  */
1764                 return WTAP_ENCAP_PPP_WITH_PHDR;
1765         }
1766
1767         if (pd[0] == 0xFF) {
1768                 /*
1769                  * PPP.  (XXX - check for 0xFF 0x03?)
1770                  */
1771                 return WTAP_ENCAP_PPP_WITH_PHDR;
1772         }
1773
1774         if (len >= 2) {
1775                 if (pd[0] == 0x07 && pd[1] == 0x03) {
1776                         /*
1777                          * Wellfleet HDLC.
1778                          */
1779                         return WTAP_ENCAP_WFLEET_HDLC;
1780                 } else if ((pd[0] == 0x0F && pd[1] == 0x00) ||
1781                            (pd[0] == 0x8F && pd[1] == 0x00)) {
1782                         /*
1783                          * Cisco HDLC.
1784                          */
1785                         return WTAP_ENCAP_CHDLC_WITH_PHDR;
1786                 }
1787
1788                 /*
1789                  * Check for Frame Relay.  Look for packets with at least
1790                  * 3 bytes of header - 2 bytes of DLCI followed by 1 byte
1791                  * of control, which, for now, we require to be 0x03 (UI),
1792                  * although there might be other frame types as well.
1793                  * Scan forward until we see the last DLCI byte, with
1794                  * the low-order bit being 1, and then check the next
1795                  * byte to see if it's a control byte.
1796                  *
1797                  * XXX - in version 4 and 5 captures, wouldn't this just
1798                  * have a capture subtype of NET_FRAME_RELAY?  Or is this
1799                  * here only to handle other versions of the capture
1800                  * file, where we might just not yet have found where
1801                  * the subtype is specified in the capture?
1802                  *
1803                  * Bay^H^H^HNortel Networks has a mechanism in the Optivity
1804                  * software for some of their routers to save captures
1805                  * in Sniffer format; they use a version number of 4.9, but
1806                  * don't put out any header records before the first FRAME2
1807                  * record.  That means we have to use heuristics to guess
1808                  * what type of packet we have.
1809                  */
1810                 for (i = 0; i < len && (pd[i] & 0x01) == 0; i++)
1811                         ;
1812                 i++;    /* advance to the byte after the last DLCI byte */
1813                 if (i == len) {
1814                         /*
1815                          * No control byte.
1816                          */
1817                         return WTAP_ENCAP_LAPB;
1818                 }
1819                 if (pd[i] == 0x03)
1820                         return WTAP_ENCAP_FRELAY_WITH_PHDR;
1821         }
1822
1823         /*
1824          * Assume LAPB, for now.  If we support other HDLC encapsulations,
1825          * we can check whether the low-order bit of the first byte is
1826          * set (as it should be for LAPB) if no other checks pass.
1827          *
1828          * Or, if it's truly impossible to distinguish ISDN from non-ISDN
1829          * captures, we could assume it's ISDN if it's not anything
1830          * else.
1831          */
1832         return WTAP_ENCAP_LAPB;
1833 }
1834
1835 static int fix_pseudo_header(int encap, const guint8 *pd, int len,
1836     union wtap_pseudo_header *pseudo_header)
1837 {
1838         switch (encap) {
1839
1840         case WTAP_ENCAP_PER_PACKET:
1841                 /*
1842                  * Infer the packet type from the first two bytes.
1843                  */
1844                 encap = infer_pkt_encap(pd, len);
1845
1846                 /*
1847                  * Fix up the pseudo-header to match the new
1848                  * encapsulation type.
1849                  */
1850                 switch (encap) {
1851
1852                 case WTAP_ENCAP_WFLEET_HDLC:
1853                 case WTAP_ENCAP_CHDLC_WITH_PHDR:
1854                 case WTAP_ENCAP_PPP_WITH_PHDR:
1855                         if (pseudo_header->x25.flags == 0)
1856                                 pseudo_header->p2p.sent = TRUE;
1857                         else
1858                                 pseudo_header->p2p.sent = FALSE;
1859                         break;
1860
1861                 case WTAP_ENCAP_ISDN:
1862                         if (pseudo_header->x25.flags == 0x00)
1863                                 pseudo_header->isdn.uton = FALSE;
1864                         else
1865                                 pseudo_header->isdn.uton = TRUE;
1866
1867                         /*
1868                          * XXX - this is currently a per-packet
1869                          * encapsulation type, and we can't determine
1870                          * whether a capture is an ISDN capture before
1871                          * seeing any packets, and B-channel PPP packets
1872                          * look like PPP packets and are given
1873                          * WTAP_ENCAP_PPP_WITH_PHDR, not WTAP_ENCAP_ISDN,
1874                          * so we assume this is a D-channel packet and
1875                          * thus give it a channel number of 0.
1876                          */
1877                         pseudo_header->isdn.channel = 0;
1878                         break;
1879                 }
1880                 break;
1881
1882         case WTAP_ENCAP_ATM_PDUS:
1883                 /*
1884                  * If the Windows Sniffer writes out one of its ATM
1885                  * capture files in DOS Sniffer format, it doesn't
1886                  * distinguish between LE Control and LANE encapsulated
1887                  * LAN frames, it just marks them as LAN frames,
1888                  * so we fix that up here.
1889                  *
1890                  * I've also seen DOS Sniffer captures claiming that
1891                  * LANE packets that *don't* start with FF 00 are
1892                  * marked as LE Control frames, so we fix that up
1893                  * as well.
1894                  */
1895                 if (pseudo_header->atm.type == TRAF_LANE && len >= 2) {
1896                         if (pd[0] == 0xff && pd[1] == 0x00) {
1897                                 /*
1898                                  * This must be LE Control.
1899                                  */
1900                                 pseudo_header->atm.subtype =
1901                                     TRAF_ST_LANE_LE_CTRL;
1902                         } else {
1903                                 /*
1904                                  * This can't be LE Control.
1905                                  */
1906                                 if (pseudo_header->atm.subtype ==
1907                                     TRAF_ST_LANE_LE_CTRL) {
1908                                         /*
1909                                          * XXX - Ethernet or Token Ring?
1910                                          */
1911                                         pseudo_header->atm.subtype =
1912                                             TRAF_ST_LANE_802_3;
1913                                 }
1914                         }
1915                 }
1916                 break;
1917         }
1918         return encap;
1919 }
1920
1921 /* Throw away the buffers used by the sequential I/O stream, but not
1922    those used by the random I/O stream. */
1923 static void ngsniffer_sequential_close(wtap *wth)
1924 {
1925         if (wth->capture.ngsniffer->seq.buf != NULL) {
1926                 g_free(wth->capture.ngsniffer->seq.buf);
1927                 wth->capture.ngsniffer->seq.buf = NULL;
1928         }
1929 }
1930
1931 static void free_blob(gpointer data, gpointer user_data _U_)
1932 {
1933         g_free(data);
1934 }
1935
1936 /* Close stuff used by the random I/O stream, if any, and free up any
1937    private data structures.  (If there's a "sequential_close" routine
1938    for a capture file type, it'll be called before the "close" routine
1939    is called, so we don't have to free the sequential buffer here.) */
1940 static void ngsniffer_close(wtap *wth)
1941 {
1942         if (wth->capture.ngsniffer->rand.buf != NULL)
1943                 g_free(wth->capture.ngsniffer->rand.buf);
1944         if (wth->capture.ngsniffer->first_blob != NULL) {
1945                 g_list_foreach(wth->capture.ngsniffer->first_blob, free_blob, NULL);
1946                 g_list_free(wth->capture.ngsniffer->first_blob);
1947         }
1948         g_free(wth->capture.ngsniffer);
1949 }
1950
1951 static const int wtap_encap[] = {
1952     -1,         /* WTAP_ENCAP_UNKNOWN -> unsupported */
1953     1,          /* WTAP_ENCAP_ETHERNET */
1954     0,          /* WTAP_ENCAP_TOKEN_RING */
1955     -1,         /* WTAP_ENCAP_SLIP -> unsupported */
1956     7,          /* WTAP_ENCAP_PPP -> Internetwork analyzer (synchronous) FIXME ! */
1957     9,          /* WTAP_ENCAP_FDDI */
1958     9,          /* WTAP_ENCAP_FDDI_BITSWAPPED */
1959     -1,         /* WTAP_ENCAP_RAW_IP -> unsupported */
1960     2,          /* WTAP_ENCAP_ARCNET */
1961     -1,         /* WTAP_ENCAP_ATM_RFC1483 */
1962     -1,         /* WTAP_ENCAP_LINUX_ATM_CLIP */
1963     7,          /* WTAP_ENCAP_LAPB -> Internetwork analyzer (synchronous) */
1964     -1,         /* WTAP_ENCAP_ATM_PDUS */
1965     -1,         /* WTAP_ENCAP_NULL -> unsupported */
1966     -1,         /* WTAP_ENCAP_ASCEND -> unsupported */
1967     -1,         /* WTAP_ENCAP_ISDN -> unsupported */
1968     -1,         /* WTAP_ENCAP_IP_OVER_FC -> unsupported */
1969     7,          /* WTAP_ENCAP_PPP_WITH_PHDR -> Internetwork analyzer (synchronous) FIXME ! */
1970 };
1971 #define NUM_WTAP_ENCAPS (sizeof wtap_encap / sizeof wtap_encap[0])
1972
1973 /* Returns 0 if we could write the specified encapsulation type,
1974    an error indication otherwise. */
1975 int ngsniffer_dump_can_write_encap(int encap)
1976 {
1977     /* Per-packet encapsulations aren't supported. */
1978     if (encap == WTAP_ENCAP_PER_PACKET)
1979         return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
1980
1981     if (encap < 0 || (unsigned)encap >= NUM_WTAP_ENCAPS || wtap_encap[encap] == -1)
1982         return WTAP_ERR_UNSUPPORTED_ENCAP;
1983
1984     return 0;
1985 }
1986
1987 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1988    failure */
1989 gboolean ngsniffer_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
1990 {
1991     size_t nwritten;
1992     char buf[6] = {REC_VERS, 0x00, 0x12, 0x00, 0x00, 0x00}; /* version record */
1993
1994     /* This is a sniffer file */
1995     wdh->subtype_write = ngsniffer_dump;
1996     wdh->subtype_close = ngsniffer_dump_close;
1997
1998     wdh->dump.ngsniffer = g_malloc(sizeof(ngsniffer_dump_t));
1999     wdh->dump.ngsniffer->first_frame = TRUE;
2000     wdh->dump.ngsniffer->start = 0;
2001
2002     /* Write the file header. */
2003     nwritten = fwrite(ngsniffer_magic, 1, sizeof ngsniffer_magic, wdh->fh);
2004     if (nwritten != sizeof ngsniffer_magic) {
2005         if (nwritten == 0 && ferror(wdh->fh))
2006             *err = errno;
2007         else
2008             *err = WTAP_ERR_SHORT_WRITE;
2009         return FALSE;
2010     }
2011     nwritten = fwrite(buf, 1, 6, wdh->fh);
2012     if (nwritten != 6) {
2013         if (nwritten == 0 && ferror(wdh->fh))
2014             *err = errno;
2015         else
2016             *err = WTAP_ERR_SHORT_WRITE;
2017         return FALSE;
2018     }
2019
2020     return TRUE;
2021 }
2022
2023 /* Write a record for a packet to a dump file.
2024    Returns TRUE on success, FALSE on failure. */
2025 static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2026     const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err)
2027 {
2028     ngsniffer_dump_t *priv = wdh->dump.ngsniffer;
2029     struct frame2_rec rec_hdr;
2030     size_t nwritten;
2031     char buf[6];
2032     time_t tsecs;
2033     guint64 t;
2034     guint16 t_low, t_med;
2035     guint8 t_high;
2036     struct vers_rec version;
2037     gint16 maj_vers, min_vers;
2038     guint16 start_date;
2039     struct tm *tm;
2040
2041     /* Sniffer files have a capture start date in the file header, and
2042        have times relative to the beginning of that day in the packet
2043        headers; pick the date of the first packet as the capture start
2044        date. */
2045     if (priv->first_frame) {
2046         priv->first_frame=FALSE;
2047         tm = localtime(&phdr->ts.secs);
2048         if (tm != NULL) {
2049           start_date = (tm->tm_year - (1980 - 1900)) << 9;
2050           start_date |= (tm->tm_mon + 1) << 5;
2051           start_date |= tm->tm_mday;
2052           /* record the start date, not the start time */
2053           priv->start = phdr->ts.secs - (3600*tm->tm_hour + 60*tm->tm_min + tm->tm_sec);
2054         } else {
2055           start_date = 0;
2056           priv->start = 0;
2057         }
2058
2059         /* "sniffer" version ? */
2060         maj_vers = 4;
2061         min_vers = 0;
2062         version.maj_vers = htoles(maj_vers);
2063         version.min_vers = htoles(min_vers);
2064         version.time = 0;
2065         version.date = htoles(start_date);
2066         version.type = 4;
2067         version.network = wtap_encap[wdh->encap];
2068         version.format = 1;
2069         version.timeunit = 1; /* 0.838096 */
2070         version.cmprs_vers = 0;
2071         version.cmprs_level = 0;
2072         version.rsvd[0] = 0;
2073         version.rsvd[1] = 0;
2074         nwritten = fwrite(&version, 1, sizeof version, wdh->fh);
2075         if (nwritten != sizeof version) {
2076             if (nwritten == 0 && ferror(wdh->fh))
2077                 *err = errno;
2078             else
2079                 *err = WTAP_ERR_SHORT_WRITE;
2080             return FALSE;
2081         }
2082     }
2083
2084     buf[0] = REC_FRAME2;
2085     buf[1] = 0x00;
2086     buf[2] = (char)((phdr->caplen + sizeof(struct frame2_rec))%256);
2087     buf[3] = (char)((phdr->caplen + sizeof(struct frame2_rec))/256);
2088     buf[4] = 0x00;
2089     buf[5] = 0x00;
2090     nwritten = fwrite(buf, 1, 6, wdh->fh);
2091     if (nwritten != 6) {
2092         if (nwritten == 0 && ferror(wdh->fh))
2093             *err = errno;
2094         else
2095             *err = WTAP_ERR_SHORT_WRITE;
2096         return FALSE;
2097     }
2098     /* Seconds since the start of the capture */
2099     tsecs = phdr->ts.secs - priv->start;
2100     /* Extract the number of days since the start of the capture */
2101     rec_hdr.time_day = (guint8)(tsecs / 86400); /* # days of capture - 86400 secs/day */
2102     tsecs -= rec_hdr.time_day * 86400;  /* time within day */
2103     /* Convert to picoseconds */
2104     t = tsecs*G_GINT64_CONSTANT(1000000000000U) +
2105         phdr->ts.nsecs*G_GINT64_CONSTANT(1000U);
2106     /* Convert to units of timeunit = 1 */
2107     t /= Psec[1];
2108     t_low = (guint16)((t >> 0) & 0xFFFF);
2109     t_med = (guint16)((t >> 16) & 0xFFFF);
2110     t_high = (guint8)((t >> 32) & 0xFF);
2111     rec_hdr.time_low = htoles(t_low);
2112     rec_hdr.time_med = htoles(t_med);
2113     rec_hdr.time_high = t_high;
2114     rec_hdr.size = htoles(phdr->caplen);
2115     switch (wdh->encap) {
2116
2117     case WTAP_ENCAP_LAPB:
2118     case WTAP_ENCAP_FRELAY_WITH_PHDR:
2119         rec_hdr.fs = (pseudo_header->x25.flags & FROM_DCE) ? 0x00 : FS_WAN_DTE;
2120         break;
2121
2122     case WTAP_ENCAP_PPP_WITH_PHDR:
2123     case WTAP_ENCAP_SDLC:
2124         rec_hdr.fs = pseudo_header->p2p.sent ? 0x00 : FS_WAN_DTE;
2125         break;
2126
2127     case WTAP_ENCAP_ISDN:
2128         rec_hdr.fs = pseudo_header->isdn.uton ? FS_WAN_DTE : 0x00;
2129         switch (pseudo_header->isdn.channel) {
2130
2131         case 0:         /* D-channel */
2132             rec_hdr.fs |= FS_ISDN_CHAN_D;
2133             break;
2134
2135         case 1:         /* B1-channel */
2136             rec_hdr.fs |= FS_ISDN_CHAN_B1;
2137             break;
2138
2139         case 2:         /* B2-channel */
2140             rec_hdr.fs |= FS_ISDN_CHAN_B2;
2141             break;
2142         }
2143         break;
2144
2145     default:
2146         rec_hdr.fs = 0;
2147         break;
2148     }
2149     rec_hdr.flags = 0;
2150     rec_hdr.true_size = phdr->len != phdr->caplen ? htoles(phdr->len) : 0;
2151     rec_hdr.rsvd = 0;
2152     nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, wdh->fh);
2153     if (nwritten != sizeof rec_hdr) {
2154         if (nwritten == 0 && ferror(wdh->fh))
2155             *err = errno;
2156         else
2157             *err = WTAP_ERR_SHORT_WRITE;
2158         return FALSE;
2159     }
2160     nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
2161     if (nwritten != phdr->caplen) {
2162         if (nwritten == 0 && ferror(wdh->fh))
2163             *err = errno;
2164         else
2165             *err = WTAP_ERR_SHORT_WRITE;
2166         return FALSE;
2167     }
2168     return TRUE;
2169 }
2170
2171 /* Finish writing to a dump file.
2172    Returns TRUE on success, FALSE on failure. */
2173 static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err)
2174 {
2175     /* EOF record */
2176     char buf[6] = {REC_EOF, 0x00, 0x00, 0x00, 0x00, 0x00};
2177     size_t nwritten;
2178
2179     nwritten = fwrite(buf, 1, 6, wdh->fh);
2180     if (nwritten != 6) {
2181         if (err != NULL) {
2182             if (nwritten == 0 && ferror(wdh->fh))
2183                 *err = errno;
2184             else
2185                 *err = WTAP_ERR_SHORT_WRITE;
2186         }
2187         return FALSE;
2188     }
2189     return TRUE;
2190 }
2191
2192 /*
2193    SnifferDecompress() decompresses a blob of compressed data from a
2194          Sniffer(R) capture file.
2195
2196    This function is Copyright (c) 1999-2999 Tim Farley
2197
2198    Parameters
2199       inbuf - buffer of compressed bytes from file, not including
2200          the preceding length word
2201       inlen - length of inbuf in bytes (max 64k)
2202       outbuf - decompressed contents, could contain a partial Sniffer
2203          record at the end.
2204       outlen - length of outbuf.
2205
2206    Return value is the number of bytes in outbuf on return.
2207 */
2208 static int
2209 SnifferDecompress( unsigned char * inbuf, size_t inlen,
2210                        unsigned char * outbuf, size_t outlen, int *err )
2211 {
2212    unsigned char * pin = inbuf;
2213    unsigned char * pout = outbuf;
2214    unsigned char * pin_end = pin + inlen;
2215    unsigned char * pout_end = pout + outlen;
2216    unsigned int bit_mask;  /* one bit is set in this, to mask with bit_value */
2217    unsigned int bit_value = 0; /* cache the last 16 coding bits we retrieved */
2218    unsigned int code_type; /* encoding type, from high 4 bits of byte */
2219    unsigned int code_low;  /* other 4 bits from encoding byte */
2220    int length;             /* length of RLE sequence or repeated string */
2221    int offset;             /* offset of string to repeat */
2222
2223    if (inlen > G_MAXUINT16) {
2224       return ( -1 );
2225    }
2226
2227    bit_mask  = 0;  /* don't have any bits yet */
2228    while (1)
2229    {
2230       /* Shift down the bit mask we use to see whats encoded */
2231       bit_mask = bit_mask >> 1;
2232
2233       /* If there are no bits left, time to get another 16 bits */
2234       if ( 0 == bit_mask )
2235       {
2236          bit_mask  = 0x8000;  /* start with the high bit */
2237          bit_value = pletohs(pin);   /* get the next 16 bits */
2238          pin += 2;          /* skip over what we just grabbed */
2239          if ( pin >= pin_end )
2240          {
2241             *err = WTAP_ERR_UNC_TRUNCATED;       /* data was oddly truncated */
2242             return ( -1 );
2243          }
2244       }
2245
2246       /* Use the bits in bit_value to see what's encoded and what is raw data */
2247       if ( !(bit_mask & bit_value) )
2248       {
2249          /* bit not set - raw byte we just copy */
2250          *(pout++) = *(pin++);
2251       }
2252       else
2253       {
2254          /* bit set - next item is encoded.  Peel off high nybble
2255             of next byte to see the encoding type.  Set aside low
2256             nybble while we are at it */
2257          code_type = (unsigned int) ((*pin) >> 4 ) & 0xF;
2258          code_low  = (unsigned int) ((*pin) & 0xF );
2259          pin++;   /* increment over the code byte we just retrieved */
2260          if ( pin >= pin_end )
2261          {
2262             *err = WTAP_ERR_UNC_TRUNCATED;       /* data was oddly truncated */
2263             return ( -1 );
2264          }
2265
2266          /* Based on the code type, decode the compressed string */
2267          switch ( code_type )
2268          {
2269             case 0  :   /* RLE short runs */
2270                 /*
2271                     Run length is the low nybble of the first code byte.
2272                     Byte to repeat immediately follows.
2273                     Total code size: 2 bytes.
2274                 */
2275                 length = code_low + 3;
2276                 /* If length would put us past end of output, avoid overflow */
2277                 if ( pout + length > pout_end )
2278                 {
2279                     *err = WTAP_ERR_UNC_OVERFLOW;
2280                     return ( -1 );
2281                 }
2282
2283                 /* generate the repeated series of bytes */
2284                 memset( pout, *pin++, length );
2285                 pout += length;
2286                 break;
2287             case 1  :   /* RLE long runs */
2288                 /*
2289                     Low 4 bits of run length is the low nybble of the
2290                     first code byte, upper 8 bits of run length is in
2291                     the next byte.
2292                     Byte to repeat immediately follows.
2293                     Total code size: 3 bytes.
2294                 */
2295                 length = code_low + ((unsigned int)(*pin++) << 4) + 19;
2296                 /* If we are already at end of input, there is no byte
2297                    to repeat */
2298                 if ( pin >= pin_end )
2299                 {
2300                     *err = WTAP_ERR_UNC_TRUNCATED;       /* data was oddly truncated */
2301                     return ( -1 );
2302                 }
2303                 /* If length would put us past end of output, avoid overflow */
2304                 if ( pout + length > pout_end )
2305                 {
2306                     *err = WTAP_ERR_UNC_OVERFLOW;
2307                     return ( -1 );
2308                 }
2309
2310                 /* generate the repeated series of bytes */
2311                 memset( pout, *pin++, length );
2312                 pout += length;
2313                 break;
2314             case 2  :   /* LZ77 long strings */
2315                 /*
2316                     Low 4 bits of offset to string is the low nybble of the
2317                     first code byte, upper 8 bits of offset is in
2318                     the next byte.
2319                     Length of string immediately follows.
2320                     Total code size: 3 bytes.
2321                 */
2322                 offset = code_low + ((unsigned int)(*pin++) << 4) + 3;
2323                 /* If we are already at end of input, there is no byte
2324                    to repeat */
2325                 if ( pin >= pin_end )
2326                 {
2327                     *err = WTAP_ERR_UNC_TRUNCATED;       /* data was oddly truncated */
2328                     return ( -1 );
2329                 }
2330                 /* Check if offset would put us back past begin of buffer */
2331                 if ( pout - offset < outbuf )
2332                 {
2333                     *err = WTAP_ERR_UNC_BAD_OFFSET;
2334                     return ( -1 );
2335                 }
2336
2337                 /* get length from next byte, make sure it won't overrun buf */
2338                 length = (unsigned int)(*pin++) + 16;
2339                 if ( pout + length > pout_end )
2340                 {
2341                     *err = WTAP_ERR_UNC_OVERFLOW;
2342                     return ( -1 );
2343                 }
2344
2345                 /* Copy the string from previous text to output position,
2346                    advance output pointer */
2347                 memcpy( pout, pout - offset, length );
2348                 pout += length;
2349                 break;
2350             default :   /* (3 to 15): LZ77 short strings */
2351                 /*
2352                     Low 4 bits of offset to string is the low nybble of the
2353                     first code byte, upper 8 bits of offset is in
2354                     the next byte.
2355                     Length of string to repeat is overloaded into code_type.
2356                     Total code size: 2 bytes.
2357                 */
2358                 offset = code_low + ((unsigned int)(*pin++) << 4) + 3;
2359                 /* Check if offset would put us back past begin of buffer */
2360                 if ( pout - offset < outbuf )
2361                 {
2362                     *err = WTAP_ERR_UNC_BAD_OFFSET;
2363                     return ( -1 );
2364                 }
2365
2366                 /* get length from code_type, make sure it won't overrun buf */
2367                 length = code_type;
2368                 if ( pout + length > pout_end )
2369                 {
2370                     *err = WTAP_ERR_UNC_OVERFLOW;
2371                     return ( -1 );
2372                 }
2373
2374                 /* Copy the string from previous text to output position,
2375                    advance output pointer */
2376                 memcpy( pout, pout - offset, length );
2377                 pout += length;
2378                 break;
2379          }
2380       }
2381
2382       /* If we've consumed all the input, we are done */
2383       if ( pin >= pin_end )
2384          break;
2385    }
2386
2387    return (int) ( pout - outbuf );  /* return length of expanded text */
2388 }
2389
2390 /*
2391  * XXX - is there any guarantee that this is big enough to hold the
2392  * uncompressed data from any blob?
2393  */
2394 #define OUTBUF_SIZE     65536
2395
2396 /* Information about a compressed blob; we save the offset in the
2397    underlying compressed file, and the offset in the uncompressed data
2398    stream, of the blob. */
2399 typedef struct {
2400         gint64  blob_comp_offset;
2401         gint64  blob_uncomp_offset;
2402 } blob_info_t;
2403
2404 static gint64
2405 ng_file_read(void *buffer, size_t elementsize, size_t numelements, wtap *wth,
2406     gboolean is_random, int *err)
2407 {
2408     FILE_T infile;
2409     ngsniffer_comp_stream_t *comp_stream;
2410     size_t copybytes = elementsize * numelements; /* bytes left to be copied */
2411     gint64 copied_bytes = 0; /* bytes already copied */
2412     unsigned char *outbuffer = buffer; /* where to write next decompressed data */
2413     blob_info_t *blob;
2414     size_t bytes_to_copy;
2415     size_t bytes_left;
2416
2417     if (is_random) {
2418         infile = wth->random_fh;
2419         comp_stream = &wth->capture.ngsniffer->rand;
2420     } else {
2421         infile = wth->fh;
2422         comp_stream = &wth->capture.ngsniffer->seq;
2423     }
2424
2425     if (wth->file_type == WTAP_FILE_NGSNIFFER_UNCOMPRESSED) {
2426         errno = WTAP_ERR_CANT_READ;
2427         copied_bytes = file_read(buffer, 1, copybytes, infile);
2428         if ((size_t) copied_bytes != copybytes)
2429             *err = file_error(infile);
2430         return copied_bytes;
2431     }
2432
2433     /* Allocate the stream buffer if it hasn't already been allocated. */
2434     if (comp_stream->buf == NULL) {
2435         comp_stream->buf = g_malloc(OUTBUF_SIZE);
2436
2437         if (is_random) {
2438             /* This is the first read of the random file, so we're at
2439                the beginning of the sequence of blobs in the file
2440                (as we've not done any random reads yet to move the
2441                current position in the random stream); set the
2442                current blob to be the first blob. */
2443             wth->capture.ngsniffer->current_blob =
2444                 wth->capture.ngsniffer->first_blob;
2445         } else {
2446             /* This is the first sequential read; if we also have a
2447                random stream open, allocate the first element for the
2448                list of blobs, and make it the last element as well. */
2449             if (wth->random_fh != NULL) {
2450                 g_assert(wth->capture.ngsniffer->first_blob == NULL);
2451                 blob = g_malloc(sizeof (blob_info_t));
2452                 blob->blob_comp_offset = comp_stream->comp_offset;
2453                 blob->blob_uncomp_offset = comp_stream->uncomp_offset;
2454                 wth->capture.ngsniffer->first_blob =
2455                         g_list_append(wth->capture.ngsniffer->first_blob, blob);
2456                 wth->capture.ngsniffer->last_blob =
2457                         wth->capture.ngsniffer->first_blob;
2458             }
2459         }
2460
2461         /* Now read the first blob into the buffer. */
2462         if (read_blob(infile, comp_stream, err) < 0)
2463             return -1;
2464     }
2465     while (copybytes > 0) {
2466         bytes_left = comp_stream->nbytes - comp_stream->nextout;
2467         if (bytes_left == 0) {
2468             /* There's no decompressed stuff left to copy from the current
2469                blob; get the next blob. */
2470
2471             if (is_random) {
2472                 /* Move to the next blob in the list. */
2473                 wth->capture.ngsniffer->current_blob =
2474                         g_list_next(wth->capture.ngsniffer->current_blob);
2475                 blob = wth->capture.ngsniffer->current_blob->data;
2476             } else {
2477                 /* If we also have a random stream open, add a new element,
2478                    for this blob, to the list of blobs; we know the list is
2479                    non-empty, as we initialized it on the first sequential
2480                    read, so we just add the new element at the end, and
2481                    adjust the pointer to the last element to refer to it. */
2482                 if (wth->random_fh != NULL) {
2483                     blob = g_malloc(sizeof (blob_info_t));
2484                     blob->blob_comp_offset = comp_stream->comp_offset;
2485                     blob->blob_uncomp_offset = comp_stream->uncomp_offset;
2486                     wth->capture.ngsniffer->last_blob =
2487                         g_list_append(wth->capture.ngsniffer->last_blob, blob);
2488                 }
2489             }
2490
2491             if (read_blob(infile, comp_stream, err) < 0)
2492                 return -1;
2493             bytes_left = comp_stream->nbytes - comp_stream->nextout;
2494         }
2495
2496         bytes_to_copy = copybytes;
2497         if (bytes_to_copy > bytes_left)
2498             bytes_to_copy = bytes_left;
2499         memcpy(outbuffer, &comp_stream->buf[comp_stream->nextout],
2500                 bytes_to_copy);
2501         copybytes -= bytes_to_copy;
2502         copied_bytes += bytes_to_copy;
2503         outbuffer += bytes_to_copy;
2504         comp_stream->nextout += (int) bytes_to_copy;
2505         comp_stream->uncomp_offset += bytes_to_copy;
2506     }
2507     return copied_bytes;
2508 }
2509
2510 /* Read a blob from a compressed stream.
2511    Return -1 and set "*err" on error, otherwise return 0. */
2512 static int
2513 read_blob(FILE_T infile, ngsniffer_comp_stream_t *comp_stream, int *err)
2514 {
2515     int in_len;
2516     size_t read_len;
2517     unsigned short blob_len;
2518     gint16 blob_len_host;
2519     gboolean uncompressed;
2520     unsigned char file_inbuf[65536];
2521     int out_len;
2522
2523     /* Read one 16-bit word which is length of next compressed blob */
2524     errno = WTAP_ERR_CANT_READ;
2525     read_len = file_read(&blob_len, 1, 2, infile);
2526     if (2 != read_len) {
2527         *err = file_error(infile);
2528         return -1;
2529     }
2530     comp_stream->comp_offset += 2;
2531     blob_len_host = pletohs(&blob_len);
2532
2533     /* Compressed or uncompressed? */
2534     if (blob_len_host < 0) {
2535         /* Uncompressed blob; blob length is absolute value of the number. */
2536         in_len = -blob_len_host;
2537         uncompressed = TRUE;
2538     } else {
2539         in_len = blob_len_host;
2540         uncompressed = FALSE;
2541     }
2542
2543     /* Read the blob */
2544     errno = WTAP_ERR_CANT_READ;
2545     read_len = file_read(file_inbuf, 1, in_len, infile);
2546     if ((size_t) in_len != read_len) {
2547         *err = file_error(infile);
2548         return -1;
2549     }
2550     comp_stream->comp_offset += in_len;
2551
2552     if (uncompressed) {
2553         memcpy(comp_stream->buf, file_inbuf, in_len);
2554         out_len = in_len;
2555     } else {
2556         /* Decompress the blob */
2557         out_len = SnifferDecompress(file_inbuf, in_len,
2558                                 comp_stream->buf, OUTBUF_SIZE, err);
2559         if (out_len < 0)
2560             return -1;
2561     }
2562     comp_stream->nextout = 0;
2563     comp_stream->nbytes = out_len;
2564     return 0;
2565 }
2566
2567 /* Seek in the sequential data stream; we can only seek forward, and we
2568    do it on compressed files by skipping forward. */
2569 static gint64
2570 ng_file_seek_seq(wtap *wth, gint64 offset, int whence, int *err)
2571 {
2572     gint64 delta;
2573     char buf[65536];
2574     long amount_to_read;
2575
2576     if (wth->file_type == WTAP_FILE_NGSNIFFER_UNCOMPRESSED)
2577         return file_seek(wth->fh, offset, whence, err);
2578
2579     switch (whence) {
2580
2581     case SEEK_SET:
2582         break;          /* "offset" is the target offset */
2583
2584     case SEEK_CUR:
2585         offset += wth->capture.ngsniffer->seq.uncomp_offset;
2586         break;          /* "offset" is relative to the current offset */
2587
2588     case SEEK_END:
2589         g_assert_not_reached(); /* "offset" is relative to the end of the file... */
2590         break;          /* ...but we don't know where that is. */
2591     }
2592
2593     delta = offset - wth->capture.ngsniffer->seq.uncomp_offset;
2594     g_assert(delta >= 0);
2595
2596     /* Ok, now read and discard "delta" bytes. */
2597     while (delta != 0) {
2598         amount_to_read = (long) delta;
2599         if ((unsigned long)amount_to_read > sizeof buf)
2600             amount_to_read = sizeof buf;
2601         if (ng_file_read(buf, 1, amount_to_read, wth, FALSE, err) < 0)
2602             return -1;  /* error */
2603         delta -= amount_to_read;
2604     }
2605     return offset;
2606 }
2607
2608 /* Seek in the random data stream.
2609
2610    On compressed files, we see whether we're seeking to a position within
2611    the blob we currently have in memory and, if not, we find in the list
2612    of blobs the last blob that starts at or before the position to which
2613    we're seeking, and read that blob in.  We can then move to the appropriate
2614    position within the blob we have in memory (whether it's the blob we
2615    already had in memory or, if necessary, the one we read in). */
2616 static gint64
2617 ng_file_seek_rand(wtap *wth, gint64 offset, int whence, int *err)
2618 {
2619     ngsniffer_t *ngsniffer;
2620     gint64 delta;
2621     GList *new, *next;
2622     blob_info_t *next_blob, *new_blob;
2623
2624     if (wth->file_type == WTAP_FILE_NGSNIFFER_UNCOMPRESSED)
2625         return file_seek(wth->random_fh, offset, whence, err);
2626
2627     ngsniffer = wth->capture.ngsniffer;
2628
2629     switch (whence) {
2630
2631     case SEEK_SET:
2632         break;          /* "offset" is the target offset */
2633
2634     case SEEK_CUR:
2635         offset += ngsniffer->rand.uncomp_offset;
2636         break;          /* "offset" is relative to the current offset */
2637
2638     case SEEK_END:
2639         g_assert_not_reached(); /* "offset" is relative to the end of the file... */
2640         break;          /* ...but we don't know where that is. */
2641     }
2642
2643     delta = offset - ngsniffer->rand.uncomp_offset;
2644
2645     /* Is the place to which we're seeking within the current buffer, or
2646        will we have to read a different blob into the buffer? */
2647     new = NULL;
2648     if (delta > 0) {
2649         /* We're going forwards.
2650            Is the place to which we're seeking within the current buffer? */
2651         if ((size_t)(ngsniffer->rand.nextout + delta) >= ngsniffer->rand.nbytes) {
2652             /* No.  Search for a blob that contains the target offset in
2653                the uncompressed byte stream, starting with the blob
2654                following the current blob. */
2655             new = g_list_next(ngsniffer->current_blob);
2656             while (new) {
2657                 next = g_list_next(new);
2658                 if (next == NULL) {
2659                     /* No more blobs; the current one is it. */
2660                     break;
2661                 }
2662
2663                 next_blob = next->data;
2664                 /* Does the next blob start after the target offset?
2665                    If so, the current blob is the one we want. */
2666                 if (next_blob->blob_uncomp_offset > offset)
2667                     break;
2668
2669                 new = next;
2670             }
2671         }
2672     } else if (delta < 0) {
2673         /* We're going backwards.
2674            Is the place to which we're seeking within the current buffer? */
2675         if (ngsniffer->rand.nextout + delta < 0) {
2676             /* No.  Search for a blob that contains the target offset in
2677                the uncompressed byte stream, starting with the blob
2678                preceding the current blob. */
2679             new = g_list_previous(ngsniffer->current_blob);
2680             while (new) {
2681                 /* Does this blob start at or before the target offset?
2682                    If so, the current blob is the one we want. */
2683                 new_blob = new->data;
2684                 if (new_blob->blob_uncomp_offset <= offset)
2685                     break;
2686
2687                 /* It doesn't - skip to the previous blob. */
2688                 new = g_list_previous(new);
2689             }
2690         }
2691     }
2692
2693     if (new != NULL) {
2694         /* The place to which we're seeking isn't in the current buffer;
2695            move to a new blob. */
2696         new_blob = new->data;
2697
2698         /* Seek in the compressed file to the offset in the compressed file
2699            of the beginning of that blob. */
2700         if (file_seek(wth->random_fh, new_blob->blob_comp_offset, SEEK_SET, err) == -1)
2701             return -1;
2702
2703         /* Make the blob we found the current one. */
2704         ngsniffer->current_blob = new;
2705
2706         /* Now set the current offsets to the offsets of the beginning
2707            of the blob. */
2708         ngsniffer->rand.uncomp_offset = new_blob->blob_uncomp_offset;
2709         ngsniffer->rand.comp_offset = new_blob->blob_comp_offset;
2710
2711         /* Now fill the buffer. */
2712         if (read_blob(wth->random_fh, &ngsniffer->rand, err) < 0)
2713             return -1;
2714
2715         /* Set "delta" to the amount to move within this blob; it had
2716            better be >= 0, and < the amount of uncompressed data in
2717            the blob, as otherwise it'd mean we need to seek before
2718            the beginning or after the end of this blob. */
2719         delta = offset - ngsniffer->rand.uncomp_offset;
2720         g_assert(delta >= 0 && (unsigned long)delta < ngsniffer->rand.nbytes);
2721     }
2722
2723     /* OK, the place to which we're seeking is in the buffer; adjust
2724        "ngsniffer->rand.nextout" to point to the place to which
2725        we're seeking, and adjust "ngsniffer->rand.uncomp_offset" to be
2726        the destination offset. */
2727     ngsniffer->rand.nextout += (int) delta;
2728     ngsniffer->rand.uncomp_offset += delta;
2729
2730     return offset;
2731 }