darwin-xnu/bsd/net/if_ethersubr.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   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.
  11 * 
  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
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/*
  23 * Copyright (c) 1982, 1989, 1993
  24 *      The Regents of the University of California.  All rights reserved.
  25 *
  26 * Redistribution and use in source and binary forms, with or without
  27 * modification, are permitted provided that the following conditions
  28 * are met:
  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.
  41 *
  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
  52 * SUCH DAMAGE.
  53 *
  54 *      @(#)if_ethersubr.c      8.1 (Berkeley) 6/10/93
  55 * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.70.2.17 2001/08/01 00:47:49 fenner Exp $
  56 */
  57
  58#include <sys/param.h>
  59#include <sys/systm.h>
  60#include <sys/kernel.h>
  61#include <sys/malloc.h>
  62#include <sys/mbuf.h>
  63#include <sys/socket.h>
  64#include <sys/sockio.h>
  65#include <sys/sysctl.h>
  66
  67#include <net/if.h>
  68#include <net/route.h>
  69#include <net/if_llc.h>
  70#include <net/if_dl.h>
  71#include <net/if_types.h>
  72
  73#if INET || INET6
  74#include <netinet/in.h>
  75#include <netinet/in_var.h>
  76#include <netinet/if_ether.h>
  77#include <netinet/in_systm.h>
  78#include <netinet/ip.h>
  79#endif
  80
  81#if IPX
  82#include <netipx/ipx.h>
  83#include <netipx/ipx_if.h>
  84#endif
  85
  86#include <sys/socketvar.h>
  87
  88#if LLC && CCITT
  89extern struct ifqueue pkintrq;
  90#endif
  91
  92#if BRIDGE
  93#include <net/bridge.h>
  94#endif
  95
  96/* #include "vlan.h" */
  97#if NVLAN > 0
  98#include <net/if_vlan_var.h>
  99#endif /* NVLAN > 0 */
 100
 101extern u_char   etherbroadcastaddr[];
 102#define senderr(e) do { error = (e); goto bad;} while (0)
 103
 104/*
 105 * Perform common duties while attaching to interface list
 106 */
 107
 108int
 109ether_resolvemulti(
 110        struct ifnet *ifp,
 111        struct sockaddr **llsa,
 112        struct sockaddr *sa)
 113{
 114        struct sockaddr_dl *sdl;
 115        struct sockaddr_in *sin;
 116        u_char *e_addr;
 117#if INET6
 118        struct sockaddr_in6 *sin6;
 119#endif
 120
 121
 122        switch(sa->sa_family) {
 123        case AF_UNSPEC:
 124                /* AppleTalk uses AF_UNSPEC for multicast registration.
 125                 * No mapping needed. Just check that it's a valid MC address.
 126                 */
 127                e_addr = &sa->sa_data[0];
 128                if ((e_addr[0] & 1) != 1)
 129                        return EADDRNOTAVAIL;
 130                *llsa = 0;
 131                return 0;
 132
 133        case AF_LINK:
 134                /* 
 135                 * No mapping needed. Just check that it's a valid MC address.
 136                 */
 137                sdl = (struct sockaddr_dl *)sa;
 138                e_addr = LLADDR(sdl);
 139                if ((e_addr[0] & 1) != 1)
 140                        return EADDRNOTAVAIL;
 141                *llsa = 0;
 142                return 0;
 143
 144#if INET
 145        case AF_INET:
 146                sin = (struct sockaddr_in *)sa;
 147                if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
 148                        return EADDRNOTAVAIL;
 149                MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
 150                       M_WAITOK);
 151                sdl->sdl_len = sizeof *sdl;
 152                sdl->sdl_family = AF_LINK;
 153                sdl->sdl_index = ifp->if_index;
 154                sdl->sdl_type = IFT_ETHER;
 155                sdl->sdl_nlen = 0;
 156                sdl->sdl_alen = ETHER_ADDR_LEN;
 157                sdl->sdl_slen = 0;
 158                e_addr = LLADDR(sdl);
 159                ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
 160                *llsa = (struct sockaddr *)sdl;
 161                return 0;
 162#endif
 163#if INET6
 164        case AF_INET6:
 165                sin6 = (struct sockaddr_in6 *)sa;
 166                if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 167                        /*
 168                         * An IP6 address of 0 means listen to all
 169                         * of the Ethernet multicast address used for IP6.
 170                         * (This is used for multicast routers.)
 171                         */
 172                        ifp->if_flags |= IFF_ALLMULTI;
 173                        *llsa = 0;
 174                        return 0;
 175                }
 176                MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
 177                       M_WAITOK);
 178                sdl->sdl_len = sizeof *sdl;
 179                sdl->sdl_family = AF_LINK;
 180                sdl->sdl_index = ifp->if_index;
 181                sdl->sdl_type = IFT_ETHER;
 182                sdl->sdl_nlen = 0;
 183                sdl->sdl_alen = ETHER_ADDR_LEN;
 184                sdl->sdl_slen = 0;
 185                e_addr = LLADDR(sdl);
 186                ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
 187                kprintf("ether_resolvemulti Adding %x:%x:%x:%x:%x:%x\n",
 188                                e_addr[0], e_addr[1], e_addr[2], e_addr[3], e_addr[4], e_addr[5]);
 189                *llsa = (struct sockaddr *)sdl;
 190                return 0;
 191#endif
 192
 193        default:
 194                /* 
 195                 * Well, the text isn't quite right, but it's the name
 196                 * that counts...
 197                 */
 198                return EAFNOSUPPORT;
 199        }
 200}
 201
 202
 203/*
 204 * Convert Ethernet address to printable (loggable) representation.
 205 */
 206static u_char digits[] = "0123456789abcdef";
 207char *
 208ether_sprintf(p, ap)
 209        register u_char *p;
 210        register u_char *ap;
 211{       register char *cp;
 212        register i;
 213
 214        for (cp = p, i = 0; i < 6; i++) {
 215                *cp++ = digits[*ap >> 4];
 216                *cp++ = digits[*ap++ & 0xf];
 217                *cp++ = ':';
 218        }
 219        *--cp = 0;
 220        return (p);
 221}
 222
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.