forked from osmocom/wireshark
Remove TPG plugin and dependencies
It doesn't build with autotools and CMake. Under-documented and unmaintained. Seems to be a work-in-progress that stalled. Introduces spurious CMake dependency on yapp. Change-Id: I0dca1ccbdfd683586c05765437d4b7804ab5cc70 Reviewed-on: https://code.wireshark.org/review/23758 Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
13184fbf3a
commit
f0e12f0fd3
|
@ -1012,8 +1012,6 @@ if(ENABLE_WINSPARKLE)
|
|||
set(PACKAGELIST ${PACKAGELIST} WINSPARKLE)
|
||||
endif()
|
||||
|
||||
set(PACKAGELIST ${PACKAGELIST} YAPP)
|
||||
|
||||
set(PACKAGELIST ${PACKAGELIST} POD)
|
||||
|
||||
if(ENABLE_HTML_GUIDES)
|
||||
|
@ -1408,13 +1406,6 @@ if(ENABLE_PLUGINS)
|
|||
)
|
||||
endif()
|
||||
|
||||
# It seems this stuff doesn't build with autofoo either...
|
||||
# if(YAPP_FOUND)
|
||||
# set(PLUGIN_SRC_DIRS
|
||||
# ${PLUGIN_SRC_DIRS}
|
||||
# plugins/tpg
|
||||
# )
|
||||
# endif()
|
||||
else()
|
||||
set(PLUGIN_SRC_DIRS )
|
||||
endif()
|
||||
|
@ -1557,12 +1548,6 @@ set_package_properties(NGHTTP2 PROPERTIES
|
|||
URL "https://nghttp2.org"
|
||||
PURPOSE "Header decompression in HTTP2"
|
||||
)
|
||||
# XXX tpg plugin is not added in CMakeLists/Makefile.am, remove plugins/tpg/?
|
||||
set_package_properties(YAPP PROPERTIES
|
||||
DESCRIPTION "Yet Another Perl Parser compiler"
|
||||
URL "http://search.cpan.org/dist/Parse-Yapp/"
|
||||
PURPOSE "tpg plugin"
|
||||
)
|
||||
|
||||
string(REPLACE ";" " " _warnings_c_flags "${WS_WARNINGS_C_FLAGS}")
|
||||
message(STATUS "C-Flags: ${CMAKE_C_FLAGS} ${_warnings_c_flags}")
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#
|
||||
# - Find unix commands from cygwin
|
||||
# This module looks for some usual Unix commands.
|
||||
#
|
||||
|
||||
INCLUDE(FindCygwin)
|
||||
|
||||
FIND_PROGRAM(YAPP_EXECUTABLE
|
||||
NAMES
|
||||
yapp
|
||||
PATHS
|
||||
${CYGWIN_INSTALL_PATH}/bin
|
||||
/bin
|
||||
/usr/bin
|
||||
/usr/local/bin
|
||||
/sbin
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(YAPP DEFAULT_MSG YAPP_EXECUTABLE)
|
||||
|
||||
MARK_AS_ADVANCED(YAPP_EXECUTABLE)
|
||||
|
|
@ -522,7 +522,6 @@ plugin_src = \
|
|||
../plugins/profinet/plugin.c \
|
||||
../plugins/stats_tree/pinfo_stats_tree.c \
|
||||
../plugins/stats_tree/stats_tree_plugin.c \
|
||||
../plugins/tpg/packet-http.c \
|
||||
../plugins/transum/decoders.c \
|
||||
../plugins/transum/extractors.c \
|
||||
../plugins/transum/packet-transum.c \
|
||||
|
|
69
epan/tpg.c
69
epan/tpg.c
|
@ -1,69 +0,0 @@
|
|||
/* tpg.c
|
||||
* helper functions for TPG
|
||||
*
|
||||
* (c) 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "tpg.h"
|
||||
#include <epan/wmem/wmem.h>
|
||||
#include <epan/packet.h>
|
||||
|
||||
extern guint32 tpg_ipv4(tvbparse_elem_t* e _U_) {
|
||||
/* XXX TO DO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern guint8* tpg_ipv6(tvbparse_elem_t* e _U_) {
|
||||
/* XXX TO DO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern tpg_parser_data_t* tpg_start(proto_tree* root_tree,
|
||||
tvbuff_t* tvb,
|
||||
int offset,
|
||||
int len,
|
||||
tvbparse_wanted_t* ignore,
|
||||
void* private_data) {
|
||||
tpg_parser_data_t* tpg = wmem_new(wmem_packet_scope(), tpg_parser_data_t);
|
||||
tpg->private_data = private_data;
|
||||
tpg->tt = tvbparse_init(tvb,offset,len,tpg,ignore);
|
||||
|
||||
tpg->stack = wmem_stack_new(wmem_packet_scope());
|
||||
wmem_stack_push(tpg->stack, root_tree);
|
||||
|
||||
return tpg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
82
epan/tpg.h
82
epan/tpg.h
|
@ -1,82 +0,0 @@
|
|||
/* tpg.h
|
||||
* Definitions of helper functions for TPG
|
||||
*
|
||||
* (c) 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _TPG_H_
|
||||
#define _TPG_H_
|
||||
|
||||
#include <glib.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/proto.h>
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/tvbparse.h>
|
||||
#include <epan/wmem/wmem.h>
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
typedef struct _tpg_parser_data_t {
|
||||
wmem_stack_t *stack;
|
||||
tvbparse_t* tt;
|
||||
void* private_data;
|
||||
} tpg_parser_data_t;
|
||||
|
||||
extern tpg_parser_data_t* tpg_start(proto_tree* root_tree,
|
||||
tvbuff_t* tvb,
|
||||
int offset,
|
||||
int len,
|
||||
tvbparse_wanted_t* ignore,
|
||||
void* private_data);
|
||||
|
||||
#define TPG_START(tree,tvb,offset,len,data) tpg_start((tree),(tvb),(offset),(len),(data))
|
||||
|
||||
#define TPG_GET(tpg, wanted) tvbparse_get((tpg)->tt,(wanted))
|
||||
#define TPG_FIND(tpg, wanted) tvbparse_find((tpg)->tt,(wanted))
|
||||
|
||||
#define TPG_TREE(vp) (((tpg_parser_data_t*)(vp))->tree)
|
||||
#define TPG_DATA(vp,type) (((type*)(((tpg_parser_data_t*)(vp))->private_data)))
|
||||
|
||||
#define TPG_STRING(i) tvb_get_string_enc(wmem_packet_scope(), (i)->tvb,(i)->offset,(i)->len, ENC_ASCII)
|
||||
#define TPG_INT(i) strtol(tvb_get_string_enc(wmem_packet_scope(), (i)->tvb,(i)->offset,(i)->len, ENC_ASCII),NULL,10)
|
||||
#define TPG_UINT(i) strtoul(tvb_get_string_enc(wmem_packet_scope(), (i)->tvb,(i)->offset,(i)->len, ENC_ASCII),NULL,10)
|
||||
#define TPG_UINT_HEX(i) strtoul(tvb_get_string_enc(wmem_packet_scope(), (i)->tvb,(i)->offset,(i)->len, ENC_ASCII),NULL,16)
|
||||
#define TPG_TVB(i) tvb_new_subset_length_caplen((i)->tvb,(i)->offset,(i)->len,(i)->len)
|
||||
|
||||
WS_DLL_PUBLIC guint32 tpg_ipv4(tvbparse_elem_t*);
|
||||
#define TPG_IPV4(i) tpg_ipv4((i))
|
||||
|
||||
WS_DLL_PUBLIC guint8* tpg_ipv6(tvbparse_elem_t*);
|
||||
#define TPG_IPV6(i) tpg_ipv6((i))
|
||||
|
||||
#define TPG_PUSH(tpg,pi,ett) wmem_stack_push(((tpg_parser_data_t*)(tpg))->stack,proto_item_add_subtree((pi),(ett)))
|
||||
#define TPG_POP(tpg) wmem_stack_pop(((tpg_parser_data_t*)(tpg))->stack) ;
|
||||
|
||||
#define TPG_ADD_STRING(tpg, hfid, elem) proto_tree_add_item(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, FALSE)
|
||||
#define TPG_ADD_BOOLEAN(tpg, hfid, elem) proto_tree_add_boolean(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, TRUE)
|
||||
#define TPG_ADD_INT(tpg, hfid, elem, value) proto_tree_add_int(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
|
||||
#define TPG_ADD_UINT(tpg, hfid, elem, value) proto_tree_add_uint(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
|
||||
#define TPG_ADD_IPV4(tpg, hfid, elem, value) proto_tree_add_ipv4(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
|
||||
#define TPG_ADD_IPV6(tpg, hfid, elem, value) proto_tree_add_ipv6(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
|
||||
#define TPG_ADD_TEXT(tpg, elem) proto_tree_add_format_text(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), (elem)->tvb, (elem)->offset, (elem)->len)
|
||||
|
||||
#define TPG_SET_TEXT(pi, elem) proto_item_set_text((pi), "%s",tvb_format_text((elem)->tvb, (elem)->offset, (elem)->len))
|
||||
|
||||
#endif /* _TPG_H_ */
|
|
@ -1,92 +0,0 @@
|
|||
# CMakeLists.txt
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
include(WiresharkPlugin)
|
||||
|
||||
# Plugin name and version info (major minor micro extra)
|
||||
# set_plugin_properties(tpg ...)
|
||||
|
||||
set(PLUGIN_FILES
|
||||
http-parser.c
|
||||
packet-http.c
|
||||
)
|
||||
|
||||
set(CLEAN_FILES
|
||||
${PLUGIN_FILES}
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
${CLEAN_FILES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(_tpg ${CMAKE_SOURCE_DIR}/tools/tpg)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT
|
||||
TPG.pm
|
||||
COMMAND ${YAPP_EXECUTABLE}
|
||||
-v
|
||||
-m TPG
|
||||
${_tpg}/tpg.yp
|
||||
DEPENDS
|
||||
${_tpg}/tpg.yp
|
||||
)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT
|
||||
http-parser.h
|
||||
http-parser.c
|
||||
COMMAND ${PERL_EXECUTABLE}
|
||||
-I${CMAKE_BINARY_DIR}
|
||||
-I${_tpg}
|
||||
${_tpg}/tpg.pl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/http.tpg
|
||||
DEPENDS
|
||||
${_tpg}/tpg.pl
|
||||
TPG.pm
|
||||
${_tpg}/V2P.pm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/http.tpg
|
||||
)
|
||||
|
||||
add_plugin_library(tpg)
|
||||
|
||||
install(TARGETS tpg
|
||||
LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP
|
||||
RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
#
|
||||
# Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
#
|
||||
# Local variables:
|
||||
# c-basic-offset: 8
|
||||
# tab-width: 8
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
#
|
||||
# vi: set shiftwidth=8 tabstop=8 noexpandtab:
|
||||
# :indentSize=8:tabSize=8:noTabs=false:
|
||||
#
|
|
@ -1,70 +0,0 @@
|
|||
# Makefile.am
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
include $(top_srcdir)/Makefile.am.inc
|
||||
include ../Makefile.am.inc
|
||||
|
||||
plugin_LTLIBRARIES = tpg.la
|
||||
|
||||
tpg_la_SOURCES = \
|
||||
moduleinfo.h \
|
||||
http-parser.c \
|
||||
http-parser.h \
|
||||
packet-http.c
|
||||
|
||||
tpg_la_CPPFLAGS = $(AM_CPPFLAGS) $(PLUGIN_CPPFLAGS)
|
||||
|
||||
tpg_la_CFLAGS = $(AM_CFLAGS) $(PLUGIN_CFLAGS)
|
||||
|
||||
tpg_la_LDFLAGS = $(PLUGIN_LDFLAGS)
|
||||
|
||||
CLEANFILES = \
|
||||
tpg \
|
||||
*~
|
||||
|
||||
DISTCLEANFILES = \
|
||||
http-parser.c \
|
||||
http-parser.h
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
http-parser.c \
|
||||
http-parser.h \
|
||||
plugin.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
http.tpg \
|
||||
CMakeLists.txt
|
||||
|
||||
TPG = $(top_builddir)/tools/tpg
|
||||
|
||||
http-parser.h: http-parser.c
|
||||
|
||||
$(TPG)/TPG.pm: $(TPG)/TPG.yp
|
||||
cd $(TPG) && make
|
||||
|
||||
http-parser.c: http.tpg $(TPG)/tpg.pl $(TPG)/TPG.pm
|
||||
$(PERL) -I$(TPG) $(TPG)/tpg.pl http.tpg
|
||||
|
||||
checkapi:
|
||||
$(PERL) $(top_srcdir)/tools/checkAPIs.pl -g abort -g termoutput -build \
|
||||
-sourcedir=$(srcdir) \
|
||||
$(DISSECTOR_SRC) $(DISSECTOR_INCLUDES)
|
|
@ -1,194 +0,0 @@
|
|||
#
|
||||
# HTTP header TPG description
|
||||
#
|
||||
# (c) 2005 Luis E. Garcia Ontanon <luis@ontanon.org>
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2004 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
%header_head %{
|
||||
typedef struct _http_info_value_t
|
||||
{
|
||||
guint32 framenum;
|
||||
gchar *request_method;
|
||||
guint response_code;
|
||||
gchar *http_host;
|
||||
gchar *request_uri;
|
||||
guint content_length;
|
||||
gchar* media;
|
||||
gboolean is_response;
|
||||
gchar* transfer_encoding;
|
||||
} http_info_value_t;
|
||||
%}
|
||||
|
||||
%parser_name http .
|
||||
%export req_resp header crlf sp.
|
||||
|
||||
%tt_type %{ http_info_value_t %}
|
||||
|
||||
%rule crlf = "\r\n" .
|
||||
|
||||
%rule sp = [ ]+ .
|
||||
|
||||
%choice versions = "1.0" | "1.1". <version>
|
||||
|
||||
%field version hyttp.version "HTTP Version" FT_STRING .
|
||||
|
||||
%sequence http_version = "HTTP/" & versions .
|
||||
|
||||
%field response hyttp.response "Response" FT_STRING .
|
||||
%field response_code hyttp.response.code "Response Code" FT_UINT32 BASE_DEC %{ http_response_codes %} .
|
||||
|
||||
%sequence %tree response = http_version & [0-9]+<response_code:RESPONSE> & ... ( crlf ) . <response:%plain_text> %{
|
||||
TT_DATA->is_response = TRUE;
|
||||
TT_DATA->response_code = TPG_UINT(RESPONSE);
|
||||
%}
|
||||
|
||||
|
||||
%field request hyttp.request "Request" FT_STRING .
|
||||
%field method hyttp.request.method "Request Method" FT_STRING .
|
||||
%field uri hyttp.request.uri "Request URI" FT_STRING .
|
||||
%sequence %tree request = [A-Z]+<method:METHOD> & [^ ]+<uri:URI> & http_version & crlf . <request:%plain_text> %{
|
||||
TT_DATA->is_response = FALSE;
|
||||
TT_DATA->request_method = TPG_STRING(METHOD);
|
||||
TT_DATA->request_uri = TPG_STRING(URI);
|
||||
%}
|
||||
|
||||
%choice req_resp = request | response.
|
||||
|
||||
%field media hyttp.content_type.media "Content-Type Media" FT_STRING .
|
||||
|
||||
%sequence media = [a-zA-Z0-9-]+ & "/" & [a-zA-Z0-9-]+ . <media:MEDIA> %{
|
||||
TT_DATA->media = TPG_STRING(MEDIA);
|
||||
%}
|
||||
|
||||
|
||||
%sequence quoted_string = ["] & [^"]* & ["] .
|
||||
|
||||
%choice value = [a-zA-Z0-9-]+ | quoted_string.
|
||||
|
||||
%field charset hyttp.content_type.charset "Content-Type Charset" FT_STRING .
|
||||
|
||||
%sequence parameter = [a-zA-Z0-9-]+ & [=] & value.
|
||||
%sequence charset_parameter = 'charset' & '=' & [a-z0-9-]+<charset> .
|
||||
|
||||
%choice content_type_param = charset_parameter | parameter .
|
||||
|
||||
%sequence content_type_params = [;] & content_type_param .
|
||||
|
||||
%sequence content_type_value = media & content_type_params* .
|
||||
|
||||
%sequence content_type_hdr = 'Content-type:' & content_type_value & crlf .
|
||||
|
||||
%field content_length hyttp.headers.content_length "Content-Length" FT_UINT32 BASE_DEC .
|
||||
%sequence content_length = 'Content-length:' & [0-9]+<content_length:LENGTH> & crlf. %{
|
||||
TT_DATA->content_length = TPG_UINT(LENGTH);
|
||||
%}
|
||||
|
||||
%field transfer_encoding hyttp.transfer_encoding "Transfer-Encoding" FT_STRING .
|
||||
%sequence transfer_encoding = 'Transfer-encoding:' & ...<transfer_encoding:ENCODING> ( crlf %leave ) & crlf. %{
|
||||
TT_DATA->transfer_encoding = TPG_STRING(ENCODING);
|
||||
%}
|
||||
|
||||
%field authorization hyttp.authorization "Authorization" FT_STRING .
|
||||
%sequence authorization = 'Authorization:' & ...<authorization> ( crlf %leave ) & crlf.
|
||||
|
||||
%field proxy_authorization hyttp.proxy_authorization "Proxy-Authorization" FT_STRING .
|
||||
%sequence proxy_author = 'Proxy-authorization:' & ...<proxy_authorization> ( crlf %leave ) & crlf.
|
||||
|
||||
%field proxy_authen hyttp.proxy_authenti "Proxy-Authenticate" FT_STRING .
|
||||
%sequence proxy_authen = 'Proxy-authenticate:' & ...<proxy_authen> ( crlf %leave ) & crlf.
|
||||
|
||||
%field www_auth hyttp.www_authenticate "WWW-Authenticate" FT_STRING .
|
||||
%sequence www_auth = 'WWW-authenticate:' & ...<www_auth> ( crlf %leave ) & crlf.
|
||||
|
||||
%field content_encoding hyttp.content_encoding "Content-Encoding" FT_STRING .
|
||||
%sequence content_encoding = 'Content-Encoding:' & ...<content_encoding> ( crlf %leave ) & crlf.
|
||||
|
||||
%field user_agent hyttp.content_encoding "User-Agent" FT_STRING .
|
||||
%sequence user_agent = 'User-Agent:' & ...<user_agent> ( crlf %leave ) & crlf.
|
||||
|
||||
%field host hyttp.host "Host" FT_STRING .
|
||||
%sequence host = 'Host:' & ...<host:HOST> ( crlf %leave ) & crlf. %{
|
||||
TT_DATA->http_host = TPG_STRING(HOST);
|
||||
%}
|
||||
|
||||
%field accept hyttp.accept "Accept" FT_STRING .
|
||||
%sequence accept = 'Accept:' & ...<accept> ( crlf %leave ) & crlf.
|
||||
|
||||
%field accept_language hyttp.accept_language "Accept-Language" FT_STRING .
|
||||
%sequence accept_language = 'Accept-language:' & ...<accept_language> ( crlf %leave ) & crlf.
|
||||
|
||||
%field accept_encoding hyttp.accept_encoding "Accept-Language" FT_STRING .
|
||||
%sequence accept_encoding = 'Accept-encoding:' & ...<accept_encoding> ( crlf %leave ) & crlf.
|
||||
|
||||
%field accept_ranges hyttp.accept_encoding "Accept-Ranges" FT_STRING .
|
||||
%sequence accept_ranges = 'Accept-Ranges:' & ...<accept_ranges> ( crlf %leave ) & crlf.
|
||||
|
||||
%field keep_alive hyttp.keep_alive "Keep-Alive" FT_UINT32 BASE_DEC .
|
||||
%sequence keep_alive = 'Keep-Alive:' & ...<keep_alive> ( crlf %leave ) & crlf.
|
||||
|
||||
%field connection hyttp.connection "Connection" FT_STRING .
|
||||
%sequence connection = 'Connection:' & ...<connection> ( crlf %leave ) & crlf.
|
||||
|
||||
%field referer hyttp.referer "Referer" FT_STRING .
|
||||
%sequence referer = 'Referer:' & ...<referer> ( crlf %leave ) & crlf.
|
||||
|
||||
%field cookie hyttp.cookie "Cookie" FT_STRING .
|
||||
%sequence cookie = 'Cookie:' & ...<cookie> ( crlf %leave ) & crlf.
|
||||
|
||||
%field etag hyttp.etag "Etag" FT_STRING .
|
||||
%sequence etag = 'Etag:' & ["] & [^"]+<etag> & ["] & crlf .
|
||||
|
||||
%field last_modified hyttp.last_modified "Last-Modified" FT_STRING .
|
||||
%sequence last_modified = 'Last-Modified:' & ...<last_modified> ( crlf %leave ) & crlf.
|
||||
|
||||
%field server hyttp.server "Server" FT_STRING .
|
||||
%sequence server = 'Server:' & ...<server> ( crlf %leave ) & crlf.
|
||||
|
||||
%sequence other_header = [A-Z] & [a-zA-Z-]+ & ":" & ... ( crlf %leave ) & crlf.
|
||||
|
||||
%field header hyttp.headers.line "HTTP Header Line" FT_BOOLEAN .
|
||||
%choice %tree header =
|
||||
content_type_hdr
|
||||
| transfer_encoding
|
||||
| content_length
|
||||
| authorization
|
||||
| proxy_author
|
||||
| proxy_authen
|
||||
| www_auth
|
||||
| content_encoding
|
||||
| user_agent
|
||||
| host
|
||||
| accept
|
||||
| accept_language
|
||||
| accept_encoding
|
||||
| accept_ranges
|
||||
| keep_alive
|
||||
| connection
|
||||
| referer
|
||||
| cookie
|
||||
| etag
|
||||
| last_modified
|
||||
| server
|
||||
| other_header . <header:%plain_text>
|
||||
|
||||
|
||||
%tail %{
|
||||
/* tail */
|
||||
%}
|
|
@ -1,154 +0,0 @@
|
|||
/* packet-http.c
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <epan/wmem/wmem.h>
|
||||
|
||||
#include "http-parser.h"
|
||||
#include <gmodule.h>
|
||||
|
||||
static const value_string http_response_codes[] = {
|
||||
{ 200, "OK" },
|
||||
{ 302, "Later" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static gint ett_http = -1;
|
||||
static int proto_http = -1;
|
||||
|
||||
static int hf_http_is_response = -1;
|
||||
static int hf_http_request_method = -1;
|
||||
static int hf_http_response_code = -1;
|
||||
static int hf_http_transfer_encoding = -1;
|
||||
static int hf_http_content_length = -1;
|
||||
static int hf_http_media = -1;
|
||||
static int hf_http_host = -1;
|
||||
static int hf_http_request_uri = -1;
|
||||
|
||||
static dissector_handle_t http_handle;
|
||||
|
||||
static int dissect_http(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, void* data _U_) {
|
||||
http_info_value_t* msgdata = wmem_alloc0(wmem_packet_scope(), sizeof(http_info_value_t));
|
||||
tvbparse_elem_t* reqresp;
|
||||
tpg_parser_data_t* tpg;
|
||||
proto_item* pi = proto_tree_add_item(tree,proto_http,tvb,0,-1,ENC_NA);
|
||||
proto_tree* pt = proto_item_add_subtree(pi,ett_http);
|
||||
|
||||
tpg = tpg_start(pt,tvb,0,-1,http_tpg_data.wanted_http_sp, msgdata);
|
||||
|
||||
if (( reqresp = TPG_GET(tpg,http_tpg_data.wanted_http_req_resp) )) {
|
||||
tvbparse_elem_t* hdr;
|
||||
|
||||
while(( hdr = TPG_GET(tpg,http_tpg_data.wanted_http_header) ))
|
||||
;
|
||||
|
||||
if ( TPG_GET(tpg,http_tpg_data.wanted_http_crlf) ) {
|
||||
pi = proto_tree_add_boolean(pt,hf_http_is_response,tvb,0,0,msgdata->is_response);
|
||||
pt = proto_item_add_subtree(pi,ett_http);
|
||||
|
||||
|
||||
if (msgdata->is_response) {
|
||||
proto_tree_add_uint(pt,hf_http_response_code,tvb,0,0,msgdata->response_code);
|
||||
proto_tree_add_uint(pt,hf_http_content_length,tvb,0,0,msgdata->content_length);
|
||||
if (msgdata->transfer_encoding) proto_tree_add_string(pt,hf_http_transfer_encoding,tvb,0,0,msgdata->transfer_encoding);
|
||||
if (msgdata->media) proto_tree_add_string(pt,hf_http_media,tvb,0,0,msgdata->media);
|
||||
} else {
|
||||
if (msgdata->request_method) proto_tree_add_string(pt,hf_http_request_method,tvb,0,0,msgdata->request_method);
|
||||
if (msgdata->http_host) proto_tree_add_string(pt,hf_http_host,tvb,0,0,msgdata->http_host);
|
||||
if (msgdata->request_uri) proto_tree_add_string(pt,hf_http_request_uri,tvb,0,0,msgdata->request_uri);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* header fragment */
|
||||
}
|
||||
} else {
|
||||
/* no header */
|
||||
}
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
static void proto_register_http(void) {
|
||||
static hf_register_info hf[] = {
|
||||
HF_HTTP_PARSER,
|
||||
{ &hf_http_is_response, { "=Is Response", "hyttp.info.is_response", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_request_method, { "=Method", "hyttp.info.method", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_response_code, { "=Response Code", "hyttp.info.response.code", FT_UINT32, BASE_DEC, VALS( http_response_codes ), 0x0, "", HFILL }},
|
||||
{ &hf_http_transfer_encoding, { "=Transfer-Encoding", "hyttp.info.transfer_encoding", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_content_length, { "=Content-Length", "hyttp.info.content_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_request_uri, { "=Request URI", "hyttp.info.uri", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_media, { "=Media", "hyttp.info.media", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
|
||||
{ &hf_http_host, { "=Host", "hyttp.info.host", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
|
||||
};
|
||||
|
||||
gint *ett[] = {
|
||||
ETT_HTTP_PARSER,
|
||||
&ett_http
|
||||
};
|
||||
|
||||
tpg_http_init();
|
||||
|
||||
proto_http = proto_register_protocol("HyTTP", "HyTTP", "hyttp");
|
||||
proto_register_field_array(proto_http, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
}
|
||||
|
||||
|
||||
static void proto_reg_handoff_http(void) {
|
||||
http_handle = create_dissector_handle(dissect_http, proto_http);
|
||||
|
||||
dissector_add_uint_with_preference("tcp.port", 80, http_handle);
|
||||
|
||||
}
|
||||
|
||||
#ifndef ENABLE_STATIC
|
||||
|
||||
WS_DLL_PUBLIC_DEF const gchar version[] = "0.0.0";
|
||||
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_register(void)
|
||||
{
|
||||
/* register the new protocol, protocol fields, and subtrees */
|
||||
if (proto_http == -1) { /* execute protocol initialization only once */
|
||||
proto_register_http();
|
||||
}
|
||||
}
|
||||
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_reg_handoff(void){
|
||||
proto_reg_handoff_http();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -89,7 +89,6 @@ EXTRA_DIST = \
|
|||
test-common.sh \
|
||||
test-captures.sh \
|
||||
textify.ps1 \
|
||||
tpg \
|
||||
usb-ptp-extract-models.pl \
|
||||
usb-ptp-extract-models.txt \
|
||||
valgrind-wireshark.sh \
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
# Makefile.am
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2001 Gerald Combs
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
# We produce an archive library. In the future, when libwireshark is a
|
||||
# shared library, this will be linked into libwireshark. While libwireshark
|
||||
# is an archive library, any executable linking against libwireshark will
|
||||
# also need to link against libftypes.
|
||||
|
||||
CLEANFILES = \
|
||||
*~
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
tpg.output \
|
||||
TPG.pm
|
||||
|
||||
EXTRA_DIST = \
|
||||
tpg.yp \
|
||||
V2P.pl \
|
||||
TPG.pm \
|
||||
tpg.pl \
|
||||
README
|
||||
|
||||
TPG.pm: tpg.yp
|
||||
yapp -v -m TPG tpg.yp
|
||||
|
||||
tpg.pl: TPG.pm
|
||||
|
||||
all: tpg.pl
|
104
tools/tpg/V2P.pm
104
tools/tpg/V2P.pm
|
@ -1,104 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# a function that prints a complex variable such that the output is a
|
||||
# valid perl representation of that variable (does not handle blessed objects)
|
||||
#
|
||||
# (c) 2002, Luis E. Garcia Ontanon <luis@ontanon.org>
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2004 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
package V2P;
|
||||
use strict;
|
||||
|
||||
|
||||
my $_v2p_columns = 120;
|
||||
|
||||
sub var2perl { # converts a complex variable reference into perl code
|
||||
__v2p(0,@_);
|
||||
}
|
||||
|
||||
sub __v2p {
|
||||
my $d = shift ;
|
||||
my $i = '';
|
||||
my $buf = '';
|
||||
|
||||
if ( $d gt 0) {
|
||||
$i .= " " for (0..$d);
|
||||
}
|
||||
|
||||
if (scalar @_ <= 1) {
|
||||
my $what = ref $_[0];
|
||||
#~ print "! $_[0] '$what'\n";
|
||||
|
||||
if ( $what ) {
|
||||
if ($what eq 'ARRAY') {
|
||||
$buf .= "[\n";
|
||||
$buf .= "$i " . __v2p($d+1,$_) . ",\n" for (@{$_[0]});
|
||||
$buf =~ s/,\n$//msi;
|
||||
$buf .= "\n$i]\n";
|
||||
}
|
||||
elsif ($what eq 'HASH') {
|
||||
$buf .= "{\n";
|
||||
$buf .= "$i " . __v2p($d+1,$_) . " =>" . __v2p($d+1,${$_[0]}{$_}) . ",\n" for (keys %{$_[0]});
|
||||
$buf =~ s/,\n$//msi;
|
||||
$buf .= "\n$i}\n";
|
||||
}
|
||||
elsif ($what eq 'SCALAR') {
|
||||
$buf .= "\\" . __v2p($d+1,$_[0]);
|
||||
}
|
||||
elsif ($what eq 'REF') {
|
||||
$buf .= "\\" . __v2p($d+1,\$_);
|
||||
}
|
||||
elsif ($what eq 'GLOB') {
|
||||
$buf .= "*" . __v2p($d+1,\$_);
|
||||
}
|
||||
elsif ($what eq 'LVALUE') {
|
||||
$buf .= 'lvalue';
|
||||
}
|
||||
elsif ($what eq 'CODE') {
|
||||
$buf .= 'sub { "sorry I cannot do perl code"; }';
|
||||
}
|
||||
else {
|
||||
$buf .= "what's '$what'?";
|
||||
}
|
||||
} else {
|
||||
return "undef" unless defined $_[0];
|
||||
return "''" if $_[0] eq '';
|
||||
return "'$_[0]'" unless $_[0]=~ /^[0-9]+[\.][0-9]*?$/
|
||||
or $_[0]=~ /^[0-9]+$/
|
||||
or $_[0]=~ /^[0-9]*[\.][0-9]+?$/;
|
||||
return $_[0];
|
||||
}
|
||||
} else {
|
||||
$buf = $i . "( ";
|
||||
$buf .= "$i , " . __v2p($d+1,$_) for (@_);
|
||||
$buf .= " )\n";
|
||||
$buf =~ s/^\( , /\( /;
|
||||
}
|
||||
|
||||
$buf =~ s/\n,/,/msg;
|
||||
if (length $buf < $_v2p_columns) {
|
||||
$buf =~ s/\n//msg;
|
||||
$buf =~ s/$i//msg;
|
||||
$buf = $i . $buf;
|
||||
}
|
||||
return $buf;
|
||||
}
|
||||
|
||||
1;
|
594
tools/tpg/tpg.pl
594
tools/tpg/tpg.pl
|
@ -1,594 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# TPG TVB Parser Generator
|
||||
#
|
||||
# Given a bnf like grammar generate a parser for text based tvbs
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2004 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
use TPG;
|
||||
use V2P;
|
||||
use strict;
|
||||
|
||||
my $DEBUG = 0;
|
||||
|
||||
my $b = '';
|
||||
|
||||
while(<>) {
|
||||
$b .= $_;
|
||||
}
|
||||
|
||||
my @T = @{tokenizer()};
|
||||
my $linenum = 1;
|
||||
my %CODE = ();
|
||||
my $codenum = 0;
|
||||
|
||||
|
||||
$b =~ s/\%\{(.*?)\%\}/add_code($1)/egms;
|
||||
|
||||
$b =~ s/#.*?\n/\n/gms;
|
||||
|
||||
my $parser = new TPG();
|
||||
my $last_token = '';
|
||||
|
||||
$parser->YYData->{DATA}=\$linenum;
|
||||
|
||||
my $parser_info = $parser->YYParse(yylex => \&next_token, yyerror => \&error_sub);#,yydebug => 0x1f);
|
||||
|
||||
die "failed parsing" unless defined $parser_info;
|
||||
|
||||
if ($DEBUG > 3) {
|
||||
warn "\n=========================== parser_info ===========================\n";
|
||||
warn V2P::var2perl( $parser_info );
|
||||
warn "\n=========================== ======== ===========================\n" ;
|
||||
}
|
||||
|
||||
my $proto_name = ${$parser_info}{proto_name};
|
||||
my $upper_name = $proto_name;
|
||||
$upper_name =~ tr/a-z/A-Z/;
|
||||
my $global_struct = "$proto_name\_tpg_data";
|
||||
|
||||
warn "parser_data_type: ${$parser_info}{pdata}\n" if $DEBUG;
|
||||
|
||||
my %exports = %{${$parser_info}{export}};
|
||||
|
||||
my $field_num = 0;
|
||||
|
||||
my $tt_type = ${$parser_info}{pdata};
|
||||
|
||||
$tt_type =~ s/\n#line.*?\n//ms;
|
||||
$tt_type =~ s@\n/\*eocode\*/\n@@ms;
|
||||
|
||||
my $init_function_hfs = "\n/* initialize hfids */\n";
|
||||
my $init_function_etts = "\n/* initialize etts */\n";
|
||||
my $init_function_wanted_decl = "\n/* declare private wanted elements */\n";
|
||||
my $init_function_wanted = "\n/* initialize wanted elements */\n";
|
||||
my $callback_definitions = "\n/* callback definitions */\n";
|
||||
my $datastruct_ett = "\n/* etts */\n";
|
||||
my $datastruct_hf = "\n/* hfis */\n";
|
||||
my $datastruct_wanted = "\n/* wanted elems */\n";
|
||||
|
||||
my $hfarr = "/* field array */\n#define HF_$upper_name\_PARSER \\\n";
|
||||
my $ett_arr = "#define ETT_$upper_name\_PARSER \\\n";
|
||||
|
||||
for my $fieldname (keys %{${$parser_info}{fields}}) {
|
||||
my $f = ${${$parser_info}{fields}}{$fieldname};
|
||||
|
||||
my $vs = defined ${$f}{vs} ? 'VALS(' . ${$f}{vs}. ')' : "NULL" ;
|
||||
|
||||
${$f}{vname} = "$global_struct.hf_${$f}{name}" unless defined ${$f}{vname};
|
||||
${$f}{base} = 'BASE_NONE' unless defined ${$f}{base};
|
||||
${$f}{desc} = '""' unless defined ${$f}{desc};
|
||||
$datastruct_hf .= "\tint hf_${$f}{name};\n";
|
||||
$init_function_hfs .= "\t${$f}{vname} = -1;\n";
|
||||
$hfarr .= "{ &${$f}{vname}, { ${$f}{pname}, ${$f}{abbr}, ${$f}{type}, ${$f}{base}, $vs, 0x0, ${$f}{desc}, HFILL }},\\\n";
|
||||
|
||||
# warn "\nFIELD:$fieldname " . V2P::var2perl($f);
|
||||
|
||||
}
|
||||
|
||||
$hfarr =~ s/,\\\n$/\n/msi;
|
||||
|
||||
|
||||
for my $rulename ( keys %{${$parser_info}{rules}} ) {
|
||||
my $r = ${${$parser_info}{rules}}{$rulename};
|
||||
|
||||
# warn "\nRULE BEFORE:$rulename " . V2P::var2perl($r);
|
||||
|
||||
make_rule($r,0);
|
||||
|
||||
# warn "\nRULE AFTER:$rulename " . V2P::var2perl($r);
|
||||
|
||||
}
|
||||
|
||||
$ett_arr =~ s/,\\\n$//ms;
|
||||
|
||||
for my $rulename (sort keys %{${$parser_info}{rules}} ) {
|
||||
my $r = ${${$parser_info}{rules}}{$rulename};
|
||||
|
||||
|
||||
$callback_definitions .= "\n\n/* callback definitions for rule $rulename */\n";
|
||||
$callback_definitions .= ${$r}{before_cb_code} . "\n";
|
||||
$callback_definitions .= ${$r}{after_cb_def} . "\n";
|
||||
$init_function_wanted .= ${$r}{definition_code} . "\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
my $h_file = <<"__H_HEAD";
|
||||
/*
|
||||
$proto_name-parser.h
|
||||
automagically generated by $0 from $ARGV
|
||||
DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
#ifndef _H_$upper_name\_PARSER
|
||||
#define _H_$upper_name\_PARSER
|
||||
#include <epan/tpg.h>
|
||||
|
||||
|
||||
/* begin %header_head */
|
||||
${$parser_info}{header_head}
|
||||
/* end %header_head */
|
||||
|
||||
extern void tpg_${proto_name}_init(void);
|
||||
|
||||
struct _${proto_name}_tpg_data_t {
|
||||
$datastruct_ett
|
||||
$datastruct_hf
|
||||
$datastruct_wanted
|
||||
};
|
||||
|
||||
|
||||
extern struct _${global_struct}_t $global_struct;
|
||||
|
||||
$hfarr
|
||||
|
||||
|
||||
$ett_arr
|
||||
|
||||
|
||||
#endif
|
||||
__H_HEAD
|
||||
|
||||
|
||||
my $c_file = <<"__C_FILE";
|
||||
/*
|
||||
$proto_name-parser.c
|
||||
automagically generated by $0 from $ARGV
|
||||
DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "$proto_name-parser.h"
|
||||
|
||||
/* begin %head */
|
||||
${$parser_info}{head}
|
||||
/* end %head */
|
||||
|
||||
/* hfids container */
|
||||
|
||||
struct _${proto_name}_tpg_data_t $global_struct;
|
||||
|
||||
|
||||
$callback_definitions
|
||||
/* end callback definitions */
|
||||
|
||||
void tpg_$proto_name\_init(void) {
|
||||
$init_function_wanted_decl
|
||||
$init_function_hfs
|
||||
$init_function_etts
|
||||
$init_function_wanted
|
||||
}
|
||||
|
||||
/* begin %tail */
|
||||
${$parser_info}{tail}
|
||||
/* end %tail */
|
||||
|
||||
__C_FILE
|
||||
|
||||
my $c_buf = '';
|
||||
my $c_line = 3;
|
||||
while($c_file =~ s/^([^\n]*)\n//ms) {
|
||||
my $line = $1;
|
||||
|
||||
$c_line += 2 if $line =~ s@/\*eocode\*/@\n#line $c_line \"$proto_name-parser.c\"\n@;
|
||||
$c_buf .= $line . "\n";
|
||||
$c_line++;
|
||||
}
|
||||
|
||||
my $h_buf = '';
|
||||
my $h_line = 3;
|
||||
while($h_file =~ s/^([^\n]*)\n//ms) {
|
||||
my $line = $1;
|
||||
|
||||
$h_line += 2 if $line =~ s@/\*eocode\*/@\n#line $h_line \"$proto_name-parser.h\"\n@;
|
||||
$h_buf .= $line . "\n";
|
||||
$h_line++;
|
||||
}
|
||||
|
||||
|
||||
open C, "> $proto_name-parser.c";
|
||||
open H, "> $proto_name-parser.h";
|
||||
print C $c_buf;
|
||||
print H $h_buf;
|
||||
close C;
|
||||
close H;
|
||||
|
||||
exit;
|
||||
|
||||
sub make_rule {
|
||||
my $r = shift;
|
||||
my $dd = shift;
|
||||
|
||||
my $rule_id = "0";
|
||||
my $code = \${$r}{definition_code};
|
||||
my $indent;
|
||||
|
||||
|
||||
|
||||
for (0..$dd) {
|
||||
$indent .= "\t";
|
||||
}
|
||||
|
||||
my $indent_more = $indent . "\t";
|
||||
|
||||
my $min;
|
||||
my $max;
|
||||
|
||||
if (exists ${$r}{min}) {
|
||||
$min = ${$r}{min};
|
||||
} else {
|
||||
$min = ${$r}{min} = 1;
|
||||
}
|
||||
|
||||
if (exists ${$r}{max}) {
|
||||
$max = ${$r}{max};
|
||||
} else {
|
||||
$max = ${$r}{max} = 1;
|
||||
}
|
||||
|
||||
if ($dd == 0) {
|
||||
my %VARS = ();
|
||||
|
||||
if ( exists $exports{${$r}{name}}) {
|
||||
${$code} = "\t$global_struct.";
|
||||
$datastruct_wanted .= "\ttvbparse_wanted_t* wanted_$proto_name\_${$r}{name};\n"
|
||||
} else {
|
||||
${$code} = "\t";
|
||||
$init_function_wanted_decl .= "\tstatic tvbparse_wanted_t* wanted_$proto_name\_${$r}{name};\n"
|
||||
}
|
||||
|
||||
${$code} .= "wanted_$proto_name\_${$r}{name} = ";
|
||||
|
||||
$VARS{"TT_DATA"} = "TPG_DATA(tpg,$tt_type)" if defined $tt_type;
|
||||
|
||||
make_vars(\%VARS,$r,"elem");
|
||||
|
||||
# warn "VARS::${$r}{name} " . V2P::var2perl(\%VARS);
|
||||
|
||||
|
||||
my $tree_code_head = "";
|
||||
my $tree_code_body = "";
|
||||
my $tree_code_after = "";
|
||||
|
||||
make_tree_code($r,\$tree_code_head,\$tree_code_body,\$tree_code_after,"elem");
|
||||
|
||||
if (length $tree_code_body ) {
|
||||
my $cb_name = ${$r}{before_cb_name} = "${$r}{name}\_before_cb";
|
||||
${$r}{before_cb_code} = "static void $cb_name(void* tpg _U_, const void* wd _U_, struct _tvbparse_elem_t* elem _U_) {\n\tproto_item* pi;\n$tree_code_head\n$tree_code_body\n}";
|
||||
${$r}{code} .= $tree_code_after;
|
||||
}
|
||||
|
||||
my $tree_code = \${$r}{tree_code};
|
||||
|
||||
|
||||
if (${$r}{code}) {
|
||||
my $after = ${$r}{code};
|
||||
|
||||
${$r}{after_cb_name} = "${$r}{name}_after\_cb";
|
||||
|
||||
${$r}{after_cb_def} = "static void ${$r}{after_cb_name}(void* tpg _U_, const void* wd _U_, struct _tvbparse_elem_t* elem _U_) {\n";
|
||||
|
||||
for (keys %VARS) {
|
||||
$after =~ s/($_)([A-Z]?)/$VARS{$1}$2/msg;
|
||||
}
|
||||
|
||||
${$r}{after_cb_def} .= $after . "\n}\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
my $after_fn = ${$r}{after_cb_name} ? ${$r}{after_cb_name} : "NULL";
|
||||
my $before_fn = ${$r}{before_cb_name} ? ${$r}{before_cb_name} : "NULL";
|
||||
|
||||
my $wd_data = "NULL";
|
||||
|
||||
if (exists ${$r}{field}) {
|
||||
my $field = ${${$parser_info}{fields}}{${$r}{field}};
|
||||
die "field ${$r}{field} does not exists\n" . V2P::var2perl(${$parser_info}{fields}) unless defined $field;
|
||||
|
||||
my $ett = exists ${$r}{ett} ? ${$r}{ett} : "NULL";
|
||||
|
||||
my $wd_data = 'tpg_wd(${$field}{vname},$ett,NULL)';
|
||||
|
||||
}
|
||||
|
||||
my $control = ${$r}{control};
|
||||
|
||||
if (${$r}{type} eq 'chars' || ${$r}{type} eq 'not_chars') {
|
||||
if (! ($min == 1 && $max == 1) ) {
|
||||
${$code} .= $indent . "tvbparse_${$r}{type}($rule_id,$min,$max,$control,$wd_data,$before_fn,$after_fn)"
|
||||
} else {
|
||||
my $rn = ${$r}{type};
|
||||
$rn =~ s/.$//;
|
||||
${$code} .= $indent . "tvbparse_$rn($rule_id,$control,$wd_data,$before_fn,$after_fn)"
|
||||
}
|
||||
} else {
|
||||
if (! ($min == 1 && $max == 1)) {
|
||||
${$code} .= $indent . "tvbparse_some(0,$min,$max,NULL,NULL,NULL,\n";
|
||||
}
|
||||
|
||||
if (${$r}{type} eq 'string') {
|
||||
|
||||
${$code} .= $indent . "tvbparse_string($rule_id,$control,$wd_data,$before_fn,$after_fn)";
|
||||
|
||||
} elsif (${$r}{type} eq 'caseless') {
|
||||
|
||||
${$code} .= $indent . "tvbparse_casestring($rule_id,$control,$wd_data,$before_fn,$after_fn)";
|
||||
|
||||
} elsif (${$r}{type} eq 'named') {
|
||||
if(exists $exports{$control}) {
|
||||
${$code} .= $indent . "tvbparse_handle(&$global_struct.wanted_$proto_name\_$control)";
|
||||
} else {
|
||||
${$code} .= $indent . "tvbparse_handle(&wanted_$proto_name\_$control)";
|
||||
}
|
||||
} elsif (${$r}{type} eq 'seq') {
|
||||
|
||||
${$code} .= $indent . "tvbparse_set_seq($rule_id,$wd_data,$before_fn,$after_fn,\n";
|
||||
|
||||
for ( @{${$r}{subrules}}) {
|
||||
$dd++;
|
||||
${$code} .= $indent_more . make_rule($_,$dd) . ",\n";
|
||||
$dd--;
|
||||
}
|
||||
|
||||
${$code} .= $indent . " NULL)"
|
||||
|
||||
} elsif (${$r}{type} eq 'choice') {
|
||||
|
||||
${$code} .= $indent . "tvbparse_set_oneof($rule_id,$wd_data,$before_fn,$after_fn,\n";
|
||||
|
||||
for (@{${$r}{subrules}}) {
|
||||
$dd++;
|
||||
${$code} .= $indent_more . make_rule($_,$dd) . ",\n";
|
||||
$dd--;
|
||||
}
|
||||
|
||||
${$code} .= $indent . " NULL)"
|
||||
|
||||
} elsif (${$r}{type} eq 'until') {
|
||||
|
||||
${$r}{inc_mode} = 'TP_UNTIL_SPEND' unless defined ${$r}{inc_mode};
|
||||
|
||||
${$code} .= $indent ."tvbparse_until(0,$wd_data,$before_fn,$after_fn,\n";
|
||||
$dd++;
|
||||
${$code} .= $indent_more . make_rule(${$r}{subrule},$dd) . ", ${$r}{inc_mode})";
|
||||
$dd--;
|
||||
}
|
||||
|
||||
if (! ($min == 1 && $max == 1) ) {
|
||||
${$code} .= ")";
|
||||
}
|
||||
}
|
||||
|
||||
if ($dd == 0) {
|
||||
${$code} .= ";\n";
|
||||
# warn "RULE::${$r}{name} " . V2P::var2perl($r);
|
||||
}
|
||||
|
||||
${$code};
|
||||
}
|
||||
|
||||
|
||||
sub make_vars {
|
||||
my $v = shift;
|
||||
my $r = shift;
|
||||
my $base = shift;
|
||||
|
||||
if (exists ${$r}{var}) {
|
||||
${$v}{${$r}{var}} = $base;
|
||||
}
|
||||
|
||||
if (! ( ${$r}{type} =~ /chars$/ ) && ! (${$r}{min} == 1 && ${$r}{max} == 1) ) {
|
||||
$base .= "->sub";
|
||||
}
|
||||
|
||||
if (exists ${$r}{subrule} ) {
|
||||
make_vars($v,${$r}{subrule},"$base->sub");
|
||||
}
|
||||
|
||||
|
||||
if (exists ${$r}{subrules} ) {
|
||||
my $sub_base = "$base->sub";
|
||||
for my $rule (@{${$r}{subrules}}) {
|
||||
make_vars($v,$rule,$sub_base);
|
||||
$sub_base .= "->next";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub make_tree_code {
|
||||
my $r = shift;
|
||||
my $head = shift;
|
||||
my $body = shift;
|
||||
my $after = shift;
|
||||
my $elem = shift;
|
||||
|
||||
if (exists ${$r}{field}) {
|
||||
my $fieldname = ${$r}{field};
|
||||
my $f = ${${$parser_info}{fields}}{$fieldname};
|
||||
|
||||
my $root_var = '';
|
||||
|
||||
if (exists ${$r}{tree}) {
|
||||
$root_var = "root_$fieldname";
|
||||
${$head} .= "\tproto_item* $root_var;\n\n";
|
||||
${$body} .= "\t$root_var = ";
|
||||
$ett_arr .= "\t&$global_struct.ett_$fieldname,\\\n";
|
||||
$datastruct_ett .= "\tguint ett_$fieldname; \n";
|
||||
$init_function_etts .= "\t$global_struct.ett_$fieldname = -1;\n";
|
||||
${$r}{ett} = "$global_struct.ett_$fieldname";
|
||||
} else {
|
||||
${$body} .= "\t";
|
||||
}
|
||||
|
||||
|
||||
if (${$f}{type} eq 'FT_STRING') {
|
||||
${$body} .= "\tpi = TPG_ADD_STRING(tpg,${$f}{vname},$elem);\n";
|
||||
} elsif (${$f}{type} =~ /^FT_UINT/) {
|
||||
my $fieldvar = "tpg_uint_$fieldname";
|
||||
${$head} .= "\tguint $fieldvar = TPG_UINT($elem);\n";
|
||||
${$body} .= "\tpi = TPG_ADD_UINT(tpg,${$f}{vname},$elem,$fieldvar);\n";
|
||||
} elsif (${$f}{type} =~ /^FT_INT/) {
|
||||
my $fieldvar = "tpg_int_$fieldname";
|
||||
${$head} .= "\tgint $fieldvar = TPG_INT($elem);\n";
|
||||
${$body} .= "\tpi = TPG_ADD_INT(tpg,${$f}{vname},$elem,$fieldvar);\n";
|
||||
} elsif (${$f}{type} eq 'FT_IPV4') {
|
||||
my $fieldvar = "tpg_ipv4_$fieldname";
|
||||
${$head} .= "\tguint32 $fieldvar = TPG_IPV4($elem);\n";
|
||||
${$body} .= "\tpi = TPG_ADD_IPV4(tpg,${$f}{vname},$elem,$fieldvar);\n";
|
||||
} elsif (${$f}{type} eq 'FT_IPV6') {
|
||||
my $fieldvar = "tpg_ipv6_$fieldname";
|
||||
${$head} .= "\tguint8* $fieldvar = TPG_IPV6($elem);\n";
|
||||
${$body} .= "\tpi = TPG_ADD_IPV6(tpg,${$f}{vname},$elem,$fieldvar);\n";
|
||||
} else {
|
||||
${$body} .= "\tpi = TPG_ADD_TEXT(tpg,$elem);\n";
|
||||
}
|
||||
|
||||
if (exists ${$r}{plain_text}) {
|
||||
${$body} .= "\tTPG_SET_TEXT(pi,$elem);\n"
|
||||
}
|
||||
|
||||
if (exists ${$r}{tree}) {
|
||||
${$body} .= "\tTPG_PUSH(tpg,$root_var,${$r}{ett});\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! ( ${$r}{type} =~ /chars$/ ) && ! (${$r}{min} == 1 && ${$r}{max} == 1) ) {
|
||||
$elem .= "->sub";
|
||||
}
|
||||
|
||||
|
||||
if (exists ${$r}{subrule} ) {
|
||||
make_tree_code(${$r}{subrule},$head,$body,$after,"$elem->sub");
|
||||
}
|
||||
|
||||
if (exists ${$r}{subrules} ) {
|
||||
my $sub_base = "$elem->sub";
|
||||
for my $rule (@{${$r}{subrules}}) {
|
||||
make_tree_code($rule,$head,$body,$after,$sub_base);
|
||||
$sub_base .= "->next";
|
||||
}
|
||||
}
|
||||
|
||||
if (exists ${$r}{field}) {
|
||||
if (exists ${$r}{tree}) {
|
||||
${$after} .= "\n\t/* tree after code */\n\tTPG_POP(tpg);\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
sub tokenizer {
|
||||
[
|
||||
[ '(FT_(UINT(8|16|24|32)|STRING|INT(8|16|24|32)|IPV[46]|ETH|BOOLEAN|DOUBLE|FLOAT|(ABSOLUTE|RELATIVE)_TIME|BYTES))' , sub { [ 'FT', $_[0] ] } ],
|
||||
[ '(BASE_(NONE|DEC|HEX))', sub { [ 'BASE', $_[0] ] }],
|
||||
[ '([a-z]+\\.[a-z0-9_\\.]*[a-z])', sub { [ 'DOTEDNAME', $_[0] ] }],
|
||||
[ '([a-z][a-z0-9_]*)', sub { [ 'LOWERCASE', $_[0] ] }],
|
||||
[ '([A-Z][A-Z0-9_]*)', sub { [ 'UPPERCASE', $_[0] ] }],
|
||||
[ '([0-9]+|0x[0-9a-fA-F]+)', sub { [ 'NUMBER', $_[0] ] }],
|
||||
[ '(\%\%[0-9]+\%\%)', \&c_code ],
|
||||
[ "'((\\\\'|[^'])*)'", sub { [ 'SQUOTED', $_[0] ] }],
|
||||
[ '\[\^((\\\\\\]|[^\\]])*)\]', sub { [ 'NOTCHARS', $_[0] ] }],
|
||||
[ '\[((\\\\\\]|[^\\]])*)\]', sub { [ 'CHARS', $_[0] ] }],
|
||||
[ '"((\\\\"|[^"])*)"', sub { [ 'DQUOTED', $_[0] ] }],
|
||||
[ '(\%[a-z_]+|\%[A-Z][A-Z-]*|\&|\=|\.\.\.|\.|\:|\;|\(|\)|\{|\}|\+|\*|\?|\<|\>|\|)', sub { [ $_[0], $_[0] ] }],
|
||||
]
|
||||
}
|
||||
|
||||
sub next_token {
|
||||
|
||||
if ($b =~ s/^([\r\n\s]+)// ) {
|
||||
my $l = $1;
|
||||
while ( $l =~ s/\n//ms ) {
|
||||
$linenum++;
|
||||
}
|
||||
}
|
||||
|
||||
return (undef,'') unless length $b;
|
||||
|
||||
for (@T) {
|
||||
my ($re,$ac) = @{$_};
|
||||
|
||||
if( $b =~ s/^$re//ms) {
|
||||
$a = &{$ac}($1);
|
||||
$last_token = ${$a}[1];
|
||||
#warn "=($linenum)=> ${$a}[0] ${$a}[1]\n";
|
||||
return (${$a}[0],${$a}[1]);
|
||||
}
|
||||
}
|
||||
|
||||
die "unrecognized token at line $linenum after '$last_token'";
|
||||
}
|
||||
|
||||
sub error_sub {
|
||||
my @a = $_[0]->YYExpect;
|
||||
my $t = $_[0]->YYCurtok;
|
||||
|
||||
die "error at $linenum after '$last_token' expecting (@a)";
|
||||
}
|
||||
|
||||
|
||||
sub add_code {
|
||||
my $k = "%%$codenum%%";
|
||||
$CODE{$k} = $_[0];
|
||||
$codenum++;
|
||||
return $k;
|
||||
}
|
||||
|
||||
sub c_code {
|
||||
my $k = $_[0];
|
||||
my $t = $CODE{$k};
|
||||
my $start = $linenum;
|
||||
$linenum++ while ( $t =~ s/\n// );
|
||||
return [ 'CODE', "\n#line $start \"$ARGV\"\n$CODE{$k}\n/*eocode*/\n"];
|
||||
}
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
do {
|
||||
($type,$value) = @{next_token()};
|
||||
last if not defined $type;
|
||||
} while(1);
|
||||
|
319
tools/tpg/tpg.yp
319
tools/tpg/tpg.yp
|
@ -1,319 +0,0 @@
|
|||
%{
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# TPG TVB Parser Generator Grammar
|
||||
#
|
||||
# Given a bnf like grammar generate a parser for text based tvbs
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2004 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
use V2P;
|
||||
|
||||
my $parser_info;
|
||||
|
||||
sub hj {
|
||||
${$_[0]}{$_} = ${$_[1]}{$_} for (keys %{$_[1]});
|
||||
return $_[0];
|
||||
}
|
||||
|
||||
sub abort {
|
||||
my $line = ${$_[0]->YYData->{DATA}};
|
||||
|
||||
die "$_[1] at $line";
|
||||
}
|
||||
|
||||
sub from_to {
|
||||
my $f = unpack "C", shift;
|
||||
my $t = unpack "C", shift;
|
||||
my $b = '';
|
||||
for ($f..$t) {
|
||||
$b .= pack("C",$_);
|
||||
}
|
||||
$b;
|
||||
}
|
||||
|
||||
|
||||
sub to_hexesc {
|
||||
sprintf "\\x%.2x", unpack("C",$_[0]);
|
||||
}
|
||||
|
||||
sub chars_control {
|
||||
$_ = $_[0];
|
||||
s/([a-zA-Z0-9])-([a-zA-Z0-9])/from_to($1,$2)/ge;
|
||||
s/"/\\"/g;
|
||||
s/\\(.)/to_hexesc($1)/ge;
|
||||
"\"$_\"";
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
start: statements {$parser_info} ;
|
||||
|
||||
statements:
|
||||
#empty { $parser_info = {}; }
|
||||
| statements statement
|
||||
;
|
||||
|
||||
statement:
|
||||
rule_statement {
|
||||
my $rulename = ${$_[1]}{name};
|
||||
|
||||
abort($_[0],"%rule $rulename already defined") if exists ${${$parser_info}{rules}}{$rulename};
|
||||
|
||||
${${$parser_info}{rules}}{$rulename} = $_[1];
|
||||
}
|
||||
| parser_name_statement {
|
||||
abort($_[0],"%parser_name already defined") if exists ${$parser_info}{name};
|
||||
${$parser_info}{proto_name} = $_[1];
|
||||
}
|
||||
| proto_desc_statement {
|
||||
abort($_[0],"%proto_desc already defined") if exists ${$parser_info}{proto_desc};
|
||||
${$parser_info}{proto_desc} = $_[1];
|
||||
}
|
||||
| header_head_statement {
|
||||
${$parser_info}{header_head} .= $_[1];
|
||||
}
|
||||
| code_head_statement {
|
||||
${$parser_info}{head} .= $_[1];
|
||||
}
|
||||
| header_tail_statement {
|
||||
${$parser_info}{header_tail} .= $_[1];
|
||||
}
|
||||
| code_tail_statement {
|
||||
${$parser_info}{tail} .= $_[1];
|
||||
}
|
||||
| static_field_statement {
|
||||
abort($_[0],"%field '${$_[1]}{name}' already defined") if (exists ${${$parser_info}{fields}}{${$_[1]}{name}});
|
||||
${${$parser_info}{fields}}{${$_[1]}{name}} = $_[1];
|
||||
}
|
||||
| parser_data_statement {
|
||||
abort($_[0],"%tt_type already defined") if exists ${$parser_info}{pdata};
|
||||
${$parser_info}{pdata} = $_[1];
|
||||
}
|
||||
| export_statement {
|
||||
abort($_[0],"%export already defined") if exists ${$parser_info}{export};
|
||||
${$parser_info}{export} = $_[1];
|
||||
}
|
||||
| value_string_statement {
|
||||
my $name = ${$_[1]}{name};
|
||||
abort($_[0],"%value_string $name already defined") if exists ${${$parser_info}{vs}}{$name};
|
||||
${${$parser_info}{vs}}{$name} = $_[1];
|
||||
}
|
||||
| ignore_statement {
|
||||
${$parser_info}{ignore} = $_[1];
|
||||
}
|
||||
;
|
||||
|
||||
ignore_statement:
|
||||
'%ignore' LOWERCASE {$_[2]}
|
||||
;
|
||||
|
||||
rule_statement:
|
||||
'%sequence' tree LOWERCASE '=' sequence_rule '.' qualification code {
|
||||
my $r = hj($_[5],$_[7]);
|
||||
${$r}{name} = $_[3];
|
||||
${$r}{code} = $_[8] if defined $_[8];
|
||||
${$r}{tree} = 1 if defined $_[2];
|
||||
$r;
|
||||
}
|
||||
| '%choice' tree LOWERCASE '=' choice_rule '.' qualification code {
|
||||
my $r = hj($_[5],$_[7]);
|
||||
${$r}{name} = $_[3];
|
||||
${$r}{code} = $_[8] if defined $_[8];
|
||||
${$r}{tree} = 1 if defined $_[2];
|
||||
$r;
|
||||
}
|
||||
| '%rule' LOWERCASE '=' complete_rule '.' code {
|
||||
my $r = $_[4];
|
||||
${$r}{name} = $_[2];
|
||||
${$r}{code} = $_[6] if defined $_[6];
|
||||
$r;
|
||||
}
|
||||
;
|
||||
|
||||
code:
|
||||
#empty { undef }
|
||||
| CODE
|
||||
;
|
||||
|
||||
tree:
|
||||
#empty {undef}
|
||||
| '%tree'
|
||||
;
|
||||
|
||||
|
||||
complete_rule:
|
||||
base_rule cardinality qualification {hj($_[1],hj($_[2],$_[3]))}
|
||||
| named_rule cardinality { hj($_[1],$_[2]) }
|
||||
| until_rule
|
||||
;
|
||||
|
||||
named_rule: LOWERCASE {{control=>$_[1],type=>'named'}} ;
|
||||
|
||||
base_rule:
|
||||
| CHARS {{control=>chars_control($_[1]),type=>'chars'}}
|
||||
| NOTCHARS {{control=>chars_control($_[1]),type=>'not_chars'}}
|
||||
| DQUOTED {{control=>"\"$_[1]\"",type=>'string'}}
|
||||
| SQUOTED {{control=>"\"$_[1]\"",type=>'caseless'}}
|
||||
;
|
||||
|
||||
until_rule:
|
||||
'...' qualification '(' last_rule include_mode ')' { @{$_[2]}{'type','subrule','inc_mode'} = ('until',$_[4],$_[5]); $_[2] }
|
||||
;
|
||||
|
||||
last_rule: base_rule | named_rule;
|
||||
|
||||
include_mode:
|
||||
#empty { 'TP_UNTIL_SPEND' }
|
||||
| '%spend' { 'TP_UNTIL_SPEND' }
|
||||
| '%include' { 'TP_UNTIL_INCLUDE' }
|
||||
| '%leave' { 'TP_UNTIL_LEAVE' }
|
||||
;
|
||||
|
||||
choice_rule: choice {{subrules=>$_[1],type=>'choice'}} ;
|
||||
|
||||
choice:
|
||||
complete_rule '|' complete_rule { [$_[1],$_[3]] }
|
||||
| choice '|' complete_rule { push @{$_[1]}, $_[3]; $_[1] }
|
||||
;
|
||||
|
||||
sequence_rule: sequence { {subrules=>$_[1],type=>'seq'}} ;
|
||||
|
||||
sequence:
|
||||
complete_rule { [$_[1]] }
|
||||
| sequence '&' complete_rule { push @{$_[1]}, $_[3]; $_[1] }
|
||||
;
|
||||
|
||||
cardinality:
|
||||
#empty { my %c; @c{'min','max'} = (1,1); \%c }
|
||||
| '+' { my %c; @c{'min','max'} = (1,"0xffffffff"); \%c }
|
||||
| '?' { my %c; @c{'min','max'} = (0,1); \%c }
|
||||
| '*' { my %c; @c{'min','max'} = (0,"0xffffffff"); \%c }
|
||||
| '{' NUMBER ',' NUMBER '}' { my %c; @c{'min','max'} = ($_[2],$_[4]); \%c }
|
||||
| '{' NUMBER '}' { my %c; @c{'min','max'} = ($_[2],$_[2]); \%c }
|
||||
| '{' ',' NUMBER '}' { my %c; @c{'min','max'} = (0,$_[3]); \%c }
|
||||
| '{' NUMBER ',' '}' { my %c; @c{'min','max'} = ($_[2],"0xffffffff"); \%c }
|
||||
;
|
||||
|
||||
qualification:
|
||||
#empty {{}}
|
||||
| '<' qualifiers '>' {$_[2]}
|
||||
;
|
||||
|
||||
qualifiers:
|
||||
qualifier { my $p = {}; ${$p} { ${$_[1]}[0] } = ${$_[1]}[1]; $p }
|
||||
| qualifiers ':' qualifier { ${$_[1]} { ${$_[3]}[0] } = ${$_[3]}[1]; $_[1] }
|
||||
;
|
||||
|
||||
qualifier:
|
||||
| LOWERCASE { ['field',$_[1]] }
|
||||
| UPPERCASE { ['var',$_[1]] }
|
||||
| '%plain_text' { ['plain_text',1] }
|
||||
;
|
||||
|
||||
proto_desc_statement:
|
||||
'%proto_desc' quoted '.' { "\"$_[2]\"" }
|
||||
;
|
||||
|
||||
header_head_statement:
|
||||
'%header_head' CODE { $_[2] }
|
||||
;
|
||||
|
||||
header_tail_statement:
|
||||
'%header_tail' CODE { $_[2] }
|
||||
;
|
||||
|
||||
code_head_statement:
|
||||
'%head' CODE { $_[2] }
|
||||
;
|
||||
|
||||
code_tail_statement:
|
||||
'%tail' CODE { $_[2] }
|
||||
;
|
||||
|
||||
parser_name_statement:
|
||||
'%parser_name' LOWERCASE '.' {$_[2]}
|
||||
;
|
||||
|
||||
parser_data_statement:
|
||||
'%tt_type' CODE { $_[2] }
|
||||
;
|
||||
|
||||
export_statement:
|
||||
'%export' exports '.' { $_[2] }
|
||||
;
|
||||
|
||||
exports:
|
||||
exports LOWERCASE { ${$_[1]}{$_[2]} = 1; $_[1] }
|
||||
| LOWERCASE { my $e = {}; ${$e}{$_[1]} = 1; $e }
|
||||
;
|
||||
|
||||
value_string_statement:
|
||||
'%value_string' LOWERCASE value_string_items { my $v = {}; ${$v}{name} = $_[2]; ${$v}{items} = $_[3]; $v }
|
||||
;
|
||||
|
||||
value_string_items:
|
||||
value_string_items value_string_item { push @{$_[1]}, $_[2] }
|
||||
| value_string_item { [$_[1]]}
|
||||
;
|
||||
|
||||
value_string_item:
|
||||
NUMBER DQUOTED { [ $_[1], "\"$_[2]\"" ] }
|
||||
;
|
||||
|
||||
static_field_statement:
|
||||
'%field' LOWERCASE DOTEDNAME field_name field_type field_base field_value_string field_description '.' {
|
||||
my $field = {};
|
||||
@{$field}{'name','abbr','pname','type','base','vs','desc'} = ($_[2],"\"$_[3]\"",$_[4],$_[5],$_[6],$_[7],$_[8]);
|
||||
return $field;
|
||||
}
|
||||
;
|
||||
|
||||
field_name:
|
||||
#empty {undef}
|
||||
| DQUOTED { "\"$_[1]\""}
|
||||
;
|
||||
|
||||
field_type:
|
||||
#empty { 'FT_STRING' }
|
||||
| FT
|
||||
;
|
||||
|
||||
field_base:
|
||||
#empty { 'BASE_NONE' }
|
||||
| BASE
|
||||
;
|
||||
|
||||
field_value_string:
|
||||
#empty { 'NULL' }
|
||||
| CODE { $_[1] =~ s/#line.*?\n//ms; $_[1] =~ s/\n//msg; $_[1] =~ s@/\*eocode\*/@@; $_[1] }
|
||||
;
|
||||
|
||||
field_description:
|
||||
#empty {'""'}
|
||||
| SQUOTED { "\"$_[1]\""}
|
||||
;
|
||||
|
||||
quoted: DQUOTED | SQUOTED ;
|
||||
|
||||
%%
|
||||
|
||||
|
Loading…
Reference in New Issue