|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1982, 1989, 1993
24: * The Regents of the University of California. All rights reserved.
25: *
26: * Redistribution and use in source and binary forms, with or without
27: * modification, are permitted provided that the following conditions
28: * are met:
29: * 1. Redistributions of source code must retain the above copyright
30: * notice, this list of conditions and the following disclaimer.
31: * 2. Redistributions in binary form must reproduce the above copyright
32: * notice, this list of conditions and the following disclaimer in the
33: * documentation and/or other materials provided with the distribution.
34: * 3. All advertising materials mentioning features or use of this software
35: * must display the following acknowledgement:
36: * This product includes software developed by the University of
37: * California, Berkeley and its contributors.
38: * 4. Neither the name of the University nor the names of its contributors
39: * may be used to endorse or promote products derived from this software
40: * without specific prior written permission.
41: *
42: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52: * SUCH DAMAGE.
53: *
54: */
55:
56:
57:
58: #include <sys/param.h>
59: #include <sys/systm.h>
60: #include <sys/kernel.h>
61: #include <sys/malloc.h>
62: #include <sys/mbuf.h>
63: #include <sys/socket.h>
64: #include <sys/sockio.h>
65: #include <sys/sysctl.h>
66:
67: #include <net/if.h>
68: #include <net/netisr.h>
69: #include <net/route.h>
70: #include <net/if_llc.h>
71: #include <net/if_dl.h>
72: #include <net/if_types.h>
73: #include <net/ndrv.h>
74:
75: #if INET
76: #include <netinet/in.h>
77: #include <netinet/in_var.h>
78: #include <netinet/if_ether.h>
79: #include <netinet/in_systm.h>
80: #include <netinet/ip.h>
81: #endif
82:
83:
84: #include <sys/socketvar.h>
85: #include <net/if_blue.h>
86:
87: #include <net/dlil.h>
88:
89:
90: #if LLC && CCITT
91: extern struct ifqueue pkintrq;
92: #endif
93:
94: /* General stuff from if_ethersubr.c - may not need some of it */
95:
96: #include <netat/at_pat.h>
97: #if NETAT
98: extern struct ifqueue atalkintrq;
99: #endif
100:
101:
102: #if BRIDGE
103: #include <net/bridge.h>
104: #endif
105:
106: /* #include "vlan.h" */
107: #if NVLAN > 0
108: #include <net/if_vlan_var.h>
109: #endif /* NVLAN > 0 */
110:
111:
112: extern struct ifnet_blue *blue_if;
113: extern struct mbuf *splitter_input(struct mbuf *, struct ifnet *);
114:
115: static u_long lo_dlt = 0;
116: static ivedonethis = 0;
117: static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
118: struct sockaddr *));
119: u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
120:
121: #define IFP2AC(IFP) ((struct arpcom *)IFP)
122:
123: /* This stuff is new */
124:
125: #define DB_HEADER_SIZE 20
126: struct en_desc {
127: short total_len;
128: u_short ethertype;
129: u_long dl_tag;
130: struct ifnet *ifp;
131: struct if_proto *proto;
132: u_long proto_id_length;
133: u_long proto_id_data[8]; /* probably less - proto-id and bitmasks */
134: };
135:
136: #define LITMUS_SIZE 16
137: #define ETHER_DESC_BLK_SIZE 50
138: #define MAX_INTERFACES 50
139:
140: /*
141: * Statics for demux module
142: */
143:
144: struct ether_desc_blk_str {
145: u_long n_blocks;
146: u_long *block_ptr;
147: };
148:
149: static struct ether_desc_blk_str ether_desc_blk[MAX_INTERFACES];
150: static u_long litmus_mask[LITMUS_SIZE];
151: static u_long litmus_length = 0;
152:
153:
154: /*
155: * Temp static for protocol registration XXX
156: */
157:
158: #define MAX_EN_COUNT 30
159:
160: static struct if_proto *en_array[MAX_EN_COUNT];
161:
162: /*
163: * This could be done below in-line with heavy casting, but the pointer arithmetic is
164: * prone to error.
165: */
166:
167: static
168: int desc_in_bounds(block, current_ptr, offset_length)
169: u_int block;
170: char *current_ptr;
171: u_long offset_length;
172: {
173: u_long end_of_block;
174: u_long current_ptr_tmp;
175:
176: current_ptr_tmp = (u_long) current_ptr;
177: end_of_block = (u_long) ether_desc_blk[block].block_ptr;
178: end_of_block += (ETHER_DESC_BLK_SIZE * ether_desc_blk[block].n_blocks);
179: if ((current_ptr_tmp + offset_length) < end_of_block)
180: return 1;
181: else
182: return 0;
183: }
184:
185:
186: /*
187: * Release all descriptor entries owned by this dl_tag (there may be several).
188: * Setting the dl_tag to 0 releases the entry. Eventually we should compact-out
189: * the unused entries.
190: */
191: static
192: int ether_del_proto(struct if_proto *proto, u_long dl_tag)
193: {
194: char *current_ptr = (char *) ether_desc_blk[proto->ifp->family_cookie].block_ptr;
195: struct en_desc *ed;
196: int i;
197: int found = 0;
198:
199: ed = (struct en_desc *) current_ptr;
200:
201: while(ed->total_len) {
202: if (ed->dl_tag == dl_tag) {
203: found = 1;
204: ed->dl_tag = 0;
205: }
206:
207: current_ptr += ed->total_len;
208: ed = (struct en_desc *) current_ptr;
209: }
210:
211: if (found) {
212: for (i=0; i < MAX_EN_COUNT; i++)
213: if (en_array[i] == proto) {
214: en_array[i] = 0;
215: break;
216: }
217:
218: return 0;
219: }
220: else
221: return ENOENT;
222: }
223:
224:
225:
226: static
227: int ether_add_proto(struct ddesc_head_str *desc_head, struct if_proto *proto, u_long dl_tag)
228: {
229: char *current_ptr;
230: struct dlil_demux_desc *desc;
231: u_long id_length; /* IN LONGWORDS!!! */
232: struct en_desc *ed;
233: u_long *bitmask;
234: u_long *proto_id;
235: int i;
236: short total_length;
237: u_long block_count;
238: u_long *tmp;
239:
240: for (i=0; i < MAX_EN_COUNT; i++)
241: if (en_array[i] == 0) {
242: en_array[i] = proto;
243: break;
244: }
245:
246: if (i == MAX_EN_COUNT) {
247: printf("WARNING: ether_add_proto -- Too many attachments\n");
248: return ENOMEM;
249: }
250:
251: TAILQ_FOREACH(desc, desc_head, next) {
252: switch (desc->type)
253: {
254: case DLIL_DESC_RAW:
255: id_length = desc->variants.bitmask.proto_id_length;
256: break;
257:
258: case DLIL_DESC_802_2:
259: id_length = 1;
260: break;
261:
262: case DLIL_DESC_802_2_SNAP:
263: id_length = 2;
264: break;
265:
266: default:
267: return EINVAL;
268: }
269:
270: restart:
271: block_count = ether_desc_blk[proto->ifp->family_cookie].n_blocks;
272: current_ptr = (char *) ether_desc_blk[proto->ifp->family_cookie].block_ptr;
273: ed = (struct en_desc *) current_ptr;
274: total_length = ((id_length << 2) * 2) + DB_HEADER_SIZE;
275:
276: while ((ed->total_len) && (desc_in_bounds(proto->ifp->family_cookie,
277: current_ptr, total_length))) {
278: if ((ed->dl_tag == 0) && (total_length <= ed->total_len))
279: break;
280: else
281: current_ptr += *(short *)current_ptr;
282:
283: ed = (struct en_desc *) current_ptr;
284: }
285:
286: if (!desc_in_bounds(proto->ifp->family_cookie, current_ptr, total_length)) {
287:
288: tmp = _MALLOC((ETHER_DESC_BLK_SIZE * (block_count + 1)),
289: M_IFADDR, M_NOWAIT);
290: if (tmp == 0) {
291: /*
292: * Remove any previous descriptors set in the call.
293: */
294: ether_del_proto(proto, dl_tag);
295: return ENOMEM;
296: }
297:
298: bzero(tmp, ETHER_DESC_BLK_SIZE * (block_count + 1));
299: bcopy(ether_desc_blk[proto->ifp->family_cookie].block_ptr,
300: tmp, (ETHER_DESC_BLK_SIZE * block_count));
301: FREE(ether_desc_blk[proto->ifp->family_cookie].block_ptr, M_IFADDR);
302: ether_desc_blk[proto->ifp->family_cookie].n_blocks = block_count + 1;
303: ether_desc_blk[proto->ifp->family_cookie].block_ptr = tmp;
304: goto restart;
305: }
306:
307: if (ed->total_len == 0)
308: ed->total_len = total_length;
309: ed->ethertype = *((u_short *) desc->native_type);
310:
311: ed->dl_tag = dl_tag;
312: ed->proto = proto;
313: ed->proto_id_length = id_length;
314: ed->ifp = proto->ifp;
315:
316: switch (desc->type)
317: {
318: case DLIL_DESC_RAW:
319: bcopy(desc->variants.bitmask.proto_id, &ed->proto_id_data[0], (id_length << 2) );
320: bcopy(desc->variants.bitmask.proto_id_mask, &ed->proto_id_data[id_length],
321: (id_length << 2));
322: break;
323:
324: case DLIL_DESC_802_2:
325: ed->proto_id_data[0] = 0;
326: bcopy(&desc->variants.desc_802_2, &ed->proto_id_data[0], 3);
327: ed->proto_id_data[1] = 0xffffff00;
328: break;
329:
330: case DLIL_DESC_802_2_SNAP:
331: /* XXX Add verification of fixed values here */
332:
333: ed->proto_id_data[0] = 0;
334: ed->proto_id_data[1] = 0;
335: bcopy(&desc->variants.desc_802_2_SNAP, &ed->proto_id_data[0], 8);
336: ed->proto_id_data[2] = 0xffffffff;
337: ed->proto_id_data[3] = 0xffffffff;;
338: break;
339: }
340:
341: if (id_length) {
342: proto_id = (u_long *) &ed->proto_id_data[0];
343: bitmask = (u_long *) &ed->proto_id_data[id_length];
344: for (i=0; i < (id_length); i++) {
345: litmus_mask[i] &= bitmask[i];
346: litmus_mask[i] &= proto_id[i];
347: }
348: if (id_length > litmus_length)
349: litmus_length = id_length;
350: }
351: }
352:
353: return 0;
354: }
355:
356:
357: static
358: int ether_shutdown()
359: {
360: return 0;
361: }
362:
363:
364:
365:
366: /*
367: * Process a received Ethernet packet;
368: * the packet is in the mbuf chain m without
369: * the ether header, which is provided separately.
370: */
371: int
372: new_ether_input(m, frame_header, ifp, dl_tag, sync_ok)
373: struct mbuf *m;
374: char *frame_header;
375: struct ifnet *ifp;
376: u_long dl_tag;
377: int sync_ok;
378:
379: {
380: register struct ether_header *eh = (struct ether_header *) frame_header;
381: register struct ifqueue *inq=0;
382: u_short ether_type;
383: int s;
384: u_int16_t ptype = -1;
385: unsigned char buf[18];
386:
387: #if ISO || LLC || NETAT
388: register struct llc *l;
389: #endif
390:
391:
392: #if DLIL_BLUEBOX
393:
394: /*
395: * Y-adapter input processing:
396: * - Don't split if coming from a dummy if
397: * - If coming from a real if, if splitting enabled,
398: * then filter the incoming packet
399: */
400: if (ifp != (struct ifnet *)blue_if)
401: { /* Is splitter turned on? */
402: if (ifp->if_flags&IFF_SPLITTER)
403: { m->m_data -= sizeof(struct ether_header);
404: m->m_len += sizeof (struct ether_header);
405: m->m_pkthdr.len += sizeof(struct ether_header);
406: /*
407: * Check to see if destined for BlueBox or Rhapsody
408: * If NULL return, mbuf's been consumed by the BlueBox.
409: * Otherwise, send on to Rhapsody
410: */
411: if ((m = splitter_input(m, ifp)) == NULL)
412: return EJUSTRETURN;
413: m->m_data += sizeof(struct ether_header);
414: m->m_len -= sizeof (struct ether_header);
415: m->m_pkthdr.len -= sizeof(struct ether_header);
416: }
417: } else
418: { /* Get the "real" IF */
419: ifp = ((struct ndrv_cb *)(blue_if->ifb_so->so_pcb))->nd_if;
420: m->m_pkthdr.rcvif = ifp;
421: blue_if->pkts_looped_b2r++;
422: }
423:
424: #endif
425: if ((ifp->if_flags & IFF_UP) == 0) {
426: m_freem(m);
427: return EJUSTRETURN;
428: }
429:
430: ifp->if_lastchange = time;
431:
432: if (eh->ether_dhost[0] & 1) {
433: if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
434: sizeof(etherbroadcastaddr)) == 0)
435: m->m_flags |= M_BCAST;
436: else
437: m->m_flags |= M_MCAST;
438: }
439: if (m->m_flags & (M_BCAST|M_MCAST))
440: ifp->if_imcasts++;
441:
442: ether_type = ntohs(eh->ether_type);
443:
444: #if NVLAN > 0
445: if (ether_type == vlan_proto) {
446: if (vlan_input(eh, m) < 0)
447: ifp->if_data.ifi_noproto++;
448: return EJUSTRETURN;
449: }
450: #endif /* NVLAN > 0 */
451:
452: switch (ether_type) {
453: #if INET
454: case ETHERTYPE_IP:
455: if (ipflow_fastforward(m))
456: return EJUSTRETURN;
457: ptype = mtod(m, struct ip *)->ip_p;
458: if ((sync_ok == 0) ||
459: (ptype != IPPROTO_TCP && ptype != IPPROTO_UDP)) {
460: schednetisr(NETISR_IP);
461: }
462:
463: inq = &ipintrq;
464: break;
465:
466: case ETHERTYPE_ARP:
467: schednetisr(NETISR_ARP);
468: inq = &arpintrq;
469: break;
470: #endif
471:
472: default: {
473: #if NETAT
474: if (ether_type > ETHERMTU)
475: return ENOENT;
476: l = mtod(m, struct llc *);
477: switch (l->llc_dsap) {
478: case LLC_SNAP_LSAP:
479:
480: /* Temporary hack: check for AppleTalk and AARP packets */
481: /* WARNING we're checking only on the "ether_type" (the 2 bytes
482: * of the SNAP header. This shouldn't be a big deal,
483: * AppleTalk pat_input is making sure we have the right packets
484: * because it needs to discrimante AARP from EtherTalk packets.
485: */
486:
487: if (l->llc_ssap == LLC_SNAP_LSAP &&
488: l->llc_un.type_snap.control == 0x03) {
489:
490: #ifdef APPLETALK_DEBUG
491: printf("new_ether_input: SNAP Cntrol type=0x%x Src=%s\n",
492: l->llc_un.type_snap.ether_type,
493: ether_sprintf(buf, &eh->ether_shost));
494: printf(" Dst=%s\n",
495: ether_sprintf(buf, &eh->ether_dhost));
496: #endif /* APPLETALK_DEBUG */
497:
498: if ((l->llc_un.type_snap.ether_type == 0x809B) ||
499: (l->llc_un.type_snap.ether_type == 0x80F3)) {
500:
501:
502: /*
503: * note: for AppleTalk we need to pass the enet header of the
504: * packet up stack. To do so, we made sure in that the FULL packet
505: * is copied in the mbuf by the mace driver, and only the m_data and
506: * length have been shifted to make IP and the other guys happy.
507: */
508:
509: m->m_data -= sizeof(*eh);
510: m->m_len += sizeof(*eh);
511: m->m_pkthdr.len += sizeof(*eh);
512: #ifdef APPLETALK_DEBUG
513: l == (struct llc *)(eh+1);
514: if (l->llc_un.type_snap.ether_type == 0x80F3) {
515: kprintf("new_ether_input: RCV AppleTalk type=0x%x Src=%s\n",
516: l->llc_un.type_snap.ether_type,
517: ether_sprintf(buf, &eh->ether_shost));
518: kprintf(" Dst=%s\n",
519: ether_sprintf(buf, &eh->ether_dhost));
520: }
521: #endif /* APPLETALK_DEBUG */
522: schednetisr(NETISR_APPLETALK);
523: inq = &atalkintrq ;
524:
525: break;
526: }
527: }
528:
529: break;
530:
531:
532: default:
533: return ENOENT;
534: }
535:
536: #else /*NETAT*/
537: return ENOENT;
538: #endif /* NETAT */
539:
540: }
541: }
542:
543: if (inq == 0)
544: return ENOENT;
545:
546: s = splimp();
547: if (IF_QFULL(inq)) {
548: IF_DROP(inq);
549: m_freem(m);
550: splx(s);
551: return EJUSTRETURN;
552: } else
553: IF_ENQUEUE(inq, m);
554: splx(s);
555:
556: if ((sync_ok) &&
557: (ptype == IPPROTO_TCP || ptype == IPPROTO_UDP)) {
558: extern void ipintr(void);
559:
560: s = splnet();
561: ipintr();
562: splx(s);
563: }
564:
565: return 0;
566: }
567:
568:
569:
570:
571: int ether_demux(ifp, m, frame_header, proto)
572: struct ifnet *ifp;
573: struct mbuf *m;
574: char *frame_header;
575: struct if_proto **proto;
576:
577: {
578: register struct ether_header *eh = (struct ether_header *)frame_header;
579: u_short ether_type;
580: char *current_ptr = (char *) ether_desc_blk[ifp->family_cookie].block_ptr;
581: struct dlil_demux_desc *desc;
582: register u_long temp;
583: u_long *data;
584: register struct if_proto *ifproto;
585: u_long i;
586: struct en_desc *ed;
587:
588:
589: if (eh->ether_dhost[0] & 1) {
590: if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
591: sizeof(etherbroadcastaddr)) == 0)
592: m->m_flags |= M_BCAST;
593: else
594: m->m_flags |= M_MCAST;
595: }
596:
597: ether_type = ntohs(eh->ether_type);
598:
599: /*
600: * Search through the connected protocols for a match.
601: */
602:
603:
604: data = mtod(m, u_long *);
605: ed = (struct en_desc *) current_ptr;
606: while (desc_in_bounds(ifp->family_cookie, current_ptr, DB_HEADER_SIZE)) {
607: if (ed->total_len == 0)
608: break;
609:
610: if ((ed->dl_tag != 0) && (ed->ifp == ifp) &&
611: ((ed->ethertype == ntohs(eh->ether_type)) || (ed->ethertype == 0))) {
612: if (ed->proto_id_length) {
613: for (i=0; i < (ed->proto_id_length); i++) {
614: temp = ntohs(data[i]) & ed->proto_id_data[ed->proto_id_length + i];
615: if ((temp ^ ed->proto_id_data[i]))
616: break;
617: }
618:
619: if (i >= (ed->proto_id_length)) {
620: *proto = ed->proto;
621: return 0;
622: }
623: }
624: else {
625: *proto = ed->proto;
626: return 0;
627: }
628: }
629: current_ptr += ed->total_len;
630: ed = (struct en_desc *) current_ptr;
631: }
632:
633: /*
634: kprintf("ether_demux - No match for <%x><%x><%x><%x><%x><%x><%x<%x>\n",
635: eh->ether_type,data[0], data[1], data[2], data[3], data[4],data[5],data[6]);
636: */
637:
638: return ENOENT;
639: }
640:
641:
642:
643: /*
644: * Ethernet output routine.
645: * Encapsulate a packet of type family for the local net.
646: * Use trailer local net encapsulation if enough data in first
647: * packet leaves a multiple of 512 bytes of data in remainder.
648: * Assumes that ifp is actually pointer to arpcom structure.
649: */
650: int
651: ether_frameout(ifp, m, ndest, edst, ether_type)
652: register struct ifnet *ifp;
653: struct mbuf **m;
654: struct sockaddr *ndest;
655: char *edst;
656: char *ether_type;
657: {
658: register struct ether_header *eh;
659: int hlen; /* link layer header lenght */
660: struct arpcom *ac = IFP2AC(ifp);
661:
662:
663: hlen = ETHER_HDR_LEN;
664:
665: /*
666: * If a simplex interface, and the packet is being sent to our
667: * Ethernet address or a broadcast address, loopback a copy.
668: * XXX To make a simplex device behave exactly like a duplex
669: * device, we should copy in the case of sending to our own
670: * ethernet address (thus letting the original actually appear
671: * on the wire). However, we don't do that here for security
672: * reasons and compatibility with the original behavior.
673: */
674: if ((ifp->if_flags & IFF_SIMPLEX) &&
675: ((*m)->m_flags & M_LOOP)) {
676: if (lo_dlt == 0)
677: dlil_find_dltag(APPLE_IF_FAM_LOOPBACK, 0, PF_INET, &lo_dlt);
678:
679: if (lo_dlt) {
680: if ((*m)->m_flags & M_BCAST) {
681: struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL);
682: dlil_output(lo_dlt, n, 0, ndest, 0);
683: }
684: else
685: {
686: if (bcmp(edst, ac->ac_enaddr, ETHER_ADDR_LEN) == 0) {
687: dlil_output(lo_dlt, *m, 0, ndest, 0);
688: return EJUSTRETURN;
689: }
690: }
691: }
692: }
693:
694:
695: /*
696: * Add local net header. If no space in first mbuf,
697: * allocate another.
698: */
699: M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT);
700: if (*m == 0) {
701: return (EJUSTRETURN);
702: }
703:
704:
705: eh = mtod(*m, struct ether_header *);
706: (void)memcpy(&eh->ether_type, ether_type,
707: sizeof(eh->ether_type));
708: (void)memcpy(eh->ether_dhost, edst, 6);
709: (void)memcpy(eh->ether_shost, ac->ac_enaddr,
710: sizeof(eh->ether_shost));
711:
712: #if DLIL_BLUEBOX
713: /*
714: * We're already to send. Let's check for the blue box...
715: */
716: if (ifp->if_flags&IFF_SPLITTER)
717: {
718: (*m)->m_flags |= 0x10;
719: if ((*m = splitter_input(*m, ifp)) == NULL)
720: return EJUSTRETURN;
721: else
722: return (0);
723: }
724: else
725: #endif
726: return 0;
727: }
728:
729:
730: static
731: int ether_add_if(struct ifnet *ifp)
732: {
733: u_long i;
734:
735: ifp->if_framer = ether_frameout;
736: ifp->if_demux = ether_demux;
737:
738: for (i=0; i < MAX_INTERFACES; i++)
739: if (ether_desc_blk[i].n_blocks == 0)
740: break;
741:
742: if (i == MAX_INTERFACES)
743: return EOVERFLOW;
744:
745: ether_desc_blk[i].block_ptr = _MALLOC(ETHER_DESC_BLK_SIZE, M_IFADDR, M_NOWAIT);
746: if (ether_desc_blk[i].block_ptr == 0)
747: return ENOMEM;
748:
749: ether_desc_blk[i].n_blocks = 1;
750: bzero(ether_desc_blk[i].block_ptr, ETHER_DESC_BLK_SIZE);
751:
752: ifp->family_cookie = i;
753:
754: return 0;
755: }
756:
757: static
758: int ether_del_if(struct ifnet *ifp)
759: {
760: if ((ifp->family_cookie < MAX_INTERFACES) &&
761: (ether_desc_blk[ifp->family_cookie].n_blocks)) {
762: FREE(ether_desc_blk[ifp->family_cookie].block_ptr, M_IFADDR);
763: ether_desc_blk[ifp->family_cookie].n_blocks = 0;
764: return 0;
765: }
766: else
767: return ENOENT;
768: }
769:
770:
771:
772:
773: int
774: ether_pre_output(ifp, m0, dst_netaddr, route, type, edst, dl_tag )
775: struct ifnet *ifp;
776: struct mbuf **m0;
777: struct sockaddr *dst_netaddr;
778: caddr_t route;
779: char *type;
780: char *edst;
781: u_long dl_tag;
782: {
783: struct rtentry *rt0 = (struct rtentry *) route;
784: int s;
785: register struct mbuf *m = *m0;
786: register struct rtentry *rt;
787: register struct ether_header *eh;
788: int off, len = m->m_pkthdr.len;
789: int hlen; /* link layer header lenght */
790: struct arpcom *ac = IFP2AC(ifp);
791:
792:
793:
794: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
795: return ENETDOWN;
796:
797: rt = rt0;
798: if (rt) {
799: if ((rt->rt_flags & RTF_UP) == 0) {
800: rt0 = rt = rtalloc1(dst_netaddr, 1, 0UL);
801: if (rt0)
802: rt->rt_refcnt--;
803: else
804: return EHOSTUNREACH;
805: }
806:
807: if (rt->rt_flags & RTF_GATEWAY) {
808: if (rt->rt_gwroute == 0)
809: goto lookup;
810: if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
811: rtfree(rt); rt = rt0;
812: lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
813: 0UL);
814: if ((rt = rt->rt_gwroute) == 0)
815: return (EHOSTUNREACH);
816: }
817: }
818:
819:
820: if (rt->rt_flags & RTF_REJECT)
821: if (rt->rt_rmx.rmx_expire == 0 ||
822: time_second < rt->rt_rmx.rmx_expire)
823: return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
824: }
825:
826: hlen = ETHER_HDR_LEN;
827:
828: /*
829: * Tell ether_frameout it's ok to loop packet unless negated below.
830: */
831: m->m_flags |= M_LOOP;
832:
833: switch (dst_netaddr->sa_family) {
834:
835: #if INET
836: case AF_INET:
837: if (!arpresolve(ac, rt, m, dst_netaddr, edst, rt0))
838: return (EJUSTRETURN); /* if not yet resolved */
839: off = m->m_pkthdr.len - m->m_len;
840: *(u_short *)type = htons(ETHERTYPE_IP);
841: break;
842: #endif
843:
844: case AF_UNSPEC:
845: m->m_flags &= ~M_LOOP;
846: eh = (struct ether_header *)dst_netaddr->sa_data;
847: (void)memcpy(edst, eh->ether_dhost, 6);
848: *(u_short *)type = eh->ether_type;
849: break;
850:
851: #if NETAT
852: case AF_APPLETALK:
853: {
854: eh = (struct ether_header *)dst_netaddr->sa_data;
855: bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, 6);
856:
857: *(u_short *)type = m->m_pkthdr.len;
858: }
859: break;
860:
861: #endif /* NETAT */
862:
863: default:
864: kprintf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
865: dst_netaddr->sa_family);
866:
867: return EAFNOSUPPORT;
868: }
869:
870: return (0);
871: }
872:
873:
874:
875:
876:
877: int
878: ether_ioctl(dl_tag, ifp, command, data)
879: u_long dl_tag;
880: struct ifnet *ifp;
881: int command;
882: caddr_t data;
883: {
884: struct ifaddr *ifa = (struct ifaddr *) data;
885: struct ifreq *ifr = (struct ifreq *) data;
886: int error = 0;
887: boolean_t funnel_state;
888:
889: funnel_state = thread_set_funneled(TRUE);
890:
891: switch (command) {
892: case SIOCSIFADDR:
893: ifp->if_flags |= IFF_UP;
894:
895: switch (ifa->ifa_addr->sa_family) {
896:
897: case AF_INET:
898:
899: if (ifp->if_init)
900: ifp->if_init(ifp->if_softc); /* before arpwhohas */
901:
902:
903: arp_ifinit(IFP2AC(ifp), ifa);
904:
905: break;
906:
907: default:
908: break;
909: }
910:
911: break;
912:
913: case SIOCGIFADDR:
914: {
915: struct sockaddr *sa;
916:
917: sa = (struct sockaddr *) & ifr->ifr_data;
918: bcopy(IFP2AC(ifp)->ac_enaddr,
919: (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
920: }
921: break;
922:
923: case SIOCSIFMTU:
924: /*
925: * Set the interface MTU.
926: */
927: if (ifr->ifr_mtu > ETHERMTU) {
928: error = EINVAL;
929: } else {
930: ifp->if_mtu = ifr->ifr_mtu;
931: }
932: break;
933: }
934:
935: (void) thread_set_funneled(funnel_state);
936:
937: return (error);
938: }
939:
940:
941:
942:
943: /*
944: * Y-adapter filter check
945: * The rules here:
946: * For Rhap: return 1
947: * For Both: return 0
948: * Not for Rhap: return -1
949: * Multicast/Broadcast => For Both
950: * Atalk address registered
951: * filter matches => For Rhap else Not For Rhap
952: * IP address registered
953: * filter matches => For Rhap else Not For Rhap
954: * For Rhap
955: * Note this is *not* a general filter mechanism in that we know
956: * what we *could* be looking for.
957: * WARNING: this is a big-endian routine.
958: * Note: ARP and AARP packets are implicitly accepted for "both"
959: */
960: int
961: Filter_check(struct mbuf **m0)
962: { register struct BlueFilter *bf;
963: register unsigned char *p;
964: register unsigned short *s;
965: register unsigned long *l;
966: int total, flags;
967: struct mbuf *m;
968: extern struct mbuf *m_pullup(struct mbuf *, int);
969: extern void kprintf( const char *, ...);
970: #define FILTER_LEN 32
971:
972: m = *m0;
973: flags = m->m_flags;
974: if (FILTER_LEN > m->m_pkthdr.len)
975: return(1);
976: while ((FILTER_LEN > m->m_len) && m->m_next) {
977: total = m->m_len + (m->m_next)->m_len;
978: if ((m = m_pullup(m, min(FILTER_LEN, total))) == 0)
979: return(-1);
980: }
981: *m0 = m;
982:
983: p = mtod(m, unsigned char *); /* Point to destination media addr */
984: if (p[0] & 0x01) /* Multicast/broadcast */
985: return(0);
986: s = (unsigned short *)p;
987: bf = &RhapFilter[BFS_ATALK];
988: #if 0
989: kprintf("!PKT: %x, %x, %x\n", s[6], s[7], s[8]);
990: #endif
991:
992: if (bf->BF_flags) /* Filtering Appletalk */
993: {
994: l = (unsigned long *)&s[8];
995: #if 0
996: kprintf("!AT: %x, %x, %x, %x, %x, %x\n", s[6], s[7],
997: *l, s[10], s[13], p[30]);
998: #endif
999: if (s[6] <= ETHERMTU)
1000: { if (s[7] == 0xaaaa) /* Could be Atalk */
1001: { /* Verify SNAP header */
1002: if (*l == 0x03080007 && s[10] == 0x809b)
1003: { if (s[13] == bf->BF_address &&
1004: p[30] == bf->BF_node)
1005: return(1);
1006: } else if (*l == 0x03000000 && s[10] == 0x80f3)
1007: /* AARP pkts aren't net-addressed */
1008: return(0);
1009: return(0);
1010: } else /* Not for us? */
1011: return(0);
1012: } /* Fall through */
1013: } /* Fall through */
1014: bf++; /* Look for IP next */
1015: if (bf->BF_flags) /* Filtering IP */
1016: {
1017: l = (unsigned long *)&s[15];
1018: #if 0
1019: kprintf("!IP: %x, %x\n", s[6], *l);
1020: #endif
1021: if (s[6] > ETHERMTU)
1022: { if (s[6] == 0x800) /* Is IP */
1023: { /* Verify IP address */
1024: if (*l == bf->BF_address)
1025: return(1);
1026: else /* Not for us */
1027: return(0);
1028: } else if (s[6] == 0x806)
1029: /* ARP pkts aren't net-addressed */
1030: return(0);
1031: }
1032: }
1033: return(0); /* No filters => Accept */
1034: }
1035:
1036:
1037:
1038: int ether_family_init()
1039: {
1040:
1041: int i;
1042:
1043: if (ivedonethis)
1044: return 0;
1045:
1046: ivedonethis = 1;
1047:
1048:
1049: if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET, ether_add_if, ether_del_if,
1050: ether_add_proto, ether_del_proto,
1051: ether_shutdown)) {
1052: printf("WARNING: ether_family_init -- Can't register if family modules\n");
1053: return EIO;
1054: }
1055:
1056: for (i=0; i < (LITMUS_SIZE/4); i++)
1057: litmus_mask[i] = 0xffffffff;
1058:
1059: for (i=0; i < MAX_EN_COUNT; i++)
1060: en_array[i] = (struct if_proto *) 0;
1061:
1062: for (i=0; i < MAX_INTERFACES; i++)
1063: ether_desc_blk[i].n_blocks = 0;
1064:
1065: return 0;
1066: }
1067:
1068:
1069:
1070: u_long ether_attach_inet(struct ifnet *ifp)
1071: {
1072: struct dlil_proto_reg_str reg;
1073: struct dlil_demux_desc desc;
1074: struct dlil_demux_desc desc2;
1075: u_long ip_dl_tag=0;
1076: u_short en_native=ETHERTYPE_IP;
1077: u_short arp_native=ETHERTYPE_ARP;
1078: int stat;
1079: int i;
1080:
1081:
1082: for (i=0; i < MAX_EN_COUNT; i++)
1083: if ((en_array[i]) && (en_array[i]->ifp == ifp) &&
1084: (en_array[i]->protocol_family == PF_INET)) {
1085: return en_array[i]->dl_tag;
1086: }
1087:
1088: TAILQ_INIT(®.demux_desc_head);
1089: desc.type = DLIL_DESC_RAW;
1090: desc.variants.bitmask.proto_id_length = 0;
1091: desc.variants.bitmask.proto_id = 0;
1092: desc.variants.bitmask.proto_id_mask = 0;
1093: desc.native_type = (char *) &en_native;
1094: TAILQ_INSERT_TAIL(®.demux_desc_head, &desc, next);
1095: reg.interface_family = ifp->if_family;
1096: reg.unit_number = ifp->if_unit;
1097: reg.input = new_ether_input;
1098: reg.pre_output = ether_pre_output;
1099: reg.event = 0;
1100: reg.offer = 0;
1101: reg.ioctl = ether_ioctl;
1102: reg.default_proto = 1;
1103: reg.protocol_family = PF_INET;
1104:
1105: desc2 = desc;
1106: desc2.native_type = (char *) &arp_native;
1107: TAILQ_INSERT_TAIL(®.demux_desc_head, &desc2, next);
1108:
1109: stat = dlil_attach_protocol(®, &ip_dl_tag);
1110: if (stat) {
1111: printf("WARNING: ether_attach_inet can't attach ip to interface\n");
1112: return stat;
1113: }
1114:
1115: return ip_dl_tag;
1116: }
1117:
1118: void ether_attach_at(struct ifnet *ifp, u_long *at_dl_tag, u_long *aarp_dl_tag)
1119: {
1120: struct dlil_proto_reg_str reg;
1121: struct dlil_demux_desc desc;
1122: struct dlil_demux_desc desc2;
1123: u_short native = 0; /* 802.2 frames use a length here */
1124: int stat;
1125:
1126: TAILQ_INIT(®.demux_desc_head);
1127: desc.type = DLIL_DESC_802_2_SNAP;
1128: desc.variants.desc_802_2_SNAP.dsap = LLC_SNAP_LSAP;
1129: desc.variants.desc_802_2_SNAP.ssap = LLC_SNAP_LSAP;
1130: desc.variants.desc_802_2_SNAP.control_code = 0x03;
1131: desc.variants.desc_802_2_SNAP.org[0] = 0x08;
1132: desc.variants.desc_802_2_SNAP.org[1] = 0x00;
1133: desc.variants.desc_802_2_SNAP.org[2] = 0x07;
1134: desc.variants.desc_802_2_SNAP.protocol_type = 0x809B;
1135: desc.native_type = (char *) &native;
1136: TAILQ_INSERT_TAIL(®.demux_desc_head, &desc, next);
1137: reg.interface_family = ifp->if_family;
1138: reg.unit_number = ifp->if_unit;
1139: reg.input = new_ether_input;
1140: reg.pre_output = ether_pre_output;
1141: reg.event = 0;
1142: reg.offer = 0;
1143: reg.ioctl = ether_ioctl;
1144: reg.default_proto = 0;
1145: reg.protocol_family = PF_APPLETALK;
1146:
1147: desc2 = desc;
1148: desc2.variants.desc_802_2_SNAP.protocol_type = 0x80F3;
1149: desc2.variants.desc_802_2_SNAP.org[0] = 0;
1150: desc2.variants.desc_802_2_SNAP.org[1] = 0;
1151: desc2.variants.desc_802_2_SNAP.org[2] = 0;
1152:
1153: TAILQ_INSERT_TAIL(®.demux_desc_head, &desc2, next);
1154:
1155: stat = dlil_attach_protocol(®, at_dl_tag);
1156: if (stat) {
1157: printf("WARNING: ether_attach_at can't attach at to interface\n");
1158: return;
1159: }
1160:
1161: *aarp_dl_tag = *at_dl_tag;
1162:
1163: } /* ether_attach_at */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.