aboutsummaryrefslogtreecommitdiffstats
path: root/asn1/h225/packet-h225-template.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2005-01-02 22:01:32 +0000
committerAnders Broman <anders.broman@ericsson.com>2005-01-02 22:01:32 +0000
commit422d331c09e1c2658f126df495646809f3fa35e2 (patch)
treefcfbc44fc2d6d4eb37bde6a0f3a873803cd271a6 /asn1/h225/packet-h225-template.c
parentedc4b8fff5b11badc57c5d17f951320915e42599 (diff)
asn2eth generated h225 dissector
svn path=/trunk/; revision=12930
Diffstat (limited to 'asn1/h225/packet-h225-template.c')
-rw-r--r--asn1/h225/packet-h225-template.c466
1 files changed, 466 insertions, 0 deletions
diff --git a/asn1/h225/packet-h225-template.c b/asn1/h225/packet-h225-template.c
new file mode 100644
index 0000000000..bb4c245ad6
--- /dev/null
+++ b/asn1/h225/packet-h225-template.c
@@ -0,0 +1,466 @@
+/* packet-h225_asn1.c
+ * Routines for h225 packet dissection
+ * Copyright 2005, Anders Broman <anders.broman@ericsson.com>
+ *
+ * $Id: packet-h225_asn1-template.c 12203 2004-10-05 09:18:55Z guy $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 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.
+ *
+ * To quote the author of the previous H323/H225/H245 dissector:
+ * "This is a complete replacement of the previous limitied dissector
+ * that Ronnie was crazy enough to write by hand. It was a lot of time
+ * to hack it by hand, but it is incomplete and buggy and it is good when
+ * it will go away."
+ * Ronnie did a great job and all the VoIP users had made good use of it!
+ * Credit to Tomas Kukosa for developing the Asn2eth compiler.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <epan/prefs.h>
+#include "tap.h"
+#include "packet-tpkt.h"
+#include "packet-per.h"
+#include "packet-h225.h"
+#include <epan/t35.h>
+#include "h225-persistentdata.h"
+#include "packet-ber.h"
+#include "packet-h235.h"
+#include "packet-h245.h"
+
+#define PNAME "h225"
+#define PSNAME "H225"
+#define PFNAME "h225"
+
+#define UDP_PORT_RAS1 1718
+#define UDP_PORT_RAS2 1719
+#define TCP_PORT_CS 1720
+
+static void reset_h225_packet_info(h225_packet_info *pi);
+static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi);
+static int dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+static h225_packet_info h225_pi;
+
+static dissector_handle_t h225ras_handle;
+static dissector_handle_t H323UserInformation_handle;
+static dissector_handle_t data_handle;
+/* Subdissector tables */
+static dissector_table_t nsp_object_dissector_table;
+static dissector_table_t nsp_h221_dissector_table;
+static dissector_table_t tp_dissector_table;
+
+
+static dissector_handle_t h245_handle=NULL;
+static dissector_handle_t h245dg_handle=NULL;
+static dissector_handle_t h4501_handle=NULL;
+
+/* Initialize the protocol and registered fields */
+static int h225_tap = -1;
+static int proto_h225 = -1;
+
+static int hf_h225_H323_UserInformation = -1;
+static int hf_h225_RasMessage = -1;
+static int hf_h221Manufacturer = -1;
+static int hf_h225_ras_req_frame = -1;
+static int hf_h225_ras_rsp_frame = -1;
+static int hf_h225_ras_dup = -1;
+static int hf_h225_ras_deltatime = -1;
+static int hf_h225_fastStart_item_length = -1;
+
+#include "packet-h225-hf.c"
+
+/* Initialize the subtree pointers */
+static gint ett_h225 = -1;
+#include "packet-h225-ett.c"
+
+/* Global variables */
+static guint32 ipv4_address;
+static guint32 ipv4_port;
+guint32 T38_manufacturer_code;
+static gboolean h225_reassembly = TRUE;
+guint32 value;
+static gboolean contains_faststart = FALSE;
+
+#include "packet-h225-fn.c"
+
+
+static int
+dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *it;
+ proto_tree *tr;
+ int offset = 0;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)){
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.225.0");
+ }
+ if (check_col(pinfo->cinfo, COL_INFO)){
+ col_clear(pinfo->cinfo, COL_INFO);
+ }
+
+ it=proto_tree_add_protocol_format(tree, proto_h225, tvb, 0, tvb_length(tvb), "H.225.0 CS");
+ tr=proto_item_add_subtree(it, ett_h225);
+
+ offset = dissect_h225_H323_UserInformation(tvb, offset,pinfo, tr, hf_h225_H323_UserInformation);
+
+ return offset;
+}
+static int
+dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
+ proto_item *it;
+ proto_tree *tr;
+ guint32 offset=0;
+
+ /* Init struct for collecting h225_packet_info */
+ reset_h225_packet_info(&(h225_pi));
+ h225_pi.msg_type = H225_RAS;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)){
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.225.0");
+ }
+
+ it=proto_tree_add_protocol_format(tree, proto_h225, tvb, offset, tvb_length(tvb), "H.225.0 RAS");
+ tr=proto_item_add_subtree(it, ett_h225);
+
+ offset = dissect_h225_RasMessage(tvb, 0, pinfo,tr, hf_h225_RasMessage );
+
+ if (check_col(pinfo->cinfo, COL_INFO)){
+ col_add_fstr(pinfo->cinfo, COL_INFO, "RAS: %s ",
+ val_to_str(value, RasMessage_vals, "<unknown>"));
+ }
+
+ h225_pi.msg_tag = value;
+
+ ras_call_matching(tvb, pinfo, tr, &(h225_pi));
+
+ tap_queue_packet(h225_tap, pinfo, &h225_pi);
+
+ return offset;
+}
+/*--- proto_register_h225 -------------------------------------------*/
+void proto_register_h225(void) {
+
+ /* List of fields */
+ static hf_register_info hf[] = {
+ { &hf_h225_H323_UserInformation,
+ { "H323_UserInformation", "h225.H323_UserInformation", FT_NONE, BASE_NONE,
+ NULL, 0, "H323_UserInformation sequence", HFILL }},
+ { &hf_h225_RasMessage,
+ { "RasMessage", "h225.RasMessage", FT_UINT32, BASE_DEC,
+ VALS(RasMessage_vals), 0, "RasMessage choice", HFILL }},
+ { &hf_h221Manufacturer,
+ { "H.221 Manufacturer", "h221.Manufacturer", FT_UINT32, BASE_HEX,
+ VALS(H221ManufacturerCode_vals), 0, "H.221 Manufacturer", HFILL }},
+ { &hf_h225_ras_req_frame,
+ { "RAS Request Frame", "h225.ras.reqframe", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "RAS Request Frame", HFILL }},
+ { &hf_h225_ras_rsp_frame,
+ { "RAS Response Frame", "h225.ras.rspframe", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "RAS Response Frame", HFILL }},
+ { &hf_h225_ras_dup,
+ { "Duplicate RAS Message", "h225.ras.dup", FT_UINT32, BASE_DEC,
+ NULL, 0, "Duplicate RAS Message", HFILL }},
+ { &hf_h225_ras_deltatime,
+ { "RAS Service Response Time", "h225.ras.timedelta", FT_RELATIVE_TIME, BASE_NONE,
+ NULL, 0, "Timedelta between RAS-Request and RAS-Response", HFILL }},
+ { &hf_h225_fastStart_item_length,
+ { "fastStart item length", "h225.fastStart_item_length", FT_UINT32, BASE_DEC,
+ NULL, 0, "fastStart item length", HFILL }},
+
+#include "packet-h225-hfarr.c"
+ };
+
+ /* List of subtrees */
+ static gint *ett[] = {
+ &ett_h225,
+#include "packet-h225-ettarr.c"
+ };
+ module_t *h225_module;
+
+ /* Register protocol */
+ proto_h225 = proto_register_protocol(PNAME, PSNAME, PFNAME);
+ /* Register fields and subtrees */
+ proto_register_field_array(proto_h225, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ h225_module = prefs_register_protocol(proto_h225, NULL);
+ prefs_register_bool_preference(h225_module, "reassembly",
+ "Reassemble H.225 messages spanning multiple TCP segments",
+ "Whether the H.225 dissector should reassemble messages spanning multiple TCP segments."
+ " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
+ &h225_reassembly);
+
+ register_dissector("h225", dissect_h225_H323UserInformation, proto_h225);
+ register_dissector("h323ui",dissect_h225_H323UserInformation, proto_h225);
+
+ nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.225 NonStandardParameter (object)", FT_STRING, BASE_NONE);
+ nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.225 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
+ tp_dissector_table = register_dissector_table("h225.tp", "H.225 TunnelledProtocol", FT_STRING, BASE_NONE);
+
+ register_init_routine(&h225_init_routine);
+ h225_tap = register_tap("h225");
+ register_ber_oid_name("0.0.8.2250.0.2","itu-t(0) recommendation(0) h(8) h225-0(2250) version(0) 2");
+
+
+}
+
+
+/*--- proto_reg_handoff_h225 ---------------------------------------*/
+void
+proto_reg_handoff_h225(void)
+{
+ h225ras_handle=new_create_dissector_handle(dissect_h225_h225_RasMessage, proto_h225);
+ H323UserInformation_handle=new_create_dissector_handle(dissect_h225_H323UserInformation, proto_h225);
+
+ h245_handle = find_dissector("h245");
+ h245dg_handle = find_dissector("h245dg");
+ h4501_handle = find_dissector("h4501");
+ data_handle = find_dissector("data");
+
+ dissector_add("udp.port", UDP_PORT_RAS1, h225ras_handle);
+ dissector_add("udp.port", UDP_PORT_RAS2, h225ras_handle);
+}
+
+
+static void reset_h225_packet_info(h225_packet_info *pi)
+{
+ if(pi == NULL) {
+ return;
+ }
+
+ pi->msg_type = H225_OTHERS;
+ pi->cs_type = H225_OTHER;
+ pi->msg_tag = -1;
+ pi->reason = -1;
+ pi->requestSeqNum = 0;
+ memset(pi->guid,0,16);
+ pi->is_duplicate = FALSE;
+ pi->request_available = FALSE;
+ pi->is_faststart = FALSE;
+ pi->is_h245 = FALSE;
+ pi->h245_address = 0;
+ pi->h245_port = 0;
+}
+
+/*
+ The following function contains the routines for RAS request/response matching.
+ A RAS response matches with a request, if both messages have the same
+ RequestSequenceNumber, belong to the same IP conversation and belong to the same
+ RAS "category" (e.g. Admission, Registration).
+
+ We use hashtables to access the lists of RAS calls (request/response pairs).
+ We have one hashtable for each RAS category. The hashkeys consist of the
+ non-unique 16-bit RequestSequenceNumber and values representing the conversation.
+
+ In big capture files, we might get different requests with identical keys.
+ These requests aren't necessarily duplicates. They might be valid new requests.
+ At the moment we just use the timedelta between the last valid and the new request
+ to decide if the new request is a duplicate or not. There might be better ways.
+ Two thresholds are defined below.
+
+ However the decision is made, another problem arises. We can't just add those
+ requests to our hashtables. Instead we create lists of RAS calls with identical keys.
+ The hashtables for RAS calls contain now pointers to the first RAS call in a list of
+ RAS calls with identical keys.
+ These lists aren't expected to contain more than 3 items and are usually single item
+ lists. So we don't need an expensive but intelligent way to access these lists
+ (e.g. hashtables). Just walk through such a list.
+*/
+
+#define THRESHOLD_REPEATED_RESPONDED_CALL 300
+#define THRESHOLD_REPEATED_NOT_RESPONDED_CALL 1800
+
+static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi)
+{
+ conversation_t* conversation = NULL;
+ h225ras_call_info_key h225ras_call_key;
+ h225ras_call_t *h225ras_call = NULL;
+ nstime_t delta;
+ guint msg_category;
+
+ if(pi->msg_type == H225_RAS && pi->msg_tag < 21) {
+ /* make RAS request/response matching only for tags from 0 to 20 for now */
+
+ msg_category = pi->msg_tag / 3;
+ if(pi->msg_tag % 3 == 0) { /* Request Message */
+ conversation = find_conversation(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+
+ if (conversation == NULL) {
+ /* It's not part of any conversation - create a new one. */
+ conversation = conversation_new(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+
+ }
+
+ /* prepare the key data */
+ h225ras_call_key.reqSeqNum = pi->requestSeqNum;
+ h225ras_call_key.conversation = conversation;
+
+ /* look up the request */
+ h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
+
+ if (h225ras_call != NULL) {
+ /* We've seen requests with this reqSeqNum, with the same
+ source and destination, before - do we have
+ *this* request already? */
+ /* Walk through list of ras requests with identical keys */
+ do {
+ if (pinfo->fd->num == h225ras_call->req_num) {
+ /* We have seen this request before -> do nothing */
+ break;
+ }
+
+ /* if end of list is reached, exit loop and decide if request is duplicate or not. */
+ if (h225ras_call->next_call == NULL) {
+ if ( (pinfo->fd->num > h225ras_call->rsp_num && h225ras_call->rsp_num != 0
+ && pinfo->fd->abs_secs > (guint) (h225ras_call->req_time.secs + THRESHOLD_REPEATED_RESPONDED_CALL) )
+ ||(pinfo->fd->num > h225ras_call->req_num && h225ras_call->rsp_num == 0
+ && pinfo->fd->abs_secs > (guint) (h225ras_call->req_time.secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL) ) )
+ {
+ /* if last request has been responded
+ and this request appears after last response (has bigger frame number)
+ and last request occured more than 300 seconds ago,
+ or if last request hasn't been responded
+ and this request appears after last request (has bigger frame number)
+ and last request occured more than 1800 seconds ago,
+ we decide that we have a new request */
+ /* Append new ras call to list */
+ h225ras_call = append_h225ras_call(h225ras_call, pinfo, pi->guid, msg_category);
+ } else {
+ /* No, so it's a duplicate request.
+ Mark it as such. */
+ pi->is_duplicate = TRUE;
+ proto_tree_add_uint_hidden(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
+ }
+ break;
+ }
+ h225ras_call = h225ras_call->next_call;
+ } while (h225ras_call != NULL );
+ }
+ else {
+ h225ras_call = new_h225ras_call(&h225ras_call_key, pinfo, pi->guid, msg_category);
+ }
+
+ /* add link to response frame, if available */
+ if(h225ras_call->rsp_num != 0){
+ proto_item *ti =
+ proto_tree_add_uint_format(tree, hf_h225_ras_rsp_frame, tvb, 0, 0, h225ras_call->rsp_num,
+ "The response to this request is in frame %u",
+ h225ras_call->rsp_num);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+
+ /* end of request message handling*/
+ }
+ else { /* Confirm or Reject Message */
+ conversation = find_conversation(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+ if (conversation != NULL) {
+ /* look only for matching request, if
+ matching conversation is available. */
+ h225ras_call_key.reqSeqNum = pi->requestSeqNum;
+ h225ras_call_key.conversation = conversation;
+ h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
+ if(h225ras_call) {
+ /* find matching ras_call in list of ras calls with identical keys */
+ do {
+ if (pinfo->fd->num == h225ras_call->rsp_num) {
+ /* We have seen this response before -> stop now with matching ras call */
+ break;
+ }
+
+ /* Break when list end is reached */
+ if(h225ras_call->next_call == NULL) {
+ break;
+ }
+ h225ras_call = h225ras_call->next_call;
+ } while (h225ras_call != NULL) ;
+
+ /* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
+ if (msg_category == 3 || msg_category == 5) {
+ memcpy(pi->guid, h225ras_call->guid,16);
+ proto_tree_add_bytes_hidden(tree, hf_h225_guid, tvb, 0, 16, pi->guid);
+ }
+
+ if (h225ras_call->rsp_num == 0) {
+ /* We have not yet seen a response to that call, so
+ this must be the first response; remember its
+ frame number. */
+ h225ras_call->rsp_num = pinfo->fd->num;
+ }
+ else {
+ /* We have seen a response to this call - but was it
+ *this* response? */
+ if (h225ras_call->rsp_num != pinfo->fd->num) {
+ /* No, so it's a duplicate response.
+ Mark it as such. */
+ pi->is_duplicate = TRUE;
+ proto_tree_add_uint_hidden(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
+ }
+ }
+
+ if(h225ras_call->req_num != 0){
+ proto_item *ti;
+ h225ras_call->responded = TRUE;
+ pi->request_available = TRUE;
+
+ /* Indicate the frame to which this is a reply. */
+ ti = proto_tree_add_uint_format(tree, hf_h225_ras_req_frame, tvb, 0, 0, h225ras_call->req_num,
+ "This is a response to a request in frame %u", h225ras_call->req_num);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ /* Calculate RAS Service Response Time */
+ delta.secs= pinfo->fd->abs_secs-h225ras_call->req_time.secs;
+ delta.nsecs=pinfo->fd->abs_usecs*1000-h225ras_call->req_time.nsecs;
+ if(delta.nsecs<0){
+ delta.nsecs+=1000000000;
+ delta.secs--;
+ }
+ pi->delta_time.secs = delta.secs; /* give it to tap */
+ pi->delta_time.nsecs = delta.nsecs;
+
+ /* display Ras Service Response Time and make it filterable */
+ ti = proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time));
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+