1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright (c) 1982, 1989, 1993
27 * The Regents of the University of California. All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 *
57 */
58
59
60
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/malloc.h>
65 #include <sys/mbuf.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
68 #include <sys/sysctl.h>
69
70 #include <net/if.h>
71 #include <net/netisr.h>
72 #include <net/route.h>
73 #include <net/if_llc.h>
74 #include <net/if_dl.h>
75 #include <net/if_types.h>
76 #include <netinet/if_ether.h>
77 #include <netinet/in.h> /* For M_LOOP */
78
79 /*
80 #if INET
81 #include <netinet/in.h>
82 #include <netinet/in_var.h>
83
84 #include <netinet/in_systm.h>
85 #include <netinet/ip.h>
86 #endif
87 */
88
89 #include <sys/socketvar.h>
90
91 #include <net/dlil.h>
92
93
94 #if LLC && CCITT
95 extern struct ifqueue pkintrq;
96 #endif
97
98 /* General stuff from if_ethersubr.c - may not need some of it */
99
100 #include <netat/at_pat.h>
101 #if NETAT
102 extern struct ifqueue atalkintrq;
103 #endif
104
105
106 #if BRIDGE
107 #include <net/bridge.h>
108 #endif
109
110 /* #include "vlan.h" */
111 #if NVLAN > 0
112 #include <net/if_vlan_var.h>
113 #endif /* NVLAN > 0 */
114
115 static u_long lo_dlt = 0;
116
117 #define IFP2AC(IFP) ((struct arpcom *)IFP)
118
119 struct en_desc {
120 u_int16_t type; /* Type of protocol stored in data */
121 struct if_proto *proto; /* Protocol structure */
122 u_long data[2]; /* Protocol data */
123 };
124
125 #define ETHER_DESC_BLK_SIZE (10)
126 #define MAX_INTERFACES 50
127
128 /*
129 * Statics for demux module
130 */
131
132 struct ether_desc_blk_str {
133 u_long n_max_used;
134 u_long n_count;
135 struct en_desc *block_ptr;
136 };
137
138
139 static struct ether_desc_blk_str ether_desc_blk[MAX_INTERFACES];
140
141
142 /* from if_ethersubr.c */
143 int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
144 struct sockaddr *));
145
146 /*
147 * Release all descriptor entries owned by this dl_tag (there may be several).
148 * Setting the type to 0 releases the entry. Eventually we should compact-out
149 * the unused entries.
150 */
151 static
152 int ether_del_proto(struct if_proto *proto, u_long dl_tag)
153 {
154 struct en_desc* ed = ether_desc_blk[proto->ifp->family_cookie].block_ptr;
155 u_long current = 0;
156 int found = 0;
157
158 for (current = ether_desc_blk[proto->ifp->family_cookie].n_max_used;
159 current > 0; current--) {
160 if (ed[current - 1].proto == proto) {
161 found = 1;
162 ed[current - 1].type = 0;
163
164 if (current == ether_desc_blk[proto->ifp->family_cookie].n_max_used) {
165 ether_desc_blk[proto->ifp->family_cookie].n_max_used--;
166 }
167 }
168 }
169
170 return found;
171 }
172
173
174
175 static int
176 ether_add_proto(struct ddesc_head_str *desc_head, struct if_proto *proto, u_long dl_tag)
177 {
178 char *current_ptr;
179 struct dlil_demux_desc *desc;
180 struct en_desc *ed;
181 struct en_desc *last;
182 u_long *bitmask;
183 u_long *proto_id;
184 u_long i;
185 short total_length;
186 u_long block_count;
187 u_long *tmp;
188
189
190 TAILQ_FOREACH(desc, desc_head, next) {
191 switch (desc->type) {
192 /* These types are supported */
193 /* Top three are preferred */
194 case DLIL_DESC_ETYPE2:
195 if (desc->variants.native_type_length != 2)
196 return EINVAL;
197 break;
198
199 case DLIL_DESC_SAP:
200 if (desc->variants.native_type_length != 3)
201 return EINVAL;
202 break;
203
204 case DLIL_DESC_SNAP:
205 if (desc->variants.native_type_length != 5)
206 return EINVAL;
207 break;
208
209 case DLIL_DESC_802_2:
210 case DLIL_DESC_802_2_SNAP:
211 break;
212
213 case DLIL_DESC_RAW:
214 if (desc->variants.bitmask.proto_id_length == 0)
215 break;
216 /* else fall through, bitmask variant not supported */
217
218 default:
219 ether_del_proto(proto, dl_tag);
220 return EINVAL;
221 }
222
223 restart:
224 ed = ether_desc_blk[proto->ifp->family_cookie].block_ptr;
225
226 /* Find a free entry */
227 for (i = 0; i < ether_desc_blk[proto->ifp->family_cookie].n_count; i++) {
228 if (ed[i].type == 0) {
229 break;
230 }
231 }
232
233 if (i >= ether_desc_blk[proto->ifp->family_cookie].n_count) {
234 u_long new_count = ETHER_DESC_BLK_SIZE +
235 ether_desc_blk[proto->ifp->family_cookie].n_count;
236 tmp = _MALLOC((new_count * (sizeof(*ed))), M_IFADDR, M_WAITOK);
237 if (tmp == 0) {
238 /*
239 * Remove any previous descriptors set in the call.
240 */
241 ether_del_proto(proto, dl_tag);
242 return ENOMEM;
243 }
244
245 bzero(tmp, new_count * sizeof(*ed));
246 bcopy(ether_desc_blk[proto->ifp->family_cookie].block_ptr,
247 tmp, ether_desc_blk[proto->ifp->family_cookie].n_count * sizeof(*ed));
248 FREE(ether_desc_blk[proto->ifp->family_cookie].block_ptr, M_IFADDR);
249 ether_desc_blk[proto->ifp->family_cookie].n_count = new_count;
250 ether_desc_blk[proto->ifp->family_cookie].block_ptr = (struct en_desc*)tmp;
251 }
252
253 /* Bump n_max_used if appropriate */
254 if (i + 1 > ether_desc_blk[proto->ifp->family_cookie].n_max_used) {
255 ether_desc_blk[proto->ifp->family_cookie].n_max_used = i + 1;
256 }
257
258 ed[i].proto = proto;
259 ed[i].data[0] = 0;
260 ed[i].data[1] = 0;
261
262 switch (desc->type) {
263 case DLIL_DESC_RAW:
264 /* 2 byte ethernet raw protocol type is at native_type */
265 /* protocol is not in network byte order */
266 ed[i].type = DLIL_DESC_ETYPE2;
267 ed[i].data[0] = htons(*(u_int16_t*)desc->native_type);
268 break;
269
270 case DLIL_DESC_ETYPE2:
271 /* 2 byte ethernet raw protocol type is at native_type */
272 /* prtocol must be in network byte order */
273 ed[i].type = DLIL_DESC_ETYPE2;
274 ed[i].data[0] = *(u_int16_t*)desc->native_type;
275 break;
276
277 case DLIL_DESC_802_2:
278 ed[i].type = DLIL_DESC_SAP;
279 ed[i].data[0] = *(u_int32_t*)&desc->variants.desc_802_2;
280 ed[i].data[0] &= htonl(0xFFFFFF00);
281 break;
282
283 case DLIL_DESC_SAP:
284 ed[i].type = DLIL_DESC_SAP;
285 bcopy(desc->native_type, &ed[i].data[0], 3);
286 break;
287
288 case DLIL_DESC_802_2_SNAP:
289 ed[i].type = DLIL_DESC_SNAP;
290 desc->variants.desc_802_2_SNAP.protocol_type =
291 htons(desc->variants.desc_802_2_SNAP.protocol_type);
292 bcopy(&desc->variants.desc_802_2_SNAP, &ed[i].data[0], 8);
293 ed[i].data[0] &= htonl(0x000000FF);
294 desc->variants.desc_802_2_SNAP.protocol_type =
295 ntohs(desc->variants.desc_802_2_SNAP.protocol_type);
296 break;
297
298 case DLIL_DESC_SNAP: {
299 u_int8_t* pDest = ((u_int8_t*)&ed[i].data[0]) + 3;
300 ed[i].type = DLIL_DESC_SNAP;
301 bcopy(desc->native_type, pDest, 5);
302 }
303 break;
304 }
305 }
306
307 return 0;
308 }
309
310
311 static
312 int ether_shutdown()
313 {
314 return 0;
315 }
316
317
318 int ether_demux(ifp, m, frame_header, proto)
319 struct ifnet *ifp;
320 struct mbuf *m;
321 char *frame_header;
322 struct if_proto **proto;
323
324 {
325 register struct ether_header *eh = (struct ether_header *)frame_header;
326 u_short ether_type = eh->ether_type;
327 u_int16_t type;
328 u_int8_t *data;
329 u_long i = 0;
330 u_long max = ether_desc_blk[ifp->family_cookie].n_max_used;
331 struct en_desc *ed = ether_desc_blk[ifp->family_cookie].block_ptr;
332 u_int32_t extProto1 = 0;
333 u_int32_t extProto2 = 0;
334
335 if (eh->ether_dhost[0] & 1) {
336 /* Check for broadcast */
337 if (*(u_int32_t*)eh->ether_dhost == 0xFFFFFFFF &&
338 *(u_int16_t*)(eh->ether_dhost + sizeof(u_int32_t)) == 0xFFFF)
339 m->m_flags |= M_BCAST;
340 else
341 m->m_flags |= M_MCAST;
342 } else {
343 /*
344 * When the driver is put into promiscuous mode we may receive unicast
345 * frames that are not intended for our interfaces. They are filtered
346 * here to keep them from traveling further up the stack to code that
347 * is not expecting them or prepared to deal with them. In the near
348 * future, the filtering done here will be moved even further down the
349 * stack into the IONetworkingFamily, preventing even interface
350 * filter NKE's from receiving promiscuous packets. Please use BPF.
351 */
352 #define ETHER_CMP(x, y) ( ((u_int16_t *) x)[0] != ((u_int16_t *) y)[0] || \
353 ((u_int16_t *) x)[1] != ((u_int16_t *) y)[1] || \
354 ((u_int16_t *) x)[2] != ((u_int16_t *) y)[2] )
355
356 if (ETHER_CMP(eh->ether_dhost, ((struct arpcom *) ifp)->ac_enaddr)) {
357 m_freem(m);
358 return EJUSTRETURN;
359 }
360 }
361
362 data = mtod(m, u_int8_t*);
363
364 /*
365 * Determine the packet's protocol type and stuff the protocol into
366 * longs for quick compares.
367 */
368
369 if (ntohs(ether_type) <= 1500) {
370 extProto1 = *(u_int32_t*)data;
371
372 // SAP or SNAP
373 if ((extProto1 & htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) {
374 // SNAP
375 type = DLIL_DESC_SNAP;
376 extProto2 = *(u_int32_t*)(data + sizeof(u_int32_t));
377 extProto1 &= htonl(0x000000FF);
378 } else {
379 type = DLIL_DESC_SAP;
380 extProto1 &= htonl(0xFFFFFF00);
381 }
382 } else {
383 type = DLIL_DESC_ETYPE2;
384 }
385
386 /*
387 * Search through the connected protocols for a match.
388 */
389
390 switch (type) {
391 case DLIL_DESC_ETYPE2:
392 for (i = 0; i < max; i++) {
393 if ((ed[i].type == type) && (ed[i].data[0] == ether_type)) {
394 *proto = ed[i].proto;
395 return 0;
396 }
397 }
398 break;
399
400 case DLIL_DESC_SAP:
401 for (i = 0; i < max; i++) {
402 if ((ed[i].type == type) && (ed[i].data[0] == extProto1)) {
403 *proto = ed[i].proto;
404 return 0;
405 }
406 }
407 break;
408
409 case DLIL_DESC_SNAP:
410 for (i = 0; i < max; i++) {
411 if ((ed[i].type == type) && (ed[i].data[0] == extProto1) &&
412 (ed[i].data[1] == extProto2)) {
413 *proto = ed[i].proto;
414 return 0;
415 }
416 }
417 break;
418 }
419
420 return ENOENT;
421 }
422
423
424
425 /*
426 * Ethernet output routine.
427 * Encapsulate a packet of type family for the local net.
428 * Use trailer local net encapsulation if enough data in first
429 * packet leaves a multiple of 512 bytes of data in remainder.
430 * Assumes that ifp is actually pointer to arpcom structure.
431 */
432 int
433 ether_frameout(ifp, m, ndest, edst, ether_type)
434 register struct ifnet *ifp;
435 struct mbuf **m;
436 struct sockaddr *ndest;
437 char *edst;
438 char *ether_type;
439 {
440 register struct ether_header *eh;
441 int hlen; /* link layer header lenght */
442 struct arpcom *ac = IFP2AC(ifp);
443
444
445 hlen = ETHER_HDR_LEN;
446
447 /*
448 * If a simplex interface, and the packet is being sent to our
449 * Ethernet address or a broadcast address, loopback a copy.
450 * XXX To make a simplex device behave exactly like a duplex
451 * device, we should copy in the case of sending to our own
452 * ethernet address (thus letting the original actually appear
453 * on the wire). However, we don't do that here for security
454 * reasons and compatibility with the original behavior.
455 */
456 if ((ifp->if_flags & IFF_SIMPLEX) &&
457 ((*m)->m_flags & M_LOOP)) {
458 if (lo_dlt == 0)
459 dlil_find_dltag(APPLE_IF_FAM_LOOPBACK, 0, PF_INET, &lo_dlt);
460
461 if (lo_dlt) {
462 if ((*m)->m_flags & M_BCAST) {
463 struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL);
464 if (n != NULL)
465 dlil_output(lo_dlt, n, 0, ndest, 0);
466 }
467 else
468 {
469 if (bcmp(edst, ac->ac_enaddr, ETHER_ADDR_LEN) == 0) {
470 dlil_output(lo_dlt, *m, 0, ndest, 0);
471 return EJUSTRETURN;
472 }
473 }
474 }
475 }
476
477
478 /*
479 * Add local net header. If no space in first mbuf,
480 * allocate another.
481 */
482 M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT);
483 if (*m == 0) {
484 return (EJUSTRETURN);
485 }
486
487
488 eh = mtod(*m, struct ether_header *);
489 (void)memcpy(&eh->ether_type, ether_type,
490 sizeof(eh->ether_type));
491 (void)memcpy(eh->ether_dhost, edst, 6);
492 (void)memcpy(eh->ether_shost, ac->ac_enaddr,
493 sizeof(eh->ether_shost));
494
495 return 0;
496 }
497
498
499 static
500 int ether_add_if(struct ifnet *ifp)
501 {
502 u_long i;
503
504 ifp->if_framer = ether_frameout;
505 ifp->if_demux = ether_demux;
506 ifp->if_event = 0;
507 ifp->if_resolvemulti = ether_resolvemulti;
508
509 for (i=0; i < MAX_INTERFACES; i++)
510 if (ether_desc_blk[i].n_count == 0)
511 break;
512
513 if (i == MAX_INTERFACES)
514 return ENOMEM;
515
516 ether_desc_blk[i].block_ptr = _MALLOC(ETHER_DESC_BLK_SIZE * sizeof(struct en_desc),
517 M_IFADDR, M_WAITOK);
518 if (ether_desc_blk[i].block_ptr == 0)
519 return ENOMEM;
520
521 ether_desc_blk[i].n_count = ETHER_DESC_BLK_SIZE;
522 bzero(ether_desc_blk[i].block_ptr, ETHER_DESC_BLK_SIZE * sizeof(struct en_desc));
523
524 ifp->family_cookie = i;
525
526 return 0;
527 }
528
529 static
530 int ether_del_if(struct ifnet *ifp)
531 {
532 if ((ifp->family_cookie < MAX_INTERFACES) &&
533 (ether_desc_blk[ifp->family_cookie].n_count))
534 {
535 FREE(ether_desc_blk[ifp->family_cookie].block_ptr, M_IFADDR);
536 ether_desc_blk[ifp->family_cookie].block_ptr = NULL;
537 ether_desc_blk[ifp->family_cookie].n_count = 0;
538 ether_desc_blk[ifp->family_cookie].n_max_used = 0;
539 return 0;
540 }
541 else
542 return ENOENT;
543 }
544
545 static
546 int ether_init_if(struct ifnet *ifp)
547 {
548 register struct ifaddr *ifa;
549 register struct sockaddr_dl *sdl;
550
551 ifa = ifnet_addrs[ifp->if_index - 1];
552 if (ifa == 0) {
553 printf("ether_ifattach: no lladdr!\n");
554 return;
555 }
556 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
557 sdl->sdl_type = IFT_ETHER;
558 sdl->sdl_alen = ifp->if_addrlen;
559 bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
560
561 return 0;
562 }
563
564
565 int
566 ether_ifmod_ioctl(ifp, command, data)
567 struct ifnet *ifp;
568 u_long command;
569 caddr_t data;
570 {
571 struct rslvmulti_req *rsreq = (struct rslvmulti_req *) data;
572 int error = 0;
573 struct sockaddr_dl *sdl;
574 struct sockaddr_in *sin;
575 u_char *e_addr;
576
577
578 switch (command) {
579 case SIOCRSLVMULTI:
580 switch(rsreq->sa->sa_family) {
581 case AF_UNSPEC:
582 /* AppleTalk uses AF_UNSPEC for multicast registration.
583 * No mapping needed. Just check that it's a valid MC address.
584 */
585 e_addr = &rsreq->sa->sa_data[0];
586 if ((e_addr[0] & 1) != 1)
587 return EADDRNOTAVAIL;
588 *rsreq->llsa = 0;
589 return EJUSTRETURN;
590
591
592 case AF_LINK:
593 /*
594 * No mapping needed. Just check that it's a valid MC address.
595 */
596 sdl = (struct sockaddr_dl *)rsreq->sa;
597 e_addr = LLADDR(sdl);
598 if ((e_addr[0] & 1) != 1)
599 return EADDRNOTAVAIL;
600 *rsreq->llsa = 0;
601 return EJUSTRETURN;
602
603 default:
604 return EAFNOSUPPORT;
605 }
606
607 default:
608 return EOPNOTSUPP;
609 }
610 }
611
612
613 extern int ether_attach_inet(struct ifnet *ifp, u_long *dl_tag);
614 extern int ether_detach_inet(struct ifnet *ifp, u_long dl_tag);
615 extern int ether_attach_inet6(struct ifnet *ifp, u_long *dl_tag);
616 extern int ether_detach_inet6(struct ifnet *ifp, u_long dl_tag);
617 int ether_family_init()
618 {
619 int i, error=0;
620 struct dlil_ifmod_reg_str ifmod_reg;
621 struct dlil_protomod_reg_str enet_protoreg;
622
623 /* ethernet family is built-in, called from bsd_init */
624 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
625
626 bzero(&ifmod_reg, sizeof(ifmod_reg));
627 ifmod_reg.add_if = ether_add_if;
628 ifmod_reg.del_if = ether_del_if;
629 ifmod_reg.init_if = ether_init_if;
630 ifmod_reg.add_proto = ether_add_proto;
631 ifmod_reg.del_proto = ether_del_proto;
632 ifmod_reg.ifmod_ioctl = ether_ifmod_ioctl;
633 ifmod_reg.shutdown = ether_shutdown;
634
635 if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET, &ifmod_reg)) {
636 printf("WARNING: ether_family_init -- Can't register if family modules\n");
637 return EIO;
638 }
639
640 for (i=0; i < MAX_INTERFACES; i++)
641 ether_desc_blk[i].n_count = 0;
642
643 /* Register protocol registration functions */
644
645 bzero(&enet_protoreg, sizeof(enet_protoreg));
646 enet_protoreg.attach_proto = ether_attach_inet;
647 enet_protoreg.detach_proto = ether_detach_inet;
648
649 if ( error = dlil_reg_proto_module(PF_INET, APPLE_IF_FAM_ETHERNET, &enet_protoreg) != 0)
650 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
651
652
653 enet_protoreg.attach_proto = ether_attach_inet6;
654 enet_protoreg.detach_proto = ether_detach_inet6;
655
656 if ( error = dlil_reg_proto_module(PF_INET6, APPLE_IF_FAM_ETHERNET, &enet_protoreg) != 0)
657 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
658
659 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
660
661 return (error);
662 }
Cache object: 95e9c510c588f78ca7026fcfe0809a4d
|