Ethereal-dev: [Ethereal-dev] New OSI Session dissector.
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Sid Sid" <ysidelnikov@xxxxxxxxxxx>
Date: Mon, 27 Oct 2003 11:07:17 +0000
Hi,I've added some additional checking and used a value_string table where it makes sense.
Fixed casting to void and so on. Thanks. Yuriy.
From: Guy Harris <guy@xxxxxxxxxxxx> To: Sid Sid <ysidelnikov@xxxxxxxxxxx> CC: ethereal-dev@xxxxxxxxxxxx Subject: Re: [Ethereal-dev] New OSI Session dissector. Date: Fri, 26 Sep 2003 15:57:28 -0700 On Sep 25, 2003, at 1:01 PM, Sid Sid wrote:Please, have a look at attachment.It returns FALSE even if the packet is a session packet, except when it appears to return a number rather than a true/false value.The only check it does is to check whether the packet is at least 4 bytes long; that's not enough - that means that it could accept packets that aren't session-layer packets, which means that other heuristic dissectors for COTP, such as the SMB dissector, might not get a chance to check whether the packet is one of theirs.If it's not possible to have a good heuristic to check for OSI Session packets, perhaps the COTP dissector should try its heuristics and, if none of them match, try the session dissector.It also casts "dissect_ses" to a "void *", which hides the compiler errors that would have detected the original problem. Remove those casts, and either fix or remove the lines that get errors or warnings as a result of that change. (All the lines I saw could just be removed.)Note also that you have a number of places where you do a "switch()" on some value and select a constant string based on the value; that's probably best done using a value_string table - especially if the value has a field associated with it, because you can then associate that value_string table with the field._______________________________________________ Ethereal-dev mailing list Ethereal-dev@xxxxxxxxxxxx http://www.ethereal.com/mailman/listinfo/ethereal-dev
_________________________________________________________________MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. http://join.msn.com/?page=features/virus
/* packet-ses.c * * Routine to dissect ISO 8327-1 OSI Session Protocol packets * * $Id: packet-ses.c,v 1.00 2003/09/01 21:00:36 * * Yuriy Sidelnikov <YSidelnikov@xxxxxxxxxxx> * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxxxx> * 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.
*/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <glib.h> #include <epan/packet.h> #include <stdio.h> #include <string.h> #include "packet-tpkt.h" #include "packet-ses.h" #include "packet-frame.h" #include "prefs.h" #include <epan/strutil.h> #include "etypes.h" /* ses header fields */ static int proto_ses = -1; static int hf_ses_version = -1; static int hf_ses_reserved = -1; static int hf_ses_length = -1; static proto_tree *ses_tree = NULL; /* ses fields defining a sub tree */ static gint ett_ses = -1;/* ----------------------------------------------------------------------------------------------------------*/
static dissector_handle_t pres_handle = NULL;/* ----------------------------------------------------------------------------------------------------------*/
/* flags */ static int hf_connect_protocol_options_flags = -1; static int hf_session_user_req_flags = -1; static int hf_version_number_options_flags = -1; static int hf_enclosure_item_options_flags = -1; static int hf_token_item_options_flags = -1; static gint ett_connect_protocol_options_flags = -1; static gint ett_protocol_version_flags = -1; static gint ett_enclosure_item_flags = -1; static gint ett_token_item_flags = -1; static gint ett_ses_req_options_flags = -1; static int able_to_receive_extended_concatenated_SPDU = -1; static int half_duplex_function_unit = -1; static int duplex_function_unit= -1; static int session_exception_report= -1; static int data_separation_function_unit= -1; static int symmetric_syncronize_function_unit= -1; static int typed_data_function_unit= -1; static int exception_function_unit= -1; static int negotiated_relese_function_unit= -1; static int activity_management_function_unit= -1; static int resyncronize_function_unit= -1; static int major_resyncronize_function_unit= -1; static int minor_resyncronize_function_unit= -1; static int expedited_data_resyncronize_function_unit= -1; static int capability_function_unit=-1; /* protocol version */ static int protocol_version_1 = -1; static int protocol_version_2 = -1; /* enclosure item */ static int beginning_of_SSDU = -1; static int end_of_SSDU = -1; /* token item */ static int release_token = -1; static int major_activity_token = -1; static int syncronize_minor_token = -1; static int data_token = -1; static const value_string ses_vals[] = { {SES_CONNECTION_REQUEST, "Connection request PDU" }, {SES_CONNECTION_ACCEPT, "Connection accept PDU" }, {SES_EXCEPTION_REPORT, "Exception report PDU" }, {SES_DATA_TRANSFER, "Data transfer PDU" }, {SES_PLEASE_TOKENS, "Please tokens PDU" }, {SES_EXPEDITED, "Expedited PDU" }, {SES_PREPARE, "Prepare PDU" }, {SES_NOT_FINISHED, "Not finished PDU" }, {SES_FINISH, "Finish PDU" }, {SES_DISCONNECT, "Disconnect PDU" }, {SES_REFUSE, "Refuse PDU" }, {SES_CONNECTION_DATA_OVERFLOW, "Data overflow PDU" }, {SES_OVERFLOW_ACCEPT, "Overflow accept PDU" }, {SES_GIVE_TOKENS_CONFIRM, "Tokens confirm PDU" }, {SES_GIVE_TOKENS_ACK, "Give tokens ACK PDU" }, {SES_ABORT, "Abort PDU" }, {SES_ABORT_ACCEPT, "Abort accept PDU" }, {SES_ACTIVITY_RESUME, "Activity resume PDU" }, {SES_TYPED_DATA, "Typed data PDU" }, {SES_RESYNCHRONIZE_ACK, "Resynchronize ACK PDU" }, {SES_MAJOR_SYNC_POINT, "Session major sync point PDU" }, {SES_MAJOR_SYNC_ACK, "Session major sync ACK PDU" }, {SES_ACTIVITY_START, "Activity start PDU" }, {SES_EXCEPTION_DATA, "Exception data PDU" }, {SES_MINOR_SYNC_POINT, "Minor sync point PDU" }, {SES_MINOR_SYNC_ACK, "Minor sync ACK PDU" }, {SES_RESYNCHRONIZE, "Resynchronize PDU" }, {SES_ACTIVITY_DISCARD, "Activity discard PDU" }, {SES_ACTIVITY_DISCARD_ACK, "Activity discard ACK PDU" }, {SES_CAPABILITY, "Capability PDU" }, {SES_CAPABILITY_DATA_ACK, "Capability data ACK PDU" }, {0, NULL } }; static const value_string reason_vals[] = {{reason_not_specified, "Reason Code: Rejection by called SS-user; reason not specified" }, {temporary_congestion, "Reason Code: Rejection by called SS-user due to temporary congestion" },
{Subsequent, "Reason Code: Rejection by called SS-user." }, {Session_Selector_unknown, "Reason Code: Session Selector unknown" },{SS_user_not_attached_to_SSAP, "Reason Code: SS-user not attached to SSAP" }, {SPM_congestion_at_connect_time, "Reason Code: SPM congestion at connect time" }, {versions_not_supported, "Reason Code: Proposed protocol versions not supported" }, {SPM_reason_not_specified, "Reason Code: Rejection by the SPM; reason not specified" },
{SPM_implementation_restriction, "Finish PDU" },{SES_DISCONNECT, "Reason Code: Rejection by the SPM; implementation restriction stated in the PICS" },
{0, NULL } }; /* desegmentation of OSI over ses */ /*static gboolean ses_desegment = TRUE;*/ /* find the dissector for data */ static dissector_handle_t data_handle; /*static struct SES_PDU* reply_pdu;*/ /* function declaration */int print_item(struct PGI_PI_UNIT* parms,tvbuff_t *tvb,int offset,proto_tree *tree,packet_info *pinfo);
char * string_to_hex(unsigned char * in,char * out,int len) { char ascii[MAXSTRING]; int i; memset(&ascii,0x00,sizeof(ascii)); for(i=0;i<len;i++) { unsigned char o_out = *(in+i); sprintf(out+(i<<1),"%.2x",* (in+i)); if( ( (o_out) >= 'a') & ( (o_out) <='z') || ( (o_out) >= 'A') & ( (o_out) <='Z') || ( (o_out) >= '0') & ( (o_out) <='9') ) { ascii[i] = o_out; } else { ascii[i] = '.'; } } strcat(out," "); strcat(out,ascii); return out; } /* this program returns length of session PDU */ int get_item_len(struct PGI_PI_UNIT* unit) { if( unit->len == TWO_BYTE_LEN) { struct CHAR_SHORT item_len; item_len.data[0] = *( (((char*)(unit)) +2 )); item_len.data[1] = *( (((char*)(unit)) +3 )); return g_ntohs( item_len.short_data ); } return unit->len; } /* this program returns address of next PGI/PI */ struct PGI_PI_UNIT* get_data_address(struct PGI_PI_UNIT* parms) { if( parms->len == TWO_BYTE_LEN) { return (struct PGI_PI_UNIT*) &parms->data1; } else { return (struct PGI_PI_UNIT*)&parms->data; } } /* this program returns address of next PI item */ struct PGI_PI_UNIT* get_next_PI(struct PGI_PI_UNIT* parms) { if( parms->len == TWO_BYTE_LEN) { return (struct PGI_PI_UNIT*) (&parms->data1+get_item_len(parms) ); } else { return (struct PGI_PI_UNIT*) (&parms->data+get_item_len(parms) ); } } int get_len_len(struct PGI_PI_UNIT* parms) { if( parms->len == TWO_BYTE_LEN) { return 4; } else { return 2; } }int print_pgi(struct PGI_PI_UNIT* parm,tvbuff_t *tvb,int offset,proto_tree *tree,packet_info *pinfo)
{ int res; /* get total PGI data lenght */ int len = get_item_len(parm) ; /*- (get_len_len(parm)); */ /* get data address into PGI */ struct PGI_PI_UNIT* parms = get_data_address(parm); offset = offset + get_len_len(parm); while(len > 0) { if( (res = print_item( parms,tvb,offset,tree,pinfo) ) ) { return res; } /* next item */ len = len - (get_item_len(parms)+get_len_len(parms)) ; offset = offset + get_item_len(parms)+get_len_len(parms); parms = get_next_PI(parms) ; continue; } return FALSE; }int print_item(struct PGI_PI_UNIT* parms,tvbuff_t *tvb,int offset,proto_tree *tree,packet_info *pinfo)
{ char tmp[MAXSTRING]; proto_item *tf; gchar *reason_str; int len = get_item_len((struct PGI_PI_UNIT*)parms); switch(parms->type) { case Called_SS_user_Reference: sprintf(tmp,"Called SS user Reference:"); break; case Calling_SS_user_Reference: sprintf(tmp,"Calling SS user Reference:"); break; case Common_Reference: sprintf(tmp,"Common Reference:"); break; case Additional_Reference_Information: sprintf(tmp,"Additional Reference Information:"); break; case Sync_Type_Item: sprintf(tmp,"Sync Type Item:"); break; case Token_Item: sprintf(tmp,"Token Item:"); if (tree) { guint8 flags = 0; proto_tree *flags_tree=NULL; proto_tree_add_text(ses_tree, tvb, offset, len+2,tmp); flags = *( (guint8*) get_data_address(parms)) ;tf = proto_tree_add_uint_format(ses_tree, hf_token_item_options_flags, tvb, offset + 2, 1,
flags, "Flags: 0x%02x", flags); flags_tree = proto_item_add_subtree(tf, ett_token_item_flags);proto_tree_add_boolean(flags_tree, release_token, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, major_activity_token, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, syncronize_minor_token, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, data_token, tvb, offset+2, 1, flags);
} return FALSE; case Transport_Disconnect: sprintf(tmp,"Transport_Disconnect:"); if (tree) {proto_tree_add_text(ses_tree, tvb, offset, 1,"%s0x%02x",tmp,parms->type);
} if(parms->data & transport_connection_is_released ) { sprintf(tmp,"transport connection is released"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } else { sprintf(tmp,"transport connection is kept"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } if(parms->data & user_abort ) { sprintf(tmp,"user abort"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } if(parms->data & protocol_error ) { sprintf(tmp,"protocol error"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } if(parms->data & no_reason ) { sprintf(tmp,"no reason"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } if(parms->data & implementation_restriction ) { sprintf(tmp,"implementation restriction"); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); } return FALSE; break; case Protocol_Options: sprintf(tmp,"Protocol Options:"); if (tree) { guint8 flags = 0; proto_tree *flags_tree=NULL; proto_tree_add_text(ses_tree, tvb, offset, len+2,tmp); flags = *( (guint8*) get_data_address(parms)) ;tf = proto_tree_add_uint_format(ses_tree, hf_connect_protocol_options_flags, tvb, offset + 2, 1,
flags, "Flags: 0x%02x", flags);flags_tree = proto_item_add_subtree(tf, ett_connect_protocol_options_flags); proto_tree_add_boolean(flags_tree, able_to_receive_extended_concatenated_SPDU, tvb, offset+2, 1, flags);
} return FALSE; case TSDU_Maximum_Size: sprintf(tmp,"TSDU Maximum Size:"); break; case Version_Number: sprintf(tmp,"Version Number:"); if (tree) { guint8 flags = 0; proto_tree *flags_tree=NULL; proto_tree_add_text(ses_tree, tvb, offset, len+2,tmp); flags = *( (guint8*) get_data_address(parms)) ;tf = proto_tree_add_uint_format(ses_tree, hf_version_number_options_flags, tvb, offset + 2, 1,
flags, "Flags: 0x%02x", flags); flags_tree = proto_item_add_subtree(tf, ett_protocol_version_flags);proto_tree_add_boolean(flags_tree, protocol_version_2, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, protocol_version_1, tvb, offset+2, 1, flags);
} return FALSE; case Initial_Serial_Number: sprintf(tmp,"Initial Serial Number:"); break; case Prepare_Type: sprintf(tmp,"Prepare Type:"); break; case EnclosureItem: sprintf(tmp,"Enclosure Item:"); if (tree) { guint8 flags = 0; proto_tree *flags_tree=NULL; proto_tree_add_text(ses_tree, tvb, offset, len+2,tmp); flags = *( (guint8*) get_data_address(parms)) ;tf = proto_tree_add_uint_format(ses_tree, hf_enclosure_item_options_flags, tvb, offset + 2, 1,
flags, "Flags: 0x%02x", flags); flags_tree = proto_item_add_subtree(tf, ett_enclosure_item_flags);proto_tree_add_boolean(flags_tree, end_of_SSDU, tvb, offset+2, 1, flags); proto_tree_add_boolean(flags_tree, beginning_of_SSDU, tvb, offset+2, 1, flags);
} return FALSE; case Token_Setting_Item: sprintf(tmp,"Token Setting Item:"); break; case Resync_Type: sprintf(tmp,"Resync Type:"); break; case Reason_Code: /* 0: Rejection by called SS-user; reason not specified. 1: Rejection by called SS-user due to temporary congestion.2: Rejection by called SS-user. Subsequent octets may be used for user data up to a length of 512 octets if Protocol Version 1 has been selected, and up to a length such that the total length (including SI and LI) of the SPDU does not exceed 65 539 octets if Protocol Version 2 has been selected.
128 + 1: Session Selector unknown. 128 + 2: SS-user not attached to SSAP. 128 + 3: SPM congestion at connect time. 128 + 4: Proposed protocol versions not supported. 128 + 5: Rejection by the SPM; reason not specified.128 + 6: Rejection by the SPM; implementation restriction stated in the PICS. */
if (!(reason_str = match_strval(parms->data, reason_vals))) {if (tree) proto_tree_add_text(ses_tree, tvb, offset, 2,"Reason Code: Unknown %d",parms->data);
} else { if (tree) proto_tree_add_text(ses_tree, tvb, offset, 2,reason_str); } /* do we have what to send to next dissector */ if (!tvb_bytes_exist(tvb, 0, 4)) return FALSE; /* No */ /* yes, call sub dissector. */ if(!pres_handle) { /* print as data */ offset = offset + get_len_len(parms);call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
offset += tvb_length_remaining(tvb, offset); } else { /* call presentation dissector */ tvbuff_t *next_tvb; offset = offset + get_len_len(parms); next_tvb = tvb_new_subset(tvb, offset, -1, -1); TRY { call_dissector(pres_handle, next_tvb, pinfo, tree); } CATCH(BoundsError) { show_reported_bounds_error(tvb, pinfo, tree); RETHROW; } CATCH(ReportedBoundsError) { show_reported_bounds_error(tvb, pinfo, tree); } ENDTRY; } return parms->len-1; break; case Calling_Session_Selector: sprintf(tmp,"Calling Session Selector:"); break; case Called_Session_Selector: sprintf(tmp,"Called Session Selector:"); break; case Second_Resync_Type: sprintf(tmp,"Second Resync Type:"); break; case Second_Serial_Number: sprintf(tmp,"Second Serial Number:"); break; case Second_Initial_Serial_Number: sprintf(tmp,"Second Initial Serial Number:"); break; case Upper_Limit_Serial_Number: sprintf(tmp,"Upper Limit Serial Number:"); break; case Large_Initial_Serial_Number: sprintf(tmp,"Large Initial Serial Number:"); break; case Large_Second_Initial_Serial_Number: sprintf(tmp,"Large Second Initial Serial Number:"); break; case Data_Overflow: sprintf(tmp,"Data Overflow:"); break; case Session_Requirement: sprintf(tmp,"Session Requirement:"); if (tree) { guint16 flags=0; proto_tree *flags_tree=NULL; struct CHAR_SHORT flg; proto_tree_add_text(ses_tree, tvb, offset, len+2,tmp); flg.data[0] = *( (guint8*) get_data_address(parms)); flg.data[1] = *( ((guint8*) get_data_address(parms)) +1); flags = g_ntohs(flg.short_data) ;tf = proto_tree_add_uint_format(ses_tree, hf_session_user_req_flags, tvb, offset + 2, 2,
flags, "Flags: 0x%04x", flags); flags_tree = proto_item_add_subtree(tf, ett_ses_req_options_flags);proto_tree_add_boolean(flags_tree, session_exception_report, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, data_separation_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, symmetric_syncronize_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, typed_data_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, exception_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, capability_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, negotiated_relese_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, activity_management_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, resyncronize_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, major_resyncronize_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, minor_resyncronize_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, expedited_data_resyncronize_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, half_duplex_function_unit, tvb, offset+2, 2, flags); proto_tree_add_boolean(flags_tree, duplex_function_unit, tvb, offset+2, 2, flags);
} return FALSE; case Reflect_Parameter: sprintf(tmp,"Reflect Parameter:"); break; default: sprintf(tmp,"Unknown session parameter:0x%02x",parms->type); break; } if (tree) { char tm[MAXSTRING]; memset(&tm,0x00,sizeof(tmp));string_to_hex( (unsigned char*) get_data_address(parms),tm,get_item_len(parms)); proto_tree_add_text(ses_tree, tvb, offset, get_len_len(parms)+get_item_len(parms),"%s0x%s",tmp,tm );
} return FALSE; }int print_ses_parameters(struct PGI_PI_UNIT* parm,int g_len,tvbuff_t *tvb,int offset,proto_tree *tree,packet_info *pinfo)
{ char tmp[MAXSTRING]; int res; while(g_len > 0) { int len = get_item_len(parm); if(parm->type == EXTENDED_USER_DATA ) { sprintf(tmp,"Session extended user data:");if (tree) proto_tree_add_text(ses_tree, tvb, offset+get_len_len(parm), len,tmp);
return TRUE; } if(parm->type == SES_USER_DATA ) { sprintf(tmp,"Session user data:"); /* do we have OSI presentation packet dissector ? */ if(!pres_handle) { /* print as data */ sprintf(tmp,"User data:");if (tree) proto_tree_add_text(ses_tree, tvb, offset+get_len_len(parm), len,tmp);
} else { /* call presentation dissector */ tvbuff_t *next_tvb; offset = offset + get_len_len(parm);next_tvb = tvb_new_subset(tvb, offset, offset+get_len_len(parm), len);
TRY { call_dissector(pres_handle, next_tvb, pinfo, tree); } CATCH(BoundsError) { show_reported_bounds_error(tvb, pinfo, tree); RETHROW; } CATCH(ReportedBoundsError) { show_reported_bounds_error(tvb, pinfo, tree); } ENDTRY; } return TRUE; } /* is it PGI ? */ if(parm->type == Connect_Accept_Item || parm->type == Connection_Identifier || parm->type == Linking_Information ) { switch(parm->type) { case Connect_Accept_Item: sprintf(tmp,"Connect/Accept Item:0x%02x",parm->type);if (tree) proto_tree_add_text(ses_tree, tvb, offset, get_item_len( (struct PGI_PI_UNIT*) parm)+get_len_len((struct PGI_PI_UNIT*)parm),tmp);
break; case Connection_Identifier: sprintf(tmp,"Connection identifier:0x%02x",parm->type); if (tree) proto_tree_add_text(ses_tree, tvb, offset, 1,tmp); break; case Linking_Information: sprintf(tmp,"Linking information:0x%02x",parm->type); if (tree) proto_tree_add_text(ses_tree, tvb, offset, 1,tmp); break; } if( (res = print_pgi(parm,tvb,offset,tree,pinfo) ) ) { return res; } g_len= g_len - (get_item_len(parm)+get_len_len(parm)); offset = offset + get_item_len(parm)+get_len_len(parm); parm = get_next_PI( parm); continue; } /* it should be PI */ if( (res = print_item( parm,tvb,offset,tree,pinfo)) ) { return res; } g_len= g_len - (get_item_len(parm)+get_len_len(parm)); offset = offset + get_item_len(parm)+get_len_len(parm); parm = get_next_PI( parm); continue; } /* do we have what to send to next dissector */ if (!tvb_bytes_exist(tvb, 0, 4)) return FALSE; /* No */ /* yes, call sub dissector. */ if(!pres_handle) { /* print as data */call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
offset += tvb_length_remaining(tvb, offset); } else { /* call presentation dissector */ tvbuff_t *next_tvb; offset = offset + get_len_len(parm); next_tvb = tvb_new_subset(tvb, offset, -1, -1); TRY { call_dissector(pres_handle, next_tvb, pinfo, tree); } CATCH(BoundsError) { show_reported_bounds_error(tvb, pinfo, tree); RETHROW; } CATCH(ReportedBoundsError) { show_reported_bounds_error(tvb, pinfo, tree); } ENDTRY; } return FALSE; } int print_spdu(tvbuff_t *tvb,int offset,proto_tree *tree,packet_info *pinfo) { /* print length */ char tmp[MAXSTRING]; int total_len=0; struct PGI_PI_UNIT* parms; /* get total len of spdu */ unsigned char len_type = tvb_get_guint8(tvb, offset+1); if( len_type == TWO_BYTE_LEN) { total_len = tvb_get_ntohs(tvb, offset+2); sprintf(tmp,"User data len: 0x%02x",(total_len) ); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 3,tmp); parms = (struct PGI_PI_UNIT*) tvb_get_ptr(tvb, offset+4, total_len); offset = offset + 4; } else { total_len = len_type; sprintf(tmp,"User data len: 0x%x",(total_len) ); if (tree) proto_tree_add_text(ses_tree, tvb, offset+1, 1,tmp); parms = (struct PGI_PI_UNIT*) tvb_get_ptr(tvb, offset+2, total_len); offset = offset + 2; } return print_ses_parameters( parms,total_len,tvb,offset,tree,pinfo); } /* * Dissect ses-encapsulated data in a SES stream. */ static void dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { // char tmp[MAXSTRING]; proto_item *ti = NULL; unsigned char type = 0; volatile int offset = 0; gchar *ses_str; /* get SPDU type */ type = tvb_get_guint8(tvb, offset); /* check SPDU type */ if (!(ses_str = match_strval(type, ses_vals))) { ses_str = "Unknown Spdu type"; } ti = proto_tree_add_item(tree, proto_ses, tvb,offset, -1, FALSE); ses_tree = proto_item_add_subtree(ti, ett_ses); if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, ""); pinfo->current_proto = "SES"; if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, PROTO_STRING_SES_INFO); if ( check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "SES"); if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, ses_str); if (tree) { proto_tree_add_text(ses_tree, tvb, offset, 1,"%s:0x%02x",ses_str,type); } /* print session pdu */ print_spdu(tvb,offset,tree,pinfo); return ; } void proto_register_ses(void) { static hf_register_info hf[] = { { &hf_ses_version, { "Version", "ses.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL } }, { &hf_ses_reserved, { "Reserved", "ses.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL } }, { &hf_ses_length, { "Length", "ses.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } }, { &expedited_data_resyncronize_function_unit, { "expedited data function unit", "ses.expedited.data", FT_BOOLEAN, 16, NULL, EXPEDITED_DATA_FUNCTION_UNIT, "expedited data function unit", HFILL } }, { &minor_resyncronize_function_unit, { "minor resyncronize function unit", "ses.minor.resyncronize", FT_BOOLEAN, 16, NULL, MINOR_SYNCRONIZE_FUNCTION_UNIT, "minor resyncronize function unit", HFILL } }, { &major_resyncronize_function_unit, { "major resyncronize function unit", "ses.major.resyncronize", FT_BOOLEAN, 16, NULL, MAJOR_SYNCRONIZE_FUNCTION_UNIT, "major resyncronize function unit", HFILL } }, { &resyncronize_function_unit, { "resyncronize function unit", "ses.resyncronize", FT_BOOLEAN, 16, NULL, RESYNCRONIZE_FUNCTION_UNIT, "resyncronize function unit", HFILL } }, { &activity_management_function_unit, { "activity management function unit", "ses.activity.management", FT_BOOLEAN, 16, NULL, ACTIVITY_MANAGEMENT_FUNCTION_UNIT, "activity management function unit", HFILL } }, { &negotiated_relese_function_unit, { "negotiated relese function unit", "ses.negotiated.relese", FT_BOOLEAN, 16, NULL, NEGOTIATED_RELEASE_FUNCTION_UNIT, "negotiated relese function unit", HFILL } }, { &capability_function_unit, { "capability function unit", "ses.capability.data", FT_BOOLEAN, 16, NULL, CAPABILITY_DATA_FUNCTION_UNIT, "capability function unit", HFILL } }, { &exception_function_unit, { "exception function unit", "ses.exception.data", FT_BOOLEAN, 16, NULL, EXCEPTION_FUNCTION_UNIT, "exception function unit", HFILL } }, { &typed_data_function_unit, { "typed data function unit", "ses.typed.data", FT_BOOLEAN, 16, NULL, TYPED_DATA_FUNCTION_UNIT, "typed data function unit", HFILL } }, { &symmetric_syncronize_function_unit, { "symmetric syncronize function unit", "ses.symm.sync", FT_BOOLEAN, 16, NULL, SYMMETRIC_SYNCRONIZE_FUNCTION_UNIT, "symmetric syncronize function unit", HFILL } }, { &data_separation_function_unit, { "data separation function unit", "ses.data.sep", FT_BOOLEAN, 16, NULL, DATA_SEPARATION_FUNCTION_UNIT, "data separation function unit", HFILL } }, { &session_exception_report, { "session exception report", "ses.exception.report.", FT_BOOLEAN, 16, NULL, SES_EXCEPTION_REPORT, "session exception report", HFILL } }, { &duplex_function_unit, { "half duplex functional unit", "ses.duplex", FT_BOOLEAN, 16, NULL, HALF_DUPLEX_FUNCTION_UNIT, "half duplex functional unit", HFILL } }, { &half_duplex_function_unit, { "duplex functional unit", "ses.half.duplex", FT_BOOLEAN, 16, NULL, DUPLEX_FUNCTION_UNIT, "duplex functional unit", HFILL } }, { &able_to_receive_extended_concatenated_SPDU, { "Able to receive extended concatenated SPDU", "ses.connect.f1", FT_BOOLEAN, 8, NULL, SES_EXT_CONT, "Able to receive extended concatenated SPDU", HFILL } }, { &beginning_of_SSDU, { "beginning of SSDU", "ses.begininng.SPDU", FT_BOOLEAN, 8, NULL, BEGINNING_SPDU, "beginning of SSDU", HFILL } }, { &end_of_SSDU, { "end of SSDU", "ses.end.SPDU", FT_BOOLEAN, 8, NULL, END_SPDU, "end of SSDU", HFILL } }, { &major_activity_token, { "major/activity token", "ses.major.token", FT_BOOLEAN, 8, NULL, MAJOR_ACTIVITY_TOKEN, "major/activity token", HFILL } }, { &syncronize_minor_token, { "syncronize minor token", "ses.syncronize.token", FT_BOOLEAN, 8, NULL, SYNCRONIZE_MINOR_TOKEN, "syncronize minor token", HFILL } }, { &data_token, { "data token", "ses.data.token", FT_BOOLEAN, 8, NULL, DATA_TOKEN, "data token", HFILL } }, { &release_token, { "release token", "ses.release.token", FT_BOOLEAN, 8, NULL, RELEASE_TOKEN, "release token", HFILL } }, { &protocol_version_1, { "Protocol Version 1", "ses.protocol.version2", FT_BOOLEAN, 8, NULL, PROTOCOL_VERSION_1, "Protocol Version 1", HFILL } }, { &protocol_version_2, { "Protocol Version 2", "ses.protocol.version2", FT_BOOLEAN, 8, NULL, PROTOCOL_VERSION_2, "Protocol Version 2", HFILL } }, { &hf_connect_protocol_options_flags, { "Flags", "ses.connect.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } }, { &hf_version_number_options_flags, { "Flags", "ses.version.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } }, { &hf_token_item_options_flags, { "Flags", "ses.tken_item.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } }, { &hf_enclosure_item_options_flags, { "Flags", "ses.enclosure.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } }, { &hf_session_user_req_flags, { "Flags", "ses.req.flags", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } }, }; static gint *ett[] = { &ett_ses, &ett_connect_protocol_options_flags, &ett_protocol_version_flags, &ett_enclosure_item_flags, &ett_token_item_flags, &ett_ses_req_options_flags, }; module_t *ses_module; proto_ses = proto_register_protocol(PROTO_STRING_SES, "SES", "ses"); proto_register_field_array(proto_ses, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); ses_module = prefs_register_protocol(proto_ses, NULL); /* prefs_register_bool_preference(ses_module, "desegment", "Desegment all session packets ","Whether the ses dissector should desegment all messages spanning multiple SES segments",
&ses_desegment); */ /* * Register the dissector by name, so other dissectors can * grab it by name rather than just referring to it directly * (you can't refer to it directly from a plugin dissector * on Windows without stuffing it into the Big Transfer Vector). */ register_dissector("ses", dissect_ses, proto_ses); } static gboolean dissect_ses_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { /* must check that this really is a ses packet */ unsigned char type = 0; volatile int offset = 0; int len=0; struct PGI_PI_UNIT* parms; gchar *ses_str; /* first, check do we have at least 4 bytes */ if (!tvb_bytes_exist(tvb, 0, 4)) return FALSE; /* no */ /* OK,let's check SPDU length */ /* get at least 4 bytes */ parms = (struct PGI_PI_UNIT*) tvb_get_ptr(tvb, offset, 4); /* get length of SPDU */ len = get_item_len((struct PGI_PI_UNIT*)parms); /* do we have enough bytes ? */ if (!tvb_bytes_exist(tvb, 0, len)) return FALSE; /* no */ /* can we regognize session PDU ? Return FALSE if not */ /* get SPDU type */ type = tvb_get_guint8(tvb, offset); /* check SPDU type */ if (!(ses_str = match_strval(type, ses_vals))) { return FALSE; /* no, it isn't a session PDU */ } dissect_ses(tvb, pinfo, parent_tree); return TRUE; } void proto_reg_handoff_ses(void) { dissector_handle_t ses_handle; /* find data dissector */ data_handle = find_dissector("data"); ses_handle = create_dissector_handle(dissect_ses, proto_ses); /* define sub dissector */ pres_handle = find_dissector("pres"); /* add our session dissector to cotp dissector list */ heur_dissector_add("cotp", dissect_ses_heur, proto_ses); }
/* packet-ses.h * * Routine to dissect ISO 8327-1 OSI Session Protocol packets * * * $Id: packet-ses.h,v 1.0 2003/09/01 21:00:36 * Yuriy Sidelnikov <YSidelnikov@xxxxxxxxxxx> * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxxxx> * 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.
*/ #define PROTO_STRING_SES "ISO 8327-1 OSI Session Protocol" #define PROTO_STRING_SES_INFO "ISO 8327-1 OSI Session Protocol." /* * Dissect ses-encapsulated data in a TCP stream. */ static void dissect_ses(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); /* max string lenght */ #define MAXSTRING 1024 /* session parms*/ #define SES_EXT_CONT 0x01 /* protocol versions */ #define PROTOCOL_VERSION_1 0x01 #define PROTOCOL_VERSION_2 0x02 /* enclosure item */ #define BEGINNING_SPDU 0x01 #define END_SPDU 0x02 #define DATA_TOKEN 0x01 #define RELEASE_TOKEN 0x40 #define SYNCRONIZE_MINOR_TOKEN 0x04 #define MAJOR_ACTIVITY_TOKEN 0x10 /* session user req flag */ #define HALF_DUPLEX_FUNCTION_UNIT 0x0001 #define DUPLEX_FUNCTION_UNIT 0x0002 #define EXPEDITED_DATA_FUNCTION_UNIT 0x0004 #define MINOR_SYNCRONIZE_FUNCTION_UNIT 0x0008 #define MAJOR_SYNCRONIZE_FUNCTION_UNIT 0x0010 #define RESYNCRONIZE_FUNCTION_UNIT 0x0020 #define ACTIVITY_MANAGEMENT_FUNCTION_UNIT 0x0040 #define NEGOTIATED_RELEASE_FUNCTION_UNIT 0x0080 #define CAPABILITY_DATA_FUNCTION_UNIT 0x0100 #define EXCEPTION_FUNCTION_UNIT 0x0200 #define TYPED_DATA_FUNCTION_UNIT 0x0400 #define SYMMETRIC_SYNCRONIZE_FUNCTION_UNIT 0x0800 #define DATA_SEPARATION_FUNCTION_UNIT 0x1000 #define SES_EXCEPTION_REPORT 0x2000 /*define SES_EXCEPTION_REPORT 0 */ #define SES_DATA_TRANSFER 1 #define SES_GIVE_TOKEN 1 #define SES_PLEASE_TOKENS 2 #define SES_EXPEDITED 5 #define SES_PREPARE 7 #define SES_NOT_FINISHED 8 #define SES_FINISH 9 #define SES_DISCONNECT 10 #define SES_REFUSE 12 #define SES_CONNECTION_REQUEST 13 #define SES_CONNECTION_ACCEPT 14 #define SES_CONNECTION_DATA_OVERFLOW 15 #define SES_OVERFLOW_ACCEPT 16 #define SES_GIVE_TOKENS_CONFIRM 21 #define SES_GIVE_TOKENS_ACK 22 #define SES_ABORT 25 #define SES_ABORT_ACCEPT 26 /*#define SES_ACTIVITY_INTERRUPT 25 #define SES_ACTIVITY_INTERRUPT_ACK 26 */ #define SES_ACTIVITY_RESUME 29 #define SES_TYPED_DATA 33 #define SES_RESYNCHRONIZE_ACK 34 #define SES_MAJOR_SYNC_POINT 41 /*#define SES_MAJOR_SYNC_POINT 41 #define SES_ACTIVITY_END 41 */ #define SES_MAJOR_SYNC_ACK 42 #define SES_ACTIVITY_START 45 #define SES_EXCEPTION_DATA 48 #define SES_MINOR_SYNC_POINT 49 #define SES_MINOR_SYNC_ACK 50 #define SES_RESYNCHRONIZE 53 #define SES_ACTIVITY_DISCARD 57 #define SES_ACTIVITY_DISCARD_ACK 58 #define SES_CAPABILITY 61 #define SES_CAPABILITY_DATA_ACK 62 #define EXTENDED_USER_DATA 192 #define SES_USER_DATA 193 /* reason code 0: Rejection by called SS-user; reason not specified. 1: Rejection by called SS-user due to temporary congestion.2: Rejection by called SS-user. Subsequent octets may be used for user data up to a length of 512 octets if Protocol Version 1 has been selected, and up to a length such that the total length (including SI and LI) of the SPDU does not exceed 65 539 octets if Protocol Version 2 has been selected.
128 + 1: Session Selector unknown. 128 + 2: SS-user not attached to SSAP. 128 + 3: SPM congestion at connect time. 128 + 4: Proposed protocol versions not supported. 128 + 5: Rejection by the SPM; reason not specified.128 + 6: Rejection by the SPM; implementation restriction stated in the PICS.
*/ #define reason_not_specified 0 #define temporary_congestion 1 #define Subsequent 2 #define Session_Selector_unknown 128+1 #define SS_user_not_attached_to_SSAP 128+2 #define SPM_congestion_at_connect_time 128+3 #define versions_not_supported 128+4 #define SPM_reason_not_specified 128+5 #define SPM_implementation_restriction 128+6 #define TWO_BYTE_LEN 0xff /* PGI */ #define Connection_Identifier 1 #define Connect_Accept_Item 5 #define Linking_Information 33 #define Called_SS_user_Reference 9 #define Calling_SS_user_Reference 10 #define Common_Reference 11 #define Additional_Reference_Information 12 #define Sync_Type_Item 15 #define Token_Item 16 #define Transport_Disconnect 17 #define Protocol_Options 19 #define Session_Requirement 20 #define TSDU_Maximum_Size 21 #define Version_Number 22 #define Initial_Serial_Number 23 #define Prepare_Type 24 #define EnclosureItem 25 #define Token_Setting_Item 26 #define Resync_Type 27 #define Reflect_Parameter 49 #define Reason_Code 50 #define Calling_Session_Selector 51 #define Called_Session_Selector 52 #define Second_Resync_Type 53 #define Second_Serial_Number 54 #define Second_Initial_Serial_Number 55 #define Upper_Limit_Serial_Number 56 #define Large_Initial_Serial_Number 57 #define Large_Second_Initial_Serial_Number 58 #define CALLED_SESSION_SELECTOR 0x33 #define CALLING_SESSION_SELECTOR 0x34 #define SES_USER_DATA 193 #define Data_Overflow 60 #define SES_PDU_HEADER_LEN 2 #define SES_DATA 0x01 // transport disconnect values #define transport_connection_is_released 0x01 #define user_abort 0x02 #define protocol_error 0x04 #define no_reason 0x08 #define implementation_restriction 0x10 struct SES_PDU { unsigned char type; unsigned char len; union { unsigned short len_short; unsigned char data; }; unsigned char data1; }; struct PGI_PI_UNIT { unsigned char type; unsigned char len; union { unsigned short len_short; unsigned char data; }; unsigned char data1; }; struct CHAR_SHORT { union { unsigned short short_data; unsigned char data[2]; }; }; struct SES_PDU_PARM { unsigned char parm_type; unsigned char len; unsigned char data; };
- Prev by Date: RE: [Ethereal-dev] reorganizing source tree
- Next by Date: Re: [Ethereal-dev] Display filter as stop condition
- Previous by thread: Re: [Ethereal-dev] Ethereal filters are case sensitive
- Next by thread: [Ethereal-dev] Patch epan/proto.c - proto_tree_append_string()
- Index(es):