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