Annotation of Net2/netiso/iso.c, revision 1.1.1.3

1.1       root        1: /*-
                      2:  * Copyright (c) 1991 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
1.1.1.3 ! root       33:  *     from: @(#)iso.c 7.14 (Berkeley) 6/27/91
        !            34:  *     iso.c,v 1.2 1993/05/20 05:27:13 cgd Exp
1.1       root       35:  */
                     36: 
                     37: /***********************************************************
                     38:                Copyright IBM Corporation 1987
                     39: 
                     40:                       All Rights Reserved
                     41: 
                     42: Permission to use, copy, modify, and distribute this software and its 
                     43: documentation for any purpose and without fee is hereby granted, 
                     44: provided that the above copyright notice appear in all copies and that
                     45: both that copyright notice and this permission notice appear in 
                     46: supporting documentation, and that the name of IBM not be
                     47: used in advertising or publicity pertaining to distribution of the
                     48: software without specific, written prior permission.  
                     49: 
                     50: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     51: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     52: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     53: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     54: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     55: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     56: SOFTWARE.
                     57: 
                     58: ******************************************************************/
                     59: 
                     60: /*
                     61:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     62:  */
                     63: /*
                     64:  * iso.c: miscellaneous routines to support the iso address family
                     65:  */
                     66: 
                     67: #include "types.h"
                     68: #include "param.h"
                     69: #include "ioctl.h"
                     70: #include "mbuf.h"
                     71: #include "domain.h"
                     72: #include "protosw.h"
                     73: #include "socket.h"
                     74: #include "socketvar.h"
                     75: #include "errno.h"
                     76: 
                     77: #include "../net/if.h"
                     78: #include "../net/route.h"
                     79: #include "../net/af.h"
                     80: 
                     81: #include "iso.h"
                     82: #include "iso_var.h"
                     83: #include "iso_snpac.h"
                     84: #include "iso_pcb.h"
                     85: #include "clnp.h"
                     86: #include "argo_debug.h"
                     87: 
                     88: #ifdef ISO
                     89: 
                     90: int    iso_interfaces = 0;             /* number of external interfaces */
                     91: extern struct ifnet loif;      /* loopback interface */
                     92: int ether_output(), llc_rtrequest();
                     93: 
                     94: 
                     95: /*
                     96:  * FUNCTION:           iso_init
                     97:  *
                     98:  * PURPOSE:                    initialize the iso address family
                     99:  *
                    100:  * RETURNS:                    nothing
                    101:  *
                    102:  * SIDE EFFECTS:       1) initializes the routing table.
                    103:  *
                    104:  *
                    105:  * NOTES:                      
                    106:  */
                    107: struct radix_node_head *iso_rnhead;
                    108: iso_init()
                    109: {
                    110:        static iso_init_done;
                    111: 
                    112:        if (iso_init_done == 0) {
                    113:                iso_init_done++;
                    114:                rn_inithead(&iso_rnhead, 48, AF_ISO);
                    115:        }
                    116: }
                    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("in_netof: isoa ");
                    421:                dump_buf(isoa, len);
                    422:                printf("in_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:                        MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
                    473:                                       M_IFADDR, M_WAITOK);
                    474:                        if (nia == (struct iso_ifaddr *)0)
                    475:                                return (ENOBUFS);
                    476:                        bzero((caddr_t)nia, sizeof(*nia));
                    477:                        if (ia = iso_ifaddr) {
                    478:                                for ( ; ia->ia_next; ia = ia->ia_next)
                    479:                                        ;
                    480:                                ia->ia_next = nia;
                    481:                        } else
                    482:                                iso_ifaddr = nia;
                    483:                        ia = nia;
                    484:                        if (ifa = ifp->if_addrlist) {
                    485:                                for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
                    486:                                        ;
                    487:                                ifa->ifa_next = (struct ifaddr *) ia;
                    488:                        } else
                    489:                                ifp->if_addrlist = (struct ifaddr *) ia;
                    490:                        ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
                    491:                        ia->ia_ifa.ifa_dstaddr
                    492:                                        = (struct sockaddr *)&ia->ia_dstaddr;
                    493:                        ia->ia_ifa.ifa_netmask
                    494:                                        = (struct sockaddr *)&ia->ia_sockmask;
                    495:                        ia->ia_ifp = ifp;
                    496:                        if (ifp != &loif)
                    497:                                iso_interfaces++;
                    498:                }
                    499:                break;
                    500: 
                    501: #define cmdbyte(x)     (((x) >> 8) & 0xff)
                    502:        default:
                    503:                if (cmdbyte(cmd) == 'a')
                    504:                        return (snpac_ioctl(so, cmd, data));
                    505:                if (ia == (struct iso_ifaddr *)0)
                    506:                        return (EADDRNOTAVAIL);
                    507:                break;
                    508:        }
                    509:        switch (cmd) {
                    510: 
                    511:        case SIOCGIFADDR_ISO:
                    512:                ifr->ifr_Addr = ia->ia_addr;
                    513:                break;
                    514: 
                    515:        case SIOCGIFDSTADDR_ISO:
                    516:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                    517:                        return (EINVAL);
                    518:                ifr->ifr_Addr = ia->ia_dstaddr;
                    519:                break;
                    520: 
                    521:        case SIOCGIFNETMASK_ISO:
                    522:                ifr->ifr_Addr = ia->ia_sockmask;
                    523:                break;
                    524: 
                    525:        case SIOCAIFADDR_ISO:
                    526:                maskIsNew = 0; hostIsNew = 1; error = 0;
                    527:                if (ia->ia_addr.siso_family == AF_ISO) {
                    528:                        if (ifra->ifra_addr.siso_len == 0) {
                    529:                                ifra->ifra_addr = ia->ia_addr;
                    530:                                hostIsNew = 0;
                    531:                        } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
                    532:                                hostIsNew = 0;
                    533:                }
                    534:                if (ifra->ifra_mask.siso_len) {
                    535:                        iso_ifscrub(ifp, ia);
                    536:                        ia->ia_sockmask = ifra->ifra_mask;
                    537:                        maskIsNew = 1;
                    538:                }
                    539:                if ((ifp->if_flags & IFF_POINTOPOINT) &&
                    540:                    (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
                    541:                        iso_ifscrub(ifp, ia);
                    542:                        ia->ia_dstaddr = ifra->ifra_dstaddr;
                    543:                        maskIsNew  = 1; /* We lie; but the effect's the same */
                    544:                }
                    545:                if (ifra->ifra_addr.siso_family == AF_ISO &&
                    546:                                            (hostIsNew || maskIsNew)) {
                    547:                        error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
                    548:                }
                    549:                if (ifra->ifra_snpaoffset)
                    550:                        ia->ia_snpaoffset = ifra->ifra_snpaoffset;
                    551:                return (error);
                    552: 
                    553:        case SIOCDIFADDR_ISO:
                    554:                iso_ifscrub(ifp, ia);
                    555:                if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
                    556:                        ifp->if_addrlist = ifa->ifa_next;
                    557:                else {
                    558:                        while (ifa->ifa_next &&
                    559:                               (ifa->ifa_next != (struct ifaddr *)ia))
                    560:                                    ifa = ifa->ifa_next;
                    561:                        if (ifa->ifa_next)
                    562:                            ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
                    563:                        else
                    564:                                printf("Couldn't unlink isoifaddr from ifp\n");
                    565:                }
                    566:                oia = ia;
                    567:                if (oia == (ia = iso_ifaddr)) {
                    568:                        iso_ifaddr = ia->ia_next;
                    569:                } else {
                    570:                        while (ia->ia_next && (ia->ia_next != oia)) {
                    571:                                ia = ia->ia_next;
                    572:                        }
                    573:                        if (ia->ia_next)
                    574:                            ia->ia_next = oia->ia_next;
                    575:                        else
                    576:                                printf("Didn't unlink isoifadr from list\n");
                    577:                }
                    578:                free((caddr_t)oia, M_IFADDR);
                    579:                break;
                    580: 
                    581:        default:
                    582:                if (ifp == 0 || ifp->if_ioctl == 0)
                    583:                        return (EOPNOTSUPP);
                    584:                return ((*ifp->if_ioctl)(ifp, cmd, data));
                    585:        }
                    586:        return (0);
                    587: }
                    588: 
                    589: /*
                    590:  * Delete any existing route for an interface.
                    591:  */
                    592: iso_ifscrub(ifp, ia)
                    593:        register struct ifnet *ifp;
                    594:        register struct iso_ifaddr *ia;
                    595: {
                    596:        int nsellength = ia->ia_addr.siso_tlen;
                    597:        if ((ia->ia_flags & IFA_ROUTE) == 0)
                    598:                return;
                    599:        ia->ia_addr.siso_tlen = 0;
                    600:        if (ifp->if_flags & IFF_LOOPBACK)
                    601:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
                    602:        else if (ifp->if_flags & IFF_POINTOPOINT)
                    603:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
                    604:        else {
                    605:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
                    606:        }
                    607:        ia->ia_addr.siso_tlen = nsellength;
                    608:        ia->ia_flags &= ~IFA_ROUTE;
                    609: }
                    610: 
                    611: /*
                    612:  * Initialize an interface's internet address
                    613:  * and routing table entry.
                    614:  */
                    615: iso_ifinit(ifp, ia, siso, scrub)
                    616:        register struct ifnet *ifp;
                    617:        register struct iso_ifaddr *ia;
                    618:        struct sockaddr_iso *siso;
                    619: {
                    620:        struct sockaddr_iso oldaddr;
                    621:        int s = splimp(), error, nsellength;
                    622: 
                    623:        oldaddr = ia->ia_addr;
                    624:        ia->ia_addr = *siso;
                    625:        /*
                    626:         * Give the interface a chance to initialize
                    627:         * if this is its first address,
                    628:         * and to validate the address if necessary.
                    629:         */
                    630:        if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
                    631:                splx(s);
                    632:                ia->ia_addr = oldaddr;
                    633:                return (error);
                    634:        }
                    635:        if (scrub) {
                    636:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
                    637:                iso_ifscrub(ifp, ia);
                    638:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
                    639:        }
                    640:        /* XXX -- The following is here temporarily out of laziness
                    641:           in not changing every ethernet driver's if_ioctl routine */
                    642:        if (ifp->if_output == ether_output) {
                    643:                ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
                    644:                ia->ia_ifa.ifa_flags |= RTF_CLONING;
                    645:                ia->ia_ifa.ifa_llinfolen = sizeof(struct llinfo_llc);
                    646:        }
                    647:        /*
                    648:         * Add route for the network.
                    649:         */
                    650:        nsellength = ia->ia_addr.siso_tlen;
                    651:        ia->ia_addr.siso_tlen = 0;
                    652:        if (ifp->if_flags & IFF_LOOPBACK) {
                    653:                ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
                    654:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
                    655:        } else if (ifp->if_flags & IFF_POINTOPOINT &&
                    656:                 ia->ia_dstaddr.siso_family == AF_ISO)
                    657:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
                    658:        else {
                    659:                rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
                    660:                        ia->ia_ifa.ifa_netmask);
                    661:                ia->ia_dstaddr.siso_nlen =
                    662:                        min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));
                    663:                error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
                    664:        }
                    665:        ia->ia_addr.siso_tlen = nsellength;
                    666:        ia->ia_flags |= IFA_ROUTE;
                    667:        splx(s);
                    668:        return (error);
                    669: }
                    670: #ifdef notdef
                    671: 
                    672: struct ifaddr *
                    673: iso_ifwithidi(addr)
                    674:        register struct sockaddr *addr;
                    675: {
                    676:        register struct ifnet *ifp;
                    677:        register struct ifaddr *ifa;
                    678:        register u_int af = addr->sa_family;
                    679: 
                    680:        if (af != AF_ISO)
                    681:                return (0);
                    682:        IFDEBUG(D_ROUTE)
                    683:                printf(">>> iso_ifwithidi addr\n");
                    684:                dump_isoaddr( (struct sockaddr_iso *)(addr));
                    685:                printf("\n");
                    686:        ENDDEBUG
                    687:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
                    688:                IFDEBUG(D_ROUTE)
                    689:                        printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
                    690:                ENDDEBUG
                    691:                for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
                    692:                        IFDEBUG(D_ROUTE)
                    693:                                printf("iso_ifwithidi address ");
                    694:                                dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
                    695:                        ENDDEBUG
                    696:                        if (ifa->ifa_addr->sa_family != addr->sa_family)
                    697:                                continue;
                    698: 
                    699: #define        IFA_SIS(ifa)\
                    700:        ((struct sockaddr_iso *)((ifa)->ifa_addr))
                    701: 
                    702:                        IFDEBUG(D_ROUTE)
                    703:                                printf(" af same, args to iso_eqtype:\n");
                    704:                                printf("0x%x ", IFA_SIS(ifa)->siso_addr);
                    705:                                printf(" 0x%x\n",
                    706:                                &(((struct sockaddr_iso *)addr)->siso_addr));
                    707:                        ENDDEBUG
                    708: 
                    709:                        if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), 
                    710:                                &(((struct sockaddr_iso *)addr)->siso_addr))) {
                    711:                                IFDEBUG(D_ROUTE)
                    712:                                        printf("ifa_ifwithidi: ifa found\n");
                    713:                                ENDDEBUG
                    714:                                return (ifa);
                    715:                        }
                    716:                        IFDEBUG(D_ROUTE)
                    717:                                printf(" iso_eqtype failed\n");
                    718:                        ENDDEBUG
                    719:                }
                    720:        }
                    721:        return ((struct ifaddr *)0);
                    722: }
                    723: 
                    724: #endif notdef
                    725: /*
                    726:  * FUNCTION:           iso_ck_addr
                    727:  *
                    728:  * PURPOSE:                    return true if the iso_addr passed is 
                    729:  *                                     within the legal size limit for an iso address.
                    730:  *
                    731:  * RETURNS:                    true or false
                    732:  *
                    733:  * SIDE EFFECTS:       
                    734:  *
                    735:  */
                    736: iso_ck_addr(isoa)
                    737: struct iso_addr        *isoa;  /* address to check */
                    738: {
                    739:        return (isoa->isoa_len <= 20);
                    740: 
                    741: }
                    742: 
                    743: #ifdef notdef
                    744: /*
                    745:  * FUNCTION:           iso_eqtype
                    746:  *
                    747:  * PURPOSE:                    Determine if two iso addresses are of the same type.
                    748:  *  This is flaky.  Really we should consider all type 47 addrs to be the
                    749:  *  same - but there do exist different structures for 47 addrs.
                    750:  *  Gosip adds a 3rd.
                    751:  *
                    752:  * RETURNS:                    true if the addresses are the same type
                    753:  *
                    754:  * SIDE EFFECTS:       
                    755:  *
                    756:  * NOTES:                      By type, I mean rfc986, t37, or osinet
                    757:  *
                    758:  *                                     This will first compare afis. If they match, then
                    759:  *                                     if the addr is not t37, the idis must be compared.
                    760:  */
                    761: iso_eqtype(isoaa, isoab)
                    762: struct iso_addr        *isoaa;         /* first addr to check */
                    763: struct iso_addr        *isoab;         /* other addr to check */
                    764: {
                    765:        if (isoaa->isoa_afi == isoab->isoa_afi) {
                    766:                if (isoaa->isoa_afi == AFI_37)
                    767:                        return(1);
                    768:                else 
                    769:                        return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
                    770:        }
                    771:        return(0);
                    772: }
                    773: #endif notdef
                    774: /*
                    775:  * FUNCTION:           iso_localifa()
                    776:  *
                    777:  * PURPOSE:                    Find an interface addresss having a given destination
                    778:  *                                     or at least matching the net.
                    779:  *
                    780:  * RETURNS:                    ptr to an interface address 
                    781:  *
                    782:  * SIDE EFFECTS:       
                    783:  *
                    784:  * NOTES:                      
                    785:  */
                    786: struct iso_ifaddr *
                    787: iso_localifa(siso)
                    788:        register struct sockaddr_iso *siso;
                    789: {
                    790:        register struct iso_ifaddr *ia;
                    791:        register char *cp1, *cp2, *cp3;
                    792:        register struct ifnet *ifp;
                    793:        struct iso_ifaddr *ia_maybe = 0;
                    794:        /*
                    795:         * We make one pass looking for both net matches and an exact
                    796:         * dst addr.
                    797:         */
                    798:        for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
                    799:                if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
                    800:                        continue;
                    801:                if (ifp->if_flags & IFF_POINTOPOINT) {
                    802:                        if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
                    803:                                SAME_ISOADDR(&ia->ia_dstaddr, siso))
                    804:                                return (ia);
                    805:                        else
                    806:                                if (SAME_ISOADDR(&ia->ia_addr, siso))
                    807:                                        ia_maybe = ia;
                    808:                        continue;
                    809:                }
                    810:                if (ia->ia_sockmask.siso_len) {
                    811:                        char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
                    812:                        cp1 = ia->ia_sockmask.siso_data;
                    813:                        cp2 = siso->siso_data;
                    814:                        cp3 = ia->ia_addr.siso_data;
                    815:                        while (cp1 < cplim)
                    816:                                if (*cp1++ & (*cp2++ ^ *cp3++))
                    817:                                        goto next;
                    818:                        ia_maybe = ia;
                    819:                }
                    820:                if (SAME_ISOADDR(&ia->ia_addr, siso))
                    821:                        return ia;
                    822:        next:;
                    823:        }
                    824:        return ia_maybe;
                    825: }
                    826: 
                    827: #ifdef TPCONS
                    828: #include "cons.h"
                    829: #endif TPCONS
                    830: /*
                    831:  * FUNCTION:           iso_nlctloutput
                    832:  *
                    833:  * PURPOSE:                    Set options at the network level
                    834:  *
                    835:  * RETURNS:                    E*
                    836:  *
                    837:  * SIDE EFFECTS:       
                    838:  *
                    839:  * NOTES:                      This could embody some of the functions of
                    840:  *                                     rclnp_ctloutput and cons_ctloutput.
                    841:  */
                    842: iso_nlctloutput(cmd, optname, pcb, m)
                    843: int                    cmd;            /* command:set or get */
                    844: int                    optname;        /* option of interest */
                    845: caddr_t                pcb;            /* nl pcb */
                    846: struct mbuf    *m;                     /* data for set, buffer for get */
                    847: {
                    848:        struct isopcb   *isop = (struct isopcb *)pcb;
                    849:        int                             error = 0;      /* return value */
                    850:        caddr_t                 data;           /* data for option */
                    851:        int                             data_len;       /* data's length */
                    852: 
                    853:        IFDEBUG(D_ISO)
                    854:                printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
                    855:                        cmd, optname, pcb, m);
                    856:        ENDDEBUG
                    857: 
                    858:        if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
                    859:                return(EOPNOTSUPP);
                    860: 
                    861:        data = mtod(m, caddr_t);
                    862:        data_len = (m)->m_len;
                    863: 
                    864:        IFDEBUG(D_ISO)
                    865:                printf("iso_nlctloutput: data is:\n");
                    866:                dump_buf(data, data_len);
                    867:        ENDDEBUG
                    868: 
                    869:        switch (optname) {
                    870: 
                    871: #ifdef TPCONS
                    872:                case CONSOPT_X25CRUD:
                    873:                        if (cmd == PRCO_GETOPT) {
                    874:                                error = EOPNOTSUPP;
                    875:                                break;
                    876:                        }
                    877: 
                    878:                        if (data_len > MAXX25CRUDLEN) {
                    879:                                error = EINVAL;
                    880:                                break;
                    881:                        }
                    882: 
                    883:                        IFDEBUG(D_ISO)
                    884:                                printf("iso_nlctloutput: setting x25 crud\n");
                    885:                        ENDDEBUG
                    886: 
                    887:                        bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
                    888:                        isop->isop_x25crud_len = data_len;
                    889:                        break;
                    890: #endif TPCONS
                    891: 
                    892:                default:
                    893:                        error = EOPNOTSUPP;
                    894:        }
                    895: 
                    896:        return error;
                    897: }
                    898: #endif ISO
                    899: 
                    900: #ifdef ARGO_DEBUG
                    901: 
                    902: /*
                    903:  * FUNCTION:           dump_isoaddr
                    904:  *
                    905:  * PURPOSE:                    debugging
                    906:  *
                    907:  * RETURNS:                    nada 
                    908:  *
                    909:  */
                    910: dump_isoaddr(s)
                    911:        struct sockaddr_iso *s;
                    912: {
                    913:        char *clnp_saddr_isop();
                    914:        register int i;
                    915: 
                    916:        if( s->siso_family == AF_ISO) {
                    917:                printf("ISO address: suffixlen %d, %s\n",
                    918:                        s->siso_tlen, clnp_saddr_isop(s));
                    919:        } else if( s->siso_family == AF_INET) {
                    920:                /* hack */
                    921:                struct sockaddr_in *sin = (struct sockaddr_in *)s;
                    922: 
                    923:                printf("%d.%d.%d.%d: %d", 
                    924:                        (sin->sin_addr.s_addr>>24)&0xff,
                    925:                        (sin->sin_addr.s_addr>>16)&0xff,
                    926:                        (sin->sin_addr.s_addr>>8)&0xff,
                    927:                        (sin->sin_addr.s_addr)&0xff,
                    928:                        sin->sin_port);
                    929:        }
                    930: }
                    931: 
                    932: #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.