/* * Dissector that returns: * * The amount of data in the protocol's PDU, if it was able to * dissect all the data; * * 0, if the tvbuff doesn't contain a PDU for that protocol; * * The negative of the amount of additional data needed, if * we need more data (e.g., from subsequent TCP segments) to * dissect the entire PDU. */ static int dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint tvb_size = 0; proto_tree *ccn_tree; proto_item *ti = NULL; const unsigned char *ccnb; struct ccn_skeleton_decoder skel_decoder; struct ccn_skeleton_decoder *sd; struct ccn_charbuf *c; int packet_type = 0; int packet_type_length = 0; /* a couple of basic checks to rule out packets that are definitely not ours */ tvb_size = tvb_length(tvb); if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0) return (0); sd = &skel_decoder; memset(sd, 0, sizeof(*sd)); sd->state |= CCN_DSTATE_PAUSE; ccnb = ep_tvb_memdup(tvb, 0, tvb_size); ccn_skeleton_decode(sd, ccnb, tvb_size); if (sd->state < 0) return (0); if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) { packet_type = sd->numval; packet_type_length = sd->index; } else { return (0); } memset(sd, 0, sizeof(*sd)); ccn_skeleton_decode(sd, ccnb, tvb_size); if (!CCN_FINAL_DSTATE(sd->state)) { pinfo->desegment_offset = 0; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return (-1); /* what should this be? */ } /* Make it visible that we're taking this packet */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN"); } /* Clear out stuff in the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_clear(pinfo->cinfo, COL_INFO); } c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, tvb_size, 1); /* Add the packet type and CCN URI to the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x")); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c)); } if (tree == NULL) { ccn_charbuf_destroy(&c); return (sd->index); } ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1, "Content-centric Networking Protocol, %s, %s", val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"), ccn_charbuf_as_string(c)); ccn_tree = proto_item_add_subtree(ti, ett_ccn); ccn_charbuf_destroy(&c); ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type); switch (packet_type) { case CCN_DTAG_ContentObject: if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; case CCN_DTAG_Interest: if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; } return (sd->index); }
static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, mq_parm_t* p_mq_parm) { gint offset = 0; gboolean bLittleEndian; bLittleEndian = ((p_mq_parm->mq_cur_ccsid.encod & MQ_MQENC_INTEGER_MASK) == MQ_MQENC_INTEGER_REVERSED) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN; if (tvb_length(tvb) >= 36) { gint iSizeMQCFH = 36; guint32 iCommand = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian); if (tree) { proto_item *ti; proto_tree *mq_tree; proto_tree *mqroot_tree; char sTmp[256]; guint32 uCnt; guint32 uTyp; guint32 uCmd; guint32 uCC; guint32 uRC; uTyp = tvb_get_guint32_endian(tvb, offset , bLittleEndian); uCmd = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian); uCC = tvb_get_guint32_endian(tvb, offset + 24, bLittleEndian); uRC = tvb_get_guint32_endian(tvb, offset + 28, bLittleEndian); uCnt = tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian); if (uCC || uRC) { g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d) CC(%d-%s) RC(%d-%s)", MQ_TEXT_CFH, uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"), uCmd, val_to_str_const(uCmd, GET_VALSV(mqcmd), "Unknown"), uCnt, uCC, val_to_str_const(uCC, GET_VALSV(mqcc), "Unknown"), uRC, val_to_str_const(uRC, GET_VALSV(mqrc), "Unknown")); } else { g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d)", MQ_TEXT_CFH, uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"), uCmd, val_to_str_const(uCmd, GET_VALSV(mqcmd), "Unknown"), uCnt); } ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, ENC_NA); proto_item_append_text(ti, " (%s)", val_to_str(iCommand, GET_VALSV(mqcmd), "Unknown (0x%02x)")); mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf); ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMQCFH, "%s", sTmp); mq_tree = proto_item_add_subtree(ti, ett_mqpcf_cfh); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type , tvb, offset + 0, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version , tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control , tvb, offset + 20, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason , tvb, offset + 28, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian); dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian, TRUE); } } }
/* * Dissect DISP PDUs inside a ROS PDUs */ static void dissect_disp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; int old_offset; proto_item *item=NULL; proto_tree *tree=NULL; int (*disp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL; char *disp_op_name; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* do we have operation information from the ROS dissector? */ if( !pinfo->private_data ){ if(parent_tree){ proto_tree_add_text(parent_tree, tvb, offset, -1, "Internal error: can't get operation information from ROS dissector."); } return ; } else { session = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) ); } if(parent_tree){ item = proto_tree_add_item(parent_tree, proto_disp, tvb, 0, -1, FALSE); tree = proto_item_add_subtree(item, ett_disp); } col_set_str(pinfo->cinfo, COL_PROTOCOL, "DISP"); col_clear(pinfo->cinfo, COL_INFO); switch(session->ros_op & ROS_OP_MASK) { case (ROS_OP_BIND | ROS_OP_ARGUMENT): /* BindInvoke */ disp_dissector = dissect_disp_DSAShadowBindArgument; disp_op_name = "Shadow-Bind-Argument"; break; case (ROS_OP_BIND | ROS_OP_RESULT): /* BindResult */ disp_dissector = dissect_disp_DSAShadowBindResult; disp_op_name = "Shadow-Bind-Result"; break; case (ROS_OP_BIND | ROS_OP_ERROR): /* BindError */ disp_dissector = dissect_disp_DSAShadowBindError; disp_op_name = "Shadow-Bind-Error"; break; case (ROS_OP_INVOKE | ROS_OP_ARGUMENT): /* Invoke Argument */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* requestShadowUpdate */ disp_dissector = dissect_disp_RequestShadowUpdateArgument; disp_op_name = "Request-Shadow-Update-Argument"; break; case 2: /* updateShadow*/ disp_dissector = dissect_disp_UpdateShadowArgument; disp_op_name = "Update-Shadow-Argument"; break; case 3: /* coordinateShadowUpdate */ disp_dissector = dissect_disp_CoordinateShadowUpdateArgument; disp_op_name = "Coordinate-Shadow-Update-Argument"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; case (ROS_OP_INVOKE | ROS_OP_RESULT): /* Return Result */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* requestShadowUpdate */ disp_dissector = dissect_disp_RequestShadowUpdateResult; disp_op_name = "Request-Shadow-Result"; break; case 2: /* updateShadow */ disp_dissector = dissect_disp_UpdateShadowResult; disp_op_name = "Update-Shadow-Result"; break; case 3: /* coordinateShadowUpdate */ disp_dissector = dissect_disp_CoordinateShadowUpdateResult; disp_op_name = "Coordinate-Shadow-Update-Result"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; case (ROS_OP_INVOKE | ROS_OP_ERROR): /* Return Error */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* shadowError */ disp_dissector = dissect_disp_ShadowError; disp_op_name = "Shadow-Error"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP errcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP PDU"); return; } if(disp_dissector) { col_set_str(pinfo->cinfo, COL_INFO, disp_op_name); while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=(*disp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1); if(offset == old_offset){ proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DISP PDU"); offset = tvb_length(tvb); break; } } } }
static void dissect_rtacser_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *rtacser_item, *ts_item, *cl_item, *data_payload; proto_tree *rtacser_tree, *cl_tree; int offset=0, len=0; guint event_type; guint32 timestamp1, timestamp2; gboolean cts, dcd, dsr, rts, dtr, ring, mbok; tvbuff_t *payload_tvb; len = RTACSER_HEADER_LEN; /* Make entries in Protocol column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTAC Serial"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { rtacser_item = proto_tree_add_protocol_format(tree, proto_rtacser, tvb, 0, len, "RTAC Serial Line"); rtacser_tree = proto_item_add_subtree(rtacser_item, ett_rtacser); /* Time-stamp is stored as 2 x 32-bit unsigned integers, the left and right-hand side of the decimal point respectively */ /* The format mirrors the timeval struct - absolute Epoch time (seconds since 1/1/1970) with an added microsecond component */ timestamp1 = tvb_get_ntohl(tvb, offset); timestamp2 = tvb_get_ntohl(tvb, offset+4); ts_item = proto_tree_add_item(rtacser_tree, hf_rtacser_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN); proto_item_set_text(ts_item, "Arrived At Time: %u.%u" , timestamp1, timestamp2); offset += 8; /* Set INFO column with RTAC Serial Event Type */ event_type = tvb_get_guint8(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "%-21s", val_to_str_const(event_type, rtacser_eventtype_vals, "Unknown Type")); /* Add event type to tree */ proto_tree_add_item(rtacser_tree, hf_rtacser_event_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Retrieve EIA-232 serial control line states */ cts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_CTS; dcd = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DCD; dsr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DSR; rts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RTS; dtr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DTR; ring = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RING; mbok = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_MBOK; cl_item = proto_tree_add_text(rtacser_tree, tvb, offset, 1, "Control Lines"); cl_tree = proto_item_add_subtree(cl_item, ett_rtacser_cl); /* Add UART Control Line information to INFO column */ col_append_str(pinfo->cinfo, COL_INFO, " ( "); (cts) ? col_append_str(pinfo->cinfo, COL_INFO, "CTS") : col_append_str(pinfo->cinfo, COL_INFO, "/CTS"); (dcd) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DCD") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DCD"); (dsr) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DSR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DSR"); (rts) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RTS") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RTS"); (dtr) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DTR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DTR"); (ring) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RING") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RING"); (mbok) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "MBOK") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/MBOK"); col_append_str(pinfo->cinfo, COL_INFO, " )"); /* Add UART Control Line information to tree */ proto_item_append_text(cl_item, " ("); (cts) ? proto_item_append_text(cl_item, "CTS, ") : proto_item_append_text(cl_item, "/CTS, "); (dcd) ? proto_item_append_text(cl_item, "DCD, ") : proto_item_append_text(cl_item, "/DCD, "); (dsr) ? proto_item_append_text(cl_item, "DSR, ") : proto_item_append_text(cl_item, "/DSR, "); (rts) ? proto_item_append_text(cl_item, "RTS, ") : proto_item_append_text(cl_item, "/RTS, "); (dtr) ? proto_item_append_text(cl_item, "DTR, ") : proto_item_append_text(cl_item, "/DTR, "); (ring) ? proto_item_append_text(cl_item, "RING, ") : proto_item_append_text(cl_item, "/RING, "); (mbok) ? proto_item_append_text(cl_item, "MBOK") : proto_item_append_text(cl_item, "/MBOK"); proto_item_append_text(cl_item, ")"); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_cts, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dcd, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dsr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_rts, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dtr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_ring, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_mbok, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* 2-byte footer */ proto_tree_add_item(rtacser_tree, hf_rtacser_footer, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* If no payload dissector has been selected, indicate to the user the preferences options */ if ((tvb_reported_length_remaining(tvb, offset) > 0) && (global_rtacser_payload_proto == RTACSER_PAYLOAD_NONE)) { data_payload = proto_tree_add_item(tree, hf_rtacser_data, tvb, offset, -1, ENC_NA); proto_item_set_text(data_payload,"Payload Protocol not selected. Check 'Preferences-> Protocols-> RTAC Serial' for options"); return; } } /* tree */ /* Determine correct message type and call appropriate dissector */ if (tvb_reported_length_remaining(tvb, RTACSER_HEADER_LEN) > 0) { switch (global_rtacser_payload_proto) { case RTACSER_PAYLOAD_SELFM: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(selfm_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_DNP3: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(dnp3_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_MODBUS: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(modbus_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_SYNPHASOR: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(synphasor_handle, payload_tvb, pinfo, tree); break; default: break; } } }
dissect_lge_monitor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { int offset = 0; guint32 lge_monitor_proto_id; tvbuff_t* next_tvb = NULL; proto_tree* header_tree; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *lge_monitor_tree; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LGE Monitor"); ti = proto_tree_add_item(tree, proto_lge_monitor, tvb, 0, LGEMON_PROTO_HEADER_LENGTH, ENC_NA); lge_monitor_tree = proto_item_add_subtree(ti, ett_lge_monitor); header_tree = proto_tree_add_subtree(lge_monitor_tree, tvb, offset, LGEMON_PROTO_HEADER_LENGTH, ett_lge_header, NULL, "LGE Monitor PDU"); proto_tree_add_item(header_tree, hf_lge_monitor_dir, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; lge_monitor_proto_id = tvb_get_ntohl(tvb,offset); proto_tree_add_item(header_tree, hf_lge_monitor_prot, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(header_tree, hf_lge_monitor_length, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; next_tvb = tvb_new_subset_remaining(tvb, offset); switch (lge_monitor_proto_id){ case 0: /* MTP3 */ call_dissector(mtp3_handle, next_tvb, pinfo, tree);
static void dissect_status (packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 flags) { proto_item *item = NULL; proto_tree *tree = NULL; if (parent_tree) { item=proto_tree_add_uint(parent_tree, hf_sbccs_dib_status, tvb, offset, 1, flags); tree=proto_item_add_subtree(item, ett_sbccs_dib_status); } proto_tree_add_boolean(tree, hf_sbccs_dib_status_attention, tvb, offset, 1, flags); if (flags & 0x80) { proto_item_append_text(item, " Attention"); col_append_str(pinfo->cinfo, COL_INFO, " Attention"); } flags &= (~( 0x80 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_modifier, tvb, offset, 1, flags); if (flags & 0x40) { proto_item_append_text(item, " Status Modifier"); col_append_str(pinfo->cinfo, COL_INFO, " Status Modifier"); } flags &= (~( 0x40 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_cue, tvb, offset, 1, flags); if (flags & 0x20) { proto_item_append_text(item, " Control-Unit End"); col_append_str(pinfo->cinfo, COL_INFO, " Control-Unit End"); } flags &= (~( 0x20 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_busy, tvb, offset, 1, flags); if (flags & 0x10) { proto_item_append_text(item, " Busy"); col_append_str(pinfo->cinfo, COL_INFO, " Busy"); } flags &= (~( 0x10 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_channelend, tvb, offset, 1, flags); if (flags & 0x08) { proto_item_append_text(item, " Channel End"); col_append_str(pinfo->cinfo, COL_INFO, " Channel End"); } flags &= (~( 0x08 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_deviceend, tvb, offset, 1, flags); if (flags & 0x04) { proto_item_append_text(item, " Device End"); col_append_str(pinfo->cinfo, COL_INFO, " Device End"); } flags &= (~( 0x04 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_check, tvb, offset, 1, flags); if (flags & 0x02) { proto_item_append_text(item, " Unit Check"); col_append_str(pinfo->cinfo, COL_INFO, " Unit Check"); } flags &= (~( 0x02 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_exception, tvb, offset, 1, flags); if (flags & 0x01) { proto_item_append_text(item, " Unit Exception"); col_append_str(pinfo->cinfo, COL_INFO, " Unit Exception"); } flags &= (~( 0x01 )); }
/* Look for conversation info and display any setup info found */ void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Conversation and current data */ conversation_t *p_conv = NULL; struct _msrp_conversation_info *p_conv_data = NULL; /* Use existing packet data if available */ p_conv_data = p_get_proto_data(pinfo->fd, proto_msrp); if (!p_conv_data) { /* First time, get info from conversation */ p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src, PT_TCP, pinfo->destport, pinfo->srcport, 0); if (p_conv) { /* Look for data in conversation */ struct _msrp_conversation_info *p_conv_packet_data; p_conv_data = conversation_get_proto_data(p_conv, proto_msrp); if (p_conv_data) { /* Save this conversation info into packet info */ p_conv_packet_data = se_alloc(sizeof(struct _msrp_conversation_info)); if (!p_conv_packet_data) { return; } memcpy(p_conv_packet_data, p_conv_data, sizeof(struct _msrp_conversation_info)); p_add_proto_data(pinfo->fd, proto_msrp, p_conv_packet_data); } } } /* Create setup info subtree with summary info. */ if (p_conv_data && p_conv_data->setup_method_set) { proto_tree *msrp_setup_tree; proto_item *ti = proto_tree_add_string_format(tree, hf_msrp_setup, tvb, 0, 0, "", "Stream setup by %s (frame %u)", p_conv_data->setup_method, p_conv_data->setup_frame_number); PROTO_ITEM_SET_GENERATED(ti); msrp_setup_tree = proto_item_add_subtree(ti, ett_msrp_setup); if (msrp_setup_tree) { /* Add details into subtree */ proto_item* item = proto_tree_add_uint(msrp_setup_tree, hf_msrp_setup_frame, tvb, 0, 0, p_conv_data->setup_frame_number); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(msrp_setup_tree, hf_msrp_setup_method, tvb, 0, 0, p_conv_data->setup_method); PROTO_ITEM_SET_GENERATED(item); } } }
static void dissect_tns_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_tree *tns_tree) { proto_tree *data_tree = NULL, *ti; proto_item *hidden_item; int is_sns = 0; if ( tvb_bytes_exist(tvb, offset+2, 4) ) { if ( tvb_get_guint8(tvb, offset+2) == 0xDE && tvb_get_guint8(tvb, offset+3) == 0xAD && tvb_get_guint8(tvb, offset+4) == 0xBE && tvb_get_guint8(tvb, offset+5) == 0xEF ) { is_sns = 1; } } if ( tree ) { if ( is_sns ) { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Secure Network Services"); } else { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Data"); } data_tree = proto_item_add_subtree(ti, ett_tns_data); hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_data, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } if ( tree ) { proto_tree *df_tree = NULL; ti = proto_tree_add_item(data_tree, hf_tns_data_flag, tvb, offset, 2, ENC_BIG_ENDIAN); df_tree = proto_item_add_subtree(ti, ett_tns_data_flag); proto_tree_add_item(df_tree, hf_tns_data_flag_send, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_rc, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_c, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_more, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_eof, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_dic, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_rts, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_sntt, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( check_col(pinfo->cinfo, COL_INFO) ) { if ( is_sns ) { col_append_str(pinfo->cinfo, COL_INFO, ", SNS"); } else { col_append_str(pinfo->cinfo, COL_INFO, ", Data"); } } if ( data_tree ) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, data_tree); } return; }
static void dissect_tns_connect(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_tree *tns_tree) { proto_tree *connect_tree = NULL, *ti; proto_item *hidden_item; int cd_offset; int cd_len; int tns_offset = offset-8; if ( tree ) { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Connect"); connect_tree = proto_item_add_subtree(ti, ett_tns_connect); hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_connect, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } col_append_str(pinfo->cinfo, COL_INFO, ", Connect"); if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_version, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_compat_version, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree *sopt_tree = NULL; ti = proto_tree_add_item(connect_tree, hf_tns_service_options, tvb, offset, 2, ENC_BIG_ENDIAN); sopt_tree = proto_item_add_subtree(ti, ett_tns_sopt_flag); dissect_tns_service_options(tvb, offset, sopt_tree); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_sdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_max_tdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree *ntp_tree = NULL; ti = proto_tree_add_item(connect_tree, hf_tns_nt_proto_characteristics, tvb, offset, 2, ENC_BIG_ENDIAN); ntp_tree = proto_item_add_subtree(ti, ett_tns_ntp_flag); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_hangon, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_crel, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_tduio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_srun, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_dtest, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_cbio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_asio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_pio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_grant, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_handoff, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigpipe, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigurg, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_urgentio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_fdio, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_testop, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_line_turnaround, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_value_of_one, tvb, offset, 2, ENC_NA); } offset += 2; cd_len = tvb_get_ntohs(tvb, offset); if ( connect_tree ) { proto_tree_add_uint(connect_tree, hf_tns_connect_data_length, tvb, offset, 2, cd_len); } offset += 2; cd_offset = tvb_get_ntohs(tvb, offset); if ( connect_tree ) { proto_tree_add_uint(connect_tree, hf_tns_connect_data_offset, tvb, offset, 2, cd_offset); } offset += 2; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_connect_data_max, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; if ( connect_tree ) { proto_tree *cflag_tree = NULL; ti = proto_tree_add_item(connect_tree, hf_tns_connect_flags0, tvb, offset, 1, ENC_BIG_ENDIAN); cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag); dissect_tns_connect_flag(tvb, offset, cflag_tree); } offset += 1; if ( connect_tree ) { proto_tree *cflag_tree = NULL; ti = proto_tree_add_item(connect_tree, hf_tns_connect_flags1, tvb, offset, 1, ENC_BIG_ENDIAN); cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag); dissect_tns_connect_flag(tvb, offset, cflag_tree); } offset += 1; /* * XXX - sometimes it appears that this stuff isn't present * in the packet. */ if (offset + 16 <= tns_offset+cd_offset) { if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_trace_cf1, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_trace_cf2, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; if ( connect_tree ) { proto_tree_add_item(connect_tree, hf_tns_trace_cid, tvb, offset, 8, ENC_BIG_ENDIAN); } offset += 8; } if ( connect_tree && cd_len > 0) { proto_tree_add_item(connect_tree, hf_tns_connect_data, tvb, tns_offset+cd_offset, -1, ENC_ASCII|ENC_NA); } return; }
/* * Name: isis_dissect_isis_hello() * * Description: * This procedure rips apart the various types of ISIS hellos. L1H and * L2H's are identical for the most part, while the PTP hello has * a shorter header. * * Input: * tvbuff_t * : tvbuffer for packet data * proto_tree * : protocol display tree to add to. May be NULL. * int offset : our offset into packet data. * int : hello type, a la packet-isis.h ISIS_TYPE_* values * int : header length of packet. * int : length of IDs in packet. * * Output: * void, will modify proto_tree if not NULL. */ void isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hello_type, int header_length, int id_length) { proto_item *ti; proto_tree *hello_tree = NULL; int len; guint8 octet; const guint8 *source_id; guint16 pdu_length; const guint8 *lan_id; if (tree) { ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO"); hello_tree = proto_item_add_subtree(ti, ett_isis_hello); octet = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format(hello_tree, hf_isis_hello_circuit_reserved, tvb, offset, 1, octet, "Circuit type : %s, reserved(0x%02x == 0)", val_to_str(octet&ISIS_HELLO_CTYPE_MASK, isis_hello_circuit_type_vals, "Unknown (0x%x)"), octet&ISIS_HELLO_CT_RESERVED_MASK ); } offset += 1; if (tree) { source_id = tvb_get_ptr(tvb, offset, id_length); proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb, offset, id_length, source_id, "System-ID {Sender of PDU} : %s", print_system_id( source_id, id_length ) ); } if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) ); } offset += id_length; if (tree) { proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb, offset, 2, FALSE); } offset += 2; pdu_length = tvb_get_ntohs(tvb, offset); if (tree) { proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb, offset, 2, pdu_length); } offset += 2; if (hello_type == ISIS_TYPE_PTP_HELLO) { if (tree) { proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb, offset, 1, FALSE ); } offset += 1; } else { if (tree) { octet = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb, offset, 1, octet, "Priority : %d, reserved(0x%02x == 0)", octet&ISIS_HELLO_PRIORITY_MASK, octet&ISIS_HELLO_P_RESERVED_MASK ); } offset += 1; if (tree) { lan_id = tvb_get_ptr(tvb, offset, id_length+1); proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb, offset, id_length + 1, lan_id, "System-ID {Designated IS} : %s", print_system_id( lan_id, id_length + 1 ) ); } offset += id_length + 1; } len = pdu_length; len -= header_length; if (len < 0) { isis_dissect_unknown(tvb, tree, offset, "Packet header length %d went beyond packet", header_length ); return; } /* * Now, we need to decode our CLVs. We need to pass in * our list of valid ones! */ if (hello_type == ISIS_TYPE_L1_HELLO){ isis_dissect_clvs(tvb, hello_tree, offset, clv_l1_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } else if (hello_type == ISIS_TYPE_L2_HELLO) { isis_dissect_clvs(tvb, hello_tree, offset, clv_l2_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } else { isis_dissect_clvs(tvb, hello_tree, offset, clv_ptp_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } }
static void dissect_pw_cesopsn( tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = PWC_PACKET_PROPERTIES_T_INITIALIZER; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC5086: * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN * packet (defined as the size of the CESoPSN header + the payload size) * if it is less than 64 bytes, and MUST be set to zero otherwise. * Note: If fixed RTP header is used in the encapsulation, it is * considered part of the CESoPSN header.] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC5086's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } { guint8 cw_lm; cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/; if (NULL == try_val_to_str(cw_lm, vals_cw_lm)) { properties |= PWC_CW_SUSPECT_LM; } { guint8 l_bit, m_bits; l_bit = (cw_lm & 0x08) >> 3; m_bits = (cw_lm & 0x03) >> 0; if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/ ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ ) { if ((payload_size == 0) || ((payload_size % 8) != 0)) { properties |= PWC_PAY_SIZE_BAD; } } else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/ { /*allow any size of payload*/ } else /*reserved combinations*/ { /*allow any size of payload*/ } } } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } else if (properties & PWC_ANYOF_CW_SUSPECT) { col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, "); } col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } item3 = proto_tree_add_item(tree3, hf_cw_lm, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_SUSPECT_LM) { expert_add_info(pinfo, item3, &ei_cw_lm); } proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be 0 if CESoPSN packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (payload_size == 0) { if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error, "CESoPSN payload: none found. Size of payload must be <> 0"); } else { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded, "CESoPSN payload: omitted to conserve bandwidth"); } } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error, "CESoPSN packet payload size must be multiple of 8"); } tree2 = proto_item_add_subtree(item2, ett); call_dissector(data_handle, tvb, pinfo, tree2); item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
static void dissect_dtp_tlv(packet_info *pinfo, tvbuff_t *tvb, int offset, int length, proto_tree *tree, proto_item *ti, proto_item *tlv_length_item, guint8 type) { switch (type) { case DTP_TLV_DOMAIN: if (length <= 33) { /* VTP domain name is at most 32 bytes long and is null-terminated */ proto_item_append_text(ti, ": %s", tvb_format_text(tvb, offset, length - 1)); proto_tree_add_item(tree, hf_dtp_domain, tvb, offset, length, ENC_ASCII|ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_TRSTATUS: if (length == 1) { /* Value field length must be 1 byte */ proto_item * value_item = NULL; proto_tree * field_tree = NULL; guint8 trunk_status = tvb_get_guint8(tvb, offset); proto_item_append_text(ti, " (Operating/Administrative): %s/%s (0x%02x)", val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"), val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"), trunk_status); value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)", val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"), val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"), trunk_status); field_tree = proto_item_add_subtree(value_item, ett_dtp_status); proto_tree_add_item(field_tree, hf_dtp_tos, tvb, offset, length, ENC_NA); proto_tree_add_item(field_tree, hf_dtp_tas, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_TRTYPE: if (length == 1) { /* Value field length must be 1 byte */ proto_item * value_item = NULL; proto_tree * field_tree = NULL; guint8 trunk_type = tvb_get_guint8(tvb, offset); proto_item_append_text(ti, " (Operating/Administrative): %s/%s (0x%02x)", val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"), val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"), trunk_type); value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)", val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"), val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"), trunk_type); field_tree = proto_item_add_subtree(value_item, ett_dtp_type); proto_tree_add_item(field_tree, hf_dtp_tot, tvb, offset, length, ENC_NA); proto_tree_add_item(field_tree, hf_dtp_tat, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_SENDERID: if (length == 6) { /* Value length must be 6 bytes for a MAC address */ proto_item_append_text(ti, ": %s", tvb_ether_to_str(tvb, offset)); /* XXX - resolve? */ proto_tree_add_item(tree, hf_dtp_senderid, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; default: proto_tree_add_text(tree, tvb, offset, length, "Data"); break; } }
static int dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *signature_tree; proto_tree *name_tree; proto_tree *signedinfo_tree; proto_tree *content_tree; proto_item *titem; struct ccn_parsed_ContentObject co; struct ccn_parsed_ContentObject *pco = &co; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t blob_size; const unsigned char *blob; int l; unsigned int i; double dt; nstime_t timestamp; int res; comps = ccn_indexbuf_create(); res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps); if (res < 0) return (-1); /* Signature */ l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]; titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE); signature_tree = proto_item_add_subtree(titem, ett_signature); /* DigestAlgorithm */ l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb, pco->offset[CCN_PCO_B_DigestAlgorithm], pco->offset[CCN_PCO_E_DigestAlgorithm], &blob, &blob_size); titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb, blob - ccnb, blob_size, FALSE); } /* Witness */ l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness]; if (l > 0) { /* add the witness item to the signature tree */ } /* Signature bits */ l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb, pco->offset[CCN_PCO_B_SignatureBits], pco->offset[CCN_PCO_E_SignatureBits], &blob, &blob_size); titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb, blob - ccnb, blob_size, blob); } /* /Signature */ /* Name */ l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pco->offset[CCN_PCO_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); /* Name Components */ for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* /Name */ /* SignedInfo */ l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]; titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_SignedInfo], l, "SignedInfo"); signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo); /* PublisherPublicKeyDigest */ l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb, pco->offset[CCN_PCO_B_PublisherPublicKeyDigest], pco->offset[CCN_PCO_E_PublisherPublicKeyDigest], &blob, &blob_size); titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob); } /* Timestamp */ l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb, pco->offset[CCN_PCO_B_Timestamp], pco->offset[CCN_PCO_E_Timestamp], &blob, &blob_size); dt = 0.0; for (i = 0; i < blob_size; i++) dt = dt * 256.0 + (double)blob[i]; dt /= 4096.0; timestamp.secs = dt; /* truncates */ timestamp.nsecs = (dt - (double) timestamp.secs) * 1000000000.0; titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, ×tamp); } /* Type */ l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb, pco->offset[CCN_PCO_B_Type], pco->offset[CCN_PCO_E_Type], &blob, &blob_size); titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type); } else { titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type); } /* FreshnessSeconds */ l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds], &blob, &blob_size); i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds]); titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i); } /* FinalBlockID */ l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb, pco->offset[CCN_PCO_B_FinalBlockID], pco->offset[CCN_PCO_E_FinalBlockID], &blob, &blob_size); titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE); } /* TODO: KeyLocator */ /* /SignedInfo */ /* Content */ l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content]; res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb, pco->offset[CCN_PCO_B_Content], pco->offset[CCN_PCO_E_Content], &blob, &blob_size); titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_Content], l, "Content: %d bytes", blob_size); if (blob_size > 0) { content_tree = proto_item_add_subtree(titem, ett_content); titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE); } return (ccnb_size); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "Exclude"); exclude_tree = proto_item_add_subtree(titem, ett_exclude); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
static int dissect_dvb_s2_bb(tvbuff_t *tvb, int cur_off, proto_tree *tree, packet_info *pinfo) { proto_item *ti, *tf; proto_tree *dvb_s2_bb_tree, *dvb_s2_bb_matype1_tree; guint8 input8; guint16 input16, bb_data_len = 0; int sub_dissected = 0, flag_is_ms = 0, new_off = 0; col_append_str(pinfo->cinfo, COL_PROTOCOL, "BB "); col_append_str(pinfo->cinfo, COL_INFO, "Baseband "); /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_dvb_s2_bb, tvb, cur_off, DVB_S2_BB_HEADER_LEN, ENC_NA); dvb_s2_bb_tree = proto_item_add_subtree(ti, ett_dvb_s2_bb); input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1); new_off += 1; if (BIT_IS_CLEAR(input8, DVB_S2_BB_MIS_POS)) flag_is_ms = 1; tf = proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_matype1, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, input8); dvb_s2_bb_matype1_tree = proto_item_add_subtree(tf, ett_dvb_s2_bb_matype1); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_gs, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_mis, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_acm, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_issyi, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_npd, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_ro, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN); input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2); new_off += 1; if (flag_is_ms) { proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "Input Stream Identifier (ISI): %d", input8); } else { proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "reserved"); } input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_UPL); new_off += 2; proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_upl, tvb, cur_off + DVB_S2_BB_OFFS_UPL, 2, input16, "User Packet Length: %d bits (%d bytes)", (guint16) input16, (guint16) input16 / 8); bb_data_len = input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_DFL); bb_data_len /= 8; new_off += 2; proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_dfl, tvb, cur_off + DVB_S2_BB_OFFS_DFL, 2, input16, "%d bits (%d bytes)", input16, input16 / 8); new_off += 1; proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_sync, tvb, cur_off + DVB_S2_BB_OFFS_SYNC, 1, ENC_BIG_ENDIAN); new_off += 2; proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_syncd, tvb, cur_off + DVB_S2_BB_OFFS_SYNCD, 2, ENC_BIG_ENDIAN); input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_CRC); new_off += 1; if (check_crc8(tvb, DVB_S2_BB_HEADER_LEN - 1, cur_off, input8)) { proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_crc, tvb, cur_off + DVB_S2_BB_OFFS_CRC, 1, 1, "Checksum: correct (0x%2.2x)", input8); } else { proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_crc, tvb, cur_off + DVB_S2_BB_OFFS_CRC, 1, -1, "Checksum: incorrect! (0x%2.2x)", input8); } while (bb_data_len) { /* start DVB-GSE dissector */ sub_dissected = dissect_dvb_s2_gse(tvb, cur_off + new_off, tree, pinfo); new_off += sub_dissected; if ((sub_dissected <= bb_data_len) && (sub_dissected >= DVB_S2_GSE_MINSIZE)) { bb_data_len -= sub_dissected; if (bb_data_len < DVB_S2_GSE_MINSIZE) bb_data_len = 0; } else bb_data_len = 0; } return new_off; }
static void dissect_tns_accept(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_tree *tns_tree) { proto_tree *accept_tree = NULL, *ti; proto_item *hidden_item; int accept_offset; int accept_len; int tns_offset = offset-8; if ( tree ) { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Accept"); accept_tree = proto_item_add_subtree(ti, ett_tns_accept); hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_accept, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } col_append_str(pinfo->cinfo, COL_INFO, ", Accept"); if ( accept_tree ) { proto_tree_add_item(accept_tree, hf_tns_version, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( accept_tree ) { proto_tree *sopt_tree = NULL; ti = proto_tree_add_item(accept_tree, hf_tns_service_options, tvb, offset, 2, ENC_BIG_ENDIAN); sopt_tree = proto_item_add_subtree(ti, ett_tns_sopt_flag); dissect_tns_service_options(tvb, offset, sopt_tree); } offset += 2; if ( accept_tree ) { proto_tree_add_item(accept_tree, hf_tns_sdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( accept_tree ) { proto_tree_add_item(accept_tree, hf_tns_max_tdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( accept_tree ) { proto_tree_add_item(accept_tree, hf_tns_value_of_one, tvb, offset, 2, ENC_NA); } offset += 2; accept_len = tvb_get_ntohs(tvb, offset); if ( accept_tree ) { proto_tree_add_uint(accept_tree, hf_tns_accept_data_length, tvb, offset, 2, accept_len); } offset += 2; accept_offset = tvb_get_ntohs(tvb, offset); if ( accept_tree ) { proto_tree_add_uint(accept_tree, hf_tns_accept_data_offset, tvb, offset, 2, accept_offset); } offset += 2; if ( accept_tree ) { proto_tree *cflag_tree = NULL; ti = proto_tree_add_item(accept_tree, hf_tns_connect_flags0, tvb, offset, 1, ENC_BIG_ENDIAN); cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag); dissect_tns_connect_flag(tvb, offset, cflag_tree); } offset += 1; if ( accept_tree ) { proto_tree *cflag_tree = NULL; ti = proto_tree_add_item(accept_tree, hf_tns_connect_flags1, tvb, offset, 1, ENC_BIG_ENDIAN); cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag); dissect_tns_connect_flag(tvb, offset, cflag_tree); } offset += 1; if ( accept_tree && accept_len > 0) { proto_tree_add_item(accept_tree, hf_tns_accept_data, tvb, tns_offset+accept_offset, -1, ENC_ASCII|ENC_NA); } return; }
static int hf_bthci_sco_data = -1; /* Initialize the subtree pointers */ static gint ett_bthci_sco = -1; /* Code to actually dissect the packets */ static void dissect_bthci_sco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) { proto_item *ti; proto_tree *bthci_sco_tree; int offset = 0; ti = proto_tree_add_item(tree, proto_bthci_sco, tvb, offset, -1, ENC_NA); bthci_sco_tree = proto_item_add_subtree(ti, ett_bthci_sco); proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_chandle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_data, tvb, offset, -1, ENC_NA); } void proto_register_bthci_sco(void) {
static void dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *usb_audio_tree, proto_tree *parent_tree, gint offset) { guint8 code; guint8 cable; gboolean save_fragmented; proto_tree *tree = NULL; col_set_str(pinfo->cinfo, COL_INFO, "USB-MIDI Event Packets"); code = tvb_get_guint8(tvb, offset); cable = (code & 0xF0) >> 4; code &= 0x0F; if (parent_tree) { proto_item *ti; ti = proto_tree_add_protocol_format(usb_audio_tree, proto_usb_audio, tvb, offset, 4, "USB Midi Event Packet"); tree = proto_item_add_subtree(ti, ett_usb_audio); proto_tree_add_item(tree, hf_midi_cable_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_code_index, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_event, tvb, offset+1, 3, ENC_BIG_ENDIAN); } save_fragmented = pinfo->fragmented; /* Reassemble SysEx commands */ if (is_sysex_code(code)) { tvbuff_t* new_tvb = NULL; fragment_head *frag_sysex_msg = NULL; pinfo->fragmented = TRUE; if (code == 0x04) { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, 3, TRUE); } else { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, (gint)(code - 4), FALSE); } if (is_last_sysex_packet_in_tvb(tvb, offset)) { new_tvb = process_reassembled_data(tvb, offset+1, pinfo, "Reassembled Message", frag_sysex_msg, &sysex_msg_frag_items, NULL, usb_audio_tree); if (code != 0x04) { /* Reassembled */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx Reassembled)"); } else { /* Not last packet of reassembled Short Message */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx fragment)"); } if (new_tvb) { call_dissector(sysex_handle, new_tvb, pinfo, parent_tree); } } } pinfo->fragmented = save_fragmented; }
static void dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_tree *who_tree = NULL; proto_item *who_ti = NULL; gchar server_name[33]; double loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0; nstime_t ts; /* Summary information */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHO"); col_clear(pinfo->cinfo, COL_INFO); ts.nsecs = 0; if (tree) { who_ti = proto_tree_add_item(tree, proto_who, tvb, offset, -1, ENC_NA); who_tree = proto_item_add_subtree(who_ti, ett_who); } if (tree) proto_tree_add_item(who_tree, hf_who_vers, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (tree) proto_tree_add_item(who_tree, hf_who_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* 2 filler bytes */ offset += 2; if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_sendtime, tvb, offset, 4, &ts); } offset += 4; if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_recvtime, tvb, offset, 4, &ts); } offset += 4; tvb_get_nstringz0(tvb, offset, sizeof(server_name), (guint8*)server_name); if (tree) proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset, 32, server_name); offset += 32; loadav_5 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_5, tvb, offset, 4, loadav_5); offset += 4; loadav_10 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_10, tvb, offset, 4, loadav_10); offset += 4; loadav_15 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_15, tvb, offset, 4, loadav_15); offset += 4; /* Summary information */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %.02f %.02f %.02f", server_name, loadav_5, loadav_10, loadav_15); if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_boottime, tvb, offset, 4, &ts); offset += 4; dissect_whoent(tvb, offset, who_tree); } }
static gint dissect_ancp_tlv(tvbuff_t *tvb, proto_tree *tlv_tree, gint offset) { guint16 tlen, ttype; gint16 num_stlvs; proto_item *tti; proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); ttype = tvb_get_ntohs(tvb, offset); offset += 2; tti = proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN); tlen = tvb_get_ntohs(tvb, offset); offset += 2; /* * Extension Block is common for event message and port * management message, but the TLVs that can appear * are different */ switch (ttype) { case TLV_DSL_LINE_ATTRIBUTES: { proto_tree *dsl_tree; guint16 stlvtype, stlvlen; gint val; /* Create a DSL Attribute SubTree */ dsl_tree = proto_item_add_subtree(tti, ett_ancp_ext_tlv_type); num_stlvs = tlen / 8; /* TODO - better way? */ for ( ;num_stlvs; num_stlvs--) { proto_tree_add_item(dsl_tree, hf_ancp_dsl_line_stlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); stlvtype = tvb_get_ntohs(tvb, offset); offset += 2; proto_tree_add_item(dsl_tree, hf_ancp_dsl_line_stlv_len, tvb, offset, 2, ENC_BIG_ENDIAN); stlvlen = tvb_get_ntohs(tvb, offset); offset += 2; /* Sub TLV Length */ tti = proto_tree_add_item(dsl_tree, hf_ancp_dsl_line_stlv_value, tvb, offset, stlvlen, ENC_BIG_ENDIAN); val = tvb_get_ntohl(tvb, offset); offset += stlvlen; /* Except loop-encap, rest are 4B */ switch (stlvtype) { case TLV_DSL_LINE_STATE: proto_item_append_text(tti, " (%s)", val_to_str(val, dsl_line_state_names, "Unknown (0x%02x)")); break; case TLV_DSL_TYPE: proto_item_append_text(tti, " (%s)", val_to_str(val, dsl_line_type_names, "Unknown (0x%02x)")); break; default: /* Add Unit */ proto_item_append_text(tti, " %s", val_to_str(stlvtype, dsl_line_attr_units, "Unknown (0x%02x)")); break; } SKIPPADDING(offset, stlvlen); } break; } case TLV_PING_OPAQUE_DATA: /* 2 32b values*/ proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case TLV_PING_PARAMS: /* Count (1B) Timeout (1B), 2B empty */ proto_tree_add_item(tlv_tree, hf_ancp_oam_loopb_cnt, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tlv_tree, hf_ancp_oam_timeout, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Lets not bother about 2B until IETF WG figures out */ offset += 2; break; default: /* Assume TLV value is string - covers ALCID, OAM resp */ proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_value_str, tvb, offset, tlen, ENC_ASCII|ENC_NA); offset += tlen; SKIPPADDING(offset, tlen); break; } /* end switch {ttype} */ return offset; }
/* Code to actually dissect the packets */ static int dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; gint next_offset = 0; proto_item *ti, *th, *msrp_headers_item, *msrp_element_item; proto_tree *msrp_tree, *reqresp_tree, *raw_tree, *msrp_hdr_tree, *msrp_end_tree; proto_tree *msrp_element_tree, *msrp_data_tree; gint linelen; gint space_offset; gint token_2_start; guint token_2_len; gint token_3_start; guint token_3_len; gint token_4_start = 0; guint token_4_len = 0; gboolean is_msrp_response; gint end_line_offset; gint end_line_len; gint line_end_offset; gint message_end_offset; gint colon_offset; char *transaction_id_str = NULL; gint header_len; gint hf_index; gint value_offset; guchar c; gint value_len; char *value; gboolean have_body = FALSE; gboolean found_match = FALSE; gint content_type_len, content_type_parameter_str_len; gchar *media_type_str_lower_case = NULL; char *content_type_parameter_str = NULL; tvbuff_t *next_tvb; gint parameter_offset; gint semi_colon_offset; if ( !check_msrp_header(tvb)){ return 0; } /* We have a MSRP header with at least three tokens * * Note that "tvb_find_line_end()" will return a value that * is not longer than what's in the buffer, so the * "tvb_get_ptr()" calls below won't throw exceptions. * */ offset = 0; linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE); /* Find the first SP and skip the first token */ token_2_start = tvb_find_guint8(tvb, 0, linelen, ' ') + 1; /* Work out 2nd token's length by finding next space */ space_offset = tvb_find_guint8(tvb, token_2_start, linelen-token_2_start, ' '); token_2_len = space_offset - token_2_start; /* Transaction ID found store it for later use */ transaction_id_str = tvb_get_ephemeral_string(tvb, token_2_start, token_2_len); /* Look for another space in this line to indicate a 4th token */ token_3_start = space_offset + 1; space_offset = tvb_find_guint8(tvb, token_3_start,linelen-token_3_start, ' '); if ( space_offset == -1){ /* 3rd token runs to the end of the line */ token_3_len = linelen - token_3_start; }else{ /* We have a fourth token */ token_3_len = space_offset - token_3_start; token_4_start = space_offset + 1; token_4_len = linelen - token_4_start; } /* * Yes, so this is either a msrp-request or msrp-response. * To be a msrp-response, the second token must be * a 3-digit number. */ is_msrp_response = FALSE; if (token_3_len == 3) { if (isdigit(tvb_get_guint8(tvb, token_3_start)) && isdigit(tvb_get_guint8(tvb, token_3_start + 1)) && isdigit(tvb_get_guint8(tvb, token_3_start + 2))) { is_msrp_response = TRUE; } } /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSRP"); if (is_msrp_response){ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "Response: %s ", tvb_format_text(tvb, token_3_start, token_3_len)); if (token_4_len ) col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", tvb_format_text(tvb, token_4_start, token_4_len)); col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s", tvb_format_text(tvb, token_2_start, token_2_len)); } }else{ if (check_col(pinfo->cinfo, COL_INFO)) { proto_tree_add_text(tree, tvb, token_3_start, token_3_len, "Col %s L=%u", tvb_format_text(tvb, token_3_start, token_3_len),token_3_len); col_add_fstr(pinfo->cinfo, COL_INFO, "Request: %s ", tvb_format_text(tvb, token_3_start, token_3_len)); col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s", tvb_format_text(tvb, token_2_start, token_2_len)); } } /* Find the end line to be able to process the headers * Note that in case of [content-stuff] headers and [content-stuff] is separated by CRLF */ offset = next_offset; end_line_offset = find_end_line(tvb,offset); /* TODO if -1 (No end line found, is returned do something) */ end_line_len = tvb_find_line_end(tvb, end_line_offset, -1, &next_offset, FALSE); message_end_offset = end_line_offset + end_line_len + 2; if (tree) { ti = proto_tree_add_item(tree, proto_msrp, tvb, 0, message_end_offset, FALSE); msrp_tree = proto_item_add_subtree(ti, ett_msrp); if (is_msrp_response){ th = proto_tree_add_item(msrp_tree,hf_msrp_response_line,tvb,0,linelen,FALSE); reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp); proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE); proto_tree_add_uint(reqresp_tree,hf_msrp_status_code,tvb,token_3_start,token_3_len, atoi(tvb_get_ephemeral_string(tvb, token_3_start, token_3_len))); }else{ th = proto_tree_add_item(msrp_tree,hf_msrp_request_line,tvb,0,linelen,FALSE); reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp); proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE); proto_tree_add_item(reqresp_tree,hf_msrp_method,tvb,token_3_start,token_3_len,FALSE); } /* Conversation setup info */ if (global_msrp_show_setup_info) { show_setup_info(tvb, pinfo, msrp_tree); } /* Headers */ msrp_headers_item = proto_tree_add_item(msrp_tree, hf_msrp_msg_hdr, tvb, offset,(end_line_offset - offset), FALSE); msrp_hdr_tree = proto_item_add_subtree(msrp_headers_item, ett_msrp_hdr); /* * Process the headers */ while (tvb_reported_length_remaining(tvb, offset) > 0 && offset < end_line_offset ) { /* 'desegment' is FALSE so will set next_offset to beyond the end of the buffer if no line ending is found */ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); if (linelen == 0) { /* * This is a blank line separating the * message header from the message body. */ have_body = TRUE; break; } line_end_offset = offset + linelen; colon_offset = tvb_find_guint8(tvb, offset, linelen, ':'); if (colon_offset == -1) { /* * Malformed header - no colon after the name. */ proto_tree_add_text(msrp_hdr_tree, tvb, offset, next_offset - offset, "%s", tvb_format_text(tvb, offset, linelen)); } else { header_len = colon_offset - offset; hf_index = msrp_is_known_msrp_header(tvb, offset, header_len); if (hf_index == -1) { proto_tree_add_text(msrp_hdr_tree, tvb, offset, next_offset - offset, "%s", tvb_format_text(tvb, offset, linelen)); } else { /* * Skip whitespace after the colon. */ value_offset = colon_offset + 1; while (value_offset < line_end_offset && ((c = tvb_get_guint8(tvb, value_offset)) == ' ' || c == '\t')) value_offset++; /* * Fetch the value. */ value_len = line_end_offset - value_offset; value = tvb_get_ephemeral_string(tvb, value_offset, value_len); /* * Add it to the protocol tree, * but display the line as is. */ msrp_element_item = proto_tree_add_string_format(msrp_hdr_tree, hf_header_array[hf_index], tvb, offset, next_offset - offset, value, "%s", tvb_format_text(tvb, offset, linelen)); msrp_element_tree = proto_item_add_subtree( msrp_element_item, ett_msrp_element); switch ( hf_index ) { case MSRP_CONTENT_TYPE : content_type_len = value_len; semi_colon_offset = tvb_find_guint8(tvb, value_offset,linelen, ';'); if ( semi_colon_offset != -1) { parameter_offset = semi_colon_offset +1; /* * Skip whitespace after the semicolon. */ while (parameter_offset < line_end_offset && ((c = tvb_get_guint8(tvb, parameter_offset)) == ' ' || c == '\t')) parameter_offset++; content_type_len = semi_colon_offset - value_offset; content_type_parameter_str_len = line_end_offset - parameter_offset; content_type_parameter_str = tvb_get_ephemeral_string(tvb, parameter_offset, content_type_parameter_str_len); } media_type_str_lower_case = ascii_strdown_inplace( (gchar *)tvb_get_ephemeral_string(tvb, value_offset, content_type_len)); break; default: break; } } } offset = next_offset; }/* End while */ if ( have_body ){ /* * There's a message body starting at "next_offset". * Set the length of the header item. */ proto_item_set_end(msrp_headers_item, tvb, next_offset); /* Create new tree & tvb for data */ next_tvb = tvb_new_subset_remaining(tvb, next_offset); ti = proto_tree_add_item(msrp_tree, hf_msrp_data, tvb, next_offset, -1, FALSE); msrp_data_tree = proto_item_add_subtree(ti, ett_msrp_data); /* give the content type parameters to sub dissectors */ if ( media_type_str_lower_case != NULL ) { void *save_private_data = pinfo->private_data; pinfo->private_data = content_type_parameter_str; found_match = dissector_try_string(media_type_dissector_table, media_type_str_lower_case, next_tvb, pinfo, msrp_data_tree); pinfo->private_data = save_private_data; /* If no match dump as text */ } if ( found_match != TRUE ) { offset = 0; while (tvb_offset_exists(next_tvb, offset)) { tvb_find_line_end(next_tvb, offset, -1, &next_offset, FALSE); linelen = next_offset - offset; proto_tree_add_text(msrp_data_tree, next_tvb, offset, linelen, "%s", tvb_format_text(next_tvb, offset, linelen)); offset = next_offset; }/* end while */ } } /* End line */ ti = proto_tree_add_item(msrp_tree,hf_msrp_end_line,tvb,end_line_offset,end_line_len,FALSE); msrp_end_tree = proto_item_add_subtree(ti, ett_msrp_end_line); proto_tree_add_item(msrp_end_tree,hf_msrp_transactionID,tvb,end_line_offset + 7,token_2_len,FALSE); /* continuation-flag */ proto_tree_add_item(msrp_end_tree,hf_msrp_cnt_flg,tvb,end_line_offset+end_line_len-1,1,FALSE); if (global_msrp_raw_text){ ti = proto_tree_add_text(tree, tvb, 0, -1,"Message Session Relay Protocol(as raw text)"); raw_tree = proto_item_add_subtree(ti, ett_msrp); tvb_raw_text_add(tvb,raw_tree); } }/* if tree */ return message_end_offset; /* return tvb_length(tvb); */ /* If this protocol has a sub-dissector call it here, see section 1.8 */ }
static void dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset, guint8 mtype) { guint8 tech_type; gint16 num_tlvs; proto_item *sti; if (mtype == ANCP_MTYPE_PORT_MGMT) { proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 14, ENC_NA); offset += 14; proto_tree_add_item(ancp_tree, hf_ancp_function, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_x_function, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 4, ENC_NA); offset += 4; } else { proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 20, ENC_NA); offset += 20; } proto_tree_add_item(ancp_tree, hf_ancp_ext_flags_res, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_mtype, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (mtype == ANCP_MTYPE_PORT_MGMT) { proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 2, ENC_NA); offset += 2; tech_type = 0; } else { proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, ENC_BIG_ENDIAN); tech_type = tvb_get_guint8(tvb, offset); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_NA); offset += 1; } proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb, offset, 2, ENC_BIG_ENDIAN); num_tlvs = tvb_get_ntohs(tvb, offset); offset += 2; sti = proto_tree_add_item(ancp_tree, hf_ancp_blk_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (tech_type == TECH_TYPE_DSL || tech_type == TECH_TYPE_PON) { proto_tree *tlv_tree; /* Create a TLV sub tree */ tlv_tree = proto_item_add_subtree(sti, ett_ancp_len); for( ;num_tlvs; num_tlvs--) { offset = dissect_ancp_tlv(tvb, tlv_tree, offset); } /* end for {numtlvs} */ } /* end if {DSL} */ }
static void dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *qllc_tree = NULL; proto_item *qllc_ti = NULL; gboolean *q_bit_set = pinfo->private_data; guint8 addr, ctrl; gboolean command = FALSE; /* * If the Q bit isn't set, this is just SNA data. */ if (!(*q_bit_set)) { call_dissector(sna_handle, tvb, pinfo, tree); return; } /* Summary information */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "QLLC"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { qllc_ti = proto_tree_add_item(tree, proto_qllc, tvb, 0, -1, ENC_NA); qllc_tree = proto_item_add_subtree(qllc_ti, ett_qllc); } /* Get the address; we need it to determine if this is a * COMMAND or a RESPONSE */ addr = tvb_get_guint8(tvb, 0); if (tree) { proto_tree_add_item(qllc_tree, hf_qllc_address, tvb, 0, 1, ENC_BIG_ENDIAN); } /* The address field equals X'FF' in commands (except QRR) * and anything in responses. */ ctrl = tvb_get_guint8(tvb, 1); if (ctrl != QRR && addr == 0xff) { command = TRUE; } /* Disambiguate QRD_QDISC_VALUE, based on whether this packet is * a COMMAND or RESPONSE. */ if (ctrl == QRD_QDISC_VALUE) { if (command) { col_set_str(pinfo->cinfo, COL_INFO, QDISC_TEXT); if (tree) { proto_tree_add_text(qllc_tree, tvb, 1, 1, "Control Field: %s (0x%02x)", QDISC_TEXT, ctrl); } } else { col_set_str(pinfo->cinfo, COL_INFO, QRD_TEXT); if (tree) { proto_tree_add_text(qllc_tree, tvb, 1, 1, "Control Field: %s (0x%02x)", QRD_TEXT, ctrl); } } /* Add the field for filtering purposes */ if (tree) { proto_item *hidden_item; hidden_item = proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb, 1, 1, ctrl); PROTO_ITEM_SET_HIDDEN(hidden_item); } } else { /* Non-ambiguous control field value */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(ctrl, qllc_control_vals, "Control Field: 0x%02x (unknown)")); } if (tree) { proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb, 1, 1, ctrl); } } /* Do we have an I field ? */ /* XXX - I field exists for QUI too, but only for subarea nodes. * Need to test for this. */ if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) { /* yes */ } }
static void dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree, gint offset, struct ancp_tap_t *ancp_info ) { proto_item *sti; proto_tree *ancp_cap_tree; guint8 byte, numcaps, adjcode; guint16 tlv_len; sti = proto_tree_add_item(ancp_tree, hf_ancp_timer, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_item_append_text(sti, " msec"); sti = proto_tree_add_item(ancp_tree, hf_ancp_adj_code, tvb, offset, 1, ENC_BIG_ENDIAN); byte = tvb_get_guint8(tvb, offset); offset += 1; adjcode = byte & ADJ_CODE_MASK; ancp_info->ancp_adjcode = adjcode; /* stats */ proto_item_append_text(sti, " (%s, M Flag %s)", val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"), (byte >> 7) ? "Set" : "Unset"); col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)")); proto_tree_add_item(ancp_tree, hf_ancp_sender_name, tvb, offset, 6, ENC_NA); offset += 6; proto_tree_add_item(ancp_tree, hf_ancp_receiver_name, tvb,offset, 6, ENC_NA); offset += 6; proto_tree_add_item(ancp_tree, hf_ancp_sender_port, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ancp_tree, hf_ancp_receiver_port, tvb,offset, 4, ENC_BIG_ENDIAN); offset += 4; sti = proto_tree_add_item(ancp_tree, hf_ancp_p_info, tvb, offset, 1, ENC_BIG_ENDIAN); byte = tvb_get_guint8(tvb, offset); offset += 1; proto_item_append_text(sti, " (Type = %d, Flag = %d)", byte >> 4, byte & 0x0F); proto_tree_add_item(ancp_tree, hf_ancp_sender_instance, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_NA); offset += 1; sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1, ENC_BIG_ENDIAN); numcaps = tvb_get_guint8(tvb, offset); offset += 1; /* Start the capability subtree */ ancp_cap_tree = proto_item_add_subtree(sti, ett_ancp_tot_len); proto_tree_add_item(ancp_cap_tree, hf_ancp_tot_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; for ( ;numcaps; numcaps--) { sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_cap, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; tlv_len = tvb_get_ntohs(tvb, offset); offset += 2; proto_item_append_text(sti, " (%d bytes)", tlv_len); /* TODO - if there are non boolean caps, validate before use */ } }
static void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree, guint offset, guint32 uCount, guint bLittleEndian, gboolean bParse) { guint32 u = 0; guint32 tOfs = 0; guint32 uLenF; char strPrm[256]; guint32 uTyp; guint32 uLen = 0; guint32 uPrm; guint32 uCnt; guint32 uCCS; guint32 uSLn; guint32 uVal; guint64 uVal64; guint32 uDig; const char sMaxLst[] = " Max # of List reached. DECODE interrupted (actual %u of %u)"; const char sPrmLn0[] = " MQPrm[%3u] has a zero length. DECODE Failed (MQPrm Count: %u)"; const char sMaxPrm[] = " Max # of Parm reached. DECODE interrupted (actual %u of %u)"; const char sPrmCnt[] = " Cnt=-1 and Length(%u) < 16. DECODE interrupted for elem %u"; proto_item *ti = NULL; proto_tree *tree = NULL; if (uCount == (guint32)-1) { guint32 xOfs = offset; uCnt = 0; while (tvb_length_remaining(tvb, xOfs) >= 16) { uLen = tvb_get_guint32_endian(tvb, xOfs + 4, bLittleEndian); if (uLen < 16) { ti = proto_tree_add_text(mq_tree, tvb, xOfs, 16, sPrmCnt, uLen, uCnt); expert_add_info(pinfo, ti, &ei_mq_pcf_PrmCnt); break; } uCnt++; xOfs += uLen; } uCount = uCnt; } uDig = dissect_mqpcf_getDigits(uCount); for (u = 0; u < uCount && u < mq_pcf_maxprm; u++) { tOfs = offset; uTyp = tvb_get_guint32_endian(tvb, offset , bLittleEndian); uLen = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian); if (uLen == 0) { ti = proto_tree_add_text(mq_tree, tvb, offset, 12, sPrmLn0, u+1, uCount); expert_add_info(pinfo, ti, &ei_mq_pcf_prmln0); u = uCount; break; } uPrm = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian); uLenF = 12; if (bParse) g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d-%-30.30s", "MQPrm", uDig, u+1, uTyp, val_to_str_const(uTyp, GET_VALSV(PrmTyp), " Unknown") + 6, uPrm, uPrm, val_to_str_const(uPrm, GET_VALSV(PrmId), "Unknown")); else g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d", "XtraD", uDig, u+1, uTyp, val_to_str_const(uTyp, GET_VALSV(PrmTyp), " Unknown") + 6, uPrm, uPrm); switch (uTyp) { case MQ_MQCFT_NONE: break; case MQ_MQCFT_COMMAND: break; case MQ_MQCFT_RESPONSE: break; case MQ_MQCFT_INTEGER: { const guint8 *pVal = NULL; uVal = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); if (bParse) pVal = dissect_mqpcf_parm_getintval(uPrm, uVal); if (pVal) { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %d-%s", strPrm, uVal, pVal); } else { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %8x-%d", strPrm, uVal, uVal); } tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp, tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen, tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); dissect_mqpcf_parm_int(tvb, tree, offset+uLenF, uPrm, uVal, hf_mq_pcf_int, 0, 0, 0, bParse); } break; case MQ_MQCFT_STRING: { guint8 *sStr; uCCS = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian); sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); if (*sStr) strip_trailing_blanks(sStr, uSLn); if (*sStr) format_text_chr(sStr, strlen(sStr), '.'); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s", strPrm, sStr); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); } break; case MQ_MQCFT_INTEGER_LIST: { guint32 u2; guint32 uDigit = 0; uCnt = tvb_get_guint32_endian(tvb, offset+uLenF, bLittleEndian); uDigit = dissect_mqpcf_getDigits(uCnt); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian); offset += uLenF+4; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { uVal = tvb_get_guint32_endian(tvb, offset, bLittleEndian); dissect_mqpcf_parm_int(tvb, tree, offset, uPrm, uVal, hf_mq_pcf_intlist, u2+1, uCnt, uDigit, bParse); offset += 4; } if (u2 != uCnt) { ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt); expert_add_info(pinfo, ti, &ei_mq_pcf_MaxInt); } } break; case MQ_MQCFT_STRING_LIST: { guint32 u2; guint32 uDigit; guint8 *sStr; header_field_info *hfinfo; hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist); uCCS = tvb_get_guint32_endian(tvb, offset + uLenF , bLittleEndian); uCnt = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian); uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount , tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian); uDigit = dissect_mqpcf_getDigits(uCnt); offset += uLenF+12; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); if (*sStr) strip_trailing_blanks(sStr, uSLn); if (*sStr) format_text_chr(sStr, strlen(sStr), '.'); proto_tree_add_string_format(tree, hf_mq_pcf_stringlist, tvb, offset, uSLn, sStr, "%s[%*d]: %s", hfinfo->name, uDigit, u2+1, sStr); offset += uSLn; } if (u2 != uCnt) { ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt); expert_add_info(pinfo, ti, &ei_mq_pcf_MaxStr); } } break; case MQ_MQCFT_EVENT: break; case MQ_MQCFT_USER: { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s", strPrm); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + 8, uLen - 8, bLittleEndian); } break; case MQ_MQCFT_BYTE_STRING: { uSLn = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); if (uSLn) { guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.'); guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.'); if (uSLn > 35) { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE); } else { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s A(%s) E(%s)", strPrm, sStrA, sStrE); } } else { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s <MISSING>", strPrm); } tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 4 , uSLn, bLittleEndian); } break; case MQ_MQCFT_TRACE_ROUTE: break; case MQ_MQCFT_REPORT: break; case MQ_MQCFT_INTEGER_FILTER: { guint32 uOpe; uOpe = tvb_get_guint32_endian(tvb, offset + uLenF , bLittleEndian); uVal = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %d", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, uVal); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_int, tvb, offset + uLenF + 4, 4, bLittleEndian); } break; case MQ_MQCFT_STRING_FILTER: { guint8 *sStr; guint32 uOpe; uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); uCCS = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian); uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian); sStr = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC), uSLn, '.'); strip_trailing_blanks(sStr, uSLn); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %s", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, sStr); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); } break; case MQ_MQCFT_BYTE_STRING_FILTER: { guint32 uOpe; uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian); if (uSLn) { guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_ASCII), uSLn, '.'); guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_EBCDIC), uSLn, '.'); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s A(%s) E(%s)", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, sStrA, sStrE); } else { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s <MISSING>", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7); } tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 8 , uSLn, bLittleEndian); } break; case MQ_MQCFT_COMMAND_XR: break; case MQ_MQCFT_XR_MSG: break; case MQ_MQCFT_XR_ITEM: break; case MQ_MQCFT_XR_SUMMARY: break; case MQ_MQCFT_GROUP: break; case MQ_MQCFT_STATISTICS: break; case MQ_MQCFT_ACCOUNTING: break; case MQ_MQCFT_INTEGER64: { uVal64 = tvb_get_guint64_endian(tvb, offset + uLenF + 4, bLittleEndian); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)", strPrm, uVal64, uVal64); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmunused, tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_int64, tvb, offset + uLenF + 4, 8, bLittleEndian); } break; case MQ_MQCFT_INTEGER64_LIST: { guint32 u2; guint32 uDigit; header_field_info *hfinfo; hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list); uCnt = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian); ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt); tree = proto_item_add_subtree(ti, ett_mqpcf_prm); uDigit = dissect_mqpcf_getDigits(uCnt); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian); offset += uLenF + 4; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { uVal64 = tvb_get_guint64_endian(tvb, offset, bLittleEndian); proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64, "%s[%*d]: %" G_GINT64_MODIFIER "d", hfinfo->name, uDigit, u2+1, uVal64); offset += 8; } if (u2 != uCnt) { ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt); expert_add_info(pinfo, ti, &ei_mq_pcf_MaxI64); } } break; } offset = tOfs+uLen; } if (u != uCount) { ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, sMaxPrm, u, uCount); expert_add_info(pinfo, ti, &ei_mq_pcf_MaxPrm); } }
static gint ett_spray_clock = -1; static int dissect_get_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { proto_item* lock_item = NULL; proto_tree* lock_tree = NULL; offset = dissect_rpc_uint32(tvb, tree, hf_spray_counter, offset); lock_item = proto_tree_add_item(tree, hf_spray_clock, tvb, offset, -1, ENC_NA); lock_tree = proto_item_add_subtree(lock_item, ett_spray_clock); offset = dissect_rpc_uint32(tvb, lock_tree, hf_spray_sec, offset); offset = dissect_rpc_uint32(tvb, lock_tree, hf_spray_usec, offset); return offset; } static int dissect_spray_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { offset = dissect_rpc_data(tvb, tree, hf_spray_sprayarr, offset);
static int dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { proto_item *volatile ti = NULL, *comment_item; guint cap_len = 0, frame_len = 0; proto_tree *volatile tree; proto_tree *comments_tree; proto_item *item; const gchar *cap_plurality, *frame_plurality; frame_data_t *fr_data = (frame_data_t*)data; tree=parent_tree; switch (pinfo->phdr->rec_type) { case REC_TYPE_PACKET: pinfo->current_proto = "Frame"; if (pinfo->pseudo_header != NULL) { switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_WFLEET_HDLC: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: case WTAP_ENCAP_SDLC: case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_BLUETOOTH_HCI: pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: case WTAP_ENCAP_FRELAY_WITH_PHDR: pinfo->p2p_dir = (pinfo->pseudo_header->x25.flags & FROM_DCE) ? P2P_DIR_RECV : P2P_DIR_SENT; break; case WTAP_ENCAP_ISDN: case WTAP_ENCAP_V5_EF: case WTAP_ENCAP_DPNSS: case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_LINUX_LAPD: pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 || pinfo->pseudo_header->lapd.pkttype == 4) ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_MTP2_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ? P2P_DIR_SENT : P2P_DIR_RECV; pinfo->link_number = pinfo->pseudo_header->mtp2.link_number; break; case WTAP_ENCAP_GSM_UM: pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ? P2P_DIR_SENT : P2P_DIR_RECV; break; } } break; case REC_TYPE_FT_SPECIFIC_EVENT: pinfo->current_proto = "Event"; break; case REC_TYPE_FT_SPECIFIC_REPORT: pinfo->current_proto = "Report"; break; default: g_assert_not_reached(); break; } if (fr_data && fr_data->pkt_comment) { item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, ENC_NA); comments_tree = proto_item_add_subtree(item, ett_comments); comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, 0, fr_data->pkt_comment, "%s", fr_data->pkt_comment); expert_add_info_format(pinfo, comment_item, &ei_comments_text, "%s", fr_data->pkt_comment); } /* if FRAME is not referenced from any filters we don't need to worry about generating any tree items. */ if (!proto_field_is_referenced(tree, proto_frame)) { tree=NULL; if (pinfo->fd->flags.has_ts) { if (pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) expert_add_info(pinfo, NULL, &ei_arrive_time_out_of_range); } } else { proto_tree *fh_tree; gboolean old_visible; /* Put in frame header information. */ cap_len = tvb_length(tvb); frame_len = tvb_reported_length(tvb); cap_plurality = plurality(cap_len, "", "s"); frame_plurality = plurality(frame_len, "", "s"); ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb), "Frame %u: %u byte%s on wire", pinfo->fd->num, frame_len, frame_plurality); if (generate_bits_field) proto_item_append_text(ti, " (%u bits)", frame_len * 8); proto_item_append_text(ti, ", %u byte%s captured", cap_len, cap_plurality); if (generate_bits_field) { proto_item_append_text(ti, " (%u bits)", cap_len * 8); } if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) { proto_item_append_text(ti, " on interface %u", pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) { if (pinfo->phdr->pack_flags & 0x00000001) { proto_item_append_text(ti, " (inbound)"); pinfo->p2p_dir = P2P_DIR_RECV; } if (pinfo->phdr->pack_flags & 0x00000002) { proto_item_append_text(ti, " (outbound)"); pinfo->p2p_dir = P2P_DIR_SENT; } } fh_tree = proto_item_add_subtree(ti, ett_frame); if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) { const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id); if (interface_name) proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name); else proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) { proto_tree *flags_tree; proto_item *flags_item; flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->phdr->pack_flags); flags_tree = proto_item_add_subtree(flags_item, ett_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags); } if (pinfo->phdr->rec_type == REC_TYPE_PACKET) proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t); if (pinfo->fd->flags.has_ts) { proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb, 0, 0, &(pinfo->fd->abs_ts)); if (pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) { expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range, "Arrival Time: Fractional second %09ld is invalid," " the valid range is 0-1000000000", (long) pinfo->fd->abs_ts.nsecs); } item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb, 0, 0, &(pinfo->fd->shift_offset)); PROTO_ITEM_SET_GENERATED(item); if (generate_epoch_time) { proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb, 0, 0, &(pinfo->fd->abs_ts)); } if (proto_field_is_referenced(tree, hf_frame_time_delta)) { nstime_t del_cap_ts; frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->num - 1, &del_cap_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb, 0, 0, &(del_cap_ts)); PROTO_ITEM_SET_GENERATED(item); } if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) { nstime_t del_dis_ts; frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->prev_dis_num, &del_dis_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb, 0, 0, &(del_dis_ts)); PROTO_ITEM_SET_GENERATED(item); } item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb, 0, 0, &(pinfo->rel_ts)); PROTO_ITEM_SET_GENERATED(item); if (pinfo->fd->flags.ref_time) { ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA); PROTO_ITEM_SET_GENERATED(ti); } } proto_tree_add_uint(fh_tree, hf_frame_number, tvb, 0, 0, pinfo->fd->num); proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb, 0, 0, frame_len, "Frame Length: %u byte%s (%u bits)", frame_len, frame_plurality, frame_len * 8); proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb, 0, 0, cap_len, "Capture Length: %u byte%s (%u bits)", cap_len, cap_plurality, cap_len * 8); if (generate_md5_hash) { const guint8 *cp; md5_state_t md_ctx; md5_byte_t digest[16]; const gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); md5_init(&md_ctx); md5_append(&md_ctx, cp, cap_len); md5_finish(&md_ctx, digest); digest_string = bytestring_to_str(wmem_packet_scope(), digest, 16, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored); PROTO_ITEM_SET_GENERATED(ti); if (proto_field_is_referenced(tree, hf_frame_protocols)) { /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ old_visible = proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); proto_tree_set_visible(fh_tree, old_visible); } /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } /* Check for existences of MTP2 link number */ if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) { proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } if (show_file_off) { proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } if (pinfo->fd->color_filter != NULL) { const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter; item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } } if (pinfo->fd->flags.ignored) { /* Ignored package, stop handling here */ col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>"); proto_tree_add_text (tree, tvb, 0, 0, "This frame is marked as ignored"); return tvb_captured_length(tvb); } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations. (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif switch (pinfo->phdr->rec_type) { case REC_TYPE_PACKET: if ((force_docsis_encap) && (docsis_handle)) { call_dissector(docsis_handle, tvb, pinfo, parent_tree); } else { if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", pinfo->fd->lnk_t); call_dissector(data_handle,tvb, pinfo, parent_tree); } } break; case REC_TYPE_FT_SPECIFIC_EVENT: case REC_TYPE_FT_SPECIFIC_REPORT: { int file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN; if (fr_data) { file_type_subtype = fr_data->file_type_subtype; } if (!dissector_try_uint(wtap_fts_rec_dissector_table, file_type_subtype, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", file_type_subtype); call_dissector(data_handle,tvb, pinfo, parent_tree); } } break; } #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch (GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if (proto_field_is_referenced(tree, hf_frame_protocols)) { wmem_strbuf_t *val = wmem_strbuf_sized_new(wmem_packet_scope(), 128, 0); wmem_list_frame_t *frame; /* skip the first entry, it's always the "frame" protocol */ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers)); if (frame) { wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } while (frame) { wmem_strbuf_append_c(val, ':'); wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } proto_item_append_string(ti, wmem_strbuf_get_str(val)); } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch (GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } tap_queue_packet(frame_tap, pinfo, NULL); if (pinfo->frame_end_routines) { g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL); g_slist_free(pinfo->frame_end_routines); pinfo->frame_end_routines = NULL; } return tvb_captured_length(tvb); }
/* *** Code to actually dissect the packets *** */ static int dissect_dvb_s2_gse(tvbuff_t *tvb, int cur_off, proto_tree *tree, packet_info *pinfo) { int new_off = 0; int frag_len; guint16 gse_hdr, data_len, gse_proto = 0; proto_item *ti, *tf; proto_tree *dvb_s2_gse_tree, *dvb_s2_gse_hdr_tree; tvbuff_t *next_tvb; col_append_str(pinfo->cinfo, COL_INFO, "GSE"); /* get header and determine length */ gse_hdr = tvb_get_ntohs(tvb, cur_off + DVB_S2_GSE_OFFS_HDR); new_off += 2; frag_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK)+2; ti = proto_tree_add_item(tree, proto_dvb_s2_gse, tvb, cur_off, frag_len, ENC_NA); dvb_s2_gse_tree = proto_item_add_subtree(ti, ett_dvb_s2_gse); tf = proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_hdr, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, gse_hdr); dvb_s2_gse_hdr_tree = proto_item_add_subtree(tf, ett_dvb_s2_gse_hdr); proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_start, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_stop, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_labeltype, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_length, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN); if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) { col_append_str(pinfo->cinfo, COL_INFO, " "); return new_off; } else { if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) || BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) { proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_fragid, tvb, cur_off + new_off, 1, ENC_BIG_ENDIAN); new_off += 1; } if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) { proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_totlength, tvb, cur_off + new_off, 2, ENC_BIG_ENDIAN); col_append_str(pinfo->cinfo, COL_INFO, "(frag) "); new_off += 2; } if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS)) { gse_proto = tvb_get_ntohs(tvb, cur_off + new_off); proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_proto, tvb, cur_off + new_off, 2, ENC_BIG_ENDIAN); new_off += 2; if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) { /* 6 byte label */ if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) col_append_str(pinfo->cinfo, COL_INFO, "6 "); proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label6, tvb, cur_off + new_off, 6, ENC_NA); new_off += 6; } else if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) { /* 3 byte label */ if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) col_append_str(pinfo->cinfo, COL_INFO, "3 "); proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label3, tvb, cur_off + new_off, 3, ENC_BIG_ENDIAN); new_off += 3; } else { /* 0 byte label */ if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) col_append_str(pinfo->cinfo, COL_INFO, "0 "); } if (gse_proto < 0x0600 && gse_proto >= 0x100) { /* Only display optional extension headers */ /* TODO: needs to be tested */ /* TODO: implementation needs to be checked (len of ext-header??) */ proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_exthdr, tvb, cur_off + new_off, 1, ENC_BIG_ENDIAN); new_off += 1; } } else { /* correct cinfo */ col_append_str(pinfo->cinfo, COL_INFO, "(frag) "); } next_tvb = tvb_new_subset_remaining(tvb, cur_off + new_off); if (dvb_s2_full_dissection) { switch (gse_proto) { case ETHERTYPE_IP: new_off += call_dissector(ip_handle, next_tvb, pinfo, tree); break; case ETHERTYPE_IPv6: new_off += call_dissector(ipv6_handle, next_tvb, pinfo, tree); break; default: if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) { data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE) - DVB_S2_GSE_CRC32_LEN; } else data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE); proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_data, tvb, cur_off + new_off, data_len, ENC_NA); new_off += data_len; break; } } else { if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) { data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE) - DVB_S2_GSE_CRC32_LEN; } else data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE); proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_data, tvb, cur_off + new_off, data_len, ENC_NA); new_off += data_len; } /* add crc32 if last fragment */ if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) { proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_crc32, tvb, cur_off + new_off, DVB_S2_GSE_CRC32_LEN, ENC_BIG_ENDIAN); new_off += DVB_S2_GSE_CRC32_LEN; } } return new_off; }
}; static int dissect_db_lsp_pdu (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_tree *db_lsp_tree; proto_item *db_lsp_item; gint offset = 0; guint8 type, opvalue; guint16 magic, length; col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME); col_set_str (pinfo->cinfo, COL_INFO, PNAME); db_lsp_item = proto_tree_add_item (tree, proto_db_lsp, tvb, offset, -1, ENC_NA); db_lsp_tree = proto_item_add_subtree (db_lsp_item, ett_db_lsp); type = tvb_get_guint8 (tvb, offset); proto_tree_add_item (db_lsp_tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (type == 0x80) { /* Two unknown bytes */ offset += 2; } magic = tvb_get_ntohs (tvb, offset); proto_tree_add_item (db_lsp_tree, hf_magic, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; length = tvb_get_ntohs (tvb, offset);
/* Code to actually dissect the packets */ static void dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char *szInfo; int offCur = 0; /* current offset from start of WTP data */ gint returned_length, str_index = 0; unsigned char b0; /* continuation flag */ unsigned char fCon; /* Continue flag */ unsigned char fRID; /* Re-transmission indicator*/ unsigned char fTTR = '\0'; /* Transmission trailer */ guint cbHeader = 0; /* Fixed header length */ guint vHeader = 0; /* Variable header length*/ int abortType = 0; /* Set up structures we'll need to add the protocol subtree and manage it */ proto_item *ti = NULL; proto_tree *wtp_tree = NULL; char pdut; char clsTransaction = 3; int numMissing = 0; /* Number of missing packets in a negative ack */ int i; tvbuff_t *wsp_tvb = NULL; guint8 psn = 0; /* Packet sequence number*/ guint16 TID = 0; /* Transaction-Id */ int dataOffset; gint dataLen; #define SZINFO_SIZE 256 szInfo=ep_alloc(SZINFO_SIZE); b0 = tvb_get_guint8 (tvb, offCur + 0); /* Discover Concatenated PDUs */ if (b0 == 0) { guint c_fieldlen = 0; /* Length of length-field */ guint c_pdulen = 0; /* Length of conc. PDU */ if (tree) { ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 1, ENC_NA); wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree); proto_item_append_text(ti, ", PDU concatenation"); } offCur = 1; i = 1; while (offCur < (int) tvb_reported_length(tvb)) { tvbuff_t *wtp_tvb; /* The length of an embedded WTP PDU is coded as either: * - a 7-bit value contained in one octet with highest bit == 0. * - a 15-bit value contained in two octets (little endian) * if the 1st octet has its highest bit == 1. * This means that this is NOT encoded as an uintvar-integer!!! */ b0 = tvb_get_guint8(tvb, offCur + 0); if (b0 & 0x80) { c_fieldlen = 2; c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1); } else { c_fieldlen = 1; c_pdulen = b0; } if (tree) { proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size, tvb, offCur, c_fieldlen, c_pdulen); } if (i > 1) { col_append_str(pinfo->cinfo, COL_INFO, ", "); } /* Skip the length field for the WTP sub-tvb */ wtp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen); dissect_wtp_common(wtp_tvb, pinfo, wtp_tree); offCur += c_fieldlen + c_pdulen; i++; } if (tree) { proto_item_append_text(ti, ", PDU count: %u", i); } return; } /* No concatenation */ fCon = b0 & 0x80; fRID = retransmission_indicator(b0); pdut = pdu_type(b0); #ifdef DEBUG printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n", pinfo->fd->num, tree, val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"), pdut, tvb_length(tvb)); #endif /* Develop the string to put in the Info column */ returned_length = g_snprintf(szInfo, SZINFO_SIZE, "WTP %s", val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x")); str_index += MIN(returned_length, SZINFO_SIZE-str_index); switch (pdut) { case INVOKE: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3)); returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " Class %d", clsTransaction); str_index += MIN(returned_length, SZINFO_SIZE-str_index); cbHeader = 4; break; case SEGMENTED_INVOKE: case SEGMENTED_RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = tvb_get_guint8(tvb, offCur + 3); if (psn != 0) { returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " (%u)", psn); str_index += MIN(returned_length, SZINFO_SIZE-str_index); } cbHeader = 4; break; case ABORT: cbHeader = 4; break; case RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; cbHeader = 3; break; case ACK: cbHeader = 3; break; case NEGATIVE_ACK: /* Variable number of missing packets */ numMissing = tvb_get_guint8(tvb, offCur + 3); cbHeader = numMissing + 4; break; default: break; }; if (fRID) { returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" ); str_index += MIN(returned_length, SZINFO_SIZE-str_index); }; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); #endif /* NOTE - Length will be set when we process the TPI */ ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA); #ifdef DEBUG fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n"); #endif wtp_tree = proto_item_add_subtree(ti, ett_wtp); /* Code to process the packet goes here */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur); #endif /* Add common items: only CON and PDU Type */ proto_tree_add_item( wtp_tree, /* tree */ hf_wtp_header_flag_continue, /* id */ tvb, offCur, /* start of highlight */ 1, /* length of highlight*/ b0 /* value */ ); proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN); switch(pdut) { case INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Invoke (%u)" ", Transaction Class: %s (%u)", INVOKE, val_to_str(clsTransaction, vals_transaction_classes, "Undefined"), clsTransaction); break; case RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: Result (%u)", RESULT); break; case ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: ACK (%u)", ACK); break; case ABORT: abortType = tvb_get_guint8 (tvb, offCur) & 0x07; proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); if (abortType == PROVIDER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: Provider (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str(reason, vals_abort_reason_provider, "Undefined"), reason); } else if (abortType == USER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: User (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"), reason); } break; case SEGMENTED_INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Invoke (%u)" ", Packet Sequence Number: %u", SEGMENTED_INVOKE, psn); break; case SEGMENTED_RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Result (%u)" ", Packet Sequence Number: %u", SEGMENTED_RESULT, psn); break; case NEGATIVE_ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); /* Iterate through missing packets */ for (i = 0; i < numMissing; i++) { proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN); } proto_item_append_text(ti, ", PDU: Negative Ack (%u)" ", Missing Packets: %u", NEGATIVE_ACK, numMissing); break; default: break; }; if (fRID) { proto_item_append_text(ti, ", Retransmission"); } } else { /* tree is NULL */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree); #endif } /* Process the variable part */ if (fCon) { /* Now, analyze variable part */ unsigned char tCon; unsigned char tByte; unsigned char tpiLen; tvbuff_t *tmp_tvb; vHeader = 0; /* Start scan all over */ do { tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader); tCon = tByte & 0x80; if (tByte & 0x04) /* Long TPI */ tpiLen = 2 + tvb_get_guint8(tvb, offCur + cbHeader + vHeader + 1); else tpiLen = 1 + (tByte & 0x03); if (tree) { tmp_tvb = tvb_new_subset(tvb, offCur + cbHeader + vHeader, tpiLen, tpiLen); wtp_handle_tpi(wtp_tree, tmp_tvb); } vHeader += tpiLen; } while (tCon); } else { /* There is no variable part */ } /* End of variable part of header */ /* Set the length of the WTP protocol part now we know the length of the * fixed and variable WTP headers */ if (tree) proto_item_set_len(ti, cbHeader + vHeader); #ifdef DEBUG fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader ); #endif /* * Any remaining data ought to be WSP data (if not WTP ACK, NACK * or ABORT pdu), so, if we have any remaining data, and it's * not an ACK, NACK, or ABORT PDU, hand it off (defragmented) to the * WSP dissector. * Note that the last packet of a fragmented WTP message needn't * contain any data, so we allow payloadless packets to be * reassembled. (XXX - does the reassembly code handle this * for packets other than the last packet?) * * Try calling a subdissector only if: * - The WTP payload is ressembled in this very packet, * - The WTP payload is not fragmented across packets. */ dataOffset = offCur + cbHeader + vHeader; dataLen = tvb_reported_length_remaining(tvb, dataOffset); if ((dataLen >= 0) && ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) { /* Try to reassemble if needed, and hand over to WSP * A fragmented WTP packet is either: * - An INVOKE with fTTR (transmission trailer) not set, * - a SEGMENTED_INVOKE, * - A RESULT with fTTR (transmission trailer) not set, * - a SEGMENTED_RESULT. */ if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) ) ) && tvb_bytes_exist(tvb, dataOffset, dataLen) ) { /* Try reassembling fragments */ fragment_data *fd_wtp = NULL; guint32 reassembled_in = 0; gboolean save_fragmented = pinfo->fragmented; pinfo->fragmented = TRUE; fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID, wtp_fragment_table, psn, dataLen, !fTTR); /* XXX - fragment_add_seq() yields NULL unless Wireshark knows * that the packet is part of a reassembled whole. This means * that fd_wtp will be NULL as long as Wireshark did not encounter * (and process) the packet containing the last fragment. * This implies that Wireshark needs two passes over the data for * correct reassembly. At the first pass, a capture containing * three fragments plus a retransmssion of the last fragment * will progressively show: * * Packet 1: (Unreassembled fragment 1) * Packet 2: (Unreassembled fragment 2) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * However at subsequent evaluation (e.g., by applying a display * filter) the packet summary will show: * * Packet 1: (WTP payload reassembled in packet 3) * Packet 2: (WTP payload reassembled in packet 3) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * This is important to know, and also affects read filters! */ wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo, "Reassembled WTP", fd_wtp, &wtp_frag_items, NULL, wtp_tree); #ifdef DEBUG printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n", pinfo->fd->num, fd_wtp ? "Reassembled" : "Not reassembled", fd_wtp ? fd_wtp->reassembled_in : -1, wsp_tvb, fd_wtp ); #endif if (fd_wtp) { /* Reassembled */ reassembled_in = fd_wtp->reassembled_in; if (pinfo->fd->num == reassembled_in) { /* Reassembled in this very packet: * We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Not reassembled in this packet */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "%s (WTP payload reassembled in packet %u)", szInfo, fd_wtp->reassembled_in); } if (tree) { proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, "Payload"); } } } else { /* Not reassembled yet, or not reassembled at all */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "%s (Unreassembled fragment %u)", szInfo, psn); } if (tree) { proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, "Payload"); } } /* Now reset fragmentation information in pinfo */ pinfo->fragmented = save_fragmented; } else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) ) { /* Non-fragmented payload */ wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset); /* We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Nothing to hand to subdissector */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, szInfo); } } else { /* Nothing to hand to subdissector */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, szInfo); } }