Beispiel #1
0
static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	unsigned short segnum;
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	int queued = 0;

	if (skb->len < 2)
		goto out;

	cb->segnum = segnum = le16_to_cpu(*(__le16 *)skb->data);
	skb_pull(skb, 2);

	if (seq_next(scp->numoth_rcv, segnum)) {

		if (dn_queue_skb(sk, skb, SIGURG, &scp->other_receive_queue) == 0) {
			seq_add(&scp->numoth_rcv, 1);
			scp->other_report = 0;
			queued = 1;
		}
	}

	dn_nsp_send_oth_ack(sk);
out:
	if (!queued)
		kfree_skb(skb);
}
Beispiel #2
0
static void dn_nsp_data(struct sock *sk, struct sk_buff *skb)
{
	int queued = 0;
	unsigned short segnum;
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	struct dn_scp *scp = DN_SK(sk);

	if (skb->len < 2)
		goto out;

	cb->segnum = segnum = le16_to_cpu(*(__le16 *)skb->data);
	skb_pull(skb, 2);

	if (seq_next(scp->numdat_rcv, segnum)) {
		if (dn_queue_skb(sk, skb, SIGIO, &sk->sk_receive_queue) == 0) {
			seq_add(&scp->numdat_rcv, 1);
			queued = 1;
		}

		if ((scp->flowloc_sw == DN_SEND) && dn_congested(sk)) {
			scp->flowloc_sw = DN_DONTSEND;
			dn_nsp_send_link(sk, DN_DONTSEND, 0);
		}
	}

	dn_nsp_send_data_ack(sk);
out:
	if (!queued)
		kfree_skb(skb);
}
static __le16 *dn_nsp_mk_data_header(struct sock *sk, struct sk_buff *skb, int oth)
{
	struct dn_scp *scp = DN_SK(sk);
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	__le16 *ptr = dn_mk_ack_header(sk, skb, cb->nsp_flags, 11, oth);

	if (unlikely(oth)) {
		cb->segnum = scp->numoth;
		seq_add(&scp->numoth, 1);
	} else {
		cb->segnum = scp->numdat;
		seq_add(&scp->numdat, 1);
	}
	*(ptr++) = cpu_to_le16(cb->segnum);

	return ptr;
}
Beispiel #4
0
static int 
RoErrorRequestAux (struct assocblk *acb, int invokeID, int error, PE params, int priority, struct RoSAPindication *roi)
{
	PE	pe,
			 p;

	if ((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_ROS))
		return rosaplose (roi, ROS_OPERATION, NULLCP, "not responder");
	if (!(acb -> acb_flags & ACB_ACS)) {
		missingP (params);
	}

	if (acb -> acb_ready
			&& !(acb -> acb_flags & ACB_TURN)
			&& (*acb -> acb_ready) (acb, priority, roi) == NOTOK)
		return NOTOK;

	/* begin Error APDU */
	if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_ERROR)) == NULLPE
			|| ((acb -> acb_flags & ACB_ACS)
				? (p = pe, 0)
				: set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS,
								   PE_CONS_SEQ)) == NOTOK)
			|| seq_add (p, int2prim (invokeID), -1) == NOTOK
			|| seq_add (p, int2prim (error), -1) == NOTOK
			|| (params && seq_add (p, params, -1) == NOTOK)) {
		if (pe) {
			if (params)
				 pe_extract (pe, params);
			pe_free (pe);
		}
		freeacblk (acb);
		return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
	}
	/* end Error APDU */

	return (*acb -> acb_putosdu) (acb, pe, params, priority, roi);
}
Beispiel #5
0
int 
RoURejectRequestAux (struct assocblk *acb, int *invokeID, int reason, int id, int priority, struct RoSAPindication *roi)
{
	PE pe,
			 p;

	if (id == REJECT_COMPLETE)
		if (acb -> acb_flags & ACB_ACS)
			id = REJECT_INVOKE;
		else
			return rosaplose (roi, ROS_PARAMETER, NULLCP,
							  "bad value for reason parameter");

	if (acb -> acb_ready
			&& !(acb -> acb_flags & ACB_TURN)
			&& (*acb -> acb_ready) (acb, priority, roi) == NOTOK)
		return NOTOK;

	/* begin Reject APDU */
	if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_REJECT)) == NULLPE
			|| ((acb -> acb_flags & ACB_ACS)
				? (p = pe, 0)
				: set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS,
								   PE_CONS_SEQ)) == NOTOK)
			|| seq_add (p, invokeID ? int2prim (*invokeID)
						: pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
									PE_PRIM_NULL), -1) == NOTOK
			|| seq_add (p, num2prim ((integer) reason, PE_CLASS_CONT, id), -1)
			== NOTOK) {
		if (pe)
			pe_free (pe);
		freeacblk (acb);
		return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
	}
	/* end Reject APDU */

	return (*acb -> acb_putosdu) (acb, pe, NULLPE, priority, roi);
}
Beispiel #6
0
static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	unsigned short segnum;
	unsigned char lsflags;
	signed char fcval;
	int wake_up = 0;
	char *ptr = skb->data;
	unsigned char fctype = scp->services_rem & NSP_FC_MASK;

	if (skb->len != 4)
		goto out;

	segnum = le16_to_cpu(*(__le16 *)ptr);
	ptr += 2;
	lsflags = *(unsigned char *)ptr++;
	fcval = *ptr;

	/*
	 * Here we ignore erronous packets which should really
	 * should cause a connection abort. It is not critical
	 * for now though.
	 */
	if (lsflags & 0xf8)
		goto out;

	if (seq_next(scp->numoth_rcv, segnum)) {
		seq_add(&scp->numoth_rcv, 1);
		switch(lsflags & 0x04) { /* FCVAL INT */
		case 0x00: /* Normal Request */
			switch(lsflags & 0x03) { /* FCVAL MOD */
			case 0x00: /* Request count */
				if (fcval < 0) {
					unsigned char p_fcval = -fcval;
					if ((scp->flowrem_dat > p_fcval) &&
					    (fctype == NSP_FC_SCMC)) {
						scp->flowrem_dat -= p_fcval;
					}
				} else if (fcval > 0) {
					scp->flowrem_dat += fcval;
					wake_up = 1;
				}
				break;
			case 0x01: /* Stop outgoing data */
				scp->flowrem_sw = DN_DONTSEND;
				break;
			case 0x02: /* Ok to start again */
				scp->flowrem_sw = DN_SEND;
				dn_nsp_output(sk);
				wake_up = 1;
			}
			break;
		case 0x04: /* Interrupt Request */
			if (fcval > 0) {
				scp->flowrem_oth += fcval;
				wake_up = 1;
			}
			break;
		}
		if (wake_up && !sock_flag(sk, SOCK_DEAD))
			sk->sk_state_change(sk);
	}

	dn_nsp_send_oth_ack(sk);

out:
	kfree_skb(skb);
}
Beispiel #7
0
static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	unsigned short segnum;
	unsigned char lsflags;
	signed char fcval;
	int wake_up = 0;
	char *ptr = skb->data;
	unsigned char fctype = scp->services_rem & NSP_FC_MASK;

	if (skb->len != 4)
		goto out;

	segnum = le16_to_cpu(*(__le16 *)ptr);
	ptr += 2;
	lsflags = *(unsigned char *)ptr++;
	fcval = *ptr;

	
	if (lsflags & 0xf8)
		goto out;

	if (seq_next(scp->numoth_rcv, segnum)) {
		seq_add(&scp->numoth_rcv, 1);
		switch(lsflags & 0x04) { 
		case 0x00: 
			switch(lsflags & 0x03) { 
			case 0x00: 
				if (fcval < 0) {
					unsigned char p_fcval = -fcval;
					if ((scp->flowrem_dat > p_fcval) &&
					    (fctype == NSP_FC_SCMC)) {
						scp->flowrem_dat -= p_fcval;
					}
				} else if (fcval > 0) {
					scp->flowrem_dat += fcval;
					wake_up = 1;
				}
				break;
			case 0x01: 
				scp->flowrem_sw = DN_DONTSEND;
				break;
			case 0x02: 
				scp->flowrem_sw = DN_SEND;
				dn_nsp_output(sk);
				wake_up = 1;
			}
			break;
		case 0x04: 
			if (fcval > 0) {
				scp->flowrem_oth += fcval;
				wake_up = 1;
			}
			break;
		}
		if (wake_up && !sock_flag(sk, SOCK_DEAD))
			sk->sk_state_change(sk);
	}

	dn_nsp_send_oth_ack(sk);

out:
	kfree_skb(skb);
}
Beispiel #8
0
static int 
RoResultRequestAux (struct assocblk *acb, int invokeID, int op, PE result, int priority, struct RoSAPindication *roi)
{
	PE pe,
			 p,
			 q;

	if ((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_ROS))
		return rosaplose (roi, ROS_OPERATION, NULLCP, "not responder");
	if (!(acb -> acb_flags & ACB_ACS)) {
		missingP (result);
	}

	if (acb -> acb_ready
			&& !(acb -> acb_flags & ACB_TURN)
			&& (*acb -> acb_ready) (acb, priority, roi) == NOTOK)
		return NOTOK;

#ifdef notyet
	if (!(acb -> acb_flags & ACB_ACS)) { /* want OPDU */
		struct type_ROS_OPDU opdu;
		struct type_ROS_ReturnResult rrs;
		struct type_ROS_InvokeIDType idtyp;

		opdu.offset = type_ROS_OPDU_2;
		opdu.un.choice_ROS_9 = &rrs;
		rrs.invokeID = &idtyp;
		rrs.result = result;
		idtyp.parm = invokeID;

		if (encode_ROS_OPDU(&pe, 1, 0, NULL, &opdu) == NOTOK) {
			abort();
			goto fail;
		}
	} else {
		struct type_ROS_ROSEapdus apdu;
		struct type_ROS_RORSapdu ras;
		struct type_ROS_InvokeIDType idtyp;
		struct element_ROS_1 el1;
		struct type_ROS_Operation ops;

		apdu.offset = type_ROS_ROSEapdus_rors__apdu;
		apdu.un.rors__apdu = &ras;
		idtyp.parm = invokeID;
		ras.invokeID = &idtyp;
		if (result) {
			ras.element_ROS_0 = &el1;
			el1.operation__value = &ops;
			ops.parm = op;
			el1.result = result;
		} else
			ras.element_ROS_0 = (struct element_ROS_1 *)0;

		if (encode_ROS_ROSEapdus(&pe, 1, 0, NULL, &apdu) == NOTOK) {
fail:
			if (pe) {
				 pe_extract (pe, result);
				pe_free (pe);
			}
			freeacblk (acb);
			return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
		}
	}

#endif

	/* begin Result APDU */
	if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_RESULT)) == NULLPE
			|| ((acb -> acb_flags & ACB_ACS)
				? (p = pe, 0)
				: set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS,
								   PE_CONS_SEQ)) == NOTOK)
			|| seq_add (p, int2prim (invokeID), -1) == NOTOK
			|| ((acb -> acb_flags & ACB_ACS)
				? (result
				   && (seq_add (p, q = pe_alloc (PE_CLASS_UNIV,
									   PE_FORM_CONS,
									   PE_CONS_SEQ),
								-1) == NOTOK
					   || seq_add (q, int2prim (op), -1) == NOTOK
					   || seq_add (q, result, -1) == NOTOK))
				: seq_add (p, result, -1) == NOTOK)) {
		if (pe) {
			 pe_extract (pe, result);
			pe_free (pe);
		}
		freeacblk (acb);
		return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
	}
	/* end Result APDU */

	return (*acb -> acb_putosdu) (acb, pe, result, priority, roi);
}