aboutsummaryrefslogtreecommitdiffstats
path: root/epan/protobuf-helper.h
diff options
context:
space:
mode:
authorHuang Qiangxiong <qiangxiong.huang@qq.com>2017-09-23 09:05:21 -0400
committerAnders Broman <a.broman58@gmail.com>2019-10-07 10:35:52 +0000
commit5750c4981c56464ef1dbb8d7cfb0446cdb4b12ec (patch)
tree83e99a97609a3b8e12653d2041b4722004c87021 /epan/protobuf-helper.h
parent0d8bebc327cd71736c152e8e428294f826e51561 (diff)
protobuf: add support for Protocol Buffers Language (*.proto) files
1. A C-style Protocol Buffers Language (PBL) parser for *.proto file is added. It contains protobuf_lang_scanner.l (lex scanner), epan/protobuf_lang.y (grammar parser), and protobuf_lang_tree.h/c (grammar tree implementation). 2. The protobuf-helper.h/cpp is an interface wrapper layer. If one day C++ is allowed, we can create a protobuf-helper.cpp file, which using offical protobuf C++ library, to replace protobuf-helper.c. That keeps packet-protobuf.c unchanged. 3. User can specify protobuf search paths, and the UDP ports to protobuf message type maps at the Protobuf protocol preferences. 4. Other dissectors can pass the message type to Protobuf dissector by data parameter or pinfo->private_table["pb_msg_type"] (pinfo.private["pb_msg_type"] in lua). Some Sample of GRPC with Protobuf captures can be found in Bug: 13932. Bug: 13932 Change-Id: Ife16c2f7b381296f8db4740dabe5f8362a456f48 Reviewed-on: https://code.wireshark.org/review/22892 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/protobuf-helper.h')
-rw-r--r--epan/protobuf-helper.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/epan/protobuf-helper.h b/epan/protobuf-helper.h
new file mode 100644
index 0000000000..3dada793eb
--- /dev/null
+++ b/epan/protobuf-helper.h
@@ -0,0 +1,209 @@
+/* protobuf-helper.h
+ *
+ * C Wrapper Layer of Protocol Buffers Language library.
+ * Copyright 2019, Huang Qiangxiong <qiangxiong.huang@qq.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/* The packet-protobuf dissector needs get information from *.proto files for dissecting
+ * protobuf packet correctly. The information includes:
+ * - The names of MESSAGE, ENUM, FIELD, ENUM_VALUE;
+ * - The data type of FIELD which assuring the value of protobuf field of packet can be dissected correctly.
+ *
+ * At present, we use C Protocol Buffers Language Parser which generated by protobuf_lang.y and protobuf_lang_scanner.l.
+ * Because wireshark is mainly implemented in plain ANSI C but the offical protobuf library is implemented in C++ language.
+ *
+ * One day, if C++ library is allowd, we can create a protobuf-helper.cpp file, that invoking offical protobuf C++ library directly,
+ * to replace protobuf-helper.c. The packet-protobuf.c can keep unchanged.
+ */
+
+#ifndef __PROTOBUF_HELPER_H__
+#define __PROTOBUF_HELPER_H__
+
+#include <epan/value_string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Protobuf field type. Must be kept in sync with FieldType of protobuf wire_format_lite.h */
+#define protobuf_field_type_VALUE_STRING_LIST(XXX) \
+ XXX(PROTOBUF_TYPE_NONE, 0, "") \
+ XXX(PROTOBUF_TYPE_DOUBLE, 1, "double") \
+ XXX(PROTOBUF_TYPE_FLOAT, 2, "float") \
+ XXX(PROTOBUF_TYPE_INT64, 3, "int64") \
+ XXX(PROTOBUF_TYPE_UINT64, 4, "uint64") \
+ XXX(PROTOBUF_TYPE_INT32, 5, "int32") \
+ XXX(PROTOBUF_TYPE_FIXED64, 6, "fixed64") \
+ XXX(PROTOBUF_TYPE_FIXED32, 7, "fixed32") \
+ XXX(PROTOBUF_TYPE_BOOL, 8, "bool") \
+ XXX(PROTOBUF_TYPE_STRING, 9, "string") \
+ XXX(PROTOBUF_TYPE_GROUP, 10, "group") \
+ XXX(PROTOBUF_TYPE_MESSAGE, 11, "message") \
+ XXX(PROTOBUF_TYPE_BYTES, 12, "bytes") \
+ XXX(PROTOBUF_TYPE_UINT32, 13, "uint32") \
+ XXX(PROTOBUF_TYPE_ENUM, 14, "enum") \
+ XXX(PROTOBUF_TYPE_SFIXED32, 15, "sfixed32") \
+ XXX(PROTOBUF_TYPE_SFIXED64, 16, "sfixed64") \
+ XXX(PROTOBUF_TYPE_SINT32, 17, "sint32") \
+ XXX(PROTOBUF_TYPE_SINT64, 18, "sint64")
+
+#define PROTOBUF_MAX_FIELD_TYPE 18
+
+VALUE_STRING_ENUM(protobuf_field_type);
+VALUE_STRING_ARRAY_GLOBAL_DCL(protobuf_field_type);
+
+/* like google::protobuf::DescriptorPool of protobuf cpp library */
+typedef struct PbwDescriptorPool PbwDescriptorPool;
+/* like google::protobuf::MethodDescriptor of protobuf cpp library */
+typedef struct PbwMethodDescriptor PbwMethodDescriptor;
+/* like google::protobuf::Descriptor of protobuf cpp library */
+typedef struct PbwDescriptor PbwDescriptor;
+/* like google::protobuf::FieldDescriptor of protobuf cpp library */
+typedef struct PbwFieldDescriptor PbwFieldDescriptor;
+/* like google::protobuf::EnumDescriptor of protobuf cpp library */
+typedef struct PbwEnumDescriptor PbwEnumDescriptor;
+/* like google::protobuf::EnumValueDescriptor of protobuf cpp library */
+typedef struct PbwEnumValueDescriptor PbwEnumValueDescriptor;
+
+typedef void(*pbw_report_error_cb_t)(const char *msg_format, ...);
+
+/**
+ Reinitialize PbwDescriptorPool according to proto files directories.
+ @param pool The output DescriptorPool will be created. If *pool is not NULL, it will free it first.
+ @param directories The root directories containing proto files. Must end with NULL element.
+ @param error_cb The error reporter callback function. */
+void
+pbw_reinit_DescriptorPool(PbwDescriptorPool** pool, const char** directories, pbw_report_error_cb_t error_cb);
+
+/* load a proto file, return 0 if successed */
+int
+pbw_load_proto_file(PbwDescriptorPool* pool, const char* filename);
+
+/* like DescriptorPool::FindMethodByName */
+const PbwMethodDescriptor*
+pbw_DescriptorPool_FindMethodByName(const PbwDescriptorPool* pool, const char* name);
+
+/* like MethodDescriptor::name() */
+const char*
+pbw_MethodDescriptor_name(const PbwMethodDescriptor* method);
+
+/* like MethodDescriptor::full_name() */
+const char*
+pbw_MethodDescriptor_full_name(const PbwMethodDescriptor* method);
+
+/* like MethodDescriptor::input_type() */
+const PbwDescriptor*
+pbw_MethodDescriptor_input_type(const PbwMethodDescriptor* method);
+
+/* like MethodDescriptor::output_type() */
+const PbwDescriptor*
+pbw_MethodDescriptor_output_type(const PbwMethodDescriptor* method);
+
+/* like DescriptorPool::FindMessageTypeByName() */
+const PbwDescriptor*
+pbw_DescriptorPool_FindMessageTypeByName(const PbwDescriptorPool* pool, const char* name);
+
+/* like Descriptor::name() */
+const char*
+pbw_Descriptor_name(const PbwDescriptor* message);
+
+/* like Descriptor::full_name() */
+const char*
+pbw_Descriptor_full_name(const PbwDescriptor* message);
+
+/* like Descriptor::field_count() */
+int
+pbw_Descriptor_field_count(const PbwDescriptor* message);
+
+/* like Descriptor::field() */
+const PbwFieldDescriptor*
+pbw_Descriptor_field(const PbwDescriptor* message, int field_index);
+
+/* like Descriptor::FindFieldByNumber() */
+const PbwFieldDescriptor*
+pbw_Descriptor_FindFieldByNumber(const PbwDescriptor* message, int number);
+
+/* like Descriptor::FindFieldByName() */
+const PbwFieldDescriptor*
+pbw_Descriptor_FindFieldByName(const PbwDescriptor* message, const char* name);
+
+/* like FieldDescriptor::full_name() */
+const char*
+pbw_FieldDescriptor_full_name(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::name() */
+const char*
+pbw_FieldDescriptor_name(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::number() */
+int
+pbw_FieldDescriptor_number(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::type() */
+int
+pbw_FieldDescriptor_type(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::is_repeated() */
+int
+pbw_FieldDescriptor_is_repeated(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::is_packed() */
+int
+pbw_FieldDescriptor_is_packed(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::typeName() */
+const char*
+pbw_FieldDescriptor_typeName(int field_type);
+
+/* like FieldDescriptor::message_type() */
+const PbwDescriptor*
+pbw_FieldDescriptor_message_type(const PbwFieldDescriptor* field);
+
+/* like FieldDescriptor::enum_type() */
+const PbwEnumDescriptor*
+pbw_FieldDescriptor_enum_type(const PbwFieldDescriptor* field);
+
+/* like EnumDescriptor::name() */
+const char*
+pbw_EnumDescriptor_name(const PbwEnumDescriptor* anEnum);
+
+/* like EnumDescriptor::full_name() */
+const char*
+pbw_EnumDescriptor_full_name(const PbwEnumDescriptor* anEnum);
+
+/* like EnumDescriptor::FindValueByNumber() */
+const PbwEnumValueDescriptor*
+pbw_EnumDescriptor_FindValueByNumber(const PbwEnumDescriptor* anEnum, int number);
+
+/* like EnumValueDescriptor::name() */
+const char*
+pbw_EnumValueDescriptor_name(const PbwEnumValueDescriptor* enumValue);
+
+/* like EnumValueDescriptor::full_name() */
+const char*
+pbw_EnumValueDescriptor_full_name(const PbwEnumValueDescriptor* enumValue);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PROTOBUF_HELPER_H__ */
+
+/*
+ * Editor modelines - https://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:
+ */