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