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