[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

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