Annotation of 43BSDReno/sys/netiso/iso.c, revision 1.1.1.1

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