2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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. 
  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 
  20  * @APPLE_LICENSE_HEADER_END@ 
  23  * Copyright (c) 1982, 1989, 1993 
  24  *      The Regents of the University of California.  All rights reserved. 
  26  * Redistribution and use in source and binary forms, with or without 
  27  * modification, are permitted provided that the following conditions 
  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. 
  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 
  58 #include <sys/param.h> 
  59 #include <sys/systm.h> 
  60 #include <sys/kernel.h> 
  61 #include <sys/malloc.h> 
  63 #include <sys/socket.h> 
  64 #include <sys/sockio.h> 
  65 #include <sys/sysctl.h> 
  68 #include <net/netisr.h> 
  69 #include <net/route.h> 
  70 #include <net/if_llc.h> 
  71 #include <net/if_dl.h> 
  72 #include <net/if_types.h> 
  75 #include <netinet/in.h> 
  76 #include <netinet/in_var.h> 
  77 #include <netinet/if_ether.h> 
  78 #include <netinet/in_systm.h> 
  79 #include <netinet/ip.h> 
  82 #include <netinet6/nd6.h> 
  83 #include <netinet6/in6_ifattach.h> 
  88 #include <sys/socketvar.h> 
  89 #include <net/if_blue.h> 
  95 extern struct ifqueue pkintrq
; 
 100 #include <net/bridge.h> 
 103 /* #include "vlan.h" */ 
 105 #include <net/if_vlan_var.h> 
 106 #endif /* NVLAN > 0 */ 
 109 extern struct ifnet_blue 
*blue_if
; 
 110 extern struct mbuf 
*splitter_input(struct mbuf 
*, struct ifnet 
*); 
 112 static u_long lo_dlt 
= 0; 
 113 static ivedonethis 
= 0; 
 114 static u_char   etherbroadcastaddr
[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 116 #define IFP2AC(IFP) ((struct arpcom *)IFP) 
 122  * Process a received Ethernet packet; 
 123  * the packet is in the mbuf chain m without 
 124  * the ether header, which is provided separately. 
 127 inet6_ether_input(m
, frame_header
, ifp
, dl_tag
, sync_ok
) 
 135     register struct ether_header 
*eh 
= (struct ether_header 
*) frame_header
; 
 136     register struct ifqueue 
*inq
=0; 
 139     u_int16_t ptype 
= -1; 
 140     unsigned char buf
[18]; 
 144     if ((ifp
->if_flags 
& IFF_UP
) == 0) { 
 149     ifp
->if_lastchange 
= time
; 
 151     if (eh
->ether_dhost
[0] & 1) { 
 152         if (bcmp((caddr_t
)etherbroadcastaddr
, (caddr_t
)eh
->ether_dhost
, 
 153                  sizeof(etherbroadcastaddr
)) == 0) 
 154             m
->m_flags 
|= M_BCAST
; 
 156             m
->m_flags 
|= M_MCAST
; 
 158     if (m
->m_flags 
& (M_BCAST
|M_MCAST
)) 
 161     ether_type 
= ntohs(eh
->ether_type
); 
 164     switch (ether_type
) { 
 167         schednetisr(NETISR_IPV6
); 
 197 inet6_ether_pre_output(ifp
, m0
, dst_netaddr
, route
, type
, edst
, dl_tag 
) 
 200     struct sockaddr 
*dst_netaddr
; 
 206     struct rtentry  
*rt0 
= (struct rtentry 
*) route
; 
 208     register struct mbuf 
*m 
= *m0
; 
 209     register struct rtentry 
*rt
; 
 210     register struct ether_header 
*eh
; 
 211     int off
, len 
= m
->m_pkthdr
.len
; 
 212     int hlen
;   /* link layer header lenght */ 
 213     struct arpcom 
*ac 
= IFP2AC(ifp
); 
 217     if ((ifp
->if_flags 
& (IFF_UP
|IFF_RUNNING
)) != (IFF_UP
|IFF_RUNNING
))  
 222         if ((rt
->rt_flags 
& RTF_UP
) == 0) { 
 223             rt0 
= rt 
= rtalloc1(dst_netaddr
, 1, 0UL); 
 230         if (rt
->rt_flags 
& RTF_GATEWAY
) { 
 231             if (rt
->rt_gwroute 
== 0) 
 233             if (((rt 
= rt
->rt_gwroute
)->rt_flags 
& RTF_UP
) == 0) { 
 234                 rtfree(rt
); rt 
= rt0
; 
 235             lookup
: rt
->rt_gwroute 
= rtalloc1(rt
->rt_gateway
, 1, 
 237                 if ((rt 
= rt
->rt_gwroute
) == 0) 
 238                     return (EHOSTUNREACH
); 
 243         if (rt
->rt_flags 
& RTF_REJECT
) 
 244             if (rt
->rt_rmx
.rmx_expire 
== 0 || 
 245                 time_second 
< rt
->rt_rmx
.rmx_expire
) 
 246                 return (rt 
== rt0 
? EHOSTDOWN 
: EHOSTUNREACH
); 
 249     hlen 
= ETHER_HDR_LEN
; 
 252      * Tell ether_frameout it's ok to loop packet unless negated below. 
 254     m
->m_flags 
|= M_LOOP
; 
 256     switch (dst_netaddr
->sa_family
) { 
 260         if (!nd6_storelladdr(&ac
->ac_if
, rt
, m
, dst_netaddr
, (u_char 
*)edst
)) { 
 261              /* this must be impossible, so we bark */ 
 262              printf("nd6_storelladdr failed\n"); 
 265        off 
= m
->m_pkthdr
.len 
- m
->m_len
; 
 266        *(u_short 
*)type 
= htons(ETHERTYPE_IPV6
); 
 270         printf("%s%d: can't handle af%d\n", ifp
->if_name
, ifp
->if_unit
, 
 271                dst_netaddr
->sa_family
); 
 281 ether_inet6_prmod_ioctl(dl_tag
, ifp
, command
, data
) 
 287     struct ifaddr 
*ifa 
= (struct ifaddr 
*) data
; 
 288     struct ifreq 
*ifr 
= (struct ifreq 
*) data
; 
 289     struct rslvmulti_req 
*rsreq 
= (struct rslvmulti_req 
*) data
; 
 291     boolean_t funnel_state
; 
 292     struct arpcom 
*ac 
= (struct arpcom 
*) ifp
; 
 293     struct sockaddr_dl 
*sdl
; 
 294     struct sockaddr_in 
*sin
; 
 295     struct sockaddr_in6 
*sin6
; 
 300     funnel_state 
= thread_funnel_set(TRUE
); 
 303     case SIOCRSLVMULTI
: { 
 304         switch(rsreq
->sa
->sa_family
) { 
 307                 sin6 
= (struct sockaddr_in6 
*)rsreq
->sa
; 
 308                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6
->sin6_addr
)) { 
 310                          * An IP6 address of 0 means listen to all 
 311                          * of the Ethernet multicast address used for IP6. 
 312                          * (This is used for multicast routers.) 
 314                         ifp
->if_flags 
|= IFF_ALLMULTI
; 
 318                 MALLOC(sdl
, struct sockaddr_dl 
*, sizeof *sdl
, M_IFMADDR
, 
 320                 sdl
->sdl_len 
= sizeof *sdl
; 
 321                 sdl
->sdl_family 
= AF_LINK
; 
 322                 sdl
->sdl_index 
= ifp
->if_index
; 
 323                 sdl
->sdl_type 
= IFT_ETHER
; 
 325                 sdl
->sdl_alen 
= ETHER_ADDR_LEN
; 
 327                 e_addr 
= LLADDR(sdl
); 
 328                 ETHER_MAP_IPV6_MULTICAST(&sin6
->sin6_addr
, e_addr
); 
 329                 printf("ether_resolvemulti AF_INET6 Adding %x:%x:%x:%x:%x:%x\n", 
 330                                 e_addr
[0], e_addr
[1], e_addr
[2], e_addr
[3], e_addr
[4], e_addr
[5]); 
 331                 *rsreq
->llsa 
= (struct sockaddr 
*)sdl
; 
 336                  * Well, the text isn't quite right, but it's the name 
 344          if ((ifp
->if_flags 
& IFF_RUNNING
) == 0) { 
 345               ifp
->if_flags 
|= IFF_UP
; 
 346               dlil_ioctl(0, ifp
, SIOCSIFFLAGS
, (caddr_t
) 0); 
 355         sa 
= (struct sockaddr 
*) & ifr
->ifr_data
; 
 356         bcopy(IFP2AC(ifp
)->ac_enaddr
, 
 357               (caddr_t
) sa
->sa_data
, ETHER_ADDR_LEN
); 
 363          * Set the interface MTU. 
 365         if (ifr
->ifr_mtu 
> ETHERMTU
) { 
 368             ifp
->if_mtu 
= ifr
->ifr_mtu
; 
 376     (void) thread_funnel_set(funnel_state
); 
 385 u_long  
ether_attach_inet6(struct ifnet 
*ifp
) 
 387     struct dlil_proto_reg_str   reg
; 
 388     struct dlil_demux_desc      desc
; 
 390     u_short en_6native
=ETHERTYPE_IPV6
; 
 395     stat 
= dlil_find_dltag(ifp
->if_family
, ifp
->if_unit
, PF_INET6
, &ip_dl_tag
); 
 399     TAILQ_INIT(®
.demux_desc_head
); 
 400     desc
.type 
= DLIL_DESC_RAW
; 
 401     desc
.variants
.bitmask
.proto_id_length 
= 0; 
 402     desc
.variants
.bitmask
.proto_id 
= 0; 
 403     desc
.variants
.bitmask
.proto_id_mask 
= 0; 
 404     desc
.native_type 
= (char *) &en_6native
; 
 405     TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
); 
 406     reg
.interface_family 
= ifp
->if_family
; 
 407     reg
.unit_number      
= ifp
->if_unit
; 
 408     reg
.input            
= inet6_ether_input
; 
 409     reg
.pre_output       
= inet6_ether_pre_output
; 
 412     reg
.ioctl            
= ether_inet6_prmod_ioctl
; 
 413     reg
.default_proto    
= 1; 
 414     reg
.protocol_family  
= PF_INET6
; 
 416     stat 
= dlil_attach_protocol(®
, &ip_dl_tag
); 
 418         printf("WARNING: ether_attach_inet6 can't attach ip to interface\n");