xref: /original-bsd/sys/netiso/iso_pcb.c (revision 92d853e2)
1 /***********************************************************
2 		Copyright IBM Corporation 1987
3 
4                       All Rights Reserved
5 
6 Permission to use, copy, modify, and distribute this software and its
7 documentation for any purpose and without fee is hereby granted,
8 provided that the above copyright notice appear in all copies and that
9 both that copyright notice and this permission notice appear in
10 supporting documentation, and that the name of IBM not be
11 used in advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
13 
14 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 SOFTWARE.
21 
22 ******************************************************************/
23 
24 /*
25  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
26  */
27 /*
28  * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $
29  * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $
30  *
31  * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
32  */
33 #ifndef lint
34 static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $";
35 #endif
36 
37 #ifdef ISO
38 
39 #include "param.h"
40 #include "systm.h"
41 #include "dir.h"
42 #include "user.h"
43 #include "mbuf.h"
44 #include "../h/socket.h"
45 #include "../h/socketvar.h"
46 #include "../netiso/argo_debug.h"
47 #include "../netiso/iso.h"
48 #include "../netiso/clnp.h"
49 #include "../netinet/in_systm.h"
50 #include "../net/if.h"
51 #include "../net/route.h"
52 #include "../netiso/iso_pcb.h"
53 #include "../netiso/iso_var.h"
54 #include "protosw.h"
55 
56 #define PCBNULL (struct isopcb *)0
57 struct	iso_addr zeroiso_addr = {
58 	0
59 };
60 
61 
62 /*
63  * FUNCTION:		iso_pcballoc
64  *
65  * PURPOSE:			creates an isopcb structure in an mbuf,
66  *					with socket (so), and
67  *					puts it in the queue with head (head)
68  *
69  * RETURNS:			0 if OK, ENOBUFS if can't alloc the necessary mbuf
70  */
71 int
72 iso_pcballoc(so, head)
73 	struct socket *so;
74 	struct isopcb *head;
75 {
76 	struct mbuf *m;
77 	register struct isopcb *isop;
78 
79 	IFDEBUG(D_ISO)
80 		printf("iso_pcballoc(so 0x%x)\n", so);
81 	ENDDEBUG
82 	m = m_getclr(M_DONTWAIT, MT_PCB);
83 	if (m == NULL)
84 		return ENOBUFS;
85 	isop = mtod(m, struct isopcb *);
86 	isop->isop_head = head;
87 	isop->isop_socket = so;
88 	insque(isop, head);
89 	so->so_pcb = (caddr_t)isop;
90 	return 0;
91 }
92 
93 /*
94  * FUNCTION:		iso_pcbbind
95  *
96  * PURPOSE:			binds the address given in *(nam) to the socket
97  *					specified by the isopcb in *(isop)
98  *					If the given address is zero, it makes sure the
99  *					address isn't already in use and if it's got a network
100  *					portion, we look for an interface with that network
101  *					address.  If the address given is zero, we allocate
102  *					a port and stuff it in the (nam) structure.
103  *
104  * RETURNS:			errno E* or 0 if ok.
105  *
106  * SIDE EFFECTS:	increments head->isop_lport if it allocates a port #
107  *
108  * NOTES:
109  */
110 int
111 iso_pcbbind(isop, nam)
112 	register struct isopcb *isop;
113 	struct mbuf *nam;
114 {
115 	register struct isopcb *head = isop->isop_head;
116 	register struct sockaddr_iso *siso;
117 	struct ifaddr *ia;
118 	u_short suf = 0;
119 
120 	IFDEBUG(D_ISO)
121 		printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam);
122 	ENDDEBUG
123 	if (iso_ifaddr == 0) /* any interfaces attached? */
124 		return EADDRNOTAVAIL;
125 	if (isop->isop_lport)  /* already bound */
126 		return EADDRINUSE;
127 	if(nam == (struct mbuf *)0)
128 		goto noname;
129 	siso = mtod(nam, struct sockaddr_iso *);
130 	IFDEBUG(D_ISO)
131 		printf("iso_pcbbind(name len 0x%x)\n", nam->m_len);
132 		printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr));
133 	ENDDEBUG
134 	/*
135 	 * We would like sort of length check but since some OSI addrs
136 	 * do not have fixed length, we can't really do much.
137 	 * The ONLY thing we can say is that an osi addr has to have
138 	 * at LEAST an afi and one more byte and had better fit into
139 	 * a struct iso_addr.
140 	 * However, in fact the size of the whole thing is a struct
141 	 * sockaddr_iso, so probably this is what we should check for.
142 	 */
143 	if( (nam->m_len < 2) || (nam->m_len > sizeof(struct sockaddr_iso))) {
144 			return ENAMETOOLONG;
145 	}
146 	suf = siso->siso_tsuffix;
147 
148 	if (bcmp(&siso->siso_addr,&zeroiso_addr, 1)) {
149 		/* non-zero net addr- better match one of our interfaces */
150 		IFDEBUG(D_ISO)
151 			printf("iso_pcbbind: bind to NOT zeroisoaddr\n");
152 		ENDDEBUG
153 		siso->siso_tsuffix = 0;		/* yech... */
154 		/* PHASE 2: this call is ok */
155 		if ((ia = ifa_ifwithaddr((struct sockaddr *)siso))
156 											== (struct ifaddr *)0)
157 			return EADDRNOTAVAIL;
158 		/* copy to the inpcb */
159 		bcopy( (caddr_t)&((struct sockaddr_iso *)&(ia->ifa_addr))->siso_addr,
160 			(caddr_t)&(isop->isop_laddr.siso_addr),
161 			sizeof(struct sockaddr_iso) );
162 		isop->isop_laddr.siso_tsuffix = suf;
163 		/* copy also to the nam parameter */
164 		bcopy( (caddr_t)&(isop->isop_laddr.siso_addr),
165 			(caddr_t)&(siso->siso_addr), sizeof(struct sockaddr_iso));
166 		siso->siso_tsuffix = suf;
167 	}
168 	if (suf) {
169 		if((suf < ISO_PORT_RESERVED) && (u.u_uid != 0))
170 			return EACCES;
171 		if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
172 			iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0) )
173 			return EADDRINUSE;
174 	}
175 	/* copy the if addr to the result (siso) and to the isopcb */
176 noname:
177 	IFDEBUG(D_ISO)
178 		printf("iso_pcbbind noname\n");
179 	ENDDEBUG
180 	if (suf == 0)
181 		do {
182 			if (head->isop_lport++ < ISO_PORT_RESERVED ||
183 			    head->isop_lport > ISO_PORT_USERRESERVED)
184 				head->isop_lport = ISO_PORT_RESERVED;
185 			suf = head->isop_lport;
186 		} while (iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0));
187 	isop->isop_lport = suf;
188 	IFDEBUG(D_ISO)
189 		printf("iso_pcbbind returns 0, suf 0x%x\n", suf);
190 	ENDDEBUG
191 	return 0;
192 }
193 
194 /*
195  * FUNCTION:		iso_pcbconnect
196  *
197  * PURPOSE:			Make the isopcb (isop) look like it's connected.
198  *					In other words, give it the peer address given in
199  *					the mbuf * (nam).   Make sure such a combination
200  *					of local, peer addresses doesn't already exist
201  *					for this protocol.  Internet mentality prevails here,
202  *					wherein a src,dst pair uniquely identifies a connection.
203  * 					Both net address and port must be specified in argument
204  *					(nam).
205  * 					If we don't have a local address for this socket yet,
206  *					we pick one by calling iso_pcbbind().
207  *
208  * RETURNS:			errno E* or 0 if ok.
209  *
210  * SIDE EFFECTS:	Looks up a route, which may cause one to be left
211  *					in the isopcb.
212  *
213  * NOTES:
214  */
215 #define	satosiso(sa)	((struct sockaddr_iso *)(sa))
216 
217 int
218 iso_pcbconnect(isop, nam)
219 	struct isopcb *isop;
220 	struct mbuf *nam;
221 {
222 	struct	ifnet 					*ifp = (struct ifnet *)0;
223 	struct sockaddr_iso				ifaddr;
224 	register struct sockaddr_iso	*siso = mtod(nam, struct sockaddr_iso *);
225 	int								local_zero = 0;
226 
227 	IFDEBUG(D_ISO)
228 		printf(
229 	"iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x nam->m_len 0x%x), addr:\n",
230 			isop, isop->isop_socket, nam, nam->m_len);
231 		dump_isoaddr(siso);
232 	ENDDEBUG
233 	if (nam->m_len > sizeof (*siso))
234 		return ENAMETOOLONG; /* not great but better than EINVAL! */
235 	if (siso->siso_family != AF_ISO)
236 		return EAFNOSUPPORT;
237 #ifdef notdef
238 	/* removed for the sake of extended tsels -
239 	 * user may setsockopt for extended tsel (foreign) and then
240 	 * connect to nsap w/ tsuffix zero
241 	 */
242 	if (siso->siso_tsuffix == 0)
243 		return EADDRNOTAVAIL;
244 	local_zero = iso_addrmatch1(&(isop->isop_laddr.siso_addr), &zeroiso_addr);
245 #endif notdef
246 	local_zero = !bcmp(&(isop->isop_laddr.siso_addr), &zeroiso_addr, 1);
247 
248 #ifdef	PHASEONE
249 	if (local_zero) {
250 		/*
251 		 *	We need to get the local nsap address.
252 		 *	First, route to the destination. This will provide us with
253 		 *	an ifp. Second, determine which local address linked on
254 		 *	that ifp is appropriate
255 		 */
256 		struct sockaddr_iso	*first_hop;		/* filled by clnp_route */
257 		struct ifnet	*ifp;			/* filled by clnp_route */
258 		int				err;
259 		struct iso_addr	*localaddr;
260 
261 		if (err = clnp_route(&siso->siso_addr, &isop->isop_route, /* flags */0,
262 			&first_hop, &ifp))
263 			return(err);
264 
265 		/* determine local address based upon ifp */
266 		if ((localaddr = clnp_srcaddr(ifp, &first_hop->siso_addr)) == NULL)
267 			return(ENETUNREACH);
268 
269 		ifaddr.siso_family = AF_ISO;
270 		ifaddr.siso_addr = *localaddr;
271 
272 		if (isop->isop_lport == 0)
273 			(void)iso_pcbbind(isop, (struct mbuf *)0);
274 		isop->isop_laddr = ifaddr;
275 	}
276 #else
277 	if (local_zero) {
278 		struct iso_ifaddr 		*ia;
279 		register struct route *ro;
280 
281 		IFDEBUG(D_ISO)
282 			printf("iso_pcbconnect localzero 1\n");
283 		ENDDEBUG
284 		ia = (struct iso_ifaddr *)0;
285 		/*
286 		 * If route is known or can be allocated now,
287 		 * our src addr is taken from the i/f, else punt.
288 		 */
289 		ro = &isop->isop_route;
290 		IFDEBUG(D_ISO)
291 			printf("iso_pcbconnect rtalloc 1.1, ro->ro_rt 0x%x\n",
292 				ro->ro_rt);
293 		ENDDEBUG
294 		if (ro->ro_rt && ! iso_addrmatch1( &(satosiso(&ro->ro_dst)->siso_addr),
295 					&siso->siso_addr)) {
296 			RTFREE(ro->ro_rt);
297 			ro->ro_rt = (struct rtentry *)0;
298 		}
299 		/*
300 		 *	TODO: it seems this code has a lot in common with clnp_route.
301 		 *	Maybe they could be combined? (RAH)
302 		 */
303 		if ((isop->isop_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
304 		    (ro->ro_rt == (struct rtentry *)0 ||
305 		    (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0)) {
306 				/* No route yet, so try to acquire one */
307 				ro->ro_dst.sa_family = AF_ISO;
308 				((struct sockaddr_iso *) &ro->ro_dst)->siso_addr =
309 					siso->siso_addr;
310 				rtalloc(ro);
311 				IFDEBUG(D_ISO)
312 					printf("iso_pcbconnect rtalloc 1.5, ro->ro_rt 0x%x\n",
313 						ro->ro_rt);
314 					if (ro->ro_rt != NULL) {
315 						printf("ro->ro_rt->rt_refcnt %d\n",
316 							ro->ro_rt->rt_refcnt);
317 						printf("rt entry rt_gateway (as sockaddr):\n");
318 						dump_buf(&ro->ro_rt->rt_gateway,
319 							sizeof (struct sockaddr));
320 					}
321 				ENDDEBUG
322 				/*
323 				 * If we found a route, use the address
324 				 * corresponding to the outgoing interface
325 				 * unless it is the loopback (in case a route
326 				 * to our address on another net goes to loopback).
327 				 *
328 				 *	We must check to use the address that is of the
329 				 *	same type (in the case where the interface has more
330 				 *	than one type associated with it). (ie ecn0 has
331 				 *	both t37 and osinet addresses.
332 				 */
333 				if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) &&
334 					(ifp->if_flags & IFF_LOOPBACK) == 0)
335 					for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
336 						struct iso_addr *isoap = &IA_SIS(ia)->siso_addr;
337 
338 						IFDEBUG(D_ISO)
339 							printf("iso_pcbconnect: ia x%x yields: %s\n",
340 								ia, clnp_iso_addrp(isoap));
341 						ENDDEBUG
342 
343 						if ((ia->ia_ifp == ifp) &&
344 							(iso_eqtype(&siso->siso_addr, isoap)))
345 							break;
346 					}
347 		}
348 		IFDEBUG(D_ISO)
349 			printf("iso_pcbconnect localzero 2: ia x%x\n", ia);
350 		ENDDEBUG
351 		if (ia == 0) {
352 			ia = (struct iso_ifaddr *)
353 			    ifa_ifwithdstaddr((struct sockaddr *)siso);
354 			if (ia == 0)
355 				ia = iso_iaonnetof(siso);
356 			if (ia == 0)
357 				return EADDRNOTAVAIL;
358 		}
359 		ifaddr = *(struct sockaddr_iso *)&ia->ia_addr;
360 	}
361 	IFDEBUG(D_ISO)
362 		printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n",
363 			isop, isop->isop_socket);
364 	ENDDEBUG
365 	if (local_zero) {
366 		if (isop->isop_lport == 0)
367 			(void)iso_pcbbind(isop, (struct mbuf *)0);
368 		isop->isop_laddr.siso_addr = ifaddr.siso_addr;
369 		isop->isop_laddr.siso_family = AF_ISO;
370 	}
371 #endif	PHASEONE
372 	IFDEBUG(D_ISO)
373 		printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n",
374 			isop, isop->isop_socket);
375 	ENDDEBUG
376 	bcopy((caddr_t) &(siso->siso_addr), (caddr_t) &(isop->isop_faddr.siso_addr),
377 		sizeof(struct iso_addr));
378 	IFDEBUG(D_ISO)
379 		printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n",
380 			isop, isop->isop_socket);
381 	ENDDEBUG
382 	isop->isop_faddr.siso_family = AF_ISO;
383 	isop->isop_fport = siso->siso_tsuffix;
384 	IFDEBUG(D_ISO)
385 		printf("in iso_pcbconnect end isop 0x%x isop->sock 0x%x\n",
386 			isop, isop->isop_socket);
387 		printf("iso_pcbconnect connected to addr:\n");
388 		dump_isoaddr(&isop->isop_faddr);
389 		printf("iso_pcbconnect end: src addr:\n");
390 		dump_isoaddr(&isop->isop_laddr);
391 	ENDDEBUG
392 	return 0;
393 }
394 
395 /*
396  * FUNCTION:		iso_pcbdisconnect()
397  *
398  * PURPOSE:			washes away the peer address info so the socket
399  *					appears to be disconnected.
400  *					If there's no file descriptor associated with the socket
401  *					it detaches the pcb.
402  *
403  * RETURNS:			Nada.
404  *
405  * SIDE EFFECTS:	May detach the pcb.
406  *
407  * NOTES:
408  */
409 void
410 iso_pcbdisconnect(isop)
411 	struct isopcb *isop;
412 {
413 	void iso_pcbdetach();
414 
415 	IFDEBUG(D_ISO)
416 		printf("iso_pcbdisconnect(isop 0x%x)\n", isop);
417 	ENDDEBUG
418 	isop->isop_laddr.siso_addr = zeroiso_addr;
419 	isop->isop_fport = 0;
420 	if (isop->isop_socket->so_state & SS_NOFDREF)
421 		iso_pcbdetach(isop);
422 }
423 
424 /*
425  * FUNCTION:		iso_pcbdetach
426  *
427  * PURPOSE:			detach the pcb at *(isop) from it's socket and free
428  *					the mbufs associated with the pcb..
429  *					Dequeues (isop) from its head.
430  *
431  * RETURNS:			Nada.
432  *
433  * SIDE EFFECTS:
434  *
435  * NOTES:
436  */
437 void
438 iso_pcbdetach(isop)
439 	struct isopcb *isop;
440 {
441 	struct socket *so = isop->isop_socket;
442 
443 	IFDEBUG(D_ISO)
444 		printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n",
445 			isop, isop->isop_socket, so);
446 	ENDDEBUG
447 	if (so ) { /* in the x.25 domain, we sometimes have no socket */
448 		so->so_pcb = 0;
449 		sofree(so);
450 	}
451 	IFDEBUG(D_ISO)
452 		printf("iso_pcbdetach 2 \n");
453 	ENDDEBUG
454 	if (isop->isop_options)
455 		(void)m_free(isop->isop_options);
456 	IFDEBUG(D_ISO)
457 		printf("iso_pcbdetach 3 \n");
458 	ENDDEBUG
459 	if (isop->isop_route.ro_rt)
460 		rtfree(isop->isop_route.ro_rt);
461 	IFDEBUG(D_ISO)
462 		printf("iso_pcbdetach 3.1\n");
463 	ENDDEBUG
464 	if (isop->isop_clnpcache != NULL) {
465 		struct clnp_cache *clcp =
466 			mtod(isop->isop_clnpcache, struct clnp_cache *);
467 		IFDEBUG(D_ISO)
468 			printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n",
469 				clcp, clcp->clc_hdr);
470 		ENDDEBUG
471 		if (clcp->clc_hdr != NULL)
472 			m_free(clcp->clc_hdr);
473 		IFDEBUG(D_ISO)
474 			printf("iso_pcbdetach 3.3: freeing cache x%x\n",
475 				isop->isop_clnpcache);
476 		ENDDEBUG
477 		m_free(isop->isop_clnpcache);
478 	}
479 	IFDEBUG(D_ISO)
480 		printf("iso_pcbdetach 4 \n");
481 	ENDDEBUG
482 	remque(isop);
483 	IFDEBUG(D_ISO)
484 		printf("iso_pcbdetach 5 \n");
485 	ENDDEBUG
486 	(void) m_free(dtom(isop));
487 }
488 
489 #ifdef notdef
490 /* NEEDED? */
491 void
492 iso_setsockaddr(isop, nam)
493 	register struct isopcb *isop;
494 	struct mbuf *nam;
495 {
496 	register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *);
497 
498 	nam->m_len = sizeof (*siso);
499 	siso = mtod(nam, struct sockaddr_iso *);
500 	bzero((caddr_t)siso, sizeof (*siso));
501 	siso->siso_family = AF_ISO;
502 	siso->siso_tsuffix = isop->isop_lport;
503 	siso->siso_addr = isop->isop_laddr.siso_addr;
504 }
505 
506 /* NEEDED? */
507 void
508 iso_setpeeraddr(isop, nam)
509 	register struct isopcb *isop;
510 	struct mbuf *nam;
511 {
512 	register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *);
513 
514 	nam->m_len = sizeof (*siso);
515 	siso = mtod(nam, struct sockaddr_iso *);
516 	bzero((caddr_t)siso, sizeof (*siso));
517 	siso->siso_family = AF_ISO;
518 	siso->siso_tsuffix = isop->isop_fport;
519 	siso->siso_addr = isop->isop_faddr.siso_addr;
520 }
521 #endif notdef
522 
523 /*
524  * FUNCTION:		iso_pcbnotify
525  *
526  * PURPOSE:			notify all connections in this protocol's queue (head)
527  *					that have peer address (dst) of the problem (errno)
528  *					by calling (notify) on the connections' isopcbs.
529  *
530  * RETURNS:			Rien.
531  *
532  * SIDE EFFECTS:
533  *
534  * NOTES:			(notify) is called at splimp!
535  */
536 void
537 iso_pcbnotify(head, dst, errno, notify)
538 	struct isopcb *head;
539 	register struct iso_addr *dst;
540 	int errno, (*notify)();
541 {
542 	register struct isopcb *isop, *oisop;
543 	int s = splimp();
544 
545 	IFDEBUG(D_ISO)
546 		printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify);
547 	ENDDEBUG
548 	for (isop = head->isop_next; isop != head;) {
549 		if (!iso_addrmatch1(&(isop->isop_faddr.siso_addr), dst) ||
550 		    isop->isop_socket == 0) {
551 			IFDEBUG(D_ISO)
552 				printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" ,
553 					isop, isop->isop_socket);
554 				printf("addrmatch cmp'd with (0x%x):\n",
555 					&(isop->isop_faddr.siso_addr));
556 				dump_isoaddr(&isop->isop_faddr);
557 			ENDDEBUG
558 			isop = isop->isop_next;
559 			continue;
560 		}
561 		if (errno)
562 			isop->isop_socket->so_error = errno;
563 		oisop = isop;
564 		isop = isop->isop_next;
565 		if (notify)
566 			(*notify)(oisop);
567 	}
568 	splx(s);
569 	IFDEBUG(D_ISO)
570 		printf("END OF iso_pcbnotify\n" );
571 	ENDDEBUG
572 }
573 
574 
575 /*
576  * FUNCTION:		iso_pcblookup
577  *
578  * PURPOSE:			looks for a given combination of (faddr), (fport),
579  *					(lport), (laddr) in the queue named by (head).
580  *					Argument (flags) is ignored.
581  *
582  * RETURNS:			ptr to the isopcb if it finds a connection matching
583  *					these arguments, o.w. returns zero.
584  *
585  * SIDE EFFECTS:
586  *
587  * NOTES:
588  */
589 struct isopcb *
590 iso_pcblookup(head, fport, laddr, lport, flags)
591 	struct isopcb *head;
592 	struct iso_addr *laddr;
593 	u_short fport, lport;
594 	int flags;
595 {
596 	register struct isopcb *isop;
597 
598 	IFDEBUG(D_ISO)
599 		printf("iso_pcblookup(head 0x%x lport 0x%x fport 0x%x)\n",
600 			head, lport, fport);
601 	ENDDEBUG
602 	for (isop = head->isop_next; isop != head; isop = isop->isop_next) {
603 #ifdef notdef
604 	/*
605 	 * This should be changed to do bcmp on lsuffix in the tpcb instead
606 	 * since we should be ignoring the lport concept.
607 	 */
608 #endif notdef
609 		if (isop->isop_lport != lport)
610 			continue;
611 		if (isop->isop_fport != fport)
612 			continue;
613 		/*	PHASE2
614 		 *	addrmatch1 should be iso_addrmatch(a, b, mask)
615 		 *	where mask is taken from isop->isop_laddrmask (new field)
616 		 *	isop_lnetmask will also be available in isop
617 		 */
618 		if (laddr != &zeroiso_addr &&
619 			!iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr)))
620 			continue;
621 		return (isop);
622 	}
623 	return (struct isopcb *)0;
624 }
625 #endif ISO
626