Annotation of XNU/bsd/netccitt/pk_llcsubr.c, revision 1.1

1.1     ! root        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) Dirk Husemann, Computer Science Department IV, 
        !            24:  *              University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
        !            25:  * Copyright (c) 1992, 1993
        !            26:  *     The Regents of the University of California.  All rights reserved.
        !            27:  * 
        !            28:  * This code is derived from software contributed to Berkeley by
        !            29:  * Dirk Husemann and the Computer Science Department (IV) of
        !            30:  * the University of Erlangen-Nuremberg, Germany.
        !            31:  *
        !            32:  * Redistribution and use in source and binary forms, with or without
        !            33:  * modification, are permitted provided that the following conditions
        !            34:  * are met:
        !            35:  * 1. Redistributions of source code must retain the above copyright
        !            36:  *    notice, this list of conditions and the following disclaimer.
        !            37:  * 2. Redistributions in binary form must reproduce the above copyright
        !            38:  *    notice, this list of conditions and the following disclaimer in the
        !            39:  *    documentation and/or other materials provided with the distribution.
        !            40:  * 3. All advertising materials mentioning features or use of this software
        !            41:  *    must display the following acknowledgement:
        !            42:  *     This product includes software developed by the University of
        !            43:  *     California, Berkeley and its contributors.
        !            44:  * 4. Neither the name of the University nor the names of its contributors
        !            45:  *    may be used to endorse or promote products derived from this software
        !            46:  *    without specific prior written permission.
        !            47:  *
        !            48:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            49:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            50:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            51:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            52:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            53:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            54:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            55:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            56:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            57:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            58:  * SUCH DAMAGE.
        !            59:  *
        !            60:  *     @(#)pk_llcsubr.c        8.1 (Berkeley) 6/10/93
        !            61:  */
        !            62: 
        !            63: #include <sys/param.h>
        !            64: #include <sys/systm.h>
        !            65: #include <sys/mbuf.h>
        !            66: #include <sys/domain.h>
        !            67: #include <sys/socket.h>
        !            68: #include <sys/socketvar.h>
        !            69: #include <sys/protosw.h>
        !            70: #include <sys/errno.h>
        !            71: #include <sys/time.h>
        !            72: #include <sys/kernel.h>
        !            73: #include <sys/malloc.h>
        !            74: 
        !            75: #include <net/if.h>
        !            76: #include <net/if_dl.h>
        !            77: #include <net/if_llc.h>
        !            78: #include <net/if_types.h>
        !            79: #include <net/route.h>
        !            80: 
        !            81: #include <netccitt/dll.h>
        !            82: #include <netccitt/x25.h>
        !            83: #include <netccitt/pk.h>
        !            84: #include <netccitt/pk_var.h>
        !            85: #include <netccitt/llc_var.h>
        !            86: 
        !            87: 
        !            88: /*
        !            89:  * Routing support for X.25
        !            90:  *
        !            91:  * We distinguish between two cases:
        !            92:  * RTF_HOST:
        !            93:  *     rt_key(rt)      X.25 address of host
        !            94:  *     rt_gateway      SNPA (MAC+DLSAP) address of host
        !            95:  *     rt_llinfo       pkcb for rt_key(rt)
        !            96:  *
        !            97:  * RTF_GATEWAY
        !            98:  *     rt_key(rt)      X.25 address of host or suitably masked network
        !            99:  *     rt_gateway      X.25 address of next X.25 gateway (switch)
        !           100:  *     rt_llinfo       rtentry for rt_gateway address
        !           101:  *                     ought to be of type RTF_HOST
        !           102:  *
        !           103:  *
        !           104:  * Mapping of X.121 to pkcbs:
        !           105:  *
        !           106:  * HDLC uses the DTE-DCE model of X.25, therefore we need a many-to-one
        !           107:  * relationship, i.e.:
        !           108:  *     
        !           109:  *     {X.121_a, X.121_b, X.121_c, ..., X.121_i} -> pkcb_0
        !           110:  *
        !           111:  * LLC2 utilizes the DTE-DTE model of X.25, resulting effectively in a
        !           112:  * one-to-one relationship, i.e.:
        !           113:  *
        !           114:  *     {X.121_j}       ->      pkcb_1a
        !           115:  *     {X.121_k}       ->      pkcb_1b
        !           116:  *     ...
        !           117:  *     {X.121_q}       ->      pkcb_1q
        !           118:  * 
        !           119:  * It might make sense to allow a many-to-one relation for LLC2 also,
        !           120:  * 
        !           121:  *     {X.121_r, X.121_s, X.121_t, X.121_u} -> pkcb_2a
        !           122:  *
        !           123:  * This would make addresses X.121_[r-u] essentially aliases of one
        !           124:  * address ({X.121_[r-u]} would constitute a representative set).
        !           125:  *
        !           126:  * Each one-to-one relation must obviously be entered individually with
        !           127:  * a route add command, whereas a many-to-one relationship can be 
        !           128:  * either entered individually or generated by using a netmask.
        !           129:  * 
        !           130:  * To facilitate dealings the many-to-one case for LLC2 can only be
        !           131:  * established via a netmask.
        !           132:  *
        !           133:  */
        !           134: 
        !           135: #define XTRACTPKP(rt)  ((rt)->rt_flags & RTF_GATEWAY ? \
        !           136:                         ((rt)->rt_llinfo ? \
        !           137:                          (struct pkcb *) ((struct rtentry *)((rt)->rt_llinfo))->rt_llinfo : \
        !           138:                          (struct pkcb *) NULL) : \
        !           139:                         (struct pkcb *)((rt)->rt_llinfo))
        !           140: 
        !           141: #define equal(a1, a2) (bcmp((caddr_t)(a1), \
        !           142:                               (caddr_t)(a2), \
        !           143:                               (a1)->sa_len) == 0)
        !           144: #define XIFA(rt) ((struct x25_ifaddr *)((rt)->rt_ifa))
        !           145: #define SA(s) ((struct sockaddr *)s)
        !           146: 
        !           147: int
        !           148: cons_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *dst)
        !           149: {
        !           150:        register struct pkcb *pkp;
        !           151:        register int i;
        !           152:        register char one_to_one;
        !           153:        struct pkcb *pk_newlink();
        !           154:        struct rtentry *npaidb_enter();
        !           155: 
        !           156:        pkp = XTRACTPKP(rt);
        !           157: 
        !           158:        switch(cmd) {
        !           159:        case RTM_RESOLVE:
        !           160:        case RTM_ADD:
        !           161:                if (pkp) 
        !           162:                        return(EEXIST);
        !           163: 
        !           164:                if (rt->rt_flags & RTF_GATEWAY) {
        !           165:                        if (rt->rt_llinfo)
        !           166:                                RTFREE((struct rtentry *)rt->rt_llinfo);
        !           167:                        rt->rt_llinfo = (caddr_t) rtalloc1(rt->rt_gateway, 1);
        !           168:                        return(0);
        !           169:                }
        !           170:                /*
        !           171:                 * Assumptions: (1) ifnet structure is filled in
        !           172:                 *              (2) at least the pkcb created via 
        !           173:                 *                  x25config (ifconfig?) has been 
        !           174:                 *                  set up already.
        !           175:                 *              (3) HDLC interfaces have an if_type of 
        !           176:                 *                  IFT_X25{,DDN}, LLC2 interfaces 
        !           177:                 *                  anything else (any better way to 
        !           178:                 *                  do this?)
        !           179:                 *
        !           180:                 */
        !           181:                if (!rt->rt_ifa)
        !           182:                        return (ENETDOWN);
        !           183:        
        !           184:                /*      
        !           185:                 * We differentiate between dealing with a many-to-one
        !           186:                 * (HDLC: DTE-DCE) and a one-to-one (LLC2: DTE-DTE) 
        !           187:                 * relationship (by looking at the if type).
        !           188:                 *
        !           189:                 * Only in case of the many-to-one relationship (HDLC)
        !           190:                 * we set the ia->ia_pkcb pointer to the pkcb allocated
        !           191:                 * via pk_newlink() as we will use just that one pkcb for
        !           192:                 * future route additions (the rtentry->rt_llinfo pointer
        !           193:                 * points to the pkcb allocated for that route).
        !           194:                 *
        !           195:                 * In case of the one-to-one relationship (LLC2) we 
        !           196:                 * create a new pkcb (via pk_newlink()) for each new rtentry.
        !           197:                 * 
        !           198:                 * NOTE: Only in case of HDLC does ia->ia_pkcb point
        !           199:                 * to a pkcb, in the LLC2 case it doesn't (as we don't 
        !           200:                 * need it here)!
        !           201:                 */
        !           202:                one_to_one = ISISO8802(rt->rt_ifp);
        !           203: 
        !           204:                if (!(pkp = XIFA(rt)->ia_pkcb) && !one_to_one) 
        !           205:                        XIFA(rt)->ia_pkcb = pkp = 
        !           206:                                pk_newlink(XIFA(rt), (caddr_t) 0);
        !           207:                else if (one_to_one && 
        !           208:                         !equal(rt->rt_gateway, rt->rt_ifa->ifa_addr)) {
        !           209:                        pkp = pk_newlink(XIFA(rt), (caddr_t) 0);
        !           210:                        /*
        !           211:                         * We also need another route entry for mapping
        !           212:                         * MAC+LSAP->X.25 address
        !           213:                         */
        !           214:                        pkp->pk_llrt = npaidb_enter(rt->rt_gateway, rt_key(rt), rt, 0);
        !           215:                }
        !           216:                if (pkp) {
        !           217:                        if (!pkp->pk_rt)
        !           218:                                pkp->pk_rt = rt;
        !           219:                        pkp->pk_refcount++;
        !           220:                }
        !           221:                rt->rt_llinfo = (caddr_t) pkp;
        !           222: 
        !           223:                return(0);
        !           224: 
        !           225:        case RTM_DELETE:
        !           226:        {
        !           227:                /*
        !           228:                 * The pkp might be empty if we are dealing
        !           229:                 * with an interface route entry for LLC2, in this 
        !           230:                 * case we don't need to do anything ...
        !           231:                 */
        !           232:                if (pkp) {
        !           233:                        if ( rt->rt_flags & RTF_GATEWAY ) {
        !           234:                                if (rt->rt_llinfo)
        !           235:                                        RTFREE((struct rtentry *)rt->rt_llinfo);
        !           236:                                return(0);
        !           237:                        }
        !           238:                        
        !           239:                        if (pkp->pk_llrt)
        !           240:                                npaidb_destroy(pkp->pk_llrt);
        !           241: 
        !           242:                        pk_dellink (pkp);
        !           243:                        
        !           244:                        return(0);
        !           245:                }
        !           246:        }
        !           247:        }
        !           248: }
        !           249: 
        !           250: /*
        !           251:  * Network Protocol Addressing Information DataBase (npaidb) 
        !           252:  * 
        !           253:  * To speed up locating the entity dealing with an LLC packet use is made 
        !           254:  * of a routing tree. This npaidb routing tree is handled 
        !           255:  * by the normal rn_*() routines just like (almost) any other routing tree. 
        !           256:  * 
        !           257:  * The mapping being done by the npaidb_*() routines is as follows: 
        !           258:  * 
        !           259:  *     Key:       MAC,LSAP (enhancing struct sockaddr_dl) 
        !           260:  *     Gateway:   sockaddr_x25 (i.e. X.25 address - X.121 or NSAP) 
        !           261:  *     Llinfo:    npaidbentry { 
        !           262:  *                         struct llc_linkcb *npaidb_linkp; 
        !           263:  *                         struct rtentry *npaidb_rt; 
        !           264:  *                } 
        !           265:  * 
        !           266:  * Using the npaidbentry provided by llinfo we can then access 
        !           267:  * 
        !           268:  *       o the pkcb by using (struct pkcb *) (npaidb_rt->rt_llinfo)
        !           269:  *       o the linkcb via npaidb_linkp 
        !           270:  * 
        !           271:  * The following functions are provided 
        !           272:  * 
        !           273:  *       o npaidb_enter(struct sockaddr_dl *sdl, struct sockaddr_x25 *sx25, 
        !           274:  *                      struct struct llc_linkcb *link, struct rtentry *rt) 
        !           275:  * 
        !           276:  *       o npaidb_enrich(short type, caddr_t info) 
        !           277:  * 
        !           278:  */
        !           279: 
        !           280: struct sockaddr_dl npdl_netmask = {
        !           281:  sizeof(struct sockaddr_dl),                                   /* _len */
        !           282:  0,                                                            /* _family */
        !           283:  0,                                                            /* _index */
        !           284:  0,                                                            /* _type */
        !           285:  -1,                                                           /* _nlen */
        !           286:  -1,                                                           /* _alen */
        !           287:  -1,                                                           /* _slen */
        !           288:  { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},            /* _data */
        !           289: }; 
        !           290: struct sockaddr npdl_dummy;
        !           291: 
        !           292: int npdl_datasize = sizeof(struct sockaddr_dl)-
        !           293:                ((int)((caddr_t)&((struct sockaddr_dl *)0)->sdl_data[0]));
        !           294: 
        !           295: struct rtentry *
        !           296: npaidb_enter(struct sockaddr_dl *key, struct sockaddr *value,
        !           297:             struct rtentry *rt, struct llc_linkcb *link)
        !           298: {
        !           299:        struct rtentry *nprt; register int i;
        !           300: 
        !           301:        USES_AF_LINK_RTS;
        !           302: 
        !           303:        if ((nprt = rtalloc1(SA(key), 0)) == 0) {
        !           304:                register u_int size = sizeof(struct npaidbentry);
        !           305:                register u_char saploc = LLSAPLOC(key, rt->rt_ifp);
        !           306: 
        !           307:                /* 
        !           308:                 * set up netmask: LLC2 packets have the lowest bit set in
        !           309:                 * response packets (e.g. 0x7e for command packets, 0x7f for
        !           310:                 * response packets), to facilitate the lookup we use a netmask
        !           311:                 * of 11111110 for the SAP position. The remaining positions 
        !           312:                 * are zeroed out.
        !           313:                 */
        !           314:                npdl_netmask.sdl_data[saploc] = NPDL_SAPNETMASK;
        !           315:                bzero((caddr_t)&npdl_netmask.sdl_data[saploc+1], 
        !           316:                      npdl_datasize-saploc-1);
        !           317: 
        !           318:                if (value == 0)
        !           319:                        value = &npdl_dummy;
        !           320: 
        !           321:                /* now enter it */
        !           322:                rtrequest(RTM_ADD, SA(key), SA(value),
        !           323:                        SA(&npdl_netmask), 0, &nprt);
        !           324: 
        !           325:                /* and reset npdl_netmask */
        !           326:                for (i = saploc; i < npdl_datasize; i++)
        !           327:                        npdl_netmask.sdl_data[i] = -1;
        !           328: 
        !           329: //             nprt->rt_llinfo = malloc(size , M_PCB, M_WAITOK);
        !           330:                MALLOC(nprt->rt_llinfo, caddr_t, size , M_PCB, M_WAITOK);
        !           331:                if (nprt->rt_llinfo) {
        !           332:                        bzero (nprt->rt_llinfo, size);
        !           333:                        ((struct npaidbentry *) (nprt->rt_llinfo))->np_rt = rt;
        !           334:                }
        !           335:        } else nprt->rt_refcnt--;
        !           336:        return nprt;
        !           337: }
        !           338: 
        !           339: struct rtentry *
        !           340: npaidb_enrich(short type, caddr_t info, struct sockaddr_dl *sdl)
        !           341: {
        !           342:        struct rtentry *rt;
        !           343: 
        !           344:        USES_AF_LINK_RTS;
        !           345: 
        !           346:        if (rt = rtalloc1((struct sockaddr *)sdl, 0)) {
        !           347:                rt->rt_refcnt--;
        !           348:                switch (type) {
        !           349:                case NPAIDB_LINK:
        !           350:                        ((struct npaidbentry *)(rt->rt_llinfo))->np_link = 
        !           351:                                (struct llc_linkcb *) info;
        !           352:                        break;
        !           353:                }
        !           354:                return rt;
        !           355:        }               
        !           356: 
        !           357:        return ((struct rtentry *) 0);
        !           358: 
        !           359: }
        !           360: 
        !           361: npaidb_destroy(struct rtentry *rt)
        !           362: {
        !           363:        USES_AF_LINK_RTS;
        !           364: 
        !           365:        if (rt->rt_llinfo) 
        !           366:                FREE((caddr_t) rt->rt_llinfo, M_PCB);
        !           367:        return(rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt), 
        !           368:                         0, 0));
        !           369: }
        !           370: 
        !           371: 
        !           372: #if LLC
        !           373: /*
        !           374:  * Glue between X.25 and LLC2
        !           375:  */
        !           376: int
        !           377: x25_llcglue(int prc, struct sockaddr *addr)
        !           378: {
        !           379:        register struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)addr;
        !           380:        register struct x25_ifaddr *x25ifa;
        !           381:        struct dll_ctlinfo ctlinfo;
        !           382:        
        !           383:        if((x25ifa = (struct x25_ifaddr *)ifa_ifwithaddr(addr)) == 0)
        !           384:                return 0;
        !           385: 
        !           386:        ctlinfo.dlcti_cfg  =
        !           387:            (struct dllconfig *)(((struct sockaddr_x25 *)(&x25ifa->ia_xc))+1);
        !           388:        ctlinfo.dlcti_lsap = LLC_X25_LSAP;
        !           389: 
        !           390:        return ((int)llc_ctlinput(prc, addr, (caddr_t)&ctlinfo));
        !           391: }
        !           392: #endif /* LLC */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.