summaryrefslogtreecommitdiffstats
path: root/sys/netiso/iso_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netiso/iso_pcb.c')
-rw-r--r--sys/netiso/iso_pcb.c617
1 files changed, 617 insertions, 0 deletions
diff --git a/sys/netiso/iso_pcb.c b/sys/netiso/iso_pcb.c
new file mode 100644
index 0000000..0b50c60
--- /dev/null
+++ b/sys/netiso/iso_pcb.c
@@ -0,0 +1,617 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)iso_pcb.c 8.1 (Berkeley) 6/10/93
+ */
+
+/***********************************************************
+ Copyright IBM Corporation 1987
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
+ */
+/*
+ * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $
+ * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $
+ *
+ * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
+ */
+
+#ifdef ISO
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <netiso/argo_debug.h>
+#include <netiso/iso.h>
+#include <netiso/clnp.h>
+#include <netinet/in_systm.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netiso/iso_pcb.h>
+#include <netiso/iso_var.h>
+#include <sys/protosw.h>
+
+#ifdef TPCONS
+#include <netccitt/x25.h>
+#include <netccitt/pk.h>
+#include <netccitt/pk_var.h>
+#endif
+
+#define PCBNULL (struct isopcb *)0
+struct iso_addr zeroiso_addr = {
+ 0
+};
+
+
+/*
+ * FUNCTION: iso_pcballoc
+ *
+ * PURPOSE: creates an isopcb structure in an mbuf,
+ * with socket (so), and
+ * puts it in the queue with head (head)
+ *
+ * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf
+ */
+int
+iso_pcballoc(so, head)
+ struct socket *so;
+ struct isopcb *head;
+{
+ register struct isopcb *isop;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcballoc(so 0x%x)\n", so);
+ ENDDEBUG
+ MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT);
+ if (isop == NULL)
+ return ENOBUFS;
+ bzero((caddr_t)isop, sizeof(*isop));
+ isop->isop_head = head;
+ isop->isop_socket = so;
+ insque(isop, head);
+ if (so)
+ so->so_pcb = (caddr_t)isop;
+ return 0;
+}
+
+/*
+ * FUNCTION: iso_pcbbind
+ *
+ * PURPOSE: binds the address given in *(nam) to the socket
+ * specified by the isopcb in *(isop)
+ * If the given address is zero, it makes sure the
+ * address isn't already in use and if it's got a network
+ * portion, we look for an interface with that network
+ * address. If the address given is zero, we allocate
+ * a port and stuff it in the (nam) structure.
+ *
+ * RETURNS: errno E* or 0 if ok.
+ *
+ * SIDE EFFECTS: increments head->isop_lport if it allocates a port #
+ *
+ * NOTES:
+ */
+#define satosiso(sa) ((struct sockaddr_iso *)(sa))
+int
+iso_pcbbind(isop, nam)
+ register struct isopcb *isop;
+ struct mbuf *nam;
+{
+ register struct isopcb *head = isop->isop_head;
+ register struct sockaddr_iso *siso;
+ struct iso_ifaddr *ia;
+ union {
+ char data[2];
+ u_short s;
+ } suf;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam);
+ ENDDEBUG
+ suf.s = 0;
+ if (iso_ifaddr == 0) /* any interfaces attached? */
+ return EADDRNOTAVAIL;
+ if (isop->isop_laddr) /* already bound */
+ return EADDRINUSE;
+ if(nam == (struct mbuf *)0) {
+ isop->isop_laddr = &isop->isop_sladdr;
+ isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso);
+ isop->isop_sladdr.siso_family = AF_ISO;
+ isop->isop_sladdr.siso_tlen = 2;
+ isop->isop_sladdr.siso_nlen = 0;
+ isop->isop_sladdr.siso_slen = 0;
+ isop->isop_sladdr.siso_plen = 0;
+ goto noname;
+ }
+ siso = mtod(nam, struct sockaddr_iso *);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbbind(name len 0x%x)\n", nam->m_len);
+ printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr));
+ ENDDEBUG
+ /*
+ * We would like sort of length check but since some OSI addrs
+ * do not have fixed length, we can't really do much.
+ * The ONLY thing we can say is that an osi addr has to have
+ * at LEAST an afi and one more byte and had better fit into
+ * a struct iso_addr.
+ * However, in fact the size of the whole thing is a struct
+ * sockaddr_iso, so probably this is what we should check for.
+ */
+ if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
+ return ENAMETOOLONG;
+ }
+ if (siso->siso_nlen) {
+ /* non-zero net addr- better match one of our interfaces */
+ IFDEBUG(D_ISO)
+ printf("iso_pcbbind: bind to NOT zeroisoaddr\n");
+ ENDDEBUG
+ for (ia = iso_ifaddr; ia; ia = ia->ia_next)
+ if (SAME_ISOADDR(siso, &ia->ia_addr))
+ break;
+ if (ia == 0)
+ return EADDRNOTAVAIL;
+ }
+ if (siso->siso_len <= sizeof (isop->isop_sladdr)) {
+ isop->isop_laddr = &isop->isop_sladdr;
+ } else {
+ if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0)
+ return ENOBUFS;
+ isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
+ }
+ bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
+ if (siso->siso_tlen == 0)
+ goto noname;
+ if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
+ iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
+ return EADDRINUSE;
+ if (siso->siso_tlen <= 2) {
+ bcopy(TSEL(siso), suf.data, sizeof(suf.data));
+ suf.s = ntohs(suf.s);
+ if((suf.s < ISO_PORT_RESERVED) &&
+ (isop->isop_socket->so_state && SS_PRIV) == 0)
+ return EACCES;
+ } else {
+ register char *cp;
+noname:
+ cp = TSEL(isop->isop_laddr);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbbind noname\n");
+ ENDDEBUG
+ do {
+ if (head->isop_lport++ < ISO_PORT_RESERVED ||
+ head->isop_lport > ISO_PORT_USERRESERVED)
+ head->isop_lport = ISO_PORT_RESERVED;
+ suf.s = htons(head->isop_lport);
+ cp[0] = suf.data[0];
+ cp[1] = suf.data[1];
+ } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
+ }
+ IFDEBUG(D_ISO)
+ printf("iso_pcbbind returns 0, suf 0x%x\n", suf);
+ ENDDEBUG
+ return 0;
+}
+/*
+ * FUNCTION: iso_pcbconnect
+ *
+ * PURPOSE: Make the isopcb (isop) look like it's connected.
+ * In other words, give it the peer address given in
+ * the mbuf * (nam). Make sure such a combination
+ * of local, peer addresses doesn't already exist
+ * for this protocol. Internet mentality prevails here,
+ * wherein a src,dst pair uniquely identifies a connection.
+ * Both net address and port must be specified in argument
+ * (nam).
+ * If we don't have a local address for this socket yet,
+ * we pick one by calling iso_pcbbind().
+ *
+ * RETURNS: errno E* or 0 if ok.
+ *
+ * SIDE EFFECTS: Looks up a route, which may cause one to be left
+ * in the isopcb.
+ *
+ * NOTES:
+ */
+int
+iso_pcbconnect(isop, nam)
+ register struct isopcb *isop;
+ struct mbuf *nam;
+{
+ register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *);
+ int local_zero, error = 0;
+ struct iso_ifaddr *ia;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x",
+ isop, isop->isop_socket, nam);
+ printf("nam->m_len 0x%x), addr:\n", nam->m_len);
+ dump_isoaddr(siso);
+ ENDDEBUG
+ if (nam->m_len < siso->siso_len)
+ return EINVAL;
+ if (siso->siso_family != AF_ISO)
+ return EAFNOSUPPORT;
+ if (siso->siso_nlen == 0) {
+ if (ia = iso_ifaddr) {
+ int nlen = ia->ia_addr.siso_nlen;
+ ovbcopy(TSEL(siso), nlen + TSEL(siso),
+ siso->siso_plen + siso->siso_tlen + siso->siso_slen);
+ bcopy((caddr_t)&ia->ia_addr.siso_addr,
+ (caddr_t)&siso->siso_addr, nlen + 1);
+ /* includes siso->siso_nlen = nlen; */
+ } else
+ return EADDRNOTAVAIL;
+ }
+ /*
+ * Local zero means either not bound, or bound to a TSEL, but no
+ * particular local interface. So, if we want to send somebody
+ * we need to choose a return address.
+ */
+ local_zero =
+ ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0));
+ if (local_zero) {
+ int flags;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbconnect localzero 1\n");
+ ENDDEBUG
+ /*
+ * If route is known or can be allocated now,
+ * our src addr is taken from the i/f, else punt.
+ */
+ flags = isop->isop_socket->so_options & SO_DONTROUTE;
+ if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags,
+ (struct sockaddr **)0, &ia))
+ return error;
+ IFDEBUG(D_ISO)
+ printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x",
+ isop->isop_route.ro_rt);
+ printf(" ia 0x%x\n", ia);
+ ENDDEBUG
+ }
+ IFDEBUG(D_ISO)
+ printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n",
+ isop, isop->isop_socket);
+ ENDDEBUG
+ if (local_zero) {
+ int nlen, tlen, totlen; caddr_t oldtsel, newtsel;
+ siso = isop->isop_laddr;
+ if (siso == 0 || siso->siso_tlen == 0)
+ (void)iso_pcbbind(isop, (struct mbuf *)0);
+ /*
+ * Here we have problem of squezeing in a definite network address
+ * into an existing sockaddr_iso, which in fact may not have room
+ * for it. This gets messy.
+ */
+ siso = isop->isop_laddr;
+ oldtsel = TSEL(siso);
+ tlen = siso->siso_tlen;
+ nlen = ia->ia_addr.siso_nlen;
+ totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]);
+ if ((siso == &isop->isop_sladdr) &&
+ (totlen > sizeof(isop->isop_sladdr))) {
+ struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
+ if (m == 0)
+ return ENOBUFS;
+ m->m_len = totlen;
+ isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);
+ }
+ siso->siso_nlen = ia->ia_addr.siso_nlen;
+ newtsel = TSEL(siso);
+ ovbcopy(oldtsel, newtsel, tlen);
+ bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen);
+ siso->siso_tlen = tlen;
+ siso->siso_family = AF_ISO;
+ siso->siso_len = totlen;
+ siso = mtod(nam, struct sockaddr_iso *);
+ }
+ IFDEBUG(D_ISO)
+ printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n",
+ isop, isop->isop_socket);
+ ENDDEBUG
+ /*
+ * If we had to allocate space to a previous big foreign address,
+ * and for some reason we didn't free it, we reuse it knowing
+ * that is going to be big enough, as sockaddrs are delivered in
+ * 128 byte mbufs.
+ * If the foreign address is small enough, we use default space;
+ * otherwise, we grab an mbuf to copy into.
+ */
+ if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) {
+ if (siso->siso_len <= sizeof(isop->isop_sfaddr))
+ isop->isop_faddr = &isop->isop_sfaddr;
+ else {
+ struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT);
+ if (m == 0)
+ return ENOBUFS;
+ isop->isop_faddr = mtod(m, struct sockaddr_iso *);
+ }
+ }
+ bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len);
+ IFDEBUG(D_ISO)
+ printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n",
+ isop, isop->isop_socket);
+ printf("iso_pcbconnect connected to addr:\n");
+ dump_isoaddr(isop->isop_faddr);
+ printf("iso_pcbconnect end: src addr:\n");
+ dump_isoaddr(isop->isop_laddr);
+ ENDDEBUG
+ return 0;
+}
+
+/*
+ * FUNCTION: iso_pcbdisconnect()
+ *
+ * PURPOSE: washes away the peer address info so the socket
+ * appears to be disconnected.
+ * If there's no file descriptor associated with the socket
+ * it detaches the pcb.
+ *
+ * RETURNS: Nada.
+ *
+ * SIDE EFFECTS: May detach the pcb.
+ *
+ * NOTES:
+ */
+void
+iso_pcbdisconnect(isop)
+ struct isopcb *isop;
+{
+ void iso_pcbdetach();
+ register struct sockaddr_iso *siso;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdisconnect(isop 0x%x)\n", isop);
+ ENDDEBUG
+ /*
+ * Preserver binding infnormation if already bound.
+ */
+ if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) {
+ caddr_t otsel = TSEL(siso);
+ siso->siso_nlen = 0;
+ ovbcopy(otsel, TSEL(siso), siso->siso_tlen);
+ }
+ if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)
+ m_freem(dtom(isop->isop_faddr));
+ isop->isop_faddr = 0;
+ if (isop->isop_socket->so_state & SS_NOFDREF)
+ iso_pcbdetach(isop);
+}
+
+/*
+ * FUNCTION: iso_pcbdetach
+ *
+ * PURPOSE: detach the pcb at *(isop) from it's socket and free
+ * the mbufs associated with the pcb..
+ * Dequeues (isop) from its head.
+ *
+ * RETURNS: Nada.
+ *
+ * SIDE EFFECTS:
+ *
+ * NOTES:
+ */
+void
+iso_pcbdetach(isop)
+ struct isopcb *isop;
+{
+ struct socket *so = isop->isop_socket;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n",
+ isop, isop->isop_socket, so);
+ ENDDEBUG
+#ifdef TPCONS
+ if (isop->isop_chan) {
+ register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
+ if (--isop->isop_refcnt > 0)
+ return;
+ if (lcp && lcp->lcd_state == DATA_TRANSFER) {
+ lcp->lcd_upper = 0;
+ lcp->lcd_upnext = 0;
+ pk_disconnect(lcp);
+ }
+ isop->isop_chan = 0;
+ }
+#endif
+ if (so) { /* in the x.25 domain, we sometimes have no socket */
+ so->so_pcb = 0;
+ sofree(so);
+ }
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 2 \n");
+ ENDDEBUG
+ if (isop->isop_options)
+ (void)m_free(isop->isop_options);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 3 \n");
+ ENDDEBUG
+ if (isop->isop_route.ro_rt)
+ rtfree(isop->isop_route.ro_rt);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 3.1\n");
+ ENDDEBUG
+ if (isop->isop_clnpcache != NULL) {
+ struct clnp_cache *clcp =
+ mtod(isop->isop_clnpcache, struct clnp_cache *);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n",
+ clcp, clcp->clc_hdr);
+ ENDDEBUG
+ if (clcp->clc_hdr != NULL)
+ m_free(clcp->clc_hdr);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 3.3: freeing cache x%x\n",
+ isop->isop_clnpcache);
+ ENDDEBUG
+ m_free(isop->isop_clnpcache);
+ }
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 4 \n");
+ ENDDEBUG
+ remque(isop);
+ IFDEBUG(D_ISO)
+ printf("iso_pcbdetach 5 \n");
+ ENDDEBUG
+ if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))
+ m_freem(dtom(isop->isop_laddr));
+ free((caddr_t)isop, M_PCB);
+}
+
+
+/*
+ * FUNCTION: iso_pcbnotify
+ *
+ * PURPOSE: notify all connections in this protocol's queue (head)
+ * that have peer address (dst) of the problem (errno)
+ * by calling (notify) on the connections' isopcbs.
+ *
+ * RETURNS: Rien.
+ *
+ * SIDE EFFECTS:
+ *
+ * NOTES: (notify) is called at splimp!
+ */
+void
+iso_pcbnotify(head, siso, errno, notify)
+ struct isopcb *head;
+ register struct sockaddr_iso *siso;
+ int errno, (*notify)();
+{
+ register struct isopcb *isop;
+ int s = splimp();
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);
+ ENDDEBUG
+ for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
+ if (isop->isop_socket == 0 || isop->isop_faddr == 0 ||
+ !SAME_ISOADDR(siso, isop->isop_faddr)) {
+ IFDEBUG(D_ISO)
+ printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,
+ isop, isop->isop_socket);
+ printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr);
+ dump_isoaddr(isop->isop_faddr);
+ ENDDEBUG
+ continue;
+ }
+ if (errno)
+ isop->isop_socket->so_error = errno;
+ if (notify)
+ (*notify)(isop);
+ }
+ splx(s);
+ IFDEBUG(D_ISO)
+ printf("END OF iso_pcbnotify\n" );
+ ENDDEBUG
+}
+
+
+/*
+ * FUNCTION: iso_pcblookup
+ *
+ * PURPOSE: looks for a given combination of (faddr), (fport),
+ * (lport), (laddr) in the queue named by (head).
+ * Argument (flags) is ignored.
+ *
+ * RETURNS: ptr to the isopcb if it finds a connection matching
+ * these arguments, o.w. returns zero.
+ *
+ * SIDE EFFECTS:
+ *
+ * NOTES:
+ */
+struct isopcb *
+iso_pcblookup(head, fportlen, fport, laddr)
+ struct isopcb *head;
+ register struct sockaddr_iso *laddr;
+ caddr_t fport;
+ int fportlen;
+{
+ register struct isopcb *isop;
+ register caddr_t lp = TSEL(laddr);
+ unsigned int llen = laddr->siso_tlen;
+
+ IFDEBUG(D_ISO)
+ printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n",
+ head, laddr, fport);
+ ENDDEBUG
+ for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
+ if (isop->isop_laddr == 0 || isop->isop_laddr == laddr)
+ continue;
+ if (isop->isop_laddr->siso_tlen != llen)
+ continue;
+ if (bcmp(lp, TSEL(isop->isop_laddr), llen))
+ continue;
+ if (fportlen && isop->isop_faddr &&
+ bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen))
+ continue;
+ /* PHASE2
+ * addrmatch1 should be iso_addrmatch(a, b, mask)
+ * where mask is taken from isop->isop_laddrmask (new field)
+ * isop_lnetmask will also be available in isop
+ if (laddr != &zeroiso_addr &&
+ !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))
+ continue;
+ */
+ if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr)))
+ continue;
+ return (isop);
+ }
+ return (struct isopcb *)0;
+}
+#endif /* ISO */
OpenPOWER on IntegriCloud