From fabf144b83e393996f872155b61a4fee0c4735c4 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 10 Jan 2003 09:04:44 +0000 Subject: [PATCH] Rename the "version" argument to "process_header_records()" "maj_vers", as it's the major version number. Try using the first word of "rsvd" to determine whether a capture is an ISDN capture or not in version 1 captures. Version 1 captures look as if they might also have a REC_HEADER2 record - it's longer than the ones in version 4 and 5 captures, but it still appears to have a network subtype in the 5th byte. Get rid of the heuristic that checks for WTAP_ENCAP_ISDN by looking at the packet data; if we fail to recognize an ISDN capture, we should look for stuff in the headers to determine whether the capture is one or not. svn path=/trunk/; revision=6894 --- wiretap/ngsniffer.c | 114 +++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c index 0f9f65eec4..5f93e96caf 100644 --- a/wiretap/ngsniffer.c +++ b/wiretap/ngsniffer.c @@ -1,6 +1,6 @@ /* ngsniffer.c * - * $Id: ngsniffer.c,v 1.105 2003/01/10 05:53:00 guy Exp $ + * $Id: ngsniffer.c,v 1.106 2003/01/10 09:04:44 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez @@ -353,11 +353,11 @@ struct frame6_rec { #define NUM_NGSNIFF_TIMEUNITS 7 static double Usec[] = { 15.0, 0.838096, 15.0, 0.5, 2.0, 1.0, 0.1 }; -static int process_header_records(wtap *wth, int *err, gint16 version); +static int process_header_records(wtap *wth, int *err, gint16 maj_vers); static int process_rec_header2_v2(wtap *wth, unsigned char *buffer, guint16 length, int *err); -static int process_rec_header2_v45(wtap *wth, unsigned char *buffer, - guint16 length, int *err); +static int process_rec_header2_v145(wtap *wth, unsigned char *buffer, + guint16 length, gint16 maj_vers, int *err); static gboolean ngsniffer_read(wtap *wth, int *err, long *data_offset); static gboolean ngsniffer_seek_read(wtap *wth, long seek_off, union wtap_pseudo_header *pseudo_header, guchar *pd, int packet_size, @@ -510,13 +510,26 @@ int ngsniffer_open(wtap *wth, int *err) * XXX - in some version 1.16 internetwork analyzer files * generated by the Windows Sniffer when saving Windows * Sniffer files as DOS Sniffer files, the first "rsvd" word - * is 0x0100 for PRI ISDN files, 0x0200 for BRI ISDN files, - * and 0x0000 for non-ISDN files; is that something the DOS - * Sniffer understands? + * is 1 for PRI ISDN files, 2 for BRI ISDN files, and 0 for + * non-ISDN files; is that something the DOS Sniffer understands? */ maj_vers = pletohs(&version.maj_vers); if (process_header_records(wth, err, maj_vers) < 0) return -1; + if (wth->file_encap == WTAP_ENCAP_PER_PACKET && maj_vers == 1) { + /* + * Well, we haven't determined the internetwork analyzer + * subtype yet, and this is a version 1 capture; look + * at the first "rsvd" word. + */ + switch (pletohs(&version.rsvd[0])) { + + case 1: + case 2: + wth->file_encap = WTAP_ENCAP_ISDN; + break; + } + } /* * Now, if we have a random stream open, position it to the same @@ -597,7 +610,7 @@ int ngsniffer_open(wtap *wth, int *err) } static int -process_header_records(wtap *wth, int *err, gint16 version) +process_header_records(wtap *wth, int *err, gint16 maj_vers) { int bytes_read; char record_type[2]; @@ -626,7 +639,7 @@ process_header_records(wtap *wth, int *err, gint16 version) && (type != REC_HEADER3) && (type != REC_HEADER4) && (type != REC_HEADER5) && (type != REC_HEADER6) && (type != REC_HEADER7) - && ((type != REC_V2DESC) || (version > 2)) ) { + && ((type != REC_V2DESC) || (maj_vers > 2)) ) { /* * Well, this is either some unknown header type * (we ignore this case), an uncompressed data @@ -676,7 +689,7 @@ process_header_records(wtap *wth, int *err, gint16 version) } } - switch (version) { + switch (maj_vers) { case 2: if (process_rec_header2_v2(wth, buffer, @@ -684,10 +697,11 @@ process_header_records(wtap *wth, int *err, gint16 version) return -1; break; + case 1: case 4: case 5: - if (process_rec_header2_v45(wth, buffer, - length, err) < 0) + if (process_rec_header2_v145(wth, buffer, + length, maj_vers, err) < 0) return -1; break; } @@ -700,7 +714,6 @@ process_header_records(wtap *wth, int *err, gint16 version) SEEK_CUR, err) == -1) return -1; } - } else { /* Nope, just skip over the data. */ if (file_seek(wth->fh, length, SEEK_CUR, err) == -1) @@ -747,8 +760,8 @@ process_rec_header2_v2(wtap *wth, unsigned char *buffer, guint16 length, } static int -process_rec_header2_v45(wtap *wth, unsigned char *buffer, guint16 length, - int *err) +process_rec_header2_v145(wtap *wth, unsigned char *buffer, guint16 length, + gint16 maj_vers, int *err) { /* * The 5th byte of the REC_HEADER2 record appears to be a @@ -802,18 +815,39 @@ process_rec_header2_v45(wtap *wth, unsigned char *buffer, guint16 length, case NET_ROUTER: /* - * XXX - for most of the files we've seen, 0xfa in - * buffer[1] means the file is an ISDN capture, but - * there's one PPP file with 0xfa there; does that + * For most of the version 4 capture files I've seen, + * 0xfa in buffer[1] means the file is an ISDN capture, + * but there's one PPP file with 0xfa there; does that * mean that the 0xfa has nothing to do with ISDN, * or is that just an ISDN file with no D channel * packets? (The channel number is not 0 in any * of the packets, so perhaps it is.) + * + * For one version 5 ISDN capture I've seen, there's + * a 0x01 in buffer[6]; none of the non-ISDN version + * 5 captures have it. */ - if (buffer[1] == 0xfa) - wth->file_encap = WTAP_ENCAP_ISDN; - else - wth->file_encap = WTAP_ENCAP_PER_PACKET; + wth->file_encap = WTAP_ENCAP_PER_PACKET; + switch (maj_vers) { + + case 4: + if (buffer[1] == 0xfa) + wth->file_encap = WTAP_ENCAP_ISDN; + break; + + case 5: + if (length < 7) { + /* + * There is no 5th byte; give up. + */ + g_message("ngsniffer: WAN bridge/router capture has no ISDN flag"); + *err = WTAP_ERR_UNSUPPORTED_ENCAP; + return -1; + } + if (buffer[6] == 0x01) + wth->file_encap = WTAP_ENCAP_ISDN; + break; + } break; case NET_PPP: @@ -1596,32 +1630,16 @@ static int infer_pkt_encap(const guint8 *pd, int len) } } - if (pd[0] & 1) { - /* - * LAPB. - */ - return WTAP_ENCAP_LAPB; - } else { - /* - * LAPD. - * We report it as WTAP_ENCAP_ISDN. - * - * XXX - there appeared, at least from the captures - * I've seen, to be something buried in REC_HEADER2 - * records in version 4 and 5 captures that indicates - * whether the capture was taken with an ISDN pod, - * and there appeared, from the output of a Windows - * Sniffer writing out ISDN and non-ISDN captures, - * to perhaps be information in the "rsvd" fields - * of the version record of version 1 captures - * that indicates whether the capture was taken with - * an ISDN pod. - * - * We leave this heuristic in here, for now, for - * non-version 4 and non-version-5 captures. - */ - return WTAP_ENCAP_ISDN; - } + /* + * Assume LAPB, for now. If we support other HDLC encapsulations, + * we can check whether the low-order bit of the first byte is + * set (as it should be for LAPB) if no other checks pass. + * + * Or, if it's truly impossible to distinguish ISDN from non-ISDN + * captures, we could assume it's ISDN if it's not anything + * else. + */ + return WTAP_ENCAP_LAPB; } static int fix_pseudo_header(int encap, const guint8 *pd, int len,