|
|
1.1 root 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:
62: Permission to use, copy, modify, and distribute this software and its
63: documentation for any purpose and without fee is hereby granted,
64: provided that the above copyright notice appear in all copies and that
65: both that copyright notice and this permission notice appear in
66: supporting documentation, and that the name of IBM not be
67: used in advertising or publicity pertaining to distribution of the
68: software without specific, written prior permission.
69:
70: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76: SOFTWARE.
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
113: struct 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: */
127: int
128: iso_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))
167: int
168: iso_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;
247: noname:
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: */
287: int
288: iso_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: */
428: void
429: iso_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: */
466: void
467: iso_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: */
547: void
548: iso_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: */
596: struct isopcb *
597: iso_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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.