2  * Copyright (c) 2000-2010 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 
  64 #include <sys/param.h> 
  65 #include <sys/systm.h> 
  66 #include <sys/kernel.h> 
  67 #include <sys/malloc.h> 
  69 #include <sys/socket.h> 
  70 #include <sys/sockio.h> 
  71 #include <sys/sysctl.h> 
  73 #include <pexpert/pexpert.h> 
  75 #define etherbroadcastaddr      fugly 
  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 
  90 #include <netinet/in.h> 
  91 #include <netinet/in_var.h> 
  93 #include <netinet/in_systm.h> 
  94 #include <netinet/ip.h> 
  97 #include <net/ether_if_module.h> 
  98 #include <sys/socketvar.h> 
  99 #include <net/if_vlan_var.h> 
 100 #include <net/if_bond_var.h> 
 102 #include <net/if_bridgevar.h> 
 103 #endif /* IF_BRIDGE */ 
 105 #include <net/dlil.h> 
 108 extern struct ifqueue pkintrq
; 
 111 /* General stuff from if_ethersubr.c - may not need some of it */ 
 113 #include <netat/at_pat.h> 
 115 extern struct ifqueue atalkintrq
; 
 119 #define memcpy(x,y,z)   bcopy(y, x, z) 
 122 SYSCTL_DECL(_net_link
); 
 123 SYSCTL_NODE(_net_link
, IFT_ETHER
, ether
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0, "Ethernet"); 
 126         u_int16_t       type
;                   /* Type of protocol stored in data */ 
 127         u_int32_t               protocol_family
;        /* Protocol family */ 
 128         u_int32_t               data
[2];                /* Protocol data */ 
 131 /* descriptors are allocated in blocks of ETHER_DESC_BLK_SIZE */ 
 133 #define ETHER_DESC_BLK_SIZE (2) /* IP, ARP */ 
 135 #define ETHER_DESC_BLK_SIZE (10) 
 139  * Header for the demux list, hangs off of IFP at if_family_cookie 
 142 struct ether_desc_blk_str 
{ 
 143         u_int32_t  n_max_used
; 
 146         struct en_desc  block_ptr
[1]; 
 148 /* Size of the above struct before the array of struct en_desc */ 
 149 #define ETHER_DESC_HEADER_SIZE  ((size_t)offsetof(struct ether_desc_blk_str, block_ptr)) 
 150 __private_extern__ u_char       etherbroadcastaddr
[ETHER_ADDR_LEN
] = 
 151                                                                 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 155  * Release all descriptor entries owned by this protocol (there may be several). 
 156  * Setting the type to 0 releases the entry. Eventually we should compact-out 
 157  * the unused entries. 
 162         protocol_family_t protocol_family
) 
 164         struct ether_desc_blk_str 
*desc_blk 
= (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 165         u_int32_t       current 
= 0; 
 168         if (desc_blk 
== NULL
) 
 171         for (current 
= desc_blk
->n_max_used
; current 
> 0; current
--) { 
 172                 if (desc_blk
->block_ptr
[current 
- 1].protocol_family 
== protocol_family
) { 
 174                         desc_blk
->block_ptr
[current 
- 1].type 
= 0; 
 179         if (desc_blk
->n_used 
== 0) { 
 180                 FREE(ifp
->if_family_cookie
, M_IFADDR
); 
 181                 ifp
->if_family_cookie 
= 0; 
 184                 /* Decrement n_max_used */ 
 185                 for (; desc_blk
->n_max_used 
> 0 && desc_blk
->block_ptr
[desc_blk
->n_max_used 
- 1].type 
== 0; desc_blk
->n_max_used
--) 
 194 ether_add_proto_internal( 
 196         protocol_family_t                               protocol
, 
 197         const struct ifnet_demux_desc   
*demux
) 
 200         struct ether_desc_blk_str 
*desc_blk 
= (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 203         switch (demux
->type
) { 
 204                 /* These types are supported */ 
 205                 /* Top three are preferred */ 
 206                 case DLIL_DESC_ETYPE2
: 
 207                         if (demux
->datalen 
!= 2) { 
 213                         if (demux
->datalen 
!= 3) { 
 219                         if (demux
->datalen 
!= 5) { 
 228         // Verify a matching descriptor does not exist. 
 229         if (desc_blk 
!= NULL
) { 
 230                 switch (demux
->type
) { 
 231                         case DLIL_DESC_ETYPE2
: 
 232                                 for (i 
= 0; i 
< desc_blk
->n_max_used
; i
++) { 
 233                                         if (desc_blk
->block_ptr
[i
].type 
== DLIL_DESC_ETYPE2 
&& 
 234                                                 desc_blk
->block_ptr
[i
].data
[0] == 
 235                                                 *(u_int16_t
*)demux
->data
) { 
 242                                 for (i 
= 0; i 
< desc_blk
->n_max_used
; i
++) { 
 243                                         if (desc_blk
->block_ptr
[i
].type 
== demux
->type 
&& 
 244                                                 bcmp(desc_blk
->block_ptr
[i
].data
, demux
->data
, 
 245                                                          demux
->datalen
) == 0) { 
 253         // Check for case where all of the descriptor blocks are in use 
 254         if (desc_blk 
== NULL 
|| desc_blk
->n_used 
== desc_blk
->n_count
) { 
 255                 struct ether_desc_blk_str 
*tmp
; 
 256                 u_int32_t       new_count 
= ETHER_DESC_BLK_SIZE
; 
 258                 u_int32_t       old_size 
= 0; 
 263                         new_count 
+= desc_blk
->n_count
; 
 264                         old_size 
= desc_blk
->n_count 
* sizeof(struct en_desc
) + ETHER_DESC_HEADER_SIZE
; 
 265                         i 
= desc_blk
->n_used
; 
 268                 new_size 
= new_count 
* sizeof(struct en_desc
) + ETHER_DESC_HEADER_SIZE
; 
 270                 tmp 
= _MALLOC(new_size
, M_IFADDR
, M_WAITOK
); 
 273                          * Remove any previous descriptors set in the call. 
 278                 bzero(((char *)tmp
) + old_size
, new_size 
- old_size
); 
 280                         bcopy(desc_blk
, tmp
, old_size
); 
 281                         FREE(desc_blk
, M_IFADDR
); 
 284                 ifp
->if_family_cookie 
= (uintptr_t)desc_blk
; 
 285                 desc_blk
->n_count 
= new_count
; 
 288                 /* Find a free entry */ 
 289                 for (i 
= 0; i 
< desc_blk
->n_count
; i
++) { 
 290                         if (desc_blk
->block_ptr
[i
].type 
== 0) { 
 296         /* Bump n_max_used if appropriate */ 
 297         if (i 
+ 1 > desc_blk
->n_max_used
) { 
 298                 desc_blk
->n_max_used 
= i 
+ 1; 
 301         ed 
= &desc_blk
->block_ptr
[i
]; 
 302         ed
->protocol_family 
= protocol
; 
 306         switch (demux
->type
) { 
 307                 case DLIL_DESC_ETYPE2
: 
 308                         /* 2 byte ethernet raw protocol type is at native_type */ 
 309                         /* prtocol must be in network byte order */ 
 310                         ed
->type 
= DLIL_DESC_ETYPE2
; 
 311                         ed
->data
[0] = *(u_int16_t
*)demux
->data
; 
 315                         ed
->type 
= DLIL_DESC_SAP
; 
 316                         bcopy(demux
->data
, &ed
->data
[0], 3); 
 319                 case DLIL_DESC_SNAP
: { 
 320                         u_int8_t
*       pDest 
= ((u_int8_t
*)&ed
->data
[0]) + 3; 
 321                         ed
->type 
= DLIL_DESC_SNAP
; 
 322                         bcopy(demux
->data
, pDest
, 5); 
 335         protocol_family_t       protocol
, 
 336         const struct ifnet_demux_desc 
*demux_list
, 
 337         u_int32_t                       demux_count
) 
 342         for (i 
= 0; i 
< demux_count
; i
++) { 
 343                 error 
= ether_add_proto_internal(ifp
, protocol
, &demux_list
[i
]); 
 345                         ether_del_proto(ifp
, protocol
); 
 358         protocol_family_t       
*protocol_family
) 
 360         struct ether_header 
*eh 
= (struct ether_header 
*)frame_header
; 
 361         u_short                 ether_type 
= eh
->ether_type
; 
 365         struct ether_desc_blk_str 
*desc_blk 
= (struct ether_desc_blk_str 
*)ifp
->if_family_cookie
; 
 366         u_int32_t                       maxd 
= desc_blk 
? desc_blk
->n_max_used 
: 0; 
 367         struct en_desc  
*ed 
= desc_blk 
? desc_blk
->block_ptr 
: NULL
; 
 368         u_int32_t               extProto1 
= 0; 
 369         u_int32_t               extProto2 
= 0; 
 371         if (eh
->ether_dhost
[0] & 1) { 
 372                 /* Check for broadcast */ 
 373                 if (_ether_cmp(etherbroadcastaddr
, eh
->ether_dhost
) == 0) 
 374                         m
->m_flags 
|= M_BCAST
; 
 376                         m
->m_flags 
|= M_MCAST
; 
 379         if (m
->m_flags 
& M_HASFCS
) { 
 381                  * If the M_HASFCS is set by the driver we want to make sure 
 382                  * that we strip off the trailing FCS data before handing it 
 385                 m_adj(m
, -ETHER_CRC_LEN
); 
 386                 m
->m_flags 
&= ~M_HASFCS
; 
 389         if (ifp
->if_eflags 
& IFEF_BOND
) { 
 390                 /* if we're bonded, bond "protocol" gets all the packets */ 
 391                 *protocol_family 
= PF_BOND
; 
 395         if ((eh
->ether_dhost
[0] & 1) == 0) { 
 397                  * When the driver is put into promiscuous mode we may receive unicast 
 398                  * frames that are not intended for our interfaces.  They are marked here 
 399                  * as being promiscuous so the caller may dispose of them after passing 
 400                  * the packets to any interface filters. 
 402                 if (_ether_cmp(eh
->ether_dhost
, ifnet_lladdr(ifp
))) { 
 403                         m
->m_flags 
|= M_PROMISC
; 
 408         if ((m
->m_pkthdr
.csum_flags 
& CSUM_VLAN_TAG_VALID
) != 0) { 
 409                 if (EVL_VLANOFTAG(m
->m_pkthdr
.vlan_tag
) != 0) { 
 410                         *protocol_family 
= PF_VLAN
; 
 413                 /* the packet is just priority-tagged, clear the bit */ 
 414                 m
->m_pkthdr
.csum_flags 
&= ~CSUM_VLAN_TAG_VALID
; 
 416         else if (ether_type 
== htons(ETHERTYPE_VLAN
)) { 
 417                 struct ether_vlan_header 
*      evl
; 
 419                 evl 
= (struct ether_vlan_header 
*)frame_header
; 
 420                 if (m
->m_len 
< ETHER_VLAN_ENCAP_LEN
 
 421                     || ntohs(evl
->evl_proto
) == ETHERTYPE_VLAN
 
 422                     || EVL_VLANOFTAG(ntohs(evl
->evl_tag
)) != 0) { 
 423                         *protocol_family 
= PF_VLAN
; 
 426                 /* the packet is just priority-tagged */ 
 428                 /* make the encapsulated ethertype the actual ethertype */ 
 429                 ether_type 
= evl
->evl_encap_proto 
= evl
->evl_proto
; 
 431                 /* remove the encapsulation header */ 
 432                 m
->m_len 
-= ETHER_VLAN_ENCAP_LEN
; 
 433                 m
->m_data 
+= ETHER_VLAN_ENCAP_LEN
; 
 434                 m
->m_pkthdr
.len 
-= ETHER_VLAN_ENCAP_LEN
; 
 435                 m
->m_pkthdr
.csum_flags 
= 0; /* can't trust hardware checksum */ 
 438         data 
= mtod(m
, u_int8_t
*); 
 441         * Determine the packet's protocol type and stuff the protocol into 
 442         * longs for quick compares. 
 445         if (ntohs(ether_type
) <= 1500) { 
 446                 extProto1 
= *(u_int32_t
*)data
; 
 449                 if ((extProto1 
& htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) { 
 451                         type 
= DLIL_DESC_SNAP
; 
 452                         extProto2 
= *(u_int32_t
*)(data 
+ sizeof(u_int32_t
)); 
 453                         extProto1 
&= htonl(0x000000FF); 
 455                         type 
= DLIL_DESC_SAP
; 
 456                         extProto1 
&= htonl(0xFFFFFF00); 
 459                 type 
= DLIL_DESC_ETYPE2
; 
 463         * Search through the connected protocols for a match.  
 467                 case DLIL_DESC_ETYPE2
: 
 468                         for (i 
= 0; i 
< maxd
; i
++) { 
 469                                 if ((ed
[i
].type 
== type
) && (ed
[i
].data
[0] == ether_type
)) { 
 470                                         *protocol_family 
= ed
[i
].protocol_family
; 
 477                         for (i 
= 0; i 
< maxd
; i
++) { 
 478                                 if ((ed
[i
].type 
== type
) && (ed
[i
].data
[0] == extProto1
)) { 
 479                                         *protocol_family 
= ed
[i
].protocol_family
; 
 486                         for (i 
= 0; i 
< maxd
; i
++) { 
 487                                 if ((ed
[i
].type 
== type
) && (ed
[i
].data
[0] == extProto1
) && 
 488                                         (ed
[i
].data
[1] == extProto2
)) { 
 489                                         *protocol_family 
= ed
[i
].protocol_family
; 
 500  * Ethernet output routine. 
 501  * Encapsulate a packet of type family for the local net. 
 502  * Use trailer local net encapsulation if enough data in first 
 503  * packet leaves a multiple of 512 bytes of data in remainder. 
 509         const struct sockaddr   
*ndest
, 
 511         const char                              *ether_type
) 
 513         struct ether_header 
*eh
; 
 514         int hlen
;       /* link layer header length */ 
 516         hlen 
= ETHER_HDR_LEN
; 
 519          * If a simplex interface, and the packet is being sent to our 
 520          * Ethernet address or a broadcast address, loopback a copy. 
 521          * XXX To make a simplex device behave exactly like a duplex 
 522          * device, we should copy in the case of sending to our own 
 523          * ethernet address (thus letting the original actually appear 
 524          * on the wire). However, we don't do that here for security 
 525          * reasons and compatibility with the original behavior. 
 527         if ((ifp
->if_flags 
& IFF_SIMPLEX
) && 
 528             ((*m
)->m_flags 
& M_LOOP
)) { 
 530             if ((*m
)->m_flags 
& M_BCAST
) { 
 531                 struct mbuf 
*n 
= m_copy(*m
, 0, (int)M_COPYALL
); 
 533                     dlil_output(lo_ifp
, ndest
->sa_family
, n
, NULL
, ndest
, 0); 
 536                                         if (_ether_cmp(edst
, ifnet_lladdr(ifp
)) == 0) { 
 537                     dlil_output(lo_ifp
, ndest
->sa_family
, *m
, NULL
, ndest
, 0); 
 545          * Add local net header.  If no space in first mbuf, 
 548         M_PREPEND(*m
, sizeof (struct ether_header
), M_DONTWAIT
); 
 550             return (EJUSTRETURN
); 
 554         eh 
= mtod(*m
, struct ether_header 
*); 
 555         (void)memcpy(&eh
->ether_type
, ether_type
, 
 556                 sizeof(eh
->ether_type
)); 
 557         (void)memcpy(eh
->ether_dhost
, edst
, ETHER_ADDR_LEN
); 
 558         ifnet_lladdr_copy_bytes(ifp
, eh
->ether_shost
, ETHER_ADDR_LEN
); 
 565         __unused ifnet_t                ifp
, 
 566         const struct sockaddr   
*proto_addr
) 
 568         errno_t result 
= EAFNOSUPPORT
; 
 569         const u_char 
*e_addr
; 
 572          * AF_SPEC and AF_LINK don't require translation. We do 
 573          * want to verify that they specify a valid multicast. 
 575         switch(proto_addr
->sa_family
) { 
 577                         e_addr 
= (const u_char
*)&proto_addr
->sa_data
[0]; 
 578                         if ((e_addr
[0] & 0x01) != 0x01) 
 579                                 result 
= EADDRNOTAVAIL
; 
 585                         e_addr 
= CONST_LLADDR((const struct sockaddr_dl
*)proto_addr
);  
 586                         if ((e_addr
[0] & 0x01) != 0x01) 
 587                                 result 
= EADDRNOTAVAIL
; 
 598     __unused ifnet_t    ifp
, 
 599     __unused u_int32_t  command
, 
 605 __private_extern__ 
int ether_family_init(void) 
 609         /* Register protocol registration functions */ 
 610         if ((error 
= proto_register_plumber(PF_INET
, APPLE_IF_FAM_ETHERNET
, 
 611                                                                           ether_attach_inet
, ether_detach_inet
)) != 0) { 
 612                 printf("proto_register_plumber failed for PF_INET error=%d\n", error
); 
 616         if ((error 
= proto_register_plumber(PF_INET6
, APPLE_IF_FAM_ETHERNET
, 
 617                                                                           ether_attach_inet6
, ether_detach_inet6
)) != 0) { 
 618                 printf("proto_register_plumber failed for PF_INET6 error=%d\n", error
); 
 623         if ((error 
= proto_register_plumber(PF_APPLETALK
, APPLE_IF_FAM_ETHERNET
, 
 624                                                                           ether_attach_at
, ether_detach_at
)) != 0) { 
 625                 printf("proto_register_plumber failed PF_APPLETALK error=%d\n", error
); 
 637 #endif /* IF_BRIDGE */