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); }
static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb) { struct dn_scp *scp = &sk->protinfo.dn; unsigned short segnum; struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; int queued = 0; if (skb->len < 2) goto out; cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data); skb_pull(skb, 2); if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0fff) == (segnum & 0x0fff)) { if (dn_queue_skb(sk, skb, SIGURG, &scp->other_receive_queue) == 0) { sk->protinfo.dn.numoth_rcv++; scp->other_report = 0; queued = 1; } } dn_nsp_send_oth_ack(sk); out: if (!queued) kfree_skb(skb); }
void dn_nsp_delayed_ack(struct sock *sk) { struct dn_scp *scp = DN_SK(sk); if (scp->ackxmt_oth != scp->numoth_rcv) dn_nsp_send_oth_ack(sk); if (scp->ackxmt_dat != scp->numdat_rcv) dn_nsp_send_data_ack(sk); }
static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb) { struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; unsigned short segnum; unsigned char lsflags; char fcval; if (skb->len != 4) goto out; cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data); skb_pull(skb, 2); lsflags = *(unsigned char *)skb->data; skb_pull(skb, 1); fcval = *(char *)skb->data; if (lsflags & 0xf0) goto out; if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0FFF) == (segnum & 0x0FFF)) { sk->protinfo.dn.numoth_rcv += 1; switch(lsflags & 0x03) { case 0x00: break; case 0x01: sk->protinfo.dn.flowrem_sw = DN_DONTSEND; break; case 0x02: sk->protinfo.dn.flowrem_sw = DN_SEND; dn_nsp_output(sk); if (!sk->dead) sk->state_change(sk); } } dn_nsp_send_oth_ack(sk); out: kfree_skb(skb); }
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); }
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); }