1 /* packet-inap-template.c
3 * Copyright 2004, Tim Endean <endeant@hotmail.com>
4 * Built from the gsm-map dissector Copyright 2004, Anders Broman <anders.broman@ericsson.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * References: ETSI 300 374
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
35 #include <epan/conversation.h>
40 #include "packet-ber.h"
41 #include "packet-inap.h"
42 #include "packet-q931.h"
43 #include "packet-e164.h"
44 #include "packet-isup.h"
45 #include "packet-tcap.h"
47 #define PNAME "Intelligent Network Application Protocol"
51 /* Initialize the protocol and registered fields */
53 static int hf_inap_invokeCmd = -1; /* Opcode */
54 static int hf_inap_invokeid = -1; /* INTEGER */
55 static int hf_inap_linkedid = -1; /* INTEGER */
56 static int hf_inap_absent = -1; /* NULL */
57 static int hf_inap_invokeId = -1; /* InvokeId */
58 static int hf_inap_invoke = -1; /* InvokePDU */
59 static int hf_inap_ReturnError = -1; /* InvokePDU */
60 static int hf_inap_returnResult = -1; /* InvokePDU */
61 static int hf_inap_returnResult_result = -1;
62 static int hf_inap_getPassword = -1;
63 static int hf_inap_currentPassword = -1;
64 static int hf_inap_genproblem = -1;
65 #include "packet-inap-hf.c"
68 static range_t *global_ssn_range;
69 static range_t *ssn_range;
71 static dissector_handle_t inap_handle;
73 /* Initialize the subtree pointers */
74 static gint ett_inap = -1;
75 static gint ett_inap_InvokeId = -1;
76 static gint ett_inap_InvokePDU = -1;
77 static gint ett_inap_ReturnErrorPDU = -1;
78 static gint ett_inap_ReturnResultPDU = -1;
79 static gint ett_inap_ReturnResult_result = -1;
80 static gint ett_inap_INAPPDU = -1;
81 static gint ett_inapisup_parameter = -1;
82 #include "packet-inap-ett.c"
84 static int dissect_invokeCmd(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
86 #include "packet-inap-fn.c"
89 const value_string inap_opr_code_strings[] = {
92 {1, "OriginationAttemptAuthorized"},
93 {2, "CollectedInformation"},
94 {3, "AnalysedInformation"},
95 {4, "RouteSelectFailure"},
96 {5, "oCalledPartyBusy"},
100 {9, "TermAttemptAuthorized"},
107 {16, "AssistRequestInstructions"},
108 {17,"EstablishTemporaryConnection"},
109 {18, "DisconnectForwardConnection"},
110 {19,"ConnectToResource"},
112 {21,"HoldCallInNetwork"},
114 {23, "RequestReportBCSMEven"},
115 {23,"RequestReportBCSMEvent"},
116 {24,"EventReportBCSM"},
117 {25, "RequestNotificationChargingEvent"},
118 {26, "EventNotificationCharging"},
119 {27, "CollectInformation"},
120 {28, "AnalyseInformation"},
122 {30, "SelectFacility"},
124 {32, "InitiateCallAttempt"},
126 {34,"FurnishChargingInformation"},
127 {35, "ApplyCharging"},
128 {36, "ApplyChargingReport"},
129 {37, "RequestCurrentStatusReport"},
130 {38, "RequestEveryStatusChangeReport"},
131 {39, "RequestFirstStatusMatchReport"},
132 {40, "StatusReport"},
134 {42, "ActivateServiceFiltering"},
135 {43, "ServiceFilteringResponse"},
136 {44, "CallInformationReport"},
137 {45, "CallInformationRequest"},
138 {46, "SendChargingInformation"},
139 {47,"PlayAnnouncement"},
140 {48,"PromptAndCollectUserInformation"},
141 {49,"SpecializedResourceReport"},
143 {55, "ActivityTest"},
144 {99,"ReceivedInformation"}, /*???????*/
148 const value_string inap_error_code_strings[] = {
153 {4,"improperCallerResponse"},
154 {6,"missingCustomerRecord"},
155 {7,"missingParameter"},
156 {8,"parameterOutOfRange"},
157 {10,"RequestedInfoError"},
158 {11,"SystemFailure"},
160 {13,"UnavailableResource"},
161 {14,"UnexpectedComponentSequence"},
162 {15,"UnexpectedDataValue"},
163 {16,"UnexpectedParameter"},
165 {18,"UnknownResource"},
169 const value_string inap_general_problem_strings[] = {
170 {0,"General Problem Unrecognized Component"},
171 {1,"General Problem Mistyped Component"},
172 {3,"General Problem Badly Structured Component"},
178 static guint32 opcode=0;
181 dissect_inap_Opcode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
182 offset = dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_index, &opcode);
184 if (check_col(pinfo->cinfo, COL_INFO)){
185 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(opcode, inap_opr_code_strings, "Unknown Inap (%u)"));
194 dissect_inap_errorCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
195 offset = dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_index, &opcode);
197 if (check_col(pinfo->cinfo, COL_INFO)){
198 col_set_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, inap_error_code_strings, "Unknown Inap (%u)"));
205 TC-Invokable OPERATION ::=
206 {activateServiceFiltering | activityTest | analysedInformation |
207 analyseInformation | applyCharging | applyChargingReport |
208 assistRequestInstructions | callGap | callInformationReport |
209 callInformationRequest | cancel | cancelStatusReportRequest |
210 collectedInformation | collectInformation | connect | connectToResource |
211 continue | disconnectForwardConnection | establishTemporaryConnection |
212 eventNotificationCharging | eventReportBCSM | furnishChargingInformation |
213 holdCallInNetwork | initialDP | initiateCallAttempt | oAnswer |
214 oCalledPartyBusy | oDisconnect | oMidCall | oNoAnswer |
215 originationAttemptAuthorized | releaseCall | requestCurrentStatusReport |
216 requestEveryStatusChangeReport | requestFirstStatusMatchReport |
217 requestNotificationChargingEvent | requestReportBCSMEvent | resetTimer |
218 routeSelectFailure | selectFacility | selectRoute | sendChargingInformation
219 | serviceFilteringResponse | statusReport | tAnswer | tBusy | tDisconnect |
220 termAttemptAuthorized | tMidCall | tNoAnswer | playAnnouncement |
221 promptAndCollectUserInformation}
224 static int dissect_invokeData(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
226 case 0: /*InitialDP*/
227 offset=dissect_inap_InitialDP(FALSE, tvb, offset, pinfo, tree, hf_inap_InitialDP_PDU);
229 case 1: /*1 OriginationAttemptAuthorized */
230 offset=dissect_inap_OriginationAttemptAuthorizedArg(FALSE, tvb, offset, pinfo, tree, hf_inap_OriginationAttemptAuthorizedArg_PDU);
232 case 2: /*2 CollectedInformation */
233 offset=dissect_inap_CollectedInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CollectedInformationArg_PDU);
235 case 3: /*3 AnalysedInformation */
236 offset=dissect_inap_AnalysedInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_AnalysedInformationArg_PDU);
238 case 4: /*4 RouteSelectFailure */
239 offset=dissect_inap_RouteSelectFailureArg(FALSE, tvb, offset, pinfo, tree, hf_inap_RouteSelectFailureArg_PDU);
241 case 5: /*5 oCalledPartyBusy */
242 offset=dissect_inap_OCalledPartyBusyArg(FALSE, tvb, offset, pinfo, tree, hf_inap_OCalledPartyBusyArg_PDU);
244 case 6: /*6 oNoAnswer */
245 offset=dissect_inap_ONoAnswer(FALSE, tvb, offset, pinfo, tree, hf_inap_ONoAnswer_PDU);
247 case 7: /*7 oAnswer */
248 offset=dissect_inap_OAnswerArg(FALSE, tvb, offset, pinfo, tree, hf_inap_OAnswerArg_PDU);
250 case 8: /*8 oDisconnect */
251 offset=dissect_inap_ODisconnectArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ODisconnectArg_PDU);
253 case 9: /*9 TermAttemptAuthorized */
254 offset=dissect_inap_TermAttemptAuthorizedArg(FALSE, tvb, offset, pinfo, tree, hf_inap_TermAttemptAuthorizedArg_PDU);
256 case 10: /*10 tBusy */
257 offset=dissect_inap_TBusyArg(FALSE, tvb, offset, pinfo, tree, hf_inap_TBusyArg_PDU);
259 case 11: /*11 tNoAnswer */
260 offset=dissect_inap_TNoAnswerArg(FALSE, tvb, offset, pinfo, tree, hf_inap_TNoAnswerArg_PDU);
262 case 12: /*12 tAnswer */
263 offset=dissect_inap_TAnswerArg(FALSE, tvb, offset, pinfo, tree, hf_inap_TAnswerArg_PDU);
265 case 13: /*13 tDisconnect */
266 offset=dissect_inap_TDisconnectArg(FALSE, tvb, offset, pinfo, tree, hf_inap_TDisconnectArg_PDU);
268 case 14: /*14 oMidCall */
269 offset=dissect_inap_MidCallArg(FALSE, tvb, offset, pinfo, tree, hf_inap_MidCallArg_PDU);
271 case 15: /*15 tMidCall */
272 offset=dissect_inap_MidCallArg(FALSE, tvb, offset, pinfo, tree, hf_inap_MidCallArg_PDU);
274 case 16: /*AssistRequestInstructions*/
275 offset=dissect_inap_AssistRequestInstructionsArg(FALSE, tvb, offset, pinfo, tree, hf_inap_AssistRequestInstructionsArg_PDU);
277 case 17: /*EstablishTemporaryConnection*/
278 offset=dissect_inap_EstablishTemporaryConnectionArg(FALSE, tvb, offset, pinfo, tree, hf_inap_EstablishTemporaryConnectionArg_PDU);
280 case 18: /*DisconnectForwardConnections*/
281 proto_tree_add_text(tree, tvb, offset, -1, "Disconnect Forward Connection");
283 case 19: /*ConnectToResource*/
284 offset=dissect_inap_ConnectToResourceArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ConnectToResourceArg_PDU);
287 offset=dissect_inap_ConnectArg(FALSE, tvb, offset, pinfo, tree,hf_inap_ConnectArg_PDU);
289 case 21: /* 21 HoldCallInNetwork */
290 offset=dissect_inap_HoldCallInNetworkArg(FALSE, tvb, offset, pinfo, tree,hf_inap_HoldCallInNetworkArg_PDU);
293 case 22: /*ReleaseCall*/
294 offset=dissect_inap_ReleaseCallArg(FALSE, tvb, offset, pinfo, tree,hf_inap_ReleaseCallArg_PDU);
296 case 23: /*InitialDP*/
297 offset=dissect_inap_RequestReportBCSMEventArg(FALSE, tvb, offset, pinfo, tree, hf_inap_RequestReportBCSMEventArg_PDU);
299 case 24: /*EventReportBCSM*/
300 offset=dissect_inap_EventReportBCSMArg(FALSE, tvb, offset, pinfo, tree, hf_inap_EventReportBCSMArg_PDU);
302 case 25: /*25, "RequestNotificationChargingEvent */
303 offset=dissect_inap_RequestNotificationChargingEvent(FALSE, tvb, offset, pinfo, tree, hf_inap_RequestNotificationChargingEvent_PDU);
305 case 26: /*26, "EventNotificationCharging */
306 offset=dissect_inap_EventNotificationChargingArg(FALSE, tvb, offset, pinfo, tree, hf_inap_EventNotificationChargingArg_PDU);
308 case 27: /*27, "CollectInformation */
309 offset=dissect_inap_CollectInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CollectInformationArg_PDU);
311 case 28: /*28, "AnalyseInformation */
312 offset=dissect_inap_AnalyseInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_AnalyseInformationArg_PDU);
314 case 29: /*29, "SelectRoute */
315 offset=dissect_inap_SelectRouteArg(FALSE, tvb, offset, pinfo, tree, hf_inap_SelectRouteArg_PDU);
317 case 30: /*30, "SelectFacility */
318 offset=dissect_inap_SelectFacilityArg(FALSE, tvb, offset, pinfo, tree, hf_inap_SelectFacilityArg_PDU);
321 case 32: /*32, InitiateCallAttempt*/
322 offset=dissect_inap_InitiateCallAttemptArg(FALSE, tvb, offset, pinfo, tree, hf_inap_InitiateCallAttemptArg_PDU);
324 case 33: /*ResetTimer*/
325 offset=dissect_inap_ResetTimerArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ResetTimerArg_PDU);
327 case 34: /*FurnishChargingInformation*/
328 offset=dissect_inap_FurnishChargingInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_FurnishChargingInformationArg_PDU);
330 case 35: /*35, ApplyCharging */
331 offset=dissect_inap_ApplyChargingArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ApplyChargingArg_PDU);
333 case 36: /*36, "ApplyChargingReport */
334 offset=dissect_inap_ApplyChargingReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ApplyChargingReportArg_PDU);
336 case 37: /*37, "RequestCurrentStatusReport */
337 offset=dissect_inap_RequestCurrentStatusReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_RequestCurrentStatusReportArg_PDU);
339 case 38:/*38, "RequestEveryStatusChangeReport */
340 offset=dissect_inap_RequestEveryStatusChangeReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_RequestEveryStatusChangeReportArg_PDU);
342 case 39:/*39, "RequestFirstStatusMatchReport */
343 offset=dissect_inap_RequestFirstStatusMatchReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_RequestFirstStatusMatchReportArg_PDU);
345 case 40:/*40, "StatusReport */
346 offset=dissect_inap_StatusReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_StatusReportArg_PDU);
348 case 41:/*41, "CallGap */
349 offset=dissect_inap_CallGapArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CallGapArg_PDU);
351 case 42:/*42, "ActivateServiceFiltering */
352 offset=dissect_inap_ActivateServiceFilteringArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ActivateServiceFilteringArg_PDU);
354 case 43:/*43, "ServiceFilteringResponse */
355 offset=dissect_inap_ServiceFilteringResponseArg(FALSE, tvb, offset, pinfo, tree, hf_inap_ServiceFilteringResponseArg_PDU);
357 case 44: /*CallInformationReport*/
358 offset=dissect_inap_CallInformationReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CallInformationReportArg_PDU);
360 case 45: /*CallInformationRequest*/
361 offset=dissect_inap_CallInformationRequestArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CallInformationRequestArg_PDU);
363 case 47: /*PlayAnnouncement*/
364 offset=dissect_inap_PlayAnnouncementArg(FALSE, tvb, offset, pinfo, tree, hf_inap_PlayAnnouncementArg_PDU);
366 case 48: /*PromptAndCollectUserInformation*/
367 offset=dissect_inap_PromptAndCollectUserInformationArg(FALSE, tvb, offset, pinfo, tree, hf_inap_PromptAndCollectUserInformationArg_PDU);
369 case 49: /* 49 SpecializedResourceReport */
370 offset=dissect_inap_SpecializedResourceReportArg(FALSE, tvb, offset, pinfo, tree, hf_inap_SpecializedResourceReportArg_PDU);
373 offset=dissect_inap_CancelArg(FALSE, tvb, offset, pinfo, tree, hf_inap_CancelArg_PDU);
377 proto_tree_add_text(tree, tvb, offset, -1, "Unknown invokeData blob");
378 /* todo call the asn.1 dissector */
384 TC-Returnable OPERATION ::=
385 {activateServiceFiltering | activityTest | requestCurrentStatusReport |
386 requestEveryStatusChangeReport | requestFirstStatusMatchReport |
387 promptAndCollectUserInformation}
389 activateServiceFiltering - No arg
390 activityTest - No Arg
391 requestCurrentStatusReport - RESULT RequestCurrentStatusReportResultArg
392 requestEveryStatusChangeReport - No arg
393 requestFirstStatusMatchReport - No Arg
394 promptAndCollectUserInformation - RESULT ReceivedInformationArg
397 static int dissect_returnResultData(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
399 case 37: /*requestCurrentStatusReport*/
400 offset=dissect_inap_RequestCurrentStatusReportResultArg(FALSE, tvb, offset, pinfo, tree, -1);
402 case 48: /*PromptAndCollectUserInformation*/
403 offset=dissect_inap_ReceivedInformationArg(FALSE, tvb, offset, pinfo, tree, -1);
406 proto_tree_add_text(tree, tvb, offset, -1, "Unknown returnResultData blob");
412 dissect_invokeCmd(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
413 return dissect_inap_Opcode(FALSE, tvb, offset, pinfo, tree, hf_inap_invokeCmd);
418 dissect_errorCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
419 return dissect_inap_errorCode(FALSE, tvb, offset, pinfo, tree, hf_inap_ReturnError);
422 static int dissect_invokeid(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
423 return dissect_ber_integer(FALSE, pinfo, tree, tvb, offset, hf_inap_invokeid, NULL);
427 static const value_string InvokeId_vals[] = {
433 static int dissect_absent(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
434 return dissect_inap_NULL(FALSE, tvb, offset, pinfo, tree, hf_inap_absent);
438 static const ber_choice_t InvokeId_choice[] = {
439 { 0, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeid },
440 { 1, BER_CLASS_UNI, BER_UNI_TAG_NULL, BER_FLAGS_NOOWNTAG, dissect_absent },
445 dissect_inap_InvokeId(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
446 offset = dissect_ber_choice(pinfo, tree, tvb, offset,
447 InvokeId_choice, hf_index, ett_inap_InvokeId, NULL);
451 static int dissect_invokeId(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
452 return dissect_inap_InvokeId(FALSE, tvb, offset, pinfo, tree, hf_inap_invokeId);
454 static int dissect_linkedID_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
455 return dissect_ber_integer(TRUE, pinfo, tree, tvb, offset, hf_inap_linkedid, NULL);
459 static const ber_sequence_t InvokePDU_sequence[] = {
460 { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_invokeId },
461 { BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_linkedID_impl },
462 { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeCmd },
463 { BER_CLASS_UNI, -1/*depends on Cmd*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_invokeData },
468 dissect_inap_InvokePDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
469 offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
470 InvokePDU_sequence, hf_index, ett_inap_InvokePDU);
476 static const ber_sequence_t returnErrorPDU_sequence[] = {
477 { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_invokeId },
478 { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_errorCode },
483 dissect_inap_returnErrorPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
484 offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
485 returnErrorPDU_sequence, hf_index, ett_inap_ReturnErrorPDU);
491 static int dissect_invoke_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
492 return dissect_inap_InvokePDU(TRUE, tvb, offset, pinfo, tree, hf_inap_invoke);
495 static int dissect_returnError_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
496 return dissect_inap_returnErrorPDU(TRUE, tvb, offset, pinfo, tree, hf_inap_invoke);
499 static const ber_sequence_t ReturnResult_result_sequence[] = {
500 { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_invokeCmd },
501 { BER_CLASS_UNI, -1/*depends on Cmd*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_returnResultData },
505 dissect_returnResult_result(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
506 offset = dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset,
507 ReturnResult_result_sequence, hf_inap_returnResult_result, ett_inap_ReturnResult_result);
512 static const ber_sequence_t ReturnResultPDU_sequence[] = {
513 { BER_CLASS_UNI, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_invokeId },
514 { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_returnResult_result },
519 dissect_inap_returnResultPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
520 offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
521 ReturnResultPDU_sequence, hf_index, ett_inap_ReturnResultPDU);
525 static int dissect_returnResult_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
526 return dissect_inap_returnResultPDU(TRUE, tvb, offset, pinfo, tree, hf_inap_returnResult);
530 static int dissect_reject_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
531 return dissect_inap_RejectPDU(TRUE, tvb, offset, pinfo, tree, -1);
534 static const value_string INAPPDU_vals[] = {
536 { 2, "returnResult" },
537 { 3, "returnError" },
542 static const ber_choice_t INAPPDU_choice[] = {
543 { 1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_invoke_impl },
544 { 2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_returnResult_impl },
545 { 3, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_returnError_impl },
546 { 4, BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_reject_impl },
550 static guint8 inap_pdu_type = 0;
551 static guint8 inap_pdu_size = 0;
554 dissect_inap_INAPPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
556 inap_pdu_type = tvb_get_guint8(tvb, offset)&0x0f;
557 /* Get the length and add 2 */
558 inap_pdu_size = tvb_get_guint8(tvb, offset+1)+2;
560 offset = dissect_ber_choice(pinfo, tree, tvb, offset,
561 INAPPDU_choice, hf_index, ett_inap_INAPPDU, NULL);
563 if (check_col(pinfo->cinfo, COL_INFO)){
564 col_prepend_fstr(pinfo->cinfo, COL_INFO, val_to_str(opcode, inap_opr_code_strings, "Unknown INAP (%u)"));
574 dissect_inap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
576 proto_item *item=NULL;
577 proto_tree *tree=NULL;
580 if (check_col(pinfo->cinfo, COL_PROTOCOL))
582 col_set_str(pinfo->cinfo, COL_PROTOCOL, "INAP");
585 /* create display subtree for the protocol */
587 item = proto_tree_add_item(parent_tree, proto_inap, tvb, 0, -1, FALSE);
588 tree = proto_item_add_subtree(item, ett_inap);
591 dissect_inap_INAPPDU(FALSE, tvb, 0, pinfo, tree, -1);
596 /*--- proto_reg_handoff_inap ---------------------------------------*/
597 static void range_delete_callback(guint32 ssn)
600 delete_itu_tcap_subdissector(ssn, inap_handle);
604 static void range_add_callback(guint32 ssn)
607 add_itu_tcap_subdissector(ssn, inap_handle);
611 void proto_reg_handoff_inap(void) {
613 static int inap_prefs_initialized = FALSE;
615 inap_handle = create_dissector_handle(dissect_inap, proto_inap);
617 if (!inap_prefs_initialized) {
618 inap_prefs_initialized = TRUE;
621 range_foreach(ssn_range, range_delete_callback);
625 ssn_range = range_copy(global_ssn_range);
627 range_foreach(ssn_range, range_add_callback);
631 void proto_register_inap(void) {
632 module_t *inap_module;
634 static hf_register_info hf[] = {
635 { &hf_inap_invokeCmd,
636 { "invokeCmd", "inap.invokeCmd",
637 FT_UINT32, BASE_DEC, VALS(inap_opr_code_strings), 0,
638 "InvokePDU/invokeCmd", HFILL }},
639 { &hf_inap_ReturnError,
640 { "ReturnError", "inap.ReturnError",
641 FT_UINT32, BASE_DEC, VALS(inap_error_code_strings), 0,
642 "InvokePDU/ReturnError", HFILL }},
644 { "invokeid", "inap.invokeid",
645 FT_INT32, BASE_DEC, NULL, 0,
646 "InvokeId/invokeid", HFILL }},
648 { "linkedid", "inap.linkedid",
649 FT_INT32, BASE_DEC, NULL, 0,
650 "LinkedId/linkedid", HFILL }},
653 { "absent", "inap.absent",
654 FT_NONE, BASE_NONE, NULL, 0,
655 "InvokeId/absent", HFILL }},
657 { "invokeId", "inap.invokeId",
658 FT_UINT32, BASE_DEC, VALS(InvokeId_vals), 0,
659 "InvokePDU/invokeId", HFILL }},
661 { "invoke", "inap.invoke",
662 FT_NONE, BASE_NONE, NULL, 0,
663 "INAPPDU/invoke", HFILL }},
664 { &hf_inap_returnResult,
665 { "returnResult", "inap.returnResult",
666 FT_NONE, BASE_NONE, NULL, 0,
667 "INAPPDU/returnResult", HFILL }},
670 #include "packet-inap-hfarr.c"
678 /* List of subtrees */
679 static gint *ett[] = {
683 &ett_inap_ReturnErrorPDU,
684 &ett_inap_ReturnResultPDU,
685 &ett_inap_ReturnResult_result,
687 &ett_inapisup_parameter,
688 #include "packet-inap-ettarr.c"
691 /* Register protocol */
692 proto_inap = proto_register_protocol(PNAME, PSNAME, PFNAME);
693 /*XXX register_dissector("inap", dissect_inap, proto_inap);*/
694 /* Register fields and subtrees */
695 proto_register_field_array(proto_inap, hf, array_length(hf));
696 proto_register_subtree_array(ett, array_length(ett));
698 /* Set default SSNs */
699 range_convert_str(&global_ssn_range, "106,241", MAX_SSN);
700 ssn_range = range_empty();
702 inap_module = prefs_register_protocol(proto_inap, proto_reg_handoff_inap);
704 prefs_register_obsolete_preference(inap_module, "tcap.itu_ssn");
706 prefs_register_obsolete_preference(inap_module, "tcap.itu_ssn1");
708 prefs_register_range_preference(inap_module, "ssn", "TCAP SSNs",
709 "TCAP Subsystem numbers used for INAP",
710 &global_ssn_range, MAX_SSN);