xref: /csrg-svn/sys/netiso/iso.c (revision 36384)
1*36384Ssklower /***********************************************************
2*36384Ssklower 		Copyright IBM Corporation 1987
3*36384Ssklower 
4*36384Ssklower                       All Rights Reserved
5*36384Ssklower 
6*36384Ssklower Permission to use, copy, modify, and distribute this software and its
7*36384Ssklower documentation for any purpose and without fee is hereby granted,
8*36384Ssklower provided that the above copyright notice appear in all copies and that
9*36384Ssklower both that copyright notice and this permission notice appear in
10*36384Ssklower supporting documentation, and that the name of IBM not be
11*36384Ssklower used in advertising or publicity pertaining to distribution of the
12*36384Ssklower software without specific, written prior permission.
13*36384Ssklower 
14*36384Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15*36384Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16*36384Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17*36384Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18*36384Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19*36384Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20*36384Ssklower SOFTWARE.
21*36384Ssklower 
22*36384Ssklower ******************************************************************/
23*36384Ssklower 
24*36384Ssklower /*
25*36384Ssklower  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
26*36384Ssklower  */
27*36384Ssklower /*
28*36384Ssklower  * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $
29*36384Ssklower  * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $
30*36384Ssklower  *
31*36384Ssklower  * iso.c: miscellaneous routines to support the iso address family
32*36384Ssklower  */
33*36384Ssklower 
34*36384Ssklower #ifndef lint
35*36384Ssklower static char *rcsid = "$Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $";
36*36384Ssklower #endif
37*36384Ssklower 
38*36384Ssklower 
39*36384Ssklower #include "../h/types.h"
40*36384Ssklower #include "../h/param.h"
41*36384Ssklower #include "../h/ioctl.h"
42*36384Ssklower #include "../h/mbuf.h"
43*36384Ssklower #include "../h/domain.h"
44*36384Ssklower #include "../h/protosw.h"
45*36384Ssklower #include "../h/socket.h"
46*36384Ssklower #include "../h/socketvar.h"
47*36384Ssklower #include "../h/uio.h"
48*36384Ssklower #include "../h/dir.h"
49*36384Ssklower #include "../h/user.h"
50*36384Ssklower #include "../h/errno.h"
51*36384Ssklower 
52*36384Ssklower #include "../net/if.h"
53*36384Ssklower #include "../net/route.h"
54*36384Ssklower #include "../net/af.h"
55*36384Ssklower 
56*36384Ssklower #include "../netiso/iso.h"
57*36384Ssklower #include "../netiso/iso_var.h"
58*36384Ssklower #include "../netiso/iso_snpac.h"
59*36384Ssklower #include "../netiso/iso_pcb.h"
60*36384Ssklower #include "../netiso/clnp.h"
61*36384Ssklower #include "../netiso/argo_debug.h"
62*36384Ssklower 
63*36384Ssklower #ifdef ISO
64*36384Ssklower 
65*36384Ssklower int	iso_interfaces = 0;		/* number of external interfaces */
66*36384Ssklower extern	struct ifnet loif;	/* loopback interface */
67*36384Ssklower 
68*36384Ssklower 
69*36384Ssklower /*
70*36384Ssklower  * FUNCTION:		iso_init
71*36384Ssklower  *
72*36384Ssklower  * PURPOSE:			initialize the iso address family
73*36384Ssklower  *
74*36384Ssklower  * RETURNS:			nothing
75*36384Ssklower  *
76*36384Ssklower  * SIDE EFFECTS:	1) zeros the maptab table.
77*36384Ssklower  *
78*36384Ssklower  * NOTES:
79*36384Ssklower  */
80*36384Ssklower iso_init()
81*36384Ssklower {
82*36384Ssklower 	extern struct maptab	iso_snpac[];
83*36384Ssklower 	extern int 				iso_snpac_size;
84*36384Ssklower 
85*36384Ssklower  	bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache));
86*36384Ssklower }
87*36384Ssklower 
88*36384Ssklower /*
89*36384Ssklower  * FUNCTION:		iso_addrmatch1
90*36384Ssklower  *
91*36384Ssklower  * PURPOSE:			decide if the two iso_addrs passed are equal
92*36384Ssklower  *
93*36384Ssklower  * RETURNS:			true if the addrs match, false if they do not
94*36384Ssklower  *
95*36384Ssklower  * SIDE EFFECTS:
96*36384Ssklower  *
97*36384Ssklower  * NOTES:
98*36384Ssklower  */
99*36384Ssklower iso_addrmatch1(isoaa, isoab)
100*36384Ssklower struct iso_addr	*isoaa, *isoab;		/* addresses to check */
101*36384Ssklower {
102*36384Ssklower 	int	compare_len;
103*36384Ssklower 
104*36384Ssklower 	IFDEBUG(D_ROUTE)
105*36384Ssklower 		printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
106*36384Ssklower 			isoab->isoa_len);
107*36384Ssklower 		printf("a:\n");
108*36384Ssklower 		dump_buf((caddr_t)isoaa, isoaa->isoa_len);
109*36384Ssklower 		printf("b:\n");
110*36384Ssklower 		dump_buf((caddr_t)isoab, isoab->isoa_len);
111*36384Ssklower 	ENDDEBUG
112*36384Ssklower 
113*36384Ssklower 	if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
114*36384Ssklower 		IFDEBUG(D_ROUTE)
115*36384Ssklower 			printf("iso_addrmatch1: returning false because of lengths\n");
116*36384Ssklower 		ENDDEBUG
117*36384Ssklower 		return 0;
118*36384Ssklower 	}
119*36384Ssklower 
120*36384Ssklower 	/* TODO : generalize this to all afis with masks */
121*36384Ssklower 	if(	isoaa->isoa_afi == AFI_37 ) {
122*36384Ssklower 		/* must not compare 2 least significant digits, or for
123*36384Ssklower 		 * that matter, the DSP
124*36384Ssklower 		 */
125*36384Ssklower 		compare_len = ADDR37_IDI_LEN - 1;
126*36384Ssklower 	}
127*36384Ssklower 
128*36384Ssklower 	IFDEBUG(D_ROUTE)
129*36384Ssklower 		int i;
130*36384Ssklower 		char *a, *b;
131*36384Ssklower 
132*36384Ssklower 		a = (char *) isoaa;
133*36384Ssklower 		b = (char *) isoab;
134*36384Ssklower 
135*36384Ssklower 		for (i=0; i<compare_len; i++) {
136*36384Ssklower 			printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
137*36384Ssklower 			if (a[i] != b[i]) {
138*36384Ssklower 				printf("\naddrs are not equal at byte %d\n", i);
139*36384Ssklower 				return(0);
140*36384Ssklower 			}
141*36384Ssklower 		}
142*36384Ssklower 		printf("\n");
143*36384Ssklower 		printf("addrs are equal\n");
144*36384Ssklower 		return (1);
145*36384Ssklower 	ENDDEBUG
146*36384Ssklower 	return (!bcmp((caddr_t)isoaa, (caddr_t)isoab, compare_len));
147*36384Ssklower }
148*36384Ssklower 
149*36384Ssklower /*
150*36384Ssklower  * FUNCTION:		iso_addrmatch
151*36384Ssklower  *
152*36384Ssklower  * PURPOSE:			decide if the two sockadrr_isos passed are equal
153*36384Ssklower  *
154*36384Ssklower  * RETURNS:			true if the addrs match, false if they do not
155*36384Ssklower  *
156*36384Ssklower  * SIDE EFFECTS:
157*36384Ssklower  *
158*36384Ssklower  * NOTES:
159*36384Ssklower  */
160*36384Ssklower iso_addrmatch(sisoa, sisob)
161*36384Ssklower struct sockaddr_iso	*sisoa, *sisob;		/* addresses to check */
162*36384Ssklower {
163*36384Ssklower 	return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
164*36384Ssklower }
165*36384Ssklower 
166*36384Ssklower /*
167*36384Ssklower  * FUNCTION:		iso_netmatch
168*36384Ssklower  *
169*36384Ssklower  * PURPOSE:			similar to iso_addrmatch but takes sockaddr_iso
170*36384Ssklower  *					as argument.
171*36384Ssklower  *
172*36384Ssklower  * RETURNS:			true if same net, false if not
173*36384Ssklower  *
174*36384Ssklower  * SIDE EFFECTS:
175*36384Ssklower  *
176*36384Ssklower  * NOTES:
177*36384Ssklower  */
178*36384Ssklower iso_netmatch(sisoa, sisob)
179*36384Ssklower struct sockaddr_iso *sisoa, *sisob;
180*36384Ssklower {
181*36384Ssklower 	u_char			bufa[sizeof(struct sockaddr_iso)];
182*36384Ssklower 	u_char			bufb[sizeof(struct sockaddr_iso)];
183*36384Ssklower 	register int	lena, lenb;
184*36384Ssklower 
185*36384Ssklower 	lena = iso_netof(&sisoa->siso_addr, bufa);
186*36384Ssklower 	lenb = iso_netof(&sisob->siso_addr, bufb);
187*36384Ssklower 
188*36384Ssklower 	IFDEBUG(D_ROUTE)
189*36384Ssklower 		printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
190*36384Ssklower 		printf("a:\n");
191*36384Ssklower 		dump_buf(bufa, lena);
192*36384Ssklower 		printf("b:\n");
193*36384Ssklower 		dump_buf(bufb, lenb);
194*36384Ssklower 	ENDDEBUG
195*36384Ssklower 
196*36384Ssklower 	return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
197*36384Ssklower }
198*36384Ssklower 
199*36384Ssklower /*
200*36384Ssklower  * FUNCTION:		iso_hashchar
201*36384Ssklower  *
202*36384Ssklower  * PURPOSE:			Hash all character in the buffer specified into
203*36384Ssklower  *					a long. Return the long.
204*36384Ssklower  *
205*36384Ssklower  * RETURNS:			The hash value.
206*36384Ssklower  *
207*36384Ssklower  * SIDE EFFECTS:
208*36384Ssklower  *
209*36384Ssklower  * NOTES:			The hash is achieved by exclusive ORing 4 byte
210*36384Ssklower  *					quantities.
211*36384Ssklower  */
212*36384Ssklower u_long
213*36384Ssklower iso_hashchar(buf, len)
214*36384Ssklower register caddr_t	buf;		/* buffer to pack from */
215*36384Ssklower register int		len;		/* length of buffer */
216*36384Ssklower {
217*36384Ssklower 	register u_long	h = 0;
218*36384Ssklower 	register int	i;
219*36384Ssklower 
220*36384Ssklower 	for (i=0; i<len; i+=4) {
221*36384Ssklower 		register u_long	l = 0;
222*36384Ssklower 
223*36384Ssklower 		if ((len - i) < 4) {
224*36384Ssklower 			/* buffer not multiple of 4 */
225*36384Ssklower 			switch (len - i) {
226*36384Ssklower 				case 3:
227*36384Ssklower 					l |= buf[i+2] << 8;
228*36384Ssklower 				case 2:
229*36384Ssklower 					l |= buf[i+1] << 16;
230*36384Ssklower 				case 1:
231*36384Ssklower 					l |= buf[i] << 24;
232*36384Ssklower 					break;
233*36384Ssklower 				default:
234*36384Ssklower 					printf("iso_hashchar: unexpected value x%x\n", len - i);
235*36384Ssklower 					break;
236*36384Ssklower 			}
237*36384Ssklower 		} else {
238*36384Ssklower 			l |= buf[i] << 24;
239*36384Ssklower 			l |= buf[i+1] << 16;
240*36384Ssklower 			l |= buf[i+2] << 8;
241*36384Ssklower 			l |= buf[i+3];
242*36384Ssklower 		}
243*36384Ssklower 
244*36384Ssklower 		h ^= l;
245*36384Ssklower 	}
246*36384Ssklower 
247*36384Ssklower 	h ^= (u_long) (len % 4);
248*36384Ssklower 
249*36384Ssklower 	return(h);
250*36384Ssklower }
251*36384Ssklower 
252*36384Ssklower /*
253*36384Ssklower  * FUNCTION:		iso_hash
254*36384Ssklower  *
255*36384Ssklower  * PURPOSE:			Fill in fields of afhash structure based upon addr passed.
256*36384Ssklower  *
257*36384Ssklower  * RETURNS:			none
258*36384Ssklower  *
259*36384Ssklower  * SIDE EFFECTS:
260*36384Ssklower  *
261*36384Ssklower  * NOTES:
262*36384Ssklower  */
263*36384Ssklower iso_hash(siso, hp)
264*36384Ssklower struct sockaddr_iso	*siso;		/* address to perform hash on */
265*36384Ssklower struct afhash		*hp;		/* RETURN: hash info here */
266*36384Ssklower {
267*36384Ssklower 	u_long			buf[sizeof(struct sockaddr_iso)+1/4];
268*36384Ssklower 	register int	bufsize;
269*36384Ssklower 
270*36384Ssklower 
271*36384Ssklower 	bzero(buf, sizeof(buf));
272*36384Ssklower 
273*36384Ssklower 	bufsize = iso_netof(&siso->siso_addr, buf);
274*36384Ssklower 	hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
275*36384Ssklower 
276*36384Ssklower 	IFDEBUG(D_ROUTE)
277*36384Ssklower 		printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
278*36384Ssklower 	ENDDEBUG
279*36384Ssklower 
280*36384Ssklower 	hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
281*36384Ssklower 		siso->siso_addr.isoa_len);
282*36384Ssklower 
283*36384Ssklower 	IFDEBUG(D_ROUTE)
284*36384Ssklower 		printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
285*36384Ssklower 			clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
286*36384Ssklower 			hp->afh_hosthash);
287*36384Ssklower 	ENDDEBUG
288*36384Ssklower }
289*36384Ssklower 
290*36384Ssklower /*
291*36384Ssklower  * FUNCTION:		iso_netof
292*36384Ssklower  *
293*36384Ssklower  * PURPOSE:			Extract the network portion of the iso address.
294*36384Ssklower  *					The network portion of the iso address varies depending
295*36384Ssklower  *					on the type of address. The network portion of the
296*36384Ssklower  *					address will include the IDP. The network portion is:
297*36384Ssklower  *
298*36384Ssklower  *						TYPE			DESC
299*36384Ssklower  *					t37					The AFI and x.121 (IDI)
300*36384Ssklower  *					osinet				The AFI, orgid, snetid
301*36384Ssklower  *					rfc986				The AFI, vers and network part of
302*36384Ssklower  *										internet address.
303*36384Ssklower  *
304*36384Ssklower  * RETURNS:			number of bytes placed into buf.
305*36384Ssklower  *
306*36384Ssklower  * SIDE EFFECTS:
307*36384Ssklower  *
308*36384Ssklower  * NOTES:			Buf is assumed to be big enough
309*36384Ssklower  */
310*36384Ssklower iso_netof(isoa, buf)
311*36384Ssklower struct iso_addr	*isoa;		/* address */
312*36384Ssklower caddr_t			buf;		/* RESULT: network portion of address here */
313*36384Ssklower {
314*36384Ssklower 	u_int		len = 1;	/* length of afi */
315*36384Ssklower 
316*36384Ssklower 	switch (isoa->isoa_afi) {
317*36384Ssklower 		case AFI_37:
318*36384Ssklower 			/*
319*36384Ssklower 			 * Due to classic x.25 tunnel vision, there is no
320*36384Ssklower 			 * net portion of an x.121 address.  For our purposes
321*36384Ssklower 			 * the AFI will do, so that all x.25 -type addresses
322*36384Ssklower 			 * map to the single x.25 SNPA. (Cannot have more than
323*36384Ssklower 			 * one, obviously).
324*36384Ssklower 			 */
325*36384Ssklower 
326*36384Ssklower 			break;
327*36384Ssklower 
328*36384Ssklower /* 		case AFI_OSINET:*/
329*36384Ssklower 		case AFI_RFC986: {
330*36384Ssklower 			u_short	idi;	/* value of idi */
331*36384Ssklower 
332*36384Ssklower 			/* osinet and rfc986 have idi in the same place */
333*36384Ssklower 			CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
334*36384Ssklower 
335*36384Ssklower 			if (idi == IDI_OSINET)
336*36384Ssklower /*
337*36384Ssklower  *	Network portion of OSINET address can only be the IDI. Clearly,
338*36384Ssklower  *	with one x25 interface, one could get to several orgids, and
339*36384Ssklower  *	several snetids.
340*36384Ssklower 				len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
341*36384Ssklower 						OVLOSINET_SNETID_LEN);
342*36384Ssklower  */
343*36384Ssklower 				len += ADDROSINET_IDI_LEN;
344*36384Ssklower 			else if (idi == IDI_RFC986) {
345*36384Ssklower 				u_long				inetaddr;
346*36384Ssklower 				struct ovl_rfc986	*o986 = (struct ovl_rfc986 *)isoa;
347*36384Ssklower 
348*36384Ssklower 				/* bump len to include idi and version (1 byte) */
349*36384Ssklower 				len += ADDRRFC986_IDI_LEN + 1;
350*36384Ssklower 
351*36384Ssklower 				/* get inet addr long aligned */
352*36384Ssklower 				bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
353*36384Ssklower 				inetaddr = ntohl(inetaddr);	/* convert to host byte order */
354*36384Ssklower 
355*36384Ssklower 				IFDEBUG(D_ROUTE)
356*36384Ssklower 					printf("iso_netof: isoa ");
357*36384Ssklower 					dump_buf(isoa, sizeof(*isoa));
358*36384Ssklower 					printf("iso_netof: inetaddr 0x%x ", inetaddr);
359*36384Ssklower 				ENDDEBUG
360*36384Ssklower 
361*36384Ssklower 				/* bump len by size of network portion of inet address */
362*36384Ssklower 				if (IN_CLASSA(inetaddr)) {
363*36384Ssklower 					len += 4-IN_CLASSA_NSHIFT/8;
364*36384Ssklower 					IFDEBUG(D_ROUTE)
365*36384Ssklower 						printf("iso_netof: class A net len is now %d\n", len);
366*36384Ssklower 					ENDDEBUG
367*36384Ssklower 				} else if (IN_CLASSB(inetaddr)) {
368*36384Ssklower 					len += 4-IN_CLASSB_NSHIFT/8;
369*36384Ssklower 					IFDEBUG(D_ROUTE)
370*36384Ssklower 						printf("iso_netof: class B net len is now %d\n", len);
371*36384Ssklower 					ENDDEBUG
372*36384Ssklower 				} else {
373*36384Ssklower 					len += 4-IN_CLASSC_NSHIFT/8;
374*36384Ssklower 					IFDEBUG(D_ROUTE)
375*36384Ssklower 						printf("iso_netof: class C net len is now %d\n", len);
376*36384Ssklower 					ENDDEBUG
377*36384Ssklower 				}
378*36384Ssklower 			} else
379*36384Ssklower 				len = 0;
380*36384Ssklower 		} break;
381*36384Ssklower 
382*36384Ssklower 		default:
383*36384Ssklower 			len = 0;
384*36384Ssklower 	}
385*36384Ssklower 
386*36384Ssklower 	bcopy((caddr_t)isoa, buf, len);
387*36384Ssklower 	IFDEBUG(D_ROUTE)
388*36384Ssklower 		printf("in_netof: isoa ");
389*36384Ssklower 		dump_buf(isoa, len);
390*36384Ssklower 		printf("in_netof: net ");
391*36384Ssklower 		dump_buf(buf, len);
392*36384Ssklower 	ENDDEBUG
393*36384Ssklower 	return len;
394*36384Ssklower }
395*36384Ssklower 
396*36384Ssklower /*
397*36384Ssklower  *	The following is a kludge until I figure something out. Since AFISO
398*36384Ssklower  *	allows >1 addr/ifp, SIOCGIFADDR can possibly return more than one
399*36384Ssklower  *	address. Rather than changing the ifreq structure, I have set up
400*36384Ssklower  *	the ioctl so it will return the address in sequential calls. When
401*36384Ssklower  *	all addresses have been read, EADDRNOTAVAIL will be returned.
402*36384Ssklower  *
403*36384Ssklower  *	A call to delete or set an addr will cause a subsequent get to
404*36384Ssklower  *	retrieve the first addr, even if the first had already been read.
405*36384Ssklower  *
406*36384Ssklower  *	The static pointer iso_ia keeps track of which addrs have been read.
407*36384Ssklower  */
408*36384Ssklower static struct iso_ifaddr *iso_iap = NULL;
409*36384Ssklower 
410*36384Ssklower /*
411*36384Ssklower  * FUNCTION:		iso_control
412*36384Ssklower  *
413*36384Ssklower  * PURPOSE:			Generic iso control operations (ioctl's).
414*36384Ssklower  *					Ifp is 0 if this is not an interface-specific ioctl.
415*36384Ssklower  *
416*36384Ssklower  * RETURNS:			unix error code
417*36384Ssklower  *
418*36384Ssklower  * SIDE EFFECTS:
419*36384Ssklower  *
420*36384Ssklower  * NOTES:			The iso address family will allow more than one
421*36384Ssklower  *					iso address per interface as long as they are different
422*36384Ssklower  *					iso address types. The three types currently supported
423*36384Ssklower  *					are rfc986, t37, and osinet.
424*36384Ssklower  */
425*36384Ssklower iso_control(so, cmd, data, ifp)
426*36384Ssklower struct socket	*so;		/* socket ioctl arrived on */
427*36384Ssklower int				cmd;		/* ioctl to perform */
428*36384Ssklower caddr_t			data;		/* data for the ioctl */
429*36384Ssklower struct ifnet	*ifp;		/* optional interface ptr */
430*36384Ssklower {
431*36384Ssklower 	register struct ifreq		*ifr = (struct ifreq *)data;
432*36384Ssklower 	register struct iso_ifaddr	*ia = 0;
433*36384Ssklower 	struct ifaddr				*ifa;
434*36384Ssklower 	struct mbuf					*m;
435*36384Ssklower 
436*36384Ssklower 
437*36384Ssklower 	switch (cmd) {
438*36384Ssklower 	case SIOCSIFADDR:
439*36384Ssklower 		if (!suser())
440*36384Ssklower 			return (u.u_error);
441*36384Ssklower 
442*36384Ssklower 		if (ifp == 0)
443*36384Ssklower 			panic("iso_control: SIOCSIFADDR");
444*36384Ssklower 
445*36384Ssklower 		/*
446*36384Ssklower 		 *	Check if a iso address of same type exists for ifp
447*36384Ssklower 		 *	If it does, then return an error.
448*36384Ssklower 		 */
449*36384Ssklower 		for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
450*36384Ssklower 			if (ia->ia_ifp == ifp) {
451*36384Ssklower 				struct sockaddr_iso *siso;
452*36384Ssklower 
453*36384Ssklower 				siso = (struct sockaddr_iso *)&ifr->ifr_addr;
454*36384Ssklower 				if (iso_eqtype(&IA_SIS(ia)->siso_addr, &siso->siso_addr))
455*36384Ssklower 					return(EADDRNOTAVAIL);
456*36384Ssklower 			}
457*36384Ssklower 		}
458*36384Ssklower 
459*36384Ssklower 		/*
460*36384Ssklower 		 *	Go ahead and create new ifaddr
461*36384Ssklower 		 *
462*36384Ssklower 		 *	Link addr into list of iso addresses
463*36384Ssklower 		 */
464*36384Ssklower 		m = m_getclr(M_WAIT, MT_IFADDR);
465*36384Ssklower 		if (m == (struct mbuf *)NULL)
466*36384Ssklower 			return (ENOBUFS);
467*36384Ssklower 		if (ia = iso_ifaddr) {
468*36384Ssklower 			for ( ; ia->ia_next; ia = ia->ia_next)
469*36384Ssklower 				;
470*36384Ssklower 			ia->ia_next = mtod(m, struct iso_ifaddr *);
471*36384Ssklower 		} else
472*36384Ssklower 			iso_ifaddr = mtod(m, struct iso_ifaddr *);
473*36384Ssklower 		iso_iap = iso_ifaddr;
474*36384Ssklower 
475*36384Ssklower 		/*
476*36384Ssklower 		 *	Link addr into list on interface
477*36384Ssklower 		 */
478*36384Ssklower 		ia = mtod(m, struct iso_ifaddr *);
479*36384Ssklower 		if (ifa = ifp->if_addrlist) {
480*36384Ssklower 			for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
481*36384Ssklower 				;
482*36384Ssklower 			ifa->ifa_next = (struct ifaddr *) ia;
483*36384Ssklower 		} else
484*36384Ssklower 			ifp->if_addrlist = (struct ifaddr *) ia;
485*36384Ssklower 
486*36384Ssklower 		ia->ia_ifp = ifp;
487*36384Ssklower 		IA_SIS(ia)->siso_family = AF_ISO;
488*36384Ssklower 		if (ifp != &loif)
489*36384Ssklower 			iso_interfaces++;
490*36384Ssklower 		return (iso_ifinit(ifp, ia, &ifr->ifr_addr));
491*36384Ssklower 
492*36384Ssklower 	case SIOCGIFADDR:
493*36384Ssklower 		for (ia = iso_iap; ia; ia = ia->ia_next) {
494*36384Ssklower 			if (ia->ia_ifp == ifp) {
495*36384Ssklower 				ifr->ifr_addr = ia->ia_addr;
496*36384Ssklower 				iso_iap = ia->ia_next;
497*36384Ssklower 				return (0);
498*36384Ssklower 			}
499*36384Ssklower 		}
500*36384Ssklower 		iso_iap = iso_ifaddr;
501*36384Ssklower 		return(EADDRNOTAVAIL);
502*36384Ssklower 
503*36384Ssklower 	case SIOCDIFADDR: /* TODO: what about this ioctl on other families */
504*36384Ssklower 		if (!suser())
505*36384Ssklower 			return (u.u_error);
506*36384Ssklower 		iso_iap = iso_ifaddr;
507*36384Ssklower 
508*36384Ssklower 		if (ifp == 0)
509*36384Ssklower 			panic("iso_control: SIOCDIFADDR");
510*36384Ssklower 
511*36384Ssklower 		return (iso_ifdelete(ifp, &ifr->ifr_addr));
512*36384Ssklower 
513*36384Ssklower 	default:
514*36384Ssklower 		if (ifp == 0 || ifp->if_ioctl == 0)
515*36384Ssklower 			return (EOPNOTSUPP);
516*36384Ssklower 		return ((*ifp->if_ioctl)(ifp, cmd, data));
517*36384Ssklower 	}
518*36384Ssklower }
519*36384Ssklower 
520*36384Ssklower struct ifaddr *
521*36384Ssklower iso_ifwithidi(addr)
522*36384Ssklower 	register struct sockaddr *addr;
523*36384Ssklower {
524*36384Ssklower 	register struct ifnet *ifp;
525*36384Ssklower 	register struct ifaddr *ifa;
526*36384Ssklower 	register u_int af = addr->sa_family;
527*36384Ssklower 
528*36384Ssklower 	if (af != AF_ISO)
529*36384Ssklower 		return (0);
530*36384Ssklower 	IFDEBUG(D_ROUTE)
531*36384Ssklower 		printf(">>> iso_ifwithidi addr\n");
532*36384Ssklower 		dump_isoaddr( (struct sockaddr_iso *)(addr));
533*36384Ssklower 		printf("\n");
534*36384Ssklower 	ENDDEBUG
535*36384Ssklower 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
536*36384Ssklower 		IFDEBUG(D_ROUTE)
537*36384Ssklower 			printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
538*36384Ssklower 		ENDDEBUG
539*36384Ssklower 		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
540*36384Ssklower 			IFDEBUG(D_ROUTE)
541*36384Ssklower 				printf("iso_ifwithidi address ");
542*36384Ssklower 				dump_isoaddr( (struct sockaddr_iso *)(&ifa->ifa_addr));
543*36384Ssklower 			ENDDEBUG
544*36384Ssklower 			if (ifa->ifa_addr.sa_family != addr->sa_family)
545*36384Ssklower 				continue;
546*36384Ssklower 
547*36384Ssklower #define	IFA_SIS(ifa)\
548*36384Ssklower 	((struct sockaddr_iso *)&((ifa)->ifa_addr))
549*36384Ssklower 
550*36384Ssklower 			IFDEBUG(D_ROUTE)
551*36384Ssklower 				printf(" af same, args to iso_eqtype:\n");
552*36384Ssklower 				printf("0x%x ", IFA_SIS(ifa)->siso_addr);
553*36384Ssklower 				printf(" 0x%x\n",
554*36384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr));
555*36384Ssklower 			ENDDEBUG
556*36384Ssklower 
557*36384Ssklower 			if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
558*36384Ssklower 				&(((struct sockaddr_iso *)addr)->siso_addr))) {
559*36384Ssklower 				IFDEBUG(D_ROUTE)
560*36384Ssklower 					printf("ifa_ifwithidi: ifa found\n");
561*36384Ssklower 				ENDDEBUG
562*36384Ssklower 				return (ifa);
563*36384Ssklower 			}
564*36384Ssklower 			IFDEBUG(D_ROUTE)
565*36384Ssklower 				printf(" iso_eqtype failed\n");
566*36384Ssklower 			ENDDEBUG
567*36384Ssklower 		}
568*36384Ssklower 	}
569*36384Ssklower 	return ((struct ifaddr *)0);
570*36384Ssklower }
571*36384Ssklower 
572*36384Ssklower /*
573*36384Ssklower  * FUNCTION:		iso_ifinit
574*36384Ssklower  *
575*36384Ssklower  * PURPOSE:			Initialize an interface's iso address and
576*36384Ssklower  *					routing table entry.
577*36384Ssklower  *
578*36384Ssklower  * RETURNS:			unix error code
579*36384Ssklower  *
580*36384Ssklower  * SIDE EFFECTS:
581*36384Ssklower  *
582*36384Ssklower  * NOTES:
583*36384Ssklower  */
584*36384Ssklower iso_ifinit(ifp, ia, siso)
585*36384Ssklower register struct ifnet		*ifp;	/* interface to initialize */
586*36384Ssklower register struct iso_ifaddr	*ia;	/* addr on ifnet list */
587*36384Ssklower struct sockaddr_iso			*siso;	/* address to use */
588*36384Ssklower {
589*36384Ssklower 	struct sockaddr oldaddr;
590*36384Ssklower 	struct sockaddr_iso netaddr;
591*36384Ssklower 	int s = splimp(), error;
592*36384Ssklower 
593*36384Ssklower 	/*
594*36384Ssklower 	 *	Make sure the address make sense
595*36384Ssklower 	 */
596*36384Ssklower 	if (!iso_ck_addr(&siso->siso_addr))
597*36384Ssklower 		return(EINVAL);
598*36384Ssklower 	IFDEBUG(D_ROUTE)
599*36384Ssklower 		int i;
600*36384Ssklower 		char *ptr;
601*36384Ssklower 
602*36384Ssklower 		ptr = (char *) siso;
603*36384Ssklower 		printf("The size of sockaddr_iso is %d\n",
604*36384Ssklower 			sizeof(struct sockaddr_iso));
605*36384Ssklower 		for(i=0; i< sizeof(struct sockaddr_iso); i++) {
606*36384Ssklower 			printf("sockaddr[%d] = 0x%x\n", i, *ptr++ & 0xff);
607*36384Ssklower 		}
608*36384Ssklower 	ENDDEBUG
609*36384Ssklower 
610*36384Ssklower 	oldaddr = ia->ia_addr;
611*36384Ssklower 	ia->ia_addr = *(struct sockaddr *)siso;
612*36384Ssklower 	bzero((caddr_t)&netaddr, sizeof (netaddr));
613*36384Ssklower 	netaddr.siso_family = AF_ISO;
614*36384Ssklower 
615*36384Ssklower 	/*
616*36384Ssklower 	 * Give the interface a chance to initialize
617*36384Ssklower 	 */
618*36384Ssklower 	if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
619*36384Ssklower 		splx(s);
620*36384Ssklower 		ia->ia_addr = oldaddr;
621*36384Ssklower 		return (error);
622*36384Ssklower 	}
623*36384Ssklower 	splx(s);
624*36384Ssklower 
625*36384Ssklower 	/*
626*36384Ssklower 	 * Add route for the network.
627*36384Ssklower 	 */
628*36384Ssklower 	if (ifp->if_flags & IFF_LOOPBACK)
629*36384Ssklower 		rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT, RTF_HOST|RTF_UP);
630*36384Ssklower 	else {
631*36384Ssklower 		int len;
632*36384Ssklower 
633*36384Ssklower 		len = iso_netof(&siso->siso_addr, (caddr_t)&netaddr.siso_addr);
634*36384Ssklower 		netaddr.siso_addr.isoa_len = len;
635*36384Ssklower 		rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
636*36384Ssklower 		    (int)SIOCADDRT, RTF_UP);
637*36384Ssklower 	}
638*36384Ssklower 	ia->ia_flags |= IFA_ROUTE;
639*36384Ssklower 	return (0);
640*36384Ssklower }
641*36384Ssklower 
642*36384Ssklower 
643*36384Ssklower /*
644*36384Ssklower  * FUNCTION:		iso_ifdelete
645*36384Ssklower  *
646*36384Ssklower  * PURPOSE:			Delete an iso address from an interface.
647*36384Ssklower  *
648*36384Ssklower  * RETURNS:			0 or unix error code
649*36384Ssklower  *
650*36384Ssklower  * SIDE EFFECTS:
651*36384Ssklower  *
652*36384Ssklower  * NOTES:
653*36384Ssklower  */
654*36384Ssklower iso_ifdelete(ifp, siso)
655*36384Ssklower struct ifnet		*ifp;	/* interface to delete addr from */
656*36384Ssklower struct sockaddr_iso	*siso;	/* address to delete */
657*36384Ssklower {
658*36384Ssklower 	struct iso_addr 			*isoa = &siso->siso_addr;
659*36384Ssklower 	register struct iso_ifaddr	*ia, *prev = 0;
660*36384Ssklower 	register struct ifaddr		*ifa;
661*36384Ssklower 	int 						s;
662*36384Ssklower 	struct sockaddr_iso 		netaddr;
663*36384Ssklower 
664*36384Ssklower 	/*
665*36384Ssklower 	 *	Find the iso address of same type as specified and delete it.
666*36384Ssklower 	 */
667*36384Ssklower 	for (ia = iso_ifaddr; ia; prev = ia, ia = ia->ia_next) {
668*36384Ssklower 		if (ia->ia_ifp == ifp) {
669*36384Ssklower 			if (iso_eqtype(&IA_SIS(ia)->siso_addr, isoa)) {
670*36384Ssklower 				/*
671*36384Ssklower 				 * Delete any previous route for the address.
672*36384Ssklower 				 */
673*36384Ssklower 				IFDEBUG(D_IOCTL)
674*36384Ssklower 					printf("iso_ifdelete: delete %s\n", clnp_iso_addrp(isoa))
675*36384Ssklower 				ENDDEBUG
676*36384Ssklower 				s = splimp();
677*36384Ssklower 				bzero((caddr_t)&netaddr, sizeof (netaddr));
678*36384Ssklower 				netaddr.siso_family = AF_ISO;
679*36384Ssklower 				if (ia->ia_flags & IFA_ROUTE) {
680*36384Ssklower 					if (ifp->if_flags & IFF_LOOPBACK)
681*36384Ssklower 						rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCDELRT,
682*36384Ssklower 							RTF_HOST);
683*36384Ssklower 					else {
684*36384Ssklower 						(void) iso_netof(&siso->siso_addr,
685*36384Ssklower 							(caddr_t)&netaddr.siso_addr);
686*36384Ssklower 						rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
687*36384Ssklower 							(int)SIOCDELRT, 0);
688*36384Ssklower 					}
689*36384Ssklower 					ia->ia_flags &= ~IFA_ROUTE;
690*36384Ssklower 				}
691*36384Ssklower 				splx(s);
692*36384Ssklower 
693*36384Ssklower 				/*
694*36384Ssklower 				 *	Remove from list of iso addresses
695*36384Ssklower 				 */
696*36384Ssklower 				if (prev == 0)
697*36384Ssklower 					iso_ifaddr = ia->ia_next;
698*36384Ssklower 				else
699*36384Ssklower 					prev->ia_next = ia->ia_next;
700*36384Ssklower 				if (ifp != &loif)
701*36384Ssklower 					iso_interfaces--;
702*36384Ssklower 
703*36384Ssklower 				/*
704*36384Ssklower 				 *	Remove from list of addrs on ifnet structure
705*36384Ssklower 				 */
706*36384Ssklower 				if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
707*36384Ssklower 					ifp->if_addrlist = ia->ia_ifa.ifa_next;
708*36384Ssklower 				else {
709*36384Ssklower 					for (; ifa; ifa = ifa->ifa_next) {
710*36384Ssklower 						if (ifa->ifa_next == (struct ifaddr *)ia) {
711*36384Ssklower 							ifa->ifa_next = ia->ia_ifa.ifa_next;
712*36384Ssklower 							break;
713*36384Ssklower 						}
714*36384Ssklower 					}
715*36384Ssklower 				}
716*36384Ssklower 
717*36384Ssklower 				/*
718*36384Ssklower 				 *	Free the iso_ifaddr mbuf
719*36384Ssklower 				 */
720*36384Ssklower 				m_free(dtom(ia));
721*36384Ssklower 				return (0);
722*36384Ssklower 			}
723*36384Ssklower 		}
724*36384Ssklower 	}
725*36384Ssklower 	return(EADDRNOTAVAIL);
726*36384Ssklower }
727*36384Ssklower 
728*36384Ssklower /*
729*36384Ssklower  * FUNCTION:		iso_ck_addr
730*36384Ssklower  *
731*36384Ssklower  * PURPOSE:			return true if the iso_addr passed is
732*36384Ssklower  *					within the legal size limit for an iso address.
733*36384Ssklower  *
734*36384Ssklower  * RETURNS:			true or false
735*36384Ssklower  *
736*36384Ssklower  * SIDE EFFECTS:
737*36384Ssklower  *
738*36384Ssklower  */
739*36384Ssklower iso_ck_addr(isoa)
740*36384Ssklower struct iso_addr	*isoa;	/* address to check */
741*36384Ssklower {
742*36384Ssklower 	return (isoa->isoa_len <= 20);
743*36384Ssklower 
744*36384Ssklower }
745*36384Ssklower 
746*36384Ssklower 
747*36384Ssklower /*
748*36384Ssklower  * FUNCTION:		iso_eqtype
749*36384Ssklower  *
750*36384Ssklower  * PURPOSE:			Determine if two iso addresses are of the same type.
751*36384Ssklower  *  This is flaky.  Really we should consider all type 47 addrs to be the
752*36384Ssklower  *  same - but there do exist different structures for 47 addrs.
753*36384Ssklower  *  Gosip adds a 3rd.
754*36384Ssklower  *
755*36384Ssklower  * RETURNS:			true if the addresses are the same type
756*36384Ssklower  *
757*36384Ssklower  * SIDE EFFECTS:
758*36384Ssklower  *
759*36384Ssklower  * NOTES:			By type, I mean rfc986, t37, or osinet
760*36384Ssklower  *
761*36384Ssklower  *					This will first compare afis. If they match, then
762*36384Ssklower  *					if the addr is not t37, the idis must be compared.
763*36384Ssklower  */
764*36384Ssklower iso_eqtype(isoaa, isoab)
765*36384Ssklower struct iso_addr	*isoaa;		/* first addr to check */
766*36384Ssklower struct iso_addr	*isoab;		/* other addr to check */
767*36384Ssklower {
768*36384Ssklower 	if (isoaa->isoa_afi == isoab->isoa_afi) {
769*36384Ssklower 		if (isoaa->isoa_afi == AFI_37)
770*36384Ssklower 			return(1);
771*36384Ssklower 		else
772*36384Ssklower 			return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
773*36384Ssklower 	}
774*36384Ssklower 	return(0);
775*36384Ssklower }
776*36384Ssklower 
777*36384Ssklower /*
778*36384Ssklower  * FUNCTION:		iso_iaonnetof()
779*36384Ssklower  *
780*36384Ssklower  * PURPOSE:			Find and interface addresss based on the network
781*36384Ssklower  *					portion of an address.
782*36384Ssklower  *
783*36384Ssklower  * RETURNS:			ptr to an interface address
784*36384Ssklower  *
785*36384Ssklower  * SIDE EFFECTS:
786*36384Ssklower  *
787*36384Ssklower  * NOTES:
788*36384Ssklower  */
789*36384Ssklower struct iso_ifaddr *
790*36384Ssklower iso_iaonnetof(siso)
791*36384Ssklower 	struct sockaddr_iso *siso;
792*36384Ssklower {
793*36384Ssklower 	register struct iso_ifaddr *ia;
794*36384Ssklower 
795*36384Ssklower 	for (ia = iso_ifaddr; ia; ia = ia->ia_next)
796*36384Ssklower 		if (iso_netmatch( (struct sockaddr_iso *)(&ia->ia_ifa.ifa_addr), siso) )
797*36384Ssklower 			return (ia);
798*36384Ssklower 	return ((struct iso_ifaddr *)0);
799*36384Ssklower }
800*36384Ssklower 
801*36384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
802*36384Ssklower #include "cons.h"
803*36384Ssklower #endif	NARGOXTWENTYFIVE > 0
804*36384Ssklower /*
805*36384Ssklower  * FUNCTION:		iso_nlctloutput
806*36384Ssklower  *
807*36384Ssklower  * PURPOSE:			Set options at the network level
808*36384Ssklower  *
809*36384Ssklower  * RETURNS:			E*
810*36384Ssklower  *
811*36384Ssklower  * SIDE EFFECTS:
812*36384Ssklower  *
813*36384Ssklower  * NOTES:			This could embody some of the functions of
814*36384Ssklower  *					rclnp_ctloutput and cons_ctloutput.
815*36384Ssklower  */
816*36384Ssklower iso_nlctloutput(cmd, optname, pcb, m)
817*36384Ssklower int			cmd;		/* command:set or get */
818*36384Ssklower int			optname;	/* option of interest */
819*36384Ssklower caddr_t		pcb;		/* nl pcb */
820*36384Ssklower struct mbuf	*m;			/* data for set, buffer for get */
821*36384Ssklower {
822*36384Ssklower 	struct isopcb	*isop = (struct isopcb *)pcb;
823*36384Ssklower 	int				error = 0;	/* return value */
824*36384Ssklower 	caddr_t			data;		/* data for option */
825*36384Ssklower 	int				data_len;	/* data's length */
826*36384Ssklower 
827*36384Ssklower 	IFDEBUG(D_ISO)
828*36384Ssklower 		printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
829*36384Ssklower 			cmd, optname, pcb, m);
830*36384Ssklower 	ENDDEBUG
831*36384Ssklower 
832*36384Ssklower 	if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
833*36384Ssklower 		return(EOPNOTSUPP);
834*36384Ssklower 
835*36384Ssklower 	data = mtod(m, caddr_t);
836*36384Ssklower 	data_len = (m)->m_len;
837*36384Ssklower 
838*36384Ssklower 	IFDEBUG(D_ISO)
839*36384Ssklower 		printf("iso_nlctloutput: data is:\n");
840*36384Ssklower 		dump_buf(data, data_len);
841*36384Ssklower 	ENDDEBUG
842*36384Ssklower 
843*36384Ssklower 	switch (optname) {
844*36384Ssklower 
845*36384Ssklower #ifdef	NARGOXTWENTYFIVE > 0
846*36384Ssklower 		case CONSOPT_X25CRUD:
847*36384Ssklower 			if (cmd == PRCO_GETOPT) {
848*36384Ssklower 				error = EOPNOTSUPP;
849*36384Ssklower 				break;
850*36384Ssklower 			}
851*36384Ssklower 
852*36384Ssklower 			if (data_len > MAXX25CRUDLEN) {
853*36384Ssklower 				error = EINVAL;
854*36384Ssklower 				break;
855*36384Ssklower 			}
856*36384Ssklower 
857*36384Ssklower 			IFDEBUG(D_ISO)
858*36384Ssklower 				printf("iso_nlctloutput: setting x25 crud\n");
859*36384Ssklower 			ENDDEBUG
860*36384Ssklower 
861*36384Ssklower 			bcopy(data, (caddr_t)&isop->isop_x25crud, data_len);
862*36384Ssklower 			isop->isop_x25crud_len = data_len;
863*36384Ssklower 			break;
864*36384Ssklower #endif	NARGOXTWENTYFIVE > 0
865*36384Ssklower 
866*36384Ssklower 		default:
867*36384Ssklower 			error = EOPNOTSUPP;
868*36384Ssklower 	}
869*36384Ssklower 
870*36384Ssklower 	return error;
871*36384Ssklower }
872*36384Ssklower 
873*36384Ssklower /*
874*36384Ssklower  * FUNCTION:		iso_routeifp
875*36384Ssklower  *
876*36384Ssklower  * PURPOSE:			Route on a sockaddr and return ifp
877*36384Ssklower  *
878*36384Ssklower  * RETURNS:			ifp of outgoing interface, or null
879*36384Ssklower  *
880*36384Ssklower  * SIDE EFFECTS:
881*36384Ssklower  *
882*36384Ssklower  * NOTES:
883*36384Ssklower  */
884*36384Ssklower struct ifnet *
885*36384Ssklower iso_routeifp(dst)
886*36384Ssklower struct sockaddr	*dst;		/* destination to route to */
887*36384Ssklower {
888*36384Ssklower 	struct route	ro;
889*36384Ssklower 	struct ifnet	*ifp = NULL;
890*36384Ssklower 
891*36384Ssklower 	ro.ro_dst = *dst;
892*36384Ssklower 	ro.ro_rt = NULL;
893*36384Ssklower 
894*36384Ssklower 	IFDEBUG(D_ROUTE)
895*36384Ssklower 		printf("iso_routeifp: dst:");
896*36384Ssklower 		dump_isoaddr(dst);
897*36384Ssklower 	ENDDEBUG
898*36384Ssklower 
899*36384Ssklower 	rtalloc(&ro);
900*36384Ssklower 
901*36384Ssklower 	if (ro.ro_rt) {
902*36384Ssklower 		ifp = ro.ro_rt->rt_ifp;
903*36384Ssklower 		RTFREE(ro.ro_rt);
904*36384Ssklower 	}
905*36384Ssklower 
906*36384Ssklower 	IFDEBUG(D_ROUTE)
907*36384Ssklower 		printf("iso_routeifp: ifp x%x", ifp);
908*36384Ssklower 		if (ifp)
909*36384Ssklower 			printf(" (%s%d)\n", ifp->if_name, ifp->if_unit);
910*36384Ssklower 		else
911*36384Ssklower 			printf("\n");
912*36384Ssklower 	ENDDEBUG
913*36384Ssklower 
914*36384Ssklower 	return(ifp);
915*36384Ssklower }
916*36384Ssklower #endif ISO
917*36384Ssklower 
918*36384Ssklower #ifdef ARGO_DEBUG
919*36384Ssklower 
920*36384Ssklower /*
921*36384Ssklower  * FUNCTION:		dump_isoaddr
922*36384Ssklower  *
923*36384Ssklower  * PURPOSE:			debugging
924*36384Ssklower  *
925*36384Ssklower  * RETURNS:			nada
926*36384Ssklower  *
927*36384Ssklower  */
928*36384Ssklower dump_isoaddr(s)
929*36384Ssklower 	struct sockaddr_iso *s;
930*36384Ssklower {
931*36384Ssklower 	caddr_t c = (caddr_t)&(s->siso_addr.isoa_u);
932*36384Ssklower 	register int i;
933*36384Ssklower 
934*36384Ssklower 	if( s->siso_family == AF_ISO) {
935*36384Ssklower 		printf("len %d family: 0x%x  suffix 0x%x, afi 0x%x,",
936*36384Ssklower 			(int)s->siso_addr.isoa_len,
937*36384Ssklower 			(int)s->siso_family,
938*36384Ssklower 			s->siso_tsuffix, (int)s->siso_addr.isoa_afi);
939*36384Ssklower 		if( s->siso_addr.isoa_len > sizeof(struct sockaddr) )
940*36384Ssklower 			printf("ERROR-ADDR TOO BIG %d\n", s->siso_addr.isoa_len);
941*36384Ssklower 		else  {
942*36384Ssklower 			if (s->siso_addr.isoa_len != 0) {
943*36384Ssklower 			/* -2 because we already skipped the afi */
944*36384Ssklower 					for (i=0; i<s->siso_addr.isoa_len-2; i++)
945*36384Ssklower 						printf("0x%x.", *(c+i)&0xff);
946*36384Ssklower 					printf("0x%x\n", *(c+i)&0xff);
947*36384Ssklower 			}
948*36384Ssklower 		}
949*36384Ssklower 	} else if( s->siso_family == AF_INET) {
950*36384Ssklower 		/* hack */
951*36384Ssklower 		struct sockaddr_in *sin = (struct sockaddr_in *)s;
952*36384Ssklower 
953*36384Ssklower 		printf("%d.%d.%d.%d: %d",
954*36384Ssklower 			(sin->sin_addr.s_addr>>24)&0xff,
955*36384Ssklower 			(sin->sin_addr.s_addr>>16)&0xff,
956*36384Ssklower 			(sin->sin_addr.s_addr>>8)&0xff,
957*36384Ssklower 			(sin->sin_addr.s_addr)&0xff,
958*36384Ssklower 			sin->sin_port);
959*36384Ssklower 	}
960*36384Ssklower }
961*36384Ssklower 
962*36384Ssklower #endif ARGO_DEBUG
963