date and time created 82/05/15 21:46:30 by sam
[unix-history] / usr / src / sys / deprecated / netdecnet / nsp_input.c
CommitLineData
af8c695d
SL
1
2#include "../h/param.h"
3#include "../h/systm.h"
4#include "../h/mbuf.h"
5#include "../h/protosw.h"
6#include "../h/socket.h"
7#include "../h/socketvar.h"
8#include "../net/dn_systm.h"
9#include "../net/nsp.h"
10#include "../net/nsp_var.h"
11#include "../errno.h"
12
13int nspidebug = 1;
14#define printd if(nspidebug)printf
15/*
16 * NSP input routine: decode incoming packet and dispatch
17 * to appropriate socket. Called from the software interrupt
18 * at splnet.
19 *
20 * TODO:
21 * count occurances of various error conditions.
22 */
23
24nspintr()
25{
26 struct mbuf *m;
27 struct tprh *t;
28 int s, bom, eom;
29 u_short srcnode;
30 char *p;
31 struct nspcb *np;
32
33 /*
34 * Loop pulling packets off the interrupt queue.
35 */
36next:
37 s = splimp();
38 IF_DEQUEUE(&nspintrq, m);
39 splx(s);
40 printd("nsp_input: m 0x%x", m);
41 if (m == 0)
42 return;
43 t = mtod(m, struct tprh *);
44 srcnode = t->tprh_srcnode;
45 m->m_len -= sizeof (struct tprh); /* use m_adj??? */
46 m->m_off += sizeof (struct tprh);
47 printd(", srcnode %d, len %d", srcnode, m->m_len);
48 if (m->m_len <= 0) {
49 m_freem(m);
50 goto next;
51 }
52
53 /*
54 * Switch on the type of the message.
55 */
56 p = mtod(m, char *);
57 switch (*p) {
58
59 /*
60 * Got a Data message, possibly with EOM and
61 * BOM flags set. Call nsp_chkaddr to do ack
62 * and flow controll processing, then pass the
63 * data to the user.
64 */
65 case NSP_DATA|NSP_EOM|NSP_BOM:
66 eom = bom = 1;
67 goto data;
68
69 case NSP_DATA|NSP_EOM:
70 eom = 1;
71 goto data;
72
73 case NSP_DATA|NSP_BOM:
74 bom = 1;
75
76 case NSP_DATA:
77 data:
78 printd(", DATA (%d,%d)", bom, eom);
79 np = nsp_chkaddr(m, srcnode, NSP_DATA, &segnum);
80 if (np == 0) {
81 m_freem(m);
82 goto next;
83 }
84
85 /*
86 * Data messages only valid in Run state
87 */
88 if (np->n_state != NS_RUN) {
89 printf(", !RUN (%d)\n", np->n_state);
90 m_freem(m);
91 goto next;
92 }
93 if (SEQ_GTR(segnum, np->na_xmtdat)) {
94 /* SHOULD DO SEGMENT RECONSTRUCTION HERE */
95 printd(", got data!");
96 sbpappend(m, &np->n_socket->sb_rcv);
97 } else
98 np->n_flags |= NF_DATACK;
99 break;
100
101 /*
102 * Got an interrupt message. Call nsp_chkaddr
103 * (as usual). Save the interrupt data for the
104 * user.
105 * GENERATE A SIGNAL OF SOME SORT???
106 */
107 case NSP_INTR:
108 printd(", INTR");
109 np = nsp_chkaddr(m, srcnode, NSP_INTR, &segnum);
110 if (np == 0) {
111 m_freem(m);
112 goto next;
113 }
114
115 /*
116 * If we are in the Connect Confirm state then
117 * this Interrupt packet causes the transition
118 * to the Run state. Otherwise we better be in
119 * the Run state already.
120 */
121 if (np->n_state == NS_CC)
122 np->n_state = NS_RUN;
123 else if (np->n_state != NS_RUN) {
124 printf(", !RUN %d\n", np->n_state);
125 m_freem(m);
126 goto next;
127 }
128
129 /*
130 * If this segment is the one after the last
131 * other data segment we acked, and there is
132 * no waiting interrupt message, then queue
133 * this one up.
134 */
135 if (segnum == SEQ_ADD(np->na_xmtoth, 1) &&
136 np->nf_locint == NFL_EMPTY) {
137 if (np->nb_rcv) {
138 printd(", flush old intr data");
139 m_freem(np->nb_rcv);
140 }
141 if (m->m_len > 16) {
142 printd(", intr data too long\n");
143 m_freem(m);
144 goto next;
145 }
146 np->nb_rcv = m;
147 np->nf_locint = NFL_INTR;
148 np->na_xmtoth = segnum; /* really += 1 */
149 np->n_flags |= NF_OTHACK;
150 } else if (SEQ_LEQ(segnum, np->na_xmtoth))
151 np->n_flags |= NF_OTHACK;
152 break;
153
154 /*
155 * Got a Link Service message. Process options
156 * to modify flow control values.
157 */
158 case NSP_LS:
159 printd(", LS");
160 np = nsp_chkaddr(m, srcnode, NSP_LS, &segnum);
161 if (np == 0) {
162 m_freem(m);
163 goto next;
164 }
165
166 /*
167 * If we are in the Connect Confirm state then
168 * this Link Service packet causes the transition
169 * to the Run state. Otherwise we better be in
170 * the Run state already.
171 */
172 if (np->n_state == NS_CC)
173 np->n_state = NS_RUN;
174 else if (np->n_state != NS_RUN) {
175 printd(", !RUN %d\n", np->n_state);
176 m_freem(m);
177 goto next;
178 }
179 p = mtod(m, char *);
180 lsf = *p++;
181 fcval = *p;
182 printd(", lsf 0x%x, fcval %d", lsf, fcval);
183 switch (lsf & NSPLS_FCVALINT) {
184 case NSPLS_DATREQ:
185 if (seqnum == SEQ_ADD(np->na_xmtoth, 1)) {
186 if (np->nf_remdat + fcval >= -128 &&
187 np->nf_remdat + fcval <= 127) {
188 np->nf_remdat += fcval;
189 np->na_xmtoth = segnum;
190 np->n_flags |= NF_OTHACK;
191 switch (lsf & NSPLS_FCMOD) {
192 case NSPLS_NOCHANGE:
193 break;
194 case NSPLS_ON:
195 np->n_flags &= ~NF_DATOFF;
196 break;
197 case NSPLS_OFF:
198 np->n_flags |= NF_DATOFF;
199 break;
200 default:
201 printd(", bad fcmod");
202 }
203 }
204 } else if (SEQ_LEQ(segnum, np->na_xmtoth))
205 np->n_flags |= NF_OTHACK;
206 break;
207
208 case NSPLS_INTREQ:
209 if (seqnum == SEQ_ADD(np->na_xmtoth, 1)) {
210 if (fcval >= 0 && np->nf_remint+fcval <= 127) {
211 np->nf_remint += fcval;
212 np->na_xmtoth = segnum;
213 np->n_flags |= NF_OTHACK;
214 } else if (SEQ_LEQ(segnum, np->na_xmtoth))
215 np->n_flags |= NF_OTHACK;
216 break;
217
218 default:
219 printd(", bad fcvalint");
220 }
221 break;
222
223 /*
224 * Got an acknowledgement for a Data message.
225 * Nsp_chkaddr processes the ack, nothing else
226 * to do.
227 */
228 case NSP_DATACK:
229 printd(", DATACK");
230 np = nsp_chkaddr(m, srcnode, NSP_DATACK, &segnum);
231 if (np == 0) {
232 m_freem(m);
233 goto next;
234 }
235 break;
236
237 /*
238 * Got an acknowledgement for an Other Data message.
239 * Nsp_chkaddr processes the ack, nothing else to do.
240 */
241 case NSP_OTHACK:
242 printd(", OTHACK");
243 np = nsp_chkaddr(m, srcnode, NSP_OTHACK, &segnum);
244 if (np == 0) {
245 m_freem(m);
246 goto next;
247 }
248 break;
249
250 /*
251 * Got a Connect Acknowledgement. Just verify
252 * the address and perform the state transition.
253 */
254 case NSP_CONACK:
255 DOIT
256 break;
257
258 /*
259 * Got an unknown message, count it and flush it.
260 */
261 default:
262 printd(", UNKNOWN!!!");
263 m_freem(m);
264 break;
265 }
266 printd("\n");
267 goto next;
268}