Annotation of XNU/bsd/netccitt/pk_llcsubr.c, revision 1.1.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.