]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netiso/iso.c
c625d013a1d235087288ecf62f25e3d959ea2f4f
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1991, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
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.
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
54 * @(#)iso.c 8.2 (Berkeley) 11/15/93
57 /***********************************************************
58 Copyright IBM Corporation 1987
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.
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
78 ******************************************************************/
81 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
84 * iso.c: miscellaneous routines to support the iso address family
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/ioctl.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>
99 #include <net/route.h>
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>
108 #include <netiso/tuba_table.h>
113 int iso_interfaces
= 0; /* number of external interfaces */
114 extern struct ifnet loif
; /* loopback interface */
116 void llc_rtrequest();
119 * FUNCTION: iso_addrmatch1
121 * PURPOSE: decide if the two iso_addrs passed are equal
123 * RETURNS: true if the addrs match, false if they do not
129 iso_addrmatch1(isoaa
, isoab
)
130 register struct iso_addr
*isoaa
, *isoab
; /* addresses to check */
135 printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa
->isoa_len
,
138 dump_buf(isoaa
->isoa_genaddr
, isoaa
->isoa_len
);
140 dump_buf(isoab
->isoa_genaddr
, isoab
->isoa_len
);
143 if ((compare_len
= isoaa
->isoa_len
) != isoab
->isoa_len
) {
145 printf("iso_addrmatch1: returning false because of lengths\n");
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
156 compare_len
= ADDR37_IDI_LEN
- 1;
164 a
= isoaa
->isoa_genaddr
;
165 b
= isoab
->isoa_genaddr
;
167 for (i
=0; i
<compare_len
; i
++) {
168 printf("<%x=%x>", a
[i
]&0xff, b
[i
]&0xff);
170 printf("\naddrs are not equal at byte %d\n", i
);
175 printf("addrs are equal\n");
178 return (!bcmp(isoaa
->isoa_genaddr
, isoab
->isoa_genaddr
, compare_len
));
182 * FUNCTION: iso_addrmatch
184 * PURPOSE: decide if the two sockadrr_isos passed are equal
186 * RETURNS: true if the addrs match, false if they do not
192 iso_addrmatch(sisoa
, sisob
)
193 struct sockaddr_iso
*sisoa
, *sisob
; /* addresses to check */
195 return(iso_addrmatch1(&sisoa
->siso_addr
, &sisob
->siso_addr
));
199 * FUNCTION: iso_netmatch
201 * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso
204 * RETURNS: true if same net, false if not
210 iso_netmatch(sisoa
, sisob
)
211 struct sockaddr_iso
*sisoa
, *sisob
;
213 u_char bufa
[sizeof(struct sockaddr_iso
)];
214 u_char bufb
[sizeof(struct sockaddr_iso
)];
215 register int lena
, lenb
;
217 lena
= iso_netof(&sisoa
->siso_addr
, bufa
);
218 lenb
= iso_netof(&sisob
->siso_addr
, bufb
);
221 printf("iso_netmatch: comparing lengths: %d to %d\n", lena
, lenb
);
223 dump_buf(bufa
, lena
);
225 dump_buf(bufb
, lenb
);
228 return ((lena
== lenb
) && (!bcmp(bufa
, bufb
, lena
)));
233 * FUNCTION: iso_hashchar
235 * PURPOSE: Hash all character in the buffer specified into
236 * a long. Return the long.
238 * RETURNS: The hash value.
242 * NOTES: The hash is achieved by exclusive ORing 4 byte
246 iso_hashchar(buf
, len
)
247 register caddr_t buf
; /* buffer to pack from */
248 register int len
; /* length of buffer */
250 register u_long h
= 0;
253 for (i
=0; i
<len
; i
+=4) {
254 register u_long l
= 0;
257 /* buffer not multiple of 4 */
267 printf("iso_hashchar: unexpected value x%x\n", len
- i
);
280 h
^= (u_long
) (len
% 4);
288 * PURPOSE: Fill in fields of afhash structure based upon addr passed.
297 struct sockaddr_iso
*siso
; /* address to perform hash on */
298 struct afhash
*hp
; /* RETURN: hash info here */
300 u_long buf
[sizeof(struct sockaddr_iso
)+1/4];
301 register int bufsize
;
304 bzero(buf
, sizeof(buf
));
306 bufsize
= iso_netof(&siso
->siso_addr
, buf
);
307 hp
->afh_nethash
= iso_hashchar((caddr_t
)buf
, bufsize
);
310 printf("iso_hash: iso_netof: bufsize = %d\n", bufsize
);
313 hp
->afh_hosthash
= iso_hashchar((caddr_t
)&siso
->siso_addr
,
314 siso
->siso_addr
.isoa_len
);
317 printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
318 clnp_iso_addrp(&siso
->siso_addr
), hp
->afh_nethash
,
323 * FUNCTION: iso_netof
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:
331 * t37 The AFI and x.121 (IDI)
332 * osinet The AFI, orgid, snetid
333 * rfc986 The AFI, vers and network part of
336 * RETURNS: number of bytes placed into buf.
340 * NOTES: Buf is assumed to be big enough
343 struct iso_addr
*isoa
; /* address */
344 caddr_t buf
; /* RESULT: network portion of address here */
346 u_int len
= 1; /* length of afi */
348 switch (isoa
->isoa_afi
) {
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
360 /* case AFI_OSINET:*/
362 u_short idi
; /* value of idi */
364 /* osinet and rfc986 have idi in the same place */
365 CTOH(isoa
->rfc986_idi
[0], isoa
->rfc986_idi
[1], idi
);
367 if (idi
== IDI_OSINET
)
369 * Network portion of OSINET address can only be the IDI. Clearly,
370 * with one x25 interface, one could get to several orgids, and
372 len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
373 OVLOSINET_SNETID_LEN);
375 len
+= ADDROSINET_IDI_LEN
;
376 else if (idi
== IDI_RFC986
) {
378 struct ovl_rfc986
*o986
= (struct ovl_rfc986
*)isoa
;
380 /* bump len to include idi and version (1 byte) */
381 len
+= ADDRRFC986_IDI_LEN
+ 1;
383 /* get inet addr long aligned */
384 bcopy(o986
->o986_inetaddr
, &inetaddr
, sizeof(inetaddr
));
385 inetaddr
= ntohl(inetaddr
); /* convert to host byte order */
388 printf("iso_netof: isoa ");
389 dump_buf(isoa
, sizeof(*isoa
));
390 printf("iso_netof: inetaddr 0x%x ", inetaddr
);
393 /* bump len by size of network portion of inet address */
394 if (IN_CLASSA(inetaddr
)) {
395 len
+= 4-IN_CLASSA_NSHIFT
/8;
397 printf("iso_netof: class A net len is now %d\n", len
);
399 } else if (IN_CLASSB(inetaddr
)) {
400 len
+= 4-IN_CLASSB_NSHIFT
/8;
402 printf("iso_netof: class B net len is now %d\n", len
);
405 len
+= 4-IN_CLASSC_NSHIFT
/8;
407 printf("iso_netof: class C net len is now %d\n", len
);
418 bcopy((caddr_t
)isoa
, buf
, len
);
420 printf("iso_netof: isoa ");
422 printf("iso_netof: net ");
429 * Generic iso control operations (ioctl's).
430 * Ifp is 0 if not an interface-specific ioctl.
433 iso_control(so
, cmd
, data
, ifp
)
437 register struct ifnet
*ifp
;
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
;
447 * Find address for this interface, if it exists.
450 for (ia
= iso_ifaddr
; ia
; ia
= ia
->ia_next
)
451 if (ia
->ia_ifp
== ifp
)
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
))
464 if ((so
->so_state
& SS_PRIV
) == 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
);
473 /* XXXXXX can't be done in the proto init routines */
477 MALLOC(nia
, struct iso_ifaddr
*, sizeof(*nia
),
479 if (nia
== (struct iso_ifaddr
*)0)
481 bzero((caddr_t
)nia
, sizeof(*nia
));
482 if (ia
= iso_ifaddr
) {
483 for ( ; ia
->ia_next
; ia
= ia
->ia_next
)
489 if (ifa
= ifp
->if_addrlist
) {
490 for ( ; ifa
->ifa_next
; ifa
= ifa
->ifa_next
)
492 ifa
->ifa_next
= (struct ifaddr
*) ia
;
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
;
506 #define cmdbyte(x) (((x) >> 8) & 0xff)
508 if (cmdbyte(cmd
) == 'a')
509 return (snpac_ioctl(so
, cmd
, data
));
510 if (ia
== (struct iso_ifaddr
*)0)
511 return (EADDRNOTAVAIL
);
516 case SIOCGIFADDR_ISO
:
517 ifr
->ifr_Addr
= ia
->ia_addr
;
520 case SIOCGIFDSTADDR_ISO
:
521 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0)
523 ifr
->ifr_Addr
= ia
->ia_dstaddr
;
526 case SIOCGIFNETMASK_ISO
:
527 ifr
->ifr_Addr
= ia
->ia_sockmask
;
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
;
536 } else if (SAME_ISOADDR(&ia
->ia_addr
, &ifra
->ifra_addr
))
539 if (ifra
->ifra_mask
.siso_len
) {
540 iso_ifscrub(ifp
, ia
);
541 ia
->ia_sockmask
= ifra
->ifra_mask
;
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 */
550 if (ifra
->ifra_addr
.siso_family
== AF_ISO
&&
551 (hostIsNew
|| maskIsNew
)) {
552 error
= iso_ifinit(ifp
, ia
, &ifra
->ifra_addr
, 0);
554 if (ifra
->ifra_snpaoffset
)
555 ia
->ia_snpaoffset
= ifra
->ifra_snpaoffset
;
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
;
563 while (ifa
->ifa_next
&&
564 (ifa
->ifa_next
!= (struct ifaddr
*)ia
))
567 ifa
->ifa_next
= ((struct ifaddr
*)ia
)->ifa_next
;
569 printf("Couldn't unlink isoifaddr from ifp\n");
572 if (oia
== (ia
= iso_ifaddr
)) {
573 iso_ifaddr
= ia
->ia_next
;
575 while (ia
->ia_next
&& (ia
->ia_next
!= oia
)) {
579 ia
->ia_next
= oia
->ia_next
;
581 printf("Didn't unlink isoifadr from list\n");
583 IFAFREE((&oia
->ia_ifa
));
587 if (ifp
== 0 || ifp
->if_ioctl
== 0)
589 return ((*ifp
->if_ioctl
)(ifp
, cmd
, data
));
595 * Delete any existing route for an interface.
598 register struct ifnet
*ifp
;
599 register struct iso_ifaddr
*ia
;
601 int nsellength
= ia
->ia_addr
.siso_tlen
;
602 if ((ia
->ia_flags
& IFA_ROUTE
) == 0)
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
);
610 rtinit(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
612 ia
->ia_addr
.siso_tlen
= nsellength
;
613 ia
->ia_flags
&= ~IFA_ROUTE
;
617 * Initialize an interface's internet address
618 * and routing table entry.
620 iso_ifinit(ifp
, ia
, siso
, scrub
)
621 register struct ifnet
*ifp
;
622 register struct iso_ifaddr
*ia
;
623 struct sockaddr_iso
*siso
;
625 struct sockaddr_iso oldaddr
;
626 int s
= splimp(), error
, nsellength
;
628 oldaddr
= ia
->ia_addr
;
631 * Give the interface a chance to initialize
632 * if this is its first address,
633 * and to validate the address if necessary.
636 (error
= (*ifp
->if_ioctl
)(ifp
, SIOCSIFADDR
, (caddr_t
)ia
))) {
638 ia
->ia_addr
= oldaddr
;
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
;
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
;
653 * Add route for the network.
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
);
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
);
670 ia
->ia_addr
.siso_tlen
= nsellength
;
671 ia
->ia_flags
|= IFA_ROUTE
;
679 register struct sockaddr
*addr
;
681 register struct ifnet
*ifp
;
682 register struct ifaddr
*ifa
;
683 register u_int af
= addr
->sa_family
;
688 printf(">>> iso_ifwithidi addr\n");
689 dump_isoaddr( (struct sockaddr_iso
*)(addr
));
692 for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
694 printf("iso_ifwithidi ifnet %s\n", ifp
->if_name
);
696 for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
) {
698 printf("iso_ifwithidi address ");
699 dump_isoaddr( (struct sockaddr_iso
*)(ifa
->ifa_addr
));
701 if (ifa
->ifa_addr
->sa_family
!= addr
->sa_family
)
704 #define IFA_SIS(ifa)\
705 ((struct sockaddr_iso *)((ifa)->ifa_addr))
708 printf(" af same, args to iso_eqtype:\n");
709 printf("0x%x ", IFA_SIS(ifa
)->siso_addr
);
711 &(((struct sockaddr_iso
*)addr
)->siso_addr
));
714 if (iso_eqtype(&(IFA_SIS(ifa
)->siso_addr
),
715 &(((struct sockaddr_iso
*)addr
)->siso_addr
))) {
717 printf("ifa_ifwithidi: ifa found\n");
722 printf(" iso_eqtype failed\n");
726 return ((struct ifaddr
*)0);
731 * FUNCTION: iso_ck_addr
733 * PURPOSE: return true if the iso_addr passed is
734 * within the legal size limit for an iso address.
736 * RETURNS: true or false
742 struct iso_addr
*isoa
; /* address to check */
744 return (isoa
->isoa_len
<= 20);
750 * FUNCTION: iso_eqtype
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.
757 * RETURNS: true if the addresses are the same type
761 * NOTES: By type, I mean rfc986, t37, or osinet
763 * This will first compare afis. If they match, then
764 * if the addr is not t37, the idis must be compared.
766 iso_eqtype(isoaa
, isoab
)
767 struct iso_addr
*isoaa
; /* first addr to check */
768 struct iso_addr
*isoab
; /* other addr to check */
770 if (isoaa
->isoa_afi
== isoab
->isoa_afi
) {
771 if (isoaa
->isoa_afi
== AFI_37
)
774 return (!bcmp(&isoaa
->isoa_u
, &isoab
->isoa_u
, 2));
780 * FUNCTION: iso_localifa()
782 * PURPOSE: Find an interface addresss having a given destination
783 * or at least matching the net.
785 * RETURNS: ptr to an interface address
793 register struct sockaddr_iso
*siso
;
795 register struct iso_ifaddr
*ia
;
796 register char *cp1
, *cp2
, *cp3
;
797 register struct ifnet
*ifp
;
798 struct iso_ifaddr
*ia_maybe
= 0;
800 * We make one pass looking for both net matches and an exact
803 for (ia
= iso_ifaddr
; ia
; ia
= ia
->ia_next
) {
804 if ((ifp
= ia
->ia_ifp
) == 0 || ((ifp
->if_flags
& IFF_UP
) == 0))
806 if (ifp
->if_flags
& IFF_POINTOPOINT
) {
807 if ((ia
->ia_dstaddr
.siso_family
== AF_ISO
) &&
808 SAME_ISOADDR(&ia
->ia_dstaddr
, siso
))
811 if (SAME_ISOADDR(&ia
->ia_addr
, siso
))
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
;
821 if (*cp1
++ & (*cp2
++ ^ *cp3
++))
825 if (SAME_ISOADDR(&ia
->ia_addr
, siso
))
833 #include <netiso/cons.h>
836 * FUNCTION: iso_nlctloutput
838 * PURPOSE: Set options at the network level
844 * NOTES: This could embody some of the functions of
845 * rclnp_ctloutput and cons_ctloutput.
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 */
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 */
859 printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
860 cmd
, optname
, pcb
, m
);
863 if ((cmd
!= PRCO_GETOPT
) && (cmd
!= PRCO_SETOPT
))
866 data
= mtod(m
, caddr_t
);
867 data_len
= (m
)->m_len
;
870 printf("iso_nlctloutput: data is:\n");
871 dump_buf(data
, data_len
);
877 case CONSOPT_X25CRUD
:
878 if (cmd
== PRCO_GETOPT
) {
883 if (data_len
> MAXX25CRUDLEN
) {
889 printf("iso_nlctloutput: setting x25 crud\n");
892 bcopy(data
, (caddr_t
)isop
->isop_x25crud
, (unsigned)data_len
);
893 isop
->isop_x25crud_len
= data_len
;
900 if (cmd
== PRCO_SETOPT
)
909 * FUNCTION: dump_isoaddr
917 struct sockaddr_iso
*s
;
919 char *clnp_saddr_isop();
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
) {
927 struct sockaddr_in
*sin
= (struct sockaddr_in
*)s
;
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,
938 #endif /* ARGO_DEBUG */