示例#1
0
/*
 * State machine for state 1, Awaiting Connection State.
 * The handling of the timer(s) is in file nr_timer.c.
 * Handling of state 0 and connection release is in netrom.c.
 */
static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
	switch (frametype) {

		case NR_CONNACK:
			nr_stop_t1timer(sk);
			nr_start_idletimer(sk);
			sk->protinfo.nr->your_index = skb->data[17];
			sk->protinfo.nr->your_id    = skb->data[18];
			sk->protinfo.nr->vs         = 0;
			sk->protinfo.nr->va         = 0;
			sk->protinfo.nr->vr         = 0;
			sk->protinfo.nr->vl	    = 0;
			sk->protinfo.nr->state      = NR_STATE_3;
			sk->protinfo.nr->n2count    = 0;
			sk->protinfo.nr->window     = skb->data[20];
			sk->state                   = TCP_ESTABLISHED;
			if (!sk->dead)
				sk->state_change(sk);
			break;

		case NR_CONNACK | NR_CHOKE_FLAG:
			nr_disconnect(sk, ECONNREFUSED);
			break;

		default:
			break;
	}

	return 0;
}
示例#2
0
static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
{
	struct sk_buff *skbo, *skbn = skb;

	skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);

	nr_start_idletimer(sk);

	if (more) {
		sk->protinfo.nr->fraglen += skb->len;
		skb_queue_tail(&sk->protinfo.nr->frag_queue, skb);
		return 0;
	}

	if (!more && sk->protinfo.nr->fraglen > 0) {	/* End of fragment */
		sk->protinfo.nr->fraglen += skb->len;
		skb_queue_tail(&sk->protinfo.nr->frag_queue, skb);

		if ((skbn = alloc_skb(sk->protinfo.nr->fraglen, GFP_ATOMIC)) == NULL)
			return 1;

		skbn->h.raw = skbn->data;

		while ((skbo = skb_dequeue(&sk->protinfo.nr->frag_queue)) != NULL) {
			memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
			kfree_skb(skbo);
		}

		sk->protinfo.nr->fraglen = 0;		
	}

	return sock_queue_rcv_skb(sk, skbn);
}
示例#3
0
static void nr_send_iframe(struct sock *sk, struct sk_buff *skb)
{
	struct nr_sock *nr = nr_sk(sk);

	if (skb == NULL)
		return;

	skb->data[2] = nr->vs;
	skb->data[3] = nr->vr;

	if (nr->condition & NR_COND_OWN_RX_BUSY)
		skb->data[4] |= NR_CHOKE_FLAG;

	nr_start_idletimer(sk);

	nr_transmit_buffer(sk, skb);
}
示例#4
0
文件: nr_in.c 项目: CSCLOG/beaglebone
/*
 * State machine for state 1, Awaiting Connection State.
 * The handling of the timer(s) is in file nr_timer.c.
 * Handling of state 0 and connection release is in netrom.c.
 */
static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
	int frametype)
{
	switch (frametype) {
	case NR_CONNACK: {
		struct nr_sock *nr = nr_sk(sk);

		nr_stop_t1timer(sk);
		nr_start_idletimer(sk);
		nr->your_index = skb->data[17];
		nr->your_id    = skb->data[18];
		nr->vs	       = 0;
		nr->va	       = 0;
		nr->vr	       = 0;
		nr->vl	       = 0;
		nr->state      = NR_STATE_3;
		nr->n2count    = 0;
		nr->window     = skb->data[20];
		sk->sk_state   = TCP_ESTABLISHED;
		if (!sock_flag(sk, SOCK_DEAD))
			sk->sk_state_change(sk);
		break;
	}

	case NR_CONNACK | NR_CHOKE_FLAG:
		nr_disconnect(sk, ECONNREFUSED);
		break;

	case NR_RESET:
		if (sysctl_netrom_reset_circuit)
			nr_disconnect(sk, ECONNRESET);
		break;

	default:
		break;
	}
	return 0;
}
示例#5
0
文件: nr_in.c 项目: CSCLOG/beaglebone
static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
{
	struct sk_buff *skbo, *skbn = skb;
	struct nr_sock *nr = nr_sk(sk);

	skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);

	nr_start_idletimer(sk);

	if (more) {
		nr->fraglen += skb->len;
		skb_queue_tail(&nr->frag_queue, skb);
		return 0;
	}

	if (!more && nr->fraglen > 0) {	/* End of fragment */
		nr->fraglen += skb->len;
		skb_queue_tail(&nr->frag_queue, skb);

		if ((skbn = alloc_skb(nr->fraglen, GFP_ATOMIC)) == NULL)
			return 1;

		skb_reset_transport_header(skbn);

		while ((skbo = skb_dequeue(&nr->frag_queue)) != NULL) {
			skb_copy_from_linear_data(skbo,
						  skb_put(skbn, skbo->len),
						  skbo->len);
			kfree_skb(skbo);
		}

		nr->fraglen = 0;
	}

	return sock_queue_rcv_skb(sk, skbn);
}