コード例 #1
0
ファイル: dn_nsp_in.c プロジェクト: AlexShiLucky/linux
/*
 * This is the main receive routine for sockets. It is called
 * from the above when the socket is not busy, and also from
 * sock_release() when there is a backlog queued up.
 */
int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	struct dn_skb_cb *cb = DN_SKB_CB(skb);

	if (cb->rt_flags & DN_RT_F_RTS) {
		if (cb->nsp_flags == 0x18 || cb->nsp_flags == 0x68)
			dn_returned_conn_init(sk, skb);
		else
			kfree_skb(skb);
		return NET_RX_SUCCESS;
	}

	/*
	 * Control packet.
	 */
	if ((cb->nsp_flags & 0x0c) == 0x08) {
		switch (cb->nsp_flags & 0x70) {
		case 0x10:
		case 0x60:
			dn_nsp_conn_init(sk, skb);
			break;
		case 0x20:
			dn_nsp_conn_conf(sk, skb);
			break;
		case 0x30:
			dn_nsp_disc_init(sk, skb);
			break;
		case 0x40:
			dn_nsp_disc_conf(sk, skb);
			break;
		}

	} else if (cb->nsp_flags == 0x24) {
		/*
		 * Special for connacks, 'cos they don't have
		 * ack data or ack otherdata info.
		 */
		dn_nsp_conn_ack(sk, skb);
	} else {
		int other = 1;

		/* both data and ack frames can kick a CC socket into RUN */
		if ((scp->state == DN_CC) && !sock_flag(sk, SOCK_DEAD)) {
			scp->state = DN_RUN;
			sk->sk_state = TCP_ESTABLISHED;
			sk->sk_state_change(sk);
		}

		if ((cb->nsp_flags & 0x1c) == 0)
			other = 0;
		if (cb->nsp_flags == 0x04)
			other = 0;

		/*
		 * Read out ack data here, this applies equally
		 * to data, other data, link serivce and both
		 * ack data and ack otherdata.
		 */
		dn_process_ack(sk, skb, other);

		/*
		 * If we've some sort of data here then call a
		 * suitable routine for dealing with it, otherwise
		 * the packet is an ack and can be discarded.
		 */
		if ((cb->nsp_flags & 0x0c) == 0) {

			if (scp->state != DN_RUN)
				goto free_out;

			switch (cb->nsp_flags) {
			case 0x10: /* LS */
				dn_nsp_linkservice(sk, skb);
				break;
			case 0x30: /* OD */
				dn_nsp_otherdata(sk, skb);
				break;
			default:
				dn_nsp_data(sk, skb);
			}

		} else { /* Ack, chuck it out here */
free_out:
			kfree_skb(skb);
		}
	}

	return NET_RX_SUCCESS;
}
コード例 #2
0
int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	struct dn_skb_cb *cb = DN_SKB_CB(skb);

	if (cb->rt_flags & DN_RT_F_RTS) {
		if (cb->nsp_flags == 0x18 || cb->nsp_flags == 0x68)
			dn_returned_conn_init(sk, skb);
		else
			kfree_skb(skb);
		return NET_RX_SUCCESS;
	}

	
	if ((cb->nsp_flags & 0x0c) == 0x08) {
		switch(cb->nsp_flags & 0x70) {
			case 0x10:
			case 0x60:
				dn_nsp_conn_init(sk, skb);
				break;
			case 0x20:
				dn_nsp_conn_conf(sk, skb);
				break;
			case 0x30:
				dn_nsp_disc_init(sk, skb);
				break;
			case 0x40:
				dn_nsp_disc_conf(sk, skb);
				break;
		}

	} else if (cb->nsp_flags == 0x24) {
		
		dn_nsp_conn_ack(sk, skb);
	} else {
		int other = 1;

		
		if ((scp->state == DN_CC) && !sock_flag(sk, SOCK_DEAD)) {
			scp->state = DN_RUN;
			sk->sk_state = TCP_ESTABLISHED;
			sk->sk_state_change(sk);
		}

		if ((cb->nsp_flags & 0x1c) == 0)
			other = 0;
		if (cb->nsp_flags == 0x04)
			other = 0;

		
		dn_process_ack(sk, skb, other);

		
		if ((cb->nsp_flags & 0x0c) == 0) {

			if (scp->state != DN_RUN)
				goto free_out;

			switch(cb->nsp_flags) {
				case 0x10: 
					dn_nsp_linkservice(sk, skb);
					break;
				case 0x30: 
					dn_nsp_otherdata(sk, skb);
					break;
				default:
					dn_nsp_data(sk, skb);
			}

		} else { 
free_out:
			kfree_skb(skb);
		}
	}

	return NET_RX_SUCCESS;
}