Esempio n. 1
0
/* returns TRUE if this TCP segment carries a MPA FPDU and FALSE otherwise */
static gboolean
is_mpa_fpdu(packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;

	conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			&pinfo->dst, pinfo->ptype, pinfo->srcport,
			pinfo->destport, 0);

	if (!conversation) {
		return FALSE;
	}

	state = get_mpa_state(conversation);
	if (!state) {
		return FALSE;
	}

	/* make sure all MPA connection parameters have been set */
	if (!state->full_operation) {
		return FALSE;
	}

	if (pinfo->fd->num == state->req_frame_num
			|| pinfo->fd->num == state->rep_frame_num) {
		return FALSE;
	} else {
		return TRUE;
	}
}
Esempio n. 2
0
/* returns TRUE if this TCP segment carries a MPA REQUEST and FLASE otherwise */
static gboolean
is_mpa_req(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REQ_FRAME)
		return FALSE;

	conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			&pinfo->dst, pinfo->ptype, pinfo->srcport,
			pinfo->destport, 0);

	if (!conversation) {
		conversation = conversation_new(pinfo->fd->num, &pinfo->src,
				&pinfo->dst, pinfo->ptype, pinfo->srcport,
				pinfo->destport, 0);
	}

	if (!get_mpa_state(conversation)) {

		/* associate a MPA connection state to this conversation if
		 * there is no MPA state already associated to this connection
		 */
		state = init_mpa_state();

		/* anaylize MPA connection parameter and record them */
		mcrres = tvb_get_guint8(tvb, 16);
		state->ini_exp_m_res = mcrres & MPA_MARKER_FLAG;
		state->crc = mcrres & MPA_CRC_FLAG;
		state->revision = tvb_get_guint8(tvb, 17);
		state->req_frame_num = pinfo->fd->num;
		state->minfo[MPA_INITIATOR].port = pinfo->srcport;
		state->minfo[MPA_RESPONDER].port = pinfo->destport;

		conversation_add_proto_data(conversation, proto_iwarp_mpa, state);

		/* update expert info */
		if (mcrres & MPA_RESERVED_FLAG)
			expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN,
					"Res field is NOT set to zero as required by RFC 5044");

		if (state->revision != 1)
			expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN,
					"Rev field is NOT set to one as required by RFC 5044");
	}
	return TRUE;
}
Esempio n. 3
0
/* returns TRUE if this TCP segment carries a MPA REPLY and FALSE otherwise */
static gboolean
is_mpa_rep(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REP_FRAME) {
		return FALSE;
	}

	conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			&pinfo->dst, pinfo->ptype, pinfo->srcport,
			pinfo->destport, 0);

	if (!conversation) {
		return FALSE;
	}

	state = get_mpa_state(conversation);
	if (!state) {
		return FALSE;
	}

	if (!state->full_operation) {
		/* update state of this conversation */
		mcrres = tvb_get_guint8(tvb, 16);
		state->res_exp_m_ini = mcrres & MPA_MARKER_FLAG;
		state->crc = state->crc | (mcrres & MPA_CRC_FLAG);
		state->rep_frame_num = pinfo->fd->num;

		 /* enter Full Operation Phase only if the Reject bit is not set */
		if (!(mcrres & MPA_REJECT_FLAG))
			state->full_operation = TRUE;
		else
			expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_NOTE,
				"Reject bit set by Responder");
	}
	return TRUE;
}
Esempio n. 4
0
/* returns TRUE if this TCP segment carries a MPA REQUEST and FLASE otherwise */
static gboolean
is_mpa_req(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REQ_FRAME)
		return FALSE;

	conversation = find_or_create_conversation(pinfo);

	if (!get_mpa_state(conversation)) {

		/* associate a MPA connection state to this conversation if
		 * there is no MPA state already associated to this connection
		 */
		state = init_mpa_state();

		/* anaylize MPA connection parameter and record them */
		mcrres = tvb_get_guint8(tvb, 16);
		state->ini_exp_m_res = mcrres & MPA_MARKER_FLAG;
		state->crc = mcrres & MPA_CRC_FLAG;
		state->revision = tvb_get_guint8(tvb, 17);
		state->req_frame_num = pinfo->fd->num;
		state->minfo[MPA_INITIATOR].port = pinfo->srcport;
		state->minfo[MPA_RESPONDER].port = pinfo->destport;

		conversation_add_proto_data(conversation, proto_iwarp_mpa, state);

		/* update expert info */
		if (mcrres & MPA_RESERVED_FLAG)
			expert_add_info(pinfo, NULL, &ei_mpa_res_field_not_set0);

		if (state->revision != 1)
			expert_add_info(pinfo, NULL, &ei_mpa_rev_field_not_set1);
	}
	return TRUE;
}
Esempio n. 5
0
/*
 * 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;
}