]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/ether_if_module.c
xnu-792.10.96.tar.gz
[apple/xnu.git] / bsd / net / ether_if_module.c
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/route.h>
69 #include <net/if_llc.h>
70 #include <net/if_dl.h>
71 #include <net/if_types.h>
72 #include <net/if_ether.h>
73 #include <netinet/if_ether.h>
74 #include <netinet/in.h> /* For M_LOOP */
75
76 /*
77 #if INET
78 #include <netinet/in.h>
79 #include <netinet/in_var.h>
80
81 #include <netinet/in_systm.h>
82 #include <netinet/ip.h>
83 #endif
84 */
85
86 #include <sys/socketvar.h>
87 #include <net/if_vlan_var.h>
88 #include <net/if_bond_var.h>
89
90 #include <net/dlil.h>
91
92 #if LLC && CCITT
93 extern struct ifqueue pkintrq;
94 #endif
95
96 /* General stuff from if_ethersubr.c - may not need some of it */
97
98 #include <netat/at_pat.h>
99 #if NETAT
100 extern struct ifqueue atalkintrq;
101 #endif
102
103
104 #if BRIDGE
105 #include <net/bridge.h>
106 #endif
107
108 #define memcpy(x,y,z) bcopy(y, x, z)
109
110
111 SYSCTL_DECL(_net_link);
112 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
113
114 struct en_desc {
115 u_int16_t type; /* Type of protocol stored in data */
116 u_long protocol_family; /* Protocol family */
117 u_long data[2]; /* Protocol data */
118 };
119 /* descriptors are allocated in blocks of ETHER_DESC_BLK_SIZE */
120 #define ETHER_DESC_BLK_SIZE (10)
121
122 /*
123 * Header for the demux list, hangs off of IFP at family_cookie
124 */
125
126 struct ether_desc_blk_str {
127 u_long n_max_used;
128 u_long n_count;
129 u_long n_used;
130 struct en_desc block_ptr[1];
131 };
132 /* Size of the above struct before the array of struct en_desc */
133 #define ETHER_DESC_HEADER_SIZE ((size_t)&(((struct ether_desc_blk_str*)0)->block_ptr[0]))
134 __private_extern__ u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
135 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
136
137 int ether_add_proto_old(struct ifnet *ifp, u_long protocol_family, struct ddesc_head_str *desc_head);
138 int ether_add_if(struct ifnet *ifp);
139 int ether_del_if(struct ifnet *ifp);
140 int ether_init_if(struct ifnet *ifp);
141 int ether_family_init(void);
142
143 /*
144 * Release all descriptor entries owned by this protocol (there may be several).
145 * Setting the type to 0 releases the entry. Eventually we should compact-out
146 * the unused entries.
147 */
148 int
149 ether_del_proto(
150 ifnet_t ifp,
151 protocol_family_t protocol_family)
152 {
153 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->family_cookie;
154 u_long current = 0;
155 int found = 0;
156
157 if (desc_blk == NULL)
158 return 0;
159
160 for (current = desc_blk->n_max_used; current > 0; current--) {
161 if (desc_blk->block_ptr[current - 1].protocol_family == protocol_family) {
162 found = 1;
163 desc_blk->block_ptr[current - 1].type = 0;
164 desc_blk->n_used--;
165 }
166 }
167
168 if (desc_blk->n_used == 0) {
169 FREE(ifp->family_cookie, M_IFADDR);
170 ifp->family_cookie = 0;
171 }
172 else {
173 /* Decrement n_max_used */
174 for (; desc_blk->n_max_used > 0 && desc_blk->block_ptr[desc_blk->n_max_used - 1].type == 0; desc_blk->n_max_used--)
175 ;
176 }
177
178 return 0;
179 }
180
181
182 static int
183 ether_add_proto_internal(
184 struct ifnet *ifp,
185 protocol_family_t protocol,
186 const struct ifnet_demux_desc *demux)
187 {
188 struct en_desc *ed;
189 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->family_cookie;
190 u_int32_t i;
191
192 switch (demux->type) {
193 /* These types are supported */
194 /* Top three are preferred */
195 case DLIL_DESC_ETYPE2:
196 if (demux->datalen != 2) {
197 return EINVAL;
198 }
199 break;
200
201 case DLIL_DESC_SAP:
202 if (demux->datalen != 3) {
203 return EINVAL;
204 }
205 break;
206
207 case DLIL_DESC_SNAP:
208 if (demux->datalen != 5) {
209 return EINVAL;
210 }
211 break;
212
213 default:
214 return ENOTSUP;
215 }
216
217 // Verify a matching descriptor does not exist.
218 if (desc_blk != NULL) {
219 switch (demux->type) {
220 case DLIL_DESC_ETYPE2:
221 for (i = 0; i < desc_blk->n_max_used; i++) {
222 if (desc_blk->block_ptr[i].type == DLIL_DESC_ETYPE2 &&
223 desc_blk->block_ptr[i].data[0] ==
224 *(u_int16_t*)demux->data) {
225 return EADDRINUSE;
226 }
227 }
228 break;
229 case DLIL_DESC_SAP:
230 case DLIL_DESC_SNAP:
231 for (i = 0; i < desc_blk->n_max_used; i++) {
232 if (desc_blk->block_ptr[i].type == demux->type &&
233 bcmp(desc_blk->block_ptr[i].data, demux->data,
234 demux->datalen) == 0) {
235 return EADDRINUSE;
236 }
237 }
238 break;
239 }
240 }
241
242 // Check for case where all of the descriptor blocks are in use
243 if (desc_blk == NULL || desc_blk->n_used == desc_blk->n_count) {
244 struct ether_desc_blk_str *tmp;
245 u_long new_count = ETHER_DESC_BLK_SIZE;
246 u_long new_size;
247 u_long old_size = 0;
248
249 i = 0;
250
251 if (desc_blk) {
252 new_count += desc_blk->n_count;
253 old_size = desc_blk->n_count * sizeof(struct en_desc) + ETHER_DESC_HEADER_SIZE;
254 i = desc_blk->n_used;
255 }
256
257 new_size = new_count * sizeof(struct en_desc) + ETHER_DESC_HEADER_SIZE;
258
259 tmp = _MALLOC(new_size, M_IFADDR, M_WAITOK);
260 if (tmp == 0) {
261 /*
262 * Remove any previous descriptors set in the call.
263 */
264 return ENOMEM;
265 }
266
267 bzero(tmp + old_size, new_size - old_size);
268 if (desc_blk) {
269 bcopy(desc_blk, tmp, old_size);
270 FREE(desc_blk, M_IFADDR);
271 }
272 desc_blk = tmp;
273 ifp->family_cookie = (u_long)desc_blk;
274 desc_blk->n_count = new_count;
275 }
276 else {
277 /* Find a free entry */
278 for (i = 0; i < desc_blk->n_count; i++) {
279 if (desc_blk->block_ptr[i].type == 0) {
280 break;
281 }
282 }
283 }
284
285 /* Bump n_max_used if appropriate */
286 if (i + 1 > desc_blk->n_max_used) {
287 desc_blk->n_max_used = i + 1;
288 }
289
290 ed = &desc_blk->block_ptr[i];
291 ed->protocol_family = protocol;
292 ed->data[0] = 0;
293 ed->data[1] = 0;
294
295 switch (demux->type) {
296 case DLIL_DESC_ETYPE2:
297 /* 2 byte ethernet raw protocol type is at native_type */
298 /* prtocol must be in network byte order */
299 ed->type = DLIL_DESC_ETYPE2;
300 ed->data[0] = *(u_int16_t*)demux->data;
301 break;
302
303 case DLIL_DESC_SAP:
304 ed->type = DLIL_DESC_SAP;
305 bcopy(demux->data, &ed->data[0], 3);
306 break;
307
308 case DLIL_DESC_SNAP: {
309 u_int8_t* pDest = ((u_int8_t*)&ed->data[0]) + 3;
310 ed->type = DLIL_DESC_SNAP;
311 bcopy(demux->data, pDest, 5);
312 }
313 break;
314 }
315
316 desc_blk->n_used++;
317
318 return 0;
319 }
320
321 int
322 ether_add_proto(
323 ifnet_t ifp,
324 protocol_family_t protocol,
325 const struct ifnet_demux_desc *demux_list,
326 u_int32_t demux_count)
327 {
328 int error = 0;
329 u_int32_t i;
330
331 for (i = 0; i < demux_count; i++) {
332 error = ether_add_proto_internal(ifp, protocol, &demux_list[i]);
333 if (error) {
334 ether_del_proto(ifp, protocol);
335 break;
336 }
337 }
338
339 return error;
340 }
341
342 __private_extern__ int
343 ether_add_proto_old(
344 struct ifnet *ifp,
345 u_long protocol_family,
346 struct ddesc_head_str *desc_head)
347 {
348 struct dlil_demux_desc *desc;
349 int error = 0;
350
351 TAILQ_FOREACH(desc, desc_head, next) {
352 struct ifnet_demux_desc dmx;
353 int swapped = 0;
354
355 // Convert dlil_demux_desc to ifnet_demux_desc
356 dmx.type = desc->type;
357 dmx.datalen = desc->variants.native_type_length;
358 dmx.data = desc->native_type;
359
360 #ifdef DLIL_DESC_RAW
361 if (dmx.type == DLIL_DESC_RAW) {
362 swapped = 1;
363 dmx.type = DLIL_DESC_ETYPE2;
364 dmx.datalen = 2;
365 *(u_int16_t*)dmx.data = htons(*(u_int16_t*)dmx.data);
366 }
367 #endif
368
369 error = ether_add_proto_internal(ifp, protocol_family, &dmx);
370 if (swapped) {
371 *(u_int16_t*)dmx.data = ntohs(*(u_int16_t*)dmx.data);
372 swapped = 0;
373 }
374 if (error) {
375 ether_del_proto(ifp, protocol_family);
376 break;
377 }
378 }
379
380 return error;
381 }
382
383
384 static int
385 ether_shutdown(void)
386 {
387 return 0;
388 }
389
390
391 int
392 ether_demux(
393 ifnet_t ifp,
394 mbuf_t m,
395 char *frame_header,
396 protocol_family_t *protocol_family)
397 {
398 struct ether_header *eh = (struct ether_header *)frame_header;
399 u_short ether_type = eh->ether_type;
400 u_int16_t type;
401 u_int8_t *data;
402 u_long i = 0;
403 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->family_cookie;
404 u_long maxd = desc_blk ? desc_blk->n_max_used : 0;
405 struct en_desc *ed = desc_blk ? desc_blk->block_ptr : NULL;
406 u_int32_t extProto1 = 0;
407 u_int32_t extProto2 = 0;
408
409 if (eh->ether_dhost[0] & 1) {
410 /* Check for broadcast */
411 if (*(u_int32_t*)eh->ether_dhost == 0xFFFFFFFF &&
412 *(u_int16_t*)(eh->ether_dhost + sizeof(u_int32_t)) == 0xFFFF)
413 m->m_flags |= M_BCAST;
414 else
415 m->m_flags |= M_MCAST;
416 }
417
418 if (ifp->if_eflags & IFEF_BOND) {
419 /* if we're bonded, bond "protocol" gets all the packets */
420 *protocol_family = PF_BOND;
421 return (0);
422 }
423
424 if ((eh->ether_dhost[0] & 1) == 0) {
425 /*
426 * When the driver is put into promiscuous mode we may receive unicast
427 * frames that are not intended for our interfaces. They are marked here
428 * as being promiscuous so the caller may dispose of them after passing
429 * the packets to any interface filters.
430 */
431 #define ETHER_CMP(x, y) ( ((u_int16_t *) x)[0] != ((u_int16_t *) y)[0] || \
432 ((u_int16_t *) x)[1] != ((u_int16_t *) y)[1] || \
433 ((u_int16_t *) x)[2] != ((u_int16_t *) y)[2] )
434
435 if (ETHER_CMP(eh->ether_dhost, ifnet_lladdr(ifp))) {
436 m->m_flags |= M_PROMISC;
437 }
438 }
439
440 /* Quick check for VLAN */
441 if ((m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) != 0 ||
442 ether_type == htons(ETHERTYPE_VLAN)) {
443 *protocol_family = PF_VLAN;
444 return 0;
445 }
446
447 data = mtod(m, u_int8_t*);
448
449 /*
450 * Determine the packet's protocol type and stuff the protocol into
451 * longs for quick compares.
452 */
453
454 if (ntohs(ether_type) <= 1500) {
455 extProto1 = *(u_int32_t*)data;
456
457 // SAP or SNAP
458 if ((extProto1 & htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) {
459 // SNAP
460 type = DLIL_DESC_SNAP;
461 extProto2 = *(u_int32_t*)(data + sizeof(u_int32_t));
462 extProto1 &= htonl(0x000000FF);
463 } else {
464 type = DLIL_DESC_SAP;
465 extProto1 &= htonl(0xFFFFFF00);
466 }
467 } else {
468 type = DLIL_DESC_ETYPE2;
469 }
470
471 /*
472 * Search through the connected protocols for a match.
473 */
474
475 switch (type) {
476 case DLIL_DESC_ETYPE2:
477 for (i = 0; i < maxd; i++) {
478 if ((ed[i].type == type) && (ed[i].data[0] == ether_type)) {
479 *protocol_family = ed[i].protocol_family;
480 return 0;
481 }
482 }
483 break;
484
485 case DLIL_DESC_SAP:
486 for (i = 0; i < maxd; i++) {
487 if ((ed[i].type == type) && (ed[i].data[0] == extProto1)) {
488 *protocol_family = ed[i].protocol_family;
489 return 0;
490 }
491 }
492 break;
493
494 case DLIL_DESC_SNAP:
495 for (i = 0; i < maxd; i++) {
496 if ((ed[i].type == type) && (ed[i].data[0] == extProto1) &&
497 (ed[i].data[1] == extProto2)) {
498 *protocol_family = ed[i].protocol_family;
499 return 0;
500 }
501 }
502 break;
503 }
504
505 return ENOENT;
506 }
507
508 /*
509 * Ethernet output routine.
510 * Encapsulate a packet of type family for the local net.
511 * Use trailer local net encapsulation if enough data in first
512 * packet leaves a multiple of 512 bytes of data in remainder.
513 */
514 int
515 ether_frameout(
516 struct ifnet *ifp,
517 struct mbuf **m,
518 const struct sockaddr *ndest,
519 const char *edst,
520 const char *ether_type)
521 {
522 struct ether_header *eh;
523 int hlen; /* link layer header length */
524
525 hlen = ETHER_HDR_LEN;
526
527 /*
528 * If a simplex interface, and the packet is being sent to our
529 * Ethernet address or a broadcast address, loopback a copy.
530 * XXX To make a simplex device behave exactly like a duplex
531 * device, we should copy in the case of sending to our own
532 * ethernet address (thus letting the original actually appear
533 * on the wire). However, we don't do that here for security
534 * reasons and compatibility with the original behavior.
535 */
536 if ((ifp->if_flags & IFF_SIMPLEX) &&
537 ((*m)->m_flags & M_LOOP)) {
538 if (lo_ifp) {
539 if ((*m)->m_flags & M_BCAST) {
540 struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL);
541 if (n != NULL)
542 dlil_output(lo_ifp, ndest->sa_family, n, 0, ndest, 0);
543 }
544 else {
545 if (bcmp(edst, ifnet_lladdr(ifp), ETHER_ADDR_LEN) == 0) {
546 dlil_output(lo_ifp, ndest->sa_family, *m, 0, ndest, 0);
547 return EJUSTRETURN;
548 }
549 }
550 }
551 }
552
553 /*
554 * Add local net header. If no space in first mbuf,
555 * allocate another.
556 */
557 M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT);
558 if (*m == 0) {
559 return (EJUSTRETURN);
560 }
561
562
563 eh = mtod(*m, struct ether_header *);
564 (void)memcpy(&eh->ether_type, ether_type,
565 sizeof(eh->ether_type));
566 (void)memcpy(eh->ether_dhost, edst, 6);
567 ifnet_lladdr_copy_bytes(ifp, eh->ether_shost, ETHER_ADDR_LEN);
568
569 return 0;
570 }
571
572
573 __private_extern__ int
574 ether_add_if(struct ifnet *ifp)
575 {
576 ifp->if_framer = ether_frameout;
577 ifp->if_demux = ether_demux;
578
579 return 0;
580 }
581
582 __private_extern__ int
583 ether_del_if(struct ifnet *ifp)
584 {
585 if (ifp->family_cookie) {
586 FREE(ifp->family_cookie, M_IFADDR);
587 return 0;
588 }
589 else
590 return ENOENT;
591 }
592
593 __private_extern__ int
594 ether_init_if(struct ifnet *ifp)
595 {
596 /*
597 * Copy ethernet address out of old style arpcom. New
598 * interfaces created using the KPIs will not have an
599 * interface family. Those interfaces will have the
600 * lladdr passed in when the interface is created.
601 */
602 u_char *enaddr = ((u_char*)ifp) + sizeof(struct ifnet);
603 ifnet_set_lladdr(ifp, enaddr, 6);
604 bzero(enaddr, 6);
605
606 return 0;
607 }
608
609
610 errno_t
611 ether_check_multi(
612 ifnet_t ifp,
613 const struct sockaddr *proto_addr)
614 {
615 errno_t result = EAFNOSUPPORT;
616 const u_char *e_addr;
617
618 /*
619 * AF_SPEC and AF_LINK don't require translation. We do
620 * want to verify that they specify a valid multicast.
621 */
622 switch(proto_addr->sa_family) {
623 case AF_UNSPEC:
624 e_addr = (const u_char*)&proto_addr->sa_data[0];
625 if ((e_addr[0] & 0x01) != 0x01)
626 result = EADDRNOTAVAIL;
627 else
628 result = 0;
629 break;
630
631 case AF_LINK:
632 e_addr = CONST_LLADDR((const struct sockaddr_dl*)proto_addr);
633 if ((e_addr[0] & 0x01) != 0x01)
634 result = EADDRNOTAVAIL;
635 else
636 result = 0;
637 break;
638 }
639
640 return result;
641 }
642
643 int
644 ether_ioctl(
645 __unused ifnet_t ifp,
646 __unused u_int32_t command,
647 __unused void* data)
648 {
649 return EOPNOTSUPP;
650 }
651
652
653 extern int ether_attach_inet(struct ifnet *ifp, u_long proto_family);
654 extern int ether_detach_inet(struct ifnet *ifp, u_long proto_family);
655 extern int ether_attach_inet6(struct ifnet *ifp, u_long proto_family);
656 extern int ether_detach_inet6(struct ifnet *ifp, u_long proto_family);
657
658 extern void kprintf(const char *, ...);
659
660 int ether_family_init(void)
661 {
662 int error=0;
663 struct dlil_ifmod_reg_str ifmod_reg;
664
665 /* ethernet family is built-in, called from bsd_init */
666
667 bzero(&ifmod_reg, sizeof(ifmod_reg));
668 ifmod_reg.add_if = ether_add_if;
669 ifmod_reg.del_if = ether_del_if;
670 ifmod_reg.init_if = ether_init_if;
671 ifmod_reg.add_proto = ether_add_proto_old;
672 ifmod_reg.del_proto = ether_del_proto;
673 ifmod_reg.ifmod_ioctl = ether_ioctl;
674 ifmod_reg.shutdown = ether_shutdown;
675
676 if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET, &ifmod_reg)) {
677 printf("WARNING: ether_family_init -- Can't register if family modules\n");
678 error = EIO;
679 goto done;
680 }
681
682 /* Register protocol registration functions */
683
684 if ((error = dlil_reg_proto_module(PF_INET, APPLE_IF_FAM_ETHERNET,
685 ether_attach_inet, ether_detach_inet)) != 0) {
686 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
687 goto done;
688 }
689
690
691 if ((error = dlil_reg_proto_module(PF_INET6, APPLE_IF_FAM_ETHERNET,
692 ether_attach_inet6, ether_detach_inet6)) != 0) {
693 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
694 goto done;
695 }
696 vlan_family_init();
697 bond_family_init();
698
699 done:
700
701 return (error);
702 }