1/* 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1982, 1989, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 */ 61 62 63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/kernel.h> 67#include <sys/malloc.h> 68#include <sys/mbuf.h> 69#include <sys/socket.h> 70#include <sys/sockio.h> 71#include <sys/sysctl.h> 72 73#include <pexpert/pexpert.h> 74 75#define etherbroadcastaddr fugly 76#include <net/if.h> 77#include <net/route.h> 78#include <net/if_llc.h> 79#include <net/if_dl.h> 80#include <net/if_types.h> 81#include <net/if_ether.h> 82#include <netinet/if_ether.h> 83#include <netinet/in.h> /* For M_LOOP */ 84#include <net/kpi_interface.h> 85#include <net/kpi_protocol.h> 86#undef etherbroadcastaddr 87 88/* 89#if INET 90#include <netinet/in.h> 91#include <netinet/in_var.h> 92 93#include <netinet/in_systm.h> 94#include <netinet/ip.h> 95#endif 96*/ 97#include <net/ether_if_module.h> 98#include <sys/socketvar.h> 99#include <net/if_vlan_var.h> 100#if BOND 101#include <net/if_bond_internal.h> 102#endif /* BOND */ 103#if IF_BRIDGE 104#include <net/if_bridgevar.h> 105#endif /* IF_BRIDGE */ 106 107#include <net/dlil.h> 108 109#if LLC && CCITT 110extern struct ifqueue pkintrq; 111#endif 112 113/* General stuff from if_ethersubr.c - may not need some of it */ 114 115#include <netat/at_pat.h> 116#if NETAT 117extern struct ifqueue atalkintrq; 118#endif 119 120 121#define memcpy(x,y,z) bcopy(y, x, z) 122 123 124SYSCTL_DECL(_net_link); 125SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Ethernet"); 126 127struct en_desc { 128 u_int16_t type; /* Type of protocol stored in data */ 129 u_int32_t protocol_family; /* Protocol family */ 130 u_int32_t data[2]; /* Protocol data */ 131}; 132 133/* descriptors are allocated in blocks of ETHER_DESC_BLK_SIZE */ 134#if CONFIG_EMBEDDED 135#define ETHER_DESC_BLK_SIZE (2) /* IP, ARP */ 136#else 137#define ETHER_DESC_BLK_SIZE (10) 138#endif 139 140/* 141 * Header for the demux list, hangs off of IFP at if_family_cookie 142 */ 143 144struct ether_desc_blk_str { 145 u_int32_t n_max_used; 146 u_int32_t n_count; 147 u_int32_t n_used; 148 struct en_desc block_ptr[1]; 149}; 150/* Size of the above struct before the array of struct en_desc */ 151#define ETHER_DESC_HEADER_SIZE ((size_t)offsetof(struct ether_desc_blk_str, block_ptr)) 152__private_extern__ u_char etherbroadcastaddr[ETHER_ADDR_LEN] = 153 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 154 155 156/* 157 * Release all descriptor entries owned by this protocol (there may be several). 158 * Setting the type to 0 releases the entry. Eventually we should compact-out 159 * the unused entries. 160 */ 161int 162ether_del_proto( 163 ifnet_t ifp, 164 protocol_family_t protocol_family) 165{ 166 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->if_family_cookie; 167 u_int32_t current = 0; 168 int found = 0; 169 170 if (desc_blk == NULL) 171 return 0; 172 173 for (current = desc_blk->n_max_used; current > 0; current--) { 174 if (desc_blk->block_ptr[current - 1].protocol_family == protocol_family) { 175 found = 1; 176 desc_blk->block_ptr[current - 1].type = 0; 177 desc_blk->n_used--; 178 } 179 } 180 181 if (desc_blk->n_used == 0) { 182 FREE(ifp->if_family_cookie, M_IFADDR); 183 ifp->if_family_cookie = 0; 184 } 185 else { 186 /* Decrement n_max_used */ 187 for (; desc_blk->n_max_used > 0 && desc_blk->block_ptr[desc_blk->n_max_used - 1].type == 0; desc_blk->n_max_used--) 188 ; 189 } 190 191 return 0; 192 } 193 194 195static int 196ether_add_proto_internal( 197 struct ifnet *ifp, 198 protocol_family_t protocol, 199 const struct ifnet_demux_desc *demux) 200{ 201 struct en_desc *ed; 202 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->if_family_cookie; 203 u_int32_t i; 204 205 switch (demux->type) { 206 /* These types are supported */ 207 /* Top three are preferred */ 208 case DLIL_DESC_ETYPE2: 209 if (demux->datalen != 2) { 210 return EINVAL; 211 } 212 break; 213 214 case DLIL_DESC_SAP: 215 if (demux->datalen != 3) { 216 return EINVAL; 217 } 218 break; 219 220 case DLIL_DESC_SNAP: 221 if (demux->datalen != 5) { 222 return EINVAL; 223 } 224 break; 225 226 default: 227 return ENOTSUP; 228 } 229 230 // Verify a matching descriptor does not exist. 231 if (desc_blk != NULL) { 232 switch (demux->type) { 233 case DLIL_DESC_ETYPE2: 234 for (i = 0; i < desc_blk->n_max_used; i++) { 235 if (desc_blk->block_ptr[i].type == DLIL_DESC_ETYPE2 && 236 desc_blk->block_ptr[i].data[0] == 237 *(u_int16_t*)demux->data) { 238 return EADDRINUSE; 239 } 240 } 241 break; 242 case DLIL_DESC_SAP: 243 case DLIL_DESC_SNAP: 244 for (i = 0; i < desc_blk->n_max_used; i++) { 245 if (desc_blk->block_ptr[i].type == demux->type && 246 bcmp(desc_blk->block_ptr[i].data, demux->data, 247 demux->datalen) == 0) { 248 return EADDRINUSE; 249 } 250 } 251 break; 252 } 253 } 254 255 // Check for case where all of the descriptor blocks are in use 256 if (desc_blk == NULL || desc_blk->n_used == desc_blk->n_count) { 257 struct ether_desc_blk_str *tmp; 258 u_int32_t new_count = ETHER_DESC_BLK_SIZE; 259 u_int32_t new_size; 260 u_int32_t old_size = 0; 261 262 i = 0; 263 264 if (desc_blk) { 265 new_count += desc_blk->n_count; 266 old_size = desc_blk->n_count * sizeof(struct en_desc) + ETHER_DESC_HEADER_SIZE; 267 i = desc_blk->n_used; 268 } 269 270 new_size = new_count * sizeof(struct en_desc) + ETHER_DESC_HEADER_SIZE; 271 272 tmp = _MALLOC(new_size, M_IFADDR, M_WAITOK); 273 if (tmp == 0) { 274 /* 275 * Remove any previous descriptors set in the call. 276 */ 277 return ENOMEM; 278 } 279 280 bzero(((char *)tmp) + old_size, new_size - old_size); 281 if (desc_blk) { 282 bcopy(desc_blk, tmp, old_size); 283 FREE(desc_blk, M_IFADDR); 284 } 285 desc_blk = tmp; 286 ifp->if_family_cookie = (uintptr_t)desc_blk; 287 desc_blk->n_count = new_count; 288 } 289 else { 290 /* Find a free entry */ 291 for (i = 0; i < desc_blk->n_count; i++) { 292 if (desc_blk->block_ptr[i].type == 0) { 293 break; 294 } 295 } 296 } 297 298 /* Bump n_max_used if appropriate */ 299 if (i + 1 > desc_blk->n_max_used) { 300 desc_blk->n_max_used = i + 1; 301 } 302 303 ed = &desc_blk->block_ptr[i]; 304 ed->protocol_family = protocol; 305 ed->data[0] = 0; 306 ed->data[1] = 0; 307 308 switch (demux->type) { 309 case DLIL_DESC_ETYPE2: 310 /* 2 byte ethernet raw protocol type is at native_type */ 311 /* prtocol must be in network byte order */ 312 ed->type = DLIL_DESC_ETYPE2; 313 ed->data[0] = *(u_int16_t*)demux->data; 314 break; 315 316 case DLIL_DESC_SAP: 317 ed->type = DLIL_DESC_SAP; 318 bcopy(demux->data, &ed->data[0], 3); 319 break; 320 321 case DLIL_DESC_SNAP: { 322 u_int8_t* pDest = ((u_int8_t*)&ed->data[0]) + 3; 323 ed->type = DLIL_DESC_SNAP; 324 bcopy(demux->data, pDest, 5); 325 } 326 break; 327 } 328 329 desc_blk->n_used++; 330 331 return 0; 332} 333 334int 335ether_add_proto( 336 ifnet_t ifp, 337 protocol_family_t protocol, 338 const struct ifnet_demux_desc *demux_list, 339 u_int32_t demux_count) 340{ 341 int error = 0; 342 u_int32_t i; 343 344 for (i = 0; i < demux_count; i++) { 345 error = ether_add_proto_internal(ifp, protocol, &demux_list[i]); 346 if (error) { 347 ether_del_proto(ifp, protocol); 348 break; 349 } 350 } 351 352 return error; 353} 354 355int 356ether_demux( 357 ifnet_t ifp, 358 mbuf_t m, 359 char *frame_header, 360 protocol_family_t *protocol_family) 361{ 362 struct ether_header *eh = (struct ether_header *)(void *)frame_header; 363 u_short ether_type = eh->ether_type; 364 u_int16_t type; 365 u_int8_t *data; 366 u_int32_t i = 0; 367 struct ether_desc_blk_str *desc_blk = (struct ether_desc_blk_str *)ifp->if_family_cookie; 368 u_int32_t maxd = desc_blk ? desc_blk->n_max_used : 0; 369 struct en_desc *ed = desc_blk ? desc_blk->block_ptr : NULL; 370 u_int32_t extProto1 = 0; 371 u_int32_t extProto2 = 0; 372 373 if (eh->ether_dhost[0] & 1) { 374 /* Check for broadcast */ 375 if (_ether_cmp(etherbroadcastaddr, eh->ether_dhost) == 0) 376 m->m_flags |= M_BCAST; 377 else 378 m->m_flags |= M_MCAST; 379 } 380 381 if (m->m_flags & M_HASFCS) { 382 /* 383 * If the M_HASFCS is set by the driver we want to make sure 384 * that we strip off the trailing FCS data before handing it 385 * up the stack. 386 */ 387 m_adj(m, -ETHER_CRC_LEN); 388 m->m_flags &= ~M_HASFCS; 389 } 390 391 if (ifp->if_eflags & IFEF_BOND) { 392 /* if we're bonded, bond "protocol" gets all the packets */ 393 *protocol_family = PF_BOND; 394 return (0); 395 } 396 397 if ((eh->ether_dhost[0] & 1) == 0) { 398 /* 399 * When the driver is put into promiscuous mode we may receive unicast 400 * frames that are not intended for our interfaces. They are marked here 401 * as being promiscuous so the caller may dispose of them after passing 402 * the packets to any interface filters. 403 */ 404 if (_ether_cmp(eh->ether_dhost, ifnet_lladdr(ifp))) { 405 m->m_flags |= M_PROMISC; 406 } 407 } 408 409 /* check for VLAN */ 410 if ((m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) != 0) { 411 if (EVL_VLANOFTAG(m->m_pkthdr.vlan_tag) != 0) { 412 *protocol_family = PF_VLAN; 413 return (0); 414 } 415 /* the packet is just priority-tagged, clear the bit */ 416 m->m_pkthdr.csum_flags &= ~CSUM_VLAN_TAG_VALID; 417 } 418 else if (ether_type == htons(ETHERTYPE_VLAN)) { 419 struct ether_vlan_header * evl; 420 421 evl = (struct ether_vlan_header *)(void *)frame_header; 422 if (m->m_len < ETHER_VLAN_ENCAP_LEN 423 || ntohs(evl->evl_proto) == ETHERTYPE_VLAN 424 || EVL_VLANOFTAG(ntohs(evl->evl_tag)) != 0) { 425 *protocol_family = PF_VLAN; 426 return 0; 427 } 428 /* the packet is just priority-tagged */ 429 430 /* make the encapsulated ethertype the actual ethertype */ 431 ether_type = evl->evl_encap_proto = evl->evl_proto; 432 433 /* remove the encapsulation header */ 434 m->m_len -= ETHER_VLAN_ENCAP_LEN; 435 m->m_data += ETHER_VLAN_ENCAP_LEN; 436 m->m_pkthdr.len -= ETHER_VLAN_ENCAP_LEN; 437 m->m_pkthdr.csum_flags = 0; /* can't trust hardware checksum */ 438 } 439 440 data = mtod(m, u_int8_t*); 441 442 /* 443 * Determine the packet's protocol type and stuff the protocol into 444 * longs for quick compares. 445 */ 446 447 if (ntohs(ether_type) <= 1500) { 448 bcopy(data, &extProto1, sizeof (u_int32_t)); 449 450 // SAP or SNAP 451 if ((extProto1 & htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) { 452 // SNAP 453 type = DLIL_DESC_SNAP; 454 bcopy(data + sizeof(u_int32_t), &extProto2, sizeof (u_int32_t)); 455 extProto1 &= htonl(0x000000FF); 456 } else { 457 type = DLIL_DESC_SAP; 458 extProto1 &= htonl(0xFFFFFF00); 459 } 460 } else { 461 type = DLIL_DESC_ETYPE2; 462 } 463 464 /* 465 * Search through the connected protocols for a match. 466 */ 467 468 switch (type) { 469 case DLIL_DESC_ETYPE2: 470 for (i = 0; i < maxd; i++) { 471 if ((ed[i].type == type) && (ed[i].data[0] == ether_type)) { 472 *protocol_family = ed[i].protocol_family; 473 return 0; 474 } 475 } 476 break; 477 478 case DLIL_DESC_SAP: 479 for (i = 0; i < maxd; i++) { 480 if ((ed[i].type == type) && (ed[i].data[0] == extProto1)) { 481 *protocol_family = ed[i].protocol_family; 482 return 0; 483 } 484 } 485 break; 486 487 case DLIL_DESC_SNAP: 488 for (i = 0; i < maxd; i++) { 489 if ((ed[i].type == type) && (ed[i].data[0] == extProto1) && 490 (ed[i].data[1] == extProto2)) { 491 *protocol_family = ed[i].protocol_family; 492 return 0; 493 } 494 } 495 break; 496 } 497 498 return ENOENT; 499} 500 501/* 502 * Ethernet output routine. 503 * Encapsulate a packet of type family for the local net. 504 * Use trailer local net encapsulation if enough data in first 505 * packet leaves a multiple of 512 bytes of data in remainder. 506 */ 507int 508ether_frameout( 509 struct ifnet *ifp, 510 struct mbuf **m, 511 const struct sockaddr *ndest, 512 const char *edst, 513 const char *ether_type 514#if KPI_INTERFACE_EMBEDDED 515 , 516 u_int32_t *prepend_len, 517 u_int32_t *postpend_len 518#endif /* KPI_INTERFACE_EMBEDDED */ 519 ) 520{ 521 struct ether_header *eh; 522 int hlen; /* link layer header length */ 523 524 hlen = ETHER_HDR_LEN; 525 526 /* 527 * If a simplex interface, and the packet is being sent to our 528 * Ethernet address or a broadcast address, loopback a copy. 529 * XXX To make a simplex device behave exactly like a duplex 530 * device, we should copy in the case of sending to our own 531 * ethernet address (thus letting the original actually appear 532 * on the wire). However, we don't do that here for security 533 * reasons and compatibility with the original behavior. 534 */ 535 if ((ifp->if_flags & IFF_SIMPLEX) && 536 ((*m)->m_flags & M_LOOP)) { 537 if (lo_ifp) { 538 if ((*m)->m_flags & M_BCAST) { 539 struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL); 540 if (n != NULL) 541 dlil_output(lo_ifp, ndest->sa_family, n, NULL, ndest, 0, NULL); 542 } 543 else { 544 if (_ether_cmp(edst, ifnet_lladdr(ifp)) == 0) { 545 dlil_output(lo_ifp, ndest->sa_family, *m, NULL, ndest, 0, NULL); 546 return EJUSTRETURN; 547 } 548 } 549 } 550 } 551 552 /* 553 * Add local net header. If no space in first mbuf, 554 * allocate another. 555 */ 556 M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT); 557 if (*m == 0) { 558 return (EJUSTRETURN); 559 } 560 561#if KPI_INTERFACE_EMBEDDED 562 *prepend_len = sizeof (struct ether_header); 563 *postpend_len = 0; 564#endif /* KPI_INTERFACE_EMBEDDED */ 565 566 eh = mtod(*m, struct ether_header *); 567 (void)memcpy(&eh->ether_type, ether_type, 568 sizeof(eh->ether_type)); 569 (void)memcpy(eh->ether_dhost, edst, ETHER_ADDR_LEN); 570 ifnet_lladdr_copy_bytes(ifp, eh->ether_shost, ETHER_ADDR_LEN); 571 572 return 0; 573} 574 575errno_t 576ether_check_multi( 577 __unused ifnet_t ifp, 578 const struct sockaddr *proto_addr) 579{ 580 errno_t result = EAFNOSUPPORT; 581 const u_char *e_addr; 582 583 /* 584 * AF_SPEC and AF_LINK don't require translation. We do 585 * want to verify that they specify a valid multicast. 586 */ 587 switch(proto_addr->sa_family) { 588 case AF_UNSPEC: 589 e_addr = (const u_char*)&proto_addr->sa_data[0]; 590 if ((e_addr[0] & 0x01) != 0x01) 591 result = EADDRNOTAVAIL; 592 else 593 result = 0; 594 break; 595 596 case AF_LINK: 597 e_addr = CONST_LLADDR((const struct sockaddr_dl*) 598 (uintptr_t)(size_t)proto_addr); 599 if ((e_addr[0] & 0x01) != 0x01) 600 result = EADDRNOTAVAIL; 601 else 602 result = 0; 603 break; 604 } 605 606 return result; 607} 608 609int 610ether_ioctl( 611 __unused ifnet_t ifp, 612 __unused u_int32_t command, 613 __unused void* data) 614{ 615 return EOPNOTSUPP; 616} 617 618__private_extern__ int ether_family_init(void) 619{ 620 errno_t error = 0; 621 622 /* Register protocol registration functions */ 623 if ((error = proto_register_plumber(PF_INET, APPLE_IF_FAM_ETHERNET, 624 ether_attach_inet, ether_detach_inet)) != 0) { 625 printf("proto_register_plumber failed for PF_INET error=%d\n", error); 626 goto done; 627 } 628#if INET6 629 if ((error = proto_register_plumber(PF_INET6, APPLE_IF_FAM_ETHERNET, 630 ether_attach_inet6, ether_detach_inet6)) != 0) { 631 printf("proto_register_plumber failed for PF_INET6 error=%d\n", error); 632 goto done; 633 } 634#endif /* INET6 */ 635#if NETAT 636 if ((error = proto_register_plumber(PF_APPLETALK, APPLE_IF_FAM_ETHERNET, 637 ether_attach_at, ether_detach_at)) != 0) { 638 printf("proto_register_plumber failed PF_APPLETALK error=%d\n", error); 639 goto done; 640 } 641#endif /* NETAT */ 642#if VLAN 643 vlan_family_init(); 644#endif /* VLAN */ 645#if BOND 646 bond_family_init(); 647#endif /* BOND */ 648#if IF_BRIDGE 649 bridgeattach(0); 650#endif /* IF_BRIDGE */ 651 652 done: 653 654 return (error); 655} 656