epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-cimd.c
blob2d5f4232f2119aba888b2cfe2dc1deab75b29496
1 /* packet-cimd.c
3 * Routines for Computer Interface to Message Distribution (CIMD) version 2 dissection
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
8 * Updates :
9 * Sub routines for further dissection of Status and Error codes added by Vineeth <vineethvijaysv@gmail.com>
11 * Refer to the AUTHORS file or the AUTHORS section in the man page
12 * for contacting the author(s) of this file.
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include "config.h"
22 #include <stdlib.h>
24 #include <epan/packet.h>
25 #include <epan/charsets.h>
26 #define CIMD_STX 0x02 /* Start of CIMD PDU */
27 #define CIMD_ETX 0x03 /* End of CIMD PDU */
28 #define CIMD_COLON 0x3A /* CIMD colon */
29 #define CIMD_DELIM 0x09 /* CIMD Delimiter */
31 #define CIMD_OC_OFFSET 1 /* CIMD Operation Code Offset */
32 #define CIMD_OC_LENGTH 2 /* CIMD Operation Code Length */
33 #define CIMD_PN_OFFSET 4 /* CIMD Packet Number Offset */
34 #define CIMD_PN_LENGTH 3 /* CIMD Packet Number Length */
35 #define CIMD_PC_LENGTH 3 /* CIMD Parameter Code Length */
36 #define CIMD_MIN_LENGTH 9 /* CIMD Minimal packet length : STX(1) + OC(2) + COLON(1) + PN(3) + DELIM(1) + ETX(1)*/
38 /* define CIMD2 operation code */
40 #define CIMD_Login 1
41 #define CIMD_LoginResp 51
42 #define CIMD_Logout 2
43 #define CIMD_LogoutResp 52
44 #define CIMD_SubmitMessage 3
45 #define CIMD_SubmitMessageResp 53
46 #define CIMD_EnqMessageStatus 4
47 #define CIMD_EnqMessageStatusResp 54
48 #define CIMD_DeliveryRequest 5
49 #define CIMD_DeliveryRequestResp 55
50 #define CIMD_CancelMessage 6
51 #define CIMD_CancelMessageResp 56
52 #define CIMD_SetMessage 8
53 #define CIMD_SetMessageResp 58
54 #define CIMD_GetMessage 9
55 #define CIMD_GetMessageResp 59
56 #define CIMD_Alive 40
57 #define CIMD_AliveResp 90
58 #define CIMD_GeneralErrorResp 98
59 #define CIMD_NACK 99
60 /* SC2App */
61 #define CIMD_DeliveryMessage 20
62 #define CIMD_DeliveryMessageResp 70
63 #define CIMD_DeliveryStatusReport 23
64 #define CIMD_DeliveryStatusReportResp 73
66 /* define CIMD2 operation's parameter codes */
68 #define CIMD_UserIdentity 10
69 #define CIMD_Password 11
70 #define CIMD_Subaddress 12
71 #define CIMD_WindowSize 19
72 #define CIMD_DestinationAddress 21
73 #define CIMD_OriginatingAddress 23
74 #define CIMD_OriginatingImsi 26
75 #define CIMD_AlphaOriginatingAddr 27
76 #define CIMD_OriginatedVisitedMSCAd 28
77 #define CIMD_DataCodingScheme 30
78 #define CIMD_UserDataHeader 32
79 #define CIMD_UserData 33
80 #define CIMD_UserDataBinary 34
81 #define CIMD_MoreMessagesToSend 44
82 #define CIMD_ValidityPeriodRelative 50
83 #define CIMD_ValidityPeriodAbsolute 51
84 #define CIMD_ProtocolIdentifier 52
85 #define CIMD_FirstDeliveryTimeRel 53
86 #define CIMD_FirstDeliveryTimeAbs 54
87 #define CIMD_ReplyPath 55
88 #define CIMD_StatusReportRequest 56
89 #define CIMD_CancelEnabled 58
90 #define CIMD_CancelMode 59
91 #define CIMD_SCTimeStamp 60
92 #define CIMD_StatusCode 61
93 #define CIMD_StatusErrorCode 62
94 #define CIMD_DischargeTime 63
95 #define CIMD_TariffClass 64
96 #define CIMD_ServiceDescription 65
97 #define CIMD_MessageCount 66
98 #define CIMD_Priority 67
99 #define CIMD_DeliveryRequestMode 68
100 #define CIMD_SCAddress 69
101 #define CIMD_GetParameter 500
102 #define CIMD_SMSCTime 501
103 #define CIMD_ErrorCode 900
104 #define CIMD_ErrorText 901
106 #define MAXPARAMSCOUNT 37
108 typedef struct cimd_parameter_t cimd_parameter_t;
110 typedef void (*cimd_pdissect)(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset);
112 struct cimd_parameter_t {
113 cimd_pdissect diss;
114 int *ett_p;
115 int *hf_p;
118 void proto_register_cimd(void);
119 void proto_reg_handoff_cimd(void);
120 static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset);
121 static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset);
122 static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset);
123 static void dissect_cimd_error_code(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset);
125 static dissector_handle_t cimd_handle;
127 static int proto_cimd;
128 /* Initialize the subtree pointers */
129 static int ett_cimd;
131 /* Initialize the protocol and registered fields */
132 static int hf_cimd_opcode_indicator;
133 static int hf_cimd_packet_number_indicator;
134 static int hf_cimd_checksum_indicator;
135 static int hf_cimd_pcode_indicator;
137 static int hf_cimd_dcs_coding_group_indicatorC0;
138 static int hf_cimd_dcs_coding_group_indicatorF0;
139 static int hf_cimd_dcs_compressed_indicator;
140 static int hf_cimd_dcs_message_class_meaning_indicator;
141 static int hf_cimd_dcs_message_class_indicator;
142 static int hf_cimd_dcs_character_set_indicator0C;
143 static int hf_cimd_dcs_character_set_indicator04;
144 static int hf_cimd_dcs_indication_sense;
145 static int hf_cimd_dcs_indication_type;
147 static const value_string vals_hdr_OC[] = {
148 /* operation codes array */
149 {CIMD_Login, "Login"},
150 {CIMD_LoginResp, "Login Resp"},
151 {CIMD_Logout, "Logout"},
152 {CIMD_LogoutResp, "Logout Resp"},
153 {CIMD_SubmitMessage, "Submit message"},
154 {CIMD_SubmitMessageResp, "Submit message Resp"},
155 {CIMD_EnqMessageStatus, "Enquire message status"},
156 {CIMD_EnqMessageStatusResp, "Enquire message status Resp"},
157 {CIMD_DeliveryRequest, "Delivery request"},
158 {CIMD_DeliveryRequestResp, "Delivery request Resp"},
159 {CIMD_CancelMessage, "Cancel message"},
160 {CIMD_CancelMessageResp, "Cancel message Resp"},
161 {CIMD_SetMessage, "Set message"},
162 {CIMD_SetMessageResp, "Set message Resp"},
163 {CIMD_GetMessage, "Get message"},
164 {CIMD_GetMessageResp, "Get message Resp"},
165 {CIMD_Alive, "Alive"},
166 {CIMD_AliveResp, "Alive Resp"},
167 {CIMD_GeneralErrorResp, "General error Resp"},
168 {CIMD_NACK, "Nack"},
169 /* SC2App */
170 {CIMD_DeliveryMessage, "Deliver message"},
171 {CIMD_DeliveryMessageResp, "Deliver message Resp"},
172 {CIMD_DeliveryStatusReport, "Deliver status report"},
173 {CIMD_DeliveryStatusReportResp, "Deliver status report Resp"},
174 {0, NULL}
177 static const value_string cimd_vals_PC[] = {
178 /* parameter codes array */
179 {CIMD_UserIdentity, "User Identity"},
180 {CIMD_Password, "Password"},
181 {CIMD_Subaddress, "Subaddr"},
182 {CIMD_WindowSize, "Window Size"},
183 {CIMD_DestinationAddress, "Destination Address"},
184 {CIMD_OriginatingAddress, "Originating Address"},
185 {CIMD_OriginatingImsi, "Originating IMSI"},
186 {CIMD_AlphaOriginatingAddr, "Alphanumeric Originating Address"},
187 {CIMD_OriginatedVisitedMSCAd, "Originated Visited MSC Address"},
188 {CIMD_DataCodingScheme, "Data Coding Scheme"},
189 {CIMD_UserDataHeader, "User Data Header"},
190 {CIMD_UserData, "User Data"},
191 {CIMD_UserDataBinary, "User Data Binary"},
192 {CIMD_MoreMessagesToSend, "More Messages To Send"},
193 {CIMD_ValidityPeriodRelative, "Validity Period Relative"},
194 {CIMD_ValidityPeriodAbsolute, "Validity Period Absolute"},
195 {CIMD_ProtocolIdentifier, "Protocol Identifier"},
196 {CIMD_FirstDeliveryTimeRel, "First Delivery Time Relative"},
197 {CIMD_FirstDeliveryTimeAbs, "First Delivery Time Absolute"},
198 {CIMD_ReplyPath, "Reply Path"},
199 {CIMD_StatusReportRequest, "Status Report Request"},
200 {CIMD_CancelEnabled, "Cancel Enabled"},
201 {CIMD_CancelMode, "Cancel Mode"},
202 {CIMD_SCTimeStamp, "Service Centre Time Stamp"},
203 {CIMD_StatusCode, "Status Code"},
204 {CIMD_StatusErrorCode, "Status Error Code"},
205 {CIMD_DischargeTime, "Discharge Time"},
206 {CIMD_TariffClass, "Tariff Class"},
207 {CIMD_ServiceDescription, "Service Description"},
208 {CIMD_MessageCount, "Message Count"},
209 {CIMD_Priority, "Priority"},
210 {CIMD_DeliveryRequestMode, "Delivery Request Mode"},
211 {CIMD_SCAddress, "Service Center Address"},
212 {CIMD_GetParameter, "Get Parameter"},
213 {CIMD_SMSCTime, "SMS Center Time"},
214 {CIMD_ErrorCode, "Error Code"},
215 {CIMD_ErrorText, "Error Text"},
216 {0, NULL}
219 static const value_string cimd_dcs_coding_groups[] = {
220 {0x00, "General Data Coding indication"},
221 {0x01, "General Data Coding indication"},
222 {0x02, "General Data Coding indication"},
223 {0x03, "General Data Coding indication"},
224 {0x04, "Message Marked for Automatic Deletion Group"},
225 {0x05, "Message Marked for Automatic Deletion Group"},
226 {0x06, "Message Marked for Automatic Deletion Group"},
227 {0x07, "Message Marked for Automatic Deletion Group"},
228 {0x08, "Reserved coding group"},
229 {0x09, "Reserved coding group"},
230 {0x0A, "Reserved coding group"},
231 {0x0B, "Reserved coding group"},
232 {0x0C, "Message Waiting Indication Group: Discard Message (7-bit encoded)"},
233 {0x0D, "Message Waiting Indication Group: Store Message (7-bit encoded)"},
234 {0x0E, "Message Waiting Indication Group: Store Message (uncompressed UCS2 encoded)"},
235 {0x0F, "Data coding/message class"},
236 {0, NULL}
239 static const value_string cimd_dcs_compressed[] = {
240 {0x00, "Text is uncompressed"},
241 {0x01, "Text is compressed"},
242 {0, NULL}
245 static const value_string cimd_dcs_message_class_meaning[] = {
246 {0x00, "Reserved, bits 1 to 0 have no message class meaning"},
247 {0x01, "Bits 1 to 0 have message class meaning"},
248 {0, NULL}
251 static const value_string cimd_dcs_message_class[] = {
252 {0x00, "Class 0"},
253 {0x01, "Class 1 Default meaning: ME-specific"},
254 {0x02, "Class 2 (U)SIM specific message"},
255 {0x03, "Class 3 Default meaning: TE-specific"},
256 {0, NULL}
259 static const value_string cimd_dcs_character_set[] = {
260 {0x00, "GSM 7 bit default alphabet"},
261 {0x01, "8 bit data"},
262 {0x02, "UCS2 (16bit)"},
263 {0x03, "Reserved"},
264 {0, NULL}
267 static const value_string cimd_dcs_indication_sense[] = {
268 {0x00, "Set Indication Inactive"},
269 {0x01, "Set Indication Active"},
270 {0, NULL}
273 static const value_string cimd_dcs_indication_type[] = {
274 {0x00, "Voicemail Message Waiting"},
275 {0x01, "Fax Message Waiting"},
276 {0x02, "Electronic Mail Message Waiting"},
277 {0x03, "Other Message Waiting"},
278 {0, NULL}
281 static const value_string cimd_error_vals[] = {
282 {1, "Unexpected operation"},
283 {2, "Syntax error"},
284 {3, "Unsupported parameter error"},
285 {4, "Connection to SMS Center lost"},
286 {5, "No response from SMS Center"},
287 {6, "General system error"},
288 {7, "Cannot find information"},
289 {8, "Parameter formatting error"},
290 {9, "Requested operation failed"},
291 {10, "Temporary congestion error"},
292 {100, "Invalid login"},
293 {101, "Incorrect access type"},
294 {102, "Too many users with this login ID"},
295 {103, "Login refused by SMS Center"},
296 {104, "Invalid window size"},
297 {105, "Windowing disabled"},
298 {106, "Virtual SMS Center-based barring"},
299 {107, "Invalid subaddr"},
300 {108, "Alias account, login refused"},
301 {300, "Incorrect destination address"},
302 {301, "Incorrect number of destination addresses"},
303 {302, "Syntax error in user data parameter"},
304 {303, "Incorrect bin/head/normal user data parameter combination"},
305 {304, "Incorrect dcs parameter usage"},
306 {305, "Incorrect validity period parameters usage"},
307 {306, "Incorrect originator address usage"},
308 {307, "Incorrect PID parameter usage"},
309 {308, "Incorrect first delivery parameter usage"},
310 {309, "Incorrect reply path usage"},
311 {310, "Incorrect status report request parameter usage"},
312 {311, "Incorrect cancel enabled parameter usage"},
313 {312, "Incorrect priority parameter usage"},
314 {313, "Incorrect tariff class parameter usage"},
315 {314, "Incorrect service description parameter usage"},
316 {315, "Incorrect transport type parameter usage"},
317 {316, "Incorrect message type parameter usage"},
318 {318, "Incorrect MMs parameter usage"},
319 {319, "Incorrect operation timer parameter usage"},
320 {320, "Incorrect dialogue ID parameter usage"},
321 {321, "Incorrect alpha originator address usage"},
322 {322, "Invalid data for alpha numeric originator"},
323 {400, "Incorrect address parameter usage"},
324 {401, "Incorrect scts parameter usage"},
325 {500, "Incorrect scts parameter usage"},
326 {501, "Incorrect mode parameter usage"},
327 {502, "Incorrect parameter combination"},
328 {600, "Incorrect scts parameter usage"},
329 {601, "Incorrect address parameter usage"},
330 {602, "Incorrect mode parameter usage"},
331 {603, "Incorrect parameter combination"},
332 {800, "Changing password failed"},
333 {801, "Changing password not allowed"},
334 {900, "Unsupported item requested"},
335 {0, NULL}
338 static value_string_ext cimd_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_error_vals);
340 static const value_string cimd_status_code_vals[] = {
341 {1, " in process"},
342 {2, " validity period expired"},
343 {3, " delivery failed"},
344 {4, " delivery successful"},
345 {5, " no response"},
346 {6, " last no response"},
347 {7, " message cancelled"},
348 {8, " message deleted"},
349 {9, " message deleted by cancel"},
350 {0, NULL}
353 static const value_string cimd_status_error_vals[] = {
354 {1, "Unknown subscriber"},
355 {9, "Illegal subscriber"},
356 {11, "Teleservice not provisioned"},
357 {13, "Call barred"},
358 {15, "CUG reject"},
359 {19, "No SMS support in MS"},
360 {20, "Error in MS"},
361 {21, "Facility not supported"},
362 {22, "Memory capacity exceeded"},
363 {29, "Absent subscriber"},
364 {30, "MS busy for MT SMS"},
365 {36, "Network/Protocol failure"},
366 {44, "Illegal equipment"},
367 {60, "No paging response"},
368 {61, "GMSC congestion"},
369 {63, "HLR timeout"},
370 {64, "MSC/SGSN_timeout"},
371 {70, "SMRSE/TCP error"},
372 {72, "MT congestion"},
373 {75, "GPRS suspended"},
374 {80, "No paging response via MSC"},
375 {81, "IMSI detached"},
376 {82, "Roaming restriction"},
377 {83, "Deregistered in HLR for GSM"},
378 {84, "Purged for GSM"},
379 {85, "No paging response via SGSN"},
380 {86, "GPRS detached"},
381 {87, "Deregistered in HLR for GPRS"},
382 {88, "The MS purged for GPRS"},
383 {89, "Unidentified subscriber via MSC"},
384 {90, "Unidentified subscriber via SGSN"},
385 {112, "Originator missing credit on prepaid account"},
386 {113, "Destination missing credit on prepaid account"},
387 {114, "Error in prepaid system"},
388 {0, NULL}
391 static value_string_ext cimd_status_error_vals_ext = VALUE_STRING_EXT_INIT(cimd_status_error_vals);
393 static const cimd_pdissect cimd_pc_handles[] = {
394 /* function handles for parsing cimd parameters */
395 dissect_cimd_parameter,
396 dissect_cimd_parameter,
397 dissect_cimd_parameter,
398 dissect_cimd_parameter,
399 dissect_cimd_parameter,
400 dissect_cimd_parameter,
401 dissect_cimd_parameter,
402 dissect_cimd_parameter,
403 dissect_cimd_parameter,
404 dissect_cimd_dcs,
405 dissect_cimd_parameter,
406 dissect_cimd_ud,
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_parameter,
417 dissect_cimd_parameter,
418 dissect_cimd_parameter,
419 dissect_cimd_error_code,
420 dissect_cimd_error_code,
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_parameter,
428 dissect_cimd_parameter,
429 dissect_cimd_parameter,
430 dissect_cimd_error_code,
431 dissect_cimd_parameter
434 /* Parameters */
435 static cimd_parameter_t vals_hdr_PC[MAXPARAMSCOUNT + 1];
436 static int ett_index[MAXPARAMSCOUNT];
437 static int hf_index[MAXPARAMSCOUNT];
439 static void dissect_cimd_parameter(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset)
441 /* Set up structures needed to add the param subtree and manage it */
442 proto_tree *param_tree;
444 param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
445 (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
447 proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
448 startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
449 proto_tree_add_item(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb,
450 startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII|ENC_NA);
453 static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset)
455 /* Set up structures needed to add the param subtree and manage it */
456 proto_tree *param_tree;
458 uint8_t *tmpBuffer1;
459 const uint8_t* payloadText;
460 wmem_strbuf_t *tmpBuffer;
461 int loop;
462 int g_offset, g_size;
463 char token[4];
465 /* The user data (33) parameter is used when the data coding scheme (30)
466 * indicates that the default GSM character set is being used.
467 * It is not transmitted directly as the 23.038 GSM encoding (packed
468 * or unpacked), but rather each character is converted to ASCII
469 * or Latin-1 (ISO-8859-1).
471 * (XXX: It is possible that the UDH indicates that a national
472 * language shift table is to be used, but we don't implement that.
473 * It is also theoretically possible for some encoding other than
474 * Latin-1 to be used.)
476 * It is simplest to first convert back to the GSM 7 bit encoding (unpacked),
477 * and then convert that to UTF-8, since the GSM extension table characters
478 * require a second level of escape handling. We will use '\xff' as a
479 * placeholder for illegal characters that will be replaced with Unicode
480 * REPLACEMENT CHARACTERS upon final conversion.
482 static const value_string combining_mapping[] = {
483 { 0, "_Oa"},
484 { 1, "_L-"},
485 { 3, "_Y-"},
486 { 4, "_e`"},
487 { 5, "_e'"},
488 { 6, "_u`"},
489 { 7, "_i`"},
490 { 8, "_o`"},
491 { 9, "_C,"},
492 { 11, "_O/"},
493 { 12, "_o/"},
494 { 14, "_A*"},
495 { 15, "_a*"},
496 { 16, "_gd"},
497 { 17, "_--"},
498 { 18, "_gf"},
499 { 19, "_gg"},
500 { 20, "_gl"},
501 { 21, "_go"},
502 { 22, "_gp"},
503 { 23, "_gi"},
504 { 24, "_gs"},
505 { 25, "_gt"},
506 { 26, "_gx"},
507 { 27, "_XX"},
508 { 28, "_AE"},
509 { 29, "_ae"},
510 { 30, "_ss"},
511 { 31, "_E'"},
512 { 34, "_qq"},
513 { 36, "_ox"},
514 { 40, "_!!"},
515 { 91, "_A\""},
516 { 92, "_O\""},
517 { 93, "_N~"},
518 { 94, "_U\""},
519 { 95, "_so"},
520 { 96, "_??"},
521 {123, "_a\""},
522 {124, "_o\""},
523 {125, "_n~"},
524 {126, "_n\""},
525 {127, "_a`"},
526 { 0, NULL }
529 static const char latin_mapping[256] = {
530 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x00 - */
531 0xff, 0xff, 0x0a, 0xff, 0xff, 0x0d, 0xff, 0xff, /* - 0x0F */
532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x10 - */
533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x1F */
534 0x20, 0x21, 0x22, 0x23, 0x02, 0x25, 0x26, 0x27, /* 0x20 - */
535 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* - 0x2F */
536 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 - */
537 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* - 0x3F */
538 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 - */
539 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* - 0x4F */
540 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 - */
541 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x0e, 0x5e, 0xff, /* - 0x5F */
542 0xff, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 - */
543 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* - 0x6F */
544 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 - */
545 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x0f, 0x7e, 0xff, /* - 0x7F */
546 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 - */
547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x8F */
548 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 - */
549 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0x9F */
550 0xff, 0x40, 0xff, 0x01, 0x24, 0x03, 0xff, 0x5f, /* 0xA0 - */
551 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0xAF */
552 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xB0 - */
553 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, /* - 0xBF */
554 0xff, 0xff, 0xff, 0xff, 0x5b, 0x0e, 0x1c, 0x09, /* 0xC0 - */
555 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* - 0xCF */
558 param_tree = proto_tree_add_subtree(tree, tvb,
559 startOffset + 1, endOffset - (startOffset + 1),
560 (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
562 proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
563 startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
565 g_offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
566 g_size = endOffset - g_offset;
568 payloadText = tvb_get_ptr(tvb, g_offset, g_size);
569 tmpBuffer = wmem_strbuf_new_sized(wmem_packet_scope(), g_size+1);
570 for (loop = 0; loop < g_size; loop++)
572 if (payloadText[loop] == '_')
574 if (loop < g_size - 2)
576 token[0] = payloadText[loop++];
577 token[1] = payloadText[loop++];
578 token[2] = payloadText[loop];
579 token[3] = '\0';
580 wmem_strbuf_append_c(tmpBuffer, str_to_val(token, combining_mapping, 0xff));
582 else
584 /* Not enough room for a combining sequence. */
585 wmem_strbuf_append_c(tmpBuffer, 0xff);
588 else
590 wmem_strbuf_append_c(tmpBuffer, latin_mapping[payloadText[loop]]);
594 tmpBuffer1 = get_ts_23_038_7bits_string_unpacked(wmem_packet_scope(), wmem_strbuf_get_str(tmpBuffer), (int)wmem_strbuf_get_len(tmpBuffer));
595 wmem_strbuf_destroy(tmpBuffer);
596 proto_tree_add_string(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, g_offset, g_size, tmpBuffer1);
599 static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset)
601 /* Set up structures needed to add the param subtree and manage it */
602 proto_tree *param_tree;
603 int offset;
604 uint32_t dcs;
605 uint32_t dcs_cg; /* coding group */
607 param_tree = proto_tree_add_subtree(tree, tvb,
608 startOffset + 1, endOffset - (startOffset + 1),
609 (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr
612 proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb,
613 startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
615 offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
616 dcs = (uint32_t) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, endOffset - offset, ENC_ASCII), NULL, 10);
617 proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, offset, endOffset - offset, dcs);
619 dcs_cg = (dcs & 0xF0) >> 4;
620 if (dcs_cg <= 0x07)
622 proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorC0, tvb, offset, 1, dcs);
624 else
626 proto_tree_add_uint(param_tree, hf_cimd_dcs_coding_group_indicatorF0, tvb, offset, 1, dcs);
629 if (dcs_cg <= 0x07)
631 proto_tree_add_uint(param_tree, hf_cimd_dcs_compressed_indicator, tvb, offset, 1, dcs);
632 proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_meaning_indicator, tvb, offset, 1, dcs);
633 proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator0C, tvb, offset, 1, dcs);
635 if (dcs & 0x10)
637 proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
640 else if (dcs_cg >= 0x0C && dcs_cg <= 0x0E)
642 proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_sense, tvb, offset, 1, dcs);
643 proto_tree_add_uint(param_tree, hf_cimd_dcs_indication_type, tvb, offset, 1, dcs);
645 else if (dcs_cg == 0x0F)
647 proto_tree_add_uint(param_tree, hf_cimd_dcs_character_set_indicator04, tvb, offset, 1, dcs);
648 proto_tree_add_uint(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs);
652 static void dissect_cimd_error_code( tvbuff_t *tvb, proto_tree *tree, int pindex, int startOffset, int endOffset )
654 /* Same routine can be used to dissect CIMD Error,Status and Status Error Codes */
655 proto_tree *param_tree;
656 uint32_t err_code;
658 param_tree = proto_tree_add_subtree(tree, tvb, startOffset + 1, endOffset - (startOffset + 1),
659 (*vals_hdr_PC[pindex].ett_p), NULL, cimd_vals_PC[pindex].strptr);
661 proto_tree_add_item(param_tree, hf_cimd_pcode_indicator, tvb, startOffset + 1, CIMD_PC_LENGTH, ENC_ASCII);
663 err_code = (uint32_t) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb,
664 startOffset + 1 + CIMD_PC_LENGTH + 1, endOffset - (startOffset + 1 + CIMD_PC_LENGTH + 1), ENC_ASCII),
665 NULL, 10);
666 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);
669 static void
670 dissect_cimd_operation(tvbuff_t *tvb, proto_tree *tree, int etxp, uint16_t checksum, uint8_t last1,uint8_t OC, uint8_t PN)
672 uint32_t PC = 0; /* Parameter code */
673 int idx;
674 int offset = 0;
675 int endOffset = 0;
676 proto_item *cimd_item;
677 proto_tree *cimd_tree;
679 /* create display subtree for the protocol */
680 cimd_item = proto_tree_add_item(tree, proto_cimd, tvb, 0, etxp + 1, ENC_NA);
681 cimd_tree = proto_item_add_subtree(cimd_item, ett_cimd);
682 proto_tree_add_uint(cimd_tree, hf_cimd_opcode_indicator, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, OC);
683 proto_tree_add_uint(cimd_tree, hf_cimd_packet_number_indicator, tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, PN);
685 offset = CIMD_PN_OFFSET + CIMD_PN_LENGTH;
686 while (offset < etxp && tvb_get_uint8(tvb, offset) == CIMD_DELIM)
688 endOffset = tvb_find_uint8(tvb, offset + 1, etxp, CIMD_DELIM);
689 if (endOffset == -1)
690 break;
692 PC = (uint32_t) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 1, CIMD_PC_LENGTH, ENC_ASCII), NULL, 10);
693 try_val_to_str_idx(PC, cimd_vals_PC, &idx);
694 if (idx != -1 && tree)
696 (vals_hdr_PC[idx].diss)(tvb, cimd_tree, idx, offset, endOffset);
698 offset = endOffset;
701 if (last1 != CIMD_DELIM)
703 /* Checksum is present */
704 proto_tree_add_uint(cimd_tree, hf_cimd_checksum_indicator, tvb, etxp - 2, 2, checksum);
708 static int
709 dissect_cimd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
711 uint8_t OC; /* Operation Code */
712 uint8_t PN; /* Packet number */
713 uint16_t checksum = 0; /* Checksum */
714 uint16_t pkt_check = 0;
715 int etxp = 0; /* ETX position */
716 int offset = 0;
717 bool checksumIsValid = true;
718 uint8_t last1, last2, last3;
720 etxp = tvb_find_uint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH, -1, CIMD_ETX);
721 if (etxp == -1) return 0;
723 OC = (uint8_t)strtoul(tvb_get_string_enc(pinfo->pool, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
724 PN = (uint8_t)strtoul(tvb_get_string_enc(pinfo->pool, tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, ENC_ASCII), NULL, 10);
726 last1 = tvb_get_uint8(tvb, etxp - 1);
727 last2 = tvb_get_uint8(tvb, etxp - 2);
728 last3 = tvb_get_uint8(tvb, etxp - 3);
730 if (last1 == CIMD_DELIM) {
731 /* valid packet, CC is missing */
732 } else if (last1 != CIMD_DELIM && last2 != CIMD_DELIM && last3 == CIMD_DELIM) {
733 /* looks valid, it would be nice to check that last1 and last2 are HEXA */
734 /* CC is present */
735 checksum = (uint16_t)strtoul(tvb_get_string_enc(pinfo->pool, tvb, etxp - 2, 2, ENC_ASCII), NULL, 16);
736 for (; offset < (etxp - 2); offset++)
738 pkt_check += tvb_get_uint8(tvb, offset);
739 pkt_check &= 0xFF;
741 checksumIsValid = (checksum == pkt_check);
742 } else {
743 checksumIsValid = false;
746 /* Make entries in Protocol column on summary display */
747 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIMD");
749 if (checksumIsValid)
750 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(OC, vals_hdr_OC, "Unknown (%d)"));
751 else
752 col_add_fstr(pinfo->cinfo, COL_INFO, "%s - %s", val_to_str(OC, vals_hdr_OC, "Unknown (%d)"), "invalid checksum");
754 dissect_cimd_operation(tvb, tree, etxp, checksum, last1, OC, PN);
755 return tvb_captured_length(tvb);
759 * A 'heuristic dissector' that attemtps to establish whether we have
760 * a CIMD MSU here.
762 static bool
763 dissect_cimd_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
765 int etxp;
766 uint8_t opcode = 0; /* Operation code */
768 if (tvb_captured_length(tvb) < CIMD_MIN_LENGTH)
769 return false;
771 if (tvb_get_uint8(tvb, 0) != CIMD_STX)
772 return false;
774 etxp = tvb_find_uint8(tvb, CIMD_OC_OFFSET, -1, CIMD_ETX);
775 if (etxp == -1)
776 { /* XXX - should we have an option to request reassembly? */
777 return false;
780 /* Try getting the operation-code */
781 opcode = (uint8_t)strtoul(tvb_get_string_enc(pinfo->pool, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
782 if (try_val_to_str(opcode, vals_hdr_OC) == NULL)
783 return false;
785 if (tvb_get_uint8(tvb, CIMD_OC_OFFSET + CIMD_OC_LENGTH) != CIMD_COLON)
786 return false;
788 if (tvb_get_uint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH) != CIMD_DELIM)
789 return false;
791 /* Ok, looks like a valid packet, go dissect. */
792 dissect_cimd(tvb, pinfo, tree, data);
793 return true;
796 void
797 proto_register_cimd(void)
799 static hf_register_info hf[] = {
800 { &hf_cimd_opcode_indicator,
801 { "Operation Code", "cimd.opcode",
802 FT_UINT8, BASE_DEC, NULL, 0x00,
803 NULL, HFILL }
805 { &hf_cimd_packet_number_indicator,
806 { "Packet Number", "cimd.pnumber",
807 FT_UINT8, BASE_DEC, NULL, 0x00,
808 NULL, HFILL }
810 { &hf_cimd_pcode_indicator,
811 { "Parameter Code", "cimd.pcode",
812 FT_STRING, BASE_NONE, NULL, 0x00,
813 NULL, HFILL }
815 { &hf_cimd_checksum_indicator,
816 { "Checksum", "cimd.chksum",
817 FT_UINT8, BASE_HEX, NULL, 0x00,
818 NULL, HFILL }
820 { &hf_cimd_dcs_coding_group_indicatorC0,
821 { "DCS Coding Group", "cimd.dcs.cg",
822 FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xC0,
823 NULL, HFILL }
825 { &hf_cimd_dcs_coding_group_indicatorF0,
826 { "DCS Coding Group", "cimd.dcs.cg",
827 FT_UINT8, BASE_DEC, VALS(cimd_dcs_coding_groups), 0xF0,
828 NULL, HFILL }
830 { &hf_cimd_dcs_compressed_indicator,
831 { "DCS Compressed Flag", "cimd.dcs.cf",
832 FT_UINT8, BASE_DEC, VALS(cimd_dcs_compressed), 0x20,
833 NULL, HFILL }
835 { &hf_cimd_dcs_message_class_meaning_indicator,
836 { "DCS Message Class Meaning", "cimd.dcs.mcm",
837 FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class_meaning), 0x10,
838 NULL, HFILL }
840 { &hf_cimd_dcs_message_class_indicator,
841 { "DCS Message Class", "cimd.dcs.mc",
842 FT_UINT8, BASE_DEC, VALS(cimd_dcs_message_class), 0x03,
843 NULL, HFILL }
845 { &hf_cimd_dcs_character_set_indicator0C,
846 { "DCS Character Set", "cimd.dcs.chs",
847 FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x0C,
848 NULL, HFILL }
850 { &hf_cimd_dcs_character_set_indicator04,
851 { "DCS Character Set", "cimd.dcs.chs",
852 FT_UINT8, BASE_DEC, VALS(cimd_dcs_character_set), 0x04,
853 NULL, HFILL }
855 { &hf_cimd_dcs_indication_sense,
856 { "DCS Indication Sense", "cimd.dcs.is",
857 FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_sense), 0x04,
858 NULL, HFILL }
860 { &hf_cimd_dcs_indication_type,
861 { "DCS Indication Type", "cimd.dcs.it",
862 FT_UINT8, BASE_DEC, VALS(cimd_dcs_indication_type), 0x03,
863 NULL, HFILL }
865 { &hf_index[0],
866 { "User Identity", "cimd.ui",
867 FT_STRING, BASE_NONE, NULL, 0x00,
868 NULL, HFILL }
870 { &hf_index[1],
871 { "Password", "cimd.passwd",
872 FT_STRING, BASE_NONE, NULL, 0x00,
873 NULL, HFILL }
875 { &hf_index[2],
876 { "Subaddress", "cimd.saddr",
877 FT_STRING, BASE_NONE, NULL, 0x00,
878 NULL, HFILL }
880 { &hf_index[3],
881 { "Window Size", "cimd.ws",
882 FT_STRING, BASE_NONE, NULL, 0x00,
883 NULL, HFILL }
885 { &hf_index[4],
886 { "Destination Address", "cimd.da",
887 FT_STRING, BASE_NONE, NULL, 0x00,
888 NULL, HFILL }
890 { &hf_index[5],
891 { "Originating Address", "cimd.oa",
892 FT_STRING, BASE_NONE, NULL, 0x00,
893 NULL, HFILL }
895 { &hf_index[6],
896 { "Originating IMSI", "cimd.oimsi",
897 FT_STRING, BASE_NONE, NULL, 0x00,
898 NULL, HFILL }
900 { &hf_index[7],
901 { "Alphanumeric Originating Address", "cimd.aoi",
902 FT_STRING, BASE_NONE, NULL, 0x00,
903 NULL, HFILL }
905 { &hf_index[8],
906 { "Originated Visited MSC Address", "cimd.ovma",
907 FT_STRING, BASE_NONE, NULL, 0x00,
908 NULL, HFILL }
910 { &hf_index[9],
911 { "Data Coding Scheme", "cimd.dcs",
912 FT_UINT8, BASE_HEX, NULL, 0x00,
913 NULL, HFILL }
915 { &hf_index[10],
916 { "User Data Header", "cimd.udh",
917 FT_STRING, BASE_NONE, NULL, 0x00,
918 NULL, HFILL }
920 { &hf_index[11],
921 { "User Data", "cimd.ud",
922 FT_STRING, BASE_NONE, NULL, 0x00,
923 NULL, HFILL }
925 { &hf_index[12],
926 { "User Data Binary", "cimd.udb",
927 FT_STRING, BASE_NONE, NULL, 0x00,
928 NULL, HFILL }
930 { &hf_index[13],
931 { "More Messages To Send", "cimd.mms",
932 FT_STRING, BASE_NONE, NULL, 0x00,
933 NULL, HFILL }
935 { &hf_index[14],
936 { "Validity Period Relative", "cimd.vpr",
937 FT_STRING, BASE_NONE, NULL, 0x00,
938 NULL, HFILL }
940 { &hf_index[15],
941 { "Validity Period Absolute", "cimd.vpa",
942 FT_STRING, BASE_NONE, NULL, 0x00,
943 NULL, HFILL }
945 { &hf_index[16],
946 { "Protocol Identifier", "cimd.pi",
947 FT_STRING, BASE_NONE, NULL, 0x00,
948 NULL, HFILL }
950 { &hf_index[17],
951 { "First Delivery Time Relative", "cimd.fdtr",
952 FT_STRING, BASE_NONE, NULL, 0x00,
953 NULL, HFILL }
955 { &hf_index[18],
956 { "First Delivery Time Absolute", "cimd.fdta",
957 FT_STRING, BASE_NONE, NULL, 0x00,
958 NULL, HFILL }
960 { &hf_index[19],
961 { "Reply Path", "cimd.rpath",
962 FT_STRING, BASE_NONE, NULL, 0x00,
963 NULL, HFILL }
965 { &hf_index[20],
966 { "Status Report Request", "cimd.srr",
967 FT_STRING, BASE_NONE, NULL, 0x00,
968 NULL, HFILL }
970 { &hf_index[21],
971 { "Cancel Enabled", "cimd.ce",
972 FT_STRING, BASE_NONE, NULL, 0x00,
973 NULL, HFILL }
975 { &hf_index[22],
976 { "Cancel Mode", "cimd.cm",
977 FT_STRING, BASE_NONE, NULL, 0x00,
978 NULL, HFILL }
980 { &hf_index[23],
981 { "Service Center Time Stamp", "cimd.scts",
982 FT_STRING, BASE_NONE, NULL, 0x00,
983 NULL, HFILL }
985 { &hf_index[24],
986 { "Status Code", "cimd.stcode",
987 FT_UINT8, BASE_DEC, VALS(cimd_status_code_vals), 0x00,
988 NULL, HFILL }
990 { &hf_index[25],
991 { "Status Error Code", "cimd.sterrcode",
992 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_status_error_vals_ext, 0x00,
993 NULL, HFILL }
995 { &hf_index[26],
996 { "Discharge Time", "cimd.dt",
997 FT_STRING, BASE_NONE, NULL, 0x00,
998 NULL, HFILL }
1000 { &hf_index[27],
1001 { "Tariff Class", "cimd.tclass",
1002 FT_STRING, BASE_NONE, NULL, 0x00,
1003 NULL, HFILL }
1005 { &hf_index[28],
1006 { "Service Description", "cimd.sdes",
1007 FT_STRING, BASE_NONE, NULL, 0x00,
1008 NULL, HFILL }
1010 { &hf_index[29],
1011 { "Message Count", "cimd.mcount",
1012 FT_STRING, BASE_NONE, NULL, 0x00,
1013 NULL, HFILL }
1015 { &hf_index[30],
1016 { "Priority", "cimd.priority",
1017 FT_STRING, BASE_NONE, NULL, 0x00,
1018 NULL, HFILL }
1020 { &hf_index[31],
1021 { "Delivery Request Mode", "cimd.drmode",
1022 FT_STRING, BASE_NONE, NULL, 0x00,
1023 NULL, HFILL }
1025 { &hf_index[32],
1026 { "Service Center Address", "cimd.scaddr",
1027 FT_STRING, BASE_NONE, NULL, 0x00,
1028 NULL, HFILL }
1030 { &hf_index[33],
1031 { "Get Parameter", "cimd.gpar",
1032 FT_STRING, BASE_NONE, NULL, 0x00,
1033 NULL, HFILL }
1035 { &hf_index[34],
1036 { "SMS Center Time", "cimd.smsct",
1037 FT_STRING, BASE_NONE, NULL, 0x00,
1038 NULL, HFILL }
1040 { &hf_index[35],
1041 { "Error Code Description", "cimd.errcode",
1042 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cimd_error_vals_ext, 0x00,
1043 NULL, HFILL }
1045 { &hf_index[36],
1046 { "Error Text", "cimd.errtext",
1047 FT_STRING, BASE_NONE, NULL, 0x00,
1048 NULL, HFILL }
1052 /* Setup protocol subtree array */
1053 int *ett[MAXPARAMSCOUNT + 1];
1054 int i;
1056 ett[0] = &ett_cimd;
1058 for(i=0;i<MAXPARAMSCOUNT;i++)
1060 ett[i + 1] = &(ett_index[i]);
1061 vals_hdr_PC[i].ett_p = &(ett_index[i]);
1062 vals_hdr_PC[i].hf_p = &(hf_index[i]);
1063 vals_hdr_PC[i].diss = cimd_pc_handles[i];
1066 /* Register the protocol name and description */
1067 proto_cimd = proto_register_protocol("Computer Interface to Message Distribution", "CIMD", "cimd");
1068 /* Required function calls to register the header fields and subtrees used */
1069 proto_register_field_array(proto_cimd, hf, array_length(hf));
1070 proto_register_subtree_array(ett, array_length(ett));
1072 /* Register the dissector */
1073 cimd_handle = register_dissector("cimd", dissect_cimd, proto_cimd);
1076 void
1077 proto_reg_handoff_cimd(void)
1080 * CIMD can be spoken on any port so, when not on a specific port, try this
1081 * one whenever TCP is spoken.
1083 heur_dissector_add("tcp", dissect_cimd_heur, "CIMD over TCP", "cimd_tcp", proto_cimd, HEURISTIC_ENABLE);
1086 * Also register as one that can be selected by a TCP port number.
1088 dissector_add_for_decode_as_with_preference("tcp.port", cimd_handle);
1092 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1094 * Local Variables:
1095 * c-basic-offset: 2
1096 * tab-width: 8
1097 * indent-tabs-mode: nil
1098 * End:
1100 * ex: set shiftwidth=2 tabstop=8 expandtab:
1101 * :indentSize=2:tabSize=8:noTabs=true: