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 $ | |
510a846b | 30 | * @(#)iso_pcb.c 7.4 (Berkeley) %G% |
627d3292 KS |
31 | * |
32 | * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 | |
33 | */ | |
510a846b | 34 | |
627d3292 KS |
35 | #ifndef lint |
36 | static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; | |
37 | #endif | |
38 | ||
39 | #ifdef ISO | |
40 | ||
41 | #include "param.h" | |
42 | #include "systm.h" | |
627d3292 KS |
43 | #include "user.h" |
44 | #include "mbuf.h" | |
a50e2bc0 KS |
45 | #include "socket.h" |
46 | #include "socketvar.h" | |
47 | #include "argo_debug.h" | |
48 | #include "iso.h" | |
49 | #include "clnp.h" | |
627d3292 KS |
50 | #include "../netinet/in_systm.h" |
51 | #include "../net/if.h" | |
52 | #include "../net/route.h" | |
a50e2bc0 KS |
53 | #include "iso_pcb.h" |
54 | #include "iso_var.h" | |
627d3292 KS |
55 | #include "protosw.h" |
56 | ||
57 | #define PCBNULL (struct isopcb *)0 | |
58 | struct iso_addr zeroiso_addr = { | |
59 | 0 | |
60 | }; | |
61 | ||
62 | ||
63 | /* | |
64 | * FUNCTION: iso_pcballoc | |
65 | * | |
66 | * PURPOSE: creates an isopcb structure in an mbuf, | |
67 | * with socket (so), and | |
68 | * puts it in the queue with head (head) | |
69 | * | |
70 | * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf | |
71 | */ | |
72 | int | |
73 | iso_pcballoc(so, head) | |
74 | struct socket *so; | |
75 | struct isopcb *head; | |
76 | { | |
627d3292 KS |
77 | register struct isopcb *isop; |
78 | ||
79 | IFDEBUG(D_ISO) | |
80 | printf("iso_pcballoc(so 0x%x)\n", so); | |
81 | ENDDEBUG | |
a50e2bc0 KS |
82 | MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT); |
83 | if (isop == NULL) | |
627d3292 | 84 | return ENOBUFS; |
a50e2bc0 | 85 | bzero((caddr_t)isop, sizeof(*isop)); |
627d3292 KS |
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 | */ | |
a50e2bc0 | 110 | #define satosiso(sa) ((struct sockaddr_iso *)(sa)) |
627d3292 KS |
111 | int |
112 | iso_pcbbind(isop, nam) | |
113 | register struct isopcb *isop; | |
114 | struct mbuf *nam; | |
115 | { | |
116 | register struct isopcb *head = isop->isop_head; | |
117 | register struct sockaddr_iso *siso; | |
a50e2bc0 KS |
118 | struct iso_ifaddr *ia; |
119 | union { | |
120 | char data[2]; | |
121 | u_short s; | |
122 | } suf; | |
627d3292 KS |
123 | |
124 | IFDEBUG(D_ISO) | |
125 | printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); | |
126 | ENDDEBUG | |
a50e2bc0 | 127 | suf.s = 0; |
627d3292 KS |
128 | if (iso_ifaddr == 0) /* any interfaces attached? */ |
129 | return EADDRNOTAVAIL; | |
a50e2bc0 | 130 | if (isop->isop_laddr) /* already bound */ |
627d3292 | 131 | return EADDRINUSE; |
a50e2bc0 KS |
132 | if(nam == (struct mbuf *)0) { |
133 | isop->isop_laddr = &isop->isop_sladdr; | |
134 | isop->isop_sladdr.siso_tsuffixlen = 2; | |
135 | isop->isop_sladdr.siso_nlen = 0; | |
136 | isop->isop_sladdr.siso_family = AF_ISO; | |
137 | isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); | |
627d3292 | 138 | goto noname; |
a50e2bc0 | 139 | } |
627d3292 KS |
140 | siso = mtod(nam, struct sockaddr_iso *); |
141 | IFDEBUG(D_ISO) | |
142 | printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); | |
143 | printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); | |
144 | ENDDEBUG | |
145 | /* | |
146 | * We would like sort of length check but since some OSI addrs | |
147 | * do not have fixed length, we can't really do much. | |
148 | * The ONLY thing we can say is that an osi addr has to have | |
149 | * at LEAST an afi and one more byte and had better fit into | |
150 | * a struct iso_addr. | |
151 | * However, in fact the size of the whole thing is a struct | |
152 | * sockaddr_iso, so probably this is what we should check for. | |
153 | */ | |
a50e2bc0 | 154 | if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { |
627d3292 KS |
155 | return ENAMETOOLONG; |
156 | } | |
a50e2bc0 KS |
157 | if (siso->siso_tsuffixlen) { |
158 | register char *cp = TSEL(siso); | |
159 | suf.data[0] = cp[0]; | |
160 | suf.data[1] = cp[1]; | |
161 | } | |
162 | if (siso->siso_nlen) { | |
627d3292 KS |
163 | /* non-zero net addr- better match one of our interfaces */ |
164 | IFDEBUG(D_ISO) | |
165 | printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); | |
166 | ENDDEBUG | |
a50e2bc0 KS |
167 | for (ia = iso_ifaddr; ia; ia = ia->ia_next) |
168 | if (SAME_ISOADDR(siso, &ia->ia_addr)) | |
169 | break; | |
170 | if (ia == 0) | |
627d3292 | 171 | return EADDRNOTAVAIL; |
627d3292 | 172 | } |
a50e2bc0 KS |
173 | if (siso->siso_len <= sizeof (isop->isop_sladdr)) { |
174 | isop->isop_laddr = &isop->isop_sladdr; | |
175 | } else { | |
176 | if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) | |
177 | return ENOBUFS; | |
178 | isop->isop_laddr = mtod(nam, struct sockaddr_iso *); | |
179 | } | |
180 | bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); | |
181 | if (suf.s) { | |
182 | if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tsuffixlen <= 2) && | |
183 | (u.u_uid != 0)) | |
627d3292 KS |
184 | return EACCES; |
185 | if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && | |
a50e2bc0 | 186 | iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) |
627d3292 | 187 | return EADDRINUSE; |
a50e2bc0 KS |
188 | } else { |
189 | register char *cp; | |
627d3292 | 190 | noname: |
a50e2bc0 | 191 | cp = TSEL(isop->isop_laddr); |
627d3292 KS |
192 | IFDEBUG(D_ISO) |
193 | printf("iso_pcbbind noname\n"); | |
194 | ENDDEBUG | |
627d3292 KS |
195 | do { |
196 | if (head->isop_lport++ < ISO_PORT_RESERVED || | |
197 | head->isop_lport > ISO_PORT_USERRESERVED) | |
198 | head->isop_lport = ISO_PORT_RESERVED; | |
a50e2bc0 KS |
199 | suf.s = head->isop_lport; |
200 | cp[0] = suf.data[0]; | |
201 | cp[1] = suf.data[1]; | |
202 | } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); | |
203 | } | |
627d3292 KS |
204 | IFDEBUG(D_ISO) |
205 | printf("iso_pcbbind returns 0, suf 0x%x\n", suf); | |
206 | ENDDEBUG | |
207 | return 0; | |
208 | } | |
627d3292 KS |
209 | /* |
210 | * FUNCTION: iso_pcbconnect | |
211 | * | |
212 | * PURPOSE: Make the isopcb (isop) look like it's connected. | |
213 | * In other words, give it the peer address given in | |
214 | * the mbuf * (nam). Make sure such a combination | |
215 | * of local, peer addresses doesn't already exist | |
216 | * for this protocol. Internet mentality prevails here, | |
217 | * wherein a src,dst pair uniquely identifies a connection. | |
218 | * Both net address and port must be specified in argument | |
219 | * (nam). | |
220 | * If we don't have a local address for this socket yet, | |
221 | * we pick one by calling iso_pcbbind(). | |
222 | * | |
223 | * RETURNS: errno E* or 0 if ok. | |
224 | * | |
225 | * SIDE EFFECTS: Looks up a route, which may cause one to be left | |
226 | * in the isopcb. | |
227 | * | |
228 | * NOTES: | |
229 | */ | |
627d3292 KS |
230 | int |
231 | iso_pcbconnect(isop, nam) | |
a50e2bc0 | 232 | register struct isopcb *isop; |
627d3292 KS |
233 | struct mbuf *nam; |
234 | { | |
627d3292 | 235 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); |
a50e2bc0 KS |
236 | int local_zero, error = 0; |
237 | struct iso_ifaddr *ia; | |
627d3292 KS |
238 | |
239 | IFDEBUG(D_ISO) | |
a50e2bc0 KS |
240 | printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", |
241 | isop, isop->isop_socket, nam); | |
242 | printf("nam->m_len 0x%x), addr:\n", nam->m_len); | |
627d3292 KS |
243 | dump_isoaddr(siso); |
244 | ENDDEBUG | |
a50e2bc0 KS |
245 | if (nam->m_len < siso->siso_len) |
246 | return EINVAL; | |
627d3292 KS |
247 | if (siso->siso_family != AF_ISO) |
248 | return EAFNOSUPPORT; | |
510a846b KS |
249 | if (siso->siso_nlen == 0) { |
250 | if (ia = iso_ifaddr) { | |
251 | int nlen = ia->ia_addr.siso_nlen; | |
252 | ovbcopy(TSEL(siso), nlen + TSEL(siso), | |
253 | siso->siso_tsuffixlen + siso->siso_ssuffixlen); | |
254 | bcopy((caddr_t)&ia->ia_addr.siso_addr, | |
255 | (caddr_t)&siso->siso_addr, nlen + 1); | |
256 | /* includes siso->siso_nlen = nlen; */ | |
257 | } else | |
258 | return EADDRNOTAVAIL; | |
259 | } | |
a50e2bc0 KS |
260 | /* |
261 | * Local zero means either not bound, or bound to a TSEL, but no | |
262 | * particular local interface. So, if we want to send somebody | |
263 | * we need to choose a return address. | |
627d3292 | 264 | */ |
a50e2bc0 KS |
265 | local_zero = |
266 | ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); | |
627d3292 | 267 | if (local_zero) { |
a50e2bc0 | 268 | int flags; |
627d3292 KS |
269 | |
270 | IFDEBUG(D_ISO) | |
271 | printf("iso_pcbconnect localzero 1\n"); | |
272 | ENDDEBUG | |
627d3292 KS |
273 | /* |
274 | * If route is known or can be allocated now, | |
275 | * our src addr is taken from the i/f, else punt. | |
276 | */ | |
a50e2bc0 KS |
277 | flags = isop->isop_socket->so_options & SO_DONTROUTE; |
278 | if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, | |
279 | (struct sockaddr **)0, &ia)) | |
280 | return error; | |
627d3292 | 281 | IFDEBUG(D_ISO) |
a50e2bc0 KS |
282 | printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", |
283 | isop->isop_route.ro_rt); | |
284 | printf(" ia 0x%x\n", ia); | |
627d3292 | 285 | ENDDEBUG |
627d3292 KS |
286 | } |
287 | IFDEBUG(D_ISO) | |
288 | printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", | |
289 | isop, isop->isop_socket); | |
290 | ENDDEBUG | |
291 | if (local_zero) { | |
a50e2bc0 KS |
292 | int nlen, tlen, totlen; caddr_t oldtsel, newtsel; |
293 | siso = isop->isop_laddr; | |
294 | if (siso == 0 || siso->siso_tsuffixlen == 0) | |
627d3292 | 295 | (void)iso_pcbbind(isop, (struct mbuf *)0); |
a50e2bc0 KS |
296 | /* |
297 | * Here we have problem of squezeing in a definite network address | |
298 | * into an existing sockaddr_iso, which in fact may not have room | |
299 | * for it. This gets messy. | |
300 | */ | |
301 | siso = isop->isop_laddr; | |
302 | oldtsel = TSEL(siso); | |
303 | tlen = siso->siso_tsuffixlen; | |
304 | nlen = ia->ia_addr.siso_nlen; | |
305 | totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); | |
306 | if ((siso == &isop->isop_sladdr) && | |
307 | (totlen > sizeof(isop->isop_sladdr))) { | |
308 | struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); | |
309 | if (m == 0) | |
310 | return ENOBUFS; | |
311 | m->m_len = totlen; | |
312 | isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); | |
313 | } | |
314 | siso->siso_nlen = ia->ia_addr.siso_nlen; | |
315 | newtsel = TSEL(siso); | |
316 | ovbcopy(oldtsel, newtsel, tlen); | |
317 | bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); | |
318 | siso->siso_tsuffixlen = tlen; | |
319 | siso->siso_family = AF_ISO; | |
320 | siso->siso_len = totlen; | |
321 | siso = mtod(nam, struct sockaddr_iso *); | |
627d3292 | 322 | } |
627d3292 KS |
323 | IFDEBUG(D_ISO) |
324 | printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", | |
325 | isop, isop->isop_socket); | |
326 | ENDDEBUG | |
a50e2bc0 KS |
327 | /* |
328 | * If we had to allocate space to a previous big foreign address, | |
329 | * and for some reason we didn't free it, we reuse it knowing | |
330 | * that is going to be big enough, as sockaddrs are delivered in | |
331 | * 128 byte mbufs. | |
332 | * If the foreign address is small enough, we use default space; | |
333 | * otherwise, we grab an mbuf to copy into. | |
334 | */ | |
335 | if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { | |
336 | if (siso->siso_len <= sizeof(isop->isop_sfaddr)) | |
337 | isop->isop_faddr = &isop->isop_sfaddr; | |
338 | else { | |
339 | struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); | |
340 | if (m == 0) | |
341 | return ENOBUFS; | |
342 | isop->isop_faddr = mtod(m, struct sockaddr_iso *); | |
343 | } | |
344 | } | |
345 | bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); | |
627d3292 KS |
346 | IFDEBUG(D_ISO) |
347 | printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", | |
348 | isop, isop->isop_socket); | |
627d3292 | 349 | printf("iso_pcbconnect connected to addr:\n"); |
a50e2bc0 | 350 | dump_isoaddr(isop->isop_faddr); |
627d3292 | 351 | printf("iso_pcbconnect end: src addr:\n"); |
a50e2bc0 | 352 | dump_isoaddr(isop->isop_laddr); |
627d3292 KS |
353 | ENDDEBUG |
354 | return 0; | |
355 | } | |
356 | ||
357 | /* | |
358 | * FUNCTION: iso_pcbdisconnect() | |
359 | * | |
360 | * PURPOSE: washes away the peer address info so the socket | |
361 | * appears to be disconnected. | |
362 | * If there's no file descriptor associated with the socket | |
363 | * it detaches the pcb. | |
364 | * | |
365 | * RETURNS: Nada. | |
366 | * | |
367 | * SIDE EFFECTS: May detach the pcb. | |
368 | * | |
369 | * NOTES: | |
370 | */ | |
371 | void | |
372 | iso_pcbdisconnect(isop) | |
373 | struct isopcb *isop; | |
374 | { | |
375 | void iso_pcbdetach(); | |
376 | ||
377 | IFDEBUG(D_ISO) | |
378 | printf("iso_pcbdisconnect(isop 0x%x)\n", isop); | |
379 | ENDDEBUG | |
a50e2bc0 KS |
380 | /* |
381 | * Preserver binding infnormation if already bound. | |
382 | */ | |
383 | if (isop->isop_laddr && isop->isop_laddr->siso_nlen) | |
384 | isop->isop_laddr->siso_nlen = 0; | |
385 | if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) | |
386 | m_freem(dtom(isop->isop_faddr)); | |
387 | isop->isop_faddr = 0; | |
627d3292 KS |
388 | if (isop->isop_socket->so_state & SS_NOFDREF) |
389 | iso_pcbdetach(isop); | |
390 | } | |
391 | ||
392 | /* | |
393 | * FUNCTION: iso_pcbdetach | |
394 | * | |
395 | * PURPOSE: detach the pcb at *(isop) from it's socket and free | |
396 | * the mbufs associated with the pcb.. | |
397 | * Dequeues (isop) from its head. | |
398 | * | |
399 | * RETURNS: Nada. | |
400 | * | |
401 | * SIDE EFFECTS: | |
402 | * | |
403 | * NOTES: | |
404 | */ | |
405 | void | |
406 | iso_pcbdetach(isop) | |
407 | struct isopcb *isop; | |
408 | { | |
409 | struct socket *so = isop->isop_socket; | |
410 | ||
411 | IFDEBUG(D_ISO) | |
412 | printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", | |
413 | isop, isop->isop_socket, so); | |
414 | ENDDEBUG | |
415 | if (so ) { /* in the x.25 domain, we sometimes have no socket */ | |
416 | so->so_pcb = 0; | |
417 | sofree(so); | |
418 | } | |
419 | IFDEBUG(D_ISO) | |
420 | printf("iso_pcbdetach 2 \n"); | |
421 | ENDDEBUG | |
422 | if (isop->isop_options) | |
423 | (void)m_free(isop->isop_options); | |
424 | IFDEBUG(D_ISO) | |
425 | printf("iso_pcbdetach 3 \n"); | |
426 | ENDDEBUG | |
427 | if (isop->isop_route.ro_rt) | |
428 | rtfree(isop->isop_route.ro_rt); | |
429 | IFDEBUG(D_ISO) | |
430 | printf("iso_pcbdetach 3.1\n"); | |
431 | ENDDEBUG | |
432 | if (isop->isop_clnpcache != NULL) { | |
433 | struct clnp_cache *clcp = | |
434 | mtod(isop->isop_clnpcache, struct clnp_cache *); | |
435 | IFDEBUG(D_ISO) | |
436 | printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", | |
437 | clcp, clcp->clc_hdr); | |
438 | ENDDEBUG | |
439 | if (clcp->clc_hdr != NULL) | |
440 | m_free(clcp->clc_hdr); | |
441 | IFDEBUG(D_ISO) | |
442 | printf("iso_pcbdetach 3.3: freeing cache x%x\n", | |
443 | isop->isop_clnpcache); | |
444 | ENDDEBUG | |
445 | m_free(isop->isop_clnpcache); | |
446 | } | |
447 | IFDEBUG(D_ISO) | |
448 | printf("iso_pcbdetach 4 \n"); | |
449 | ENDDEBUG | |
450 | remque(isop); | |
451 | IFDEBUG(D_ISO) | |
452 | printf("iso_pcbdetach 5 \n"); | |
453 | ENDDEBUG | |
a50e2bc0 KS |
454 | if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) |
455 | m_freem(dtom(isop->isop_laddr)); | |
456 | free((caddr_t)isop, M_IFADDR); | |
627d3292 KS |
457 | } |
458 | ||
459 | #ifdef notdef | |
460 | /* NEEDED? */ | |
461 | void | |
462 | iso_setsockaddr(isop, nam) | |
463 | register struct isopcb *isop; | |
464 | struct mbuf *nam; | |
465 | { | |
466 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); | |
467 | ||
468 | nam->m_len = sizeof (*siso); | |
469 | siso = mtod(nam, struct sockaddr_iso *); | |
470 | bzero((caddr_t)siso, sizeof (*siso)); | |
471 | siso->siso_family = AF_ISO; | |
472 | siso->siso_tsuffix = isop->isop_lport; | |
473 | siso->siso_addr = isop->isop_laddr.siso_addr; | |
474 | } | |
475 | ||
476 | /* NEEDED? */ | |
477 | void | |
478 | iso_setpeeraddr(isop, nam) | |
479 | register struct isopcb *isop; | |
480 | struct mbuf *nam; | |
481 | { | |
482 | register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); | |
483 | ||
484 | nam->m_len = sizeof (*siso); | |
485 | siso = mtod(nam, struct sockaddr_iso *); | |
486 | bzero((caddr_t)siso, sizeof (*siso)); | |
487 | siso->siso_family = AF_ISO; | |
488 | siso->siso_tsuffix = isop->isop_fport; | |
489 | siso->siso_addr = isop->isop_faddr.siso_addr; | |
490 | } | |
491 | #endif notdef | |
492 | ||
493 | /* | |
494 | * FUNCTION: iso_pcbnotify | |
495 | * | |
496 | * PURPOSE: notify all connections in this protocol's queue (head) | |
497 | * that have peer address (dst) of the problem (errno) | |
498 | * by calling (notify) on the connections' isopcbs. | |
499 | * | |
500 | * RETURNS: Rien. | |
501 | * | |
502 | * SIDE EFFECTS: | |
503 | * | |
504 | * NOTES: (notify) is called at splimp! | |
505 | */ | |
506 | void | |
507 | iso_pcbnotify(head, dst, errno, notify) | |
508 | struct isopcb *head; | |
509 | register struct iso_addr *dst; | |
510 | int errno, (*notify)(); | |
511 | { | |
512 | register struct isopcb *isop, *oisop; | |
513 | int s = splimp(); | |
514 | ||
515 | IFDEBUG(D_ISO) | |
516 | printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); | |
517 | ENDDEBUG | |
518 | for (isop = head->isop_next; isop != head;) { | |
a50e2bc0 | 519 | if (!iso_addrmatch1(&(isop->isop_faddr->siso_addr), dst) || |
627d3292 KS |
520 | isop->isop_socket == 0) { |
521 | IFDEBUG(D_ISO) | |
522 | printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , | |
523 | isop, isop->isop_socket); | |
524 | printf("addrmatch cmp'd with (0x%x):\n", | |
a50e2bc0 KS |
525 | &(isop->isop_faddr->siso_addr)); |
526 | dump_isoaddr(isop->isop_faddr); | |
627d3292 KS |
527 | ENDDEBUG |
528 | isop = isop->isop_next; | |
529 | continue; | |
530 | } | |
531 | if (errno) | |
532 | isop->isop_socket->so_error = errno; | |
533 | oisop = isop; | |
534 | isop = isop->isop_next; | |
535 | if (notify) | |
536 | (*notify)(oisop); | |
537 | } | |
538 | splx(s); | |
539 | IFDEBUG(D_ISO) | |
540 | printf("END OF iso_pcbnotify\n" ); | |
541 | ENDDEBUG | |
542 | } | |
543 | ||
544 | ||
545 | /* | |
546 | * FUNCTION: iso_pcblookup | |
547 | * | |
548 | * PURPOSE: looks for a given combination of (faddr), (fport), | |
549 | * (lport), (laddr) in the queue named by (head). | |
550 | * Argument (flags) is ignored. | |
551 | * | |
552 | * RETURNS: ptr to the isopcb if it finds a connection matching | |
553 | * these arguments, o.w. returns zero. | |
554 | * | |
555 | * SIDE EFFECTS: | |
556 | * | |
557 | * NOTES: | |
558 | */ | |
559 | struct isopcb * | |
a50e2bc0 | 560 | iso_pcblookup(head, fportlen, fport, laddr) |
627d3292 | 561 | struct isopcb *head; |
a50e2bc0 KS |
562 | register struct sockaddr_iso *laddr; |
563 | caddr_t fport; | |
564 | int fportlen; | |
627d3292 KS |
565 | { |
566 | register struct isopcb *isop; | |
a50e2bc0 KS |
567 | register caddr_t lp = TSEL(laddr); |
568 | unsigned int llen = laddr->siso_tsuffixlen; | |
627d3292 KS |
569 | |
570 | IFDEBUG(D_ISO) | |
a50e2bc0 KS |
571 | printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", |
572 | head, laddr, fport); | |
627d3292 KS |
573 | ENDDEBUG |
574 | for (isop = head->isop_next; isop != head; isop = isop->isop_next) { | |
a50e2bc0 KS |
575 | if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) |
576 | continue; | |
577 | if (isop->isop_laddr->siso_tsuffixlen != llen) | |
627d3292 | 578 | continue; |
a50e2bc0 KS |
579 | if (bcmp(lp, TSEL(isop->isop_laddr), llen)) |
580 | continue; | |
581 | if (fportlen && isop->isop_faddr && | |
582 | bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) | |
627d3292 KS |
583 | continue; |
584 | /* PHASE2 | |
585 | * addrmatch1 should be iso_addrmatch(a, b, mask) | |
586 | * where mask is taken from isop->isop_laddrmask (new field) | |
587 | * isop_lnetmask will also be available in isop | |
627d3292 KS |
588 | if (laddr != &zeroiso_addr && |
589 | !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) | |
590 | continue; | |
a50e2bc0 KS |
591 | */ |
592 | if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) | |
593 | continue; | |
627d3292 KS |
594 | return (isop); |
595 | } | |
596 | return (struct isopcb *)0; | |
597 | } | |
598 | #endif ISO |