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