Commit | Line | Data |
---|---|---|
627d3292 KS |
1 | /*********************************************************** |
2 | Copyright IBM Corporation 1987 | |
3 | ||
4 | All Rights Reserved | |
5 | ||
6 | Permission to use, copy, modify, and distribute this software and its | |
7 | documentation for any purpose and without fee is hereby granted, | |
8 | provided that the above copyright notice appear in all copies and that | |
9 | both that copyright notice and this permission notice appear in | |
10 | supporting documentation, and that the name of IBM not be | |
11 | used in advertising or publicity pertaining to distribution of the | |
12 | software without specific, written prior permission. | |
13 | ||
14 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
15 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
16 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
17 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
18 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
19 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
20 | SOFTWARE. | |
21 | ||
22 | ******************************************************************/ | |
23 | ||
24 | /* | |
25 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison | |
26 | */ | |
27 | /* | |
28 | * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $ | |
29 | * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $ | |
30 | * | |
31 | * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 | |
32 | */ | |
33 | #ifndef lint | |
34 | static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; | |
35 | #endif | |
36 | ||
37 | #ifdef ISO | |
38 | ||
39 | #include "param.h" | |
40 | #include "systm.h" | |
41 | #include "dir.h" | |
42 | #include "user.h" | |
43 | #include "mbuf.h" | |
44 | #include "../h/socket.h" | |
45 | #include "../h/socketvar.h" | |
46 | #include "../netiso/argo_debug.h" | |
47 | #include "../netiso/iso.h" | |
48 | #include "../netiso/clnp.h" | |
49 | #include "../netinet/in_systm.h" | |
50 | #include "../net/if.h" | |
51 | #include "../net/route.h" | |
52 | #include "../netiso/iso_pcb.h" | |
53 | #include "../netiso/iso_var.h" | |
54 | #include "protosw.h" | |
55 | ||
56 | #define PCBNULL (struct isopcb *)0 | |
57 | struct iso_addr zeroiso_addr = { | |
58 | 0 | |
59 | }; | |
60 | ||
61 | ||
62 | /* | |
63 | * FUNCTION: iso_pcballoc | |
64 | * | |
65 | * PURPOSE: creates an isopcb structure in an mbuf, | |
66 | * with socket (so), and | |
67 | * puts it in the queue with head (head) | |
68 | * | |
69 | * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf | |
70 | */ | |
71 | int | |
72 | iso_pcballoc(so, head) | |
73 | struct socket *so; | |
74 | struct isopcb *head; | |
75 | { | |
76 | struct mbuf *m; | |
77 | register struct isopcb *isop; | |
78 | ||
79 | IFDEBUG(D_ISO) | |
80 | printf("iso_pcballoc(so 0x%x)\n", so); | |
81 | ENDDEBUG | |
82 | m = m_getclr(M_DONTWAIT, MT_PCB); | |
83 | if (m == NULL) | |
84 | return ENOBUFS; | |
85 | isop = mtod(m, struct isopcb *); | |
86 | isop->isop_head = head; | |
87 | isop->isop_socket = so; | |
88 | insque(isop, head); | |
89 | so->so_pcb = (caddr_t)isop; | |
90 | return 0; | |
91 | } | |
92 | ||
93 | /* | |
94 | * FUNCTION: iso_pcbbind | |
95 | * | |
96 | * PURPOSE: binds the address given in *(nam) to the socket | |
97 | * specified by the isopcb in *(isop) | |
98 | * If the given address is zero, it makes sure the | |
99 | * address isn't already in use and if it's got a network | |
100 | * portion, we look for an interface with that network | |
101 | * address. If the address given is zero, we allocate | |
102 | * a port and stuff it in the (nam) structure. | |
103 | * | |
104 | * RETURNS: errno E* or 0 if ok. | |
105 | * | |
106 | * SIDE EFFECTS: increments head->isop_lport if it allocates a port # | |
107 | * | |
108 | * NOTES: | |
109 | */ | |
110 | int | |
111 | iso_pcbbind(isop, nam) | |
112 | register struct isopcb *isop; | |
113 | struct mbuf *nam; | |
114 | { | |
115 | register struct isopcb *head = isop->isop_head; | |
116 | register struct sockaddr_iso *siso; | |
117 | struct ifaddr *ia; | |
118 | u_short suf = 0; | |
119 | ||
120 | IFDEBUG(D_ISO) | |
121 | printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); | |
122 | ENDDEBUG | |
123 | if (iso_ifaddr == 0) /* any interfaces attached? */ | |
124 | return EADDRNOTAVAIL; | |
125 | if (isop->isop_lport) /* already bound */ | |
126 | return EADDRINUSE; | |
127 | if(nam == (struct mbuf *)0) | |
128 | goto noname; | |
129 | siso = mtod(nam, struct sockaddr_iso *); | |
130 | IFDEBUG(D_ISO) | |
131 | printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); | |
132 | printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); | |
133 | ENDDEBUG | |
134 | /* | |
135 | * We would like sort of length check but since some OSI addrs | |
136 | * do not have fixed length, we can't really do much. | |
137 | * The ONLY thing we can say is that an osi addr has to have | |
138 | * at LEAST an afi and one more byte and had better fit into | |
139 | * a struct iso_addr. | |
140 | * However, in fact the size of the whole thing is a struct | |
141 | * sockaddr_iso, so probably this is what we should check for. | |
142 | */ | |
143 | if( (nam->m_len < 2) || (nam->m_len > sizeof(struct sockaddr_iso))) { | |
144 | return ENAMETOOLONG; | |
145 | } | |
146 | suf = siso->siso_tsuffix; | |
147 | ||
148 | if (bcmp(&siso->siso_addr,&zeroiso_addr, 1)) { | |
149 | /* non-zero net addr- better match one of our interfaces */ | |
150 | IFDEBUG(D_ISO) | |
151 | printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); | |
152 | ENDDEBUG | |
153 | siso->siso_tsuffix = 0; /* yech... */ | |
154 | /* PHASE 2: this call is ok */ | |
155 | if ((ia = ifa_ifwithaddr((struct sockaddr *)siso)) | |
156 | == (struct ifaddr *)0) | |
157 | return EADDRNOTAVAIL; | |
158 | /* copy to the inpcb */ | |
159 | bcopy( (caddr_t)&((struct sockaddr_iso *)&(ia->ifa_addr))->siso_addr, | |
160 | (caddr_t)&(isop->isop_laddr.siso_addr), | |
161 | sizeof(struct sockaddr_iso) ); | |
162 | isop->isop_laddr.siso_tsuffix = suf; | |
163 | /* copy also to the nam parameter */ | |
164 | bcopy( (caddr_t)&(isop->isop_laddr.siso_addr), | |
165 | (caddr_t)&(siso->siso_addr), sizeof(struct sockaddr_iso)); | |
166 | siso->siso_tsuffix = suf; | |
167 | } | |
168 | if (suf) { | |
169 | if((suf < ISO_PORT_RESERVED) && (u.u_uid != 0)) | |
170 | return EACCES; | |
171 | if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && | |
172 | iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0) ) | |
173 | return EADDRINUSE; | |
174 | } | |
175 | /* copy the if addr to the result (siso) and to the isopcb */ | |
176 | noname: | |
177 | IFDEBUG(D_ISO) | |
178 | printf("iso_pcbbind noname\n"); | |
179 | ENDDEBUG | |
180 | if (suf == 0) | |
181 | do { | |
182 | if (head->isop_lport++ < ISO_PORT_RESERVED || | |
183 | head->isop_lport > ISO_PORT_USERRESERVED) | |
184 | head->isop_lport = ISO_PORT_RESERVED; | |
185 | suf = head->isop_lport; | |
186 | } while (iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0)); | |
187 | isop->isop_lport = suf; | |
188 | IFDEBUG(D_ISO) | |
189 | printf("iso_pcbbind returns 0, suf 0x%x\n", suf); | |
190 | ENDDEBUG | |
191 | return 0; | |
192 | } | |
193 | ||
194 | /* | |
195 | * FUNCTION: iso_pcbconnect | |
196 | * | |
197 | * PURPOSE: Make the isopcb (isop) look like it's connected. | |
198 | * In other words, give it the peer address given in | |
199 | * the mbuf * (nam). Make sure such a combination | |
200 | * of local, peer addresses doesn't already exist | |
201 | * for this protocol. Internet mentality prevails here, | |
202 | * wherein a src,dst pair uniquely identifies a connection. | |
203 | * Both net address and port must be specified in argument | |
204 | * (nam). | |
205 | * If we don't have a local address for this socket yet, | |
206 | * we pick one by calling iso_pcbbind(). | |
207 | * | |
208 | * RETURNS: errno E* or 0 if ok. | |
209 | * | |
210 | * SIDE EFFECTS: Looks up a route, which may cause one to be left | |
211 | * in the isopcb. | |
212 | * | |
213 | * NOTES: | |
214 | */ | |
215 | #define satosiso(sa) ((struct sockaddr_iso *)(sa)) | |
216 | ||
217 | int | |
218 | iso_pcbconnect(isop, nam) | |
219 | struct isopcb *isop; | |
220 | struct mbuf *nam; | |
221 | { | |
222 | struct ifnet *ifp = (struct ifnet *)0; | |
223 | struct sockaddr_iso ifaddr; | |
224 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); | |
225 | int local_zero = 0; | |
226 | ||
227 | IFDEBUG(D_ISO) | |
228 | printf( | |
229 | "iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x nam->m_len 0x%x), addr:\n", | |
230 | isop, isop->isop_socket, nam, nam->m_len); | |
231 | dump_isoaddr(siso); | |
232 | ENDDEBUG | |
233 | if (nam->m_len > sizeof (*siso)) | |
234 | return ENAMETOOLONG; /* not great but better than EINVAL! */ | |
235 | if (siso->siso_family != AF_ISO) | |
236 | return EAFNOSUPPORT; | |
237 | #ifdef notdef | |
238 | /* removed for the sake of extended tsels - | |
239 | * user may setsockopt for extended tsel (foreign) and then | |
240 | * connect to nsap w/ tsuffix zero | |
241 | */ | |
242 | if (siso->siso_tsuffix == 0) | |
243 | return EADDRNOTAVAIL; | |
244 | local_zero = iso_addrmatch1(&(isop->isop_laddr.siso_addr), &zeroiso_addr); | |
245 | #endif notdef | |
246 | local_zero = !bcmp(&(isop->isop_laddr.siso_addr), &zeroiso_addr, 1); | |
247 | ||
248 | #ifdef PHASEONE | |
249 | if (local_zero) { | |
250 | /* | |
251 | * We need to get the local nsap address. | |
252 | * First, route to the destination. This will provide us with | |
253 | * an ifp. Second, determine which local address linked on | |
254 | * that ifp is appropriate | |
255 | */ | |
256 | struct sockaddr_iso *first_hop; /* filled by clnp_route */ | |
257 | struct ifnet *ifp; /* filled by clnp_route */ | |
258 | int err; | |
259 | struct iso_addr *localaddr; | |
260 | ||
261 | if (err = clnp_route(&siso->siso_addr, &isop->isop_route, /* flags */0, | |
262 | &first_hop, &ifp)) | |
263 | return(err); | |
264 | ||
265 | /* determine local address based upon ifp */ | |
266 | if ((localaddr = clnp_srcaddr(ifp, &first_hop->siso_addr)) == NULL) | |
267 | return(ENETUNREACH); | |
268 | ||
269 | ifaddr.siso_family = AF_ISO; | |
270 | ifaddr.siso_addr = *localaddr; | |
271 | ||
272 | if (isop->isop_lport == 0) | |
273 | (void)iso_pcbbind(isop, (struct mbuf *)0); | |
274 | isop->isop_laddr = ifaddr; | |
275 | } | |
276 | #else | |
277 | if (local_zero) { | |
278 | struct iso_ifaddr *ia; | |
279 | register struct route *ro; | |
280 | ||
281 | IFDEBUG(D_ISO) | |
282 | printf("iso_pcbconnect localzero 1\n"); | |
283 | ENDDEBUG | |
284 | ia = (struct iso_ifaddr *)0; | |
285 | /* | |
286 | * If route is known or can be allocated now, | |
287 | * our src addr is taken from the i/f, else punt. | |
288 | */ | |
289 | ro = &isop->isop_route; | |
290 | IFDEBUG(D_ISO) | |
291 | printf("iso_pcbconnect rtalloc 1.1, ro->ro_rt 0x%x\n", | |
292 | ro->ro_rt); | |
293 | ENDDEBUG | |
294 | if (ro->ro_rt && ! iso_addrmatch1( &(satosiso(&ro->ro_dst)->siso_addr), | |
295 | &siso->siso_addr)) { | |
296 | RTFREE(ro->ro_rt); | |
297 | ro->ro_rt = (struct rtentry *)0; | |
298 | } | |
299 | /* | |
300 | * TODO: it seems this code has a lot in common with clnp_route. | |
301 | * Maybe they could be combined? (RAH) | |
302 | */ | |
303 | if ((isop->isop_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ | |
304 | (ro->ro_rt == (struct rtentry *)0 || | |
305 | (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0)) { | |
306 | /* No route yet, so try to acquire one */ | |
307 | ro->ro_dst.sa_family = AF_ISO; | |
308 | ((struct sockaddr_iso *) &ro->ro_dst)->siso_addr = | |
309 | siso->siso_addr; | |
310 | rtalloc(ro); | |
311 | IFDEBUG(D_ISO) | |
312 | printf("iso_pcbconnect rtalloc 1.5, ro->ro_rt 0x%x\n", | |
313 | ro->ro_rt); | |
314 | if (ro->ro_rt != NULL) { | |
315 | printf("ro->ro_rt->rt_refcnt %d\n", | |
316 | ro->ro_rt->rt_refcnt); | |
317 | printf("rt entry rt_gateway (as sockaddr):\n"); | |
318 | dump_buf(&ro->ro_rt->rt_gateway, | |
319 | sizeof (struct sockaddr)); | |
320 | } | |
321 | ENDDEBUG | |
322 | /* | |
323 | * If we found a route, use the address | |
324 | * corresponding to the outgoing interface | |
325 | * unless it is the loopback (in case a route | |
326 | * to our address on another net goes to loopback). | |
327 | * | |
328 | * We must check to use the address that is of the | |
329 | * same type (in the case where the interface has more | |
330 | * than one type associated with it). (ie ecn0 has | |
331 | * both t37 and osinet addresses. | |
332 | */ | |
333 | if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) && | |
334 | (ifp->if_flags & IFF_LOOPBACK) == 0) | |
335 | for (ia = iso_ifaddr; ia; ia = ia->ia_next) { | |
336 | struct iso_addr *isoap = &IA_SIS(ia)->siso_addr; | |
337 | ||
338 | IFDEBUG(D_ISO) | |
339 | printf("iso_pcbconnect: ia x%x yields: %s\n", | |
340 | ia, clnp_iso_addrp(isoap)); | |
341 | ENDDEBUG | |
342 | ||
343 | if ((ia->ia_ifp == ifp) && | |
344 | (iso_eqtype(&siso->siso_addr, isoap))) | |
345 | break; | |
346 | } | |
347 | } | |
348 | IFDEBUG(D_ISO) | |
349 | printf("iso_pcbconnect localzero 2: ia x%x\n", ia); | |
350 | ENDDEBUG | |
351 | if (ia == 0) { | |
352 | ia = (struct iso_ifaddr *) | |
353 | ifa_ifwithdstaddr((struct sockaddr *)siso); | |
354 | if (ia == 0) | |
355 | ia = iso_iaonnetof(siso); | |
356 | if (ia == 0) | |
357 | return EADDRNOTAVAIL; | |
358 | } | |
359 | ifaddr = *(struct sockaddr_iso *)&ia->ia_addr; | |
360 | } | |
361 | IFDEBUG(D_ISO) | |
362 | printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", | |
363 | isop, isop->isop_socket); | |
364 | ENDDEBUG | |
365 | if (local_zero) { | |
366 | if (isop->isop_lport == 0) | |
367 | (void)iso_pcbbind(isop, (struct mbuf *)0); | |
368 | isop->isop_laddr.siso_addr = ifaddr.siso_addr; | |
369 | isop->isop_laddr.siso_family = AF_ISO; | |
370 | } | |
371 | #endif PHASEONE | |
372 | IFDEBUG(D_ISO) | |
373 | printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", | |
374 | isop, isop->isop_socket); | |
375 | ENDDEBUG | |
376 | bcopy((caddr_t) &(siso->siso_addr), (caddr_t) &(isop->isop_faddr.siso_addr), | |
377 | sizeof(struct iso_addr)); | |
378 | IFDEBUG(D_ISO) | |
379 | printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", | |
380 | isop, isop->isop_socket); | |
381 | ENDDEBUG | |
382 | isop->isop_faddr.siso_family = AF_ISO; | |
383 | isop->isop_fport = siso->siso_tsuffix; | |
384 | IFDEBUG(D_ISO) | |
385 | printf("in iso_pcbconnect end isop 0x%x isop->sock 0x%x\n", | |
386 | isop, isop->isop_socket); | |
387 | printf("iso_pcbconnect connected to addr:\n"); | |
388 | dump_isoaddr(&isop->isop_faddr); | |
389 | printf("iso_pcbconnect end: src addr:\n"); | |
390 | dump_isoaddr(&isop->isop_laddr); | |
391 | ENDDEBUG | |
392 | return 0; | |
393 | } | |
394 | ||
395 | /* | |
396 | * FUNCTION: iso_pcbdisconnect() | |
397 | * | |
398 | * PURPOSE: washes away the peer address info so the socket | |
399 | * appears to be disconnected. | |
400 | * If there's no file descriptor associated with the socket | |
401 | * it detaches the pcb. | |
402 | * | |
403 | * RETURNS: Nada. | |
404 | * | |
405 | * SIDE EFFECTS: May detach the pcb. | |
406 | * | |
407 | * NOTES: | |
408 | */ | |
409 | void | |
410 | iso_pcbdisconnect(isop) | |
411 | struct isopcb *isop; | |
412 | { | |
413 | void iso_pcbdetach(); | |
414 | ||
415 | IFDEBUG(D_ISO) | |
416 | printf("iso_pcbdisconnect(isop 0x%x)\n", isop); | |
417 | ENDDEBUG | |
418 | isop->isop_laddr.siso_addr = zeroiso_addr; | |
419 | isop->isop_fport = 0; | |
420 | if (isop->isop_socket->so_state & SS_NOFDREF) | |
421 | iso_pcbdetach(isop); | |
422 | } | |
423 | ||
424 | /* | |
425 | * FUNCTION: iso_pcbdetach | |
426 | * | |
427 | * PURPOSE: detach the pcb at *(isop) from it's socket and free | |
428 | * the mbufs associated with the pcb.. | |
429 | * Dequeues (isop) from its head. | |
430 | * | |
431 | * RETURNS: Nada. | |
432 | * | |
433 | * SIDE EFFECTS: | |
434 | * | |
435 | * NOTES: | |
436 | */ | |
437 | void | |
438 | iso_pcbdetach(isop) | |
439 | struct isopcb *isop; | |
440 | { | |
441 | struct socket *so = isop->isop_socket; | |
442 | ||
443 | IFDEBUG(D_ISO) | |
444 | printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", | |
445 | isop, isop->isop_socket, so); | |
446 | ENDDEBUG | |
447 | if (so ) { /* in the x.25 domain, we sometimes have no socket */ | |
448 | so->so_pcb = 0; | |
449 | sofree(so); | |
450 | } | |
451 | IFDEBUG(D_ISO) | |
452 | printf("iso_pcbdetach 2 \n"); | |
453 | ENDDEBUG | |
454 | if (isop->isop_options) | |
455 | (void)m_free(isop->isop_options); | |
456 | IFDEBUG(D_ISO) | |
457 | printf("iso_pcbdetach 3 \n"); | |
458 | ENDDEBUG | |
459 | if (isop->isop_route.ro_rt) | |
460 | rtfree(isop->isop_route.ro_rt); | |
461 | IFDEBUG(D_ISO) | |
462 | printf("iso_pcbdetach 3.1\n"); | |
463 | ENDDEBUG | |
464 | if (isop->isop_clnpcache != NULL) { | |
465 | struct clnp_cache *clcp = | |
466 | mtod(isop->isop_clnpcache, struct clnp_cache *); | |
467 | IFDEBUG(D_ISO) | |
468 | printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", | |
469 | clcp, clcp->clc_hdr); | |
470 | ENDDEBUG | |
471 | if (clcp->clc_hdr != NULL) | |
472 | m_free(clcp->clc_hdr); | |
473 | IFDEBUG(D_ISO) | |
474 | printf("iso_pcbdetach 3.3: freeing cache x%x\n", | |
475 | isop->isop_clnpcache); | |
476 | ENDDEBUG | |
477 | m_free(isop->isop_clnpcache); | |
478 | } | |
479 | IFDEBUG(D_ISO) | |
480 | printf("iso_pcbdetach 4 \n"); | |
481 | ENDDEBUG | |
482 | remque(isop); | |
483 | IFDEBUG(D_ISO) | |
484 | printf("iso_pcbdetach 5 \n"); | |
485 | ENDDEBUG | |
486 | (void) m_free(dtom(isop)); | |
487 | } | |
488 | ||
489 | #ifdef notdef | |
490 | /* NEEDED? */ | |
491 | void | |
492 | iso_setsockaddr(isop, nam) | |
493 | register struct isopcb *isop; | |
494 | struct mbuf *nam; | |
495 | { | |
496 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); | |
497 | ||
498 | nam->m_len = sizeof (*siso); | |
499 | siso = mtod(nam, struct sockaddr_iso *); | |
500 | bzero((caddr_t)siso, sizeof (*siso)); | |
501 | siso->siso_family = AF_ISO; | |
502 | siso->siso_tsuffix = isop->isop_lport; | |
503 | siso->siso_addr = isop->isop_laddr.siso_addr; | |
504 | } | |
505 | ||
506 | /* NEEDED? */ | |
507 | void | |
508 | iso_setpeeraddr(isop, nam) | |
509 | register struct isopcb *isop; | |
510 | struct mbuf *nam; | |
511 | { | |
512 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); | |
513 | ||
514 | nam->m_len = sizeof (*siso); | |
515 | siso = mtod(nam, struct sockaddr_iso *); | |
516 | bzero((caddr_t)siso, sizeof (*siso)); | |
517 | siso->siso_family = AF_ISO; | |
518 | siso->siso_tsuffix = isop->isop_fport; | |
519 | siso->siso_addr = isop->isop_faddr.siso_addr; | |
520 | } | |
521 | #endif notdef | |
522 | ||
523 | /* | |
524 | * FUNCTION: iso_pcbnotify | |
525 | * | |
526 | * PURPOSE: notify all connections in this protocol's queue (head) | |
527 | * that have peer address (dst) of the problem (errno) | |
528 | * by calling (notify) on the connections' isopcbs. | |
529 | * | |
530 | * RETURNS: Rien. | |
531 | * | |
532 | * SIDE EFFECTS: | |
533 | * | |
534 | * NOTES: (notify) is called at splimp! | |
535 | */ | |
536 | void | |
537 | iso_pcbnotify(head, dst, errno, notify) | |
538 | struct isopcb *head; | |
539 | register struct iso_addr *dst; | |
540 | int errno, (*notify)(); | |
541 | { | |
542 | register struct isopcb *isop, *oisop; | |
543 | int s = splimp(); | |
544 | ||
545 | IFDEBUG(D_ISO) | |
546 | printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); | |
547 | ENDDEBUG | |
548 | for (isop = head->isop_next; isop != head;) { | |
549 | if (!iso_addrmatch1(&(isop->isop_faddr.siso_addr), dst) || | |
550 | isop->isop_socket == 0) { | |
551 | IFDEBUG(D_ISO) | |
552 | printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , | |
553 | isop, isop->isop_socket); | |
554 | printf("addrmatch cmp'd with (0x%x):\n", | |
555 | &(isop->isop_faddr.siso_addr)); | |
556 | dump_isoaddr(&isop->isop_faddr); | |
557 | ENDDEBUG | |
558 | isop = isop->isop_next; | |
559 | continue; | |
560 | } | |
561 | if (errno) | |
562 | isop->isop_socket->so_error = errno; | |
563 | oisop = isop; | |
564 | isop = isop->isop_next; | |
565 | if (notify) | |
566 | (*notify)(oisop); | |
567 | } | |
568 | splx(s); | |
569 | IFDEBUG(D_ISO) | |
570 | printf("END OF iso_pcbnotify\n" ); | |
571 | ENDDEBUG | |
572 | } | |
573 | ||
574 | ||
575 | /* | |
576 | * FUNCTION: iso_pcblookup | |
577 | * | |
578 | * PURPOSE: looks for a given combination of (faddr), (fport), | |
579 | * (lport), (laddr) in the queue named by (head). | |
580 | * Argument (flags) is ignored. | |
581 | * | |
582 | * RETURNS: ptr to the isopcb if it finds a connection matching | |
583 | * these arguments, o.w. returns zero. | |
584 | * | |
585 | * SIDE EFFECTS: | |
586 | * | |
587 | * NOTES: | |
588 | */ | |
589 | struct isopcb * | |
590 | iso_pcblookup(head, fport, laddr, lport, flags) | |
591 | struct isopcb *head; | |
592 | struct iso_addr *laddr; | |
593 | u_short fport, lport; | |
594 | int flags; | |
595 | { | |
596 | register struct isopcb *isop; | |
597 | ||
598 | IFDEBUG(D_ISO) | |
599 | printf("iso_pcblookup(head 0x%x lport 0x%x fport 0x%x)\n", | |
600 | head, lport, fport); | |
601 | ENDDEBUG | |
602 | for (isop = head->isop_next; isop != head; isop = isop->isop_next) { | |
603 | #ifdef notdef | |
604 | /* | |
605 | * This should be changed to do bcmp on lsuffix in the tpcb instead | |
606 | * since we should be ignoring the lport concept. | |
607 | */ | |
608 | #endif notdef | |
609 | if (isop->isop_lport != lport) | |
610 | continue; | |
611 | if (isop->isop_fport != fport) | |
612 | continue; | |
613 | /* PHASE2 | |
614 | * addrmatch1 should be iso_addrmatch(a, b, mask) | |
615 | * where mask is taken from isop->isop_laddrmask (new field) | |
616 | * isop_lnetmask will also be available in isop | |
617 | */ | |
618 | if (laddr != &zeroiso_addr && | |
619 | !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) | |
620 | continue; | |
621 | return (isop); | |
622 | } | |
623 | return (struct isopcb *)0; | |
624 | } | |
625 | #endif ISO |