xref: /csrg-svn/sys/netiso/iso.c (revision 37469)
136384Ssklower /***********************************************************
236384Ssklower 		Copyright IBM Corporation 1987
336384Ssklower 
436384Ssklower                       All Rights Reserved
536384Ssklower 
636384Ssklower Permission to use, copy, modify, and distribute this software and its
736384Ssklower documentation for any purpose and without fee is hereby granted,
836384Ssklower provided that the above copyright notice appear in all copies and that
936384Ssklower both that copyright notice and this permission notice appear in
1036384Ssklower supporting documentation, and that the name of IBM not be
1136384Ssklower used in advertising or publicity pertaining to distribution of the
1236384Ssklower software without specific, written prior permission.
1336384Ssklower 
1436384Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1536384Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1636384Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1736384Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1836384Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1936384Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2036384Ssklower SOFTWARE.
2136384Ssklower 
2236384Ssklower ******************************************************************/
2336384Ssklower 
2436384Ssklower /*
2536384Ssklower  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
2636384Ssklower  */
2736384Ssklower /*
2836384Ssklower  * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $
2936384Ssklower  * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $
30*37469Ssklower  *	@(#)iso.c	7.2 (Berkeley) 04/22/89
3136384Ssklower  *
3236384Ssklower  * iso.c: miscellaneous routines to support the iso address family
3336384Ssklower  */
3436384Ssklower 
3536384Ssklower #ifndef lint
3636384Ssklower static char *rcsid = "$Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $";
3736384Ssklower #endif
3836384Ssklower 
3936384Ssklower 
40*37469Ssklower #include "types.h"
41*37469Ssklower #include "param.h"
42*37469Ssklower #include "ioctl.h"
43*37469Ssklower #include "mbuf.h"
44*37469Ssklower #include "domain.h"
45*37469Ssklower #include "protosw.h"
46*37469Ssklower #include "socket.h"
47*37469Ssklower #include "socketvar.h"
48*37469Ssklower #include "uio.h"
49*37469Ssklower #include "dir.h"
50*37469Ssklower #include "user.h"
51*37469Ssklower #include "errno.h"
5236384Ssklower 
5336384Ssklower #include "../net/if.h"
5436384Ssklower #include "../net/route.h"
5536384Ssklower #include "../net/af.h"
5636384Ssklower 
57*37469Ssklower #include "iso.h"
58*37469Ssklower #include "iso_var.h"
59*37469Ssklower #include "iso_snpac.h"
60*37469Ssklower #include "iso_pcb.h"
61*37469Ssklower #include "clnp.h"
62*37469Ssklower #include "argo_debug.h"
6336384Ssklower 
6436384Ssklower #ifdef ISO
65*37469Ssklower #include "argoxtwentyfive.h"
6636384Ssklower 
6736384Ssklower int	iso_interfaces = 0;		/* number of external interfaces */
6836384Ssklower extern	struct ifnet loif;	/* loopback interface */
6936384Ssklower 
7036384Ssklower 
7136384Ssklower /*
7236384Ssklower  * FUNCTION:		iso_init
7336384Ssklower  *
7436384Ssklower  * PURPOSE:			initialize the iso address family
7536384Ssklower  *
7636384Ssklower  * RETURNS:			nothing
7736384Ssklower  *
7836384Ssklower  * SIDE EFFECTS:	1) zeros the maptab table.
79*37469Ssklower  *					2) initializes the routing table.
8036384Ssklower  *
8136384Ssklower  * NOTES:
8236384Ssklower  */
83*37469Ssklower struct radix_node_head *iso_rnhead;
8436384Ssklower iso_init()
8536384Ssklower {
86*37469Ssklower 	extern struct spna_cache	iso_snpac[];
87*37469Ssklower 	extern u_int 				iso_snpac_size;
88*37469Ssklower 	static iso_init_done;
8936384Ssklower 
90*37469Ssklower 	if (iso_init_done == 0) {
91*37469Ssklower 		iso_init_done++;
92*37469Ssklower 		bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache));
93*37469Ssklower 		rn_inithead(&iso_rnhead, 40, AF_ISO);
94*37469Ssklower 	}
9536384Ssklower }
9636384Ssklower 
9736384Ssklower /*
9836384Ssklower  * FUNCTION:		iso_addrmatch1
9936384Ssklower  *
10036384Ssklower  * PURPOSE:			decide if the two iso_addrs passed are equal
10136384Ssklower  *
10236384Ssklower  * RETURNS:			true if the addrs match, false if they do not
10336384Ssklower  *
10436384Ssklower  * SIDE EFFECTS:
10536384Ssklower  *
10636384Ssklower  * NOTES:
10736384Ssklower  */
10836384Ssklower iso_addrmatch1(isoaa, isoab)
109*37469Ssklower register struct iso_addr *isoaa, *isoab;		/* addresses to check */
11036384Ssklower {
111*37469Ssklower 	u_int	compare_len;
11236384Ssklower 
11336384Ssklower 	IFDEBUG(D_ROUTE)
11436384Ssklower 		printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
11536384Ssklower 			isoab->isoa_len);
11636384Ssklower 		printf("a:\n");
117*37469Ssklower 		dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
11836384Ssklower 		printf("b:\n");
119*37469Ssklower 		dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
12036384Ssklower 	ENDDEBUG
12136384Ssklower 
12236384Ssklower 	if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
12336384Ssklower 		IFDEBUG(D_ROUTE)
12436384Ssklower 			printf("iso_addrmatch1: returning false because of lengths\n");
12536384Ssklower 		ENDDEBUG
12636384Ssklower 		return 0;
12736384Ssklower 	}
12836384Ssklower 
129*37469Ssklower #ifdef notdef
13036384Ssklower 	/* TODO : generalize this to all afis with masks */
13136384Ssklower 	if(	isoaa->isoa_afi == AFI_37 ) {
13236384Ssklower 		/* must not compare 2 least significant digits, or for
13336384Ssklower 		 * that matter, the DSP
13436384Ssklower 		 */
13536384Ssklower 		compare_len = ADDR37_IDI_LEN - 1;
13636384Ssklower 	}
137*37469Ssklower #endif
13836384Ssklower 
13936384Ssklower 	IFDEBUG(D_ROUTE)
14036384Ssklower 		int i;
14136384Ssklower 		char *a, *b;
14236384Ssklower 
143*37469Ssklower 		a = isoaa->isoa_genaddr;
144*37469Ssklower 		b = isoab->isoa_genaddr;
14536384Ssklower 
14636384Ssklower 		for (i=0; i<compare_len; i++) {
14736384Ssklower 			printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
14836384Ssklower 			if (a[i] != b[i]) {
14936384Ssklower 				printf("\naddrs are not equal at byte %d\n", i);
15036384Ssklower 				return(0);
15136384Ssklower 			}
15236384Ssklower 		}
15336384Ssklower 		printf("\n");
15436384Ssklower 		printf("addrs are equal\n");
15536384Ssklower 		return (1);
15636384Ssklower 	ENDDEBUG
157*37469Ssklower 	return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
15836384Ssklower }
15936384Ssklower 
16036384Ssklower /*
16136384Ssklower  * FUNCTION:		iso_addrmatch
16236384Ssklower  *
16336384Ssklower  * PURPOSE:			decide if the two sockadrr_isos passed are equal
16436384Ssklower  *
16536384Ssklower  * RETURNS:			true if the addrs match, false if they do not
16636384Ssklower  *
16736384Ssklower  * SIDE EFFECTS:
16836384Ssklower  *
16936384Ssklower  * NOTES:
17036384Ssklower  */
17136384Ssklower iso_addrmatch(sisoa, sisob)
17236384Ssklower struct sockaddr_iso	*sisoa, *sisob;		/* addresses to check */
17336384Ssklower {
17436384Ssklower 	return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
17536384Ssklower }
176*37469Ssklower #ifdef notdef
17736384Ssklower /*
17836384Ssklower  * FUNCTION:		iso_netmatch
17936384Ssklower  *
18036384Ssklower  * PURPOSE:			similar to iso_addrmatch but takes sockaddr_iso
18136384Ssklower  *					as argument.
18236384Ssklower  *
18336384Ssklower  * RETURNS:			true if same net, false if not
18436384Ssklower  *
18536384Ssklower  * SIDE EFFECTS:
18636384Ssklower  *
18736384Ssklower  * NOTES:
18836384Ssklower  */
18936384Ssklower iso_netmatch(sisoa, sisob)
19036384Ssklower struct sockaddr_iso *sisoa, *sisob;
19136384Ssklower {
19236384Ssklower 	u_char			bufa[sizeof(struct sockaddr_iso)];
19336384Ssklower 	u_char			bufb[sizeof(struct sockaddr_iso)];
19436384Ssklower 	register int	lena, lenb;
19536384Ssklower 
19636384Ssklower 	lena = iso_netof(&sisoa->siso_addr, bufa);
19736384Ssklower 	lenb = iso_netof(&sisob->siso_addr, bufb);
19836384Ssklower 
19936384Ssklower 	IFDEBUG(D_ROUTE)
20036384Ssklower 		printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
20136384Ssklower 		printf("a:\n");
20236384Ssklower 		dump_buf(bufa, lena);
20336384Ssklower 		printf("b:\n");
20436384Ssklower 		dump_buf(bufb, lenb);
20536384Ssklower 	ENDDEBUG
20636384Ssklower 
20736384Ssklower 	return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
20836384Ssklower }
209*37469Ssklower #endif notdef
21036384Ssklower 
21136384Ssklower /*
21236384Ssklower  * FUNCTION:		iso_hashchar
21336384Ssklower  *
21436384Ssklower  * PURPOSE:			Hash all character in the buffer specified into
21536384Ssklower  *					a long. Return the long.
21636384Ssklower  *
21736384Ssklower  * RETURNS:			The hash value.
21836384Ssklower  *
21936384Ssklower  * SIDE EFFECTS:
22036384Ssklower  *
22136384Ssklower  * NOTES:			The hash is achieved by exclusive ORing 4 byte
22236384Ssklower  *					quantities.
22336384Ssklower  */
22436384Ssklower u_long
22536384Ssklower iso_hashchar(buf, len)
22636384Ssklower register caddr_t	buf;		/* buffer to pack from */
22736384Ssklower register int		len;		/* length of buffer */
22836384Ssklower {
22936384Ssklower 	register u_long	h = 0;
23036384Ssklower 	register int	i;
23136384Ssklower 
23236384Ssklower 	for (i=0; i<len; i+=4) {
23336384Ssklower 		register u_long	l = 0;
23436384Ssklower 
23536384Ssklower 		if ((len - i) < 4) {
23636384Ssklower 			/* buffer not multiple of 4 */
23736384Ssklower 			switch (len - i) {
23836384Ssklower 				case 3:
23936384Ssklower 					l |= buf[i+2] << 8;
24036384Ssklower 				case 2:
24136384Ssklower 					l |= buf[i+1] << 16;
24236384Ssklower 				case 1:
24336384Ssklower 					l |= buf[i] << 24;
24436384Ssklower 					break;
24536384Ssklower 				default:
24636384Ssklower 					printf("iso_hashchar: unexpected value x%x\n", len - i);
24736384Ssklower 					break;
24836384Ssklower 			}
24936384Ssklower 		} else {
25036384Ssklower 			l |= buf[i] << 24;
25136384Ssklower 			l |= buf[i+1] << 16;
25236384Ssklower 			l |= buf[i+2] << 8;
25336384Ssklower 			l |= buf[i+3];
25436384Ssklower 		}
25536384Ssklower 
25636384Ssklower 		h ^= l;
25736384Ssklower 	}
25836384Ssklower 
25936384Ssklower 	h ^= (u_long) (len % 4);
26036384Ssklower 
26136384Ssklower 	return(h);
26236384Ssklower }
263*37469Ssklower #ifdef notdef
26436384Ssklower /*
26536384Ssklower  * FUNCTION:		iso_hash
26636384Ssklower  *
26736384Ssklower  * PURPOSE:			Fill in fields of afhash structure based upon addr passed.
26836384Ssklower  *
26936384Ssklower  * RETURNS:			none
27036384Ssklower  *
27136384Ssklower  * SIDE EFFECTS:
27236384Ssklower  *
27336384Ssklower  * NOTES:
27436384Ssklower  */
27536384Ssklower iso_hash(siso, hp)
27636384Ssklower struct sockaddr_iso	*siso;		/* address to perform hash on */
27736384Ssklower struct afhash		*hp;		/* RETURN: hash info here */
27836384Ssklower {
27936384Ssklower 	u_long			buf[sizeof(struct sockaddr_iso)+1/4];
28036384Ssklower 	register int	bufsize;
28136384Ssklower 
28236384Ssklower 
28336384Ssklower 	bzero(buf, sizeof(buf));
28436384Ssklower 
28536384Ssklower 	bufsize = iso_netof(&siso->siso_addr, buf);
28636384Ssklower 	hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
28736384Ssklower 
28836384Ssklower 	IFDEBUG(D_ROUTE)
28936384Ssklower 		printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
29036384Ssklower 	ENDDEBUG
29136384Ssklower 
29236384Ssklower 	hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
29336384Ssklower 		siso->siso_addr.isoa_len);
29436384Ssklower 
29536384Ssklower 	IFDEBUG(D_ROUTE)
29636384Ssklower 		printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
29736384Ssklower 			clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
29836384Ssklower 			hp->afh_hosthash);
29936384Ssklower 	ENDDEBUG
30036384Ssklower }
30136384Ssklower /*
30236384Ssklower  * FUNCTION:		iso_netof
30336384Ssklower  *
30436384Ssklower  * PURPOSE:			Extract the network portion of the iso address.
30536384Ssklower  *					The network portion of the iso address varies depending
30636384Ssklower  *					on the type of address. The network portion of the
30736384Ssklower  *					address will include the IDP. The network portion is:
30836384Ssklower  *
30936384Ssklower  *						TYPE			DESC
31036384Ssklower  *					t37					The AFI and x.121 (IDI)
31136384Ssklower  *					osinet				The AFI, orgid, snetid
31236384Ssklower  *					rfc986				The AFI, vers and network part of
31336384Ssklower  *										internet address.
31436384Ssklower  *
31536384Ssklower  * RETURNS:			number of bytes placed into buf.
31636384Ssklower  *
31736384Ssklower  * SIDE EFFECTS:
31836384Ssklower  *
31936384Ssklower  * NOTES:			Buf is assumed to be big enough
32036384Ssklower  */
32136384Ssklower iso_netof(isoa, buf)
32236384Ssklower struct iso_addr	*isoa;		/* address */
32336384Ssklower caddr_t			buf;		/* RESULT: network portion of address here */
32436384Ssklower {
32536384Ssklower 	u_int		len = 1;	/* length of afi */
32636384Ssklower 
32736384Ssklower 	switch (isoa->isoa_afi) {
32836384Ssklower 		case AFI_37:
32936384Ssklower 			/*
33036384Ssklower 			 * Due to classic x.25 tunnel vision, there is no
33136384Ssklower 			 * net portion of an x.121 address.  For our purposes
33236384Ssklower 			 * the AFI will do, so that all x.25 -type addresses
33336384Ssklower 			 * map to the single x.25 SNPA. (Cannot have more than
33436384Ssklower 			 * one, obviously).
33536384Ssklower 			 */
33636384Ssklower 
33736384Ssklower 			break;
33836384Ssklower 
33936384Ssklower /* 		case AFI_OSINET:*/
34036384Ssklower 		case AFI_RFC986: {
34136384Ssklower 			u_short	idi;	/* value of idi */
34236384Ssklower 
34336384Ssklower 			/* osinet and rfc986 have idi in the same place */
34436384Ssklower 			CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
34536384Ssklower 
34636384Ssklower 			if (idi == IDI_OSINET)
34736384Ssklower /*
34836384Ssklower  *	Network portion of OSINET address can only be the IDI. Clearly,
34936384Ssklower  *	with one x25 interface, one could get to several orgids, and
35036384Ssklower  *	several snetids.
35136384Ssklower 				len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
35236384Ssklower 						OVLOSINET_SNETID_LEN);
35336384Ssklower  */
35436384Ssklower 				len += ADDROSINET_IDI_LEN;
35536384Ssklower 			else if (idi == IDI_RFC986) {
35636384Ssklower 				u_long				inetaddr;
35736384Ssklower 				struct ovl_rfc986	*o986 = (struct ovl_rfc986 *)isoa;
35836384Ssklower 
35936384Ssklower 				/* bump len to include idi and version (1 byte) */
36036384Ssklower 				len += ADDRRFC986_IDI_LEN + 1;
36136384Ssklower 
36236384Ssklower 				/* get inet addr long aligned */
36336384Ssklower 				bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
36436384Ssklower 				inetaddr = ntohl(inetaddr);	/* convert to host byte order */
36536384Ssklower 
36636384Ssklower 				IFDEBUG(D_ROUTE)
36736384Ssklower 					printf("iso_netof: isoa ");
36836384Ssklower 					dump_buf(isoa, sizeof(*isoa));
36936384Ssklower 					printf("iso_netof: inetaddr 0x%x ", inetaddr);
37036384Ssklower 				ENDDEBUG
37136384Ssklower 
37236384Ssklower 				/* bump len by size of network portion of inet address */
37336384Ssklower 				if (IN_CLASSA(inetaddr)) {
37436384Ssklower 					len += 4-IN_CLASSA_NSHIFT/8;
37536384Ssklower 					IFDEBUG(D_ROUTE)
37636384Ssklower 						printf("iso_netof: class A net len is now %d\n", len);
37736384Ssklower 					ENDDEBUG
37836384Ssklower 				} else if (IN_CLASSB(inetaddr)) {
37936384Ssklower 					len += 4-IN_CLASSB_NSHIFT/8;
38036384Ssklower 					IFDEBUG(D_ROUTE)
38136384Ssklower 						printf("iso_netof: class B net len is now %d\n", len);
38236384Ssklower 					ENDDEBUG
38336384Ssklower 				} else {
38436384Ssklower 					len += 4-IN_CLASSC_NSHIFT/8;
38536384Ssklower 					IFDEBUG(D_ROUTE)
38636384Ssklower 						printf("iso_netof: class C net len is now %d\n", len);
38736384Ssklower 					ENDDEBUG
38836384Ssklower 				}
38936384Ssklower 			} else
39036384Ssklower 				len = 0;
39136384Ssklower 		} break;
39236384Ssklower 
39336384Ssklower 		default:
39436384Ssklower 			len = 0;
39536384Ssklower 	}
39636384Ssklower 
39736384Ssklower 	bcopy((caddr_t)isoa, buf, len);
39836384Ssklower 	IFDEBUG(D_ROUTE)
39936384Ssklower 		printf("in_netof: isoa ");
40036384Ssklower 		dump_buf(isoa, len);
40136384Ssklower 		printf("in_netof: net ");
40236384Ssklower 		dump_buf(buf, len);
40336384Ssklower 	ENDDEBUG
40436384Ssklower 	return len;
40536384Ssklower }
406*37469Ssklower #endif notdef
40736384Ssklower /*
408*37469Ssklower  * Generic iso control operations (ioctl's).
409*37469Ssklower  * Ifp is 0 if not an interface-specific ioctl.
41036384Ssklower  */
411*37469Ssklower /* ARGSUSED */
41236384Ssklower iso_control(so, cmd, data, ifp)
413*37469Ssklower 	struct socket *so;
414*37469Ssklower 	int cmd;
415*37469Ssklower 	caddr_t data;
416*37469Ssklower 	register struct ifnet *ifp;
41736384Ssklower {
418*37469Ssklower 	register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
419*37469Ssklower 	register struct iso_ifaddr *ia = 0;
420*37469Ssklower 	register struct ifaddr *ifa;
421*37469Ssklower 	struct iso_ifaddr *oia;
422*37469Ssklower 	struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
423*37469Ssklower 	int error, hostIsNew, maskIsNew;
42436384Ssklower 
425*37469Ssklower 	/*
426*37469Ssklower 	 * Find address for this interface, if it exists.
427*37469Ssklower 	 */
428*37469Ssklower 	if (ifp)
429*37469Ssklower 		for (ia = iso_ifaddr; ia; ia = ia->ia_next)
430*37469Ssklower 			if (ia->ia_ifp == ifp)
431*37469Ssklower 				break;
43236384Ssklower 
43336384Ssklower 	switch (cmd) {
434*37469Ssklower 
435*37469Ssklower 	case SIOCAIFADDR_ISO:
436*37469Ssklower 	case SIOCDIFADDR_ISO:
437*37469Ssklower 		if (ifra->ifra_addr.siso_family == AF_ISO)
438*37469Ssklower 		    for (oia = ia; ia; ia = ia->ia_next) {
439*37469Ssklower 			if (ia->ia_ifp == ifp  &&
440*37469Ssklower 			    SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
441*37469Ssklower 				break;
442*37469Ssklower 		}
44336384Ssklower 		if (!suser())
44436384Ssklower 			return (u.u_error);
44536384Ssklower 		if (ifp == 0)
446*37469Ssklower 			panic("iso_control");
447*37469Ssklower 		if (ia == (struct iso_ifaddr *)0) {
448*37469Ssklower 			struct iso_ifaddr *nia;
449*37469Ssklower 			if (cmd == SIOCDIFADDR_ISO)
450*37469Ssklower 				return (EADDRNOTAVAIL);
451*37469Ssklower 			MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
452*37469Ssklower 				       M_IFADDR, M_WAITOK);
453*37469Ssklower 			if (nia == (struct iso_ifaddr *)0)
454*37469Ssklower 				return (ENOBUFS);
455*37469Ssklower 			bzero((caddr_t)nia, sizeof(*nia));
456*37469Ssklower 			if (ia = iso_ifaddr) {
457*37469Ssklower 				for ( ; ia->ia_next; ia = ia->ia_next)
458*37469Ssklower 					;
459*37469Ssklower 				ia->ia_next = nia;
460*37469Ssklower 			} else
461*37469Ssklower 				iso_ifaddr = nia;
462*37469Ssklower 			ia = nia;
463*37469Ssklower 			if (ifa = ifp->if_addrlist) {
464*37469Ssklower 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
465*37469Ssklower 					;
466*37469Ssklower 				ifa->ifa_next = (struct ifaddr *) ia;
467*37469Ssklower 			} else
468*37469Ssklower 				ifp->if_addrlist = (struct ifaddr *) ia;
469*37469Ssklower 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
470*37469Ssklower 			ia->ia_ifa.ifa_dstaddr
471*37469Ssklower 					= (struct sockaddr *)&ia->ia_dstaddr;
472*37469Ssklower 			ia->ia_ifa.ifa_netmask
473*37469Ssklower 					= (struct sockaddr *)&ia->ia_sockmask;
474*37469Ssklower 			ia->ia_ifp = ifp;
475*37469Ssklower 			if (ifp != &loif)
476*37469Ssklower 				iso_interfaces++;
477*37469Ssklower 		}
478*37469Ssklower 		break;
47936384Ssklower 
480*37469Ssklower #define cmdbyte(x)	(((x) >> 8) & 0xff)
481*37469Ssklower 	default:
482*37469Ssklower 		if (cmdbyte(cmd) == 'a')
483*37469Ssklower 			return (snpac_ioctl(cmd, data));
484*37469Ssklower 		if (ia == (struct iso_ifaddr *)0)
485*37469Ssklower 			return (EADDRNOTAVAIL);
486*37469Ssklower 		break;
487*37469Ssklower 	}
488*37469Ssklower 	switch (cmd) {
48936384Ssklower 
490*37469Ssklower 	case SIOCGIFADDR_ISO:
491*37469Ssklower 		ifr->ifr_Addr = ia->ia_addr;
492*37469Ssklower 		break;
49336384Ssklower 
494*37469Ssklower 	case SIOCGIFDSTADDR_ISO:
495*37469Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
496*37469Ssklower 			return (EINVAL);
497*37469Ssklower 		ifr->ifr_Addr = ia->ia_dstaddr;
498*37469Ssklower 		break;
49936384Ssklower 
500*37469Ssklower 	case SIOCGIFNETMASK_ISO:
501*37469Ssklower 		ifr->ifr_Addr = ia->ia_sockmask;
502*37469Ssklower 		break;
50336384Ssklower 
504*37469Ssklower 	case SIOCAIFADDR_ISO:
505*37469Ssklower 		maskIsNew = 0; hostIsNew = 1; error = u.u_error;
506*37469Ssklower 		if (ia->ia_addr.siso_family == AF_ISO) {
507*37469Ssklower 			if (ifra->ifra_addr.siso_len == 0) {
508*37469Ssklower 				ifra->ifra_addr = ia->ia_addr;
509*37469Ssklower 				hostIsNew = 0;
510*37469Ssklower 			} else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
511*37469Ssklower 				hostIsNew = 0;
512*37469Ssklower 		}
513*37469Ssklower 		if (ifra->ifra_mask.siso_len) {
514*37469Ssklower 			iso_ifscrub(ifp, ia);
515*37469Ssklower 			ia->ia_sockmask = ifra->ifra_mask;
516*37469Ssklower 			maskIsNew = 1;
517*37469Ssklower 		}
518*37469Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
519*37469Ssklower 		    (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
520*37469Ssklower 			iso_ifscrub(ifp, ia);
521*37469Ssklower 			ia->ia_dstaddr = ifra->ifra_dstaddr;
522*37469Ssklower 			maskIsNew  = 1; /* We lie; but the effect's the same */
523*37469Ssklower 		}
524*37469Ssklower 		if (ifra->ifra_addr.siso_family == AF_ISO &&
525*37469Ssklower 					    (hostIsNew || maskIsNew)) {
526*37469Ssklower 			error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
527*37469Ssklower 		}
528*37469Ssklower 		if (ifra->ifra_snpaoffset)
529*37469Ssklower 			ia->ia_snpaoffset = ifra->ifra_snpaoffset;
530*37469Ssklower 		return (error);
531*37469Ssklower 
532*37469Ssklower 	case SIOCDIFADDR_ISO:
533*37469Ssklower 		iso_ifscrub(ifp, ia);
534*37469Ssklower 		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
535*37469Ssklower 			ifp->if_addrlist = ifa->ifa_next;
536*37469Ssklower 		else {
537*37469Ssklower 			while (ifa->ifa_next &&
538*37469Ssklower 			       (ifa->ifa_next != (struct ifaddr *)ia))
539*37469Ssklower 				    ifa = ifa->ifa_next;
540*37469Ssklower 			if (ifa->ifa_next)
541*37469Ssklower 			    ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
542*37469Ssklower 			else
543*37469Ssklower 				printf("Couldn't unlink isoifaddr from ifp\n");
544*37469Ssklower 		}
545*37469Ssklower 		oia = ia;
546*37469Ssklower 		if (oia == (ia = iso_ifaddr)) {
547*37469Ssklower 			iso_ifaddr = ia->ia_next;
548*37469Ssklower 		} else {
549*37469Ssklower 			while (ia->ia_next && (ia->ia_next != oia)) {
550*37469Ssklower 				ia = ia->ia_next;
55136384Ssklower 			}
552*37469Ssklower 			if (ia->ia_next)
553*37469Ssklower 			    ia->ia_next = oia->ia_next;
554*37469Ssklower 			else
555*37469Ssklower 				printf("Didn't unlink isoifadr from list\n");
55636384Ssklower 		}
557*37469Ssklower 		free((caddr_t)oia, M_IFADDR);
558*37469Ssklower 		break;
55936384Ssklower 
56036384Ssklower 	default:
56136384Ssklower 		if (ifp == 0 || ifp->if_ioctl == 0)
56236384Ssklower 			return (EOPNOTSUPP);
56336384Ssklower 		return ((*ifp->if_ioctl)(ifp, cmd, data));
56436384Ssklower 	}
565*37469Ssklower 	return (0);
56636384Ssklower }
56736384Ssklower 
568*37469Ssklower /*
569*37469Ssklower  * Delete any existing route for an interface.
570*37469Ssklower  */
571*37469Ssklower iso_ifscrub(ifp, ia)
572*37469Ssklower 	register struct ifnet *ifp;
573*37469Ssklower 	register struct iso_ifaddr *ia;
574*37469Ssklower {
575*37469Ssklower 	if ((ia->ia_flags & IFA_ROUTE) == 0)
576*37469Ssklower 		return;
577*37469Ssklower 	if (ifp->if_flags & IFF_LOOPBACK)
578*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
579*37469Ssklower 	else if (ifp->if_flags & IFF_POINTOPOINT)
580*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
581*37469Ssklower 	else {
582*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
583*37469Ssklower 	}
584*37469Ssklower 	ia->ia_flags &= ~IFA_ROUTE;
585*37469Ssklower }
586*37469Ssklower 
587*37469Ssklower /*
588*37469Ssklower  * Initialize an interface's internet address
589*37469Ssklower  * and routing table entry.
590*37469Ssklower  */
591*37469Ssklower iso_ifinit(ifp, ia, siso, scrub)
592*37469Ssklower 	register struct ifnet *ifp;
593*37469Ssklower 	register struct iso_ifaddr *ia;
594*37469Ssklower 	struct sockaddr_iso *siso;
595*37469Ssklower {
596*37469Ssklower 	struct sockaddr_iso oldaddr;
597*37469Ssklower 	int s = splimp(), error;
598*37469Ssklower 
599*37469Ssklower 	oldaddr = ia->ia_addr;
600*37469Ssklower 	ia->ia_addr = *siso;
601*37469Ssklower 	/*
602*37469Ssklower 	 * Give the interface a chance to initialize
603*37469Ssklower 	 * if this is its first address,
604*37469Ssklower 	 * and to validate the address if necessary.
605*37469Ssklower 	 */
606*37469Ssklower 	if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
607*37469Ssklower 		splx(s);
608*37469Ssklower 		ia->ia_addr = oldaddr;
609*37469Ssklower 		return (error);
610*37469Ssklower 	}
611*37469Ssklower 	if (scrub) {
612*37469Ssklower 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
613*37469Ssklower 		iso_ifscrub(ifp, ia);
614*37469Ssklower 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
615*37469Ssklower 	}
616*37469Ssklower 	/*
617*37469Ssklower 	 * Add route for the network.
618*37469Ssklower 	 */
619*37469Ssklower 	if (ifp->if_flags & IFF_LOOPBACK) {
620*37469Ssklower 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
621*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
622*37469Ssklower 	} else if (ifp->if_flags & IFF_POINTOPOINT &&
623*37469Ssklower 		 ia->ia_dstaddr.siso_family == AF_ISO)
624*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
625*37469Ssklower 	else {
626*37469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
627*37469Ssklower 	}
628*37469Ssklower 	ia->ia_flags |= IFA_ROUTE;
629*37469Ssklower 	splx(s);
630*37469Ssklower 	return (0);
631*37469Ssklower }
632*37469Ssklower #ifdef notdef
633*37469Ssklower 
63436384Ssklower struct ifaddr *
63536384Ssklower iso_ifwithidi(addr)
63636384Ssklower 	register struct sockaddr *addr;
63736384Ssklower {
63836384Ssklower 	register struct ifnet *ifp;
63936384Ssklower 	register struct ifaddr *ifa;
64036384Ssklower 	register u_int af = addr->sa_family;
64136384Ssklower 
64236384Ssklower 	if (af != AF_ISO)
64336384Ssklower 		return (0);
64436384Ssklower 	IFDEBUG(D_ROUTE)
64536384Ssklower 		printf(">>> iso_ifwithidi addr\n");
64636384Ssklower 		dump_isoaddr( (struct sockaddr_iso *)(addr));
64736384Ssklower 		printf("\n");
64836384Ssklower 	ENDDEBUG
64936384Ssklower 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
65036384Ssklower 		IFDEBUG(D_ROUTE)
65136384Ssklower 			printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
65236384Ssklower 		ENDDEBUG
65336384Ssklower 		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
65436384Ssklower 			IFDEBUG(D_ROUTE)
65536384Ssklower 				printf("iso_ifwithidi address ");
656*37469Ssklower 				dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
65736384Ssklower 			ENDDEBUG
658*37469Ssklower 			if (ifa->ifa_addr->sa_family != addr->sa_family)
65936384Ssklower 				continue;
66036384Ssklower 
66136384Ssklower #define	IFA_SIS(ifa)\
662*37469Ssklower 	((struct sockaddr_iso *)((ifa)->ifa_addr))
66336384Ssklower 
66436384Ssklower 			IFDEBUG(D_ROUTE)
66536384Ssklower 				printf(" af same, args to iso_eqtype:\n");
66636384Ssklower 				printf("0x%x ", IFA_SIS(ifa)->siso_addr);
66736384Ssklower 				printf(" 0x%x\n",
66836384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr));
66936384Ssklower 			ENDDEBUG
67036384Ssklower 
67136384Ssklower 			if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
67236384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr))) {
67336384Ssklower 				IFDEBUG(D_ROUTE)
67436384Ssklower 					printf("ifa_ifwithidi: ifa found\n");
67536384Ssklower 				ENDDEBUG
67636384Ssklower 				return (ifa);
67736384Ssklower 			}
67836384Ssklower 			IFDEBUG(D_ROUTE)
67936384Ssklower 				printf(" iso_eqtype failed\n");
68036384Ssklower 			ENDDEBUG
68136384Ssklower 		}
68236384Ssklower 	}
68336384Ssklower 	return ((struct ifaddr *)0);
68436384Ssklower }
68536384Ssklower 
686*37469Ssklower #endif notdef
68736384Ssklower /*
68836384Ssklower  * FUNCTION:		iso_ck_addr
68936384Ssklower  *
69036384Ssklower  * PURPOSE:			return true if the iso_addr passed is
69136384Ssklower  *					within the legal size limit for an iso address.
69236384Ssklower  *
69336384Ssklower  * RETURNS:			true or false
69436384Ssklower  *
69536384Ssklower  * SIDE EFFECTS:
69636384Ssklower  *
69736384Ssklower  */
69836384Ssklower iso_ck_addr(isoa)
69936384Ssklower struct iso_addr	*isoa;	/* address to check */
70036384Ssklower {
70136384Ssklower 	return (isoa->isoa_len <= 20);
70236384Ssklower 
70336384Ssklower }
70436384Ssklower 
705*37469Ssklower #ifdef notdef
70636384Ssklower /*
70736384Ssklower  * FUNCTION:		iso_eqtype
70836384Ssklower  *
70936384Ssklower  * PURPOSE:			Determine if two iso addresses are of the same type.
71036384Ssklower  *  This is flaky.  Really we should consider all type 47 addrs to be the
71136384Ssklower  *  same - but there do exist different structures for 47 addrs.
71236384Ssklower  *  Gosip adds a 3rd.
71336384Ssklower  *
71436384Ssklower  * RETURNS:			true if the addresses are the same type
71536384Ssklower  *
71636384Ssklower  * SIDE EFFECTS:
71736384Ssklower  *
71836384Ssklower  * NOTES:			By type, I mean rfc986, t37, or osinet
71936384Ssklower  *
72036384Ssklower  *					This will first compare afis. If they match, then
72136384Ssklower  *					if the addr is not t37, the idis must be compared.
72236384Ssklower  */
72336384Ssklower iso_eqtype(isoaa, isoab)
72436384Ssklower struct iso_addr	*isoaa;		/* first addr to check */
72536384Ssklower struct iso_addr	*isoab;		/* other addr to check */
72636384Ssklower {
72736384Ssklower 	if (isoaa->isoa_afi == isoab->isoa_afi) {
72836384Ssklower 		if (isoaa->isoa_afi == AFI_37)
72936384Ssklower 			return(1);
73036384Ssklower 		else
73136384Ssklower 			return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
73236384Ssklower 	}
73336384Ssklower 	return(0);
73436384Ssklower }
735*37469Ssklower #endif notdef
73636384Ssklower /*
737*37469Ssklower  * FUNCTION:		iso_localifa()
73836384Ssklower  *
739*37469Ssklower  * PURPOSE:			Find an interface addresss having a given destination
740*37469Ssklower  *					or at least matching the net.
74136384Ssklower  *
74236384Ssklower  * RETURNS:			ptr to an interface address
74336384Ssklower  *
74436384Ssklower  * SIDE EFFECTS:
74536384Ssklower  *
74636384Ssklower  * NOTES:
74736384Ssklower  */
74836384Ssklower struct iso_ifaddr *
749*37469Ssklower iso_localifa(siso)
750*37469Ssklower 	register struct sockaddr_iso *siso;
75136384Ssklower {
75236384Ssklower 	register struct iso_ifaddr *ia;
753*37469Ssklower 	register char *cp1, *cp2, *cp3;
754*37469Ssklower 	register struct ifnet *ifp;
755*37469Ssklower 	struct iso_ifaddr *ia_maybe = 0;
756*37469Ssklower 	/*
757*37469Ssklower 	 * We make one pass looking for both net matches and an exact
758*37469Ssklower 	 * dst addr.
759*37469Ssklower 	 */
760*37469Ssklower 	for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
761*37469Ssklower 		if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
762*37469Ssklower 			continue;
763*37469Ssklower 		if (ifp->if_flags & IFF_POINTOPOINT) {
764*37469Ssklower 			if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
765*37469Ssklower 				SAME_ISOADDR(&ia->ia_dstaddr, siso))
766*37469Ssklower 				return (ia);
767*37469Ssklower 			else
768*37469Ssklower 				if (SAME_ISOADDR(&ia->ia_addr, siso))
769*37469Ssklower 					ia_maybe = ia;
770*37469Ssklower 			continue;
771*37469Ssklower 		}
772*37469Ssklower 		if (ia->ia_sockmask.siso_len) {
773*37469Ssklower 			char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
774*37469Ssklower 			cp1 = ia->ia_sockmask.siso_data;
775*37469Ssklower 			cp2 = siso->siso_data;
776*37469Ssklower 			cp3 = ia->ia_addr.siso_data;
777*37469Ssklower 			while (cp2 < cplim)
778*37469Ssklower 				if (*cp1++ & (*cp2++ ^ *cp3++))
779*37469Ssklower 					goto next;
780*37469Ssklower 			ia_maybe = ia;
781*37469Ssklower 		}
782*37469Ssklower 		if (SAME_ISOADDR(&ia->ia_addr, siso))
783*37469Ssklower 			return ia;
784*37469Ssklower 	next:;
785*37469Ssklower 	}
786*37469Ssklower 	return ia_maybe;
78736384Ssklower }
78836384Ssklower 
78936384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
79036384Ssklower #include "cons.h"
79136384Ssklower #endif	NARGOXTWENTYFIVE > 0
79236384Ssklower /*
79336384Ssklower  * FUNCTION:		iso_nlctloutput
79436384Ssklower  *
79536384Ssklower  * PURPOSE:			Set options at the network level
79636384Ssklower  *
79736384Ssklower  * RETURNS:			E*
79836384Ssklower  *
79936384Ssklower  * SIDE EFFECTS:
80036384Ssklower  *
80136384Ssklower  * NOTES:			This could embody some of the functions of
80236384Ssklower  *					rclnp_ctloutput and cons_ctloutput.
80336384Ssklower  */
80436384Ssklower iso_nlctloutput(cmd, optname, pcb, m)
80536384Ssklower int			cmd;		/* command:set or get */
80636384Ssklower int			optname;	/* option of interest */
80736384Ssklower caddr_t		pcb;		/* nl pcb */
80836384Ssklower struct mbuf	*m;			/* data for set, buffer for get */
80936384Ssklower {
81036384Ssklower 	struct isopcb	*isop = (struct isopcb *)pcb;
81136384Ssklower 	int				error = 0;	/* return value */
81236384Ssklower 	caddr_t			data;		/* data for option */
81336384Ssklower 	int				data_len;	/* data's length */
81436384Ssklower 
81536384Ssklower 	IFDEBUG(D_ISO)
81636384Ssklower 		printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
81736384Ssklower 			cmd, optname, pcb, m);
81836384Ssklower 	ENDDEBUG
81936384Ssklower 
82036384Ssklower 	if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
82136384Ssklower 		return(EOPNOTSUPP);
82236384Ssklower 
82336384Ssklower 	data = mtod(m, caddr_t);
82436384Ssklower 	data_len = (m)->m_len;
82536384Ssklower 
82636384Ssklower 	IFDEBUG(D_ISO)
82736384Ssklower 		printf("iso_nlctloutput: data is:\n");
82836384Ssklower 		dump_buf(data, data_len);
82936384Ssklower 	ENDDEBUG
83036384Ssklower 
83136384Ssklower 	switch (optname) {
83236384Ssklower 
83336384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
83436384Ssklower 		case CONSOPT_X25CRUD:
83536384Ssklower 			if (cmd == PRCO_GETOPT) {
83636384Ssklower 				error = EOPNOTSUPP;
83736384Ssklower 				break;
83836384Ssklower 			}
83936384Ssklower 
84036384Ssklower 			if (data_len > MAXX25CRUDLEN) {
84136384Ssklower 				error = EINVAL;
84236384Ssklower 				break;
84336384Ssklower 			}
84436384Ssklower 
84536384Ssklower 			IFDEBUG(D_ISO)
84636384Ssklower 				printf("iso_nlctloutput: setting x25 crud\n");
84736384Ssklower 			ENDDEBUG
84836384Ssklower 
849*37469Ssklower 			bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
85036384Ssklower 			isop->isop_x25crud_len = data_len;
85136384Ssklower 			break;
85236384Ssklower #endif	NARGOXTWENTYFIVE > 0
85336384Ssklower 
85436384Ssklower 		default:
85536384Ssklower 			error = EOPNOTSUPP;
85636384Ssklower 	}
85736384Ssklower 
85836384Ssklower 	return error;
85936384Ssklower }
86036384Ssklower 
86136384Ssklower /*
86236384Ssklower  * FUNCTION:		iso_routeifp
86336384Ssklower  *
86436384Ssklower  * PURPOSE:			Route on a sockaddr and return ifp
86536384Ssklower  *
86636384Ssklower  * RETURNS:			ifp of outgoing interface, or null
86736384Ssklower  *
86836384Ssklower  * SIDE EFFECTS:
86936384Ssklower  *
87036384Ssklower  * NOTES:
87136384Ssklower  */
872*37469Ssklower struct iso_ifaddr *
873*37469Ssklower iso_routeifa(dst)
87436384Ssklower struct sockaddr	*dst;		/* destination to route to */
87536384Ssklower {
876*37469Ssklower 	struct rtentry	*rt;
877*37469Ssklower 	struct ifaddr *ifa = 0;
878*37469Ssklower 	struct ifnet *ifp = 0;
87936384Ssklower 
88036384Ssklower 
88136384Ssklower 	IFDEBUG(D_ROUTE)
88236384Ssklower 		printf("iso_routeifp: dst:");
883*37469Ssklower 		dump_isoaddr((struct sockaddr_iso *)dst);
88436384Ssklower 	ENDDEBUG
88536384Ssklower 
886*37469Ssklower 	rt = rtalloc1(dst, 0);
88736384Ssklower 
888*37469Ssklower 	if (rt) {
889*37469Ssklower 		ifa = rt->rt_ifa;
890*37469Ssklower 		ifp = rt->rt_ifp;
891*37469Ssklower 		RTFREE(rt);
89236384Ssklower 	}
89336384Ssklower 
89436384Ssklower 	IFDEBUG(D_ROUTE)
895*37469Ssklower 		printf("iso_routeifp: ifa x%x", ifa);
89636384Ssklower 		if (ifp)
89736384Ssklower 			printf(" (%s%d)\n", ifp->if_name, ifp->if_unit);
89836384Ssklower 		else
89936384Ssklower 			printf("\n");
90036384Ssklower 	ENDDEBUG
90136384Ssklower 
902*37469Ssklower 	return((struct iso_ifaddr *)ifa);
90336384Ssklower }
90436384Ssklower #endif ISO
90536384Ssklower 
90636384Ssklower #ifdef ARGO_DEBUG
90736384Ssklower 
90836384Ssklower /*
90936384Ssklower  * FUNCTION:		dump_isoaddr
91036384Ssklower  *
91136384Ssklower  * PURPOSE:			debugging
91236384Ssklower  *
91336384Ssklower  * RETURNS:			nada
91436384Ssklower  *
91536384Ssklower  */
91636384Ssklower dump_isoaddr(s)
91736384Ssklower 	struct sockaddr_iso *s;
91836384Ssklower {
919*37469Ssklower 	char *clnp_saddr_isop();
92036384Ssklower 	register int i;
92136384Ssklower 
92236384Ssklower 	if( s->siso_family == AF_ISO) {
923*37469Ssklower 		printf("ISO address: suffixlen %d, %s\n",
924*37469Ssklower 			s->siso_tsuffixlen, clnp_saddr_isop(s));
92536384Ssklower 	} else if( s->siso_family == AF_INET) {
92636384Ssklower 		/* hack */
92736384Ssklower 		struct sockaddr_in *sin = (struct sockaddr_in *)s;
92836384Ssklower 
92936384Ssklower 		printf("%d.%d.%d.%d: %d",
93036384Ssklower 			(sin->sin_addr.s_addr>>24)&0xff,
93136384Ssklower 			(sin->sin_addr.s_addr>>16)&0xff,
93236384Ssklower 			(sin->sin_addr.s_addr>>8)&0xff,
93336384Ssklower 			(sin->sin_addr.s_addr)&0xff,
93436384Ssklower 			sin->sin_port);
93536384Ssklower 	}
93636384Ssklower }
93736384Ssklower 
93836384Ssklower #endif ARGO_DEBUG
939