Annotation of XNU/bsd/netiso/iso.c, revision 1.1.1.1

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