static int mpc_validate_xid()

in net/ctcm_mpc.c [1528:1643]


static int mpc_validate_xid(struct mpcg_info *mpcginfo)
{
	struct channel	   *ch	 = mpcginfo->ch;
	struct net_device  *dev  = ch->netdev;
	struct ctcm_priv   *priv = dev->ml_priv;
	struct mpc_group   *grp  = priv->mpcg;
	struct xid2	   *xid  = mpcginfo->xid;
	int	rc	 = 0;
	__u64	our_id   = 0;
	__u64   their_id = 0;
	int	len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;

	CTCM_PR_DEBUG("Enter %s: xid=%p\n", __func__, xid);

	if (xid == NULL) {
		rc = 1;
		/* XID REJECTED: xid == NULL */
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): xid = NULL",
				CTCM_FUNTAIL, ch->id);
			goto done;
	}

	CTCM_D3_DUMP((char *)xid, XID2_LENGTH);

	/*the received direction should be the opposite of ours  */
	if (((CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ? XID2_WRITE_SIDE :
				XID2_READ_SIDE) != xid->xid2_dlc_type) {
		rc = 2;
		/* XID REJECTED: r/w channel pairing mismatch */
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): r/w channel pairing mismatch",
				CTCM_FUNTAIL, ch->id);
			goto done;
	}

	if (xid->xid2_dlc_type == XID2_READ_SIDE) {
		CTCM_PR_DEBUG("%s: grpmaxbuf:%d xid2buflen:%d\n", __func__,
				grp->group_max_buflen, xid->xid2_buf_len);

		if (grp->group_max_buflen == 0 || grp->group_max_buflen >
						xid->xid2_buf_len - len)
			grp->group_max_buflen = xid->xid2_buf_len - len;
	}

	if (grp->saved_xid2 == NULL) {
		grp->saved_xid2 =
			(struct xid2 *)skb_tail_pointer(grp->rcvd_xid_skb);

		skb_put_data(grp->rcvd_xid_skb, xid, XID2_LENGTH);
		grp->rcvd_xid_skb->data = grp->rcvd_xid_data;

		skb_reset_tail_pointer(grp->rcvd_xid_skb);
		grp->rcvd_xid_skb->len = 0;

		/* convert two 32 bit numbers into 1 64 bit for id compare */
		our_id = (__u64)priv->xid->xid2_adj_id;
		our_id = our_id << 32;
		our_id = our_id + priv->xid->xid2_sender_id;
		their_id = (__u64)xid->xid2_adj_id;
		their_id = their_id << 32;
		their_id = their_id + xid->xid2_sender_id;
		/* lower id assume the xside role */
		if (our_id < their_id) {
			grp->roll = XSIDE;
			CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
				"%s(%s): WE HAVE LOW ID - TAKE XSIDE",
					CTCM_FUNTAIL, ch->id);
		} else {
			grp->roll = YSIDE;
			CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
				"%s(%s): WE HAVE HIGH ID - TAKE YSIDE",
					CTCM_FUNTAIL, ch->id);
		}

	} else {
		if (xid->xid2_flag4 != grp->saved_xid2->xid2_flag4) {
			rc = 3;
			/* XID REJECTED: xid flag byte4 mismatch */
			CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
				"%s(%s): xid flag byte4 mismatch",
					CTCM_FUNTAIL, ch->id);
		}
		if (xid->xid2_flag2 == 0x40) {
			rc = 4;
			/* XID REJECTED - xid NOGOOD */
			CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
				"%s(%s): xid NOGOOD",
					CTCM_FUNTAIL, ch->id);
		}
		if (xid->xid2_adj_id != grp->saved_xid2->xid2_adj_id) {
			rc = 5;
			/* XID REJECTED - Adjacent Station ID Mismatch */
			CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
				"%s(%s): Adjacent Station ID Mismatch",
					CTCM_FUNTAIL, ch->id);
		}
		if (xid->xid2_sender_id != grp->saved_xid2->xid2_sender_id) {
			rc = 6;
			/* XID REJECTED - Sender Address Mismatch */
			CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
				"%s(%s): Sender Address Mismatch",
					CTCM_FUNTAIL, ch->id);
		}
	}
done:
	if (rc) {
		dev_warn(&dev->dev,
			"The XID used in the MPC protocol is not valid, "
			"rc = %d\n", rc);
		priv->xid->xid2_flag2 = 0x40;
		grp->saved_xid2->xid2_flag2 = 0x40;
	}

	return rc;
}