From f21cd2e23f372bd42e4792ef0b4294d2db881a92 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Wed, 18 Nov 2020 17:39:19 -0800 Subject: [PATCH] wiretap: Convert ascend.y to Lemon. Convert wiretap/ascend.y.in from Bison/YACC to Lemon and rename it to wiretap/ascend_parser.lemon. Tighten up some of our scanning and parsing. Make the indentation in it and related files consistent. Aside from the recent IPv4 fragment offset changes, this produces identical output to the 3.4 branch for the Ascend trace files I have here. Remove the comment about supporting other commands. Another timeline might have an Ascend that successfully pivoted to DSL or 15625B+1D gigabit ISDN, but this one has neither. This was our last/only Bison/YACC file, so remove Bison/YACC as a development and packaging dependency and remove references to it from the documentation. --- CMakeLists.txt | 1 - README.md | 15 +- cmake/modules/FindYACC.cmake | 60 -- debian/control | 2 +- .../wsdg_src/WSDG_chapter_quick_setup.adoc | 4 +- docbook/wsdg_src/WSDG_chapter_sources.adoc | 2 +- docbook/wsdg_src/WSDG_chapter_tools.adoc | 57 +- packaging/rpm/wireshark.spec.in | 4 +- tools/alpine-setup.sh | 1 - tools/bsd-setup.sh | 3 - tools/checklicenses.py | 2 +- tools/debian-setup.sh | 1 - tools/rpm-setup.sh | 1 - wiretap/CMakeLists.txt | 6 +- wiretap/ascend-int.h | 48 +- wiretap/ascend.y.in | 519 -------------- wiretap/ascend_parser.lemon | 505 ++++++++++++++ wiretap/ascend_scanner.l | 285 ++++---- wiretap/ascendtext.c | 644 +++++++++--------- ws_diag_control.h | 29 - 20 files changed, 1016 insertions(+), 1173 deletions(-) delete mode 100644 cmake/modules/FindYACC.cmake delete mode 100644 wiretap/ascend.y.in create mode 100644 wiretap/ascend_parser.lemon diff --git a/CMakeLists.txt b/CMakeLists.txt index ca405b9fdd..c4ed6c6db6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1050,7 +1050,6 @@ find_package(GCRYPT "1.4.2" REQUIRED) reset_find_package(CARES) find_package(CARES "1.5.0" REQUIRED) find_package(LEX REQUIRED) -find_package(YACC REQUIRED) find_package(Perl REQUIRED) if(CMAKE_VERSION VERSION_LESS "3.12") diff --git a/README.md b/README.md index 6e6f132f97..eec9bf59a2 100644 --- a/README.md +++ b/README.md @@ -46,18 +46,11 @@ operating system. This is the case for Windows XP, which is supported by Wireshark 1.10 and earlier. In other cases the standard package for Wireshark might simply be old. This is the case for Solaris and HP-UX. -NOTE: The Makefile depends on GNU "make"; it doesn't appear to -work with the "make" that comes with Solaris 7 nor the BSD "make". +Both Perl and Python 3 are needed, the former for building the man +pages. -Both Perl and Python are needed, the former for building the man pages. - -If you decide to modify the yacc grammar or lex scanner, then -you need "flex" - it cannot be built with vanilla "lex" - -and either "bison" or the Berkeley "yacc". Your flex -version must be 2.5.1 or greater. Check this with `flex -V`. - -You must therefore install Perl, Python, GNU "make", "flex", and either "bison" -or Berkeley "yacc" on systems that lack them. +You must therefore install Perl, Python, GNU "make", and "flex" (vanilla +"lex" won't work) on systems that lack them. Full installation instructions can be found in the INSTALL file and in the Developer's Guide at https://www.wireshark.org/docs/wsdg_html_chunked/ diff --git a/cmake/modules/FindYACC.cmake b/cmake/modules/FindYACC.cmake deleted file mode 100644 index c4e889f4ac..0000000000 --- a/cmake/modules/FindYACC.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# -# - Find bison/yacc executable -# - -INCLUDE(FindChocolatey) - -FIND_PROGRAM(YACC_EXECUTABLE - NAMES - win_bison - bison - yacc - PATHS - ${CHOCOLATEY_BIN_PATH} - /bin - /usr/bin - /usr/local/bin - /sbin -) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(YACC DEFAULT_MSG YACC_EXECUTABLE) - -MARK_AS_ADVANCED(YACC_EXECUTABLE) - -# Specifying "%pure-parser" will fail with a deprecation warning in -# Bison 3.4 and later. Specifying "%define api.pure" doesn't work with -# Berkeley YACC and older versions of Bison (such as 2.3, which ships -# with macOS). If we're using Bison and it's new, configure our .y.in -# files with "%define api.pure", otherwise use "%pure-parser". -set(YACC_PURE_PARSER_DIRECTIVE "%pure-parser") -if(YACC_EXECUTABLE) - execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_VARIABLE _yacc_full_version) - string(REGEX MATCH "[1-9]+\.[0-9]+" _yacc_major_minor ${_yacc_full_version}) - if (_yacc_full_version MATCHES "GNU Bison" AND _yacc_major_minor VERSION_GREATER "2.6") - set(YACC_PURE_PARSER_DIRECTIVE "%define api.pure") - endif() -endif() - -MACRO(ADD_YACC_FILES _source _generated) - FOREACH (_current_FILE ${ARGN}) - configure_file(${_current_FILE}.in ${_current_FILE}) - GET_FILENAME_COMPONENT(_in ${CMAKE_CURRENT_BINARY_DIR}/${_current_FILE} ABSOLUTE) - GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE) - - SET(_out ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.c) - - ADD_CUSTOM_COMMAND( - OUTPUT ${_out} - COMMAND ${YACC_EXECUTABLE} - -d - -p ${_basename} - -o${_out} - ${_in} - DEPENDS ${_in} - ) - LIST(APPEND ${_source} ${_in}) - LIST(APPEND ${_generated} ${_out}) - ENDFOREACH (_current_FILE) -ENDMACRO(ADD_YACC_FILES) - diff --git a/debian/control b/debian/control index 80de18e0c6..6581989b71 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Build-Depends: python3, python3-ply, libc-ares-dev, xsltproc, dh-python, docbook-xsl (>= 1.64.1.0-0), docbook-xml, libxml2-utils, libpcre3-dev, libcap2-dev [linux-any] | libcap-dev (>= 2.17) [linux-any], lsb-release, - bison, quilt, libparse-yapp-perl, + quilt, libparse-yapp-perl, # libgnutls28-dev >= 3.2.14-1 is GPLv2+ compatible. libgnutls28-dev (>= 3.2.14-1~), libgcrypt-dev, libkrb5-dev, liblua5.2-dev, libsmi2-dev, diff --git a/docbook/wsdg_src/WSDG_chapter_quick_setup.adoc b/docbook/wsdg_src/WSDG_chapter_quick_setup.adoc index 776a4ea598..fc88b89fad 100644 --- a/docbook/wsdg_src/WSDG_chapter_quick_setup.adoc +++ b/docbook/wsdg_src/WSDG_chapter_quick_setup.adoc @@ -58,7 +58,7 @@ command `choco install` (or its shorthand, `cinst`), e.g. [source,cmd] ---- -> rem Flex and Bison are required. +> rem Flex is required. > choco install -y winflexbison3 > rem Git, CMake, Perl, Python, etc are also required, but can be installed > rem via their respective installation packages. @@ -254,7 +254,7 @@ Alternatively you can install Winflexbison using Chocolatey: PS$> choco install -y winflexbison3 ---- -Chocolatey ensures win_flex.exe and win_bison.exe are on your path. +Chocolatey ensures win_flex.exe is on your path. ==== Install and Prepare Sources diff --git a/docbook/wsdg_src/WSDG_chapter_sources.adoc b/docbook/wsdg_src/WSDG_chapter_sources.adoc index 7066fa4e7d..4da83b178d 100644 --- a/docbook/wsdg_src/WSDG_chapter_sources.adoc +++ b/docbook/wsdg_src/WSDG_chapter_sources.adoc @@ -1007,7 +1007,7 @@ your `~/.rpmmacros` file to enable parallel builds: ==== Building the RPM package requires quite a few packages and libraries -including GLib, `gcc`, `bison`, `flex`, Asciidoctor, and Qt development +including GLib, `gcc`, `flex`, Asciidoctor, and Qt development tools such as `uic` and `moc`. The required Qt packages can usually be obtained by installing the _qt5-devel_ package. For a complete list of build requirements, look for the “BuildRequires” lines in diff --git a/docbook/wsdg_src/WSDG_chapter_tools.adoc b/docbook/wsdg_src/WSDG_chapter_tools.adoc index 3f847b5f16..ec963b1116 100644 --- a/docbook/wsdg_src/WSDG_chapter_tools.adoc +++ b/docbook/wsdg_src/WSDG_chapter_tools.adoc @@ -770,59 +770,6 @@ Built 18:08:02 Feb 4 2003 However, the version string may vary. -// Sed is no longer required. -//[[ChToolsSed]] - -[[ChToolsBison]] - -=== Bison - -Bison is a parser generator used for some of Wireshark’s file format support. - -[[ChToolsUnixBison]] - -[discrete] -==== Unix - -Bison is available for most UNIX and UNIX-like platforms. See the next -section for native Windows options. - -If GNU Bison isn't already installed or available as a package for your -platform you can get it at: https://www.gnu.org/software/bison/bison.html[]. - -After correct installation running the following - -[source,sh] ----- -$ bison --version ----- - -should result in something like: - ----- -bison (GNU Bison) 2.3 -Written by Robert Corbett and Richard Stallman. - -Copyright (C) 2006 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ----- - -Your version string may vary. - -[[ChToolsWindowsBison]] - -[discrete] -==== Windows - -A native Windows version of bison is available in the _winflexbison3_ -https://chocolatey.org/[Chocolatey] package. Note that the executable is named -_win_bison_. - -Native packages are available from other sources such as -http://gnuwin32.sourceforge.net/packages/bison.htm[GnuWin]. -They aren't officially supported but _should_ work. - [[ChToolsFlex]] === Flex @@ -861,13 +808,13 @@ Your version string may vary. [discrete] ==== Windows -A native Windows version of flex is available in the _winflexbison_ +A native Windows version of flex is available in the _winflexbison3_ https://chocolatey.org/[Chocolatey] package. Note that the executable is named _win_flex_. [source,cmd] ---- -PS:\> choco install winflexbison +PS:\> choco install winflexbison3 ---- Native packages are available from other sources such as diff --git a/packaging/rpm/wireshark.spec.in b/packaging/rpm/wireshark.spec.in index 473c403e45..f3b9634794 100644 --- a/packaging/rpm/wireshark.spec.in +++ b/packaging/rpm/wireshark.spec.in @@ -59,7 +59,6 @@ BuildRequires: python3 BuildRequires: gcc BuildRequires: perl BuildRequires: flex -BuildRequires: bison %if %{with guides} # HTML guides BuildRequires: asciidoctor @@ -538,6 +537,9 @@ update-mime-database %{_datadir}/mime &> /dev/null || : %{_libdir}/pkgconfig/wireshark.pc %changelog +* Thu Nov 26 2020 Gerald Combs +- Bison is no longer required + * Tue Sep 29 2020 Lin Sun - Added opus codec as an option diff --git a/tools/alpine-setup.sh b/tools/alpine-setup.sh index 6cb461f6f9..a43d0540f6 100755 --- a/tools/alpine-setup.sh +++ b/tools/alpine-setup.sh @@ -47,7 +47,6 @@ BASIC_LIST="cmake \ glib-dev \ libgcrypt-dev \ flex \ - bison \ perl \ tiff-dev \ c-ares-dev \ diff --git a/tools/bsd-setup.sh b/tools/bsd-setup.sh index 7b8acc8880..72a99e05a2 100755 --- a/tools/bsd-setup.sh +++ b/tools/bsd-setup.sh @@ -152,9 +152,6 @@ echo "libilbc is unavailable" # Add OS-specific required/optional packages # Those not listed don't require additions. case `uname` in - OpenBSD) - add_package ADDITIONAL_LIST bison || echo "bison is unavailable" - ;; NetBSD) add_package ADDITIONAL_LIST libgcrypt || echo "libgcrypt is unavailable" ;; diff --git a/tools/checklicenses.py b/tools/checklicenses.py index b339d3aea5..9e950c87f0 100755 --- a/tools/checklicenses.py +++ b/tools/checklicenses.py @@ -100,7 +100,7 @@ PATH_SPECIFIC_ALLOWED_LICENSES = { 'cmake/TestFileOffsetBits.c': [ 'UNKNOWN', ], - # Generated header files by lex/yacc/whatever + # Generated header files by lex/lemon/whatever 'epan/dtd_grammar.h': [ 'UNKNOWN', ], diff --git a/tools/debian-setup.sh b/tools/debian-setup.sh index 29812ff5a8..3960f1f6a4 100755 --- a/tools/debian-setup.sh +++ b/tools/debian-setup.sh @@ -58,7 +58,6 @@ BASIC_LIST="libglib2.0-dev \ qt5-default \ libc-ares-dev \ libpcap-dev \ - bison \ flex \ make \ python3 \ diff --git a/tools/rpm-setup.sh b/tools/rpm-setup.sh index 508c59ab4e..3b51aa6098 100755 --- a/tools/rpm-setup.sh +++ b/tools/rpm-setup.sh @@ -43,7 +43,6 @@ BASIC_LIST="cmake \ gcc \ gcc-c++ \ flex \ - bison \ python3 \ perl \ desktop-file-utils \ diff --git a/wiretap/CMakeLists.txt b/wiretap/CMakeLists.txt index b9d8405a2d..2a6eb14058 100644 --- a/wiretap/CMakeLists.txt +++ b/wiretap/CMakeLists.txt @@ -96,11 +96,8 @@ add_lex_files(LEX_FILES WIRETAP_FILES k12text.l ) -add_yacc_files(YACC_FILES WIRETAP_FILES - ascend.y -) - add_lemon_files(LEMON_FILES WIRETAP_FILES + ascend_parser.lemon busmaster_parser.lemon candump_parser.lemon ) @@ -162,7 +159,6 @@ CHECKAPI( ${WIRETAP_NONGENERATED_FILES} # LEX files commented out due to use of malloc, free etc. # ${LEX_FILES} - ${YACC_FILES} ${LEMON_FILES} ) diff --git a/wiretap/ascend-int.h b/wiretap/ascend-int.h index 73581531b5..7b0ef6d348 100644 --- a/wiretap/ascend-int.h +++ b/wiretap/ascend-int.h @@ -13,34 +13,44 @@ #define __ASCEND_INT_H__ #include +#include #include "ws_symbol_export.h" typedef struct { - time_t inittime; - gboolean adjusted; - gint64 next_packet_seek_start; + time_t inittime; + gboolean adjusted; + gint64 next_packet_seek_start; } ascend_t; typedef struct { - FILE_T fh; - const gchar *ascend_parse_error; - int err; - gchar *err_info; - struct ascend_phdr *pseudo_header; - guint8 *pkt_data; + int length; + guint32 u32_val; + guint16 u16_val; + guint8 u8_val; + char str_val[ASCEND_MAX_STR_LEN]; +} ascend_token_t; - gboolean saw_timestamp; - guint32 timestamp; +typedef struct { + FILE_T fh; + const gchar *ascend_parse_error; + int err; + gchar *err_info; + struct ascend_phdr *pseudo_header; + guint8 *pkt_data; - gint64 first_hexbyte; - guint32 wirelen; - guint32 caplen; - time_t secs; - guint32 usecs; + gboolean saw_timestamp; + guint32 timestamp; + + gint64 first_hexbyte; + guint32 wirelen; + guint32 caplen; + time_t secs; + guint32 usecs; + + ascend_token_t token; } ascend_state_t; -extern int -run_ascend_parser(FILE_T fh, wtap_rec *rec, guint8 *pd, - ascend_state_t *parser_state, int *err, gchar **err_info); +extern bool +run_ascend_parser(guint8 *pd, ascend_state_t *parser_state, int *err, gchar **err_info); #endif /* ! __ASCEND_INT_H__ */ diff --git a/wiretap/ascend.y.in b/wiretap/ascend.y.in deleted file mode 100644 index 0b4dafe803..0000000000 --- a/wiretap/ascend.y.in +++ /dev/null @@ -1,519 +0,0 @@ -/* - * We want a reentrant parser. - * Berkeley YACC and older versions of Bison use "%pure-parser" and newer - * versions of Bison use "%define api.pure". - * As https://code.wireshark.org/review/#/c/33771/ - * says, "This doesn't work with Berkeley YACC, and I'd *really* prefer not to require Bison." - */ -${YACC_PURE_PARSER_DIRECTIVE} - -/* - * We also want a reentrant scanner, so we have to pass the - * handle for the reentrant scanner to the parser, and the - * parser has to pass it to the lexical analyzer. - * - * We use void * rather than yyscan_t because, at least with some - * versions of Flex and Bison, if you use yyscan_t in %parse-param and - * %lex-param, you have to include the ascend_lex_scanner.h before - * ascend.h to get yyscan_t declared, and you have to include ascend.h - * before ascend_lex_scanner.h to get YYSTYPE declared. Using void * - * breaks the cycle; the Flex documentation says yyscan_t is just a void *. - */ -%parse-param {void *yyscanner} -%lex-param {void *yyscanner} - -/* - * And we need to pass the parser/scanner state to the parser. - */ -%parse-param {ascend_state_t *parser_state} - -%{ -/* ascend.y - * - * Wiretap Library - * Copyright (c) 1998 by Gilbert Ramirez - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -/* - Example 'pridisp' output data - one paragraph/frame: - -PRI-XMIT-27: (task "l1Task" at 0x10216fe0, time: 560194.01) 4 octets @ 0x1027c5b0 - [0000]: 00 01 01 a9 .... -PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00 - [0000]: 00 01 01 dd - - Example 'pridisp' output data - two paragraphs/frame for XMIT case only: - -PRI-XMIT-19/1: (task "l1Task" at 0x10216840, time: 274759.98) 4 octets @ 0x1027f230 - [0000]: 00 01 30 d8 ..0. -PRI-XMIT-19/2 (task "l1Task" at 0x10216840, time: 274759.98) 11 octets @ 0x1027f234 - [0000]: 08 02 8c bf 02 18 04 e9 82 83 8f ........ ... - - Example 'ether-disp' output data: - -ETHER3ND RECV: (task "_sarTask" at 0x802c6eb0, time: 259848.03) 775 octets @ 0xa8fb2020 - [0000]: 00 d0 52 04 e7 1e 08 00 20 ae 51 b5 08 00 45 00 ..R..... .Q...E. - [0010]: 02 f9 05 e6 40 00 3f 11 6e 39 87 fe c4 95 3c 3c ....@.?. n9....<< - [0020]: 3c 05 13 c4 13 c4 02 e5 ef ed 49 4e 56 49 54 45 <....... ..INVITE - [0030]: 20 73 69 70 3a 35 32 30 37 33 40 36 30 2e 36 30 sip:520 73@60.60 - [0040]: 2e 36 30 2e 35 20 53 49 50 2f 32 2e 30 0d 0a 56 .60.5 SI P/2.0..V - [0050]: 69 61 3a 20 53 49 50 2f 32 2e 30 2f 55 44 50 20 ia: SIP/ 2.0/UDP - [0060]: 31 33 35 2e 135. - - Example 'wandsess' output data: - -RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 - [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40 - [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00 - [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00 - [0030]: 00 -XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16 - [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40 - [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20 - [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00 - [0030]: 00 02 04 05 B4 - - Example 'wdd' output data: - -Date: 01/12/1990. Time: 12:22:33 -Cause an attempt to place call to 14082750382 -WD_DIALOUT_DISP: chunk 2515EE type IP. -(task: 251790, time: 994953.28) 44 octets @ 2782B8 - [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00 - [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47 - [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00 - - The following output comes from a MAX with Software 7.2.3: - -RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 - [0000]: FF 03 00 21 45 00 00 60 E3 49 00 00 7F 11 FD 7B - [0010]: C0 A8 F7 05 8A C8 18 51 00 89 00 89 00 4C C7 C1 - [0020]: CC 8E 40 00 00 01 00 00 00 00 00 01 20 45 4A 45 - [0030]: 42 45 43 45 48 43 4E 46 43 46 41 43 41 43 41 43 - [0040]: 41 43 41 43 41 43 41 43 41 43 41 42 4E 00 00 20 - [0050]: 00 01 C0 0C 00 20 00 01 00 04 93 E0 00 06 60 00 - [0060]: C0 A8 F7 05 -XMIT-187:(task: B0292CA0, time: 18042248.04) 60 octets @ 800AD576 - [0000]: FF 03 00 21 45 00 00 38 D7 EE 00 00 0F 01 11 2B - [0010]: 0A FF FF FE C0 A8 F7 05 03 0D 33 D3 00 00 00 00 - [0020]: 45 00 00 60 E3 49 00 00 7E 11 FE 7B C0 A8 F7 05 - [0030]: 8A C8 18 51 00 89 00 89 00 4C C7 C1 -RECV-187:(task: B0292CA0, time: 18042251.92) 16 octets @ 800018E8 - [0000]: FF 03 C0 21 09 01 00 0C DE 61 96 4B 00 30 94 92 - - In TAOS 8.0, Lucent slightly changed the format as follows: - - Example 'wandisp' output data (TAOS 8.0.3): (same format is used - for 'wanopen' and 'wannext' command) - -RECV-14: (task "idle task" at 0xb05e6e00, time: 1279.01) 29 octets @ 0x8000e0fc - [0000]: ff 03 c0 21 01 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........ - [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -.... -XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 38 octets @ 0x8007fd56 - [0000]: ff 03 c0 21 01 01 00 22 00 04 00 00 01 04 05 f4 ...!..." ........ - [0010]: 03 05 c2 23 05 11 04 05 f4 13 09 03 00 c0 7b 80 ...#.... ......{. - [0020]: 7c ef 17 04 0e 00 |..... -XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 29 octets @ 0x8007fa36 - [0000]: ff 03 c0 21 02 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........ - [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -.... - - Example 'wandsess' output data (TAOS 8.0.3): - -RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 - [0000]: ff 03 00 3d c0 00 00 04 80 fd 02 01 00 0a 11 06 ...=.... ........ - [0010]: 00 01 01 03 .... -XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 26 octets @ 0x800806b6 - [0000]: ff 03 00 3d c0 00 00 00 80 21 01 01 00 10 02 06 ...=.... .!...... - [0010]: 00 2d 0f 01 03 06 89 64 03 08 .-.....d .. -XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octets @ 0x8007f716 - [0000]: ff 03 00 3d c0 00 00 01 80 fd 01 01 00 0a 11 06 ...=.... ........ - [0010]: 00 01 01 03 .... - - The changes since TAOS 7.X are: - - 1) White space is added before "(task". - 2) Task has a name, indicated by a subsequent string surrounded by a - double-quote. - 3) Address expressed in hex number has a preceding "0x". - 4) Hex numbers are in lower case. - 5) There is a character display corresponding to hex data in each line. - - */ - -#include "config.h" - -#if defined(_MSC_VER) && !defined(__STDC_VERSION__) - /* - * MSVC doesn't, by default, define __STDC_VERSION__, which - * means that the code generated by newer versions of winflexbison3's - * Bison end up defining YYPTRDIFF_T as long, which is wrong on - * 64-bit Windows, as that's an LLP64 platform, not an LP64 platform, - * and causes warnings to be generated. Those warnings turn into - * errors. - * - * With MSVC, if __STDC_VERSION__ isn't defined, Forcibly include - * here to work around that. - */ - #include -#endif -#include -#include - -#include "wtap-int.h" -#include -#include "ascendtext.h" -#include "ascend-int.h" -DIAG_OFF_BYACC -#include "ascend.h" -#include "ascend_scanner_lex.h" -DIAG_ON_BYACC -#include "file_wrappers.h" - -#define NO_USER "" - -extern void yyerror (void *yyscanner, ascend_state_t *state, FILE_T fh _U_, const char *s); - -DIAG_OFF_BYACC -%} - -%union { -gchar *s; -guint32 d; -guint8 b; -} - -%token STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER SLASH_SUFFIX -%token WDS_PREFIX ISDN_PREFIX ETHER_PREFIX DECNUM HEXNUM -%token HEXBYTE - -%type string dataln datagroup -%type wds_prefix isdn_prefix ether_prefix decnum hexnum -%type byte bytegroup - -%parse-param { FILE_T fh } - -%% - -data_packet: - | ether_hdr datagroup - | deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup - | isdn_hdr datagroup - | wds_hdr datagroup - | wds8_hdr datagroup - | wdp7_hdr datagroup - | wdp8_hdr datagroup - | wdd_date wdd_hdr datagroup - | wdd_hdr datagroup -; - -isdn_prefix: ISDN_PREFIX; - -ether_prefix: ETHER_PREFIX; - -wds_prefix: WDS_PREFIX; - -string: STRING; - -decnum: DECNUM; - -hexnum: HEXNUM; - -/* - pridisp special case - I-frame header printed separately from contents, - one frame across two messages. - -PRI-XMIT-0/1: (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @ -0x80128220 - [0000]: 00 01 ae b2 .... -PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @ -0x80128224 - [0000]: 08 02 d7 e3 02 18 03 a9 83 8a ........ - -*/ -deferred_isdn_hdr: isdn_prefix decnum SLASH_SUFFIX KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen += $11; - parser_state->secs = $9; - parser_state->usecs = $10; - if (parser_state->pseudo_header != NULL) { - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $2; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $7; - } - /* because we have two data groups */ - parser_state->first_hexbyte = 0; -} -; - -/* -PRI-XMIT-19: (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0 - ... or ... -PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00 -*/ -isdn_hdr: isdn_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $10; - parser_state->secs = $8; - parser_state->usecs = $9; - if (parser_state->pseudo_header != NULL) { - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $2; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $6; - } - parser_state->first_hexbyte = 0; -} -; - -/* -ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa -885f80e -*/ -ether_hdr: ether_prefix string KEYWORD string KEYWORD hexnum KEYWORD decnum decnum - decnum KEYWORD HEXNUM { - parser_state->wirelen = $10; - parser_state->secs = $8; - parser_state->usecs = $9; - if (parser_state->pseudo_header != NULL) { - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $6; - } -} -; - -/* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */ -/* 1 2 3 4 5 6 7 8 9 10 11 */ -wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $9; - parser_state->secs = $7; - parser_state->usecs = $8; - if (parser_state->pseudo_header != NULL) { - /* parser_state->pseudo_header->user is set in ascend_scanner.l */ - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $3; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $5; - } -} -; - -/* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */ -/* 1 2 3 4 5 6 7 8 9 10 11 12 13 */ -wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $11; - parser_state->secs = $9; - parser_state->usecs = $10; - if (parser_state->pseudo_header != NULL) { - /* parser_state->pseudo_header->user is set in ascend_scanner.l */ - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $3; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $7; - } -} -; - -/* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */ -/* 1 2 3 4 5 6 7 8 9 10 */ -wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $8; - parser_state->secs = $6; - parser_state->usecs = $7; - if (parser_state->pseudo_header != NULL) { - /* parser_state->pseudo_header->user is set in ascend_scanner.l */ - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $2; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $4; - } -} -; - -/* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */ -/* 1 2 3 4 5 6 7 8 9 10 11 12 */ -wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $10; - parser_state->secs = $8; - parser_state->usecs = $9; - if (parser_state->pseudo_header != NULL) { - /* parser_state->pseudo_header->user is set in ascend_scanner.l */ - parser_state->pseudo_header->type = $1; - parser_state->pseudo_header->sess = $2; - parser_state->pseudo_header->call_num[0] = '\0'; - parser_state->pseudo_header->chunk = 0; - parser_state->pseudo_header->task = $6; - } -} -; - -/* -Date: 01/12/1990. Time: 12:22:33 -Cause an attempt to place call to 14082750382 -*/ -/* 1 2 3 4 5 6 7 8 9 10*/ -wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD string { - /* - * Supply the date/time value to the code above us; it will use the - * first date/time value supplied as the capture start date/time. - */ - struct tm wddt; - - wddt.tm_sec = $8; - wddt.tm_min = $7; - wddt.tm_hour = $6; - wddt.tm_mday = $3; - wddt.tm_mon = $2 - 1; - wddt.tm_year = ($4 > 1970) ? $4 - 1900 : 70; - wddt.tm_isdst = -1; - - parser_state->timestamp = (guint32) mktime(&wddt); - parser_state->saw_timestamp = TRUE; -} -; - -/* -WD_DIALOUT_DISP: chunk 2515EE type IP. -(task: 251790, time: 994953.28) 44 octets @ 2782B8 -*/ -/* 1 2 3 4 5 6 7 8 9 10 11*/ -wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM { - parser_state->wirelen = $9; - parser_state->secs = $7; - parser_state->usecs = $8; - if (parser_state->pseudo_header != NULL) { - /* parser_state->pseudo_header->call_num is set in ascend_scanner.l */ - parser_state->pseudo_header->type = ASCEND_PFX_WDD; - parser_state->pseudo_header->user[0] = '\0'; - parser_state->pseudo_header->sess = 0; - parser_state->pseudo_header->chunk = $2; - parser_state->pseudo_header->task = $5; - } -} -; - -byte: HEXBYTE { - /* remember the position of the data group in the trace, to tip off - ascend_find_next_packet() as to where to look for the next header. */ - if (parser_state->first_hexbyte == 0) - parser_state->first_hexbyte = file_tell(fh); - - /* XXX - if this test fails, it means that we parsed more bytes than - the header claimed there were. */ - if (parser_state->caplen < parser_state->wirelen) { - parser_state->pkt_data[parser_state->caplen] = $1; - parser_state->caplen++; - } - - /* arbitrary safety maximum... */ - if (parser_state->caplen >= ASCEND_MAX_PKT_LEN) - YYACCEPT; -} -; - -/* XXX There must be a better way to do this... */ -bytegroup: byte - | byte byte - | byte byte byte - | byte byte byte byte - | byte byte byte byte byte - | byte byte byte byte byte byte - | byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte - | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte -; - -dataln: COUNTER bytegroup; - -datagroup: dataln - | dataln dataln - | dataln dataln dataln - | dataln dataln dataln dataln - | dataln dataln dataln dataln dataln - | dataln dataln dataln dataln dataln dataln - | dataln dataln dataln dataln dataln dataln dataln - | dataln dataln dataln dataln dataln dataln dataln dataln -; - -%% - -DIAG_ON_BYACC - -/* Run the parser. */ -int -run_ascend_parser(FILE_T fh, wtap_rec *rec, guint8 *pd, - ascend_state_t *parser_state, int *err, gchar **err_info) -{ - yyscan_t scanner = NULL; - int status; - - if (ascendlex_init(&scanner) != 0) { - /* errno is set if this fails */ - *err = errno; - *err_info = NULL; - return 1; - } - /* Associate the parser state with the lexical analyzer state */ - ascendset_extra(parser_state, scanner); - parser_state->fh = fh; - parser_state->ascend_parse_error = NULL; - parser_state->err = 0; - parser_state->err_info = NULL; - parser_state->pseudo_header = &rec->rec_header.packet_header.pseudo_header.ascend; - parser_state->pkt_data = pd; - - /* - * We haven't seen a time stamp yet. - */ - parser_state->saw_timestamp = FALSE; - parser_state->timestamp = 0; - - parser_state->first_hexbyte = 0; - parser_state->caplen = 0; - parser_state->wirelen = 0; - - parser_state->secs = 0; - parser_state->usecs = 0; - - /* - * Not all packets in a "wdd" dump necessarily have a "Cause an - * attempt to place call to" header (I presume this can happen if - * there was a call in progress when the packet was sent or - * received), so we won't necessarily have the phone number for - * the packet. - * - * XXX - we could assume, in the sequential pass, that it's the - * phone number from the last call, and remember that for use - * when doing random access. - */ - parser_state->pseudo_header->call_num[0] = '\0'; - - status = yyparse(scanner, parser_state, fh); - ascendlex_destroy(scanner); - - *err = parser_state->err; - *err_info = parser_state->err_info; - return status; -} - -void -yyerror (void *yyscanner, ascend_state_t *state _U_, FILE_T fh _U_, const char *s) -{ - ascendget_extra(yyscanner)->ascend_parse_error = s; -} - -DIAG_OFF_BYACC diff --git a/wiretap/ascend_parser.lemon b/wiretap/ascend_parser.lemon new file mode 100644 index 0000000000..51716fe658 --- /dev/null +++ b/wiretap/ascend_parser.lemon @@ -0,0 +1,505 @@ +%include { +/* ascend_parser.lemon + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* + Example 'pridisp' output data - one paragraph/frame: + +PRI-XMIT-27: (task "l1Task" at 0x10216fe0, time: 560194.01) 4 octets @ 0x1027c5b0 + [0000]: 00 01 01 a9 .... +PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00 + [0000]: 00 01 01 dd + + Example 'pridisp' output data - two paragraphs/frame for XMIT case only: + +PRI-XMIT-19/1: (task "l1Task" at 0x10216840, time: 274759.98) 4 octets @ 0x1027f230 + [0000]: 00 01 30 d8 ..0. +PRI-XMIT-19/2 (task "l1Task" at 0x10216840, time: 274759.98) 11 octets @ 0x1027f234 + [0000]: 08 02 8c bf 02 18 04 e9 82 83 8f ........ ... + + Example 'ether-disp' output data: + +ETHER3ND RECV: (task "_sarTask" at 0x802c6eb0, time: 259848.03) 775 octets @ 0xa8fb2020 + [0000]: 00 d0 52 04 e7 1e 08 00 20 ae 51 b5 08 00 45 00 ..R..... .Q...E. + [0010]: 02 f9 05 e6 40 00 3f 11 6e 39 87 fe c4 95 3c 3c ....@.?. n9....<< + [0020]: 3c 05 13 c4 13 c4 02 e5 ef ed 49 4e 56 49 54 45 <....... ..INVITE + [0030]: 20 73 69 70 3a 35 32 30 37 33 40 36 30 2e 36 30 sip:520 73@60.60 + [0040]: 2e 36 30 2e 35 20 53 49 50 2f 32 2e 30 0d 0a 56 .60.5 SI P/2.0..V + [0050]: 69 61 3a 20 53 49 50 2f 32 2e 30 2f 55 44 50 20 ia: SIP/ 2.0/UDP + [0060]: 31 33 35 2e 135. + + Example 'wandsess' output data: + +RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 + [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40 + [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00 + [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00 + [0030]: 00 +XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16 + [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40 + [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20 + [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00 + [0030]: 00 02 04 05 B4 + + Example 'wdd' output data: + +Date: 01/12/1990. Time: 12:22:33 +Cause an attempt to place call to 14082750382 +WD_DIALOUT_DISP: chunk 2515EE type IP. +(task: 251790, time: 994953.28) 44 octets @ 2782B8 + [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00 + [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47 + [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00 + + The following output comes from a MAX with Software 7.2.3: + +RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 + [0000]: FF 03 00 21 45 00 00 60 E3 49 00 00 7F 11 FD 7B + [0010]: C0 A8 F7 05 8A C8 18 51 00 89 00 89 00 4C C7 C1 + [0020]: CC 8E 40 00 00 01 00 00 00 00 00 01 20 45 4A 45 + [0030]: 42 45 43 45 48 43 4E 46 43 46 41 43 41 43 41 43 + [0040]: 41 43 41 43 41 43 41 43 41 43 41 42 4E 00 00 20 + [0050]: 00 01 C0 0C 00 20 00 01 00 04 93 E0 00 06 60 00 + [0060]: C0 A8 F7 05 +XMIT-187:(task: B0292CA0, time: 18042248.04) 60 octets @ 800AD576 + [0000]: FF 03 00 21 45 00 00 38 D7 EE 00 00 0F 01 11 2B + [0010]: 0A FF FF FE C0 A8 F7 05 03 0D 33 D3 00 00 00 00 + [0020]: 45 00 00 60 E3 49 00 00 7E 11 FE 7B C0 A8 F7 05 + [0030]: 8A C8 18 51 00 89 00 89 00 4C C7 C1 +RECV-187:(task: B0292CA0, time: 18042251.92) 16 octets @ 800018E8 + [0000]: FF 03 C0 21 09 01 00 0C DE 61 96 4B 00 30 94 92 + + In TAOS 8.0, Lucent slightly changed the format as follows: + + Example 'wandisp' output data (TAOS 8.0.3): (same format is used + for 'wanopen' and 'wannext' command) + +RECV-14: (task "idle task" at 0xb05e6e00, time: 1279.01) 29 octets @ 0x8000e0fc + [0000]: ff 03 c0 21 01 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........ + [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -.... +XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 38 octets @ 0x8007fd56 + [0000]: ff 03 c0 21 01 01 00 22 00 04 00 00 01 04 05 f4 ...!..." ........ + [0010]: 03 05 c2 23 05 11 04 05 f4 13 09 03 00 c0 7b 80 ...#.... ......{. + [0020]: 7c ef 17 04 0e 00 |..... +XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 29 octets @ 0x8007fa36 + [0000]: ff 03 c0 21 02 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........ + [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -.... + + Example 'wandsess' output data (TAOS 8.0.3): + +RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 + [0000]: ff 03 00 3d c0 00 00 04 80 fd 02 01 00 0a 11 06 ...=.... ........ + [0010]: 00 01 01 03 .... +XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 26 octets @ 0x800806b6 + [0000]: ff 03 00 3d c0 00 00 00 80 21 01 01 00 10 02 06 ...=.... .!...... + [0010]: 00 2d 0f 01 03 06 89 64 03 08 .-.....d .. +XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octets @ 0x8007f716 + [0000]: ff 03 00 3d c0 00 00 01 80 fd 01 01 00 0a 11 06 ...=.... ........ + [0010]: 00 01 01 03 .... + + The changes since TAOS 7.X are: + + 1) White space is added before "(task". + 2) Task has a name, indicated by a subsequent string surrounded by a + double-quote. + 3) Address expressed in hex number has a preceding "0x". + 4) Hex numbers are in lower case. + 5) There is a character display corresponding to hex data in each line. + + */ + +#include "config.h" +#include +#include +#include + +#include "wtap-int.h" +#include "ascendtext.h" +#include "ascend-int.h" +#include "ascend_parser.h" +#include "ascend_scanner_lex.h" +#include "file_wrappers.h" + +#define NO_USER "" + +#if 0 +#define ASCEND_PARSER_DEBUG 1 +#undef NDEBUG +#define ascend_debug(...) g_warning(__VA_ARGS__) +#else +#define ascend_debug(...) +#endif + +} // %include + +%name AscendParser + +%extra_argument { ascend_state_t *parser_state } + +%token_type { ascend_token_t } + +%token_destructor { + (void) parser_state; + (void) yypminor; +} + +%type STRING { ascend_token_t* } +%type KEYWORD { ascend_token_t* } +%type WDD_DATE { ascend_token_t* } +%type WDD_DECNUM { ascend_token_t* } +%type WDD_TIME { ascend_token_t* } +%type WDD_CAUSE { ascend_token_t* } +%type WDD_CALLNUM { ascend_token_t* } +%type WDD_CHUNK { ascend_token_t* } +%type COUNTER { ascend_token_t* } +%type SLASH_SUFFIX { ascend_token_t* } + +%type WDS_PREFIX { ascend_token_t* } +%type ISDN_PREFIX { ascend_token_t* } +%type ETHER_PREFIX { ascend_token_t* } +%type DECNUM { ascend_token_t* } +%type YEAR { ascend_token_t* } +%type MONTH { ascend_token_t* } +%type MDAY { ascend_token_t* } +%type HEXNUM { ascend_token_t* } + +%type HEXBYTE { ascend_token_t* } + +data_packet ::= ether_hdr datagroup . +data_packet ::= deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup . +data_packet ::= isdn_hdr datagroup . +data_packet ::= wds_hdr datagroup . +data_packet ::= wds8_hdr datagroup . +data_packet ::= wdp7_hdr datagroup . +data_packet ::= wdp8_hdr datagroup . +data_packet ::= wdd_date wdd_hdr datagroup . +data_packet ::= wdd_hdr datagroup . + +%type isdn_prefix { guint16 } +isdn_prefix(U16) ::= ISDN_PREFIX(A_TOK) . { U16 = A_TOK.u16_val; } + +%type ether_prefix { guint16 } +ether_prefix(U16) ::= ETHER_PREFIX(A_TOK) . { U16 = A_TOK.u16_val; } + +%type wds_prefix { guint16 } +wds_prefix(U16) ::= WDS_PREFIX(A_TOK) . { U16 = A_TOK.u16_val; } + +string ::= STRING . + +%type decnum { guint32 } +decnum(U32) ::= DECNUM(A_TOK) . { U32 = A_TOK.u32_val; } + +%type hexnum { guint32 } +hexnum(U32) ::= HEXNUM(A_TOK) . { U32 = A_TOK.u32_val; } + +%type wdd_decnum { guint32 } +wdd_decnum(U32) ::= WDD_DECNUM(A_TOK) . { U32 = A_TOK.u32_val; } + +/* + pridisp special case - I-frame header printed separately from contents, + one frame across two messages. + +PRI-XMIT-0/1: (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @ +0x80128220 + [0000]: 00 01 ae b2 .... +PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @ +0x80128224 + [0000]: 08 02 d7 e3 02 18 03 a9 83 8a ........ + +*/ +deferred_isdn_hdr ::= isdn_prefix(TYPE) decnum(SESS) SLASH_SUFFIX KEYWORD string KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } + /* because we have two data groups */ + parser_state->first_hexbyte = 0; +} + +/* +PRI-XMIT-19: (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0 + ... or ... +PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00 +*/ +isdn_hdr ::= isdn_prefix(TYPE) decnum(SESS) KEYWORD string KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } + parser_state->first_hexbyte = 0; +} + +/* +ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa +885f80e +*/ +ether_hdr ::= ether_prefix(TYPE) string KEYWORD string KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } +} + +/* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */ +/* 1 2 3 4 5 6 7 8 9 10 11 */ +wds_hdr ::= wds_prefix(TYPE) string decnum(SESS) KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + /* parser_state->pseudo_header->user is set in ascend_scanner.l */ + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } +} + +/* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */ +/* 1 2 3 4 5 6 7 8 9 10 11 12 13 */ +wds8_hdr ::= wds_prefix(TYPE) string decnum(SESS) KEYWORD string KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + /* parser_state->pseudo_header->user is set in ascend_scanner.l */ + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } +} + +/* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */ +/* 1 2 3 4 5 6 7 8 9 10 */ +wdp7_hdr ::= wds_prefix(TYPE) decnum(SESS) KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + /* parser_state->pseudo_header->user is set in ascend_scanner.l */ + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } +} + +/* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */ +/* 1 2 3 4 5 6 7 8 9 10 11 12 */ +wdp8_hdr ::= wds_prefix(TYPE) decnum(SESS) KEYWORD string KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen += WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + /* parser_state->pseudo_header->user is set in ascend_scanner.l */ + parser_state->pseudo_header->type = TYPE; + parser_state->pseudo_header->sess = SESS; + parser_state->pseudo_header->call_num[0] = '\0'; + parser_state->pseudo_header->chunk = 0; + parser_state->pseudo_header->task = TASK; + } +} + +/* +Date: 01/12/1990. Time: 12:22:33 +Cause an attempt to place call to 14082750382 +*/ +/* 1 2 3 4 5 6 7 8 9 10*/ +wdd_date ::= WDD_DATE wdd_decnum(MONTH) wdd_decnum(MDAY) wdd_decnum(YEAR) WDD_TIME wdd_decnum(HOUR) wdd_decnum(MINUTE) wdd_decnum(SECOND) WDD_CAUSE WDD_CALLNUM(CN_T) . { + /* + * Supply the date/time value to the code above us; it will use the + * first date/time value supplied as the capture start date/time. + */ + struct tm wddt; + + wddt.tm_sec = SECOND; + wddt.tm_min = MINUTE; + wddt.tm_hour = HOUR; + wddt.tm_mday = MDAY; + wddt.tm_mon = MONTH - 1; + wddt.tm_year = (YEAR > 1970) ? YEAR - 1900 : 70; + wddt.tm_isdst = -1; + + parser_state->timestamp = (guint32) mktime(&wddt); + parser_state->saw_timestamp = TRUE; + + g_strlcpy(parser_state->pseudo_header->call_num, CN_T.str_val, ASCEND_MAX_STR_LEN); +} + +/* +WD_DIALOUT_DISP: chunk 2515EE type IP. +(task: 251790, time: 994953.28) 44 octets @ 2782B8 +*/ +/* 1 2 3 4 5 6 7 8 9 10 11*/ +wdd_hdr ::= WDD_CHUNK hexnum(CHUNK) KEYWORD KEYWORD hexnum(TASK) KEYWORD decnum(SECS) decnum(USECS) decnum(WIRELEN) KEYWORD HEXNUM . { + parser_state->wirelen = WIRELEN; + parser_state->secs = SECS; + parser_state->usecs = USECS; + if (parser_state->pseudo_header != NULL) { + parser_state->pseudo_header->type = ASCEND_PFX_WDD; + parser_state->pseudo_header->user[0] = '\0'; + parser_state->pseudo_header->sess = 0; + parser_state->pseudo_header->chunk = CHUNK; + parser_state->pseudo_header->task = TASK; + } +} + +byte ::= HEXBYTE(A_TOK) . { + /* remember the position of the data group in the trace, to tip off + ascend_find_next_packet() as to where to look for the next header. */ + if (parser_state->first_hexbyte == 0) { + parser_state->first_hexbyte = file_tell(parser_state->fh) - A_TOK.length; + } + + /* XXX - if this test fails, it means that we parsed more bytes than + the header claimed there were. */ + if (parser_state->caplen < parser_state->wirelen) { + parser_state->pkt_data[parser_state->caplen] = A_TOK.u8_val; + parser_state->caplen++; + } +} + +/* XXX There must be a better way to do this... */ +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte byte . +bytegroup ::= byte byte byte byte byte . +bytegroup ::= byte byte byte byte . +bytegroup ::= byte byte byte . +bytegroup ::= byte byte . +bytegroup ::= byte . + +dataln ::= COUNTER bytegroup . + +datagroup ::= dataln dataln dataln dataln dataln dataln dataln dataln . +datagroup ::= dataln dataln dataln dataln dataln dataln dataln . +datagroup ::= dataln dataln dataln dataln dataln dataln . +datagroup ::= dataln dataln dataln dataln dataln . +datagroup ::= dataln dataln dataln dataln . +datagroup ::= dataln dataln dataln . +datagroup ::= dataln dataln . +datagroup ::= dataln . + +%syntax_error +{ + /* + * We might be parsing output that includes console session output along + * with packet dumps. + */ + (void)yypParser; + (void)yyminor; + static char *err = "non-packet data"; + + parser_state->ascend_parse_error = err; +} + +%code { + +/* Run the parser. */ +bool +run_ascend_parser(guint8 *pd, ascend_state_t *parser_state, int *err, gchar **err_info) +{ + yyscan_t scanner = NULL; + void *parser; + + if (ascend_lex_init(&scanner) != 0) { + /* errno is set if this fails */ + *err = errno; + *err_info = NULL; + return false; + } + /* Associate the parser state with the lexical analyzer state */ + ascend_set_extra(parser_state, scanner); + parser_state->ascend_parse_error = NULL; + parser_state->err = 0; + parser_state->err_info = NULL; + parser_state->pkt_data = pd; + + /* + * We haven't seen a time stamp yet. + */ + parser_state->saw_timestamp = FALSE; + parser_state->timestamp = 0; + + parser_state->first_hexbyte = 0; + parser_state->caplen = 0; + parser_state->wirelen = 0; + + parser_state->secs = 0; + parser_state->usecs = 0; + + /* + * Not all packets in a "wdd" dump necessarily have a "Cause an + * attempt to place call to" header (I presume this can happen if + * there was a call in progress when the packet was sent or + * received), so we won't necessarily have the phone number for + * the packet. + * + * XXX - we could assume, in the sequential pass, that it's the + * phone number from the last call, and remember that for use + * when doing random access. + */ + parser_state->pseudo_header->call_num[0] = '\0'; + + parser = AscendParserAlloc(g_malloc); + +#ifdef ASCEND_PARSER_DEBUG + AscendParserTrace(stderr, "=AP "); +#endif + + int token_id; + do { + token_id = ascend_lex(scanner); + + ascend_debug("Got token %d at %" G_GINT64_MODIFIER "d", token_id, file_tell(parser_state->fh)); + + AscendParser(parser, token_id, parser_state->token, parser_state); + } while (token_id && !parser_state->err && !parser_state->ascend_parse_error && parser_state->caplen < ASCEND_MAX_PKT_LEN); + + AscendParserFree(parser, g_free); + ascend_lex_destroy(scanner); + + if (parser_state->err) { + *err = parser_state->err; + *err_info = parser_state->err_info; + return false; + } + + return true; +} + +} // %code diff --git a/wiretap/ascend_scanner.l b/wiretap/ascend_scanner.l index befe5aa019..5058980849 100644 --- a/wiretap/ascend_scanner.l +++ b/wiretap/ascend_scanner.l @@ -8,12 +8,6 @@ */ %option reentrant -/* - * We want to generate code that can be used by a reentrant parser - * generated by Bison or Berkeley YACC. - */ -%option bison-bridge - /* * We don't read interactively from the terminal. */ @@ -30,10 +24,10 @@ %option extra-type="ascend_state_t *" /* - * Prefix scanner routines with "ascend" rather than "yy", so this scanner + * Prefix scanner routines with "ascend_" rather than "yy", so this scanner * can coexist with other scanners. */ -%option prefix="ascend" +%option prefix="ascend_" /* * We have to override the memory allocators so that we don't get @@ -63,7 +57,7 @@ #include "wtap-int.h" #include "ascendtext.h" #include "ascend-int.h" -#include "ascend.h" +#include "ascend_parser.h" #include "file_wrappers.h" /* @@ -71,21 +65,29 @@ */ DIAG_OFF_FLEX -#define YY_INPUT(buf,result,max_size) { \ - ascend_state_t *parser_state = ascendget_extra(yyscanner); \ - int c = file_getc(parser_state->fh); \ - if (c == EOF) { \ - parser_state->err = file_error(parser_state->fh, \ - &parser_state->err_info); \ - if (parser_state->err == 0) \ - parser_state->err = WTAP_ERR_SHORT_READ; \ - result = YY_NULL; \ - } else { \ - buf[0] = c; \ - result = 1; \ - } \ +static int ascend_yyinput(void *buf, ascend_state_t *parser_state) { + int c = file_getc(parser_state->fh); + if (c == EOF) { + parser_state->err = file_error(parser_state->fh, + &parser_state->err_info); + if (parser_state->err == 0) + parser_state->err = WTAP_ERR_SHORT_READ; + return YY_NULL; + } else { + *(char *) buf = c; + return 1; + } } +#define YY_INPUT(buf, result, max_size) \ + do { (result) = ascend_yyinput((buf), yyextra); } while (0) + + +/* Count bytes read. This is required in order to rewind the file + * to the beginning of the next packet, since flex reads more bytes + * before executing the action that does yyterminate(). */ +#define YY_USER_ACTION do { yyextra->token.length = yyleng; } while (0); + #define NO_USER "" #ifndef HAVE_UNISTD_H @@ -100,9 +102,9 @@ DIAG_OFF_FLEX /* * Macros for the allocators, to discard the extra argument. */ -#define ascendalloc(size, yyscanner) (void *)malloc(size) -#define ascendrealloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size)) -#define ascendfree(ptr, yyscanner) free((char *)ptr) +#define ascend_alloc(size, yyscanner) (void *)malloc(size) +#define ascend_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size)) +#define ascend_free(ptr, yyscanner) free((char *)ptr) %} @@ -155,45 +157,45 @@ WDD_TYPE "type "[^\n\r\t ]+ %% {ETHER_PFX} { - BEGIN(sc_ether_direction); - yylval->d = ASCEND_PFX_ETHER; - return ETHER_PREFIX; + BEGIN(sc_ether_direction); + yyextra->token.u16_val = ASCEND_PFX_ETHER; + return ETHER_PREFIX; } {ISDN_XPFX} { - BEGIN(sc_isdn_call); - yylval->d = ASCEND_PFX_ISDN_X; - return ISDN_PREFIX; + BEGIN(sc_isdn_call); + yyextra->token.u16_val = ASCEND_PFX_ISDN_X; + return ISDN_PREFIX; } {ISDN_RPFX} { - BEGIN(sc_isdn_call); - yylval->d = ASCEND_PFX_ISDN_R; - return ISDN_PREFIX; + BEGIN(sc_isdn_call); + yyextra->token.u16_val = ASCEND_PFX_ISDN_R; + return ISDN_PREFIX; } {WAN_XPFX} { - BEGIN(sc_wds_user); - yylval->d = ASCEND_PFX_WDS_X; - return WDS_PREFIX; + BEGIN(sc_wds_user); + yyextra->token.u16_val = ASCEND_PFX_WDS_X; + return WDS_PREFIX; } {WAN_RPFX} { - BEGIN(sc_wds_user); - yylval->d = ASCEND_PFX_WDS_R; - return WDS_PREFIX; + BEGIN(sc_wds_user); + yyextra->token.u16_val = ASCEND_PFX_WDS_R; + return WDS_PREFIX; } {PPP_XPFX} { - BEGIN(sc_wds_user); - yylval->d = ASCEND_PFX_WDS_X; - return WDS_PREFIX; + BEGIN(sc_wds_user); + yyextra->token.u16_val = ASCEND_PFX_WDS_X; + return WDS_PREFIX; } {PPP_RPFX} { - BEGIN(sc_wds_user); - yylval->d = ASCEND_PFX_WDS_R; - return WDS_PREFIX; + BEGIN(sc_wds_user); + yyextra->token.u16_val = ASCEND_PFX_WDS_R; + return WDS_PREFIX; } /* @@ -206,8 +208,8 @@ WDD_TYPE "type "[^\n\r\t ]+ * XXX - any reason to require at least two of them? */ [^\(]{2,20} { - BEGIN(sc_gen_task); - return STRING; + BEGIN(sc_gen_task); + return STRING; } /* @@ -218,171 +220,176 @@ WDD_TYPE "type "[^\n\r\t ]+ * characters. Limit it to 20 characters. */ [^\/\(:]{1,20} { - BEGIN(sc_gen_task); - return DECNUM; + BEGIN(sc_gen_task); + return DECNUM; } [^:]{2,20} { - char *atcopy = g_strdup(yytext); - char colon = input(yyscanner); - char after = input(yyscanner); - int retval = STRING; + char *atcopy = g_strdup(yytext); + char colon = input(yyscanner); + char after = input(yyscanner); + int retval = STRING; - unput(after); unput(colon); + unput(after); unput(colon); - if (after != '(' && after != ' ') { - BEGIN(sc_wds_sess); - if (yyextra->pseudo_header != NULL) { - g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN); + if (after != '(' && after != ' ') { + BEGIN(sc_wds_sess); + if (yyextra->pseudo_header != NULL && yyextra->pseudo_header->user[0] == '\0') { + g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN); + } + } else { /* We have a version 7 file */ + BEGIN(sc_gen_task); + if (yyextra->pseudo_header != NULL && yyextra->pseudo_header->user[0] == '\0') { + g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN); + } + /* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */ + /* upstream code accordingly. */ + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + retval = DECNUM; } - } else { /* We have a version 7 file */ - BEGIN(sc_gen_task); - if (yyextra->pseudo_header != NULL) { - g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN); - } - /* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */ - /* upstream code accordingly. */ - yylval->d = (guint32) strtoul(yytext, NULL, 10); - retval = DECNUM; - } - g_free (atcopy); - return retval; + g_free (atcopy); + return retval; } {D}* { - BEGIN(sc_gen_task); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_gen_task); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return DECNUM; } (0x|0X)?{H}{2,8} { - BEGIN(sc_gen_time_s); - yylval->d = (guint32) strtoul(yytext, NULL, 16); - return HEXNUM; + BEGIN(sc_gen_time_s); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 16); + return HEXNUM; } \"[A-Za-z0-9_ ]+\" { - return STRING; + return STRING; } {D}{1,10} { - BEGIN(sc_gen_time_u); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_gen_time_u); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return DECNUM; } {D}{1,6} { - char *atcopy = g_strdup(yytext); - BEGIN(sc_gen_octets); - /* only want the most significant 2 digits. convert to usecs */ - if (strlen(atcopy) > 2) - atcopy[2] = '\0'; - yylval->d = (guint32) strtoul(atcopy, NULL, 10) * 10000; - g_free(atcopy); - return DECNUM; + char *atcopy = g_strdup(yytext); + BEGIN(sc_gen_octets); + /* only want the most significant 2 digits. convert to usecs */ + if (strlen(atcopy) > 2) + atcopy[2] = '\0'; + yyextra->token.u32_val = (guint32) strtoul(atcopy, NULL, 10) * 10000; + g_free(atcopy); + return DECNUM; } {D}{1,10} { - BEGIN(sc_gen_counter); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_gen_counter); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return DECNUM; } "["{H}{4}"]:" { - BEGIN(sc_gen_byte); - return COUNTER; + BEGIN(sc_gen_byte); + return COUNTER; } {H}{2} { - yylval->b = (guint8)(guint32) strtoul(yytext, NULL, 16); - return HEXBYTE; + yyextra->token.u8_val = (guint8) strtoul(yytext, NULL, 16); + return HEXBYTE; } " "{4} { - BEGIN(sc_chardisp); + BEGIN(sc_chardisp); } .* { - BEGIN(sc_gen_byte); + BEGIN(sc_gen_byte); } {WDD_DATE} { - BEGIN(sc_wdd_date_d); - return WDD_DATE; -} - -{D}{2} { - BEGIN(sc_wdd_date_m); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_wdd_date_m); + return WDD_DATE; } + /* + * Scan m/d/y as three separate m, /d/, and y tokens. + * We could alternately treat m/d/y as a single token. + */ {D}{2} { - BEGIN(sc_wdd_date_y); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_wdd_date_d); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return WDD_DECNUM; +} + +\/{D}{2}\/ { + BEGIN(sc_wdd_date_y); + yyextra->token.u32_val = (guint32) strtoul(yytext+1, NULL, 10); + return WDD_DECNUM; } {D}{4} { - BEGIN(sc_wdd_time); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_wdd_time); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return WDD_DECNUM; } {WDD_TIME} { - BEGIN(sc_wdd_time_h); - return KEYWORD; + BEGIN(sc_wdd_time_h); + return WDD_TIME; } + /* + * Scan h:m:s as three separate h, :m:, and s tokens similar to above. + */ {D}{2} { - BEGIN(sc_wdd_time_m); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_wdd_time_m); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return WDD_DECNUM; } -{D}{2} { - BEGIN(sc_wdd_time_s); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; +:{D}{2}: { + BEGIN(sc_wdd_time_s); + yyextra->token.u32_val = (guint32) strtoul(yytext+1, NULL, 10); + return WDD_DECNUM; } {D}{2} { - BEGIN(sc_wdd_cause); - yylval->d = (guint32) strtoul(yytext, NULL, 10); - return DECNUM; + BEGIN(sc_wdd_cause); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 10); + return WDD_DECNUM; } {WDD_CAUSE} { - BEGIN(sc_wdd_callnum); - return KEYWORD; + BEGIN(sc_wdd_callnum); + return WDD_CAUSE; } {WDD_CALLNUM} { - BEGIN(sc_wdd_chunk); - if (yyextra->pseudo_header != NULL) { - g_strlcpy(yyextra->pseudo_header->call_num, yytext, ASCEND_MAX_STR_LEN); - } - return STRING; + BEGIN(sc_wdd_chunk); + g_strlcpy(yyextra->token.str_val, yytext, ASCEND_MAX_STR_LEN); + return WDD_CALLNUM; } {WDD_CHUNK} { - BEGIN(sc_wdd_chunknum); - return WDD_CHUNK; + BEGIN(sc_wdd_chunknum); + return WDD_CHUNK; } {H}{1,8} { - BEGIN(sc_wdd_type); - yylval->d = (guint32) strtoul(yytext, NULL, 16); - return HEXNUM; + BEGIN(sc_wdd_type); + yyextra->token.u32_val = (guint32) strtoul(yytext, NULL, 16); + return HEXNUM; } {WDD_TYPE} { - BEGIN(sc_gen_task); - return KEYWORD; + BEGIN(sc_gen_task); + return KEYWORD; } \/{D}+ { - return SLASH_SUFFIX; + return SLASH_SUFFIX; } (0x|0X)?{H}+ { return HEXNUM; } diff --git a/wiretap/ascendtext.c b/wiretap/ascendtext.c index 47ec6e182c..5a24215572 100644 --- a/wiretap/ascendtext.c +++ b/wiretap/ascendtext.c @@ -23,46 +23,54 @@ /* Last updated: Feb 03 2005: Josh Bailey (joshbailey@lucent.com). This module reads the text hex dump output of various TAOS - (Lucent/Ascend Max, Max TNT, APX, etc) debug commands, including: + (Avaya/Alcatel/Lucent/Ascend Max, Max TNT, APX, etc) debug commands, including: * pridisplay traces primary rate ISDN * ether-display traces Ethernet packets (dangerous! CPU intensive) * wanopening, wandisplay, wannext, wandsess traces PPP or other WAN connections - Please see ascend.y for examples. + Please see ascend_parser.lemon for examples. Detailed documentation on TAOS products was at http://support.lucent.com; that no longer works, and appears not to be available on the Wayback Machine. - Some online manuals include: + Some online manuals and other information include: MAX Administration Guide: https://downloads.avaya.com/elmodocs2/definity/def_r10_new/max/0678_002.pdf - Support for other commands will be added on an ongoing basis. */ + Other MAX documentation: + https://support.avaya.com/products/P1192/max + https://web.archive.org/web/20201127014004/https://support.avaya.com/products/P1192/max#Tab4 + + Ascend Router Information: + http://maxrouter.rde.net/ + https://web.archive.org/web/20200807215418/http://maxrouter.rde.net/ + + */ typedef struct _ascend_magic_string { - guint type; - const gchar *strptr; - size_t strlength; + guint type; + const gchar *strptr; + size_t strlength; } ascend_magic_string; /* these magic strings signify the headers of a supported debug commands */ #define ASCEND_MAGIC_ENTRY(type, string) \ - { type, string, sizeof string - 1 } /* strlen of a constant string */ + { type, string, sizeof string - 1 } /* strlen of a constant string */ static const ascend_magic_string ascend_magic[] = { - ASCEND_MAGIC_ENTRY(ASCEND_PFX_ISDN_X, "PRI-XMIT-"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_ISDN_R, "PRI-RCV-"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "XMIT-"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "RECV-"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "XMIT:"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "RECV:"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "PPP-OUT"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "PPP-IN"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDD, "WD_DIALOUT_DISP:"), - ASCEND_MAGIC_ENTRY(ASCEND_PFX_ETHER, "ETHER"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_ISDN_X, "PRI-XMIT-"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_ISDN_R, "PRI-RCV-"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "XMIT-"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "RECV-"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "XMIT:"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "RECV:"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_X, "PPP-OUT"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDS_R, "PPP-IN"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_WDD, "WD_DIALOUT_DISP:"), + ASCEND_MAGIC_ENTRY(ASCEND_PFX_ETHER, "ETHER"), }; #define ASCEND_MAGIC_STRINGS G_N_ELEMENTS(ascend_magic) @@ -80,213 +88,214 @@ static gboolean ascend_seek_read(wtap *wth, gint64 seek_off, Returns -1 on failure. */ static gint64 ascend_find_next_packet(wtap *wth, int *err, gchar **err_info) { - int byte; - gint64 date_off = -1, cur_off, packet_off; - size_t string_level[ASCEND_MAGIC_STRINGS]; - guint string_i = 0; - static const gchar ascend_date[] = ASCEND_DATE; - size_t ascend_date_len = sizeof ascend_date - 1; /* strlen of a constant string */ - size_t ascend_date_string_level; - guint excessive_read_count = 262144; + int byte; + gint64 date_off = -1, cur_off, packet_off; + size_t string_level[ASCEND_MAGIC_STRINGS]; + guint string_i = 0; + static const gchar ascend_date[] = ASCEND_DATE; + size_t ascend_date_len = sizeof ascend_date - 1; /* strlen of a constant string */ + size_t ascend_date_string_level; + guint excessive_read_count = 262144; - memset(&string_level, 0, sizeof(string_level)); - ascend_date_string_level = 0; + memset(&string_level, 0, sizeof(string_level)); + ascend_date_string_level = 0; - while (((byte = file_getc(wth->fh)) != EOF)) { - excessive_read_count--; + while (((byte = file_getc(wth->fh)) != EOF)) { + excessive_read_count--; - if (!excessive_read_count) { - *err = 0; - return -1; - } - - /* - * See whether this is the string_level[string_i]th character of - * Ascend magic string string_i. - */ - for (string_i = 0; string_i < ASCEND_MAGIC_STRINGS; string_i++) { - const gchar *strptr = ascend_magic[string_i].strptr; - size_t len = ascend_magic[string_i].strlength; - - if (byte == *(strptr + string_level[string_i])) { - /* - * Yes, it is, so we need to check for the next character of - * that string. - */ - string_level[string_i]++; + if (!excessive_read_count) { + *err = 0; + return -1; + } /* - * Have we matched the entire string? - */ - if (string_level[string_i] >= len) { - /* - * Yes. - */ - cur_off = file_tell(wth->fh); - if (cur_off == -1) { + * See whether this is the string_level[string_i]th character of + * Ascend magic string string_i. + */ + for (string_i = 0; string_i < ASCEND_MAGIC_STRINGS; string_i++) { + const gchar *strptr = ascend_magic[string_i].strptr; + size_t len = ascend_magic[string_i].strlength; + + if (byte == *(strptr + string_level[string_i])) { + /* + * Yes, it is, so we need to check for the next character of + * that string. + */ + string_level[string_i]++; + + /* + * Have we matched the entire string? + */ + if (string_level[string_i] >= len) { + /* + * Yes. + */ + cur_off = file_tell(wth->fh); + if (cur_off == -1) { + /* Error. */ + *err = file_error(wth->fh, err_info); + return -1; + } + + /* We matched some other type of header. */ + if (date_off == -1) { + /* We haven't yet seen a date header, so this packet + doesn't have one. + Back up over the header we just read; that's where a read + of this packet should start. */ + packet_off = cur_off - len; + } else { + /* This packet has a date/time header; a read of it should + start at the beginning of *that* header. */ + packet_off = date_off; + } + + goto found; + } + } else { + /* + * Not a match for this string, so reset the match process. + */ + string_level[string_i] = 0; + } + } + + /* + * See whether this is the date_string_level'th character of + * ASCEND_DATE. + */ + if (byte == *(ascend_date + ascend_date_string_level)) { + /* + * Yes, it is, so we need to check for the next character of + * that string. + */ + ascend_date_string_level++; + + /* + * Have we matched the entire string? + */ + if (ascend_date_string_level >= ascend_date_len) { + /* We matched a Date: header. It's a special case; + remember the offset, but keep looking for other + headers. + + Reset the amount of Date: header that we've matched, + so that we start the process of matching a Date: + header all over again. + + XXX - what if we match multiple Date: headers before + matching some other header? */ + cur_off = file_tell(wth->fh); + if (cur_off == -1) { /* Error. */ *err = file_error(wth->fh, err_info); return -1; - } + } - /* We matched some other type of header. */ - if (date_off == -1) { - /* We haven't yet seen a date header, so this packet - doesn't have one. - Back up over the header we just read; that's where a read - of this packet should start. */ - packet_off = cur_off - len; - } else { - /* This packet has a date/time header; a read of it should - start at the beginning of *that* header. */ - packet_off = date_off; - } - - goto found; + date_off = cur_off - ascend_date_len; + ascend_date_string_level = 0; } - } else { + } else { /* - * Not a match for this string, so reset the match process. - */ - string_level[string_i] = 0; - } - } - - /* - * See whether this is the date_string_level'th character of - * ASCEND_DATE. - */ - if (byte == *(ascend_date + ascend_date_string_level)) { - /* - * Yes, it is, so we need to check for the next character of - * that string. - */ - ascend_date_string_level++; - - /* - * Have we matched the entire string? - */ - if (ascend_date_string_level >= ascend_date_len) { - /* We matched a Date: header. It's a special case; - remember the offset, but keep looking for other - headers. - - Reset the amount of Date: header that we've matched, - so that we start the process of matching a Date: - header all over again. - - XXX - what if we match multiple Date: headers before - matching some other header? */ - cur_off = file_tell(wth->fh); - if (cur_off == -1) { - /* Error. */ - *err = file_error(wth->fh, err_info); - return -1; - } - - date_off = cur_off - ascend_date_len; + * Not a match for the Date: string, so reset the match process. + */ ascend_date_string_level = 0; - } - } else { - /* - * Not a match for the Date: string, so reset the match process. - */ - ascend_date_string_level = 0; + } } - } - *err = file_error(wth->fh, err_info); - return -1; - -found: - /* - * Move to where the read for this packet should start, and return - * that seek offset. - */ - if (file_seek(wth->fh, packet_off, SEEK_SET, err) == -1) + *err = file_error(wth->fh, err_info); return -1; - return packet_off; +found: + /* + * Move to where the read for this packet should start, and return + * that seek offset. + */ + if (file_seek(wth->fh, packet_off, SEEK_SET, err) == -1) + return -1; + + return packet_off; } wtap_open_return_val ascend_open(wtap *wth, int *err, gchar **err_info) { - gint64 offset; - guint8 buf[ASCEND_MAX_PKT_LEN]; - ascend_state_t parser_state; - ws_statb64 statbuf; - ascend_t *ascend; - wtap_rec rec; + gint64 offset; + guint8 buf[ASCEND_MAX_PKT_LEN]; + ascend_state_t parser_state = {0}; + ws_statb64 statbuf; + ascend_t *ascend; + wtap_rec rec; - /* We haven't yet allocated a data structure for our private stuff; - set the pointer to null, so that "ascend_find_next_packet()" knows - not to fill it in. */ - wth->priv = NULL; + /* We haven't yet allocated a data structure for our private stuff; + set the pointer to null, so that "ascend_find_next_packet()" knows + not to fill it in. */ + wth->priv = NULL; - offset = ascend_find_next_packet(wth, err, err_info); - if (offset == -1) { - if (*err != 0 && *err != WTAP_ERR_SHORT_READ) - return WTAP_OPEN_ERROR; /* read error */ - return WTAP_OPEN_NOT_MINE; /* EOF */ - } + offset = ascend_find_next_packet(wth, err, err_info); + if (offset == -1) { + if (*err != 0 && *err != WTAP_ERR_SHORT_READ) + return WTAP_OPEN_ERROR; /* read error */ + return WTAP_OPEN_NOT_MINE; /* EOF */ + } - /* Do a trial parse of the first packet just found to see if we might - really have an Ascend file. If it fails with an actual error, - fail; those will be I/O errors. */ - if (run_ascend_parser(wth->fh, &rec, buf, &parser_state, err, - err_info) != 0 && *err != 0) { - /* An I/O error. */ - return WTAP_OPEN_ERROR; - } + /* Do a trial parse of the first packet just found to see if we might + really have an Ascend file. If it fails with an actual error, + fail; those will be I/O errors. */ + parser_state.fh = wth->fh; + parser_state.pseudo_header = &rec.rec_header.packet_header.pseudo_header.ascend; + if (run_ascend_parser(buf, &parser_state, err, err_info) != 0 && *err != 0) { + /* An I/O error. */ + return WTAP_OPEN_ERROR; + } - /* Either the parse succeeded, or it failed but didn't get an I/O - error. + /* Either the parse succeeded, or it failed but didn't get an I/O + error. - If we got at least some data, return success even if the parser - reported an error. This is because the debug header gives the - number of bytes on the wire, not actually how many bytes are in - the trace. We won't know where the data ends until we run into - the next packet. */ - if (parser_state.caplen == 0) { - /* We read no data, so this presumably isn't an Ascend file. */ - return WTAP_OPEN_NOT_MINE; - } + If we got at least some data, return success even if the parser + reported an error. This is because the debug header gives the + number of bytes on the wire, not actually how many bytes are in + the trace. We won't know where the data ends until we run into + the next packet. */ + if (parser_state.caplen == 0) { + /* We read no data, so this presumably isn't an Ascend file. */ + return WTAP_OPEN_NOT_MINE; + } - wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ASCEND; - wth->file_encap = WTAP_ENCAP_ASCEND; + wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ASCEND; + wth->file_encap = WTAP_ENCAP_ASCEND; - wth->snapshot_length = ASCEND_MAX_PKT_LEN; - wth->subtype_read = ascend_read; - wth->subtype_seek_read = ascend_seek_read; - ascend = (ascend_t *)g_malloc(sizeof(ascend_t)); - wth->priv = (void *)ascend; + wth->snapshot_length = ASCEND_MAX_PKT_LEN; + wth->subtype_read = ascend_read; + wth->subtype_seek_read = ascend_seek_read; + ascend = (ascend_t *)g_malloc(sizeof(ascend_t)); + wth->priv = (void *)ascend; - /* The first packet we want to read is the one that - "ascend_find_next_packet()" just found; start searching - for it at the offset at which it found it. */ - ascend->next_packet_seek_start = offset; + /* The first packet we want to read is the one that + "ascend_find_next_packet()" just found; start searching + for it at the offset at which it found it. */ + ascend->next_packet_seek_start = offset; - /* MAXen and Pipelines report the time since reboot. In order to keep - from reporting packet times near the epoch, we subtract the first - packet's timestamp from the capture file's ctime, which gives us an - offset that we can apply to each packet. - */ - if (wtap_fstat(wth, &statbuf, err) == -1) { - return WTAP_OPEN_ERROR; - } - ascend->inittime = statbuf.st_ctime; - ascend->adjusted = FALSE; - wth->file_tsprec = WTAP_TSPREC_USEC; + /* MAXen and Pipelines report the time since reboot. In order to keep + from reporting packet times near the epoch, we subtract the first + packet's timestamp from the capture file's ctime, which gives us an + offset that we can apply to each packet. + */ + if (wtap_fstat(wth, &statbuf, err) == -1) { + return WTAP_OPEN_ERROR; + } + ascend->inittime = statbuf.st_ctime; + ascend->adjusted = FALSE; + wth->file_tsprec = WTAP_TSPREC_USEC; - /* - * Add an IDB; we don't know how many interfaces were - * involved, so we just say one interface, about which - * we only know the link-layer type, snapshot length, - * and time stamp resolution. - */ - wtap_add_generated_idb(wth); + /* + * Add an IDB; we don't know how many interfaces were + * involved, so we just say one interface, about which + * we only know the link-layer type, snapshot length, + * and time stamp resolution. + */ + wtap_add_generated_idb(wth); - return WTAP_OPEN_MINE; + return WTAP_OPEN_MINE; } /* Parse the capture file. @@ -296,161 +305,150 @@ parse_ascend(ascend_t *ascend, FILE_T fh, wtap_rec *rec, Buffer *buf, guint length, gint64 *next_packet_seek_start_ret, int *err, gchar **err_info) { - ascend_state_t parser_state; - int retval; + ascend_state_t parser_state = {0}; + int retval; - ws_buffer_assure_space(buf, length); - retval = run_ascend_parser(fh, rec, ws_buffer_start_ptr(buf), &parser_state, - err, err_info); + ws_buffer_assure_space(buf, length); + parser_state.fh = fh; + parser_state.pseudo_header = &rec->rec_header.packet_header.pseudo_header.ascend; - /* Did we see any data (hex bytes)? */ - if (parser_state.first_hexbyte) { - /* Yes. Provide the offset of the first byte so that our caller can - tip off ascend_find_next_packet() as to where to look for the next - packet, if any. */ - if (next_packet_seek_start_ret != NULL) - *next_packet_seek_start_ret = parser_state.first_hexbyte; - } else { - /* No. Maybe this record was broken; sometimes, a header will be - printed but the data will be omitted, or worse -- two headers will - be printed, followed by the data for each. + retval = run_ascend_parser(ws_buffer_start_ptr(buf), &parser_state, err, err_info); - Because of this, we need to be fairly tolerant of what we accept - here. Provide our current offset so that our caller can tell - ascend_find_next_packet() to skip over what we've read so far so - we can try reading a new packet. + /* Did we see any data (hex bytes)? */ + if (parser_state.first_hexbyte) { + /* Yes. Provide the offset of the first byte so that our caller can + tip off ascend_find_next_packet() as to where to look for the next + packet, if any. */ + if (next_packet_seek_start_ret != NULL) + *next_packet_seek_start_ret = parser_state.first_hexbyte; + } else { + /* No. Maybe this record was broken; sometimes, a header will be + printed but the data will be omitted, or worse -- two headers will + be printed, followed by the data for each. - . That keeps us from getting into an infinite loop reading a broken - trace. */ - if (next_packet_seek_start_ret != NULL) - *next_packet_seek_start_ret = file_tell(fh); + Because of this, we need to be fairly tolerant of what we accept + here. Provide our current offset so that our caller can tell + ascend_find_next_packet() to skip over what we've read so far so + we can try reading a new packet. - /* Don't treat that as a fatal error; pretend the parse succeeded. */ - retval = 0; - } + . That keeps us from getting into an infinite loop reading a broken + trace. */ + if (next_packet_seek_start_ret != NULL) + *next_packet_seek_start_ret = file_tell(fh); - /* if we got at least some data, return success even if the parser - reported an error. This is because the debug header gives the number - of bytes on the wire, not actually how many bytes are in the trace. - We won't know where the data ends until we run into the next packet. */ - if (parser_state.caplen) { - if (! ascend->adjusted) { - ascend->adjusted = TRUE; - if (parser_state.saw_timestamp) { - /* - * Capture file contained a date and time. - * We do this only if this is the very first packet we've seen - - * i.e., if "ascend->adjusted" is false - because - * if we get a date and time after the first packet, we can't - * go back and adjust the time stamps of the packets we've already - * processed, and basing the time stamps of this and following - * packets on the time stamp from the file text rather than the - * ctime of the capture file means times before this and after - * this can't be compared. - */ - ascend->inittime = parser_state.timestamp; - } - if (ascend->inittime > parser_state.secs) - ascend->inittime -= parser_state.secs; + /* Don't treat that as a fatal error; pretend the parse succeeded. */ + retval = 0; } - rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; - rec->ts.secs = parser_state.secs + ascend->inittime; - rec->ts.nsecs = parser_state.usecs * 1000; - rec->rec_header.packet_header.caplen = parser_state.caplen; - rec->rec_header.packet_header.len = parser_state.wirelen; - return TRUE; - } + /* if we got at least some data, return success even if the parser + reported an error. This is because the debug header gives the number + of bytes on the wire, not actually how many bytes are in the trace. + We won't know where the data ends until we run into the next packet. */ + if (parser_state.caplen) { + if (! ascend->adjusted) { + ascend->adjusted = TRUE; + if (parser_state.saw_timestamp) { + /* + * Capture file contained a date and time. + * We do this only if this is the very first packet we've seen - + * i.e., if "ascend->adjusted" is false - because + * if we get a date and time after the first packet, we can't + * go back and adjust the time stamps of the packets we've already + * processed, and basing the time stamps of this and following + * packets on the time stamp from the file text rather than the + * ctime of the capture file means times before this and after + * this can't be compared. + */ + ascend->inittime = parser_state.timestamp; + } + if (ascend->inittime > parser_state.secs) + ascend->inittime -= parser_state.secs; + } + rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; + rec->ts.secs = parser_state.secs + ascend->inittime; + rec->ts.nsecs = parser_state.usecs * 1000; + rec->rec_header.packet_header.caplen = parser_state.caplen; + rec->rec_header.packet_header.len = parser_state.wirelen; - /* Didn't see any data. Still, perhaps the parser was happy. */ - if (retval) { - if (*err == 0) { - /* Parser failed, but didn't report an I/O error, so a parse error. - Return WTAP_ERR_BAD_FILE, with the parse error as the error string. */ - *err = WTAP_ERR_BAD_FILE; - *err_info = g_strdup((parser_state.ascend_parse_error != NULL) ? parser_state.ascend_parse_error : "parse error"); + return TRUE; } - } else { - if (*err == 0) { - /* Parser succeeded, but got no data, and didn't report an I/O error. - Return WTAP_ERR_BAD_FILE, with a "got no data" error string. */ - *err = WTAP_ERR_BAD_FILE; - *err_info = g_strdup("no data returned by parse"); + + /* Didn't see any data. Still, perhaps the parser was happy. */ + if (retval) { + if (*err == 0) { + /* Parser failed, but didn't report an I/O error, so a parse error. + Return WTAP_ERR_BAD_FILE, with the parse error as the error string. */ + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup((parser_state.ascend_parse_error != NULL) ? parser_state.ascend_parse_error : "parse error"); + } + } else { + if (*err == 0) { + /* Parser succeeded, but got no data, and didn't report an I/O error. + Return WTAP_ERR_BAD_FILE, with a "got no data" error string. */ + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("no data returned by parse"); + } } - } - return FALSE; + return FALSE; } /* Read the next packet; called from wtap_read(). */ static gboolean ascend_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info, gint64 *data_offset) { - ascend_t *ascend = (ascend_t *)wth->priv; - gint64 offset; + ascend_t *ascend = (ascend_t *)wth->priv; + gint64 offset; - /* parse_ascend() will advance the point at which to look for the next - packet's header, to just after the last packet's header (ie. at the - start of the last packet's data). We have to get past the last - packet's header because we might mistake part of it for a new header. */ - if (file_seek(wth->fh, ascend->next_packet_seek_start, - SEEK_SET, err) == -1) - return FALSE; + /* parse_ascend() will advance the point at which to look for the next + packet's header, to just after the last packet's header (ie. at the + start of the last packet's data). We have to get past the last + packet's header because we might mistake part of it for a new header. */ + if (file_seek(wth->fh, ascend->next_packet_seek_start, + SEEK_SET, err) == -1) + return FALSE; - offset = ascend_find_next_packet(wth, err, err_info); - if (offset == -1) { - /* EOF or read error */ - return FALSE; - } - if (!parse_ascend(ascend, wth->fh, rec, buf, wth->snapshot_length, - &ascend->next_packet_seek_start, err, err_info)) - return FALSE; + offset = ascend_find_next_packet(wth, err, err_info); + if (offset == -1) { + /* EOF or read error */ + return FALSE; + } + if (!parse_ascend(ascend, wth->fh, rec, buf, wth->snapshot_length, + &ascend->next_packet_seek_start, err, err_info)) + return FALSE; - /* Flex might have gotten an EOF and caused *err to be set to - WTAP_ERR_SHORT_READ. If so, that's not an error, as the parser - didn't return an error; set *err to 0, and get rid of any error - string. */ - *err = 0; - if (*err_info != NULL) { - g_free(*err_info); - *err_info = NULL; - } - *data_offset = offset; - return TRUE; + /* Flex might have gotten an EOF and caused *err to be set to + WTAP_ERR_SHORT_READ. If so, that's not an error, as the parser + didn't return an error; set *err to 0, and get rid of any error + string. */ + *err = 0; + if (*err_info != NULL) { + g_free(*err_info); + *err_info = NULL; + } + *data_offset = offset; + return TRUE; } static gboolean ascend_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { - ascend_t *ascend = (ascend_t *)wth->priv; + ascend_t *ascend = (ascend_t *)wth->priv; - if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) - return FALSE; - if (!parse_ascend(ascend, wth->random_fh, rec, buf, - wth->snapshot_length, NULL, err, err_info)) - return FALSE; + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + if (!parse_ascend(ascend, wth->random_fh, rec, buf, + wth->snapshot_length, NULL, err, err_info)) + return FALSE; - /* Flex might have gotten an EOF and caused *err to be set to - WTAP_ERR_SHORT_READ. If so, that's not an error, as the parser - didn't return an error; set *err to 0, and get rid of any error - string. */ - *err = 0; - if (*err_info != NULL) { - g_free(*err_info); - *err_info = NULL; - } - return TRUE; + /* Flex might have gotten an EOF and caused *err to be set to + WTAP_ERR_SHORT_READ. If so, that's not an error, as the parser + didn't return an error; set *err to 0, and get rid of any error + string. */ + *err = 0; + if (*err_info != NULL) { + g_free(*err_info); + *err_info = NULL; + } + return TRUE; } - -/* - * Editor modelines - https://www.wireshark.org/tools/modelines.html - * - * Local Variables: - * c-basic-offset: 2 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=2 tabstop=8 expandtab: - * :indentSize=2:tabSize=8:noTabs=true: - */ diff --git a/ws_diag_control.h b/ws_diag_control.h index 52799f540b..6f6aebad61 100644 --- a/ws_diag_control.h +++ b/ws_diag_control.h @@ -149,13 +149,6 @@ extern "C" { __pragma(warning(disable:6387)) \ __pragma(warning(disable:28182)) #define DIAG_ON_FLEX __pragma(warning(pop)) - - /* - * XXX - is there an issue with shadowed definitions with MSVC if - * somebody were to happen to use Berkeley YACC rather than Bison? - */ - #define DIAG_OFF_BYACC - #define DIAG_ON_BYACC #else /* * Suppress: @@ -191,28 +184,6 @@ extern "C" { #define DIAG_ON_FLEX \ DIAG_ON(sign-compare) #endif - - /* - * Berkeley YACC and, apparently, some versions of Bison, such as the - * one in Fedora 21, generate a global declaration of yylval, or the - * appropriately prefixed version of yylval, in grammar.h, *even - * though it's been told to generate a pure parser, meaning it - * doesn't have any global variables*. Other versions of Bison, such - * as the one in macOS Sierra don't do that. - * - * That causes a warning due to the local declaration in the parser - * shadowing the global declaration. - * - * So, if we have _Pragma, and have pragmas to suppress diagnostics, - * we use it to turn off -Wshadow warnings. - * - * XXX - do this for Bison only in versions of Bison with this - * problem? - */ - #define DIAG_OFF_BYACC \ - DIAG_OFF(shadow) - #define DIAG_ON_BYACC \ - DIAG_ON(shadow) #endif /*