|
|
1.1 root 1: /***********************************************************
2: Copyright IBM Corporation 1987
3:
4: All Rights Reserved
5:
6: Permission to use, copy, modify, and distribute this software and its
7: documentation for any purpose and without fee is hereby granted,
8: provided that the above copyright notice appear in all copies and that
9: both that copyright notice and this permission notice appear in
10: supporting documentation, and that the name of IBM not be
11: used in advertising or publicity pertaining to distribution of the
12: software without specific, written prior permission.
13:
14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20: SOFTWARE.
21:
22: ******************************************************************/
23:
24: /*
25: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
26: */
27: /*
28: * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $
29: * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $
30: * @(#)iso.c 7.10 (Berkeley) 6/22/90
31: *
32: * iso.c: miscellaneous routines to support the iso address family
33: */
34:
35: #ifndef lint
36: static char *rcsid = "$Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $";
37: #endif
38:
39:
40: #include "types.h"
41: #include "param.h"
42: #include "ioctl.h"
43: #include "mbuf.h"
44: #include "domain.h"
45: #include "protosw.h"
46: #include "socket.h"
47: #include "socketvar.h"
48: #include "user.h"
49: #include "errno.h"
50:
51: #include "../net/if.h"
52: #include "../net/route.h"
53: #include "../net/af.h"
54:
55: #include "iso.h"
56: #include "iso_var.h"
57: #include "iso_snpac.h"
58: #include "iso_pcb.h"
59: #include "clnp.h"
60: #include "argo_debug.h"
61:
62: #ifdef ISO
63: #include "argoxtwentyfive.h"
64:
65: int iso_interfaces = 0; /* number of external interfaces */
66: extern struct ifnet loif; /* loopback interface */
67: int ether_output(), llc_rtrequest();
68:
69:
70: /*
71: * FUNCTION: iso_init
72: *
73: * PURPOSE: initialize the iso address family
74: *
75: * RETURNS: nothing
76: *
77: * SIDE EFFECTS: 1) zeros the maptab table.
78: * 2) initializes the routing table.
79: *
80: * NOTES:
81: */
82: struct radix_node_head *iso_rnhead;
83: iso_init()
84: {
85: static iso_init_done;
86:
87: if (iso_init_done == 0) {
88: iso_init_done++;
89: rn_inithead(&iso_rnhead, 40, AF_ISO);
90: }
91: }
92:
93: /*
94: * FUNCTION: iso_addrmatch1
95: *
96: * PURPOSE: decide if the two iso_addrs passed are equal
97: *
98: * RETURNS: true if the addrs match, false if they do not
99: *
100: * SIDE EFFECTS:
101: *
102: * NOTES:
103: */
104: iso_addrmatch1(isoaa, isoab)
105: register struct iso_addr *isoaa, *isoab; /* addresses to check */
106: {
107: u_int compare_len;
108:
109: IFDEBUG(D_ROUTE)
110: printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
111: isoab->isoa_len);
112: printf("a:\n");
113: dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
114: printf("b:\n");
115: dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
116: ENDDEBUG
117:
118: if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
119: IFDEBUG(D_ROUTE)
120: printf("iso_addrmatch1: returning false because of lengths\n");
121: ENDDEBUG
122: return 0;
123: }
124:
125: #ifdef notdef
126: /* TODO : generalize this to all afis with masks */
127: if( isoaa->isoa_afi == AFI_37 ) {
128: /* must not compare 2 least significant digits, or for
129: * that matter, the DSP
130: */
131: compare_len = ADDR37_IDI_LEN - 1;
132: }
133: #endif
134:
135: IFDEBUG(D_ROUTE)
136: int i;
137: char *a, *b;
138:
139: a = isoaa->isoa_genaddr;
140: b = isoab->isoa_genaddr;
141:
142: for (i=0; i<compare_len; i++) {
143: printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
144: if (a[i] != b[i]) {
145: printf("\naddrs are not equal at byte %d\n", i);
146: return(0);
147: }
148: }
149: printf("\n");
150: printf("addrs are equal\n");
151: return (1);
152: ENDDEBUG
153: return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
154: }
155:
156: /*
157: * FUNCTION: iso_addrmatch
158: *
159: * PURPOSE: decide if the two sockadrr_isos passed are equal
160: *
161: * RETURNS: true if the addrs match, false if they do not
162: *
163: * SIDE EFFECTS:
164: *
165: * NOTES:
166: */
167: iso_addrmatch(sisoa, sisob)
168: struct sockaddr_iso *sisoa, *sisob; /* addresses to check */
169: {
170: return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
171: }
172: #ifdef notdef
173: /*
174: * FUNCTION: iso_netmatch
175: *
176: * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso
177: * as argument.
178: *
179: * RETURNS: true if same net, false if not
180: *
181: * SIDE EFFECTS:
182: *
183: * NOTES:
184: */
185: iso_netmatch(sisoa, sisob)
186: struct sockaddr_iso *sisoa, *sisob;
187: {
188: u_char bufa[sizeof(struct sockaddr_iso)];
189: u_char bufb[sizeof(struct sockaddr_iso)];
190: register int lena, lenb;
191:
192: lena = iso_netof(&sisoa->siso_addr, bufa);
193: lenb = iso_netof(&sisob->siso_addr, bufb);
194:
195: IFDEBUG(D_ROUTE)
196: printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
197: printf("a:\n");
198: dump_buf(bufa, lena);
199: printf("b:\n");
200: dump_buf(bufb, lenb);
201: ENDDEBUG
202:
203: return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
204: }
205: #endif notdef
206:
207: /*
208: * FUNCTION: iso_hashchar
209: *
210: * PURPOSE: Hash all character in the buffer specified into
211: * a long. Return the long.
212: *
213: * RETURNS: The hash value.
214: *
215: * SIDE EFFECTS:
216: *
217: * NOTES: The hash is achieved by exclusive ORing 4 byte
218: * quantities.
219: */
220: u_long
221: iso_hashchar(buf, len)
222: register caddr_t buf; /* buffer to pack from */
223: register int len; /* length of buffer */
224: {
225: register u_long h = 0;
226: register int i;
227:
228: for (i=0; i<len; i+=4) {
229: register u_long l = 0;
230:
231: if ((len - i) < 4) {
232: /* buffer not multiple of 4 */
233: switch (len - i) {
234: case 3:
235: l |= buf[i+2] << 8;
236: case 2:
237: l |= buf[i+1] << 16;
238: case 1:
239: l |= buf[i] << 24;
240: break;
241: default:
242: printf("iso_hashchar: unexpected value x%x\n", len - i);
243: break;
244: }
245: } else {
246: l |= buf[i] << 24;
247: l |= buf[i+1] << 16;
248: l |= buf[i+2] << 8;
249: l |= buf[i+3];
250: }
251:
252: h ^= l;
253: }
254:
255: h ^= (u_long) (len % 4);
256:
257: return(h);
258: }
259: #ifdef notdef
260: /*
261: * FUNCTION: iso_hash
262: *
263: * PURPOSE: Fill in fields of afhash structure based upon addr passed.
264: *
265: * RETURNS: none
266: *
267: * SIDE EFFECTS:
268: *
269: * NOTES:
270: */
271: iso_hash(siso, hp)
272: struct sockaddr_iso *siso; /* address to perform hash on */
273: struct afhash *hp; /* RETURN: hash info here */
274: {
275: u_long buf[sizeof(struct sockaddr_iso)+1/4];
276: register int bufsize;
277:
278:
279: bzero(buf, sizeof(buf));
280:
281: bufsize = iso_netof(&siso->siso_addr, buf);
282: hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
283:
284: IFDEBUG(D_ROUTE)
285: printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
286: ENDDEBUG
287:
288: hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
289: siso->siso_addr.isoa_len);
290:
291: IFDEBUG(D_ROUTE)
292: printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
293: clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
294: hp->afh_hosthash);
295: ENDDEBUG
296: }
297: /*
298: * FUNCTION: iso_netof
299: *
300: * PURPOSE: Extract the network portion of the iso address.
301: * The network portion of the iso address varies depending
302: * on the type of address. The network portion of the
303: * address will include the IDP. The network portion is:
304: *
305: * TYPE DESC
306: * t37 The AFI and x.121 (IDI)
307: * osinet The AFI, orgid, snetid
308: * rfc986 The AFI, vers and network part of
309: * internet address.
310: *
311: * RETURNS: number of bytes placed into buf.
312: *
313: * SIDE EFFECTS:
314: *
315: * NOTES: Buf is assumed to be big enough
316: */
317: iso_netof(isoa, buf)
318: struct iso_addr *isoa; /* address */
319: caddr_t buf; /* RESULT: network portion of address here */
320: {
321: u_int len = 1; /* length of afi */
322:
323: switch (isoa->isoa_afi) {
324: case AFI_37:
325: /*
326: * Due to classic x.25 tunnel vision, there is no
327: * net portion of an x.121 address. For our purposes
328: * the AFI will do, so that all x.25 -type addresses
329: * map to the single x.25 SNPA. (Cannot have more than
330: * one, obviously).
331: */
332:
333: break;
334:
335: /* case AFI_OSINET:*/
336: case AFI_RFC986: {
337: u_short idi; /* value of idi */
338:
339: /* osinet and rfc986 have idi in the same place */
340: CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
341:
342: if (idi == IDI_OSINET)
343: /*
344: * Network portion of OSINET address can only be the IDI. Clearly,
345: * with one x25 interface, one could get to several orgids, and
346: * several snetids.
347: len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
348: OVLOSINET_SNETID_LEN);
349: */
350: len += ADDROSINET_IDI_LEN;
351: else if (idi == IDI_RFC986) {
352: u_long inetaddr;
353: struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa;
354:
355: /* bump len to include idi and version (1 byte) */
356: len += ADDRRFC986_IDI_LEN + 1;
357:
358: /* get inet addr long aligned */
359: bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
360: inetaddr = ntohl(inetaddr); /* convert to host byte order */
361:
362: IFDEBUG(D_ROUTE)
363: printf("iso_netof: isoa ");
364: dump_buf(isoa, sizeof(*isoa));
365: printf("iso_netof: inetaddr 0x%x ", inetaddr);
366: ENDDEBUG
367:
368: /* bump len by size of network portion of inet address */
369: if (IN_CLASSA(inetaddr)) {
370: len += 4-IN_CLASSA_NSHIFT/8;
371: IFDEBUG(D_ROUTE)
372: printf("iso_netof: class A net len is now %d\n", len);
373: ENDDEBUG
374: } else if (IN_CLASSB(inetaddr)) {
375: len += 4-IN_CLASSB_NSHIFT/8;
376: IFDEBUG(D_ROUTE)
377: printf("iso_netof: class B net len is now %d\n", len);
378: ENDDEBUG
379: } else {
380: len += 4-IN_CLASSC_NSHIFT/8;
381: IFDEBUG(D_ROUTE)
382: printf("iso_netof: class C net len is now %d\n", len);
383: ENDDEBUG
384: }
385: } else
386: len = 0;
387: } break;
388:
389: default:
390: len = 0;
391: }
392:
393: bcopy((caddr_t)isoa, buf, len);
394: IFDEBUG(D_ROUTE)
395: printf("in_netof: isoa ");
396: dump_buf(isoa, len);
397: printf("in_netof: net ");
398: dump_buf(buf, len);
399: ENDDEBUG
400: return len;
401: }
402: #endif notdef
403: /*
404: * Generic iso control operations (ioctl's).
405: * Ifp is 0 if not an interface-specific ioctl.
406: */
407: /* ARGSUSED */
408: iso_control(so, cmd, data, ifp)
409: struct socket *so;
410: int cmd;
411: caddr_t data;
412: register struct ifnet *ifp;
413: {
414: register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
415: register struct iso_ifaddr *ia = 0;
416: register struct ifaddr *ifa;
417: struct iso_ifaddr *oia;
418: struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
419: int error, hostIsNew, maskIsNew;
420:
421: /*
422: * Find address for this interface, if it exists.
423: */
424: if (ifp)
425: for (ia = iso_ifaddr; ia; ia = ia->ia_next)
426: if (ia->ia_ifp == ifp)
427: break;
428:
429: switch (cmd) {
430:
431: case SIOCAIFADDR_ISO:
432: case SIOCDIFADDR_ISO:
433: if (ifra->ifra_addr.siso_family == AF_ISO)
434: for (oia = ia; ia; ia = ia->ia_next) {
435: if (ia->ia_ifp == ifp &&
436: SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
437: break;
438: }
439: if (error = suser(u.u_cred, &u.u_acflag))
440: return (error);
441: if (ifp == 0)
442: panic("iso_control");
443: if (ia == (struct iso_ifaddr *)0) {
444: struct iso_ifaddr *nia;
445: if (cmd == SIOCDIFADDR_ISO)
446: return (EADDRNOTAVAIL);
447: MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
448: M_IFADDR, M_WAITOK);
449: if (nia == (struct iso_ifaddr *)0)
450: return (ENOBUFS);
451: bzero((caddr_t)nia, sizeof(*nia));
452: if (ia = iso_ifaddr) {
453: for ( ; ia->ia_next; ia = ia->ia_next)
454: ;
455: ia->ia_next = nia;
456: } else
457: iso_ifaddr = nia;
458: ia = nia;
459: if (ifa = ifp->if_addrlist) {
460: for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
461: ;
462: ifa->ifa_next = (struct ifaddr *) ia;
463: } else
464: ifp->if_addrlist = (struct ifaddr *) ia;
465: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
466: ia->ia_ifa.ifa_dstaddr
467: = (struct sockaddr *)&ia->ia_dstaddr;
468: ia->ia_ifa.ifa_netmask
469: = (struct sockaddr *)&ia->ia_sockmask;
470: ia->ia_ifp = ifp;
471: if (ifp != &loif)
472: iso_interfaces++;
473: }
474: break;
475:
476: #define cmdbyte(x) (((x) >> 8) & 0xff)
477: default:
478: if (cmdbyte(cmd) == 'a')
479: return (snpac_ioctl(cmd, data));
480: if (ia == (struct iso_ifaddr *)0)
481: return (EADDRNOTAVAIL);
482: break;
483: }
484: switch (cmd) {
485:
486: case SIOCGIFADDR_ISO:
487: ifr->ifr_Addr = ia->ia_addr;
488: break;
489:
490: case SIOCGIFDSTADDR_ISO:
491: if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
492: return (EINVAL);
493: ifr->ifr_Addr = ia->ia_dstaddr;
494: break;
495:
496: case SIOCGIFNETMASK_ISO:
497: ifr->ifr_Addr = ia->ia_sockmask;
498: break;
499:
500: case SIOCAIFADDR_ISO:
501: maskIsNew = 0; hostIsNew = 1; error = 0;
502: if (ia->ia_addr.siso_family == AF_ISO) {
503: if (ifra->ifra_addr.siso_len == 0) {
504: ifra->ifra_addr = ia->ia_addr;
505: hostIsNew = 0;
506: } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
507: hostIsNew = 0;
508: }
509: if (ifra->ifra_mask.siso_len) {
510: iso_ifscrub(ifp, ia);
511: ia->ia_sockmask = ifra->ifra_mask;
512: maskIsNew = 1;
513: }
514: if ((ifp->if_flags & IFF_POINTOPOINT) &&
515: (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
516: iso_ifscrub(ifp, ia);
517: ia->ia_dstaddr = ifra->ifra_dstaddr;
518: maskIsNew = 1; /* We lie; but the effect's the same */
519: }
520: if (ifra->ifra_addr.siso_family == AF_ISO &&
521: (hostIsNew || maskIsNew)) {
522: error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
523: }
524: if (ifra->ifra_snpaoffset)
525: ia->ia_snpaoffset = ifra->ifra_snpaoffset;
526: return (error);
527:
528: case SIOCDIFADDR_ISO:
529: iso_ifscrub(ifp, ia);
530: if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
531: ifp->if_addrlist = ifa->ifa_next;
532: else {
533: while (ifa->ifa_next &&
534: (ifa->ifa_next != (struct ifaddr *)ia))
535: ifa = ifa->ifa_next;
536: if (ifa->ifa_next)
537: ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
538: else
539: printf("Couldn't unlink isoifaddr from ifp\n");
540: }
541: oia = ia;
542: if (oia == (ia = iso_ifaddr)) {
543: iso_ifaddr = ia->ia_next;
544: } else {
545: while (ia->ia_next && (ia->ia_next != oia)) {
546: ia = ia->ia_next;
547: }
548: if (ia->ia_next)
549: ia->ia_next = oia->ia_next;
550: else
551: printf("Didn't unlink isoifadr from list\n");
552: }
553: free((caddr_t)oia, M_IFADDR);
554: break;
555:
556: default:
557: if (ifp == 0 || ifp->if_ioctl == 0)
558: return (EOPNOTSUPP);
559: return ((*ifp->if_ioctl)(ifp, cmd, data));
560: }
561: return (0);
562: }
563:
564: /*
565: * Delete any existing route for an interface.
566: */
567: iso_ifscrub(ifp, ia)
568: register struct ifnet *ifp;
569: register struct iso_ifaddr *ia;
570: {
571: int nsellength = ia->ia_addr.siso_tlen;
572: if ((ia->ia_flags & IFA_ROUTE) == 0)
573: return;
574: ia->ia_addr.siso_tlen = 0;
575: if (ifp->if_flags & IFF_LOOPBACK)
576: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
577: else if (ifp->if_flags & IFF_POINTOPOINT)
578: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
579: else {
580: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
581: }
582: ia->ia_addr.siso_tlen = nsellength;
583: ia->ia_flags &= ~IFA_ROUTE;
584: }
585:
586: /*
587: * Initialize an interface's internet address
588: * and routing table entry.
589: */
590: iso_ifinit(ifp, ia, siso, scrub)
591: register struct ifnet *ifp;
592: register struct iso_ifaddr *ia;
593: struct sockaddr_iso *siso;
594: {
595: struct sockaddr_iso oldaddr;
596: int s = splimp(), error, nsellength;
597:
598: oldaddr = ia->ia_addr;
599: ia->ia_addr = *siso;
600: /*
601: * Give the interface a chance to initialize
602: * if this is its first address,
603: * and to validate the address if necessary.
604: */
605: if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
606: splx(s);
607: ia->ia_addr = oldaddr;
608: return (error);
609: }
610: if (scrub) {
611: ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
612: iso_ifscrub(ifp, ia);
613: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
614: }
615: /* XXX -- The following is here temporarily out of laziness
616: in not changing every ethernet driver's if_ioctl routine */
617: if (ifp->if_output == ether_output) {
618: ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
619: ia->ia_ifa.ifa_flags |= RTF_CLONING;
620: ia->ia_ifa.ifa_llinfolen = sizeof(struct llinfo_llc);
621: }
622: /*
623: * Add route for the network.
624: */
625: nsellength = ia->ia_addr.siso_tlen;
626: ia->ia_addr.siso_tlen = 0;
627: if (ifp->if_flags & IFF_LOOPBACK) {
628: ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
629: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
630: } else if (ifp->if_flags & IFF_POINTOPOINT &&
631: ia->ia_dstaddr.siso_family == AF_ISO)
632: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
633: else {
634: rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
635: ia->ia_ifa.ifa_netmask);
636: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
637: }
638: ia->ia_addr.siso_tlen = nsellength;
639: ia->ia_flags |= IFA_ROUTE;
640: splx(s);
641: return (error);
642: }
643: #ifdef notdef
644:
645: struct ifaddr *
646: iso_ifwithidi(addr)
647: register struct sockaddr *addr;
648: {
649: register struct ifnet *ifp;
650: register struct ifaddr *ifa;
651: register u_int af = addr->sa_family;
652:
653: if (af != AF_ISO)
654: return (0);
655: IFDEBUG(D_ROUTE)
656: printf(">>> iso_ifwithidi addr\n");
657: dump_isoaddr( (struct sockaddr_iso *)(addr));
658: printf("\n");
659: ENDDEBUG
660: for (ifp = ifnet; ifp; ifp = ifp->if_next) {
661: IFDEBUG(D_ROUTE)
662: printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
663: ENDDEBUG
664: for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
665: IFDEBUG(D_ROUTE)
666: printf("iso_ifwithidi address ");
667: dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
668: ENDDEBUG
669: if (ifa->ifa_addr->sa_family != addr->sa_family)
670: continue;
671:
672: #define IFA_SIS(ifa)\
673: ((struct sockaddr_iso *)((ifa)->ifa_addr))
674:
675: IFDEBUG(D_ROUTE)
676: printf(" af same, args to iso_eqtype:\n");
677: printf("0x%x ", IFA_SIS(ifa)->siso_addr);
678: printf(" 0x%x\n",
679: &(((struct sockaddr_iso *)addr)->siso_addr));
680: ENDDEBUG
681:
682: if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
683: &(((struct sockaddr_iso *)addr)->siso_addr))) {
684: IFDEBUG(D_ROUTE)
685: printf("ifa_ifwithidi: ifa found\n");
686: ENDDEBUG
687: return (ifa);
688: }
689: IFDEBUG(D_ROUTE)
690: printf(" iso_eqtype failed\n");
691: ENDDEBUG
692: }
693: }
694: return ((struct ifaddr *)0);
695: }
696:
697: #endif notdef
698: /*
699: * FUNCTION: iso_ck_addr
700: *
701: * PURPOSE: return true if the iso_addr passed is
702: * within the legal size limit for an iso address.
703: *
704: * RETURNS: true or false
705: *
706: * SIDE EFFECTS:
707: *
708: */
709: iso_ck_addr(isoa)
710: struct iso_addr *isoa; /* address to check */
711: {
712: return (isoa->isoa_len <= 20);
713:
714: }
715:
716: #ifdef notdef
717: /*
718: * FUNCTION: iso_eqtype
719: *
720: * PURPOSE: Determine if two iso addresses are of the same type.
721: * This is flaky. Really we should consider all type 47 addrs to be the
722: * same - but there do exist different structures for 47 addrs.
723: * Gosip adds a 3rd.
724: *
725: * RETURNS: true if the addresses are the same type
726: *
727: * SIDE EFFECTS:
728: *
729: * NOTES: By type, I mean rfc986, t37, or osinet
730: *
731: * This will first compare afis. If they match, then
732: * if the addr is not t37, the idis must be compared.
733: */
734: iso_eqtype(isoaa, isoab)
735: struct iso_addr *isoaa; /* first addr to check */
736: struct iso_addr *isoab; /* other addr to check */
737: {
738: if (isoaa->isoa_afi == isoab->isoa_afi) {
739: if (isoaa->isoa_afi == AFI_37)
740: return(1);
741: else
742: return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
743: }
744: return(0);
745: }
746: #endif notdef
747: /*
748: * FUNCTION: iso_localifa()
749: *
750: * PURPOSE: Find an interface addresss having a given destination
751: * or at least matching the net.
752: *
753: * RETURNS: ptr to an interface address
754: *
755: * SIDE EFFECTS:
756: *
757: * NOTES:
758: */
759: struct iso_ifaddr *
760: iso_localifa(siso)
761: register struct sockaddr_iso *siso;
762: {
763: register struct iso_ifaddr *ia;
764: register char *cp1, *cp2, *cp3;
765: register struct ifnet *ifp;
766: struct iso_ifaddr *ia_maybe = 0;
767: /*
768: * We make one pass looking for both net matches and an exact
769: * dst addr.
770: */
771: for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
772: if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
773: continue;
774: if (ifp->if_flags & IFF_POINTOPOINT) {
775: if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
776: SAME_ISOADDR(&ia->ia_dstaddr, siso))
777: return (ia);
778: else
779: if (SAME_ISOADDR(&ia->ia_addr, siso))
780: ia_maybe = ia;
781: continue;
782: }
783: if (ia->ia_sockmask.siso_len) {
784: char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
785: cp1 = ia->ia_sockmask.siso_data;
786: cp2 = siso->siso_data;
787: cp3 = ia->ia_addr.siso_data;
788: while (cp1 < cplim)
789: if (*cp1++ & (*cp2++ ^ *cp3++))
790: goto next;
791: ia_maybe = ia;
792: }
793: if (SAME_ISOADDR(&ia->ia_addr, siso))
794: return ia;
795: next:;
796: }
797: return ia_maybe;
798: }
799:
800: #ifdef NARGOXTWENTYFIVE > 0
801: #include "cons.h"
802: #endif NARGOXTWENTYFIVE > 0
803: /*
804: * FUNCTION: iso_nlctloutput
805: *
806: * PURPOSE: Set options at the network level
807: *
808: * RETURNS: E*
809: *
810: * SIDE EFFECTS:
811: *
812: * NOTES: This could embody some of the functions of
813: * rclnp_ctloutput and cons_ctloutput.
814: */
815: iso_nlctloutput(cmd, optname, pcb, m)
816: int cmd; /* command:set or get */
817: int optname; /* option of interest */
818: caddr_t pcb; /* nl pcb */
819: struct mbuf *m; /* data for set, buffer for get */
820: {
821: struct isopcb *isop = (struct isopcb *)pcb;
822: int error = 0; /* return value */
823: caddr_t data; /* data for option */
824: int data_len; /* data's length */
825:
826: IFDEBUG(D_ISO)
827: printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
828: cmd, optname, pcb, m);
829: ENDDEBUG
830:
831: if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
832: return(EOPNOTSUPP);
833:
834: data = mtod(m, caddr_t);
835: data_len = (m)->m_len;
836:
837: IFDEBUG(D_ISO)
838: printf("iso_nlctloutput: data is:\n");
839: dump_buf(data, data_len);
840: ENDDEBUG
841:
842: switch (optname) {
843:
844: #ifdef NARGOXTWENTYFIVE > 0
845: case CONSOPT_X25CRUD:
846: if (cmd == PRCO_GETOPT) {
847: error = EOPNOTSUPP;
848: break;
849: }
850:
851: if (data_len > MAXX25CRUDLEN) {
852: error = EINVAL;
853: break;
854: }
855:
856: IFDEBUG(D_ISO)
857: printf("iso_nlctloutput: setting x25 crud\n");
858: ENDDEBUG
859:
860: bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
861: isop->isop_x25crud_len = data_len;
862: break;
863: #endif NARGOXTWENTYFIVE > 0
864:
865: default:
866: error = EOPNOTSUPP;
867: }
868:
869: return error;
870: }
871: #endif ISO
872:
873: #ifdef ARGO_DEBUG
874:
875: /*
876: * FUNCTION: dump_isoaddr
877: *
878: * PURPOSE: debugging
879: *
880: * RETURNS: nada
881: *
882: */
883: dump_isoaddr(s)
884: struct sockaddr_iso *s;
885: {
886: char *clnp_saddr_isop();
887: register int i;
888:
889: if( s->siso_family == AF_ISO) {
890: printf("ISO address: suffixlen %d, %s\n",
891: s->siso_tlen, clnp_saddr_isop(s));
892: } else if( s->siso_family == AF_INET) {
893: /* hack */
894: struct sockaddr_in *sin = (struct sockaddr_in *)s;
895:
896: printf("%d.%d.%d.%d: %d",
897: (sin->sin_addr.s_addr>>24)&0xff,
898: (sin->sin_addr.s_addr>>16)&0xff,
899: (sin->sin_addr.s_addr>>8)&0xff,
900: (sin->sin_addr.s_addr)&0xff,
901: sin->sin_port);
902: }
903: }
904:
905: #endif ARGO_DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.