Index: epan/dissectors/packet-telnet.c =================================================================== --- epan/dissectors/packet-telnet.c (revision 29136) +++ epan/dissectors/packet-telnet.c (working copy) @@ -155,6 +155,17 @@ (strcmp(terminaltype,"IBM-3279-4-E") == 0)) add_tn3270_conversation(pinfo, 0); + if ((strcmp(terminaltype,"IBM-5555-C01") == 0) || /* 24 x 80 Double-Byte Character Set color display */ + (strcmp(terminaltype,"IBM-5555-B01") == 0) || /* 24 x 80 Double-Byte Character Set (DBCS)*/ + (strcmp(terminaltype,"IBM-3477-FC") == 0) || /* 27 x 132 color display*/ + (strcmp(terminaltype,"IBM-3477-FG") == 0) || /* 27 x 132 monochrome display*/ + (strcmp(terminaltype,"IBM-3180-2") == 0) || /* 27 x 132 monochrome display*/ + (strcmp(terminaltype,"IBM-3179-2") == 0) || /* 24 x 80 color display*/ + (strcmp(terminaltype,"IBM-3196-A1") == 0) || /* 24 x 80 monochrome display*/ + (strcmp(terminaltype,"IBM-5292-2") == 0) || /* 24 x 80 color display*/ + (strcmp(terminaltype,"IBM-5291-1") == 0) || /* 24 x 80 monochrome display*/ + (strcmp(terminaltype,"IBM-5251-11") == 0)) /* 24 x 80 monochrome display*/ + add_tn5250_conversation(pinfo, 0); } static void @@ -1844,6 +1855,7 @@ gint offset = 0; guint len = 0; guint is_tn3270 = 0; + guint is_tn5250 = 0; if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "TELNET"); @@ -1852,6 +1864,7 @@ col_set_str(pinfo->cinfo, COL_INFO, "Telnet Data ..."); is_tn3270 = find_tn3270_conversation(pinfo); + is_tn5250 = find_tn5250_conversation(pinfo); if (tree) { int data_len; @@ -1873,11 +1886,14 @@ */ data_len = iac_offset - offset; if (data_len > 0) { - if (is_tn3270) { - next_tvb = tvb_new_subset(tvb, offset, data_len, data_len); - call_dissector(tn3270_handle, next_tvb, pinfo, telnet_tree); - } else - telnet_add_text(telnet_tree, tvb, offset, data_len); + if (is_tn3270) { + next_tvb = tvb_new_subset(tvb, offset, data_len, data_len); + call_dissector(tn3270_handle, next_tvb, pinfo, telnet_tree); + }else if (is_tn5250) { + next_tvb = tvb_new_subset(tvb, offset, data_len, data_len); + call_dissector(tn5250_handle, next_tvb, pinfo, telnet_tree); + } else + telnet_add_text(telnet_tree, tvb, offset, data_len); } /* * Now interpret the command. @@ -1885,7 +1901,7 @@ offset = telnet_command(pinfo, telnet_tree, tvb, iac_offset); } else { /* get more data if tn3270 */ - if (is_tn3270) { + if (is_tn3270 || tn5250) { pinfo->desegment_offset = offset; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return; @@ -1991,4 +2007,5 @@ telnet_handle = create_dissector_handle(dissect_telnet, proto_telnet); dissector_add("tcp.port", TCP_PORT_TELNET, telnet_handle); tn3270_handle = find_dissector("tn3270"); + tn5250_handle = find_dissector("tn5250"); } Index: epan/dissectors/packet-tn5250.c =================================================================== --- epan/dissectors/packet-tn5250.c (revision 0) +++ epan/dissectors/packet-tn5250.c (revision 0) @@ -0,0 +1,4261 @@ +/* packet-tn5250.c + * Routines for tn5250.packet dissection + * + * Reference: + * 5494 Remote Control Unit - Functions Reference + * Release 3.0 Document Number SC30-3533-03 + * + * Copyright 2009, Robert Hogan + * + * $Id: packet-tn5250.c 26356 2008-10-05 23:08:54Z wmeier $ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + * + * + * TODO: + * Check for memleaks + * + * + */ + +#include "packet-tn5250.h" + +static int proto_tn5250 = -1; + +static int hf_tn5250_fa_display=-1; +static int hf_tn5250_fa_graphic_convert1=-1; +static int hf_tn5250_fa_graphic_convert2=-1; +static int hf_tn5250_fa_modified=-1; +static int hf_tn5250_fa_numeric=-1; +static int hf_tn5250_fa_protected=-1; +static int hf_tn5250_fa_reserved=-1; +static int hf_tn5250_field_attribute=-1; +static int hf_tn5250_aid= -1; +static int hf_tn5250_all_character_attributes= -1; +static int hf_tn5250_attribute_type= -1; +static int hf_tn5250_begin_end_flags1= -1; +static int hf_tn5250_begin_end_flags2= -1; +static int hf_tn5250_bsc= -1; +static int hf_tn5250_buffer_x= -1; +static int hf_tn5250_buffer_y= -1; +static int hf_tn5250_c_cav= -1; +static int hf_tn5250_cc= -1; +static int hf_tn5250_character_code= -1; +static int hf_tn5250_character_set= -1; +static int hf_tn5250_charset= -1; +static int hf_tn5250_checkpoint= -1; +static int hf_tn5250_c_ci= -1; +static int hf_tn5250_c_offset= -1; +static int hf_tn5250_color= -1; +static int hf_tn5250_color_command= -1; +static int hf_tn5250_color_flags= -1; +static int hf_tn5250_command_code= -1; +static int hf_tn5250_cro= -1; +static int hf_tn5250_c_scsoff= -1; +static int hf_tn5250_c_seqoff= -1; +static int hf_tn5250_c_sequence= -1; +static int hf_tn5250_cursor_x= -1; +static int hf_tn5250_cursor_y= -1; +static int hf_tn5250_cw= -1; +static int hf_tn5250_data_chain_bitmask= -1; +static int hf_tn5250_destination_or_origin_bitmask= -1; +static int hf_tn5250_dl= -1; +static int hf_tn5250_double_byte_sf_id= -1; +static int hf_tn5250_erase_flags= -1; +static int hf_tn5250_exception_or_status_flags= -1; +static int hf_tn5250_extended_highlighting= -1; +static int hf_tn5250_extended_ps_color= -1; +static int hf_tn5250_extended_ps_echar= -1; +static int hf_tn5250_extended_ps_flags= -1; +static int hf_tn5250_extended_ps_length= -1; +static int hf_tn5250_extended_ps_lw= -1; +static int hf_tn5250_extended_ps_lh= -1; +static int hf_tn5250_extended_ps_nh= -1; +static int hf_tn5250_extended_ps_nw= -1; +static int hf_tn5250_extended_ps_res= -1; +static int hf_tn5250_extended_ps_stsubs= -1; +static int hf_tn5250_extended_ps_subsn= -1; +static int hf_tn5250_featl= -1; +static int hf_tn5250_feats= -1; +static int hf_tn5250_field_data= -1; +static int hf_tn5250_field_outlining= -1; +static int hf_tn5250_field_validation_mandatory_entry= -1; +static int hf_tn5250_field_validation_mandatory_fill= -1; +static int hf_tn5250_field_validation_trigger= -1; +static int hf_tn5250_format_group= -1; +static int hf_tn5250_format_name= -1; +static int hf_tn5250_fov= -1; +static int hf_tn5250_fpc= -1; +static int hf_tn5250_hilite= -1; +static int hf_tn5250_h_length= -1; +static int hf_tn5250_h_offset= -1; +static int hf_tn5250_horizon= -1; +static int hf_tn5250_h_sequence= -1; +static int hf_tn5250_hw= -1; +static int hf_tn5250_interval= -1; +static int hf_tn5250_limin= -1; +static int hf_tn5250_limout= -1; +static int hf_tn5250_lines= -1; +static int hf_tn5250_load_color_command= -1; +static int hf_tn5250_load_format_storage_flags1= -1; +static int hf_tn5250_load_format_storage_flags2= -1; +static int hf_tn5250_load_format_storage_format_data= -1; +static int hf_tn5250_load_format_storage_localname= -1; +static int hf_tn5250_load_format_storage_operand= -1; +static int hf_tn5250_load_line_type_command= -1; +static int hf_tn5250_lvl= -1; +static int hf_tn5250_mode= -1; +static int hf_tn5250_msr_ind_mask= -1; +static int hf_tn5250_msr_ind_value= -1; +static int hf_tn5250_msr_state_mask= -1; +static int hf_tn5250_msr_state_value= -1; +static int hf_tn5250_msr_type= -1; +static int hf_tn5250_ap_na= -1; +static int hf_tn5250_ap_m= -1; +static int hf_tn5250_ap_vertical_scrolling=-1; +static int hf_tn5250_ap_horizontal_scrolling=-1; +static int hf_tn5250_ap_apres1=-1; +static int hf_tn5250_ap_apa=-1; +static int hf_tn5250_ap_pp=-1; +static int hf_tn5250_ap_lc=-1; +static int hf_tn5250_ap_mp=-1; +static int hf_tn5250_ap_apres2=-1; +static int hf_tn5250_c_np= -1; +static int hf_tn5250_number_of_attributes= -1; +static int hf_tn5250_object_control_flags= -1; +static int hf_tn5250_object_type= -1; +static int hf_tn5250_operation_type= -1; +static int hf_tn5250_order_code= -1; +static int hf_tn5250_outbound_text_header_hdr= -1; +static int hf_tn5250_outbound_text_header_lhdr= -1; +static int hf_tn5250_pages= -1; +static int hf_tn5250_partition_command= -1; +static int hf_tn5250_partition_cv= -1; +static int hf_tn5250_partition_cw= -1; +static int hf_tn5250_partition_flags= -1; +static int hf_tn5250_partition_height= -1; +static int hf_tn5250_partition_hv= -1; +static int hf_tn5250_partition_id= -1; +static int hf_tn5250_partition_ph= -1; +static int hf_tn5250_partition_pw= -1; +static int hf_tn5250_partition_res= -1; +static int hf_tn5250_partition_rs= -1; +static int hf_tn5250_partition_rv= -1; +static int hf_tn5250_partition_rw= -1; +static int hf_tn5250_partition_uom= -1; +static int hf_tn5250_partition_width= -1; +static int hf_tn5250_partition_wv= -1; +static int hf_tn5250_prime= -1; +static int hf_tn5250_printer_flags= -1; +static int hf_tn5250_ps_char= -1; +static int hf_tn5250_ps_flags= -1; +static int hf_tn5250_ps_lcid= -1; +static int hf_tn5250_ps_rws= -1; +static int hf_tn5250_query_reply_alphanumeric_flags= -1; +static int hf_tn5250_recovery_data_flags= -1; +static int hf_tn5250_reply_mode_attr_list= -1; +static int hf_tn5250_reqtyp= -1; +static int hf_tn5250_resbyte= -1; +static int hf_tn5250_resbytes= -1; +static int hf_tn5250_res_twobytes= -1; +static int hf_tn5250_rw= -1; +static int hf_tn5250_save_or_restore_format_flags= -1; +static int hf_tn5250_scs_data= -1; +static int hf_tn5250_sf_outbound_id= -1; +static int hf_tn5250_sf_inbound_id= -1; +static int hf_tn5250_sf_inbound_outbound_id= -1; +static int hf_tn5250_sf_length= -1; +static int hf_tn5250_sf_query_replies=-1; +static int hf_tn5250_sld= -1; +static int hf_tn5250_spd= -1; +static int hf_tn5250_start_line= -1; +static int hf_tn5250_start_page= -1; +static int hf_tn5250_stop_address= -1; +static int hf_tn5250_transparency= -1; +static int hf_tn5250_type_1_text_outbound_data= -1; +static int hf_tn5250_vertical= -1; +static int hf_tn5250_v_length= -1; +static int hf_tn5250_v_offset= -1; +static int hf_tn5250_v_sequence= -1; +static int hf_tn5250_wcc= -1; +static int hf_tn5250_wcc_nop= -1; +static int hf_tn5250_wcc_reset= -1; +static int hf_tn5250_wcc_printer1=-1; +static int hf_tn5250_wcc_printer2=-1; +static int hf_tn5250_wcc_start_printer=-1; +static int hf_tn5250_wcc_sound_alarm=-1; +static int hf_tn5250_wcc_keyboard_restore=-1; +static int hf_tn5250_wcc_reset_mdt=-1; +static int hf_tn5250_ww= -1; +static int hf_tn5250_tn5250e_data_type= -1; +static int hf_tn5250_tn5250e_request_flag= -1; +static int hf_tn5250_tn5250e_response_flag_3270_SCS= -1; +static int hf_tn5250_tn5250e_response_flag_response= -1; +static int hf_tn5250_tn5250e_seq_number= -1; +static int hf_tn5250_tn5250e_header_data=-1; +static int hf_tn5250_ua_cell_units=-1; +static int hf_tn5250_ua_characters=-1; +static int hf_tn5250_ua_hard_copy=-1; +static int hf_tn5250_ua_page_printer=-1; +static int hf_tn5250_ua_reserved1=-1; +static int hf_tn5250_ua_reserved2=-1; +static int hf_tn5250_ua_variable_cells=-1; +static int hf_tn5250_usable_area_flags1=-1; +static int hf_tn5250_usable_area_flags2=-1; +static int hf_tn5250_ua_addressing=-1; +static int hf_tn5250_ua_width_cells_pels=-1; +static int hf_tn5250_ua_height_cells_pels=-1; +static int hf_tn5250_ua_uom_cells_pels=-1; +static int hf_tn5250_ua_xr=-1; +static int hf_tn5250_ua_yr=-1; +static int hf_tn5250_ua_aw=-1; +static int hf_tn5250_ua_ah=-1; +static int hf_tn5250_ua_buffsz=-1; +static int hf_tn5250_ua_xmin=-1; +static int hf_tn5250_ua_ymin=-1; +static int hf_tn5250_ua_xmax=-1; +static int hf_tn5250_ua_ymax=-1; +static int hf_tn5250_cs_ge=-1; +static int hf_tn5250_cs_mi=-1; +static int hf_tn5250_cs_lps=-1; +static int hf_tn5250_cs_lpse=-1; +static int hf_tn5250_cs_ms=-1; +static int hf_tn5250_cs_ch2=-1; +static int hf_tn5250_cs_gf=-1; +static int hf_tn5250_cs_res=-1; +static int hf_tn5250_cs_res2=-1; +static int hf_tn5250_cs_pscs=-1; +static int hf_tn5250_cs_res3=-1; +static int hf_tn5250_cs_cf=-1; +static int hf_tn5250_cs_form_type1=-1; +static int hf_tn5250_cs_form_type2=-1; +static int hf_tn5250_cs_form_type3=-1; +static int hf_tn5250_cs_form_type4=-1; +static int hf_tn5250_cs_form_type5=-1; +static int hf_tn5250_cs_form_type6=-1; +static int hf_tn5250_cs_form_type8=-1; +static int hf_tn5250_cs_ds_load=-1; +static int hf_tn5250_cs_ds_triple=-1; +static int hf_tn5250_cs_ds_char=-1; +static int hf_tn5250_cs_ds_cb=-1; +static int hf_tn5250_character_sets_flags1=-1; +static int hf_tn5250_character_sets_flags2=-1; +static int hf_tn5250_sdw=-1; +static int hf_tn5250_sdh=-1; +static int hf_tn5250_form=-1; +static int hf_tn5250_formres=-1; +static int hf_tn5250_formres2=-1; +static int hf_tn5250_cs_dl=-1; +static int hf_tn5250_cs_descriptor_set=-1; +static int hf_tn5250_cs_descriptor_flags=-1; +static int hf_tn5250_lcid=-1; +static int hf_tn5250_sw=-1; +static int hf_tn5250_sh=-1; +static int hf_tn5250_ssubsn=-1; +static int hf_tn5250_esubsn=-1; +static int hf_tn5250_ccsgid=-1; +static int hf_tn5250_ccsid=-1; +static int hf_tn5250_c_prtblk=-1; +static int hf_tn5250_h_np=-1; +static int hf_tn5250_h_vi=-1; +static int hf_tn5250_h_ai=-1; +static int hf_tn5250_ddm_flags=-1; +static int hf_tn5250_ddm_limin=-1; +static int hf_tn5250_ddm_limout=-1; +static int hf_tn5250_ddm_nss=-1; +static int hf_tn5250_ddm_ddmss=-1; +static int hf_tn5250_rpq_device=-1; +static int hf_tn5250_rpq_mid=-1; +static int hf_tn5250_rpq_rpql=-1; +static int hf_tn5250_rpq_name=-1; +static int hf_tn5250_ip_flags=-1; +static int hf_tn5250_ipdd_length=-1; +static int hf_tn5250_ip_id=-1; +static int hf_tn5250_ipdd_wd=-1; +static int hf_tn5250_ipdd_hd=-1; +static int hf_tn5250_ipdd_wa=-1; +static int hf_tn5250_ipdd_ha=-1; +static int hf_tn5250_ippd_dpbs=-1; +static int hf_tn5250_ippd_apbs=-1; +static int hf_tn5250_ipccd_wcd=-1; +static int hf_tn5250_ipccd_hcd=-1; +static int hf_tn5250_ipccd_wca=-1; +static int hf_tn5250_ipccd_hca=-1; +static int hf_tn5250_dc_dir_flags=-1; +static int hf_tn5250_dc_both=-1; +static int hf_tn5250_dc_from_device=-1; +static int hf_tn5250_dc_to_device=-1; +static int hf_tn5250_oem_dsref=-1; +static int hf_tn5250_oem_dtype=-1; +static int hf_tn5250_oem_uname=-1; +static int hf_tn5250_sdp_daid=-1; +static int hf_tn5250_oem_sdp_ll_limin=-1; +static int hf_tn5250_oem_sdp_ll_limout=-1; +static int hf_tn5250_oem_sdp_pclk_vers=-1; +static int hf_tn5250_null=-1; +static int hf_tn5250_unknown_data=-1; +static int hf_tn5250_ds_default_sfid=-1; +static int hf_tn5250_ds_sfid=-1; +static int hf_tn5250_asia_sdp_sosi_soset=-1; +static int hf_tn5250_asia_sdp_ic_func=-1; +static int hf_tn5250_ccc=-1; +static int hf_tn5250_ccc_coding=-1; +static int hf_tn5250_ccc_printout=-1; +static int hf_tn5250_ccc_start_print=-1; +static int hf_tn5250_ccc_sound_alarm=-1; +static int hf_tn5250_ccc_copytype=-1; +static int hf_tn5250_msr_user=-1; +static int hf_tn5250_msr_locked=-1; +static int hf_tn5250_msr_auto=-1; +static int hf_tn5250_msr_ind1=-1; +static int hf_tn5250_msr_ind2=-1; +static int hf_tn5250_spc_sdp_ot=-1; +static int hf_tn5250_spc_sdp_ob=-1; +static int hf_tn5250_spc_sdp_ol=-1; +static int hf_tn5250_spc_sdp_or=-1; +static int hf_tn5250_spc_sdp_eucflags=-1; +static int hf_tn5250_spc_sdp_srepc=-1; +static int hf_tn5250_srf_fpcb=-1; +static int hf_tn5250_sdp_statcode=-1; +static int hf_tn5250_sdp_excode=-1; +static int hf_tn5250_sdp_ngl=-1; +static int hf_tn5250_sdp_nml=-1; +static int hf_tn5250_sdp_nlml=-1; +static int hf_tn5250_sdp_stor=-1; +static int hf_tn5250_ap_cm=-1; +static int hf_tn5250_ap_ro=-1; +static int hf_tn5250_ap_co=-1; +static int hf_tn5250_ap_fo=-1; +static int hf_tn5250_sdp_ln=-1; +static int hf_tn5250_sdp_id=-1; +static int hf_tn5250_db_cavdef=-1; +static int hf_tn5250_db_cidef=-1; +static int hf_tn5250_dia_flags=-1; +static int hf_tn5250_dia_limin=-1; +static int hf_tn5250_dia_limout=-1; +static int hf_tn5250_dia_nfs=-1; +static int hf_tn5250_dia_diafs=-1; +static int hf_tn5250_dia_diafn=-1; +static int hf_tn5250_fo_flags=-1; +static int hf_tn5250_fo_vpos=-1; +static int hf_tn5250_fo_hpos=-1; +static int hf_tn5250_fo_hpos0=-1; +static int hf_tn5250_fo_hpos1=-1; +static int hf_tn5250_fsad_flags=-1; +static int hf_tn5250_fsad_limin=-1; +static int hf_tn5250_fsad_limout=-1; +static int hf_tn5250_fsad_size=-1; +static int hf_tn5250_ibm_flags=-1; +static int hf_tn5250_ibm_limin=-1; +static int hf_tn5250_ibm_limout=-1; +static int hf_tn5250_ibm_type=-1; +static int hf_tn5250_msr_nd=-1; +static int hf_tn5250_pft_flags=-1; +static int hf_tn5250_pft_tmo=-1; +static int hf_tn5250_pft_bmo=-1; +static int hf_tn5250_ioca_limin=-1; +static int hf_tn5250_ioca_limout=-1; +static int hf_tn5250_ioca_type=-1; +static int hf_tn5250_pc_vo_thickness=-1; +static int hf_tn5250_pdds_ssid=-1; +static int hf_tn5250_pdds_refid=-1; +static int hf_tn5250_srf_fpcbl=-1; +static int hf_tn5250_spc_epc_flags=-1; +static int hf_tn5250_sp_spid=-1; +static int hf_tn5250_sp_size=-1; +static int hf_tn5250_sp_space=-1; +static int hf_tn5250_sp_objlist=-1; +static int hf_tn5250_tp_nt=-1; +static int hf_tn5250_tp_m=-1; +static int hf_tn5250_tp_flags=-1; +static int hf_tn5250_tp_ntt=-1; +static int hf_tn5250_tp_tlist=-1; +static int hf_tn5250_t_np=-1; +static int hf_tn5250_t_vi=-1; +static int hf_tn5250_t_ai=-1; +static int hf_tn5250_3270_tranlim=-1; + +static gint ett_tn5250 = -1; +static gint ett_sf = -1; +static gint ett_tn5250_field_attribute = -1; +static gint ett_tn5250_field_validation = -1; +static gint ett_tn5250_wcc = -1; +static gint ett_tn5250_usable_area_flags1 = -1; +static gint ett_tn5250_usable_area_flags2 = -1; +static gint ett_tn5250_query_reply_alphanumeric_flags=-1; +static gint ett_tn5250_character_sets_flags1=-1; +static gint ett_tn5250_character_sets_flags2=-1; +static gint ett_tn5250_character_sets_form=-1; +static gint ett_tn5250_cs_descriptor_flags=-1; +static gint ett_tn5250_color_flags=-1; +static gint ett_tn5250_dc_dir_flags=-1; +static gint ett_tn5250_ccc=-1; +static gint ett_tn5250_msr_state_mask=-1; + +tn5250_conv_info_t *tn5250_info_items; + +void proto_reg_handoff_tn5250(void); + +gint dissect_orders_and_data(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset); + +typedef struct hf_items { + int hf; + gint bitmask_ett; + int length; + const int **bitmask; +} hf_items; + +/* Utility Functions */ + +static gint +tn5250_add_hf_items(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + hf_items *fields) +{ + int start=offset; + int i; + + for (i = 0; fields[i].hf; ++i) { + if (fields[i].bitmask == 0) { + proto_tree_add_item(tn5250_tree, + fields[i].hf, + tvb, offset, + fields[i].length, + FALSE); + } else { + proto_tree_add_bitmask(tn5250_tree, tvb, offset, fields[i].hf, + fields[i].bitmask_ett, fields[i].bitmask, FALSE); + } + offset+=fields[i].length; + } + return (offset - start); +} + +static gint +dissect_unknown_data(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint start, + gint sf_length) +{ + int len_left; + + len_left = (sf_length - 4) - (offset - start); + + if (len_left > 0) { + proto_tree_add_item(tn5250_tree, hf_tn5250_unknown_data, + tvb, offset, len_left, + FALSE); + return len_left; + } + return 0; +} + +static gint +add_data_until_next_order_code(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int datalen = 0; + gint order_code = 0; + + while (tvb_offset_exists(tvb, (offset + datalen))) { + order_code = tvb_get_guint8(tvb, (offset + datalen)); + switch (order_code) { + case SF: + /*dummy*/ + case SFE: + case SA: + case MF: + case IC: + case PT: + case RA: + case EUA: + case GE: + case SBA: + goto done; + default: + datalen++; + break; + } + } + +done: + if (datalen) { + proto_tree_add_item(tn5250_tree, + hf_tn5250_field_data, + tvb, offset, + datalen, + FALSE); + } + return datalen; +} + +static gint +dissect_query_reply_resbytes(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + + hf_items fields[] = { + { hf_tn5250_res_twobytes, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +int +dissect_wcc(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + static const int *wcc_fields[] = { + &hf_tn5250_wcc_nop, + &hf_tn5250_wcc_reset, + &hf_tn5250_wcc_printer1, + &hf_tn5250_wcc_printer2, + &hf_tn5250_wcc_start_printer, + &hf_tn5250_wcc_sound_alarm, + &hf_tn5250_wcc_keyboard_restore, + &hf_tn5250_wcc_reset_mdt, + NULL + }; + + /* Qualifier and DeviceType */ + proto_tree_add_bitmask_text(tn5250_tree, tvb, offset, 1, "Write Control Character: ", "None", + ett_tn5250_wcc, wcc_fields, TRUE, 0); + return 1; + +} + +static gint +dissect_3270_field_validation(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + + static const int *byte[] = { + &hf_tn5250_field_validation_mandatory_fill, + &hf_tn5250_field_validation_mandatory_entry, + &hf_tn5250_field_validation_trigger, + NULL + }; + + proto_tree_add_bitmask_text(tn5250_tree, tvb, 1, 1, "Field Validation: ", + "None", ett_tn5250_field_validation, byte, TRUE, 0); + + offset++; + return (offset - start); +} + + +static gint +dissect_3270_field_attribute(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + + static const int *byte[] = { + &hf_tn5250_fa_display, + &hf_tn5250_fa_graphic_convert1, + &hf_tn5250_fa_graphic_convert2, + &hf_tn5250_fa_modified, + &hf_tn5250_fa_numeric, + &hf_tn5250_fa_protected, + &hf_tn5250_fa_reserved, + NULL + }; + + + proto_tree_add_bitmask(tn5250_tree, tvb, offset, hf_tn5250_field_attribute, + ett_tn5250_field_attribute, byte, FALSE); + + offset++; + return (offset - start); +} + +/* 8.7 - Copy Control Code */ +static gint +dissect_ccc(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + + static const int *byte[] = { + &hf_tn5250_ccc_coding, + &hf_tn5250_ccc_printout, + &hf_tn5250_ccc_start_print, + &hf_tn5250_ccc_sound_alarm, + &hf_tn5250_ccc_copytype, + NULL + }; + + + + proto_tree_add_bitmask(tn5250_tree, tvb, offset, hf_tn5250_ccc, + ett_tn5250_ccc, byte, FALSE); + + offset++; + return (offset - start); +} + +/* End - Utility Functions */ + +/* Start: Handle Structured Fields */ + +/* --------------------------------------------------- */ +/* 5.0 Outbound/Inbound and Outbound Structured Fields */ +/* --------------------------------------------------- */ + +/* 5.5 Activate Partition - Search for ACTIVATE_PARTITION */ +/* 5.6 Begin/End of File - Search for BEGIN_OR_END_OF_FILE */ +/* 5.7 Create Partition */ +static gint +dissect_create_partition(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_partition_uom, 0, 1, 0 }, + { hf_tn5250_partition_flags, 0, 1, 0 }, + { hf_tn5250_partition_height, 0, 2, 0 }, + { hf_tn5250_partition_width, 0, 2, 0 }, + { hf_tn5250_partition_rv, 0, 2, 0 }, + { hf_tn5250_partition_cv, 0, 2, 0 }, + { hf_tn5250_partition_hv, 0, 2, 0 }, + { hf_tn5250_partition_wv, 0, 2, 0 }, + { hf_tn5250_partition_rw, 0, 2, 0 }, + { hf_tn5250_partition_cw, 0, 2, 0 }, + { hf_tn5250_partition_rs, 0, 2, 0 }, + { hf_tn5250_partition_res, 0, 2, 0 }, + { hf_tn5250_partition_pw, 0, 2, 0 }, + { hf_tn5250_partition_ph, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.7 Create Partition - Search for CREATE_PARTITION */ +/* 5.8 Destroy Partition - Search for DESTROY_PARTITION */ +/* 5.9 Erase/Reset - Search for ERASE_OR_RESET */ +/* 5.10 Load Color Table - Search for LOAD_COLOR_TABLE */ + +/* 5.11 Load Format Storage */ +static gint +dissect_load_format_storage(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint sf_length) +{ + int start=offset; + int operand; + + hf_items fields[] = { + { hf_tn5250_load_format_storage_flags1, 0, 1, 0 }, + { hf_tn5250_load_format_storage_flags2, 0, 1, 0 }, + { hf_tn5250_load_format_storage_operand, 0, 1, 0 }, + { hf_tn5250_load_format_storage_localname, 0, 8, 0 }, + { hf_tn5250_format_group, 0, 6, 0 }, + { hf_tn5250_format_name, 0, 16, 0 }, + { 0, 0, 0, 0 }, + }; + + operand = tvb_get_guint8(tvb, offset+2); + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + if (operand == ADD) { + int fmtln = ((sf_length - 4) - (offset - start)); + proto_tree_add_item(tn5250_tree, hf_tn5250_load_format_storage_format_data, + tvb, offset, fmtln, FALSE); + offset+=fmtln; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.12 Load Line Type - Search for LOAD_LINE_TYPE */ + +/* 5.13 Load Programmed Symbols (Load PS) */ +static gint +dissect_load_programmed_symbols(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint sf_length) +{ + int start=offset, i; + gint8 flags; + gint8 extended_ps_length; + hf_items ps_fields[] = { + { hf_tn5250_ps_flags, 0, 1, 0 }, + { hf_tn5250_ps_lcid, 0, 1, 0 }, + { hf_tn5250_ps_char, 0, 1, 0 }, + { hf_tn5250_ps_rws, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items extended_ps_fields[] = { + { hf_tn5250_extended_ps_lw, 0, 1, 0 }, + { hf_tn5250_extended_ps_lh, 0, 1, 0 }, + { hf_tn5250_extended_ps_subsn, 0, 1, 0 }, + { hf_tn5250_extended_ps_color, 0, 1, 0 }, + { hf_tn5250_extended_ps_stsubs, 0, 1, 0 }, + { hf_tn5250_extended_ps_echar, 0, 1, 0 }, + { hf_tn5250_extended_ps_nw, 0, 1, 0 }, + { hf_tn5250_extended_ps_nh, 0, 1, 0 }, + { hf_tn5250_extended_ps_res, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + flags = tvb_get_guint8(tvb, offset); + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + ps_fields); + + /*If extended flag not set return */ + if (!(flags & 0x80)) { + return (offset - start); + } + + extended_ps_length = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, hf_tn5250_extended_ps_length, + tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tn5250_tree, hf_tn5250_extended_ps_flags, + tvb, offset, 1, FALSE); + offset++; + + for (i = 0; i < extended_ps_length; ++i) { + proto_tree_add_item(tn5250_tree, extended_ps_fields[i].hf, + tvb, offset, extended_ps_fields[i].length, FALSE); + offset+=extended_ps_fields[i].length; + } + + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.14 Modify Partition) */ +static gint +dissect_modify_partition(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_partition_flags, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_resbytes, 0, 2, 0 }, + { hf_tn5250_partition_rv, 0, 2, 0 }, + { hf_tn5250_partition_cv, 0, 2, 0 }, + { hf_tn5250_partition_hv, 0, 2, 0 }, + { hf_tn5250_partition_wv, 0, 2, 0 }, + { hf_tn5250_partition_rw, 0, 2, 0 }, + { hf_tn5250_partition_cw, 0, 2, 0 }, + { hf_tn5250_partition_rs, 0, 2, 0 }, + { hf_tn5250_partition_res, 0, 2, 0 }, + { hf_tn5250_partition_pw, 0, 2, 0 }, + { hf_tn5250_partition_ph, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.15 Outbound Text Header */ +static gint +dissect_outbound_text_header(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + gint16 hdr_length; + + hf_items outbound_text_header_fields1[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_operation_type, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items outbound_text_header_fields2[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_lvl, 0, 1, 0 }, + { hf_tn5250_cro, 0, 2, 0 }, + { hf_tn5250_cc, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + outbound_text_header_fields1); + offset += dissect_wcc(tn5250_tree, tvb, offset); + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + outbound_text_header_fields2); + + hdr_length = tvb_get_ntohs(tvb, offset); + + proto_tree_add_item(tn5250_tree, hf_tn5250_outbound_text_header_lhdr, + tvb, offset, 2, FALSE); + offset+=2; + + proto_tree_add_item(tn5250_tree, hf_tn5250_outbound_text_header_hdr, + tvb, offset, hdr_length, FALSE); + offset+=hdr_length; + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.16 Outbound 3270DS */ +static gint +dissect_outbound_3270ds(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int cmd; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + + cmd = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_command, + tvb, offset, + 1, + FALSE); + offset++; + + /* FIXME: the spec is ambiguous at best about what to expect here, + need a live sample to validate. */ + switch (cmd) { + case SNA_BSC: + offset += dissect_ccc(tn5250_tree, tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_bsc, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + case W: + case EW: + case EWA: + case EAU: + case SNA_W: + case SNA_EW: + case SNA_EWA: + case SNA_EAU: + /* WCC */ + if ((offset - start) < (sf_length - 3)) + offset += dissect_wcc(tn5250_tree, tvb, offset); + if ((offset - start) < (sf_length - 3)) + offset += dissect_orders_and_data(tn5250_tree, tvb, offset); + break; + default: + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.17 Present Absolute Format */ +static gint +dissect_present_absolute_format(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_fpc, + tvb, offset, + 1, + FALSE); + offset++; + + offset+=dissect_wcc(tn5250_tree, tvb, offset); + + proto_tree_add_item(tn5250_tree, + hf_tn5250_format_name, + tvb, offset, + (sf_length - 5), + FALSE); + offset+=(sf_length - 5); + return (offset - start); +} + +/* 5.18 Present Relative Format */ +static gint +dissect_present_relative_format(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_fov, + tvb, offset, + 2, + FALSE); + offset+=2; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_fpc, + tvb, offset, + 1, + FALSE); + offset++; + + offset += dissect_wcc(tn5250_tree, tvb, offset); + + proto_tree_add_item(tn5250_tree, + hf_tn5250_format_name, + tvb, offset, + (sf_length - 7), + FALSE); + offset+=(sf_length - 7); + return (offset - start); +} + +/* 5.19 Read Partition */ +static gint +dissect_read_partition(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int type; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + + type = tvb_get_guint8(tvb, offset); + if (type == 0xFF) { /* Partition ID of 0xFF is escaped with another 0xFF */ + offset++; + type = tvb_get_guint8(tvb, offset); + } + + proto_tree_add_item(tn5250_tree, + hf_tn5250_operation_type, + tvb, offset, + 1, + FALSE); + offset++; + + if (type == 0x03) { /* 'Query List' */ + proto_tree_add_item(tn5250_tree, + hf_tn5250_reqtyp, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_query_replies, + tvb, offset, + (sf_length - 6), + FALSE); + offset+=(sf_length - 6); + } + return (offset - start); +} + +/*5.20 Request Recovery Data - Search for REQUEST_RECOVERY_DATA*/ +/*5.21 Reset Partition - Search for RESET_PARTITION */ + +/*5.22 Restart */ +static gint +dissect_restart(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbyte, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_start_page, + tvb, offset, + 2, + FALSE); + offset+=2; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_start_line, + tvb, offset, + 2, + FALSE); + offset+=2; + + + proto_tree_add_item(tn5250_tree, + hf_tn5250_scs_data, + tvb, offset, + (sf_length - 9), + FALSE); + offset+=(sf_length - 9); + + return (offset - start); +} + +/* 5.23 SCS Data - Search for SCS_DATA */ +/* 5.24 Color Table - Search for COLOR_TABLE */ +/* 5.25 Format Group - Search for FORMAT_GROUP */ +/* 5.26 Set Checkpoint Interval - Search for CHECKPOINT_INTERVAL */ + +/* 5.27 Set MSR Control */ +static gint +dissect_set_msr_control(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + static const int *byte[] = { + &hf_tn5250_msr_user, + &hf_tn5250_msr_locked, + &hf_tn5250_msr_auto, + &hf_tn5250_msr_ind1, + &hf_tn5250_msr_ind2, + NULL + }; + + hf_items outbound_text_header_fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_msr_type, 0, 1, 0 }, + { hf_tn5250_msr_state_mask, ett_tn5250_msr_state_mask, 1, byte }, + { hf_tn5250_msr_state_value, 1, 1, 0 }, + { hf_tn5250_msr_ind_mask, 1, 1, 0 }, + { hf_tn5250_msr_ind_value, 1, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + outbound_text_header_fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.28 Set Partition Characteristics */ +static gint +dissect_set_partition_characteristics_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + guint16 sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_spc_sdp_ot, 0, 1, 0 }, + { hf_tn5250_spc_sdp_ob, 0, 1, 0 }, + { hf_tn5250_spc_sdp_ol, 0, 1, 0 }, + { hf_tn5250_spc_sdp_or, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_spc_sdp_eucflags, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp3[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_spc_sdp_eucflags, 0, 1, 0 }, + { hf_tn5250_spc_sdp_eucflags, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + sdp = tvb_get_ntohs(tvb, offset); + + switch (sdp) { + case 0x0601: /*View Outport*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + case 0x0304: /*Enable User Call Up*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp2); + break; + case 0x0405: /*Select Base Character Set*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp3); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_set_partition_characteristics(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + + int start=offset; + int i; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_resbytes, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + offset += dissect_set_partition_characteristics_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.29 Set Printer Characteristics */ +static gint +dissect_set_printer_characteristics_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + guint16 sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_spc_sdp_srepc, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + sdp = tvb_get_ntohs(tvb, offset); + + switch (sdp) { + case 0x0301: /*Early Print Complete*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_set_printer_characteristics(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + + int start=offset; + int i; + + hf_items fields[] = { + { hf_tn5250_printer_flags, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + offset += dissect_set_printer_characteristics_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + + +/* 5.30 Set Reply Mode */ +static gint +dissect_set_reply_mode(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int type; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_mode, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + type = tvb_get_guint8(tvb, offset+1); + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + if (type == 0x02) { /* 'Query List' */ + proto_tree_add_item(tn5250_tree, + hf_tn5250_reply_mode_attr_list, + tvb, offset, + (sf_length - 5), + FALSE); + offset+=(sf_length - 5); + } + return (offset - start); +} + +/* 5.31 Set Window Origin - Search for SET_WINDOW_ORIGIN */ +/* 6.6 Type 1 Text Inbound + 5.32 Type 1 Text Outbound */ +static gint +dissect_type_1_text(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_resbytes, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + proto_tree_add_item(tn5250_tree, + hf_tn5250_field_data, + tvb, offset, + (sf_length - 7), + FALSE); + offset+=(sf_length - 7); + return (offset - start); +} + +/* 5.34 Data Chain - Search for DATA_CHAIN*/ +/* 5.35 Destination/Origin - Search for DESTINATION_OR_ORIGIN*/ + +/* 5.36 Object Control */ +static gint +dissect_object_control(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_object_control_flags, 0, 1, 0 }, + { hf_tn5250_object_type, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + proto_tree_add_item(tn5250_tree, + hf_tn5250_type_1_text_outbound_data, + tvb, offset, + (sf_length - 7), + FALSE); + offset+=(sf_length - 7); + return (offset - start); +} + +/* 5.37 Object Data - Search for OBJECT_DATA*/ +/* 5.38 Object Picture - Search for OBJECT_PICTURE */ +/* 5.39 OEM Data - Search for OEM_DATA */ + +/* 5.40 Save/Restore Format */ +static gint +dissect_save_or_restore_format(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_save_or_restore_format_flags, 0, 1, 0 }, + { hf_tn5250_srf_fpcb, 0, (sf_length-5), 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 5.41 Select Intelligent Printer Data Stream (IPDS) Mode - Search for SELECT_IPDS_MODE*/ + +/* -----------------------------------------*/ +/* 6.0 CHAPTER 6. INBOUND STRUCTURED FIELDS */ +/* -----------------------------------------*/ + +/* 6.2 Exception/Status */ +static gint +dissect_exception_or_status_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + guint16 sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_sdp_excode, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_sdp_statcode, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp3[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_format_group, 0, 16, 0 }, + { hf_tn5250_format_name, 0, 16, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp4[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_sdp_ngl, 0, 2, 0 }, + { hf_tn5250_sdp_nml, 0, 2, 0 }, + { hf_tn5250_sdp_nlml, 0, 2, 0 }, + { hf_tn5250_sdp_stor, 0, 4, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp5[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_format_group, 0, 16, 0 }, + { hf_tn5250_sdp_nml, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + sdp = tvb_get_ntohs(tvb, offset); + + switch (sdp) { + case 0x0601: /*Auxiliary Device Exception*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + case 0x0402: /*Auxiliary Device status*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp2); + break; + case 0x2203: /*Failing Format status*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp3); + break; + case 0x0C04: /*Format status*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp4); + case 0x1405: /*Group status*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp5); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_exception_or_status(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, i; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_exception_or_status_flags, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 5; i++) { + offset += dissect_exception_or_status_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.3 Inbound Text Header */ +static gint +dissect_inbound_text_header(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items outbound_text_header_fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_aid, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_lvl, 0, 1, 0 }, + { hf_tn5250_cro, 0, 2, 0 }, + { hf_tn5250_cc, 0, 2, 0 }, + { hf_tn5250_rw, 0, 2, 0 }, + { hf_tn5250_cw, 0, 2, 0 }, + { hf_tn5250_hw, 0, 2, 0 }, + { hf_tn5250_ww, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + outbound_text_header_fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.4 Inbound 3270DS */ +static gint +dissect_inbound_3270ds(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_partition_id, 0, 1, 0 }, + { hf_tn5250_aid, 0, 1, 0 }, + { hf_tn5250_cursor_x, 0, 1, 0 }, + { hf_tn5250_cursor_y, 0, 1, 0 }, + { hf_tn5250_field_data, 0, (sf_length - 8), 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + return (offset - start); +} + + + +/* 6.5 Recovery Data */ +static gint +dissect_recovery_data(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_recovery_data_flags, 1, 1, 0 }, + { hf_tn5250_sld, 0, 1, 0 }, + { hf_tn5250_charset, 0, 1, 0 }, + { hf_tn5250_vertical, 0, 2, 0 }, + { hf_tn5250_v_offset, 0, 2, 0 }, + { hf_tn5250_v_sequence, 0, 2, 0 }, + { hf_tn5250_v_length, 0, 2, 0 }, + { hf_tn5250_spd, 0, 2, 0 }, + { hf_tn5250_horizon, 0, 2, 0 }, + { hf_tn5250_h_offset, 0, 2, 0 }, + { hf_tn5250_h_sequence, 0, 2, 0 }, + { hf_tn5250_h_length, 0, 2, 0 }, + { hf_tn5250_color, 0, 1, 0 }, + { hf_tn5250_hilite, 0, 1, 0 }, + { hf_tn5250_pages, 0, 2, 0 }, + { hf_tn5250_lines, 0, 2, 0 }, + { hf_tn5250_checkpoint, 0, 2, 0 }, + { hf_tn5250_c_offset, 0, 2, 0 }, + { hf_tn5250_c_sequence, 0, 2, 0 }, + { hf_tn5250_c_seqoff, 0, 2, 0 }, + { hf_tn5250_c_scsoff, 0, 2, 0 }, + { hf_tn5250_prime, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.6 Query Reply (Type 1 Text Inbound) - See above*/ +/* 6.7 and 6.8 Query Reply - Introductory Matter */ + +/* 6.9 Query Reply (Alphanumeric Partitions) */ +static gint +dissect_query_reply_alphanumeric_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + guint16 sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_ap_cm, 0, 1, 0 }, + { hf_tn5250_ap_ro, 0, 1, 0 }, + { hf_tn5250_ap_co, 0, 1, 0 }, + { hf_tn5250_ap_fo, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + sdp = tvb_get_ntohs(tvb, offset); + + switch (sdp) { + case 0x0702: /*Buffer Allocation*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_query_reply_alphanumeric(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + static const int *byte[] = { + &hf_tn5250_ap_vertical_scrolling, + &hf_tn5250_ap_horizontal_scrolling, + &hf_tn5250_ap_apres1, + &hf_tn5250_ap_apa, + &hf_tn5250_ap_pp, + &hf_tn5250_ap_lc, + &hf_tn5250_ap_mp, + &hf_tn5250_ap_apres2, + NULL + }; + + hf_items fields[] = { + { hf_tn5250_ap_na, 0, 1, 0 }, + { hf_tn5250_ap_m, 0, 2, 0 }, + { hf_tn5250_query_reply_alphanumeric_flags, ett_tn5250_query_reply_alphanumeric_flags, 1, byte }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_query_reply_alphanumeric_sd_parms(tn5250_tree, tvb, offset); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.10 Query Reply (Auxiliary Device) - Search for QUERY_REPLY_AUXILIARY_DEVICE */ +/* 6.11 Query Reply (BEGIN/End of File ) - Search for QUERY_REPLY_BEGIN_OR_END_OF_FILE */ + +/* 6.12 Query Reply (Character Sets) */ +static gint +dissect_query_reply_character_sets(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int flagbyte1, flagbyte2; + + static const int *byte1[] = { + &hf_tn5250_cs_ge, + &hf_tn5250_cs_mi, + &hf_tn5250_cs_lps, + &hf_tn5250_cs_lpse, + &hf_tn5250_cs_ms, + &hf_tn5250_cs_ch2, + &hf_tn5250_cs_gf, + &hf_tn5250_cs_res, + NULL + }; + + static const int *byte2[] = { + &hf_tn5250_cs_res2, + &hf_tn5250_cs_pscs, + &hf_tn5250_cs_res3, + &hf_tn5250_cs_cf, + NULL + }; + + static const int *byte3[] = { + &hf_tn5250_cs_form_type1, + &hf_tn5250_cs_form_type2, + &hf_tn5250_cs_form_type3, + &hf_tn5250_cs_form_type4, + &hf_tn5250_cs_form_type5, + &hf_tn5250_cs_form_type6, + &hf_tn5250_cs_form_type8, + NULL + }; + + static const int *byte4[] = { + &hf_tn5250_cs_ds_load, + &hf_tn5250_cs_ds_triple, + &hf_tn5250_cs_ds_char, + &hf_tn5250_cs_ds_cb, + NULL + }; + + + hf_items fields[] = { + { hf_tn5250_character_sets_flags1, ett_tn5250_character_sets_flags1, 1, byte1 }, + { hf_tn5250_character_sets_flags2, ett_tn5250_character_sets_flags2, 1, byte2 }, + { hf_tn5250_sdw, 0, 1, 0 }, + { hf_tn5250_sdh, 0, 1, 0 }, + { hf_tn5250_form, ett_tn5250_character_sets_form, 1, byte3 }, + { hf_tn5250_formres, 0, 1, 0 }, + { hf_tn5250_formres, 0, 1, 0 }, + { hf_tn5250_formres, 0, 1, 0 }, + { hf_tn5250_cs_dl, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items descriptors[] = { + { hf_tn5250_cs_descriptor_set, 0, 1, 0 }, + { hf_tn5250_cs_descriptor_flags, ett_tn5250_cs_descriptor_flags, 1, byte4 }, + { hf_tn5250_lcid, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sw_sh[] = { + { hf_tn5250_sw, 0, 1, 0 }, + { hf_tn5250_sh, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items subsn[] = { + { hf_tn5250_ssubsn, 0, 1, 0 }, + { hf_tn5250_esubsn, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items gf[] = { + { hf_tn5250_ccsgid, 0, 4, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items cf[] = { + { hf_tn5250_ccsid, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + flagbyte1 = tvb_get_guint8(tvb, offset); + flagbyte2 = tvb_get_guint8(tvb, offset+1); + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + while ((offset - start) < (sf_length - 4)) { + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + descriptors); + + if (flagbyte1 & MS) { + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sw_sh); + } + + if (flagbyte1 & CH2) { + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + subsn); + } + + if (flagbyte1 & GF) { + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + gf); + } + + if (flagbyte2 & CF) { + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + cf); + } + } + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.13 Query Reply (Color) */ +static gint +dissect_query_reply_color_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + guint16 sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_db_cavdef, 0, 1, 0 }, + { hf_tn5250_db_cidef, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + sdp = tvb_get_ntohs(tvb, offset); + + switch (sdp) { + case 0x0402: /*Default Background Color*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_query_reply_color(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + int np; + + static const int *byte[] = { + &hf_tn5250_c_prtblk, + NULL + }; + + hf_items fields[] = { + { hf_tn5250_color_flags, ett_tn5250_color_flags, 1, byte }, + { hf_tn5250_c_np, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + np = tvb_get_guint8(tvb, offset +1); + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i=0; i < np; i++) { + if (tvb_get_guint8(tvb, offset) == 0xFF) { + offset++; + } + proto_tree_add_item(tn5250_tree, + hf_tn5250_c_cav, + tvb, offset, + 1, + FALSE); + offset++; + if (tvb_get_guint8(tvb, offset) == 0xFF) { + offset++; + } + proto_tree_add_item(tn5250_tree, + hf_tn5250_c_ci, + tvb, offset, + 1, + FALSE); + offset++; + } + offset += dissect_query_reply_color_sd_parms(tn5250_tree, tvb, offset); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + + +/* 6.36 - Query Reply (OEM Auxiliary Device) Self-Defining Parameters */ +static gint +dissect_daid_sd_parm(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_sdp_daid, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + return (offset - start); + +} + +static gint +dissect_pclk_sd_parm(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_oem_sdp_pclk_vers, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + return (offset - start); + +} + +static gint +dissect_query_reply_oem_auxiliary_device_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + int sdp_len; + int sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_sdp_daid, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_oem_sdp_ll_limin, 0, 2, 0 }, + { hf_tn5250_oem_sdp_ll_limout, 0, 2, 0 }, + + { 0, 0, 0, 0 }, + }; + + hf_items sdp3[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_oem_sdp_pclk_vers, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + sdp_len = tvb_get_guint8(tvb, offset); + if ((sdp_len != 0x04) && (sdp_len != 0x06)) { + return 0; + } + + sdp = tvb_get_guint8(tvb, offset+1); + + switch (sdp) { + case 0x01: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + case 0x02: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp2); + break; + case 0x03: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp3); + break; + default: + return 0; + } + + return (offset - start); + +} + +/* 6.14 - Query Reply (Cooperative Processing Requestor) */ +static gint +dissect_query_reply_cooperative(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_res_twobytes, 0, 2, 0 }, + { hf_tn5250_limin, 0, 2, 0 }, + { hf_tn5250_limout, 0, 2, 0 }, + { hf_tn5250_featl, 0, 1, 0 }, + { hf_tn5250_feats, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + /*FIXME: Need to see this in action to dissect in detail */ + proto_tree_add_item(tn5250_tree, + hf_tn5250_field_data, + tvb, offset, + (sf_length - 13), + FALSE); + offset+=(sf_length - 13); + + /* Uses same Self-Defining Parm as OEM Auxiliary Device */ + offset += dissect_query_reply_oem_auxiliary_device_sd_parms(tn5250_tree, tvb, offset); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.15 - Query Reply (Data Chaining) */ +static gint +dissect_query_reply_data_chaining(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + static const int *byte1[] = { + &hf_tn5250_dc_both, + &hf_tn5250_dc_from_device, + &hf_tn5250_dc_to_device, + NULL + }; + + hf_items fields[] = { + { hf_tn5250_dc_dir_flags, ett_tn5250_dc_dir_flags, 1, byte1 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.16 - Query Reply (Data Streams) */ + +static gint +dissect_query_reply_data_streams(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + + proto_tree_add_item(tn5250_tree, hf_tn5250_ds_default_sfid, tvb, offset, 1, + FALSE); + for (i=0; i < (sf_length - 4); i++) { + proto_tree_add_item(tn5250_tree, + hf_tn5250_ds_sfid, + tvb, offset, + 1, + FALSE); + offset++; + } + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + return (offset - start); +} + +/* 6.17 - Query Reply (DBCS Asia) */ + +static gint +dissect_query_reply_dbcs_asia_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + int sdp_len; + int sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_asia_sdp_sosi_soset, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_asia_sdp_ic_func, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + sdp_len = tvb_get_guint8(tvb, offset); + if (sdp_len != 0x03) { + return 0; + } + + sdp = tvb_get_guint8(tvb, offset+1); + + switch (sdp) { + case 0x01: /*SO/SI*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, sdp1); + break; + case 0x02: /*Input Control*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, sdp2); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_query_reply_dbcs_asia(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + + int start=offset; + int i; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + offset += dissect_query_reply_dbcs_asia_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.18 - Query Reply (Device Characteristics) */ +static gint +dissect_query_reply_device_characteristics(proto_tree *tn5250_tree, tvbuff_t *tvb, + gint offset, gint sf_length) +{ + int start=offset; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_outbound_id, + tvb, offset, + 1, + FALSE); + offset++; + + /* TODO: dissect descriptors */ + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.19 - Query Reply (Distributed Data Management) */ +static gint +dissect_query_reply_distributed_data_management(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, i; + int sdp; + + hf_items fields[] = { + { hf_tn5250_ddm_flags,0, 1, 0 }, + { hf_tn5250_ddm_flags,0, 1, 0 }, + { hf_tn5250_ddm_limin,0, 2, 0 }, + { hf_tn5250_ddm_limout,0, 2, 0 }, + { hf_tn5250_ddm_nss,0, 1, 0 }, + { hf_tn5250_ddm_ddmss,0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + sdp = tvb_get_guint8(tvb, offset+1); + switch (sdp) { + case 0x02: /*DDM*/ + /*TODO: DDM */ + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, tvb_get_guint8(tvb,offset)); + break; + case 0x01: /*DAID*/ + offset += dissect_daid_sd_parm(tn5250_tree, tvb, offset); + break; + case 0x03: /*PCLK*/ + offset += dissect_pclk_sd_parm(tn5250_tree, tvb, offset); + break; + default: + goto done; + } + if (!tvb_length_remaining(tvb, offset)) + break; + } + +done: + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.20 - Query Reply (Document Interchange Architecture) */ +static gint +dissect_query_reply_document_interchange_architecture(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, sdp, ln, i; + + hf_items fields[] = { + { hf_tn5250_dia_flags, 0, 2, 0 }, + { hf_tn5250_dia_limin, 0, 2, 0 }, + { hf_tn5250_dia_limout, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + ln = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, hf_tn5250_dia_nfs,tvb, offset, 1, FALSE); + + for (i=0; i < ln; i++) { + proto_tree_add_item(tn5250_tree, hf_tn5250_dia_diafs, tvb, offset, 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, hf_tn5250_dia_diafn, tvb, offset, 2, + FALSE); + offset++; + } + + sdp = tvb_get_guint8(tvb, offset+1); + if (sdp == 0x01) { /*DAID*/ + offset += dissect_daid_sd_parm(tn5250_tree, tvb, offset); + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.21 - Query Reply (Extended Drawing Routine) */ +static gint +dissect_query_reply_extended_drawing_routine(proto_tree *tn5250_tree, tvbuff_t *tvb, + gint offset, gint sf_length) +{ + int start=offset; + + proto_tree_add_item(tn5250_tree, hf_tn5250_field_data ,tvb, offset, + (sf_length-4), FALSE); + + offset += (sf_length - 4); + + return (offset - start); +} + +/* 6.22 - Query Reply (Field Outlining) */ +static gint +dissect_query_reply_field_outlining(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_fo_flags, 0, 1, 0 }, + { hf_tn5250_fo_vpos, 0, 1, 0 }, + { hf_tn5250_fo_hpos, 0, 1, 0 }, + { hf_tn5250_fo_hpos0, 0, 1, 0 }, + { hf_tn5250_fo_hpos1, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.23 - Query Reply (Field Validation) - Search for FIELD_VALIDATION*/ +/* 6.24 - Query Reply (Format Presentation) - Search for FORMAT_PRESENTATION*/ + +/* 6.25 - Query Reply (Format Storage Auxiliary Device)*/ +static gint +dissect_query_reply_format_storage_aux_device(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, sdp; + + hf_items fields[] = { + { hf_tn5250_fsad_flags, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_fsad_limin, 0, 2, 0 }, + { hf_tn5250_fsad_limout, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + sdp = tvb_get_guint8(tvb, offset+1); + if (sdp == 0x01) { /*DAID*/ + offset += dissect_daid_sd_parm(tn5250_tree, tvb, offset); + proto_tree_add_item(tn5250_tree, hf_tn5250_fsad_size ,tvb, offset, + 2, FALSE); + offset+=2; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.26 - Query Reply (Graphic Color) - Search for GRAPHIC_COLOR*/ +/* 6.27 - Query Reply (Graphic Symbol Sets) - Search for GRAPHIC_SYMBOL_SETS*/ + +/* 6.28 - Query Reply (Highlighting) */ +static gint +dissect_query_reply_highlighting(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + int np; + + hf_items fields[] = { + { hf_tn5250_h_np, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + np = tvb_get_guint8(tvb, offset); + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i=0; i < np; i++) { + if (tvb_get_guint8(tvb, offset) == 0xFF) { + offset++; + } + proto_tree_add_item(tn5250_tree, + hf_tn5250_h_vi, + tvb, offset, + 1, + FALSE); + offset++; + if (tvb_get_guint8(tvb, offset) == 0xFF) { + offset++; + } + proto_tree_add_item(tn5250_tree, + hf_tn5250_h_ai, + tvb, offset, + 1, + FALSE); + offset++; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.29 - Query Reply (IBM Auxiliary Device) */ +static gint +dissect_query_reply_ibm_aux_device(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, i, sdp; + + hf_items fields[] = { + { hf_tn5250_ibm_flags, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_ibm_limin, 0, 2, 0 }, + { hf_tn5250_ibm_limout, 0, 2, 0 }, + { hf_tn5250_ibm_type, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + for (i = 0; i < 3; i++) { + sdp = tvb_get_guint8(tvb, offset+1); + switch (sdp) { + case 0x02: /*Printer Name*/ + /*TODO: Printer Name */ + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, tvb_get_guint8(tvb,offset)); + break; + case 0x01: /*DAID*/ + offset += dissect_daid_sd_parm(tn5250_tree, tvb, offset); + break; + case 0x03: /*PCLK*/ + offset += dissect_pclk_sd_parm(tn5250_tree, tvb, offset); + break; + default: + goto done; + } + if (!tvb_length_remaining(tvb, offset)) + break; + } + +done: + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.30 - Query Reply (Image) */ + +/* 6.31 - Query Reply (Implicit Partitions) */ +static gint +dissect_query_reply_implicit_partitions_sd_parms(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + int sdp_len; + int sdp; + + hf_items sdp1[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_ip_flags, 0, 1, 0 }, + { hf_tn5250_ipdd_wd, 0, 2, 0 }, + { hf_tn5250_ipdd_hd, 0, 2, 0 }, + { hf_tn5250_ipdd_wa, 0, 2, 0 }, + { hf_tn5250_ipdd_ha, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_ip_flags, 0, 1, 0 }, + { hf_tn5250_ippd_dpbs, 0, 4, 0 }, + { hf_tn5250_ippd_apbs, 0, 4, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items sdp3[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_ip_flags, 0, 1, 0 }, + { hf_tn5250_ipccd_wcd, 0, 2, 0 }, + { hf_tn5250_ipccd_hcd, 0, 2, 0 }, + { hf_tn5250_ipccd_wca, 0, 2, 0 }, + { hf_tn5250_ipccd_hca, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + sdp_len = tvb_get_guint8(tvb, offset); + if (sdp_len != 0x0B) { + return 0; + } + + sdp = tvb_get_guint8(tvb, offset+1); + + switch (sdp) { + case DISPLAY: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp1); + break; + case PRINTER: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp2); + break; + case CHARACTER: + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + sdp3); + break; + default: + return 0; + } + + return (offset - start); + +} + +static gint +dissect_query_reply_implicit_partitions(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + + hf_items fields[] = { + { hf_tn5250_ip_flags, 0, 1, 0 }, + { hf_tn5250_ip_flags, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + offset += dissect_query_reply_implicit_partitions_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.32 - Query Reply (IOCA Auxiliary Device) */ +static gint +dissect_query_reply_ioca_aux_device(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_ioca_limin, 0, 2, 0 }, + { hf_tn5250_ioca_limout, 0, 2, 0 }, + { hf_tn5250_ioca_type, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.33 - Query Reply (Line Type) - Search for LINE_TYPE*/ + +/* 6.34 - Query Reply (MSR Control) */ +static gint +dissect_query_reply_msr_control(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_msr_nd, 0, 1, 0 }, + { hf_tn5250_msr_type, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.35 - Query Reply (Null) - Search for QUERY_REPLY_NULL */ + +/* 6.36 - Query Reply (OEM Auxiliary Device) */ +static gint +dissect_query_reply_oem_auxiliary_device(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + + hf_items fields[] = { + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_oem_dsref, 0, 1, 0 }, + { hf_tn5250_oem_dtype, 0, 8, 0 }, + { hf_tn5250_oem_uname, 0, 8, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + for (i = 0; i < 3; i++) { + offset += dissect_query_reply_oem_auxiliary_device_sd_parms(tn5250_tree, tvb, offset); + if (!tvb_length_remaining(tvb, offset)) + break; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.37 - Query Reply (Paper Feed Techniques) */ +static gint +dissect_query_reply_paper_feed_techniques(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_pft_flags, 0, 1, 0 }, + { hf_tn5250_pft_tmo, 0, 2, 0 }, + { hf_tn5250_pft_bmo, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.38 - Query Reply (Partition Characteristics) */ +static gint +dissect_query_reply_partition_characteristics(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, i, sdp; + + hf_items fields[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + for (i = 0; i < 2; i++) { + sdp = tvb_get_guint8(tvb, offset+1); + switch (sdp) { + case 0x01: /*Viewport Outline*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + proto_tree_add_item(tn5250_tree, hf_tn5250_pc_vo_thickness, + tvb, offset, 1, FALSE); + offset++; + break; + case 0x03: /*Enable User Call-Up*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + break; + default: + goto done; + } + if (!tvb_length_remaining(tvb, offset)) + break; + } + +done: + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.39 - Query Reply (Port) - Search for QUERY_REPLY_PORT */ +/* 6.40 - Query Reply (Procedure) - Search for QUERY_REPLY_PROCEDURE */ + +/* 6.41 - Query Reply ((Product Defined Data Stream) */ +static gint +dissect_query_reply_product_defined_data_stream(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, sdp; + + hf_items fields[] = { + { hf_tn5250_resbytes, 0, 2, 0 }, + { hf_tn5250_pdds_refid, 0, 1, 0 }, + { hf_tn5250_pdds_ssid, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + sdp = tvb_get_guint8(tvb, offset+1); + if (sdp == 0x01) { /*DAID*/ + offset += dissect_daid_sd_parm(tn5250_tree, tvb, offset); + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.42 - Query Reply (Modes) */ +static gint +dissect_query_reply_modes(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + + for (i=0; i < (sf_length - 4); i++) { + proto_tree_add_item(tn5250_tree, + hf_tn5250_mode, + tvb, offset, + 1, + FALSE); + offset++; + } + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.43 - Query Reply (RPQ Names) */ +static gint +dissect_query_reply_rpq_names(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int rpql; + + hf_items fields[] = { + { hf_tn5250_rpq_device,0, 4, 0 }, + { hf_tn5250_rpq_mid,0, 4, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + rpql = tvb_get_guint8(tvb, offset); + + proto_tree_add_item(tn5250_tree, + hf_tn5250_rpq_rpql, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_rpq_name, + tvb, offset, + (rpql - 1), + FALSE); + offset+=(rpql-1); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.44 - Query Reply (Save/Restore Format) */ +static gint +dissect_query_reply_save_or_restore_format(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_srf_fpcbl, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.45 - Query Reply (Segment) - Search for QUERY_REPLY_SEGMENT */ + +/* 6.46 - Query Reply ((Settable Printer Characteristics) */ +static gint +dissect_query_reply_settable_printer_characteristics(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, sdp; + + hf_items fields[] = { + { hf_tn5250_resbytes, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items fields2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + sdp = tvb_get_guint8(tvb, offset+1); + if (sdp == 0x01) { /*Early Print Complete*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields2); + proto_tree_add_item(tn5250_tree, hf_tn5250_spc_epc_flags, tvb, offset, + 1, FALSE); + offset++; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.47 - Query Reply (Storage Pools) */ +static gint +dissect_query_reply_storage_pools(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, sdp, i; + + hf_items fields2[] = { + { hf_tn5250_sdp_ln, 0, 1, 0 }, + { hf_tn5250_sdp_id, 0, 1, 0 }, + { hf_tn5250_sp_spid, 0, 1, 0 }, + { hf_tn5250_sp_size, 0, 4, 0 }, + { hf_tn5250_sp_space, 0, 4, 0 }, + { 0, 0, 0, 0 }, + }; + + sdp = tvb_get_guint8(tvb, offset+1); + if (sdp == 0x01) { /*Storage Pool Characteristics*/ + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields2); + for (i=0; i < (sf_length - 4); i+=2) { + proto_tree_add_item(tn5250_tree, hf_tn5250_sp_objlist, + tvb, offset, 2, FALSE); + offset+=2; + } + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.48 - Query Reply (Summary) */ +static gint +dissect_query_reply_summary(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int i; + + for (i=0; i < (sf_length - 4); i++) { + if (!tvb_offset_exists(tvb, offset)) { + return (offset - start); + } + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_query_replies, + tvb, offset, + 1, + FALSE); + offset++; + } + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + return (offset - start); +} + +/* 6.49 - Query Reply (Text Partitions) */ +static gint +dissect_query_reply_text_partitions(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, len, i; + + hf_items fields[] = { + { hf_tn5250_tp_nt, 0, 1, 0 }, + { hf_tn5250_tp_m, 0, 2, 0 }, + { hf_tn5250_tp_flags, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + + len = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, hf_tn5250_tp_ntt, tvb, offset, 1, FALSE); + offset++; + + for (i=0; i < len; i++) { + proto_tree_add_item(tn5250_tree, hf_tn5250_tp_tlist, + tvb, offset, 1, FALSE); + offset++; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.50 - Query Reply (Transparency) */ +static gint +dissect_query_reply_transparency(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset, i, len; + + len = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, hf_tn5250_t_np, tvb, offset, 1, FALSE); + offset++; + + for (i=0; i < len; i+=2) { + proto_tree_add_item(tn5250_tree, hf_tn5250_t_vi, + tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tn5250_tree, hf_tn5250_t_ai, + tvb, offset, 1, FALSE); + offset++; + } + + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.51 - Query Reply Usable Area */ +static gint +dissect_query_reply_usable_area(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + int vcp; + + static const int *byte1[] = { + &hf_tn5250_ua_reserved1, + &hf_tn5250_ua_page_printer, + &hf_tn5250_ua_reserved2, + &hf_tn5250_ua_hard_copy, + &hf_tn5250_ua_addressing, + NULL + }; + + static const int *byte2[] = { + &hf_tn5250_ua_variable_cells, + &hf_tn5250_ua_characters, + &hf_tn5250_ua_cell_units, + NULL + }; + + hf_items fields[] = { + { hf_tn5250_usable_area_flags1, ett_tn5250_usable_area_flags1, 1, byte1 }, + { hf_tn5250_usable_area_flags2, ett_tn5250_usable_area_flags1, 1, byte2 }, + { hf_tn5250_ua_width_cells_pels, 0, 2, 0 }, + { hf_tn5250_ua_height_cells_pels, 0, 2, 0 }, + { hf_tn5250_ua_uom_cells_pels, 0, 1, 0 }, + { hf_tn5250_ua_xr, 0, 4, 0 }, + { hf_tn5250_ua_yr, 0, 4, 0 }, + { hf_tn5250_ua_aw, 0, 1, 0 }, + { hf_tn5250_ua_ah, 0, 1, 0 }, + { hf_tn5250_ua_buffsz, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + hf_items fields2[] = { + { hf_tn5250_ua_xmin, 0, 1, 0 }, + { hf_tn5250_ua_ymin, 0, 1, 0 }, + { hf_tn5250_ua_xmax, 0, 1, 0 }, + { hf_tn5250_ua_ymax, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + vcp = tvb_get_guint8(tvb, offset+1); + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + if (vcp == VARIABLE_CELLS) { + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields2); + } + + /*TODO: self defining parms */ + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +/* 6.52 - Query Reply 3270 IPDS */ +static gint +dissect_query_reply_3270_ipds(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length) +{ + int start=offset; + + hf_items fields[] = { + { hf_tn5250_resbytes, 0, 2, 0 }, + { hf_tn5250_3270_tranlim, 0, 2, 0 }, + { 0, 0, 0, 0 }, + }; + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, fields); + offset += dissect_unknown_data(tn5250_tree, tvb, offset, start, sf_length); + + return (offset - start); +} + +static gint +process_in_out_structured_fields(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, + gint sf_length, gint16 sfid) +{ + int start = offset; + + switch (sfid) { + case DATA_CHAIN: + proto_tree_add_bits_item(tn5250_tree, + hf_tn5250_data_chain_bitmask, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbyte, + tvb, offset, + 1, + FALSE); + offset++; + break; + case DESTINATION_OR_ORIGIN: + proto_tree_add_bits_item(tn5250_tree, + hf_tn5250_destination_or_origin_bitmask, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbyte, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_inbound_outbound_id, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + case OBJECT_DATA: + case OBJECT_CONTROL: + case OBJECT_PICTURE: + case OEM_DATA: /* FIXME: Not really but same layout */ + offset += dissect_object_control(tn5250_tree, tvb, offset, sf_length); + break; + case SAVE_OR_RESTORE_FORMAT: + offset += dissect_save_or_restore_format(tn5250_tree, tvb, offset, sf_length); + break; + case SELECT_IPDS_MODE: + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbytes, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + default: + break; + } + + return (offset - start); +} + +static gint +process_double_byte_sf(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset, gint sf_length) +{ + gint16 full_sf_id; + int start = offset; + + full_sf_id = tvb_get_guint8(tvb, offset-1); + proto_tree_add_item(tn5250_tree, + hf_tn5250_double_byte_sf_id, + tvb, offset-1, + 2, + FALSE); + offset++; + switch (full_sf_id) { + case BEGIN_OR_END_OF_FILE: + proto_tree_add_item(tn5250_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + /*TODO: use bits_text */ + proto_tree_add_bits_item(tn5250_tree, + hf_tn5250_begin_end_flags1, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_bits_item(tn5250_tree, + hf_tn5250_begin_end_flags2, + tvb, offset, + 1, + FALSE); + offset++; + break; + case LOAD_COLOR_TABLE: + /* Refer to related graphics docs !*/ + proto_tree_add_item(tn5250_tree, + hf_tn5250_load_color_command, + tvb, offset, + (sf_length - 4), + FALSE); + offset+=(sf_length - 4); + break; + case LOAD_FORMAT_STORAGE: + offset += dissect_load_format_storage(tn5250_tree, tvb, offset, sf_length); + break; + case LOAD_LINE_TYPE: + /* Refer to related graphics docs !*/ + proto_tree_add_item(tn5250_tree, + hf_tn5250_load_line_type_command, + tvb, offset, + (sf_length - 4), + FALSE); + offset+=(sf_length - 4); + break; + case MODIFY_PARTITION: + offset += dissect_modify_partition(tn5250_tree, tvb, offset, sf_length); + break; + case OUTBOUND_TEXT_HEADER: + offset += dissect_outbound_text_header(tn5250_tree, tvb, offset, sf_length); + break; + case REQUEST_RECOVERY_DATA: + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbyte, + tvb, offset, + 1, + FALSE); + offset++; + break; + case RESTART: + offset += dissect_restart(tn5250_tree, tvb, offset, sf_length); + break; + case SELECT_COLOR_TABLE: + proto_tree_add_item(tn5250_tree, + hf_tn5250_color_command, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + case SET_CHECKPOINT_INTERVAL: + proto_tree_add_item(tn5250_tree, + hf_tn5250_resbyte, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, + hf_tn5250_interval, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + case SET_MSR_CONTROL: + offset += dissect_set_msr_control(tn5250_tree, tvb, offset, sf_length); + break; + case SET_PARTITION_CHARACTERISTICS: + offset += dissect_set_partition_characteristics(tn5250_tree, tvb, offset, sf_length); + break; + case SET_PRINTER_CHARACTERISTICS: + offset += dissect_set_printer_characteristics(tn5250_tree, tvb, offset, sf_length); + break; + case TYPE_1_TEXT_OUTBOUND: + offset += dissect_type_1_text(tn5250_tree, tvb, offset, sf_length); + break; + default: + offset += process_in_out_structured_fields(tn5250_tree, tvb, offset, sf_length, + full_sf_id); + break; + } + + return (offset - start); +} + +static gint +dissect_outbound_structured_fields(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + int sf_id; + gint16 sf_length; + proto_tree *sf_tree; + proto_item *ti; + + while (tvb_offset_exists(tvb, offset)) { + sf_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_length, + tvb, offset, + 2, + FALSE); + offset+=2; + sf_id = tvb_get_guint8(tvb, offset); + ti = proto_tree_add_item(tn5250_tree, hf_tn5250_sf_outbound_id, tvb, offset, 1, FALSE); + offset++; + sf_tree = proto_item_add_subtree(ti, ett_sf); + switch (sf_id) { + case 0x0F: + case 0x10: + process_double_byte_sf(sf_tree, tvb, offset, sf_length); + break; + case READ_PARTITION: + offset += dissect_read_partition(sf_tree, tvb, offset, sf_length); + break; + case ACTIVATE_PARTITION: + case DESTROY_PARTITION: + case RESET_PARTITION: + proto_tree_add_item(sf_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + break; + case CREATE_PARTITION: + offset += dissect_create_partition(sf_tree, tvb, offset, sf_length); + break; + case ERASE_OR_RESET: + proto_tree_add_bits_item(sf_tree, + hf_tn5250_erase_flags, + tvb, offset, + 1, + FALSE); + offset++; + break; + case LOAD_PROGRAMMED_SYMBOLS: + offset += dissect_load_programmed_symbols(sf_tree, tvb, offset, sf_length); + break; + case OUTBOUND_3270DS: + offset += dissect_outbound_3270ds(sf_tree, tvb, offset, sf_length); + break; + case PRESENT_ABSOLUTE_FORMAT: + offset += dissect_present_absolute_format(sf_tree, tvb, offset, sf_length); + break; + case PRESENT_RELATIVE_FORMAT: + offset += dissect_present_relative_format(sf_tree, tvb, offset, sf_length); + break; + case SCS_DATA: + proto_tree_add_item(sf_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(sf_tree, + hf_tn5250_scs_data, + tvb, offset, + (sf_length - 4), + FALSE); + offset+=(sf_length - 4); + break; + case SET_REPLY_MODE: + offset += dissect_set_reply_mode(sf_tree, tvb, offset, sf_length); + break; + case SELECT_FORMAT_GROUP: + proto_tree_add_item(sf_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(sf_tree, + hf_tn5250_format_group, + tvb, offset, + (sf_length - 4), + FALSE); + offset+=(sf_length - 4); + break; + case SET_WINDOW_ORIGIN: + proto_tree_add_item(sf_tree, + hf_tn5250_partition_id, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(sf_tree, + hf_tn5250_partition_rw, + tvb, offset, + 2, + FALSE); + offset+=2; + proto_tree_add_item(sf_tree, + hf_tn5250_partition_cw, + tvb, offset, + 2, + FALSE); + offset+=2; + break; + default: + break; + } + //offset += add_data_until_next_order_code(sf_tree, tvb, offset); + } + return (offset - start); +} + +static gint +dissect_inbound_structured_fields(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + gint16 sf_length; + guint16 sf_id; + proto_tree *sf_tree; + proto_item *ti; + + while (tvb_offset_exists(tvb, offset)) { + /*Handle NULL bytes until we find a length value */ + sf_length = tvb_get_ntohs(tvb, offset); + while (!sf_length){ + proto_tree_add_item(tn5250_tree, + hf_tn5250_null, + tvb, offset, + 1, + FALSE); + offset++; + sf_length = tvb_get_ntohs(tvb, offset); + } + + proto_tree_add_item(tn5250_tree, + hf_tn5250_sf_length, + tvb, offset, + 2, + FALSE); + offset+=2; + + sf_id = tvb_get_ntohs(tvb, offset); + ti = proto_tree_add_item(tn5250_tree, hf_tn5250_sf_inbound_id, tvb, offset, 2, FALSE); + offset+=2; + sf_tree = proto_item_add_subtree(ti, ett_sf); + switch (sf_id) { + case EXCEPTION_OR_STATUS: + offset += dissect_exception_or_status(sf_tree, tvb, offset, sf_length); + break; + case INBOUND_TEXT_HEADER: + offset += dissect_inbound_text_header(sf_tree, tvb, offset, sf_length); + break; + case INBOUND_3270DS: + offset += dissect_inbound_3270ds(sf_tree, tvb, offset, sf_length); + break; + case RECOVERY_DATA: + offset += dissect_recovery_data(sf_tree, tvb, offset, sf_length); + break; + case TYPE_1_TEXT_INBOUND: + offset += dissect_type_1_text(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_ALPHANUMERIC_PARTITIONS: + offset += dissect_query_reply_alphanumeric(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_AUXILIARY_DEVICE: + case QUERY_REPLY_BEGIN_OR_END_OF_FILE: + offset += dissect_query_reply_resbytes(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_CHARACTER_SETS: + offset += dissect_query_reply_character_sets(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_COLOR: + offset += dissect_query_reply_color(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_COOPERATIVE_PROCESSING_REQUESTOR: + offset += dissect_query_reply_cooperative(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DATA_CHAINING: + offset += dissect_query_reply_data_chaining(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DATA_STREAMS: + offset += dissect_query_reply_data_streams(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DBCS_ASIA: + offset += dissect_query_reply_dbcs_asia(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DEVICE_CHARACTERISTICS: + /*TODO: implement this beast */ + offset += dissect_query_reply_device_characteristics(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_SUMMARY: + offset += dissect_query_reply_summary(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_USABLE_AREA: + offset += dissect_query_reply_usable_area(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_HIGHLIGHTING: + offset += dissect_query_reply_highlighting(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_REPLY_MODES: + offset += dissect_query_reply_modes(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DISTRIBUTED_DATA_MANAGEMENT: + offset += dissect_query_reply_distributed_data_management(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_RPQ_NAMES: + offset += dissect_query_reply_rpq_names(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_IMPLICIT_PARTITION: + offset += dissect_query_reply_implicit_partitions(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_OEM_AUXILIARY_DEVICE: + offset += dissect_query_reply_oem_auxiliary_device(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_DOCUMENT_INTERCHANGE_ARCHITECTURE: + offset += dissect_query_reply_document_interchange_architecture(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_EXTENDED_DRAWING_ROUTINE: + offset += dissect_query_reply_extended_drawing_routine(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_FIELD_OUTLINING: + offset += dissect_query_reply_field_outlining(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_FIELD_VALIDATION: + offset += dissect_3270_field_validation(sf_tree, tvb, offset); + break; + case QUERY_REPLY_FORMAT_STORAGE_AUXILIARY_DEVICE: + offset += dissect_query_reply_format_storage_aux_device(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_GRAPHIC_COLOR: + case QUERY_REPLY_GRAPHIC_SYMBOL_SETS: + case QUERY_REPLY_IMAGE: + case QUERY_REPLY_LINE_TYPE: + case QUERY_REPLY_PROCEDURE: + case QUERY_REPLY_SEGMENT: + /* Not an error - just has a data field like 'extended drawing'*/ + offset += dissect_query_reply_extended_drawing_routine(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_IBM_AUXILIARY_DEVICE: + offset += dissect_query_reply_ibm_aux_device(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_IOCA_AUXILIARY_DEVICE: + offset += dissect_query_reply_ioca_aux_device(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_MSR_CONTROL: + offset += dissect_query_reply_msr_control(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_FORMAT_PRESENTATION: + case QUERY_REPLY_NULL: + case QUERY_REPLY_PORT: + /* This field is always empty */ + break; + case QUERY_REPLY_PAPER_FEED_TECHNIQUES: + offset += dissect_query_reply_paper_feed_techniques(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_PARTITION_CHARACTERISTICS: + offset += dissect_query_reply_partition_characteristics(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_PRODUCT_DEFINED_DATA_STREAM: + offset += dissect_query_reply_product_defined_data_stream(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_SAVE_OR_RESTORE_FORMAT: + offset += dissect_query_reply_save_or_restore_format(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_SETTABLE_PRINTER_CHARACTERISTICS: + offset += dissect_query_reply_settable_printer_characteristics(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_STORAGE_POOLS: + offset += dissect_query_reply_storage_pools(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_TEXT_PARTITIONS: + offset += dissect_query_reply_text_partitions(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_TRANSPARENCY: + offset += dissect_query_reply_transparency(sf_tree, tvb, offset, sf_length); + break; + case QUERY_REPLY_3270_IPDS: + offset += dissect_query_reply_3270_ipds(sf_tree, tvb, offset, sf_length); + break; + default: + break; + } + //offset += add_data_until_next_order_code(sf_tree, tvb, offset); + } + + return (offset - start); +} + +/* Start: Handle WCC, Orders and Data */ + +static gint +dissect_stop_address(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + int is_ge; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_stop_address, + tvb, offset, + 2, + FALSE); + offset++; + is_ge = tvb_get_guint8(tvb, offset); + if (is_ge != GE) { + proto_tree_add_item(tn5250_tree, + hf_tn5250_character_code, + tvb, offset, + 1, + FALSE); + offset++; + } + + return (offset - start); +} + +static gint +dissect_sba(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + proto_tree_add_item(tn5250_tree, + hf_tn5250_buffer_x, + tvb, offset, + 1, + FALSE); + offset++; + proto_tree_add_item(tn5250_tree, + hf_tn5250_buffer_y, + tvb, offset, + 1, + FALSE); + offset++; + + return (offset - start); +} + +static gint +dissect_field_attribute_pair(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + int attribute_type; + + attribute_type = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_attribute_type, + tvb, offset, + 1, + FALSE); + offset++; + switch (attribute_type) { + case ALL_CHARACTER_ATTRIBUTES: + proto_tree_add_item(tn5250_tree, + hf_tn5250_all_character_attributes, + tvb, offset, + 1, + FALSE); + offset++; + break; + case T3270_FIELD_ATTRIBUTE: + dissect_3270_field_attribute(tn5250_tree, tvb, offset); + break; + case EXTENDED_HIGHLIGHTING: + proto_tree_add_item(tn5250_tree, + hf_tn5250_extended_highlighting, + tvb, offset, + 1, + FALSE); + offset++; + break; + case FOREGROUND_COLOR: + case BACKGROUND_COLOR: + proto_tree_add_item(tn5250_tree, + hf_tn5250_color, + tvb, offset, + 1, + FALSE); + offset++; + break; + case CHARACTER_SET: + proto_tree_add_item(tn5250_tree, + hf_tn5250_character_set, + tvb, offset, + 1, + FALSE); + offset++; + break; + case FIELD_OUTLINING: + proto_tree_add_item(tn5250_tree, + hf_tn5250_field_outlining, + tvb, offset, + 1, + FALSE); + offset++; + break; + case TRANSPARENCY: + proto_tree_add_item(tn5250_tree, + hf_tn5250_transparency, + tvb, offset, + 1, + FALSE); + offset++; + break; + case FIELD_VALIDATION: + dissect_3270_field_validation(tn5250_tree, tvb, offset); + break; + } + + return (offset - start); +} + +static gint +dissect_field_attribute_pairs(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + int start = offset; + int no_of_pairs; + int i; + + no_of_pairs = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_number_of_attributes, + tvb, offset, + 1, + FALSE); + offset++; + + for (i=0; i < no_of_pairs; i++) { + offset += dissect_field_attribute_pair(tn5250_tree, tvb, offset); + } + return (offset - start); +} + +gint +dissect_orders_and_data(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + gint start = offset; + gint order_code; + + /* Order Code */ + + while (tvb_offset_exists(tvb, offset)) { + order_code = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_order_code, + tvb, offset, + 1, + FALSE); + offset++; + switch (order_code) { + case SF: + offset += dissect_3270_field_attribute(tn5250_tree, tvb, offset); + break; + case MF: + case SFE: + offset += dissect_field_attribute_pairs(tn5250_tree, tvb, offset); + break; + case SA: + offset += dissect_field_attribute_pair(tn5250_tree, tvb, offset); + break; + case EUA: + case RA: + offset += dissect_stop_address(tn5250_tree, tvb, offset); + break; + case GE: + proto_tree_add_item(tn5250_tree, + hf_tn5250_character_code, + tvb, offset, + 1, + FALSE); + offset++; + break; + case SBA: + offset += dissect_sba(tn5250_tree, tvb, offset); + break; +/* case PT:*/ + case IC: + case EW: + case EWA: + break; +/* return (offset - start);*/ + default: + proto_tree_add_text(tn5250_tree, tvb, offset, 1, "Bogus value: %u", order_code); + offset ++; + break; + } + offset += add_data_until_next_order_code(tn5250_tree, tvb, offset); + } + offset += add_data_until_next_order_code(tn5250_tree, tvb, offset); + return (offset - start); +} + +/* End: Handle WCC, Orders and Data */ + + +static gint +dissect_tn5250_header(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + + int start=offset; + gint data_type; + int len = 0; + + static const int *byte[] = { + &hf_tn5250_ds_output_error, + &hf_tn5250_attn_key, + &hf_tn5250_sys_request_key, + &hf_tn5250_test_request_key, + &hf_tn5250_error_state, + NULL + }; + + + hf_items fields[] = { + { hf_tn5250_logical_record_length, 0, 2, 0 }, + { hf_tn5250_sna_record_type, 0, 2, 0 }, + { hf_tn5250_resbytes, 0, 2, 0 }, + { hf_tn5250_variable_record_length, 0, 1, 0 }, + { hf_tn5250_header_flags, ett_tn5250_header_flags, 1, byte }, + { hf_tn5250_resbyte, 0, 1, 0 }, + { hf_tn5250_operation_code, 0, 1, 0 }, + { 0, 0, 0, 0 }, + }; + + error_flag = tvb_get_guint8(tvb, offset+8); + + offset += tn5250_add_hf_items(tn5250_tree, tvb, offset, + fields); + + if (error_flag & 0x02) { /*HLP*/ + proto_tree_add_item(tn5250_tree, hf_tn5250_error_code, tvb, offset, 2, FALSE); + } + + return (offset - start); +} + +/* Detect and Handle Direction of Stream */ +static gint +dissect_outbound_stream(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + gint command_code; + gint start = offset; + + /*Escape*/ + proto_tree_add_item(tn5250_tree, + hf_tn5250_escape_code, + tvb, offset, + 1, + FALSE); + offset++; + + /* Command Code*/ + command_code = tvb_get_guint8(tvb, offset); + switch (command_code) { + case CLEAR_UNIT: + proto_tree_add_item(tn5250_tree, hf_tn5250_command_code, + tvb, offset, 1, FALSE); + offset++; + case CLEAR_UNIT_ALTERNATE: + proto_tree_add_item(tn5250_tree, hf_tn5250_command_code, + tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tn5250_tree, hf_tn5250_cua_parm, + tvb, offset, 1, FALSE); + offset++; + case CLEAR_FORMAT_TABLE: + case WRITE_TO_DISPLAY: + case WRITE_ERROR_CODE: + case WRITE_ERROR_CODE_TO_WINDOW: + case READ_INPUT_FIELDS: + case READ_MDT_FIELDS: + case READ_MDT_ALTERNATE: + case READ_SCREEN: + case READ_SCREEN_WITH_EXTENDED_ATTRIBUTES: + case READ_SCREEN_TO_PRINT: + case READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES: + case READ_SCREEN_TO_PRINT_WITH_GRIDLINES: + case READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES_AND_GRIDLINES: + case READ_IMMEDIATE: + case READ_MODIFIED_IMMEDIATE_ALTERNATE: + case SAVE_SCREEN: + case SAVE_PARTIAL_SCREEN: + case RESTORE_SCREEN: + case RESTORE_PARTIAL_SCREEN: + case ROLL: + case WRITE_STRUCTURED_FIELD: + case WRITE_SINGLE_STRUCTURED_FIELD: + case COPY-TO-PRINTER: + + /* WCC */ + offset += dissect_wcc(tn5250_tree, tvb, offset); + offset += dissect_orders_and_data(tn5250_tree, tvb, offset); + break; + case WSF: + case SNA_WSF: + proto_tree_add_item(tn5250_tree, + hf_tn5250_command_code, + tvb, offset, + 1, + FALSE); + offset++; + offset += dissect_outbound_structured_fields(tn5250_tree, tvb, offset); + break; + default: + proto_tree_add_text(tn5250_tree, tvb, offset, 1, "Bogus value: %u", command_code); + offset ++; + break; + } + return (offset - start); + +} + +/* INBOUND DATA STREAM (DISPLAY -> MAINFRAME PROGRAM) */ +static gint +dissect_inbound_stream(proto_tree *tn5250_tree, tvbuff_t *tvb, gint offset) +{ + gint start = offset; + gint aid; + + /* Command Code*/ + aid = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tn5250_tree, + hf_tn5250_aid, + tvb, offset, + 1, + FALSE); + offset++; + switch (aid) { + case STRUCTURED_FIELD: + offset += dissect_inbound_structured_fields(tn5250_tree, tvb, offset); + break; + case READ_PARTITION_AID: + case NO_AID_GENERATED: + case NO_AID_GENERATED_(PRINTER_ONLY): + case TRIGGER_ACTION: + case TEST_REQ_AND_SYS_REQ: + case PF1_KEY: + case PF2_KEY: + case PF3_KEY: + case PF4_KEY: + case PF5_KEY: + case PF6_KEY: + case PF7_KEY: + case PF8_KEY: + case PF9_KEY: + case PF10_KEY: + case PF11_KEY: + case PF12_KEY: + case PF13_KEY: + case PF14_KEY: + case PF15_KEY: + case PF16_KEY: + case PF17_KEY: + case PF18_KEY: + case PF19_KEY: + case PF20_KEY: + case PF21_KEY: + case PF22_KEY: + case PF23_KEY: + case PF24_KEY: + case PA1_KEY: + case PA2_KEY_(CNCL): + case PA3_KEY: + case CLEAR_KEY: + case CLEAR_PARTITION_KEY: + case ENTER_KEY: + case SELECTOR_PEN_ATTENTION: + case OPERATOR_ID_READER: + case MAG_READER_NUMBER: + proto_tree_add_item(tn5250_tree, + hf_tn5250_cursor_x, + tvb, offset, + 1, + FALSE); + offset++; + + proto_tree_add_item(tn5250_tree, + hf_tn5250_cursor_y, + tvb, offset, + 1, + FALSE); + offset++; + offset += dissect_orders_and_data(tn5250_tree, tvb, offset); + break; + default: + proto_tree_add_text(tn5250_tree, tvb, offset, 1, "Bogus value: %u", aid); + offset++; + break; + } + return (offset - start); +} + + +static void +dissect_tn5250(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *tn5250_tree; + proto_item *ti; + gint offset = 0; + gint tn5250_cmd = 0; + conversation_t *conversation; + tn5250_conv_info_t *tn5250_info = NULL; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "TN5250"); + + pinfo->fd->flags.encoding = CHAR_EBCDIC; + + /* Do we have a conversation for this connection? */ + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + if (conversation != NULL) { + /* Do we already have a type and mechanism? */ + tn5250_info = conversation_get_proto_data(conversation, proto_tn5250); + } + + if (!tn5250_info) + return; + + if (tree) { + ti = proto_tree_add_item(tree, proto_tn5250, tvb, offset, -1, FALSE); + tn5250_tree = proto_item_add_subtree(ti, ett_tn5250); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + offset += dissect_tn5250_header(tn5250_tree, tvb, offset); + + while (tvb_offset_exists(tvb, offset)) { + tn5250_cmd = tvb_get_guint8(tvb, offset); + if (pinfo->srcport == tn5250_info->outbound_port) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "TN5250 Data from Mainframe"); + offset += dissect_outbound_stream(tn5250_tree, tvb, offset); + }else{ + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "TN5250 Data to Mainframe"); + offset += dissect_inbound_stream(tn5250_tree, tvb, offset); + } + } + } + +} + +void +proto_register_tn5250(void) +{ + static hf_register_info hf[] = { + { &hf_tn5250_escape_code, + { "Escape Code", "tn5250.escape_code", + FT_UINT8, BASE_HEX, VALS(vals_escape_codes), 0x0, + "Escape Code", HFILL }}, + { &hf_tn5250_command_code, + { "Command Code", "tn5250.command_code", + FT_UINT8, BASE_HEX, VALS(vals_command_codes), 0x0, + "Command Code", HFILL }}, + { &hf_tn5250_sf_length, + { "Structured Field Length", "tn5250.sf_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Structured Field Length", HFILL }}, + + /* Write Control Characters */ + { &hf_tn5250_wcc, + { "Write Control Character", "tn5250.wcc", + FT_UINT8, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_tn5250_wcc_nop, + { "WCC NOP", + "tn5250.wcc.nop", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }}, + { &hf_tn5250_wcc_reset, + { "WCC Reset", + "tn5250.wcc.reset", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_tn5250_wcc_printer1, + { "WCC Printer1", + "tn5250.wcc.printer1", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_tn5250_wcc_printer2, + { "WCC Printer2", + "tn5250.wcc.printer2", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_tn5250_wcc_start_printer, + { "WCC Start Printer", + "tn5250.wcc.start_printer", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }}, + { &hf_tn5250_wcc_sound_alarm, + { "WCC Sound Alarm", + "tn5250.wcc.sound_alarm", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }}, + { &hf_tn5250_wcc_keyboard_restore, + { "WCC Keyboard Restore", + "tn5250.wcc.keyboard_restore", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_tn5250_wcc_reset_mdt, + { "WCC Reset MDT", + "tn5250.wcc.reset_mdt", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + + /* 8.7 Copy Control Codes (CCC) */ + { &hf_tn5250_ccc, + {"Copy Control Code", "tn5250.ccc", FT_UINT8, BASE_HEX, + NULL, 0, NULL, HFILL}}, + { &hf_tn5250_ccc_coding, + {"Coding", "tn5250.ccc_coding", FT_UINT8, BASE_HEX, + VALS (vals_coding), CODING_BITS, "", HFILL}}, + { &hf_tn5250_ccc_printout, + {"Printout Format", "tn5250.ccc_printout", FT_UINT8, BASE_HEX, + VALS (vals_printout_format), PRINT_BITS, "", HFILL}}, + { &hf_tn5250_ccc_start_print, + { "The start-print bit", + "tn5250.ccc_start_print", FT_BOOLEAN, 8, NULL, START_PRINT, "", HFILL }}, + { &hf_tn5250_ccc_sound_alarm, + { "The sound-alarm bit", + "tn5250.ccc_sound_alarm", FT_BOOLEAN, 8, NULL, SOUND_ALARM, "", HFILL }}, + { &hf_tn5250_ccc_copytype, + {"Type of Data to be Copied", "tn5250.ccc_copytype", FT_UINT8, BASE_HEX, + VALS (vals_copytype), ATTRIBUTE_BITS, "", HFILL}}, + + /* 4.4.1 Field Attributes */ + { &hf_tn5250_field_attribute, + {"3270 Field Attribute", "tn5250.field_attribute", FT_UINT8, BASE_HEX, + NULL, 0, NULL, HFILL}}, + { &hf_tn5250_fa_graphic_convert1, + { "Graphic Convert1", + "tn5250.fa.graphic_convert1", FT_BOOLEAN, 8, NULL, GRAPHIC_CONVERT1, "", HFILL }}, + { &hf_tn5250_fa_graphic_convert2, + { "Graphic Convert2", + "tn5250.fa.graphic_convert2", FT_BOOLEAN, 8, NULL, GRAPHIC_CONVERT2, "", HFILL }}, + { &hf_tn5250_fa_protected, + { "Protected", + "tn5250.fa.protected", FT_BOOLEAN, 8, NULL, PROTECTED, "", HFILL }}, + { &hf_tn5250_fa_numeric, + { "Numeric", + "tn5250.fa.numeric", FT_BOOLEAN, 8, NULL, NUMERIC, "", HFILL }}, + { &hf_tn5250_fa_display, + {"Display", "tn5250.fa.display", FT_UINT8, BASE_HEX, + VALS (vals_fa_display), DISPLAY_BITS, "", HFILL}}, + { &hf_tn5250_fa_reserved, + { "Reserved", + "tn5250.fa.reserved", FT_BOOLEAN, 8, NULL, RESERVED, "", HFILL }}, + { &hf_tn5250_fa_modified, + { "Modified", + "tn5250.fa.modified", FT_BOOLEAN, 8, NULL, MODIFIED, "", HFILL }}, + + /* Order Code */ + { &hf_tn5250_order_code, + { "Order Code", "tn5250.order_code", + FT_UINT8, BASE_HEX, VALS(vals_order_codes), 0x0, + "Order Code", HFILL }}, + { &hf_tn5250_character_code, + { "Character Code", "tn5250.character_code", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Character Code", HFILL }}, + { &hf_tn5250_stop_address, + { "Stop Address", "tn5250.stop_address", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Stop Address", HFILL }}, + { &hf_tn5250_attribute_type, + { "Attribute Type", "tn5250.attribute_type", + FT_UINT8, BASE_HEX, VALS(vals_attribute_types), 0x0, + "Attribute Type", HFILL }}, + { &hf_tn5250_extended_highlighting, + { "Extended Highlighting", "tn5250.extended_highlighting", + FT_UINT8, BASE_HEX, VALS(vals_extended_highlighting), 0x0, + "Extended Highlighting", HFILL }}, + { &hf_tn5250_color, + { "Color", "tn5250.color", + FT_UINT8, BASE_HEX, VALS(vals_color_identifications), 0x0, + "Color", HFILL }}, + { &hf_tn5250_character_set, + { "Character Set", "tn5250.color", + FT_UINT8, BASE_HEX, RVALS(rvals_character_set), 0x0, + "Character Set", HFILL }}, + { &hf_tn5250_field_outlining, + { "Field Outlining", "tn5250.field_outlining", + FT_UINT8, BASE_HEX, VALS(vals_field_outlining), 0x0, + "Field Outlining", HFILL }}, + { &hf_tn5250_transparency, + { "Transparency", "tn5250.transparency", + FT_UINT8, BASE_HEX, VALS(vals_transparency), 0x0, + "Transparency", HFILL }}, + { &hf_tn5250_field_validation_mandatory_fill, + { "3270 Field validation_mandatory_fill", "tn5250.field_validation_mandatory_fill", + FT_BOOLEAN, 8, TFS(&tn5250_field_validation_mandatory_fill), + RESERVED, "3270 Field Attribute Modified", HFILL }}, + { &hf_tn5250_field_validation_trigger, + { "3270 Field validation_mandatory_trigger", "tn5250.field_validation_mandatory_trigger", + FT_BOOLEAN, 8, TFS(&tn5250_field_validation_trigger), + RESERVED, "3270 Field Attribute Modified", HFILL }}, + { &hf_tn5250_field_validation_mandatory_entry, + { "3270 Field validation_mandatory_entry", "tn5250.field_validation_mandatory_entry", + FT_BOOLEAN, 8, TFS(&tn5250_field_validation_mandatory_entry), + RESERVED, "3270 Field Attribute Modified", HFILL }}, + { &hf_tn5250_all_character_attributes, + { "all_character_attributes", "tn5250.all_character_attributes", + FT_UINT8, BASE_HEX, NULL, 0x0, + "all_character_attributes", HFILL }}, + { &hf_tn5250_aid, + { "Attention Identification", "hf_tn5250_aid", + FT_UINT8, BASE_HEX, VALS(vals_attention_identification_bytes), 0x0, + "hf_tn5250_aid", HFILL }}, + + { &hf_tn5250_buffer_x, + { "Buffer X", "hf_tn5250_buffer_x", + FT_UINT8, BASE_HEX, NULL, 0x0, + "hf_tn5250_buffer_x", HFILL }}, + { &hf_tn5250_buffer_y, + { "Buffer Y", "hf_tn5250_buffer_y", + FT_UINT8, BASE_HEX, NULL, 0x0, + "hf_tn5250_buffer_y", HFILL }}, + + { &hf_tn5250_color_command, + { "tn5250.color_command", "tn5250.color_command", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.color_command", HFILL }}, + { &hf_tn5250_cursor_x, + { "Cursor X", "tn5250.cursor_x", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.cursor_x", HFILL }}, + { &hf_tn5250_cursor_y, + { "Cursor Y", "tn5250.cursor_y", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.cursor_y", HFILL }}, + { &hf_tn5250_cw, + { "tn5250.cw", "tn5250.cw", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.cw", HFILL }}, + { &hf_tn5250_dl, + { "tn5250.dl", "tn5250.dl", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.dl", HFILL }}, + { &hf_tn5250_double_byte_sf_id, + { "tn5250.double_byte_sf_id", "tn5250.double_byte_sf_id", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.double_byte_sf_id", HFILL }}, + { &hf_tn5250_erase_flags, + { "tn5250.erase_flags", "tn5250.erase_flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.erase_flags", HFILL }}, + + { &hf_tn5250_field_data, + { "Field Data", "tn5250.field_data", + FT_EBCDIC, BASE_NONE, NULL, 0x0, + "tn5250.field_data", HFILL }}, + + { &hf_tn5250_number_of_attributes, + { "tn5250.number_of_attributes", "tn5250.number_of_attributes", + FT_UINT8, BASE_HEX, NULL, 0x0, + "tn5250.number_of_attributes", HFILL }}, + + { &hf_tn5250_resbyte, + { "Flags (Reserved):", "tn5250.resbyte", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Flags (Reserved):", HFILL }}, + { &hf_tn5250_resbytes, + { "Flags (Reserved):", "tn5250.resbytes", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Flags (Reserved):", HFILL }}, + { &hf_tn5250_res_twobytes, + { "Flags (Reserved):", "tn5250.res_twobytes", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Flags (Reserved):", HFILL }}, + { &hf_tn5250_sf_outbound_id, + { "Structured Field", "tn5250.sf_outbound_id", + FT_UINT8, BASE_HEX, VALS(vals_outbound_structured_fields), 0x0, + "Structured Field", HFILL }}, + { &hf_tn5250_sf_inbound_id, + { "Structured Field", "tn5250.sf_inbound_id", + FT_UINT8, BASE_HEX, VALS(vals_inbound_structured_fields), 0x0, + "Structured Field", HFILL }}, + { &hf_tn5250_sf_inbound_outbound_id, + { "Structured Field", "tn5250.sf_inbound_outbound_id", + FT_UINT8, BASE_HEX, VALS(vals_outbound_inbound_structured_fields), 0x0, + "Structured Field", HFILL }}, + { &hf_tn5250_sf_query_replies, + { "Query Reply", "tn5250.sf_query_reply", + FT_UINT8, BASE_HEX, VALS(vals_query_replies), 0x0, + "Query Reply", HFILL }}, + + { &hf_tn5250_null, + { "Trailing Null (Possible Mainframe/Emulator Bug)", "tn5250.null", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Trailing Null (Possible Mainframe/Emulator Bug)", HFILL }}, + { &hf_tn5250_unknown_data, + { "Unknown Data (Possible Mainframe/Emulator Bug)", "tn5250.unknown_data", + FT_EBCDIC, BASE_HEX, NULL, 0x0, + "Unknown Data (Possible Mainframe/Emulator Bug)", HFILL }}, + + /* 14.4 - Clear Unit Alternate */ + { &hf_tn5250_cua_parm, + { "TN5250 CUA Parameter", "tn5250.cua_parm", + FT_UINT16, BASE_HEX, VALS(vals_cua_parms), 0x0, + "TN5250 CUA Parameter", HFILL }}, + + + /*TN5250 - RFC1205 - SNA Header Fields */ + { &hf_tn5250_logical_record_length, + { "TN5250 Logical Record Length", "tn5250.logical_record_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "TN5250 Logical Record Length", HFILL }}, + { &hf_tn5250_sna_record_type, + { "TN5250 SNA Record Type", "tn5250.sna_record_type", + FT_UINT16, BASE_HEX, VALS(vals_tn5250_header_data_types), 0x0, + "TN5250 SNA Record Type", HFILL }}, + { &hf_tn5250_variable_record_length, + { "TN5250 Variable Record Length", "tn5250.variable_record_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "TN5250 Variable Record Length", HFILL }}, + { &hf_tn5250_header_flags, + { "TN5250 SNA Flags", "tn5250.header_flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + "TN5250 SNA Flags", HFILL }}, + { &hf_tn5250_ds_output_error, + { "Data Stream Output Error", + "tn5250.ds_output_error", FT_BOOLEAN, 8, NULL, 0x80, "", HFILL }}, + { &hf_tn5250_attn_key, + { "5250 attention key was pressed.", + "tn5250.attn_key", FT_BOOLEAN, 8, NULL, 0x40, "", HFILL }}, + { &hf_tn5250_sys_request_key, + { "5250 System Request key was pressed", + "tn5250.sys_request_key", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }}, + { &hf_tn5250_test_request_key, + { "5250 Test Request key was pressed", + "tn5250.test_request_key", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }}, + { &hf_tn5250_error_state, + { "In Error State", + "tn5250.error_state", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }}, + { &hf_tn5250_operation_code, + { "TN5250 Operation Code", "tn5250.operation_code", + FT_UINT8, BASE_HEX, VALS(vals_tn5250_header_operation_code), 0x0, + "TN5250 Operation Code", HFILL }}, + { &hf_tn5250_error_code, + { "TN5250 Error Code", "tn5250.error_code", + FT_UINT16, BASE_HEX, VALS(vals_tn5250_header_error_codes), 0x0, + "TN5250 Error Code", HFILL }}, + }; + + static gint *ett[] = { + &ett_tn5250, + &ett_sf, + &ett_tn5250_field_attribute, + &ett_tn5250_field_validation, + &ett_tn5250_usable_area_flags1, + &ett_tn5250_usable_area_flags2, + &ett_tn5250_query_reply_alphanumeric_flags, + &ett_tn5250_character_sets_flags1, + &ett_tn5250_character_sets_flags2, + &ett_tn5250_character_sets_form, + &ett_tn5250_cs_descriptor_flags, + &ett_tn5250_color_flags, + &ett_tn5250_dc_dir_flags, + &ett_tn5250_wcc, + &ett_tn5250_ccc, + &ett_tn5250_msr_state_mask, + &ett_tn5250_header_flags + }; + module_t *tn5250_module; + + proto_tn5250 = proto_register_protocol("TN5250 Protocol", "TN5250", "tn5250"); + register_dissector("tn5250", dissect_tn5250, proto_tn5250); + proto_register_field_array(proto_tn5250, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + /* Preferences */ + tn5250_module = prefs_register_protocol(proto_tn5250, proto_reg_handoff_tn5250); + +} + +void +proto_reg_handoff_tn5250(void) +{ + dissector_handle_t tn5250_handle; + tn5250_handle = create_dissector_handle(dissect_tn5250, proto_tn5250); + dissector_add_handle("tcp.port", tn5250_handle); /* for "decode-as" */ +} + +void +add_tn5250_conversation(packet_info *pinfo _U_, int tn5250e) +{ + conversation_t *conversation; + tn5250_conv_info_t *tn5250_info = NULL; + + /* + * Do we have a conversation for this connection? + */ + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + if (conversation == NULL) { + /* We don't yet have a conversation, so create one. */ + conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + } + + /* + * Do we already have a type and mechanism? + */ + tn5250_info = conversation_get_proto_data(conversation, proto_tn5250); + if (tn5250_info == NULL) { + /* No. Attach that information to the conversation, and add + * it to the list of information structures. + */ + tn5250_info = g_malloc(sizeof(tn5250_conv_info_t)); + COPY_ADDRESS(&(tn5250_info->outbound_addr),&(pinfo->dst)); + tn5250_info->outbound_port = pinfo->destport; + COPY_ADDRESS(&(tn5250_info->inbound_addr),&(pinfo->src)); + tn5250_info->inbound_port = pinfo->srcport; + conversation_add_proto_data(conversation, proto_tn5250, tn5250_info); + tn5250_info->next = tn5250_info_items; + tn5250_info_items = tn5250_info; + } + + tn5250_info->extended = tn5250e; + +} + +int +find_tn5250_conversation(packet_info *pinfo _U_) +{ + conversation_t *conversation = NULL; + tn5250_conv_info_t *tn5250_info = NULL; + + /* + * Do we have a conversation for this connection? + */ + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + if (conversation != NULL) { + tn5250_info = conversation_get_proto_data(conversation, proto_tn5250); + if (tn5250_info != NULL) { + /* + * Do we already have a type and mechanism? + */ + return 1; + } + } + return 0; +} Index: epan/dissectors/packet-tn5250.h =================================================================== --- epan/dissectors/packet-tn5250.h (revision 0) +++ epan/dissectors/packet-tn5250.h (revision 0) @@ -0,0 +1,1312 @@ +/* packet-tn5250.h + * Headers for tn5250.packet dissection + * + * Reference: + * 5250 Information Display System: Data Stream Programmer's Reference + * GA23-0059-07 + * + * Copyright 2009, Robert Hogan + * + * $Id: packet-tn5250.h 26356 2008-10-05 23:08:54Z wmeier $ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + * + * + * TODO: + * + * + */ + +#ifndef TN5250_H_INCLUDED +#define TN5250_H_INCLUDED + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* OUTBOUND DATA STREAM (MAINFRAME PROGRAM -> DISPLAY) + + ________________ _____ __________________ +| Command Code |WCC | Orders and Data | +|________________|_____|__________________| + + or + ______ ______________________ +| WSF | Structured Field(s) | +|______|______________________| + +*/ +static const value_string vals_escape_codes[] = { + { 0x04 , "ESC"}, + { 0x00, NULL } +}; + +/*14.1 Workstation Data Stream Commands*/ +#define CLEAR_UNIT 0x40 +#define CLEAR_UNIT_ALTERNATE 0x20 +#define CLEAR_FORMAT_TABLE 0x50 +#define WRITE_TO_DISPLAY 0x11 +#define WRITE_ERROR_CODE 0x21 +#define WRITE_ERROR_CODE_TO_WINDOW 0x22 +#define READ_INPUT_FIELDS 0x42 +#define READ_MDT_FIELDS 0x52 +#define READ_MDT_ALTERNATE 0x82 +#define READ_SCREEN 0x62 +#define READ_SCREEN_WITH_EXTENDED_ATTRIBUTES 0x64 +#define READ_SCREEN_TO_PRINT 0x66 +#define READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES 0x68 +#define READ_SCREEN_TO_PRINT_WITH_GRIDLINES 0x6A +#define READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES_AND_GRIDLINES 0x6C +#define READ_IMMEDIATE 0x72 +#define READ_MODIFIED_IMMEDIATE_ALTERNATE 0x83 +#define SAVE_SCREEN 0x02 +#define SAVE_PARTIAL_SCREEN 0x03 +#define RESTORE_SCREEN 0x12 +#define RESTORE_PARTIAL_SCREEN 0x13 +#define ROLL 0x23 +#define WRITE_STRUCTURED_FIELD 0xF3 +#define WRITE_SINGLE_STRUCTURED_FIELD 0xF4 +#define COPY-TO-PRINTER 0x16 + +static const value_string vals_command_codes[] = { + { CLEAR_UNIT , "Clear Unit"}, + { CLEAR_UNIT_ALTERNATE , "Clear Unit Alternate"}, + { CLEAR_FORMAT_TABLE , "Clear Format Table"}, + { WRITE_TO_DISPLAY , "Write To Display"}, + { WRITE_ERROR_CODE , "Write Error Code"}, + { WRITE_ERROR_CODE_TO_WINDOW , "Write Error Code To Window"}, + { READ_INPUT_FIELDS , "Read Input Fields"}, + { READ_MDT_FIELDS , "Read Mdt Fields"}, + { READ_MDT_ALTERNATE , "Read Mdt Alternate"}, + { READ_SCREEN , "Read Screen"}, + { READ_SCREEN_WITH_EXTENDED_ATTRIBUTES , "Read Screen With Extended Attributes"}, + { READ_SCREEN_TO_PRINT , "Read Screen To Print"}, + { READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES , "Read Screen To Print With Extended Attributes"}, + { READ_SCREEN_TO_PRINT_WITH_GRIDLINES , "Read Screen To Print With Gridlines"}, + { READ_SCREEN_TO_PRINT_WITH_EXTENDED_ATTRIBUTES_AND_GRIDLINES , "Read Screen To Print With Extended Attributes And Gridlines"}, + { READ_IMMEDIATE , "Read Immediate"}, + { READ_MODIFIED_IMMEDIATE_ALTERNATE , "Read Modified Immediate Alternate"}, + { SAVE_SCREEN , "Save Screen"}, + { SAVE_PARTIAL_SCREEN , "Save Partial Screen"}, + { RESTORE_SCREEN , "Restore Screen"}, + { RESTORE_PARTIAL_SCREEN , "Restore Partial Screen"}, + { ROLL , "Roll"}, + { WRITE_STRUCTURED_FIELD , "Write Structured Field"}, + { WRITE_SINGLE_STRUCTURED_FIELD , "Write Single Structured Field"}, + { COPY-TO-PRINTER , "Copy-To-Printer"}, + { 0x00, NULL } +}; + +/*14.4 Clear Unit Alternate*/ +static const value_string vals_cua_parms[] = { + { 0x00 , "Set screen size to 27 rows by 132 columns"}, + { 0x80 , "Leave the screen size unchanged and do not erase image/fax data from the display memory."}, + { 0x00, NULL } +}; + +/* WCC (Write Control Characters) */ +/* +#define NOP 0x01 +#define WCC_RESET 0x02 +#define PRINTER1 0x04 +#define PRINTER2 0x08 +#define START_PRINTER 0x10 +#define SOUND_ALARM 0x20 +#define KEYBOARD_RESTORE 0x40 +#define RESET_MDT 0x80 + +static const value_string vals_write_control_characters[] = { + { NOP , "Nop"}, + { WCC_RESET , "Wcc Reset"}, + { PRINTER1 , "Printer"}, + { PRINTER2 , "Printer"}, + { START_PRINTER , "Start Printer"}, + { SOUND_ALARM , "Sound Alarm"}, + { KEYBOARD_RESTORE, "Keyboard Restore"}, + { RESET_MDT , "Reset Mdt"}, + { 0x00, NULL } +}; +*/ + +/* Order Codes */ + +#define SF 0x1D +#define SFE 0x29 +#define SBA 0x11 +#define SA 0x28 +#define MF 0x2C +#define IC 0x13 +#define PT 0x05 +#define RA 0x3C +#define EUA 0x12 +#define GE 0x08 + +static const value_string vals_order_codes[] = { + { SF , "Start Field (SF)"}, + { SFE, "Start Field Extended (SFE)"}, + { SBA, "Set Buffer Address (SBA)"}, + { SA , "Set Attribute (SA)"}, + { MF , "Modify Field (MF)"}, + { IC , "Insert Cursor (IC)"}, + { PT , "Program Tab (PT)"}, + { RA , "Repeat to Address (RA)"}, + { EUA, "Erase Unprotected to Address (EUA)"}, + { GE , "Graphic Escape (GE)"}, + { 0x00, NULL } +}; + +/* 4.3.11 Format Control Orders */ + +#define NUL 0x00 +#define SUB 0x3F +#define DUP 0x1C +#define FM 0x1E +#define FF 0x0C +#define CR 0x0D +#define NL 0x15 +#define EM 0x19 +#define EO 0xFF + +static const value_string vals_format_control_orders[] = { + { NUL , "Null"}, + { SUB , "Substitute"}, + { DUP , "Duplicate"}, + { FM , "Field Mark"}, + { FF , "Form Feed"}, + { CR , "Carriage Return"}, + { NL , "New Line"}, + { EM , "End of Medium"}, + { EO , "Eight Ones"}, + { 0x00, NULL } +}; + + +/* 8.7 Copy Control Code */ +#define BIT_14 0x00 +#define BIT_12 0x40 +#define RESERVEDCCC 0x80 +#define BIT_12_2 0xC0 +#define CODING_BITS 0xC0 + +static const value_string vals_coding[] = { + { BIT_14 , "Display Selector Pen Detectable"}, + { BIT_12 , "Intensified Display Selector Pen Detectable"}, + { RESERVEDCCC, "Non Display Non Detectable"}, + { BIT_12_2, "Display Not Selector Pen Detectable"}, + { 0x00, NULL } +}; + +#define POINT_LINE_LENGTH 0x00 +#define PRINT_LINE_40 0x10 +#define PRINT_LINE_64 0x20 +#define PRINT_LINE_80 0x30 +#define PRINT_BITS 0x30 + +static const value_string vals_printout_format[] = { + { POINT_LINE_LENGTH, "The NL, EM, and CR orders in the data stream determine pointline length. " + "Provides a 132-print position line when the orders are not present."}, + { PRINT_LINE_40 , "Specifies a 40-character print line."}, + { PRINT_LINE_64 , "Specifies a 64-character print line."}, + { PRINT_LINE_80 , "Specifies an 80-character print line."}, + { 0x00, NULL } +}; + +#define START_PRINT 0x08 +#define SOUND_ALARM 0x04 + +#define ONLY_ATTRIBUTE_CHARACTERS 0x00 +#define ATTRIBUTE_CHARACTERS_UNPROTECTED_AN 0x01 +#define ALL_ATTRIBUTE_PROTECTED 0x02 +#define ENTIRE_CONTENTS 0x03 +#define ATTRIBUTE_BITS 0x03 + +static const value_string vals_copytype[] = { + { ONLY_ATTRIBUTE_CHARACTERS , "Only attribute characters are copied."}, + { ATTRIBUTE_CHARACTERS_UNPROTECTED_AN , "Attribute characters and unprotected alphanumeric fields (including nulls) are copied. Nulls are transferred for the alphanumeric characters not copied from the protected fields."}, + { ALL_ATTRIBUTE_PROTECTED , "All attribute characters and protected alphanumeric fields (including nulls) are copied. Nulls are transferred for the alphanumeric characters not copied from the unprotected fields."}, + { ENTIRE_CONTENTS , "The entire contents of the storage buffer (including nulls) are copied."}, + { 0x00, NULL } +}; + +/* 4.4.1 Field Attributes */ +#define GRAPHIC_CONVERT1 0x80 +#define GRAPHIC_CONVERT2 0x40 +#define PROTECTED 0x20 +#define NUMERIC 0x10 +#define RESERVED 0x08 +#define MODIFIED 0x04 + +#define DISPLAY_NOT_SELECTOR_PEN_DETECTABLE 0x00 +#define DISPLAY_SELECTOR_PEN_DETECTABLE 0x01 +#define INTENSIFIED_DISPLAY_SELECTOR_PEN_DETECTABLE 0x02 +#define NON_DISPLAY_NON_DETECTABLE 0x03 +#define DISPLAY_BITS 0x03 + +static const value_string vals_fa_display[] = { + { DISPLAY_SELECTOR_PEN_DETECTABLE , "Display Selector Pen Detectable"}, + { INTENSIFIED_DISPLAY_SELECTOR_PEN_DETECTABLE, "Intensified Display Selector Pen Detectable"}, + { NON_DISPLAY_NON_DETECTABLE , "Non Display Non Detectable"}, + { DISPLAY_NOT_SELECTOR_PEN_DETECTABLE , "Display Not Selector Pen Detectable"}, + { 0x00, NULL } +}; + +/* 4.4.5 Attribute Types */ +#define ALL_CHARACTER_ATTRIBUTES 0x00 +#define T5250_FIELD_ATTRIBUTE 0xC0 +#define FIELD_VALIDATION 0xC1 +#define FIELD_OUTLINING 0xC2 +#define EXTENDED_HIGHLIGHTING 0x41 +#define FOREGROUND_COLOR 0x42 +#define CHARACTER_SET 0x43 +#define BACKGROUND_COLOR 0x45 +#define TRANSPARENCY 0x46 + + +static const value_string vals_attribute_types[] = { + { ALL_CHARACTER_ATTRIBUTES, "All character attributes"}, + { T5250_FIELD_ATTRIBUTE , "5250 Field attribute"}, + { FIELD_VALIDATION , "Field validation"}, + { FIELD_OUTLINING , "Field outlining"}, + { EXTENDED_HIGHLIGHTING , "Extended highlighting"}, + { FOREGROUND_COLOR , "Foreground color"}, + { CHARACTER_SET , "Character set"}, + { BACKGROUND_COLOR , "Background color"}, + { TRANSPARENCY , "Transparency"}, + { 0x00, NULL } +}; + +/* 4.4.6.3 Extended Highlighting */ +#define DEFAULT_HIGHLIGHTING 0x00 +#define NORMAL 0xF0 +#define BLINK 0xF1 +#define REVERSE_VIDEO 0xF2 +#define UNDERSCORE 0xF4 + +static const value_string vals_extended_highlighting[] = { + { DEFAULT_HIGHLIGHTING , "Default"}, + { NORMAL , "Normal (as determined by the 5250 field attribute)"}, + { BLINK , "Blink"}, + { REVERSE_VIDEO, "Reverse video"}, + { UNDERSCORE , "Underscore."}, + { 0x00, NULL } +}; + +/* 4.4.6.4 Color Identifications */ +#define ALL_PLANES 0x00 +#define BLUE_PLANE 0x01 +#define RED_PLANE 0x02 +#define GREEN_PLANE 0x04 +#define NEUTRAL1 0xF0 +#define BLUE 0xF1 +#define RED 0xF2 +#define PINK 0xF3 +#define GREEN 0xF4 +#define TURQUOISE 0xF5 +#define YELLOW 0xF6 +#define NEUTRAL2 0xF7 +#define BLACK 0xF8 +#define DEEP_BLUE 0xF9 +#define ORANGE 0xFA +#define PURPLE 0xFB +#define PALE_GREEN 0xFC +#define PALE_TURQUOISE 0xFD +#define GREY 0xFE +#define WHITE 0xFF + + +static const value_string vals_color_identifications[] = { + { ALL_PLANES , "ALL PLANES"}, + { BLUE_PLANE , "BLUE PLANE"}, + { RED_PLANE , "RED PLANE"}, + { GREEN_PLANE , "GREEN PLANE"}, + { NEUTRAL1 , "Neutral"}, + { BLUE , "Blue"}, + { RED , "Red"}, + { PINK , "Pink"}, + { GREEN , "Green"}, + { TURQUOISE , "Turquoise"}, + { YELLOW , "Yellow"}, + { NEUTRAL2 , "Neutral"}, + { BLACK , "Black"}, + { DEEP_BLUE , "Deep Blue"}, + { ORANGE , "Orange"}, + { PURPLE , "Purple"}, + { PALE_GREEN , "Pale Green"}, + { PALE_TURQUOISE, "Pale Turquoise"}, + { GREY , "Grey"}, + { WHITE , "White"}, + { 0x00, NULL } +}; + +/* 4.4.6.5 Character Set */ + +#define DEFAULT_CHARACTER_SET 0x00 +#define MIN_LOCAL_ID_FOR_LOADABLE_CHARACTER_SETS 0x40 +#define MAX_LOCAL_ID_FOR_LOADABLE_CHARACTER_SETS 0xEF +#define MIN_LOCAL_ID_FOR_NONLOADABLE_CHARACTER_SETS 0xF0 +#define MAX_LOCAL_ID_FOR_NONLOADABLE_CHARACTER_SETS 0xF7 +#define MIN_LOCAL_ID_FOR_TWO_BYTE_CODED_CHARACTER_SETS 0xF8 +#define MAX_LOCAL_ID_FOR_TWO_BYTE_CODED_CHARACTER_SETS 0xFE + + +static const range_string rvals_character_set[] = { + { DEFAULT_CHARACTER_SET, DEFAULT_CHARACTER_SET, + "DEFAULT_CHARACTER_SET" }, + { MIN_LOCAL_ID_FOR_LOADABLE_CHARACTER_SETS, MAX_LOCAL_ID_FOR_LOADABLE_CHARACTER_SETS, + "LOCAL_ID_FOR_LOADABLE_CHARACTER_SETS"}, + { MIN_LOCAL_ID_FOR_NONLOADABLE_CHARACTER_SETS, MAX_LOCAL_ID_FOR_NONLOADABLE_CHARACTER_SETS, + "LOCAL_ID_FOR_NONLOADABLE_CHARACTER_SETS"}, + { MIN_LOCAL_ID_FOR_TWO_BYTE_CODED_CHARACTER_SETS, MAX_LOCAL_ID_FOR_TWO_BYTE_CODED_CHARACTER_SETS, + "LOCAL_ID_FOR_TWO_BYTE_CODED_CHARACTER_SETS" }, + { 0, 0, NULL } +}; + +/* 4.4.6.6 Field Outlining */ +#define NO_OUTLINING_LINES 0X00 +#define UNDERLINE_ONLY 0X01 +#define RIGHT_VERTICAL_LINE_ONLY 0X02 +#define OVERLINE_ONLY 0X04 +#define LEFT_VERTICAL_LINE_ONLY 0X08 +#define UNDERLINE_AND_RIGHT_VERTICAL_LINE 0X03 +#define UNDERLINE_AND_OVERLINE 0X05 +#define UNDERLINE_AND_LEFT_VERTICAL_LINE 0X09 +#define RIGHT_VERTICAL_LINE_AND_OVERLINE 0X06 +#define RIGHT_AND_LEFT_VERTICAL_LINES 0X0A +#define OVERLINE_AND_LEFT_VERTICAL_LINE 0X0C +#define RECTANGLE_MINUS_LEFT_VERTICAL_LINE 0X07 +#define RECTANGLE_MINUS_OVERLINE 0X0B +#define RECTANGLE_MINUS_RIGHT_VERTICAL_LINE 0X0D +#define RECTANGLE_MINUS_UNDERLINE 0X0E +#define RECTANGLE 0X0F + + +static const value_string vals_field_outlining[] = { + { NO_OUTLINING_LINES , "No outlining lines"}, + { UNDERLINE_ONLY , "Underline only"}, + { RIGHT_VERTICAL_LINE_ONLY , "Right vertical line only"}, + { OVERLINE_ONLY , "Overline only"}, + { LEFT_VERTICAL_LINE_ONLY , "Left vertical line only"}, + { UNDERLINE_AND_RIGHT_VERTICAL_LINE , "Underline and right vertical line"}, + { UNDERLINE_AND_OVERLINE , "Underline and overline"}, + { UNDERLINE_AND_LEFT_VERTICAL_LINE , "Underline and left vertical line"}, + { RIGHT_VERTICAL_LINE_AND_OVERLINE , "Right vertical line and overline"}, + { RIGHT_AND_LEFT_VERTICAL_LINES , "Right and left vertical lines"}, + { OVERLINE_AND_LEFT_VERTICAL_LINE , "Overline and left vertical line"}, + { RECTANGLE_MINUS_LEFT_VERTICAL_LINE , "Rectangle minus left vertical line"}, + { RECTANGLE_MINUS_OVERLINE , "Rectangle minus overline"}, + { RECTANGLE_MINUS_RIGHT_VERTICAL_LINE , "Rectangle minus right vertical line"}, + { RECTANGLE_MINUS_UNDERLINE , "Rectangle minus underline"}, + { RECTANGLE , "Rectangle"}, + { 0x00, NULL } +}; + + +/* 4.4.6.7 Transparency */ +#define DEFAULT_TRANSPARENCY 0X00 +#define BACKGROUND_IS_TRANSPARENT_OR 0XF0 +#define BACKGROUND_IS_TRANSPARENT_XOR 0XF1 +#define BACKGROUND_IS_OPAQUE 0XFF + +static const value_string vals_transparency[] = { + { DEFAULT_TRANSPARENCY , "Default"}, + { BACKGROUND_IS_TRANSPARENT_OR , "Background is transparent (OR)"}, + { BACKGROUND_IS_TRANSPARENT_XOR, "Background is transparent (XOR)"}, + { BACKGROUND_IS_OPAQUE , "Background is opaque (non-transparent)"}, + { 0x00, NULL } +}; + +/* 4.4.6.8 Field Validation */ +#define MANDATORY_FILL 0X10 +#define MANDATORY_ENTRY 0X20 +#define TRIGGER 0X40 + +static const value_string vals_field_validation[] = { + { MANDATORY_FILL , "Mandatory fill"}, + { MANDATORY_ENTRY, "Mandatory entry"}, + { TRIGGER , "Trigger"}, + { 0x00, NULL } +}; + +static const struct true_false_string tn5250_field_validation_mandatory_fill = { + "Mandatory fill", + "" +}; + +static const struct true_false_string tn5250_field_validation_mandatory_entry = { + "Mandatory entry", + "" +}; + +static const struct true_false_string tn5250_field_validation_trigger = { + "Trigger", + "" +}; + +/* 5.1 Outbound Structured Fields */ + +#define READ_PARTITION_QUERY 0x02 +#define READ_PARTITION_QUERY_LIST 0x03 +#define READ_PARTITION_READ_MODIFIED_ALL 0x6E +#define READ_PARTITION_READ_BUFFER 0xF2 +#define READ_PARTITION_READ_MODIFIED 0xF6 + +static const value_string vals_operation_types[] = { + { READ_PARTITION_QUERY , "Read Partition Query"}, + { READ_PARTITION_QUERY_LIST , "Read Partition Query List"}, + { READ_PARTITION_READ_MODIFIED_ALL , "Read Partition Read Modified All"}, + { READ_PARTITION_READ_BUFFER , "Read Partition Read Buffer"}, + { READ_PARTITION_READ_MODIFIED , "Read Partition Read Modified"}, + { 0x00, NULL } +}; + + +#define ACTIVATE_PARTITION 0x0E +#define BEGIN_OR_END_OF_FILE 0x0F85 +#define CREATE_PARTITION 0x0C +#define DESTROY_PARTITION 0x0D +#define ERASE_OR_RESET 0x03 +#define LOAD_COLOR_TABLE 0x0F05 +#define LOAD_FORMAT_STORAGE 0x0F24 +#define LOAD_LINE_TYPE 0x0F07 +#define LOAD_PROGRAMMED_SYMBOLS 0x06 +#define MODIFY_PARTITION 0x0F0A +#define OUTBOUND_TEXT_HEADER 0x0F71 +#define OUTBOUND_5250DS 0x40 +#define PRESENT_ABSOLUTE_FORMAT 0x4B +#define PRESENT_RELATIVE_FORMAT 0x4C +#define SET_PARTITION_CHARACTERISTICS 0x0F08 +#define SET_REPLY_MODE 0x09 +#define TYPE_1_TEXT_OUTBOUND 0x0FC1 +#define READ_PARTITION 0x01 +#define REQUEST_RECOVERY_DATA 0x1030 +#define RESET_PARTITION 0x00 +#define RESTART 0x1033 +#define SCS_DATA 0x41 +#define SELECT_COLOR_TABLE 0x0F04 +#define SELECT_FORMAT_GROUP 0x4A +#define SET_CHECKPOINT_INTERVAL 0x1032 +#define SET_MSR_CONTROL 0x0F01 +#define SET_PRINTER_CHARACTERISTICS 0x0F84 +#define SET_WINDOW_ORIGIN 0x0B + + +static const value_string vals_outbound_structured_fields[] = { + { ACTIVATE_PARTITION , "Activate Partition"}, + { BEGIN_OR_END_OF_FILE , "Begin Or End Of File"}, + { CREATE_PARTITION , "Create Partition"}, + { DESTROY_PARTITION , "Destroy Partition"}, + { ERASE_OR_RESET , "Erase Or Reset"}, + { LOAD_COLOR_TABLE , "Load Color Table"}, + { LOAD_FORMAT_STORAGE , "Load Format Storage"}, + { LOAD_LINE_TYPE , "Load Line Type"}, + { LOAD_PROGRAMMED_SYMBOLS , "Load Programmed Symbols"}, + { MODIFY_PARTITION , "Modify Partition"}, + { OUTBOUND_TEXT_HEADER , "Outbound Text Header"}, + { OUTBOUND_5250DS , "Outbound 5250ds"}, + { PRESENT_ABSOLUTE_FORMAT , "Present Absolute Format"}, + { PRESENT_RELATIVE_FORMAT , "Present Relative Format"}, + { SET_PARTITION_CHARACTERISTICS , "Set Partition Characteristics"}, + { SET_REPLY_MODE , "Set Reply Mode"}, + { TYPE_1_TEXT_OUTBOUND , "Type 1 Text Outbound"}, + { READ_PARTITION , "Read Partition"}, + { REQUEST_RECOVERY_DATA , "Request Recovery Data"}, + { RESET_PARTITION , "Reset Partition"}, + { RESTART , "Restart"}, + { SCS_DATA , "Scs Data"}, + { SELECT_COLOR_TABLE , "Select Color Table"}, + { SELECT_FORMAT_GROUP , "Select Format Group"}, + { SET_CHECKPOINT_INTERVAL , "Set Checkpoint Interval"}, + { SET_MSR_CONTROL , "Set Msr Control"}, + { SET_PRINTER_CHARACTERISTICS , "Set Printer Characteristics"}, + { SET_WINDOW_ORIGIN , "Set Window Origin"}, + { 0x00, NULL } +}; + +/* 5.1 Outbound/Inbound Structured Fields */ + +#define DATA_CHAIN 0x0F21 +#define DESTINATION_OR_ORIGIN 0x0F02 +#define OBJECT_CONTROL 0x0F11 +#define OBJECT_DATA 0x0F0F +#define OBJECT_PICTURE 0x0F10 +#define OEM_DATA 0x0F1F +#define SAVE_OR_RESTORE_FORMAT 0x1034 +#define SELECT_IPDS_MODE 0x0F83 + +static const value_string vals_outbound_inbound_structured_fields[] = { + { DATA_CHAIN , "Data Chain"}, + { DESTINATION_OR_ORIGIN , "Destination/Origin"}, + { OBJECT_CONTROL , "Object Control"}, + { OBJECT_DATA , "Object Data"}, + { OBJECT_PICTURE , "Object Picture"}, + { OEM_DATA , "OEM Data"}, + { SAVE_OR_RESTORE_FORMAT , "Save/Restore Format"}, + { SELECT_IPDS_MODE , "Select IPDS Mode."}, + { 0x00, NULL } +}; + +/* 5.11 Load Format Storage */ +#define ADD 0x01 +#define DELETE_FORMAT 0x02 +#define DELETE_GROUP 0x03 +#define RESET_ALL 0x04 +#define REQUEST_SUMMARY_STATUS 0x05 +#define REQUEST_GROUP_STATUS 0x06 + +static const value_string vals_operand[] = { + { ADD , "Add"}, + { DELETE_FORMAT , "Delete Format"}, + { DELETE_GROUP , "Delete Group"}, + { RESET_ALL , "Reset All"}, + { REQUEST_SUMMARY_STATUS , "Request Summary Status"}, + { REQUEST_GROUP_STATUS , "Request Group Status"}, + { 0x00, NULL } +}; + + +/* INBOUND DATA STREAM (DISPLAY -> MAINFRAME PROGRAM) */ + +/* + ______ _______ ________ _______ +| | | | | +| AID | Cursor address | Data | +| | (2 bytes) | | +| | | | | +|______|_______|________|_______| + +An inbound data stream can also consist of an AID (X'88') followed by +structured fields as follows: + ______ __________________ ________ ___________________ +| | | | | +| AID | Structured Field | ...... | Structured Field | +| 0x88 | | | | +|______|__________________|________|___________________| + +*/ + +/* 3.5.6 Attention Identification Bytes (AID) */ + +#define NO_AID_GENERATED 0x60 +#define NO_AID_GENERATED_(PRINTER_ONLY) 0xE8 +#define STRUCTURED_FIELD 0x88 +#define READ_PARTITION_AID 0x61 +#define TRIGGER_ACTION 0x7F +#define TEST_REQ_AND_SYS_REQ 0xF0 +#define PF1_KEY 0xF1 +#define PF2_KEY 0xF2 +#define PF3_KEY 0xF3 +#define PF4_KEY 0xF4 +#define PF5_KEY 0xF5 +#define PF6_KEY 0xF6 +#define PF7_KEY 0xF7 +#define PF8_KEY 0xF8 +#define PF9_KEY 0xF9 +#define PF10_KEY 0x7A +#define PF11_KEY 0x7B +#define PF12_KEY 0x7C +#define PF13_KEY 0xC1 +#define PF14_KEY 0xC2 +#define PF15_KEY 0xC3 +#define PF16_KEY 0xC4 +#define PF17_KEY 0xC5 +#define PF18_KEY 0xC6 +#define PF19_KEY 0xC7 +#define PF20_KEY 0xC8 +#define PF21_KEY 0xC9 +#define PF22_KEY 0x4A +#define PF23_KEY 0x4B +#define PF24_KEY 0x4C +#define PA1_KEY 0x6C +#define PA2_KEY_(CNCL) 0x6E +#define PA3_KEY 0x6B +#define CLEAR_KEY 0x6D +#define CLEAR_PARTITION_KEY 0x6A +#define ENTER_KEY 0x7D +#define SELECTOR_PEN_ATTENTION 0x7E +#define OPERATOR_ID_READER 0xE6 +#define MAG_READER_NUMBER 0xE7 + + +static const value_string vals_attention_identification_bytes[] = { + { NO_AID_GENERATED , "No AID generated"}, + { NO_AID_GENERATED_(PRINTER_ONLY), "No AID generated (printer only)"}, + { STRUCTURED_FIELD , "Structured field"}, + { READ_PARTITION_AID , "Read partition"}, + { TRIGGER_ACTION , "Trigger action"}, + { TEST_REQ_AND_SYS_REQ , "Test Req and Sys Req"}, + { PF1_KEY , "PF1 key"}, + { PF2_KEY , "PF2 key"}, + { PF3_KEY , "PF3 key"}, + { PF4_KEY , "PF4 key"}, + { PF5_KEY , "PF5 key"}, + { PF6_KEY , "PF6 key"}, + { PF7_KEY , "PF7 key"}, + { PF8_KEY , "PF8 key"}, + { PF9_KEY , "PF9 key"}, + { PF10_KEY , "PF10 key"}, + { PF11_KEY , "PF11 key"}, + { PF12_KEY , "PF12 key"}, + { PF13_KEY , "PF13 key"}, + { PF14_KEY , "PF14 key"}, + { PF15_KEY , "PF15 key"}, + { PF16_KEY , "PF16 key"}, + { PF17_KEY , "PF17 key"}, + { PF18_KEY , "PF18 key"}, + { PF19_KEY , "PF19 key"}, + { PF20_KEY , "PF20 key"}, + { PF21_KEY , "PF21 key"}, + { PF22_KEY , "PF22 key"}, + { PF23_KEY , "PF23 key"}, + { PF24_KEY , "PF24 key"}, + { PA1_KEY , "PA1 key"}, + { PA2_KEY_(CNCL) , "PA2 key (Cncl)"}, + { PA3_KEY , "PA3 key"}, + { CLEAR_KEY , "Clear key"}, + { CLEAR_PARTITION_KEY , "Clear Partition key"}, + { ENTER_KEY , "Enter key"}, + { SELECTOR_PEN_ATTENTION , "Selector pen attention"}, + { OPERATOR_ID_READER , "Operator ID reader"}, + { MAG_READER_NUMBER , "Mag Reader Number"}, + { 0x00, NULL } +}; + + + +/* 5.3.6 Object Control */ +#define OCGRAPHICS 0x00 +#define OCIMAGE 0x01 + +static const value_string vals_oc_type[] = { + { OCGRAPHICS, "Graphics"}, + { OCIMAGE , "Image)"}, + { 0x00, NULL } +}; + +/* 6.1 Inbound Structured Fields */ + +#define EXCEPTION_OR_STATUS 0x0F22 +#define INBOUND_TEXT_HEADER 0x0FB1 +#define INBOUND_5250DS 0x0F80 /* TODO: Check */ +#define RECOVERY_DATA 0x1031 +#define TYPE_1_TEXT_INBOUND 0x0FC1 +#define QUERY_REPLY_ALPHANUMERIC_PARTITIONS 0x8184 +#define QUERY_REPLY_AUXILIARY_DEVICE 0x8199 +#define QUERY_REPLY_BEGIN_OR_END_OF_FILE 0x819F +#define QUERY_REPLY_CHARACTER_SETS 0x8185 +#define QUERY_REPLY_COLOR 0x8186 +#define QUERY_REPLY_COOPERATIVE_PROCESSING_REQUESTOR 0x81AB +#define QUERY_REPLY_DATA_CHAINING 0x8198 +#define QUERY_REPLY_DATA_STREAMS 0x81A2 +#define QUERY_REPLY_DBCS_ASIA 0x8191 +#define QUERY_REPLY_DEVICE_CHARACTERISTICS 0x81A0 +#define QUERY_REPLY_DISTRIBUTED_DATA_MANAGEMENT 0x8195 +#define QUERY_REPLY_DOCUMENT_INTERCHANGE_ARCHITECTURE 0x8197 +#define QUERY_REPLY_EXTENDED_DRAWING_ROUTINE 0x81B5 +#define QUERY_REPLY_FIELD_OUTLINING 0x818C +#define QUERY_REPLY_FIELD_VALIDATION 0x818A +#define QUERY_REPLY_FORMAT_PRESENTATION 0x8190 +#define QUERY_REPLY_FORMAT_STORAGE_AUXILIARY_DEVICE 0x8194 +#define QUERY_REPLY_GRAPHIC_COLOR 0x81B4 +#define QUERY_REPLY_GRAPHIC_SYMBOL_SETS 0x81B6 +#define QUERY_REPLY_HIGHLIGHTING 0x8187 +#define QUERY_REPLY_IBM_AUXILIARY_DEVICE 0x819E +#define QUERY_REPLY_IMAGE 0x8182 +#define QUERY_REPLY_IMPLICIT_PARTITION 0x81A6 +#define QUERY_REPLY_IOCA_AUXILIARY_DEVICE 0x81AA +#define QUERY_REPLY_LINE_TYPE 0x81B2 +#define QUERY_REPLY_MSR_CONTROL 0x818B +#define QUERY_REPLY_NULL 0x81FF +#define QUERY_REPLY_OEM_AUXILIARY_DEVICE 0x818F +#define QUERY_REPLY_PAPER_FEED_TECHNIQUES 0x81A7 +#define QUERY_REPLY_PARTITION_CHARACTERISTICS 0x818E +#define QUERY_REPLY_PORT 0x81B3 +#define QUERY_REPLY_PROCEDURE 0x81B1 +#define QUERY_REPLY_PRODUCT_DEFINED_DATA_STREAM 0x819C +#define QUERY_REPLY_REPLY_MODES 0x8188 +#define QUERY_REPLY_RPQ_NAMES 0x81A1 +#define QUERY_REPLY_SAVE_OR_RESTORE_FORMAT 0x8192 +#define QUERY_REPLY_SEGMENT 0x81B0 +#define QUERY_REPLY_SETTABLE_PRINTER_CHARACTERISTICS 0x81A9 +#define QUERY_REPLY_STORAGE_POOLS 0x8196 +#define QUERY_REPLY_SUMMARY 0x8180 +#define QUERY_REPLY_TEXT_PARTITIONS 0x8183 +#define QUERY_REPLY_TRANSPARENCY 0x81A8 +#define QUERY_REPLY_USABLE_AREA 0x8181 +#define QUERY_REPLY_5250_IPDS 0x819A + + +static const value_string vals_inbound_structured_fields[] = { + { EXCEPTION_OR_STATUS , "Exception/Status"}, + { INBOUND_TEXT_HEADER , "Inbound Text Header"}, + { INBOUND_5250DS , "Inbound 5250DS"}, + { RECOVERY_DATA , "Recovery Data"}, + { TYPE_1_TEXT_INBOUND , "Type 1 Text Inbound"}, + { QUERY_REPLY_ALPHANUMERIC_PARTITIONS , "Query Reply (Alphanumeric Partitions)"}, + { QUERY_REPLY_AUXILIARY_DEVICE , "Query Reply (Auxiliary Device)"}, + { QUERY_REPLY_BEGIN_OR_END_OF_FILE , "Query Reply (Begin/End of File)"}, + { QUERY_REPLY_CHARACTER_SETS , "Query Reply (Character Sets)"}, + { QUERY_REPLY_COLOR , "Query Reply (Color)"}, + { QUERY_REPLY_COOPERATIVE_PROCESSING_REQUESTOR , "Query Reply (Cooperative Processing Requestor)"}, + { QUERY_REPLY_DATA_CHAINING , "Query Reply (Data Chaining)"}, + { QUERY_REPLY_DATA_STREAMS , "Query Reply (Data Streams)"}, + { QUERY_REPLY_DBCS_ASIA , "Query Reply (DBCS-Asia)"}, + { QUERY_REPLY_DEVICE_CHARACTERISTICS , "Query Reply (Device Characteristics)"}, + { QUERY_REPLY_DISTRIBUTED_DATA_MANAGEMENT , "Query Reply (Distributed Data Management)"}, + { QUERY_REPLY_DOCUMENT_INTERCHANGE_ARCHITECTURE , "Query Reply (Document Interchange Architecture)"}, + { QUERY_REPLY_EXTENDED_DRAWING_ROUTINE , "Query Reply (Extended Drawing Routine)"}, + { QUERY_REPLY_FIELD_OUTLINING , "Query Reply (Field Outlining)"}, + { QUERY_REPLY_FIELD_VALIDATION , "Query Reply (Field Validation)"}, + { QUERY_REPLY_FORMAT_PRESENTATION , "Query Reply (Format Presentation)"}, + { QUERY_REPLY_FORMAT_STORAGE_AUXILIARY_DEVICE , "Query Reply (Format Storage Auxiliary Device)"}, + { QUERY_REPLY_GRAPHIC_COLOR , "Query Reply (Graphic Color)"}, + { QUERY_REPLY_GRAPHIC_SYMBOL_SETS , "Query Reply (Graphic Symbol Sets)"}, + { QUERY_REPLY_HIGHLIGHTING , "Query Reply (Highlighting)"}, + { QUERY_REPLY_IBM_AUXILIARY_DEVICE , "Query Reply (IBM Auxiliary Device)"}, + { QUERY_REPLY_IMAGE , "Query Reply (Image)"}, + { QUERY_REPLY_IMPLICIT_PARTITION , "Query Reply (Implicit Partition)"}, + { QUERY_REPLY_IOCA_AUXILIARY_DEVICE , "Query Reply (IOCA Auxiliary Device)"}, + { QUERY_REPLY_LINE_TYPE , "Query Reply (Line Type)"}, + { QUERY_REPLY_MSR_CONTROL , "Query Reply (MSR Control)"}, + { QUERY_REPLY_NULL , "Query Reply (Null)"}, + { QUERY_REPLY_OEM_AUXILIARY_DEVICE , "Query Reply (OEM Auxiliary Device)"}, + { QUERY_REPLY_PAPER_FEED_TECHNIQUES , "Query Reply (Paper Feed Techniques)"}, + { QUERY_REPLY_PARTITION_CHARACTERISTICS , "Query Reply (Partition Characteristics)"}, + { QUERY_REPLY_PORT , "Query Reply (Port)"}, + { QUERY_REPLY_PROCEDURE , "Query Reply (Procedure)"}, + { QUERY_REPLY_PRODUCT_DEFINED_DATA_STREAM , "Query Reply (Product Defined Data Stream)"}, + { QUERY_REPLY_REPLY_MODES , "Query Reply (Reply Modes)"}, + { QUERY_REPLY_RPQ_NAMES , "Query Reply (RPQ Names)"}, + { QUERY_REPLY_SAVE_OR_RESTORE_FORMAT , "Query Reply (Save/Restore Format)"}, + { QUERY_REPLY_SEGMENT , "Query Reply (Segment)"}, + { QUERY_REPLY_SETTABLE_PRINTER_CHARACTERISTICS , "Query Reply (Settable Printer Characteristics)"}, + { QUERY_REPLY_STORAGE_POOLS , "Query Reply (Storage Pools)"}, + { QUERY_REPLY_SUMMARY , "Query Reply (Summary)"}, + { QUERY_REPLY_TEXT_PARTITIONS , "Query Reply (Text Partitions)"}, + { QUERY_REPLY_TRANSPARENCY , "Query Reply (Transparency)"}, + { QUERY_REPLY_USABLE_AREA , "Query Reply (Usable Area)"}, + { QUERY_REPLY_5250_IPDS , "Query Reply (5250 IPDS)."}, + { 0x00, NULL } +}; + +/* 6.2 - Exception/Status */ + +#define ACKNOWLEDGED 0x0000 +#define AUXDEVICEAVAIL 0X0001 + +static const value_string vals_statcode[] = { + { ACKNOWLEDGED , "Acknowledged. The formats were successfully loaded, and no exception occurred."}, + { AUXDEVICEAVAIL , "Auxiliary device available"}, + { 0x00, NULL } +}; + + +#define INVALID_DOID 0x0801 +#define DEVICENOTAVAIL 0X0802 +#define RETIRED 0X0803 +#define BUFFER_OVERRUN 0X0804 +#define STORAGE 0X0805 +#define FORMATNOTSPEC 0X0806 +#define DATAERROR 0X0807 +#define INSUFFRESOURCE 0X084B +#define EXCEEDSLIMIT 0X084C +#define FUNCTNOTSUPP 0X1003 + +static const value_string vals_excode[] = { + { INVALID_DOID , "Invalid/unrecognized DOID in the Destination/Origin structured field. " + "AVAILSTAT must be set to B’0’."}, + { DEVICENOTAVAIL , "DOID valid, but the auxiliary device is not available because of an " + "intervention required condition (for example, out of paper, power " + "off, or processing code not resident). Available status is sent " + "when the condition clears. AVAILSTAT must be set to B’1’."}, + { RETIRED , "Retired."}, + { BUFFER_OVERRUN , "Buffer overrun."}, + { STORAGE , "Insufficient storage. The loading of the formats could not be " + "completed because storage was exhausted."}, + { FORMATNOTSPEC , "The format or group name was not specified in the Load Format " + "Storage structured field."}, + { DATAERROR , "Data error."}, + { INSUFFRESOURCE , "Temporary insufficient resource. The application does not have " + "a buffer available or is busy. The device chooses whether to " + "set send status when the condition clears and set AVAILSTAT accordingly."}, + { EXCEEDSLIMIT , "The auxiliary device data in the transmission exceeds the limit specified " + "in the LIMOUT parameter of the Query Reply for the auxiliary device. " + "AVAILSTAT must be set to B’0’."}, + { FUNCTNOTSUPP , "Function not supported."}, + { 0x00, NULL } +}; + +/* Query Reply Types */ +#define ALPHANUMERIC_PARTITIONS 0x84 +#define AUXILIARY_DEVICE 0x99 +#define QBEGIN_OR_END_OF_FILE 0x9F +#define CHARACTER_SETS 0x85 +#define COLOR 0x86 +#define COOPERATIVE_PROCESSING_REQUESTOR 0xAB +#define DATA_CHAINING 0x98 +#define DATA_STREAMS 0xA2 +#define DBCS_ASIA 0x91 +#define DEVICE_CHARACTERISTICS 0xA0 +#define DISTRIBUTED_DATA_MANAGEMENT 0x95 +#define DOCUMENT_INTERCHANGE_ARCHITECTURE 0x97 +#define EXTENDED_DRAWING_ROUTINE 0xB5 +#define QFIELD_OUTLINING 0x8C +#define QFIELD_VALIDATION 0x8A +#define FORMAT_PRESENTATION 0x90 +#define FORMAT_STORAGE_AUXILIARY_DEVICE 0x94 +#define GRAPHIC_COLOR 0xB4 +#define GRAPHIC_SYMBOL_SETS 0xB6 +#define HIGHLIGHTING 0x87 +#define IBM_AUXILIARY_DEVICE 0x9E +#define IMAGE 0x82 +#define IMPLICIT_PARTITION 0xA6 +#define IOCA_AUXILIARY_DEVICE 0xAA +#define LINE_TYPE 0xB2 +#define MSR_CONTROL 0x8B +#define QNULL 0xFF +#define OEM_AUXILIARY_DEVICE 0x8F +#define PAPER_FEED_TECHNIQUES 0xA7 +#define PARTITION_CHARACTERISTICS 0x8E +#define PORT 0xB3 +#define PROCEDURE 0xB1 +#define PRODUCT_DEFINED_DATA_STREAM 0x9C +#define REPLY_MODES 0x88 +#define RPQ_NAMES 0xA1 +#define QSAVE_OR_RESTORE_FORMAT 0x92 +#define SEGMENT 0xB0 +#define SETTABLE_PRINTER_CHARACTERISTICS 0xA9 +#define STORAGE_POOLS 0x96 +#define SUMMARY 0x80 +#define TEXT_PARTITIONS 0x83 +#define QTRANSPARENCY 0xA8 +#define USABLE_AREA 0x81 +#define T5250_IPDS 0x9A + + +static const value_string vals_query_replies[] = { + { ALPHANUMERIC_PARTITIONS , "Alphanumeric Partitions"}, + { AUXILIARY_DEVICE , "Auxiliary Device"}, + { QBEGIN_OR_END_OF_FILE , "Begin/End of File"}, + { CHARACTER_SETS , "Character Sets"}, + { COLOR , "Color"}, + { COOPERATIVE_PROCESSING_REQUESTOR , "Cooperative Processing Requestor"}, + { DATA_CHAINING , "Data Chaining"}, + { DATA_STREAMS , "Data Streams"}, + { DBCS_ASIA , "DBCS-Asia"}, + { DEVICE_CHARACTERISTICS , "Device Characteristics"}, + { DISTRIBUTED_DATA_MANAGEMENT , "Distributed Data Management"}, + { DOCUMENT_INTERCHANGE_ARCHITECTURE , "Document Interchange Architecture"}, + { EXTENDED_DRAWING_ROUTINE , "Extended Drawing Routine"}, + { QFIELD_OUTLINING , "Field Outlining"}, + { QFIELD_VALIDATION , "Field Validation"}, + { FORMAT_PRESENTATION , "Format Presentation"}, + { FORMAT_STORAGE_AUXILIARY_DEVICE , "Format Storage Auxiliary Device"}, + { GRAPHIC_COLOR , "Graphic Color"}, + { GRAPHIC_SYMBOL_SETS , "Graphic Symbol Sets"}, + { HIGHLIGHTING , "Highlighting"}, + { IBM_AUXILIARY_DEVICE , "IBM Auxiliary Device"}, + { IMAGE , "Image"}, + { IMPLICIT_PARTITION , "Implicit Partition"}, + { IOCA_AUXILIARY_DEVICE , "IOCA Auxiliary Device"}, + { LINE_TYPE , "Line Type"}, + { MSR_CONTROL , "MSR Control"}, + { QNULL , "Null"}, + { OEM_AUXILIARY_DEVICE , "OEM Auxiliary Device"}, + { PAPER_FEED_TECHNIQUES , "Paper Feed Techniques"}, + { PARTITION_CHARACTERISTICS , "Partition Characteristics"}, + { PORT , "Port"}, + { PROCEDURE , "Procedure"}, + { PRODUCT_DEFINED_DATA_STREAM , "Product Defined Data Stream"}, + { REPLY_MODES , "Reply Modes"}, + { RPQ_NAMES , "RPQ Names"}, + { QSAVE_OR_RESTORE_FORMAT , "Save/Restore Format"}, + { SEGMENT , "Segment"}, + { SETTABLE_PRINTER_CHARACTERISTICS , "Settable Printer Characteristics"}, + { STORAGE_POOLS , "Storage Pools"}, + { SUMMARY , "Summary"}, + { TEXT_PARTITIONS , "Text Partitions"}, + { QTRANSPARENCY , "Transparency"}, + { USABLE_AREA , "Usable Area"}, + { T5250_IPDS , "5250 IPDS."}, + { 0x00, NULL } +}; + +/* 6.9 Query Reply Alphanumeric Partitions */ + +#define VERTWIN 0x80 +#define HORWIN 0x40 +#define APRES1 0x20 +#define APA_FLG 0x10 +#define PROT 0x08 +#define LCOPY 0x04 +#define MODPART 0x02 +#define APRES2 0x01 + +/* 6.12 - Query Reply (Character Sets) */ +#define ALT 0x80 +#define MULTID 0x40 +#define LOADABLE 0x20 +#define EXT 0x10 +#define MS 0x08 +#define CH2 0x04 +#define GF 0x02 +#define CSRES 0x01 + +#define CSRES2 0x80 +#define PSCS 0x40 +#define CSRES3 0x20 +#define CF 0x10 +#define CSRES4 0x08 +#define CSRES5 0x04 +#define GCSRES6 0x02 +#define CSRES7 0x01 + + +/* 6.16 Query Reply (Data Streams) */ +#define SCS 0x00 +#define DCAL2 0x01 +#define IPDS 0x02 + +static const value_string vals_data_streams[] = { + { SCS , "SCS Base Data Stream with extensions as specified in the BIND request and Device Characteristics Query Reply structured field"}, + { DCAL2, "Document Content Architecture Level 2"}, + { IPDS , "IPDS as defined in related documentation"}, + { 0x00, NULL } +}; + +/* 6.51 Query Reply Usable Area */ +#define UA_RESERVED1 0x80 +#define PAGE_PRINTER 0x40 +#define UA_RESERVED2 0x20 +#define HARD_COPY 0x10 + +#define UA_RESERVED3 0x00 +#define TWELVE_FOURTEEN_BIT_ADDRESSING 0x01 +#define UA_RESERVED4 0x02 +#define TWELVE_FOURTEEN_SXTN_BIT_ADDRESSING 0x03 +#define UNMAPPED 0x0F + +static const value_string vals_usable_area_flags1[] = { + { UA_RESERVED3 , "RESERVED "}, + { TWELVE_FOURTEEN_BIT_ADDRESSING , "TWELVE FOURTEEN BIT ADDRESSING"}, + { UA_RESERVED4 , "RESERVED"}, + { TWELVE_FOURTEEN_SXTN_BIT_ADDRESSING , "TWELVE FOURTEEN SXTN BIT ADDRESSING"}, + { UNMAPPED , "UNMAPPED"}, + { 0x00, NULL } +}; + +#define VARIABLE_CELLS 0x10 +#define CHARACTERS 0x20 +#define CELL_UNITS 0x40 + +#define INCHES 0x00 +#define MM 0x01 + +static const value_string vals_usable_area_uom[] = { + { INCHES , "Inches"}, + { MM , "Millimetres"}, + { 0x00, NULL } +}; + +/* 6.42 - Reply Modes */ + +#define FIELD_MODE 0x00 +#define EXTENDED_FIELD_MODE 0x01 +#define CHARACTER_MODE 0x02 + +static const value_string vals_modes[] = { + { FIELD_MODE , "Field Mode"}, + { EXTENDED_FIELD_MODE, "Extended Field Mode"}, + { CHARACTER_MODE , "Character Mode"}, + { 0x00, NULL } +}; + +/* 6.19 - Query Reply (Distributed Data Management) */ +#define DDM_COPY_SUBSET_1 0x01 + +static const value_string vals_ddm[] = { + { DDM_COPY_SUBSET_1 , "DDM Copy Subset 1"}, + { 0x00, NULL } +}; + +/* 6.20 - Query Reply (Document Interchange Architecture) */ +#define FILE_SERVER 0x01 +#define FILE_REQ 0x02 +#define FILE_SERVER_REQ 0x03 + +static const value_string vals_dia[] = { + { FILE_SERVER , "File Server"}, + { FILE_REQ , "File Requestor"}, + { FILE_SERVER_REQ , "Both File Server and File Requestor"}, + { 0x00, NULL } +}; + +/* 6.31 - Query Reply (Implicit Partitions) */ +#define DISPLAY 0x01 +#define PRINTER 0x02 +#define CHARACTER 0x03 + +static const value_string vals_ip[] = { + { DISPLAY , "Display Devices"}, + { PRINTER , "Printer Devices"}, + { CHARACTER , "Character Devices"}, + { 0x00, NULL } +}; + +/* 6.41 - Query Reply (Product Defined Data Streams) */ +#define GRAPH5080 0x01 +#define WHIPAPI 0x02 + +static const value_string vals_pdds_refid[] = { + { GRAPH5080 , "Supports the 5080 Graphics System"}, + { WHIPAPI , "Supports the WHIP API data stream"}, + { 0x00, NULL } +}; + +#define HFGD 0x01 +#define RS232 0x02 + +static const value_string vals_pdds_ssid[] = { + { HFGD , "5080 HFGD Graphics Subset"}, + { RS232 , "5080 RS232 Ports Subset"}, + { 0x00, NULL } +}; + +/* 6.47 - Query Reply (Storage Pools) */ +#define SEGMENT1 0x0001 +#define PROCEDURE1 0x0002 +#define EXTENDED_DRAWING 0x0003 +#define DATA_UNIT 0x0004 +#define TEMPORARY 0x0005 +#define LINE_TYPE1 0x0006 +#define SYMBOL_SET 0x0007 + +static const value_string vals_objlist[] = { + { SEGMENT1 , "Segment"}, + { PROCEDURE1 , "Procedure"}, + { EXTENDED_DRAWING , "Extended drawing routine"}, + { DATA_UNIT , "Data unit"}, + { TEMPORARY , "Temporary"}, + { LINE_TYPE1 , "Line type"}, + { SYMBOL_SET , "Symbol set"}, + { 0x00, NULL } +}; + +/* TN5250 Header - Data Type */ +#define TN5250_5250_DATA 0x00 +#define TN5250_BIND_IMAGE 0x03 +#define TN5250_NVT_DATA 0x05 +#define TN5250_REQUEST 0x06 +#define TN5250_RESPONSE 0x02 +#define TN5250_SCS_DATA 0x01 +#define TN5250_SSCP_LU_DATA 0x07 +#define TN5250_UNBIND 0x04 + +static const value_string vals_tn5250_header_data_types[] = { + { TN5250_5250_DATA , "5250_DATA"}, + { TN5250_BIND_IMAGE , "BIND_IMAGE"}, + { TN5250_NVT_DATA , "NVT_DATA"}, + { TN5250_REQUEST , "REQUEST"}, + { TN5250_RESPONSE , "RESPONSE"}, + { TN5250_SCS_DATA , "SCS_DATA"}, + { TN5250_SSCP_LU_DATA, "SSCP_LU_DATA"}, + { TN5250_UNBIND , "UNBIND"}, + { 0x00, NULL } +}; + + +/* TN5250 Header - Record Type */ +#define GDS 0x12A0 + +static const value_string vals_tn5250_sna_record_type[] = { + { GDS , "General Data Stream"}, + { 0x00, NULL } +}; + +/* TN5250 Header - Operation Code */ +#define NO_OPERATION 0x00 +#define INVITE_OPERATION 0x01 +#define OUTPUT_ONLY 0x02 +#define PUT/GET_OPERATION 0x03 +#define SAVE_SCREEN_OPERATION 0x04 +#define RESTORE_SCREEN_OPERATION 0x05 +#define READ_IMMEDIATE_OPERATION 0x06 +#define RESERVED 0x07 +#define READ_SCREEN_OPERATION 0x08 +#define RESERVED 0x09 +#define CANCEL_INVITE_OPERATION 0x0A +#define TURN_ON_MESSAGE_LIGHT 0x0B +#define TURN_OFF_MESSAGE_LIGHT 0x0C + +static const value_string vals_tn5250_header_operation_code[] = { + { NO_OPERATION , "No Operation"}, + { INVITE_OPERATION , "Invite Operation"}, + { OUTPUT_ONLY , "Output Only"}, + { PUT/GET_OPERATION , "Put/Get Operation"}, + { SAVE_SCREEN_OPERATION , "Save Screen Operation"}, + { RESTORE_SCREEN_OPERATION, "Restore Screen Operation"}, + { READ_IMMEDIATE_OPERATION, "Read Immediate Operation"}, + { RESERVED , "Reserved"}, + { READ_SCREEN_OPERATION , "Read Screen Operation"}, + { RESERVED , "Reserved"}, + { CANCEL_INVITE_OPERATION , "Cancel Invite Operation"}, + { TURN_ON_MESSAGE_LIGHT , "Turn On Message Light"}, + { TURN_OFF_MESSAGE_LIGHT , "Turn Off Message Light"}, + { 0x00, NULL } +}; + +/* TN5250 Header _ Response Flags - Data Type Response */ +#define TN5250_POSITIVE_RESPONSE 0x00 +#define TN5250_NEGATIVE_RESPONSE 0x01 + +static const value_string vals_tn5250_header_response_flags_response[] = { + { TN5250_POSITIVE_RESPONSE, "POSITIVE-RESPONSE"}, + { TN5250_NEGATIVE_RESPONSE, "NEGATIVE-RESPONSE"}, + { 0x00, NULL } +}; + + +static const value_string vals_tn5250_header_error_codes[] = { + { 0x0000, "Help key not allowed."}, + { 0x0001, "Keyboard overrun."}, + { 0x0002, "Incorrect scan code."}, + { 0x0003, "Command or PF key not valid."}, + { 0x0004, "Data not allowed in this field."}, + { 0x0005, "Cursor in protected area of display."}, + { 0x0006, "Key following Sys Req Key is not valid."}, + { 0x0007, "Mandatory entry field; you must enter data."}, + { 0x0008, "This field must have alphabetic characters."}, + { 0x0009, "This field must have numeric characters."}, + { 0x0010, "Only characters 0 through 9 allowed."}, + { 0x0011, "You tried to enter data into the last position of a signed numeric field."}, + { 0x0012, "Insert mode; no room to insert data."}, + { 0x0013, "Insert mode; only data keys permitted."}, + { 0x0014, "Must fill field to exit."}, + { 0x0015, "Modulo 10 or 11 check digit error. You entered data into a self-check field, and the number you entered and the check digit do not compare."}, + { 0x0016, "Field- not valid in this field."}, + { 0x0017, "Mandatory-fill field; key pressed is not valid."}, + { 0x0018, "Key used to exit this field not valid."}, + { 0x0019, "Dup or Field Mark not permitted in this field."}, + { 0x0020, "Function key not valid for right-adjust field."}, + { 0x0021, "Must enter data in mandatory entry field."}, + { 0x0022, "An AS/400 system error occurred. The status of the current field is not known. This error can occur during an insert or delete operation."}, + { 0x0023, "Hexadecimal mode; entry not valid."}, + { 0x0024, "Decimal field; entry not valid."}, + { 0x0026, "Field- entry not allowed."}, + { 0x0027, "Cannot use undefined key."}, + { 0x0029, "Diacritic character not valid."}, + { 0x0031, "Data buffer overflow."}, + { 0x0032, "MSR error."}, + { 0x0033, "MSR data not authorized."}, + { 0x0034, "Magnetic stripe reader (MSR) data exceeds length of field."}, + { 0x0035, "MSR error."}, + { 0x0036, "Cursor select not allowed in field exit required state."}, + { 0x0037, "You pressed Cursor Select in a non-selectable field."}, + { 0x0038, "Light pen and magnetic stripe reader (MSR) not allowed."}, + { 0x0040, "The modem or data circuit-terminating equipment (DCE) is not ready for one of the following reasons:"}, + { 0x0041, "X.25: Idle condition has been detected. The receive line was idle for 15 or more contiguous bit-times."}, + { 0x0042, "The receive clock signal is not being received from the modem or data circuit-terminating equipment (DCE)."}, + { 0x0043, "The 5494 attempted to disconnect from the line, but the data set ready (DSR) signal was not deactivated by the modem or DCE."}, + { 0x0044, "Switched lines: This error indicates that no valid data has been received for 30 seconds. The 5494 disconnected the line."}, + { 0x0045, "X.25: The data circuit-terminating equipment (DCE) will not activate. Either a Disconnect mode (DM) or a Disconnect (DISC) command was received during the link setup sequence."}, + { 0x0046, "X.25 or LAN: Frame reject received. The 5494 received a frame reject (FRMR) from the network, indicating that an error was detected in the last frame transmitted."}, + { 0x0047, "X.25 or LAN: An unexpected Disconnect mode (DM) or a Disconnect (DISC) command was received while in information transfer state."}, + { 0x0048, "X.25: An unexpected unnumbered acknowledgment (UA) frame was received."}, + { 0x0049, "LAN: A set asynchronous balance mode extended (SABME) was received while the 5494 was in information transfer state."}, + { 0x0050, "Error in ready-for-sending (RFS) signal, also known as the clear-to-send (CTS) signal, received from the modem or data circuit-terminating equipment (DCE). This error is posted when one of the following has occurred:"}, + { 0x0051, "The transmit clock from the modem or data circuit-terminating equipment (DCE) failed during a transmit operation."}, + { 0x0052, "The link adapter hardware failed to complete a transmit operation within 30 seconds, but no transmit clock or other modem or data circuit-terminating equipment (DCE) signal failure was detected."}, + { 0x0053, "X.25: The retry count has expired. No acknowledgment of a transmission was received within the allowed timeout. Timeout retry count (N2) and retry interval (T1) are specified in the 5494 configuration."}, + { 0x0054, "Frame reject (FRMR) sent. The 5494 sent a link-level FRMR response to the AS/400 system after receiving a data link control (DLC) or link access protocol balanced (LAPB) command that is not valid. Sense bytes S1, S2, and S3 preserve the contents of the FRMR I-field."}, + { 0x0055, "The 5494 ran a cable wrap test and determined that the communication cable is not attached to the 5494."}, + { 0x0056, "The link between the AS/400 system and the 5494 was lost. A bridge failure occurred, the AS/400 system has varied off line, or a node in an SNA Subarea network has failed."}, + { 0x0060, "Ideographic support SRC: You attempted to enter alphanumeric data into a field that accepts only double-byte data characters."}, + { 0x0061, "Ideographic support SRC: You attempted to enter a double-byte character into a field that accepts only alphanumeric data."}, + { 0x0062, "You attempted to change the data type, but the cursor is not in an open field or in the first position of an ideographic either field."}, + { 0x0063, "You entered an ideographic character that is not valid while operating in Alternate Entry mode."}, + { 0x0064, "You pressed a key that is not valid for the current keyboard mode."}, + { 0x0065, "The cursor is positioned in a column reserved for shift-out or shift-in characters."}, + { 0x0066, "Repeat key not valid. The cursor is positioned under a shift character or attribute character, or at the first valid entry character position of an input field. Only data characters can be repeated at these positions."}, + { 0x0067, "The workstation extension character RAM is full. Any additional extension characters display as special default characters."}, + { 0x0068, "The output data stream to the 5494 is not valid for extension characters. Any additional extension characters display as special default characters."}, + { 0x0069, "Ideographic support SRC: The output data stream to the 5494 contains extension characters that are not valid or are undefined. Any additional extension characters display as special default characters."}, + { 0x0070, "An error occurred during the word spill function or the carriage return function."}, + { 0x0071, "You attempted a start copy, move, or delete text operation while one of the previous operations was already in progress."}, + { 0x0072, "The key pressed is not valid when the cursor is in the current position."}, + { 0x0073, "An attempt was made to delete or replace an instruction or format change when the general prompt function was not active."}, + { 0x0074, "A key was pressed that is not valid when using the general prompt function."}, + { 0x0075, "The find function failed to find the keyed characters."}, + { 0x0076, "The insert function failed because the AS/400 system has not processed the text on the screen."}, + { 0x0077, "You either pressed a function key that is not valid at this time or tried to use a 5250 keyboard function while in word-processing mode."}, + { 0x0078, "The required scale line is not defined for your workstation. There is an error in the application program."}, + { 0x0081, "Too many workstations are attached to the 5494. The 5494 with LAN adapter installed allows a maximum of 80 devices."}, + { 0x0082, "Keyboard function is not valid within a selection field. These invalid functions include Dup, Erase EOF, and Field Mark."}, + { 0x0083, "A selection character is not valid. The numeric or mnemonic character you entered is not associated with any of the choices defined within the current selection field."}, + { 0x0084, "An attempt has been made to select an unavailable selection field."}, + { 0x0087, "X.25: A flow control entry error has occurred. The 5494 configuration settings for Flow Control Negotiation and Manual Options Allowed are not compatible. If the configuration setting for Flow Control Negotiation is permitted, then Manual Options must be allowed."}, + { 0x0089, "One or more fields required for the operation of the 5494 are blank. When you press Enter, the 5494 checks for blank fields and moves the cursor to the first blank."}, + { 0x008A, "One or more fields contain an embedded blank. When you press Enter, the 5494 checks for embedded blanks and moves the cursor to the first embedded blank."}, + { 0x008B, "Too many different keyboard codes have been used. A maximum of 4 different keyboard codes can be selected (the master country and 3 others)."}, + { 0x008D, "Printer port and station values are not valid. Valid ports for the Twinaxial Expansion Kit are 4-7. Valid stations are 0-7."}, + { 0x008E, "One or more fields contain an insufficient number of characters. The cursor is positioned in the field that contains an insufficient number of characters."}, + { 0x008F, "One or more fields contain a value that is outside the valid range. The cursor is placed under the first character of the field with a value that is out of range."}, + { 0x0091, "Reverse and Close keys are not supported in a Word Wrap entry field."}, + { 0x0092, "The reverse key is not supported on a display which is configured for shared addressing."}, + { 0x0097, "A test request function is not supported by the AS/400 system."}, + { 0x0098, "Undefined hardware error."}, + { 0x0099, "A key requiring AS/400 system action was pressed, but one of the following has occurred:"}, + { 0x009A, "An invalid password has been entered three times in an attempt to access concurrent diagnostics from a PWS."}, + { 0x0170, "A problem with an attached workstation has been detected. The workstation failed to detect the end of a printer definition table (PDT). Sense data is 00."}, + { 0x0172, "A problem with an attached workstation has been detected. The workstation detected invalid data in a printer definition table (PDT) sent to it from the AS/400 system. The sense data is 00ccxxyyyyyyyy, where cc is the command code of the definition containing invalid data, xx, is the offset from the command to invalid data in bytes, and yyyyyyyy is additional error data."}, + { 0x0173, "A problem with an attached workstation has been detected. The workstation received a printer definition table (PDT) that was larger than its maximum size. Sense data is 00xxxxyyyy, where xxxx is the workstation's maximum PDT size, and yyyy was the size of the PDT sent to the display by the AS/400 system."}, + { 0x0176, "A problem with an attached workstation has been detected. The workstation received a microcode correction file from the AS/400 system that was in error. The sense data defines the error as follows:"}, + { 0x0177, "A problem with an attached workstation has been detected. The workstation received a font file from the AS/400 system that was in error. Sense data defines the error as follows:"}, + { 0x0000, NULL } +}; + + + +/* + * Data structure attached to a conversation, giving authentication + * information from a bind request. + * We keep a linked list of them, so that we can free up all the + * authentication mechanism strings. + */ +typedef struct tn5250_conv_info_t { + struct tn5250_conv_info_t *next; + address outbound_addr; + guint32 outbound_port; + address inbound_addr; + guint32 inbound_port; + gint extended; +} tn5250_conv_info_t; + +void add_tn5250_conversation(packet_info *pinfo _U_, int tn5250e); +int find_tn5250_conversation(packet_info *pinfo _U_); +#endif