/* packet-edonkey.c * Routines for edonkey dissection * Copyright 2003, Xuan Zhang * Copyright 2007, Stefano Picerno * Copyright 2008, Stefan Monhof * * eDonkey dissector based on protocol descriptions from mldonkey: * ftp://ftp.chatnfiles.com/gnu-mirror/savannah/files/mldonkey/docs/Edonkey-Overnet/edonkey-protocol.txt * ftp://ftp.chatnfiles.com/gnu-mirror/savannah/files/mldonkey/docs/Edonkey-Overnet/overnet-protocol.txt * * Kademlia dissector based on source code inspection of aMule 2.1.3 and eMule 0.48a * Modified and added on the basis of information and names from the eMule 0.50 source code * found at http://www.emule-project.net * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include #include #include #include "packet-edonkey.h" #include "packet-tcp.h" void proto_reg_handoff_edonkey(void); static dissector_handle_t edonkey_tcp_handle; static dissector_handle_t edonkey_udp_handle; static int proto_edonkey = -1; static int hf_edonkey_message = -1; static int hf_edonkey_protocol = -1; static int hf_edonkey_message_length = -1; static int hf_edonkey_message_type = -1; static int hf_edonkey_client_hash = -1; static int hf_edonkey_server_hash = -1; static int hf_edonkey_file_hash = -1; static int hf_edonkey_client_id = -1; static int hf_edonkey_metatag_namesize = -1; static int hf_edonkey_metatag_type = -1; static int hf_edonkey_metatag = -1; static int hf_edonkey_metatag_name = -1; static int hf_edonkey_metatag_id = -1; static int hf_edonkey_ip = -1; static int hf_edonkey_port = -1; static int hf_edonkey_hash = -1; static int hf_edonkey_part_count = -1; static int hf_edonkey_file_status = -1; static int hf_edonkey_directory = -1; static int hf_edonkey_string = -1; static int hf_edonkey_string_length = -1; static int hf_edonkey_fileinfo = -1; static int hf_edonkey_clientinfo = -1; static int hf_edonkey_serverinfo = -1; static int hf_emule_aich_partnum = -1; static int hf_emule_aich_root_hash = -1; static int hf_emule_aich_hash_entry = -1; static int hf_emule_aich_hash_id = -1; static int hf_emule_aich_hash = -1; static int hf_emule_multipacket_entry = -1; static int hf_emule_multipacket_opcode = -1; static int hf_emule_source_count = -1; static int hf_emule_zlib = -1; static int hf_emule_public_key = -1; static int hf_emule_signature = -1; static int hf_emule_sourceOBFU = -1; static int hf_overnet_peer = -1; static int hf_edonkey_unparsed_data_length = -1; static int hf_kademlia = -1; static int hf_kademlia_search_condition = -1; static int hf_kademlia_search_condition_argument_uint32 = -1; static int hf_kademlia_search_condition_argument_uint64 = -1; /* static int hf_kademlia_unparsed_data_length = -1; */ static int hf_kademlia_peer = -1; static int hf_kademlia_peer_id = -1; static int hf_kademlia_hash = -1; static int hf_kademlia_file_id = -1; static int hf_kademlia_keyword_hash = -1; static int hf_kademlia_recipients_id = -1; static int hf_kademlia_sender_id = -1; static int hf_kademlia_target_id = -1; static int hf_kademlia_distance = -1; static int hf_kademlia_version = -1; static int hf_kademlia_peertype = -1; static int hf_kademlia_tag_float = -1; static int hf_kademlia_tag_uint64 = -1; static int hf_kademlia_tag_uint32 = -1; static int hf_kademlia_tag_ipv4 = -1; static int hf_kademlia_tag_uint16 = -1; static int hf_kademlia_tag_uint8 = -1; static int hf_kademlia_tag_hash = -1; static int hf_kademlia_tag_bsob = -1; static int hf_kademlia_tag_string = -1; static int hf_kademlia_udp_port = -1; static int hf_kademlia_tcp_port = -1; static int hf_kademlia_ip = -1; static int hf_kademlia_tag_name = -1; static int hf_kademlia_tag_name_length = -1; static int hf_kademlia_tag_type = -1; static int hf_kademlia_request_type = -1; static int hf_kademlia_search_expression_type = -1; static int hf_kademlia_search_bool_op = -1; /* Generated from convert_proto_tree_add_text.pl */ static int hf_edonkey_list_size = -1; static int hf_edonkey_meta_tag_value_revision = -1; static int hf_edonkey_meta_tag_value_uint = -1; static int hf_edonkey_boolean_array_length = -1; static int hf_edonkey_blob_length = -1; static int hf_edonkey_kademlia_string = -1; static int hf_emule_public_key_length = -1; static int hf_emule_signature_length = -1; static int hf_edonkey_obfuscation_settings = -1; static int hf_edonkey_start_offset = -1; static int hf_edonkey_start_offset_64 = -1; static int hf_edonkey_end_offset = -1; static int hf_edonkey_end_offset_64 = -1; static int hf_edonkey_emule_file_length = -1; static int hf_edonkey_overnet_peer_type = -1; static int hf_edonkey_more_search_file_results = -1; static int hf_edonkey_file_size = -1; static int hf_edonkey_large_file_size = -1; static int hf_edonkey_number_of_users = -1; static int hf_edonkey_number_of_files = -1; static int hf_edonkey_message_data = -1; static int hf_edonkey_emule_version = -1; static int hf_edonkey_emule_queue_ranking = -1; static int hf_edonkey_emule_ident_state = -1; static int hf_edonkey_emule_rndchallenge = -1; static int hf_edonkey_emule_sig_ip_used = -1; static int hf_edonkey_packed_length = -1; static int hf_edonkey_compressed_message_data = -1; static int hf_edonkey_challenge = -1; static int hf_edonkey_max_number_of_users = -1; static int hf_edonkey_search_type = -1; static int hf_edonkey_search_range_min = -1; static int hf_edonkey_search_range_max = -1; static int hf_edonkey_kademlia_uload = -1; static int hf_edonkey_kademlia_start_position = -1; static int hf_edonkey_kademlia_filesize = -1; static int hf_edonkey_kademlia_restrictive = -1; static int hf_edonkey_broken_compressed_data = -1; static int hf_edonkey_search_limit = -1; static int hf_edonkey_search_limit_type = -1; static int hf_edonkey_search_ops = -1; static int hf_edonkey_user_hash_length = -1; static gint ett_kademlia_tag = -1; static gint ett_edonkey_listitem = -1; static gint ett_kademlia_search_expression = -1; static gint ett_edonkey = -1; static gint ett_edonkey_message = -1; static gint ett_edonkey_metatag = -1; static gint ett_edonkey_search = -1; static gint ett_edonkey_fileinfo = -1; static gint ett_edonkey_serverinfo = -1; static gint ett_edonkey_clientinfo = -1; static gint ett_emule_aichhash = -1; static gint ett_emule_multipacket = -1; static gint ett_emule_zlib = -1; static gint ett_overnet_peer = -1; static gint ett_emule_sourceOBFU = -1; static expert_field ei_kademlia_tag_type = EI_INIT; static expert_field ei_kademlia_search_expression_type = EI_INIT; #define EDONKEY_TCP_PORT_RANGE "4661-4663" /* Not IANA registered */ #define EDONKEY_UDP_PORT_RANGE "4665,4672" /* Not IANA registered */ /* desegmentation of eDonkey over TCP */ static gboolean edonkey_desegment = TRUE; static const value_string kademlia_msgs[] = { { KADEMLIA2_BOOTSTRAP_REQ ,"KADEMLIA2_BOOTSTRAP_REQ" }, { KADEMLIA2_BOOTSTRAP_RES ,"KADEMLIA2_BOOTSTRAP_RES" }, { KADEMLIA2_HELLO_REQ ,"KADEMLIA2_HELLO_REQ" }, { KADEMLIA2_HELLO_RES ,"KADEMLIA2_HELLO_RES" }, { KADEMLIA2_PUBLISH_KEY_REQ ,"KADEMLIA2_PUBLISH_KEY_REQ" }, { KADEMLIA2_PUBLISH_NOTES_REQ ,"KADEMLIA2_PUBLISH_NOTES_REQ" }, { KADEMLIA2_PUBLISH_RES ,"KADEMLIA2_PUBLISH_RES" }, { KADEMLIA2_PUBLISH_SOURCE_REQ ,"KADEMLIA2_PUBLISH_SOURCE_REQ" }, { KADEMLIA2_REQ ,"KADEMLIA2_REQ" }, { KADEMLIA2_RES ,"KADEMLIA2_RES" }, { KADEMLIA2_SEARCH_KEY_REQ ,"KADEMLIA2_SEARCH_KEY_REQ" }, { KADEMLIA2_SEARCH_NOTES_REQ ,"KADEMLIA2_SEARCH_NOTES_REQ" }, { KADEMLIA2_SEARCH_RES ,"KADEMLIA2_SEARCH_RES" }, { KADEMLIA2_SEARCH_SOURCE_REQ ,"KADEMLIA2_SEARCH_SOURCE_REQ" }, { KADEMLIA_BOOTSTRAP_REQ ,"KADEMLIA_BOOTSTRAP_REQ" }, { KADEMLIA_BOOTSTRAP_RES ,"KADEMLIA_BOOTSTRAP_RES" }, { KADEMLIA_CALLBACK_REQ ,"KADEMLIA_CALLBACK_REQ" }, { KADEMLIA_FINDBUDDY_REQ ,"KADEMLIA_FINDBUDDY_REQ" }, { KADEMLIA_FINDBUDDY_RES ,"KADEMLIA_FINDBUDDY_RES" }, { KADEMLIA_FIREWALLED_ACK_RES ,"KADEMLIA_FIREWALLED_ACK_RES" }, { KADEMLIA_FIREWALLED_REQ ,"KADEMLIA_FIREWALLED_REQ" }, { KADEMLIA_FIREWALLED_RES ,"KADEMLIA_FIREWALLED_RES" }, { KADEMLIA_HELLO_REQ ,"KADEMLIA_HELLO_REQ" }, { KADEMLIA_HELLO_RES ,"KADEMLIA_HELLO_RES" }, { KADEMLIA_PUBLISH_NOTES_REQ ,"KADEMLIA_PUBLISH_NOTES_REQ" }, { KADEMLIA_PUBLISH_NOTES_RES ,"KADEMLIA_PUBLISH_NOTES_RES" }, { KADEMLIA_PUBLISH_REQ ,"KADEMLIA_PUBLISH_REQ" }, { KADEMLIA_PUBLISH_RES ,"KADEMLIA_PUBLISH_RES" }, { KADEMLIA_REQ ,"KADEMLIA_REQ" }, { KADEMLIA_RES ,"KADEMLIA_RES" }, { KADEMLIA_SEARCH_NOTES_REQ ,"KADEMLIA_SEARCH_NOTES_REQ" }, { KADEMLIA_SEARCH_NOTES_RES ,"KADEMLIA_SEARCH_NOTES_RES" }, { KADEMLIA_SEARCH_REQ ,"KADEMLIA_SEARCH_REQ" }, { KADEMLIA_SEARCH_RES ,"KADEMLIA_SEARCH_RES" }, { 0, NULL } }; static const value_string kademlia_tag_types[] = { { KADEMLIA_TAGTYPE_HASH ,"TAGTYPE_HASH" }, { KADEMLIA_TAGTYPE_STRING ,"TAGTYPE_STRING" }, { KADEMLIA_TAGTYPE_UINT32 ,"TAGTYPE_UINT32" }, { KADEMLIA_TAGTYPE_FLOAT32 ,"TAGTYPE_FLOAT32" }, { KADEMLIA_TAGTYPE_BOOL ,"TAGTYPE_BOOL" }, { KADEMLIA_TAGTYPE_BOOLARRAY ,"TAGTYPE_BOOLARRAY" }, { KADEMLIA_TAGTYPE_BLOB ,"TAGTYPE_BLOB" }, { KADEMLIA_TAGTYPE_UINT16 ,"TAGTYPE_UINT16" }, { KADEMLIA_TAGTYPE_UINT8 ,"TAGTYPE_UINT8" }, { KADEMLIA_TAGTYPE_BSOB ,"TAGTYPE_BSOB" }, { KADEMLIA_TAGTYPE_UINT64 ,"TAGTYPE_UINT64" }, { KADEMLIA_TAGTYPE_STR1 ,"TAGTYPE_STR1" }, { KADEMLIA_TAGTYPE_STR2 ,"TAGTYPE_STR2" }, { KADEMLIA_TAGTYPE_STR3 ,"TAGTYPE_STR3" }, { KADEMLIA_TAGTYPE_STR4 ,"TAGTYPE_STR4" }, { KADEMLIA_TAGTYPE_STR5 ,"TAGTYPE_STR5" }, { KADEMLIA_TAGTYPE_STR6 ,"TAGTYPE_STR6" }, { KADEMLIA_TAGTYPE_STR7 ,"TAGTYPE_STR7" }, { KADEMLIA_TAGTYPE_STR8 ,"TAGTYPE_STR8" }, { KADEMLIA_TAGTYPE_STR9 ,"TAGTYPE_STR9" }, { KADEMLIA_TAGTYPE_STR10 ,"TAGTYPE_STR10" }, { KADEMLIA_TAGTYPE_STR11 ,"TAGTYPE_STR11" }, { KADEMLIA_TAGTYPE_STR12 ,"TAGTYPE_STR12" }, { KADEMLIA_TAGTYPE_STR13 ,"TAGTYPE_STR13" }, { KADEMLIA_TAGTYPE_STR14 ,"TAGTYPE_STR14" }, { KADEMLIA_TAGTYPE_STR15 ,"TAGTYPE_STR15" }, { KADEMLIA_TAGTYPE_STR16 ,"TAGTYPE_STR16" }, { KADEMLIA_TAGTYPE_STR17 ,"TAGTYPE_STR17" }, { KADEMLIA_TAGTYPE_STR18 ,"TAGTYPE_STR18" }, { KADEMLIA_TAGTYPE_STR19 ,"TAGTYPE_STR19" }, { KADEMLIA_TAGTYPE_STR20 ,"TAGTYPE_STR20" }, { KADEMLIA_TAGTYPE_STR21 ,"TAGTYPE_STR21" }, { KADEMLIA_TAGTYPE_STR22 ,"TAGTYPE_STR22" }, { 0, NULL } }; static const value_string kademlia_tags[] = { { KADEMLIA_TAG_BUDDYHASH ,"TAG_BUDDYHASH" }, { KADEMLIA_TAG_CLIENTLOWID ,"TAG_CLIENTLOWID" }, { KADEMLIA_TAG_COLLECTION ,"TAG_COLLECTION" }, { KADEMLIA_TAG_COPIED ,"TAG_COPIED" }, { KADEMLIA_TAG_DESCRIPTION ,"TAG_DESCRIPTION" }, { KADEMLIA_TAG_ENCRYPTION ,"TAG_ENCRYPTION" }, { KADEMLIA_TAG_FAIL ,"TAG_FAIL" }, { KADEMLIA_TAG_FILECOMMENT ,"TAG_FILECOMMENT" }, { KADEMLIA_TAG_FILE_COUNT ,"TAG_FILE_COUNT" }, { KADEMLIA_TAG_FILEFORMAT ,"TAG_FILEFORMAT" }, { KADEMLIA_TAG_FILENAME ,"TAG_FILENAME" }, { KADEMLIA_TAG_FILERATING ,"TAG_FILERATING" }, { KADEMLIA_TAG_FILESIZE_HI ,"TAG_FILESIZE_HI" }, { KADEMLIA_TAG_FILESIZE ,"TAG_FILESIZE" }, { KADEMLIA_TAG_FILETYPE ,"TAG_FILETYPE" }, { KADEMLIA_TAG_GAP_END ,"TAG_GAP_END" }, { KADEMLIA_TAG_GAP_START ,"TAG_GAP_START" }, { KADEMLIA_TAG_IP_ADDRESS ,"TAG_IP_ADDRESS" }, { KADEMLIA_TAG_MEDIA_ALBUM ,"TAG_MEDIA_ALBUM" }, { KADEMLIA_TAG_MEDIA_ARTIST ,"TAG_MEDIA_ARTIST" }, { KADEMLIA_TAG_MEDIA_BITRATE ,"TAG_MEDIA_BITRATE"}, { KADEMLIA_TAG_MEDIA_CODEC ,"TAG_MEDIA_CODEC" }, { KADEMLIA_TAG_MEDIA_LENGTH ,"TAG_MEDIA_LENGTH" }, { KADEMLIA_TAG_MEDIA_TITLE ,"TAG_MEDIA_TITLE" }, { KADEMLIA_TAG_PART_HASH ,"TAG_PART_HASH" }, { KADEMLIA_TAG_PART_PATH ,"TAG_PART_PATH" }, { KADEMLIA_TAG_PARTS ,"TAG_PARTS" }, { KADEMLIA_TAG_PERMISSIONS ,"TAG_PERMISSIONS" }, { KADEMLIA_TAG_PING ,"TAG_PING" }, { KADEMLIA_TAG_PORT ,"TAG_PORT" }, { KADEMLIA_TAG_PREFERENCE ,"TAG_PREFERENCE" }, { KADEMLIA_TAG_PRIORITY ,"TAG_PRIORITY" }, { KADEMLIA_TAG_QTIME ,"TAG_QTIME" }, { KADEMLIA_TAG_SERVERIP ,"TAG_SERVERIP" }, { KADEMLIA_TAG_SERVERPORT ,"TAG_SERVERPORT" }, { KADEMLIA_TAG_SOURCEIP ,"TAG_SOURCEIP" }, { KADEMLIA_TAG_SOURCEPORT ,"TAG_SOURCEPORT" }, { KADEMLIA_TAG_SOURCES ,"TAG_SOURCES" }, { KADEMLIA_TAG_SOURCETYPE ,"TAG_SOURCETYPE" }, { KADEMLIA_TAG_SOURCEUPORT ,"TAG_SOURCEUPORT" }, { KADEMLIA_TAG_STATUS ,"TAG_STATUS" }, { KADEMLIA_TAG_TEMPFILE ,"TAG_TEMPFILE" }, { KADEMLIA_TAG_USER_COUNT ,"TAG_USER_COUNT" }, { KADEMLIA_TAG_VERSION ,"TAG_VERSION" }, { 0, NULL } }; static const value_string edonkey_protocols[] = { { EDONKEY_PROTO_EDONKEY, "eDonkey" }, { EDONKEY_PROTO_EMULE_EXT, "eMule Extensions" }, { EDONKEY_PROTO_EMULE_COMP, "eMule Compressed" }, { EDONKEY_PROTO_KADEMLIA, "Kademlia" }, { EDONKEY_PROTO_KADEMLIA_COMP, "Kademlia Compressed" }, { EDONKEY_PROTO_ADU_KADEMLIA, "KAdu" }, { EDONKEY_PROTO_ADU_KADEMLIA_COMP, "KAdu Compressed" }, { 0, NULL } }; static const value_string edonkey_tcp_msgs[] = { { EDONKEY_MSG_HELLO, "Hello" }, { EDONKEY_MSG_BAD_PROTO, "Bad Proto" }, { EDONKEY_MSG_GET_SERVER_LIST, "Get Server List" }, { EDONKEY_MSG_OFFER_FILES, "Offer Files" }, { EDONKEY_MSG_SEARCH_FILES, "Search Files" }, { EDONKEY_MSG_DISCONNECT, "Disconnect" }, { EDONKEY_MSG_GET_SOURCES, "Get Sources" }, { EDONKEY_MSG_GET_SOURCES_OBFU, "Get Sources Obfuscation" }, { EDONKEY_MSG_SEARCH_USER, "Search User" }, { EDONKEY_MSG_CLIENT_CB_REQ, "Client Callback Request" }, { EDONKEY_MSG_MORE_RESULTS, "More Results" }, { EDONKEY_MSG_SERVER_LIST, "Server List" }, { EDONKEY_MSG_SEARCH_FILE_RESULTS, "Search File Results" }, { EDONKEY_MSG_SERVER_STATUS, "Server Status" }, { EDONKEY_MSG_SERVER_CB_REQ, "Server Callback Request" }, { EDONKEY_MSG_CALLBACK_FAIL, "Callback Fail" }, { EDONKEY_MSG_SERVER_MESSAGE, "Server Message" }, { EDONKEY_MSG_ID_CHANGE, "ID Change" }, { EDONKEY_MSG_SERVER_INFO_DATA, "Server Info Data" }, { EDONKEY_MSG_FOUND_SOURCES, "Found Sources" }, { EDONKEY_MSG_FOUND_SOURCES_OBFU, "Found Sources Obfuscation"}, { EDONKEY_MSG_SEARCH_USER_RESULTS, "Search User Results" }, { EDONKEY_MSG_SENDING_PART, "Sending Part" }, { EDONKEY_MSG_REQUEST_PARTS, "Request Parts" }, { EDONKEY_MSG_NO_SUCH_FILE, "No Such File" }, { EDONKEY_MSG_END_OF_DOWNLOAD, "End of Download" }, { EDONKEY_MSG_VIEW_FILES, "View Files" }, { EDONKEY_MSG_VIEW_FILES_ANSWER, "View Files Answer" }, { EDONKEY_MSG_HELLO_ANSWER, "Hello Answer" }, { EDONKEY_MSG_NEW_CLIENT_ID, "New Client ID" }, { EDONKEY_MSG_CLIENT_MESSAGE, "Client Message" }, { EDONKEY_MSG_FILE_STATUS_REQUEST, "File Status Request" }, { EDONKEY_MSG_FILE_STATUS, "File Status" }, { EDONKEY_MSG_HASHSET_REQUEST, "Hashset Request" }, { EDONKEY_MSG_HASHSET_ANSWER, "Hashset Answer" }, { EDONKEY_MSG_SLOT_REQUEST, "Slot Request" }, { EDONKEY_MSG_SLOT_GIVEN, "Slot Given" }, { EDONKEY_MSG_SLOT_RELEASE, "Slot Release" }, { EDONKEY_MSG_SLOT_TAKEN, "Slot Taken" }, { EDONKEY_MSG_FILE_REQUEST, "File Request" }, { EDONKEY_MSG_FILE_REQUEST_ANSWER, "File Request Answer" }, { EDONKEY_MSG_GET_SHARED_DIRS, "Get Shared Directories" }, { EDONKEY_MSG_GET_SHARED_FILES, "Get Shared Files" }, { EDONKEY_MSG_SHARED_DIRS, "Shared Directories" }, { EDONKEY_MSG_SHARED_FILES, "Shared Files" }, { EDONKEY_MSG_SHARED_DENIED, "Shared Denied" }, { 0, NULL } }; static const value_string emule_tcp_msgs[] = { { EMULE_MSG_HELLO, "Hello" }, { EMULE_MSG_HELLO_ANSWER, "Hello Answer" }, { EMULE_MSG_DATA_COMPRESSED, "Data Compressed" }, { EMULE_MSG_QUEUE_RANKING, "Queue Ranking" }, { EMULE_MSG_FILE_DESC, "File Description" }, { EMULE_MSG_SOURCES_REQUEST, "Sources Request" }, { EMULE_MSG_SOURCES_ANSWER, "Sources Answer" }, { EMULE_MSG_SIGNATURE, "Signature" }, { EMULE_MSG_PUBLIC_KEY, "Public Key" }, { EMULE_MSG_SEC_IDENT_STATE, "Second Identification State" }, { EMULE_MSG_MULTIPACKET, "MultiPacket" }, { EMULE_MSG_MULTIPACKET_EXT, "MultiPacketExt" }, { EMULE_MSG_MULTIPACKET_ANSWER, "MultiPacket Answer" }, { EMULE_MSG_CALLBACK, "Callback" }, { EMULE_MSG_AICH_REQUEST, "AICH Hashset Request" }, { EMULE_MSG_AICH_ANSWER, "AICH Hashset Answer" }, { EMULE_MSG_AICHFILEHASH_ANSWER, "AICH Master Hash Request" }, { EMULE_MSG_AICHFILEHASH_REQUEST, "AICH Master Hash Answer" }, { EMULE_MSG_DATA_COMPRESSED_64, "Data Compressed (64bit)" }, { EMULE_MSG_SENDING_PART_64, "Sending Part (64bit)" }, { EMULE_MSG_REQUEST_PARTS_64, "Request Parts (64bit)" }, { 0, NULL } }; static const value_string edonkey_udp_msgs[] = { { EDONKEY_MSG_UDP_SERVER_STATUS_REQUEST, "Server Status Request" }, { EDONKEY_MSG_UDP_SERVER_STATUS, "Server Status" }, { EDONKEY_MSG_UDP_SEARCH_FILE, "Search File" }, { EDONKEY_MSG_UDP_SEARCH_FILE_RESULTS, "Search File Results" }, { EDONKEY_MSG_UDP_GET_SOURCES, "Get Sources" }, { EDONKEY_MSG_UDP_FOUND_SOURCES, "Found Sources" }, { EDONKEY_MSG_UDP_CALLBACK_REQUEST, "Callback Request" }, { EDONKEY_MSG_UDP_CALLBACK_FAIL, "Callback Fail" }, { EDONKEY_MSG_UDP_SERVER_LIST, "Server List" }, { EDONKEY_MSG_UDP_GET_SERVER_INFO, "Get Server Info" }, { EDONKEY_MSG_UDP_SERVER_INFO, "Server Info" }, { EDONKEY_MSG_UDP_GET_SERVER_LIST, "Get Server List" }, /* eMule Extensions */ { EMULE_MSG_UDP_REASKFILEPING, "Reask File Ping" }, { EMULE_MSG_UDP_REASKACK, "Reask ACK" }, { EMULE_MSG_UDP_FILE_NOT_FOUND, "File not found" }, { EMULE_MSG_UDP_QUEUE_FULL, "Queue Full" }, /* Overnet Extensions */ { OVERNET_MSG_UDP_CONNECT, "Connect" }, { OVERNET_MSG_UDP_CONNECT_REPLY, "Connect Reply" }, { OVERNET_MSG_UDP_PUBLICIZE, "Publicize" }, { OVERNET_MSG_UDP_PUBLICIZE_ACK, "Publicize ACK" }, { OVERNET_MSG_UDP_SEARCH, "Search" }, { OVERNET_MSG_UDP_SEARCH_NEXT, "Search Next" }, { OVERNET_MSG_UDP_SEARCH_INFO, "Search Info" }, { OVERNET_MSG_UDP_SEARCH_RESULT, "Search Result" }, { OVERNET_MSG_UDP_SEARCH_END, "Search End" }, { OVERNET_MSG_UDP_PUBLISH, "Publish" }, { OVERNET_MSG_UDP_PUBLISH_ACK, "Publish ACK" }, { OVERNET_MSG_UDP_IDENTIFY_REPLY, "Identify Reply" }, { OVERNET_MSG_UDP_IDENTIFY_ACK, "Identify ACK" }, { OVERNET_MSG_UDP_FIREWALL_CONNECTION, "Firewall Connection" }, { OVERNET_MSG_UDP_FIREWALL_CONNECTION_ACK, "Firewall Connection ACK" }, { OVERNET_MSG_UDP_FIREWALL_CONNECTION_NACK, "Firewall Connection NACK" }, { OVERNET_MSG_UDP_IP_QUERY, "IP Query" }, { OVERNET_MSG_UDP_IP_QUERY_ANSWER, "IP Query Answer" }, { OVERNET_MSG_UDP_IP_QUERY_END, "IP Query End" }, { OVERNET_MSG_UDP_IDENTIFY, "Identify" }, { 0, NULL } }; static const value_string edonkey_special_tags[] = { { EDONKEY_STAG_NAME, "Name" }, { EDONKEY_STAG_SIZE, "Size" }, { EDONKEY_STAG_TYPE, "Type" }, { EDONKEY_STAG_FORMAT, "Format" }, { EDONKEY_STAG_COLLECTION, "Collection" }, { EDONKEY_STAG_PART_PATH, "Part Path" }, { EDONKEY_STAG_PART_HASH, "Part Hash" }, { EDONKEY_STAG_COPIED, "Copied" }, { EDONKEY_STAG_GAP_START, "Gap Start" }, { EDONKEY_STAG_GAP_END, "Gap End" }, { EDONKEY_STAG_DESCRIPTION, "Description" }, { EDONKEY_STAG_PING, "Ping" }, { EDONKEY_STAG_FAIL, "Fail" }, { EDONKEY_STAG_PREFERENCE, "Preference" }, { EDONKEY_STAG_PORT, "Port" }, { EDONKEY_STAG_IP, "IP" }, { EDONKEY_STAG_VERSION, "Version" }, { EDONKEY_STAG_TEMPFILE, "Temporary File" }, { EDONKEY_STAG_PRIORITY, "Priority" }, { EDONKEY_STAG_STATUS, "Status" }, { EDONKEY_STAG_AVAILABILITY, "Availability" }, { EDONKEY_STAG_QTIME, "Queue Time" }, { EDONKEY_STAG_PARTS, "Parts" }, { EDONKEY_STAG_MOD_VERSION, "Mod Version" }, { EMULE_STAG_COMPRESSION, "Compression" }, { EMULE_STAG_UDP_CLIENT_PORT, "UDP Client Port" }, { EMULE_STAG_UDP_VERSION, "UDP Version" }, { EMULE_STAG_SOURCE_EXCHANGE, "Source Exchange" }, { EMULE_STAG_COMMENTS, "Comments" }, { EMULE_STAG_EXTENDED_REQUEST, "Extended Request" }, { EMULE_STAG_COMPATIBLE_CLIENT, "Compatible Client" }, { EMULE_STAG_COMPLETE_SOURCES, "Complete Sources" }, { EMULE_STAG_SIZE_HI, "Size (High Byte)" }, { EMULE_STAG_SERVER_VERSION, "Server Version" }, { EMULE_STAG_COMPAT_OPTIONS1, "Compatible Options" }, { EMULE_STAG_UDPPORTS, "UDP Ports" }, { EMULE_STAG_MISCOPTIONS1, "Misc Options 1" }, { EMULE_STAG_VERSION, "eMule Version" }, { EMULE_STAG_BUDDYIP, "Buddy IP" }, { EMULE_STAG_BUDDYUDP, "Buddy UDP" }, { EMULE_STAG_MISCOPTIONS2, "Misc Options 2" }, { 0, NULL } }; static const value_string edonkey_search_type_vals[] = { { EDONKEY_SEARCH_BOOL, "Boolean" }, { EDONKEY_SEARCH_NAME, "Name" }, { EDONKEY_SEARCH_META, "Metadata" }, { EDONKEY_SEARCH_LIMIT, "Limit" }, { 0, NULL } }; static const value_string edonkey_search_ext_type_vals[] = { { 0, "BoolOp" }, { 1, "String" }, { 2, "MetaTag" }, { 3, "32bitOp" }, { 4, "64bitOp" }, { 0, NULL } }; static const value_string edonkey_search_ops[] = { { EDONKEY_SEARCH_AND, "AND" }, { EDONKEY_SEARCH_OR, "OR" }, { EDONKEY_SEARCH_ANDNOT, "AND NOT" }, { 0, NULL } }; static const value_string edonkey_search_conds[] = { { EDONKEY_SEARCH_MIN, "MIN" }, { EDONKEY_SEARCH_MAX, "MAX" }, { 0, NULL } }; static const value_string kademlia_search_conds[] = { { 0, "=" }, { 1, ">" }, { 2, "<" }, { 3, ">=" }, { 4, "<=" }, { 5, "<>" }, { 0, NULL } }; static const value_string kademlia_versions[] = { { KADEMLIA_VERSION1_46c, " (eMule <= 0.46c or compatibles)" }, { KADEMLIA_VERSION2_47a, " (eMule 0.47a or compatibles)" }, { KADEMLIA_VERSION3_47b, " (eMule 0.47b or compatibles)" }, { KADEMLIA_VERSION5_48a, " (eMule 0.48a or compatibles)" }, { KADEMLIA_VERSION6_49aBETA, " (eMule 0.49aBETA1 or compatibles)" }, { KADEMLIA_VERSION7_49a, " (eMule 0.49a or compatibles)" }, { 0, NULL } }; static const value_string kademlia_parameter[] = { { KADEMLIA_FIND_VALUE, " (Find Value)" }, { KADEMLIA_STORE, " (Store)" }, { KADEMLIA_FIND_NODE, " (Find Node)" }, { 0, NULL } }; static const value_string kademlia_tag_sourcetype[] = { { 1, "HighID Source" }, { 3, "Firewalled Kad Source" }, { 4, ">4GB file HighID Source" }, { 5, ">4GB file Firewalled Kad Source" }, { 6, "Firewalled Source with Direct Callback (supports >4GB)" }, { 0, NULL } }; static const value_string kademlia_tag_encryption[] = { { 1, "Supports Crypt Layer" }, { 2, "Requests Crypt Layer" }, { 3, "Supports & Requests Crypt Layer" }, { 4, "Requires Crypt Layer" }, { 5, "Supports & Requires Crypt Layer" }, { 6, "Requests & Requires Crypt Layer" }, { 7, "Supports, Requests & Requires Crypt Layer" }, { 8, "Direct UDP Callback" }, { 9, "Supports Crypt Layer; Direct UDP Callback" }, { 10, "Requests Crypt Layer; Direct UDP Callback" }, { 11, "Supports & Requests Crypt Layer; Direct UDP Callback" }, { 12, "Requires Crypt Layer; Direct UDP Callback" }, { 13, "Supports & Requires Crypt Layer; Direct UDP Callback" }, { 14, "Requests & Requires Crypt Layer; Direct UDP Callback" }, { 15, "Supports, Requests & Requires Crypt Layer; Direct UDP Callback" }, { 0, NULL } }; static const range_string emule_ident_state_rvals[] = { { 0, 0, "nothing is needed" }, { 1, 1, "signature is needed" }, { 2, 255, "public key and signature are needed" }, { 0, 0, NULL } }; /* Dissects a generic eDonkey list */ static int dissect_edonkey_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, int listnum_length, const char* listdesc, int (*item_dissector)(tvbuff_t *, packet_info *, int, proto_tree *)) { /* ::= * */ guint32 listnum, i; proto_tree *subtree; proto_item* ti; proto_item* list_ti; int list_start_offset; list_start_offset = offset; switch (listnum_length) { case -1: case 1: listnum = tvb_get_guint8(tvb, offset); break; case -2: listnum = tvb_get_ntohs(tvb, offset); break; case 2: listnum = tvb_get_letohs(tvb, offset); break; case 4: listnum = tvb_get_letohl(tvb, offset); break; case -4: listnum = tvb_get_ntohl(tvb, offset); break; default: /* Not Supported */ return offset; } if (listnum_length < 0) listnum_length = -listnum_length; /* keep the tree item object, its length will be set at the end of the function */ list_ti = proto_tree_add_uint_format(tree, hf_edonkey_list_size, tvb, offset, listnum_length, listnum, "%s List Size: %u", listdesc, listnum); offset+= listnum_length; for (i=0; i 1 means "string"? Something else? */ tag_name = try_val_to_str(special_tagtype, edonkey_special_tags); if (tag_name == NULL) { return proto_tree_add_item(tree, hf_edonkey_metatag_name, tvb, start, length, ENC_ASCII); } else { return proto_tree_add_uint_format(tree, hf_edonkey_metatag_id, tvb, start, length, special_tagtype, "Meta Tag Name: %s (0x%02x)", tag_name, special_tagtype); } } static int dissect_kademlia_search_condition_argument_uint64(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item( tree, hf_kademlia_search_condition_argument_uint64, tvb, offset, 8, ENC_LITTLE_ENDIAN ); return offset + 8; } static int dissect_kademlia_search_condition_argument_uint32(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item( tree, hf_kademlia_search_condition_argument_uint32, tvb, offset, 4, ENC_LITTLE_ENDIAN ); return offset + 4; } static int dissect_kademlia_search_condition(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree ) { proto_item * ti; guint16 value = tvb_get_guint8(tvb, offset); ti = proto_tree_add_item( tree, hf_kademlia_search_condition, tvb, offset, 1, ENC_BIG_ENDIAN ); proto_item_append_text(ti, " [%s]", val_to_str_const( value, kademlia_search_conds, "Unknown") ); return offset + 1; } /* Dissects the eDonkey meta tag */ static int dissect_edonkey_metatag(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= */ /* ::= || */ /* ::= iff Tag Type had the top bit set */ proto_item *ti; proto_tree *metatag_tree; guint8 real_tag_type, tag_type, special_tagtype, trans_tagtype; guint16 tag_name_size, string_length, array_length; guint32 tag_length, blob_length; int tag_offset; real_tag_type = tag_type = tvb_get_guint8(tvb, offset); if (tag_type & EDONKEY_MTAG_SHORTNAME) { real_tag_type &= ~EDONKEY_MTAG_SHORTNAME; tag_name_size = 1; special_tagtype = tvb_get_guint8(tvb, offset+1); tag_length = 2; } else { tag_name_size = tvb_get_letohs(tvb, offset+1); special_tagtype = tvb_get_guint8(tvb, offset+3); tag_length = 3 + tag_name_size; } tag_offset = offset + tag_length; switch (real_tag_type) { case EDONKEY_MTAG_HASH: /* ::= HASH */ tag_length += 16; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_hash, tvb, tag_offset, 16, ENC_NA); break; case EDONKEY_MTAG_STRING: /* ::= */ string_length = tvb_get_letohs(tvb, tag_offset); tag_length += 2+string_length; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_uint(metatag_tree, hf_edonkey_string_length, tvb, tag_offset, 2, string_length); proto_tree_add_item(metatag_tree, hf_edonkey_string, tvb, tag_offset+2, string_length, ENC_ASCII); break; case EDONKEY_MTAG_DWORD: /* ::= guint32 */ tag_length += 4; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); trans_tagtype = edonkey_metatag_name_get_type(tvb, offset+3, tag_name_size, special_tagtype); if (trans_tagtype == EDONKEY_STAG_IP) { proto_tree_add_item(metatag_tree, hf_edonkey_ip, tvb, tag_offset, 4, ENC_BIG_ENDIAN); } else if (trans_tagtype == EMULE_STAG_SERVER_VERSION) { proto_tree_add_item(metatag_tree, hf_edonkey_meta_tag_value_revision, tvb, tag_offset, 4, ENC_LITTLE_ENDIAN); } else { proto_tree_add_item(metatag_tree, hf_edonkey_meta_tag_value_uint, tvb, tag_offset, 4, ENC_LITTLE_ENDIAN); } break; case EDONKEY_MTAG_FLOAT: /* ::= 4 byte float */ tag_length += 4; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); break; case EDONKEY_MTAG_WORD: /* ::= guint16 */ tag_length += 2; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_meta_tag_value_uint, tvb, tag_offset, 2, ENC_LITTLE_ENDIAN); break; case EDONKEY_MTAG_BYTE: /* ::= guint8 */ tag_length += 1; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_meta_tag_value_uint, tvb, tag_offset, 1, ENC_NA); break; case EDONKEY_MTAG_BOOL: /* ::= */ tag_length += 1; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_meta_tag_value_uint, tvb, tag_offset, 1, ENC_NA); break; case EDONKEY_MTAG_BOOL_ARRAY: /* ::= */ array_length = tvb_get_letohs(tvb, tag_offset); /* * This is allegedly what the protocol uses, rather than the * correct value of (array_length+7)/8 * Therefore an extra unused byte is transmitted if the array * is a multiple of 8 longs. */ tag_length += 2+(array_length/8)+1; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_boolean_array_length, tvb, tag_offset, 2, ENC_LITTLE_ENDIAN); break; case EDONKEY_MTAG_BLOB: /* ::= */ blob_length = tvb_get_letohl(tvb, tag_offset); tag_length += 4+blob_length; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (tag_type==real_tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_blob_length, tvb, tag_offset, 2, ENC_LITTLE_ENDIAN); break; case EDONKEY_MTAG_BSOB: /* This is possibly a Binary Small OBject, like a BLOB but with an 8 or 16-bit length field */ /* That's a complete guess though, so don't handle it yet. */ case EDONKEY_MTAG_UNKNOWN: default: if (real_tag_type>=EDONKEY_MTAG_STR1 && real_tag_type<=EDONKEY_MTAG_STR16) { /* ::= */ string_length = real_tag_type-EDONKEY_MTAG_STR1+1; tag_length += string_length; ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type); if (real_tag_type==tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); proto_tree_add_item(metatag_tree, hf_edonkey_string, tvb, tag_offset, string_length, ENC_ASCII); } else { /* Unknown tag type - actual tag length is also unknown */ ti = proto_tree_add_item(tree, hf_edonkey_metatag, tvb, offset, tag_length, ENC_NA); metatag_tree = proto_item_add_subtree(ti, ett_edonkey_metatag); proto_tree_add_uint_format(metatag_tree, hf_edonkey_metatag_type, tvb, offset, 1, tag_type, "Unknown Meta Tag Type (0x%02x)", tag_type); if (real_tag_type==tag_type) proto_tree_add_uint(metatag_tree, hf_edonkey_metatag_namesize, tvb, offset+1, 2, tag_name_size); edonkey_tree_add_metatag_name(metatag_tree, tvb, tag_offset-tag_name_size, tag_name_size, special_tagtype); } break; } return offset + tag_length; } /* Dissects the eDonkey address */ static int dissect_edonkey_address(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /*
::= */ /* guint32 ip = tvb_get_letohl(tvb, offset); proto_tree_add_ipv4(tree, hf_edonkey_ip, tvb, offset, 4, ip); */ proto_tree_add_item(tree, hf_edonkey_ip, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_edonkey_port, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); return offset+6; } static int dissect_kademlia_udp_port(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_kademlia_udp_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); return offset +2; } static int dissect_kademlia_tcp_port(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_kademlia_tcp_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); return offset +2; } static int dissect_kademlia_ip_address(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_kademlia_ip, tvb, offset, 4, ENC_LITTLE_ENDIAN); return offset + 4; } static int dissect_kademlia_address(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /*
::= */ offset = dissect_kademlia_ip_address( tvb, pinfo, offset, tree ); offset = dissect_kademlia_udp_port( tvb, pinfo, offset, tree ); offset = dissect_kademlia_tcp_port( tvb, pinfo, offset, tree ); return offset; } static int dissect_kademlia_tagname(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, const gchar** outputTagName, const gchar** outputExtendedTagName) { /* ::= DATA */ const gchar * tagname; const gchar * tag_full_name = NULL; guint8 tagname_value; proto_item *ti, *hidden_item; guint16 string_length = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_kademlia_tag_name_length, tvb, offset, 2, string_length); hidden_item = proto_tree_add_uint(tree, hf_edonkey_string_length, tvb, offset, 2, string_length); proto_item_set_hidden(hidden_item); tagname = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 2, string_length, ENC_ASCII|ENC_NA); tag_full_name = "UnknownTagName"; if ( tagname && string_length == 1 ) { tagname_value = *(const guint8*)tagname; /* lookup tagname */ tag_full_name = val_to_str_const( tagname_value, kademlia_tags, tag_full_name ); } ti = proto_tree_add_item(tree, hf_kademlia_tag_name, tvb, offset + 2, string_length, ENC_BIG_ENDIAN); proto_item_append_text(ti, " [%s]", tag_full_name); if (outputTagName) *outputTagName = tagname; if (outputExtendedTagName) *outputExtendedTagName = tag_full_name; return offset+2+string_length; } static int dissect_kademlia_string(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= DATA */ guint16 string_length = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_edonkey_string_length, tvb, offset, 2, string_length); /* TODO: ASCII or UTF-8? */ proto_tree_add_item(tree, hf_edonkey_kademlia_string, tvb, offset+2, string_length, ENC_ASCII); return offset+2+string_length; } /* Dissects the eDonkey address list */ static int dissect_edonkey_address_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /*
::=
* */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Address", dissect_edonkey_address); } /* Dissects the eDonkey hash */ static int dissect_edonkey_hash(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= HASH (16 word MD4 digest) */ proto_tree_add_item(tree, hf_edonkey_hash, tvb, offset, 16, ENC_NA); return offset+16; } /* Dissects the eDonkey file hash */ static int dissect_edonkey_file_hash(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= HASH (16 word MD4 digest) */ proto_tree_add_item(tree, hf_edonkey_file_hash, tvb, offset, 16, ENC_NA); return offset+16; } /* Dissects the eMule public key */ static int dissect_edonkey_public_key(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { guint8 length = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_emule_public_key_length, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(tree, hf_emule_public_key, tvb, offset, length, ENC_NA); return offset + length; } /* Dissects the eMule signature */ static int dissect_edonkey_signature(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { guint8 length = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_emule_signature_length, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(tree, hf_emule_signature, tvb, offset, length, ENC_NA); return offset + length; } static const char *kademlia_hash(tvbuff_t *tvb, int offset) { guint32 hash[4]; int i; for (i = 0; i < 4; i++) hash[i] = tvb_get_letohl(tvb, offset + i*4); return wmem_strdup_printf(wmem_packet_scope(), "%08X%08X%08X%08X", hash[0], hash[1], hash[2], hash[3]); } static int dissect_kademlia_hash_hidden(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_item *hidden_item; const char *hash; hash = kademlia_hash(tvb, offset); /* ::= HASH (16 word MD4 digest) */ hidden_item = proto_tree_add_string(tree, hf_kademlia_hash, tvb, offset, 16, hash); proto_item_set_hidden(hidden_item); return offset+16; } /* Dissects the Kademlia hash*/ static int dissect_kademlia_hash(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, int *value_ptr) { const char *hash; hash = kademlia_hash(tvb, offset); /* ::= HASH (16 word MD4 digest) */ proto_tree_add_string(tree, *value_ptr, tvb, offset, 16, hash); return dissect_kademlia_hash_hidden(tvb, pinfo, offset, tree); } static int dissect_kademlia_tag_hash_hidden(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_item *hidden_item; const char *hash; hash = kademlia_hash(tvb, offset); /* ::= HASH (16 word MD4 digest) */ hidden_item = proto_tree_add_string(tree, hf_kademlia_tag_hash, tvb, offset, 16, hash); proto_item_set_hidden(hidden_item); return offset+16; } static int dissect_kademlia_tag_hash(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { const char *hash; hash = kademlia_hash(tvb, offset); /* ::= HASH (16 word MD4 digest) */ proto_tree_add_string(tree, hf_kademlia_hash, tvb, offset, 16, hash); return dissect_kademlia_tag_hash_hidden( tvb, pinfo, offset, tree ); } static int dissect_kademlia_tag_bsob(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, const gchar** string_value ) { guint16 bsob_length; bsob_length = tvb_get_guint8(tvb, offset); *string_value = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset + 1, bsob_length ); proto_tree_add_item(tree, hf_kademlia_tag_bsob, tvb, offset + 1, bsob_length, ENC_NA); return offset + 1 + bsob_length; } static int dissect_kademlia_tag_string(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, const guint8** string_value) { proto_item *hidden_item; guint16 string_length = tvb_get_letohs(tvb, offset); hidden_item = proto_tree_add_uint(tree, hf_edonkey_string_length, tvb, offset, 2, string_length); proto_item_set_hidden(hidden_item); hidden_item = proto_tree_add_item_ret_string(tree, hf_edonkey_string, tvb, offset + 2, string_length, ENC_ASCII|ENC_NA, wmem_packet_scope(), string_value); proto_item_set_hidden(hidden_item); proto_tree_add_item(tree, hf_kademlia_tag_string, tvb, offset + 2, string_length, ENC_ASCII); return offset + 2 + string_length; } /* Dissects the eDonkey hash list */ static int dissect_edonkey_hash_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= * */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); return dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Hash", dissect_edonkey_hash); } /* Dissects the eDonkey meta tag list */ static int dissect_edonkey_metatag_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= * */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 4, "Meta Tag", dissect_edonkey_metatag); } /* Dissects the eDonkey String */ static int dissect_edonkey_string(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= DATA */ guint16 string_length = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_edonkey_string_length, tvb, offset, 2, string_length); proto_tree_add_item(tree, hf_edonkey_string, tvb, offset+2, string_length, ENC_ASCII); return offset+2+string_length; } /* Dissects the eDonkey Directory */ static int dissect_edonkey_directory(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= */ guint16 string_length = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_edonkey_string_length, tvb, offset, 2, string_length); proto_tree_add_item(tree, hf_edonkey_directory, tvb, offset+2, string_length, ENC_ASCII); return offset+2+string_length; } /* Dissects the eDonkey Filename */ static int dissect_edonkey_file_name(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= */ return dissect_edonkey_string(tvb, pinfo, offset, tree); } /* Dissects the eDonkey File Status */ static int dissect_edonkey_file_status(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { guint16 partcount, arrlen; /* ::= */ partcount = tvb_get_letohs(tvb, offset); arrlen = (partcount+7)/8; proto_tree_add_uint(tree, hf_edonkey_part_count, tvb, offset, 2, partcount); if (partcount>0) { proto_tree_add_item(tree, hf_edonkey_file_status, tvb, offset+2, arrlen, ENC_NA); } return offset+2+arrlen; } /* Dissects the eDonkey directory list */ static int dissect_edonkey_directory_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= * */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 4, "Directory", dissect_edonkey_directory); } /* Dissects the eDonkey server hash */ static int dissect_edonkey_server_hash(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= HASH (16 word MD4 digest) */ proto_tree_add_item(tree, hf_edonkey_server_hash, tvb, offset, 16, ENC_NA); return offset+16; } /* Dissects the eDonkey client hash */ static int dissect_edonkey_client_hash(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= HASH (16 word MD4 digest) */ proto_tree_add_item(tree, hf_edonkey_client_hash, tvb, offset, 16, ENC_NA); return offset+16; } /* Dissects the eMule sourceOBFU */ static int dissect_emule_sourceOBFU(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { proto_item *ti; proto_tree *sourceOBFU_tree; guint8 settings = tvb_get_guint8(tvb, offset+6); /* Add subtree for client info */ ti = proto_tree_add_item(tree, hf_emule_sourceOBFU, tvb, offset, 7 + ((settings & 0x80) ? 16 : 0), ENC_NA); sourceOBFU_tree = proto_item_add_subtree(ti, ett_emule_sourceOBFU); proto_tree_add_item(sourceOBFU_tree, hf_edonkey_ip, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(sourceOBFU_tree, hf_edonkey_port, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(sourceOBFU_tree, hf_edonkey_obfuscation_settings, tvb, offset+6, 1, ENC_NA); offset += 7; if (settings & 0x80) offset = dissect_edonkey_client_hash(tvb, pinfo, offset, sourceOBFU_tree); return offset; } /* Dissects the eMule sourceOBFU list */ static int dissect_emule_sourceOBFU_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Sources Obfuscation", dissect_emule_sourceOBFU); } /* Dissects the eDonkey client ID */ static int dissect_edonkey_client_id(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree, gboolean fileinfo) { proto_item *ti; /* ::= guint32 */ /* guint32 ip = tvb_get_letohl(tvb, offset); proto_tree_add_ipv4(tree, hf_edonkey_client_id, tvb, offset, 4, ip); */ ti = proto_tree_add_item(tree, hf_edonkey_client_id, tvb, offset, 4, ENC_BIG_ENDIAN); if (fileinfo) { guint32 ip = tvb_get_letohl(tvb, offset); guint16 port = tvb_get_letohs(tvb, offset+4); if (ip==0xfcfcfcfc && port==0xfcfc) { proto_item_append_text(ti, " (myself, incomplete file)"); } else if (ip==0xfbfbfbfb && port==0xfbfb) { proto_item_append_text(ti, " (myself, complete file)"); } } return offset+4; } /* Dissects the eDonkey port */ static int dissect_edonkey_port(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= guint16 */ proto_tree_add_item(tree, hf_edonkey_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); return offset+2; } /* Dissects the eDonkey start offset */ static int dissect_edonkey_start_offset(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= guint32 */ proto_tree_add_item(tree, hf_edonkey_start_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); return offset+4; } static int dissect_edonkey_start_offset_64(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= guint64 */ proto_tree_add_item(tree, hf_edonkey_start_offset_64, tvb, offset, 8, ENC_LITTLE_ENDIAN); return offset+8; } /* Dissects the eDonkey end offset */ static int dissect_edonkey_end_offset(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= guint32 */ proto_tree_add_item(tree, hf_edonkey_end_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); return offset+4; } static int dissect_edonkey_end_offset_64(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= guint64 */ proto_tree_add_item(tree, hf_edonkey_end_offset_64, tvb, offset, 8, ENC_LITTLE_ENDIAN); return offset+8; } /* Dissects the eDonkey client info */ static int dissect_edonkey_client_info(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= */ proto_item *ti; proto_tree *clientinfo_tree; /* Add subtree for client info */ ti = proto_tree_add_item(tree, hf_edonkey_clientinfo, tvb, offset, 0, ENC_NA); clientinfo_tree = proto_item_add_subtree(ti, ett_edonkey_clientinfo); offset = dissect_edonkey_client_hash(tvb, pinfo, offset, clientinfo_tree); offset = dissect_edonkey_client_id(tvb, pinfo, offset, clientinfo_tree, FALSE); offset = dissect_edonkey_port(tvb, pinfo, offset, clientinfo_tree); offset = dissect_edonkey_metatag_list(tvb, pinfo, offset, clientinfo_tree); return offset; } /* Dissects the eDonkey client info list */ static int dissect_edonkey_client_info_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= * */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 4, "Client Info", dissect_edonkey_client_info); } /* Dissects the eDonkey server info */ static int dissect_edonkey_server_info(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= */ proto_item *ti; proto_tree *serverinfo_tree; /* Add subtree for server info */ ti = proto_tree_add_item(tree, hf_edonkey_serverinfo, tvb, offset, 0, ENC_NA); serverinfo_tree = proto_item_add_subtree(ti, ett_edonkey_serverinfo); offset = dissect_edonkey_server_hash(tvb, pinfo, offset, serverinfo_tree); offset = dissect_edonkey_address(tvb, pinfo, offset, serverinfo_tree); offset = dissect_edonkey_metatag_list(tvb, pinfo, offset, serverinfo_tree); return offset; } /* Dissects the eDonkey file info */ static int dissect_edonkey_file_info(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= */ proto_item *ti; proto_tree *fileinfo_tree; int startoff; /* Add subtree for file info */ ti = proto_tree_add_item(tree, hf_edonkey_fileinfo, tvb, offset, 0, ENC_NA); startoff = offset; fileinfo_tree = proto_item_add_subtree(ti, ett_edonkey_fileinfo); offset = dissect_edonkey_file_hash(tvb, pinfo, offset, fileinfo_tree); offset = dissect_edonkey_client_id(tvb, pinfo, offset, fileinfo_tree, TRUE); offset = dissect_edonkey_port(tvb, pinfo, offset, fileinfo_tree); offset = dissect_edonkey_metatag_list(tvb, pinfo, offset, fileinfo_tree); proto_item_set_len(ti, offset-startoff); return offset; } /* Dissects the eDonkey file info list */ static int dissect_edonkey_file_info_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= * */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 4, "File Info", dissect_edonkey_file_info); } /* Dissects the eMule address list */ static int dissect_emule_address_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /*
::=
* */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Address", dissect_edonkey_address); } static int dissect_emule_aich_root_hash(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= HASH (20 byte SHA1 digest) */ proto_tree_add_item(tree, hf_emule_aich_root_hash, tvb, offset, 20, ENC_NA); return offset + 20; } static int dissect_emule_aich_hash_list_entry(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { guint16 hashid; proto_item *ti; proto_tree *aichhash_tree; /* ::= */ ti = proto_tree_add_item(tree, hf_emule_aich_hash_entry, tvb, offset, 22, ENC_NA); aichhash_tree = proto_item_add_subtree(ti, ett_emule_aichhash); hashid = tvb_get_letohs(tvb, offset); proto_tree_add_uint(aichhash_tree, hf_emule_aich_hash_id, tvb, offset, 2, hashid); proto_tree_add_item(aichhash_tree, hf_emule_aich_hash, tvb, offset+2, 20, ENC_NA); return offset + 22; } static int dissect_emule_aich_hash_list(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= < >* */ return dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "AICH Hash", dissect_emule_aich_hash_list_entry); } static int dissect_emule_multipacket(tvbuff_t *tvb, packet_info *pinfo, int offset, int eoffset, proto_tree *tree, int isext) { guint8 opcode, nextop; guint16 namelen, partcount, arrlen, oplen; guint32 sourcecount; proto_item *ti; proto_tree *mp_tree; /* ::= * */ /* ::= * */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); if (isext) { proto_tree_add_item(tree, hf_edonkey_emule_file_length, tvb, offset, 8, ENC_LITTLE_ENDIAN); offset += 8; } while (offset ::= guint8 */ proto_tree_add_item(tree, hf_edonkey_overnet_peer_type, tvb, offset, 1, ENC_NA); return offset+1; } /* Dissects the Overnet peer */ static int dissect_overnet_peer(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::=
*/ proto_item *ti; proto_tree *peer_tree; ti = proto_tree_add_item(tree, hf_overnet_peer, tvb, offset, 16 + 6 + 1, ENC_NA); peer_tree = proto_item_add_subtree(ti, ett_overnet_peer); offset = dissect_edonkey_hash(tvb, pinfo, offset, peer_tree); offset = dissect_edonkey_address(tvb, pinfo, offset, peer_tree); offset = dissect_overnet_peertype(tvb, pinfo, offset, peer_tree); return offset; } static int dissect_kademlia_peertype(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { /* ::= 1bytes */ proto_tree_add_item( tree, hf_kademlia_peertype, tvb, offset, 1, ENC_BIG_ENDIAN ); return offset + 1; } /* Dissects the Kademlia peer */ static int dissect_kademlia_peer(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::=
*/ proto_item *ti; proto_tree *peer_tree; ti = proto_tree_add_item(tree, hf_kademlia_peer, tvb, offset, 16 + 4 + 4 + 1, ENC_NA); peer_tree = proto_item_add_subtree(ti, ett_overnet_peer); /* 16 */ offset = dissect_kademlia_hash(tvb, pinfo, offset, peer_tree, &hf_kademlia_peer_id); /* 8 ( 4 ip + 2 tcp port + 2 udp port ) */ offset = dissect_kademlia_address(tvb, pinfo, offset, peer_tree); /* 1 */ /* offset = dissect_kademlia_peertype(tvb, pinfo, offset, peer_tree); */ proto_tree_add_item(peer_tree, hf_kademlia_version, tvb, offset, 1, ENC_BIG_ENDIAN); return offset + 1; } /* Dissects the Kademlia2 peer */ static int dissect_kademlia2_peer(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::=
*/ proto_item *ti; proto_tree *peer_tree; ti = proto_tree_add_item(tree, hf_kademlia_peer, tvb, offset, 16 + 4 + 4 + 1, ENC_NA); peer_tree = proto_item_add_subtree(ti, ett_overnet_peer); /* 16 */ offset = dissect_kademlia_hash(tvb, pinfo, offset, peer_tree, &hf_kademlia_peer_id); /* 8 ( 4 ip + 2 tcp port + 2 udp port ) */ offset = dissect_kademlia_address(tvb, pinfo, offset, peer_tree); /* 1 */ offset = dissect_kademlia_peertype(tvb, pinfo, offset, peer_tree); return offset; } /* Dissects the eDonkey search query */ // NOLINTNEXTLINE(misc-no-recursion) static int dissect_edonkey_search_query(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* ::= */ proto_item *ti; proto_tree *search_tree; guint8 search_type, special_tagtype; guint16 tag_name_size, string_length; guint32 search_length; int string_offset, tag_name_offset; search_type = tvb_get_guint8(tvb, offset); search_length = 1; ti = proto_tree_add_uint(tree, hf_edonkey_search_type, tvb, offset, 1, search_type); increment_dissection_depth(pinfo); switch (search_type) { case EDONKEY_SEARCH_BOOL: /* ::= */ search_length += 1; /* Add subtree for search entry */ proto_item_set_len(ti, search_length); search_tree = proto_item_add_subtree(ti, ett_edonkey_search); /* Add query info */ proto_tree_add_item(search_tree, hf_edonkey_search_ops, tvb, offset+1, 1, ENC_LITTLE_ENDIAN); offset+=2; offset = dissect_edonkey_search_query(tvb, pinfo, offset, search_tree); offset = dissect_edonkey_search_query(tvb, pinfo, offset, search_tree); break; case EDONKEY_SEARCH_NAME: /* ::= */ string_offset = offset + search_length; string_length = tvb_get_letohs(tvb, string_offset); search_length += 2+string_length; /* Add subtree for search entry */ proto_item_set_len(ti, search_length); search_tree = proto_item_add_subtree(ti, ett_edonkey_search); /* Add query info */ proto_tree_add_uint(search_tree, hf_edonkey_string_length, tvb, string_offset, 2, string_length); proto_tree_add_item(search_tree, hf_edonkey_string, tvb, string_offset+2, string_length, ENC_ASCII); offset += search_length; break; case EDONKEY_SEARCH_META: /* ::= */ string_offset = offset + search_length; string_length = tvb_get_letohs(tvb, offset+1); search_length += 2+string_length; tag_name_offset = offset + search_length; tag_name_size = tvb_get_letohs(tvb, tag_name_offset); special_tagtype = tvb_get_guint8(tvb, tag_name_offset+2); search_length += 2 + tag_name_size; /* Add subtree for search entry */ proto_item_set_len(ti, search_length); search_tree = proto_item_add_subtree(ti, ett_edonkey_search); /* Add query info */ proto_tree_add_uint(search_tree, hf_edonkey_string_length, tvb, string_offset, 2, string_length); proto_tree_add_item(search_tree, hf_edonkey_string, tvb, string_offset+2, string_length, ENC_ASCII); proto_tree_add_uint(search_tree, hf_edonkey_metatag_namesize, tvb, tag_name_offset, 2, tag_name_size); edonkey_tree_add_metatag_name(search_tree, tvb, tag_name_offset+2, tag_name_size, special_tagtype); offset += search_length; break; case EDONKEY_SEARCH_LIMIT: /* ::= */ search_length += 5; /* 4 bytes for the limit, one for the minmax */ tag_name_offset = offset + search_length; tag_name_size = tvb_get_letohs(tvb, tag_name_offset); special_tagtype = tvb_get_guint8(tvb, tag_name_offset+2); search_length += 2 + tag_name_size; /* Add subtree for search entry */ proto_item_set_len(ti, search_length); search_tree = proto_item_add_subtree(ti, ett_edonkey_search); /* Add query info */ proto_tree_add_item(search_tree, hf_edonkey_search_limit, tvb, offset+1, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(search_tree, hf_edonkey_search_limit_type, tvb, offset+5, 1, ENC_LITTLE_ENDIAN); proto_tree_add_uint(search_tree, hf_edonkey_metatag_namesize, tvb, tag_name_offset, 2, tag_name_size); edonkey_tree_add_metatag_name(search_tree, tvb, tag_name_offset+2, tag_name_size, special_tagtype); offset += search_length; break; default: /* Unknown search type - actual search length is also unknown */ proto_item_set_len(ti, search_length); offset += search_length; break; } decrement_dissection_depth(pinfo); return offset; } static void dissect_edonkey_tcp_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { int msg_end, bytes_remaining; guint8 helloClient; bytes_remaining = tvb_reported_length_remaining(tvb, offset); if ((length < 0) || (length > bytes_remaining)) length = bytes_remaining; if (length <= 0) return; msg_end = offset + length; switch (msg_type) { case EDONKEY_MSG_HELLO: /* Client to Server: */ /* Client to Client: 0x10 */ /* If Hello is sent to server 0x10 before UserHash is skipped, but UserHash might starts with 0x10. To decrease posibility of mistake, we check also 6th and 15h byte of UserHash - they have constant value. The best way would be to process whole packet to check it. */ helloClient = (tvb_get_guint8(tvb, offset) == 0x10 && tvb_get_guint8(tvb, offset + 6) == 0x0E && tvb_get_guint8(tvb, offset + 15) == 0x6F); if (helloClient) { proto_tree_add_uint(tree, hf_edonkey_user_hash_length, tvb, offset, 1, 16); offset += 1; } offset = dissect_edonkey_client_info(tvb, pinfo, offset, tree); if (helloClient) /* User's server ip is sent only to clients. */ offset = dissect_edonkey_address(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_HELLO_ANSWER: /* Hello Answer: */ offset = dissect_edonkey_client_info(tvb, pinfo, offset, tree); offset = dissect_edonkey_address(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SERVER_CB_REQ: /* Server Callback Request: */ offset = dissect_edonkey_address(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SERVER_INFO_DATA: /* Server Info Data: */ offset = dissect_edonkey_server_info(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SERVER_LIST: /* Server List:
*/ offset = dissect_edonkey_address_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_OFFER_FILES: /* Offer Files: */ case EDONKEY_MSG_VIEW_FILES_ANSWER: /* View Files Answer: */ offset = dissect_edonkey_file_info_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SEARCH_FILE_RESULTS: /* Search File Results: */ offset = dissect_edonkey_file_info_list(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_edonkey_more_search_file_results, tvb, offset, 1, ENC_NA); break; case EDONKEY_MSG_SEARCH_FILES: /* Search File: */ case EDONKEY_MSG_SEARCH_USER: /* Search User: */ offset = dissect_edonkey_search_query(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_GET_SOURCES: /* Get Sources: */ case EDONKEY_MSG_GET_SOURCES_OBFU: /* Get Sources: */ { guint32 fileSize; proto_item* ti; offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); fileSize = tvb_get_letohl(tvb, offset); ti = proto_tree_add_uint(tree, hf_edonkey_file_size, tvb, offset, 4, fileSize); offset += 4; /* if fileSize = 0 then 64bit file size comes next */ if (fileSize == 0) { proto_item_append_text(ti, " (64bit file size used)"); proto_tree_add_item(tree, hf_edonkey_large_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN); } } break; case EDONKEY_MSG_NO_SUCH_FILE: /* No Such File: */ case EDONKEY_MSG_END_OF_DOWNLOAD: /* End of Download: */ case EDONKEY_MSG_FILE_STATUS_REQUEST: /* File Status Request: */ case EDONKEY_MSG_HASHSET_REQUEST: /* Hashset Request: */ case EDONKEY_MSG_SLOT_REQUEST: /* Slot Request: */ case EDONKEY_MSG_FILE_REQUEST: /* File Request: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_FOUND_SOURCES_OBFU: /* Found Sources: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_emule_sourceOBFU_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_FOUND_SOURCES: /* Found Sources:
*/ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_address_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_CLIENT_CB_REQ: /* Client Callback Request: */ case EDONKEY_MSG_CALLBACK_FAIL: /* Callback Fail: */ case EDONKEY_MSG_ID_CHANGE: /* ID Change: */ offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); break; case EDONKEY_MSG_NEW_CLIENT_ID: /* New Client ID: */ offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); break; case EDONKEY_MSG_SERVER_MESSAGE: /* Server Message: */ case EDONKEY_MSG_CLIENT_MESSAGE: /* Client Message: */ offset = dissect_edonkey_string(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SERVER_STATUS: /* Server Status: */ proto_tree_add_item(tree, hf_edonkey_number_of_users, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(tree, hf_edonkey_number_of_files, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); break; case EDONKEY_MSG_FILE_STATUS: /* File Status: ? */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_file_status(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_FILE_REQUEST_ANSWER: /* File Request Answer: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_file_name(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_REQUEST_PARTS: /* Request Parts: (3) (3) */ { int pairs, count; offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); pairs = (msg_end - offset) / 8; for (count=0; count < pairs; count++) { offset = dissect_edonkey_start_offset(tvb, pinfo, offset, tree); } for (count=0; count < pairs; count++) { offset = dissect_edonkey_end_offset(tvb, pinfo, offset, tree); } } break; case EDONKEY_MSG_SENDING_PART: /* Sending Part: DATA */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset(tvb, pinfo, offset, tree); offset = dissect_edonkey_end_offset(tvb, pinfo, offset, tree); if (msg_end > offset) { bytes_remaining = msg_end - offset; proto_tree_add_item(tree, hf_edonkey_message_data, tvb, offset, bytes_remaining, ENC_NA); } break; case EDONKEY_MSG_SEARCH_USER_RESULTS: /* Search User Results: */ offset = dissect_edonkey_client_info_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_GET_SHARED_FILES: /* Get Shared Files: */ offset = dissect_edonkey_directory(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SHARED_DIRS: /* Shared Dirs: */ offset = dissect_edonkey_directory_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_SHARED_FILES: /* Shared Files: */ offset = dissect_edonkey_directory(tvb, pinfo, offset, tree); offset = dissect_edonkey_file_info_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_HASHSET_ANSWER: /* Hashset Answer: */ offset = dissect_edonkey_hash_list(tvb, pinfo, offset, tree); break; default: proto_tree_add_item(tree, hf_edonkey_message_data, tvb, offset, length, ENC_NA); break; } if (offset < msg_end) { int extra_bytes = msg_end - offset; /* trailing garbage or broken packet */ proto_tree_add_uint_format(tree, hf_edonkey_unparsed_data_length, tvb, offset, extra_bytes, extra_bytes, "Trailing/Undecoded data: %d bytes", extra_bytes ); } return; } static void dissect_emule_tcp_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { int msg_end, bytes_remaining; guint16 partnum; bytes_remaining = tvb_reported_length_remaining(tvb, offset); if ((length < 0) || (length > bytes_remaining)) length = bytes_remaining; if (length <= 0) return; msg_end = offset + length; switch (msg_type) { case EMULE_MSG_HELLO: /* eMule Info: */ case EMULE_MSG_HELLO_ANSWER: /* eMule Info Answer: */ proto_tree_add_item(tree, hf_edonkey_emule_version, tvb, offset, 2, ENC_LITTLE_ENDIAN); dissect_edonkey_metatag_list(tvb, pinfo, offset+2, tree); break; case EMULE_MSG_QUEUE_RANKING: /* eMule Queue Ranking: */ proto_tree_add_item(tree, hf_edonkey_emule_queue_ranking, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; case EMULE_MSG_SOURCES_REQUEST: /* Sources Request: */ dissect_edonkey_file_hash(tvb, pinfo, offset, tree); break; case EMULE_MSG_SOURCES_ANSWER: /* Sources Answer:
*/ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); dissect_emule_address_list(tvb, pinfo, offset, tree); break; case EMULE_MSG_SEC_IDENT_STATE: proto_tree_add_item(tree, hf_edonkey_emule_ident_state, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(tree, hf_edonkey_emule_rndchallenge, tvb, offset, 4, ENC_LITTLE_ENDIAN); break; case EMULE_MSG_PUBLIC_KEY: /* Public Key: <1byte : len> */ /* offset =*/ dissect_edonkey_public_key(tvb, pinfo, offset, tree); /* offset = dissect_emule_publickey(tvb, pinfo, offset, tree); */ break; case EMULE_MSG_SIGNATURE: offset = dissect_edonkey_signature(tvb, pinfo, offset, tree); if (msg_end != offset) { proto_tree_add_item(tree, hf_edonkey_emule_sig_ip_used, tvb, offset, 1, ENC_NA); } break; /* case EMULE_MSG_SIGNATURE: Public Key: <1byte : len> */ /* offset = dissect_emule_publickey(tvb, pinfo, offset, tree); */ /* break; */ /* case EMULE_MSG_SECIDENTSTATE: Public Key: <1byte : len> */ /* offset = dissect_emule_secstate(tvb, pinfo, offset, tree); */ /* offset = dissect_emule_challenge(tvb, pinfo, offset, tree); */ /* break; */ case EMULE_MSG_DATA_COMPRESSED: /* Data Compressed: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_edonkey_packed_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; if (msg_end > offset) { bytes_remaining = msg_end - offset; proto_tree_add_item(tree, hf_edonkey_compressed_message_data, tvb, offset, bytes_remaining, ENC_NA); } break; case EMULE_MSG_DATA_COMPRESSED_64: /* Data Compressed: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset_64(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_edonkey_packed_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; if (msg_end > offset) { bytes_remaining = msg_end - offset; proto_tree_add_item(tree, hf_edonkey_compressed_message_data, tvb, offset, bytes_remaining, ENC_NA); } break; case EMULE_MSG_REQUEST_PARTS_64: /* Request Parts: (3) (3) */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset_64(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset_64(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset_64(tvb, pinfo, offset, tree); offset = dissect_edonkey_end_offset_64(tvb, pinfo, offset, tree); offset = dissect_edonkey_end_offset_64(tvb, pinfo, offset, tree); dissect_edonkey_end_offset_64(tvb, pinfo, offset, tree); break; case EMULE_MSG_SENDING_PART_64: /* Sending Part: DATA */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_start_offset_64(tvb, pinfo, offset, tree); offset = dissect_edonkey_end_offset_64(tvb, pinfo, offset, tree); if (msg_end > offset) { bytes_remaining = msg_end - offset; proto_tree_add_item(tree, hf_edonkey_message_data, tvb, offset, bytes_remaining, ENC_NA); } break; case EMULE_MSG_CALLBACK: /* Callback: < hash > */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); /*offset = */dissect_edonkey_file_hash(tvb, pinfo, offset, tree); /* offset = dissect_edonkey_generic_uint16(tvb, pinfo, offset, tree, "uint16" ); */ break; case EMULE_MSG_AICH_REQUEST: /* AICH Request: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); partnum = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_emule_aich_partnum, tvb, offset, 2, partnum); offset += 2; dissect_emule_aich_root_hash(tvb, pinfo, offset, tree); break; case EMULE_MSG_AICH_ANSWER: /* AICH Answer: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); partnum = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_emule_aich_partnum, tvb, offset, 2, partnum); offset += 2; offset = dissect_emule_aich_root_hash(tvb, pinfo, offset, tree); dissect_emule_aich_hash_list(tvb, pinfo, offset, tree); break; case EMULE_MSG_MULTIPACKET: /* MultiPacket: */ case EMULE_MSG_MULTIPACKET_ANSWER: case EMULE_MSG_MULTIPACKET_EXT: /* MultiPacketExt: */ dissect_emule_multipacket(tvb, pinfo, offset, offset+length, tree, msg_type==EMULE_MSG_MULTIPACKET_EXT); break; default: dissect_edonkey_tcp_message(msg_type, tvb, pinfo, offset, length, tree); break; } return; } static int dissect_edonkey_udp_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { int msg_end, bytes_remaining; guint16 ischal; bytes_remaining = tvb_reported_length_remaining(tvb, offset); if ((length < 0) || (length > bytes_remaining)) length = bytes_remaining; if (length <= 0) return offset; msg_end = offset + length; switch (msg_type) { /* EDonkey UDP Messages */ case EDONKEY_MSG_UDP_CALLBACK_REQUEST: /* Callback Request:
*/ offset = dissect_edonkey_address(tvb, pinfo, offset, tree); offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); break; case EDONKEY_MSG_UDP_CALLBACK_FAIL: /* Callback Fail: */ offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); break; case EDONKEY_MSG_UDP_GET_SERVER_INFO: /* Get Server Info: */ if (length>=2) { ischal = tvb_get_letohs(tvb, offset); if (ischal==0xf0ff) { proto_tree_add_item(tree, hf_edonkey_challenge, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; } } break; case EDONKEY_MSG_UDP_SERVER_INFO: /* Server Info: */ ischal = tvb_get_letohs(tvb, offset); if (ischal==0xf0ff) { proto_tree_add_item(tree, hf_edonkey_challenge, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset = dissect_edonkey_metatag_list(tvb, pinfo, offset+4, tree); } else { offset = dissect_edonkey_string(tvb, pinfo, offset, tree); offset = dissect_edonkey_string(tvb, pinfo, offset, tree); } break; case EDONKEY_MSG_UDP_SERVER_LIST: /* Server List:
*/ offset = dissect_edonkey_address_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_UDP_SEARCH_FILE_RESULTS: /* Search File Result: */ offset = dissect_edonkey_file_info(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_UDP_SEARCH_FILE: /* Search File: */ offset = dissect_edonkey_search_query(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_UDP_GET_SOURCES: /* Get Sources: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_UDP_FOUND_SOURCES: /* Found Sources:
*/ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_address_list(tvb, pinfo, offset, tree); break; case EDONKEY_MSG_UDP_SERVER_STATUS_REQUEST: /* Server Status Request: */ proto_tree_add_item(tree, hf_edonkey_challenge, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; break; case EDONKEY_MSG_UDP_SERVER_STATUS: /* Server Status: */ proto_tree_add_item(tree, hf_edonkey_challenge, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_edonkey_number_of_users, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(tree, hf_edonkey_number_of_files, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); offset += 8; if (offset < msg_end) { proto_tree_add_item(tree, hf_edonkey_max_number_of_users, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; } break; /* Overnet UDP Messages */ case OVERNET_MSG_UDP_CONNECT: /* Connect: */ case OVERNET_MSG_UDP_PUBLICIZE: /* Publicize: */ offset = dissect_overnet_peer(tvb, pinfo, offset, tree); break; case OVERNET_MSG_UDP_CONNECT_REPLY: /* Connect Reply: */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Overnet Peer", dissect_overnet_peer); break; case OVERNET_MSG_UDP_SEARCH: /* Search: */ proto_tree_add_item(tree, hf_edonkey_search_type, tvb, offset, 1, ENC_NA); offset = dissect_edonkey_hash(tvb, pinfo, offset+1, tree); break; case OVERNET_MSG_UDP_SEARCH_INFO: /* Search Info: */ offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_edonkey_search_type, tvb, offset, 1, ENC_NA); proto_tree_add_item(tree, hf_edonkey_search_range_min, tvb, offset+1, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(tree, hf_edonkey_search_range_max, tvb, offset+3, 2, ENC_LITTLE_ENDIAN); break; case OVERNET_MSG_UDP_SEARCH_NEXT: /* Search Next: */ offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Overnet Peer", dissect_overnet_peer); break; case OVERNET_MSG_UDP_SEARCH_RESULT: /* Search Result: */ case OVERNET_MSG_UDP_PUBLISH: /* Publish: */ offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_metatag_list(tvb, pinfo, offset, tree); break; case OVERNET_MSG_UDP_SEARCH_END: /* Search End: */ offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); break; case OVERNET_MSG_UDP_PUBLISH_ACK: /* Publish ACK: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); break; case OVERNET_MSG_UDP_IP_QUERY: /* IP Query: */ proto_tree_add_item(tree, hf_edonkey_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; case OVERNET_MSG_UDP_IP_QUERY_ANSWER: /* IP Query Answer: */ offset = dissect_edonkey_client_id(tvb, pinfo, offset, tree, FALSE); break; case OVERNET_MSG_UDP_IDENTIFY_REPLY: /* Identify Reply: */ /* ::=
*/ offset = dissect_edonkey_hash(tvb, pinfo, offset, tree); offset = dissect_edonkey_address(tvb, pinfo, offset, tree); break; case OVERNET_MSG_UDP_IDENTIFY_ACK: /* Identify Reply: */ proto_tree_add_item(tree, hf_edonkey_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; case OVERNET_MSG_UDP_FIREWALL_CONNECTION: /* Firewall Connnection Ack: */ offset = dissect_edonkey_client_hash(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_edonkey_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; case OVERNET_MSG_UDP_FIREWALL_CONNECTION_ACK: /* Firewall Connnection Ack: */ case OVERNET_MSG_UDP_FIREWALL_CONNECTION_NACK: /* Firewall Connnection NAck: */ offset = dissect_edonkey_client_hash(tvb, pinfo, offset, tree); break; default: proto_tree_add_item(tree, hf_edonkey_message_data, tvb, offset, length, ENC_NA); offset+=length; break; } return offset; } static int dissect_emule_udp_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { int msg_end, bytes_remaining; bytes_remaining = tvb_reported_length_remaining(tvb, offset); if ((length < 0) || (length > bytes_remaining)) length = bytes_remaining; if (length <= 0) return offset; msg_end = offset + length; switch (msg_type) { case EMULE_MSG_UDP_REASKFILEPING: /* Reask File Ping: */ offset = dissect_edonkey_file_hash(tvb, pinfo, offset, tree); if ( offset + 2 < msg_end ) { /* Udp version > 3 */ offset = dissect_edonkey_file_status( tvb, pinfo, offset, tree ); } if ( msg_end == offset + 2 ) { /* Udp version > 2 */ proto_tree_add_item( tree, hf_emule_source_count, tvb, offset, 2, ENC_LITTLE_ENDIAN ); offset += 2; } break; case EMULE_MSG_UDP_REASKACK: /* Reask ACK: */ if ( offset + 2 < msg_end ) { /* Udp version > 3 */ offset = dissect_edonkey_file_status( tvb, pinfo, offset, tree ); } proto_tree_add_item(tree, hf_edonkey_emule_queue_ranking, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; default: offset = dissect_edonkey_udp_message(msg_type, tvb, pinfo, offset, length,tree); break; } return offset; } static int dissect_kademlia_peer_list_2byte(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Peer", dissect_kademlia_peer ); } static int dissect_kademlia_peer_list_1byte(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Peer", dissect_kademlia_peer ); } static int dissect_kademlia2_peer_list_2byte(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Peer", dissect_kademlia2_peer ); } static int dissect_kademlia2_peer_list_1byte(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Peer", dissect_kademlia2_peer ); } static int dissect_kademlia_tag(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { guint8 type; guint8 tag_type; const gchar *str_type; proto_item *ti; proto_item* tag_node; proto_tree *subtree; int item_start_offset; proto_item * ti_tagtype; item_start_offset = offset; /* tag_node length is adjusted at the end of this function */ subtree = proto_tree_add_subtree( tree, tvb, offset, 1, ett_kademlia_tag, &tag_node, "Tag " ); type = tvb_get_guint8( tvb, offset ); str_type = val_to_str_const(type, kademlia_tag_types, "Unknown" ); ti_tagtype = proto_tree_add_item( subtree, hf_kademlia_tag_type, tvb, offset, 1, ENC_LITTLE_ENDIAN ); offset += 1; { const gchar *tagname_string; const gchar *tagname_extended_string; /* Read tagname */ tag_type = tvb_get_guint8( tvb, offset+2 ); offset = dissect_kademlia_tagname( tvb, pinfo, offset, subtree, &tagname_string, &tagname_extended_string ); if ( strlen( tagname_string ) == 1 ) { const guint8 tagname_guint = *(const guint8*)tagname_string; proto_item_append_text( tag_node, " 0x%02X [%s] = ", tagname_guint, tagname_extended_string ); } else proto_item_append_text( tag_node, " \"%s\" [%s] = ", tagname_string, tagname_extended_string ); } /* Switch on type */ switch( type ) { case KADEMLIA_TAGTYPE_HASH: proto_item_append_text( tag_node, "%s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, 16 )); offset = dissect_kademlia_tag_hash( tvb, pinfo, offset, subtree ); break; case KADEMLIA_TAGTYPE_STRING: { const guint8* value; offset = dissect_kademlia_tag_string( tvb, pinfo, offset, subtree, &value ); proto_item_append_text( tag_node, "\"%s\"", value ); } break; case KADEMLIA_TAGTYPE_UINT8: { guint8 value; ti = proto_tree_add_item( subtree, hf_kademlia_tag_uint8, tvb, offset, 1, ENC_LITTLE_ENDIAN); value = tvb_get_guint8( tvb, offset ); proto_item_append_text( tag_node, "%u (0x%02X)", value, value ); switch (tag_type) { case KADEMLIA_TAG_SOURCETYPE: { proto_item_append_text(ti," (%s)", val_to_str_const(value, kademlia_tag_sourcetype, "Unknown")); } break; case KADEMLIA_TAG_ENCRYPTION: proto_item_append_text(ti, " (%s)", val_to_str_const(value, kademlia_tag_encryption, "Unknown")); break; } offset += 1; } break; case KADEMLIA_TAGTYPE_UINT16: { guint16 value; proto_tree_add_item( subtree, hf_kademlia_tag_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); value = tvb_get_letohs( tvb, offset ); proto_item_append_text( tag_node, "%u (0x%04X)", value, value ); offset += 2; } break; case KADEMLIA_TAGTYPE_UINT64: { guint64 value; proto_tree_add_item( subtree, hf_kademlia_tag_uint64, tvb, offset, 8, ENC_LITTLE_ENDIAN); value = tvb_get_letoh64( tvb, offset ); proto_item_append_text( tag_node, "%" PRIu64 " (0x%08" PRIX64 ")", value, value ); offset += 8; } break; case KADEMLIA_TAGTYPE_UINT32: { guint32 value; /* show ip as dotted decimal */ switch( tag_type) { case KADEMLIA_TAG_SERVERIP: case KADEMLIA_TAG_SOURCEIP: { int ipa = 0, ipb = 0, ipc = 0, ipd = 0; proto_tree_add_item( subtree, hf_kademlia_tag_ipv4, tvb, offset, 4, ENC_LITTLE_ENDIAN); value = tvb_get_letohl( tvb, offset ); ipa = (value / (256*256*256)) % 256; ipb = (value / (256*256)) % 256; ipc = (value / 256) % 256; ipd = value % 256; proto_item_append_text( tag_node, "%u.%u.%u.%u (0x%02X) ", ipa, ipb, ipc, ipd, value ); } break; default: proto_tree_add_item( subtree, hf_kademlia_tag_uint32, tvb, offset, 4, ENC_LITTLE_ENDIAN); value = tvb_get_letohl( tvb, offset ); proto_item_append_text( tag_node, "%u (0x%02X) ", value, value ); } offset += 4; } break; case KADEMLIA_TAGTYPE_FLOAT32: { float value; proto_tree_add_item( subtree, hf_kademlia_tag_float, tvb, offset, 4, ENC_LITTLE_ENDIAN); value = tvb_get_letohieee_float( tvb, offset ); proto_item_append_text( tag_node, "%f", value ); offset += 4; } break; case KADEMLIA_TAGTYPE_BSOB: { const gchar* value; offset = dissect_kademlia_tag_bsob( tvb, pinfo, offset, subtree, &value ); proto_item_append_text( tag_node, "%s", value ); } break; default: expert_add_info_format(pinfo, ti_tagtype, &ei_kademlia_tag_type, "Tag value not decoded for type: 0x%02X", type ); } proto_item_append_text( tag_node, " (Type: %s)", str_type ); proto_item_set_len( tag_node, offset - item_start_offset ); return offset; } static int dissect_kademlia_taglist(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { return dissect_edonkey_list(tvb, pinfo, offset, tree, 1, "Tag", dissect_kademlia_tag ); } static int dissect_kademlia_publish_req_entry_file(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* Get the hash */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_file_id); /* Read all the kad tags */ return dissect_kademlia_taglist( tvb, pinfo, offset, tree ); } static int dissect_kademlia_publish_req_entry_peer(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* Get the hash */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_peer_id); /* Read all the kad tags */ return dissect_kademlia_taglist( tvb, pinfo, offset, tree ); } static int dissect_kademlia_search_result(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { /* Get the hash */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_hash); /* Read all the kad tags */ return dissect_kademlia_taglist( tvb, pinfo, offset, tree ); } // NOLINTNEXTLINE(misc-no-recursion) static int dissect_kademlia_search_expression_tree(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { int op, item_start_offset; proto_item* ti; item_start_offset = offset; op = tvb_get_guint8(tvb, offset); ti = proto_tree_add_uint(tree, hf_kademlia_search_expression_type, tvb, offset, 1, op); tree = proto_item_add_subtree( ti, ett_kademlia_search_expression ); ++offset; increment_dissection_depth(pinfo); switch( op ) { case 0: /* Bool op */ proto_tree_add_item(tree, hf_kademlia_search_bool_op, tvb, offset, 1, ENC_NA ); ++offset; /* Left */ offset = dissect_kademlia_search_expression_tree( tvb, pinfo, offset, tree ); /* Right */ offset = dissect_kademlia_search_expression_tree( tvb, pinfo, offset, tree ); break; case 1: /* String */ offset = dissect_kademlia_string( tvb, pinfo, offset, tree ); break; case 2: /* Meta Tag */ /* tag value */ offset = dissect_edonkey_string( tvb, pinfo, offset, tree ); /* tag name */ offset = dissect_kademlia_tagname( tvb, pinfo, offset, tree, NULL, NULL ); break; case 3: /* Min/Max - 32bit! */ offset = dissect_kademlia_search_condition_argument_uint32( tvb, pinfo, offset, tree ); offset = dissect_kademlia_search_condition( tvb, pinfo, offset, tree ); /* tag name */ offset = dissect_kademlia_tagname( tvb, pinfo, offset, tree, NULL, NULL ); break; case 8: /* Min/Max - 64bit! */ offset = dissect_kademlia_search_condition_argument_uint64( tvb, pinfo, offset, tree ); offset = dissect_kademlia_search_condition( tvb, pinfo, offset, tree ); /* tag name */ offset = dissect_kademlia_tagname( tvb, pinfo, offset, tree, NULL, NULL ); break; default: expert_add_info_format(pinfo, ti, &ei_kademlia_search_expression_type, "NOT DECODED op %x", op ); } decrement_dissection_depth(pinfo); proto_item_set_len( ti, offset - item_start_offset ); return offset; } static int dissect_kademlia2_prolog( tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_peer_id); offset = dissect_kademlia_tcp_port(tvb, pinfo, offset, tree); proto_tree_add_item(tree, hf_kademlia_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; return offset; } static int dissect_kademlia_uload( tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_edonkey_kademlia_uload, tvb, offset, 1, ENC_NA); return offset +1; } static int dissect_kademlia_udp_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { int msg_end, bytes_remaining; proto_item *hidden_item; bytes_remaining = tvb_reported_length_remaining(tvb, offset); if ((length < 0) || (length > bytes_remaining)) length = bytes_remaining; if (length <= 0) return offset; hidden_item = proto_tree_add_item(tree, hf_kademlia, tvb, offset, 1, ENC_BIG_ENDIAN); proto_item_set_hidden(hidden_item); msg_end = offset + length; switch (msg_type) { case KADEMLIA_BOOTSTRAP_REQ:/* */ case KADEMLIA_HELLO_REQ: case KADEMLIA_HELLO_RES: offset = dissect_kademlia_peer(tvb, pinfo, offset, tree); break; case KADEMLIA2_BOOTSTRAP_REQ: offset = dissect_kademlia2_prolog( tvb, pinfo, offset, tree ); break; case KADEMLIA2_HELLO_REQ: case KADEMLIA2_HELLO_RES: offset = dissect_kademlia2_prolog( tvb, pinfo, offset, tree ); offset = dissect_kademlia_taglist( tvb, pinfo, offset, tree ); break; case KADEMLIA_BOOTSTRAP_RES: /* *(CNT) */ offset = dissect_kademlia_peer_list_2byte( tvb, pinfo, offset, tree ); break; case KADEMLIA2_BOOTSTRAP_RES: offset = dissect_kademlia2_prolog( tvb, pinfo, offset, tree ); offset = dissect_kademlia2_peer_list_2byte( tvb, pinfo, offset, tree ); break; case KADEMLIA2_SEARCH_SOURCE_REQ: { offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* start pos */ proto_tree_add_item(tree, hf_edonkey_kademlia_start_position, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset +=2; /* filesize */ proto_tree_add_item(tree, hf_edonkey_kademlia_filesize, tvb, offset, 8, ENC_LITTLE_ENDIAN); offset +=8; } break; case KADEMLIA_SEARCH_NOTES_REQ: /* */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_hash); break; case KADEMLIA2_SEARCH_KEY_REQ: { offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* start pos */ proto_tree_add_item(tree, hf_edonkey_kademlia_start_position, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } break; case KADEMLIA2_SEARCH_NOTES_REQ: case KADEMLIA_PUBLISH_RES: offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); if (offset */ case KADEMLIA2_REQ: { int type; guint8 target_id[16]; guint8 recipients_id[16]; proto_item *ti; int i, j, k, l; char binarray[129]; type = tvb_get_guint8(tvb, offset); ti = proto_tree_add_uint_format_value(tree, hf_kademlia_request_type, tvb, offset, 1, type, "0x%02x", type ); proto_item_append_text(ti, "%s", val_to_str_const(type, kademlia_parameter, " Unknown")); offset +=1; /* get target id */ for (i=0; i<4; i++) { for (j=3; j>=0; j--) { l = (j+4*i); target_id[l] = tvb_get_guint8(tvb, offset + abs(8*i-(l-3))); } } offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* get recipient's id */ for (i=0; i<4; i++) { for (j=3; j>=0; j--) { l = (j+4*i); recipients_id[l] = tvb_get_guint8(tvb, offset + abs(8*i-(l-3))); } } offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_recipients_id); /* target_id XOR recipients_id */ for (i=0; i<16; i++) { k = 128; l = target_id[i]^recipients_id[i]; for(j=8*i; j<8*i+8; j++) { if (l >= k) { binarray[j] = '1'; l = l-k; } else binarray[j] = '0'; k = k/2; } } binarray[128] = '\0'; proto_tree_add_string(tree, hf_kademlia_distance, tvb, offset, 0, binarray); } break; case KADEMLIA_RES: /* *(CNT) */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); offset = dissect_kademlia_peer_list_1byte( tvb, pinfo, offset, tree ); break; case KADEMLIA2_RES: offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); offset = dissect_kademlia2_peer_list_1byte( tvb, pinfo, offset, tree ); break; case KADEMLIA_FIREWALLED_RES: /* */ offset = dissect_kademlia_ip_address( tvb, pinfo, offset, tree ); break; case KADEMLIA_FIREWALLED_REQ: /* */ offset = dissect_kademlia_tcp_port( tvb, pinfo, offset, tree ); break; case KADEMLIA_CALLBACK_REQ: case KADEMLIA_FINDBUDDY_REQ: case KADEMLIA_FINDBUDDY_RES: /* buddy id */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_hash); /* userid */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_hash); offset = dissect_kademlia_tcp_port( tvb, pinfo, offset, tree ); break; case KADEMLIA2_PUBLISH_SOURCE_REQ: offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_file_id); offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_peer_id); offset = dissect_kademlia_taglist( tvb, pinfo, offset, tree ); break; case KADEMLIA_SEARCH_REQ: { int restrictive; /* Target (16bytes) */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* Restrictive (1 byte) 0/1 */ restrictive = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_edonkey_kademlia_restrictive, tvb, offset, 1, ENC_NA); offset +=1; if ( offset < msg_end && restrictive ) offset = dissect_kademlia_search_expression_tree( tvb, pinfo, offset, tree ); } break; case KADEMLIA_SEARCH_RES: /* Target */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* Results list */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Result", dissect_kademlia_search_result ); break; case KADEMLIA2_SEARCH_RES: /* Sender */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_sender_id); /* Target */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_target_id); /* Results list */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "Result", dissect_kademlia_search_result ); break; case KADEMLIA2_PUBLISH_KEY_REQ: { /* Keyword Hash */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_keyword_hash); /* Results list */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "StuffToPublish", dissect_kademlia_publish_req_entry_file ); break; } case KADEMLIA_PUBLISH_REQ: /* 0x40 // ( *(CNT2))*(CNT1) */ { guint8 tagname_value=0, taglist_size, type; int i=1, j=34; /* check if TAG_SOURCETYPE is set */ taglist_size = tvb_get_guint8(tvb, offset + j); j++; while(i <= taglist_size) { type = tvb_get_guint8(tvb, offset + j); j +=3; tagname_value = tvb_get_guint8(tvb, offset + j); if (tagname_value == 0xff) i = taglist_size; j++; switch(type) { case KADEMLIA_TAGTYPE_HASH: j += 16; break; case KADEMLIA_TAGTYPE_STRING: { guint16 string_length = tvb_get_letohs(tvb, offset+j); j += 2 + string_length; break; } case KADEMLIA_TAGTYPE_UINT8: j += 1; break; case KADEMLIA_TAGTYPE_UINT16: j += 2; break; case KADEMLIA_TAGTYPE_UINT32: case KADEMLIA_TAGTYPE_FLOAT32: j += 4; break; case KADEMLIA_TAGTYPE_UINT64: j += 8; break; case KADEMLIA_TAGTYPE_BSOB: { guint16 bsob_length = tvb_get_guint8(tvb, offset); j += 1 + bsob_length; break; } } i++; } switch (tagname_value) { case KADEMLIA_TAG_SOURCETYPE: { /* Target */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_file_id); /* Results list */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "StuffToPublish", dissect_kademlia_publish_req_entry_peer); } break; default: { /* Target */ offset = dissect_kademlia_hash(tvb, pinfo, offset, tree, &hf_kademlia_keyword_hash); /* Results list */ offset = dissect_edonkey_list(tvb, pinfo, offset, tree, 2, "StuffToPublish", dissect_kademlia_publish_req_entry_file); } } } } return offset; } static int dissect_kademlia_udp_compressed_message(guint8 msg_type, tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree) { tvbuff_t *tvbraw = NULL; tvbraw = tvb_child_uncompress(tvb, tvb, offset, length); if (tvbraw) { guint32 raw_length; raw_length = tvb_captured_length( tvbraw ); add_new_data_source(pinfo, tvbraw, "Decompressed Data"); dissect_kademlia_udp_message( msg_type, tvbraw, pinfo, 0, raw_length, tree ); offset += length; } else { proto_tree_add_item(tree, hf_edonkey_broken_compressed_data, tvb, offset, length, ENC_NA); } return offset; } static guint get_edonkey_tcp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { guint32 msg_len; /* * Get the length of the eDonkey packet. */ msg_len = tvb_get_letohl(tvb, offset+1); /* * That length doesn't include the header; add that in. * XXX - what if it overflows? */ return msg_len + EDONKEY_TCP_HEADER_LENGTH; } static int dissect_edonkey_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_item *ti; proto_tree *edonkey_tree, *edonkey_msg_tree = NULL, *emule_zlib_tree = NULL; int offset; guint8 protocol, msg_type; guint32 msg_len; const gchar *protocol_name, *message_name; void (*dissector)(guint8, tvbuff_t*, packet_info*, int, int, proto_tree*); tvbuff_t *tvbraw = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "eDonkey"); ti = proto_tree_add_item(tree, proto_edonkey, tvb, 0, -1, ENC_NA); edonkey_tree = proto_item_add_subtree(ti, ett_edonkey); offset = 0; protocol = tvb_get_guint8(tvb, offset); msg_len = tvb_get_letohl(tvb, offset+1); protocol_name = val_to_str_const(protocol, edonkey_protocols, "Unknown"); col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s TCP", protocol_name); /* Add edonkey message tree */ if (edonkey_tree) { ti = proto_tree_add_item(edonkey_tree, hf_edonkey_message, tvb, offset, EDONKEY_TCP_HEADER_LENGTH + msg_len, ENC_NA); edonkey_msg_tree = proto_item_add_subtree(ti, ett_edonkey_message); proto_tree_add_uint(edonkey_msg_tree, hf_edonkey_protocol, tvb, offset, 1, protocol); proto_tree_add_uint(edonkey_msg_tree, hf_edonkey_message_length, tvb, offset+1, 4, msg_len); } /* Skip past the EDONKEY Header */ offset += EDONKEY_TCP_HEADER_LENGTH; msg_type = tvb_get_guint8(tvb, offset); switch (protocol) { case EDONKEY_PROTO_EDONKEY: message_name = val_to_str_const(msg_type, edonkey_tcp_msgs, "Unknown"); dissector = dissect_edonkey_tcp_message; break; case EDONKEY_PROTO_EMULE_EXT: message_name = val_to_str_const(msg_type, emule_tcp_msgs, val_to_str_const(msg_type, edonkey_tcp_msgs, "Unknown")); dissector = dissect_emule_tcp_message; break; case EDONKEY_PROTO_EMULE_COMP: /* * These ought to be exactly the same as standard eDonkey (0xe5) messages, * except that the payload (after the type byte) is a zlib compressed * stream. */ message_name = val_to_str_const(msg_type, edonkey_tcp_msgs, "Unknown"); tvbraw = tvb_child_uncompress(tvb, tvb, offset+1, msg_len-1); if (tvbraw) { dissector = dissect_edonkey_tcp_message; break; } /* FALL THROUGH */ default: message_name = "Unknown"; dissector = NULL; break; } col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_name); if (edonkey_msg_tree) { proto_tree_add_uint_format_value(edonkey_msg_tree, hf_edonkey_message_type, tvb, offset, 1, msg_type, "%s (0x%02x)", message_name, msg_type); if (dissector && (msg_len > 1)) { if (!tvbraw) { (*dissector)(msg_type, tvb, pinfo, offset+1, msg_len-1, edonkey_msg_tree); } else { ti = proto_tree_add_item(edonkey_msg_tree, hf_emule_zlib, tvb, offset+1, msg_len-1, ENC_NA); emule_zlib_tree = proto_item_add_subtree(ti, ett_emule_zlib); add_new_data_source(pinfo, tvbraw, "Decompressed Data"); (*dissector)(msg_type, tvbraw, pinfo, 0, tvb_captured_length(tvbraw), emule_zlib_tree); } } } return tvb_captured_length(tvb); } static int dissect_edonkey_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { guint8 protocol; /* An eDonkey TCP packet is at least 5 bytes long msg type + length */ if (!tvb_bytes_exist(tvb, 0, EDONKEY_TCP_HEADER_LENGTH)) return 0; protocol = tvb_get_guint8(tvb, 0); if (try_val_to_str(protocol, edonkey_protocols) == NULL) return 0; /* Not a known protocol */ col_clear(pinfo->cinfo, COL_INFO); tcp_dissect_pdus(tvb, pinfo, tree, edonkey_desegment, EDONKEY_TCP_HEADER_LENGTH, get_edonkey_tcp_pdu_len, dissect_edonkey_tcp_pdu, data); return tvb_reported_length(tvb); } static int dissect_edonkey_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { proto_item *ti; proto_tree *edonkey_tree = NULL, *edonkey_msg_tree = NULL; int offset = 0; guint8 protocol, msg_type; const gchar *protocol_name, *message_name; /* An eDonkey UDP packet is at least 2 bytes long */ if (!tvb_bytes_exist(tvb, 0, EDONKEY_UDP_HEADER_LENGTH)) return 0; protocol = tvb_get_guint8(tvb, offset); if (try_val_to_str(protocol, edonkey_protocols) == NULL) return 0; /* Not a known protocol */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "eDonkey"); if (tree) { ti = proto_tree_add_item(tree, proto_edonkey, tvb, 0, -1, ENC_NA); edonkey_tree = proto_item_add_subtree(ti, ett_edonkey); } offset = 0; /* eDonkey UDP message - Assume that there is one message per packet */ msg_type = tvb_get_guint8(tvb, offset+1); protocol_name = val_to_str_const(protocol, edonkey_protocols, "Unknown"); if (protocol == EDONKEY_PROTO_KADEMLIA || protocol == EDONKEY_PROTO_KADEMLIA_COMP || protocol == EDONKEY_PROTO_ADU_KADEMLIA || protocol == EDONKEY_PROTO_ADU_KADEMLIA_COMP) message_name = val_to_str_const( msg_type, kademlia_msgs, "Unknown"); else message_name = val_to_str_const(msg_type, edonkey_udp_msgs, "Unknown"); col_add_fstr(pinfo->cinfo, COL_INFO, "%s UDP: %s", protocol_name, message_name); if (edonkey_tree) { int remainingLength, extraBytes; ti = proto_tree_add_item(edonkey_tree, hf_edonkey_message, tvb, offset, -1, ENC_NA); edonkey_msg_tree = proto_item_add_subtree(ti, ett_edonkey_message); proto_tree_add_uint(edonkey_msg_tree, hf_edonkey_protocol, tvb, offset, 1, protocol); proto_tree_add_uint_format_value(edonkey_msg_tree, hf_edonkey_message_type, tvb, offset+1, 1, msg_type, "%s (0x%02x)", message_name, msg_type); offset += EDONKEY_UDP_HEADER_LENGTH; remainingLength = tvb_captured_length_remaining( tvb, offset ); if (remainingLength > 0) { switch (protocol) { case EDONKEY_PROTO_EDONKEY: offset = dissect_edonkey_udp_message(msg_type, tvb, pinfo, offset, remainingLength, edonkey_msg_tree); break; case EDONKEY_PROTO_EMULE_EXT: offset = dissect_emule_udp_message(msg_type, tvb, pinfo, offset, remainingLength, edonkey_msg_tree); break; case EDONKEY_PROTO_ADU_KADEMLIA: case EDONKEY_PROTO_KADEMLIA: offset = dissect_kademlia_udp_message(msg_type, tvb, pinfo, offset, remainingLength, edonkey_msg_tree); break; case EDONKEY_PROTO_ADU_KADEMLIA_COMP: case EDONKEY_PROTO_KADEMLIA_COMP: offset = dissect_kademlia_udp_compressed_message(msg_type, tvb, pinfo, offset, remainingLength, edonkey_msg_tree); break; default: break; } } extraBytes = tvb_reported_length_remaining( tvb, offset ); if ( extraBytes > 0 ) { /* trailing garbage or broken packet */ proto_tree_add_uint_format(tree, hf_edonkey_unparsed_data_length, tvb, offset, extraBytes, extraBytes, "Trailing/Undecoded data: %d bytes", extraBytes ); } } return tvb_reported_length(tvb); } static void edonkey_fmt_revision(gchar *result, guint32 revision ) { snprintf( result, ITEM_LABEL_LENGTH, "%u.%u", (guint16)(revision & 0xFFFF), (guint16)(( revision & 0xFFFF0000 ) >> 16) ); } void proto_register_edonkey(void) { static hf_register_info hf[] = { { &hf_edonkey_message, { "eDonkey Message", "edonkey.message", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_edonkey_protocol, { "Protocol", "edonkey.protocol", FT_UINT8, BASE_HEX, VALS(edonkey_protocols), 0, "eDonkey Protocol", HFILL } }, { &hf_edonkey_message_length, { "Message Length", "edonkey.message.length", FT_UINT32, BASE_DEC, NULL, 0, "eDonkey Message Length", HFILL } }, { &hf_edonkey_message_type, { "Message Type", "edonkey.message.type", FT_UINT8, BASE_HEX, NULL, 0, "eDonkey Message Type", HFILL } }, { &hf_edonkey_client_hash, { "Client Hash", "edonkey.client_hash", FT_BYTES, BASE_NONE, NULL, 0, "eDonkey Client Hash", HFILL } }, { &hf_edonkey_server_hash, { "Server Hash", "edonkey.server_hash", FT_BYTES, BASE_NONE, NULL, 0, "eDonkey Server Hash", HFILL } }, { &hf_edonkey_file_hash, { "File Hash", "edonkey.file_hash", FT_BYTES, BASE_NONE, NULL, 0, "eDonkey File Hash", HFILL } }, { &hf_edonkey_client_id, { "Client ID", "edonkey.clientid", FT_IPv4, BASE_NONE, NULL, 0, "eDonkey Client ID", HFILL } }, { &hf_edonkey_ip, { "IP", "edonkey.ip", FT_IPv4, BASE_NONE, NULL, 0, "eDonkey IP", HFILL } }, { &hf_edonkey_port, { "Port", "edonkey.port", FT_UINT16, BASE_DEC, NULL, 0, "eDonkey Port", HFILL } }, { &hf_edonkey_metatag, { "eDonkey Meta Tag", "edonkey.metatag", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_edonkey_metatag_type, { "Meta Tag Type", "edonkey.metatag.type", FT_UINT8, BASE_HEX, NULL, 0, "eDonkey Meta Tag Type", HFILL } }, { &hf_edonkey_metatag_id, { "Meta Tag ID", "edonkey.metatag.id", FT_UINT8, BASE_HEX, NULL, 0, "eDonkey Meta Tag ID", HFILL } }, { &hf_edonkey_metatag_name, { "Meta Tag Name", "edonkey.metatag.name", FT_STRING, BASE_NONE, NULL, 0, "eDonkey Meta Tag Name", HFILL } }, { &hf_edonkey_metatag_namesize, { "Meta Tag Name Size", "edonkey.metatag.namesize", FT_UINT16, BASE_DEC, NULL, 0, "eDonkey Meta Tag Name Size", HFILL } }, { &hf_edonkey_hash, { "Hash", "edonkey.hash", FT_BYTES, BASE_NONE, NULL, 0, "eDonkey Hash", HFILL } }, { &hf_edonkey_string, { "String", "edonkey.string", FT_STRING, BASE_NONE, NULL, 0, "eDonkey String", HFILL } }, { &hf_edonkey_string_length, { "String Length", "edonkey.string_length", FT_UINT16, BASE_DEC, NULL, 0, "eDonkey String Length", HFILL } }, { &hf_edonkey_part_count, { "Part Count", "edonkey.part_count", FT_UINT16, BASE_DEC, NULL, 0, "eDonkey Part Count", HFILL } }, { &hf_edonkey_file_status, { "File Status", "edonkey.file_status", FT_BYTES, BASE_NONE, NULL, 0, "eDonkey File Status", HFILL } }, { &hf_edonkey_directory, { "Directory", "edonkey.directory", FT_STRING, BASE_NONE, NULL, 0, "eDonkey Directory", HFILL } }, { &hf_edonkey_fileinfo, { "eDonkey File Info", "edonkey.fileinfo", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_edonkey_serverinfo, { "eDonkey Server Info", "edonkey.serverinfo", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_edonkey_clientinfo, { "eDonkey Client Info", "edonkey.clientinfo", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_emule_public_key, { "Public Key", "edonkey.emule.public_key", FT_BYTES, BASE_NONE, NULL, 0, "eMule Public Key", HFILL } }, { &hf_emule_signature, { "Signature", "edonkey.emule.signature", FT_BYTES, BASE_NONE, NULL, 0, "eMule Signature", HFILL } }, { &hf_emule_aich_partnum, { "Part Number", "edonkey.emule.aich_partnum", FT_UINT16, BASE_DEC, NULL, 0, "eMule AICH Part Number", HFILL } }, { &hf_emule_aich_root_hash, { "AICH Root Hash", "edonkey.emule.aich_root_hash", FT_BYTES, BASE_NONE, NULL, 0, "eMule AICH Root Hash", HFILL } }, { &hf_emule_aich_hash_entry, { "AICH Hash Entry", "edonkey.emule.aich_hash_entry", FT_NONE, BASE_NONE, NULL, 0, "eMule AICH Hash Entry", HFILL } }, { &hf_emule_aich_hash_id, { "AICH Hash ID", "edonkey.emule.aich_hash_id", FT_UINT16, BASE_HEX, NULL, 0, "eMule AICH Hash ID", HFILL } }, { &hf_emule_aich_hash, { "AICH Hash", "edonkey.emule.aich_hash", FT_BYTES, BASE_NONE, NULL, 0, "eMule AICH Hash", HFILL } }, { &hf_emule_multipacket_entry, { "eMule MultiPacket Entry", "edonkey.emule.multipacket_entry", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_emule_multipacket_opcode, { "MultiPacket Opcode", "edonkey.emule.multipacket_opcode", FT_UINT8, BASE_HEX, NULL, 0, "eMule MultiPacket Opcode", HFILL } }, { &hf_emule_sourceOBFU, {"Source", "edonkey.source", FT_NONE, BASE_NONE, NULL, 0, "eDonkey File Source", HFILL } }, { &hf_emule_source_count, { "Completed Sources Count", "edonkey.emule.source_count", FT_UINT16, BASE_DEC, NULL, 0, "eMule Completed Sources Count", HFILL } }, { &hf_emule_zlib, { "Compressed Data", "edonkey.emule.zlib", FT_NONE, BASE_NONE, NULL, 0, "eMule Compressed Data", HFILL } }, { &hf_overnet_peer, { "Overnet Peer", "edonkey.overnet.peer", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_kademlia, { "Kademlia Packet", "edonkey.kademlia", FT_UINT8, BASE_HEX, NULL, 0, "Kademlia Packet Type", HFILL } }, { &hf_kademlia_peertype, { "Peer Type", "edonkey.kademlia.peer.type", FT_UINT8, BASE_DEC_HEX, NULL, 0, "Kademlia Peer Type", HFILL } }, { &hf_kademlia_peer, { "Kademlia Peer", "edonkey.kademlia.peer", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_kademlia_peer_id, { "Peer ID", "edonkey.kademlia.peer.id", FT_STRING, BASE_NONE, NULL, 0, "Kademlia Peer ID", HFILL } }, { &hf_kademlia_hash, { "Kademlia Hash", "edonkey.kademlia.hash", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_kademlia_file_id, { "File ID", "edonkey.kademlia.file.id", FT_STRING, BASE_NONE, NULL, 0, "Kademlia File ID", HFILL } }, { &hf_kademlia_keyword_hash, { "Keyword Hash", "edonkey.kademlia.keyword.hash", FT_STRING, BASE_NONE, NULL, 0, "Kademlia Keyword Hash", HFILL } }, { &hf_kademlia_recipients_id, { "Recipient's ID", "edonkey.kademlia.recipients.id", FT_STRING, BASE_NONE, NULL, 0, "Kademlia Recipient's ID", HFILL } }, { &hf_kademlia_sender_id, { "Sender ID", "edonkey.kademlia.sender.id", FT_STRING, BASE_NONE, NULL, 0, "Kademlia Sender ID", HFILL } }, { &hf_kademlia_target_id, { "Target ID", "edonkey.kademlia.target.id", FT_STRING, BASE_NONE, NULL, 0, "Kademlia Target ID", HFILL } }, { &hf_kademlia_distance, { "XOR Distance", "edonkey.kademlia.distance", FT_STRING, BASE_NONE, NULL, 0, "Kademlia XOR Distance", HFILL } }, { &hf_kademlia_version, { "Kad Version", "edonkey.kademlia.version", FT_UINT8, BASE_DEC_HEX, VALS(kademlia_versions), 0, NULL, HFILL } }, { &hf_kademlia_tag_float, { "Tag Value (Float)", "edonkey.kademlia.tag.value.float", FT_FLOAT, BASE_NONE, NULL, 0, "Float Tag Value", HFILL } }, { &hf_kademlia_tag_uint64, { "Tag Value (UINT64)", "edonkey.kademlia.tag.value.uint64", FT_UINT64, BASE_DEC_HEX, NULL, 0, "UINT64 Tag Value", HFILL } }, { &hf_kademlia_tag_uint32, { "Tag Value (UINT32)", "edonkey.kademlia.tag.value.uint32", FT_UINT32, BASE_DEC_HEX, NULL, 0, "UINT32 Tag Value", HFILL } }, { &hf_kademlia_tag_ipv4, { "Tag Value (IPv4)", "edonkey.kademlia.tag.value.ipv4", FT_IPv4, BASE_NONE, NULL, 0, "UINT32 Tag Value (IPv4)", HFILL } }, { &hf_kademlia_tag_uint16, { "Tag Value (UINT16)", "edonkey.kademlia.tag.value.uint16", FT_UINT16, BASE_DEC_HEX, NULL, 0, "UINT16 Tag Value", HFILL } }, { &hf_kademlia_tag_uint8, { "Tag Value (UINT8)", "edonkey.kademlia.tag.value.uint8", FT_UINT8, BASE_DEC_HEX, NULL, 0, "UINT8 Tag Value", HFILL } }, { &hf_kademlia_tag_hash, { "Tag Value (HASH)", "edonkey.kademlia.tag.value.hash", FT_STRING, BASE_NONE, NULL, 0, "HASH Tag Value", HFILL } }, { &hf_kademlia_tag_string, { "Tag Value (String)", "edonkey.kademlia.tag.value.string", FT_STRING, BASE_NONE, NULL, 0, "String Tag Value", HFILL } }, { &hf_kademlia_tag_bsob, { "Tag Value (BSOB)", "edonkey.kademlia.tag.value.bsob", FT_BYTES, BASE_NONE, NULL, 0, "BSOB Tag Value", HFILL } }, { &hf_kademlia_udp_port, { "UDP Port", "edonkey.kademlia.udp_port", FT_UINT16, BASE_DEC, NULL, 0, "Kademlia UDP Port", HFILL } }, { &hf_kademlia_ip, { "IP", "edonkey.kademlia.ip", FT_IPv4, BASE_NONE, NULL, 0, "eDonkey IP", HFILL } }, { &hf_kademlia_tcp_port, { "TCP Port", "edonkey.kademlia.tcp_port", FT_UINT16, BASE_DEC, NULL, 0, "Kademlia TCP Port", HFILL } }, #if 0 { &hf_kademlia_unparsed_data_length, { "Kademlia unparsed data length", "edonkey.kademlia.unparsed", FT_UINT16, BASE_DEC, NULL, 0, "Kademlia trailing data length", HFILL } }, #endif { &hf_kademlia_tag_name, { "Tag Name", "edonkey.kademlia.tag.name", FT_UINT8, BASE_HEX, NULL, 0, "Kademlia Tag Name String", HFILL } }, { &hf_kademlia_tag_name_length, { "Tag Name Length", "edonkey.kademlia.tag.name.length", FT_UINT16, BASE_DEC, NULL, 0, "Kademlia Tag Name String Length", HFILL } }, { &hf_kademlia_tag_type, { "Tag Type", "edonkey.kademlia.tag.type", FT_UINT8, BASE_HEX, VALS(kademlia_tag_types), 0, "Kademlia Tag Type", HFILL } }, { &hf_kademlia_request_type, { "Request Type", "edonkey.kademlia.request.type", FT_UINT8, BASE_HEX, NULL, 0, "Kademlia Request Type", HFILL } }, { &hf_kademlia_search_expression_type, { "SearchExp Type", "edonkey.kademlia.search_expression.type", FT_UINT8, BASE_HEX, VALS(edonkey_search_ext_type_vals), 0, NULL, HFILL } }, { &hf_kademlia_search_bool_op, { "Bool op", "edonkey.kademlia.search.bool_op", FT_UINT8, BASE_HEX, VALS(edonkey_search_ops), 0, NULL, HFILL } }, { &hf_kademlia_search_condition, { "Search Condition", "edonkey.kademlia.search.condition", FT_UINT8, BASE_HEX, NULL, 0, "Kademlia Search Condition", HFILL } }, { &hf_kademlia_search_condition_argument_uint32, { "32bit Argument", "edonkey.kademlia.search.condition.argument.uint32", FT_UINT32, BASE_DEC_HEX, NULL, 0, "Kademlia Search Condition Argument 32bit Value", HFILL } }, { &hf_kademlia_search_condition_argument_uint64, { "64bit Argument", "edonkey.kademlia.search.condition.argument.uint64", FT_UINT64, BASE_DEC_HEX, NULL, 0, "Kademlia Search Condition Argument 64bit Value", HFILL } }, { &hf_edonkey_unparsed_data_length, { "eDonkey unparsed data length", "edonkey.unparsed", FT_UINT32, BASE_DEC_HEX, NULL, 0, "eDonkey trailing or unparsed data length", HFILL } }, /* Generated from convert_proto_tree_add_text.pl */ { &hf_edonkey_list_size, { "List Size", "edonkey.list_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_meta_tag_value_revision, { "Meta Tag Value", "edonkey.meta_tag_value.revision", FT_UINT32, BASE_CUSTOM, CF_FUNC(edonkey_fmt_revision), 0x0, NULL, HFILL }}, { &hf_edonkey_meta_tag_value_uint, { "Meta Tag Value", "edonkey.meta_tag_value.uint", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_boolean_array_length, { "Boolean Array Length", "edonkey.boolean_array_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_blob_length, { "BLOB Length", "edonkey.blob_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_kademlia_string, { "String", "edonkey.kademlia_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_emule_public_key_length, { "Public key length", "edonkey.emule.public_key_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_emule_signature_length, { "Signature length", "edonkey.emule.signature_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_obfuscation_settings, { "Obfuscation Settings", "edonkey.obfuscation_settings", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_start_offset, { "Start Offset", "edonkey.start_offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_start_offset_64, { "Start Offset", "edonkey.start_offset64", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_end_offset, { "End Offset", "edonkey.end_offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_end_offset_64, { "End Offset", "edonkey.end_offset64", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_emule_file_length, { "File Length", "edonkey.emule.file_length", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_overnet_peer_type, { "Peer Type", "edonkey.overnet_peer_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_more_search_file_results, { "More", "edonkey.more_search_file_results", FT_BOOLEAN, 8, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_file_size, { "File size", "edonkey.file_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_large_file_size, { "Large file size", "edonkey.large_file_size", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_number_of_users, { "Number of Users", "edonkey.number_of_users", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_number_of_files, { "Number of Files", "edonkey.number_of_files", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_message_data, { "Message Data", "edonkey.message_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_emule_version, { "Version", "edonkey.emule.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_emule_queue_ranking, { "Queue Ranking", "edonkey.emule.queue_ranking", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_emule_ident_state, { "State", "edonkey.emule.state", FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(emule_ident_state_rvals), 0x0, NULL, HFILL }}, { &hf_edonkey_emule_rndchallenge, { "Rndchallenge", "edonkey.emule.rndchallenge", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_emule_sig_ip_used, { "Sig IP Used", "edonkey.emule.sig_ip_used", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_packed_length, { "Packed Length", "edonkey.emule.packed_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_compressed_message_data, { "Compressed Message Data", "edonkey.emule.compressed_message_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_challenge, { "Challenge", "edonkey.challenge", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_max_number_of_users, { "Max number of Users", "edonkey.max_number_of_users", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_search_type, { "Search Type", "edonkey.search_type", FT_UINT8, BASE_DEC, VALS(edonkey_search_type_vals), 0x0, NULL, HFILL }}, { &hf_edonkey_search_range_min, { "Search Range Min", "edonkey.search_range.min", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_search_range_max, { "Search Range Max", "edonkey.search_range.max", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_kademlia_uload, { "uLoad", "edonkey.kademlia_uload", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_kademlia_start_position, { "Start position", "edonkey.kademlia_start_position", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_kademlia_filesize, { "Filesize", "edonkey.kademlia_filesize", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_kademlia_restrictive, { "Restrictive", "edonkey.kademlia_restrictive", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_broken_compressed_data, { "Broken Compressed data", "edonkey.broken_compressed_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_search_limit, { "Search Limit", "edonkey.search_limit", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_edonkey_search_limit_type, { "Limit Type", "edonkey.search_limit_type", FT_UINT8, BASE_DEC, VALS(edonkey_search_conds), 0x0, NULL, HFILL }}, { &hf_edonkey_search_ops, { "Search Operator", "edonkey.search_ops", FT_UINT8, BASE_HEX, VALS(edonkey_search_ops), 0x0, NULL, HFILL }}, { &hf_edonkey_user_hash_length, { "User hash length", "edonkey.user_hash_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, }; static gint *ett[] = { &ett_edonkey, &ett_edonkey_message, &ett_edonkey_metatag, &ett_edonkey_search, &ett_edonkey_fileinfo, &ett_edonkey_serverinfo, &ett_edonkey_clientinfo, &ett_emule_aichhash, &ett_emule_multipacket, &ett_emule_zlib, &ett_overnet_peer, &ett_emule_sourceOBFU, &ett_edonkey_listitem, &ett_kademlia_search_expression, &ett_kademlia_tag }; static ei_register_info ei[] = { { &ei_kademlia_tag_type, { "edonkey.kademlia.tag.type.undecoded", PI_PROTOCOL, PI_WARN, "Tag value not decoded", EXPFILL }}, { &ei_kademlia_search_expression_type, { "edonkey.kademlia.search_expression.type.undecoded", PI_UNDECODED, PI_WARN, "NOT DECODED op", EXPFILL }}, }; module_t *edonkey_module; expert_module_t* expert_edonkey; proto_edonkey = proto_register_protocol("eDonkey Protocol", "EDONKEY", "edonkey"); proto_register_field_array(proto_edonkey, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); expert_edonkey = expert_register_protocol(proto_edonkey); expert_register_field_array(expert_edonkey, ei, array_length(ei)); edonkey_tcp_handle = register_dissector("edonkey.tcp", dissect_edonkey_tcp, proto_edonkey); edonkey_udp_handle = register_dissector("edonkey.udp", dissect_edonkey_udp, proto_edonkey); edonkey_module = prefs_register_protocol(proto_edonkey, NULL); prefs_register_bool_preference(edonkey_module, "desegment", "Reassemble eDonkey messages spanning multiple TCP segments", "Whether the eDonkey dissector should reassemble messages spanning multiple TCP segments." " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &edonkey_desegment); } void proto_reg_handoff_edonkey(void) { dissector_add_uint_range_with_preference("tcp.port", EDONKEY_TCP_PORT_RANGE, edonkey_tcp_handle); dissector_add_uint_range_with_preference("udp.port", EDONKEY_UDP_PORT_RANGE, edonkey_udp_handle); } /* * 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: */