Annotation of kernel/bsd/netiso/iso.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) 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.