/** * dissect_content_length_vle is a utility function which * calculates how long is the payload section of the message * in bytes which is VLE encoded. * * @see dissect_packetid() * @see dissect_reliable_message_index_base() * @see dissect_reliable_message_number() * @see dissect_messageid() * @see dissect_payload() * @param buffer the buffer to the data * @param offset the offset where to start reading the data * @param tree the parent tree where the dissected data is going to be inserted * @return int returns the content length of the packet * */ static int dissect_content_length_vle(tvbuff_t *buffer, int *offset, proto_tree *tree) { int byte_count; guint32 length; length = 0; byte_count = count_vle_bytes(buffer, *offset); switch(byte_count) /*We must calculate length by hand because we use the length later */ { case 4: length = tvb_get_guint8(buffer, (*offset) + 3) << 23; length += (tvb_get_guint8(buffer, (*offset) + 2) << 15); /* FALLTHRU */ case 2: length += (tvb_get_guint8(buffer, (*offset) + 1) << 7); /* FALLTHRU */ case 1: length += (tvb_get_guint8(buffer, (*offset)) & 0x7F); break; default: REPORT_DISSECTOR_BUG("Error in Content Length calculation"); break; } proto_tree_add_uint(tree, hf_knet_content_length_vle, buffer, (*offset), byte_count, length); (*offset) += byte_count; return length; }
int PIDL_dissect_uint32 (tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, guint8 *drep, int hfindex, guint32 param) { dcerpc_info *di; guint32 val; di=pinfo->private_data; if(di->conformant_run){ /* just a run to handle conformant arrays, no scalars to dissect */ return offset; } if (offset % 4) { offset += 4 - (offset % 4); } offset=dissect_dcerpc_uint32 (tvb, offset, pinfo, tree, drep, hfindex, &val); if(param&PIDL_SET_COL_INFO){ header_field_info *hf_info; char *valstr; hf_info=proto_registrar_get_nth(hfindex); valstr=ep_alloc(64); valstr[0]=0; switch(hf_info->display){ case BASE_DEC: if(hf_info->strings){ g_snprintf(valstr, 64, "%s(%d)",val_to_str(val, hf_info->strings, "Unknown:%u"), val); } else { g_snprintf(valstr, 64, "%d", val); } break; case BASE_HEX: if(hf_info->strings){ g_snprintf(valstr, 64, "%s(0x%08x)",val_to_str(val, hf_info->strings, "Unknown:%u"), val); } else { g_snprintf(valstr, 64, "0x%08x", val); } break; default: REPORT_DISSECTOR_BUG("Invalid hf->display value"); } if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); } } return offset; }
int PIDL_dissect_uint16_val(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex, guint32 param, guint16 *pval) { guint16 val; if (di->conformant_run) { /* just a run to handle conformant arrays, no scalars to dissect */ return offset; } if (!di->no_align && (offset % 2)) { offset++; } offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hfindex, &val); if (param&PIDL_SET_COL_INFO) { header_field_info *hf_info; char *valstr; hf_info = proto_registrar_get_nth(hfindex); valstr = (char *)wmem_alloc(wmem_packet_scope(), 64); valstr[0]=0; switch (hf_info->display) { case BASE_DEC: if (hf_info->strings) { g_snprintf(valstr, 64, "%s(%d)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); } else { g_snprintf(valstr, 64, "%d", val); } break; case BASE_HEX: if (hf_info->strings) { g_snprintf(valstr, 64, "%s(0x%04x)",val_to_str(val, (const value_string *)hf_info->strings, "Unknown:%u"), val); } else { g_snprintf(valstr, 64, "0x%04x", val); } break; default: REPORT_DISSECTOR_BUG("Invalid hf->display value"); } col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, valstr); } if (pval) { *pval = val; } return offset; }
/* * Main dissection routine. */ static gboolean dissect_iwarp_mpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { tvbuff_t *next_tvb = NULL; conversation_t *conversation = NULL; mpa_state_t *state = NULL; struct tcpinfo *tcpinfo; guint8 endpoint = 3; guint16 ulpdu_length = 0; if (data == NULL) return FALSE; tcpinfo = (struct tcpinfo *)data; /* FPDU */ if (tvb_length(tvb) >= MPA_SMALLEST_FPDU_LEN && is_mpa_fpdu(pinfo)) { conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); state = get_mpa_state(conversation); if (pinfo->srcport == state->minfo[MPA_INITIATOR].port) { endpoint = MPA_INITIATOR; } else if (pinfo->srcport == state->minfo[MPA_RESPONDER].port) { endpoint = MPA_RESPONDER; } else { REPORT_DISSECTOR_BUG("endpoint cannot be determined"); } /* Markers are used by either the Initiator or the Responder or both. */ if ((state->ini_exp_m_res || state->res_exp_m_ini) && endpoint <= MPA_RESPONDER) { /* find the TCP sequence number of the first FPDU */ if (!state->minfo[endpoint].valid) { state->minfo[endpoint].seq = tcpinfo->seq; state->minfo[endpoint].valid = TRUE; } } /* dissect FPDU */ ulpdu_length = dissect_mpa_fpdu(tvb, pinfo, tree, state, tcpinfo, endpoint); /* an ulpdu_length of 0 should never happen */ if (!ulpdu_length) return FALSE; /* removes Markers if any and prepares new tvbuff for next dissector */ if (endpoint <= MPA_RESPONDER && state->minfo[endpoint].valid && number_of_markers(state, tcpinfo, endpoint) > 0) { next_tvb = tvb_new_subset_length(remove_markers(tvb, pinfo, get_first_marker_offset(state, tcpinfo, endpoint), number_of_markers(state, tcpinfo, endpoint), fpdu_total_length(tcpinfo)), MPA_ULPDU_LENGTH_LEN, ulpdu_length); } else { next_tvb = tvb_new_subset_length(tvb, MPA_ULPDU_LENGTH_LEN, ulpdu_length); } /* call subdissector */ if (ddp_rdmap_handle) { call_dissector(ddp_rdmap_handle, next_tvb, pinfo, tree); } else { REPORT_DISSECTOR_BUG("ddp_handle was null"); } return TRUE; } /* MPA REQUEST or MPA REPLY */ if (tvb_length(tvb) >= MPA_REQ_REP_FRAME_HEADER_LEN) { if (is_mpa_req(tvb, pinfo)) return dissect_mpa_req_rep(tvb, pinfo, tree, MPA_REQUEST_FRAME); else if (is_mpa_rep(tvb, pinfo)) return dissect_mpa_req_rep(tvb, pinfo, tree, MPA_REPLY_FRAME); } return FALSE; }