2 * Routines for GSM Mobile Application Part dissection
4 * Copyright 2000, Felix Fei <felix.fei [AT] utstar.com>
6 * Michael Lum <mlum [AT] telostech.com>,
7 * Changed to run on new version of TCAP, many changes for
8 * EOC matching, and parameter separation. (2003)
10 * $Id: packet-gsm_map.c,v 1.4 2003/12/21 21:41:10 guy Exp $
12 * Ethereal - Network traffic analyzer
13 * By Gerald Combs <gerald@ethereal.com>
14 * Copyright 1998 Gerald Combs
16 * Copied from packet-tcap.c (where "WHATEVER_FILE_YOU_USED"
17 * is a dissector file; if you just copied this from README.developer,
18 * don't bother with the "Copied from" - you don't even need to put
19 * in a "Copied from" if you copied an existing dissector, especially
20 * if the bulk of the code in the new dissector is your code)
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45 #include "epan/packet.h"
49 /* OPERATION CODE DEFINITION */
51 /* LOCATION MANAGEMENT */
52 #define MAP_UPD_LOC 2 /* Update Location */
53 #define MAP_CANCEL_LOC 3 /* Cancel Location */
54 #define MAP_PURGE 67 /* Purge MS */
55 #define MAP_SEND_ID 5 /* Send Identification */
56 #define MAP_GPRS_UPD_LOC 23 /* GPRS Update Location */
57 #define MAP_DET_IMSI 5 /* Detach IMSI */
58 #define MAP_NOTE_MM_EVT 89 /* Note MM Event */
60 /* HANDOVER MANAGEMENT */
61 #define MAP_PREP_HO 68 /* Prepare Handover */
62 #define MAP_PREP_SUBS_HO 69 /* Prepare Subsequent Handover */
63 #define MAP_PERF_HO 28 /* Perform Handover */
64 #define MAP_PERF_SUBS_HO 30 /* Perform Subsequent Handover */
65 #define MAP_SEND_END_SIG 29 /* Send End Signal */
66 #define MAP_PROC_ACC_SIG 33 /* Process Access Signalling */
67 #define MAP_FWD_ACC_SIG 34 /* Forward Access Signalling */
69 /* AUTHENTICATION MANAGEMENT */
70 #define MAP_AUTH_INFO 56 /* Send Authintication Info */
71 #define MAP_AUTH_FAIL_RPT 15 /* Authentication Failure Report */
73 /* IDENTIFICATION MANAGEMENT */
74 #define MAP_CHK_IMEI 43 /* Check IMEI */
76 /* FAULT & RECOVERY MANAGEMENT */
77 #define MAP_RESET 37 /* Reset */
78 #define MAP_RESTORE_DATA 57 /* Restore Data */
79 #define MAP_FWD_CHK_SS_IND 38 /* Forward Check SS Indication */
82 #define MAP_ACT_TRACE 50 /* Activate Trace */
83 #define MAP_DEACT_TRACE 51 /* Deactivate Trace Mode */
84 #define MAP_SEND_IMSI 58 /* Send IMSI */
85 #define MAP_TRACE_SUBS_ACTV 52 /* Trace Subscriber Activity */
86 #define MAP_NOTE_INTER_HO 35 /* Not Internal Handover */
89 #define MAP_ROUTE_INFO 22 /* Send Routing Info */
90 #define MAP_PROV_ROAM_NUM 4 /* Provide Roaming Number */
91 #define MAP_PROV_SIWFS_NUM 31 /* Provide SIWFS Number */
92 #define MAP_SIWFS_SIG_MOD 32 /* SIWFS Signalling Modify */
93 #define MAP_RES_CALL_HAND 6 /* Resume Call Handling */
94 #define MAP_SET_RPT_STATE 73 /* Set Reporting State */
95 #define MAP_STAT_RPT 74 /* Status Report */
96 #define MAP_REM_USR_FREE 75 /* Remote user free */
97 #define MAP_PREP_GRP_CALL 39 /* Prepare Group Call */
98 #define MAP_SND_GRP_CALL_END_SIG 40 /* Send Group Call End Signalling */
99 #define MAP_PRO_GRP_CALL_SIG 41 /* Process Group Call Signalling */
100 #define MAP_FWD_GRP_CALL_SIG 42 /* Forward Group Call Signalling */
101 #define MAP_IST_ALERT 87 /* IST Alert */
102 #define MAP_IST_COMMAND 88 /* IST Command */
105 #define MAP_REG_SS 10 /* Register SS */
106 #define MAP_ERASE_SS 11 /* Erase SS */
107 #define MAP_ACT_SS 12 /* Activate SS */
108 #define MAP_DEACT_SS 13 /* Deactivate SS */
109 #define MAP_INTER_SS 14 /* Interogate SS */
110 #define MAP_PROC_U_SS_REQ 59 /* Process Unstructured SS Req */
111 #define MAP_U_SS_REQ 60 /* Unstructured SS Request */
112 #define MAP_U_SS_NOTIFY 61 /* Unstructured SS Notify */
113 #define MAP_REG_PASSWD 17 /* Register Password */
114 #define MAP_GET_PASSWD 18 /* Get Password */
115 #define MAP_REG_CC_ENT 76 /* Register CC Entry */
116 #define MAP_ERASE_CC_ENT 77 /* Erase CC Entry */
117 #define MAP_BEGIN_SUBS_ACTV 54 /* Begin Subscriber Activity */
118 #define MAP_PROC_U_SS_DATA 19 /* Process Unstructured SS Data */
119 #define MAP_SS_INV_NOTIFY 72 /* SS Invocation Notify */
122 #define MAP_MO_FWD_SM 46 /* Forward Short Message */
123 #define MAP_MT_FWD_SM 44 /* MT-Fwd SM */
124 #define MAP_ROUTE_INFO_SM 45 /* Routing Info for SM */
125 #define MAP_SM_DEL_STAT 47 /* Report SM Delivery Status */
126 #define MAP_INFORM_SC 63 /* Inform Service Center */
127 #define MAP_ALERT_SC 64 /* Alert Service Center */
128 #define MAP_SM_READY 66 /* SM Ready */
129 #define MAP_NOTE_SUB_PRES 48 /* Note Subscriber Present */
130 #define MAP_ALERT_SC_W_RES 49 /* Alert SC Without Result */
132 /* SUBSCRIBER MANAGEMENT */
133 #define MAP_INS_SUB_DATA 7 /* Insert Subscriber Data */
134 #define MAP_DEL_SUB_DATA 8 /* Delete Subscriber Data */
135 #define MAP_PROV_SUB_INFO 70 /* Provide Subscriber Info */
136 #define MAP_ANY_TIME_INTER 71 /* Any Time Interrogation */
137 #define MAP_SEND_PARAM 9 /* Send Parameters */
138 #define MAP_ANY_TIME_SUB_DATA_INTER 62 /* Any Time Subscriber Info Interrogation */
139 #define MAP_ANY_TIME_MOD 65 /* Any Time Modification */
140 #define MAP_NOTE_SUB_DATA_MOD 5 /* Note Subscriber Data Modified */
142 /* PDP ACTIVE MANAGEMENT */
143 #define MAP_GPRS_ROUTE_INFO 24 /* Rout Info for GPRS */
144 #define MAP_FAIL_REP 25 /* Failure Report */
145 #define MAP_GPRS_NOTE_MS_PRES 26 /* GPRS NoteMs Present */
147 /* LOCATION SERVICE */
148 #define MAP_PROV_SUB_LOC 83 /* Provide Subscriber Location */
149 #define MAP_SEND_ROUTE_INFO_FOR_LCS 85 /* Send Routing Info For LCS */
150 #define MAP_SUB_LOC_REP 86 /* Subscriber Location Report */
153 #define MAP_OPR_CODE_TAG 0x02
154 #define MAP_INVOKE_ID_TAG 0x02
155 #define MAP_LINK_ID_TAG 0x80
156 #define MAP_SEQ_TAG 0x30
157 #define MAP_GE_PROBLEM_TAG 0x80
158 #define MAP_IN_PROBLEM_TAG 0x81
159 #define MAP_RR_PROBLEM_TAG 0x82
160 #define MAP_RE_PROBLEM_TAG 0x83
161 #define MAP_INVALID_TAG 0x00
166 static const value_string opr_code_strings[] = {
168 /* LOCATION MANAGEMENT */
169 { MAP_UPD_LOC, "Update Location"},
170 { MAP_CANCEL_LOC, "Cancel Location"},
171 { MAP_PURGE, "Purge MS"},
172 { MAP_SEND_ID, "Send Identification"},
173 { MAP_GPRS_UPD_LOC, "Update GPRS Location"},
174 { MAP_DET_IMSI, "Detach IMSI"},
175 { MAP_NOTE_MM_EVT, "Note MM Event"},
177 /* HANDOVER MANAGEMENT */
178 { MAP_PREP_HO, "Prepare Handover"},
179 { MAP_PREP_SUBS_HO, "Prepare Subsequent Handover"},
180 { MAP_PERF_HO, "Perform Handover"},
181 { MAP_PERF_SUBS_HO, "Perform Subsequent Handover"},
182 { MAP_SEND_END_SIG, "Send End Signal"},
183 { MAP_PROC_ACC_SIG, "Process Access Signalling"},
184 { MAP_FWD_ACC_SIG, "Forward Access Signalling"},
186 /* AUTHENTICATION MANAGEMENT */
187 { MAP_AUTH_INFO, "Send Authentication Info"},
188 { MAP_AUTH_FAIL_RPT, "Authentication Failure Report"},
190 /* IDENTIFICATION MANAGEMENT */
191 { MAP_CHK_IMEI, "Check IMEI"},
193 /* FAULT & RECOVERY MANAGEMENT */
194 { MAP_RESET, "Reset"},
195 { MAP_RESTORE_DATA, "Restore Data"},
196 { MAP_FWD_CHK_SS_IND, "Forward Check SS Indication"},
199 { MAP_ACT_TRACE, "Activate Trace Mode"},
200 { MAP_DEACT_TRACE, "Deactivate Trace Mode"},
201 { MAP_SEND_IMSI, "Send IMSI"},
202 { MAP_TRACE_SUBS_ACTV, "Trace Subscriber Activity"},
203 { MAP_NOTE_INTER_HO, "Note Internal Handover"},
205 /* CALL MANAGEMENT */
206 { MAP_ROUTE_INFO, "Send Routing Info"},
207 { MAP_PROV_ROAM_NUM, "Provide Roaming Number"},
208 { MAP_PROV_SIWFS_NUM, "Provide SIWFS Number"},
209 { MAP_SIWFS_SIG_MOD, "SIWFS Signalling Modify"},
210 { MAP_RES_CALL_HAND, "Resume Call Handling"},
211 { MAP_SET_RPT_STATE, "Set Reporting State"},
212 { MAP_STAT_RPT, "Status Report"},
213 { MAP_REM_USR_FREE, "Remote User Free"},
214 { MAP_PREP_GRP_CALL, "Prepare Group Call"},
215 { MAP_SND_GRP_CALL_END_SIG, "Send Group Call End Signalling"},
216 { MAP_PRO_GRP_CALL_SIG, "Process Group Call Signalling"},
217 { MAP_FWD_GRP_CALL_SIG, "Forward Group Call Signalling"},
218 { MAP_IST_ALERT, "IST Alert"},
219 { MAP_IST_COMMAND, "IST Command"},
222 { MAP_REG_SS, "Register SS"},
223 { MAP_ERASE_SS, "Erase SS"},
224 { MAP_ACT_SS, "Activate SS"},
225 { MAP_DEACT_SS, "Deactivate SS"},
226 { MAP_INTER_SS, "Interogate SS"},
227 { MAP_PROC_U_SS_REQ, "Process Unstructured SS Request"},
228 { MAP_U_SS_REQ, "Unstructured SS Request"},
229 { MAP_U_SS_NOTIFY, "Unstructured SS Notify"},
230 { MAP_REG_PASSWD, "Register Password"},
231 { MAP_GET_PASSWD, "Get Password"},
232 { MAP_REG_CC_ENT, "Register CC Entry"},
233 { MAP_ERASE_CC_ENT, "Erase CC Entry"},
234 { MAP_BEGIN_SUBS_ACTV, "Begin Subscriber Activity"},
235 { MAP_PROC_U_SS_DATA, "Process Unstructured SS Data"},
236 { MAP_SS_INV_NOTIFY, "SS Invocation Notification"},
239 { MAP_MO_FWD_SM, "MO Forward SM"},
240 { MAP_MT_FWD_SM, "MT Forward SM"},
241 { MAP_ROUTE_INFO_SM, "Send Routing Info For SM"},
242 { MAP_SM_DEL_STAT, "Report SM Delivery Status"},
243 { MAP_INFORM_SC, "Inform Service Center"},
244 { MAP_ALERT_SC, "Alert Service Center"},
245 { MAP_SM_READY, "Ready For SM"},
246 { MAP_NOTE_SUB_PRES, "Note Subscriber Present"},
247 { MAP_ALERT_SC_W_RES, "Alert SC Without Result"},
249 /* SUBSCRIBER MANAGEMENT */
250 { MAP_INS_SUB_DATA, "Insert Subscriber Data"},
251 { MAP_DEL_SUB_DATA, "Delete Subscriber Data"},
252 { MAP_PROV_SUB_INFO, "Provide Subscriber Info"},
253 { MAP_ANY_TIME_INTER, "Any Time Interrogation"},
254 { MAP_SEND_PARAM, "Send Parameters"},
255 { MAP_ANY_TIME_SUB_DATA_INTER, "Any Time Subscription Interrogation"},
256 { MAP_ANY_TIME_MOD, "Any Time Modification"},
257 { MAP_NOTE_SUB_DATA_MOD, "Note Subscriber Data Modified"},
259 /* PDP ACTIVE MANAGEMENT */
260 { MAP_GPRS_ROUTE_INFO, "Send Routing Info For GPRS"},
261 { MAP_FAIL_REP, "Failure Report"},
262 { MAP_GPRS_NOTE_MS_PRES, "Note MS Present For GPRS"},
264 /* LOCATION SERVICE */
265 { MAP_PROV_SUB_LOC, "Provide Subscriber Location"},
266 { MAP_SEND_ROUTE_INFO_FOR_LCS, "Send Routing Info For LCS"},
267 { MAP_SUB_LOC_REP, "Subscriber Location Report"},
272 /* TCAP component type */
273 #define MAP_TC_INVOKE 0xa1
274 #define MAP_TC_RRL 0xa2
275 #define MAP_TC_RE 0xa3
276 #define MAP_TC_REJECT 0xa4
277 #define MAP_TC_RRN 0xa7
279 static const value_string tag_strings[] = {
280 { MAP_TC_INVOKE, "Invoke" },
281 { MAP_TC_RRL, "RetRes(Last)" },
282 { MAP_TC_RE, "RetErr" },
283 { MAP_TC_REJECT, "Reject" },
284 { MAP_TC_RRN, "RetRes(Not Last)" },
288 /* Initialize the protocol and registered fields */
289 static int proto_map = -1;
290 static int hf_map_tag = -1;
291 static int hf_map_length = -1;
292 static int hf_map_opr_code = -1;
293 static int hf_map_int = -1;
295 /* Initialize the subtree pointers */
296 static gint ett_map = -1;
297 static gint ett_component = -1;
298 static gint ett_components = -1;
299 static gint ett_param = -1;
300 static gint ett_params = -1;
301 static gint ett_problem = -1;
302 static gint ett_opr_code = -1;
304 static const value_string param_1_strings[] = {
306 { 0x81, "msc-Number" },
311 typedef struct dgt_set_t
313 unsigned char out[15];
317 static dgt_set_t Dgt_tbcd = {
319 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
320 '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
324 static dgt_set_t Dgt_msid = {
326 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
327 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
335 * Unpack BCD input pattern into output ASCII pattern
337 * Input Pattern is supplied using the same format as the digits
339 * Returns: length of unpacked pattern
343 char *out, /* ASCII pattern out */
344 guchar *in, /* packed pattern in */
345 int num_octs, /* Number of octets to unpack */
346 dgt_set_t *dgt /* Digit definitions */
355 * unpack first value in byte
358 *out++ = dgt->out[i & 0x0f];
362 * unpack second value in byte
366 if (i == 0x0f) /* odd number bytes - hit filler */
369 *out++ = dgt->out[i];
380 my_match_strval(guint32 val, const value_string *vs, gint *idx)
384 while (vs[i].strptr) {
385 if (vs[i].value == val)
388 return(vs[i].strptr);
400 check_map_tag(ASN1_SCK *asn1, guint tag)
402 guint saved_offset, real_tag;
404 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
409 saved_offset = asn1->offset;
410 asn1_id_decode1(asn1, &real_tag);
411 asn1->offset = saved_offset;
413 return(tag == real_tag);
419 param_imsi(ASN1_SCK *asn1, proto_tree *tree, guint len)
425 saved_offset = asn1->offset;
426 asn1_string_value_decode(asn1, len, &poctets);
428 my_dgt_tbcd_unpack(bigbuf, poctets, len, &Dgt_msid);
430 proto_tree_add_text(tree, asn1->tvb,
431 saved_offset, len, "IMSI %s", bigbuf);
435 param_AddressString(ASN1_SCK *asn1, proto_tree *tree, guint len)
443 saved_offset = asn1->offset;
444 asn1_int32_value_decode(asn1, 1, &value);
446 other_decode_bitfield_value(bigbuf, value, 0x80, 8);
447 proto_tree_add_text(tree, asn1->tvb,
450 bigbuf, (value & 0x80) ? "No E" : "E");
452 switch ((value & 0x70) >> 4)
454 case 0x00: str = "unknown"; break;
455 case 0x01: str = "International Number"; break;
456 case 0x02: str = "National Significant Number"; break;
457 case 0x03: str = "Network Specific Number"; break;
458 case 0x04: str = "Subscriber Number"; break;
459 case 0x05: str = "Reserved"; break;
460 case 0x06: str = "Abbreviated Number"; break;
461 case 0x07: str = "Reserved for extension"; break;
464 other_decode_bitfield_value(bigbuf, value, 0x70, 8);
465 proto_tree_add_text(tree, asn1->tvb,
466 saved_offset, asn1->offset - saved_offset,
470 switch (value & 0x0f)
472 case 0x00: str = "unknown"; break;
473 case 0x01: str = "ISDN/Telephony Numbering (Rec ITU-T E.164)"; break;
474 case 0x02: str = "spare"; break;
475 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
476 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
477 case 0x05: str = "spare"; break;
478 case 0x06: str = "Land Mobile Numbering (ITU-T Rec. E.212)"; break;
479 case 0x07: str = "spare"; break;
480 case 0x08: str = "National Numbering"; break;
481 case 0x09: str = "Private Numbering"; break;
482 case 0x0f: str = "Reserved for extension"; break;
488 other_decode_bitfield_value(bigbuf, value, 0x0f, 8);
489 proto_tree_add_text(tree, asn1->tvb,
490 saved_offset, asn1->offset - saved_offset,
494 saved_offset = asn1->offset;
495 asn1_string_value_decode(asn1, len - 1, &poctets);
497 my_dgt_tbcd_unpack(bigbuf, poctets, len - 1, &Dgt_msid);
499 proto_tree_add_text(tree, asn1->tvb, saved_offset, len - 1,
500 "BCD Digits %s", bigbuf);
503 #define NUM_PARAM_1 (sizeof(param_1_strings)/sizeof(value_string))
504 static gint ett_param_1[NUM_PARAM_1];
505 static void (*param_1_fcn[])(ASN1_SCK *asn1, proto_tree *tree, guint len) = {
506 param_imsi, /* IMSI */
507 param_AddressString, /* msc-Number */
515 op_send_auth_info(ASN1_SCK *asn1, proto_tree *tree)
517 void (*param_fcn)(ASN1_SCK *asn1, proto_tree *tree, guint len) = NULL;
518 guint off_tree[100], saved_offset, len_offset;
521 gboolean def_len = FALSE;
522 proto_item *item_tree[100], *item;
523 proto_tree *seq_tree[100], *use_tree, *subtree;
525 gint ett_param_idx, idx;
530 while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
531 (!check_map_tag(asn1, 0)))
533 saved_offset = asn1->offset;
534 asn1_id_decode1(asn1, &tag);
535 len_offset = asn1->offset;
536 asn1_length_decode(asn1, &def_len, &len);
538 if (tag == MAP_SEQ_TAG)
541 proto_tree_add_text(use_tree, asn1->tvb,
542 saved_offset, -1, "Sequence");
544 subtree = proto_item_add_subtree(item, ett_params);
546 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
547 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
551 proto_tree_add_text(subtree, asn1->tvb,
552 len_offset, asn1->offset - len_offset, "Length: Indefinite");
554 seq_tree[num_seq] = subtree;
555 item_tree[num_seq] = item;
556 off_tree[num_seq] = saved_offset;
561 proto_tree_add_uint(subtree, hf_map_length, asn1->tvb,
562 len_offset, asn1->offset - len_offset, len);
564 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
573 proto_tree_add_uint_format(use_tree, hf_map_tag, asn1->tvb,
574 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
575 proto_tree_add_text(use_tree, asn1->tvb,
576 len_offset, asn1->offset - len_offset, "Length: Indefinite");
578 seq_tree[num_seq] = use_tree;
579 item_tree[num_seq] = NULL;
588 * how do you recognize the correct parameters here ?
590 str = my_match_strval((guint32) tag, param_1_strings, &idx);
599 ett_param_idx = ett_param;
604 ett_param_idx = ett_param_1[idx];
605 param_fcn = param_1_fcn[idx];
609 proto_tree_add_text(use_tree, asn1->tvb,
610 saved_offset, -1, str);
612 subtree = proto_item_add_subtree(item, ett_param_idx);
614 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
615 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
617 proto_tree_add_uint(subtree, hf_map_length, asn1->tvb,
618 len_offset, asn1->offset - len_offset, len);
620 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
622 if (param_fcn == NULL)
624 proto_tree_add_text(subtree, asn1->tvb,
625 asn1->offset, len, "Parameter Data");
631 (*param_fcn)(asn1, subtree, len);
635 if (tvb_length_remaining(asn1->tvb, asn1->offset) <=0) break;
637 while ((num_seq > 0) &&
640 saved_offset = asn1->offset;
641 asn1_eoc_decode(asn1, -1);
643 proto_tree_add_text(seq_tree[num_seq-1], asn1->tvb,
644 saved_offset, asn1->offset - saved_offset, "End of Contents");
646 if (item_tree[num_seq-1] != NULL)
648 proto_item_set_len(item_tree[num_seq-1], asn1->offset - off_tree[num_seq-1]);
656 #define GSM_MAP_NUM_OP (sizeof(opr_code_strings)/sizeof(value_string))
657 static gint ett_op[GSM_MAP_NUM_OP];
658 static void (*op_fcn[])(ASN1_SCK *asn1, proto_tree *tree) = {
659 NULL, /* Update Location */
660 NULL, /* Cancel Location */
662 NULL, /* Send Identification */
663 NULL, /* Update GPRS Location */
664 NULL, /* Detach IMSI */
665 NULL, /* Note MM Event */
666 NULL, /* Prepare Handover */
667 NULL, /* Prepare Subsequent Handover */
668 NULL, /* Perform Handover */
669 NULL, /* Perform Subsequent Handover */
670 NULL, /* Send End Signal */
671 NULL, /* Process Access Signalling */
672 NULL, /* Forward Access Signalling */
673 op_send_auth_info, /* Send Authentication Info */
674 NULL, /* Authentication Failure Report */
675 NULL, /* Check IMEI */
677 NULL, /* Restore Data */
678 NULL, /* Forward Check SS Indication */
679 NULL, /* Activate Trace Mode */
680 NULL, /* Deactivate Trace Mode */
681 NULL, /* Send IMSI */
682 NULL, /* Trace Subscriber Activity */
683 NULL, /* Note Internal Handover */
684 NULL, /* Send Routing Info */
685 NULL, /* Provide Roaming Number */
686 NULL, /* Provide SIWFS Number */
687 NULL, /* SIWFS Signalling Modify */
688 NULL, /* Resume Call Handling */
689 NULL, /* Set Reporting State */
690 NULL, /* Status Report */
691 NULL, /* Remote User Free */
692 NULL, /* Prepare Group Call */
693 NULL, /* Send Group Call End Signalling */
694 NULL, /* Process Group Call Signalling */
695 NULL, /* Forward Group Call Signalling */
696 NULL, /* IST Alert */
697 NULL, /* IST Command */
698 NULL, /* Register SS */
700 NULL, /* Activate SS */
701 NULL, /* Deactivate SS */
702 NULL, /* Interogate SS */
703 NULL, /* Process Unstructured SS Request */
704 NULL, /* Unstructured SS Request */
705 NULL, /* Unstructured SS Notify */
706 NULL, /* Register Password */
707 NULL, /* Get Password */
708 NULL, /* Register CC Entry */
709 NULL, /* Erase CC Entry */
710 NULL, /* Begin Subscriber Activity */
711 NULL, /* Process Unstructured SS Data */
712 NULL, /* SS Invocation Notification */
713 NULL, /* MO Forward SM */
714 NULL, /* MT Forward SM */
715 NULL, /* Send Routing Info For SM */
716 NULL, /* Report SM Delivery Status */
717 NULL, /* Inform Service Center */
718 NULL, /* Alert Service Center */
719 NULL, /* Ready For SM */
720 NULL, /* Note Subscriber Present */
721 NULL, /* Alert SC Without Result */
722 NULL, /* Insert Subscriber Data */
723 NULL, /* Delete Subscriber Data */
724 NULL, /* Provide Subscriber Info */
725 NULL, /* Any Time Interrogation */
726 NULL, /* Send Parameters */
727 NULL, /* Any Time Subscription Interrogation */
728 NULL, /* Any Time Modification */
729 NULL, /* Note Subscriber Data Modified */
730 NULL, /* Send Routing Info For GPRS */
731 NULL, /* Failure Report */
732 NULL, /* Note MS Present For GPRS */
733 NULL, /* Provide Subscriber Location */
734 NULL, /* Send Routing Info For LCS */
735 NULL, /* Subscriber Location Report */
741 /* GENERIC MAP DISSECTOR FUNCTIONS */
744 dissect_map_tag(ASN1_SCK *asn1, proto_tree *tree, guint *tag, guchar * str,
747 guint saved_offset, real_tag;
749 saved_offset = asn1->offset;
750 asn1_id_decode1(asn1, &real_tag);
751 if ((*tag != (guint) -1) && (real_tag != *tag))
753 asn1->offset = saved_offset;
758 proto_tree_add_uint_format(tree, hf_map_tag, asn1->tvb,
759 saved_offset, asn1->offset - saved_offset,
767 dissect_map_len(ASN1_SCK *asn1, proto_tree *tree, gboolean *def_len, guint *len)
771 saved_offset = asn1->offset;
774 asn1_length_decode(asn1, def_len, len);
778 proto_tree_add_uint(tree, hf_map_length, asn1->tvb, saved_offset,
779 asn1->offset - saved_offset, *len);
783 proto_tree_add_text(tree, asn1->tvb,
784 saved_offset, asn1->offset - saved_offset, "Length: Indefinite");
792 dissect_map_integer(ASN1_SCK *asn1, proto_tree *tree, guint len, guchar * str)
797 saved_offset = asn1->offset;
798 asn1_int32_value_decode(asn1, len, &invokeId);
800 proto_tree_add_int_format(tree, hf_map_int, asn1->tvb,
801 saved_offset, asn1->offset - saved_offset,
802 invokeId, "%s %d", str, invokeId);
809 dissect_map_invokeId(ASN1_SCK *asn1, proto_tree *tree)
811 guint saved_offset = 0;
814 proto_item *item, *null_item;
818 if (check_map_tag(asn1, MAP_INVOKE_ID_TAG))
820 saved_offset = asn1->offset;
822 proto_tree_add_text(tree, asn1->tvb,
823 saved_offset, -1, "Invoke Id");
825 subtree = proto_item_add_subtree(item, ett_component);
828 dissect_map_tag(asn1, subtree, &tag, "Invoke Id Tag", &null_item);
829 dissect_map_len(asn1, subtree, &def_len, &len);
830 dissect_map_integer(asn1, subtree, len, "Invoke Id:");
832 proto_item_set_len(item, asn1->offset - saved_offset);
840 dissect_map_problem(ASN1_SCK *asn1, proto_tree *tree)
842 guint orig_offset, saved_offset = 0;
846 proto_item *item = NULL;
848 gchar *type_str = NULL;
852 orig_offset = asn1->offset;
853 saved_offset = asn1->offset;
854 asn1_id_decode1(asn1, &tag);
855 tag_len = asn1->offset - saved_offset;
858 proto_tree_add_text(tree, asn1->tvb,
859 saved_offset, -1, "Problem Code");
861 subtree = proto_item_add_subtree(item, ett_problem);
863 dissect_map_len(asn1, subtree, &def_len, &len);
864 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
868 proto_tree_add_text(subtree, asn1->tvb,
869 asn1->offset, len, "Unknown encoding of Problem Code");
875 saved_offset = asn1->offset;
876 asn1_int32_value_decode(asn1, 1, &spec);
880 case MAP_GE_PROBLEM_TAG:
881 type_str = "General Problem";
884 case 0: str = "Unrecognized Component"; break;
885 case 1: str = "Mistyped Component"; break;
886 case 2: str = "Badly Structured Component"; break;
893 case MAP_IN_PROBLEM_TAG:
897 case 0: str = "Duplicate Invoke ID"; break;
898 case 1: str = "Unrecognized Operation"; break;
899 case 2: str = "Mistyped Parameter"; break;
900 case 3: str = "Resource Limitation"; break;
901 case 4: str = "Initiating Release"; break;
902 case 5: str = "Unrecognized Linked ID"; break;
903 case 6: str = "Linked Response Unexpected"; break;
904 case 7: str = "Unexpected Linked Operation"; break;
911 case MAP_RR_PROBLEM_TAG:
912 type_str = "Return Result";
915 case 0: str = "Unrecognized Invoke ID"; break;
916 case 1: str = "Return Result Unexpected"; break;
917 case 2: str = "Mistyped Parameter"; break;
924 case MAP_RE_PROBLEM_TAG:
925 type_str = "Return Error";
928 case 0: str = "Unrecognized Invoke ID"; break;
929 case 1: str = "Return Error Unexpected"; break;
930 case 2: str = "Unrecognized Error"; break;
931 case 3: str = "Unexpected Error"; break;
932 case 4: str = "Mistyped Parameter"; break;
940 type_str = "Undefined";
944 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
945 orig_offset, tag_len, tag, type_str);
947 proto_tree_add_text(subtree, asn1->tvb,
948 saved_offset, 1, "Problem Specifier %s", str);
953 dissect_map_lnkId(ASN1_SCK *asn1, proto_tree *tree)
955 guint saved_offset = 0;
958 proto_item *item, *null_item;
962 if (check_map_tag(asn1, MAP_LINK_ID_TAG))
964 saved_offset = asn1->offset;
966 proto_tree_add_text(tree, asn1->tvb,
967 saved_offset, -1, "Linked Id");
969 subtree = proto_item_add_subtree(item, ett_component);
972 dissect_map_tag(asn1, tree, &tag, "Linked Id Tag", &null_item);
973 dissect_map_len(asn1, tree, &def_len, &len);
974 dissect_map_integer(asn1, tree, len, "Linked Id:");
976 proto_item_set_len(item, asn1->offset - saved_offset);
984 dissect_map_opr_code(ASN1_SCK *asn1, packet_info *pinfo, proto_tree *tree, gint *op_idx_p)
986 guint saved_offset = 0;
995 if (check_map_tag(asn1, MAP_OPR_CODE_TAG))
998 dissect_map_tag(asn1, tree, &tag, "Operation Code", &item);
999 subtree = proto_item_add_subtree(item, ett_opr_code);
1000 dissect_map_len(asn1, subtree, &def_len, &len);
1002 saved_offset = asn1->offset;
1003 asn1_int32_value_decode(asn1, len, &val);
1004 proto_tree_add_int(subtree, hf_map_opr_code, asn1->tvb, saved_offset,
1005 asn1->offset - saved_offset, val);
1007 str = my_match_strval(val, opr_code_strings, op_idx_p);
1009 if (NULL == str) return(MAP_FAIL);
1011 if (check_col(pinfo->cinfo, COL_INFO))
1013 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
1022 dissect_map_params(ASN1_SCK *asn1, proto_tree *tree)
1024 guint off_tree[100], saved_offset, len_offset;
1027 gboolean def_len = FALSE;
1028 proto_item *item_tree[100], *item;
1029 proto_tree *seq_tree[100], *use_tree, *subtree;
1034 while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
1035 (!check_map_tag(asn1, 0)))
1037 saved_offset = asn1->offset;
1038 asn1_id_decode1(asn1, &tag);
1039 len_offset = asn1->offset;
1040 asn1_length_decode(asn1, &def_len, &len);
1042 if (tag == MAP_SEQ_TAG)
1045 proto_tree_add_text(use_tree, asn1->tvb,
1046 saved_offset, -1, "Sequence");
1048 subtree = proto_item_add_subtree(item, ett_params);
1050 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
1051 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
1055 proto_tree_add_text(subtree, asn1->tvb,
1056 len_offset, asn1->offset - len_offset, "Length: Indefinite");
1058 seq_tree[num_seq] = subtree;
1059 item_tree[num_seq] = item;
1060 off_tree[num_seq] = saved_offset;
1065 proto_tree_add_uint(subtree, hf_map_length, asn1->tvb,
1066 len_offset, asn1->offset - len_offset, len);
1068 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
1077 proto_tree_add_uint_format(use_tree, hf_map_tag, asn1->tvb,
1078 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
1079 proto_tree_add_text(use_tree, asn1->tvb,
1080 len_offset, asn1->offset - len_offset, "Length: Indefinite");
1082 seq_tree[num_seq] = use_tree;
1083 item_tree[num_seq] = NULL;
1090 proto_tree_add_text(use_tree, asn1->tvb,
1091 saved_offset, -1, "Parameter");
1093 subtree = proto_item_add_subtree(item, ett_param);
1095 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
1096 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
1098 proto_tree_add_uint(subtree, hf_map_length, asn1->tvb,
1099 len_offset, asn1->offset - len_offset, len);
1101 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
1103 proto_tree_add_text(subtree, asn1->tvb,
1104 asn1->offset, len, "Parameter Data");
1106 asn1->offset += len;
1109 if (tvb_length_remaining(asn1->tvb, asn1->offset) <=0) break;
1111 while ((num_seq > 0) &&
1114 saved_offset = asn1->offset;
1115 asn1_eoc_decode(asn1, -1);
1117 proto_tree_add_text(seq_tree[num_seq-1], asn1->tvb,
1118 saved_offset, asn1->offset - saved_offset, "End of Contents");
1120 if (item_tree[num_seq-1] != NULL)
1122 proto_item_set_len(item_tree[num_seq-1], asn1->offset - off_tree[num_seq-1]);
1134 dissect_map_eoc(ASN1_SCK *asn1, proto_tree *tree)
1138 saved_offset = asn1->offset;
1140 if (tvb_length_remaining(asn1->tvb, saved_offset) <= 0)
1145 if (!asn1_eoc(asn1, -1))
1150 asn1_eoc_decode(asn1, -1);
1152 proto_tree_add_text(tree, asn1->tvb,
1153 saved_offset, asn1->offset - saved_offset, "End of Contents");
1160 dissect_map_invoke(ASN1_SCK *asn1, packet_info *pinfo, proto_tree *tree)
1162 proto_tree *subtree;
1163 guint saved_offset = 0;
1171 saved_offset = asn1->offset;
1172 ret = asn1_id_decode1(asn1, &tag);
1173 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Components");
1174 subtree = proto_item_add_subtree(item, ett_components);
1175 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1176 tag, "Invoke Type Tag");
1178 dissect_map_len(asn1, subtree, &def_len, &len);
1182 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
1185 dissect_map_invokeId(asn1, subtree);
1187 dissect_map_lnkId(asn1, subtree);
1189 if (dissect_map_opr_code(asn1, pinfo, subtree, &op_idx) == MAP_OK)
1194 if (op_fcn[op_idx] == NULL)
1196 dissect_map_params(asn1, subtree);
1200 (*op_fcn[op_idx])(asn1, subtree);
1206 dissect_map_eoc(asn1, subtree);
1212 dissect_map_rr(ASN1_SCK *asn1, packet_info *pinfo, proto_tree *tree, gchar *str)
1214 guint tag, len, comp_len;
1217 proto_item *item, *null_item;
1218 proto_tree *subtree;
1220 gboolean comp_def_len;
1223 saved_offset = asn1->offset;
1224 asn1_id_decode1(asn1, &tag);
1226 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Components");
1228 subtree = proto_item_add_subtree(item, ett_components);
1230 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb,
1231 saved_offset, asn1->offset - saved_offset, tag, str);
1233 dissect_map_len(asn1, subtree, &comp_def_len, &comp_len);
1237 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1240 dissect_map_invokeId(asn1, subtree);
1242 if (check_map_tag(asn1, MAP_SEQ_TAG))
1245 dissect_map_tag(asn1, subtree, &tag, "Sequence Tag", &null_item);
1246 dissect_map_len(asn1, subtree, &def_len, &len);
1249 if (dissect_map_opr_code(asn1, pinfo, subtree, &op_idx) == MAP_OK)
1251 dissect_map_params(asn1, subtree);
1256 dissect_map_eoc(asn1, subtree);
1262 dissect_map_re(ASN1_SCK *asn1, proto_tree *tree)
1264 guint tag, len, comp_len;
1266 proto_item *item, *null_item;
1267 proto_tree *subtree;
1271 saved_offset = asn1->offset;
1272 asn1_id_decode1(asn1, &tag);
1274 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Components");
1276 subtree = proto_item_add_subtree(item, ett_components);
1278 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1279 tag, "Return Error Type Tag");
1281 dissect_map_len(asn1, subtree, &def_len, &comp_len);
1285 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1288 saved_offset = asn1->offset;
1289 dissect_map_invokeId(asn1, subtree);
1291 #define MAP_LOCAL_ERR_CODE_TAG 0x2
1292 #define MAP_GBL_ERR_CODE_TAG 0x6
1293 if (check_map_tag(asn1, MAP_LOCAL_ERR_CODE_TAG))
1296 dissect_map_tag(asn1, subtree, &tag, "Local Error Code Tag", &null_item);
1298 else if (check_map_tag(asn1, MAP_GBL_ERR_CODE_TAG))
1301 dissect_map_tag(asn1, subtree, &tag, "Global Error Code Tag", &null_item);
1305 proto_tree_add_text(subtree, asn1->tvb, asn1->offset, comp_len,
1306 "Unknown Error Code");
1308 asn1->offset += (comp_len - (asn1->offset - saved_offset));
1312 dissect_map_len(asn1, subtree, &def_len, &len);
1313 dissect_map_integer(asn1, subtree, len, "Error Code:");
1315 dissect_map_params(asn1, subtree);
1319 dissect_map_eoc(asn1, subtree);
1327 dissect_map_reject(ASN1_SCK *asn1, proto_tree *tree)
1332 proto_tree *subtree;
1337 saved_offset = asn1->offset;
1338 asn1_id_decode1(asn1, &tag);
1340 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Components");
1342 subtree = proto_item_add_subtree(item, ett_components);
1344 proto_tree_add_uint_format(subtree, hf_map_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1345 tag, "Reject Type Tag");
1347 dissect_map_len(asn1, subtree, &def_len, &len);
1351 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
1354 dissect_map_invokeId(asn1, subtree);
1355 dissect_map_problem(asn1, subtree);
1359 dissect_map_eoc(asn1, subtree);
1365 dissect_map_message(packet_info *pinfo, proto_tree *map_tree, ASN1_SCK *asn1)
1372 saved_offset = asn1->offset;
1373 asn1_id_decode1(asn1, &tag);
1374 asn1->offset = saved_offset;
1376 str = match_strval(tag, tag_strings);
1378 if (NULL == str) return;
1380 if (check_col(pinfo->cinfo, COL_INFO))
1384 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
1388 col_append_fstr(pinfo->cinfo, COL_INFO, "& %s ", str);
1394 case MAP_TC_INVOKE :
1395 dissect_map_invoke(asn1, pinfo, map_tree);
1399 dissect_map_rr(asn1, pinfo, map_tree, "Return Result(Last) Type Tag");
1403 dissect_map_re(asn1, map_tree);
1406 case MAP_TC_REJECT :
1407 dissect_map_reject(asn1, map_tree);
1411 dissect_map_rr(asn1, pinfo, map_tree, "Return Result(Not Last) Type Tag");
1415 proto_tree_add_text(map_tree, asn1->tvb, saved_offset, -1,
1416 "Message type not handled, ignoring");
1423 dissect_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1426 proto_tree *map_tree;
1431 * Make entries in Protocol column on summary display
1433 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1435 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSM MAP");
1439 /* In the interest of speed, if "tree" is NULL, don't do any work not
1440 * necessary to generate protocol tree items.
1444 /* create display subtree for the protocol */
1445 ti = proto_tree_add_item(tree, proto_map, tvb, 0, -1, FALSE);
1447 map_tree = proto_item_add_subtree(ti, ett_map);
1449 asn1_open(&asn1, tvb, offset);
1451 dissect_map_message(pinfo, map_tree, &asn1);
1453 asn1_close(&asn1, &offset);
1458 /* Register the protocol with Ethereal */
1461 proto_register_map(void)
1466 /* Setup list of header fields See Section 1.6.1 for details*/
1467 static hf_register_info hf[] =
1470 { "Tag", "map.msgtype",
1471 FT_UINT8, BASE_HEX, NULL, 0,
1475 { "Length", "map.len",
1476 FT_UINT8, BASE_HEX, NULL, 0,
1480 { "Operation Code", "map.oprcode",
1481 FT_INT32, BASE_DEC, VALS(opr_code_strings), 0,
1485 { "Integer Data", "map.data",
1486 FT_INT32, BASE_DEC, 0, 0,
1491 /* Setup protocol subtree array */
1492 #define NUM_INDIVIDUAL_PARAMS 7
1493 static gint *ett[NUM_INDIVIDUAL_PARAMS+GSM_MAP_NUM_OP+NUM_PARAM_1];
1495 memset((void *) ett, 0, sizeof(ett));
1498 ett[1] = &ett_opr_code;
1499 ett[2] = &ett_component;
1500 ett[3] = &ett_components;
1501 ett[4] = &ett_param;
1502 ett[5] = &ett_params;
1503 ett[6] = &ett_problem;
1505 last_offset = NUM_INDIVIDUAL_PARAMS;
1507 for (i=0; i < GSM_MAP_NUM_OP; i++, last_offset++)
1510 ett[last_offset] = &ett_op[i];
1513 for (i=0; i < NUM_PARAM_1; i++, last_offset++)
1515 ett_param_1[i] = -1;
1516 ett[last_offset] = &ett_param_1[i];
1519 /* Register the protocol name and description */
1521 proto_register_protocol("GSM Mobile Application Part",
1522 "GSM MAP", "gsm_map");
1524 /* Required function calls to register the header fields and subtrees used */
1525 proto_register_field_array(proto_map, hf, array_length(hf));
1526 proto_register_subtree_array(ett, array_length(ett));
1530 proto_reg_handoff_map(void)
1532 dissector_handle_t map_handle;
1534 map_handle = create_dissector_handle(dissect_map, proto_map);
1535 dissector_add("tcap.itu_ssn", 6, map_handle);
1536 dissector_add("tcap.itu_ssn", 7, map_handle);
1537 dissector_add("tcap.itu_ssn", 8, map_handle);
1538 dissector_add("tcap.itu_ssn", 9, map_handle);