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