xref: /csrg-svn/sys/netiso/iso.c (revision 38841)
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*38841Ssklower  *	@(#)iso.c	7.5 (Berkeley) 08/29/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 
4037469Ssklower #include "types.h"
4137469Ssklower #include "param.h"
4237469Ssklower #include "ioctl.h"
4337469Ssklower #include "mbuf.h"
4437469Ssklower #include "domain.h"
4537469Ssklower #include "protosw.h"
4637469Ssklower #include "socket.h"
4737469Ssklower #include "socketvar.h"
4837469Ssklower #include "user.h"
4937469Ssklower #include "errno.h"
5036384Ssklower 
5136384Ssklower #include "../net/if.h"
5236384Ssklower #include "../net/route.h"
5336384Ssklower #include "../net/af.h"
5436384Ssklower 
5537469Ssklower #include "iso.h"
5637469Ssklower #include "iso_var.h"
5737469Ssklower #include "iso_snpac.h"
5837469Ssklower #include "iso_pcb.h"
5937469Ssklower #include "clnp.h"
6037469Ssklower #include "argo_debug.h"
6136384Ssklower 
6236384Ssklower #ifdef ISO
6337469Ssklower #include "argoxtwentyfive.h"
6436384Ssklower 
6536384Ssklower int	iso_interfaces = 0;		/* number of external interfaces */
6636384Ssklower extern	struct ifnet loif;	/* loopback interface */
6736384Ssklower 
6836384Ssklower 
6936384Ssklower /*
7036384Ssklower  * FUNCTION:		iso_init
7136384Ssklower  *
7236384Ssklower  * PURPOSE:			initialize the iso address family
7336384Ssklower  *
7436384Ssklower  * RETURNS:			nothing
7536384Ssklower  *
7636384Ssklower  * SIDE EFFECTS:	1) zeros the maptab table.
7737469Ssklower  *					2) initializes the routing table.
7836384Ssklower  *
7936384Ssklower  * NOTES:
8036384Ssklower  */
8137469Ssklower struct radix_node_head *iso_rnhead;
8236384Ssklower iso_init()
8336384Ssklower {
8437469Ssklower 	extern struct spna_cache	iso_snpac[];
8537469Ssklower 	extern u_int 				iso_snpac_size;
8637469Ssklower 	static iso_init_done;
8736384Ssklower 
8837469Ssklower 	if (iso_init_done == 0) {
8937469Ssklower 		iso_init_done++;
9037469Ssklower 		bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache));
9137469Ssklower 		rn_inithead(&iso_rnhead, 40, AF_ISO);
9237469Ssklower 	}
9336384Ssklower }
9436384Ssklower 
9536384Ssklower /*
9636384Ssklower  * FUNCTION:		iso_addrmatch1
9736384Ssklower  *
9836384Ssklower  * PURPOSE:			decide if the two iso_addrs passed are equal
9936384Ssklower  *
10036384Ssklower  * RETURNS:			true if the addrs match, false if they do not
10136384Ssklower  *
10236384Ssklower  * SIDE EFFECTS:
10336384Ssklower  *
10436384Ssklower  * NOTES:
10536384Ssklower  */
10636384Ssklower iso_addrmatch1(isoaa, isoab)
10737469Ssklower register struct iso_addr *isoaa, *isoab;		/* addresses to check */
10836384Ssklower {
10937469Ssklower 	u_int	compare_len;
11036384Ssklower 
11136384Ssklower 	IFDEBUG(D_ROUTE)
11236384Ssklower 		printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
11336384Ssklower 			isoab->isoa_len);
11436384Ssklower 		printf("a:\n");
11537469Ssklower 		dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
11636384Ssklower 		printf("b:\n");
11737469Ssklower 		dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
11836384Ssklower 	ENDDEBUG
11936384Ssklower 
12036384Ssklower 	if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
12136384Ssklower 		IFDEBUG(D_ROUTE)
12236384Ssklower 			printf("iso_addrmatch1: returning false because of lengths\n");
12336384Ssklower 		ENDDEBUG
12436384Ssklower 		return 0;
12536384Ssklower 	}
12636384Ssklower 
12737469Ssklower #ifdef notdef
12836384Ssklower 	/* TODO : generalize this to all afis with masks */
12936384Ssklower 	if(	isoaa->isoa_afi == AFI_37 ) {
13036384Ssklower 		/* must not compare 2 least significant digits, or for
13136384Ssklower 		 * that matter, the DSP
13236384Ssklower 		 */
13336384Ssklower 		compare_len = ADDR37_IDI_LEN - 1;
13436384Ssklower 	}
13537469Ssklower #endif
13636384Ssklower 
13736384Ssklower 	IFDEBUG(D_ROUTE)
13836384Ssklower 		int i;
13936384Ssklower 		char *a, *b;
14036384Ssklower 
14137469Ssklower 		a = isoaa->isoa_genaddr;
14237469Ssklower 		b = isoab->isoa_genaddr;
14336384Ssklower 
14436384Ssklower 		for (i=0; i<compare_len; i++) {
14536384Ssklower 			printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
14636384Ssklower 			if (a[i] != b[i]) {
14736384Ssklower 				printf("\naddrs are not equal at byte %d\n", i);
14836384Ssklower 				return(0);
14936384Ssklower 			}
15036384Ssklower 		}
15136384Ssklower 		printf("\n");
15236384Ssklower 		printf("addrs are equal\n");
15336384Ssklower 		return (1);
15436384Ssklower 	ENDDEBUG
15537469Ssklower 	return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
15636384Ssklower }
15736384Ssklower 
15836384Ssklower /*
15936384Ssklower  * FUNCTION:		iso_addrmatch
16036384Ssklower  *
16136384Ssklower  * PURPOSE:			decide if the two sockadrr_isos passed are equal
16236384Ssklower  *
16336384Ssklower  * RETURNS:			true if the addrs match, false if they do not
16436384Ssklower  *
16536384Ssklower  * SIDE EFFECTS:
16636384Ssklower  *
16736384Ssklower  * NOTES:
16836384Ssklower  */
16936384Ssklower iso_addrmatch(sisoa, sisob)
17036384Ssklower struct sockaddr_iso	*sisoa, *sisob;		/* addresses to check */
17136384Ssklower {
17236384Ssklower 	return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
17336384Ssklower }
17437469Ssklower #ifdef notdef
17536384Ssklower /*
17636384Ssklower  * FUNCTION:		iso_netmatch
17736384Ssklower  *
17836384Ssklower  * PURPOSE:			similar to iso_addrmatch but takes sockaddr_iso
17936384Ssklower  *					as argument.
18036384Ssklower  *
18136384Ssklower  * RETURNS:			true if same net, false if not
18236384Ssklower  *
18336384Ssklower  * SIDE EFFECTS:
18436384Ssklower  *
18536384Ssklower  * NOTES:
18636384Ssklower  */
18736384Ssklower iso_netmatch(sisoa, sisob)
18836384Ssklower struct sockaddr_iso *sisoa, *sisob;
18936384Ssklower {
19036384Ssklower 	u_char			bufa[sizeof(struct sockaddr_iso)];
19136384Ssklower 	u_char			bufb[sizeof(struct sockaddr_iso)];
19236384Ssklower 	register int	lena, lenb;
19336384Ssklower 
19436384Ssklower 	lena = iso_netof(&sisoa->siso_addr, bufa);
19536384Ssklower 	lenb = iso_netof(&sisob->siso_addr, bufb);
19636384Ssklower 
19736384Ssklower 	IFDEBUG(D_ROUTE)
19836384Ssklower 		printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
19936384Ssklower 		printf("a:\n");
20036384Ssklower 		dump_buf(bufa, lena);
20136384Ssklower 		printf("b:\n");
20236384Ssklower 		dump_buf(bufb, lenb);
20336384Ssklower 	ENDDEBUG
20436384Ssklower 
20536384Ssklower 	return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
20636384Ssklower }
20737469Ssklower #endif notdef
20836384Ssklower 
20936384Ssklower /*
21036384Ssklower  * FUNCTION:		iso_hashchar
21136384Ssklower  *
21236384Ssklower  * PURPOSE:			Hash all character in the buffer specified into
21336384Ssklower  *					a long. Return the long.
21436384Ssklower  *
21536384Ssklower  * RETURNS:			The hash value.
21636384Ssklower  *
21736384Ssklower  * SIDE EFFECTS:
21836384Ssklower  *
21936384Ssklower  * NOTES:			The hash is achieved by exclusive ORing 4 byte
22036384Ssklower  *					quantities.
22136384Ssklower  */
22236384Ssklower u_long
22336384Ssklower iso_hashchar(buf, len)
22436384Ssklower register caddr_t	buf;		/* buffer to pack from */
22536384Ssklower register int		len;		/* length of buffer */
22636384Ssklower {
22736384Ssklower 	register u_long	h = 0;
22836384Ssklower 	register int	i;
22936384Ssklower 
23036384Ssklower 	for (i=0; i<len; i+=4) {
23136384Ssklower 		register u_long	l = 0;
23236384Ssklower 
23336384Ssklower 		if ((len - i) < 4) {
23436384Ssklower 			/* buffer not multiple of 4 */
23536384Ssklower 			switch (len - i) {
23636384Ssklower 				case 3:
23736384Ssklower 					l |= buf[i+2] << 8;
23836384Ssklower 				case 2:
23936384Ssklower 					l |= buf[i+1] << 16;
24036384Ssklower 				case 1:
24136384Ssklower 					l |= buf[i] << 24;
24236384Ssklower 					break;
24336384Ssklower 				default:
24436384Ssklower 					printf("iso_hashchar: unexpected value x%x\n", len - i);
24536384Ssklower 					break;
24636384Ssklower 			}
24736384Ssklower 		} else {
24836384Ssklower 			l |= buf[i] << 24;
24936384Ssklower 			l |= buf[i+1] << 16;
25036384Ssklower 			l |= buf[i+2] << 8;
25136384Ssklower 			l |= buf[i+3];
25236384Ssklower 		}
25336384Ssklower 
25436384Ssklower 		h ^= l;
25536384Ssklower 	}
25636384Ssklower 
25736384Ssklower 	h ^= (u_long) (len % 4);
25836384Ssklower 
25936384Ssklower 	return(h);
26036384Ssklower }
26137469Ssklower #ifdef notdef
26236384Ssklower /*
26336384Ssklower  * FUNCTION:		iso_hash
26436384Ssklower  *
26536384Ssklower  * PURPOSE:			Fill in fields of afhash structure based upon addr passed.
26636384Ssklower  *
26736384Ssklower  * RETURNS:			none
26836384Ssklower  *
26936384Ssklower  * SIDE EFFECTS:
27036384Ssklower  *
27136384Ssklower  * NOTES:
27236384Ssklower  */
27336384Ssklower iso_hash(siso, hp)
27436384Ssklower struct sockaddr_iso	*siso;		/* address to perform hash on */
27536384Ssklower struct afhash		*hp;		/* RETURN: hash info here */
27636384Ssklower {
27736384Ssklower 	u_long			buf[sizeof(struct sockaddr_iso)+1/4];
27836384Ssklower 	register int	bufsize;
27936384Ssklower 
28036384Ssklower 
28136384Ssklower 	bzero(buf, sizeof(buf));
28236384Ssklower 
28336384Ssklower 	bufsize = iso_netof(&siso->siso_addr, buf);
28436384Ssklower 	hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
28536384Ssklower 
28636384Ssklower 	IFDEBUG(D_ROUTE)
28736384Ssklower 		printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
28836384Ssklower 	ENDDEBUG
28936384Ssklower 
29036384Ssklower 	hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
29136384Ssklower 		siso->siso_addr.isoa_len);
29236384Ssklower 
29336384Ssklower 	IFDEBUG(D_ROUTE)
29436384Ssklower 		printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
29536384Ssklower 			clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
29636384Ssklower 			hp->afh_hosthash);
29736384Ssklower 	ENDDEBUG
29836384Ssklower }
29936384Ssklower /*
30036384Ssklower  * FUNCTION:		iso_netof
30136384Ssklower  *
30236384Ssklower  * PURPOSE:			Extract the network portion of the iso address.
30336384Ssklower  *					The network portion of the iso address varies depending
30436384Ssklower  *					on the type of address. The network portion of the
30536384Ssklower  *					address will include the IDP. The network portion is:
30636384Ssklower  *
30736384Ssklower  *						TYPE			DESC
30836384Ssklower  *					t37					The AFI and x.121 (IDI)
30936384Ssklower  *					osinet				The AFI, orgid, snetid
31036384Ssklower  *					rfc986				The AFI, vers and network part of
31136384Ssklower  *										internet address.
31236384Ssklower  *
31336384Ssklower  * RETURNS:			number of bytes placed into buf.
31436384Ssklower  *
31536384Ssklower  * SIDE EFFECTS:
31636384Ssklower  *
31736384Ssklower  * NOTES:			Buf is assumed to be big enough
31836384Ssklower  */
31936384Ssklower iso_netof(isoa, buf)
32036384Ssklower struct iso_addr	*isoa;		/* address */
32136384Ssklower caddr_t			buf;		/* RESULT: network portion of address here */
32236384Ssklower {
32336384Ssklower 	u_int		len = 1;	/* length of afi */
32436384Ssklower 
32536384Ssklower 	switch (isoa->isoa_afi) {
32636384Ssklower 		case AFI_37:
32736384Ssklower 			/*
32836384Ssklower 			 * Due to classic x.25 tunnel vision, there is no
32936384Ssklower 			 * net portion of an x.121 address.  For our purposes
33036384Ssklower 			 * the AFI will do, so that all x.25 -type addresses
33136384Ssklower 			 * map to the single x.25 SNPA. (Cannot have more than
33236384Ssklower 			 * one, obviously).
33336384Ssklower 			 */
33436384Ssklower 
33536384Ssklower 			break;
33636384Ssklower 
33736384Ssklower /* 		case AFI_OSINET:*/
33836384Ssklower 		case AFI_RFC986: {
33936384Ssklower 			u_short	idi;	/* value of idi */
34036384Ssklower 
34136384Ssklower 			/* osinet and rfc986 have idi in the same place */
34236384Ssklower 			CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
34336384Ssklower 
34436384Ssklower 			if (idi == IDI_OSINET)
34536384Ssklower /*
34636384Ssklower  *	Network portion of OSINET address can only be the IDI. Clearly,
34736384Ssklower  *	with one x25 interface, one could get to several orgids, and
34836384Ssklower  *	several snetids.
34936384Ssklower 				len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
35036384Ssklower 						OVLOSINET_SNETID_LEN);
35136384Ssklower  */
35236384Ssklower 				len += ADDROSINET_IDI_LEN;
35336384Ssklower 			else if (idi == IDI_RFC986) {
35436384Ssklower 				u_long				inetaddr;
35536384Ssklower 				struct ovl_rfc986	*o986 = (struct ovl_rfc986 *)isoa;
35636384Ssklower 
35736384Ssklower 				/* bump len to include idi and version (1 byte) */
35836384Ssklower 				len += ADDRRFC986_IDI_LEN + 1;
35936384Ssklower 
36036384Ssklower 				/* get inet addr long aligned */
36136384Ssklower 				bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
36236384Ssklower 				inetaddr = ntohl(inetaddr);	/* convert to host byte order */
36336384Ssklower 
36436384Ssklower 				IFDEBUG(D_ROUTE)
36536384Ssklower 					printf("iso_netof: isoa ");
36636384Ssklower 					dump_buf(isoa, sizeof(*isoa));
36736384Ssklower 					printf("iso_netof: inetaddr 0x%x ", inetaddr);
36836384Ssklower 				ENDDEBUG
36936384Ssklower 
37036384Ssklower 				/* bump len by size of network portion of inet address */
37136384Ssklower 				if (IN_CLASSA(inetaddr)) {
37236384Ssklower 					len += 4-IN_CLASSA_NSHIFT/8;
37336384Ssklower 					IFDEBUG(D_ROUTE)
37436384Ssklower 						printf("iso_netof: class A net len is now %d\n", len);
37536384Ssklower 					ENDDEBUG
37636384Ssklower 				} else if (IN_CLASSB(inetaddr)) {
37736384Ssklower 					len += 4-IN_CLASSB_NSHIFT/8;
37836384Ssklower 					IFDEBUG(D_ROUTE)
37936384Ssklower 						printf("iso_netof: class B net len is now %d\n", len);
38036384Ssklower 					ENDDEBUG
38136384Ssklower 				} else {
38236384Ssklower 					len += 4-IN_CLASSC_NSHIFT/8;
38336384Ssklower 					IFDEBUG(D_ROUTE)
38436384Ssklower 						printf("iso_netof: class C net len is now %d\n", len);
38536384Ssklower 					ENDDEBUG
38636384Ssklower 				}
38736384Ssklower 			} else
38836384Ssklower 				len = 0;
38936384Ssklower 		} break;
39036384Ssklower 
39136384Ssklower 		default:
39236384Ssklower 			len = 0;
39336384Ssklower 	}
39436384Ssklower 
39536384Ssklower 	bcopy((caddr_t)isoa, buf, len);
39636384Ssklower 	IFDEBUG(D_ROUTE)
39736384Ssklower 		printf("in_netof: isoa ");
39836384Ssklower 		dump_buf(isoa, len);
39936384Ssklower 		printf("in_netof: net ");
40036384Ssklower 		dump_buf(buf, len);
40136384Ssklower 	ENDDEBUG
40236384Ssklower 	return len;
40336384Ssklower }
40437469Ssklower #endif notdef
40536384Ssklower /*
40637469Ssklower  * Generic iso control operations (ioctl's).
40737469Ssklower  * Ifp is 0 if not an interface-specific ioctl.
40836384Ssklower  */
40937469Ssklower /* ARGSUSED */
41036384Ssklower iso_control(so, cmd, data, ifp)
41137469Ssklower 	struct socket *so;
41237469Ssklower 	int cmd;
41337469Ssklower 	caddr_t data;
41437469Ssklower 	register struct ifnet *ifp;
41536384Ssklower {
41637469Ssklower 	register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
41737469Ssklower 	register struct iso_ifaddr *ia = 0;
41837469Ssklower 	register struct ifaddr *ifa;
41937469Ssklower 	struct iso_ifaddr *oia;
42037469Ssklower 	struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
42137469Ssklower 	int error, hostIsNew, maskIsNew;
42236384Ssklower 
42337469Ssklower 	/*
42437469Ssklower 	 * Find address for this interface, if it exists.
42537469Ssklower 	 */
42637469Ssklower 	if (ifp)
42737469Ssklower 		for (ia = iso_ifaddr; ia; ia = ia->ia_next)
42837469Ssklower 			if (ia->ia_ifp == ifp)
42937469Ssklower 				break;
43036384Ssklower 
43136384Ssklower 	switch (cmd) {
43237469Ssklower 
43337469Ssklower 	case SIOCAIFADDR_ISO:
43437469Ssklower 	case SIOCDIFADDR_ISO:
43537469Ssklower 		if (ifra->ifra_addr.siso_family == AF_ISO)
43637469Ssklower 		    for (oia = ia; ia; ia = ia->ia_next) {
43737469Ssklower 			if (ia->ia_ifp == ifp  &&
43837469Ssklower 			    SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
43937469Ssklower 				break;
44037469Ssklower 		}
44137547Smckusick 		if (error = suser(u.u_cred, &u.u_acflag))
44237547Smckusick 			return (error);
44336384Ssklower 		if (ifp == 0)
44437469Ssklower 			panic("iso_control");
44537469Ssklower 		if (ia == (struct iso_ifaddr *)0) {
44637469Ssklower 			struct iso_ifaddr *nia;
44737469Ssklower 			if (cmd == SIOCDIFADDR_ISO)
44837469Ssklower 				return (EADDRNOTAVAIL);
44937469Ssklower 			MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
45037469Ssklower 				       M_IFADDR, M_WAITOK);
45137469Ssklower 			if (nia == (struct iso_ifaddr *)0)
45237469Ssklower 				return (ENOBUFS);
45337469Ssklower 			bzero((caddr_t)nia, sizeof(*nia));
45437469Ssklower 			if (ia = iso_ifaddr) {
45537469Ssklower 				for ( ; ia->ia_next; ia = ia->ia_next)
45637469Ssklower 					;
45737469Ssklower 				ia->ia_next = nia;
45837469Ssklower 			} else
45937469Ssklower 				iso_ifaddr = nia;
46037469Ssklower 			ia = nia;
46137469Ssklower 			if (ifa = ifp->if_addrlist) {
46237469Ssklower 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
46337469Ssklower 					;
46437469Ssklower 				ifa->ifa_next = (struct ifaddr *) ia;
46537469Ssklower 			} else
46637469Ssklower 				ifp->if_addrlist = (struct ifaddr *) ia;
46737469Ssklower 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
46837469Ssklower 			ia->ia_ifa.ifa_dstaddr
46937469Ssklower 					= (struct sockaddr *)&ia->ia_dstaddr;
47037469Ssklower 			ia->ia_ifa.ifa_netmask
47137469Ssklower 					= (struct sockaddr *)&ia->ia_sockmask;
47237469Ssklower 			ia->ia_ifp = ifp;
47337469Ssklower 			if (ifp != &loif)
47437469Ssklower 				iso_interfaces++;
47537469Ssklower 		}
47637469Ssklower 		break;
47736384Ssklower 
47837469Ssklower #define cmdbyte(x)	(((x) >> 8) & 0xff)
47937469Ssklower 	default:
48037469Ssklower 		if (cmdbyte(cmd) == 'a')
48137469Ssklower 			return (snpac_ioctl(cmd, data));
48237469Ssklower 		if (ia == (struct iso_ifaddr *)0)
48337469Ssklower 			return (EADDRNOTAVAIL);
48437469Ssklower 		break;
48537469Ssklower 	}
48637469Ssklower 	switch (cmd) {
48736384Ssklower 
48837469Ssklower 	case SIOCGIFADDR_ISO:
48937469Ssklower 		ifr->ifr_Addr = ia->ia_addr;
49037469Ssklower 		break;
49136384Ssklower 
49237469Ssklower 	case SIOCGIFDSTADDR_ISO:
49337469Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
49437469Ssklower 			return (EINVAL);
49537469Ssklower 		ifr->ifr_Addr = ia->ia_dstaddr;
49637469Ssklower 		break;
49736384Ssklower 
49837469Ssklower 	case SIOCGIFNETMASK_ISO:
49937469Ssklower 		ifr->ifr_Addr = ia->ia_sockmask;
50037469Ssklower 		break;
50136384Ssklower 
50237469Ssklower 	case SIOCAIFADDR_ISO:
50337469Ssklower 		maskIsNew = 0; hostIsNew = 1; error = u.u_error;
50437469Ssklower 		if (ia->ia_addr.siso_family == AF_ISO) {
50537469Ssklower 			if (ifra->ifra_addr.siso_len == 0) {
50637469Ssklower 				ifra->ifra_addr = ia->ia_addr;
50737469Ssklower 				hostIsNew = 0;
50837469Ssklower 			} else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
50937469Ssklower 				hostIsNew = 0;
51037469Ssklower 		}
51137469Ssklower 		if (ifra->ifra_mask.siso_len) {
51237469Ssklower 			iso_ifscrub(ifp, ia);
51337469Ssklower 			ia->ia_sockmask = ifra->ifra_mask;
51437469Ssklower 			maskIsNew = 1;
51537469Ssklower 		}
51637469Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
51737469Ssklower 		    (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
51837469Ssklower 			iso_ifscrub(ifp, ia);
51937469Ssklower 			ia->ia_dstaddr = ifra->ifra_dstaddr;
52037469Ssklower 			maskIsNew  = 1; /* We lie; but the effect's the same */
52137469Ssklower 		}
52237469Ssklower 		if (ifra->ifra_addr.siso_family == AF_ISO &&
52337469Ssklower 					    (hostIsNew || maskIsNew)) {
52437469Ssklower 			error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
52537469Ssklower 		}
52637469Ssklower 		if (ifra->ifra_snpaoffset)
52737469Ssklower 			ia->ia_snpaoffset = ifra->ifra_snpaoffset;
52837469Ssklower 		return (error);
52937469Ssklower 
53037469Ssklower 	case SIOCDIFADDR_ISO:
53137469Ssklower 		iso_ifscrub(ifp, ia);
53237469Ssklower 		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
53337469Ssklower 			ifp->if_addrlist = ifa->ifa_next;
53437469Ssklower 		else {
53537469Ssklower 			while (ifa->ifa_next &&
53637469Ssklower 			       (ifa->ifa_next != (struct ifaddr *)ia))
53737469Ssklower 				    ifa = ifa->ifa_next;
53837469Ssklower 			if (ifa->ifa_next)
53937469Ssklower 			    ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
54037469Ssklower 			else
54137469Ssklower 				printf("Couldn't unlink isoifaddr from ifp\n");
54237469Ssklower 		}
54337469Ssklower 		oia = ia;
54437469Ssklower 		if (oia == (ia = iso_ifaddr)) {
54537469Ssklower 			iso_ifaddr = ia->ia_next;
54637469Ssklower 		} else {
54737469Ssklower 			while (ia->ia_next && (ia->ia_next != oia)) {
54837469Ssklower 				ia = ia->ia_next;
54936384Ssklower 			}
55037469Ssklower 			if (ia->ia_next)
55137469Ssklower 			    ia->ia_next = oia->ia_next;
55237469Ssklower 			else
55337469Ssklower 				printf("Didn't unlink isoifadr from list\n");
55436384Ssklower 		}
55537469Ssklower 		free((caddr_t)oia, M_IFADDR);
55637469Ssklower 		break;
55736384Ssklower 
55836384Ssklower 	default:
55936384Ssklower 		if (ifp == 0 || ifp->if_ioctl == 0)
56036384Ssklower 			return (EOPNOTSUPP);
56136384Ssklower 		return ((*ifp->if_ioctl)(ifp, cmd, data));
56236384Ssklower 	}
56337469Ssklower 	return (0);
56436384Ssklower }
56536384Ssklower 
56637469Ssklower /*
56737469Ssklower  * Delete any existing route for an interface.
56837469Ssklower  */
56937469Ssklower iso_ifscrub(ifp, ia)
57037469Ssklower 	register struct ifnet *ifp;
57137469Ssklower 	register struct iso_ifaddr *ia;
57237469Ssklower {
57337469Ssklower 	if ((ia->ia_flags & IFA_ROUTE) == 0)
57437469Ssklower 		return;
57537469Ssklower 	if (ifp->if_flags & IFF_LOOPBACK)
57637469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
57737469Ssklower 	else if (ifp->if_flags & IFF_POINTOPOINT)
57837469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
57937469Ssklower 	else {
58037469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
58137469Ssklower 	}
58237469Ssklower 	ia->ia_flags &= ~IFA_ROUTE;
58337469Ssklower }
58437469Ssklower 
58537469Ssklower /*
58637469Ssklower  * Initialize an interface's internet address
58737469Ssklower  * and routing table entry.
58837469Ssklower  */
58937469Ssklower iso_ifinit(ifp, ia, siso, scrub)
59037469Ssklower 	register struct ifnet *ifp;
59137469Ssklower 	register struct iso_ifaddr *ia;
59237469Ssklower 	struct sockaddr_iso *siso;
59337469Ssklower {
59437469Ssklower 	struct sockaddr_iso oldaddr;
59537469Ssklower 	int s = splimp(), error;
59637469Ssklower 
59737469Ssklower 	oldaddr = ia->ia_addr;
59837469Ssklower 	ia->ia_addr = *siso;
59937469Ssklower 	/*
60037469Ssklower 	 * Give the interface a chance to initialize
60137469Ssklower 	 * if this is its first address,
60237469Ssklower 	 * and to validate the address if necessary.
60337469Ssklower 	 */
60437469Ssklower 	if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
60537469Ssklower 		splx(s);
60637469Ssklower 		ia->ia_addr = oldaddr;
60737469Ssklower 		return (error);
60837469Ssklower 	}
60937469Ssklower 	if (scrub) {
61037469Ssklower 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
61137469Ssklower 		iso_ifscrub(ifp, ia);
61237469Ssklower 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
61337469Ssklower 	}
61437469Ssklower 	/*
61537469Ssklower 	 * Add route for the network.
61637469Ssklower 	 */
61737469Ssklower 	if (ifp->if_flags & IFF_LOOPBACK) {
61837469Ssklower 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
61937469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
62037469Ssklower 	} else if (ifp->if_flags & IFF_POINTOPOINT &&
62137469Ssklower 		 ia->ia_dstaddr.siso_family == AF_ISO)
62237469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
62337469Ssklower 	else {
62437469Ssklower 		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
62537469Ssklower 	}
62637469Ssklower 	ia->ia_flags |= IFA_ROUTE;
62737469Ssklower 	splx(s);
62837469Ssklower 	return (0);
62937469Ssklower }
63037469Ssklower #ifdef notdef
63137469Ssklower 
63236384Ssklower struct ifaddr *
63336384Ssklower iso_ifwithidi(addr)
63436384Ssklower 	register struct sockaddr *addr;
63536384Ssklower {
63636384Ssklower 	register struct ifnet *ifp;
63736384Ssklower 	register struct ifaddr *ifa;
63836384Ssklower 	register u_int af = addr->sa_family;
63936384Ssklower 
64036384Ssklower 	if (af != AF_ISO)
64136384Ssklower 		return (0);
64236384Ssklower 	IFDEBUG(D_ROUTE)
64336384Ssklower 		printf(">>> iso_ifwithidi addr\n");
64436384Ssklower 		dump_isoaddr( (struct sockaddr_iso *)(addr));
64536384Ssklower 		printf("\n");
64636384Ssklower 	ENDDEBUG
64736384Ssklower 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
64836384Ssklower 		IFDEBUG(D_ROUTE)
64936384Ssklower 			printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
65036384Ssklower 		ENDDEBUG
65136384Ssklower 		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
65236384Ssklower 			IFDEBUG(D_ROUTE)
65336384Ssklower 				printf("iso_ifwithidi address ");
65437469Ssklower 				dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
65536384Ssklower 			ENDDEBUG
65637469Ssklower 			if (ifa->ifa_addr->sa_family != addr->sa_family)
65736384Ssklower 				continue;
65836384Ssklower 
65936384Ssklower #define	IFA_SIS(ifa)\
66037469Ssklower 	((struct sockaddr_iso *)((ifa)->ifa_addr))
66136384Ssklower 
66236384Ssklower 			IFDEBUG(D_ROUTE)
66336384Ssklower 				printf(" af same, args to iso_eqtype:\n");
66436384Ssklower 				printf("0x%x ", IFA_SIS(ifa)->siso_addr);
66536384Ssklower 				printf(" 0x%x\n",
66636384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr));
66736384Ssklower 			ENDDEBUG
66836384Ssklower 
66936384Ssklower 			if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
67036384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr))) {
67136384Ssklower 				IFDEBUG(D_ROUTE)
67236384Ssklower 					printf("ifa_ifwithidi: ifa found\n");
67336384Ssklower 				ENDDEBUG
67436384Ssklower 				return (ifa);
67536384Ssklower 			}
67636384Ssklower 			IFDEBUG(D_ROUTE)
67736384Ssklower 				printf(" iso_eqtype failed\n");
67836384Ssklower 			ENDDEBUG
67936384Ssklower 		}
68036384Ssklower 	}
68136384Ssklower 	return ((struct ifaddr *)0);
68236384Ssklower }
68336384Ssklower 
68437469Ssklower #endif notdef
68536384Ssklower /*
68636384Ssklower  * FUNCTION:		iso_ck_addr
68736384Ssklower  *
68836384Ssklower  * PURPOSE:			return true if the iso_addr passed is
68936384Ssklower  *					within the legal size limit for an iso address.
69036384Ssklower  *
69136384Ssklower  * RETURNS:			true or false
69236384Ssklower  *
69336384Ssklower  * SIDE EFFECTS:
69436384Ssklower  *
69536384Ssklower  */
69636384Ssklower iso_ck_addr(isoa)
69736384Ssklower struct iso_addr	*isoa;	/* address to check */
69836384Ssklower {
69936384Ssklower 	return (isoa->isoa_len <= 20);
70036384Ssklower 
70136384Ssklower }
70236384Ssklower 
70337469Ssklower #ifdef notdef
70436384Ssklower /*
70536384Ssklower  * FUNCTION:		iso_eqtype
70636384Ssklower  *
70736384Ssklower  * PURPOSE:			Determine if two iso addresses are of the same type.
70836384Ssklower  *  This is flaky.  Really we should consider all type 47 addrs to be the
70936384Ssklower  *  same - but there do exist different structures for 47 addrs.
71036384Ssklower  *  Gosip adds a 3rd.
71136384Ssklower  *
71236384Ssklower  * RETURNS:			true if the addresses are the same type
71336384Ssklower  *
71436384Ssklower  * SIDE EFFECTS:
71536384Ssklower  *
71636384Ssklower  * NOTES:			By type, I mean rfc986, t37, or osinet
71736384Ssklower  *
71836384Ssklower  *					This will first compare afis. If they match, then
71936384Ssklower  *					if the addr is not t37, the idis must be compared.
72036384Ssklower  */
72136384Ssklower iso_eqtype(isoaa, isoab)
72236384Ssklower struct iso_addr	*isoaa;		/* first addr to check */
72336384Ssklower struct iso_addr	*isoab;		/* other addr to check */
72436384Ssklower {
72536384Ssklower 	if (isoaa->isoa_afi == isoab->isoa_afi) {
72636384Ssklower 		if (isoaa->isoa_afi == AFI_37)
72736384Ssklower 			return(1);
72836384Ssklower 		else
72936384Ssklower 			return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
73036384Ssklower 	}
73136384Ssklower 	return(0);
73236384Ssklower }
73337469Ssklower #endif notdef
73436384Ssklower /*
73537469Ssklower  * FUNCTION:		iso_localifa()
73636384Ssklower  *
73737469Ssklower  * PURPOSE:			Find an interface addresss having a given destination
73837469Ssklower  *					or at least matching the net.
73936384Ssklower  *
74036384Ssklower  * RETURNS:			ptr to an interface address
74136384Ssklower  *
74236384Ssklower  * SIDE EFFECTS:
74336384Ssklower  *
74436384Ssklower  * NOTES:
74536384Ssklower  */
74636384Ssklower struct iso_ifaddr *
74737469Ssklower iso_localifa(siso)
74837469Ssklower 	register struct sockaddr_iso *siso;
74936384Ssklower {
75036384Ssklower 	register struct iso_ifaddr *ia;
75137469Ssklower 	register char *cp1, *cp2, *cp3;
75237469Ssklower 	register struct ifnet *ifp;
75337469Ssklower 	struct iso_ifaddr *ia_maybe = 0;
75437469Ssklower 	/*
75537469Ssklower 	 * We make one pass looking for both net matches and an exact
75637469Ssklower 	 * dst addr.
75737469Ssklower 	 */
75837469Ssklower 	for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
75937469Ssklower 		if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
76037469Ssklower 			continue;
76137469Ssklower 		if (ifp->if_flags & IFF_POINTOPOINT) {
76237469Ssklower 			if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
76337469Ssklower 				SAME_ISOADDR(&ia->ia_dstaddr, siso))
76437469Ssklower 				return (ia);
76537469Ssklower 			else
76637469Ssklower 				if (SAME_ISOADDR(&ia->ia_addr, siso))
76737469Ssklower 					ia_maybe = ia;
76837469Ssklower 			continue;
76937469Ssklower 		}
77037469Ssklower 		if (ia->ia_sockmask.siso_len) {
77137469Ssklower 			char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
77237469Ssklower 			cp1 = ia->ia_sockmask.siso_data;
77337469Ssklower 			cp2 = siso->siso_data;
77437469Ssklower 			cp3 = ia->ia_addr.siso_data;
77537469Ssklower 			while (cp2 < cplim)
77637469Ssklower 				if (*cp1++ & (*cp2++ ^ *cp3++))
77737469Ssklower 					goto next;
77837469Ssklower 			ia_maybe = ia;
77937469Ssklower 		}
78037469Ssklower 		if (SAME_ISOADDR(&ia->ia_addr, siso))
78137469Ssklower 			return ia;
78237469Ssklower 	next:;
78337469Ssklower 	}
78437469Ssklower 	return ia_maybe;
78536384Ssklower }
78636384Ssklower 
78736384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
78836384Ssklower #include "cons.h"
78936384Ssklower #endif	NARGOXTWENTYFIVE > 0
79036384Ssklower /*
79136384Ssklower  * FUNCTION:		iso_nlctloutput
79236384Ssklower  *
79336384Ssklower  * PURPOSE:			Set options at the network level
79436384Ssklower  *
79536384Ssklower  * RETURNS:			E*
79636384Ssklower  *
79736384Ssklower  * SIDE EFFECTS:
79836384Ssklower  *
79936384Ssklower  * NOTES:			This could embody some of the functions of
80036384Ssklower  *					rclnp_ctloutput and cons_ctloutput.
80136384Ssklower  */
80236384Ssklower iso_nlctloutput(cmd, optname, pcb, m)
80336384Ssklower int			cmd;		/* command:set or get */
80436384Ssklower int			optname;	/* option of interest */
80536384Ssklower caddr_t		pcb;		/* nl pcb */
80636384Ssklower struct mbuf	*m;			/* data for set, buffer for get */
80736384Ssklower {
80836384Ssklower 	struct isopcb	*isop = (struct isopcb *)pcb;
80936384Ssklower 	int				error = 0;	/* return value */
81036384Ssklower 	caddr_t			data;		/* data for option */
81136384Ssklower 	int				data_len;	/* data's length */
81236384Ssklower 
81336384Ssklower 	IFDEBUG(D_ISO)
81436384Ssklower 		printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
81536384Ssklower 			cmd, optname, pcb, m);
81636384Ssklower 	ENDDEBUG
81736384Ssklower 
81836384Ssklower 	if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
81936384Ssklower 		return(EOPNOTSUPP);
82036384Ssklower 
82136384Ssklower 	data = mtod(m, caddr_t);
82236384Ssklower 	data_len = (m)->m_len;
82336384Ssklower 
82436384Ssklower 	IFDEBUG(D_ISO)
82536384Ssklower 		printf("iso_nlctloutput: data is:\n");
82636384Ssklower 		dump_buf(data, data_len);
82736384Ssklower 	ENDDEBUG
82836384Ssklower 
82936384Ssklower 	switch (optname) {
83036384Ssklower 
83136384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
83236384Ssklower 		case CONSOPT_X25CRUD:
83336384Ssklower 			if (cmd == PRCO_GETOPT) {
83436384Ssklower 				error = EOPNOTSUPP;
83536384Ssklower 				break;
83636384Ssklower 			}
83736384Ssklower 
83836384Ssklower 			if (data_len > MAXX25CRUDLEN) {
83936384Ssklower 				error = EINVAL;
84036384Ssklower 				break;
84136384Ssklower 			}
84236384Ssklower 
84336384Ssklower 			IFDEBUG(D_ISO)
84436384Ssklower 				printf("iso_nlctloutput: setting x25 crud\n");
84536384Ssklower 			ENDDEBUG
84636384Ssklower 
84737469Ssklower 			bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
84836384Ssklower 			isop->isop_x25crud_len = data_len;
84936384Ssklower 			break;
85036384Ssklower #endif	NARGOXTWENTYFIVE > 0
85136384Ssklower 
85236384Ssklower 		default:
85336384Ssklower 			error = EOPNOTSUPP;
85436384Ssklower 	}
85536384Ssklower 
85636384Ssklower 	return error;
85736384Ssklower }
85836384Ssklower 
85936384Ssklower /*
86036384Ssklower  * FUNCTION:		iso_routeifp
86136384Ssklower  *
86236384Ssklower  * PURPOSE:			Route on a sockaddr and return ifp
86336384Ssklower  *
86436384Ssklower  * RETURNS:			ifp of outgoing interface, or null
86536384Ssklower  *
86636384Ssklower  * SIDE EFFECTS:
86736384Ssklower  *
86836384Ssklower  * NOTES:
86936384Ssklower  */
87037469Ssklower struct iso_ifaddr *
87137469Ssklower iso_routeifa(dst)
87236384Ssklower struct sockaddr	*dst;		/* destination to route to */
87336384Ssklower {
87437469Ssklower 	struct rtentry	*rt;
87537469Ssklower 	struct ifaddr *ifa = 0;
87637469Ssklower 	struct ifnet *ifp = 0;
87736384Ssklower 
87836384Ssklower 
87936384Ssklower 	IFDEBUG(D_ROUTE)
88036384Ssklower 		printf("iso_routeifp: dst:");
88137469Ssklower 		dump_isoaddr((struct sockaddr_iso *)dst);
88236384Ssklower 	ENDDEBUG
88336384Ssklower 
88437469Ssklower 	rt = rtalloc1(dst, 0);
88536384Ssklower 
88637469Ssklower 	if (rt) {
88737469Ssklower 		ifa = rt->rt_ifa;
88837469Ssklower 		ifp = rt->rt_ifp;
88937469Ssklower 		RTFREE(rt);
89036384Ssklower 	}
89136384Ssklower 
89236384Ssklower 	IFDEBUG(D_ROUTE)
89337469Ssklower 		printf("iso_routeifp: ifa x%x", ifa);
89436384Ssklower 		if (ifp)
89536384Ssklower 			printf(" (%s%d)\n", ifp->if_name, ifp->if_unit);
89636384Ssklower 		else
89736384Ssklower 			printf("\n");
89836384Ssklower 	ENDDEBUG
89936384Ssklower 
90037469Ssklower 	return((struct iso_ifaddr *)ifa);
90136384Ssklower }
90236384Ssklower #endif ISO
90336384Ssklower 
90436384Ssklower #ifdef ARGO_DEBUG
90536384Ssklower 
90636384Ssklower /*
90736384Ssklower  * FUNCTION:		dump_isoaddr
90836384Ssklower  *
90936384Ssklower  * PURPOSE:			debugging
91036384Ssklower  *
91136384Ssklower  * RETURNS:			nada
91236384Ssklower  *
91336384Ssklower  */
91436384Ssklower dump_isoaddr(s)
91536384Ssklower 	struct sockaddr_iso *s;
91636384Ssklower {
91737469Ssklower 	char *clnp_saddr_isop();
91836384Ssklower 	register int i;
91936384Ssklower 
92036384Ssklower 	if( s->siso_family == AF_ISO) {
92137469Ssklower 		printf("ISO address: suffixlen %d, %s\n",
922*38841Ssklower 			s->siso_tlen, clnp_saddr_isop(s));
92336384Ssklower 	} else if( s->siso_family == AF_INET) {
92436384Ssklower 		/* hack */
92536384Ssklower 		struct sockaddr_in *sin = (struct sockaddr_in *)s;
92636384Ssklower 
92736384Ssklower 		printf("%d.%d.%d.%d: %d",
92836384Ssklower 			(sin->sin_addr.s_addr>>24)&0xff,
92936384Ssklower 			(sin->sin_addr.s_addr>>16)&0xff,
93036384Ssklower 			(sin->sin_addr.s_addr>>8)&0xff,
93136384Ssklower 			(sin->sin_addr.s_addr)&0xff,
93236384Ssklower 			sin->sin_port);
93336384Ssklower 	}
93436384Ssklower }
93536384Ssklower 
93636384Ssklower #endif ARGO_DEBUG
937