|
|
1.1 root 1: /* From ddp.c:
2:
3: ddp_shrink_hdr()
4: ddp_extend_hdr()
5:
6: Saved from xnu/bsd/bsd/netat/ddp.c on 4/14/99.
7: */
8:
9: #ifdef NOT_USED
10: /* This routine shrinks the ddp header from long to short,
11: * It also prepends ALAP header and fills up some of the
12: * fields as appropriate.
13: */
14: static at_ddp_short_t *ddp_shrink_hdr (mp)
15: register gbuf_t *mp;
16: {
17: register at_ddp_t *ddp;
18: register at_ddp_short_t *ddp_short;
19: register at_llap_hdr_t *llap;
20: gbuf_t *newmp;
21:
22: if ((newmp = (gbuf_t *)gbuf_copym((gbuf_t *) mp)) == (gbuf_t *)NULL)
23: return ((at_ddp_short_t *)NULL);
24: gbuf_freem(mp);
25: mp = newmp;
26:
27: ddp = (at_ddp_t *)gbuf_rptr(mp);
28: gbuf_rinc(mp,((DDP_X_HDR_SIZE - DDP_HDR_SIZE) - LLAP_HDR_SIZE));
29: llap = (at_llap_hdr_t *)gbuf_rptr(mp);
30: ddp_short = (at_ddp_short_t *)(gbuf_rptr(mp) + LLAP_HDR_SIZE);
31:
32: llap->destination = ddp->dst_node;
33: llap->type = LLAP_TYPE_DDP;
34: ddp_short->length = ddp->length - (DDP_X_HDR_SIZE - DDP_HDR_SIZE);
35: ddp_short->unused = 0;
36: return ((at_ddp_short_t *)mp);
37: }
38:
39:
40: /* mp points to message of the form {llap, short ddp, ...}.
41: * Get rid of llap, extend ddp header to make it of the form
42: * {extended ddp, ... }
43: */
44: static gbuf_t *ddp_extend_hdr(mp)
45: register gbuf_t *mp;
46: {
47: register at_llap_hdr_t *llap;
48: register at_ddp_short_t *ddp_short;
49: register at_ddp_t *ddp;
50: char buf[DDP_HDR_SIZE + LLAP_HDR_SIZE];
51: gbuf_t *m1, *m2;
52:
53: /* We need to remove the llap header from the packet and extend the
54: * short DDP header in to a long one. 5 bytes of additional space
55: * is required in effect, but we can not afford to put these 5 bytes
56: * in a separate buffer, since the ddp buffer would end up being
57: * fragmented into two pieces, which is a no-no. So, we first get
58: * rid of the llap and ddp short headers and then add the extended
59: * header.
60: */
61:
62: /* Assuming that the llap and ddp short headers are placed next
63: * to each other in the same buffer
64: */
65: bcopy(gbuf_rptr(mp), buf, LLAP_HDR_SIZE + DDP_HDR_SIZE);
66: m1 = ddp_adjmsg(mp, LLAP_HDR_SIZE+DDP_HDR_SIZE) ? mp : 0;
67:
68: /* If the message did not contain any ddp data bytes, then m would
69: * be NULL at this point... and we can't just grow a NULL message,
70: * we need to ALLOC a new one.
71: */
72: if (m1) {
73: if ((m2 = (gbuf_t *)ddp_growmsg(m1, -DDP_X_HDR_SIZE)) == NULL) {
74: dPrintf(D_M_DDP, D_L_WARNING,
75: ("Dropping packet - no bufs to extend hdr"));
76: at_ddp_stats.rcv_dropped_nobuf++;
77: gbuf_freem(m1);
78: return(NULL);
79: }
80: } else
81: /* Original message mp has already been freed by ddp_adjmsg if we
82: * managed to arrive here... this case occurs only when the
83: * message mp did not contain any ddp data bytes, only lap and
84: * ddp headers
85: */
86: if ((m2 = gbuf_alloc(AT_WR_OFFSET+DDP_X_HDR_SIZE, PRI_MED)) == NULL) {
87: dPrintf(D_M_DDP,D_L_WARNING,
88: ("Packet (no data) dropped - no bufs to extend hdr"));
89: at_ddp_stats.rcv_dropped_nobuf++;
90: return(NULL);
91: } else {
92: gbuf_rinc(m2,AT_WR_OFFSET);
93: gbuf_wset(m2,DDP_X_HDR_SIZE);
94: }
95:
96: /* By the time we arrive here, m2 points to message of the form
97: * {Extended DDP, ... }
98: * mp and m1 are either non-existent or irrelevant.
99: */
100: ddp = (at_ddp_t *)gbuf_rptr(m2);
101: llap = (at_llap_hdr_t *)buf;
102: ddp_short = (at_ddp_short_t *)(buf + LLAP_HDR_SIZE);
103:
104: ddp->unused = ddp->hopcount = 0;
105: ddp->length = ddp_short->length + DDP_X_HDR_SIZE - DDP_HDR_SIZE;
106: UAS_ASSIGN(ddp->checksum, 0);
107: NET_NET(ddp->dst_net, ifID_home->ifThisNode.atalk_net);
108: NET_NET(ddp->src_net, ifID_home->ifThisNode.atalk_net);
109: ddp->src_node = llap->source;
110: ddp->dst_node = llap->destination;
111: ddp->dst_socket = ddp_short->dst_socket;
112: ddp->src_socket = ddp_short->src_socket;
113: ddp->type = ddp_short->type;
114: return (m2);
115: }
116: #endif
117:
118: From sys_dep.c:
119:
120: #ifdef _AIX /* This AIX code (to the end of this file) is no longer supported. */
121:
122: int ATsocket(proto) /* AIX version */
123: int proto;
124: {
125: int err, rc = -1;
126:
127: if (sys_ATsocket)
128: rc = (*sys_ATsocket)(proto, &err, 0);
129: else
130: err = ENXIO;
131: if (err)
132: setuerror(err);
133: return rc;
134: }
135:
136: int ATgetmsg(fd, ctlptr, datptr, flags) /* AIX version */
137: int fd;
138: void *ctlptr;
139: void *datptr;
140: int *flags;
141: {
142: int err, rc = -1;
143:
144: if (sys_ATgetmsg)
145: rc = (*sys_ATgetmsg)(fd, ctlptr, datptr, flags, &err, 0);
146: else
147: err = ENXIO;
148: if (err)
149: setuerror(err);
150: return rc;
151: }
152:
153: int ATputmsg(fd, ctlptr, datptr, flags) /* AIX version */
154: int fd;
155: void *ctlptr;
156: void *datptr;
157: int flags;
158: {
159: int err, rc = -1;
160:
161: if (sys_ATputmsg)
162: rc = (*sys_ATputmsg)(fd, ctlptr, datptr, flags, &err, 0);
163: else
164: err = ENXIO;
165: if (err)
166: setuerror(err);
167: return rc;
168: }
169:
170: int ATPsndreq(fd, buf, len, nowait) /* AIX version */
171: int fd;
172: unsigned char *buf;
173: int len;
174: int nowait;
175: {
176: int err, rc = -1;
177:
178: if (sys_ATPsndreq)
179: rc = (*sys_ATPsndreq)(fd, buf, len, nowait, &err, 0);
180: else
181: err = ENXIO;
182: if (err)
183: setuerror(err);
184: return rc;
185: }
186:
187: int ATPsndrsp(fd, respbuff, resplen, datalen) /* AIX version */
188: int fd;
189: unsigned char *respbuff;
190: int resplen;
191: int datalen;
192: {
193: int err, rc = -1;
194:
195: if (sys_ATPsndrsp)
196: rc = (*sys_ATPsndrsp)(fd, respbuff, resplen, datalen, &err, 0);
197: else
198: err = ENXIO;
199: if (err)
200: setuerror(err);
201: return rc;
202: }
203:
204: int ATPgetreq(fd, buf, buflen) /* AIX version */
205: int fd;
206: unsigned char *buf;
207: int buflen;
208: {
209: int err, rc = -1;
210:
211: if (sys_ATPgetreq)
212: rc = (*sys_ATPgetreq)(fd, buf, buflen, &err, 0);
213: else
214: err = ENXIO;
215: if (err)
216: setuerror(err);
217: return rc;
218: }
219:
220: int ATPgetrsp(fd, bdsp) /* AIX version */
221: int fd;
222: unsigned char *bdsp;
223: {
224: int err, rc = -1;
225:
226: if (sys_ATPgetrsp)
227: rc = (*sys_ATPgetrsp)(fd, bdsp, &err, 0);
228: else
229: err = ENXIO;
230: if (err)
231: setuerror(err);
232: return rc;
233: }
234:
235: void *atalk_kalloc(size) /* AIX version */
236: int size;
237: {
238: return (void *)xmalloc(size, 2, pinned_heap);
239: }
240:
241: void atalk_kfree(buf) /* AIX version */
242: void *buf;
243: {
244: xmfree(buf, pinned_heap);
245: }
246:
247: int atalk_closeref(fp, grefp) /* AIX version */
248: struct file *fp;
249: gref_t **grefp;
250: {
251: *grefp = (gref_t *)fp->f_data;
252: fp->f_data = 0;
253: return 0;
254: }
255:
256: int atalk_openref(gref, retfd, proc) /* AIX version */
257: gref_t *gref;
258: int *retfd;
259: void *proc;
260: {
261: extern int _ATrw(), _ATioctl(), _ATselect(), _ATclose(), _ATstat();
262: static struct fileops fileops = {_ATrw, _ATioctl, _ATselect, _ATclose, _ATstat};
263: int err, fd;
264: struct file *fp;
265: void *crp;
266:
267: crp = (void *)crref();
268: #ifdef _AIX
269: if ((err = ufdcreate(FREAD|FWRITE,
270: &fileops, 0, DTYPE_OTHER, &fd, crp)) != 0)
271: #else
272: if ((err = ufdcreate(FREAD|FWRITE,
273: &fileops, 0, DTYPE_ATALK, &fd, crp)) != 0)
274: #endif
275: return err;
276: *retfd = fd;
277: fp = U.U_ufd[fd].fp;
278: fp->f_data = (void *)gref;
279: gref->next = (void *)fp;
280: return 0;
281: }
282:
283: int atalk_getref(fp, fd, grefp, proc) /* AIX version */
284: struct file *fp;
285: int fd;
286: gref_t **grefp;
287: struct proc *proc;
288: {
289: if (fp == 0) {
290: if ((fd < 0) || (fd > U.U_maxofile) || ((fp = U.U_ufd[fd].fp) == 0)) {
291: *grefp = (gref_t *)0;
292: return EBADF;
293: }
294: }
295: if ((*grefp = (gref_t *)fp->f_data) == 0)
296: return EBADF;
297: return 0;
298: }
299:
300: gbuf_t *gbuf_alloc(size, pri) /* AIX version */
301: int size;
302: int pri;
303: {
304: gbuf_t *m;
305:
306: m = (size > MHLEN) ? (gbuf_t *)m_getclustm(M_DONTWAIT, MSG_DATA, size)
307: : (gbuf_t *)m_gethdr(M_DONTWAIT, MSG_DATA);
308: #ifdef APPLETALK_DEBUG
309: kprintf("gbuf_alloc: for size = %d m=%x\n", size, m);
310: #endif
311: gbuf_next(m) = 0;
312: gbuf_cont(m) = 0;
313: gbuf_wset(m,0);
314: return m;
315: }
316:
317: void gbuf_freeb(m) /* AIX version */
318: gbuf_t *m;
319: {
320: if (m)
321: m_free(m);
322: }
323:
324: static struct trb *trb_freehead = 0;
325: static struct trb *trb_freetail = 0;
326: static struct trb *trb_pendhead = 0;
327: static int trb_cnt = 0;
328: static atlock_t trb_lock;
329:
330: static void atalk_rem_timeoutcf() /* AIX version */
331: {
332: register int s;
333: register struct trb *trb;
334: register struct trb *tmp_freehead, *tmp_pendhead;
335:
336: ATDISABLE(s, trb_lock);
337: tmp_freehead = trb_freehead;
338: trb_freehead = 0;
339: tmp_pendhead = trb_pendhead;
340: trb_pendhead = 0;
341: trb_cnt = 0;
342: ATENABLE(s, trb_lock);
343: while ((trb = tmp_pendhead) != 0) {
344: tmp_pendhead = trb->to_next;
345: while (tstop(trb));
346: tfree(trb);
347: }
348: while ((trb = tmp_freehead) != 0) {
349: tmp_freehead = trb->to_next;
350: tfree(trb);
351: }
352: dPrintf(D_M_ATP,D_L_ERROR, "atalk: timer stopped!\n",0,0,0,0,0);
353: }
354:
355: static void atalk_timeoutcf(cnt) /* AIX version */
356: int cnt;
357: {
358: register int i;
359: register struct trb *trb;
360:
361: if (trb_freehead == 0) {
362: for (i=0; i < cnt-1; i++) {
363: trb = (struct trb *)talloc();
364: trb->to_next = trb_freehead;
365: trb_freehead = trb;
366: if (!i) trb_freetail = trb;
367: trb_cnt++;
368: }
369: }
370: ATLOCKINIT(trb_lock);
371: }
372:
373: static void atalk_clock(trb) /* AIX version */
374: register struct trb *trb;
375: {
376: register int s;
377: register struct trb *next;
378: void (*tof)();
379: void *arg;
380:
381: ATDISABLE(s, trb_lock);
382: if (trb_pendhead && trb->func) {
383: /*
384: * remove the timeout from the pending queue
385: */
386: if (trb_pendhead == trb)
387: trb_pendhead = trb->to_next;
388: else {
389: for (next=trb_pendhead; next->to_next; next=next->to_next) {
390: if (next->to_next == trb) {
391: next->to_next = trb->to_next;
392: trb->func = 0;
393: break;
394: }
395: }
396: if (trb->func) {
397: dPrintf(D_M_ATP,D_L_WARNING,
398: "atalk_clock: %d,%x,%x\n", trb_cnt,trb,trb_pendhead,0,0);
399: /*
400: * we have not found the trb in the pending list - something
401: * has gone wrong here. maybe the trb has been returned to
402: * the free list; in which case, we should simply ignore
403: * this timeout event!
404: */
405: for (next=trb_freehead; next; next=next->to_next) {
406: if (next == trb)
407: {
408: ATENABLE(s, trb_lock);
409: return;
410: }
411: }
412: /*
413: * the trb is not in the free list either - something has
414: * really gone wacky here! all we can do now is put the
415: * trb back into the free list and hope that it will be ok.
416: */
417: trb->to_next = 0;
418: if (trb_freehead)
419: trb_freetail->to_next = trb;
420: else
421: trb_freehead = trb;
422: trb_freetail = trb;
423: trb_cnt++;
424: ATENABLE(s, trb_lock);
425: return;
426: }
427: }
428:
429: /*
430: * process the timeout
431: */
432: trb->func = 0;
433: trb->to_next = 0;
434: tof = trb->tof;
435: trb->tof = 0;
436: arg = (void *)trb->func_data;
437: trb->func_data = 999;
438: if (trb_freehead)
439: trb_freetail->to_next = trb;
440: else
441: trb_freehead = trb;
442: trb_freetail = trb;
443: trb_cnt++;
444: ATENABLE(s, trb_lock);
445: if (tof) {
446: dPrintf(D_M_ATP,D_L_VERBOSE, "atalk_clock: func=%x, arg=%x, %d\n",
447: tof,arg,trb_cnt,0,0);
448: (*tof)(arg);
449: } else {
450: dPrintf(D_M_ATP,D_L_ERROR, "atalk_clock: func=%x, arg=%x, %d\n",
451: tof,arg,trb_cnt,0,0);
452: }
453: } else
454: ATENABLE(s, trb_lock);
455: }
456:
457: void *atalk_timeout(func, arg, ticks) /* AIX version */
458: void (*func)();
459: void *arg;
460: int ticks;
461: {
462: register int s;
463: register struct trb *trb;
464:
465: dPrintf(D_M_ATP,D_L_VERBOSE,
466: "atalk_timeout: func=%x,arg=%x,time=%d, %d,%x\n", func,arg,ticks,trb_cnt,trb_pendhead);
467: /*
468: * set up the timeout request
469: */
470: ATDISABLE(s, trb_lock);
471: if ((trb = trb_freehead) == 0) {
472: ATENABLE(s, trb_lock);
473: dPrintf(D_M_ATP,D_L_WARNING,
474: "atalk_timeout: NO TRB! time=%d, %d\n", ticks,trb_cnt,0,0,0);
475: return 0;
476: }
477: trb_freehead = trb->to_next;
478: trb->to_next = trb_pendhead;
479: trb_pendhead = trb;
480: trb_cnt--;
481: trb->timeout.it_value.tv_sec = ticks / HZ;
482: trb->timeout.it_value.tv_nsec = (ticks % HZ) * (NS_PER_SEC / HZ);
483: trb->knext = 0;
484: trb->kprev = 0;
485: trb->flags = 0;
486: trb->tof = func;
487: trb->func = (void (*)())atalk_clock;
488: trb->func_data = (ulong)arg;
489: trb->ipri = PL_IMP;
490: trb->id = -1;
491:
492: /*
493: * start the timeout
494: */
495: ATENABLE(s, trb_lock);
496: tstart(trb);
497: return (void *)trb;
498: }
499:
500: void atalk_untimeout(func, arg, trb) /* AIX version */
501: void (*func)();
502: void *arg;
503: register struct trb *trb;
504: {
505: register int s;
506: register struct trb *next;
507:
508: dPrintf(D_M_ATP,D_L_VERBOSE,
509: "atalk_untimeout: func=%x,arg=%x, %d\n", func,arg,trb_cnt,0,0);
510:
511: ATDISABLE(s, trb_lock);
512: if (trb == 0) {
513: for (trb=trb_pendhead; trb; trb=trb->to_next) {
514: if ((func == trb->tof) && (arg == (void *)trb->func_data))
515: break;
516: }
517: }
518: if (trb && (trb->func == (void (*)())atalk_clock)
519: && (func == trb->tof) && (arg == (void *)trb->func_data)) {
520: trb->func_data = 999;
521: if (!(trb->flags & T_PENDING))
522: {
523: trb->tof = 0;
524: ATENABLE(s, trb_lock);
525: return;
526: }
527: trb->func = 0;
528: while (tstop(trb));
529: if (trb_pendhead == trb)
530: trb_pendhead = trb->to_next;
531: else {
532: for (next=trb_pendhead; next->to_next != trb; next=next->to_next) {
533: if (next->to_next == 0) {
534: ATENABLE(s, trb_lock);
535: dPrintf(D_M_ATP,D_L_WARNING,
536: "atalk_untimeout: UNKNOWN TRB %x...\n",trb,0,0,0,0);
537: return;
538: }
539: }
540: next->to_next = trb->to_next;
541: }
542: trb->to_next = 0;
543: trb_freetail->to_next = trb;
544: trb_freetail = trb;
545: trb_cnt++;
546: }
547: ATENABLE(s, trb_lock);
548: }
549:
550: int config_atalk(dev, cmd, uiop) /* AIX only */
551: dev_t dev;
552: int cmd;
553: void *uiop;
554: {
555: static int loaded = 0;
556: int err, nest;
557:
558: err = 0;
559: nest = lockl(&kernel_lock, LOCK_SHORT);
560:
561: if (cmd == CFG_INIT) {
562: if (loaded)
563: goto out;
564: vm_protect(0, 4096, 3);
565: atalk_timeoutcf(256);
566: atalk_load();
567: loaded = 1;
568:
569: } else if (cmd == CFG_TERM) {
570: if (!loaded)
571: goto out;
572: atalk_rem_timeoutcf();
573: atalk_unload();
574: loaded = 0;
575:
576: } else
577: err = EINVAL;
578:
579: out:
580: if (nest != LOCK_NEST)
581: unlockl(&kernel_lock);
582: return(err);
583: }
584:
585: #endif
586:
587: From sys_glue.c:
588:
589: #ifdef _AIX /* AIX code, to the end of this file, is no longer supported. */
590:
591: int _ATselect(fp, corl, reqevents, retevents, notify) /* AIX version */
592: void *fp;
593: int corl;
594: unsigned short reqevents;
595: unsigned short *retevents;
596: void (*notify)();
597: {
598: int s, err, rc = 0;
599: gref_t *gref;
600: unsigned short sevents = 0;
601:
602: if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
603: return err;
604:
605: ATDISABLE(s, gref->lock);
606: if (reqevents & POLLIN) {
607: if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
608: sevents |= POLLIN;
609: }
610:
611: if (reqevents & POLLOUT) {
612: if (gref->writeable) {
613: if ((*gref->writeable)(gref))
614: sevents |= POLLOUT;
615: } else
616: sevents |= POLLOUT;
617: }
618:
619: if ((sevents == 0) && ((reqevents & POLLSYNC) == 0)) {
620: if (rc = selreg(corl, 99, gref, reqevents, notify)) {
621: ATENABLE(s, gref->lock);
622: goto l_done;
623: }
624:
625: if (reqevents & POLLIN) {
626: if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
627: sevents |= POLLIN;
628: else
629: gref->sevents |= POLLIN;
630: }
631:
632: if (reqevents & POLLOUT) {
633: if (gref->writeable) {
634: if ((*gref->writeable)(gref))
635: sevents |= POLLOUT;
636: else
637: gref->sevents |= POLLOUT;
638: } else
639: sevents |= POLLOUT;
640: }
641: }
642: ATENABLE(s, gref->lock);
643: *retevents = sevents;
644:
645: l_done:
646: return rc;
647: }
648: #endif /* end AIX section */
649:
650: From drv_dep.c:
651:
652:
653:
654:
655: #ifdef _AIX
656: /* AIX section to end of file (not supported) */
657:
658: /* from beginning of file ... */
659: #include <sys/cdli.h>
660: #include <sys/ndd.h>
661: static struct ns_8022 elap_link; /* The SNAP header description */
662: static struct ns_user elap_user; /* The interface to the demuxer */
663:
664: int
665: pat_ifpresent(name) /* AIX */
666: char *name;
667: {
668: return (int)ifunit(name);
669: }
670:
671: int
672: pat_output(pat_id, mlist, dst_addr, type) /* AIX */
673: int pat_id;
674: gbuf_t *mlist;
675: unsigned char *dst_addr;
676: int type;
677: {
678: int len;
679: pat_unit_t *patp;
680: gbuf_t *m, *m_prev, *new_mlist, *m_temp;
681: struct ndd *nddp;
682: short size;
683: enet_header_t *enet_header;
684: llc_header_t *llc_header;
685:
686: patp = (pat_unit_t *)&pat_units[pat_id];
687: if (patp->state != PAT_ONLINE) {
688: gbuf_freel(mlist);
689: return ENOTREADY;
690: }
691:
692: if (patp->xtype == IFTYPE_NULLTALK) {
693: gbuf_freel(mlist);
694: return 0;
695: }
696:
697: nddp = (void *)patp->nddp;
698: new_mlist = 0;
699:
700: for (m = mlist; m; m = mlist) {
701: mlist = gbuf_next(m);
702: gbuf_next(m) = 0;
703:
704: gbuf_prepend(m,ENET_LLC_SIZE);
705: if (m == 0) {
706: if (mlist)
707: gbuf_freel(mlist);
708: if (new_mlist)
709: gbuf_freel(new_mlist);
710: return 0;
711: }
712:
713: enet_header = (enet_header_t *)gbuf_rptr(m);
714: bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst));
715: bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src));
716: size = gbuf_msgsize(m);
717: enet_header->len = size - sizeof(enet_header_t);
718: llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t));
719: *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
720:
721: m->m_pkthdr.len = size;
722: m->m_pkthdr.rcvif = 0;
723:
724: if (new_mlist)
725: gbuf_next(m_prev) = m;
726: else
727: new_mlist = m;
728: m_prev = m;
729: pktsOut++;
730: }
731:
732: if (new_mlist)
733: (*nddp->ndd_output)(nddp, new_mlist);
734:
735: return 0;
736: }
737:
738: int
739: pat_online (ifName, ifType) /* AIX */
740: char *ifName;
741: char *ifType;
742: {
743: void pat_input();
744: int pat_id;
745: pat_unit_t *patp;
746: struct ndd *nddp;
747: char ns_name[8];
748:
749: if ((pat_id = pat_ID(ifName)) == -1)
750: return (-1);
751: patp = &pat_units[pat_id];
752:
753: if (patp->xtype == IFTYPE_ETHERTALK) {
754: ns_name[0] = ifName[0];
755: ns_name[1] = 'n';
756: strcpy(&ns_name[2], &ifName[1]);
757: } else if (patp->xtype == IFTYPE_NULLTALK) {
758: patp->xaddrlen = 6;
759: bzero(patp->xaddr, patp->xaddrlen);
760: if (ifType)
761: *ifType = patp->xtype;
762: patp->nddp = (void *)0;
763: patp->state = PAT_ONLINE;
764: at_statep->flags |= AT_ST_IF_CHANGED;
765: return (pat_id);
766: } else
767: return -1;
768:
769: if (ns_alloc(ns_name, &nddp))
770: return -1;
771:
772: bzero(&elap_user, sizeof(elap_user));
773: elap_user.isr = pat_input;
774: elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC;
775:
776: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
777: elap_link.orgcode[0] = 0;
778: elap_link.orgcode[2] = 0;
779: elap_link.dsap = DSAP_SNAP;
780: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
781: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user))
782: return -1;
783:
784: elap_link.orgcode[0] = 0x08;
785: elap_link.orgcode[2] = 0x07;
786: elap_link.ethertype = 0x809b; /* DDP SNAP code */
787: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) {
788: elap_link.orgcode[0] = 0;
789: elap_link.orgcode[2] = 0;
790: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
791: (void)ns_del_filter(nddp, &elap_link, sizeof(elap_link));
792: return -1;
793: }
794:
795: patp->xaddrlen = nddp->ndd_addrlen;
796: bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen);
797:
798: if (ifType)
799: *ifType = patp->xtype;
800:
801: patp->nddp = (void *)nddp;
802: patp->state = PAT_ONLINE;
803: at_statep->flags |= AT_ST_IF_CHANGED;
804:
805: return (pat_id);
806: }
807:
808: void
809: pat_offline(pat_id) /* AIX */
810: int pat_id;
811: {
812: pat_unit_t *patp = &pat_units[pat_id];
813:
814: if (patp->state == PAT_ONLINE) {
815: if (patp->xtype != IFTYPE_NULLTALK) {
816: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
817: elap_link.orgcode[0] = 0;
818: elap_link.orgcode[2] = 0;
819: elap_link.dsap = DSAP_SNAP;
820: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
821: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
822: elap_link.orgcode[0] = 0x08;
823: elap_link.orgcode[2] = 0x07;
824: elap_link.ethertype = 0x809b; /* DDP SNAP code */
825: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
826: ns_free(patp->nddp);
827: }
828: at_statep->flags |= AT_ST_IF_CHANGED;
829: bzero(patp, sizeof(pat_unit_t));
830: }
831: }
832:
833: int
834: pat_mcast(pat_id, control, data) /* AIX */
835: int pat_id;
836: int control;
837: unsigned char *data;
838: {
839: struct ndd *nddp;
840:
841: nddp = (struct ndd *)pat_units[pat_id].nddp;
842: return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ?
843: NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS,
844: data, nddp->ndd_addrlen);
845: }
846:
847: void
848: pat_input(nddp, m, unused) /* AIX */
849: struct ndd *nddp;
850: gbuf_t *m;
851: void *unused;
852: {
853: extern int ddprunning_flag;
854: llc_header_t *llc_header;
855: int pat_id;
856: pat_unit_t *patp;
857: char src[6];
858: enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m);
859:
860: for (pat_id=0, patp = &pat_units[pat_id];
861: pat_id < xpatcnt; pat_id++, patp++) {
862: if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp))
863: break;
864: }
865: if (pat_id == xpatcnt) {
866: gbuf_freem(m);
867: return;
868: }
869:
870: /* Ignore multicast packets from local station */
871: if (patp->xtype == IFTYPE_ETHERTALK) {
872: bcopy((char *)enet_header->src, src, sizeof(src));
873: if ((enet_header->dst[0] & 1) &&
874: (bcmp(src, patp->xaddr, sizeof(src)) == 0)) {
875: gbuf_freem(m);
876: return;
877: }
878: llc_header = (llc_header_t *)(enet_header+1);
879: }
880:
881: gbuf_rinc(m,(ENET_LLC_SIZE));
882: (void)fetch_and_add((atomic_p)&ddprunning_flag, 1);
883: pktsIn++;
884: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
885: patp->aarp_func(gbuf_rptr(m), patp->context);
886: gbuf_freem(m);
887: } else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) {
888: /* if we're a router take all pkts */
889: if (!ROUTING_MODE) {
890: if (patp->addr_check(gbuf_rptr(m), patp->context)
891: == AARP_ERR_NOT_OURS) {
892: gbuf_freem(m);
893: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
894: return;
895: }
896: }
897: gbuf_set_type(m, MSG_DATA);
898: elap_input(m, patp->context, src);
899: } else
900: gbuf_freem(m);
901: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
902: }
903: #endif /* AIX */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.