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