1 /* protobuf-helper.h 2 * 3 * C Wrapper Layer of Protocol Buffers Language library. 4 * Copyright 2019, Huang Qiangxiong <qiangxiong.huang@qq.com> 5 * 6 * Wireshark - Network traffic analyzer 7 * By Gerald Combs <gerald@wireshark.org> 8 * Copyright 1998 Gerald Combs 9 * 10 * SPDX-License-Identifier: GPL-2.0-or-later 11 */ 12 13 /* The packet-protobuf dissector needs get information from *.proto files for dissecting 14 * protobuf packet correctly. The information includes: 15 * - The names of MESSAGE, ENUM, FIELD, ENUM_VALUE; 16 * - The data type of FIELD which assuring the value of protobuf field of packet can be dissected correctly. 17 * 18 * At present, we use C Protocol Buffers Language Parser which generated by protobuf_lang_parser.lemon and protobuf_lang_scanner.l. 19 * Because wireshark is mainly implemented in plain ANSI C but the offical protobuf library is implemented in C++ language. 20 * 21 * One day, if C++ library is allowd, we can create a protobuf-helper.cpp file, that invoking offical protobuf C++ library directly, 22 * to replace protobuf-helper.c. The packet-protobuf.c can keep unchanged. 23 */ 24 25 #ifndef __PROTOBUF_HELPER_H__ 26 #define __PROTOBUF_HELPER_H__ 27 28 #include <epan/value_string.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif /* __cplusplus */ 33 34 /* Protobuf field type. Must be kept in sync with FieldType of protobuf wire_format_lite.h */ 35 #define protobuf_field_type_VALUE_STRING_LIST(XXX) \ 36 XXX(PROTOBUF_TYPE_NONE, 0, "") \ 37 XXX(PROTOBUF_TYPE_DOUBLE, 1, "double") \ 38 XXX(PROTOBUF_TYPE_FLOAT, 2, "float") \ 39 XXX(PROTOBUF_TYPE_INT64, 3, "int64") \ 40 XXX(PROTOBUF_TYPE_UINT64, 4, "uint64") \ 41 XXX(PROTOBUF_TYPE_INT32, 5, "int32") \ 42 XXX(PROTOBUF_TYPE_FIXED64, 6, "fixed64") \ 43 XXX(PROTOBUF_TYPE_FIXED32, 7, "fixed32") \ 44 XXX(PROTOBUF_TYPE_BOOL, 8, "bool") \ 45 XXX(PROTOBUF_TYPE_STRING, 9, "string") \ 46 XXX(PROTOBUF_TYPE_GROUP, 10, "group") \ 47 XXX(PROTOBUF_TYPE_MESSAGE, 11, "message") \ 48 XXX(PROTOBUF_TYPE_BYTES, 12, "bytes") \ 49 XXX(PROTOBUF_TYPE_UINT32, 13, "uint32") \ 50 XXX(PROTOBUF_TYPE_ENUM, 14, "enum") \ 51 XXX(PROTOBUF_TYPE_SFIXED32, 15, "sfixed32") \ 52 XXX(PROTOBUF_TYPE_SFIXED64, 16, "sfixed64") \ 53 XXX(PROTOBUF_TYPE_SINT32, 17, "sint32") \ 54 XXX(PROTOBUF_TYPE_SINT64, 18, "sint64") 55 56 #define PROTOBUF_MAX_FIELD_TYPE 18 57 58 VALUE_STRING_ENUM(protobuf_field_type); 59 VALUE_STRING_ARRAY_GLOBAL_DCL(protobuf_field_type); 60 61 /* like google::protobuf::DescriptorPool of protobuf cpp library */ 62 typedef struct PbwDescriptorPool PbwDescriptorPool; 63 /* like google::protobuf::MethodDescriptor of protobuf cpp library */ 64 typedef struct PbwMethodDescriptor PbwMethodDescriptor; 65 /* like google::protobuf::Descriptor of protobuf cpp library */ 66 typedef struct PbwDescriptor PbwDescriptor; 67 /* like google::protobuf::FieldDescriptor of protobuf cpp library */ 68 typedef struct PbwFieldDescriptor PbwFieldDescriptor; 69 /* like google::protobuf::EnumDescriptor of protobuf cpp library */ 70 typedef struct PbwEnumDescriptor PbwEnumDescriptor; 71 /* like google::protobuf::EnumValueDescriptor of protobuf cpp library */ 72 typedef struct PbwEnumValueDescriptor PbwEnumValueDescriptor; 73 74 typedef void(*pbw_report_error_cb_t)(const char *msg_format, ...); 75 76 /** 77 Reinitialize PbwDescriptorPool according to proto files directories. 78 @param pool The output DescriptorPool will be created. If *pool is not NULL, it will free it first. 79 @param directories The root directories containing proto files. Must end with NULL element. 80 @param error_cb The error reporter callback function. */ 81 void 82 pbw_reinit_DescriptorPool(PbwDescriptorPool** pool, const char** directories, pbw_report_error_cb_t error_cb); 83 84 /* load a proto file, return 0 if successed */ 85 int 86 pbw_load_proto_file(PbwDescriptorPool* pool, const char* filename); 87 88 /* like DescriptorPool::FindMethodByName */ 89 const PbwMethodDescriptor* 90 pbw_DescriptorPool_FindMethodByName(const PbwDescriptorPool* pool, const char* name); 91 92 /* like MethodDescriptor::name() */ 93 const char* 94 pbw_MethodDescriptor_name(const PbwMethodDescriptor* method); 95 96 /* like MethodDescriptor::full_name() */ 97 const char* 98 pbw_MethodDescriptor_full_name(const PbwMethodDescriptor* method); 99 100 /* like MethodDescriptor::input_type() */ 101 const PbwDescriptor* 102 pbw_MethodDescriptor_input_type(const PbwMethodDescriptor* method); 103 104 /* like MethodDescriptor::output_type() */ 105 const PbwDescriptor* 106 pbw_MethodDescriptor_output_type(const PbwMethodDescriptor* method); 107 108 /* like DescriptorPool::FindMessageTypeByName() */ 109 const PbwDescriptor* 110 pbw_DescriptorPool_FindMessageTypeByName(const PbwDescriptorPool* pool, const char* name); 111 112 /* like Descriptor::name() */ 113 const char* 114 pbw_Descriptor_name(const PbwDescriptor* message); 115 116 /* like Descriptor::full_name() */ 117 const char* 118 pbw_Descriptor_full_name(const PbwDescriptor* message); 119 120 /* like Descriptor::field_count() */ 121 int 122 pbw_Descriptor_field_count(const PbwDescriptor* message); 123 124 /* like Descriptor::field() */ 125 const PbwFieldDescriptor* 126 pbw_Descriptor_field(const PbwDescriptor* message, int field_index); 127 128 /* like Descriptor::FindFieldByNumber() */ 129 const PbwFieldDescriptor* 130 pbw_Descriptor_FindFieldByNumber(const PbwDescriptor* message, int number); 131 132 /* like Descriptor::FindFieldByName() */ 133 const PbwFieldDescriptor* 134 pbw_Descriptor_FindFieldByName(const PbwDescriptor* message, const char* name); 135 136 /* like FieldDescriptor::full_name() */ 137 const char* 138 pbw_FieldDescriptor_full_name(const PbwFieldDescriptor* field); 139 140 /* like FieldDescriptor::name() */ 141 const char* 142 pbw_FieldDescriptor_name(const PbwFieldDescriptor* field); 143 144 /* like FieldDescriptor::number() */ 145 int 146 pbw_FieldDescriptor_number(const PbwFieldDescriptor* field); 147 148 /* like FieldDescriptor::type() */ 149 int 150 pbw_FieldDescriptor_type(const PbwFieldDescriptor* field); 151 152 /* like FieldDescriptor::is_repeated() */ 153 int 154 pbw_FieldDescriptor_is_repeated(const PbwFieldDescriptor* field); 155 156 /* like FieldDescriptor::is_packed() */ 157 int 158 pbw_FieldDescriptor_is_packed(const PbwFieldDescriptor* field); 159 160 /* like FieldDescriptor::typeName() */ 161 const char* 162 pbw_FieldDescriptor_typeName(int field_type); 163 164 /* like FieldDescriptor::message_type() */ 165 const PbwDescriptor* 166 pbw_FieldDescriptor_message_type(const PbwFieldDescriptor* field); 167 168 /* like FieldDescriptor::enum_type() */ 169 const PbwEnumDescriptor* 170 pbw_FieldDescriptor_enum_type(const PbwFieldDescriptor* field); 171 172 /* like FieldDescriptor::is_required() */ 173 gboolean 174 pbw_FieldDescriptor_is_required(const PbwFieldDescriptor* field); 175 176 /* like FieldDescriptor::has_default_value(). 177 * Does this field have an explicitly-declared default value? */ 178 gboolean 179 pbw_FieldDescriptor_has_default_value(const PbwFieldDescriptor* field); 180 181 /* like FieldDescriptor::default_value_int32() */ 182 gint32 183 pbw_FieldDescriptor_default_value_int32(const PbwFieldDescriptor* field); 184 185 /* like FieldDescriptor::default_value_int64() */ 186 gint64 187 pbw_FieldDescriptor_default_value_int64(const PbwFieldDescriptor* field); 188 189 /* like FieldDescriptor::default_value_uint32() */ 190 guint32 191 pbw_FieldDescriptor_default_value_uint32(const PbwFieldDescriptor* field); 192 193 /* like FieldDescriptor::default_value_uint64() */ 194 guint64 195 pbw_FieldDescriptor_default_value_uint64(const PbwFieldDescriptor* field); 196 197 /* like FieldDescriptor::default_value_float() */ 198 gfloat 199 pbw_FieldDescriptor_default_value_float(const PbwFieldDescriptor* field); 200 201 /* like FieldDescriptor::default_value_double() */ 202 gdouble 203 pbw_FieldDescriptor_default_value_double(const PbwFieldDescriptor* field); 204 205 /* like FieldDescriptor::default_value_bool() */ 206 gboolean 207 pbw_FieldDescriptor_default_value_bool(const PbwFieldDescriptor* field); 208 209 /* like FieldDescriptor::default_value_string() */ 210 const gchar* 211 pbw_FieldDescriptor_default_value_string(const PbwFieldDescriptor* field, int* size); 212 213 /* like FieldDescriptor::default_value_enum() */ 214 const PbwEnumValueDescriptor* 215 pbw_FieldDescriptor_default_value_enum(const PbwFieldDescriptor* field); 216 217 /* like EnumDescriptor::name() */ 218 const char* 219 pbw_EnumDescriptor_name(const PbwEnumDescriptor* anEnum); 220 221 /* like EnumDescriptor::full_name() */ 222 const char* 223 pbw_EnumDescriptor_full_name(const PbwEnumDescriptor* anEnum); 224 225 /* like EnumDescriptor::value_count() */ 226 int 227 pbw_EnumDescriptor_value_count(const PbwEnumDescriptor* anEnum); 228 229 /* like EnumDescriptor::value() */ 230 const PbwEnumValueDescriptor* 231 pbw_EnumDescriptor_value(const PbwEnumDescriptor* anEnum, int value_index); 232 233 /* like EnumDescriptor::FindValueByNumber() */ 234 const PbwEnumValueDescriptor* 235 pbw_EnumDescriptor_FindValueByNumber(const PbwEnumDescriptor* anEnum, int number); 236 237 /* like EnumDescriptor::FindValueByName() */ 238 const PbwEnumValueDescriptor* 239 pbw_EnumDescriptor_FindValueByName(const PbwEnumDescriptor* anEnum, const gchar* name); 240 241 /* like EnumValueDescriptor::name() */ 242 const char* 243 pbw_EnumValueDescriptor_name(const PbwEnumValueDescriptor* enumValue); 244 245 /* like EnumValueDescriptor::full_name() */ 246 const char* 247 pbw_EnumValueDescriptor_full_name(const PbwEnumValueDescriptor* enumValue); 248 249 /* like EnumValueDescriptor::number() */ 250 int 251 pbw_EnumValueDescriptor_number(const PbwEnumValueDescriptor* enumValue); 252 253 /* visit all messages of this pool */ 254 void 255 pbw_foreach_message(const PbwDescriptorPool* pool, void (*cb)(const PbwDescriptor* message, void* userdata), void* userdata); 256 257 #ifdef __cplusplus 258 } 259 #endif /* __cplusplus */ 260 261 #endif /* __PROTOBUF_HELPER_H__ */ 262 263 /* 264 * Editor modelines - https://www.wireshark.org/tools/modelines.html 265 * 266 * Local variables: 267 * c-basic-offset: 4 268 * tab-width: 8 269 * indent-tabs-mode: nil 270 * End: 271 * 272 * vi: set shiftwidth=4 tabstop=8 expandtab: 273 * :indentSize=4:tabSize=8:noTabs=true: 274 */ 275