Home | History | Annotate | Line # | Download | only in net
if_ethersubr.c revision 1.152.2.2
      1  1.152.2.2  dyoung /*	$NetBSD: if_ethersubr.c,v 1.152.2.2 2007/08/07 04:37:45 dyoung Exp $	*/
      2  1.152.2.2  dyoung 
      3  1.152.2.2  dyoung /*
      4  1.152.2.2  dyoung  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      5  1.152.2.2  dyoung  * All rights reserved.
      6  1.152.2.2  dyoung  *
      7  1.152.2.2  dyoung  * Redistribution and use in source and binary forms, with or without
      8  1.152.2.2  dyoung  * modification, are permitted provided that the following conditions
      9  1.152.2.2  dyoung  * are met:
     10  1.152.2.2  dyoung  * 1. Redistributions of source code must retain the above copyright
     11  1.152.2.2  dyoung  *    notice, this list of conditions and the following disclaimer.
     12  1.152.2.2  dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.152.2.2  dyoung  *    notice, this list of conditions and the following disclaimer in the
     14  1.152.2.2  dyoung  *    documentation and/or other materials provided with the distribution.
     15  1.152.2.2  dyoung  * 3. Neither the name of the project nor the names of its contributors
     16  1.152.2.2  dyoung  *    may be used to endorse or promote products derived from this software
     17  1.152.2.2  dyoung  *    without specific prior written permission.
     18  1.152.2.2  dyoung  *
     19  1.152.2.2  dyoung  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     20  1.152.2.2  dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  1.152.2.2  dyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  1.152.2.2  dyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     23  1.152.2.2  dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  1.152.2.2  dyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  1.152.2.2  dyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  1.152.2.2  dyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  1.152.2.2  dyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  1.152.2.2  dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  1.152.2.2  dyoung  * SUCH DAMAGE.
     30  1.152.2.2  dyoung  */
     31  1.152.2.2  dyoung 
     32  1.152.2.2  dyoung /*
     33  1.152.2.2  dyoung  * Copyright (c) 1982, 1989, 1993
     34  1.152.2.2  dyoung  *	The Regents of the University of California.  All rights reserved.
     35  1.152.2.2  dyoung  *
     36  1.152.2.2  dyoung  * Redistribution and use in source and binary forms, with or without
     37  1.152.2.2  dyoung  * modification, are permitted provided that the following conditions
     38  1.152.2.2  dyoung  * are met:
     39  1.152.2.2  dyoung  * 1. Redistributions of source code must retain the above copyright
     40  1.152.2.2  dyoung  *    notice, this list of conditions and the following disclaimer.
     41  1.152.2.2  dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     42  1.152.2.2  dyoung  *    notice, this list of conditions and the following disclaimer in the
     43  1.152.2.2  dyoung  *    documentation and/or other materials provided with the distribution.
     44  1.152.2.2  dyoung  * 3. Neither the name of the University nor the names of its contributors
     45  1.152.2.2  dyoung  *    may be used to endorse or promote products derived from this software
     46  1.152.2.2  dyoung  *    without specific prior written permission.
     47  1.152.2.2  dyoung  *
     48  1.152.2.2  dyoung  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     49  1.152.2.2  dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     50  1.152.2.2  dyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     51  1.152.2.2  dyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     52  1.152.2.2  dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     53  1.152.2.2  dyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     54  1.152.2.2  dyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     55  1.152.2.2  dyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     56  1.152.2.2  dyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     57  1.152.2.2  dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     58  1.152.2.2  dyoung  * SUCH DAMAGE.
     59  1.152.2.2  dyoung  *
     60  1.152.2.2  dyoung  *	@(#)if_ethersubr.c	8.2 (Berkeley) 4/4/96
     61  1.152.2.2  dyoung  */
     62  1.152.2.2  dyoung 
     63  1.152.2.2  dyoung #include <sys/cdefs.h>
     64  1.152.2.2  dyoung __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.152.2.2 2007/08/07 04:37:45 dyoung Exp $");
     65  1.152.2.2  dyoung 
     66  1.152.2.2  dyoung #include "opt_inet.h"
     67  1.152.2.2  dyoung #include "opt_atalk.h"
     68  1.152.2.2  dyoung #include "opt_iso.h"
     69  1.152.2.2  dyoung #include "opt_ipx.h"
     70  1.152.2.2  dyoung #include "opt_mbuftrace.h"
     71  1.152.2.2  dyoung #include "opt_gateway.h"
     72  1.152.2.2  dyoung #include "opt_pfil_hooks.h"
     73  1.152.2.2  dyoung #include "opt_pppoe.h"
     74  1.152.2.2  dyoung #include "vlan.h"
     75  1.152.2.2  dyoung #include "pppoe.h"
     76  1.152.2.2  dyoung #include "bridge.h"
     77  1.152.2.2  dyoung #include "bpfilter.h"
     78  1.152.2.2  dyoung #include "arp.h"
     79  1.152.2.2  dyoung #include "agr.h"
     80  1.152.2.2  dyoung 
     81  1.152.2.2  dyoung #include <sys/param.h>
     82  1.152.2.2  dyoung #include <sys/systm.h>
     83  1.152.2.2  dyoung #include <sys/kernel.h>
     84  1.152.2.2  dyoung #include <sys/callout.h>
     85  1.152.2.2  dyoung #include <sys/malloc.h>
     86  1.152.2.2  dyoung #include <sys/mbuf.h>
     87  1.152.2.2  dyoung #include <sys/protosw.h>
     88  1.152.2.2  dyoung #include <sys/socket.h>
     89  1.152.2.2  dyoung #include <sys/ioctl.h>
     90  1.152.2.2  dyoung #include <sys/errno.h>
     91  1.152.2.2  dyoung #include <sys/syslog.h>
     92  1.152.2.2  dyoung #include <sys/kauth.h>
     93  1.152.2.2  dyoung 
     94  1.152.2.2  dyoung #include <machine/cpu.h>
     95  1.152.2.2  dyoung 
     96  1.152.2.2  dyoung #include <net/if.h>
     97  1.152.2.2  dyoung #include <net/netisr.h>
     98  1.152.2.2  dyoung #include <net/route.h>
     99  1.152.2.2  dyoung #include <net/if_llc.h>
    100  1.152.2.2  dyoung #include <net/if_dl.h>
    101  1.152.2.2  dyoung #include <net/if_types.h>
    102  1.152.2.2  dyoung 
    103  1.152.2.2  dyoung #if NARP == 0
    104  1.152.2.2  dyoung /*
    105  1.152.2.2  dyoung  * XXX there should really be a way to issue this warning from within config(8)
    106  1.152.2.2  dyoung  */
    107  1.152.2.2  dyoung #error You have included NETATALK or a pseudo-device in your configuration that depends on the presence of ethernet interfaces, but have no such interfaces configured. Check if you really need pseudo-device bridge, pppoe, vlan or options NETATALK.
    108  1.152.2.2  dyoung #endif
    109  1.152.2.2  dyoung 
    110  1.152.2.2  dyoung #if NBPFILTER > 0
    111  1.152.2.2  dyoung #include <net/bpf.h>
    112  1.152.2.2  dyoung #endif
    113  1.152.2.2  dyoung 
    114  1.152.2.2  dyoung #include <net/if_ether.h>
    115  1.152.2.2  dyoung #if NVLAN > 0
    116  1.152.2.2  dyoung #include <net/if_vlanvar.h>
    117  1.152.2.2  dyoung #endif
    118  1.152.2.2  dyoung 
    119  1.152.2.2  dyoung #if NPPPOE > 0
    120  1.152.2.2  dyoung #include <net/if_pppoe.h>
    121  1.152.2.2  dyoung #endif
    122  1.152.2.2  dyoung 
    123  1.152.2.2  dyoung #if NAGR > 0
    124  1.152.2.2  dyoung #include <net/agr/ieee8023_slowprotocols.h>	/* XXX */
    125  1.152.2.2  dyoung #include <net/agr/ieee8023ad.h>
    126  1.152.2.2  dyoung #include <net/agr/if_agrvar.h>
    127  1.152.2.2  dyoung #endif
    128  1.152.2.2  dyoung 
    129  1.152.2.2  dyoung #if NBRIDGE > 0
    130  1.152.2.2  dyoung #include <net/if_bridgevar.h>
    131  1.152.2.2  dyoung #endif
    132  1.152.2.2  dyoung 
    133  1.152.2.2  dyoung #include <netinet/in.h>
    134  1.152.2.2  dyoung #ifdef INET
    135  1.152.2.2  dyoung #include <netinet/in_var.h>
    136  1.152.2.2  dyoung #endif
    137  1.152.2.2  dyoung #include <netinet/if_inarp.h>
    138  1.152.2.2  dyoung 
    139  1.152.2.2  dyoung #ifdef INET6
    140  1.152.2.2  dyoung #ifndef INET
    141  1.152.2.2  dyoung #include <netinet/in.h>
    142  1.152.2.2  dyoung #endif
    143  1.152.2.2  dyoung #include <netinet6/in6_var.h>
    144  1.152.2.2  dyoung #include <netinet6/nd6.h>
    145  1.152.2.2  dyoung #endif
    146  1.152.2.2  dyoung 
    147  1.152.2.2  dyoung 
    148  1.152.2.2  dyoung #include "carp.h"
    149  1.152.2.2  dyoung #if NCARP > 0
    150  1.152.2.2  dyoung #include <netinet/ip_carp.h>
    151  1.152.2.2  dyoung #endif
    152  1.152.2.2  dyoung 
    153  1.152.2.2  dyoung #ifdef IPX
    154  1.152.2.2  dyoung #include <netipx/ipx.h>
    155  1.152.2.2  dyoung #include <netipx/ipx_if.h>
    156  1.152.2.2  dyoung #endif
    157  1.152.2.2  dyoung 
    158  1.152.2.2  dyoung #ifdef ISO
    159  1.152.2.2  dyoung #include <netiso/argo_debug.h>
    160  1.152.2.2  dyoung #include <netiso/iso.h>
    161  1.152.2.2  dyoung #include <netiso/iso_var.h>
    162  1.152.2.2  dyoung #include <netiso/iso_snpac.h>
    163  1.152.2.2  dyoung #endif
    164  1.152.2.2  dyoung 
    165  1.152.2.2  dyoung 
    166  1.152.2.2  dyoung 
    167  1.152.2.2  dyoung #ifdef NETATALK
    168  1.152.2.2  dyoung #include <netatalk/at.h>
    169  1.152.2.2  dyoung #include <netatalk/at_var.h>
    170  1.152.2.2  dyoung #include <netatalk/at_extern.h>
    171  1.152.2.2  dyoung 
    172  1.152.2.2  dyoung #define llc_snap_org_code llc_un.type_snap.org_code
    173  1.152.2.2  dyoung #define llc_snap_ether_type llc_un.type_snap.ether_type
    174  1.152.2.2  dyoung 
    175  1.152.2.2  dyoung extern u_char	at_org_code[3];
    176  1.152.2.2  dyoung extern u_char	aarp_org_code[3];
    177  1.152.2.2  dyoung #endif /* NETATALK */
    178  1.152.2.2  dyoung 
    179  1.152.2.2  dyoung static struct timeval bigpktppslim_last;
    180  1.152.2.2  dyoung static int bigpktppslim = 2;	/* XXX */
    181  1.152.2.2  dyoung static int bigpktpps_count;
    182  1.152.2.2  dyoung 
    183  1.152.2.2  dyoung 
    184  1.152.2.2  dyoung const uint8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
    185  1.152.2.2  dyoung     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    186  1.152.2.2  dyoung const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN] =
    187  1.152.2.2  dyoung     { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02 };
    188  1.152.2.2  dyoung #define senderr(e) { error = (e); goto bad;}
    189  1.152.2.2  dyoung 
    190  1.152.2.2  dyoung static	int ether_output(struct ifnet *, struct mbuf *,
    191  1.152.2.2  dyoung 	    const struct sockaddr *, struct rtentry *);
    192  1.152.2.2  dyoung 
    193  1.152.2.2  dyoung /*
    194  1.152.2.2  dyoung  * Ethernet output routine.
    195  1.152.2.2  dyoung  * Encapsulate a packet of type family for the local net.
    196  1.152.2.2  dyoung  * Assumes that ifp is actually pointer to ethercom structure.
    197  1.152.2.2  dyoung  */
    198  1.152.2.2  dyoung static int
    199  1.152.2.2  dyoung ether_output(struct ifnet *ifp0, struct mbuf *m0, const struct sockaddr *dst,
    200  1.152.2.2  dyoung 	struct rtentry *rt0)
    201  1.152.2.2  dyoung {
    202  1.152.2.2  dyoung 	u_int16_t etype = 0;
    203  1.152.2.2  dyoung 	int error = 0, hdrcmplt = 0;
    204  1.152.2.2  dyoung  	uint8_t esrc[6], edst[6];
    205  1.152.2.2  dyoung 	struct mbuf *m = m0;
    206  1.152.2.2  dyoung 	struct rtentry *rt;
    207  1.152.2.2  dyoung 	struct mbuf *mcopy = NULL;
    208  1.152.2.2  dyoung 	struct ether_header *eh;
    209  1.152.2.2  dyoung 	struct ifnet *ifp = ifp0;
    210  1.152.2.2  dyoung 	ALTQ_DECL(struct altq_pktattr pktattr;)
    211  1.152.2.2  dyoung #ifdef INET
    212  1.152.2.2  dyoung 	struct arphdr *ah;
    213  1.152.2.2  dyoung #endif /* INET */
    214  1.152.2.2  dyoung #ifdef NETATALK
    215  1.152.2.2  dyoung 	struct at_ifaddr *aa;
    216  1.152.2.2  dyoung #endif /* NETATALK */
    217  1.152.2.2  dyoung 
    218  1.152.2.2  dyoung #ifdef MBUFTRACE
    219  1.152.2.2  dyoung 	m_claimm(m, ifp->if_mowner);
    220  1.152.2.2  dyoung #endif
    221  1.152.2.2  dyoung 
    222  1.152.2.2  dyoung #if NCARP > 0
    223  1.152.2.2  dyoung 	if (ifp->if_type == IFT_CARP) {
    224  1.152.2.2  dyoung 		struct ifaddr *ifa;
    225  1.152.2.2  dyoung 
    226  1.152.2.2  dyoung 		/* loop back if this is going to the carp interface */
    227  1.152.2.2  dyoung 		if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
    228  1.152.2.2  dyoung 		    (ifa = ifa_ifwithaddr(dst)) != NULL &&
    229  1.152.2.2  dyoung 		    ifa->ifa_ifp == ifp0)
    230  1.152.2.2  dyoung 			return looutput(ifp0, m, dst, rt0);
    231  1.152.2.2  dyoung 
    232  1.152.2.2  dyoung 		ifp = ifp->if_carpdev;
    233  1.152.2.2  dyoung 		/* ac = (struct arpcom *)ifp; */
    234  1.152.2.2  dyoung 
    235  1.152.2.2  dyoung 		if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
    236  1.152.2.2  dyoung 		    (IFF_UP|IFF_RUNNING))
    237  1.152.2.2  dyoung 			senderr(ENETDOWN);
    238  1.152.2.2  dyoung 	}
    239  1.152.2.2  dyoung #endif /* NCARP > 0 */
    240  1.152.2.2  dyoung 
    241  1.152.2.2  dyoung 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
    242  1.152.2.2  dyoung 		senderr(ENETDOWN);
    243  1.152.2.2  dyoung 	if ((rt = rt0) != NULL) {
    244  1.152.2.2  dyoung 		if ((rt->rt_flags & RTF_UP) == 0) {
    245  1.152.2.2  dyoung 			if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
    246  1.152.2.2  dyoung 				rt->rt_refcnt--;
    247  1.152.2.2  dyoung 				if (rt->rt_ifp != ifp)
    248  1.152.2.2  dyoung 					return (*rt->rt_ifp->if_output)
    249  1.152.2.2  dyoung 							(ifp, m0, dst, rt);
    250  1.152.2.2  dyoung 			} else
    251  1.152.2.2  dyoung 				senderr(EHOSTUNREACH);
    252  1.152.2.2  dyoung 		}
    253  1.152.2.2  dyoung 		if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) {
    254  1.152.2.2  dyoung 			if (rt->rt_gwroute == 0)
    255  1.152.2.2  dyoung 				goto lookup;
    256  1.152.2.2  dyoung 			if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
    257  1.152.2.2  dyoung 				rtfree(rt); rt = rt0;
    258  1.152.2.2  dyoung 			lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
    259  1.152.2.2  dyoung 				if ((rt = rt->rt_gwroute) == 0)
    260  1.152.2.2  dyoung 					senderr(EHOSTUNREACH);
    261  1.152.2.2  dyoung 				/* the "G" test below also prevents rt == rt0 */
    262  1.152.2.2  dyoung 				if ((rt->rt_flags & RTF_GATEWAY) ||
    263  1.152.2.2  dyoung 				    (rt->rt_ifp != ifp)) {
    264  1.152.2.2  dyoung 					rt->rt_refcnt--;
    265  1.152.2.2  dyoung 					rt0->rt_gwroute = 0;
    266  1.152.2.2  dyoung 					senderr(EHOSTUNREACH);
    267  1.152.2.2  dyoung 				}
    268  1.152.2.2  dyoung 			}
    269  1.152.2.2  dyoung 		}
    270  1.152.2.2  dyoung 		if (rt->rt_flags & RTF_REJECT)
    271  1.152.2.2  dyoung 			if (rt->rt_rmx.rmx_expire == 0 ||
    272  1.152.2.2  dyoung 			    (u_long) time_second < rt->rt_rmx.rmx_expire)
    273  1.152.2.2  dyoung 				senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
    274  1.152.2.2  dyoung 	}
    275  1.152.2.2  dyoung 
    276  1.152.2.2  dyoung 	switch (dst->sa_family) {
    277  1.152.2.2  dyoung 
    278  1.152.2.2  dyoung #ifdef INET
    279  1.152.2.2  dyoung 	case AF_INET:
    280  1.152.2.2  dyoung 		if (m->m_flags & M_BCAST)
    281  1.152.2.2  dyoung                 	(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
    282  1.152.2.2  dyoung 		else if (m->m_flags & M_MCAST)
    283  1.152.2.2  dyoung 			ETHER_MAP_IP_MULTICAST(&satocsin(dst)->sin_addr, edst);
    284  1.152.2.2  dyoung 		else if (!arpresolve(ifp, rt, m, dst, edst))
    285  1.152.2.2  dyoung 			return (0);	/* if not yet resolved */
    286  1.152.2.2  dyoung 		/* If broadcasting on a simplex interface, loopback a copy */
    287  1.152.2.2  dyoung 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
    288  1.152.2.2  dyoung 			mcopy = m_copy(m, 0, (int)M_COPYALL);
    289  1.152.2.2  dyoung 		etype = htons(ETHERTYPE_IP);
    290  1.152.2.2  dyoung 		break;
    291  1.152.2.2  dyoung 
    292  1.152.2.2  dyoung 	case AF_ARP:
    293  1.152.2.2  dyoung 		ah = mtod(m, struct arphdr *);
    294  1.152.2.2  dyoung 		if (m->m_flags & M_BCAST)
    295  1.152.2.2  dyoung                 	(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
    296  1.152.2.2  dyoung 		else {
    297  1.152.2.2  dyoung 			void *tha = ar_tha(ah);
    298  1.152.2.2  dyoung 
    299  1.152.2.2  dyoung 			KASSERT(tha);
    300  1.152.2.2  dyoung 			memcpy(edst, tha, sizeof(edst));
    301  1.152.2.2  dyoung 		}
    302  1.152.2.2  dyoung 
    303  1.152.2.2  dyoung 		ah->ar_hrd = htons(ARPHRD_ETHER);
    304  1.152.2.2  dyoung 
    305  1.152.2.2  dyoung 		switch (ntohs(ah->ar_op)) {
    306  1.152.2.2  dyoung 		case ARPOP_REVREQUEST:
    307  1.152.2.2  dyoung 		case ARPOP_REVREPLY:
    308  1.152.2.2  dyoung 			etype = htons(ETHERTYPE_REVARP);
    309  1.152.2.2  dyoung 			break;
    310  1.152.2.2  dyoung 
    311  1.152.2.2  dyoung 		case ARPOP_REQUEST:
    312  1.152.2.2  dyoung 		case ARPOP_REPLY:
    313  1.152.2.2  dyoung 		default:
    314  1.152.2.2  dyoung 			etype = htons(ETHERTYPE_ARP);
    315  1.152.2.2  dyoung 		}
    316  1.152.2.2  dyoung 
    317  1.152.2.2  dyoung 		break;
    318  1.152.2.2  dyoung #endif
    319  1.152.2.2  dyoung #ifdef INET6
    320  1.152.2.2  dyoung 	case AF_INET6:
    321  1.152.2.2  dyoung 		if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst, sizeof(edst))){
    322  1.152.2.2  dyoung 			/* something bad happened */
    323  1.152.2.2  dyoung 			return (0);
    324  1.152.2.2  dyoung 		}
    325  1.152.2.2  dyoung 		etype = htons(ETHERTYPE_IPV6);
    326  1.152.2.2  dyoung 		break;
    327  1.152.2.2  dyoung #endif
    328  1.152.2.2  dyoung #ifdef NETATALK
    329  1.152.2.2  dyoung     case AF_APPLETALK:
    330  1.152.2.2  dyoung 		if (!aarpresolve(ifp, m, (const struct sockaddr_at *)dst, edst)) {
    331  1.152.2.2  dyoung #ifdef NETATALKDEBUG
    332  1.152.2.2  dyoung 			printf("aarpresolv failed\n");
    333  1.152.2.2  dyoung #endif /* NETATALKDEBUG */
    334  1.152.2.2  dyoung 			return (0);
    335  1.152.2.2  dyoung 		}
    336  1.152.2.2  dyoung 		/*
    337  1.152.2.2  dyoung 		 * ifaddr is the first thing in at_ifaddr
    338  1.152.2.2  dyoung 		 */
    339  1.152.2.2  dyoung 		aa = (struct at_ifaddr *) at_ifawithnet(
    340  1.152.2.2  dyoung 		    (const struct sockaddr_at *)dst, ifp);
    341  1.152.2.2  dyoung 		if (aa == NULL)
    342  1.152.2.2  dyoung 		    goto bad;
    343  1.152.2.2  dyoung 
    344  1.152.2.2  dyoung 		/*
    345  1.152.2.2  dyoung 		 * In the phase 2 case, we need to prepend an mbuf for the
    346  1.152.2.2  dyoung 		 * llc header.  Since we must preserve the value of m,
    347  1.152.2.2  dyoung 		 * which is passed to us by value, we m_copy() the first
    348  1.152.2.2  dyoung 		 * mbuf, and use it for our llc header.
    349  1.152.2.2  dyoung 		 */
    350  1.152.2.2  dyoung 		if (aa->aa_flags & AFA_PHASE2) {
    351  1.152.2.2  dyoung 			struct llc llc;
    352  1.152.2.2  dyoung 
    353  1.152.2.2  dyoung 			M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
    354  1.152.2.2  dyoung 			llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
    355  1.152.2.2  dyoung 			llc.llc_control = LLC_UI;
    356  1.152.2.2  dyoung 			memcpy(llc.llc_snap_org_code, at_org_code,
    357  1.152.2.2  dyoung 			    sizeof(llc.llc_snap_org_code));
    358  1.152.2.2  dyoung 			llc.llc_snap_ether_type = htons(ETHERTYPE_ATALK);
    359  1.152.2.2  dyoung 			memcpy(mtod(m, void *), &llc, sizeof(struct llc));
    360  1.152.2.2  dyoung 		} else {
    361  1.152.2.2  dyoung 			etype = htons(ETHERTYPE_ATALK);
    362  1.152.2.2  dyoung 		}
    363  1.152.2.2  dyoung 		break;
    364  1.152.2.2  dyoung #endif /* NETATALK */
    365  1.152.2.2  dyoung #ifdef IPX
    366  1.152.2.2  dyoung 	case AF_IPX:
    367  1.152.2.2  dyoung 		etype = htons(ETHERTYPE_IPX);
    368  1.152.2.2  dyoung  		memcpy(edst,
    369  1.152.2.2  dyoung 		    &(((const struct sockaddr_ipx *)dst)->sipx_addr.x_host),
    370  1.152.2.2  dyoung 		    sizeof(edst));
    371  1.152.2.2  dyoung 		/* If broadcasting on a simplex interface, loopback a copy */
    372  1.152.2.2  dyoung 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
    373  1.152.2.2  dyoung 			mcopy = m_copy(m, 0, (int)M_COPYALL);
    374  1.152.2.2  dyoung 		break;
    375  1.152.2.2  dyoung #endif
    376  1.152.2.2  dyoung #ifdef	ISO
    377  1.152.2.2  dyoung 	case AF_ISO: {
    378  1.152.2.2  dyoung 		int	snpalen;
    379  1.152.2.2  dyoung 		struct	llc *l;
    380  1.152.2.2  dyoung 		const struct sockaddr_dl *sdl;
    381  1.152.2.2  dyoung 
    382  1.152.2.2  dyoung 		if (rt && (sdl = satocsdl(rt->rt_gateway)) &&
    383  1.152.2.2  dyoung 		    sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
    384  1.152.2.2  dyoung 			memcpy(edst, CLLADDR(sdl), sizeof(edst));
    385  1.152.2.2  dyoung 		} else {
    386  1.152.2.2  dyoung 			error = iso_snparesolve(ifp,
    387  1.152.2.2  dyoung 			    (const struct sockaddr_iso *)dst,
    388  1.152.2.2  dyoung 						(char *)edst, &snpalen);
    389  1.152.2.2  dyoung 			if (error)
    390  1.152.2.2  dyoung 				goto bad; /* Not Resolved */
    391  1.152.2.2  dyoung 		}
    392  1.152.2.2  dyoung 		/* If broadcasting on a simplex interface, loopback a copy */
    393  1.152.2.2  dyoung 		if (*edst & 1)
    394  1.152.2.2  dyoung 			m->m_flags |= (M_BCAST|M_MCAST);
    395  1.152.2.2  dyoung 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
    396  1.152.2.2  dyoung 		    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
    397  1.152.2.2  dyoung 			M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
    398  1.152.2.2  dyoung 			if (mcopy) {
    399  1.152.2.2  dyoung 				eh = mtod(mcopy, struct ether_header *);
    400  1.152.2.2  dyoung 				memcpy(eh->ether_dhost, edst, sizeof(edst));
    401  1.152.2.2  dyoung 				memcpy(eh->ether_shost, LLADDR(ifp->if_sadl),
    402  1.152.2.2  dyoung 				    sizeof(edst));
    403  1.152.2.2  dyoung 			}
    404  1.152.2.2  dyoung 		}
    405  1.152.2.2  dyoung 		M_PREPEND(m, 3, M_DONTWAIT);
    406  1.152.2.2  dyoung 		if (m == NULL)
    407  1.152.2.2  dyoung 			return (0);
    408  1.152.2.2  dyoung 		l = mtod(m, struct llc *);
    409  1.152.2.2  dyoung 		l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
    410  1.152.2.2  dyoung 		l->llc_control = LLC_UI;
    411  1.152.2.2  dyoung #ifdef ARGO_DEBUG
    412  1.152.2.2  dyoung 		if (argo_debug[D_ETHER]) {
    413  1.152.2.2  dyoung 			int i;
    414  1.152.2.2  dyoung 			printf("unoutput: sending pkt to: ");
    415  1.152.2.2  dyoung 			for (i=0; i<6; i++)
    416  1.152.2.2  dyoung 				printf("%x ", edst[i] & 0xff);
    417  1.152.2.2  dyoung 			printf("\n");
    418  1.152.2.2  dyoung 		}
    419  1.152.2.2  dyoung #endif
    420  1.152.2.2  dyoung 		} break;
    421  1.152.2.2  dyoung #endif /* ISO */
    422  1.152.2.2  dyoung 
    423  1.152.2.2  dyoung 	case pseudo_AF_HDRCMPLT:
    424  1.152.2.2  dyoung 		hdrcmplt = 1;
    425  1.152.2.2  dyoung 		memcpy(esrc,
    426  1.152.2.2  dyoung 		    ((const struct ether_header *)dst->sa_data)->ether_shost,
    427  1.152.2.2  dyoung 		    sizeof(esrc));
    428  1.152.2.2  dyoung 		/* FALLTHROUGH */
    429  1.152.2.2  dyoung 
    430  1.152.2.2  dyoung 	case AF_UNSPEC:
    431  1.152.2.2  dyoung  		memcpy(edst,
    432  1.152.2.2  dyoung 		    ((const struct ether_header *)dst->sa_data)->ether_dhost,
    433  1.152.2.2  dyoung 		    sizeof(edst));
    434  1.152.2.2  dyoung 		/* AF_UNSPEC doesn't swap the byte order of the ether_type. */
    435  1.152.2.2  dyoung 		etype = ((const struct ether_header *)dst->sa_data)->ether_type;
    436  1.152.2.2  dyoung 		break;
    437  1.152.2.2  dyoung 
    438  1.152.2.2  dyoung 	default:
    439  1.152.2.2  dyoung 		printf("%s: can't handle af%d\n", ifp->if_xname,
    440  1.152.2.2  dyoung 			dst->sa_family);
    441  1.152.2.2  dyoung 		senderr(EAFNOSUPPORT);
    442  1.152.2.2  dyoung 	}
    443  1.152.2.2  dyoung 
    444  1.152.2.2  dyoung 	if (mcopy)
    445  1.152.2.2  dyoung 		(void)looutput(ifp, mcopy, dst, rt);
    446  1.152.2.2  dyoung 
    447  1.152.2.2  dyoung 	/* If no ether type is set, this must be a 802.2 formatted packet.
    448  1.152.2.2  dyoung 	 */
    449  1.152.2.2  dyoung 	if (etype == 0)
    450  1.152.2.2  dyoung 		etype = htons(m->m_pkthdr.len);
    451  1.152.2.2  dyoung 	/*
    452  1.152.2.2  dyoung 	 * Add local net header.  If no space in first mbuf,
    453  1.152.2.2  dyoung 	 * allocate another.
    454  1.152.2.2  dyoung 	 */
    455  1.152.2.2  dyoung 	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
    456  1.152.2.2  dyoung 	if (m == 0)
    457  1.152.2.2  dyoung 		senderr(ENOBUFS);
    458  1.152.2.2  dyoung 	eh = mtod(m, struct ether_header *);
    459  1.152.2.2  dyoung 	/* Note: etype is already in network byte order. */
    460  1.152.2.2  dyoung 	(void)memcpy(&eh->ether_type, &etype, sizeof(eh->ether_type));
    461  1.152.2.2  dyoung  	memcpy(eh->ether_dhost, edst, sizeof(edst));
    462  1.152.2.2  dyoung 	if (hdrcmplt)
    463  1.152.2.2  dyoung 		memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
    464  1.152.2.2  dyoung 	else
    465  1.152.2.2  dyoung 	 	memcpy(eh->ether_shost, LLADDR(ifp->if_sadl),
    466  1.152.2.2  dyoung 		    sizeof(eh->ether_shost));
    467  1.152.2.2  dyoung 
    468  1.152.2.2  dyoung #if NCARP > 0
    469  1.152.2.2  dyoung 	if (ifp0 != ifp && ifp0->if_type == IFT_CARP) {
    470  1.152.2.2  dyoung 	 	memcpy(eh->ether_shost, LLADDR(ifp0->if_sadl),
    471  1.152.2.2  dyoung 		    sizeof(eh->ether_shost));
    472  1.152.2.2  dyoung 	}
    473  1.152.2.2  dyoung #endif /* NCARP > 0 */
    474  1.152.2.2  dyoung 
    475  1.152.2.2  dyoung #ifdef PFIL_HOOKS
    476  1.152.2.2  dyoung 	if ((error = pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
    477  1.152.2.2  dyoung 		return (error);
    478  1.152.2.2  dyoung 	if (m == NULL)
    479  1.152.2.2  dyoung 		return (0);
    480  1.152.2.2  dyoung #endif
    481  1.152.2.2  dyoung 
    482  1.152.2.2  dyoung #if NBRIDGE > 0
    483  1.152.2.2  dyoung 	/*
    484  1.152.2.2  dyoung 	 * Bridges require special output handling.
    485  1.152.2.2  dyoung 	 */
    486  1.152.2.2  dyoung 	if (ifp->if_bridge)
    487  1.152.2.2  dyoung 		return (bridge_output(ifp, m, NULL, NULL));
    488  1.152.2.2  dyoung #endif
    489  1.152.2.2  dyoung 
    490  1.152.2.2  dyoung #if NCARP > 0
    491  1.152.2.2  dyoung 	if (ifp != ifp0)
    492  1.152.2.2  dyoung 		ifp0->if_obytes += m->m_pkthdr.len + ETHER_HDR_LEN;
    493  1.152.2.2  dyoung #endif /* NCARP > 0 */
    494  1.152.2.2  dyoung 
    495  1.152.2.2  dyoung #ifdef ALTQ
    496  1.152.2.2  dyoung 	/*
    497  1.152.2.2  dyoung 	 * If ALTQ is enabled on the parent interface, do
    498  1.152.2.2  dyoung 	 * classification; the queueing discipline might not
    499  1.152.2.2  dyoung 	 * require classification, but might require the
    500  1.152.2.2  dyoung 	 * address family/header pointer in the pktattr.
    501  1.152.2.2  dyoung 	 */
    502  1.152.2.2  dyoung 	if (ALTQ_IS_ENABLED(&ifp->if_snd))
    503  1.152.2.2  dyoung 		altq_etherclassify(&ifp->if_snd, m, &pktattr);
    504  1.152.2.2  dyoung #endif
    505  1.152.2.2  dyoung 
    506  1.152.2.2  dyoung 	return ifq_enqueue(ifp, m ALTQ_COMMA ALTQ_DECL(&pktattr));
    507  1.152.2.2  dyoung 
    508  1.152.2.2  dyoung bad:
    509  1.152.2.2  dyoung 	if (m)
    510  1.152.2.2  dyoung 		m_freem(m);
    511  1.152.2.2  dyoung 	return (error);
    512  1.152.2.2  dyoung }
    513  1.152.2.2  dyoung 
    514  1.152.2.2  dyoung #ifdef ALTQ
    515  1.152.2.2  dyoung /*
    516  1.152.2.2  dyoung  * This routine is a slight hack to allow a packet to be classified
    517  1.152.2.2  dyoung  * if the Ethernet headers are present.  It will go away when ALTQ's
    518  1.152.2.2  dyoung  * classification engine understands link headers.
    519  1.152.2.2  dyoung  */
    520  1.152.2.2  dyoung void
    521  1.152.2.2  dyoung altq_etherclassify(struct ifaltq *ifq, struct mbuf *m,
    522  1.152.2.2  dyoung     struct altq_pktattr *pktattr)
    523  1.152.2.2  dyoung {
    524  1.152.2.2  dyoung 	struct ether_header *eh;
    525  1.152.2.2  dyoung 	u_int16_t ether_type;
    526  1.152.2.2  dyoung 	int hlen, af, hdrsize;
    527  1.152.2.2  dyoung 	void *hdr;
    528  1.152.2.2  dyoung 
    529  1.152.2.2  dyoung 	hlen = ETHER_HDR_LEN;
    530  1.152.2.2  dyoung 	eh = mtod(m, struct ether_header *);
    531  1.152.2.2  dyoung 
    532  1.152.2.2  dyoung 	ether_type = htons(eh->ether_type);
    533  1.152.2.2  dyoung 
    534  1.152.2.2  dyoung 	if (ether_type < ETHERMTU) {
    535  1.152.2.2  dyoung 		/* LLC/SNAP */
    536  1.152.2.2  dyoung 		struct llc *llc = (struct llc *)(eh + 1);
    537  1.152.2.2  dyoung 		hlen += 8;
    538  1.152.2.2  dyoung 
    539  1.152.2.2  dyoung 		if (m->m_len < hlen ||
    540  1.152.2.2  dyoung 		    llc->llc_dsap != LLC_SNAP_LSAP ||
    541  1.152.2.2  dyoung 		    llc->llc_ssap != LLC_SNAP_LSAP ||
    542  1.152.2.2  dyoung 		    llc->llc_control != LLC_UI) {
    543  1.152.2.2  dyoung 			/* Not SNAP. */
    544  1.152.2.2  dyoung 			goto bad;
    545  1.152.2.2  dyoung 		}
    546  1.152.2.2  dyoung 
    547  1.152.2.2  dyoung 		ether_type = htons(llc->llc_un.type_snap.ether_type);
    548  1.152.2.2  dyoung 	}
    549  1.152.2.2  dyoung 
    550  1.152.2.2  dyoung 	switch (ether_type) {
    551  1.152.2.2  dyoung 	case ETHERTYPE_IP:
    552  1.152.2.2  dyoung 		af = AF_INET;
    553  1.152.2.2  dyoung 		hdrsize = 20;		/* sizeof(struct ip) */
    554  1.152.2.2  dyoung 		break;
    555  1.152.2.2  dyoung 
    556  1.152.2.2  dyoung 	case ETHERTYPE_IPV6:
    557  1.152.2.2  dyoung 		af = AF_INET6;
    558  1.152.2.2  dyoung 		hdrsize = 40;		/* sizeof(struct ip6_hdr) */
    559  1.152.2.2  dyoung 		break;
    560  1.152.2.2  dyoung 
    561  1.152.2.2  dyoung 	default:
    562  1.152.2.2  dyoung 		af = AF_UNSPEC;
    563  1.152.2.2  dyoung 		hdrsize = 0;
    564  1.152.2.2  dyoung 		break;
    565  1.152.2.2  dyoung 	}
    566  1.152.2.2  dyoung 
    567  1.152.2.2  dyoung 	while (m->m_len <= hlen) {
    568  1.152.2.2  dyoung 		hlen -= m->m_len;
    569  1.152.2.2  dyoung 		m = m->m_next;
    570  1.152.2.2  dyoung 	}
    571  1.152.2.2  dyoung 	if (m->m_len < (hlen + hdrsize)) {
    572  1.152.2.2  dyoung 		/*
    573  1.152.2.2  dyoung 		 * protocol header not in a single mbuf.
    574  1.152.2.2  dyoung 		 * We can't cope with this situation right
    575  1.152.2.2  dyoung 		 * now (but it shouldn't ever happen, really, anyhow).
    576  1.152.2.2  dyoung 		 */
    577  1.152.2.2  dyoung #ifdef DEBUG
    578  1.152.2.2  dyoung 		printf("altq_etherclassify: headers span multiple mbufs: "
    579  1.152.2.2  dyoung 		    "%d < %d\n", m->m_len, (hlen + hdrsize));
    580  1.152.2.2  dyoung #endif
    581  1.152.2.2  dyoung 		goto bad;
    582  1.152.2.2  dyoung 	}
    583  1.152.2.2  dyoung 
    584  1.152.2.2  dyoung 	m->m_data += hlen;
    585  1.152.2.2  dyoung 	m->m_len -= hlen;
    586  1.152.2.2  dyoung 
    587  1.152.2.2  dyoung 	hdr = mtod(m, void *);
    588  1.152.2.2  dyoung 
    589  1.152.2.2  dyoung 	if (ALTQ_NEEDS_CLASSIFY(ifq))
    590  1.152.2.2  dyoung 		pktattr->pattr_class =
    591  1.152.2.2  dyoung 		    (*ifq->altq_classify)(ifq->altq_clfier, m, af);
    592  1.152.2.2  dyoung 	pktattr->pattr_af = af;
    593  1.152.2.2  dyoung 	pktattr->pattr_hdr = hdr;
    594  1.152.2.2  dyoung 
    595  1.152.2.2  dyoung 	m->m_data -= hlen;
    596  1.152.2.2  dyoung 	m->m_len += hlen;
    597  1.152.2.2  dyoung 
    598  1.152.2.2  dyoung 	return;
    599  1.152.2.2  dyoung 
    600  1.152.2.2  dyoung  bad:
    601  1.152.2.2  dyoung 	pktattr->pattr_class = NULL;
    602  1.152.2.2  dyoung 	pktattr->pattr_hdr = NULL;
    603  1.152.2.2  dyoung 	pktattr->pattr_af = AF_UNSPEC;
    604  1.152.2.2  dyoung }
    605  1.152.2.2  dyoung #endif /* ALTQ */
    606  1.152.2.2  dyoung 
    607  1.152.2.2  dyoung /*
    608  1.152.2.2  dyoung  * Process a received Ethernet packet;
    609  1.152.2.2  dyoung  * the packet is in the mbuf chain m with
    610  1.152.2.2  dyoung  * the ether header.
    611  1.152.2.2  dyoung  */
    612  1.152.2.2  dyoung void
    613  1.152.2.2  dyoung ether_input(struct ifnet *ifp, struct mbuf *m)
    614  1.152.2.2  dyoung {
    615  1.152.2.2  dyoung 	struct ethercom *ec = (struct ethercom *) ifp;
    616  1.152.2.2  dyoung 	struct ifqueue *inq;
    617  1.152.2.2  dyoung 	u_int16_t etype;
    618  1.152.2.2  dyoung 	struct ether_header *eh;
    619  1.152.2.2  dyoung #if defined (ISO) || defined (LLC) || defined(NETATALK)
    620  1.152.2.2  dyoung 	struct llc *l;
    621  1.152.2.2  dyoung #endif
    622  1.152.2.2  dyoung 
    623  1.152.2.2  dyoung 	if ((ifp->if_flags & IFF_UP) == 0) {
    624  1.152.2.2  dyoung 		m_freem(m);
    625  1.152.2.2  dyoung 		return;
    626  1.152.2.2  dyoung 	}
    627  1.152.2.2  dyoung 
    628  1.152.2.2  dyoung #ifdef MBUFTRACE
    629  1.152.2.2  dyoung 	m_claimm(m, &ec->ec_rx_mowner);
    630  1.152.2.2  dyoung #endif
    631  1.152.2.2  dyoung 	eh = mtod(m, struct ether_header *);
    632  1.152.2.2  dyoung 	etype = ntohs(eh->ether_type);
    633  1.152.2.2  dyoung 
    634  1.152.2.2  dyoung 	/*
    635  1.152.2.2  dyoung 	 * Determine if the packet is within its size limits.
    636  1.152.2.2  dyoung 	 */
    637  1.152.2.2  dyoung 	if (m->m_pkthdr.len >
    638  1.152.2.2  dyoung 	    ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
    639  1.152.2.2  dyoung 		if (ppsratecheck(&bigpktppslim_last, &bigpktpps_count,
    640  1.152.2.2  dyoung 			    bigpktppslim)) {
    641  1.152.2.2  dyoung 			printf("%s: discarding oversize frame (len=%d)\n",
    642  1.152.2.2  dyoung 			    ifp->if_xname, m->m_pkthdr.len);
    643  1.152.2.2  dyoung 		}
    644  1.152.2.2  dyoung 		m_freem(m);
    645  1.152.2.2  dyoung 		return;
    646  1.152.2.2  dyoung 	}
    647  1.152.2.2  dyoung 
    648  1.152.2.2  dyoung 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
    649  1.152.2.2  dyoung 		/*
    650  1.152.2.2  dyoung 		 * If this is not a simplex interface, drop the packet
    651  1.152.2.2  dyoung 		 * if it came from us.
    652  1.152.2.2  dyoung 		 */
    653  1.152.2.2  dyoung 		if ((ifp->if_flags & IFF_SIMPLEX) == 0 &&
    654  1.152.2.2  dyoung 		    memcmp(LLADDR(ifp->if_sadl), eh->ether_shost,
    655  1.152.2.2  dyoung 		    ETHER_ADDR_LEN) == 0) {
    656  1.152.2.2  dyoung 			m_freem(m);
    657  1.152.2.2  dyoung 			return;
    658  1.152.2.2  dyoung 		}
    659  1.152.2.2  dyoung 
    660  1.152.2.2  dyoung 		if (memcmp(etherbroadcastaddr,
    661  1.152.2.2  dyoung 		    eh->ether_dhost, ETHER_ADDR_LEN) == 0)
    662  1.152.2.2  dyoung 			m->m_flags |= M_BCAST;
    663  1.152.2.2  dyoung 		else
    664  1.152.2.2  dyoung 			m->m_flags |= M_MCAST;
    665  1.152.2.2  dyoung 		ifp->if_imcasts++;
    666  1.152.2.2  dyoung 	}
    667  1.152.2.2  dyoung 
    668  1.152.2.2  dyoung 	/* If the CRC is still on the packet, trim it off. */
    669  1.152.2.2  dyoung 	if (m->m_flags & M_HASFCS) {
    670  1.152.2.2  dyoung 		m_adj(m, -ETHER_CRC_LEN);
    671  1.152.2.2  dyoung 		m->m_flags &= ~M_HASFCS;
    672  1.152.2.2  dyoung 	}
    673  1.152.2.2  dyoung 
    674  1.152.2.2  dyoung 	ifp->if_ibytes += m->m_pkthdr.len;
    675  1.152.2.2  dyoung 
    676  1.152.2.2  dyoung #if NBRIDGE > 0
    677  1.152.2.2  dyoung 	/*
    678  1.152.2.2  dyoung 	 * Tap the packet off here for a bridge.  bridge_input()
    679  1.152.2.2  dyoung 	 * will return NULL if it has consumed the packet, otherwise
    680  1.152.2.2  dyoung 	 * it gets processed as normal.  Note that bridge_input()
    681  1.152.2.2  dyoung 	 * will always return the original packet if we need to
    682  1.152.2.2  dyoung 	 * process it locally.
    683  1.152.2.2  dyoung 	 */
    684  1.152.2.2  dyoung 	if (ifp->if_bridge) {
    685  1.152.2.2  dyoung 		/* clear M_PROMISC, in case the packets comes from a vlan */
    686  1.152.2.2  dyoung 		m->m_flags &= ~M_PROMISC;
    687  1.152.2.2  dyoung 		m = bridge_input(ifp, m);
    688  1.152.2.2  dyoung 		if (m == NULL)
    689  1.152.2.2  dyoung 			return;
    690  1.152.2.2  dyoung 
    691  1.152.2.2  dyoung 		/*
    692  1.152.2.2  dyoung 		 * Bridge has determined that the packet is for us.
    693  1.152.2.2  dyoung 		 * Update our interface pointer -- we may have had
    694  1.152.2.2  dyoung 		 * to "bridge" the packet locally.
    695  1.152.2.2  dyoung 		 */
    696  1.152.2.2  dyoung 		ifp = m->m_pkthdr.rcvif;
    697  1.152.2.2  dyoung 	} else
    698  1.152.2.2  dyoung #endif /* NBRIDGE > 0 */
    699  1.152.2.2  dyoung 	{
    700  1.152.2.2  dyoung 
    701  1.152.2.2  dyoung #if NCARP > 0
    702  1.152.2.2  dyoung 		if (ifp->if_carp && ifp->if_type != IFT_CARP) {
    703  1.152.2.2  dyoung 			/*
    704  1.152.2.2  dyoung 			 * clear M_PROMISC, in case the packets comes from a
    705  1.152.2.2  dyoung 			 * vlan
    706  1.152.2.2  dyoung 			 */
    707  1.152.2.2  dyoung 			m->m_flags &= ~M_PROMISC;
    708  1.152.2.2  dyoung 			if (carp_input(m, (u_int8_t *)&eh->ether_shost,
    709  1.152.2.2  dyoung 			    (u_int8_t *)&eh->ether_dhost, eh->ether_type) == 0)
    710  1.152.2.2  dyoung 				return;
    711  1.152.2.2  dyoung 		}
    712  1.152.2.2  dyoung #endif /* NCARP > 0 */
    713  1.152.2.2  dyoung 		if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
    714  1.152.2.2  dyoung 		    (ifp->if_flags & IFF_PROMISC) != 0 &&
    715  1.152.2.2  dyoung 		    memcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
    716  1.152.2.2  dyoung 			   ETHER_ADDR_LEN) != 0) {
    717  1.152.2.2  dyoung 			m->m_flags |= M_PROMISC;
    718  1.152.2.2  dyoung 		}
    719  1.152.2.2  dyoung 	}
    720  1.152.2.2  dyoung 
    721  1.152.2.2  dyoung #ifdef PFIL_HOOKS
    722  1.152.2.2  dyoung 	if ((m->m_flags & M_PROMISC) == 0) {
    723  1.152.2.2  dyoung 		if (pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
    724  1.152.2.2  dyoung 			return;
    725  1.152.2.2  dyoung 		if (m == NULL)
    726  1.152.2.2  dyoung 			return;
    727  1.152.2.2  dyoung 
    728  1.152.2.2  dyoung 		eh = mtod(m, struct ether_header *);
    729  1.152.2.2  dyoung 		etype = ntohs(eh->ether_type);
    730  1.152.2.2  dyoung 	}
    731  1.152.2.2  dyoung #endif
    732  1.152.2.2  dyoung 
    733  1.152.2.2  dyoung 	/*
    734  1.152.2.2  dyoung 	 * If VLANs are configured on the interface, check to
    735  1.152.2.2  dyoung 	 * see if the device performed the decapsulation and
    736  1.152.2.2  dyoung 	 * provided us with the tag.
    737  1.152.2.2  dyoung 	 */
    738  1.152.2.2  dyoung 	if (ec->ec_nvlans && m_tag_find(m, PACKET_TAG_VLAN, NULL) != NULL) {
    739  1.152.2.2  dyoung #if NVLAN > 0
    740  1.152.2.2  dyoung 		/*
    741  1.152.2.2  dyoung 		 * vlan_input() will either recursively call ether_input()
    742  1.152.2.2  dyoung 		 * or drop the packet.
    743  1.152.2.2  dyoung 		 */
    744  1.152.2.2  dyoung 		vlan_input(ifp, m);
    745  1.152.2.2  dyoung #else
    746  1.152.2.2  dyoung 		m_freem(m);
    747  1.152.2.2  dyoung #endif
    748  1.152.2.2  dyoung 		return;
    749  1.152.2.2  dyoung 	}
    750  1.152.2.2  dyoung 
    751  1.152.2.2  dyoung #if NAGR > 0
    752  1.152.2.2  dyoung 	if (ifp->if_agrprivate &&
    753  1.152.2.2  dyoung 	    __predict_true(etype != ETHERTYPE_SLOWPROTOCOLS)) {
    754  1.152.2.2  dyoung 		m->m_flags &= ~M_PROMISC;
    755  1.152.2.2  dyoung 		agr_input(ifp, m);
    756  1.152.2.2  dyoung 		return;
    757  1.152.2.2  dyoung 	}
    758  1.152.2.2  dyoung #endif /* NAGR > 0 */
    759  1.152.2.2  dyoung 
    760  1.152.2.2  dyoung 	/*
    761  1.152.2.2  dyoung 	 * Handle protocols that expect to have the Ethernet header
    762  1.152.2.2  dyoung 	 * (and possibly FCS) intact.
    763  1.152.2.2  dyoung 	 */
    764  1.152.2.2  dyoung 	switch (etype) {
    765  1.152.2.2  dyoung #if NVLAN > 0
    766  1.152.2.2  dyoung 	case ETHERTYPE_VLAN:
    767  1.152.2.2  dyoung 		/*
    768  1.152.2.2  dyoung 		 * vlan_input() will either recursively call ether_input()
    769  1.152.2.2  dyoung 		 * or drop the packet.
    770  1.152.2.2  dyoung 		 */
    771  1.152.2.2  dyoung 		if (((struct ethercom *)ifp)->ec_nvlans != 0)
    772  1.152.2.2  dyoung 			vlan_input(ifp, m);
    773  1.152.2.2  dyoung 		else
    774  1.152.2.2  dyoung 			m_freem(m);
    775  1.152.2.2  dyoung 		return;
    776  1.152.2.2  dyoung #endif /* NVLAN > 0 */
    777  1.152.2.2  dyoung #if NPPPOE > 0
    778  1.152.2.2  dyoung 	case ETHERTYPE_PPPOEDISC:
    779  1.152.2.2  dyoung 	case ETHERTYPE_PPPOE:
    780  1.152.2.2  dyoung 		if (m->m_flags & M_PROMISC) {
    781  1.152.2.2  dyoung 			m_freem(m);
    782  1.152.2.2  dyoung 			return;
    783  1.152.2.2  dyoung 		}
    784  1.152.2.2  dyoung #ifndef PPPOE_SERVER
    785  1.152.2.2  dyoung 		if (m->m_flags & (M_MCAST | M_BCAST)) {
    786  1.152.2.2  dyoung 			m_freem(m);
    787  1.152.2.2  dyoung 			return;
    788  1.152.2.2  dyoung 		}
    789  1.152.2.2  dyoung #endif
    790  1.152.2.2  dyoung 
    791  1.152.2.2  dyoung 		if (etype == ETHERTYPE_PPPOEDISC)
    792  1.152.2.2  dyoung 			inq = &ppoediscinq;
    793  1.152.2.2  dyoung 		else
    794  1.152.2.2  dyoung 			inq = &ppoeinq;
    795  1.152.2.2  dyoung 		if (IF_QFULL(inq)) {
    796  1.152.2.2  dyoung 			IF_DROP(inq);
    797  1.152.2.2  dyoung 			m_freem(m);
    798  1.152.2.2  dyoung 		} else
    799  1.152.2.2  dyoung 			IF_ENQUEUE(inq, m);
    800  1.152.2.2  dyoung 		softintr_schedule(pppoe_softintr);
    801  1.152.2.2  dyoung 		return;
    802  1.152.2.2  dyoung #endif /* NPPPOE > 0 */
    803  1.152.2.2  dyoung 	case ETHERTYPE_SLOWPROTOCOLS: {
    804  1.152.2.2  dyoung 		uint8_t subtype;
    805  1.152.2.2  dyoung 
    806  1.152.2.2  dyoung #if defined(DIAGNOSTIC)
    807  1.152.2.2  dyoung 		if (m->m_pkthdr.len < sizeof(*eh) + sizeof(subtype)) {
    808  1.152.2.2  dyoung 			panic("ether_input: too short slow protocol packet");
    809  1.152.2.2  dyoung 		}
    810  1.152.2.2  dyoung #endif
    811  1.152.2.2  dyoung 		m_copydata(m, sizeof(*eh), sizeof(subtype), &subtype);
    812  1.152.2.2  dyoung 		switch (subtype) {
    813  1.152.2.2  dyoung #if NAGR > 0
    814  1.152.2.2  dyoung 		case SLOWPROTOCOLS_SUBTYPE_LACP:
    815  1.152.2.2  dyoung 			if (ifp->if_agrprivate) {
    816  1.152.2.2  dyoung 				ieee8023ad_lacp_input(ifp, m);
    817  1.152.2.2  dyoung 				return;
    818  1.152.2.2  dyoung 			}
    819  1.152.2.2  dyoung 			break;
    820  1.152.2.2  dyoung 
    821  1.152.2.2  dyoung 		case SLOWPROTOCOLS_SUBTYPE_MARKER:
    822  1.152.2.2  dyoung 			if (ifp->if_agrprivate) {
    823  1.152.2.2  dyoung 				ieee8023ad_marker_input(ifp, m);
    824  1.152.2.2  dyoung 				return;
    825  1.152.2.2  dyoung 			}
    826  1.152.2.2  dyoung 			break;
    827  1.152.2.2  dyoung #endif /* NAGR > 0 */
    828  1.152.2.2  dyoung 		default:
    829  1.152.2.2  dyoung 			if (subtype == 0 || subtype > 10) {
    830  1.152.2.2  dyoung 				/* illegal value */
    831  1.152.2.2  dyoung 				m_freem(m);
    832  1.152.2.2  dyoung 				return;
    833  1.152.2.2  dyoung 			}
    834  1.152.2.2  dyoung 			/* unknown subtype */
    835  1.152.2.2  dyoung 			break;
    836  1.152.2.2  dyoung 		}
    837  1.152.2.2  dyoung 		/* FALLTHROUGH */
    838  1.152.2.2  dyoung 	}
    839  1.152.2.2  dyoung 	default:
    840  1.152.2.2  dyoung 		if (m->m_flags & M_PROMISC) {
    841  1.152.2.2  dyoung 			m_freem(m);
    842  1.152.2.2  dyoung 			return;
    843  1.152.2.2  dyoung 		}
    844  1.152.2.2  dyoung 	}
    845  1.152.2.2  dyoung 
    846  1.152.2.2  dyoung 	/* If the CRC is still on the packet, trim it off. */
    847  1.152.2.2  dyoung 	if (m->m_flags & M_HASFCS) {
    848  1.152.2.2  dyoung 		m_adj(m, -ETHER_CRC_LEN);
    849  1.152.2.2  dyoung 		m->m_flags &= ~M_HASFCS;
    850  1.152.2.2  dyoung 	}
    851  1.152.2.2  dyoung 
    852  1.152.2.2  dyoung 	if (etype > ETHERMTU + sizeof (struct ether_header)) {
    853  1.152.2.2  dyoung 		/* Strip off the Ethernet header. */
    854  1.152.2.2  dyoung 		m_adj(m, sizeof(struct ether_header));
    855  1.152.2.2  dyoung 
    856  1.152.2.2  dyoung 		switch (etype) {
    857  1.152.2.2  dyoung #ifdef INET
    858  1.152.2.2  dyoung 		case ETHERTYPE_IP:
    859  1.152.2.2  dyoung #ifdef GATEWAY
    860  1.152.2.2  dyoung 			if (ipflow_fastforward(m))
    861  1.152.2.2  dyoung 				return;
    862  1.152.2.2  dyoung #endif
    863  1.152.2.2  dyoung 			schednetisr(NETISR_IP);
    864  1.152.2.2  dyoung 			inq = &ipintrq;
    865  1.152.2.2  dyoung 			break;
    866  1.152.2.2  dyoung 
    867  1.152.2.2  dyoung 		case ETHERTYPE_ARP:
    868  1.152.2.2  dyoung 			schednetisr(NETISR_ARP);
    869  1.152.2.2  dyoung 			inq = &arpintrq;
    870  1.152.2.2  dyoung 			break;
    871  1.152.2.2  dyoung 
    872  1.152.2.2  dyoung 		case ETHERTYPE_REVARP:
    873  1.152.2.2  dyoung 			revarpinput(m);	/* XXX queue? */
    874  1.152.2.2  dyoung 			return;
    875  1.152.2.2  dyoung #endif
    876  1.152.2.2  dyoung #ifdef INET6
    877  1.152.2.2  dyoung 		case ETHERTYPE_IPV6:
    878  1.152.2.2  dyoung #ifdef GATEWAY
    879  1.152.2.2  dyoung 			if (ip6flow_fastforward(m))
    880  1.152.2.2  dyoung 				return;
    881  1.152.2.2  dyoung #endif
    882  1.152.2.2  dyoung 			schednetisr(NETISR_IPV6);
    883  1.152.2.2  dyoung 			inq = &ip6intrq;
    884  1.152.2.2  dyoung 			break;
    885  1.152.2.2  dyoung #endif
    886  1.152.2.2  dyoung #ifdef IPX
    887  1.152.2.2  dyoung 		case ETHERTYPE_IPX:
    888  1.152.2.2  dyoung 			schednetisr(NETISR_IPX);
    889  1.152.2.2  dyoung 			inq = &ipxintrq;
    890  1.152.2.2  dyoung 			break;
    891  1.152.2.2  dyoung #endif
    892  1.152.2.2  dyoung #ifdef NETATALK
    893  1.152.2.2  dyoung         	case ETHERTYPE_ATALK:
    894  1.152.2.2  dyoung                 	schednetisr(NETISR_ATALK);
    895  1.152.2.2  dyoung                 	inq = &atintrq1;
    896  1.152.2.2  dyoung                 	break;
    897  1.152.2.2  dyoung         	case ETHERTYPE_AARP:
    898  1.152.2.2  dyoung 			/* probably this should be done with a NETISR as well */
    899  1.152.2.2  dyoung                 	aarpinput(ifp, m); /* XXX */
    900  1.152.2.2  dyoung                 	return;
    901  1.152.2.2  dyoung #endif /* NETATALK */
    902  1.152.2.2  dyoung 		default:
    903  1.152.2.2  dyoung 			m_freem(m);
    904  1.152.2.2  dyoung 			return;
    905  1.152.2.2  dyoung 		}
    906  1.152.2.2  dyoung 	} else {
    907  1.152.2.2  dyoung #if defined (ISO) || defined (LLC) || defined (NETATALK)
    908  1.152.2.2  dyoung 		l = (struct llc *)(eh+1);
    909  1.152.2.2  dyoung 		switch (l->llc_dsap) {
    910  1.152.2.2  dyoung #ifdef NETATALK
    911  1.152.2.2  dyoung 		case LLC_SNAP_LSAP:
    912  1.152.2.2  dyoung 			switch (l->llc_control) {
    913  1.152.2.2  dyoung 			case LLC_UI:
    914  1.152.2.2  dyoung 				if (l->llc_ssap != LLC_SNAP_LSAP) {
    915  1.152.2.2  dyoung 					goto dropanyway;
    916  1.152.2.2  dyoung 				}
    917  1.152.2.2  dyoung 
    918  1.152.2.2  dyoung 				if (Bcmp(&(l->llc_snap_org_code)[0],
    919  1.152.2.2  dyoung 				    at_org_code, sizeof(at_org_code)) == 0 &&
    920  1.152.2.2  dyoung 				    ntohs(l->llc_snap_ether_type) ==
    921  1.152.2.2  dyoung 				    ETHERTYPE_ATALK) {
    922  1.152.2.2  dyoung 					inq = &atintrq2;
    923  1.152.2.2  dyoung 					m_adj(m, sizeof(struct ether_header)
    924  1.152.2.2  dyoung 					    + sizeof(struct llc));
    925  1.152.2.2  dyoung 					schednetisr(NETISR_ATALK);
    926  1.152.2.2  dyoung 					break;
    927  1.152.2.2  dyoung 				}
    928  1.152.2.2  dyoung 
    929  1.152.2.2  dyoung 				if (Bcmp(&(l->llc_snap_org_code)[0],
    930  1.152.2.2  dyoung 				    aarp_org_code,
    931  1.152.2.2  dyoung 				    sizeof(aarp_org_code)) == 0 &&
    932  1.152.2.2  dyoung 				    ntohs(l->llc_snap_ether_type) ==
    933  1.152.2.2  dyoung 				    ETHERTYPE_AARP) {
    934  1.152.2.2  dyoung 					m_adj( m, sizeof(struct ether_header)
    935  1.152.2.2  dyoung 					    + sizeof(struct llc));
    936  1.152.2.2  dyoung 					aarpinput(ifp, m); /* XXX */
    937  1.152.2.2  dyoung 				    return;
    938  1.152.2.2  dyoung 				}
    939  1.152.2.2  dyoung 
    940  1.152.2.2  dyoung 			default:
    941  1.152.2.2  dyoung 				goto dropanyway;
    942  1.152.2.2  dyoung 			}
    943  1.152.2.2  dyoung 			break;
    944  1.152.2.2  dyoung #endif /* NETATALK */
    945  1.152.2.2  dyoung #ifdef	ISO
    946  1.152.2.2  dyoung 		case LLC_ISO_LSAP:
    947  1.152.2.2  dyoung 			switch (l->llc_control) {
    948  1.152.2.2  dyoung 			case LLC_UI:
    949  1.152.2.2  dyoung 				/* LLC_UI_P forbidden in class 1 service */
    950  1.152.2.2  dyoung 				if ((l->llc_dsap == LLC_ISO_LSAP) &&	/* XXX? case tested */
    951  1.152.2.2  dyoung 				    (l->llc_ssap == LLC_ISO_LSAP)) {
    952  1.152.2.2  dyoung 					/* LSAP for ISO */
    953  1.152.2.2  dyoung 					/* XXX length computation?? */
    954  1.152.2.2  dyoung 					if (m->m_pkthdr.len > etype + sizeof(struct ether_header))
    955  1.152.2.2  dyoung 						m_adj(m, etype - m->m_pkthdr.len);
    956  1.152.2.2  dyoung 
    957  1.152.2.2  dyoung #ifdef ARGO_DEBUG
    958  1.152.2.2  dyoung 					if (argo_debug[D_ETHER])
    959  1.152.2.2  dyoung 						printf("clnp packet");
    960  1.152.2.2  dyoung #endif
    961  1.152.2.2  dyoung 					schednetisr(NETISR_ISO);
    962  1.152.2.2  dyoung 					inq = &clnlintrq;
    963  1.152.2.2  dyoung 					break;
    964  1.152.2.2  dyoung 				}
    965  1.152.2.2  dyoung 				goto dropanyway;
    966  1.152.2.2  dyoung 
    967  1.152.2.2  dyoung 			case LLC_XID:
    968  1.152.2.2  dyoung 			case LLC_XID_P:
    969  1.152.2.2  dyoung 				if(m->m_len < LLC_XID_BASIC_MINLEN + sizeof(struct ether_header))
    970  1.152.2.2  dyoung 					/* XXX m_pullup? */
    971  1.152.2.2  dyoung 					goto dropanyway;
    972  1.152.2.2  dyoung 				l->llc_window = 0;
    973  1.152.2.2  dyoung 				l->llc_fid = LLC_XID_FORMAT_BASIC;
    974  1.152.2.2  dyoung 				l->llc_class = LLC_XID_CLASS_I;
    975  1.152.2.2  dyoung 				l->llc_dsap = l->llc_ssap = 0;
    976  1.152.2.2  dyoung 				/* Fall through to */
    977  1.152.2.2  dyoung 			case LLC_TEST:
    978  1.152.2.2  dyoung 			case LLC_TEST_P:
    979  1.152.2.2  dyoung 			{
    980  1.152.2.2  dyoung 				struct sockaddr sa;
    981  1.152.2.2  dyoung 				struct ether_header *eh2;
    982  1.152.2.2  dyoung 				int i;
    983  1.152.2.2  dyoung 				u_char c = l->llc_dsap;
    984  1.152.2.2  dyoung 
    985  1.152.2.2  dyoung 				l->llc_dsap = l->llc_ssap;
    986  1.152.2.2  dyoung 				l->llc_ssap = c;
    987  1.152.2.2  dyoung 				m_adj(m, sizeof(struct ether_header));
    988  1.152.2.2  dyoung 				/* XXX we can optimize here? */
    989  1.152.2.2  dyoung 				if (m->m_flags & (M_BCAST | M_MCAST))
    990  1.152.2.2  dyoung 					memcpy(eh->ether_dhost,
    991  1.152.2.2  dyoung 					    LLADDR(ifp->if_sadl),
    992  1.152.2.2  dyoung 					    ETHER_ADDR_LEN);
    993  1.152.2.2  dyoung 				sa.sa_family = AF_UNSPEC;
    994  1.152.2.2  dyoung 				sa.sa_len = sizeof(sa);
    995  1.152.2.2  dyoung 				eh2 = (struct ether_header *)sa.sa_data;
    996  1.152.2.2  dyoung 				for (i = 0; i < 6; i++) {
    997  1.152.2.2  dyoung 					eh2->ether_shost[i] = c =
    998  1.152.2.2  dyoung 					    eh->ether_dhost[i];
    999  1.152.2.2  dyoung 					eh2->ether_dhost[i] =
   1000  1.152.2.2  dyoung 					    eh->ether_dhost[i] =
   1001  1.152.2.2  dyoung 					    eh->ether_shost[i];
   1002  1.152.2.2  dyoung 					eh->ether_shost[i] = c;
   1003  1.152.2.2  dyoung 				}
   1004  1.152.2.2  dyoung 				ifp->if_output(ifp, m, &sa, NULL);
   1005  1.152.2.2  dyoung 				return;
   1006  1.152.2.2  dyoung 			}
   1007  1.152.2.2  dyoung 			default:
   1008  1.152.2.2  dyoung 				m_freem(m);
   1009  1.152.2.2  dyoung 				return;
   1010  1.152.2.2  dyoung 			}
   1011  1.152.2.2  dyoung 			break;
   1012  1.152.2.2  dyoung #endif /* ISO */
   1013  1.152.2.2  dyoung #if defined (ISO) || defined (NETATALK)
   1014  1.152.2.2  dyoung 		dropanyway:
   1015  1.152.2.2  dyoung #endif
   1016  1.152.2.2  dyoung 		default:
   1017  1.152.2.2  dyoung 			m_freem(m);
   1018  1.152.2.2  dyoung 			return;
   1019  1.152.2.2  dyoung 		}
   1020  1.152.2.2  dyoung #else /* ISO || LLC || NETATALK*/
   1021  1.152.2.2  dyoung 		m_freem(m);
   1022  1.152.2.2  dyoung 		return;
   1023  1.152.2.2  dyoung #endif /* ISO || LLC || NETATALK*/
   1024  1.152.2.2  dyoung 	}
   1025  1.152.2.2  dyoung 
   1026  1.152.2.2  dyoung 	if (IF_QFULL(inq)) {
   1027  1.152.2.2  dyoung 		IF_DROP(inq);
   1028  1.152.2.2  dyoung 		m_freem(m);
   1029  1.152.2.2  dyoung 	} else
   1030  1.152.2.2  dyoung 		IF_ENQUEUE(inq, m);
   1031  1.152.2.2  dyoung }
   1032  1.152.2.2  dyoung 
   1033  1.152.2.2  dyoung /*
   1034  1.152.2.2  dyoung  * Convert Ethernet address to printable (loggable) representation.
   1035  1.152.2.2  dyoung  */
   1036  1.152.2.2  dyoung char *
   1037  1.152.2.2  dyoung ether_sprintf(const u_char *ap)
   1038  1.152.2.2  dyoung {
   1039  1.152.2.2  dyoung 	static char etherbuf[3 * ETHER_ADDR_LEN];
   1040  1.152.2.2  dyoung 	return ether_snprintf(etherbuf, sizeof(etherbuf), ap);
   1041  1.152.2.2  dyoung 	return etherbuf;
   1042  1.152.2.2  dyoung }
   1043  1.152.2.2  dyoung 
   1044  1.152.2.2  dyoung char *
   1045  1.152.2.2  dyoung ether_snprintf(char *buf, size_t len, const u_char *ap)
   1046  1.152.2.2  dyoung {
   1047  1.152.2.2  dyoung 	char *cp = buf;
   1048  1.152.2.2  dyoung 	size_t i;
   1049  1.152.2.2  dyoung 
   1050  1.152.2.2  dyoung 	for (i = 0; i < len / 3; i++) {
   1051  1.152.2.2  dyoung 		*cp++ = hexdigits[*ap >> 4];
   1052  1.152.2.2  dyoung 		*cp++ = hexdigits[*ap++ & 0xf];
   1053  1.152.2.2  dyoung 		*cp++ = ':';
   1054  1.152.2.2  dyoung 	}
   1055  1.152.2.2  dyoung 	*--cp = '\0';
   1056  1.152.2.2  dyoung 	return buf;
   1057  1.152.2.2  dyoung }
   1058  1.152.2.2  dyoung 
   1059  1.152.2.2  dyoung /*
   1060  1.152.2.2  dyoung  * Perform common duties while attaching to interface list
   1061  1.152.2.2  dyoung  */
   1062  1.152.2.2  dyoung void
   1063  1.152.2.2  dyoung ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
   1064  1.152.2.2  dyoung {
   1065  1.152.2.2  dyoung 	struct ethercom *ec = (struct ethercom *)ifp;
   1066  1.152.2.2  dyoung 
   1067  1.152.2.2  dyoung 	ifp->if_type = IFT_ETHER;
   1068  1.152.2.2  dyoung 	ifp->if_addrlen = ETHER_ADDR_LEN;
   1069  1.152.2.2  dyoung 	ifp->if_hdrlen = ETHER_HDR_LEN;
   1070  1.152.2.2  dyoung 	ifp->if_dlt = DLT_EN10MB;
   1071  1.152.2.2  dyoung 	ifp->if_mtu = ETHERMTU;
   1072  1.152.2.2  dyoung 	ifp->if_output = ether_output;
   1073  1.152.2.2  dyoung 	ifp->if_input = ether_input;
   1074  1.152.2.2  dyoung 	if (ifp->if_baudrate == 0)
   1075  1.152.2.2  dyoung 		ifp->if_baudrate = IF_Mbps(10);		/* just a default */
   1076  1.152.2.2  dyoung 
   1077  1.152.2.2  dyoung 	if_alloc_sadl(ifp);
   1078  1.152.2.2  dyoung 	memcpy(LLADDR(ifp->if_sadl), lla, ifp->if_addrlen);
   1079  1.152.2.2  dyoung 
   1080  1.152.2.2  dyoung 	LIST_INIT(&ec->ec_multiaddrs);
   1081  1.152.2.2  dyoung 	ifp->if_broadcastaddr = etherbroadcastaddr;
   1082  1.152.2.2  dyoung #if NBPFILTER > 0
   1083  1.152.2.2  dyoung 	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
   1084  1.152.2.2  dyoung #endif
   1085  1.152.2.2  dyoung #ifdef MBUFTRACE
   1086  1.152.2.2  dyoung 	strlcpy(ec->ec_tx_mowner.mo_name, ifp->if_xname,
   1087  1.152.2.2  dyoung 	    sizeof(ec->ec_tx_mowner.mo_name));
   1088  1.152.2.2  dyoung 	strlcpy(ec->ec_tx_mowner.mo_descr, "tx",
   1089  1.152.2.2  dyoung 	    sizeof(ec->ec_tx_mowner.mo_descr));
   1090  1.152.2.2  dyoung 	strlcpy(ec->ec_rx_mowner.mo_name, ifp->if_xname,
   1091  1.152.2.2  dyoung 	    sizeof(ec->ec_rx_mowner.mo_name));
   1092  1.152.2.2  dyoung 	strlcpy(ec->ec_rx_mowner.mo_descr, "rx",
   1093  1.152.2.2  dyoung 	    sizeof(ec->ec_rx_mowner.mo_descr));
   1094  1.152.2.2  dyoung 	MOWNER_ATTACH(&ec->ec_tx_mowner);
   1095  1.152.2.2  dyoung 	MOWNER_ATTACH(&ec->ec_rx_mowner);
   1096  1.152.2.2  dyoung 	ifp->if_mowner = &ec->ec_tx_mowner;
   1097  1.152.2.2  dyoung #endif
   1098  1.152.2.2  dyoung }
   1099  1.152.2.2  dyoung 
   1100  1.152.2.2  dyoung void
   1101  1.152.2.2  dyoung ether_ifdetach(struct ifnet *ifp)
   1102  1.152.2.2  dyoung {
   1103  1.152.2.2  dyoung 	struct ethercom *ec = (void *) ifp;
   1104  1.152.2.2  dyoung 	struct ether_multi *enm;
   1105  1.152.2.2  dyoung 	int s;
   1106  1.152.2.2  dyoung 
   1107  1.152.2.2  dyoung #if NBRIDGE > 0
   1108  1.152.2.2  dyoung 	if (ifp->if_bridge)
   1109  1.152.2.2  dyoung 		bridge_ifdetach(ifp);
   1110  1.152.2.2  dyoung #endif
   1111  1.152.2.2  dyoung 
   1112  1.152.2.2  dyoung #if NBPFILTER > 0
   1113  1.152.2.2  dyoung 	bpfdetach(ifp);
   1114  1.152.2.2  dyoung #endif
   1115  1.152.2.2  dyoung 
   1116  1.152.2.2  dyoung #if NVLAN > 0
   1117  1.152.2.2  dyoung 	if (ec->ec_nvlans)
   1118  1.152.2.2  dyoung 		vlan_ifdetach(ifp);
   1119  1.152.2.2  dyoung #endif
   1120  1.152.2.2  dyoung 
   1121  1.152.2.2  dyoung 	s = splnet();
   1122  1.152.2.2  dyoung 	while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
   1123  1.152.2.2  dyoung 		LIST_REMOVE(enm, enm_list);
   1124  1.152.2.2  dyoung 		free(enm, M_IFMADDR);
   1125  1.152.2.2  dyoung 		ec->ec_multicnt--;
   1126  1.152.2.2  dyoung 	}
   1127  1.152.2.2  dyoung 	splx(s);
   1128  1.152.2.2  dyoung 
   1129  1.152.2.2  dyoung #if 0	/* done in if_detach() */
   1130  1.152.2.2  dyoung 	if_free_sadl(ifp);
   1131  1.152.2.2  dyoung #endif
   1132  1.152.2.2  dyoung 
   1133  1.152.2.2  dyoung 	MOWNER_DETACH(&ec->ec_rx_mowner);
   1134  1.152.2.2  dyoung 	MOWNER_DETACH(&ec->ec_tx_mowner);
   1135  1.152.2.2  dyoung }
   1136  1.152.2.2  dyoung 
   1137  1.152.2.2  dyoung #if 0
   1138  1.152.2.2  dyoung /*
   1139  1.152.2.2  dyoung  * This is for reference.  We have a table-driven version
   1140  1.152.2.2  dyoung  * of the little-endian crc32 generator, which is faster
   1141  1.152.2.2  dyoung  * than the double-loop.
   1142  1.152.2.2  dyoung  */
   1143  1.152.2.2  dyoung u_int32_t
   1144  1.152.2.2  dyoung ether_crc32_le(const u_int8_t *buf, size_t len)
   1145  1.152.2.2  dyoung {
   1146  1.152.2.2  dyoung 	u_int32_t c, crc, carry;
   1147  1.152.2.2  dyoung 	size_t i, j;
   1148  1.152.2.2  dyoung 
   1149  1.152.2.2  dyoung 	crc = 0xffffffffU;	/* initial value */
   1150  1.152.2.2  dyoung 
   1151  1.152.2.2  dyoung 	for (i = 0; i < len; i++) {
   1152  1.152.2.2  dyoung 		c = buf[i];
   1153  1.152.2.2  dyoung 		for (j = 0; j < 8; j++) {
   1154  1.152.2.2  dyoung 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
   1155  1.152.2.2  dyoung 			crc >>= 1;
   1156  1.152.2.2  dyoung 			c >>= 1;
   1157  1.152.2.2  dyoung 			if (carry)
   1158  1.152.2.2  dyoung 				crc = (crc ^ ETHER_CRC_POLY_LE);
   1159  1.152.2.2  dyoung 		}
   1160  1.152.2.2  dyoung 	}
   1161  1.152.2.2  dyoung 
   1162  1.152.2.2  dyoung 	return (crc);
   1163  1.152.2.2  dyoung }
   1164  1.152.2.2  dyoung #else
   1165  1.152.2.2  dyoung u_int32_t
   1166  1.152.2.2  dyoung ether_crc32_le(const u_int8_t *buf, size_t len)
   1167  1.152.2.2  dyoung {
   1168  1.152.2.2  dyoung 	static const u_int32_t crctab[] = {
   1169  1.152.2.2  dyoung 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
   1170  1.152.2.2  dyoung 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
   1171  1.152.2.2  dyoung 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
   1172  1.152.2.2  dyoung 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
   1173  1.152.2.2  dyoung 	};
   1174  1.152.2.2  dyoung 	u_int32_t crc;
   1175  1.152.2.2  dyoung 	size_t i;
   1176  1.152.2.2  dyoung 
   1177  1.152.2.2  dyoung 	crc = 0xffffffffU;	/* initial value */
   1178  1.152.2.2  dyoung 
   1179  1.152.2.2  dyoung 	for (i = 0; i < len; i++) {
   1180  1.152.2.2  dyoung 		crc ^= buf[i];
   1181  1.152.2.2  dyoung 		crc = (crc >> 4) ^ crctab[crc & 0xf];
   1182  1.152.2.2  dyoung 		crc = (crc >> 4) ^ crctab[crc & 0xf];
   1183  1.152.2.2  dyoung 	}
   1184  1.152.2.2  dyoung 
   1185  1.152.2.2  dyoung 	return (crc);
   1186  1.152.2.2  dyoung }
   1187  1.152.2.2  dyoung #endif
   1188  1.152.2.2  dyoung 
   1189  1.152.2.2  dyoung u_int32_t
   1190  1.152.2.2  dyoung ether_crc32_be(const u_int8_t *buf, size_t len)
   1191  1.152.2.2  dyoung {
   1192  1.152.2.2  dyoung 	u_int32_t c, crc, carry;
   1193  1.152.2.2  dyoung 	size_t i, j;
   1194  1.152.2.2  dyoung 
   1195  1.152.2.2  dyoung 	crc = 0xffffffffU;	/* initial value */
   1196  1.152.2.2  dyoung 
   1197  1.152.2.2  dyoung 	for (i = 0; i < len; i++) {
   1198  1.152.2.2  dyoung 		c = buf[i];
   1199  1.152.2.2  dyoung 		for (j = 0; j < 8; j++) {
   1200  1.152.2.2  dyoung 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
   1201  1.152.2.2  dyoung 			crc <<= 1;
   1202  1.152.2.2  dyoung 			c >>= 1;
   1203  1.152.2.2  dyoung 			if (carry)
   1204  1.152.2.2  dyoung 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
   1205  1.152.2.2  dyoung 		}
   1206  1.152.2.2  dyoung 	}
   1207  1.152.2.2  dyoung 
   1208  1.152.2.2  dyoung 	return (crc);
   1209  1.152.2.2  dyoung }
   1210  1.152.2.2  dyoung 
   1211  1.152.2.2  dyoung #ifdef INET
   1212  1.152.2.2  dyoung const uint8_t ether_ipmulticast_min[ETHER_ADDR_LEN] =
   1213  1.152.2.2  dyoung     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
   1214  1.152.2.2  dyoung const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN] =
   1215  1.152.2.2  dyoung     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
   1216  1.152.2.2  dyoung #endif
   1217  1.152.2.2  dyoung #ifdef INET6
   1218  1.152.2.2  dyoung const uint8_t ether_ip6multicast_min[ETHER_ADDR_LEN] =
   1219  1.152.2.2  dyoung     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
   1220  1.152.2.2  dyoung const uint8_t ether_ip6multicast_max[ETHER_ADDR_LEN] =
   1221  1.152.2.2  dyoung     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
   1222  1.152.2.2  dyoung #endif
   1223  1.152.2.2  dyoung 
   1224  1.152.2.2  dyoung /*
   1225  1.152.2.2  dyoung  * ether_aton implementation, not using a static buffer.
   1226  1.152.2.2  dyoung  */
   1227  1.152.2.2  dyoung int
   1228  1.152.2.2  dyoung ether_nonstatic_aton(u_char *dest, char *str)
   1229  1.152.2.2  dyoung {
   1230  1.152.2.2  dyoung         int i;
   1231  1.152.2.2  dyoung         char *cp = str;
   1232  1.152.2.2  dyoung         u_char val[6];
   1233  1.152.2.2  dyoung 
   1234  1.152.2.2  dyoung #define set_value                       \
   1235  1.152.2.2  dyoung         if (*cp > '9' && *cp < 'a')     \
   1236  1.152.2.2  dyoung                 *cp -= 'A' - 10;        \
   1237  1.152.2.2  dyoung         else if (*cp > '9')             \
   1238  1.152.2.2  dyoung                 *cp -= 'a' - 10;        \
   1239  1.152.2.2  dyoung         else                            \
   1240  1.152.2.2  dyoung                 *cp -= '0'
   1241  1.152.2.2  dyoung 
   1242  1.152.2.2  dyoung         for (i = 0; i < 6; i++, cp++) {
   1243  1.152.2.2  dyoung                 if (!isxdigit(*cp))
   1244  1.152.2.2  dyoung                         return (1);
   1245  1.152.2.2  dyoung                 set_value;
   1246  1.152.2.2  dyoung                 val[i] = *cp++;
   1247  1.152.2.2  dyoung                 if (isxdigit(*cp)) {
   1248  1.152.2.2  dyoung                         set_value;
   1249  1.152.2.2  dyoung                         val[i] *= 16;
   1250  1.152.2.2  dyoung                         val[i] += *cp++;
   1251  1.152.2.2  dyoung                 }
   1252  1.152.2.2  dyoung                 if (*cp == ':' || i == 5)
   1253  1.152.2.2  dyoung                         continue;
   1254  1.152.2.2  dyoung                 else
   1255  1.152.2.2  dyoung                         return 1;
   1256  1.152.2.2  dyoung         }
   1257  1.152.2.2  dyoung         memcpy(dest, val, 6);
   1258  1.152.2.2  dyoung 
   1259  1.152.2.2  dyoung         return 0;
   1260  1.152.2.2  dyoung }
   1261  1.152.2.2  dyoung 
   1262  1.152.2.2  dyoung 
   1263  1.152.2.2  dyoung /*
   1264  1.152.2.2  dyoung  * Convert a sockaddr into an Ethernet address or range of Ethernet
   1265  1.152.2.2  dyoung  * addresses.
   1266  1.152.2.2  dyoung  */
   1267  1.152.2.2  dyoung int
   1268  1.152.2.2  dyoung ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
   1269  1.152.2.2  dyoung     u_int8_t addrhi[ETHER_ADDR_LEN])
   1270  1.152.2.2  dyoung {
   1271  1.152.2.2  dyoung #ifdef INET
   1272  1.152.2.2  dyoung 	struct sockaddr_in *sin;
   1273  1.152.2.2  dyoung #endif /* INET */
   1274  1.152.2.2  dyoung #ifdef INET6
   1275  1.152.2.2  dyoung 	struct sockaddr_in6 *sin6;
   1276  1.152.2.2  dyoung #endif /* INET6 */
   1277  1.152.2.2  dyoung 
   1278  1.152.2.2  dyoung 	switch (sa->sa_family) {
   1279  1.152.2.2  dyoung 
   1280  1.152.2.2  dyoung 	case AF_UNSPEC:
   1281  1.152.2.2  dyoung 		memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
   1282  1.152.2.2  dyoung 		memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
   1283  1.152.2.2  dyoung 		break;
   1284  1.152.2.2  dyoung 
   1285  1.152.2.2  dyoung #ifdef INET
   1286  1.152.2.2  dyoung 	case AF_INET:
   1287  1.152.2.2  dyoung 		sin = satosin(sa);
   1288  1.152.2.2  dyoung 		if (sin->sin_addr.s_addr == INADDR_ANY) {
   1289  1.152.2.2  dyoung 			/*
   1290  1.152.2.2  dyoung 			 * An IP address of INADDR_ANY means listen to
   1291  1.152.2.2  dyoung 			 * or stop listening to all of the Ethernet
   1292  1.152.2.2  dyoung 			 * multicast addresses used for IP.
   1293  1.152.2.2  dyoung 			 * (This is for the sake of IP multicast routers.)
   1294  1.152.2.2  dyoung 			 */
   1295  1.152.2.2  dyoung 			memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
   1296  1.152.2.2  dyoung 			memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
   1297  1.152.2.2  dyoung 		}
   1298  1.152.2.2  dyoung 		else {
   1299  1.152.2.2  dyoung 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
   1300  1.152.2.2  dyoung 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
   1301  1.152.2.2  dyoung 		}
   1302  1.152.2.2  dyoung 		break;
   1303  1.152.2.2  dyoung #endif
   1304  1.152.2.2  dyoung #ifdef INET6
   1305  1.152.2.2  dyoung 	case AF_INET6:
   1306  1.152.2.2  dyoung 		sin6 = satosin6(sa);
   1307  1.152.2.2  dyoung 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   1308  1.152.2.2  dyoung 			/*
   1309  1.152.2.2  dyoung 			 * An IP6 address of 0 means listen to or stop
   1310  1.152.2.2  dyoung 			 * listening to all of the Ethernet multicast
   1311  1.152.2.2  dyoung 			 * address used for IP6.
   1312  1.152.2.2  dyoung 			 * (This is used for multicast routers.)
   1313  1.152.2.2  dyoung 			 */
   1314  1.152.2.2  dyoung 			memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
   1315  1.152.2.2  dyoung 			memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
   1316  1.152.2.2  dyoung 		} else {
   1317  1.152.2.2  dyoung 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
   1318  1.152.2.2  dyoung 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
   1319  1.152.2.2  dyoung 		}
   1320  1.152.2.2  dyoung 		break;
   1321  1.152.2.2  dyoung #endif
   1322  1.152.2.2  dyoung 
   1323  1.152.2.2  dyoung 	default:
   1324  1.152.2.2  dyoung 		return EAFNOSUPPORT;
   1325  1.152.2.2  dyoung 	}
   1326  1.152.2.2  dyoung 	return 0;
   1327  1.152.2.2  dyoung }
   1328  1.152.2.2  dyoung 
   1329  1.152.2.2  dyoung /*
   1330  1.152.2.2  dyoung  * Add an Ethernet multicast address or range of addresses to the list for a
   1331  1.152.2.2  dyoung  * given interface.
   1332  1.152.2.2  dyoung  */
   1333  1.152.2.2  dyoung int
   1334  1.152.2.2  dyoung ether_addmulti(struct ifreq *ifr, struct ethercom *ec)
   1335  1.152.2.2  dyoung {
   1336  1.152.2.2  dyoung 	struct ether_multi *enm;
   1337  1.152.2.2  dyoung 	u_char addrlo[ETHER_ADDR_LEN];
   1338  1.152.2.2  dyoung 	u_char addrhi[ETHER_ADDR_LEN];
   1339  1.152.2.2  dyoung 	int s = splnet(), error;
   1340  1.152.2.2  dyoung 
   1341  1.152.2.2  dyoung 	error = ether_multiaddr(&ifr->ifr_addr, addrlo,
   1342  1.152.2.2  dyoung 	    addrhi);
   1343  1.152.2.2  dyoung 	if (error != 0) {
   1344  1.152.2.2  dyoung 		splx(s);
   1345  1.152.2.2  dyoung 		return error;
   1346  1.152.2.2  dyoung 	}
   1347  1.152.2.2  dyoung 
   1348  1.152.2.2  dyoung 	/*
   1349  1.152.2.2  dyoung 	 * Verify that we have valid Ethernet multicast addresses.
   1350  1.152.2.2  dyoung 	 */
   1351  1.152.2.2  dyoung 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
   1352  1.152.2.2  dyoung 		splx(s);
   1353  1.152.2.2  dyoung 		return EINVAL;
   1354  1.152.2.2  dyoung 	}
   1355  1.152.2.2  dyoung 	/*
   1356  1.152.2.2  dyoung 	 * See if the address range is already in the list.
   1357  1.152.2.2  dyoung 	 */
   1358  1.152.2.2  dyoung 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
   1359  1.152.2.2  dyoung 	if (enm != NULL) {
   1360  1.152.2.2  dyoung 		/*
   1361  1.152.2.2  dyoung 		 * Found it; just increment the reference count.
   1362  1.152.2.2  dyoung 		 */
   1363  1.152.2.2  dyoung 		++enm->enm_refcount;
   1364  1.152.2.2  dyoung 		splx(s);
   1365  1.152.2.2  dyoung 		return 0;
   1366  1.152.2.2  dyoung 	}
   1367  1.152.2.2  dyoung 	/*
   1368  1.152.2.2  dyoung 	 * New address or range; malloc a new multicast record
   1369  1.152.2.2  dyoung 	 * and link it into the interface's multicast list.
   1370  1.152.2.2  dyoung 	 */
   1371  1.152.2.2  dyoung 	enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
   1372  1.152.2.2  dyoung 	if (enm == NULL) {
   1373  1.152.2.2  dyoung 		splx(s);
   1374  1.152.2.2  dyoung 		return ENOBUFS;
   1375  1.152.2.2  dyoung 	}
   1376  1.152.2.2  dyoung 	memcpy(enm->enm_addrlo, addrlo, 6);
   1377  1.152.2.2  dyoung 	memcpy(enm->enm_addrhi, addrhi, 6);
   1378  1.152.2.2  dyoung 	enm->enm_refcount = 1;
   1379  1.152.2.2  dyoung 	LIST_INSERT_HEAD(&ec->ec_multiaddrs, enm, enm_list);
   1380  1.152.2.2  dyoung 	ec->ec_multicnt++;
   1381  1.152.2.2  dyoung 	splx(s);
   1382  1.152.2.2  dyoung 	/*
   1383  1.152.2.2  dyoung 	 * Return ENETRESET to inform the driver that the list has changed
   1384  1.152.2.2  dyoung 	 * and its reception filter should be adjusted accordingly.
   1385  1.152.2.2  dyoung 	 */
   1386  1.152.2.2  dyoung 	return ENETRESET;
   1387  1.152.2.2  dyoung }
   1388  1.152.2.2  dyoung 
   1389  1.152.2.2  dyoung /*
   1390  1.152.2.2  dyoung  * Delete a multicast address record.
   1391  1.152.2.2  dyoung  */
   1392  1.152.2.2  dyoung int
   1393  1.152.2.2  dyoung ether_delmulti(struct ifreq *ifr, struct ethercom *ec)
   1394  1.152.2.2  dyoung {
   1395  1.152.2.2  dyoung 	struct ether_multi *enm;
   1396  1.152.2.2  dyoung 	u_char addrlo[ETHER_ADDR_LEN];
   1397  1.152.2.2  dyoung 	u_char addrhi[ETHER_ADDR_LEN];
   1398  1.152.2.2  dyoung 	int s = splnet(), error;
   1399  1.152.2.2  dyoung 
   1400  1.152.2.2  dyoung 	error = ether_multiaddr(&ifr->ifr_addr, addrlo,
   1401  1.152.2.2  dyoung 	    addrhi);
   1402  1.152.2.2  dyoung 	if (error != 0) {
   1403  1.152.2.2  dyoung 		splx(s);
   1404  1.152.2.2  dyoung 		return (error);
   1405  1.152.2.2  dyoung 	}
   1406  1.152.2.2  dyoung 
   1407  1.152.2.2  dyoung 	/*
   1408  1.152.2.2  dyoung 	 * Look ur the address in our list.
   1409  1.152.2.2  dyoung 	 */
   1410  1.152.2.2  dyoung 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
   1411  1.152.2.2  dyoung 	if (enm == NULL) {
   1412  1.152.2.2  dyoung 		splx(s);
   1413  1.152.2.2  dyoung 		return (ENXIO);
   1414  1.152.2.2  dyoung 	}
   1415  1.152.2.2  dyoung 	if (--enm->enm_refcount != 0) {
   1416  1.152.2.2  dyoung 		/*
   1417  1.152.2.2  dyoung 		 * Still some claims to this record.
   1418  1.152.2.2  dyoung 		 */
   1419  1.152.2.2  dyoung 		splx(s);
   1420  1.152.2.2  dyoung 		return (0);
   1421  1.152.2.2  dyoung 	}
   1422  1.152.2.2  dyoung 	/*
   1423  1.152.2.2  dyoung 	 * No remaining claims to this record; unlink and free it.
   1424  1.152.2.2  dyoung 	 */
   1425  1.152.2.2  dyoung 	LIST_REMOVE(enm, enm_list);
   1426  1.152.2.2  dyoung 	free(enm, M_IFMADDR);
   1427  1.152.2.2  dyoung 	ec->ec_multicnt--;
   1428  1.152.2.2  dyoung 	splx(s);
   1429  1.152.2.2  dyoung 	/*
   1430  1.152.2.2  dyoung 	 * Return ENETRESET to inform the driver that the list has changed
   1431  1.152.2.2  dyoung 	 * and its reception filter should be adjusted accordingly.
   1432  1.152.2.2  dyoung 	 */
   1433  1.152.2.2  dyoung 	return (ENETRESET);
   1434  1.152.2.2  dyoung }
   1435  1.152.2.2  dyoung 
   1436  1.152.2.2  dyoung /*
   1437  1.152.2.2  dyoung  * Common ioctls for Ethernet interfaces.  Note, we must be
   1438  1.152.2.2  dyoung  * called at splnet().
   1439  1.152.2.2  dyoung  */
   1440  1.152.2.2  dyoung int
   1441  1.152.2.2  dyoung ether_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1442  1.152.2.2  dyoung {
   1443  1.152.2.2  dyoung 	struct ethercom *ec = (void *) ifp;
   1444  1.152.2.2  dyoung 	struct ifreq *ifr = (struct ifreq *)data;
   1445  1.152.2.2  dyoung 	struct ifaddr *ifa = (struct ifaddr *)data;
   1446  1.152.2.2  dyoung 	int error = 0;
   1447  1.152.2.2  dyoung 
   1448  1.152.2.2  dyoung 	switch (cmd) {
   1449  1.152.2.2  dyoung 	case SIOCSIFADDR:
   1450  1.152.2.2  dyoung 		ifp->if_flags |= IFF_UP;
   1451  1.152.2.2  dyoung 		switch (ifa->ifa_addr->sa_family) {
   1452  1.152.2.2  dyoung 		case AF_LINK:
   1453  1.152.2.2  dyoung 		    {
   1454  1.152.2.2  dyoung 			const struct sockaddr_dl *sdl = satocsdl(ifa->ifa_addr);
   1455  1.152.2.2  dyoung 
   1456  1.152.2.2  dyoung 			if (sdl->sdl_type != IFT_ETHER ||
   1457  1.152.2.2  dyoung 			    sdl->sdl_alen != ifp->if_addrlen) {
   1458  1.152.2.2  dyoung 				error = EINVAL;
   1459  1.152.2.2  dyoung 				break;
   1460  1.152.2.2  dyoung 			}
   1461  1.152.2.2  dyoung 
   1462  1.152.2.2  dyoung 			memcpy(LLADDR(ifp->if_sadl), CLLADDR(sdl),
   1463  1.152.2.2  dyoung 			    ifp->if_addrlen);
   1464  1.152.2.2  dyoung 
   1465  1.152.2.2  dyoung 			/* Set new address. */
   1466  1.152.2.2  dyoung 			error = (*ifp->if_init)(ifp);
   1467  1.152.2.2  dyoung 			break;
   1468  1.152.2.2  dyoung 		    }
   1469  1.152.2.2  dyoung #ifdef INET
   1470  1.152.2.2  dyoung 		case AF_INET:
   1471  1.152.2.2  dyoung 			if ((ifp->if_flags & IFF_RUNNING) == 0 &&
   1472  1.152.2.2  dyoung 			    (error = (*ifp->if_init)(ifp)) != 0)
   1473  1.152.2.2  dyoung 				break;
   1474  1.152.2.2  dyoung 			arp_ifinit(ifp, ifa);
   1475  1.152.2.2  dyoung 			break;
   1476  1.152.2.2  dyoung #endif /* INET */
   1477  1.152.2.2  dyoung 		default:
   1478  1.152.2.2  dyoung 			if ((ifp->if_flags & IFF_RUNNING) == 0)
   1479  1.152.2.2  dyoung 				error = (*ifp->if_init)(ifp);
   1480  1.152.2.2  dyoung 			break;
   1481  1.152.2.2  dyoung 		}
   1482  1.152.2.2  dyoung 		break;
   1483  1.152.2.2  dyoung 
   1484  1.152.2.2  dyoung 	case SIOCGIFADDR:
   1485  1.152.2.2  dyoung 		memcpy(((struct sockaddr *)&ifr->ifr_data)->sa_data,
   1486  1.152.2.2  dyoung 		    LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   1487  1.152.2.2  dyoung 		break;
   1488  1.152.2.2  dyoung 
   1489  1.152.2.2  dyoung 	case SIOCSIFMTU:
   1490  1.152.2.2  dyoung 	    {
   1491  1.152.2.2  dyoung 		int maxmtu;
   1492  1.152.2.2  dyoung 
   1493  1.152.2.2  dyoung 		if (ec->ec_capabilities & ETHERCAP_JUMBO_MTU)
   1494  1.152.2.2  dyoung 			maxmtu = ETHERMTU_JUMBO;
   1495  1.152.2.2  dyoung 		else
   1496  1.152.2.2  dyoung 			maxmtu = ETHERMTU;
   1497  1.152.2.2  dyoung 
   1498  1.152.2.2  dyoung 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > maxmtu)
   1499  1.152.2.2  dyoung 			error = EINVAL;
   1500  1.152.2.2  dyoung 		else {
   1501  1.152.2.2  dyoung 			ifp->if_mtu = ifr->ifr_mtu;
   1502  1.152.2.2  dyoung 
   1503  1.152.2.2  dyoung 			/* Make sure the device notices the MTU change. */
   1504  1.152.2.2  dyoung 			if (ifp->if_flags & IFF_UP)
   1505  1.152.2.2  dyoung 				error = (*ifp->if_init)(ifp);
   1506  1.152.2.2  dyoung 		}
   1507  1.152.2.2  dyoung 		break;
   1508  1.152.2.2  dyoung 	    }
   1509  1.152.2.2  dyoung 
   1510  1.152.2.2  dyoung 	case SIOCSIFFLAGS:
   1511  1.152.2.2  dyoung 		if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) {
   1512  1.152.2.2  dyoung 			/*
   1513  1.152.2.2  dyoung 			 * If interface is marked down and it is running,
   1514  1.152.2.2  dyoung 			 * then stop and disable it.
   1515  1.152.2.2  dyoung 			 */
   1516  1.152.2.2  dyoung 			(*ifp->if_stop)(ifp, 1);
   1517  1.152.2.2  dyoung 		} else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) {
   1518  1.152.2.2  dyoung 			/*
   1519  1.152.2.2  dyoung 			 * If interface is marked up and it is stopped, then
   1520  1.152.2.2  dyoung 			 * start it.
   1521  1.152.2.2  dyoung 			 */
   1522  1.152.2.2  dyoung 			error = (*ifp->if_init)(ifp);
   1523  1.152.2.2  dyoung 		} else if ((ifp->if_flags & IFF_UP) != 0) {
   1524  1.152.2.2  dyoung 			/*
   1525  1.152.2.2  dyoung 			 * Reset the interface to pick up changes in any other
   1526  1.152.2.2  dyoung 			 * flags that affect the hardware state.
   1527  1.152.2.2  dyoung 			 */
   1528  1.152.2.2  dyoung 			error = (*ifp->if_init)(ifp);
   1529  1.152.2.2  dyoung 		}
   1530  1.152.2.2  dyoung 		break;
   1531  1.152.2.2  dyoung 
   1532  1.152.2.2  dyoung 	case SIOCADDMULTI:
   1533  1.152.2.2  dyoung 		error = ether_addmulti(ifr, ec);
   1534  1.152.2.2  dyoung 		break;
   1535  1.152.2.2  dyoung 
   1536  1.152.2.2  dyoung 	case SIOCDELMULTI:
   1537  1.152.2.2  dyoung 		error = ether_delmulti(ifr, ec);
   1538  1.152.2.2  dyoung 		break;
   1539  1.152.2.2  dyoung 
   1540  1.152.2.2  dyoung 	default:
   1541  1.152.2.2  dyoung 		error = ENOTTY;
   1542  1.152.2.2  dyoung 	}
   1543  1.152.2.2  dyoung 
   1544  1.152.2.2  dyoung 	return (error);
   1545  1.152.2.2  dyoung }
   1546