You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/scripts/setup-app-layer.sh

211 lines
3.9 KiB
Bash

#! /usr/bin/env bash
#
# Script to provision a new application layer detector and parser.
set -e
#set -x
# Fail if "ed" is not available.
if ! which ed > /dev/null 2>&1; then
echo "error: the program \"ed\" is required for this script"
exit 1
fi
function usage() {
cat <<EOF
usage: $0 <protocol name>
This script will provision a new app-layer parser for the protocol
name specified on the command line. This is done by copying and
patching src/app-layer-template.[ch] then linking the new files into
the build system.
Examples:
$0 DNP3
$0 Gopher
EOF
}
# Make sure we are running from the correct directory.
set_dir() {
if [ -e ./suricata.c ]; then
cd ..
elif [ -e ./src/suricata.c ]; then
# Do nothing.
true
else
echo "error: this does not appear to be a suricata source directory."
exit 1
fi
}
fail_if_exists() {
path="$1"
if test -e "${path}"; then
echo "error: ${path} already exists."
exit 1
fi
}
function copy_template_file() {
src="$1"
dst="$2"
echo "Creating ${dst}."
sed -e '/TEMPLATE_START_REMOVE/,/TEMPLATE_END_REMOVE/d' \
-e "s/TEMPLATE/${protoname_upper}/g" \
-e "s/template/${protoname_lower}/g" \
-e "s/Template/${protoname}/g" \
> ${dst} < ${src}
}
function copy_app_layer_templates {
src_h="src/app-layer-template.h"
dst_h="src/app-layer-${protoname_lower}.h"
src_c="src/app-layer-template.c"
dst_c="src/app-layer-${protoname_lower}.c"
fail_if_exists ${dst_h}
fail_if_exists ${dst_c}
copy_template_file ${src_h} ${dst_h}
copy_template_file ${src_c} ${dst_c}
}
function patch_makefile_am {
filename="src/Makefile.am"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/app-layer-template
t-
s/template/${protoname_lower}/g
w
EOF
}
function patch_app_layer_protos_h {
filename="src/app-layer-protos.h"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/ALPROTO_TEMPLATE
t-
s/TEMPLATE/${protoname_upper}/
w
EOF
}
function patch_app_layer_protos_c {
filename="src/app-layer-protos.c"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/case ALPROTO_TEMPLATE
.,+2t-
-2
s/TEMPLATE/${protoname_upper}/
+
s/template/${protoname_lower}/
/if (strcmp(proto_name,"template")==0)
t-
-,.s/TEMPLATE/${protoname_upper}/
-,.s/template/${protoname_lower}/
w
EOF
}
function patch_app_layer_detect_proto_c() {
filename="src/app-layer-detect-proto.c"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/== ALPROTO_TEMPLATE
.,+t-
-,.s/TEMPLATE/${protoname_upper}/
+3
/== ALPROTO_TEMPLATE
.,+t-
-,.s/TEMPLATE/${protoname_upper}/
+3
w
EOF
}
function patch_app_layer_parser_c() {
filename="src/app-layer-parser.c"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/#include "app-layer-template.h"
t-
s/template/${protoname_lower}/
/RegisterTemplateParsers
t-
s/Template/${protoname}/
w
EOF
}
function patch_suricata_yaml_in() {
filename="suricata.yaml.in"
echo "Patching ${filename}."
ed -s ${filename} > /dev/null <<EOF
/^app-layer:
/protocols:
a
${protoname_lower}:
enabled: yes
.
w
EOF
}
# Main...
set_dir
protoname="$1"
# Make sure the protocol name looks like a proper name (starts with a
# capital letter).
case "${protoname}" in
[[:upper:]]*)
# OK.
;;
"")
usage
exit 1
;;
*)
echo "error: protocol name must beging with an upper case letter"
exit 1
;;
esac
protoname_lower=$(printf ${protoname} | tr '[:upper:]' '[:lower:]')
protoname_upper=$(printf ${protoname} | tr '[:lower:]' '[:upper:]')
copy_app_layer_templates
patch_makefile_am
patch_app_layer_protos_h
patch_app_layer_protos_c
patch_app_layer_detect_proto_c
patch_app_layer_parser_c
patch_suricata_yaml_in
cat <<EOF
An application detector and parser for the protocol ${protoname} has
now been setup in the files:
src/app-layer-${protoname_lower}.h
src/app-layer-${protoname_lower}.c
and should now build cleanly. Try running 'make'.
EOF