|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright 1994 Apple Computer, Inc.
27: * All Rights Reserved.
28: *
29: * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
30: * The copyright notice above does not evidence any actual or
31: * intended publication of such source code.
32: *
33: */
34:
35: #include <localglue.h>
36: #include <sysglue.h>
37: #include <at/appletalk.h>
38: #include <at/elap.h>
39: #include <at/at_lap.h>
40: #include <atlog.h>
41: #include <lap.h>
42: #include <at_elap.h>
43: #include <at_aarp.h>
44: #include <at_pat.h>
45: #include <routing_tables.h>
46:
47: #include <sys/socket.h>
48: #include <sys/socketvar.h>
49: #include <sys/sockio.h>
50: #include <net/if.h>
51: #include <net/if_dl.h>
52: #include <net/etherdefs.h>
53: #include <net/tokendefs.h>
54:
55: #define DSAP_SNAP 0xaa
56:
57: extern at_state_t *at_statep;
58: extern elap_specifics_t elap_specifics[];
59:
60: static llc_header_t snap_hdr_at = SNAP_HDR_AT;
61: static llc_header_t snap_hdr_aarp = SNAP_HDR_AARP;
62: static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT;
63: static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP;
64: /* static struct etalk_addr etalk_mcast_base =
65: {0x09,0x00,0x07,0x00,0x00,0x00}; *** not used ***
66: */
67: int pktsIn, pktsOut;
68: int xpatcnt = 0;
69:
70: extern pat_unit_t pat_units[];
71:
72: #ifndef _AIX
73:
74: /* struct ifnet atalkif[1]; *** not used *** */
75: struct ifqueue atalkintrq; /* appletalk and aarp packet input queue */
76:
77: /* xxdevcnt, xxtype, xxnddp tables are no longer needed since the ifp's
78: are being initialized as a result of actions taken by the drivers.
79: There was a bug in which "xxnddp" was indexed by count in one place,
80: and unit in another place. However upon closer examination we
81: determined that "xxnddp" is no longer needed.
82: Annette DeSchon ([email protected]) 11/20/97
83: */
84:
85: short appletalk_inited = 0;
86:
87: #define FETCH_AND_ADD(x,y) (*x += y)
88:
89:
90: extern int (*sys_ATsocket )(), (*sys_ATgetmsg)(), (*sys_ATputmsg)();
91: extern int (*sys_ATPsndreq)(), (*sys_ATPsndrsp)();
92: extern int (*sys_ATPgetreq)(), (*sys_ATPgetrsp)();
93:
94: void atalk_load()
95: {
96: extern int _ATsocket(), _ATgetmsg(), _ATputmsg();
97: extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
98:
99: extern atlock_t ddpall_lock;
100: extern atlock_t ddpinp_lock;
101: extern atlock_t arpinp_lock;
102:
103: sys_ATsocket = _ATsocket;
104: sys_ATgetmsg = _ATgetmsg;
105: sys_ATputmsg = _ATputmsg;
106: sys_ATPsndreq = _ATPsndreq;
107: sys_ATPsndrsp = _ATPsndrsp;
108: sys_ATPgetreq = _ATPgetreq;
109: sys_ATPgetrsp = _ATPgetrsp;
110:
111: xpatcnt = 0;
112: ATLOCKINIT(ddpall_lock);
113: ATLOCKINIT(ddpinp_lock);
114: ATLOCKINIT(arpinp_lock);
115: gref_init();
116: atp_init();
117: /* adsp_init();
118: for 2225395
119: this happens in adsp_open and is undone on ADSP_UNLINK
120: */
121: } /* atalk_load */
122:
123: void atalk_unload() /* not currently used */
124: {
125: extern gbuf_t *scb_resource_m;
126: extern gbuf_t *atp_resource_m;
127:
128: sys_ATsocket = 0;
129: sys_ATgetmsg = 0;
130: sys_ATputmsg = 0;
131: sys_ATPsndreq = 0;
132: sys_ATPsndrsp = 0;
133: sys_ATPgetreq = 0;
134: sys_ATPgetrsp = 0;
135:
136: if (scb_resource_m) {
137: gbuf_freem(scb_resource_m);
138: scb_resource_m = 0;
139: }
140: if (atp_resource_m) {
141: gbuf_freem(atp_resource_m);
142: atp_resource_m = 0;
143: }
144: /* CleanupGlobals()
145: this happens on ADSP_UNLINK for 2225395 */
146: appletalk_inited = 0;
147: } /* atalk_unload */
148:
149: void appletalk_hack_start(nddp)
150: struct ifnet *nddp;
151: {
152: if (!appletalk_inited) {
153: appletalk_inited =1 ;
154: atalk_load();
155: atalkintrq.ifq_maxlen = IFQ_MAXLEN;
156: }
157:
158: /* Call to pat_attach(nddp) and the "xx" tables are no longer
159: needed since the ifp's are being initialized as a result
160: of actions taken by the drivers. AD 11/21/97 */
161: } /* appletalk_hack_start */
162:
163: /* return the unit number of this interface
164: return -1 if the interface is not found
165: */
166: /* int pat_ifpresent(name) *** not used ***
167: char *name;
168: {
169: struct ifnet *ifp;
170:
171: if (ifp = (ifunit(name)))
172: return(ifp->if_unit);
173: else
174: return(-1);
175: }
176: */
177:
178: int
179: pat_output(pat_id, mlist, dst_addr, type)
180: int pat_id;
181: gbuf_t *mlist;
182: unsigned char *dst_addr;
183: int type;
184: {
185: pat_unit_t *patp;
186: gbuf_t *m, *m_prev, *new_mlist;
187: llc_header_t *llc_header;
188:
189: struct sockaddr dst;
190:
191: /* this is for ether_output */
192:
193: dst.sa_family = AF_APPLETALK;
194: dst.sa_len = sizeof(struct etalk_addr);
195: bcopy (dst_addr, &dst.sa_data[0], dst.sa_len);
196: patp = (pat_unit_t *)&pat_units[pat_id];
197: if (patp->state != PAT_ONLINE) {
198: gbuf_freel(mlist);
199: return ENOTREADY;
200: }
201:
202: if (patp->xtype == IFTYPE_NULLTALK) {
203: gbuf_freel(mlist);
204: return 0;
205: }
206: new_mlist = 0;
207:
208: for (m = mlist; m; m = mlist) {
209: mlist = gbuf_next(m);
210: gbuf_next(m) = 0;
211:
212: gbuf_prepend(m,sizeof(llc_header_t));
213: if (m == 0) {
214: if (mlist)
215: gbuf_freel(mlist);
216: if (new_mlist)
217: gbuf_freel(new_mlist);
218: return 0;
219: }
220:
221: llc_header = (llc_header_t *)gbuf_rptr(m);
222: *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
223:
224: m->m_pkthdr.len = gbuf_msgsize(m);
225: m->m_pkthdr.rcvif = 0;
226:
227: if (new_mlist)
228: gbuf_next(m_prev) = m;
229: else
230: new_mlist = m;
231: m_prev = m;
232: pktsOut++;
233: }
234:
235: while ((m = new_mlist) != 0) {
236: new_mlist = gbuf_next(m);
237: gbuf_next(m) = 0;
238: ((struct ifnet *)patp->nddp)->if_output((void *)patp->nddp, m, &dst, NULL);
239: }
240:
241: return 0;
242: } /* pat_output */
243:
244: int
245: pat_online (ifName, ifType)
246: char *ifName;
247: char *ifType;
248: {
249: /*###int pat_input();*/
250: int pat_id;
251: pat_unit_t *patp;
252: register struct ifaddr *ifa;
253: register struct sockaddr_dl *sdl;
254: struct ifnet *nddp;
255:
256: if ((pat_id = pat_ID(ifName)) == -1)
257: return (-1);
258: patp = &pat_units[pat_id];
259:
260: if (patp->xtype == IFTYPE_ETHERTALK) {
261: if ((nddp = ifunit(ifName)) == NULL)
262: return -1;
263: } else if (patp->xtype == IFTYPE_NULLTALK) {
264: patp->xaddrlen = 6;
265: bzero(patp->xaddr, patp->xaddrlen);
266: if (ifType)
267: *ifType = patp->xtype;
268: patp->nddp = (void *)0;
269: patp->state = PAT_ONLINE;
270: at_statep->flags |= AT_ST_IF_CHANGED;
271: return (pat_id);
272: } else
273: return -1;
274:
275: /*###********* No need to declare ourself as an if for now
276: if_attach(NULL, pat_input, 0, 0, 0,
277: if_name((void *)nddp), if_unit((void *)nddp), "AppleTalk",
278: 622, IFF_BROADCAST, NETIFCLASS_VIRTUAL, 0);
279: */
280:
281: /* if_control((void *)nddp, IFCONTROL_GETADDR, patp->xaddr); */
282:
283: for (ifa = nddp->if_addrlist; ifa; ifa = ifa->ifa_next)
284: if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
285: (sdl->sdl_family == AF_LINK)) {
286: bcopy(LLADDR(sdl), patp->xaddr, 6);
287: #ifdef APPLETALK_DEBUG
288: kprintf("pat_online: our local enet address is=%s\n",
289: ether_sprintf(patp->xaddr));
290: #endif
291: break;
292: }
293:
294: patp->xaddrlen = 6;
295:
296: if (ifType)
297: *ifType = patp->xtype;
298:
299: patp->nddp = (void *)nddp;
300: patp->state = PAT_ONLINE;
301: at_statep->flags |= AT_ST_IF_CHANGED;
302:
303: return (pat_id);
304: } /* pat_online */
305:
306: void
307: pat_offline(pat_id)
308: int pat_id;
309: {
310: pat_unit_t *patp = &pat_units[pat_id];
311:
312: if (patp->state == PAT_ONLINE) {
313: /*#####
314: if (patp->xtype != IFTYPE_NULLTALK) {
315:
316: if_detach((void *)patp->nddp);
317: }
318: */
319: at_statep->flags |= AT_ST_IF_CHANGED;
320: bzero(patp, sizeof(pat_unit_t));
321: }
322: } /* pat_offline */
323:
324: int
325: pat_mcast(pat_id, control, data)
326: int pat_id;
327: int control;
328: unsigned char *data;
329: {
330: struct ifnet *nddp;
331: struct ifreq request;
332:
333: /* this is for ether_output */
334:
335: request.ifr_addr.sa_family = AF_UNSPEC;
336: request.ifr_addr.sa_len = 6; /* warning ### */
337: bcopy (data, &request.ifr_addr.sa_data[0], 6);
338:
339: nddp = (struct ifnet *)pat_units[pat_id].nddp;
340:
341: /*### LD Direct access to the ifp->if_ioctl function */
342:
343: if (nddp == 0) {
344: #ifdef APPLETALK_DEBUG
345: kprintf("pat_mcast: BAD ndpp\n");
346: #endif
347: return(-1);
348: }
349: #ifdef APPLETALK_DEBUG
350: else kprintf("pat_mcast: register multicast for ifname=%s\n", nddp->if_name);
351: #endif
352: return (*nddp->if_ioctl)(nddp, (control == PAT_REG_MCAST) ?
353: SIOCADDMULTI : SIOCDELMULTI, &request);
354: } /* pat_mcast */
355:
356: void
357: atalkintr()
358: {
359: struct mbuf *m;
360: struct ifnet *ifp;
361: int s, ret;
362:
363: next:
364: s = splimp();
365: IF_DEQUEUE(&atalkintrq, m);
366: splx(s);
367:
368: if (m == 0)
369: return;
370:
371: if ((m->m_flags & M_PKTHDR) == 0) {
372: #ifdef APPLETALK_DEBUG
373: kprintf("atalkintr: no HDR on packet received");
374: #endif
375: return;
376: }
377:
378: ifp = m->m_pkthdr.rcvif;
379:
380: /* do stuff */
381: /*
382: if (m->m_len < ENET_LLC_SIZE &&
383: (m = m_pullup(m, ENET_LLC_SIZE)) == 0) {
384: kprintf("atalkintr: packet too small\n");
385: goto next;
386: }
387: */
388:
389: ret = pat_input(NULL, ifp, m);
390: /*
391: if (ret)
392: kprintf("atalkintr: pat_input ret=%d\n", ret);
393: */
394: goto next;
395: } /* atalkintr */
396:
397:
398: int
399: pat_input(xddp, nddp, m)
400: void *xddp;
401: void *nddp;
402: gbuf_t *m;
403: {
404: #ifdef CHECK_DDPR_FLAG
405: extern int ddprunning_flag;
406: #endif
407: llc_header_t *llc_header;
408: int pat_id;
409: pat_unit_t *patp;
410: char src[6];
411: enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m);
412:
413: for (pat_id=0, patp = &pat_units[pat_id];
414: pat_id < xpatcnt; pat_id++, patp++) {
415: if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp))
416: break;
417: }
418: /* if we didn't find a matching interface */
419: if (pat_id == xpatcnt) {
420: gbuf_freem(m);
421: #ifdef CHECK_DDPR_FLAG
422: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1);
423: #endif
424: return EAFNOSUPPORT;
425: }
426:
427: /* Ignore multicast packets from local station */
428: if (patp->xtype == IFTYPE_ETHERTALK) {
429: bcopy((char *)enet_header->src, src, sizeof(src));
430: /*
431: kprintf("pat_input: Packet received src addr=%s len=%x\n",
432: ether_sprintf(enet_header->src), enet_header->len);
433: */
434: /* In order to receive packets from the Blue Box, we cannot reject packets
435: whose source address matches our local address.
436: if ((enet_header->dst[0] & 1) &&
437: (bcmp(src, patp->xaddr, sizeof(src)) == 0)) {
438: #ifdef APPLETALK_DEBUG
439: kprintf("pat_input: Packet rejected: think it's a local mcast\n");
440: #endif
441: gbuf_freem(m);
442: #ifdef CHECK_DDPR_FLAG
443: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1);
444: #endif
445: return EAFNOSUPPORT;
446: }
447: */
448:
449: llc_header = (llc_header_t *)(enet_header+1);
450:
451: gbuf_rinc(m,(ENET_LLC_SIZE));
452: #ifdef CHECK_DDPR_FLAG
453: FETCH_AND_ADD((atomic_p)&ddprunning_flag, 1);
454: #endif
455: pktsIn++;
456: /*
457: kprintf("pat_input: enet_header: dest=%s LLC_PROTO= %02x%02x\n",
458: ether_sprintf(enet_header->dst),
459: llc_header->protocol[3],
460: llc_header->protocol[4]);
461: */
462:
463: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
464: /*
465: kprintf("pat_input: Calling aarp_func dest=%s LLC_PROTO=%02x%02x\n",
466: ether_sprintf(enet_header->dst),
467: llc_header->protocol[3],
468: llc_header->protocol[4]);
469: */
470: patp->aarp_func(gbuf_rptr(m), patp->context);
471: gbuf_freem(m);
472: }
473: else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) {
474: /* if we're a router take all pkts */
475: if (!ROUTING_MODE) {
476: if (patp->addr_check(gbuf_rptr(m), patp->context)
477: == AARP_ERR_NOT_OURS) {
478: /*
479: kprintf("pat_input: Packet Rejected: not for us? dest=%s LLC_PROTO= %02x%02x\n",
480: ether_sprintf(enet_header->dst),
481: llc_header->protocol[3],
482: llc_header->protocol[4]);
483: */
484: gbuf_freem(m);
485: #ifdef CHECK_DDPR_FLAG
486: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1);
487: #endif
488: return EAFNOSUPPORT;
489: }
490: }
491: gbuf_set_type(m, MSG_DATA);
492: elap_input(m, patp->context, src);
493: } else {
494: gbuf_rdec(m,(ENET_LLC_SIZE));
495:
496: #ifdef APPLETALK_DEBUG
497: kprintf("pat_input: Packet Rejected: wrong LLC_PROTO dest=%s LLC_PROTO= %02x%02x\n",
498: ether_sprintf(enet_header->dst),
499: llc_header->protocol[3],
500: llc_header->protocol[4]);
501: #endif
502: gbuf_freem(m);
503: #ifdef CHECK_DDPR_FLAG
504: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1);
505: #endif
506: return EAFNOSUPPORT;
507: }
508: }
509: #ifdef CHECK_DDPR_FLAG
510: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1);
511: #endif
512: return 0;
513: } /* pat_input */
514:
515: #else /* AIX section to end of file (not supported) */
516:
517: /* from beginning of file ... */
518: #include <sys/cdli.h>
519: #include <sys/ndd.h>
520: static struct ns_8022 elap_link; /* The SNAP header description */
521: static struct ns_user elap_user; /* The interface to the demuxer */
522:
523: int
524: pat_ifpresent(name) /* AIX */
525: char *name;
526: {
527: return (int)ifunit(name);
528: }
529:
530: int
531: pat_output(pat_id, mlist, dst_addr, type) /* AIX */
532: int pat_id;
533: gbuf_t *mlist;
534: unsigned char *dst_addr;
535: int type;
536: {
537: int len;
538: pat_unit_t *patp;
539: gbuf_t *m, *m_prev, *new_mlist, *m_temp;
540: struct ndd *nddp;
541: short size;
542: enet_header_t *enet_header;
543: llc_header_t *llc_header;
544:
545: patp = (pat_unit_t *)&pat_units[pat_id];
546: if (patp->state != PAT_ONLINE) {
547: gbuf_freel(mlist);
548: return ENOTREADY;
549: }
550:
551: if (patp->xtype == IFTYPE_NULLTALK) {
552: gbuf_freel(mlist);
553: return 0;
554: }
555:
556: nddp = (void *)patp->nddp;
557: new_mlist = 0;
558:
559: for (m = mlist; m; m = mlist) {
560: mlist = gbuf_next(m);
561: gbuf_next(m) = 0;
562:
563: gbuf_prepend(m,ENET_LLC_SIZE);
564: if (m == 0) {
565: if (mlist)
566: gbuf_freel(mlist);
567: if (new_mlist)
568: gbuf_freel(new_mlist);
569: return 0;
570: }
571:
572: enet_header = (enet_header_t *)gbuf_rptr(m);
573: bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst));
574: bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src));
575: size = gbuf_msgsize(m);
576: enet_header->len = size - sizeof(enet_header_t);
577: llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t));
578: *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
579:
580: m->m_pkthdr.len = size;
581: m->m_pkthdr.rcvif = 0;
582:
583: if (new_mlist)
584: gbuf_next(m_prev) = m;
585: else
586: new_mlist = m;
587: m_prev = m;
588: pktsOut++;
589: }
590:
591: if (new_mlist)
592: (*nddp->ndd_output)(nddp, new_mlist);
593:
594: return 0;
595: }
596:
597: int
598: pat_online (ifName, ifType) /* AIX */
599: char *ifName;
600: char *ifType;
601: {
602: void pat_input();
603: int pat_id;
604: pat_unit_t *patp;
605: struct ndd *nddp;
606: char ns_name[8];
607:
608: if ((pat_id = pat_ID(ifName)) == -1)
609: return (-1);
610: patp = &pat_units[pat_id];
611:
612: if (patp->xtype == IFTYPE_ETHERTALK) {
613: ns_name[0] = ifName[0];
614: ns_name[1] = 'n';
615: strcpy(&ns_name[2], &ifName[1]);
616: } else if (patp->xtype == IFTYPE_NULLTALK) {
617: patp->xaddrlen = 6;
618: bzero(patp->xaddr, patp->xaddrlen);
619: if (ifType)
620: *ifType = patp->xtype;
621: patp->nddp = (void *)0;
622: patp->state = PAT_ONLINE;
623: at_statep->flags |= AT_ST_IF_CHANGED;
624: return (pat_id);
625: } else
626: return -1;
627:
628: if (ns_alloc(ns_name, &nddp))
629: return -1;
630:
631: bzero(&elap_user, sizeof(elap_user));
632: elap_user.isr = pat_input;
633: elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC;
634:
635: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
636: elap_link.orgcode[0] = 0;
637: elap_link.orgcode[2] = 0;
638: elap_link.dsap = DSAP_SNAP;
639: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
640: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user))
641: return -1;
642:
643: elap_link.orgcode[0] = 0x08;
644: elap_link.orgcode[2] = 0x07;
645: elap_link.ethertype = 0x809b; /* DDP SNAP code */
646: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) {
647: elap_link.orgcode[0] = 0;
648: elap_link.orgcode[2] = 0;
649: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
650: (void)ns_del_filter(nddp, &elap_link, sizeof(elap_link));
651: return -1;
652: }
653:
654: patp->xaddrlen = nddp->ndd_addrlen;
655: bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen);
656:
657: if (ifType)
658: *ifType = patp->xtype;
659:
660: patp->nddp = (void *)nddp;
661: patp->state = PAT_ONLINE;
662: at_statep->flags |= AT_ST_IF_CHANGED;
663:
664: return (pat_id);
665: }
666:
667: void
668: pat_offline(pat_id) /* AIX */
669: int pat_id;
670: {
671: pat_unit_t *patp = &pat_units[pat_id];
672:
673: if (patp->state == PAT_ONLINE) {
674: if (patp->xtype != IFTYPE_NULLTALK) {
675: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP;
676: elap_link.orgcode[0] = 0;
677: elap_link.orgcode[2] = 0;
678: elap_link.dsap = DSAP_SNAP;
679: elap_link.ethertype = 0x80f3; /* AARP SNAP code */
680: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
681: elap_link.orgcode[0] = 0x08;
682: elap_link.orgcode[2] = 0x07;
683: elap_link.ethertype = 0x809b; /* DDP SNAP code */
684: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link));
685: ns_free(patp->nddp);
686: }
687: at_statep->flags |= AT_ST_IF_CHANGED;
688: bzero(patp, sizeof(pat_unit_t));
689: }
690: }
691:
692: int
693: pat_mcast(pat_id, control, data) /* AIX */
694: int pat_id;
695: int control;
696: unsigned char *data;
697: {
698: struct ndd *nddp;
699:
700: nddp = (struct ndd *)pat_units[pat_id].nddp;
701: return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ?
702: NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS,
703: data, nddp->ndd_addrlen);
704: }
705:
706: void
707: pat_input(nddp, m, unused) /* AIX */
708: struct ndd *nddp;
709: gbuf_t *m;
710: void *unused;
711: {
712: extern int ddprunning_flag;
713: llc_header_t *llc_header;
714: int pat_id;
715: pat_unit_t *patp;
716: char src[6];
717: enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m);
718:
719: for (pat_id=0, patp = &pat_units[pat_id];
720: pat_id < xpatcnt; pat_id++, patp++) {
721: if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp))
722: break;
723: }
724: if (pat_id == xpatcnt) {
725: gbuf_freem(m);
726: return;
727: }
728:
729: /* Ignore multicast packets from local station */
730: if (patp->xtype == IFTYPE_ETHERTALK) {
731: bcopy((char *)enet_header->src, src, sizeof(src));
732: if ((enet_header->dst[0] & 1) &&
733: (bcmp(src, patp->xaddr, sizeof(src)) == 0)) {
734: gbuf_freem(m);
735: return;
736: }
737: llc_header = (llc_header_t *)(enet_header+1);
738: }
739:
740: gbuf_rinc(m,(ENET_LLC_SIZE));
741: (void)fetch_and_add((atomic_p)&ddprunning_flag, 1);
742: pktsIn++;
743: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
744: patp->aarp_func(gbuf_rptr(m), patp->context);
745: gbuf_freem(m);
746: } else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) {
747: /* if we're a router take all pkts */
748: if (!ROUTING_MODE) {
749: if (patp->addr_check(gbuf_rptr(m), patp->context)
750: == AARP_ERR_NOT_OURS) {
751: gbuf_freem(m);
752: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
753: return;
754: }
755: }
756: gbuf_set_type(m, MSG_DATA);
757: elap_input(m, patp->context, src);
758: } else
759: gbuf_freem(m);
760: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1);
761: }
762: #endif /* AIX */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.