PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/epan/dissectors/packet-megaco.c

https://github.com/labx-technologies-llc/wireshark
C | 3664 lines | 2589 code | 639 blank | 436 comment | 452 complexity | d1120d55ed35d3d68e137e2bcfb78ea8 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /* packet-megaco.c
  2. * Routines for megaco packet disassembly
  3. * RFC 3015
  4. *
  5. * $Id$
  6. *
  7. * Christian Falckenberg, 2002/10/17
  8. * Copyright (c) 2002 by Christian Falckenberg
  9. * <christian.falckenberg@nortelnetworks.com>
  10. *
  11. * Christoph Wiest, 2003/06/28
  12. * Modified 2003 by Christoph Wiest
  13. * <ch.wiest@tesionmail.de>
  14. * Modified 2004 by Anders Broman
  15. * <anders.broman@ericsson.com>
  16. * To handle TPKT headers if over TCP
  17. * Modified 2005 by Karl Knoebl
  18. * <karl.knoebl@siemens.com>
  19. * provide info to COL_INFO and some "prettification"
  20. *
  21. * Copyright (c) 2006 Anders Broman <anders.broman@ericsson.com>
  22. *
  23. * Wireshark - Network traffic analyzer
  24. * By Gerald Combs <gerald@wireshark.org>
  25. * Copyright 1999 Gerald Combs
  26. *
  27. * This program is free software; you can redistribute it and/or
  28. * modify it under the terms of the GNU General Public License
  29. * as published by the Free Software Foundation; either version 2
  30. * of the License, or (at your option) any later version.
  31. *
  32. * This program is distributed in the hope that it will be useful,
  33. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  34. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  35. * GNU General Public License for more details.
  36. *
  37. * You should have received a copy of the GNU General Public License
  38. * along with this program; if not, write to the Free Software
  39. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  40. */
  41. #include "config.h"
  42. #include <stdlib.h>
  43. #include <ctype.h>
  44. #include <glib.h>
  45. #include <epan/packet.h>
  46. #include <epan/wmem/wmem.h>
  47. #include <epan/addr_resolv.h>
  48. #include <epan/prefs.h>
  49. #include <epan/strutil.h>
  50. #include <epan/sctpppids.h>
  51. #include <epan/dissectors/packet-tpkt.h>
  52. #include <epan/asn1.h>
  53. #include <epan/dissectors/packet-per.h>
  54. #include <epan/dissectors/packet-h245.h>
  55. #include <epan/dissectors/packet-ip.h>
  56. #include <epan/dissectors/packet-ber.h>
  57. #include <epan/gcp.h>
  58. #include <epan/tap.h>
  59. #define PORT_MEGACO_TXT 2944
  60. #define PORT_MEGACO_BIN 2945
  61. /* Define the megaco proto */
  62. static int proto_megaco = -1;
  63. /* Define headers for megaco */
  64. static int hf_megaco_version = -1;
  65. static int hf_megaco_transaction = -1;
  66. static int hf_megaco_transid = -1;
  67. static int hf_megaco_Context = -1;
  68. /* static int hf_megaco_command_line = -1; */
  69. static int hf_megaco_command = -1;
  70. static int hf_megaco_termid = -1;
  71. /* Define headers in subtree for megaco */
  72. static int hf_megaco_modem_descriptor = -1;
  73. static int hf_megaco_multiplex_descriptor = -1;
  74. /* static int hf_megaco_media_descriptor = -1; */
  75. /* static int hf_megaco_events_descriptor = -1; */
  76. /* static int hf_megaco_signal_descriptor = -1; */
  77. static int hf_megaco_audit_descriptor = -1;
  78. /* static int hf_megaco_servicechange_descriptor = -1; */
  79. static int hf_megaco_digitmap_descriptor = -1;
  80. static int hf_megaco_statistics_descriptor = -1;
  81. /* static int hf_megaco_observedevents_descriptor = -1; */
  82. static int hf_megaco_topology_descriptor = -1;
  83. static int hf_megaco_error_descriptor = -1;
  84. /* static int hf_megaco_TerminationState_descriptor= -1; */
  85. /* static int hf_megaco_Remote_descriptor = -1; */
  86. /* static int hf_megaco_Local_descriptor = -1; */
  87. /* static int hf_megaco_LocalControl_descriptor = -1; */
  88. static int hf_megaco_packages_descriptor = -1;
  89. static int hf_megaco_error_Frame = -1;
  90. static int hf_megaco_Service_State = -1;
  91. static int hf_megaco_Event_Buffer_Control = -1;
  92. static int hf_megaco_mode = -1;
  93. static int hf_megaco_reserve_group = -1;
  94. static int hf_megaco_h324_muxtbl_in = -1;
  95. static int hf_megaco_h324_muxtbl_out = -1;
  96. static int hf_megaco_ds_dscp = -1;
  97. static int hf_megaco_h324_h223capr = -1;
  98. static int hf_megaco_reserve_value = -1;
  99. static int hf_megaco_streamid = -1;
  100. static int hf_megaco_requestid = -1;
  101. static int hf_megaco_pkgdname = -1;
  102. static int hf_megaco_mId = -1;
  103. /* static int hf_megaco_h245 = -1; */
  104. static int hf_megaco_h223Capability = -1;
  105. static int hf_megaco_audititem = -1;
  106. /* Define the trees for megaco */
  107. static int ett_megaco = -1;
  108. static int ett_megaco_message = -1;
  109. static int ett_megaco_message_body = -1;
  110. static int ett_megaco_context = -1;
  111. static int ett_megaco_command_line = -1;
  112. static int ett_megaco_mediadescriptor = -1;
  113. static int ett_megaco_descriptors = -1;
  114. static int ett_megaco_TerminationState = -1;
  115. static int ett_megaco_Localdescriptor = -1;
  116. static int ett_megaco_Remotedescriptor = -1;
  117. static int ett_megaco_LocalControldescriptor = -1;
  118. static int ett_megaco_auditdescriptor = -1;
  119. static int ett_megaco_eventsdescriptor = -1;
  120. static int ett_megaco_observedeventsdescriptor = -1;
  121. static int ett_megaco_observedevent = -1;
  122. static int ett_megaco_packagesdescriptor = -1;
  123. static int ett_megaco_requestedevent = -1;
  124. static int ett_megaco_signalsdescriptor = -1;
  125. static int ett_megaco_requestedsignal = -1;
  126. static int ett_megaco_h245 = -1;
  127. static gcp_hf_ett_t megaco_ctx_ids = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}};
  128. static expert_field ei_megaco_errored_command = EI_INIT;
  129. static dissector_handle_t megaco_text_handle;
  130. static int megaco_tap = -1;
  131. /*
  132. * Here are the global variables associated with
  133. * the various user definable characteristics of the dissection
  134. *
  135. * MEGACO has two kinds of message formats: text and binary
  136. *
  137. * global_megaco_raw_text determines whether we are going to display
  138. * the raw text of the megaco message, much like the HTTP dissector does.
  139. *
  140. * global_megaco_dissect_tree determines whether we are going to display
  141. * a detailed tree that expresses a somewhat more semantically meaningful
  142. * decode.
  143. */
  144. static guint global_megaco_txt_sctp_port = PORT_MEGACO_TXT;
  145. static guint global_megaco_txt_tcp_port = PORT_MEGACO_TXT;
  146. static guint global_megaco_txt_udp_port = PORT_MEGACO_TXT;
  147. #if 0
  148. static guint global_megaco_bin_sctp_port = PORT_MEGACO_BIN;
  149. static guint global_megaco_bin_tcp_port = PORT_MEGACO_BIN;
  150. static guint global_megaco_bin_udp_port = PORT_MEGACO_BIN;
  151. #endif
  152. static gboolean global_megaco_raw_text = TRUE;
  153. static gboolean global_megaco_dissect_tree = TRUE;
  154. /* Some basic utility functions that are specific to this dissector */
  155. static gint megaco_tvb_skip_wsp(tvbuff_t* tvb, gint offset);
  156. static gint megaco_tvb_skip_wsp_return(tvbuff_t* tvb, gint offset);
  157. /*
  158. * The various functions that either dissect some
  159. * subpart of MEGACO. These aren't really proto dissectors but they
  160. * are written in the same style.
  161. *
  162. */
  163. static void
  164. dissect_megaco_descriptors(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_descriptors_start_offset, gint tvb_descriptors_end_offset);
  165. static void
  166. dissect_megaco_modemdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  167. static void
  168. dissect_megaco_multiplexdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  169. static void
  170. dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset);
  171. static void
  172. dissect_megaco_eventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  173. static void
  174. dissect_megaco_signaldescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  175. static void
  176. dissect_megaco_auditdescriptor(tvbuff_t *tvb, proto_tree *tree,packet_info *pinfo, gint tvb_RBRKT, gint tvb_previous_offset);
  177. static void
  178. dissect_megaco_servicechangedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  179. static void
  180. dissect_megaco_digitmapdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  181. static void
  182. dissect_megaco_statisticsdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  183. static void
  184. dissect_megaco_observedeventsdescriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  185. static void
  186. dissect_megaco_topologydescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  187. static void
  188. dissect_megaco_errordescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_RBRKT, gint tvb_previous_offset);
  189. static void
  190. dissect_megaco_TerminationStatedescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
  191. static void
  192. dissect_megaco_Localdescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset);
  193. static void
  194. dissect_megaco_LocalControldescriptor(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tvb_next_offset, gint tvb_current_offset);
  195. static void
  196. dissect_megaco_Packagesdescriptor(tvbuff_t *tvb, proto_tree *tree, gint tvb_next_offset, gint tvb_current_offset);
  197. static void
  198. tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
  199. static void
  200. dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
  201. static gint
  202. megaco_tvb_find_token(tvbuff_t* tvb, gint offset, gint maxlenght);
  203. static dissector_handle_t data_handle;
  204. static dissector_handle_t sdp_handle;
  205. static dissector_handle_t h245_handle;
  206. static dissector_handle_t h248_handle;
  207. static dissector_handle_t h248_otp_handle;
  208. static gboolean keep_persistent_data = FALSE;
  209. static proto_tree *top_tree;
  210. /*
  211. * dissect_megaco_text over TCP, there will be a TPKT header there
  212. *
  213. */
  214. static void dissect_megaco_text_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  215. {
  216. int lv_tpkt_len;
  217. /* This code is copied from the Q.931 dissector, some parts skipped.
  218. * Check whether this looks like a TPKT-encapsulated
  219. * MEGACO packet.
  220. *
  221. * The minimum length of a MEGACO message is 6?:
  222. * Re-assembly ?
  223. */
  224. lv_tpkt_len = is_tpkt(tvb, 6);
  225. if (lv_tpkt_len == -1) {
  226. /*
  227. * It's not a TPKT packet;
  228. * Is in MEGACO ?
  229. */
  230. dissect_megaco_text(tvb, pinfo, tree);
  231. }
  232. dissect_tpkt_encap(tvb, pinfo, tree, TRUE,
  233. megaco_text_handle);
  234. }
  235. #define ERRORTOKEN 1
  236. #define TRANSTOKEN 2
  237. #define REPLYTOKEN 3
  238. #define PENDINGTOKEN 4
  239. #define RESPONSEACKTOKEN 5
  240. typedef struct {
  241. const char *name;
  242. const char *compact_name;
  243. } megaco_tokens_t;
  244. static const megaco_tokens_t megaco_messageBody_names[] = {
  245. { "Unknown-token", NULL }, /* 0 Pad so that the real headers start at index 1 */
  246. { "Error", "ER" }, /* 1 */
  247. { "Transaction", "T" }, /* 2 */
  248. { "Reply", "P" }, /* 3 */
  249. { "Pending", "PN" }, /* 4 */
  250. { "TransactionResponseAck", "K" }, /* 5 */
  251. };
  252. /* Returns index of megaco_tokens_t */
  253. static gint find_megaco_messageBody_names(tvbuff_t *tvb, int offset, guint header_len)
  254. {
  255. guint i;
  256. for (i = 1; i < array_length(megaco_messageBody_names); i++) {
  257. if (header_len == strlen(megaco_messageBody_names[i].name) &&
  258. tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].name, header_len) == 0)
  259. return i;
  260. if (megaco_messageBody_names[i].compact_name != NULL &&
  261. header_len == strlen(megaco_messageBody_names[i].compact_name) &&
  262. tvb_strncaseeql(tvb, offset, megaco_messageBody_names[i].compact_name, header_len) == 0)
  263. return i;
  264. }
  265. return -1;
  266. }
  267. static proto_item *
  268. my_proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  269. gint start, gint length, const char *value)
  270. {
  271. proto_item *pi;
  272. pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
  273. if (!global_megaco_dissect_tree) {
  274. PROTO_ITEM_SET_HIDDEN(pi);
  275. }
  276. return(pi);
  277. }
  278. /*
  279. * dissect_megaco_text - The dissector for the MEGACO Protocol, using
  280. * text encoding.
  281. */
  282. static void
  283. dissect_megaco_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  284. {
  285. gint tvb_len, len;
  286. gint tvb_offset,tvb_current_offset,tvb_previous_offset,tvb_next_offset,tokenlen;
  287. gint line_start_offset, ver_offset, ver_length, mId_offset, mId_length;
  288. gint tvb_command_start_offset, tvb_command_end_offset;
  289. gint tvb_descriptors_start_offset, tvb_descriptors_end_offset;
  290. gint tvb_transaction_end_offset;
  291. proto_tree *megaco_tree, *message_tree, *message_body_tree, *megaco_context_tree, *megaco_tree_command_line, *ti, *sub_ti;
  292. guint8 word[7];
  293. guint8 TermID[30];
  294. guint8 tempchar;
  295. gint tvb_RBRKT, tvb_LBRKT, RBRKT_counter, LBRKT_counter;
  296. guint token_index=0;
  297. guint32 dword;
  298. guchar needle;
  299. guint8 first;
  300. gcp_msg_t* msg = NULL;
  301. gcp_trx_t* trx = NULL;
  302. gcp_ctx_t* ctx = NULL;
  303. gcp_cmd_t* cmd = NULL;
  304. gcp_term_t* term = NULL;
  305. gcp_trx_type_t trx_type = GCP_TRX_NONE;
  306. guint32 trx_id = 0;
  307. guint32 ctx_id = 0;
  308. gcp_cmd_type_t cmd_type = GCP_CMD_NONE;
  309. gcp_wildcard_t wild_term = GCP_WILDCARD_NONE;
  310. proto_item *hidden_item;
  311. top_tree=tree;
  312. /* Initialize variables */
  313. tvb_len = tvb_length(tvb);
  314. megaco_tree = NULL;
  315. ti = NULL;
  316. tvb_offset = 0;
  317. tvb_next_offset = 0;
  318. RBRKT_counter = 0;
  319. LBRKT_counter = 0;
  320. /* Check if H.248 in otp(Erlang) internal format
  321. * XXX Needs improvement?
  322. * Ref:
  323. * http://www.erlang.org/doc/apps/megaco/part_frame.html
  324. * 4.1 Internal form of messages
  325. * 4.2 The different encodings
  326. */
  327. dword = tvb_get_ntoh24(tvb,0);
  328. if ((dword == 0x836803)&&(h248_otp_handle)){
  329. call_dissector(h248_otp_handle, tvb, pinfo, tree);
  330. return;
  331. }
  332. msg = gcp_msg(pinfo, tvb_raw_offset(tvb), keep_persistent_data);
  333. /*
  334. * Check to see whether we're really dealing with MEGACO by looking
  335. * for the "MEGACO" string or a "!".This needs to be improved when supporting
  336. * binary encodings. Bugfix add skipping of leading spaces.
  337. */
  338. tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
  339. line_start_offset = tvb_offset;
  340. /* Quick fix for MEGACO not following the RFC, hopefully not breaking any thing
  341. * Turned out to be TPKT in case of TCP, added some code to handle that.
  342. *
  343. * tvb_offset = tvb_find_guint8(tvb, tvb_offset, 5, 'M');
  344. */
  345. if(!tvb_get_nstringz0(tvb,tvb_offset,sizeof(word),word)) return;
  346. if (g_ascii_strncasecmp(word, "MEGACO", 6) != 0 && tvb_get_guint8(tvb, tvb_offset ) != '!'){
  347. gint8 ber_class;
  348. gboolean pc;
  349. gint32 tag;
  350. dissector_handle_t handle = data_handle;
  351. get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
  352. if (ber_class == BER_CLASS_UNI && pc && tag == BER_UNI_TAG_SEQUENCE ) {
  353. handle = h248_handle;
  354. }
  355. call_dissector(handle,tvb,pinfo,tree);
  356. return;
  357. }
  358. /* Display MEGACO in protocol column */
  359. col_set_str(pinfo->cinfo, COL_PROTOCOL, "MEGACO");
  360. /* Build the info tree if we've been given a root */
  361. /* Create megaco subtree */
  362. ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, ENC_NA);
  363. megaco_tree = proto_item_add_subtree(ti, ett_megaco);
  364. /* Format of 'message' is = MegacopToken SLASH Version SEP mId SEP messageBody */
  365. /* MegacopToken = "MEGACO" or "!" */
  366. /* According to H248.1-200205 Annex B Text encoding ( protocol version 2 ) */
  367. /* Find version */
  368. tvb_previous_offset = tvb_find_guint8(tvb, 0,
  369. tvb_len, '/');
  370. if (tvb_previous_offset == -1) {
  371. expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
  372. "Sorry, no \"/\" in the MEGACO header, I can't parse this packet");
  373. return;
  374. }
  375. /* skip / */
  376. tvb_previous_offset++;
  377. /* assume at least one digit in version */
  378. tvb_current_offset = tvb_previous_offset + 1;
  379. if (isdigit(tvb_get_guint8(tvb, tvb_current_offset))) {
  380. /* 2-digit version */
  381. tvb_current_offset++;
  382. }
  383. tokenlen = tvb_current_offset - tvb_previous_offset;
  384. ver_offset = tvb_previous_offset;
  385. ver_length = tokenlen;
  386. tvb_previous_offset = tvb_current_offset;
  387. tvb_current_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
  388. if (tvb_previous_offset == tvb_current_offset) {
  389. expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
  390. "[ Parse error: missing SEP in MEGACO header ]");
  391. return;
  392. }
  393. tvb_previous_offset = tvb_current_offset;
  394. /* mId should follow here,
  395. * mId = (( domainAddress / domainName ) [":" portNumber]) / mtpAddress / deviceName
  396. * domainAddress = "[" (IPv4address / IPv6address) "]"
  397. * domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /".") ">"
  398. * mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT
  399. * MTPToken = ("MTP")
  400. * deviceName = pathNAME
  401. * pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )["@" pathDomainName ]
  402. */
  403. tvb_current_offset = tvb_pbrk_guint8(tvb, tvb_current_offset, -1, " \t\r\n", &needle);
  404. if (tvb_current_offset == -1) {
  405. expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
  406. "[ Parse error: no body in MEGACO message (missing SEP after mId) ]");
  407. return;
  408. }
  409. tokenlen = tvb_current_offset - tvb_previous_offset;
  410. tvb_next_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset);
  411. /* At this point we should point to the "\n" ending the mId element
  412. * or to the next character after white space SEP
  413. */
  414. mId_offset = tvb_previous_offset;
  415. mId_length = tokenlen;
  416. /* Add the first line to the tree */
  417. tokenlen = tvb_next_offset - line_start_offset - 1;
  418. ti = proto_tree_add_text(megaco_tree, tvb, line_start_offset, tokenlen,
  419. "%s",tvb_format_text(tvb,line_start_offset,tokenlen));
  420. message_tree = proto_item_add_subtree(ti, ett_megaco_message);
  421. if (tree){
  422. if(global_megaco_dissect_tree){
  423. proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, ENC_ASCII|ENC_NA);
  424. proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, ENC_ASCII|ENC_NA);
  425. }else{
  426. hidden_item = proto_tree_add_item(message_tree, hf_megaco_version,tvb, ver_offset, ver_length, ENC_ASCII|ENC_NA);
  427. PROTO_ITEM_SET_HIDDEN(hidden_item);
  428. hidden_item = proto_tree_add_item(message_tree, hf_megaco_mId,tvb, mId_offset, mId_length, ENC_ASCII|ENC_NA);
  429. PROTO_ITEM_SET_HIDDEN(hidden_item);
  430. }
  431. }
  432. col_clear(pinfo->cinfo, COL_INFO);
  433. first = 1;
  434. do{
  435. tvb_previous_offset = tvb_next_offset;
  436. /* Next part is
  437. * : messageBody = ( errorDescriptor / transactionList )
  438. * errorDescriptor = ErrorToken EQUAL ErrorCode LBRKT [quotedString] RBRKT
  439. * ErrorToken = ("Error" / "ER")
  440. *
  441. * transactionList = 1*( transactionRequest / transactionReply /
  442. * transactionPending / transactionResponseAck )
  443. *
  444. * transactionResponseAck = ResponseAckToken LBRKT
  445. * transactionAck*(COMMA transactionAck) RBRKT
  446. * ResponseAckToken = ("TransactionResponseAck"/ "K")
  447. *
  448. * transactionPending = PendingToken EQUAL TransactionID LBRKT RBRKT
  449. * PendingToken = ("Pending" / "PN")
  450. *
  451. * transactionReply = ReplyToken EQUAL TransactionID LBRKT
  452. * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
  453. * ReplyToken = ("Reply" / "P")
  454. *
  455. * transactionRequest = TransToken EQUAL TransactionID LBRKT
  456. * actionRequest *(COMMA actionRequest) RBRKT
  457. * TransToken = ("Transaction" / "T")
  458. */
  459. /* Find token length */
  460. for (tvb_offset=tvb_previous_offset; tvb_offset < tvb_len-1; tvb_offset++){
  461. if (!isalpha(tvb_get_guint8(tvb, tvb_offset ))){
  462. break;
  463. }
  464. }
  465. tokenlen = tvb_offset - tvb_previous_offset;
  466. token_index = find_megaco_messageBody_names(tvb, tvb_previous_offset, tokenlen);
  467. /* Debug code
  468. g_warning("token_index %u",token_index);
  469. */
  470. tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_len, '{');
  471. tvb_current_offset = tvb_LBRKT;
  472. tvb_transaction_end_offset = megaco_tvb_find_token(tvb, tvb_LBRKT - 1, tvb_len);
  473. switch ( token_index ){
  474. /* errorDescriptor */
  475. case ERRORTOKEN:
  476. col_set_str(pinfo->cinfo, COL_INFO, "Error ");
  477. tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_len); /*tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');*/
  478. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
  479. "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset));
  480. message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
  481. if (tree) {
  482. my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
  483. tvb_previous_offset, tokenlen,
  484. "Error" );
  485. tvb_command_start_offset = tvb_previous_offset;
  486. dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_len-1, tvb_command_start_offset);
  487. }
  488. return;
  489. /* transactionResponseAck
  490. * transactionResponseAck = ResponseAckToken LBRKT transactionAck
  491. * *(COMMA transactionAck) RBRKT
  492. * transactionAck = transactionID / (transactionID "-" transactionID)
  493. */
  494. case RESPONSEACKTOKEN:
  495. tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
  496. tvb_offset = tvb_LBRKT;
  497. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset,
  498. "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_offset-tvb_previous_offset+1));
  499. message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
  500. my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
  501. tvb_previous_offset, tokenlen,
  502. "TransactionResponseAck" );
  503. tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_offset+1);
  504. tvb_current_offset = tvb_find_guint8(tvb, tvb_offset+1, tvb_len, '}');
  505. /*tvb_current_offset = megaco_tvb_find_token(tvb, tvb_offset, tvb_transaction_end_offset);*/
  506. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset)-1; /* cut last RBRKT */
  507. len = tvb_current_offset - tvb_previous_offset;
  508. if (!first) {
  509. col_append_str(pinfo->cinfo, COL_INFO, " ");
  510. }
  511. col_append_fstr(pinfo->cinfo, COL_INFO, "%s TransactionResponseAck",
  512. tvb_format_text(tvb,tvb_previous_offset,len));
  513. if(tree)
  514. my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
  515. tvb_previous_offset, len,
  516. tvb_format_text(tvb,tvb_previous_offset,len));
  517. if(global_megaco_raw_text){
  518. tvb_raw_text_add(tvb, megaco_tree);
  519. }
  520. return;
  521. /* Pe and PN is transactionPending, P+"any char" is transactionReply */
  522. case PENDINGTOKEN:
  523. tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1;
  524. tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
  525. tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
  526. tvb_current_offset = tvb_LBRKT;
  527. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
  528. "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
  529. message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
  530. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
  531. len = tvb_current_offset - tvb_offset;
  532. if (tree)
  533. my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
  534. tvb_previous_offset, tokenlen,
  535. "Pending" );
  536. if (!first) {
  537. col_append_str(pinfo->cinfo, COL_INFO, " ");
  538. }
  539. col_append_fstr(pinfo->cinfo, COL_INFO, "%s Pending",
  540. tvb_format_text(tvb,tvb_offset,len));
  541. if(tree)
  542. my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
  543. tvb_offset, len,
  544. tvb_format_text(tvb,tvb_offset,len));
  545. return;
  546. /* transactionReply */
  547. case REPLYTOKEN:
  548. trx_type = GCP_TRX_REPLY;
  549. tvb_LBRKT = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '{');
  550. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset,
  551. "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_LBRKT-tvb_previous_offset+1));
  552. message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
  553. if (tree)
  554. my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
  555. tvb_previous_offset, tokenlen,
  556. "Reply" );
  557. tvb_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '=')+1;
  558. tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
  559. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_LBRKT-1);
  560. len = tvb_current_offset - tvb_offset;
  561. col_add_fstr(pinfo->cinfo, COL_INFO, "%s Reply ",
  562. tvb_format_text(tvb,tvb_offset,len));
  563. trx_id = (guint)strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
  564. if(tree)
  565. my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb,
  566. tvb_offset, len, tvb_format_text(tvb,tvb_offset,len));
  567. /* Find if we have a errorDescriptor or actionReplyList */
  568. tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
  569. tempchar = tvb_get_guint8(tvb,tvb_offset);
  570. if ((tempchar == 'E')||(tempchar == 'e')){
  571. dissect_megaco_errordescriptor(tvb, megaco_tree, tvb_transaction_end_offset-1, tvb_offset);
  572. return;
  573. }
  574. /* Offset should be at first printable char after { */
  575. tvb_previous_offset = tvb_offset;
  576. break;
  577. case TRANSTOKEN:
  578. /* TransactionRequest */
  579. trx_type = GCP_TRX_REQUEST;
  580. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset,
  581. "%s",tvb_format_text(tvb, tvb_previous_offset, tvb_current_offset-tvb_previous_offset+1));
  582. message_body_tree = proto_item_add_subtree(ti, ett_megaco_message_body);
  583. if(tree)
  584. my_proto_tree_add_string(message_body_tree, hf_megaco_transaction, tvb,
  585. tvb_previous_offset, tokenlen,
  586. "Request" );
  587. tvb_offset = tvb_find_guint8(tvb, tvb_offset, tvb_transaction_end_offset, '=')+1;
  588. tvb_offset = megaco_tvb_skip_wsp(tvb, tvb_offset);
  589. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset-1);
  590. len = tvb_current_offset - tvb_offset;
  591. if (!first) {
  592. col_append_str(pinfo->cinfo, COL_INFO, " ");
  593. }
  594. col_append_fstr(pinfo->cinfo, COL_INFO, "%s Request",
  595. tvb_format_text(tvb,tvb_offset,len));
  596. trx_id = (guint)strtoul(tvb_format_text(tvb,tvb_offset,len),NULL,10);
  597. if(tree)
  598. my_proto_tree_add_string(message_body_tree, hf_megaco_transid, tvb, tvb_offset,len,
  599. tvb_format_text(tvb,tvb_offset,len));
  600. /* Offset should be at first printable char after { */
  601. tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_LBRKT+1);
  602. break;
  603. default :
  604. ti = proto_tree_add_item(tree,proto_megaco,tvb, 0, -1, ENC_NA);
  605. expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
  606. "Sorry, can't understand errorDescriptor / transactionList = %s, can't parse it pos %u",
  607. tvb_format_text(tvb,tvb_previous_offset,2),tvb_previous_offset);
  608. return;
  609. } /* end switch */
  610. /* Only these remains now
  611. * transactionReply = ReplyToken EQUAL TransactionID LBRKT
  612. * [ ImmAckRequiredToken COMMA]( errorDescriptor / actionReplyList ) RBRKT
  613. * ReplyToken = ("Reply" / "P")
  614. *
  615. * errorDescriptor = ErrorToken EQUAL ErrorCode
  616. * LBRKT [quotedString] RBRKT
  617. *
  618. * transactionRequest = TransToken EQUAL TransactionID LBRKT
  619. * actionRequest *(COMMA actionRequest) RBRKT
  620. * TransToken = ("Transaction" / "T")
  621. */
  622. trx = gcp_trx(msg , trx_id , trx_type, keep_persistent_data);
  623. /* Find Context */
  624. nextcontext:
  625. tvb_next_offset = tvb_find_guint8(tvb, tvb_previous_offset, tvb_transaction_end_offset, '{');
  626. ti = proto_tree_add_text(megaco_tree, tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1,
  627. "%s", tvb_format_text(tvb, tvb_previous_offset, tvb_next_offset-tvb_previous_offset+1));
  628. megaco_context_tree = proto_item_add_subtree(ti, ett_megaco_context);
  629. tvb_previous_offset = tvb_find_guint8(tvb, tvb_current_offset,
  630. tvb_transaction_end_offset, '=')+1;
  631. tvb_previous_offset = megaco_tvb_skip_wsp(tvb, tvb_previous_offset);
  632. if (tvb_current_offset >= tvb_next_offset) {
  633. expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Invalid offset ]");
  634. return;
  635. }
  636. tvb_current_offset = tvb_next_offset;
  637. tokenlen = tvb_current_offset - tvb_previous_offset;
  638. tempchar = tvb_get_guint8(tvb, tvb_previous_offset );
  639. if (tvb_get_guint8(tvb, tvb_current_offset-1 ) == ' '){
  640. tokenlen--;
  641. }
  642. switch ( tempchar ){
  643. case '$':
  644. ctx_id = CHOOSE_CONTEXT;
  645. my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
  646. tvb_previous_offset, 1,
  647. "Choose one");
  648. col_append_str(pinfo->cinfo, COL_INFO, " |=Choose one");
  649. break;
  650. case '*':
  651. ctx_id = ALL_CONTEXTS;
  652. my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
  653. tvb_previous_offset, 1,
  654. "All");
  655. col_append_str(pinfo->cinfo, COL_INFO, " |=All");
  656. break;
  657. case '-':
  658. ctx_id = NULL_CONTEXT;
  659. proto_tree_add_text(megaco_context_tree, tvb, tvb_previous_offset, tokenlen, "Context: NULL" );
  660. col_append_str(pinfo->cinfo, COL_INFO, " |=NULL");
  661. break;
  662. default:
  663. my_proto_tree_add_string(megaco_context_tree, hf_megaco_Context, tvb,
  664. tvb_previous_offset, tokenlen,
  665. tvb_format_text(tvb, tvb_previous_offset,
  666. tokenlen));
  667. ctx_id = (guint)strtoul(tvb_format_text(tvb, tvb_previous_offset, tokenlen),NULL,10);
  668. col_append_fstr(pinfo->cinfo, COL_INFO, " |=%s",tvb_format_text(tvb, tvb_previous_offset,tokenlen));
  669. }
  670. ctx = gcp_ctx(msg,trx,ctx_id,keep_persistent_data);
  671. /* Find Commands */
  672. /* If Transaction is is Request, Reply or Pending */
  673. tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_current_offset +1);
  674. tvb_command_end_offset = tvb_command_start_offset;
  675. tvb_LBRKT = tvb_command_start_offset;
  676. tvb_RBRKT = tvb_command_start_offset;
  677. /* The following loop find the individual contexts, commands and call the for every Descriptor a subroutine */
  678. do {
  679. tvb_command_end_offset = tvb_find_guint8(tvb, tvb_command_end_offset +1,
  680. tvb_transaction_end_offset, ',');
  681. if ( tvb_command_end_offset == -1 || tvb_command_end_offset > tvb_transaction_end_offset){
  682. tvb_command_end_offset = tvb_transaction_end_offset ;
  683. }
  684. /* checking how many left brackets are before the next comma */
  685. while ( tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') != -1
  686. && (tvb_find_guint8(tvb, tvb_LBRKT+1,tvb_transaction_end_offset, '{') < tvb_command_end_offset)){
  687. tvb_LBRKT = tvb_find_guint8(tvb, tvb_LBRKT+1,
  688. tvb_transaction_end_offset, '{');
  689. LBRKT_counter++;
  690. }
  691. /* checking how many right brackets are before the next comma */
  692. while ( (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') != -1 )
  693. && (tvb_find_guint8(tvb, tvb_RBRKT+1,tvb_transaction_end_offset, '}') <= tvb_command_end_offset)
  694. && LBRKT_counter != 0){
  695. tvb_RBRKT = tvb_find_guint8(tvb, tvb_RBRKT+1,
  696. tvb_transaction_end_offset, '}');
  697. RBRKT_counter++;
  698. }
  699. /* If equal or more right brackets before the comma, one command is complete */
  700. if ( LBRKT_counter <= RBRKT_counter ){
  701. tvb_current_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
  702. tvb_transaction_end_offset, '{');
  703. /* includes no descriptors */
  704. if ( LBRKT_counter == 0 ){
  705. tvb_current_offset = tvb_command_end_offset;
  706. /* the last command in a context */
  707. if ( tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') < tvb_current_offset
  708. && tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}') != -1){
  709. tvb_previous_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
  710. tvb_transaction_end_offset, '}');
  711. len = tvb_previous_offset - tvb_command_start_offset;
  712. tvb_previous_offset = megaco_tvb_skip_wsp_return(tvb, tvb_previous_offset -1);
  713. tokenlen = tvb_previous_offset - tvb_command_start_offset;
  714. }
  715. /* not the last command in a context*/
  716. else{
  717. len = tvb_current_offset - tvb_command_start_offset;
  718. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
  719. tokenlen = tvb_current_offset - tvb_command_start_offset;
  720. }
  721. }
  722. /* command includes descriptors */
  723. else{
  724. len = tvb_current_offset - tvb_command_start_offset;
  725. tvb_current_offset = megaco_tvb_skip_wsp_return(tvb, tvb_current_offset -1);
  726. tokenlen = tvb_current_offset - tvb_command_start_offset;
  727. }
  728. /* if a next context is specified */
  729. if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'C'){
  730. tvb_current_offset = tvb_command_start_offset;
  731. tvb_previous_offset = tvb_command_start_offset;
  732. LBRKT_counter = 0;
  733. RBRKT_counter = 0;
  734. goto nextcontext;
  735. }
  736. sub_ti = proto_tree_add_text(megaco_tree, tvb, tvb_command_start_offset, len+1,
  737. "%s", tvb_format_text(tvb, tvb_command_start_offset, len+1));
  738. megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
  739. /* creation of the megaco_tree_command_line additionally Command and Transaction ID will be printed in this line */
  740. /* Changed to use the lines above. this code is saved if there is complaints
  741. sub_ti = proto_tree_add_item(megaco_tree,hf_megaco_command_line,tvb,tvb_command_start_offset,tokenlen, ENC_ASCII|ENC_NA);
  742. megaco_tree_command_line = proto_item_add_subtree(sub_ti, ett_megaco_command_line);
  743. */
  744. tvb_next_offset = tvb_command_start_offset + tokenlen;
  745. /* Try to dissect Topology Descriptor before the command */
  746. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
  747. if ( (tempchar >= 'a')&& (tempchar <= 'z')){
  748. tempchar = tempchar - 0x20;
  749. }
  750. if ( tempchar == 'T') {
  751. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
  752. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  753. tempchar = tempchar - 0x20;
  754. if ( tempchar == 'P' || tempchar == 'O'){
  755. gint tvb_topology_end_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '}');
  756. if ( tvb_topology_end_offset == -1 ){
  757. expert_add_info_format(pinfo, sub_ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"}\" ]");
  758. return;
  759. }
  760. tvb_command_start_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');
  761. if ( tvb_command_start_offset == -1 ){
  762. expert_add_info_format(pinfo, sub_ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"{\" ]");
  763. return;
  764. }
  765. dissect_megaco_topologydescriptor(tvb, megaco_tree_command_line, tvb_topology_end_offset-1, tvb_command_start_offset+1);
  766. /* Command after Topology Descriptor */
  767. tvb_command_start_offset = tvb_find_guint8(tvb, tvb_topology_end_offset + 1,
  768. tvb_transaction_end_offset, ',');
  769. if ( tvb_command_start_offset == -1 ){
  770. /* No Command present after Topology Descriptor */
  771. break;
  772. } else {
  773. /* Try to find the first char of the command */
  774. tvb_command_start_offset = megaco_tvb_skip_wsp(tvb, tvb_command_start_offset + 1);
  775. tvb_next_offset = tvb_find_guint8(tvb, tvb_command_start_offset, tvb_transaction_end_offset, '{');
  776. continue;
  777. }
  778. }
  779. }
  780. /* Additional value */
  781. if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'O'){
  782. proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "O- indicates an optional command" );
  783. tvb_command_start_offset = tvb_command_start_offset+2;
  784. }
  785. /* Additional value */
  786. if ( tvb_get_guint8(tvb, tvb_command_start_offset ) == 'W'){
  787. proto_tree_add_text(megaco_tree_command_line, tvb, tvb_command_start_offset, 2, "W- indicates a wildcarded response to a command" );
  788. tvb_command_start_offset = tvb_command_start_offset+2;
  789. }
  790. tvb_offset = tvb_find_guint8(tvb, tvb_command_start_offset,
  791. tvb_transaction_end_offset, '=');
  792. if (tvb_offset == -1 ) {
  793. expert_add_info_format(pinfo, sub_ti, PI_MALFORMED, PI_ERROR, "[ Parse error: Missing \"=\" ]");
  794. return;
  795. }
  796. tvb_offset = megaco_tvb_skip_wsp_return(tvb, tvb_offset -1);
  797. tokenlen = tvb_offset - tvb_command_start_offset;
  798. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset);
  799. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  800. tempchar = tempchar - 0x20;
  801. if ( tempchar != 'E' ){
  802. /* Short form used */
  803. if ( tvb_get_guint8(tvb, 0 ) == '!'){
  804. switch ( tempchar ){
  805. case 'A':
  806. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
  807. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  808. tempchar = tempchar - 0x20;
  809. switch ( tempchar ){
  810. case 'V':
  811. switch(trx_type) {
  812. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITVAL_REPLY; break;
  813. case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITVAL_REQ; break;
  814. default: cmd_type = GCP_CMD_NONE; break;
  815. }
  816. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  817. tvb_command_start_offset, tokenlen,
  818. "AuditValue");
  819. col_append_str(pinfo->cinfo, COL_INFO, " AuditValue");
  820. break;
  821. case 'C':
  822. switch(trx_type) {
  823. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_AUDITCAP_REQ; break;
  824. case GCP_TRX_REPLY: cmd_type = GCP_CMD_AUDITCAP_REPLY; break;
  825. default: cmd_type = GCP_CMD_NONE; break;
  826. }
  827. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  828. tvb_command_start_offset, tokenlen,
  829. "AuditCapability");
  830. col_append_str(pinfo->cinfo, COL_INFO, " AuditCapability");
  831. break;
  832. default:
  833. switch(trx_type) {
  834. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_ADD_REQ; break;
  835. case GCP_TRX_REPLY: cmd_type = GCP_CMD_ADD_REPLY; break;
  836. default: cmd_type = GCP_CMD_NONE; break;
  837. }
  838. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  839. tvb_command_start_offset, tokenlen,
  840. "Add");
  841. col_append_str(pinfo->cinfo, COL_INFO, " Add");
  842. break;
  843. }
  844. break;
  845. case 'N':
  846. switch(trx_type) {
  847. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_NOTIFY_REQ; break;
  848. case GCP_TRX_REPLY: cmd_type = GCP_CMD_NOTIFY_REPLY; break;
  849. default: cmd_type = GCP_CMD_NONE; break;
  850. }
  851. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  852. tvb_command_start_offset, tokenlen,
  853. "Notify");
  854. col_append_str(pinfo->cinfo, COL_INFO, " Notify");
  855. break;
  856. case 'M':
  857. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
  858. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  859. tempchar = tempchar - 0x20;
  860. switch ( tempchar ){
  861. case 'F':
  862. switch(trx_type) {
  863. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOD_REQ; break;
  864. case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOD_REPLY; break;
  865. default: cmd_type = GCP_CMD_NONE; break;
  866. }
  867. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  868. tvb_command_start_offset, tokenlen,
  869. "Modify");
  870. col_append_str(pinfo->cinfo, COL_INFO, " Modify");
  871. break;
  872. case 'V':
  873. switch(trx_type) {
  874. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_MOVE_REQ; break;
  875. case GCP_TRX_REPLY: cmd_type = GCP_CMD_MOVE_REPLY; break;
  876. default: cmd_type = GCP_CMD_NONE; break;
  877. }
  878. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  879. tvb_command_start_offset, tokenlen,
  880. "Move");
  881. col_append_str(pinfo->cinfo, COL_INFO, " Move");
  882. break;
  883. }
  884. break;
  885. case 'P':
  886. cmd_type = GCP_CMD_NONE;
  887. /*
  888. PackagesToken = ("Packages" / "PG")
  889. PendingToken = ("Pending" / "PN")
  890. PriorityToken = ("Priority" / "PR")
  891. ProfileToken = ("Profile" / "PF")
  892. */
  893. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
  894. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  895. tempchar = tempchar - 0x20;
  896. switch ( tempchar ){
  897. case 'G':
  898. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  899. tvb_command_start_offset, tokenlen,
  900. "Packages");
  901. break;
  902. case 'N':
  903. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  904. tvb_command_start_offset, tokenlen,
  905. "Pending");
  906. break;
  907. case 'R':
  908. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  909. tvb_command_start_offset, tokenlen,
  910. "Priority");
  911. break;
  912. case 'F':
  913. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  914. tvb_command_start_offset, tokenlen,
  915. "Profile");
  916. break;
  917. }
  918. break;
  919. case 'S':
  920. tempchar = tvb_get_guint8(tvb, tvb_command_start_offset+1);
  921. if ( (tempchar >= 'a')&& (tempchar <= 'z'))
  922. tempchar = tempchar - 0x20;
  923. switch ( tempchar ){
  924. case 'C':
  925. switch(trx_type) {
  926. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SVCCHG_REQ; break;
  927. case GCP_TRX_REPLY: cmd_type = GCP_CMD_SVCCHG_REPLY; break;
  928. default: cmd_type = GCP_CMD_NONE; break;
  929. }
  930. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  931. tvb_command_start_offset, tokenlen,
  932. "ServiceChange");
  933. break;
  934. default:
  935. switch(trx_type) {
  936. case GCP_TRX_REQUEST: cmd_type = GCP_CMD_SUB_REQ; break;
  937. case GCP_TRX_REPLY: cmd_type = GCP_CMD_SUB_REPLY; break;
  938. default: cmd_type = GCP_CMD_NONE; break;
  939. }
  940. my_proto_tree_add_string(megaco_tree_command_line, hf_megaco_command, tvb,
  941. tvb_command_start_offset, tokenlen,
  942. "Subtract");
  943. col_append_str(pinfo->cinfo, COL_INFO, " Subtract");
  944. break;
  945. }
  946. break;
  947. default:
  948. {
  949. proto_item *item;
  950. tokenlen = (tvb_RBRKT+1) - tvb_previous_offset;
  951. tvb_ensure_bytes_exist(tvb, tvb_previous_offset, tokenlen);
  952. item = proto_tree_add_string(m

Large files files are truncated, but you can click here to view the full file