From 428f280a405916f676758bb1cbf6137402e0df24 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 18 Mar 2002 00:45:11 +0000 Subject: Skinny Client Control Protocol enhancements, from Paul E. Erkkila. svn path=/trunk/; revision=4967 --- packet-skinny.c | 818 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 742 insertions(+), 76 deletions(-) (limited to 'packet-skinny.c') diff --git a/packet-skinny.c b/packet-skinny.c index c6869e0fda..78fa86c092 100644 --- a/packet-skinny.c +++ b/packet-skinny.c @@ -4,10 +4,12 @@ * (The "D-Channel"-Protocol for Cisco Systems' IP-Phones) * Copyright 2001, Joerg Mayer (email: see AUTHORS file) * + * Further decode work by pee@erkkila.org + * * This file is based on packet-aim.c, which is * Copyright 2000, Ralf Hoelzer * - * $Id: packet-skinny.c,v 1.9 2002/01/21 23:35:32 guy Exp $ + * $Id: packet-skinny.c,v 1.10 2002/03/18 00:45:10 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -36,31 +38,9 @@ # include "config.h" #endif -/* REMOVE? - * #include - * #include - * #include - * #include - * - * #ifdef HAVE_SYS_TYPES_H - * # include - * #endif - * - * #ifdef HAVE_NETINET_IN_H - * # include - * #endif - * - * #include // already in packet.h -> tvbuff.h - * - * #ifdef NEED_SNPRINTF_H - * # include "snprintf.h" - * #endif - */ +#include #include -/* REMOVE? - * #include - */ #define TCP_PORT_SKINNY 2000 @@ -106,6 +86,8 @@ static const value_string message_id[] = { {0x0027, "UnregisterMessage"}, {0x0028, "SoftKeyEventMessage"}, {0x0029, "RegisterTokenReq"}, + {0x002B, "unknownClientMessage1"}, + {0x002D, "unknownClientMessage2"}, /* Callmanager -> Station */ /* 0x0000, 0x0003? */ @@ -160,6 +142,7 @@ static const value_string message_id[] = { {0x0119, "BackSpaceReqMessage"}, {0x011A, "RegisterTokenAck"}, {0x011B, "RegisterTokenReject"}, + {0x011D, "unknownForwardMessage1"}, {0 , NULL} /* needed for value_string automagic */ }; @@ -171,6 +154,30 @@ static int proto_skinny = -1; static int hf_skinny_data_length = -1; static int hf_skinny_reserved = -1; static int hf_skinny_messageid = -1; +static int hf_skinny_callIdentifier = -1; +static int hf_skinny_packetsSent = -1; +static int hf_skinny_octetsSent = -1; +static int hf_skinny_packetsRecv = -1; +static int hf_skinny_octetsRecv = -1; +static int hf_skinny_packetsLost = -1; +static int hf_skinny_latency = -1; +static int hf_skinny_jitter = -1; +static int hf_skinny_extension = -1; +static int hf_skinny_displayMessage = -1; +static int hf_skinny_timeStamp = -1; +static int hf_skinny_unknown = -1; +static int hf_skinny_ipDest = -1; +static int hf_skinny_ipSrc = -1; +static int hf_skinny_dateYear = -1; +static int hf_skinny_dateMonth = -1; +static int hf_skinny_dateDay = -1; +static int hf_skinny_dateHour = -1; +static int hf_skinny_dateMinute = -1; +static int hf_skinny_destPort = -1; +static int hf_skinny_srcPort = -1; +static int hf_skinny_softKeyNumber = -1; +static int hf_skinny_line = -1; +static int hf_skinny_dialedDigit = -1; /* Initialize the subtree pointers */ static gint ett_skinny = -1; @@ -183,26 +190,72 @@ static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* The general structure of a packet: {IP-Header|TCP-Header|n*SKINNY} * SKINNY-Packet: {Header(Size, Reserved)|Data(MessageID, Message-Data)} */ + + /* Header fields */ guint32 hdr_data_length; guint32 hdr_reserved; guint32 data_messageid; gchar *messageid_str; - guint32 data_size; + /* guint32 data_size; */ -/* Set up structures we will need to add the protocol subtree and manage it */ - proto_item *ti; - proto_tree *skinny_tree = NULL; + guint32 offset = 0; -/* check, if this is really an SKINNY packet, they start with a length + 0 */ + guint32 callIdentifier = 0; + guint32 packetsSent = 0; + guint32 octetsSent = 0; + guint32 packetsRecv = 0; + guint32 octetsRecv = 0; + guint32 packetsLost = 0; + guint32 latency = 0; + guint32 jitter = 0; + guint32 timeStamp = 0; + guint32 ipSrc = 0; + guint32 ipDest = 0; + guint32 year = 0; + guint32 month = 0; + guint32 day = 0; + guint32 hour = 0; + guint32 minute = 0; + guint32 destPort = 0; + guint32 srcPort = 0; + guint32 softKeyNumber = 0; + guint32 line = 0; + guint32 dialedDigit = 0; -/* get relevant header information */ + guint32 unknown1 = 0; + guint32 unknown2 = 0; + guint32 unknown3 = 0; + guint32 unknown4 = 0; + guint32 unknown5 = 0; + guint32 unknown6 = 0; + guint32 unknown7 = 0; + guint32 unknown8 = 0; + guint32 unknown9 = 0; + guint32 unknown10 = 0; + guint32 unknown11 = 0; + + int extensionLength = 10; + int displayLength = 100; + char extension[extensionLength]; + char displayMessage[displayLength]; + int softKeyLoop = 0; + + /* Set up structures we will need to add the protocol subtree and manage it */ + proto_item *ti; + proto_tree *skinny_tree = NULL; + + /* check, if this is really an SKINNY packet, they start with a length + 0 */ + + /* get relevant header information */ hdr_data_length = tvb_get_letohl(tvb, 0); hdr_reserved = tvb_get_letohl(tvb, 4); data_messageid = tvb_get_letohl(tvb, 8); - data_size = MIN(8+hdr_data_length, tvb_length(tvb)) - 0xC; + + /* data_size = MIN(8+hdr_data_length, tvb_length(tvb)) - 0xC; */ + /* hdr_data_length > 1024 is just a heuristic. Better values/checks welcome */ if (hdr_data_length < 4 || hdr_data_length > 1024 || hdr_reserved != 0) { /* Not an SKINNY packet, just happened to use the same port */ @@ -211,79 +264,692 @@ static void dissect_skinny(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } /* Make entries in Protocol column and Info column on summary display */ - if (check_col(pinfo->cinfo, COL_PROTOCOL)) + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "SKINNY"); - - if (check_col(pinfo->cinfo, COL_INFO)) - col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol"); - - /* In the interest of speed, if "tree" is NULL, don't do any work not - * necessary to generate protocol tree items. */ - if (tree) { - ti = proto_tree_add_item(tree, proto_skinny, tvb, 0, - data_size + 0xC, FALSE); - skinny_tree = proto_item_add_subtree(ti, ett_skinny); - proto_tree_add_uint(skinny_tree, hf_skinny_data_length, tvb, - 0, 4, hdr_data_length); - proto_tree_add_uint(skinny_tree, hf_skinny_reserved, tvb, - 4, 4, hdr_reserved); } - messageid_str = val_to_str(data_messageid, message_id, "0x%08X (Unknown)"); + if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_str(pinfo->cinfo, COL_INFO, messageid_str); + col_set_str(pinfo->cinfo, COL_INFO, "Skinny Client Control Protocol"); } - if (tree) { - proto_tree_add_uint(skinny_tree, hf_skinny_messageid, tvb, - 8, 4, data_messageid /* FIXME: add messageid_str */ ); - if (data_size > 0) { - proto_tree_add_protocol_format(skinny_tree, proto_skinny, tvb, - 0xC, - data_size, "Data (%d byte%s)", data_size, - plurality(data_size, "", "s")); + + while (tvb_reported_length_remaining(tvb, offset) != 0) { + + hdr_data_length = tvb_get_letohl(tvb, offset); + hdr_reserved = tvb_get_letohl(tvb, offset+4); + data_messageid = tvb_get_letohl(tvb, offset+8); + + /* In the interest of speed, if "tree" is NULL, don't do any work not + * necessary to generate protocol tree items. */ + if (tree) { + ti = proto_tree_add_item(tree, proto_skinny, tvb, offset, hdr_data_length+8, FALSE); + skinny_tree = proto_item_add_subtree(ti, ett_skinny); + proto_tree_add_uint(skinny_tree, hf_skinny_data_length, tvb, offset, 4, hdr_data_length); + proto_tree_add_uint(skinny_tree, hf_skinny_reserved, tvb, offset+4, 4, hdr_reserved); } - } - /*FIXME: call dissect_skinny recursively until all data is used up */ + messageid_str = val_to_str(data_messageid, message_id, "0x%08X (Unknown)"); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_str(pinfo->cinfo, COL_INFO, messageid_str); + } + + if (tree) { + proto_tree_add_uint(skinny_tree, hf_skinny_messageid, tvb,offset+8, 4, data_messageid ); + } + + if (tree) { + switch(data_messageid) { + + /* cases that do not need to be decoded */ + case 0x0 : /* keepAlive */ + break; + + case 0x6 : /* offHook */ + break; + + case 0x7 : /* onHook */ + break; + + case 0xd : /* timeDateReqMessage */ + break; + + case 0xe : /* buttoneTemplateReqMessage */ + break; + + case 0x25 : /* softKeySetReqMessage */ + break; + + case 0x27 : /* unregisterMessage */ + break; + + case 0x28 : /* softKeyEventMessage */ + break; + + case 0x83 : /* stopTone */ + break; + + case 0x9b : /* capabilitiesReqMessage */ + break; + + case 0x100 : /* keepAliveAck */ + break; + + /* + ** cases that need decode + ** + */ + + case 0x1 : /* register message */ + memset(displayMessage, '\0', displayLength); + tvb_memcpy(tvb, displayMessage, offset+12, 15); /* Note hack on field size ^_^ */ + unknown1 = tvb_get_letohl(tvb, offset+28); + unknown2 = tvb_get_letohl(tvb, offset+32); + tvb_memcpy(tvb, (guint8 *)&ipSrc, offset+36,4); + unknown4 = tvb_get_letohl(tvb, offset+40); + unknown5 = tvb_get_letohl(tvb, offset+44); + unknown6 = tvb_get_letohl(tvb, offset+48); + unknown7 = tvb_get_letohl(tvb, offset+52); + + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, strlen(displayMessage), displayMessage); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+28, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown2); + proto_tree_add_ipv4(skinny_tree, hf_skinny_ipSrc, tvb, offset+36, 4, ipSrc); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown4); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown5); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+48, 4, unknown6); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+52, 4, unknown7); + break; + + case 0x2 : /* ipPortMessage */ + srcPort = tvb_get_ntohs(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_srcPort, tvb, offset+12, 4, srcPort); + break; + + case 0x3 : /* keyPadButtonMessage */ + dialedDigit = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_dialedDigit, tvb, offset+12, 4, dialedDigit); + break; + + case 0x5 : + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + break; + + case 0xa : /* speedDialStatReqMessage */ + line = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_line, tvb, offset+12, 4, line); + break; + + case 0xb : /* LineStatReqMessage */ + line = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_line, tvb, offset+12, 4, line); + break; + + case 0x10 : /* capabilitiesResMessage ===== LOTS to decode here, check jtapi */ + break; + + case 0x20 : /* alarmMessage */ + unknown1 = tvb_get_letohl(tvb,offset+12); + memset(displayMessage, '\0', displayLength); + tvb_memcpy(tvb, displayMessage, offset+16, 76); /* Note hack on field size ^_^ */ + unknown2 = tvb_get_letohl(tvb, offset+92); + unknown3 = tvb_get_letohl(tvb, offset+96); + unknown4 = tvb_get_letohl(tvb, offset+100); + tvb_memcpy(tvb, (guint8 *)&ipSrc, offset+100,4); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, strlen(displayMessage), displayMessage); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+92, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+96, 4, unknown3); + proto_tree_add_ipv4(skinny_tree, hf_skinny_ipSrc, tvb, offset+100, 4, ipSrc); + break; + + case 0x22 : + unknown1 = tvb_get_letohl(tvb, offset+12); + tvb_memcpy(tvb, (guint8 *)&ipSrc, offset+16,4); + srcPort = tvb_get_letohl(tvb, offset+20); + unknown3 = tvb_get_letohl(tvb, offset+24); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_ipv4(skinny_tree, hf_skinny_ipSrc, tvb, offset+16, 4, ipSrc); + proto_tree_add_uint(skinny_tree, hf_skinny_srcPort, tvb, offset+20, 4, srcPort); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+24, 4, unknown3); + break; + + case 0x26 : /* softKeyEventMessage */ + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + callIdentifier = tvb_get_letohl(tvb, offset+20); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, callIdentifier); + break; + + case 0x2b : /* unknownClientMessage1 */ + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x2d : /* unknownClientMessage2 */ + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x81 : /* registerAck */ + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + unknown3 = tvb_get_letohl(tvb, offset+20); + unknown4 = tvb_get_letohl(tvb, offset+24); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown3); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+24, 4, unknown4); + break; + + case 0x82 : /* startTone */ + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x85 : + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x86 : + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + unknown3 = tvb_get_letohl(tvb, offset+20); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown3); + break; + + case 0x88 : + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x8a : + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + tvb_memcpy(tvb, (guint8 *)&ipDest, offset+20,4); + destPort = tvb_get_letohl(tvb, offset+24); + unknown5 = tvb_get_letohl(tvb, offset+28); + unknown6 = tvb_get_letohl(tvb, offset+32); + unknown7 = tvb_get_letohl(tvb, offset+36); + unknown8 = tvb_get_letohl(tvb, offset+40); + unknown9 = tvb_get_letohl(tvb, offset+44); + unknown10 = tvb_get_letohl(tvb, offset+48); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_ipv4(skinny_tree, hf_skinny_ipDest, tvb, offset+20, 4, ipDest); + proto_tree_add_uint(skinny_tree, hf_skinny_destPort,tvb, offset+24, 4, destPort); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+28, 4, unknown5); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown6); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown7); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown8); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown9); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+48, 4, unknown10); + break; + + case 0x8b : /* stopMediaTransmission */ + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + break; + + case 0x91 : /* speedDialStatMessage */ + line = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_line, tvb, offset+12, 4, line); + break; + + case 0x92 : /* lineStatMessage */ + line = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_line, tvb, offset+12, 4, line); + break; + + case 0x94 : + year = tvb_get_letohl(tvb, offset+12); + month = tvb_get_letohl(tvb, offset+16); + unknown1 = tvb_get_letohl(tvb, offset+20); + day = tvb_get_letohl(tvb, offset+24); + hour = tvb_get_letohl(tvb, offset+28); + minute = tvb_get_letohl(tvb, offset+32); + unknown2 = tvb_get_letohl(tvb, offset+36); + unknown3 = tvb_get_letohl(tvb, offset+40); + timeStamp = tvb_get_letohl(tvb, offset+44); + + proto_tree_add_uint(skinny_tree, hf_skinny_dateYear, tvb, offset+12, 4, year); + proto_tree_add_uint(skinny_tree, hf_skinny_dateMonth, tvb, offset+16, 4, month); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_dateDay, tvb, offset+24, 4, day); + proto_tree_add_uint(skinny_tree, hf_skinny_dateHour, tvb, offset+28, 4, hour); + proto_tree_add_uint(skinny_tree, hf_skinny_dateMinute,tvb, offset+32, 4, minute); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown3); + proto_tree_add_uint(skinny_tree, hf_skinny_timeStamp, tvb, offset+44, 4, timeStamp); + break; + + case 0x97 : /* buttonTemplateMessage === LOTS here check jtapi for hints */ + break; + + case 0x99 : /* displayTextMessage */ + memset(displayMessage, '\0', displayLength); + tvb_memcpy(tvb, displayMessage, offset+12, 32); + unknown1 = tvb_get_letohl(tvb, offset+44); + + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+12, strlen(displayMessage), displayMessage); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown1); + break; + + case 0x9f : /* reset */ + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x106 : /* closeReceiveChannel */ + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + break; + + case 0x105 : + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + unknown3 = tvb_get_letohl(tvb, offset+20); + unknown4 = tvb_get_letohl(tvb, offset+24); + unknown5 = tvb_get_letohl(tvb, offset+28); + unknown6 = tvb_get_letohl(tvb, offset+32); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown3); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+24, 4, unknown4); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+28, 4, unknown5); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown6); + break; + + case 0x107 : + memset(extension, '\0', extensionLength); + tvb_get_nstringz0(tvb, offset+12, extensionLength, extension); + callIdentifier = tvb_get_letohl(tvb, offset+36); + + proto_tree_add_string(skinny_tree, hf_skinny_extension, tvb, offset+12, strlen(extension), extension); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+36, 4, callIdentifier); + break; + + case 0x108 : /* softkeyTemplateResMessage == Jtapi again :P, can decode some*/ + unknown1 = tvb_get_letohl(tvb, offset+12); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + + unknown2 = tvb_get_letohl(tvb, offset+16); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + + unknown3 = tvb_get_letohl(tvb, offset+20); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown3); + + softKeyNumber = 0; + softKeyLoop = 0; + /* NOTE ***** This loop *MIGHT* need to revolve around the unknow1/2 properties, not sure though */ + while (softKeyLoop < 18) { + int softOffset = offset+(softKeyLoop*20); + memset(displayMessage, '\0', displayLength); + tvb_memcpy(tvb, displayMessage, softOffset+24, 16); + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, softOffset+24, strlen(displayMessage), displayMessage); + softKeyNumber = tvb_get_letohl(tvb, softOffset+40); + proto_tree_add_uint(skinny_tree, hf_skinny_softKeyNumber, tvb, softOffset+40, 4, softKeyNumber); + + softKeyLoop++; + } + + break; + + case 0x110 : + unknown1 = tvb_get_letohl(tvb, offset+12); + callIdentifier = tvb_get_letohl(tvb, offset+16); + unknown2 = tvb_get_letohl(tvb, offset+20); + unknown3 = tvb_get_letohl(tvb, offset+24); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, callIdentifier); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+20, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+24, 4, unknown3); + break; + + case 0x111 : + unknown1 = tvb_get_letohl(tvb, offset+12); + unknown2 = tvb_get_letohl(tvb, offset+16); + callIdentifier = tvb_get_letohl(tvb, offset+20); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+16, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+20, 4, callIdentifier); + break; + + case 0x112 : + memset(displayMessage,'\0',displayLength); + unknown1 = tvb_get_letohl(tvb, offset+12); + tvb_get_nstringz0(tvb,offset+16,displayLength, displayMessage); + unknown2 = tvb_get_letohl(tvb, offset+48); + callIdentifier = tvb_get_letohl(tvb, offset+52); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, strlen(displayMessage), displayMessage); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+48, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+52, 4, callIdentifier); + break; + + case 0x113: + callIdentifier = tvb_get_letohl(tvb, offset+16); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+16, 4, callIdentifier); + break; + + case 0x114 : + + unknown1 = tvb_get_letohl(tvb, offset+12); + memset(displayMessage,'\0',displayLength); + tvb_memcpy(tvb, displayMessage, offset+16, 16); + unknown2 = tvb_get_letohl(tvb, offset+32); + unknown3 = tvb_get_letohl(tvb, offset+36); + unknown4 = tvb_get_letohl(tvb, offset+40); + unknown5 = tvb_get_letohl(tvb, offset+44); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + proto_tree_add_string(skinny_tree, hf_skinny_displayMessage, tvb, offset+16, strlen(displayMessage), displayMessage); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+32, 4, unknown2); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown3); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+40, 4, unknown4); + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+44, 4, unknown5); + break; + + case 0x116 : + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x118 : /* unregisterAckMessage */ + unknown1 = tvb_get_letohl(tvb, offset+12); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+12, 4, unknown1); + break; + + case 0x0023 : + + memset(extension,'\0', extensionLength); + tvb_get_nstringz0(tvb,offset+12,extensionLength,extension); + callIdentifier = tvb_get_letohl(tvb,offset+36); + packetsSent = tvb_get_letohl(tvb,offset+44); + octetsSent = tvb_get_letohl(tvb,offset+48); + packetsRecv = tvb_get_letohl(tvb,offset+52); + octetsRecv = tvb_get_letohl(tvb,offset+56); + packetsLost = tvb_get_letohl(tvb,offset+60); + jitter = tvb_get_letohl(tvb,offset+64); + latency = tvb_get_letohl(tvb,offset+68); + + proto_tree_add_string(skinny_tree, hf_skinny_extension, tvb, offset+12, strlen(extension), extension); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+36, 4, callIdentifier); + proto_tree_add_uint(skinny_tree, hf_skinny_packetsSent, tvb, offset+44, 4, packetsSent); + proto_tree_add_uint(skinny_tree, hf_skinny_octetsSent, tvb, offset+48, 4, octetsSent); + proto_tree_add_uint(skinny_tree, hf_skinny_packetsRecv, tvb, offset+52, 4, packetsRecv); + proto_tree_add_uint(skinny_tree, hf_skinny_octetsRecv, tvb, offset+56, 4, octetsRecv); + proto_tree_add_uint(skinny_tree, hf_skinny_packetsLost, tvb, offset+60, 4, packetsLost); + proto_tree_add_uint(skinny_tree, hf_skinny_latency, tvb, offset+64, 4, latency); + proto_tree_add_uint(skinny_tree, hf_skinny_jitter, tvb, offset+68, 4, jitter); + break; + + case 0x11D : + unknown1 = tvb_get_letohl(tvb, offset+36); + callIdentifier = tvb_get_letohl(tvb, offset+40); + + proto_tree_add_uint(skinny_tree, hf_skinny_unknown, tvb, offset+36, 4, unknown1); + proto_tree_add_uint(skinny_tree, hf_skinny_callIdentifier, tvb, offset+40, 4, callIdentifier); + break; + + + default: + break; + } + + } + offset = offset + hdr_data_length+8; + } } /* Register the protocol with Ethereal */ void proto_register_skinny(void) { - -/* Setup list of header fields */ + + /* Setup list of header fields */ static hf_register_info hf[] = { { &hf_skinny_data_length, { "Data Length", "skinny.data_length", - FT_UINT32, BASE_HEX, NULL, 0x0, - "Number of bytes in the data portion.", - HFILL } + FT_UINT32, BASE_DEC, NULL, 0x0, + "Number of bytes in the data portion.", + HFILL } }, { &hf_skinny_reserved, { "Reserved", "skinny.reserved", - FT_UINT32, BASE_HEX, NULL, 0x0, - "Reserved for furture(?) use.", - HFILL } + FT_UINT32, BASE_HEX, NULL, 0x0, + "Reserved for furture(?) use.", + HFILL } }, /* FIXME: Enable use of message name ??? */ { &hf_skinny_messageid, { "Message ID", "skinny.messageid", - FT_UINT32, BASE_HEX, VALS(message_id), 0x0, - "The function requested/done with this message.", - HFILL } + FT_UINT32, BASE_HEX, VALS(message_id), 0x0, + "The function requested/done with this message.", + HFILL } + }, + + { &hf_skinny_callIdentifier, + { "Call Identifier", "skinny.callIdentifier", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Call identifier for this call.", + HFILL } + }, + + { &hf_skinny_packetsSent, + { "Packets Sent", "skinny.packetsSent", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Packets Sent during the call.", + HFILL } + }, + + { &hf_skinny_octetsSent, + { "Octets Sent", "skinny.octetsSent", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Octets sent during the call.", + HFILL } + }, + + { &hf_skinny_packetsRecv, + { "Packets Received", "skinny.packetsRecv", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Packets received during the call.", + HFILL } + }, + + + { &hf_skinny_octetsRecv, + { "Octets Received", "skinny.octetsRecv", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Octets received during the call.", + HFILL } + }, + + + { &hf_skinny_packetsLost, + { "Packets Lost", "skinny.packetsLost", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Packets lost during the call.", + HFILL } }, - }; -/* Setup protocol subtree array */ + + { &hf_skinny_latency, + { "Latency(ms)", "skinny.latency", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Average packet latency during the call.", + HFILL } + }, + + { &hf_skinny_jitter, + { "Jitter", "skinny.jitter", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Average jitter during the call.", + HFILL } + }, + + { &hf_skinny_extension, + { "Extension", "skinny.extension", + FT_STRING, BASE_NONE, NULL, 0x0, + "The extension this packets is for.", + HFILL } + }, + + { &hf_skinny_displayMessage, + { "Text", "skinny.displayMessage", + FT_STRING, BASE_NONE, NULL, 0x0, + "The message displayed on the phone.", + HFILL } + }, + + { &hf_skinny_timeStamp, + { "Timestamp", "skinny.timeStamp", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Time stamp for the call reference", + HFILL } + }, + + { &hf_skinny_unknown, + { "Unknown Long", "skinny.unknown", + FT_UINT32, BASE_HEX, NULL, 0x0, + "An as yet undecoded long value", + HFILL } + }, + + { &hf_skinny_ipSrc, + { "IP Source", "skinny.ipSrc", + FT_IPv4, BASE_NONE, NULL, 0x0, + "Ip source address", + HFILL } + }, + + { &hf_skinny_ipDest, + { "IP Destination", "skinny.ipDest", + FT_IPv4, BASE_NONE, NULL, 0x0, + "IP destination address", + HFILL } + }, + + { &hf_skinny_dateYear, + { "Year", "skinny.year", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The current year", + HFILL } + }, + + { &hf_skinny_dateMonth, + { "Month", "skinny.month", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The current month", + HFILL } + }, + + { &hf_skinny_dateDay, + { "Day", "skinny.day", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The day of the current month", + HFILL } + }, + + { &hf_skinny_dateHour, + { "Hour", "skinny.hour", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Hour of the day", + HFILL } + }, + + { &hf_skinny_dateMinute, + { "Minute", "skinny.minute", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Minute", + HFILL } + }, + + { &hf_skinny_destPort, + { "Destination Port", "skinny.destPort", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Destination Port", + HFILL } + }, + + { &hf_skinny_srcPort, + { "Source Port", "skinny.srcPort", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Source Port", + HFILL } + }, + + { &hf_skinny_softKeyNumber, + { "SoftKey", "skinny.softKeyNumber", + FT_UINT32, BASE_DEC, NULL, 0x0, + "SoftKey", + HFILL } + }, + + { &hf_skinny_dialedDigit, + { "Dialed Digit", "skinny.dialedDigit", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Dialed Digit", + HFILL } + }, + + { &hf_skinny_line, + { "Line", "skinny.line", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Line", + HFILL } + }, + + }; + + /* Setup protocol subtree array */ static gint *ett[] = { &ett_skinny, }; - -/* Register the protocol name and description */ + + /* Register the protocol name and description */ proto_skinny = proto_register_protocol("Skinny Client Control Protocol", - "SKINNY", "skinny"); - -/* Required function calls to register the header fields and subtrees used */ + "SKINNY", "skinny"); + + /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_skinny, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); }; -- cgit v1.2.3