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
29
30#include <sys/errno.h>
31#include <sys/types.h>
32#include <sys/param.h>
33#include <machine/spl.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/proc.h>
37#include <sys/filedesc.h>
38#include <sys/fcntl.h>
39#include <sys/mbuf.h>
40#include <sys/ioctl.h>
41#include <sys/malloc.h>
42#include <sys/socket.h>
43#include <sys/socketvar.h>
44#include <sys/time.h>
45
46#include <net/if.h>
47
48#include <netat/sysglue.h>
49#include <netat/appletalk.h>
50#include <netat/at_pcb.h>
51#include <netat/ddp.h>
52#include <netat/at_var.h>
53
54#include <netat/adsp.h>
55#include <netat/adsp_internal.h>
56
57extern at_ifaddr_t *ifID_home;
58
59
60
61
62
63
64
65
66
67
68
69
70static void GleanSession(sp)
71 CCBPtr sp;
72{
73 if (sp->openState == O_STATE_OPEN) {
74
75 RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
76 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
77 sp->probeInterval);
78 sp->probeCntr = 4;
79 }
80
81}
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107typedef struct {
108 u_char match;
109
110 char action;
111 char send;
112
113
114 char openState;
115 char state;
116 char pad;
117
118} TBL, *TBLPtr;
119
120#define M_LSOC 0x01
121#define M_ADDR 0x02
122#define M_DCID 0x04
123#define M_SCID 0x08
124#define M_DCIDZERO 0x10
125#define M_SCIDZERO 0x20
126#define M_FILTER 0x40
127#define M_IGNORE 0x80
128
129#define A_COMPLETE 0x01
130#define A_SAVEPARMS 0x02
131#define A_OREQACKOPEN 0x04
132
133#define A_GLEAN 0x08
134#define A_DENY 0x10
135
136
137
138
139
140
141static TBL tbl[16] = {
142
143
144
145
146
147
148
149
150
151
152
153
154
155 { M_LSOC + M_DCIDZERO + M_FILTER,
156 A_SAVEPARMS + A_GLEAN,
157 B_CTL_OREQACK,
158 O_STATE_ESTABLISHED,
159 sOpening,
160 0
161 },
162
163
164
165
166
167
168
169
170
171
172 { M_LSOC + M_ADDR + M_DCIDZERO,
173 A_SAVEPARMS + A_GLEAN,
174 B_CTL_OACK,
175 O_STATE_ESTABLISHED,
176 sOpening,
177 0
178 },
179
180
181
182
183
184
185
186 { M_ADDR + M_SCID + M_DCIDZERO,
187 A_GLEAN,
188 B_CTL_OACK,
189 O_STATE_ESTABLISHED,
190 sOpening,
191 0
192 },
193
194
195
196
197 { M_IGNORE,
198 0,
199 0,
200 0,
201 0,
202 0
203 },
204
205
206
207
208
209
210
211
212 { M_IGNORE,
213 0,
214 0,
215 0,
216 0,
217 0
218 },
219
220
221
222
223
224 { M_IGNORE,
225 0,
226 0,
227 0,
228 0,
229 0
230 },
231
232
233
234
235
236
237
238 { M_ADDR + M_DCID + M_SCID + M_LSOC,
239 A_COMPLETE + A_GLEAN,
240 0,
241 O_STATE_OPEN,
242 sOpen,
243 0
244 },
245
246
247
248
249
250 { M_IGNORE,
251 0,
252 0,
253 0,
254 0,
255 0
256 },
257
258
259
260
261
262
263
264
265 { M_IGNORE,
266 0,
267 0,
268 0,
269 0,
270 0
271 },
272
273
274
275
276
277
278
279
280
281
282
283 { M_DCID + M_LSOC,
284 A_COMPLETE + A_SAVEPARMS + A_GLEAN,
285 B_CTL_OACK,
286 O_STATE_OPEN,
287 sOpen,
288 0
289 },
290
291
292
293
294
295 { M_IGNORE,
296 0,
297 0,
298 0,
299 0,
300 0
301 },
302
303
304
305
306
307
308
309 { M_ADDR + M_DCID + M_SCID + M_LSOC,
310 A_OREQACKOPEN + A_GLEAN,
311 B_CTL_OACK,
312 O_STATE_OPEN,
313 sOpen,
314 0
315 },
316
317
318
319
320
321
322
323
324
325 { M_IGNORE,
326 0,
327 0,
328 0,
329 0,
330 0
331 },
332
333
334
335
336
337
338
339 { M_SCIDZERO + M_DCID + M_ADDR,
340 A_DENY,
341 0,
342 O_STATE_NOTHING,
343 sClosed,
344 0
345 },
346
347
348
349
350
351 { M_IGNORE,
352 0,
353 0,
354 0,
355 0,
356 0
357 },
358
359
360
361
362
363 { M_IGNORE,
364 0,
365 0,
366 0,
367 0,
368 0
369 }
370};
371
372extern at_ifaddr_t *ifID_table[];
373
374
375
376
377
378typedef struct {
379 AddrUnion addr;
380 word dstCID;
381 word srcCID;
382 byte socket;
383 byte descriptor;
384 byte idx;
385 TBLPtr t;
386} MATCH, *MATCHPtr;
387
388
389
390
391
392
393
394
395
396static boolean
397MatchStream(sp, m)
398 CCBPtr sp;
399 MATCHPtr m;
400{
401 unsigned char match;
402 struct adspcmd *opb;
403
404 if (sp->openState < O_STATE_LISTEN ||
405 sp->openState > O_STATE_OPEN)
406 return 0;
407
408
409 m->t = &tbl[sp->openState - O_STATE_LISTEN + m->idx];
410
411 match = m->t->match;
412
413 if (match & M_IGNORE)
414 return 0;
415
416 if (match & M_LSOC) {
417 if (sp->localSocket != m->socket)
418 return 0;
419 }
420
421 if (match & M_ADDR) {
422 AddrUnion addr;
423 addr = m->addr;
424 if (sp->remoteAddress.a.node != addr.a.node)
425 return 0;
426 if (sp->remoteAddress.a.socket != addr.a.socket)
427 return 0;
428 if (sp->remoteAddress.a.net && addr.a.net &&
429 (sp->remoteAddress.a.net != addr.a.net))
430 return 0;
431
432
433
434
435 if ((m->srcCID == sp->locCID) &&
436 (addr.a.node == ifID_home->ifThisNode.s_node) &&
437
438 ((addr.a.net == 0) ||
439 (ifID_home->ifThisNode.s_net == 0) ||
440 (ifID_home->ifThisNode.s_net == addr.a.net)) )
441
442
443
444
445
446
447
448 return 0;
449 }
450
451 if (match & M_DCID) {
452 if (sp->locCID != m->dstCID)
453 return 0;
454 }
455
456 if (match & M_SCID) {
457 if (sp->remCID != m->srcCID)
458 return 0;
459 }
460
461 if (match & M_DCIDZERO) {
462 if (m->dstCID != 0)
463 return 0;
464 }
465
466 if (match & M_SCIDZERO)
467 {
468 if (m->srcCID != 0)
469 return 0;
470 }
471
472 if (match & M_FILTER) {
473 if ((opb = sp->opb))
474 {
475 AddrUnion addr;
476 addr = m->addr;
477 if ((opb->u.openParams.filterAddress.net &&
478 addr.a.net &&
479 opb->u.openParams.filterAddress.net != addr.a.net) ||
480 (opb->u.openParams.filterAddress.node != 0 &&
481 opb->u.openParams.filterAddress.node != addr.a.node)||
482 (opb->u.openParams.filterAddress.socket != 0 &&
483 opb->u.openParams.filterAddress.socket != addr.a.socket))
484 return 0;
485 }
486 }
487
488 return 1;
489}
490
491
492
493
494
495
496
497
498
499static boolean MatchListener(sp, m)
500 CCBPtr sp;
501 MATCHPtr m;
502{
503
504 if ((sp->state == (word)sListening) &&
505 (sp->localSocket == m->socket))
506 return 1;
507
508 return 0;
509}
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528static int RXConnection(gref, spPtr, f, len, addr, dsoc)
529
530 gref_t *gref;
531 CCBPtr *spPtr;
532 ADSP_FRAMEPtr f;
533 int len;
534 AddrUnion addr;
535 unsigned char dsoc;
536{
537 CCBPtr sp;
538 ADSP_OPEN_DATAPtr op;
539 struct adspcmd *pb;
540 MATCH m;
541 gbuf_t *mp;
542 ADSP_FRAMEPtr adspp;
543 ADSP_OPEN_DATAPtr adspop;
544 int s;
545
546 op = (ADSP_OPEN_DATAPtr)&f->data[0];
547 len -= ADSP_FRAME_LEN;
548
549 if (len < (sizeof(ADSP_OPEN_DATA)))
550 return 1;
551
552
553 if (UAS_VALUE(op->version) != netw(0x0100)) {
554
555
556
557
558 mp = gbuf_alloc(AT_WR_OFFSET + DDPL_FRAME_LEN + ADSP_FRAME_LEN + ADSP_OPEN_FRAME_LEN,
559 PRI_LO);
560 gbuf_rinc(mp,AT_WR_OFFSET);
561 gbuf_wset(mp,DDPL_FRAME_LEN);
562 adspp = (ADSP_FRAMEPtr)gbuf_wptr(mp);
563 gbuf_winc(mp,ADSP_FRAME_LEN);
564 bzero((caddr_t) gbuf_rptr(mp),DDPL_FRAME_LEN + ADSP_FRAME_LEN +
565 ADSP_OPEN_FRAME_LEN);
566 adspp->descriptor = ADSP_CONTROL_BIT | ADSP_CTL_ODENY;
567 adspop = (ADSP_OPEN_DATAPtr)gbuf_wptr(mp);
568 gbuf_winc(mp,ADSP_OPEN_FRAME_LEN);
569 UAS_UAS(adspop->dstCID, f->CID);
570 UAS_ASSIGN(adspop->version, 0x100);
571 adsp_sendddp(0, mp, DDPL_FRAME_LEN + ADSP_FRAME_LEN +
572 ADSP_OPEN_FRAME_LEN, &addr, DDP_ADSP);
573
574 return 0;
575 }
576 m.addr = addr;
577 m.socket = dsoc;
578 m.descriptor = f->descriptor;
579 m.srcCID = UAS_VALUE(f->CID);
580 m.dstCID = UAS_VALUE(op->dstCID);
581 m.idx = ((f->descriptor & ADSP_CONTROL_MASK) - 1) * 4;
582
583
584
585
586 if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchStream)) == 0)
587 {
588 struct adspcmd *p;
589 struct adspcmd *n;
590
591
592
593
594 if ((f->descriptor & ADSP_CONTROL_MASK) != (byte)ADSP_CTL_OREQ)
595 return 1;
596
597 if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m,
598 (ProcPtr)MatchListener)) == 0)
599 return 1;
600
601 ATDISABLE(s, sp->lock);
602 p = (struct adspcmd *)&sp->opb;
603 while (n = (struct adspcmd *)p->qLink)
604 {
605
606 if (((n->u.openParams.filterAddress.net == 0) ||
607 (addr.a.net == 0) ||
608 (n->u.openParams.filterAddress.net == addr.a.net)) &&
609
610 ((n->u.openParams.filterAddress.node == 0) ||
611 (n->u.openParams.filterAddress.node == addr.a.node)) &&
612
613 ((n->u.openParams.filterAddress.socket == 0) ||
614 (n->u.openParams.filterAddress.socket == addr.a.socket))) {
615 p->qLink = n->qLink;
616 n->u.openParams.remoteCID = m.srcCID;
617 *((AddrUnionPtr)&n->u.openParams.remoteAddress) = addr;
618 n->u.openParams.sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
619 n->u.openParams.sendWindow = netw(UAS_VALUE(f->pktRecvWdw));
620 n->u.openParams.attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq));
621 n->ioResult = 0;
622 ATENABLE(s, sp->lock);
623 completepb(sp, n);
624
625 return 0;
626 }
627
628 p = n;
629
630 }
631
632 ATENABLE(s, sp->lock);
633 return 1;
634 }
635
636 *spPtr = sp;
637
638 ATDISABLE(s, sp->lock);
639 sp->openState = m.t->openState;
640 sp->state = m.t->state;
641
642 if (m.t->action & A_SAVEPARMS) {
643 sp->firstRtmtSeq = sp->sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
644 sp->sendWdwSeq = netdw(UAL_VALUE(f->pktNextRecvSeq)) + netw(UAS_VALUE(f->pktRecvWdw)) - 1;
645 sp->attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq));
646
647
648 sp->remCID = UAS_VALUE(f->CID);
649 UAS_UAS(sp->of.dstCID, f->CID);
650
651 sp->remoteAddress = addr;
652
653 }
654 ATENABLE(s, sp->lock);
655
656 if (m.t->action & A_DENY) {
657 DoClose(sp, errOpenDenied, -1);
658 }
659
660 if (m.t->action & A_OREQACKOPEN) {
661
662
663 RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
664 sp->sendSeq = sp->firstRtmtSeq;
665 sp->pktSendCnt = 0;
666 sp->waitingAck = 0;
667 sp->callSend = 1;
668 }
669
670 if (m.t->send) {
671 sp->sendCtl |= m.t->send;
672 sp->callSend = 1;
673 }
674
675 if (m.t->action & A_COMPLETE) {
676 RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
677
678 if (pb = sp->opb) {
679 sp->opb = 0;
680 pb->u.openParams.localCID = sp->locCID;
681 pb->u.openParams.remoteCID = sp->remCID;
682 pb->u.openParams.remoteAddress =
683 *((at_inet_t *)&sp->remoteAddress);
684 pb->u.openParams.sendSeq = sp->sendSeq;
685 pb->u.openParams.sendWindow = sp->sendWdwSeq - sp->sendSeq;
686 pb->u.openParams.attnSendSeq = sp->attnSendSeq;
687 pb->ioResult = 0;
688 completepb(sp, pb);
689 return 0;
690 }
691
692 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
693 sp->probeInterval);
694 }
695 return 0;
696}
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719int adspPacket(gref, mp)
720
721 gref_t *gref;
722 gbuf_t *mp;
723{
724 unsigned char *bp;
725 int len;
726 AddrUnion a;
727 int dsoc;
728 int s;
729 register DDPX_FRAME *ddp;
730 register ADSP_FRAMEPtr f;
731 CCBPtr sp;
732
733 sp = 0;
734 bp = (unsigned char *)gbuf_rptr(mp);
735 ddp = (DDPX_FRAME *)bp;
736 if (ddp->ddpx_type != DDP_ADSP)
737 return -1;
738 f = (ADSP_FRAMEPtr)(bp + DDPL_FRAME_LEN);
739
740 len = UAS_VALUE(ddp->ddpx_length) & 0x3ff;
741 len -= DDPL_FRAME_LEN;
742 if (len < (sizeof(ADSP_FRAME) - 1))
743 return -1;
744
745 a.a.net = NET_VALUE(ddp->ddpx_snet);
746 a.a.node = ddp->ddpx_snode;
747 a.a.socket = ddp->ddpx_source;
748
749 dsoc = ddp->ddpx_dest;
750
751 if (sp = (CCBPtr)FindSender(f, a))
752 GleanSession(sp);
753
754 if (f->descriptor & ADSP_ATTENTION_BIT) {
755 if (sp && RXAttention(sp, mp, f, len))
756 goto ignore;
757 else
758 mp = 0;
759 }
760
761 else if (f->descriptor & ADSP_CONTROL_BIT) {
762 switch (f->descriptor & ADSP_CONTROL_MASK) {
763 case ADSP_CTL_PROBE:
764 if (sp)
765 CheckRecvSeq(sp, f);
766 break;
767
768 case ADSP_CTL_OREQ:
769 case ADSP_CTL_OREQACK:
770 case ADSP_CTL_OACK:
771 case ADSP_CTL_ODENY:
772 if (RXConnection(gref, &sp, f, len, a, dsoc))
773 goto ignore;
774 break;
775
776 case ADSP_CTL_CLOSE:
777 if (sp) {
778
779 CheckRecvSeq(sp, f);
780 RxClose(sp);
781 sp = 0;
782 } else
783 goto ignore;
784 break;
785
786 case ADSP_CTL_FRESET:
787
788 if (sp && (CheckRecvSeq(sp, f), RXFReset(sp, f)))
789 goto ignore;
790 break;
791
792 case ADSP_CTL_FRESET_ACK:
793 if (sp && (CheckRecvSeq(sp, f), RXFResetAck(sp, f)))
794 goto ignore;
795 break;
796
797 case ADSP_CTL_RETRANSMIT:
798 if (sp) {
799
800 CheckRecvSeq(sp, f);
801 RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
802 ATDISABLE(s, sp->lock);
803 sp->sendSeq = sp->firstRtmtSeq;
804 sp->pktSendCnt = 0;
805 sp->waitingAck = 0;
806 sp->callSend = 1;
807 ATENABLE(s, sp->lock);
808 } else
809 goto ignore;
810 break;
811
812 default:
813 goto ignore;
814 }
815 }
816
817 else {
818 if ((sp == 0) || RXData(sp, mp, f, len))
819 goto ignore;
820 else
821 mp = 0;
822 }
823
824 if (mp)
825 gbuf_freem(mp);
826
827checksend:
828 if (sp && sp->callSend)
829 CheckSend(sp);
830
831 return 0;
832
833ignore:
834 gbuf_freem(mp);
835 return 0;
836}
837