home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netiso / iso_pcb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-27  |  17.8 KB  |  616 lines

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