Fix definitions to be in terms of a minimum number of constants by
[unix-history] / sys / netiso / iso.c
CommitLineData
15637ed4
RG
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
41Permission to use, copy, modify, and distribute this software and its
42documentation for any purpose and without fee is hereby granted,
43provided that the above copyright notice appear in all copies and that
44both that copyright notice and this permission notice appear in
45supporting documentation, and that the name of IBM not be
46used in advertising or publicity pertaining to distribution of the
47software without specific, written prior permission.
48
49IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
50ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
51IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
52ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
53WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
54ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
55SOFTWARE.
56
57******************************************************************/
58
59/*
60 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
61 */
62/*
dd18dc33
DG
63 * $Header: /a/cvs/386BSD/src/sys/netiso/iso.c,v 1.1.1.1 1993/06/12 14:57:20 rgrimes Exp $
64 * $Source: /a/cvs/386BSD/src/sys/netiso/iso.c,v $
15637ed4
RG
65 *
66 * iso.c: miscellaneous routines to support the iso address family
67 */
68
69#include "types.h"
70#include "param.h"
dd18dc33 71#include "systm.h"
15637ed4
RG
72#include "ioctl.h"
73#include "mbuf.h"
74#include "domain.h"
75#include "protosw.h"
76#include "socket.h"
77#include "socketvar.h"
78#include "errno.h"
79
80#include "../net/if.h"
81#include "../net/route.h"
82#include "../net/af.h"
83
84#include "iso.h"
85#include "iso_var.h"
86#include "iso_snpac.h"
87#include "iso_pcb.h"
88#include "clnp.h"
89#include "argo_debug.h"
90
91#ifdef ISO
92
93int iso_interfaces = 0; /* number of external interfaces */
94extern struct ifnet loif; /* loopback interface */
95int ether_output(), llc_rtrequest();
96
97
98/*
99 * FUNCTION: iso_init
100 *
101 * PURPOSE: initialize the iso address family
102 *
103 * RETURNS: nothing
104 *
105 * SIDE EFFECTS: 1) initializes the routing table.
106 *
107 *
108 * NOTES:
109 */
110struct radix_node_head *iso_rnhead;
111iso_init()
112{
113 static iso_init_done;
114
115 if (iso_init_done == 0) {
116 iso_init_done++;
117 rn_inithead(&iso_rnhead, 48, AF_ISO);
118 }
119}
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 */
132iso_addrmatch1(isoaa, isoab)
133register 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 */
195iso_addrmatch(sisoa, sisob)
196struct 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 */
213iso_netmatch(sisoa, sisob)
214struct 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 */
248u_long
249iso_hashchar(buf, len)
250register caddr_t buf; /* buffer to pack from */
251register 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 */
299iso_hash(siso, hp)
300struct sockaddr_iso *siso; /* address to perform hash on */
301struct 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 */
345iso_netof(isoa, buf)
346struct iso_addr *isoa; /* address */
347caddr_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("in_netof: isoa ");
424 dump_buf(isoa, len);
425 printf("in_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 */
436iso_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 MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
476 M_IFADDR, M_WAITOK);
477 if (nia == (struct iso_ifaddr *)0)
478 return (ENOBUFS);
479 bzero((caddr_t)nia, sizeof(*nia));
480 if (ia = iso_ifaddr) {
481 for ( ; ia->ia_next; ia = ia->ia_next)
482 ;
483 ia->ia_next = nia;
484 } else
485 iso_ifaddr = nia;
486 ia = nia;
487 if (ifa = ifp->if_addrlist) {
488 for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
489 ;
490 ifa->ifa_next = (struct ifaddr *) ia;
491 } else
492 ifp->if_addrlist = (struct ifaddr *) ia;
493 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
494 ia->ia_ifa.ifa_dstaddr
495 = (struct sockaddr *)&ia->ia_dstaddr;
496 ia->ia_ifa.ifa_netmask
497 = (struct sockaddr *)&ia->ia_sockmask;
498 ia->ia_ifp = ifp;
499 if (ifp != &loif)
500 iso_interfaces++;
501 }
502 break;
503
504#define cmdbyte(x) (((x) >> 8) & 0xff)
505 default:
506 if (cmdbyte(cmd) == 'a')
507 return (snpac_ioctl(so, cmd, data));
508 if (ia == (struct iso_ifaddr *)0)
509 return (EADDRNOTAVAIL);
510 break;
511 }
512 switch (cmd) {
513
514 case SIOCGIFADDR_ISO:
515 ifr->ifr_Addr = ia->ia_addr;
516 break;
517
518 case SIOCGIFDSTADDR_ISO:
519 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
520 return (EINVAL);
521 ifr->ifr_Addr = ia->ia_dstaddr;
522 break;
523
524 case SIOCGIFNETMASK_ISO:
525 ifr->ifr_Addr = ia->ia_sockmask;
526 break;
527
528 case SIOCAIFADDR_ISO:
529 maskIsNew = 0; hostIsNew = 1; error = 0;
530 if (ia->ia_addr.siso_family == AF_ISO) {
531 if (ifra->ifra_addr.siso_len == 0) {
532 ifra->ifra_addr = ia->ia_addr;
533 hostIsNew = 0;
534 } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
535 hostIsNew = 0;
536 }
537 if (ifra->ifra_mask.siso_len) {
538 iso_ifscrub(ifp, ia);
539 ia->ia_sockmask = ifra->ifra_mask;
540 maskIsNew = 1;
541 }
542 if ((ifp->if_flags & IFF_POINTOPOINT) &&
543 (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
544 iso_ifscrub(ifp, ia);
545 ia->ia_dstaddr = ifra->ifra_dstaddr;
546 maskIsNew = 1; /* We lie; but the effect's the same */
547 }
548 if (ifra->ifra_addr.siso_family == AF_ISO &&
549 (hostIsNew || maskIsNew)) {
550 error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
551 }
552 if (ifra->ifra_snpaoffset)
553 ia->ia_snpaoffset = ifra->ifra_snpaoffset;
554 return (error);
555
556 case SIOCDIFADDR_ISO:
557 iso_ifscrub(ifp, ia);
558 if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
559 ifp->if_addrlist = ifa->ifa_next;
560 else {
561 while (ifa->ifa_next &&
562 (ifa->ifa_next != (struct ifaddr *)ia))
563 ifa = ifa->ifa_next;
564 if (ifa->ifa_next)
565 ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
566 else
567 printf("Couldn't unlink isoifaddr from ifp\n");
568 }
569 oia = ia;
570 if (oia == (ia = iso_ifaddr)) {
571 iso_ifaddr = ia->ia_next;
572 } else {
573 while (ia->ia_next && (ia->ia_next != oia)) {
574 ia = ia->ia_next;
575 }
576 if (ia->ia_next)
577 ia->ia_next = oia->ia_next;
578 else
579 printf("Didn't unlink isoifadr from list\n");
580 }
581 free((caddr_t)oia, M_IFADDR);
582 break;
583
584 default:
585 if (ifp == 0 || ifp->if_ioctl == 0)
586 return (EOPNOTSUPP);
587 return ((*ifp->if_ioctl)(ifp, cmd, data));
588 }
589 return (0);
590}
591
592/*
593 * Delete any existing route for an interface.
594 */
595iso_ifscrub(ifp, ia)
596 register struct ifnet *ifp;
597 register struct iso_ifaddr *ia;
598{
599 int nsellength = ia->ia_addr.siso_tlen;
600 if ((ia->ia_flags & IFA_ROUTE) == 0)
601 return;
602 ia->ia_addr.siso_tlen = 0;
603 if (ifp->if_flags & IFF_LOOPBACK)
604 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
605 else if (ifp->if_flags & IFF_POINTOPOINT)
606 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
607 else {
608 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
609 }
610 ia->ia_addr.siso_tlen = nsellength;
611 ia->ia_flags &= ~IFA_ROUTE;
612}
613
614/*
615 * Initialize an interface's internet address
616 * and routing table entry.
617 */
618iso_ifinit(ifp, ia, siso, scrub)
619 register struct ifnet *ifp;
620 register struct iso_ifaddr *ia;
621 struct sockaddr_iso *siso;
622{
623 struct sockaddr_iso oldaddr;
624 int s = splimp(), error, nsellength;
625
626 oldaddr = ia->ia_addr;
627 ia->ia_addr = *siso;
628 /*
629 * Give the interface a chance to initialize
630 * if this is its first address,
631 * and to validate the address if necessary.
632 */
633 if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
634 splx(s);
635 ia->ia_addr = oldaddr;
636 return (error);
637 }
638 if (scrub) {
639 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
640 iso_ifscrub(ifp, ia);
641 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
642 }
643 /* XXX -- The following is here temporarily out of laziness
644 in not changing every ethernet driver's if_ioctl routine */
645 if (ifp->if_output == ether_output) {
646 ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
647 ia->ia_ifa.ifa_flags |= RTF_CLONING;
648 ia->ia_ifa.ifa_llinfolen = sizeof(struct llinfo_llc);
649 }
650 /*
651 * Add route for the network.
652 */
653 nsellength = ia->ia_addr.siso_tlen;
654 ia->ia_addr.siso_tlen = 0;
655 if (ifp->if_flags & IFF_LOOPBACK) {
656 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
657 error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
658 } else if (ifp->if_flags & IFF_POINTOPOINT &&
659 ia->ia_dstaddr.siso_family == AF_ISO)
660 error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
661 else {
662 rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
663 ia->ia_ifa.ifa_netmask);
664 ia->ia_dstaddr.siso_nlen =
665 min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));
666 error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
667 }
668 ia->ia_addr.siso_tlen = nsellength;
669 ia->ia_flags |= IFA_ROUTE;
670 splx(s);
671 return (error);
672}
673#ifdef notdef
674
675struct ifaddr *
676iso_ifwithidi(addr)
677 register struct sockaddr *addr;
678{
679 register struct ifnet *ifp;
680 register struct ifaddr *ifa;
681 register u_int af = addr->sa_family;
682
683 if (af != AF_ISO)
684 return (0);
685 IFDEBUG(D_ROUTE)
686 printf(">>> iso_ifwithidi addr\n");
687 dump_isoaddr( (struct sockaddr_iso *)(addr));
688 printf("\n");
689 ENDDEBUG
690 for (ifp = ifnet; ifp; ifp = ifp->if_next) {
691 IFDEBUG(D_ROUTE)
692 printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
693 ENDDEBUG
694 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
695 IFDEBUG(D_ROUTE)
696 printf("iso_ifwithidi address ");
697 dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
698 ENDDEBUG
699 if (ifa->ifa_addr->sa_family != addr->sa_family)
700 continue;
701
702#define IFA_SIS(ifa)\
703 ((struct sockaddr_iso *)((ifa)->ifa_addr))
704
705 IFDEBUG(D_ROUTE)
706 printf(" af same, args to iso_eqtype:\n");
707 printf("0x%x ", IFA_SIS(ifa)->siso_addr);
708 printf(" 0x%x\n",
709 &(((struct sockaddr_iso *)addr)->siso_addr));
710 ENDDEBUG
711
712 if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
713 &(((struct sockaddr_iso *)addr)->siso_addr))) {
714 IFDEBUG(D_ROUTE)
715 printf("ifa_ifwithidi: ifa found\n");
716 ENDDEBUG
717 return (ifa);
718 }
719 IFDEBUG(D_ROUTE)
720 printf(" iso_eqtype failed\n");
721 ENDDEBUG
722 }
723 }
724 return ((struct ifaddr *)0);
725}
726
727#endif notdef
728/*
729 * FUNCTION: iso_ck_addr
730 *
731 * PURPOSE: return true if the iso_addr passed is
732 * within the legal size limit for an iso address.
733 *
734 * RETURNS: true or false
735 *
736 * SIDE EFFECTS:
737 *
738 */
739iso_ck_addr(isoa)
740struct iso_addr *isoa; /* address to check */
741{
742 return (isoa->isoa_len <= 20);
743
744}
745
746#ifdef notdef
747/*
748 * FUNCTION: iso_eqtype
749 *
750 * PURPOSE: Determine if two iso addresses are of the same type.
751 * This is flaky. Really we should consider all type 47 addrs to be the
752 * same - but there do exist different structures for 47 addrs.
753 * Gosip adds a 3rd.
754 *
755 * RETURNS: true if the addresses are the same type
756 *
757 * SIDE EFFECTS:
758 *
759 * NOTES: By type, I mean rfc986, t37, or osinet
760 *
761 * This will first compare afis. If they match, then
762 * if the addr is not t37, the idis must be compared.
763 */
764iso_eqtype(isoaa, isoab)
765struct iso_addr *isoaa; /* first addr to check */
766struct iso_addr *isoab; /* other addr to check */
767{
768 if (isoaa->isoa_afi == isoab->isoa_afi) {
769 if (isoaa->isoa_afi == AFI_37)
770 return(1);
771 else
772 return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
773 }
774 return(0);
775}
776#endif notdef
777/*
778 * FUNCTION: iso_localifa()
779 *
780 * PURPOSE: Find an interface addresss having a given destination
781 * or at least matching the net.
782 *
783 * RETURNS: ptr to an interface address
784 *
785 * SIDE EFFECTS:
786 *
787 * NOTES:
788 */
789struct iso_ifaddr *
790iso_localifa(siso)
791 register struct sockaddr_iso *siso;
792{
793 register struct iso_ifaddr *ia;
794 register char *cp1, *cp2, *cp3;
795 register struct ifnet *ifp;
796 struct iso_ifaddr *ia_maybe = 0;
797 /*
798 * We make one pass looking for both net matches and an exact
799 * dst addr.
800 */
801 for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
802 if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
803 continue;
804 if (ifp->if_flags & IFF_POINTOPOINT) {
805 if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
806 SAME_ISOADDR(&ia->ia_dstaddr, siso))
807 return (ia);
808 else
809 if (SAME_ISOADDR(&ia->ia_addr, siso))
810 ia_maybe = ia;
811 continue;
812 }
813 if (ia->ia_sockmask.siso_len) {
814 char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
815 cp1 = ia->ia_sockmask.siso_data;
816 cp2 = siso->siso_data;
817 cp3 = ia->ia_addr.siso_data;
818 while (cp1 < cplim)
819 if (*cp1++ & (*cp2++ ^ *cp3++))
820 goto next;
821 ia_maybe = ia;
822 }
823 if (SAME_ISOADDR(&ia->ia_addr, siso))
824 return ia;
825 next:;
826 }
827 return ia_maybe;
828}
829
830#ifdef TPCONS
831#include "cons.h"
832#endif TPCONS
833/*
834 * FUNCTION: iso_nlctloutput
835 *
836 * PURPOSE: Set options at the network level
837 *
838 * RETURNS: E*
839 *
840 * SIDE EFFECTS:
841 *
842 * NOTES: This could embody some of the functions of
843 * rclnp_ctloutput and cons_ctloutput.
844 */
845iso_nlctloutput(cmd, optname, pcb, m)
846int cmd; /* command:set or get */
847int optname; /* option of interest */
848caddr_t pcb; /* nl pcb */
849struct mbuf *m; /* data for set, buffer for get */
850{
851 struct isopcb *isop = (struct isopcb *)pcb;
852 int error = 0; /* return value */
853 caddr_t data; /* data for option */
854 int data_len; /* data's length */
855
856 IFDEBUG(D_ISO)
857 printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
858 cmd, optname, pcb, m);
859 ENDDEBUG
860
861 if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
862 return(EOPNOTSUPP);
863
864 data = mtod(m, caddr_t);
865 data_len = (m)->m_len;
866
867 IFDEBUG(D_ISO)
868 printf("iso_nlctloutput: data is:\n");
869 dump_buf(data, data_len);
870 ENDDEBUG
871
872 switch (optname) {
873
874#ifdef TPCONS
875 case CONSOPT_X25CRUD:
876 if (cmd == PRCO_GETOPT) {
877 error = EOPNOTSUPP;
878 break;
879 }
880
881 if (data_len > MAXX25CRUDLEN) {
882 error = EINVAL;
883 break;
884 }
885
886 IFDEBUG(D_ISO)
887 printf("iso_nlctloutput: setting x25 crud\n");
888 ENDDEBUG
889
890 bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
891 isop->isop_x25crud_len = data_len;
892 break;
893#endif TPCONS
894
895 default:
896 error = EOPNOTSUPP;
897 }
898
899 return error;
900}
901#endif ISO
902
903#ifdef ARGO_DEBUG
904
905/*
906 * FUNCTION: dump_isoaddr
907 *
908 * PURPOSE: debugging
909 *
910 * RETURNS: nada
911 *
912 */
913dump_isoaddr(s)
914 struct sockaddr_iso *s;
915{
916 char *clnp_saddr_isop();
917 register int i;
918
919 if( s->siso_family == AF_ISO) {
920 printf("ISO address: suffixlen %d, %s\n",
921 s->siso_tlen, clnp_saddr_isop(s));
922 } else if( s->siso_family == AF_INET) {
923 /* hack */
924 struct sockaddr_in *sin = (struct sockaddr_in *)s;
925
926 printf("%d.%d.%d.%d: %d",
927 (sin->sin_addr.s_addr>>24)&0xff,
928 (sin->sin_addr.s_addr>>16)&0xff,
929 (sin->sin_addr.s_addr>>8)&0xff,
930 (sin->sin_addr.s_addr)&0xff,
931 sin->sin_port);
932 }
933}
934
935#endif ARGO_DEBUG