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