Get rid of get_ber_last_reated_item() and fix dissection of wIN-TriggerList.
[obnox/wireshark/wip.git] / epan / dissectors / packet-etheric.c
1 /* packet-etheric.c
2  * Routines for Etheric dissection a Ericsson propriatary protocol.
3  * See
4  *
5  *      http://watersprings.org/pub/id/draft-toivanen-sccp-etheric-00.txt
6  *
7  * XXX - the version in that draft appears to use the same codes for
8  * parameters as ISUP does, although it doesn't use all of them.  Should
9  * we use the ISUP dissector's #defines and tables for them, as we do
10  * now, or should we use our own?
11  *
12  * We also use its table for message types, but have our own #defines
13  * for them; should we adopt the ISUP dissector's #defines, or have our
14  * own table?
15  * 
16  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
17  *
18  * $Id$
19  *
20  * Wireshark - Network traffic analyzer
21  * By Gerald Combs <gerald@wireshark.org>
22  * Copyright 1998 Gerald Combs
23  * 
24  * This program is free software; you can redistribute it and/or
25  * modify it under the terms of the GNU General Public License
26  * as published by the Free Software Foundation; either version 2
27  * of the License, or (at your option) any later version.
28  * 
29  * This program is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  * GNU General Public License for more details.
33  * 
34  * You should have received a copy of the GNU General Public License
35  * along with this program; if not, write to the Free Software
36  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37  */
38
39 #ifdef HAVE_CONFIG_H
40 # include "config.h"
41 #endif
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #include <glib.h>
48
49 #include <epan/packet.h>
50 #include <epan/emem.h>
51 #include <prefs.h>
52 #include "packet-e164.h"
53 #include "packet-q931.h"
54 #include "packet-isup.h"
55
56 /* Initialize the protocol and registered fields */
57 static int proto_etheric                                = -1;
58 static int hf_etheric_protocol_version  = -1;
59 static int hf_etheric_message_length    = -1;
60 static int hf_etheric_cic                               = -1;
61 static int hf_etheric_message_type              = -1;
62 static int hf_etheric_parameter_type    = -1;
63
64 static int hf_etheric_calling_partys_category                                   = -1;
65 static int hf_etheric_forw_call_isdn_access_indicator                   = -1;
66         
67 static int hf_etheric_transmission_medium_requirement                   = -1;
68 static int hf_etheric_odd_even_indicator                                                = -1;
69 static int hf_etheric_called_party_nature_of_address_indicator  = -1;
70
71 static int hf_etheric_ni_indicator                                                              = -1;
72 static int hf_etheric_calling_party_nature_of_address_indicator = -1;
73
74 static int hf_etheric_inn_indicator                                                             = -1;
75
76 static int hf_etheric_numbering_plan_indicator                                  = -1;
77
78 static int hf_etheric_address_presentation_restricted_indicator = -1;
79 static int hf_etheric_screening_indicator                                               = -1;
80 static int hf_etheric_called_party_odd_address_signal_digit             = -1;
81 static int hf_etheric_calling_party_odd_address_signal_digit    = -1;
82 static int hf_etheric_called_party_even_address_signal_digit    = -1;
83 static int hf_etheric_calling_party_even_address_signal_digit   = -1;
84 static int hf_etheric_mandatory_variable_parameter_pointer              = -1;
85 static int hf_etheric_parameter_length                                                  = -1;
86 static int hf_etheric_pointer_to_start_of_optional_part                 = -1;
87 static int hf_etheric_inband_information_ind                                    = -1;
88 static int hf_etheric_cause_indicator                                                   = -1;
89 static int hf_etheric_event_ind                                                                 = -1;   
90 static int hf_etheric_event_presentation_restricted_ind                 = -1;
91
92 /* Initialize the subtree pointers */
93 static gint ett_etheric                                         = -1;
94 static gint ett_etheric_parameter                       = -1;
95 static gint ett_etheric_address_digits          = -1;
96 static gint ett_etheric_circuit_state_ind       = -1;
97
98 /* set the tcp port */
99 static guint ethericTCPport1 =1806;
100 static guint ethericTCPport2 =10002;
101
102 static dissector_handle_t       q931_ie_handle = NULL;
103 /* Value strings */
104 static const value_string protocol_version_vals[] = {
105         { 0x00, "Etheric 1.0" },
106         { 0x10, "Etheric 2.0" },
107         { 0x11, "Etheric 2.1" },
108         { 0,    NULL }
109 };
110
111 /* Definition of Message Types */
112 #define ETHERIC_MESSAGE_TYPE_INITIAL_ADDR       1
113 #define ETHERIC_MESSAGE_TYPE_SUBSEQ_ADDR        2
114 #define ETHERIC_MESSAGE_TYPE_INFO_REQ           3
115 #define ETHERIC_MESSAGE_TYPE_INFO               4
116 #define ETHERIC_MESSAGE_TYPE_CONTINUITY         5
117 #define ETHERIC_MESSAGE_TYPE_ADDR_CMPL          6
118 #define ETHERIC_MESSAGE_TYPE_CONNECT            7
119 #define ETHERIC_MESSAGE_TYPE_FORW_TRANS         8
120 #define ETHERIC_MESSAGE_TYPE_ANSWER             9
121 #define ETHERIC_MESSAGE_TYPE_RELEASE           12
122 #define ETHERIC_MESSAGE_TYPE_SUSPEND           13
123 #define ETHERIC_MESSAGE_TYPE_RESUME            14
124 #define ETHERIC_MESSAGE_TYPE_REL_CMPL          16
125 #define ETHERIC_MESSAGE_TYPE_CONT_CHECK_REQ    17
126 #define ETHERIC_MESSAGE_TYPE_RESET_CIRCUIT     18
127 #define ETHERIC_MESSAGE_TYPE_BLOCKING          19
128 #define ETHERIC_MESSAGE_TYPE_UNBLOCKING        20
129 #define ETHERIC_MESSAGE_TYPE_BLOCK_ACK         21
130 #define ETHERIC_MESSAGE_TYPE_UNBLOCK_ACK       22
131 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_RST      23
132 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_BLCK     24
133 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_UNBL     25
134 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_BL_ACK   26
135 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_UNBL_ACK 27
136 #define ETHERIC_MESSAGE_TYPE_FACILITY_REQ      31
137 #define ETHERIC_MESSAGE_TYPE_FACILITY_ACC      32
138 #define ETHERIC_MESSAGE_TYPE_FACILITY_REJ      33
139 #define ETHERIC_MESSAGE_TYPE_LOOP_BACK_ACK     36
140 #define ETHERIC_MESSAGE_TYPE_PASS_ALONG        40
141 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_RST_ACK  41
142 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_QRY      42
143 #define ETHERIC_MESSAGE_TYPE_CIRC_GRP_QRY_RSP  43
144 #define ETHERIC_MESSAGE_TYPE_CALL_PROGRSS      44
145 #define ETHERIC_MESSAGE_TYPE_USER2USER_INFO    45
146 #define ETHERIC_MESSAGE_TYPE_UNEQUIPPED_CIC    46
147 #define ETHERIC_MESSAGE_TYPE_CONFUSION         47
148 #define ETHERIC_MESSAGE_TYPE_OVERLOAD          48
149 #define ETHERIC_MESSAGE_TYPE_CHARGE_INFO       49
150 #define ETHERIC_MESSAGE_TYPE_NETW_RESRC_MGMT   50
151 #define ETHERIC_MESSAGE_TYPE_FACILITY          51
152 #define ETHERIC_MESSAGE_TYPE_USER_PART_TEST    52
153 #define ETHERIC_MESSAGE_TYPE_USER_PART_AVAIL   53
154 #define ETHERIC_MESSAGE_TYPE_IDENT_REQ         54
155 #define ETHERIC_MESSAGE_TYPE_IDENT_RSP         55
156 #define ETHERIC_MESSAGE_TYPE_SEGMENTATION      56
157 #define ETHERIC_MESSAGE_TYPE_LOOP_PREVENTION   64
158 #define ETHERIC_MESSAGE_TYPE_APPLICATION_TRANS 65
159 #define ETHERIC_MESSAGE_TYPE_PRE_RELEASE_INFO  66
160 #define ETHERIC_MESSAGE_TYPE_SUBSEQUENT_DIR_NUM 67
161
162 static const true_false_string isup_ISDN_originating_access_ind_value = {
163   "originating access ISDN",
164   "originating access non-ISDN"
165 };
166 static const value_string etheric_calling_partys_category_value[] = {
167   { 0,  "Reserved"},
168   { 1,  "Reserved"},
169   { 2,  "Reserved"},
170   { 3,  "Reserved"},
171   { 4,  "Reserved"},
172   { 5,  "Reserved"},
173   { 10, "Ordinary calling subscriber"},
174   { 11, "Reserved"},
175   { 12, "Reserved"},
176   { 13, "Test call"},
177   /* q.763-200212Amd2 */
178   { 14, "Reserved"},
179   { 15, "Reserved"},
180   { 0,  NULL}};
181
182 static const true_false_string isup_odd_even_ind_value = {
183   "odd number of address signals",
184   "even number of address signals"
185 };
186
187 static const value_string isup_called_party_nature_of_address_ind_value[] = {
188   { 0,  "Spare"},
189   { 1,  "Reserved"},
190   { 2,  "Reserved"},
191   { 3,  "national (significant) number"},
192   { 4,  "international number"},
193   { 5,  "Reserved"},
194   { 0,  NULL}};
195
196 static const true_false_string isup_NI_ind_value = {
197   "incomplete",
198   "complete"
199 };
200
201   static const value_string etheric_location_number_nature_of_address_ind_value[] = {
202   { 0,  "Spare"},
203   { 1,  "subscriber number (national use)"},
204   { 2,  "unknown (national use)"},
205   { 3,  "national (significant) number"},
206   { 4,  "international number"},
207   { 0,NULL}};
208
209 static const value_string isup_address_presentation_restricted_ind_value[] = {
210   { 0,  "Presentation allowed"},
211   { 1,  "Presentation restricted"},
212   { 2,  "Reserved"},
213   { 3,  "Spare"},
214   { 0,  NULL}};
215
216 static const value_string isup_screening_ind_value[] = {
217   { 0,     "Not available"},
218   { 1,     "User provided, verified and passed"},
219   { 2,     "reserved"},
220   { 3,     "Network provided"},
221   { 0,     NULL}};
222
223 static const value_string isup_called_party_address_digit_value[] = {
224   { 0,  "0"},
225   { 1,  "1"},
226   { 2,  "2"},
227   { 3,  "3"},
228   { 4,  "4"},
229   { 5,  "5"},
230   { 6,  "6"},
231   { 7,  "7"},
232   { 8,  "8"},
233   { 9,  "9"},
234   { 10, "spare"},
235   { 11, "code 11 "},
236   { 12, "code 12"},
237   { 15, "Stop sending"},
238   { 0,  NULL}};
239
240 static const value_string isup_calling_party_address_digit_value[] = {
241   { 0,  "0"},
242   { 1,  "1"},
243   { 2,  "2"},
244   { 3,  "3"},
245   { 4,  "4"},
246   { 5,  "5"},
247   { 6,  "6"},
248   { 7,  "7"},
249   { 8,  "8"},
250   { 9,  "9"},
251   { 10, "spare"},
252   { 11, "code 11 "},
253   { 12, "code 12"},
254   { 15, "spare"},
255   { 0,  NULL}};
256 static const true_false_string isup_INN_ind_value = {
257   "routing to internal network number not allowed",
258   "routing to internal network number allowed "
259 };
260 static const value_string isup_numbering_plan_ind_value[] = {
261   { 1,  "ISDN (Telephony) numbering plan"},
262   { 3,  "Data numbering plan (national use)"},
263   { 4,  "Telex numbering plan (national use)"},
264   { 5,  "Reserved for national use"},
265   { 6,  "Reserved for national use"},
266   { 0,  NULL}};
267
268   static const true_false_string isup_inband_information_ind_value = {
269   /* according 3.37/Q.763 */
270   "in-band information or an appropirate pattern is now available",
271   "no indication"
272 };
273 static const true_false_string isup_event_presentation_restricted_ind_value = {
274   /* according 3.21/Q.763 */
275   "presentation restricted",
276   "no indication"
277 };
278 static const value_string isup_event_ind_value[] = {
279   /* according 3.21/Q.763 */
280   {  1, "ALERTING"},
281   {  2, "PROGRESS"},
282   {  3, "in-band information or an appropriate pattern is now available"},
283   {  4, "call forwarded on busy (national use)"},
284   {  5, "call forwarded on no reply (national use)"},
285   {  6, "call forwarded unconditional (national use)"},
286   {  0, NULL}};
287
288 static void dissect_etheric_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *etheric_tree, guint8 etheric_version, guint8 message_length);
289
290 /* ------------------------------------------------------------------
291   Mapping number to ASCII-character
292  ------------------------------------------------------------------ */
293 static char number_to_char_2(int number)
294 {
295   if (number < 10)
296     return ((char) number + 0x30);
297   else
298     return ((char) number + 0x37);
299 }
300
301 /* Code to actually dissect the packets */
302 static int
303 dissect_etheric(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
304 {
305
306 /* Set up structures needed to add the protocol subtree and manage it */
307         proto_item *ti;
308         proto_tree *etheric_tree;
309         gint            offset = 0;
310         guint8          message_length; 
311         guint16         cic;
312         guint8          message_type,etheric_version;
313         
314         tvbuff_t        *message_tvb;
315         
316         
317         /* Do we have the version number? */
318         if (!tvb_bytes_exist(tvb, 0, 1)) {
319                 /* No - reject this packet. */
320                 return 0;
321         }
322         etheric_version = tvb_get_guint8(tvb, 0);
323         /* Do we know the version? */
324         if (match_strval(etheric_version, protocol_version_vals) == NULL) {
325                 /* No - reject this packet. */
326                 return 0;
327         }
328
329         /* Make entries in Protocol column and Info column on summary display */
330         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
331                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Etheric");
332
333         if (check_col(pinfo->cinfo, COL_INFO)) 
334                 col_clear(pinfo->cinfo, COL_INFO);
335
336         message_type = tvb_get_guint8(tvb, 4);
337         if (check_col(pinfo->cinfo, COL_INFO))
338                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(message_type, isup_message_type_value_acro, "reserved"));
339
340         if(tree){
341
342
343 /* create display subtree for the protocol */
344                 ti = proto_tree_add_item(tree, proto_etheric, tvb, 0, -1, FALSE);
345
346                 etheric_tree = proto_item_add_subtree(ti, ett_etheric);
347                 proto_tree_add_item(etheric_tree, hf_etheric_protocol_version, tvb, offset, 1, FALSE);
348                 offset++;
349                 message_length = tvb_get_guint8(tvb, offset);
350                 proto_tree_add_item(etheric_tree, hf_etheric_message_length, tvb, offset, 1, FALSE);
351                 offset++;
352
353                 cic = tvb_get_letohs(tvb, offset) & 0x0FFF; /*since upper 4 bits spare */
354                 proto_tree_add_uint_format(etheric_tree, hf_etheric_cic, tvb, offset, 2, cic, "CIC: %u", cic);
355                 offset = offset + 2;
356         
357                 message_tvb = tvb_new_subset(tvb, offset, -1, -1);
358                 dissect_etheric_message(message_tvb, pinfo, etheric_tree,etheric_version, message_length);
359
360
361         }/* end end if tree */
362         return tvb_length(tvb);
363 }
364
365 /* ------------------------------------------------------------------
366  Dissector Parameter Forward Call Indicators
367  */
368 static void
369 dissect_etheric_forward_call_indicators_parameter(tvbuff_t *parameter_tvb,proto_tree *parameter_tree, proto_item *parameter_item)
370 {
371   guint8 forward_call_ind;
372
373   forward_call_ind = tvb_get_guint8(parameter_tvb, 0);
374   proto_tree_add_boolean(parameter_tree, hf_etheric_forw_call_isdn_access_indicator, 
375           parameter_tvb, 0, 1, forward_call_ind);
376
377   proto_item_set_text(parameter_item, "Forward Call Indicators: 0x%x", forward_call_ind );
378 }
379
380 /* ------------------------------------------------------------------
381  Dissector Parameter Calling Party's Category
382  */
383 static void
384 dissect_etheric_calling_partys_category_parameter(tvbuff_t *parameter_tvb,proto_tree *parameter_tree, proto_item *parameter_item)
385 {
386   guint8 calling_partys_category;
387
388   calling_partys_category = tvb_get_guint8(parameter_tvb, 0);
389   proto_tree_add_uint(parameter_tree, hf_etheric_calling_partys_category, parameter_tvb, 
390           0, 1, calling_partys_category);
391
392   proto_item_set_text(parameter_item, "Calling Party's category: 0x%x (%s)", calling_partys_category,
393           val_to_str(calling_partys_category, etheric_calling_partys_category_value, "reserved/spare"));
394 }
395 /* ------------------------------------------------------------------
396   Dissector Parameter Transmission medium requirement
397  */
398 static void
399 dissect_etheric_transmission_medium_requirement_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
400 {
401   guint8 transmission_medium_requirement;
402
403   transmission_medium_requirement = tvb_get_guint8(parameter_tvb, 0);
404   proto_tree_add_uint(parameter_tree, hf_etheric_transmission_medium_requirement, parameter_tvb, 0, 1,transmission_medium_requirement);
405
406   proto_item_set_text(parameter_item, "Transmission medium requirement: %u (%s)",  transmission_medium_requirement, val_to_str(transmission_medium_requirement, isup_transmission_medium_requirement_value, "spare"));
407 }
408 /* ------------------------------------------------------------------
409   Dissector Parameter Called party number
410  */
411 static void
412 dissect_etheric_called_party_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
413 {
414   proto_item *address_digits_item;
415   proto_tree *address_digits_tree;
416   guint8 indicators1;
417   guint8 address_digit_pair=0;
418   gint offset=0;
419   gint i=0;
420   gint length;
421   char *called_number;
422   e164_info_t e164_info;
423  
424   indicators1 = tvb_get_guint8(parameter_tvb, 0);
425   proto_tree_add_boolean(parameter_tree, hf_etheric_odd_even_indicator, parameter_tvb, 0, 1, indicators1);
426   proto_tree_add_uint(parameter_tree, hf_etheric_called_party_nature_of_address_indicator, parameter_tvb, 0, 1, indicators1);
427   offset = 1;
428
429   address_digits_item = proto_tree_add_text(parameter_tree, parameter_tvb,
430                                             offset, -1,
431                                             "Called Party Number");
432   address_digits_tree = proto_item_add_subtree(address_digits_item, ett_etheric_address_digits);
433
434   length = tvb_reported_length_remaining(parameter_tvb, offset);
435   called_number = ep_alloc((length+1) *2);
436   while((length = tvb_reported_length_remaining(parameter_tvb, offset)) > 0){
437     address_digit_pair = tvb_get_guint8(parameter_tvb, offset);
438     proto_tree_add_uint(address_digits_tree, hf_etheric_called_party_odd_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
439     called_number[i++] = number_to_char_2(address_digit_pair & 0x0F);
440     if ((length - 1) > 0 ){
441       proto_tree_add_uint(address_digits_tree, hf_etheric_called_party_even_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
442       called_number[i++] = number_to_char_2((address_digit_pair & 0xf0) / 0x10);
443     }
444     offset++;
445   }
446
447   if  (((indicators1 & 0x80) == 0) && (tvb_length(parameter_tvb) > 0)){ /* Even Indicator set -> last even digit is valid & has be displayed */
448       proto_tree_add_uint(address_digits_tree, hf_etheric_called_party_even_address_signal_digit, parameter_tvb, offset - 1, 1, address_digit_pair);
449       called_number[i++] = number_to_char_2((address_digit_pair & 0xf0) / 0x10);
450   }
451   called_number[i++] = '\0';
452   e164_info.e164_number_type = CALLED_PARTY_NUMBER;
453   e164_info.nature_of_address = indicators1 & 0x7f;
454   e164_info.E164_number_str = called_number;
455   e164_info.E164_number_length = i - 1;
456   dissect_e164_number(parameter_tvb, address_digits_tree, 2,
457                                                                   (offset - 2), e164_info);
458   proto_item_set_text(address_digits_item, "Called Party Number: %s", called_number);
459   proto_item_set_text(parameter_item, "Called Party Number: %s", called_number);
460 }
461 /* ------------------------------------------------------------------
462   Dissector Parameter calling party number
463  */
464 static void
465 dissect_etheric_calling_party_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
466 {
467   proto_item *address_digits_item;
468   proto_tree *address_digits_tree;
469   guint8 indicators1, indicators2;
470   guint8 address_digit_pair=0;
471   gint offset=0;
472   gint i=0;
473   gint length;
474   char *calling_number;
475   e164_info_t e164_info;
476
477   indicators1 = tvb_get_guint8(parameter_tvb, 0);
478   proto_tree_add_boolean(parameter_tree, hf_etheric_odd_even_indicator, parameter_tvb, 0, 1, indicators1);
479   proto_tree_add_uint(parameter_tree, hf_etheric_called_party_nature_of_address_indicator, parameter_tvb, 0, 1, indicators1);
480   indicators2 = tvb_get_guint8(parameter_tvb, 1);
481   proto_tree_add_uint(parameter_tree, hf_etheric_address_presentation_restricted_indicator, parameter_tvb, 1, 1, indicators2);
482   proto_tree_add_uint(parameter_tree, hf_etheric_screening_indicator, parameter_tvb, 1, 1, indicators2);
483   offset = 2;
484
485   address_digits_item = proto_tree_add_text(parameter_tree, parameter_tvb,
486                                             offset, -1,
487                                             "Calling Party Number");
488   address_digits_tree = proto_item_add_subtree(address_digits_item, ett_etheric_address_digits);
489
490   length = tvb_length_remaining(parameter_tvb, offset);
491   /* prevent running behind the end of calling_number array by throwing an exception */
492   calling_number = ep_alloc((length+1) *2);
493   while(length > 0){
494     address_digit_pair = tvb_get_guint8(parameter_tvb, offset);
495     proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_odd_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
496     calling_number[i++] = number_to_char_2(address_digit_pair & 0x0F);
497     if ((length - 1) > 0 ){
498       proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_even_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
499       calling_number[i++] = number_to_char_2((address_digit_pair & 0xF0) / 0x10);
500     }
501     offset++;
502     length = tvb_length_remaining(parameter_tvb, offset);
503   }
504
505   if  (((indicators1 & 0x80) == 0) && (tvb_length(parameter_tvb) > 0)){ /* Even Indicator set -> last even digit is valid & has be displayed */
506       proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_even_address_signal_digit, parameter_tvb, offset - 1, 1, address_digit_pair);
507       calling_number[i++] = number_to_char_2((address_digit_pair & 0xF0) / 0x10);
508   }
509   calling_number[i++] = '\0';
510
511   proto_item_set_text(address_digits_item, "Calling Party Number: %s", calling_number);
512   proto_item_set_text(parameter_item, "Calling Party Number: %s", calling_number);
513   
514     e164_info.e164_number_type = CALLING_PARTY_NUMBER;
515     e164_info.nature_of_address = indicators1 & 0x7f;
516     e164_info.E164_number_str = calling_number;
517     e164_info.E164_number_length = i - 1;
518     dissect_e164_number(parameter_tvb, address_digits_tree, 2, (offset - 2), e164_info);
519 }
520 /* ------------------------------------------------------------------
521   Dissector Parameter location number
522  */
523 static void
524 dissect_etheric_location_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
525 {
526   proto_item *address_digits_item;
527   proto_tree *address_digits_tree;
528   guint8 indicators1, indicators2;
529   guint8 address_digit_pair=0;
530   gint offset=0;
531   gint i=0;
532   gint length;
533   char *calling_number;
534
535   indicators1 = tvb_get_guint8(parameter_tvb, 0);
536   proto_tree_add_boolean(parameter_tree, hf_etheric_odd_even_indicator, parameter_tvb, 0, 1, indicators1);
537   proto_tree_add_uint(parameter_tree, hf_etheric_calling_party_nature_of_address_indicator, parameter_tvb, 0, 1, indicators1);
538   indicators2 = tvb_get_guint8(parameter_tvb, 1);
539   proto_tree_add_boolean(parameter_tree, hf_etheric_inn_indicator, parameter_tvb, 1, 1, indicators2);
540   proto_tree_add_uint(parameter_tree, hf_etheric_numbering_plan_indicator, parameter_tvb, 1, 1, indicators2);
541   if ((indicators2 & 0x70) == 0x50)
542     proto_tree_add_text(parameter_tree, parameter_tvb, 1, 1, "Different meaning for Location Number: Numbering plan indicator = private numbering plan");
543   proto_tree_add_uint(parameter_tree, hf_etheric_address_presentation_restricted_indicator, parameter_tvb, 1, 1, indicators2);
544   proto_tree_add_uint(parameter_tree, hf_etheric_screening_indicator, parameter_tvb, 1, 1, indicators2);
545
546    /* NOTE  When the address presentation restricted indicator indicates address not available, the
547     * subfields in items a), b), c) and d) are coded with 0's, and the screening indicator is set to 11
548     * (network provided).
549     */
550   if ( indicators2 == 0x0b ){
551     proto_tree_add_text(parameter_tree, parameter_tvb, 1, -1, "Location number: address not available");
552     proto_item_set_text(parameter_item, "Location number: address not available");
553     return;
554   }
555
556   offset = 2;
557
558   address_digits_item = proto_tree_add_text(parameter_tree, parameter_tvb,
559                                             offset, -1,
560                                             "Location number");
561   address_digits_tree = proto_item_add_subtree(address_digits_item, ett_etheric_address_digits);
562
563   length = tvb_length_remaining(parameter_tvb, offset);
564   calling_number = ep_alloc((length+1) *2);
565   while(length > 0){
566     address_digit_pair = tvb_get_guint8(parameter_tvb, offset);
567     proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_odd_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
568     calling_number[i++] = number_to_char_2(address_digit_pair & 0x0f);
569     if ((length - 1) > 0 ){
570       proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_even_address_signal_digit, parameter_tvb, offset, 1, address_digit_pair);
571       calling_number[i++] = number_to_char_2((address_digit_pair & 0xf0) / 0x10);
572     }
573     offset++;
574     length = tvb_length_remaining(parameter_tvb, offset);
575   }
576
577   if  (((indicators1 & 0x80) == 0) && (tvb_length(parameter_tvb) > 0)){ /* Even Indicator set -> last even digit is valid & has be displayed */
578       proto_tree_add_uint(address_digits_tree, hf_etheric_calling_party_even_address_signal_digit, parameter_tvb, offset - 1, 1, address_digit_pair);
579       calling_number[i++] = number_to_char_2((address_digit_pair & 0xf0) / 0x10);
580   }
581   calling_number[i++] = '\0';
582
583   proto_item_set_text(address_digits_item, "Location number: %s", calling_number);
584   proto_item_set_text(parameter_item, "Location number: %s", calling_number);
585 }
586
587 /* ------------------------------------------------------------------
588   Dissector Parameter User service information- no detailed dissection since defined in Rec. Q.931
589  */
590 static void
591 dissect_etheric_user_service_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
592 { guint length = tvb_length(parameter_tvb);
593   proto_tree_add_text(parameter_tree, parameter_tvb, 0, length,
594           "User service information (-> Q.931 Bearer_capability)");
595   proto_item_set_text(parameter_item, "User service information, (%u byte%s length)",
596           length , plurality(length, "", "s"));
597   dissect_q931_bearer_capability_ie(parameter_tvb,
598                                             0, length,
599                                             parameter_tree);
600 }
601 /* ------------------------------------------------------------------
602   Dissector Parameter Access Transport - no detailed dissection since defined in Rec. Q.931
603  */
604 static void
605 dissect_etheric_access_transport_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree,
606                          proto_item *parameter_item, packet_info *pinfo)
607 { guint length = tvb_reported_length(parameter_tvb);
608
609   proto_tree_add_text(parameter_tree, parameter_tvb, 0, -1, 
610           "Access transport parameter field (-> Q.931)");
611   
612   if (q931_ie_handle)
613     call_dissector(q931_ie_handle, parameter_tvb, pinfo, parameter_tree);
614
615   proto_item_set_text(parameter_item, "Access transport (%u byte%s length)",
616           length , plurality(length, "", "s"));
617 }
618 /* ------------------------------------------------------------------
619  Dissector Parameter Backward Call Indicators
620  */
621 static void
622 dissect_etheric_backward_call_indicators_parameter(tvbuff_t *parameter_tvb,proto_tree *parameter_tree, proto_item *parameter_item)
623 {
624   guint8 backward_call_ind;
625
626   backward_call_ind = tvb_get_guint8(parameter_tvb, 0);
627
628
629   proto_tree_add_boolean(parameter_tree, hf_etheric_inband_information_ind, parameter_tvb, 0, 1, backward_call_ind);
630
631   proto_item_set_text(parameter_item, "Backward Call Indicators: 0x%x", backward_call_ind);
632 }
633 /* ------------------------------------------------------------------
634   Dissector Parameter Cause Indicators - no detailed dissection since defined in Rec. Q.850
635  */
636
637
638
639 /* ------------------------------------------------------------------
640   Dissector Message Type release message
641  */
642 static gint
643 dissect_etheric_release_message(tvbuff_t *message_tvb, proto_tree *etheric_tree)
644 { proto_item* parameter_item;
645   proto_tree* parameter_tree;
646   gint offset = 0;
647   gint parameter_type, parameter_pointer, parameter_length;
648
649   /* Do stuff for mandatory variable parameter Cause indicators */
650   parameter_type =  PARAM_TYPE_CAUSE_INDICATORS;
651
652   parameter_pointer = 0;
653   parameter_length = 1;
654
655   parameter_item = proto_tree_add_text(etheric_tree, message_tvb,
656                                        offset +  parameter_pointer, 1,"Cause indicators, see Q.850");
657
658   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
659   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 1, parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
660   proto_tree_add_item(parameter_tree, hf_etheric_cause_indicator, message_tvb, 0, 1,FALSE);
661   offset += 1;
662
663   return offset;
664 }
665 /* ------------------------------------------------------------------
666   Dissector Parameter Event information
667  */
668 static void
669 dissect_etheric_event_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
670 {
671   guint8 indicators;
672
673   indicators = tvb_get_guint8(parameter_tvb, 0);
674   proto_tree_add_uint_format(parameter_tree, hf_etheric_event_ind, parameter_tvb, 0, 1, indicators, "Event indicator: %s (%u)", val_to_str(indicators & 0x7f, isup_event_ind_value, "spare"), indicators & 0x7f);
675   proto_tree_add_boolean(parameter_tree, hf_etheric_event_presentation_restricted_ind, parameter_tvb, 0, 1, indicators);
676
677   proto_item_set_text(parameter_item,"Event information: %s (%u)", val_to_str(indicators & 0x7f, isup_event_ind_value, "spare"),indicators );
678 }
679
680 /* ------------------------------------------------------------------ */
681 static void
682 dissect_etheric_unknown_parameter(tvbuff_t *parameter_tvb, proto_item *parameter_item)
683 { guint length = tvb_length(parameter_tvb);
684   proto_item_set_text(parameter_item, "Parameter Type unknown/reserved (%u Byte%s)", length , plurality(length, "", "s"));
685 }
686
687 /* ------------------------------------------------------------------ */
688 /* Dissectors for all used message types                              */
689 /* Called by dissect_etheric_message(),                               */
690 /* call parameter dissectors in order of mandatory parameters         */
691 /* (since not labeled)                                                */
692 /* ------------------------------------------------------------------
693   Dissector Message Type Initial address message
694  */
695 static gint
696 dissect_etheric_initial_address_message(tvbuff_t *message_tvb, proto_tree *etheric_tree)
697 { proto_item* parameter_item;
698   proto_tree* parameter_tree;
699   tvbuff_t *parameter_tvb;
700   gint offset = 0;
701   gint parameter_type, parameter_pointer, parameter_length, actual_length;
702
703   /* Do stuff for 1nd mandatory fixed parameter: Forward Call Indicators */
704   parameter_type =  PARAM_TYPE_FORW_CALL_IND;
705   parameter_item = proto_tree_add_text(etheric_tree, message_tvb, offset,
706                                        1,
707                                        "Forward Call Indicators");
708   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
709   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0,
710           parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
711   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
712   parameter_tvb = tvb_new_subset(message_tvb, offset, MIN(2, actual_length), 2 );
713   dissect_etheric_forward_call_indicators_parameter(parameter_tvb, parameter_tree, parameter_item);
714   offset +=  1;
715
716   /* Do stuff for 2nd mandatory fixed parameter: Calling party's category */
717   parameter_type = PARAM_TYPE_CALLING_PRTY_CATEG;
718   parameter_item = proto_tree_add_text(etheric_tree, message_tvb, offset,
719                                        1, "Calling Party's category");
720   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
721   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0, parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
722   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
723   parameter_tvb = tvb_new_subset(message_tvb, offset, MIN(1, actual_length),1 );
724   dissect_etheric_calling_partys_category_parameter(parameter_tvb, parameter_tree, parameter_item);
725   offset += 1;
726   /* Do stuff for 3d mandatory fixed parameter: Transmission medium requirement */
727   parameter_type = PARAM_TYPE_TRANSM_MEDIUM_REQU;
728   parameter_item = proto_tree_add_text(etheric_tree, message_tvb, offset,
729                                        1, "Transmission medium requirement");
730   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
731   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0, parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
732   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
733   parameter_tvb = tvb_new_subset(message_tvb, offset, MIN(1, actual_length), 1);
734   dissect_etheric_transmission_medium_requirement_parameter(parameter_tvb, parameter_tree, parameter_item);
735   offset += 1;
736
737
738   /* Do stuff for mandatory variable parameter Called party number */
739   parameter_type = PARAM_TYPE_CALLED_PARTY_NR;
740   parameter_pointer = tvb_get_guint8(message_tvb, offset);
741   parameter_length = tvb_get_guint8(message_tvb, offset + parameter_pointer);
742
743   parameter_item = proto_tree_add_text(etheric_tree, message_tvb,
744                                        offset +  parameter_pointer,
745                                        parameter_length + 1,
746                                        "Called Party Number");
747   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
748   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0,
749           parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
750   proto_tree_add_uint_format(parameter_tree, hf_etheric_mandatory_variable_parameter_pointer,
751           message_tvb, offset, 1, parameter_pointer, "Pointer to Parameter: %u", parameter_pointer);
752   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_length, message_tvb,
753           offset + parameter_pointer, 1, parameter_length, "Parameter length: %u", parameter_length);
754   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
755   parameter_tvb = tvb_new_subset(message_tvb, offset + parameter_pointer + 1, MIN(parameter_length, actual_length), parameter_length );
756   dissect_etheric_called_party_number_parameter(parameter_tvb, parameter_tree, parameter_item);
757   offset += 1;
758   /* Do stuff for mandatory variable parameter Calling party number */
759   parameter_type = PARAM_TYPE_CALLING_PARTY_NR;
760   parameter_pointer = tvb_get_guint8(message_tvb, offset);
761   parameter_length = tvb_get_guint8(message_tvb, offset + parameter_pointer);
762
763   parameter_item = proto_tree_add_text(etheric_tree, message_tvb,
764                                        offset +  parameter_pointer,
765                                        parameter_length + 1,
766                                        "Calling Party Number");
767   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
768   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0,
769           parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
770   proto_tree_add_uint_format(parameter_tree, hf_etheric_mandatory_variable_parameter_pointer,
771           message_tvb, offset, 1, parameter_pointer, "Pointer to Parameter: %u", parameter_pointer);
772   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_length, message_tvb,
773           offset + parameter_pointer, 1, parameter_length, "Parameter length: %u", parameter_length);
774   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
775   parameter_tvb = tvb_new_subset(message_tvb, offset + parameter_pointer + 1, MIN(parameter_length, actual_length), parameter_length );
776   dissect_etheric_calling_party_number_parameter(parameter_tvb, parameter_tree, parameter_item);
777   offset += 1;
778   return offset;
779 }
780 /* ------------------------------------------------------------------
781   Dissector Message Type Address complete
782  */
783 static gint
784 dissect_etheric_address_complete_message(tvbuff_t *message_tvb, proto_tree *etheric_tree)
785 { proto_item* parameter_item;
786   proto_tree* parameter_tree;
787   tvbuff_t *parameter_tvb;
788   gint offset = 0;
789   gint parameter_type, actual_length;
790
791   /* Do stuff for first mandatory fixed parameter: backward call indicators*/
792   parameter_type = PARAM_TYPE_BACKW_CALL_IND;
793   parameter_item = proto_tree_add_text(etheric_tree, message_tvb, offset,
794                                        1,
795                                        "Backward Call Indicators");
796   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
797   
798   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0,
799           parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
800   
801   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
802   parameter_tvb = tvb_new_subset(message_tvb, offset, MIN(1, actual_length), 1);
803   dissect_etheric_backward_call_indicators_parameter(parameter_tvb, parameter_tree, parameter_item);
804   offset += 1;
805   return offset;
806 }
807 /* ------------------------------------------------------------------
808   Dissector Message Type Call Progress
809 */
810 static gint
811 dissect_etheric_call_progress_message(tvbuff_t *message_tvb, proto_tree *isup_tree)
812 { proto_item* parameter_item;
813   proto_tree* parameter_tree;
814   tvbuff_t *parameter_tvb;
815   gint offset = 0;
816   gint parameter_type, actual_length;
817
818   /* Do stuff for first mandatory fixed parameter: Event information*/
819   parameter_type = PARAM_TYPE_EVENT_INFO;
820   parameter_item = proto_tree_add_text(isup_tree, message_tvb, offset,
821                                        1,
822                                        "Event information");
823   parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
824   proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, message_tvb, 0, 0, parameter_type, "Mandatory Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
825   actual_length = tvb_ensure_length_remaining(message_tvb, offset);
826   parameter_tvb = tvb_new_subset(message_tvb, offset, MIN(1, actual_length), 1);
827   dissect_etheric_event_information_parameter(parameter_tvb, parameter_tree, parameter_item);
828   offset += 1;
829   return offset;
830 }
831
832 /* ------------------------------------------------------------------
833   Dissector all optional parameters
834 */
835 static void
836 dissect_etheric_optional_parameter(tvbuff_t *optional_parameters_tvb,packet_info *pinfo, proto_tree *etheric_tree)
837 { proto_item* parameter_item;
838   proto_tree* parameter_tree;
839   gint offset = 0;
840   guint parameter_type, parameter_length, actual_length;
841   tvbuff_t *parameter_tvb;
842
843   /* Dissect all optional parameters while end of message isn't reached */
844   parameter_type = 0xFF; /* Start-initializiation since parameter_type is used for while-condition */
845
846   while ((tvb_length_remaining(optional_parameters_tvb, offset)  >= 1) && (parameter_type != PARAM_TYPE_END_OF_OPT_PARAMS)){
847     parameter_type = tvb_get_guint8(optional_parameters_tvb, offset);
848
849     if (parameter_type != PARAM_TYPE_END_OF_OPT_PARAMS){
850       parameter_length = tvb_get_guint8(optional_parameters_tvb, offset + 1);
851
852       parameter_item = proto_tree_add_text(etheric_tree, optional_parameters_tvb,
853                                            offset,
854                                            parameter_length  + 1 + 1,
855                                            "Parameter: type %u",
856                                            parameter_type);
857       parameter_tree = proto_item_add_subtree(parameter_item, ett_etheric_parameter);
858       proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_type, optional_parameters_tvb, offset, 1, parameter_type, "Optional Parameter: %u (%s)", parameter_type, val_to_str(parameter_type, isup_parameter_type_value,"unknown"));
859       offset += 1;
860
861       proto_tree_add_uint_format(parameter_tree, hf_etheric_parameter_length, optional_parameters_tvb, offset, 1, parameter_length, "Parameter length: %u", parameter_length);
862       offset += 1;
863
864       actual_length = tvb_length_remaining(optional_parameters_tvb, offset);
865       if (actual_length > 0){
866         parameter_tvb = tvb_new_subset(optional_parameters_tvb, offset, MIN(parameter_length, actual_length), parameter_length);
867         switch (parameter_type) {
868         case PARAM_TYPE_USER_SERVICE_INFO:
869           dissect_etheric_user_service_information_parameter(parameter_tvb, parameter_tree, parameter_item);
870           break;
871         case PARAM_TYPE_ACC_TRANSP:
872           dissect_etheric_access_transport_parameter(parameter_tvb, parameter_tree, parameter_item, pinfo);
873           break;
874          
875         case PARAM_TYPE_LOCATION_NR:
876           dissect_etheric_location_number_parameter(parameter_tvb, parameter_tree, parameter_item);
877           break;
878
879         default:
880           dissect_etheric_unknown_parameter(parameter_tvb, parameter_item);
881           break;
882         }
883         offset += MIN(parameter_length, actual_length);
884       }
885
886     }
887     else {
888         /* End of optional parameters is reached */
889         proto_tree_add_uint_format(etheric_tree, hf_etheric_message_type, optional_parameters_tvb , offset, 1, parameter_type, "End of optional parameters (%u)", parameter_type);
890     }
891   }
892 }
893                 
894
895 static void
896 dissect_etheric_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *etheric_tree, guint8 etheric_version, guint8 message_length)
897 {
898   tvbuff_t *parameter_tvb;
899   tvbuff_t *optional_parameter_tvb;
900   gint offset, bufferlength;
901   guint8 message_type; 
902   guint8 opt_parameter_pointer = 0;
903   gint opt_part_possible = FALSE; /* default setting - for message types allowing optional
904                                      params explicitely set to TRUE in case statement */
905   offset = 0;
906     /* Extract message type field */
907   message_type = tvb_get_guint8(message_tvb,0);
908   proto_tree_add_item(etheric_tree, hf_etheric_message_type, message_tvb, 0, 1,FALSE);
909   offset ++;
910   parameter_tvb = tvb_new_subset(message_tvb, offset, -1, -1);
911
912   switch (message_type) {
913     case ETHERIC_MESSAGE_TYPE_ADDR_CMPL:
914        offset += dissect_etheric_address_complete_message(parameter_tvb, etheric_tree);
915        opt_part_possible = FALSE;
916       break;
917
918     case ETHERIC_MESSAGE_TYPE_ANSWER:
919       /* no dissector necessary since no mandatory parameters included */
920                 if (etheric_version > 0x10 ) /* 0x10,   "Etheric 2.0" */
921                opt_part_possible = TRUE;
922       break;
923
924     case ETHERIC_MESSAGE_TYPE_BLOCK_ACK:
925       /* no dissector necessary since no mandatory parameters included */
926       break;
927
928     case ETHERIC_MESSAGE_TYPE_BLOCKING:
929       /* no dissector necessary since no mandatory parameters included */
930       break;
931
932     case ETHERIC_MESSAGE_TYPE_CONNECT:
933                 if (etheric_version > 0x10 ) /* 0x10,   "Etheric 2.0" */
934                         opt_part_possible = TRUE;
935       break;
936
937     case ETHERIC_MESSAGE_TYPE_CALL_PROGRSS:
938        offset += dissect_etheric_call_progress_message(parameter_tvb, etheric_tree);
939        opt_part_possible = TRUE;
940       break;
941
942     case ETHERIC_MESSAGE_TYPE_CIRC_GRP_RST:
943       /* no dissector necessary since no mandatory parameters included */
944       break;
945
946     case ETHERIC_MESSAGE_TYPE_CIRC_GRP_RST_ACK:
947       /* no dissector necessary since no mandatory parameters included */
948       break;
949
950     case ETHERIC_MESSAGE_TYPE_INITIAL_ADDR:
951                 offset += dissect_etheric_initial_address_message(parameter_tvb, etheric_tree);
952                 if (etheric_version > 0 ) /* 0x00,      "Etheric 1.0" */
953                         opt_part_possible = TRUE;
954      break;
955
956     case ETHERIC_MESSAGE_TYPE_RELEASE:
957        offset += dissect_etheric_release_message(parameter_tvb, etheric_tree);
958        opt_part_possible = FALSE;
959       break;
960
961         case ETHERIC_MESSAGE_TYPE_REL_CMPL:
962       /* no dissector necessary since no mandatory parameters included */
963       break;
964     case ETHERIC_MESSAGE_TYPE_RESET_CIRCUIT:
965       /* no dissector necessary since no mandatory parameters included */
966       break;
967  
968         case ETHERIC_MESSAGE_TYPE_UNBLOCKING:
969       /* no dissector necessary since no mandatory parameters included */
970       break;
971     case ETHERIC_MESSAGE_TYPE_UNBLOCK_ACK:
972       /* no dissector necessary since no mandatory parameters included */
973       break;
974  default:
975      bufferlength = tvb_length_remaining(message_tvb, offset);
976      if (bufferlength != 0)
977        proto_tree_add_text(etheric_tree, parameter_tvb, 0, bufferlength, 
978                         "Unknown Message type (possibly reserved/used in former ISUP version)");
979      break;
980   }
981
982    /* extract pointer to start of optional part (if any) */
983    if (opt_part_possible == TRUE){
984            if (message_length > 5 ) {
985                    opt_parameter_pointer = tvb_get_guint8(message_tvb, offset);
986
987                    proto_tree_add_uint_format(etheric_tree, hf_etheric_pointer_to_start_of_optional_part,
988                                 message_tvb, offset, 1, opt_parameter_pointer, "Pointer to start of optional part: %u", opt_parameter_pointer);
989                    offset += opt_parameter_pointer;
990                    if (opt_parameter_pointer > 0){
991                      optional_parameter_tvb = tvb_new_subset(message_tvb, offset, -1, -1 );
992                      dissect_etheric_optional_parameter(optional_parameter_tvb, pinfo, etheric_tree);
993                    }
994            }
995    }
996    else if (message_type !=ETHERIC_MESSAGE_TYPE_CHARGE_INFO)
997      proto_tree_add_text(etheric_tree, message_tvb, 0, 0, 
998                 "No optional parameters are possible with this message type");
999
1000 }
1001 /* If this dissector uses sub-dissector registration add a registration routine.
1002    This format is required because a script is used to find these routines and
1003    create the code that calls these routines.
1004 */
1005 void
1006 proto_reg_handoff_etheric(void)
1007 {
1008         static dissector_handle_t etheric_handle;
1009
1010         static int tcp_port1 = 1806;
1011         static int tcp_port2 = 10002;
1012         static int Initialized=FALSE;
1013
1014
1015         if (!Initialized) {
1016                 etheric_handle = find_dissector("etheric");
1017                 Initialized=TRUE;
1018         }else{
1019                 dissector_delete("udp.port", tcp_port1, etheric_handle);
1020                 dissector_delete("udp.port", tcp_port2, etheric_handle);
1021         }
1022
1023         tcp_port1 = ethericTCPport1;
1024         tcp_port2 = ethericTCPport2;
1025
1026         dissector_add("tcp.port", ethericTCPport1, etheric_handle);
1027         dissector_add("tcp.port", ethericTCPport2, etheric_handle);
1028         q931_ie_handle = find_dissector("q931.ie");
1029
1030 }
1031
1032 void
1033 proto_register_etheric(void)
1034 {                 
1035
1036 /* Setup list of header fields  See Section 1.6.1 for details*/
1037         static hf_register_info hf[] = {
1038                 { &hf_etheric_protocol_version,
1039                         { "Protocol version",           "etheric.protocol_version",
1040                         FT_UINT8, BASE_HEX, VALS(&protocol_version_vals), 0x0,          
1041                         "Etheric protocol version", HFILL }
1042                 },
1043                 { &hf_etheric_message_length,
1044                         { "Message length",           "etheric.message.length",
1045                         FT_UINT8, BASE_DEC, NULL, 0x0,          
1046                         "Etheric Message length", HFILL }
1047                 },
1048                 { &hf_etheric_cic,
1049                         { "CIC",           "etheric.cic",
1050                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1051                         "Etheric CIC", HFILL }
1052                 },
1053                 { &hf_etheric_message_type,
1054                         { "Message type",           "etheric.message.type",
1055                         FT_UINT8, BASE_HEX, VALS(&isup_message_type_value), 0x0,          
1056                         "Etheric message types", HFILL }
1057                 },
1058                 { &hf_etheric_parameter_type,
1059                         { "Parameter Type",  "etheric.parameter_type",
1060                         FT_UINT8, BASE_DEC, NULL, 0x0,
1061                         "", HFILL }},
1062
1063                 { &hf_etheric_forw_call_isdn_access_indicator,
1064                         { "ISDN access indicator",  "etheric.forw_call_isdn_access_indicator",
1065                         FT_BOOLEAN, 16, TFS(&isup_ISDN_originating_access_ind_value), 0x01,
1066                         "", HFILL }},
1067
1068                 { &hf_etheric_calling_partys_category,
1069                         { "Calling Party's category",  "etheric.calling_partys_category",
1070                         FT_UINT8, BASE_HEX, VALS(etheric_calling_partys_category_value), 0x0,
1071                         "", HFILL }},
1072
1073                 { &hf_etheric_mandatory_variable_parameter_pointer,
1074                         { "Pointer to Parameter",  "etheric.mandatory_variable_parameter_pointer",
1075                         FT_UINT8, BASE_DEC, NULL, 0x0,
1076                         "", HFILL }},
1077
1078                 { &hf_etheric_pointer_to_start_of_optional_part,
1079                         { "Pointer to optional parameter part",  "etheric.optional_parameter_part_pointer",
1080                         FT_UINT8, BASE_DEC, NULL, 0x0,
1081                         "", HFILL }},
1082
1083                 { &hf_etheric_parameter_length,
1084                         { "Parameter Length",  "etheric.parameter_length",
1085                         FT_UINT8, BASE_DEC, NULL, 0x0,
1086                         "", HFILL }},
1087
1088                 { &hf_etheric_transmission_medium_requirement,
1089                         { "Transmission medium requirement",  "etheric.transmission_medium_requirement",
1090                         FT_UINT8, BASE_DEC, VALS(isup_transmission_medium_requirement_value), 0x0,
1091                         "", HFILL }},
1092
1093                 { &hf_etheric_odd_even_indicator,
1094                         { "Odd/even indicator",  "etheric.isdn_odd_even_indicator",
1095                         FT_BOOLEAN, 8, TFS(&isup_odd_even_ind_value), 0x80,
1096                         "", HFILL }},
1097
1098                 { &hf_etheric_called_party_nature_of_address_indicator,
1099                         { "Nature of address indicator",  "etheric.called_party_nature_of_address_indicator",
1100                         FT_UINT8, BASE_DEC, VALS(isup_called_party_nature_of_address_ind_value), 0x3f,
1101                         "", HFILL }},
1102
1103                 { &hf_etheric_calling_party_nature_of_address_indicator,
1104                         { "Nature of address indicator",  "etheric.calling_party_nature_of_address_indicator",
1105                         FT_UINT8, BASE_DEC, VALS(etheric_location_number_nature_of_address_ind_value), 0x7f,
1106                         "", HFILL }},
1107
1108
1109                 { &hf_etheric_ni_indicator,
1110                         { "NI indicator",  "etheric.ni_indicator",
1111                         FT_BOOLEAN, 8, TFS(&isup_NI_ind_value), 0x80,
1112                         "", HFILL }},
1113
1114                 { &hf_etheric_inn_indicator,
1115                         { "INN indicator",  "etheric.inn_indicator",
1116                         FT_BOOLEAN, 8, TFS(&isup_INN_ind_value), 0x80,
1117                         "", HFILL }},
1118
1119                 { &hf_etheric_numbering_plan_indicator,
1120                         { "Numbering plan indicator",  "etheric.numbering_plan_indicator",
1121                         FT_UINT8, BASE_DEC, VALS(isup_numbering_plan_ind_value), 0x70,
1122                         "", HFILL }},
1123
1124                 { &hf_etheric_address_presentation_restricted_indicator,
1125                         { "Address presentation restricted indicator",  "etheric.address_presentation_restricted_indicator",
1126                         FT_UINT8, BASE_DEC, VALS(isup_address_presentation_restricted_ind_value), 0x0c,
1127                         "", HFILL }},
1128
1129                 { &hf_etheric_screening_indicator,
1130                         { "Screening indicator",  "etheric.screening_indicator",
1131                         FT_UINT8, BASE_DEC, VALS(isup_screening_ind_value), 0x03,
1132                         "", HFILL }},
1133
1134                 { &hf_etheric_called_party_odd_address_signal_digit,
1135                         { "Address signal digit",  "etheric.called_party_odd_address_signal_digit",
1136                         FT_UINT8, BASE_DEC, VALS(isup_called_party_address_digit_value), 0x0F,
1137                         "", HFILL }},
1138
1139                 { &hf_etheric_calling_party_odd_address_signal_digit,
1140                         { "Address signal digit",  "etheric.calling_party_odd_address_signal_digit",
1141                         FT_UINT8, BASE_DEC, VALS(isup_calling_party_address_digit_value), 0x0F,
1142                         "", HFILL }},
1143
1144                 { &hf_etheric_called_party_even_address_signal_digit,
1145                         { "Address signal digit",  "etheric.called_party_even_address_signal_digit",
1146                         FT_UINT8, BASE_DEC, VALS(isup_called_party_address_digit_value), 0xF0,
1147                         "", HFILL }},
1148
1149                 { &hf_etheric_calling_party_even_address_signal_digit,
1150                         { "Address signal digit",  "etheric.calling_party_even_address_signal_digit",
1151                         FT_UINT8, BASE_DEC, VALS(isup_calling_party_address_digit_value), 0xF0,
1152                         "", HFILL }},
1153
1154                 { &hf_etheric_inband_information_ind,
1155                         { "In-band information indicator",  "etheric.inband_information_ind",
1156                         FT_BOOLEAN, 8, TFS(&isup_inband_information_ind_value), 0x01,
1157                         "", HFILL }},
1158
1159                 { &hf_etheric_cause_indicator,
1160                         { "Cause indicator",  "etheric.cause_indicator",
1161                         FT_UINT8, BASE_DEC, VALS(q850_cause_code_vals), 0x7f,
1162                         "", HFILL }},
1163
1164                 { &hf_etheric_event_ind,
1165                         { "Event indicator",  "etheric.event_ind",
1166                           FT_UINT8, 8, VALS(isup_event_ind_value), 0x7f,
1167                         "", HFILL }},
1168
1169                 { &hf_etheric_event_presentation_restricted_ind,
1170                         { "Event presentation restricted indicator",  "etheric.event_presentatiation_restr_ind",
1171                         FT_BOOLEAN, 8, TFS(&isup_event_presentation_restricted_ind_value), 0x80,
1172                         "", HFILL }},
1173
1174
1175         };
1176
1177 /* Setup protocol subtree array */
1178         static gint *ett[] = {
1179                 &ett_etheric,
1180                 &ett_etheric_parameter,
1181                 &ett_etheric_address_digits,
1182                 &ett_etheric_circuit_state_ind,
1183         };
1184
1185         module_t *etheric_module;
1186
1187 /* Register the protocol name and description */
1188         proto_etheric = proto_register_protocol("Etheric",
1189             "ETHERIC", "etheric");
1190
1191         new_register_dissector("etheric", dissect_etheric, proto_etheric);
1192
1193
1194 /* Required function calls to register the header fields and subtrees used */
1195         proto_register_field_array(proto_etheric, hf, array_length(hf));
1196         proto_register_subtree_array(ett, array_length(ett));
1197
1198
1199         /* Register a configuration option for port */
1200         etheric_module = prefs_register_protocol(proto_etheric,
1201                                                                                           proto_reg_handoff_etheric);
1202
1203         prefs_register_uint_preference(etheric_module, "tcp.port1",
1204                                                                    "etheric TCP Port 1",
1205                                                                    "Set TCP port 1 for etheric messages",
1206                                                                    10,
1207                                                                    &ethericTCPport1);
1208
1209         prefs_register_uint_preference(etheric_module, "tcp.port2",
1210                                                                    "etheric TCP Port 2",
1211                                                                    "Set TCP port 2 for etheric messages",
1212                                                                    10,
1213                                                                    &ethericTCPport2);
1214 }