1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#define RESOLVE_DBG
29#include <sys/errno.h>
30#include <sys/types.h>
31#include <sys/param.h>
32#include <machine/spl.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35#include <sys/proc.h>
36#include <sys/filedesc.h>
37#include <sys/fcntl.h>
38#include <sys/mbuf.h>
39#include <sys/socket.h>
40
41#include <netat/sysglue.h>
42#include <netat/appletalk.h>
43#include <netat/at_pcb.h>
44#include <netat/ddp.h>
45#include <netat/adsp.h>
46#include <netat/adsp_internal.h>
47
48#ifdef notdefn
49struct adsp_debug adsp_dtable[1025];
50int ad_entry = 0;
51#endif
52
53extern atlock_t adspgen_lock;
54
55adspAllocateCCB(gref)
56 register gref_t *gref;
57{
58 gbuf_t *ccb_mp;
59 register CCBPtr sp;
60
61 if (!(ccb_mp = gbuf_alloc(sizeof(CCB), PRI_LO))) {
62 return (0);
63 }
64 bzero((caddr_t) gbuf_rptr(ccb_mp), sizeof(CCB));
65 gbuf_wset(ccb_mp,sizeof(CCB));
66 gref->info = (caddr_t) ccb_mp;
67 sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
68
69 sp->pid = gref->pid;
70 sp->gref = gref;
71 sp->sp_mp = ccb_mp;
72 ATLOCKINIT(sp->lock);
73 ATLOCKINIT(sp->lockClose);
74 ATLOCKINIT(sp->lockRemove);
75 return 1;
76}
77
78adspRelease(gref)
79 register gref_t *gref;
80{
81 register CCBPtr sp;
82 int s, l;
83
84 ATDISABLE(l, adspgen_lock);
85 if (gref->info) {
86 sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
87 ATDISABLE(s, sp->lock);
88 ATENABLE(s, adspgen_lock);
89
90
91
92 if (sp->state == sPassive || sp->state == sClosed ||
93 sp->state == sOpening || sp->state == sListening) {
94 ATENABLE(l, sp->lock);
95 if (sp->state == sListening)
96 CompleteQueue(&sp->opb, errAborted);
97 sp->removing = 1;
98 DoClose(sp, errAborted, 0);
99 return 0;
100 } else {
101 sp->state = sClosing;
102 }
103 ATENABLE(l, sp->lock);
104
105 if (CheckOkToClose(sp)) {
106 sp->sendCtl = B_CTL_CLOSE;
107 } else {
108 CheckSend(sp);
109 if (sp->state != sClosed)
110 sp->sendCtl = B_CTL_CLOSE;
111 }
112 CheckSend(sp);
113 ATDISABLE(s, sp->lock);
114 sp->removing = 1;
115 sp->state = sClosed;
116 ATENABLE(s, sp->lock);
117 DoClose(sp, errAborted, 0);
118 } else
119 ATENABLE(l, adspgen_lock);
120}
121
122
123
124
125adspWriteHandler(gref, mp)
126 gref_t *gref;
127 gbuf_t *mp;
128{
129
130 register ioc_t *iocbp;
131 register struct adspcmd *ap;
132 int error, flag;
133 void *sp;
134
135 switch(gbuf_type(mp)) {
136 case MSG_DATA:
137 if (gref->info == 0) {
138 gbuf_freem(mp);
139 return(STR_IGNORE);
140 }
141
142
143
144 ap = (struct adspcmd *)gbuf_rptr(mp);
145 ap->gref = gref;
146 ap->ioc = 0;
147 ap->mp = mp;
148 sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
149 switch(ap->csCode) {
150 case dspWrite:
151 if ((error = adspWrite(sp, ap)))
152 gbuf_freem(mp);
153 return(STR_IGNORE);
154 case dspAttention:
155 if ((error = adspAttention(sp, ap)))
156 gbuf_freem(mp);
157 return(STR_IGNORE);
158 }
159 case MSG_IOCTL:
160 if (gref->info == 0) {
161 adspioc_ack(EPROTOTYPE, mp, gref);
162 return(STR_IGNORE);
163 }
164 iocbp = (ioc_t *) gbuf_rptr(mp);
165 if (ADSP_IOCTL(iocbp->ioc_cmd)) {
166 iocbp->ioc_count = sizeof(*ap) - 1;
167 if (gbuf_cont(mp) == 0) {
168 adspioc_ack(EINVAL, mp, gref);
169 return(STR_IGNORE);
170 }
171 ap = (struct adspcmd *) gbuf_rptr(gbuf_cont(mp));
172 ap->gref = gref;
173 ap->ioc = (caddr_t) mp;
174 ap->mp = gbuf_cont(mp);
175 ap->ioResult = 0;
176
177 if ((gref->info == 0) && ((iocbp->ioc_cmd != ADSPOPEN) &&
178 (iocbp->ioc_cmd != ADSPCLLISTEN))) {
179 ap->ioResult = errState;
180
181 adspioc_ack(EINVAL, mp, gref);
182 return(STR_IGNORE);
183 }
184 } else
185 return(STR_PUTNEXT);
186 sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
187 switch(iocbp->ioc_cmd) {
188 case ADSPOPEN:
189 case ADSPCLLISTEN:
190 ap->socket = ((CCBPtr)sp)->localSocket;
191 flag = (adspMode(ap) == ocAccept) ? 1 : 0;
192 if (flag && ap->socket) {
193 if (adspDeassignSocket((CCBPtr)sp) >= 0)
194 ap->socket = 0;
195 }
196 if ((ap->socket == 0) &&
197 ((ap->socket =
198 (at_socket)adspAssignSocket(gref, flag)) == 0)) {
199 adspioc_ack(EADDRNOTAVAIL, mp, gref);
200 return(STR_IGNORE);
201 }
202 ap->csCode = iocbp->ioc_cmd == ADSPOPEN ? dspInit : dspCLInit;
203 if ((error = adspInit(sp, ap)) == 0) {
204 switch(ap->csCode) {
205 case dspInit:
206
207 ap->csCode = dspOpen;
208 error = adspOpen(sp, ap);
209 break;
210 case dspCLInit:
211
212 ap->csCode = dspCLListen;
213 error = adspCLListen(sp, ap);
214 break;
215 }
216 }
217 if (error)
218 adspioc_ack(error, mp, gref);
219 return(STR_IGNORE);
220 case ADSPCLOSE:
221 ap->csCode = dspClose;
222 if ((error = adspClose(sp, ap))) {
223 adspioc_ack(error, mp, gref);
224 break;
225 }
226 break;
227 case ADSPCLREMOVE:
228 ap->csCode = dspCLRemove;
229 error = adspClose(sp, ap);
230 adspioc_ack(error, mp, gref);
231 return(STR_IGNORE);
232 case ADSPCLDENY:
233 ap->csCode = dspCLDeny;
234 if ((error = adspCLDeny(sp, ap))) {
235 adspioc_ack(error, mp, gref);
236 }
237 return(STR_IGNORE);
238 case ADSPSTATUS:
239 ap->csCode = dspStatus;
240 if ((error = adspStatus(sp, ap))) {
241 adspioc_ack(error, mp, gref);
242 }
243 return(STR_IGNORE);
244 case ADSPREAD:
245 ap->csCode = dspRead;
246 if ((error = adspRead(sp, ap))) {
247 adspioc_ack(error, mp, gref);
248 }
249 return(STR_IGNORE);
250 case ADSPATTENTION:
251 ap->csCode = dspAttention;
252 if ((error = adspReadAttention(sp, ap))) {
253 adspioc_ack(error, mp, gref);
254 }
255 return(STR_IGNORE);
256 case ADSPOPTIONS:
257 ap->csCode = dspOptions;
258 if ((error = adspOptions(sp, ap))) {
259 adspioc_ack(error, mp, gref);
260 }
261 return(STR_IGNORE);
262 case ADSPRESET:
263 ap->csCode = dspReset;
264 if ((error = adspReset(sp, ap))) {
265 adspioc_ack(error, mp, gref);
266 }
267 return(STR_IGNORE);
268 case ADSPNEWCID:
269 ap->csCode = dspNewCID;
270 if ((error = adspNewCID(sp, ap))) {
271 adspioc_ack(error, mp, gref);
272 }
273 return(STR_IGNORE);
274 default:
275 return(STR_PUTNEXT);
276 }
277 return(STR_IGNORE);
278 case MSG_PROTO:
279 default:
280 gbuf_freem(mp);
281 }
282}
283
284
285adspReadHandler(gref, mp)
286 gref_t *gref;
287 gbuf_t *mp;
288{
289 int error;
290
291 switch(gbuf_type(mp)) {
292 case MSG_DATA:
293 if ((error = adspPacket(gref, mp))) {
294 gbuf_freem(mp);
295 }
296 break;
297
298 case MSG_IOCTL:
299 default:
300 return(STR_PUTNEXT);
301 break;
302 }
303 return(STR_IGNORE);
304}
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337adsp_sendddp(sp, mp, length, dstnetaddr, ddptype)
338 CCBPtr sp;
339 gbuf_t *mp;
340 int length;
341 AddrUnion *dstnetaddr;
342 int ddptype;
343{
344 DDPX_FRAME *ddp;
345 gbuf_t *mlist = mp;
346
347 if (mp == 0)
348 return EINVAL;
349
350 if (length > DDP_DATA_SIZE) {
351 gbuf_freel(mlist);
352 return EMSGSIZE;
353 }
354
355 while (mp) {
356
357 if (length == 0)
358 length = gbuf_msgsize(mp) - DDPL_FRAME_LEN;
359
360
361 ddp = (DDPX_FRAME *) gbuf_rptr(mp);
362 UAS_ASSIGN(ddp->ddpx_length, (length + DDPL_FRAME_LEN));
363 UAS_ASSIGN(ddp->ddpx_cksm, 0);
364 if (sp) {
365 if (sp->useCheckSum)
366 UAS_ASSIGN(ddp->ddpx_cksm, 1);
367 }
368
369 NET_ASSIGN(ddp->ddpx_dnet, dstnetaddr->a.net);
370 ddp->ddpx_dnode = dstnetaddr->a.node;
371 ddp->ddpx_source = sp ? sp->localSocket : ddp->ddpx_dest;
372 ddp->ddpx_dest = dstnetaddr->a.socket;
373
374 ddp->ddpx_type = ddptype;
375 length = 0;
376 mp = gbuf_next(mp);
377
378 }
379
380 DDP_OUTPUT(mlist);
381 return 0;
382}
383
384void NotifyUser(sp)
385 register CCBPtr sp;
386
387{
388
389
390
391}
392
393void UrgentUser(sp)
394 register CCBPtr sp;
395{
396
397
398
399}
400