Annotation of kernel/bsd/netccitt/pk_llcsubr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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