Annotation of 43BSDReno/sys/netiso/iso_pcb.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_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $
                     29:  * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $
                     30:  *     @(#)iso_pcb.c   7.7 (Berkeley) 4/16/90
                     31:  *
                     32:  * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
                     33:  */
                     34: 
                     35: #ifndef lint
                     36: static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $";
                     37: #endif
                     38: 
                     39: #ifdef ISO
                     40: 
                     41: #include "param.h"
                     42: #include "systm.h"
                     43: #include "user.h"
                     44: #include "mbuf.h"
                     45: #include "socket.h"
                     46: #include "socketvar.h"
                     47: #include "argo_debug.h"
                     48: #include "iso.h"
                     49: #include "clnp.h"
                     50: #include "../netinet/in_systm.h"
                     51: #include "../net/if.h"
                     52: #include "../net/route.h"
                     53: #include "iso_pcb.h"
                     54: #include "iso_var.h"
                     55: #include "protosw.h"
                     56: 
                     57: #define PCBNULL (struct isopcb *)0
                     58: struct iso_addr zeroiso_addr = {
                     59:        0
                     60: };
                     61: 
                     62: 
                     63: /*
                     64:  * FUNCTION:           iso_pcballoc
                     65:  *
                     66:  * PURPOSE:                    creates an isopcb structure in an mbuf,
                     67:  *                                     with socket (so), and 
                     68:  *                                     puts it in the queue with head (head)
                     69:  *
                     70:  * RETURNS:                    0 if OK, ENOBUFS if can't alloc the necessary mbuf
                     71:  */
                     72: int
                     73: iso_pcballoc(so, head)
                     74:        struct socket *so;
                     75:        struct isopcb *head;
                     76: {
                     77:        register struct isopcb *isop;
                     78: 
                     79:        IFDEBUG(D_ISO)
                     80:                printf("iso_pcballoc(so 0x%x)\n", so);
                     81:        ENDDEBUG
                     82:        MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT);
                     83:        if (isop == NULL)
                     84:                return ENOBUFS;
                     85:        bzero((caddr_t)isop, sizeof(*isop));
                     86:        isop->isop_head = head;
                     87:        isop->isop_socket = so;
                     88:        insque(isop, head);
                     89:        so->so_pcb = (caddr_t)isop;
                     90:        return 0;
                     91: }
                     92:        
                     93: /*
                     94:  * FUNCTION:           iso_pcbbind
                     95:  *
                     96:  * PURPOSE:                    binds the address given in *(nam) to the socket
                     97:  *                                     specified by the isopcb in *(isop)
                     98:  *                                     If the given address is zero, it makes sure the
                     99:  *                                     address isn't already in use and if it's got a network
                    100:  *                                     portion, we look for an interface with that network
                    101:  *                                     address.  If the address given is zero, we allocate
                    102:  *                                     a port and stuff it in the (nam) structure.
                    103:  *
                    104:  * RETURNS:                    errno E* or 0 if ok.
                    105:  *
                    106:  * SIDE EFFECTS:       increments head->isop_lport if it allocates a port #
                    107:  *
                    108:  * NOTES:                      
                    109:  */
                    110: #define        satosiso(sa)    ((struct sockaddr_iso *)(sa))
                    111: int
                    112: iso_pcbbind(isop, nam)
                    113:        register struct isopcb *isop;
                    114:        struct mbuf *nam;
                    115: {
                    116:        register struct isopcb *head = isop->isop_head;
                    117:        register struct sockaddr_iso *siso;
                    118:        struct iso_ifaddr *ia;
                    119:        union {
                    120:                char data[2];
                    121:                u_short s;
                    122:        } suf;
                    123: 
                    124:        IFDEBUG(D_ISO)
                    125:                printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam);
                    126:        ENDDEBUG
                    127:        suf.s = 0;
                    128:        if (iso_ifaddr == 0) /* any interfaces attached? */
                    129:                return EADDRNOTAVAIL;
                    130:        if (isop->isop_laddr)  /* already bound */
                    131:                return EADDRINUSE;
                    132:        if(nam == (struct mbuf *)0) {
                    133:                isop->isop_laddr = &isop->isop_sladdr;
                    134:                isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso);
                    135:                isop->isop_sladdr.siso_family = AF_ISO;
                    136:                isop->isop_sladdr.siso_tlen = 2;
                    137:                isop->isop_sladdr.siso_nlen = 0;
                    138:                isop->isop_sladdr.siso_slen = 0;
                    139:                isop->isop_sladdr.siso_plen = 0;
                    140:                goto noname;
                    141:        }
                    142:        siso = mtod(nam, struct sockaddr_iso *);
                    143:        IFDEBUG(D_ISO)
                    144:                printf("iso_pcbbind(name len 0x%x)\n", nam->m_len);
                    145:                printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr));
                    146:        ENDDEBUG
                    147:        /*
                    148:         * We would like sort of length check but since some OSI addrs
                    149:         * do not have fixed length, we can't really do much.
                    150:         * The ONLY thing we can say is that an osi addr has to have
                    151:         * at LEAST an afi and one more byte and had better fit into
                    152:         * a struct iso_addr.
                    153:         * However, in fact the size of the whole thing is a struct
                    154:         * sockaddr_iso, so probably this is what we should check for.
                    155:         */
                    156:        if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
                    157:                        return ENAMETOOLONG;
                    158:        }
                    159:        if (siso->siso_tlen) {
                    160:                        register char *cp = TSEL(siso);
                    161:                        suf.data[0] = cp[0];
                    162:                        suf.data[1] = cp[1];
                    163:        }
                    164:        if (siso->siso_nlen) {
                    165:                /* non-zero net addr- better match one of our interfaces */
                    166:                IFDEBUG(D_ISO)
                    167:                        printf("iso_pcbbind: bind to NOT zeroisoaddr\n");
                    168:                ENDDEBUG
                    169:                for (ia = iso_ifaddr; ia; ia = ia->ia_next) 
                    170:                        if (SAME_ISOADDR(siso, &ia->ia_addr))
                    171:                                break;
                    172:                if (ia == 0)
                    173:                        return EADDRNOTAVAIL;
                    174:        } 
                    175:        if (siso->siso_len <= sizeof (isop->isop_sladdr)) {
                    176:                isop->isop_laddr = &isop->isop_sladdr;
                    177:        } else {
                    178:                if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0)
                    179:                        return ENOBUFS;
                    180:                isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
                    181:        }
                    182:        bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
                    183:        if (suf.s || siso->siso_tlen != 2) {
                    184:                if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tlen <= 2) &&
                    185:                   (u.u_uid != 0))
                    186:                        return EACCES;
                    187:                if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
                    188:                        iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
                    189:                        return EADDRINUSE;
                    190:        } else {
                    191:                register char *cp;
                    192: noname:
                    193:                cp = TSEL(isop->isop_laddr);
                    194:        IFDEBUG(D_ISO)
                    195:                printf("iso_pcbbind noname\n");
                    196:        ENDDEBUG
                    197:                do {
                    198:                        if (head->isop_lport++ < ISO_PORT_RESERVED ||
                    199:                            head->isop_lport > ISO_PORT_USERRESERVED)
                    200:                                head->isop_lport = ISO_PORT_RESERVED;
                    201:                        suf.s = head->isop_lport;
                    202:                        cp[0] = suf.data[0];
                    203:                        cp[1] = suf.data[1];
                    204:                } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
                    205:        }
                    206:        IFDEBUG(D_ISO)
                    207:                printf("iso_pcbbind returns 0, suf 0x%x\n", suf);
                    208:        ENDDEBUG
                    209:        return 0;
                    210: }
                    211: /*
                    212:  * FUNCTION:           iso_pcbconnect
                    213:  *
                    214:  * PURPOSE:                    Make the isopcb (isop) look like it's connected.
                    215:  *                                     In other words, give it the peer address given in 
                    216:  *                                     the mbuf * (nam).   Make sure such a combination
                    217:  *                                     of local, peer addresses doesn't already exist
                    218:  *                                     for this protocol.  Internet mentality prevails here,
                    219:  *                                     wherein a src,dst pair uniquely identifies a connection.
                    220:  *                                     Both net address and port must be specified in argument 
                    221:  *                                     (nam).
                    222:  *                                     If we don't have a local address for this socket yet, 
                    223:  *                                     we pick one by calling iso_pcbbind().
                    224:  *
                    225:  * RETURNS:                    errno E* or 0 if ok.
                    226:  *
                    227:  * SIDE EFFECTS:       Looks up a route, which may cause one to be left
                    228:  *                                     in the isopcb.
                    229:  *
                    230:  * NOTES:                      
                    231:  */
                    232: int
                    233: iso_pcbconnect(isop, nam)
                    234:        register struct isopcb *isop;
                    235:        struct mbuf *nam;
                    236: {
                    237:        register struct sockaddr_iso    *siso = mtod(nam, struct sockaddr_iso *);
                    238:        int                                                             local_zero, error = 0;
                    239:        struct iso_ifaddr                               *ia;
                    240: 
                    241:        IFDEBUG(D_ISO)
                    242:                printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x",
                    243:                                        isop, isop->isop_socket, nam);
                    244:                printf("nam->m_len 0x%x), addr:\n", nam->m_len);
                    245:                dump_isoaddr(siso);
                    246:        ENDDEBUG
                    247:        if (nam->m_len < siso->siso_len)
                    248:                return EINVAL; 
                    249:        if (siso->siso_family != AF_ISO)
                    250:                return EAFNOSUPPORT;
                    251:        if (siso->siso_nlen == 0) {
                    252:                if (ia = iso_ifaddr) {
                    253:                        int nlen = ia->ia_addr.siso_nlen;
                    254:                        ovbcopy(TSEL(siso), nlen + TSEL(siso),
                    255:                                siso->siso_plen + siso->siso_tlen + siso->siso_slen);
                    256:                        bcopy((caddr_t)&ia->ia_addr.siso_addr,
                    257:                                  (caddr_t)&siso->siso_addr, nlen + 1);
                    258:                        /* includes siso->siso_nlen = nlen; */
                    259:                } else
                    260:                        return EADDRNOTAVAIL;
                    261:        }
                    262:        /*
                    263:         * Local zero means either not bound, or bound to a TSEL, but no
                    264:         * particular local interface.  So, if we want to send somebody
                    265:         * we need to choose a return address.
                    266:         */
                    267:        local_zero = 
                    268:                ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0));
                    269:        if (local_zero) {
                    270:                int flags;
                    271: 
                    272:                IFDEBUG(D_ISO)
                    273:                        printf("iso_pcbconnect localzero 1\n");
                    274:                ENDDEBUG
                    275:                /* 
                    276:                 * If route is known or can be allocated now,
                    277:                 * our src addr is taken from the i/f, else punt.
                    278:                 */
                    279:                flags = isop->isop_socket->so_options & SO_DONTROUTE;
                    280:                if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags,
                    281:                                                (struct sockaddr **)0, &ia))
                    282:                        return error;
                    283:                IFDEBUG(D_ISO)
                    284:                        printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x",
                    285:                                isop->isop_route.ro_rt);
                    286:                        printf(" ia 0x%x\n", ia);
                    287:                ENDDEBUG
                    288:        }
                    289:        IFDEBUG(D_ISO)
                    290:                printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 
                    291:                        isop, isop->isop_socket);
                    292:        ENDDEBUG
                    293:        if (local_zero) {
                    294:                int nlen, tlen, totlen; caddr_t oldtsel, newtsel;
                    295:                siso = isop->isop_laddr;
                    296:                if (siso == 0 || siso->siso_tlen == 0)
                    297:                        (void)iso_pcbbind(isop, (struct mbuf *)0);
                    298:                /*
                    299:                 * Here we have problem of squezeing in a definite network address
                    300:                 * into an existing sockaddr_iso, which in fact may not have room
                    301:                 * for it.  This gets messy.
                    302:                 */
                    303:                siso = isop->isop_laddr;
                    304:                oldtsel = TSEL(siso);
                    305:                tlen = siso->siso_tlen;
                    306:                nlen = ia->ia_addr.siso_nlen;
                    307:                totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]);
                    308:                if ((siso == &isop->isop_sladdr) &&
                    309:                        (totlen > sizeof(isop->isop_sladdr))) {
                    310:                        struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
                    311:                        if (m == 0)
                    312:                                        return ENOBUFS;
                    313:                        m->m_len = totlen;
                    314:                        isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);
                    315:                }
                    316:                siso->siso_nlen = ia->ia_addr.siso_nlen;
                    317:                newtsel = TSEL(siso);
                    318:                ovbcopy(oldtsel, newtsel, tlen);
                    319:                bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen);
                    320:                siso->siso_tlen = tlen;
                    321:                siso->siso_family = AF_ISO;
                    322:                siso->siso_len = totlen;
                    323:                siso = mtod(nam, struct sockaddr_iso *);
                    324:        }
                    325:        IFDEBUG(D_ISO)
                    326:                printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 
                    327:                        isop, isop->isop_socket);
                    328:        ENDDEBUG
                    329:        /*
                    330:         * If we had to allocate space to a previous big foreign address,
                    331:         * and for some reason we didn't free it, we reuse it knowing
                    332:         * that is going to be big enough, as sockaddrs are delivered in
                    333:         * 128 byte mbufs.
                    334:         * If the foreign address is small enough, we use default space;
                    335:         * otherwise, we grab an mbuf to copy into.
                    336:         */
                    337:        if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) {
                    338:                if (siso->siso_len <= sizeof(isop->isop_sfaddr))
                    339:                        isop->isop_faddr = &isop->isop_sfaddr;
                    340:                else {
                    341:                        struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
                    342:                        if (m == 0)
                    343:                                return ENOBUFS;
                    344:                        isop->isop_faddr = mtod(m, struct sockaddr_iso *);
                    345:                }
                    346:        }
                    347:        bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len);
                    348:        IFDEBUG(D_ISO)
                    349:                printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 
                    350:                        isop, isop->isop_socket);
                    351:                printf("iso_pcbconnect connected to addr:\n");
                    352:                dump_isoaddr(isop->isop_faddr);
                    353:                printf("iso_pcbconnect end: src addr:\n");
                    354:                dump_isoaddr(isop->isop_laddr);
                    355:        ENDDEBUG
                    356:        return 0;
                    357: }
                    358: 
                    359: /*
                    360:  * FUNCTION:           iso_pcbdisconnect()
                    361:  *
                    362:  * PURPOSE:                    washes away the peer address info so the socket
                    363:  *                                     appears to be disconnected.
                    364:  *                                     If there's no file descriptor associated with the socket
                    365:  *                                     it detaches the pcb.
                    366:  *
                    367:  * RETURNS:                    Nada.
                    368:  *
                    369:  * SIDE EFFECTS:       May detach the pcb.
                    370:  *
                    371:  * NOTES:                      
                    372:  */
                    373: void
                    374: iso_pcbdisconnect(isop)
                    375:        struct isopcb *isop;
                    376: {
                    377:        void iso_pcbdetach();
                    378:        register struct sockaddr_iso *siso;
                    379: 
                    380:        IFDEBUG(D_ISO)
                    381:                printf("iso_pcbdisconnect(isop 0x%x)\n", isop);
                    382:        ENDDEBUG
                    383:        /*
                    384:         * Preserver binding infnormation if already bound.
                    385:         */
                    386:        if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) {
                    387:                caddr_t otsel = TSEL(siso);
                    388:                siso->siso_nlen = 0;
                    389:                ovbcopy(otsel, TSEL(siso), siso->siso_tlen);
                    390:        }
                    391:        if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)
                    392:                m_freem(dtom(isop->isop_faddr));
                    393:        isop->isop_faddr = 0;
                    394:        if (isop->isop_socket->so_state & SS_NOFDREF)
                    395:                iso_pcbdetach(isop);
                    396: }
                    397: 
                    398: /*
                    399:  * FUNCTION:           iso_pcbdetach
                    400:  *
                    401:  * PURPOSE:                    detach the pcb at *(isop) from it's socket and free
                    402:  *                                     the mbufs associated with the pcb..
                    403:  *                                     Dequeues (isop) from its head.
                    404:  *
                    405:  * RETURNS:                    Nada.
                    406:  *
                    407:  * SIDE EFFECTS:       
                    408:  *
                    409:  * NOTES:                      
                    410:  */
                    411: void
                    412: iso_pcbdetach(isop)
                    413:        struct isopcb *isop;
                    414: {
                    415:        struct socket *so = isop->isop_socket;
                    416: 
                    417:        IFDEBUG(D_ISO)
                    418:                printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 
                    419:                        isop, isop->isop_socket, so);
                    420:        ENDDEBUG
                    421:        if (so ) { /* in the x.25 domain, we sometimes have no socket */
                    422:                so->so_pcb = 0;
                    423:                sofree(so); 
                    424:        }
                    425:        IFDEBUG(D_ISO)
                    426:                printf("iso_pcbdetach 2 \n");
                    427:        ENDDEBUG
                    428:        if (isop->isop_options)
                    429:                (void)m_free(isop->isop_options);
                    430:        IFDEBUG(D_ISO)
                    431:                printf("iso_pcbdetach 3 \n");
                    432:        ENDDEBUG
                    433:        if (isop->isop_route.ro_rt)
                    434:                rtfree(isop->isop_route.ro_rt);
                    435:        IFDEBUG(D_ISO)
                    436:                printf("iso_pcbdetach 3.1\n");
                    437:        ENDDEBUG
                    438:        if (isop->isop_clnpcache != NULL) {
                    439:                struct clnp_cache *clcp =
                    440:                        mtod(isop->isop_clnpcache, struct clnp_cache *);
                    441:                IFDEBUG(D_ISO)
                    442:                        printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 
                    443:                                clcp, clcp->clc_hdr);
                    444:                ENDDEBUG
                    445:                if (clcp->clc_hdr != NULL)
                    446:                        m_free(clcp->clc_hdr);
                    447:                IFDEBUG(D_ISO)
                    448:                        printf("iso_pcbdetach 3.3: freeing cache x%x\n", 
                    449:                                isop->isop_clnpcache);
                    450:                ENDDEBUG
                    451:                m_free(isop->isop_clnpcache);
                    452:        }
                    453:        IFDEBUG(D_ISO)
                    454:                printf("iso_pcbdetach 4 \n");
                    455:        ENDDEBUG
                    456:        remque(isop);
                    457:        IFDEBUG(D_ISO)
                    458:                printf("iso_pcbdetach 5 \n");
                    459:        ENDDEBUG
                    460:        if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))
                    461:                m_freem(dtom(isop->isop_laddr));
                    462:        free((caddr_t)isop, M_PCB);
                    463: }
                    464: 
                    465: 
                    466: /*
                    467:  * FUNCTION:           iso_pcbnotify
                    468:  *
                    469:  * PURPOSE:                    notify all connections in this protocol's queue (head)
                    470:  *                                     that have peer address (dst) of the problem (errno)
                    471:  *                                     by calling (notify) on the connections' isopcbs.
                    472:  *
                    473:  * RETURNS:                    Rien.
                    474:  *
                    475:  * SIDE EFFECTS:       
                    476:  *
                    477:  * NOTES:                      (notify) is called at splimp!
                    478:  */
                    479: void
                    480: iso_pcbnotify(head, siso, errno, notify)
                    481:        struct isopcb *head;
                    482:        register struct sockaddr_iso *siso;
                    483:        int errno, (*notify)();
                    484: {
                    485:        register struct isopcb *isop;
                    486:        int s = splimp();
                    487: 
                    488:        IFDEBUG(D_ISO)
                    489:                printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);
                    490:        ENDDEBUG
                    491:        for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
                    492:                if (isop->isop_socket == 0 || isop->isop_faddr == 0 ||
                    493:                        !SAME_ISOADDR(siso, isop->isop_faddr)) {
                    494:                        IFDEBUG(D_ISO)
                    495:                                printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,
                    496:                                        isop, isop->isop_socket);
                    497:                                printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr);
                    498:                                dump_isoaddr(isop->isop_faddr);
                    499:                        ENDDEBUG
                    500:                        continue;
                    501:                }
                    502:                if (errno) 
                    503:                        isop->isop_socket->so_error = errno;
                    504:                if (notify)
                    505:                        (*notify)(isop);
                    506:        }
                    507:        splx(s);
                    508:        IFDEBUG(D_ISO)
                    509:                printf("END OF iso_pcbnotify\n" );
                    510:        ENDDEBUG
                    511: }
                    512: 
                    513: 
                    514: /*
                    515:  * FUNCTION:           iso_pcblookup
                    516:  *
                    517:  * PURPOSE:                    looks for a given combination of (faddr), (fport),
                    518:  *                                     (lport), (laddr) in the queue named by (head).
                    519:  *                                     Argument (flags) is ignored.
                    520:  *
                    521:  * RETURNS:                    ptr to the isopcb if it finds a connection matching
                    522:  *                                     these arguments, o.w. returns zero.
                    523:  *
                    524:  * SIDE EFFECTS:       
                    525:  *
                    526:  * NOTES:                      
                    527:  */
                    528: struct isopcb *
                    529: iso_pcblookup(head, fportlen, fport, laddr)
                    530:        struct isopcb *head;
                    531:        register struct sockaddr_iso *laddr;
                    532:        caddr_t fport;
                    533:        int fportlen;
                    534: {
                    535:        register struct isopcb *isop;
                    536:        register caddr_t lp = TSEL(laddr);
                    537:        unsigned int llen = laddr->siso_tlen;
                    538: 
                    539:        IFDEBUG(D_ISO)
                    540:                printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 
                    541:                        head, laddr, fport);
                    542:        ENDDEBUG
                    543:        for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
                    544:                if (isop->isop_laddr == 0 || isop->isop_laddr == laddr)
                    545:                        continue;
                    546:                if (isop->isop_laddr->siso_tlen != llen)
                    547:                        continue;
                    548:                if (bcmp(lp, TSEL(isop->isop_laddr), llen))
                    549:                        continue;
                    550:                if (fportlen && isop->isop_faddr &&
                    551:                        bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen))
                    552:                        continue;
                    553:                /*      PHASE2
                    554:                 *      addrmatch1 should be iso_addrmatch(a, b, mask)
                    555:                 *      where mask is taken from isop->isop_laddrmask (new field)
                    556:                 *      isop_lnetmask will also be available in isop
                    557:                if (laddr != &zeroiso_addr &&
                    558:                        !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))
                    559:                        continue;
                    560:                */
                    561:                if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr)))
                    562:                        continue;
                    563:                return (isop);
                    564:        }
                    565:        return (struct isopcb *)0;
                    566: }
                    567: #endif ISO

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.