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