📄 packet-mgcp.c
字号:
/* packet-mgcp.c * Routines for mgcp packet disassembly * RFC 2705 * * $Id: packet-mgcp.c,v 1.31 2002/01/21 07:37:49 guy Exp $ * * Copyright (c) 2000 by Ed Warnicke <hagbard@physics.rutgers.edu> * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> * Copyright 1999 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "plugins/plugin_api.h"#include "moduleinfo.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#include <stdio.h>#include <stdlib.h>#include <gmodule.h>#include <ctype.h>#include <time.h>#include <string.h>#include <epan/packet.h>#include <epan/resolv.h>#include "prefs.h"#include <epan/strutil.h>#include "plugins/plugin_api_defs.h"#ifndef __ETHEREAL_STATIC__G_MODULE_EXPORT const gchar version[] = VERSION;#endif#define TCP_PORT_MGCP_GATEWAY 2427#define UDP_PORT_MGCP_GATEWAY 2427#define TCP_PORT_MGCP_CALLAGENT 2727#define UDP_PORT_MGCP_CALLAGENT 2727void proto_reg_handoff_mgcp(void);/* Define the mgcp proto */static int proto_mgcp = -1;/* Define many many headers for mgcp */static int hf_mgcp_req = -1;static int hf_mgcp_req_verb = -1;static int hf_mgcp_req_endpoint = -1;static int hf_mgcp_rsp = -1;static int hf_mgcp_transid = -1;static int hf_mgcp_version = -1;static int hf_mgcp_rsp_rspcode = -1;static int hf_mgcp_rsp_rspstring = -1;static int hf_mgcp_param_rspack = -1;static int hf_mgcp_param_bearerinfo = -1;static int hf_mgcp_param_callid = -1;static int hf_mgcp_param_connectionid = -1;static int hf_mgcp_param_secondconnectionid = -1;static int hf_mgcp_param_notifiedentity = -1;static int hf_mgcp_param_requestid = -1;static int hf_mgcp_param_localconnoptions = -1;static int hf_mgcp_param_connectionmode = -1;static int hf_mgcp_param_reqevents = -1;static int hf_mgcp_param_restartmethod = -1;static int hf_mgcp_param_restartdelay = -1;static int hf_mgcp_param_signalreq = -1;static int hf_mgcp_param_digitmap = -1;static int hf_mgcp_param_observedevent = -1;static int hf_mgcp_param_connectionparam = -1;static int hf_mgcp_param_reasoncode = -1;static int hf_mgcp_param_eventstates = -1;static int hf_mgcp_param_specificendpoint = -1;static int hf_mgcp_param_secondendpointid = -1;static int hf_mgcp_param_reqinfo = -1;static int hf_mgcp_param_quarantinehandling = -1;static int hf_mgcp_param_detectedevents = -1;static int hf_mgcp_param_capabilities = -1;static int hf_mgcp_param_extention = -1;static int hf_mgcp_param_invalid = -1;static int hf_mgcp_messagecount = -1;/* * Define the trees for mgcp * We need one for MGCP itself and one for the MGCP paramters */static int ett_mgcp = -1;static int ett_mgcp_param = -1;/* * Here are the global variables associated with * the various user definable characteristics of the dissection * * MGCP has two kinds of "agents", gateways and callagents. Callagents * control gateways in a master/slave sort of arrangement. Since gateways * and callagents have different well known ports and could both * operate under either udp or tcp we have rather a lot of port info to * specify. * * global_mgcp_raw_text determines whether we are going to display * the raw text of the mgcp message, much like the HTTP dissector does. * * global_mgcp_dissect_tree determines whether we are going to display * a detailed tree that expresses a somewhat more semantically meaningful * decode. */static int global_mgcp_gateway_tcp_port = TCP_PORT_MGCP_GATEWAY;static int global_mgcp_gateway_udp_port = UDP_PORT_MGCP_GATEWAY;static int global_mgcp_callagent_tcp_port = TCP_PORT_MGCP_CALLAGENT;static int global_mgcp_callagent_udp_port = UDP_PORT_MGCP_CALLAGENT;static gboolean global_mgcp_raw_text = FALSE;static gboolean global_mgcp_dissect_tree = TRUE;static gboolean global_mgcp_message_count = FALSE;/* * Variables to allow for proper deletion of dissector registration when * the user changes port from the gui. */static int gateway_tcp_port = 0;static int gateway_udp_port = 0;static int callagent_tcp_port = 0;static int callagent_udp_port = 0;/* A simple MGCP type that is occasionally handy */typedef enum _mgcp_type { MGCP_REQUEST, MGCP_RESPONSE, MGCP_OTHERS} mgcp_type_t;/* Some basic utility functions that are specific to this dissector */static gboolean is_mgcp_verb(tvbuff_t *tvb, gint offset, gint maxlength); static gboolean is_mgcp_rspcode(tvbuff_t *tvb, gint offset, gint maxlength);static gint tvb_parse_param(tvbuff_t *tvb, gint offset, gint maxlength, int** hf);/* * The various functions that either dissect some * subpart of MGCP. These aren't really proto dissectors but they * are written in the same style. */ static void dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,proto_tree *mgcp_tree, proto_tree *ti);static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree);static void dissect_mgcp_params(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree);static void mgcp_raw_text_add(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);/* * Some functions which should be moved to a library * as I think that people may find them of general usefulness. */static gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength);static gint tvb_find_null_line(tvbuff_t* tvb, gint offset, gint len, gint* next_offset); static gint tvb_find_dot_line(tvbuff_t* tvb, gint offset, gint len, gint* next_offset);static gboolean is_rfc2234_alpha(guint8 c);static dissector_handle_t sdp_handle;/* * dissect_mgcp - The dissector for the Media Gateway Control Protocol */static voiddissect_mgcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){ gint sectionlen; guint32 num_messages; gint tvb_sectionend,tvb_sectionbegin, tvb_len, tvb_current_len; proto_tree *mgcp_tree, *ti; /* Initialize variables */ tvb_sectionend = 0; tvb_sectionbegin = tvb_sectionend; sectionlen = 0; tvb_len = tvb_length(tvb); tvb_current_len = tvb_len; num_messages = 0; mgcp_tree = NULL; ti = NULL; /* * Set the columns now, so that they'll be set correctly if we throw * an exception. We can set them later as well.... */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_add_str(pinfo->cinfo, COL_PROTOCOL, "MGCP"); if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); /* * Check to see whether we're really dealing with MGCP by looking * for a valid MGCP verb or response code. This isn't infallible, * but its cheap and its better than nothing. */ if(is_mgcp_verb(tvb,0,tvb_len) || is_mgcp_rspcode(tvb,0,tvb_len)){ /* Build the info tree if we've been given a root */ if (tree || global_mgcp_message_count == TRUE) { /* * Loop through however many mgcp messages may be stuck in * this packet using piggybacking */ do{ num_messages++; if(tree){ /* Create out mgcp subtree */ ti = proto_tree_add_item(tree,proto_mgcp,tvb,0,0, FALSE); mgcp_tree = proto_item_add_subtree(ti, ett_mgcp); } sectionlen = tvb_find_dot_line(tvb, tvb_sectionbegin, -1, &tvb_sectionend); if( sectionlen != -1){ dissect_mgcp_message(tvb_new_subset(tvb, tvb_sectionbegin, sectionlen, -1), pinfo, tree, mgcp_tree,ti); tvb_sectionbegin = tvb_sectionend; } else { break; } } while(tvb_sectionend < tvb_len ); if(mgcp_tree){ proto_tree_add_uint_hidden(mgcp_tree, hf_mgcp_messagecount, tvb, 0 ,0 , num_messages); } } /* * Add our column information we do this after dissecting SDP * in order to prevent the column info changing to reflect the SDP. */ tvb_sectionbegin = 0; if (check_col(pinfo->cinfo, COL_PROTOCOL)){ if( global_mgcp_message_count == TRUE ){ if(num_messages > 1){ col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "MGCP (%i messages)",num_messages); } else { col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "MGCP (%i message)",num_messages); } } else { col_add_str(pinfo->cinfo, COL_PROTOCOL, "MGCP"); } } if (check_col(pinfo->cinfo, COL_INFO) ){ sectionlen = tvb_find_line_end(tvb, tvb_sectionbegin,-1, &tvb_sectionend); col_add_fstr(pinfo->cinfo, COL_INFO, "%s", tvb_format_text(tvb,tvb_sectionbegin,sectionlen)); } } }static void dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *mgcp_tree, proto_tree *ti){ /* Declare variables */ gint sectionlen; gint tvb_sectionend,tvb_sectionbegin, tvb_len, tvb_current_len; tvbuff_t *next_tvb; /* Initialize variables */ tvb_sectionend = 0; tvb_sectionbegin = tvb_sectionend; sectionlen = 0; tvb_len = tvb_length(tvb); tvb_current_len = tvb_len; /* * Check to see whether we're really dealing with MGCP by looking * for a valid MGCP verb or response code. This isn't infallible, * but its cheap and its better than nothing. */ if(is_mgcp_verb(tvb,0,tvb_len) || is_mgcp_rspcode(tvb,0,tvb_len)){ /* Build the info tree if we've been given a root */ if (tree && mgcp_tree) { /* dissect first line */ tvb_sectionbegin = 0; tvb_current_len = tvb_len; tvb_sectionend = tvb_sectionbegin; sectionlen = tvb_find_line_end(tvb,0,-1,&tvb_sectionend); if( sectionlen > 0){ dissect_mgcp_firstline(tvb_new_subset(tvb, tvb_sectionbegin, sectionlen,-1), pinfo, mgcp_tree); } tvb_sectionbegin = tvb_sectionend; /* dissect params */ if(tvb_sectionbegin < tvb_len){ sectionlen = tvb_find_null_line(tvb, tvb_sectionbegin, -1, &tvb_sectionend); dissect_mgcp_params(tvb_new_subset(tvb, tvb_sectionbegin, sectionlen, -1), pinfo, mgcp_tree); tvb_sectionbegin = tvb_sectionend; } /* set the mgcp payload length correctly so we don't include the * encapsulated SDP */ sectionlen = tvb_sectionend; proto_item_set_len(ti,sectionlen); /* Display the raw text of the mgcp message if desired */ /* Do we want to display the raw text of our MGCP packet? */ if(global_mgcp_raw_text){ mgcp_raw_text_add(tvb_new_subset(tvb,0,tvb_len,-1),pinfo, mgcp_tree); } /* dissect sdp payload */ if( tvb_sectionend < tvb_len && global_mgcp_dissect_tree == TRUE){ next_tvb = tvb_new_subset(tvb, tvb_sectionend, -1, -1); call_dissector(sdp_handle, next_tvb, pinfo, tree); } } }}/* * Add the raw text of the message to the dissect tree if appropriate * preferences are specified. The args and returns follow the general * convention for proto dissectors (although this is NOT a proto dissector). */static void mgcp_raw_text_add(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){ gint tvb_linebegin,tvb_lineend,tvb_len,linelen; tvb_linebegin = 0; tvb_len = tvb_length(tvb); do { tvb_find_line_end(tvb,tvb_linebegin,-1,&tvb_lineend); linelen = tvb_lineend - tvb_linebegin; proto_tree_add_text(tree, tvb, tvb_linebegin, linelen, "%s", tvb_format_text(tvb,tvb_linebegin, linelen)); tvb_linebegin = tvb_lineend; } while ( tvb_lineend < tvb_len );}/* Register all the bits needed with the filtering engine */void proto_register_mgcp(void){ static hf_register_info hf[] = { { &hf_mgcp_req, { "Request", "mgcp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "True if MGCP request", HFILL }}, { &hf_mgcp_rsp, { "Response", "mgcp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "TRUE if MGCP response", HFILL }}, { &hf_mgcp_req_verb, { "Verb", "mgcp.req.verb", FT_STRING, BASE_DEC, NULL, 0x0, "Name of the verb", HFILL }}, { &hf_mgcp_req_endpoint, { "Endpoint", "mgcp.req.endpoint", FT_STRING, BASE_DEC, NULL, 0x0, "Endpoint referenced by the message", HFILL }}, { &hf_mgcp_transid, { "Transaction ID", "mgcp.transid", FT_STRING, BASE_DEC, NULL, 0x0, "Transaction ID of this message", HFILL }}, { &hf_mgcp_version, { "Version", "mgcp.version", FT_STRING, BASE_DEC, NULL, 0x0, "MGCP Version", HFILL }}, { &hf_mgcp_rsp_rspcode, { "Response Code", "mgcp.rsp.rspcode", FT_STRING, BASE_DEC, NULL, 0x0, "Response Code", HFILL }}, { &hf_mgcp_rsp_rspstring, { "Response String", "mgcp.rsp.rspstring", FT_STRING, BASE_DEC, NULL, 0x0, "Response String", HFILL }}, { &hf_mgcp_param_rspack, { "ResponseAck (K)", "mgcp.param.rspack", FT_STRING, BASE_DEC, NULL, 0x0, "Response Ack", HFILL }}, { &hf_mgcp_param_bearerinfo, { "BearerInformation (B)", "mgcp.param.bearerinfo", FT_STRING, BASE_DEC, NULL, 0x0, "Bearer Information", HFILL }}, { &hf_mgcp_param_callid, { "CallId (C)", "mgcp.param.callid", FT_STRING, BASE_DEC, NULL, 0x0, "Call Id", HFILL }},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -