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