1*6829Ssam 
2*6829Ssam #include "../h/param.h"
3*6829Ssam #include "../h/systm.h"
4*6829Ssam #include "../h/mbuf.h"
5*6829Ssam #include "../h/protosw.h"
6*6829Ssam #include "../h/socket.h"
7*6829Ssam #include "../h/socketvar.h"
8*6829Ssam #include "../net/dn_systm.h"
9*6829Ssam #include "../net/nsp.h"
10*6829Ssam #include "../net/nsp_var.h"
11*6829Ssam #include "../errno.h"
12*6829Ssam 
13*6829Ssam extern int nspidebug;
14*6829Ssam #define	printd	if(nspidebug)printf
15*6829Ssam 
16*6829Ssam /*
17*6829Ssam  * NSP initialization
18*6829Ssam  */
19*6829Ssam nsp_init()
20*6829Ssam {
21*6829Ssam 	init queues
22*6829Ssam 	what else?
23*6829Ssam }
24*6829Ssam 
25*6829Ssam /*
26*6829Ssam  * Nsp_chkaddr performs many functions common to the processing
27*6829Ssam  * of input packets.  The arguments are:
28*6829Ssam  *	m	- the mbuf with the packet in it
29*6829Ssam  *	srcnode	- the srcnode from the transport header
30*6829Ssam  *	type	- the packet type, one of:
31*6829Ssam  *		  NSP_DATA, NSP_LS, NSP_INTR, NSP_DATACK, NSP_OTHACK
32*6829Ssam  *	sp	- pointer to a short to receive the segment number
33*6829Ssam  *
34*6829Ssam  * It performs the following functions:
35*6829Ssam  *	1. verify that the packet is of the correct minimum length
36*6829Ssam  *	2. find the associated NSP control block (by calling dn_addrtonspcb())
37*6829Ssam  *	3. process any ack or nak and force retransmission or remove
38*6829Ssam  *		acked data from the retransmit queue, as required
39*6829Ssam  *	4. update the mbuf to point past the segnum field
40*6829Ssam  *	5. return the segnum and nspcb pointer
41*6829Ssam  */
42*6829Ssam struct nspcb *
43*6829Ssam nsp_chkaddr(m, srcnode, type, sp)
44*6829Ssam 	struct mbuf *m;
45*6829Ssam 	short srcnode;
46*6829Ssam 	int type;
47*6829Ssam 	u_short *sp;
48*6829Ssam {
49*6829Ssam 	register struct nspcb *np;
50*6829Ssam 	struct nspd *n;
51*6829Ssam 	u_short dstaddr;
52*6829Ssam 	int ack, qual, num;
53*6829Ssam 
54*6829Ssam 	/* make sure we are accessing valid data */
55*6829Ssam 	if (m->m_len < sizeof (struct nspd) - sizeof (d_short)) {
56*6829Ssam 		m_freem(m);
57*6829Ssam 		return (0);
58*6829Ssam 	}
59*6829Ssam 	n = mtod(m, struct nspd *);
60*6829Ssam 	dstaddr = D_SHORT(n->nsp_dstaddr);
61*6829Ssam 	np = dn_addrtonspcb(dstaddr);
62*6829Ssam 	if (np == 0) {
63*6829Ssam 		no such address, return "no link" message
64*6829Ssam 	}
65*6829Ssam 	if (np->n_node != srcnode) {
66*6829Ssam 		printf("nsp_chkaddr: n_node %d, srcnode %d\n", np->n_node,
67*6829Ssam 			scrnode);
68*6829Ssam 		m_freem(m);
69*6829Ssam 		return (0);
70*6829Ssam 	}
71*6829Ssam 	/* make sure remote addresses match (consistency check) */
72*6829Ssam 	if (np->n_rem != D_SHORT(n->nsp_srcaddr)) {
73*6829Ssam 		printf("nsp_chkaddr: n_rem %d, srcaddr %d\n", np->n_rem,
74*6829Ssam 			D_SHORT(n->nsp_srcaddr));
75*6829Ssam 		m_freem(m);
76*6829Ssam 		return (0);
77*6829Ssam 	}
78*6829Ssam 	ack = D_SHORT(n->nsp_acknum);
79*6829Ssam 	if (ack & NSPA_ACK) {
80*6829Ssam 		qual = ack & NSPA_QUAL;
81*6829Ssam 		num = ack & NSPA_NUM;
82*6829Ssam 		printd(", qual 0x%x, num %d", qual, num);
83*6829Ssam 		/* make sure there's room for a segnum */
84*6829Ssam 		if (m->m_len < sizeof (struct nspd)) {
85*6829Ssam 			m_freem(m);
86*6829Ssam 			return (0);
87*6829Ssam 		}
88*6829Ssam 		if (type == NSP_DATA) {
89*6829Ssam 			if (SEQ_GTR(num, np->na_rcvdat) &&
90*6829Ssam 			    SEQ_LEQ(num, np->nn_high)) {
91*6829Ssam 				np->n_retrans = 0;
92*6829Ssam 				np->nf_remdat -= SEQ_SUB(num, np->na_rcvdat);
93*6829Ssam 			}
94*6829Ssam 			if (qual == NSPA_NAK || SEQ_LEQ(np->nn_dat, num))
95*6829Ssam 				np->nn_dat = SEQ_ADD(num, 1);
96*6829Ssam 			np->na_rcvdat = num;
97*6829Ssam 			nsp_purgertq(np, type);
98*6829Ssam 		} else if (n == np->nn_oth && (np->n_flags&NF_OTHSENT)) {
99*6829Ssam 			if (qual == NSPA_NAK) {
100*6829Ssam 				/* force retransmission of other data seg */
101*6829Ssam 				printf("nsp_chkaddr: NAK other\n");
102*6829Ssam 			} else {
103*6829Ssam 				np->n_flags &= ~NF_OTHSENT;
104*6829Ssam 				np->nn_oth = SEQ_ADD(np->nn_oth, 1);
105*6829Ssam 				if (np->n_flags & NF_OTHINTR) {
106*6829Ssam 					np->n_flags &=
107*6829Ssam 					    ~(NF_OTHINTR|NF_INTAVAIL);
108*6829Ssam 					if (np->nb_xmt)
109*6829Ssam 						m_freem(np->nb_xmt);
110*6829Ssam 				} else
111*6829Ssam 					np->nf_locdat = 0;
112*6829Ssam 				nsp_purgertq(np, type);
113*6829Ssam 			}
114*6829Ssam 		}
115*6829Ssam 		*sp = D_SHORT(n->nsp_segnum);
116*6829Ssam 		num = sizeof (struct nspd);
117*6829Ssam 	} else {
118*6829Ssam 		*sp = (u_short)ack;
119*6829Ssam 		num = sizeof (struct nspd) - sizeof (u_short);
120*6829Ssam 	}
121*6829Ssam 	m->m_len -= num;
122*6829Ssam 	m->m_off += num;
123*6829Ssam 	return (np);
124*6829Ssam }
125