Package: wireshark Version: 1.0.0-3 Severity: wishlist Tags: patch
Hello, In analyzing VoIP traffic, I found that the ZRTP project has a patch availble to wireshark to help inspect ZRTP packets. It basically renders ZRTP packets in a clearer and better understood format. Please find the patch attached. Thanks! Micah -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.25-2-vserver-686 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages wireshark depends on: ii libadns1 1.4-0.1 Asynchronous-capable DNS client li ii libatk1.0-0 1.22.0-1 The ATK accessibility toolkit ii libc6 2.7-12 GNU C Library: Shared libraries ii libcairo2 1.6.4-6 The Cairo 2D vector graphics libra ii libcomerr2 1.40.8-2 common error description library ii libgcrypt11 1.4.1-1 LGPL Crypto library - runtime libr ii libglib2.0-0 2.16.3-2 The GLib library of C routines ii libgnutls26 2.3.12-1 the GNU TLS library - runtime libr ii libgtk2.0-0 2.12.10-2 The GTK+ graphical user interface ii libkrb53 1.6.dfsg.3-2 MIT Kerberos runtime libraries ii libpango1.0-0 1.20.2-2 Layout and rendering of internatio ii libpcap0.8 0.9.8-5 system interface for user-level pa ii libpcre3 7.6-2 Perl 5 Compatible Regular Expressi ii libportaudio2 19+svn20071022-2 Portable audio I/O - shared librar ii wireshark-common 1.0.0-3 network traffic analyser (common f ii zlib1g 1:1.2.3.3.dfsg-12 compression library - runtime Versions of packages wireshark recommends: ii gksu 2.0.0-5 graphical frontend to su -- no debconf information
diff -Naur old/wireshark-1.0.0/epan/dissectors/Makefile.common new/wireshark-1.0.0/epan/dissectors/Makefile.common --- old/wireshark-1.0.0/epan/dissectors/Makefile.common 2008-03-29 19:26:32.000000000 +0200 +++ new/wireshark-1.0.0/epan/dissectors/Makefile.common 2008-04-03 18:54:29.000000000 +0300 @@ -714,6 +714,7 @@ packet-stat.c \ packet-stun.c \ packet-stun2.c \ + packet-zrtp.c \ packet-sua.c \ packet-symantec.c \ packet-synergy.c \ diff -Naur old/wireshark-1.0.0/epan/dissectors/Makefile.in new/wireshark-1.0.0/epan/dissectors/Makefile.in --- old/wireshark-1.0.0/epan/dissectors/Makefile.in 2008-03-29 19:27:16.000000000 +0200 +++ new/wireshark-1.0.0/epan/dissectors/Makefile.in 2008-04-03 18:57:05.000000000 +0300 @@ -682,6 +682,7 @@ libcleandissectors_la-packet-stat.lo \ libcleandissectors_la-packet-stun.lo \ libcleandissectors_la-packet-stun2.lo \ + libcleandissectors_la-packet-zrtp.lo \ libcleandissectors_la-packet-sua.lo \ libcleandissectors_la-packet-symantec.lo \ libcleandissectors_la-packet-synergy.lo \ @@ -1733,6 +1734,7 @@ packet-stat.c \ packet-stun.c \ packet-stun2.c \ + packet-zrtp.c \ packet-sua.c \ packet-symantec.c \ packet-synergy.c \ @@ -2810,6 +2812,7 @@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ [EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @@ -6892,6 +6895,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-stun2.lo `test -f 'packet-stun2.c' || echo '$(srcdir)/'`packet-stun2.c +libcleandissectors_la-packet-zrtp.lo: packet-zrtp.c [EMAIL PROTECTED]@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-zrtp.lo -MD -MP -MF $(DEPDIR)/libcleandissectors_la-packet-zrtp.Tpo -c -o libcleandissectors_la-packet-zrtp.lo `test -f 'packet-zrtp.c' || echo '$(srcdir)/'`packet-zrtp.c [EMAIL PROTECTED]@ mv -f $(DEPDIR)/libcleandissectors_la-packet-zrtp.Tpo $(DEPDIR)/libcleandissectors_la-packet-zrtp.Plo [EMAIL PROTECTED]@@am__fastdepCC_FALSE@ source='packet-zrtp.c' object='libcleandissectors_la-packet-zrtp.lo' libtool=yes @AMDEPBACKSLASH@ [EMAIL PROTECTED]@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ [EMAIL PROTECTED]@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-zrtp.lo `test -f 'packet-zrtp.c' || echo '$(srcdir)/'`packet-zrtp.c + libcleandissectors_la-packet-sua.lo: packet-sua.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-sua.lo -MD -MP -MF $(DEPDIR)/libcleandissectors_la-packet-sua.Tpo -c -o libcleandissectors_la-packet-sua.lo `test -f 'packet-sua.c' || echo '$(srcdir)/'`packet-sua.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libcleandissectors_la-packet-sua.Tpo $(DEPDIR)/libcleandissectors_la-packet-sua.Plo diff -Naur old/wireshark-1.0.0/epan/dissectors/packet-rtp.c new/wireshark-1.0.0/epan/dissectors/packet-rtp.c --- old/wireshark-1.0.0/epan/dissectors/packet-rtp.c 2008-03-29 19:26:31.000000000 +0200 +++ new/wireshark-1.0.0/epan/dissectors/packet-rtp.c 2008-04-03 18:49:28.000000000 +0300 @@ -139,6 +139,7 @@ static dissector_handle_t rtp_rfc2198_handle; static dissector_handle_t stun_handle; static dissector_handle_t t38_handle; +static dissector_handle_t zrtp_handle; static dissector_handle_t pkt_ccc_handle; @@ -469,6 +470,8 @@ unsigned int version; unsigned int payload_type; unsigned int offset = 0; + unsigned char zrtp_cookie[4]; + int i; /* This is a heuristic dissector, which means we get all the UDP * traffic not sent to a known dissector and not claimed by @@ -488,19 +491,30 @@ version = RTP_VERSION( octet1 ); if (version == 0) { - switch (global_rtp_version0_type) { - case RTP0_STUN: - call_dissector(stun_handle, tvb, pinfo, tree); - return TRUE; - - case RTP0_T38: - call_dissector(t38_handle, tvb, pinfo, tree); - return TRUE; + //Are We ZRTP + for (i=0;i<4;i++){ + zrtp_cookie[i] = tvb_get_guint8(tvb,4+i); + } + + if ((zrtp_cookie[0]==0x5a) && (zrtp_cookie[1]=0x52) && (zrtp_cookie[2]=0x54) && (zrtp_cookie[3]=0x50)) { + // if (zrtp_cookie == g_ntohl(0x5a525450)){ + call_dissector(zrtp_handle,tvb,pinfo,tree); + return TRUE; + } else { + switch (global_rtp_version0_type) { + case RTP0_STUN: + call_dissector(stun_handle, tvb, pinfo, tree); + return TRUE; + + case RTP0_T38: + call_dissector(t38_handle, tvb, pinfo, tree); + return TRUE; - case RTP0_INVALID: + case RTP0_INVALID: - default: - return FALSE; /* Unknown or unsupported version */ + default: + return FALSE; /* Unknown or unsupported version */ + } } } else if (version != 2) { /* Unknown or unsupported version */ @@ -942,6 +956,7 @@ struct srtp_info *srtp_info = NULL; unsigned int srtp_offset; tvbuff_t *newtvb = NULL; + guint8 zrtp_cookie[4]; /* Can tap up to 4 RTP packets within same packet */ static struct _rtp_info rtp_info_arr[4]; @@ -969,6 +984,15 @@ return; case RTP0_INVALID: + for (i=0;i<4;i++){ + zrtp_cookie[i] = tvb_get_guint8(tvb,4+i); + } + + if ((zrtp_cookie[0]==0x5a) && (zrtp_cookie[1]=0x52) && (zrtp_cookie[2]=0x54) && (zrtp_cookie[3]=0x50)) { + call_dissector(zrtp_handle,tvb,pinfo,tree); + return; + } + default: ; /* Unknown or unsupported version (let it fall through */ } @@ -1916,6 +1940,8 @@ data_handle = find_dissector("data"); stun_handle = find_dissector("stun"); t38_handle = find_dissector("t38"); + zrtp_handle = find_dissector("zrtp"); + /* * Register this dissector as one that can be selected by a * UDP port number. diff -Naur old/wireshark-1.0.0/epan/dissectors/packet-zrtp.c new/wireshark-1.0.0/epan/dissectors/packet-zrtp.c --- old/wireshark-1.0.0/epan/dissectors/packet-zrtp.c 1970-01-01 03:00:00.000000000 +0300 +++ new/wireshark-1.0.0/epan/dissectors/packet-zrtp.c 2008-06-04 19:16:03.000000000 +0300 @@ -0,0 +1,1403 @@ +/* packet-zrtp.c + * Routines for zrtp packet dissection + * IETF draft + * Copyright 2007, Sagar Pai <[EMAIL PROTECTED]> + * + * $Id: packet-zrtp.c 18608 2007-08-29 08:31:38Z sahlberg $ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <[EMAIL PROTECTED]> + * Copyright 1998 Gerald Combs + * + * Copied from packet-pop.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#include <string.h> +#include <glib.h> +#include <epan/packet.h> +#include <epan/strutil.h> + + +/* + RTP header +*/ +static int proto_zrtp = -1; +static int hf_zrtp_rtpversion = -1; +static int hf_zrtp_rtppadding = -1; +static int hf_zrtp_rtpextension = -1; +static int hf_zrtp_id = -1; +static int hf_zrtp_sequence = -1; +static int hf_zrtp_cookie = -1; +static int hf_zrtp_source_id = -1; + +/* + ZRTP header +*/ +static int hf_zrtp_signature=-1; +static int hf_zrtp_msg_length=-1; +static int hf_zrtp_msg_type = -1; +static int hf_zrtp_msg_version=-1; + +/* + Hello Data +*/ +static int hf_zrtp_msg_client_id=-1; +static int hf_zrtp_msg_zid=-1; +static int hf_zrtp_msg_initiator=-1; +static int hf_zrtp_msg_passive=-1; +static int hf_zrtp_msg_hash_count=-1; +static int hf_zrtp_msg_cipher_count=-1; +static int hf_zrtp_msg_authtag_count=-1; +static int hf_zrtp_msg_key_count=-1; +static int hf_zrtp_msg_sas_count=-1; +static int hf_zrtp_msg_hash=-1; +static int hf_zrtp_msg_cipher=-1; +static int hf_zrtp_msg_at=-1; +static int hf_zrtp_msg_keya=-1; +static int hf_zrtp_msg_sas=-1; +static int hf_zrtp_msg_hash_image=-1; + +/* + Commit data +*/ +static int hf_zrtp_msg_hvi = -1; +static int hf_zrtp_msg_nonce = -1; +static int hf_zrtp_msg_key_id = -1; + +/* + DHParts Data +*/ +static int hf_zrtp_msg_rs1ID=-1; +static int hf_zrtp_msg_rs2ID=-1; +static int hf_zrtp_msg_auxs=-1; +static int hf_zrtp_msg_pbxs=-1; + +/* + Confirm Data +*/ +static int hf_zrtp_msg_hmac=-1; +static int hf_zrtp_msg_cfb=-1; + +/* + Error Data +*/ +static int hf_zrtp_msg_error=-1; + +/* + Checksum Data +*/ +static int hf_zrtp_checksum=-1; + +/* + Sub-Tree +*/ +static gint ett_zrtp = -1; +static gint ett_zrtp_msg=-1; +static gint ett_zrtp_msg_data=-1; + +static gint ett_zrtp_msg_encrypted=-1; +static gint ett_zrtp_msg_pvr = -1; +static gint ett_zrtp_msg_hc = -1; +static gint ett_zrtp_msg_kc = -1; +static gint ett_zrtp_msg_ac = -1; +static gint ett_zrtp_msg_cc = -1; +static gint ett_zrtp_msg_sc = -1; + + +/* + Definitions +*/ +#define ZRTP_ERR_10 0x10 +#define ZRTP_ERR_20 0x20 +#define ZRTP_ERR_30 0x30 +#define ZRTP_ERR_40 0x40 +#define ZRTP_ERR_51 0x51 +#define ZRTP_ERR_52 0x52 +#define ZRTP_ERR_53 0x53 +#define ZRTP_ERR_54 0x54 +#define ZRTP_ERR_55 0x55 +#define ZRTP_ERR_61 0x61 +#define ZRTP_ERR_62 0x62 +#define ZRTP_ERR_63 0x63 +#define ZRTP_ERR_70 0x70 +#define ZRTP_ERR_80 0x80 +#define ZRTP_ERR_90 0x90 + +/* + Text for Display +*/ +typedef struct _value_zrtp_versions { + const gchar *version; +} value_zrtp_versions; + + + + +typedef struct _value_string_keyval +{ + const gchar *key; + const gchar *val; +} value_string_keyval; + + +const value_zrtp_versions valid_zrtp_versions[]= + { + {"0.85"}, + {NULL}, + }; + + +const value_string_keyval zrtp_hash_type_vals[] = +{ + { "S256", "SHA-256 Hash"}, + { NULL, NULL }, +}; +const value_string_keyval zrtp_cipher_type_vals[] = +{ + { "AES1", "AES-CM with 128 bit Keys"}, + { "AES3", "AES-CM with 256 bit Keys"}, + { NULL, NULL }, +}; + +const value_string_keyval zrtp_auth_tag_vals[] = +{ + { "HS32", "HMAC-SHA1 32 bit authentication tag"}, + { "HS80", "HMAC-SHA1 80 bit authentication tag"}, + { NULL, NULL }, +}; + +const value_string_keyval zrtp_sas_type_vals[] = +{ + { "B32 ", "Short authentication string using base 32"}, + { "B256", "Short authentication string using base 256"}, + { NULL, NULL }, +}; + +const value_string_keyval zrtp_key_agreement_vals[] = +{ + { "DH3k", "DH mode with p=3072 bit prime"}, + { "DH4k", "DH mode with p=4096 bit prime"}, + { "Prsh", "Preshared non-DH mode using shared secret"}, + { "EC25", "Elliptic Curve DH-256"}, + { "EC38", "Elliptic Curve DH-384"}, + { "EC52", "Elliptic Curve DH-521"}, + { "Mult", "Multistream mode"}, + { NULL, NULL }, +}; +const value_string zrtp_error_vals[] = + { + { ZRTP_ERR_10, "Malformed Packet (CRC OK but wrong structure)"}, + { ZRTP_ERR_20, "Critical Software Error"}, + { ZRTP_ERR_30, "Unsupported ZRTP version"}, + { ZRTP_ERR_40, "Hello Components mismatch"}, + { ZRTP_ERR_51, "Hash type unsupported"}, + { ZRTP_ERR_52, "Cipher type not supported"}, + { ZRTP_ERR_53, "Public key exchange not supported"}, + { ZRTP_ERR_54, "SRTP auth. tag not supported"}, + { ZRTP_ERR_55, "SAS scheme not supported"}, + { ZRTP_ERR_61, "DH Error: bad pv for initiator/responder value is (1,0,p-1)"}, + { ZRTP_ERR_62, "DH Error: bad hash commitment ( hvi != hashed data) "}, + { ZRTP_ERR_63, "Received relayed SAS from untrusted MiTM "}, + { ZRTP_ERR_70, "Auth. Error Bad Confirm Packet HMAC"}, + { ZRTP_ERR_80, "Nounce is reused"}, + { ZRTP_ERR_90, "Equal ZID's in Hello"}, + { 0, NULL}, + }; + +void +convert_to_hexstr(unsigned char *in,int inlen, unsigned char *out); +static void +dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) ; +static void +dissect_ErrorACK(packet_info *pinfo); +static void +dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree); +static void +dissect_ClearACK( packet_info *pinfo); +static void +dissect_Conf2ACK(packet_info *pinfo); +static void +dissect_HelloACK( packet_info *pinfo); +static void +dissect_GoClear(tvbuff_t *tvb,packet_info *pinfo, proto_tree *zrtp_tree); +static void +dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree); +static void +dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part); +static void +dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part); +static void +dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree); +static void +dissect_RelayACK(packet_info *pinfo); + +static const gchar * +key_to_val(const gchar *key,int keylen,const value_string_keyval *kv,const gchar *fmt); + + +static const gchar * + key_to_val(const gchar *key,int keylen,const value_string_keyval *kv,const gchar *fmt){ + int i=0; + while (kv[i].key) { + if (!strncmp(kv[i].key,key,keylen)){ + return(kv[i].val); + } + i++; + } + return ep_strdup_printf(fmt, key); + } + +static const gchar * + check_valid_version(const gchar *version){ + int i=0; + while (valid_zrtp_versions[i].version) { + if (!strncmp(valid_zrtp_versions[i].version,version,4)){ + return(valid_zrtp_versions[i].version); + } + i++; + } + return NULL; + } + + +static void +dissect_zrtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *zrtp_tree; + proto_tree *zrtp_msg_tree; + proto_tree *zrtp_msg_data_tree; + proto_item *ti; + gint offset = 0; + const guchar *line; + gint next_offset; + int linelen; + int checksum_offset; + guint8 val_b; + unsigned short val_s; + unsigned int val_l; + unsigned char message_type[9]; + unsigned int prime_offset=0; + unsigned int msg_offset=12; + unsigned char cookie_str[5]; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "zrtp"); + + /* + * Find the end of the first line. + * + * Note that "tvb_find_line_end()" will return a value that is + * not longer than what's in the buffer, so the "tvb_get_ptr()" + * call won#t throw an exception. + */ + linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); + line = tvb_get_ptr(tvb, offset, linelen); + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown zrtp Packet"); + } + + if (tree) { + ti = proto_tree_add_protocol_format(tree,proto_zrtp,tvb,0,-1,"zrtp protocol"); + zrtp_tree = proto_item_add_subtree(ti,ett_zrtp); + + val_b = tvb_get_guint8(tvb,prime_offset+0); + + ti=proto_tree_add_uint(zrtp_tree,hf_zrtp_rtpversion,tvb,prime_offset+0,1,((val_b>>6)&0x03)); + ti=proto_tree_add_boolean(zrtp_tree,hf_zrtp_rtppadding,tvb,prime_offset+0,1,val_b); + ti=proto_tree_add_boolean(zrtp_tree,hf_zrtp_rtpextension,tvb,prime_offset+0,1,val_b); + val_s = tvb_get_ntohs(tvb,prime_offset+2); + ti=proto_tree_add_uint(zrtp_tree,hf_zrtp_sequence,tvb,prime_offset+2,2,val_s); + + + + tvb_memcpy(tvb,(void *)cookie_str,prime_offset+4,4); + cookie_str[4]=0; + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_cookie,tvb,prime_offset+4,4,cookie_str); + + val_l= tvb_get_ntohl(tvb,prime_offset+8); + ti=proto_tree_add_uint(zrtp_tree,hf_zrtp_source_id,tvb,prime_offset+8,4,val_l); + + + linelen=tvb_reported_length_remaining(tvb,msg_offset); + checksum_offset=linelen -4; + ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,msg_offset,linelen-4,"Message"); + zrtp_msg_tree = proto_item_add_subtree(ti,ett_zrtp_msg); + + val_s = tvb_get_ntohs(tvb,msg_offset+0); + ti=proto_tree_add_uint(zrtp_msg_tree,hf_zrtp_signature,tvb,msg_offset+0,2,val_s); + + val_s = tvb_get_ntohs(tvb,msg_offset+2); + ti=proto_tree_add_uint(zrtp_msg_tree,hf_zrtp_msg_length,tvb,msg_offset+2,2,val_s); + + tvb_memcpy(tvb,(void *)message_type,msg_offset+4,8); + message_type[8]=0; + ti=proto_tree_add_string(zrtp_msg_tree,hf_zrtp_msg_type,tvb,msg_offset+4,8,message_type); + + linelen=tvb_reported_length_remaining(tvb,msg_offset+12); + if (!strncmp(message_type,"Hello ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_Hello(tvb,pinfo,zrtp_msg_data_tree); + } else if (!strncmp(message_type,"HelloACK",8)){ + dissect_HelloACK(pinfo); + } else if (!strncmp(message_type,"Commit ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_Commit(tvb,pinfo,zrtp_msg_data_tree); + } else if (!strncmp(message_type,"DHPart1 ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_DHPart(tvb,pinfo,zrtp_msg_data_tree,1); + } else if (!strncmp(message_type,"DHPart2 ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_DHPart(tvb,pinfo,zrtp_msg_data_tree,2); + } else if (!strncmp(message_type,"Confirm1",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_Confirm(tvb,pinfo,zrtp_msg_data_tree,1); + } else if (!strncmp(message_type,"Confirm2",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_Confirm(tvb,pinfo,zrtp_msg_data_tree,2); + } else if (!strncmp(message_type,"Conf2ACK",8)){ + dissect_Conf2ACK(pinfo); + } else if (!strncmp(message_type,"Error ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_Error(tvb,pinfo,zrtp_msg_data_tree); + } else if (!strncmp(message_type,"ErrorACK",8)){ + dissect_ErrorACK(pinfo); + } else if (!strncmp(message_type,"GoClear ",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_GoClear(tvb,pinfo,zrtp_msg_data_tree); + } else if (!strncmp(message_type,"ClearACK",8)){ + dissect_ClearACK(pinfo); + } else if (!strncmp(message_type,"SASrelay",8)){ + ti = proto_tree_add_protocol_format(zrtp_msg_tree,proto_zrtp,tvb,msg_offset+12,linelen-4,"Data"); + zrtp_msg_data_tree = proto_item_add_subtree(ti,ett_zrtp_msg_data); + dissect_SASrelay(tvb,pinfo,zrtp_msg_data_tree); + } else if (!strncmp(message_type,"RelayACK",8)){ + dissect_RelayACK(pinfo); + } + + val_l= tvb_get_ntohl(tvb,msg_offset+checksum_offset); + ti=proto_tree_add_uint(zrtp_tree,hf_zrtp_checksum,tvb,msg_offset+checksum_offset,4,val_l); + } +} +static void +dissect_ErrorACK(packet_info *pinfo) { + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "ErrorACK Packet"); + } +} + +static void +dissect_ClearACK(packet_info *pinfo) { + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "ClearACK Packet"); + } +} + +static void +dissect_RelayACK(packet_info *pinfo) { + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "RelayACK Packet"); + } +} + +static void +dissect_Conf2ACK(packet_info *pinfo) { + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Conf2ACK Packet"); + } +} +static void +dissect_HelloACK(packet_info *pinfo) { + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "HelloACK Packet"); + } +} +static void +dissect_GoClear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) { + proto_item *ti; + unsigned int data_offset=24; + unsigned char buffer[8]; + unsigned char buffer_display[48]; + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "GoClear Packet"); + } + + tvb_memcpy(tvb,(void *)buffer,data_offset+0,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,buffer_display); +} +static void +dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) { + proto_item *ti; + unsigned int data_offset=24; + unsigned int val_l; + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Error Packet"); + } + val_l= tvb_get_ntohl(tvb,data_offset); + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_error,tvb,data_offset,4,val_l, + "Error :%s",val_to_str(val_l,zrtp_error_vals,"Unknown Value 0x%x")); + +} + + +static void +dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part) { + proto_item *ti; + unsigned int data_offset=24; + unsigned char buffer[16]; + unsigned char buffer_display[64]; + proto_tree *zrtp_msg_encrypted_tree; + int linelen; + + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + if (part==1) + col_add_fstr(pinfo->cinfo, COL_INFO, "Confirm1 Packet"); + else if (part==2) + col_add_fstr(pinfo->cinfo, COL_INFO, "Confirm2 Packet"); + } + + tvb_memcpy(tvb,(void *)buffer,data_offset+0,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,buffer_display); + + tvb_memcpy(tvb,(void *)buffer,data_offset+8,16); + convert_to_hexstr(buffer,16,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_cfb,tvb,data_offset+8,16,buffer_display); + + + linelen=tvb_reported_length_remaining(tvb,data_offset+24); + ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+24,linelen-4,"encrypted Data"); + zrtp_msg_encrypted_tree = proto_item_add_subtree(ti,ett_zrtp_msg_encrypted); +} + +static void +dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) { + proto_item *ti; + unsigned int data_offset=24; + unsigned char buffer[16]; + unsigned char buffer_display[64]; + proto_tree *zrtp_msg_encrypted_tree; + int linelen; + + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "SASrelay Packet"); + } + + tvb_memcpy(tvb,(void *)buffer,data_offset+0,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+0,8,buffer_display); + + tvb_memcpy(tvb,(void *)buffer,data_offset+8,16); + convert_to_hexstr(buffer,16,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_cfb,tvb,data_offset+8,16,buffer_display); + + + linelen=tvb_reported_length_remaining(tvb,data_offset+24); + ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+24,linelen-4,"encrypted Data"); + zrtp_msg_encrypted_tree = proto_item_add_subtree(ti,ett_zrtp_msg_encrypted); +} + + +static void +dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree,int part) { + proto_item *ti; + unsigned int msg_offset=12; + unsigned int data_offset=56; + unsigned char hashimage[32]; + unsigned char hashimage_display[128]; + unsigned char buffer[8]; + unsigned char buffer_display[48]; + proto_tree *zrtp_msg_pvr_tree; + int linelen, pvr_len; + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + if (part==1) + col_add_fstr(pinfo->cinfo, COL_INFO, "DHPart1 Packet"); + else if (part==2) + col_add_fstr(pinfo->cinfo, COL_INFO, "DHPart2 Packet"); + } + + tvb_memcpy(tvb,(void *)hashimage,msg_offset+12,32); + convert_to_hexstr(hashimage,32,hashimage_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+12,32,hashimage_display); + + + tvb_memcpy(tvb,(void *)buffer,data_offset+0,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_rs1ID,tvb,data_offset+0,8,buffer_display); + + tvb_memcpy(tvb,(void *)buffer,data_offset+8,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_rs2ID,tvb,data_offset+8,8,buffer_display); + + tvb_memcpy(tvb,(void *)buffer,data_offset+16,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_auxs,tvb,data_offset+16,8,buffer_display); + + tvb_memcpy(tvb,(void *)buffer,data_offset+24,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_pbxs,tvb,data_offset+24,8,buffer_display); + + linelen=tvb_reported_length_remaining(tvb,data_offset+32); + pvr_len = linelen-8-4; + ti = proto_tree_add_protocol_format(zrtp_tree,proto_zrtp,tvb,data_offset+32,pvr_len,"pvr/nouncer Data"); + zrtp_msg_pvr_tree = proto_item_add_subtree(ti,ett_zrtp_msg_pvr); + + tvb_memcpy(tvb,(void *)buffer,data_offset+32+pvr_len,8); + convert_to_hexstr(buffer,8,buffer_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+32+pvr_len,8,buffer_display); + +} + +static void +dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) { + proto_item *ti; + unsigned int msg_offset=12; + unsigned int data_offset=56; + unsigned char buf_bin[32]; + unsigned char buf_display[128]; + unsigned char value[5]; + int key_type = 0; //0 - other type + //1 - "Mult" + //2 - "Prsh" + unsigned int offset; + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Commit Packet"); + } + + tvb_memcpy(tvb,(void *)buf_bin,msg_offset+12,32); + convert_to_hexstr(buf_bin,32,buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+12,32,buf_display); + + /* ZID */ + tvb_memcpy(tvb,(void *)buf_bin,data_offset+0,12); + convert_to_hexstr(buf_bin,12,buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_zid,tvb,data_offset+0,12,buf_display); + + tvb_memcpy(tvb,(void *)value,data_offset+12,4); + value[4]=0; + ti=proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_hash,tvb,data_offset+12,4,value, + "Hash: %s",key_to_val(value,4,zrtp_hash_type_vals,"Unknown hash type %s")); + + tvb_memcpy(tvb,(void *)value,data_offset+16,4); + value[4]=0; + ti=proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_cipher,tvb,data_offset+16,4,value,"Cipher: %s", + key_to_val(value,4,zrtp_cipher_type_vals,"Unknown cipher type %s")); + + + tvb_memcpy(tvb,(void *)value,data_offset+20,4); + value[4]=0; + ti=proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_at,tvb,data_offset+20,4,value, + "Auth tag: %s",key_to_val(value,4,zrtp_auth_tag_vals,"Unknown auth tag %s")); + + + tvb_memcpy(tvb,(void *)value,data_offset+24,4); + value[4]=0; + ti=proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_keya,tvb,data_offset+24,4,value, + "Key agreement: %s",key_to_val(value,4,zrtp_key_agreement_vals,"Unknown key agreement %s")); + + if(!strncmp(value, "Mult", 4)){ + key_type = 1; + }else if(!strncmp(value, "Prsh", 4)){ + key_type = 2; + } + + tvb_memcpy(tvb,(void *)value,data_offset+28,4); + value[4]=0; + ti=proto_tree_add_string_format(zrtp_tree,hf_zrtp_msg_sas,tvb,data_offset+28,4,value, + "Sas type: %s",key_to_val(value,4,zrtp_sas_type_vals,"Unknown sas type %s")); + + switch(key_type){ + case 1: //Mult + tvb_memcpy(tvb, (void*)buf_bin, data_offset+32, 16); + convert_to_hexstr(buf_bin, 16, buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_nonce,tvb,data_offset+32,16,buf_display); + + offset = 48; + break; + case 2: //Prsh + tvb_memcpy(tvb, (void*)buf_bin, data_offset+32, 16); + convert_to_hexstr(buf_bin, 16, buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_nonce,tvb,data_offset+32,16,buf_display); + + tvb_memcpy(tvb, (void*)buf_bin, data_offset+48, 8); + convert_to_hexstr(buf_bin, 8, buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_key_id,tvb,data_offset+48,8,buf_display); + + offset = 56; + break; + default: //other + tvb_memcpy(tvb, (void*)buf_bin, data_offset+32, 32); + convert_to_hexstr(buf_bin, 32, buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hvi,tvb,data_offset+32, 32, buf_display); + + offset = 64; + break; + } + + tvb_memcpy(tvb,(void *)buf_bin,data_offset+offset,8); + convert_to_hexstr(buf_bin,8,buf_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,data_offset+offset,8,buf_display); + +} + +static void +dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) { + proto_item *ti; + unsigned int msg_offset=12; + unsigned int data_offset=88; + guint8 val_b; + unsigned char zid[12]; + unsigned char zid_display[48]; + unsigned char client_id[16+1]; + unsigned char hashimage[32]; + unsigned char hashimage_display[128]; + unsigned char hmac[8]; + unsigned char hmac_display[32]; + unsigned int i; + unsigned int run_offset; + unsigned int hc,cc,ac,kc,sc; + unsigned int vhc,vcc,vac,vkc,vsc; + unsigned char value[5]; + unsigned char version_str[5]; + proto_tree *tmp_tree; + + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Hello Packet"); + } + + + tvb_memcpy(tvb,version_str,msg_offset+12,4); + version_str[4]=0; + if (check_valid_version(version_str) == NULL){ + if (check_col(pinfo->cinfo, COL_INFO)) { + /* + * Put the first line from the buffer into the summary + * if it's a POP request or reply (but leave out the + * line terminator). + * Otherwise, just call it a continuation. + */ + col_add_fstr(pinfo->cinfo, COL_INFO, "Invalid Wireshark version for dissecting this version of ZRTP protocol. Download current patch"); + } + } + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_version,tvb,msg_offset+12,4,version_str); + // val_l= tvb_get_ntohl(tvb,msg_offset+12); + //ti=proto_tree_add_uint(zrtp_tree,hf_zrtp_msg_version,tvb,msg_offset+12,4,val_l); + + tvb_memcpy(tvb,client_id,msg_offset+16,16); + client_id[16]=0; + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_client_id,tvb,msg_offset+16,16,client_id); + + tvb_memcpy(tvb,(void *)hashimage,msg_offset+32,32); + convert_to_hexstr(hashimage,32,hashimage_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hash_image,tvb,msg_offset+32,32,hashimage_display); + + + tvb_memcpy(tvb,(void *)zid,msg_offset+64,12); + convert_to_hexstr(zid,12,zid_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_zid,tvb,msg_offset+64,12,zid_display); + + + val_b = tvb_get_guint8(tvb,data_offset+0); + ti=proto_tree_add_boolean(zrtp_tree,hf_zrtp_msg_passive,tvb,data_offset+0,1,val_b); + + val_b = tvb_get_guint8(tvb,data_offset+1); + hc = val_b & 0x0F; + vhc=hc; + + val_b = tvb_get_guint8(tvb,data_offset+2); + cc = val_b & 0xF0; + ac = val_b & 0x0F; + vcc = cc >> 4; + vac = ac; + + val_b = tvb_get_guint8(tvb,data_offset+3); + kc = val_b & 0xF0; + sc = val_b & 0x0F; + vkc = kc >> 4; + vsc = sc; + + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_hash_count,tvb,data_offset+1,1,hc,"Hash type count = %d",vhc); + tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_hc); + run_offset = data_offset+4; + for(i=0;i<vhc;i++){ + tvb_memcpy(tvb,(void *)value,run_offset,4); + value[4]=0; + ti=proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_hash,tvb,run_offset,4,value, + "Hash[%d]: %s",i,key_to_val(value,4,zrtp_hash_type_vals,"Unknown hash type %s")); + run_offset+=4; + } + + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_cipher_count,tvb,data_offset+2,1,cc,"Cipher type count = %d",vcc); + tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_cc); + for(i=0;i<vcc;i++){ + tvb_memcpy(tvb,(void *)value,run_offset,4); + value[4]=0; + ti=proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_cipher,tvb,run_offset,4,value,"Cipher[%d]: %s",i, + key_to_val(value,4,zrtp_cipher_type_vals,"Unknown cipher type %s")); + run_offset+=4; + } + + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_authtag_count,tvb,data_offset+2,1,ac,"Auth tag count = %d",vac); + tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_ac); + for(i=0;i<vac;i++){ + tvb_memcpy(tvb,(void *)value,run_offset,4); + value[4]=0; + ti=proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_at,tvb,run_offset,4,value, + "Auth tag[%d]: %s",i,key_to_val(value,4,zrtp_auth_tag_vals,"Unknown auth tag %s")); + run_offset+=4; + } + + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_key_count,tvb,data_offset+3,1,kc,"Key agreement type count = %d",vkc); + tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_kc); + for(i=0;i<vkc;i++){ + tvb_memcpy(tvb,(void *)value,run_offset,4); + value[4]=0; + ti=proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_keya,tvb,run_offset,4,value, + "Key agreement[%d]: %s",i,key_to_val(value,4,zrtp_key_agreement_vals,"Unknown key agreement %s")); + run_offset+=4; + } + + ti=proto_tree_add_uint_format(zrtp_tree,hf_zrtp_msg_sas_count,tvb,data_offset+3,1,sc,"Sas type count = %d",vsc); + tmp_tree = proto_item_add_subtree(ti,ett_zrtp_msg_sc); + for(i=0;i<vsc;i++){ + tvb_memcpy(tvb,(void *)value,run_offset,4); + value[4]=0; + ti=proto_tree_add_string_format(tmp_tree,hf_zrtp_msg_sas,tvb,run_offset,4,value, + "Sas type[%d]: %s",i,key_to_val(value,4,zrtp_sas_type_vals,"Unknown sas type %s")); + run_offset+=4; + } + + tvb_memcpy(tvb,(void *)hmac,run_offset,8); + convert_to_hexstr(hmac,8,hmac_display); + ti=proto_tree_add_string(zrtp_tree,hf_zrtp_msg_hmac,tvb,run_offset,8,hmac_display); +} + +void +convert_to_hexstr(unsigned char *in,int inlen, unsigned char *out) +{ + int i; + unsigned char *ptr = out; + for (i=0;i<inlen;i++){ + sprintf(ptr,":%02x",in[i]); + ptr = ptr+3; + *ptr=0; + } + return; +} + +void +proto_register_zrtp(void) +{ + static hf_register_info hf[] = { + {&hf_zrtp_rtpversion, + { + "RTP Version", + "zrtp.rtpversion", + FT_UINT8, + BASE_DEC, + NULL, + 0xC0, + "", HFILL + } + }, + + {&hf_zrtp_rtppadding, + { + "RTP padding", + "zrtp.rtppadding", + FT_BOOLEAN, + 8, + NULL, + 0x20, + "", HFILL + } + }, + + {&hf_zrtp_rtpextension, + { + "RTP Extension", + "zrtp.rtpextension", + FT_BOOLEAN, + 8, + NULL, + 0x10, + "", HFILL + } + }, + + {&hf_zrtp_id, + { + "ID", + "zrtp.id", + FT_UINT8, + BASE_HEX, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_sequence, + { + "Sequence", + "zrtp.sequence", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_cookie, + { + "Magic Cookie", + "zrtp.cookie", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_source_id, + { + "Source Identifier", + "zrtp.source_id", + FT_UINT32, + BASE_HEX, + NULL, + 0x0, + "", HFILL + } + }, + + //Message Types + {&hf_zrtp_signature, + { + "Signature", + "zrtp.signature", + FT_UINT16, + BASE_HEX, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_length, + { + "Length", + "zrtp.length", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_type, + { + "Type", + "zrtp.type", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + //Message Hello +#if 0 + {&hf_zrtp_msg_version, + { + "zrtp protocol version", + "zrtp.version", + FT_UINT32, + BASE_HEX, + NULL, + 0x0, + "", HFILL + } + }, +#endif + + {&hf_zrtp_msg_version, + { + "zrtp protocol version", + "zrtp.version", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_client_id, + { + "Client Identifier", + "zrtp.client_source_id", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_hash_image, + { + "Hash Image", + "zrtp.hash_image", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_zid, + { + "ZID", + "zrtp.zid", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_initiator, + { + "Initiator", + "zrtp.initiator", + FT_BOOLEAN, + 8, + NULL, + 0x20, + "", HFILL + } + }, + + {&hf_zrtp_msg_passive, + { + "Passive", + "zrtp.passive", + FT_BOOLEAN, + 8, + NULL, + 0x10, + "", HFILL + } + }, + + {&hf_zrtp_msg_hash_count, + { + "Hash Count", + "zrtp.hc", + FT_UINT8, + BASE_DEC, + NULL, + 0x0F, + "", HFILL + } + }, + + {&hf_zrtp_msg_cipher_count, + { + "Cipher Count", + "zrtp.cc", + FT_UINT8, + BASE_DEC, + NULL, + 0xF0, + "", HFILL + } + }, + + {&hf_zrtp_msg_authtag_count, + { + "Auth tag Count", + "zrtp.ac", + FT_UINT8, + BASE_DEC, + NULL, + 0x0F, + "", HFILL + } + }, + + {&hf_zrtp_msg_key_count, + { + "Key Agreement Count", + "zrtp.kc", + FT_UINT8, + BASE_DEC, + NULL, + 0xF0, + "", HFILL + } + }, + + {&hf_zrtp_msg_sas_count, + { + "SAS Count", + "zrtp.sc", + FT_UINT8, + BASE_DEC, + NULL, + 0x0F, + "", HFILL + } + }, + + {&hf_zrtp_msg_hash, + { + "Hash", + "zrtp.hash", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_cipher, + { + "Cipher", + "zrtp.cipher", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_at, + { + "AT", + "zrtp.at", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_keya, + { + "Key Agreement", + "zrtp.keya", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_sas, + { + "SAS", + "zrtp.sas", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_rs1ID, + { + "rs1ID", + "zrtp.rs1id", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_rs2ID, + { + "rs2ID", + "zrtp.rs2id", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_auxs, + { + "auxs", + "zrtp.auxs", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_pbxs, + { + "pbxs", + "zrtp.pbxs", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_hmac, + { + "HMAC", + "zrtp.hmac", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_cfb, + { + "CFB", + "zrtp.cfb", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_error, + { + "Error", + "zrtp.error", + FT_UINT32, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_checksum, + { + "Checksum", + "zrtp.checksum", + FT_UINT32, + BASE_HEX, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_hvi, + { + "hvi", + "zrtp.hvi", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_nonce, + { + "nonce", + "zrtp.nonce", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + {&hf_zrtp_msg_key_id, + { + "key ID", + "zrtp.key_id", + FT_STRING, + BASE_DEC, + NULL, + 0x0, + "", HFILL + } + }, + + }; + + static gint *ett[] = { + &ett_zrtp, + &ett_zrtp_msg, + &ett_zrtp_msg_data, + &ett_zrtp_msg_encrypted, + &ett_zrtp_msg_pvr, + &ett_zrtp_msg_hc, + &ett_zrtp_msg_kc , + &ett_zrtp_msg_ac , + &ett_zrtp_msg_cc , + &ett_zrtp_msg_sc , + }; + + proto_zrtp = proto_register_protocol("zrtp", "zrtp", "zrtp"); + proto_register_field_array(proto_zrtp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("zrtp", dissect_zrtp, proto_zrtp); +} + +void +proto_reg_handoff_zrtp(void) +{ + static gboolean inited = FALSE; + + if (!inited){ + dissector_handle_t zrtp_handle; + + zrtp_handle = create_dissector_handle(dissect_zrtp, proto_zrtp); + dissector_add_handle("udp.port", zrtp_handle); + //data_handle = find_dissector("data"); + inited=TRUE; + } +} diff -Naur old/wireshark-1.0.0/epan/dissectors/register.c new/wireshark-1.0.0/epan/dissectors/register.c --- old/wireshark-1.0.0/epan/dissectors/register.c 2008-03-29 19:28:04.000000000 +0200 +++ new/wireshark-1.0.0/epan/dissectors/register.c 2008-06-04 19:16:14.000000000 +0300 @@ -764,6 +764,7 @@ {extern void proto_register_ypserv (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ypserv", client_data); proto_register_ypserv ();} {extern void proto_register_ypxfr (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ypxfr", client_data); proto_register_ypxfr ();} {extern void proto_register_zebra (void); if(cb) (*cb)(RA_REGISTER, "proto_register_zebra", client_data); proto_register_zebra ();} + {extern void proto_register_zrtp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_zrtp", client_data); proto_register_zrtp ();} } void @@ -1492,10 +1493,11 @@ {extern void proto_reg_handoff_ypserv (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ypserv", client_data); proto_reg_handoff_ypserv ();} {extern void proto_reg_handoff_ypxfr (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ypxfr", client_data); proto_reg_handoff_ypxfr ();} {extern void proto_reg_handoff_zebra (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_zebra", client_data); proto_reg_handoff_zebra ();} + {extern void proto_reg_handoff_zrtp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_zrtp", client_data); proto_reg_handoff_zrtp ();} } gulong register_count(void) { - return 759 + 723; + return 760 + 724; }