Ethereal-dev: Re: [Ethereal-dev] Service Response Time for H.225 RAS
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Lars Roland" <Lars.Roland@xxxxxxx>
Date: Thu, 13 Nov 2003 00:26:42 +0100 (MET)
Hello, attached is an updated diff for packet-h225.c . It now contains a preference for deactivating RAS call matching. Please test. Regards, Lars
Index: ethereal/packet-h225.c =================================================================== RCS file: /cvsroot/ethereal/packet-h225.c,v retrieving revision 1.24 diff -u -r1.24 packet-h225.c --- ethereal/packet-h225.c 10 Nov 2003 21:42:38 -0000 1.24 +++ ethereal/packet-h225.c 12 Nov 2003 23:17:22 -0000 @@ -43,12 +43,14 @@ #include "packet-h225.h" #include "packet-h245.h" #include "t35.h" +#include "h225-persistentdata.h" #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 h225_packet_info h225_pi; @@ -524,6 +526,10 @@ static int hf_h225_nonStandardReason = -1; static int hf_h225_nonStandardAddress = -1; static int hf_h225_aliasAddress_sequence = -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; /*aaa*/ static gint ett_h225 = -1; @@ -1103,7 +1109,7 @@ static gboolean h225_reassembly = TRUE; - +static gboolean h225_ras_call_matching = TRUE; static int @@ -7150,7 +7156,10 @@ val_to_str(value, h323_message_body_vals, "<unknown>")); } - h225_pi.msg_tag = value; + if (h225_pi.msg_type == H225_CS) { + /* Don't override msg_tag value from IRR */ + h225_pi.msg_tag = value; + } if (contains_faststart == TRUE ) { @@ -8448,6 +8457,9 @@ val_to_str(value, RasMessage_vals, "<unknown>")); } h225_pi.msg_tag = value; + if(h225_ras_call_matching == TRUE) { + ras_call_matching(tvb, pinfo, tr, &(h225_pi)); + } tap_queue_packet(h225_tap, pinfo, &h225_pi); } @@ -9900,6 +9912,18 @@ { &hf_h225_nonStandardAddress, { "nonStandardAddress", "h225.nonStandardAddress", FT_NONE, BASE_NONE, NULL, 0, "NonStandardParameter SEQUENCE", 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 }}, /*ddd*/ }; @@ -10169,7 +10193,7 @@ &ett_h225_H221NonStandard, &ett_h225_NonStandardIdentifier, &ett_h225_NonStandardParameter, - &ett_h225_aliasAddress_sequence, + &ett_h225_aliasAddress_sequence, /*eee*/ }; module_t *h225_module; @@ -10182,11 +10206,16 @@ "Reassemble H.225 over TCP", "Whether the dissector should reassemble H.225 PDUs spanning multiple TCP segments", &h225_reassembly); + prefs_register_bool_preference(h225_module, "ras_call_matching", + "Enable RAS Request/Response matching (necessary for RAS Service Response Time)", + "Whether the dissector should try to match RAS responses with requests", + &h225_ras_call_matching); register_dissector("h225", dissect_h225_H323UserInformation, proto_h225); nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE); nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX); + register_init_routine(&h225_init_routine); h225_tap = register_tap("h225"); } @@ -10205,6 +10234,7 @@ dissector_add("udp.port", UDP_PORT_RAS2, h225ras_handle); } + static void reset_h225_packet_info(h225_packet_info *pi) { if(pi == NULL) { @@ -10216,4 +10246,191 @@ pi->reason = -1; pi->requestSeqNum = 0; memset(pi->guid,0,16); + pi->is_duplicate = FALSE; + pi->request_available = FALSE; } + +/* + 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 > 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 > 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_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); + } + + /* 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){ + h225ras_call->responded = TRUE; + pi->request_available = TRUE; + + /* Indicate the frame to which this is a reply. */ + 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); + + /* 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 */ + proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time)); + } + } + } + } + } +} \ No newline at end of file
- Prev by Date: Re: [Ethereal-dev] Ethereal DOCSIS plugin
- Next by Date: Re: [Ethereal-dev] Ethereal DOCSIS plugin
- Previous by thread: Re: [Ethereal-dev] Service Response Time for H.225 RAS
- Next by thread: [Ethereal-dev] Questions about a few code fragments
- Index(es):