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