2  * Copyright (c) 2000-2013 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1982, 1989, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  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. 
  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 
  62 #include <sys/param.h> 
  63 #include <sys/systm.h> 
  64 #include <sys/kernel.h> 
  65 #include <sys/malloc.h> 
  67 #include <sys/socket.h> 
  68 #include <sys/sockio.h> 
  69 #include <sys/sysctl.h> 
  71 #include <pexpert/pexpert.h> 
  73 #define etherbroadcastaddr      fugly 
  75 #include <net/route.h> 
  76 #include <net/if_llc.h> 
  77 #include <net/if_dl.h> 
  78 #include <net/if_types.h> 
  79 #include <net/if_ether.h> 
  80 #include <net/if_gif.h> 
  81 #include <netinet/if_ether.h> 
  82 #include <netinet/in.h> /* For M_LOOP */ 
  83 #include <net/kpi_interface.h> 
  84 #include <net/kpi_protocol.h> 
  85 #undef etherbroadcastaddr 
  89 #include <netinet/in.h> 
  90 #include <netinet/in_var.h> 
  92 #include <netinet/in_systm.h> 
  93 #include <netinet/ip.h> 
  96 #include <net/ether_if_module.h> 
  97 #include <sys/socketvar.h> 
  98 #include <net/if_vlan_var.h> 
 100 #include <net/if_bond_internal.h> 
 103 #include <net/if_bridgevar.h> 
 104 #endif /* IF_BRIDGE */ 
 106 #include <net/dlil.h> 
 108 #define memcpy(x,y,z)   bcopy(y, x, z) 
 110 SYSCTL_DECL(_net_link
); 
 111 SYSCTL_NODE(_net_link
, IFT_ETHER
, ether
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0, 
 115         u_int16_t type
;                 /* Type of protocol stored in data */ 
 116         u_int32_t protocol_family
;      /* Protocol family */ 
 117         u_int32_t data
[2];              /* Protocol data */ 
 120 /* descriptors are allocated in blocks of ETHER_DESC_BLK_SIZE */ 
 121 #define ETHER_DESC_BLK_SIZE (10) 
 124  * Header for the demux list, hangs off of IFP at if_family_cookie 
 126 struct ether_desc_blk_str 
{ 
 127         u_int32_t  n_max_used
; 
 130         struct en_desc  block_ptr
[1]; 
 133 /* Size of the above struct before the array of struct en_desc */ 
 134 #define ETHER_DESC_HEADER_SIZE  \ 
 135         ((size_t) offsetof(struct ether_desc_blk_str, block_ptr)) 
 137 __private_extern__ u_char etherbroadcastaddr
[ETHER_ADDR_LEN
] = 
 138     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 141  * Release all descriptor entries owned by this protocol (there may be several). 
 142  * Setting the type to 0 releases the entry. Eventually we should compact-out 
 143  * the unused entries. 
 146 ether_del_proto(ifnet_t ifp
, protocol_family_t protocol_family
) 
 148         struct ether_desc_blk_str 
*desc_blk 
= 
 149             (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 150         u_int32_t current 
= 0; 
 153         if (desc_blk 
== NULL
) 
 156         for (current 
= desc_blk
->n_max_used
; current 
> 0; current
--) { 
 157                 if (desc_blk
->block_ptr
[current 
- 1].protocol_family 
== 
 160                         desc_blk
->block_ptr
[current 
- 1].type 
= 0; 
 165         if (desc_blk
->n_used 
== 0) { 
 166                 FREE(ifp
->if_family_cookie
, M_IFADDR
); 
 167                 ifp
->if_family_cookie 
= 0; 
 169                 /* Decrement n_max_used */ 
 170                 for (; desc_blk
->n_max_used 
> 0 && 
 171                     desc_blk
->block_ptr
[desc_blk
->n_max_used 
- 1].type 
== 0; 
 172                     desc_blk
->n_max_used
--) 
 180 ether_add_proto_internal(struct ifnet 
*ifp
, protocol_family_t protocol
, 
 181     const struct ifnet_demux_desc 
*demux
) 
 184         struct ether_desc_blk_str 
*desc_blk 
= 
 185             (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 188         switch (demux
->type
) { 
 189         /* These types are supported */ 
 190         /* Top three are preferred */ 
 191         case DLIL_DESC_ETYPE2
: 
 192                 if (demux
->datalen 
!= 2) 
 197                 if (demux
->datalen 
!= 3) 
 202                 if (demux
->datalen 
!= 5) 
 210         /* Verify a matching descriptor does not exist */ 
 211         if (desc_blk 
!= NULL
) { 
 212                 switch (demux
->type
) { 
 213                 case DLIL_DESC_ETYPE2
: 
 214                         for (i 
= 0; i 
< desc_blk
->n_max_used
; i
++) { 
 215                                 if (desc_blk
->block_ptr
[i
].type 
== 
 217                                     desc_blk
->block_ptr
[i
].data
[0] == 
 218                                     *(u_int16_t
*)demux
->data
) { 
 225                         for (i 
= 0; i 
< desc_blk
->n_max_used
; i
++) { 
 226                                 if (desc_blk
->block_ptr
[i
].type 
== 
 228                                     bcmp(desc_blk
->block_ptr
[i
].data
, 
 229                                     demux
->data
, demux
->datalen
) == 0) { 
 237         /* Check for case where all of the descriptor blocks are in use */ 
 238         if (desc_blk 
== NULL 
|| desc_blk
->n_used 
== desc_blk
->n_count
) { 
 239                 struct ether_desc_blk_str 
*tmp
; 
 240                 u_int32_t new_count 
= ETHER_DESC_BLK_SIZE
; 
 242                 u_int32_t old_size 
= 0; 
 247                         new_count 
+= desc_blk
->n_count
; 
 248                         old_size 
= desc_blk
->n_count 
* sizeof (struct en_desc
) + 
 249                             ETHER_DESC_HEADER_SIZE
; 
 250                         i 
= desc_blk
->n_used
; 
 253                 new_size 
= new_count 
* sizeof (struct en_desc
) + 
 254                     ETHER_DESC_HEADER_SIZE
; 
 256                 tmp 
= _MALLOC(new_size
, M_IFADDR
, M_WAITOK
); 
 259                          * Remove any previous descriptors set in the call. 
 264                 bzero(((char *)tmp
) + old_size
, new_size 
- old_size
); 
 266                         bcopy(desc_blk
, tmp
, old_size
); 
 267                         FREE(desc_blk
, M_IFADDR
); 
 270                 ifp
->if_family_cookie 
= (uintptr_t)desc_blk
; 
 271                 desc_blk
->n_count 
= new_count
; 
 273                 /* Find a free entry */ 
 274                 for (i 
= 0; i 
< desc_blk
->n_count
; i
++) { 
 275                         if (desc_blk
->block_ptr
[i
].type 
== 0) { 
 281         /* Bump n_max_used if appropriate */ 
 282         if (i 
+ 1 > desc_blk
->n_max_used
) { 
 283                 desc_blk
->n_max_used 
= i 
+ 1; 
 286         ed 
= &desc_blk
->block_ptr
[i
]; 
 287         ed
->protocol_family 
= protocol
; 
 291         switch (demux
->type
) { 
 292         case DLIL_DESC_ETYPE2
: 
 293                 /* 2 byte ethernet raw protocol type is at native_type */ 
 294                 /* prtocol must be in network byte order */ 
 295                 ed
->type 
= DLIL_DESC_ETYPE2
; 
 296                 ed
->data
[0] = *(u_int16_t
*)demux
->data
; 
 300                 ed
->type 
= DLIL_DESC_SAP
; 
 301                 bcopy(demux
->data
, &ed
->data
[0], 3); 
 304         case DLIL_DESC_SNAP
: { 
 305                 u_int8_t
*       pDest 
= ((u_int8_t
*)&ed
->data
[0]) + 3; 
 306                 ed
->type 
= DLIL_DESC_SNAP
; 
 307                 bcopy(demux
->data
, pDest
, 5); 
 318 ether_add_proto(ifnet_t  ifp
, protocol_family_t protocol
, 
 319     const struct ifnet_demux_desc 
*demux_list
, u_int32_t demux_count
) 
 324         for (i 
= 0; i 
< demux_count
; i
++) { 
 325                 error 
= ether_add_proto_internal(ifp
, protocol
, &demux_list
[i
]); 
 327                         ether_del_proto(ifp
, protocol
); 
 336 ether_demux(ifnet_t ifp
, mbuf_t m
, char *frame_header
, 
 337     protocol_family_t 
*protocol_family
) 
 339         struct ether_header 
*eh 
= (struct ether_header 
*)(void *)frame_header
; 
 340         u_short  ether_type 
= eh
->ether_type
; 
 344         struct ether_desc_blk_str 
*desc_blk 
= 
 345             (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 346         u_int32_t maxd 
= desc_blk 
? desc_blk
->n_max_used 
: 0; 
 347         struct en_desc  
*ed 
= desc_blk 
? desc_blk
->block_ptr 
: NULL
; 
 348         u_int32_t extProto1 
= 0; 
 349         u_int32_t extProto2 
= 0; 
 351         if (eh
->ether_dhost
[0] & 1) { 
 352                 /* Check for broadcast */ 
 353                 if (_ether_cmp(etherbroadcastaddr
, eh
->ether_dhost
) == 0) 
 354                         m
->m_flags 
|= M_BCAST
; 
 356                         m
->m_flags 
|= M_MCAST
; 
 359         if (m
->m_flags 
& M_HASFCS
) { 
 361                  * If the M_HASFCS is set by the driver we want to make sure 
 362                  * that we strip off the trailing FCS data before handing it 
 365                 m_adj(m
, -ETHER_CRC_LEN
); 
 366                 m
->m_flags 
&= ~M_HASFCS
; 
 369         if (ifp
->if_eflags 
& IFEF_BOND
) { 
 370                 /* if we're bonded, bond "protocol" gets all the packets */ 
 371                 *protocol_family 
= PF_BOND
; 
 375         if ((eh
->ether_dhost
[0] & 1) == 0) { 
 377                  * When the driver is put into promiscuous mode we may receive 
 378                  * unicast frames that are not intended for our interfaces. 
 379                  * They are marked here as being promiscuous so the caller may 
 380                  * dispose of them after passing the packets to any interface 
 383                 if (_ether_cmp(eh
->ether_dhost
, IF_LLADDR(ifp
))) { 
 384                         m
->m_flags 
|= M_PROMISC
; 
 389         if ((m
->m_pkthdr
.csum_flags 
& CSUM_VLAN_TAG_VALID
) != 0) { 
 390                 if (EVL_VLANOFTAG(m
->m_pkthdr
.vlan_tag
) != 0) { 
 391                         *protocol_family 
= PF_VLAN
; 
 394                 /* the packet is just priority-tagged, clear the bit */ 
 395                 m
->m_pkthdr
.csum_flags 
&= ~CSUM_VLAN_TAG_VALID
; 
 396         } else if (ether_type 
== htons(ETHERTYPE_VLAN
)) { 
 397                 struct ether_vlan_header 
*      evl
; 
 399                 evl 
= (struct ether_vlan_header 
*)(void *)frame_header
; 
 400                 if (m
->m_len 
< ETHER_VLAN_ENCAP_LEN 
|| 
 401                     ntohs(evl
->evl_proto
) == ETHERTYPE_VLAN 
|| 
 402                     EVL_VLANOFTAG(ntohs(evl
->evl_tag
)) != 0) { 
 403                         *protocol_family 
= PF_VLAN
; 
 406                 /* the packet is just priority-tagged */ 
 408                 /* make the encapsulated ethertype the actual ethertype */ 
 409                 ether_type 
= evl
->evl_encap_proto 
= evl
->evl_proto
; 
 411                 /* remove the encapsulation header */ 
 412                 m
->m_len 
-= ETHER_VLAN_ENCAP_LEN
; 
 413                 m
->m_data 
+= ETHER_VLAN_ENCAP_LEN
; 
 414                 m
->m_pkthdr
.len 
-= ETHER_VLAN_ENCAP_LEN
; 
 415                 m
->m_pkthdr
.csum_flags 
= 0; /* can't trust hardware checksum */ 
 416         } else if (ether_type 
== htons(ETHERTYPE_ARP
)) 
 417                 m
->m_pkthdr
.pkt_flags 
|= PKTF_INET_RESOLVE
; /* ARP packet */ 
 419         data 
= mtod(m
, u_int8_t
*); 
 422         * Determine the packet's protocol type and stuff the protocol into 
 423         * longs for quick compares. 
 425         if (ntohs(ether_type
) <= 1500) { 
 426                 bcopy(data
, &extProto1
, sizeof (u_int32_t
)); 
 429                 if ((extProto1 
& htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) { 
 431                         type 
= DLIL_DESC_SNAP
; 
 432                         bcopy(data 
+ sizeof (u_int32_t
), &extProto2
, 
 434                         extProto1 
&= htonl(0x000000FF); 
 436                         type 
= DLIL_DESC_SAP
; 
 437                         extProto1 
&= htonl(0xFFFFFF00); 
 440                 type 
= DLIL_DESC_ETYPE2
; 
 444         * Search through the connected protocols for a match. 
 447         case DLIL_DESC_ETYPE2
: 
 448                 for (i 
= 0; i 
< maxd
; i
++) { 
 449                         if ((ed
[i
].type 
== type
) && 
 450                             (ed
[i
].data
[0] == ether_type
)) { 
 451                                 *protocol_family 
= ed
[i
].protocol_family
; 
 458                 for (i 
= 0; i 
< maxd
; i
++) { 
 459                         if ((ed
[i
].type 
== type
) && 
 460                             (ed
[i
].data
[0] == extProto1
)) { 
 461                                 *protocol_family 
= ed
[i
].protocol_family
; 
 468                 for (i 
= 0; i 
< maxd
; i
++) { 
 469                         if ((ed
[i
].type 
== type
) && 
 470                             (ed
[i
].data
[0] == extProto1
) && 
 471                                 (ed
[i
].data
[1] == extProto2
)) { 
 472                                 *protocol_family 
= ed
[i
].protocol_family
; 
 483  * On embedded, ether_frameout is practicaly ether_frameout_extended. 
 484  * On non-embedded, ether_frameout has long been exposed as a public KPI, 
 485  * and therefore its signature must remain the same (without the pre- and 
 486  * postpend length parameters.) 
 488 #if KPI_INTERFACE_EMBEDDED 
 490 ether_frameout(struct ifnet 
*ifp
, struct mbuf 
**m
, 
 491     const struct sockaddr 
*ndest
, const char *edst
, 
 492     const char *ether_type
, u_int32_t 
*prepend_len
, u_int32_t 
*postpend_len
) 
 493 #else /* !KPI_INTERFACE_EMBEDDED */ 
 495 ether_frameout(struct ifnet 
*ifp
, struct mbuf 
**m
, 
 496     const struct sockaddr 
*ndest
, const char *edst
, 
 497     const char *ether_type
) 
 498 #endif /* KPI_INTERFACE_EMBEDDED */ 
 500 #if KPI_INTERFACE_EMBEDDED 
 501         return (ether_frameout_extended(ifp
, m
, ndest
, edst
, ether_type
, 
 502             prepend_len
, postpend_len
)); 
 503 #else /* !KPI_INTERFACE_EMBEDDED */ 
 504         return (ether_frameout_extended(ifp
, m
, ndest
, edst
, ether_type
, 
 506 #endif /* !KPI_INTERFACE_EMBEDDED */ 
 510  * Ethernet output routine. 
 511  * Encapsulate a packet of type family for the local net. 
 512  * Use trailer local net encapsulation if enough data in first 
 513  * packet leaves a multiple of 512 bytes of data in remainder. 
 516 ether_frameout_extended(struct ifnet 
*ifp
, struct mbuf 
**m
, 
 517     const struct sockaddr 
*ndest
, const char *edst
, 
 518     const char *ether_type
, u_int32_t 
*prepend_len
, u_int32_t 
*postpend_len
) 
 520         struct ether_header 
*eh
; 
 521         int hlen
;       /* link layer header length */ 
 523         hlen 
= ETHER_HDR_LEN
; 
 526          * If a simplex interface, and the packet is being sent to our 
 527          * Ethernet address or a broadcast address, loopback a copy. 
 528          * XXX To make a simplex device behave exactly like a duplex 
 529          * device, we should copy in the case of sending to our own 
 530          * ethernet address (thus letting the original actually appear 
 531          * on the wire). However, we don't do that here for security 
 532          * reasons and compatibility with the original behavior. 
 534         if ((ifp
->if_flags 
& IFF_SIMPLEX
) && 
 535             ((*m
)->m_flags 
& M_LOOP
) && lo_ifp 
!= NULL
) { 
 536                 if ((*m
)->m_flags 
& M_BCAST
) { 
 537                         struct mbuf 
*n 
= m_copy(*m
, 0, (int)M_COPYALL
); 
 539                                 dlil_output(lo_ifp
, ndest
->sa_family
, 
 540                                     n
, NULL
, ndest
, 0, NULL
); 
 542                 } else if (_ether_cmp(edst
, IF_LLADDR(ifp
)) == 0) { 
 543                         dlil_output(lo_ifp
, ndest
->sa_family
, *m
, 
 544                             NULL
, ndest
, 0, NULL
); 
 545                         return (EJUSTRETURN
); 
 550          * Add local net header.  If no space in first mbuf, 
 553         M_PREPEND(*m
, sizeof (struct ether_header
), M_DONTWAIT
, 0); 
 555                 return (EJUSTRETURN
); 
 557         if (prepend_len 
!= NULL
) 
 558                 *prepend_len 
= sizeof (struct ether_header
); 
 559         if (postpend_len 
!= NULL
) 
 562         eh 
= mtod(*m
, struct ether_header 
*); 
 563         (void) memcpy(&eh
->ether_type
, ether_type
, sizeof(eh
->ether_type
)); 
 564         (void) memcpy(eh
->ether_dhost
, edst
, ETHER_ADDR_LEN
); 
 565         ifnet_lladdr_copy_bytes(ifp
, eh
->ether_shost
, ETHER_ADDR_LEN
); 
 571 ether_check_multi(ifnet_t ifp
, const struct sockaddr 
*proto_addr
) 
 574         errno_t result 
= EAFNOSUPPORT
; 
 575         const u_char 
*e_addr
; 
 578          * AF_SPEC and AF_LINK don't require translation. We do 
 579          * want to verify that they specify a valid multicast. 
 581         switch(proto_addr
->sa_family
) { 
 583                 e_addr 
= (const u_char
*)&proto_addr
->sa_data
[0]; 
 584                 if ((e_addr
[0] & 0x01) != 0x01) 
 585                         result 
= EADDRNOTAVAIL
; 
 591                 e_addr 
= CONST_LLADDR((const struct sockaddr_dl
*) 
 592                     (uintptr_t)(size_t)proto_addr
); 
 593                 if ((e_addr
[0] & 0x01) != 0x01) 
 594                         result 
= EADDRNOTAVAIL
; 
 604 ether_ioctl(ifnet_t ifp
, u_int32_t command
, void *data
) 
 606 #pragma unused(ifp, command, data) 
 610 __private_extern__ 
int 
 611 ether_family_init(void) 
 615         /* Register protocol registration functions */ 
 616         if ((error 
= proto_register_plumber(PF_INET
, APPLE_IF_FAM_ETHERNET
, 
 617             ether_attach_inet
, ether_detach_inet
)) != 0) { 
 618                 printf("proto_register_plumber failed for PF_INET error=%d\n", 
 623         if ((error 
= proto_register_plumber(PF_INET6
, APPLE_IF_FAM_ETHERNET
, 
 624             ether_attach_inet6
, ether_detach_inet6
)) != 0) { 
 625                 printf("proto_register_plumber failed for PF_INET6 error=%d\n", 
 638 #endif /* IF_BRIDGE */