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 <[EMAIL PROTECTED]>
To: Sid Sid <[EMAIL PROTECTED]>
CC: [EMAIL PROTECTED]
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
[EMAIL PROTECTED]
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 <[EMAIL PROTECTED]>
* Ethereal - Network traffic analyzer
* By Gerald Combs <[EMAIL PROTECTED]>
* 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 <[EMAIL PROTECTED]>
*

* Ethereal - Network traffic analyzer
* By Gerald Combs <[EMAIL PROTECTED]>
* 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; };









Reply via email to