1 /* packet-camel-template.c
2 * Routines for Camel
3 * Copyright 2004, Tim Endean <endeant@hotmail.com>
4 * Copyright 2005, Olivier Jacques <olivier.jacques@hp.com>
5 * Copyright 2005, Javier Acuna <javier.acuna@sixbell.com>
6 * Updated to ETSI TS 129 078 V6.4.0 (2004-3GPP TS 29.078 version 6.4.0 Release 6 1 12)
7 * Copyright 2005-2010, Anders Broman <anders.broman@ericsson.com>
8 * Updated to 3GPP TS 29.078 version 7.3.0 Release 7 (2006-06)
9 * Built from the gsm-map dissector Copyright 2004, Anders Broman <anders.broman@ericsson.com>
10 *
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
14 *
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 * References: ETSI 300 374
17 */
18 /*
19 * Indentation logic: this file is indented with 2 spaces indentation.
20 * there are no tabs.
21 */
22 #include "config.h"
23
24 #include <stdlib.h>
25
26 #include <epan/packet.h>
27 #include <epan/prefs.h>
28 #include <epan/oids.h>
29 #include <epan/tap.h>
30 #include <epan/srt_table.h>
31 #include <epan/stat_tap_ui.h>
32 #include <epan/asn1.h>
33 #include <epan/expert.h>
34 #include <wsutil/strtoi.h>
35
36 #include "packet-ber.h"
37 #include "packet-camel.h"
38 #include "packet-q931.h"
39 #include "packet-e164.h"
40 #include "packet-isup.h"
41 #include "packet-gsm_map.h"
42 #include "packet-gsm_a_common.h"
43 #include "packet-inap.h"
44 #include "packet-tcap.h"
45
46 #define PNAME "Camel"
47 #define PSNAME "CAMEL"
48 #define PFNAME "camel"
49
50 /* Initialize the protocol and registered fields */
51 static int proto_camel = -1;
52 int date_format = 1; /*assume european date format */
53 int camel_tap = -1;
54 /* Global variables */
55 static guint32 opcode=0;
56 static guint32 errorCode=0;
57 static guint32 camel_ver = 0;
58
59 /* When several Camel components are received in a single TCAP message,
60 we have to use several buffers for the stored parameters
61 because else this data are erased during TAP dissector call */
62 #define MAX_CAMEL_INSTANCE 10
63 static int camelsrt_global_current=0;
64 static struct camelsrt_info_t camelsrt_global_info[MAX_CAMEL_INSTANCE];
65
66 /* ROSE context */
67 static rose_ctx_t camel_rose_ctx;
68
69 static int hf_digit = -1;
70 static int hf_camel_extension_code_local = -1;
71 static int hf_camel_error_code_local = -1;
72 static int hf_camel_cause_indicator = -1;
73 static int hf_camel_PDPTypeNumber_etsi = -1;
74 static int hf_camel_PDPTypeNumber_ietf = -1;
75 static int hf_camel_PDPAddress_IPv4 = -1;
76 static int hf_camel_PDPAddress_IPv6 = -1;
77 static int hf_camel_cellGlobalIdOrServiceAreaIdFixedLength = -1;
78 static int hf_camel_RP_Cause = -1;
79 static int hf_camel_CAMEL_AChBillingChargingCharacteristics = -1;
80 static int hf_camel_CAMEL_FCIBillingChargingCharacteristics = -1;
81 static int hf_camel_CAMEL_FCIGPRSBillingChargingCharacteristics = -1;
82 static int hf_camel_CAMEL_FCISMSBillingChargingCharacteristics = -1;
83 static int hf_camel_CAMEL_SCIBillingChargingCharacteristics = -1;
84 static int hf_camel_CAMEL_SCIGPRSBillingChargingCharacteristics = -1;
85 static int hf_camel_CAMEL_CallResult = -1;
86
87 /* Used by persistent data */
88 static int hf_camelsrt_SessionId=-1;
89 static int hf_camelsrt_RequestNumber=-1;
90 static int hf_camelsrt_Duplicate=-1;
91 static int hf_camelsrt_RequestFrame=-1;
92 static int hf_camelsrt_ResponseFrame=-1;
93 static int hf_camelsrt_DeltaTime=-1;
94 static int hf_camelsrt_SessionTime=-1;
95 static int hf_camelsrt_DeltaTime31=-1;
96 static int hf_camelsrt_DeltaTime75=-1;
97 static int hf_camelsrt_DeltaTime65=-1;
98 static int hf_camelsrt_DeltaTime22=-1;
99 static int hf_camelsrt_DeltaTime35=-1;
100 static int hf_camelsrt_DeltaTime80=-1;
101
102 #include "packet-camel-hf.c"
103
104 static struct camelsrt_info_t * gp_camelsrt_info;
105
106 /* Forward declarations */
107 static int dissect_invokeData(proto_tree *tree, tvbuff_t *tvb, int offset,asn1_ctx_t *actx);
108 static int dissect_returnResultData(proto_tree *tree, tvbuff_t *tvb, int offset,asn1_ctx_t *actx);
109 static int dissect_returnErrorData(proto_tree *tree, tvbuff_t *tvb, int offset,asn1_ctx_t *actx);
110 static int dissect_camel_CAMEL_AChBillingChargingCharacteristics(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
111 static int dissect_camel_CAMEL_AChBillingChargingCharacteristicsV2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
112 static int dissect_camel_CAMEL_CallResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
113 static int dissect_camel_EstablishTemporaryConnectionArgV2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
114 static int dissect_camel_SpecializedResourceReportArgV23(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
115
116 /* XXX - can we get rid of these and always do the SRT work? */
117 static gboolean gcamel_HandleSRT=FALSE;
118 static gboolean gcamel_PersistentSRT=FALSE;
119 static gboolean gcamel_DisplaySRT=FALSE;
120 gboolean gcamel_StatSRT=FALSE;
121
122 /* Initialize the subtree pointers */
123 static gint ett_camel = -1;
124 static gint ett_camelisup_parameter = -1;
125 static gint ett_camel_AccessPointName = -1;
126 static gint ett_camel_pdptypenumber = -1;
127 static gint ett_camel_cause = -1;
128 static gint ett_camel_RPcause = -1;
129 static gint ett_camel_stat = -1;
130 static gint ett_camel_calledpartybcdnumber = -1;
131 static gint ett_camel_callingpartynumber = -1;
132 static gint ett_camel_originalcalledpartyid = -1;
133 static gint ett_camel_redirectingpartyid = -1;
134 static gint ett_camel_locationnumber = -1;
135 static gint ett_camel_additionalcallingpartynumber = -1;
136 static gint ett_camel_calledAddressValue = -1;
137 static gint ett_camel_callingAddressValue = -1;
138 static gint ett_camel_assistingSSPIPRoutingAddress = -1;
139 static gint ett_camel_correlationID = -1;
140 static gint ett_camel_dTMFDigitsCompleted = -1;
141 static gint ett_camel_dTMFDigitsTimeOut = -1;
142 static gint ett_camel_number = -1;
143 static gint ett_camel_digitsResponse = -1;
144
145 #include "packet-camel-ett.c"
146
147 static expert_field ei_camel_unknown_invokeData = EI_INIT;
148 static expert_field ei_camel_unknown_returnResultData = EI_INIT;
149 static expert_field ei_camel_unknown_returnErrorData = EI_INIT;
150
151 /* Preference settings default */
152 #define MAX_SSN 254
153 static range_t *global_ssn_range;
154 static dissector_handle_t camel_handle;
155 static dissector_handle_t camel_v1_handle;
156 static dissector_handle_t camel_v2_handle;
157 static dissector_handle_t camel_v3_handle;
158 static dissector_handle_t camel_v4_handle;
159
160 /* Global variables */
161
162 static guint8 PDPTypeOrganization;
163 static guint8 PDPTypeNumber;
164 const char *camel_obj_id = NULL;
165 gboolean is_ExtensionField =FALSE;
166
167 /* Global hash tables*/
168 static wmem_map_t *srt_calls = NULL;
169 static guint32 camelsrt_global_SessionId=1;
170
171 static int camel_opcode_type;
172 #define CAMEL_OPCODE_INVOKE 1
173 #define CAMEL_OPCODE_RETURN_RESULT 2
174 #define CAMEL_OPCODE_RETURN_ERROR 3
175 #define CAMEL_OPCODE_REJECT 4
176
177 static const value_string camel_Component_vals[] = {
178 { 1, "invoke" },
179 { 2, "returnResultLast" },
180 { 3, "returnError" },
181 { 4, "reject" },
182 { 0, NULL }
183 };
184
185 const value_string camelSRTtype_naming[]= {
186 { CAMELSRT_SESSION, "TCAP_Session" },
187 { CAMELSRT_VOICE_INITIALDP, "InialDP/Continue" },
188 { CAMELSRT_VOICE_ACR1, "Slice1_ACR/ACH" },
189 { CAMELSRT_VOICE_ACR2, "Slice2_ACR/ACH" },
190 { CAMELSRT_VOICE_ACR3, "Slice3_ACR/ACH" },
191 { CAMELSRT_VOICE_DISC, "EvtRepBSCM/Release" },
192 { CAMELSRT_SMS_INITIALDP, "InitialDP/ContinueSMS" },
193 { CAMELSRT_GPRS_INITIALDP, "InitialDP/ContinueGPRS" },
194 { CAMELSRT_GPRS_REPORT, "EvtRepGPRS/ContinueGPRS" },
195 { 0,NULL}
196 };
197
198 #define EUROPEAN_DATE 1
199 #define AMERICAN_DATE 2
200 #define CAMEL_DATE_AND_TIME_LEN 20 /* 2*5 + 4 + 5 + 1 (HH:MM:SS;mm/dd/yyyy) */
201
202 static const enum_val_t date_options[] = {
203 { "european", "DD/MM/YYYY", EUROPEAN_DATE },
204 { "american", "MM/DD/YYYY", AMERICAN_DATE },
205 { NULL, NULL, 0 }
206 };
207
208 static const value_string digit_value[] = {
209 { 0, "0"},
210 { 1, "1"},
211 { 2, "2"},
212 { 3, "3"},
213 { 4, "4"},
214 { 5, "5"},
215 { 6, "6"},
216 { 7, "7"},
217 { 8, "8"},
218 { 9, "9"},
219 { 10, "spare"},
220 { 11, "spare"},
221 { 12, "spare"},
222 { 13, "spare"},
223 { 0, NULL}
224
225 };
226
227
228 #if 0
229 static const value_string camel_nature_of_addr_indicator_values[] = {
230 { 0x00, "unknown" },
231 { 0x01, "International Number" },
232 { 0x02, "National Significant Number" },
233 { 0x03, "Network Specific Number" },
234 { 0x04, "Subscriber Number" },
235 { 0x05, "Reserved" },
236 { 0x06, "Abbreviated Number" },
237 { 0x07, "Reserved for extension" },
238 { 0, NULL }
239 };
240 static const value_string camel_number_plan_values[] = {
241 { 0x00, "unknown" },
242 { 0x01, "ISDN/Telephony Numbering (Rec ITU-T E.164)" },
243 { 0x02, "spare" },
244 { 0x03, "Data Numbering (ITU-T Rec. X.121)" },
245 { 0x04, "Telex Numbering (ITU-T Rec. F.69)" },
246 { 0x05, "spare" },
247 { 0x06, "Land Mobile Numbering (ITU-T Rec. E.212)" },
248 { 0x07, "spare" },
249 { 0x08, "National Numbering" },
250 { 0x09, "Private Numbering" },
251 { 0x0f, "Reserved for extension" },
252 { 0, NULL }
253 };
254 #endif
255
256 /* End includes from old" packet-camel.c */
257
258 static const value_string camel_RP_Cause_values[] = {
259 { 1, "Unassigned (unallocated) number" },
260 { 8, "Operator determined barring" },
261 { 10, "Call barred" },
262 { 11, "Reserved" },
263 { 21, "Short message transfer rejected" },
264 { 27, "Destination out of order" },
265 { 28, "Unidentified subscriber" },
266 { 29, "Facility Rejected" },
267 { 30, "Unknown subscriber" },
268 { 38, "Network out of order" },
269 { 41, "Temporary failure" },
270 { 42, "Congestion" },
271 { 47, "Resources unavailable, unspecified" },
272 { 50, "Requested facility not subscribed" },
273 { 69, "Requested facility not implemented" },
274 { 81, "Invalid short message transfer reference value" },
275 { 95, "Semantically incorrect message" },
276 { 96, "Invalid mandatory information" },
277 { 97, " Message Type non-existent or not implemented" },
278 { 98, "Message not compatible with short message protocol state" },
279 { 99, "Information element non existent or not implemented" },
280 { 111, "Protocol error, unspecified" },
281 { 127, "Interworking, unspecified" },
282 { 22,"Memory capacity exceeded" },
283 { 0, NULL }
284 };
285
286 static const value_string camel_holdTreatmentIndicator_values[] = {
287 { 0x01, "acceptHoldRequest" },
288 { 0x02, "rejectHoldRequest" },
289 { 0, NULL }
290 };
291 static const value_string camel_cwTreatmentIndicator_values[] = {
292 { 0x01, "acceptCw" },
293 { 0x02, "rejectCw" },
294 { 0, NULL }
295 };
296 static const value_string camel_ectTreatmentIndicator_values[] = {
297 { 0x01, "acceptEctRequest" },
298 { 0x02, "rejectEctRequest" },
299 { 0, NULL }
300 };
301
302 #include "packet-camel-val.h"
303
304 #include "packet-camel-table.c"
305
306 /*
307 * DEBUG fonctions
308 */
309
310 #undef DEBUG_CAMELSRT
311 /* #define DEBUG_CAMELSRT */
312
313 #ifdef DEBUG_CAMELSRT
314 #include <stdio.h>
315 #include <stdarg.h>
316 static guint debug_level = 99;
317
dbg(guint level,char * fmt,...)318 static void dbg(guint level, char *fmt, ...) {
319 va_list ap;
320
321 if (level > debug_level) return;
322 va_start(ap,fmt);
323 vfprintf(stderr, fmt, ap);
324 va_end(ap);
325 }
326 #endif
327
328 static void
camelstat_init(struct register_srt * srt _U_,GArray * srt_array)329 camelstat_init(struct register_srt* srt _U_, GArray* srt_array)
330 {
331 srt_stat_table *camel_srt_table;
332 gchar* tmp_str;
333 guint32 i;
334
335 camel_srt_table = init_srt_table("CAMEL Commands", NULL, srt_array, NB_CAMELSRT_CATEGORY, NULL, NULL, NULL);
336 for (i = 0; i < NB_CAMELSRT_CATEGORY; i++)
337 {
338 tmp_str = val_to_str_wmem(NULL,i,camelSRTtype_naming,"Unknown (%d)");
339 init_srt_table_row(camel_srt_table, i, tmp_str);
340 wmem_free(NULL, tmp_str);
341 }
342 }
343
344 static tap_packet_status
camelstat_packet(void * pcamel,packet_info * pinfo,epan_dissect_t * edt _U_,const void * psi)345 camelstat_packet(void *pcamel, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
346 {
347 guint idx = 0;
348 srt_stat_table *camel_srt_table;
349 const struct camelsrt_info_t * pi=(const struct camelsrt_info_t *)psi;
350 srt_data_t *data = (srt_data_t *)pcamel;
351 int i;
352
353 for (i=1; i<NB_CAMELSRT_CATEGORY; i++) {
354 if ( pi->bool_msginfo[i] &&
355 pi->msginfo[i].is_delta_time
356 && pi->msginfo[i].request_available
357 && !pi->msginfo[i].is_duplicate )
358 {
359 camel_srt_table = g_array_index(data->srt_array, srt_stat_table*, idx);
360 add_srt_table_data(camel_srt_table, i, &pi->msginfo[i].req_time, pinfo);
361 }
362 } /* category */
363 return TAP_PACKET_REDRAW;
364 }
365
366
camel_number_to_char(int number)367 static char camel_number_to_char(int number)
368 {
369 if (number < 10)
370 return (char) (number + 48 ); /* this is ASCII specific */
371 else
372 return (char) (number + 55 );
373 }
374
375 /*
376 * 24.011 8.2.5.4
377 */
378 static guint8
dissect_RP_cause_ie(tvbuff_t * tvb,guint32 offset,_U_ guint len,proto_tree * tree,int hf_cause_value,guint8 * cause_value)379 dissect_RP_cause_ie(tvbuff_t *tvb, guint32 offset, _U_ guint len,
380 proto_tree *tree, int hf_cause_value, guint8 *cause_value)
381 {
382 guint8 oct;
383 guint32 curr_offset;
384
385 curr_offset = offset;
386 oct = tvb_get_guint8(tvb, curr_offset);
387
388 *cause_value = oct & 0x7f;
389
390 proto_tree_add_uint(tree, hf_cause_value, tvb, curr_offset, 1, oct);
391 curr_offset++;
392
393 if ((oct & 0x80)) {
394 oct = tvb_get_guint8(tvb, curr_offset);
395 proto_tree_add_uint_format(tree, hf_cause_value,
396 tvb, curr_offset, 1, oct,
397 "Diagnostic : %u", oct);
398 curr_offset++;
399 }
400 return(curr_offset - offset);
401 }
402
403 static int dissect_camel_InitialDPArgExtensionV2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
404
405 #include "packet-camel-fn.c"
406
407 #include "packet-camel-table2.c"
408
409 /*
410 * Functions needed for Hash-Table
411 */
412
413 /* compare 2 keys */
414 static gint
camelsrt_call_equal(gconstpointer k1,gconstpointer k2)415 camelsrt_call_equal(gconstpointer k1, gconstpointer k2)
416 {
417 const struct camelsrt_call_info_key_t *key1 = (const struct camelsrt_call_info_key_t *) k1;
418 const struct camelsrt_call_info_key_t *key2 = (const struct camelsrt_call_info_key_t *) k2;
419
420 return (key1->SessionIdKey == key2->SessionIdKey) ;
421 }
422
423 /* calculate a hash key */
424 static guint
camelsrt_call_hash(gconstpointer k)425 camelsrt_call_hash(gconstpointer k)
426 {
427 const struct camelsrt_call_info_key_t *key = (const struct camelsrt_call_info_key_t *) k;
428 return key->SessionIdKey;
429 }
430
431 /*
432 * Find the dialog by Key and Time
433 */
434 static struct camelsrt_call_t *
find_camelsrt_call(struct camelsrt_call_info_key_t * p_camelsrt_call_key)435 find_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
436 {
437 struct camelsrt_call_t *p_camelsrt_call = NULL;
438 p_camelsrt_call = (struct camelsrt_call_t *)wmem_map_lookup(srt_calls, p_camelsrt_call_key);
439
440 #ifdef DEBUG_CAMELSRT
441 if(p_camelsrt_call) {
442 dbg(10,"D%d ", p_camelsrt_call->session_id);
443 } else {
444 dbg(23,"Not in hash ");
445 }
446 #endif
447
448 return p_camelsrt_call;
449 }
450
451 /*
452 * Initialize the data per call for the Service Response Time Statistics
453 * Data are linked to a Camel operation in a TCAP transaction
454 */
455 static void
raz_camelsrt_call(struct camelsrt_call_t * p_camelsrt_call)456 raz_camelsrt_call (struct camelsrt_call_t *p_camelsrt_call)
457 {
458 memset(p_camelsrt_call,0,sizeof(struct camelsrt_call_t));
459 }
460
461 /*
462 * New record to create, to identify a new transaction
463 */
464 static struct camelsrt_call_t *
new_camelsrt_call(struct camelsrt_call_info_key_t * p_camelsrt_call_key)465 new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
466 {
467 struct camelsrt_call_info_key_t *p_new_camelsrt_call_key;
468 struct camelsrt_call_t *p_new_camelsrt_call = NULL;
469
470 /* Register the transaction in the hash table
471 with the tcap transaction Id as main Key
472 Once created, this entry will be updated later */
473
474 p_new_camelsrt_call_key = wmem_new(wmem_file_scope(), struct camelsrt_call_info_key_t);
475 p_new_camelsrt_call_key->SessionIdKey = p_camelsrt_call_key->SessionIdKey;
476 p_new_camelsrt_call = wmem_new(wmem_file_scope(), struct camelsrt_call_t);
477 raz_camelsrt_call(p_new_camelsrt_call);
478 p_new_camelsrt_call->session_id = camelsrt_global_SessionId++;
479 #ifdef DEBUG_CAMELSRT
480 dbg(10,"D%d ", p_new_camelsrt_call->session_id);
481 #endif
482 /* store it */
483 wmem_map_insert(srt_calls, p_new_camelsrt_call_key, p_new_camelsrt_call);
484 return p_new_camelsrt_call;
485 }
486
487 /*
488 * Routine called when the TAP is initialized.
489 * so hash table are (re)created
490 */
491 static void
camelsrt_init_routine(void)492 camelsrt_init_routine(void)
493 {
494 /* Reset the session counter */
495 camelsrt_global_SessionId=1;
496
497 /* The Display of SRT is enable
498 * 1) For wireshark only if Persistent Stat is enable
499 * 2) For Tshark, if the SRT handling is enable
500 */
501 gcamel_DisplaySRT=gcamel_PersistentSRT || gcamel_HandleSRT&gcamel_StatSRT;
502 }
503
504
505 /*
506 * Update a record with the data of the Request
507 */
508 static void
update_camelsrt_call(struct camelsrt_call_t * p_camelsrt_call,packet_info * pinfo,guint msg_category)509 update_camelsrt_call(struct camelsrt_call_t *p_camelsrt_call, packet_info *pinfo,
510 guint msg_category)
511 {
512 p_camelsrt_call->category[msg_category].req_num = pinfo->num;
513 p_camelsrt_call->category[msg_category].rsp_num = 0;
514 p_camelsrt_call->category[msg_category].responded = FALSE;
515 p_camelsrt_call->category[msg_category].req_time = pinfo->abs_ts;
516 }
517
518 /*
519 * Update the Camel session info, and close the session.
520 * Then remove the associated context, if we do not have persistentSRT enable
521 */
522 static void
camelsrt_close_call_matching(packet_info * pinfo,struct camelsrt_info_t * p_camelsrt_info)523 camelsrt_close_call_matching(packet_info *pinfo,
524 struct camelsrt_info_t *p_camelsrt_info)
525 {
526 struct camelsrt_call_t *p_camelsrt_call;
527 struct camelsrt_call_info_key_t camelsrt_call_key;
528 nstime_t delta;
529
530 p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
531 #ifdef DEBUG_CAMELSRT
532 dbg(10,"\n Session end #%u\n", pinfo->num);
533 #endif
534 /* look only for matching request, if matching conversation is available. */
535 camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
536
537 #ifdef DEBUG_CAMELSRT
538 dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
539 #endif
540 p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
541 if(p_camelsrt_call) {
542 #ifdef DEBUG_CAMELSRT
543 dbg(12,"Found ");
544 #endif
545 /* Calculate Service Response Time */
546 nstime_delta(&delta, &pinfo->abs_ts, &p_camelsrt_call->category[CAMELSRT_SESSION].req_time);
547 p_camelsrt_call->category[CAMELSRT_SESSION].responded = TRUE;
548 p_camelsrt_info->msginfo[CAMELSRT_SESSION].request_available = TRUE;
549 p_camelsrt_info->msginfo[CAMELSRT_SESSION].is_delta_time = TRUE;
550 p_camelsrt_info->msginfo[CAMELSRT_SESSION].delta_time = delta; /* give it to tap */
551 p_camelsrt_info->msginfo[CAMELSRT_SESSION].req_time = p_camelsrt_call->category[CAMELSRT_SESSION].req_time;
552
553 if ( !gcamel_PersistentSRT ) {
554 wmem_map_remove(srt_calls, &camelsrt_call_key);
555 #ifdef DEBUG_CAMELSRT
556 dbg(20,"remove hash ");
557 #endif
558 } else {
559 #ifdef DEBUG_CAMELSRT
560 dbg(20,"keep hash ");
561 #endif
562 }
563 } /* call reference found */
564 }
565
566 /*
567 * Callback function for the TCAP dissector
568 * This callback function is used to inform the camel layer, that the session
569 * has been Closed or Aborted by a TCAP message without Camel component
570 * So, we can close the context for camel session, and update the stats.
571 */
572 static void
camelsrt_tcap_matching(tvbuff_t * tvb _U_,packet_info * pinfo,proto_tree * tree _U_,struct tcaphash_context_t * p_tcap_context)573 camelsrt_tcap_matching(tvbuff_t *tvb _U_, packet_info *pinfo,
574 proto_tree *tree _U_,
575 struct tcaphash_context_t *p_tcap_context)
576 {
577 struct camelsrt_info_t *p_camelsrt_info;
578
579 #ifdef DEBUG_CAMELSRT
580 dbg(11,"Camel_CallBack ");
581 #endif
582 p_camelsrt_info=camelsrt_razinfo();
583
584 p_camelsrt_info->tcap_context=p_tcap_context;
585 if (p_tcap_context) {
586 #ifdef DEBUG_CAMELSRT
587 dbg(11,"Close TCAP ");
588 #endif
589 p_camelsrt_info->tcap_session_id = p_tcap_context->session_id;
590 camelsrt_close_call_matching(pinfo, p_camelsrt_info);
591 tap_queue_packet(camel_tap, pinfo, p_camelsrt_info);
592 }
593 }
594
595 /*
596 * Create the record identifiying the Camel session
597 * As the Tcap session id given by the TCAP dissector is uniq, it will be
598 * used as main key.
599 */
600 static void
camelsrt_begin_call_matching(packet_info * pinfo,struct camelsrt_info_t * p_camelsrt_info)601 camelsrt_begin_call_matching(packet_info *pinfo,
602 struct camelsrt_info_t *p_camelsrt_info)
603 {
604 struct camelsrt_call_t *p_camelsrt_call;
605 struct camelsrt_call_info_key_t camelsrt_call_key;
606
607 p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
608
609 /* prepare the key data */
610 camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
611
612 /* look up the request */
613 #ifdef DEBUG_CAMELSRT
614 dbg(10,"\n Session begin #%u\n", pinfo->num);
615 dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
616 #endif
617 p_camelsrt_call = (struct camelsrt_call_t *)wmem_map_lookup(srt_calls, &camelsrt_call_key);
618 if (p_camelsrt_call) {
619 /* We have seen this request before -> do nothing */
620 #ifdef DEBUG_CAMELSRT
621 dbg(22,"Already seen ");
622 #endif
623 } else { /* p_camelsrt_call has not been found */
624 #ifdef DEBUG_CAMELSRT
625 dbg(10,"New key %lu ",camelsrt_call_key.SessionIdKey);
626 #endif
627 p_camelsrt_call = new_camelsrt_call(&camelsrt_call_key);
628 p_camelsrt_call->tcap_context=(struct tcaphash_context_t *)p_camelsrt_info->tcap_context;
629 update_camelsrt_call(p_camelsrt_call, pinfo,CAMELSRT_SESSION);
630
631 #ifdef DEBUG_CAMELSRT
632 dbg(11,"Update Callback ");
633 #endif
634 p_camelsrt_call->tcap_context->callback=camelsrt_tcap_matching;
635 }
636 }
637
638 /*
639 * Register the request, and try to find the response
640 *
641 */
642 static void
camelsrt_request_call_matching(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,struct camelsrt_info_t * p_camelsrt_info,guint srt_type)643 camelsrt_request_call_matching(tvbuff_t *tvb, packet_info *pinfo,
644 proto_tree *tree,
645 struct camelsrt_info_t *p_camelsrt_info,
646 guint srt_type )
647 {
648 struct camelsrt_call_t *p_camelsrt_call;
649 struct camelsrt_call_info_key_t camelsrt_call_key;
650 proto_item *ti, *hidden_item;
651
652 #ifdef DEBUG_CAMELSRT
653 dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->num);
654 #endif
655
656 /* look only for matching request, if matching conversation is available. */
657 camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
658
659 #ifdef DEBUG_CAMELSRT
660 dbg(11,"Search key %lu ", camelsrt_call_key.SessionIdKey);
661 #endif
662 p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
663 if(p_camelsrt_call) {
664 #ifdef DEBUG_CAMELSRT
665 dbg(12,"Found ");
666 #endif
667 if (gcamel_DisplaySRT)
668 proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
669
670
671 /* Hmm.. As there are several slices ApplyChargingReport/ApplyCharging
672 * we will prepare the measurement for 3 slices with 3 categories */
673 if (srt_type==CAMELSRT_VOICE_ACR1) {
674 if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num == 0) {
675 srt_type=CAMELSRT_VOICE_ACR1;
676 } else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num == 0)
677 && (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0)
678 && (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num < pinfo->num) ) {
679 srt_type=CAMELSRT_VOICE_ACR2;
680 } else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num == 0)
681 && (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0)
682 && (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num < pinfo->num) ) {
683 srt_type=CAMELSRT_VOICE_ACR3;
684 } else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
685 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num > pinfo->num) {
686 srt_type=CAMELSRT_VOICE_ACR1;
687 } else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0
688 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num > pinfo->num) {
689 srt_type=CAMELSRT_VOICE_ACR2;
690 } else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
691 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num > pinfo->num) {
692 srt_type=CAMELSRT_VOICE_ACR3;
693 }
694 #ifdef DEBUG_CAMELSRT
695 dbg(70,"Request ACR %u ",srt_type);
696 dbg(70,"ACR1 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num);
697 dbg(70,"ACR2 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num);
698 dbg(70,"ACR3 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num);
699 #endif
700 } /* not ACR */
701 p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
702
703
704 if (p_camelsrt_call->category[srt_type].req_num == 0) {
705 /* We have not yet seen a request to that call, so this must be the first request
706 remember its frame number. */
707 #ifdef DEBUG_CAMELSRT
708 dbg(5,"Set reqlink #%u ", pinfo->num);
709 #endif
710 update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
711 } else {
712 /* We have seen a request to this call - but was it *this* request? */
713 if (p_camelsrt_call->category[srt_type].req_num != pinfo->num) {
714
715 if (srt_type!=CAMELSRT_VOICE_DISC) {
716 /* No, so it's a duplicate request. Mark it as such. */
717 #ifdef DEBUG_CAMELSRT
718 dbg(21,"Display_duplicate with req %d ", p_camelsrt_call->category[srt_type].req_num);
719 #endif
720 p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
721 if (gcamel_DisplaySRT){
722 hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
723 proto_item_set_hidden(hidden_item);
724 }
725
726 } else {
727 /* Ignore duplicate frame */
728 if (pinfo->num > p_camelsrt_call->category[srt_type].req_num) {
729 p_camelsrt_call->category[srt_type].req_num = pinfo->num;
730 #ifdef DEBUG_CAMELSRT
731 dbg(5,"DISC Set reqlink #%u ", pinfo->num);
732 #endif
733 update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
734 } /* greater frame */
735 } /* DISC */
736 } /* req_num already seen */
737 } /* req_num != 0 */
738
739 /* add link to response frame, if available */
740 if ( gcamel_DisplaySRT &&
741 (p_camelsrt_call->category[srt_type].rsp_num != 0) &&
742 (p_camelsrt_call->category[srt_type].req_num != 0) &&
743 (p_camelsrt_call->category[srt_type].req_num == pinfo->num) ) {
744 #ifdef DEBUG_CAMELSRT
745 dbg(20,"Display_framersplink %d ",p_camelsrt_call->category[srt_type].rsp_num);
746 #endif
747 ti = proto_tree_add_uint_format(tree, hf_camelsrt_RequestFrame, tvb, 0, 0,
748 p_camelsrt_call->category[srt_type].rsp_num,
749 "Linked response %s in frame %u",
750 val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
751 p_camelsrt_call->category[srt_type].rsp_num);
752 proto_item_set_generated(ti);
753 } /* frame valid */
754 } /* call reference */
755 }
756
757 /*
758 * Display the delta time between two messages in a field corresponding
759 * to the category (hf_camelsrt_DeltaTimexx).
760 */
761 static void
camelsrt_display_DeltaTime(proto_tree * tree,tvbuff_t * tvb,nstime_t * value_ptr,guint category)762 camelsrt_display_DeltaTime(proto_tree *tree, tvbuff_t *tvb, nstime_t *value_ptr,
763 guint category)
764 {
765 proto_item *ti;
766
767 if ( gcamel_DisplaySRT ) {
768 switch(category) {
769 case CAMELSRT_VOICE_INITIALDP:
770 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime31, tvb, 0, 0, value_ptr);
771 proto_item_set_generated(ti);
772 break;
773
774 case CAMELSRT_VOICE_ACR1:
775 case CAMELSRT_VOICE_ACR2:
776 case CAMELSRT_VOICE_ACR3:
777 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime22, tvb, 0, 0, value_ptr);
778 proto_item_set_generated(ti);
779 break;
780
781 case CAMELSRT_VOICE_DISC:
782 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime35, tvb, 0, 0, value_ptr);
783 proto_item_set_generated(ti);
784 break;
785
786 case CAMELSRT_GPRS_INITIALDP:
787 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime75, tvb, 0, 0, value_ptr);
788 proto_item_set_generated(ti);
789 break;
790
791 case CAMELSRT_GPRS_REPORT:
792 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime80, tvb, 0, 0, value_ptr);
793 proto_item_set_generated(ti);
794 break;
795
796 case CAMELSRT_SMS_INITIALDP:
797 ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime65, tvb, 0, 0, value_ptr);
798 proto_item_set_generated(ti);
799 break;
800
801 default:
802 break;
803 }
804 }
805 }
806
807 /*
808 * Check if the received message is a response to a previous request
809 * registered is the camel session context.
810 */
811 static void
camelsrt_report_call_matching(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,struct camelsrt_info_t * p_camelsrt_info,guint srt_type)812 camelsrt_report_call_matching(tvbuff_t *tvb, packet_info *pinfo,
813 proto_tree *tree,
814 struct camelsrt_info_t *p_camelsrt_info,
815 guint srt_type)
816 {
817 struct camelsrt_call_t *p_camelsrt_call;
818 struct camelsrt_call_info_key_t camelsrt_call_key;
819 nstime_t delta;
820 proto_item *ti, *hidden_item;
821
822 #ifdef DEBUG_CAMELSRT
823 dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->num);
824 #endif
825 camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
826 /* look only for matching request, if matching conversation is available. */
827
828 #ifdef DEBUG_CAMELSRT
829 dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
830 #endif
831 p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
832 if(p_camelsrt_call) {
833 #ifdef DEBUG_CAMELSRT
834 dbg(12,"Found, req=%d ",p_camelsrt_call->category[srt_type].req_num);
835 #endif
836 if ( gcamel_DisplaySRT )
837 proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
838
839 if (srt_type==CAMELSRT_VOICE_ACR1) {
840 if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num != 0
841 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num < pinfo->num) {
842 srt_type=CAMELSRT_VOICE_ACR1;
843 } else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num != 0
844 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num < pinfo->num) {
845 srt_type=CAMELSRT_VOICE_ACR2;
846 } else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num != 0
847 && p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num < pinfo->num) {
848 srt_type=CAMELSRT_VOICE_ACR1;
849 }
850 #ifdef DEBUG_CAMELSRT
851 dbg(70,"Report ACR %u ",srt_type);
852 #endif
853 } /* not ACR */
854 p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
855
856 if (p_camelsrt_call->category[srt_type].rsp_num == 0) {
857 if ( (p_camelsrt_call->category[srt_type].req_num != 0)
858 && (pinfo->num > p_camelsrt_call->category[srt_type].req_num) ){
859 /* We have not yet seen a response to that call, so this must be the first response;
860 remember its frame number only if response comes after request */
861 #ifdef DEBUG_CAMELSRT
862 dbg(14,"Set reslink #%d req %u ",pinfo->num, p_camelsrt_call->category[srt_type].req_num);
863 #endif
864 p_camelsrt_call->category[srt_type].rsp_num = pinfo->num;
865
866 } else {
867 #ifdef DEBUG_CAMELSRT
868 dbg(2,"badreslink #%u req %u ",pinfo->num, p_camelsrt_call->category[srt_type].req_num);
869 #endif
870 } /* req_num != 0 */
871 } else { /* rsp_num != 0 */
872 /* We have seen a response to this call - but was it *this* response? */
873 if (p_camelsrt_call->category[srt_type].rsp_num != pinfo->num) {
874 /* No, so it's a duplicate response. Mark it as such. */
875 #ifdef DEBUG_CAMELSRT
876 dbg(21,"Display_duplicate rsp=%d ", p_camelsrt_call->category[srt_type].rsp_num);
877 #endif
878 p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
879 if ( gcamel_DisplaySRT ){
880 hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
881 proto_item_set_hidden(hidden_item);
882 }
883 }
884 } /* rsp_num != 0 */
885
886 if ( (p_camelsrt_call->category[srt_type].req_num != 0) &&
887 (p_camelsrt_call->category[srt_type].rsp_num != 0) &&
888 (p_camelsrt_call->category[srt_type].rsp_num == pinfo->num) ) {
889
890 p_camelsrt_call->category[srt_type].responded = TRUE;
891 p_camelsrt_info->msginfo[srt_type].request_available = TRUE;
892 #ifdef DEBUG_CAMELSRT
893 dbg(20,"Display_frameReqlink %d ",p_camelsrt_call->category[srt_type].req_num);
894 #endif
895 /* Indicate the frame to which this is a reply. */
896 if ( gcamel_DisplaySRT ) {
897 ti = proto_tree_add_uint_format(tree, hf_camelsrt_ResponseFrame, tvb, 0, 0,
898 p_camelsrt_call->category[srt_type].req_num,
899 "Linked request %s in frame %u",
900 val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
901 p_camelsrt_call->category[srt_type].req_num);
902 proto_item_set_generated(ti);
903 }
904 /* Calculate Service Response Time */
905 nstime_delta(&delta, &pinfo->abs_ts, &p_camelsrt_call->category[srt_type].req_time);
906
907 p_camelsrt_info->msginfo[srt_type].is_delta_time = TRUE;
908 p_camelsrt_info->msginfo[srt_type].delta_time = delta; /* give it to tap */
909 p_camelsrt_info->msginfo[srt_type].req_time = p_camelsrt_call->category[srt_type].req_time;
910
911 /* display Service Response Time and make it filterable */
912 camelsrt_display_DeltaTime(tree, tvb, &delta, srt_type);
913
914 } /*req_num != 0 && not duplicate */
915 } /* call reference found */
916 }
917
918 /*
919 * Service Response Time analyze, called just after the camel dissector
920 * According to the camel operation, we
921 * - open/close a context for the camel session
922 * - look for a request, or look for the corresponding response
923 */
924 void
camelsrt_call_matching(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,struct camelsrt_info_t * p_camelsrt_info)925 camelsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
926 struct camelsrt_info_t *p_camelsrt_info)
927 {
928
929 #ifdef DEBUG_CAMELSRT
930 dbg(10,"tcap_session #%d ", p_camelsrt_info->tcap_session_id);
931 #endif
932
933 switch (p_camelsrt_info->opcode) {
934
935 case 0: /*InitialDP*/
936 camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
937 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
938 CAMELSRT_VOICE_INITIALDP);
939 break;
940 case 60: /*InitialDPSMS*/
941 camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
942 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
943 CAMELSRT_SMS_INITIALDP);
944 break;
945 case 78: /*InitialDPGPRS*/
946 camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
947 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
948 CAMELSRT_GPRS_INITIALDP);
949 break;
950
951 case 23: /*RequestReportBCSMEvent*/
952 break;
953
954 case 63: /*RequestReportSMSEvent*/
955 break;
956
957 case 81: /*RequestReportGPRSEvent*/
958 break;
959
960 case 24: /*EventReportBCSMEvent*/
961 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
962 CAMELSRT_VOICE_DISC );
963 break;
964
965 case 64: /*EventReportSMS*/
966 /* Session has been explicity closed without TC_END */
967 camelsrt_close_call_matching(pinfo, p_camelsrt_info);
968 tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context, pinfo);
969 break;
970
971 case 80: /*EventReportGPRS*/
972 camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
973 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
974 CAMELSRT_GPRS_REPORT);
975 break;
976
977 case 35: /*ApplyCharging*/
978 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
979 CAMELSRT_VOICE_ACR1 );
980 break;
981
982 case 71: /*ApplyChargingGPRS*/
983 break;
984
985 case 36: /*ApplyChargingReport*/
986 camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
987 CAMELSRT_VOICE_ACR1 );
988 break;
989
990 case 72: /*ApplyChargingReportGPRS*/
991 break;
992
993 case 31: /*Continue*/
994 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
995 CAMELSRT_VOICE_INITIALDP);
996 break;
997 case 65: /*ContinueSMS*/
998 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
999 CAMELSRT_SMS_INITIALDP);
1000 break;
1001 case 75: /*ContinueGPRS*/
1002 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
1003 CAMELSRT_GPRS_INITIALDP);
1004 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
1005 CAMELSRT_GPRS_REPORT);
1006 break;
1007
1008 case 22: /*ReleaseCall*/
1009 camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
1010 CAMELSRT_VOICE_DISC);
1011 /* Session has been closed by Network */
1012 camelsrt_close_call_matching(pinfo, p_camelsrt_info);
1013 break;
1014
1015 case 66: /*ReleaseSMS*/
1016 /* Session has been closed by Network */
1017 camelsrt_close_call_matching(pinfo, p_camelsrt_info);
1018 tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context,pinfo);
1019 break;
1020
1021 case 79: /*ReleaseGPRS*/
1022 /* Session has been closed by Network */
1023 camelsrt_close_call_matching(pinfo, p_camelsrt_info);
1024 break;
1025 } /* switch opcode */
1026 }
1027
1028 /*
1029 * Initialize the Message Info used by the main dissector
1030 * Data are linked to a TCAP transaction
1031 */
1032 struct camelsrt_info_t *
camelsrt_razinfo(void)1033 camelsrt_razinfo(void)
1034 {
1035 struct camelsrt_info_t *p_camelsrt_info ;
1036
1037 /* Global buffer for packet extraction */
1038 camelsrt_global_current++;
1039 if(camelsrt_global_current==MAX_CAMEL_INSTANCE){
1040 camelsrt_global_current=0;
1041 }
1042
1043 p_camelsrt_info=&camelsrt_global_info[camelsrt_global_current];
1044 memset(p_camelsrt_info,0,sizeof(struct camelsrt_info_t));
1045
1046 p_camelsrt_info->opcode=255;
1047
1048 return p_camelsrt_info;
1049 }
1050
1051
1052 static guint8 camel_pdu_type = 0;
1053 static guint8 camel_pdu_size = 0;
1054
1055
1056 static int
dissect_camel_camelPDU(gboolean implicit_tag _U_,tvbuff_t * tvb,int offset,asn1_ctx_t * actx _U_,proto_tree * tree,int hf_index,struct tcap_private_t * p_private_tcap)1057 dissect_camel_camelPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_,proto_tree *tree,
1058 int hf_index, struct tcap_private_t * p_private_tcap) {
1059
1060 opcode = 0;
1061 if (p_private_tcap != NULL){
1062 gp_camelsrt_info->tcap_context=p_private_tcap->context;
1063 if (p_private_tcap->context)
1064 gp_camelsrt_info->tcap_session_id = ( (struct tcaphash_context_t *) (p_private_tcap->context))->session_id;
1065 }
1066
1067 camel_pdu_type = tvb_get_guint8(tvb, offset)&0x0f;
1068 /* Get the length and add 2 */
1069 camel_pdu_size = tvb_get_guint8(tvb, offset+1)+2;
1070
1071 /* Populate the info column with PDU type*/
1072 col_add_str(actx->pinfo->cinfo, COL_INFO, val_to_str(camel_pdu_type, camel_Component_vals, "Unknown Camel (%u)"));
1073 col_append_str(actx->pinfo->cinfo, COL_INFO, " ");
1074
1075 is_ExtensionField =FALSE;
1076 offset = dissect_camel_ROS(TRUE, tvb, offset, actx, tree, hf_index);
1077
1078 return offset;
1079 }
1080
1081 static int
dissect_camel_all(int version,const char * col_protocol,const char * suffix,tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1082 dissect_camel_all(int version, const char* col_protocol, const char* suffix,
1083 tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1084 {
1085 proto_item *item;
1086 proto_tree *tree = NULL, *stat_tree = NULL;
1087 struct tcap_private_t * p_private_tcap = (struct tcap_private_t*)data;
1088 asn1_ctx_t asn1_ctx;
1089 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1090
1091 col_set_str(pinfo->cinfo, COL_PROTOCOL, col_protocol);
1092
1093 camel_ver = version;
1094
1095 /* create display subtree for the protocol */
1096 if(parent_tree){
1097 item = proto_tree_add_item(parent_tree, proto_camel, tvb, 0, -1, ENC_NA);
1098 tree = proto_item_add_subtree(item, ett_camel);
1099 proto_item_append_text(item, "%s", suffix);
1100 }
1101 /* camelsrt reset counter, and initialise global pointer
1102 to store service response time related data */
1103 gp_camelsrt_info=camelsrt_razinfo();
1104
1105 dissect_camel_camelPDU(FALSE, tvb, 0, &asn1_ctx , tree, -1, p_private_tcap);
1106
1107 /* If a Tcap context is associated to this transaction */
1108 if (gcamel_HandleSRT &&
1109 gp_camelsrt_info->tcap_context ) {
1110 if (gcamel_DisplaySRT && tree) {
1111 stat_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_camel_stat, NULL, "Stat");
1112 }
1113 camelsrt_call_matching(tvb, pinfo, stat_tree, gp_camelsrt_info);
1114 tap_queue_packet(camel_tap, pinfo, gp_camelsrt_info);
1115 }
1116
1117 return tvb_captured_length(tvb);
1118 }
1119
1120 static int
dissect_camel_v1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1121 dissect_camel_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1122 {
1123 return dissect_camel_all(1, "Camel-v1", "-V1", tvb, pinfo, parent_tree, data);
1124 }
1125
1126 static int
dissect_camel_v2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1127 dissect_camel_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1128 {
1129 return dissect_camel_all(2, "Camel-v2", "-V2", tvb, pinfo, parent_tree, data);
1130 }
1131
1132 static int
dissect_camel_v3(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1133 dissect_camel_v3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1134 {
1135 return dissect_camel_all(3, "Camel-v3", "-V3", tvb, pinfo, parent_tree, data);
1136 }
1137
1138 static int
dissect_camel_v4(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1139 dissect_camel_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1140 {
1141 return dissect_camel_all(4, "Camel-v4", "-V4", tvb, pinfo, parent_tree, data);
1142 }
1143
1144 static int
dissect_camel(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)1145 dissect_camel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
1146 {
1147 return dissect_camel_all(4, "Camel", "", tvb, pinfo, parent_tree, data);
1148 }
1149
1150 /* TAP STAT INFO */
1151 typedef enum
1152 {
1153 MESSAGE_TYPE_COLUMN = 0,
1154 COUNT_COLUMN
1155 } camel_stat_columns;
1156
1157 static stat_tap_table_item camel_stat_fields[] = {{TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Message Type or Reason", "%-25s"}, {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", "%d"}};
1158
camel_stat_init(stat_tap_table_ui * new_stat)1159 static void camel_stat_init(stat_tap_table_ui* new_stat)
1160 {
1161 const char *table_name = "CAMEL Message Counters";
1162 int num_fields = sizeof(camel_stat_fields)/sizeof(stat_tap_table_item);
1163 stat_tap_table *table;
1164 int i;
1165 stat_tap_table_item_type items[sizeof(camel_stat_fields)/sizeof(stat_tap_table_item)];
1166
1167 table = stat_tap_find_table(new_stat, table_name);
1168 if (table) {
1169 if (new_stat->stat_tap_reset_table_cb) {
1170 new_stat->stat_tap_reset_table_cb(table);
1171 }
1172 return;
1173 }
1174
1175 table = stat_tap_init_table(table_name, num_fields, 0, NULL);
1176 stat_tap_add_table(new_stat, table);
1177
1178 items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING;
1179 items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
1180 items[COUNT_COLUMN].value.uint_value = 0;
1181
1182 /* Add a row for each value type */
1183 for (i = 0; i < camel_MAX_NUM_OPR_CODES; i++)
1184 {
1185 const char *ocs = try_val_to_str(i, camel_opr_code_strings);
1186 char *col_str;
1187 if (ocs) {
1188 col_str = g_strdup_printf("Request %s", ocs);
1189 } else {
1190 col_str = g_strdup_printf("Unknown op code %d", i);
1191 }
1192
1193 items[MESSAGE_TYPE_COLUMN].value.string_value = col_str;
1194 stat_tap_init_table_row(table, i, num_fields, items);
1195 }
1196 }
1197
1198 static tap_packet_status
camel_stat_packet(void * tapdata,packet_info * pinfo _U_,epan_dissect_t * edt _U_,const void * csi_ptr)1199 camel_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *csi_ptr)
1200 {
1201 stat_data_t* stat_data = (stat_data_t*)tapdata;
1202 const struct camelsrt_info_t *csi = (const struct camelsrt_info_t *) csi_ptr;
1203 stat_tap_table* table;
1204 stat_tap_table_item_type* msg_data;
1205
1206 table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0);
1207 if (csi->opcode >= table->num_elements)
1208 return TAP_PACKET_DONT_REDRAW;
1209 msg_data = stat_tap_get_field_data(table, csi->opcode, COUNT_COLUMN);
1210 msg_data->value.uint_value++;
1211 stat_tap_set_field_data(table, csi->opcode, COUNT_COLUMN, msg_data);
1212
1213 return TAP_PACKET_REDRAW;
1214 }
1215
1216 static void
camel_stat_reset(stat_tap_table * table)1217 camel_stat_reset(stat_tap_table* table)
1218 {
1219 guint element;
1220 stat_tap_table_item_type* item_data;
1221
1222 for (element = 0; element < table->num_elements; element++)
1223 {
1224 item_data = stat_tap_get_field_data(table, element, COUNT_COLUMN);
1225 item_data->value.uint_value = 0;
1226 stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
1227 }
1228 }
1229
1230 static void
camel_stat_free_table_item(stat_tap_table * table _U_,guint row _U_,guint column,stat_tap_table_item_type * field_data)1231 camel_stat_free_table_item(stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data)
1232 {
1233 if (column != MESSAGE_TYPE_COLUMN) return;
1234 g_free((char*)field_data->value.string_value);
1235 }
1236
1237 /*--- proto_reg_handoff_camel ---------------------------------------*/
range_delete_callback(guint32 ssn,gpointer ptr _U_)1238 static void range_delete_callback(guint32 ssn, gpointer ptr _U_)
1239 {
1240 if (ssn) {
1241 delete_itu_tcap_subdissector(ssn, camel_handle);
1242 }
1243 }
1244
range_add_callback(guint32 ssn,gpointer ptr _U_)1245 static void range_add_callback(guint32 ssn, gpointer ptr _U_)
1246 {
1247 if (ssn) {
1248 add_itu_tcap_subdissector(ssn, camel_handle);
1249 }
1250 }
1251
proto_reg_handoff_camel(void)1252 void proto_reg_handoff_camel(void) {
1253 static gboolean camel_prefs_initialized = FALSE;
1254 static range_t *ssn_range;
1255
1256 if (!camel_prefs_initialized) {
1257
1258 camel_prefs_initialized = TRUE;
1259
1260 register_ber_oid_dissector_handle("0.4.0.0.1.0.50.0",camel_v1_handle, proto_camel, "CAP-v1-gsmSSF-to-gsmSCF-AC" );
1261 register_ber_oid_dissector_handle("0.4.0.0.1.0.50.1",camel_v2_handle, proto_camel, "CAP-v2-gsmSSF-to-gsmSCF-AC" );
1262 register_ber_oid_dissector_handle("0.4.0.0.1.0.51.1",camel_v2_handle, proto_camel, "CAP-v2-assist-gsmSSF-to-gsmSCF-AC" );
1263 register_ber_oid_dissector_handle("0.4.0.0.1.0.52.1",camel_v2_handle, proto_camel, "CAP-v2-gsmSRF-to-gsmSCF-AC" );
1264
1265 /* CAMEL Phase 3 Application Context Names */
1266 register_ber_oid_dissector_handle("0.4.0.0.1.21.3.4", camel_v3_handle, proto_camel, "capssf-scfGenericAC");
1267 register_ber_oid_dissector_handle("0.4.0.0.1.21.3.6", camel_v3_handle, proto_camel, "capssf-scfAssistHandoffAC");
1268 register_ber_oid_dissector_handle("0.4.0.0.1.20.3.14", camel_v3_handle, proto_camel, "gsmSRF-gsmSCF-ac");
1269 register_ber_oid_dissector_handle("0.4.0.0.1.21.3.50", camel_v3_handle, proto_camel, "cap3-gprssf-scfAC");
1270 register_ber_oid_dissector_handle("0.4.0.0.1.21.3.51", camel_v3_handle, proto_camel, "cap3-gsmscf-gprsssfAC");
1271 register_ber_oid_dissector_handle("0.4.0.0.1.21.3.61", camel_v3_handle, proto_camel, "cap3-sms-AC");
1272
1273 /* CAMEL Phase 4 Application Context Names */
1274 register_ber_oid_dissector_handle("0.4.0.0.1.23.3.4", camel_v4_handle, proto_camel, "capssf-scfGenericAC");
1275 register_ber_oid_dissector_handle("0.4.0.0.1.23.3.6", camel_v4_handle, proto_camel, "capssf-scfAssistHandoffAC");
1276 register_ber_oid_dissector_handle("0.4.0.0.1.23.3.8", camel_v4_handle, proto_camel, "capscf-ssfGenericAC");
1277 register_ber_oid_dissector_handle("0.4.0.0.1.22.3.14", camel_v4_handle, proto_camel, "gsmSRF-gsmSCF-ac");
1278 register_ber_oid_dissector_handle("0.4.0.0.1.23.3.61", camel_v4_handle, proto_camel, "cap4-sms-AC");
1279
1280
1281 #include "packet-camel-dis-tab.c"
1282 } else {
1283 range_foreach(ssn_range, range_delete_callback, NULL);
1284 wmem_free(wmem_epan_scope(), ssn_range);
1285 }
1286
1287 ssn_range = range_copy(wmem_epan_scope(), global_ssn_range);
1288
1289 range_foreach(ssn_range, range_add_callback, NULL);
1290
1291 }
1292
proto_register_camel(void)1293 void proto_register_camel(void) {
1294 module_t *camel_module;
1295 /* List of fields */
1296 static hf_register_info hf[] = {
1297 { &hf_camel_extension_code_local,
1298 { "local", "camel.extension_code_local",
1299 FT_INT32, BASE_DEC, NULL, 0,
1300 "Extension local code", HFILL }},
1301 { &hf_camel_error_code_local,
1302 { "local", "camel.error_code_local",
1303 FT_INT32, BASE_DEC, VALS(camel_err_code_string_vals), 0,
1304 "ERROR code", HFILL }},
1305 { &hf_camel_cause_indicator, /* Currently not enabled */
1306 { "Cause indicator", "camel.cause_indicator",
1307 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &q850_cause_code_vals_ext, 0x7f,
1308 NULL, HFILL }},
1309 { &hf_digit,
1310 { "Digit Value", "camel.digit_value",
1311 FT_UINT8, BASE_DEC, VALS(digit_value), 0, NULL, HFILL }},
1312 { &hf_camel_PDPTypeNumber_etsi,
1313 { "ETSI defined PDP Type Value", "camel.PDPTypeNumber_etsi",
1314 FT_UINT8, BASE_HEX, VALS(gsm_map_etsi_defined_pdp_vals), 0,
1315 NULL, HFILL }},
1316 { &hf_camel_PDPTypeNumber_ietf,
1317 { "IETF defined PDP Type Value", "camel.PDPTypeNumber_ietf",
1318 FT_UINT8, BASE_HEX, VALS(gsm_map_ietf_defined_pdp_vals), 0,
1319 NULL, HFILL }},
1320 { &hf_camel_PDPAddress_IPv4,
1321 { "PDPAddress IPv4", "camel.PDPAddress_IPv4",
1322 FT_IPv4, BASE_NONE, NULL, 0,
1323 "IPAddress IPv4", HFILL }},
1324 { &hf_camel_PDPAddress_IPv6,
1325 { "PDPAddress IPv6", "camel.PDPAddress_IPv6",
1326 FT_IPv6, BASE_NONE, NULL, 0,
1327 "IPAddress IPv6", HFILL }},
1328 { &hf_camel_cellGlobalIdOrServiceAreaIdFixedLength,
1329 { "CellGlobalIdOrServiceAreaIdFixedLength", "camel.CellGlobalIdOrServiceAreaIdFixedLength",
1330 FT_BYTES, BASE_NONE, NULL, 0,
1331 "LocationInformationGPRS/CellGlobalIdOrServiceAreaIdOrLAI", HFILL }},
1332 { &hf_camel_RP_Cause,
1333 { "RP Cause", "camel.RP_Cause",
1334 FT_UINT8, BASE_DEC, VALS(camel_RP_Cause_values), 0x7F,
1335 "RP Cause Value", HFILL }},
1336
1337 { &hf_camel_CAMEL_AChBillingChargingCharacteristics,
1338 { "CAMEL-AChBillingChargingCharacteristics", "camel.CAMEL_AChBillingChargingCharacteristics",
1339 FT_UINT32, BASE_DEC, VALS(camel_CAMEL_AChBillingChargingCharacteristics_vals), 0,
1340 NULL, HFILL }},
1341
1342 { &hf_camel_CAMEL_FCIBillingChargingCharacteristics,
1343 { "CAMEL-FCIBillingChargingCharacteristics", "camel.CAMEL_FCIBillingChargingCharacteristics",
1344 FT_UINT32, BASE_DEC, VALS(camel_CAMEL_FCIBillingChargingCharacteristics_vals), 0,
1345 NULL, HFILL }},
1346
1347 { &hf_camel_CAMEL_FCIGPRSBillingChargingCharacteristics,
1348 { "CAMEL-FCIGPRSBillingChargingCharacteristics", "camel.CAMEL_FCIGPRSBillingChargingCharacteristics",
1349 FT_UINT32, BASE_DEC, NULL, 0,
1350 NULL, HFILL }},
1351
1352 { &hf_camel_CAMEL_FCISMSBillingChargingCharacteristics,
1353 { "CAMEL-FCISMSBillingChargingCharacteristics", "camel.CAMEL_FCISMSBillingChargingCharacteristics",
1354 FT_UINT32, BASE_DEC, VALS(camel_CAMEL_FCISMSBillingChargingCharacteristics_vals), 0,
1355 NULL, HFILL }},
1356
1357 { &hf_camel_CAMEL_SCIBillingChargingCharacteristics,
1358 { "CAMEL-SCIBillingChargingCharacteristics", "camel.CAMEL_SCIBillingChargingCharacteristics",
1359 FT_UINT32, BASE_DEC, VALS(camel_CAMEL_SCIBillingChargingCharacteristics_vals), 0,
1360 NULL, HFILL }},
1361
1362 { &hf_camel_CAMEL_SCIGPRSBillingChargingCharacteristics,
1363 { "CAMEL-SCIGPRSBillingChargingCharacteristics", "camel.CAMEL_SCIGPRSBillingChargingCharacteristics",
1364 FT_UINT32, BASE_DEC, NULL, 0,
1365 "CAMEL-FSCIGPRSBillingChargingCharacteristics", HFILL }},
1366
1367 { &hf_camel_CAMEL_CallResult,
1368 { "CAMEL-CAMEL_CallResult", "camel.CAMEL_CallResult",
1369 FT_UINT32, BASE_DEC, VALS(camel_CAMEL_CallResult_vals), 0,
1370 "CAMEL-CallResult", HFILL }},
1371
1372 /* Camel Service Response Time */
1373 { &hf_camelsrt_SessionId,
1374 { "Session Id",
1375 "camel.srt.session_id",
1376 FT_UINT32, BASE_DEC, NULL, 0x0,
1377 NULL, HFILL }
1378 },
1379 { &hf_camelsrt_RequestNumber,
1380 { "Request Number",
1381 "camel.srt.request_number",
1382 FT_UINT64, BASE_DEC, NULL, 0x0,
1383 NULL, HFILL }
1384 },
1385 { &hf_camelsrt_Duplicate,
1386 { "Request Duplicate",
1387 "camel.srt.duplicate",
1388 FT_UINT32, BASE_DEC, NULL, 0x0,
1389 NULL, HFILL }
1390 },
1391 { &hf_camelsrt_RequestFrame,
1392 { "Requested Frame",
1393 "camel.srt.reqframe",
1394 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1395 "SRT Request Frame", HFILL }
1396 },
1397 { &hf_camelsrt_ResponseFrame,
1398 { "Response Frame",
1399 "camel.srt.rspframe",
1400 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1401 "SRT Response Frame", HFILL }
1402 },
1403 { &hf_camelsrt_DeltaTime,
1404 { "Service Response Time",
1405 "camel.srt.deltatime",
1406 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1407 "DeltaTime between Request and Response", HFILL }
1408 },
1409 { &hf_camelsrt_SessionTime,
1410 { "Session duration",
1411 "camel.srt.sessiontime",
1412 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1413 "Duration of the TCAP session", HFILL }
1414 },
1415 { &hf_camelsrt_DeltaTime31,
1416 { "Service Response Time",
1417 "camel.srt.deltatime31",
1418 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1419 "DeltaTime between InitialDP and Continue", HFILL }
1420 },
1421 { &hf_camelsrt_DeltaTime65,
1422 { "Service Response Time",
1423 "camel.srt.deltatime65",
1424 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1425 "DeltaTime between InitialDPSMS and ContinueSMS", HFILL }
1426 },
1427 { &hf_camelsrt_DeltaTime75,
1428 { "Service Response Time",
1429 "camel.srt.deltatime75",
1430 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1431 "DeltaTime between InitialDPGPRS and ContinueGPRS", HFILL }
1432 },
1433 { &hf_camelsrt_DeltaTime35,
1434 { "Service Response Time",
1435 "camel.srt.deltatime35",
1436 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1437 "DeltaTime between ApplyChargingReport and ApplyCharging", HFILL }
1438 },
1439 { &hf_camelsrt_DeltaTime22,
1440 { "Service Response Time",
1441 "camel.srt.deltatime22",
1442 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1443 "DeltaTime between EventReport(Disconnect) and Release Call", HFILL }
1444 },
1445 { &hf_camelsrt_DeltaTime80,
1446 { "Service Response Time",
1447 "camel.srt.deltatime80",
1448 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1449 "DeltaTime between EventReportGPRS and ContinueGPRS", HFILL }
1450 },
1451
1452 #ifdef REMOVED
1453 #endif
1454 #include "packet-camel-hfarr.c"
1455 };
1456
1457 /* List of subtrees */
1458 static gint *ett[] = {
1459 &ett_camel,
1460 &ett_camelisup_parameter,
1461 &ett_camel_AccessPointName,
1462 &ett_camel_pdptypenumber,
1463 &ett_camel_cause,
1464 &ett_camel_RPcause,
1465 &ett_camel_stat,
1466 &ett_camel_calledpartybcdnumber,
1467 &ett_camel_callingpartynumber,
1468 &ett_camel_originalcalledpartyid,
1469 &ett_camel_redirectingpartyid,
1470 &ett_camel_locationnumber,
1471 &ett_camel_additionalcallingpartynumber,
1472 &ett_camel_calledAddressValue,
1473 &ett_camel_callingAddressValue,
1474 &ett_camel_assistingSSPIPRoutingAddress,
1475 &ett_camel_correlationID,
1476 &ett_camel_dTMFDigitsCompleted,
1477 &ett_camel_dTMFDigitsTimeOut,
1478 &ett_camel_number,
1479 &ett_camel_digitsResponse,
1480
1481 #include "packet-camel-ettarr.c"
1482 };
1483
1484 static ei_register_info ei[] = {
1485 { &ei_camel_unknown_invokeData, { "camel.unknown.invokeData", PI_MALFORMED, PI_WARN, "Unknown invokeData", EXPFILL }},
1486 { &ei_camel_unknown_returnResultData, { "camel.unknown.returnResultData", PI_MALFORMED, PI_WARN, "Unknown returnResultData", EXPFILL }},
1487 { &ei_camel_unknown_returnErrorData, { "camel.unknown.returnErrorData", PI_MALFORMED, PI_WARN, "Unknown returnResultData", EXPFILL }},
1488 };
1489
1490 expert_module_t* expert_camel;
1491
1492 static tap_param camel_stat_params[] = {
1493 { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
1494 };
1495
1496 static stat_tap_table_ui camel_stat_table = {
1497 REGISTER_STAT_GROUP_TELEPHONY_GSM,
1498 "CAMEL Messages and Response Status",
1499 PSNAME,
1500 "camel,counter",
1501 camel_stat_init,
1502 camel_stat_packet,
1503 camel_stat_reset,
1504 camel_stat_free_table_item,
1505 NULL,
1506 sizeof(camel_stat_fields)/sizeof(stat_tap_table_item), camel_stat_fields,
1507 sizeof(camel_stat_params)/sizeof(tap_param), camel_stat_params,
1508 NULL,
1509 0
1510 };
1511
1512 /* Register protocol */
1513 proto_camel = proto_register_protocol(PNAME, PSNAME, PFNAME);
1514
1515 camel_handle = register_dissector("camel", dissect_camel, proto_camel);
1516 camel_v1_handle = register_dissector("camel-v1", dissect_camel_v1, proto_camel);
1517 camel_v2_handle = register_dissector("camel-v2", dissect_camel_v2, proto_camel);
1518 camel_v3_handle = register_dissector("camel-v3", dissect_camel_v3, proto_camel);
1519 camel_v4_handle = register_dissector("camel-v4", dissect_camel_v4, proto_camel);
1520
1521 proto_register_field_array(proto_camel, hf, array_length(hf));
1522 proto_register_subtree_array(ett, array_length(ett));
1523 expert_camel = expert_register_protocol(proto_camel);
1524 expert_register_field_array(expert_camel, ei, array_length(ei));
1525
1526 rose_ctx_init(&camel_rose_ctx);
1527
1528 /* Register dissector tables */
1529 camel_rose_ctx.arg_local_dissector_table = register_dissector_table("camel.ros.local.arg",
1530 "CAMEL Operation Argument (local opcode)", proto_camel,
1531 FT_UINT32, BASE_HEX);
1532 camel_rose_ctx.res_local_dissector_table = register_dissector_table("camel.ros.local.res",
1533 "CAMEL Operation Result (local opcode)", proto_camel,
1534 FT_UINT32, BASE_HEX);
1535 camel_rose_ctx.err_local_dissector_table = register_dissector_table("camel.ros.local.err",
1536 "CAMEL Error (local opcode)", proto_camel,
1537 FT_UINT32, BASE_HEX);
1538
1539 /* Register our configuration options, particularly our SSNs */
1540 /* Set default SSNs */
1541 range_convert_str(wmem_epan_scope(), &global_ssn_range, "146", MAX_SSN);
1542
1543 camel_module = prefs_register_protocol(proto_camel, proto_reg_handoff_camel);
1544
1545 prefs_register_enum_preference(camel_module, "date.format", "Date Format",
1546 "The date format: (DD/MM) or (MM/DD)",
1547 &date_format, date_options, FALSE);
1548
1549
1550 prefs_register_range_preference(camel_module, "tcap.ssn",
1551 "TCAP SSNs",
1552 "TCAP Subsystem numbers used for Camel",
1553 &global_ssn_range, MAX_SSN);
1554
1555 prefs_register_bool_preference(camel_module, "srt",
1556 "Analyze Service Response Time",
1557 "Enable response time analysis",
1558 &gcamel_HandleSRT);
1559
1560 prefs_register_bool_preference(camel_module, "persistentsrt",
1561 "Persistent stats for SRT",
1562 "Statistics for Response Time",
1563 &gcamel_PersistentSRT);
1564
1565 /* Routine for statistic */
1566 register_init_routine(&camelsrt_init_routine);
1567
1568 /* create new hash-table for SRT */
1569 srt_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), camelsrt_call_hash, camelsrt_call_equal);
1570
1571 camel_tap=register_tap(PSNAME);
1572
1573 register_srt_table(proto_camel, PSNAME, 1, camelstat_packet, camelstat_init, NULL);
1574 register_stat_tap_table_ui(&camel_stat_table);
1575 }
1576
1577 /*
1578 * Editor modelines
1579 *
1580 * Local Variables:
1581 * c-basic-offset: 2
1582 * tab-width: 8
1583 * indent-tabs-mode: nil
1584 * End:
1585 *
1586 * ex: set shiftwidth=2 tabstop=8 expandtab:
1587 * :indentSize=2:tabSize=8:noTabs=true:
1588 */
1589