[BACK]Return to if_atm.c CVS log [TXT][DIR] Up to [local] / sys / netinet

Annotation of sys/netinet/if_atm.c, Revision 1.1

1.1     ! nbrk        1: /*      $OpenBSD: if_atm.c,v 1.13 2006/06/17 10:22:06 henning Exp $       */
        !             2:
        !             3: /*
        !             4:  *
        !             5:  * Copyright (c) 1996 Charles D. Cranor and Washington University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *      This product includes software developed by Charles D. Cranor and
        !            19:  *     Washington University.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: /*
        !            36:  * IP <=> ATM address resolution.
        !            37:  */
        !            38:
        !            39: #if defined(INET) || defined(INET6)
        !            40:
        !            41: #include <sys/param.h>
        !            42: #include <sys/systm.h>
        !            43: #include <sys/malloc.h>
        !            44: #include <sys/mbuf.h>
        !            45: #include <sys/socket.h>
        !            46: #include <sys/time.h>
        !            47: #include <sys/kernel.h>
        !            48: #include <sys/errno.h>
        !            49: #include <sys/ioctl.h>
        !            50: #include <sys/syslog.h>
        !            51: #include <sys/proc.h>
        !            52:
        !            53: #include <net/if.h>
        !            54: #include <net/if_dl.h>
        !            55: #include <net/route.h>
        !            56: #include <net/if_atm.h>
        !            57:
        !            58: #include <netinet/in.h>
        !            59: #include <netinet/in_systm.h>
        !            60: #include <netinet/in_var.h>
        !            61: #include <netinet/ip.h>
        !            62: #include <netinet/if_atm.h>
        !            63:
        !            64: #ifdef NATM
        !            65: #include <netnatm/natm.h>
        !            66: #endif
        !            67:
        !            68:
        !            69: #define SDL(s) ((struct sockaddr_dl *)s)
        !            70:
        !            71: /*
        !            72:  * atm_rtrequest: handle ATM rt request (in support of generic code)
        !            73:  *   inputs: "req" = request code
        !            74:  *           "rt" = route entry
        !            75:  *           "sa" = sockaddr
        !            76:  */
        !            77:
        !            78: void
        !            79: atm_rtrequest(req, rt, info)
        !            80:        int req;
        !            81:        struct rtentry *rt;
        !            82:        struct rt_addrinfo *info;
        !            83: {
        !            84:        struct sockaddr *gate = rt->rt_gateway;
        !            85:        struct atm_pseudoioctl api;
        !            86: #ifdef NATM
        !            87:        struct sockaddr_in *sin;
        !            88:        struct natmpcb *npcb = NULL;
        !            89:        struct atm_pseudohdr *aph;
        !            90: #endif
        !            91:        static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
        !            92:
        !            93:        if (rt->rt_flags & RTF_GATEWAY)   /* link level requests only */
        !            94:                return;
        !            95:
        !            96:        switch (req) {
        !            97:
        !            98:        case RTM_RESOLVE: /* resolve: only happens when cloning */
        !            99:                printf("atm_rtrequest: RTM_RESOLVE request detected?\n");
        !           100:                break;
        !           101:
        !           102:        case RTM_ADD:
        !           103:
        !           104:                /*
        !           105:                 * route added by a command (e.g. ifconfig, route, arp...).
        !           106:                 *
        !           107:                 * first check to see if this is not a host route, in which
        !           108:                 * case we are being called via "ifconfig" to set the address.
        !           109:                 */
        !           110:
        !           111:                if ((rt->rt_flags & RTF_HOST) == 0) {
        !           112:                        rt_setgate(rt,rt_key(rt),(struct sockaddr *)&null_sdl, 0);
        !           113:                        gate = rt->rt_gateway;
        !           114:                        SDL(gate)->sdl_type = rt->rt_ifp->if_type;
        !           115:                        SDL(gate)->sdl_index = rt->rt_ifp->if_index;
        !           116:                        break;
        !           117:                }
        !           118:
        !           119:                if ((rt->rt_flags & RTF_CLONING) != 0) {
        !           120:                        printf("atm_rtrequest: cloning route detected?\n");
        !           121:                        break;
        !           122:                }
        !           123:                if (gate->sa_family != AF_LINK ||
        !           124:                    gate->sa_len < sizeof(null_sdl)) {
        !           125:                        log(LOG_DEBUG, "atm_rtrequest: bad gateway value\n");
        !           126:                        break;
        !           127:                }
        !           128:
        !           129: #ifdef DIAGNOSTIC
        !           130:                if (rt->rt_ifp->if_ioctl == NULL) panic("atm null ioctl");
        !           131: #endif
        !           132:
        !           133: #ifdef NATM
        !           134:                /*
        !           135:                 * let native ATM know we are using this VCI/VPI
        !           136:                 * (i.e. reserve it)
        !           137:                 */
        !           138:                sin = (struct sockaddr_in *) rt_key(rt);
        !           139:                if (sin->sin_family != AF_INET)
        !           140:                        goto failed;
        !           141:                aph = (struct atm_pseudohdr *) LLADDR(SDL(gate));
        !           142:                npcb = npcb_add(NULL, rt->rt_ifp, ATM_PH_VCI(aph),
        !           143:                                                ATM_PH_VPI(aph));
        !           144:                if (npcb == NULL)
        !           145:                        goto failed;
        !           146:                npcb->npcb_flags |= NPCB_IP;
        !           147:                npcb->ipaddr.s_addr = sin->sin_addr.s_addr;
        !           148:                /* XXX: move npcb to llinfo when ATM ARP is ready */
        !           149:                rt->rt_llinfo = (caddr_t) npcb;
        !           150:                rt->rt_flags |= RTF_LLINFO;
        !           151: #endif
        !           152:                /*
        !           153:                 * let the lower level know this circuit is active
        !           154:                 */
        !           155:                bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
        !           156:                api.rxhand = NULL;
        !           157:                if (rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMENA,
        !           158:                                                        (caddr_t)&api) != 0) {
        !           159:                        printf("atm: couldn't add VC\n");
        !           160:                        goto failed;
        !           161:                }
        !           162:
        !           163:                SDL(gate)->sdl_type = rt->rt_ifp->if_type;
        !           164:                SDL(gate)->sdl_index = rt->rt_ifp->if_index;
        !           165:
        !           166:                break;
        !           167:
        !           168: failed:
        !           169: #ifdef NATM
        !           170:                if (npcb) {
        !           171:                        npcb_free(npcb, NPCB_DESTROY);
        !           172:                        rt->rt_llinfo = NULL;
        !           173:                        rt->rt_flags &= ~RTF_LLINFO;
        !           174:                }
        !           175: #endif
        !           176:                rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
        !           177:                        rt_mask(rt), 0, (struct rtentry **) 0, 0);
        !           178:                break;
        !           179:
        !           180:        case RTM_DELETE:
        !           181:
        !           182: #ifdef NATM
        !           183:                /*
        !           184:                 * tell native ATM we are done with this VC
        !           185:                 */
        !           186:
        !           187:                if (rt->rt_flags & RTF_LLINFO) {
        !           188:                        npcb_free((struct natmpcb *)rt->rt_llinfo,
        !           189:                                                                NPCB_DESTROY);
        !           190:                        rt->rt_llinfo = NULL;
        !           191:                        rt->rt_flags &= ~RTF_LLINFO;
        !           192:                }
        !           193: #endif
        !           194:                /*
        !           195:                 * tell the lower layer to disable this circuit
        !           196:                 */
        !           197:
        !           198:                bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
        !           199:                api.rxhand = NULL;
        !           200:                (void)rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMDIS,
        !           201:                                                        (caddr_t)&api);
        !           202:
        !           203:                break;
        !           204:        }
        !           205: }
        !           206:
        !           207: /*
        !           208:  * atmresolve:
        !           209:  *   inputs:
        !           210:  *     [1] "rt" = the link level route to use (or null if need to look one up)
        !           211:  *     [2] "m" = mbuf containing the data to be sent
        !           212:  *     [3] "dst" = sockaddr_in (IP) address of dest.
        !           213:  *   output:
        !           214:  *     [4] "desten" = ATM pseudo header which we will fill in VPI/VCI info
        !           215:  *   return:
        !           216:  *     0 == resolve FAILED; note that "m" gets m_freem'd in this case
        !           217:  *     1 == resolve OK; desten contains result
        !           218:  *
        !           219:  *   XXX: will need more work if we wish to support ATMARP in the kernel,
        !           220:  *   but this is enough for PVCs entered via the "route" command.
        !           221:  */
        !           222:
        !           223: int
        !           224: atmresolve(rt, m, dst, desten)
        !           225:        struct rtentry *rt;
        !           226:        struct mbuf *m;
        !           227:        struct sockaddr *dst;
        !           228:        struct atm_pseudohdr *desten;   /* OUT */
        !           229: {
        !           230:        struct sockaddr_dl *sdl;
        !           231:
        !           232:        if (m->m_flags & (M_BCAST|M_MCAST)) {
        !           233:                log(LOG_INFO,
        !           234:                    "atmresolve: BCAST/MCAST packet detected/dumped\n");
        !           235:                goto bad;
        !           236:        }
        !           237:
        !           238:        if (rt == NULL) {
        !           239:                rt = RTALLOC1(dst, 0);
        !           240:                if (rt == NULL) goto bad; /* failed */
        !           241:                rt->rt_refcnt--;        /* don't keep LL references */
        !           242:                if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
        !           243:                        (rt->rt_flags & RTF_LLINFO) == 0 ||
        !           244:                        /* XXX: are we using LLINFO? */
        !           245:                        rt->rt_gateway->sa_family != AF_LINK) {
        !           246:                                goto bad;
        !           247:                }
        !           248:        }
        !           249:
        !           250:        /*
        !           251:         * note that rt_gateway is a sockaddr_dl which contains the
        !           252:         * atm_pseudohdr data structure for this route.   we currently
        !           253:         * don't need any rt_llinfo info (but will if we want to support
        !           254:         * ATM ARP [c.f. if_ether.c]).
        !           255:         */
        !           256:
        !           257:        sdl = SDL(rt->rt_gateway);
        !           258:
        !           259:        /*
        !           260:         * Check the address family and length is valid, the address
        !           261:         * is resolved; otherwise, try to resolve.
        !           262:         */
        !           263:
        !           264:
        !           265:        if (sdl->sdl_family == AF_LINK && sdl->sdl_alen == sizeof(*desten)) {
        !           266:                bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
        !           267:                return (1);     /* ok, go for it! */
        !           268:        }
        !           269:
        !           270:        /*
        !           271:         * we got an entry, but it doesn't have valid link address
        !           272:         * info in it (it is prob. the interface route, which has
        !           273:         * sdl_alen == 0).    dump packet.  (fall through to "bad").
        !           274:         */
        !           275:
        !           276: bad:
        !           277:        m_freem(m);
        !           278:        return (0);
        !           279: }
        !           280: #endif /* INET */

CVSweb