Ethereal-dev: [Ethereal-dev] New ISO 8823 OSI Presentation Protocol 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, 12 Jan 2004 14:39:50 +0000
Please find attached a new ISO 8823 OSI Presentation Protocol dissector. Will work correctly only with my latest path for session dissector. Thank you. Sidelnikov Yuriy. _________________________________________________________________Add photos to your e-mail with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail
/* packet-pres.c * * Routine to dissect ISO 8823 OSI Presentation Protocol packets * * * 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-pres.h" #include "packet-frame.h" #include "prefs.h" #include <epan/strutil.h> #include "asn1.h" #include "packet-ses.h" extern const value_string ses_vals[]; /* pres header fields */ static int proto_pres = -1; /* type of session envelop */ static struct SESSION_DATA_STRUCTURE* session = NULL; static int hf_pres_rc_type = -1; static int hf_pres_ms_type = -1; static int hf_pres_seq_type = -1; static int hf_pres_protocol_version =-1; /* pres fields defining a sub tree */ static gint ett_pres = -1; static gint ett_pres_param = -1; static gint ett_pres_rc = -1; static gint ett_pres_ms = -1; static gint ett_pres_itm = -1; /* ----------------------------------------------------------------------------------------------------------*/ static dissector_handle_t acse_handle = NULL; static int hf_pres_type = -1; static int hf_pres_length = -1; static int hf_value = -1; static int hf_cp_type_message_length = -1; static int hf_protocol_version = -1; static int hf_context_management = -1; static int hf_restoration = -1; static const value_string pres_vals[] = { {PRES_CONNECTION_REQUEST_CONFIRM, "Connection request/confirm PDU" }, {PRES_CONNECTION_REFUSE, "Connection refuse PDU" }, {0, NULL } }; static const value_string cr_vals[] = { {MODE_SELECTOR, "Mode Selector"}, {SEQUENCE_TOP, "Sequence"}, {SET_TOP, "Set"}, {0, NULL} }; static const value_string sequence_top_vals[] = { {CALLED_PRESENTATION_SELECTOR, "Called presentation selector"}, {CALLING_PRESENTATION_SELECTOR, "Calling presentation selector"},{PRESENTATION_CONTEXT_DEFINITION_LIST, "Presentation context definition list"},
{RESPONDING_PRESENTATION_SELECTOR, "Responding presentation selector"}, {PROTOCOL_VERSION, "Protocol version"},{PRESENTATION_CONTEXT_DEFINITION_RESULT_LIST, "Presentation context definition result list"},
{PRESENTATION_REQUIREMENTS,"Presentation requirements"}, {DEFAULT_CONTEXT_NAME,"Default context name"}, {USER_SESSION_REQUIREMENTS,"User session requirements"}, {DEFAULT_CONTEXT_RESULT,"Default context result"}, {PROVIDER_REASON,"Provider reason"}, {0, NULL} }; static const value_string sequence_list_vals[] = { {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"}, {ABSTRACT_SYNTAX_NAME,"Abstract syntax name"}, {TRANSFER_SYNTAX_NAMES,"Transfer syntax names"}, {0, NULL} }; static const value_string sequence_list_result_vals[] = { {PRESENTATION_RESULT,"Result"}, {PRESENTATION_RESULT_INTEGER,"Integer"}, {PRESENTATION_RESULT_TRANSFER_SYNTAX_NAME,"Transfer syntax name"}, {0, NULL} }; static const value_string presentation_context_definition_vals[] = { {SEQUENCE, "Sequence"}, {0, NULL} }; static const value_string sequence_list_result_values_vals[] = { {PRESENTATION_RESULT_ACCEPTANCE,"Acceptance"}, {PRESENTATION_RESULT_USER_REJECTION,"User rejection"}, {PRESENTATION_RESULT_PROVIDER_REJECTION,"Provider rejection"}, {0, NULL} }; static const value_string provider_reason_values_vals[] = { {REASON_NOT_SPECIFIED,"Reason not specified"}, {TEMPORARY_CONGESTION,"Temporary congestion"}, {LOCAL_LIMIT_EXCEEDED,"Local limit exceeded"},{CALLED_PRESENTATION_ADDRESS_UNKNOWN,"Called presentation address unknown"},
{PROTOCOL_VERSION_NOT_SUPPORTED,"Protocol version not supported"}, {DEFAULT_CONTEXT_NOT_SUPPORTED,"Default context not supported"}, {USER_DATA_NOT_READABLE,"User data not readable"}, {NO_PSAP_AVAILABLE,"No PSAP available"}, {0, NULL} }; static const value_string user_data_values_vals[] = { {SIMPLY_ENCODED_DATA,"Simply encoded data"}, {FULLY_ENCODED_DATA,"Fully encoded data "}, {0, NULL} }; static const value_string presentation_data_values[] = { {PRESENTATION_CONTEXT_IDENTIFIER,"Presentation context identifier"}, {SINGLE_ASN1_TYPE,"Single ASN.1 type"}, {OCTET_ALIGNED,"Octet aligned"}, {ARBITRARY,"Arbitrary"}, {0, NULL} }; static const value_string provider_abort_values_vals[] = { {PR_REASON_NOT_SPECIFIED,"Reason not specified"}, {UNRECOGNIZED_PDU,"Unrecognized ppdu"}, {UNEXPECTED_PDU,"Unexpected ppdu"},{UNEXPECTED_SESSION_SERVICE_PRIMITIVE,"Unexpected session service primitive"},
{UNRECOGNIZED_PPDU_PARAMETER,"Unrecognized ppdu parameter"}, {UNEXPECTED_PPDU_PARAMETER,"Unexpected ppdu parameter"}, {INVALID_PPDU_PARAMETER_VALUE,"Invalid ppdu parameter value"}, {0, NULL} }; static const value_string event_identifier_values_vals[] = { {REASON_CP_PPDU,"cp PPDU"}, {REASON_CPA_PPDU,"cpa PPDU"}, {REASON_CPR_PPDU,"cpr PPDU"}, {REASON_ARU_PPDU,"aru PPDU"}, {REASON_ARP_PPDU,"arp PPDU"}, {REASON_AC_PPDU,"ac PPDU"}, {REASON_ACA_PPDU,"aca PPDU"}, {REASON_TD_PPDU,"td PPDU"}, {REASON_TTD_PPDU,"td PPDU"}, {REASON_TE_PPDU,"te PPDU"}, {REASON_TC_PPDU,"tc PPDU"}, {REASON_TCC_PPDU,"tcc PPDU"}, {REASON_RS_PPDU,"rs PPDU"}, {REASON_RSA_PPDU,"rsa PPDU"}, {S_RELEASE_INDICATION,"s release indication"}, {S_RELEASE_CONFIRM,"s release confirm"}, {S_TOKEN_GIVE_INDICATION,"s token give indication"}, {S_TOKEN_PLEASE_INDICATION,"s token please indication"}, {S_CONTROL_GIVE_INDICATION,"s control give indication"}, {S_SYNC_MINOR_INDICATION,"s sync minor indication"}, {S_SYNC_MINOR_CONFIRM,"s sync minor confirm"}, {S_SYNC_MAJOR_INDICATION,"s sync major indication"}, {S_SYNC_MAJOR_CONFIRM,"s sync major confirm"}, {S_P_EXCEPTION_REPORT_INDICATION,"s p exception report indication"}, {S_U_EXCEPTION_REPORT_INDICATION,"s u exception report indication"}, {S_ACTIVITY_START_INDICATION,"s activity start indication"}, {S_ACTIVITY_RESUME_INDICATION,"s activity resume indication"}, {S_ACTIVITY_INTERRUPT_INDICATION,"s activity interrupt indication"}, {S_ACTIVITY_INTERRUPT_CONFIRM,"s activity interrupt confirm"}, {S_ACTIVITY_DISCARD_INDICATION,"s activity discard indication"}, {S_ACTIVITY_DISCARD_CONFIRM,"s activity discard confirm"}, {S_ACTIVITY_END_INDICATION,"s activity end indication"}, {S_ACTIVITY_END_CONFIRM,"s activity end confirm"}, {0, NULL} }; /* external function */ gchar * format_oid(subid_t *oid, guint oid_length); /* pointers for acse dissector */ proto_tree *global_tree = NULL; packet_info *global_pinfo = NULL; /* dissector for data */ static dissector_handle_t data_handle; static void call_acse_dissector(tvbuff_t *tvb, int offset, guint16 param_len, packet_info *pinfo, proto_tree *tree, proto_tree *param_tree) { /* do we have OSI acse/rose packet dissector ? */ if(!acse_handle) { /* No - display as data */ if (tree) { proto_tree_add_text(param_tree, tvb, offset, param_len, "No ACSE dissector available"); } else { /* Yes - call app dissector */ tvbuff_t *next_tvb; next_tvb = tvb_new_subset(tvb, offset, param_len, param_len); TRY { call_dissector(acse_handle, next_tvb, pinfo, tree); } CATCH_ALL { show_exception(tvb, pinfo, tree, EXCEPT_CODE); } ENDTRY; } } } static 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; } static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len) { guint length = 0; gboolean def = FALSE; int start = a->offset; int ret; ret = asn1_length_decode(a, &def, &length); if (ret != ASN1_ERR_NOERROR) { if (tree) { proto_tree_add_text(tree, a->tvb, start, 0, "%s: ERROR: Couldn't parse length: %s", proto_registrar_get_name(hf_id), asn1_err_to_str(ret)); } return ret; } if (len) *len = length; if (tree && hf_id)proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, length);
return ASN1_ERR_NOERROR; } static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id, proto_item **new_item, guint *i, int start, guint length) { guint integer = 0; proto_item *temp_item = NULL; int ret; ret = asn1_uint32_value_decode(a, length, &integer); if (ret != ASN1_ERR_NOERROR) { if (tree) { proto_tree_add_text(tree, a->tvb, start, 0, "%s: ERROR: Couldn't parse value: %s", proto_registrar_get_name(hf_id), asn1_err_to_str(ret)); } return ret; } if (i) *i = integer; if (tree && hf_id)temp_item = proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, integer);
if (new_item) *new_item = temp_item; return ASN1_ERR_NOERROR; } static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id, proto_item **new_item, guint *i) { guint cls, con, tag; gboolean def; guint length; int start = a->offset; int ret; ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length); if (ret != ASN1_ERR_NOERROR) { if (tree) { proto_tree_add_text(tree, a->tvb, start, 0, "%s: ERROR: Couldn't parse header: %s", (hf_id != -1) ? proto_registrar_get_name(hf_id) : "LDAP message", asn1_err_to_str(ret)); } return ret; } return read_integer_value(a, tree, hf_id, new_item, i, start, length); } /* display asn.1 Integer type */ static voidshow_integer(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ proto_tree *pres_tree_itm = NULL; proto_item *itm; int ret; int save_len = item_len; int off = *offset; itm = proto_tree_add_text(pres_tree, tvb, *offset, item_len, "Integer"); pres_tree_itm = proto_item_add_subtree(itm, ett_pres_itm); ret = read_integer(asn,pres_tree_itm,0,NULL,&item_len); if (ret == ASN1_ERR_NOERROR ) { *offset = asn->offset;itm = proto_tree_add_text(pres_tree_itm, tvb, (*offset)-item_len, item_len,
"Integer value: %u",item_len); } else { /* can't dissect item. Skip it. */ *offset = off+ save_len; } } static voidshow_presentation_requirements(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int tag)
{ proto_tree *pres_tree_itm = NULL; proto_item *itm; guint16 flags; gint length; /* do we have enough bytes to dissect this item ? */if( ( length = tvb_reported_length_remaining(tvb, *offset)) < (asn->offset -*offset)+ item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, item_len, "Wrong Item.Need %u bytes but have %u", item_len,length); return; }itm = proto_tree_add_text(pres_tree, tvb, *offset,(asn->offset -*offset)+ item_len,
val_to_str(tag, sequence_top_vals,"Unknown item (0x%02x)")); pres_tree_itm = proto_item_add_subtree(itm, ett_pres_itm); *offset = asn->offset; flags = tvb_get_ntohs(tvb, *offset);proto_tree_add_boolean(pres_tree_itm,hf_context_management, tvb, *offset, 2, flags); proto_tree_add_boolean(pres_tree_itm,hf_restoration, tvb, *offset, 2, flags);
*offset = *offset + item_len; asn->offset = *offset; } static voidshow_protocol_version(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int tag)
{ proto_tree *pres_tree_itm = NULL; proto_item *itm; guint16 flags; gint length; /* do we have enough bytes to dissect this item ? */if( ( length = tvb_reported_length_remaining(tvb, *offset)) < (asn->offset -*offset)+ item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, item_len, "Wrong Item.Need %u bytes but have %u", item_len,length); return; }itm = proto_tree_add_text(pres_tree, tvb, *offset,(asn->offset -*offset)+ item_len,
val_to_str(tag, sequence_top_vals,"Unknown item (0x%02x)")); pres_tree_itm = proto_item_add_subtree(itm, ett_pres_itm); *offset = asn->offset; flags = tvb_get_ntohs(tvb, *offset);proto_tree_add_boolean(pres_tree_itm,hf_protocol_version, tvb, *offset, 2, flags);
*offset = *offset + item_len; asn->offset = *offset; } static voidprint_oid_value(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ guint ret; subid_t *oid; guint len; gchar *display_string; guint length; guint start=*offset; ret = asn1_oid_value_decode (asn, item_len, &oid, &len); if (ret != ASN1_ERR_NOERROR) { return ; } length = asn->offset - start; display_string = format_oid(oid, len);proto_tree_add_text(pres_tree, tvb, *offset,length,"Value:%s", display_string);
g_free(display_string); (*offset)=start+item_len; asn->offset = (*offset); } static voidprint_oid(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ guint ret; subid_t *oid; guint len; guint nbytes; gchar *display_string; guint length; guint start=*offset; ret = asn1_oid_decode ( asn, &oid, &len, &nbytes); if (ret != ASN1_ERR_NOERROR) { return ; } length = asn->offset - start; display_string = format_oid(oid, len);proto_tree_add_text(pres_tree, tvb, *offset,length,"Value:%s", display_string);
g_free(display_string); (*offset)=start+item_len; asn->offset = (*offset); } static voidprint_value(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ gint start = *offset; char tmp[MAXSTRING]; *offset = asn->offset; /* align to data*/ string_to_hex((char*)tvb_get_ptr(tvb,*offset,item_len),tmp,item_len); proto_tree_add_text(pres_tree, tvb, *offset, item_len, tmp); (*offset)=start+item_len; asn->offset = (*offset); } static int get_integer_value(ASN1_SCK *asn,int length,int *offset) { int off = *offset; int asn_off = asn->offset; int item_len = -1; int ret; /* align pointers */ *offset=asn->offset; ret = asn1_uint32_value_decode(asn, length, &item_len); /* return to present position */ *offset = off; asn->offset = asn_off; if (ret != ASN1_ERR_NOERROR ) { return -1; } else { return item_len; } } static voidshow_presentation_context_definition_result_seq(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ proto_tree *pres_tree_ms = NULL; guint length; guint type; proto_item *ms; guint new_item_len; guint start = *offset; guint header_len; int old_offset; /* print seq */ while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 ) { old_offset = *offset ; /* get item type */ type = tvb_get_guint8(tvb, *offset); /* skip type */ (*offset)++; asn->offset = *offset; /* get length */ if (read_length(asn, pres_tree, 0, &new_item_len) != ASN1_ERR_NOERROR) { (*offset)=start+item_len; asn->offset = (*offset); return ; } /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < new_item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, new_item_len, "Wrong item.Need %u bytes but have %u", new_item_len,length); (*offset)=start+item_len; asn->offset = (*offset); return ; } header_len = asn->offset - (*offset) +1;ms = proto_tree_add_text(pres_tree, tvb, *offset-1, new_item_len+(asn->offset-*offset)+1,
val_to_str(type, sequence_list_result_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); *offset = asn->offset; switch(type) { case PRESENTATION_RESULT: { proto_tree *pres_tree_pr = NULL; proto_item *pr; int value = get_integer_value(asn,new_item_len,offset);pr = proto_tree_add_text(pres_tree_ms, tvb, *offset, new_item_len+(asn->offset-*offset),
val_to_str(value ,sequence_list_result_values_vals, "Unknown item (0x%02x)")); pres_tree_pr = proto_item_add_subtree(pr, ett_pres_ms); print_value(asn,pres_tree_pr,tvb,offset,new_item_len); } break; case PRESENTATION_RESULT_INTEGER: print_value(asn,pres_tree_ms,tvb,offset,new_item_len); break; case PRESENTATION_RESULT_TRANSFER_SYNTAX_NAME: print_oid_value(asn,pres_tree_ms,tvb,offset,new_item_len); break; default:proto_tree_add_text(pres_tree, tvb, *offset, new_item_len+(asn->offset-*offset),
"Unknown asn.1 parameter: (0x%02x)", type); } *offset = old_offset+new_item_len+header_len; item_len-=new_item_len+header_len; } /* align the pointer */ (*offset)=start+item_len; asn->offset = (*offset); } static voidshow_presentation_context_definition_seq(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ proto_tree *pres_tree_ms = NULL; guint length; guint type; proto_item *ms; guint new_item_len; guint start = *offset; guint header_len; int old_offset; /* print seq */ while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 ) { old_offset = *offset ; /* get item type */ type = tvb_get_guint8(tvb, *offset); /* skip type */ (*offset)++; asn->offset = *offset; /* get length */ if (read_length(asn, pres_tree, 0, &new_item_len) != ASN1_ERR_NOERROR) { (*offset)=start+item_len; asn->offset = (*offset); return ; } /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < new_item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, new_item_len, "Wrong item.Need %u bytes but have %u", new_item_len,length); (*offset)=start+item_len; asn->offset = (*offset); return ; } header_len = asn->offset - (*offset) +1;ms = proto_tree_add_text(pres_tree, tvb, *offset-1, new_item_len+(asn->offset-*offset)+1,
val_to_str(type, sequence_list_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); *offset = asn->offset; switch(type) { case PRESENTATION_CONTEXT_IDENTIFIER: print_value(asn,pres_tree_ms,tvb,offset,new_item_len); break; case ABSTRACT_SYNTAX_NAME: print_oid_value(asn,pres_tree_ms,tvb,offset,new_item_len); break; case TRANSFER_SYNTAX_NAMES: print_oid(asn,pres_tree_ms,tvb,offset,new_item_len); break; default:proto_tree_add_text(pres_tree, tvb, *offset, new_item_len+(asn->offset-*offset),
"Unknown asn.1 parameter: (0x%02x)", type); } *offset = old_offset+new_item_len+header_len; item_len-=new_item_len+header_len; } /* align the pointer */ (*offset)=start+item_len; asn->offset = (*offset); } static voidshow_fully_encoded_seq(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ proto_tree *pres_tree_ms = NULL; guint length; guint type; proto_item *ms; guint new_item_len; guint start = *offset; guint header_len; guint acse = 0; /* no acse id */ int old_offset; /* print seq */ while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 ) { old_offset = *offset ; /* get item type */ type = tvb_get_guint8(tvb, *offset); /* skip type */ (*offset)++; asn->offset = *offset; /* get length */ if (read_length(asn, pres_tree, 0, &new_item_len) != ASN1_ERR_NOERROR) { (*offset)=start+item_len; asn->offset = (*offset); return ; } /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < new_item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, new_item_len, "Wrong item.Need %u bytes but have %u", new_item_len,length); (*offset)=start+item_len; asn->offset = (*offset); return ; } header_len = asn->offset - (*offset) +1;ms = proto_tree_add_text(pres_tree, tvb, *offset-1, new_item_len+(asn->offset-*offset)+1,
val_to_str(type, presentation_data_values, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); *offset = asn->offset; switch(type) { case PRESENTATION_CONTEXT_IDENTIFIER: { /* if Presentation context identifier = 3 we have ACSE data */ /* this data we have to send to ACSE dissector */ acse = get_integer_value(asn,new_item_len,offset); print_value(asn,pres_tree_ms,tvb,offset,new_item_len); } break; case OCTET_ALIGNED: break; case SINGLE_ASN1_TYPE: if( acse == ACSE_PRESENTATION_CONTEXT_IDENTIFIER ) { proto_item *acse_ms; /* yes, we have to call ACSE dissector */acse_ms = proto_tree_add_text(pres_tree_ms, tvb, *offset, new_item_len+(asn->offset-*offset),
"Acse data"); /* call acse dissector */ call_acse_dissector(tvb,*offset,new_item_len,global_pinfo,global_tree,pres_tree_ms); acse = 0; } break; case ARBITRARY: print_value(asn,pres_tree_ms,tvb,offset,new_item_len); break; default:proto_tree_add_text(pres_tree, tvb, *offset, new_item_len+(asn->offset-*offset),
"Unknown asn.1 parameter: (0x%02x)", type); } *offset = old_offset+new_item_len+header_len; item_len-=new_item_len+header_len; } /* align the pointer */ (*offset)=start+item_len; asn->offset = (*offset); } static voidshow_fully_encoded_data(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ proto_tree *pres_tree_ms = NULL; proto_tree *pres_tree_pc = NULL; gint length; guint type; guint header_len; proto_item *ms; gint new_item_len; guint start = asn->offset; guint item_length = item_len; pres_tree_pc = pres_tree; /* do we have enough bytes to dissect ? */ if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len ) { proto_tree_add_text(pres_tree_pc, tvb, *offset, item_len, "Wrong item.Need %u bytes but have %u", item_len,length); /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; } *offset =asn->offset; start = *offset; /* read the rest */ while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 ) { int old_offset = *offset; /* get item type */ type = tvb_get_guint8(tvb, *offset); /* skip type */ (*offset)++; asn->offset = *offset; /* get length */if (read_length(asn, pres_tree_pc, 0, &new_item_len) != ASN1_ERR_NOERROR)
{ /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; } header_len = asn->offset - (*offset) +1; /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < new_item_len )
{ proto_tree_add_text(pres_tree_pc, tvb, *offset, new_item_len, "Wrong item.Need %u bytes but have %u", new_item_len,length); /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; }ms = proto_tree_add_text(pres_tree_pc, tvb, *offset-1, new_item_len+(asn->offset-*offset)+1,
val_to_str(type, presentation_context_definition_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); *offset = asn->offset; switch(type) { case SEQUENCE: show_fully_encoded_seq(asn,pres_tree_ms,tvb,offset,new_item_len); *offset = old_offset+(new_item_len+header_len); break; default:proto_tree_add_text(pres_tree_ms, tvb, *offset, new_item_len+(asn->offset-*offset),
"Unknown asn.1 parameter: (0x%02x)", type); *offset = old_offset+(new_item_len+header_len); } item_len = item_len - (new_item_len+header_len); } /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); } static voidshow_session_provider_abort(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len)
{ gint length; gint value; proto_tree *pres_tree_pc = NULL; proto_tree *pres_tree_pp = NULL; proto_item *itu; gint new_item_len; /* do we have enough bytes to dissect this item ? */ if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len ) { proto_tree_add_text(pres_tree, tvb, *offset, item_len, "Wrong Item.Need %u bytes but have %u", item_len,length); *offset = asn->offset; return; } itu = proto_tree_add_text(pres_tree, tvb, *offset,item_len, "Provider abort"); pres_tree_pp = proto_item_add_subtree(itu, ett_pres_ms); if(item_len <= 0) { proto_tree_add_text(pres_tree_pc, tvb, *offset, item_len, "Provider reason not specified"); *offset = asn->offset; return; } itu = proto_tree_add_text(pres_tree_pp, tvb, *offset,ABORT_REASON_LEN, "Abort reason"); pres_tree_pc = proto_item_add_subtree(itu, ett_pres_ms); (*offset)++; /* skip type */ asn->offset = *offset; item_len--; /* get length */if (read_length(asn, pres_tree_pc, 0, &new_item_len) != ASN1_ERR_NOERROR)
{ *offset = asn->offset; return; } /* try to get Abort reason */ value = get_integer_value(asn,new_item_len,offset); proto_tree_add_text(pres_tree_pc, tvb, *offset+1,new_item_len, val_to_str(value, provider_abort_values_vals,"Unknown item (0x%02x)")); item_len-=(asn->offset-*offset)+new_item_len; *offset = asn->offset+new_item_len; asn->offset = *offset; /* do we have Event identifier ? */ if(item_len > 0) { itu = proto_tree_add_text(pres_tree_pp, tvb, *offset,item_len, "Event identifier"); pres_tree_pc = proto_item_add_subtree(itu, ett_pres_ms); (*offset)++; /* skip type */ asn->offset = *offset; item_len--; /* get length */if (read_length(asn, pres_tree_pc, 0, &new_item_len) != ASN1_ERR_NOERROR)
{ *offset = asn->offset; return; } /* try to get Event identifier */ value = get_integer_value(asn,new_item_len,offset); proto_tree_add_text(pres_tree_pc, tvb, *offset+1,new_item_len,val_to_str(value, event_identifier_values_vals,"Unknown item (0x%02x)"));
item_len-=(asn->offset-*offset)+new_item_len; *offset = asn->offset+new_item_len; asn->offset = *offset; } } static voidshow_user_data(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int tag)
{ proto_tree *pres_tree_ud = NULL; proto_tree *pres_tree_pc = NULL; proto_item *itm; proto_item *itu; guint start = asn->offset; guint item_length = item_len;itm = proto_tree_add_text(pres_tree, tvb, *offset,(asn->offset -*offset)+ item_len, "User data");
pres_tree_ud = proto_item_add_subtree(itm, ett_pres_ms);itu = proto_tree_add_text(pres_tree_ud, tvb, *offset,item_len+(asn->offset-*offset),
val_to_str(tag, user_data_values_vals,"Unknown item (0x%02x)")); pres_tree_pc = proto_item_add_subtree(itu, ett_pres_ms); switch(tag) { case SIMPLY_ENCODED_DATA: break; case FULLY_ENCODED_DATA: show_fully_encoded_data(asn,pres_tree_pc,tvb,offset,item_len); break; default: break; } /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); } static voidshow_presentation_context_definition(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int tag)
{ proto_tree *pres_tree_ms = NULL; proto_tree *pres_tree_pc = NULL; proto_item *itm; gint length; guint type; guint header_len; proto_item *ms; gint new_item_len; guint start = asn->offset; guint item_length = item_len;itm = proto_tree_add_text(pres_tree, tvb, *offset,item_len+(asn->offset-*offset),
val_to_str(tag, sequence_top_vals,"Unknown item (0x%02x)")); pres_tree_pc = proto_item_add_subtree(itm, ett_pres_ms); /* do we have enough bytes to dissect ? */ if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len ) { proto_tree_add_text(pres_tree_pc, tvb, *offset, item_len, "Wrong item.Need %u bytes but have %u", item_len,length); /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; } *offset =asn->offset; start = *offset; /* read the rest */ while ( item_len > 0 && tvb_reported_length_remaining(tvb, *offset) > 0 ) { int old_offset = *offset; /* get item type */ type = tvb_get_guint8(tvb, *offset); /* skip type */ (*offset)++; asn->offset = *offset; /* get length */if (read_length(asn, pres_tree_pc, 0, &new_item_len) != ASN1_ERR_NOERROR)
{ /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; } header_len = asn->offset - (*offset) +1; /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < new_item_len )
{ proto_tree_add_text(pres_tree_pc, tvb, *offset, new_item_len, "Wrong item.Need %u bytes but have %u", new_item_len,length); /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); return ; }ms = proto_tree_add_text(pres_tree_pc, tvb, *offset-1, new_item_len+(asn->offset-*offset)+1,
val_to_str(type, presentation_context_definition_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); *offset = asn->offset; switch(type) { case SEQUENCE: if(tag == PRESENTATION_CONTEXT_DEFINITION_RESULT_LIST || tag == DEFAULT_CONTEXT_RESULT) { show_presentation_context_definition_result_seq(asn,pres_tree_ms,tvb,offset,new_item_len); } else { show_presentation_context_definition_seq(asn,pres_tree_ms,tvb,offset,new_item_len); } *offset = old_offset+(new_item_len+header_len); break; default:proto_tree_add_text(pres_tree_ms, tvb, *offset, new_item_len+(asn->offset-*offset),
"Unknown asn.1 parameter: (0x%02x)", type); *offset = old_offset+(new_item_len+header_len); } item_len = item_len - (new_item_len+header_len); } /* align the pointer */ (*offset)=start+item_length; asn->offset = (*offset); } /* if we can't dissect */ static void dissect_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *field_name, int ret) { char *errstr; errstr = asn1_err_to_str(ret); if (tree != NULL) { proto_tree_add_text(tree, tvb, offset, 0, "ERROR: Couldn't parse %s: %s", field_name, errstr); call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree); } } static int read_string_value(ASN1_SCK *a, proto_tree *tree, int hf_id, proto_item **new_item, char **s, int start, guint length) { guchar *string; proto_item *temp_item = NULL; int ret; if (length) { ret = asn1_string_value_decode(a, length, &string); if (ret != ASN1_ERR_NOERROR) { if (tree) { proto_tree_add_text(tree, a->tvb, start, 0, "%s: ERROR: Couldn't parse value: %s", proto_registrar_get_name(hf_id), asn1_err_to_str(ret)); } return ret; } string = g_realloc(string, length + 1); string[length] = '\0'; } else string = "(null)"; if (tree && hf_id)temp_item = proto_tree_add_string(tree, hf_id, a->tvb, start, a->offset - start, string);
if (new_item) *new_item = temp_item; if (s && length) *s = string; else if (length) g_free(string); return ASN1_ERR_NOERROR; } static voidshow_provider_reason(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int type)
{ proto_item *ms; proto_item *pr; proto_tree *pres_tree_ms = NULL; proto_tree *pres_tree_pr = NULL; int off = *offset; int value=0; int new_item_len = item_len+(asn->offset-*offset); ms = proto_tree_add_text(pres_tree, tvb, *offset, new_item_len, val_to_str(type, sequence_top_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); value = get_integer_value(asn,item_len,offset); pr = proto_tree_add_text(pres_tree_ms, tvb, *offset, new_item_len, val_to_str(value, provider_reason_values_vals, "Unknown item (0x%02x)")); pres_tree_pr = proto_item_add_subtree(pr, ett_pres_ms); print_value(asn,pres_tree_pr,tvb,offset,item_len); asn->offset = *offset = off+new_item_len; } static voidshow_presentation_selector (ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,int *offset,int item_len,int type)
{ proto_item *ms; proto_tree *pres_tree_ms = NULL; int ret; char *s;ms = proto_tree_add_text(pres_tree, tvb, *offset, item_len+(asn->offset-*offset),
val_to_str(type, sequence_top_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms);ret = read_string_value(asn, pres_tree,0,NULL, &s, *offset+(asn->offset-*offset), item_len);
if(ret == ASN1_ERR_NOERROR) { proto_tree_add_text(pres_tree_ms, tvb, *offset+2, item_len, "String:%s",s); } g_free(s); } /* display top sequence */ static voidshow_sequence_top(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,packet_info *pinfo,int *offset,int item_len)
{ int ret; guint cls, con, tag,len1; gint type; gboolean def; proto_item *itm; gint length; while(item_len > 0 ) { /* do we have enough bytes to dissect this item ? */ if( ( length =tvb_reported_length_remaining(tvb, *offset)) < item_len ) { proto_tree_add_text(pres_tree, tvb, *offset, item_len, "Wrong Item.Need %u bytes but have %u", item_len,length); break; } /* get tag */ type = tvb_get_guint8(tvb, *offset); /* decode header */ ret = asn1_header_decode(asn, &cls, &con, &tag, &def, &len1); if (ret != ASN1_ERR_NOERROR) { dissect_parse_error(tvb, *offset, pinfo, pres_tree, "sequence error", ret); break; } item_len = item_len - (asn->offset - *offset); /* * [APPLICATION <tag>] */ switch (tag) { case TAG_01: /* Calling-presentation-selector and User data have the same tag number Try to recognize which one do we really have */ if( con == ASN1_CON) { /* it is User data */ /* print it */ show_user_data(asn,pres_tree,tvb,offset,len1,type); break; } /* it is Calling-presentation-selector */ /* simply go below, we don't need to break here */ case CALLED_PRESENTATION_SELECTOR: case RESPONDING_PRESENTATION_SELECTOR: /*case CALLING_PRESENTATION_SELECTOR:*/ /* * [Called-presentation-selector] * [Calling-presentation-selector] * [Responding-presentation-selector] */ show_presentation_selector(asn,pres_tree,tvb,offset,len1,tag); break; case DEFAULT_CONTEXT_NAME: case PRESENTATION_CONTEXT_DEFINITION_LIST: show_presentation_context_definition(asn,pres_tree,tvb,offset,len1,tag); break; case PROTOCOL_VERSION: /*case TAG_00: */ if(cls == ASN1_APL) { /* yes, it is application */ *offset = asn->offset; item_len = len1; continue; } show_protocol_version(asn,pres_tree,tvb,offset,len1,tag); break; case PRESENTATION_CONTEXT_DEFINITION_RESULT_LIST: case DEFAULT_CONTEXT_RESULT: show_presentation_context_definition(asn,pres_tree,tvb,offset,len1,tag); break; case PRESENTATION_REQUIREMENTS: show_presentation_requirements(asn,pres_tree,tvb,offset,len1,tag); break; case PROVIDER_REASON: show_provider_reason(asn,pres_tree,tvb,offset,len1,tag); break; /* to do */ case USER_SESSION_REQUIREMENTS:itm = proto_tree_add_text(pres_tree, tvb, *offset,(asn->offset -*offset)+ len1,
val_to_str(tag, sequence_top_vals,"Unknown item (0x%02x)")); (asn->offset)+=len1; break; default:itm = proto_tree_add_text(pres_tree, tvb, *offset,(asn->offset -*offset)+ len1,
"Unknown tag: %x",tag); (asn->offset)+=len1; } item_len-=len1; *offset = asn->offset; } } static voidshow_connection_request_confirm(ASN1_SCK *asn,proto_tree *pres_tree,tvbuff_t *tvb,packet_info *pinfo,int *offset,int* item_len)
{ guint8 type; guint length; proto_tree *pres_tree_ms = NULL; proto_item *ms; /* get type of set */ while ( tvb_reported_length_remaining(tvb, *offset) > 0 ) { int asn1_tag; /* get item type */ type = tvb_get_guint8(tvb, *offset); asn1_tag = type & 0x1f; /* skip type */ (*offset)++; asn->offset = *offset; /* get length */ if (read_length(asn, pres_tree, 0, item_len) != ASN1_ERR_NOERROR) { return; } /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, *offset)) < (guint)*item_len )
{ proto_tree_add_text(pres_tree, tvb, *offset, -1, "Wrong item.Need %u bytes but have %u", *item_len,length); return; }ms = proto_tree_add_text(pres_tree, tvb, *offset-1, *item_len+(asn->offset-*offset)+1,
val_to_str(asn1_tag, cr_vals, "Unknown item (0x%02x)")); pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); switch(asn1_tag) { case MODE_SELECTOR:proto_tree_add_uint(pres_tree_ms, hf_pres_ms_type, tvb, (*offset)-1, 1, type);
proto_tree_add_text(pres_tree_ms, tvb, *offset, (asn->offset-*offset), "Lenght:%u",*item_len); *offset=asn->offset; show_integer(asn,pres_tree_ms,tvb,offset,*item_len); break; case SET_TOP: case SEQUENCE_TOP:proto_tree_add_uint(pres_tree_ms, hf_pres_seq_type, tvb, (*offset)-1, 1, type);
proto_tree_add_text(pres_tree_ms, tvb, *offset, (asn->offset-*offset), "Lenght:%u",*item_len); *offset=asn->offset; show_sequence_top(asn,pres_tree_ms,tvb,pinfo,offset,*item_len); break; default:proto_tree_add_text(pres_tree, tvb, (*offset)-1, *item_len+(asn->offset-*offset)+1,
"Unknown asn.1 parameter: (0x%02x).Tag :(0x%02x)", type,asn1_tag); (*offset)+=*item_len+(asn->offset-*offset); asn->offset = *offset; } } } /* * Dissect an Ppdu. */ static intdissect_ppdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{ proto_item *ti; proto_tree *pres_tree = NULL; guint length; guint rest_len; guint s_type; ASN1_SCK asn; guint cp_type_len; /* do we have spdu type from the session dissector? */ if( !pinfo->private_data ) { if(tree) { proto_tree_add_text(tree, tvb, offset, -1, "Internal error:can't get spdu type from session dissector."); return FALSE; } } else { session = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) ); if(session->spdu_type == 0 ) { if(tree) { proto_tree_add_text(tree, tvb, offset, -1,"Internal error:wrong spdu type %x from session dissector.",session->spdu_type);
return FALSE; } } } /* get type of tag */ s_type = tvb_get_guint8(tvb, offset); /* set up type of Ppdu */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO,val_to_str(session->spdu_type, ses_vals, "Unknown Ppdu type (0x%02x)"));
if (tree) { ti = proto_tree_add_item(tree, proto_pres, tvb, offset, -1, FALSE); pres_tree = proto_item_add_subtree(ti, ett_pres); } offset++; /* open asn.1 stream */ asn1_open(&asn, tvb, offset); switch(session->spdu_type) { case SES_REFUSE: proto_tree_add_uint(pres_tree, hf_pres_type, tvb, offset-1, 1, s_type);if (read_length(&asn, pres_tree, hf_cp_type_message_length, &cp_type_len) != ASN1_ERR_NOERROR)
{ return FALSE; } /* skip length */ offset = asn.offset; /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, offset)) < cp_type_len )
{ if(tree) { proto_tree_add_text(pres_tree, tvb, offset, -1, "Wrong Ppdu.Need %u bytes but have %u", cp_type_len,length); } return FALSE; } if (tree) { asn.offset = offset; show_sequence_top(&asn,pres_tree,tvb,pinfo,&offset,cp_type_len); offset=asn.offset; } break; case SES_CONNECTION_REQUEST: case SES_CONNECTION_ACCEPT: proto_tree_add_uint(pres_tree, hf_pres_type, tvb, offset-1, 1, s_type);if (read_length(&asn, pres_tree, hf_cp_type_message_length, &cp_type_len) != ASN1_ERR_NOERROR)
{ return FALSE; } /* skip length */ offset = asn.offset; /* do we have enough bytes to dissect ? */if( ( length =tvb_reported_length_remaining(tvb, offset)) < cp_type_len )
{ if(tree) { proto_tree_add_text(pres_tree, tvb, offset, -1, "Wrong Ppdu.Need %u bytes but have %u", cp_type_len,length); } return FALSE; } if(tree) { show_connection_request_confirm(&asn,pres_tree,tvb,pinfo,&offset,&cp_type_len); } break; case SES_ABORT: /* get length */ if (read_length(&asn, pres_tree, 0, &rest_len) != ASN1_ERR_NOERROR) { return FALSE; } /* skip length */ offset = asn.offset; /* do we have enough bytes to dissect ? */ if( ( length =tvb_reported_length_remaining(tvb, offset)) < rest_len ) { if(tree) { proto_tree_add_text(pres_tree, tvb, offset, -1, "Wrong Ppdu.Need %u bytes but have %u", rest_len,length); } return FALSE; } if(session->abort_type == SESSION_USER_ABORT ) { /* is it PC */ if(s_type == ASN1_CLASS_PC+ASN1_CLASS_CONTEXT_SPECIFIC) { if (tree) { offset=asn.offset; show_sequence_top(&asn,pres_tree,tvb,pinfo,&offset,rest_len); offset=asn.offset; } } else { if (tree) { offset=asn.offset; show_session_provider_abort(&asn,pres_tree,tvb,&offset,rest_len); offset=asn.offset; } } } else { if (tree) { offset=asn.offset; show_sequence_top(&asn,pres_tree,tvb,pinfo,&offset,rest_len); offset=asn.offset; } } break; default: { proto_item *ms; proto_tree *pres_tree_ms = NULL; /* back to length */ offset--; /* get length */ if (read_length(&asn, pres_tree, 0, &rest_len) != ASN1_ERR_NOERROR) { return FALSE; } ms = proto_tree_add_text(pres_tree, tvb, offset, rest_len,val_to_str(session->spdu_type, ses_vals, "Unknown Ppdu type (0x%02x)"));
pres_tree_ms = proto_item_add_subtree(ms, ett_pres_ms); show_user_data(&asn,pres_tree_ms,tvb,&offset,rest_len,s_type); } } /* close asn.1 stream */ asn1_close(&asn, &offset); return offset; } /* * Dissect PPDUs inside a SPDU. */ static void dissect_pres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; /* first, try to check length */ /* do we have at least 4 bytes */ if (!tvb_bytes_exist(tvb, 0, 4)) {proto_tree_add_text(tree, tvb, offset, tvb_reported_length_remaining(tvb, offset),
"User data"); return; /* no, it isn't a presentation PDU */ } /* we can't make any additional checking here */ /* postpone it before dissector will have more information */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "PRES"); if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); /* save pointers for calling the acse dissector */ global_tree = tree; global_pinfo = pinfo; while (tvb_reported_length_remaining(tvb, offset) > 0) { offset = dissect_ppdu(tvb, offset, pinfo, tree); if(offset == FALSE ) { proto_tree_add_text(tree, tvb, offset, -1,"Internal error"); offset = tvb_length(tvb); break; } } } void proto_register_pres(void) { static hf_register_info hf[] = { { &hf_pres_type, { "PPDU Type", "pres.type", FT_UINT8, BASE_DEC, VALS(pres_vals), 0x0, "", HFILL } }, { &hf_pres_length, { "Length", "pres.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } }, { &hf_cp_type_message_length, { "Message Length", "cp_type.message_length", FT_UINT32, BASE_DEC, NULL, 0x0, "CP type Message Length", HFILL } }, { &hf_pres_rc_type, { "Connection reqiest/confirm", "pres.type", FT_UINT8, BASE_DEC, VALS(pres_vals), 0x0, "Connection reqiest/confirm", HFILL } }, { &hf_pres_ms_type, { "Mode selector", "pres.mode.selector", FT_UINT8, BASE_DEC, NULL, 0x0, "Mode select", HFILL } }, { &hf_pres_protocol_version, { "Protocol version", "pres.protocol.version", FT_UINT16, BASE_HEX, NULL, 0x0, "Protocol version", HFILL } }, { &hf_value, { "Value", "pres.value", FT_UINT8, BASE_DEC, NULL, 0x0, "Value", HFILL } }, { &hf_pres_seq_type, { "Sequence", "pres.sequence", FT_UINT8, BASE_DEC, NULL, 0x0, "Mode select", HFILL } }, { &hf_protocol_version, { "Protocol version 1", "pres.protocol.version", FT_BOOLEAN, 16, NULL, PRES_PROTOCOL_VERGION, "Protocol version 1", HFILL } }, { &hf_context_management, { "Context management", "pres.context.management", FT_BOOLEAN, 16, NULL, PRES_CONTEXT_MANAGEMENT, "Context management", HFILL } }, { &hf_restoration, { "Restoration", "pres.restoration", FT_BOOLEAN, 16, NULL, PRES_RESTORATION, "Restoration", HFILL } }, }; static gint *ett[] = { &ett_pres, &ett_pres_param, &ett_pres_rc, &ett_pres_ms, &ett_pres_itm, }; module_t *pres_module; proto_pres = proto_register_protocol(PROTO_STRING_PRES, "PRES", "pres"); proto_register_field_array(proto_pres, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); pres_module = prefs_register_protocol(proto_pres, NULL); /* * 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("pres", dissect_pres, proto_pres); } void proto_reg_handoff_pres(void) { /* find data dissector */ data_handle = find_dissector("data"); /* define acse sub dissector */ acse_handle = find_dissector("acse"); }
/* packet-pres.h * * Routine to dissect ISO 8823 OSI Presentation Protocol packets * * * 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_PRES "ISO 8823 OSI Presentation Protocol" #define PROTO_STRING_PRES_INFO "ISO 8823 OSI Presentation Protocol." /* type of PPDU */ #define PRES_CONNECTION_REQUEST_CONFIRM 0x31 #define PRES_CONNECTION_REFUSE 0x30 /* asn.1 definitions */ #define ASN1_CLASS_UNIVERSAL 0x00 #define ASN1_CLASS_APPLICATION 0x40 #define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 #define ASN1_CLASS_Private 0xc0 #define ASN1_CLASS_PC 0x20 #define INTEGER_ITEM 0x01 #define BOOLEAN_ITEM 0x01 /* type of parameters */ #define MODE_SELECTOR 0 #define SET_TOP 1 #define SEQUENCE_TOP 2 #define SEQUENCE 0x30 /* sequence top */ #define TAG_00 0 #define TAG_01 1 enum { PROTOCOL_VERSION, CALLING_PRESENTATION_SELECTOR, CALLED_PRESENTATION_SELECTOR, RESPONDING_PRESENTATION_SELECTOR, PRESENTATION_CONTEXT_DEFINITION_LIST, PRESENTATION_CONTEXT_DEFINITION_RESULT_LIST, DEFAULT_CONTEXT_NAME, DEFAULT_CONTEXT_RESULT, PRESENTATION_REQUIREMENTS, USER_SESSION_REQUIREMENTS, PROVIDER_REASON }; /* definition list **/ #define PRESENTATION_CONTEXT_IDENTIFIER 2 #define ABSTRACT_SYNTAX_NAME 6 #define TRANSFER_SYNTAX_NAMES 0x30 /* result list */ #define PRESENTATION_RESULT 0x80 #define PRESENTATION_RESULT_TRANSFER_SYNTAX_NAME 0x81 #define PRESENTATION_RESULT_INTEGER 0x82 /* result values */ #define PRESENTATION_RESULT_ACCEPTANCE 0 #define PRESENTATION_RESULT_USER_REJECTION 1 #define PRESENTATION_RESULT_PROVIDER_REJECTION 2 /* provider reason */ enum { REASON_NOT_SPECIFIED, TEMPORARY_CONGESTION, LOCAL_LIMIT_EXCEEDED, CALLED_PRESENTATION_ADDRESS_UNKNOWN, PROTOCOL_VERSION_NOT_SUPPORTED, DEFAULT_CONTEXT_NOT_SUPPORTED, USER_DATA_NOT_READABLE, NO_PSAP_AVAILABLE }; /* user data */ #define SIMPLY_ENCODED_DATA 0x60 #define FULLY_ENCODED_DATA 0x61 /* PDV */ #define SINGLE_ASN1_TYPE 0xa0 #define OCTET_ALIGNED 0xa1 #define ARBITRARY 0xa2 /* provider reasons */ enum { PR_REASON_NOT_SPECIFIED, UNRECOGNIZED_PDU, UNEXPECTED_PDU, UNEXPECTED_SESSION_SERVICE_PRIMITIVE, UNRECOGNIZED_PPDU_PARAMETER, UNEXPECTED_PPDU_PARAMETER, INVALID_PPDU_PARAMETER_VALUE }; /* event identifier */ enum { REASON_CP_PPDU, REASON_CPA_PPDU, REASON_CPR_PPDU, REASON_ARU_PPDU, REASON_ARP_PPDU, REASON_AC_PPDU, REASON_ACA_PPDU, REASON_TD_PPDU, REASON_TTD_PPDU, REASON_TE_PPDU, REASON_TC_PPDU, REASON_TCC_PPDU, REASON_RS_PPDU, REASON_RSA_PPDU, S_RELEASE_INDICATION, S_RELEASE_CONFIRM, S_TOKEN_GIVE_INDICATION, S_TOKEN_PLEASE_INDICATION, S_CONTROL_GIVE_INDICATION, S_SYNC_MINOR_INDICATION, S_SYNC_MINOR_CONFIRM, S_SYNC_MAJOR_INDICATION, S_SYNC_MAJOR_CONFIRM, S_P_EXCEPTION_REPORT_INDICATION, S_U_EXCEPTION_REPORT_INDICATION, S_ACTIVITY_START_INDICATION, S_ACTIVITY_RESUME_INDICATION, S_ACTIVITY_INTERRUPT_INDICATION, S_ACTIVITY_INTERRUPT_CONFIRM, S_ACTIVITY_DISCARD_INDICATION, S_ACTIVITY_DISCARD_CONFIRM, S_ACTIVITY_END_INDICATION, S_ACTIVITY_END_CONFIRM }; /* flags */ #define PRES_PROTOCOL_VERGION 0x0080 #define PRES_CONTEXT_MANAGEMENT 0x0080 #define PRES_RESTORATION 0x0040 #define ACSE_PRESENTATION_CONTEXT_IDENTIFIER 3 #define MAXSTRING 256 #define UNKNOWN_SES_PDU_TYPE -1 #define ABORT_REASON_LEN 3
- Follow-Ups:
- Re: [Ethereal-dev] New ISO 8823 OSI Presentation Protocol dissector.
- From: Guy Harris
- Re: [Ethereal-dev] New ISO 8823 OSI Presentation Protocol dissector.
- Prev by Date: Re: [Ethereal-dev] Ethereal Client/Server Model
- Next by Date: RE: [Ethereal-dev] Source release 0.10.0a broken for win32 platfo rms!
- Previous by thread: Re: [Ethereal-dev] Source release 0.10.0a broken for win32 platforms!
- Next by thread: Re: [Ethereal-dev] New ISO 8823 OSI Presentation Protocol dissector.
- Index(es):