Annotation of kernel/bsd/netiso/iso.c, revision 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) 1991, 1993
        !            27:  *     The Regents of the University of California.  All rights reserved.
        !            28:  *
        !            29:  * Redistribution and use in source and binary forms, with or without
        !            30:  * modification, are permitted provided that the following conditions
        !            31:  * are met:
        !            32:  * 1. Redistributions of source code must retain the above copyright
        !            33:  *    notice, this list of conditions and the following disclaimer.
        !            34:  * 2. Redistributions in binary form must reproduce the above copyright
        !            35:  *    notice, this list of conditions and the following disclaimer in the
        !            36:  *    documentation and/or other materials provided with the distribution.
        !            37:  * 3. All advertising materials mentioning features or use of this software
        !            38:  *    must display the following acknowledgement:
        !            39:  *     This product includes software developed by the University of
        !            40:  *     California, Berkeley and its contributors.
        !            41:  * 4. Neither the name of the University nor the names of its contributors
        !            42:  *    may be used to endorse or promote products derived from this software
        !            43:  *    without specific prior written permission.
        !            44:  *
        !            45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            55:  * SUCH DAMAGE.
        !            56:  *
        !            57:  *     @(#)iso.c       8.2 (Berkeley) 11/15/93
        !            58:  */
        !            59: 
        !            60: /***********************************************************
        !            61:                Copyright IBM Corporation 1987
        !            62: 
        !            63:                       All Rights Reserved
        !            64: 
        !            65: Permission to use, copy, modify, and distribute this software and its 
        !            66: documentation for any purpose and without fee is hereby granted, 
        !            67: provided that the above copyright notice appear in all copies and that
        !            68: both that copyright notice and this permission notice appear in 
        !            69: supporting documentation, and that the name of IBM not be
        !            70: used in advertising or publicity pertaining to distribution of the
        !            71: software without specific, written prior permission.  
        !            72: 
        !            73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            79: SOFTWARE.
        !            80: 
        !            81: ******************************************************************/
        !            82: 
        !            83: /*
        !            84:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
        !            85:  */
        !            86: /*
        !            87:  * iso.c: miscellaneous routines to support the iso address family
        !            88:  */
        !            89: 
        !            90: #include <sys/param.h>
        !            91: #include <sys/systm.h>
        !            92: #include <sys/ioctl.h>
        !            93: #include <sys/mbuf.h>
        !            94: #include <sys/domain.h>
        !            95: #include <sys/protosw.h>
        !            96: #include <sys/socket.h>
        !            97: #include <sys/socketvar.h>
        !            98: #include <sys/errno.h>
        !            99: #include <sys/malloc.h>
        !           100: 
        !           101: #include <net/if.h>
        !           102: #include <net/route.h>
        !           103: 
        !           104: #include <netiso/iso.h>
        !           105: #include <netiso/iso_var.h>
        !           106: #include <netiso/iso_snpac.h>
        !           107: #include <netiso/iso_pcb.h>
        !           108: #include <netiso/clnp.h>
        !           109: #include <netiso/argo_debug.h>
        !           110: #if TUBA
        !           111: #include <netiso/tuba_table.h>
        !           112: #endif
        !           113: 
        !           114: #if ISO
        !           115: 
        !           116: int    iso_interfaces = 0;             /* number of external interfaces */
        !           117: extern struct ifnet loif;      /* loopback interface */
        !           118: int    ether_output();
        !           119: void   llc_rtrequest();
        !           120: 
        !           121: /*
        !           122:  * FUNCTION:           iso_addrmatch1
        !           123:  *
        !           124:  * PURPOSE:                    decide if the two iso_addrs passed are equal
        !           125:  *
        !           126:  * RETURNS:                    true if the addrs match, false if they do not
        !           127:  *
        !           128:  * SIDE EFFECTS:       
        !           129:  *
        !           130:  * NOTES:                      
        !           131:  */
        !           132: iso_addrmatch1(isoaa, isoab)
        !           133: register struct iso_addr *isoaa, *isoab;               /* addresses to check */
        !           134: {
        !           135:        u_int   compare_len;
        !           136: 
        !           137:        IFDEBUG(D_ROUTE)
        !           138:                printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
        !           139:                        isoab->isoa_len);
        !           140:                printf("a:\n");
        !           141:                dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
        !           142:                printf("b:\n");
        !           143:                dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
        !           144:        ENDDEBUG
        !           145: 
        !           146:        if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
        !           147:                IFDEBUG(D_ROUTE)
        !           148:                        printf("iso_addrmatch1: returning false because of lengths\n");
        !           149:                ENDDEBUG
        !           150:                return 0;
        !           151:        }
        !           152:        
        !           153: #ifdef notdef
        !           154:        /* TODO : generalize this to all afis with masks */
        !           155:        if(     isoaa->isoa_afi == AFI_37 ) {
        !           156:                /* must not compare 2 least significant digits, or for
        !           157:                 * that matter, the DSP
        !           158:                 */
        !           159:                compare_len = ADDR37_IDI_LEN - 1; 
        !           160:        }
        !           161: #endif
        !           162: 
        !           163:        IFDEBUG(D_ROUTE)
        !           164:                int i;
        !           165:                char *a, *b;
        !           166: 
        !           167:                a = isoaa->isoa_genaddr;
        !           168:                b = isoab->isoa_genaddr;
        !           169: 
        !           170:                for (i=0; i<compare_len; i++) {
        !           171:                        printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
        !           172:                        if (a[i] != b[i]) {
        !           173:                                printf("\naddrs are not equal at byte %d\n", i);
        !           174:                                return(0);
        !           175:                        }
        !           176:                }
        !           177:                printf("\n");
        !           178:                printf("addrs are equal\n");
        !           179:                return (1);
        !           180:        ENDDEBUG
        !           181:        return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
        !           182: }
        !           183: 
        !           184: /*
        !           185:  * FUNCTION:           iso_addrmatch
        !           186:  *
        !           187:  * PURPOSE:                    decide if the two sockadrr_isos passed are equal
        !           188:  *
        !           189:  * RETURNS:                    true if the addrs match, false if they do not
        !           190:  *
        !           191:  * SIDE EFFECTS:       
        !           192:  *
        !           193:  * NOTES:                      
        !           194:  */
        !           195: iso_addrmatch(sisoa, sisob)
        !           196: struct sockaddr_iso    *sisoa, *sisob;         /* addresses to check */
        !           197: {
        !           198:        return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
        !           199: }
        !           200: #ifdef notdef
        !           201: /*
        !           202:  * FUNCTION:           iso_netmatch
        !           203:  *
        !           204:  * PURPOSE:                    similar to iso_addrmatch but takes sockaddr_iso
        !           205:  *                                     as argument.
        !           206:  *
        !           207:  * RETURNS:                    true if same net, false if not
        !           208:  *
        !           209:  * SIDE EFFECTS:       
        !           210:  *
        !           211:  * NOTES:                      
        !           212:  */
        !           213: iso_netmatch(sisoa, sisob)
        !           214: struct sockaddr_iso *sisoa, *sisob;
        !           215: {
        !           216:        u_char                  bufa[sizeof(struct sockaddr_iso)];
        !           217:        u_char                  bufb[sizeof(struct sockaddr_iso)];
        !           218:        register int    lena, lenb;
        !           219: 
        !           220:        lena = iso_netof(&sisoa->siso_addr, bufa);
        !           221:        lenb = iso_netof(&sisob->siso_addr, bufb);
        !           222: 
        !           223:        IFDEBUG(D_ROUTE)
        !           224:                printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
        !           225:                printf("a:\n");
        !           226:                dump_buf(bufa, lena);
        !           227:                printf("b:\n");
        !           228:                dump_buf(bufb, lenb);
        !           229:        ENDDEBUG
        !           230: 
        !           231:        return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
        !           232: }
        !           233: #endif /* notdef */
        !           234: 
        !           235: /*
        !           236:  * FUNCTION:           iso_hashchar
        !           237:  *
        !           238:  * PURPOSE:                    Hash all character in the buffer specified into
        !           239:  *                                     a long. Return the long.
        !           240:  *
        !           241:  * RETURNS:                    The hash value.
        !           242:  *
        !           243:  * SIDE EFFECTS:       
        !           244:  *
        !           245:  * NOTES:                      The hash is achieved by exclusive ORing 4 byte
        !           246:  *                                     quantities. 
        !           247:  */
        !           248: u_long
        !           249: iso_hashchar(buf, len)
        !           250: register caddr_t       buf;            /* buffer to pack from */
        !           251: register int           len;            /* length of buffer */
        !           252: {
        !           253:        register u_long h = 0;
        !           254:        register int    i;
        !           255: 
        !           256:        for (i=0; i<len; i+=4) {
        !           257:                register u_long l = 0;
        !           258: 
        !           259:                if ((len - i) < 4) {
        !           260:                        /* buffer not multiple of 4 */
        !           261:                        switch (len - i) {
        !           262:                                case 3:
        !           263:                                        l |= buf[i+2] << 8;
        !           264:                                case 2:
        !           265:                                        l |= buf[i+1] << 16;
        !           266:                                case 1:
        !           267:                                        l |= buf[i] << 24;
        !           268:                                        break;
        !           269:                                default:
        !           270:                                        printf("iso_hashchar: unexpected value x%x\n", len - i);
        !           271:                                        break;
        !           272:                        }
        !           273:                } else {
        !           274:                        l |= buf[i] << 24;
        !           275:                        l |= buf[i+1] << 16;
        !           276:                        l |= buf[i+2] << 8;
        !           277:                        l |= buf[i+3];
        !           278:                }
        !           279: 
        !           280:                h ^= l;
        !           281:        }
        !           282:        
        !           283:        h ^= (u_long) (len % 4);
        !           284: 
        !           285:        return(h);
        !           286: }
        !           287: #ifdef notdef
        !           288: /*
        !           289:  * FUNCTION:           iso_hash
        !           290:  *
        !           291:  * PURPOSE:                    Fill in fields of afhash structure based upon addr passed.
        !           292:  *
        !           293:  * RETURNS:                    none
        !           294:  *
        !           295:  * SIDE EFFECTS:       
        !           296:  *
        !           297:  * NOTES:                      
        !           298:  */
        !           299: iso_hash(siso, hp)
        !           300: struct sockaddr_iso    *siso;          /* address to perform hash on */
        !           301: struct afhash          *hp;            /* RETURN: hash info here */
        !           302: {
        !           303:        u_long                  buf[sizeof(struct sockaddr_iso)+1/4];
        !           304:        register int    bufsize;
        !           305: 
        !           306: 
        !           307:        bzero(buf, sizeof(buf));
        !           308: 
        !           309:        bufsize = iso_netof(&siso->siso_addr, buf);
        !           310:        hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
        !           311: 
        !           312:        IFDEBUG(D_ROUTE)
        !           313:                printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
        !           314:        ENDDEBUG
        !           315: 
        !           316:        hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr, 
        !           317:                siso->siso_addr.isoa_len);
        !           318: 
        !           319:        IFDEBUG(D_ROUTE)
        !           320:                printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
        !           321:                        clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, 
        !           322:                        hp->afh_hosthash);
        !           323:        ENDDEBUG
        !           324: }
        !           325: /*
        !           326:  * FUNCTION:           iso_netof
        !           327:  *
        !           328:  * PURPOSE:                    Extract the network portion of the iso address.
        !           329:  *                                     The network portion of the iso address varies depending
        !           330:  *                                     on the type of address. The network portion of the
        !           331:  *                                     address will include the IDP. The network portion is:
        !           332:  *                     
        !           333:  *                                             TYPE                    DESC
        !           334:  *                                     t37                                     The AFI and x.121 (IDI)
        !           335:  *                                     osinet                          The AFI, orgid, snetid
        !           336:  *                                     rfc986                          The AFI, vers and network part of
        !           337:  *                                                                             internet address.
        !           338:  *
        !           339:  * RETURNS:                    number of bytes placed into buf.
        !           340:  *
        !           341:  * SIDE EFFECTS:       
        !           342:  *
        !           343:  * NOTES:                      Buf is assumed to be big enough
        !           344:  */
        !           345: iso_netof(isoa, buf)
        !           346: struct iso_addr        *isoa;          /* address */
        !           347: caddr_t                        buf;            /* RESULT: network portion of address here */
        !           348: {
        !           349:        u_int           len = 1;        /* length of afi */
        !           350: 
        !           351:        switch (isoa->isoa_afi) {
        !           352:                case AFI_37:
        !           353:                        /*
        !           354:                         * Due to classic x.25 tunnel vision, there is no
        !           355:                         * net portion of an x.121 address.  For our purposes
        !           356:                         * the AFI will do, so that all x.25 -type addresses
        !           357:                         * map to the single x.25 SNPA. (Cannot have more than
        !           358:                         * one, obviously).
        !           359:                         */
        !           360: 
        !           361:                        break;
        !           362: 
        !           363: /*             case AFI_OSINET:*/
        !           364:                case AFI_RFC986: {
        !           365:                        u_short idi;    /* value of idi */
        !           366: 
        !           367:                        /* osinet and rfc986 have idi in the same place */
        !           368:                        CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
        !           369: 
        !           370:                        if (idi == IDI_OSINET)
        !           371: /*
        !           372:  *     Network portion of OSINET address can only be the IDI. Clearly,
        !           373:  *     with one x25 interface, one could get to several orgids, and
        !           374:  *     several snetids.
        !           375:                                len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN + 
        !           376:                                                OVLOSINET_SNETID_LEN);
        !           377:  */
        !           378:                                len += ADDROSINET_IDI_LEN;
        !           379:                        else if (idi == IDI_RFC986) {
        !           380:                                u_long                          inetaddr;
        !           381:                                struct ovl_rfc986       *o986 = (struct ovl_rfc986 *)isoa;
        !           382: 
        !           383:                                /* bump len to include idi and version (1 byte) */
        !           384:                                len += ADDRRFC986_IDI_LEN + 1;
        !           385: 
        !           386:                                /* get inet addr long aligned */
        !           387:                                bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
        !           388:                                inetaddr = ntohl(inetaddr);     /* convert to host byte order */
        !           389: 
        !           390:                                IFDEBUG(D_ROUTE)
        !           391:                                        printf("iso_netof: isoa ");
        !           392:                                        dump_buf(isoa, sizeof(*isoa));
        !           393:                                        printf("iso_netof: inetaddr 0x%x ", inetaddr);
        !           394:                                ENDDEBUG
        !           395: 
        !           396:                                /* bump len by size of network portion of inet address */
        !           397:                                if (IN_CLASSA(inetaddr)) {
        !           398:                                        len += 4-IN_CLASSA_NSHIFT/8;
        !           399:                                        IFDEBUG(D_ROUTE)
        !           400:                                                printf("iso_netof: class A net len is now %d\n", len);
        !           401:                                        ENDDEBUG
        !           402:                                } else if (IN_CLASSB(inetaddr)) {
        !           403:                                        len += 4-IN_CLASSB_NSHIFT/8;
        !           404:                                        IFDEBUG(D_ROUTE)
        !           405:                                                printf("iso_netof: class B net len is now %d\n", len);
        !           406:                                        ENDDEBUG
        !           407:                                } else {
        !           408:                                        len += 4-IN_CLASSC_NSHIFT/8;
        !           409:                                        IFDEBUG(D_ROUTE)
        !           410:                                                printf("iso_netof: class C net len is now %d\n", len);
        !           411:                                        ENDDEBUG
        !           412:                                }
        !           413:                        } else
        !           414:                                len = 0;
        !           415:                } break;
        !           416: 
        !           417:                default:
        !           418:                        len = 0;
        !           419:        }
        !           420: 
        !           421:        bcopy((caddr_t)isoa, buf, len);
        !           422:        IFDEBUG(D_ROUTE)
        !           423:                printf("iso_netof: isoa ");
        !           424:                dump_buf(isoa, len);
        !           425:                printf("iso_netof: net ");
        !           426:                dump_buf(buf, len);
        !           427:        ENDDEBUG
        !           428:        return len;
        !           429: }
        !           430: #endif /* notdef */
        !           431: /*
        !           432:  * Generic iso control operations (ioctl's).
        !           433:  * Ifp is 0 if not an interface-specific ioctl.
        !           434:  */
        !           435: /* ARGSUSED */
        !           436: iso_control(so, cmd, data, ifp)
        !           437:        struct socket *so;
        !           438:        int cmd;
        !           439:        caddr_t data;
        !           440:        register struct ifnet *ifp;
        !           441: {
        !           442:        register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
        !           443:        register struct iso_ifaddr *ia = 0;
        !           444:        register struct ifaddr *ifa;
        !           445:        struct iso_ifaddr *oia;
        !           446:        struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
        !           447:        int error, hostIsNew, maskIsNew;
        !           448: 
        !           449:        /*
        !           450:         * Find address for this interface, if it exists.
        !           451:         */
        !           452:        if (ifp)
        !           453:                for (ia = iso_ifaddr; ia; ia = ia->ia_next)
        !           454:                        if (ia->ia_ifp == ifp)
        !           455:                                break;
        !           456: 
        !           457:        switch (cmd) {
        !           458: 
        !           459:        case SIOCAIFADDR_ISO:
        !           460:        case SIOCDIFADDR_ISO:
        !           461:                if (ifra->ifra_addr.siso_family == AF_ISO)
        !           462:                    for (oia = ia; ia; ia = ia->ia_next) {
        !           463:                        if (ia->ia_ifp == ifp  &&
        !           464:                            SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
        !           465:                                break;
        !           466:                }
        !           467:                if ((so->so_state & SS_PRIV) == 0)
        !           468:                        return (EPERM);
        !           469:                if (ifp == 0)
        !           470:                        panic("iso_control");
        !           471:                if (ia == (struct iso_ifaddr *)0) {
        !           472:                        struct iso_ifaddr *nia;
        !           473:                        if (cmd == SIOCDIFADDR_ISO)
        !           474:                                return (EADDRNOTAVAIL);
        !           475: #if TUBA
        !           476:                        /* XXXXXX can't be done in the proto init routines */
        !           477:                        if (tuba_tree == 0)
        !           478:                                tuba_table_init();
        !           479: #endif
        !           480:                        MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
        !           481:                                       M_IFADDR, M_WAITOK);
        !           482:                        if (nia == (struct iso_ifaddr *)0)
        !           483:                                return (ENOBUFS);
        !           484:                        bzero((caddr_t)nia, sizeof(*nia));
        !           485:                        if (ia = iso_ifaddr) {
        !           486:                                for ( ; ia->ia_next; ia = ia->ia_next)
        !           487:                                        ;
        !           488:                                ia->ia_next = nia;
        !           489:                        } else
        !           490:                                iso_ifaddr = nia;
        !           491:                        ia = nia;
        !           492:                        if (ifa = ifp->if_addrlist) {
        !           493:                                for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
        !           494:                                        ;
        !           495:                                ifa->ifa_next = (struct ifaddr *) ia;
        !           496:                        } else
        !           497:                                ifp->if_addrlist = (struct ifaddr *) ia;
        !           498:                        ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
        !           499:                        ia->ia_ifa.ifa_dstaddr
        !           500:                                        = (struct sockaddr *)&ia->ia_dstaddr;
        !           501:                        ia->ia_ifa.ifa_netmask
        !           502:                                        = (struct sockaddr *)&ia->ia_sockmask;
        !           503:                        ia->ia_ifp = ifp;
        !           504:                        if (ifp != &loif)
        !           505:                                iso_interfaces++;
        !           506:                }
        !           507:                break;
        !           508: 
        !           509: #define cmdbyte(x)     (((x) >> 8) & 0xff)
        !           510:        default:
        !           511:                if (cmdbyte(cmd) == 'a')
        !           512:                        return (snpac_ioctl(so, cmd, data));
        !           513:                if (ia == (struct iso_ifaddr *)0)
        !           514:                        return (EADDRNOTAVAIL);
        !           515:                break;
        !           516:        }
        !           517:        switch (cmd) {
        !           518: 
        !           519:        case SIOCGIFADDR_ISO:
        !           520:                ifr->ifr_Addr = ia->ia_addr;
        !           521:                break;
        !           522: 
        !           523:        case SIOCGIFDSTADDR_ISO:
        !           524:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
        !           525:                        return (EINVAL);
        !           526:                ifr->ifr_Addr = ia->ia_dstaddr;
        !           527:                break;
        !           528: 
        !           529:        case SIOCGIFNETMASK_ISO:
        !           530:                ifr->ifr_Addr = ia->ia_sockmask;
        !           531:                break;
        !           532: 
        !           533:        case SIOCAIFADDR_ISO:
        !           534:                maskIsNew = 0; hostIsNew = 1; error = 0;
        !           535:                if (ia->ia_addr.siso_family == AF_ISO) {
        !           536:                        if (ifra->ifra_addr.siso_len == 0) {
        !           537:                                ifra->ifra_addr = ia->ia_addr;
        !           538:                                hostIsNew = 0;
        !           539:                        } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
        !           540:                                hostIsNew = 0;
        !           541:                }
        !           542:                if (ifra->ifra_mask.siso_len) {
        !           543:                        iso_ifscrub(ifp, ia);
        !           544:                        ia->ia_sockmask = ifra->ifra_mask;
        !           545:                        maskIsNew = 1;
        !           546:                }
        !           547:                if ((ifp->if_flags & IFF_POINTOPOINT) &&
        !           548:                    (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
        !           549:                        iso_ifscrub(ifp, ia);
        !           550:                        ia->ia_dstaddr = ifra->ifra_dstaddr;
        !           551:                        maskIsNew  = 1; /* We lie; but the effect's the same */
        !           552:                }
        !           553:                if (ifra->ifra_addr.siso_family == AF_ISO &&
        !           554:                                            (hostIsNew || maskIsNew)) {
        !           555:                        error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
        !           556:                }
        !           557:                if (ifra->ifra_snpaoffset)
        !           558:                        ia->ia_snpaoffset = ifra->ifra_snpaoffset;
        !           559:                return (error);
        !           560: 
        !           561:        case SIOCDIFADDR_ISO:
        !           562:                iso_ifscrub(ifp, ia);
        !           563:                if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
        !           564:                        ifp->if_addrlist = ifa->ifa_next;
        !           565:                else {
        !           566:                        while (ifa->ifa_next &&
        !           567:                               (ifa->ifa_next != (struct ifaddr *)ia))
        !           568:                                    ifa = ifa->ifa_next;
        !           569:                        if (ifa->ifa_next)
        !           570:                            ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
        !           571:                        else
        !           572:                                printf("Couldn't unlink isoifaddr from ifp\n");
        !           573:                }
        !           574:                oia = ia;
        !           575:                if (oia == (ia = iso_ifaddr)) {
        !           576:                        iso_ifaddr = ia->ia_next;
        !           577:                } else {
        !           578:                        while (ia->ia_next && (ia->ia_next != oia)) {
        !           579:                                ia = ia->ia_next;
        !           580:                        }
        !           581:                        if (ia->ia_next)
        !           582:                            ia->ia_next = oia->ia_next;
        !           583:                        else
        !           584:                                printf("Didn't unlink isoifadr from list\n");
        !           585:                }
        !           586:                IFAFREE((&oia->ia_ifa));
        !           587:                break;
        !           588: 
        !           589:        default:
        !           590:                if (ifp == 0 || ifp->if_ioctl == 0)
        !           591:                        return (EOPNOTSUPP);
        !           592:                return ((*ifp->if_ioctl)(ifp, cmd, data));
        !           593:        }
        !           594:        return (0);
        !           595: }
        !           596: 
        !           597: /*
        !           598:  * Delete any existing route for an interface.
        !           599:  */
        !           600: iso_ifscrub(ifp, ia)
        !           601:        register struct ifnet *ifp;
        !           602:        register struct iso_ifaddr *ia;
        !           603: {
        !           604:        int nsellength = ia->ia_addr.siso_tlen;
        !           605:        if ((ia->ia_flags & IFA_ROUTE) == 0)
        !           606:                return;
        !           607:        ia->ia_addr.siso_tlen = 0;
        !           608:        if (ifp->if_flags & IFF_LOOPBACK)
        !           609:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
        !           610:        else if (ifp->if_flags & IFF_POINTOPOINT)
        !           611:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
        !           612:        else {
        !           613:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
        !           614:        }
        !           615:        ia->ia_addr.siso_tlen = nsellength;
        !           616:        ia->ia_flags &= ~IFA_ROUTE;
        !           617: }
        !           618: 
        !           619: /*
        !           620:  * Initialize an interface's internet address
        !           621:  * and routing table entry.
        !           622:  */
        !           623: iso_ifinit(ifp, ia, siso, scrub)
        !           624:        register struct ifnet *ifp;
        !           625:        register struct iso_ifaddr *ia;
        !           626:        struct sockaddr_iso *siso;
        !           627: {
        !           628:        struct sockaddr_iso oldaddr;
        !           629:        int s = splimp(), error, nsellength;
        !           630: 
        !           631:        oldaddr = ia->ia_addr;
        !           632:        ia->ia_addr = *siso;
        !           633:        /*
        !           634:         * Give the interface a chance to initialize
        !           635:         * if this is its first address,
        !           636:         * and to validate the address if necessary.
        !           637:         */
        !           638:        if (ifp->if_ioctl &&
        !           639:                                (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
        !           640:                splx(s);
        !           641:                ia->ia_addr = oldaddr;
        !           642:                return (error);
        !           643:        }
        !           644:        if (scrub) {
        !           645:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
        !           646:                iso_ifscrub(ifp, ia);
        !           647:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
        !           648:        }
        !           649:        /* XXX -- The following is here temporarily out of laziness
        !           650:           in not changing every ethernet driver's if_ioctl routine */
        !           651:        if (ifp->if_output == ether_output) {
        !           652:                ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
        !           653:                ia->ia_ifa.ifa_flags |= RTF_CLONING;
        !           654:        }
        !           655:        /*
        !           656:         * Add route for the network.
        !           657:         */
        !           658:        nsellength = ia->ia_addr.siso_tlen;
        !           659:        ia->ia_addr.siso_tlen = 0;
        !           660:        if (ifp->if_flags & IFF_LOOPBACK) {
        !           661:                ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
        !           662:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
        !           663:        } else if (ifp->if_flags & IFF_POINTOPOINT &&
        !           664:                 ia->ia_dstaddr.siso_family == AF_ISO)
        !           665:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
        !           666:        else {
        !           667:                rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
        !           668:                        ia->ia_ifa.ifa_netmask);
        !           669:                ia->ia_dstaddr.siso_nlen =
        !           670:                        min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));
        !           671:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
        !           672:        }
        !           673:        ia->ia_addr.siso_tlen = nsellength;
        !           674:        ia->ia_flags |= IFA_ROUTE;
        !           675:        splx(s);
        !           676:        return (error);
        !           677: }
        !           678: #ifdef notdef
        !           679: 
        !           680: struct ifaddr *
        !           681: iso_ifwithidi(addr)
        !           682:        register struct sockaddr *addr;
        !           683: {
        !           684:        register struct ifnet *ifp;
        !           685:        register struct ifaddr *ifa;
        !           686:        register u_int af = addr->sa_family;
        !           687: 
        !           688:        if (af != AF_ISO)
        !           689:                return (0);
        !           690:        IFDEBUG(D_ROUTE)
        !           691:                printf(">>> iso_ifwithidi addr\n");
        !           692:                dump_isoaddr( (struct sockaddr_iso *)(addr));
        !           693:                printf("\n");
        !           694:        ENDDEBUG
        !           695:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        !           696:                IFDEBUG(D_ROUTE)
        !           697:                        printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
        !           698:                ENDDEBUG
        !           699:                for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
        !           700:                        IFDEBUG(D_ROUTE)
        !           701:                                printf("iso_ifwithidi address ");
        !           702:                                dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
        !           703:                        ENDDEBUG
        !           704:                        if (ifa->ifa_addr->sa_family != addr->sa_family)
        !           705:                                continue;
        !           706: 
        !           707: #define        IFA_SIS(ifa)\
        !           708:        ((struct sockaddr_iso *)((ifa)->ifa_addr))
        !           709: 
        !           710:                        IFDEBUG(D_ROUTE)
        !           711:                                printf(" af same, args to iso_eqtype:\n");
        !           712:                                printf("0x%x ", IFA_SIS(ifa)->siso_addr);
        !           713:                                printf(" 0x%x\n",
        !           714:                                &(((struct sockaddr_iso *)addr)->siso_addr));
        !           715:                        ENDDEBUG
        !           716: 
        !           717:                        if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), 
        !           718:                                &(((struct sockaddr_iso *)addr)->siso_addr))) {
        !           719:                                IFDEBUG(D_ROUTE)
        !           720:                                        printf("ifa_ifwithidi: ifa found\n");
        !           721:                                ENDDEBUG
        !           722:                                return (ifa);
        !           723:                        }
        !           724:                        IFDEBUG(D_ROUTE)
        !           725:                                printf(" iso_eqtype failed\n");
        !           726:                        ENDDEBUG
        !           727:                }
        !           728:        }
        !           729:        return ((struct ifaddr *)0);
        !           730: }
        !           731: 
        !           732: #endif /* notdef */
        !           733: /*
        !           734:  * FUNCTION:           iso_ck_addr
        !           735:  *
        !           736:  * PURPOSE:                    return true if the iso_addr passed is 
        !           737:  *                                     within the legal size limit for an iso address.
        !           738:  *
        !           739:  * RETURNS:                    true or false
        !           740:  *
        !           741:  * SIDE EFFECTS:       
        !           742:  *
        !           743:  */
        !           744: iso_ck_addr(isoa)
        !           745: struct iso_addr        *isoa;  /* address to check */
        !           746: {
        !           747:        return (isoa->isoa_len <= 20);
        !           748: 
        !           749: }
        !           750: 
        !           751: #ifdef notdef
        !           752: /*
        !           753:  * FUNCTION:           iso_eqtype
        !           754:  *
        !           755:  * PURPOSE:                    Determine if two iso addresses are of the same type.
        !           756:  *  This is flaky.  Really we should consider all type 47 addrs to be the
        !           757:  *  same - but there do exist different structures for 47 addrs.
        !           758:  *  Gosip adds a 3rd.
        !           759:  *
        !           760:  * RETURNS:                    true if the addresses are the same type
        !           761:  *
        !           762:  * SIDE EFFECTS:       
        !           763:  *
        !           764:  * NOTES:                      By type, I mean rfc986, t37, or osinet
        !           765:  *
        !           766:  *                                     This will first compare afis. If they match, then
        !           767:  *                                     if the addr is not t37, the idis must be compared.
        !           768:  */
        !           769: iso_eqtype(isoaa, isoab)
        !           770: struct iso_addr        *isoaa;         /* first addr to check */
        !           771: struct iso_addr        *isoab;         /* other addr to check */
        !           772: {
        !           773:        if (isoaa->isoa_afi == isoab->isoa_afi) {
        !           774:                if (isoaa->isoa_afi == AFI_37)
        !           775:                        return(1);
        !           776:                else 
        !           777:                        return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
        !           778:        }
        !           779:        return(0);
        !           780: }
        !           781: #endif /* notdef */
        !           782: /*
        !           783:  * FUNCTION:           iso_localifa()
        !           784:  *
        !           785:  * PURPOSE:                    Find an interface addresss having a given destination
        !           786:  *                                     or at least matching the net.
        !           787:  *
        !           788:  * RETURNS:                    ptr to an interface address 
        !           789:  *
        !           790:  * SIDE EFFECTS:       
        !           791:  *
        !           792:  * NOTES:                      
        !           793:  */
        !           794: struct iso_ifaddr *
        !           795: iso_localifa(siso)
        !           796:        register struct sockaddr_iso *siso;
        !           797: {
        !           798:        register struct iso_ifaddr *ia;
        !           799:        register char *cp1, *cp2, *cp3;
        !           800:        register struct ifnet *ifp;
        !           801:        struct iso_ifaddr *ia_maybe = 0;
        !           802:        /*
        !           803:         * We make one pass looking for both net matches and an exact
        !           804:         * dst addr.
        !           805:         */
        !           806:        for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
        !           807:                if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
        !           808:                        continue;
        !           809:                if (ifp->if_flags & IFF_POINTOPOINT) {
        !           810:                        if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
        !           811:                                SAME_ISOADDR(&ia->ia_dstaddr, siso))
        !           812:                                return (ia);
        !           813:                        else
        !           814:                                if (SAME_ISOADDR(&ia->ia_addr, siso))
        !           815:                                        ia_maybe = ia;
        !           816:                        continue;
        !           817:                }
        !           818:                if (ia->ia_sockmask.siso_len) {
        !           819:                        char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
        !           820:                        cp1 = ia->ia_sockmask.siso_data;
        !           821:                        cp2 = siso->siso_data;
        !           822:                        cp3 = ia->ia_addr.siso_data;
        !           823:                        while (cp1 < cplim)
        !           824:                                if (*cp1++ & (*cp2++ ^ *cp3++))
        !           825:                                        goto next;
        !           826:                        ia_maybe = ia;
        !           827:                }
        !           828:                if (SAME_ISOADDR(&ia->ia_addr, siso))
        !           829:                        return ia;
        !           830:        next:;
        !           831:        }
        !           832:        return ia_maybe;
        !           833: }
        !           834: 
        !           835: #if    TPCONS
        !           836: #include <netiso/cons.h>
        !           837: #endif /* TPCONS */
        !           838: /*
        !           839:  * FUNCTION:           iso_nlctloutput
        !           840:  *
        !           841:  * PURPOSE:                    Set options at the network level
        !           842:  *
        !           843:  * RETURNS:                    E*
        !           844:  *
        !           845:  * SIDE EFFECTS:       
        !           846:  *
        !           847:  * NOTES:                      This could embody some of the functions of
        !           848:  *                                     rclnp_ctloutput and cons_ctloutput.
        !           849:  */
        !           850: iso_nlctloutput(cmd, optname, pcb, m)
        !           851: int                    cmd;            /* command:set or get */
        !           852: int                    optname;        /* option of interest */
        !           853: caddr_t                pcb;            /* nl pcb */
        !           854: struct mbuf    *m;                     /* data for set, buffer for get */
        !           855: {
        !           856:        struct isopcb   *isop = (struct isopcb *)pcb;
        !           857:        int                             error = 0;      /* return value */
        !           858:        caddr_t                 data;           /* data for option */
        !           859:        int                             data_len;       /* data's length */
        !           860: 
        !           861:        IFDEBUG(D_ISO)
        !           862:                printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
        !           863:                        cmd, optname, pcb, m);
        !           864:        ENDDEBUG
        !           865: 
        !           866:        if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
        !           867:                return(EOPNOTSUPP);
        !           868: 
        !           869:        data = mtod(m, caddr_t);
        !           870:        data_len = (m)->m_len;
        !           871: 
        !           872:        IFDEBUG(D_ISO)
        !           873:                printf("iso_nlctloutput: data is:\n");
        !           874:                dump_buf(data, data_len);
        !           875:        ENDDEBUG
        !           876: 
        !           877:        switch (optname) {
        !           878: 
        !           879: #if    TPCONS
        !           880:                case CONSOPT_X25CRUD:
        !           881:                        if (cmd == PRCO_GETOPT) {
        !           882:                                error = EOPNOTSUPP;
        !           883:                                break;
        !           884:                        }
        !           885: 
        !           886:                        if (data_len > MAXX25CRUDLEN) {
        !           887:                                error = EINVAL;
        !           888:                                break;
        !           889:                        }
        !           890: 
        !           891:                        IFDEBUG(D_ISO)
        !           892:                                printf("iso_nlctloutput: setting x25 crud\n");
        !           893:                        ENDDEBUG
        !           894: 
        !           895:                        bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
        !           896:                        isop->isop_x25crud_len = data_len;
        !           897:                        break;
        !           898: #endif /* TPCONS */
        !           899: 
        !           900:                default:
        !           901:                        error = EOPNOTSUPP;
        !           902:        }
        !           903:        if (cmd == PRCO_SETOPT)
        !           904:                m_freem(m);
        !           905:        return error;
        !           906: }
        !           907: #endif /* ISO */
        !           908: 
        !           909: #ifdef ARGO_DEBUG
        !           910: 
        !           911: /*
        !           912:  * FUNCTION:           dump_isoaddr
        !           913:  *
        !           914:  * PURPOSE:                    debugging
        !           915:  *
        !           916:  * RETURNS:                    nada 
        !           917:  *
        !           918:  */
        !           919: dump_isoaddr(s)
        !           920:        struct sockaddr_iso *s;
        !           921: {
        !           922:        char *clnp_saddr_isop();
        !           923:        register int i;
        !           924: 
        !           925:        if( s->siso_family == AF_ISO) {
        !           926:                printf("ISO address: suffixlen %d, %s\n",
        !           927:                        s->siso_tlen, clnp_saddr_isop(s));
        !           928:        } else if( s->siso_family == AF_INET) {
        !           929:                /* hack */
        !           930:                struct sockaddr_in *sin = (struct sockaddr_in *)s;
        !           931: 
        !           932:                printf("%d.%d.%d.%d: %d", 
        !           933:                        (sin->sin_addr.s_addr>>24)&0xff,
        !           934:                        (sin->sin_addr.s_addr>>16)&0xff,
        !           935:                        (sin->sin_addr.s_addr>>8)&0xff,
        !           936:                        (sin->sin_addr.s_addr)&0xff,
        !           937:                        sin->sin_port);
        !           938:        }
        !           939: }
        !           940: 
        !           941: #endif /* ARGO_DEBUG */

unix.superglobalmegacorp.com

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