1 /* packet-cimd.c
2  *
3  * Routines for Computer Interface to Message Distribution (CIMD) version 2 dissection
4  *
5  * Copyright : 2005 Viorel Suman <vsuman[AT]avmob.ro>, Lucian Piros <lpiros[AT]avmob.ro>
6  *             In association with Avalanche Mobile BV, http://www.avmob.com
7  *
8  * Updates :
9  *            Sub routines for further dissection of Status and Error codes added by Vineeth <vineethvijaysv@gmail.com>
10  *
11  * Refer to the AUTHORS file or the AUTHORS section in the man page
12  * for contacting the author(s) of this file.
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * SPDX-License-Identifier: GPL-2.0-or-later
19  */
20 #include "config.h"
21 
22 #include <stdlib.h>
23 
24 #include <epan/packet.h>
25 #define CIMD_STX   0x02 /* Start of CIMD PDU */
26 #define CIMD_ETX   0x03 /* End of CIMD PDU */
27 #define CIMD_COLON 0x3A /* CIMD colon */
28 #define CIMD_DELIM 0x09 /* CIMD Delimiter */
29 
30 #define CIMD_OC_OFFSET  1 /* CIMD Operation Code Offset */
31 #define CIMD_OC_LENGTH  2 /* CIMD Operation Code Length */
32 #define CIMD_PN_OFFSET  4 /* CIMD Packet Number Offset */
33 #define CIMD_PN_LENGTH  3 /* CIMD Packet Number Length */
34 #define CIMD_PC_LENGTH  3 /* CIMD Parameter Code Length */
35 #define CIMD_MIN_LENGTH 9 /* CIMD Minimal packet length : STX(1) + OC(2) + COLON(1) + PN(3) + DELIM(1) + ETX(1)*/
36 
37 /* define CIMD2 operation code */
38 
39 #define CIMD_Login                     1
40 #define CIMD_LoginResp                51
41 #define CIMD_Logout                    2
42 #define CIMD_LogoutResp               52
43 #define CIMD_SubmitMessage             3
44 #define CIMD_SubmitMessageResp        53
45 #define CIMD_EnqMessageStatus          4
46 #define CIMD_EnqMessageStatusResp     54
47 #define CIMD_DeliveryRequest           5
48 #define CIMD_DeliveryRequestResp      55
49 #define CIMD_CancelMessage             6
50 #define CIMD_CancelMessageResp        56
51 #define CIMD_SetMessage                8
52 #define CIMD_SetMessageResp           58
53 #define CIMD_GetMessage                9
54 #define CIMD_GetMessageResp           59
55 #define CIMD_Alive                    40
56 #define CIMD_AliveResp                90
57 #define CIMD_GeneralErrorResp         98
58 #define CIMD_NACK                     99
59   /* SC2App */
60 #define CIMD_DeliveryMessage          20
61 #define CIMD_DeliveryMessageResp      70
62 #define CIMD_DeliveryStatusReport     23
63 #define CIMD_DeliveryStatusReportResp 73
64 
65 /* define CIMD2 operation's parameter codes */
66 
67 #define CIMD_UserIdentity            10
68 #define CIMD_Password                11
69 #define CIMD_Subaddress              12
70 #define CIMD_WindowSize              19
71 #define CIMD_DestinationAddress      21
72 #define CIMD_OriginatingAddress      23
73 #define CIMD_OriginatingImsi         26
74 #define CIMD_AlphaOriginatingAddr    27
75 #define CIMD_OriginatedVisitedMSCAd  28
76 #define CIMD_DataCodingScheme        30
77 #define CIMD_UserDataHeader          32
78 #define CIMD_UserData                33
79 #define CIMD_UserDataBinary          34
80 #define CIMD_MoreMessagesToSend      44
81 #define CIMD_ValidityPeriodRelative  50
82 #define CIMD_ValidityPeriodAbsolute  51
83 #define CIMD_ProtocolIdentifier      52
84 #define CIMD_FirstDeliveryTimeRel    53
85 #define CIMD_FirstDeliveryTimeAbs    54
86 #define CIMD_ReplyPath               55
87 #define CIMD_StatusReportRequest     56
88 #define CIMD_CancelEnabled           58
89 #define CIMD_CancelMode              59
90 #define CIMD_SCTimeStamp             60
91 #define CIMD_StatusCode              61
92 #define CIMD_StatusErrorCode         62
93 #define CIMD_DischargeTime           63
94 #define CIMD_TariffClass             64
CombinedStacks()95 #define CIMD_ServiceDescription      65
96 #define CIMD_MessageCount            66
97 #define CIMD_Priority                67
98 #define CIMD_DeliveryRequestMode     68
99 #define CIMD_SCAddress               69
100 #define CIMD_GetParameter           500
101 #define CIMD_SMSCTime               501
102 #define CIMD_ErrorCode              900
103 #define CIMD_ErrorText              901
104 
105 #define MAXPARAMSCOUNT               37
106 
107 typedef struct cimd_parameter_t cimd_parameter_t;
108 
109 typedef void (*cimd_pdissect)(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
110 
111 struct cimd_parameter_t {
112   cimd_pdissect  diss;
113   gint          *ett_p;
114   gint          *hf_p;
GetModuleCount() const115 };
116 
117 void proto_register_cimd(void);
118 void proto_reg_handoff_cimd(void);
119 static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
GetModule(unsigned aIndex) const120 static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
121 static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
122 static void dissect_cimd_error_code(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset);
123 
124 static int proto_cimd = -1;
AddStack(const Telemetry::ProcessedStack & aStack)125 /* Initialize the subtree pointers */
126 static gint ett_cimd = -1;
127 
128 /* Initialize the protocol and registered fields */
129 static int hf_cimd_opcode_indicator = -1;
130 static int hf_cimd_packet_number_indicator = -1;
131 static int hf_cimd_checksum_indicator = -1;
132 static int hf_cimd_pcode_indicator = -1;
133 
134 static int hf_cimd_dcs_coding_group_indicatorC0 = -1;
135 static int hf_cimd_dcs_coding_group_indicatorF0 = -1;
136 static int hf_cimd_dcs_compressed_indicator = -1;
137 static int hf_cimd_dcs_message_class_meaning_indicator = -1;
138 static int hf_cimd_dcs_message_class_indicator = -1;
139 static int hf_cimd_dcs_character_set_indicator0C = -1;
140 static int hf_cimd_dcs_character_set_indicator04 = -1;
141 static int hf_cimd_dcs_indication_sense = -1;
142 static int hf_cimd_dcs_indication_type = -1;
143 
144 static const value_string vals_hdr_OC[] = {
145   /* operation codes array */
146   {CIMD_Login,                    "Login"},
147   {CIMD_LoginResp,                "Login Resp"},
148   {CIMD_Logout,                   "Logout"},
149   {CIMD_LogoutResp,               "Logout Resp"},
150   {CIMD_SubmitMessage,            "Submit message"},
151   {CIMD_SubmitMessageResp,        "Submit message Resp"},
152   {CIMD_EnqMessageStatus,         "Enquire message status"},
153   {CIMD_EnqMessageStatusResp,     "Enquire message status Resp"},
154   {CIMD_DeliveryRequest,          "Delivery request"},
155   {CIMD_DeliveryRequestResp,      "Delivery request Resp"},
156   {CIMD_CancelMessage,            "Cancel message"},
157   {CIMD_CancelMessageResp,        "Cancel message Resp"},
158   {CIMD_SetMessage,               "Set message"},
159   {CIMD_SetMessageResp,           "Set message Resp"},
160   {CIMD_GetMessage,               "Get message"},
161   {CIMD_GetMessageResp,           "Get message Resp"},
GetStack(unsigned aIndex) const162   {CIMD_Alive,                    "Alive"},
163   {CIMD_AliveResp,                "Alive Resp"},
164   {CIMD_GeneralErrorResp,         "General error Resp"},
165   {CIMD_NACK,                     "Nack"},
166   /* SC2App */
GetStackCount() const167   {CIMD_DeliveryMessage,          "Deliver message"},
168   {CIMD_DeliveryMessageResp,      "Deliver message Resp"},
169   {CIMD_DeliveryStatusReport,     "Deliver status report"},
170   {CIMD_DeliveryStatusReportResp, "Deliver status report Resp"},
171   {0, NULL}
SizeOfExcludingThis() const172 };
173 
174 static const value_string cimd_vals_PC[] = {
175   /* parameter codes array */
176   {CIMD_UserIdentity,           "User Identity"},
177   {CIMD_Password,               "Password"},
178   {CIMD_Subaddress,             "Subaddr"},
179   {CIMD_WindowSize,             "Window Size"},
180   {CIMD_DestinationAddress,     "Destination Address"},
181   {CIMD_OriginatingAddress,     "Originating Address"},
182   {CIMD_OriginatingImsi,        "Originating IMSI"},
183   {CIMD_AlphaOriginatingAddr,   "Alphanumeric Originating Address"},
184   {CIMD_OriginatedVisitedMSCAd, "Originated Visited MSC Address"},
185   {CIMD_DataCodingScheme,       "Data Coding Scheme"},
186   {CIMD_UserDataHeader,         "User Data Header"},
187   {CIMD_UserData,               "User Data"},
188   {CIMD_UserDataBinary,         "User Data Binary"},
189   {CIMD_MoreMessagesToSend,     "More Messages To Send"},
190   {CIMD_ValidityPeriodRelative, "Validity Period Relative"},
191   {CIMD_ValidityPeriodAbsolute, "Validity Period Absolute"},
192   {CIMD_ProtocolIdentifier,     "Protocol Identifier"},
ComputeAnnotationsKey(const HangAnnotationsPtr & aAnnotations,nsAString & aKeyOut)193   {CIMD_FirstDeliveryTimeRel,   "First Delivery Time Relative"},
194   {CIMD_FirstDeliveryTimeAbs,   "First Delivery Time Absolute"},
195   {CIMD_ReplyPath,              "Reply Path"},
196   {CIMD_StatusReportRequest,    "Status Report Request"},
197   {CIMD_CancelEnabled,          "Cancel Enabled"},
198   {CIMD_CancelMode,             "Cancel Mode"},
199   {CIMD_SCTimeStamp,            "Service Centre Time Stamp"},
200   {CIMD_StatusCode,             "Status Code"},
201   {CIMD_StatusErrorCode,        "Status Error Code"},
202   {CIMD_DischargeTime,          "Discharge Time"},
203   {CIMD_TariffClass,            "Tariff Class"},
204   {CIMD_ServiceDescription,     "Service Description"},
205   {CIMD_MessageCount,           "Message Count"},
206   {CIMD_Priority,               "Priority"},
207   {CIMD_DeliveryRequestMode,    "Delivery Request Mode"},
208   {CIMD_SCAddress,              "Service Center Address"},
209   {CIMD_GetParameter,           "Get Parameter"},
210   {CIMD_SMSCTime,               "SMS Center Time"},
211   {CIMD_ErrorCode,              "Error Code"},
212   {CIMD_ErrorText,              "Error Text"},
213   {0, NULL}
214 };
215 
216 static const value_string cimd_dcs_coding_groups[] = {
217   {0x00, "General Data Coding indication"},
AnnotationInfo__anon90091ce60111::HangReports::AnnotationInfo218   {0x01, "General Data Coding indication"},
219   {0x02, "General Data Coding indication"},
220   {0x03, "General Data Coding indication"},
221   {0x04, "Message Marked for Automatic Deletion Group"},
222   {0x05, "Message Marked for Automatic Deletion Group"},
223   {0x06, "Message Marked for Automatic Deletion Group"},
AnnotationInfo__anon90091ce60111::HangReports::AnnotationInfo224   {0x07, "Message Marked for Automatic Deletion Group"},
225   {0x08, "Reserved coding group"},
226   {0x09, "Reserved coding group"},
227   {0x0A, "Reserved coding group"},
~AnnotationInfo__anon90091ce60111::HangReports::AnnotationInfo228   {0x0B, "Reserved coding group"},
operator =__anon90091ce60111::HangReports::AnnotationInfo229   {0x0C, "Message Waiting Indication Group: Discard Message (7-bit encoded)"},
230   {0x0D, "Message Waiting Indication Group: Store Message (7-bit encoded)"},
231   {0x0E, "Message Waiting Indication Group: Store Message (uncompressed UCS2 encoded)"},
232   {0x0F, "Data coding/message class"},
233   {0, NULL}
234 };
235 
236 static const value_string cimd_dcs_compressed[] = {
237   {0x00, "Text is uncompressed"},
238   {0x01, "Text is compressed"},
239   {0, NULL}
240 };
241 
242 static const value_string cimd_dcs_message_class_meaning[] = {
243   {0x00, "Reserved, bits 1 to 0 have no message class meaning"},
244   {0x01, "Bits 1 to 0 have message class meaning"},
245   {0, NULL}
246 };
247 
248 static const value_string cimd_dcs_message_class[] = {
249   {0x00, "Class 0"},
250   {0x01, "Class 1 Default meaning: ME-specific"},
251   {0x02, "Class 2 (U)SIM specific message"},
252   {0x03, "Class 3 Default meaning: TE-specific"},
253   {0, NULL}
254 };
255 
256 static const value_string cimd_dcs_character_set[] = {
257   {0x00, "GSM 7 bit default alphabet"},
258   {0x01, "8 bit data"},
259   {0x02, "UCS2 (16bit)"},
260   {0x03, "Reserved"},
261   {0, NULL}
262 };
263 
264 static const value_string cimd_dcs_indication_sense[] = {
265   {0x00, "Set Indication Inactive"},
266   {0x01, "Set Indication Active"},
267   {0, NULL}
268 };
269 
270 static const value_string cimd_dcs_indication_type[] = {
271   {0x00, "Voicemail Message Waiting"},
272   {0x01, "Fax Message Waiting"},
273   {0x02, "Electronic Mail Message Waiting"},
AddHang(const Telemetry::ProcessedStack & aStack,uint32_t aDuration,int32_t aSystemUptime,int32_t aFirefoxUptime,HangAnnotationsPtr aAnnotations)274   {0x03, "Other Message Waiting"},
275   {0, NULL}
276 };
277 
278 static const value_string cimd_error_vals[] = {
279   {1, "Unexpected operation"},
280   {2, "Syntax error"},
281   {3, "Unsupported parameter error"},
282   {4, "Connection to SMS Center lost"},
283   {5, "No response from SMS Center"},
284   {6, "General system error"},
285   {7, "Cannot find information"},
286   {8, "Parameter formatting error"},
287   {9, "Requested operation failed"},
288   {10, "Temporary congestion error"},
289   {100, "Invalid login"},
290   {101, "Incorrect access type"},
291   {102, "Too many users with this login ID"},
292   {103, "Login refused by SMS Center"},
293   {104, "Invalid window size"},
294   {105, "Windowing disabled"},
295   {106, "Virtual SMS Center-based barring"},
296   {107, "Invalid subaddr"},
297   {108, "Alias account, login refused"},
298   {300, "Incorrect destination address"},
299   {301, "Incorrect number of destination addresses"},
300   {302, "Syntax error in user data parameter"},
301   {303, "Incorrect bin/head/normal user data parameter combination"},
302   {304, "Incorrect dcs parameter usage"},
303   {305, "Incorrect validity period parameters usage"},
304   {306, "Incorrect originator address usage"},
305   {307, "Incorrect PID parameter usage"},
306   {308, "Incorrect first delivery parameter usage"},
307   {309, "Incorrect reply path usage"},
308   {310, "Incorrect status report request parameter usage"},
309   {311, "Incorrect cancel enabled parameter usage"},
310   {312, "Incorrect priority parameter usage"},
311   {313, "Incorrect tariff class parameter usage"},
312   {314, "Incorrect service description parameter usage"},
313   {315, "Incorrect transport type parameter usage"},
314   {316, "Incorrect message type parameter usage"},
315   {318, "Incorrect MMs parameter usage"},
316   {319, "Incorrect operation timer parameter usage"},
317   {320, "Incorrect dialogue ID parameter usage"},
318   {321, "Incorrect alpha originator address usage"},
319   {322, "Invalid data for alpha numeric originator"},
PruneStackReferences(const size_t aRemovedStackIndex)320   {400, "Incorrect address parameter usage"},
321   {401, "Incorrect scts parameter usage"},
322   {500, "Incorrect scts parameter usage"},
323   {501, "Incorrect mode parameter usage"},
324   {502, "Incorrect parameter combination"},
325   {600, "Incorrect scts parameter usage"},
326   {601, "Incorrect address parameter usage"},
327   {602, "Incorrect mode parameter usage"},
328   {603, "Incorrect parameter combination"},
329   {800, "Changing password failed"},
330   {801, "Changing password not allowed"},
331   {900, "Unsupported item requested"},
332   {0, NULL}
333 };
334 
335 static value_string_ext cimd_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_error_vals);
336 
337 static const value_string cimd_status_code_vals[] = {
338   {1, " in process"},
339   {2, " validity period expired"},
340   {3, " delivery failed"},
341   {4, " delivery successful"},
342   {5, " no response"},
343   {6, " last no response"},
344   {7, " message cancelled"},
345   {8, " message deleted"},
346   {9, " message deleted by cancel"},
347   {0, NULL}
SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const348 };
349 
350 static const value_string cimd_status_error_vals[] = {
351  {1, "Unknown subscriber"},
352  {9, "Illegal subscriber"},
353  {11, "Teleservice not provisioned"},
354  {13, "Call barred"},
355  {15, "CUG reject"},
356  {19, "No SMS support in MS"},
357  {20, "Error in MS"},
358  {21, "Facility not supported"},
359  {22, "Memory capacity exceeded"},
360  {29, "Absent subscriber"},
361  {30, "MS busy for MT SMS"},
362  {36, "Network/Protocol failure"},
363  {44, "Illegal equipment"},
GetStacks() const364  {60, "No paging response"},
365  {61, "GMSC congestion"},
366  {63, "HLR timeout"},
367  {64, "MSC/SGSN_timeout"},
368  {70, "SMRSE/TCP error"},
GetDuration(unsigned aIndex) const369  {72, "MT congestion"},
370  {75, "GPRS suspended"},
371  {80, "No paging response via MSC"},
372  {81, "IMSI detached"},
373  {82, "Roaming restriction"},
GetSystemUptime(unsigned aIndex) const374  {83, "Deregistered in HLR for GSM"},
375  {84, "Purged for GSM"},
376  {85, "No paging response via SGSN"},
377  {86, "GPRS detached"},
378  {87, "Deregistered in HLR for GPRS"},
GetFirefoxUptime(unsigned aIndex) const379  {88, "The MS purged for GPRS"},
380  {89, "Unidentified subscriber via MSC"},
381  {90, "Unidentified subscriber via SGSN"},
382  {112, "Originator missing credit on prepaid account"},
383  {113, "Destination missing credit on prepaid account"},
GetAnnotationInfo() const384  {114, "Error in prepaid system"},
385  {0, NULL}
386 };
387 
388 static value_string_ext cimd_status_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_status_error_vals);
389 
390 static const cimd_pdissect cimd_pc_handles[] = {
391  /* function handles for parsing cimd parameters */
392   dissect_cimd_parameter,
393   dissect_cimd_parameter,
394   dissect_cimd_parameter,
395   dissect_cimd_parameter,
FileStats__anon90091ce60111::TelemetryIOInterposeObserver::FileStats396   dissect_cimd_parameter,
397   dissect_cimd_parameter,
398   dissect_cimd_parameter,
399   dissect_cimd_parameter,
400   dissect_cimd_parameter,
401   dissect_cimd_dcs,
402   dissect_cimd_parameter,
403   dissect_cimd_ud,
404   dissect_cimd_parameter,
405   dissect_cimd_parameter,
406   dissect_cimd_parameter,
407   dissect_cimd_parameter,
408   dissect_cimd_parameter,
409   dissect_cimd_parameter,
410   dissect_cimd_parameter,
411   dissect_cimd_parameter,
412   dissect_cimd_parameter,
413   dissect_cimd_parameter,
414   dissect_cimd_parameter,
415   dissect_cimd_parameter,
416   dissect_cimd_error_code,
417   dissect_cimd_error_code,
418   dissect_cimd_parameter,
419   dissect_cimd_parameter,
420   dissect_cimd_parameter,
421   dissect_cimd_parameter,
422   dissect_cimd_parameter,
423   dissect_cimd_parameter,
424   dissect_cimd_parameter,
425   dissect_cimd_parameter,
426   dissect_cimd_parameter,
427   dissect_cimd_error_code,
428   dissect_cimd_parameter
429 };
430 
431 /* Parameters */
432 static cimd_parameter_t vals_hdr_PC[MAXPARAMSCOUNT + 1];
433 static gint ett_index[MAXPARAMSCOUNT];
434 static gint hf_index[MAXPARAMSCOUNT];
435 
436 static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
437 {
438   /* Set up structures needed to add the param subtree and manage it */
439   proto_tree *param_tree;
440 
441   param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
442                                    (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
443 
444   proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
445     startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII|ENC_NA);
446   proto_tree_add_item(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb,
447     startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII|ENC_NA);
448 }
SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const449 
450 static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
451 {
452   /* Set up structures needed to add the param subtree and manage it */
453   proto_tree *param_tree;
454 
455   gchar *payloadText, *tmpBuffer, *tmpBuffer1;
456   int    loop,i,poz, bufPoz = 0, bufPoz1 = 0, size, size1, resch;
457   gint   g_offset, g_size;
458   gchar  token[4];
459   gchar  ch;
460   static const char* mapping[128]  = {
461     "_Oa" , "_L-", ""    , "_Y-", "_e`", "_e'", "_u`", "_i`", "_o`", "_C,",        /*10*/
462     ""    , "_O/", "_o/" , ""   , "_A*", "_a*", "_gd", "_--", "_gf", "_gg", "_gl", /*21*/
463     "_go" , "_gp", "_gi" , "_gs", "_gt", "_gx", "_XX", "_AE", "_ae", "_ss", "_E'", /*32*/
464     ""    , ""   , "_qq" , ""   , "_ox", ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
465     ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
466     "_!!" , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
467     ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , "_A\"", "_O\"", "_N~",
468     "_U\"", "_so", "_??" , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   ,
469     ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "_a\"",
470     "_o\"", "_n~", "_n\"","_a`"
471   };
472 
473   param_tree = proto_tree_add_subtree(tree, tvb,
474     startOffset + 1, endOffset - (startOffset + 1),
475     (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
476   );
477   proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
478     startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII|ENC_NA);
479 
480   g_offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
481   g_size   = endOffset - g_offset;
482 
483   payloadText = tvb_format_text(wmem_packet_scope(), tvb, g_offset, g_size);
484   size = (int)strlen(payloadText);
485   tmpBuffer = (gchar*)wmem_alloc(wmem_packet_scope(), size+1);
486   for (loop = 0; loop < size; loop++)
487   {
488     if (payloadText[loop] == '_')
489     {
490       if (loop < size - 2)
491       {
492         token[0] = payloadText[loop++];
493         token[1] = payloadText[loop++];
494         token[2] = payloadText[loop];
495         token[3] = '\0';
496         poz = -1;
497         for (i = 0; i < 128; i++)
498         {
499           if (strcmp(token, mapping[i]) == 0)
500           {
501             poz = i;
502             break;
503           }
504         }
505         if (poz > 0)
506         {
507           tmpBuffer[bufPoz++] = poz;
508         }
509         else
510         {
511           tmpBuffer[bufPoz++] = payloadText[loop-2];
512           tmpBuffer[bufPoz++] = payloadText[loop-1];
513           tmpBuffer[bufPoz++] = payloadText[loop];
514         }
515       }
516       else
517       {
518         if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
519         if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
520         if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
521       }
522     }
523     else
524     {
525       tmpBuffer[bufPoz++] = payloadText[loop];
526     }
527   }
528   tmpBuffer[bufPoz] = '\0';
529 
530   size1 = (int)strlen(tmpBuffer);
531   tmpBuffer1 = (gchar*)wmem_alloc(wmem_packet_scope(), size1+1);
532   for (loop=0; loop<size1; loop++)
533   {
534     ch = tmpBuffer[loop];
535     switch ((gint)ch)
536     {
537     case 0x40: resch = 0x0040; break;
538     case 0x01: resch = 0x00A3; break;
539     case 0x02: resch = 0x0024; break;
540     case 0x03: resch = 0x00A5; break;
541     case 0x04: resch = 0x00E8; break;
542     case 0x05: resch = 0x00E9; break;
543     case 0x06: resch = 0x00F9; break;
544     case 0x07: resch = 0x00EC; break;
545     case 0x08: resch = 0x00F2; break;
546     case 0x09: resch = 0x00E7; break;
547     case 0x0B: resch = 0x00D8; break;
548     case 0x0C: resch = 0x00F8; break;
549     case 0x0E: resch = 0x00C5; break;
550     case 0x0F: resch = 0x00E5; break;
551     case 0x11: resch = 0x005F; break;
552 /*  case 0x1B14: resch = 0x005E; break; */
553 /*  case 0x1B28: resch = 0x007B; break; */
554 /*  case 0x1B29: resch = 0x007D; break; */
555 /*  case 0x1B2F: resch = 0x005C; break; */
556 /*  case 0x1B3C: resch = 0x005B; break; */
557 /*  case 0x1B3D: resch = 0x007E; break; */
558 /*  case 0x1B3E: resch = 0x005D; break; */
559 /*  case 0x1B40: resch = 0x007C; break; */
560     case 0x1C: resch = 0x00C6; break;
561     case 0x1D: resch = 0x00E6; break;
562     case 0x1E: resch = 0x00DF; break;
563     case 0x1F: resch = 0x00C9; break;
564     case 0x20: resch = 0x0020; break;
565     case 0x21: resch = 0x0021; break;
566     case 0x22: resch = 0x0022; break;
567     case 0x23: resch = 0x0023; break;
568     case 0xA4: resch = 0x00A4; break;
569     case 0x25: resch = 0x0025; break;
570     case 0x26: resch = 0x0026; break;
571     case 0x27: resch = 0x0027; break;
572     case 0x28: resch = 0x0028; break;
573     case 0x29: resch = 0x0029; break;
574     case 0x2A: resch = 0x002A; break;
575     case 0x2B: resch = 0x002B; break;
576     case 0x2C: resch = 0x002C; break;
577     case 0x2D: resch = 0x002D; break;
578     case 0x2E: resch = 0x002E; break;
579     case 0x2F: resch = 0x002F; break;
580     case 0x30: resch = 0x0030; break;
581     case 0x31: resch = 0x0031; break;
582     case 0x32: resch = 0x0032; break;
583     case 0x33: resch = 0x0033; break;
584     case 0x34: resch = 0x0034; break;
585     case 0x35: resch = 0x0035; break;
586     case 0x36: resch = 0x0036; break;
587     case 0x37: resch = 0x0037; break;
588     case 0x38: resch = 0x0038; break;
589     case 0x39: resch = 0x0039; break;
590     case 0x3A: resch = 0x003A; break;
591     case 0x3B: resch = 0x003B; break;
592     case 0x3C: resch = 0x003C; break;
593     case 0x3D: resch = 0x003D; break;
594     case 0x3E: resch = 0x003E; break;
595     case 0x3F: resch = 0x003F; break;
596 /*  case 0x40: resch = 0x00A1; break; */
597     case 0x41: resch = 0x0041; break;
598     case 0x42: resch = 0x0042; break;
599 /*  case 0x42: resch = 0x0392; break; */
600     case 0x43: resch = 0x0043; break;
601     case 0x44: resch = 0x0044; break;
602     case 0x45: resch = 0x0045; break;
603     case 0x46: resch = 0x0046; break;
604     case 0x47: resch = 0x0047; break;
605     case 0x48: resch = 0x0048; break;
606     case 0x49: resch = 0x0049; break;
607     case 0x4A: resch = 0x004A; break;
608     case 0x4B: resch = 0x004B; break;
609     case 0x4C: resch = 0x004C; break;
610     case 0x4D: resch = 0x004D; break;
611     case 0x4E: resch = 0x004E; break;
612     case 0x4F: resch = 0x004F; break;
613     case 0x50: resch = 0x0050; break;
614     case 0x51: resch = 0x0051; break;
615     case 0x52: resch = 0x0052; break;
616     case 0x53: resch = 0x0053; break;
617     case 0x54: resch = 0x0054; break;
618     case 0x55: resch = 0x0055; break;
619     case 0x56: resch = 0x0056; break;
620     case 0x57: resch = 0x0057; break;
621     case 0x58: resch = 0x0058; break;
622     case 0x59: resch = 0x0059; break;
623     case 0x5A: resch = 0x005A; break;
624     case 0x5B: resch = 0x00C4; break;
625     case 0x5C: resch = 0x00D6; break;
626     case 0x5D: resch = 0x00D1; break;
627     case 0x5E: resch = 0x00DC; break;
628     case 0x5F: resch = 0x00A7; break;
629     case 0x60: resch = 0x00BF; break;
630     case 0x61: resch = 0x0061; break;
631     case 0x62: resch = 0x0062; break;
632     case 0x63: resch = 0x0063; break;
633     case 0x64: resch = 0x0064; break;
634     case 0x65: resch = 0x0065; break;
635     case 0x66: resch = 0x0066; break;
636     case 0x67: resch = 0x0067; break;
637     case 0x68: resch = 0x0068; break;
638     case 0x69: resch = 0x0069; break;
639     case 0x6A: resch = 0x006A; break;
640     case 0x6B: resch = 0x006B; break;
641     case 0x6C: resch = 0x006C; break;
642     case 0x6D: resch = 0x006D; break;
643     case 0x6E: resch = 0x006E; break;
644     case 0x6F: resch = 0x006F; break;
645     case 0x70: resch = 0x0070; break;
646     case 0x71: resch = 0x0071; break;
647     case 0x72: resch = 0x0072; break;
648     case 0x73: resch = 0x0073; break;
649     case 0x74: resch = 0x0074; break;
650     case 0x75: resch = 0x0075; break;
651     case 0x76: resch = 0x0076; break;
652     case 0x77: resch = 0x0077; break;
653     case 0x78: resch = 0x0078; break;
654     case 0x79: resch = 0x0079; break;
655     case 0x7A: resch = 0x007A; break;
656     case 0x7B: resch = 0x00E4; break;
657     case 0x7C: resch = 0x00F6; break;
658     case 0x7D: resch = 0x00F1; break;
659     case 0x7F: resch = 0x00E0; break;
660     default:resch = ch; break;
661     }
662     tmpBuffer1[bufPoz1++] = (gchar)resch;
663   }
664 
665   tmpBuffer1[bufPoz1] = '\0';
666   proto_tree_add_string(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, g_offset, g_size, tmpBuffer1);
667 }
668 
669 static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
670 {
671   /* Set up structures needed to add the param subtree and manage it */
672   proto_tree *param_tree;
673   gint        offset;
674   guint32     dcs;
675   guint32     dcs_cg;           /* coding group */
676 
677   param_tree = proto_tree_add_subtree(tree, tvb,
678     startOffset + 1, endOffset - (startOffset + 1),
679     (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
680   );
681 
682   proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
683     startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII|ENC_NA);
684 
685   offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
686   dcs    = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, endOffset - offset, ENC_ASCII), NULL, 10);
687   proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, offset, endOffset - offset, dcs);
688 
689   dcs_cg = (dcs & 0xF0) >> 4;
690   if (dcs_cg <= 0x07)
691   {
692      proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorC0, tvb, offset, 1, dcs);
693   }
694   else
695   {
696      proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorF0, tvb, offset, 1, dcs);
697   }
698 
699   if (dcs_cg <= 0x07)
700   {
701     proto_tree_add_uint(param_tree, hf_cimd_dcs_compressed_indicator, tvb, offset, 1, dcs);
702     proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_meaning_indicator, tvb, offset, 1, dcs);
703     proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator0C, tvb, offset, 1, dcs);
704 
705     if (dcs & 0x10)
706     {
707       proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
708     }
709   }
710   else if (dcs_cg >= 0x0C && dcs_cg <= 0x0E)
711   {
712     proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_sense, tvb, offset, 1, dcs);
713     proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_type, tvb, offset, 1, dcs);
714   }
715   else if (dcs_cg == 0x0F)
716   {
717     proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator04, tvb, offset, 1, dcs);
718     proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
719   }
720 }
721 
722 static void dissect_cimd_error_code( tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset )
723 {
724   /* Same routine can be used to dissect CIMD Error,Status and Status Error Codes */
725   proto_tree *param_tree;
726   guint32 err_code;
727 
728   param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
729                                       (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
730 
731   proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb, startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII|ENC_NA);
732 
733   err_code = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb,
734                                                   startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII),
735                                NULL, 10);
736   proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), err_code);
737 }
738 
739 static void
740 dissect_cimd_operation(tvbuff_t *tvb, proto_tree *tree, gint etxp, guint16 checksum, guint8 last1,guint8 OC, guint8 PN)
741 {
742   guint32     PC        = 0;    /* Parameter code */
743   gint        idx;
744   gint        offset    = 0;
745   gint        endOffset = 0;
746   proto_item *cimd_item;
747   proto_tree *cimd_tree;
748 
749     /* create display subtree for the protocol */
750   cimd_item = proto_tree_add_item(tree, proto_cimd, tvb, 0, etxp + 1, ENC_NA);
751   cimd_tree = proto_item_add_subtree(cimd_item, ett_cimd);
752   proto_tree_add_uint(cimd_tree, hf_cimd_opcode_indicator, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, OC);
MOZ_DEFINE_MALLOC_SIZE_OF(TelemetryMallocSizeOf)753   proto_tree_add_uint(cimd_tree, hf_cimd_packet_number_indicator, tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, PN);
754 
755   offset = CIMD_PN_OFFSET + CIMD_PN_LENGTH;
756   while (offset < etxp && tvb_get_guint8(tvb, offset) == CIMD_DELIM)
757   {
758     endOffset = tvb_find_guint8(tvb, offset + 1, etxp, CIMD_DELIM);
759     if (endOffset == -1)
760       break;
761 
762     PC = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 1, CIMD_PC_LENGTH, ENC_ASCII), NULL, 10);
763     try_val_to_str_idx(PC, cimd_vals_PC, &idx);
764     if (idx != -1 && tree)
765     {
766       (vals_hdr_PC[idx].diss)(tvb, cimd_tree, idx, offset, endOffset);
767     }
InitHistogramRecordingEnabled()768     offset = endOffset;
769   }
770 
771   if (last1 != CIMD_DELIM)
772   {
773     /* Checksum is present */
ReadLastShutdownDuration(const char * filename)774     proto_tree_add_uint(cimd_tree, hf_cimd_checksum_indicator, tvb, etxp - 2, 2, checksum);
775   }
776 }
777 
778 static int
779 dissect_cimd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
780 {
781   guint8   OC;                  /* Operation Code */
782   guint8   PN;                  /* Packet number */
783   guint16  checksum        = 0; /* Checksum */
784   guint16  pkt_check       = 0;
785   gint     etxp            = 0; /* ETX position */
786   gint     offset          = 0;
787   gboolean checksumIsValid = TRUE;
788   guint8   last1, last2, last3;
789 
790   etxp = tvb_find_guint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH, -1, CIMD_ETX);
791   if (etxp == -1) return 0;
792 
GetFailedLockCount(nsIInputStream * inStream,uint32_t aCount,unsigned int & result)793   OC = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
794   PN = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, ENC_ASCII), NULL, 10);
795 
796   last1 = tvb_get_guint8(tvb, etxp - 1);
797   last2 = tvb_get_guint8(tvb, etxp - 2);
798   last3 = tvb_get_guint8(tvb, etxp - 3);
799 
800   if (last1 == CIMD_DELIM) {
801     /* valid packet, CC is missing */
802   } else if (last1 != CIMD_DELIM && last2 != CIMD_DELIM && last3 == CIMD_DELIM) {
803     /* looks valid, it would be nice to check that last1 and last2 are HEXA */
804     /* CC is present */
GetFailedProfileLockFile(nsIFile ** aFile,nsIFile * aProfileDir)805     checksum = (guint16)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, etxp - 2, 2, ENC_ASCII), NULL, 16);
806     for (; offset < (etxp - 2); offset++)
807     {
808       pkt_check += tvb_get_guint8(tvb, offset);
809       pkt_check &= 0xFF;
810     }
811     checksumIsValid = (checksum == pkt_check);
812   } else {
813     checksumIsValid = FALSE;
814   }
815 
816   /* Make entries in Protocol column on summary display */
817   col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIMD");
818 
nsFetchTelemetryData(const char * aShutdownTimeFilename,nsIFile * aFailedProfileLockFile,nsIFile * aProfileDir)819   if (checksumIsValid)
820     col_add_str(pinfo->cinfo, COL_INFO, val_to_str(OC, vals_hdr_OC, "Unknown (%d)"));
821   else
822     col_add_fstr(pinfo->cinfo, COL_INFO, "%s - %s", val_to_str(OC, vals_hdr_OC, "Unknown (%d)"), "invalid checksum");
823 
824   dissect_cimd_operation(tvb, tree, etxp, checksum, last1, OC, PN);
825   return tvb_captured_length(tvb);
826 }
827 
828 /**
829  * A 'heuristic dissector' that attemtps to establish whether we have
830  * a CIMD MSU here.
831  */
832 static gboolean
833 dissect_cimd_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
834 {
835   int    etxp;
MainThread()836   guint8 opcode = 0;            /* Operation code */
837 
838   if (tvb_captured_length(tvb) < CIMD_MIN_LENGTH)
839     return FALSE;
840 
841   if (tvb_get_guint8(tvb, 0) != CIMD_STX)
842     return FALSE;
843 
Run()844   etxp = tvb_find_guint8(tvb, CIMD_OC_OFFSET, -1, CIMD_ETX);
845   if (etxp == -1)
846   { /* XXX - should we have an option to request reassembly? */
847     return FALSE;
848   }
849 
850   /* Try getting the operation-code */
851   opcode = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
852   if (try_val_to_str(opcode, vals_hdr_OC) == NULL)
853     return FALSE;
854 
855   if (tvb_get_guint8(tvb, CIMD_OC_OFFSET + CIMD_OC_LENGTH) != CIMD_COLON)
856     return FALSE;
857 
LoadFailedLockCount(uint32_t & failedLockCount)858   if (tvb_get_guint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH) != CIMD_DELIM)
859     return FALSE;
860 
861   /* Ok, looks like a valid packet, go dissect. */
862   dissect_cimd(tvb, pinfo, tree, data);
863   return TRUE;
864 }
865 
866 void
867 proto_register_cimd(void)
868 {
869   static hf_register_info hf[] = {
870     { &hf_cimd_opcode_indicator,
871       { "Operation Code", "cimd.opcode",
872         FT_UINT8, BASE_DEC, NULL, 0x00,
873         NULL, HFILL }
874     },
875     { &hf_cimd_packet_number_indicator,
876       { "Packet Number", "cimd.pnumber",
877         FT_UINT8, BASE_DEC, NULL, 0x00,
878         NULL, HFILL }
879     },
880     { &hf_cimd_pcode_indicator,
881       { "Parameter Code", "cimd.pcode",
882         FT_STRING, BASE_NONE, NULL, 0x00,
883         NULL, HFILL }
884     },
885     { &hf_cimd_checksum_indicator,
886       { "Checksum", "cimd.chksum",
GetShutdownTimeFileName()887         FT_UINT8, BASE_HEX, NULL, 0x00,
888         NULL, HFILL }
889     },
890     { &hf_cimd_dcs_coding_group_indicatorC0,
891       { "DCS Coding Group", "cimd.dcs.cg",
892         FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xC0,
893         NULL, HFILL }
894     },
895     { &hf_cimd_dcs_coding_group_indicatorF0,
896       { "DCS Coding Group", "cimd.dcs.cg",
897         FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xF0,
898         NULL, HFILL }
899     },
900     { &hf_cimd_dcs_compressed_indicator,
901       { "DCS Compressed Flag", "cimd.dcs.cf",
902         FT_UINT8, BASE_DEC, VALS(cimd_dcs_compressed), 0x20,
903         NULL, HFILL }
904     },
905     { &hf_cimd_dcs_message_class_meaning_indicator,
906       { "DCS Message Class Meaning", "cimd.dcs.mcm",
907         FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class_meaning), 0x10,
908         NULL, HFILL }
909     },
910     { &hf_cimd_dcs_message_class_indicator,
911       { "DCS Message Class", "cimd.dcs.mc",
GetLastShutdownDuration(uint32_t * aResult)912         FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class), 0x03,
913         NULL, HFILL }
914     },
915     { &hf_cimd_dcs_character_set_indicator0C,
916       { "DCS Character Set", "cimd.dcs.chs",
917         FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x0C,
918         NULL, HFILL }
919     },
920     { &hf_cimd_dcs_character_set_indicator04,
921       { "DCS Character Set", "cimd.dcs.chs",
922         FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x04,
923         NULL, HFILL }
924     },
925     { &hf_cimd_dcs_indication_sense,
926       { "DCS Indication Sense", "cimd.dcs.is",
GetFailedProfileLockCount(uint32_t * aResult)927         FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_sense), 0x04,
928         NULL, HFILL }
929     },
930     { &hf_cimd_dcs_indication_type,
931       { "DCS Indication Type", "cimd.dcs.it",
932         FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_type), 0x03,
933         NULL, HFILL }
934     },
935     { &hf_index[0],
936       { "User Identity", "cimd.ui",
937         FT_STRING, BASE_NONE, NULL, 0x00,
938         NULL, HFILL }
939     },
940     { &hf_index[1],
941       { "Password", "cimd.passwd",
AsyncFetchTelemetryData(nsIFetchTelemetryDataCallback * aCallback)942         FT_STRING, BASE_NONE, NULL, 0x00,
943         NULL, HFILL }
944     },
945     { &hf_index[2],
946       { "Subaddress", "cimd.saddr",
947         FT_STRING, BASE_NONE, NULL, 0x00,
948         NULL, HFILL }
949     },
950     { &hf_index[3],
951       { "Window Size", "cimd.ws",
952         FT_STRING, BASE_NONE, NULL, 0x00,
953         NULL, HFILL }
954     },
955     { &hf_index[4],
956       { "Destination Address", "cimd.da",
957         FT_STRING, BASE_NONE, NULL, 0x00,
958         NULL, HFILL }
959     },
960     { &hf_index[5],
961       { "Originating Address", "cimd.oa",
962         FT_STRING, BASE_NONE, NULL, 0x00,
963         NULL, HFILL }
964     },
965     { &hf_index[6],
966       { "Originating IMSI", "cimd.oimsi",
967         FT_STRING, BASE_NONE, NULL, 0x00,
968         NULL, HFILL }
969     },
970     { &hf_index[7],
971       { "Alphanumeric Originating Address", "cimd.aoi",
972         FT_STRING, BASE_NONE, NULL, 0x00,
973         NULL, HFILL }
974     },
975     { &hf_index[8],
976       { "Originated Visited MSC Address", "cimd.ovma",
977         FT_STRING, BASE_NONE, NULL, 0x00,
978         NULL, HFILL }
979     },
980     { &hf_index[9],
981       { "Data Coding Scheme", "cimd.dcs",
982         FT_UINT8, BASE_HEX, NULL, 0x00,
983         NULL, HFILL }
984     },
985     { &hf_index[10],
986       { "User Data Header", "cimd.udh",
987         FT_STRING, BASE_NONE, NULL, 0x00,
988         NULL, HFILL }
989     },
990     { &hf_index[11],
991       { "User Data", "cimd.ud",
992         FT_STRING, BASE_NONE, NULL, 0x00,
993         NULL, HFILL }
994     },
995     { &hf_index[12],
996       { "User Data Binary", "cimd.udb",
997         FT_STRING, BASE_NONE, NULL, 0x00,
998         NULL, HFILL }
999     },
1000     { &hf_index[13],
1001       { "More Messages To Send", "cimd.mms",
1002         FT_STRING, BASE_NONE, NULL, 0x00,
1003         NULL, HFILL }
1004     },
1005     { &hf_index[14],
1006       { "Validity Period Relative", "cimd.vpr",
1007         FT_STRING, BASE_NONE, NULL, 0x00,
1008         NULL, HFILL }
1009     },
1010     { &hf_index[15],
TelemetryImpl()1011       { "Validity Period Absolute", "cimd.vpa",
1012         FT_STRING, BASE_NONE, NULL, 0x00,
1013         NULL, HFILL }
1014     },
1015     { &hf_index[16],
1016       { "Protocol Identifier", "cimd.pi",
1017         FT_STRING, BASE_NONE, NULL, 0x00,
1018         NULL, HFILL }
1019     },
1020     { &hf_index[17],
1021       { "First Delivery Time Relative", "cimd.fdtr",
1022         FT_STRING, BASE_NONE, NULL, 0x00,
1023         NULL, HFILL }
~TelemetryImpl()1024     },
1025     { &hf_index[18],
1026       { "First Delivery Time Absolute", "cimd.fdta",
1027         FT_STRING, BASE_NONE, NULL, 0x00,
1028         NULL, HFILL }
1029     },
1030     { &hf_index[19],
1031       { "Reply Path", "cimd.rpath",
1032         FT_STRING, BASE_NONE, NULL, 0x00,
1033         NULL, HFILL }
ReflectSQL(const SlowSQLEntryType * entry,const Stat * stat,JSContext * cx,JS::Handle<JSObject * > obj)1034     },
1035     { &hf_index[20],
1036       { "Status Report Request", "cimd.srr",
1037         FT_STRING, BASE_NONE, NULL, 0x00,
1038         NULL, HFILL }
1039     },
1040     { &hf_index[21],
1041       { "Cancel Enabled", "cimd.ce",
1042         FT_STRING, BASE_NONE, NULL, 0x00,
1043         NULL, HFILL }
1044     },
1045     { &hf_index[22],
1046       { "Cancel Mode", "cimd.cm",
1047         FT_STRING, BASE_NONE, NULL, 0x00,
1048         NULL, HFILL }
1049     },
1050     { &hf_index[23],
1051       { "Service Center Time Stamp", "cimd.scts",
1052         FT_STRING, BASE_NONE, NULL, 0x00,
1053         NULL, HFILL }
1054     },
ReflectMainThreadSQL(SlowSQLEntryType * entry,JSContext * cx,JS::Handle<JSObject * > obj)1055     { &hf_index[24],
1056       { "Status Code", "cimd.stcode",
1057         FT_UINT8, BASE_DEC, VALS(cimd_status_code_vals), 0x00,
1058         NULL, HFILL }
1059     },
1060     { &hf_index[25],
1061       { "Status Error Code", "cimd.sterrcode",
ReflectOtherThreadsSQL(SlowSQLEntryType * entry,JSContext * cx,JS::Handle<JSObject * > obj)1062         FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_status_error_vals_ext, 0x00,
1063         NULL, HFILL }
1064     },
1065     { &hf_index[26],
1066       { "Discharge Time", "cimd.dt",
1067         FT_STRING, BASE_NONE, NULL, 0x00,
1068         NULL, HFILL }
1069     },
1070     { &hf_index[27],
1071       { "Tariff Class", "cimd.tclass",
1072         FT_STRING, BASE_NONE, NULL, 0x00,
1073         NULL, HFILL }
1074     },
1075     { &hf_index[28],
1076       { "Service Description", "cimd.sdes",
1077         FT_STRING, BASE_NONE, NULL, 0x00,
1078         NULL, HFILL }
1079     },
1080     { &hf_index[29],
1081       { "Message Count", "cimd.mcount",
1082         FT_STRING, BASE_NONE, NULL, 0x00,
1083         NULL, HFILL }
1084     },
1085     { &hf_index[30],
1086       { "Priority", "cimd.priority",
1087         FT_STRING, BASE_NONE, NULL, 0x00,
1088         NULL, HFILL }
RegisterAddonHistogram(const nsACString & id,const nsACString & name,uint32_t histogramType,uint32_t min,uint32_t max,uint32_t bucketCount,uint8_t optArgCount)1089     },
1090     { &hf_index[31],
1091       { "Delivery Request Mode", "cimd.drmode",
1092         FT_STRING, BASE_NONE, NULL, 0x00,
1093         NULL, HFILL }
1094     },
1095     { &hf_index[32],
1096       { "Service Center Address", "cimd.scaddr",
1097         FT_STRING, BASE_NONE, NULL, 0x00,
1098         NULL, HFILL }
1099     },
1100     { &hf_index[33],
GetAddonHistogram(const nsACString & id,const nsACString & name,JSContext * cx,JS::MutableHandle<JS::Value> ret)1101       { "Get Parameter", "cimd.gpar",
1102         FT_STRING, BASE_NONE, NULL, 0x00,
1103         NULL, HFILL }
1104     },
1105     { &hf_index[34],
1106       { "SMS Center Time", "cimd.smsct",
1107         FT_STRING, BASE_NONE, NULL, 0x00,
UnregisterAddonHistograms(const nsACString & id)1108         NULL, HFILL }
1109     },
1110     { &hf_index[35],
1111       { "Error Code Description", "cimd.errcode",
1112         FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_error_vals_ext, 0x00,
1113         NULL, HFILL }
1114     },
1115     { &hf_index[36],
1116       { "Error Text", "cimd.errtext",
1117         FT_STRING, BASE_NONE, NULL, 0x00,
1118         NULL, HFILL }
1119     }
GetHistogramSnapshots(JSContext * cx,JS::MutableHandle<JS::Value> ret)1120   };
1121 
1122   /* Setup protocol subtree array */
1123   gint *ett[MAXPARAMSCOUNT + 1];
1124   int i;
1125 
SnapshotSubsessionHistograms(bool clearSubsession,JSContext * cx,JS::MutableHandle<JS::Value> ret)1126   ett[0] = &ett_cimd;
1127 
1128   for(i=0;i<MAXPARAMSCOUNT;i++)
1129   {
1130     ett_index[i]         = -1;
1131     ett[i + 1]           = &(ett_index[i]);
1132     vals_hdr_PC[i].ett_p = &(ett_index[i]);
1133     vals_hdr_PC[i].hf_p  = &(hf_index[i]);
1134     vals_hdr_PC[i].diss  = cimd_pc_handles[i];
1135   };
1136 
1137   /* Register the protocol name and description */
1138   proto_cimd = proto_register_protocol("Computer Interface to Message Distribution", "CIMD", "cimd");
GetAddonHistogramSnapshots(JSContext * cx,JS::MutableHandle<JS::Value> ret)1139   /* Required function calls to register the header fields and subtrees used */
1140   proto_register_field_array(proto_cimd, hf, array_length(hf));
1141   proto_register_subtree_array(ett, array_length(ett));
1142 }
1143 
1144 void
GetKeyedHistogramSnapshots(JSContext * cx,JS::MutableHandle<JS::Value> ret)1145 proto_reg_handoff_cimd(void)
1146 {
1147   dissector_handle_t cimd_handle;
1148 
1149   /**
1150    * CIMD can be spoken on any port so, when not on a specific port, try this
1151    * one whenever TCP is spoken.
1152    */
1153   heur_dissector_add("tcp", dissect_cimd_heur, "CIMD over TCP", "cimd_tcp", proto_cimd, HEURISTIC_ENABLE);
1154 
1155   /**
1156    * Also register as one that can be selected by a TCP port number.
1157    */
1158   cimd_handle = create_dissector_handle(dissect_cimd, proto_cimd);
1159   dissector_add_for_decode_as_with_preference("tcp.port", cimd_handle);
1160 }
1161 
1162 /*
1163  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1164  *
1165  * Local Variables:
1166  * c-basic-offset: 2
1167  * tab-width: 8
1168  * indent-tabs-mode: nil
1169  * End:
GetSlowSQL(JSContext * cx,JS::MutableHandle<JS::Value> ret)1170  *
1171  * ex: set shiftwidth=2 tabstop=8 expandtab:
1172  * :indentSize=2:tabSize=8:noTabs=true:
1173  */
1174