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

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