1*8409Swnj /*	nsp_subr.c	1.3	82/10/09	*/
26829Ssam 
36829Ssam #include "../h/param.h"
46829Ssam #include "../h/systm.h"
56829Ssam #include "../h/mbuf.h"
66829Ssam #include "../h/protosw.h"
76829Ssam #include "../h/socket.h"
86829Ssam #include "../h/socketvar.h"
9*8409Swnj #include "../netdecnet/dn_systm.h"
10*8409Swnj #include "../netdecnet/nsp.h"
11*8409Swnj #include "../netdecnet/nsp_var.h"
12*8409Swnj #include <errno.h>
136829Ssam 
146829Ssam extern int nspidebug;
156829Ssam #define	printd	if(nspidebug)printf
166829Ssam 
176829Ssam /*
186829Ssam  * NSP initialization
196829Ssam  */
nsp_init()206829Ssam nsp_init()
216829Ssam {
226829Ssam 	init queues
236829Ssam 	what else?
246829Ssam }
256829Ssam 
266829Ssam /*
276829Ssam  * Nsp_chkaddr performs many functions common to the processing
286829Ssam  * of input packets.  The arguments are:
296829Ssam  *	m	- the mbuf with the packet in it
306829Ssam  *	srcnode	- the srcnode from the transport header
316829Ssam  *	type	- the packet type, one of:
326829Ssam  *		  NSP_DATA, NSP_LS, NSP_INTR, NSP_DATACK, NSP_OTHACK
336829Ssam  *	sp	- pointer to a short to receive the segment number
346829Ssam  *
356829Ssam  * It performs the following functions:
366829Ssam  *	1. verify that the packet is of the correct minimum length
376829Ssam  *	2. find the associated NSP control block (by calling dn_addrtonspcb())
386829Ssam  *	3. process any ack or nak and force retransmission or remove
396829Ssam  *		acked data from the retransmit queue, as required
406829Ssam  *	4. update the mbuf to point past the segnum field
416829Ssam  *	5. return the segnum and nspcb pointer
426829Ssam  */
436829Ssam struct nspcb *
nsp_chkaddr(m,srcnode,type,sp)446829Ssam nsp_chkaddr(m, srcnode, type, sp)
456829Ssam 	struct mbuf *m;
466829Ssam 	short srcnode;
476829Ssam 	int type;
486829Ssam 	u_short *sp;
496829Ssam {
506829Ssam 	register struct nspcb *np;
516829Ssam 	struct nspd *n;
526829Ssam 	u_short dstaddr;
536829Ssam 	int ack, qual, num;
546829Ssam 
556829Ssam 	/* make sure we are accessing valid data */
566829Ssam 	if (m->m_len < sizeof (struct nspd) - sizeof (d_short)) {
576829Ssam 		m_freem(m);
586829Ssam 		return (0);
596829Ssam 	}
606829Ssam 	n = mtod(m, struct nspd *);
616829Ssam 	dstaddr = D_SHORT(n->nsp_dstaddr);
626829Ssam 	np = dn_addrtonspcb(dstaddr);
636829Ssam 	if (np == 0) {
646829Ssam 		no such address, return "no link" message
656829Ssam 	}
666829Ssam 	if (np->n_node != srcnode) {
676829Ssam 		printf("nsp_chkaddr: n_node %d, srcnode %d\n", np->n_node,
686829Ssam 			scrnode);
696829Ssam 		m_freem(m);
706829Ssam 		return (0);
716829Ssam 	}
726829Ssam 	/* make sure remote addresses match (consistency check) */
736829Ssam 	if (np->n_rem != D_SHORT(n->nsp_srcaddr)) {
746829Ssam 		printf("nsp_chkaddr: n_rem %d, srcaddr %d\n", np->n_rem,
756829Ssam 			D_SHORT(n->nsp_srcaddr));
766829Ssam 		m_freem(m);
776829Ssam 		return (0);
786829Ssam 	}
796829Ssam 	ack = D_SHORT(n->nsp_acknum);
806829Ssam 	if (ack & NSPA_ACK) {
816829Ssam 		qual = ack & NSPA_QUAL;
826829Ssam 		num = ack & NSPA_NUM;
836829Ssam 		printd(", qual 0x%x, num %d", qual, num);
846829Ssam 		/* make sure there's room for a segnum */
856829Ssam 		if (m->m_len < sizeof (struct nspd)) {
866829Ssam 			m_freem(m);
876829Ssam 			return (0);
886829Ssam 		}
896829Ssam 		if (type == NSP_DATA) {
906829Ssam 			if (SEQ_GTR(num, np->na_rcvdat) &&
916829Ssam 			    SEQ_LEQ(num, np->nn_high)) {
926829Ssam 				np->n_retrans = 0;
936829Ssam 				np->nf_remdat -= SEQ_SUB(num, np->na_rcvdat);
946829Ssam 			}
956829Ssam 			if (qual == NSPA_NAK || SEQ_LEQ(np->nn_dat, num))
966829Ssam 				np->nn_dat = SEQ_ADD(num, 1);
976829Ssam 			np->na_rcvdat = num;
986829Ssam 			nsp_purgertq(np, type);
996829Ssam 		} else if (n == np->nn_oth && (np->n_flags&NF_OTHSENT)) {
1006829Ssam 			if (qual == NSPA_NAK) {
1016829Ssam 				/* force retransmission of other data seg */
1026829Ssam 				printf("nsp_chkaddr: NAK other\n");
1036829Ssam 			} else {
1046829Ssam 				np->n_flags &= ~NF_OTHSENT;
1056829Ssam 				np->nn_oth = SEQ_ADD(np->nn_oth, 1);
1066829Ssam 				if (np->n_flags & NF_OTHINTR) {
1076829Ssam 					np->n_flags &=
1086829Ssam 					    ~(NF_OTHINTR|NF_INTAVAIL);
1096829Ssam 					if (np->nb_xmt)
1106829Ssam 						m_freem(np->nb_xmt);
1116829Ssam 				} else
1126829Ssam 					np->nf_locdat = 0;
1136829Ssam 				nsp_purgertq(np, type);
1146829Ssam 			}
1156829Ssam 		}
1166829Ssam 		*sp = D_SHORT(n->nsp_segnum);
1176829Ssam 		num = sizeof (struct nspd);
1186829Ssam 	} else {
1196829Ssam 		*sp = (u_short)ack;
1206829Ssam 		num = sizeof (struct nspd) - sizeof (u_short);
1216829Ssam 	}
1226829Ssam 	m->m_len -= num;
1236829Ssam 	m->m_off += num;
1246829Ssam 	return (np);
1256829Ssam }
126