]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer: shorter code for proto string helpers
authorPhilippe Antoine <contact@catenacyber.fr>
Thu, 23 Mar 2023 16:32:45 +0000 (17:32 +0100)
committerVictor Julien <vjulien@oisf.net>
Fri, 5 May 2023 08:34:33 +0000 (10:34 +0200)
scripts/setup-app-layer.py
src/app-layer-protos.c

index c56042e9c4409f37531b5a8ced66246b55bd0a03..72f28c986c66ba600c5dc2372564fd5d14979c63 100755 (executable)
@@ -132,30 +132,13 @@ def patch_app_layer_protos_c(protoname):
     print("Patching %s." % (filename))
     output = io.StringIO()
 
-    # Read in all the lines as we'll be doing some multi-line
-    # duplications.
-    inlines = open(filename).readlines()
-    for i, line in enumerate(inlines):
-
-        if line.find("case ALPROTO_TEMPLATE:") > -1:
-            # Duplicate the section starting at this line and
-            # including the following 2 lines.
-            for j in range(i, i + 3):
-                temp = inlines[j]
-                temp = temp.replace("TEMPLATE", protoname.upper())
-                temp = temp.replace("template", protoname.lower())
-                output.write(temp)
-
-        if line.find("strcmp(proto_name, \"template\")") > -1:
-            # Duplicate the section starting at this line and
-            # including the following line.
-            for j in range(i, i + 2):
-                temp = inlines[j]
-                temp = temp.replace("TEMPLATE", protoname.upper())
-                temp = temp.replace("template", protoname.lower())
-                output.write(temp)
-
-        output.write(line)
+    with open(filename) as infile:
+        for line in infile:
+            if line.find("TEMPLATE") > -1:
+                new_line = line.replace("TEMPLATE", protoname.upper()).replace(
+                    "template", protoname.lower())
+                output.write(new_line)
+            output.write(line)
     open(filename, "w").write(output.getvalue())
 
 def patch_app_layer_parser_c(proto):
index f944af7c438e061032aa49940730360fead77585..368efacd88d710ad7b12ce3e470df79fc8e2bbc4 100644 (file)
 #include "suricata-common.h"
 #include "app-layer-protos.h"
 
-#define CASE_CODE(E)  case E: return #E
+typedef struct AppProtoStringTuple {
+    AppProto alproto;
+    const char *str;
+} AppProtoStringTuple;
+
+const AppProtoStringTuple AppProtoStrings[ALPROTO_MAX] = {
+    { ALPROTO_UNKNOWN, "unknown" },
+    { ALPROTO_HTTP1, "http1" },
+    { ALPROTO_FTP, "ftp" },
+    { ALPROTO_SMTP, "smtp" },
+    { ALPROTO_TLS, "tls" },
+    { ALPROTO_SSH, "ssh" },
+    { ALPROTO_IMAP, "imap" },
+    { ALPROTO_JABBER, "jabber" },
+    { ALPROTO_SMB, "smb" },
+    { ALPROTO_DCERPC, "dcerpc" },
+    { ALPROTO_IRC, "irc" },
+    { ALPROTO_DNS, "dns" },
+    { ALPROTO_MODBUS, "modbus" },
+    { ALPROTO_ENIP, "enip" },
+    { ALPROTO_DNP3, "dnp3" },
+    { ALPROTO_NFS, "nfs" },
+    { ALPROTO_NTP, "ntp" },
+    { ALPROTO_FTPDATA, "ftp-data" },
+    { ALPROTO_TFTP, "tftp" },
+    { ALPROTO_IKE, "ike" },
+    { ALPROTO_KRB5, "krb5" },
+    { ALPROTO_QUIC, "quic" },
+    { ALPROTO_DHCP, "dhcp" },
+    { ALPROTO_SNMP, "snmp" },
+    { ALPROTO_SIP, "sip" },
+    { ALPROTO_RFB, "rfb" },
+    { ALPROTO_MQTT, "mqtt" },
+    { ALPROTO_PGSQL, "pgsql" },
+    { ALPROTO_TELNET, "telnet" },
+    { ALPROTO_TEMPLATE, "template" },
+    { ALPROTO_RDP, "rdp" },
+    { ALPROTO_HTTP2, "http2" },
+    { ALPROTO_BITTORRENT_DHT, "bittorrent-dht" },
+    { ALPROTO_HTTP, "http" },
+    { ALPROTO_FAILED, "failed" },
+#ifdef UNITTESTS
+    { ALPROTO_TEST, "test" },
+#endif
+};
 
 const char *AppProtoToString(AppProto alproto)
 {
     const char *proto_name = NULL;
-    enum AppProtoEnum proto = alproto;
-
-    switch (proto) {
+    switch (alproto) {
+        // special cases
         case ALPROTO_HTTP1:
             proto_name = "http";
             break;
-        case ALPROTO_FTP:
-            proto_name = "ftp";
-            break;
-        case ALPROTO_SMTP:
-            proto_name = "smtp";
-            break;
-        case ALPROTO_TLS:
-            proto_name = "tls";
-            break;
-        case ALPROTO_SSH:
-            proto_name = "ssh";
-            break;
-        case ALPROTO_IMAP:
-            proto_name = "imap";
-            break;
-        case ALPROTO_JABBER:
-            proto_name = "jabber";
-            break;
-        case ALPROTO_SMB:
-            proto_name = "smb";
-            break;
-        case ALPROTO_DCERPC:
-            proto_name = "dcerpc";
-            break;
-        case ALPROTO_IRC:
-            proto_name = "irc";
-            break;
-        case ALPROTO_DNS:
-            proto_name = "dns";
-            break;
-        case ALPROTO_MODBUS:
-            proto_name = "modbus";
-            break;
-        case ALPROTO_ENIP:
-            proto_name = "enip";
-            break;
-        case ALPROTO_DNP3:
-            proto_name = "dnp3";
-            break;
-        case ALPROTO_NFS:
-            proto_name = "nfs";
-            break;
-        case ALPROTO_NTP:
-            proto_name = "ntp";
-            break;
-        case ALPROTO_FTPDATA:
-            proto_name = "ftp-data";
-            break;
-        case ALPROTO_TFTP:
-            proto_name = "tftp";
-            break;
-        case ALPROTO_IKE:
-            proto_name = "ike";
-            break;
-        case ALPROTO_KRB5:
-            proto_name = "krb5";
-            break;
-        case ALPROTO_QUIC:
-            proto_name = "quic";
-            break;
-        case ALPROTO_DHCP:
-            proto_name = "dhcp";
-            break;
-        case ALPROTO_SNMP:
-            proto_name = "snmp";
-            break;
-        case ALPROTO_SIP:
-            proto_name = "sip";
-            break;
-        case ALPROTO_RFB:
-            proto_name = "rfb";
-           break;
-        case ALPROTO_MQTT:
-            proto_name = "mqtt";
-            break;
-        case ALPROTO_PGSQL:
-            proto_name = "pgsql";
-            break;
-        case ALPROTO_TELNET:
-            proto_name = "telnet";
-            break;
-        case ALPROTO_TEMPLATE:
-            proto_name = "template";
-            break;
-        case ALPROTO_RDP:
-            proto_name = "rdp";
-            break;
-        case ALPROTO_HTTP2:
-            proto_name = "http2";
-            break;
         case ALPROTO_HTTP:
             proto_name = "http_any";
             break;
-        case ALPROTO_BITTORRENT_DHT:
-            proto_name = "bittorrent-dht";
-            break;
-        case ALPROTO_FAILED:
-            proto_name = "failed";
-            break;
-#ifdef UNITTESTS
-        case ALPROTO_TEST:
-#endif
-        case ALPROTO_MAX:
-        case ALPROTO_UNKNOWN:
-            break;
+        default:
+            if (alproto < ARRAY_SIZE(AppProtoStrings)) {
+                BUG_ON(AppProtoStrings[alproto].alproto != alproto);
+                proto_name = AppProtoStrings[alproto].str;
+            }
     }
-
     return proto_name;
 }
 
@@ -151,74 +96,11 @@ AppProto StringToAppProto(const char *proto_name)
     if (proto_name == NULL)
         return ALPROTO_UNKNOWN;
 
-    if (strcmp(proto_name, "http") == 0)
-        return ALPROTO_HTTP;
-    if (strcmp(proto_name, "http1") == 0)
-        return ALPROTO_HTTP1;
-    if (strcmp(proto_name, "ftp") == 0)
-        return ALPROTO_FTP;
-    if (strcmp(proto_name, "ftp-data") == 0)
-        return ALPROTO_FTPDATA;
-    if (strcmp(proto_name, "tftp") == 0)
-        return ALPROTO_TFTP;
-    if (strcmp(proto_name, "smtp") == 0)
-        return ALPROTO_SMTP;
-    if (strcmp(proto_name, "tls") == 0)
-        return ALPROTO_TLS;
-    if (strcmp(proto_name, "ssh") == 0)
-        return ALPROTO_SSH;
-    if (strcmp(proto_name, "imap") == 0)
-        return ALPROTO_IMAP;
-    if (strcmp(proto_name, "jabber") == 0)
-        return ALPROTO_JABBER;
-    if (strcmp(proto_name, "smb") == 0)
-        return ALPROTO_SMB;
-    if (strcmp(proto_name, "dcerpc") == 0)
-        return ALPROTO_DCERPC;
-    if (strcmp(proto_name, "irc") == 0)
-        return ALPROTO_IRC;
-    if (strcmp(proto_name, "dns") == 0)
-        return ALPROTO_DNS;
-    if (strcmp(proto_name, "modbus") == 0)
-        return ALPROTO_MODBUS;
-    if (strcmp(proto_name, "enip") == 0)
-        return ALPROTO_ENIP;
-    if (strcmp(proto_name, "dnp3") == 0)
-        return ALPROTO_DNP3;
-    if (strcmp(proto_name, "nfs") == 0)
-        return ALPROTO_NFS;
-    if (strcmp(proto_name, "ntp") == 0)
-        return ALPROTO_NTP;
-    if (strcmp(proto_name, "ike") == 0)
-        return ALPROTO_IKE;
-    if (strcmp(proto_name, "krb5") == 0)
-        return ALPROTO_KRB5;
-    if (strcmp(proto_name, "quic") == 0)
-        return ALPROTO_QUIC;
-    if (strcmp(proto_name, "dhcp") == 0)
-        return ALPROTO_DHCP;
-    if (strcmp(proto_name, "snmp") == 0)
-        return ALPROTO_SNMP;
-    if (strcmp(proto_name, "sip") == 0)
-        return ALPROTO_SIP;
-    if (strcmp(proto_name, "rfb") == 0)
-        return ALPROTO_RFB;
-    if (strcmp(proto_name, "mqtt") == 0)
-        return ALPROTO_MQTT;
-    if (strcmp(proto_name, "pgsql") == 0)
-        return ALPROTO_PGSQL;
-    if (strcmp(proto_name, "telnet") == 0)
-        return ALPROTO_TELNET;
-    if (strcmp(proto_name, "template") == 0)
-        return ALPROTO_TEMPLATE;
-    if (strcmp(proto_name, "rdp") == 0)
-        return ALPROTO_RDP;
-    if (strcmp(proto_name, "http2") == 0)
-        return ALPROTO_HTTP2;
-    if (strcmp(proto_name, "bittorrent-dht") == 0)
-        return ALPROTO_BITTORRENT_DHT;
-    if (strcmp(proto_name, "failed") == 0)
-        return ALPROTO_FAILED;
+    // We could use a Multi Pattern Matcher
+    for (size_t i = 0; i < ARRAY_SIZE(AppProtoStrings); i++) {
+        if (strcmp(proto_name, AppProtoStrings[i].str) == 0)
+            return AppProtoStrings[i].alproto;
+    }
 
     return ALPROTO_UNKNOWN;
 }