Annotation of kernel/bsd/netiso/iso_pcb.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*-
        !            26:  * Copyright (c) 1991, 1993
        !            27:  *     The Regents of the University of California.  All rights reserved.
        !            28:  *
        !            29:  * Redistribution and use in source and binary forms, with or without
        !            30:  * modification, are permitted provided that the following conditions
        !            31:  * are met:
        !            32:  * 1. Redistributions of source code must retain the above copyright
        !            33:  *    notice, this list of conditions and the following disclaimer.
        !            34:  * 2. Redistributions in binary form must reproduce the above copyright
        !            35:  *    notice, this list of conditions and the following disclaimer in the
        !            36:  *    documentation and/or other materials provided with the distribution.
        !            37:  * 3. All advertising materials mentioning features or use of this software
        !            38:  *    must display the following acknowledgement:
        !            39:  *     This product includes software developed by the University of
        !            40:  *     California, Berkeley and its contributors.
        !            41:  * 4. Neither the name of the University nor the names of its contributors
        !            42:  *    may be used to endorse or promote products derived from this software
        !            43:  *    without specific prior written permission.
        !            44:  *
        !            45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            55:  * SUCH DAMAGE.
        !            56:  *
        !            57:  *     @(#)iso_pcb.c   8.1 (Berkeley) 6/10/93
        !            58:  */
        !            59: 
        !            60: /***********************************************************
        !            61:                Copyright IBM Corporation 1987
        !            62: 
        !            63:                       All Rights Reserved
        !            64: 
        !            65: Permission to use, copy, modify, and distribute this software and its 
        !            66: documentation for any purpose and without fee is hereby granted, 
        !            67: provided that the above copyright notice appear in all copies and that
        !            68: both that copyright notice and this permission notice appear in 
        !            69: supporting documentation, and that the name of IBM not be
        !            70: used in advertising or publicity pertaining to distribution of the
        !            71: software without specific, written prior permission.  
        !            72: 
        !            73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            79: SOFTWARE.
        !            80: 
        !            81: ******************************************************************/
        !            82: 
        !            83: /*
        !            84:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
        !            85:  */
        !            86: /*
        !            87:  * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
        !            88:  */
        !            89: 
        !            90: #if ISO
        !            91: 
        !            92: #include <sys/param.h>
        !            93: #include <sys/systm.h>
        !            94: #include <sys/mbuf.h>
        !            95: #include <sys/socket.h>
        !            96: #include <sys/socketvar.h>
        !            97: #include <sys/errno.h>
        !            98: 
        !            99: #include <netiso/argo_debug.h>
        !           100: #include <netiso/iso.h>
        !           101: #include <netiso/clnp.h>
        !           102: #include <netinet/in_systm.h>
        !           103: #include <net/if.h>
        !           104: #include <net/route.h>
        !           105: #include <netiso/iso_pcb.h>
        !           106: #include <netiso/iso_var.h>
        !           107: #include <sys/protosw.h>
        !           108: 
        !           109: #if TPCONS
        !           110: #include <netccitt/x25.h>
        !           111: #include <netccitt/pk.h>
        !           112: #include <netccitt/pk_var.h>
        !           113: #endif
        !           114: 
        !           115: #define PCBNULL (struct isopcb *)0
        !           116: struct iso_addr zeroiso_addr = {
        !           117:        0
        !           118: };
        !           119: 
        !           120: 
        !           121: /*
        !           122:  * FUNCTION:           iso_pcballoc
        !           123:  *
        !           124:  * PURPOSE:                    creates an isopcb structure in an mbuf,
        !           125:  *                                     with socket (so), and 
        !           126:  *                                     puts it in the queue with head (head)
        !           127:  *
        !           128:  * RETURNS:                    0 if OK, ENOBUFS if can't alloc the necessary mbuf
        !           129:  */
        !           130: int
        !           131: iso_pcballoc(so, head)
        !           132:        struct socket *so;
        !           133:        struct isopcb *head;
        !           134: {
        !           135:        register struct isopcb *isop;
        !           136: 
        !           137:        IFDEBUG(D_ISO)
        !           138:                printf("iso_pcballoc(so 0x%x)\n", so);
        !           139:        ENDDEBUG
        !           140:        MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT);
        !           141:        if (isop == NULL)
        !           142:                return ENOBUFS;
        !           143:        bzero((caddr_t)isop, sizeof(*isop));
        !           144:        isop->isop_head = head;
        !           145:        isop->isop_socket = so;
        !           146:        insque(isop, head);
        !           147:        if (so)
        !           148:                so->so_pcb = (caddr_t)isop;
        !           149:        return 0;
        !           150: }
        !           151:        
        !           152: /*
        !           153:  * FUNCTION:           iso_pcbbind
        !           154:  *
        !           155:  * PURPOSE:                    binds the address given in *(nam) to the socket
        !           156:  *                                     specified by the isopcb in *(isop)
        !           157:  *                                     If the given address is zero, it makes sure the
        !           158:  *                                     address isn't already in use and if it's got a network
        !           159:  *                                     portion, we look for an interface with that network
        !           160:  *                                     address.  If the address given is zero, we allocate
        !           161:  *                                     a port and stuff it in the (nam) structure.
        !           162:  *
        !           163:  * RETURNS:                    errno E* or 0 if ok.
        !           164:  *
        !           165:  * SIDE EFFECTS:       increments head->isop_lport if it allocates a port #
        !           166:  *
        !           167:  * NOTES:                      
        !           168:  */
        !           169: #define        satosiso(sa)    ((struct sockaddr_iso *)(sa))
        !           170: int
        !           171: iso_pcbbind(isop, nam)
        !           172:        register struct isopcb *isop;
        !           173:        struct mbuf *nam;
        !           174: {
        !           175:        register struct isopcb *head = isop->isop_head;
        !           176:        register struct sockaddr_iso *siso;
        !           177:        struct iso_ifaddr *ia;
        !           178:        union {
        !           179:                char data[2];
        !           180:                u_short s;
        !           181:        } suf;
        !           182: 
        !           183:        IFDEBUG(D_ISO)
        !           184:                printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam);
        !           185:        ENDDEBUG
        !           186:        suf.s = 0;
        !           187:        if (iso_ifaddr == 0) /* any interfaces attached? */
        !           188:                return EADDRNOTAVAIL;
        !           189:        if (isop->isop_laddr)  /* already bound */
        !           190:                return EADDRINUSE;
        !           191:        if(nam == (struct mbuf *)0) {
        !           192:                isop->isop_laddr = &isop->isop_sladdr;
        !           193:                isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso);
        !           194:                isop->isop_sladdr.siso_family = AF_ISO;
        !           195:                isop->isop_sladdr.siso_tlen = 2;
        !           196:                isop->isop_sladdr.siso_nlen = 0;
        !           197:                isop->isop_sladdr.siso_slen = 0;
        !           198:                isop->isop_sladdr.siso_plen = 0;
        !           199:                goto noname;
        !           200:        }
        !           201:        siso = mtod(nam, struct sockaddr_iso *);
        !           202:        IFDEBUG(D_ISO)
        !           203:                printf("iso_pcbbind(name len 0x%x)\n", nam->m_len);
        !           204:                printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr));
        !           205:        ENDDEBUG
        !           206:        /*
        !           207:         * We would like sort of length check but since some OSI addrs
        !           208:         * do not have fixed length, we can't really do much.
        !           209:         * The ONLY thing we can say is that an osi addr has to have
        !           210:         * at LEAST an afi and one more byte and had better fit into
        !           211:         * a struct iso_addr.
        !           212:         * However, in fact the size of the whole thing is a struct
        !           213:         * sockaddr_iso, so probably this is what we should check for.
        !           214:         */
        !           215:        if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
        !           216:                        return ENAMETOOLONG;
        !           217:        }
        !           218:        if (siso->siso_nlen) {
        !           219:                /* non-zero net addr- better match one of our interfaces */
        !           220:                IFDEBUG(D_ISO)
        !           221:                        printf("iso_pcbbind: bind to NOT zeroisoaddr\n");
        !           222:                ENDDEBUG
        !           223:                for (ia = iso_ifaddr; ia; ia = ia->ia_next) 
        !           224:                        if (SAME_ISOADDR(siso, &ia->ia_addr))
        !           225:                                break;
        !           226:                if (ia == 0)
        !           227:                        return EADDRNOTAVAIL;
        !           228:        } 
        !           229:        if (siso->siso_len <= sizeof (isop->isop_sladdr)) {
        !           230:                isop->isop_laddr = &isop->isop_sladdr;
        !           231:        } else {
        !           232:                if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0)
        !           233:                        return ENOBUFS;
        !           234:                isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
        !           235:        }
        !           236:        bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
        !           237:        if (siso->siso_tlen == 0)
        !           238:                goto noname;
        !           239:        if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
        !           240:                iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
        !           241:                return EADDRINUSE;
        !           242:        if (siso->siso_tlen <= 2) {
        !           243:                bcopy(TSEL(siso), suf.data, sizeof(suf.data));
        !           244:                suf.s = ntohs(suf.s);
        !           245:                if((suf.s < ISO_PORT_RESERVED) &&
        !           246:                   (isop->isop_socket->so_state && SS_PRIV) == 0)
        !           247:                        return EACCES;
        !           248:        } else {
        !           249:                register char *cp;
        !           250: noname:
        !           251:                cp = TSEL(isop->isop_laddr);
        !           252:        IFDEBUG(D_ISO)
        !           253:                printf("iso_pcbbind noname\n");
        !           254:        ENDDEBUG
        !           255:                do {
        !           256:                        if (head->isop_lport++ < ISO_PORT_RESERVED ||
        !           257:                            head->isop_lport > ISO_PORT_USERRESERVED)
        !           258:                                head->isop_lport = ISO_PORT_RESERVED;
        !           259:                        suf.s = htons(head->isop_lport);
        !           260:                        cp[0] = suf.data[0];
        !           261:                        cp[1] = suf.data[1];
        !           262:                } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
        !           263:        }
        !           264:        IFDEBUG(D_ISO)
        !           265:                printf("iso_pcbbind returns 0, suf 0x%x\n", suf);
        !           266:        ENDDEBUG
        !           267:        return 0;
        !           268: }
        !           269: /*
        !           270:  * FUNCTION:           iso_pcbconnect
        !           271:  *
        !           272:  * PURPOSE:                    Make the isopcb (isop) look like it's connected.
        !           273:  *                                     In other words, give it the peer address given in 
        !           274:  *                                     the mbuf * (nam).   Make sure such a combination
        !           275:  *                                     of local, peer addresses doesn't already exist
        !           276:  *                                     for this protocol.  Internet mentality prevails here,
        !           277:  *                                     wherein a src,dst pair uniquely identifies a connection.
        !           278:  *                                     Both net address and port must be specified in argument 
        !           279:  *                                     (nam).
        !           280:  *                                     If we don't have a local address for this socket yet, 
        !           281:  *                                     we pick one by calling iso_pcbbind().
        !           282:  *
        !           283:  * RETURNS:                    errno E* or 0 if ok.
        !           284:  *
        !           285:  * SIDE EFFECTS:       Looks up a route, which may cause one to be left
        !           286:  *                                     in the isopcb.
        !           287:  *
        !           288:  * NOTES:                      
        !           289:  */
        !           290: int
        !           291: iso_pcbconnect(isop, nam)
        !           292:        register struct isopcb *isop;
        !           293:        struct mbuf *nam;
        !           294: {
        !           295:        register struct sockaddr_iso    *siso = mtod(nam, struct sockaddr_iso *);
        !           296:        int                                                             local_zero, error = 0;
        !           297:        struct iso_ifaddr                               *ia;
        !           298: 
        !           299:        IFDEBUG(D_ISO)
        !           300:                printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x",
        !           301:                                        isop, isop->isop_socket, nam);
        !           302:                printf("nam->m_len 0x%x), addr:\n", nam->m_len);
        !           303:                dump_isoaddr(siso);
        !           304:        ENDDEBUG
        !           305:        if (nam->m_len < siso->siso_len)
        !           306:                return EINVAL; 
        !           307:        if (siso->siso_family != AF_ISO)
        !           308:                return EAFNOSUPPORT;
        !           309:        if (siso->siso_nlen == 0) {
        !           310:                if (ia = iso_ifaddr) {
        !           311:                        int nlen = ia->ia_addr.siso_nlen;
        !           312:                        ovbcopy(TSEL(siso), nlen + TSEL(siso),
        !           313:                                siso->siso_plen + siso->siso_tlen + siso->siso_slen);
        !           314:                        bcopy((caddr_t)&ia->ia_addr.siso_addr,
        !           315:                                  (caddr_t)&siso->siso_addr, nlen + 1);
        !           316:                        /* includes siso->siso_nlen = nlen; */
        !           317:                } else
        !           318:                        return EADDRNOTAVAIL;
        !           319:        }
        !           320:        /*
        !           321:         * Local zero means either not bound, or bound to a TSEL, but no
        !           322:         * particular local interface.  So, if we want to send somebody
        !           323:         * we need to choose a return address.
        !           324:         */
        !           325:        local_zero = 
        !           326:                ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0));
        !           327:        if (local_zero) {
        !           328:                int flags;
        !           329: 
        !           330:                IFDEBUG(D_ISO)
        !           331:                        printf("iso_pcbconnect localzero 1\n");
        !           332:                ENDDEBUG
        !           333:                /* 
        !           334:                 * If route is known or can be allocated now,
        !           335:                 * our src addr is taken from the i/f, else punt.
        !           336:                 */
        !           337:                flags = isop->isop_socket->so_options & SO_DONTROUTE;
        !           338:                if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags,
        !           339:                                                (struct sockaddr **)0, &ia))
        !           340:                        return error;
        !           341:                IFDEBUG(D_ISO)
        !           342:                        printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x",
        !           343:                                isop->isop_route.ro_rt);
        !           344:                        printf(" ia 0x%x\n", ia);
        !           345:                ENDDEBUG
        !           346:        }
        !           347:        IFDEBUG(D_ISO)
        !           348:                printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 
        !           349:                        isop, isop->isop_socket);
        !           350:        ENDDEBUG
        !           351:        if (local_zero) {
        !           352:                int nlen, tlen, totlen; caddr_t oldtsel, newtsel;
        !           353:                siso = isop->isop_laddr;
        !           354:                if (siso == 0 || siso->siso_tlen == 0)
        !           355:                        (void)iso_pcbbind(isop, (struct mbuf *)0);
        !           356:                /*
        !           357:                 * Here we have problem of squezeing in a definite network address
        !           358:                 * into an existing sockaddr_iso, which in fact may not have room
        !           359:                 * for it.  This gets messy.
        !           360:                 */
        !           361:                siso = isop->isop_laddr;
        !           362:                oldtsel = TSEL(siso);
        !           363:                tlen = siso->siso_tlen;
        !           364:                nlen = ia->ia_addr.siso_nlen;
        !           365:                totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]);
        !           366:                if ((siso == &isop->isop_sladdr) &&
        !           367:                        (totlen > sizeof(isop->isop_sladdr))) {
        !           368:                        struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
        !           369:                        if (m == 0)
        !           370:                                        return ENOBUFS;
        !           371:                        m->m_len = totlen;
        !           372:                        isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);
        !           373:                }
        !           374:                siso->siso_nlen = ia->ia_addr.siso_nlen;
        !           375:                newtsel = TSEL(siso);
        !           376:                ovbcopy(oldtsel, newtsel, tlen);
        !           377:                bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen);
        !           378:                siso->siso_tlen = tlen;
        !           379:                siso->siso_family = AF_ISO;
        !           380:                siso->siso_len = totlen;
        !           381:                siso = mtod(nam, struct sockaddr_iso *);
        !           382:        }
        !           383:        IFDEBUG(D_ISO)
        !           384:                printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 
        !           385:                        isop, isop->isop_socket);
        !           386:        ENDDEBUG
        !           387:        /*
        !           388:         * If we had to allocate space to a previous big foreign address,
        !           389:         * and for some reason we didn't free it, we reuse it knowing
        !           390:         * that is going to be big enough, as sockaddrs are delivered in
        !           391:         * 128 byte mbufs.
        !           392:         * If the foreign address is small enough, we use default space;
        !           393:         * otherwise, we grab an mbuf to copy into.
        !           394:         */
        !           395:        if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) {
        !           396:                if (siso->siso_len <= sizeof(isop->isop_sfaddr))
        !           397:                        isop->isop_faddr = &isop->isop_sfaddr;
        !           398:                else {
        !           399:                        struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
        !           400:                        if (m == 0)
        !           401:                                return ENOBUFS;
        !           402:                        isop->isop_faddr = mtod(m, struct sockaddr_iso *);
        !           403:                }
        !           404:        }
        !           405:        bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len);
        !           406:        IFDEBUG(D_ISO)
        !           407:                printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 
        !           408:                        isop, isop->isop_socket);
        !           409:                printf("iso_pcbconnect connected to addr:\n");
        !           410:                dump_isoaddr(isop->isop_faddr);
        !           411:                printf("iso_pcbconnect end: src addr:\n");
        !           412:                dump_isoaddr(isop->isop_laddr);
        !           413:        ENDDEBUG
        !           414:        return 0;
        !           415: }
        !           416: 
        !           417: /*
        !           418:  * FUNCTION:           iso_pcbdisconnect()
        !           419:  *
        !           420:  * PURPOSE:                    washes away the peer address info so the socket
        !           421:  *                                     appears to be disconnected.
        !           422:  *                                     If there's no file descriptor associated with the socket
        !           423:  *                                     it detaches the pcb.
        !           424:  *
        !           425:  * RETURNS:                    Nada.
        !           426:  *
        !           427:  * SIDE EFFECTS:       May detach the pcb.
        !           428:  *
        !           429:  * NOTES:                      
        !           430:  */
        !           431: void
        !           432: iso_pcbdisconnect(isop)
        !           433:        struct isopcb *isop;
        !           434: {
        !           435:        void iso_pcbdetach();
        !           436:        register struct sockaddr_iso *siso;
        !           437: 
        !           438:        IFDEBUG(D_ISO)
        !           439:                printf("iso_pcbdisconnect(isop 0x%x)\n", isop);
        !           440:        ENDDEBUG
        !           441:        /*
        !           442:         * Preserver binding infnormation if already bound.
        !           443:         */
        !           444:        if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) {
        !           445:                caddr_t otsel = TSEL(siso);
        !           446:                siso->siso_nlen = 0;
        !           447:                ovbcopy(otsel, TSEL(siso), siso->siso_tlen);
        !           448:        }
        !           449:        if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)
        !           450:                m_freem(dtom(isop->isop_faddr));
        !           451:        isop->isop_faddr = 0;
        !           452:        if (isop->isop_socket->so_state & SS_NOFDREF)
        !           453:                iso_pcbdetach(isop);
        !           454: }
        !           455: 
        !           456: /*
        !           457:  * FUNCTION:           iso_pcbdetach
        !           458:  *
        !           459:  * PURPOSE:                    detach the pcb at *(isop) from it's socket and free
        !           460:  *                                     the mbufs associated with the pcb..
        !           461:  *                                     Dequeues (isop) from its head.
        !           462:  *
        !           463:  * RETURNS:                    Nada.
        !           464:  *
        !           465:  * SIDE EFFECTS:       
        !           466:  *
        !           467:  * NOTES:                      
        !           468:  */
        !           469: void
        !           470: iso_pcbdetach(isop)
        !           471:        struct isopcb *isop;
        !           472: {
        !           473:        struct socket *so = isop->isop_socket;
        !           474: 
        !           475:        IFDEBUG(D_ISO)
        !           476:                printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 
        !           477:                        isop, isop->isop_socket, so);
        !           478:        ENDDEBUG
        !           479: #if TPCONS
        !           480:        if (isop->isop_chan) {
        !           481:                register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
        !           482:                if (--isop->isop_refcnt > 0)
        !           483:                        return;
        !           484:                if (lcp && lcp->lcd_state == DATA_TRANSFER) {
        !           485:                        lcp->lcd_upper = 0;
        !           486:                        lcp->lcd_upnext = 0;
        !           487:                        pk_disconnect(lcp);
        !           488:                }
        !           489:                isop->isop_chan = 0;
        !           490:        }
        !           491: #endif
        !           492:        if (so) { /* in the x.25 domain, we sometimes have no socket */
        !           493:                so->so_pcb = 0;
        !           494:                sofree(so); 
        !           495:        }
        !           496:        IFDEBUG(D_ISO)
        !           497:                printf("iso_pcbdetach 2 \n");
        !           498:        ENDDEBUG
        !           499:        if (isop->isop_options)
        !           500:                (void)m_free(isop->isop_options);
        !           501:        IFDEBUG(D_ISO)
        !           502:                printf("iso_pcbdetach 3 \n");
        !           503:        ENDDEBUG
        !           504:        if (isop->isop_route.ro_rt)
        !           505:                rtfree(isop->isop_route.ro_rt);
        !           506:        IFDEBUG(D_ISO)
        !           507:                printf("iso_pcbdetach 3.1\n");
        !           508:        ENDDEBUG
        !           509:        if (isop->isop_clnpcache != NULL) {
        !           510:                struct clnp_cache *clcp =
        !           511:                        mtod(isop->isop_clnpcache, struct clnp_cache *);
        !           512:                IFDEBUG(D_ISO)
        !           513:                        printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 
        !           514:                                clcp, clcp->clc_hdr);
        !           515:                ENDDEBUG
        !           516:                if (clcp->clc_hdr != NULL)
        !           517:                        m_free(clcp->clc_hdr);
        !           518:                IFDEBUG(D_ISO)
        !           519:                        printf("iso_pcbdetach 3.3: freeing cache x%x\n", 
        !           520:                                isop->isop_clnpcache);
        !           521:                ENDDEBUG
        !           522:                m_free(isop->isop_clnpcache);
        !           523:        }
        !           524:        IFDEBUG(D_ISO)
        !           525:                printf("iso_pcbdetach 4 \n");
        !           526:        ENDDEBUG
        !           527:        remque(isop);
        !           528:        IFDEBUG(D_ISO)
        !           529:                printf("iso_pcbdetach 5 \n");
        !           530:        ENDDEBUG
        !           531:        if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))
        !           532:                m_freem(dtom(isop->isop_laddr));
        !           533:        free((caddr_t)isop, M_PCB);
        !           534: }
        !           535: 
        !           536: 
        !           537: /*
        !           538:  * FUNCTION:           iso_pcbnotify
        !           539:  *
        !           540:  * PURPOSE:                    notify all connections in this protocol's queue (head)
        !           541:  *                                     that have peer address (dst) of the problem (errno)
        !           542:  *                                     by calling (notify) on the connections' isopcbs.
        !           543:  *
        !           544:  * RETURNS:                    Rien.
        !           545:  *
        !           546:  * SIDE EFFECTS:       
        !           547:  *
        !           548:  * NOTES:                      (notify) is called at splimp!
        !           549:  */
        !           550: void
        !           551: iso_pcbnotify(head, siso, errno, notify)
        !           552:        struct isopcb *head;
        !           553:        register struct sockaddr_iso *siso;
        !           554:        int errno, (*notify)();
        !           555: {
        !           556:        register struct isopcb *isop;
        !           557:        int s = splimp();
        !           558: 
        !           559:        IFDEBUG(D_ISO)
        !           560:                printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);
        !           561:        ENDDEBUG
        !           562:        for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
        !           563:                if (isop->isop_socket == 0 || isop->isop_faddr == 0 ||
        !           564:                        !SAME_ISOADDR(siso, isop->isop_faddr)) {
        !           565:                        IFDEBUG(D_ISO)
        !           566:                                printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,
        !           567:                                        isop, isop->isop_socket);
        !           568:                                printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr);
        !           569:                                dump_isoaddr(isop->isop_faddr);
        !           570:                        ENDDEBUG
        !           571:                        continue;
        !           572:                }
        !           573:                if (errno) 
        !           574:                        isop->isop_socket->so_error = errno;
        !           575:                if (notify)
        !           576:                        (*notify)(isop);
        !           577:        }
        !           578:        splx(s);
        !           579:        IFDEBUG(D_ISO)
        !           580:                printf("END OF iso_pcbnotify\n" );
        !           581:        ENDDEBUG
        !           582: }
        !           583: 
        !           584: 
        !           585: /*
        !           586:  * FUNCTION:           iso_pcblookup
        !           587:  *
        !           588:  * PURPOSE:                    looks for a given combination of (faddr), (fport),
        !           589:  *                                     (lport), (laddr) in the queue named by (head).
        !           590:  *                                     Argument (flags) is ignored.
        !           591:  *
        !           592:  * RETURNS:                    ptr to the isopcb if it finds a connection matching
        !           593:  *                                     these arguments, o.w. returns zero.
        !           594:  *
        !           595:  * SIDE EFFECTS:       
        !           596:  *
        !           597:  * NOTES:                      
        !           598:  */
        !           599: struct isopcb *
        !           600: iso_pcblookup(head, fportlen, fport, laddr)
        !           601:        struct isopcb *head;
        !           602:        register struct sockaddr_iso *laddr;
        !           603:        caddr_t fport;
        !           604:        int fportlen;
        !           605: {
        !           606:        register struct isopcb *isop;
        !           607:        register caddr_t lp = TSEL(laddr);
        !           608:        unsigned int llen = laddr->siso_tlen;
        !           609: 
        !           610:        IFDEBUG(D_ISO)
        !           611:                printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 
        !           612:                        head, laddr, fport);
        !           613:        ENDDEBUG
        !           614:        for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
        !           615:                if (isop->isop_laddr == 0 || isop->isop_laddr == laddr)
        !           616:                        continue;
        !           617:                if (isop->isop_laddr->siso_tlen != llen)
        !           618:                        continue;
        !           619:                if (bcmp(lp, TSEL(isop->isop_laddr), llen))
        !           620:                        continue;
        !           621:                if (fportlen && isop->isop_faddr &&
        !           622:                        bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen))
        !           623:                        continue;
        !           624:                /*      PHASE2
        !           625:                 *      addrmatch1 should be iso_addrmatch(a, b, mask)
        !           626:                 *      where mask is taken from isop->isop_laddrmask (new field)
        !           627:                 *      isop_lnetmask will also be available in isop
        !           628:                if (laddr != &zeroiso_addr &&
        !           629:                        !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))
        !           630:                        continue;
        !           631:                */
        !           632:                if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr)))
        !           633:                        continue;
        !           634:                return (isop);
        !           635:        }
        !           636:        return (struct isopcb *)0;
        !           637: }
        !           638: #endif /* ISO */

unix.superglobalmegacorp.com

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