forked from osmocom/wireshark
tools: add automatic C skeleton dissector generator.
Generate a dissector based on doc/packet-PROTOABBREV.c. Change-Id: I9233c1212acb30f7166ba91e39d98bc3fb123731 Reviewed-on: https://code.wireshark.org/review/35062 Reviewed-by: Graham Bloice <graham.bloice@trihedral.com> Reviewed-by: Dario Lombardo <lomato@gmail.com>
This commit is contained in:
parent
9dbf684c71
commit
40d822ed61
|
@ -97,6 +97,9 @@ PROTOSHORTNAME An abbreviated name for the protocol; this is displayed
|
||||||
PROTOABBREV A name for the protocol for use in filter expressions;
|
PROTOABBREV A name for the protocol for use in filter expressions;
|
||||||
it may contain only lower-case letters, digits, and hyphens,
|
it may contain only lower-case letters, digits, and hyphens,
|
||||||
underscores, and periods.
|
underscores, and periods.
|
||||||
|
LICENSE The license this dissector is under. Please use a SPDX License
|
||||||
|
identifier.
|
||||||
|
YEARS The years the above license is valid for.
|
||||||
FIELDNAME The displayed name for the header field.
|
FIELDNAME The displayed name for the header field.
|
||||||
FIELDABBREV The abbreviated name for the header field; it may contain
|
FIELDABBREV The abbreviated name for the header field; it may contain
|
||||||
only letters, digits, hyphens, underscores, and periods.
|
only letters, digits, hyphens, underscores, and periods.
|
||||||
|
@ -195,6 +198,16 @@ If, for example, PROTONAME is "Internet Bogosity Discovery Protocol",
|
||||||
PROTOSHORTNAME would be "IBDP", and PROTOABBREV would be "ibdp". Try to
|
PROTOSHORTNAME would be "IBDP", and PROTOABBREV would be "ibdp". Try to
|
||||||
conform with IANA names.
|
conform with IANA names.
|
||||||
|
|
||||||
|
1.2.1 Automatic substitution in code skeleton
|
||||||
|
|
||||||
|
Instead of manual substitutions in the code skeleton, a tool to automate it can
|
||||||
|
be found under the tools directory. The script is called tools/generate-dissector.py
|
||||||
|
and takes all the needed options to generate a compilable dissector. Look at the
|
||||||
|
above fields to know how to set them. Some assumptions have been made in the
|
||||||
|
generation to shorten the list of required options. The script patches the
|
||||||
|
CMakeLists.txt file adding the new dissector in the proper list, alphabetically
|
||||||
|
sorted.
|
||||||
|
|
||||||
1.3 The dissector and the data it receives.
|
1.3 The dissector and the data it receives.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/* packet-PROTOABBREV.c
|
/* packet-PROTOABBREV.c
|
||||||
* Routines for PROTONAME dissection
|
* Routines for PROTONAME dissection
|
||||||
* Copyright 201x, YOUR_NAME <YOUR_EMAIL_ADDRESS>
|
* Copyright YEARS, YOUR_NAME <YOUR_EMAIL_ADDRESS>
|
||||||
*
|
*
|
||||||
* Wireshark - Network traffic analyzer
|
* Wireshark - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@wireshark.org>
|
* By Gerald Combs <gerald@wireshark.org>
|
||||||
* Copyright 1998 Gerald Combs
|
* Copyright 1998 Gerald Combs
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2019-2020, Dario Lombardo <lomato@gmail.com>
|
||||||
|
#
|
||||||
|
# Wireshark - Network traffic analyzer
|
||||||
|
# By Gerald Combs <gerald@wireshark.org>
|
||||||
|
# Copyright 1998 Gerald Combs
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
# This script generates a Wireshark skeleton dissector, based on the example in the doc/ directory.
|
||||||
|
#
|
||||||
|
# Example usage:
|
||||||
|
#
|
||||||
|
# generate-dissector.py --name "My Self" --email "myself@example.com" --protoname "The dumb protocol"
|
||||||
|
# --protoshortname DUMB --protoabbrev dumb --license GPL-2.0-or-later --years "2019-2020"
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='The Wireshark Dissector Generator')
|
||||||
|
parser.add_argument("--name", help="The author of the dissector", required=True)
|
||||||
|
parser.add_argument("--email", help="The email address of the author", required=True)
|
||||||
|
parser.add_argument("--protoname", help="The name of the protocol", required=True)
|
||||||
|
parser.add_argument("--protoshortname", help="The protocol short name", required=True)
|
||||||
|
parser.add_argument("--protoabbrev", help="The protocol abbreviation", required=True)
|
||||||
|
parser.add_argument("--license", help="The license for this dissector (please use a SPDX-License-Identifier). If omitted, GPL-2.0-or-later will be used")
|
||||||
|
parser.add_argument("--years", help="Years of validity for the license. If omitted, the current year will be used")
|
||||||
|
parser.add_argument("-f", "--force", action='store_true', help="Force overwriting the dissector file if it already exists")
|
||||||
|
|
||||||
|
def wsdir():
|
||||||
|
return os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
|
||||||
|
def output_file(args):
|
||||||
|
return os.path.join(wsdir(), "epan/dissectors/packet-" + args.protoabbrev + ".c")
|
||||||
|
|
||||||
|
def read_skeleton():
|
||||||
|
skeletonfile = os.path.join(wsdir(), "doc/packet-PROTOABBREV.c")
|
||||||
|
print("Reding skeleton file: " + skeletonfile)
|
||||||
|
return open(skeletonfile).read()
|
||||||
|
|
||||||
|
def replace_fields(buffer, args):
|
||||||
|
print("Replacing fields in skeleton")
|
||||||
|
output = buffer\
|
||||||
|
.replace("YOUR_NAME", args.name)\
|
||||||
|
.replace("YOUR_EMAIL_ADDRESS", args.email)\
|
||||||
|
.replace("PROTONAME", args.protoname)\
|
||||||
|
.replace("PROTOSHORTNAME", args.protoshortname)\
|
||||||
|
.replace("PROTOABBREV", args.protoabbrev)\
|
||||||
|
.replace("FIELDNAME", "Sample Field")\
|
||||||
|
.replace("FIELDABBREV", "sample_field")\
|
||||||
|
.replace("FT_FIELDTYPE", "FT_STRING")\
|
||||||
|
.replace("FIELDDISPLAY", "BASE_NONE")\
|
||||||
|
.replace("FIELDCONVERT", "NULL")\
|
||||||
|
.replace("BITMASK", "0x0")\
|
||||||
|
.replace("FIELDDESCR", "NULL")\
|
||||||
|
.replace("MAX_NEEDED_FOR_HEURISTICS", "1")\
|
||||||
|
.replace("TEST_HEURISTICS_FAIL", "0")\
|
||||||
|
.replace("ENC_xxx", "ENC_NA")\
|
||||||
|
.replace("EXPERTABBREV", "expert")\
|
||||||
|
.replace("PI_GROUP", "PI_PROTOCOL")\
|
||||||
|
.replace("PI_SEVERITY", "PI_ERROR")\
|
||||||
|
.replace("TEST_EXPERT_condition", "0")\
|
||||||
|
.replace("const char *subtree", "\"\"")
|
||||||
|
|
||||||
|
if args.license:
|
||||||
|
output = output.replace("LICENSE", args.license)
|
||||||
|
else:
|
||||||
|
output = output.replace("LICENSE", "GPL-2.0-or-later")
|
||||||
|
|
||||||
|
if args.years:
|
||||||
|
output = output.replace("YEARS", args.years)
|
||||||
|
else:
|
||||||
|
output = output.replace("YEARS", str(datetime.now().year))
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def write_dissector(buffer, args):
|
||||||
|
ofile = output_file(args)
|
||||||
|
if os.path.isfile(ofile) and not args.force:
|
||||||
|
raise Exception("The file " + ofile + " already exists. You're likely overwriting an existing dissector.")
|
||||||
|
print("Writing output file: " + ofile)
|
||||||
|
return open(ofile, "w").write(buffer)
|
||||||
|
|
||||||
|
def patch_makefile(args):
|
||||||
|
cmakefile = os.path.join(wsdir(), "epan/dissectors/CMakeLists.txt")
|
||||||
|
print("Patching makefile: " + cmakefile)
|
||||||
|
output = ""
|
||||||
|
patchline = "${CMAKE_CURRENT_SOURCE_DIR}/packet-" + args.protoabbrev + ".c"
|
||||||
|
in_group = False
|
||||||
|
patched = False
|
||||||
|
for line in open(cmakefile):
|
||||||
|
line_strip = line.strip()
|
||||||
|
if in_group and line_strip == ")":
|
||||||
|
in_group = False
|
||||||
|
if in_group and not patched and line_strip > patchline:
|
||||||
|
output += "\t" + patchline + "\n"
|
||||||
|
patched = True
|
||||||
|
if line_strip == "set(DISSECTOR_SRC":
|
||||||
|
in_group = True
|
||||||
|
if line_strip != patchline:
|
||||||
|
output += line
|
||||||
|
open(cmakefile, "w").write(output)
|
||||||
|
|
||||||
|
def print_header():
|
||||||
|
print("")
|
||||||
|
print("**************************************************")
|
||||||
|
print("* Wireshark skeleton dissector generator *")
|
||||||
|
print("* *")
|
||||||
|
print("* Generate a new dissector for your protocol *")
|
||||||
|
print("* starting from the skeleton provided in the *")
|
||||||
|
print("* doc directory. *")
|
||||||
|
print("* *")
|
||||||
|
print("* Copyright 2019 Dario Lombardo *")
|
||||||
|
print("**************************************************")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def print_trailer(args):
|
||||||
|
print("")
|
||||||
|
print("The skeleton for the dissector of the " + args.protoshortname + " protocol has been generated.")
|
||||||
|
print("Please review/extend it to match your specific criterias.")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print_header()
|
||||||
|
args = parser.parse_args()
|
||||||
|
buffer = replace_fields(read_skeleton(), args)
|
||||||
|
write_dissector(buffer, args)
|
||||||
|
patch_makefile(args)
|
||||||
|
print_trailer(args)
|
Loading…
Reference in New Issue