17981378eSbostic /*-
2fdf395daSbostic * Copyright (c) 1991, 1993
3fdf395daSbostic * The Regents of the University of California. All rights reserved.
47981378eSbostic *
57981378eSbostic * %sccs.include.redist.c%
67981378eSbostic *
7*7fa9e8f7Scgd * @(#)iso.c 8.3 (Berkeley) 01/09/95
87981378eSbostic */
97981378eSbostic
10e014b9acSsklower /***********************************************************
11e014b9acSsklower Copyright IBM Corporation 1987
12e014b9acSsklower
13e014b9acSsklower All Rights Reserved
14e014b9acSsklower
15e014b9acSsklower Permission to use, copy, modify, and distribute this software and its
16e014b9acSsklower documentation for any purpose and without fee is hereby granted,
17e014b9acSsklower provided that the above copyright notice appear in all copies and that
18e014b9acSsklower both that copyright notice and this permission notice appear in
19e014b9acSsklower supporting documentation, and that the name of IBM not be
20e014b9acSsklower used in advertising or publicity pertaining to distribution of the
21e014b9acSsklower software without specific, written prior permission.
22e014b9acSsklower
23e014b9acSsklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24e014b9acSsklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25e014b9acSsklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26e014b9acSsklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27e014b9acSsklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28e014b9acSsklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29e014b9acSsklower SOFTWARE.
30e014b9acSsklower
31e014b9acSsklower ******************************************************************/
32e014b9acSsklower
33e014b9acSsklower /*
34e014b9acSsklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
35e014b9acSsklower */
36e014b9acSsklower /*
37e014b9acSsklower * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $
38e014b9acSsklower * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $
39e014b9acSsklower *
40e014b9acSsklower * iso.c: miscellaneous routines to support the iso address family
41e014b9acSsklower */
42e014b9acSsklower
43e1ca26eaSbostic #include <sys/param.h>
44e1ca26eaSbostic #include <sys/systm.h>
45e1ca26eaSbostic #include <sys/ioctl.h>
46e1ca26eaSbostic #include <sys/mbuf.h>
47e1ca26eaSbostic #include <sys/domain.h>
48e1ca26eaSbostic #include <sys/protosw.h>
49e1ca26eaSbostic #include <sys/socket.h>
50e1ca26eaSbostic #include <sys/socketvar.h>
51e1ca26eaSbostic #include <sys/errno.h>
52e014b9acSsklower
53e1ca26eaSbostic #include <net/if.h>
54e1ca26eaSbostic #include <net/route.h>
55e014b9acSsklower
56e1ca26eaSbostic #include <netiso/iso.h>
57e1ca26eaSbostic #include <netiso/iso_var.h>
58e1ca26eaSbostic #include <netiso/iso_snpac.h>
59e1ca26eaSbostic #include <netiso/iso_pcb.h>
60e1ca26eaSbostic #include <netiso/clnp.h>
61e1ca26eaSbostic #include <netiso/argo_debug.h>
6268756140Ssklower #ifdef TUBA
6368756140Ssklower #include <netiso/tuba_table.h>
6468756140Ssklower #endif
65e014b9acSsklower
66e014b9acSsklower #ifdef ISO
67e014b9acSsklower
68e014b9acSsklower int iso_interfaces = 0; /* number of external interfaces */
69e014b9acSsklower extern struct ifnet loif; /* loopback interface */
701dd7e156Ssklower int ether_output();
711dd7e156Ssklower void llc_rtrequest();
72e014b9acSsklower
73e014b9acSsklower /*
74e014b9acSsklower * FUNCTION: iso_addrmatch1
75e014b9acSsklower *
76e014b9acSsklower * PURPOSE: decide if the two iso_addrs passed are equal
77e014b9acSsklower *
78e014b9acSsklower * RETURNS: true if the addrs match, false if they do not
79e014b9acSsklower *
80e014b9acSsklower * SIDE EFFECTS:
81e014b9acSsklower *
82e014b9acSsklower * NOTES:
83e014b9acSsklower */
iso_addrmatch1(isoaa,isoab)84e014b9acSsklower iso_addrmatch1(isoaa, isoab)
850b7547b2Ssklower register struct iso_addr *isoaa, *isoab; /* addresses to check */
86e014b9acSsklower {
870b7547b2Ssklower u_int compare_len;
88e014b9acSsklower
89e014b9acSsklower IFDEBUG(D_ROUTE)
90e014b9acSsklower printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len,
91e014b9acSsklower isoab->isoa_len);
92e014b9acSsklower printf("a:\n");
930b7547b2Ssklower dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len);
94e014b9acSsklower printf("b:\n");
950b7547b2Ssklower dump_buf(isoab->isoa_genaddr, isoab->isoa_len);
96e014b9acSsklower ENDDEBUG
97e014b9acSsklower
98e014b9acSsklower if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) {
99e014b9acSsklower IFDEBUG(D_ROUTE)
100e014b9acSsklower printf("iso_addrmatch1: returning false because of lengths\n");
101e014b9acSsklower ENDDEBUG
102e014b9acSsklower return 0;
103e014b9acSsklower }
104e014b9acSsklower
1050b7547b2Ssklower #ifdef notdef
106e014b9acSsklower /* TODO : generalize this to all afis with masks */
107e014b9acSsklower if( isoaa->isoa_afi == AFI_37 ) {
108e014b9acSsklower /* must not compare 2 least significant digits, or for
109e014b9acSsklower * that matter, the DSP
110e014b9acSsklower */
111e014b9acSsklower compare_len = ADDR37_IDI_LEN - 1;
112e014b9acSsklower }
1130b7547b2Ssklower #endif
114e014b9acSsklower
115e014b9acSsklower IFDEBUG(D_ROUTE)
116e014b9acSsklower int i;
117e014b9acSsklower char *a, *b;
118e014b9acSsklower
1190b7547b2Ssklower a = isoaa->isoa_genaddr;
1200b7547b2Ssklower b = isoab->isoa_genaddr;
121e014b9acSsklower
122e014b9acSsklower for (i=0; i<compare_len; i++) {
123e014b9acSsklower printf("<%x=%x>", a[i]&0xff, b[i]&0xff);
124e014b9acSsklower if (a[i] != b[i]) {
125e014b9acSsklower printf("\naddrs are not equal at byte %d\n", i);
126e014b9acSsklower return(0);
127e014b9acSsklower }
128e014b9acSsklower }
129e014b9acSsklower printf("\n");
130e014b9acSsklower printf("addrs are equal\n");
131e014b9acSsklower return (1);
132e014b9acSsklower ENDDEBUG
1330b7547b2Ssklower return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len));
134e014b9acSsklower }
135e014b9acSsklower
136e014b9acSsklower /*
137e014b9acSsklower * FUNCTION: iso_addrmatch
138e014b9acSsklower *
139e014b9acSsklower * PURPOSE: decide if the two sockadrr_isos passed are equal
140e014b9acSsklower *
141e014b9acSsklower * RETURNS: true if the addrs match, false if they do not
142e014b9acSsklower *
143e014b9acSsklower * SIDE EFFECTS:
144e014b9acSsklower *
145e014b9acSsklower * NOTES:
146e014b9acSsklower */
147e014b9acSsklower iso_addrmatch(sisoa, sisob)
148e014b9acSsklower struct sockaddr_iso *sisoa, *sisob; /* addresses to check */
149e014b9acSsklower {
150e014b9acSsklower return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr));
151e014b9acSsklower }
1520b7547b2Ssklower #ifdef notdef
153e014b9acSsklower /*
154e014b9acSsklower * FUNCTION: iso_netmatch
155e014b9acSsklower *
156e014b9acSsklower * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso
157e014b9acSsklower * as argument.
158e014b9acSsklower *
159e014b9acSsklower * RETURNS: true if same net, false if not
160e014b9acSsklower *
161e014b9acSsklower * SIDE EFFECTS:
162e014b9acSsklower *
163e014b9acSsklower * NOTES:
164e014b9acSsklower */
165e014b9acSsklower iso_netmatch(sisoa, sisob)
166e014b9acSsklower struct sockaddr_iso *sisoa, *sisob;
167e014b9acSsklower {
168e014b9acSsklower u_char bufa[sizeof(struct sockaddr_iso)];
169e014b9acSsklower u_char bufb[sizeof(struct sockaddr_iso)];
170e014b9acSsklower register int lena, lenb;
171e014b9acSsklower
172e014b9acSsklower lena = iso_netof(&sisoa->siso_addr, bufa);
173e014b9acSsklower lenb = iso_netof(&sisob->siso_addr, bufb);
174e014b9acSsklower
175e014b9acSsklower IFDEBUG(D_ROUTE)
176e014b9acSsklower printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb);
177e014b9acSsklower printf("a:\n");
178e014b9acSsklower dump_buf(bufa, lena);
179e014b9acSsklower printf("b:\n");
180e014b9acSsklower dump_buf(bufb, lenb);
181e014b9acSsklower ENDDEBUG
182e014b9acSsklower
183e014b9acSsklower return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
184e014b9acSsklower }
1855cbc22e2Sbostic #endif /* notdef */
186e014b9acSsklower
187e014b9acSsklower /*
188e014b9acSsklower * FUNCTION: iso_hashchar
189e014b9acSsklower *
190e014b9acSsklower * PURPOSE: Hash all character in the buffer specified into
191e014b9acSsklower * a long. Return the long.
192e014b9acSsklower *
193e014b9acSsklower * RETURNS: The hash value.
194e014b9acSsklower *
195e014b9acSsklower * SIDE EFFECTS:
196e014b9acSsklower *
197e014b9acSsklower * NOTES: The hash is achieved by exclusive ORing 4 byte
198e014b9acSsklower * quantities.
199e014b9acSsklower */
200e014b9acSsklower u_long
iso_hashchar(buf,len)201e014b9acSsklower iso_hashchar(buf, len)
202e014b9acSsklower register caddr_t buf; /* buffer to pack from */
203e014b9acSsklower register int len; /* length of buffer */
204e014b9acSsklower {
205e014b9acSsklower register u_long h = 0;
206e014b9acSsklower register int i;
207e014b9acSsklower
208e014b9acSsklower for (i=0; i<len; i+=4) {
209e014b9acSsklower register u_long l = 0;
210e014b9acSsklower
211e014b9acSsklower if ((len - i) < 4) {
212e014b9acSsklower /* buffer not multiple of 4 */
213e014b9acSsklower switch (len - i) {
214e014b9acSsklower case 3:
215e014b9acSsklower l |= buf[i+2] << 8;
216e014b9acSsklower case 2:
217e014b9acSsklower l |= buf[i+1] << 16;
218e014b9acSsklower case 1:
219e014b9acSsklower l |= buf[i] << 24;
220e014b9acSsklower break;
221e014b9acSsklower default:
222e014b9acSsklower printf("iso_hashchar: unexpected value x%x\n", len - i);
223e014b9acSsklower break;
224e014b9acSsklower }
225e014b9acSsklower } else {
226e014b9acSsklower l |= buf[i] << 24;
227e014b9acSsklower l |= buf[i+1] << 16;
228e014b9acSsklower l |= buf[i+2] << 8;
229e014b9acSsklower l |= buf[i+3];
230e014b9acSsklower }
231e014b9acSsklower
232e014b9acSsklower h ^= l;
233e014b9acSsklower }
234e014b9acSsklower
235e014b9acSsklower h ^= (u_long) (len % 4);
236e014b9acSsklower
237e014b9acSsklower return(h);
238e014b9acSsklower }
2390b7547b2Ssklower #ifdef notdef
240e014b9acSsklower /*
241e014b9acSsklower * FUNCTION: iso_hash
242e014b9acSsklower *
243e014b9acSsklower * PURPOSE: Fill in fields of afhash structure based upon addr passed.
244e014b9acSsklower *
245e014b9acSsklower * RETURNS: none
246e014b9acSsklower *
247e014b9acSsklower * SIDE EFFECTS:
248e014b9acSsklower *
249e014b9acSsklower * NOTES:
250e014b9acSsklower */
251e014b9acSsklower iso_hash(siso, hp)
252e014b9acSsklower struct sockaddr_iso *siso; /* address to perform hash on */
253e014b9acSsklower struct afhash *hp; /* RETURN: hash info here */
254e014b9acSsklower {
255e014b9acSsklower u_long buf[sizeof(struct sockaddr_iso)+1/4];
256e014b9acSsklower register int bufsize;
257e014b9acSsklower
258e014b9acSsklower
259e014b9acSsklower bzero(buf, sizeof(buf));
260e014b9acSsklower
261e014b9acSsklower bufsize = iso_netof(&siso->siso_addr, buf);
262e014b9acSsklower hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
263e014b9acSsklower
264e014b9acSsklower IFDEBUG(D_ROUTE)
265e014b9acSsklower printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
266e014b9acSsklower ENDDEBUG
267e014b9acSsklower
268e014b9acSsklower hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
269e014b9acSsklower siso->siso_addr.isoa_len);
270e014b9acSsklower
271e014b9acSsklower IFDEBUG(D_ROUTE)
272e014b9acSsklower printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
273e014b9acSsklower clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
274e014b9acSsklower hp->afh_hosthash);
275e014b9acSsklower ENDDEBUG
276e014b9acSsklower }
277e014b9acSsklower /*
278e014b9acSsklower * FUNCTION: iso_netof
279e014b9acSsklower *
280e014b9acSsklower * PURPOSE: Extract the network portion of the iso address.
281e014b9acSsklower * The network portion of the iso address varies depending
282e014b9acSsklower * on the type of address. The network portion of the
283e014b9acSsklower * address will include the IDP. The network portion is:
284e014b9acSsklower *
285e014b9acSsklower * TYPE DESC
286e014b9acSsklower * t37 The AFI and x.121 (IDI)
287e014b9acSsklower * osinet The AFI, orgid, snetid
288e014b9acSsklower * rfc986 The AFI, vers and network part of
289e014b9acSsklower * internet address.
290e014b9acSsklower *
291e014b9acSsklower * RETURNS: number of bytes placed into buf.
292e014b9acSsklower *
293e014b9acSsklower * SIDE EFFECTS:
294e014b9acSsklower *
295e014b9acSsklower * NOTES: Buf is assumed to be big enough
296e014b9acSsklower */
297e014b9acSsklower iso_netof(isoa, buf)
298e014b9acSsklower struct iso_addr *isoa; /* address */
299e014b9acSsklower caddr_t buf; /* RESULT: network portion of address here */
300e014b9acSsklower {
301e014b9acSsklower u_int len = 1; /* length of afi */
302e014b9acSsklower
303e014b9acSsklower switch (isoa->isoa_afi) {
304e014b9acSsklower case AFI_37:
305e014b9acSsklower /*
306e014b9acSsklower * Due to classic x.25 tunnel vision, there is no
307e014b9acSsklower * net portion of an x.121 address. For our purposes
308e014b9acSsklower * the AFI will do, so that all x.25 -type addresses
309e014b9acSsklower * map to the single x.25 SNPA. (Cannot have more than
310e014b9acSsklower * one, obviously).
311e014b9acSsklower */
312e014b9acSsklower
313e014b9acSsklower break;
314e014b9acSsklower
315e014b9acSsklower /* case AFI_OSINET:*/
316e014b9acSsklower case AFI_RFC986: {
317e014b9acSsklower u_short idi; /* value of idi */
318e014b9acSsklower
319e014b9acSsklower /* osinet and rfc986 have idi in the same place */
320e014b9acSsklower CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
321e014b9acSsklower
322e014b9acSsklower if (idi == IDI_OSINET)
323e014b9acSsklower /*
324e014b9acSsklower * Network portion of OSINET address can only be the IDI. Clearly,
325e014b9acSsklower * with one x25 interface, one could get to several orgids, and
326e014b9acSsklower * several snetids.
327e014b9acSsklower len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
328e014b9acSsklower OVLOSINET_SNETID_LEN);
329e014b9acSsklower */
330e014b9acSsklower len += ADDROSINET_IDI_LEN;
331e014b9acSsklower else if (idi == IDI_RFC986) {
332e014b9acSsklower u_long inetaddr;
333e014b9acSsklower struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa;
334e014b9acSsklower
335e014b9acSsklower /* bump len to include idi and version (1 byte) */
336e014b9acSsklower len += ADDRRFC986_IDI_LEN + 1;
337e014b9acSsklower
338e014b9acSsklower /* get inet addr long aligned */
339e014b9acSsklower bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
340e014b9acSsklower inetaddr = ntohl(inetaddr); /* convert to host byte order */
341e014b9acSsklower
342e014b9acSsklower IFDEBUG(D_ROUTE)
343e014b9acSsklower printf("iso_netof: isoa ");
344e014b9acSsklower dump_buf(isoa, sizeof(*isoa));
345e014b9acSsklower printf("iso_netof: inetaddr 0x%x ", inetaddr);
346e014b9acSsklower ENDDEBUG
347e014b9acSsklower
348e014b9acSsklower /* bump len by size of network portion of inet address */
349e014b9acSsklower if (IN_CLASSA(inetaddr)) {
350e014b9acSsklower len += 4-IN_CLASSA_NSHIFT/8;
351e014b9acSsklower IFDEBUG(D_ROUTE)
352e014b9acSsklower printf("iso_netof: class A net len is now %d\n", len);
353e014b9acSsklower ENDDEBUG
354e014b9acSsklower } else if (IN_CLASSB(inetaddr)) {
355e014b9acSsklower len += 4-IN_CLASSB_NSHIFT/8;
356e014b9acSsklower IFDEBUG(D_ROUTE)
357e014b9acSsklower printf("iso_netof: class B net len is now %d\n", len);
358e014b9acSsklower ENDDEBUG
359e014b9acSsklower } else {
360e014b9acSsklower len += 4-IN_CLASSC_NSHIFT/8;
361e014b9acSsklower IFDEBUG(D_ROUTE)
362e014b9acSsklower printf("iso_netof: class C net len is now %d\n", len);
363e014b9acSsklower ENDDEBUG
364e014b9acSsklower }
365e014b9acSsklower } else
366e014b9acSsklower len = 0;
367e014b9acSsklower } break;
368e014b9acSsklower
369e014b9acSsklower default:
370e014b9acSsklower len = 0;
371e014b9acSsklower }
372e014b9acSsklower
373e014b9acSsklower bcopy((caddr_t)isoa, buf, len);
374e014b9acSsklower IFDEBUG(D_ROUTE)
37553524399Ssklower printf("iso_netof: isoa ");
376e014b9acSsklower dump_buf(isoa, len);
37753524399Ssklower printf("iso_netof: net ");
378e014b9acSsklower dump_buf(buf, len);
379e014b9acSsklower ENDDEBUG
380e014b9acSsklower return len;
381e014b9acSsklower }
3825cbc22e2Sbostic #endif /* notdef */
383e014b9acSsklower /*
3840b7547b2Ssklower * Generic iso control operations (ioctl's).
3850b7547b2Ssklower * Ifp is 0 if not an interface-specific ioctl.
386e014b9acSsklower */
3870b7547b2Ssklower /* ARGSUSED */
388e014b9acSsklower iso_control(so, cmd, data, ifp)
3890b7547b2Ssklower struct socket *so;
390*7fa9e8f7Scgd u_long cmd;
3910b7547b2Ssklower caddr_t data;
3920b7547b2Ssklower register struct ifnet *ifp;
393e014b9acSsklower {
3940b7547b2Ssklower register struct iso_ifreq *ifr = (struct iso_ifreq *)data;
395e014b9acSsklower register struct iso_ifaddr *ia = 0;
3960b7547b2Ssklower register struct ifaddr *ifa;
3970b7547b2Ssklower struct iso_ifaddr *oia;
3980b7547b2Ssklower struct iso_aliasreq *ifra = (struct iso_aliasreq *)data;
3990b7547b2Ssklower int error, hostIsNew, maskIsNew;
400e014b9acSsklower
4010b7547b2Ssklower /*
4020b7547b2Ssklower * Find address for this interface, if it exists.
4030b7547b2Ssklower */
4040b7547b2Ssklower if (ifp)
4050b7547b2Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next)
4060b7547b2Ssklower if (ia->ia_ifp == ifp)
4070b7547b2Ssklower break;
408e014b9acSsklower
409e014b9acSsklower switch (cmd) {
4100b7547b2Ssklower
4110b7547b2Ssklower case SIOCAIFADDR_ISO:
4120b7547b2Ssklower case SIOCDIFADDR_ISO:
4130b7547b2Ssklower if (ifra->ifra_addr.siso_family == AF_ISO)
4140b7547b2Ssklower for (oia = ia; ia; ia = ia->ia_next) {
4150b7547b2Ssklower if (ia->ia_ifp == ifp &&
4160b7547b2Ssklower SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
4170b7547b2Ssklower break;
4180b7547b2Ssklower }
41934dd6a78Ssklower if ((so->so_state & SS_PRIV) == 0)
42034dd6a78Ssklower return (EPERM);
421e014b9acSsklower if (ifp == 0)
4220b7547b2Ssklower panic("iso_control");
4230b7547b2Ssklower if (ia == (struct iso_ifaddr *)0) {
4240b7547b2Ssklower struct iso_ifaddr *nia;
4250b7547b2Ssklower if (cmd == SIOCDIFADDR_ISO)
426e014b9acSsklower return (EADDRNOTAVAIL);
42768756140Ssklower #ifdef TUBA
42868756140Ssklower /* XXXXXX can't be done in the proto init routines */
42968756140Ssklower if (tuba_tree == 0)
43068756140Ssklower tuba_table_init();
43168756140Ssklower #endif
4320b7547b2Ssklower MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
4330b7547b2Ssklower M_IFADDR, M_WAITOK);
4340b7547b2Ssklower if (nia == (struct iso_ifaddr *)0)
435e014b9acSsklower return (ENOBUFS);
4360b7547b2Ssklower bzero((caddr_t)nia, sizeof(*nia));
437e014b9acSsklower if (ia = iso_ifaddr) {
438e014b9acSsklower for ( ; ia->ia_next; ia = ia->ia_next)
439e014b9acSsklower ;
4400b7547b2Ssklower ia->ia_next = nia;
441e014b9acSsklower } else
4420b7547b2Ssklower iso_ifaddr = nia;
4430b7547b2Ssklower ia = nia;
444e014b9acSsklower if (ifa = ifp->if_addrlist) {
445e014b9acSsklower for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
446e014b9acSsklower ;
447e014b9acSsklower ifa->ifa_next = (struct ifaddr *) ia;
448e014b9acSsklower } else
449e014b9acSsklower ifp->if_addrlist = (struct ifaddr *) ia;
4500b7547b2Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
4510b7547b2Ssklower ia->ia_ifa.ifa_dstaddr
4520b7547b2Ssklower = (struct sockaddr *)&ia->ia_dstaddr;
4530b7547b2Ssklower ia->ia_ifa.ifa_netmask
4540b7547b2Ssklower = (struct sockaddr *)&ia->ia_sockmask;
455e014b9acSsklower ia->ia_ifp = ifp;
456e014b9acSsklower if (ifp != &loif)
457e014b9acSsklower iso_interfaces++;
4580b7547b2Ssklower }
4590b7547b2Ssklower break;
460e014b9acSsklower
4610b7547b2Ssklower #define cmdbyte(x) (((x) >> 8) & 0xff)
4620b7547b2Ssklower default:
4630b7547b2Ssklower if (cmdbyte(cmd) == 'a')
46434dd6a78Ssklower return (snpac_ioctl(so, cmd, data));
4650b7547b2Ssklower if (ia == (struct iso_ifaddr *)0)
466e014b9acSsklower return (EADDRNOTAVAIL);
4670b7547b2Ssklower break;
4680b7547b2Ssklower }
4690b7547b2Ssklower switch (cmd) {
470e014b9acSsklower
4710b7547b2Ssklower case SIOCGIFADDR_ISO:
4720b7547b2Ssklower ifr->ifr_Addr = ia->ia_addr;
4730b7547b2Ssklower break;
474e014b9acSsklower
4750b7547b2Ssklower case SIOCGIFDSTADDR_ISO:
4760b7547b2Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
4770b7547b2Ssklower return (EINVAL);
4780b7547b2Ssklower ifr->ifr_Addr = ia->ia_dstaddr;
4790b7547b2Ssklower break;
480e014b9acSsklower
4810b7547b2Ssklower case SIOCGIFNETMASK_ISO:
4820b7547b2Ssklower ifr->ifr_Addr = ia->ia_sockmask;
4830b7547b2Ssklower break;
4840b7547b2Ssklower
4850b7547b2Ssklower case SIOCAIFADDR_ISO:
48644e1ed6cSsklower maskIsNew = 0; hostIsNew = 1; error = 0;
4870b7547b2Ssklower if (ia->ia_addr.siso_family == AF_ISO) {
4880b7547b2Ssklower if (ifra->ifra_addr.siso_len == 0) {
4890b7547b2Ssklower ifra->ifra_addr = ia->ia_addr;
4900b7547b2Ssklower hostIsNew = 0;
4910b7547b2Ssklower } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))
4920b7547b2Ssklower hostIsNew = 0;
4930b7547b2Ssklower }
4940b7547b2Ssklower if (ifra->ifra_mask.siso_len) {
4950b7547b2Ssklower iso_ifscrub(ifp, ia);
4960b7547b2Ssklower ia->ia_sockmask = ifra->ifra_mask;
4970b7547b2Ssklower maskIsNew = 1;
4980b7547b2Ssklower }
4990b7547b2Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) &&
5000b7547b2Ssklower (ifra->ifra_dstaddr.siso_family == AF_ISO)) {
5010b7547b2Ssklower iso_ifscrub(ifp, ia);
5020b7547b2Ssklower ia->ia_dstaddr = ifra->ifra_dstaddr;
5030b7547b2Ssklower maskIsNew = 1; /* We lie; but the effect's the same */
5040b7547b2Ssklower }
5050b7547b2Ssklower if (ifra->ifra_addr.siso_family == AF_ISO &&
5060b7547b2Ssklower (hostIsNew || maskIsNew)) {
5070b7547b2Ssklower error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);
5080b7547b2Ssklower }
5090b7547b2Ssklower if (ifra->ifra_snpaoffset)
5100b7547b2Ssklower ia->ia_snpaoffset = ifra->ifra_snpaoffset;
5110b7547b2Ssklower return (error);
5120b7547b2Ssklower
5130b7547b2Ssklower case SIOCDIFADDR_ISO:
5140b7547b2Ssklower iso_ifscrub(ifp, ia);
5150b7547b2Ssklower if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
5160b7547b2Ssklower ifp->if_addrlist = ifa->ifa_next;
5170b7547b2Ssklower else {
5180b7547b2Ssklower while (ifa->ifa_next &&
5190b7547b2Ssklower (ifa->ifa_next != (struct ifaddr *)ia))
5200b7547b2Ssklower ifa = ifa->ifa_next;
5210b7547b2Ssklower if (ifa->ifa_next)
5220b7547b2Ssklower ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
5230b7547b2Ssklower else
5240b7547b2Ssklower printf("Couldn't unlink isoifaddr from ifp\n");
5250b7547b2Ssklower }
5260b7547b2Ssklower oia = ia;
5270b7547b2Ssklower if (oia == (ia = iso_ifaddr)) {
5280b7547b2Ssklower iso_ifaddr = ia->ia_next;
5290b7547b2Ssklower } else {
5300b7547b2Ssklower while (ia->ia_next && (ia->ia_next != oia)) {
5310b7547b2Ssklower ia = ia->ia_next;
5320b7547b2Ssklower }
5330b7547b2Ssklower if (ia->ia_next)
5340b7547b2Ssklower ia->ia_next = oia->ia_next;
5350b7547b2Ssklower else
5360b7547b2Ssklower printf("Didn't unlink isoifadr from list\n");
5370b7547b2Ssklower }
53841634bf6Ssklower IFAFREE((&oia->ia_ifa));
5390b7547b2Ssklower break;
540e014b9acSsklower
541e014b9acSsklower default:
542e014b9acSsklower if (ifp == 0 || ifp->if_ioctl == 0)
543e014b9acSsklower return (EOPNOTSUPP);
544e014b9acSsklower return ((*ifp->if_ioctl)(ifp, cmd, data));
545e014b9acSsklower }
5460b7547b2Ssklower return (0);
547e014b9acSsklower }
548e014b9acSsklower
5490b7547b2Ssklower /*
5500b7547b2Ssklower * Delete any existing route for an interface.
5510b7547b2Ssklower */
iso_ifscrub(ifp,ia)5520b7547b2Ssklower iso_ifscrub(ifp, ia)
5530b7547b2Ssklower register struct ifnet *ifp;
5540b7547b2Ssklower register struct iso_ifaddr *ia;
5550b7547b2Ssklower {
5564f8f8de6Ssklower int nsellength = ia->ia_addr.siso_tlen;
5570b7547b2Ssklower if ((ia->ia_flags & IFA_ROUTE) == 0)
5580b7547b2Ssklower return;
5594f8f8de6Ssklower ia->ia_addr.siso_tlen = 0;
5600b7547b2Ssklower if (ifp->if_flags & IFF_LOOPBACK)
5610b7547b2Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
5620b7547b2Ssklower else if (ifp->if_flags & IFF_POINTOPOINT)
5630b7547b2Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
5640b7547b2Ssklower else {
5650b7547b2Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
5660b7547b2Ssklower }
5674f8f8de6Ssklower ia->ia_addr.siso_tlen = nsellength;
5680b7547b2Ssklower ia->ia_flags &= ~IFA_ROUTE;
5690b7547b2Ssklower }
5700b7547b2Ssklower
5710b7547b2Ssklower /*
5720b7547b2Ssklower * Initialize an interface's internet address
5730b7547b2Ssklower * and routing table entry.
5740b7547b2Ssklower */
iso_ifinit(ifp,ia,siso,scrub)5750b7547b2Ssklower iso_ifinit(ifp, ia, siso, scrub)
5760b7547b2Ssklower register struct ifnet *ifp;
5770b7547b2Ssklower register struct iso_ifaddr *ia;
5780b7547b2Ssklower struct sockaddr_iso *siso;
5790b7547b2Ssklower {
5800b7547b2Ssklower struct sockaddr_iso oldaddr;
5814f8f8de6Ssklower int s = splimp(), error, nsellength;
5820b7547b2Ssklower
5830b7547b2Ssklower oldaddr = ia->ia_addr;
5840b7547b2Ssklower ia->ia_addr = *siso;
5850b7547b2Ssklower /*
5860b7547b2Ssklower * Give the interface a chance to initialize
5870b7547b2Ssklower * if this is its first address,
5880b7547b2Ssklower * and to validate the address if necessary.
5890b7547b2Ssklower */
5901dd7e156Ssklower if (ifp->if_ioctl &&
5911dd7e156Ssklower (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
5920b7547b2Ssklower splx(s);
5930b7547b2Ssklower ia->ia_addr = oldaddr;
5940b7547b2Ssklower return (error);
5950b7547b2Ssklower }
5960b7547b2Ssklower if (scrub) {
5970b7547b2Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
5980b7547b2Ssklower iso_ifscrub(ifp, ia);
5990b7547b2Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
6000b7547b2Ssklower }
6014f8f8de6Ssklower /* XXX -- The following is here temporarily out of laziness
6024f8f8de6Ssklower in not changing every ethernet driver's if_ioctl routine */
6034f8f8de6Ssklower if (ifp->if_output == ether_output) {
6044f8f8de6Ssklower ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
6054f8f8de6Ssklower ia->ia_ifa.ifa_flags |= RTF_CLONING;
6064f8f8de6Ssklower }
6070b7547b2Ssklower /*
6080b7547b2Ssklower * Add route for the network.
6090b7547b2Ssklower */
6104f8f8de6Ssklower nsellength = ia->ia_addr.siso_tlen;
6114f8f8de6Ssklower ia->ia_addr.siso_tlen = 0;
6120b7547b2Ssklower if (ifp->if_flags & IFF_LOOPBACK) {
6130b7547b2Ssklower ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
61450feba3cSsklower error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
6150b7547b2Ssklower } else if (ifp->if_flags & IFF_POINTOPOINT &&
6160b7547b2Ssklower ia->ia_dstaddr.siso_family == AF_ISO)
61750feba3cSsklower error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
6180b7547b2Ssklower else {
61950feba3cSsklower rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,
62050feba3cSsklower ia->ia_ifa.ifa_netmask);
621f2b38841Ssklower ia->ia_dstaddr.siso_nlen =
622f2b38841Ssklower min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));
62350feba3cSsklower error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
6240b7547b2Ssklower }
6254f8f8de6Ssklower ia->ia_addr.siso_tlen = nsellength;
6260b7547b2Ssklower ia->ia_flags |= IFA_ROUTE;
6270b7547b2Ssklower splx(s);
62850feba3cSsklower return (error);
6290b7547b2Ssklower }
6300b7547b2Ssklower #ifdef notdef
6310b7547b2Ssklower
632e014b9acSsklower struct ifaddr *
iso_ifwithidi(addr)633e014b9acSsklower iso_ifwithidi(addr)
634e014b9acSsklower register struct sockaddr *addr;
635e014b9acSsklower {
636e014b9acSsklower register struct ifnet *ifp;
637e014b9acSsklower register struct ifaddr *ifa;
638e014b9acSsklower register u_int af = addr->sa_family;
639e014b9acSsklower
640e014b9acSsklower if (af != AF_ISO)
641e014b9acSsklower return (0);
642e014b9acSsklower IFDEBUG(D_ROUTE)
643e014b9acSsklower printf(">>> iso_ifwithidi addr\n");
644e014b9acSsklower dump_isoaddr( (struct sockaddr_iso *)(addr));
645e014b9acSsklower printf("\n");
646e014b9acSsklower ENDDEBUG
647e014b9acSsklower for (ifp = ifnet; ifp; ifp = ifp->if_next) {
648e014b9acSsklower IFDEBUG(D_ROUTE)
649e014b9acSsklower printf("iso_ifwithidi ifnet %s\n", ifp->if_name);
650e014b9acSsklower ENDDEBUG
651e014b9acSsklower for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
652e014b9acSsklower IFDEBUG(D_ROUTE)
653e014b9acSsklower printf("iso_ifwithidi address ");
6540b7547b2Ssklower dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));
655e014b9acSsklower ENDDEBUG
6560b7547b2Ssklower if (ifa->ifa_addr->sa_family != addr->sa_family)
657e014b9acSsklower continue;
658e014b9acSsklower
659e014b9acSsklower #define IFA_SIS(ifa)\
6600b7547b2Ssklower ((struct sockaddr_iso *)((ifa)->ifa_addr))
661e014b9acSsklower
662e014b9acSsklower IFDEBUG(D_ROUTE)
663e014b9acSsklower printf(" af same, args to iso_eqtype:\n");
664e014b9acSsklower printf("0x%x ", IFA_SIS(ifa)->siso_addr);
665e014b9acSsklower printf(" 0x%x\n",
666e014b9acSsklower &(((struct sockaddr_iso *)addr)->siso_addr));
667e014b9acSsklower ENDDEBUG
668e014b9acSsklower
669e014b9acSsklower if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr),
670e014b9acSsklower &(((struct sockaddr_iso *)addr)->siso_addr))) {
671e014b9acSsklower IFDEBUG(D_ROUTE)
672e014b9acSsklower printf("ifa_ifwithidi: ifa found\n");
673e014b9acSsklower ENDDEBUG
674e014b9acSsklower return (ifa);
675e014b9acSsklower }
676e014b9acSsklower IFDEBUG(D_ROUTE)
677e014b9acSsklower printf(" iso_eqtype failed\n");
678e014b9acSsklower ENDDEBUG
679e014b9acSsklower }
680e014b9acSsklower }
681e014b9acSsklower return ((struct ifaddr *)0);
682e014b9acSsklower }
683e014b9acSsklower
6845cbc22e2Sbostic #endif /* notdef */
685e014b9acSsklower /*
686e014b9acSsklower * FUNCTION: iso_ck_addr
687e014b9acSsklower *
688e014b9acSsklower * PURPOSE: return true if the iso_addr passed is
689e014b9acSsklower * within the legal size limit for an iso address.
690e014b9acSsklower *
691e014b9acSsklower * RETURNS: true or false
692e014b9acSsklower *
693e014b9acSsklower * SIDE EFFECTS:
694e014b9acSsklower *
695e014b9acSsklower */
696e014b9acSsklower iso_ck_addr(isoa)
697e014b9acSsklower struct iso_addr *isoa; /* address to check */
698e014b9acSsklower {
699e014b9acSsklower return (isoa->isoa_len <= 20);
700e014b9acSsklower
701e014b9acSsklower }
702e014b9acSsklower
7030b7547b2Ssklower #ifdef notdef
704e014b9acSsklower /*
705e014b9acSsklower * FUNCTION: iso_eqtype
706e014b9acSsklower *
707e014b9acSsklower * PURPOSE: Determine if two iso addresses are of the same type.
708e014b9acSsklower * This is flaky. Really we should consider all type 47 addrs to be the
709e014b9acSsklower * same - but there do exist different structures for 47 addrs.
710e014b9acSsklower * Gosip adds a 3rd.
711e014b9acSsklower *
712e014b9acSsklower * RETURNS: true if the addresses are the same type
713e014b9acSsklower *
714e014b9acSsklower * SIDE EFFECTS:
715e014b9acSsklower *
716e014b9acSsklower * NOTES: By type, I mean rfc986, t37, or osinet
717e014b9acSsklower *
718e014b9acSsklower * This will first compare afis. If they match, then
719e014b9acSsklower * if the addr is not t37, the idis must be compared.
720e014b9acSsklower */
721e014b9acSsklower iso_eqtype(isoaa, isoab)
722e014b9acSsklower struct iso_addr *isoaa; /* first addr to check */
723e014b9acSsklower struct iso_addr *isoab; /* other addr to check */
724e014b9acSsklower {
725e014b9acSsklower if (isoaa->isoa_afi == isoab->isoa_afi) {
726e014b9acSsklower if (isoaa->isoa_afi == AFI_37)
727e014b9acSsklower return(1);
728e014b9acSsklower else
729e014b9acSsklower return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));
730e014b9acSsklower }
731e014b9acSsklower return(0);
732e014b9acSsklower }
7335cbc22e2Sbostic #endif /* notdef */
734e014b9acSsklower /*
7350b7547b2Ssklower * FUNCTION: iso_localifa()
736e014b9acSsklower *
7370b7547b2Ssklower * PURPOSE: Find an interface addresss having a given destination
7380b7547b2Ssklower * or at least matching the net.
739e014b9acSsklower *
740e014b9acSsklower * RETURNS: ptr to an interface address
741e014b9acSsklower *
742e014b9acSsklower * SIDE EFFECTS:
743e014b9acSsklower *
744e014b9acSsklower * NOTES:
745e014b9acSsklower */
746e014b9acSsklower struct iso_ifaddr *
iso_localifa(siso)7470b7547b2Ssklower iso_localifa(siso)
7480b7547b2Ssklower register struct sockaddr_iso *siso;
749e014b9acSsklower {
750e014b9acSsklower register struct iso_ifaddr *ia;
7510b7547b2Ssklower register char *cp1, *cp2, *cp3;
7520b7547b2Ssklower register struct ifnet *ifp;
7530b7547b2Ssklower struct iso_ifaddr *ia_maybe = 0;
7540b7547b2Ssklower /*
7550b7547b2Ssklower * We make one pass looking for both net matches and an exact
7560b7547b2Ssklower * dst addr.
7570b7547b2Ssklower */
7580b7547b2Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
7590b7547b2Ssklower if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))
7600b7547b2Ssklower continue;
7610b7547b2Ssklower if (ifp->if_flags & IFF_POINTOPOINT) {
7620b7547b2Ssklower if ((ia->ia_dstaddr.siso_family == AF_ISO) &&
7630b7547b2Ssklower SAME_ISOADDR(&ia->ia_dstaddr, siso))
764e014b9acSsklower return (ia);
7650b7547b2Ssklower else
7660b7547b2Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso))
7670b7547b2Ssklower ia_maybe = ia;
7680b7547b2Ssklower continue;
7690b7547b2Ssklower }
7700b7547b2Ssklower if (ia->ia_sockmask.siso_len) {
7710b7547b2Ssklower char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;
7720b7547b2Ssklower cp1 = ia->ia_sockmask.siso_data;
7730b7547b2Ssklower cp2 = siso->siso_data;
7740b7547b2Ssklower cp3 = ia->ia_addr.siso_data;
775d65650a8Ssklower while (cp1 < cplim)
7760b7547b2Ssklower if (*cp1++ & (*cp2++ ^ *cp3++))
7770b7547b2Ssklower goto next;
7780b7547b2Ssklower ia_maybe = ia;
7790b7547b2Ssklower }
7800b7547b2Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso))
7810b7547b2Ssklower return ia;
7820b7547b2Ssklower next:;
7830b7547b2Ssklower }
7840b7547b2Ssklower return ia_maybe;
785e014b9acSsklower }
786e014b9acSsklower
7877e563708Ssklower #ifdef TPCONS
788e1ca26eaSbostic #include <netiso/cons.h>
7895cbc22e2Sbostic #endif /* TPCONS */
790e014b9acSsklower /*
791e014b9acSsklower * FUNCTION: iso_nlctloutput
792e014b9acSsklower *
793e014b9acSsklower * PURPOSE: Set options at the network level
794e014b9acSsklower *
795e014b9acSsklower * RETURNS: E*
796e014b9acSsklower *
797e014b9acSsklower * SIDE EFFECTS:
798e014b9acSsklower *
799e014b9acSsklower * NOTES: This could embody some of the functions of
800e014b9acSsklower * rclnp_ctloutput and cons_ctloutput.
801e014b9acSsklower */
iso_nlctloutput(cmd,optname,pcb,m)802e014b9acSsklower iso_nlctloutput(cmd, optname, pcb, m)
803e014b9acSsklower int cmd; /* command:set or get */
804e014b9acSsklower int optname; /* option of interest */
805e014b9acSsklower caddr_t pcb; /* nl pcb */
806e014b9acSsklower struct mbuf *m; /* data for set, buffer for get */
807e014b9acSsklower {
808e014b9acSsklower struct isopcb *isop = (struct isopcb *)pcb;
809e014b9acSsklower int error = 0; /* return value */
810e014b9acSsklower caddr_t data; /* data for option */
811e014b9acSsklower int data_len; /* data's length */
812e014b9acSsklower
813e014b9acSsklower IFDEBUG(D_ISO)
814e014b9acSsklower printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",
815e014b9acSsklower cmd, optname, pcb, m);
816e014b9acSsklower ENDDEBUG
817e014b9acSsklower
818e014b9acSsklower if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))
819e014b9acSsklower return(EOPNOTSUPP);
820e014b9acSsklower
821e014b9acSsklower data = mtod(m, caddr_t);
822e014b9acSsklower data_len = (m)->m_len;
823e014b9acSsklower
824e014b9acSsklower IFDEBUG(D_ISO)
825e014b9acSsklower printf("iso_nlctloutput: data is:\n");
826e014b9acSsklower dump_buf(data, data_len);
827e014b9acSsklower ENDDEBUG
828e014b9acSsklower
829e014b9acSsklower switch (optname) {
830e014b9acSsklower
8317e563708Ssklower #ifdef TPCONS
832e014b9acSsklower case CONSOPT_X25CRUD:
833e014b9acSsklower if (cmd == PRCO_GETOPT) {
834e014b9acSsklower error = EOPNOTSUPP;
835e014b9acSsklower break;
836e014b9acSsklower }
837e014b9acSsklower
838e014b9acSsklower if (data_len > MAXX25CRUDLEN) {
839e014b9acSsklower error = EINVAL;
840e014b9acSsklower break;
841e014b9acSsklower }
842e014b9acSsklower
843e014b9acSsklower IFDEBUG(D_ISO)
844e014b9acSsklower printf("iso_nlctloutput: setting x25 crud\n");
845e014b9acSsklower ENDDEBUG
846e014b9acSsklower
8470b7547b2Ssklower bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
848e014b9acSsklower isop->isop_x25crud_len = data_len;
849e014b9acSsklower break;
8505cbc22e2Sbostic #endif /* TPCONS */
851e014b9acSsklower
852e014b9acSsklower default:
853e014b9acSsklower error = EOPNOTSUPP;
854e014b9acSsklower }
855eaae3387Ssklower if (cmd == PRCO_SETOPT)
856eaae3387Ssklower m_freem(m);
857e014b9acSsklower return error;
858e014b9acSsklower }
8595cbc22e2Sbostic #endif /* ISO */
860e014b9acSsklower
861e014b9acSsklower #ifdef ARGO_DEBUG
862e014b9acSsklower
863e014b9acSsklower /*
864e014b9acSsklower * FUNCTION: dump_isoaddr
865e014b9acSsklower *
866e014b9acSsklower * PURPOSE: debugging
867e014b9acSsklower *
868e014b9acSsklower * RETURNS: nada
869e014b9acSsklower *
870e014b9acSsklower */
871e014b9acSsklower dump_isoaddr(s)
872e014b9acSsklower struct sockaddr_iso *s;
873e014b9acSsklower {
8740b7547b2Ssklower char *clnp_saddr_isop();
875e014b9acSsklower register int i;
876e014b9acSsklower
877e014b9acSsklower if( s->siso_family == AF_ISO) {
8780b7547b2Ssklower printf("ISO address: suffixlen %d, %s\n",
8790b3e9d7fSsklower s->siso_tlen, clnp_saddr_isop(s));
880e014b9acSsklower } else if( s->siso_family == AF_INET) {
881e014b9acSsklower /* hack */
882e014b9acSsklower struct sockaddr_in *sin = (struct sockaddr_in *)s;
883e014b9acSsklower
884e014b9acSsklower printf("%d.%d.%d.%d: %d",
885e014b9acSsklower (sin->sin_addr.s_addr>>24)&0xff,
886e014b9acSsklower (sin->sin_addr.s_addr>>16)&0xff,
887e014b9acSsklower (sin->sin_addr.s_addr>>8)&0xff,
888e014b9acSsklower (sin->sin_addr.s_addr)&0xff,
889e014b9acSsklower sin->sin_port);
890e014b9acSsklower }
891e014b9acSsklower }
892e014b9acSsklower
8935cbc22e2Sbostic #endif /* ARGO_DEBUG */
894