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