|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1989, 1993
24: * The Regents of the University of California. All rights reserved.
25: *
26: * Redistribution and use in source and binary forms, with or without
27: * modification, are permitted provided that the following conditions
28: * are met:
29: * 1. Redistributions of source code must retain the above copyright
30: * notice, this list of conditions and the following disclaimer.
31: * 2. Redistributions in binary form must reproduce the above copyright
32: * notice, this list of conditions and the following disclaimer in the
33: * documentation and/or other materials provided with the distribution.
34: * 3. All advertising materials mentioning features or use of this software
35: * must display the following acknowledgement:
36: * This product includes software developed by the University of
37: * California, Berkeley and its contributors.
38: * 4. Neither the name of the University nor the names of its contributors
39: * may be used to endorse or promote products derived from this software
40: * without specific prior written permission.
41: *
42: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52: * SUCH DAMAGE.
53: *
54: * @(#)cltp_usrreq.c 8.1 (Berkeley) 6/10/93
55: */
56:
57: #ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
58: #include <sys/param.h>
59: #include <sys/malloc.h>
60: #include <sys/mbuf.h>
61: #include <sys/protosw.h>
62: #include <sys/socket.h>
63: #include <sys/socketvar.h>
64: #include <sys/errno.h>
65: #include <sys/stat.h>
66:
67: #include <net/if.h>
68: #include <net/route.h>
69:
70: #include <netiso/argo_debug.h>
71: #include <netiso/iso.h>
72: #include <netiso/iso_pcb.h>
73: #include <netiso/iso_var.h>
74: #include <netiso/clnp.h>
75: #include <netiso/cltp_var.h>
76: #endif
77:
78: /*
79: * CLTP protocol implementation.
80: * Per ISO 8602, December, 1987.
81: */
82: cltp_init()
83: {
84:
85: cltb.isop_next = cltb.isop_prev = &cltb;
86: }
87:
88: int cltp_cksum = 1;
89:
90:
91: /* ARGUSED */
92: cltp_input(m0, srcsa, dstsa, cons_channel, output)
93: struct mbuf *m0;
94: struct sockaddr *srcsa, *dstsa;
95: u_int cons_channel;
96: int (*output)();
97: {
98: register struct isopcb *isop;
99: register struct mbuf *m = m0;
100: register u_char *up = mtod(m, u_char *);
101: register struct sockaddr_iso *src = (struct sockaddr_iso *)srcsa;
102: int len, hdrlen = *up + 1, dlen = 0;
103: u_char *uplim = up + hdrlen;
104: caddr_t dtsap;
105:
106: for (len = 0; m; m = m->m_next)
107: len += m->m_len;
108: up += 2; /* skip header */
109: while (up < uplim) switch (*up) { /* process options */
110: case CLTPOVAL_SRC:
111: src->siso_tlen = up[1];
112: src->siso_len = up[1] + TSEL(src) - (caddr_t)src;
113: if (src->siso_len < sizeof(*src))
114: src->siso_len = sizeof(*src);
115: else if (src->siso_len > sizeof(*src)) {
116: MGET(m, M_DONTWAIT, MT_SONAME);
117: if (m == 0)
118: goto bad;
119: m->m_len = src->siso_len;
120: src = mtod(m, struct sockaddr_iso *);
121: bcopy((caddr_t)srcsa, (caddr_t)src, srcsa->sa_len);
122: }
123: bcopy((caddr_t)up + 2, TSEL(src), up[1]);
124: up += 2 + src->siso_tlen;
125: continue;
126:
127: case CLTPOVAL_DST:
128: dtsap = 2 + (caddr_t)up;
129: dlen = up[1];
130: up += 2 + dlen;
131: continue;
132:
133: case CLTPOVAL_CSM:
134: if (iso_check_csum(m0, len)) {
135: cltpstat.cltps_badsum++;
136: goto bad;
137: }
138: up += 4;
139: continue;
140:
141: default:
142: printf("clts: unknown option (%x)\n", up[0]);
143: cltpstat.cltps_hdrops++;
144: goto bad;
145: }
146: if (dlen == 0 || src->siso_tlen == 0)
147: goto bad;
148: for (isop = cltb.isop_next;; isop = isop->isop_next) {
149: if (isop == &cltb) {
150: cltpstat.cltps_noport++;
151: goto bad;
152: }
153: if (isop->isop_laddr &&
154: bcmp(TSEL(isop->isop_laddr), dtsap, dlen) == 0)
155: break;
156: }
157: m = m0;
158: m->m_len -= hdrlen;
159: m->m_data += hdrlen;
160: if (sbappendaddr(&isop->isop_socket->so_rcv, (struct sockaddr *)src,
161: m, (struct mbuf *)0) == 0)
162: goto bad;
163: cltpstat.cltps_ipackets++;
164: sorwakeup(isop->isop_socket);
165: m0 = 0;
166: bad:
167: if (src != (struct sockaddr_iso *)srcsa)
168: m_freem(dtom(src));
169: if (m0)
170: m_freem(m0);
171: return 0;
172: }
173:
174: /*
175: * Notify a cltp user of an asynchronous error;
176: * just wake up so that he can collect error status.
177: */
178: cltp_notify(isop)
179: register struct isopcb *isop;
180: {
181:
182: sorwakeup(isop->isop_socket);
183: sowwakeup(isop->isop_socket);
184: }
185:
186: cltp_ctlinput(cmd, sa)
187: int cmd;
188: struct sockaddr *sa;
189: {
190: extern u_char inetctlerrmap[];
191: struct sockaddr_iso *siso;
192: int iso_rtchange();
193:
194: if ((unsigned)cmd > PRC_NCMDS)
195: return;
196: if (sa->sa_family != AF_ISO && sa->sa_family != AF_CCITT)
197: return;
198: siso = (struct sockaddr_iso *)sa;
199: if (siso == 0 || siso->siso_nlen == 0)
200: return;
201:
202: switch (cmd) {
203: case PRC_ROUTEDEAD:
204: case PRC_REDIRECT_NET:
205: case PRC_REDIRECT_HOST:
206: case PRC_REDIRECT_TOSNET:
207: case PRC_REDIRECT_TOSHOST:
208: iso_pcbnotify(&cltb, siso,
209: (int)inetctlerrmap[cmd], iso_rtchange);
210: break;
211:
212: default:
213: if (inetctlerrmap[cmd] == 0)
214: return; /* XXX */
215: iso_pcbnotify(&cltb, siso, (int)inetctlerrmap[cmd],
216: cltp_notify);
217: }
218: }
219:
220: cltp_output(isop, m)
221: register struct isopcb *isop;
222: register struct mbuf *m;
223: {
224: register int len;
225: register struct sockaddr_iso *siso;
226: int hdrlen, error = 0, docsum;
227: register u_char *up;
228:
229: if (isop->isop_laddr == 0 || isop->isop_faddr == 0) {
230: error = ENOTCONN;
231: goto bad;
232: }
233: /*
234: * Calculate data length and get a mbuf for CLTP header.
235: */
236: hdrlen = 2 + 2 + isop->isop_laddr->siso_tlen
237: + 2 + isop->isop_faddr->siso_tlen;
238: if (docsum = /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum)
239: hdrlen += 4;
240: M_PREPEND(m, hdrlen, M_WAIT);
241: len = m->m_pkthdr.len;
242: /*
243: * Fill in mbuf with extended CLTP header
244: */
245: up = mtod(m, u_char *);
246: up[0] = hdrlen - 1;
247: up[1] = UD_TPDU_type;
248: up[2] = CLTPOVAL_SRC;
249: up[3] = (siso = isop->isop_laddr)->siso_tlen;
250: up += 4;
251: bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
252: up += siso->siso_tlen;
253: up[0] = CLTPOVAL_DST;
254: up[1] = (siso = isop->isop_faddr)->siso_tlen;
255: up += 2;
256: bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
257: /*
258: * Stuff checksum and output datagram.
259: */
260: if (docsum) {
261: up += siso->siso_tlen;
262: up[0] = CLTPOVAL_CSM;
263: up[1] = 2;
264: iso_gen_csum(m, 2 + up - mtod(m, u_char *), len);
265: }
266: cltpstat.cltps_opackets++;
267: return (tpclnp_output(isop, m, len, !docsum));
268: bad:
269: m_freem(m);
270: return (error);
271: }
272:
273: u_long cltp_sendspace = 9216; /* really max datagram size */
274: u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso));
275: /* 40 1K datagrams */
276:
277:
278: /*ARGSUSED*/
279: cltp_usrreq(so, req, m, nam, control)
280: struct socket *so;
281: int req;
282: struct mbuf *m, *nam, *control;
283: {
284: register struct isopcb *isop = sotoisopcb(so);
285: int s, error = 0;
286:
287: if (req == PRU_CONTROL)
288: return (iso_control(so, (int)m, (caddr_t)nam,
289: (struct ifnet *)control));
290: if ((isop == NULL && req != PRU_ATTACH) ||
291: (control && control->m_len)) {
292: error = EINVAL;
293: goto release;
294: }
295: switch (req) {
296:
297: case PRU_ATTACH:
298: if (isop != NULL) {
299: error = EINVAL;
300: break;
301: }
302: error = iso_pcballoc(so, &cltb);
303: if (error)
304: break;
305: error = soreserve(so, cltp_sendspace, cltp_recvspace);
306: if (error)
307: break;
308: break;
309:
310: case PRU_DETACH:
311: iso_pcbdetach(isop);
312: break;
313:
314: case PRU_BIND:
315: error = iso_pcbbind(isop, nam);
316: break;
317:
318: case PRU_LISTEN:
319: error = EOPNOTSUPP;
320: break;
321:
322: case PRU_CONNECT:
323: if (isop->isop_faddr) {
324: error = EISCONN;
325: break;
326: }
327: error = iso_pcbconnect(isop, nam);
328: if (error == 0)
329: soisconnected(so);
330: break;
331:
332: case PRU_CONNECT2:
333: error = EOPNOTSUPP;
334: break;
335:
336: case PRU_ACCEPT:
337: error = EOPNOTSUPP;
338: break;
339:
340: case PRU_DISCONNECT:
341: if (isop->isop_faddr == 0) {
342: error = ENOTCONN;
343: break;
344: }
345: iso_pcbdisconnect(isop);
346: so->so_state &= ~SS_ISCONNECTED; /* XXX */
347: break;
348:
349: case PRU_SHUTDOWN:
350: socantsendmore(so);
351: break;
352:
353: case PRU_SEND:
354: if (nam) {
355: if (isop->isop_faddr) {
356: error = EISCONN;
357: break;
358: }
359: /*
360: * Must block input while temporarily connected.
361: */
362: s = splnet();
363: error = iso_pcbconnect(isop, nam);
364: if (error) {
365: splx(s);
366: break;
367: }
368: } else {
369: if (isop->isop_faddr == 0) {
370: error = ENOTCONN;
371: break;
372: }
373: }
374: error = cltp_output(isop, m);
375: m = 0;
376: if (nam) {
377: iso_pcbdisconnect(isop);
378: splx(s);
379: }
380: break;
381:
382: case PRU_ABORT:
383: soisdisconnected(so);
384: iso_pcbdetach(isop);
385: break;
386:
387: case PRU_SOCKADDR:
388: if (isop->isop_laddr)
389: bcopy((caddr_t)isop->isop_laddr, mtod(m, caddr_t),
390: nam->m_len = isop->isop_laddr->siso_len);
391: break;
392:
393: case PRU_PEERADDR:
394: if (isop->isop_faddr)
395: bcopy((caddr_t)isop->isop_faddr, mtod(m, caddr_t),
396: nam->m_len = isop->isop_faddr->siso_len);
397: break;
398:
399: case PRU_SENSE:
400: /*
401: * stat: don't bother with a blocksize.
402: */
403: return (0);
404:
405: case PRU_SENDOOB:
406: case PRU_FASTTIMO:
407: case PRU_SLOWTIMO:
408: case PRU_PROTORCV:
409: case PRU_PROTOSEND:
410: error = EOPNOTSUPP;
411: break;
412:
413: case PRU_RCVD:
414: case PRU_RCVOOB:
415: return (EOPNOTSUPP); /* do not free mbuf's */
416:
417: default:
418: panic("cltp_usrreq");
419: }
420: release:
421: if (control != NULL)
422: m_freem(control);
423: if (m != NULL)
424: m_freem(m);
425: return (error);
426: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.