Annotation of kernel/bsd/netiso/iso_pcb.c, revision 1.1.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.